@astrosheep/keiyaku 4.6.4 → 4.6.7
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 +7 -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/claude}/skills/keiyaku-akuma/SKILL.md +43 -8
- package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-bind/SKILL.md +7 -8
- package/build/{integrations/marketplace/plugins/keiyaku → plugins/claude}/skills/keiyaku-workflow/SKILL.md +3 -3
- 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/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-instance.js +7 -5
- package/build/src/akuma/akuma-observe.d.ts +22 -15
- package/build/src/akuma/akuma-observe.js +87 -16
- package/build/src/akuma/akuma-owner.d.ts +3 -2
- package/build/src/akuma/akuma-owner.js +28 -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 +6 -4
- package/build/src/akuma/akuma-wait.js +78 -53
- package/build/src/akuma/akuma.d.ts +6 -4
- package/build/src/akuma/akuma.js +4 -0
- package/build/src/akuma/body.d.ts +1 -0
- package/build/src/akuma/body.js +12 -23
- package/build/src/akuma/call-initial-tell.d.ts +2 -2
- package/build/src/akuma/call-initial-tell.js +1 -1
- package/build/src/akuma/call-request.d.ts +2 -2
- package/build/src/akuma/heart/index.d.ts +7 -2
- package/build/src/akuma/heart/index.js +50 -5
- package/build/src/akuma/heart/tells.d.ts +33 -2
- package/build/src/akuma/heart/tells.js +24 -18
- package/build/src/akuma/heart/timeline.d.ts +23 -1
- package/build/src/akuma/heart/timeline.js +28 -21
- package/build/src/akuma/projection.d.ts +10 -10
- package/build/src/akuma/providers/pi/index.js +72 -39
- package/build/src/akuma/selection-observation.d.ts +20 -20
- 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-body.js +5 -2
- package/build/src/alias/index.d.ts +0 -1
- package/build/src/alias/index.js +0 -4
- package/build/src/body/amend.d.ts +0 -4
- package/build/src/body/amend.js +0 -3
- package/build/src/body/region.d.ts +0 -1
- package/build/src/body/region.js +0 -3
- package/build/src/body/verification.d.ts +0 -1
- package/build/src/cli/commands/akuma-grammar.js +23 -66
- package/build/src/cli/commands/akuma.js +23 -42
- package/build/src/cli/commands/contract-grammar.d.ts +14 -1
- package/build/src/cli/commands/contract-grammar.js +54 -21
- package/build/src/cli/commands/contract-help.d.ts +9 -8
- package/build/src/cli/commands/contract-help.js +14 -7
- package/build/src/cli/commands/contract.js +57 -117
- package/build/src/cli/commands/install.d.ts +5 -5
- package/build/src/cli/commands/install.js +4 -7
- package/build/src/cli/commands/task-grammar.js +10 -66
- package/build/src/cli/commands/task.d.ts +0 -1
- package/build/src/cli/commands/task.js +34 -53
- package/build/src/cli/coordinates.d.ts +1 -2
- package/build/src/cli/coordinates.js +1 -4
- package/build/src/cli/parse.d.ts +2 -3
- package/build/src/cli/parse.js +24 -66
- package/build/src/cli/render/akuma.d.ts +3 -16
- package/build/src/cli/render/akuma.js +1 -13
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/contract.js +34 -32
- package/build/src/cli/render/kanshi-akuma.d.ts +8 -2
- package/build/src/cli/render/kanshi-akuma.js +14 -7
- package/build/src/cli/render/kanshi.d.ts +3 -1
- package/build/src/cli/render/kanshi.js +44 -32
- package/build/src/cli/render/receipt.js +6 -1
- package/build/src/cli/render/task.d.ts +1 -1
- package/build/src/cli/render/task.js +3 -27
- package/build/src/cli/render/terminal.d.ts +6 -2
- package/build/src/cli/render/terminal.js +8 -2
- package/build/src/cli/runtime.js +3 -16
- package/build/src/cli/scan.d.ts +26 -0
- package/build/src/cli/scan.js +82 -0
- package/build/src/cli/streams.d.ts +5 -0
- package/build/src/cli/streams.js +11 -0
- package/build/src/contract-worktree.js +38 -21
- package/build/src/core/facts/codec.d.ts +1 -2
- package/build/src/core/facts/codec.js +5 -11
- package/build/src/core/facts/types.d.ts +16 -2
- package/build/src/core/facts/types.js +15 -0
- package/build/src/core/verbs/abandon.js +3 -9
- package/build/src/core/verbs/amend.js +2 -9
- package/build/src/core/verbs/arc.js +6 -13
- package/build/src/core/verbs/attestation.js +2 -9
- package/build/src/core/verbs/bind.js +2 -9
- package/build/src/core/verbs/deliver.js +2 -9
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +2 -9
- package/build/src/core/verbs/reintegrate.d.ts +1 -1
- package/build/src/core/verbs/reintegrate.js +2 -9
- package/build/src/dispatch/index.d.ts +2 -2
- package/build/src/dispatch/index.js +33 -11
- package/build/src/git/hooks.d.ts +2 -4
- package/build/src/git/hooks.js +0 -12
- package/build/src/git/integration.d.ts +5 -3
- package/build/src/git/integration.js +36 -25
- package/build/src/git/nuke.js +4 -4
- package/build/src/git/observe.d.ts +4 -4
- package/build/src/git/observe.js +5 -5
- package/build/src/git/process.d.ts +1 -4
- package/build/src/git/process.js +1 -11
- package/build/src/git/read-observation.js +1 -1
- package/build/src/git/reconcile.d.ts +1 -1
- package/build/src/git/reconcile.js +15 -13
- package/build/src/git/repository.d.ts +2 -6
- package/build/src/git/repository.js +18 -31
- package/build/src/git/scratch.d.ts +6 -6
- package/build/src/git/scratch.js +110 -46
- package/build/src/git/target-placement.d.ts +5 -5
- package/build/src/git/target-placement.js +18 -33
- package/build/src/git/tender.d.ts +6 -2
- package/build/src/git/tender.js +19 -12
- package/build/src/git/terminal-reconcile.js +24 -13
- package/build/src/git/terminal-seal.d.ts +2 -5
- package/build/src/git/terminal-seal.js +5 -3
- package/build/src/git/workspace.d.ts +17 -13
- package/build/src/git/workspace.js +58 -41
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +8 -1
- package/build/src/kanshi/read.js +72 -7
- package/build/src/kanshi/report.d.ts +12 -0
- package/build/src/library/akuma-creation.d.ts +4 -4
- package/build/src/library/akuma-creation.js +21 -19
- package/build/src/library/bind.d.ts +1 -63
- package/build/src/library/bind.js +3 -9
- package/build/src/library/contract-creation.js +2 -30
- package/build/src/library/contract-execution.d.ts +0 -1
- package/build/src/library/contract-execution.js +9 -34
- package/build/src/library/contract-operations.d.ts +5 -1
- package/build/src/library/contract-operations.js +7 -3
- package/build/src/library/contract-types.d.ts +1 -1
- package/build/src/library/delivery.d.ts +91 -93
- package/build/src/library/delivery.js +2 -1
- package/build/src/library/input.d.ts +0 -2
- package/build/src/library/input.js +0 -4
- package/build/src/library/invocation.d.ts +0 -1
- package/build/src/library/invocation.js +3 -25
- package/build/src/library/outcome.d.ts +651 -602
- package/build/src/library/outcome.js +4 -4
- package/build/src/library/reconcile.d.ts +6 -0
- package/build/src/library/reconcile.js +31 -1
- package/build/src/library/repo.d.ts +0 -1
- package/build/src/library/selection.d.ts +1 -10
- package/build/src/library/selection.js +19 -17
- package/build/src/plugin/akuma-signals.d.ts +10 -11
- package/build/src/plugin/akuma-signals.js +36 -20
- package/build/src/plugin/public.d.ts +5 -0
- package/build/src/plugin/runtime.d.ts +1 -0
- package/build/src/plugin/runtime.js +34 -23
- package/build/src/protocol/abandon.d.ts +1 -1
- package/build/src/protocol/abandon.js +3 -10
- package/build/src/protocol/amend.js +2 -5
- package/build/src/protocol/arc.d.ts +1 -1
- package/build/src/protocol/arc.js +2 -9
- package/build/src/protocol/attempt.d.ts +3 -20
- package/build/src/protocol/attempt.js +6 -5
- package/build/src/protocol/audit.d.ts +1 -0
- package/build/src/protocol/audit.js +10 -11
- package/build/src/protocol/completion.d.ts +129 -55
- package/build/src/protocol/completion.js +62 -73
- package/build/src/protocol/deliver.d.ts +7 -5
- package/build/src/protocol/deliver.js +74 -44
- package/build/src/protocol/execution-observation.d.ts +2 -4
- package/build/src/protocol/execution-observation.js +3 -7
- package/build/src/protocol/intent.d.ts +1 -1
- package/build/src/protocol/intent.js +1 -0
- package/build/src/protocol/operations.d.ts +24 -12
- package/build/src/protocol/operations.js +36 -15
- package/build/src/protocol/placement.d.ts +2 -1
- package/build/src/protocol/placement.js +21 -5
- package/build/src/protocol/progress.d.ts +1 -1
- package/build/src/protocol/read/status.js +58 -41
- package/build/src/protocol/reintegrate.d.ts +1 -1
- package/build/src/protocol/reintegrate.js +10 -19
- package/build/src/protocol/review.d.ts +3 -28
- package/build/src/protocol/review.js +10 -37
- package/build/src/protocol/run.d.ts +19 -7
- package/build/src/protocol/run.js +19 -9
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settlement/holder.d.ts +2 -4
- package/build/src/settlement/holder.js +3 -6
- package/build/src/task/board.d.ts +6 -0
- package/build/src/task/board.js +30 -1
- package/build/src/task/catalog.js +1 -4
- package/build/src/task/compose.d.ts +0 -1
- package/build/src/task/compose.js +0 -1
- package/build/src/task/context.d.ts +0 -1
- package/build/src/task/context.js +0 -3
- package/build/src/task/created-observation.d.ts +5 -1
- package/build/src/task/created-observation.js +12 -5
- package/build/src/task/index.d.ts +1 -1
- package/build/src/task/index.js +7 -6
- package/build/src/task/input.d.ts +0 -6
- package/build/src/task/input.js +2 -14
- package/build/src/task/mutation.d.ts +3 -4
- package/build/src/task/mutation.js +11 -39
- package/build/src/task/operations.d.ts +2 -7
- package/build/src/task/operations.js +37 -49
- package/build/src/task/query.d.ts +0 -1
- package/build/src/task/query.js +1 -4
- package/build/src/task/store.d.ts +0 -2
- package/build/src/task/store.js +27 -11
- package/build/src/verification/declaration.js +3 -2
- package/build/src/verification/execution.d.ts +3 -2
- package/build/src/verification/execution.js +10 -6
- package/build/src/workspace-place.d.ts +0 -1
- package/build/src/workspace-place.js +0 -11
- package/package.json +13 -9
- package/build/integrations/marketplace/.claude-plugin/marketplace.json +0 -5
- package/build/integrations/marketplace/plugins/keiyaku/package.json +0 -17
- /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/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/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/opencode.js → plugins/opencode/index.js} +0 -0
- /package/build/{integrations → plugins}/pi/keiyaku.ts +0 -0
|
@@ -2,8 +2,9 @@ import { z } from "zod";
|
|
|
2
2
|
import type { ContractId, SnapshotId } from "../core/facts/types.js";
|
|
3
3
|
import { type GitObjectId } from "./identity.js";
|
|
4
4
|
import { type GitRepository } from "./process.js";
|
|
5
|
+
import type { GitReadObservation } from "./read-observation.js";
|
|
5
6
|
import type { ContractWorkspaceLocation } from "../workspace-place.js";
|
|
6
|
-
|
|
7
|
+
type WorkspaceChanges = Readonly<{
|
|
7
8
|
staged: readonly string[];
|
|
8
9
|
unstaged: readonly string[];
|
|
9
10
|
untracked: readonly string[];
|
|
@@ -19,7 +20,7 @@ export type WorkspaceTree = Readonly<{
|
|
|
19
20
|
export declare function worktreePath(repository: GitRepository, place: string): string;
|
|
20
21
|
/** Check out a captured candidate tree in the appointed detached worktree. */
|
|
21
22
|
export declare function checkoutDetachedSnapshot(repository: GitRepository, workspace: string, snapshot: SnapshotId): Promise<void>;
|
|
22
|
-
|
|
23
|
+
type DependentWorktreeFollow = Readonly<{
|
|
23
24
|
kind: "followed";
|
|
24
25
|
before: SnapshotId;
|
|
25
26
|
after: SnapshotId;
|
|
@@ -42,7 +43,7 @@ export declare function workspaceMergeHead(repository: GitRepository, workspace:
|
|
|
42
43
|
export declare function workspaceMergeStatePresent(repository: GitRepository, workspace: string): Promise<boolean>;
|
|
43
44
|
/** Sorted unique unmerged index paths from porcelain status. */
|
|
44
45
|
export declare function unmergedWorkspacePaths(repository: GitRepository, workspace: string): Promise<readonly string[]>;
|
|
45
|
-
|
|
46
|
+
type WorkspaceChangeCounts = Readonly<{
|
|
46
47
|
staged: number;
|
|
47
48
|
unstaged: number;
|
|
48
49
|
untracked: number;
|
|
@@ -55,7 +56,7 @@ export declare const conflictRecoverySchema: z.ZodObject<{
|
|
|
55
56
|
}, z.core.$strict>;
|
|
56
57
|
type ConflictRecovery = z.infer<typeof conflictRecoverySchema>;
|
|
57
58
|
export declare const conflictRecovery: ConflictRecovery;
|
|
58
|
-
|
|
59
|
+
type ContractWorkspaceMerge = Readonly<{
|
|
59
60
|
head: SnapshotId;
|
|
60
61
|
unmergedPaths: readonly string[];
|
|
61
62
|
handoffBase?: SnapshotId;
|
|
@@ -100,7 +101,16 @@ export declare function observeWorkspace(repository: GitRepository, location: Co
|
|
|
100
101
|
export declare function observeTargetLag(repository: GitRepository, workspace: string, head: SnapshotId | null | undefined): Promise<ContractTargetLag>;
|
|
101
102
|
/** Capture tracked and untracked workspace bytes without changing its real index. */
|
|
102
103
|
export declare function captureWorkspaceTree(repository: GitRepository, workspace: string): Promise<WorkspaceTree>;
|
|
103
|
-
export type
|
|
104
|
+
export type HandoffReceiptCoordinate = Readonly<{
|
|
105
|
+
contractId: ContractId;
|
|
106
|
+
place: string;
|
|
107
|
+
workspace: string;
|
|
108
|
+
}>;
|
|
109
|
+
export type ConflictHandoff = Readonly<{
|
|
110
|
+
base: SnapshotId;
|
|
111
|
+
mergeHead: SnapshotId;
|
|
112
|
+
}>;
|
|
113
|
+
type HandoffRetirement = Readonly<{
|
|
104
114
|
kind: "absent" | "active" | "orphan-retired" | "retired";
|
|
105
115
|
}> | Readonly<{
|
|
106
116
|
kind: "retained";
|
|
@@ -113,14 +123,8 @@ export declare function recordConflictHandoff(repository: GitRepository, input:
|
|
|
113
123
|
head: SnapshotId;
|
|
114
124
|
mergeHead: SnapshotId;
|
|
115
125
|
}>): Promise<void>;
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
place: string;
|
|
119
|
-
workspace: string;
|
|
120
|
-
}>): Promise<Readonly<{
|
|
121
|
-
base: SnapshotId;
|
|
122
|
-
mergeHead: SnapshotId;
|
|
123
|
-
}> | undefined>;
|
|
126
|
+
/** Read selected handoff refs once and decode their receipts through the call's blob channel. */
|
|
127
|
+
export declare function readConflictHandoffs(repository: GitRepository, readBlobs: GitReadObservation["readBlobs"], coordinates: readonly HandoffReceiptCoordinate[]): Promise<ReadonlyMap<ContractId, ConflictHandoff>>;
|
|
124
128
|
export declare function retireConflictHandoff(repository: GitRepository, input: Readonly<{
|
|
125
129
|
contractId: ContractId;
|
|
126
130
|
place: string;
|
|
@@ -2,20 +2,21 @@ import { z } from "zod";
|
|
|
2
2
|
import { access, mkdtemp, rm } from "node:fs/promises";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
|
+
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
5
6
|
import { contractPhysicalName, gitObjectId, mintSnapshotId } from "./identity.js";
|
|
6
|
-
import {
|
|
7
|
-
import { HANDOFF_RECEIPT_REF_NAMESPACE, readBlob, readRef, worktreeGitDirectory, writeBlob } from "./repository.js";
|
|
7
|
+
import { executeGit, GitPlumbingError } from "./process.js";
|
|
8
|
+
import { HANDOFF_RECEIPT_REF_NAMESPACE, readBlob, readRef, readRefs, worktreeGitDirectory, writeBlob, } from "./repository.js";
|
|
8
9
|
const WORKTREE_DIRECTORY = [".keiyaku", "wt"];
|
|
9
10
|
export function worktreePath(repository, place) {
|
|
10
11
|
return resolve(repository.primaryWorktree, ...WORKTREE_DIRECTORY, place);
|
|
11
12
|
}
|
|
12
13
|
/** Check out a captured candidate tree in the appointed detached worktree. */
|
|
13
14
|
export async function checkoutDetachedSnapshot(repository, workspace, snapshot) {
|
|
14
|
-
await
|
|
15
|
+
await executeGit(repository, ["-C", workspace, "checkout", "--quiet", "--force", "--detach", gitObjectId(snapshot)]);
|
|
15
16
|
}
|
|
16
17
|
async function workspaceRevision(repository, workspace, revision) {
|
|
17
18
|
try {
|
|
18
|
-
const value = (await
|
|
19
|
+
const value = (await executeGit(repository, ["-C", workspace, "rev-parse", "--verify", "--quiet", revision]))
|
|
19
20
|
.toString("utf8")
|
|
20
21
|
.trim();
|
|
21
22
|
return value.length === 0 ? null : mintSnapshotId(value);
|
|
@@ -37,7 +38,7 @@ async function workspaceOperationState(repository, workspace, gitDirectory) {
|
|
|
37
38
|
return false;
|
|
38
39
|
}
|
|
39
40
|
}));
|
|
40
|
-
const unmerged = (await
|
|
41
|
+
const unmerged = (await executeGit(repository, ["-C", workspace, "ls-files", "--unmerged", "-z"])).length > 0;
|
|
41
42
|
return { other: other.some(Boolean), unmerged };
|
|
42
43
|
}
|
|
43
44
|
/** Follow a dependency baseline only through a clean, detached fast-forward. */
|
|
@@ -58,7 +59,7 @@ export async function followDependentManagedWorktree(repository, workspace, targ
|
|
|
58
59
|
...status.unmergedPaths,
|
|
59
60
|
]),
|
|
60
61
|
].sort();
|
|
61
|
-
const attached = await
|
|
62
|
+
const attached = await executeGit(repository, ["-C", workspace, "symbolic-ref", "--quiet", "HEAD"]).then(() => true, (error) => {
|
|
62
63
|
if (error instanceof GitPlumbingError && error.status === 1)
|
|
63
64
|
return false;
|
|
64
65
|
throw error;
|
|
@@ -72,7 +73,7 @@ export async function followDependentManagedWorktree(repository, workspace, targ
|
|
|
72
73
|
return { kind: "unchanged" };
|
|
73
74
|
let ancestor = false;
|
|
74
75
|
try {
|
|
75
|
-
await
|
|
76
|
+
await executeGit(repository, ["merge-base", "--is-ancestor", gitObjectId(head), gitObjectId(target)]);
|
|
76
77
|
ancestor = true;
|
|
77
78
|
}
|
|
78
79
|
catch (error) {
|
|
@@ -81,17 +82,26 @@ export async function followDependentManagedWorktree(repository, workspace, targ
|
|
|
81
82
|
}
|
|
82
83
|
if (!ancestor)
|
|
83
84
|
return { kind: "retained", head, reason: "head-moved", paths };
|
|
84
|
-
await
|
|
85
|
+
await executeGit(repository, ["-C", workspace, "checkout", "--quiet", "--detach", gitObjectId(target)]);
|
|
85
86
|
return { kind: "followed", before: head, after: target };
|
|
86
87
|
}
|
|
87
88
|
export async function withPrivateGitIndex(action) {
|
|
88
89
|
const directory = await mkdtemp(join(tmpdir(), "keiyaku-v4-index-"));
|
|
90
|
+
let value;
|
|
89
91
|
try {
|
|
90
|
-
|
|
92
|
+
value = await action({ GIT_INDEX_FILE: join(directory, "index") });
|
|
91
93
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
+
catch (error) {
|
|
95
|
+
try {
|
|
96
|
+
await rm(directory, { recursive: true, force: true });
|
|
97
|
+
}
|
|
98
|
+
catch (cleanup) {
|
|
99
|
+
throw new AggregateError([error, cleanup], "Private Git index capture and cleanup failed");
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
94
102
|
}
|
|
103
|
+
await rm(directory, { recursive: true, force: true });
|
|
104
|
+
return value;
|
|
95
105
|
}
|
|
96
106
|
function fields(record, count) {
|
|
97
107
|
const result = [];
|
|
@@ -107,15 +117,7 @@ function fields(record, count) {
|
|
|
107
117
|
return result;
|
|
108
118
|
}
|
|
109
119
|
async function workspaceStatus(repository, workspace) {
|
|
110
|
-
const records = (await
|
|
111
|
-
"-C",
|
|
112
|
-
workspace,
|
|
113
|
-
"status",
|
|
114
|
-
"--porcelain=v2",
|
|
115
|
-
"-z",
|
|
116
|
-
"--untracked-files=all",
|
|
117
|
-
"--ignore-submodules=none",
|
|
118
|
-
]))
|
|
120
|
+
const records = (await executeGit(repository, ["-C", workspace, "status", "--porcelain=v2", "-z", "--untracked-files=all", "--ignore-submodules=none"], undefined, { GIT_OPTIONAL_LOCKS: "0" }))
|
|
119
121
|
.toString("utf8")
|
|
120
122
|
.split("\0");
|
|
121
123
|
const staged = new Set();
|
|
@@ -172,7 +174,7 @@ async function workspaceChanges(repository, workspace) {
|
|
|
172
174
|
/** Observe MERGE_HEAD in an appointed workspace, or undefined when absent. */
|
|
173
175
|
export async function workspaceMergeHead(repository, workspace) {
|
|
174
176
|
try {
|
|
175
|
-
return mintSnapshotId((await
|
|
177
|
+
return mintSnapshotId((await executeGit(repository, ["-C", workspace, "rev-parse", "-q", "--verify", "MERGE_HEAD"]))
|
|
176
178
|
.toString("utf8")
|
|
177
179
|
.trim());
|
|
178
180
|
}
|
|
@@ -250,7 +252,7 @@ export async function observeTargetLag(repository, workspace, head) {
|
|
|
250
252
|
if (head === null)
|
|
251
253
|
return { kind: "unknown", subject };
|
|
252
254
|
try {
|
|
253
|
-
const text = (await
|
|
255
|
+
const text = (await executeGit(repository, ["-C", workspace, "rev-list", "--count", `HEAD..${head}`]))
|
|
254
256
|
.toString("utf8")
|
|
255
257
|
.trim();
|
|
256
258
|
if (!/^[0-9]+$/u.test(text))
|
|
@@ -265,7 +267,7 @@ export async function observeTargetLag(repository, workspace, head) {
|
|
|
265
267
|
}
|
|
266
268
|
/** Capture tracked and untracked workspace bytes without changing its real index. */
|
|
267
269
|
export async function captureWorkspaceTree(repository, workspace) {
|
|
268
|
-
const identities = (await
|
|
270
|
+
const identities = (await executeGit(repository, ["-C", workspace, "show", "-s", "--format=%H%n%T%n%cI", "HEAD"]))
|
|
269
271
|
.toString("utf8")
|
|
270
272
|
.split("\n");
|
|
271
273
|
if (identities.length !== 4 ||
|
|
@@ -285,10 +287,10 @@ export async function captureWorkspaceTree(repository, workspace) {
|
|
|
285
287
|
if (!dirty)
|
|
286
288
|
return { tree, head, at, dirty, changes };
|
|
287
289
|
return await withPrivateGitIndex(async (environment) => {
|
|
288
|
-
await
|
|
289
|
-
await
|
|
290
|
+
await executeGit(repository, ["-C", workspace, "-c", "core.splitIndex=false", "read-tree", gitObjectId(head)], undefined, environment);
|
|
291
|
+
await executeGit(repository, ["-C", workspace, "-c", "core.splitIndex=false", "add", "--all"], undefined, environment);
|
|
290
292
|
return {
|
|
291
|
-
tree: gitObjectId((await
|
|
293
|
+
tree: gitObjectId((await executeGit(repository, ["-C", workspace, "-c", "core.splitIndex=false", "write-tree"], undefined, environment))
|
|
292
294
|
.toString("utf8")
|
|
293
295
|
.trim(), "workspace tree"),
|
|
294
296
|
head,
|
|
@@ -320,6 +322,11 @@ function receiptFor(value) {
|
|
|
320
322
|
mergeHead: mintSnapshotId(record.mergeHead),
|
|
321
323
|
};
|
|
322
324
|
}
|
|
325
|
+
function receiptMatches(receipt, coordinate) {
|
|
326
|
+
return (receipt.contractId === coordinate.contractId &&
|
|
327
|
+
receipt.place === coordinate.place &&
|
|
328
|
+
receipt.workspace === resolve(coordinate.workspace));
|
|
329
|
+
}
|
|
323
330
|
async function storedHandoffReceipt(repository, contractId, place) {
|
|
324
331
|
const ref = handoffRefFor(contractId, place);
|
|
325
332
|
const oid = await readRef(repository, ref);
|
|
@@ -329,7 +336,7 @@ async function storedHandoffReceipt(repository, contractId, place) {
|
|
|
329
336
|
return { receipt, ref, oid };
|
|
330
337
|
}
|
|
331
338
|
async function removeHandoffReceipt(repository, stored) {
|
|
332
|
-
await
|
|
339
|
+
await executeGit(repository, ["update-ref", "--no-deref", "-d", stored.ref, stored.oid]);
|
|
333
340
|
}
|
|
334
341
|
export async function recordConflictHandoff(repository, input) {
|
|
335
342
|
const ref = handoffRefFor(input.contractId, input.place);
|
|
@@ -345,27 +352,37 @@ export async function recordConflictHandoff(repository, input) {
|
|
|
345
352
|
mergeHead: input.mergeHead,
|
|
346
353
|
};
|
|
347
354
|
const oid = await writeBlob(repository, `${JSON.stringify(receipt)}\n`);
|
|
348
|
-
await
|
|
355
|
+
await executeGit(repository, ["update-ref", "--no-deref", ref, oid, "0".repeat(oid.length)]);
|
|
349
356
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
357
|
+
/** Read selected handoff refs once and decode their receipts through the call's blob channel. */
|
|
358
|
+
export async function readConflictHandoffs(repository, readBlobs, coordinates) {
|
|
359
|
+
const byRef = new Map();
|
|
360
|
+
for (const coordinate of coordinates)
|
|
361
|
+
byRef.set(handoffRefFor(coordinate.contractId, coordinate.place), coordinate);
|
|
362
|
+
if (byRef.size === 0)
|
|
363
|
+
return new Map();
|
|
364
|
+
const resolved = await readRefs(repository, [...byRef.keys()]);
|
|
365
|
+
const present = [...resolved].flatMap(([ref, oid]) => (oid === null ? [] : [{ ref, oid }]));
|
|
366
|
+
const blobs = await readBlobs(present.map(({ oid }) => oid));
|
|
367
|
+
const handoffs = new Map();
|
|
368
|
+
for (const { ref, oid } of present) {
|
|
369
|
+
const result = blobs.get(oid);
|
|
370
|
+
if (result?.kind !== "present")
|
|
371
|
+
throw new AuthorityCorruptionError(`Git handoff receipt is missing: ${ref}`);
|
|
372
|
+
const receipt = receiptFor(JSON.parse(result.bytes.toString("utf8")));
|
|
373
|
+
const coordinate = byRef.get(ref);
|
|
374
|
+
if (!receiptMatches(receipt, coordinate))
|
|
375
|
+
continue;
|
|
376
|
+
handoffs.set(coordinate.contractId, { base: receipt.head, mergeHead: receipt.mergeHead });
|
|
358
377
|
}
|
|
359
|
-
return
|
|
378
|
+
return handoffs;
|
|
360
379
|
}
|
|
361
380
|
export async function retireConflictHandoff(repository, input) {
|
|
362
381
|
const stored = await storedHandoffReceipt(repository, input.contractId, input.place);
|
|
363
382
|
if (stored === null)
|
|
364
383
|
return { kind: "absent" };
|
|
365
384
|
const { receipt } = stored;
|
|
366
|
-
if (receipt
|
|
367
|
-
receipt.place !== input.place ||
|
|
368
|
-
receipt.workspace !== resolve(input.workspace)) {
|
|
385
|
+
if (!receiptMatches(receipt, input)) {
|
|
369
386
|
return { kind: "retained", reason: "receipt-mismatch" };
|
|
370
387
|
}
|
|
371
388
|
const gitDirectory = await worktreeGitDirectory(repository, input.workspace);
|
|
@@ -389,7 +406,7 @@ export async function retireConflictHandoff(repository, input) {
|
|
|
389
406
|
}
|
|
390
407
|
if (!input.consume)
|
|
391
408
|
return { kind: "active" };
|
|
392
|
-
await
|
|
409
|
+
await executeGit(repository, ["-C", input.workspace, "merge", "--quit"]);
|
|
393
410
|
await removeHandoffReceipt(repository, stored);
|
|
394
411
|
return { kind: "retired" };
|
|
395
412
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { kanshi, observeKanshi } from "./read.js";
|
|
1
|
+
export { kanshi, kanshiCategory, observeKanshi } from "./read.js";
|
|
2
2
|
export { selectKanshi, selectRegion } from "./select.js";
|
|
3
3
|
export type { KanshiInput } from "./read.js";
|
|
4
|
-
export type { AkumaKanshiRow, AkumaKanshiWorld, ContractEndpointObservation, ContractHolderObservation, ContractKanshiBoard, ContractKanshiRow, KanshiReport, Section, TaskKanshiRow, TaskKanshiWorld, KanshiRegionSelection, RegionDeclaration, RegionOverlap, RegionRead, } from "./report.js";
|
|
4
|
+
export type { AkumaKanshiRow, AkumaKanshiWorld, ContractEndpointObservation, ContractHolderObservation, ContractKanshiBoard, ContractKanshiRow, KanshiCategoryReport, KanshiReport, Section, TaskKanshiRow, TaskKanshiWorld, KanshiRegionSelection, RegionDeclaration, RegionOverlap, RegionRead, } from "./report.js";
|
|
5
5
|
export type { KanshiSelection } from "./select.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { kanshi, observeKanshi } from "./read.js";
|
|
1
|
+
export { kanshi, kanshiCategory, observeKanshi } from "./read.js";
|
|
2
2
|
export { selectKanshi, selectRegion } from "./select.js";
|
|
@@ -2,7 +2,7 @@ import { type AliasBinding } from "../alias/index.js";
|
|
|
2
2
|
import { Repo } from "../library/repo.js";
|
|
3
3
|
import type { ContractBoard } from "../protocol/read/status.js";
|
|
4
4
|
import type { WorldRoot } from "../world.js";
|
|
5
|
-
import type { KanshiRegionSelection, KanshiReport, Section } from "./report.js";
|
|
5
|
+
import type { KanshiCategoryReport, KanshiRegionSelection, KanshiReport, Section } from "./report.js";
|
|
6
6
|
export type KanshiInput = Readonly<{
|
|
7
7
|
world: WorldRoot | null;
|
|
8
8
|
repo?: Repo;
|
|
@@ -15,3 +15,10 @@ export type KanshiObservation = Readonly<{
|
|
|
15
15
|
}>;
|
|
16
16
|
export declare function observeKanshi(input: KanshiInput): Promise<KanshiObservation>;
|
|
17
17
|
export declare function kanshi(input: KanshiInput): Promise<KanshiReport>;
|
|
18
|
+
export type KanshiCategoryInput = Readonly<{
|
|
19
|
+
world: WorldRoot | null;
|
|
20
|
+
repo?: Repo;
|
|
21
|
+
category: KanshiCategoryReport["category"];
|
|
22
|
+
limit?: number;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function kanshiCategory(input: KanshiCategoryInput): Promise<KanshiCategoryReport>;
|
package/build/src/kanshi/read.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { withoutReportedChanges } from "../akuma/projection.js";
|
|
2
|
-
import {
|
|
2
|
+
import { observeAkumaRoster, readAkumaTimeline } from "../akuma/akuma.js";
|
|
3
3
|
import { readAliases } from "../alias/index.js";
|
|
4
4
|
import { decodeContractDocument } from "../body/decode.js";
|
|
5
5
|
import { assertRegionPattern } from "../body/region.js";
|
|
@@ -16,6 +16,7 @@ import { observeRecentTaskStatus, TaskAuthorityCorruptionError } from "../task/i
|
|
|
16
16
|
import { observeTaskBoard } from "../task/operations.js";
|
|
17
17
|
import { ROSTER_SNAPSHOT_ROWS, ROSTER_VISIBLE_ROWS } from "./roster.js";
|
|
18
18
|
import { selectKanshi, selectRegion } from "./select.js";
|
|
19
|
+
const WORLD_CONTRACT_ROWS = 10;
|
|
19
20
|
function diagnostic(error) {
|
|
20
21
|
let source;
|
|
21
22
|
if (error instanceof Error)
|
|
@@ -128,12 +129,12 @@ async function readBranch(repo) {
|
|
|
128
129
|
return null;
|
|
129
130
|
}
|
|
130
131
|
}
|
|
131
|
-
async function readContracts(observation, include) {
|
|
132
|
+
async function readContracts(observation, include, limit = WORLD_CONTRACT_ROWS) {
|
|
132
133
|
try {
|
|
133
134
|
return {
|
|
134
135
|
kind: "present",
|
|
135
136
|
value: include === undefined
|
|
136
|
-
? await readContractCatalogue(observation,
|
|
137
|
+
? await readContractCatalogue(observation, limit)
|
|
137
138
|
: await readContractBoard(observation, include),
|
|
138
139
|
};
|
|
139
140
|
}
|
|
@@ -282,11 +283,12 @@ async function claimedAssociatedContracts(observation, dispatches) {
|
|
|
282
283
|
}));
|
|
283
284
|
return claimed;
|
|
284
285
|
}
|
|
285
|
-
async function joinAkuma(path, observeContract, isContractClaimed, dispatches,
|
|
286
|
+
async function joinAkuma(path, observeContract, isContractClaimed, dispatches, input) {
|
|
287
|
+
const { aliases, limit = ROSTER_VISIBLE_ROWS } = input;
|
|
286
288
|
if (aliases.kind !== "present")
|
|
287
289
|
return aliases;
|
|
288
290
|
try {
|
|
289
|
-
const source = await
|
|
291
|
+
const source = await observeAkumaRoster(path, limit);
|
|
290
292
|
const aliasById = new Map();
|
|
291
293
|
for (const binding of aliases.value)
|
|
292
294
|
aliasById.set(binding.akuId, [...(aliasById.get(binding.akuId) ?? []), binding]);
|
|
@@ -355,7 +357,9 @@ async function observeWithoutRepo(world, region, observedAt, branch) {
|
|
|
355
357
|
const observeContract = contractEndpointObserver(contracts);
|
|
356
358
|
const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
|
|
357
359
|
const aliases = world === null ? { kind: "absent" } : await readAliasBindings(world);
|
|
358
|
-
const akuma = world === null
|
|
360
|
+
const akuma = world === null
|
|
361
|
+
? { kind: "absent" }
|
|
362
|
+
: await joinAkuma(world, observeContract, () => false, [], { aliases });
|
|
359
363
|
return {
|
|
360
364
|
report: {
|
|
361
365
|
root: world,
|
|
@@ -394,7 +398,7 @@ async function observeRepo(input) {
|
|
|
394
398
|
? { kind: "absent" }
|
|
395
399
|
: dispatches.kind === "failed"
|
|
396
400
|
? dispatches
|
|
397
|
-
: await joinAkuma(world, observeContract, (id) => claimed.has(id), dispatches.value, aliases);
|
|
401
|
+
: await joinAkuma(world, observeContract, (id) => claimed.has(id), dispatches.value, { aliases });
|
|
398
402
|
const assembled = {
|
|
399
403
|
root: world,
|
|
400
404
|
observedAt,
|
|
@@ -443,6 +447,67 @@ export async function observeKanshi(input) {
|
|
|
443
447
|
export async function kanshi(input) {
|
|
444
448
|
return (await observeKanshi(input)).report;
|
|
445
449
|
}
|
|
450
|
+
/** Category observations reuse owner rows without reading the Task board. */
|
|
451
|
+
async function observeAkumaCategory(world, repo, limit, observedAt) {
|
|
452
|
+
const report = (akuma) => ({
|
|
453
|
+
category: "akuma",
|
|
454
|
+
root: world,
|
|
455
|
+
observedAt,
|
|
456
|
+
akuma,
|
|
457
|
+
});
|
|
458
|
+
if (world === null)
|
|
459
|
+
return report({ kind: "absent" });
|
|
460
|
+
const composed = async (observation) => {
|
|
461
|
+
const aliases = await readAliasBindings(world);
|
|
462
|
+
if (aliases.kind !== "present")
|
|
463
|
+
return report(aliases);
|
|
464
|
+
if (observation === undefined)
|
|
465
|
+
return report(await joinAkuma(world, () => "unavailable", () => false, [], { aliases, limit }));
|
|
466
|
+
const dispatches = await readDispatches(observation);
|
|
467
|
+
if (dispatches.kind === "failed")
|
|
468
|
+
return report(dispatches);
|
|
469
|
+
const claimed = await claimedAssociatedContracts(observation, dispatches.value);
|
|
470
|
+
return report(await joinAkuma(world, () => "unavailable", (id) => claimed.has(id), dispatches.value, { aliases, limit }));
|
|
471
|
+
};
|
|
472
|
+
if (repo === undefined)
|
|
473
|
+
return await composed();
|
|
474
|
+
try {
|
|
475
|
+
return await withGitDecodeChannel(repo, (channel) => withGitReadObservation(repo, channel, composed));
|
|
476
|
+
}
|
|
477
|
+
catch (error) {
|
|
478
|
+
return report({ kind: "failed", failure: { message: diagnostic(error) } });
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
async function observeContractCategory(world, repo, limit, observedAt) {
|
|
482
|
+
const report = (contracts) => ({
|
|
483
|
+
category: "contract",
|
|
484
|
+
root: world,
|
|
485
|
+
observedAt,
|
|
486
|
+
contracts,
|
|
487
|
+
});
|
|
488
|
+
try {
|
|
489
|
+
return await withGitDecodeChannel(repo, (channel) => withGitReadObservation(repo, channel, async (observation) => {
|
|
490
|
+
const [contracts, holders] = await Promise.all([
|
|
491
|
+
readContracts(observation, undefined, limit),
|
|
492
|
+
readHolders(observation),
|
|
493
|
+
]);
|
|
494
|
+
return report(decorateContracts(contracts, holders));
|
|
495
|
+
}));
|
|
496
|
+
}
|
|
497
|
+
catch (error) {
|
|
498
|
+
return report({ kind: "failed", failure: { message: diagnostic(error) } });
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
export async function kanshiCategory(input) {
|
|
502
|
+
const observedAt = new Date().toISOString();
|
|
503
|
+
const { world, repo, category, limit = 10 } = input;
|
|
504
|
+
if (category === "contract") {
|
|
505
|
+
if (repo === undefined)
|
|
506
|
+
throw new TypeError("kanshi contract category requires a Repo");
|
|
507
|
+
return await observeContractCategory(world, scopeForRepo(repo), limit, observedAt);
|
|
508
|
+
}
|
|
509
|
+
return await observeAkumaCategory(world, repo === undefined ? undefined : scopeForRepo(repo), limit, observedAt);
|
|
510
|
+
}
|
|
446
511
|
async function attachSelectedIssue(observation, contracts, selected) {
|
|
447
512
|
if (contracts.kind !== "present")
|
|
448
513
|
return contracts;
|
|
@@ -100,4 +100,16 @@ export type KanshiReport = Readonly<{
|
|
|
100
100
|
akuma: Section<AkumaKanshiWorld>;
|
|
101
101
|
region?: Section<RegionRead>;
|
|
102
102
|
}>;
|
|
103
|
+
/** Internal category observation retains only the requested owner section. */
|
|
104
|
+
export type KanshiCategoryReport = Readonly<{
|
|
105
|
+
category: "akuma";
|
|
106
|
+
root: WorldRoot | null;
|
|
107
|
+
observedAt: string;
|
|
108
|
+
akuma: Section<AkumaKanshiWorld>;
|
|
109
|
+
}> | Readonly<{
|
|
110
|
+
category: "contract";
|
|
111
|
+
root: WorldRoot | null;
|
|
112
|
+
observedAt: string;
|
|
113
|
+
contracts: Section<ContractKanshiBoard>;
|
|
114
|
+
}>;
|
|
103
115
|
export type { CurrentPhysicalIssue };
|
|
@@ -15,8 +15,7 @@ import type { Settings } from "../settings.js";
|
|
|
15
15
|
import { type WorldRoot } from "../world.js";
|
|
16
16
|
import type { Keiyaku } from "./keiyaku.js";
|
|
17
17
|
import { type Repo } from "./repo.js";
|
|
18
|
-
|
|
19
|
-
export type IntegrationFailure = Readonly<{
|
|
18
|
+
type IntegrationFailure = Readonly<{
|
|
20
19
|
kind: "authority-corruption" | "infrastructure";
|
|
21
20
|
diagnostic: string;
|
|
22
21
|
}>;
|
|
@@ -30,7 +29,7 @@ export type DispatchStage = Readonly<{
|
|
|
30
29
|
kind: "failed";
|
|
31
30
|
failure: DispatchFailure | IntegrationFailure;
|
|
32
31
|
}>;
|
|
33
|
-
|
|
32
|
+
type AliasStage = Readonly<{
|
|
34
33
|
kind: "none";
|
|
35
34
|
}> | Readonly<{
|
|
36
35
|
kind: "aliased";
|
|
@@ -47,7 +46,7 @@ export type CallWaitHead = Readonly<{
|
|
|
47
46
|
dispatch: DispatchStage;
|
|
48
47
|
alias: AliasStage;
|
|
49
48
|
}>;
|
|
50
|
-
|
|
49
|
+
type CallWaitObserver = Readonly<{
|
|
51
50
|
admitted?: (tell: TellResult, id: AkumaStatus["id"], head: CallWaitHead) => void | Promise<void>;
|
|
52
51
|
observe?: AskObserver["observe"];
|
|
53
52
|
}>;
|
|
@@ -117,3 +116,4 @@ export declare function callAkumas(input: CallInput & Readonly<{
|
|
|
117
116
|
export declare function forkAkumas(input: ForkInput & Readonly<{
|
|
118
117
|
path: WorldRoot;
|
|
119
118
|
}>): Promise<ForkResult>;
|
|
119
|
+
export {};
|
|
@@ -13,7 +13,7 @@ import { moveAlias } from "../alias/index.js";
|
|
|
13
13
|
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
14
14
|
import { publishDispatch, readDispatch } from "../dispatch/index.js";
|
|
15
15
|
import { parseAkumaAlias } from "../identity/selector.js";
|
|
16
|
-
import {
|
|
16
|
+
import { emitPluginSignal, outcomePluginObserver } from "../plugin/akuma-signals.js";
|
|
17
17
|
import { World } from "../world.js";
|
|
18
18
|
import { addressAkuma } from "./address.js";
|
|
19
19
|
import { requireInput } from "./input.js";
|
|
@@ -108,9 +108,9 @@ function pluginDiagnostic(error) {
|
|
|
108
108
|
const message = error instanceof Error ? error.message : String(error);
|
|
109
109
|
return message.length <= 500 ? message : `${message.slice(0, 500)}...`;
|
|
110
110
|
}
|
|
111
|
-
async function recordPluginDiagnostic(paths, error) {
|
|
111
|
+
async function recordPluginDiagnostic(paths, error, occurrence = "call admission") {
|
|
112
112
|
try {
|
|
113
|
-
await appendFile(paths.log, `plugin
|
|
113
|
+
await appendFile(paths.log, `plugin ${occurrence} failed: ${pluginDiagnostic(error)}\n`);
|
|
114
114
|
}
|
|
115
115
|
catch {
|
|
116
116
|
// Plugin diagnostic loss must not change an already admitted call.
|
|
@@ -126,22 +126,16 @@ async function emitCalledSignal(input) {
|
|
|
126
126
|
try {
|
|
127
127
|
const paths = pathsForAkuId(input.path, input.admitted.id);
|
|
128
128
|
const callerAkumaId = input.admitted.requested ? await requestedParent(input.path, input.admitted.id) : undefined;
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
...(input.contractId === undefined ? {} : { contractId: input.contractId }),
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
catch (error) {
|
|
143
|
-
await recordPluginDiagnostic(paths, error);
|
|
144
|
-
}
|
|
129
|
+
await emitPluginSignal({
|
|
130
|
+
world: input.path,
|
|
131
|
+
...(input.settings === undefined ? {} : { settings: input.settings }),
|
|
132
|
+
reportDiagnostic: (message) => void recordPluginDiagnostic(paths, message),
|
|
133
|
+
}, {
|
|
134
|
+
kind: "akuma.called",
|
|
135
|
+
akumaId: input.admitted.id,
|
|
136
|
+
...(callerAkumaId === undefined ? {} : { callerAkumaId }),
|
|
137
|
+
...(input.contractId === undefined ? {} : { contractId: input.contractId }),
|
|
138
|
+
});
|
|
145
139
|
}
|
|
146
140
|
catch {
|
|
147
141
|
// Plugin delivery must not change an already admitted call.
|
|
@@ -320,6 +314,13 @@ async function observeCall(input) {
|
|
|
320
314
|
tellId: input.initialTell.tellId,
|
|
321
315
|
timeoutMs: input.timeoutMs,
|
|
322
316
|
receipt: input.receipt,
|
|
317
|
+
outcomeObserved: outcomePluginObserver({
|
|
318
|
+
world: input.path,
|
|
319
|
+
...(input.settings === undefined ? {} : { settings: input.settings }),
|
|
320
|
+
reportDiagnostic: (message) => {
|
|
321
|
+
void recordPluginDiagnostic(pathsForAkuId(input.path, input.akuma), message, "outcome observation");
|
|
322
|
+
},
|
|
323
|
+
}),
|
|
323
324
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
324
325
|
onObserve,
|
|
325
326
|
});
|
|
@@ -400,6 +401,7 @@ export async function callAkumas(input, execution = localExecutionContext()) {
|
|
|
400
401
|
initialTell: parsed.initialTell,
|
|
401
402
|
receipt,
|
|
402
403
|
timeoutMs: parsed.timeoutMs,
|
|
404
|
+
...(parsed.settings === undefined ? {} : { settings: parsed.settings }),
|
|
403
405
|
...(parsed.signal === undefined ? {} : { signal: parsed.signal }),
|
|
404
406
|
...(parsed.observe === undefined ? {} : { observe: parsed.observe }),
|
|
405
407
|
});
|