@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,643 @@
|
|
|
1
|
+
import { projectDispatchSettleResult, projectDispatchShowDispatch, projectInboxAckResult, projectQuestionCancelResult, projectQuestionOpenResult, projectQuestionReplyResult, projectRunCreateResult, projectRunShowResult, } from "../orchestration/compact-aggregate.js";
|
|
2
|
+
import { projectRunListResult } from "../orchestration/compact-run-list.js";
|
|
3
|
+
import { projectStatusResult } from "../status/compact.js";
|
|
4
|
+
import { HELP_USAGE } from "./help.js";
|
|
5
|
+
const EXIT_DATA_NOT_FOUND = 66;
|
|
6
|
+
const EXIT_USAGE = 64;
|
|
7
|
+
const EXIT_UNAVAILABLE = 69;
|
|
8
|
+
const EXIT_SOFTWARE = 70;
|
|
9
|
+
const EXIT_DEADLINE = 74;
|
|
10
|
+
const EXIT_TEMPORARY = 75;
|
|
11
|
+
const EXIT_OUTCOME_UNKNOWN = 76;
|
|
12
|
+
const EXIT_PERMISSION = 77;
|
|
13
|
+
const projectRuntimeListItem = (item) => item.detected
|
|
14
|
+
? { harnessId: item.harnessId, status: item.status }
|
|
15
|
+
: {
|
|
16
|
+
harnessId: item.harnessId,
|
|
17
|
+
reason: item.reason,
|
|
18
|
+
status: item.status,
|
|
19
|
+
};
|
|
20
|
+
const isHelpFamilyResult = (result) => "family" in result;
|
|
21
|
+
const formatHumanHelpIndex = (result) => {
|
|
22
|
+
const commandLines = result.commands
|
|
23
|
+
.map((command) => ` ${command.name.padEnd(12)}${command.summary}`)
|
|
24
|
+
.join("\n");
|
|
25
|
+
return `Maia CLI ${result.version}\n\nUsage:\n ${HELP_USAGE.join("\n ")}\n\nCallable commands:\n${commandLines}\n\nCommands use the SDK and the same durable node state.\n`;
|
|
26
|
+
};
|
|
27
|
+
const formatHumanHelp = (result) => {
|
|
28
|
+
if (!isHelpFamilyResult(result))
|
|
29
|
+
return formatHumanHelpIndex(result);
|
|
30
|
+
if (result.usage.length === 0) {
|
|
31
|
+
return `Maia CLI ${result.version}\n\nNo usage rows for that command family.\n`;
|
|
32
|
+
}
|
|
33
|
+
return `Maia CLI ${result.version}\n\nUsage:\n ${result.usage.map((row) => row.usage).join("\n ")}\n`;
|
|
34
|
+
};
|
|
35
|
+
const processResourceNextStep = (nextStep) => {
|
|
36
|
+
switch (nextStep) {
|
|
37
|
+
case "close_idle_terminal":
|
|
38
|
+
return "close an idle Maia terminal, then retry";
|
|
39
|
+
case "inspect_cleanup_unknown":
|
|
40
|
+
return "inspect cleanup-unknown terminals and processes before restart";
|
|
41
|
+
case "inspect_observed_pressure":
|
|
42
|
+
return "inspect per-tree pressure warnings; termination stays disabled";
|
|
43
|
+
case "none":
|
|
44
|
+
return "none";
|
|
45
|
+
case "verify_native_host":
|
|
46
|
+
return "verify the native process host";
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const formatObservedMetric = (label, metric) => `${label} ${metric.state}${metric.maximumValue === undefined ? "" : ` max ${String(metric.maximumValue)}`}; budget ${metric.budget}; ${String(metric.warningTrees)} warning`;
|
|
50
|
+
const formatHumanStatus = (result) => {
|
|
51
|
+
const { node } = result;
|
|
52
|
+
const resources = node.processResources;
|
|
53
|
+
const observed = resources.observations;
|
|
54
|
+
return `Maia node ${node.lifecycle}\n profile: ${node.profile}\n pid: ${String(node.pid)}\n instance: ${node.instanceId}\n storage: ${node.storage.integrity} (${node.storage.journalMode})\n process resources: ${resources.pressure} (${resources.capability.mode}; hard limits ${resources.capability.hardLimitEnforcement}; release qualified ${String(resources.capability.releaseQualified)})\n admission: ${resources.admission.state}; ${String(resources.admission.usedTrees)}/${String(resources.admission.capacity)} used; ${String(resources.admission.availableTrees)} available; ${String(resources.admission.queuedSpawns)} queued\n ownership: ${String(resources.activeTrees)} active; ${String(resources.fencedTrees)} fenced; ${String(resources.cleanupUnknownTrees)} cleanup unknown; ${String(resources.supervision.watcherFibers)} watcher fibers\n latest target observations: ${[
|
|
55
|
+
formatObservedMetric("cpu-ms", observed.cpuTimeMilliseconds),
|
|
56
|
+
formatObservedMetric("rss-bytes", observed.rssBytes),
|
|
57
|
+
formatObservedMetric("peak-rss-bytes", observed.observedPeakRssBytes),
|
|
58
|
+
formatObservedMetric("processes", observed.processCount),
|
|
59
|
+
formatObservedMetric("fds", observed.fileDescriptorCount),
|
|
60
|
+
formatObservedMetric("io-read-bytes", observed.ioReadBytes),
|
|
61
|
+
formatObservedMetric("io-write-bytes", observed.ioWriteBytes),
|
|
62
|
+
].join("; ")}\n observed-pressure termination: ${resources.capability.observedPressureTermination}; samples are advisory, not hard enforcement or automatic kill\n inspect: --json compact; SDK lossless\n next step: ${processResourceNextStep(resources.nextStep)}\n`;
|
|
63
|
+
};
|
|
64
|
+
const formatIntegration = (result) => {
|
|
65
|
+
switch (result.command) {
|
|
66
|
+
case "integration.plan": {
|
|
67
|
+
const target = result.result.plan.target;
|
|
68
|
+
const digest = target.adapter === "codex"
|
|
69
|
+
? target.executableSha256
|
|
70
|
+
: target.packageClosure.closureSha256;
|
|
71
|
+
return `${result.result.integration}\tplanned\t${result.result.plan.planId}\t${result.result.plan.expiresAt}\t${digest}\n`;
|
|
72
|
+
}
|
|
73
|
+
case "integration.apply":
|
|
74
|
+
return `${result.result.integration}\t${result.result.authorization.state}\t${result.result.authorization.revision}\n`;
|
|
75
|
+
case "integration.remove":
|
|
76
|
+
return `${result.result.integration}\t${result.result.outcome}\t${result.result.authorization.revision}\n`;
|
|
77
|
+
case "integration.status": {
|
|
78
|
+
const item = result.result.items[0];
|
|
79
|
+
return item.authorizationAvailable
|
|
80
|
+
? `${result.result.integration}\t${item.authorization.state}\t${item.authorization.revision}\t${item.nextAction}\n`
|
|
81
|
+
: `${result.result.integration}\tunavailable\t${item.reason}\t${item.nextAction}\n`;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
};
|
|
85
|
+
const formatRuntimeList = (items) => formatRows(items, (item) => {
|
|
86
|
+
const reason = item.reason;
|
|
87
|
+
return reason === undefined
|
|
88
|
+
? `${item.harnessId}\t${item.status}`
|
|
89
|
+
: `${item.harnessId}\t${item.status}\t${reason}`;
|
|
90
|
+
}, true);
|
|
91
|
+
const formatRuntimeProbe = (result) => {
|
|
92
|
+
const runtime = result.adapter === "pi-rpc" ? "pi-rpc" : "codex";
|
|
93
|
+
if (result.status === "ready") {
|
|
94
|
+
return `${runtime}\tready\t${result.executableVersion}\t${String(result.handshakeMilliseconds)}ms\n`;
|
|
95
|
+
}
|
|
96
|
+
const version = result.status === "incompatible" && result.executableVersion !== undefined
|
|
97
|
+
? `\t${result.executableVersion}`
|
|
98
|
+
: "";
|
|
99
|
+
return `${runtime}\t${result.status}\t${result.reason}${version}\n`;
|
|
100
|
+
};
|
|
101
|
+
const isTerminalControl = (character) => {
|
|
102
|
+
const point = character.codePointAt(0);
|
|
103
|
+
return (point !== undefined &&
|
|
104
|
+
(point <= 31 ||
|
|
105
|
+
(point >= 127 && point <= 159) ||
|
|
106
|
+
point === 8232 ||
|
|
107
|
+
point === 8233));
|
|
108
|
+
};
|
|
109
|
+
const formatTerminalCell = (value) => Array.from(value, (character) => isTerminalControl(character) ? "�" : character).join("");
|
|
110
|
+
const formatRows = (items, format, newlineWhenEmpty = false) => `${items.map(format).join("\n")}${items.length > 0 || newlineWhenEmpty ? "\n" : ""}`;
|
|
111
|
+
const tab = (values) => values.join("\t");
|
|
112
|
+
const formatProjectList = (result) => formatRows(result.items, (project) => `${project.id}\t${formatTerminalCell(project.name)}\t${project.revision}`);
|
|
113
|
+
const formatWorkspaceList = (result) => formatRows(result.items, (workspace) => `${workspace.id}\t${formatTerminalCell(workspace.name)}\t${workspace.kind}\t${workspace.revision}`);
|
|
114
|
+
const formatSessionList = (result) => formatRows(result.items, (session) => `${session.id}\t${session.runtime}\t${session.state}\t${session.workspaceId}`);
|
|
115
|
+
const formatSessionSuccess = (result) => {
|
|
116
|
+
switch (result.command) {
|
|
117
|
+
case "session.create":
|
|
118
|
+
return `${result.result.sessionId}\n`;
|
|
119
|
+
case "session.events":
|
|
120
|
+
return formatRows(result.result.items, (event) => `${event.sessionCursor}\t${event.eventType}\t${event.globalCursor}`);
|
|
121
|
+
case "session.list":
|
|
122
|
+
return formatSessionList(result.result);
|
|
123
|
+
case "session.show":
|
|
124
|
+
return `${result.result.session.id}\t${result.result.session.runtime}\t${result.result.session.state}\t${result.result.session.workspaceId}\n`;
|
|
125
|
+
case "session.start":
|
|
126
|
+
return `${result.result.sessionId}\t${result.result.state}\t${result.result.revision}\n`;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
const formatWorkspaceSuccess = (result) => {
|
|
130
|
+
switch (result.command) {
|
|
131
|
+
case "workspace.execution.configure":
|
|
132
|
+
return `${result.result.workspaceId}\t${result.result.workspaceRevision}\t${result.result.resolution.status}\t${result.result.resolution.reason}\n`;
|
|
133
|
+
case "workspace.execution.show":
|
|
134
|
+
return `${result.result.workspace.id}\t${result.result.workspace.revision}\t${result.result.resolution.status}\t${result.result.resolution.reason}\n`;
|
|
135
|
+
case "workspace.list":
|
|
136
|
+
return formatWorkspaceList(result.result);
|
|
137
|
+
case "workspace.repo.add":
|
|
138
|
+
return `${result.result.repositoryId}\n`;
|
|
139
|
+
case "workspace.show":
|
|
140
|
+
return `${result.result.workspace.id}\t${formatTerminalCell(result.result.workspace.name)}\t${result.result.workspace.revision}\n`;
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
const formatTurnSuccess = (result) => {
|
|
144
|
+
switch (result.command) {
|
|
145
|
+
case "turn.interrupt":
|
|
146
|
+
case "turn.send":
|
|
147
|
+
return `${result.result.turnId}\t${result.result.state}\t${result.result.revision}\n`;
|
|
148
|
+
case "turn.show": {
|
|
149
|
+
const turn = result.result.turn;
|
|
150
|
+
return `${turn.id}\t${turn.state}\t${turn.revision}\t${turn.sessionId}\n`;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
const isHumanLiveTerminal = (terminal) => terminal.state !== "unavailable" && "capability" in terminal;
|
|
155
|
+
const formatTerminalProjection = (terminal) => {
|
|
156
|
+
if (terminal.state === "unavailable") {
|
|
157
|
+
return `${formatTerminalCell(terminal.id)}\t${formatTerminalCell(terminal.state)}\t${formatTerminalCell(terminal.unavailability.code)}\t${formatTerminalCell(terminal.workspaceId)}`;
|
|
158
|
+
}
|
|
159
|
+
if (!isHumanLiveTerminal(terminal)) {
|
|
160
|
+
throw new Error("Human live terminal TSV requires capability.tier.");
|
|
161
|
+
}
|
|
162
|
+
return `${formatTerminalCell(terminal.id)}\t${formatTerminalCell(terminal.state)}\t${formatTerminalCell(terminal.capability.tier)}\t${formatTerminalCell(terminal.workspaceId)}`;
|
|
163
|
+
};
|
|
164
|
+
export const formatTerminalList = (result) => formatRows(result.items, formatTerminalProjection);
|
|
165
|
+
export const formatTerminalShow = (result) => `${formatTerminalProjection(result.terminal)}\n`;
|
|
166
|
+
const isHumanLegacyEvent = (event) => "unavailability" in event && "globalCursor" in event;
|
|
167
|
+
const formatTerminalEvent = (event) => {
|
|
168
|
+
if ("unavailability" in event) {
|
|
169
|
+
if (!isHumanLegacyEvent(event)) {
|
|
170
|
+
throw new Error("Human legacy terminal event TSV requires globalCursor.");
|
|
171
|
+
}
|
|
172
|
+
return `${formatTerminalCell(event.cursor)}\t${formatTerminalCell(event.type)}\t${formatTerminalCell(event.globalCursor)}`;
|
|
173
|
+
}
|
|
174
|
+
return `${formatTerminalCell(event.cursor)}\t${formatTerminalCell(event.type)}`;
|
|
175
|
+
};
|
|
176
|
+
export const formatTerminalEvents = (result) => formatRows(result.items, formatTerminalEvent);
|
|
177
|
+
export const formatTerminalRead = (result) => formatRows(result.items, (chunk) => `${formatTerminalCell(chunk.cursor)}\t${chunk.bytesBase64}`);
|
|
178
|
+
const formatTerminalSuccess = (result) => {
|
|
179
|
+
switch (result.command) {
|
|
180
|
+
case "terminal.create":
|
|
181
|
+
return "accepted" in result.result && !result.result.accepted
|
|
182
|
+
? `${result.result.terminalId}\t${result.result.state}\t${result.result.unavailability.code}\n`
|
|
183
|
+
: `${JSON.stringify(result.result)}\n`;
|
|
184
|
+
case "terminal.close":
|
|
185
|
+
case "terminal.controller.acquire":
|
|
186
|
+
case "terminal.controller.release":
|
|
187
|
+
case "terminal.controller.request":
|
|
188
|
+
case "terminal.controller.request.show":
|
|
189
|
+
case "terminal.input.write":
|
|
190
|
+
case "terminal.resize":
|
|
191
|
+
case "terminal.signal":
|
|
192
|
+
return `${JSON.stringify(result.result)}\n`;
|
|
193
|
+
case "terminal.events":
|
|
194
|
+
return formatTerminalEvents(result);
|
|
195
|
+
case "terminal.list":
|
|
196
|
+
return formatTerminalList(result);
|
|
197
|
+
case "terminal.read":
|
|
198
|
+
return formatTerminalRead(result);
|
|
199
|
+
case "terminal.show":
|
|
200
|
+
return formatTerminalShow(result);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
const formatProjectSuccess = (result) => {
|
|
204
|
+
switch (result.command) {
|
|
205
|
+
case "project.add":
|
|
206
|
+
return `${result.result.projectId}\n`;
|
|
207
|
+
case "project.list":
|
|
208
|
+
return formatProjectList(result.result);
|
|
209
|
+
case "project.show":
|
|
210
|
+
return `${result.result.project.id}\t${formatTerminalCell(result.result.project.name)}\t${result.result.project.revision}\n`;
|
|
211
|
+
}
|
|
212
|
+
};
|
|
213
|
+
const isProjectResult = (result) => result.command.startsWith("project.");
|
|
214
|
+
const isOrchestrationResult = (result) => result.command.startsWith("run.");
|
|
215
|
+
const isSessionResult = (result) => result.command.startsWith("session.");
|
|
216
|
+
const isTerminalResult = (result) => result.command.startsWith("terminal.");
|
|
217
|
+
const isTurnResult = (result) => result.command.startsWith("turn.");
|
|
218
|
+
const isWorkspaceResult = (result) => result.command.startsWith("workspace.");
|
|
219
|
+
export const formatInboxAck = (result) => `${tab([
|
|
220
|
+
result.command,
|
|
221
|
+
result.receipt.commandId,
|
|
222
|
+
result.runId,
|
|
223
|
+
result.owner.kind,
|
|
224
|
+
result.owner.id,
|
|
225
|
+
result.mailboxRevision,
|
|
226
|
+
result.receipt.state,
|
|
227
|
+
])}\n${tab([
|
|
228
|
+
result.delivery.deliveryId,
|
|
229
|
+
result.delivery.sequence,
|
|
230
|
+
result.delivery.type,
|
|
231
|
+
formatTerminalCell(result.delivery.subject),
|
|
232
|
+
])}\n`;
|
|
233
|
+
const formatInboxCheck = (result) => {
|
|
234
|
+
const header = tab([
|
|
235
|
+
result.command,
|
|
236
|
+
result.runId,
|
|
237
|
+
result.owner.kind,
|
|
238
|
+
result.owner.id,
|
|
239
|
+
String(result.count),
|
|
240
|
+
result.mailboxRevision,
|
|
241
|
+
]);
|
|
242
|
+
if (result.items.length === 0)
|
|
243
|
+
return `${header}\n`;
|
|
244
|
+
return `${header}\n${result.items
|
|
245
|
+
.map((item) => tab([
|
|
246
|
+
item.deliveryId,
|
|
247
|
+
item.sequence,
|
|
248
|
+
item.type,
|
|
249
|
+
formatTerminalCell(item.subject),
|
|
250
|
+
]))
|
|
251
|
+
.join("\n")}\n`;
|
|
252
|
+
};
|
|
253
|
+
export const formatReceiptList = (result) => {
|
|
254
|
+
const header = tab([
|
|
255
|
+
result.command,
|
|
256
|
+
String(result.count),
|
|
257
|
+
result.nextCursor ?? "-",
|
|
258
|
+
]);
|
|
259
|
+
if (result.items.length === 0)
|
|
260
|
+
return `${header}\n`;
|
|
261
|
+
return `${header}\n${result.items
|
|
262
|
+
.map((item) => tab([
|
|
263
|
+
item.commandId,
|
|
264
|
+
item.method,
|
|
265
|
+
item.state,
|
|
266
|
+
item.target.type,
|
|
267
|
+
item.target.id,
|
|
268
|
+
]))
|
|
269
|
+
.join("\n")}\n`;
|
|
270
|
+
};
|
|
271
|
+
export const formatRunList = (result) => {
|
|
272
|
+
const header = tab([
|
|
273
|
+
result.command,
|
|
274
|
+
result.workspaceId,
|
|
275
|
+
String(result.count),
|
|
276
|
+
result.nextCursor ?? "-",
|
|
277
|
+
]);
|
|
278
|
+
if (result.items.length === 0)
|
|
279
|
+
return `${header}\n`;
|
|
280
|
+
return `${header}\n${result.items
|
|
281
|
+
.map((item) => tab([
|
|
282
|
+
item.id,
|
|
283
|
+
item.state,
|
|
284
|
+
item.revision,
|
|
285
|
+
item.terminalId,
|
|
286
|
+
item.rootTaskId,
|
|
287
|
+
item.dispatchTaskId,
|
|
288
|
+
]))
|
|
289
|
+
.join("\n")}\n`;
|
|
290
|
+
};
|
|
291
|
+
const formatTaskList = (result) => {
|
|
292
|
+
const header = tab([
|
|
293
|
+
result.command,
|
|
294
|
+
result.runId,
|
|
295
|
+
String(result.count),
|
|
296
|
+
result.nextCursor ?? "-",
|
|
297
|
+
]);
|
|
298
|
+
if (result.items.length === 0)
|
|
299
|
+
return `${header}\n`;
|
|
300
|
+
return `${header}\n${result.items
|
|
301
|
+
.map((item) => tab([item.id, item.clientKey, item.state, item.revision]))
|
|
302
|
+
.join("\n")}\n`;
|
|
303
|
+
};
|
|
304
|
+
const formatTaskShow = (result) => [
|
|
305
|
+
tab([
|
|
306
|
+
result.command,
|
|
307
|
+
result.task.runId,
|
|
308
|
+
result.task.id,
|
|
309
|
+
result.task.clientKey,
|
|
310
|
+
result.task.state,
|
|
311
|
+
result.task.revision,
|
|
312
|
+
]),
|
|
313
|
+
formatTerminalCell(result.task.objective),
|
|
314
|
+
"",
|
|
315
|
+
].join("\n");
|
|
316
|
+
const formatDispatchShow = (result) => {
|
|
317
|
+
const header = tab([
|
|
318
|
+
result.command,
|
|
319
|
+
result.dispatch.runId,
|
|
320
|
+
result.dispatch.id,
|
|
321
|
+
result.dispatch.taskId,
|
|
322
|
+
result.dispatch.state,
|
|
323
|
+
result.dispatch.revision,
|
|
324
|
+
]);
|
|
325
|
+
if (result.dispatch.state !== "failed" ||
|
|
326
|
+
result.dispatch.failure === undefined) {
|
|
327
|
+
return `${header}\n`;
|
|
328
|
+
}
|
|
329
|
+
return `${header}\n${result.dispatch.failure.code}\t${result.dispatch.failure.platform}\n`;
|
|
330
|
+
};
|
|
331
|
+
const formatFailedDispatchLine = (dispatch) => dispatch.state === "failed" && dispatch.failure !== undefined
|
|
332
|
+
? `${dispatch.failure.code}\t${dispatch.failure.platform}\n`
|
|
333
|
+
: "";
|
|
334
|
+
const formatMailboxLines = (mailboxes) => `${mailboxes.map((mailbox) => `${mailbox.owner.kind}\t${mailbox.id}\t${mailbox.revision}`).join("\n")}\n`;
|
|
335
|
+
const formatQuestionLines = (question) => {
|
|
336
|
+
if (question === undefined)
|
|
337
|
+
return "";
|
|
338
|
+
const lines = [
|
|
339
|
+
`${question.id}\t${question.state}\t${question.revision}`,
|
|
340
|
+
formatTerminalCell(question.subject),
|
|
341
|
+
formatTerminalCell(question.body),
|
|
342
|
+
];
|
|
343
|
+
if (question.state === "answered" && question.answer !== undefined) {
|
|
344
|
+
lines.push(formatTerminalCell(question.answer));
|
|
345
|
+
}
|
|
346
|
+
return `${lines.join("\n")}\n`;
|
|
347
|
+
};
|
|
348
|
+
const formatDeliveryLine = (delivery) => delivery === undefined
|
|
349
|
+
? ""
|
|
350
|
+
: `${delivery.deliveryId}\t${delivery.sequence}\t${delivery.type}\t${formatTerminalCell(delivery.subject)}\n`;
|
|
351
|
+
const formatCompactAggregateBody = (aggregate, delivery) => `${formatFailedDispatchLine(aggregate.dispatch)}${formatMailboxLines(aggregate.mailboxes)}${formatQuestionLines(aggregate.question)}${formatDeliveryLine(delivery)}`;
|
|
352
|
+
export const formatRunShow = (result) => `${tab([
|
|
353
|
+
result.command,
|
|
354
|
+
result.aggregate.run.id,
|
|
355
|
+
result.aggregate.run.state,
|
|
356
|
+
result.aggregate.run.revision,
|
|
357
|
+
result.aggregate.dispatch.id,
|
|
358
|
+
result.aggregate.dispatch.state,
|
|
359
|
+
result.aggregate.dispatch.revision,
|
|
360
|
+
])}\n${formatCompactAggregateBody(result.aggregate)}`;
|
|
361
|
+
export const formatRunCreate = (result) => `${tab([
|
|
362
|
+
result.command,
|
|
363
|
+
result.delivery,
|
|
364
|
+
result.receipt.commandId,
|
|
365
|
+
result.aggregate.run.id,
|
|
366
|
+
result.aggregate.run.revision,
|
|
367
|
+
result.aggregate.dispatch.id,
|
|
368
|
+
result.aggregate.dispatch.revision,
|
|
369
|
+
])}\n${formatCompactAggregateBody(result.aggregate, result.initialDelivery)}`;
|
|
370
|
+
const formatQuestionMutation = (result) => `${tab([
|
|
371
|
+
result.command,
|
|
372
|
+
result.receipt.commandId,
|
|
373
|
+
result.aggregate.run.id,
|
|
374
|
+
result.aggregate.question?.id ?? "",
|
|
375
|
+
result.aggregate.question?.revision ?? "",
|
|
376
|
+
result.aggregate.run.revision,
|
|
377
|
+
result.aggregate.dispatch.revision,
|
|
378
|
+
])}\n${formatCompactAggregateBody(result.aggregate, result.delivery)}`;
|
|
379
|
+
export const formatQuestionOpen = (result) => formatQuestionMutation(result);
|
|
380
|
+
export const formatQuestionReply = (result) => formatQuestionMutation(result);
|
|
381
|
+
export const formatQuestionCancel = (result) => `${tab([
|
|
382
|
+
result.command,
|
|
383
|
+
result.receipt.commandId,
|
|
384
|
+
result.aggregate.run.id,
|
|
385
|
+
result.aggregate.run.revision,
|
|
386
|
+
result.aggregate.dispatch.revision,
|
|
387
|
+
])}\n${formatCompactAggregateBody(result.aggregate)}`;
|
|
388
|
+
export const formatDispatchSettle = (result) => `${tab([
|
|
389
|
+
result.command,
|
|
390
|
+
result.receipt.commandId,
|
|
391
|
+
result.aggregate.run.id,
|
|
392
|
+
result.aggregate.dispatch.state,
|
|
393
|
+
result.aggregate.run.revision,
|
|
394
|
+
result.aggregate.dispatch.revision,
|
|
395
|
+
])}\n${formatCompactAggregateBody(result.aggregate, result.delivery)}`;
|
|
396
|
+
const formatCompactOrchestration = (result) => {
|
|
397
|
+
if (result.command === "run.inbox.ack")
|
|
398
|
+
return formatInboxAck(result);
|
|
399
|
+
if (result.command === "run.inbox.check")
|
|
400
|
+
return formatInboxCheck(result);
|
|
401
|
+
if (result.command === "run.task.list")
|
|
402
|
+
return formatTaskList(result);
|
|
403
|
+
if (result.command === "run.task.show")
|
|
404
|
+
return formatTaskShow(result);
|
|
405
|
+
if (result.command === "run.dispatch.show")
|
|
406
|
+
return formatDispatchShow(result);
|
|
407
|
+
if (result.command === "run.show")
|
|
408
|
+
return formatRunShow(result);
|
|
409
|
+
if (result.command === "run.create")
|
|
410
|
+
return formatRunCreate(result);
|
|
411
|
+
if (result.command === "run.question.open")
|
|
412
|
+
return formatQuestionOpen(result);
|
|
413
|
+
if (result.command === "run.question.reply") {
|
|
414
|
+
return formatQuestionReply(result);
|
|
415
|
+
}
|
|
416
|
+
if (result.command === "run.question.cancel") {
|
|
417
|
+
return formatQuestionCancel(result);
|
|
418
|
+
}
|
|
419
|
+
if (result.command === "run.dispatch.settle-terminal") {
|
|
420
|
+
return formatDispatchSettle(result);
|
|
421
|
+
}
|
|
422
|
+
return formatRunList(result);
|
|
423
|
+
};
|
|
424
|
+
const formatNodeSuccess = (result) => {
|
|
425
|
+
if (result.command === "monitor")
|
|
426
|
+
return `${result.result.url}\n`;
|
|
427
|
+
if (result.command === "execution.catalog") {
|
|
428
|
+
const [provider] = result.result.providers;
|
|
429
|
+
return `${provider.id}\t${provider.kind}\t${provider.binding}\t${provider.reason}\n`;
|
|
430
|
+
}
|
|
431
|
+
if (isProjectResult(result))
|
|
432
|
+
return formatProjectSuccess(result);
|
|
433
|
+
if (isOrchestrationResult(result))
|
|
434
|
+
return formatCompactOrchestration(result);
|
|
435
|
+
if (isSessionResult(result))
|
|
436
|
+
return formatSessionSuccess(result);
|
|
437
|
+
if (isTerminalResult(result))
|
|
438
|
+
return formatTerminalSuccess(result);
|
|
439
|
+
if (isTurnResult(result))
|
|
440
|
+
return formatTurnSuccess(result);
|
|
441
|
+
if (isWorkspaceResult(result))
|
|
442
|
+
return formatWorkspaceSuccess(result);
|
|
443
|
+
switch (result.command) {
|
|
444
|
+
case "integration.apply":
|
|
445
|
+
case "integration.plan":
|
|
446
|
+
case "integration.remove":
|
|
447
|
+
case "integration.status":
|
|
448
|
+
return formatIntegration(result);
|
|
449
|
+
case "context.show":
|
|
450
|
+
return `${result.principal.kind}\t${result.principal.id}\t${result.actorId}\n`;
|
|
451
|
+
case "receipt.list":
|
|
452
|
+
return formatReceiptList(result);
|
|
453
|
+
case "receipt.show":
|
|
454
|
+
return `${result.result.receipt.receiptId}\t${result.result.receipt.state}\t${result.result.receipt.target.type}:${result.result.receipt.target.id}\n`;
|
|
455
|
+
case "runtime.list":
|
|
456
|
+
return formatRuntimeList(result.items);
|
|
457
|
+
case "runtime.probe":
|
|
458
|
+
return formatRuntimeProbe(result.result);
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
const isHumanStatusResult = (result) => result.command === "status" && "node" in result;
|
|
462
|
+
const formatHumanSuccess = (result) => {
|
|
463
|
+
if (result.command === "help")
|
|
464
|
+
return formatHumanHelp(result);
|
|
465
|
+
if (result.command === "status") {
|
|
466
|
+
if (!isHumanStatusResult(result)) {
|
|
467
|
+
throw new Error("Compact status is JSON-only.");
|
|
468
|
+
}
|
|
469
|
+
return formatHumanStatus(result);
|
|
470
|
+
}
|
|
471
|
+
if (result.command === "version")
|
|
472
|
+
return `${result.version}\n`;
|
|
473
|
+
return formatNodeSuccess(result);
|
|
474
|
+
};
|
|
475
|
+
export const writeStatusResult = (node, context) => {
|
|
476
|
+
if (context.json) {
|
|
477
|
+
writeSuccess(projectStatusResult(node), true, context.io);
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
writeSuccess({ command: "status", node }, false, context.io);
|
|
481
|
+
};
|
|
482
|
+
export const writeSuccess = (result, json, io) => {
|
|
483
|
+
if (json) {
|
|
484
|
+
const output = { ok: true, result };
|
|
485
|
+
io.stdout(`${JSON.stringify(output)}\n`);
|
|
486
|
+
return;
|
|
487
|
+
}
|
|
488
|
+
io.stdout(formatHumanSuccess(result));
|
|
489
|
+
};
|
|
490
|
+
const writeError = (error, recovery, context) => {
|
|
491
|
+
if (context.json) {
|
|
492
|
+
const output = {
|
|
493
|
+
error,
|
|
494
|
+
ok: false,
|
|
495
|
+
...(recovery === undefined ? {} : { recovery }),
|
|
496
|
+
};
|
|
497
|
+
context.io.stderr(`${JSON.stringify(output)}\n`);
|
|
498
|
+
return;
|
|
499
|
+
}
|
|
500
|
+
const usage = error.code === "invalid_argument" ||
|
|
501
|
+
error.code === "command_not_implemented"
|
|
502
|
+
? "Run 'maia --help' for usage.\n"
|
|
503
|
+
: "";
|
|
504
|
+
const recoveryHint = recovery === undefined
|
|
505
|
+
? ""
|
|
506
|
+
: `Outcome unknown. Recover with:\n maia receipt show ${recovery.commandId}\n`;
|
|
507
|
+
context.io.stderr(`maia: ${error.message}\n${recoveryHint}${usage}`);
|
|
508
|
+
};
|
|
509
|
+
export const reportError = (error, context) => {
|
|
510
|
+
writeError(error, context.recovery, context);
|
|
511
|
+
if (error.code === "invalid_argument" ||
|
|
512
|
+
error.code === "command_not_implemented") {
|
|
513
|
+
return EXIT_USAGE;
|
|
514
|
+
}
|
|
515
|
+
if (error.code === "resource_not_found")
|
|
516
|
+
return EXIT_DATA_NOT_FOUND;
|
|
517
|
+
if (error.code === "authentication_failed")
|
|
518
|
+
return EXIT_PERMISSION;
|
|
519
|
+
if (error.code === "node_unavailable" ||
|
|
520
|
+
error.code === "node_context_unavailable") {
|
|
521
|
+
return EXIT_UNAVAILABLE;
|
|
522
|
+
}
|
|
523
|
+
if (error.code === "context_override_forbidden")
|
|
524
|
+
return EXIT_PERMISSION;
|
|
525
|
+
if (error.code === "deadline_exceeded")
|
|
526
|
+
return EXIT_DEADLINE;
|
|
527
|
+
if (error.code === "outcome_unknown")
|
|
528
|
+
return EXIT_OUTCOME_UNKNOWN;
|
|
529
|
+
if (error.code === "saturated")
|
|
530
|
+
return EXIT_TEMPORARY;
|
|
531
|
+
if (error.retryable)
|
|
532
|
+
return EXIT_TEMPORARY;
|
|
533
|
+
return EXIT_SOFTWARE;
|
|
534
|
+
};
|
|
535
|
+
export const writeNodeResult = (result, context, map) => {
|
|
536
|
+
if (!result.ok) {
|
|
537
|
+
return reportError(result.error, {
|
|
538
|
+
...context,
|
|
539
|
+
...(result.recovery === undefined ? {} : { recovery: result.recovery }),
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
writeSuccess(map(result.value), context.json, context.io);
|
|
543
|
+
return 0;
|
|
544
|
+
};
|
|
545
|
+
const projectInboxCheckItem = (delivery) => ({
|
|
546
|
+
body: delivery.message.body,
|
|
547
|
+
deliveryId: delivery.id,
|
|
548
|
+
mailboxId: delivery.mailboxId,
|
|
549
|
+
sequence: delivery.sequence,
|
|
550
|
+
subject: delivery.message.subject,
|
|
551
|
+
type: delivery.message.type,
|
|
552
|
+
});
|
|
553
|
+
const projectedResultWriter = (project) => (result, context) => writeNodeResult(result, context, project);
|
|
554
|
+
export const writeInboxAckResult = projectedResultWriter(projectInboxAckResult);
|
|
555
|
+
export const writeInboxCheckResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
556
|
+
command: "run.inbox.check",
|
|
557
|
+
count: value.items.length,
|
|
558
|
+
items: value.items.map(projectInboxCheckItem),
|
|
559
|
+
mailboxId: value.mailbox.id,
|
|
560
|
+
mailboxRevision: value.mailbox.revision,
|
|
561
|
+
owner: {
|
|
562
|
+
id: value.mailbox.owner.id,
|
|
563
|
+
kind: value.mailbox.owner.kind,
|
|
564
|
+
},
|
|
565
|
+
runId: value.mailbox.runId,
|
|
566
|
+
}));
|
|
567
|
+
const projectTaskListItem = (task) => ({
|
|
568
|
+
clientKey: task.clientKey,
|
|
569
|
+
dependencyTaskIds: task.dependencyTaskIds,
|
|
570
|
+
id: task.id,
|
|
571
|
+
revision: task.revision,
|
|
572
|
+
state: task.state,
|
|
573
|
+
});
|
|
574
|
+
export const writeRunListResult = (result, context, workspaceId) => writeNodeResult(result, context, (value) => projectRunListResult(value, workspaceId));
|
|
575
|
+
export const writeTaskListResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
576
|
+
command: "run.task.list",
|
|
577
|
+
count: value.items.length,
|
|
578
|
+
items: value.items.map(projectTaskListItem),
|
|
579
|
+
...(value.nextCursor === undefined ? {} : { nextCursor: value.nextCursor }),
|
|
580
|
+
runId: value.runId,
|
|
581
|
+
}));
|
|
582
|
+
const projectTaskShowTask = (task) => ({
|
|
583
|
+
clientKey: task.clientKey,
|
|
584
|
+
dependencyTaskIds: task.dependencyTaskIds,
|
|
585
|
+
id: task.id,
|
|
586
|
+
objective: task.objective,
|
|
587
|
+
revision: task.revision,
|
|
588
|
+
runId: task.runId,
|
|
589
|
+
state: task.state,
|
|
590
|
+
});
|
|
591
|
+
export const writeTaskShowResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
592
|
+
command: "run.task.show",
|
|
593
|
+
task: projectTaskShowTask(value.task),
|
|
594
|
+
}));
|
|
595
|
+
export const writeDispatchShowResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
596
|
+
command: "run.dispatch.show",
|
|
597
|
+
dispatch: projectDispatchShowDispatch(value.dispatch),
|
|
598
|
+
}));
|
|
599
|
+
export const writeRunShowResult = projectedResultWriter(projectRunShowResult);
|
|
600
|
+
export const writeRunCreateResult = projectedResultWriter(projectRunCreateResult);
|
|
601
|
+
export const writeQuestionOpenResult = projectedResultWriter(projectQuestionOpenResult);
|
|
602
|
+
export const writeQuestionReplyResult = projectedResultWriter(projectQuestionReplyResult);
|
|
603
|
+
export const writeQuestionCancelResult = projectedResultWriter(projectQuestionCancelResult);
|
|
604
|
+
export const writeDispatchSettleResult = projectedResultWriter(projectDispatchSettleResult);
|
|
605
|
+
export const writeCurrentContextResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
606
|
+
actorId: value.actorId,
|
|
607
|
+
allowedActions: value.allowedActions,
|
|
608
|
+
command: "context.show",
|
|
609
|
+
contextRevision: value.contextRevision,
|
|
610
|
+
principal: value.principal,
|
|
611
|
+
}));
|
|
612
|
+
export const writeIntegrationApplyResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
613
|
+
command: "integration.apply",
|
|
614
|
+
result: value,
|
|
615
|
+
}));
|
|
616
|
+
export const writeIntegrationPlanResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
617
|
+
command: "integration.plan",
|
|
618
|
+
result: value,
|
|
619
|
+
}));
|
|
620
|
+
export const writeIntegrationRemoveResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
621
|
+
command: "integration.remove",
|
|
622
|
+
result: value,
|
|
623
|
+
}));
|
|
624
|
+
export const writeIntegrationStatusResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
625
|
+
command: "integration.status",
|
|
626
|
+
result: value,
|
|
627
|
+
}));
|
|
628
|
+
export const writeRuntimeListResult = (result, context) => writeNodeResult(result, context, (value) => ({
|
|
629
|
+
command: "runtime.list",
|
|
630
|
+
items: value.items.map(projectRuntimeListItem),
|
|
631
|
+
}));
|
|
632
|
+
export const writeRuntimeProbeResult = (result, context) => {
|
|
633
|
+
const exitCode = writeNodeResult(result, context, (value) => ({
|
|
634
|
+
command: "runtime.probe",
|
|
635
|
+
result: value,
|
|
636
|
+
}));
|
|
637
|
+
if (!result.ok || result.value.status === "ready")
|
|
638
|
+
return exitCode;
|
|
639
|
+
return result.value.status === "unavailable"
|
|
640
|
+
? EXIT_UNAVAILABLE
|
|
641
|
+
: EXIT_SOFTWARE;
|
|
642
|
+
};
|
|
643
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type BoundedStdinRequest = {
|
|
2
|
+
readonly label: string;
|
|
3
|
+
readonly maxBytes: number;
|
|
4
|
+
readonly maxChunks: number;
|
|
5
|
+
};
|
|
6
|
+
export declare const readBoundedStdin: (input: AsyncIterable<string | Uint8Array>, request: BoundedStdinRequest) => Promise<string>;
|
|
7
|
+
//# sourceMappingURL=stdin.d.ts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Buffer } from "node:buffer";
|
|
2
|
+
import { CliArgumentError } from "./arguments.js";
|
|
3
|
+
const collectNextChunk = async (step) => {
|
|
4
|
+
const next = await step.iterator.next();
|
|
5
|
+
if (next.done === true)
|
|
6
|
+
return;
|
|
7
|
+
const buffer = Buffer.from(next.value);
|
|
8
|
+
const nextBytes = step.collected.bytes + buffer.byteLength;
|
|
9
|
+
if (nextBytes > step.request.maxBytes ||
|
|
10
|
+
step.collected.chunks.length >= step.request.maxChunks) {
|
|
11
|
+
throw new CliArgumentError(`Standard input exceeds the bounded ${step.request.label} limit.`);
|
|
12
|
+
}
|
|
13
|
+
step.collected.bytes = nextBytes;
|
|
14
|
+
step.collected.chunks.push(buffer);
|
|
15
|
+
await collectNextChunk(step);
|
|
16
|
+
};
|
|
17
|
+
export const readBoundedStdin = async (input, request) => {
|
|
18
|
+
const iterator = input[Symbol.asyncIterator]();
|
|
19
|
+
const collected = { bytes: 0, chunks: [] };
|
|
20
|
+
try {
|
|
21
|
+
await collectNextChunk({ collected, iterator, request });
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
await Promise.resolve(iterator.return?.()).catch(() => false);
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(collected.chunks, collected.bytes));
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
throw new CliArgumentError("Standard input must contain valid UTF-8.");
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=stdin.js.map
|