@astrosheep/keiyaku 4.0.1 → 4.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +137 -5
- package/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +3 -3
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +91 -35
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +98 -58
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +152 -53
- package/build/src/akuma/abort.d.ts +2 -0
- package/build/src/akuma/abort.js +50 -0
- package/build/src/akuma/akuma.d.ts +23 -14
- package/build/src/akuma/akuma.js +120 -104
- package/build/src/akuma/archetype.d.ts +7 -6
- package/build/src/akuma/archetype.js +68 -41
- package/build/src/akuma/body.d.ts +3 -5
- package/build/src/akuma/body.js +408 -213
- package/build/src/akuma/heart/facts.d.ts +25 -34
- package/build/src/akuma/heart/facts.js +18 -7
- package/build/src/akuma/heart/index.d.ts +39 -42
- package/build/src/akuma/heart/index.js +134 -93
- package/build/src/akuma/heart/rows.d.ts +9 -31
- package/build/src/akuma/heart/rows.js +26 -44
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +7 -15
- package/build/src/akuma/heart/soul.d.ts +8 -0
- package/build/src/akuma/heart/soul.js +136 -0
- package/build/src/akuma/heart/storage.d.ts +28 -14
- package/build/src/akuma/heart/storage.js +86 -26
- package/build/src/akuma/identity.d.ts +2 -2
- package/build/src/akuma/identity.js +9 -9
- package/build/src/akuma/index.d.ts +6 -1
- package/build/src/akuma/index.js +6 -0
- package/build/src/akuma/projection.d.ts +117 -38
- package/build/src/akuma/projection.js +208 -97
- package/build/src/akuma/provider-recipe.d.ts +24 -0
- package/build/src/akuma/provider-recipe.js +100 -0
- package/build/src/akuma/provider.d.ts +12 -4
- package/build/src/akuma/provider.js +117 -70
- package/build/src/akuma/providers/acp/core.d.ts +19 -0
- package/build/src/akuma/providers/acp/core.js +159 -0
- package/build/src/akuma/providers/acp/events.d.ts +20 -0
- package/build/src/akuma/providers/acp/events.js +73 -0
- package/build/src/akuma/providers/acp/index.d.ts +12 -0
- package/build/src/akuma/providers/acp/index.js +94 -0
- package/build/src/akuma/providers/claude/events.js +66 -13
- package/build/src/akuma/providers/claude/index.d.ts +2 -1
- package/build/src/akuma/providers/claude/index.js +35 -21
- package/build/src/akuma/providers/codex-app-server/events.js +4 -1
- package/build/src/akuma/providers/codex-app-server/index.d.ts +3 -3
- package/build/src/akuma/providers/codex-app-server/index.js +24 -31
- package/build/src/akuma/providers/grok-build/index.d.ts +4 -0
- package/build/src/akuma/providers/grok-build/index.js +70 -0
- package/build/src/akuma/providers/index.d.ts +5 -3
- package/build/src/akuma/providers/index.js +24 -59
- package/build/src/akuma/providers/opencode-sdk/events.d.ts +40 -34
- package/build/src/akuma/providers/opencode-sdk/events.js +220 -101
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +3 -2
- package/build/src/akuma/providers/opencode-sdk/index.js +233 -128
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +11 -26
- package/build/src/akuma/providers/opencode-sdk/session.js +10 -9
- package/build/src/akuma/providers/pi/events.js +49 -11
- package/build/src/akuma/providers/pi/index.d.ts +1 -1
- package/build/src/akuma/providers/pi/index.js +50 -21
- package/build/src/akuma/publication.d.ts +3 -3
- package/build/src/akuma/publication.js +28 -40
- package/build/src/akuma/requests.d.ts +9 -7
- package/build/src/akuma/requests.js +92 -65
- package/build/src/alias/index.d.ts +2 -2
- package/build/src/alias/index.js +10 -10
- package/build/src/body/decode.js +7 -1
- package/build/src/body/region.d.ts +2 -0
- package/build/src/body/region.js +77 -7
- package/build/src/cli/accepted.d.ts +17 -13
- package/build/src/cli/accepted.js +72 -34
- package/build/src/cli/actor.js +3 -3
- package/build/src/cli/commands/akuma-invoke.d.ts +4 -3
- package/build/src/cli/commands/akuma-invoke.js +14 -9
- package/build/src/cli/commands/akuma.d.ts +13 -3
- package/build/src/cli/commands/akuma.js +67 -34
- package/build/src/cli/commands/contract.d.ts +18 -5
- package/build/src/cli/commands/contract.js +9 -3
- package/build/src/cli/commands/task-invoke.d.ts +17 -4
- package/build/src/cli/commands/task-invoke.js +43 -20
- package/build/src/cli/commands/task-query.d.ts +5 -0
- package/build/src/cli/commands/task-query.js +247 -0
- package/build/src/cli/commands/task.d.ts +3 -1
- package/build/src/cli/commands/task.js +51 -13
- package/build/src/cli/coordinates.d.ts +18 -0
- package/build/src/cli/coordinates.js +120 -0
- package/build/src/cli/draft.d.ts +8 -0
- package/build/src/cli/draft.js +96 -0
- package/build/src/cli/invoke.d.ts +4 -3
- package/build/src/cli/invoke.js +160 -179
- package/build/src/cli/main.js +34 -6
- package/build/src/cli/parse.d.ts +9 -2
- package/build/src/cli/parse.js +29 -7
- package/build/src/cli/render/akuma-tool-command.d.ts +6 -0
- package/build/src/cli/render/akuma-tool-command.js +144 -0
- package/build/src/cli/render/akuma-tool.d.ts +2 -2
- package/build/src/cli/render/akuma-tool.js +30 -4
- package/build/src/cli/render/akuma.d.ts +1 -0
- package/build/src/cli/render/akuma.js +211 -116
- package/build/src/cli/render/audit.d.ts +3 -0
- package/build/src/cli/render/audit.js +104 -0
- package/build/src/cli/render/contract.d.ts +3 -3
- package/build/src/cli/render/contract.js +192 -79
- package/build/src/cli/render/kanshi.js +263 -168
- package/build/src/cli/render/receipt.d.ts +19 -0
- package/build/src/cli/render/receipt.js +106 -0
- package/build/src/cli/render/refusal.d.ts +16 -2
- package/build/src/cli/render/refusal.js +88 -20
- package/build/src/cli/render/region.d.ts +2 -0
- package/build/src/cli/render/region.js +17 -0
- package/build/src/cli/render/task.d.ts +2 -1
- package/build/src/cli/render/task.js +223 -60
- package/build/src/cli/render/terminal.d.ts +7 -0
- package/build/src/cli/render/terminal.js +46 -0
- package/build/src/cli/render/text.js +6 -3
- package/build/src/cli/result.d.ts +115 -20
- package/build/src/cli/usage.d.ts +1 -0
- package/build/src/cli/usage.js +3 -0
- package/build/src/contract-worktree.d.ts +6 -5
- package/build/src/contract-worktree.js +95 -57
- package/build/src/coordination/durable-file.d.ts +4 -3
- package/build/src/coordination/durable-file.js +29 -25
- package/build/src/coordination/sqlite-transaction-lock.d.ts +4 -0
- package/build/src/coordination/sqlite-transaction-lock.js +22 -5
- package/build/src/core/facts/fold.js +1 -6
- package/build/src/core/facts/gate.d.ts +1 -0
- package/build/src/core/facts/gate.js +1 -0
- package/build/src/core/verbs/amend.d.ts +1 -1
- package/build/src/core/verbs/amend.js +0 -11
- package/build/src/core/verbs/deliver.d.ts +1 -1
- package/build/src/core/verbs/deliver.js +1 -7
- package/build/src/core/verbs/placement.d.ts +1 -1
- package/build/src/core/verbs/placement.js +4 -1
- package/build/src/dispatch/index.d.ts +2 -2
- package/build/src/dispatch/index.js +17 -17
- package/build/src/git/admission.d.ts +1 -1
- package/build/src/git/admission.js +11 -11
- package/build/src/git/hooks.js +13 -13
- package/build/src/git/integration.d.ts +14 -15
- package/build/src/git/integration.js +80 -44
- package/build/src/git/observe.d.ts +5 -3
- package/build/src/git/observe.js +18 -12
- package/build/src/git/read-observation.js +9 -9
- package/build/src/git/reconcile.d.ts +2 -0
- package/build/src/git/reconcile.js +138 -95
- package/build/src/git/repository.d.ts +27 -19
- package/build/src/git/repository.js +155 -83
- package/build/src/git/scratch.d.ts +7 -3
- package/build/src/git/scratch.js +44 -37
- package/build/src/git/target-placement.d.ts +40 -4
- package/build/src/git/target-placement.js +221 -101
- package/build/src/git/tender.d.ts +6 -5
- package/build/src/git/tender.js +24 -43
- package/build/src/git/terminal-seal.d.ts +1 -1
- package/build/src/git/terminal-seal.js +7 -5
- package/build/src/git/workspace.d.ts +36 -4
- package/build/src/git/workspace.js +53 -18
- package/build/src/identity/selector.js +1 -1
- package/build/src/index.d.ts +3 -3
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +2 -2
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +2 -1
- package/build/src/kanshi/read.js +118 -27
- package/build/src/kanshi/report.d.ts +50 -0
- package/build/src/kanshi/select.d.ts +5 -0
- package/build/src/kanshi/select.js +32 -0
- package/build/src/library/address.d.ts +12 -3
- package/build/src/library/address.js +77 -46
- package/build/src/library/akuma-creation.d.ts +6 -1
- package/build/src/library/akuma-creation.js +86 -13
- package/build/src/library/audit.d.ts +18 -0
- package/build/src/library/audit.js +44 -0
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -1
- package/build/src/library/catalog.js +5 -8
- package/build/src/library/contract.d.ts +5 -6
- package/build/src/library/contract.js +11 -35
- package/build/src/library/delivery.d.ts +2 -1
- package/build/src/library/fleet.d.ts +2 -2
- package/build/src/library/fleet.js +35 -71
- package/build/src/library/keiyaku.d.ts +3 -2
- package/build/src/library/keiyaku.js +1 -0
- package/build/src/library/mutation.d.ts +7 -6
- package/build/src/library/mutation.js +23 -25
- package/build/src/library/reconcile.d.ts +29 -0
- package/build/src/library/reconcile.js +179 -0
- package/build/src/library/region.d.ts +12 -0
- package/build/src/library/region.js +15 -1
- package/build/src/library/repo.d.ts +4 -16
- package/build/src/library/repo.js +13 -38
- package/build/src/protocol/attempt.js +6 -6
- package/build/src/protocol/bind.js +4 -4
- package/build/src/protocol/intent.d.ts +15 -2
- package/build/src/protocol/intent.js +21 -6
- package/build/src/protocol/operations.d.ts +73 -22
- package/build/src/protocol/operations.js +292 -88
- package/build/src/protocol/outcome.d.ts +9 -3
- package/build/src/protocol/outcome.js +3 -1
- package/build/src/protocol/placement.d.ts +15 -4
- package/build/src/protocol/placement.js +58 -25
- package/build/src/protocol/read/status.d.ts +8 -1
- package/build/src/protocol/read/status.js +61 -14
- package/build/src/runtime/proc/line-rpc.d.ts +3 -8
- package/build/src/runtime/proc/line-rpc.js +16 -43
- package/build/src/runtime/proc/run.d.ts +15 -29
- package/build/src/runtime/proc/run.js +113 -105
- package/build/src/runtime/proc/stdio.d.ts +18 -0
- package/build/src/runtime/proc/stdio.js +58 -0
- package/build/src/settings.d.ts +2 -2
- package/build/src/settings.js +8 -8
- package/build/src/settlement/fence.d.ts +0 -4
- package/build/src/settlement/fence.js +0 -9
- package/build/src/settlement/holder.d.ts +11 -1
- package/build/src/settlement/holder.js +25 -0
- package/build/src/settlement/settle.d.ts +1 -1
- package/build/src/settlement/settle.js +52 -89
- package/build/src/task/board.d.ts +3 -3
- package/build/src/task/board.js +6 -9
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +18 -10
- package/build/src/task/context.d.ts +3 -3
- package/build/src/task/context.js +14 -14
- package/build/src/task/document.d.ts +2 -1
- package/build/src/task/document.js +15 -5
- package/build/src/task/index.d.ts +19 -7
- package/build/src/task/index.js +42 -23
- package/build/src/task/operations.d.ts +15 -9
- package/build/src/task/operations.js +78 -48
- package/build/src/task/query.d.ts +67 -0
- package/build/src/task/query.js +279 -0
- package/build/src/task/store.d.ts +2 -2
- package/build/src/task/store.js +40 -25
- package/build/src/verification/execution.d.ts +4 -2
- package/build/src/verification/execution.js +9 -5
- package/build/src/workspace-place.d.ts +41 -0
- package/build/src/workspace-place.js +386 -0
- package/build/src/world.d.ts +13 -2
- package/build/src/world.js +81 -48
- package/package.json +3 -2
- package/build/src/protocol/read/audit.d.ts +0 -31
- package/build/src/protocol/read/audit.js +0 -55
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { SnapshotId } from "../core/facts/types.js";
|
|
2
2
|
import { type GitObjectId } from "./identity.js";
|
|
3
3
|
import { type GitRepository } from "./repository.js";
|
|
4
4
|
export type WorkspaceChanges = Readonly<{
|
|
@@ -13,9 +13,41 @@ export type WorkspaceTree = Readonly<{
|
|
|
13
13
|
dirty: boolean;
|
|
14
14
|
changes: WorkspaceChanges;
|
|
15
15
|
}>;
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function worktreePath(repository: GitRepository, place: string): string;
|
|
17
17
|
export declare function withPrivateGitIndex<Value>(action: (environment: Readonly<{
|
|
18
18
|
GIT_INDEX_FILE: string;
|
|
19
|
-
}>) => Value): Value
|
|
19
|
+
}>) => Value | PromiseLike<Value>): Promise<Value>;
|
|
20
|
+
export type WorkspaceChangeCounts = Readonly<{
|
|
21
|
+
staged: number;
|
|
22
|
+
unstaged: number;
|
|
23
|
+
untracked: number;
|
|
24
|
+
submodules: number;
|
|
25
|
+
}>;
|
|
26
|
+
export type ContractWorkspaceLocation = Readonly<{
|
|
27
|
+
kind: "worktree";
|
|
28
|
+
path: string;
|
|
29
|
+
}> | Readonly<{
|
|
30
|
+
kind: "here";
|
|
31
|
+
}>;
|
|
32
|
+
export type ContractWorkspaceObservation = Readonly<{
|
|
33
|
+
kind: "clean" | "dirty";
|
|
34
|
+
location: ContractWorkspaceLocation;
|
|
35
|
+
counts: WorkspaceChangeCounts;
|
|
36
|
+
}> | Readonly<{
|
|
37
|
+
kind: "unavailable";
|
|
38
|
+
location: ContractWorkspaceLocation;
|
|
39
|
+
}> | Readonly<{
|
|
40
|
+
kind: "unappointed";
|
|
41
|
+
}>;
|
|
42
|
+
export type ContractTargetLag = Readonly<{
|
|
43
|
+
kind: "counted";
|
|
44
|
+
behind: number;
|
|
45
|
+
}> | Readonly<{
|
|
46
|
+
kind: "unknown";
|
|
47
|
+
}> | Readonly<{
|
|
48
|
+
kind: "none";
|
|
49
|
+
}>;
|
|
50
|
+
export declare function observeWorkspace(repository: GitRepository, location: ContractWorkspaceLocation, workspace: string): Promise<ContractWorkspaceObservation>;
|
|
51
|
+
export declare function observeTargetLag(repository: GitRepository, workspace: string, head: SnapshotId | null | undefined): Promise<ContractTargetLag>;
|
|
20
52
|
/** Capture tracked and untracked workspace bytes without changing its real index. */
|
|
21
|
-
export declare function captureWorkspaceTree(repository: GitRepository, workspace: string): WorkspaceTree
|
|
53
|
+
export declare function captureWorkspaceTree(repository: GitRepository, workspace: string): Promise<WorkspaceTree>;
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join, resolve } from "node:path";
|
|
4
|
-
import {
|
|
4
|
+
import { gitObjectId, mintSnapshotId } from "./identity.js";
|
|
5
5
|
import { runGit, runGitWithEnvironment } from "./repository.js";
|
|
6
6
|
const WORKTREE_DIRECTORY = ["keiyaku", "wt"];
|
|
7
|
-
export function
|
|
8
|
-
return resolve(repository.commonDirectory, ...WORKTREE_DIRECTORY,
|
|
7
|
+
export function worktreePath(repository, place) {
|
|
8
|
+
return resolve(repository.commonDirectory, ...WORKTREE_DIRECTORY, place);
|
|
9
9
|
}
|
|
10
|
-
export function withPrivateGitIndex(action) {
|
|
11
|
-
const directory =
|
|
10
|
+
export async function withPrivateGitIndex(action) {
|
|
11
|
+
const directory = await mkdtemp(join(tmpdir(), "keiyaku-v4-index-"));
|
|
12
12
|
try {
|
|
13
|
-
return action({ GIT_INDEX_FILE: join(directory, "index") });
|
|
13
|
+
return await action({ GIT_INDEX_FILE: join(directory, "index") });
|
|
14
14
|
}
|
|
15
15
|
finally {
|
|
16
|
-
|
|
16
|
+
await rm(directory, { recursive: true, force: true });
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
function fields(record, count) {
|
|
@@ -29,11 +29,11 @@ function fields(record, count) {
|
|
|
29
29
|
result.push(record.slice(start));
|
|
30
30
|
return result;
|
|
31
31
|
}
|
|
32
|
-
function workspaceChanges(repository, workspace) {
|
|
33
|
-
const records = runGit(repository, [
|
|
32
|
+
async function workspaceChanges(repository, workspace) {
|
|
33
|
+
const records = (await runGit(repository, [
|
|
34
34
|
"-C", workspace,
|
|
35
35
|
"status", "--porcelain=v2", "-z", "--untracked-files=all", "--ignore-submodules=none",
|
|
36
|
-
]).toString("utf8").split("\0");
|
|
36
|
+
])).toString("utf8").split("\0");
|
|
37
37
|
const staged = new Set();
|
|
38
38
|
const unstaged = new Set();
|
|
39
39
|
const untracked = new Set();
|
|
@@ -77,9 +77,44 @@ function workspaceChanges(repository, workspace) {
|
|
|
77
77
|
submodules: [...submodules].sort(),
|
|
78
78
|
};
|
|
79
79
|
}
|
|
80
|
+
function countsOf(changes) {
|
|
81
|
+
return {
|
|
82
|
+
staged: changes.staged.length,
|
|
83
|
+
unstaged: changes.unstaged.length,
|
|
84
|
+
untracked: changes.untracked.length,
|
|
85
|
+
submodules: changes.submodules.length,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export async function observeWorkspace(repository, location, workspace) {
|
|
89
|
+
try {
|
|
90
|
+
const counts = countsOf(await workspaceChanges(repository, workspace));
|
|
91
|
+
const dirty = counts.staged > 0 || counts.unstaged > 0 || counts.untracked > 0 || counts.submodules > 0;
|
|
92
|
+
return { kind: dirty ? "dirty" : "clean", location, counts };
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
return { kind: "unavailable", location };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
export async function observeTargetLag(repository, workspace, head) {
|
|
99
|
+
if (head === undefined)
|
|
100
|
+
return { kind: "none" };
|
|
101
|
+
if (head === null)
|
|
102
|
+
return { kind: "unknown" };
|
|
103
|
+
try {
|
|
104
|
+
const text = (await runGit(repository, ["-C", workspace, "rev-list", "--count", `HEAD..${head}`]))
|
|
105
|
+
.toString("utf8")
|
|
106
|
+
.trim();
|
|
107
|
+
if (!/^[0-9]+$/u.test(text))
|
|
108
|
+
return { kind: "unknown" };
|
|
109
|
+
return { kind: "counted", behind: Number(text) };
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return { kind: "unknown" };
|
|
113
|
+
}
|
|
114
|
+
}
|
|
80
115
|
/** Capture tracked and untracked workspace bytes without changing its real index. */
|
|
81
|
-
export function captureWorkspaceTree(repository, workspace) {
|
|
82
|
-
const identities = runGit(repository, ["-C", workspace, "show", "-s", "--format=%H%n%T", "HEAD"])
|
|
116
|
+
export async function captureWorkspaceTree(repository, workspace) {
|
|
117
|
+
const identities = (await runGit(repository, ["-C", workspace, "show", "-s", "--format=%H%n%T", "HEAD"]))
|
|
83
118
|
.toString("utf8")
|
|
84
119
|
.split("\n");
|
|
85
120
|
if (identities.length !== 3 || identities[0] === undefined || identities[1] === undefined || identities[2] !== "") {
|
|
@@ -87,15 +122,15 @@ export function captureWorkspaceTree(repository, workspace) {
|
|
|
87
122
|
}
|
|
88
123
|
const head = mintSnapshotId(identities[0]);
|
|
89
124
|
const tree = gitObjectId(identities[1], "workspace tree");
|
|
90
|
-
const changes = workspaceChanges(repository, workspace);
|
|
125
|
+
const changes = await workspaceChanges(repository, workspace);
|
|
91
126
|
const dirty = changes.staged.length > 0 || changes.unstaged.length > 0 || changes.untracked.length > 0;
|
|
92
127
|
if (!dirty)
|
|
93
128
|
return { tree, head, dirty, changes };
|
|
94
|
-
return withPrivateGitIndex((environment) => {
|
|
95
|
-
runGitWithEnvironment(repository, ["-C", workspace, "read-tree", "HEAD"], undefined, environment);
|
|
96
|
-
runGitWithEnvironment(repository, ["-C", workspace, "add", "--all"], undefined, environment);
|
|
129
|
+
return await withPrivateGitIndex(async (environment) => {
|
|
130
|
+
await runGitWithEnvironment(repository, ["-C", workspace, "read-tree", "HEAD"], undefined, environment);
|
|
131
|
+
await runGitWithEnvironment(repository, ["-C", workspace, "add", "--all"], undefined, environment);
|
|
97
132
|
return {
|
|
98
|
-
tree: gitObjectId(runGitWithEnvironment(repository, ["-C", workspace, "write-tree"], undefined, environment).toString("utf8").trim(), "workspace tree"),
|
|
133
|
+
tree: gitObjectId((await runGitWithEnvironment(repository, ["-C", workspace, "write-tree"], undefined, environment)).toString("utf8").trim(), "workspace tree"),
|
|
99
134
|
head,
|
|
100
135
|
dirty,
|
|
101
136
|
changes,
|
|
@@ -13,7 +13,7 @@ export function parseAkumaGlob(value) {
|
|
|
13
13
|
if (segments.length !== 3 || segments[0] !== "aku" || !value.includes("*")
|
|
14
14
|
|| archetype.length === 0 || normalizeIdentityStem({ source: archetypeProbe }) !== archetypeProbe
|
|
15
15
|
|| !AKUMA_GLOB_SUFFIX.test(segments[2] ?? "")) {
|
|
16
|
-
throw new TypeError("Akuma glob must be aku/<
|
|
16
|
+
throw new TypeError("Akuma glob must be aku/<akuma-pattern>/<hex-pattern> and contain *");
|
|
17
17
|
}
|
|
18
18
|
return value;
|
|
19
19
|
}
|
package/build/src/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { AuthorityCorruptionError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
|
|
1
|
+
export { AuthorityCorruptionError, AkumaWorldScopeError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
|
|
2
2
|
export { settings } from "./settings.js";
|
|
3
3
|
export { World, WorldError } from "./world.js";
|
|
4
|
-
export type { WorldRoot } from "./world.js";
|
|
4
|
+
export type { WorldResolution, WorldResolutionInput, WorldRoot } from "./world.js";
|
|
5
5
|
export type { Settings, SettingsEntry, SettingsInput, SettingsNamespaceFailure, SettingsNamespaceView, SettingsScope, SettingsScopeState, } from "./settings.js";
|
|
6
|
-
export type { AttestationVerdict, AbandonInput, ActorId, AkuId, AkumaAddressInput, AkumaAlias, AkumaGlob, AkumaHistoryInput, AkumaHistoryResult, AkumaInterruptInput, AkumaInterruptResult, AkumaKillResult, AkumaSetAddressInput, AkumaStatus, AkumaStatusView, AkumaTellInput, AkumaTellResult, AkumaWaitInput, AkumaWaitResult, AliasBinding, AliasStage, AmendResult, AmendInput, ArcInput, AuditReport, BindInput, BindResult, CallInput, CallObservation, CallResult, Catalog, CatalogInput, CatalogQuery, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractListInput, ContractObservation, ContractObservationInput, ContractPhase, ContractRow, DeliverInput, Fact, FactKind, Dispatch, DispatchFailure, DispatchStage, DirectAkumaSelector, Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, KeiyakuOfInput, KeiyakuRefusal, KeiyakuRetryReason, ForkInput, ForkResult, IntegrationFailure, Lag, MutationResult, PlacementStop, RegionOverlap, ReconcileInput, RepoReconcileReport, Review, ReconcileReport, ReviewInput, RepoAtInput, AuditInput, SnapshotId, SettlementAction, SettlementLag, SettlementReport, SetAkumaSelector, TaskId,
|
|
6
|
+
export type { AttestationVerdict, AbandonInput, ActorId, AkuId, AkumaAddressInput, AkumaAlias, AkumaGlob, AkumaHistoryInput, AkumaHistoryResult, AkumaInterruptInput, AkumaInterruptResult, AkumaKillResult, AkumaSetAddressInput, AkumaStatus, AkumaStatusView, AkumaTellInput, AkumaTellResult, AkumaWaitInput, AkumaWaitResult, AkumaWorldScopeRefusal, AliasBinding, AliasStage, AmendResult, AmendInput, ArcInput, AuditReport, DeliveryPreparationRefusal, BindInput, BindResult, CallInput, CallObservation, CallResult, Catalog, CatalogInput, CatalogQuery, ChangeId, ContractId, ContractState, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractListInput, ContractObservation, ContractObservationInput, ContractPhase, ContractRow, DeliverInput, Fact, FactKind, Dispatch, DispatchFailure, DispatchStage, DirectAkumaSelector, Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, KeiyakuOfInput, KeiyakuRefusal, KeiyakuRetryReason, ForkInput, ForkResult, IntegrationFailure, Lag, MutationResult, PlacementStop, RegionOverlap, ReconcileInput, RepoReconcileReport, Review, ReconcileReport, ReviewInput, RepoAtInput, AuditInput, SnapshotId, SettlementAction, SettlementLag, SettlementReport, SetAkumaSelector, TaskId, TopologyEffect, VerificationReuse, VerificationStop, WorktreeHooks, } from "./library/keiyaku.js";
|
package/build/src/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { AuthorityCorruptionError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
|
|
1
|
+
export { AuthorityCorruptionError, AkumaWorldScopeError, Delivery, gatesFrom, Keiyaku, KeiyakuRefused, KeiyakuRetry, NoGitWorldError, Repo, requireBranchesToBeUpToDateFrom, SettingsError, worktreeHooksFrom } from "./library/keiyaku.js";
|
|
2
2
|
export { settings } from "./settings.js";
|
|
3
3
|
export { World, WorldError } from "./world.js";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { kanshi } from "./read.js";
|
|
2
|
-
export { selectKanshi } from "./select.js";
|
|
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, } from "./report.js";
|
|
4
|
+
export type { AkumaKanshiRow, AkumaKanshiWorld, ContractEndpointObservation, ContractHolderObservation, ContractKanshiBoard, ContractKanshiRow, KanshiReport, Section, TaskKanshiRow, TaskKanshiWorld, KanshiRegionSelection, RegionDeclaration, RegionIntersection, RegionPathMatch, RegionRead, } from "./report.js";
|
|
5
5
|
export type { KanshiSelection } from "./select.js";
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export { kanshi } from "./read.js";
|
|
2
|
-
export { selectKanshi } from "./select.js";
|
|
2
|
+
export { selectKanshi, selectRegion } from "./select.js";
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Repo } from "../library/repo.js";
|
|
2
|
-
import type { KanshiReport } from "./report.js";
|
|
2
|
+
import type { KanshiReport, KanshiRegionSelection } from "./report.js";
|
|
3
3
|
import type { WorldRoot } from "../world.js";
|
|
4
4
|
export type KanshiInput = Readonly<{
|
|
5
5
|
world: WorldRoot | null;
|
|
6
6
|
repo?: Repo;
|
|
7
|
+
region?: KanshiRegionSelection;
|
|
7
8
|
}>;
|
|
8
9
|
export declare function kanshi(input: KanshiInput): Promise<KanshiReport>;
|
package/build/src/kanshi/read.js
CHANGED
|
@@ -7,6 +7,10 @@ import { readDispatchesAt } from "../dispatch/index.js";
|
|
|
7
7
|
import { readTaskHolderProjectionAt } from "../settlement/holder.js";
|
|
8
8
|
import { readContractBoard } from "../protocol/read/status.js";
|
|
9
9
|
import { withGitDecodeChannel, withGitReadObservation } from "../git/read-observation.js";
|
|
10
|
+
import { readDocuments } from "../protocol/read/documents.js";
|
|
11
|
+
import { readRegionDeclarations, validateRegionPath } from "../library/region.js";
|
|
12
|
+
import { contractId } from "../core/facts/types.js";
|
|
13
|
+
import { selectRegion } from "./select.js";
|
|
10
14
|
function diagnostic(error) {
|
|
11
15
|
let source;
|
|
12
16
|
if (error instanceof Error)
|
|
@@ -24,18 +28,81 @@ function diagnostic(error) {
|
|
|
24
28
|
const line = source.replaceAll(/\s+/gu, " ").trim();
|
|
25
29
|
return line.length <= 240 ? line : `${line.slice(0, 239)}…`;
|
|
26
30
|
}
|
|
31
|
+
function record(value, label) {
|
|
32
|
+
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
33
|
+
throw new TypeError(`kanshi ${label} must be an object`);
|
|
34
|
+
return value;
|
|
35
|
+
}
|
|
36
|
+
function exactKeys(value, allowed, label) {
|
|
37
|
+
for (const key of Object.keys(value))
|
|
38
|
+
if (!allowed.includes(key))
|
|
39
|
+
throw new TypeError(`kanshi ${label} has unknown field: ${key}`);
|
|
40
|
+
}
|
|
41
|
+
function regionSelection(value) {
|
|
42
|
+
const selection = record(value, "region selection");
|
|
43
|
+
if (typeof selection.kind !== "string")
|
|
44
|
+
throw new TypeError("kanshi region selection kind must be a string");
|
|
45
|
+
if (selection.kind === "declarations") {
|
|
46
|
+
exactKeys(selection, ["kind"], "region selection");
|
|
47
|
+
return { kind: "declarations" };
|
|
48
|
+
}
|
|
49
|
+
if (selection.kind === "contract") {
|
|
50
|
+
exactKeys(selection, ["kind", "contract"], "region selection");
|
|
51
|
+
if (typeof selection.contract !== "string")
|
|
52
|
+
throw new TypeError("kanshi region contract must be a ContractId");
|
|
53
|
+
try {
|
|
54
|
+
return { kind: "contract", contract: contractId(selection.contract) };
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
throw new TypeError("kanshi region contract must be a canonical ContractId");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
if (selection.kind === "overlap") {
|
|
61
|
+
exactKeys(selection, ["kind", "contract"], "region selection");
|
|
62
|
+
if (selection.contract === undefined)
|
|
63
|
+
return { kind: "overlap" };
|
|
64
|
+
if (typeof selection.contract !== "string")
|
|
65
|
+
throw new TypeError("kanshi region contract must be a ContractId");
|
|
66
|
+
try {
|
|
67
|
+
return { kind: "overlap", contract: contractId(selection.contract) };
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
throw new TypeError("kanshi region contract must be a canonical ContractId");
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (selection.kind === "path") {
|
|
74
|
+
exactKeys(selection, ["kind", "path"], "region selection");
|
|
75
|
+
try {
|
|
76
|
+
validateRegionPath(selection.path);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
throw new TypeError(error instanceof Error ? error.message : String(error));
|
|
80
|
+
}
|
|
81
|
+
return { kind: "path", path: selection.path };
|
|
82
|
+
}
|
|
83
|
+
throw new TypeError(`kanshi region selection kind is invalid: ${selection.kind}`);
|
|
84
|
+
}
|
|
27
85
|
function coordinate(input) {
|
|
28
86
|
if (typeof input !== "object" || input === null || Array.isArray(input))
|
|
29
87
|
throw new TypeError("kanshi input must be an object");
|
|
30
88
|
for (const key of Object.keys(input))
|
|
31
|
-
if (key !== "world" && key !== "repo")
|
|
89
|
+
if (key !== "world" && key !== "repo" && key !== "region")
|
|
32
90
|
throw new TypeError(`kanshi input has unknown field: ${key}`);
|
|
33
91
|
if (input.world !== null && (typeof input.world !== "string" || input.world.trim().length === 0)) {
|
|
34
92
|
throw new TypeError("kanshi world must be a WorldRoot or null");
|
|
35
93
|
}
|
|
36
94
|
if (input.repo !== undefined && !(input.repo instanceof Repo))
|
|
37
95
|
throw new TypeError("kanshi repo must be a Repo");
|
|
38
|
-
return input;
|
|
96
|
+
return input.region === undefined ? input : { ...input, region: regionSelection(input.region) };
|
|
97
|
+
}
|
|
98
|
+
async function readRegion(observation, selection) {
|
|
99
|
+
try {
|
|
100
|
+
const declarations = [...readRegionDeclarations(await readDocuments(observation))].sort((left, right) => left.contract.localeCompare(right.contract));
|
|
101
|
+
return { kind: "present", value: selectRegion({ declarations, selection }) };
|
|
102
|
+
}
|
|
103
|
+
catch (error) {
|
|
104
|
+
return { kind: "failed", failure: { message: diagnostic(error) } };
|
|
105
|
+
}
|
|
39
106
|
}
|
|
40
107
|
async function readBranch(repo) {
|
|
41
108
|
if (repo === undefined)
|
|
@@ -63,6 +130,27 @@ async function readHolders(observation) {
|
|
|
63
130
|
return { kind: "failed", failure: { message: diagnostic(error) } };
|
|
64
131
|
}
|
|
65
132
|
}
|
|
133
|
+
function attachFleet(contracts, akuma) {
|
|
134
|
+
if (contracts.kind !== "present")
|
|
135
|
+
return contracts;
|
|
136
|
+
const attachments = new Map();
|
|
137
|
+
if (akuma.kind === "present") {
|
|
138
|
+
for (const row of akuma.value.rows) {
|
|
139
|
+
if (row.contract === undefined)
|
|
140
|
+
continue;
|
|
141
|
+
const current = attachments.get(row.contract.id) ?? [];
|
|
142
|
+
current.push({ id: row.id, aliases: row.aliases });
|
|
143
|
+
attachments.set(row.contract.id, current);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
kind: "present",
|
|
148
|
+
value: {
|
|
149
|
+
...contracts.value,
|
|
150
|
+
rows: contracts.value.rows.map((row) => ({ ...row, fleet: attachments.get(row.id) ?? [] })),
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
66
154
|
function decorateContracts(contracts, holders) {
|
|
67
155
|
if (contracts.kind !== "present")
|
|
68
156
|
return contracts;
|
|
@@ -72,11 +160,15 @@ function decorateContracts(contracts, holders) {
|
|
|
72
160
|
...contracts.value,
|
|
73
161
|
rows: contracts.value.rows.map((row) => {
|
|
74
162
|
if (holders.kind === "failed")
|
|
75
|
-
return { ...row, holder: { kind: "unavailable" } };
|
|
163
|
+
return { ...row, holder: { kind: "unavailable" }, fleet: [] };
|
|
76
164
|
const holder = holders.kind === "present" ? holders.value.get(row.id) : undefined;
|
|
77
|
-
return
|
|
78
|
-
|
|
79
|
-
:
|
|
165
|
+
return {
|
|
166
|
+
...row,
|
|
167
|
+
fleet: [],
|
|
168
|
+
holder: holder?.disposition === "held"
|
|
169
|
+
? { kind: "held", taskId: holder.taskId }
|
|
170
|
+
: { kind: "none" },
|
|
171
|
+
};
|
|
80
172
|
}),
|
|
81
173
|
},
|
|
82
174
|
};
|
|
@@ -100,23 +192,23 @@ function joinTasks(rows, holders, observeContract) {
|
|
|
100
192
|
return { ...row, contract: { id: contractId, observed: observeContract(contractId) } };
|
|
101
193
|
});
|
|
102
194
|
}
|
|
103
|
-
function readTasks(path, holders, observeContract) {
|
|
195
|
+
async function readTasks(path, holders, observeContract) {
|
|
104
196
|
if (holders.kind === "failed")
|
|
105
197
|
return { kind: "failed", failure: holders.failure };
|
|
106
198
|
try {
|
|
107
199
|
return {
|
|
108
200
|
kind: "present",
|
|
109
|
-
value: { root: path, rows: joinTasks(observeTaskStatusRows(path), holders, observeContract) },
|
|
201
|
+
value: { root: path, rows: joinTasks(await observeTaskStatusRows(path), holders, observeContract) },
|
|
110
202
|
};
|
|
111
203
|
}
|
|
112
204
|
catch (error) {
|
|
113
205
|
return { kind: "failed", failure: { message: diagnostic(error) } };
|
|
114
206
|
}
|
|
115
207
|
}
|
|
116
|
-
function joinAkuma(path, observeContract, dispatches) {
|
|
208
|
+
async function joinAkuma(path, observeContract, dispatches) {
|
|
117
209
|
try {
|
|
118
|
-
const source = Akuma.of(path).list();
|
|
119
|
-
const aliases = readAliases(path);
|
|
210
|
+
const source = await Akuma.of(path).list();
|
|
211
|
+
const aliases = await readAliases(path);
|
|
120
212
|
const aliasById = new Map();
|
|
121
213
|
for (const binding of aliases)
|
|
122
214
|
aliasById.set(binding.akuId, [...(aliasById.get(binding.akuId) ?? []), binding]);
|
|
@@ -161,37 +253,35 @@ export async function kanshi(input) {
|
|
|
161
253
|
const contracts = { kind: "absent" };
|
|
162
254
|
const holders = { kind: "absent" };
|
|
163
255
|
const observeContract = contractEndpointObserver(contracts);
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
branch,
|
|
168
|
-
contracts,
|
|
169
|
-
tasks: world === null ? { kind: "absent" } : readTasks(world, holders, observeContract),
|
|
170
|
-
akuma: world === null ? { kind: "absent" } : joinAkuma(world, observeContract, []),
|
|
171
|
-
};
|
|
256
|
+
const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
|
|
257
|
+
const akuma = world === null ? { kind: "absent" } : await joinAkuma(world, observeContract, []);
|
|
258
|
+
return { root: world, observedAt, branch, contracts, tasks, akuma, ...(input.region === undefined ? {} : { region: { kind: "absent" } }) };
|
|
172
259
|
}
|
|
173
260
|
try {
|
|
174
261
|
const repository = scopeForRepo(repo);
|
|
175
262
|
return await withGitDecodeChannel(repository, (channel) => withGitReadObservation(repository, channel, async (observation) => {
|
|
176
|
-
const [contractSection, holders, dispatches] = await Promise.all([
|
|
263
|
+
const [contractSection, holders, dispatches, region] = await Promise.all([
|
|
177
264
|
readContracts(observation),
|
|
178
265
|
readHolders(observation),
|
|
179
266
|
readDispatches(observation),
|
|
267
|
+
input.region === undefined ? Promise.resolve(undefined) : readRegion(observation, input.region),
|
|
180
268
|
]);
|
|
181
269
|
const contracts = decorateContracts(contractSection, holders);
|
|
182
270
|
const observeContract = contractEndpointObserver(contracts);
|
|
183
|
-
const tasks = world === null ? { kind: "absent" } : readTasks(world, holders, observeContract);
|
|
271
|
+
const tasks = world === null ? { kind: "absent" } : await readTasks(world, holders, observeContract);
|
|
272
|
+
const akuma = world === null
|
|
273
|
+
? { kind: "absent" }
|
|
274
|
+
: dispatches.kind === "failed"
|
|
275
|
+
? dispatches
|
|
276
|
+
: await joinAkuma(world, observeContract, dispatches.value);
|
|
184
277
|
return {
|
|
185
278
|
root: world,
|
|
186
279
|
observedAt,
|
|
187
280
|
branch,
|
|
188
|
-
contracts,
|
|
281
|
+
contracts: attachFleet(contracts, akuma),
|
|
189
282
|
tasks,
|
|
190
|
-
akuma
|
|
191
|
-
|
|
192
|
-
: dispatches.kind === "failed"
|
|
193
|
-
? dispatches
|
|
194
|
-
: joinAkuma(world, observeContract, dispatches.value),
|
|
283
|
+
akuma,
|
|
284
|
+
...(region === undefined ? {} : { region }),
|
|
195
285
|
};
|
|
196
286
|
}));
|
|
197
287
|
}
|
|
@@ -204,6 +294,7 @@ export async function kanshi(input) {
|
|
|
204
294
|
contracts: failure,
|
|
205
295
|
tasks: world === null ? { kind: "absent" } : failure,
|
|
206
296
|
akuma: world === null ? { kind: "absent" } : failure,
|
|
297
|
+
...(input.region === undefined ? {} : { region: failure }),
|
|
207
298
|
};
|
|
208
299
|
}
|
|
209
300
|
}
|
|
@@ -3,6 +3,7 @@ import type { TaskId, TaskRef, TaskRow } from "../task/index.js";
|
|
|
3
3
|
import type { AkumaList, AkumaListRow, UnbornAkumaListRow } from "../akuma/index.js";
|
|
4
4
|
import type { AkumaAlias } from "../identity/selector.js";
|
|
5
5
|
import type { WorldRoot } from "../world.js";
|
|
6
|
+
import type { ContractId } from "../library/contract.js";
|
|
6
7
|
export type Section<Value> = Readonly<{
|
|
7
8
|
kind: "present";
|
|
8
9
|
value: Value;
|
|
@@ -23,8 +24,13 @@ export type ContractHolderObservation = Readonly<{
|
|
|
23
24
|
}> | Readonly<{
|
|
24
25
|
kind: "unavailable";
|
|
25
26
|
}>;
|
|
27
|
+
export type ContractFleetAttachment = Readonly<{
|
|
28
|
+
id: string;
|
|
29
|
+
aliases: readonly AkumaAlias[];
|
|
30
|
+
}>;
|
|
26
31
|
export type ContractKanshiRow = ContractBoard["rows"][number] & Readonly<{
|
|
27
32
|
holder: ContractHolderObservation;
|
|
33
|
+
fleet: readonly ContractFleetAttachment[];
|
|
28
34
|
}>;
|
|
29
35
|
export type ContractKanshiBoard = Omit<ContractBoard, "rows"> & Readonly<{
|
|
30
36
|
rows: readonly ContractKanshiRow[];
|
|
@@ -50,6 +56,49 @@ export type AkumaKanshiRow = (AkumaListRow | UnbornAkumaListRow) & Readonly<{
|
|
|
50
56
|
export type AkumaKanshiWorld = Omit<AkumaList, "rows"> & Readonly<{
|
|
51
57
|
rows: readonly AkumaKanshiRow[];
|
|
52
58
|
}>;
|
|
59
|
+
export type KanshiRegionSelection = Readonly<{
|
|
60
|
+
kind: "declarations";
|
|
61
|
+
}> | Readonly<{
|
|
62
|
+
kind: "contract";
|
|
63
|
+
contract: ContractId;
|
|
64
|
+
}> | Readonly<{
|
|
65
|
+
kind: "overlap";
|
|
66
|
+
contract?: ContractId;
|
|
67
|
+
}> | Readonly<{
|
|
68
|
+
kind: "path";
|
|
69
|
+
path: string;
|
|
70
|
+
}>;
|
|
71
|
+
export type RegionDeclaration = Readonly<{
|
|
72
|
+
contract: ContractId;
|
|
73
|
+
patterns: readonly string[];
|
|
74
|
+
}>;
|
|
75
|
+
export type RegionIntersection = Readonly<{
|
|
76
|
+
left: ContractId;
|
|
77
|
+
right: ContractId;
|
|
78
|
+
patterns: readonly Readonly<{
|
|
79
|
+
left: string;
|
|
80
|
+
right: string;
|
|
81
|
+
}>[];
|
|
82
|
+
}>;
|
|
83
|
+
export type RegionPathMatch = Readonly<{
|
|
84
|
+
contract: ContractId;
|
|
85
|
+
pattern: string;
|
|
86
|
+
}>;
|
|
87
|
+
export type RegionRead = Readonly<{
|
|
88
|
+
kind: "declarations";
|
|
89
|
+
declarations: readonly RegionDeclaration[];
|
|
90
|
+
}> | Readonly<{
|
|
91
|
+
kind: "contract";
|
|
92
|
+
declaration: RegionDeclaration;
|
|
93
|
+
}> | Readonly<{
|
|
94
|
+
kind: "overlap";
|
|
95
|
+
subject?: ContractId;
|
|
96
|
+
intersections: readonly RegionIntersection[];
|
|
97
|
+
}> | Readonly<{
|
|
98
|
+
kind: "path";
|
|
99
|
+
path: string;
|
|
100
|
+
matches: readonly RegionPathMatch[];
|
|
101
|
+
}>;
|
|
53
102
|
export type KanshiReport = Readonly<{
|
|
54
103
|
root: WorldRoot | null;
|
|
55
104
|
observedAt: string;
|
|
@@ -57,4 +106,5 @@ export type KanshiReport = Readonly<{
|
|
|
57
106
|
contracts: Section<ContractKanshiBoard>;
|
|
58
107
|
tasks: Section<TaskKanshiWorld>;
|
|
59
108
|
akuma: Section<AkumaKanshiWorld>;
|
|
109
|
+
region?: Section<RegionRead>;
|
|
60
110
|
}>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { KanshiReport } from "./report.js";
|
|
2
|
+
import type { KanshiRegionSelection, RegionDeclaration, RegionRead } from "./report.js";
|
|
2
3
|
export type KanshiSelection = Readonly<{
|
|
3
4
|
contract: string;
|
|
4
5
|
}>;
|
|
@@ -6,3 +7,7 @@ export declare function selectKanshi(input: Readonly<{
|
|
|
6
7
|
report: KanshiReport;
|
|
7
8
|
contract: string;
|
|
8
9
|
}>): KanshiReport;
|
|
10
|
+
export declare function selectRegion(input: Readonly<{
|
|
11
|
+
declarations: readonly RegionDeclaration[];
|
|
12
|
+
selection: KanshiRegionSelection;
|
|
13
|
+
}>): RegionRead;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { regionIntersections, regionPathMatches } from "../library/region.js";
|
|
1
2
|
export function selectKanshi(input) {
|
|
2
3
|
const { report, contract } = input;
|
|
3
4
|
return {
|
|
@@ -19,3 +20,34 @@ export function selectKanshi(input) {
|
|
|
19
20
|
: report.akuma,
|
|
20
21
|
};
|
|
21
22
|
}
|
|
23
|
+
export function selectRegion(input) {
|
|
24
|
+
const { declarations, selection } = input;
|
|
25
|
+
if (selection.kind === "declarations")
|
|
26
|
+
return { kind: "declarations", declarations };
|
|
27
|
+
if (selection.kind === "contract") {
|
|
28
|
+
const declaration = declarations.find((value) => value.contract === selection.contract);
|
|
29
|
+
if (declaration === undefined)
|
|
30
|
+
throw new Error(`active contract not found: ${selection.contract}`);
|
|
31
|
+
return { kind: "contract", declaration };
|
|
32
|
+
}
|
|
33
|
+
if (selection.kind === "path") {
|
|
34
|
+
const matches = declarations.flatMap((declaration) => regionPathMatches(declaration.patterns, selection.path).map((pattern) => ({ contract: declaration.contract, pattern })));
|
|
35
|
+
return { kind: "path", path: selection.path, matches };
|
|
36
|
+
}
|
|
37
|
+
const intersections = [];
|
|
38
|
+
for (let leftIndex = 0; leftIndex < declarations.length; leftIndex += 1) {
|
|
39
|
+
for (let rightIndex = leftIndex + 1; rightIndex < declarations.length; rightIndex += 1) {
|
|
40
|
+
const left = declarations[leftIndex];
|
|
41
|
+
const right = declarations[rightIndex];
|
|
42
|
+
if (selection.contract !== undefined && left.contract !== selection.contract && right.contract !== selection.contract)
|
|
43
|
+
continue;
|
|
44
|
+
const patterns = regionIntersections(left.patterns, right.patterns);
|
|
45
|
+
if (patterns.length > 0)
|
|
46
|
+
intersections.push({ left: left.contract, right: right.contract, patterns });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
if (selection.contract !== undefined && !declarations.some((value) => value.contract === selection.contract)) {
|
|
50
|
+
throw new Error(`active contract not found: ${selection.contract}`);
|
|
51
|
+
}
|
|
52
|
+
return { kind: "overlap", ...(selection.contract === undefined ? {} : { subject: selection.contract }), intersections };
|
|
53
|
+
}
|
|
@@ -17,6 +17,15 @@ export type AkumaSetAddressInput = Readonly<{
|
|
|
17
17
|
settings?: Settings;
|
|
18
18
|
repo?: Repo;
|
|
19
19
|
}>;
|
|
20
|
+
export type AkumaWorldScopeRefusal = Readonly<{
|
|
21
|
+
kind: "akuma-not-in-world";
|
|
22
|
+
ids: readonly AkuId[];
|
|
23
|
+
world: WorldRoot;
|
|
24
|
+
}>;
|
|
25
|
+
export declare class AkumaWorldScopeError extends TypeError {
|
|
26
|
+
readonly refusal: AkumaWorldScopeRefusal;
|
|
27
|
+
constructor(refusal: AkumaWorldScopeRefusal);
|
|
28
|
+
}
|
|
20
29
|
export type NamedAddressContract = Readonly<{
|
|
21
30
|
id: string;
|
|
22
31
|
disposition: "active" | "terminal";
|
|
@@ -35,12 +44,12 @@ export type NamedAddressInput = Readonly<{
|
|
|
35
44
|
selector: string;
|
|
36
45
|
contracts: readonly NamedAddressContract[];
|
|
37
46
|
}>;
|
|
38
|
-
export declare function resolveNamedAddress(input: NamedAddressInput): NamedAddress
|
|
39
|
-
export declare function addressAkuma(input: AkumaAddressInput): Readonly<{
|
|
47
|
+
export declare function resolveNamedAddress(input: NamedAddressInput): Promise<NamedAddress>;
|
|
48
|
+
export declare function addressAkuma(input: AkumaAddressInput): Promise<Readonly<{
|
|
40
49
|
path: WorldRoot;
|
|
41
50
|
id: AkuId;
|
|
42
51
|
settings?: Settings;
|
|
43
|
-
}
|
|
52
|
+
}>>;
|
|
44
53
|
export declare function addressAkumaSet(input: AkumaSetAddressInput): Promise<Readonly<{
|
|
45
54
|
path: WorldRoot;
|
|
46
55
|
ids: readonly AkuId[];
|