@astrosheep/keiyaku 4.5.19 → 4.5.21
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 +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +14 -7
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +53 -20
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md +237 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +6 -7
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +2 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -3
- package/build/src/akuma/akuma-handle.d.ts +5 -1
- package/build/src/akuma/akuma-handle.js +4 -1
- package/build/src/akuma/akuma-instance.d.ts +7 -2
- package/build/src/akuma/akuma-instance.js +14 -7
- package/build/src/akuma/akuma-observe.d.ts +11 -0
- package/build/src/akuma/akuma-observe.js +23 -0
- package/build/src/akuma/akuma-product.d.ts +2 -0
- package/build/src/akuma/akuma-product.js +6 -0
- package/build/src/akuma/akuma.d.ts +20 -1
- package/build/src/akuma/akuma.js +2 -0
- package/build/src/akuma/allowed.d.ts +20 -0
- package/build/src/akuma/allowed.js +11 -0
- package/build/src/akuma/archetype.js +3 -0
- package/build/src/akuma/body.d.ts +25 -5
- package/build/src/akuma/body.js +70 -31
- package/build/src/akuma/call-request.d.ts +5 -0
- package/build/src/akuma/call-request.js +14 -4
- package/build/src/akuma/fleet-execution.d.ts +28 -0
- package/build/src/akuma/fleet-execution.js +36 -4
- package/build/src/akuma/fleet-observation.d.ts +54 -0
- package/build/src/akuma/fleet-request.d.ts +10 -0
- package/build/src/akuma/fleet-request.js +13 -3
- package/build/src/akuma/heart/facts.d.ts +2 -0
- package/build/src/akuma/heart/index.d.ts +1 -0
- package/build/src/akuma/heart/index.js +4 -1
- package/build/src/akuma/heart/rows.d.ts +2 -0
- package/build/src/akuma/heart/rows.js +7 -5
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +3 -1
- package/build/src/akuma/heart/tells.js +6 -5
- package/build/src/akuma/heart/timeline.js +1 -1
- package/build/src/akuma/provider-recipe.d.ts +1 -0
- package/build/src/akuma/provider-recipe.js +5 -0
- package/build/src/akuma/provider.d.ts +1 -1
- package/build/src/akuma/provider.js +1 -1
- package/build/src/akuma/providers/acp/core.js +3 -6
- package/build/src/akuma/providers/acp/index.js +3 -0
- package/build/src/akuma/providers/claude/index.js +10 -10
- package/build/src/akuma/providers/codex-app-server/index.js +12 -11
- package/build/src/akuma/providers/execution-environment.d.ts +6 -0
- package/build/src/akuma/providers/execution-environment.js +24 -0
- package/build/src/akuma/providers/grok-build/index.js +3 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +32 -23
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +8 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +6 -5
- package/build/src/akuma/providers/pi/events.js +7 -2
- package/build/src/akuma/providers/pi/index.js +5 -2
- package/build/src/akuma/request-observation.d.ts +45 -0
- package/build/src/akuma/request-observation.js +162 -0
- package/build/src/akuma/request-rendezvous.d.ts +6 -3
- package/build/src/akuma/request-rendezvous.js +80 -14
- package/build/src/akuma/request-serve.js +27 -4
- package/build/src/akuma/request-wire.d.ts +5 -0
- package/build/src/akuma/request-wire.js +2 -0
- package/build/src/akuma/turn-drive.d.ts +1 -0
- package/build/src/akuma/turn-drive.js +2 -0
- package/build/src/akuma-body.js +5 -0
- package/build/src/body/amend.js +6 -4
- package/build/src/body/decode.d.ts +3 -1
- package/build/src/body/decode.js +53 -17
- package/build/src/body/region.d.ts +9 -1
- package/build/src/body/region.js +87 -12
- package/build/src/body/render.js +1 -1
- package/build/src/body/verification.d.ts +3 -1
- package/build/src/body/verification.js +4 -1
- package/build/src/cli/accepted.js +19 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +3 -1
- package/build/src/cli/commands/akuma-invoke.js +134 -14
- package/build/src/cli/commands/akuma.js +24 -12
- package/build/src/cli/commands/contract-help.d.ts +15 -15
- package/build/src/cli/commands/contract-help.js +45 -19
- package/build/src/cli/commands/contract-invoke.d.ts +3 -0
- package/build/src/cli/commands/contract-invoke.js +25 -11
- package/build/src/cli/commands/contract.js +6 -4
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +1 -1
- package/build/src/cli/commands/status-set.js +15 -24
- package/build/src/cli/commands/task.js +18 -18
- package/build/src/cli/invoke.d.ts +3 -0
- package/build/src/cli/invoke.js +58 -23
- package/build/src/cli/main.js +5 -0
- package/build/src/cli/parse.d.ts +3 -0
- package/build/src/cli/parse.js +26 -4
- package/build/src/cli/render/akuma-activity.d.ts +100 -2
- package/build/src/cli/render/akuma-activity.js +485 -40
- package/build/src/cli/render/akuma.d.ts +10 -0
- package/build/src/cli/render/akuma.js +31 -21
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/board.js +1 -1
- package/build/src/cli/render/catalog.js +16 -13
- package/build/src/cli/render/contract-history.js +39 -10
- package/build/src/cli/render/contract-observation.js +10 -6
- package/build/src/cli/render/contract.js +109 -106
- package/build/src/cli/render/execution-progress.d.ts +26 -0
- package/build/src/cli/render/execution-progress.js +178 -0
- package/build/src/cli/render/kanshi-akuma.js +27 -39
- package/build/src/cli/render/kanshi.js +33 -26
- package/build/src/cli/render/nuke.js +1 -1
- package/build/src/cli/render/receipt.d.ts +1 -1
- package/build/src/cli/render/receipt.js +6 -6
- package/build/src/cli/render/refusal.js +10 -7
- package/build/src/cli/render/region.js +1 -1
- package/build/src/cli/render/settings.js +12 -2
- package/build/src/cli/render/status-line.d.ts +30 -0
- package/build/src/cli/render/status-line.js +58 -0
- package/build/src/cli/render/status-set.js +1 -1
- package/build/src/cli/render/task.d.ts +2 -0
- package/build/src/cli/render/task.js +11 -7
- package/build/src/cli/render/terminal.d.ts +0 -1
- package/build/src/cli/render/terminal.js +47 -15
- package/build/src/cli/result.d.ts +1 -0
- package/build/src/cli/runtime.d.ts +2 -0
- package/build/src/cli/runtime.js +36 -4
- package/build/src/cli/usage.js +2 -2
- package/build/src/cli/version.d.ts +1 -0
- package/build/src/cli/version.js +25 -0
- package/build/src/git/hooks.d.ts +13 -1
- package/build/src/git/hooks.js +2 -1
- package/build/src/git/workspace.d.ts +1 -1
- package/build/src/git/workspace.js +1 -1
- package/build/src/identity/mint.d.ts +13 -0
- package/build/src/identity/mint.js +26 -0
- package/build/src/identity/normalize.d.ts +4 -0
- package/build/src/identity/normalize.js +30 -0
- package/build/src/index.d.ts +2 -0
- package/build/src/index.js +1 -0
- package/build/src/kanshi/read.js +17 -4
- package/build/src/kanshi/report.d.ts +1 -0
- package/build/src/library/akuma-creation.d.ts +2 -0
- package/build/src/library/akuma-creation.js +34 -18
- package/build/src/library/audit.d.ts +2 -0
- package/build/src/library/audit.js +1 -0
- package/build/src/library/bind.js +18 -16
- package/build/src/library/composition.d.ts +1 -0
- package/build/src/library/contract-bind.d.ts +3 -1
- package/build/src/library/contract-bind.js +5 -3
- package/build/src/library/contract-execution.d.ts +2 -0
- package/build/src/library/contract-execution.js +15 -1
- package/build/src/library/contract-forwarding.d.ts +4 -0
- package/build/src/library/contract-forwarding.js +3 -0
- package/build/src/library/contract-handle.d.ts +7 -0
- package/build/src/library/contract-handle.js +25 -0
- package/build/src/library/contract-operations.d.ts +7 -2
- package/build/src/library/contract-operations.js +21 -1
- package/build/src/library/contract-types.d.ts +1 -0
- package/build/src/library/execution-result.d.ts +2 -2
- package/build/src/library/execution.d.ts +8 -0
- package/build/src/library/execution.js +102 -0
- package/build/src/library/fleet.d.ts +4 -1
- package/build/src/library/fleet.js +32 -8
- package/build/src/library/keiyaku.d.ts +2 -0
- package/build/src/library/mutation.js +15 -7
- package/build/src/plugin/akuma-signals.d.ts +6 -0
- package/build/src/plugin/akuma-signals.js +9 -1
- package/build/src/plugin/public.d.ts +6 -2
- package/build/src/plugin/runtime.d.ts +1 -3
- package/build/src/plugin/runtime.js +95 -103
- package/build/src/protocol/amend.js +4 -3
- package/build/src/protocol/attempt.d.ts +2 -0
- package/build/src/protocol/bind.js +41 -14
- package/build/src/protocol/completion.d.ts +3 -0
- package/build/src/protocol/completion.js +35 -11
- package/build/src/protocol/deliver.js +165 -92
- package/build/src/protocol/execution-observation.d.ts +181 -0
- package/build/src/protocol/execution-observation.js +45 -0
- package/build/src/protocol/intent.d.ts +18 -22
- package/build/src/protocol/intent.js +63 -41
- package/build/src/protocol/operations.d.ts +2 -0
- package/build/src/protocol/placement.js +5 -1
- package/build/src/protocol/progress.d.ts +5 -1
- package/build/src/protocol/progress.js +10 -1
- package/build/src/protocol/read/status.d.ts +1 -0
- package/build/src/protocol/read/status.js +10 -2
- package/build/src/protocol/reintegrate.d.ts +1 -1
- package/build/src/protocol/reintegrate.js +70 -43
- package/build/src/protocol/result-codec.js +27 -11
- package/build/src/protocol/review.js +53 -30
- package/build/src/protocol/run.d.ts +83 -36
- package/build/src/protocol/run.js +90 -75
- package/build/src/runtime/proc/run.d.ts +16 -4
- package/build/src/runtime/proc/run.js +64 -22
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settings.js +5 -14
- package/build/src/task/document.d.ts +5 -1
- package/build/src/task/document.js +6 -1
- package/build/src/verification/execution.d.ts +10 -2
- package/build/src/verification/execution.js +143 -42
- package/build/src/verification/observation.d.ts +41 -0
- package/build/src/verification/observation.js +29 -0
- package/package.json +3 -1
|
@@ -26,7 +26,7 @@ function retainTrailingFailure(context, operation, error) {
|
|
|
26
26
|
}
|
|
27
27
|
/** The channel's own retirement cannot hide an already returned admission. */
|
|
28
28
|
export async function withContractExecution(input, operation, run) {
|
|
29
|
-
const progress = new ExecutionProgress();
|
|
29
|
+
const progress = new ExecutionProgress(input.observe);
|
|
30
30
|
const scope = withScopeAbortSignal(input.scope, input.signal);
|
|
31
31
|
let produced;
|
|
32
32
|
try {
|
|
@@ -71,6 +71,13 @@ async function advanceAndContinue(context, checkpoint, start) {
|
|
|
71
71
|
...(context.actor === undefined ? {} : { actor: context.actor }),
|
|
72
72
|
...(context.signal === undefined ? {} : { signal: context.signal }),
|
|
73
73
|
});
|
|
74
|
+
if (result.kind === "completed")
|
|
75
|
+
context.progress.observe({
|
|
76
|
+
kind: "stage",
|
|
77
|
+
contractId: context.contractId,
|
|
78
|
+
stage: "continuation",
|
|
79
|
+
state: "started",
|
|
80
|
+
});
|
|
74
81
|
const continuation = result.kind !== "completed"
|
|
75
82
|
? undefined
|
|
76
83
|
: await continueDeliveredDependents({
|
|
@@ -78,6 +85,13 @@ async function advanceAndContinue(context, checkpoint, start) {
|
|
|
78
85
|
completed: result,
|
|
79
86
|
deriveDocument: derivedDocument,
|
|
80
87
|
});
|
|
88
|
+
if (result.kind === "completed")
|
|
89
|
+
context.progress.observe({
|
|
90
|
+
kind: "stage",
|
|
91
|
+
contractId: context.contractId,
|
|
92
|
+
stage: "continuation",
|
|
93
|
+
state: "finished",
|
|
94
|
+
});
|
|
81
95
|
return { ...result.evidence, ...(continuation === undefined ? {} : { continuation }) };
|
|
82
96
|
}
|
|
83
97
|
/** Review records testimony, then the same shared node judges automatic placement. */
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ActorId, ContractId } from "../core/facts/types.js";
|
|
2
|
+
import type { ExecutionObserver } from "../protocol/execution-observation.js";
|
|
2
3
|
import type { IntegrationConflictMaterialized } from "../protocol/deliver.js";
|
|
3
4
|
import type { AuditReport } from "../protocol/audit.js";
|
|
4
5
|
import { type AuditComposition } from "./audit.js";
|
|
@@ -20,6 +21,7 @@ export declare function executeForwardedDeliver(input: Readonly<{
|
|
|
20
21
|
requireBranchesToBeUpToDate: boolean;
|
|
21
22
|
hooks: Parameters<typeof executeLocalDelivery>[0]["hooks"];
|
|
22
23
|
signal?: AbortSignal;
|
|
24
|
+
observe?: ExecutionObserver;
|
|
23
25
|
}>): Promise<Readonly<{
|
|
24
26
|
result: MutationResult<DeliveryValue> | IntegrationConflictMaterialized;
|
|
25
27
|
deliveryFactId?: string;
|
|
@@ -32,6 +34,7 @@ export declare function executeForwardedReview(input: Readonly<{
|
|
|
32
34
|
summary?: string;
|
|
33
35
|
signal?: AbortSignal;
|
|
34
36
|
hooks: Parameters<typeof executeLocalReview>[0]["hooks"];
|
|
37
|
+
observe?: ExecutionObserver;
|
|
35
38
|
}>): Promise<Readonly<{
|
|
36
39
|
result: MutationResult<Review>;
|
|
37
40
|
reviewFactId?: string;
|
|
@@ -45,6 +48,7 @@ export declare function executeForwardedAudit(input: Readonly<{
|
|
|
45
48
|
requireBranchesToBeUpToDate: boolean;
|
|
46
49
|
hooks: NonNullable<AuditComposition["hooks"]>;
|
|
47
50
|
signal?: AbortSignal;
|
|
51
|
+
observe?: ExecutionObserver;
|
|
48
52
|
}>): Promise<Readonly<{
|
|
49
53
|
result: MutationResult<AuditReport>;
|
|
50
54
|
auditReport?: AuditReport;
|
|
@@ -16,6 +16,7 @@ export async function executeForwardedDeliver(input) {
|
|
|
16
16
|
overwrite: input.overwrite ?? false,
|
|
17
17
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
18
18
|
hooks: input.hooks,
|
|
19
|
+
...(input.observe === undefined ? {} : { observe: input.observe }),
|
|
19
20
|
});
|
|
20
21
|
if (result.kind !== "accepted")
|
|
21
22
|
return { result };
|
|
@@ -38,6 +39,7 @@ export async function executeForwardedReview(input) {
|
|
|
38
39
|
verdict: input.verdict,
|
|
39
40
|
...(input.summary === undefined ? {} : { summary: input.summary }),
|
|
40
41
|
hooks: input.hooks,
|
|
42
|
+
...(input.observe === undefined ? {} : { observe: input.observe }),
|
|
41
43
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
42
44
|
});
|
|
43
45
|
const review = result.facts.find((fact) => fact.kind === "attestation");
|
|
@@ -49,6 +51,7 @@ export async function executeForwardedAudit(input) {
|
|
|
49
51
|
const result = await auditContract({
|
|
50
52
|
scope: scopeForRepo(input.repo),
|
|
51
53
|
contractId: input.contractId,
|
|
54
|
+
...(input.observe === undefined ? {} : { observe: input.observe }),
|
|
52
55
|
input: {
|
|
53
56
|
includeDirty: input.includeDirty,
|
|
54
57
|
showDiff: input.showDiff,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ContractExecution } from "./execution.js";
|
|
1
2
|
import { type ContractId, type ContractState } from "../core/facts/types.js";
|
|
2
3
|
import { type RepositoryScope } from "../protocol/operations.js";
|
|
3
4
|
import type { AuditReport } from "../protocol/audit.js";
|
|
@@ -22,11 +23,17 @@ export declare class KeiyakuHandle {
|
|
|
22
23
|
guidance(): Promise<string>;
|
|
23
24
|
delivery(): Promise<Delivery | null>;
|
|
24
25
|
amend(input: AmendInput): Promise<AmendResult>;
|
|
26
|
+
startDelivery(input?: DeliverInput): ContractExecution<MutationResult<Delivery> | IntegrationConflictMaterialized>;
|
|
25
27
|
deliver(input?: DeliverInput): Promise<MutationResult<Delivery> | IntegrationConflictMaterialized>;
|
|
28
|
+
private runDelivery;
|
|
29
|
+
startReview(input: ReviewInput): ContractExecution<MutationResult<Review>>;
|
|
26
30
|
review(input: ReviewInput): Promise<MutationResult<Review>>;
|
|
31
|
+
private runReview;
|
|
27
32
|
abandon(input?: AbandonInput): Promise<MutationResult<void>>;
|
|
28
33
|
arc(input: ArcInput): Promise<MutationResult<void>>;
|
|
34
|
+
startAudit(input?: AuditInput): ContractExecution<MutationResult<AuditReport>>;
|
|
29
35
|
audit(input?: AuditInput): Promise<MutationResult<AuditReport>>;
|
|
36
|
+
private runAudit;
|
|
30
37
|
reconcile(input?: ReconcileInput): Promise<ReconcileReport>;
|
|
31
38
|
private deliveryHandle;
|
|
32
39
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** @architectureCompositionRoot */
|
|
2
2
|
import { documentDiff } from "../markdown/diff.js";
|
|
3
|
+
import { startContractExecution } from "./execution.js";
|
|
3
4
|
import { applyAmendDocument } from "../body/amend.js";
|
|
4
5
|
import { decodeArcDocument } from "../body/arc.js";
|
|
5
6
|
import { decodeContractDocument } from "../body/decode.js";
|
|
@@ -156,7 +157,13 @@ export class KeiyakuHandle {
|
|
|
156
157
|
...regionObservation,
|
|
157
158
|
};
|
|
158
159
|
}
|
|
160
|
+
startDelivery(input) {
|
|
161
|
+
return startContractExecution((observe) => this.runDelivery(input, observe));
|
|
162
|
+
}
|
|
159
163
|
async deliver(input) {
|
|
164
|
+
return this.startDelivery(input).result;
|
|
165
|
+
}
|
|
166
|
+
async runDelivery(input, observe) {
|
|
160
167
|
const values = input === undefined
|
|
161
168
|
? undefined
|
|
162
169
|
: requireInput(input, "deliver input", [
|
|
@@ -184,10 +191,12 @@ export class KeiyakuHandle {
|
|
|
184
191
|
overwrite,
|
|
185
192
|
...(signal === undefined ? {} : { signal }),
|
|
186
193
|
hooks: this.composition.hooks,
|
|
194
|
+
observe,
|
|
187
195
|
})
|
|
188
196
|
: await requestForwardedContractLive({
|
|
189
197
|
directory: channel.directory,
|
|
190
198
|
action: "contract.deliver",
|
|
199
|
+
observe,
|
|
191
200
|
request: {
|
|
192
201
|
action: "contract.deliver",
|
|
193
202
|
repoRoot: this.scope.primaryWorktree,
|
|
@@ -201,7 +210,13 @@ export class KeiyakuHandle {
|
|
|
201
210
|
});
|
|
202
211
|
return "facts" in result ? { ...result, value: this.deliveryHandle(result.value) } : result;
|
|
203
212
|
}
|
|
213
|
+
startReview(input) {
|
|
214
|
+
return startContractExecution((observe) => this.runReview(input, observe));
|
|
215
|
+
}
|
|
204
216
|
async review(input) {
|
|
217
|
+
return this.startReview(input).result;
|
|
218
|
+
}
|
|
219
|
+
async runReview(input, observe) {
|
|
205
220
|
const values = requireInput(input, "review input", ["verdict", "summary", "signal"]);
|
|
206
221
|
const verdict = values.verdict;
|
|
207
222
|
if (verdict !== "satisfied" && verdict !== "unsatisfied") {
|
|
@@ -214,6 +229,7 @@ export class KeiyakuHandle {
|
|
|
214
229
|
return await requestForwardedContractLive({
|
|
215
230
|
directory: channel.directory,
|
|
216
231
|
action: "contract.review",
|
|
232
|
+
observe,
|
|
217
233
|
...(signal === undefined ? {} : { signal }),
|
|
218
234
|
request: {
|
|
219
235
|
action: "contract.review",
|
|
@@ -231,6 +247,7 @@ export class KeiyakuHandle {
|
|
|
231
247
|
verdict,
|
|
232
248
|
...(summary === undefined ? {} : { summary }),
|
|
233
249
|
hooks: this.composition.hooks,
|
|
250
|
+
observe,
|
|
234
251
|
...(signal === undefined ? {} : { signal }),
|
|
235
252
|
});
|
|
236
253
|
}
|
|
@@ -290,7 +307,13 @@ export class KeiyakuHandle {
|
|
|
290
307
|
});
|
|
291
308
|
});
|
|
292
309
|
}
|
|
310
|
+
startAudit(input) {
|
|
311
|
+
return startContractExecution((observe) => this.runAudit(input, observe));
|
|
312
|
+
}
|
|
293
313
|
async audit(input) {
|
|
314
|
+
return this.startAudit(input).result;
|
|
315
|
+
}
|
|
316
|
+
async runAudit(input, observe) {
|
|
294
317
|
const values = input === undefined ? undefined : requireInput(input, "audit input", ["includeDirty", "showDiff", "signal"]);
|
|
295
318
|
const includeDirty = optionalBoolean(values?.includeDirty, "includeDirty") ?? false;
|
|
296
319
|
const showDiff = optionalBoolean(values?.showDiff, "showDiff") ?? false;
|
|
@@ -305,6 +328,7 @@ export class KeiyakuHandle {
|
|
|
305
328
|
return await requestForwardedContractLive({
|
|
306
329
|
directory: channel.directory,
|
|
307
330
|
action: "contract.audit",
|
|
331
|
+
observe,
|
|
308
332
|
request: {
|
|
309
333
|
action: "contract.audit",
|
|
310
334
|
repoRoot: this.scope.primaryWorktree,
|
|
@@ -320,6 +344,7 @@ export class KeiyakuHandle {
|
|
|
320
344
|
contractId: this.id,
|
|
321
345
|
input: auditInput,
|
|
322
346
|
composition: this.composition,
|
|
347
|
+
observe,
|
|
323
348
|
});
|
|
324
349
|
}
|
|
325
350
|
async reconcile(input) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ExecutionObserver } from "../protocol/execution-observation.js";
|
|
1
2
|
import { type ErasedRequestCommand, type RequestProtocol, type ServiceRequestCommand } from "../akuma/request-wire.js";
|
|
2
3
|
import type { AuditReport } from "../protocol/audit.js";
|
|
3
4
|
import type { IntegrationConflictMaterialized } from "../protocol/deliver.js";
|
|
@@ -90,7 +91,7 @@ declare const materializedHandoffReferenceSchema: z.ZodObject<{
|
|
|
90
91
|
handoffBase: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
|
|
91
92
|
recovery: z.ZodObject<{
|
|
92
93
|
materialize: z.ZodLiteral<"deliver --materialize-conflict --include-dirty">;
|
|
93
|
-
|
|
94
|
+
deliver: z.ZodLiteral<"deliver --include-dirty">;
|
|
94
95
|
staging: z.ZodLiteral<"not-required">;
|
|
95
96
|
}, z.core.$strict>;
|
|
96
97
|
conflictPaths: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<readonly string[], string[]>>;
|
|
@@ -215,7 +216,7 @@ declare const contractServiceSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
|
215
216
|
handoffBase: z.ZodPipe<z.ZodString, z.ZodTransform<import("../core/facts/types.js").SnapshotId, string>>;
|
|
216
217
|
recovery: z.ZodObject<{
|
|
217
218
|
materialize: z.ZodLiteral<"deliver --materialize-conflict --include-dirty">;
|
|
218
|
-
|
|
219
|
+
deliver: z.ZodLiteral<"deliver --include-dirty">;
|
|
219
220
|
staging: z.ZodLiteral<"not-required">;
|
|
220
221
|
}, z.core.$strict>;
|
|
221
222
|
conflictPaths: z.ZodPipe<z.ZodArray<z.ZodString>, z.ZodTransform<readonly string[], string[]>>;
|
|
@@ -235,6 +236,7 @@ export type ContractRequestPort = Readonly<{
|
|
|
235
236
|
audit(input: AuditRequest & Readonly<{
|
|
236
237
|
requester: ContractRequester;
|
|
237
238
|
signal: AbortSignal;
|
|
239
|
+
observe?: ExecutionObserver;
|
|
238
240
|
}>): Promise<Readonly<{
|
|
239
241
|
result: AuditResult;
|
|
240
242
|
auditReport?: AuditReport;
|
|
@@ -242,6 +244,7 @@ export type ContractRequestPort = Readonly<{
|
|
|
242
244
|
deliver(input: DeliverRequest & Readonly<{
|
|
243
245
|
requester: ContractRequester;
|
|
244
246
|
signal: AbortSignal;
|
|
247
|
+
observe?: ExecutionObserver;
|
|
245
248
|
}>): Promise<Readonly<{
|
|
246
249
|
result: DeliveryResult;
|
|
247
250
|
deliveryFactId?: string;
|
|
@@ -249,6 +252,7 @@ export type ContractRequestPort = Readonly<{
|
|
|
249
252
|
review(input: ReviewRequest & Readonly<{
|
|
250
253
|
requester: ContractRequester;
|
|
251
254
|
signal: AbortSignal;
|
|
255
|
+
observe?: ExecutionObserver;
|
|
252
256
|
}>): Promise<Readonly<{
|
|
253
257
|
result: ReviewResult;
|
|
254
258
|
reviewFactId?: string;
|
|
@@ -262,6 +266,7 @@ export declare function requestForwardedContractLive<Action extends ContractRequ
|
|
|
262
266
|
action: Action;
|
|
263
267
|
request: ContractRequestFor<Action>;
|
|
264
268
|
signal?: AbortSignal;
|
|
269
|
+
observe?: ExecutionObserver;
|
|
265
270
|
}>): Promise<ContractResultFor<Action>>;
|
|
266
271
|
export { executeLocalDelivery, executeLocalReview, executeForwardedAudit, executeForwardedDeliver, executeForwardedReview, } from "./contract-forwarding.js";
|
|
267
272
|
export type { AttestationVerdict, DeliveryExecutionInput, Review, ReviewExecutionInput, } from "./contract-forwarding.js";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { executionReceipt } from "./execution-result.js";
|
|
2
|
+
import { decodeExecutionEvent, observeExecution } from "../protocol/execution-observation.js";
|
|
2
3
|
import { contractId, snapshotId } from "../core/facts/types.js";
|
|
3
4
|
import { AkumaBodyRequestError, requestBodyCommand } from "../akuma/request-rendezvous.js";
|
|
4
5
|
import { eraseRequestCommand, } from "../akuma/request-wire.js";
|
|
@@ -30,7 +31,7 @@ const contractRequestBaseSchema = z.object({ repoRoot: absolutePathSchema, contr
|
|
|
30
31
|
const conflictRecoverySchema = z
|
|
31
32
|
.object({
|
|
32
33
|
materialize: z.literal("deliver --materialize-conflict --include-dirty"),
|
|
33
|
-
|
|
34
|
+
deliver: z.literal("deliver --include-dirty"),
|
|
34
35
|
staging: z.literal("not-required"),
|
|
35
36
|
})
|
|
36
37
|
.strict();
|
|
@@ -138,10 +139,17 @@ function decodeContractReference(action, value) {
|
|
|
138
139
|
throw new Error(`malformed stored Contract service evidence for ${action}`);
|
|
139
140
|
return parsed.data;
|
|
140
141
|
}
|
|
142
|
+
function executionObservation(facts) {
|
|
143
|
+
if (facts.progress === undefined)
|
|
144
|
+
return {};
|
|
145
|
+
return { observe: (event) => facts.progress?.(event) };
|
|
146
|
+
}
|
|
141
147
|
async function executeContractRequest(request, facts, port) {
|
|
148
|
+
const observation = executionObservation(facts);
|
|
142
149
|
if (request.action === "contract.audit") {
|
|
143
150
|
const served = await port.audit({
|
|
144
151
|
...request,
|
|
152
|
+
...observation,
|
|
145
153
|
requester: facts.requester,
|
|
146
154
|
signal: facts.signal,
|
|
147
155
|
});
|
|
@@ -160,6 +168,7 @@ async function executeContractRequest(request, facts, port) {
|
|
|
160
168
|
if (request.action === "contract.deliver") {
|
|
161
169
|
const served = await port.deliver({
|
|
162
170
|
...request,
|
|
171
|
+
...observation,
|
|
163
172
|
overwrite: request.overwrite ?? false,
|
|
164
173
|
requester: facts.requester,
|
|
165
174
|
signal: facts.signal,
|
|
@@ -193,6 +202,7 @@ async function executeContractRequest(request, facts, port) {
|
|
|
193
202
|
}
|
|
194
203
|
const served = await port.review({
|
|
195
204
|
...request,
|
|
205
|
+
...observation,
|
|
196
206
|
requester: facts.requester,
|
|
197
207
|
signal: facts.signal,
|
|
198
208
|
});
|
|
@@ -222,6 +232,7 @@ function decodedContractResult(action, value) {
|
|
|
222
232
|
export function contractRequestProtocol(action) {
|
|
223
233
|
return {
|
|
224
234
|
action,
|
|
235
|
+
supportsCancellation: true,
|
|
225
236
|
encodeRequest: (request) => {
|
|
226
237
|
const { action: _action, ...payload } = request;
|
|
227
238
|
return payload;
|
|
@@ -258,6 +269,15 @@ export async function requestForwardedContractLive(input) {
|
|
|
258
269
|
directory: input.directory,
|
|
259
270
|
command,
|
|
260
271
|
value: input.request,
|
|
272
|
+
onProgress: (value) => {
|
|
273
|
+
try {
|
|
274
|
+
observeExecution(input.observe, decodeExecutionEvent(value));
|
|
275
|
+
}
|
|
276
|
+
catch {
|
|
277
|
+
observeExecution(input.observe, { kind: "progress-dropped", count: 1 });
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
onProgressGap: (count) => observeExecution(input.observe, { kind: "progress-dropped", count }),
|
|
261
281
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
262
282
|
}).catch((error) => {
|
|
263
283
|
if (error instanceof AkumaBodyRequestError &&
|
|
@@ -13,6 +13,7 @@ import type { ContractWorkspaceLocation } from "../workspace-place.js";
|
|
|
13
13
|
export type BindResult = Readonly<Omit<MutationResult<Keiyaku>, "value"> & {
|
|
14
14
|
keiyaku: Keiyaku;
|
|
15
15
|
workspace?: ContractWorkspaceLocation;
|
|
16
|
+
warnings?: readonly string[];
|
|
16
17
|
} & RegionObservation>;
|
|
17
18
|
export type Fact = JournalEntry;
|
|
18
19
|
export type ContractHistoryEvent = Readonly<{
|
|
@@ -103,9 +103,9 @@ export declare const executionStopSchema: z.ZodObject<{
|
|
|
103
103
|
admission: "admission";
|
|
104
104
|
placement: "placement";
|
|
105
105
|
verification: "verification";
|
|
106
|
-
reintegration: "reintegration";
|
|
107
106
|
continuation: "continuation";
|
|
108
107
|
reconciliation: "reconciliation";
|
|
108
|
+
reintegration: "reintegration";
|
|
109
109
|
}>;
|
|
110
110
|
reason: z.ZodEnum<{
|
|
111
111
|
failed: "failed";
|
|
@@ -226,9 +226,9 @@ export declare const executionReceiptSchema: z.ZodObject<{
|
|
|
226
226
|
admission: "admission";
|
|
227
227
|
placement: "placement";
|
|
228
228
|
verification: "verification";
|
|
229
|
-
reintegration: "reintegration";
|
|
230
229
|
continuation: "continuation";
|
|
231
230
|
reconciliation: "reconciliation";
|
|
231
|
+
reintegration: "reintegration";
|
|
232
232
|
}>;
|
|
233
233
|
reason: z.ZodEnum<{
|
|
234
234
|
failed: "failed";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ExecutionEvent, ExecutionObserver } from "../protocol/execution-observation.js";
|
|
2
|
+
export type { ExecutionEvent } from "../protocol/execution-observation.js";
|
|
3
|
+
export type ContractExecution<Result> = Readonly<{
|
|
4
|
+
progress: AsyncIterable<ExecutionEvent>;
|
|
5
|
+
result: Promise<Result>;
|
|
6
|
+
}>;
|
|
7
|
+
/** An eager invocation with one bounded, optional progress subscription. */
|
|
8
|
+
export declare function startContractExecution<Result>(run: (observe: ExecutionObserver) => Promise<Result>): ContractExecution<Result>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
const MAX_EVENTS = 256;
|
|
2
|
+
const MAX_BYTES = 128 * 1024;
|
|
3
|
+
class BoundedExecutionProgress {
|
|
4
|
+
pending = [];
|
|
5
|
+
bytes = 0;
|
|
6
|
+
dropped = 0;
|
|
7
|
+
finished = false;
|
|
8
|
+
unsubscribed = false;
|
|
9
|
+
subscribed = false;
|
|
10
|
+
wake;
|
|
11
|
+
notify() {
|
|
12
|
+
const waiter = this.wake;
|
|
13
|
+
this.wake = undefined;
|
|
14
|
+
waiter?.();
|
|
15
|
+
}
|
|
16
|
+
publish = (event) => {
|
|
17
|
+
if (this.unsubscribed || this.finished)
|
|
18
|
+
return;
|
|
19
|
+
const size = Buffer.byteLength(JSON.stringify(event));
|
|
20
|
+
if (size > MAX_BYTES) {
|
|
21
|
+
this.dropped += 1;
|
|
22
|
+
this.notify();
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
while (this.pending.length >= MAX_EVENTS || this.bytes + size > MAX_BYTES) {
|
|
26
|
+
this.bytes -= this.pending.shift().bytes;
|
|
27
|
+
this.dropped += 1;
|
|
28
|
+
}
|
|
29
|
+
this.pending.push({ event, bytes: size });
|
|
30
|
+
this.bytes += size;
|
|
31
|
+
this.notify();
|
|
32
|
+
};
|
|
33
|
+
close() {
|
|
34
|
+
this.finished = true;
|
|
35
|
+
this.notify();
|
|
36
|
+
}
|
|
37
|
+
iterable() {
|
|
38
|
+
return {
|
|
39
|
+
[Symbol.asyncIterator]: () => this.iterator(),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
iterator() {
|
|
43
|
+
if (this.subscribed)
|
|
44
|
+
throw new Error("execution progress supports one subscription");
|
|
45
|
+
this.subscribed = true;
|
|
46
|
+
let reading = false;
|
|
47
|
+
return {
|
|
48
|
+
next: async () => {
|
|
49
|
+
if (reading)
|
|
50
|
+
throw new Error("execution progress next calls must be serial");
|
|
51
|
+
reading = true;
|
|
52
|
+
try {
|
|
53
|
+
for (;;) {
|
|
54
|
+
const next = await this.next();
|
|
55
|
+
if (next !== undefined)
|
|
56
|
+
return next;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
finally {
|
|
60
|
+
reading = false;
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
return: async () => {
|
|
64
|
+
this.unsubscribed = true;
|
|
65
|
+
this.pending.length = 0;
|
|
66
|
+
this.bytes = 0;
|
|
67
|
+
this.dropped = 0;
|
|
68
|
+
this.notify();
|
|
69
|
+
return { done: true, value: undefined };
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async next() {
|
|
74
|
+
if (this.unsubscribed)
|
|
75
|
+
return { done: true, value: undefined };
|
|
76
|
+
if (this.dropped > 0) {
|
|
77
|
+
const count = this.dropped;
|
|
78
|
+
this.dropped = 0;
|
|
79
|
+
return { done: false, value: { kind: "progress-dropped", count } };
|
|
80
|
+
}
|
|
81
|
+
const pending = this.pending.shift();
|
|
82
|
+
if (pending !== undefined) {
|
|
83
|
+
this.bytes -= pending.bytes;
|
|
84
|
+
return { done: false, value: pending.event };
|
|
85
|
+
}
|
|
86
|
+
if (this.finished)
|
|
87
|
+
return { done: true, value: undefined };
|
|
88
|
+
await new Promise((resolve) => {
|
|
89
|
+
this.wake = resolve;
|
|
90
|
+
});
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** An eager invocation with one bounded, optional progress subscription. */
|
|
95
|
+
export function startContractExecution(run) {
|
|
96
|
+
const observations = new BoundedExecutionProgress();
|
|
97
|
+
const result = Promise.resolve()
|
|
98
|
+
.then(() => run(observations.publish))
|
|
99
|
+
.finally(() => observations.close());
|
|
100
|
+
void result.catch(() => undefined);
|
|
101
|
+
return Object.freeze({ progress: observations.iterable(), result });
|
|
102
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/** @architectureCompositionRoot */
|
|
2
2
|
import { type ActivityHistory, type OutcomeRow, type AkumaStatus, type InterruptReceipt } from "../akuma/akuma.js";
|
|
3
3
|
import { type ExecutionContext } from "../akuma/requests.js";
|
|
4
|
+
import type { WaitObserver } from "../akuma/fleet-execution.js";
|
|
4
5
|
import { type DispatchAssociation } from "../dispatch/index.js";
|
|
5
6
|
import { type AkumaAddressInput, type AkumaSetAddressInput } from "./address.js";
|
|
6
7
|
import { type AkumaKillResult, type AkumaObservation, type AkumaObservationStage, type AkumaTellResult, type AkumaWaitResult } from "../akuma/fleet-observation.js";
|
|
@@ -10,6 +11,7 @@ export type AkumaWaitInput = AkumaSetAddressInput & Readonly<{
|
|
|
10
11
|
}>;
|
|
11
12
|
export type AkumaTellInput = AkumaAddressInput & Readonly<{
|
|
12
13
|
body: string;
|
|
14
|
+
initiator?: string;
|
|
13
15
|
}>;
|
|
14
16
|
export type { TellResult, TellWake } from "../akuma/akuma.js";
|
|
15
17
|
export type { CreatedTaskObservation } from "../task/created-observation.js";
|
|
@@ -17,6 +19,7 @@ export type { DispatchAssociation } from "../dispatch/association.js";
|
|
|
17
19
|
export type { AkumaKillResult, AkumaObservation, AkumaObservationStage, AkumaTellResult, AkumaUnobserved, AkumaWaitResult, } from "../akuma/fleet-observation.js";
|
|
18
20
|
export type AkumaInterruptInput = AkumaAddressInput & Readonly<{
|
|
19
21
|
body: string;
|
|
22
|
+
initiator?: string;
|
|
20
23
|
}>;
|
|
21
24
|
export type AkumaInterruptResult = Readonly<{
|
|
22
25
|
id: AkumaStatus["id"];
|
|
@@ -56,7 +59,7 @@ export type AkumaHistoryResult = Readonly<{
|
|
|
56
59
|
contract: DispatchAssociation;
|
|
57
60
|
}>;
|
|
58
61
|
export declare function statusAkuma(input: AkumaAddressInput): Promise<AkumaObservation>;
|
|
59
|
-
export declare function waitAkuma(input: AkumaWaitInput, execution?: ExecutionContext): Promise<AkumaWaitResult>;
|
|
62
|
+
export declare function waitAkuma(input: AkumaWaitInput, execution?: ExecutionContext, observer?: WaitObserver): Promise<AkumaWaitResult>;
|
|
60
63
|
export declare function killAkuma(input: AkumaSetAddressInput, execution?: ExecutionContext): Promise<AkumaKillResult>;
|
|
61
64
|
export declare function tellAkuma(input: AkumaTellInput, execution?: ExecutionContext): Promise<AkumaTellResult>;
|
|
62
65
|
export declare function interruptAkuma(input: AkumaInterruptInput): Promise<AkumaInterruptResult>;
|
|
@@ -4,6 +4,7 @@ import { createAkumaProduct } from "../akuma/akuma-product.js";
|
|
|
4
4
|
import { executionChannel, localExecutionContext } from "../akuma/requests.js";
|
|
5
5
|
import { requestForwardedFleetKill, requestForwardedFleetTell, requestForwardedFleetWait, } from "../akuma/fleet-request.js";
|
|
6
6
|
import { executeKillAkuma, executeTellAkuma, executeWaitAkuma } from "../akuma/fleet-execution.js";
|
|
7
|
+
import { readAliases } from "../alias/index.js";
|
|
7
8
|
import { observeDispatchAssociation } from "../dispatch/index.js";
|
|
8
9
|
import { observeCreatedTaskObservations } from "../task/created-observation.js";
|
|
9
10
|
import { addressAkuma, addressAkumaSet } from "./address.js";
|
|
@@ -23,6 +24,26 @@ async function dispatchAssociation(repo, id) {
|
|
|
23
24
|
async function createdTasksFor(path, statuses) {
|
|
24
25
|
return await observeCreatedTaskObservations(path, statuses.map((status) => status.id));
|
|
25
26
|
}
|
|
27
|
+
/**
|
|
28
|
+
* One wait's identity-fact resolver: the alias bound to an Akuma in its world and
|
|
29
|
+
* its Dispatch association. The alias index is read once, on the first observed
|
|
30
|
+
* Akuma, and each Akuma's alias is the first binding the canonical order offers.
|
|
31
|
+
*/
|
|
32
|
+
function waitIdentityFacts(path, repo) {
|
|
33
|
+
let aliases;
|
|
34
|
+
return async (id) => {
|
|
35
|
+
if (aliases === undefined) {
|
|
36
|
+
const bound = new Map();
|
|
37
|
+
for (const binding of await readAliases(path)) {
|
|
38
|
+
if (!bound.has(binding.akuId))
|
|
39
|
+
bound.set(binding.akuId, binding.alias);
|
|
40
|
+
}
|
|
41
|
+
aliases = bound;
|
|
42
|
+
}
|
|
43
|
+
const alias = aliases.get(id);
|
|
44
|
+
return { ...(alias === undefined ? {} : { alias }), contract: await dispatchAssociation(repo, id) };
|
|
45
|
+
};
|
|
46
|
+
}
|
|
26
47
|
async function observeAkuma(status, path, repo) {
|
|
27
48
|
return (await observeAkumaSet([status], path, repo))[0];
|
|
28
49
|
}
|
|
@@ -85,7 +106,7 @@ export async function statusAkuma(input) {
|
|
|
85
106
|
const addressed = await addressAkuma(input);
|
|
86
107
|
return await observeAkuma(await source(addressed.path).selectHandle({ id: addressed.id }).status(), addressed.path, input.repo);
|
|
87
108
|
}
|
|
88
|
-
export async function waitAkuma(input, execution = localExecutionContext()) {
|
|
109
|
+
export async function waitAkuma(input, execution = localExecutionContext(), observer) {
|
|
89
110
|
const values = requireInput(input, "Keiyaku.wait input");
|
|
90
111
|
for (const key of Object.keys(values)) {
|
|
91
112
|
if (!["path", "akuma", "repo", "completion", "timeoutMs"].includes(key)) {
|
|
@@ -94,13 +115,11 @@ export async function waitAkuma(input, execution = localExecutionContext()) {
|
|
|
94
115
|
}
|
|
95
116
|
const addressed = await addressAkumaSet(setAddress(values));
|
|
96
117
|
const completion = values.completion;
|
|
97
|
-
if (addressed.ids.length > 1 && completion !== "any" && completion !== "all") {
|
|
98
|
-
throw new TypeError("completion must be any or all when waiting for multiple Akuma");
|
|
99
|
-
}
|
|
100
118
|
if (completion !== undefined && completion !== "any" && completion !== "all") {
|
|
101
119
|
throw new TypeError("completion must be any or all");
|
|
102
120
|
}
|
|
103
|
-
|
|
121
|
+
// An omitted mode is any: a plural wait returns when any selected Akuma is complete.
|
|
122
|
+
const selected = completion ?? "any";
|
|
104
123
|
const timeoutMs = timeout(values.timeoutMs);
|
|
105
124
|
const channel = executionChannel(execution);
|
|
106
125
|
const repo = values.repo;
|
|
@@ -117,6 +136,9 @@ export async function waitAkuma(input, execution = localExecutionContext()) {
|
|
|
117
136
|
ids: addressed.ids,
|
|
118
137
|
completion: selected,
|
|
119
138
|
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
139
|
+
identity: waitIdentityFacts(addressed.path, repo),
|
|
140
|
+
...(observer?.selected === undefined ? {} : { onSelected: observer.selected }),
|
|
141
|
+
...(observer?.observe === undefined ? {} : { observe: observer.observe }),
|
|
120
142
|
}));
|
|
121
143
|
}
|
|
122
144
|
export async function killAkuma(input, execution = localExecutionContext()) {
|
|
@@ -136,7 +158,7 @@ export async function killAkuma(input, execution = localExecutionContext()) {
|
|
|
136
158
|
export async function tellAkuma(input, execution = localExecutionContext()) {
|
|
137
159
|
const values = requireInput(input, "Keiyaku.tell input");
|
|
138
160
|
for (const key of Object.keys(values)) {
|
|
139
|
-
if (!["path", "akuma", "body", "repo"].includes(key)) {
|
|
161
|
+
if (!["path", "akuma", "body", "repo", "initiator"].includes(key)) {
|
|
140
162
|
throw new TypeError(`Keiyaku.tell input has unknown field: ${key}`);
|
|
141
163
|
}
|
|
142
164
|
}
|
|
@@ -149,18 +171,20 @@ export async function tellAkuma(input, execution = localExecutionContext()) {
|
|
|
149
171
|
directory: channel.directory,
|
|
150
172
|
target: addressed.id,
|
|
151
173
|
body: values.body,
|
|
174
|
+
...(input.initiator === undefined ? {} : { initiator: input.initiator }),
|
|
152
175
|
});
|
|
153
176
|
}
|
|
154
177
|
return await executeTellAkuma({
|
|
155
178
|
path: addressed.path,
|
|
156
179
|
id: addressed.id,
|
|
157
180
|
body: values.body,
|
|
181
|
+
...(input.initiator === undefined ? {} : { initiator: input.initiator }),
|
|
158
182
|
});
|
|
159
183
|
}
|
|
160
184
|
export async function interruptAkuma(input) {
|
|
161
185
|
const values = requireInput(input, "Keiyaku.interrupt input");
|
|
162
186
|
for (const key of Object.keys(values)) {
|
|
163
|
-
if (!["path", "akuma", "body", "repo"].includes(key)) {
|
|
187
|
+
if (!["path", "akuma", "body", "repo", "initiator"].includes(key)) {
|
|
164
188
|
throw new TypeError(`Keiyaku.interrupt input has unknown field: ${key}`);
|
|
165
189
|
}
|
|
166
190
|
}
|
|
@@ -168,7 +192,7 @@ export async function interruptAkuma(input) {
|
|
|
168
192
|
throw new TypeError("body must be a string");
|
|
169
193
|
const addressed = await addressAkuma(directAddress(values));
|
|
170
194
|
const handle = source(addressed.path).selectHandle({ id: addressed.id });
|
|
171
|
-
const receipt = await handle.interrupt(values.body);
|
|
195
|
+
const receipt = await handle.interrupt(values.body, input.initiator === undefined ? {} : { initiator: input.initiator });
|
|
172
196
|
const observation = await observeAkumaStage(addressed.path, addressed.id, values.repo);
|
|
173
197
|
return { id: addressed.id, receipt, observation };
|
|
174
198
|
}
|
|
@@ -122,6 +122,7 @@ export declare const Keiyaku: Readonly<{
|
|
|
122
122
|
status: {
|
|
123
123
|
id: import("../akuma/identity.js").AkuId;
|
|
124
124
|
life: "killed" | "hung" | "untidy" | "running" | "asleep" | "stranded";
|
|
125
|
+
allowed: import("../akuma/allowed.js").AllowedActions;
|
|
125
126
|
timeline: {
|
|
126
127
|
reportedChanges: readonly {
|
|
127
128
|
sequence: number;
|
|
@@ -418,4 +419,5 @@ export declare const Keiyaku: Readonly<{
|
|
|
418
419
|
}>;
|
|
419
420
|
}>;
|
|
420
421
|
export { executionReceipt } from "./execution-result.js";
|
|
422
|
+
export type { ContractExecution, ExecutionEvent } from "./execution.js";
|
|
421
423
|
export type { ExecutionCleanup, ExecutionStop, ExecutionReceipt, MutationOperation } from "./execution-result.js";
|
|
@@ -184,13 +184,21 @@ async function reconcileExecution(input, progress) {
|
|
|
184
184
|
for (const contractId of contracts) {
|
|
185
185
|
try {
|
|
186
186
|
input.scope.signal?.throwIfAborted();
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
187
|
+
progress.observe({ kind: "stage", contractId, stage: "reconciliation", state: "started" });
|
|
188
|
+
const report = await (async () => {
|
|
189
|
+
try {
|
|
190
|
+
return await completeReconcile({
|
|
191
|
+
scope: input.scope,
|
|
192
|
+
channel: input.channel,
|
|
193
|
+
contractId,
|
|
194
|
+
hooks: input.hooks,
|
|
195
|
+
retryHooks: false,
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
progress.observe({ kind: "stage", contractId, stage: "reconciliation", state: "finished" });
|
|
200
|
+
}
|
|
201
|
+
})();
|
|
194
202
|
reports.push(report);
|
|
195
203
|
progress.recordResidue(contractId, report.settlement);
|
|
196
204
|
}
|