@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
|
@@ -57,9 +57,9 @@ export type AkumaHistoryResult = Readonly<{
|
|
|
57
57
|
id: AkumaStatus["id"];
|
|
58
58
|
contractId?: ContractId;
|
|
59
59
|
}>;
|
|
60
|
-
export declare function statusAkuma(input: AkumaAddressInput): AkumaStatusView
|
|
60
|
+
export declare function statusAkuma(input: AkumaAddressInput): Promise<AkumaStatusView>;
|
|
61
61
|
export declare function waitAkuma(input: AkumaWaitInput): Promise<AkumaWaitResult>;
|
|
62
62
|
export declare function killAkuma(input: AkumaSetAddressInput): Promise<AkumaKillResult>;
|
|
63
63
|
export declare function tellAkuma(input: AkumaTellInput): Promise<AkumaTellResult>;
|
|
64
64
|
export declare function interruptAkuma(input: AkumaInterruptInput): Promise<AkumaInterruptResult>;
|
|
65
|
-
export declare function historyAkuma(input: AkumaHistoryInput): AkumaHistoryResult
|
|
65
|
+
export declare function historyAkuma(input: AkumaHistoryInput): Promise<AkumaHistoryResult>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Akuma, } from "../akuma/index.js";
|
|
2
|
-
import { readActionFeedbackStatus } from "../akuma/akuma.js";
|
|
2
|
+
import { readActionFeedbackStatus, readBudgetedStatus } from "../akuma/akuma.js";
|
|
3
3
|
import { readDispatch } from "../dispatch/index.js";
|
|
4
4
|
import { addressAkuma, addressAkumaSet } from "./address.js";
|
|
5
5
|
import { requireInput } from "./input.js";
|
|
@@ -7,11 +7,12 @@ import { scopeForRepo } from "./repo.js";
|
|
|
7
7
|
function source(path, settings) {
|
|
8
8
|
return Akuma.of(path, settings);
|
|
9
9
|
}
|
|
10
|
-
function contractFor(repo, id) {
|
|
11
|
-
|
|
10
|
+
async function contractFor(repo, id) {
|
|
11
|
+
const dispatch = repo === undefined ? null : await readDispatch(scopeForRepo(repo), id);
|
|
12
|
+
return dispatch?.contractId;
|
|
12
13
|
}
|
|
13
|
-
function statusView(status, repo) {
|
|
14
|
-
const contractId = contractFor(repo, status.id);
|
|
14
|
+
async function statusView(status, repo) {
|
|
15
|
+
const contractId = await contractFor(repo, status.id);
|
|
15
16
|
return contractId === undefined ? { status } : { status, contractId };
|
|
16
17
|
}
|
|
17
18
|
function timeout(value) {
|
|
@@ -25,55 +26,19 @@ function timeout(value) {
|
|
|
25
26
|
function delay(milliseconds) {
|
|
26
27
|
return new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
27
28
|
}
|
|
28
|
-
const
|
|
29
|
-
function
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|| (entry.row.kind === "tell" && entry.row.state === "pending"));
|
|
33
|
-
}
|
|
34
|
-
function budgetStatus(status, allowance) {
|
|
35
|
-
const entries = [];
|
|
36
|
-
const ordinary = status.timeline.entries.filter((entry) => entry.kind === "row" && !pinned(entry));
|
|
37
|
-
const kept = new Set(allowance === 0 ? [] : ordinary.slice(-allowance));
|
|
38
|
-
const used = kept.size;
|
|
39
|
-
let hidden = 0;
|
|
40
|
-
let single;
|
|
41
|
-
const flush = () => {
|
|
42
|
-
if (hidden === 1 && single !== undefined)
|
|
43
|
-
entries.push(single);
|
|
44
|
-
else if (hidden > 0)
|
|
45
|
-
entries.push({ kind: "gap", count: hidden });
|
|
46
|
-
hidden = 0;
|
|
47
|
-
single = undefined;
|
|
48
|
-
};
|
|
49
|
-
for (const entry of status.timeline.entries) {
|
|
50
|
-
if (pinned(entry)) {
|
|
51
|
-
flush();
|
|
52
|
-
entries.push(entry);
|
|
53
|
-
continue;
|
|
54
|
-
}
|
|
55
|
-
if (entry.kind === "row" && kept.has(entry)) {
|
|
56
|
-
flush();
|
|
57
|
-
entries.push(entry);
|
|
58
|
-
continue;
|
|
59
|
-
}
|
|
60
|
-
const count = entry.kind === "gap" ? entry.count : 1;
|
|
61
|
-
if (hidden === 0 && count === 1 && entry.kind === "row")
|
|
62
|
-
single = entry;
|
|
63
|
-
else
|
|
64
|
-
single = undefined;
|
|
65
|
-
hidden += count;
|
|
29
|
+
const SHARED_ORDINARY_BUDGET = 30;
|
|
30
|
+
async function observeWaitStatuses(path, ids, settings) {
|
|
31
|
+
if (ids.length <= 1) {
|
|
32
|
+
return await Promise.all(ids.map(async (id) => await source(path, settings).of({ id }).status()));
|
|
66
33
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
return budgeted.status;
|
|
76
|
-
});
|
|
34
|
+
let remaining = SHARED_ORDINARY_BUDGET;
|
|
35
|
+
const statuses = [];
|
|
36
|
+
for (const id of ids) {
|
|
37
|
+
const observed = await readBudgetedStatus(path, id, { ordinaryBudget: remaining });
|
|
38
|
+
statuses.push(observed.status);
|
|
39
|
+
remaining -= observed.ordinarySelected;
|
|
40
|
+
}
|
|
41
|
+
return statuses;
|
|
77
42
|
}
|
|
78
43
|
function directAddress(values) {
|
|
79
44
|
return {
|
|
@@ -91,9 +56,9 @@ function setAddress(values) {
|
|
|
91
56
|
...(values.repo === undefined ? {} : { repo: values.repo }),
|
|
92
57
|
};
|
|
93
58
|
}
|
|
94
|
-
export function statusAkuma(input) {
|
|
95
|
-
const addressed = addressAkuma(input);
|
|
96
|
-
return statusView(source(addressed.path, addressed.settings).of({ id: addressed.id }).status(), input.repo);
|
|
59
|
+
export async function statusAkuma(input) {
|
|
60
|
+
const addressed = await addressAkuma(input);
|
|
61
|
+
return await statusView(await source(addressed.path, addressed.settings).of({ id: addressed.id }).status(), input.repo);
|
|
97
62
|
}
|
|
98
63
|
export async function waitAkuma(input) {
|
|
99
64
|
const values = requireInput(input, "Keiyaku.wait input");
|
|
@@ -111,15 +76,13 @@ export async function waitAkuma(input) {
|
|
|
111
76
|
throw new TypeError("completion must be any or all");
|
|
112
77
|
const selected = completion ?? "all";
|
|
113
78
|
const timeoutMs = timeout(values.timeoutMs);
|
|
114
|
-
const handles = addressed.ids.map((id) => source(addressed.path, addressed.settings).of({ id }));
|
|
115
79
|
const deadline = timeoutMs === undefined ? undefined : performance.now() + timeoutMs;
|
|
116
80
|
for (;;) {
|
|
117
|
-
const statuses =
|
|
81
|
+
const statuses = await observeWaitStatuses(addressed.path, addressed.ids, addressed.settings);
|
|
118
82
|
const settled = statuses.map((status) => status.life !== "running");
|
|
119
83
|
if ((selected === "any" ? settled.some(Boolean) : settled.every(Boolean))
|
|
120
84
|
|| (deadline !== undefined && performance.now() >= deadline)) {
|
|
121
|
-
|
|
122
|
-
return { completion: selected, statuses: observed.map((status) => statusView(status, values.repo)) };
|
|
85
|
+
return { completion: selected, statuses: await Promise.all(statuses.map(async (status) => await statusView(status, values.repo))) };
|
|
123
86
|
}
|
|
124
87
|
await delay(deadline === undefined ? 25 : Math.min(25, Math.max(0, deadline - performance.now())));
|
|
125
88
|
}
|
|
@@ -128,11 +91,12 @@ export async function killAkuma(input) {
|
|
|
128
91
|
const addressed = await addressAkumaSet(input);
|
|
129
92
|
const handles = addressed.ids.map((id) => source(addressed.path, addressed.settings).of({ id }));
|
|
130
93
|
const evidence = await Promise.all(handles.map(async (handle) => await handle.kill()));
|
|
94
|
+
const observations = await Promise.all(addressed.ids.map(async (id) => await statusView(await readActionFeedbackStatus(addressed.path, id), input.repo)));
|
|
131
95
|
return {
|
|
132
96
|
results: addressed.ids.map((id, index) => ({
|
|
133
97
|
id,
|
|
134
98
|
evidence: evidence[index],
|
|
135
|
-
observation:
|
|
99
|
+
observation: observations[index],
|
|
136
100
|
})),
|
|
137
101
|
};
|
|
138
102
|
}
|
|
@@ -144,10 +108,10 @@ export async function tellAkuma(input) {
|
|
|
144
108
|
}
|
|
145
109
|
if (typeof values.body !== "string")
|
|
146
110
|
throw new TypeError("body must be a string");
|
|
147
|
-
const addressed = addressAkuma(directAddress(values));
|
|
111
|
+
const addressed = await addressAkuma(directAddress(values));
|
|
148
112
|
const handle = source(addressed.path, addressed.settings).of({ id: addressed.id });
|
|
149
113
|
const tell = await handle.tell(values.body);
|
|
150
|
-
return { akuma: addressed.id, tell, observation: statusView(readActionFeedbackStatus(addressed.path, addressed.id), values.repo) };
|
|
114
|
+
return { akuma: addressed.id, tell, observation: await statusView(await readActionFeedbackStatus(addressed.path, addressed.id), values.repo) };
|
|
151
115
|
}
|
|
152
116
|
export async function interruptAkuma(input) {
|
|
153
117
|
const values = requireInput(input, "Keiyaku.interrupt input");
|
|
@@ -157,11 +121,11 @@ export async function interruptAkuma(input) {
|
|
|
157
121
|
}
|
|
158
122
|
if (typeof values.body !== "string")
|
|
159
123
|
throw new TypeError("body must be a string");
|
|
160
|
-
const addressed = addressAkuma(directAddress(values));
|
|
124
|
+
const addressed = await addressAkuma(directAddress(values));
|
|
161
125
|
const receipt = await source(addressed.path, addressed.settings).of({ id: addressed.id }).interrupt(values.body);
|
|
162
|
-
return { id: addressed.id, receipt, observation: statusView(readActionFeedbackStatus(addressed.path, addressed.id), values.repo) };
|
|
126
|
+
return { id: addressed.id, receipt, observation: await statusView(await readActionFeedbackStatus(addressed.path, addressed.id), values.repo) };
|
|
163
127
|
}
|
|
164
|
-
export function historyAkuma(input) {
|
|
128
|
+
export async function historyAkuma(input) {
|
|
165
129
|
const values = requireInput(input, "Keiyaku.history input");
|
|
166
130
|
for (const key of Object.keys(values)) {
|
|
167
131
|
if (!["path", "akuma", "settings", "before", "since", "limit", "last", "repo"].includes(key)) {
|
|
@@ -170,20 +134,20 @@ export function historyAkuma(input) {
|
|
|
170
134
|
}
|
|
171
135
|
if (values.last !== undefined && typeof values.last !== "boolean")
|
|
172
136
|
throw new TypeError("last must be a boolean");
|
|
173
|
-
const addressed = addressAkuma(directAddress(values));
|
|
137
|
+
const addressed = await addressAkuma(directAddress(values));
|
|
174
138
|
const handle = source(addressed.path, addressed.settings).of({ id: addressed.id });
|
|
175
139
|
if (values.last === true) {
|
|
176
|
-
const answer = handle.lastAnswer();
|
|
177
|
-
const contractId = contractFor(values.repo, addressed.id);
|
|
140
|
+
const answer = await handle.lastAnswer();
|
|
141
|
+
const contractId = await contractFor(values.repo, addressed.id);
|
|
178
142
|
return answer.kind === "answer"
|
|
179
143
|
? { kind: "last", id: addressed.id, answer: answer.answer, ...(contractId === undefined ? {} : { contractId }) }
|
|
180
144
|
: { kind: "no-answer", id: addressed.id, ...(contractId === undefined ? {} : { contractId }) };
|
|
181
145
|
}
|
|
182
|
-
const history = handle.history({
|
|
146
|
+
const history = await handle.history({
|
|
183
147
|
...(values.before === undefined ? {} : { before: values.before }),
|
|
184
148
|
...(values.since === undefined ? {} : { since: values.since }),
|
|
185
149
|
...(values.limit === undefined ? {} : { limit: values.limit }),
|
|
186
150
|
});
|
|
187
|
-
const contractId = contractFor(values.repo, addressed.id);
|
|
151
|
+
const contractId = await contractFor(values.repo, addressed.id);
|
|
188
152
|
return { kind: "history", id: addressed.id, history, ...(contractId === undefined ? {} : { contractId }) };
|
|
189
153
|
}
|
|
@@ -7,7 +7,8 @@ export { Delivery, KeiyakuRefused, KeiyakuRetry, } from "./contract.js";
|
|
|
7
7
|
export { NoGitWorldError, Repo } from "./repo.js";
|
|
8
8
|
export { gatesFrom, requireBranchesToBeUpToDateFrom, SettingsError, } from "./configuration.js";
|
|
9
9
|
export { worktreeHooksFrom } from "../git/hooks.js";
|
|
10
|
-
export
|
|
10
|
+
export { AkumaWorldScopeError } from "./address.js";
|
|
11
|
+
export type { AbandonInput, ActorId, AmendInput, AmendResult, ArcInput, AttestationVerdict, AuditInput, AuditReport, DeliveryPreparationRefusal, BindInput, BindResult, ContractBoard, ContractDisposition, ContractGateCurrent, ContractGateReport, ContractListInput, ContractObservation, ContractObservationInput, ContractPhase, ContractRow, DeliverInput, Fact, FactKind, KeiyakuOfInput, KeiyakuRefusal, KeiyakuRetryReason, Lag, MutationResult, PlacementStop, ReconcileReport, Review, ReviewInput, TaskId, TopologyEffect, VerificationReuse, VerificationStop, } from "./contract.js";
|
|
11
12
|
export type { ContractId, ContractState, ChangeId, SnapshotId, } from "../core/facts/types.js";
|
|
12
13
|
export type { Gate, GatesFromInput, HookCommand, RequireBranchesToBeUpToDateFromInput, WorktreeHooks, } from "./configuration.js";
|
|
13
14
|
export type { RegionOverlap } from "./region.js";
|
|
@@ -20,7 +21,7 @@ export type { AkumaAlias } from "../identity/selector.js";
|
|
|
20
21
|
export type { AkumaGlob } from "../identity/selector.js";
|
|
21
22
|
export type { AkuId } from "../akuma/identity.js";
|
|
22
23
|
export type { Catalog, CatalogInput, CatalogQuery } from "./catalog.js";
|
|
23
|
-
export type { AkumaAddressInput, AkumaSetAddressInput, DirectAkumaSelector, SetAkumaSelector, } from "./address.js";
|
|
24
|
+
export type { AkumaAddressInput, AkumaSetAddressInput, AkumaWorldScopeRefusal, DirectAkumaSelector, SetAkumaSelector, } from "./address.js";
|
|
24
25
|
export type { AkumaHistoryInput, AkumaHistoryResult, AkumaInterruptInput, AkumaInterruptResult, AkumaKillResult, AkumaStatusView, AkumaTellInput, AkumaTellResult, AkumaWaitInput, AkumaWaitResult, } from "./fleet.js";
|
|
25
26
|
export type Keiyaku = KeiyakuType;
|
|
26
27
|
export declare const Keiyaku: Readonly<{
|
|
@@ -7,6 +7,7 @@ export { Delivery, KeiyakuRefused, KeiyakuRetry, } from "./contract.js";
|
|
|
7
7
|
export { NoGitWorldError, Repo } from "./repo.js";
|
|
8
8
|
export { gatesFrom, requireBranchesToBeUpToDateFrom, SettingsError, } from "./configuration.js";
|
|
9
9
|
export { worktreeHooksFrom } from "../git/hooks.js";
|
|
10
|
+
export { AkumaWorldScopeError } from "./address.js";
|
|
10
11
|
export const Keiyaku = Object.freeze({
|
|
11
12
|
prototype: KeiyakuHandle.prototype,
|
|
12
13
|
[Symbol.hasInstance]: (value) => value instanceof KeiyakuHandle,
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
import type { ContractHead, ContractId, JournalEntry } from "../core/facts/types.js";
|
|
2
2
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
3
|
-
import {
|
|
3
|
+
import type { ReconcileReport, RepositoryScope } from "../protocol/operations.js";
|
|
4
4
|
import type { IntentOutcome } from "../protocol/operations.js";
|
|
5
|
+
import type { AcceptedObligations } from "../protocol/outcome.js";
|
|
5
6
|
import { type SettlementReport } from "../settlement/settle.js";
|
|
6
7
|
import type { TaskHolderAdmission } from "../settlement/holder.js";
|
|
7
8
|
import type { WorktreeHooks } from "./configuration.js";
|
|
8
|
-
import { type
|
|
9
|
+
import { type ReconcileCompletion } from "./reconcile.js";
|
|
9
10
|
export type AcceptedIntent<Value> = Readonly<{
|
|
10
11
|
kind: "accepted";
|
|
11
12
|
facts: readonly JournalEntry[];
|
|
12
13
|
head: ContractHead;
|
|
13
14
|
value: Value;
|
|
14
15
|
physical?: ReconcileReport;
|
|
15
|
-
}>;
|
|
16
|
+
} & AcceptedObligations>;
|
|
16
17
|
export type MutationResult<Value> = Readonly<{
|
|
17
18
|
facts: readonly JournalEntry[];
|
|
18
19
|
head: ContractHead;
|
|
19
20
|
value: Value;
|
|
20
|
-
effects:
|
|
21
|
-
lags:
|
|
21
|
+
effects: ReconcileCompletion["effects"];
|
|
22
|
+
lags: ReconcileCompletion["lag"];
|
|
22
23
|
settlement: SettlementReport;
|
|
23
|
-
}>;
|
|
24
|
+
} & AcceptedObligations>;
|
|
24
25
|
type Completion<Value, PublicValue> = Readonly<{
|
|
25
26
|
scope: RepositoryScope;
|
|
26
27
|
channel: GitDecodeChannel;
|
|
@@ -1,39 +1,37 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { projectContractWorktree } from "../contract-worktree.js";
|
|
1
|
+
import { deferredTaskHolderSettlement } from "../settlement/settle.js";
|
|
2
|
+
import { completeReconcile } from "./reconcile.js";
|
|
4
3
|
export async function completeMutation(input) {
|
|
5
4
|
const { scope, channel, contractId, accepted, value, hooks } = input;
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
const cleanup = deferRemoval
|
|
12
|
-
? await reconcileOperation({ scope, channel, contractId, hooks, retryHooks: false })
|
|
13
|
-
: null;
|
|
5
|
+
const report = await completeReconcile({ scope, channel, contractId, hooks, retryHooks: false });
|
|
6
|
+
const obligations = {
|
|
7
|
+
...(accepted.cleanup === undefined ? {} : { cleanup: accepted.cleanup }),
|
|
8
|
+
...(accepted.leak === undefined ? {} : { leak: accepted.leak }),
|
|
9
|
+
};
|
|
14
10
|
return {
|
|
15
11
|
facts: accepted.facts,
|
|
16
12
|
head: accepted.head,
|
|
17
13
|
value: value(accepted.value),
|
|
18
|
-
effects: [...(accepted.physical?.effects ?? []), ...
|
|
19
|
-
lags: [...(accepted.physical?.lag ?? []), ...
|
|
20
|
-
settlement,
|
|
14
|
+
effects: [...(accepted.physical?.effects ?? []), ...report.effects],
|
|
15
|
+
lags: [...(accepted.physical?.lag ?? []), ...report.lag],
|
|
16
|
+
settlement: report.settlement,
|
|
17
|
+
...obligations,
|
|
21
18
|
};
|
|
22
19
|
}
|
|
23
20
|
export async function completeHolderMutation(input) {
|
|
24
21
|
const accepted = input.requireAccepted(input.admission.result);
|
|
22
|
+
const completed = await completeMutation({ ...input.completion, accepted });
|
|
25
23
|
if (input.admission.kind === "completed")
|
|
26
|
-
return
|
|
24
|
+
return completed;
|
|
25
|
+
const deferred = deferredTaskHolderSettlement({
|
|
26
|
+
contractId: input.completion.contractId,
|
|
27
|
+
taskId: input.admission.taskId,
|
|
28
|
+
diagnostic: input.admission.diagnostic,
|
|
29
|
+
});
|
|
27
30
|
return {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
settlement: deferredTaskHolderSettlement({
|
|
34
|
-
contractId: input.completion.contractId,
|
|
35
|
-
taskId: input.admission.taskId,
|
|
36
|
-
diagnostic: input.admission.diagnostic,
|
|
37
|
-
}),
|
|
31
|
+
...completed,
|
|
32
|
+
settlement: {
|
|
33
|
+
actions: completed.settlement.actions,
|
|
34
|
+
lags: [...completed.settlement.lags, ...deferred.lags],
|
|
35
|
+
},
|
|
38
36
|
};
|
|
39
37
|
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ContractId } from "../core/facts/types.js";
|
|
2
|
+
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
3
|
+
import { type ReconcileReport, type RepositoryScope } from "../protocol/operations.js";
|
|
4
|
+
import { type SettlementReport } from "../settlement/settle.js";
|
|
5
|
+
import type { WorktreeHooks } from "./configuration.js";
|
|
6
|
+
import { type ContractFileEffect, type ContractFileLag } from "../contract-worktree.js";
|
|
7
|
+
export type ReconcileCompletion = Readonly<{
|
|
8
|
+
effects: readonly (ReconcileReport["effects"][number] | ContractFileEffect)[];
|
|
9
|
+
lag: readonly (ReconcileReport["lag"][number] | ContractFileLag)[];
|
|
10
|
+
settlement: SettlementReport;
|
|
11
|
+
}>;
|
|
12
|
+
export type RepoContractReconcileReport = ReconcileCompletion;
|
|
13
|
+
export type RepoReconcileReport = Readonly<{
|
|
14
|
+
contracts: readonly Readonly<{
|
|
15
|
+
contractId: ContractId;
|
|
16
|
+
report: RepoContractReconcileReport;
|
|
17
|
+
}>[];
|
|
18
|
+
}>;
|
|
19
|
+
type ReconcileOptions = Readonly<{
|
|
20
|
+
scope: RepositoryScope;
|
|
21
|
+
channel: GitDecodeChannel;
|
|
22
|
+
hooks: WorktreeHooks;
|
|
23
|
+
retryHooks: boolean;
|
|
24
|
+
}>;
|
|
25
|
+
export declare function completeReconcile(input: ReconcileOptions & Readonly<{
|
|
26
|
+
contractId: ContractId;
|
|
27
|
+
}>): Promise<ReconcileCompletion>;
|
|
28
|
+
export declare function completeRepoReconcile(input: ReconcileOptions): Promise<RepoReconcileReport>;
|
|
29
|
+
export {};
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { AuthorityCorruptionError } from "../core/facts/errors.js";
|
|
2
|
+
import { reconcileAllOperation, reconcileObservationFailure, reconcileOperation, stateOperation, worldContractStates, } from "../protocol/operations.js";
|
|
3
|
+
import { settle, settleAll } from "../settlement/settle.js";
|
|
4
|
+
import { projectContractWorktree, } from "../contract-worktree.js";
|
|
5
|
+
import { appointManagedWorktrees, placeRegisterPath, releaseManagedWorktrees, } from "../workspace-place.js";
|
|
6
|
+
function registerLag(scope, error) {
|
|
7
|
+
return {
|
|
8
|
+
kind: "contract-file-failed",
|
|
9
|
+
worktree: scope.primaryWorktree,
|
|
10
|
+
path: placeRegisterPath(scope),
|
|
11
|
+
diagnostic: error instanceof Error ? error.message : String(error),
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function emptySettlement() {
|
|
15
|
+
return { actions: [], lags: [] };
|
|
16
|
+
}
|
|
17
|
+
function isManagedWorktree(state) {
|
|
18
|
+
return state.coordinates.workspace === "worktree";
|
|
19
|
+
}
|
|
20
|
+
function isManagedTerminal(state) {
|
|
21
|
+
return state !== null && isManagedWorktree(state) && state.terminal !== null;
|
|
22
|
+
}
|
|
23
|
+
function appointableManagedContracts(states) {
|
|
24
|
+
return states
|
|
25
|
+
.filter((state) => isManagedWorktree(state) && state.terminal === null)
|
|
26
|
+
.map((state) => state.id);
|
|
27
|
+
}
|
|
28
|
+
async function appointPlaces(scope, states) {
|
|
29
|
+
return await appointManagedWorktrees(scope, appointableManagedContracts(states));
|
|
30
|
+
}
|
|
31
|
+
function releaseEligible(state, cleanup, appointed) {
|
|
32
|
+
return cleanup !== undefined
|
|
33
|
+
&& cleanup.lag.length === 0
|
|
34
|
+
&& isManagedTerminal(state)
|
|
35
|
+
&& appointed;
|
|
36
|
+
}
|
|
37
|
+
async function releaseAppointments(scope, contracts) {
|
|
38
|
+
try {
|
|
39
|
+
await releaseManagedWorktrees(scope, contracts);
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error instanceof AuthorityCorruptionError || error instanceof TypeError)
|
|
44
|
+
throw error;
|
|
45
|
+
return registerLag(scope, error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function observeState(scope, channel, contractId) {
|
|
49
|
+
try {
|
|
50
|
+
return { state: await stateOperation({ scope, channel, contractId }) };
|
|
51
|
+
}
|
|
52
|
+
catch (error) {
|
|
53
|
+
if (error instanceof AuthorityCorruptionError || error instanceof TypeError)
|
|
54
|
+
throw error;
|
|
55
|
+
return { failed: reconcileObservationFailure(error) };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
async function appointForContract(scope, state) {
|
|
59
|
+
if (!isManagedWorktree(state))
|
|
60
|
+
return {};
|
|
61
|
+
try {
|
|
62
|
+
const register = await appointPlaces(scope, [state]);
|
|
63
|
+
const place = register.byContract.get(state.id)?.place;
|
|
64
|
+
if (place === undefined) {
|
|
65
|
+
if (state.terminal !== null)
|
|
66
|
+
return { register };
|
|
67
|
+
throw new Error(`Place appointment was not recorded: ${state.id}`);
|
|
68
|
+
}
|
|
69
|
+
return { place, register };
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
if (error instanceof AuthorityCorruptionError || error instanceof TypeError)
|
|
73
|
+
throw error;
|
|
74
|
+
return { lag: registerLag(scope, error) };
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export async function completeReconcile(input) {
|
|
78
|
+
const observed = await observeState(input.scope, input.channel, input.contractId);
|
|
79
|
+
if ("failed" in observed) {
|
|
80
|
+
return { effects: observed.failed.effects, lag: observed.failed.lag, settlement: emptySettlement() };
|
|
81
|
+
}
|
|
82
|
+
const appointment = await appointForContract(input.scope, observed.state);
|
|
83
|
+
if ("lag" in appointment) {
|
|
84
|
+
return { effects: [], lag: [appointment.lag], settlement: emptySettlement() };
|
|
85
|
+
}
|
|
86
|
+
const appointed = appointment.place === undefined ? {} : { place: appointment.place };
|
|
87
|
+
const retained = await reconcileOperation({
|
|
88
|
+
...input,
|
|
89
|
+
retainTerminalWorktree: true,
|
|
90
|
+
...appointed,
|
|
91
|
+
});
|
|
92
|
+
const projection = await projectContractWorktree(input.scope, retained.state, appointment.register);
|
|
93
|
+
const settlement = await settle({
|
|
94
|
+
repository: input.scope,
|
|
95
|
+
channel: input.channel,
|
|
96
|
+
state: retained.state,
|
|
97
|
+
effects: retained.report.effects,
|
|
98
|
+
});
|
|
99
|
+
const cleanup = isManagedTerminal(retained.state)
|
|
100
|
+
? await reconcileOperation({ ...input, ...appointed })
|
|
101
|
+
: null;
|
|
102
|
+
const release = releaseEligible(retained.state, cleanup?.report, appointment.place !== undefined)
|
|
103
|
+
? await releaseAppointments(input.scope, [input.contractId])
|
|
104
|
+
: undefined;
|
|
105
|
+
return {
|
|
106
|
+
effects: [...retained.report.effects, ...projection.effects, ...(cleanup?.report.effects ?? [])],
|
|
107
|
+
lag: [...retained.report.lag, ...projection.lag, ...(cleanup?.report.lag ?? []), ...(release === undefined ? [] : [release])],
|
|
108
|
+
settlement,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function attachReleaseLag(contracts, released, lag) {
|
|
112
|
+
const affected = new Set(released);
|
|
113
|
+
return {
|
|
114
|
+
contracts: contracts.map((contract) => affected.has(contract.contractId)
|
|
115
|
+
? { ...contract, report: { ...contract.report, lag: [...contract.report.lag, lag] } }
|
|
116
|
+
: contract),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
export async function completeRepoReconcile(input) {
|
|
120
|
+
const states = await worldContractStates(input);
|
|
121
|
+
let appointed;
|
|
122
|
+
try {
|
|
123
|
+
appointed = await appointPlaces(input.scope, states);
|
|
124
|
+
}
|
|
125
|
+
catch (error) {
|
|
126
|
+
if (error instanceof AuthorityCorruptionError || error instanceof TypeError)
|
|
127
|
+
throw error;
|
|
128
|
+
const lag = registerLag(input.scope, error);
|
|
129
|
+
const contracts = [];
|
|
130
|
+
for (const state of states) {
|
|
131
|
+
contracts.push({
|
|
132
|
+
contractId: state.id,
|
|
133
|
+
report: isManagedWorktree(state)
|
|
134
|
+
? { effects: [], lag: [lag], settlement: emptySettlement() }
|
|
135
|
+
: await completeReconcile({ ...input, contractId: state.id }),
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return { contracts };
|
|
139
|
+
}
|
|
140
|
+
const places = new Map(appointed.appointments.map((appointment) => [appointment.contract, appointment.place]));
|
|
141
|
+
const retained = await reconcileAllOperation({
|
|
142
|
+
...input,
|
|
143
|
+
retainTerminalWorktree: true,
|
|
144
|
+
places,
|
|
145
|
+
});
|
|
146
|
+
const settlements = await settleAll({
|
|
147
|
+
repository: input.scope,
|
|
148
|
+
channel: input.channel,
|
|
149
|
+
contracts: retained.contracts.map((contract) => ({
|
|
150
|
+
state: contract.state,
|
|
151
|
+
effects: contract.report.effects,
|
|
152
|
+
})),
|
|
153
|
+
});
|
|
154
|
+
const cleanup = retained.contracts.some((contract) => isManagedTerminal(contract.state))
|
|
155
|
+
? await reconcileAllOperation({ ...input, places })
|
|
156
|
+
: null;
|
|
157
|
+
const later = cleanup === null
|
|
158
|
+
? null
|
|
159
|
+
: new Map(cleanup.contracts.map((contract) => [contract.contractId, contract.report]));
|
|
160
|
+
const released = [];
|
|
161
|
+
const contracts = [];
|
|
162
|
+
for (const [index, contract] of retained.contracts.entries()) {
|
|
163
|
+
const report = later?.get(contract.contractId);
|
|
164
|
+
if (releaseEligible(contract.state, report, places.has(contract.contractId))) {
|
|
165
|
+
released.push(contract.contractId);
|
|
166
|
+
}
|
|
167
|
+
const projection = await projectContractWorktree(input.scope, contract.state, appointed);
|
|
168
|
+
contracts.push({
|
|
169
|
+
contractId: contract.contractId,
|
|
170
|
+
report: {
|
|
171
|
+
effects: [...contract.report.effects, ...projection.effects, ...(report?.effects ?? [])],
|
|
172
|
+
lag: [...contract.report.lag, ...projection.lag, ...(report?.lag ?? [])],
|
|
173
|
+
settlement: settlements[index],
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
const lag = await releaseAppointments(input.scope, released);
|
|
178
|
+
return lag === undefined ? { contracts } : attachReleaseLag(contracts, released, lag);
|
|
179
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ContractId } from "../core/facts/types.js";
|
|
2
2
|
import type { GitDecodeChannel } from "../git/read-observation.js";
|
|
3
3
|
import { type RepositoryScope } from "../protocol/operations.js";
|
|
4
|
+
import type { ContractDocumentProjection } from "../protocol/operations.js";
|
|
4
5
|
export type RegionOverlap = Readonly<{
|
|
5
6
|
contract: ContractId;
|
|
6
7
|
patterns: readonly Readonly<{
|
|
@@ -15,4 +16,15 @@ export type RegionObservation = Readonly<{
|
|
|
15
16
|
overlapFailure: string;
|
|
16
17
|
overlaps?: never;
|
|
17
18
|
}>;
|
|
19
|
+
export type RegionDeclarationRead = Readonly<{
|
|
20
|
+
contract: ContractId;
|
|
21
|
+
patterns: readonly string[];
|
|
22
|
+
}>;
|
|
23
|
+
export declare function readRegionDeclarations(documents: readonly ContractDocumentProjection[]): readonly RegionDeclarationRead[];
|
|
24
|
+
export declare function regionIntersections(left: readonly string[], right: readonly string[]): readonly Readonly<{
|
|
25
|
+
left: string;
|
|
26
|
+
right: string;
|
|
27
|
+
}>[];
|
|
28
|
+
export declare function regionPathMatches(patterns: readonly string[], path: string): readonly string[];
|
|
29
|
+
export declare function validateRegionPath(path: unknown): asserts path is string;
|
|
18
30
|
export declare function observeRegion(scope: RepositoryScope, channel: GitDecodeChannel, self: ContractId, mine: readonly string[]): Promise<RegionObservation>;
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import { decodeContractDocument } from "../body/decode.js";
|
|
2
|
-
import { regionsOverlap } from "../body/region.js";
|
|
2
|
+
import { assertCanonicalRegionPath, regionPatternsMatchPath, regionsOverlap } from "../body/region.js";
|
|
3
3
|
import { documentsOperationAt } from "../protocol/operations.js";
|
|
4
|
+
export function readRegionDeclarations(documents) {
|
|
5
|
+
return documents.map((document) => ({ contract: document.contract, patterns: decodeContractDocument(document.documentBytes).region }));
|
|
6
|
+
}
|
|
7
|
+
export function regionIntersections(left, right) {
|
|
8
|
+
return regionsOverlap(left, right).map(([leftPattern, rightPattern]) => ({ left: leftPattern, right: rightPattern }));
|
|
9
|
+
}
|
|
10
|
+
export function regionPathMatches(patterns, path) {
|
|
11
|
+
return regionPatternsMatchPath(patterns, path);
|
|
12
|
+
}
|
|
13
|
+
export function validateRegionPath(path) {
|
|
14
|
+
if (typeof path !== "string")
|
|
15
|
+
throw new Error("Region path must be a string");
|
|
16
|
+
assertCanonicalRegionPath(path);
|
|
17
|
+
}
|
|
4
18
|
function diagnostic(error) {
|
|
5
19
|
return error instanceof Error ? error.message : String(error);
|
|
6
20
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { NoGitWorldError, type
|
|
2
|
-
import { type SettlementReport } from "../settlement/settle.js";
|
|
1
|
+
import { NoGitWorldError, type RepositoryScope } from "../protocol/operations.js";
|
|
3
2
|
import { type WorktreeHooks } from "./configuration.js";
|
|
4
|
-
import type
|
|
5
|
-
import { type ContractFileEffect, type ContractFileLag } from "../contract-worktree.js";
|
|
3
|
+
import { type RepoContractReconcileReport, type RepoReconcileReport } from "./reconcile.js";
|
|
6
4
|
export { NoGitWorldError };
|
|
5
|
+
export type { RepoContractReconcileReport, RepoReconcileReport };
|
|
7
6
|
export type RepoAtInput = Readonly<{
|
|
8
7
|
path?: string;
|
|
9
8
|
}>;
|
|
@@ -11,17 +10,6 @@ export type ReconcileInput = Readonly<{
|
|
|
11
10
|
hooks?: WorktreeHooks;
|
|
12
11
|
retryHooks?: boolean;
|
|
13
12
|
}>;
|
|
14
|
-
export type RepoContractReconcileReport = Readonly<{
|
|
15
|
-
effects: readonly (ProtocolReconcileReport["effects"][number] | ContractFileEffect)[];
|
|
16
|
-
lag: readonly (ProtocolReconcileReport["lag"][number] | ContractFileLag)[];
|
|
17
|
-
settlement: SettlementReport;
|
|
18
|
-
}>;
|
|
19
|
-
export type RepoReconcileReport = Readonly<{
|
|
20
|
-
contracts: readonly Readonly<{
|
|
21
|
-
contractId: ContractId;
|
|
22
|
-
report: RepoContractReconcileReport;
|
|
23
|
-
}>[];
|
|
24
|
-
}>;
|
|
25
13
|
export declare function reconcileInput(input: ReconcileInput | undefined): Readonly<{
|
|
26
14
|
hooks: WorktreeHooks;
|
|
27
15
|
retryHooks: boolean;
|
|
@@ -29,7 +17,7 @@ export declare function reconcileInput(input: ReconcileInput | undefined): Reado
|
|
|
29
17
|
export declare class Repo {
|
|
30
18
|
readonly root: string;
|
|
31
19
|
private constructor();
|
|
32
|
-
static at(input?: RepoAtInput): Repo
|
|
20
|
+
static at(input?: RepoAtInput): Promise<Repo>;
|
|
33
21
|
currentBranch(): Promise<string | null>;
|
|
34
22
|
reconcile(input?: ReconcileInput): Promise<RepoReconcileReport>;
|
|
35
23
|
}
|