@astrosheep/keiyaku 4.5.19 → 4.5.21
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 +4 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku/SKILL.md +14 -7
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +53 -20
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/references/automation.md +237 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +6 -7
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +2 -4
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +3 -3
- package/build/src/akuma/akuma-handle.d.ts +5 -1
- package/build/src/akuma/akuma-handle.js +4 -1
- package/build/src/akuma/akuma-instance.d.ts +7 -2
- package/build/src/akuma/akuma-instance.js +14 -7
- package/build/src/akuma/akuma-observe.d.ts +11 -0
- package/build/src/akuma/akuma-observe.js +23 -0
- package/build/src/akuma/akuma-product.d.ts +2 -0
- package/build/src/akuma/akuma-product.js +6 -0
- package/build/src/akuma/akuma.d.ts +20 -1
- package/build/src/akuma/akuma.js +2 -0
- package/build/src/akuma/allowed.d.ts +20 -0
- package/build/src/akuma/allowed.js +11 -0
- package/build/src/akuma/archetype.js +3 -0
- package/build/src/akuma/body.d.ts +25 -5
- package/build/src/akuma/body.js +70 -31
- package/build/src/akuma/call-request.d.ts +5 -0
- package/build/src/akuma/call-request.js +14 -4
- package/build/src/akuma/fleet-execution.d.ts +28 -0
- package/build/src/akuma/fleet-execution.js +36 -4
- package/build/src/akuma/fleet-observation.d.ts +54 -0
- package/build/src/akuma/fleet-request.d.ts +10 -0
- package/build/src/akuma/fleet-request.js +13 -3
- package/build/src/akuma/heart/facts.d.ts +2 -0
- package/build/src/akuma/heart/index.d.ts +1 -0
- package/build/src/akuma/heart/index.js +4 -1
- package/build/src/akuma/heart/rows.d.ts +2 -0
- package/build/src/akuma/heart/rows.js +7 -5
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +3 -1
- package/build/src/akuma/heart/tells.js +6 -5
- package/build/src/akuma/heart/timeline.js +1 -1
- package/build/src/akuma/provider-recipe.d.ts +1 -0
- package/build/src/akuma/provider-recipe.js +5 -0
- package/build/src/akuma/provider.d.ts +1 -1
- package/build/src/akuma/provider.js +1 -1
- package/build/src/akuma/providers/acp/core.js +3 -6
- package/build/src/akuma/providers/acp/index.js +3 -0
- package/build/src/akuma/providers/claude/index.js +10 -10
- package/build/src/akuma/providers/codex-app-server/index.js +12 -11
- package/build/src/akuma/providers/execution-environment.d.ts +6 -0
- package/build/src/akuma/providers/execution-environment.js +24 -0
- package/build/src/akuma/providers/grok-build/index.js +3 -0
- package/build/src/akuma/providers/opencode-sdk/index.js +32 -23
- package/build/src/akuma/providers/opencode-sdk/session.d.ts +8 -1
- package/build/src/akuma/providers/opencode-sdk/session.js +6 -5
- package/build/src/akuma/providers/pi/events.js +7 -2
- package/build/src/akuma/providers/pi/index.js +5 -2
- package/build/src/akuma/request-observation.d.ts +45 -0
- package/build/src/akuma/request-observation.js +162 -0
- package/build/src/akuma/request-rendezvous.d.ts +6 -3
- package/build/src/akuma/request-rendezvous.js +80 -14
- package/build/src/akuma/request-serve.js +27 -4
- package/build/src/akuma/request-wire.d.ts +5 -0
- package/build/src/akuma/request-wire.js +2 -0
- package/build/src/akuma/turn-drive.d.ts +1 -0
- package/build/src/akuma/turn-drive.js +2 -0
- package/build/src/akuma-body.js +5 -0
- package/build/src/body/amend.js +6 -4
- package/build/src/body/decode.d.ts +3 -1
- package/build/src/body/decode.js +53 -17
- package/build/src/body/region.d.ts +9 -1
- package/build/src/body/region.js +87 -12
- package/build/src/body/render.js +1 -1
- package/build/src/body/verification.d.ts +3 -1
- package/build/src/body/verification.js +4 -1
- package/build/src/cli/accepted.js +19 -2
- package/build/src/cli/commands/akuma-invoke.d.ts +3 -1
- package/build/src/cli/commands/akuma-invoke.js +134 -14
- package/build/src/cli/commands/akuma.js +24 -12
- package/build/src/cli/commands/contract-help.d.ts +15 -15
- package/build/src/cli/commands/contract-help.js +45 -19
- package/build/src/cli/commands/contract-invoke.d.ts +3 -0
- package/build/src/cli/commands/contract-invoke.js +25 -11
- package/build/src/cli/commands/contract.js +6 -4
- package/build/src/cli/commands/install.d.ts +1 -1
- package/build/src/cli/commands/install.js +1 -1
- package/build/src/cli/commands/status-set.js +15 -24
- package/build/src/cli/commands/task.js +18 -18
- package/build/src/cli/invoke.d.ts +3 -0
- package/build/src/cli/invoke.js +58 -23
- package/build/src/cli/main.js +5 -0
- package/build/src/cli/parse.d.ts +3 -0
- package/build/src/cli/parse.js +26 -4
- package/build/src/cli/render/akuma-activity.d.ts +100 -2
- package/build/src/cli/render/akuma-activity.js +485 -40
- package/build/src/cli/render/akuma.d.ts +10 -0
- package/build/src/cli/render/akuma.js +31 -21
- package/build/src/cli/render/audit.js +1 -1
- package/build/src/cli/render/board.js +1 -1
- package/build/src/cli/render/catalog.js +16 -13
- package/build/src/cli/render/contract-history.js +39 -10
- package/build/src/cli/render/contract-observation.js +10 -6
- package/build/src/cli/render/contract.js +109 -106
- package/build/src/cli/render/execution-progress.d.ts +26 -0
- package/build/src/cli/render/execution-progress.js +178 -0
- package/build/src/cli/render/kanshi-akuma.js +27 -39
- package/build/src/cli/render/kanshi.js +33 -26
- package/build/src/cli/render/nuke.js +1 -1
- package/build/src/cli/render/receipt.d.ts +1 -1
- package/build/src/cli/render/receipt.js +6 -6
- package/build/src/cli/render/refusal.js +10 -7
- package/build/src/cli/render/region.js +1 -1
- package/build/src/cli/render/settings.js +12 -2
- package/build/src/cli/render/status-line.d.ts +30 -0
- package/build/src/cli/render/status-line.js +58 -0
- package/build/src/cli/render/status-set.js +1 -1
- package/build/src/cli/render/task.d.ts +2 -0
- package/build/src/cli/render/task.js +11 -7
- package/build/src/cli/render/terminal.d.ts +0 -1
- package/build/src/cli/render/terminal.js +47 -15
- package/build/src/cli/result.d.ts +1 -0
- package/build/src/cli/runtime.d.ts +2 -0
- package/build/src/cli/runtime.js +36 -4
- package/build/src/cli/usage.js +2 -2
- package/build/src/cli/version.d.ts +1 -0
- package/build/src/cli/version.js +25 -0
- package/build/src/git/hooks.d.ts +13 -1
- package/build/src/git/hooks.js +2 -1
- package/build/src/git/workspace.d.ts +1 -1
- package/build/src/git/workspace.js +1 -1
- package/build/src/identity/mint.d.ts +13 -0
- package/build/src/identity/mint.js +26 -0
- package/build/src/identity/normalize.d.ts +4 -0
- package/build/src/identity/normalize.js +30 -0
- package/build/src/index.d.ts +2 -0
- package/build/src/index.js +1 -0
- package/build/src/kanshi/read.js +17 -4
- package/build/src/kanshi/report.d.ts +1 -0
- package/build/src/library/akuma-creation.d.ts +2 -0
- package/build/src/library/akuma-creation.js +34 -18
- package/build/src/library/audit.d.ts +2 -0
- package/build/src/library/audit.js +1 -0
- package/build/src/library/bind.js +18 -16
- package/build/src/library/composition.d.ts +1 -0
- package/build/src/library/contract-bind.d.ts +3 -1
- package/build/src/library/contract-bind.js +5 -3
- package/build/src/library/contract-execution.d.ts +2 -0
- package/build/src/library/contract-execution.js +15 -1
- package/build/src/library/contract-forwarding.d.ts +4 -0
- package/build/src/library/contract-forwarding.js +3 -0
- package/build/src/library/contract-handle.d.ts +7 -0
- package/build/src/library/contract-handle.js +25 -0
- package/build/src/library/contract-operations.d.ts +7 -2
- package/build/src/library/contract-operations.js +21 -1
- package/build/src/library/contract-types.d.ts +1 -0
- package/build/src/library/execution-result.d.ts +2 -2
- package/build/src/library/execution.d.ts +8 -0
- package/build/src/library/execution.js +102 -0
- package/build/src/library/fleet.d.ts +4 -1
- package/build/src/library/fleet.js +32 -8
- package/build/src/library/keiyaku.d.ts +2 -0
- package/build/src/library/mutation.js +15 -7
- package/build/src/plugin/akuma-signals.d.ts +6 -0
- package/build/src/plugin/akuma-signals.js +9 -1
- package/build/src/plugin/public.d.ts +6 -2
- package/build/src/plugin/runtime.d.ts +1 -3
- package/build/src/plugin/runtime.js +95 -103
- package/build/src/protocol/amend.js +4 -3
- package/build/src/protocol/attempt.d.ts +2 -0
- package/build/src/protocol/bind.js +41 -14
- package/build/src/protocol/completion.d.ts +3 -0
- package/build/src/protocol/completion.js +35 -11
- package/build/src/protocol/deliver.js +165 -92
- package/build/src/protocol/execution-observation.d.ts +181 -0
- package/build/src/protocol/execution-observation.js +45 -0
- package/build/src/protocol/intent.d.ts +18 -22
- package/build/src/protocol/intent.js +63 -41
- package/build/src/protocol/operations.d.ts +2 -0
- package/build/src/protocol/placement.js +5 -1
- package/build/src/protocol/progress.d.ts +5 -1
- package/build/src/protocol/progress.js +10 -1
- package/build/src/protocol/read/status.d.ts +1 -0
- package/build/src/protocol/read/status.js +10 -2
- package/build/src/protocol/reintegrate.d.ts +1 -1
- package/build/src/protocol/reintegrate.js +70 -43
- package/build/src/protocol/result-codec.js +27 -11
- package/build/src/protocol/review.js +53 -30
- package/build/src/protocol/run.d.ts +83 -36
- package/build/src/protocol/run.js +90 -75
- package/build/src/runtime/proc/run.d.ts +16 -4
- package/build/src/runtime/proc/run.js +64 -22
- package/build/src/runtime/proc/windows-launch.exe +0 -0
- package/build/src/settings.js +5 -14
- package/build/src/task/document.d.ts +5 -1
- package/build/src/task/document.js +6 -1
- package/build/src/verification/execution.d.ts +10 -2
- package/build/src/verification/execution.js +143 -42
- package/build/src/verification/observation.d.ts +41 -0
- package/build/src/verification/observation.js +29 -0
- package/package.json +3 -1
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import { resolveActor } from "../actor.js";
|
|
2
2
|
import { CliUsageError } from "../usage.js";
|
|
3
|
+
async function consumeExecution(execution, edge) {
|
|
4
|
+
const observation = edge.progress === undefined ? undefined : Promise.resolve().then(() => edge.progress(execution.progress));
|
|
5
|
+
void observation?.catch(() => undefined);
|
|
6
|
+
try {
|
|
7
|
+
return await execution.result;
|
|
8
|
+
}
|
|
9
|
+
finally {
|
|
10
|
+
await observation?.catch(() => undefined);
|
|
11
|
+
}
|
|
12
|
+
}
|
|
3
13
|
function actorFromEdge(actor, environment) {
|
|
4
14
|
try {
|
|
5
15
|
return resolveActor({ env: environment, ...(actor === undefined ? {} : { actor }) });
|
|
@@ -141,15 +151,16 @@ async function existingSeat(input, parsed, library) {
|
|
|
141
151
|
const actor = "actor" in parsed ? actorFromEdge(parsed.actor, edge.environment) : undefined;
|
|
142
152
|
return { contract, id, ...(actor === undefined ? {} : { actor }), ...(hooks === undefined ? {} : { hooks }) };
|
|
143
153
|
}
|
|
144
|
-
async function invokeDeliver(parsed, seat) {
|
|
154
|
+
async function invokeDeliver(parsed, seat, edge) {
|
|
145
155
|
const { acceptedDeliver } = await import("../accepted.js");
|
|
146
156
|
try {
|
|
147
|
-
const delivered = await seat.contract.
|
|
157
|
+
const delivered = await consumeExecution(seat.contract.startDelivery({
|
|
148
158
|
...(parsed.message === undefined ? {} : { message: parsed.message }),
|
|
149
159
|
includeDirty: parsed.includeDirty,
|
|
150
160
|
materializeConflict: parsed.materializeConflict,
|
|
151
161
|
overwrite: parsed.overwrite,
|
|
152
|
-
|
|
162
|
+
...(edge.signal === undefined ? {} : { signal: edge.signal }),
|
|
163
|
+
}), edge);
|
|
153
164
|
if (!("facts" in delivered))
|
|
154
165
|
return delivered;
|
|
155
166
|
return acceptedDeliver(delivered, seat.id);
|
|
@@ -166,13 +177,15 @@ async function invokeDeliver(parsed, seat) {
|
|
|
166
177
|
throw error;
|
|
167
178
|
}
|
|
168
179
|
}
|
|
169
|
-
async function invokeReview(parsed, seat,
|
|
170
|
-
const summary = parsed.summaryFromStdin === true ? await readStdin() : parsed.summary;
|
|
180
|
+
async function invokeReview(parsed, seat, edge) {
|
|
181
|
+
const summary = parsed.summaryFromStdin === true ? await edge.readStdin() : parsed.summary;
|
|
171
182
|
const { acceptedReview, resultFromMutationCall } = await import("../accepted.js");
|
|
172
|
-
|
|
183
|
+
const input = {
|
|
173
184
|
verdict: parsed.verdict,
|
|
174
185
|
...(summary === undefined ? {} : { summary }),
|
|
175
|
-
|
|
186
|
+
...(edge.signal === undefined ? {} : { signal: edge.signal }),
|
|
187
|
+
};
|
|
188
|
+
return resultFromMutationCall("review", () => consumeExecution(seat.contract.startReview(input), edge), (result) => acceptedReview(result, seat.id), { coordinate: seat.id });
|
|
176
189
|
}
|
|
177
190
|
async function contractLibrary(input, parsed) {
|
|
178
191
|
const { configuration, edge, hooks } = input;
|
|
@@ -214,9 +227,9 @@ export async function invokeContractMutation(input) {
|
|
|
214
227
|
}), (result) => acceptedAmend(result, id), { coordinate: id });
|
|
215
228
|
}
|
|
216
229
|
case "deliver":
|
|
217
|
-
return invokeDeliver(parsed, seat);
|
|
230
|
+
return invokeDeliver(parsed, seat, edge);
|
|
218
231
|
case "review":
|
|
219
|
-
return invokeReview(parsed, seat, edge
|
|
232
|
+
return invokeReview(parsed, seat, edge);
|
|
220
233
|
case "arc": {
|
|
221
234
|
const markdown = await edge.readStdin();
|
|
222
235
|
const { acceptedArc, resultFromMutationCall } = await import("../accepted.js");
|
|
@@ -236,10 +249,11 @@ export async function invokeContractMutation(input) {
|
|
|
236
249
|
}
|
|
237
250
|
case "audit": {
|
|
238
251
|
const { acceptedAudit, resultFromMutationCall } = await import("../accepted.js");
|
|
239
|
-
return resultFromMutationCall("audit", () => contract.
|
|
252
|
+
return resultFromMutationCall("audit", () => consumeExecution(contract.startAudit({
|
|
240
253
|
includeDirty: parsed.includeDirty,
|
|
241
254
|
showDiff: parsed.showDiff,
|
|
242
|
-
|
|
255
|
+
...(edge.signal === undefined ? {} : { signal: edge.signal }),
|
|
256
|
+
}), edge), (result) => acceptedAudit(result, id), { coordinate: id });
|
|
243
257
|
}
|
|
244
258
|
}
|
|
245
259
|
}
|
|
@@ -20,13 +20,15 @@ function optionalFlag(flags, name) {
|
|
|
20
20
|
function refuse(command, message) {
|
|
21
21
|
throw new CliUsageError(message, commandGuide(command, CONTRACT_COMMAND_SPECS[command].usage));
|
|
22
22
|
}
|
|
23
|
-
function
|
|
23
|
+
function parseGateNames(parts, command) {
|
|
24
24
|
const value = optionalFlag(parts.flags, "gates");
|
|
25
25
|
if (value === undefined)
|
|
26
26
|
return undefined;
|
|
27
|
+
if (value === "")
|
|
28
|
+
return [];
|
|
27
29
|
const names = value.split(",");
|
|
28
30
|
if (names.some((name) => name.length === 0)) {
|
|
29
|
-
refuse(command,
|
|
31
|
+
refuse(command, '--gates requires comma-separated names or "" to clear gates');
|
|
30
32
|
}
|
|
31
33
|
return names;
|
|
32
34
|
}
|
|
@@ -53,7 +55,7 @@ function parseBind(parts) {
|
|
|
53
55
|
const task = optionalFlag(parts.flags, "task");
|
|
54
56
|
const target = optionalFlag(parts.flags, "target");
|
|
55
57
|
const after = parts.flags.after === undefined ? [] : Array.isArray(parts.flags.after) ? parts.flags.after : [parts.flags.after];
|
|
56
|
-
const gates =
|
|
58
|
+
const gates = parseGateNames(parts, "bind");
|
|
57
59
|
return {
|
|
58
60
|
command: "bind",
|
|
59
61
|
...(task === undefined ? {} : { task }),
|
|
@@ -69,7 +71,7 @@ function parseAmend(parts) {
|
|
|
69
71
|
const after = parts.flags.after === undefined ? [] : Array.isArray(parts.flags.after) ? parts.flags.after : [parts.flags.after];
|
|
70
72
|
if (parts.flags["clear-after"] === true && after.length > 0)
|
|
71
73
|
refuse("amend", "--clear-after and --after are mutually exclusive");
|
|
72
|
-
const gates =
|
|
74
|
+
const gates = parseGateNames(parts, "amend");
|
|
73
75
|
if (!parts.stdin && parts.flags.after === undefined && parts.flags["clear-after"] !== true && gates === undefined) {
|
|
74
76
|
refuse("amend", "amend requires stdin or --after, --clear-after, or --gates");
|
|
75
77
|
}
|
|
@@ -16,7 +16,7 @@ export type InstallInvocationResult = Readonly<{
|
|
|
16
16
|
results: readonly HarnessInstallResult[];
|
|
17
17
|
}>;
|
|
18
18
|
export type InstallRunner = (input: ProcessInput) => Promise<ProcessOutcome>;
|
|
19
|
-
export declare const INSTALL_USAGE = "install <codex|claude|opencode|pi
|
|
19
|
+
export declare const INSTALL_USAGE = "install <codex|claude|opencode|pi>\ninstall --all";
|
|
20
20
|
export declare const INSTALL_ROOT_PURPOSE = "Install Keiyaku into coding harnesses";
|
|
21
21
|
export declare function parseInstallCommand(argv: readonly string[]): ParsedInstallCommand;
|
|
22
22
|
export declare function renderInstallHelp(): string;
|
|
@@ -2,7 +2,7 @@ import { dirname, resolve } from "node:path";
|
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
3
|
import { CliUsageError, commandGuide, usageLine } from "../usage.js";
|
|
4
4
|
export const HARNESS_NAMES = ["codex", "claude", "opencode", "pi"];
|
|
5
|
-
export const INSTALL_USAGE = "install <codex|claude|opencode|pi
|
|
5
|
+
export const INSTALL_USAGE = "install <codex|claude|opencode|pi>\ninstall --all";
|
|
6
6
|
export const INSTALL_ROOT_PURPOSE = "Install Keiyaku into coding harnesses";
|
|
7
7
|
function isHarness(value) {
|
|
8
8
|
return value !== undefined && HARNESS_NAMES.includes(value);
|
|
@@ -13,33 +13,25 @@ async function statusSetAkuma(selector, id, alias, world, repo) {
|
|
|
13
13
|
...(result.alias === undefined ? {} : { alias: result.alias }),
|
|
14
14
|
};
|
|
15
15
|
}
|
|
16
|
-
async function
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
async function statusSetContract(selector, id, world, repo) {
|
|
17
|
+
if (repo === undefined)
|
|
18
|
+
throw new CliUsageError("cannot select a contract while the Contract world is absent");
|
|
19
|
+
const observation = await (await import("../../kanshi/index.js")).observeKanshi({ world, repo, contract: canonicalContractSelector(id) });
|
|
20
|
+
return { selector, kind: "contract", report: observation.report };
|
|
21
|
+
}
|
|
22
|
+
async function statusSetEntry(selector, world, repo, named) {
|
|
19
23
|
if (selector.startsWith("@")) {
|
|
20
|
-
if (
|
|
24
|
+
if (named === undefined)
|
|
21
25
|
throw new CliUsageError("cannot resolve a named status selector");
|
|
22
26
|
const { resolveNamedAddress } = await import("../../library/address.js");
|
|
23
|
-
const address = resolveNamedAddress({ selector, report:
|
|
27
|
+
const address = resolveNamedAddress({ selector, report: named.report, aliases: named.aliases });
|
|
24
28
|
if (address.kind === "akuma")
|
|
25
29
|
return await statusSetAkuma(selector, address.id, selector, world, repo);
|
|
26
|
-
|
|
27
|
-
alias = selector;
|
|
30
|
+
return await statusSetContract(selector, address.id, world, repo);
|
|
28
31
|
}
|
|
29
|
-
if (
|
|
30
|
-
return await statusSetAkuma(selector,
|
|
31
|
-
|
|
32
|
-
throw new CliUsageError("cannot select a contract while the Contract world is absent");
|
|
33
|
-
if (observed === undefined)
|
|
34
|
-
throw new CliUsageError("cannot observe Contract status without a Kanshi report");
|
|
35
|
-
return {
|
|
36
|
-
selector,
|
|
37
|
-
kind: "contract",
|
|
38
|
-
report: (await import("../../kanshi/index.js")).selectKanshi({
|
|
39
|
-
report: observed.report,
|
|
40
|
-
contract: canonicalContractSelector(resolved),
|
|
41
|
-
}),
|
|
42
|
-
};
|
|
32
|
+
if (selector.startsWith("aku/"))
|
|
33
|
+
return await statusSetAkuma(selector, selector, undefined, world, repo);
|
|
34
|
+
return await statusSetContract(selector, selector, world, repo);
|
|
43
35
|
}
|
|
44
36
|
export async function invokeStatusSet(selectors, world, repo) {
|
|
45
37
|
if (selectors.length < 2)
|
|
@@ -47,8 +39,7 @@ export async function invokeStatusSet(selectors, world, repo) {
|
|
|
47
39
|
if (selectors.some((selector) => !selector.startsWith("aku/") && !selector.startsWith("@")) && repo === undefined) {
|
|
48
40
|
throw new CliUsageError("cannot select a contract while the Contract world is absent");
|
|
49
41
|
}
|
|
50
|
-
const
|
|
51
|
-
const observed = needsKanshi
|
|
42
|
+
const named = selectors.some((selector) => selector.startsWith("@"))
|
|
52
43
|
? await (await import("../../kanshi/index.js")).observeKanshi({
|
|
53
44
|
world,
|
|
54
45
|
...(repo === undefined ? {} : { repo }),
|
|
@@ -56,6 +47,6 @@ export async function invokeStatusSet(selectors, world, repo) {
|
|
|
56
47
|
: undefined;
|
|
57
48
|
const entries = [];
|
|
58
49
|
for (const selector of selectors)
|
|
59
|
-
entries.push(await statusSetEntry(selector, world, repo,
|
|
50
|
+
entries.push(await statusSetEntry(selector, world, repo, named));
|
|
60
51
|
return { kind: "status-set", entries };
|
|
61
52
|
}
|
|
@@ -19,39 +19,39 @@ const TASK_COMMAND_SPECS = {
|
|
|
19
19
|
note: "value",
|
|
20
20
|
actor: "value",
|
|
21
21
|
},
|
|
22
|
-
usage: `task add <TITLE> [--namespace <ns>] [--priority 0..3]
|
|
22
|
+
usage: `task add <TITLE> [--namespace <ns>] [--priority 0..3]
|
|
23
23
|
[--state open|in_progress|on_hold|done|drop]
|
|
24
24
|
[--note <text>] [--actor <actor>]
|
|
25
25
|
[--needs <TaskId>]... [--parent <TaskId>]
|
|
26
26
|
[--supersedes <TaskId>]... [--relates <TaskId>]...
|
|
27
27
|
[--body <text>]
|
|
28
|
-
task add [--namespace <ns>] [--actor <actor>]
|
|
28
|
+
task add [--namespace <ns>] [--actor <actor>] -`,
|
|
29
29
|
purpose: "Create one Task from flags or a canonical stdin document.",
|
|
30
30
|
},
|
|
31
31
|
show: {
|
|
32
32
|
arity: [1, Number.POSITIVE_INFINITY],
|
|
33
33
|
flags: COMMON,
|
|
34
|
-
usage: "task show <TaskId>...
|
|
34
|
+
usage: "task show <TaskId>...",
|
|
35
35
|
purpose: "Read one or more Tasks and their relationships.",
|
|
36
36
|
},
|
|
37
37
|
ls: {
|
|
38
38
|
arity: [0, 1],
|
|
39
39
|
flags: { ...COMMON, closed: "boolean", all: "boolean", world: "boolean", limit: "value" },
|
|
40
|
-
usage: "task ls [<namespace-selector>] [--closed | --all] [--world] [--limit <n>]
|
|
40
|
+
usage: "task ls [<namespace-selector>] [--closed | --all] [--world] [--limit <n>]",
|
|
41
41
|
purpose: "List Tasks in the selected scope.",
|
|
42
42
|
details: "--world lists every namespace in the current Task world.",
|
|
43
43
|
},
|
|
44
44
|
ready: {
|
|
45
45
|
arity: [0, 0],
|
|
46
46
|
flags: { ...COMMON, world: "boolean", parent: "value", limit: "value" },
|
|
47
|
-
usage: "task ready [--world] [--parent <TaskId>] [--limit <n>]
|
|
47
|
+
usage: "task ready [--world] [--parent <TaskId>] [--limit <n>]",
|
|
48
48
|
purpose: "List open Tasks whose every need is terminal.",
|
|
49
49
|
details: "--world lists every namespace in the current Task world.",
|
|
50
50
|
},
|
|
51
51
|
blocked: {
|
|
52
52
|
arity: [0, 0],
|
|
53
53
|
flags: { ...COMMON, world: "boolean", parent: "value", limit: "value" },
|
|
54
|
-
usage: "task blocked [--world] [--parent <TaskId>] [--limit <n>]
|
|
54
|
+
usage: "task blocked [--world] [--parent <TaskId>] [--limit <n>]",
|
|
55
55
|
purpose: "List Tasks blocked by dependencies.",
|
|
56
56
|
details: "--world lists every namespace in the current Task world.",
|
|
57
57
|
},
|
|
@@ -59,7 +59,7 @@ task add [--namespace <ns>] [--actor <actor>] [--json] -`,
|
|
|
59
59
|
arity: [0, 0],
|
|
60
60
|
flags: { ...COMMON, where: "value", world: "boolean", sort: "value", limit: "value" },
|
|
61
61
|
usage: `task query [--where <expression>] [--world]
|
|
62
|
-
[--sort priority|created|updated|id] [--limit <n>]
|
|
62
|
+
[--sort priority|created|updated|id] [--limit <n>]`,
|
|
63
63
|
purpose: "Query Task facts with a typed boolean expression.",
|
|
64
64
|
details: [
|
|
65
65
|
"fields: state priority title id parent under needs blocks ready blocked created updated",
|
|
@@ -73,13 +73,13 @@ task add [--namespace <ns>] [--actor <actor>] [--json] -`,
|
|
|
73
73
|
tree: {
|
|
74
74
|
arity: [1, 1],
|
|
75
75
|
flags: COMMON,
|
|
76
|
-
usage: "task tree <TaskId>
|
|
76
|
+
usage: "task tree <TaskId>",
|
|
77
77
|
purpose: "Read one Task parent decomposition tree.",
|
|
78
78
|
},
|
|
79
79
|
doctor: {
|
|
80
80
|
arity: [0, 0],
|
|
81
81
|
flags: COMMON,
|
|
82
|
-
usage: "task doctor
|
|
82
|
+
usage: "task doctor",
|
|
83
83
|
purpose: "Inspect Task authority without repairing it.",
|
|
84
84
|
},
|
|
85
85
|
update: {
|
|
@@ -105,56 +105,56 @@ task add [--namespace <ns>] [--actor <actor>] [--json] -`,
|
|
|
105
105
|
[--priority 0..3] [--needs <TaskId>]... [--drop-needs <TaskId>]...
|
|
106
106
|
[--parent <TaskId> | --no-parent]
|
|
107
107
|
[--supersedes <TaskId>]... [--drop-supersedes <TaskId>]...
|
|
108
|
-
[--relates <TaskId>]... [--drop-relates <TaskId>]
|
|
108
|
+
[--relates <TaskId>]... [--drop-relates <TaskId>]...`,
|
|
109
109
|
purpose: "Apply one or more patches to a Task.",
|
|
110
110
|
},
|
|
111
111
|
start: {
|
|
112
112
|
arity: [1, Number.POSITIVE_INFINITY],
|
|
113
113
|
flags: COMMON,
|
|
114
|
-
usage: "task start <TaskId>...
|
|
114
|
+
usage: "task start <TaskId>...",
|
|
115
115
|
purpose: "Move one or more open Tasks into progress.",
|
|
116
116
|
},
|
|
117
117
|
stop: {
|
|
118
118
|
arity: [1, 1],
|
|
119
119
|
flags: COMMON,
|
|
120
|
-
usage: "task stop <TaskId>
|
|
120
|
+
usage: "task stop <TaskId>",
|
|
121
121
|
purpose: "Return one in-progress Task to open.",
|
|
122
122
|
},
|
|
123
123
|
hold: {
|
|
124
124
|
arity: [1, Number.POSITIVE_INFINITY],
|
|
125
125
|
flags: COMMON,
|
|
126
|
-
usage: "task hold <TaskId>...
|
|
126
|
+
usage: "task hold <TaskId>...",
|
|
127
127
|
purpose: "Put one or more Tasks on hold.",
|
|
128
128
|
},
|
|
129
129
|
resume: {
|
|
130
130
|
arity: [1, 1],
|
|
131
131
|
flags: COMMON,
|
|
132
|
-
usage: "task resume <TaskId>
|
|
132
|
+
usage: "task resume <TaskId>",
|
|
133
133
|
purpose: "Return one held Task to open.",
|
|
134
134
|
},
|
|
135
135
|
done: {
|
|
136
136
|
arity: [1, Number.POSITIVE_INFINITY],
|
|
137
137
|
flags: { ...COMMON, note: "value" },
|
|
138
|
-
usage: "task done <TaskId>... [--note <text>]
|
|
138
|
+
usage: "task done <TaskId>... [--note <text>]",
|
|
139
139
|
purpose: "Mark one or more Tasks done.",
|
|
140
140
|
},
|
|
141
141
|
drop: {
|
|
142
142
|
arity: [1, Number.POSITIVE_INFINITY],
|
|
143
143
|
flags: { ...COMMON, note: "value" },
|
|
144
|
-
usage: "task drop <TaskId>... [--note <text>]
|
|
144
|
+
usage: "task drop <TaskId>... [--note <text>]",
|
|
145
145
|
purpose: "Drop one or more Tasks.",
|
|
146
146
|
},
|
|
147
147
|
context: {
|
|
148
148
|
arity: [0, 1],
|
|
149
149
|
flags: COMMON,
|
|
150
|
-
usage: "task context [<namespace>]
|
|
150
|
+
usage: "task context [<namespace>]",
|
|
151
151
|
purpose: "Read or replace the directory Task context.",
|
|
152
152
|
},
|
|
153
153
|
compose: {
|
|
154
154
|
arity: [0, 0],
|
|
155
155
|
stdin: "compose",
|
|
156
156
|
flags: { ...COMMON, actor: "value", plan: "boolean" },
|
|
157
|
-
usage: "task compose [--actor <actor>] [--plan]
|
|
157
|
+
usage: "task compose [--actor <actor>] [--plan] -",
|
|
158
158
|
purpose: "Plan or admit one explicit Task composition.",
|
|
159
159
|
details: [
|
|
160
160
|
"nodes: + <Title> creates; @task/<id> modifies a pre-existing Task",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ExecutionEvent } from "../library/execution.js";
|
|
1
2
|
import type { AkumaInvocationResult } from "./commands/akuma-invoke.js";
|
|
2
3
|
import type { InstallInvocationResult } from "./commands/install.js";
|
|
3
4
|
import type { TaskInvocationResult } from "./commands/task-invoke.js";
|
|
@@ -11,6 +12,8 @@ type InvokeRuntime = Readonly<{
|
|
|
11
12
|
environment?: NodeJS.ProcessEnv;
|
|
12
13
|
readStdin?: () => Promise<string>;
|
|
13
14
|
actor?: ActorId;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
progress?: (events: AsyncIterable<ExecutionEvent>) => Promise<void>;
|
|
14
17
|
}>;
|
|
15
18
|
export type SettingsInvocationResult = Readonly<{
|
|
16
19
|
kind: "settings";
|
package/build/src/cli/invoke.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { resolve } from "node:path";
|
|
1
2
|
import { resolveActor } from "./actor.js";
|
|
2
3
|
import { isParsedAkumaCommand } from "./commands/akuma.js";
|
|
3
4
|
import { invokeContractMutation } from "./commands/contract-invoke.js";
|
|
4
5
|
import { assertExplicitRepoUse, CliUsageError, usageGuideForCommand, } from "./parse.js";
|
|
5
6
|
import { isBlankInput } from "./usage.js";
|
|
6
7
|
import { AKUMA_REQUESTS_ENV } from "../akuma/provider.js";
|
|
8
|
+
import { canonicalBirthCwd } from "../akuma/call-input.js";
|
|
7
9
|
import { bodyRequestExecution, executionChannel, localExecutionContext, } from "../akuma/requests.js";
|
|
8
10
|
async function readStdin() {
|
|
9
11
|
const chunks = [];
|
|
@@ -118,7 +120,7 @@ async function selectContract(repo, selector, scope) {
|
|
|
118
120
|
}
|
|
119
121
|
async function invokeAkumaFromEdge(parsed, input) {
|
|
120
122
|
try {
|
|
121
|
-
const {
|
|
123
|
+
const { executionCwd, repo, edge } = input;
|
|
122
124
|
const path = await akumaWorldFor(parsed, input.located, input.candidate, input.establish);
|
|
123
125
|
const home = parsed.command === "call" ? input.home : undefined;
|
|
124
126
|
const configuration = parsed.command === "call" ? await settingsAt(path, home) : undefined;
|
|
@@ -131,7 +133,7 @@ async function invokeAkumaFromEdge(parsed, input) {
|
|
|
131
133
|
: undefined;
|
|
132
134
|
return await invokeAkuma(parsed, {
|
|
133
135
|
path,
|
|
134
|
-
...(
|
|
136
|
+
...(executionCwd === undefined ? {} : { executionCwd }),
|
|
135
137
|
...(home === undefined ? {} : { home }),
|
|
136
138
|
...(configuration === undefined ? {} : { settings: configuration }),
|
|
137
139
|
...(contract === undefined ? (repo === undefined ? {} : { repo }) : { contract }),
|
|
@@ -326,13 +328,56 @@ async function resolveInvocationCoordinates(invocation, runtime) {
|
|
|
326
328
|
command: invocation.command,
|
|
327
329
|
});
|
|
328
330
|
}
|
|
331
|
+
async function invokeTask(parsed, runtime, edge, execution, coordinates) {
|
|
332
|
+
const actor = taskActor(parsed, runtime, edge.environment);
|
|
333
|
+
return await (await import("./commands/task-invoke.js")).invokeTaskFromEdge({
|
|
334
|
+
parsed,
|
|
335
|
+
world: coordinates.world,
|
|
336
|
+
candidate: coordinates.candidateWorld,
|
|
337
|
+
context: coordinates.taskContext,
|
|
338
|
+
establish: coordinates.establishWorld,
|
|
339
|
+
readStdin: edge.readStdin,
|
|
340
|
+
actor,
|
|
341
|
+
execution,
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
async function callExecutionCwd(input) {
|
|
345
|
+
if (input.command.command !== "call")
|
|
346
|
+
return undefined;
|
|
347
|
+
if (input.workdir !== undefined) {
|
|
348
|
+
return await canonicalBirthCwd(resolve(input.cwd, input.workdir), `workdir is not an existing directory: ${input.workdir}`);
|
|
349
|
+
}
|
|
350
|
+
return input.command.contract === undefined ? input.cwd : undefined;
|
|
351
|
+
}
|
|
352
|
+
async function invokeParsedAkuma(input) {
|
|
353
|
+
const executionCwd = await callExecutionCwd({
|
|
354
|
+
command: input.parsed,
|
|
355
|
+
cwd: input.cwd,
|
|
356
|
+
...(input.workdir === undefined ? {} : { workdir: input.workdir }),
|
|
357
|
+
});
|
|
358
|
+
return await invokeAkumaFromEdge(input.parsed, {
|
|
359
|
+
located: input.world,
|
|
360
|
+
candidate: input.candidate,
|
|
361
|
+
establish: input.establish,
|
|
362
|
+
...(executionCwd === undefined ? {} : { executionCwd }),
|
|
363
|
+
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
364
|
+
...(input.home === undefined ? {} : { home: input.home }),
|
|
365
|
+
edge: input.edge,
|
|
366
|
+
execution: input.execution,
|
|
367
|
+
});
|
|
368
|
+
}
|
|
329
369
|
// eslint-disable-next-line complexity -- command dispatch keeps the CLI's existing boundary in one place.
|
|
330
370
|
async function invokeParsed(invocation, runtime) {
|
|
331
371
|
const environment = runtime.environment ?? process.env;
|
|
332
372
|
const execution = executionForEnvironment(environment);
|
|
333
373
|
const coordinates = await resolveInvocationCoordinates(invocation, runtime);
|
|
334
|
-
const { cwd,
|
|
335
|
-
const edge = {
|
|
374
|
+
const { cwd, repo, world, candidateWorld, establishWorld } = coordinates;
|
|
375
|
+
const edge = {
|
|
376
|
+
environment,
|
|
377
|
+
readStdin: runtime.readStdin ?? readStdin,
|
|
378
|
+
...(runtime.signal === undefined ? {} : { signal: runtime.signal }),
|
|
379
|
+
...(runtime.progress === undefined ? {} : { progress: runtime.progress }),
|
|
380
|
+
};
|
|
336
381
|
const parsed = invocation.command;
|
|
337
382
|
const mapped = edge.environment.KEIYAKU_HOME?.trim();
|
|
338
383
|
const home = mapped === undefined || mapped.length === 0 ? undefined : mapped;
|
|
@@ -340,34 +385,23 @@ async function invokeParsed(invocation, runtime) {
|
|
|
340
385
|
return { kind: "settings", value: await settingsAt(world ?? undefined, home) };
|
|
341
386
|
if (parsed.command === "nuke")
|
|
342
387
|
return await (await import("./commands/nuke.js")).invokeNuke(parsed, world);
|
|
343
|
-
if (parsed.command === "task")
|
|
344
|
-
|
|
345
|
-
return await (await import("./commands/task-invoke.js")).invokeTaskFromEdge({
|
|
346
|
-
parsed,
|
|
347
|
-
world,
|
|
348
|
-
candidate: candidateWorld,
|
|
349
|
-
context: taskContext,
|
|
350
|
-
establish: coordinates.establishWorld,
|
|
351
|
-
readStdin: edge.readStdin,
|
|
352
|
-
actor,
|
|
353
|
-
execution,
|
|
354
|
-
});
|
|
355
|
-
}
|
|
388
|
+
if (parsed.command === "task")
|
|
389
|
+
return await invokeTask(parsed, runtime, edge, execution, coordinates);
|
|
356
390
|
if (parsed.command === "history" && "contract" in parsed)
|
|
357
391
|
return await invokeContractHistory(repo, parsed.contract);
|
|
358
|
-
if (isParsedAkumaCommand(parsed))
|
|
359
|
-
return await
|
|
360
|
-
|
|
392
|
+
if (isParsedAkumaCommand(parsed))
|
|
393
|
+
return await invokeParsedAkuma({
|
|
394
|
+
parsed,
|
|
395
|
+
cwd,
|
|
396
|
+
...(invocation.workdir === undefined ? {} : { workdir: invocation.workdir }),
|
|
397
|
+
world,
|
|
361
398
|
candidate: candidateWorld,
|
|
362
399
|
establish: coordinates.establishWorld,
|
|
363
|
-
invocationCwd: cwd,
|
|
364
|
-
...(cwdSource === "input" ? { statedCwd: cwd } : {}),
|
|
365
400
|
...(repo === undefined ? {} : { repo }),
|
|
366
401
|
...(home === undefined ? {} : { home }),
|
|
367
402
|
edge,
|
|
368
403
|
execution,
|
|
369
404
|
});
|
|
370
|
-
}
|
|
371
405
|
if (parsed.command === "ls")
|
|
372
406
|
return await invokeCatalog(parsed, world, repo, home);
|
|
373
407
|
if (parsed.command === "status")
|
|
@@ -434,6 +468,7 @@ export async function invoke(invocation, runtime = {}) {
|
|
|
434
468
|
return await invokeParsed({
|
|
435
469
|
...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
|
|
436
470
|
...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
|
|
471
|
+
...(invocation.workdir === undefined ? {} : { workdir: invocation.workdir }),
|
|
437
472
|
command,
|
|
438
473
|
}, acquiredRuntime);
|
|
439
474
|
}
|
package/build/src/cli/main.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CliUsageError, parseArgv, renderHelp } from "./parse.js";
|
|
2
|
+
import { installedPackageVersion } from "./version.js";
|
|
2
3
|
export async function main(argv = process.argv.slice(2)) {
|
|
3
4
|
try {
|
|
4
5
|
const parsed = parseArgv(argv);
|
|
@@ -8,6 +9,10 @@ export async function main(argv = process.argv.slice(2)) {
|
|
|
8
9
|
process.stdout.write(help.endsWith("\n") ? help : `${help}\n`);
|
|
9
10
|
return 0;
|
|
10
11
|
}
|
|
12
|
+
if ("version" in parsed) {
|
|
13
|
+
process.stdout.write(`${await installedPackageVersion()}\n`);
|
|
14
|
+
return 0;
|
|
15
|
+
}
|
|
11
16
|
return await (await import("./runtime.js")).runCliCommand(parsed);
|
|
12
17
|
}
|
|
13
18
|
catch (error) {
|
package/build/src/cli/parse.d.ts
CHANGED
|
@@ -29,10 +29,13 @@ export type CliHelpCoordinate = Readonly<{
|
|
|
29
29
|
export type ParsedExecution = Readonly<{
|
|
30
30
|
cwd?: string;
|
|
31
31
|
repo?: string;
|
|
32
|
+
workdir?: string;
|
|
32
33
|
command: ParsedCommand;
|
|
33
34
|
}>;
|
|
34
35
|
export type ParsedInvocation = ParsedExecution | Readonly<{
|
|
35
36
|
help: CliHelpCoordinate;
|
|
37
|
+
}> | Readonly<{
|
|
38
|
+
version: true;
|
|
36
39
|
}>;
|
|
37
40
|
type RepoUse = "none" | "optional" | "required";
|
|
38
41
|
export type CommandRepoPolicy = Readonly<{
|
package/build/src/cli/parse.js
CHANGED
|
@@ -10,6 +10,7 @@ const ROOT_USAGE = [
|
|
|
10
10
|
"usage keiyaku <command> [options]",
|
|
11
11
|
" keiyaku <command> --help shows that command's complete usage",
|
|
12
12
|
].join("\n");
|
|
13
|
+
const INVOCATION_PATH_OPTIONS = new Set(["-C", "--cwd", "--repo", "--workdir"]);
|
|
13
14
|
export function renderRootHelp(columns) {
|
|
14
15
|
return renderHelpText([
|
|
15
16
|
"keiyaku — Contract, Task, and Akuma control for one repository",
|
|
@@ -31,9 +32,13 @@ export function renderRootHelp(columns) {
|
|
|
31
32
|
` install ${INSTALL_ROOT_PURPOSE}`,
|
|
32
33
|
` settings ${CONTRACT_COMMAND_SPECS.settings.purpose}`,
|
|
33
34
|
"",
|
|
35
|
+
"Package",
|
|
36
|
+
" --version Print the running package version.",
|
|
37
|
+
"",
|
|
34
38
|
"Global options:",
|
|
35
39
|
" -C, --cwd <path> Set the invocation working directory.",
|
|
36
40
|
" --repo <path> Select the Git repository coordinate.",
|
|
41
|
+
" --workdir <path> Set the execution directory for call only.",
|
|
37
42
|
].join("\n"), columns);
|
|
38
43
|
}
|
|
39
44
|
function renderHelpText(help, columns) {
|
|
@@ -219,25 +224,31 @@ function scanArgv(argv) {
|
|
|
219
224
|
function invocationOptions(argv) {
|
|
220
225
|
let cwd;
|
|
221
226
|
let repo;
|
|
227
|
+
let workdir;
|
|
222
228
|
const commandArgv = [];
|
|
223
229
|
for (let index = 0; index < argv.length; index += 1) {
|
|
224
230
|
const token = argv[index];
|
|
225
|
-
if (token
|
|
231
|
+
if (!INVOCATION_PATH_OPTIONS.has(token)) {
|
|
226
232
|
commandArgv.push(token);
|
|
227
233
|
continue;
|
|
228
234
|
}
|
|
229
235
|
if (token === "--repo" && repo !== undefined) {
|
|
230
236
|
throw new CliUsageError("--repo may appear only once", ROOT_USAGE_GUIDE);
|
|
231
237
|
}
|
|
232
|
-
if (token
|
|
238
|
+
if ((token === "-C" || token === "--cwd") && cwd !== undefined) {
|
|
233
239
|
throw new CliUsageError("-C/--cwd may appear only once", ROOT_USAGE_GUIDE);
|
|
234
240
|
}
|
|
241
|
+
if (token === "--workdir" && workdir !== undefined) {
|
|
242
|
+
throw new CliUsageError("--workdir may appear only once", ROOT_USAGE_GUIDE);
|
|
243
|
+
}
|
|
235
244
|
const value = argv[index + 1];
|
|
236
|
-
if (
|
|
245
|
+
if (invalidInvocationPath(value)) {
|
|
237
246
|
throw new CliUsageError(`${token} requires a path`, ROOT_USAGE_GUIDE);
|
|
238
247
|
}
|
|
239
248
|
if (token === "--repo")
|
|
240
249
|
repo = value;
|
|
250
|
+
else if (token === "--workdir")
|
|
251
|
+
workdir = value;
|
|
241
252
|
else
|
|
242
253
|
cwd = value;
|
|
243
254
|
index += 1;
|
|
@@ -245,9 +256,13 @@ function invocationOptions(argv) {
|
|
|
245
256
|
return {
|
|
246
257
|
...(cwd === undefined ? {} : { cwd }),
|
|
247
258
|
...(repo === undefined ? {} : { repo }),
|
|
259
|
+
...(workdir === undefined ? {} : { workdir }),
|
|
248
260
|
commandArgv,
|
|
249
261
|
};
|
|
250
262
|
}
|
|
263
|
+
function invalidInvocationPath(value) {
|
|
264
|
+
return value === undefined || value === "-" || value.startsWith("-") || isBlankInput(value);
|
|
265
|
+
}
|
|
251
266
|
function helpCoordinate(argv) {
|
|
252
267
|
const help = argv.indexOf("--help");
|
|
253
268
|
if (help < 0)
|
|
@@ -272,6 +287,8 @@ export function parseArgv(argv) {
|
|
|
272
287
|
const help = helpCoordinate(invocation.commandArgv);
|
|
273
288
|
if (help !== null)
|
|
274
289
|
return { help };
|
|
290
|
+
if (invocation.commandArgv.length === 1 && invocation.commandArgv[0] === "--version")
|
|
291
|
+
return { version: true };
|
|
275
292
|
if (invocation.commandArgv[0] === "ls" &&
|
|
276
293
|
(invocation.commandArgv.length === 1 ||
|
|
277
294
|
(invocation.commandArgv.length === 2 && invocation.commandArgv[1] === "--json"))) {
|
|
@@ -280,9 +297,14 @@ export function parseArgv(argv) {
|
|
|
280
297
|
const task = invocation.commandArgv[0] === "task" ? parseTaskCommand(invocation.commandArgv.slice(1)) : undefined;
|
|
281
298
|
const install = invocation.commandArgv[0] === "install" ? parseInstallCommand(invocation.commandArgv.slice(1)) : undefined;
|
|
282
299
|
const akuma = isAkumaAction(invocation.commandArgv[0]) ? parseAkumaCommand(invocation.commandArgv) : undefined;
|
|
300
|
+
const command = task ?? akuma ?? install ?? parseContractCommand(scanArgv(invocation.commandArgv));
|
|
301
|
+
if (invocation.workdir !== undefined && command.command !== "call") {
|
|
302
|
+
throw new CliUsageError(`option --workdir is not valid for ${command.command}`, usageGuideForCommand(command));
|
|
303
|
+
}
|
|
283
304
|
return {
|
|
284
305
|
...(invocation.cwd === undefined ? {} : { cwd: invocation.cwd }),
|
|
285
306
|
...(invocation.repo === undefined ? {} : { repo: invocation.repo }),
|
|
286
|
-
|
|
307
|
+
...(invocation.workdir === undefined ? {} : { workdir: invocation.workdir }),
|
|
308
|
+
command,
|
|
287
309
|
};
|
|
288
310
|
}
|