@astrosheep/keiyaku 4.6.7 → 4.6.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -2
- package/build/plugins/pi/keiyaku.ts +0 -5
- package/build/src/akuma/akuma-call.d.ts +2 -0
- package/build/src/akuma/akuma-call.js +8 -2
- package/build/src/akuma/akuma-instance.d.ts +12 -1
- package/build/src/akuma/akuma-instance.js +27 -7
- package/build/src/akuma/akuma-observe.js +2 -0
- package/build/src/akuma/akuma-owner.d.ts +3 -0
- package/build/src/akuma/akuma-owner.js +4 -0
- package/build/src/akuma/akuma.d.ts +35 -5
- package/build/src/akuma/akuma.js +8 -10
- package/build/src/akuma/archetype.d.ts +7 -15
- package/build/src/akuma/archetype.js +36 -35
- package/build/src/akuma/body.d.ts +5 -3
- package/build/src/akuma/body.js +29 -7
- package/build/src/akuma/call-request.d.ts +18 -10
- package/build/src/akuma/call-request.js +10 -3
- package/build/src/akuma/caller.d.ts +39 -0
- package/build/src/akuma/caller.js +36 -0
- package/build/src/akuma/dispatch-association.d.ts +0 -1
- package/build/src/akuma/dispatch-association.js +0 -3
- package/build/src/akuma/heart/facts.d.ts +16 -12
- package/build/src/akuma/heart/facts.js +8 -0
- package/build/src/akuma/heart/index.d.ts +2 -7
- package/build/src/akuma/heart/index.js +3 -17
- package/build/src/akuma/heart/rows.d.ts +3 -3
- package/build/src/akuma/heart/soul.d.ts +1 -1
- package/build/src/akuma/heart/soul.js +5 -24
- package/build/src/akuma/heart/storage.d.ts +5 -0
- package/build/src/akuma/heart/storage.js +7 -3
- package/build/src/akuma/identity.d.ts +0 -1
- package/build/src/akuma/identity.js +2 -5
- package/build/src/akuma/index.d.ts +5 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/nuke.js +6 -28
- package/build/src/akuma/projection.d.ts +0 -11
- package/build/src/akuma/provider-recipe.d.ts +7 -6
- package/build/src/akuma/provider-recipe.js +1 -1
- package/build/src/akuma/provider.d.ts +6 -10
- package/build/src/akuma/provider.js +6 -7
- package/build/src/akuma/providers/acp/events.js +5 -18
- package/build/src/akuma/providers/acp/index.js +2 -3
- package/build/src/akuma/providers/claude/events.js +35 -60
- package/build/src/akuma/providers/claude/index.d.ts +2 -2
- package/build/src/akuma/providers/claude/index.js +2 -3
- package/build/src/akuma/providers/codex-app-server/index.js +2 -2
- package/build/src/akuma/providers/decode.d.ts +25 -0
- package/build/src/akuma/providers/decode.js +44 -0
- package/build/src/akuma/providers/execution-environment.d.ts +2 -1
- package/build/src/akuma/providers/execution-environment.js +3 -0
- package/build/src/akuma/providers/grok-build/index.js +6 -22
- package/build/src/akuma/providers/index.js +2 -0
- package/build/src/akuma/providers/lifecycle.d.ts +9 -0
- package/build/src/akuma/providers/lifecycle.js +10 -0
- package/build/src/akuma/providers/opencode-sdk/events.js +1 -14
- package/build/src/akuma/providers/opencode-sdk/index.js +10 -17
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -3
- package/build/src/akuma/providers/paseo/events.d.ts +25 -0
- package/build/src/akuma/providers/paseo/events.js +157 -0
- package/build/src/akuma/providers/paseo/index.d.ts +9 -0
- package/build/src/akuma/providers/paseo/index.js +353 -0
- package/build/src/akuma/providers/pi/events.js +5 -15
- package/build/src/akuma/publication.d.ts +2 -0
- package/build/src/akuma/publication.js +5 -0
- package/build/src/akuma/request-lifecycle.d.ts +3 -0
- package/build/src/akuma/request-lifecycle.js +25 -4
- package/build/src/akuma/requests.d.ts +3 -1
- package/build/src/akuma/requests.js +32 -0
- package/build/src/akuma/selection-observation.d.ts +72 -2
- package/build/src/akuma/selection-observation.js +0 -6
- package/build/src/akuma/turn-drive.js +2 -5
- package/build/src/cli/akuma-caller.d.ts +3 -0
- package/build/src/cli/akuma-caller.js +21 -0
- package/build/src/cli/commands/akuma-grammar.js +7 -12
- package/build/src/cli/commands/akuma.js +12 -4
- package/build/src/cli/commands/contract-grammar.d.ts +2 -1
- package/build/src/cli/commands/contract-grammar.js +13 -15
- package/build/src/cli/commands/contract-help.d.ts +2 -1
- package/build/src/cli/commands/contract-help.js +31 -1
- package/build/src/cli/commands/contract.js +24 -53
- package/build/src/cli/commands/task.js +18 -35
- package/build/src/cli/parse.d.ts +2 -2
- package/build/src/cli/render/catalog.d.ts +2 -5
- package/build/src/cli/render/contract-history.js +3 -6
- package/build/src/cli/render/contract.js +15 -50
- package/build/src/cli/render/receipt.js +3 -10
- package/build/src/cli/render/task.d.ts +4 -6
- package/build/src/cli/render/task.js +9 -26
- package/build/src/cli/runtime.d.ts +1 -1
- package/build/src/cli/runtime.js +11 -17
- package/build/src/cli/selectors.d.ts +3 -6
- package/build/src/cli/selectors.js +22 -53
- package/build/src/dispatch/index.d.ts +3 -3
- package/build/src/dispatch/index.js +1 -2
- package/build/src/git/observe.d.ts +6 -2
- package/build/src/git/observe.js +6 -2
- package/build/src/index.d.ts +6 -6
- package/build/src/index.js +2 -2
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/read.js +21 -6
- package/build/src/library/address.js +2 -4
- package/build/src/library/akuma-creation.d.ts +5 -1
- package/build/src/library/akuma-creation.js +27 -47
- package/build/src/library/akumas.d.ts +5 -4
- package/build/src/library/akumas.js +13 -9
- package/build/src/library/bind.d.ts +14 -14
- package/build/src/library/bind.js +11 -7
- package/build/src/library/contract-address.d.ts +9 -0
- package/build/src/library/contract-address.js +71 -0
- package/build/src/library/contract-composition.d.ts +4 -7
- package/build/src/library/contract-composition.js +6 -18
- package/build/src/library/contract-creation.d.ts +3 -5
- package/build/src/library/contract-creation.js +19 -17
- package/build/src/library/contract-execution.js +18 -23
- package/build/src/library/contract-outcomes.d.ts +2 -14
- package/build/src/library/contract-outcomes.js +2 -13
- package/build/src/library/contract-types.d.ts +36 -2
- package/build/src/library/delivery.d.ts +0 -2
- package/build/src/library/delivery.js +2 -5
- package/build/src/library/keiyaku.d.ts +0 -5
- package/build/src/library/keiyaku.js +6 -12
- package/build/src/library/outcome.d.ts +500 -499
- package/build/src/library/outcome.js +10 -0
- package/build/src/library/reconcile.js +8 -16
- package/build/src/library/refusal.d.ts +2 -2
- package/build/src/library/repo.d.ts +3 -2
- package/build/src/library/repo.js +10 -5
- package/build/src/library/selection.d.ts +4 -4
- package/build/src/library/selection.js +12 -12
- package/build/src/plugin/akuma-signals.d.ts +2 -0
- package/build/src/plugin/akuma-signals.js +4 -0
- package/build/src/plugin/public.d.ts +27 -2
- package/build/src/plugin/runtime.js +2 -2
- package/build/src/protocol/amend.js +3 -2
- package/build/src/protocol/attempt.js +3 -8
- package/build/src/protocol/bind.d.ts +2 -2
- package/build/src/protocol/bind.js +1 -1
- package/build/src/protocol/deliver.js +3 -3
- package/build/src/protocol/operations.d.ts +1 -3
- package/build/src/protocol/operations.js +0 -8
- package/build/src/protocol/outcome.d.ts +1 -2
- package/build/src/protocol/outcome.js +1 -13
- package/build/src/protocol/placement.js +3 -10
- package/build/src/protocol/read/status.js +31 -70
- package/build/src/protocol/reintegrate.js +3 -10
- package/build/src/protocol/review.js +3 -3
- package/build/src/protocol/run.d.ts +5 -1
- package/build/src/protocol/run.js +3 -3
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/package.json +8 -4
- package/plugins/pi/keiyaku.ts +57 -0
- package/skills/keiyaku/SKILL.md +44 -0
- package/skills/keiyaku-akuma/SKILL.md +130 -0
- package/skills/keiyaku-akuma/references/automation.md +269 -0
- package/skills/keiyaku-babysit/SKILL.md +65 -0
- package/skills/keiyaku-bind/SKILL.md +216 -0
- package/skills/keiyaku-bind/agents/openai.yaml +4 -0
- package/skills/keiyaku-task/SKILL.md +104 -0
- package/skills/keiyaku-workflow/SKILL.md +129 -0
- package/build/src/cli/commands/amend.d.ts +0 -12
- package/build/src/cli/commands/amend.js +0 -10
- package/build/src/cli/commands/bind.d.ts +0 -11
- package/build/src/cli/commands/bind.js +0 -23
- package/build/src/dispatch/association.d.ts +0 -1
- package/build/src/dispatch/association.js +0 -1
|
@@ -156,21 +156,15 @@ async function runRead(input) {
|
|
|
156
156
|
});
|
|
157
157
|
return emit(command.output, result, () => renderTaskList("ls", scope, result, displayContext()), taskExitCode(result));
|
|
158
158
|
}
|
|
159
|
-
case "ready":
|
|
160
|
-
const result = await tasks.ready({
|
|
161
|
-
...readScope(command, current),
|
|
162
|
-
...(value(command, "parent") === undefined ? {} : { parent: value(command, "parent") }),
|
|
163
|
-
...(limit(command) === undefined ? {} : { limit: limit(command) }),
|
|
164
|
-
});
|
|
165
|
-
return emit(command.output, result, () => renderTaskList("ready", scope, result, displayContext()), taskExitCode(result));
|
|
166
|
-
}
|
|
159
|
+
case "ready":
|
|
167
160
|
case "blocked": {
|
|
168
|
-
const
|
|
161
|
+
const action = command.action;
|
|
162
|
+
const result = await tasks[action]({
|
|
169
163
|
...readScope(command, current),
|
|
170
164
|
...(value(command, "parent") === undefined ? {} : { parent: value(command, "parent") }),
|
|
171
165
|
...(limit(command) === undefined ? {} : { limit: limit(command) }),
|
|
172
166
|
});
|
|
173
|
-
return emit(command.output, result, () => renderTaskList(
|
|
167
|
+
return emit(command.output, result, () => renderTaskList(action, scope, result, displayContext()), taskExitCode(result));
|
|
174
168
|
}
|
|
175
169
|
case "query": {
|
|
176
170
|
const result = await tasks.query({
|
|
@@ -233,26 +227,18 @@ function missingWorld(command) {
|
|
|
233
227
|
const result = missingTask(command.positionals[0]);
|
|
234
228
|
return emit(output, result, () => renderTaskUpdate(result, displayContext()), taskExitCode(result));
|
|
235
229
|
}
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
}
|
|
244
|
-
const result = {
|
|
245
|
-
items: command.positionals.map((id) => ({ id: id, outcome: missingTask(id) })),
|
|
246
|
-
};
|
|
247
|
-
return emit(output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
|
|
248
|
-
}
|
|
249
|
-
if (command.action === "done" || command.action === "drop") {
|
|
250
|
-
const result = {
|
|
251
|
-
items: command.positionals.map((id) => ({ id: id, outcome: missingTask(id) })),
|
|
252
|
-
};
|
|
253
|
-
return emit(output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
|
|
230
|
+
const singleLifecycle = ["start", "stop", "hold", "resume"].includes(command.action);
|
|
231
|
+
const batchLifecycle = ["done", "drop"].includes(command.action);
|
|
232
|
+
if (!singleLifecycle && !batchLifecycle)
|
|
233
|
+
throw new Error(`task action has no missing-world answer: ${command.action}`);
|
|
234
|
+
if (singleLifecycle && command.positionals.length === 1) {
|
|
235
|
+
const result = missingTask(command.positionals[0]);
|
|
236
|
+
return emit(output, result, () => renderTaskMutation(command.action, result, displayContext()), taskExitCode(result));
|
|
254
237
|
}
|
|
255
|
-
|
|
238
|
+
const result = {
|
|
239
|
+
items: command.positionals.map((id) => ({ id: id, outcome: missingTask(id) })),
|
|
240
|
+
};
|
|
241
|
+
return emit(output, result, () => renderTaskLifecycle(command.action, result, displayContext()), taskExitCode(result));
|
|
256
242
|
}
|
|
257
243
|
/**
|
|
258
244
|
* One compose execution outcome: JSON keeps the untouched native value, while an incomplete text
|
|
@@ -284,7 +270,7 @@ async function runBatchLifecycle(tasks, command, verb) {
|
|
|
284
270
|
return emit(command.output, result, () => renderTaskLifecycle(verb, result, displayContext()), taskExitCode(result));
|
|
285
271
|
}
|
|
286
272
|
async function runMutation(input) {
|
|
287
|
-
const { tasks, command, current, stdin,
|
|
273
|
+
const { tasks, command, current, stdin, composeNamespace } = input;
|
|
288
274
|
if (isWorldObservationAction(command) || command.action === "tree")
|
|
289
275
|
return await runRead(input);
|
|
290
276
|
switch (command.action) {
|
|
@@ -326,7 +312,7 @@ async function runMutation(input) {
|
|
|
326
312
|
}
|
|
327
313
|
case "compose": {
|
|
328
314
|
const result = await tasks.compose({
|
|
329
|
-
markdown:
|
|
315
|
+
markdown: stdin ?? "",
|
|
330
316
|
namespace: composeNamespace ?? current ?? [],
|
|
331
317
|
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
332
318
|
...(command.flags.plan === true ? { plan: true } : {}),
|
|
@@ -377,8 +363,7 @@ export async function runTaskCommand(command, coordinates, runtime) {
|
|
|
377
363
|
if (stdinDiagnostic !== undefined && isBlankInput(stdin ?? ""))
|
|
378
364
|
throw new CliUsageError(stdinDiagnostic);
|
|
379
365
|
const planOnly = command.action === "compose" && command.flags.plan === true;
|
|
380
|
-
const
|
|
381
|
-
const composition = composeMarkdown === undefined ? undefined : taskCompositionNamespaceHeader(composeMarkdown);
|
|
366
|
+
const composition = command.action === "compose" && stdin !== undefined ? taskCompositionNamespaceHeader(stdin) : undefined;
|
|
382
367
|
const explicitNamespace = command.action === "add"
|
|
383
368
|
? namespace(value(command, "namespace"))
|
|
384
369
|
: command.action === "compose" && composition?.specified
|
|
@@ -414,12 +399,10 @@ export async function runTaskCommand(command, coordinates, runtime) {
|
|
|
414
399
|
return await runMutation({
|
|
415
400
|
tasks,
|
|
416
401
|
command,
|
|
417
|
-
runtime,
|
|
418
402
|
context: coordinates.taskContext,
|
|
419
403
|
...(actor === undefined ? {} : { actor }),
|
|
420
404
|
...(current === undefined ? {} : { current }),
|
|
421
405
|
...(stdin === undefined ? {} : { stdin }),
|
|
422
|
-
...(composeMarkdown === undefined ? {} : { composeMarkdown }),
|
|
423
406
|
...(explicitNamespace === undefined ? {} : { composeNamespace: explicitNamespace }),
|
|
424
407
|
});
|
|
425
408
|
}
|
package/build/src/cli/parse.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type ParsedTaskCommand, type TaskAction } from "./commands/task-grammar.js";
|
|
2
2
|
import { type AkumaAction, type ParsedAkumaCommand } from "./commands/akuma-grammar.js";
|
|
3
3
|
import { type ParsedInstallCommand } from "./commands/install.js";
|
|
4
|
-
import { type
|
|
4
|
+
import { type ParsedContractCommand } from "./commands/contract-grammar.js";
|
|
5
5
|
import { type ContractCommand as Command } from "./commands/contract-help.js";
|
|
6
6
|
import { type CliUsageGuide } from "./usage.js";
|
|
7
7
|
export { CliUsageError } from "./usage.js";
|
|
@@ -10,7 +10,7 @@ export type { Command };
|
|
|
10
10
|
export declare function renderRootHelp(columns?: number): string;
|
|
11
11
|
export declare function usageGuideForCommand(command: ParsedCommand): CliUsageGuide;
|
|
12
12
|
export declare function renderHelp(coordinate: CliHelpCoordinate, columns?: number): string;
|
|
13
|
-
export type ParsedCommand =
|
|
13
|
+
export type ParsedCommand = ParsedContractCommand | ParsedInstallCommand | ParsedAkumaCommand | ParsedTaskCommand;
|
|
14
14
|
type CliHelpCoordinate = Readonly<{
|
|
15
15
|
kind: "root";
|
|
16
16
|
}> | Readonly<{
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import type { AkumaList } from "../../akuma/akuma.js";
|
|
2
|
-
import type {
|
|
2
|
+
import type { ArchetypeCatalog } from "../../index.js";
|
|
3
3
|
import type { ContractList } from "../../library/contract-types.js";
|
|
4
4
|
import type { TaskPage, TaskRow } from "../../task/index.js";
|
|
5
5
|
export declare function renderAkumaCatalogue(list: AkumaList, archetype: string | null): string;
|
|
6
6
|
export declare function renderContractCatalogue(list: ContractList): string;
|
|
7
|
-
export declare function renderArchetypeCatalogue(list:
|
|
8
|
-
rows: readonly ArchetypeCatalogRow[];
|
|
9
|
-
hasMore: boolean;
|
|
10
|
-
}>): string;
|
|
7
|
+
export declare function renderArchetypeCatalogue(list: ArchetypeCatalog): string;
|
|
11
8
|
export declare function renderTaskCatalogue(list: TaskPage<TaskRow>, namespace: readonly string[]): string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { parseAkuId } from "../../akuma/identity.js";
|
|
2
|
-
import { lifecycleWord, shortGitId } from "./contract-observation.js";
|
|
2
|
+
import { gateDisplayName, lifecycleWord, shortGitId } from "./contract-observation.js";
|
|
3
3
|
import { receiptPayload } from "./receipt.js";
|
|
4
4
|
import { renderOpaqueBlock, DEFAULT_CLI_COLUMNS } from "./terminal.js";
|
|
5
5
|
function journalCount(events, source) {
|
|
@@ -120,15 +120,12 @@ function eventAt(event) {
|
|
|
120
120
|
function eventKind(event) {
|
|
121
121
|
return event.source === "journal" ? event.fact.kind : "dispatch";
|
|
122
122
|
}
|
|
123
|
-
function gateNoun(gate) {
|
|
124
|
-
return gate === "reviewed" ? "review" : gate === "verified" ? "verification" : gate;
|
|
125
|
-
}
|
|
126
123
|
function mark(verdict) {
|
|
127
124
|
return verdict === "satisfied" ? "✓" : "×";
|
|
128
125
|
}
|
|
129
126
|
function bindLine(bind, dispatch) {
|
|
130
127
|
const target = bind.data.coordinates.target?.replace(/^refs\/heads\//u, "") ?? "targetless";
|
|
131
|
-
const gates = bind.data.terms.gates.map(
|
|
128
|
+
const gates = bind.data.terms.gates.map(gateDisplayName);
|
|
132
129
|
const gateFact = gates.length === 0 ? "" : ` · ${gates.length === 1 ? "gate" : "gates"} ${gates.join(" · ")}`;
|
|
133
130
|
let alias = "";
|
|
134
131
|
if (dispatch?.source === "dispatch") {
|
|
@@ -190,7 +187,7 @@ function skeletonBeatLines(beat, history) {
|
|
|
190
187
|
];
|
|
191
188
|
}
|
|
192
189
|
case "attestation":
|
|
193
|
-
return [`${clock(first)} ${mark(fact.data.verdict)} ${
|
|
190
|
+
return [`${clock(first)} ${mark(fact.data.verdict)} ${gateDisplayName(fact.data.gate)}${evidenceSuffix()}`];
|
|
194
191
|
case "amend": {
|
|
195
192
|
const changed = [fact.data.gates.length > 0 ? "gates" : "", fact.data.after.length > 0 ? "after" : ""]
|
|
196
193
|
.filter((value) => value.length > 0)
|
|
@@ -40,26 +40,7 @@ function checkoutBehindRows(path, target, columns) {
|
|
|
40
40
|
}
|
|
41
41
|
function lagRows(lag, columns) {
|
|
42
42
|
const lines = [];
|
|
43
|
-
if (lag.kind === "worktree-
|
|
44
|
-
receiptRow(lines, "!", "lag", [{ text: "worktree retained" }, { text: lag.path, opaque: true }], columns);
|
|
45
|
-
}
|
|
46
|
-
else if (lag.kind === "worktree-follow-retained") {
|
|
47
|
-
receiptRow(lines, "!", "lag", [
|
|
48
|
-
{ text: "worktree follow retained" },
|
|
49
|
-
{ text: "·" },
|
|
50
|
-
{ text: lag.reason.replaceAll("-", " ") },
|
|
51
|
-
{ text: "·" },
|
|
52
|
-
{ text: lag.path, opaque: true },
|
|
53
|
-
], columns);
|
|
54
|
-
}
|
|
55
|
-
else if (lag.kind === "unsealed-bytes") {
|
|
56
|
-
receiptRow(lines, "!", "lag", [{ text: "unsealed bytes" }, { text: lag.path, opaque: true }], columns);
|
|
57
|
-
}
|
|
58
|
-
else if (lag.kind === "target-checkout-retained") {
|
|
59
|
-
pushBlock(lines, checkoutBehindRows(lag.path, lag.target, columns));
|
|
60
|
-
receiptPayload(lines, "reason", lag.diagnostic);
|
|
61
|
-
}
|
|
62
|
-
else if (lag.kind === "worktree-hook-failed") {
|
|
43
|
+
if (lag.kind === "worktree-hook-failed") {
|
|
63
44
|
receiptRow(lines, "!", "lag", [
|
|
64
45
|
{
|
|
65
46
|
text: `worktree-hook-failed ${lag.phase} ${lag.path} command ${lag.command} name ${lag.name} ${hookFailureSummary(lag.failure)}`,
|
|
@@ -153,24 +134,12 @@ function overlapRows(overlaps, color) {
|
|
|
153
134
|
}
|
|
154
135
|
return lines;
|
|
155
136
|
}
|
|
156
|
-
function pushBlock(lines, block) {
|
|
157
|
-
if (block.length === 0)
|
|
158
|
-
return;
|
|
159
|
-
lines.push(...block);
|
|
160
|
-
}
|
|
161
|
-
function acceptedRecord(result, columns) {
|
|
162
|
-
const record = [];
|
|
163
|
-
const recoverySnapshot = effectRecoverySnapshot(result.effects);
|
|
164
|
-
if (recoverySnapshot !== undefined)
|
|
165
|
-
receiptRow(record, " ", "recovery snapshot", [{ text: recoverySnapshot, opaque: true }], columns);
|
|
166
|
-
return record;
|
|
167
|
-
}
|
|
168
137
|
function acceptedLagRows(result, columns) {
|
|
169
138
|
const obligations = [];
|
|
170
139
|
// A checkout this invocation's own follow could not carry is loud; the same arm's reconciliation lag
|
|
171
140
|
// is pre-existing residue and stays in the typed result only.
|
|
172
141
|
for (const checkout of effectRetainedCheckouts(result.effects) ?? []) {
|
|
173
|
-
|
|
142
|
+
obligations.push(...checkoutBehindRows(checkout.path, checkout.target, columns));
|
|
174
143
|
}
|
|
175
144
|
for (const { contract, lag } of effectLags(result.effects)) {
|
|
176
145
|
if (lag.kind === "worktree-retained" ||
|
|
@@ -180,29 +149,34 @@ function acceptedLagRows(result, columns) {
|
|
|
180
149
|
continue;
|
|
181
150
|
if (contract !== result.contract)
|
|
182
151
|
receiptRow(obligations, "!", "lag owner", [{ text: contract, opaque: true }], columns);
|
|
183
|
-
|
|
152
|
+
obligations.push(...lagRows(lag, columns));
|
|
184
153
|
}
|
|
185
154
|
for (const { contract, lag } of effectSettlementLags(result.effects)) {
|
|
186
155
|
if (contract !== result.contract)
|
|
187
156
|
receiptRow(obligations, "!", "settlement owner", [{ text: contract, opaque: true }], columns);
|
|
188
|
-
|
|
157
|
+
obligations.push(...settlementLagRows(lag, columns));
|
|
189
158
|
}
|
|
190
|
-
|
|
191
|
-
|
|
159
|
+
obligations.push(...executionCleanupLines(effectCleanup(result.effects), columns, result.contract));
|
|
160
|
+
obligations.push(...executionStopLines(effectExecutionStops(result.effects), columns));
|
|
192
161
|
return obligations;
|
|
193
162
|
}
|
|
194
163
|
function acceptedDeviations(result, columns, color) {
|
|
195
164
|
const deviations = [];
|
|
196
165
|
if (result.value.overlaps !== undefined)
|
|
197
|
-
|
|
166
|
+
deviations.push(...overlapRows(result.value.overlaps, color));
|
|
198
167
|
if (result.value.overlapFailure !== undefined) {
|
|
199
168
|
receiptRow(deviations, "!", "overlap", [{ text: "unavailable" }], columns);
|
|
200
169
|
receiptPayload(deviations, "reason", result.value.overlapFailure);
|
|
201
170
|
}
|
|
202
171
|
return deviations;
|
|
203
172
|
}
|
|
173
|
+
/** Evidence handles stay in JSON and history; ordinary receipt text carries only outstanding obligations. */
|
|
204
174
|
function recordBlock(result, columns) {
|
|
205
|
-
const rows = [
|
|
175
|
+
const rows = [];
|
|
176
|
+
const recoverySnapshot = effectRecoverySnapshot(result.effects);
|
|
177
|
+
if (recoverySnapshot !== undefined)
|
|
178
|
+
receiptRow(rows, " ", "recovery snapshot", [{ text: recoverySnapshot, opaque: true }], columns);
|
|
179
|
+
rows.push(...acceptedLagRows(result, columns));
|
|
206
180
|
return rows;
|
|
207
181
|
}
|
|
208
182
|
/** A terminal command names the worktree it retired, or the retained worktree it failed to remove. */
|
|
@@ -279,15 +253,6 @@ function completedPlacementLines(result, columns) {
|
|
|
279
253
|
receiptRow(lines, "✓", lifecycleWord("claimed"), [], columns);
|
|
280
254
|
return lines;
|
|
281
255
|
}
|
|
282
|
-
/** Evidence handles stay in JSON and history; ordinary receipt text carries only outstanding obligations. */
|
|
283
|
-
function obligationLines(result, columns) {
|
|
284
|
-
const rows = [];
|
|
285
|
-
const recoverySnapshot = effectRecoverySnapshot(result.effects);
|
|
286
|
-
if (recoverySnapshot !== undefined)
|
|
287
|
-
receiptRow(rows, " ", "recovery snapshot", [{ text: recoverySnapshot, opaque: true }], columns);
|
|
288
|
-
rows.push(...acceptedLagRows(result, columns));
|
|
289
|
-
return rows;
|
|
290
|
-
}
|
|
291
256
|
function movementLines(result, columns) {
|
|
292
257
|
const count = result.facts.filter((fact) => fact.kind === "reintegrated").length;
|
|
293
258
|
if (count === 0)
|
|
@@ -403,7 +368,7 @@ function renderAcceptedDeliver(result, columns) {
|
|
|
403
368
|
lines.push(...stopLines(verification.stop, columns, result.contract));
|
|
404
369
|
if (!complete && result.value.placement !== undefined)
|
|
405
370
|
lines.push(...stopLines(result.value.placement, columns, result.contract));
|
|
406
|
-
lines.push(...continuationLines(result, columns), ...
|
|
371
|
+
lines.push(...continuationLines(result, columns), ...recordBlock(result, columns), ...worktreeRetirementLines(result, columns), ...gatesAwaitLines(result.value.placement));
|
|
407
372
|
return lines.join("\n");
|
|
408
373
|
}
|
|
409
374
|
function renderAcceptedReview(result, columns) {
|
|
@@ -416,7 +381,7 @@ function renderAcceptedReview(result, columns) {
|
|
|
416
381
|
lines.push(...stopLines(result.value.placement, columns, result.contract));
|
|
417
382
|
}
|
|
418
383
|
lines.push(...continuationLines(result, columns));
|
|
419
|
-
lines.push(...
|
|
384
|
+
lines.push(...recordBlock(result, columns));
|
|
420
385
|
lines.push(...worktreeRetirementLines(result, columns));
|
|
421
386
|
lines.push(...gatesAwaitLines(result.value.placement));
|
|
422
387
|
return lines.join("\n");
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { gateDisplayName } from "./contract-observation.js";
|
|
1
2
|
import { renderRefusalFacts } from "./refusal.js";
|
|
2
3
|
import { DEFAULT_CLI_COLUMNS, displayColumns, orderRefusalFacts, renderOpaqueBlock, safeText, quotedText, } from "./terminal.js";
|
|
3
4
|
export function receiptRow(lines, mark, label, segments, columns) {
|
|
@@ -73,14 +74,6 @@ function prerequisiteRows(stop, columns) {
|
|
|
73
74
|
}
|
|
74
75
|
return lines;
|
|
75
76
|
}
|
|
76
|
-
/** Requirement names speak as plain event nouns; the "gate" class word never prints on a receipt. */
|
|
77
|
-
function eventNoun(gate) {
|
|
78
|
-
if (gate === "reviewed")
|
|
79
|
-
return "review";
|
|
80
|
-
if (gate === "verified")
|
|
81
|
-
return "verification";
|
|
82
|
-
return gate;
|
|
83
|
-
}
|
|
84
77
|
/** Only a recorded unsatisfied verdict alarms; missing and stale requirements fold into the await line. */
|
|
85
78
|
function gateAlarmRows(stop, columns) {
|
|
86
79
|
if (!("refusal" in stop) || stop.refusal?.kind !== "gates-unsatisfied")
|
|
@@ -90,7 +83,7 @@ function gateAlarmRows(stop, columns) {
|
|
|
90
83
|
const { gate, current } = report;
|
|
91
84
|
if (current.kind !== "attested")
|
|
92
85
|
continue;
|
|
93
|
-
receiptRow(lines, "!",
|
|
86
|
+
receiptRow(lines, "!", gateDisplayName(gate), [{ text: `· ${current.verdict}` }, { text: `· at ${current.at}` }], columns);
|
|
94
87
|
if (current.summary !== undefined)
|
|
95
88
|
receiptPayload(lines, " summary", current.summary);
|
|
96
89
|
}
|
|
@@ -106,7 +99,7 @@ export function gatesAwaitLines(placement) {
|
|
|
106
99
|
return [];
|
|
107
100
|
const events = placement.refusal.unmet
|
|
108
101
|
.filter((report) => report.current.kind !== "attested")
|
|
109
|
-
.map((report) =>
|
|
102
|
+
.map((report) => gateDisplayName(report.gate));
|
|
110
103
|
if (events.length === 0)
|
|
111
104
|
return [];
|
|
112
105
|
return [`⧗ awaiting ${events.length > 3 ? `${events.length} gates` : events.join(", ")}`];
|
|
@@ -22,17 +22,15 @@ type TaskFailure = Extract<TaskMutationResult, {
|
|
|
22
22
|
/** Task dispositions and relation states are snake_case facts; people read them as words. */
|
|
23
23
|
export declare function dispositionText(word: string): string;
|
|
24
24
|
export declare function taskFrameHead(view: string, scope: string): string;
|
|
25
|
-
export declare function renderDoctor(report: TaskDoctorReport): string;
|
|
26
|
-
/** One addressed show selection rendered directly from its native answer. */
|
|
27
|
-
export declare function renderTaskShow(result: TaskShowResult, context?: TextRenderContext): string;
|
|
28
|
-
/** One list read rendered from its native answer and the leaf's presentation-only scope. */
|
|
29
25
|
export declare function renderTaskList(action: "ls" | "ready" | "blocked" | "query", scope: TaskListScope, result: TaskListOutcome, context?: TextRenderContext): string;
|
|
26
|
+
export declare function renderTaskShow(result: TaskShowResult, context?: TextRenderContext): string;
|
|
27
|
+
export declare function renderDoctor(report: TaskDoctorReport): string;
|
|
28
|
+
export declare function renderTaskUpdate(result: TaskUpdateResult, context?: TextRenderContext): string;
|
|
29
|
+
export declare function renderTaskCompose(result: TaskCompositionResult, context?: TextRenderContext): string;
|
|
30
30
|
export declare function renderTaskTree(result: TaskDecompositionTree, context?: TextRenderContext): string;
|
|
31
31
|
export declare function renderTaskContext(result: TaskContextResult, context?: TextRenderContext): string;
|
|
32
|
-
export declare function renderTaskCompose(result: TaskCompositionResult, context?: TextRenderContext): string;
|
|
33
32
|
/** One single-Task mutation answer; `verb` is the literal action the leaf invoked. */
|
|
34
33
|
export declare function renderTaskMutation(verb: string, result: TaskMutationResult, context?: TextRenderContext): string;
|
|
35
|
-
export declare function renderTaskUpdate(result: TaskUpdateResult, context?: TextRenderContext): string;
|
|
36
34
|
/** One lifecycle answer: a single mutation or a plural batch, both native shapes. */
|
|
37
35
|
export declare function renderTaskLifecycle(verb: string, result: TaskMutationResult | TaskBatchResult, context?: TextRenderContext): string;
|
|
38
36
|
/** A native refusal the CLI edge raised for one action, through the shared refusal grammar. */
|
|
@@ -33,15 +33,8 @@ function stateEntity(task) {
|
|
|
33
33
|
title: task.title,
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
|
-
const TASK_REFUSAL_WORDS = {
|
|
37
|
-
"task-missing": "task missing",
|
|
38
|
-
"invalid-lifecycle-transition": "invalid lifecycle transition",
|
|
39
|
-
"invalid-namespace-context": "invalid namespace context",
|
|
40
|
-
"relation-owned-by-other": "relation owned by other",
|
|
41
|
-
"invalid-composition": "invalid composition",
|
|
42
|
-
};
|
|
43
36
|
function projectRefusal(refusal) {
|
|
44
|
-
const diagnostic =
|
|
37
|
+
const diagnostic = refusal.kind.replaceAll("-", " ");
|
|
45
38
|
if (refusal.kind === "task-missing")
|
|
46
39
|
return { diagnostic, facts: [`task ${refusal.taskId}`] };
|
|
47
40
|
if (refusal.kind === "invalid-lifecycle-transition") {
|
|
@@ -110,7 +103,8 @@ function renderListRow(item, columns, omitDisposition) {
|
|
|
110
103
|
}
|
|
111
104
|
return lines;
|
|
112
105
|
}
|
|
113
|
-
function
|
|
106
|
+
export function renderTaskList(action, scope, result, context = DEFAULT_CONTEXT) {
|
|
107
|
+
const columns = context.columns;
|
|
114
108
|
if (result.kind !== "accepted")
|
|
115
109
|
return renderFailure(action, result, columns);
|
|
116
110
|
const view = action === "ls" ? "tasks" : action;
|
|
@@ -162,7 +156,8 @@ function renderShowDetail(result, columns) {
|
|
|
162
156
|
receiptPayload(lines, "body", task.body);
|
|
163
157
|
return lines.join("\n");
|
|
164
158
|
}
|
|
165
|
-
function
|
|
159
|
+
export function renderTaskShow(result, context = DEFAULT_CONTEXT) {
|
|
160
|
+
const columns = context.columns;
|
|
166
161
|
if (Array.isArray(result))
|
|
167
162
|
return result.map((detail) => renderShowDetail(detail, columns)).join("\n\n");
|
|
168
163
|
if ("kind" in result)
|
|
@@ -214,7 +209,8 @@ function renderMutation(action, result, columns) {
|
|
|
214
209
|
return renderFailure(action, result, columns);
|
|
215
210
|
return renderAcceptedMutation(action, result.value, columns);
|
|
216
211
|
}
|
|
217
|
-
function
|
|
212
|
+
export function renderTaskUpdate(result, context = DEFAULT_CONTEXT) {
|
|
213
|
+
const columns = context.columns;
|
|
218
214
|
if (result.kind !== "accepted")
|
|
219
215
|
return renderFailure("update", result, columns);
|
|
220
216
|
return renderAcceptedMutation("update", result.value.task, columns, result.value.changedFields);
|
|
@@ -259,7 +255,8 @@ function renderPlan(result) {
|
|
|
259
255
|
}
|
|
260
256
|
return lines.join("\n");
|
|
261
257
|
}
|
|
262
|
-
function
|
|
258
|
+
export function renderTaskCompose(result, context = DEFAULT_CONTEXT) {
|
|
259
|
+
const columns = context.columns;
|
|
263
260
|
if (result.kind === "incomplete")
|
|
264
261
|
return "";
|
|
265
262
|
if (result.kind === "planned")
|
|
@@ -272,14 +269,6 @@ function renderCompose(result, columns) {
|
|
|
272
269
|
...admissionLines(result.admissions),
|
|
273
270
|
].join("\n");
|
|
274
271
|
}
|
|
275
|
-
/** One addressed show selection rendered directly from its native answer. */
|
|
276
|
-
export function renderTaskShow(result, context = DEFAULT_CONTEXT) {
|
|
277
|
-
return renderShow(result, context.columns);
|
|
278
|
-
}
|
|
279
|
-
/** One list read rendered from its native answer and the leaf's presentation-only scope. */
|
|
280
|
-
export function renderTaskList(action, scope, result, context = DEFAULT_CONTEXT) {
|
|
281
|
-
return renderRows(action, scope, result, context.columns);
|
|
282
|
-
}
|
|
283
272
|
export function renderTaskTree(result, context = DEFAULT_CONTEXT) {
|
|
284
273
|
return result.kind === "accepted"
|
|
285
274
|
? treeLines(result.value, context.columns).join("\n")
|
|
@@ -291,16 +280,10 @@ export function renderTaskContext(result, context = DEFAULT_CONTEXT) {
|
|
|
291
280
|
const value = result.value.namespace.length === 0 ? "root" : result.value.namespace.join("/");
|
|
292
281
|
return `context ${value} · ${result.value.source}`;
|
|
293
282
|
}
|
|
294
|
-
export function renderTaskCompose(result, context = DEFAULT_CONTEXT) {
|
|
295
|
-
return renderCompose(result, context.columns);
|
|
296
|
-
}
|
|
297
283
|
/** One single-Task mutation answer; `verb` is the literal action the leaf invoked. */
|
|
298
284
|
export function renderTaskMutation(verb, result, context = DEFAULT_CONTEXT) {
|
|
299
285
|
return renderMutation(verb, result, context.columns);
|
|
300
286
|
}
|
|
301
|
-
export function renderTaskUpdate(result, context = DEFAULT_CONTEXT) {
|
|
302
|
-
return renderUpdate(result, context.columns);
|
|
303
|
-
}
|
|
304
287
|
/** One lifecycle answer: a single mutation or a plural batch, both native shapes. */
|
|
305
288
|
export function renderTaskLifecycle(verb, result, context = DEFAULT_CONTEXT) {
|
|
306
289
|
return "items" in result ? renderBatch(verb, result, context.columns) : renderMutation(verb, result, context.columns);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type LibraryExecution } from "../akuma/requests.js";
|
|
2
|
-
import type
|
|
2
|
+
import { type ActorId } from "../index.js";
|
|
3
3
|
import type { ExecutionObserver } from "../protocol/execution-observation.js";
|
|
4
4
|
import { type ParsedCommand, type ParsedInvocation } from "./parse.js";
|
|
5
5
|
export type ParsedCommandInvocation = Extract<ParsedInvocation, {
|
package/build/src/cli/runtime.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { AkumaNotBornError, AkumaObservationError } from "../akuma/akuma-errors.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { bodyRequestExecution, localExecutionContext } from "../akuma/requests.js";
|
|
2
|
+
import { executionForEnvironment } from "../akuma/requests.js";
|
|
3
|
+
import { AkumaArchetypeError } from "../index.js";
|
|
5
4
|
import { AkumaAddressError, AkumaWorldScopeError } from "../library/address.js";
|
|
6
5
|
import { encodeFailureWire, KeiyakuError } from "../library/outcome.js";
|
|
7
6
|
import { isParsedAkumaCommand, runAkumaCommand } from "./commands/akuma.js";
|
|
@@ -28,11 +27,6 @@ function memoized(reader) {
|
|
|
28
27
|
let value;
|
|
29
28
|
return () => (value ??= reader());
|
|
30
29
|
}
|
|
31
|
-
function executionForEnvironment(environment) {
|
|
32
|
-
return environment[AKUMA_REQUESTS_ENV] === undefined
|
|
33
|
-
? localExecutionContext()
|
|
34
|
-
: bodyRequestExecution({ directory: environment[AKUMA_REQUESTS_ENV] });
|
|
35
|
-
}
|
|
36
30
|
function homeFromEnvironment(environment) {
|
|
37
31
|
const mapped = environment.KEIYAKU_HOME?.trim();
|
|
38
32
|
return mapped === undefined || mapped.length === 0 ? undefined : mapped;
|
|
@@ -175,16 +169,16 @@ export async function runCliCommand(invocation, input = {}) {
|
|
|
175
169
|
const home = homeFromEnvironment(environment);
|
|
176
170
|
const cancellation = cliCancellation(input.signal);
|
|
177
171
|
let progress;
|
|
178
|
-
const runtime = {
|
|
179
|
-
environment,
|
|
180
|
-
execution: executionForEnvironment(environment),
|
|
181
|
-
...(home === undefined ? {} : { home }),
|
|
182
|
-
readStdin: memoized(input.readStdin ?? processStdin),
|
|
183
|
-
signal: cancellation.signal,
|
|
184
|
-
progress: () => (progress ??= writeExecutionProgress()),
|
|
185
|
-
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
186
|
-
};
|
|
187
172
|
try {
|
|
173
|
+
const runtime = {
|
|
174
|
+
environment,
|
|
175
|
+
execution: await executionForEnvironment(environment, cancellation.signal),
|
|
176
|
+
...(home === undefined ? {} : { home }),
|
|
177
|
+
readStdin: memoized(input.readStdin ?? processStdin),
|
|
178
|
+
signal: cancellation.signal,
|
|
179
|
+
progress: () => (progress ??= writeExecutionProgress()),
|
|
180
|
+
...(input.actor === undefined ? {} : { actor: input.actor }),
|
|
181
|
+
};
|
|
188
182
|
if (command.command === "install")
|
|
189
183
|
return await runInstall(command, environment);
|
|
190
184
|
await admitBindInput(command, invocation, runtime, input.cwd ?? process.cwd());
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { type ExecutionContext } from "../akuma/requests.js";
|
|
2
|
-
import
|
|
3
|
-
import type { KanshiReport } from "../kanshi/index.js";
|
|
2
|
+
import { Keiyaku, type ContractId, type Repo } from "../index.js";
|
|
4
3
|
type SelectedContract = Readonly<{
|
|
5
4
|
id: ContractId;
|
|
6
5
|
contract: Keiyaku;
|
|
7
6
|
}>;
|
|
8
7
|
export declare function contractFromInput(repo: Repo, value: string, execution?: ExecutionContext): SelectedContract;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export declare function resolveContractId(repo: Repo, selector: string | undefined, scope: string): Promise<ContractId>;
|
|
8
|
+
/** Adapt public Contract resolution evidence to the existing CLI usage diagnostics. */
|
|
9
|
+
export declare function resolveContractId(repo: Repo, selector: string | undefined, cwd: string): Promise<ContractId>;
|
|
12
10
|
export declare function canonicalContractSelector(selector: string): ContractId;
|
|
13
|
-
export declare function resolveKanshiContract(report: KanshiReport, selector: string): string;
|
|
14
11
|
export {};
|
|
@@ -1,76 +1,45 @@
|
|
|
1
|
-
import { resolve } from "node:path";
|
|
2
1
|
import { localExecutionContext } from "../akuma/requests.js";
|
|
3
2
|
import { identitySegments } from "../identity/coordinates.js";
|
|
3
|
+
import { Keiyaku } from "../index.js";
|
|
4
4
|
import { composeContractLibrary } from "../library/contract-composition.js";
|
|
5
5
|
import { createKeiyakuHandle } from "../library/keiyaku.js";
|
|
6
6
|
import { CliUsageError } from "./parse.js";
|
|
7
|
-
function selectorError(message) {
|
|
8
|
-
throw new CliUsageError(message);
|
|
9
|
-
}
|
|
10
|
-
function activeManagedCandidates(rows) {
|
|
11
|
-
return rows.flatMap((contract) => {
|
|
12
|
-
if (contract.disposition !== "active" || contract.workspace !== "worktree" || contract.worktreePath === null)
|
|
13
|
-
return [];
|
|
14
|
-
return [{ id: contract.id, worktreePath: contract.worktreePath }];
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
7
|
export function contractFromInput(repo, value, execution = localExecutionContext()) {
|
|
18
8
|
try {
|
|
19
9
|
const id = value;
|
|
20
10
|
return { id, contract: composeContractLibrary(execution, createKeiyakuHandle).select({ repo, id }) };
|
|
21
11
|
}
|
|
22
12
|
catch (error) {
|
|
23
|
-
|
|
13
|
+
throw new CliUsageError(error instanceof Error ? error.message : String(error));
|
|
24
14
|
}
|
|
25
15
|
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
16
|
+
/** Adapt public Contract resolution evidence to the existing CLI usage diagnostics. */
|
|
17
|
+
export async function resolveContractId(repo, selector, cwd) {
|
|
18
|
+
const result = await Keiyaku.with().resolve({ repo, ...(selector === undefined ? {} : { selector }), cwd });
|
|
19
|
+
if (result.kind === "resolved")
|
|
20
|
+
return result.id;
|
|
21
|
+
const refusal = result.refusal;
|
|
22
|
+
switch (refusal.kind) {
|
|
23
|
+
case "invalid-selector":
|
|
24
|
+
throw new CliUsageError(refusal.diagnostic);
|
|
25
|
+
case "redundant-short-selector":
|
|
26
|
+
throw new CliUsageError(`redundant short contract selector: ${refusal.selector}`);
|
|
27
|
+
case "unknown-short-selector":
|
|
28
|
+
throw new CliUsageError(`unknown contract selector: ${refusal.selector}`);
|
|
29
|
+
case "ambiguous-selector":
|
|
30
|
+
throw new CliUsageError("selector" in refusal
|
|
31
|
+
? `ambiguous contract selector: ${refusal.selector}`
|
|
32
|
+
: "ambiguous managed worktree contract selector");
|
|
33
|
+
case "no-contextual-match":
|
|
34
|
+
throw new CliUsageError("an explicit full or @ contract selector is required outside a managed worktree");
|
|
41
35
|
}
|
|
42
|
-
if (candidates.length !== 1)
|
|
43
|
-
selectorError("ambiguous managed worktree contract selector");
|
|
44
|
-
return candidates[0].id;
|
|
45
|
-
}
|
|
46
|
-
export function resolveContextualContract(board, selector, scope) {
|
|
47
|
-
if (selector === undefined)
|
|
48
|
-
return resolveOmittedContract(board, scope);
|
|
49
|
-
if (selector.startsWith("@"))
|
|
50
|
-
return resolveShortContract(board.rows, selector);
|
|
51
|
-
return selectorError(`contract selector must be kei/<contract-segment> or @<contract-segment>: ${selector}`);
|
|
52
|
-
}
|
|
53
|
-
/** Resolve one explicit, short, or worktree-contextual selector to its Contract id. */
|
|
54
|
-
export async function resolveContractId(repo, selector, scope) {
|
|
55
|
-
if (selector !== undefined && !selector.startsWith("@"))
|
|
56
|
-
return contractFromInput(repo, selector).id;
|
|
57
|
-
const { listKeiyaku } = await import("../library/contract-composition.js");
|
|
58
|
-
return resolveContextualContract(await listKeiyaku({ repo }), selector, scope);
|
|
59
36
|
}
|
|
60
37
|
export function canonicalContractSelector(selector) {
|
|
61
38
|
try {
|
|
62
39
|
identitySegments({ family: "kei", value: selector });
|
|
63
40
|
}
|
|
64
41
|
catch {
|
|
65
|
-
|
|
42
|
+
throw new CliUsageError(`contract selector must use kei/: ${selector}`);
|
|
66
43
|
}
|
|
67
44
|
return selector;
|
|
68
45
|
}
|
|
69
|
-
export function resolveKanshiContract(report, selector) {
|
|
70
|
-
if (report.contracts.kind !== "present") {
|
|
71
|
-
return selectorError(`cannot select a contract while the Contract world is ${report.contracts.kind}`);
|
|
72
|
-
}
|
|
73
|
-
if (selector.startsWith("@"))
|
|
74
|
-
return resolveShortContract(report.contracts.value.rows, selector);
|
|
75
|
-
return canonicalContractSelector(selector);
|
|
76
|
-
}
|