@astrosheep/keiyaku 4.0.2 → 4.0.4
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 +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-akuma/SKILL.md +1 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-bind/SKILL.md +5 -0
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-task/SKILL.md +3 -1
- package/build/integrations/marketplace/plugins/keiyaku/skills/keiyaku-workflow/SKILL.md +9 -8
- package/build/src/akuma/akuma.d.ts +34 -11
- package/build/src/akuma/akuma.js +121 -61
- package/build/src/akuma/allowed.d.ts +7 -0
- package/build/src/akuma/allowed.js +40 -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 +3 -1
- package/build/src/akuma/body.js +19 -8
- package/build/src/akuma/heart/facts.d.ts +49 -7
- package/build/src/akuma/heart/index.d.ts +4 -8
- package/build/src/akuma/heart/index.js +76 -15
- package/build/src/akuma/heart/rows.d.ts +7 -5
- package/build/src/akuma/heart/rows.js +98 -11
- package/build/src/akuma/heart/schema.d.ts +1 -1
- package/build/src/akuma/heart/schema.js +15 -10
- package/build/src/akuma/heart/soul.js +3 -1
- package/build/src/akuma/heart/storage.d.ts +2 -0
- package/build/src/akuma/heart/storage.js +20 -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 +4 -1
- 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.d.ts +1 -1
- 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 +4 -4
- 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/claude/events.js +62 -3
- package/build/src/akuma/providers/codex-app-server/events.js +1 -13
- package/build/src/akuma/providers/grok-build/index.d.ts +2 -1
- package/build/src/akuma/providers/grok-build/index.js +72 -2
- package/build/src/akuma/providers/opencode-sdk/events.js +71 -6
- package/build/src/akuma/providers/pi/events.js +17 -3
- 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 +36 -7
- package/build/src/akuma/requests.d.ts +70 -4
- package/build/src/akuma/requests.js +288 -77
- package/build/src/akuma-body.d.ts +1 -0
- package/build/src/akuma-body.js +31 -0
- package/build/src/cli/accepted.d.ts +4 -1
- package/build/src/cli/accepted.js +26 -4
- 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 +3 -3
- package/build/src/cli/commands/contract.js +1 -1
- package/build/src/cli/commands/install.js +4 -4
- 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/commands/task.js +4 -4
- package/build/src/cli/coordinates.d.ts +1 -0
- package/build/src/cli/coordinates.js +5 -1
- package/build/src/cli/invoke.d.ts +1 -0
- package/build/src/cli/invoke.js +90 -73
- package/build/src/cli/main.d.ts +2 -0
- package/build/src/cli/main.js +29 -4
- package/build/src/cli/parse.d.ts +1 -0
- package/build/src/cli/parse.js +8 -4
- package/build/src/cli/render/akuma.d.ts +2 -2
- package/build/src/cli/render/akuma.js +84 -13
- package/build/src/cli/render/audit.js +16 -2
- package/build/src/cli/render/contract.d.ts +2 -0
- package/build/src/cli/render/contract.js +203 -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 +9 -1
- package/build/src/cli/render/text.js +3 -1
- package/build/src/cli/result.d.ts +38 -3
- package/build/src/cli/selectors.d.ts +1 -0
- package/build/src/cli/selectors.js +9 -6
- package/build/src/cli/usage.d.ts +2 -0
- package/build/src/cli/usage.js +4 -0
- package/build/src/contract-worktree.js +3 -0
- package/build/src/dispatch/index.js +50 -39
- package/build/src/git/hooks.d.ts +0 -4
- package/build/src/git/hooks.js +0 -36
- package/build/src/git/integration.d.ts +2 -6
- package/build/src/git/integration.js +8 -8
- package/build/src/git/read-observation.js +1 -0
- package/build/src/git/reconcile.d.ts +6 -1
- package/build/src/git/reconcile.js +55 -9
- package/build/src/git/tender.d.ts +19 -4
- package/build/src/git/tender.js +44 -13
- package/build/src/git/terminal-seal.d.ts +14 -0
- package/build/src/git/terminal-seal.js +15 -2
- package/build/src/git/workspace.d.ts +1 -0
- package/build/src/git/workspace.js +12 -4
- package/build/src/index.d.ts +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 +20 -22
- package/build/src/library/akuma-creation.d.ts +4 -2
- package/build/src/library/akuma-creation.js +43 -26
- package/build/src/library/bind.js +3 -3
- package/build/src/library/catalog.d.ts +1 -2
- package/build/src/library/catalog.js +11 -6
- package/build/src/library/configuration.d.ts +4 -0
- package/build/src/library/configuration.js +19 -0
- package/build/src/library/contract.d.ts +15 -1
- package/build/src/library/contract.js +51 -4
- package/build/src/library/fleet.d.ts +47 -9
- package/build/src/library/fleet.js +184 -44
- package/build/src/library/input.js +1 -0
- package/build/src/library/keiyaku.d.ts +4 -4
- package/build/src/library/keiyaku.js +1 -2
- package/build/src/protocol/bind.d.ts +1 -2
- package/build/src/protocol/bind.js +2 -16
- package/build/src/protocol/operations.d.ts +4 -1
- package/build/src/protocol/operations.js +33 -27
- package/build/src/protocol/read/status.d.ts +3 -1
- package/build/src/protocol/read/status.js +24 -14
- package/build/src/runtime/proc/run.d.ts +1 -0
- package/build/src/runtime/proc/run.js +9 -2
- package/build/src/settlement/settle.d.ts +1 -0
- package/build/src/settlement/settle.js +4 -1
- package/build/src/task/board.d.ts +18 -3
- package/build/src/task/board.js +73 -26
- package/build/src/task/index.d.ts +3 -3
- package/build/src/task/index.js +7 -5
- package/build/src/task/operations.d.ts +2 -19
- package/build/src/task/operations.js +29 -7
- package/build/src/task/query.d.ts +9 -2
- package/build/src/task/query.js +32 -64
- package/build/src/verification/execution.js +2 -1
- package/package.json +3 -1
|
@@ -13,7 +13,6 @@ async function invokeWait(command, input) {
|
|
|
13
13
|
result: await Keiyaku.wait({
|
|
14
14
|
path: input.path,
|
|
15
15
|
akuma: command.akuma,
|
|
16
|
-
settings: input.settings,
|
|
17
16
|
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
18
17
|
...(command.completion === undefined ? {} : { completion: command.completion }),
|
|
19
18
|
...(command.timeoutMs === undefined ? {} : { timeoutMs: command.timeoutMs }),
|
|
@@ -24,11 +23,21 @@ async function invokeWait(command, input) {
|
|
|
24
23
|
async function invokeTell(command, input) {
|
|
25
24
|
const body = await promptBody(command, input);
|
|
26
25
|
if (command.interrupt) {
|
|
27
|
-
const result = await Keiyaku.interrupt({
|
|
26
|
+
const result = await Keiyaku.interrupt({
|
|
27
|
+
path: input.path,
|
|
28
|
+
akuma: command.akuma,
|
|
29
|
+
body,
|
|
30
|
+
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
31
|
+
});
|
|
28
32
|
const alias = inputAlias(command.akuma);
|
|
29
33
|
return { kind: "akuma", action: "tell", mode: "interrupt", result, body, ...(alias === undefined ? {} : { alias }) };
|
|
30
34
|
}
|
|
31
|
-
const result = await Keiyaku.tell({
|
|
35
|
+
const result = await Keiyaku.tell({
|
|
36
|
+
path: input.path,
|
|
37
|
+
akuma: command.akuma,
|
|
38
|
+
body,
|
|
39
|
+
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
40
|
+
});
|
|
32
41
|
const alias = inputAlias(command.akuma);
|
|
33
42
|
return { kind: "akuma", action: "tell", mode: "ordinary", result, body, ...(alias === undefined ? {} : { alias }) };
|
|
34
43
|
}
|
|
@@ -36,7 +45,6 @@ async function invokeHistory(command, input) {
|
|
|
36
45
|
const result = await Keiyaku.history({
|
|
37
46
|
path: input.path,
|
|
38
47
|
akuma: command.akuma,
|
|
39
|
-
settings: input.settings,
|
|
40
48
|
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
41
49
|
...(command.before === undefined ? {} : { before: command.before }),
|
|
42
50
|
...(command.since === undefined ? {} : { since: command.since }),
|
|
@@ -64,7 +72,6 @@ async function invokeFork(command, input) {
|
|
|
64
72
|
path: input.path,
|
|
65
73
|
akuma: command.akuma,
|
|
66
74
|
at: command.at,
|
|
67
|
-
settings: input.settings,
|
|
68
75
|
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
69
76
|
}),
|
|
70
77
|
};
|
|
@@ -77,7 +84,6 @@ async function invokeKill(command, input) {
|
|
|
77
84
|
result: await Keiyaku.kill({
|
|
78
85
|
path: input.path,
|
|
79
86
|
akuma: command.akuma,
|
|
80
|
-
settings: input.settings,
|
|
81
87
|
...(input.repo === undefined ? {} : { repo: input.repo }),
|
|
82
88
|
}),
|
|
83
89
|
...(alias === undefined ? {} : { alias }),
|
|
@@ -91,12 +97,14 @@ export async function invokeAkuma(command, input) {
|
|
|
91
97
|
path: input.path,
|
|
92
98
|
archetype: command.archetype,
|
|
93
99
|
body,
|
|
94
|
-
|
|
95
|
-
...(input.
|
|
100
|
+
...(input.home === undefined ? {} : { home: input.home }),
|
|
101
|
+
...(input.settings === undefined ? {} : { settings: input.settings }),
|
|
102
|
+
...(input.statedCwd === undefined ? {} : { cwd: input.statedCwd }),
|
|
96
103
|
mode: command.mode,
|
|
97
104
|
...(command.timeoutMs === undefined ? {} : { timeoutMs: command.timeoutMs }),
|
|
98
105
|
...(input.contract === undefined ? {} : { contract: input.contract }),
|
|
99
106
|
...(command.alias === undefined ? {} : { alias: command.alias }),
|
|
107
|
+
...(command.allowed === undefined ? {} : { allowed: command.allowed }),
|
|
100
108
|
});
|
|
101
109
|
return { kind: "akuma", action: "call", result, world: input.path };
|
|
102
110
|
}
|
|
@@ -107,11 +115,11 @@ export async function invokeAkuma(command, input) {
|
|
|
107
115
|
case "kill": return await invokeKill(command, input);
|
|
108
116
|
}
|
|
109
117
|
}
|
|
110
|
-
export async function invokeAkumaStatus(path, akuma,
|
|
118
|
+
export async function invokeAkumaStatus(path, akuma, alias, repo) {
|
|
111
119
|
return {
|
|
112
120
|
kind: "akuma",
|
|
113
121
|
action: "status",
|
|
114
|
-
status: await Keiyaku.status({ path, akuma,
|
|
122
|
+
status: await Keiyaku.status({ path, akuma, ...(repo === undefined ? {} : { repo }) }),
|
|
115
123
|
...(alias === undefined ? {} : { alias }),
|
|
116
124
|
};
|
|
117
125
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type AkumaAlias } from "../../identity/selector.js";
|
|
2
|
+
import { type AllowedActions } from "../../akuma/allowed.js";
|
|
2
3
|
type Output = Readonly<{
|
|
3
4
|
output: "text" | "json";
|
|
4
5
|
}>;
|
|
@@ -21,6 +22,7 @@ export type ParsedAkumaCommand = Output & ((Readonly<{
|
|
|
21
22
|
alias?: AkumaAlias;
|
|
22
23
|
mode: "wait" | "detach";
|
|
23
24
|
timeoutMs?: number;
|
|
25
|
+
allowed?: AllowedActions;
|
|
24
26
|
}> & Prompted) | Readonly<{
|
|
25
27
|
command: "kill";
|
|
26
28
|
akuma: readonly string[];
|
|
@@ -38,15 +40,22 @@ export type ParsedAkumaCommand = Output & ((Readonly<{
|
|
|
38
40
|
before?: number;
|
|
39
41
|
since?: number;
|
|
40
42
|
limit?: number;
|
|
41
|
-
}> & Addressed) |
|
|
43
|
+
}> & Addressed) | Readonly<{
|
|
44
|
+
command: "history";
|
|
45
|
+
contract: string;
|
|
46
|
+
}> | (Readonly<{
|
|
42
47
|
command: "fork";
|
|
43
48
|
at: string;
|
|
44
49
|
}> & Addressed));
|
|
50
|
+
export type InvokedAkumaCommand = Exclude<ParsedAkumaCommand, {
|
|
51
|
+
command: "history";
|
|
52
|
+
contract: string;
|
|
53
|
+
}>;
|
|
45
54
|
export type AkumaAction = ParsedAkumaCommand["command"];
|
|
46
55
|
export declare function isAkumaAction(value: string | undefined): value is AkumaAction;
|
|
47
56
|
export declare function isParsedAkumaCommand(command: Readonly<{
|
|
48
57
|
command: string;
|
|
49
|
-
}>): command is
|
|
58
|
+
}>): command is InvokedAkumaCommand;
|
|
50
59
|
export declare function renderAkumaRootRows(): readonly string[];
|
|
51
60
|
export declare function renderAkumaHelp(action: AkumaAction): string;
|
|
52
61
|
export declare function renderAkumaUsage(action: AkumaAction): string;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { CliUsageError, isBlankInput, usageLine } from "../usage.js";
|
|
1
|
+
import { CliUsageError, isBlankInput, usageLine, withJsonAutomationHelp } from "../usage.js";
|
|
2
2
|
import { archetypeName, parseAkuId } from "../../akuma/identity.js";
|
|
3
3
|
import { parseDuration as decodeDuration } from "../../duration.js";
|
|
4
4
|
import { parseAkumaAlias, parseAkumaGlob } from "../../identity/selector.js";
|
|
5
|
+
import { decodeAllowedActions } from "../../akuma/allowed.js";
|
|
5
6
|
const AKUMA_COMMAND_SPECS = {
|
|
6
7
|
call: {
|
|
7
8
|
arity: 1,
|
|
@@ -11,15 +12,17 @@ const AKUMA_COMMAND_SPECS = {
|
|
|
11
12
|
alias: "value",
|
|
12
13
|
wait: "value",
|
|
13
14
|
detach: "boolean",
|
|
15
|
+
allowed: "repeatable",
|
|
14
16
|
json: "boolean",
|
|
15
17
|
},
|
|
16
|
-
usage: "call <akuma-name> [--contract <kei/...>] [--alias @name] [--wait <duration> | -d | --detach] [--json] (<prompt> | -)",
|
|
18
|
+
usage: "call <akuma-name> [--contract <kei/...>] [--alias @name] [--allowed <product.action>]... [--wait <duration> | -d | --detach] [--json] (<prompt> | -)",
|
|
17
19
|
purpose: "Birth an Akuma from <akuma-name> with one prompt.",
|
|
18
20
|
details: [
|
|
19
21
|
"Give <prompt> as one argument, or use final - to read stdin.",
|
|
20
22
|
"Default: --wait 5m. An explicit --wait replaces that duration; -d and --detach return after birth.",
|
|
21
23
|
"--contract dispatches the born Akuma to that Contract.",
|
|
22
24
|
"--alias assigns the world-local @name selector to the born Akuma.",
|
|
25
|
+
"Repeated --allowed replaces the Archetype list; --allowed none selects an empty list.",
|
|
23
26
|
"With --contract, Dispatch succeeds first. If @name exists, the alias then moves.",
|
|
24
27
|
].join("\n"),
|
|
25
28
|
},
|
|
@@ -45,8 +48,8 @@ const AKUMA_COMMAND_SPECS = {
|
|
|
45
48
|
arity: 1,
|
|
46
49
|
stdin: false,
|
|
47
50
|
flags: { before: "value", since: "value", limit: "value", last: "boolean", json: "boolean" },
|
|
48
|
-
usage: "history <aku/...> [--before <index> | --since <index>] [--limit <count>] [--last] [--json]",
|
|
49
|
-
purpose: "Read
|
|
51
|
+
usage: "history <aku/...|@alias|kei/...> [--before <index> | --since <index>] [--limit <count>] [--last] [--json]",
|
|
52
|
+
purpose: "Read Akuma execution history or one complete Contract journal and Dispatch timeline.",
|
|
50
53
|
},
|
|
51
54
|
fork: {
|
|
52
55
|
arity: 1,
|
|
@@ -67,14 +70,14 @@ export function isAkumaAction(value) {
|
|
|
67
70
|
return value !== undefined && Object.hasOwn(AKUMA_COMMAND_SPECS, value);
|
|
68
71
|
}
|
|
69
72
|
export function isParsedAkumaCommand(command) {
|
|
70
|
-
return isAkumaAction(command.command);
|
|
73
|
+
return isAkumaAction(command.command) && !("contract" in command && command.command === "history");
|
|
71
74
|
}
|
|
72
75
|
export function renderAkumaRootRows() {
|
|
73
76
|
return Object.values(AKUMA_COMMAND_SPECS).flatMap((spec) => [` ${spec.usage}`, ` ${spec.purpose}`]);
|
|
74
77
|
}
|
|
75
78
|
export function renderAkumaHelp(action) {
|
|
76
79
|
const spec = AKUMA_COMMAND_SPECS[action];
|
|
77
|
-
return `${spec.purpose}\n\n${usageLine(spec.usage)}${spec.details === undefined ? "" : `\n\n${spec.details}`}
|
|
80
|
+
return withJsonAutomationHelp(`${spec.purpose}\n\n${usageLine(spec.usage)}${spec.details === undefined ? "" : `\n\n${spec.details}`}`);
|
|
78
81
|
}
|
|
79
82
|
export function renderAkumaUsage(action) {
|
|
80
83
|
return usageLine(AKUMA_COMMAND_SPECS[action].usage);
|
|
@@ -104,6 +107,29 @@ function parseDuration(raw, option, fail) {
|
|
|
104
107
|
fail(`${option} duration exceeds the safe millisecond range`);
|
|
105
108
|
return duration.milliseconds;
|
|
106
109
|
}
|
|
110
|
+
function scanNamedOption(input, flags, fail) {
|
|
111
|
+
const token = input.argv[input.index];
|
|
112
|
+
const name = token.slice(2);
|
|
113
|
+
const kind = input.spec.flags[name];
|
|
114
|
+
if (kind === undefined)
|
|
115
|
+
fail(`option ${token} is not valid for ${input.action}`);
|
|
116
|
+
if (kind !== "repeatable" && flags[name] !== undefined)
|
|
117
|
+
fail(`duplicate option: ${token}`);
|
|
118
|
+
if (kind === "boolean") {
|
|
119
|
+
flags[name] = true;
|
|
120
|
+
return input.index;
|
|
121
|
+
}
|
|
122
|
+
const value = input.argv[input.index + 1];
|
|
123
|
+
if (value === undefined || value === "-" || value === "-d" || value.startsWith("--")) {
|
|
124
|
+
fail(`${token} requires a value`);
|
|
125
|
+
}
|
|
126
|
+
if (isBlankInput(value))
|
|
127
|
+
fail(`${token} requires a nonblank value`);
|
|
128
|
+
flags[name] = kind === "repeatable"
|
|
129
|
+
? [...(Array.isArray(flags[name]) ? flags[name] : []), value]
|
|
130
|
+
: value;
|
|
131
|
+
return input.index + 1;
|
|
132
|
+
}
|
|
107
133
|
function scanAkuma(action, argv, fail) {
|
|
108
134
|
const spec = AKUMA_COMMAND_SPECS[action];
|
|
109
135
|
const flags = {};
|
|
@@ -129,24 +155,7 @@ function scanAkuma(action, argv, fail) {
|
|
|
129
155
|
positionals.push(token);
|
|
130
156
|
}
|
|
131
157
|
else {
|
|
132
|
-
|
|
133
|
-
const kind = spec.flags[name];
|
|
134
|
-
if (kind === undefined)
|
|
135
|
-
fail(`option ${token} is not valid for ${action}`);
|
|
136
|
-
if (flags[name] !== undefined)
|
|
137
|
-
fail(`duplicate option: ${token}`);
|
|
138
|
-
if (kind === "boolean")
|
|
139
|
-
flags[name] = true;
|
|
140
|
-
else {
|
|
141
|
-
const value = argv[index + 1];
|
|
142
|
-
if (value === undefined || value === "-" || value === "-d" || value.startsWith("--")) {
|
|
143
|
-
fail(`${token} requires a value`);
|
|
144
|
-
}
|
|
145
|
-
if (isBlankInput(value))
|
|
146
|
-
fail(`${token} requires a nonblank value`);
|
|
147
|
-
flags[name] = value;
|
|
148
|
-
index += 1;
|
|
149
|
-
}
|
|
158
|
+
index = scanNamedOption({ action, spec, argv, index }, flags, fail);
|
|
150
159
|
}
|
|
151
160
|
}
|
|
152
161
|
return { flags, positionals, stdin };
|
|
@@ -200,7 +209,13 @@ function parseWait(rawSelectors, flags, output, fail) {
|
|
|
200
209
|
output,
|
|
201
210
|
};
|
|
202
211
|
}
|
|
203
|
-
function parseHistory(
|
|
212
|
+
function parseHistory(selector, flags, output, fail) {
|
|
213
|
+
if (selector.startsWith("kei/")) {
|
|
214
|
+
if (flags.before !== undefined || flags.since !== undefined || flags.limit !== undefined || flags.last === true) {
|
|
215
|
+
fail("history kei/... does not accept --before, --since, --limit, or --last");
|
|
216
|
+
}
|
|
217
|
+
return { command: "history", contract: selector, output };
|
|
218
|
+
}
|
|
204
219
|
if (flags.before !== undefined && flags.since !== undefined)
|
|
205
220
|
fail("history --before and --since are mutually exclusive");
|
|
206
221
|
if (flags.last === true && (flags.before !== undefined || flags.since !== undefined || flags.limit !== undefined)) {
|
|
@@ -211,7 +226,7 @@ function parseHistory(akuma, flags, output, fail) {
|
|
|
211
226
|
fail("--limit must be no greater than 5000");
|
|
212
227
|
return {
|
|
213
228
|
command: "history",
|
|
214
|
-
akuma,
|
|
229
|
+
akuma: validateDirect(selector, fail),
|
|
215
230
|
last: flags.last === true,
|
|
216
231
|
...(flags.before === undefined ? {} : { before: positiveIndex(flags.before, "--before", fail) }),
|
|
217
232
|
...(flags.since === undefined ? {} : { since: positiveIndex(flags.since, "--since", fail) }),
|
|
@@ -224,9 +239,13 @@ function parseAddressed(action, rawSelectors, flags, output, fail) {
|
|
|
224
239
|
return { command: action, akuma: rawSelectors.map((value) => validateSet(value, fail)), output };
|
|
225
240
|
if (action === "wait")
|
|
226
241
|
return parseWait(rawSelectors, flags, output, fail);
|
|
242
|
+
if (action === "history") {
|
|
243
|
+
const selector = rawSelectors[0];
|
|
244
|
+
if (selector.includes("*"))
|
|
245
|
+
fail("history accepts one complete aku/..., @alias, or kei/... selector");
|
|
246
|
+
return parseHistory(selector, flags, output, fail);
|
|
247
|
+
}
|
|
227
248
|
const akuma = validateDirect(rawSelectors[0], fail);
|
|
228
|
-
if (action === "history")
|
|
229
|
-
return parseHistory(akuma, flags, output, fail);
|
|
230
249
|
const at = stringFlag(flags.at, "fork requires --at <historyId>", fail);
|
|
231
250
|
return { command: action, akuma, at, output };
|
|
232
251
|
}
|
|
@@ -246,6 +265,24 @@ function parsePrompted(action, positionals, stdin, fail) {
|
|
|
246
265
|
function parseTell(flags, subject, prompt, output, fail) {
|
|
247
266
|
return { command: "tell", akuma: validateDirect(subject, fail), interrupt: flags.interrupt === true, prompt, output };
|
|
248
267
|
}
|
|
268
|
+
function parseAllowedFlag(raw, fail) {
|
|
269
|
+
if (raw === undefined)
|
|
270
|
+
return undefined;
|
|
271
|
+
if (!Array.isArray(raw))
|
|
272
|
+
fail("--allowed requires a value");
|
|
273
|
+
const selected = raw;
|
|
274
|
+
if (selected.includes("none")) {
|
|
275
|
+
if (selected.length !== 1)
|
|
276
|
+
fail("--allowed none cannot be combined with another value");
|
|
277
|
+
return [];
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
return decodeAllowedActions(selected, "--allowed");
|
|
281
|
+
}
|
|
282
|
+
catch (error) {
|
|
283
|
+
fail(error instanceof Error ? error.message : "invalid --allowed action");
|
|
284
|
+
}
|
|
285
|
+
}
|
|
249
286
|
function parseCall(flags, archetype, prompt, output, fail) {
|
|
250
287
|
let alias;
|
|
251
288
|
if (flags.alias !== undefined) {
|
|
@@ -260,6 +297,7 @@ function parseCall(flags, archetype, prompt, output, fail) {
|
|
|
260
297
|
fail("call --wait and --detach are mutually exclusive");
|
|
261
298
|
const mode = flags.detach === true ? "detach" : "wait";
|
|
262
299
|
const timeoutMs = flags.wait === undefined ? undefined : parseDuration(flags.wait, "--wait", fail);
|
|
300
|
+
const allowed = parseAllowedFlag(flags.allowed, fail);
|
|
263
301
|
return {
|
|
264
302
|
command: "call",
|
|
265
303
|
archetype,
|
|
@@ -267,6 +305,7 @@ function parseCall(flags, archetype, prompt, output, fail) {
|
|
|
267
305
|
...(alias === undefined ? {} : { alias }),
|
|
268
306
|
mode,
|
|
269
307
|
...(timeoutMs === undefined ? {} : { timeoutMs }),
|
|
308
|
+
...(allowed === undefined ? {} : { allowed }),
|
|
270
309
|
prompt,
|
|
271
310
|
output,
|
|
272
311
|
};
|
|
@@ -4,7 +4,7 @@ export function amendFromCommand({ command, repo, contract, markdown, gates, act
|
|
|
4
4
|
? []
|
|
5
5
|
: command.after?.map((id) => contractFromInput(repo, id).id);
|
|
6
6
|
return contract.amend({
|
|
7
|
-
markdown,
|
|
7
|
+
...(markdown === undefined ? {} : { markdown }),
|
|
8
8
|
...(actor === undefined ? {} : { actor }),
|
|
9
9
|
...(hooks === undefined ? {} : { hooks }),
|
|
10
10
|
...(after === undefined ? {} : { after }),
|
|
@@ -25,7 +25,7 @@ export declare const CONTRACT_COMMAND_SPECS: {
|
|
|
25
25
|
};
|
|
26
26
|
readonly amend: {
|
|
27
27
|
readonly positional: "optional";
|
|
28
|
-
readonly stdin: "
|
|
28
|
+
readonly stdin: "optional";
|
|
29
29
|
readonly flags: {
|
|
30
30
|
readonly actor: "value";
|
|
31
31
|
readonly after: "repeat-value";
|
|
@@ -33,8 +33,8 @@ export declare const CONTRACT_COMMAND_SPECS: {
|
|
|
33
33
|
readonly gates: "value";
|
|
34
34
|
readonly json: "boolean";
|
|
35
35
|
};
|
|
36
|
-
readonly usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name>] [--actor <actor>] [--json] -";
|
|
37
|
-
readonly purpose: "
|
|
36
|
+
readonly usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name>] [--actor <actor>] [--json] [-]";
|
|
37
|
+
readonly purpose: "Amend one Contract's document operations or structured terms.";
|
|
38
38
|
};
|
|
39
39
|
readonly deliver: {
|
|
40
40
|
readonly positional: "optional";
|
|
@@ -5,7 +5,7 @@ export const AMEND_MINIMAL_STDIN_HELP = [
|
|
|
5
5
|
].join("\n");
|
|
6
6
|
export const CONTRACT_COMMAND_SPECS = {
|
|
7
7
|
bind: { positional: "none", stdin: "required", flags: { actor: "value", task: "value", target: "value", here: "boolean", after: "repeat-value", gates: "value", json: "boolean" }, usage: "bind [--task <task/...>] [--target <ref>] [--here] [--after <kei/...> ...] [--gates <name>] [--actor <actor>] [--json] -", purpose: "Create one Contract from stdin Markdown." },
|
|
8
|
-
amend: { positional: "optional", stdin: "
|
|
8
|
+
amend: { positional: "optional", stdin: "optional", flags: { actor: "value", after: "repeat-value", "clear-after": "boolean", gates: "value", json: "boolean" }, usage: "amend [<contract>|@<contract>] [--after <kei/...> ... | --clear-after] [--gates <name>] [--actor <actor>] [--json] [-]", purpose: "Amend one Contract's document operations or structured terms." },
|
|
9
9
|
deliver: { positional: "optional", stdin: "none", flags: { actor: "value", message: "value", "include-dirty": "boolean", json: "boolean" }, usage: "deliver [<contract>|@<contract>] [--message <text>] [--include-dirty] [--actor <actor>] [--json]", purpose: "Deliver one Contract candidate." },
|
|
10
10
|
review: { positional: "optional", stdin: "optional", flags: { actor: "value", satisfied: "boolean", unsatisfied: "boolean", summary: "value", json: "boolean" }, usage: "review [<contract>|@<contract>] (--satisfied | --unsatisfied) (--summary <text> | -) [--actor <actor>] [--json]", purpose: "Record one review verdict." },
|
|
11
11
|
arc: { positional: "optional", stdin: "required", flags: { actor: "value", json: "boolean" }, usage: "arc [<contract>|@<contract>] [--actor <actor>] [--json] -", purpose: "Record stdin arc Markdown for one Contract." },
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { dirname, resolve } from "node:path";
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
-
import {
|
|
4
|
-
import { CliUsageError, usageLine } from "../usage.js";
|
|
3
|
+
import { runCrossPlatformProcess } from "../../runtime/proc/run.js";
|
|
4
|
+
import { CliUsageError, usageLine, withJsonAutomationHelp } from "../usage.js";
|
|
5
5
|
export const HARNESS_NAMES = ["codex", "claude", "opencode", "pi"];
|
|
6
6
|
export const INSTALL_USAGE = "install <codex|claude|opencode|pi> [--json]\n install --all [--json]";
|
|
7
7
|
function isHarness(value) {
|
|
@@ -43,7 +43,7 @@ export function parseInstallCommand(argv) {
|
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
export function renderInstallHelp() {
|
|
46
|
-
return `Install the Keiyaku skills into one or more agent harnesses.\n\n${usageLine(INSTALL_USAGE)}
|
|
46
|
+
return withJsonAutomationHelp(`Install the Keiyaku skills into one or more agent harnesses.\n\n${usageLine(INSTALL_USAGE)}`);
|
|
47
47
|
}
|
|
48
48
|
const INSTALL_TIMEOUT_MS = 5 * 60 * 1000;
|
|
49
49
|
const ASSET_ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "../../../integrations/marketplace");
|
|
@@ -80,7 +80,7 @@ function diagnostic(argv, outcome) {
|
|
|
80
80
|
export function installAssetsRoot() {
|
|
81
81
|
return ASSET_ROOT;
|
|
82
82
|
}
|
|
83
|
-
export async function installHarnesses(harnesses, environment, runner =
|
|
83
|
+
export async function installHarnesses(harnesses, environment, runner = runCrossPlatformProcess) {
|
|
84
84
|
const results = [];
|
|
85
85
|
for (const harness of harnesses) {
|
|
86
86
|
let failure;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type TaskQueryExpression } from "../../task/index.js";
|
|
2
2
|
export type { TaskQueryExpression } from "../../task/index.js";
|
|
3
3
|
export declare function parseTaskQueryExpression(source: string): TaskQueryExpression;
|
|
4
4
|
export declare function validateTaskLimit(source: string): void;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { TASK_RELATION_PREDICATE_FIELDS, } from "../../task/index.js";
|
|
1
2
|
import { MAX_TASK_LIMIT, normalizeTaskQuery } from "../../task/query.js";
|
|
2
3
|
function syntax(message, offset) { throw new Error(`${message} at column ${offset + 1}`); }
|
|
3
4
|
function scanString(source, offset) {
|
|
@@ -133,7 +134,15 @@ function parseTextPredicate(field, operator, value) {
|
|
|
133
134
|
return { field, operator: selected, value: value.value };
|
|
134
135
|
}
|
|
135
136
|
function parseRelationPredicate(field, operator, value) {
|
|
136
|
-
|
|
137
|
+
const relationField = TASK_RELATION_PREDICATE_FIELDS.find((candidate) => candidate === field.value);
|
|
138
|
+
if (relationField === undefined) {
|
|
139
|
+
syntax(`unknown query field ${JSON.stringify(field.value)}`, field.offset);
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
field: relationField,
|
|
143
|
+
operator: equalityOperator(operator, relationField),
|
|
144
|
+
value: canonicalTaskId(value, relationField),
|
|
145
|
+
};
|
|
137
146
|
}
|
|
138
147
|
function parseBooleanPredicate(field, operator, value) {
|
|
139
148
|
return { field, operator: equalityOperator(operator, field), value: boolean(value) };
|
|
@@ -216,14 +225,11 @@ class Parser {
|
|
|
216
225
|
operator: equalityOperator(operator, "parent"),
|
|
217
226
|
value: value.value === "none" ? null : canonicalTaskId(value, "parent"),
|
|
218
227
|
};
|
|
219
|
-
case "under": return parseRelationPredicate("under", operator, value);
|
|
220
|
-
case "needs": return parseRelationPredicate("needs", operator, value);
|
|
221
|
-
case "blocks": return parseRelationPredicate("blocks", operator, value);
|
|
222
228
|
case "ready": return parseBooleanPredicate("ready", operator, value);
|
|
223
229
|
case "blocked": return parseBooleanPredicate("blocked", operator, value);
|
|
224
230
|
case "created": return parseTimestampPredicate("created", operator, value);
|
|
225
231
|
case "updated": return parseTimestampPredicate("updated", operator, value);
|
|
226
|
-
default: return
|
|
232
|
+
default: return parseRelationPredicate(field, operator, value);
|
|
227
233
|
}
|
|
228
234
|
}
|
|
229
235
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CliUsageError, isBlankInput, usageLine } from "../usage.js";
|
|
1
|
+
import { CliUsageError, isBlankInput, usageLine, withJsonAutomationHelp } from "../usage.js";
|
|
2
2
|
import { parseTaskQueryExpression, validateTaskLimit, validateTaskParent, } from "./task-query.js";
|
|
3
3
|
const COMMON = { json: "boolean" };
|
|
4
4
|
const TASK_COMMAND_SPECS = {
|
|
@@ -46,14 +46,14 @@ export function isTaskAction(value) {
|
|
|
46
46
|
export function renderTaskHelp(action) {
|
|
47
47
|
if (action !== undefined) {
|
|
48
48
|
const spec = TASK_COMMAND_SPECS[action];
|
|
49
|
-
return `${spec.purpose}\n\n${usageLine(spec.usage)}
|
|
49
|
+
return withJsonAutomationHelp(`${spec.purpose}\n\n${usageLine(spec.usage)}`);
|
|
50
50
|
}
|
|
51
|
-
return [
|
|
51
|
+
return withJsonAutomationHelp([
|
|
52
52
|
"usage: keiyaku task <command> ...",
|
|
53
53
|
"",
|
|
54
54
|
"commands:",
|
|
55
55
|
...Object.values(TASK_COMMAND_SPECS).flatMap((spec) => spec.usage.split("\n").map((line) => ` ${line}`).concat(` ${spec.purpose}`)),
|
|
56
|
-
].join("\n");
|
|
56
|
+
].join("\n"));
|
|
57
57
|
}
|
|
58
58
|
export function renderTaskUsage(action) {
|
|
59
59
|
return usageLine(TASK_COMMAND_SPECS[action].usage);
|
|
@@ -38,8 +38,11 @@ function repoPolicy(command) {
|
|
|
38
38
|
return { use: command.query.kind === "contracts" ? "required" : "none", acceptsExplicit: false };
|
|
39
39
|
case "status":
|
|
40
40
|
case "tell":
|
|
41
|
-
case "history":
|
|
42
41
|
return { use: "optional", acceptsExplicit: false };
|
|
42
|
+
case "history":
|
|
43
|
+
return "contract" in command
|
|
44
|
+
? { use: "required", acceptsExplicit: true }
|
|
45
|
+
: { use: "optional", acceptsExplicit: false };
|
|
43
46
|
case "fork":
|
|
44
47
|
return { use: "optional", acceptsExplicit: true };
|
|
45
48
|
case "wait":
|
|
@@ -112,6 +115,7 @@ export async function resolveCliCoordinates(input) {
|
|
|
112
115
|
const world = await resolveWorld(cwd, worldRepo);
|
|
113
116
|
return {
|
|
114
117
|
cwd,
|
|
118
|
+
cwdSource: input.cwd === undefined ? "process" : "input",
|
|
115
119
|
...(repo === undefined ? {} : { repo }),
|
|
116
120
|
world: world.root,
|
|
117
121
|
candidateWorld: world.candidate,
|