@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
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { readStatusFacts, readLifeSnapshot, HeldAkumaLeash, isHeartAbsent, life, lifeAt, probeLeash, readHeart, readSeal, readSoul, } from "./heart/index.js";
|
|
1
|
+
import { readStatusFacts, createStatusFactReader, readLifeSnapshot, HeldAkumaLeash, isHeartAbsent, life, lifeAt, probeLeash, readHeart, readSeal, readSoul, } from "./heart/index.js";
|
|
2
2
|
import { pathsForAkuId } from "./identity.js";
|
|
3
3
|
import { ordinarySnapshotBudget, projectTurns, selectHistory, selectSnapshot, } from "./projection.js";
|
|
4
4
|
import { resolveProviderExecution } from "./providers/index.js";
|
|
@@ -59,21 +59,68 @@ async function bornObservation(paths, expected, read, snapshot) {
|
|
|
59
59
|
claim?.release();
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
|
+
export async function observeOutcomeRows(id, rows, observer) {
|
|
63
|
+
if (observer === undefined)
|
|
64
|
+
return;
|
|
65
|
+
const historyIds = rows.flatMap((row) => (row.kind === "outcome" ? [row.outcome.historyId] : []));
|
|
66
|
+
if (historyIds.length > 0)
|
|
67
|
+
await observer(id, historyIds);
|
|
68
|
+
}
|
|
69
|
+
export async function observeStatusOutcome(status, observer) {
|
|
70
|
+
const snapshot = status.timeline;
|
|
71
|
+
if (snapshot.kind === "idle" && snapshot.outcome !== undefined)
|
|
72
|
+
await observer?.(status.id, [snapshot.outcome.outcome.historyId]);
|
|
73
|
+
}
|
|
74
|
+
function snapshotSelection(input) {
|
|
75
|
+
return {
|
|
76
|
+
aperture: input.aperture,
|
|
77
|
+
budget: ordinarySnapshotBudget(input.ordinaryBudget),
|
|
78
|
+
...(input.admittedTellId === undefined ? {} : { admittedTellId: input.admittedTellId }),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
/** Private to a live wait: retain only this member's current frontier and last selection. */
|
|
82
|
+
export function createLiveStatusReader(paths, expected) {
|
|
83
|
+
const reader = createStatusFactReader(paths);
|
|
84
|
+
let memo;
|
|
85
|
+
const clear = () => {
|
|
86
|
+
reader.clear();
|
|
87
|
+
memo = undefined;
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
clear,
|
|
91
|
+
async read(input, signal) {
|
|
92
|
+
try {
|
|
93
|
+
return await bornLiveStatus(paths, expected, input, signal, async () => {
|
|
94
|
+
const facts = await reader.read(input, signal);
|
|
95
|
+
const ledger = memo?.facts === facts ? memo.ledger : projectTurns(facts);
|
|
96
|
+
const options = snapshotSelection(input);
|
|
97
|
+
const selected = memo?.ledger === ledger &&
|
|
98
|
+
memo.options.aperture === options.aperture &&
|
|
99
|
+
memo.options.admittedTellId === options.admittedTellId &&
|
|
100
|
+
memo.options.budget.tail === options.budget.tail &&
|
|
101
|
+
memo.options.budget.voice === options.budget.voice
|
|
102
|
+
? memo.selected
|
|
103
|
+
: selectSnapshot(ledger, options);
|
|
104
|
+
memo = { facts, ledger, options, selected };
|
|
105
|
+
return { ledger, selected };
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
clear();
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
62
115
|
/** Internal live companion for an observation loop; it is not a public result. */
|
|
63
|
-
export async function bornLiveStatus(paths, expected, input) {
|
|
116
|
+
export async function bornLiveStatus(paths, expected, input, signal, readProjection) {
|
|
64
117
|
if (input.ordinaryBudget !== undefined && (!Number.isSafeInteger(input.ordinaryBudget) || input.ordinaryBudget < 0))
|
|
65
118
|
throw new TypeError("ordinary budget must be a nonnegative safe integer");
|
|
66
|
-
const { snapshot, soul, currentLife } = await bornObservation(paths, expected, () => readLifeSnapshot(paths));
|
|
119
|
+
const { snapshot, soul, currentLife } = await bornObservation(paths, expected, () => readLifeSnapshot(paths, signal));
|
|
67
120
|
const resumeUnsupported = currentLife === "stranded" &&
|
|
68
121
|
snapshot.latestSession?.provider === soul.provider.name &&
|
|
69
122
|
(await resolveProviderExecution(soul.provider)).adapter.resume === undefined;
|
|
70
|
-
const
|
|
71
|
-
const ledger = projectTurns(facts);
|
|
72
|
-
const selected = selectSnapshot(ledger, {
|
|
73
|
-
aperture: input.aperture,
|
|
74
|
-
budget: ordinarySnapshotBudget(input.ordinaryBudget),
|
|
75
|
-
...(input.admittedTellId === undefined ? {} : { admittedTellId: input.admittedTellId }),
|
|
76
|
-
});
|
|
123
|
+
const { ledger, selected } = readProjection === undefined ? await readStatusProjection(paths, input, signal) : await readProjection();
|
|
77
124
|
return {
|
|
78
125
|
status: {
|
|
79
126
|
id: soul.id,
|
|
@@ -87,12 +134,20 @@ export async function bornLiveStatus(paths, expected, input) {
|
|
|
87
134
|
rows: ledger.rows,
|
|
88
135
|
};
|
|
89
136
|
}
|
|
137
|
+
async function readStatusProjection(paths, input, signal) {
|
|
138
|
+
const facts = await readStatusFacts(paths, input, signal);
|
|
139
|
+
const ledger = projectTurns(facts);
|
|
140
|
+
return {
|
|
141
|
+
ledger,
|
|
142
|
+
selected: selectSnapshot(ledger, snapshotSelection(input)),
|
|
143
|
+
};
|
|
144
|
+
}
|
|
90
145
|
export async function bornStatus(paths, expected, input) {
|
|
91
146
|
const { rows: _rows, ...status } = await bornLiveStatus(paths, expected, input);
|
|
92
147
|
return status;
|
|
93
148
|
}
|
|
94
|
-
export async function readLiveStatus(worldPath, id, input) {
|
|
95
|
-
return await bornLiveStatus(pathsForAkuId(worldPath, id), id, input);
|
|
149
|
+
export async function readLiveStatus(worldPath, id, input, signal) {
|
|
150
|
+
return await bornLiveStatus(pathsForAkuId(worldPath, id), id, input, signal);
|
|
96
151
|
}
|
|
97
152
|
function complete(life, pending) {
|
|
98
153
|
return life !== "running" && !pending;
|
|
@@ -100,10 +155,26 @@ function complete(life, pending) {
|
|
|
100
155
|
export function defaultWaitComplete(status) {
|
|
101
156
|
return complete(status.life, status.timeline.entries.some((entry) => entry.kind === "row" && entry.row.kind === "tell" && entry.row.state === "pending"));
|
|
102
157
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
158
|
+
/** Probe completion only; returned statuses still come from a full observation. */
|
|
159
|
+
export async function readWaitComplete(worldPath, ids, completion, signal) {
|
|
160
|
+
let completed = 0;
|
|
161
|
+
for (const id of ids) {
|
|
162
|
+
signal?.throwIfAborted();
|
|
163
|
+
try {
|
|
164
|
+
const paths = pathsForAkuId(worldPath, id);
|
|
165
|
+
const observed = await bornObservation(paths, id, () => readLifeSnapshot(paths, signal));
|
|
166
|
+
if (complete(observed.currentLife, observed.snapshot.hasPendingTell)) {
|
|
167
|
+
if (completion === "any")
|
|
168
|
+
return true;
|
|
169
|
+
completed += 1;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch (error) {
|
|
173
|
+
if (ids.length === 1 || error instanceof AkumaNotBornError)
|
|
174
|
+
throw error;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return ids.length > 0 && completed === ids.length;
|
|
107
178
|
}
|
|
108
179
|
const OBSERVATION_POLL_MS = 100;
|
|
109
180
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WorldRoot } from "../world.js";
|
|
2
|
-
import { type LiveStatusObservation, type WaitReason } from "./akuma-observe.js";
|
|
2
|
+
import { type OutcomeObserver, type LiveStatusObservation, type WaitReason } from "./akuma-observe.js";
|
|
3
3
|
import type { AkumaStatus } from "./akuma.js";
|
|
4
4
|
import { type TellResult, type TellWakeRuntime } from "./body.js";
|
|
5
5
|
import { type CallInitialTell, type CallInitialTellAdmission } from "./call-initial-tell.js";
|
|
@@ -68,7 +68,8 @@ export declare function killAkumaWithRecovery(paths: AkumaPaths, recover?: (path
|
|
|
68
68
|
export declare class AkumaOwner {
|
|
69
69
|
readonly id: AkuId;
|
|
70
70
|
private readonly worldPath;
|
|
71
|
-
|
|
71
|
+
private readonly outcomeObserved?;
|
|
72
|
+
constructor(id: AkuId, worldPath: WorldRoot, outcomeObserved?: OutcomeObserver | undefined);
|
|
72
73
|
private get paths();
|
|
73
74
|
private projectHistoryTurns;
|
|
74
75
|
private exactHistory;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { AkumaNotBornError, AkumaProviderError } from "./akuma-errors.js";
|
|
3
|
-
import { bornLiveStatus, bornStatus, defaultWaitComplete, waitForObservation, } from "./akuma-observe.js";
|
|
3
|
+
import { bornLiveStatus, bornStatus, defaultWaitComplete, observeOutcomeRows, observeStatusOutcome, waitForObservation, } from "./akuma-observe.js";
|
|
4
4
|
import { executeWaitAkuma } from "./akuma-wait.js";
|
|
5
5
|
import { handoffPendingTells, spawnAkumaBody, wakeRecordedTell, } from "./body.js";
|
|
6
6
|
import { admitCallInitialTell } from "./call-initial-tell.js";
|
|
@@ -88,9 +88,11 @@ export async function killAkumaWithRecovery(paths, recover, signal) {
|
|
|
88
88
|
export class AkumaOwner {
|
|
89
89
|
id;
|
|
90
90
|
worldPath;
|
|
91
|
-
|
|
91
|
+
outcomeObserved;
|
|
92
|
+
constructor(id, worldPath, outcomeObserved) {
|
|
92
93
|
this.id = id;
|
|
93
94
|
this.worldPath = worldPath;
|
|
95
|
+
this.outcomeObserved = outcomeObserved;
|
|
94
96
|
}
|
|
95
97
|
get paths() {
|
|
96
98
|
return pathsForAkuId(this.worldPath, this.id);
|
|
@@ -109,11 +111,17 @@ export class AkumaOwner {
|
|
|
109
111
|
return selectExactHistory((await this.projectHistoryTurns()).rows, input.id);
|
|
110
112
|
}
|
|
111
113
|
async status() {
|
|
112
|
-
|
|
114
|
+
const { status } = await bornStatus(this.paths, this.id, { aperture: "monitoring" });
|
|
115
|
+
await observeStatusOutcome(status, this.outcomeObserved);
|
|
116
|
+
return status;
|
|
113
117
|
}
|
|
114
118
|
async history(input = {}) {
|
|
115
|
-
if (input.id !== undefined)
|
|
116
|
-
|
|
119
|
+
if (input.id !== undefined) {
|
|
120
|
+
const exact = await this.exactHistory(input);
|
|
121
|
+
if (exact.kind === "exact")
|
|
122
|
+
await this.outcomeObserved?.(this.id, [exact.outcome.outcome.historyId]);
|
|
123
|
+
return exact;
|
|
124
|
+
}
|
|
117
125
|
if (input.before !== undefined && input.since !== undefined) {
|
|
118
126
|
throw new TypeError("Akuma history before and since are mutually exclusive");
|
|
119
127
|
}
|
|
@@ -129,11 +137,13 @@ export class AkumaOwner {
|
|
|
129
137
|
if (!Number.isSafeInteger(limit) || limit <= 0 || limit > 5_000) {
|
|
130
138
|
throw new TypeError("Akuma history limit must be a positive safe integer no greater than 5000");
|
|
131
139
|
}
|
|
132
|
-
|
|
140
|
+
const history = selectHistory(await this.projectHistoryTurns(), {
|
|
133
141
|
...(input.before === undefined ? {} : { before: input.before }),
|
|
134
142
|
...(input.since === undefined ? {} : { since: input.since }),
|
|
135
143
|
limit,
|
|
136
144
|
});
|
|
145
|
+
await observeOutcomeRows(this.id, history.rows, this.outcomeObserved);
|
|
146
|
+
return history;
|
|
137
147
|
}
|
|
138
148
|
async waitReceipt(predicate = defaultWaitComplete, options = {}) {
|
|
139
149
|
if (options.timeoutMs !== undefined && (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)) {
|
|
@@ -143,6 +153,7 @@ export class AkumaOwner {
|
|
|
143
153
|
path: this.worldPath,
|
|
144
154
|
ids: [this.id],
|
|
145
155
|
completion: "all",
|
|
156
|
+
...(this.outcomeObserved === undefined ? {} : { outcomeObserved: this.outcomeObserved }),
|
|
146
157
|
...(options.timeoutMs === undefined ? {} : { timeoutMs: options.timeoutMs }),
|
|
147
158
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
148
159
|
...(predicate === defaultWaitComplete ? {} : { predicate }),
|
|
@@ -220,6 +231,8 @@ export class AkumaOwner {
|
|
|
220
231
|
if (tell === null)
|
|
221
232
|
throw new AkumaProviderError(`recorded Tell ${tellId} is missing from Heart`);
|
|
222
233
|
const outcome = await this.boundTellOutcome(tell);
|
|
234
|
+
if (outcome.historyId !== undefined)
|
|
235
|
+
await this.outcomeObserved?.(this.id, [outcome.historyId]);
|
|
223
236
|
if (options.observe !== undefined) {
|
|
224
237
|
await options.observe(await bornLiveStatus(this.paths, this.id, { aperture: "monitoring", admittedTellId: tellId }));
|
|
225
238
|
}
|
|
@@ -237,7 +250,11 @@ export class AkumaOwner {
|
|
|
237
250
|
if (tell.binding === undefined)
|
|
238
251
|
return { outcome: null, completedAt: null };
|
|
239
252
|
const end = (await readTurn(this.paths, tell.binding.turnSequence))?.end;
|
|
240
|
-
return {
|
|
253
|
+
return {
|
|
254
|
+
outcome: end?.outcome ?? null,
|
|
255
|
+
completedAt: end?.completedAt ?? null,
|
|
256
|
+
...(end === undefined ? {} : { historyId: `turn/${tell.binding.turnSequence}` }),
|
|
257
|
+
};
|
|
241
258
|
}
|
|
242
259
|
async interrupt(body, options = {}) {
|
|
243
260
|
const admitted = await this.admitInterrupt(body, options);
|
|
@@ -369,9 +386,10 @@ export class AkumaOwner {
|
|
|
369
386
|
}
|
|
370
387
|
async lastAnswer() {
|
|
371
388
|
const turn = await readLastAnsweredTurn(this.paths);
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
389
|
+
if (turn?.end?.outcome.kind !== "answered")
|
|
390
|
+
return { kind: "no-answer" };
|
|
391
|
+
await this.outcomeObserved?.(this.id, [`turn/${turn.sequence}`]);
|
|
392
|
+
return { kind: "answer", answer: turn.end.outcome.answer };
|
|
375
393
|
}
|
|
376
394
|
}
|
|
377
395
|
/* ---------------------------------------------------------------------------
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { WorldRoot } from "../world.js";
|
|
2
|
-
import type { LiveStatusObservation } from "./akuma-observe.js";
|
|
2
|
+
import type { LiveStatusObservation, OutcomeObserver } from "./akuma-observe.js";
|
|
3
3
|
import type { AkumaStatus } from "./akuma.js";
|
|
4
4
|
import type { TellResult } from "./body.js";
|
|
5
5
|
import type { Schema } from "./schema.js";
|
|
@@ -18,6 +18,7 @@ type TellExecutionInput = Readonly<{
|
|
|
18
18
|
signal?: AbortSignal;
|
|
19
19
|
interrupt?: boolean;
|
|
20
20
|
onObserve?: AskObserver;
|
|
21
|
+
outcomeObserved?: OutcomeObserver;
|
|
21
22
|
}>;
|
|
22
23
|
export declare function executeTellAkuma(input: TellExecutionInput): Promise<AkumaTellResult>;
|
|
23
24
|
export declare function decodeAskObservation<T>(observation: AkumaAskObservation, schema: Schema<T>): AkumaAskObservation<T>;
|
|
@@ -37,6 +38,7 @@ export declare function observeAdmittedAskAkuma(input: Readonly<{
|
|
|
37
38
|
*/
|
|
38
39
|
receipt?: TellResult;
|
|
39
40
|
onObserve?: AskObserver;
|
|
41
|
+
outcomeObserved?: OutcomeObserver;
|
|
40
42
|
}>): Promise<AkumaAskResult>;
|
|
41
43
|
export declare function executeAskAkuma(input: TellExecutionInput & Readonly<{
|
|
42
44
|
timeoutMs?: number;
|
|
@@ -64,7 +64,7 @@ export function decodeAskObservation(observation, schema) {
|
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
export async function observeAdmittedAskAkuma(input) {
|
|
67
|
-
const owner = new AkumaOwner(input.id, input.path);
|
|
67
|
+
const owner = new AkumaOwner(input.id, input.path, input.outcomeObserved);
|
|
68
68
|
const tell = input.receipt ?? (await owner.admittedReceipt(input.tellId));
|
|
69
69
|
await input.onObserve?.admitted?.(tell, input.id);
|
|
70
70
|
let settled;
|
|
@@ -118,6 +118,7 @@ export async function executeAskAkuma(input) {
|
|
|
118
118
|
wake: admission.wake,
|
|
119
119
|
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
120
120
|
...(input.onObserve === undefined ? {} : { onObserve: input.onObserve }),
|
|
121
|
+
...(input.outcomeObserved === undefined ? {} : { outcomeObserved: input.outcomeObserved }),
|
|
121
122
|
});
|
|
122
123
|
}
|
|
123
124
|
export async function executeKillAkuma(input) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AkumaAlias } from "../identity/selector.js";
|
|
2
2
|
import type { WorldRoot } from "../world.js";
|
|
3
|
-
import { type WaitReason } from "./akuma-observe.js";
|
|
3
|
+
import { type OutcomeObserver, type WaitReason } from "./akuma-observe.js";
|
|
4
4
|
import type { AkumaStatus } from "./akuma.js";
|
|
5
5
|
import type { DispatchAssociation } from "./dispatch-association.js";
|
|
6
6
|
import type { ActivityRow } from "./projection.js";
|
|
@@ -33,6 +33,7 @@ type WaitExecutionInput = Readonly<{
|
|
|
33
33
|
signal?: AbortSignal;
|
|
34
34
|
/** Internal custom completion judge over the full final observation where supplied. */
|
|
35
35
|
predicate?: (status: AkumaStatus) => boolean;
|
|
36
|
+
outcomeObserved?: OutcomeObserver;
|
|
36
37
|
/** Resolves one Akuma's identity facts; consulted once per Akuma a viewer first sees. */
|
|
37
38
|
identity?: (id: AkumaStatus["id"]) => Promise<WaitIdentityFacts>;
|
|
38
39
|
/** The selected set in the caller's order; a viewer's head and scoreboard follow it. */
|
|
@@ -53,9 +54,10 @@ export type NativeWaitResult = Readonly<{
|
|
|
53
54
|
* The one lower set-observation owner for Akuma wait completion. It serves the
|
|
54
55
|
* standalone one-ID association-free face and the plural any/all face with one
|
|
55
56
|
* ordered round algorithm, one shared ordinary-detail budget, transient
|
|
56
|
-
* unreadable peers, and an honest final deadline edge.
|
|
57
|
-
*
|
|
58
|
-
*
|
|
57
|
+
* unreadable peers, and an honest final deadline edge. A silent observation —
|
|
58
|
+
* no live row callback and no custom judge — decides which running rounds to
|
|
59
|
+
* skip with the owner's lightweight completion probe over the selected set; a
|
|
60
|
+
* live viewer or a custom judge always observes full rounds.
|
|
59
61
|
*/
|
|
60
62
|
export declare function executeWaitAkuma(input: WaitExecutionInput): Promise<NativeWaitResult>;
|
|
61
63
|
export {};
|
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { AkumaNotBornError } from "./akuma-errors.js";
|
|
2
|
-
import { defaultWaitComplete, readLiveStatus, readWaitComplete, waitForObservation, } from "./akuma-observe.js";
|
|
2
|
+
import { createLiveStatusReader, defaultWaitComplete, readLiveStatus, readWaitComplete, observeOutcomeRows, observeStatusOutcome, waitForObservation, } from "./akuma-observe.js";
|
|
3
|
+
import { pathsForAkuId } from "./identity.js";
|
|
3
4
|
const SHARED_ORDINARY_BUDGET = 30;
|
|
4
|
-
async function observeWaitRound(path, ids, signal) {
|
|
5
|
+
async function observeWaitRound(path, ids, signal, readers) {
|
|
6
|
+
const read = async (id, ordinaryBudget) => {
|
|
7
|
+
const options = { aperture: "monitoring", ...(ordinaryBudget === undefined ? {} : { ordinaryBudget }) };
|
|
8
|
+
if (readers === undefined)
|
|
9
|
+
return await readLiveStatus(path, id, options, signal);
|
|
10
|
+
let reader = readers.get(id);
|
|
11
|
+
if (reader === undefined) {
|
|
12
|
+
reader = createLiveStatusReader(pathsForAkuId(path, id), id);
|
|
13
|
+
readers.set(id, reader);
|
|
14
|
+
}
|
|
15
|
+
return await reader.read(options, signal);
|
|
16
|
+
};
|
|
5
17
|
signal?.throwIfAborted();
|
|
6
18
|
if (ids.length <= 1) {
|
|
7
|
-
const observations = await Promise.all(ids.map(async (id) => await
|
|
19
|
+
const observations = await Promise.all(ids.map(async (id) => await read(id)));
|
|
8
20
|
return { observations, unobserved: [] };
|
|
9
21
|
}
|
|
10
22
|
let remaining = SHARED_ORDINARY_BUDGET;
|
|
@@ -13,11 +25,13 @@ async function observeWaitRound(path, ids, signal) {
|
|
|
13
25
|
for (const id of ids) {
|
|
14
26
|
signal?.throwIfAborted();
|
|
15
27
|
try {
|
|
16
|
-
const observed = await
|
|
28
|
+
const observed = await read(id, remaining);
|
|
17
29
|
observations.push(observed);
|
|
18
30
|
remaining -= observed.ordinarySelected;
|
|
19
31
|
}
|
|
20
32
|
catch (error) {
|
|
33
|
+
readers?.get(id)?.clear();
|
|
34
|
+
readers?.delete(id);
|
|
21
35
|
if (error instanceof AkumaNotBornError)
|
|
22
36
|
throw error;
|
|
23
37
|
unobserved.push({ id, diagnostic: diagnostic(error) });
|
|
@@ -54,59 +68,70 @@ function selectionOrderedIds(ids, order) {
|
|
|
54
68
|
* The one lower set-observation owner for Akuma wait completion. It serves the
|
|
55
69
|
* standalone one-ID association-free face and the plural any/all face with one
|
|
56
70
|
* ordered round algorithm, one shared ordinary-detail budget, transient
|
|
57
|
-
* unreadable peers, and an honest final deadline edge.
|
|
58
|
-
*
|
|
59
|
-
*
|
|
71
|
+
* unreadable peers, and an honest final deadline edge. A silent observation —
|
|
72
|
+
* no live row callback and no custom judge — decides which running rounds to
|
|
73
|
+
* skip with the owner's lightweight completion probe over the selected set; a
|
|
74
|
+
* live viewer or a custom judge always observes full rounds.
|
|
60
75
|
*/
|
|
61
76
|
export async function executeWaitAkuma(input) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
input.onSelected(ordered.map((id) => ({ id, ...facts.get(id) })));
|
|
72
|
-
}
|
|
73
|
-
const observeRound = async (round) => {
|
|
74
|
-
if (input.observe === undefined)
|
|
75
|
-
return;
|
|
76
|
-
const observed = [];
|
|
77
|
-
for (const observation of round.observations) {
|
|
78
|
-
input.signal?.throwIfAborted();
|
|
79
|
-
const { status, rows } = observation;
|
|
80
|
-
let known = facts.get(status.id);
|
|
81
|
-
if (known === undefined && input.identity !== undefined) {
|
|
82
|
-
known = await input.identity(status.id);
|
|
83
|
-
facts.set(status.id, known);
|
|
84
|
-
}
|
|
85
|
-
if (known === undefined) {
|
|
86
|
-
observed.push({ status, rows, contract: { kind: "none" } });
|
|
87
|
-
continue;
|
|
77
|
+
const readers = input.observe === undefined ? undefined : new Map();
|
|
78
|
+
try {
|
|
79
|
+
// Identity facts are read once per observed Akuma, not once per 100ms round.
|
|
80
|
+
const facts = new Map();
|
|
81
|
+
if (input.onSelected !== undefined) {
|
|
82
|
+
for (const id of input.ids) {
|
|
83
|
+
input.signal?.throwIfAborted();
|
|
84
|
+
const known = input.identity === undefined ? undefined : await input.identity(id);
|
|
85
|
+
facts.set(id, known ?? { contract: { kind: "none" } });
|
|
88
86
|
}
|
|
89
|
-
|
|
87
|
+
const ordered = input.selectionOrder === undefined ? input.ids : selectionOrderedIds(input.ids, input.selectionOrder);
|
|
88
|
+
input.onSelected(ordered.map((id) => ({ id, ...facts.get(id) })));
|
|
90
89
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
90
|
+
const observeRound = async (round) => {
|
|
91
|
+
await Promise.all(round.observations.map(({ status, rows }) => input.observe === undefined
|
|
92
|
+
? observeStatusOutcome(status, input.outcomeObserved)
|
|
93
|
+
: observeOutcomeRows(status.id, rows, input.outcomeObserved)));
|
|
94
|
+
if (input.observe === undefined)
|
|
95
|
+
return;
|
|
96
|
+
const observed = [];
|
|
97
|
+
for (const observation of round.observations) {
|
|
98
|
+
input.signal?.throwIfAborted();
|
|
99
|
+
const { status, rows } = observation;
|
|
100
|
+
let known = facts.get(status.id);
|
|
101
|
+
if (known === undefined && input.identity !== undefined) {
|
|
102
|
+
known = await input.identity(status.id);
|
|
103
|
+
facts.set(status.id, known);
|
|
104
|
+
}
|
|
105
|
+
if (known === undefined) {
|
|
106
|
+
observed.push({ status, rows, contract: { kind: "none" } });
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
observed.push({ status, rows, ...known });
|
|
110
|
+
}
|
|
111
|
+
input.observe(structuredClone(observed));
|
|
112
|
+
};
|
|
113
|
+
const waited = await waitForObservation({
|
|
114
|
+
...(input.timeoutMs === undefined ? {} : { timeoutMs: input.timeoutMs }),
|
|
115
|
+
...(input.signal === undefined ? {} : { signal: input.signal }),
|
|
116
|
+
...(input.predicate === undefined && input.observe === undefined
|
|
117
|
+
? { probe: async () => await readWaitComplete(input.path, input.ids, input.completion, input.signal) }
|
|
118
|
+
: {}),
|
|
119
|
+
observe: async () => await observeWaitRound(input.path, input.ids, input.signal, readers),
|
|
120
|
+
complete: (round) => roundComplete(round, input.completion, input.predicate),
|
|
121
|
+
onObserve: async (round) => await observeRound(round),
|
|
122
|
+
});
|
|
123
|
+
return {
|
|
124
|
+
mode: input.completion,
|
|
125
|
+
reason: waited.reason,
|
|
126
|
+
observations: waited.value.observations.map((observation) => observation.status),
|
|
127
|
+
unobserved: waited.value.unobserved,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
for (const reader of readers?.values() ?? [])
|
|
132
|
+
reader.clear();
|
|
133
|
+
readers?.clear();
|
|
134
|
+
}
|
|
110
135
|
}
|
|
111
136
|
function diagnostic(error) {
|
|
112
137
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -156,8 +156,8 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
156
156
|
}>;
|
|
157
157
|
turnSequence: z.ZodNumber;
|
|
158
158
|
receipt: z.ZodOptional<z.ZodEnum<{
|
|
159
|
-
required: "required";
|
|
160
159
|
unavailable: "unavailable";
|
|
160
|
+
required: "required";
|
|
161
161
|
}>>;
|
|
162
162
|
}, z.core.$strict>, z.ZodTransform<Readonly<{
|
|
163
163
|
turnSequence: number;
|
|
@@ -168,7 +168,7 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
168
168
|
deliveredAt: string;
|
|
169
169
|
route: "live" | "launch";
|
|
170
170
|
turnSequence: number;
|
|
171
|
-
receipt?: "
|
|
171
|
+
receipt?: "unavailable" | "required" | undefined;
|
|
172
172
|
}>>>>;
|
|
173
173
|
}, z.core.$strict>]>, z.ZodObject<{
|
|
174
174
|
kind: z.ZodLiteral<"tool">;
|
|
@@ -363,8 +363,8 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
363
363
|
}>;
|
|
364
364
|
turnSequence: z.ZodNumber;
|
|
365
365
|
receipt: z.ZodOptional<z.ZodEnum<{
|
|
366
|
-
required: "required";
|
|
367
366
|
unavailable: "unavailable";
|
|
367
|
+
required: "required";
|
|
368
368
|
}>>;
|
|
369
369
|
}, z.core.$strict>, z.ZodTransform<Readonly<{
|
|
370
370
|
turnSequence: number;
|
|
@@ -375,7 +375,7 @@ export declare const akumaStatusSchema: z.ZodObject<{
|
|
|
375
375
|
deliveredAt: string;
|
|
376
376
|
route: "live" | "launch";
|
|
377
377
|
turnSequence: number;
|
|
378
|
-
receipt?: "
|
|
378
|
+
receipt?: "unavailable" | "required" | undefined;
|
|
379
379
|
}>>>>;
|
|
380
380
|
}, z.core.$strict>]>, z.ZodObject<{
|
|
381
381
|
kind: z.ZodLiteral<"tool">;
|
|
@@ -450,6 +450,8 @@ export declare function listAkumaArchetypes(path: WorldRoot, input?: Readonly<{
|
|
|
450
450
|
* observed extent. World Alias context is attached by the upper composition.
|
|
451
451
|
*/
|
|
452
452
|
export declare function readAkumaRoster(path: WorldRoot, input?: AkumaListInput): Promise<AkumaList>;
|
|
453
|
+
/** Internal recent observation with an aperture already validated by the composition. */
|
|
454
|
+
export declare function observeAkumaRoster(path: WorldRoot, limit: number, selected?: string): Promise<AkumaList>;
|
|
453
455
|
/** The complete native roster for callers whose semantics require a frozen set. */
|
|
454
456
|
export declare function readAkumaCompleteRoster(path: WorldRoot, input?: Readonly<{
|
|
455
457
|
archetype?: string;
|
package/build/src/akuma/akuma.js
CHANGED
|
@@ -118,6 +118,10 @@ function rosterArchetype(input, allowLimit) {
|
|
|
118
118
|
export async function readAkumaRoster(path, input = {}) {
|
|
119
119
|
const selected = rosterArchetype(input, true);
|
|
120
120
|
const limit = boundedListLimit(input.limit);
|
|
121
|
+
return observeAkumaRoster(path, limit, selected);
|
|
122
|
+
}
|
|
123
|
+
/** Internal recent observation with an aperture already validated by the composition. */
|
|
124
|
+
export async function observeAkumaRoster(path, limit, selected) {
|
|
121
125
|
const observedAt = new Date().toISOString();
|
|
122
126
|
const known = await knownAkuma(path, selected);
|
|
123
127
|
const candidatesWithBounds = await boundedMap(known.rows, async (row) => ({
|
|
@@ -93,6 +93,7 @@ type BodyRuntime = Readonly<{
|
|
|
93
93
|
world: WorldRoot;
|
|
94
94
|
externalCommands: Readonly<Record<string, ErasedRequestCommand>>;
|
|
95
95
|
}>;
|
|
96
|
+
export declare function recordPluginDiagnostic(paths: AkumaPaths, occurrence: string, error: unknown): Promise<void>;
|
|
96
97
|
export declare function bodyProcessInput(launch: BodyLaunch, bodyModuleUrl?: string): Promise<{
|
|
97
98
|
argv: string[];
|
|
98
99
|
cwd: string;
|