@runtypelabs/cli 2.0.1 → 2.1.0
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 +80 -4
- package/dist/index.js +429 -227
- package/dist/index.js.map +1 -1
- package/package.json +4 -2
package/dist/index.js
CHANGED
|
@@ -688,7 +688,7 @@ var require_builtin_tools_registry = __commonJS({
|
|
|
688
688
|
return compatibility.models.some((m) => modelId.includes(m));
|
|
689
689
|
}
|
|
690
690
|
function getCompatibleBuiltInTools(modelId, provider) {
|
|
691
|
-
return exports.BUILTIN_TOOLS_REGISTRY.filter((tool) => isToolCompatibleWithModel2(tool.id, modelId, provider));
|
|
691
|
+
return exports.BUILTIN_TOOLS_REGISTRY.filter((tool) => !tool.hidden && isToolCompatibleWithModel2(tool.id, modelId, provider));
|
|
692
692
|
}
|
|
693
693
|
function validateToolConfig(toolId, config2) {
|
|
694
694
|
const tool = getBuiltInToolById2(toolId);
|
|
@@ -8333,7 +8333,7 @@ import { Command as Command11 } from "commander";
|
|
|
8333
8333
|
import chalk17 from "chalk";
|
|
8334
8334
|
import React10 from "react";
|
|
8335
8335
|
import { render as render10 } from "ink";
|
|
8336
|
-
import { useState as useState24, useEffect as
|
|
8336
|
+
import { useState as useState24, useEffect as useEffect21 } from "react";
|
|
8337
8337
|
import { processStream as processStream4 } from "@runtypelabs/sdk";
|
|
8338
8338
|
|
|
8339
8339
|
// src/commands/agents-task.ts
|
|
@@ -8343,7 +8343,7 @@ import { render as render9 } from "ink";
|
|
|
8343
8343
|
import React9 from "react";
|
|
8344
8344
|
|
|
8345
8345
|
// src/ink/marathon/MarathonApp.tsx
|
|
8346
|
-
import { useState as useState22, useEffect as
|
|
8346
|
+
import { useState as useState22, useEffect as useEffect19, useRef as useRef9, useCallback as useCallback8, useMemo as useMemo11 } from "react";
|
|
8347
8347
|
import { execSync } from "child_process";
|
|
8348
8348
|
import * as fs4 from "fs";
|
|
8349
8349
|
import open4 from "open";
|
|
@@ -8539,12 +8539,12 @@ function pushRawEvent(eventsRef, type, data, writer, listData) {
|
|
|
8539
8539
|
type: event.type,
|
|
8540
8540
|
data: buildPersistedEventData(event.data, listData)
|
|
8541
8541
|
};
|
|
8542
|
-
|
|
8542
|
+
queueMicrotask(() => {
|
|
8543
8543
|
try {
|
|
8544
8544
|
w(jsonlEvent);
|
|
8545
8545
|
} catch {
|
|
8546
8546
|
}
|
|
8547
|
-
}
|
|
8547
|
+
});
|
|
8548
8548
|
}
|
|
8549
8549
|
eventsRef.current.push(event);
|
|
8550
8550
|
if (eventsRef.current.length > MAX_RAW_EVENTS) {
|
|
@@ -10821,7 +10821,7 @@ function createSandboxInstructions(provider) {
|
|
|
10821
10821
|
"Deploy rules:",
|
|
10822
10822
|
"1. Use this when you need to run a web server (Express, Hono, etc.) that the user can visit in their browser.",
|
|
10823
10823
|
"2. The `code` is written to main.ts (or main.js/main.py). The `packageJson` object installs dependencies.",
|
|
10824
|
-
"3. The `files` parameter writes additional files (path \u2192 content). Use this for HTML/CSS/JS assets instead of embedding them in template literals.",
|
|
10824
|
+
"3. The `files` parameter writes additional files (path \u2192 content). Keys must be plain file paths without wrapping quotes. Use this for HTML/CSS/JS assets instead of embedding them in template literals.",
|
|
10825
10825
|
"4. The server must listen on the specified `port` (default 3000).",
|
|
10826
10826
|
"5. The sandbox is persistent \u2014 it stays alive across sessions. The same sandbox is reused on subsequent calls.",
|
|
10827
10827
|
"6. The returned `previewUrl` is a live URL the user can open in their browser.",
|
|
@@ -10979,7 +10979,7 @@ function createDeploySandboxLocalTool(client, debugMode) {
|
|
|
10979
10979
|
},
|
|
10980
10980
|
files: {
|
|
10981
10981
|
type: "object",
|
|
10982
|
-
description: 'Additional files to write (path \u2192 content), e.g. { "public/index.html": "<html>..." }. Use this for multi-file projects instead of embedding HTML in template literals.',
|
|
10982
|
+
description: 'Additional files to write (path \u2192 content), e.g. { "public/index.html": "<html>..." }. Keys must be plain file paths without wrapping quotes. Use this for multi-file projects instead of embedding HTML in template literals.',
|
|
10983
10983
|
additionalProperties: { type: "string" }
|
|
10984
10984
|
}
|
|
10985
10985
|
},
|
|
@@ -11109,7 +11109,7 @@ function readSessionEventLog(stateFilePath2, sessionIndex) {
|
|
|
11109
11109
|
}
|
|
11110
11110
|
|
|
11111
11111
|
// src/ink/marathon/CheckpointPrompt.tsx
|
|
11112
|
-
import { useState as useState18, useEffect as
|
|
11112
|
+
import { useState as useState18, useEffect as useEffect15, useRef as useRef8 } from "react";
|
|
11113
11113
|
import { Box as Box21, Text as Text23 } from "ink";
|
|
11114
11114
|
|
|
11115
11115
|
// src/ink/marathon/BlinkingTextInput.tsx
|
|
@@ -11247,12 +11247,11 @@ function BlinkingTextInput({
|
|
|
11247
11247
|
import { theme as theme23 } from "@runtypelabs/ink-components";
|
|
11248
11248
|
|
|
11249
11249
|
// src/ink/talk/ModelPicker.tsx
|
|
11250
|
-
import { useState as useState15, useMemo as useMemo7, useCallback as useCallback5,
|
|
11250
|
+
import { useState as useState15, useMemo as useMemo7, useCallback as useCallback5, useRef as useRef6 } from "react";
|
|
11251
11251
|
import { Box as Box17, Text as Text19, useInput as useInput7, useStdout as useStdout2 } from "ink";
|
|
11252
|
-
import TextInput2 from "ink-text-input";
|
|
11253
11252
|
import open3 from "open";
|
|
11254
11253
|
import { theme as theme19 } from "@runtypelabs/ink-components";
|
|
11255
|
-
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
11254
|
+
import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
11256
11255
|
var DEFAULT_MODELS = [
|
|
11257
11256
|
// Anthropic
|
|
11258
11257
|
{ label: "Claude Opus 4.6", value: "claude-opus-4-6", group: "Anthropic" },
|
|
@@ -11293,38 +11292,45 @@ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
|
11293
11292
|
(text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text,
|
|
11294
11293
|
[contentWidth]
|
|
11295
11294
|
);
|
|
11295
|
+
const sorted = useMemo7(
|
|
11296
|
+
() => [...availableModels].sort((a, b) => a.group.localeCompare(b.group)),
|
|
11297
|
+
[availableModels]
|
|
11298
|
+
);
|
|
11296
11299
|
const filtered = useMemo7(() => {
|
|
11297
|
-
if (!search.trim()) return
|
|
11300
|
+
if (!search.trim()) return sorted;
|
|
11298
11301
|
const q = search.toLowerCase();
|
|
11299
|
-
return
|
|
11302
|
+
return sorted.filter(
|
|
11300
11303
|
(m) => m.label.toLowerCase().includes(q) || m.value.toLowerCase().includes(q) || m.group.toLowerCase().includes(q)
|
|
11301
11304
|
);
|
|
11302
|
-
}, [
|
|
11305
|
+
}, [sorted, search]);
|
|
11306
|
+
const searchRef = useRef6("");
|
|
11307
|
+
const cursorRef = useRef6(0);
|
|
11308
|
+
const [cursorPos, setCursorPos] = useState15(0);
|
|
11303
11309
|
const [selectedIndex, setSelectedIndex] = useState15(() => {
|
|
11304
|
-
const currentIndex =
|
|
11310
|
+
const currentIndex = sorted.findIndex((model) => model.value === currentModel);
|
|
11305
11311
|
return currentIndex >= 0 ? currentIndex : 0;
|
|
11306
11312
|
});
|
|
11307
|
-
const
|
|
11308
|
-
|
|
11309
|
-
|
|
11310
|
-
|
|
11311
|
-
|
|
11312
|
-
|
|
11313
|
-
if (!
|
|
11314
|
-
const
|
|
11315
|
-
setSelectedIndex(
|
|
11316
|
-
|
|
11313
|
+
const safeIndex = filtered.length > 0 ? Math.min(selectedIndex, filtered.length - 1) : 0;
|
|
11314
|
+
const applySearch = useCallback5((newValue, newCursor) => {
|
|
11315
|
+
searchRef.current = newValue;
|
|
11316
|
+
cursorRef.current = newCursor;
|
|
11317
|
+
setSearch(newValue);
|
|
11318
|
+
setCursorPos(newCursor);
|
|
11319
|
+
if (!newValue.trim()) {
|
|
11320
|
+
const idx = sorted.findIndex((model) => model.value === currentModel);
|
|
11321
|
+
setSelectedIndex(idx >= 0 ? idx : 0);
|
|
11322
|
+
} else {
|
|
11323
|
+
setSelectedIndex(0);
|
|
11317
11324
|
}
|
|
11318
|
-
|
|
11319
|
-
|
|
11320
|
-
useInput7((_input, key) => {
|
|
11325
|
+
}, [sorted, currentModel]);
|
|
11326
|
+
useInput7((input, key) => {
|
|
11321
11327
|
if (key.escape) {
|
|
11322
11328
|
onCancel();
|
|
11323
11329
|
return;
|
|
11324
11330
|
}
|
|
11325
11331
|
if (key.return) {
|
|
11326
11332
|
if (filtered.length > 0) {
|
|
11327
|
-
onSelect(filtered[
|
|
11333
|
+
onSelect(filtered[safeIndex].value);
|
|
11328
11334
|
}
|
|
11329
11335
|
return;
|
|
11330
11336
|
}
|
|
@@ -11340,30 +11346,65 @@ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
|
11340
11346
|
void open3(`${getDashboardUrl()}/settings/models`);
|
|
11341
11347
|
return;
|
|
11342
11348
|
}
|
|
11349
|
+
if (key.backspace || key.delete) {
|
|
11350
|
+
const cursor = cursorRef.current;
|
|
11351
|
+
if (cursor > 0) {
|
|
11352
|
+
const prev = searchRef.current;
|
|
11353
|
+
applySearch(prev.slice(0, cursor - 1) + prev.slice(cursor), cursor - 1);
|
|
11354
|
+
}
|
|
11355
|
+
return;
|
|
11356
|
+
}
|
|
11357
|
+
if (key.leftArrow) {
|
|
11358
|
+
const nc = Math.max(0, cursorRef.current - 1);
|
|
11359
|
+
cursorRef.current = nc;
|
|
11360
|
+
setCursorPos(nc);
|
|
11361
|
+
return;
|
|
11362
|
+
}
|
|
11363
|
+
if (key.rightArrow) {
|
|
11364
|
+
const nc = Math.min(searchRef.current.length, cursorRef.current + 1);
|
|
11365
|
+
cursorRef.current = nc;
|
|
11366
|
+
setCursorPos(nc);
|
|
11367
|
+
return;
|
|
11368
|
+
}
|
|
11369
|
+
if (input && !key.ctrl && !key.meta) {
|
|
11370
|
+
const cursor = cursorRef.current;
|
|
11371
|
+
const prev = searchRef.current;
|
|
11372
|
+
applySearch(prev.slice(0, cursor) + input + prev.slice(cursor), cursor + input.length);
|
|
11373
|
+
}
|
|
11343
11374
|
});
|
|
11344
|
-
|
|
11345
|
-
|
|
11346
|
-
|
|
11347
|
-
|
|
11348
|
-
|
|
11349
|
-
|
|
11350
|
-
|
|
11351
|
-
|
|
11352
|
-
|
|
11353
|
-
|
|
11354
|
-
|
|
11355
|
-
|
|
11356
|
-
|
|
11357
|
-
|
|
11358
|
-
|
|
11359
|
-
|
|
11360
|
-
|
|
11361
|
-
|
|
11362
|
-
|
|
11363
|
-
|
|
11364
|
-
|
|
11365
|
-
|
|
11366
|
-
|
|
11375
|
+
let modelWindow = MAX_VISIBLE2 - 4;
|
|
11376
|
+
let modelWindowStart = 0;
|
|
11377
|
+
let modelWindowEnd = 0;
|
|
11378
|
+
let rows = [];
|
|
11379
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
11380
|
+
modelWindowStart = Math.max(
|
|
11381
|
+
0,
|
|
11382
|
+
Math.min(
|
|
11383
|
+
safeIndex - Math.floor(modelWindow / 2),
|
|
11384
|
+
filtered.length - modelWindow
|
|
11385
|
+
)
|
|
11386
|
+
);
|
|
11387
|
+
modelWindowEnd = Math.min(modelWindowStart + modelWindow, filtered.length);
|
|
11388
|
+
rows = [];
|
|
11389
|
+
let lastGroup = "";
|
|
11390
|
+
for (let i = modelWindowStart; i < modelWindowEnd; i++) {
|
|
11391
|
+
const model = filtered[i];
|
|
11392
|
+
if (model.group !== lastGroup) {
|
|
11393
|
+
rows.push({ type: "group", label: model.group });
|
|
11394
|
+
lastGroup = model.group;
|
|
11395
|
+
}
|
|
11396
|
+
rows.push({
|
|
11397
|
+
type: "model",
|
|
11398
|
+
model,
|
|
11399
|
+
isHighlighted: i === safeIndex,
|
|
11400
|
+
isCurrent: model.value === currentModel
|
|
11401
|
+
});
|
|
11402
|
+
}
|
|
11403
|
+
if (rows.length <= MAX_VISIBLE2) break;
|
|
11404
|
+
modelWindow = Math.max(1, modelWindow - (rows.length - MAX_VISIBLE2));
|
|
11405
|
+
}
|
|
11406
|
+
while (rows.length < MAX_VISIBLE2) {
|
|
11407
|
+
rows.push({ type: "blank" });
|
|
11367
11408
|
}
|
|
11368
11409
|
const showScrollUp = modelWindowStart > 0;
|
|
11369
11410
|
const showScrollDown = modelWindowEnd < filtered.length;
|
|
@@ -11387,17 +11428,23 @@ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
|
11387
11428
|
] }),
|
|
11388
11429
|
/* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
|
|
11389
11430
|
/* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: "/ " }),
|
|
11390
|
-
/* @__PURE__ */
|
|
11391
|
-
|
|
11392
|
-
{
|
|
11393
|
-
|
|
11394
|
-
|
|
11395
|
-
|
|
11396
|
-
}
|
|
11397
|
-
)
|
|
11431
|
+
search.length > 0 ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
11432
|
+
/* @__PURE__ */ jsx19(Text19, { children: search.slice(0, cursorPos) }),
|
|
11433
|
+
/* @__PURE__ */ jsx19(Text19, { inverse: true, children: search[cursorPos] ?? " " }),
|
|
11434
|
+
cursorPos < search.length && /* @__PURE__ */ jsx19(Text19, { children: search.slice(cursorPos + 1) })
|
|
11435
|
+
] }) : /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
11436
|
+
/* @__PURE__ */ jsx19(Text19, { inverse: true, children: " " }),
|
|
11437
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: "Search models..." })
|
|
11438
|
+
] })
|
|
11398
11439
|
] }),
|
|
11399
11440
|
/* @__PURE__ */ jsx19(Box17, { height: 1, children: /* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: pad(showScrollUp ? " ..." : "") }) }),
|
|
11400
|
-
/* @__PURE__ */ jsx19(Box17, { flexDirection: "column", height: MAX_VISIBLE2, children: filtered.length === 0 ? /* @__PURE__ */
|
|
11441
|
+
/* @__PURE__ */ jsx19(Box17, { flexDirection: "column", height: MAX_VISIBLE2, children: filtered.length === 0 ? /* @__PURE__ */ jsxs16(Fragment2, { children: [
|
|
11442
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: pad(" No matching models") }),
|
|
11443
|
+
Array.from({ length: MAX_VISIBLE2 - 1 }, (_, i) => /* @__PURE__ */ jsx19(Text19, { children: pad("") }, `empty-${i}`))
|
|
11444
|
+
] }) : rows.map((row, i) => {
|
|
11445
|
+
if (row.type === "blank") {
|
|
11446
|
+
return /* @__PURE__ */ jsx19(Text19, { children: pad("") }, `blank-${i}`);
|
|
11447
|
+
}
|
|
11401
11448
|
if (row.type === "group") {
|
|
11402
11449
|
return /* @__PURE__ */ jsx19(Box17, { children: /* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, dimColor: true, children: pad(` ${row.label}`) }) }, `group-${row.label}`);
|
|
11403
11450
|
}
|
|
@@ -11423,7 +11470,7 @@ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
|
11423
11470
|
// src/ink/marathon/CommandPicker.tsx
|
|
11424
11471
|
import { useState as useState16, useMemo as useMemo8, useCallback as useCallback6 } from "react";
|
|
11425
11472
|
import { Box as Box18, Text as Text20, useInput as useInput8, useStdout as useStdout3 } from "ink";
|
|
11426
|
-
import
|
|
11473
|
+
import TextInput2 from "ink-text-input";
|
|
11427
11474
|
import { theme as theme20 } from "@runtypelabs/ink-components";
|
|
11428
11475
|
|
|
11429
11476
|
// src/ink/marathon/types.ts
|
|
@@ -11513,7 +11560,7 @@ function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
|
11513
11560
|
/* @__PURE__ */ jsxs17(Box18, { marginBottom: 1, children: [
|
|
11514
11561
|
/* @__PURE__ */ jsx20(Text20, { color: theme20.textSubtle, children: "/ " }),
|
|
11515
11562
|
/* @__PURE__ */ jsx20(
|
|
11516
|
-
|
|
11563
|
+
TextInput2,
|
|
11517
11564
|
{
|
|
11518
11565
|
value: search,
|
|
11519
11566
|
onChange: handleSearchChange,
|
|
@@ -11541,7 +11588,7 @@ function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
|
11541
11588
|
}
|
|
11542
11589
|
|
|
11543
11590
|
// src/ink/marathon/TextArea.tsx
|
|
11544
|
-
import { useState as useState17, useCallback as useCallback7, useRef as
|
|
11591
|
+
import { useState as useState17, useCallback as useCallback7, useRef as useRef7, useEffect as useEffect14, useMemo as useMemo9 } from "react";
|
|
11545
11592
|
import { Box as Box19, Text as Text21, useInput as useInput9, useStdout as useStdout4 } from "ink";
|
|
11546
11593
|
import { theme as theme21 } from "@runtypelabs/ink-components";
|
|
11547
11594
|
|
|
@@ -11633,12 +11680,12 @@ function TextArea({
|
|
|
11633
11680
|
});
|
|
11634
11681
|
const [scrollOffset, setScrollOffset] = useState17(0);
|
|
11635
11682
|
const [blinkVisible, setBlinkVisible] = useState17(true);
|
|
11636
|
-
const blinkRef =
|
|
11637
|
-
const linesRef =
|
|
11683
|
+
const blinkRef = useRef7(null);
|
|
11684
|
+
const linesRef = useRef7(lines);
|
|
11638
11685
|
linesRef.current = lines;
|
|
11639
|
-
const cursorRef =
|
|
11686
|
+
const cursorRef = useRef7(cursor);
|
|
11640
11687
|
cursorRef.current = cursor;
|
|
11641
|
-
|
|
11688
|
+
useEffect14(() => {
|
|
11642
11689
|
blinkRef.current = setInterval(() => {
|
|
11643
11690
|
setBlinkVisible((v) => !v);
|
|
11644
11691
|
}, CURSOR_BLINK_MS);
|
|
@@ -11649,10 +11696,10 @@ function TextArea({
|
|
|
11649
11696
|
}
|
|
11650
11697
|
};
|
|
11651
11698
|
}, []);
|
|
11652
|
-
|
|
11699
|
+
useEffect14(() => {
|
|
11653
11700
|
setBlinkVisible(true);
|
|
11654
11701
|
}, [lines, cursor]);
|
|
11655
|
-
|
|
11702
|
+
useEffect14(() => {
|
|
11656
11703
|
const visibleStart = scrollOffset;
|
|
11657
11704
|
const visibleEnd = scrollOffset + maxHeight - 1;
|
|
11658
11705
|
if (cursor.line < visibleStart) {
|
|
@@ -11902,7 +11949,7 @@ function CheckpointRecap({
|
|
|
11902
11949
|
historyWarning,
|
|
11903
11950
|
isTerminal
|
|
11904
11951
|
}) {
|
|
11905
|
-
const label = isTerminal ? `\u2713
|
|
11952
|
+
const label = isTerminal ? `\u2713 Run ${sessionNumber} complete` : `Run ${sessionNumber} complete`;
|
|
11906
11953
|
const separator = theme22.separator ?? " \xB7 ";
|
|
11907
11954
|
const usageSummary = [
|
|
11908
11955
|
`Tools: ${toolCallsMade}`,
|
|
@@ -11966,7 +12013,7 @@ function CheckpointPrompt({
|
|
|
11966
12013
|
const [pendingSandbox, setPendingSandbox] = useState18(void 0);
|
|
11967
12014
|
const [pendingToolsToggle, setPendingToolsToggle] = useState18(false);
|
|
11968
12015
|
const [pendingStop, setPendingStop] = useState18(false);
|
|
11969
|
-
const timerRef =
|
|
12016
|
+
const timerRef = useRef8(null);
|
|
11970
12017
|
const separator = theme23.separator ?? " \xB7 ";
|
|
11971
12018
|
const hasPendingChanges = pendingModel !== void 0 || pendingSandbox !== void 0 || pendingToolsToggle || pendingStop;
|
|
11972
12019
|
const clearInputDraft = () => {
|
|
@@ -11991,9 +12038,9 @@ function CheckpointPrompt({
|
|
|
11991
12038
|
resetDraft();
|
|
11992
12039
|
onSubmit(result);
|
|
11993
12040
|
};
|
|
11994
|
-
|
|
12041
|
+
useEffect15(() => {
|
|
11995
12042
|
const title = "Marathon";
|
|
11996
|
-
const body = isTerminal ? "Marathon complete" : `
|
|
12043
|
+
const body = isTerminal ? "Marathon complete" : `Run ${recap?.sessionNumber ?? "?"} complete`;
|
|
11997
12044
|
process.stderr.write(`\x1B]777;notify;${title};${body}\x07`);
|
|
11998
12045
|
process.stderr.write(`\x1B]9;${body}\x07`);
|
|
11999
12046
|
process.stderr.write("\x07");
|
|
@@ -12011,7 +12058,7 @@ function CheckpointPrompt({
|
|
|
12011
12058
|
setIsTyping(false);
|
|
12012
12059
|
}
|
|
12013
12060
|
};
|
|
12014
|
-
|
|
12061
|
+
useEffect15(() => {
|
|
12015
12062
|
if (shouldPauseCheckpointTimer({
|
|
12016
12063
|
isTerminal,
|
|
12017
12064
|
timeout,
|
|
@@ -12225,7 +12272,7 @@ import { theme as theme24 } from "@runtypelabs/ink-components";
|
|
|
12225
12272
|
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
12226
12273
|
var MENU_ITEMS = [
|
|
12227
12274
|
{ key: "c", label: "Copy session JSON" },
|
|
12228
|
-
{ key: "
|
|
12275
|
+
{ key: "e", label: "Open session JSON in editor" },
|
|
12229
12276
|
{ key: "f", label: "Open marathon folder in file manager" },
|
|
12230
12277
|
{ key: "d", label: "Open agent in Runtype dashboard" }
|
|
12231
12278
|
];
|
|
@@ -12247,7 +12294,7 @@ function SessionActionMenu({
|
|
|
12247
12294
|
onCopySession();
|
|
12248
12295
|
return;
|
|
12249
12296
|
}
|
|
12250
|
-
if (input === "
|
|
12297
|
+
if (input === "e" && hasStateFile) {
|
|
12251
12298
|
onOpenStateFile();
|
|
12252
12299
|
return;
|
|
12253
12300
|
}
|
|
@@ -12273,7 +12320,7 @@ function SessionActionMenu({
|
|
|
12273
12320
|
children: [
|
|
12274
12321
|
/* @__PURE__ */ jsx25(Text24, { bold: true, color: theme24.accent, children: "Session" }),
|
|
12275
12322
|
/* @__PURE__ */ jsx25(Box22, { flexDirection: "column", marginTop: 1, children: MENU_ITEMS.map((item) => {
|
|
12276
|
-
const dimmed = item.key === "
|
|
12323
|
+
const dimmed = item.key === "e" && !hasStateFile || item.key === "f" && !hasStateFile || item.key === "d" && !hasDashboard;
|
|
12277
12324
|
return /* @__PURE__ */ jsxs21(Text24, { children: [
|
|
12278
12325
|
/* @__PURE__ */ jsx25(Text24, { color: dimmed ? theme24.textSubtle : theme24.accentActive, children: ` ${item.key} ` }),
|
|
12279
12326
|
/* @__PURE__ */ jsx25(Text24, { color: dimmed ? theme24.textSubtle : theme24.textMuted, children: item.label })
|
|
@@ -12338,10 +12385,10 @@ import { Box as Box25 } from "ink";
|
|
|
12338
12385
|
import { theme as theme27 } from "@runtypelabs/ink-components";
|
|
12339
12386
|
|
|
12340
12387
|
// src/ink/marathon/ToolPanel.tsx
|
|
12341
|
-
import { useState as useState19, useEffect as
|
|
12388
|
+
import { useState as useState19, useEffect as useEffect16, useMemo as useMemo10, memo as memo3 } from "react";
|
|
12342
12389
|
import { Box as Box24, Text as Text26 } from "ink";
|
|
12343
12390
|
import { Spinner as Spinner5, theme as theme26 } from "@runtypelabs/ink-components";
|
|
12344
|
-
import { Fragment as
|
|
12391
|
+
import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
12345
12392
|
var TOOL_PANEL_TIMER_MS = 500;
|
|
12346
12393
|
function formatCharCount2(chars) {
|
|
12347
12394
|
if (chars >= 1e3) {
|
|
@@ -12402,7 +12449,7 @@ var ToolPanel = memo3(function ToolPanel2({
|
|
|
12402
12449
|
}) {
|
|
12403
12450
|
const [now, setNow] = useState19(Date.now());
|
|
12404
12451
|
const hasRunning = tools.some((t) => t.status === "running");
|
|
12405
|
-
|
|
12452
|
+
useEffect16(() => {
|
|
12406
12453
|
if (!hasRunning) return;
|
|
12407
12454
|
const interval = setInterval(() => setNow(Date.now()), TOOL_PANEL_TIMER_MS);
|
|
12408
12455
|
return () => clearInterval(interval);
|
|
@@ -12460,7 +12507,7 @@ var ToolPanel = memo3(function ToolPanel2({
|
|
|
12460
12507
|
] })
|
|
12461
12508
|
] }, tool.id);
|
|
12462
12509
|
}),
|
|
12463
|
-
visibleFiles.length > 0 && /* @__PURE__ */ jsxs23(
|
|
12510
|
+
visibleFiles.length > 0 && /* @__PURE__ */ jsxs23(Fragment3, { children: [
|
|
12464
12511
|
/* @__PURE__ */ jsxs23(Box24, { marginTop: 1, children: [
|
|
12465
12512
|
/* @__PURE__ */ jsx27(Text26, { bold: true, color: theme26.accent, children: "Files" }),
|
|
12466
12513
|
hiddenFileCount > 0 && /* @__PURE__ */ jsxs23(Text26, { color: theme26.textSubtle, children: [
|
|
@@ -12523,14 +12570,14 @@ import { StreamOutput, ErrorDisplay as ErrorDisplay3 } from "@runtypelabs/ink-co
|
|
|
12523
12570
|
import { LoadingAnimation } from "@runtypelabs/terminal-animations";
|
|
12524
12571
|
|
|
12525
12572
|
// src/ink/marathon/ThinkingIndicator.tsx
|
|
12526
|
-
import { useState as useState20, useEffect as
|
|
12573
|
+
import { useState as useState20, useEffect as useEffect17 } from "react";
|
|
12527
12574
|
import { Spinner as Spinner6, theme as theme28 } from "@runtypelabs/ink-components";
|
|
12528
12575
|
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
12529
12576
|
function ThinkingIndicator({ startedAt }) {
|
|
12530
12577
|
const [elapsed, setElapsed] = useState20(
|
|
12531
12578
|
() => startedAt ? Math.floor((Date.now() - startedAt) / 1e3) : 0
|
|
12532
12579
|
);
|
|
12533
|
-
|
|
12580
|
+
useEffect17(() => {
|
|
12534
12581
|
const start = startedAt ?? Date.now();
|
|
12535
12582
|
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
12536
12583
|
const interval = setInterval(() => {
|
|
@@ -12542,7 +12589,7 @@ function ThinkingIndicator({ startedAt }) {
|
|
|
12542
12589
|
}
|
|
12543
12590
|
|
|
12544
12591
|
// src/ink/marathon/ContextCompactionIndicator.tsx
|
|
12545
|
-
import { useEffect as
|
|
12592
|
+
import { useEffect as useEffect18, useState as useState21 } from "react";
|
|
12546
12593
|
import { Spinner as Spinner7, theme as theme29 } from "@runtypelabs/ink-components";
|
|
12547
12594
|
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
12548
12595
|
function buildCompactionLabel(compaction, elapsedSeconds) {
|
|
@@ -12560,7 +12607,7 @@ function ContextCompactionIndicator({
|
|
|
12560
12607
|
const [elapsed, setElapsed] = useState21(
|
|
12561
12608
|
() => Math.floor((Date.now() - compaction.startedAt) / 1e3)
|
|
12562
12609
|
);
|
|
12563
|
-
|
|
12610
|
+
useEffect18(() => {
|
|
12564
12611
|
const start = compaction.startedAt;
|
|
12565
12612
|
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
12566
12613
|
const interval = setInterval(() => {
|
|
@@ -12613,7 +12660,7 @@ function ReasoningBlock({
|
|
|
12613
12660
|
}
|
|
12614
12661
|
|
|
12615
12662
|
// src/ink/marathon/OverviewTranscriptPane.tsx
|
|
12616
|
-
import { Fragment as
|
|
12663
|
+
import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
12617
12664
|
var UPGRADE_BROWSE_HINT_LINES = [
|
|
12618
12665
|
"Upgrade modal dismissed.",
|
|
12619
12666
|
"Use Shift+Left/Right or 1-9 to review previous marathon runs."
|
|
@@ -12642,7 +12689,7 @@ var OverviewTranscriptPane = memo5(function OverviewTranscriptPane2({
|
|
|
12642
12689
|
return /* @__PURE__ */ jsx32(Box27, { flexGrow: 1, minHeight: contentHeight, overflow: "hidden", children: /* @__PURE__ */ jsx32(LoadingAnimation, { width: paneWidth, height: contentHeight }) });
|
|
12643
12690
|
}
|
|
12644
12691
|
const maxScroll = Math.max(0, totalLines - maxVisibleLines);
|
|
12645
|
-
return /* @__PURE__ */ jsxs25(
|
|
12692
|
+
return /* @__PURE__ */ jsxs25(Fragment4, { children: [
|
|
12646
12693
|
hasReasoning && /* @__PURE__ */ jsx32(Box27, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx32(
|
|
12647
12694
|
ReasoningBlock,
|
|
12648
12695
|
{
|
|
@@ -12958,7 +13005,7 @@ function MarathonApp({
|
|
|
12958
13005
|
const { exit } = useApp4();
|
|
12959
13006
|
const { stdout } = useStdout5();
|
|
12960
13007
|
const separator = theme31.separator ?? " \xB7 ";
|
|
12961
|
-
const checkpointResolveRef =
|
|
13008
|
+
const checkpointResolveRef = useRef9(null);
|
|
12962
13009
|
const [checkpointRecap, setCheckpointRecap] = useState22(null);
|
|
12963
13010
|
const [currentModel, setCurrentModel] = useState22(model || "default");
|
|
12964
13011
|
const [currentSandbox, setCurrentSandbox] = useState22(sandbox);
|
|
@@ -12975,7 +13022,7 @@ function MarathonApp({
|
|
|
12975
13022
|
const [previewUrl, setPreviewUrl] = useState22(initialPreviewUrl);
|
|
12976
13023
|
const [isCheckpointExploring, setIsCheckpointExploring] = useState22(false);
|
|
12977
13024
|
const isRunnerAnimating = state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool" || Boolean(state.contextCompaction?.active);
|
|
12978
|
-
const isTerminalCheckpointRef =
|
|
13025
|
+
const isTerminalCheckpointRef = useRef9(false);
|
|
12979
13026
|
const markCheckpointExploring = useCallback8(() => {
|
|
12980
13027
|
if (state.phase === "checkpoint" && checkpointRecap) {
|
|
12981
13028
|
setIsCheckpointExploring(true);
|
|
@@ -13007,7 +13054,7 @@ function MarathonApp({
|
|
|
13007
13054
|
},
|
|
13008
13055
|
[resetForNewSession]
|
|
13009
13056
|
);
|
|
13010
|
-
|
|
13057
|
+
useEffect19(() => {
|
|
13011
13058
|
streamRef.current = {
|
|
13012
13059
|
getCallbacks: () => callbacks,
|
|
13013
13060
|
getState: () => getHydratedState(),
|
|
@@ -13079,7 +13126,7 @@ function MarathonApp({
|
|
|
13079
13126
|
const isStacked = terminalWidth < STACKED_THRESHOLD;
|
|
13080
13127
|
const toolPanelWidth = terminalWidth < NARROW_THRESHOLD ? TOOL_PANEL_NARROW : TOOL_PANEL_WIDE;
|
|
13081
13128
|
const [ctrlCPressed, setCtrlCPressed] = useState22(false);
|
|
13082
|
-
const ctrlCTimeout =
|
|
13129
|
+
const ctrlCTimeout = useRef9(null);
|
|
13083
13130
|
const [activeScreen, setActiveScreen] = useState22("overview");
|
|
13084
13131
|
const showEventStream = activeScreen === "events";
|
|
13085
13132
|
const showReasoningPanel = activeScreen === "reasoning";
|
|
@@ -13109,7 +13156,7 @@ function MarathonApp({
|
|
|
13109
13156
|
const [goalExpanded, setGoalExpanded] = useState22(false);
|
|
13110
13157
|
const [upgradeModalDismissed, setUpgradeModalDismissed] = useState22(false);
|
|
13111
13158
|
const [clipboardFlash, setClipboardFlash] = useState22(null);
|
|
13112
|
-
const flashTimeout =
|
|
13159
|
+
const flashTimeout = useRef9(null);
|
|
13113
13160
|
const billingPageUrl = billingUrl || `${(dashboardUrl || "https://use.runtype.com").replace(/\/$/, "")}/settings/billing`;
|
|
13114
13161
|
function showFlash(msg) {
|
|
13115
13162
|
setClipboardFlash(msg);
|
|
@@ -13200,7 +13247,7 @@ function MarathonApp({
|
|
|
13200
13247
|
}
|
|
13201
13248
|
return snapshotEvents ?? liveRawEvents;
|
|
13202
13249
|
}, [displayedSessionSnapshot, liveRawEvents, stateFilePath2]);
|
|
13203
|
-
const seenTypesRef =
|
|
13250
|
+
const seenTypesRef = useRef9({
|
|
13204
13251
|
set: /* @__PURE__ */ new Set(),
|
|
13205
13252
|
lastLen: 0,
|
|
13206
13253
|
eventsRef: null
|
|
@@ -13222,7 +13269,7 @@ function MarathonApp({
|
|
|
13222
13269
|
}
|
|
13223
13270
|
return void 0;
|
|
13224
13271
|
}, [displayedEvents]);
|
|
13225
|
-
const stableSeenEventTypesRef =
|
|
13272
|
+
const stableSeenEventTypesRef = useRef9([]);
|
|
13226
13273
|
if (seenEventTypes !== void 0) {
|
|
13227
13274
|
stableSeenEventTypesRef.current = seenEventTypes;
|
|
13228
13275
|
}
|
|
@@ -13234,7 +13281,7 @@ function MarathonApp({
|
|
|
13234
13281
|
() => displayedTools.filter((t) => t.name === "write_file" || t.name === "read_file").map((t) => `${t.id}:${t.name}:${String(t.parameters?.path ?? "")}:${t.startedAt}`).join("|"),
|
|
13235
13282
|
[displayedTools]
|
|
13236
13283
|
);
|
|
13237
|
-
const trackedFilesCacheRef =
|
|
13284
|
+
const trackedFilesCacheRef = useRef9({
|
|
13238
13285
|
snapshots: null,
|
|
13239
13286
|
fingerprint: "",
|
|
13240
13287
|
planPath: void 0,
|
|
@@ -13248,7 +13295,7 @@ function MarathonApp({
|
|
|
13248
13295
|
trackedFilesCache.value = extractTrackedFiles(sessionSnapshots, displayedTools, planPath);
|
|
13249
13296
|
}
|
|
13250
13297
|
const trackedFiles = trackedFilesCache.value;
|
|
13251
|
-
const latestLiveActivityRef =
|
|
13298
|
+
const latestLiveActivityRef = useRef9(void 0);
|
|
13252
13299
|
const upgradePrompt = useMemo11(() => parseMarathonUpgradePrompt(state.error), [state.error]);
|
|
13253
13300
|
const upgradePromptKey = useMemo11(
|
|
13254
13301
|
() => upgradePrompt ? `${upgradePrompt.message}|${upgradePrompt.code ?? ""}|${upgradePrompt.limitType ?? ""}|${upgradePrompt.retryAfter ?? ""}` : void 0,
|
|
@@ -13279,25 +13326,25 @@ function MarathonApp({
|
|
|
13279
13326
|
},
|
|
13280
13327
|
[latestSessionKey]
|
|
13281
13328
|
);
|
|
13282
|
-
|
|
13329
|
+
useEffect19(() => {
|
|
13283
13330
|
if (!selectedSessionKey && latestSessionKey) {
|
|
13284
13331
|
setSelectedSessionKey(latestSessionKey);
|
|
13285
13332
|
}
|
|
13286
13333
|
}, [latestSessionKey, selectedSessionKey]);
|
|
13287
|
-
|
|
13334
|
+
useEffect19(() => {
|
|
13288
13335
|
if (followLatest && latestSessionKey && selectedSessionKey !== latestSessionKey) {
|
|
13289
13336
|
setSelectedSessionKey(latestSessionKey);
|
|
13290
13337
|
}
|
|
13291
13338
|
}, [followLatest, latestSessionKey, selectedSessionKey]);
|
|
13292
|
-
|
|
13339
|
+
useEffect19(() => {
|
|
13293
13340
|
if (selectedSessionKey && selectedSessionKey === latestSessionKey && latestUnreadKey) {
|
|
13294
13341
|
setLatestUnreadKey(void 0);
|
|
13295
13342
|
}
|
|
13296
13343
|
}, [latestSessionKey, latestUnreadKey, selectedSessionKey]);
|
|
13297
|
-
|
|
13344
|
+
useEffect19(() => {
|
|
13298
13345
|
setUpgradeModalDismissed(false);
|
|
13299
13346
|
}, [upgradePromptKey]);
|
|
13300
|
-
|
|
13347
|
+
useEffect19(() => {
|
|
13301
13348
|
const liveActivityKey = liveSessionSnapshot ? `${liveSessionSnapshot.sessionIndex}:${state.phase}:${state.content.length}:${state.reasoning.length}:${state.tools.length}:${rawEventsRef.current.length}` : void 0;
|
|
13302
13349
|
if (!liveActivityKey) {
|
|
13303
13350
|
latestLiveActivityRef.current = void 0;
|
|
@@ -13316,7 +13363,7 @@ function MarathonApp({
|
|
|
13316
13363
|
state.reasoning.length,
|
|
13317
13364
|
state.tools.length
|
|
13318
13365
|
]);
|
|
13319
|
-
|
|
13366
|
+
useEffect19(() => {
|
|
13320
13367
|
if (selectedIsLive || followLatest) {
|
|
13321
13368
|
const liveUrl = getActiveDeploySandboxPreviewUrl();
|
|
13322
13369
|
if (liveUrl) {
|
|
@@ -13336,14 +13383,14 @@ function MarathonApp({
|
|
|
13336
13383
|
}
|
|
13337
13384
|
setPreviewUrl(void 0);
|
|
13338
13385
|
}, [displayedTools, selectedIsLive, followLatest, state.phase]);
|
|
13339
|
-
|
|
13386
|
+
useEffect19(() => {
|
|
13340
13387
|
if (allowInitialInlineLoader) return;
|
|
13341
13388
|
const hasVisibleSessionActivity = !isBlank(state.content) || !isBlank(state.reasoning) || state.tools.length > 0 || state.error !== null;
|
|
13342
13389
|
if (hasVisibleSessionActivity) {
|
|
13343
13390
|
setAllowInitialInlineLoader(true);
|
|
13344
13391
|
}
|
|
13345
13392
|
}, [allowInitialInlineLoader, state.content, state.error, state.reasoning, state.tools.length]);
|
|
13346
|
-
|
|
13393
|
+
useEffect19(() => {
|
|
13347
13394
|
if (showToolsPanel && displayedTools.length > 0 && toolCursor === -1) {
|
|
13348
13395
|
setToolCursor(displayedTools.length - 1);
|
|
13349
13396
|
}
|
|
@@ -13753,7 +13800,7 @@ function MarathonApp({
|
|
|
13753
13800
|
return;
|
|
13754
13801
|
}
|
|
13755
13802
|
});
|
|
13756
|
-
|
|
13803
|
+
useEffect19(() => {
|
|
13757
13804
|
return () => {
|
|
13758
13805
|
if (ctrlCTimeout.current) clearTimeout(ctrlCTimeout.current);
|
|
13759
13806
|
if (flashTimeout.current) clearTimeout(flashTimeout.current);
|
|
@@ -14222,7 +14269,7 @@ function MarathonApp({
|
|
|
14222
14269
|
}
|
|
14223
14270
|
|
|
14224
14271
|
// src/ink/marathon/MarathonStartupShell.tsx
|
|
14225
|
-
import { useEffect as
|
|
14272
|
+
import { useEffect as useEffect20, useRef as useRef10, useState as useState23 } from "react";
|
|
14226
14273
|
import { Box as Box29, Text as Text29, useApp as useApp5, useInput as useInput12, useStdout as useStdout6 } from "ink";
|
|
14227
14274
|
import { theme as theme32 } from "@runtypelabs/ink-components";
|
|
14228
14275
|
import { AnimatedVariant, StartupGridIconCompactLightInverted } from "@runtypelabs/terminal-animations";
|
|
@@ -14278,14 +14325,14 @@ function MarathonStartupShell({
|
|
|
14278
14325
|
}) {
|
|
14279
14326
|
const { exit } = useApp5();
|
|
14280
14327
|
const { stdout } = useStdout6();
|
|
14281
|
-
const mountedAtRef =
|
|
14282
|
-
const promptResolverRef =
|
|
14283
|
-
const modelResolverRef =
|
|
14284
|
-
const playbookConfirmResolverRef =
|
|
14285
|
-
const appReadyResolverRef =
|
|
14286
|
-
const dismissResolverRef =
|
|
14287
|
-
const transitionPromiseRef =
|
|
14288
|
-
const latestAppPropsRef =
|
|
14328
|
+
const mountedAtRef = useRef10(Date.now());
|
|
14329
|
+
const promptResolverRef = useRef10(null);
|
|
14330
|
+
const modelResolverRef = useRef10(null);
|
|
14331
|
+
const playbookConfirmResolverRef = useRef10(null);
|
|
14332
|
+
const appReadyResolverRef = useRef10(null);
|
|
14333
|
+
const dismissResolverRef = useRef10(null);
|
|
14334
|
+
const transitionPromiseRef = useRef10(null);
|
|
14335
|
+
const latestAppPropsRef = useRef10(marathonAppProps);
|
|
14289
14336
|
const [statusMessage, setStatusMessage] = useState23("preparing marathon");
|
|
14290
14337
|
const [scene, setScene] = useState23("splash");
|
|
14291
14338
|
const [transition, setTransition] = useState23(null);
|
|
@@ -14298,7 +14345,7 @@ function MarathonStartupShell({
|
|
|
14298
14345
|
() => STARTUP_BACKGROUND_VARIANTS[Math.floor(Math.random() * STARTUP_BACKGROUND_VARIANTS.length)]
|
|
14299
14346
|
);
|
|
14300
14347
|
latestAppPropsRef.current = marathonAppProps;
|
|
14301
|
-
|
|
14348
|
+
useEffect20(() => {
|
|
14302
14349
|
if (scene !== "app" || !appReadyResolverRef.current) return;
|
|
14303
14350
|
const resolve7 = appReadyResolverRef.current;
|
|
14304
14351
|
appReadyResolverRef.current = null;
|
|
@@ -14343,7 +14390,7 @@ function MarathonStartupShell({
|
|
|
14343
14390
|
transitionPromiseRef.current = promise;
|
|
14344
14391
|
return promise;
|
|
14345
14392
|
};
|
|
14346
|
-
|
|
14393
|
+
useEffect20(() => {
|
|
14347
14394
|
startupRef.current = {
|
|
14348
14395
|
setStatus: (message) => {
|
|
14349
14396
|
setStatusMessage(message);
|
|
@@ -14509,7 +14556,8 @@ function MarathonStartupShell({
|
|
|
14509
14556
|
{
|
|
14510
14557
|
variantId: backgroundVariantId,
|
|
14511
14558
|
width: terminalWidth,
|
|
14512
|
-
height: terminalRows
|
|
14559
|
+
height: terminalRows,
|
|
14560
|
+
autoplay: !modelChoices && !playbookConfirm
|
|
14513
14561
|
}
|
|
14514
14562
|
)
|
|
14515
14563
|
}
|
|
@@ -15263,7 +15311,9 @@ function extractRunTaskResumeState(state) {
|
|
|
15263
15311
|
...sanitized.bestCandidateNeedsVerification ? { bestCandidateNeedsVerification: sanitized.bestCandidateNeedsVerification } : {},
|
|
15264
15312
|
...sanitized.bestCandidateVerified ? { bestCandidateVerified: sanitized.bestCandidateVerified } : {},
|
|
15265
15313
|
...sanitized.verificationRequired !== void 0 ? { verificationRequired: sanitized.verificationRequired } : {},
|
|
15266
|
-
...sanitized.lastVerificationPassed ? { lastVerificationPassed: sanitized.lastVerificationPassed } : {}
|
|
15314
|
+
...sanitized.lastVerificationPassed ? { lastVerificationPassed: sanitized.lastVerificationPassed } : {},
|
|
15315
|
+
...sanitized.isCreationTask !== void 0 ? { isCreationTask: sanitized.isCreationTask } : {},
|
|
15316
|
+
...sanitized.outputRoot ? { outputRoot: sanitized.outputRoot } : {}
|
|
15267
15317
|
};
|
|
15268
15318
|
}
|
|
15269
15319
|
function findStateFile(name, stateDir) {
|
|
@@ -15428,6 +15478,29 @@ var IGNORED_REPO_DIRS = /* @__PURE__ */ new Set([
|
|
|
15428
15478
|
"dist",
|
|
15429
15479
|
"node_modules"
|
|
15430
15480
|
]);
|
|
15481
|
+
var SENSITIVE_PATH_PATTERNS = [
|
|
15482
|
+
{ name: ".env", test: (n) => n === ".env" || n.endsWith("/.env") },
|
|
15483
|
+
{ name: ".env.*", test: (n) => /\.env\.?[^/]*$/.test(n) || /\/\.env\.?[^/]*$/.test(n) },
|
|
15484
|
+
{ name: "private keys", test: (n) => /(^|\/)(id_rsa|id_ed25519|id_ecdsa)(\.pub)?$/.test(n) },
|
|
15485
|
+
{ name: "known_hosts", test: (n) => n.endsWith("known_hosts") || n.endsWith("/known_hosts") },
|
|
15486
|
+
{ name: "authorized_keys", test: (n) => n.endsWith("authorized_keys") || n.endsWith("/authorized_keys") },
|
|
15487
|
+
{ name: "cert/key extensions", test: (n) => /\.(pem|key|p12|pfx)$/i.test(n) },
|
|
15488
|
+
{ name: "npm/pypi config", test: (n) => /(^|\/)(\.npmrc|\.pypirc|\.netrc)$/.test(n) },
|
|
15489
|
+
{ name: "docker config", test: (n) => /\.docker\/config\.json$/i.test(n) },
|
|
15490
|
+
{ name: "credentials", test: (n) => /(^|\/)(credentials\.json|secrets\.json)$/i.test(n) },
|
|
15491
|
+
{ name: "service account", test: (n) => /service-account.*\.json$/i.test(n) || /firebase-admin.*\.json$/i.test(n) },
|
|
15492
|
+
{ name: ".ssh", test: (n) => n === ".ssh" || n.startsWith(".ssh/") || n.includes("/.ssh/") },
|
|
15493
|
+
{ name: ".aws", test: (n) => n === ".aws" || n.startsWith(".aws/") || n.includes("/.aws/") },
|
|
15494
|
+
{ name: ".gnupg", test: (n) => n === ".gnupg" || n.startsWith(".gnupg/") || n.includes("/.gnupg/") },
|
|
15495
|
+
{ name: ".terraform", test: (n) => n === ".terraform" || n.startsWith(".terraform/") || n.includes("/.terraform/") },
|
|
15496
|
+
{ name: ".git", test: (n) => n === ".git" || n.startsWith(".git/") || n.includes("/.git/") },
|
|
15497
|
+
{ name: ".runtype", test: (n) => n === ".runtype" || n.startsWith(".runtype/") || n.includes("/.runtype/") }
|
|
15498
|
+
];
|
|
15499
|
+
function isSensitivePath(normalizedPath) {
|
|
15500
|
+
const n = normalizedPath.replace(/\\/g, "/").trim();
|
|
15501
|
+
if (!n) return false;
|
|
15502
|
+
return SENSITIVE_PATH_PATTERNS.some(({ test }) => test(n));
|
|
15503
|
+
}
|
|
15431
15504
|
var DEFAULT_DISCOVERY_MAX_RESULTS = 50;
|
|
15432
15505
|
var MAX_FILE_BYTES_TO_SCAN = 1024 * 1024;
|
|
15433
15506
|
var LOW_SIGNAL_FILE_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -15516,12 +15589,15 @@ function scoreSearchPath(relativePath) {
|
|
|
15516
15589
|
return score;
|
|
15517
15590
|
}
|
|
15518
15591
|
function shouldIgnoreRepoEntry(entryPath) {
|
|
15519
|
-
const normalized = normalizeToolPath(entryPath);
|
|
15592
|
+
const normalized = normalizeToolPath(entryPath).replace(/\\/g, "/");
|
|
15520
15593
|
if (normalized === ".") return false;
|
|
15594
|
+
if (isSensitivePath(normalized)) return true;
|
|
15521
15595
|
return normalized.split(path8.sep).some((segment) => IGNORED_REPO_DIRS.has(segment));
|
|
15522
15596
|
}
|
|
15523
15597
|
function safeReadTextFile(filePath) {
|
|
15524
15598
|
try {
|
|
15599
|
+
const normalized = normalizeToolPath(filePath).replace(/\\/g, "/");
|
|
15600
|
+
if (isSensitivePath(normalized)) return null;
|
|
15525
15601
|
const stat = fs8.statSync(filePath);
|
|
15526
15602
|
if (!stat.isFile() || stat.size > MAX_FILE_BYTES_TO_SCAN) return null;
|
|
15527
15603
|
const buffer = fs8.readFileSync(filePath);
|
|
@@ -15652,9 +15728,10 @@ function resolveToolPath(toolPath, options = {}) {
|
|
|
15652
15728
|
return { ok: false, error: `Path does not exist: ${requestedPath}` };
|
|
15653
15729
|
}
|
|
15654
15730
|
const workspaceRoot = fs9.realpathSync.native(process.cwd());
|
|
15731
|
+
const extraRoots = (options.allowedRoots || []).map((rootPath) => canonicalizeAllowedRoot(rootPath));
|
|
15655
15732
|
const allowedRoots = [
|
|
15656
|
-
|
|
15657
|
-
|
|
15733
|
+
...extraRoots,
|
|
15734
|
+
workspaceRoot
|
|
15658
15735
|
];
|
|
15659
15736
|
const matchedRoot = allowedRoots.find(
|
|
15660
15737
|
(rootPath) => isPathWithinRoot(resolved.canonicalPath, rootPath)
|
|
@@ -15673,6 +15750,13 @@ function resolveToolPath(toolPath, options = {}) {
|
|
|
15673
15750
|
error: `Access denied: ${requestedPath} is inside restricted workspace state (${blockedSegment})`
|
|
15674
15751
|
};
|
|
15675
15752
|
}
|
|
15753
|
+
const relativeFromWorkspace = path9.relative(workspaceRoot, resolved.canonicalPath).replace(/\\/g, "/");
|
|
15754
|
+
if (isSensitivePath(relativeFromWorkspace)) {
|
|
15755
|
+
return {
|
|
15756
|
+
ok: false,
|
|
15757
|
+
error: `Access denied: ${requestedPath} is a sensitive path and cannot be read or written`
|
|
15758
|
+
};
|
|
15759
|
+
}
|
|
15676
15760
|
}
|
|
15677
15761
|
if (resolved.exists) {
|
|
15678
15762
|
const stat = fs9.statSync(resolved.canonicalPath);
|
|
@@ -15693,8 +15777,17 @@ function resolveToolPath(toolPath, options = {}) {
|
|
|
15693
15777
|
}
|
|
15694
15778
|
return { ok: true, resolvedPath: resolved.canonicalPath };
|
|
15695
15779
|
}
|
|
15780
|
+
function getTaskStateRoot(taskName, stateDir) {
|
|
15781
|
+
return path9.join(stateDir || getMarathonStateDir(), stateSafeName3(taskName));
|
|
15782
|
+
}
|
|
15696
15783
|
function createDefaultLocalTools(context) {
|
|
15697
|
-
const
|
|
15784
|
+
const taskStateRoot = context?.taskName ? getTaskStateRoot(context.taskName, context.stateDir) : void 0;
|
|
15785
|
+
const planDir = context?.taskName ? path9.resolve(`.runtype/marathons/${stateSafeName3(context.taskName)}`) : void 0;
|
|
15786
|
+
const allowedReadRoots = context?.taskName ? [
|
|
15787
|
+
getOffloadedOutputDir(context.taskName, context.stateDir),
|
|
15788
|
+
...taskStateRoot ? [taskStateRoot] : [],
|
|
15789
|
+
...planDir ? [planDir] : []
|
|
15790
|
+
] : [];
|
|
15698
15791
|
return {
|
|
15699
15792
|
read_file: {
|
|
15700
15793
|
description: "Read the contents of a file at the given path",
|
|
@@ -15896,6 +15989,8 @@ function createDefaultLocalTools(context) {
|
|
|
15896
15989
|
};
|
|
15897
15990
|
}
|
|
15898
15991
|
function createCheckpointedWriteFileTool(taskName, stateDir) {
|
|
15992
|
+
const taskStateRoot = getTaskStateRoot(taskName, stateDir);
|
|
15993
|
+
const planDir = path9.resolve(`.runtype/marathons/${stateSafeName3(taskName)}`);
|
|
15899
15994
|
return {
|
|
15900
15995
|
description: "Write content to a file, creating directories as needed and checkpointing original repo files",
|
|
15901
15996
|
parametersSchema: {
|
|
@@ -15908,7 +16003,8 @@ function createCheckpointedWriteFileTool(taskName, stateDir) {
|
|
|
15908
16003
|
},
|
|
15909
16004
|
execute: async (args) => {
|
|
15910
16005
|
const resolvedPath = resolveToolPath(String(args.path || ""), {
|
|
15911
|
-
allowMissing: true
|
|
16006
|
+
allowMissing: true,
|
|
16007
|
+
allowedRoots: [taskStateRoot, planDir]
|
|
15912
16008
|
});
|
|
15913
16009
|
if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
|
|
15914
16010
|
const content = String(args.content || "");
|
|
@@ -15999,6 +16095,7 @@ function createRunCheckTool() {
|
|
|
15999
16095
|
if (!isSafeVerificationCommand(command)) {
|
|
16000
16096
|
return JSON.stringify({
|
|
16001
16097
|
success: false,
|
|
16098
|
+
blocked: true,
|
|
16002
16099
|
command,
|
|
16003
16100
|
error: "Blocked unsafe verification command. Use a single non-destructive lint/test/typecheck/build command."
|
|
16004
16101
|
});
|
|
@@ -16414,12 +16511,46 @@ function resolveModelForPhase(phase, cliOverrides, milestoneModels) {
|
|
|
16414
16511
|
}
|
|
16415
16512
|
return cliOverrides.defaultModel;
|
|
16416
16513
|
}
|
|
16514
|
+
function resolveErrorHandlingForPhase(phase, cliFallbackModel, milestoneFallbackModels) {
|
|
16515
|
+
const phaseFallbacks = phase ? milestoneFallbackModels?.[phase] : void 0;
|
|
16516
|
+
if (phaseFallbacks?.length) {
|
|
16517
|
+
return {
|
|
16518
|
+
onError: "fallback",
|
|
16519
|
+
fallbacks: [
|
|
16520
|
+
{ type: "retry", delay: 5e3 },
|
|
16521
|
+
...phaseFallbacks.map((fb) => ({
|
|
16522
|
+
type: "model",
|
|
16523
|
+
model: fb.model,
|
|
16524
|
+
...fb.temperature !== void 0 ? { temperature: fb.temperature } : {},
|
|
16525
|
+
...fb.maxTokens !== void 0 ? { maxTokens: fb.maxTokens } : {}
|
|
16526
|
+
}))
|
|
16527
|
+
]
|
|
16528
|
+
};
|
|
16529
|
+
}
|
|
16530
|
+
if (cliFallbackModel) {
|
|
16531
|
+
return {
|
|
16532
|
+
onError: "fallback",
|
|
16533
|
+
fallbacks: [
|
|
16534
|
+
{ type: "retry", delay: 5e3 },
|
|
16535
|
+
{ type: "model", model: cliFallbackModel }
|
|
16536
|
+
]
|
|
16537
|
+
};
|
|
16538
|
+
}
|
|
16539
|
+
return void 0;
|
|
16540
|
+
}
|
|
16417
16541
|
|
|
16418
16542
|
// src/marathon/playbook-loader.ts
|
|
16419
16543
|
import * as fs12 from "fs";
|
|
16420
16544
|
import * as path12 from "path";
|
|
16421
16545
|
import * as os4 from "os";
|
|
16546
|
+
import micromatch from "micromatch";
|
|
16422
16547
|
import { parse as parseYaml } from "yaml";
|
|
16548
|
+
var DISCOVERY_TOOLS = /* @__PURE__ */ new Set([
|
|
16549
|
+
"search_repo",
|
|
16550
|
+
"glob_files",
|
|
16551
|
+
"tree_directory",
|
|
16552
|
+
"list_directory"
|
|
16553
|
+
]);
|
|
16423
16554
|
var PLAYBOOKS_DIR = ".runtype/marathons/playbooks";
|
|
16424
16555
|
function getCandidatePaths(nameOrPath, cwd) {
|
|
16425
16556
|
const home = os4.homedir();
|
|
@@ -16494,7 +16625,54 @@ function buildIsComplete(criteria) {
|
|
|
16494
16625
|
return () => false;
|
|
16495
16626
|
}
|
|
16496
16627
|
}
|
|
16628
|
+
function buildPolicyIntercept(policy) {
|
|
16629
|
+
if (!policy.blockedTools?.length && !policy.blockDiscoveryTools && !policy.allowedReadGlobs?.length && !policy.allowedWriteGlobs?.length && !policy.requirePlanBeforeWrite) {
|
|
16630
|
+
return void 0;
|
|
16631
|
+
}
|
|
16632
|
+
const blockedSet = new Set(
|
|
16633
|
+
(policy.blockedTools ?? []).map((t) => t.trim()).filter(Boolean)
|
|
16634
|
+
);
|
|
16635
|
+
const readGlobs = policy.allowedReadGlobs ?? [];
|
|
16636
|
+
const writeGlobs = policy.allowedWriteGlobs ?? [];
|
|
16637
|
+
return (toolName, args, ctx) => {
|
|
16638
|
+
if (blockedSet.has(toolName)) {
|
|
16639
|
+
return `Blocked by playbook policy: ${toolName} is not allowed for this task.`;
|
|
16640
|
+
}
|
|
16641
|
+
if (policy.blockDiscoveryTools && DISCOVERY_TOOLS.has(toolName)) {
|
|
16642
|
+
return `Blocked by playbook policy: discovery tools are disabled for this task.`;
|
|
16643
|
+
}
|
|
16644
|
+
const pathArg = typeof args.path === "string" && args.path.trim() ? ctx.normalizePath(String(args.path)) : void 0;
|
|
16645
|
+
if (pathArg) {
|
|
16646
|
+
const isWrite = toolName === "write_file" || toolName === "restore_file_checkpoint";
|
|
16647
|
+
const isRead = toolName === "read_file";
|
|
16648
|
+
if (isRead && readGlobs.length > 0) {
|
|
16649
|
+
const allowed = micromatch.some(pathArg, readGlobs, { dot: true });
|
|
16650
|
+
if (!allowed) {
|
|
16651
|
+
return `Blocked by playbook policy: ${toolName} path "${pathArg}" is outside allowed read globs: ${readGlobs.join(", ")}`;
|
|
16652
|
+
}
|
|
16653
|
+
}
|
|
16654
|
+
if (isWrite && writeGlobs.length > 0) {
|
|
16655
|
+
const planPath = ctx.state.planPath ? ctx.normalizePath(ctx.state.planPath) : void 0;
|
|
16656
|
+
if (planPath && pathArg === planPath) {
|
|
16657
|
+
} else {
|
|
16658
|
+
const allowed = micromatch.some(pathArg, writeGlobs, { dot: true });
|
|
16659
|
+
if (!allowed) {
|
|
16660
|
+
return `Blocked by playbook policy: ${toolName} path "${pathArg}" is outside allowed write globs: ${writeGlobs.join(", ")}`;
|
|
16661
|
+
}
|
|
16662
|
+
}
|
|
16663
|
+
}
|
|
16664
|
+
if (isWrite && policy.requirePlanBeforeWrite && !ctx.state.planWritten && !ctx.trace.planWritten) {
|
|
16665
|
+
const planPath = ctx.state.planPath ? ctx.normalizePath(ctx.state.planPath) : void 0;
|
|
16666
|
+
if (!planPath || pathArg !== planPath) {
|
|
16667
|
+
return `Blocked by playbook policy: write the plan before creating other files.`;
|
|
16668
|
+
}
|
|
16669
|
+
}
|
|
16670
|
+
}
|
|
16671
|
+
return void 0;
|
|
16672
|
+
};
|
|
16673
|
+
}
|
|
16497
16674
|
function convertToWorkflow(config2) {
|
|
16675
|
+
const policyIntercept = config2.policy ? buildPolicyIntercept(config2.policy) : void 0;
|
|
16498
16676
|
const phases = config2.milestones.map((milestone) => ({
|
|
16499
16677
|
name: milestone.name,
|
|
16500
16678
|
description: milestone.description,
|
|
@@ -16510,6 +16688,7 @@ ${instructions}`;
|
|
|
16510
16688
|
return milestone.toolGuidance ?? [];
|
|
16511
16689
|
},
|
|
16512
16690
|
isComplete: buildIsComplete(milestone.completionCriteria),
|
|
16691
|
+
interceptToolCall: policyIntercept,
|
|
16513
16692
|
// Default to rejecting TASK_COMPLETE unless the playbook explicitly allows it.
|
|
16514
16693
|
// The SDK accepts completion by default when canAcceptCompletion is undefined,
|
|
16515
16694
|
// which would let the model end the marathon prematurely in early phases.
|
|
@@ -16520,23 +16699,37 @@ ${instructions}`;
|
|
|
16520
16699
|
phases
|
|
16521
16700
|
};
|
|
16522
16701
|
}
|
|
16702
|
+
function normalizeFallbackModel(input) {
|
|
16703
|
+
if (typeof input === "string") return { model: input };
|
|
16704
|
+
return {
|
|
16705
|
+
model: input.model,
|
|
16706
|
+
...input.temperature !== void 0 ? { temperature: input.temperature } : {},
|
|
16707
|
+
...input.maxTokens !== void 0 ? { maxTokens: input.maxTokens } : {}
|
|
16708
|
+
};
|
|
16709
|
+
}
|
|
16523
16710
|
function loadPlaybook(nameOrPath, cwd) {
|
|
16524
16711
|
const baseCwd = cwd || process.cwd();
|
|
16525
16712
|
const candidates = getCandidatePaths(nameOrPath, baseCwd);
|
|
16526
16713
|
for (const candidate of candidates) {
|
|
16527
|
-
if (!fs12.existsSync(candidate)) continue;
|
|
16714
|
+
if (!fs12.existsSync(candidate) || fs12.statSync(candidate).isDirectory()) continue;
|
|
16528
16715
|
const config2 = parsePlaybookFile(candidate);
|
|
16529
16716
|
validatePlaybook(config2, candidate);
|
|
16530
16717
|
const milestoneModels = {};
|
|
16718
|
+
const milestoneFallbackModels = {};
|
|
16531
16719
|
for (const m of config2.milestones) {
|
|
16532
16720
|
if (m.model) milestoneModels[m.name] = m.model;
|
|
16721
|
+
if (m.fallbackModels?.length) {
|
|
16722
|
+
milestoneFallbackModels[m.name] = m.fallbackModels.map(normalizeFallbackModel);
|
|
16723
|
+
}
|
|
16533
16724
|
}
|
|
16534
16725
|
return {
|
|
16535
16726
|
workflow: convertToWorkflow(config2),
|
|
16536
16727
|
milestones: config2.milestones.map((m) => m.name),
|
|
16537
16728
|
milestoneModels: Object.keys(milestoneModels).length > 0 ? milestoneModels : void 0,
|
|
16729
|
+
milestoneFallbackModels: Object.keys(milestoneFallbackModels).length > 0 ? milestoneFallbackModels : void 0,
|
|
16538
16730
|
verification: config2.verification,
|
|
16539
|
-
rules: config2.rules
|
|
16731
|
+
rules: config2.rules,
|
|
16732
|
+
policy: config2.policy
|
|
16540
16733
|
};
|
|
16541
16734
|
}
|
|
16542
16735
|
throw new Error(
|
|
@@ -16564,7 +16757,7 @@ function shouldRequestResumeCheckpoint(status, resumeMessage, noCheckpoint, orig
|
|
|
16564
16757
|
return false;
|
|
16565
16758
|
}
|
|
16566
16759
|
function buildResumeCheckpointRecap(state, snapshots) {
|
|
16567
|
-
const
|
|
16760
|
+
const totalToolCalls = snapshots.reduce((sum, s) => sum + s.tools.length, 0);
|
|
16568
16761
|
const derivedTokens = state.sessions?.reduce(
|
|
16569
16762
|
(totals, session) => ({
|
|
16570
16763
|
input: totals.input + (session.totalTokens?.input ?? 0),
|
|
@@ -16575,7 +16768,7 @@ function buildResumeCheckpointRecap(state, snapshots) {
|
|
|
16575
16768
|
const resumeTokens = state.totalTokens ?? derivedTokens;
|
|
16576
16769
|
return {
|
|
16577
16770
|
sessionNumber: state.sessionCount,
|
|
16578
|
-
toolCallsMade:
|
|
16771
|
+
toolCallsMade: totalToolCalls,
|
|
16579
16772
|
tokensInput: resumeTokens.input,
|
|
16580
16773
|
tokensOutput: resumeTokens.output,
|
|
16581
16774
|
cost: state.totalCost,
|
|
@@ -16701,13 +16894,22 @@ function normalizeMarathonAgentArgument(agent) {
|
|
|
16701
16894
|
function buildMarathonAutoCreatedAgentBootstrap(agentName, options = {}) {
|
|
16702
16895
|
const normalizedModel = options.model?.trim();
|
|
16703
16896
|
const normalizedToolIds = [...new Set((options.toolIds || []).map((toolId) => toolId.trim()).filter(Boolean))];
|
|
16704
|
-
const
|
|
16897
|
+
const normalizedFallbackModel = options.fallbackModel?.trim();
|
|
16898
|
+
const errorHandling = normalizedFallbackModel ? {
|
|
16899
|
+
onError: "fallback",
|
|
16900
|
+
fallbacks: [
|
|
16901
|
+
{ type: "retry", delay: 5e3 },
|
|
16902
|
+
{ type: "model", model: normalizedFallbackModel }
|
|
16903
|
+
]
|
|
16904
|
+
} : void 0;
|
|
16905
|
+
const config2 = normalizedModel || normalizedToolIds.length > 0 || errorHandling ? {
|
|
16705
16906
|
...normalizedModel ? { model: normalizedModel } : {},
|
|
16706
16907
|
...normalizedToolIds.length > 0 ? {
|
|
16707
16908
|
tools: {
|
|
16708
16909
|
toolIds: normalizedToolIds
|
|
16709
16910
|
}
|
|
16710
|
-
} : {}
|
|
16911
|
+
} : {},
|
|
16912
|
+
...errorHandling ? { errorHandling } : {}
|
|
16711
16913
|
} : void 0;
|
|
16712
16914
|
return {
|
|
16713
16915
|
description: `Powering a marathon for ${agentName}`,
|
|
@@ -17061,11 +17263,17 @@ async function taskAction(agent, options) {
|
|
|
17061
17263
|
let playbookWorkflow;
|
|
17062
17264
|
let playbookMilestones;
|
|
17063
17265
|
let playbookMilestoneModels;
|
|
17266
|
+
let playbookMilestoneFallbackModels;
|
|
17267
|
+
let playbookPolicy;
|
|
17064
17268
|
if (options.playbook) {
|
|
17065
17269
|
const result = loadPlaybook(options.playbook);
|
|
17066
17270
|
playbookWorkflow = result.workflow;
|
|
17067
17271
|
playbookMilestones = result.milestones;
|
|
17068
17272
|
playbookMilestoneModels = result.milestoneModels;
|
|
17273
|
+
playbookMilestoneFallbackModels = result.milestoneFallbackModels;
|
|
17274
|
+
playbookPolicy = result.policy;
|
|
17275
|
+
} else {
|
|
17276
|
+
playbookPolicy = void 0;
|
|
17069
17277
|
}
|
|
17070
17278
|
if (useStartupShell && !options.model?.trim()) {
|
|
17071
17279
|
if (playbookMilestoneModels && Object.keys(playbookMilestoneModels).length > 0 && startupShellRef.current) {
|
|
@@ -17166,7 +17374,8 @@ ${rulesContext}`;
|
|
|
17166
17374
|
if (autoCreatedAgent) {
|
|
17167
17375
|
const bootstrapPayload = buildMarathonAutoCreatedAgentBootstrap(normalizedAgent, {
|
|
17168
17376
|
model: options.model || agentConfigModel || defaultConfiguredModel,
|
|
17169
|
-
toolIds: resolvedToolIds
|
|
17377
|
+
toolIds: resolvedToolIds,
|
|
17378
|
+
fallbackModel: options.fallbackModel
|
|
17170
17379
|
});
|
|
17171
17380
|
try {
|
|
17172
17381
|
await client.agents.update(agentId, bootstrapPayload);
|
|
@@ -17182,6 +17391,16 @@ ${rulesContext}`;
|
|
|
17182
17391
|
);
|
|
17183
17392
|
}
|
|
17184
17393
|
}
|
|
17394
|
+
} else if (options.fallbackModel || playbookMilestoneFallbackModels) {
|
|
17395
|
+
const initialErrorHandling = resolveErrorHandlingForPhase(
|
|
17396
|
+
currentPhase,
|
|
17397
|
+
options.fallbackModel,
|
|
17398
|
+
playbookMilestoneFallbackModels
|
|
17399
|
+
);
|
|
17400
|
+
if (initialErrorHandling) {
|
|
17401
|
+
await client.agents.update(agentId, { config: { errorHandling: initialErrorHandling } }).catch(() => {
|
|
17402
|
+
});
|
|
17403
|
+
}
|
|
17185
17404
|
}
|
|
17186
17405
|
let localTools = buildLocalTools(client, parsedSandbox, options, {
|
|
17187
17406
|
taskName,
|
|
@@ -17390,6 +17609,7 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17390
17609
|
let accumulatedSessions = 0;
|
|
17391
17610
|
let accumulatedCost = 0;
|
|
17392
17611
|
let accumulatedTokens = { input: 0, output: 0 };
|
|
17612
|
+
let accumulatedToolCalls = 0;
|
|
17393
17613
|
let lastResult = null;
|
|
17394
17614
|
let lastSessionMessages = [];
|
|
17395
17615
|
if (resumeLoadedState) {
|
|
@@ -17441,6 +17661,7 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17441
17661
|
maxSessions: remainingSessions - accumulatedSessions,
|
|
17442
17662
|
maxCost: currentRemainingCost,
|
|
17443
17663
|
model: phaseModel || options.model,
|
|
17664
|
+
reasoning: !options.noReasoning,
|
|
17444
17665
|
debugMode: options.debug ?? true,
|
|
17445
17666
|
stream: true,
|
|
17446
17667
|
streamCallbacks: currentStreamCallbacks,
|
|
@@ -17482,7 +17703,13 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17482
17703
|
model: event.model || effectiveModelForContext
|
|
17483
17704
|
});
|
|
17484
17705
|
},
|
|
17485
|
-
...resumeState
|
|
17706
|
+
...resumeState || playbookPolicy ? {
|
|
17707
|
+
resumeState: {
|
|
17708
|
+
...resumeState ?? {},
|
|
17709
|
+
...playbookPolicy?.outputRoot ? { outputRoot: playbookPolicy.outputRoot } : {},
|
|
17710
|
+
...playbookPolicy?.requireVerification !== void 0 ? { verificationRequired: playbookPolicy.requireVerification } : {}
|
|
17711
|
+
}
|
|
17712
|
+
} : {},
|
|
17486
17713
|
toolContextMode: options.toolContext || "hot-tail",
|
|
17487
17714
|
toolWindow: options.toolWindow === "session" || !options.toolWindow ? "session" : parseInt(options.toolWindow, 10) || 10,
|
|
17488
17715
|
onSession: async (state) => {
|
|
@@ -17544,12 +17771,32 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17544
17771
|
options.model = newPhaseModel;
|
|
17545
17772
|
modelChangedOnPhaseTransition = true;
|
|
17546
17773
|
}
|
|
17774
|
+
if (options.fallbackModel || playbookMilestoneFallbackModels) {
|
|
17775
|
+
const newErrorHandling = resolveErrorHandlingForPhase(
|
|
17776
|
+
resumeState.workflowPhase,
|
|
17777
|
+
options.fallbackModel,
|
|
17778
|
+
playbookMilestoneFallbackModels
|
|
17779
|
+
);
|
|
17780
|
+
client.agents.update(agentId, {
|
|
17781
|
+
config: { errorHandling: newErrorHandling ?? null }
|
|
17782
|
+
}).catch(() => {
|
|
17783
|
+
});
|
|
17784
|
+
}
|
|
17547
17785
|
}
|
|
17548
17786
|
if (state.recentActionKeys && state.recentActionKeys.length > 0) {
|
|
17549
17787
|
for (const key of state.recentActionKeys) {
|
|
17550
17788
|
loopDetector.recordAction(key);
|
|
17551
17789
|
}
|
|
17552
17790
|
}
|
|
17791
|
+
if (loopDetector.isLooping() && state.status === "running") {
|
|
17792
|
+
const checkpointMsg = loopDetector.getCheckpointMessage();
|
|
17793
|
+
loopDetector.reset();
|
|
17794
|
+
taskMessage = checkpointMsg;
|
|
17795
|
+
continuationMessage = checkpointMsg;
|
|
17796
|
+
useCompact = false;
|
|
17797
|
+
shouldContinue = true;
|
|
17798
|
+
return false;
|
|
17799
|
+
}
|
|
17553
17800
|
if (modelChangedOnPhaseTransition) {
|
|
17554
17801
|
shouldContinue = true;
|
|
17555
17802
|
return false;
|
|
@@ -17559,10 +17806,10 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17559
17806
|
if (!currentActions) return;
|
|
17560
17807
|
const recap = {
|
|
17561
17808
|
sessionNumber: adjustedState.sessionCount,
|
|
17562
|
-
toolCallsMade: currentActions.getState().tools.length,
|
|
17563
|
-
tokensInput: state.totalTokens?.input ?? 0,
|
|
17564
|
-
tokensOutput: state.totalTokens?.output ?? 0,
|
|
17565
|
-
cost:
|
|
17809
|
+
toolCallsMade: accumulatedToolCalls + currentActions.getState().tools.length,
|
|
17810
|
+
tokensInput: accumulatedTokens.input + (state.totalTokens?.input ?? 0),
|
|
17811
|
+
tokensOutput: accumulatedTokens.output + (state.totalTokens?.output ?? 0),
|
|
17812
|
+
cost: adjustedState.totalCost,
|
|
17566
17813
|
outputPreview: adjustedState.lastOutput.slice(0, 100)
|
|
17567
17814
|
};
|
|
17568
17815
|
const checkpointResult = await currentActions.requestCheckpoint(recap);
|
|
@@ -17645,6 +17892,7 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17645
17892
|
output: accumulatedTokens.output + result2.totalTokens.output
|
|
17646
17893
|
};
|
|
17647
17894
|
}
|
|
17895
|
+
accumulatedToolCalls += streamRef.current?.getState().tools.length ?? 0;
|
|
17648
17896
|
lastResult = result2;
|
|
17649
17897
|
if (result2.status === "complete") {
|
|
17650
17898
|
streamRef.current?.updateMilestone("complete");
|
|
@@ -17665,7 +17913,7 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
17665
17913
|
const terminalPreview = knownState2?.lastOutput ?? currentActions.getState().content;
|
|
17666
17914
|
const recap = {
|
|
17667
17915
|
sessionNumber: priorSessionCount + accumulatedSessions,
|
|
17668
|
-
toolCallsMade:
|
|
17916
|
+
toolCallsMade: accumulatedToolCalls,
|
|
17669
17917
|
tokensInput: accumulatedTokens.input,
|
|
17670
17918
|
tokensOutput: accumulatedTokens.output,
|
|
17671
17919
|
cost: accumulatedCost,
|
|
@@ -17879,7 +18127,7 @@ ${details}`);
|
|
|
17879
18127
|
}
|
|
17880
18128
|
return resolved;
|
|
17881
18129
|
}
|
|
17882
|
-
function
|
|
18130
|
+
function detectDeployWorkflow(_message, sandboxProvider, resumeState) {
|
|
17883
18131
|
if (resumeState?.workflowVariant === "game") return gameWorkflow;
|
|
17884
18132
|
if (resumeState?.workflowPhase === "design" || resumeState?.workflowPhase === "build" || resumeState?.workflowPhase === "verify") {
|
|
17885
18133
|
return gameWorkflow;
|
|
@@ -17888,52 +18136,6 @@ function detectSandboxWorkflow(message, resumeState) {
|
|
|
17888
18136
|
if (resumeState?.workflowPhase === "scaffold" || resumeState?.workflowPhase === "deploy") {
|
|
17889
18137
|
return deployWorkflow;
|
|
17890
18138
|
}
|
|
17891
|
-
const lower = message.toLowerCase();
|
|
17892
|
-
const gamePatterns = [
|
|
17893
|
-
/\b3d\b.*\bgame\b/,
|
|
17894
|
-
/\bgame\b.*\b3d\b/,
|
|
17895
|
-
/\bthree\.?js\b/,
|
|
17896
|
-
/\bphaser\b/,
|
|
17897
|
-
/\bwebgl\b/,
|
|
17898
|
-
/\bplatformer\b/,
|
|
17899
|
-
/\bracing\b.*\bgame\b/,
|
|
17900
|
-
/\bgame\b.*\bracing\b/,
|
|
17901
|
-
/\bgame\b/
|
|
17902
|
-
];
|
|
17903
|
-
if (gamePatterns.some((p) => p.test(lower))) {
|
|
17904
|
-
return gameWorkflow;
|
|
17905
|
-
}
|
|
17906
|
-
const deployPatterns = [
|
|
17907
|
-
/\bdeploy\b/,
|
|
17908
|
-
/\bsandbox\b/,
|
|
17909
|
-
/\bpreview\s*url\b/,
|
|
17910
|
-
/\blive\s*preview\b/,
|
|
17911
|
-
/\bhost(?:ed|ing)?\b.*\b(?:app|server|api|site)\b/,
|
|
17912
|
-
/\b(?:app|server|api|site)\b.*\bhost(?:ed|ing)?\b/,
|
|
17913
|
-
/\b(?:run|launch|start)\b.*\b(?:app|server|api|site|web\s*app|web\s*server)\b/,
|
|
17914
|
-
/\bnpx\s+serve\b/,
|
|
17915
|
-
/\bserve(?:d|s|ing)?\b.*\b(?:app|site|preview|route|routes|localhost|url|urls)\b/,
|
|
17916
|
-
/\b(?:route|routes|preview|localhost|url|urls)\b.*\bserve(?:d|s|ing)?\b/,
|
|
17917
|
-
/\bverify\b.*\b(?:route|routes|preview|localhost|url|urls)\b/,
|
|
17918
|
-
/\bmulti[-\s]route\b/,
|
|
17919
|
-
/\b(?:serve|start|run|listen)\b.{0,40}\bport\s*\d{2,5}\b/,
|
|
17920
|
-
/\bport\s*\d{2,5}\b.{0,40}\b(?:serve|server|preview|localhost|route|routes)\b/
|
|
17921
|
-
];
|
|
17922
|
-
if (deployPatterns.some((p) => p.test(lower))) {
|
|
17923
|
-
return deployWorkflow;
|
|
17924
|
-
}
|
|
17925
|
-
const webAppPatterns = [
|
|
17926
|
-
/\bbuild\b.*\b(?:web\s*app|website|api|server|express|hono|fastify)\b/,
|
|
17927
|
-
/\bcreate\b.*\b(?:web\s*app|website|api|server|express|hono|fastify)\b/,
|
|
17928
|
-
/\bmake\b.*\b(?:web\s*app|website|api|server|express|hono|fastify)\b/
|
|
17929
|
-
];
|
|
17930
|
-
const repoEditPatterns = [
|
|
17931
|
-
/\b(?:edit|modify|update|fix|refactor|change|patch|rename|remove)\b.*\b(?:file|files|repo|repository|codebase|project|directory|folder|component|module|page|route|router)\b/,
|
|
17932
|
-
/\b(?:file|files|repo|repository|codebase|project|directory|folder|component|module|page|route|router)\b.*\b(?:edit|modify|update|fix|refactor|change|patch|rename|remove)\b/
|
|
17933
|
-
];
|
|
17934
|
-
if (webAppPatterns.some((p) => p.test(lower)) && !repoEditPatterns.some((p) => p.test(lower))) {
|
|
17935
|
-
return deployWorkflow;
|
|
17936
|
-
}
|
|
17937
18139
|
return void 0;
|
|
17938
18140
|
}
|
|
17939
18141
|
function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState) {
|
|
@@ -17943,7 +18145,7 @@ function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState)
|
|
|
17943
18145
|
sandboxProvider
|
|
17944
18146
|
};
|
|
17945
18147
|
}
|
|
17946
|
-
const workflow =
|
|
18148
|
+
const workflow = detectDeployWorkflow(message, sandboxProvider, resumeState);
|
|
17947
18149
|
if (!workflow) {
|
|
17948
18150
|
return {
|
|
17949
18151
|
workflow: void 0,
|
|
@@ -17956,7 +18158,7 @@ function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState)
|
|
|
17956
18158
|
};
|
|
17957
18159
|
}
|
|
17958
18160
|
function applyTaskOptions(cmd) {
|
|
17959
|
-
return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option("--state-dir <path>", "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)").option("--resume [message]", "Resume from existing local state, optionally with a new message").option("--fresh", "Start a new run and ignore any existing local state for this task").option("--compact", "Force compact-summary resume mode instead of replaying full history").option("--compact-strategy <strategy>", "Compaction strategy: auto (default), provider_native, or summary_fallback").option("--compact-threshold <value>", "Auto-compact when estimated context crosses this threshold (default: 80% fallback, 90% native; accepts percent like 90% or absolute token count like 120000)").option("--compact-instructions <text>", "Extra instructions for what a compact summary must preserve").option("--no-auto-compact", "Disable automatic context-aware history compaction").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").option("--sandbox <provider>", "Enable sandbox code execution tool (cloudflare-worker, quickjs, or daytona)").option("--no-local-tools", "Disable built-in local tool execution (read_file, write_file, list_directory)").option("-t, --tools <tools...>", "Enable built-in tools (e.g., exa, firecrawl, dalle, openai_web_search, anthropic_web_search)").option("--plain-text", "Disable markdown rendering in output").option("--no-checkpoint", "Run all iterations without checkpoint pauses (fully autonomous)").option("--checkpoint-timeout <seconds>", "Auto-continue timeout in seconds (default: 10)", "10").option("--planning-model <modelId>", "Model to use during research/planning phases").option("--execution-model <modelId>", "Model to use during execution phase").option("--playbook <name>", "Load a playbook from .runtype/marathons/playbooks/").option("--offload-threshold <chars>", 'Offload tool outputs larger than this to files (default: 100000; use "off" or "0" to disable guardrails)').option("--tool-context <mode>", "Tool result storage: hot-tail (default), observation-mask, or full-inline").option("--tool-window <window>", 'Compaction window: "session" (default) or a number for last-N tool results (e.g. 10)').option("--runner-char <char>", "Custom runner emoji (default: \u{1F3C3})").option("--finish-char <char>", "Custom finish line emoji (default: \u{1F3C1})").option("--no-runner", "Hide the runner emoji from the header border").option("--no-finish", "Hide the finish line emoji from the header border").action(taskAction);
|
|
18161
|
+
return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option("--state-dir <path>", "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)").option("--resume [message]", "Resume from existing local state, optionally with a new message").option("--fresh", "Start a new run and ignore any existing local state for this task").option("--compact", "Force compact-summary resume mode instead of replaying full history").option("--compact-strategy <strategy>", "Compaction strategy: auto (default), provider_native, or summary_fallback").option("--compact-threshold <value>", "Auto-compact when estimated context crosses this threshold (default: 80% fallback, 90% native; accepts percent like 90% or absolute token count like 120000)").option("--compact-instructions <text>", "Extra instructions for what a compact summary must preserve").option("--no-auto-compact", "Disable automatic context-aware history compaction").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").option("--sandbox <provider>", "Enable sandbox code execution tool (cloudflare-worker, quickjs, or daytona)").option("--no-local-tools", "Disable built-in local tool execution (read_file, write_file, list_directory)").option("-t, --tools <tools...>", "Enable built-in tools (e.g., exa, firecrawl, dalle, openai_web_search, anthropic_web_search)").option("--plain-text", "Disable markdown rendering in output").option("--no-reasoning", "Disable model reasoning/thinking (enabled by default for supported models)").option("--no-checkpoint", "Run all iterations without checkpoint pauses (fully autonomous)").option("--checkpoint-timeout <seconds>", "Auto-continue timeout in seconds (default: 10)", "10").option("--planning-model <modelId>", "Model to use during research/planning phases").option("--execution-model <modelId>", "Model to use during execution phase").option("--fallback-model <modelId>", "Model to fall back to when primary model fails").option("--playbook <name>", "Load a playbook from .runtype/marathons/playbooks/").option("--offload-threshold <chars>", 'Offload tool outputs larger than this to files (default: 100000; use "off" or "0" to disable guardrails)').option("--tool-context <mode>", "Tool result storage: hot-tail (default), observation-mask, or full-inline").option("--tool-window <window>", 'Compaction window: "session" (default) or a number for last-N tool results (e.g. 10)').option("--runner-char <char>", "Custom runner emoji (default: \u{1F3C3})").option("--finish-char <char>", "Custom finish line emoji (default: \u{1F3C1})").option("--no-runner", "Hide the runner emoji from the header border").option("--no-finish", "Hide the finish line emoji from the header border").action(taskAction);
|
|
17960
18162
|
}
|
|
17961
18163
|
var taskCommand = applyTaskOptions(
|
|
17962
18164
|
new Command10("task").description("Run a multi-session agent task")
|
|
@@ -18009,7 +18211,7 @@ agentsCommand.command("list").description("List all agents").option("--json", "O
|
|
|
18009
18211
|
const [items, setItems] = useState24(null);
|
|
18010
18212
|
const [error, setError] = useState24(null);
|
|
18011
18213
|
const [total, setTotal] = useState24();
|
|
18012
|
-
|
|
18214
|
+
useEffect21(() => {
|
|
18013
18215
|
client.get("/agents", { limit: options.limit }).then((res) => {
|
|
18014
18216
|
setItems(res.data ?? []);
|
|
18015
18217
|
setTotal(getTotalCount(res.pagination));
|
|
@@ -18069,7 +18271,7 @@ agentsCommand.command("get <id>").description("Get agent details").option("--jso
|
|
|
18069
18271
|
const App = () => {
|
|
18070
18272
|
const [items, setItems] = useState24(null);
|
|
18071
18273
|
const [error, setError] = useState24(null);
|
|
18072
|
-
|
|
18274
|
+
useEffect21(() => {
|
|
18073
18275
|
client.get(`/agents/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
|
|
18074
18276
|
}, []);
|
|
18075
18277
|
return React10.createElement(DataList, {
|
|
@@ -18123,7 +18325,7 @@ agentsCommand.command("create").description("Create a new agent").requiredOption
|
|
|
18123
18325
|
const [success, setSuccess] = useState24(null);
|
|
18124
18326
|
const [error, setError] = useState24(null);
|
|
18125
18327
|
const [result, setResult] = useState24(null);
|
|
18126
|
-
|
|
18328
|
+
useEffect21(() => {
|
|
18127
18329
|
client.post("/agents", {
|
|
18128
18330
|
name: options.name,
|
|
18129
18331
|
description: options.description
|
|
@@ -18174,7 +18376,7 @@ agentsCommand.command("delete <id>").description("Delete an agent").option("--tt
|
|
|
18174
18376
|
const [loading, setLoading] = useState24(false);
|
|
18175
18377
|
const [success, setSuccess] = useState24(null);
|
|
18176
18378
|
const [error, setError] = useState24(null);
|
|
18177
|
-
|
|
18379
|
+
useEffect21(() => {
|
|
18178
18380
|
if (confirmed !== true) return void 0;
|
|
18179
18381
|
setLoading(true);
|
|
18180
18382
|
client.delete(`/agents/${id}`).then(() => {
|
|
@@ -18264,7 +18466,7 @@ import { Command as Command12 } from "commander";
|
|
|
18264
18466
|
import chalk18 from "chalk";
|
|
18265
18467
|
import React11 from "react";
|
|
18266
18468
|
import { render as render11 } from "ink";
|
|
18267
|
-
import { useState as useState25, useEffect as
|
|
18469
|
+
import { useState as useState25, useEffect as useEffect22 } from "react";
|
|
18268
18470
|
var modelsCommand = new Command12("models").description("Manage model configurations");
|
|
18269
18471
|
modelsCommand.command("list").description("List your enabled model configurations").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
|
|
18270
18472
|
const apiKey = await ensureAuth();
|
|
@@ -18304,7 +18506,7 @@ modelsCommand.command("list").description("List your enabled model configuration
|
|
|
18304
18506
|
const [items, setItems] = useState25(null);
|
|
18305
18507
|
const [error, setError] = useState25(null);
|
|
18306
18508
|
const [total, setTotal] = useState25();
|
|
18307
|
-
|
|
18509
|
+
useEffect22(() => {
|
|
18308
18510
|
client.get("/model-configs").then((res) => {
|
|
18309
18511
|
setItems(res.data ?? []);
|
|
18310
18512
|
setTotal(getTotalCount(res.pagination));
|
|
@@ -18368,7 +18570,7 @@ modelsCommand.command("available").description("List all available models groupe
|
|
|
18368
18570
|
const App = () => {
|
|
18369
18571
|
const [items, setItems] = useState25(null);
|
|
18370
18572
|
const [error, setError] = useState25(null);
|
|
18371
|
-
|
|
18573
|
+
useEffect22(() => {
|
|
18372
18574
|
client.get("/model-configs/grouped").then((res) => setItems(res.data ?? [])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
|
|
18373
18575
|
}, []);
|
|
18374
18576
|
return React11.createElement(DataList, {
|
|
@@ -18418,7 +18620,7 @@ modelsCommand.command("enable <modelId>").description("Enable a model by creatin
|
|
|
18418
18620
|
const [success, setSuccess] = useState25(null);
|
|
18419
18621
|
const [error, setError] = useState25(null);
|
|
18420
18622
|
const [result, setResult] = useState25(null);
|
|
18421
|
-
|
|
18623
|
+
useEffect22(() => {
|
|
18422
18624
|
client.post("/model-configs", { modelId }).then((data) => {
|
|
18423
18625
|
setResult(data);
|
|
18424
18626
|
setSuccess(true);
|
|
@@ -18465,7 +18667,7 @@ modelsCommand.command("disable <id>").description("Disable a model configuration
|
|
|
18465
18667
|
const [loading, setLoading] = useState25(true);
|
|
18466
18668
|
const [success, setSuccess] = useState25(null);
|
|
18467
18669
|
const [error, setError] = useState25(null);
|
|
18468
|
-
|
|
18670
|
+
useEffect22(() => {
|
|
18469
18671
|
client.patch(`/model-configs/${id}/status`, { enabled: false }).then(() => {
|
|
18470
18672
|
setSuccess(true);
|
|
18471
18673
|
setLoading(false);
|
|
@@ -18505,7 +18707,7 @@ modelsCommand.command("default <id>").description("Set a model configuration as
|
|
|
18505
18707
|
const [loading, setLoading] = useState25(true);
|
|
18506
18708
|
const [success, setSuccess] = useState25(null);
|
|
18507
18709
|
const [error, setError] = useState25(null);
|
|
18508
|
-
|
|
18710
|
+
useEffect22(() => {
|
|
18509
18711
|
client.patch(`/model-configs/${id}/default`, {}).then(() => {
|
|
18510
18712
|
setSuccess(true);
|
|
18511
18713
|
setLoading(false);
|
|
@@ -18546,7 +18748,7 @@ import { Command as Command13 } from "commander";
|
|
|
18546
18748
|
import chalk19 from "chalk";
|
|
18547
18749
|
import React12 from "react";
|
|
18548
18750
|
import { render as render12 } from "ink";
|
|
18549
|
-
import { useState as useState26, useEffect as
|
|
18751
|
+
import { useState as useState26, useEffect as useEffect23 } from "react";
|
|
18550
18752
|
var schedulesCommand = new Command13("schedules").description("Manage schedules");
|
|
18551
18753
|
schedulesCommand.command("list").description("List all schedules").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
|
|
18552
18754
|
const apiKey = await ensureAuth();
|
|
@@ -18593,7 +18795,7 @@ schedulesCommand.command("list").description("List all schedules").option("--jso
|
|
|
18593
18795
|
const [items, setItems] = useState26(null);
|
|
18594
18796
|
const [error, setError] = useState26(null);
|
|
18595
18797
|
const [total, setTotal] = useState26();
|
|
18596
|
-
|
|
18798
|
+
useEffect23(() => {
|
|
18597
18799
|
client.get("/schedules").then((res) => {
|
|
18598
18800
|
setItems(res.data ?? []);
|
|
18599
18801
|
setTotal(getTotalCount(res.pagination));
|
|
@@ -18658,7 +18860,7 @@ schedulesCommand.command("get <id>").description("Get schedule details").option(
|
|
|
18658
18860
|
const App = () => {
|
|
18659
18861
|
const [items, setItems] = useState26(null);
|
|
18660
18862
|
const [error, setError] = useState26(null);
|
|
18661
|
-
|
|
18863
|
+
useEffect23(() => {
|
|
18662
18864
|
client.get(`/schedules/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
|
|
18663
18865
|
}, []);
|
|
18664
18866
|
return React12.createElement(DataList, {
|
|
@@ -18716,7 +18918,7 @@ schedulesCommand.command("create").description("Create a new schedule").required
|
|
|
18716
18918
|
const [success, setSuccess] = useState26(null);
|
|
18717
18919
|
const [error, setError] = useState26(null);
|
|
18718
18920
|
const [result, setResult] = useState26(null);
|
|
18719
|
-
|
|
18921
|
+
useEffect23(() => {
|
|
18720
18922
|
client.post("/schedules", {
|
|
18721
18923
|
flowId: options.flow,
|
|
18722
18924
|
cronExpression: options.cron,
|
|
@@ -18770,7 +18972,7 @@ function simpleMutationCommand(name, description, mutationFn, successMsg, loadin
|
|
|
18770
18972
|
const [loading, setLoading] = useState26(true);
|
|
18771
18973
|
const [success, setSuccess] = useState26(null);
|
|
18772
18974
|
const [error, setError] = useState26(null);
|
|
18773
|
-
|
|
18975
|
+
useEffect23(() => {
|
|
18774
18976
|
mutationFn(client, id).then(() => {
|
|
18775
18977
|
setSuccess(true);
|
|
18776
18978
|
setLoading(false);
|
|
@@ -18833,7 +19035,7 @@ schedulesCommand.command("delete <id>").description("Delete a schedule").option(
|
|
|
18833
19035
|
const [loading, setLoading] = useState26(false);
|
|
18834
19036
|
const [success, setSuccess] = useState26(null);
|
|
18835
19037
|
const [error, setError] = useState26(null);
|
|
18836
|
-
|
|
19038
|
+
useEffect23(() => {
|
|
18837
19039
|
if (confirmed !== true) return void 0;
|
|
18838
19040
|
setLoading(true);
|
|
18839
19041
|
client.delete(`/schedules/${id}`).then(() => {
|
|
@@ -18877,7 +19079,7 @@ import { Command as Command14 } from "commander";
|
|
|
18877
19079
|
import chalk20 from "chalk";
|
|
18878
19080
|
import React13 from "react";
|
|
18879
19081
|
import { render as render13 } from "ink";
|
|
18880
|
-
import { useState as useState27, useEffect as
|
|
19082
|
+
import { useState as useState27, useEffect as useEffect24 } from "react";
|
|
18881
19083
|
import { Text as Text30 } from "ink";
|
|
18882
19084
|
import { readFileSync as readFileSync13 } from "fs";
|
|
18883
19085
|
var evalCommand = new Command14("eval").description("Manage evaluations");
|
|
@@ -18926,7 +19128,7 @@ evalCommand.command("submit").description("Submit an eval batch").requiredOption
|
|
|
18926
19128
|
const [success, setSuccess] = useState27(null);
|
|
18927
19129
|
const [error, setError] = useState27(null);
|
|
18928
19130
|
const [resultNode, setResultNode] = useState27(void 0);
|
|
18929
|
-
|
|
19131
|
+
useEffect24(() => {
|
|
18930
19132
|
const run = async () => {
|
|
18931
19133
|
try {
|
|
18932
19134
|
const data = await client.post("/eval/submit", {
|
|
@@ -19009,7 +19211,7 @@ evalCommand.command("list").description("List eval batches").option("--flow <id>
|
|
|
19009
19211
|
const [items, setItems] = useState27(null);
|
|
19010
19212
|
const [total, setTotal] = useState27(void 0);
|
|
19011
19213
|
const [error, setError] = useState27(null);
|
|
19012
|
-
|
|
19214
|
+
useEffect24(() => {
|
|
19013
19215
|
const run = async () => {
|
|
19014
19216
|
try {
|
|
19015
19217
|
const data = await client.get("/eval/batches", params);
|
|
@@ -19089,7 +19291,7 @@ evalCommand.command("results <id>").description("Get eval batch results").option
|
|
|
19089
19291
|
const [success, setSuccess] = useState27(null);
|
|
19090
19292
|
const [error, setError] = useState27(null);
|
|
19091
19293
|
const [resultNode, setResultNode] = useState27(void 0);
|
|
19092
|
-
|
|
19294
|
+
useEffect24(() => {
|
|
19093
19295
|
const run = async () => {
|
|
19094
19296
|
try {
|
|
19095
19297
|
const data = await client.get(`/eval/${id}/results`);
|
|
@@ -19152,7 +19354,7 @@ evalCommand.command("compare <groupId>").description("Compare evals in a group")
|
|
|
19152
19354
|
const [loading, setLoading] = useState27(true);
|
|
19153
19355
|
const [success, setSuccess] = useState27(null);
|
|
19154
19356
|
const [error, setError] = useState27(null);
|
|
19155
|
-
|
|
19357
|
+
useEffect24(() => {
|
|
19156
19358
|
const run = async () => {
|
|
19157
19359
|
try {
|
|
19158
19360
|
const data = await client.post("/eval/compare", { groupId });
|
|
@@ -19184,7 +19386,7 @@ import { Command as Command15 } from "commander";
|
|
|
19184
19386
|
import chalk21 from "chalk";
|
|
19185
19387
|
import React14 from "react";
|
|
19186
19388
|
import { render as render14 } from "ink";
|
|
19187
|
-
import { useState as useState28, useEffect as
|
|
19389
|
+
import { useState as useState28, useEffect as useEffect25 } from "react";
|
|
19188
19390
|
import { Text as Text31 } from "ink";
|
|
19189
19391
|
var apiKeysCommand = new Command15("api-keys").description("Manage API keys");
|
|
19190
19392
|
apiKeysCommand.command("list").description("List your API keys").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
|
|
@@ -19227,7 +19429,7 @@ apiKeysCommand.command("list").description("List your API keys").option("--json"
|
|
|
19227
19429
|
const [items, setItems] = useState28(null);
|
|
19228
19430
|
const [total, setTotal] = useState28(void 0);
|
|
19229
19431
|
const [error, setError] = useState28(null);
|
|
19230
|
-
|
|
19432
|
+
useEffect25(() => {
|
|
19231
19433
|
const run = async () => {
|
|
19232
19434
|
try {
|
|
19233
19435
|
const data = await client.get("/api-keys");
|
|
@@ -19291,7 +19493,7 @@ apiKeysCommand.command("get <id>").description("Get API key details").option("--
|
|
|
19291
19493
|
const [success, setSuccess] = useState28(null);
|
|
19292
19494
|
const [error, setError] = useState28(null);
|
|
19293
19495
|
const [resultNode, setResultNode] = useState28(void 0);
|
|
19294
|
-
|
|
19496
|
+
useEffect25(() => {
|
|
19295
19497
|
const run = async () => {
|
|
19296
19498
|
try {
|
|
19297
19499
|
const data = await client.get(`/api-keys/${id}`);
|
|
@@ -19360,7 +19562,7 @@ apiKeysCommand.command("create").description("Create a new API key").requiredOpt
|
|
|
19360
19562
|
const [success, setSuccess] = useState28(null);
|
|
19361
19563
|
const [error, setError] = useState28(null);
|
|
19362
19564
|
const [resultNode, setResultNode] = useState28(void 0);
|
|
19363
|
-
|
|
19565
|
+
useEffect25(() => {
|
|
19364
19566
|
const run = async () => {
|
|
19365
19567
|
try {
|
|
19366
19568
|
const data = await client.post("/api-keys", {
|
|
@@ -19418,7 +19620,7 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
|
|
|
19418
19620
|
const [loading, setLoading] = useState28(true);
|
|
19419
19621
|
const [success, setSuccess] = useState28(null);
|
|
19420
19622
|
const [error, setError] = useState28(null);
|
|
19421
|
-
|
|
19623
|
+
useEffect25(() => {
|
|
19422
19624
|
const run = async () => {
|
|
19423
19625
|
try {
|
|
19424
19626
|
await client.delete(`/api-keys/${id}`);
|
|
@@ -19461,7 +19663,7 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
|
|
|
19461
19663
|
const [loading, setLoading] = useState28(true);
|
|
19462
19664
|
const [success, setSuccess] = useState28(null);
|
|
19463
19665
|
const [error, setError] = useState28(null);
|
|
19464
|
-
|
|
19666
|
+
useEffect25(() => {
|
|
19465
19667
|
const run = async () => {
|
|
19466
19668
|
try {
|
|
19467
19669
|
await client.delete(`/api-keys/${id}`);
|
|
@@ -19515,7 +19717,7 @@ apiKeysCommand.command("regenerate <id>").description("Regenerate an API key").o
|
|
|
19515
19717
|
const [success, setSuccess] = useState28(null);
|
|
19516
19718
|
const [error, setError] = useState28(null);
|
|
19517
19719
|
const [resultNode, setResultNode] = useState28(void 0);
|
|
19518
|
-
|
|
19720
|
+
useEffect25(() => {
|
|
19519
19721
|
const run = async () => {
|
|
19520
19722
|
try {
|
|
19521
19723
|
const data = await client.post(`/api-keys/${id}/regenerate`);
|
|
@@ -19570,7 +19772,7 @@ apiKeysCommand.command("analytics").description("Show API key usage analytics").
|
|
|
19570
19772
|
const [loading, setLoading] = useState28(true);
|
|
19571
19773
|
const [success, setSuccess] = useState28(null);
|
|
19572
19774
|
const [error, setError] = useState28(null);
|
|
19573
|
-
|
|
19775
|
+
useEffect25(() => {
|
|
19574
19776
|
const run = async () => {
|
|
19575
19777
|
try {
|
|
19576
19778
|
const path13 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
|
|
@@ -19603,7 +19805,7 @@ import { Command as Command16 } from "commander";
|
|
|
19603
19805
|
import chalk22 from "chalk";
|
|
19604
19806
|
import React15 from "react";
|
|
19605
19807
|
import { render as render15 } from "ink";
|
|
19606
|
-
import { useState as useState29, useEffect as
|
|
19808
|
+
import { useState as useState29, useEffect as useEffect26 } from "react";
|
|
19607
19809
|
import { Text as Text32 } from "ink";
|
|
19608
19810
|
var analyticsCommand = new Command16("analytics").description("View analytics and execution results");
|
|
19609
19811
|
analyticsCommand.command("stats").description("Show account statistics").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
|
|
@@ -19636,7 +19838,7 @@ analyticsCommand.command("stats").description("Show account statistics").option(
|
|
|
19636
19838
|
const [success, setSuccess] = useState29(null);
|
|
19637
19839
|
const [error, setError] = useState29(null);
|
|
19638
19840
|
const [resultNode, setResultNode] = useState29(void 0);
|
|
19639
|
-
|
|
19841
|
+
useEffect26(() => {
|
|
19640
19842
|
const run = async () => {
|
|
19641
19843
|
try {
|
|
19642
19844
|
const data = await client.get("/analytics/stats");
|
|
@@ -19720,7 +19922,7 @@ analyticsCommand.command("results").description("List execution results").option
|
|
|
19720
19922
|
const [items, setItems] = useState29(null);
|
|
19721
19923
|
const [total, setTotal] = useState29(void 0);
|
|
19722
19924
|
const [error, setError] = useState29(null);
|
|
19723
|
-
|
|
19925
|
+
useEffect26(() => {
|
|
19724
19926
|
const run = async () => {
|
|
19725
19927
|
try {
|
|
19726
19928
|
const data = await client.get(
|
|
@@ -19765,7 +19967,7 @@ import { Command as Command17 } from "commander";
|
|
|
19765
19967
|
import chalk23 from "chalk";
|
|
19766
19968
|
import React16 from "react";
|
|
19767
19969
|
import { render as render16 } from "ink";
|
|
19768
|
-
import { useState as useState30, useEffect as
|
|
19970
|
+
import { useState as useState30, useEffect as useEffect27 } from "react";
|
|
19769
19971
|
import open5 from "open";
|
|
19770
19972
|
var billingCommand = new Command17("billing").description("View billing and subscription info");
|
|
19771
19973
|
billingCommand.command("status").description("Show current plan and usage").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
|
|
@@ -19815,7 +20017,7 @@ billingCommand.command("status").description("Show current plan and usage").opti
|
|
|
19815
20017
|
const [success, setSuccess] = useState30(null);
|
|
19816
20018
|
const [error, setError] = useState30(null);
|
|
19817
20019
|
const [resultNode, setResultNode] = useState30(void 0);
|
|
19818
|
-
|
|
20020
|
+
useEffect27(() => {
|
|
19819
20021
|
const run = async () => {
|
|
19820
20022
|
try {
|
|
19821
20023
|
const data = await client.get("/billing/status");
|
|
@@ -19886,7 +20088,7 @@ billingCommand.command("portal").description("Open the billing portal in your br
|
|
|
19886
20088
|
const [success, setSuccess] = useState30(null);
|
|
19887
20089
|
const [error, setError] = useState30(null);
|
|
19888
20090
|
const [msg, setMsg] = useState30("Opening billing portal...");
|
|
19889
|
-
|
|
20091
|
+
useEffect27(() => {
|
|
19890
20092
|
const run = async () => {
|
|
19891
20093
|
try {
|
|
19892
20094
|
const data = await client.post("/billing/portal");
|
|
@@ -19938,7 +20140,7 @@ billingCommand.command("refresh").description("Refresh plan data from billing pr
|
|
|
19938
20140
|
const [loading, setLoading] = useState30(true);
|
|
19939
20141
|
const [success, setSuccess] = useState30(null);
|
|
19940
20142
|
const [error, setError] = useState30(null);
|
|
19941
|
-
|
|
20143
|
+
useEffect27(() => {
|
|
19942
20144
|
const run = async () => {
|
|
19943
20145
|
try {
|
|
19944
20146
|
await client.post("/billing/refresh");
|
|
@@ -19969,7 +20171,7 @@ import { Command as Command18 } from "commander";
|
|
|
19969
20171
|
import chalk24 from "chalk";
|
|
19970
20172
|
import React17 from "react";
|
|
19971
20173
|
import { render as render17 } from "ink";
|
|
19972
|
-
import { useState as useState31, useEffect as
|
|
20174
|
+
import { useState as useState31, useEffect as useEffect28 } from "react";
|
|
19973
20175
|
import { Text as Text33 } from "ink";
|
|
19974
20176
|
var flowVersionsCommand = new Command18("flow-versions").description(
|
|
19975
20177
|
"Manage flow versions"
|
|
@@ -20009,7 +20211,7 @@ flowVersionsCommand.command("list <flowId>").description("List all versions for
|
|
|
20009
20211
|
const [loading, setLoading] = useState31(true);
|
|
20010
20212
|
const [items, setItems] = useState31(null);
|
|
20011
20213
|
const [error, setError] = useState31(null);
|
|
20012
|
-
|
|
20214
|
+
useEffect28(() => {
|
|
20013
20215
|
const run = async () => {
|
|
20014
20216
|
try {
|
|
20015
20217
|
const data = await client.get(`/flow-versions/${flowId}`);
|
|
@@ -20071,7 +20273,7 @@ flowVersionsCommand.command("get <flowId> <versionId>").description("Get a speci
|
|
|
20071
20273
|
const [success, setSuccess] = useState31(null);
|
|
20072
20274
|
const [error, setError] = useState31(null);
|
|
20073
20275
|
const [resultNode, setResultNode] = useState31(void 0);
|
|
20074
|
-
|
|
20276
|
+
useEffect28(() => {
|
|
20075
20277
|
const run = async () => {
|
|
20076
20278
|
try {
|
|
20077
20279
|
const data = await client.get(`/flow-versions/${flowId}/${versionId}`);
|
|
@@ -20137,7 +20339,7 @@ flowVersionsCommand.command("published <flowId>").description("Get the published
|
|
|
20137
20339
|
const [success, setSuccess] = useState31(null);
|
|
20138
20340
|
const [error, setError] = useState31(null);
|
|
20139
20341
|
const [resultNode, setResultNode] = useState31(void 0);
|
|
20140
|
-
|
|
20342
|
+
useEffect28(() => {
|
|
20141
20343
|
const run = async () => {
|
|
20142
20344
|
try {
|
|
20143
20345
|
const data = await client.get(`/flow-versions/${flowId}/published`);
|
|
@@ -20193,7 +20395,7 @@ flowVersionsCommand.command("publish <flowId>").description("Publish a version")
|
|
|
20193
20395
|
const [loading, setLoading] = useState31(true);
|
|
20194
20396
|
const [success, setSuccess] = useState31(null);
|
|
20195
20397
|
const [error, setError] = useState31(null);
|
|
20196
|
-
|
|
20398
|
+
useEffect28(() => {
|
|
20197
20399
|
const run = async () => {
|
|
20198
20400
|
try {
|
|
20199
20401
|
await client.post(`/flow-versions/${flowId}/publish`, {
|