@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
|
@@ -3,6 +3,30 @@ import { type AkumaStatus } from "./akuma.js";
|
|
|
3
3
|
declare const akumaObservationSchema: z.ZodObject<{
|
|
4
4
|
status: z.ZodObject<{
|
|
5
5
|
id: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
6
|
+
birth: z.ZodObject<{
|
|
7
|
+
origin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
8
|
+
kind: z.ZodLiteral<"direct">;
|
|
9
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
10
|
+
kind: z.ZodLiteral<"request">;
|
|
11
|
+
parent: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
12
|
+
requestId: z.ZodString;
|
|
13
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
14
|
+
kind: z.ZodLiteral<"fork">;
|
|
15
|
+
parent: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
16
|
+
at: z.ZodString;
|
|
17
|
+
}, z.core.$strip>], "kind">;
|
|
18
|
+
caller: z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
19
|
+
kind: z.ZodLiteral<"akuma">;
|
|
20
|
+
world: z.ZodCustom<import("../world.js").WorldRoot, import("../world.js").WorldRoot>;
|
|
21
|
+
akuId: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
22
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
23
|
+
kind: z.ZodLiteral<"external">;
|
|
24
|
+
integration: z.ZodString;
|
|
25
|
+
id: z.ZodString;
|
|
26
|
+
}, z.core.$strict>], "kind">, z.ZodObject<{
|
|
27
|
+
kind: z.ZodLiteral<"unknown">;
|
|
28
|
+
}, z.core.$strict>]>;
|
|
29
|
+
}, z.core.$strict>;
|
|
6
30
|
life: z.ZodEnum<{
|
|
7
31
|
killed: "killed";
|
|
8
32
|
hung: "hung";
|
|
@@ -467,6 +491,30 @@ declare const akumaWaitResultSchema: z.ZodObject<{
|
|
|
467
491
|
observations: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
468
492
|
status: z.ZodObject<{
|
|
469
493
|
id: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
494
|
+
birth: z.ZodObject<{
|
|
495
|
+
origin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
496
|
+
kind: z.ZodLiteral<"direct">;
|
|
497
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
498
|
+
kind: z.ZodLiteral<"request">;
|
|
499
|
+
parent: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
500
|
+
requestId: z.ZodString;
|
|
501
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
502
|
+
kind: z.ZodLiteral<"fork">;
|
|
503
|
+
parent: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
504
|
+
at: z.ZodString;
|
|
505
|
+
}, z.core.$strip>], "kind">;
|
|
506
|
+
caller: z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
507
|
+
kind: z.ZodLiteral<"akuma">;
|
|
508
|
+
world: z.ZodCustom<import("../world.js").WorldRoot, import("../world.js").WorldRoot>;
|
|
509
|
+
akuId: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
510
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
511
|
+
kind: z.ZodLiteral<"external">;
|
|
512
|
+
integration: z.ZodString;
|
|
513
|
+
id: z.ZodString;
|
|
514
|
+
}, z.core.$strict>], "kind">, z.ZodObject<{
|
|
515
|
+
kind: z.ZodLiteral<"unknown">;
|
|
516
|
+
}, z.core.$strict>]>;
|
|
517
|
+
}, z.core.$strict>;
|
|
470
518
|
life: z.ZodEnum<{
|
|
471
519
|
killed: "killed";
|
|
472
520
|
hung: "hung";
|
|
@@ -1164,8 +1212,6 @@ export type AkumaAskResult<T = unknown> = Omit<z.infer<typeof akumaAskResultSche
|
|
|
1164
1212
|
}>;
|
|
1165
1213
|
/** Compose one native status into the canonical observation its crossing transports. */
|
|
1166
1214
|
export declare function akumaObservationOf(status: AkumaStatus): AkumaObservation;
|
|
1167
|
-
export declare function isTellResult(value: unknown): value is AkumaTellResult;
|
|
1168
|
-
export declare function isAskResult(value: unknown): value is AkumaAskResult;
|
|
1169
1215
|
export declare const selectionResultSchemas: {
|
|
1170
1216
|
wait: z.ZodObject<{
|
|
1171
1217
|
mode: z.ZodEnum<{
|
|
@@ -1179,6 +1225,30 @@ export declare const selectionResultSchemas: {
|
|
|
1179
1225
|
observations: z.ZodReadonly<z.ZodArray<z.ZodObject<{
|
|
1180
1226
|
status: z.ZodObject<{
|
|
1181
1227
|
id: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
1228
|
+
birth: z.ZodObject<{
|
|
1229
|
+
origin: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1230
|
+
kind: z.ZodLiteral<"direct">;
|
|
1231
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1232
|
+
kind: z.ZodLiteral<"request">;
|
|
1233
|
+
parent: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
1234
|
+
requestId: z.ZodString;
|
|
1235
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
1236
|
+
kind: z.ZodLiteral<"fork">;
|
|
1237
|
+
parent: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
1238
|
+
at: z.ZodString;
|
|
1239
|
+
}, z.core.$strip>], "kind">;
|
|
1240
|
+
caller: z.ZodUnion<readonly [z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
1241
|
+
kind: z.ZodLiteral<"akuma">;
|
|
1242
|
+
world: z.ZodCustom<import("../world.js").WorldRoot, import("../world.js").WorldRoot>;
|
|
1243
|
+
akuId: z.ZodPipe<z.ZodString, z.ZodTransform<import("./identity.js").AkuId, string>>;
|
|
1244
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
1245
|
+
kind: z.ZodLiteral<"external">;
|
|
1246
|
+
integration: z.ZodString;
|
|
1247
|
+
id: z.ZodString;
|
|
1248
|
+
}, z.core.$strict>], "kind">, z.ZodObject<{
|
|
1249
|
+
kind: z.ZodLiteral<"unknown">;
|
|
1250
|
+
}, z.core.$strict>]>;
|
|
1251
|
+
}, z.core.$strict>;
|
|
1182
1252
|
life: z.ZodEnum<{
|
|
1183
1253
|
killed: "killed";
|
|
1184
1254
|
hung: "hung";
|
|
@@ -50,12 +50,6 @@ const akumaAskResultSchema = z
|
|
|
50
50
|
export function akumaObservationOf(status) {
|
|
51
51
|
return { status, contract: NO_DISPATCH_ASSOCIATION, createdTasks: EMPTY_CREATED_TASK_OBSERVATION };
|
|
52
52
|
}
|
|
53
|
-
export function isTellResult(value) {
|
|
54
|
-
return akumaTellResultSchema.safeParse(value).success;
|
|
55
|
-
}
|
|
56
|
-
export function isAskResult(value) {
|
|
57
|
-
return akumaAskResultSchema.safeParse(value).success;
|
|
58
|
-
}
|
|
59
53
|
export const selectionResultSchemas = {
|
|
60
54
|
wait: akumaWaitResultSchema,
|
|
61
55
|
tell: akumaTellResultSchema,
|
|
@@ -115,7 +115,7 @@ async function startTurnDrive(input) {
|
|
|
115
115
|
cwd,
|
|
116
116
|
options,
|
|
117
117
|
signal: driveController.signal,
|
|
118
|
-
requests: { dir: requests.directory },
|
|
118
|
+
requests: { dir: requests.directory, entry: requests.entry },
|
|
119
119
|
...(schemaJson === undefined ? {} : { schemaJson }),
|
|
120
120
|
};
|
|
121
121
|
const attempt = session === undefined
|
|
@@ -232,9 +232,6 @@ function pumpReceipts(writers) {
|
|
|
232
232
|
function observeFailure(settlement) {
|
|
233
233
|
return settlement.then(() => new Promise(() => { }), (error) => Promise.reject(error));
|
|
234
234
|
}
|
|
235
|
-
function observeReceiptFailure(receiptPump) {
|
|
236
|
-
return observeFailure(receiptPump);
|
|
237
|
-
}
|
|
238
235
|
function observeCompletionFailure(drive) {
|
|
239
236
|
return drive.completion.then(() => new Promise(() => { }), (error) => ({ kind: "completion-failed", error }));
|
|
240
237
|
}
|
|
@@ -354,7 +351,7 @@ async function consumeTurnDrive(input, active) {
|
|
|
354
351
|
let writesOpen = true;
|
|
355
352
|
const mayWrite = () => writesOpen && !input.supervisor.signal.aborted;
|
|
356
353
|
const writers = { input, turnSequence, drive, writeWitness, mayWrite };
|
|
357
|
-
const receiptFailure =
|
|
354
|
+
const receiptFailure = observeFailure(pumpReceipts(writers));
|
|
358
355
|
const completionFailure = observeCompletionFailure(drive);
|
|
359
356
|
const iterator = drive.events[Symbol.asyncIterator]();
|
|
360
357
|
let liveTells = true;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { decodeAkumaCaller } from "../akuma/caller.js";
|
|
2
|
+
import { World } from "../world.js";
|
|
3
|
+
/** Environment attribution belongs to the process edge, never SDK admission. */
|
|
4
|
+
export async function akumaCallerFromEnvironment(environment) {
|
|
5
|
+
const id = environment.KEIYAKU_ACTOR_ID;
|
|
6
|
+
const world = environment.KEIYAKU_ACTOR_WORLD;
|
|
7
|
+
if ((id === undefined) !== (world === undefined)) {
|
|
8
|
+
throw new TypeError("Akuma caller requires both KEIYAKU_ACTOR_ID and KEIYAKU_ACTOR_WORLD");
|
|
9
|
+
}
|
|
10
|
+
if (id !== undefined && world !== undefined) {
|
|
11
|
+
const resolved = await World.resolve({ cwd: world, repositoryRoot: world });
|
|
12
|
+
return decodeAkumaCaller({ kind: "akuma", akuId: id, world: resolved.candidate });
|
|
13
|
+
}
|
|
14
|
+
const external = environment.KEIYAKU_EXTERNAL_CALLER;
|
|
15
|
+
if (external === undefined)
|
|
16
|
+
return undefined;
|
|
17
|
+
const colon = external.indexOf(":");
|
|
18
|
+
if (colon < 0)
|
|
19
|
+
throw new TypeError("KEIYAKU_EXTERNAL_CALLER must be <integration>:<id>");
|
|
20
|
+
return decodeAkumaCaller({ kind: "external", integration: external.slice(0, colon), id: external.slice(colon + 1) });
|
|
21
|
+
}
|
|
@@ -175,11 +175,6 @@ function positiveIndex(raw, option, fail) {
|
|
|
175
175
|
fail(`${option} exceeds the safe integer range`);
|
|
176
176
|
return value;
|
|
177
177
|
}
|
|
178
|
-
function validateDirect(value, _fail) {
|
|
179
|
-
// Address validation belongs to the operation boundary so callers receive
|
|
180
|
-
// the compact Akuma refusal instead of a generic usage page.
|
|
181
|
-
return value;
|
|
182
|
-
}
|
|
183
178
|
function validateSet(value, fail) {
|
|
184
179
|
if (value.startsWith("kei/"))
|
|
185
180
|
return value;
|
|
@@ -192,7 +187,7 @@ function validateSet(value, fail) {
|
|
|
192
187
|
}
|
|
193
188
|
return value;
|
|
194
189
|
}
|
|
195
|
-
return
|
|
190
|
+
return value;
|
|
196
191
|
}
|
|
197
192
|
function parseWait(rawSelectors, flags, output, fail) {
|
|
198
193
|
if (flags.any === true && flags.all === true)
|
|
@@ -236,7 +231,7 @@ function parseAkumaHistory(selector, flags, output, fail) {
|
|
|
236
231
|
fail("history --id requires turn/<positive safe integer>");
|
|
237
232
|
return {
|
|
238
233
|
command: "history",
|
|
239
|
-
akuma:
|
|
234
|
+
akuma: selector,
|
|
240
235
|
...(id === undefined ? {} : { id }),
|
|
241
236
|
last: flags.last === true,
|
|
242
237
|
...(flags.before === undefined ? {} : { before: positiveIndex(flags.before, "--before", fail) }),
|
|
@@ -256,7 +251,7 @@ function parseAddressed(action, rawSelectors, flags, output, fail) {
|
|
|
256
251
|
fail("history accepts one complete aku/..., @alias, or kei/... selector");
|
|
257
252
|
return parseHistory(selector, flags, output, fail);
|
|
258
253
|
}
|
|
259
|
-
const akuma =
|
|
254
|
+
const akuma = rawSelectors[0];
|
|
260
255
|
const at = stringFlag(flags.at, "fork requires --at <historyId>", fail);
|
|
261
256
|
return { command: action, akuma, at, output };
|
|
262
257
|
}
|
|
@@ -279,10 +274,10 @@ function parsePrompted(action, positionals, stdin, fail) {
|
|
|
279
274
|
: { prompt: { kind: "argument", value: argument } }),
|
|
280
275
|
};
|
|
281
276
|
}
|
|
282
|
-
function parseTell(flags, subject, prompt, output
|
|
277
|
+
function parseTell(flags, subject, prompt, output) {
|
|
283
278
|
return {
|
|
284
279
|
command: "tell",
|
|
285
|
-
akuma:
|
|
280
|
+
akuma: subject,
|
|
286
281
|
interrupt: flags.interrupt === true,
|
|
287
282
|
prompt,
|
|
288
283
|
output,
|
|
@@ -292,7 +287,7 @@ function parseAsk(flags, subject, prompt, output, fail) {
|
|
|
292
287
|
const schema = flags.schema === undefined ? undefined : stringFlag(flags.schema, "ask --schema requires a file", fail);
|
|
293
288
|
return {
|
|
294
289
|
command: "ask",
|
|
295
|
-
akuma:
|
|
290
|
+
akuma: subject,
|
|
296
291
|
interrupt: flags.interrupt === true,
|
|
297
292
|
...(schema === undefined ? {} : { schema }),
|
|
298
293
|
...(flags.wait === undefined ? {} : { timeoutMs: parseDuration(flags.wait, "--wait", fail) }),
|
|
@@ -361,7 +356,7 @@ export function parseAkumaCommand(argv) {
|
|
|
361
356
|
return action === "call"
|
|
362
357
|
? parseCall(flags, parsed.subject, parsed.prompt, output, fail)
|
|
363
358
|
: action === "tell"
|
|
364
|
-
? parseTell(flags, parsed.subject, parsed.prompt, output
|
|
359
|
+
? parseTell(flags, parsed.subject, parsed.prompt, output)
|
|
365
360
|
: parseAsk(flags, parsed.subject, parsed.prompt, output, fail);
|
|
366
361
|
}
|
|
367
362
|
if (spec.arity === "one-or-more" ? positionals.length === 0 : positionals.length !== spec.arity) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { akumaCallerFromEnvironment } from "../akuma-caller.js";
|
|
1
2
|
import { CliUsageError, isBlankInput } from "../usage.js";
|
|
2
3
|
import { readFile } from "node:fs/promises";
|
|
3
4
|
import { resolve } from "node:path";
|
|
@@ -27,7 +28,7 @@ async function settingsAt(root, home) {
|
|
|
27
28
|
});
|
|
28
29
|
}
|
|
29
30
|
function akumas(input) {
|
|
30
|
-
return akumasWithExecution(input.path, input.execution);
|
|
31
|
+
return akumasWithExecution(input.path, input.execution, { reportDiagnostic: writeStderr });
|
|
31
32
|
}
|
|
32
33
|
async function schemaFromFile(path) {
|
|
33
34
|
try {
|
|
@@ -68,9 +69,7 @@ async function inputInitiator(input) {
|
|
|
68
69
|
catch { }
|
|
69
70
|
if (initiator === undefined)
|
|
70
71
|
return {};
|
|
71
|
-
//
|
|
72
|
-
// marker does not exist yet, and activating there would only fail noisily.
|
|
73
|
-
// The initiator still travels with the request either way.
|
|
72
|
+
// Identity preparation needs established plugin custody, not just a candidate.
|
|
74
73
|
if (!(await World.established(input.path)))
|
|
75
74
|
return { initiator };
|
|
76
75
|
await emitPluginSignal({
|
|
@@ -90,9 +89,15 @@ function emitAnswer(body, exact) {
|
|
|
90
89
|
async function runCall(command, input) {
|
|
91
90
|
const body = command.prompt === undefined ? undefined : await promptBody("call", { prompt: command.prompt }, input);
|
|
92
91
|
const schema = command.schema === undefined ? undefined : await schemaFromFile(command.schema);
|
|
92
|
+
const declaredCaller = executionChannel(input.execution).kind === "body-request"
|
|
93
|
+
? undefined
|
|
94
|
+
: await akumaCallerFromEnvironment(input.environment);
|
|
95
|
+
// Establish the selected World before preparing the submitting Square route.
|
|
96
|
+
await World.at(input.path);
|
|
93
97
|
const caller = akumas(input);
|
|
94
98
|
const request = {
|
|
95
99
|
...(await inputInitiator(input)),
|
|
100
|
+
...(declaredCaller === undefined ? {} : { caller: declaredCaller }),
|
|
96
101
|
archetype: command.archetype,
|
|
97
102
|
...(body === undefined ? {} : { body }),
|
|
98
103
|
...(input.home === undefined ? {} : { home: input.home }),
|
|
@@ -287,7 +292,10 @@ async function runHistory(command, input) {
|
|
|
287
292
|
return historyExitCode(result, command.id);
|
|
288
293
|
}
|
|
289
294
|
async function runFork(command, input) {
|
|
295
|
+
const caller = await akumaCallerFromEnvironment(input.environment);
|
|
290
296
|
const receipt = await akumas(input).fork({
|
|
297
|
+
...(await inputInitiator(input)),
|
|
298
|
+
...(caller === undefined ? {} : { caller }),
|
|
291
299
|
akuma: command.akuma,
|
|
292
300
|
at: command.at,
|
|
293
301
|
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
@@ -24,7 +24,8 @@ export type ParsedBind = Output & Actor & Readonly<{
|
|
|
24
24
|
command: "bind";
|
|
25
25
|
forkOf?: string;
|
|
26
26
|
task?: string;
|
|
27
|
-
target
|
|
27
|
+
/** A literal target branch, or `null` for a deliberately targetless bind. */
|
|
28
|
+
target?: string | null;
|
|
28
29
|
after?: readonly string[];
|
|
29
30
|
gates?: readonly string[];
|
|
30
31
|
}>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { validateAkumaName } from "../../identity/normalize.js";
|
|
2
2
|
import { parseTaskNamespaceSelector } from "../../task/catalog.js";
|
|
3
3
|
import { CliUsageError, commandGuide } from "../usage.js";
|
|
4
4
|
import { CONTRACT_COMMAND_SPECS } from "./contract-help.js";
|
|
@@ -9,11 +9,11 @@ function parseAkumaCatalogPath(value) {
|
|
|
9
9
|
return { kind: "akuma" };
|
|
10
10
|
const scopedGlob = /^aku\/([^/]+)\/\*$/u.exec(value);
|
|
11
11
|
if (scopedGlob !== null)
|
|
12
|
-
return { kind: "akuma", archetype:
|
|
12
|
+
return { kind: "akuma", archetype: validateAkumaName(scopedGlob[1]) };
|
|
13
13
|
const match = /^aku\/([^/]+)\/?$/u.exec(value);
|
|
14
14
|
if (match === null)
|
|
15
15
|
return null;
|
|
16
|
-
return { kind: "akuma", archetype:
|
|
16
|
+
return { kind: "akuma", archetype: validateAkumaName(match[1]) };
|
|
17
17
|
}
|
|
18
18
|
function optionalFlag(flags, name) {
|
|
19
19
|
const value = flags[name];
|
|
@@ -41,6 +41,13 @@ function parseGateNames(parts, command) {
|
|
|
41
41
|
}
|
|
42
42
|
return names;
|
|
43
43
|
}
|
|
44
|
+
function parseBindTarget(parts) {
|
|
45
|
+
const target = optionalFlag(parts.flags, "target");
|
|
46
|
+
const noTarget = parts.flags["no-target"] === true;
|
|
47
|
+
if (target !== undefined && noTarget)
|
|
48
|
+
refuse("bind", "--target and --no-target are mutually exclusive");
|
|
49
|
+
return noTarget ? null : target;
|
|
50
|
+
}
|
|
44
51
|
function parseBind(parts) {
|
|
45
52
|
const forkOf = optionalFlag(parts.flags, "fork-of");
|
|
46
53
|
if (forkOf !== undefined) {
|
|
@@ -50,7 +57,7 @@ function parseBind(parts) {
|
|
|
50
57
|
if (parts.flags[option] !== undefined)
|
|
51
58
|
refuse("bind", `--${option} is not valid with --fork-of`);
|
|
52
59
|
}
|
|
53
|
-
const target =
|
|
60
|
+
const target = parseBindTarget(parts);
|
|
54
61
|
return {
|
|
55
62
|
command: "bind",
|
|
56
63
|
forkOf,
|
|
@@ -62,7 +69,7 @@ function parseBind(parts) {
|
|
|
62
69
|
if (!parts.stdin)
|
|
63
70
|
refuse("bind", "bind requires stdin");
|
|
64
71
|
const task = optionalFlag(parts.flags, "task");
|
|
65
|
-
const target =
|
|
72
|
+
const target = parseBindTarget(parts);
|
|
66
73
|
const after = parts.flags.after === undefined ? [] : Array.isArray(parts.flags.after) ? parts.flags.after : [parts.flags.after];
|
|
67
74
|
const gates = parseGateNames(parts, "bind");
|
|
68
75
|
return {
|
|
@@ -196,15 +203,6 @@ function parseRegion(parts) {
|
|
|
196
203
|
output: parts.output,
|
|
197
204
|
};
|
|
198
205
|
}
|
|
199
|
-
function akumaCatalogQuery(query, parts) {
|
|
200
|
-
const limit = optionalFlag(parts.flags, "limit");
|
|
201
|
-
if (limit !== undefined && (!/^[1-9][0-9]*$/u.test(limit) || !Number.isSafeInteger(Number(limit))))
|
|
202
|
-
refuse("ls", "--limit requires a positive safe integer");
|
|
203
|
-
return {
|
|
204
|
-
...query,
|
|
205
|
-
...(limit === undefined ? {} : { limit: Number(limit) }),
|
|
206
|
-
};
|
|
207
|
-
}
|
|
208
206
|
function listLimit(parts, command = "ls") {
|
|
209
207
|
const limit = optionalFlag(parts.flags, "limit");
|
|
210
208
|
if (limit !== undefined && (!/^[1-9][0-9]*$/u.test(limit) || !Number.isSafeInteger(Number(limit))))
|
|
@@ -249,7 +247,7 @@ function parseLs(parts) {
|
|
|
249
247
|
const query = parseAkumaCatalogPath(path);
|
|
250
248
|
if (query === null)
|
|
251
249
|
refuse("ls", "ls requires a supported identity directory selector");
|
|
252
|
-
return { command: "ls", query:
|
|
250
|
+
return { command: "ls", query: { ...query, ...(limit === undefined ? {} : { limit }) }, output: parts.output };
|
|
253
251
|
}
|
|
254
252
|
catch (error) {
|
|
255
253
|
if (error instanceof CliUsageError)
|
|
@@ -15,12 +15,13 @@ export declare const CONTRACT_COMMAND_SPECS: {
|
|
|
15
15
|
readonly actor: "value";
|
|
16
16
|
readonly task: "value";
|
|
17
17
|
readonly target: "value";
|
|
18
|
+
readonly "no-target": "boolean";
|
|
18
19
|
readonly after: "repeat";
|
|
19
20
|
readonly gates: "raw-value";
|
|
20
21
|
readonly "fork-of": "value";
|
|
21
22
|
readonly json: "boolean";
|
|
22
23
|
};
|
|
23
|
-
readonly usage: "bind [--task <task/...>] [--target <ref>] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] - | bind --fork-of <kei/...> [--target <ref>] [--actor <actor>]";
|
|
24
|
+
readonly usage: "bind [--task <task/...>] [--target <ref> | --no-target] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] - | bind --fork-of <kei/...> [--target <ref> | --no-target] [--actor <actor>]";
|
|
24
25
|
readonly purpose: "Create a Contract from stdin Markdown or copy an existing Contract as a starting point.";
|
|
25
26
|
readonly details: string;
|
|
26
27
|
};
|
|
@@ -7,14 +7,21 @@ export const CONTRACT_COMMAND_SPECS = {
|
|
|
7
7
|
actor: "value",
|
|
8
8
|
task: "value",
|
|
9
9
|
target: "value",
|
|
10
|
+
"no-target": "boolean",
|
|
10
11
|
after: "repeat",
|
|
11
12
|
gates: "raw-value",
|
|
12
13
|
"fork-of": "value",
|
|
13
14
|
json: "boolean",
|
|
14
15
|
},
|
|
15
|
-
usage: "bind [--task <task/...>] [--target <ref>] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] - | bind --fork-of <kei/...> [--target <ref>] [--actor <actor>]",
|
|
16
|
+
usage: "bind [--task <task/...>] [--target <ref> | --no-target] [--after <kei/...> ...] [--gates <name,...>] [--actor <actor>] - | bind --fork-of <kei/...> [--target <ref> | --no-target] [--actor <actor>]",
|
|
16
17
|
purpose: "Create a Contract from stdin Markdown or copy an existing Contract as a starting point.",
|
|
17
18
|
details: [
|
|
19
|
+
"--target names one existing local branch literally; it is never created and never",
|
|
20
|
+
"guessed. Omitting it binds to the current branch of the invocation worktree",
|
|
21
|
+
"coordinate, or binds without a target on a detached committed HEAD. --no-target",
|
|
22
|
+
"binds without a target on purpose, and is refused together with --target.",
|
|
23
|
+
"A fork copies its source target when neither flag is given.",
|
|
24
|
+
"",
|
|
18
25
|
"Gates are acceptance obligations checked at placement: reviewed awaits a",
|
|
19
26
|
"satisfied review, verified awaits a passing Verification run.",
|
|
20
27
|
"",
|
|
@@ -245,6 +252,29 @@ export function renderContractHelp(command) {
|
|
|
245
252
|
"effort, network, allowed, systemPromptMode, and description; the body is",
|
|
246
253
|
"an optional system prompt.",
|
|
247
254
|
"",
|
|
255
|
+
"Local Paseo provider in settings.json:",
|
|
256
|
+
' { "providers": { "paseo": {',
|
|
257
|
+
' "kind": "paseo",',
|
|
258
|
+
' "config": { "url": "ws://127.0.0.1:6767/ws", "provider": "claude" }',
|
|
259
|
+
" } } }",
|
|
260
|
+
"The native provider id is bare (claude, codex, pi), not provider/model.",
|
|
261
|
+
"Example .keiyaku/akuma/paseo-worker.md frontmatter:",
|
|
262
|
+
" ---",
|
|
263
|
+
" provider: paseo",
|
|
264
|
+
" model: <native-model-id>",
|
|
265
|
+
" effort: high",
|
|
266
|
+
" ---",
|
|
267
|
+
"Model and effort must be offered by the selected native provider;",
|
|
268
|
+
"effort names its native thinking option id.",
|
|
269
|
+
'PASEO_PASSWORD=<password> keiyaku call paseo-worker "<prompt>"',
|
|
270
|
+
"Paseo must already be running locally. Resume keeps its live native",
|
|
271
|
+
"runtime; after Paseo native reload/restart create a fresh Akuma.",
|
|
272
|
+
"Observed busy agents refuse; native steer still has a check/send race.",
|
|
273
|
+
"Explicit control cancels native current execution session-wide and may",
|
|
274
|
+
"affect concurrent human work. Normal completion only retires the client",
|
|
275
|
+
"and its sockets; it never cancels later work or closes the native runtime.",
|
|
276
|
+
"Socket closure does not prove native cancellation succeeded.",
|
|
277
|
+
"",
|
|
248
278
|
usageLine(spec.usage),
|
|
249
279
|
].join("\n");
|
|
250
280
|
}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { listArchetypeDefinitions } from "../../akuma/archetype.js";
|
|
2
1
|
import { executionChannel } from "../../akuma/requests.js";
|
|
3
|
-
import { Akumas, Keiyaku, KeiyakuError, nuke } from "../../index.js";
|
|
4
|
-
import { kanshi,
|
|
2
|
+
import { Akumas, Keiyaku, KeiyakuError, kanshiCategory, listArchetypeDefinitions, nuke } from "../../index.js";
|
|
3
|
+
import { kanshi, observeKanshi, selectRegion } from "../../kanshi/index.js";
|
|
5
4
|
import { resolveNamedAddress } from "../../library/address.js";
|
|
6
5
|
import { composeContractLibrary, observeKeiyaku } from "../../library/contract-composition.js";
|
|
7
6
|
import { validateArcMarkdown, validateContractMarkdown } from "../../library/input.js";
|
|
@@ -20,11 +19,9 @@ import { reconcileHasFailure, renderReconcile } from "../render/reconcile.js";
|
|
|
20
19
|
import { renderConflictMaterialized, renderRefusal } from "../render/refusal.js";
|
|
21
20
|
import { renderRegionText } from "../render/region.js";
|
|
22
21
|
import { renderSettingsText, settingsJsonValue } from "../render/settings.js";
|
|
23
|
-
import { canonicalContractSelector, contractFromInput, resolveContractId
|
|
24
|
-
import { displayContext, emit, writeJson, writeStdout } from "../streams.js";
|
|
22
|
+
import { canonicalContractSelector, contractFromInput, resolveContractId } from "../selectors.js";
|
|
23
|
+
import { displayContext, emit, writeJson, writeStderr, writeStdout } from "../streams.js";
|
|
25
24
|
import { CliUsageError, isBlankInput } from "../usage.js";
|
|
26
|
-
import { amendFromCommand } from "./amend.js";
|
|
27
|
-
import { bindFromCommand } from "./bind.js";
|
|
28
25
|
function requiredRepo(coordinates) {
|
|
29
26
|
if (coordinates.repo === undefined)
|
|
30
27
|
throw new CliUsageError("this command requires a resolved Repo");
|
|
@@ -50,17 +47,6 @@ async function contractSettings(command, execution, world, home) {
|
|
|
50
47
|
function draftWarning(error) {
|
|
51
48
|
return { warning: `bind draft could not be preserved: ${error instanceof Error ? error.message : String(error)}` };
|
|
52
49
|
}
|
|
53
|
-
/** Preserve a refused bind draft at the invocation cwd; coordinates are not yet available. */
|
|
54
|
-
async function bindDraftReceiptAtCwd(input, markdown) {
|
|
55
|
-
try {
|
|
56
|
-
return await preserveBindDraft(await resolveInvocationCwd(input), markdown);
|
|
57
|
-
}
|
|
58
|
-
catch (error) {
|
|
59
|
-
if (error instanceof Error && "executionReceipt" in error)
|
|
60
|
-
throw error;
|
|
61
|
-
return draftWarning(error);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
50
|
/**
|
|
65
51
|
* The one bind-document admission that runs before coordinate resolution, so a malformed document
|
|
66
52
|
* refuses as a draft-bearing refusal instead of a later Repo/Git failure. Reads the memoized stdin.
|
|
@@ -76,7 +62,7 @@ export async function admitBindMarkdown(input) {
|
|
|
76
62
|
throw error;
|
|
77
63
|
if (!(error instanceof TypeError) && !(error instanceof KeiyakuError && error.category === "invalid-input"))
|
|
78
64
|
throw error;
|
|
79
|
-
throw new BindDraftError(error, await
|
|
65
|
+
throw new BindDraftError(error, await bindDraftReceipt(() => resolveInvocationCwd(input), input.markdown));
|
|
80
66
|
}
|
|
81
67
|
}
|
|
82
68
|
async function bindDraftReceipt(world, markdown) {
|
|
@@ -145,41 +131,32 @@ async function contractLibrary(command, execution, configuration, runtime) {
|
|
|
145
131
|
return composeContractLibrary(execution, createKeiyakuHandle, {
|
|
146
132
|
...(configuration === undefined ? {} : { settings: configuration }),
|
|
147
133
|
...(actor === undefined ? {} : { actor }),
|
|
148
|
-
}
|
|
149
|
-
// The CLI owns this default: an omitted Markdown --target names the invocation branch.
|
|
150
|
-
{ kind: "current-branch" });
|
|
134
|
+
});
|
|
151
135
|
}
|
|
152
136
|
async function runBind(command, input, library) {
|
|
153
137
|
const { coordinates, runtime } = input;
|
|
154
138
|
const repo = requiredRepo(coordinates);
|
|
155
139
|
const actor = actorFromEdge(command.actor, runtime.environment);
|
|
156
140
|
if (command.forkOf !== undefined) {
|
|
157
|
-
const answer = await
|
|
158
|
-
command,
|
|
141
|
+
const answer = await library.bind({
|
|
159
142
|
repo,
|
|
160
|
-
|
|
143
|
+
forkOf: contractFromInput(repo, command.forkOf).id,
|
|
144
|
+
...(command.target === undefined ? {} : { target: command.target }),
|
|
161
145
|
...(actor === undefined ? {} : { actor }),
|
|
162
146
|
});
|
|
163
147
|
return await finishContractAnswer(answer, command.output);
|
|
164
148
|
}
|
|
165
149
|
const markdown = await runtime.readStdin();
|
|
166
|
-
if (isBlankInput(markdown))
|
|
167
|
-
throw new CliUsageError("bind requires a nonblank stdin document");
|
|
168
150
|
try {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
catch (error) {
|
|
172
|
-
if (!(error instanceof TypeError) && !(error instanceof KeiyakuError && error.category === "invalid-input"))
|
|
173
|
-
throw error;
|
|
174
|
-
throw new BindDraftError(error, await bindDraftReceipt(coordinates.establishWorld, markdown));
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
const answer = await bindFromCommand({
|
|
178
|
-
command,
|
|
151
|
+
const after = command.after?.map((id) => contractFromInput(repo, id).id);
|
|
152
|
+
const answer = await library.bind({
|
|
179
153
|
repo,
|
|
180
|
-
library,
|
|
181
154
|
markdown,
|
|
155
|
+
...(command.task === undefined ? {} : { task: command.task }),
|
|
156
|
+
...(command.target === undefined ? {} : { target: command.target }),
|
|
182
157
|
...(actor === undefined ? {} : { actor }),
|
|
158
|
+
...(after === undefined ? {} : { after }),
|
|
159
|
+
...(command.gates === undefined ? {} : { gates: command.gates }),
|
|
183
160
|
});
|
|
184
161
|
if (answer.kind !== "refused")
|
|
185
162
|
return await finishContractAnswer(answer, command.output);
|
|
@@ -203,13 +180,13 @@ async function runAmend(command, input, seat) {
|
|
|
203
180
|
const markdown = command.stdin === true ? await runtime.readStdin() : undefined;
|
|
204
181
|
if (markdown !== undefined && isBlankInput(markdown))
|
|
205
182
|
throw new CliUsageError("amend requires a nonblank stdin document");
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
contract: seat.contract,
|
|
183
|
+
const repo = requiredRepo(coordinates);
|
|
184
|
+
const after = command.clearAfter === true ? [] : command.after?.map((id) => contractFromInput(repo, id).id);
|
|
185
|
+
const answer = await seat.contract.amend({
|
|
210
186
|
...(markdown === undefined ? {} : { markdown }),
|
|
211
|
-
...(command.gates === undefined ? {} : { gates: command.gates }),
|
|
212
187
|
...(seat.actor === undefined ? {} : { actor: seat.actor }),
|
|
188
|
+
...(after === undefined ? {} : { after }),
|
|
189
|
+
...(command.gates === undefined ? {} : { gates: command.gates }),
|
|
213
190
|
});
|
|
214
191
|
return await finishContractAnswer(answer, command.output);
|
|
215
192
|
}
|
|
@@ -366,7 +343,7 @@ async function runLs(command, coordinates, home) {
|
|
|
366
343
|
async function readAkumaStatus(akuma, alias, coordinates) {
|
|
367
344
|
if (coordinates.world === null)
|
|
368
345
|
throw new CliUsageError("no Keiyaku world contains the Akuma selector");
|
|
369
|
-
const status = await Akumas.of(coordinates.world).status({
|
|
346
|
+
const status = await Akumas.of(coordinates.world, { reportDiagnostic: writeStderr }).status({
|
|
370
347
|
akuma,
|
|
371
348
|
...(coordinates.repo === undefined ? {} : { repo: coordinates.repo }),
|
|
372
349
|
});
|
|
@@ -473,13 +450,7 @@ async function runStatusIdentity(command, coordinates) {
|
|
|
473
450
|
}
|
|
474
451
|
return emit(command.output, report, () => renderKanshiText(report, displayContext(), "contract"), 0);
|
|
475
452
|
}
|
|
476
|
-
|
|
477
|
-
world: coordinates.world,
|
|
478
|
-
...(coordinates.repo === undefined ? {} : { repo: coordinates.repo }),
|
|
479
|
-
});
|
|
480
|
-
const contract = resolveKanshiContract(report, command.contract);
|
|
481
|
-
const selected = selectKanshi({ report, contract });
|
|
482
|
-
return emit(command.output, selected, () => renderKanshiText(selected, displayContext(), "contract"), 0);
|
|
453
|
+
throw new CliUsageError(`contract selector must use kei/: ${command.contract}`);
|
|
483
454
|
}
|
|
484
455
|
async function runStatus(command, coordinates) {
|
|
485
456
|
if (command.guidance === true)
|
|
@@ -501,10 +472,10 @@ async function runRegion(command, coordinates) {
|
|
|
501
472
|
const report = await kanshi({ world: coordinates.world, repo, region: { kind: "path", patterns: command.paths } });
|
|
502
473
|
return emitSection(report.region ?? { kind: "absent" });
|
|
503
474
|
}
|
|
475
|
+
const contract = command.contract === undefined ? undefined : await resolveContractId(repo, command.contract, coordinates.cwd);
|
|
504
476
|
const report = await kanshi({ world: coordinates.world, repo, region: { kind: "declarations" } });
|
|
505
|
-
if (
|
|
477
|
+
if (contract === undefined)
|
|
506
478
|
return emitSection(report.region ?? { kind: "absent" });
|
|
507
|
-
const contract = resolveKanshiContract(report, command.contract);
|
|
508
479
|
const observed = await observeKeiyaku({ repo, id: contract });
|
|
509
480
|
if (observed.kind === "missing" || observed.row.phase === "claimed" || observed.row.phase === "abandoned") {
|
|
510
481
|
const refusal = {
|