@runtypelabs/cli 2.59.0 → 2.59.2

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.
Files changed (84) hide show
  1. package/dist/chunk-0-T9NWjH.js +3899 -0
  2. package/dist/chunk-0x7UKC1U.js +17 -0
  3. package/dist/chunk-2ySxXtcg.js +418 -0
  4. package/dist/chunk-3An_BRHv.js +501 -0
  5. package/dist/chunk-6uTxgdiY.js +16218 -0
  6. package/dist/chunk-87nRnNRG.js +1363 -0
  7. package/dist/chunk-B3wo8uRx.js +322 -0
  8. package/dist/chunk-BGp3ZdBy.js +560 -0
  9. package/dist/chunk-BJQv9Elp.js +107 -0
  10. package/dist/chunk-BOpO6xE-.js +6053 -0
  11. package/dist/chunk-BQXXCL8B.js +102 -0
  12. package/dist/chunk-BV-8isOd.js +34 -0
  13. package/dist/chunk-BVMhjGVe.js +826 -0
  14. package/dist/chunk-BW2fg46T.js +141 -0
  15. package/dist/chunk-BWJdY5Ag.js +36 -0
  16. package/dist/chunk-BYJOrLhh.js +302 -0
  17. package/dist/chunk-BYab8EVL.js +127 -0
  18. package/dist/chunk-BfEKvp7h.js +82 -0
  19. package/dist/chunk-BhgLSfH6.js +1123 -0
  20. package/dist/chunk-BirUxTtH.js +296 -0
  21. package/dist/chunk-BmB6UVZ9.js +1559 -0
  22. package/dist/chunk-BnWhIqW1.js +109 -0
  23. package/dist/chunk-Bpfnfk0t.js +123 -0
  24. package/dist/chunk-BrhgdnM3.js +108 -0
  25. package/dist/chunk-Bt0XAgX5.js +327 -0
  26. package/dist/chunk-Bu0FJr6S.js +84 -0
  27. package/dist/chunk-BvEoKpN3.js +255 -0
  28. package/dist/chunk-BxNJgYbE.js +28 -0
  29. package/dist/chunk-C1OFhd7F.js +6131 -0
  30. package/dist/chunk-C7e7WwbU.js +331 -0
  31. package/dist/chunk-CDTYP6bN.js +558 -0
  32. package/dist/chunk-CGDQoqDC.js +24 -0
  33. package/dist/chunk-CJraEBVd.js +127 -0
  34. package/dist/chunk-CQrNhOtv.js +40 -0
  35. package/dist/chunk-CW6AzBH6.js +128 -0
  36. package/dist/chunk-CXgL4w-9.js +317 -0
  37. package/dist/chunk-CZrqoPyf.js +233 -0
  38. package/dist/chunk-CcFCyqbB.js +83 -0
  39. package/dist/chunk-CdaIvO-y.js +485 -0
  40. package/dist/chunk-CehSXtgK.js +624 -0
  41. package/dist/chunk-Ciqkop65.js +218 -0
  42. package/dist/chunk-CoAWdSiE.js +43 -0
  43. package/dist/chunk-Crb4y7t4.js +830 -0
  44. package/dist/chunk-CrlqIfmb.js +337 -0
  45. package/dist/chunk-Cs4pwCQ-.js +324 -0
  46. package/dist/chunk-CwM_9y01.js +519 -0
  47. package/dist/chunk-CyRbIJg8.js +440 -0
  48. package/dist/chunk-D0OHsyMy.js +212 -0
  49. package/dist/chunk-D3y2bURs.js +1347 -0
  50. package/dist/chunk-D4_mJk03.js +2338 -0
  51. package/dist/chunk-D6C8rned.js +578 -0
  52. package/dist/chunk-D9ZbUnks.js +11 -0
  53. package/dist/chunk-DEPmLshX.js +834 -0
  54. package/dist/chunk-DFj1UPB2.js +330 -0
  55. package/dist/chunk-DGdFdZVf.js +197 -0
  56. package/dist/chunk-DGv7X9S_.js +63 -0
  57. package/dist/chunk-DJQ47WYZ.js +664 -0
  58. package/dist/chunk-DJw3O61j.js +1974 -0
  59. package/dist/chunk-DK4FbWVK.js +100 -0
  60. package/dist/chunk-DSRYhUus.js +993 -0
  61. package/dist/chunk-DajZ9Eg4.js +299 -0
  62. package/dist/chunk-Df4dunvU.js +195 -0
  63. package/dist/chunk-DjNTPhfO.js +481 -0
  64. package/dist/chunk-Dn8eaJuu.js +1042 -0
  65. package/dist/chunk-DwDWqSxM.js +637 -0
  66. package/dist/chunk-Dz7cEtxl.js +84 -0
  67. package/dist/chunk-E_0bgjrS.js +359 -0
  68. package/dist/chunk-KPYN2vUp.js +776 -0
  69. package/dist/chunk-KcqPQJBi.js +86 -0
  70. package/dist/chunk-N9H0JnoG.js +349 -0
  71. package/dist/chunk-NONFcXkn.js +728 -0
  72. package/dist/chunk-PrFjcpmH.js +256 -0
  73. package/dist/chunk-QSfNYiw9.js +11 -0
  74. package/dist/chunk-R265bzj9.js +226 -0
  75. package/dist/chunk-X9V_r6jM.js +166 -0
  76. package/dist/chunk-ZBtPUtyA.js +55 -0
  77. package/dist/chunk-ZCTfmOs7.js +4939 -0
  78. package/dist/chunk-h6oavj0t.js +97 -0
  79. package/dist/chunk-i7DwkvvD.js +42 -0
  80. package/dist/chunk-mG-4eZ6S.js +203 -0
  81. package/dist/chunk-o0ygUbCf.js +313 -0
  82. package/dist/chunk-ucu5lrDZ.js +5715 -0
  83. package/dist/index.js +11367 -73764
  84. package/package.json +6 -6
