@astrosheep/keiyaku 4.6.6 → 4.6.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 +11 -0
- package/build/{integrations/marketplace → plugins}/.agents/plugins/marketplace.json +1 -1
- package/build/plugins/.claude-plugin/marketplace.json +5 -0
- package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/.claude-plugin/plugin.json +1 -1
- package/build/{integrations/marketplace/plugins/keiyaku → plugins/codex}/.codex-plugin/plugin.json +1 -1
- package/build/plugins/codex/skills/keiyaku/SKILL.md +44 -0
- package/build/plugins/codex/skills/keiyaku-akuma/SKILL.md +130 -0
- package/build/plugins/codex/skills/keiyaku-akuma/references/automation.md +269 -0
- package/build/plugins/codex/skills/keiyaku-babysit/SKILL.md +65 -0
- package/build/plugins/codex/skills/keiyaku-bind/SKILL.md +216 -0
- package/build/plugins/codex/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/plugins/codex/skills/keiyaku-task/SKILL.md +104 -0
- package/build/plugins/codex/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/plugins/opencode/package.json +6 -0
- package/build/plugins/opencode/skills/keiyaku/SKILL.md +44 -0
- package/build/plugins/opencode/skills/keiyaku-akuma/SKILL.md +130 -0
- package/build/plugins/opencode/skills/keiyaku-akuma/references/automation.md +269 -0
- package/build/plugins/opencode/skills/keiyaku-babysit/SKILL.md +65 -0
- package/build/plugins/opencode/skills/keiyaku-bind/SKILL.md +216 -0
- package/build/plugins/opencode/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/plugins/opencode/skills/keiyaku-task/SKILL.md +104 -0
- package/build/plugins/opencode/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/{integrations → plugins}/pi/keiyaku.ts +0 -5
- package/build/skills/keiyaku/SKILL.md +44 -0
- package/build/skills/keiyaku-akuma/SKILL.md +130 -0
- package/build/skills/keiyaku-akuma/references/automation.md +269 -0
- package/build/skills/keiyaku-babysit/SKILL.md +65 -0
- package/build/skills/keiyaku-bind/SKILL.md +216 -0
- package/build/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/build/skills/keiyaku-task/SKILL.md +104 -0
- package/build/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/src/akuma/akuma-call.d.ts +2 -0
- package/build/src/akuma/akuma-call.js +8 -2
- package/build/src/akuma/akuma-instance.d.ts +12 -1
- package/build/src/akuma/akuma-instance.js +31 -9
- package/build/src/akuma/akuma-observe.d.ts +4 -0
- package/build/src/akuma/akuma-observe.js +14 -0
- package/build/src/akuma/akuma-owner.d.ts +6 -2
- package/build/src/akuma/akuma-owner.js +32 -10
- package/build/src/akuma/akuma-selection-execution.d.ts +3 -1
- package/build/src/akuma/akuma-selection-execution.js +2 -1
- package/build/src/akuma/akuma-wait.d.ts +2 -1
- package/build/src/akuma/akuma-wait.js +4 -1
- package/build/src/akuma/akuma.d.ts +35 -5
- package/build/src/akuma/akuma.js +8 -10
- package/build/src/akuma/archetype.d.ts +7 -15
- package/build/src/akuma/archetype.js +36 -35
- package/build/src/akuma/body.d.ts +6 -3
- package/build/src/akuma/body.js +41 -30
- package/build/src/akuma/call-request.d.ts +18 -10
- package/build/src/akuma/call-request.js +10 -3
- package/build/src/akuma/caller.d.ts +39 -0
- package/build/src/akuma/caller.js +36 -0
- package/build/src/akuma/dispatch-association.d.ts +0 -1
- package/build/src/akuma/dispatch-association.js +0 -3
- package/build/src/akuma/heart/facts.d.ts +16 -12
- package/build/src/akuma/heart/facts.js +8 -0
- package/build/src/akuma/heart/index.d.ts +2 -7
- package/build/src/akuma/heart/index.js +3 -17
- package/build/src/akuma/heart/rows.d.ts +3 -3
- package/build/src/akuma/heart/soul.d.ts +1 -1
- package/build/src/akuma/heart/soul.js +5 -24
- package/build/src/akuma/heart/storage.d.ts +5 -0
- package/build/src/akuma/heart/storage.js +7 -3
- package/build/src/akuma/identity.d.ts +0 -1
- package/build/src/akuma/identity.js +2 -5
- package/build/src/akuma/index.d.ts +5 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/nuke.js +6 -28
- package/build/src/akuma/projection.d.ts +0 -11
- package/build/src/akuma/provider-recipe.d.ts +7 -6
- package/build/src/akuma/provider-recipe.js +1 -1
- package/build/src/akuma/provider.d.ts +6 -10
- package/build/src/akuma/provider.js +6 -7
- package/build/src/akuma/providers/acp/events.js +5 -18
- package/build/src/akuma/providers/acp/index.js +2 -3
- package/build/src/akuma/providers/claude/events.js +35 -60
- package/build/src/akuma/providers/claude/index.d.ts +2 -2
- package/build/src/akuma/providers/claude/index.js +2 -3
- package/build/src/akuma/providers/codex-app-server/index.js +2 -2
- package/build/src/akuma/providers/decode.d.ts +25 -0
- package/build/src/akuma/providers/decode.js +44 -0
- package/build/src/akuma/providers/execution-environment.d.ts +2 -1
- package/build/src/akuma/providers/execution-environment.js +3 -0
- package/build/src/akuma/providers/grok-build/index.js +6 -22
- package/build/src/akuma/providers/index.js +2 -0
- package/build/src/akuma/providers/lifecycle.d.ts +9 -0
- package/build/src/akuma/providers/lifecycle.js +10 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +1 -14
- package/build/src/akuma/providers/opencode-sdk/index.js +10 -17
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -3
- package/build/src/akuma/providers/paseo/events.d.ts +25 -0
- package/build/src/akuma/providers/paseo/events.js +157 -0
- package/build/src/akuma/providers/paseo/index.d.ts +9 -0
- package/build/src/akuma/providers/paseo/index.js +353 -0
- package/build/src/akuma/providers/pi/events.js +5 -15
- package/build/src/akuma/publication.d.ts +2 -0
- package/build/src/akuma/publication.js +5 -0
- package/build/src/akuma/request-lifecycle.d.ts +3 -0
- package/build/src/akuma/request-lifecycle.js +25 -4
- package/build/src/akuma/requests.d.ts +3 -1
- package/build/src/akuma/requests.js +32 -0
- package/build/src/akuma/selection-observation.d.ts +72 -2
- package/build/src/akuma/selection-observation.js +0 -6
- package/build/src/akuma/selection-owner-port.d.ts +1 -1
- package/build/src/akuma/selection-owner-port.js +16 -5
- package/build/src/akuma/selection-request.d.ts +2 -0
- package/build/src/akuma/selection-request.js +2 -1
- package/build/src/akuma/turn-drive.js +2 -5
- package/build/src/akuma-body.js +4 -2
- package/build/src/cli/akuma-caller.d.ts +3 -0
- package/build/src/cli/akuma-caller.js +21 -0
- package/build/src/cli/commands/akuma-grammar.js +7 -12
- package/build/src/cli/commands/akuma.js +18 -16
- package/build/src/cli/commands/contract-grammar.d.ts +2 -1
- package/build/src/cli/commands/contract-grammar.js +13 -15
- package/build/src/cli/commands/contract-help.d.ts +2 -1
- package/build/src/cli/commands/contract-help.js +31 -1
- package/build/src/cli/commands/contract.js +24 -53
- package/build/src/cli/commands/install.js +3 -3
- package/build/src/cli/commands/task.js +18 -35
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/render/catalog.d.ts +2 -5
- package/build/src/cli/render/contract-history.js +3 -6
- package/build/src/cli/render/contract.js +15 -50
- package/build/src/cli/render/receipt.js +3 -10
- package/build/src/cli/render/task.d.ts +4 -6
- package/build/src/cli/render/task.js +9 -26
- package/build/src/cli/runtime.d.ts +1 -1
- package/build/src/cli/runtime.js +11 -17
- package/build/src/cli/selectors.d.ts +3 -6
- package/build/src/cli/selectors.js +22 -53
- package/build/src/dispatch/index.d.ts +3 -3
- package/build/src/dispatch/index.js +1 -2
- package/build/src/git/observe.d.ts +6 -2
- package/build/src/git/observe.js +6 -2
- package/build/src/index.d.ts +6 -6
- package/build/src/index.js +2 -2
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +21 -6
- package/build/src/library/address.js +2 -4
- package/build/src/library/akuma-creation.d.ts +5 -1
- package/build/src/library/akuma-creation.js +33 -51
- package/build/src/library/akumas.d.ts +5 -4
- package/build/src/library/akumas.js +13 -9
- package/build/src/library/bind.d.ts +14 -14
- package/build/src/library/bind.js +11 -7
- package/build/src/library/contract-address.d.ts +9 -0
- package/build/src/library/contract-address.js +71 -0
- package/build/src/library/contract-composition.d.ts +4 -7
- package/build/src/library/contract-composition.js +6 -18
- package/build/src/library/contract-creation.d.ts +3 -5
- package/build/src/library/contract-creation.js +19 -17
- package/build/src/library/contract-execution.js +18 -23
- package/build/src/library/contract-outcomes.d.ts +2 -14
- package/build/src/library/contract-outcomes.js +2 -13
- package/build/src/library/contract-types.d.ts +36 -2
- package/build/src/library/delivery.d.ts +0 -2
- package/build/src/library/delivery.js +2 -5
- package/build/src/library/keiyaku.d.ts +0 -5
- package/build/src/library/keiyaku.js +6 -12
- package/build/src/library/outcome.d.ts +500 -499
- package/build/src/library/outcome.js +10 -0
- package/build/src/library/reconcile.js +8 -16
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/repo.d.ts +3 -2
- package/build/src/library/repo.js +10 -5
- package/build/src/library/selection.d.ts +4 -4
- package/build/src/library/selection.js +12 -9
- package/build/src/plugin/akuma-signals.d.ts +12 -11
- package/build/src/plugin/akuma-signals.js +40 -20
- package/build/src/plugin/public.d.ts +32 -2
- package/build/src/plugin/runtime.d.ts +1 -0
- package/build/src/plugin/runtime.js +35 -24
- package/build/src/protocol/amend.js +3 -2
- package/build/src/protocol/attempt.js +3 -8
- package/build/src/protocol/bind.d.ts +2 -2
- package/build/src/protocol/bind.js +1 -1
- package/build/src/protocol/deliver.js +3 -3
- package/build/src/protocol/operations.d.ts +1 -3
- package/build/src/protocol/operations.js +0 -8
- package/build/src/protocol/outcome.d.ts +1 -2
- package/build/src/protocol/outcome.js +1 -13
- package/build/src/protocol/placement.js +3 -10
- package/build/src/protocol/read/status.js +31 -70
- package/build/src/protocol/reintegrate.js +3 -10
- package/build/src/protocol/review.js +3 -3
- package/build/src/protocol/run.d.ts +5 -1
- package/build/src/protocol/run.js +3 -3
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/package.json +12 -8
- package/plugins/pi/keiyaku.ts +57 -0
- package/skills/keiyaku/SKILL.md +44 -0
- package/skills/keiyaku-akuma/SKILL.md +130 -0
- package/skills/keiyaku-akuma/references/automation.md +269 -0
- package/skills/keiyaku-babysit/SKILL.md +65 -0
- package/skills/keiyaku-bind/SKILL.md +216 -0
- package/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/skills/keiyaku-task/SKILL.md +104 -0
- package/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/integrations/marketplace/.claude-plugin/marketplace.json +0 -5
- package/build/integrations/marketplace/plugins/keiyaku/package.json +0 -17
- package/build/src/cli/commands/amend.d.ts +0 -12
- package/build/src/cli/commands/amend.js +0 -10
- package/build/src/cli/commands/bind.d.ts +0 -11
- package/build/src/cli/commands/bind.js +0 -23
- package/build/src/dispatch/association.d.ts +0 -1
- package/build/src/dispatch/association.js +0 -1
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku/SKILL.md +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-akuma/SKILL.md +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-akuma/references/automation.md +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-babysit/SKILL.md +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-bind/SKILL.md +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-bind/agents/openai.yaml +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-task/SKILL.md +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-workflow/SKILL.md +0 -0
- /package/build/{integrations/marketplace/plugins/keiyaku/opencode.js → plugins/opencode/index.js} +0 -0
|
@@ -257,6 +257,16 @@ export function errorCategory(error) {
|
|
|
257
257
|
return "aborted";
|
|
258
258
|
return "internal";
|
|
259
259
|
}
|
|
260
|
+
export async function readContractValue(operation) {
|
|
261
|
+
try {
|
|
262
|
+
return await operation();
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
if (error instanceof KeiyakuError)
|
|
266
|
+
throw error;
|
|
267
|
+
throw new KeiyakuError(errorCategory(error), errorDiagnostic(error), { cause: error });
|
|
268
|
+
}
|
|
269
|
+
}
|
|
260
270
|
function errorDiagnostic(error) {
|
|
261
271
|
return error instanceof Error ? error.message : String(error);
|
|
262
272
|
}
|
|
@@ -54,11 +54,8 @@ function registerLag(scope, error) {
|
|
|
54
54
|
function emptySettlement() {
|
|
55
55
|
return { actions: [], lags: [] };
|
|
56
56
|
}
|
|
57
|
-
function isManagedWorktree(state) {
|
|
58
|
-
return state.coordinates.workspace === "worktree";
|
|
59
|
-
}
|
|
60
57
|
function isManagedTerminal(state) {
|
|
61
|
-
return state !== null &&
|
|
58
|
+
return state !== null && state.terminal !== null;
|
|
62
59
|
}
|
|
63
60
|
/**
|
|
64
61
|
* Terminal cleanup retires the appointed worktree. Name its short name only when this
|
|
@@ -76,7 +73,7 @@ function terminalWorktreeOutcome(scope, cleanup, place) {
|
|
|
76
73
|
return undefined;
|
|
77
74
|
}
|
|
78
75
|
function appointableManagedContracts(states) {
|
|
79
|
-
return states.filter((state) =>
|
|
76
|
+
return states.filter((state) => state.terminal === null).map((state) => state.id);
|
|
80
77
|
}
|
|
81
78
|
async function appointPlaces(scope, states) {
|
|
82
79
|
return await appointManagedWorktrees(scope, appointableManagedContracts(states));
|
|
@@ -114,8 +111,6 @@ async function observeState(scope, channel, contractId) {
|
|
|
114
111
|
}
|
|
115
112
|
}
|
|
116
113
|
async function appointForContract(scope, state) {
|
|
117
|
-
if (!isManagedWorktree(state))
|
|
118
|
-
return {};
|
|
119
114
|
try {
|
|
120
115
|
const register = await appointPlaces(scope, [state]);
|
|
121
116
|
const place = register.byContract.get(state.id)?.place;
|
|
@@ -265,16 +260,13 @@ export async function completeRepoReconcile(input) {
|
|
|
265
260
|
if (!isOperationalFailure(error))
|
|
266
261
|
throw error;
|
|
267
262
|
const lag = registerLag(input.scope, error);
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
contracts.
|
|
263
|
+
return {
|
|
264
|
+
kind: "completed",
|
|
265
|
+
contracts: states.map((state) => ({
|
|
271
266
|
contractId: state.id,
|
|
272
|
-
report:
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
return { kind: "completed", contracts };
|
|
267
|
+
report: { effects: [], lag: [lag], settlement: emptySettlement() },
|
|
268
|
+
})),
|
|
269
|
+
};
|
|
278
270
|
}
|
|
279
271
|
const places = new Map(appointed.appointments.map((appointment) => [appointment.contract, appointment.place]));
|
|
280
272
|
const retained = await reconcileAllOperation({
|
|
@@ -177,8 +177,8 @@ export declare const keiyakuRefusalSchema: z.ZodUnion<readonly [z.ZodUnion<reado
|
|
|
177
177
|
}, z.core.$strict>>>;
|
|
178
178
|
}, z.core.$strict>]>, z.ZodObject<{
|
|
179
179
|
kind: z.ZodEnum<{
|
|
180
|
-
"unborn-head": "unborn-head";
|
|
181
180
|
"target-missing": "target-missing";
|
|
181
|
+
"unborn-head": "unborn-head";
|
|
182
182
|
"invalid-target": "invalid-target";
|
|
183
183
|
}>;
|
|
184
184
|
}, z.core.$strict>, z.ZodObject<{
|
|
@@ -302,8 +302,8 @@ export declare const operationRefusalSchemas: {
|
|
|
302
302
|
contractId: z.ZodPipe<z.ZodString, z.ZodTransform<import("../index.js").ContractId, string>>;
|
|
303
303
|
}, z.core.$strict>, z.ZodObject<{
|
|
304
304
|
kind: z.ZodEnum<{
|
|
305
|
-
"unborn-head": "unborn-head";
|
|
306
305
|
"target-missing": "target-missing";
|
|
306
|
+
"unborn-head": "unborn-head";
|
|
307
307
|
"invalid-target": "invalid-target";
|
|
308
308
|
}>;
|
|
309
309
|
}, z.core.$strict>, z.ZodUnion<readonly [z.ZodObject<{
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { type RepositoryScope } from "../protocol/operations.js";
|
|
2
2
|
import { NoGitWorldError } from "../git/repository.js";
|
|
3
3
|
export { NoGitWorldError };
|
|
4
|
+
/** One explicit worktree coordinate. The caller resolves relative and ambient spellings, never this edge. */
|
|
4
5
|
export type RepoAtInput = Readonly<{
|
|
5
|
-
path
|
|
6
|
+
path: string;
|
|
6
7
|
gitPath?: string;
|
|
7
8
|
}>;
|
|
8
9
|
/** One Git world shared by its worktrees; it is coordinate proof and branch observation only. */
|
|
@@ -10,7 +11,7 @@ export declare class Repo {
|
|
|
10
11
|
readonly root: string;
|
|
11
12
|
readonly cwd: string;
|
|
12
13
|
private constructor();
|
|
13
|
-
static at(input
|
|
14
|
+
static at(input: RepoAtInput): Promise<Repo>;
|
|
14
15
|
currentBranch(): Promise<string | null>;
|
|
15
16
|
}
|
|
16
17
|
export declare function scopeForRepo(value: unknown): RepositoryScope;
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
import { realpath } from "node:fs/promises";
|
|
2
|
-
import {
|
|
2
|
+
import { isAbsolute } from "node:path";
|
|
3
3
|
import { currentBranchOperation, scopeOperation } from "../protocol/operations.js";
|
|
4
4
|
import { NoGitWorldError } from "../git/repository.js";
|
|
5
5
|
import { optionalNonblank, requireInput } from "./input.js";
|
|
6
6
|
export { NoGitWorldError };
|
|
7
7
|
const REPO_SCOPES = new WeakMap();
|
|
8
|
-
async function resolvePinnedScope(
|
|
8
|
+
async function resolvePinnedScope(values) {
|
|
9
|
+
const path = values.path;
|
|
10
|
+
if (typeof path !== "string" || path.trim().length === 0)
|
|
11
|
+
throw new TypeError("repository path must be a nonblank string");
|
|
12
|
+
if (!isAbsolute(path))
|
|
13
|
+
throw new TypeError(`repository path must be absolute: ${path}`);
|
|
14
|
+
const gitPath = optionalNonblank(values.gitPath, "Git executable path");
|
|
9
15
|
return await scopeOperation({
|
|
10
|
-
coordinate: await realpath(
|
|
16
|
+
coordinate: await realpath(path),
|
|
11
17
|
...(gitPath === undefined ? {} : { gitPath }),
|
|
12
18
|
});
|
|
13
19
|
}
|
|
@@ -21,8 +27,7 @@ export class Repo {
|
|
|
21
27
|
REPO_SCOPES.set(this, scope);
|
|
22
28
|
}
|
|
23
29
|
static async at(input) {
|
|
24
|
-
|
|
25
|
-
return new Repo(await resolvePinnedScope(optionalNonblank(values?.path, "repository path"), optionalNonblank(values?.gitPath, "Git executable path")));
|
|
30
|
+
return new Repo(await resolvePinnedScope(requireInput(input, "Repo.at input", ["path", "gitPath"])));
|
|
26
31
|
}
|
|
27
32
|
async currentBranch() {
|
|
28
33
|
return await currentBranchOperation({ scope: scopeForRepo(this) });
|
|
@@ -5,7 +5,7 @@ import { type ActivityHistory, type OutcomeRow } from "../akuma/projection.js";
|
|
|
5
5
|
import { type ExecutionContext } from "../akuma/requests.js";
|
|
6
6
|
import { type Schema } from "../akuma/schema.js";
|
|
7
7
|
import type { AkumaAskResult, AkumaKillResult, AkumaObservation, AkumaTellResult, AkumaWaitResult } from "../akuma/selection-observation.js";
|
|
8
|
-
import {
|
|
8
|
+
import type { DispatchAssociation } from "../akuma/dispatch-association.js";
|
|
9
9
|
import type { WorldRoot } from "../world.js";
|
|
10
10
|
import { addressAkuma, addressAkumaSet, type AkumaAddressInput, type AkumaSetAddressInput } from "./address.js";
|
|
11
11
|
import { type Repo } from "./repo.js";
|
|
@@ -33,7 +33,7 @@ export type SelectionSeam = Readonly<{
|
|
|
33
33
|
tell(addressed: AddressedAkuma, input: AkumaTellInput, signal?: AbortSignal): Promise<AkumaTellResult>;
|
|
34
34
|
ask<T>(addressed: AddressedAkuma, input: AkumaAskInput<T>, signal?: AbortSignal): Promise<AkumaAskResult<T>>;
|
|
35
35
|
}>;
|
|
36
|
-
export declare function selectionSeam(execution: ExecutionContext): SelectionSeam;
|
|
36
|
+
export declare function selectionSeam(execution: ExecutionContext, reportDiagnostic?: (message: string) => void): SelectionSeam;
|
|
37
37
|
export type AkumaWaitInput = AkumaSetAddressInput & Readonly<{
|
|
38
38
|
completion?: "any" | "all";
|
|
39
39
|
timeoutMs?: number;
|
|
@@ -94,7 +94,7 @@ export type AkumaHistoryResult = Readonly<{
|
|
|
94
94
|
}>;
|
|
95
95
|
export declare function statusAkuma(input: AkumaAddressInput & Readonly<{
|
|
96
96
|
path: WorldRoot;
|
|
97
|
-
}
|
|
97
|
+
}>, reportDiagnostic?: (message: string) => void): Promise<AkumaObservation>;
|
|
98
98
|
export declare function waitAkumaOn(seam: SelectionSeam, input: AkumaWaitInput & Readonly<{
|
|
99
99
|
path: WorldRoot;
|
|
100
100
|
}>): Promise<AkumaWaitResult>;
|
|
@@ -109,4 +109,4 @@ export declare function askAkumaOn<T = string>(seam: SelectionSeam, input: Akuma
|
|
|
109
109
|
}>): Promise<AkumaAskResult<T>>;
|
|
110
110
|
export declare function historyAkuma(input: AkumaHistoryInput & Readonly<{
|
|
111
111
|
path: WorldRoot;
|
|
112
|
-
}
|
|
112
|
+
}>, reportDiagnostic?: (message: string) => void): Promise<AkumaHistoryResult>;
|
|
@@ -13,12 +13,13 @@ import { observeDispatchAssociations } from "../dispatch/index.js";
|
|
|
13
13
|
import { observeContractAt } from "../git/observe.js";
|
|
14
14
|
import { withGitDecodeChannel } from "../git/read-observation.js";
|
|
15
15
|
import { observeCreatedTaskObservations } from "../task/created-observation.js";
|
|
16
|
+
import { outcomePluginObserver, stderrPluginDiagnostic } from "../plugin/akuma-signals.js";
|
|
16
17
|
import { addressAkuma, addressAkumaSet, resolveAkuma, resolveAkumaSet, } from "./address.js";
|
|
17
18
|
import { requireInput } from "./input.js";
|
|
18
19
|
import { scopeForRepo } from "./repo.js";
|
|
19
|
-
export function selectionSeam(execution) {
|
|
20
|
+
export function selectionSeam(execution, reportDiagnostic = stderrPluginDiagnostic) {
|
|
20
21
|
const channel = executionChannel(execution);
|
|
21
|
-
return channel.kind === "body-request" ? forwardedSelection(channel.directory) : localSelection();
|
|
22
|
+
return channel.kind === "body-request" ? forwardedSelection(channel.directory) : localSelection(reportDiagnostic);
|
|
22
23
|
}
|
|
23
24
|
function forwardedSelection(directory) {
|
|
24
25
|
return {
|
|
@@ -55,11 +56,11 @@ function forwardedSelection(directory) {
|
|
|
55
56
|
},
|
|
56
57
|
};
|
|
57
58
|
}
|
|
58
|
-
function localSelection() {
|
|
59
|
+
function localSelection(reportDiagnostic) {
|
|
59
60
|
return {
|
|
60
61
|
addressOne: addressAkuma,
|
|
61
62
|
addressSet: addressAkumaSet,
|
|
62
|
-
wait: async (addressed, mode, observer) => await localWait(addressed, { ...mode, ...(observer === undefined ? {} : { observer }) }),
|
|
63
|
+
wait: async (addressed, mode, observer) => await localWait(addressed, { ...mode, ...(observer === undefined ? {} : { observer }) }, reportDiagnostic),
|
|
63
64
|
kill: async (addressed, abort) => await executeKillAkuma({
|
|
64
65
|
path: addressed.path,
|
|
65
66
|
ids: addressed.orderedIds,
|
|
@@ -77,6 +78,7 @@ function localSelection() {
|
|
|
77
78
|
const result = await executeAskAkuma({
|
|
78
79
|
path: addressed.path,
|
|
79
80
|
id: addressed.id,
|
|
81
|
+
outcomeObserved: outcomePluginObserver({ world: addressed.path, reportDiagnostic }),
|
|
80
82
|
body: input.body,
|
|
81
83
|
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
82
84
|
...(input.schema === undefined ? {} : { schemaJson: schemaJsonText(input.schema) }),
|
|
@@ -236,10 +238,10 @@ function setAddress(values) {
|
|
|
236
238
|
...(values.repo === undefined ? {} : { repo: values.repo }),
|
|
237
239
|
};
|
|
238
240
|
}
|
|
239
|
-
export async function statusAkuma(input) {
|
|
241
|
+
export async function statusAkuma(input, reportDiagnostic = stderrPluginDiagnostic) {
|
|
240
242
|
const addressed = await addressAkuma(input);
|
|
241
243
|
try {
|
|
242
|
-
return await observeAkuma(await new AkumaOwner(addressed.id, addressed.path).status(), addressed.path, input.repo);
|
|
244
|
+
return await observeAkuma(await new AkumaOwner(addressed.id, addressed.path, outcomePluginObserver({ world: addressed.path, reportDiagnostic })).status(), addressed.path, input.repo);
|
|
243
245
|
}
|
|
244
246
|
catch (error) {
|
|
245
247
|
throw observationError(addressed.id, error);
|
|
@@ -262,12 +264,13 @@ async function forwardedWait(addressed, input) {
|
|
|
262
264
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
263
265
|
}));
|
|
264
266
|
}
|
|
265
|
-
async function localWait(addressed, input) {
|
|
267
|
+
async function localWait(addressed, input, reportDiagnostic) {
|
|
266
268
|
try {
|
|
267
269
|
return await composeWaitResult(addressed.path, input.repo, await executeWaitAkuma({
|
|
268
270
|
path: addressed.path,
|
|
269
271
|
ids: addressed.orderedIds,
|
|
270
272
|
completion: input.completion,
|
|
273
|
+
outcomeObserved: outcomePluginObserver({ world: addressed.path, reportDiagnostic }),
|
|
271
274
|
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
272
275
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
273
276
|
identity: waitIdentityFacts(addressed.path, input.repo, addressed.orderedIds),
|
|
@@ -385,12 +388,12 @@ function validateHistoryInput(values) {
|
|
|
385
388
|
(values.last === true || values.before !== undefined || values.since !== undefined || values.limit !== undefined))
|
|
386
389
|
throw new TypeError("id cannot be combined with last, before, since, or limit");
|
|
387
390
|
}
|
|
388
|
-
export async function historyAkuma(input) {
|
|
391
|
+
export async function historyAkuma(input, reportDiagnostic = stderrPluginDiagnostic) {
|
|
389
392
|
const values = requireInput(input, "Akumas.history input");
|
|
390
393
|
validateHistoryInput(values);
|
|
391
394
|
const addressed = await addressAkuma(directAddress(values));
|
|
392
395
|
try {
|
|
393
|
-
const handle = new AkumaOwner(addressed.id, addressed.path);
|
|
396
|
+
const handle = new AkumaOwner(addressed.id, addressed.path, outcomePluginObserver({ world: addressed.path, reportDiagnostic }));
|
|
394
397
|
const contract = (await dispatchAssociations(values.repo, [addressed.id])).get(addressed.id);
|
|
395
398
|
if (values.last === true) {
|
|
396
399
|
const answer = await handle.lastAnswer();
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import type { Settings } from "../settings.js";
|
|
2
2
|
import type { WorldRoot } from "../world.js";
|
|
3
|
-
type
|
|
3
|
+
import type { PluginSignal } from "./public.js";
|
|
4
|
+
/** The local library observation default; CLI and Body supply their own sinks. */
|
|
5
|
+
export declare function stderrPluginDiagnostic(message: string): void;
|
|
6
|
+
type PluginSignalEmission = Readonly<{
|
|
4
7
|
world: WorldRoot;
|
|
5
8
|
settings?: Settings;
|
|
6
9
|
reportDiagnostic: (message: string) => void;
|
|
7
|
-
akumaId: string;
|
|
8
|
-
callerAkumaId?: string;
|
|
9
|
-
contractId?: string;
|
|
10
10
|
}>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
/**
|
|
12
|
+
* The one producer entry for plugin signals. It owns runtime acquisition, the
|
|
13
|
+
* World Settings fallback, bounded delivery, and failure isolation: a delivery
|
|
14
|
+
* problem reaches the producer only as a diagnostic, never as a thrown error.
|
|
15
|
+
*/
|
|
16
|
+
export declare function emitPluginSignal(emission: PluginSignalEmission, signal: PluginSignal): Promise<void>;
|
|
17
|
+
/** One public observer operation, never shared with incidental owner reads. */
|
|
18
|
+
export declare function outcomePluginObserver(emission: PluginSignalEmission, observer?: string): (akumaId: string, historyIds: readonly string[]) => Promise<void>;
|
|
18
19
|
export {};
|
|
@@ -1,22 +1,42 @@
|
|
|
1
|
-
import { pluginRuntime } from "./runtime.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
...(input.settings === undefined ? {} : { settings: input.settings }),
|
|
6
|
-
reportDiagnostic: input.reportDiagnostic,
|
|
7
|
-
});
|
|
8
|
-
await runtime.emit({ kind: "akuma.initiating", initiator: input.initiator }, input.reportDiagnostic);
|
|
1
|
+
import { pluginRuntime, reportPluginDiagnostic } from "./runtime.js";
|
|
2
|
+
/** The local library observation default; CLI and Body supply their own sinks. */
|
|
3
|
+
export function stderrPluginDiagnostic(message) {
|
|
4
|
+
console.error(message);
|
|
9
5
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
/**
|
|
7
|
+
* The one producer entry for plugin signals. It owns runtime acquisition, the
|
|
8
|
+
* World Settings fallback, bounded delivery, and failure isolation: a delivery
|
|
9
|
+
* problem reaches the producer only as a diagnostic, never as a thrown error.
|
|
10
|
+
*/
|
|
11
|
+
export async function emitPluginSignal(emission, signal) {
|
|
12
|
+
try {
|
|
13
|
+
const runtime = await pluginRuntime({
|
|
14
|
+
world: emission.world,
|
|
15
|
+
...(emission.settings === undefined ? {} : { settings: emission.settings }),
|
|
16
|
+
reportDiagnostic: emission.reportDiagnostic,
|
|
17
|
+
});
|
|
18
|
+
await runtime.emit(signal, emission.reportDiagnostic);
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
reportPluginDiagnostic(emission.reportDiagnostic, "runtime", "signal", error);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
/** One public observer operation, never shared with incidental owner reads. */
|
|
25
|
+
export function outcomePluginObserver(emission, observer) {
|
|
26
|
+
const seen = new Set();
|
|
27
|
+
return async (akumaId, historyIds) => {
|
|
28
|
+
const fresh = historyIds.filter((historyId) => {
|
|
29
|
+
const key = `${akumaId}:${historyId}`;
|
|
30
|
+
if (seen.has(key))
|
|
31
|
+
return false;
|
|
32
|
+
seen.add(key);
|
|
33
|
+
return true;
|
|
34
|
+
});
|
|
35
|
+
await Promise.all(fresh.map(async (historyId) => await emitPluginSignal(emission, {
|
|
36
|
+
kind: "akuma.outcome-observed",
|
|
37
|
+
akumaId,
|
|
38
|
+
historyId,
|
|
39
|
+
...(observer === undefined ? {} : { observer }),
|
|
40
|
+
})));
|
|
41
|
+
};
|
|
22
42
|
}
|
|
@@ -15,15 +15,45 @@ export type PluginOutcome = Readonly<{
|
|
|
15
15
|
reason: string;
|
|
16
16
|
}>;
|
|
17
17
|
export type PluginBodyEnd = "exited" | "broke-off" | "put-down" | "hung";
|
|
18
|
+
export type PluginAkumaOrigin = Readonly<{
|
|
19
|
+
kind: "direct";
|
|
20
|
+
}> | Readonly<{
|
|
21
|
+
kind: "request";
|
|
22
|
+
parent: string;
|
|
23
|
+
requestId: string;
|
|
24
|
+
}> | Readonly<{
|
|
25
|
+
kind: "fork";
|
|
26
|
+
parent: string;
|
|
27
|
+
at: string;
|
|
28
|
+
}>;
|
|
29
|
+
export type PluginAkumaCaller = Readonly<{
|
|
30
|
+
kind: "akuma";
|
|
31
|
+
world: string;
|
|
32
|
+
akuId: string;
|
|
33
|
+
}> | Readonly<{
|
|
34
|
+
kind: "external";
|
|
35
|
+
integration: string;
|
|
36
|
+
id: string;
|
|
37
|
+
}> | Readonly<{
|
|
38
|
+
kind: "unknown";
|
|
39
|
+
}>;
|
|
18
40
|
export type PluginSignalMap = Readonly<{
|
|
19
41
|
"akuma.initiating": Readonly<{
|
|
20
42
|
initiator: string;
|
|
21
43
|
}>;
|
|
22
|
-
"akuma.
|
|
44
|
+
"akuma.born": Readonly<{
|
|
23
45
|
akumaId: string;
|
|
24
|
-
|
|
46
|
+
bodySequence: number;
|
|
47
|
+
origin: PluginAkumaOrigin;
|
|
48
|
+
caller: PluginAkumaCaller;
|
|
49
|
+
initiator?: string;
|
|
25
50
|
contractId?: string;
|
|
26
51
|
}>;
|
|
52
|
+
"akuma.outcome-observed": Readonly<{
|
|
53
|
+
akumaId: string;
|
|
54
|
+
historyId: string;
|
|
55
|
+
observer?: string;
|
|
56
|
+
}>;
|
|
27
57
|
"akuma.turn-outcome": Readonly<{
|
|
28
58
|
akumaId: string;
|
|
29
59
|
bodySequence: number;
|
|
@@ -10,5 +10,6 @@ type PluginRuntimeInput = Readonly<{
|
|
|
10
10
|
export type PluginRuntime = Readonly<{
|
|
11
11
|
emit(signal: PluginSignal, reportDiagnostic?: PluginDiagnostic): Promise<void>;
|
|
12
12
|
}>;
|
|
13
|
+
export declare function reportPluginDiagnostic(report: PluginDiagnostic | undefined, subject: string, stage: string, error: unknown): void;
|
|
13
14
|
export declare function pluginRuntime(input: PluginRuntimeInput): Promise<PluginRuntime>;
|
|
14
15
|
export {};
|
|
@@ -18,11 +18,11 @@ function object(value) {
|
|
|
18
18
|
function message(error) {
|
|
19
19
|
return (error instanceof Error ? error.message : String(error)).slice(0, DIAGNOSTIC_LIMIT);
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
export function reportPluginDiagnostic(report, subject, stage, error) {
|
|
22
22
|
if (report === undefined)
|
|
23
23
|
return;
|
|
24
24
|
try {
|
|
25
|
-
report(`plugin ${subject} ${stage}: ${message(error)}`.slice(0, DIAGNOSTIC_LIMIT));
|
|
25
|
+
void Promise.resolve(report(`plugin ${subject} ${stage}: ${message(error)}`.slice(0, DIAGNOSTIC_LIMIT))).catch(() => { });
|
|
26
26
|
}
|
|
27
27
|
catch {
|
|
28
28
|
// Diagnostics are optional side effects too.
|
|
@@ -67,30 +67,30 @@ async function settleBefore(promise, cancellation) {
|
|
|
67
67
|
}
|
|
68
68
|
function selectedEntry(entry, report) {
|
|
69
69
|
if (entry.name.trim().length === 0) {
|
|
70
|
-
|
|
70
|
+
reportPluginDiagnostic(report, "<unnamed>", "selection", new TypeError("plugin setting name must be nonblank"));
|
|
71
71
|
return null;
|
|
72
72
|
}
|
|
73
73
|
if (!object(entry.value)) {
|
|
74
|
-
|
|
74
|
+
reportPluginDiagnostic(report, entry.name, "selection", new TypeError("plugin setting must be an object"));
|
|
75
75
|
return null;
|
|
76
76
|
}
|
|
77
77
|
const names = Object.keys(entry.value);
|
|
78
78
|
if (!names.includes("package") || names.some((name) => !["package", "enabled", "config"].includes(name))) {
|
|
79
|
-
|
|
79
|
+
reportPluginDiagnostic(report, entry.name, "selection", new TypeError("plugin setting has unknown or missing fields"));
|
|
80
80
|
return null;
|
|
81
81
|
}
|
|
82
82
|
const packageName = entry.value.package;
|
|
83
83
|
if (typeof packageName !== "string" || packageName.trim().length === 0) {
|
|
84
|
-
|
|
84
|
+
reportPluginDiagnostic(report, entry.name, "selection", new TypeError("plugin package must be a nonblank string"));
|
|
85
85
|
return null;
|
|
86
86
|
}
|
|
87
87
|
if (packageName !== packageName.trim()) {
|
|
88
|
-
|
|
88
|
+
reportPluginDiagnostic(report, entry.name, "selection", new TypeError("plugin package must not have surrounding whitespace"));
|
|
89
89
|
return null;
|
|
90
90
|
}
|
|
91
91
|
const enabled = entry.value.enabled;
|
|
92
92
|
if (enabled !== undefined && typeof enabled !== "boolean") {
|
|
93
|
-
|
|
93
|
+
reportPluginDiagnostic(report, entry.name, "selection", new TypeError("plugin enabled must be a boolean"));
|
|
94
94
|
return null;
|
|
95
95
|
}
|
|
96
96
|
if (enabled === false)
|
|
@@ -101,7 +101,7 @@ function selectedPlugins(input, report) {
|
|
|
101
101
|
const view = input.namespace(PLUGIN_NAMESPACE);
|
|
102
102
|
if (view.kind === "failed") {
|
|
103
103
|
for (const failure of view.failures)
|
|
104
|
-
|
|
104
|
+
reportPluginDiagnostic(report, "settings", failure.scope, failure.diagnostic);
|
|
105
105
|
return BUILTIN_PLUGINS;
|
|
106
106
|
}
|
|
107
107
|
if (view.entries.length === 0)
|
|
@@ -197,6 +197,21 @@ async function writablePaths(world, declarations) {
|
|
|
197
197
|
}
|
|
198
198
|
return paths;
|
|
199
199
|
}
|
|
200
|
+
/**
|
|
201
|
+
* The runtime's acceptance vocabulary. The record is exhaustive over the public
|
|
202
|
+
* payload map, so adding a signal there fails compilation here until the same
|
|
203
|
+
* kind is accepted.
|
|
204
|
+
*/
|
|
205
|
+
const SIGNAL_KINDS = Object.freeze({
|
|
206
|
+
"akuma.initiating": true,
|
|
207
|
+
"akuma.born": true,
|
|
208
|
+
"akuma.outcome-observed": true,
|
|
209
|
+
"akuma.turn-outcome": true,
|
|
210
|
+
"akuma.body-ended": true,
|
|
211
|
+
});
|
|
212
|
+
function isSignalKind(kind) {
|
|
213
|
+
return Object.hasOwn(SIGNAL_KINDS, kind);
|
|
214
|
+
}
|
|
200
215
|
function handlers(pluginId, instance) {
|
|
201
216
|
if (!object(instance))
|
|
202
217
|
throw new TypeError("plugin activation must return an object");
|
|
@@ -208,12 +223,8 @@ function handlers(pluginId, instance) {
|
|
|
208
223
|
throw new TypeError("plugin signals must be an object");
|
|
209
224
|
const registered = [];
|
|
210
225
|
for (const [kind, handler] of Object.entries(instance.signals)) {
|
|
211
|
-
if (kind
|
|
212
|
-
kind !== "akuma.called" &&
|
|
213
|
-
kind !== "akuma.turn-outcome" &&
|
|
214
|
-
kind !== "akuma.body-ended") {
|
|
226
|
+
if (!isSignalKind(kind))
|
|
215
227
|
throw new TypeError(`plugin signal is unknown: ${kind}`);
|
|
216
|
-
}
|
|
217
228
|
if (typeof handler !== "function")
|
|
218
229
|
throw new TypeError(`plugin signal handler is not a function: ${kind}`);
|
|
219
230
|
registered.push({ pluginId, kind, handler });
|
|
@@ -270,7 +281,7 @@ async function activate(input) {
|
|
|
270
281
|
}
|
|
271
282
|
catch (error) {
|
|
272
283
|
markStarted();
|
|
273
|
-
|
|
284
|
+
reportPluginDiagnostic(report, selected.id, "import", error);
|
|
274
285
|
return [];
|
|
275
286
|
}
|
|
276
287
|
if (cancellation.aborted) {
|
|
@@ -288,7 +299,7 @@ async function activate(input) {
|
|
|
288
299
|
}
|
|
289
300
|
catch (error) {
|
|
290
301
|
markStarted();
|
|
291
|
-
|
|
302
|
+
reportPluginDiagnostic(report, selected.id, "validation", error);
|
|
292
303
|
return [];
|
|
293
304
|
}
|
|
294
305
|
let context;
|
|
@@ -307,7 +318,7 @@ async function activate(input) {
|
|
|
307
318
|
}
|
|
308
319
|
catch (error) {
|
|
309
320
|
markStarted();
|
|
310
|
-
|
|
321
|
+
reportPluginDiagnostic(report, selected.id, "validation", error);
|
|
311
322
|
return [];
|
|
312
323
|
}
|
|
313
324
|
if (cancellation.aborted) {
|
|
@@ -324,16 +335,16 @@ async function activate(input) {
|
|
|
324
335
|
return registered;
|
|
325
336
|
}
|
|
326
337
|
catch (error) {
|
|
327
|
-
|
|
338
|
+
reportPluginDiagnostic(report, selected.id, "activation", error);
|
|
328
339
|
return [];
|
|
329
340
|
}
|
|
330
341
|
}
|
|
331
342
|
async function deliver(entry, signal, reportDiagnostic, timeoutMs) {
|
|
332
343
|
const result = await boundedAttempt((cancellation) => entry.handler(signal, cancellation), timeoutMs);
|
|
333
344
|
if (result.kind === "timed-out")
|
|
334
|
-
|
|
345
|
+
reportPluginDiagnostic(reportDiagnostic, entry.pluginId, "signal", timeoutError());
|
|
335
346
|
if (result.kind === "failed")
|
|
336
|
-
|
|
347
|
+
reportPluginDiagnostic(reportDiagnostic, entry.pluginId, "signal", result.error);
|
|
337
348
|
}
|
|
338
349
|
export async function pluginRuntime(input) {
|
|
339
350
|
let runtime = PROCESS_RUNTIMES.get(input.world);
|
|
@@ -358,7 +369,7 @@ async function createPluginRuntime(input) {
|
|
|
358
369
|
releaseStarted();
|
|
359
370
|
if (result.kind === "settled")
|
|
360
371
|
return { handlers: result.value, timedOut: false };
|
|
361
|
-
|
|
372
|
+
reportPluginDiagnostic(report, entry.id, "activation", result.kind === "failed" ? result.error : timeoutError());
|
|
362
373
|
return { handlers: [], timedOut: result.kind === "timed-out" };
|
|
363
374
|
});
|
|
364
375
|
previousStarted = started;
|
|
@@ -372,16 +383,16 @@ async function createPluginRuntime(input) {
|
|
|
372
383
|
const activatedHandlers = await settleBefore(activation, cancellation);
|
|
373
384
|
if (activatedHandlers !== ABORTED) {
|
|
374
385
|
if (activatedHandlers.timedOut)
|
|
375
|
-
|
|
386
|
+
reportPluginDiagnostic(reportDiagnostic, selected[index].id, "signal", timeoutError());
|
|
376
387
|
return activatedHandlers.handlers;
|
|
377
388
|
}
|
|
378
|
-
|
|
389
|
+
reportPluginDiagnostic(reportDiagnostic, selected[index].id, "signal", timeoutError());
|
|
379
390
|
return [];
|
|
380
391
|
}));
|
|
381
392
|
return handlers.flat();
|
|
382
393
|
});
|
|
383
394
|
if (activated.kind === "failed") {
|
|
384
|
-
|
|
395
|
+
reportPluginDiagnostic(reportDiagnostic, "runtime", "signal", activated.error);
|
|
385
396
|
return;
|
|
386
397
|
}
|
|
387
398
|
if (activated.kind === "timed-out")
|
|
@@ -3,7 +3,8 @@ import { withPrivateStatePublicationSeat } from "../git/private-state-seat.js";
|
|
|
3
3
|
import { contractState } from "../core/facts/observation.js";
|
|
4
4
|
import { decideAmend } from "../core/verbs/amend.js";
|
|
5
5
|
import { admitDecidedOffer, mintAttempts } from "./attempt.js";
|
|
6
|
-
import { admitted
|
|
6
|
+
import { admitted } from "./outcome.js";
|
|
7
|
+
import { protocolSeatClose } from "./run.js";
|
|
7
8
|
import { timestamp } from "./operations.js";
|
|
8
9
|
async function extendPrerequisiteClosureAt(channel, observation, seeds) {
|
|
9
10
|
let current = observation;
|
|
@@ -34,7 +35,7 @@ export async function amendOperation(input) {
|
|
|
34
35
|
const amendment = source === undefined || input.deriveAmendment === undefined
|
|
35
36
|
? undefined
|
|
36
37
|
: { source, ...input.deriveAmendment(source) };
|
|
37
|
-
return
|
|
38
|
+
return protocolSeatClose(await withPrivateStatePublicationSeat(input.scope, async (seat) => {
|
|
38
39
|
const attempts = mintAttempts({ entryCount: 1 });
|
|
39
40
|
for (let index = 0; index < attempts.length; index += 1) {
|
|
40
41
|
let observation = await observeContractsForAdmissionAt(input.scope, input.channel, [input.contractId]);
|
|
@@ -65,12 +65,6 @@ function validateOffer(offer, attempt) {
|
|
|
65
65
|
if (actualEntries.size === 0)
|
|
66
66
|
throw new Error("offer requires at least one current-attempt ULID");
|
|
67
67
|
}
|
|
68
|
-
function snapshotFor(append, journals, head) {
|
|
69
|
-
const record = journals.get(append.contractId);
|
|
70
|
-
if (record === undefined)
|
|
71
|
-
throw new Error("accepted offer contract is missing from its observation");
|
|
72
|
-
return foldJournal(append.contractId, [...record.entries, ...append.entries], head);
|
|
73
|
-
}
|
|
74
68
|
function journalFor(append, journals) {
|
|
75
69
|
const record = journals.get(append.contractId);
|
|
76
70
|
if (record === undefined)
|
|
@@ -118,11 +112,12 @@ export async function admitDecidedOffer(input) {
|
|
|
118
112
|
if (admission.kind === "accepted") {
|
|
119
113
|
confirmPrivateStatePublication(seat);
|
|
120
114
|
input.progress?.recordPublication(primaryContract, admission.heads[primary.contractId], offerEntries(offer));
|
|
115
|
+
const journal = journalFor(primary, decisionObservation.journals);
|
|
121
116
|
const accepted = {
|
|
122
117
|
kind: "accepted",
|
|
123
118
|
facts: offerEntries(offer),
|
|
124
|
-
state:
|
|
125
|
-
journal
|
|
119
|
+
state: foldJournal(primary.contractId, journal, admission.heads[primary.contractId]),
|
|
120
|
+
journal,
|
|
126
121
|
};
|
|
127
122
|
input.progress?.recordAdmission(accepted);
|
|
128
123
|
return accepted;
|
|
@@ -11,8 +11,8 @@ export type { BindRefusal } from "../core/verbs/bind.js";
|
|
|
11
11
|
export type { BindTargetSelection };
|
|
12
12
|
export declare const targetInputRefusalSchema: z.ZodObject<{
|
|
13
13
|
kind: z.ZodEnum<{
|
|
14
|
-
"unborn-head": "unborn-head";
|
|
15
14
|
"target-missing": "target-missing";
|
|
15
|
+
"unborn-head": "unborn-head";
|
|
16
16
|
"invalid-target": "invalid-target";
|
|
17
17
|
}>;
|
|
18
18
|
}, z.core.$strict>;
|
|
@@ -27,7 +27,7 @@ type BindOperationInput = Readonly<{
|
|
|
27
27
|
channel: GitDecodeChannel;
|
|
28
28
|
terms: BindData["terms"];
|
|
29
29
|
verification: VerificationDeclarationPreparation;
|
|
30
|
-
targetSelection
|
|
30
|
+
targetSelection: BindTargetSelection;
|
|
31
31
|
workspace: "worktree";
|
|
32
32
|
actor?: ActorId;
|
|
33
33
|
decorateOffer?: CompanionDecorator;
|