@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,160 @@
|
|
|
1
|
+
import { CliArgumentError, parseOptions, readCursor, readExpectedRevision, readPageSize, requirePositionals, } from "../command-line/arguments.js";
|
|
2
|
+
import { writeNodeResult } from "../command-line/output.js";
|
|
3
|
+
const SESSION_CREATE_USAGE = "maia session create <workspace-id> --runtime <codex|pi> [--profile <codex|pi-rpc>]";
|
|
4
|
+
const SESSION_CREATE_SELECTION_ERROR = "Use '--runtime codex [--profile codex]' or '--runtime pi --profile pi-rpc'.";
|
|
5
|
+
const SESSION_CREATE_OPTIONS = new Set([
|
|
6
|
+
"--command-id",
|
|
7
|
+
"--profile",
|
|
8
|
+
"--runtime",
|
|
9
|
+
]);
|
|
10
|
+
const summarizeSessionCreation = (result) => ({
|
|
11
|
+
delivery: result.delivery,
|
|
12
|
+
receipt: result.receipt,
|
|
13
|
+
sessionId: result.session.id,
|
|
14
|
+
state: result.session.state,
|
|
15
|
+
workspaceId: result.session.workspaceId,
|
|
16
|
+
workspaceRevision: result.session.workspaceRevision,
|
|
17
|
+
});
|
|
18
|
+
const summarizeSessionStart = (result) => ({
|
|
19
|
+
delivery: result.delivery,
|
|
20
|
+
receipt: result.receipt,
|
|
21
|
+
revision: result.session.revision,
|
|
22
|
+
sessionId: result.session.id,
|
|
23
|
+
state: result.session.state,
|
|
24
|
+
});
|
|
25
|
+
const readSessionEventPageSize = (value) => {
|
|
26
|
+
if (value === undefined)
|
|
27
|
+
return 2;
|
|
28
|
+
if (!/^(?:[1-9]|[12]\d|3[0-2])$/u.test(value)) {
|
|
29
|
+
throw new CliArgumentError("Option '--limit' must be an integer from 1 to 32 for session events.");
|
|
30
|
+
}
|
|
31
|
+
return Number(value);
|
|
32
|
+
};
|
|
33
|
+
const readSessionCreateOptions = (tokens) => {
|
|
34
|
+
const parsed = parseOptions(tokens, SESSION_CREATE_OPTIONS);
|
|
35
|
+
requirePositionals(parsed.positionals, 1, SESSION_CREATE_USAGE);
|
|
36
|
+
const workspaceId = parsed.positionals[0];
|
|
37
|
+
const runtime = parsed.options.get("--runtime");
|
|
38
|
+
const profile = parsed.options.get("--profile");
|
|
39
|
+
if (workspaceId === undefined ||
|
|
40
|
+
(runtime !== "codex" && runtime !== "pi") ||
|
|
41
|
+
(runtime === "codex" && profile !== undefined && profile !== "codex") ||
|
|
42
|
+
(runtime === "pi" && profile !== "pi-rpc")) {
|
|
43
|
+
throw new CliArgumentError(SESSION_CREATE_SELECTION_ERROR);
|
|
44
|
+
}
|
|
45
|
+
const command = parsed.options.has("--command-id")
|
|
46
|
+
? { commandId: parsed.options.get("--command-id") }
|
|
47
|
+
: {};
|
|
48
|
+
return runtime === "pi"
|
|
49
|
+
? { ...command, profile: "pi-rpc", runtime, workspaceId }
|
|
50
|
+
: {
|
|
51
|
+
...command,
|
|
52
|
+
...(profile === "codex" ? { profile } : {}),
|
|
53
|
+
runtime,
|
|
54
|
+
workspaceId,
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
const createSessionInput = (options) => options.runtime === "pi"
|
|
58
|
+
? {
|
|
59
|
+
...(options.commandId === undefined
|
|
60
|
+
? {}
|
|
61
|
+
: { commandId: options.commandId }),
|
|
62
|
+
profile: "pi-rpc",
|
|
63
|
+
runtime: options.runtime,
|
|
64
|
+
workspaceId: options.workspaceId,
|
|
65
|
+
}
|
|
66
|
+
: {
|
|
67
|
+
...(options.commandId === undefined
|
|
68
|
+
? {}
|
|
69
|
+
: { commandId: options.commandId }),
|
|
70
|
+
...(options.profile === "codex" ? { profile: options.profile } : {}),
|
|
71
|
+
runtime: options.runtime,
|
|
72
|
+
workspaceId: options.workspaceId,
|
|
73
|
+
};
|
|
74
|
+
const runSessionCreate = async (tokens, context) => {
|
|
75
|
+
const result = await context.dependencies.createSession(createSessionInput(readSessionCreateOptions(tokens)));
|
|
76
|
+
return writeNodeResult(result, context, (value) => ({
|
|
77
|
+
command: "session.create",
|
|
78
|
+
result: summarizeSessionCreation(value),
|
|
79
|
+
}));
|
|
80
|
+
};
|
|
81
|
+
const runSessionList = async (tokens, context) => {
|
|
82
|
+
const parsed = parseOptions(tokens, new Set(["--after", "--limit", "--project"]));
|
|
83
|
+
requirePositionals(parsed.positionals, 0, "maia session list --project <id>");
|
|
84
|
+
const projectId = parsed.options.get("--project");
|
|
85
|
+
if (projectId === undefined) {
|
|
86
|
+
throw new CliArgumentError("Option '--project' is required.");
|
|
87
|
+
}
|
|
88
|
+
const result = await context.dependencies.listSessions({
|
|
89
|
+
afterCursor: readCursor(parsed.options.get("--after")),
|
|
90
|
+
limit: readPageSize(parsed.options.get("--limit")),
|
|
91
|
+
projectId,
|
|
92
|
+
});
|
|
93
|
+
return writeNodeResult(result, context, (value) => ({
|
|
94
|
+
command: "session.list",
|
|
95
|
+
result: value,
|
|
96
|
+
}));
|
|
97
|
+
};
|
|
98
|
+
const runSessionShow = async (tokens, context) => {
|
|
99
|
+
const parsed = parseOptions(tokens, new Set());
|
|
100
|
+
requirePositionals(parsed.positionals, 1, "maia session show <session-id>");
|
|
101
|
+
const sessionId = parsed.positionals[0];
|
|
102
|
+
if (sessionId === undefined) {
|
|
103
|
+
throw new CliArgumentError("The session identifier is missing.");
|
|
104
|
+
}
|
|
105
|
+
const result = await context.dependencies.showSession(sessionId);
|
|
106
|
+
return writeNodeResult(result, context, (value) => ({
|
|
107
|
+
command: "session.show",
|
|
108
|
+
result: value,
|
|
109
|
+
}));
|
|
110
|
+
};
|
|
111
|
+
const runSessionStart = async (tokens, context) => {
|
|
112
|
+
const parsed = parseOptions(tokens, new Set(["--command-id", "--expected-revision"]));
|
|
113
|
+
requirePositionals(parsed.positionals, 1, "maia session start <session-id> --expected-revision <revision>");
|
|
114
|
+
const sessionId = parsed.positionals[0];
|
|
115
|
+
if (sessionId === undefined) {
|
|
116
|
+
throw new CliArgumentError("The session identifier is missing.");
|
|
117
|
+
}
|
|
118
|
+
const commandId = parsed.options.get("--command-id");
|
|
119
|
+
const result = await context.dependencies.startSession({
|
|
120
|
+
expectedRevision: readExpectedRevision(parsed.options.get("--expected-revision")),
|
|
121
|
+
sessionId,
|
|
122
|
+
...(commandId === undefined ? {} : { commandId }),
|
|
123
|
+
});
|
|
124
|
+
return writeNodeResult(result, context, (value) => ({
|
|
125
|
+
command: "session.start",
|
|
126
|
+
result: summarizeSessionStart(value),
|
|
127
|
+
}));
|
|
128
|
+
};
|
|
129
|
+
const runSessionEvents = async (tokens, context) => {
|
|
130
|
+
const parsed = parseOptions(tokens, new Set(["--after", "--limit"]));
|
|
131
|
+
requirePositionals(parsed.positionals, 1, "maia session events <session-id>");
|
|
132
|
+
const sessionId = parsed.positionals[0];
|
|
133
|
+
if (sessionId === undefined) {
|
|
134
|
+
throw new CliArgumentError("The session identifier is missing.");
|
|
135
|
+
}
|
|
136
|
+
const result = await context.dependencies.listSessionEvents({
|
|
137
|
+
afterSessionCursor: readCursor(parsed.options.get("--after")),
|
|
138
|
+
limit: readSessionEventPageSize(parsed.options.get("--limit")),
|
|
139
|
+
sessionId,
|
|
140
|
+
});
|
|
141
|
+
return writeNodeResult(result, context, (value) => ({
|
|
142
|
+
command: "session.events",
|
|
143
|
+
result: value,
|
|
144
|
+
}));
|
|
145
|
+
};
|
|
146
|
+
export const runSessionCommand = (tokens, context) => {
|
|
147
|
+
const [subcommand, ...rest] = tokens;
|
|
148
|
+
if (subcommand === "create")
|
|
149
|
+
return runSessionCreate(rest, context);
|
|
150
|
+
if (subcommand === "events")
|
|
151
|
+
return runSessionEvents(rest, context);
|
|
152
|
+
if (subcommand === "list")
|
|
153
|
+
return runSessionList(rest, context);
|
|
154
|
+
if (subcommand === "show")
|
|
155
|
+
return runSessionShow(rest, context);
|
|
156
|
+
if (subcommand === "start")
|
|
157
|
+
return runSessionStart(rest, context);
|
|
158
|
+
throw new CliArgumentError("Usage: maia session <create|events|list|show|start>");
|
|
159
|
+
};
|
|
160
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LocalNodeStatusResult, MonitorBootstrapCreateResult } from "@maiaos/sdk";
|
|
2
|
+
import { type CliNodeResult } from "../local-node/client.js";
|
|
3
|
+
export declare const readLocalNodeStatus: () => Promise<LocalNodeStatusResult>;
|
|
4
|
+
export declare const createMonitorBootstrap: () => Promise<CliNodeResult<MonitorBootstrapCreateResult>>;
|
|
5
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import * as Effect from "effect/Effect";
|
|
2
|
+
import { connectCliLocalNode, runNodeClientOperation, } from "../local-node/client.js";
|
|
3
|
+
class CliStatusError extends Error {
|
|
4
|
+
_tag = "CliStatusError";
|
|
5
|
+
}
|
|
6
|
+
const statusEffect = Effect.fn("Cli.status")(function* () {
|
|
7
|
+
const connection = yield* Effect.tryPromise({
|
|
8
|
+
catch: () => new CliStatusError("Local Maia node unavailable."),
|
|
9
|
+
try: (signal) => connectCliLocalNode(signal),
|
|
10
|
+
});
|
|
11
|
+
return connection.status;
|
|
12
|
+
});
|
|
13
|
+
export const readLocalNodeStatus = () => Effect.runPromise(statusEffect());
|
|
14
|
+
export const createMonitorBootstrap = () => runNodeClientOperation((client, options) => client.createMonitorBootstrap(options));
|
|
15
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { reportError, writeStatusResult } from "../command-line/output.js";
|
|
2
|
+
const createUnavailableError = () => ({
|
|
3
|
+
code: "node_unavailable",
|
|
4
|
+
message: "The local Maia node is unavailable.",
|
|
5
|
+
retryable: true,
|
|
6
|
+
});
|
|
7
|
+
export const runStatusCommand = async (context) => {
|
|
8
|
+
try {
|
|
9
|
+
const node = await context.dependencies.readStatus();
|
|
10
|
+
writeStatusResult(node, context);
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return reportError(createUnavailableError(), context);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
//# sourceMappingURL=command.js.map
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { LocalNodeStatusResult } from "@maiaos/sdk";
|
|
2
|
+
export declare const sumObservationWarningTrees: (observations: LocalNodeStatusResult["processResources"]["observations"]) => number;
|
|
3
|
+
export type CliCompactStatusResult = {
|
|
4
|
+
readonly command: "status";
|
|
5
|
+
readonly instanceId: LocalNodeStatusResult["instanceId"];
|
|
6
|
+
readonly lifecycle: LocalNodeStatusResult["lifecycle"];
|
|
7
|
+
readonly pid: LocalNodeStatusResult["pid"];
|
|
8
|
+
readonly processResources: {
|
|
9
|
+
readonly admission: {
|
|
10
|
+
readonly capacity: LocalNodeStatusResult["processResources"]["admission"]["capacity"];
|
|
11
|
+
readonly state: LocalNodeStatusResult["processResources"]["admission"]["state"];
|
|
12
|
+
readonly usedTrees: LocalNodeStatusResult["processResources"]["admission"]["usedTrees"];
|
|
13
|
+
};
|
|
14
|
+
readonly capability: {
|
|
15
|
+
readonly hardLimitEnforcement: LocalNodeStatusResult["processResources"]["capability"]["hardLimitEnforcement"];
|
|
16
|
+
readonly mode: LocalNodeStatusResult["processResources"]["capability"]["mode"];
|
|
17
|
+
readonly releaseQualified: LocalNodeStatusResult["processResources"]["capability"]["releaseQualified"];
|
|
18
|
+
};
|
|
19
|
+
readonly nextStep: LocalNodeStatusResult["processResources"]["nextStep"];
|
|
20
|
+
readonly pressure: LocalNodeStatusResult["processResources"]["pressure"];
|
|
21
|
+
readonly warningTrees: number;
|
|
22
|
+
};
|
|
23
|
+
readonly profile: LocalNodeStatusResult["profile"];
|
|
24
|
+
readonly storage: {
|
|
25
|
+
readonly integrity: LocalNodeStatusResult["storage"]["integrity"];
|
|
26
|
+
readonly journalMode: LocalNodeStatusResult["storage"]["journalMode"];
|
|
27
|
+
readonly schemaVersion: LocalNodeStatusResult["storage"]["schemaVersion"];
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
export declare const projectStatusResult: (node: LocalNodeStatusResult) => CliCompactStatusResult;
|
|
31
|
+
//# sourceMappingURL=compact.d.ts.map
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
const observedMetricKeys = [
|
|
2
|
+
"cpuTimeMilliseconds",
|
|
3
|
+
"fileDescriptorCount",
|
|
4
|
+
"ioReadBytes",
|
|
5
|
+
"ioWriteBytes",
|
|
6
|
+
"observedPeakRssBytes",
|
|
7
|
+
"processCount",
|
|
8
|
+
"rssBytes",
|
|
9
|
+
];
|
|
10
|
+
const warningTreesFromMetric = (metric) => "warningTrees" in metric && typeof metric.warningTrees === "number"
|
|
11
|
+
? metric.warningTrees
|
|
12
|
+
: undefined;
|
|
13
|
+
export const sumObservationWarningTrees = (observations) => observedMetricKeys.reduce((total, key) => {
|
|
14
|
+
const warningTrees = warningTreesFromMetric(observations[key]);
|
|
15
|
+
return warningTrees === undefined ? total : total + warningTrees;
|
|
16
|
+
}, 0);
|
|
17
|
+
const projectStatusAdmission = (admission) => ({
|
|
18
|
+
capacity: admission.capacity,
|
|
19
|
+
state: admission.state,
|
|
20
|
+
usedTrees: admission.usedTrees,
|
|
21
|
+
});
|
|
22
|
+
const projectStatusCapability = (capability) => ({
|
|
23
|
+
hardLimitEnforcement: capability.hardLimitEnforcement,
|
|
24
|
+
mode: capability.mode,
|
|
25
|
+
releaseQualified: capability.releaseQualified,
|
|
26
|
+
});
|
|
27
|
+
export const projectStatusResult = (node) => ({
|
|
28
|
+
command: "status",
|
|
29
|
+
instanceId: node.instanceId,
|
|
30
|
+
lifecycle: node.lifecycle,
|
|
31
|
+
pid: node.pid,
|
|
32
|
+
processResources: {
|
|
33
|
+
admission: projectStatusAdmission(node.processResources.admission),
|
|
34
|
+
capability: projectStatusCapability(node.processResources.capability),
|
|
35
|
+
nextStep: node.processResources.nextStep,
|
|
36
|
+
pressure: node.processResources.pressure,
|
|
37
|
+
warningTrees: sumObservationWarningTrees(node.processResources.observations),
|
|
38
|
+
},
|
|
39
|
+
profile: node.profile,
|
|
40
|
+
storage: {
|
|
41
|
+
integrity: node.storage.integrity,
|
|
42
|
+
journalMode: node.storage.journalMode,
|
|
43
|
+
schemaVersion: node.storage.schemaVersion,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
//# sourceMappingURL=compact.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { LiveTerminalCloseParameters } from "@maiaos/sdk";
|
|
2
|
+
import { type ParsedOptions } from "../command-line/arguments.js";
|
|
3
|
+
export declare const readTerminalColumns: (value: string | undefined, fallback?: number) => number;
|
|
4
|
+
export declare const readTerminalRows: (value: string | undefined, fallback?: number) => number;
|
|
5
|
+
export declare const readTerminalGeneration: (parsed: ParsedOptions) => number;
|
|
6
|
+
export declare const readTerminalLeaseDuration: (parsed: ParsedOptions) => number;
|
|
7
|
+
export declare const readTerminalInputSequence: (parsed: ParsedOptions) => number;
|
|
8
|
+
export declare const readTerminalExpectedRevision: (parsed: ParsedOptions) => string;
|
|
9
|
+
export type TerminalControllerFenceInput = Omit<LiveTerminalCloseParameters, "commandId">;
|
|
10
|
+
export declare const readTerminalControllerFence: (parsed: ParsedOptions, terminalId: string) => TerminalControllerFenceInput;
|
|
11
|
+
export declare const terminalControllerFenceOptionNames: readonly ["--command-id", "--controller-epoch", "--controller-expires-at", "--controller-id", "--controller-revision", "--expected-revision", "--terminal-generation"];
|
|
12
|
+
//# sourceMappingURL=arguments.d.ts.map
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { MAX_TERMINAL_COLUMNS, MAX_TERMINAL_CONTROLLER_LEASE_MS, MAX_TERMINAL_GENERATION, MAX_TERMINAL_INPUT_SEQUENCE, MAX_TERMINAL_ROWS, MIN_TERMINAL_COLUMNS, MIN_TERMINAL_CONTROLLER_LEASE_MS, MIN_TERMINAL_ROWS, } from "@maiaos/sdk";
|
|
2
|
+
import { CliArgumentError, } from "../command-line/arguments.js";
|
|
3
|
+
const MAX_SIGNED_SQLITE_INTEGER = 9223372036854775807n;
|
|
4
|
+
const requiredOption = (parsed, name) => {
|
|
5
|
+
const value = parsed.options.get(name);
|
|
6
|
+
if (value === undefined) {
|
|
7
|
+
throw new CliArgumentError(`Option '${name}' is required.`);
|
|
8
|
+
}
|
|
9
|
+
return value;
|
|
10
|
+
};
|
|
11
|
+
const readBoundedInteger = (value, bounds) => {
|
|
12
|
+
const { maximum, minimum, name } = bounds;
|
|
13
|
+
if (!/^[1-9]\d*$/u.test(value)) {
|
|
14
|
+
throw new CliArgumentError(`Option '${name}' must be an integer from ${String(minimum)} to ${String(maximum)}.`);
|
|
15
|
+
}
|
|
16
|
+
const parsed = Number(value);
|
|
17
|
+
if (!Number.isSafeInteger(parsed) || parsed < minimum || parsed > maximum) {
|
|
18
|
+
throw new CliArgumentError(`Option '${name}' must be an integer from ${String(minimum)} to ${String(maximum)}.`);
|
|
19
|
+
}
|
|
20
|
+
return parsed;
|
|
21
|
+
};
|
|
22
|
+
const readRevision = (value, name) => {
|
|
23
|
+
if (!/^(?:0|[1-9]\d*)$/u.test(value) ||
|
|
24
|
+
BigInt(value) > MAX_SIGNED_SQLITE_INTEGER) {
|
|
25
|
+
throw new CliArgumentError(`Option '${name}' must be a non-negative signed 64-bit integer.`);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
};
|
|
29
|
+
export const readTerminalColumns = (value, fallback) => readBoundedInteger(value ?? String(fallback), {
|
|
30
|
+
maximum: MAX_TERMINAL_COLUMNS,
|
|
31
|
+
minimum: MIN_TERMINAL_COLUMNS,
|
|
32
|
+
name: "--columns",
|
|
33
|
+
});
|
|
34
|
+
export const readTerminalRows = (value, fallback) => readBoundedInteger(value ?? String(fallback), {
|
|
35
|
+
maximum: MAX_TERMINAL_ROWS,
|
|
36
|
+
minimum: MIN_TERMINAL_ROWS,
|
|
37
|
+
name: "--rows",
|
|
38
|
+
});
|
|
39
|
+
export const readTerminalGeneration = (parsed) => readBoundedInteger(requiredOption(parsed, "--terminal-generation"), {
|
|
40
|
+
maximum: MAX_TERMINAL_GENERATION,
|
|
41
|
+
minimum: 1,
|
|
42
|
+
name: "--terminal-generation",
|
|
43
|
+
});
|
|
44
|
+
export const readTerminalLeaseDuration = (parsed) => readBoundedInteger(requiredOption(parsed, "--lease-ms"), {
|
|
45
|
+
maximum: MAX_TERMINAL_CONTROLLER_LEASE_MS,
|
|
46
|
+
minimum: MIN_TERMINAL_CONTROLLER_LEASE_MS,
|
|
47
|
+
name: "--lease-ms",
|
|
48
|
+
});
|
|
49
|
+
export const readTerminalInputSequence = (parsed) => readBoundedInteger(requiredOption(parsed, "--input-sequence"), {
|
|
50
|
+
maximum: MAX_TERMINAL_INPUT_SEQUENCE,
|
|
51
|
+
minimum: 1,
|
|
52
|
+
name: "--input-sequence",
|
|
53
|
+
});
|
|
54
|
+
export const readTerminalExpectedRevision = (parsed) => readRevision(requiredOption(parsed, "--expected-revision"), "--expected-revision");
|
|
55
|
+
export const readTerminalControllerFence = (parsed, terminalId) => {
|
|
56
|
+
const terminalGeneration = readTerminalGeneration(parsed);
|
|
57
|
+
return {
|
|
58
|
+
controller: {
|
|
59
|
+
epoch: readRevision(requiredOption(parsed, "--controller-epoch"), "--controller-epoch"),
|
|
60
|
+
expiresAt: requiredOption(parsed, "--controller-expires-at"),
|
|
61
|
+
id: requiredOption(parsed, "--controller-id"),
|
|
62
|
+
revision: readRevision(requiredOption(parsed, "--controller-revision"), "--controller-revision"),
|
|
63
|
+
terminalGeneration,
|
|
64
|
+
terminalId,
|
|
65
|
+
},
|
|
66
|
+
expectedTerminalRevision: readTerminalExpectedRevision(parsed),
|
|
67
|
+
terminalId,
|
|
68
|
+
};
|
|
69
|
+
};
|
|
70
|
+
export const terminalControllerFenceOptionNames = [
|
|
71
|
+
"--command-id",
|
|
72
|
+
"--controller-epoch",
|
|
73
|
+
"--controller-expires-at",
|
|
74
|
+
"--controller-id",
|
|
75
|
+
"--controller-revision",
|
|
76
|
+
"--expected-revision",
|
|
77
|
+
"--terminal-generation",
|
|
78
|
+
];
|
|
79
|
+
//# sourceMappingURL=arguments.js.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { LiveTerminalCloseParameters, LiveTerminalCloseResult, LiveTerminalControllerAcquireParameters, LiveTerminalControllerAcquireResult, LiveTerminalControllerReleaseParameters, LiveTerminalControllerReleaseResult, LiveTerminalControllerRequestParameters, LiveTerminalControllerRequestResult, LiveTerminalControllerRequestShowParameters, LiveTerminalControllerRequestShowResult, LiveTerminalResizeParameters, LiveTerminalResizeResult, LiveTerminalSignalParameters, LiveTerminalSignalResult, LiveTerminalWriteParameters, LiveTerminalWriteResult, TerminalCreateResult, TerminalEventsListResult, TerminalListResult, TerminalReadResult, TerminalShowResult } from "@maiaos/sdk";
|
|
2
|
+
import { type CliNodeResult } from "../local-node/client.js";
|
|
3
|
+
export type CreateTerminalInput = {
|
|
4
|
+
readonly columns: number;
|
|
5
|
+
readonly commandId?: string;
|
|
6
|
+
readonly interactive: true;
|
|
7
|
+
readonly rows: number;
|
|
8
|
+
readonly workspaceId: string;
|
|
9
|
+
} | {
|
|
10
|
+
readonly commandId?: string;
|
|
11
|
+
readonly interactive?: false;
|
|
12
|
+
readonly workspaceId: string;
|
|
13
|
+
};
|
|
14
|
+
export declare const createTerminal: (input: CreateTerminalInput) => Promise<CliNodeResult<TerminalCreateResult>>;
|
|
15
|
+
type OptionalCommandId<TParameters extends {
|
|
16
|
+
readonly commandId: string;
|
|
17
|
+
}> = Omit<TParameters, "commandId"> & {
|
|
18
|
+
readonly commandId?: string;
|
|
19
|
+
};
|
|
20
|
+
export declare const requestTerminalController: (input: OptionalCommandId<LiveTerminalControllerRequestParameters>) => Promise<CliNodeResult<LiveTerminalControllerRequestResult>>;
|
|
21
|
+
export declare const showTerminalControllerRequest: (input: LiveTerminalControllerRequestShowParameters) => Promise<CliNodeResult<LiveTerminalControllerRequestShowResult>>;
|
|
22
|
+
export declare const acquireTerminalController: (input: OptionalCommandId<LiveTerminalControllerAcquireParameters>) => Promise<CliNodeResult<LiveTerminalControllerAcquireResult>>;
|
|
23
|
+
export declare const releaseTerminalController: (input: OptionalCommandId<LiveTerminalControllerReleaseParameters>) => Promise<CliNodeResult<LiveTerminalControllerReleaseResult>>;
|
|
24
|
+
export declare const writeTerminalInput: (input: OptionalCommandId<LiveTerminalWriteParameters>) => Promise<CliNodeResult<LiveTerminalWriteResult>>;
|
|
25
|
+
export declare const resizeTerminal: (input: OptionalCommandId<LiveTerminalResizeParameters>) => Promise<CliNodeResult<LiveTerminalResizeResult>>;
|
|
26
|
+
export declare const signalTerminal: (input: OptionalCommandId<LiveTerminalSignalParameters>) => Promise<CliNodeResult<LiveTerminalSignalResult>>;
|
|
27
|
+
export declare const closeTerminal: (input: OptionalCommandId<LiveTerminalCloseParameters>) => Promise<CliNodeResult<LiveTerminalCloseResult>>;
|
|
28
|
+
export declare const listTerminals: (input: {
|
|
29
|
+
readonly afterCursor: string;
|
|
30
|
+
readonly limit: number;
|
|
31
|
+
readonly workspaceId: string;
|
|
32
|
+
}) => Promise<CliNodeResult<TerminalListResult>>;
|
|
33
|
+
export declare const showTerminal: (terminalId: string) => Promise<CliNodeResult<TerminalShowResult>>;
|
|
34
|
+
export declare const listTerminalEvents: (input: {
|
|
35
|
+
readonly afterTerminalCursor: string;
|
|
36
|
+
readonly limit: number;
|
|
37
|
+
readonly terminalId: string;
|
|
38
|
+
}) => Promise<CliNodeResult<TerminalEventsListResult>>;
|
|
39
|
+
export declare const readTerminal: (input: {
|
|
40
|
+
readonly afterChunkCursor: string;
|
|
41
|
+
readonly limit: number;
|
|
42
|
+
readonly terminalId: string;
|
|
43
|
+
}) => Promise<CliNodeResult<TerminalReadResult>>;
|
|
44
|
+
export {};
|
|
45
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { liveTerminalCloseParametersSchema, liveTerminalControllerAcquireParametersSchema, liveTerminalControllerReleaseParametersSchema, liveTerminalControllerRequestParametersSchema, liveTerminalControllerRequestShowParametersSchema, liveTerminalResizeParametersSchema, liveTerminalSignalParametersSchema, liveTerminalWriteParametersSchema, terminalCreateParametersSchema, terminalEventsListParametersSchema, terminalListParametersSchema, terminalReadParametersSchema, terminalShowParametersSchema, } from "@maiaos/sdk";
|
|
2
|
+
import { newCliIdentifier, runValidatedNodeOperation, } from "../local-node/client.js";
|
|
3
|
+
export const createTerminal = (input) => {
|
|
4
|
+
const commandId = input.commandId ?? newCliIdentifier("command");
|
|
5
|
+
return runValidatedNodeOperation(input.interactive === true
|
|
6
|
+
? {
|
|
7
|
+
columns: input.columns,
|
|
8
|
+
commandId,
|
|
9
|
+
expectedRevision: "0",
|
|
10
|
+
mode: "interactive",
|
|
11
|
+
rows: input.rows,
|
|
12
|
+
workspaceId: input.workspaceId,
|
|
13
|
+
}
|
|
14
|
+
: {
|
|
15
|
+
commandId,
|
|
16
|
+
expectedRevision: "0",
|
|
17
|
+
workspaceId: input.workspaceId,
|
|
18
|
+
}, terminalCreateParametersSchema, (client, parameters, options) => client.createTerminal(parameters, options), { commandId });
|
|
19
|
+
};
|
|
20
|
+
const runValidatedTerminalMutation = (input, schema, operation) => {
|
|
21
|
+
const commandId = input.commandId ?? newCliIdentifier("command");
|
|
22
|
+
return runValidatedNodeOperation({ ...input, commandId }, schema, operation, {
|
|
23
|
+
commandId,
|
|
24
|
+
});
|
|
25
|
+
};
|
|
26
|
+
export const requestTerminalController = (input) => runValidatedTerminalMutation(input, liveTerminalControllerRequestParametersSchema, (client, parameters, options) => client.requestTerminalController(parameters, options));
|
|
27
|
+
export const showTerminalControllerRequest = (input) => {
|
|
28
|
+
return runValidatedNodeOperation(input, liveTerminalControllerRequestShowParametersSchema, (client, parameters, options) => client.showTerminalControllerRequest(parameters, options));
|
|
29
|
+
};
|
|
30
|
+
export const acquireTerminalController = (input) => runValidatedTerminalMutation(input, liveTerminalControllerAcquireParametersSchema, (client, parameters, options) => client.acquireTerminalController(parameters, options));
|
|
31
|
+
export const releaseTerminalController = (input) => runValidatedTerminalMutation(input, liveTerminalControllerReleaseParametersSchema, (client, parameters, options) => client.releaseTerminalController(parameters, options));
|
|
32
|
+
export const writeTerminalInput = (input) => runValidatedTerminalMutation(input, liveTerminalWriteParametersSchema, (client, parameters, options) => client.writeTerminalInput(parameters, options));
|
|
33
|
+
export const resizeTerminal = (input) => runValidatedTerminalMutation(input, liveTerminalResizeParametersSchema, (client, parameters, options) => client.resizeTerminal(parameters, options));
|
|
34
|
+
export const signalTerminal = (input) => runValidatedTerminalMutation(input, liveTerminalSignalParametersSchema, (client, parameters, options) => client.signalTerminal(parameters, options));
|
|
35
|
+
export const closeTerminal = (input) => runValidatedTerminalMutation(input, liveTerminalCloseParametersSchema, (client, parameters, options) => client.closeTerminal(parameters, options));
|
|
36
|
+
export const listTerminals = (input) => {
|
|
37
|
+
return runValidatedNodeOperation(input, terminalListParametersSchema, (client, parameters, options) => client.listTerminals(parameters, options));
|
|
38
|
+
};
|
|
39
|
+
export const showTerminal = (terminalId) => {
|
|
40
|
+
return runValidatedNodeOperation({ terminalId }, terminalShowParametersSchema, (client, parameters, options) => client.showTerminal(parameters, options));
|
|
41
|
+
};
|
|
42
|
+
export const listTerminalEvents = (input) => {
|
|
43
|
+
return runValidatedNodeOperation(input, terminalEventsListParametersSchema, (client, parameters, options) => client.listTerminalEvents(parameters, options));
|
|
44
|
+
};
|
|
45
|
+
export const readTerminal = (input) => {
|
|
46
|
+
return runValidatedNodeOperation(input, terminalReadParametersSchema, (client, parameters, options) => client.readTerminal(parameters, options));
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { CliArgumentError, parseOptions, readCursor, readPageSize, requirePositionals, } from "../command-line/arguments.js";
|
|
2
|
+
import { writeNodeResult } from "../command-line/output.js";
|
|
3
|
+
import { readTerminalColumns, readTerminalRows } from "./arguments.js";
|
|
4
|
+
import { projectTerminalEventsResult, projectTerminalListResult, projectTerminalReadResult, projectTerminalShowResult, terminalOutputAudience, } from "./compact-list.js";
|
|
5
|
+
import { runTerminalClose, runTerminalControllerCommand, runTerminalInputCommand, runTerminalResize, runTerminalSignal, } from "./control-commands.js";
|
|
6
|
+
const summarizeTerminalCreation = (result) => {
|
|
7
|
+
if (!("accepted" in result) || result.accepted)
|
|
8
|
+
return result;
|
|
9
|
+
const unavailableResult = result;
|
|
10
|
+
return {
|
|
11
|
+
accepted: unavailableResult.accepted,
|
|
12
|
+
delivery: unavailableResult.delivery,
|
|
13
|
+
receipt: unavailableResult.receipt,
|
|
14
|
+
state: unavailableResult.terminal.state,
|
|
15
|
+
terminalId: unavailableResult.terminal.id,
|
|
16
|
+
unavailability: unavailableResult.terminal.unavailability,
|
|
17
|
+
workspaceId: unavailableResult.terminal.workspaceId,
|
|
18
|
+
workspaceRevision: unavailableResult.terminal.workspaceRevision,
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
const readTerminalEventPageSize = (value) => {
|
|
22
|
+
if (value === undefined)
|
|
23
|
+
return 2;
|
|
24
|
+
if (!/^(?:[1-9]|[12]\d|3[0-2])$/u.test(value)) {
|
|
25
|
+
throw new CliArgumentError("Option '--limit' must be an integer from 1 to 32 for terminal events.");
|
|
26
|
+
}
|
|
27
|
+
return Number(value);
|
|
28
|
+
};
|
|
29
|
+
const readTerminalChunkPageSize = (value) => {
|
|
30
|
+
if (value === undefined)
|
|
31
|
+
return 2;
|
|
32
|
+
if (!/^[1-8]$/u.test(value)) {
|
|
33
|
+
throw new CliArgumentError("Option '--limit' must be an integer from 1 to 8 for terminal chunks.");
|
|
34
|
+
}
|
|
35
|
+
return Number(value);
|
|
36
|
+
};
|
|
37
|
+
const parseTerminalCreate = (tokens) => {
|
|
38
|
+
const parsed = parseOptions(tokens, new Set(["--columns", "--command-id", "--rows"]), new Set(["--interactive"]));
|
|
39
|
+
requirePositionals(parsed.positionals, 1, "maia terminal create <workspace-id> [--interactive --columns <columns> --rows <rows>]");
|
|
40
|
+
const workspaceId = parsed.positionals[0];
|
|
41
|
+
if (workspaceId === undefined) {
|
|
42
|
+
throw new CliArgumentError("The workspace identifier is missing.");
|
|
43
|
+
}
|
|
44
|
+
return { parsed, workspaceId };
|
|
45
|
+
};
|
|
46
|
+
const makeTerminalCreateInput = (parsed, workspaceId) => {
|
|
47
|
+
const interactive = parsed.flags.has("--interactive");
|
|
48
|
+
if (!interactive &&
|
|
49
|
+
(parsed.options.has("--columns") || parsed.options.has("--rows"))) {
|
|
50
|
+
throw new CliArgumentError("Options '--columns' and '--rows' require '--interactive'.");
|
|
51
|
+
}
|
|
52
|
+
const commandId = parsed.options.get("--command-id");
|
|
53
|
+
return interactive
|
|
54
|
+
? {
|
|
55
|
+
columns: readTerminalColumns(parsed.options.get("--columns"), 80),
|
|
56
|
+
...(commandId === undefined ? {} : { commandId }),
|
|
57
|
+
interactive: true,
|
|
58
|
+
rows: readTerminalRows(parsed.options.get("--rows"), 24),
|
|
59
|
+
workspaceId,
|
|
60
|
+
}
|
|
61
|
+
: {
|
|
62
|
+
...(commandId === undefined ? {} : { commandId }),
|
|
63
|
+
workspaceId,
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
const runTerminalCreate = async (tokens, context) => {
|
|
67
|
+
const { parsed, workspaceId } = parseTerminalCreate(tokens);
|
|
68
|
+
const input = makeTerminalCreateInput(parsed, workspaceId);
|
|
69
|
+
const result = await context.dependencies.createTerminal(input);
|
|
70
|
+
return writeNodeResult(result, context, (value) => ({
|
|
71
|
+
command: "terminal.create",
|
|
72
|
+
result: summarizeTerminalCreation(value),
|
|
73
|
+
}));
|
|
74
|
+
};
|
|
75
|
+
const runTerminalList = async (tokens, context) => {
|
|
76
|
+
const parsed = parseOptions(tokens, new Set(["--after", "--limit", "--workspace"]));
|
|
77
|
+
requirePositionals(parsed.positionals, 0, "maia terminal list --workspace <id>");
|
|
78
|
+
const workspaceId = parsed.options.get("--workspace");
|
|
79
|
+
if (workspaceId === undefined) {
|
|
80
|
+
throw new CliArgumentError("Option '--workspace' is required.");
|
|
81
|
+
}
|
|
82
|
+
const result = await context.dependencies.listTerminals({
|
|
83
|
+
afterCursor: readCursor(parsed.options.get("--after")),
|
|
84
|
+
limit: readPageSize(parsed.options.get("--limit")),
|
|
85
|
+
workspaceId,
|
|
86
|
+
});
|
|
87
|
+
return writeNodeResult(result, context, (value) => projectTerminalListResult(value, workspaceId, terminalOutputAudience(context.json)));
|
|
88
|
+
};
|
|
89
|
+
const runTerminalShow = async (tokens, context) => {
|
|
90
|
+
const parsed = parseOptions(tokens, new Set());
|
|
91
|
+
requirePositionals(parsed.positionals, 1, "maia terminal show <terminal-id>");
|
|
92
|
+
const terminalId = parsed.positionals[0];
|
|
93
|
+
if (terminalId === undefined) {
|
|
94
|
+
throw new CliArgumentError("The terminal identifier is missing.");
|
|
95
|
+
}
|
|
96
|
+
const result = await context.dependencies.showTerminal(terminalId);
|
|
97
|
+
return writeNodeResult(result, context, (value) => projectTerminalShowResult(value, terminalOutputAudience(context.json)));
|
|
98
|
+
};
|
|
99
|
+
const runTerminalEvents = async (tokens, context) => {
|
|
100
|
+
const parsed = parseOptions(tokens, new Set(["--after", "--limit"]));
|
|
101
|
+
requirePositionals(parsed.positionals, 1, "maia terminal events <terminal-id>");
|
|
102
|
+
const terminalId = parsed.positionals[0];
|
|
103
|
+
if (terminalId === undefined) {
|
|
104
|
+
throw new CliArgumentError("The terminal identifier is missing.");
|
|
105
|
+
}
|
|
106
|
+
const result = await context.dependencies.listTerminalEvents({
|
|
107
|
+
afterTerminalCursor: readCursor(parsed.options.get("--after")),
|
|
108
|
+
limit: readTerminalEventPageSize(parsed.options.get("--limit")),
|
|
109
|
+
terminalId,
|
|
110
|
+
});
|
|
111
|
+
return writeNodeResult(result, context, (value) => projectTerminalEventsResult(value, terminalOutputAudience(context.json)));
|
|
112
|
+
};
|
|
113
|
+
const runTerminalRead = async (tokens, context) => {
|
|
114
|
+
const parsed = parseOptions(tokens, new Set(["--after", "--limit"]));
|
|
115
|
+
requirePositionals(parsed.positionals, 1, "maia terminal read <terminal-id>");
|
|
116
|
+
const terminalId = parsed.positionals[0];
|
|
117
|
+
if (terminalId === undefined) {
|
|
118
|
+
throw new CliArgumentError("The terminal identifier is missing.");
|
|
119
|
+
}
|
|
120
|
+
const result = await context.dependencies.readTerminal({
|
|
121
|
+
afterChunkCursor: readCursor(parsed.options.get("--after")),
|
|
122
|
+
limit: readTerminalChunkPageSize(parsed.options.get("--limit")),
|
|
123
|
+
terminalId,
|
|
124
|
+
});
|
|
125
|
+
return writeNodeResult(result, context, projectTerminalReadResult);
|
|
126
|
+
};
|
|
127
|
+
export const runTerminalCommand = (tokens, context) => {
|
|
128
|
+
const [subcommand, ...rest] = tokens;
|
|
129
|
+
if (subcommand === "close")
|
|
130
|
+
return runTerminalClose(rest, context);
|
|
131
|
+
if (subcommand === "controller")
|
|
132
|
+
return runTerminalControllerCommand(rest, context);
|
|
133
|
+
if (subcommand === "create")
|
|
134
|
+
return runTerminalCreate(rest, context);
|
|
135
|
+
if (subcommand === "events")
|
|
136
|
+
return runTerminalEvents(rest, context);
|
|
137
|
+
if (subcommand === "input")
|
|
138
|
+
return runTerminalInputCommand(rest, context);
|
|
139
|
+
if (subcommand === "list")
|
|
140
|
+
return runTerminalList(rest, context);
|
|
141
|
+
if (subcommand === "read")
|
|
142
|
+
return runTerminalRead(rest, context);
|
|
143
|
+
if (subcommand === "resize")
|
|
144
|
+
return runTerminalResize(rest, context);
|
|
145
|
+
if (subcommand === "show")
|
|
146
|
+
return runTerminalShow(rest, context);
|
|
147
|
+
if (subcommand === "signal")
|
|
148
|
+
return runTerminalSignal(rest, context);
|
|
149
|
+
throw new CliArgumentError("Usage: maia terminal <create|list|show|events|read|controller|input|resize|signal|close>");
|
|
150
|
+
};
|
|
151
|
+
//# sourceMappingURL=commands.js.map
|