@maiaos/cli 0.1.0-canary.44938d4.manual.1
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 +382 -0
- package/dist/bin/maia.NOTICES.txt +31 -0
- package/dist/bin/maia.cdx.json +138 -0
- package/dist/bin/maia.mjs +115 -0
- package/dist/command-line/arguments.d.ts +21 -0
- package/dist/command-line/arguments.js +99 -0
- package/dist/command-line/context.d.ts +112 -0
- package/dist/command-line/context.js +2 -0
- package/dist/command-line/help.d.ts +36 -0
- package/dist/command-line/help.js +267 -0
- package/dist/command-line/output.d.ts +2111 -0
- package/dist/command-line/output.js +643 -0
- package/dist/command-line/stdin.d.ts +7 -0
- package/dist/command-line/stdin.js +34 -0
- package/dist/command-receipt/command.d.ts +3 -0
- package/dist/command-receipt/command.js +63 -0
- package/dist/command-receipt/compact-list.d.ts +18 -0
- package/dist/command-receipt/compact-list.js +18 -0
- package/dist/context/client.d.ts +4 -0
- package/dist/context/client.js +19 -0
- package/dist/context/commands.d.ts +3 -0
- package/dist/context/commands.js +13 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +202 -0
- package/dist/integration-authorization/client.d.ts +16 -0
- package/dist/integration-authorization/client.js +30 -0
- package/dist/integration-authorization/commands.d.ts +3 -0
- package/dist/integration-authorization/commands.js +92 -0
- package/dist/local-node/client.d.ts +31 -0
- package/dist/local-node/client.js +99 -0
- package/dist/orchestration/client.d.ts +59 -0
- package/dist/orchestration/client.js +66 -0
- package/dist/orchestration/commands.d.ts +3 -0
- package/dist/orchestration/commands.js +336 -0
- package/dist/orchestration/compact-aggregate.d.ts +123 -0
- package/dist/orchestration/compact-aggregate.js +110 -0
- package/dist/orchestration/compact-run-list.d.ts +19 -0
- package/dist/orchestration/compact-run-list.js +16 -0
- package/dist/project-workspace/client.d.ts +43 -0
- package/dist/project-workspace/client.js +54 -0
- package/dist/project-workspace/commands.d.ts +5 -0
- package/dist/project-workspace/commands.js +239 -0
- package/dist/runtime/client.d.ts +6 -0
- package/dist/runtime/client.js +10 -0
- package/dist/runtime/command.d.ts +3 -0
- package/dist/runtime/command.js +20 -0
- package/dist/session/client.d.ts +32 -0
- package/dist/session/client.js +30 -0
- package/dist/session/commands.d.ts +3 -0
- package/dist/session/commands.js +160 -0
- package/dist/status/client.d.ts +5 -0
- package/dist/status/client.js +15 -0
- package/dist/status/command.d.ts +3 -0
- package/dist/status/command.js +17 -0
- package/dist/status/compact.d.ts +31 -0
- package/dist/status/compact.js +46 -0
- package/dist/terminal/arguments.d.ts +12 -0
- package/dist/terminal/arguments.js +79 -0
- package/dist/terminal/client.d.ts +45 -0
- package/dist/terminal/client.js +48 -0
- package/dist/terminal/commands.d.ts +3 -0
- package/dist/terminal/commands.js +151 -0
- package/dist/terminal/compact-list.d.ts +148 -0
- package/dist/terminal/compact-list.js +152 -0
- package/dist/terminal/control-commands.d.ts +7 -0
- package/dist/terminal/control-commands.js +211 -0
- package/dist/turn/client.d.ts +17 -0
- package/dist/turn/client.js +23 -0
- package/dist/turn/commands.d.ts +3 -0
- package/dist/turn/commands.js +126 -0
- package/dist/turn/prompt.d.ts +2 -0
- package/dist/turn/prompt.js +9 -0
- package/guidance/maia-cli/SKILL.md +75 -0
- package/guidance/maia-orchestration/SKILL.md +54 -0
- package/package.json +50 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { DEFAULT_RECEIPT_LIST_PAGE_SIZE, } from "@maiaos/sdk";
|
|
2
|
+
import { CliArgumentError, parseOptions, requirePositionals, } from "../command-line/arguments.js";
|
|
3
|
+
import { writeNodeResult } from "../command-line/output.js";
|
|
4
|
+
import { projectReceiptListResult } from "./compact-list.js";
|
|
5
|
+
const RECEIPT_LIST_USAGE = "maia [--json] receipt list [--limit <1..32>] [--after <cursor>] [--actor <actor-id>] [--method <method>] [--since <recorded-at>] [--until <recorded-at>]";
|
|
6
|
+
const RECEIPT_SHOW_USAGE = "maia receipt show <command-id>";
|
|
7
|
+
const readReceiptListPageSize = (value) => {
|
|
8
|
+
if (value === undefined)
|
|
9
|
+
return DEFAULT_RECEIPT_LIST_PAGE_SIZE;
|
|
10
|
+
if (!/^(?:[1-9]|[12]\d|3[0-2])$/u.test(value)) {
|
|
11
|
+
throw new CliArgumentError("Option '--limit' must be an integer from 1 to 32.");
|
|
12
|
+
}
|
|
13
|
+
return Number(value);
|
|
14
|
+
};
|
|
15
|
+
const optionalListFilter = (options, flag, key) => {
|
|
16
|
+
const value = options.get(flag);
|
|
17
|
+
return value === undefined ? {} : { [key]: value };
|
|
18
|
+
};
|
|
19
|
+
const readReceiptListParameters = (tokens) => {
|
|
20
|
+
const parsed = parseOptions(tokens, new Set([
|
|
21
|
+
"--actor",
|
|
22
|
+
"--after",
|
|
23
|
+
"--limit",
|
|
24
|
+
"--method",
|
|
25
|
+
"--since",
|
|
26
|
+
"--until",
|
|
27
|
+
]));
|
|
28
|
+
requirePositionals(parsed.positionals, 0, RECEIPT_LIST_USAGE);
|
|
29
|
+
return {
|
|
30
|
+
limit: readReceiptListPageSize(parsed.options.get("--limit")),
|
|
31
|
+
...optionalListFilter(parsed.options, "--actor", "actor"),
|
|
32
|
+
...optionalListFilter(parsed.options, "--after", "afterCursor"),
|
|
33
|
+
...optionalListFilter(parsed.options, "--method", "method"),
|
|
34
|
+
...optionalListFilter(parsed.options, "--since", "since"),
|
|
35
|
+
...optionalListFilter(parsed.options, "--until", "until"),
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
const runReceiptList = async (tokens, context) => {
|
|
39
|
+
const result = await context.dependencies.listReceipts(readReceiptListParameters(tokens));
|
|
40
|
+
return writeNodeResult(result, context, projectReceiptListResult);
|
|
41
|
+
};
|
|
42
|
+
const runReceiptShow = async (tokens, context) => {
|
|
43
|
+
const parsed = parseOptions(tokens, new Set());
|
|
44
|
+
requirePositionals(parsed.positionals, 1, RECEIPT_SHOW_USAGE);
|
|
45
|
+
const commandId = parsed.positionals[0];
|
|
46
|
+
if (commandId === undefined) {
|
|
47
|
+
throw new CliArgumentError("The command identifier is missing.");
|
|
48
|
+
}
|
|
49
|
+
const result = await context.dependencies.getReceipt(commandId);
|
|
50
|
+
return writeNodeResult(result, context, (value) => ({
|
|
51
|
+
command: "receipt.show",
|
|
52
|
+
result: value,
|
|
53
|
+
}));
|
|
54
|
+
};
|
|
55
|
+
export const runReceiptCommand = async (tokens, context) => {
|
|
56
|
+
const [subcommand, ...rest] = tokens;
|
|
57
|
+
if (subcommand === "list")
|
|
58
|
+
return runReceiptList(rest, context);
|
|
59
|
+
if (subcommand === "show")
|
|
60
|
+
return runReceiptShow(rest, context);
|
|
61
|
+
throw new CliArgumentError(`Usage: ${RECEIPT_LIST_USAGE} | ${RECEIPT_SHOW_USAGE}`);
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ReceiptListResult } from "@maiaos/sdk";
|
|
2
|
+
export type CliReceiptListItem = {
|
|
3
|
+
readonly commandId: ReceiptListResult["items"][number]["commandId"];
|
|
4
|
+
readonly createdAt: ReceiptListResult["items"][number]["createdAt"];
|
|
5
|
+
readonly method: ReceiptListResult["items"][number]["method"];
|
|
6
|
+
readonly receiptId: ReceiptListResult["items"][number]["receiptId"];
|
|
7
|
+
readonly state: ReceiptListResult["items"][number]["state"];
|
|
8
|
+
readonly target: ReceiptListResult["items"][number]["target"];
|
|
9
|
+
};
|
|
10
|
+
export type CliReceiptListResult = {
|
|
11
|
+
readonly command: "receipt.list";
|
|
12
|
+
readonly count: number;
|
|
13
|
+
readonly items: readonly CliReceiptListItem[];
|
|
14
|
+
readonly nextCursor?: ReceiptListResult["nextCursor"];
|
|
15
|
+
};
|
|
16
|
+
export declare const projectReceiptListItem: (item: ReceiptListResult["items"][number]) => CliReceiptListItem;
|
|
17
|
+
export declare const projectReceiptListResult: (value: ReceiptListResult) => CliReceiptListResult;
|
|
18
|
+
//# sourceMappingURL=compact-list.d.ts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export const projectReceiptListItem = (item) => ({
|
|
2
|
+
commandId: item.commandId,
|
|
3
|
+
createdAt: item.createdAt,
|
|
4
|
+
method: item.method,
|
|
5
|
+
receiptId: item.receiptId,
|
|
6
|
+
state: item.state,
|
|
7
|
+
target: {
|
|
8
|
+
id: item.target.id,
|
|
9
|
+
type: item.target.type,
|
|
10
|
+
},
|
|
11
|
+
});
|
|
12
|
+
export const projectReceiptListResult = (value) => ({
|
|
13
|
+
command: "receipt.list",
|
|
14
|
+
count: value.items.length,
|
|
15
|
+
items: value.items.map(projectReceiptListItem),
|
|
16
|
+
...(value.nextCursor === undefined ? {} : { nextCursor: value.nextCursor }),
|
|
17
|
+
});
|
|
18
|
+
//# sourceMappingURL=compact-list.js.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { INVOCATION_CONTEXT_ERROR_NODE_UNAVAILABLE, invocationContextShowParametersSchema, } from "@maiaos/sdk";
|
|
2
|
+
import { runValidatedNodeOperation, } from "../local-node/client.js";
|
|
3
|
+
const nodeContextUnavailable = () => Promise.resolve({
|
|
4
|
+
error: {
|
|
5
|
+
code: INVOCATION_CONTEXT_ERROR_NODE_UNAVAILABLE,
|
|
6
|
+
message: "The authenticated Maia node is unavailable.",
|
|
7
|
+
retryable: true,
|
|
8
|
+
},
|
|
9
|
+
ok: false,
|
|
10
|
+
});
|
|
11
|
+
export const showCurrentContext = () => {
|
|
12
|
+
return runValidatedNodeOperation({}, invocationContextShowParametersSchema, (client, parameters, options) => client.showCurrentContext(parameters, options)).then((result) => {
|
|
13
|
+
if (!result.ok && result.error.code === "node_unavailable") {
|
|
14
|
+
return nodeContextUnavailable();
|
|
15
|
+
}
|
|
16
|
+
return result;
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { CliArgumentError, requireNoArguments, } from "../command-line/arguments.js";
|
|
2
|
+
import { writeCurrentContextResult } from "../command-line/output.js";
|
|
3
|
+
export const runContextCommand = (tokens, context) => {
|
|
4
|
+
const [subcommand, ...rest] = tokens;
|
|
5
|
+
if (subcommand !== "show") {
|
|
6
|
+
throw new CliArgumentError("Usage: maia context show");
|
|
7
|
+
}
|
|
8
|
+
requireNoArguments(rest, "Context show");
|
|
9
|
+
return context.dependencies
|
|
10
|
+
.showCurrentContext()
|
|
11
|
+
.then((result) => writeCurrentContextResult(result, context));
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=commands.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CliDependencies } from "./command-line/context.js";
|
|
2
|
+
import { type CliIo } from "./command-line/output.js";
|
|
3
|
+
export type { CliDependencies } from "./command-line/context.js";
|
|
4
|
+
export type { CliErrorOutput, CliHelpResult, CliIo, CliStatusResult, CliSuccessOutput, CliSuccessResult, CliVersionResult, } from "./command-line/output.js";
|
|
5
|
+
export declare const makeCli: (dependencies: CliDependencies) => (arguments_: readonly string[], version: string, io: CliIo) => Promise<number>;
|
|
6
|
+
export declare const runCli: (arguments_: readonly string[], version: string, io: CliIo) => Promise<number>;
|
|
7
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
import { argumentsAreBounded, CliArgumentError, parseArguments, requireNoArguments, } from "./command-line/arguments.js";
|
|
2
|
+
import { createHelpResult } from "./command-line/help.js";
|
|
3
|
+
import { reportError, writeNodeResult, writeSuccess, } from "./command-line/output.js";
|
|
4
|
+
import { runReceiptCommand } from "./command-receipt/command.js";
|
|
5
|
+
import { runContextCommand } from "./context/commands.js";
|
|
6
|
+
import { runIntegrationCommand } from "./integration-authorization/commands.js";
|
|
7
|
+
import { runOrchestrationCommand } from "./orchestration/commands.js";
|
|
8
|
+
import { runExecutionCommand, runProjectCommand, runWorkspaceCommand, } from "./project-workspace/commands.js";
|
|
9
|
+
import { runRuntimeCommand } from "./runtime/command.js";
|
|
10
|
+
import { runSessionCommand } from "./session/commands.js";
|
|
11
|
+
import { runStatusCommand } from "./status/command.js";
|
|
12
|
+
import { runTerminalCommand } from "./terminal/commands.js";
|
|
13
|
+
import { runTurnCommand } from "./turn/commands.js";
|
|
14
|
+
const HELP_ALIASES = new Set(["help", "--help", "-h"]);
|
|
15
|
+
const VERSION_ALIASES = new Set(["version", "--version", "-v"]);
|
|
16
|
+
const createArgumentError = (message) => ({
|
|
17
|
+
code: "invalid_argument",
|
|
18
|
+
message,
|
|
19
|
+
retryable: false,
|
|
20
|
+
});
|
|
21
|
+
const runHelpCommand = (rest, context) => {
|
|
22
|
+
writeSuccess(createHelpResult(context.version, rest), context.json, context.io);
|
|
23
|
+
return Promise.resolve(0);
|
|
24
|
+
};
|
|
25
|
+
const runVersionCommand = (rest, context) => {
|
|
26
|
+
requireNoArguments(rest, "Version");
|
|
27
|
+
writeSuccess({ command: "version", name: "maia", version: context.version }, context.json, context.io);
|
|
28
|
+
return Promise.resolve(0);
|
|
29
|
+
};
|
|
30
|
+
const runMonitorCommand = (rest, context) => {
|
|
31
|
+
requireNoArguments(rest, "Monitor");
|
|
32
|
+
return (context.dependencies.createMonitorBootstrap?.().then((result) => writeNodeResult(result, context, (value) => ({
|
|
33
|
+
command: "monitor",
|
|
34
|
+
result: value,
|
|
35
|
+
}))) ?? Promise.reject(new Error("No monitor.")));
|
|
36
|
+
};
|
|
37
|
+
const PRODUCT_COMMANDS = {
|
|
38
|
+
context: runContextCommand,
|
|
39
|
+
execution: runExecutionCommand,
|
|
40
|
+
integration: runIntegrationCommand,
|
|
41
|
+
project: runProjectCommand,
|
|
42
|
+
receipt: runReceiptCommand,
|
|
43
|
+
run: runOrchestrationCommand,
|
|
44
|
+
runtime: runRuntimeCommand,
|
|
45
|
+
session: runSessionCommand,
|
|
46
|
+
terminal: runTerminalCommand,
|
|
47
|
+
turn: runTurnCommand,
|
|
48
|
+
workspace: runWorkspaceCommand,
|
|
49
|
+
};
|
|
50
|
+
const runCommand = (tokens, context) => {
|
|
51
|
+
const [command, ...rest] = tokens;
|
|
52
|
+
if (command === undefined || HELP_ALIASES.has(command))
|
|
53
|
+
return runHelpCommand(rest, context);
|
|
54
|
+
if (VERSION_ALIASES.has(command))
|
|
55
|
+
return runVersionCommand(rest, context);
|
|
56
|
+
if (command === "status") {
|
|
57
|
+
requireNoArguments(rest, "Status");
|
|
58
|
+
return runStatusCommand(context);
|
|
59
|
+
}
|
|
60
|
+
if (command === "monitor")
|
|
61
|
+
return runMonitorCommand(rest, context);
|
|
62
|
+
const product = PRODUCT_COMMANDS[command];
|
|
63
|
+
if (product !== undefined)
|
|
64
|
+
return product(rest, context);
|
|
65
|
+
if (command.startsWith("-"))
|
|
66
|
+
throw new CliArgumentError("Command has an unknown option.");
|
|
67
|
+
return Promise.resolve(reportError({
|
|
68
|
+
code: "command_not_implemented",
|
|
69
|
+
message: "Command not implemented.",
|
|
70
|
+
retryable: false,
|
|
71
|
+
}, context));
|
|
72
|
+
};
|
|
73
|
+
const parseInvocation = (input) => {
|
|
74
|
+
if (!argumentsAreBounded(input.arguments_)) {
|
|
75
|
+
return {
|
|
76
|
+
exitCode: reportError(createArgumentError("Command arguments exceed the limit."), { io: input.io, json: input.arguments_.includes("--json") }),
|
|
77
|
+
ok: false,
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const parsed = parseArguments(input.arguments_);
|
|
81
|
+
if (parsed.jsonFlagCount > 1) {
|
|
82
|
+
return {
|
|
83
|
+
exitCode: reportError(createArgumentError("Option '--json' may be used only once."), { io: input.io, json: true }),
|
|
84
|
+
ok: false,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return { ok: true, parsed };
|
|
88
|
+
};
|
|
89
|
+
const executeCli = async (input) => {
|
|
90
|
+
const invocation = parseInvocation(input);
|
|
91
|
+
if (!invocation.ok)
|
|
92
|
+
return invocation.exitCode;
|
|
93
|
+
const context = {
|
|
94
|
+
dependencies: input.dependencies,
|
|
95
|
+
io: input.io,
|
|
96
|
+
json: invocation.parsed.json,
|
|
97
|
+
version: input.version,
|
|
98
|
+
};
|
|
99
|
+
try {
|
|
100
|
+
return await runCommand(invocation.parsed.tokens, context);
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
return error instanceof CliArgumentError
|
|
104
|
+
? reportError(createArgumentError(error.message), context)
|
|
105
|
+
: reportError({
|
|
106
|
+
code: "internal_error",
|
|
107
|
+
message: "Maia CLI command failed.",
|
|
108
|
+
retryable: false,
|
|
109
|
+
}, context);
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
export const makeCli = (dependencies) => (arguments_, version, io) => executeCli({
|
|
113
|
+
arguments_,
|
|
114
|
+
dependencies,
|
|
115
|
+
io,
|
|
116
|
+
version,
|
|
117
|
+
});
|
|
118
|
+
const readStatus = async () => {
|
|
119
|
+
const { readLocalNodeStatus } = await import("./status/client.js");
|
|
120
|
+
return readLocalNodeStatus();
|
|
121
|
+
};
|
|
122
|
+
const loadIntegrationAuthorization = () => import("./integration-authorization/client.js");
|
|
123
|
+
const loadProjectWorkspace = () => import("./project-workspace/client.js");
|
|
124
|
+
const loadOrchestration = () => import("./orchestration/client.js");
|
|
125
|
+
const loadSession = () => import("./session/client.js");
|
|
126
|
+
const loadTerminal = () => import("./terminal/client.js");
|
|
127
|
+
const loadTurn = () => import("./turn/client.js");
|
|
128
|
+
const loadStatus = () => import("./status/client.js");
|
|
129
|
+
const loadRuntime = () => import("./runtime/client.js");
|
|
130
|
+
const loadContext = () => import("./context/client.js");
|
|
131
|
+
const lazyDependencies = (load, names) => Object.fromEntries(names.map((name) => [
|
|
132
|
+
name,
|
|
133
|
+
(...arguments_) => load().then((module) => {
|
|
134
|
+
const operation = module[name];
|
|
135
|
+
return operation(...arguments_);
|
|
136
|
+
}),
|
|
137
|
+
]));
|
|
138
|
+
const defaultCliDependencies = {
|
|
139
|
+
...lazyDependencies(loadIntegrationAuthorization, [
|
|
140
|
+
"applyIntegration",
|
|
141
|
+
"planIntegration",
|
|
142
|
+
"removeIntegration",
|
|
143
|
+
"statusIntegration",
|
|
144
|
+
]),
|
|
145
|
+
...lazyDependencies(loadProjectWorkspace, [
|
|
146
|
+
"attachWorkspaceRepository",
|
|
147
|
+
"configureWorkspaceExecution",
|
|
148
|
+
"getReceipt",
|
|
149
|
+
"listProjects",
|
|
150
|
+
"listReceipts",
|
|
151
|
+
"listWorkspaces",
|
|
152
|
+
"readExecutionCatalog",
|
|
153
|
+
"registerProject",
|
|
154
|
+
"showProject",
|
|
155
|
+
"showWorkspace",
|
|
156
|
+
"showWorkspaceExecution",
|
|
157
|
+
]),
|
|
158
|
+
...lazyDependencies(loadOrchestration, [
|
|
159
|
+
"acknowledgeRunDelivery",
|
|
160
|
+
"cancelRunQuestion",
|
|
161
|
+
"checkRunInbox",
|
|
162
|
+
"createRun",
|
|
163
|
+
"listRuns",
|
|
164
|
+
"listTasks",
|
|
165
|
+
"openRunQuestion",
|
|
166
|
+
"replyRunQuestion",
|
|
167
|
+
"settleRunDispatchTerminal",
|
|
168
|
+
"showDispatch",
|
|
169
|
+
"showRun",
|
|
170
|
+
"showTask",
|
|
171
|
+
]),
|
|
172
|
+
...lazyDependencies(loadSession, [
|
|
173
|
+
"createSession",
|
|
174
|
+
"listSessionEvents",
|
|
175
|
+
"listSessions",
|
|
176
|
+
"showSession",
|
|
177
|
+
"startSession",
|
|
178
|
+
]),
|
|
179
|
+
...lazyDependencies(loadTerminal, [
|
|
180
|
+
"acquireTerminalController",
|
|
181
|
+
"closeTerminal",
|
|
182
|
+
"createTerminal",
|
|
183
|
+
"listTerminalEvents",
|
|
184
|
+
"listTerminals",
|
|
185
|
+
"readTerminal",
|
|
186
|
+
"releaseTerminalController",
|
|
187
|
+
"requestTerminalController",
|
|
188
|
+
"resizeTerminal",
|
|
189
|
+
"showTerminal",
|
|
190
|
+
"showTerminalControllerRequest",
|
|
191
|
+
"signalTerminal",
|
|
192
|
+
"writeTerminalInput",
|
|
193
|
+
]),
|
|
194
|
+
...lazyDependencies(loadTurn, ["interruptTurn", "sendTurn", "showTurn"]),
|
|
195
|
+
...lazyDependencies(loadRuntime, ["listInstalledHarnesses"]),
|
|
196
|
+
...lazyDependencies(loadContext, ["showCurrentContext"]),
|
|
197
|
+
...lazyDependencies(loadStatus, ["createMonitorBootstrap"]),
|
|
198
|
+
probeRuntime: (runtime = "codex") => loadRuntime().then((module) => module.probeRuntime(runtime)),
|
|
199
|
+
readStatus,
|
|
200
|
+
};
|
|
201
|
+
export const runCli = makeCli(defaultCliDependencies);
|
|
202
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { IntegrationApplyCodexResult, IntegrationApplyPiRpcResult, IntegrationPlanCodexResult, IntegrationPlanPiRpcResult, IntegrationRemoveCodexResult, IntegrationRemovePiRpcResult, IntegrationStatusCodexResult, IntegrationStatusPiRpcResult } from "@maiaos/sdk";
|
|
2
|
+
import { type CliNodeResult } from "../local-node/client.js";
|
|
3
|
+
export type IntegrationTarget = "codex" | "pi-rpc";
|
|
4
|
+
export declare const planIntegration: (integration: IntegrationTarget) => Promise<CliNodeResult<IntegrationPlanCodexResult | IntegrationPlanPiRpcResult>>;
|
|
5
|
+
type ApplyIntegrationInput = {
|
|
6
|
+
readonly commandId?: string;
|
|
7
|
+
readonly planId: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const applyIntegration: (integration: IntegrationTarget, input: ApplyIntegrationInput) => Promise<CliNodeResult<IntegrationApplyCodexResult | IntegrationApplyPiRpcResult>>;
|
|
10
|
+
export declare const statusIntegration: (integration: IntegrationTarget) => Promise<CliNodeResult<IntegrationStatusCodexResult | IntegrationStatusPiRpcResult>>;
|
|
11
|
+
type RemoveIntegrationInput = {
|
|
12
|
+
readonly commandId?: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const removeIntegration: (integration: IntegrationTarget, input: RemoveIntegrationInput) => Promise<CliNodeResult<IntegrationRemoveCodexResult | IntegrationRemovePiRpcResult>>;
|
|
15
|
+
export {};
|
|
16
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { integrationApplyCodexParametersSchema, integrationApplyPiRpcParametersSchema, integrationPlanCodexParametersSchema, integrationPlanPiRpcParametersSchema, integrationRemoveCodexParametersSchema, integrationRemovePiRpcParametersSchema, integrationStatusCodexParametersSchema, integrationStatusPiRpcParametersSchema, } from "@maiaos/sdk";
|
|
2
|
+
import { newCliIdentifier, runValidatedNodeOperation, } from "../local-node/client.js";
|
|
3
|
+
const commandId = (requested) => requested ?? newCliIdentifier("command");
|
|
4
|
+
export const planIntegration = (integration) => {
|
|
5
|
+
if (integration === "codex") {
|
|
6
|
+
return runValidatedNodeOperation({ integration }, integrationPlanCodexParametersSchema, (client, parameters, options) => client.planCodexIntegration(parameters, options));
|
|
7
|
+
}
|
|
8
|
+
return runValidatedNodeOperation({ integration }, integrationPlanPiRpcParametersSchema, (client, parameters, options) => client.planPiRpcIntegration(parameters, options));
|
|
9
|
+
};
|
|
10
|
+
export const applyIntegration = (integration, input) => {
|
|
11
|
+
const selectedCommandId = commandId(input.commandId);
|
|
12
|
+
if (integration === "codex") {
|
|
13
|
+
return runValidatedNodeOperation({ commandId: selectedCommandId, planId: input.planId }, integrationApplyCodexParametersSchema, (client, parameters, options) => client.applyCodexIntegration(parameters, options), { commandId: selectedCommandId });
|
|
14
|
+
}
|
|
15
|
+
return runValidatedNodeOperation({ commandId: selectedCommandId, planId: input.planId }, integrationApplyPiRpcParametersSchema, (client, parameters, options) => client.applyPiRpcIntegration(parameters, options), { commandId: selectedCommandId });
|
|
16
|
+
};
|
|
17
|
+
export const statusIntegration = (integration) => {
|
|
18
|
+
if (integration === "codex") {
|
|
19
|
+
return runValidatedNodeOperation({ integration }, integrationStatusCodexParametersSchema, (client, parameters, options) => client.statusCodexIntegration(parameters, options));
|
|
20
|
+
}
|
|
21
|
+
return runValidatedNodeOperation({ integration }, integrationStatusPiRpcParametersSchema, (client, parameters, options) => client.statusPiRpcIntegration(parameters, options));
|
|
22
|
+
};
|
|
23
|
+
export const removeIntegration = (integration, input) => {
|
|
24
|
+
const selectedCommandId = commandId(input.commandId);
|
|
25
|
+
if (integration === "codex") {
|
|
26
|
+
return runValidatedNodeOperation({ commandId: selectedCommandId, integration }, integrationRemoveCodexParametersSchema, (client, parameters, options) => client.removeCodexIntegration(parameters, options), { commandId: selectedCommandId });
|
|
27
|
+
}
|
|
28
|
+
return runValidatedNodeOperation({ commandId: selectedCommandId, integration }, integrationRemovePiRpcParametersSchema, (client, parameters, options) => client.removePiRpcIntegration(parameters, options), { commandId: selectedCommandId });
|
|
29
|
+
};
|
|
30
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { CliArgumentError, parseOptions, requirePositionals, } from "../command-line/arguments.js";
|
|
2
|
+
import { writeIntegrationApplyResult, writeIntegrationPlanResult, writeIntegrationRemoveResult, writeIntegrationStatusResult, } from "../command-line/output.js";
|
|
3
|
+
const EXIT_OUTCOME_UNKNOWN = 76;
|
|
4
|
+
const integrationUsage = (tail) => `maia integration ${tail}`;
|
|
5
|
+
const PLAN_USAGE = integrationUsage("plan <codex|pi-rpc>");
|
|
6
|
+
const APPLY_USAGE = integrationUsage("apply <plan-id> [--integration <codex|pi-rpc>] [--command-id <id>]");
|
|
7
|
+
const STATUS_USAGE = integrationUsage("status <codex|pi-rpc>");
|
|
8
|
+
const REMOVE_USAGE = integrationUsage("remove <codex|pi-rpc> [--command-id <id>]");
|
|
9
|
+
const INTEGRATION_USAGE = [
|
|
10
|
+
PLAN_USAGE,
|
|
11
|
+
APPLY_USAGE,
|
|
12
|
+
STATUS_USAGE,
|
|
13
|
+
REMOVE_USAGE,
|
|
14
|
+
].join(" | ");
|
|
15
|
+
const requireIntegrationTarget = (value) => {
|
|
16
|
+
if (value === "codex" || value === "pi-rpc")
|
|
17
|
+
return value;
|
|
18
|
+
throw new CliArgumentError(`Usage: ${INTEGRATION_USAGE}`);
|
|
19
|
+
};
|
|
20
|
+
const applyIntegrationTarget = (options) => {
|
|
21
|
+
const requested = options.get("--integration");
|
|
22
|
+
return requested === undefined
|
|
23
|
+
? "codex"
|
|
24
|
+
: requireIntegrationTarget(requested);
|
|
25
|
+
};
|
|
26
|
+
const runPlan = (tokens, context) => {
|
|
27
|
+
const parsed = parseOptions(tokens, new Set());
|
|
28
|
+
requirePositionals(parsed.positionals, 1, PLAN_USAGE);
|
|
29
|
+
const integration = requireIntegrationTarget(parsed.positionals[0]);
|
|
30
|
+
const operation = context.dependencies.planIntegration;
|
|
31
|
+
if (operation === undefined)
|
|
32
|
+
throw new Error("Missing integration client.");
|
|
33
|
+
return operation(integration).then((result) => writeIntegrationPlanResult(result, context));
|
|
34
|
+
};
|
|
35
|
+
const runApply = (tokens, context) => {
|
|
36
|
+
const parsed = parseOptions(tokens, new Set(["--command-id", "--integration"]));
|
|
37
|
+
requirePositionals(parsed.positionals, 1, APPLY_USAGE);
|
|
38
|
+
const planId = parsed.positionals[0];
|
|
39
|
+
if (planId === undefined)
|
|
40
|
+
throw new CliArgumentError("The integration plan identifier is missing.");
|
|
41
|
+
const integration = applyIntegrationTarget(parsed.options);
|
|
42
|
+
const operation = context.dependencies.applyIntegration;
|
|
43
|
+
if (operation === undefined)
|
|
44
|
+
throw new Error("Missing integration client.");
|
|
45
|
+
const requestedCommandId = parsed.options.get("--command-id");
|
|
46
|
+
return operation(integration, {
|
|
47
|
+
planId,
|
|
48
|
+
...(requestedCommandId === undefined
|
|
49
|
+
? {}
|
|
50
|
+
: { commandId: requestedCommandId }),
|
|
51
|
+
}).then((result) => writeIntegrationApplyResult(result, context));
|
|
52
|
+
};
|
|
53
|
+
const runStatus = (tokens, context) => {
|
|
54
|
+
const parsed = parseOptions(tokens, new Set());
|
|
55
|
+
requirePositionals(parsed.positionals, 1, STATUS_USAGE);
|
|
56
|
+
const integration = requireIntegrationTarget(parsed.positionals[0]);
|
|
57
|
+
const operation = context.dependencies.statusIntegration;
|
|
58
|
+
if (operation === undefined)
|
|
59
|
+
throw new Error("Missing integration client.");
|
|
60
|
+
return operation(integration).then((result) => writeIntegrationStatusResult(result, context));
|
|
61
|
+
};
|
|
62
|
+
const runRemove = async (tokens, context) => {
|
|
63
|
+
const parsed = parseOptions(tokens, new Set(["--command-id"]));
|
|
64
|
+
requirePositionals(parsed.positionals, 1, REMOVE_USAGE);
|
|
65
|
+
const integration = requireIntegrationTarget(parsed.positionals[0]);
|
|
66
|
+
const operation = context.dependencies.removeIntegration;
|
|
67
|
+
if (operation === undefined)
|
|
68
|
+
throw new Error("Missing integration client.");
|
|
69
|
+
const requestedCommandId = parsed.options.get("--command-id");
|
|
70
|
+
const result = await operation(integration, {
|
|
71
|
+
...(requestedCommandId === undefined
|
|
72
|
+
? {}
|
|
73
|
+
: { commandId: requestedCommandId }),
|
|
74
|
+
});
|
|
75
|
+
const exitCode = writeIntegrationRemoveResult(result, context);
|
|
76
|
+
return result.ok && result.value.outcome === "cleanup_unknown"
|
|
77
|
+
? EXIT_OUTCOME_UNKNOWN
|
|
78
|
+
: exitCode;
|
|
79
|
+
};
|
|
80
|
+
export const runIntegrationCommand = (tokens, context) => {
|
|
81
|
+
const [subcommand, ...rest] = tokens;
|
|
82
|
+
if (subcommand === "plan")
|
|
83
|
+
return runPlan(rest, context);
|
|
84
|
+
if (subcommand === "apply")
|
|
85
|
+
return runApply(rest, context);
|
|
86
|
+
if (subcommand === "status")
|
|
87
|
+
return runStatus(rest, context);
|
|
88
|
+
if (subcommand === "remove")
|
|
89
|
+
return runRemove(rest, context);
|
|
90
|
+
throw new CliArgumentError(`Usage: ${INTEGRATION_USAGE}`);
|
|
91
|
+
};
|
|
92
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LocalNodeClient, LocalNodeRequestOptions, ProtocolError } from "@maiaos/sdk";
|
|
2
|
+
import { type LocalNodeConnection, type LocalNodeDiscoveryOptions } from "@maiaos/sdk/node";
|
|
3
|
+
export type CliMutationRecovery = {
|
|
4
|
+
readonly commandId: string;
|
|
5
|
+
};
|
|
6
|
+
export type CliNodeResult<TValue> = {
|
|
7
|
+
readonly error: ProtocolError;
|
|
8
|
+
readonly ok: false;
|
|
9
|
+
readonly recovery?: CliMutationRecovery;
|
|
10
|
+
} | {
|
|
11
|
+
readonly ok: true;
|
|
12
|
+
readonly value: TValue;
|
|
13
|
+
};
|
|
14
|
+
export declare const newCliIdentifier: (prefix: "command" | "request") => string;
|
|
15
|
+
export declare const resolveCliDiscoveryOptions: () => LocalNodeDiscoveryOptions;
|
|
16
|
+
export declare const connectCliLocalNode: (signal: AbortSignal) => Promise<LocalNodeConnection>;
|
|
17
|
+
export declare const outcomeCanBeAmbiguous: (error: unknown) => boolean;
|
|
18
|
+
export declare const invalidNodeInput: <TValue>() => Promise<CliNodeResult<TValue>>;
|
|
19
|
+
export declare const runNodeOperation: <TValue>(operation: (signal: AbortSignal) => Promise<TValue>, recovery?: CliMutationRecovery) => Promise<CliNodeResult<TValue>>;
|
|
20
|
+
export declare const runNodeClientOperation: <TValue>(operation: (client: LocalNodeClient, options: LocalNodeRequestOptions) => Promise<TValue>, recovery?: CliMutationRecovery) => Promise<CliNodeResult<TValue>>;
|
|
21
|
+
type ParameterSchema<TParameters> = {
|
|
22
|
+
readonly safeParse: (input: unknown) => {
|
|
23
|
+
readonly data: TParameters;
|
|
24
|
+
readonly success: true;
|
|
25
|
+
} | {
|
|
26
|
+
readonly success: false;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export declare const runValidatedNodeOperation: <TParameters, TValue>(...[input, schema, operation, recovery]: readonly [input: unknown, schema: ParameterSchema<TParameters>, operation: (client: LocalNodeClient, parameters: TParameters, options: LocalNodeRequestOptions) => Promise<TValue>, recovery?: CliMutationRecovery]) => Promise<CliNodeResult<TValue>>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { MaiaClientError, protocolErrorSchema } from "@maiaos/sdk";
|
|
3
|
+
import { connectLocalNode, } from "@maiaos/sdk/node";
|
|
4
|
+
import * as Effect from "effect/Effect";
|
|
5
|
+
export const newCliIdentifier = (prefix) => `${prefix}_${randomUUID().replaceAll("-", "")}`;
|
|
6
|
+
export const resolveCliDiscoveryOptions = () => {
|
|
7
|
+
if (process.env.MAIA_CLI_TEST_MODE !== "1")
|
|
8
|
+
return {};
|
|
9
|
+
const runtimeRootOverride = process.env.MAIA_CLI_TEST_RUNTIME_ROOT;
|
|
10
|
+
if (runtimeRootOverride === undefined) {
|
|
11
|
+
throw new Error("The CLI test runtime root is missing.");
|
|
12
|
+
}
|
|
13
|
+
return { runtimeRootOverride };
|
|
14
|
+
};
|
|
15
|
+
export const connectCliLocalNode = (signal) => connectLocalNode({ ...resolveCliDiscoveryOptions(), signal });
|
|
16
|
+
const LOCAL_DEADLINE_ERROR = {
|
|
17
|
+
code: "deadline_exceeded",
|
|
18
|
+
message: "Local request expired before dispatch.",
|
|
19
|
+
retryable: true,
|
|
20
|
+
};
|
|
21
|
+
const LOCAL_OUTCOME_UNKNOWN_ERROR = {
|
|
22
|
+
code: "outcome_unknown",
|
|
23
|
+
message: "Local request outcome unknown.",
|
|
24
|
+
retryable: false,
|
|
25
|
+
};
|
|
26
|
+
const LOCAL_SATURATED_ERROR = {
|
|
27
|
+
code: "saturated",
|
|
28
|
+
message: "Local node saturated.",
|
|
29
|
+
retryable: true,
|
|
30
|
+
};
|
|
31
|
+
const localOperationError = (error) => {
|
|
32
|
+
if (error.code === "deadline_exceeded")
|
|
33
|
+
return LOCAL_DEADLINE_ERROR;
|
|
34
|
+
if (error.code === "outcome_unknown")
|
|
35
|
+
return LOCAL_OUTCOME_UNKNOWN_ERROR;
|
|
36
|
+
if (error.code === "saturated")
|
|
37
|
+
return LOCAL_SATURATED_ERROR;
|
|
38
|
+
};
|
|
39
|
+
const operationError = (error) => {
|
|
40
|
+
const remoteError = error instanceof Error && "remoteError" in error
|
|
41
|
+
? error.remoteError
|
|
42
|
+
: undefined;
|
|
43
|
+
const parsed = protocolErrorSchema.safeParse(remoteError);
|
|
44
|
+
if (parsed.success)
|
|
45
|
+
return parsed.data;
|
|
46
|
+
if (error instanceof MaiaClientError) {
|
|
47
|
+
if (error.code === "invalid_request") {
|
|
48
|
+
return {
|
|
49
|
+
code: "invalid_argument",
|
|
50
|
+
message: "Command input is invalid.",
|
|
51
|
+
retryable: false,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const local = localOperationError(error);
|
|
55
|
+
if (local !== undefined)
|
|
56
|
+
return local;
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
code: "node_unavailable",
|
|
60
|
+
message: "Local Maia node unavailable.",
|
|
61
|
+
retryable: true,
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
export const outcomeCanBeAmbiguous = (error) => !(error instanceof MaiaClientError) ||
|
|
65
|
+
(error.code !== "deadline_exceeded" &&
|
|
66
|
+
error.code !== "invalid_request" &&
|
|
67
|
+
error.code !== "saturated");
|
|
68
|
+
export const invalidNodeInput = () => Promise.resolve({
|
|
69
|
+
error: {
|
|
70
|
+
code: "invalid_argument",
|
|
71
|
+
message: "The command input is invalid.",
|
|
72
|
+
retryable: false,
|
|
73
|
+
},
|
|
74
|
+
ok: false,
|
|
75
|
+
});
|
|
76
|
+
export const runNodeOperation = (operation, recovery) => Effect.runPromise(Effect.tryPromise({
|
|
77
|
+
catch: (cause) => ({ cause, error: operationError(cause) }),
|
|
78
|
+
try: operation,
|
|
79
|
+
}).pipe(Effect.map((value) => ({ ok: true, value })), Effect.catch(({ cause, error }) => Effect.succeed({
|
|
80
|
+
error,
|
|
81
|
+
ok: false,
|
|
82
|
+
...(recovery !== undefined && outcomeCanBeAmbiguous(cause)
|
|
83
|
+
? { recovery }
|
|
84
|
+
: {}),
|
|
85
|
+
}))));
|
|
86
|
+
export const runNodeClientOperation = (operation, recovery) => runNodeOperation(async (signal) => {
|
|
87
|
+
const connection = await connectCliLocalNode(signal);
|
|
88
|
+
return operation(connection.client, {
|
|
89
|
+
messageId: newCliIdentifier("request"),
|
|
90
|
+
signal,
|
|
91
|
+
});
|
|
92
|
+
}, recovery);
|
|
93
|
+
export const runValidatedNodeOperation = (...[input, schema, operation, recovery]) => {
|
|
94
|
+
const parameters = schema.safeParse(input);
|
|
95
|
+
if (!parameters.success)
|
|
96
|
+
return invalidNodeInput();
|
|
97
|
+
return runNodeClientOperation((client, options) => operation(client, parameters.data, options), recovery);
|
|
98
|
+
};
|
|
99
|
+
//# sourceMappingURL=client.js.map
|