@astrosheep/keiyaku 4.0.3 → 4.0.5
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/build/integrations/marketplace/plugins/keiyaku/.claude-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/.codex-plugin/plugin.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/package.json +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +15 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +34 -13
- package/build/src/akuma/akuma.d.ts +34 -12
- package/build/src/akuma/akuma.js +118 -63
- package/build/src/akuma/allowed.d.ts +7 -0
- package/build/src/akuma/allowed.js +33 -0
- package/build/src/akuma/archetype.d.ts +7 -4
- package/build/src/akuma/archetype.js +15 -16
- package/build/src/akuma/body.d.ts +6 -1
- package/build/src/akuma/body.js +36 -27
- package/build/src/akuma/heart/facts.d.ts +82 -14
- package/build/src/akuma/heart/index.d.ts +5 -18
- package/build/src/akuma/heart/index.js +14 -84
- package/build/src/akuma/heart/request-authority.d.ts +12 -0
- package/build/src/akuma/heart/request-authority.js +119 -0
- package/build/src/akuma/heart/request-rows.d.ts +16 -0
- package/build/src/akuma/heart/request-rows.js +88 -0
- package/build/src/akuma/heart/rows.d.ts +1 -26
- package/build/src/akuma/heart/rows.js +0 -50
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +22 -10
- package/build/src/akuma/heart/soul.js +2 -36
- package/build/src/akuma/heart/storage.d.ts +1 -0
- package/build/src/akuma/heart/storage.js +15 -0
- package/build/src/akuma/heart/timeline.d.ts +1 -5
- package/build/src/akuma/heart/timeline.js +8 -17
- package/build/src/akuma/index.d.ts +5 -2
- package/build/src/akuma/index.js +1 -0
- package/build/src/akuma/projection.d.ts +17 -3
- package/build/src/akuma/projection.js +40 -3
- package/build/src/akuma/provider-recipe.js +1 -11
- package/build/src/akuma/provider.d.ts +2 -7
- package/build/src/akuma/provider.js +2 -1
- package/build/src/akuma/providers/acp/core.d.ts +3 -1
- package/build/src/akuma/providers/acp/core.js +10 -6
- package/build/src/akuma/providers/acp/events.d.ts +11 -3
- package/build/src/akuma/providers/acp/events.js +78 -4
- package/build/src/akuma/providers/acp/index.js +0 -1
- package/build/src/akuma/providers/claude/events.js +62 -3
- package/build/src/akuma/providers/claude/index.d.ts +0 -4
- package/build/src/akuma/providers/claude/index.js +7 -3
- package/build/src/akuma/providers/codex-app-server/events.js +1 -13
- package/build/src/akuma/providers/codex-app-server/index.d.ts +2 -27
- package/build/src/akuma/providers/codex-app-server/index.js +0 -2
- package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
- package/build/src/akuma/providers/grok-build/index.js +72 -3
- package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
- package/build/src/akuma/providers/opencode-sdk/index.d.ts +2 -28
- package/build/src/akuma/providers/opencode-sdk/index.js +8 -4
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +1 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +1 -1
- package/build/src/akuma/providers/pi/events.js +17 -3
- package/build/src/akuma/providers/pi/index.js +11 -4
- package/build/src/akuma/providers/unified-patch.d.ts +4 -0
- package/build/src/akuma/providers/unified-patch.js +14 -0
- package/build/src/akuma/publication.d.ts +1 -1
- package/build/src/akuma/publication.js +1 -1
- package/build/src/akuma/request-serve.d.ts +87 -0
- package/build/src/akuma/request-serve.js +484 -0
- package/build/src/akuma/request-wire.d.ts +124 -0
- package/build/src/akuma/request-wire.js +380 -0
- package/build/src/akuma/requests.d.ts +41 -41
- package/build/src/akuma/requests.js +75 -374
- package/build/src/akuma-body.d.ts +8 -0
- package/build/src/akuma-body.js +84 -0
- package/build/src/body/arc.js +4 -29
- package/build/src/body/decode.js +5 -39
- package/build/src/body/envelope.d.ts +7 -0
- package/build/src/body/envelope.js +37 -0
- package/build/src/cli/accepted.d.ts +4 -1
- package/build/src/cli/accepted.js +39 -9
- package/build/src/cli/commands/akuma-invoke.d.ts +8 -7
- package/build/src/cli/commands/akuma-invoke.js +18 -10
- package/build/src/cli/commands/akuma.d.ts +11 -2
- package/build/src/cli/commands/akuma.js +67 -28
- package/build/src/cli/commands/amend.d.ts +1 -1
- package/build/src/cli/commands/amend.js +1 -1
- package/build/src/cli/commands/contract.d.ts +8 -8
- package/build/src/cli/commands/contract.js +3 -3
- package/build/src/cli/commands/install.js +2 -2
- package/build/src/cli/commands/task-invoke.js +98 -9
- package/build/src/cli/commands/task-query.d.ts +1 -1
- package/build/src/cli/commands/task-query.js +11 -5
- package/build/src/cli/coordinates.d.ts +2 -0
- package/build/src/cli/coordinates.js +12 -5
- package/build/src/cli/invoke.d.ts +1 -0
- package/build/src/cli/invoke.js +116 -75
- package/build/src/cli/main.d.ts +2 -0
- package/build/src/cli/main.js +29 -4
- package/build/src/cli/parse.d.ts +3 -2
- package/build/src/cli/parse.js +25 -8
- package/build/src/cli/render/akuma.d.ts +2 -2
- package/build/src/cli/render/akuma.js +138 -24
- package/build/src/cli/render/audit.js +18 -8
- package/build/src/cli/render/contract.d.ts +2 -0
- package/build/src/cli/render/contract.js +243 -36
- package/build/src/cli/render/kanshi.js +64 -29
- package/build/src/cli/render/receipt.d.ts +2 -1
- package/build/src/cli/render/receipt.js +37 -2
- package/build/src/cli/render/terminal.d.ts +0 -2
- package/build/src/cli/render/terminal.js +0 -29
- package/build/src/cli/render/text.js +3 -1
- package/build/src/cli/result.d.ts +52 -9
- package/build/src/cli/selectors.d.ts +1 -0
- package/build/src/cli/selectors.js +9 -6
- package/build/src/contract-worktree.d.ts +1 -2
- package/build/src/contract-worktree.js +7 -9
- package/build/src/core/facts/codec.js +9 -0
- package/build/src/core/facts/fold.js +13 -1
- package/build/src/core/facts/types.d.ts +8 -1
- package/build/src/core/subject.js +4 -3
- package/build/src/core/verbs/placement.d.ts +9 -1
- package/build/src/core/verbs/placement.js +24 -6
- package/build/src/core/verbs/reintegrate.d.ts +13 -0
- package/build/src/core/verbs/reintegrate.js +24 -0
- package/build/src/dispatch/index.d.ts +1 -1
- package/build/src/dispatch/index.js +50 -39
- package/build/src/git/admission.d.ts +2 -1
- package/build/src/git/hooks.d.ts +0 -4
- package/build/src/git/hooks.js +0 -36
- package/build/src/git/integration.d.ts +7 -8
- package/build/src/git/integration.js +62 -9
- package/build/src/git/observe.d.ts +2 -1
- package/build/src/git/observe.js +6 -5
- package/build/src/git/process.d.ts +26 -0
- package/build/src/git/process.js +94 -0
- package/build/src/git/read-observation.d.ts +2 -1
- package/build/src/git/read-observation.js +3 -2
- package/build/src/git/reconcile.d.ts +8 -2
- package/build/src/git/reconcile.js +63 -14
- package/build/src/git/repository.d.ts +2 -29
- package/build/src/git/repository.js +4 -118
- package/build/src/git/scratch.d.ts +1 -1
- package/build/src/git/scratch.js +1 -1
- package/build/src/git/target-placement.d.ts +1 -1
- package/build/src/git/target-placement.js +9 -7
- package/build/src/git/tender.d.ts +20 -5
- package/build/src/git/tender.js +45 -13
- package/build/src/git/terminal-seal.d.ts +16 -2
- package/build/src/git/terminal-seal.js +15 -5
- package/build/src/git/workspace.d.ts +2 -1
- package/build/src/git/workspace.js +13 -5
- package/build/src/index.d.ts +1 -2
- package/build/src/index.js +1 -1
- package/build/src/kanshi/index.d.ts +1 -1
- package/build/src/kanshi/index.js +1 -1
- package/build/src/kanshi/read.d.ts +9 -1
- package/build/src/kanshi/read.js +91 -37
- package/build/src/kanshi/report.d.ts +1 -0
- package/build/src/library/address.d.ts +5 -14
- package/build/src/library/address.js +27 -23
- package/build/src/library/akuma-creation.d.ts +4 -2
- package/build/src/library/akuma-creation.js +43 -26
- package/build/src/library/audit.d.ts +2 -1
- package/build/src/library/audit.js +1 -1
- package/build/src/library/bind.d.ts +2 -1
- package/build/src/library/bind.js +4 -4
- package/build/src/library/catalog.d.ts +1 -2
- package/build/src/library/catalog.js +11 -6
- package/build/src/library/configuration.d.ts +5 -1
- package/build/src/library/configuration.js +71 -18
- package/build/src/library/contract.d.ts +70 -3
- package/build/src/library/contract.js +213 -27
- package/build/src/library/delivery.d.ts +1 -1
- package/build/src/library/fleet.d.ts +70 -12
- package/build/src/library/fleet.js +236 -56
- package/build/src/library/input.d.ts +0 -1
- package/build/src/library/input.js +1 -5
- package/build/src/library/keiyaku.d.ts +4 -4
- package/build/src/library/keiyaku.js +1 -2
- package/build/src/library/mutation.d.ts +2 -1
- package/build/src/library/reconcile.d.ts +2 -1
- package/build/src/library/reconcile.js +3 -1
- package/build/src/library/region.d.ts +1 -1
- package/build/src/library/repo.d.ts +3 -1
- package/build/src/library/repo.js +8 -4
- package/build/src/protocol/abandon.d.ts +9 -0
- package/build/src/protocol/abandon.js +15 -0
- package/build/src/protocol/amend.d.ts +16 -0
- package/build/src/protocol/amend.js +77 -0
- package/build/src/protocol/arc.d.ts +6 -0
- package/build/src/protocol/arc.js +12 -0
- package/build/src/protocol/attempt.d.ts +2 -1
- package/build/src/protocol/audit.d.ts +53 -0
- package/build/src/protocol/audit.js +140 -0
- package/build/src/protocol/bind.d.ts +2 -3
- package/build/src/protocol/bind.js +2 -16
- package/build/src/protocol/completion.d.ts +32 -0
- package/build/src/protocol/completion.js +130 -0
- package/build/src/protocol/deliver.d.ts +37 -0
- package/build/src/protocol/deliver.js +160 -0
- package/build/src/protocol/intent.d.ts +1 -1
- package/build/src/protocol/intent.js +1 -1
- package/build/src/protocol/operations.d.ts +65 -198
- package/build/src/protocol/operations.js +21 -634
- package/build/src/protocol/placement.d.ts +4 -13
- package/build/src/protocol/placement.js +3 -15
- package/build/src/protocol/read/status.d.ts +4 -2
- package/build/src/protocol/read/status.js +27 -15
- package/build/src/protocol/reconcile.d.ts +35 -0
- package/build/src/protocol/reconcile.js +41 -0
- package/build/src/protocol/reintegrate.d.ts +31 -0
- package/build/src/protocol/reintegrate.js +74 -0
- package/build/src/protocol/review.d.ts +33 -0
- package/build/src/protocol/review.js +148 -0
- package/build/src/protocol/run.d.ts +1 -1
- package/build/src/runtime/proc/run.d.ts +1 -0
- package/build/src/runtime/proc/run.js +9 -2
- package/build/src/settlement/fence.d.ts +1 -1
- package/build/src/settlement/holder.d.ts +1 -1
- package/build/src/settlement/settle.d.ts +2 -1
- package/build/src/settlement/settle.js +4 -1
- package/build/src/task/board.d.ts +18 -4
- package/build/src/task/board.js +73 -29
- package/build/src/task/compose.d.ts +1 -1
- package/build/src/task/compose.js +11 -4
- package/build/src/task/index.d.ts +4 -4
- package/build/src/task/index.js +8 -131
- package/build/src/task/input.d.ts +18 -0
- package/build/src/task/input.js +189 -0
- package/build/src/task/mutation.d.ts +39 -0
- package/build/src/task/mutation.js +85 -0
- package/build/src/task/operations.d.ts +4 -19
- package/build/src/task/operations.js +64 -18
- package/build/src/task/query.d.ts +9 -2
- package/build/src/task/query.js +32 -64
- package/build/src/task/store.js +0 -2
- package/build/src/verification/execution.d.ts +1 -1
- package/build/src/verification/execution.js +2 -1
- package/build/src/workspace-place.d.ts +1 -4
- package/build/src/workspace-place.js +0 -15
- package/package.json +5 -3
package/build/src/cli/invoke.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AkumaWorldScopeError, gatesFrom, Keiyaku, requireBranchesToBeUpToDateFrom, settings, SettingsError, worktreeHooksFrom } from "../index.js";
|
|
2
|
-
import { kanshi, selectKanshi, selectRegion } from "../kanshi/index.js";
|
|
1
|
+
import { AkumaWorldScopeError, gatesFrom, Keiyaku, KeiyakuRefused, requireBranchesToBeUpToDateFrom, settings, SettingsError, worktreeHooksFrom, } from "../index.js";
|
|
2
|
+
import { kanshi, observeKanshi, selectKanshi, selectRegion, } from "../kanshi/index.js";
|
|
3
3
|
import { resolveActor } from "./actor.js";
|
|
4
4
|
import { acceptedAbandon, acceptedAmend, acceptedArc, acceptedAudit, acceptedBind, acceptedDeliver, acceptedReview, resultFromMutationCall, } from "./accepted.js";
|
|
5
5
|
import { amendFromCommand } from "./commands/amend.js";
|
|
@@ -10,8 +10,10 @@ import { installHarnesses } from "./commands/install.js";
|
|
|
10
10
|
import { invokeTask } from "./commands/task-invoke.js";
|
|
11
11
|
import { CliUsageError, renderCommandUsage } from "./parse.js";
|
|
12
12
|
import { isBlankInput } from "./usage.js";
|
|
13
|
-
import { contractFromInput, resolveContextualContract, resolveKanshiContract } from "./selectors.js";
|
|
13
|
+
import { canonicalContractSelector, contractFromInput, resolveContextualContract, resolveKanshiContract, } from "./selectors.js";
|
|
14
14
|
import { resolveNamedAddress } from "../library/address.js";
|
|
15
|
+
import { injectedBodyRequests } from "../akuma/requests.js";
|
|
16
|
+
import { EMPTY_WORKTREE_HOOKS } from "../library/configuration.js";
|
|
15
17
|
import { assertExplicitRepoUse, resolveCliCoordinates } from "./coordinates.js";
|
|
16
18
|
import { BindDraftError, preserveBindDraft } from "./draft.js";
|
|
17
19
|
async function readStdin() {
|
|
@@ -23,9 +25,10 @@ async function readStdin() {
|
|
|
23
25
|
function selectedStdinDiagnostic(command) {
|
|
24
26
|
switch (command.command) {
|
|
25
27
|
case "bind":
|
|
26
|
-
case "amend":
|
|
27
28
|
case "arc":
|
|
28
29
|
return `${command.command} requires a nonblank stdin document`;
|
|
30
|
+
case "amend":
|
|
31
|
+
return command.stdin === true ? "amend requires a nonblank stdin document" : undefined;
|
|
29
32
|
case "review":
|
|
30
33
|
return command.summaryFromStdin === true ? "review requires a nonblank summary" : undefined;
|
|
31
34
|
case "call":
|
|
@@ -53,13 +56,12 @@ async function withAcquiredStdin(command, runtime) {
|
|
|
53
56
|
throw new CliUsageError(diagnostic);
|
|
54
57
|
return { ...runtime, readStdin: async () => bytes };
|
|
55
58
|
}
|
|
56
|
-
function settingsAt(root,
|
|
57
|
-
|
|
58
|
-
return settings({ ...(root === undefined ? {} : { root }), ...(home === undefined || home.length === 0 ? {} : { home }) });
|
|
59
|
+
function settingsAt(root, home) {
|
|
60
|
+
return settings({ ...(root === undefined ? {} : { root }), ...(home === undefined ? {} : { home }) });
|
|
59
61
|
}
|
|
60
|
-
function
|
|
62
|
+
function consumeSettings(run) {
|
|
61
63
|
try {
|
|
62
|
-
return
|
|
64
|
+
return run();
|
|
63
65
|
}
|
|
64
66
|
catch (error) {
|
|
65
67
|
if (error instanceof SettingsError)
|
|
@@ -67,25 +69,11 @@ function selectedGates(value, name) {
|
|
|
67
69
|
throw error;
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
|
-
function
|
|
71
|
-
|
|
72
|
-
return worktreeHooksFrom({ settings: value });
|
|
73
|
-
}
|
|
74
|
-
catch (error) {
|
|
75
|
-
if (error instanceof SettingsError)
|
|
76
|
-
throw new CliUsageError(error.message);
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
72
|
+
function selectedGates(value, names) {
|
|
73
|
+
return consumeSettings(() => gatesFrom({ settings: value, ...(names === undefined ? {} : { names }) }));
|
|
79
74
|
}
|
|
80
75
|
function selectedGitPolicy(value) {
|
|
81
|
-
|
|
82
|
-
return requireBranchesToBeUpToDateFrom({ settings: value });
|
|
83
|
-
}
|
|
84
|
-
catch (error) {
|
|
85
|
-
if (error instanceof SettingsError)
|
|
86
|
-
throw new CliUsageError(error.message);
|
|
87
|
-
throw error;
|
|
88
|
-
}
|
|
76
|
+
return consumeSettings(() => requireBranchesToBeUpToDateFrom({ settings: value }));
|
|
89
77
|
}
|
|
90
78
|
function actorFromEdge(actor, environment) {
|
|
91
79
|
let resolved;
|
|
@@ -97,6 +85,14 @@ function actorFromEdge(actor, environment) {
|
|
|
97
85
|
}
|
|
98
86
|
return resolved;
|
|
99
87
|
}
|
|
88
|
+
function gitPathFromEdge(environment) {
|
|
89
|
+
const value = environment.KEIYAKU_GIT_PATH;
|
|
90
|
+
if (value === undefined)
|
|
91
|
+
return undefined;
|
|
92
|
+
if (value.trim().length === 0)
|
|
93
|
+
throw new CliUsageError("KEIYAKU_GIT_PATH requires a nonblank value");
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
100
96
|
async function selectContract(repo, selector, scope) {
|
|
101
97
|
if (selector !== undefined && !selector.startsWith("@"))
|
|
102
98
|
return contractFromInput(repo, selector);
|
|
@@ -127,7 +123,7 @@ async function invokeBind({ parsed, repo, edge, configuration, hooks, establishW
|
|
|
127
123
|
const bound = accepted.facts.find((fact) => fact.kind === "bind");
|
|
128
124
|
if (bound === undefined || bound.kind !== "bind")
|
|
129
125
|
throw new Error("accepted bind is missing its bind fact");
|
|
130
|
-
return acceptedBind(accepted, bound.data.coordinates
|
|
126
|
+
return acceptedBind(accepted, bound.data.coordinates);
|
|
131
127
|
});
|
|
132
128
|
if (result.kind !== "refused")
|
|
133
129
|
return result;
|
|
@@ -176,17 +172,30 @@ async function invokeAudit(parsed, seat, requireBranchesToBeUpToDate) {
|
|
|
176
172
|
hooks: seat.hooks,
|
|
177
173
|
}), (result) => acceptedAudit(result, seat.id), { coordinate: seat.id });
|
|
178
174
|
}
|
|
179
|
-
async function
|
|
175
|
+
async function existingSeat({ parsed, repo, edge, scope, hooks }) {
|
|
180
176
|
const { id, contract } = await selectContract(repo, parsed.contract, scope);
|
|
181
177
|
const actor = actorFromEdge(parsed.actor, edge.environment);
|
|
182
|
-
|
|
178
|
+
return { contract, id, ...(actor === undefined ? {} : { actor }), hooks };
|
|
179
|
+
}
|
|
180
|
+
async function invokeExisting(input) {
|
|
181
|
+
const { parsed, repo, edge, configuration, hooks } = input;
|
|
182
|
+
const seat = await existingSeat(input);
|
|
183
|
+
const { id, contract, actor } = seat;
|
|
183
184
|
switch (parsed.command) {
|
|
184
185
|
case "amend": {
|
|
185
|
-
const markdown = await edge.readStdin();
|
|
186
|
+
const markdown = parsed.stdin === true ? await edge.readStdin() : undefined;
|
|
186
187
|
const gates = parsed.gates === undefined
|
|
187
188
|
? undefined
|
|
188
189
|
: selectedGates(configuration, parsed.gates);
|
|
189
|
-
return resultFromMutationCall("amend", () => amendFromCommand({
|
|
190
|
+
return resultFromMutationCall("amend", () => amendFromCommand({
|
|
191
|
+
command: parsed,
|
|
192
|
+
repo,
|
|
193
|
+
contract,
|
|
194
|
+
...(markdown === undefined ? {} : { markdown }),
|
|
195
|
+
gates,
|
|
196
|
+
...(actor === undefined ? {} : { actor }),
|
|
197
|
+
hooks,
|
|
198
|
+
}), (result) => acceptedAmend(result, id), { coordinate: id });
|
|
190
199
|
}
|
|
191
200
|
case "deliver":
|
|
192
201
|
return invokeDeliver(parsed, seat, selectedGitPolicy(configuration));
|
|
@@ -212,32 +221,23 @@ async function invokeExisting({ parsed, repo, edge, scope, configuration, hooks
|
|
|
212
221
|
return parsed;
|
|
213
222
|
}
|
|
214
223
|
}
|
|
215
|
-
async function
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
if (repo === undefined)
|
|
224
|
+
async function invokeAkumaFromEdge(parsed, input) {
|
|
225
|
+
try {
|
|
226
|
+
const { path, statedCwd, repo, home, configuration, edge } = input;
|
|
227
|
+
if (parsed.command === "call" && parsed.contract !== undefined && repo === undefined) {
|
|
219
228
|
throw new Error("call with Contract requires a resolved Repo");
|
|
220
|
-
|
|
229
|
+
}
|
|
221
230
|
return await invokeAkuma(parsed, {
|
|
222
231
|
path,
|
|
223
|
-
...(
|
|
224
|
-
|
|
225
|
-
|
|
232
|
+
...(statedCwd === undefined ? {} : { statedCwd }),
|
|
233
|
+
...(home === undefined ? {} : { home }),
|
|
234
|
+
...(configuration === undefined ? {} : { settings: configuration }),
|
|
235
|
+
...(parsed.command === "call" && parsed.contract !== undefined
|
|
236
|
+
? { contract: contractFromInput(repo, parsed.contract).contract }
|
|
237
|
+
: repo === undefined ? {} : { repo }),
|
|
226
238
|
readStdin: edge.readStdin,
|
|
227
239
|
});
|
|
228
240
|
}
|
|
229
|
-
return await invokeAkuma(parsed, {
|
|
230
|
-
path,
|
|
231
|
-
...(executionCwd === undefined ? {} : { executionCwd }),
|
|
232
|
-
settings: configuration,
|
|
233
|
-
...(repo === undefined ? {} : { repo }),
|
|
234
|
-
readStdin: edge.readStdin,
|
|
235
|
-
});
|
|
236
|
-
}
|
|
237
|
-
async function invokeAkumaFromEdge(parsed, input) {
|
|
238
|
-
try {
|
|
239
|
-
return await invokeAkumaCommand(parsed, input);
|
|
240
|
-
}
|
|
241
241
|
catch (error) {
|
|
242
242
|
if (error instanceof AkumaWorldScopeError)
|
|
243
243
|
throw error;
|
|
@@ -252,7 +252,7 @@ async function akumaWorldFor(parsed, located, candidate, establish) {
|
|
|
252
252
|
throw new CliUsageError("no Keiyaku world contains the invocation cwd");
|
|
253
253
|
return world;
|
|
254
254
|
}
|
|
255
|
-
async function invokeCatalog(parsed, world, repo,
|
|
255
|
+
async function invokeCatalog(parsed, world, repo, home) {
|
|
256
256
|
try {
|
|
257
257
|
if (parsed.query.kind === "contracts") {
|
|
258
258
|
if (repo === undefined)
|
|
@@ -262,7 +262,7 @@ async function invokeCatalog(parsed, world, repo, edge) {
|
|
|
262
262
|
if (parsed.query.kind === "archetypes") {
|
|
263
263
|
return {
|
|
264
264
|
kind: "catalog",
|
|
265
|
-
catalog: await Keiyaku.ls({ query: parsed.query,
|
|
265
|
+
catalog: await Keiyaku.ls({ query: parsed.query, ...(home === undefined ? {} : { home }) }),
|
|
266
266
|
};
|
|
267
267
|
}
|
|
268
268
|
if (world === null)
|
|
@@ -278,12 +278,11 @@ async function invokeCatalog(parsed, world, repo, edge) {
|
|
|
278
278
|
throw error;
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
-
async function invokeStatus(parsed, world, repo
|
|
282
|
-
const configuration = await settingsAt(world ?? undefined, edge.environment);
|
|
281
|
+
async function invokeStatus(parsed, world, repo) {
|
|
283
282
|
if (parsed.akuma === true) {
|
|
284
283
|
if (world === null)
|
|
285
284
|
throw new CliUsageError("no Keiyaku world contains the invocation cwd");
|
|
286
|
-
return invokeAkumaStatus(world, parsed.contract,
|
|
285
|
+
return invokeAkumaStatus(world, parsed.contract, undefined, repo);
|
|
287
286
|
}
|
|
288
287
|
if (parsed.contract === undefined) {
|
|
289
288
|
const report = await kanshi({ world, ...(repo === undefined ? {} : { repo }) });
|
|
@@ -291,18 +290,18 @@ async function invokeStatus(parsed, world, repo, edge) {
|
|
|
291
290
|
}
|
|
292
291
|
if (parsed.contract.startsWith("@")) {
|
|
293
292
|
try {
|
|
294
|
-
const
|
|
295
|
-
|
|
293
|
+
const observation = await observeKanshi({ world, ...(repo === undefined ? {} : { repo }) });
|
|
294
|
+
const address = resolveNamedAddress({
|
|
296
295
|
selector: parsed.contract,
|
|
297
|
-
|
|
296
|
+
report: observation.report,
|
|
297
|
+
aliases: observation.aliases,
|
|
298
298
|
});
|
|
299
299
|
if (address.kind === "akuma") {
|
|
300
300
|
if (world === null)
|
|
301
301
|
throw new CliUsageError("no Keiyaku world contains the invocation cwd");
|
|
302
|
-
return invokeAkumaStatus(world, address.id,
|
|
302
|
+
return invokeAkumaStatus(world, address.id, parsed.contract, repo);
|
|
303
303
|
}
|
|
304
|
-
|
|
305
|
-
return { kind: "status", report: selectKanshi({ report, contract: address.id }), selection: "contract" };
|
|
304
|
+
return { kind: "status", report: selectKanshi({ report: observation.report, contract: address.id }), selection: "contract" };
|
|
306
305
|
}
|
|
307
306
|
catch (error) {
|
|
308
307
|
if (error instanceof TypeError)
|
|
@@ -310,6 +309,16 @@ async function invokeStatus(parsed, world, repo, edge) {
|
|
|
310
309
|
throw error;
|
|
311
310
|
}
|
|
312
311
|
}
|
|
312
|
+
if (parsed.contract.startsWith("kei/")) {
|
|
313
|
+
if (repo === undefined)
|
|
314
|
+
throw new CliUsageError("cannot select a contract while the Contract world is absent");
|
|
315
|
+
const contract = canonicalContractSelector(parsed.contract);
|
|
316
|
+
return {
|
|
317
|
+
kind: "status",
|
|
318
|
+
report: await kanshi({ world, repo, contract }),
|
|
319
|
+
selection: "contract",
|
|
320
|
+
};
|
|
321
|
+
}
|
|
313
322
|
const report = await kanshi({ world, ...(repo === undefined ? {} : { repo }) });
|
|
314
323
|
const contract = resolveKanshiContract(report, parsed.contract);
|
|
315
324
|
return { kind: "status", report: selectKanshi({ report, contract }), selection: "contract" };
|
|
@@ -343,22 +352,43 @@ async function invokeRegion(parsed, world, repo) {
|
|
|
343
352
|
const selection = parsed.overlap ? { kind: "overlap", contract } : { kind: "contract", contract };
|
|
344
353
|
return { kind: "region", region: { kind: "present", value: selectRegion({ declarations: report.region.value.declarations, selection }) } };
|
|
345
354
|
}
|
|
355
|
+
async function invokeContractHistory(repo, contract) {
|
|
356
|
+
if (repo === undefined)
|
|
357
|
+
throw new Error("history kei/... requires a resolved Repo");
|
|
358
|
+
const selected = contractFromInput(repo, contract);
|
|
359
|
+
try {
|
|
360
|
+
return { kind: "contract-history", history: await selected.contract.history() };
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
if (error instanceof TypeError)
|
|
364
|
+
throw new CliUsageError(error.message);
|
|
365
|
+
if (error instanceof KeiyakuRefused) {
|
|
366
|
+
return { kind: "refused", verb: "history", contract: selected.id, refusal: error.refusal };
|
|
367
|
+
}
|
|
368
|
+
throw error;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
346
371
|
// eslint-disable-next-line complexity -- command dispatch keeps the CLI's existing boundary in one place.
|
|
347
372
|
async function invokeParsed(invocation, runtime) {
|
|
373
|
+
const environment = runtime.environment ?? process.env;
|
|
374
|
+
const gitPath = gitPathFromEdge(environment);
|
|
348
375
|
const coordinates = await resolveCliCoordinates({
|
|
349
376
|
...(runtime.cwd === undefined ? {} : { processCwd: runtime.cwd }),
|
|
350
377
|
...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
|
|
351
378
|
...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
|
|
379
|
+
...(gitPath === undefined ? {} : { gitPath }),
|
|
352
380
|
command: invocation.command,
|
|
353
381
|
});
|
|
354
|
-
const { cwd, repo, world, candidateWorld, establishWorld } = coordinates;
|
|
382
|
+
const { cwd, cwdSource, repo, world, candidateWorld, establishWorld } = coordinates;
|
|
355
383
|
const edge = {
|
|
356
384
|
environment: runtime.environment ?? process.env,
|
|
357
385
|
readStdin: runtime.readStdin ?? readStdin,
|
|
358
386
|
};
|
|
359
387
|
const parsed = invocation.command;
|
|
388
|
+
const mapped = edge.environment.KEIYAKU_HOME?.trim();
|
|
389
|
+
const home = mapped === undefined || mapped.length === 0 ? undefined : mapped;
|
|
360
390
|
if (parsed.command === "settings") {
|
|
361
|
-
return { kind: "settings", value: await settingsAt(world ?? undefined,
|
|
391
|
+
return { kind: "settings", value: await settingsAt(world ?? undefined, home) };
|
|
362
392
|
}
|
|
363
393
|
if (parsed.command === "task") {
|
|
364
394
|
try {
|
|
@@ -375,30 +405,37 @@ async function invokeParsed(invocation, runtime) {
|
|
|
375
405
|
throw error;
|
|
376
406
|
}
|
|
377
407
|
}
|
|
408
|
+
if (parsed.command === "history" && "contract" in parsed)
|
|
409
|
+
return await invokeContractHistory(repo, parsed.contract);
|
|
378
410
|
if (isParsedAkumaCommand(parsed)) {
|
|
379
411
|
const akumaWorld = await akumaWorldFor(parsed, world, candidateWorld, coordinates.establishWorld);
|
|
380
|
-
const configuration = await settingsAt(akumaWorld,
|
|
412
|
+
const configuration = parsed.command === "call" ? await settingsAt(akumaWorld, home) : undefined;
|
|
381
413
|
return await invokeAkumaFromEdge(parsed, {
|
|
382
414
|
path: akumaWorld,
|
|
383
|
-
...(
|
|
384
|
-
? {}
|
|
385
|
-
: { executionCwd: cwd }),
|
|
415
|
+
...(cwdSource === "input" ? { statedCwd: cwd } : {}),
|
|
386
416
|
...(repo === undefined ? {} : { repo }),
|
|
387
|
-
|
|
417
|
+
...(parsed.command === "call" && home !== undefined ? { home } : {}),
|
|
418
|
+
...(configuration === undefined ? {} : { configuration }),
|
|
388
419
|
edge,
|
|
389
420
|
});
|
|
390
421
|
}
|
|
391
422
|
if (parsed.command === "ls")
|
|
392
|
-
return await invokeCatalog(parsed, world, repo,
|
|
423
|
+
return await invokeCatalog(parsed, world, repo, home);
|
|
393
424
|
if (parsed.command === "status")
|
|
394
|
-
return await invokeStatus(parsed, world, repo
|
|
425
|
+
return await invokeStatus(parsed, world, repo);
|
|
395
426
|
if (repo === undefined)
|
|
396
427
|
throw new Error(`${parsed.command} requires a resolved Repo`);
|
|
397
428
|
if (parsed.command === "region")
|
|
398
429
|
return invokeRegion(parsed, world, repo);
|
|
399
430
|
const scope = cwd;
|
|
400
|
-
|
|
401
|
-
|
|
431
|
+
if ((parsed.command === "deliver" || parsed.command === "review") && injectedBodyRequests() !== null) {
|
|
432
|
+
const seat = await existingSeat({ parsed, repo, edge, scope, hooks: EMPTY_WORKTREE_HOOKS });
|
|
433
|
+
return parsed.command === "deliver"
|
|
434
|
+
? await invokeDeliver(parsed, seat, false)
|
|
435
|
+
: await invokeReview(parsed, seat, edge.readStdin);
|
|
436
|
+
}
|
|
437
|
+
const configuration = await settingsAt(world ?? undefined, home);
|
|
438
|
+
const hooks = consumeSettings(() => worktreeHooksFrom({ settings: configuration }));
|
|
402
439
|
if (parsed.command === "show") {
|
|
403
440
|
const selected = await selectContract(repo, parsed.contract, scope);
|
|
404
441
|
return { kind: "guidance", contract: selected.id, guidance: await selected.contract.guidance() };
|
|
@@ -427,13 +464,17 @@ export async function invoke(invocation, runtime = {}) {
|
|
|
427
464
|
try {
|
|
428
465
|
const command = invocation.command;
|
|
429
466
|
assertExplicitRepoUse(command, invocation.repo);
|
|
430
|
-
if (command.command === "install")
|
|
467
|
+
if (command.command === "install") {
|
|
468
|
+
runtime.onOperationStart?.();
|
|
431
469
|
return installHarnesses(command.harnesses, runtime.environment ?? process.env);
|
|
470
|
+
}
|
|
471
|
+
const acquiredRuntime = await withAcquiredStdin(command, withResolvedTaskActor(command, runtime));
|
|
472
|
+
runtime.onOperationStart?.();
|
|
432
473
|
return await invokeParsed({
|
|
433
474
|
...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
|
|
434
475
|
...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
|
|
435
476
|
command,
|
|
436
|
-
},
|
|
477
|
+
}, acquiredRuntime);
|
|
437
478
|
}
|
|
438
479
|
catch (error) {
|
|
439
480
|
if (error instanceof CliUsageError && error.projection === undefined) {
|
package/build/src/cli/main.d.ts
CHANGED
package/build/src/cli/main.js
CHANGED
|
@@ -28,7 +28,7 @@ function writeTask(command, result) {
|
|
|
28
28
|
return taskExitCode(result);
|
|
29
29
|
}
|
|
30
30
|
function writeAkuma(command, result) {
|
|
31
|
-
const output = command.output === "json" ? renderAkumaJson(
|
|
31
|
+
const output = command.output === "json" ? renderAkumaJson(result) : renderAkumaText(command, result, {
|
|
32
32
|
columns: process.stdout.isTTY === true && Number.isInteger(process.stdout.columns) ? process.stdout.columns : 80,
|
|
33
33
|
color: process.stdout.isTTY === true && process.env.NO_COLOR === undefined,
|
|
34
34
|
});
|
|
@@ -46,6 +46,18 @@ function renderHelp(coordinate) {
|
|
|
46
46
|
case "akuma": return renderAkumaHelp(coordinate.action);
|
|
47
47
|
}
|
|
48
48
|
}
|
|
49
|
+
export function invocationStart(command) {
|
|
50
|
+
if (command.output === "json")
|
|
51
|
+
return undefined;
|
|
52
|
+
switch (command.command) {
|
|
53
|
+
case "bind": return "⧖ preparing keiyaku";
|
|
54
|
+
case "deliver": return "⧖ delivering";
|
|
55
|
+
case "audit": return "⧖ auditing";
|
|
56
|
+
case "reconcile": return "⧖ reconciling";
|
|
57
|
+
case "install": return "⧖ installing skills";
|
|
58
|
+
default: return undefined;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
49
61
|
function writeGuidance(command, result) {
|
|
50
62
|
if (command.output === "json")
|
|
51
63
|
process.stdout.write(`${JSON.stringify({ contract: result.contract, guidance: result.guidance })}\n`);
|
|
@@ -71,8 +83,17 @@ function writeResult(command, result) {
|
|
|
71
83
|
process.stdout.write(`${command.output === "json" ? JSON.stringify(settingsJsonValue(value)) : renderSettingsText(value)}\n`);
|
|
72
84
|
return 0;
|
|
73
85
|
}
|
|
74
|
-
if (
|
|
75
|
-
|
|
86
|
+
if (typeof result === "object" && result !== null && "kind" in result && result.kind === "contract-history") {
|
|
87
|
+
const history = result.history;
|
|
88
|
+
const output = command.output === "json" ? JSON.stringify(history) : renderText(result);
|
|
89
|
+
process.stdout.write(`${output}\n`);
|
|
90
|
+
return 0;
|
|
91
|
+
}
|
|
92
|
+
const akumaResult = typeof result === "object" && result !== null && "kind" in result && result.kind === "akuma";
|
|
93
|
+
if (isParsedAkumaCommand(command)) {
|
|
94
|
+
return writeAkuma(command, result);
|
|
95
|
+
}
|
|
96
|
+
if (akumaResult && command.command === "status") {
|
|
76
97
|
return writeAkuma(command, result);
|
|
77
98
|
}
|
|
78
99
|
const contractResult = result;
|
|
@@ -111,7 +132,11 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
111
132
|
}
|
|
112
133
|
output = parsed.command.output;
|
|
113
134
|
const { invoke } = await import("./invoke.js");
|
|
114
|
-
const
|
|
135
|
+
const start = invocationStart(parsed.command);
|
|
136
|
+
const result = await invoke(parsed, {
|
|
137
|
+
cwd: process.cwd(),
|
|
138
|
+
...(start === undefined ? {} : { onOperationStart: () => { process.stderr.write(`${start}\n`); } }),
|
|
139
|
+
});
|
|
115
140
|
return writeResult(parsed.command, result);
|
|
116
141
|
}
|
|
117
142
|
catch (error) {
|
package/build/src/cli/parse.d.ts
CHANGED
|
@@ -20,14 +20,15 @@ export type ParsedBind = Output & Actor & Readonly<{
|
|
|
20
20
|
target?: string;
|
|
21
21
|
workspace?: "here";
|
|
22
22
|
after?: readonly string[];
|
|
23
|
-
gates?: string;
|
|
23
|
+
gates?: readonly string[];
|
|
24
24
|
}>;
|
|
25
25
|
export type ParsedAmend = Output & Actor & Readonly<{
|
|
26
26
|
command: "amend";
|
|
27
27
|
contract?: string;
|
|
28
28
|
after?: readonly string[];
|
|
29
29
|
clearAfter?: true;
|
|
30
|
-
gates?: string;
|
|
30
|
+
gates?: readonly string[];
|
|
31
|
+
stdin?: true;
|
|
31
32
|
}>;
|
|
32
33
|
export type ParsedDeliver = Output & Actor & Readonly<{
|
|
33
34
|
command: "deliver";
|
package/build/src/cli/parse.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isTaskAction, parseTaskCommand, renderTaskUsage, } from "./commands/task.js";
|
|
2
2
|
import { isAkumaAction, parseAkumaCatalogPath, parseAkumaCommand, renderAkumaRootRows, renderAkumaUsage, } from "./commands/akuma.js";
|
|
3
3
|
import { INSTALL_USAGE, parseInstallCommand, renderInstallHelp } from "./commands/install.js";
|
|
4
|
-
import { AMEND_MINIMAL_STDIN_HELP, CONTRACT_COMMAND_SPECS } from "./commands/contract.js";
|
|
4
|
+
import { AMEND_MINIMAL_STDIN_HELP, CONTRACT_COMMAND_SPECS, } from "./commands/contract.js";
|
|
5
5
|
import { CliUsageError, isBlankInput, usageLine, withJsonAutomationHelp } from "./usage.js";
|
|
6
6
|
export { CliUsageError } from "./usage.js";
|
|
7
7
|
const ROOT_USAGE = "usage: keiyaku [-C <path>] [--repo <path>] <command> [<contract>|@<contract>] [--flag ...] [-]";
|
|
@@ -69,9 +69,12 @@ function scanOption(command, argv, state, index) {
|
|
|
69
69
|
return index;
|
|
70
70
|
}
|
|
71
71
|
const value = argv[index + 1];
|
|
72
|
-
if (value === undefined
|
|
72
|
+
if (value === undefined)
|
|
73
73
|
refuse(command, `${token} requires a value`);
|
|
74
|
-
if (
|
|
74
|
+
if (kind !== "raw-value" && (value === "-" || value.startsWith("--"))) {
|
|
75
|
+
refuse(command, `${token} requires a value`);
|
|
76
|
+
}
|
|
77
|
+
if (kind !== "raw-value" && isBlankInput(value))
|
|
75
78
|
refuse(command, `${token} requires a nonblank value`);
|
|
76
79
|
if (kind === "repeat-value") {
|
|
77
80
|
const values = state.flags[name];
|
|
@@ -121,7 +124,7 @@ function parseBind(parts) {
|
|
|
121
124
|
const task = optionalFlag(parts.flags, "task");
|
|
122
125
|
const target = optionalFlag(parts.flags, "target");
|
|
123
126
|
const after = parts.flags.after === undefined ? [] : Array.isArray(parts.flags.after) ? parts.flags.after : [parts.flags.after];
|
|
124
|
-
const gates =
|
|
127
|
+
const gates = parseGateBundleNames(parts, "bind");
|
|
125
128
|
return {
|
|
126
129
|
command: "bind",
|
|
127
130
|
...(task === undefined ? {} : { task }),
|
|
@@ -138,7 +141,10 @@ function parseAmend(parts) {
|
|
|
138
141
|
const after = parts.flags.after === undefined ? [] : Array.isArray(parts.flags.after) ? parts.flags.after : [parts.flags.after];
|
|
139
142
|
if (parts.flags["clear-after"] === true && after.length > 0)
|
|
140
143
|
refuse("amend", "--clear-after and --after are mutually exclusive");
|
|
141
|
-
const gates =
|
|
144
|
+
const gates = parseGateBundleNames(parts, "amend");
|
|
145
|
+
if (!parts.stdin && parts.flags.after === undefined && parts.flags["clear-after"] !== true && gates === undefined) {
|
|
146
|
+
refuse("amend", "amend requires stdin or --after, --clear-after, or --gates");
|
|
147
|
+
}
|
|
142
148
|
return {
|
|
143
149
|
command: "amend",
|
|
144
150
|
...(contract === undefined ? {} : { contract }),
|
|
@@ -146,9 +152,20 @@ function parseAmend(parts) {
|
|
|
146
152
|
...(parts.flags["clear-after"] === true ? { clearAfter: true } : {}),
|
|
147
153
|
...(gates === undefined ? {} : { gates }),
|
|
148
154
|
...(parts.actor === undefined ? {} : { actor: parts.actor }),
|
|
155
|
+
...(parts.stdin ? { stdin: true } : {}),
|
|
149
156
|
output: parts.output,
|
|
150
157
|
};
|
|
151
158
|
}
|
|
159
|
+
function parseGateBundleNames(parts, command) {
|
|
160
|
+
const value = optionalFlag(parts.flags, "gates");
|
|
161
|
+
if (value === undefined)
|
|
162
|
+
return undefined;
|
|
163
|
+
const names = value.split(",");
|
|
164
|
+
if (names.some((name) => name.length === 0)) {
|
|
165
|
+
refuse(command, "--gates requires nonempty comma-separated names");
|
|
166
|
+
}
|
|
167
|
+
return names;
|
|
168
|
+
}
|
|
152
169
|
function parseDeliver(parts) {
|
|
153
170
|
const contract = parts.positionals[0];
|
|
154
171
|
const message = optionalFlag(parts.flags, "message");
|
|
@@ -236,14 +253,14 @@ function parseRegion(parts) {
|
|
|
236
253
|
}
|
|
237
254
|
function parseLs(parts) {
|
|
238
255
|
const path = parts.positionals[0];
|
|
239
|
-
if (path === "task/")
|
|
256
|
+
if (path === "task" || path === "task/")
|
|
240
257
|
return { command: "ls", query: { kind: "tasks" }, output: parts.output };
|
|
241
|
-
if (path === "kei/")
|
|
258
|
+
if (path === "kei" || path === "kei/")
|
|
242
259
|
return { command: "ls", query: { kind: "contracts" }, output: parts.output };
|
|
243
260
|
try {
|
|
244
261
|
const query = parseAkumaCatalogPath(path);
|
|
245
262
|
if (query === null)
|
|
246
|
-
refuse("ls", "ls requires
|
|
263
|
+
refuse("ls", "ls requires a supported identity directory selector");
|
|
247
264
|
return { command: "ls", query, output: parts.output };
|
|
248
265
|
}
|
|
249
266
|
catch (error) {
|
|
@@ -4,5 +4,5 @@ import { type TextRenderContext } from "./terminal.js";
|
|
|
4
4
|
export declare function akumaRawAnswer(result: AkumaInvocationResult): string | undefined;
|
|
5
5
|
export declare function renderAkumaText(command: ParsedCommand, result: AkumaInvocationResult, context?: TextRenderContext): string;
|
|
6
6
|
export declare function akumaExitCode(result: AkumaInvocationResult): number;
|
|
7
|
-
export declare function akumaJsonValue(
|
|
8
|
-
export declare function renderAkumaJson(
|
|
7
|
+
export declare function akumaJsonValue(result: AkumaInvocationResult): unknown;
|
|
8
|
+
export declare function renderAkumaJson(result: AkumaInvocationResult): string;
|