@@ -0,0 +1,337 @@
1
+ #!/usr/bin/env node
2
+ import { I as __exportAll } from "./index.js";
3
+ import { s as getDashboardUrl } from "./chunk-BW2fg46T.js";
4
+ import open from "open";
5
+ import { useCallback, useMemo, useRef, useState } from "react";
6
+ import { Box, Text, useInput, useStdout } from "ink";
7
+ import { theme } from "@runtypelabs/ink-components";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
+ // src/ink/talk/ModelPicker.tsx
10
+ var ModelPicker_exports = /* @__PURE__ */ __exportAll({
11
+ DEFAULT_MODELS: () => DEFAULT_MODELS,
12
+ ModelPicker: () => ModelPicker
13
+ });
14
+ const DEFAULT_MODELS = [
15
+ {
16
+ label: "Claude Opus 4.6",
17
+ value: "claude-opus-4-6",
18
+ group: "Anthropic"
19
+ },
20
+ {
21
+ label: "Claude Sonnet 4.6",
22
+ value: "claude-sonnet-4-6",
23
+ group: "Anthropic"
24
+ },
25
+ {
26
+ label: "Claude Haiku 4.5",
27
+ value: "claude-haiku-4-5",
28
+ group: "Anthropic"
29
+ },
30
+ {
31
+ label: "GPT-5",
32
+ value: "gpt-5",
33
+ group: "OpenAI"
34
+ },
35
+ {
36
+ label: "GPT-5 Mini",
37
+ value: "gpt-5-mini",
38
+ group: "OpenAI"
39
+ },
40
+ {
41
+ label: "GPT-4.1",
42
+ value: "gpt-4.1",
43
+ group: "OpenAI"
44
+ },
45
+ {
46
+ label: "GPT-4.1 Mini",
47
+ value: "gpt-4.1-mini",
48
+ group: "OpenAI"
49
+ },
50
+ {
51
+ label: "GPT-4.1 Nano",
52
+ value: "gpt-4.1-nano",
53
+ group: "OpenAI"
54
+ },
55
+ {
56
+ label: "GPT-5 Nano",
57
+ value: "gpt-5-nano",
58
+ group: "OpenAI"
59
+ },
60
+ {
61
+ label: "Gemini 3.1 Pro",
62
+ value: "gemini-3.1-pro",
63
+ group: "Google"
64
+ },
65
+ {
66
+ label: "Gemini 3 Pro Image",
67
+ value: "gemini-3-pro-image",
68
+ group: "Google"
69
+ },
70
+ {
71
+ label: "Gemini 3.1 Flash-Lite",
72
+ value: "gemini-3-1-flash-lite",
73
+ group: "Google"
74
+ },
75
+ {
76
+ label: "Gemini 2.5 Pro",
77
+ value: "gemini-2.5-pro",
78
+ group: "Google"
79
+ },
80
+ {
81
+ label: "Gemini 2.5 Flash",
82
+ value: "gemini-2.5-flash",
83
+ group: "Google"
84
+ },
85
+ {
86
+ label: "Gemini 2.5 Flash Image",
87
+ value: "gemini-2.5-flash-image",
88
+ group: "Google"
89
+ },
90
+ {
91
+ label: "Gemini 2.5 Flash-Lite",
92
+ value: "gemini-2.5-flash-lite",
93
+ group: "Google"
94
+ },
95
+ {
96
+ label: "Grok 4",
97
+ value: "grok-4",
98
+ group: "xAI"
99
+ },
100
+ {
101
+ label: "Grok 4 Fast",
102
+ value: "grok-4-fast",
103
+ group: "xAI"
104
+ },
105
+ {
106
+ label: "Grok 4.1 Fast",
107
+ value: "grok-4.1-fast",
108
+ group: "xAI"
109
+ },
110
+ {
111
+ label: "Qwen 3.5 Plus",
112
+ value: "qwen3.5-plus",
113
+ group: "Qwen"
114
+ },
115
+ {
116
+ label: "Qwen 3.5 35B A3B",
117
+ value: "qwen3.5-35b-a3b",
118
+ group: "Qwen"
119
+ },
120
+ {
121
+ label: "Qwen 3.5 Flash",
122
+ value: "qwen3.5-flash",
123
+ group: "Qwen"
124
+ },
125
+ {
126
+ label: "Qwen 3 8B",
127
+ value: "qwen/qwen3-8b",
128
+ group: "Qwen"
129
+ }
130
+ ];
131
+ /** Max visible rows in the model list (excluding header/footer) */
132
+ const MAX_VISIBLE = 12;
133
+ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
134
+ const { stdout } = useStdout();
135
+ const [search, setSearch] = useState("");
136
+ const availableModels = models && models.length > 0 ? models : DEFAULT_MODELS;
137
+ const contentWidth = (stdout?.columns ?? 120) - 4;
138
+ const pad = useCallback((text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text, [contentWidth]);
139
+ const sorted = useMemo(() => [...availableModels].sort((a, b) => a.group.localeCompare(b.group)), [availableModels]);
140
+ const filtered = useMemo(() => {
141
+ if (!search.trim()) return sorted;
142
+ const q = search.toLowerCase();
143
+ return sorted.filter((m) => m.label.toLowerCase().includes(q) || m.value.toLowerCase().includes(q) || m.group.toLowerCase().includes(q));
144
+ }, [sorted, search]);
145
+ const searchRef = useRef("");
146
+ const cursorRef = useRef(0);
147
+ const [cursorPos, setCursorPos] = useState(0);
148
+ const [selectedIndex, setSelectedIndex] = useState(() => {
149
+ const currentIndex = sorted.findIndex((model) => model.value === currentModel);
150
+ return currentIndex >= 0 ? currentIndex : 0;
151
+ });
152
+ const safeIndex = filtered.length > 0 ? Math.min(selectedIndex, filtered.length - 1) : 0;
153
+ const applySearch = useCallback((newValue, newCursor) => {
154
+ searchRef.current = newValue;
155
+ cursorRef.current = newCursor;
156
+ setSearch(newValue);
157
+ setCursorPos(newCursor);
158
+ if (!newValue.trim()) {
159
+ const idx = sorted.findIndex((model) => model.value === currentModel);
160
+ setSelectedIndex(idx >= 0 ? idx : 0);
161
+ } else setSelectedIndex(0);
162
+ }, [sorted, currentModel]);
163
+ useInput((input, key) => {
164
+ if (key.escape) {
165
+ onCancel();
166
+ return;
167
+ }
168
+ if (key.return) {
169
+ if (filtered.length > 0) onSelect(filtered[safeIndex].value);
170
+ return;
171
+ }
172
+ if (key.upArrow) {
173
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : filtered.length - 1);
174
+ return;
175
+ }
176
+ if (key.downArrow) {
177
+ setSelectedIndex((prev) => prev < filtered.length - 1 ? prev + 1 : 0);
178
+ return;
179
+ }
180
+ if (key.tab) {
181
+ open(`${getDashboardUrl()}/settings/models`);
182
+ return;
183
+ }
184
+ if (key.backspace || key.delete) {
185
+ const cursor = cursorRef.current;
186
+ if (cursor > 0) {
187
+ const prev = searchRef.current;
188
+ applySearch(prev.slice(0, cursor - 1) + prev.slice(cursor), cursor - 1);
189
+ }
190
+ return;
191
+ }
192
+ if (key.leftArrow) {
193
+ const nc = Math.max(0, cursorRef.current - 1);
194
+ cursorRef.current = nc;
195
+ setCursorPos(nc);
196
+ return;
197
+ }
198
+ if (key.rightArrow) {
199
+ const nc = Math.min(searchRef.current.length, cursorRef.current + 1);
200
+ cursorRef.current = nc;
201
+ setCursorPos(nc);
202
+ return;
203
+ }
204
+ if (input && !key.ctrl && !key.meta) {
205
+ const cursor = cursorRef.current;
206
+ const prev = searchRef.current;
207
+ applySearch(prev.slice(0, cursor) + input + prev.slice(cursor), cursor + input.length);
208
+ }
209
+ });
210
+ let modelWindow = 8;
211
+ let modelWindowStart = 0;
212
+ let modelWindowEnd = 0;
213
+ let rows = [];
214
+ for (let attempt = 0; attempt < 3; attempt++) {
215
+ modelWindowStart = Math.max(0, Math.min(safeIndex - Math.floor(modelWindow / 2), filtered.length - modelWindow));
216
+ modelWindowEnd = Math.min(modelWindowStart + modelWindow, filtered.length);
217
+ rows = [];
218
+ let lastGroup = "";
219
+ for (let i = modelWindowStart; i < modelWindowEnd; i++) {
220
+ const model = filtered[i];
221
+ if (model.group !== lastGroup) {
222
+ rows.push({
223
+ type: "group",
224
+ label: model.group
225
+ });
226
+ lastGroup = model.group;
227
+ }
228
+ rows.push({
229
+ type: "model",
230
+ model,
231
+ isHighlighted: i === safeIndex,
232
+ isCurrent: model.value === currentModel
233
+ });
234
+ }
235
+ if (rows.length <= MAX_VISIBLE) break;
236
+ modelWindow = Math.max(1, modelWindow - (rows.length - MAX_VISIBLE));
237
+ }
238
+ while (rows.length < MAX_VISIBLE) rows.push({ type: "blank" });
239
+ const showScrollUp = modelWindowStart > 0;
240
+ const showScrollDown = modelWindowEnd < filtered.length;
241
+ return /* @__PURE__ */ jsxs(Box, {
242
+ borderStyle: "single",
243
+ borderColor: theme.border,
244
+ backgroundColor: theme.surfaceElevated,
245
+ paddingX: theme.panelPaddingX,
246
+ paddingY: theme.panelPaddingY,
247
+ flexDirection: "column",
248
+ children: [
249
+ /* @__PURE__ */ jsxs(Box, {
250
+ marginBottom: 1,
251
+ children: [/* @__PURE__ */ jsx(Text, {
252
+ color: theme.accent,
253
+ bold: true,
254
+ children: "Select Model"
255
+ }), /* @__PURE__ */ jsxs(Text, {
256
+ color: theme.textSubtle,
257
+ children: [
258
+ " ",
259
+ filtered.length,
260
+ " models"
261
+ ]
262
+ })]
263
+ }),
264
+ /* @__PURE__ */ jsxs(Box, {
265
+ marginBottom: 1,
266
+ children: [/* @__PURE__ */ jsx(Text, {
267
+ color: theme.textSubtle,
268
+ children: "/ "
269
+ }), search.length > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
270
+ /* @__PURE__ */ jsx(Text, { children: search.slice(0, cursorPos) }),
271
+ /* @__PURE__ */ jsx(Text, {
272
+ inverse: true,
273
+ children: search[cursorPos] ?? " "
274
+ }),
275
+ cursorPos < search.length && /* @__PURE__ */ jsx(Text, { children: search.slice(cursorPos + 1) })
276
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, {
277
+ inverse: true,
278
+ children: " "
279
+ }), /* @__PURE__ */ jsx(Text, {
280
+ color: theme.textSubtle,
281
+ children: "Search models..."
282
+ })] })]
283
+ }),
284
+ /* @__PURE__ */ jsx(Box, {
285
+ height: 1,
286
+ children: /* @__PURE__ */ jsx(Text, {
287
+ color: theme.textSubtle,
288
+ children: pad(showScrollUp ? " ..." : "")
289
+ })
290
+ }),
291
+ /* @__PURE__ */ jsx(Box, {
292
+ flexDirection: "column",
293
+ height: MAX_VISIBLE,
294
+ children: filtered.length === 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Text, {
295
+ color: theme.textSubtle,
296
+ children: pad(" No matching models")
297
+ }), Array.from({ length: 11 }, (_, i) => /* @__PURE__ */ jsx(Text, { children: pad("") }, `empty-${i}`))] }) : rows.map((row, i) => {
298
+ if (row.type === "blank") return /* @__PURE__ */ jsx(Text, { children: pad("") }, `blank-${i}`);
299
+ if (row.type === "group") return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, {
300
+ color: theme.textSubtle,
301
+ dimColor: true,
302
+ children: pad(` ${row.label}`)
303
+ }) }, `group-${row.label}`);
304
+ const { model, isHighlighted, isCurrent } = row;
305
+ const indicator = isHighlighted ? "› " : " ";
306
+ const suffix = isCurrent ? " *" : "";
307
+ return /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsx(Text, {
308
+ color: isHighlighted ? theme.accentActive : isCurrent ? theme.accent : theme.textMuted,
309
+ bold: isHighlighted,
310
+ children: pad(`${indicator}${model.label}${suffix}`)
311
+ }) }, model.value);
312
+ })
313
+ }),
314
+ /* @__PURE__ */ jsx(Box, {
315
+ height: 1,
316
+ children: /* @__PURE__ */ jsx(Text, {
317
+ color: theme.textSubtle,
318
+ children: pad(showScrollDown ? " ..." : "")
319
+ })
320
+ }),
321
+ /* @__PURE__ */ jsx(Box, {
322
+ marginTop: 1,
323
+ children: /* @__PURE__ */ jsx(Text, {
324
+ color: theme.textSubtle,
325
+ children: [
326
+ "↑↓ navigate",
327
+ "Enter select",
328
+ "Tab manage models",
329
+ "Esc cancel"
330
+ ].join(theme.separator ?? " · ")
331
+ })
332
+ })
333
+ ]
334
+ });
335
+ }
336
+ export { ModelPicker_exports as n, ModelPicker as t };
337
+
@@ -0,0 +1,324 @@
1
+ #!/usr/bin/env node
2
+ import { g as isOwnExecutionFrame } from "./chunk-ucu5lrDZ.js";
3
+ import { r as createCliClient } from "./chunk-BW2fg46T.js";
4
+ import { n as ensureAuth } from "./chunk-CJraEBVd.js";
5
+ import { a as printJson } from "./chunk-CcFCyqbB.js";
6
+ import chalk from "chalk";
7
+ import { readFileSync } from "fs";
8
+ import { RuntypeApiError, parseFinalBuffer, parseSSEChunk } from "@runtypelabs/sdk";
9
+ // src/lib/execution-input.ts
10
+ function addExecutionInputOptions(command) {
11
+ return command.option("--inputs <json>", "Typed input variables as a JSON object").option("--inputs-file <file|->", "Read input variables from a JSON object file or stdin").option("-v, --variable <key=value>", "Set a string variable (repeatable)", collectVariables, []).option("--messages-file <file|->", "Read structured messages from a JSON array file or stdin");
12
+ }
13
+ function collectVariables(value, previous) {
14
+ return [...previous, value];
15
+ }
16
+ function usesExecutionStdin(options) {
17
+ return [
18
+ options.inputsFile,
19
+ options.messagesFile,
20
+ options.recordJson
21
+ ].includes("-");
22
+ }
23
+ function parseJson(raw, label) {
24
+ try {
25
+ return JSON.parse(raw);
26
+ } catch {
27
+ throw new Error(`Invalid JSON in ${label}`);
28
+ }
29
+ }
30
+ function readJson(path, label) {
31
+ if (path === "-" && process.stdin.isTTY) throw new Error(`Pipe ${label} JSON to stdin when using -`);
32
+ let raw;
33
+ try {
34
+ raw = readFileSync(path === "-" ? 0 : path, "utf-8");
35
+ } catch {
36
+ throw new Error(`Failed to read ${label}`);
37
+ }
38
+ return parseJson(raw, label);
39
+ }
40
+ function isObject(value) {
41
+ return typeof value === "object" && value !== null && !Array.isArray(value);
42
+ }
43
+ function requireObject(value, label) {
44
+ if (!isObject(value)) throw new Error(`${label} must be a JSON object`);
45
+ return value;
46
+ }
47
+ function validateContent(content, agent) {
48
+ if (typeof content === "string" && (agent || content.length > 0)) return;
49
+ if (!Array.isArray(content) || content.length === 0) throw new Error("Message content must be a string or a nonempty multimodal array");
50
+ for (const part of content) {
51
+ if (!isObject(part) || typeof part.type !== "string" || !part.type) throw new Error("Message content parts must be objects with a type");
52
+ const required = {
53
+ text: ["text"],
54
+ image: ["image"],
55
+ file: agent ? ["data"] : [
56
+ "data",
57
+ "mimeType",
58
+ "filename"
59
+ ],
60
+ reasoning: ["text"]
61
+ };
62
+ const fields = Object.hasOwn(required, part.type) ? required[part.type] : void 0;
63
+ if (!agent && !fields || fields?.some((field) => typeof part[field] !== "string")) throw new Error(`Invalid ${part.type} message content part`);
64
+ }
65
+ }
66
+ function resolveExecutionInput(options, agent = false) {
67
+ if ([
68
+ options.inputsFile,
69
+ options.messagesFile,
70
+ options.recordJson
71
+ ].filter((p) => p === "-").length > 1) throw new Error("Only one input source may read stdin");
72
+ if (options.inputs !== void 0 && options.inputsFile !== void 0) throw new Error("Use only one of --inputs and --inputs-file");
73
+ if (options.message !== void 0 && options.messagesFile !== void 0) throw new Error("Use only one of --message and --messages-file");
74
+ if (options.record !== void 0 && options.recordJson !== void 0) throw new Error("Use only one of --record and --record-json");
75
+ let inputs;
76
+ if (options.inputs !== void 0 || options.inputsFile !== void 0) inputs = { ...requireObject(options.inputsFile !== void 0 ? readJson(options.inputsFile, "Inputs") : parseJson(options.inputs, "Inputs"), "Inputs") };
77
+ for (const variable of options.variable ?? []) {
78
+ const separator = variable.indexOf("=");
79
+ if (separator <= 0 || !variable.slice(0, separator).trim()) throw new Error("--variable must be key=value with a nonempty key");
80
+ const key = variable.slice(0, separator);
81
+ inputs ??= {};
82
+ if (Object.hasOwn(inputs, key)) throw new Error(`Duplicate input key: ${key}`);
83
+ Object.defineProperty(inputs, key, {
84
+ value: variable.slice(separator + 1),
85
+ enumerable: true
86
+ });
87
+ }
88
+ const messages = options.messagesFile !== void 0 ? readJson(options.messagesFile, "Messages") : options.message !== void 0 ? [{
89
+ role: "user",
90
+ content: options.message
91
+ }] : void 0;
92
+ if (messages !== void 0) {
93
+ if (!Array.isArray(messages) || messages.length === 0) throw new Error("Messages must be a nonempty JSON array");
94
+ const roles = agent ? [
95
+ "system",
96
+ "user",
97
+ "assistant",
98
+ "tool"
99
+ ] : [
100
+ "system",
101
+ "user",
102
+ "assistant"
103
+ ];
104
+ for (const message of messages) {
105
+ if (!isObject(message) || !roles.includes(String(message.role))) throw new Error(`Invalid message role: ${agent ? "agent execute" : "dispatch (including agents with inputs)"} accepts ${roles.join(", ")}`);
106
+ validateContent(message.content, agent);
107
+ }
108
+ } else if (agent) throw new Error("Either --message or --messages-file is required");
109
+ const record = options.record !== void 0 ? { id: options.record } : options.recordJson !== void 0 ? { metadata: requireObject(readJson(options.recordJson, "Record"), "Record") } : void 0;
110
+ return {
111
+ ...inputs !== void 0 ? { inputs } : {},
112
+ ...messages !== void 0 ? { messages } : {},
113
+ ...record ? { record } : {}
114
+ };
115
+ }
116
+ // src/lib/execution-output.ts
117
+ function asObject(value) {
118
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : void 0;
119
+ }
120
+ function executionFailed(value) {
121
+ const result = asObject(value);
122
+ if (!result) return false;
123
+ return result.success === false || result.success === void 0 && typeof result.failedSteps === "number" && result.failedSteps > 0 || [
124
+ "failed",
125
+ "error",
126
+ "cancelled",
127
+ "canceled"
128
+ ].includes(String(result.status)) || executionFailed(result.executionSummary) || executionFailed(result.execution);
129
+ }
130
+ function normalizeExecutionResult(value) {
131
+ const result = asObject(value);
132
+ if (result && ([
133
+ "paused",
134
+ "awaiting",
135
+ "awaiting_input",
136
+ "awaiting_approval"
137
+ ].includes(String(result.status)) || result.stopReason === "paused")) {
138
+ const awaiting = {
139
+ ...result,
140
+ status: "awaiting_input"
141
+ };
142
+ delete awaiting.success;
143
+ return awaiting;
144
+ }
145
+ return value;
146
+ }
147
+ function executionError(error, code) {
148
+ const source = asObject(error);
149
+ const data = error instanceof RuntypeApiError ? asObject(error.data) : source;
150
+ const nested = asObject(data?.error);
151
+ const requestId = nested?.requestId ?? data?.requestId ?? (error instanceof RuntypeApiError ? error.headers?.get("x-request-id") : void 0);
152
+ return {
153
+ success: false,
154
+ error: {
155
+ code: nested?.code ?? data?.code ?? code,
156
+ message: error instanceof Error ? error.message : nested?.message ?? data?.message ?? (typeof data?.error === "string" ? data.error : void 0) ?? (typeof error === "string" ? error : "Execution failed"),
157
+ ...error instanceof RuntypeApiError ? { status: error.statusCode } : {},
158
+ ...requestId ? { requestId } : {}
159
+ }
160
+ };
161
+ }
162
+ function emitResult(value, options) {
163
+ if (options.jsonl && !options.json) console.log(JSON.stringify({
164
+ type: "execution_summary",
165
+ data: value
166
+ }));
167
+ else printJson(value);
168
+ }
169
+ async function consumeExecutionStream(response, options) {
170
+ if (!response.ok) {
171
+ let data;
172
+ try {
173
+ data = await response.json();
174
+ } catch {
175
+ data = void 0;
176
+ }
177
+ throw new RuntypeApiError(`HTTP ${response.status}: ${response.statusText}`, response.status, data, response.headers);
178
+ }
179
+ if (response.headers.get("content-type")?.includes("application/json")) {
180
+ const result = asObject(await response.json());
181
+ if (!result) throw new Error("Invalid execution response");
182
+ if (result.error && result.success === void 0 && result.status === void 0) return executionError(result, "EXECUTION_FAILED");
183
+ if (result.success === void 0 && result.status === void 0 && !result.executionSummary && !result.execution) return executionError("Execution response did not contain a terminal or await summary", "INCOMPLETE_STREAM");
184
+ return result;
185
+ }
186
+ const reader = response.body?.getReader();
187
+ if (!reader) throw new Error("Response body is not readable");
188
+ const decoder = new TextDecoder();
189
+ let buffer = "";
190
+ let terminal;
191
+ let awaiting;
192
+ let failure;
193
+ let ownerExecutionId;
194
+ const results = {};
195
+ const accept = (raw) => {
196
+ let parsed;
197
+ try {
198
+ parsed = JSON.parse(raw);
199
+ } catch {
200
+ throw new Error("Invalid JSON in execution stream");
201
+ }
202
+ const event = asObject(parsed);
203
+ if (!event || typeof event.type !== "string") throw new Error("Invalid execution stream event");
204
+ if (options.jsonl) console.log(JSON.stringify(event));
205
+ const data = asObject(event.data) ?? event;
206
+ const executionId = typeof data.executionId === "string" ? data.executionId : typeof event.executionId === "string" ? event.executionId : void 0;
207
+ const attributedSubagent = Object.hasOwn(event, "subagent") || Object.hasOwn(data, "subagent");
208
+ if (!attributedSubagent && !data.parentToolCallId && !event.parentToolCallId) ownerExecutionId ??= executionId;
209
+ if (attributedSubagent && (!ownerExecutionId || executionId !== ownerExecutionId)) return;
210
+ if (isOwnExecutionFrame({ executionId: executionId ?? ownerExecutionId }, ownerExecutionId)) {
211
+ if ([
212
+ "execution_complete",
213
+ "flow_complete",
214
+ "agent_complete"
215
+ ].includes(event.type)) terminal = data;
216
+ if ([
217
+ "execution_error",
218
+ "flow_error",
219
+ "agent_error"
220
+ ].includes(event.type)) failure = executionError(data, "EXECUTION_FAILED");
221
+ if ([
222
+ "await",
223
+ "flow_await",
224
+ "agent_await"
225
+ ].includes(event.type)) awaiting = {
226
+ ...data,
227
+ status: "awaiting_input",
228
+ await: event
229
+ };
230
+ if (["approval_start", "agent_approval_start"].includes(event.type)) awaiting = {
231
+ ...data,
232
+ status: "awaiting_input",
233
+ awaitReason: "approval_required",
234
+ await: event
235
+ };
236
+ if (["approval_complete", "agent_approval_complete"].includes(event.type)) awaiting = void 0;
237
+ if (event.type === "step_complete") {
238
+ const name = String(data.name ?? data.stepName ?? data.stepId ?? "");
239
+ Object.defineProperty(results, name, {
240
+ value: data.result ?? data.output,
241
+ enumerable: true,
242
+ configurable: true
243
+ });
244
+ }
245
+ }
246
+ if (!options.json && !options.jsonl) {
247
+ if (event.type === "text_delta" || event.type === "step_delta" || ["turn_delta", "agent_turn_delta"].includes(event.type) && data.contentType === "text") process.stdout.write(String(data.text ?? data.delta ?? data.chunk ?? ""));
248
+ if (options.debug && ["step_start", "step_complete"].includes(event.type)) console.log(chalk.gray(`\n[${String(data.name ?? data.stepName ?? data.stepId ?? "")}] ${event.type === "step_start" ? "Running..." : "Complete"}`));
249
+ }
250
+ };
251
+ try {
252
+ while (true) {
253
+ const { done, value } = await reader.read();
254
+ const parsed = parseSSEChunk(done ? decoder.decode() : decoder.decode(value, { stream: true }), buffer);
255
+ buffer = parsed.remainingBuffer;
256
+ for (const raw of parsed.events) accept(raw);
257
+ if (done) break;
258
+ }
259
+ const final = parseFinalBuffer(buffer);
260
+ if (final) accept(final);
261
+ } catch (error) {
262
+ await reader.cancel().catch(() => void 0);
263
+ throw error;
264
+ } finally {
265
+ reader.releaseLock();
266
+ }
267
+ const resultFields = Object.keys(results).length ? { results } : {};
268
+ if (failure) return {
269
+ ...terminal,
270
+ ...failure,
271
+ ...resultFields
272
+ };
273
+ if (terminal) return {
274
+ ...terminal,
275
+ ...resultFields
276
+ };
277
+ if (awaiting && awaiting.awaitReason !== "detached") {
278
+ delete awaiting.success;
279
+ return {
280
+ ...awaiting,
281
+ ...resultFields
282
+ };
283
+ }
284
+ return executionError("Execution stream ended without a terminal or await event", "INCOMPLETE_STREAM");
285
+ }
286
+ async function runExecution(options, build, execute, label, renderResult) {
287
+ let errorCode = "INVALID_INPUT";
288
+ try {
289
+ if (options.json && options.jsonl) throw new Error("--json and --jsonl are mutually exclusive");
290
+ const payload = build();
291
+ errorCode = "AUTH_REQUIRED";
292
+ const apiKey = await ensureAuth({
293
+ exitOnFailure: false,
294
+ ...usesExecutionStdin(options) || options.json || options.jsonl ? { interactive: false } : {}
295
+ });
296
+ if (!apiKey) throw new Error("Authentication required");
297
+ errorCode = "EXECUTION_FAILED";
298
+ if (!options.json && !options.jsonl) console.log(chalk.gray(`${options.stream ? "Starting" : "Executing"} ${label}...`));
299
+ const response = await execute(createCliClient(apiKey), payload);
300
+ const result = normalizeExecutionResult(options.stream ? await consumeExecutionStream(response, options) : response);
301
+ if (executionFailed(result)) process.exitCode = 1;
302
+ else if ([
303
+ "awaiting",
304
+ "awaiting_input",
305
+ "awaiting_approval"
306
+ ].includes(String(asObject(result)?.status))) process.exitCode = 2;
307
+ if (options.json || options.jsonl) emitResult(result, options);
308
+ else if (!options.stream) {
309
+ if (renderResult) renderResult(result);
310
+ else printJson(result);
311
+ } else {
312
+ console.log();
313
+ if (executionFailed(result)) console.error(chalk.red("Execution failed"));
314
+ else if (asObject(result)?.status === "awaiting_input") printJson(result);
315
+ }
316
+ } catch (error) {
317
+ process.exitCode = 1;
318
+ const result = executionError(error, errorCode);
319
+ if (options.json || options.jsonl) emitResult(result, options);
320
+ else console.error(chalk.red(String(result.error.message)));
321
+ }
322
+ }
323
+ export { addExecutionInputOptions as n, resolveExecutionInput as r, runExecution as t };
324
+