@astrosheep/keiyaku 4.5.7 → 4.5.8
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 +10 -0
- 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/opencode.js +3 -2
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +10 -9
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +22 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-babysit/SKILL.md +35 -96
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +28 -49
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +21 -15
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +148 -89
- package/build/src/akuma/abort.d.ts +2 -1
- package/build/src/akuma/abort.js +6 -23
- package/build/src/akuma/akuma-handle.js +4 -2
- package/build/src/akuma/akuma-observe.d.ts +2 -0
- package/build/src/akuma/akuma-observe.js +1 -0
- package/build/src/akuma/akuma-product.js +9 -7
- package/build/src/akuma/akuma.d.ts +372 -9
- package/build/src/akuma/akuma.js +31 -1
- package/build/src/akuma/allowed.d.ts +1 -1
- package/build/src/akuma/allowed.js +1 -0
- package/build/src/akuma/body.d.ts +6 -4
- package/build/src/akuma/body.js +5 -3
- package/build/src/akuma/call-request.d.ts +80 -0
- package/build/src/akuma/call-request.js +211 -0
- package/build/src/akuma/heart/facts.d.ts +6 -78
- package/build/src/akuma/heart/index.d.ts +1 -1
- package/build/src/akuma/heart/request-authority.d.ts +5 -4
- package/build/src/akuma/heart/request-authority.js +20 -34
- package/build/src/akuma/heart/request-rows.js +12 -23
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +5 -13
- package/build/src/akuma/index.d.ts +1 -1
- package/build/src/akuma/index.js +1 -1
- package/build/src/akuma/projection-read.d.ts +1 -0
- package/build/src/akuma/projection-read.js +8 -1
- package/build/src/akuma/projection.d.ts +856 -137
- package/build/src/akuma/projection.js +190 -0
- package/build/src/akuma/provider.d.ts +30 -3
- package/build/src/akuma/provider.js +104 -0
- package/build/src/akuma/providers/acp/core.d.ts +2 -2
- package/build/src/akuma/providers/acp/core.js +13 -6
- package/build/src/akuma/providers/acp/index.js +5 -4
- package/build/src/akuma/providers/claude/index.d.ts +3 -3
- package/build/src/akuma/providers/claude/index.js +16 -5
- package/build/src/akuma/providers/codex-app-server/events.js +1 -1
- package/build/src/akuma/providers/codex-app-server/index.js +18 -6
- package/build/src/akuma/providers/grok-build/index.js +5 -4
- package/build/src/akuma/providers/opencode-sdk/index.js +66 -25
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/session.js +28 -11
- package/build/src/akuma/providers/pi/index.js +42 -14
- package/build/src/akuma/request-lifecycle.d.ts +3 -9
- package/build/src/akuma/request-lifecycle.js +4 -4
- package/build/src/akuma/request-rendezvous.d.ts +26 -0
- package/build/src/akuma/request-rendezvous.js +100 -0
- package/build/src/akuma/request-serve.d.ts +5 -65
- package/build/src/akuma/request-serve.js +81 -208
- package/build/src/akuma/request-wire.d.ts +109 -115
- package/build/src/akuma/request-wire.js +63 -318
- package/build/src/akuma/requests.d.ts +19 -47
- package/build/src/akuma/requests.js +51 -107
- package/build/src/akuma/turn-drive.d.ts +5 -3
- package/build/src/akuma/turn-drive.js +32 -10
- package/build/src/akuma-body.d.ts +7 -2
- package/build/src/akuma-body.js +68 -46
- package/build/src/cli/accepted.d.ts +1 -1
- package/build/src/cli/accepted.js +2 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +2 -0
- package/build/src/cli/commands/akuma-invoke.js +17 -9
- package/build/src/cli/commands/akuma.js +7 -7
- package/build/src/cli/commands/contract-invoke.d.ts +3 -2
- package/build/src/cli/commands/contract-invoke.js +26 -19
- package/build/src/cli/commands/contract.d.ts +13 -13
- package/build/src/cli/commands/contract.js +32 -17
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +1 -1
- package/build/src/cli/commands/task-invoke.d.ts +3 -0
- package/build/src/cli/commands/task-invoke.js +23 -140
- package/build/src/cli/commands/task.js +54 -20
- package/build/src/cli/invoke.js +39 -25
- package/build/src/cli/main.js +2 -1
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/parse.js +37 -22
- package/build/src/cli/render/akuma-activity.d.ts +4 -1
- package/build/src/cli/render/akuma-activity.js +45 -30
- package/build/src/cli/render/akuma-tool.d.ts +5 -1
- package/build/src/cli/render/akuma.js +5 -9
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/catalog.js +80 -21
- package/build/src/cli/render/contract-observation.d.ts +2 -0
- package/build/src/cli/render/contract-observation.js +11 -0
- package/build/src/cli/render/contract.js +25 -65
- package/build/src/cli/render/kanshi-akuma.d.ts +8 -0
- package/build/src/cli/render/kanshi-akuma.js +111 -0
- package/build/src/cli/render/kanshi.js +108 -213
- package/build/src/cli/render/receipt.d.ts +1 -2
- package/build/src/cli/render/receipt.js +76 -26
- package/build/src/cli/render/refusal.js +2 -10
- package/build/src/cli/render/region.js +5 -2
- package/build/src/cli/render/settings.d.ts +1 -1
- package/build/src/cli/render/settings.js +27 -8
- package/build/src/cli/render/task.js +22 -5
- package/build/src/cli/render/terminal.d.ts +28 -0
- package/build/src/cli/render/terminal.js +65 -0
- package/build/src/cli/result.d.ts +3 -3
- package/build/src/cli/runtime.js +3 -1
- package/build/src/cli/selectors.d.ts +2 -1
- package/build/src/cli/selectors.js +4 -3
- package/build/src/cli/square-edge.js +120 -36
- package/build/src/cli/usage.js +2 -1
- package/build/src/contract-guidance.d.ts +5 -0
- package/build/src/contract-guidance.js +121 -0
- package/build/src/contract-worktree.d.ts +0 -1
- package/build/src/contract-worktree.js +32 -83
- package/build/src/coordination/sqlite-transaction-lock.d.ts +1 -0
- package/build/src/coordination/sqlite-transaction-lock.js +5 -0
- package/build/src/core/facts/codec.d.ts +2 -0
- package/build/src/core/facts/codec.js +4 -0
- package/build/src/core/verbs/placement.d.ts +6 -1
- package/build/src/core/verbs/placement.js +5 -3
- package/build/src/dispatch/index.d.ts +0 -2
- package/build/src/dispatch/index.js +54 -55
- package/build/src/git/admission.js +2 -2
- package/build/src/git/hooks.d.ts +9 -15
- package/build/src/git/hooks.js +23 -317
- package/build/src/git/nuke.d.ts +2 -1
- package/build/src/git/nuke.js +36 -18
- package/build/src/git/private-state-seat.d.ts +12 -0
- package/build/src/git/private-state-seat.js +39 -0
- package/build/src/git/process.d.ts +6 -0
- package/build/src/git/process.js +19 -7
- package/build/src/git/read-observation.js +29 -20
- package/build/src/git/reconcile.d.ts +11 -0
- package/build/src/git/reconcile.js +64 -11
- package/build/src/git/repository.d.ts +6 -2
- package/build/src/git/repository.js +8 -0
- package/build/src/git/target-placement.d.ts +1 -0
- package/build/src/git/target-placement.js +5 -0
- package/build/src/git/tender.d.ts +1 -0
- package/build/src/git/terminal-reconcile.d.ts +1 -1
- package/build/src/git/terminal-reconcile.js +22 -20
- package/build/src/git/workspace.d.ts +14 -0
- package/build/src/git/workspace.js +44 -0
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +16 -16
- package/build/src/kanshi/report.d.ts +2 -2
- package/build/src/library/address.d.ts +9 -3
- package/build/src/library/address.js +3 -2
- package/build/src/library/akuma-creation.d.ts +4 -3
- package/build/src/library/akuma-creation.js +19 -13
- package/build/src/library/audit.d.ts +1 -1
- package/build/src/library/audit.js +5 -3
- package/build/src/library/catalog.d.ts +3 -1
- package/build/src/library/catalog.js +20 -6
- package/build/src/library/composition.d.ts +371 -0
- package/build/src/library/composition.js +28 -0
- package/build/src/library/configuration.js +8 -2
- package/build/src/library/continuation.js +66 -30
- package/build/src/library/contract-bind.js +10 -2
- package/build/src/library/contract-forwarding-reconciliation-result.d.ts +96 -0
- package/build/src/library/contract-forwarding-reconciliation-result.js +83 -0
- package/build/src/library/contract-forwarding-result.d.ts +6723 -0
- package/build/src/library/contract-forwarding-result.js +521 -0
- package/build/src/library/contract-forwarding.d.ts +72 -0
- package/build/src/library/contract-forwarding.js +125 -0
- package/build/src/library/contract-handle.d.ts +36 -0
- package/build/src/library/contract-handle.js +313 -0
- package/build/src/library/contract-operations.d.ts +1044 -67
- package/build/src/library/contract-operations.js +190 -118
- package/build/src/library/contract.d.ts +11 -32
- package/build/src/library/contract.js +16 -289
- package/build/src/library/fleet-result.d.ts +1454 -0
- package/build/src/library/fleet-result.js +96 -0
- package/build/src/library/fleet.d.ts +112 -54
- package/build/src/library/fleet.js +211 -71
- package/build/src/library/input.d.ts +2 -0
- package/build/src/library/input.js +4 -0
- package/build/src/library/keiyaku.d.ts +371 -20
- package/build/src/library/keiyaku.js +8 -21
- package/build/src/library/mutation.d.ts +3 -3
- package/build/src/library/mutation.js +5 -9
- package/build/src/library/nuke.d.ts +1 -1
- package/build/src/library/nuke.js +4 -3
- package/build/src/library/reconcile.d.ts +4 -0
- package/build/src/library/reconcile.js +2 -0
- package/build/src/library/refusal.d.ts +0 -9
- package/build/src/library/refusal.js +0 -7
- package/build/src/protocol/amend.js +56 -50
- package/build/src/protocol/attempt.d.ts +2 -0
- package/build/src/protocol/attempt.js +8 -1
- package/build/src/protocol/completion.js +7 -0
- package/build/src/protocol/deliver.js +6 -2
- package/build/src/protocol/operations.d.ts +4 -1
- package/build/src/protocol/operations.js +5 -2
- package/build/src/protocol/placement.d.ts +1 -0
- package/build/src/protocol/placement.js +52 -38
- package/build/src/protocol/read/observation.d.ts +1 -4
- package/build/src/protocol/read/observation.js +2 -15
- package/build/src/protocol/reintegrate.js +62 -58
- package/build/src/protocol/review.js +5 -0
- package/build/src/protocol/run.js +17 -13
- package/build/src/runtime/proc/run.d.ts +8 -0
- package/build/src/runtime/proc/run.js +27 -0
- package/build/src/runtime/proc/termination.js +26 -22
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/holder.d.ts +2 -1
- package/build/src/settlement/holder.js +15 -4
- package/build/src/settlement/settle.js +99 -33
- package/build/src/task/board.d.ts +68 -27
- package/build/src/task/board.js +31 -1
- package/build/src/task/catalog.d.ts +4 -0
- package/build/src/task/catalog.js +23 -0
- package/build/src/task/compose-language.js +33 -7
- package/build/src/task/compose-parser.d.ts +1 -1
- package/build/src/task/compose-parser.js +1 -1
- package/build/src/task/compose.js +2 -0
- package/build/src/task/index.d.ts +12 -4
- package/build/src/task/index.js +97 -16
- package/build/src/task/mutation-result.d.ts +923 -0
- package/build/src/task/mutation-result.js +140 -0
- package/build/src/task/mutation.d.ts +552 -28
- package/build/src/task/mutation.js +304 -97
- package/build/src/task/operations.d.ts +1 -4
- package/build/src/task/operations.js +0 -6
- package/build/src/task/public.d.ts +2 -0
- package/build/src/task/public.js +1 -0
- package/build/src/workspace-place.d.ts +7 -2
- package/build/src/workspace-place.js +34 -24
- package/build/src/world.d.ts +1 -0
- package/build/src/world.js +11 -0
- package/package.json +8 -6
- package/build/src/akuma/request-execution.d.ts +0 -8
- package/build/src/akuma/request-execution.js +0 -98
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { decodeContractDocument } from "../body/decode.js";
|
|
2
|
+
import { contractId } from "../core/facts/types.js";
|
|
3
|
+
import { withGitDecodeChannel } from "../git/read-observation.js";
|
|
4
|
+
import { deliverOperation } from "../protocol/deliver.js";
|
|
5
|
+
import { reviewOperation } from "../protocol/review.js";
|
|
6
|
+
import { auditContract } from "./audit.js";
|
|
7
|
+
import { continueAcceptedCompletion } from "./continuation.js";
|
|
8
|
+
import { actorOption, documentDerivation, invalidInput, optionalNonblank } from "./input.js";
|
|
9
|
+
import { completionInput, completeMutation } from "./mutation.js";
|
|
10
|
+
import { requireAccepted } from "./refusal.js";
|
|
11
|
+
import { auditReportSchema, auditResultSchema, deliveryResultSchema, reviewResultSchema, } from "./contract-forwarding-result.js";
|
|
12
|
+
import { scopeForRepo } from "./repo.js";
|
|
13
|
+
function derivedDocument(state) {
|
|
14
|
+
return documentDerivation(decodeContractDocument(state.terms.document.bytes), state.terms.gates, state.id);
|
|
15
|
+
}
|
|
16
|
+
function operationContext(scope, channel, contractId) {
|
|
17
|
+
return { scope, channel, contractId, deriveDocument: derivedDocument };
|
|
18
|
+
}
|
|
19
|
+
export async function executeLocalDelivery(input) {
|
|
20
|
+
const scope = input.scope;
|
|
21
|
+
return withGitDecodeChannel(scope, async (channel) => {
|
|
22
|
+
const operation = operationContext(scope, channel, input.contractId);
|
|
23
|
+
const outcome = await deliverOperation({
|
|
24
|
+
...operation,
|
|
25
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
26
|
+
...(input.message === undefined ? {} : { message: input.message }),
|
|
27
|
+
requireBranchesToBeUpToDate: input.requireBranchesToBeUpToDate,
|
|
28
|
+
includeDirty: input.includeDirty,
|
|
29
|
+
materializeConflict: input.materializeConflict,
|
|
30
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
31
|
+
});
|
|
32
|
+
if (outcome.kind === "integration-conflict-materialized")
|
|
33
|
+
return outcome;
|
|
34
|
+
const accepted = requireAccepted(outcome);
|
|
35
|
+
const continued = await continueAcceptedCompletion({
|
|
36
|
+
...operation,
|
|
37
|
+
accepted,
|
|
38
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
39
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
40
|
+
});
|
|
41
|
+
return completeMutation({
|
|
42
|
+
...completionInput(scope, channel, input.contractId, (delivery) => delivery, input.hooks),
|
|
43
|
+
accepted: continued,
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
export async function executeLocalReview(input) {
|
|
48
|
+
return withGitDecodeChannel(input.scope, async (channel) => {
|
|
49
|
+
const operation = operationContext(input.scope, channel, input.contractId);
|
|
50
|
+
const accepted = requireAccepted(await reviewOperation({
|
|
51
|
+
...operation,
|
|
52
|
+
verdict: input.verdict,
|
|
53
|
+
...(input.summary === undefined ? {} : { summary: input.summary }),
|
|
54
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
55
|
+
}));
|
|
56
|
+
const continued = await continueAcceptedCompletion({
|
|
57
|
+
...operation,
|
|
58
|
+
accepted,
|
|
59
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
60
|
+
});
|
|
61
|
+
return completeMutation({
|
|
62
|
+
...completionInput(input.scope, channel, input.contractId, (review) => review, input.hooks),
|
|
63
|
+
accepted: continued,
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
export async function executeForwardedDeliver(input) {
|
|
68
|
+
const id = contractId(input.contractId);
|
|
69
|
+
const actor = actorOption(input.requester).actor;
|
|
70
|
+
const message = optionalNonblank(input.message, "deliver message");
|
|
71
|
+
const result = await executeLocalDelivery({
|
|
72
|
+
scope: scopeForRepo(input.repo),
|
|
73
|
+
contractId: id,
|
|
74
|
+
...(actor === undefined ? {} : { actor }),
|
|
75
|
+
...(message === undefined ? {} : { message }),
|
|
76
|
+
requireBranchesToBeUpToDate: input.requireBranchesToBeUpToDate,
|
|
77
|
+
includeDirty: input.includeDirty,
|
|
78
|
+
materializeConflict: input.materializeConflict,
|
|
79
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
80
|
+
hooks: input.hooks,
|
|
81
|
+
});
|
|
82
|
+
if (!("facts" in result))
|
|
83
|
+
return { result: deliveryResultSchema.parse(result) };
|
|
84
|
+
const delivery = result.facts.find((fact) => fact.kind === "deliver");
|
|
85
|
+
if (delivery === undefined)
|
|
86
|
+
throw new Error("accepted delivery is missing its journal fact");
|
|
87
|
+
return { result: deliveryResultSchema.parse(result), deliveryFactId: delivery.entry };
|
|
88
|
+
}
|
|
89
|
+
export async function executeForwardedReview(input) {
|
|
90
|
+
const id = contractId(input.contractId);
|
|
91
|
+
const actor = actorOption(input.requester).actor;
|
|
92
|
+
if (input.verdict !== "satisfied" && input.verdict !== "unsatisfied") {
|
|
93
|
+
invalidInput("verdict must be satisfied or unsatisfied");
|
|
94
|
+
}
|
|
95
|
+
const summary = optionalNonblank(input.summary, "review summary");
|
|
96
|
+
const result = await executeLocalReview({
|
|
97
|
+
scope: scopeForRepo(input.repo),
|
|
98
|
+
contractId: id,
|
|
99
|
+
...(actor === undefined ? {} : { actor }),
|
|
100
|
+
verdict: input.verdict,
|
|
101
|
+
...(summary === undefined ? {} : { summary }),
|
|
102
|
+
hooks: input.hooks,
|
|
103
|
+
});
|
|
104
|
+
const review = result.facts.find((fact) => fact.kind === "attestation");
|
|
105
|
+
if (review === undefined)
|
|
106
|
+
throw new Error("accepted review is missing its journal fact");
|
|
107
|
+
return { result: reviewResultSchema.parse(result), reviewFactId: review.entry };
|
|
108
|
+
}
|
|
109
|
+
export async function executeForwardedAudit(input) {
|
|
110
|
+
const id = contractId(input.contractId);
|
|
111
|
+
const actor = actorOption(input.requester).actor;
|
|
112
|
+
const result = await auditContract({
|
|
113
|
+
scope: scopeForRepo(input.repo),
|
|
114
|
+
contractId: id,
|
|
115
|
+
input: {
|
|
116
|
+
...(actor === undefined ? {} : { actor }),
|
|
117
|
+
includeDirty: input.includeDirty,
|
|
118
|
+
showDiff: input.showDiff,
|
|
119
|
+
requireBranchesToBeUpToDate: input.requireBranchesToBeUpToDate,
|
|
120
|
+
...(input.hooks === undefined ? {} : { hooks: input.hooks }),
|
|
121
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
return { result: auditResultSchema.parse(result), auditReport: auditReportSchema.parse(result.value) };
|
|
125
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type ContractId, type ContractState } from "../core/facts/types.js";
|
|
2
|
+
import { type RepositoryScope } from "../protocol/operations.js";
|
|
3
|
+
import type { AuditReport } from "../protocol/audit.js";
|
|
4
|
+
import type { IntegrationConflictMaterialized } from "../protocol/deliver.js";
|
|
5
|
+
import { type ReconcileInput } from "./repo.js";
|
|
6
|
+
import { type ExecutionContext } from "../akuma/requests.js";
|
|
7
|
+
import { type AuditInput } from "./audit.js";
|
|
8
|
+
import { Delivery } from "./delivery.js";
|
|
9
|
+
import { type MutationResult } from "./mutation.js";
|
|
10
|
+
import type { AbandonInput, AmendInput, AmendResult, ArcInput, DeliverInput, ReconcileReport, ReviewInput, ContractHistory } from "./contract-types.js";
|
|
11
|
+
import { type Review as OperationReview } from "./contract-operations.js";
|
|
12
|
+
type Review = OperationReview;
|
|
13
|
+
export declare class KeiyakuHandle {
|
|
14
|
+
private readonly id;
|
|
15
|
+
private readonly scope;
|
|
16
|
+
private readonly execution;
|
|
17
|
+
constructor(id: ContractId, scope: RepositoryScope, execution?: ExecutionContext);
|
|
18
|
+
state(): Promise<ContractState>;
|
|
19
|
+
history(): Promise<ContractHistory>;
|
|
20
|
+
guidance(): Promise<string>;
|
|
21
|
+
delivery(): Promise<Delivery | null>;
|
|
22
|
+
amend(input: AmendInput): Promise<AmendResult>;
|
|
23
|
+
deliver(input?: DeliverInput): Promise<MutationResult<Delivery> | IntegrationConflictMaterialized>;
|
|
24
|
+
review(input: ReviewInput): Promise<MutationResult<Review>>;
|
|
25
|
+
abandon(input?: AbandonInput): Promise<MutationResult<void>>;
|
|
26
|
+
arc(input: ArcInput): Promise<MutationResult<void>>;
|
|
27
|
+
audit(input?: AuditInput): Promise<MutationResult<AuditReport>>;
|
|
28
|
+
reconcile(input?: ReconcileInput): Promise<ReconcileReport>;
|
|
29
|
+
private deliveryHandle;
|
|
30
|
+
}
|
|
31
|
+
/** Internal package composition capability; not exported from the package root. */
|
|
32
|
+
export declare function seatForKeiyaku(value: unknown): Readonly<{
|
|
33
|
+
id: ContractId;
|
|
34
|
+
scope: RepositoryScope;
|
|
35
|
+
}> | null;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
import { documentDiff } from "../markdown/diff.js";
|
|
2
|
+
import { applyAmendDocument } from "../body/amend.js";
|
|
3
|
+
import { decodeArcDocument } from "../body/arc.js";
|
|
4
|
+
import { decodeContractDocument } from "../body/decode.js";
|
|
5
|
+
import { renderContractGuidance } from "../contract-guidance.js";
|
|
6
|
+
import { actorOption, contractTerms, documentDerivation, normalizedGates, normalizedList, optionalBoolean, optionalNonblank, optionalSignal, invalidInput, requireInput, requireMarkdown, } from "./input.js";
|
|
7
|
+
import { observeChangedRegion } from "./region.js";
|
|
8
|
+
import { worktreeHooksOption } from "./configuration.js";
|
|
9
|
+
import { contractId } from "../core/facts/types.js";
|
|
10
|
+
import { contractObservationOperation, deliveryDiffOperation, deliveryOperation, stateOperation, } from "../protocol/operations.js";
|
|
11
|
+
import { abandonOperation } from "../protocol/abandon.js";
|
|
12
|
+
import { amendOperation } from "../protocol/amend.js";
|
|
13
|
+
import { arcOperation } from "../protocol/arc.js";
|
|
14
|
+
import { readDispatchesAt } from "../dispatch/index.js";
|
|
15
|
+
import { mintSnapshotId } from "../git/identity.js";
|
|
16
|
+
import { observeContractsForAdmissionInObservationAt } from "../git/observe.js";
|
|
17
|
+
import { withGitDecodeChannel, withGitReadObservation } from "../git/read-observation.js";
|
|
18
|
+
import { releaseTaskHolder, releaseTaskHolderWithFence, taskHolderObservationSelection } from "../settlement/holder.js";
|
|
19
|
+
import { reconcileInput } from "./repo.js";
|
|
20
|
+
import { executionChannel, localExecutionContext } from "../akuma/requests.js";
|
|
21
|
+
import { auditContract } from "./audit.js";
|
|
22
|
+
import { deliveryHandle } from "./delivery.js";
|
|
23
|
+
import { completionInput, completeHolderMutation, completeMutation } from "./mutation.js";
|
|
24
|
+
import { completeReconcile } from "./reconcile.js";
|
|
25
|
+
import { executeLocalDelivery, executeLocalReview, requestForwardedContractLive, } from "./contract-operations.js";
|
|
26
|
+
import { KeiyakuRefused, requireAccepted } from "./refusal.js";
|
|
27
|
+
export class KeiyakuHandle {
|
|
28
|
+
id;
|
|
29
|
+
scope;
|
|
30
|
+
execution;
|
|
31
|
+
constructor(id, scope, execution = localExecutionContext()) {
|
|
32
|
+
this.id = id;
|
|
33
|
+
this.scope = scope;
|
|
34
|
+
this.execution = execution;
|
|
35
|
+
KEIYAKU_SEATS.set(this, { id, scope });
|
|
36
|
+
}
|
|
37
|
+
async state() {
|
|
38
|
+
return withGitDecodeChannel(this.scope, (channel) => stateOperation({
|
|
39
|
+
scope: this.scope,
|
|
40
|
+
channel,
|
|
41
|
+
contractId: this.id,
|
|
42
|
+
}));
|
|
43
|
+
}
|
|
44
|
+
async history() {
|
|
45
|
+
return withGitDecodeChannel(this.scope, (channel) => withGitReadObservation(this.scope, channel, async (observation) => {
|
|
46
|
+
const [journals, dispatches] = await Promise.all([
|
|
47
|
+
observeContractsForAdmissionInObservationAt(observation, [this.id]),
|
|
48
|
+
readDispatchesAt(observation),
|
|
49
|
+
]);
|
|
50
|
+
const record = journals.journals.get(this.id);
|
|
51
|
+
if (record === undefined)
|
|
52
|
+
throw new Error(`missing requested contract observation: ${this.id}`);
|
|
53
|
+
if (record.state === null)
|
|
54
|
+
throw new KeiyakuRefused({ kind: "contract-missing", contractId: this.id });
|
|
55
|
+
const commit = observation.snapshot.commit;
|
|
56
|
+
if (commit === null)
|
|
57
|
+
throw new Error("contract history requires a keiyaku-state snapshot");
|
|
58
|
+
const recordedAt = (event) => event.source === "journal" ? event.fact.at : event.dispatch.dispatchedAt;
|
|
59
|
+
const events = [
|
|
60
|
+
...record.entries.map((fact) => ({ source: "journal", fact })),
|
|
61
|
+
...dispatches
|
|
62
|
+
.filter((dispatch) => dispatch.contractId === this.id)
|
|
63
|
+
.map((dispatch) => ({ source: "dispatch", dispatch })),
|
|
64
|
+
].sort((left, right) => {
|
|
65
|
+
const leftAt = recordedAt(left);
|
|
66
|
+
const rightAt = recordedAt(right);
|
|
67
|
+
if (leftAt !== rightAt)
|
|
68
|
+
return leftAt < rightAt ? -1 : 1;
|
|
69
|
+
if (left.source !== right.source)
|
|
70
|
+
return left.source === "journal" ? -1 : 1;
|
|
71
|
+
return 0;
|
|
72
|
+
});
|
|
73
|
+
return { id: this.id, state: mintSnapshotId(commit), events };
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
async guidance() {
|
|
77
|
+
return withGitDecodeChannel(this.scope, async (channel) => {
|
|
78
|
+
const observed = await contractObservationOperation({ scope: this.scope, channel, contractId: this.id });
|
|
79
|
+
if (observed.kind === "missing")
|
|
80
|
+
throw new KeiyakuRefused({ kind: "contract-missing", contractId: this.id });
|
|
81
|
+
return renderContractGuidance(await stateOperation({ scope: this.scope, channel, contractId: this.id }));
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
async delivery() {
|
|
85
|
+
const delivery = await withGitDecodeChannel(this.scope, (channel) => deliveryOperation({
|
|
86
|
+
scope: this.scope,
|
|
87
|
+
channel,
|
|
88
|
+
contractId: this.id,
|
|
89
|
+
}));
|
|
90
|
+
return delivery === null ? null : this.deliveryHandle(delivery);
|
|
91
|
+
}
|
|
92
|
+
async amend(input) {
|
|
93
|
+
const values = requireInput(input, "amend input");
|
|
94
|
+
const hooks = worktreeHooksOption(values.hooks);
|
|
95
|
+
const markdown = values.markdown === undefined ? undefined : requireMarkdown(values.markdown);
|
|
96
|
+
const actor = actorOption(values.actor);
|
|
97
|
+
const gates = values.gates === undefined ? undefined : normalizedGates(values.gates);
|
|
98
|
+
const prerequisites = values.after === undefined ? undefined : normalizedList(values.after, "after", contractId);
|
|
99
|
+
if (markdown === undefined && gates === undefined && prerequisites === undefined) {
|
|
100
|
+
return invalidInput("amend requires markdown, after, or gates");
|
|
101
|
+
}
|
|
102
|
+
const amendment = await withGitDecodeChannel(this.scope, async (channel) => {
|
|
103
|
+
let changedSections;
|
|
104
|
+
const accepted = requireAccepted(await amendOperation({
|
|
105
|
+
scope: this.scope,
|
|
106
|
+
channel,
|
|
107
|
+
contractId: this.id,
|
|
108
|
+
...actor,
|
|
109
|
+
deriveAmendment: (source) => {
|
|
110
|
+
const amendment = markdown === undefined
|
|
111
|
+
? undefined
|
|
112
|
+
: applyAmendDocument(markdown, decodeContractDocument(source.document.bytes));
|
|
113
|
+
changedSections = amendment?.changedSections;
|
|
114
|
+
const document = amendment === undefined
|
|
115
|
+
? decodeContractDocument(source.document.bytes)
|
|
116
|
+
: decodeContractDocument(amendment.document);
|
|
117
|
+
const terms = markdown === undefined
|
|
118
|
+
? {
|
|
119
|
+
document: source.document,
|
|
120
|
+
segments: source.segments,
|
|
121
|
+
gates: gates ?? source.gates,
|
|
122
|
+
after: prerequisites ?? source.after,
|
|
123
|
+
}
|
|
124
|
+
: contractTerms(document, gates ?? source.gates, prerequisites ?? source.after);
|
|
125
|
+
return {
|
|
126
|
+
terms,
|
|
127
|
+
verification: documentDerivation(document, terms.gates, this.id).verification,
|
|
128
|
+
};
|
|
129
|
+
},
|
|
130
|
+
}));
|
|
131
|
+
const completed = await completeMutation({
|
|
132
|
+
...completionInput(this.scope, channel, this.id, () => undefined, hooks),
|
|
133
|
+
accepted,
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
completed,
|
|
137
|
+
document: decodeContractDocument(accepted.value.terms.document.bytes),
|
|
138
|
+
changedSections,
|
|
139
|
+
documentDiff: documentDiff("before", "after", accepted.value.source.document.bytes, accepted.value.terms.document.bytes),
|
|
140
|
+
};
|
|
141
|
+
});
|
|
142
|
+
const regionObservation = await observeChangedRegion(this.scope, this.id, amendment.changedSections, amendment.document.region);
|
|
143
|
+
return {
|
|
144
|
+
...amendment.completed,
|
|
145
|
+
documentDiff: amendment.documentDiff,
|
|
146
|
+
...regionObservation,
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
async deliver(input) {
|
|
150
|
+
const values = input === undefined ? undefined : requireInput(input, "deliver input");
|
|
151
|
+
const hooks = worktreeHooksOption(values?.hooks);
|
|
152
|
+
const message = optionalNonblank(values?.message, "deliver message");
|
|
153
|
+
const requireBranchesToBeUpToDate = optionalBoolean(values?.requireBranchesToBeUpToDate, "requireBranchesToBeUpToDate") ?? false;
|
|
154
|
+
const includeDirty = optionalBoolean(values?.includeDirty, "includeDirty") ?? false;
|
|
155
|
+
const materializeConflict = optionalBoolean(values?.materializeConflict, "materializeConflict") ?? false;
|
|
156
|
+
const actor = actorOption(values?.actor);
|
|
157
|
+
const signal = optionalSignal(values?.signal);
|
|
158
|
+
const channel = executionChannel(this.execution);
|
|
159
|
+
const result = channel.kind === "local"
|
|
160
|
+
? await executeLocalDelivery({
|
|
161
|
+
scope: this.scope,
|
|
162
|
+
contractId: this.id,
|
|
163
|
+
...actor,
|
|
164
|
+
...(message === undefined ? {} : { message }),
|
|
165
|
+
requireBranchesToBeUpToDate,
|
|
166
|
+
includeDirty,
|
|
167
|
+
materializeConflict,
|
|
168
|
+
...(signal === undefined ? {} : { signal }),
|
|
169
|
+
hooks,
|
|
170
|
+
})
|
|
171
|
+
: await requestForwardedContractLive({
|
|
172
|
+
directory: channel.directory,
|
|
173
|
+
action: "contract.deliver",
|
|
174
|
+
request: {
|
|
175
|
+
action: "contract.deliver",
|
|
176
|
+
repoRoot: this.scope.primaryWorktree,
|
|
177
|
+
contractId: this.id,
|
|
178
|
+
...(message === undefined ? {} : { message }),
|
|
179
|
+
includeDirty,
|
|
180
|
+
materializeConflict,
|
|
181
|
+
},
|
|
182
|
+
...(signal === undefined ? {} : { signal }),
|
|
183
|
+
});
|
|
184
|
+
return "facts" in result ? { ...result, value: this.deliveryHandle(result.value) } : result;
|
|
185
|
+
}
|
|
186
|
+
async review(input) {
|
|
187
|
+
const values = requireInput(input, "review input");
|
|
188
|
+
const hooks = worktreeHooksOption(values.hooks);
|
|
189
|
+
const verdict = values.verdict;
|
|
190
|
+
if (verdict !== "satisfied" && verdict !== "unsatisfied") {
|
|
191
|
+
return invalidInput("verdict must be satisfied or unsatisfied");
|
|
192
|
+
}
|
|
193
|
+
const summary = optionalNonblank(values.summary, "review summary");
|
|
194
|
+
const actor = actorOption(values.actor);
|
|
195
|
+
const channel = executionChannel(this.execution);
|
|
196
|
+
if (channel.kind === "body-request") {
|
|
197
|
+
return await requestForwardedContractLive({
|
|
198
|
+
directory: channel.directory,
|
|
199
|
+
action: "contract.review",
|
|
200
|
+
request: {
|
|
201
|
+
action: "contract.review",
|
|
202
|
+
repoRoot: this.scope.primaryWorktree,
|
|
203
|
+
contractId: this.id,
|
|
204
|
+
verdict,
|
|
205
|
+
...(summary === undefined ? {} : { summary }),
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return await executeLocalReview({
|
|
210
|
+
scope: this.scope,
|
|
211
|
+
contractId: this.id,
|
|
212
|
+
...actor,
|
|
213
|
+
verdict,
|
|
214
|
+
...(summary === undefined ? {} : { summary }),
|
|
215
|
+
hooks,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
async abandon(input) {
|
|
219
|
+
const values = input === undefined ? undefined : requireInput(input, "abandon input");
|
|
220
|
+
const hooks = worktreeHooksOption(values?.hooks);
|
|
221
|
+
const note = optionalNonblank(values?.note, "abandon note");
|
|
222
|
+
return withGitDecodeChannel(this.scope, async (channel) => {
|
|
223
|
+
const admission = await releaseTaskHolderWithFence(this.scope, channel, this.id, () => abandonOperation({
|
|
224
|
+
scope: this.scope,
|
|
225
|
+
channel,
|
|
226
|
+
contractId: this.id,
|
|
227
|
+
...actorOption(values?.actor),
|
|
228
|
+
...(note === undefined ? {} : { note }),
|
|
229
|
+
observationSelection: taskHolderObservationSelection(),
|
|
230
|
+
decorateOffer: async ({ observation, contractId: owner }) => {
|
|
231
|
+
const companion = await releaseTaskHolder(channel, observation, owner);
|
|
232
|
+
return companion === null ? [] : [companion];
|
|
233
|
+
},
|
|
234
|
+
}));
|
|
235
|
+
return completeHolderMutation({
|
|
236
|
+
completion: completionInput(this.scope, channel, this.id, () => undefined, hooks),
|
|
237
|
+
admission,
|
|
238
|
+
requireAccepted,
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
async arc(input) {
|
|
243
|
+
const values = requireInput(input, "arc input");
|
|
244
|
+
const hooks = worktreeHooksOption(values.hooks);
|
|
245
|
+
const chapter = decodeArcDocument(requireMarkdown(values.markdown));
|
|
246
|
+
return withGitDecodeChannel(this.scope, async (channel) => {
|
|
247
|
+
const accepted = requireAccepted(await arcOperation({
|
|
248
|
+
scope: this.scope,
|
|
249
|
+
channel,
|
|
250
|
+
contractId: this.id,
|
|
251
|
+
...actorOption(values.actor),
|
|
252
|
+
chapter,
|
|
253
|
+
}));
|
|
254
|
+
return completeMutation({
|
|
255
|
+
...completionInput(this.scope, channel, this.id, () => undefined, hooks),
|
|
256
|
+
accepted,
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
async audit(input) {
|
|
261
|
+
const channel = executionChannel(this.execution);
|
|
262
|
+
if (channel.kind === "body-request") {
|
|
263
|
+
const values = input === undefined ? undefined : requireInput(input, "audit input");
|
|
264
|
+
worktreeHooksOption(values?.hooks);
|
|
265
|
+
actorOption(values?.actor);
|
|
266
|
+
const includeDirty = optionalBoolean(values?.includeDirty, "includeDirty") ?? false;
|
|
267
|
+
const showDiff = optionalBoolean(values?.showDiff, "showDiff") ?? false;
|
|
268
|
+
const requireBranchesToBeUpToDate = optionalBoolean(values?.requireBranchesToBeUpToDate, "requireBranchesToBeUpToDate") ?? false;
|
|
269
|
+
const signal = optionalSignal(values?.signal);
|
|
270
|
+
return await requestForwardedContractLive({
|
|
271
|
+
directory: channel.directory,
|
|
272
|
+
action: "contract.audit",
|
|
273
|
+
request: {
|
|
274
|
+
action: "contract.audit",
|
|
275
|
+
repoRoot: this.scope.primaryWorktree,
|
|
276
|
+
contractId: this.id,
|
|
277
|
+
includeDirty,
|
|
278
|
+
showDiff,
|
|
279
|
+
requireBranchesToBeUpToDate,
|
|
280
|
+
},
|
|
281
|
+
...(signal === undefined ? {} : { signal }),
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
return auditContract({
|
|
285
|
+
scope: this.scope,
|
|
286
|
+
contractId: this.id,
|
|
287
|
+
...(input === undefined ? {} : { input }),
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
async reconcile(input) {
|
|
291
|
+
const options = reconcileInput(input);
|
|
292
|
+
return withGitDecodeChannel(this.scope, (channel) => completeReconcile({
|
|
293
|
+
scope: this.scope,
|
|
294
|
+
channel,
|
|
295
|
+
contractId: this.id,
|
|
296
|
+
...options,
|
|
297
|
+
}));
|
|
298
|
+
}
|
|
299
|
+
deliveryHandle(delivery) {
|
|
300
|
+
return deliveryHandle(delivery, () => deliveryDiffOperation({
|
|
301
|
+
scope: this.scope,
|
|
302
|
+
integrationPredecessor: delivery.integration.predecessor,
|
|
303
|
+
integrationSnapshot: delivery.integration.snapshot,
|
|
304
|
+
}));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
const KEIYAKU_SEATS = new WeakMap();
|
|
308
|
+
/** Internal package composition capability; not exported from the package root. */
|
|
309
|
+
export function seatForKeiyaku(value) {
|
|
310
|
+
return value !== null && (typeof value === "object" || typeof value === "function")
|
|
311
|
+
? (KEIYAKU_SEATS.get(value) ?? null)
|
|
312
|
+
: null;
|
|
313
|
+
}
|