@runtypelabs/cli 1.9.0 → 1.9.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +320 -47
- package/dist/index.js +1186 -599
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -3741,7 +3741,7 @@ var require_provider_routing = __commonJS({
|
|
|
3741
3741
|
exports.extractBaseModel = extractBaseModel;
|
|
3742
3742
|
exports.extractModelIdentity = extractModelIdentity;
|
|
3743
3743
|
exports.getRoutedModelDisplayName = getRoutedModelDisplayName;
|
|
3744
|
-
exports.normalizeModelId =
|
|
3744
|
+
exports.normalizeModelId = normalizeModelId2;
|
|
3745
3745
|
exports.buildModelId = buildModelId;
|
|
3746
3746
|
exports.parseModelId = parseModelId;
|
|
3747
3747
|
exports.parseModelIdLegacy = parseModelIdLegacy;
|
|
@@ -4049,7 +4049,7 @@ var require_provider_routing = __commonJS({
|
|
|
4049
4049
|
}
|
|
4050
4050
|
return baseModel.split("-").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
4051
4051
|
}
|
|
4052
|
-
function
|
|
4052
|
+
function normalizeModelId2(modelId) {
|
|
4053
4053
|
if (modelId.startsWith("model/")) {
|
|
4054
4054
|
return modelId.slice(6);
|
|
4055
4055
|
}
|
|
@@ -8305,7 +8305,7 @@ import { Command as Command11 } from "commander";
|
|
|
8305
8305
|
import chalk17 from "chalk";
|
|
8306
8306
|
import React10 from "react";
|
|
8307
8307
|
import { render as render10 } from "ink";
|
|
8308
|
-
import { useState as
|
|
8308
|
+
import { useState as useState23, useEffect as useEffect22 } from "react";
|
|
8309
8309
|
import { processStream as processStream4 } from "@runtypelabs/sdk";
|
|
8310
8310
|
|
|
8311
8311
|
// src/commands/agents-task.ts
|
|
@@ -8315,17 +8315,33 @@ import { render as render9 } from "ink";
|
|
|
8315
8315
|
import React9 from "react";
|
|
8316
8316
|
|
|
8317
8317
|
// src/ink/marathon/MarathonApp.tsx
|
|
8318
|
-
import { useState as
|
|
8318
|
+
import { useState as useState21, useEffect as useEffect20, useRef as useRef8, useCallback as useCallback7, useMemo as useMemo10 } from "react";
|
|
8319
8319
|
import { execSync } from "child_process";
|
|
8320
8320
|
import * as fs3 from "fs";
|
|
8321
8321
|
import open4 from "open";
|
|
8322
8322
|
import { Box as Box24, Text as Text26, useApp as useApp4, useInput as useInput10, useStdout as useStdout4 } from "ink";
|
|
8323
|
-
import { StreamOutput, StatusBar, ErrorDisplay as ErrorDisplay3, theme as
|
|
8323
|
+
import { StreamOutput, StatusBar, ErrorDisplay as ErrorDisplay3, theme as theme27 } from "@runtypelabs/ink-components";
|
|
8324
8324
|
import { LoadingAnimation } from "@runtypelabs/terminal-animations";
|
|
8325
8325
|
|
|
8326
8326
|
// src/ink/marathon/useMarathonStream.ts
|
|
8327
8327
|
import { useState as useState10, useRef as useRef3, useMemo, useCallback as useCallback2 } from "react";
|
|
8328
8328
|
|
|
8329
|
+
// src/ink/marathon/context-compaction-format.ts
|
|
8330
|
+
function formatTokenCount(value) {
|
|
8331
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return void 0;
|
|
8332
|
+
return value.toLocaleString();
|
|
8333
|
+
}
|
|
8334
|
+
function formatCompactionThresholdLabel(compaction) {
|
|
8335
|
+
const estimated = formatTokenCount(compaction.estimatedTokens);
|
|
8336
|
+
const threshold = formatTokenCount(compaction.thresholdTokens);
|
|
8337
|
+
const contextLimit = formatTokenCount(compaction.contextLimitTokens);
|
|
8338
|
+
if (estimated && contextLimit) return `~${estimated}/${contextLimit} tokens`;
|
|
8339
|
+
if (estimated && threshold) return `~${estimated}/${threshold} tokens`;
|
|
8340
|
+
if (estimated) return `~${estimated} tokens`;
|
|
8341
|
+
if (threshold && contextLimit) return `${threshold}/${contextLimit} tokens`;
|
|
8342
|
+
return contextLimit ? `${contextLimit} tokens` : threshold ? `${threshold} tokens` : void 0;
|
|
8343
|
+
}
|
|
8344
|
+
|
|
8329
8345
|
// src/ink/marathon/transcript-utils.ts
|
|
8330
8346
|
function appendTranscriptText(content, delta, previousKind) {
|
|
8331
8347
|
if (!content) return delta;
|
|
@@ -8354,7 +8370,8 @@ var INITIAL_STATE = {
|
|
|
8354
8370
|
error: null,
|
|
8355
8371
|
rawEvents: [],
|
|
8356
8372
|
totalInputTokens: 0,
|
|
8357
|
-
totalOutputTokens: 0
|
|
8373
|
+
totalOutputTokens: 0,
|
|
8374
|
+
contextCompaction: null
|
|
8358
8375
|
};
|
|
8359
8376
|
var MAX_RAW_EVENTS = 500;
|
|
8360
8377
|
function appendContentLine(content, line) {
|
|
@@ -8367,6 +8384,23 @@ function pushRawEvent(prev, type, data) {
|
|
|
8367
8384
|
const events = [...prev.rawEvents, event];
|
|
8368
8385
|
return events.length > MAX_RAW_EVENTS ? events.slice(-MAX_RAW_EVENTS) : events;
|
|
8369
8386
|
}
|
|
8387
|
+
function formatContextCompactionCompleteLine(event) {
|
|
8388
|
+
const modeLabel = event.mode === "auto" ? "automatically" : "with compact mode";
|
|
8389
|
+
const modelLabel = event.model ? ` for ${event.model}` : "";
|
|
8390
|
+
const strategyLabel = event.strategy === "provider_native" ? " via provider-native compaction" : " via summary compaction";
|
|
8391
|
+
const thresholdLabel = formatCompactionThresholdLabel(event);
|
|
8392
|
+
const breakdownParts = [
|
|
8393
|
+
event.breakdown?.historyTokens ? `history ${formatTokenCount(event.breakdown.historyTokens)}` : void 0,
|
|
8394
|
+
event.breakdown?.toolOutputTokens ? `tool outputs ${formatTokenCount(event.breakdown.toolOutputTokens)}` : void 0,
|
|
8395
|
+
event.breakdown?.toolDefinitionTokens ? `tool defs ${formatTokenCount(event.breakdown.toolDefinitionTokens)}` : void 0,
|
|
8396
|
+
event.reservedOutputTokens ? `reserve ${formatTokenCount(event.reservedOutputTokens)}` : void 0
|
|
8397
|
+
].filter(Boolean);
|
|
8398
|
+
const breakdownLabel = breakdownParts.length > 0 ? ` (${breakdownParts.join(", ")})` : "";
|
|
8399
|
+
return thresholdLabel ? `[context] History compacted ${modeLabel}${modelLabel}${strategyLabel} at ${thresholdLabel}${breakdownLabel}.` : `[context] History compacted ${modeLabel}${modelLabel}${strategyLabel}${breakdownLabel}.`;
|
|
8400
|
+
}
|
|
8401
|
+
function formatContextNoticeLine(event) {
|
|
8402
|
+
return `[context] ${event.message}`;
|
|
8403
|
+
}
|
|
8370
8404
|
var toolCounter = 0;
|
|
8371
8405
|
function useMarathonStream() {
|
|
8372
8406
|
const [state, setState] = useState10(INITIAL_STATE);
|
|
@@ -8515,6 +8549,45 @@ function useMarathonStream() {
|
|
|
8515
8549
|
const setSteering = useCallback2(() => {
|
|
8516
8550
|
setState((prev) => ({ ...prev, phase: "steering" }));
|
|
8517
8551
|
}, []);
|
|
8552
|
+
const startContextCompaction = useCallback2((event) => {
|
|
8553
|
+
setState((prev) => ({
|
|
8554
|
+
...prev,
|
|
8555
|
+
contextCompaction: {
|
|
8556
|
+
active: true,
|
|
8557
|
+
mode: event.mode,
|
|
8558
|
+
strategy: event.strategy,
|
|
8559
|
+
sessionIndex: event.sessionIndex,
|
|
8560
|
+
model: event.model,
|
|
8561
|
+
estimatedTokens: event.estimatedTokens,
|
|
8562
|
+
thresholdTokens: event.thresholdTokens,
|
|
8563
|
+
contextLimitTokens: event.contextLimitTokens,
|
|
8564
|
+
effectiveInputBudgetTokens: event.effectiveInputBudgetTokens,
|
|
8565
|
+
reservedOutputTokens: event.reservedOutputTokens,
|
|
8566
|
+
beforeTokens: event.beforeTokens,
|
|
8567
|
+
afterTokens: event.afterTokens,
|
|
8568
|
+
breakdown: event.breakdown,
|
|
8569
|
+
startedAt: Date.now()
|
|
8570
|
+
},
|
|
8571
|
+
rawEvents: pushRawEvent(prev, "marathon_context_compaction_start", { ...event })
|
|
8572
|
+
}));
|
|
8573
|
+
}, []);
|
|
8574
|
+
const finishContextCompaction = useCallback2((event) => {
|
|
8575
|
+
setState((prev) => ({
|
|
8576
|
+
...prev,
|
|
8577
|
+
contextCompaction: null,
|
|
8578
|
+
content: appendContentLine(prev.content, formatContextCompactionCompleteLine(event)),
|
|
8579
|
+
lastTranscriptKind: "text",
|
|
8580
|
+
rawEvents: pushRawEvent(prev, "marathon_context_compaction_complete", { ...event })
|
|
8581
|
+
}));
|
|
8582
|
+
}, []);
|
|
8583
|
+
const reportContextNotice = useCallback2((event) => {
|
|
8584
|
+
setState((prev) => ({
|
|
8585
|
+
...prev,
|
|
8586
|
+
content: appendContentLine(prev.content, formatContextNoticeLine(event)),
|
|
8587
|
+
lastTranscriptKind: "text",
|
|
8588
|
+
rawEvents: pushRawEvent(prev, "marathon_context_notice", { ...event })
|
|
8589
|
+
}));
|
|
8590
|
+
}, []);
|
|
8518
8591
|
const resetForNewSession = useCallback2(() => {
|
|
8519
8592
|
setState((prev) => ({
|
|
8520
8593
|
...prev,
|
|
@@ -8525,7 +8598,8 @@ function useMarathonStream() {
|
|
|
8525
8598
|
thinkingStartedAt: null,
|
|
8526
8599
|
tools: [],
|
|
8527
8600
|
currentIteration: 0,
|
|
8528
|
-
error: null
|
|
8601
|
+
error: null,
|
|
8602
|
+
contextCompaction: null
|
|
8529
8603
|
}));
|
|
8530
8604
|
}, []);
|
|
8531
8605
|
const showError = useCallback2((error) => {
|
|
@@ -8536,7 +8610,17 @@ function useMarathonStream() {
|
|
|
8536
8610
|
rawEvents: pushRawEvent(prev, "agent_error", { message: error.message })
|
|
8537
8611
|
}));
|
|
8538
8612
|
}, []);
|
|
8539
|
-
return {
|
|
8613
|
+
return {
|
|
8614
|
+
state,
|
|
8615
|
+
callbacks,
|
|
8616
|
+
reset,
|
|
8617
|
+
setSteering,
|
|
8618
|
+
startContextCompaction,
|
|
8619
|
+
finishContextCompaction,
|
|
8620
|
+
reportContextNotice,
|
|
8621
|
+
resetForNewSession,
|
|
8622
|
+
showError
|
|
8623
|
+
};
|
|
8540
8624
|
}
|
|
8541
8625
|
|
|
8542
8626
|
// src/ink/marathon/SessionHeader.tsx
|
|
@@ -8918,18 +9002,48 @@ function ThinkingIndicator({ startedAt }) {
|
|
|
8918
9002
|
return /* @__PURE__ */ jsx11(Spinner4, { label: `Thinking... ${elapsed}s`, color: theme11.textMuted });
|
|
8919
9003
|
}
|
|
8920
9004
|
|
|
9005
|
+
// src/ink/marathon/ContextCompactionIndicator.tsx
|
|
9006
|
+
import { useEffect as useEffect13, useState as useState13 } from "react";
|
|
9007
|
+
import { Spinner as Spinner5, theme as theme12 } from "@runtypelabs/ink-components";
|
|
9008
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
9009
|
+
function buildCompactionLabel(compaction, elapsedSeconds) {
|
|
9010
|
+
const modeLabel = compaction.mode === "auto" ? "auto" : "manual";
|
|
9011
|
+
const strategyLabel = compaction.strategy === "provider_native" ? "native" : "summary";
|
|
9012
|
+
const thresholdLabel = formatCompactionThresholdLabel(compaction);
|
|
9013
|
+
if (thresholdLabel) {
|
|
9014
|
+
return `Compacting context for session ${compaction.sessionIndex} (${modeLabel}, ${strategyLabel}, ${thresholdLabel})... ${elapsedSeconds}s`;
|
|
9015
|
+
}
|
|
9016
|
+
return `Compacting context for session ${compaction.sessionIndex} (${modeLabel}, ${strategyLabel})... ${elapsedSeconds}s`;
|
|
9017
|
+
}
|
|
9018
|
+
function ContextCompactionIndicator({
|
|
9019
|
+
compaction
|
|
9020
|
+
}) {
|
|
9021
|
+
const [elapsed, setElapsed] = useState13(
|
|
9022
|
+
() => Math.floor((Date.now() - compaction.startedAt) / 1e3)
|
|
9023
|
+
);
|
|
9024
|
+
useEffect13(() => {
|
|
9025
|
+
const start = compaction.startedAt;
|
|
9026
|
+
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
9027
|
+
const interval = setInterval(() => {
|
|
9028
|
+
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
9029
|
+
}, 1e3);
|
|
9030
|
+
return () => clearInterval(interval);
|
|
9031
|
+
}, [compaction.startedAt]);
|
|
9032
|
+
return /* @__PURE__ */ jsx12(Spinner5, { label: buildCompactionLabel(compaction, elapsed), color: theme12.warning });
|
|
9033
|
+
}
|
|
9034
|
+
|
|
8921
9035
|
// src/ink/marathon/ToolPanel.tsx
|
|
8922
|
-
import { useState as
|
|
9036
|
+
import { useState as useState14, useEffect as useEffect14, useMemo as useMemo2 } from "react";
|
|
8923
9037
|
import { Box as Box11, Text as Text12 } from "ink";
|
|
8924
|
-
import { Spinner as
|
|
9038
|
+
import { Spinner as Spinner6, theme as theme14 } from "@runtypelabs/ink-components";
|
|
8925
9039
|
|
|
8926
9040
|
// src/ink/marathon/ReasoningBlock.tsx
|
|
8927
9041
|
import { Box as Box10, Text as Text11 } from "ink";
|
|
8928
|
-
import { theme as
|
|
8929
|
-
import { jsx as
|
|
8930
|
-
var REASONING_LABEL_COLOR =
|
|
8931
|
-
var REASONING_TEXT_COLOR =
|
|
8932
|
-
var REASONING_HINT_COLOR =
|
|
9042
|
+
import { theme as theme13 } from "@runtypelabs/ink-components";
|
|
9043
|
+
import { jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
9044
|
+
var REASONING_LABEL_COLOR = theme13.accent;
|
|
9045
|
+
var REASONING_TEXT_COLOR = theme13.textMuted;
|
|
9046
|
+
var REASONING_HINT_COLOR = theme13.textSubtle;
|
|
8933
9047
|
function renderReasoningLine(line) {
|
|
8934
9048
|
return line ? `| ${line}` : "|";
|
|
8935
9049
|
}
|
|
@@ -8944,14 +9058,14 @@ function ReasoningBlock({
|
|
|
8944
9058
|
const hint = showToggleHint ? collapsed ? "r to show" : "r to hide" : null;
|
|
8945
9059
|
return /* @__PURE__ */ jsxs9(Box10, { flexDirection: "column", children: [
|
|
8946
9060
|
/* @__PURE__ */ jsxs9(Box10, { children: [
|
|
8947
|
-
/* @__PURE__ */
|
|
9061
|
+
/* @__PURE__ */ jsx13(Text11, { color: REASONING_LABEL_COLOR, children: label }),
|
|
8948
9062
|
hint && /* @__PURE__ */ jsxs9(Text11, { color: REASONING_HINT_COLOR, children: [
|
|
8949
9063
|
" (",
|
|
8950
9064
|
hint,
|
|
8951
9065
|
")"
|
|
8952
9066
|
] })
|
|
8953
9067
|
] }),
|
|
8954
|
-
!collapsed && lines.map((line, index) => /* @__PURE__ */
|
|
9068
|
+
!collapsed && lines.map((line, index) => /* @__PURE__ */ jsx13(
|
|
8955
9069
|
Text11,
|
|
8956
9070
|
{
|
|
8957
9071
|
color: REASONING_TEXT_COLOR,
|
|
@@ -8960,12 +9074,12 @@ function ReasoningBlock({
|
|
|
8960
9074
|
},
|
|
8961
9075
|
`${index}:${line}`
|
|
8962
9076
|
)),
|
|
8963
|
-
!collapsed && live && /* @__PURE__ */
|
|
9077
|
+
!collapsed && live && /* @__PURE__ */ jsx13(Text11, { color: REASONING_TEXT_COLOR, wrap: compact ? "truncate" : void 0, children: "| ..." })
|
|
8964
9078
|
] });
|
|
8965
9079
|
}
|
|
8966
9080
|
|
|
8967
9081
|
// src/ink/marathon/ToolPanel.tsx
|
|
8968
|
-
import { Fragment, jsx as
|
|
9082
|
+
import { Fragment, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
8969
9083
|
var REASONING_PREVIEW_LINES = 4;
|
|
8970
9084
|
var STATUS_ICONS = {
|
|
8971
9085
|
complete: "\u2713",
|
|
@@ -8983,18 +9097,18 @@ function formatElapsed(tool, now) {
|
|
|
8983
9097
|
return `${((now - tool.startedAt) / 1e3).toFixed(1)}s`;
|
|
8984
9098
|
}
|
|
8985
9099
|
function getStatusColor(status) {
|
|
8986
|
-
if (status === "error") return
|
|
8987
|
-
if (status === "complete") return
|
|
8988
|
-
return
|
|
9100
|
+
if (status === "error") return theme14.danger;
|
|
9101
|
+
if (status === "complete") return theme14.success;
|
|
9102
|
+
return theme14.accent;
|
|
8989
9103
|
}
|
|
8990
9104
|
function ToolPanel({ tools, reasoning, files, maxHeight }) {
|
|
8991
|
-
const [now, setNow] =
|
|
9105
|
+
const [now, setNow] = useState14(Date.now());
|
|
8992
9106
|
const hasRunning = tools.some((t) => t.status === "running");
|
|
8993
9107
|
const reasoningLines = useMemo2(
|
|
8994
9108
|
() => getVisibleReasoningLines(reasoning || "", REASONING_PREVIEW_LINES),
|
|
8995
9109
|
[reasoning]
|
|
8996
9110
|
);
|
|
8997
|
-
|
|
9111
|
+
useEffect14(() => {
|
|
8998
9112
|
if (!hasRunning) return;
|
|
8999
9113
|
const interval = setInterval(() => setNow(Date.now()), 100);
|
|
9000
9114
|
return () => clearInterval(interval);
|
|
@@ -9014,10 +9128,10 @@ function ToolPanel({ tools, reasoning, files, maxHeight }) {
|
|
|
9014
9128
|
}, [tools, files, maxHeight, reasoningLines]);
|
|
9015
9129
|
const hiddenToolCount = tools.length - visibleTools.length;
|
|
9016
9130
|
const hiddenFileCount = (files || []).length - visibleFiles.length;
|
|
9017
|
-
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", backgroundColor:
|
|
9018
|
-
reasoningLines.length > 0 && /* @__PURE__ */
|
|
9019
|
-
/* @__PURE__ */
|
|
9020
|
-
hiddenToolCount > 0 && /* @__PURE__ */ jsxs10(Text12, { color:
|
|
9131
|
+
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", backgroundColor: theme14.background, children: [
|
|
9132
|
+
reasoningLines.length > 0 && /* @__PURE__ */ jsx14(Box11, { flexDirection: "column", marginBottom: theme14.sectionGap, children: /* @__PURE__ */ jsx14(ReasoningBlock, { lines: reasoningLines, compact: true }) }),
|
|
9133
|
+
/* @__PURE__ */ jsx14(Text12, { bold: true, color: theme14.accent, children: "Activity" }),
|
|
9134
|
+
hiddenToolCount > 0 && /* @__PURE__ */ jsxs10(Text12, { color: theme14.textSubtle, children: [
|
|
9021
9135
|
" ",
|
|
9022
9136
|
hiddenToolCount,
|
|
9023
9137
|
" earlier hidden"
|
|
@@ -9026,9 +9140,9 @@ function ToolPanel({ tools, reasoning, files, maxHeight }) {
|
|
|
9026
9140
|
const statusColor = getStatusColor(tool.status);
|
|
9027
9141
|
const elapsed = formatElapsed(tool, now);
|
|
9028
9142
|
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9029
|
-
/* @__PURE__ */
|
|
9030
|
-
/* @__PURE__ */
|
|
9031
|
-
/* @__PURE__ */
|
|
9143
|
+
/* @__PURE__ */ jsx14(Box11, { width: 2, flexShrink: 0, children: tool.status === "running" ? /* @__PURE__ */ jsx14(Spinner6, { label: "", color: theme14.spinner }) : /* @__PURE__ */ jsx14(Text12, { color: statusColor, children: STATUS_ICONS[tool.status] || "?" }) }),
|
|
9144
|
+
/* @__PURE__ */ jsx14(Box11, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx14(Text12, { color: theme14.text, wrap: "truncate", children: tool.name }) }),
|
|
9145
|
+
/* @__PURE__ */ jsx14(Box11, { flexShrink: 0, children: /* @__PURE__ */ jsxs10(Text12, { color: theme14.textMuted, children: [
|
|
9032
9146
|
" ",
|
|
9033
9147
|
elapsed
|
|
9034
9148
|
] }) })
|
|
@@ -9036,8 +9150,8 @@ function ToolPanel({ tools, reasoning, files, maxHeight }) {
|
|
|
9036
9150
|
}),
|
|
9037
9151
|
visibleFiles.length > 0 && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
9038
9152
|
/* @__PURE__ */ jsxs10(Box11, { marginTop: 1, children: [
|
|
9039
|
-
/* @__PURE__ */
|
|
9040
|
-
hiddenFileCount > 0 && /* @__PURE__ */ jsxs10(Text12, { color:
|
|
9153
|
+
/* @__PURE__ */ jsx14(Text12, { bold: true, color: theme14.accent, children: "Files" }),
|
|
9154
|
+
hiddenFileCount > 0 && /* @__PURE__ */ jsxs10(Text12, { color: theme14.textSubtle, children: [
|
|
9041
9155
|
" +",
|
|
9042
9156
|
hiddenFileCount
|
|
9043
9157
|
] })
|
|
@@ -9046,8 +9160,8 @@ function ToolPanel({ tools, reasoning, files, maxHeight }) {
|
|
|
9046
9160
|
const icon = FILE_TYPE_ICONS[file.type] || "\u2022";
|
|
9047
9161
|
const filename = file.path.split("/").pop() || file.path;
|
|
9048
9162
|
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9049
|
-
/* @__PURE__ */
|
|
9050
|
-
/* @__PURE__ */
|
|
9163
|
+
/* @__PURE__ */ jsx14(Box11, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx14(Text12, { color: file.type === "written" ? theme14.success : theme14.textMuted, children: icon }) }),
|
|
9164
|
+
/* @__PURE__ */ jsx14(Box11, { flexShrink: 1, children: /* @__PURE__ */ jsx14(Text12, { color: theme14.text, wrap: "truncate", children: filename }) })
|
|
9051
9165
|
] }, file.path);
|
|
9052
9166
|
})
|
|
9053
9167
|
] })
|
|
@@ -9055,28 +9169,28 @@ function ToolPanel({ tools, reasoning, files, maxHeight }) {
|
|
|
9055
9169
|
}
|
|
9056
9170
|
|
|
9057
9171
|
// src/ink/marathon/ToolsPanel.tsx
|
|
9058
|
-
import { useState as
|
|
9172
|
+
import { useState as useState15, useEffect as useEffect15, useMemo as useMemo3 } from "react";
|
|
9059
9173
|
import { Box as Box13, Text as Text14 } from "ink";
|
|
9060
|
-
import { Spinner as
|
|
9174
|
+
import { Spinner as Spinner7, theme as theme16 } from "@runtypelabs/ink-components";
|
|
9061
9175
|
|
|
9062
9176
|
// src/ink/marathon/Scrollbar.tsx
|
|
9063
9177
|
import { Box as Box12, Text as Text13 } from "ink";
|
|
9064
|
-
import { theme as
|
|
9065
|
-
import { jsx as
|
|
9178
|
+
import { theme as theme15 } from "@runtypelabs/ink-components";
|
|
9179
|
+
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
9066
9180
|
function Scrollbar({ totalLines, visibleLines, scrollOffset, height }) {
|
|
9067
9181
|
if (totalLines <= visibleLines) return null;
|
|
9068
9182
|
const maxScroll = Math.max(0, totalLines - visibleLines);
|
|
9069
9183
|
const clampedOffset = Math.min(scrollOffset, maxScroll);
|
|
9070
9184
|
const thumbSize = Math.max(1, Math.round(visibleLines / totalLines * height));
|
|
9071
9185
|
const thumbStart = maxScroll > 0 ? Math.round(clampedOffset / maxScroll * (height - thumbSize)) : 0;
|
|
9072
|
-
return /* @__PURE__ */
|
|
9186
|
+
return /* @__PURE__ */ jsx15(Box12, { flexDirection: "column", marginLeft: 1, children: Array.from({ length: height }, (_, i) => {
|
|
9073
9187
|
const isThumb = i >= thumbStart && i < thumbStart + thumbSize;
|
|
9074
|
-
return /* @__PURE__ */
|
|
9188
|
+
return /* @__PURE__ */ jsx15(Text13, { color: isThumb ? theme15.textMuted : theme15.border, children: isThumb ? "\u2588" : "\u2502" }, i);
|
|
9075
9189
|
}) });
|
|
9076
9190
|
}
|
|
9077
9191
|
|
|
9078
9192
|
// src/ink/marathon/ToolsPanel.tsx
|
|
9079
|
-
import { jsx as
|
|
9193
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
9080
9194
|
function formatElapsed2(tool, now) {
|
|
9081
9195
|
if (tool.executionTime != null) {
|
|
9082
9196
|
return `${(tool.executionTime / 1e3).toFixed(1)}s`;
|
|
@@ -9088,9 +9202,9 @@ var STATUS_ICONS2 = {
|
|
|
9088
9202
|
error: "\u2717"
|
|
9089
9203
|
};
|
|
9090
9204
|
function getStatusColor2(status) {
|
|
9091
|
-
if (status === "error") return
|
|
9092
|
-
if (status === "complete") return
|
|
9093
|
-
return
|
|
9205
|
+
if (status === "error") return theme16.danger;
|
|
9206
|
+
if (status === "complete") return theme16.success;
|
|
9207
|
+
return theme16.accent;
|
|
9094
9208
|
}
|
|
9095
9209
|
function wrapLines(lines, width) {
|
|
9096
9210
|
if (width <= 0) return lines;
|
|
@@ -9141,7 +9255,7 @@ function ToolDetailView({
|
|
|
9141
9255
|
scrollOffset = 0,
|
|
9142
9256
|
width = 120
|
|
9143
9257
|
}) {
|
|
9144
|
-
const separator =
|
|
9258
|
+
const separator = theme16.separator ?? " \xB7 ";
|
|
9145
9259
|
const statusColor = getStatusColor2(tool.status);
|
|
9146
9260
|
const { lines, totalLines, clampedOffset } = useMemo3(() => {
|
|
9147
9261
|
const allLines = getToolDetailLines(tool, width);
|
|
@@ -9155,29 +9269,29 @@ function ToolDetailView({
|
|
|
9155
9269
|
Box13,
|
|
9156
9270
|
{
|
|
9157
9271
|
flexDirection: "column",
|
|
9158
|
-
paddingX:
|
|
9159
|
-
paddingY:
|
|
9272
|
+
paddingX: theme16.panelPaddingX,
|
|
9273
|
+
paddingY: theme16.panelPaddingY,
|
|
9160
9274
|
children: [
|
|
9161
|
-
/* @__PURE__ */ jsxs11(Box13, { marginBottom:
|
|
9162
|
-
tool.status === "running" ? /* @__PURE__ */
|
|
9163
|
-
/* @__PURE__ */
|
|
9164
|
-
/* @__PURE__ */
|
|
9165
|
-
/* @__PURE__ */ jsxs11(Text14, { color:
|
|
9275
|
+
/* @__PURE__ */ jsxs11(Box13, { marginBottom: theme16.sectionGap, children: [
|
|
9276
|
+
tool.status === "running" ? /* @__PURE__ */ jsx16(Spinner7, { label: "", color: theme16.spinner }) : /* @__PURE__ */ jsx16(Text14, { color: statusColor, children: STATUS_ICONS2[tool.status] || "?" }),
|
|
9277
|
+
/* @__PURE__ */ jsx16(Text14, { color: theme16.textMuted, children: ` [${tool.sequence}] ` }),
|
|
9278
|
+
/* @__PURE__ */ jsx16(Text14, { bold: true, color: theme16.text, children: tool.name }),
|
|
9279
|
+
/* @__PURE__ */ jsxs11(Text14, { color: theme16.textMuted, children: [
|
|
9166
9280
|
" ",
|
|
9167
9281
|
formatElapsed2(tool, now)
|
|
9168
9282
|
] }),
|
|
9169
|
-
/* @__PURE__ */ jsxs11(Text14, { color:
|
|
9283
|
+
/* @__PURE__ */ jsxs11(Text14, { color: theme16.textSubtle, children: [
|
|
9170
9284
|
separator,
|
|
9171
9285
|
"c: copy"
|
|
9172
9286
|
] }),
|
|
9173
|
-
/* @__PURE__ */ jsxs11(Text14, { color:
|
|
9287
|
+
/* @__PURE__ */ jsxs11(Text14, { color: theme16.textSubtle, children: [
|
|
9174
9288
|
separator,
|
|
9175
9289
|
"Esc: close"
|
|
9176
9290
|
] })
|
|
9177
9291
|
] }),
|
|
9178
9292
|
/* @__PURE__ */ jsxs11(Box13, { flexDirection: "row", flexGrow: 1, children: [
|
|
9179
|
-
/* @__PURE__ */
|
|
9180
|
-
/* @__PURE__ */
|
|
9293
|
+
/* @__PURE__ */ jsx16(Box13, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx16(Text14, { color: theme16.text, wrap: "truncate", children: line }, i)) }),
|
|
9294
|
+
/* @__PURE__ */ jsx16(
|
|
9181
9295
|
Scrollbar,
|
|
9182
9296
|
{
|
|
9183
9297
|
totalLines,
|
|
@@ -9199,10 +9313,10 @@ function ToolsPanel({
|
|
|
9199
9313
|
detailScrollOffset = 0,
|
|
9200
9314
|
width = 120
|
|
9201
9315
|
}) {
|
|
9202
|
-
const separator =
|
|
9203
|
-
const [now, setNow] =
|
|
9316
|
+
const separator = theme16.separator ?? " \xB7 ";
|
|
9317
|
+
const [now, setNow] = useState15(Date.now());
|
|
9204
9318
|
const hasRunning = tools.some((t) => t.status === "running");
|
|
9205
|
-
|
|
9319
|
+
useEffect15(() => {
|
|
9206
9320
|
if (!hasRunning) return;
|
|
9207
9321
|
const interval = setInterval(() => setNow(Date.now()), 100);
|
|
9208
9322
|
return () => clearInterval(interval);
|
|
@@ -9232,7 +9346,7 @@ function ToolsPanel({
|
|
|
9232
9346
|
};
|
|
9233
9347
|
}, [tools, maxVisibleLines, selectedIndex]);
|
|
9234
9348
|
if (detailTool) {
|
|
9235
|
-
return /* @__PURE__ */
|
|
9349
|
+
return /* @__PURE__ */ jsx16(
|
|
9236
9350
|
ToolDetailView,
|
|
9237
9351
|
{
|
|
9238
9352
|
tool: detailTool,
|
|
@@ -9244,13 +9358,13 @@ function ToolsPanel({
|
|
|
9244
9358
|
);
|
|
9245
9359
|
}
|
|
9246
9360
|
if (tools.length === 0) {
|
|
9247
|
-
return /* @__PURE__ */
|
|
9361
|
+
return /* @__PURE__ */ jsx16(
|
|
9248
9362
|
Box13,
|
|
9249
9363
|
{
|
|
9250
9364
|
flexDirection: "column",
|
|
9251
|
-
paddingX:
|
|
9252
|
-
paddingY:
|
|
9253
|
-
children: /* @__PURE__ */
|
|
9365
|
+
paddingX: theme16.panelPaddingX,
|
|
9366
|
+
paddingY: theme16.panelPaddingY,
|
|
9367
|
+
children: /* @__PURE__ */ jsx16(Text14, { color: theme16.textSubtle, children: "No tool calls yet..." })
|
|
9254
9368
|
}
|
|
9255
9369
|
);
|
|
9256
9370
|
}
|
|
@@ -9258,43 +9372,43 @@ function ToolsPanel({
|
|
|
9258
9372
|
Box13,
|
|
9259
9373
|
{
|
|
9260
9374
|
flexDirection: "column",
|
|
9261
|
-
paddingX:
|
|
9262
|
-
paddingY:
|
|
9375
|
+
paddingX: theme16.panelPaddingX,
|
|
9376
|
+
paddingY: theme16.panelPaddingY,
|
|
9263
9377
|
children: [
|
|
9264
9378
|
/* @__PURE__ */ jsxs11(Box13, { marginBottom: 0, children: [
|
|
9265
|
-
/* @__PURE__ */
|
|
9266
|
-
/* @__PURE__ */ jsxs11(Text14, { color:
|
|
9379
|
+
/* @__PURE__ */ jsx16(Text14, { bold: true, color: theme16.accent, children: "Tools" }),
|
|
9380
|
+
/* @__PURE__ */ jsxs11(Text14, { color: theme16.textSubtle, children: [
|
|
9267
9381
|
separator,
|
|
9268
9382
|
tools.length,
|
|
9269
9383
|
" calls"
|
|
9270
9384
|
] })
|
|
9271
9385
|
] }),
|
|
9272
9386
|
/* @__PURE__ */ jsxs11(Box13, { flexDirection: "row", children: [
|
|
9273
|
-
/* @__PURE__ */
|
|
9387
|
+
/* @__PURE__ */ jsx16(Box13, { flexDirection: "column", flexGrow: 1, children: rows.map((row) => {
|
|
9274
9388
|
const isSelected = row.globalIndex === selectedIndex;
|
|
9275
9389
|
const statusColor = getStatusColor2(row.tool.status);
|
|
9276
9390
|
const elapsed = formatElapsed2(row.tool, now);
|
|
9277
9391
|
return /* @__PURE__ */ jsxs11(Box13, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9278
|
-
/* @__PURE__ */
|
|
9279
|
-
/* @__PURE__ */
|
|
9280
|
-
/* @__PURE__ */
|
|
9392
|
+
/* @__PURE__ */ jsx16(Box13, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx16(Text14, { color: isSelected ? theme16.accentActive : theme16.textSubtle, children: isSelected ? "\u203A" : " " }) }),
|
|
9393
|
+
/* @__PURE__ */ jsx16(Box13, { width: 2, flexShrink: 0, children: row.tool.status === "running" ? /* @__PURE__ */ jsx16(Spinner7, { label: "", color: theme16.spinner }) : /* @__PURE__ */ jsx16(Text14, { color: statusColor, children: STATUS_ICONS2[row.tool.status] || "?" }) }),
|
|
9394
|
+
/* @__PURE__ */ jsx16(Box13, { width: 5, flexShrink: 0, children: /* @__PURE__ */ jsxs11(Text14, { color: theme16.textMuted, children: [
|
|
9281
9395
|
"[",
|
|
9282
9396
|
row.tool.sequence,
|
|
9283
9397
|
"] "
|
|
9284
9398
|
] }) }),
|
|
9285
|
-
/* @__PURE__ */
|
|
9399
|
+
/* @__PURE__ */ jsx16(Box13, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx16(
|
|
9286
9400
|
Text14,
|
|
9287
9401
|
{
|
|
9288
|
-
color: isSelected ?
|
|
9402
|
+
color: isSelected ? theme16.accentActive : theme16.text,
|
|
9289
9403
|
bold: isSelected,
|
|
9290
9404
|
wrap: "truncate",
|
|
9291
9405
|
children: row.tool.name
|
|
9292
9406
|
}
|
|
9293
9407
|
) }),
|
|
9294
|
-
/* @__PURE__ */
|
|
9408
|
+
/* @__PURE__ */ jsx16(Box13, { width: 7, flexShrink: 0, justifyContent: "flex-end", children: /* @__PURE__ */ jsx16(Text14, { color: theme16.textMuted, children: elapsed }) })
|
|
9295
9409
|
] }, row.key);
|
|
9296
9410
|
}) }),
|
|
9297
|
-
/* @__PURE__ */
|
|
9411
|
+
/* @__PURE__ */ jsx16(
|
|
9298
9412
|
Scrollbar,
|
|
9299
9413
|
{
|
|
9300
9414
|
totalLines: tools.length,
|
|
@@ -9312,19 +9426,22 @@ function ToolsPanel({
|
|
|
9312
9426
|
// src/ink/marathon/EventStreamPanel.tsx
|
|
9313
9427
|
import { useMemo as useMemo4 } from "react";
|
|
9314
9428
|
import { Box as Box14, Text as Text15 } from "ink";
|
|
9315
|
-
import { theme as
|
|
9316
|
-
import { jsx as
|
|
9429
|
+
import { theme as theme17 } from "@runtypelabs/ink-components";
|
|
9430
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
9317
9431
|
var EVENT_COLORS = {
|
|
9318
|
-
agent_start:
|
|
9319
|
-
agent_complete:
|
|
9320
|
-
agent_error:
|
|
9321
|
-
agent_await:
|
|
9322
|
-
agent_iteration_start:
|
|
9323
|
-
agent_iteration_complete:
|
|
9324
|
-
agent_turn_delta:
|
|
9325
|
-
agent_turn_complete:
|
|
9326
|
-
agent_tool_start:
|
|
9327
|
-
agent_tool_complete:
|
|
9432
|
+
agent_start: theme17.success,
|
|
9433
|
+
agent_complete: theme17.success,
|
|
9434
|
+
agent_error: theme17.danger,
|
|
9435
|
+
agent_await: theme17.warning,
|
|
9436
|
+
agent_iteration_start: theme17.accent,
|
|
9437
|
+
agent_iteration_complete: theme17.accent,
|
|
9438
|
+
agent_turn_delta: theme17.textMuted,
|
|
9439
|
+
agent_turn_complete: theme17.accentActive,
|
|
9440
|
+
agent_tool_start: theme17.warning,
|
|
9441
|
+
agent_tool_complete: theme17.warning,
|
|
9442
|
+
marathon_context_compaction_start: theme17.warning,
|
|
9443
|
+
marathon_context_compaction_complete: theme17.success,
|
|
9444
|
+
marathon_context_notice: theme17.warning
|
|
9328
9445
|
};
|
|
9329
9446
|
function formatTimestamp(ts, start) {
|
|
9330
9447
|
if (!start) return "0.000s";
|
|
@@ -9369,7 +9486,7 @@ function EventDetailView({
|
|
|
9369
9486
|
scrollOffset = 0,
|
|
9370
9487
|
width = 120
|
|
9371
9488
|
}) {
|
|
9372
|
-
const separator =
|
|
9489
|
+
const separator = theme17.separator ?? " \xB7 ";
|
|
9373
9490
|
const { lines, totalLines, clampedOffset } = useMemo4(() => {
|
|
9374
9491
|
const allLines = getEventDetailLines(event, width);
|
|
9375
9492
|
const total = allLines.length;
|
|
@@ -9378,32 +9495,32 @@ function EventDetailView({
|
|
|
9378
9495
|
const end = Math.min(total, start + maxVisibleLines);
|
|
9379
9496
|
return { lines: allLines.slice(start, end), totalLines: total, clampedOffset: clamped };
|
|
9380
9497
|
}, [event, maxVisibleLines, scrollOffset, width]);
|
|
9381
|
-
const color = EVENT_COLORS[event.type] ||
|
|
9498
|
+
const color = EVENT_COLORS[event.type] || theme17.text;
|
|
9382
9499
|
return /* @__PURE__ */ jsxs12(
|
|
9383
9500
|
Box14,
|
|
9384
9501
|
{
|
|
9385
9502
|
flexDirection: "column",
|
|
9386
|
-
paddingX:
|
|
9387
|
-
paddingY:
|
|
9503
|
+
paddingX: theme17.panelPaddingX,
|
|
9504
|
+
paddingY: theme17.panelPaddingY,
|
|
9388
9505
|
children: [
|
|
9389
|
-
/* @__PURE__ */ jsxs12(Box14, { marginBottom:
|
|
9390
|
-
/* @__PURE__ */ jsxs12(Text15, { color:
|
|
9506
|
+
/* @__PURE__ */ jsxs12(Box14, { marginBottom: theme17.sectionGap, children: [
|
|
9507
|
+
/* @__PURE__ */ jsxs12(Text15, { color: theme17.textMuted, children: [
|
|
9391
9508
|
formatTimestamp(event.timestamp, startTime),
|
|
9392
9509
|
" "
|
|
9393
9510
|
] }),
|
|
9394
|
-
/* @__PURE__ */
|
|
9395
|
-
/* @__PURE__ */ jsxs12(Text15, { color:
|
|
9511
|
+
/* @__PURE__ */ jsx17(Text15, { bold: true, color, children: event.type }),
|
|
9512
|
+
/* @__PURE__ */ jsxs12(Text15, { color: theme17.textSubtle, children: [
|
|
9396
9513
|
separator,
|
|
9397
9514
|
"c: copy"
|
|
9398
9515
|
] }),
|
|
9399
|
-
/* @__PURE__ */ jsxs12(Text15, { color:
|
|
9516
|
+
/* @__PURE__ */ jsxs12(Text15, { color: theme17.textSubtle, children: [
|
|
9400
9517
|
separator,
|
|
9401
9518
|
"Esc: close"
|
|
9402
9519
|
] })
|
|
9403
9520
|
] }),
|
|
9404
9521
|
/* @__PURE__ */ jsxs12(Box14, { flexDirection: "row", flexGrow: 1, children: [
|
|
9405
|
-
/* @__PURE__ */
|
|
9406
|
-
/* @__PURE__ */
|
|
9522
|
+
/* @__PURE__ */ jsx17(Box14, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx17(Text15, { color: theme17.text, wrap: "truncate", children: line }, i)) }),
|
|
9523
|
+
/* @__PURE__ */ jsx17(
|
|
9407
9524
|
Scrollbar,
|
|
9408
9525
|
{
|
|
9409
9526
|
totalLines,
|
|
@@ -9426,7 +9543,7 @@ function EventStreamPanel({
|
|
|
9426
9543
|
detailScrollOffset = 0,
|
|
9427
9544
|
width = 120
|
|
9428
9545
|
}) {
|
|
9429
|
-
const separator =
|
|
9546
|
+
const separator = theme17.separator ?? " \xB7 ";
|
|
9430
9547
|
const { rows, hiddenAbove } = useMemo4(() => {
|
|
9431
9548
|
if (events.length === 0) return { rows: [], hiddenAbove: 0 };
|
|
9432
9549
|
const total = events.length;
|
|
@@ -9448,14 +9565,14 @@ function EventStreamPanel({
|
|
|
9448
9565
|
key: `${start + i}`,
|
|
9449
9566
|
time: formatTimestamp(evt.timestamp, startTime),
|
|
9450
9567
|
type: evt.type,
|
|
9451
|
-
color: EVENT_COLORS[evt.type] ||
|
|
9568
|
+
color: EVENT_COLORS[evt.type] || theme17.text,
|
|
9452
9569
|
data: formatEventData(evt.data)
|
|
9453
9570
|
})),
|
|
9454
9571
|
hiddenAbove: start
|
|
9455
9572
|
};
|
|
9456
9573
|
}, [events, startTime, maxVisibleLines, selectedIndex]);
|
|
9457
9574
|
if (detailEvent) {
|
|
9458
|
-
return /* @__PURE__ */
|
|
9575
|
+
return /* @__PURE__ */ jsx17(
|
|
9459
9576
|
EventDetailView,
|
|
9460
9577
|
{
|
|
9461
9578
|
event: detailEvent,
|
|
@@ -9467,13 +9584,13 @@ function EventStreamPanel({
|
|
|
9467
9584
|
);
|
|
9468
9585
|
}
|
|
9469
9586
|
if (events.length === 0) {
|
|
9470
|
-
return /* @__PURE__ */
|
|
9587
|
+
return /* @__PURE__ */ jsx17(
|
|
9471
9588
|
Box14,
|
|
9472
9589
|
{
|
|
9473
9590
|
flexDirection: "column",
|
|
9474
|
-
paddingX:
|
|
9475
|
-
paddingY:
|
|
9476
|
-
children: /* @__PURE__ */
|
|
9591
|
+
paddingX: theme17.panelPaddingX,
|
|
9592
|
+
paddingY: theme17.panelPaddingY,
|
|
9593
|
+
children: /* @__PURE__ */ jsx17(Text15, { color: theme17.textSubtle, children: "Waiting for events..." })
|
|
9477
9594
|
}
|
|
9478
9595
|
);
|
|
9479
9596
|
}
|
|
@@ -9481,28 +9598,28 @@ function EventStreamPanel({
|
|
|
9481
9598
|
Box14,
|
|
9482
9599
|
{
|
|
9483
9600
|
flexDirection: "column",
|
|
9484
|
-
paddingX:
|
|
9485
|
-
paddingY:
|
|
9601
|
+
paddingX: theme17.panelPaddingX,
|
|
9602
|
+
paddingY: theme17.panelPaddingY,
|
|
9486
9603
|
children: [
|
|
9487
9604
|
/* @__PURE__ */ jsxs12(Box14, { marginBottom: 0, children: [
|
|
9488
|
-
/* @__PURE__ */
|
|
9489
|
-
/* @__PURE__ */ jsxs12(Text15, { color:
|
|
9605
|
+
/* @__PURE__ */ jsx17(Text15, { bold: true, color: theme17.accent, children: "Event Stream" }),
|
|
9606
|
+
/* @__PURE__ */ jsxs12(Text15, { color: theme17.textSubtle, children: [
|
|
9490
9607
|
separator,
|
|
9491
9608
|
events.length,
|
|
9492
9609
|
" events"
|
|
9493
9610
|
] })
|
|
9494
9611
|
] }),
|
|
9495
9612
|
/* @__PURE__ */ jsxs12(Box14, { flexDirection: "row", children: [
|
|
9496
|
-
/* @__PURE__ */
|
|
9613
|
+
/* @__PURE__ */ jsx17(Box14, { flexDirection: "column", flexGrow: 1, children: rows.map((row) => {
|
|
9497
9614
|
const isSelected = row.globalIndex === selectedIndex;
|
|
9498
9615
|
return /* @__PURE__ */ jsxs12(Box14, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9499
|
-
/* @__PURE__ */
|
|
9500
|
-
/* @__PURE__ */
|
|
9501
|
-
/* @__PURE__ */
|
|
9502
|
-
/* @__PURE__ */
|
|
9616
|
+
/* @__PURE__ */ jsx17(Box14, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx17(Text15, { color: isSelected ? theme17.accentActive : theme17.textSubtle, children: isSelected ? "\u203A" : " " }) }),
|
|
9617
|
+
/* @__PURE__ */ jsx17(Box14, { width: 9, flexShrink: 0, children: /* @__PURE__ */ jsx17(Text15, { color: theme17.textMuted, children: row.time }) }),
|
|
9618
|
+
/* @__PURE__ */ jsx17(Box14, { width: 28, flexShrink: 0, children: /* @__PURE__ */ jsx17(Text15, { color: isSelected ? theme17.accentActive : row.color, bold: isSelected, children: row.type }) }),
|
|
9619
|
+
/* @__PURE__ */ jsx17(Box14, { flexShrink: 1, children: /* @__PURE__ */ jsx17(Text15, { color: theme17.textMuted, wrap: "truncate", children: row.data }) })
|
|
9503
9620
|
] }, row.key);
|
|
9504
9621
|
}) }),
|
|
9505
|
-
/* @__PURE__ */
|
|
9622
|
+
/* @__PURE__ */ jsx17(
|
|
9506
9623
|
Scrollbar,
|
|
9507
9624
|
{
|
|
9508
9625
|
totalLines: events.length,
|
|
@@ -9520,12 +9637,12 @@ function EventStreamPanel({
|
|
|
9520
9637
|
// src/ink/marathon/FilesPanel.tsx
|
|
9521
9638
|
import { useMemo as useMemo5 } from "react";
|
|
9522
9639
|
import { Box as Box15, Text as Text16 } from "ink";
|
|
9523
|
-
import { theme as
|
|
9524
|
-
import { jsx as
|
|
9640
|
+
import { theme as theme18, renderMarkdownToTerminal } from "@runtypelabs/ink-components";
|
|
9641
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
9525
9642
|
var TYPE_COLORS = {
|
|
9526
|
-
plan:
|
|
9527
|
-
written:
|
|
9528
|
-
read:
|
|
9643
|
+
plan: theme18.accent,
|
|
9644
|
+
written: theme18.success,
|
|
9645
|
+
read: theme18.textMuted
|
|
9529
9646
|
};
|
|
9530
9647
|
var TYPE_LABELS = {
|
|
9531
9648
|
plan: "plan",
|
|
@@ -9597,7 +9714,7 @@ function FileContentView({
|
|
|
9597
9714
|
scrollOffset = 0,
|
|
9598
9715
|
width = 120
|
|
9599
9716
|
}) {
|
|
9600
|
-
const separator =
|
|
9717
|
+
const separator = theme18.separator ?? " \xB7 ";
|
|
9601
9718
|
const contentWidth = Math.max(20, width - 4);
|
|
9602
9719
|
const isMd = isMarkdownFile(file.path);
|
|
9603
9720
|
const { lines, displayTotalLines, clampedOffset } = useMemo5(() => {
|
|
@@ -9615,32 +9732,32 @@ function FileContentView({
|
|
|
9615
9732
|
Box15,
|
|
9616
9733
|
{
|
|
9617
9734
|
flexDirection: "column",
|
|
9618
|
-
paddingX:
|
|
9619
|
-
paddingY:
|
|
9735
|
+
paddingX: theme18.panelPaddingX,
|
|
9736
|
+
paddingY: theme18.panelPaddingY,
|
|
9620
9737
|
children: [
|
|
9621
|
-
/* @__PURE__ */ jsxs13(Box15, { marginBottom:
|
|
9622
|
-
/* @__PURE__ */
|
|
9623
|
-
/* @__PURE__ */ jsxs13(Text16, { color:
|
|
9738
|
+
/* @__PURE__ */ jsxs13(Box15, { marginBottom: theme18.sectionGap, children: [
|
|
9739
|
+
/* @__PURE__ */ jsx18(Text16, { bold: true, color: theme18.accent, children: filename }),
|
|
9740
|
+
/* @__PURE__ */ jsxs13(Text16, { color: theme18.textSubtle, children: [
|
|
9624
9741
|
separator,
|
|
9625
9742
|
totalLines,
|
|
9626
9743
|
" lines"
|
|
9627
9744
|
] }),
|
|
9628
|
-
truncated && /* @__PURE__ */ jsxs13(Text16, { color:
|
|
9745
|
+
truncated && /* @__PURE__ */ jsxs13(Text16, { color: theme18.warning, children: [
|
|
9629
9746
|
separator,
|
|
9630
9747
|
"truncated"
|
|
9631
9748
|
] }),
|
|
9632
|
-
/* @__PURE__ */ jsxs13(Text16, { color:
|
|
9749
|
+
/* @__PURE__ */ jsxs13(Text16, { color: theme18.textSubtle, children: [
|
|
9633
9750
|
separator,
|
|
9634
9751
|
"c: copy"
|
|
9635
9752
|
] }),
|
|
9636
|
-
/* @__PURE__ */ jsxs13(Text16, { color:
|
|
9753
|
+
/* @__PURE__ */ jsxs13(Text16, { color: theme18.textSubtle, children: [
|
|
9637
9754
|
separator,
|
|
9638
9755
|
"Esc: back"
|
|
9639
9756
|
] })
|
|
9640
9757
|
] }),
|
|
9641
9758
|
/* @__PURE__ */ jsxs13(Box15, { flexDirection: "row", flexGrow: 1, children: [
|
|
9642
|
-
/* @__PURE__ */
|
|
9643
|
-
/* @__PURE__ */
|
|
9759
|
+
/* @__PURE__ */ jsx18(Box15, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx18(Text16, { color: theme18.text, wrap: "truncate", children: line }, i)) }),
|
|
9760
|
+
/* @__PURE__ */ jsx18(
|
|
9644
9761
|
Scrollbar,
|
|
9645
9762
|
{
|
|
9646
9763
|
totalLines: displayTotalLines,
|
|
@@ -9665,9 +9782,9 @@ function FilesPanel({
|
|
|
9665
9782
|
detailScrollOffset = 0,
|
|
9666
9783
|
width = 120
|
|
9667
9784
|
}) {
|
|
9668
|
-
const separator =
|
|
9785
|
+
const separator = theme18.separator ?? " \xB7 ";
|
|
9669
9786
|
if (detailFile && detailContent !== null) {
|
|
9670
|
-
return /* @__PURE__ */
|
|
9787
|
+
return /* @__PURE__ */ jsx18(
|
|
9671
9788
|
FileContentView,
|
|
9672
9789
|
{
|
|
9673
9790
|
file: detailFile,
|
|
@@ -9705,13 +9822,13 @@ function FilesPanel({
|
|
|
9705
9822
|
};
|
|
9706
9823
|
}, [files, maxVisibleLines, selectedIndex]);
|
|
9707
9824
|
if (files.length === 0) {
|
|
9708
|
-
return /* @__PURE__ */
|
|
9825
|
+
return /* @__PURE__ */ jsx18(
|
|
9709
9826
|
Box15,
|
|
9710
9827
|
{
|
|
9711
9828
|
flexDirection: "column",
|
|
9712
|
-
paddingX:
|
|
9713
|
-
paddingY:
|
|
9714
|
-
children: /* @__PURE__ */
|
|
9829
|
+
paddingX: theme18.panelPaddingX,
|
|
9830
|
+
paddingY: theme18.panelPaddingY,
|
|
9831
|
+
children: /* @__PURE__ */ jsx18(Text16, { color: theme18.textSubtle, children: "No files tracked yet..." })
|
|
9715
9832
|
}
|
|
9716
9833
|
);
|
|
9717
9834
|
}
|
|
@@ -9719,33 +9836,33 @@ function FilesPanel({
|
|
|
9719
9836
|
Box15,
|
|
9720
9837
|
{
|
|
9721
9838
|
flexDirection: "column",
|
|
9722
|
-
paddingX:
|
|
9723
|
-
paddingY:
|
|
9839
|
+
paddingX: theme18.panelPaddingX,
|
|
9840
|
+
paddingY: theme18.panelPaddingY,
|
|
9724
9841
|
children: [
|
|
9725
9842
|
/* @__PURE__ */ jsxs13(Box15, { marginBottom: 0, children: [
|
|
9726
|
-
/* @__PURE__ */
|
|
9727
|
-
/* @__PURE__ */ jsxs13(Text16, { color:
|
|
9843
|
+
/* @__PURE__ */ jsx18(Text16, { bold: true, color: theme18.accent, children: "Files" }),
|
|
9844
|
+
/* @__PURE__ */ jsxs13(Text16, { color: theme18.textSubtle, children: [
|
|
9728
9845
|
separator,
|
|
9729
9846
|
files.length,
|
|
9730
9847
|
" files"
|
|
9731
9848
|
] })
|
|
9732
9849
|
] }),
|
|
9733
9850
|
/* @__PURE__ */ jsxs13(Box15, { flexDirection: "row", children: [
|
|
9734
|
-
/* @__PURE__ */
|
|
9851
|
+
/* @__PURE__ */ jsx18(Box15, { flexDirection: "column", flexGrow: 1, children: rows.map((row) => {
|
|
9735
9852
|
const isSelected = row.globalIndex === selectedIndex;
|
|
9736
|
-
const typeColor = TYPE_COLORS[row.file.type] ||
|
|
9853
|
+
const typeColor = TYPE_COLORS[row.file.type] || theme18.text;
|
|
9737
9854
|
const typeLabel = TYPE_LABELS[row.file.type] || row.file.type;
|
|
9738
9855
|
return /* @__PURE__ */ jsxs13(Box15, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9739
|
-
/* @__PURE__ */
|
|
9740
|
-
/* @__PURE__ */
|
|
9856
|
+
/* @__PURE__ */ jsx18(Box15, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx18(Text16, { color: isSelected ? theme18.accentActive : theme18.textSubtle, children: isSelected ? "\u203A" : " " }) }),
|
|
9857
|
+
/* @__PURE__ */ jsx18(Box15, { width: 8, flexShrink: 0, children: /* @__PURE__ */ jsxs13(Text16, { color: typeColor, children: [
|
|
9741
9858
|
"[",
|
|
9742
9859
|
typeLabel,
|
|
9743
9860
|
"]"
|
|
9744
9861
|
] }) }),
|
|
9745
|
-
/* @__PURE__ */
|
|
9862
|
+
/* @__PURE__ */ jsx18(Box15, { flexShrink: 1, children: /* @__PURE__ */ jsx18(
|
|
9746
9863
|
Text16,
|
|
9747
9864
|
{
|
|
9748
|
-
color: isSelected ?
|
|
9865
|
+
color: isSelected ? theme18.accentActive : theme18.text,
|
|
9749
9866
|
bold: isSelected,
|
|
9750
9867
|
wrap: "truncate",
|
|
9751
9868
|
children: shortenPath(row.file.path, 80)
|
|
@@ -9753,7 +9870,7 @@ function FilesPanel({
|
|
|
9753
9870
|
) })
|
|
9754
9871
|
] }, row.key);
|
|
9755
9872
|
}) }),
|
|
9756
|
-
/* @__PURE__ */
|
|
9873
|
+
/* @__PURE__ */ jsx18(
|
|
9757
9874
|
Scrollbar,
|
|
9758
9875
|
{
|
|
9759
9876
|
totalLines: files.length,
|
|
@@ -9771,8 +9888,8 @@ function FilesPanel({
|
|
|
9771
9888
|
// src/ink/marathon/HelpPanel.tsx
|
|
9772
9889
|
import { useMemo as useMemo6 } from "react";
|
|
9773
9890
|
import { Box as Box16, Text as Text17 } from "ink";
|
|
9774
|
-
import { theme as
|
|
9775
|
-
import { Fragment as Fragment2, jsx as
|
|
9891
|
+
import { theme as theme19 } from "@runtypelabs/ink-components";
|
|
9892
|
+
import { Fragment as Fragment2, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
9776
9893
|
var NAVIGATION_SHORTCUTS = [
|
|
9777
9894
|
{ key: "Tab", desc: "Next screen" },
|
|
9778
9895
|
{ key: "Esc", desc: "Back / close detail / close help" },
|
|
@@ -9850,26 +9967,26 @@ function HelpPanel({ width, height, isSteering, scrollOffset }) {
|
|
|
9850
9967
|
height: Math.min(height - 2, isSteering ? 38 : 28),
|
|
9851
9968
|
flexDirection: "column",
|
|
9852
9969
|
borderStyle: "round",
|
|
9853
|
-
borderColor:
|
|
9854
|
-
backgroundColor:
|
|
9970
|
+
borderColor: theme19.accent,
|
|
9971
|
+
backgroundColor: theme19.surfaceElevated,
|
|
9855
9972
|
paddingX: 2,
|
|
9856
9973
|
paddingY: 1,
|
|
9857
9974
|
children: [
|
|
9858
|
-
/* @__PURE__ */
|
|
9975
|
+
/* @__PURE__ */ jsx19(Text17, { bold: true, color: theme19.accent, children: "Keyboard Shortcuts" }),
|
|
9859
9976
|
/* @__PURE__ */ jsxs14(Box16, { flexDirection: "row", flexGrow: 1, marginTop: 1, children: [
|
|
9860
|
-
/* @__PURE__ */
|
|
9977
|
+
/* @__PURE__ */ jsx19(Box16, { flexDirection: "column", flexGrow: 1, children: visibleLines.map((line, idx) => {
|
|
9861
9978
|
if (line.type === "header") {
|
|
9862
|
-
return /* @__PURE__ */
|
|
9979
|
+
return /* @__PURE__ */ jsx19(Text17, { bold: true, color: theme19.accentActive, children: line.title }, idx);
|
|
9863
9980
|
}
|
|
9864
9981
|
if (line.type === "item") {
|
|
9865
9982
|
return /* @__PURE__ */ jsxs14(Text17, { children: [
|
|
9866
|
-
/* @__PURE__ */
|
|
9867
|
-
/* @__PURE__ */
|
|
9983
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.textSubtle, children: ` ${line.key.padEnd(16)}` }),
|
|
9984
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.textMuted, children: line.desc })
|
|
9868
9985
|
] }, idx);
|
|
9869
9986
|
}
|
|
9870
|
-
return /* @__PURE__ */
|
|
9987
|
+
return /* @__PURE__ */ jsx19(Text17, { children: " " }, idx);
|
|
9871
9988
|
}) }),
|
|
9872
|
-
/* @__PURE__ */
|
|
9989
|
+
/* @__PURE__ */ jsx19(
|
|
9873
9990
|
Scrollbar,
|
|
9874
9991
|
{
|
|
9875
9992
|
totalLines: allLines.length,
|
|
@@ -9880,14 +9997,14 @@ function HelpPanel({ width, height, isSteering, scrollOffset }) {
|
|
|
9880
9997
|
)
|
|
9881
9998
|
] }),
|
|
9882
9999
|
/* @__PURE__ */ jsxs14(Box16, { marginTop: 1, children: [
|
|
9883
|
-
/* @__PURE__ */
|
|
9884
|
-
/* @__PURE__ */
|
|
9885
|
-
/* @__PURE__ */
|
|
9886
|
-
/* @__PURE__ */
|
|
10000
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.info, children: "Esc" }),
|
|
10001
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.muted, children: " or " }),
|
|
10002
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.info, children: "?" }),
|
|
10003
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.muted, children: " to close" }),
|
|
9887
10004
|
isSteering && /* @__PURE__ */ jsxs14(Fragment2, { children: [
|
|
9888
|
-
/* @__PURE__ */
|
|
9889
|
-
/* @__PURE__ */
|
|
9890
|
-
/* @__PURE__ */
|
|
10005
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.muted, children: " (use " }),
|
|
10006
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.info, children: "/help" }),
|
|
10007
|
+
/* @__PURE__ */ jsx19(Text17, { color: theme19.muted, children: " during steering)" })
|
|
9891
10008
|
] })
|
|
9892
10009
|
] })
|
|
9893
10010
|
]
|
|
@@ -9951,14 +10068,14 @@ function readFileContent(filePath, maxLines = 5e3) {
|
|
|
9951
10068
|
}
|
|
9952
10069
|
|
|
9953
10070
|
// src/ink/marathon/SteeringPrompt.tsx
|
|
9954
|
-
import { useState as
|
|
10071
|
+
import { useState as useState20, useEffect as useEffect19, useRef as useRef7 } from "react";
|
|
9955
10072
|
import { Box as Box21, Text as Text23 } from "ink";
|
|
9956
10073
|
|
|
9957
10074
|
// src/ink/marathon/BlinkingTextInput.tsx
|
|
9958
|
-
import { useState as
|
|
10075
|
+
import { useState as useState16, useEffect as useEffect16, useRef as useRef5 } from "react";
|
|
9959
10076
|
import { Text as Text18, useInput as useInput5 } from "ink";
|
|
9960
10077
|
import chalk11 from "chalk";
|
|
9961
|
-
import { jsx as
|
|
10078
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
9962
10079
|
var CURSOR_BLINK_MS = 800;
|
|
9963
10080
|
function BlinkingTextInput({
|
|
9964
10081
|
value: originalValue,
|
|
@@ -9971,14 +10088,14 @@ function BlinkingTextInput({
|
|
|
9971
10088
|
onChange,
|
|
9972
10089
|
onSubmit
|
|
9973
10090
|
}) {
|
|
9974
|
-
const [state, setState] =
|
|
10091
|
+
const [state, setState] = useState16({
|
|
9975
10092
|
cursorOffset: (originalValue || "").length,
|
|
9976
10093
|
cursorWidth: 0
|
|
9977
10094
|
});
|
|
9978
|
-
const [blinkVisible, setBlinkVisible] =
|
|
10095
|
+
const [blinkVisible, setBlinkVisible] = useState16(true);
|
|
9979
10096
|
const blinkRef = useRef5(null);
|
|
9980
10097
|
const { cursorOffset, cursorWidth } = state;
|
|
9981
|
-
|
|
10098
|
+
useEffect16(() => {
|
|
9982
10099
|
if (!focus || !showCursor || !blinkCursor) {
|
|
9983
10100
|
setBlinkVisible(true);
|
|
9984
10101
|
return;
|
|
@@ -9993,10 +10110,10 @@ function BlinkingTextInput({
|
|
|
9993
10110
|
}
|
|
9994
10111
|
};
|
|
9995
10112
|
}, [focus, showCursor, blinkCursor]);
|
|
9996
|
-
|
|
10113
|
+
useEffect16(() => {
|
|
9997
10114
|
setBlinkVisible(true);
|
|
9998
10115
|
}, [originalValue, cursorOffset]);
|
|
9999
|
-
|
|
10116
|
+
useEffect16(() => {
|
|
10000
10117
|
setState((previousState) => {
|
|
10001
10118
|
if (!focus || !showCursor) {
|
|
10002
10119
|
return previousState;
|
|
@@ -10082,20 +10199,20 @@ function BlinkingTextInput({
|
|
|
10082
10199
|
},
|
|
10083
10200
|
{ isActive: focus }
|
|
10084
10201
|
);
|
|
10085
|
-
return /* @__PURE__ */
|
|
10202
|
+
return /* @__PURE__ */ jsx20(Text18, { children: placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue });
|
|
10086
10203
|
}
|
|
10087
10204
|
|
|
10088
10205
|
// src/ink/marathon/SteeringPrompt.tsx
|
|
10089
|
-
import { theme as
|
|
10206
|
+
import { theme as theme24 } from "@runtypelabs/ink-components";
|
|
10090
10207
|
|
|
10091
10208
|
// src/ink/talk/ModelPicker.tsx
|
|
10092
|
-
import { useState as
|
|
10209
|
+
import { useState as useState17, useMemo as useMemo7, useCallback as useCallback4, useEffect as useEffect17 } from "react";
|
|
10093
10210
|
import { Box as Box17, Text as Text19, useInput as useInput6, useStdout } from "ink";
|
|
10094
10211
|
import TextInput2 from "ink-text-input";
|
|
10095
10212
|
import open3 from "open";
|
|
10096
|
-
import { theme as
|
|
10097
|
-
import { jsx as
|
|
10098
|
-
var
|
|
10213
|
+
import { theme as theme20 } from "@runtypelabs/ink-components";
|
|
10214
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
10215
|
+
var DEFAULT_MODELS = [
|
|
10099
10216
|
// Anthropic
|
|
10100
10217
|
{ label: "Claude Opus 4.6", value: "claude-opus-4-6", group: "Anthropic" },
|
|
10101
10218
|
{ label: "Claude Sonnet 4.6", value: "claude-sonnet-4-6", group: "Anthropic" },
|
|
@@ -10126,27 +10243,39 @@ var ALL_MODELS = [
|
|
|
10126
10243
|
{ label: "Qwen 3 8B", value: "qwen/qwen3-8b", group: "Qwen" }
|
|
10127
10244
|
];
|
|
10128
10245
|
var MAX_VISIBLE = 12;
|
|
10129
|
-
function ModelPicker({ currentModel, onSelect, onCancel }) {
|
|
10246
|
+
function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
10130
10247
|
const { stdout } = useStdout();
|
|
10131
|
-
const [search, setSearch] =
|
|
10132
|
-
const
|
|
10248
|
+
const [search, setSearch] = useState17("");
|
|
10249
|
+
const availableModels = models && models.length > 0 ? models : DEFAULT_MODELS;
|
|
10133
10250
|
const contentWidth = (stdout?.columns ?? 120) - 4;
|
|
10134
10251
|
const pad = useCallback4(
|
|
10135
10252
|
(text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text,
|
|
10136
10253
|
[contentWidth]
|
|
10137
10254
|
);
|
|
10138
10255
|
const filtered = useMemo7(() => {
|
|
10139
|
-
if (!search.trim()) return
|
|
10256
|
+
if (!search.trim()) return availableModels;
|
|
10140
10257
|
const q = search.toLowerCase();
|
|
10141
|
-
return
|
|
10258
|
+
return availableModels.filter(
|
|
10142
10259
|
(m) => m.label.toLowerCase().includes(q) || m.value.toLowerCase().includes(q) || m.group.toLowerCase().includes(q)
|
|
10143
10260
|
);
|
|
10144
|
-
}, [search]);
|
|
10261
|
+
}, [availableModels, search]);
|
|
10262
|
+
const [selectedIndex, setSelectedIndex] = useState17(() => {
|
|
10263
|
+
const currentIndex = availableModels.findIndex((model) => model.value === currentModel);
|
|
10264
|
+
return currentIndex >= 0 ? currentIndex : 0;
|
|
10265
|
+
});
|
|
10145
10266
|
const handleSearchChange = (value) => {
|
|
10146
10267
|
if (value === search) return;
|
|
10147
10268
|
setSearch(value);
|
|
10148
10269
|
setSelectedIndex(0);
|
|
10149
10270
|
};
|
|
10271
|
+
useEffect17(() => {
|
|
10272
|
+
if (!search.trim()) {
|
|
10273
|
+
const currentIndex = filtered.findIndex((model) => model.value === currentModel);
|
|
10274
|
+
setSelectedIndex(currentIndex >= 0 ? currentIndex : 0);
|
|
10275
|
+
return;
|
|
10276
|
+
}
|
|
10277
|
+
setSelectedIndex((prev) => Math.min(prev, Math.max(0, filtered.length - 1)));
|
|
10278
|
+
}, [currentModel, filtered, search]);
|
|
10150
10279
|
useInput6((_input, key) => {
|
|
10151
10280
|
if (key.escape) {
|
|
10152
10281
|
onCancel();
|
|
@@ -10201,23 +10330,23 @@ function ModelPicker({ currentModel, onSelect, onCancel }) {
|
|
|
10201
10330
|
Box17,
|
|
10202
10331
|
{
|
|
10203
10332
|
borderStyle: "single",
|
|
10204
|
-
borderColor:
|
|
10205
|
-
backgroundColor:
|
|
10206
|
-
paddingX:
|
|
10207
|
-
paddingY:
|
|
10333
|
+
borderColor: theme20.border,
|
|
10334
|
+
backgroundColor: theme20.surfaceElevated,
|
|
10335
|
+
paddingX: theme20.panelPaddingX,
|
|
10336
|
+
paddingY: theme20.panelPaddingY,
|
|
10208
10337
|
flexDirection: "column",
|
|
10209
10338
|
children: [
|
|
10210
10339
|
/* @__PURE__ */ jsxs15(Box17, { marginBottom: 1, children: [
|
|
10211
|
-
/* @__PURE__ */
|
|
10212
|
-
/* @__PURE__ */ jsxs15(Text19, { color:
|
|
10340
|
+
/* @__PURE__ */ jsx21(Text19, { color: theme20.accent, bold: true, children: "Select Model" }),
|
|
10341
|
+
/* @__PURE__ */ jsxs15(Text19, { color: theme20.textSubtle, children: [
|
|
10213
10342
|
" ",
|
|
10214
10343
|
filtered.length,
|
|
10215
10344
|
" models"
|
|
10216
10345
|
] })
|
|
10217
10346
|
] }),
|
|
10218
10347
|
/* @__PURE__ */ jsxs15(Box17, { marginBottom: 1, children: [
|
|
10219
|
-
/* @__PURE__ */
|
|
10220
|
-
/* @__PURE__ */
|
|
10348
|
+
/* @__PURE__ */ jsx21(Text19, { color: theme20.textSubtle, children: "/ " }),
|
|
10349
|
+
/* @__PURE__ */ jsx21(
|
|
10221
10350
|
TextInput2,
|
|
10222
10351
|
{
|
|
10223
10352
|
value: search,
|
|
@@ -10226,35 +10355,35 @@ function ModelPicker({ currentModel, onSelect, onCancel }) {
|
|
|
10226
10355
|
}
|
|
10227
10356
|
)
|
|
10228
10357
|
] }),
|
|
10229
|
-
/* @__PURE__ */
|
|
10230
|
-
/* @__PURE__ */
|
|
10358
|
+
/* @__PURE__ */ jsx21(Box17, { height: 1, children: /* @__PURE__ */ jsx21(Text19, { color: theme20.textSubtle, children: pad(showScrollUp ? " ..." : "") }) }),
|
|
10359
|
+
/* @__PURE__ */ jsx21(Box17, { flexDirection: "column", height: MAX_VISIBLE, children: filtered.length === 0 ? /* @__PURE__ */ jsx21(Text19, { color: theme20.textSubtle, children: " No matching models" }) : rows.map((row) => {
|
|
10231
10360
|
if (row.type === "group") {
|
|
10232
|
-
return /* @__PURE__ */
|
|
10361
|
+
return /* @__PURE__ */ jsx21(Box17, { children: /* @__PURE__ */ jsx21(Text19, { color: theme20.textSubtle, dimColor: true, children: pad(` ${row.label}`) }) }, `group-${row.label}`);
|
|
10233
10362
|
}
|
|
10234
10363
|
const { model, isHighlighted, isCurrent } = row;
|
|
10235
10364
|
const indicator = isHighlighted ? "\u203A " : " ";
|
|
10236
10365
|
const suffix = isCurrent ? " *" : "";
|
|
10237
|
-
return /* @__PURE__ */
|
|
10366
|
+
return /* @__PURE__ */ jsx21(Box17, { children: /* @__PURE__ */ jsx21(
|
|
10238
10367
|
Text19,
|
|
10239
10368
|
{
|
|
10240
|
-
color: isHighlighted ?
|
|
10369
|
+
color: isHighlighted ? theme20.accentActive : isCurrent ? theme20.accent : theme20.textMuted,
|
|
10241
10370
|
bold: isHighlighted,
|
|
10242
10371
|
children: pad(`${indicator}${model.label}${suffix}`)
|
|
10243
10372
|
}
|
|
10244
10373
|
) }, model.value);
|
|
10245
10374
|
}) }),
|
|
10246
|
-
/* @__PURE__ */
|
|
10247
|
-
/* @__PURE__ */
|
|
10375
|
+
/* @__PURE__ */ jsx21(Box17, { height: 1, children: /* @__PURE__ */ jsx21(Text19, { color: theme20.textSubtle, children: pad(showScrollDown ? " ..." : "") }) }),
|
|
10376
|
+
/* @__PURE__ */ jsx21(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx21(Text19, { color: theme20.textSubtle, children: ["\u2191\u2193 navigate", "Enter select", "Tab manage models", "Esc cancel"].join(theme20.separator ?? " \xB7 ") }) })
|
|
10248
10377
|
]
|
|
10249
10378
|
}
|
|
10250
10379
|
);
|
|
10251
10380
|
}
|
|
10252
10381
|
|
|
10253
10382
|
// src/ink/marathon/CommandPicker.tsx
|
|
10254
|
-
import { useState as
|
|
10383
|
+
import { useState as useState18, useMemo as useMemo8, useCallback as useCallback5 } from "react";
|
|
10255
10384
|
import { Box as Box18, Text as Text20, useInput as useInput7, useStdout as useStdout2 } from "ink";
|
|
10256
10385
|
import TextInput3 from "ink-text-input";
|
|
10257
|
-
import { theme as
|
|
10386
|
+
import { theme as theme21 } from "@runtypelabs/ink-components";
|
|
10258
10387
|
|
|
10259
10388
|
// src/ink/marathon/types.ts
|
|
10260
10389
|
var MARATHON_STEER_COMMANDS = [
|
|
@@ -10280,11 +10409,11 @@ var MARATHON_STEER_COMMANDS = [
|
|
|
10280
10409
|
];
|
|
10281
10410
|
|
|
10282
10411
|
// src/ink/marathon/CommandPicker.tsx
|
|
10283
|
-
import { jsx as
|
|
10412
|
+
import { jsx as jsx22, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
10284
10413
|
function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
10285
10414
|
const { stdout } = useStdout2();
|
|
10286
|
-
const [search, setSearch] =
|
|
10287
|
-
const [selectedIndex, setSelectedIndex] =
|
|
10415
|
+
const [search, setSearch] = useState18(initialFilter);
|
|
10416
|
+
const [selectedIndex, setSelectedIndex] = useState18(0);
|
|
10288
10417
|
const contentWidth = (stdout?.columns ?? 120) - 4;
|
|
10289
10418
|
const pad = useCallback5(
|
|
10290
10419
|
(text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text,
|
|
@@ -10326,23 +10455,23 @@ function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
|
10326
10455
|
Box18,
|
|
10327
10456
|
{
|
|
10328
10457
|
borderStyle: "single",
|
|
10329
|
-
borderColor:
|
|
10330
|
-
backgroundColor:
|
|
10331
|
-
paddingX:
|
|
10332
|
-
paddingY:
|
|
10458
|
+
borderColor: theme21.border,
|
|
10459
|
+
backgroundColor: theme21.surfaceElevated,
|
|
10460
|
+
paddingX: theme21.panelPaddingX,
|
|
10461
|
+
paddingY: theme21.panelPaddingY,
|
|
10333
10462
|
flexDirection: "column",
|
|
10334
10463
|
children: [
|
|
10335
10464
|
/* @__PURE__ */ jsxs16(Box18, { marginBottom: 1, children: [
|
|
10336
|
-
/* @__PURE__ */
|
|
10337
|
-
/* @__PURE__ */ jsxs16(Text20, { color:
|
|
10465
|
+
/* @__PURE__ */ jsx22(Text20, { color: theme21.accent, bold: true, children: "Commands" }),
|
|
10466
|
+
/* @__PURE__ */ jsxs16(Text20, { color: theme21.textSubtle, children: [
|
|
10338
10467
|
" ",
|
|
10339
10468
|
filtered.length,
|
|
10340
10469
|
" available"
|
|
10341
10470
|
] })
|
|
10342
10471
|
] }),
|
|
10343
10472
|
/* @__PURE__ */ jsxs16(Box18, { marginBottom: 1, children: [
|
|
10344
|
-
/* @__PURE__ */
|
|
10345
|
-
/* @__PURE__ */
|
|
10473
|
+
/* @__PURE__ */ jsx22(Text20, { color: theme21.textSubtle, children: "/ " }),
|
|
10474
|
+
/* @__PURE__ */ jsx22(
|
|
10346
10475
|
TextInput3,
|
|
10347
10476
|
{
|
|
10348
10477
|
value: search,
|
|
@@ -10351,29 +10480,29 @@ function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
|
10351
10480
|
}
|
|
10352
10481
|
)
|
|
10353
10482
|
] }),
|
|
10354
|
-
/* @__PURE__ */
|
|
10483
|
+
/* @__PURE__ */ jsx22(Box18, { flexDirection: "column", children: filtered.length === 0 ? /* @__PURE__ */ jsx22(Text20, { color: theme21.textSubtle, children: pad(" No matching commands") }) : filtered.map((cmd, index) => {
|
|
10355
10484
|
const isHighlighted = index === selectedIndex;
|
|
10356
10485
|
const indicator = isHighlighted ? "\u203A " : " ";
|
|
10357
10486
|
const nameCol = cmd.name.padEnd(14);
|
|
10358
|
-
return /* @__PURE__ */
|
|
10487
|
+
return /* @__PURE__ */ jsx22(Box18, { children: /* @__PURE__ */ jsx22(
|
|
10359
10488
|
Text20,
|
|
10360
10489
|
{
|
|
10361
|
-
color: isHighlighted ?
|
|
10490
|
+
color: isHighlighted ? theme21.accentActive : theme21.textMuted,
|
|
10362
10491
|
bold: isHighlighted,
|
|
10363
10492
|
children: pad(`${indicator}${nameCol}${cmd.description}`)
|
|
10364
10493
|
}
|
|
10365
10494
|
) }, cmd.name);
|
|
10366
10495
|
}) }),
|
|
10367
|
-
/* @__PURE__ */
|
|
10496
|
+
/* @__PURE__ */ jsx22(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx22(Text20, { color: theme21.textSubtle, children: ["\u2191\u2193 navigate", "Enter select", "Esc cancel"].join(theme21.separator ?? " \xB7 ") }) })
|
|
10368
10497
|
]
|
|
10369
10498
|
}
|
|
10370
10499
|
);
|
|
10371
10500
|
}
|
|
10372
10501
|
|
|
10373
10502
|
// src/ink/marathon/TextArea.tsx
|
|
10374
|
-
import { useState as
|
|
10503
|
+
import { useState as useState19, useCallback as useCallback6, useRef as useRef6, useEffect as useEffect18, useMemo as useMemo9 } from "react";
|
|
10375
10504
|
import { Box as Box19, Text as Text21, useInput as useInput8, useStdout as useStdout3 } from "ink";
|
|
10376
|
-
import { theme as
|
|
10505
|
+
import { theme as theme22 } from "@runtypelabs/ink-components";
|
|
10377
10506
|
|
|
10378
10507
|
// src/ink/marathon/text-area-editing.ts
|
|
10379
10508
|
function ensureLines(lines) {
|
|
@@ -10437,7 +10566,7 @@ function deleteToLineStart(lines, cursor) {
|
|
|
10437
10566
|
}
|
|
10438
10567
|
|
|
10439
10568
|
// src/ink/marathon/TextArea.tsx
|
|
10440
|
-
import { jsx as
|
|
10569
|
+
import { jsx as jsx23, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
10441
10570
|
function splitLines(text) {
|
|
10442
10571
|
const lines = text.split("\n");
|
|
10443
10572
|
return lines.length === 0 ? [""] : lines;
|
|
@@ -10455,20 +10584,20 @@ function TextArea({
|
|
|
10455
10584
|
const { stdout } = useStdout3();
|
|
10456
10585
|
const terminalWidth = stdout?.columns ?? 120;
|
|
10457
10586
|
const contentWidth = Math.max(20, terminalWidth - 6);
|
|
10458
|
-
const separator =
|
|
10459
|
-
const [lines, setLines] =
|
|
10460
|
-
const [cursor, setCursor] =
|
|
10587
|
+
const separator = theme22.separator ?? " \xB7 ";
|
|
10588
|
+
const [lines, setLines] = useState19(() => splitLines(defaultValue));
|
|
10589
|
+
const [cursor, setCursor] = useState19(() => {
|
|
10461
10590
|
const l = splitLines(defaultValue);
|
|
10462
10591
|
return { line: l.length - 1, col: l[l.length - 1].length };
|
|
10463
10592
|
});
|
|
10464
|
-
const [scrollOffset, setScrollOffset] =
|
|
10465
|
-
const [blinkVisible, setBlinkVisible] =
|
|
10593
|
+
const [scrollOffset, setScrollOffset] = useState19(0);
|
|
10594
|
+
const [blinkVisible, setBlinkVisible] = useState19(true);
|
|
10466
10595
|
const blinkRef = useRef6(null);
|
|
10467
10596
|
const linesRef = useRef6(lines);
|
|
10468
10597
|
linesRef.current = lines;
|
|
10469
10598
|
const cursorRef = useRef6(cursor);
|
|
10470
10599
|
cursorRef.current = cursor;
|
|
10471
|
-
|
|
10600
|
+
useEffect18(() => {
|
|
10472
10601
|
blinkRef.current = setInterval(() => {
|
|
10473
10602
|
setBlinkVisible((v) => !v);
|
|
10474
10603
|
}, CURSOR_BLINK_MS);
|
|
@@ -10479,10 +10608,10 @@ function TextArea({
|
|
|
10479
10608
|
}
|
|
10480
10609
|
};
|
|
10481
10610
|
}, []);
|
|
10482
|
-
|
|
10611
|
+
useEffect18(() => {
|
|
10483
10612
|
setBlinkVisible(true);
|
|
10484
10613
|
}, [lines, cursor]);
|
|
10485
|
-
|
|
10614
|
+
useEffect18(() => {
|
|
10486
10615
|
const visibleStart = scrollOffset;
|
|
10487
10616
|
const visibleEnd = scrollOffset + maxHeight - 1;
|
|
10488
10617
|
if (cursor.line < visibleStart) {
|
|
@@ -10629,23 +10758,23 @@ function TextArea({
|
|
|
10629
10758
|
Box19,
|
|
10630
10759
|
{
|
|
10631
10760
|
borderStyle: "single",
|
|
10632
|
-
borderColor:
|
|
10633
|
-
backgroundColor:
|
|
10761
|
+
borderColor: theme22.borderActive,
|
|
10762
|
+
backgroundColor: theme22.surface,
|
|
10634
10763
|
flexDirection: "column",
|
|
10635
10764
|
paddingX: 1,
|
|
10636
10765
|
children: [
|
|
10637
10766
|
title && /* @__PURE__ */ jsxs17(Box19, { marginBottom: 1, children: [
|
|
10638
|
-
/* @__PURE__ */
|
|
10639
|
-
/* @__PURE__ */ jsxs17(Text21, { color:
|
|
10767
|
+
/* @__PURE__ */ jsx23(Text21, { color: theme22.accent, bold: true, children: title }),
|
|
10768
|
+
/* @__PURE__ */ jsxs17(Text21, { color: theme22.textSubtle, children: [
|
|
10640
10769
|
" ",
|
|
10641
10770
|
lines.length,
|
|
10642
10771
|
" lines"
|
|
10643
10772
|
] })
|
|
10644
10773
|
] }),
|
|
10645
10774
|
/* @__PURE__ */ jsxs17(Box19, { flexDirection: "row", height: maxHeight, children: [
|
|
10646
|
-
/* @__PURE__ */
|
|
10647
|
-
/* @__PURE__ */
|
|
10648
|
-
vl.hasCursor ? /* @__PURE__ */
|
|
10775
|
+
/* @__PURE__ */ jsx23(Box19, { flexDirection: "column", flexGrow: 1, children: visibleLines.map((vl, idx) => /* @__PURE__ */ jsxs17(Box19, { children: [
|
|
10776
|
+
/* @__PURE__ */ jsx23(Text21, { color: theme22.textSubtle, children: vl.lineIndex >= 0 ? `${String(vl.lineIndex + 1).padStart(3)} ` : " " }),
|
|
10777
|
+
vl.hasCursor ? /* @__PURE__ */ jsx23(
|
|
10649
10778
|
CursorLine,
|
|
10650
10779
|
{
|
|
10651
10780
|
content: vl.content,
|
|
@@ -10653,9 +10782,9 @@ function TextArea({
|
|
|
10653
10782
|
maxWidth: contentWidth - 6,
|
|
10654
10783
|
visible: blinkVisible
|
|
10655
10784
|
}
|
|
10656
|
-
) : /* @__PURE__ */
|
|
10785
|
+
) : /* @__PURE__ */ jsx23(Text21, { color: theme22.text, children: vl.content.slice(0, contentWidth - 6) })
|
|
10657
10786
|
] }, idx)) }),
|
|
10658
|
-
/* @__PURE__ */
|
|
10787
|
+
/* @__PURE__ */ jsx23(
|
|
10659
10788
|
Scrollbar,
|
|
10660
10789
|
{
|
|
10661
10790
|
totalLines: lines.length,
|
|
@@ -10668,7 +10797,7 @@ function TextArea({
|
|
|
10668
10797
|
]
|
|
10669
10798
|
}
|
|
10670
10799
|
),
|
|
10671
|
-
/* @__PURE__ */
|
|
10800
|
+
/* @__PURE__ */ jsx23(Text21, { color: theme22.textSubtle, children: [
|
|
10672
10801
|
"Ctrl+S: submit",
|
|
10673
10802
|
"Esc: cancel",
|
|
10674
10803
|
"Enter: newline",
|
|
@@ -10689,21 +10818,21 @@ function CursorLine({
|
|
|
10689
10818
|
const cursorChar = truncated[col] ?? " ";
|
|
10690
10819
|
const after = truncated.slice(col + 1);
|
|
10691
10820
|
return /* @__PURE__ */ jsxs17(Text21, { children: [
|
|
10692
|
-
/* @__PURE__ */
|
|
10693
|
-
visible ? /* @__PURE__ */
|
|
10694
|
-
/* @__PURE__ */
|
|
10821
|
+
/* @__PURE__ */ jsx23(Text21, { color: theme22.text, children: before }),
|
|
10822
|
+
visible ? /* @__PURE__ */ jsx23(Text21, { color: theme22.background, backgroundColor: theme22.accentActive, children: cursorChar }) : /* @__PURE__ */ jsx23(Text21, { color: theme22.text, children: cursorChar }),
|
|
10823
|
+
/* @__PURE__ */ jsx23(Text21, { color: theme22.text, children: after })
|
|
10695
10824
|
] });
|
|
10696
10825
|
}
|
|
10697
10826
|
|
|
10698
10827
|
// src/ink/marathon/ReflectEditor.tsx
|
|
10699
|
-
import { jsx as
|
|
10828
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
10700
10829
|
var DEFAULT_REFLECT_PROMPT = `Before continuing, step back and reflect:
|
|
10701
10830
|
- What has been accomplished so far?
|
|
10702
10831
|
- What isn't working or is blocking progress?
|
|
10703
10832
|
- What approach should be taken next and why?
|
|
10704
10833
|
- Are there any assumptions that should be reconsidered?`;
|
|
10705
10834
|
function ReflectEditor({ onSubmit, onCancel, maxHeight = 10 }) {
|
|
10706
|
-
return /* @__PURE__ */
|
|
10835
|
+
return /* @__PURE__ */ jsx24(
|
|
10707
10836
|
TextArea,
|
|
10708
10837
|
{
|
|
10709
10838
|
title: "Reflect",
|
|
@@ -10717,9 +10846,9 @@ function ReflectEditor({ onSubmit, onCancel, maxHeight = 10 }) {
|
|
|
10717
10846
|
|
|
10718
10847
|
// src/ink/marathon/SteeringRecap.tsx
|
|
10719
10848
|
import { Box as Box20, Text as Text22 } from "ink";
|
|
10720
|
-
import { theme as
|
|
10721
|
-
import { jsx as
|
|
10722
|
-
function
|
|
10849
|
+
import { theme as theme23 } from "@runtypelabs/ink-components";
|
|
10850
|
+
import { jsx as jsx25, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
10851
|
+
function formatTokenCount2(value) {
|
|
10723
10852
|
return value.toLocaleString("en-US");
|
|
10724
10853
|
}
|
|
10725
10854
|
function SteeringRecap({
|
|
@@ -10733,26 +10862,26 @@ function SteeringRecap({
|
|
|
10733
10862
|
isTerminal
|
|
10734
10863
|
}) {
|
|
10735
10864
|
const label = isTerminal ? `\u2713 Session ${sessionNumber} complete` : `Session ${sessionNumber} complete`;
|
|
10736
|
-
const separator =
|
|
10865
|
+
const separator = theme23.separator ?? " \xB7 ";
|
|
10737
10866
|
const usageSummary = [
|
|
10738
10867
|
`Tools: ${toolCallsMade}`,
|
|
10739
|
-
`Tokens: ${
|
|
10740
|
-
...reasoningTokens && reasoningTokens > 0 ? [`Reasoning: ${
|
|
10868
|
+
`Tokens: ${formatTokenCount2(tokensInput)} in${separator}${formatTokenCount2(tokensOutput)} out`,
|
|
10869
|
+
...reasoningTokens && reasoningTokens > 0 ? [`Reasoning: ${formatTokenCount2(reasoningTokens)}`] : [],
|
|
10741
10870
|
`Cost: $${cost.toFixed(4)}`
|
|
10742
10871
|
].join(separator);
|
|
10743
10872
|
return /* @__PURE__ */ jsxs18(
|
|
10744
10873
|
Box20,
|
|
10745
10874
|
{
|
|
10746
10875
|
borderStyle: "single",
|
|
10747
|
-
borderColor:
|
|
10748
|
-
backgroundColor:
|
|
10876
|
+
borderColor: theme23.border,
|
|
10877
|
+
backgroundColor: theme23.background,
|
|
10749
10878
|
flexDirection: "column",
|
|
10750
|
-
paddingX:
|
|
10751
|
-
paddingY:
|
|
10879
|
+
paddingX: theme23.panelPaddingX,
|
|
10880
|
+
paddingY: theme23.panelPaddingY,
|
|
10752
10881
|
children: [
|
|
10753
|
-
/* @__PURE__ */
|
|
10754
|
-
/* @__PURE__ */
|
|
10755
|
-
historyWarning && /* @__PURE__ */
|
|
10882
|
+
/* @__PURE__ */ jsx25(Text22, { color: isTerminal ? theme23.accentActive : theme23.accent, children: label }),
|
|
10883
|
+
/* @__PURE__ */ jsx25(Text22, { color: theme23.textMuted, children: usageSummary }),
|
|
10884
|
+
historyWarning && /* @__PURE__ */ jsx25(Text22, { color: theme23.warning, children: historyWarning })
|
|
10756
10885
|
]
|
|
10757
10886
|
}
|
|
10758
10887
|
);
|
|
@@ -10774,7 +10903,7 @@ function getSteeringCountdownText(state) {
|
|
|
10774
10903
|
}
|
|
10775
10904
|
|
|
10776
10905
|
// src/ink/marathon/SteeringPrompt.tsx
|
|
10777
|
-
import { jsx as
|
|
10906
|
+
import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
10778
10907
|
function SteeringPrompt({
|
|
10779
10908
|
onSubmit,
|
|
10780
10909
|
onToggleHelp,
|
|
@@ -10786,18 +10915,18 @@ function SteeringPrompt({
|
|
|
10786
10915
|
recap,
|
|
10787
10916
|
isReviewing = false
|
|
10788
10917
|
}) {
|
|
10789
|
-
const [value, setValue] =
|
|
10790
|
-
const [remaining, setRemaining] =
|
|
10791
|
-
const [isTyping, setIsTyping] =
|
|
10792
|
-
const [showModelPicker, setShowModelPicker] =
|
|
10793
|
-
const [showReflectEditor, setShowReflectEditor] =
|
|
10794
|
-
const [showCommandPicker, setShowCommandPicker] =
|
|
10795
|
-
const [pendingModel, setPendingModel] =
|
|
10796
|
-
const [pendingSandbox, setPendingSandbox] =
|
|
10797
|
-
const [pendingToolsToggle, setPendingToolsToggle] =
|
|
10798
|
-
const [pendingStop, setPendingStop] =
|
|
10918
|
+
const [value, setValue] = useState20("");
|
|
10919
|
+
const [remaining, setRemaining] = useState20(timeout);
|
|
10920
|
+
const [isTyping, setIsTyping] = useState20(false);
|
|
10921
|
+
const [showModelPicker, setShowModelPicker] = useState20(false);
|
|
10922
|
+
const [showReflectEditor, setShowReflectEditor] = useState20(false);
|
|
10923
|
+
const [showCommandPicker, setShowCommandPicker] = useState20(false);
|
|
10924
|
+
const [pendingModel, setPendingModel] = useState20(void 0);
|
|
10925
|
+
const [pendingSandbox, setPendingSandbox] = useState20(void 0);
|
|
10926
|
+
const [pendingToolsToggle, setPendingToolsToggle] = useState20(false);
|
|
10927
|
+
const [pendingStop, setPendingStop] = useState20(false);
|
|
10799
10928
|
const timerRef = useRef7(null);
|
|
10800
|
-
const separator =
|
|
10929
|
+
const separator = theme24.separator ?? " \xB7 ";
|
|
10801
10930
|
const hasPendingChanges = pendingModel !== void 0 || pendingSandbox !== void 0 || pendingToolsToggle || pendingStop;
|
|
10802
10931
|
const clearInputDraft = () => {
|
|
10803
10932
|
setValue("");
|
|
@@ -10821,7 +10950,7 @@ function SteeringPrompt({
|
|
|
10821
10950
|
resetDraft();
|
|
10822
10951
|
onSubmit(result);
|
|
10823
10952
|
};
|
|
10824
|
-
|
|
10953
|
+
useEffect19(() => {
|
|
10825
10954
|
const title = "Marathon";
|
|
10826
10955
|
const body = isTerminal ? "Marathon complete" : `Session ${recap?.sessionNumber ?? "?"} complete`;
|
|
10827
10956
|
process.stderr.write(`\x1B]777;notify;${title};${body}\x07`);
|
|
@@ -10841,7 +10970,7 @@ function SteeringPrompt({
|
|
|
10841
10970
|
setIsTyping(false);
|
|
10842
10971
|
}
|
|
10843
10972
|
};
|
|
10844
|
-
|
|
10973
|
+
useEffect19(() => {
|
|
10845
10974
|
if (shouldPauseSteeringTimer({
|
|
10846
10975
|
isTerminal,
|
|
10847
10976
|
timeout,
|
|
@@ -10987,20 +11116,20 @@ ${trimmed}` : trimmed);
|
|
|
10987
11116
|
return "Enter: continue";
|
|
10988
11117
|
})();
|
|
10989
11118
|
return /* @__PURE__ */ jsxs19(Box21, { flexDirection: "column", flexShrink: 0, children: [
|
|
10990
|
-
showCommandPicker ? /* @__PURE__ */
|
|
11119
|
+
showCommandPicker ? /* @__PURE__ */ jsx26(
|
|
10991
11120
|
CommandPicker,
|
|
10992
11121
|
{
|
|
10993
11122
|
onSelect: handleCommandSelect,
|
|
10994
11123
|
onCancel: handleCommandCancel
|
|
10995
11124
|
}
|
|
10996
|
-
) : showModelPicker ? /* @__PURE__ */
|
|
11125
|
+
) : showModelPicker ? /* @__PURE__ */ jsx26(
|
|
10997
11126
|
ModelPicker,
|
|
10998
11127
|
{
|
|
10999
11128
|
currentModel,
|
|
11000
11129
|
onSelect: handleModelSelect,
|
|
11001
11130
|
onCancel: handleModelCancel
|
|
11002
11131
|
}
|
|
11003
|
-
) : showReflectEditor ? /* @__PURE__ */
|
|
11132
|
+
) : showReflectEditor ? /* @__PURE__ */ jsx26(
|
|
11004
11133
|
ReflectEditor,
|
|
11005
11134
|
{
|
|
11006
11135
|
onSubmit: handleReflectSubmit,
|
|
@@ -11014,15 +11143,15 @@ ${trimmed}` : trimmed);
|
|
|
11014
11143
|
borderRight: false,
|
|
11015
11144
|
borderTop: false,
|
|
11016
11145
|
borderBottom: false,
|
|
11017
|
-
borderColor:
|
|
11018
|
-
backgroundColor:
|
|
11146
|
+
borderColor: theme24.accent,
|
|
11147
|
+
backgroundColor: theme24.backgroundDeep,
|
|
11019
11148
|
flexDirection: "column",
|
|
11020
11149
|
paddingX: 1,
|
|
11021
11150
|
paddingY: 1,
|
|
11022
11151
|
children: [
|
|
11023
11152
|
/* @__PURE__ */ jsxs19(Box21, { children: [
|
|
11024
|
-
/* @__PURE__ */
|
|
11025
|
-
/* @__PURE__ */
|
|
11153
|
+
/* @__PURE__ */ jsx26(Text23, { color: theme24.accentActive, children: "> " }),
|
|
11154
|
+
/* @__PURE__ */ jsx26(Box21, { flexGrow: 1, children: /* @__PURE__ */ jsx26(
|
|
11026
11155
|
BlinkingTextInput,
|
|
11027
11156
|
{
|
|
11028
11157
|
value,
|
|
@@ -11031,28 +11160,28 @@ ${trimmed}` : trimmed);
|
|
|
11031
11160
|
placeholder: isTerminal ? "Send new instructions to continue marathon, or press enter to exit..." : "Steer next iteration..."
|
|
11032
11161
|
}
|
|
11033
11162
|
) }),
|
|
11034
|
-
countdownText && /* @__PURE__ */ jsxs19(Text23, { color:
|
|
11163
|
+
countdownText && /* @__PURE__ */ jsxs19(Text23, { color: theme24.textSubtle, children: [
|
|
11035
11164
|
" ",
|
|
11036
11165
|
countdownText
|
|
11037
11166
|
] })
|
|
11038
11167
|
] }),
|
|
11039
|
-
/* @__PURE__ */
|
|
11168
|
+
/* @__PURE__ */ jsx26(Text23, { color: theme24.textSubtle, children: [
|
|
11040
11169
|
enterHint,
|
|
11041
11170
|
"/: commands",
|
|
11042
11171
|
"/help"
|
|
11043
11172
|
].join(separator) }),
|
|
11044
|
-
pendingSummary.length > 0 && /* @__PURE__ */
|
|
11173
|
+
pendingSummary.length > 0 && /* @__PURE__ */ jsx26(Text23, { color: theme24.textMuted, children: `Pending: ${pendingSummary.join(separator)}` })
|
|
11045
11174
|
]
|
|
11046
11175
|
}
|
|
11047
11176
|
),
|
|
11048
|
-
/* @__PURE__ */
|
|
11177
|
+
/* @__PURE__ */ jsx26(SteeringRecap, { ...recap, isTerminal })
|
|
11049
11178
|
] });
|
|
11050
11179
|
}
|
|
11051
11180
|
|
|
11052
11181
|
// src/ink/marathon/SessionActionMenu.tsx
|
|
11053
11182
|
import { Box as Box22, Text as Text24, useInput as useInput9 } from "ink";
|
|
11054
|
-
import { theme as
|
|
11055
|
-
import { jsx as
|
|
11183
|
+
import { theme as theme25 } from "@runtypelabs/ink-components";
|
|
11184
|
+
import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
11056
11185
|
var MENU_ITEMS = [
|
|
11057
11186
|
{ key: "c", label: "Copy session JSON" },
|
|
11058
11187
|
{ key: "o", label: "Open state file" },
|
|
@@ -11089,23 +11218,23 @@ function SessionActionMenu({
|
|
|
11089
11218
|
{
|
|
11090
11219
|
flexDirection: "column",
|
|
11091
11220
|
borderStyle: "round",
|
|
11092
|
-
borderColor:
|
|
11093
|
-
backgroundColor:
|
|
11221
|
+
borderColor: theme25.accent,
|
|
11222
|
+
backgroundColor: theme25.surfaceElevated,
|
|
11094
11223
|
paddingX: 2,
|
|
11095
11224
|
paddingY: 1,
|
|
11096
11225
|
width: 36,
|
|
11097
11226
|
children: [
|
|
11098
|
-
/* @__PURE__ */
|
|
11099
|
-
/* @__PURE__ */
|
|
11227
|
+
/* @__PURE__ */ jsx27(Text24, { bold: true, color: theme25.accent, children: "Session" }),
|
|
11228
|
+
/* @__PURE__ */ jsx27(Box22, { flexDirection: "column", marginTop: 1, children: MENU_ITEMS.map((item) => {
|
|
11100
11229
|
const dimmed = item.key === "o" && !hasStateFile || item.key === "d" && !hasDashboard;
|
|
11101
11230
|
return /* @__PURE__ */ jsxs20(Text24, { children: [
|
|
11102
|
-
/* @__PURE__ */
|
|
11103
|
-
/* @__PURE__ */
|
|
11231
|
+
/* @__PURE__ */ jsx27(Text24, { color: dimmed ? theme25.textSubtle : theme25.accentActive, children: ` ${item.key} ` }),
|
|
11232
|
+
/* @__PURE__ */ jsx27(Text24, { color: dimmed ? theme25.textSubtle : theme25.textMuted, children: item.label })
|
|
11104
11233
|
] }, item.key);
|
|
11105
11234
|
}) }),
|
|
11106
11235
|
/* @__PURE__ */ jsxs20(Box22, { marginTop: 1, children: [
|
|
11107
|
-
/* @__PURE__ */
|
|
11108
|
-
/* @__PURE__ */
|
|
11236
|
+
/* @__PURE__ */ jsx27(Text24, { color: theme25.info, children: "Esc" }),
|
|
11237
|
+
/* @__PURE__ */ jsx27(Text24, { color: theme25.muted, children: " to close" })
|
|
11109
11238
|
] })
|
|
11110
11239
|
]
|
|
11111
11240
|
}
|
|
@@ -11114,8 +11243,8 @@ function SessionActionMenu({
|
|
|
11114
11243
|
|
|
11115
11244
|
// src/ink/marathon/UpgradeModal.tsx
|
|
11116
11245
|
import { Box as Box23, Text as Text25 } from "ink";
|
|
11117
|
-
import { theme as
|
|
11118
|
-
import { jsx as
|
|
11246
|
+
import { theme as theme26 } from "@runtypelabs/ink-components";
|
|
11247
|
+
import { jsx as jsx28, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
11119
11248
|
function UpgradeModal({ prompt, width }) {
|
|
11120
11249
|
return /* @__PURE__ */ jsxs21(
|
|
11121
11250
|
Box23,
|
|
@@ -11123,34 +11252,34 @@ function UpgradeModal({ prompt, width }) {
|
|
|
11123
11252
|
width,
|
|
11124
11253
|
flexDirection: "column",
|
|
11125
11254
|
borderStyle: "round",
|
|
11126
|
-
borderColor:
|
|
11127
|
-
backgroundColor:
|
|
11255
|
+
borderColor: theme26.warning,
|
|
11256
|
+
backgroundColor: theme26.surfaceElevated,
|
|
11128
11257
|
paddingX: 2,
|
|
11129
11258
|
paddingY: 1,
|
|
11130
11259
|
children: [
|
|
11131
|
-
/* @__PURE__ */
|
|
11132
|
-
/* @__PURE__ */
|
|
11260
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.warning, bold: true, children: "Upgrade available" }),
|
|
11261
|
+
/* @__PURE__ */ jsx28(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx28(Text25, { color: theme26.label, children: prompt.message }) }),
|
|
11133
11262
|
(prompt.code || prompt.limitType || prompt.retryAfter) && /* @__PURE__ */ jsxs21(Box23, { flexDirection: "column", marginTop: 1, children: [
|
|
11134
|
-
prompt.code && /* @__PURE__ */ jsxs21(Text25, { color:
|
|
11263
|
+
prompt.code && /* @__PURE__ */ jsxs21(Text25, { color: theme26.muted, children: [
|
|
11135
11264
|
"Code: ",
|
|
11136
|
-
/* @__PURE__ */
|
|
11265
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.label, children: prompt.code })
|
|
11137
11266
|
] }),
|
|
11138
|
-
prompt.limitType && /* @__PURE__ */ jsxs21(Text25, { color:
|
|
11267
|
+
prompt.limitType && /* @__PURE__ */ jsxs21(Text25, { color: theme26.muted, children: [
|
|
11139
11268
|
"Limit: ",
|
|
11140
|
-
/* @__PURE__ */
|
|
11269
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.label, children: prompt.limitType })
|
|
11141
11270
|
] }),
|
|
11142
|
-
prompt.retryAfter && /* @__PURE__ */ jsxs21(Text25, { color:
|
|
11271
|
+
prompt.retryAfter && /* @__PURE__ */ jsxs21(Text25, { color: theme26.muted, children: [
|
|
11143
11272
|
"Retry after: ",
|
|
11144
|
-
/* @__PURE__ */
|
|
11273
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.label, children: prompt.retryAfter })
|
|
11145
11274
|
] })
|
|
11146
11275
|
] }),
|
|
11147
11276
|
/* @__PURE__ */ jsxs21(Box23, { marginTop: 1, children: [
|
|
11148
|
-
/* @__PURE__ */
|
|
11149
|
-
/* @__PURE__ */
|
|
11150
|
-
/* @__PURE__ */
|
|
11151
|
-
/* @__PURE__ */
|
|
11277
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.info, children: "Enter" }),
|
|
11278
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.muted, children: " open billing " }),
|
|
11279
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.info, children: "Esc" }),
|
|
11280
|
+
/* @__PURE__ */ jsx28(Text25, { color: theme26.muted, children: " close" })
|
|
11152
11281
|
] }),
|
|
11153
|
-
/* @__PURE__ */
|
|
11282
|
+
/* @__PURE__ */ jsx28(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx28(Text25, { color: theme26.dimLabel, children: "Opens your dashboard billing page" }) })
|
|
11154
11283
|
]
|
|
11155
11284
|
}
|
|
11156
11285
|
);
|
|
@@ -11310,7 +11439,7 @@ function isAllowedSteeringBrowseKey(key, isBrowsingScreen) {
|
|
|
11310
11439
|
}
|
|
11311
11440
|
|
|
11312
11441
|
// src/ink/marathon/MarathonApp.tsx
|
|
11313
|
-
import { Fragment as Fragment3, jsx as
|
|
11442
|
+
import { Fragment as Fragment3, jsx as jsx29, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
11314
11443
|
var TOOL_PANEL_WIDE = 48;
|
|
11315
11444
|
var TOOL_PANEL_NARROW = 36;
|
|
11316
11445
|
var NARROW_THRESHOLD = 100;
|
|
@@ -11344,7 +11473,7 @@ function upsertSessionSnapshots(snapshots, nextSnapshot) {
|
|
|
11344
11473
|
return Array.from(bySessionIndex.values()).sort((left, right) => left.sessionIndex - right.sessionIndex);
|
|
11345
11474
|
}
|
|
11346
11475
|
function buildLiveSessionSnapshot(liveState, sessionIndex, model) {
|
|
11347
|
-
const hasLiveState = Boolean(liveState.content) || Boolean(liveState.reasoning) || liveState.tools.length > 0 || liveState.rawEvents.length > 0;
|
|
11476
|
+
const hasLiveState = Boolean(liveState.content) || Boolean(liveState.reasoning) || liveState.tools.length > 0 || liveState.rawEvents.length > 0 || Boolean(liveState.contextCompaction?.active);
|
|
11348
11477
|
if (!hasLiveState) return void 0;
|
|
11349
11478
|
return {
|
|
11350
11479
|
sessionIndex,
|
|
@@ -11412,25 +11541,35 @@ function MarathonApp({
|
|
|
11412
11541
|
onComplete: _onComplete,
|
|
11413
11542
|
streamRef
|
|
11414
11543
|
}) {
|
|
11415
|
-
const {
|
|
11544
|
+
const {
|
|
11545
|
+
state,
|
|
11546
|
+
callbacks,
|
|
11547
|
+
reset: _reset,
|
|
11548
|
+
setSteering,
|
|
11549
|
+
startContextCompaction,
|
|
11550
|
+
finishContextCompaction,
|
|
11551
|
+
reportContextNotice,
|
|
11552
|
+
resetForNewSession,
|
|
11553
|
+
showError
|
|
11554
|
+
} = useMarathonStream();
|
|
11416
11555
|
const { exit } = useApp4();
|
|
11417
11556
|
const { stdout } = useStdout4();
|
|
11418
|
-
const separator =
|
|
11557
|
+
const separator = theme27.separator ?? " \xB7 ";
|
|
11419
11558
|
const steeringResolveRef = useRef8(null);
|
|
11420
|
-
const [steeringRecap, setSteeringRecap] =
|
|
11421
|
-
const [currentModel, setCurrentModel] =
|
|
11422
|
-
const [currentSandbox, setCurrentSandbox] =
|
|
11423
|
-
const [isTerminalSteering, setIsTerminalSteering] =
|
|
11424
|
-
const [allowInitialInlineLoader, setAllowInitialInlineLoader] =
|
|
11425
|
-
const [sessionSnapshots, setSessionSnapshots] =
|
|
11559
|
+
const [steeringRecap, setSteeringRecap] = useState21(null);
|
|
11560
|
+
const [currentModel, setCurrentModel] = useState21(model || "default");
|
|
11561
|
+
const [currentSandbox, setCurrentSandbox] = useState21(sandbox);
|
|
11562
|
+
const [isTerminalSteering, setIsTerminalSteering] = useState21(false);
|
|
11563
|
+
const [allowInitialInlineLoader, setAllowInitialInlineLoader] = useState21(!suppressInitialInlineLoader);
|
|
11564
|
+
const [sessionSnapshots, setSessionSnapshots] = useState21(
|
|
11426
11565
|
() => (initialSessionSnapshots || []).map((snapshot) => cloneSessionSnapshot(snapshot))
|
|
11427
11566
|
);
|
|
11428
|
-
const [selectedSessionKey, setSelectedSessionKey] =
|
|
11429
|
-
const [followLatest, setFollowLatest] =
|
|
11430
|
-
const [latestUnreadKey, setLatestUnreadKey] =
|
|
11431
|
-
const [previewUrl, setPreviewUrl] =
|
|
11432
|
-
const [isSteeringExploring, setIsSteeringExploring] =
|
|
11433
|
-
const isRunnerAnimating = state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool";
|
|
11567
|
+
const [selectedSessionKey, setSelectedSessionKey] = useState21(void 0);
|
|
11568
|
+
const [followLatest, setFollowLatest] = useState21(true);
|
|
11569
|
+
const [latestUnreadKey, setLatestUnreadKey] = useState21(void 0);
|
|
11570
|
+
const [previewUrl, setPreviewUrl] = useState21(initialPreviewUrl);
|
|
11571
|
+
const [isSteeringExploring, setIsSteeringExploring] = useState21(false);
|
|
11572
|
+
const isRunnerAnimating = state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool" || Boolean(state.contextCompaction?.active);
|
|
11434
11573
|
const isTerminalSteeringRef = useRef8(false);
|
|
11435
11574
|
const markSteeringExploring = useCallback7(() => {
|
|
11436
11575
|
if (state.phase === "steering" && steeringRecap) {
|
|
@@ -11463,7 +11602,7 @@ function MarathonApp({
|
|
|
11463
11602
|
},
|
|
11464
11603
|
[resetForNewSession]
|
|
11465
11604
|
);
|
|
11466
|
-
|
|
11605
|
+
useEffect20(() => {
|
|
11467
11606
|
streamRef.current = {
|
|
11468
11607
|
getCallbacks: () => callbacks,
|
|
11469
11608
|
getState: () => state,
|
|
@@ -11492,6 +11631,9 @@ function MarathonApp({
|
|
|
11492
11631
|
steeringResolveRef.current = resolve6;
|
|
11493
11632
|
});
|
|
11494
11633
|
},
|
|
11634
|
+
startContextCompaction,
|
|
11635
|
+
finishContextCompaction,
|
|
11636
|
+
reportContextNotice,
|
|
11495
11637
|
resetForNewSession,
|
|
11496
11638
|
showError,
|
|
11497
11639
|
exit: () => exit()
|
|
@@ -11500,9 +11642,12 @@ function MarathonApp({
|
|
|
11500
11642
|
callbacks,
|
|
11501
11643
|
exit,
|
|
11502
11644
|
followLatest,
|
|
11645
|
+
finishContextCompaction,
|
|
11646
|
+
reportContextNotice,
|
|
11503
11647
|
setIsSteeringExploring,
|
|
11504
11648
|
setSteering,
|
|
11505
11649
|
showError,
|
|
11650
|
+
startContextCompaction,
|
|
11506
11651
|
state,
|
|
11507
11652
|
streamRef,
|
|
11508
11653
|
resetForNewSession
|
|
@@ -11513,32 +11658,32 @@ function MarathonApp({
|
|
|
11513
11658
|
const contentHeight = Math.max(5, terminalRows - chromeRows);
|
|
11514
11659
|
const isStacked = terminalWidth < STACKED_THRESHOLD;
|
|
11515
11660
|
const toolPanelWidth = terminalWidth < NARROW_THRESHOLD ? TOOL_PANEL_NARROW : TOOL_PANEL_WIDE;
|
|
11516
|
-
const [ctrlCPressed, setCtrlCPressed] =
|
|
11661
|
+
const [ctrlCPressed, setCtrlCPressed] = useState21(false);
|
|
11517
11662
|
const ctrlCTimeout = useRef8(null);
|
|
11518
|
-
const [activeScreen, setActiveScreen] =
|
|
11663
|
+
const [activeScreen, setActiveScreen] = useState21("overview");
|
|
11519
11664
|
const showEventStream = activeScreen === "events";
|
|
11520
11665
|
const showToolsPanel = activeScreen === "tools";
|
|
11521
11666
|
const showFilesPanel = activeScreen === "files";
|
|
11522
|
-
const [showHelpOverlay, setShowHelpOverlay] =
|
|
11523
|
-
const [helpScrollOffset, setHelpScrollOffset] =
|
|
11524
|
-
const [showSessionMenu, setShowSessionMenu] =
|
|
11525
|
-
const [fileCursor, setFileCursor] =
|
|
11526
|
-
const [detailFile, setDetailFile] =
|
|
11527
|
-
const [detailFileContent, setDetailFileContent] =
|
|
11528
|
-
const [detailFileTotalLines, setDetailFileTotalLines] =
|
|
11529
|
-
const [detailFileTruncated, setDetailFileTruncated] =
|
|
11530
|
-
const [fileDetailScrollOffset, setFileDetailScrollOffset] =
|
|
11531
|
-
const [scrollOffset, setScrollOffset] =
|
|
11532
|
-
const [reasoningCollapsed, setReasoningCollapsed] =
|
|
11533
|
-
const [eventCursor, setEventCursor] =
|
|
11534
|
-
const [detailEvent, setDetailEvent] =
|
|
11535
|
-
const [detailScrollOffset, setDetailScrollOffset] =
|
|
11536
|
-
const [toolCursor, setToolCursor] =
|
|
11537
|
-
const [detailToolEntry, setDetailToolEntry] =
|
|
11538
|
-
const [toolDetailScrollOffset, setToolDetailScrollOffset] =
|
|
11539
|
-
const [goalExpanded, setGoalExpanded] =
|
|
11540
|
-
const [upgradeModalDismissed, setUpgradeModalDismissed] =
|
|
11541
|
-
const [clipboardFlash, setClipboardFlash] =
|
|
11667
|
+
const [showHelpOverlay, setShowHelpOverlay] = useState21(false);
|
|
11668
|
+
const [helpScrollOffset, setHelpScrollOffset] = useState21(0);
|
|
11669
|
+
const [showSessionMenu, setShowSessionMenu] = useState21(false);
|
|
11670
|
+
const [fileCursor, setFileCursor] = useState21(0);
|
|
11671
|
+
const [detailFile, setDetailFile] = useState21(null);
|
|
11672
|
+
const [detailFileContent, setDetailFileContent] = useState21(null);
|
|
11673
|
+
const [detailFileTotalLines, setDetailFileTotalLines] = useState21(0);
|
|
11674
|
+
const [detailFileTruncated, setDetailFileTruncated] = useState21(false);
|
|
11675
|
+
const [fileDetailScrollOffset, setFileDetailScrollOffset] = useState21(0);
|
|
11676
|
+
const [scrollOffset, setScrollOffset] = useState21(0);
|
|
11677
|
+
const [reasoningCollapsed, setReasoningCollapsed] = useState21(false);
|
|
11678
|
+
const [eventCursor, setEventCursor] = useState21(-1);
|
|
11679
|
+
const [detailEvent, setDetailEvent] = useState21(null);
|
|
11680
|
+
const [detailScrollOffset, setDetailScrollOffset] = useState21(0);
|
|
11681
|
+
const [toolCursor, setToolCursor] = useState21(-1);
|
|
11682
|
+
const [detailToolEntry, setDetailToolEntry] = useState21(null);
|
|
11683
|
+
const [toolDetailScrollOffset, setToolDetailScrollOffset] = useState21(0);
|
|
11684
|
+
const [goalExpanded, setGoalExpanded] = useState21(false);
|
|
11685
|
+
const [upgradeModalDismissed, setUpgradeModalDismissed] = useState21(false);
|
|
11686
|
+
const [clipboardFlash, setClipboardFlash] = useState21(null);
|
|
11542
11687
|
const flashTimeout = useRef8(null);
|
|
11543
11688
|
const billingPageUrl = billingUrl || `${(dashboardUrl || "https://use.runtype.com").replace(/\/$/, "")}/settings/billing`;
|
|
11544
11689
|
function showFlash(msg) {
|
|
@@ -11584,7 +11729,7 @@ function MarathonApp({
|
|
|
11584
11729
|
}
|
|
11585
11730
|
}, [agentPageUrl]);
|
|
11586
11731
|
const latestCompletedSessionIndex = sessionSnapshots[sessionSnapshots.length - 1]?.sessionIndex ?? initialSessionCount;
|
|
11587
|
-
const shouldShowLiveTab = state.phase !== "idle" && state.phase !== "steering" && state.phase !== "complete" && (Boolean(state.content) || Boolean(state.reasoning) || state.tools.length > 0 || state.rawEvents.length > 0 || state.phase === "thinking" || state.phase === "error");
|
|
11732
|
+
const shouldShowLiveTab = Boolean(state.contextCompaction?.active) || state.phase !== "idle" && state.phase !== "steering" && state.phase !== "complete" && (Boolean(state.content) || Boolean(state.reasoning) || state.tools.length > 0 || state.rawEvents.length > 0 || state.phase === "thinking" || state.phase === "error");
|
|
11588
11733
|
const liveSessionSnapshot = useMemo10(
|
|
11589
11734
|
() => shouldShowLiveTab ? buildLiveSessionSnapshot(state, latestCompletedSessionIndex + 1, currentModel) : void 0,
|
|
11590
11735
|
[currentModel, latestCompletedSessionIndex, shouldShowLiveTab, state]
|
|
@@ -11643,25 +11788,25 @@ function MarathonApp({
|
|
|
11643
11788
|
},
|
|
11644
11789
|
[latestSessionKey]
|
|
11645
11790
|
);
|
|
11646
|
-
|
|
11791
|
+
useEffect20(() => {
|
|
11647
11792
|
if (!selectedSessionKey && latestSessionKey) {
|
|
11648
11793
|
setSelectedSessionKey(latestSessionKey);
|
|
11649
11794
|
}
|
|
11650
11795
|
}, [latestSessionKey, selectedSessionKey]);
|
|
11651
|
-
|
|
11796
|
+
useEffect20(() => {
|
|
11652
11797
|
if (followLatest && latestSessionKey && selectedSessionKey !== latestSessionKey) {
|
|
11653
11798
|
setSelectedSessionKey(latestSessionKey);
|
|
11654
11799
|
}
|
|
11655
11800
|
}, [followLatest, latestSessionKey, selectedSessionKey]);
|
|
11656
|
-
|
|
11801
|
+
useEffect20(() => {
|
|
11657
11802
|
if (selectedSessionKey && selectedSessionKey === latestSessionKey && latestUnreadKey) {
|
|
11658
11803
|
setLatestUnreadKey(void 0);
|
|
11659
11804
|
}
|
|
11660
11805
|
}, [latestSessionKey, latestUnreadKey, selectedSessionKey]);
|
|
11661
|
-
|
|
11806
|
+
useEffect20(() => {
|
|
11662
11807
|
setUpgradeModalDismissed(false);
|
|
11663
11808
|
}, [upgradePromptKey]);
|
|
11664
|
-
|
|
11809
|
+
useEffect20(() => {
|
|
11665
11810
|
const liveActivityKey = liveSessionSnapshot ? `${liveSessionSnapshot.sessionIndex}:${state.phase}:${state.content.length}:${state.reasoning.length}:${state.tools.length}:${state.rawEvents.length}` : void 0;
|
|
11666
11811
|
if (!liveActivityKey) {
|
|
11667
11812
|
latestLiveActivityRef.current = void 0;
|
|
@@ -11681,7 +11826,7 @@ function MarathonApp({
|
|
|
11681
11826
|
state.reasoning.length,
|
|
11682
11827
|
state.tools.length
|
|
11683
11828
|
]);
|
|
11684
|
-
|
|
11829
|
+
useEffect20(() => {
|
|
11685
11830
|
const deploySandboxTool = state.tools.find(
|
|
11686
11831
|
(t) => t.name === "deploy_sandbox" && t.status === "complete" && t.result
|
|
11687
11832
|
);
|
|
@@ -11692,19 +11837,19 @@ function MarathonApp({
|
|
|
11692
11837
|
}
|
|
11693
11838
|
}
|
|
11694
11839
|
}, [state.tools]);
|
|
11695
|
-
|
|
11840
|
+
useEffect20(() => {
|
|
11696
11841
|
if (showEventStream && displayedEvents.length > 0 && eventCursor === -1) {
|
|
11697
11842
|
setEventCursor(displayedEvents.length - 1);
|
|
11698
11843
|
}
|
|
11699
11844
|
}, [displayedEvents.length, eventCursor, showEventStream]);
|
|
11700
|
-
|
|
11845
|
+
useEffect20(() => {
|
|
11701
11846
|
if (allowInitialInlineLoader) return;
|
|
11702
11847
|
const hasVisibleSessionActivity = Boolean(state.content.trim()) || Boolean(state.reasoning.trim()) || state.tools.length > 0 || state.error !== null;
|
|
11703
11848
|
if (hasVisibleSessionActivity) {
|
|
11704
11849
|
setAllowInitialInlineLoader(true);
|
|
11705
11850
|
}
|
|
11706
11851
|
}, [allowInitialInlineLoader, state.content, state.error, state.reasoning, state.tools.length]);
|
|
11707
|
-
|
|
11852
|
+
useEffect20(() => {
|
|
11708
11853
|
if (showToolsPanel && displayedTools.length > 0 && toolCursor === -1) {
|
|
11709
11854
|
setToolCursor(displayedTools.length - 1);
|
|
11710
11855
|
}
|
|
@@ -12060,7 +12205,7 @@ function MarathonApp({
|
|
|
12060
12205
|
return;
|
|
12061
12206
|
}
|
|
12062
12207
|
});
|
|
12063
|
-
|
|
12208
|
+
useEffect20(() => {
|
|
12064
12209
|
return () => {
|
|
12065
12210
|
if (ctrlCTimeout.current) clearTimeout(ctrlCTimeout.current);
|
|
12066
12211
|
if (flashTimeout.current) clearTimeout(flashTimeout.current);
|
|
@@ -12072,7 +12217,8 @@ function MarathonApp({
|
|
|
12072
12217
|
const hasTools = displayedTools.length > 0;
|
|
12073
12218
|
const hasReasoning = Boolean(displayedReasoning.trim());
|
|
12074
12219
|
const showThinkingIndicator = selectedIsLive && state.phase === "thinking" && !hasReasoning;
|
|
12075
|
-
const
|
|
12220
|
+
const showContextCompactionIndicator = selectedIsLive && Boolean(state.contextCompaction?.active);
|
|
12221
|
+
const showLoadingAnimation = !showContextCompactionIndicator && shouldShowMarathonLoadingAnimation({
|
|
12076
12222
|
allowInitialInlineLoader,
|
|
12077
12223
|
content: displayedContent,
|
|
12078
12224
|
reasoning: displayedReasoning,
|
|
@@ -12175,10 +12321,11 @@ function MarathonApp({
|
|
|
12175
12321
|
const steeringPromptRows = STEERING_PROMPT_ROWS + steeringWarningRows;
|
|
12176
12322
|
const reasoningHintRows = hasReasoning ? 1 : 0;
|
|
12177
12323
|
const thinkingRows = showThinkingIndicator ? 2 : 0;
|
|
12324
|
+
const compactionIndicatorRows = showContextCompactionIndicator ? 1 : 0;
|
|
12178
12325
|
const reasoningLiveRows = hasReasoning && !reasoningCollapsed && selectedIsLive && state.phase === "thinking" ? 1 : 0;
|
|
12179
12326
|
const maxReasoningRows = Math.max(
|
|
12180
12327
|
0,
|
|
12181
|
-
adjustedContentHeight - reasoningHintRows - reasoningLiveRows - thinkingRows - 3
|
|
12328
|
+
adjustedContentHeight - reasoningHintRows - reasoningLiveRows - thinkingRows - compactionIndicatorRows - 3
|
|
12182
12329
|
);
|
|
12183
12330
|
const targetReasoningRows = hasReasoning && !reasoningCollapsed ? Math.min(maxReasoningRows, Math.max(3, Math.min(8, Math.floor(adjustedContentHeight * 0.3)))) : 0;
|
|
12184
12331
|
const visibleReasoningLines = useMemo10(
|
|
@@ -12188,7 +12335,7 @@ function MarathonApp({
|
|
|
12188
12335
|
const reasoningBodyRows = reasoningCollapsed ? 0 : visibleReasoningLines.length;
|
|
12189
12336
|
const transcriptRows = Math.max(
|
|
12190
12337
|
3,
|
|
12191
|
-
adjustedContentHeight - reasoningHintRows - reasoningBodyRows - reasoningLiveRows - thinkingRows
|
|
12338
|
+
adjustedContentHeight - reasoningHintRows - reasoningBodyRows - reasoningLiveRows - thinkingRows - compactionIndicatorRows
|
|
12192
12339
|
);
|
|
12193
12340
|
const upgradeModalWidth = Math.max(24, Math.min(terminalWidth - 6, 88));
|
|
12194
12341
|
const showUpgradeBrowseHint = canBrowseAfterUpgradeError && selectedIsLive && !displayedContent.trim() && !displayedReasoning.trim() && displayedTools.length === 0 && displayedEvents.length === 0;
|
|
@@ -12199,7 +12346,7 @@ function MarathonApp({
|
|
|
12199
12346
|
height: terminalRows,
|
|
12200
12347
|
width: terminalWidth,
|
|
12201
12348
|
children: [
|
|
12202
|
-
/* @__PURE__ */
|
|
12349
|
+
/* @__PURE__ */ jsx29(
|
|
12203
12350
|
SessionHeader,
|
|
12204
12351
|
{
|
|
12205
12352
|
sessionName: taskName,
|
|
@@ -12217,8 +12364,8 @@ function MarathonApp({
|
|
|
12217
12364
|
previewUrl
|
|
12218
12365
|
}
|
|
12219
12366
|
),
|
|
12220
|
-
/* @__PURE__ */
|
|
12221
|
-
hasTabs && /* @__PURE__ */
|
|
12367
|
+
/* @__PURE__ */ jsx29(Box24, { marginLeft: 1, children: /* @__PURE__ */ jsx29(ScreenTabs, { activeTab: activeScreen, width: terminalWidth - 1 }) }),
|
|
12368
|
+
hasTabs && /* @__PURE__ */ jsx29(Box24, { width: terminalWidth, marginBottom: 1, marginLeft: 1, children: /* @__PURE__ */ jsx29(
|
|
12222
12369
|
SessionTabs,
|
|
12223
12370
|
{
|
|
12224
12371
|
tabs: visibleTabs.tabs,
|
|
@@ -12227,13 +12374,13 @@ function MarathonApp({
|
|
|
12227
12374
|
shortcutHint: "Shift+\\u2190/\\u2192: runs"
|
|
12228
12375
|
}
|
|
12229
12376
|
) }),
|
|
12230
|
-
showFilesPanel ? /* @__PURE__ */
|
|
12377
|
+
showFilesPanel ? /* @__PURE__ */ jsx29(
|
|
12231
12378
|
Box24,
|
|
12232
12379
|
{
|
|
12233
12380
|
flexDirection: "column",
|
|
12234
12381
|
height: adjustedContentHeight,
|
|
12235
12382
|
overflow: "hidden",
|
|
12236
|
-
children: /* @__PURE__ */
|
|
12383
|
+
children: /* @__PURE__ */ jsx29(
|
|
12237
12384
|
FilesPanel,
|
|
12238
12385
|
{
|
|
12239
12386
|
files: trackedFiles,
|
|
@@ -12248,13 +12395,13 @@ function MarathonApp({
|
|
|
12248
12395
|
}
|
|
12249
12396
|
)
|
|
12250
12397
|
}
|
|
12251
|
-
) : showEventStream ? /* @__PURE__ */
|
|
12398
|
+
) : showEventStream ? /* @__PURE__ */ jsx29(
|
|
12252
12399
|
Box24,
|
|
12253
12400
|
{
|
|
12254
12401
|
flexDirection: "column",
|
|
12255
12402
|
height: adjustedContentHeight,
|
|
12256
12403
|
overflow: "hidden",
|
|
12257
|
-
children: /* @__PURE__ */
|
|
12404
|
+
children: /* @__PURE__ */ jsx29(
|
|
12258
12405
|
EventStreamPanel,
|
|
12259
12406
|
{
|
|
12260
12407
|
events: displayedEvents,
|
|
@@ -12267,13 +12414,13 @@ function MarathonApp({
|
|
|
12267
12414
|
}
|
|
12268
12415
|
)
|
|
12269
12416
|
}
|
|
12270
|
-
) : showToolsPanel ? /* @__PURE__ */
|
|
12417
|
+
) : showToolsPanel ? /* @__PURE__ */ jsx29(
|
|
12271
12418
|
Box24,
|
|
12272
12419
|
{
|
|
12273
12420
|
flexDirection: "column",
|
|
12274
12421
|
height: adjustedContentHeight,
|
|
12275
12422
|
overflow: "hidden",
|
|
12276
|
-
children: /* @__PURE__ */
|
|
12423
|
+
children: /* @__PURE__ */ jsx29(
|
|
12277
12424
|
ToolsPanel,
|
|
12278
12425
|
{
|
|
12279
12426
|
tools: displayedTools,
|
|
@@ -12301,7 +12448,7 @@ function MarathonApp({
|
|
|
12301
12448
|
marginRight: contentMarginRight,
|
|
12302
12449
|
children: [
|
|
12303
12450
|
/* @__PURE__ */ jsxs22(Box24, { flexDirection: "row", flexGrow: 1, overflow: "hidden", marginBottom: 1, children: [
|
|
12304
|
-
/* @__PURE__ */
|
|
12451
|
+
/* @__PURE__ */ jsx29(Box24, { flexDirection: "column", flexGrow: 1, marginRight: 1, children: /* @__PURE__ */ jsx29(
|
|
12305
12452
|
StreamOutput,
|
|
12306
12453
|
{
|
|
12307
12454
|
content: displayedContent,
|
|
@@ -12315,7 +12462,7 @@ function MarathonApp({
|
|
|
12315
12462
|
const steeringVisibleRows = adjustedContentHeight - steeringPromptRows - 1;
|
|
12316
12463
|
const steeringTotalLines = displayedContent.split("\n").length;
|
|
12317
12464
|
const steeringMaxScroll = Math.max(0, steeringTotalLines - steeringVisibleRows);
|
|
12318
|
-
return /* @__PURE__ */
|
|
12465
|
+
return /* @__PURE__ */ jsx29(
|
|
12319
12466
|
Scrollbar,
|
|
12320
12467
|
{
|
|
12321
12468
|
totalLines: steeringTotalLines,
|
|
@@ -12326,7 +12473,7 @@ function MarathonApp({
|
|
|
12326
12473
|
);
|
|
12327
12474
|
})()
|
|
12328
12475
|
] }),
|
|
12329
|
-
/* @__PURE__ */
|
|
12476
|
+
/* @__PURE__ */ jsx29(
|
|
12330
12477
|
SteeringPrompt,
|
|
12331
12478
|
{
|
|
12332
12479
|
onSubmit: handleSteeringSubmit,
|
|
@@ -12344,18 +12491,18 @@ function MarathonApp({
|
|
|
12344
12491
|
]
|
|
12345
12492
|
}
|
|
12346
12493
|
),
|
|
12347
|
-
!isStacked && (hasTools || hasReasoning) && /* @__PURE__ */
|
|
12494
|
+
!isStacked && (hasTools || hasReasoning) && /* @__PURE__ */ jsx29(
|
|
12348
12495
|
Box24,
|
|
12349
12496
|
{
|
|
12350
12497
|
flexDirection: "column",
|
|
12351
12498
|
width: toolPanelWidth,
|
|
12352
12499
|
flexShrink: 0,
|
|
12353
12500
|
borderStyle: "single",
|
|
12354
|
-
borderColor:
|
|
12355
|
-
backgroundColor:
|
|
12356
|
-
paddingX:
|
|
12357
|
-
paddingY:
|
|
12358
|
-
children: /* @__PURE__ */
|
|
12501
|
+
borderColor: theme27.border,
|
|
12502
|
+
backgroundColor: theme27.background,
|
|
12503
|
+
paddingX: theme27.panelPaddingX,
|
|
12504
|
+
paddingY: theme27.panelPaddingY,
|
|
12505
|
+
children: /* @__PURE__ */ jsx29(
|
|
12359
12506
|
ToolPanel,
|
|
12360
12507
|
{
|
|
12361
12508
|
tools: displayedTools,
|
|
@@ -12375,7 +12522,7 @@ function MarathonApp({
|
|
|
12375
12522
|
height: adjustedContentHeight,
|
|
12376
12523
|
overflow: "hidden",
|
|
12377
12524
|
children: [
|
|
12378
|
-
/* @__PURE__ */
|
|
12525
|
+
/* @__PURE__ */ jsx29(
|
|
12379
12526
|
Box24,
|
|
12380
12527
|
{
|
|
12381
12528
|
flexDirection: "column",
|
|
@@ -12383,13 +12530,13 @@ function MarathonApp({
|
|
|
12383
12530
|
flexShrink: 1,
|
|
12384
12531
|
marginLeft: contentMarginLeft,
|
|
12385
12532
|
marginRight: contentMarginRight,
|
|
12386
|
-
children: showLoadingAnimation ? /* @__PURE__ */
|
|
12533
|
+
children: showLoadingAnimation ? /* @__PURE__ */ jsx29(
|
|
12387
12534
|
Box24,
|
|
12388
12535
|
{
|
|
12389
12536
|
flexGrow: 1,
|
|
12390
12537
|
minHeight: adjustedContentHeight,
|
|
12391
12538
|
overflow: "hidden",
|
|
12392
|
-
children: /* @__PURE__ */
|
|
12539
|
+
children: /* @__PURE__ */ jsx29(
|
|
12393
12540
|
LoadingAnimation,
|
|
12394
12541
|
{
|
|
12395
12542
|
width: transcriptPaneWidth,
|
|
@@ -12398,7 +12545,7 @@ function MarathonApp({
|
|
|
12398
12545
|
)
|
|
12399
12546
|
}
|
|
12400
12547
|
) : /* @__PURE__ */ jsxs22(Fragment3, { children: [
|
|
12401
|
-
hasReasoning && /* @__PURE__ */
|
|
12548
|
+
hasReasoning && /* @__PURE__ */ jsx29(Box24, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx29(
|
|
12402
12549
|
ReasoningBlock,
|
|
12403
12550
|
{
|
|
12404
12551
|
lines: visibleReasoningLines,
|
|
@@ -12407,8 +12554,9 @@ function MarathonApp({
|
|
|
12407
12554
|
showToggleHint: true
|
|
12408
12555
|
}
|
|
12409
12556
|
) }),
|
|
12410
|
-
showThinkingIndicator && /* @__PURE__ */
|
|
12411
|
-
|
|
12557
|
+
showThinkingIndicator && /* @__PURE__ */ jsx29(ThinkingIndicator, { startedAt: state.thinkingStartedAt }),
|
|
12558
|
+
showContextCompactionIndicator && state.contextCompaction && /* @__PURE__ */ jsx29(ContextCompactionIndicator, { compaction: state.contextCompaction }),
|
|
12559
|
+
showUpgradeBrowseHint && /* @__PURE__ */ jsx29(Box24, { marginBottom: 1, children: /* @__PURE__ */ jsx29(
|
|
12412
12560
|
ReasoningBlock,
|
|
12413
12561
|
{
|
|
12414
12562
|
lines: [
|
|
@@ -12419,7 +12567,7 @@ function MarathonApp({
|
|
|
12419
12567
|
}
|
|
12420
12568
|
) }),
|
|
12421
12569
|
/* @__PURE__ */ jsxs22(Box24, { flexDirection: "row", children: [
|
|
12422
|
-
/* @__PURE__ */
|
|
12570
|
+
/* @__PURE__ */ jsx29(Box24, { flexDirection: "column", flexGrow: 1, marginRight: 1, children: /* @__PURE__ */ jsx29(
|
|
12423
12571
|
StreamOutput,
|
|
12424
12572
|
{
|
|
12425
12573
|
content: displayedContent,
|
|
@@ -12432,7 +12580,7 @@ function MarathonApp({
|
|
|
12432
12580
|
(() => {
|
|
12433
12581
|
const overviewTotalLines = displayedContent.split("\n").length;
|
|
12434
12582
|
const overviewMaxScroll = Math.max(0, overviewTotalLines - transcriptRows);
|
|
12435
|
-
return /* @__PURE__ */
|
|
12583
|
+
return /* @__PURE__ */ jsx29(
|
|
12436
12584
|
Scrollbar,
|
|
12437
12585
|
{
|
|
12438
12586
|
totalLines: overviewTotalLines,
|
|
@@ -12443,22 +12591,22 @@ function MarathonApp({
|
|
|
12443
12591
|
);
|
|
12444
12592
|
})()
|
|
12445
12593
|
] }),
|
|
12446
|
-
selectedIsLive && state.error && !upgradePrompt && /* @__PURE__ */
|
|
12594
|
+
selectedIsLive && state.error && !upgradePrompt && /* @__PURE__ */ jsx29(ErrorDisplay3, { error: state.error })
|
|
12447
12595
|
] })
|
|
12448
12596
|
}
|
|
12449
12597
|
),
|
|
12450
|
-
(hasTools || hasReasoning) && /* @__PURE__ */
|
|
12598
|
+
(hasTools || hasReasoning) && /* @__PURE__ */ jsx29(
|
|
12451
12599
|
Box24,
|
|
12452
12600
|
{
|
|
12453
12601
|
flexDirection: "column",
|
|
12454
12602
|
width: isStacked ? void 0 : toolPanelWidth,
|
|
12455
12603
|
flexShrink: 0,
|
|
12456
12604
|
borderStyle: "single",
|
|
12457
|
-
borderColor:
|
|
12458
|
-
backgroundColor:
|
|
12459
|
-
paddingX:
|
|
12460
|
-
paddingY:
|
|
12461
|
-
children: /* @__PURE__ */
|
|
12605
|
+
borderColor: theme27.border,
|
|
12606
|
+
backgroundColor: theme27.background,
|
|
12607
|
+
paddingX: theme27.panelPaddingX,
|
|
12608
|
+
paddingY: theme27.panelPaddingY,
|
|
12609
|
+
children: /* @__PURE__ */ jsx29(
|
|
12462
12610
|
ToolPanel,
|
|
12463
12611
|
{
|
|
12464
12612
|
tools: displayedTools,
|
|
@@ -12472,7 +12620,7 @@ function MarathonApp({
|
|
|
12472
12620
|
]
|
|
12473
12621
|
}
|
|
12474
12622
|
),
|
|
12475
|
-
showHelpOverlay && /* @__PURE__ */
|
|
12623
|
+
showHelpOverlay && /* @__PURE__ */ jsx29(
|
|
12476
12624
|
Box24,
|
|
12477
12625
|
{
|
|
12478
12626
|
width: terminalWidth,
|
|
@@ -12481,8 +12629,8 @@ function MarathonApp({
|
|
|
12481
12629
|
justifyContent: "center",
|
|
12482
12630
|
alignItems: "center",
|
|
12483
12631
|
flexShrink: 0,
|
|
12484
|
-
backgroundColor:
|
|
12485
|
-
children: /* @__PURE__ */
|
|
12632
|
+
backgroundColor: theme27.surfaceMuted,
|
|
12633
|
+
children: /* @__PURE__ */ jsx29(
|
|
12486
12634
|
HelpPanel,
|
|
12487
12635
|
{
|
|
12488
12636
|
width: terminalWidth,
|
|
@@ -12493,7 +12641,7 @@ function MarathonApp({
|
|
|
12493
12641
|
)
|
|
12494
12642
|
}
|
|
12495
12643
|
),
|
|
12496
|
-
showSessionMenu && /* @__PURE__ */
|
|
12644
|
+
showSessionMenu && /* @__PURE__ */ jsx29(
|
|
12497
12645
|
Box24,
|
|
12498
12646
|
{
|
|
12499
12647
|
width: terminalWidth,
|
|
@@ -12502,8 +12650,8 @@ function MarathonApp({
|
|
|
12502
12650
|
justifyContent: "center",
|
|
12503
12651
|
alignItems: "center",
|
|
12504
12652
|
flexShrink: 0,
|
|
12505
|
-
backgroundColor:
|
|
12506
|
-
children: /* @__PURE__ */
|
|
12653
|
+
backgroundColor: theme27.surfaceMuted,
|
|
12654
|
+
children: /* @__PURE__ */ jsx29(
|
|
12507
12655
|
SessionActionMenu,
|
|
12508
12656
|
{
|
|
12509
12657
|
onCopySession: handleCopySession,
|
|
@@ -12516,7 +12664,7 @@ function MarathonApp({
|
|
|
12516
12664
|
)
|
|
12517
12665
|
}
|
|
12518
12666
|
),
|
|
12519
|
-
showUpgradeModal && upgradePrompt && /* @__PURE__ */
|
|
12667
|
+
showUpgradeModal && upgradePrompt && /* @__PURE__ */ jsx29(
|
|
12520
12668
|
Box24,
|
|
12521
12669
|
{
|
|
12522
12670
|
marginTop: -adjustedContentHeight,
|
|
@@ -12525,15 +12673,15 @@ function MarathonApp({
|
|
|
12525
12673
|
justifyContent: "center",
|
|
12526
12674
|
alignItems: "center",
|
|
12527
12675
|
flexShrink: 0,
|
|
12528
|
-
children: /* @__PURE__ */
|
|
12676
|
+
children: /* @__PURE__ */ jsx29(UpgradeModal, { prompt: upgradePrompt, width: upgradeModalWidth })
|
|
12529
12677
|
}
|
|
12530
12678
|
),
|
|
12531
|
-
/* @__PURE__ */
|
|
12679
|
+
/* @__PURE__ */ jsx29(
|
|
12532
12680
|
StatusBar,
|
|
12533
12681
|
{
|
|
12534
|
-
left: /* @__PURE__ */ jsxs22(Text26, { color:
|
|
12682
|
+
left: /* @__PURE__ */ jsxs22(Text26, { color: theme27.textMuted, children: [
|
|
12535
12683
|
`Model: ${currentModel}${currentSandbox ? `${separator}Sandbox: ${currentSandbox}` : ""}`,
|
|
12536
|
-
previewUrl && /* @__PURE__ */
|
|
12684
|
+
previewUrl && /* @__PURE__ */ jsx29(Text26, { color: theme27.accent, children: `${separator}\x1B]8;;${previewUrl}\x07preview\x1B]8;;\x07` })
|
|
12537
12685
|
] }),
|
|
12538
12686
|
center: showFilesPanel ? filesCenter : showEventStream ? detailCenter : showToolsPanel ? toolsCenter : void 0,
|
|
12539
12687
|
right: statusRight
|
|
@@ -12545,10 +12693,10 @@ function MarathonApp({
|
|
|
12545
12693
|
}
|
|
12546
12694
|
|
|
12547
12695
|
// src/ink/marathon/MarathonStartupShell.tsx
|
|
12548
|
-
import { useEffect as
|
|
12696
|
+
import { useEffect as useEffect21, useRef as useRef9, useState as useState22 } from "react";
|
|
12549
12697
|
import { Box as Box25, Text as Text27, useApp as useApp5, useInput as useInput11, useStdout as useStdout5 } from "ink";
|
|
12550
|
-
import { theme as
|
|
12551
|
-
import { jsx as
|
|
12698
|
+
import { theme as theme28 } from "@runtypelabs/ink-components";
|
|
12699
|
+
import { jsx as jsx30, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
12552
12700
|
var SCROLL_HINT = "\u2191\u2193 Enter 1-3";
|
|
12553
12701
|
var PROMPT_COLUMN_MAX = 68;
|
|
12554
12702
|
var MIN_HOLD_MS = 1500;
|
|
@@ -12601,17 +12749,20 @@ function MarathonStartupShell({
|
|
|
12601
12749
|
const { stdout } = useStdout5();
|
|
12602
12750
|
const mountedAtRef = useRef9(Date.now());
|
|
12603
12751
|
const promptResolverRef = useRef9(null);
|
|
12752
|
+
const modelResolverRef = useRef9(null);
|
|
12604
12753
|
const appReadyResolverRef = useRef9(null);
|
|
12605
12754
|
const dismissResolverRef = useRef9(null);
|
|
12606
12755
|
const transitionPromiseRef = useRef9(null);
|
|
12607
12756
|
const latestAppPropsRef = useRef9(marathonAppProps);
|
|
12608
|
-
const [statusMessage, setStatusMessage] =
|
|
12609
|
-
const [scene, setScene] =
|
|
12610
|
-
const [transition, setTransition] =
|
|
12611
|
-
const [prompt, setPrompt] =
|
|
12612
|
-
const [
|
|
12757
|
+
const [statusMessage, setStatusMessage] = useState22("preparing marathon");
|
|
12758
|
+
const [scene, setScene] = useState22("splash");
|
|
12759
|
+
const [transition, setTransition] = useState22(null);
|
|
12760
|
+
const [prompt, setPrompt] = useState22(null);
|
|
12761
|
+
const [modelChoices, setModelChoices] = useState22(null);
|
|
12762
|
+
const [currentModel, setCurrentModel] = useState22("default");
|
|
12763
|
+
const [selectedPromptIndex, setSelectedPromptIndex] = useState22(0);
|
|
12613
12764
|
latestAppPropsRef.current = marathonAppProps;
|
|
12614
|
-
|
|
12765
|
+
useEffect21(() => {
|
|
12615
12766
|
if (scene !== "app" || !appReadyResolverRef.current) return;
|
|
12616
12767
|
const resolve6 = appReadyResolverRef.current;
|
|
12617
12768
|
appReadyResolverRef.current = null;
|
|
@@ -12625,6 +12776,7 @@ function MarathonStartupShell({
|
|
|
12625
12776
|
const promise = new Promise((resolve6) => {
|
|
12626
12777
|
globalThis.setTimeout(() => {
|
|
12627
12778
|
setPrompt(null);
|
|
12779
|
+
setModelChoices(null);
|
|
12628
12780
|
setTransition({
|
|
12629
12781
|
startedAt: Date.now(),
|
|
12630
12782
|
target
|
|
@@ -12655,18 +12807,27 @@ function MarathonStartupShell({
|
|
|
12655
12807
|
transitionPromiseRef.current = promise;
|
|
12656
12808
|
return promise;
|
|
12657
12809
|
};
|
|
12658
|
-
|
|
12810
|
+
useEffect21(() => {
|
|
12659
12811
|
startupRef.current = {
|
|
12660
12812
|
setStatus: (message) => {
|
|
12661
12813
|
setStatusMessage(message);
|
|
12662
12814
|
},
|
|
12663
12815
|
requestStateChoice: async (nextPrompt) => {
|
|
12816
|
+
setModelChoices(null);
|
|
12664
12817
|
setPrompt(nextPrompt);
|
|
12665
12818
|
setSelectedPromptIndex(0);
|
|
12666
12819
|
return new Promise((resolve6) => {
|
|
12667
12820
|
promptResolverRef.current = resolve6;
|
|
12668
12821
|
});
|
|
12669
12822
|
},
|
|
12823
|
+
requestModelChoice: async (nextCurrentModel, models) => {
|
|
12824
|
+
setPrompt(null);
|
|
12825
|
+
setCurrentModel(nextCurrentModel);
|
|
12826
|
+
setModelChoices(models);
|
|
12827
|
+
return new Promise((resolve6) => {
|
|
12828
|
+
modelResolverRef.current = resolve6;
|
|
12829
|
+
});
|
|
12830
|
+
},
|
|
12670
12831
|
completeStartup: () => beginTransition("app"),
|
|
12671
12832
|
dismiss: () => beginTransition("exit")
|
|
12672
12833
|
};
|
|
@@ -12680,7 +12841,7 @@ function MarathonStartupShell({
|
|
|
12680
12841
|
process.kill(process.pid, "SIGINT");
|
|
12681
12842
|
return;
|
|
12682
12843
|
}
|
|
12683
|
-
if (!prompt || transition) return;
|
|
12844
|
+
if (!prompt || transition || modelChoices) return;
|
|
12684
12845
|
if (key.upArrow || input === "k") {
|
|
12685
12846
|
setSelectedPromptIndex((current) => (current - 1 + prompt.choices.length) % prompt.choices.length);
|
|
12686
12847
|
return;
|
|
@@ -12717,7 +12878,7 @@ function MarathonStartupShell({
|
|
|
12717
12878
|
const promptShellModel = prompt ? buildPromptShellModel(prompt, promptColumnWidth) : null;
|
|
12718
12879
|
const selectedChoice = prompt?.choices[selectedPromptIndex];
|
|
12719
12880
|
if (scene === "app" && marathonAppProps) {
|
|
12720
|
-
return /* @__PURE__ */
|
|
12881
|
+
return /* @__PURE__ */ jsx30(
|
|
12721
12882
|
MarathonApp,
|
|
12722
12883
|
{
|
|
12723
12884
|
...marathonAppProps,
|
|
@@ -12725,38 +12886,56 @@ function MarathonStartupShell({
|
|
|
12725
12886
|
}
|
|
12726
12887
|
);
|
|
12727
12888
|
}
|
|
12728
|
-
return /* @__PURE__ */
|
|
12889
|
+
return /* @__PURE__ */ jsx30(
|
|
12729
12890
|
Box25,
|
|
12730
12891
|
{
|
|
12731
12892
|
width: terminalWidth,
|
|
12732
12893
|
height: terminalRows,
|
|
12733
|
-
backgroundColor:
|
|
12894
|
+
backgroundColor: theme28.background,
|
|
12734
12895
|
flexDirection: "column",
|
|
12735
12896
|
justifyContent: "center",
|
|
12736
12897
|
alignItems: "center",
|
|
12737
12898
|
children: /* @__PURE__ */ jsxs23(Box25, { flexDirection: "column", alignItems: "center", children: [
|
|
12738
|
-
!prompt && /* @__PURE__ */
|
|
12899
|
+
!prompt && !modelChoices && /* @__PURE__ */ jsx30(Box25, { width: terminalWidth, justifyContent: "center", children: /* @__PURE__ */ jsx30(Text27, { color: theme28.textMuted, children: statusMessage }) }),
|
|
12900
|
+
modelChoices && /* @__PURE__ */ jsx30(Box25, { width: promptColumnWidth, flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsx30(
|
|
12901
|
+
ModelPicker,
|
|
12902
|
+
{
|
|
12903
|
+
currentModel,
|
|
12904
|
+
models: modelChoices,
|
|
12905
|
+
onSelect: (model) => {
|
|
12906
|
+
modelResolverRef.current?.(model);
|
|
12907
|
+
modelResolverRef.current = null;
|
|
12908
|
+
setCurrentModel(model);
|
|
12909
|
+
setModelChoices(null);
|
|
12910
|
+
},
|
|
12911
|
+
onCancel: () => {
|
|
12912
|
+
modelResolverRef.current?.(currentModel);
|
|
12913
|
+
modelResolverRef.current = null;
|
|
12914
|
+
setModelChoices(null);
|
|
12915
|
+
}
|
|
12916
|
+
}
|
|
12917
|
+
) }),
|
|
12739
12918
|
prompt && /* @__PURE__ */ jsxs23(Box25, { width: promptColumnWidth, flexDirection: "column", marginTop: 1, children: [
|
|
12740
|
-
/* @__PURE__ */
|
|
12919
|
+
/* @__PURE__ */ jsx30(Text27, { bold: true, color: theme28.text, children: promptShellModel?.heading }),
|
|
12741
12920
|
promptShellModel?.task && /* @__PURE__ */ jsxs23(Box25, { marginTop: 1, children: [
|
|
12742
|
-
/* @__PURE__ */
|
|
12743
|
-
/* @__PURE__ */
|
|
12921
|
+
/* @__PURE__ */ jsx30(Text27, { color: theme28.textSubtle, children: "task " }),
|
|
12922
|
+
/* @__PURE__ */ jsx30(Text27, { color: theme28.text, children: promptShellModel.task })
|
|
12744
12923
|
] }),
|
|
12745
12924
|
promptShellModel?.filePath && /* @__PURE__ */ jsxs23(Box25, { children: [
|
|
12746
|
-
/* @__PURE__ */
|
|
12747
|
-
/* @__PURE__ */
|
|
12925
|
+
/* @__PURE__ */ jsx30(Text27, { color: theme28.textSubtle, children: "state " }),
|
|
12926
|
+
/* @__PURE__ */ jsx30(Text27, { color: theme28.textSubtle, children: promptShellModel.filePath })
|
|
12748
12927
|
] }),
|
|
12749
|
-
promptShellModel?.metaLine && /* @__PURE__ */
|
|
12750
|
-
/* @__PURE__ */
|
|
12751
|
-
/* @__PURE__ */
|
|
12928
|
+
promptShellModel?.metaLine && /* @__PURE__ */ jsx30(Box25, { marginTop: 1, children: /* @__PURE__ */ jsx30(Text27, { color: theme28.textSubtle, children: promptShellModel.metaLine }) }),
|
|
12929
|
+
/* @__PURE__ */ jsx30(Box25, { marginTop: 1, children: /* @__PURE__ */ jsx30(Text27, { color: theme28.textSubtle, children: prompt.hint }) }),
|
|
12930
|
+
/* @__PURE__ */ jsx30(Box25, { flexDirection: "column", marginTop: 1, children: prompt.choices.map((choice, index) => {
|
|
12752
12931
|
const isSelected = index === selectedPromptIndex;
|
|
12753
12932
|
return /* @__PURE__ */ jsxs23(Box25, { marginTop: index === 0 ? 0 : 1, children: [
|
|
12754
|
-
/* @__PURE__ */
|
|
12755
|
-
/* @__PURE__ */
|
|
12933
|
+
/* @__PURE__ */ jsx30(Text27, { color: isSelected ? theme28.accent : theme28.textSubtle, bold: isSelected, children: isSelected ? "\u203A " : " " }),
|
|
12934
|
+
/* @__PURE__ */ jsx30(Text27, { color: isSelected ? theme28.text : theme28.textSubtle, bold: isSelected, children: `${index + 1} ${choice.label}` })
|
|
12756
12935
|
] }, choice.value);
|
|
12757
12936
|
}) }),
|
|
12758
|
-
selectedChoice && /* @__PURE__ */
|
|
12759
|
-
/* @__PURE__ */
|
|
12937
|
+
selectedChoice && /* @__PURE__ */ jsx30(Box25, { marginTop: 1, children: /* @__PURE__ */ jsx30(Text27, { color: theme28.textSubtle, children: selectedChoice.description }) }),
|
|
12938
|
+
/* @__PURE__ */ jsx30(Box25, { marginTop: 1, children: /* @__PURE__ */ jsx30(Text27, { color: theme28.border, children: SCROLL_HINT }) })
|
|
12760
12939
|
] })
|
|
12761
12940
|
] })
|
|
12762
12941
|
}
|
|
@@ -14451,7 +14630,17 @@ function stateSafeName3(name) {
|
|
|
14451
14630
|
var offloadCounter = 0;
|
|
14452
14631
|
function offloadToolOutput(taskName, toolName, output, options = {}, stateDir) {
|
|
14453
14632
|
const threshold = options.threshold ?? DEFAULT_OUTPUT_THRESHOLD;
|
|
14633
|
+
const warnThreshold = options.warnThreshold;
|
|
14454
14634
|
const previewLength = options.previewLength ?? DEFAULT_PREVIEW_LENGTH;
|
|
14635
|
+
if (typeof warnThreshold === "number" && warnThreshold > 0 && output.length > warnThreshold && output.length <= threshold) {
|
|
14636
|
+
options.onEvent?.({
|
|
14637
|
+
kind: "warning",
|
|
14638
|
+
toolName,
|
|
14639
|
+
outputLength: output.length,
|
|
14640
|
+
threshold,
|
|
14641
|
+
warnThreshold
|
|
14642
|
+
});
|
|
14643
|
+
}
|
|
14455
14644
|
if (output.length <= threshold) {
|
|
14456
14645
|
return { offloaded: false, content: output };
|
|
14457
14646
|
}
|
|
@@ -14473,6 +14662,14 @@ function offloadToolOutput(taskName, toolName, output, options = {}, stateDir) {
|
|
|
14473
14662
|
"",
|
|
14474
14663
|
"Use read_file to retrieve the full output if needed."
|
|
14475
14664
|
].join("\n");
|
|
14665
|
+
options.onEvent?.({
|
|
14666
|
+
kind: "offloaded",
|
|
14667
|
+
toolName,
|
|
14668
|
+
outputLength: output.length,
|
|
14669
|
+
threshold,
|
|
14670
|
+
warnThreshold,
|
|
14671
|
+
filePath
|
|
14672
|
+
});
|
|
14476
14673
|
return { offloaded: true, content: reference, filePath };
|
|
14477
14674
|
}
|
|
14478
14675
|
function withOffloading(tool, taskName, toolName, options, stateDir) {
|
|
@@ -14487,6 +14684,147 @@ function withOffloading(tool, taskName, toolName, options, stateDir) {
|
|
|
14487
14684
|
};
|
|
14488
14685
|
}
|
|
14489
14686
|
|
|
14687
|
+
// src/marathon/model-context.ts
|
|
14688
|
+
var DEFAULT_AUTO_COMPACT_THRESHOLD_RATIO = 0.8;
|
|
14689
|
+
var DEFAULT_PROVIDER_NATIVE_COMPACT_THRESHOLD_RATIO = 0.9;
|
|
14690
|
+
var DEFAULT_OUTPUT_RESERVE_RATIO = 0.15;
|
|
14691
|
+
var MIN_OUTPUT_RESERVE_TOKENS = 8e3;
|
|
14692
|
+
var MAX_OUTPUT_RESERVE_TOKENS = 64e3;
|
|
14693
|
+
function normalizeModelId(value) {
|
|
14694
|
+
return value?.trim().toLowerCase().replace(/^model\//, "") ?? "";
|
|
14695
|
+
}
|
|
14696
|
+
function buildModelLookupCandidates(modelId) {
|
|
14697
|
+
const raw = modelId?.trim();
|
|
14698
|
+
if (!raw) return [];
|
|
14699
|
+
const candidates = /* @__PURE__ */ new Set();
|
|
14700
|
+
const push = (value) => {
|
|
14701
|
+
const normalized = normalizeModelId(value);
|
|
14702
|
+
if (normalized) {
|
|
14703
|
+
candidates.add(normalized);
|
|
14704
|
+
}
|
|
14705
|
+
};
|
|
14706
|
+
push(raw);
|
|
14707
|
+
if (raw.includes(":")) {
|
|
14708
|
+
const colonTail = raw.split(":").slice(1).join(":");
|
|
14709
|
+
push(colonTail);
|
|
14710
|
+
if (colonTail.includes("/")) {
|
|
14711
|
+
push(colonTail.split("/").slice(1).join("/"));
|
|
14712
|
+
push(colonTail.split("/").pop());
|
|
14713
|
+
}
|
|
14714
|
+
}
|
|
14715
|
+
if (raw.includes("/")) {
|
|
14716
|
+
push(raw.split("/").slice(1).join("/"));
|
|
14717
|
+
push(raw.split("/").pop());
|
|
14718
|
+
}
|
|
14719
|
+
return [...candidates];
|
|
14720
|
+
}
|
|
14721
|
+
function matchesModelIdentifier(sourceModelId, candidates) {
|
|
14722
|
+
const normalizedSource = normalizeModelId(sourceModelId);
|
|
14723
|
+
if (!normalizedSource) return false;
|
|
14724
|
+
return candidates.some((candidate) => normalizedSource === candidate || normalizedSource.endsWith(`/${candidate}`) || normalizedSource.endsWith(`:${candidate}`));
|
|
14725
|
+
}
|
|
14726
|
+
function extractAgentConfigModel(agent) {
|
|
14727
|
+
const config2 = agent?.config;
|
|
14728
|
+
if (!config2 || typeof config2 !== "object") return void 0;
|
|
14729
|
+
const model = config2.model;
|
|
14730
|
+
return typeof model === "string" && model.trim() ? model.trim() : void 0;
|
|
14731
|
+
}
|
|
14732
|
+
function findDefaultModelId(configuredModels) {
|
|
14733
|
+
return configuredModels.find((model) => model.isDefault)?.modelId;
|
|
14734
|
+
}
|
|
14735
|
+
function resolveModelProvider(modelId, configuredModels, availableModels) {
|
|
14736
|
+
const candidates = buildModelLookupCandidates(modelId);
|
|
14737
|
+
if (candidates.length === 0) return void 0;
|
|
14738
|
+
for (const configuredModel of configuredModels) {
|
|
14739
|
+
if (configuredModel.provider && matchesModelIdentifier(configuredModel.modelId, candidates)) {
|
|
14740
|
+
return configuredModel.provider;
|
|
14741
|
+
}
|
|
14742
|
+
}
|
|
14743
|
+
for (const availableModel of availableModels) {
|
|
14744
|
+
const providerMatch = availableModel.providers?.find((provider) => matchesModelIdentifier(provider.modelId, candidates) || matchesModelIdentifier(availableModel.baseModel, candidates));
|
|
14745
|
+
if (providerMatch?.provider) {
|
|
14746
|
+
return providerMatch.provider;
|
|
14747
|
+
}
|
|
14748
|
+
}
|
|
14749
|
+
const normalizedModelId = normalizeModelId(modelId);
|
|
14750
|
+
if (!normalizedModelId) return void 0;
|
|
14751
|
+
if (normalizedModelId.includes("claude") || normalizedModelId.includes("anthropic")) {
|
|
14752
|
+
return "anthropic";
|
|
14753
|
+
}
|
|
14754
|
+
if (normalizedModelId.startsWith("gpt-") || normalizedModelId.includes("openai") || normalizedModelId.startsWith("o1") || normalizedModelId.startsWith("o3") || normalizedModelId.startsWith("o4")) {
|
|
14755
|
+
return "openai";
|
|
14756
|
+
}
|
|
14757
|
+
return void 0;
|
|
14758
|
+
}
|
|
14759
|
+
function resolveDefaultCompactStrategy(modelId, configuredModels, availableModels) {
|
|
14760
|
+
const provider = resolveModelProvider(modelId, configuredModels, availableModels);
|
|
14761
|
+
return provider === "anthropic" ? "provider_native" : "summary_fallback";
|
|
14762
|
+
}
|
|
14763
|
+
function resolveOutputReserveTokens(modelContextLength) {
|
|
14764
|
+
if (typeof modelContextLength !== "number" || modelContextLength <= 0) {
|
|
14765
|
+
return void 0;
|
|
14766
|
+
}
|
|
14767
|
+
return Math.max(
|
|
14768
|
+
MIN_OUTPUT_RESERVE_TOKENS,
|
|
14769
|
+
Math.min(MAX_OUTPUT_RESERVE_TOKENS, Math.floor(modelContextLength * DEFAULT_OUTPUT_RESERVE_RATIO))
|
|
14770
|
+
);
|
|
14771
|
+
}
|
|
14772
|
+
function resolveEffectiveInputBudgetTokens(modelContextLength, reservedOutputTokens) {
|
|
14773
|
+
if (typeof modelContextLength !== "number" || modelContextLength <= 0) {
|
|
14774
|
+
return void 0;
|
|
14775
|
+
}
|
|
14776
|
+
const reserve = reservedOutputTokens ?? resolveOutputReserveTokens(modelContextLength) ?? 0;
|
|
14777
|
+
return Math.max(1, modelContextLength - reserve);
|
|
14778
|
+
}
|
|
14779
|
+
function resolveModelContextLength(modelId, configuredModels, availableModels) {
|
|
14780
|
+
const candidates = buildModelLookupCandidates(modelId);
|
|
14781
|
+
if (candidates.length === 0) return void 0;
|
|
14782
|
+
for (const configuredModel of configuredModels) {
|
|
14783
|
+
if (typeof configuredModel.contextLength === "number" && configuredModel.contextLength > 0 && matchesModelIdentifier(configuredModel.modelId, candidates)) {
|
|
14784
|
+
return configuredModel.contextLength;
|
|
14785
|
+
}
|
|
14786
|
+
}
|
|
14787
|
+
for (const availableModel of availableModels) {
|
|
14788
|
+
if (typeof availableModel.contextLength !== "number" || availableModel.contextLength <= 0) {
|
|
14789
|
+
continue;
|
|
14790
|
+
}
|
|
14791
|
+
if (matchesModelIdentifier(availableModel.baseModel, candidates)) {
|
|
14792
|
+
return availableModel.contextLength;
|
|
14793
|
+
}
|
|
14794
|
+
if (availableModel.providers?.some(
|
|
14795
|
+
(provider) => matchesModelIdentifier(provider.modelId, candidates)
|
|
14796
|
+
)) {
|
|
14797
|
+
return availableModel.contextLength;
|
|
14798
|
+
}
|
|
14799
|
+
}
|
|
14800
|
+
return void 0;
|
|
14801
|
+
}
|
|
14802
|
+
function resolveAutoCompactTokenThreshold(modelContextLength, rawThreshold, strategy = "summary_fallback") {
|
|
14803
|
+
const effectiveBudget = resolveEffectiveInputBudgetTokens(modelContextLength);
|
|
14804
|
+
const trimmed = rawThreshold?.trim();
|
|
14805
|
+
if (!trimmed) {
|
|
14806
|
+
const ratio = strategy === "provider_native" ? DEFAULT_PROVIDER_NATIVE_COMPACT_THRESHOLD_RATIO : DEFAULT_AUTO_COMPACT_THRESHOLD_RATIO;
|
|
14807
|
+
return typeof effectiveBudget === "number" && effectiveBudget > 0 ? Math.max(1, Math.floor(effectiveBudget * ratio)) : void 0;
|
|
14808
|
+
}
|
|
14809
|
+
const percentMatch = trimmed.match(/^(\d+(?:\.\d+)?)%$/);
|
|
14810
|
+
if (percentMatch) {
|
|
14811
|
+
const percentValue = Number(percentMatch[1]);
|
|
14812
|
+
if (!Number.isFinite(percentValue) || percentValue <= 0 || percentValue > 100) {
|
|
14813
|
+
throw new Error(
|
|
14814
|
+
`Invalid --compact-threshold value "${rawThreshold}". Use a percentage (e.g. 80%) or absolute token count (e.g. 120000).`
|
|
14815
|
+
);
|
|
14816
|
+
}
|
|
14817
|
+
return typeof effectiveBudget === "number" && effectiveBudget > 0 ? Math.max(1, Math.floor(effectiveBudget * (percentValue / 100))) : void 0;
|
|
14818
|
+
}
|
|
14819
|
+
const numericValue = Number(trimmed);
|
|
14820
|
+
if (!Number.isFinite(numericValue) || numericValue <= 0) {
|
|
14821
|
+
throw new Error(
|
|
14822
|
+
`Invalid --compact-threshold value "${rawThreshold}". Use a percentage (e.g. 80%) or absolute token count (e.g. 120000).`
|
|
14823
|
+
);
|
|
14824
|
+
}
|
|
14825
|
+
return Math.max(1, Math.floor(numericValue));
|
|
14826
|
+
}
|
|
14827
|
+
|
|
14490
14828
|
// src/marathon/recipes.ts
|
|
14491
14829
|
import * as fs10 from "fs";
|
|
14492
14830
|
import * as path9 from "path";
|
|
@@ -14631,6 +14969,80 @@ function buildResumeHistoryWarning(state) {
|
|
|
14631
14969
|
function canUseMarathonStartupShell(options) {
|
|
14632
14970
|
return process.stdin.isTTY === true && process.stdout.isTTY === true && !options.json;
|
|
14633
14971
|
}
|
|
14972
|
+
function normalizeStartupModelOptionValue(value) {
|
|
14973
|
+
const trimmed = value?.trim().toLowerCase().replace(/^model\//, "") ?? "";
|
|
14974
|
+
if (!trimmed) return "";
|
|
14975
|
+
const withoutProvider = trimmed.includes(":") ? trimmed.split(":").slice(1).join(":") : trimmed;
|
|
14976
|
+
if (withoutProvider.includes("/")) {
|
|
14977
|
+
return withoutProvider.split("/").pop() ?? withoutProvider;
|
|
14978
|
+
}
|
|
14979
|
+
return withoutProvider;
|
|
14980
|
+
}
|
|
14981
|
+
function formatModelGroup(provider, fallbackValue) {
|
|
14982
|
+
const normalized = provider?.trim().toLowerCase() || normalizeStartupModelOptionValue(fallbackValue).split("-")[0];
|
|
14983
|
+
switch (normalized) {
|
|
14984
|
+
case "anthropic":
|
|
14985
|
+
return "Anthropic";
|
|
14986
|
+
case "openai":
|
|
14987
|
+
return "OpenAI";
|
|
14988
|
+
case "google":
|
|
14989
|
+
return "Google";
|
|
14990
|
+
case "xai":
|
|
14991
|
+
return "xAI";
|
|
14992
|
+
case "qwen":
|
|
14993
|
+
return "Qwen";
|
|
14994
|
+
case "deepseek":
|
|
14995
|
+
return "DeepSeek";
|
|
14996
|
+
case "mistral":
|
|
14997
|
+
return "Mistral";
|
|
14998
|
+
case "meta":
|
|
14999
|
+
return "Meta";
|
|
15000
|
+
default:
|
|
15001
|
+
return "Other";
|
|
15002
|
+
}
|
|
15003
|
+
}
|
|
15004
|
+
function buildMarathonStartupModelOptions(configuredModels, availableModels) {
|
|
15005
|
+
const options = [];
|
|
15006
|
+
const seen = /* @__PURE__ */ new Set();
|
|
15007
|
+
const pushOption = (option) => {
|
|
15008
|
+
if (!option) return;
|
|
15009
|
+
const normalizedValue = normalizeStartupModelOptionValue(option.value);
|
|
15010
|
+
if (!normalizedValue || seen.has(normalizedValue)) return;
|
|
15011
|
+
seen.add(normalizedValue);
|
|
15012
|
+
options.push(option);
|
|
15013
|
+
};
|
|
15014
|
+
for (const model of configuredModels) {
|
|
15015
|
+
const modelId = model.modelId?.trim();
|
|
15016
|
+
if (!modelId) continue;
|
|
15017
|
+
pushOption({
|
|
15018
|
+
label: model.displayName?.trim() || modelId,
|
|
15019
|
+
value: modelId,
|
|
15020
|
+
group: formatModelGroup(model.provider, modelId)
|
|
15021
|
+
});
|
|
15022
|
+
}
|
|
15023
|
+
for (const model of availableModels) {
|
|
15024
|
+
if (Array.isArray(model.providers) && model.providers.length > 0) {
|
|
15025
|
+
for (const provider of model.providers) {
|
|
15026
|
+
const modelId2 = provider.modelId?.trim() || model.baseModel?.trim();
|
|
15027
|
+
if (!modelId2) continue;
|
|
15028
|
+
pushOption({
|
|
15029
|
+
label: provider.displayName?.trim() || model.displayName?.trim() || model.baseModel?.trim() || modelId2,
|
|
15030
|
+
value: modelId2,
|
|
15031
|
+
group: formatModelGroup(provider.provider, modelId2)
|
|
15032
|
+
});
|
|
15033
|
+
}
|
|
15034
|
+
continue;
|
|
15035
|
+
}
|
|
15036
|
+
const modelId = model.baseModel?.trim();
|
|
15037
|
+
if (!modelId) continue;
|
|
15038
|
+
pushOption({
|
|
15039
|
+
label: model.displayName?.trim() || modelId,
|
|
15040
|
+
value: modelId,
|
|
15041
|
+
group: formatModelGroup(void 0, modelId)
|
|
15042
|
+
});
|
|
15043
|
+
}
|
|
15044
|
+
return options;
|
|
15045
|
+
}
|
|
14634
15046
|
function buildMarathonClientHeaders(devPlanOverride) {
|
|
14635
15047
|
const cliVersion = getCliVersion();
|
|
14636
15048
|
return {
|
|
@@ -14641,6 +15053,42 @@ function buildMarathonClientHeaders(devPlanOverride) {
|
|
|
14641
15053
|
...devPlanOverride ? { "X-Dev-Plan-Override": devPlanOverride } : {}
|
|
14642
15054
|
};
|
|
14643
15055
|
}
|
|
15056
|
+
var DEFAULT_TOOL_OUTPUT_WARNING_CHARS = 4e4;
|
|
15057
|
+
var DEFAULT_TOOL_OUTPUT_OFFLOAD_CHARS = 1e5;
|
|
15058
|
+
function parseCompactStrategy(value) {
|
|
15059
|
+
if (!value) return void 0;
|
|
15060
|
+
const normalized = value.trim().toLowerCase();
|
|
15061
|
+
if (normalized === "auto" || normalized === "provider_native" || normalized === "summary_fallback") {
|
|
15062
|
+
return normalized;
|
|
15063
|
+
}
|
|
15064
|
+
throw new Error(
|
|
15065
|
+
`Invalid --compact-strategy value "${value}". Use auto, provider_native, or summary_fallback.`
|
|
15066
|
+
);
|
|
15067
|
+
}
|
|
15068
|
+
function resolveToolOutputGuardrails(rawThreshold) {
|
|
15069
|
+
if (!rawThreshold || rawThreshold.trim() === "") {
|
|
15070
|
+
return {
|
|
15071
|
+
warnThreshold: DEFAULT_TOOL_OUTPUT_WARNING_CHARS,
|
|
15072
|
+
threshold: DEFAULT_TOOL_OUTPUT_OFFLOAD_CHARS
|
|
15073
|
+
};
|
|
15074
|
+
}
|
|
15075
|
+
const normalized = rawThreshold.trim().toLowerCase();
|
|
15076
|
+
if (normalized === "0" || normalized === "off" || normalized === "false") {
|
|
15077
|
+
return false;
|
|
15078
|
+
}
|
|
15079
|
+
const numericValue = Number(rawThreshold);
|
|
15080
|
+
if (!Number.isFinite(numericValue) || numericValue <= 0) {
|
|
15081
|
+
throw new Error(
|
|
15082
|
+
`Invalid --offload-threshold value "${rawThreshold}". Use a positive number of characters, "0", or "off".`
|
|
15083
|
+
);
|
|
15084
|
+
}
|
|
15085
|
+
const threshold = Math.max(1, Math.floor(numericValue));
|
|
15086
|
+
const warnThreshold = threshold <= 1 ? void 0 : threshold > DEFAULT_TOOL_OUTPUT_WARNING_CHARS ? DEFAULT_TOOL_OUTPUT_WARNING_CHARS : Math.max(1, Math.floor(threshold * 0.8));
|
|
15087
|
+
return {
|
|
15088
|
+
warnThreshold,
|
|
15089
|
+
threshold
|
|
15090
|
+
};
|
|
15091
|
+
}
|
|
14644
15092
|
async function taskAction(agent, options) {
|
|
14645
15093
|
if (!options.resume && !options.goal) {
|
|
14646
15094
|
console.error(chalk16.red("Error: -g, --goal <text> is required for new tasks"));
|
|
@@ -14660,6 +15108,13 @@ async function taskAction(agent, options) {
|
|
|
14660
15108
|
console.error(chalk16.red(`Invalid --sandbox value "${options.sandbox}". Use: cloudflare-worker, quickjs, or daytona`));
|
|
14661
15109
|
process.exit(1);
|
|
14662
15110
|
}
|
|
15111
|
+
let requestedCompactStrategy;
|
|
15112
|
+
try {
|
|
15113
|
+
requestedCompactStrategy = parseCompactStrategy(options.compactStrategy);
|
|
15114
|
+
} catch (error) {
|
|
15115
|
+
console.error(chalk16.red(error instanceof Error ? error.message : String(error)));
|
|
15116
|
+
process.exit(1);
|
|
15117
|
+
}
|
|
14663
15118
|
let recipe = null;
|
|
14664
15119
|
if (options.recipe) {
|
|
14665
15120
|
recipe = loadRecipe(options.recipe);
|
|
@@ -14693,8 +15148,15 @@ async function taskAction(agent, options) {
|
|
|
14693
15148
|
if (resolvedToolIds.length > 0) {
|
|
14694
15149
|
console.log(chalk16.cyan(`Built-in tools: ${resolvedToolIds.join(", ")}`));
|
|
14695
15150
|
}
|
|
14696
|
-
|
|
14697
|
-
|
|
15151
|
+
let offloadOptions;
|
|
15152
|
+
try {
|
|
15153
|
+
const guardrails = resolveToolOutputGuardrails(options.offloadThreshold);
|
|
15154
|
+
offloadOptions = guardrails === false ? void 0 : guardrails;
|
|
15155
|
+
} catch (error) {
|
|
15156
|
+
console.error(chalk16.red(error instanceof Error ? error.message : String(error)));
|
|
15157
|
+
process.exit(1);
|
|
15158
|
+
}
|
|
15159
|
+
const useStartupShell = canUseMarathonStartupShell(options);
|
|
14698
15160
|
const streamRef = { current: null };
|
|
14699
15161
|
const startupShellRef = { current: null };
|
|
14700
15162
|
let waitForUiExit;
|
|
@@ -14789,6 +15251,26 @@ async function taskAction(agent, options) {
|
|
|
14789
15251
|
]);
|
|
14790
15252
|
}
|
|
14791
15253
|
}
|
|
15254
|
+
let agentConfigModel;
|
|
15255
|
+
let defaultConfiguredModel;
|
|
15256
|
+
let configuredModels = [];
|
|
15257
|
+
let availableModels = [];
|
|
15258
|
+
const modelMetadataResults = await Promise.allSettled([
|
|
15259
|
+
client.agents.get(agentId),
|
|
15260
|
+
client.modelConfigs.list(),
|
|
15261
|
+
client.modelConfigs.getAvailable()
|
|
15262
|
+
]);
|
|
15263
|
+
const [agentResult, configuredModelsResult, availableModelsResult] = modelMetadataResults;
|
|
15264
|
+
if (agentResult.status === "fulfilled") {
|
|
15265
|
+
agentConfigModel = extractAgentConfigModel(agentResult.value);
|
|
15266
|
+
}
|
|
15267
|
+
if (configuredModelsResult.status === "fulfilled") {
|
|
15268
|
+
configuredModels = configuredModelsResult.value;
|
|
15269
|
+
defaultConfiguredModel = findDefaultModelId(configuredModels);
|
|
15270
|
+
}
|
|
15271
|
+
if (availableModelsResult.status === "fulfilled") {
|
|
15272
|
+
availableModels = availableModelsResult.value;
|
|
15273
|
+
}
|
|
14792
15274
|
let taskName = options.session || options.name || agentId;
|
|
14793
15275
|
let filePath = stateFilePath(taskName, options.stateDir);
|
|
14794
15276
|
const maxSessions = parseInt(options.maxSessions, 10);
|
|
@@ -14927,6 +15409,37 @@ async function taskAction(agent, options) {
|
|
|
14927
15409
|
}
|
|
14928
15410
|
}
|
|
14929
15411
|
}
|
|
15412
|
+
if (useStartupShell && !options.model?.trim()) {
|
|
15413
|
+
const startupModelOptions = buildMarathonStartupModelOptions(configuredModels, availableModels);
|
|
15414
|
+
const initialStartupModel = agentConfigModel || defaultConfiguredModel || startupModelOptions[0]?.value;
|
|
15415
|
+
if (startupModelOptions.length > 0 && initialStartupModel && startupShellRef.current) {
|
|
15416
|
+
setStartupStatus("selecting model");
|
|
15417
|
+
options.model = await startupShellRef.current.requestModelChoice(
|
|
15418
|
+
initialStartupModel,
|
|
15419
|
+
startupModelOptions
|
|
15420
|
+
);
|
|
15421
|
+
setStartupStatus(`model ready: ${options.model}`);
|
|
15422
|
+
}
|
|
15423
|
+
}
|
|
15424
|
+
try {
|
|
15425
|
+
const validationStrategy = options.compact ? "summary_fallback" : requestedCompactStrategy && requestedCompactStrategy !== "auto" ? requestedCompactStrategy : resolveDefaultCompactStrategy(
|
|
15426
|
+
options.model || agentConfigModel || defaultConfiguredModel,
|
|
15427
|
+
configuredModels,
|
|
15428
|
+
availableModels
|
|
15429
|
+
);
|
|
15430
|
+
resolveAutoCompactTokenThreshold(
|
|
15431
|
+
resolveModelContextLength(
|
|
15432
|
+
options.model || agentConfigModel || defaultConfiguredModel,
|
|
15433
|
+
configuredModels,
|
|
15434
|
+
availableModels
|
|
15435
|
+
),
|
|
15436
|
+
options.compactThreshold,
|
|
15437
|
+
validationStrategy
|
|
15438
|
+
);
|
|
15439
|
+
} catch (error) {
|
|
15440
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
15441
|
+
await failBeforeMain([chalk16.red(message)]);
|
|
15442
|
+
}
|
|
14930
15443
|
const remainingSessions = maxSessions - priorSessionCount;
|
|
14931
15444
|
const remainingCost = maxCost ? maxCost - priorCost : void 0;
|
|
14932
15445
|
const baseMessage = options.goal || (resumeRequested ? "Continue the task." : "");
|
|
@@ -14953,15 +15466,55 @@ ${rulesContext}`;
|
|
|
14953
15466
|
taskName,
|
|
14954
15467
|
stateDir: options.stateDir
|
|
14955
15468
|
});
|
|
15469
|
+
const resolveContextLimitForModel = (modelId) => resolveModelContextLength(modelId, configuredModels, availableModels);
|
|
15470
|
+
const resolveCompactStrategyForModel = (modelId) => {
|
|
15471
|
+
if (options.compact) return "summary_fallback";
|
|
15472
|
+
if (requestedCompactStrategy && requestedCompactStrategy !== "auto") {
|
|
15473
|
+
return requestedCompactStrategy === "provider_native" ? resolveDefaultCompactStrategy(modelId, configuredModels, availableModels) === "provider_native" ? "provider_native" : "summary_fallback" : "summary_fallback";
|
|
15474
|
+
}
|
|
15475
|
+
return resolveDefaultCompactStrategy(modelId, configuredModels, availableModels);
|
|
15476
|
+
};
|
|
15477
|
+
const resolveCompactThresholdForModel = (modelId) => {
|
|
15478
|
+
if (options.autoCompact === false) return void 0;
|
|
15479
|
+
const contextLength = resolveContextLimitForModel(modelId);
|
|
15480
|
+
return resolveAutoCompactTokenThreshold(
|
|
15481
|
+
contextLength,
|
|
15482
|
+
options.compactThreshold,
|
|
15483
|
+
resolveCompactStrategyForModel(modelId)
|
|
15484
|
+
);
|
|
15485
|
+
};
|
|
15486
|
+
const reportContextNotice = (event) => {
|
|
15487
|
+
streamRef.current?.reportContextNotice(event);
|
|
15488
|
+
};
|
|
14956
15489
|
if (localTools && offloadOptions) {
|
|
14957
15490
|
const toolNames = Object.keys(localTools);
|
|
14958
15491
|
for (const toolName of toolNames) {
|
|
14959
|
-
if (toolName === "search_repo" || toolName === "read_file" || toolName === "glob_files") {
|
|
15492
|
+
if (toolName === "search_repo" || toolName === "read_file" || toolName === "glob_files" || toolName === "tree_directory" || toolName === "list_directory") {
|
|
14960
15493
|
localTools[toolName] = withOffloading(
|
|
14961
15494
|
localTools[toolName],
|
|
14962
15495
|
taskName,
|
|
14963
15496
|
toolName,
|
|
14964
|
-
|
|
15497
|
+
{
|
|
15498
|
+
...offloadOptions,
|
|
15499
|
+
onEvent: (event) => {
|
|
15500
|
+
if (event.kind === "warning") {
|
|
15501
|
+
reportContextNotice({
|
|
15502
|
+
kind: "tool_output_warning",
|
|
15503
|
+
message: `${event.toolName} returned ${Math.ceil(event.outputLength / 4).toLocaleString()} estimated tokens of output. Consider narrowing the query or reading a smaller slice.`,
|
|
15504
|
+
toolName: event.toolName,
|
|
15505
|
+
outputLength: event.outputLength
|
|
15506
|
+
});
|
|
15507
|
+
return;
|
|
15508
|
+
}
|
|
15509
|
+
reportContextNotice({
|
|
15510
|
+
kind: "tool_output_offloaded",
|
|
15511
|
+
message: `${event.toolName} returned ${Math.ceil(event.outputLength / 4).toLocaleString()} estimated tokens and was offloaded ${event.filePath ? `to ${event.filePath}` : "to a file"} to protect the context window.`,
|
|
15512
|
+
toolName: event.toolName,
|
|
15513
|
+
outputLength: event.outputLength,
|
|
15514
|
+
filePath: event.filePath
|
|
15515
|
+
});
|
|
15516
|
+
}
|
|
15517
|
+
},
|
|
14965
15518
|
options.stateDir
|
|
14966
15519
|
);
|
|
14967
15520
|
}
|
|
@@ -15002,7 +15555,7 @@ ${rulesContext}`;
|
|
|
15002
15555
|
const marathonAppProps = {
|
|
15003
15556
|
taskName,
|
|
15004
15557
|
agentId,
|
|
15005
|
-
model: options.model,
|
|
15558
|
+
model: options.model || agentConfigModel || defaultConfiguredModel,
|
|
15006
15559
|
sandbox: parsedSandbox,
|
|
15007
15560
|
goal: baseMessage,
|
|
15008
15561
|
initialSessionCount: priorSessionCount,
|
|
@@ -15146,6 +15699,12 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
15146
15699
|
defaultModel: options.model
|
|
15147
15700
|
}
|
|
15148
15701
|
);
|
|
15702
|
+
const effectiveModelForContext = phaseModel || options.model || agentConfigModel || defaultConfiguredModel;
|
|
15703
|
+
const compactStrategy = resolveCompactStrategyForModel(effectiveModelForContext);
|
|
15704
|
+
const contextLimitTokens = resolveContextLimitForModel(effectiveModelForContext);
|
|
15705
|
+
const autoCompactTokenThreshold = resolveCompactThresholdForModel(
|
|
15706
|
+
effectiveModelForContext
|
|
15707
|
+
);
|
|
15149
15708
|
const runTaskOptions = {
|
|
15150
15709
|
message: taskMessage,
|
|
15151
15710
|
maxSessions: remainingSessions - accumulatedSessions,
|
|
@@ -15164,6 +15723,34 @@ Saving state... done. Session saved to ${filePath}`);
|
|
|
15164
15723
|
continuationMessage,
|
|
15165
15724
|
compact: useCompact
|
|
15166
15725
|
} : {},
|
|
15726
|
+
...autoCompactTokenThreshold ? { autoCompactTokenThreshold } : {},
|
|
15727
|
+
...contextLimitTokens ? { contextLimitTokens } : {},
|
|
15728
|
+
compactStrategy,
|
|
15729
|
+
...options.compactInstructions ? { compactInstructions: options.compactInstructions } : {},
|
|
15730
|
+
onContextCompaction: async (event) => {
|
|
15731
|
+
const currentActions = streamRef.current;
|
|
15732
|
+
if (!currentActions) return;
|
|
15733
|
+
const absoluteEvent = {
|
|
15734
|
+
...event,
|
|
15735
|
+
sessionIndex: currentSessionOffset + event.sessionIndex,
|
|
15736
|
+
model: event.model || effectiveModelForContext
|
|
15737
|
+
};
|
|
15738
|
+
if (event.phase === "start") {
|
|
15739
|
+
currentActions.startContextCompaction(absoluteEvent);
|
|
15740
|
+
await new Promise((resolve6) => setTimeout(resolve6, 0));
|
|
15741
|
+
return;
|
|
15742
|
+
}
|
|
15743
|
+
currentActions.finishContextCompaction(absoluteEvent);
|
|
15744
|
+
},
|
|
15745
|
+
onContextNotice: async (event) => {
|
|
15746
|
+
const currentActions = streamRef.current;
|
|
15747
|
+
if (!currentActions) return;
|
|
15748
|
+
currentActions.reportContextNotice({
|
|
15749
|
+
...event,
|
|
15750
|
+
sessionIndex: typeof event.sessionIndex === "number" ? currentSessionOffset + event.sessionIndex : void 0,
|
|
15751
|
+
model: event.model || effectiveModelForContext
|
|
15752
|
+
});
|
|
15753
|
+
},
|
|
15167
15754
|
...resumeState ? { resumeState } : {},
|
|
15168
15755
|
toolContextMode: options.toolContext || "hot-tail",
|
|
15169
15756
|
toolWindow: options.toolWindow === "session" || !options.toolWindow ? "session" : parseInt(options.toolWindow, 10) || 10,
|
|
@@ -15592,7 +16179,7 @@ function detectDeployWorkflow(message, sandboxProvider, resumeState) {
|
|
|
15592
16179
|
return void 0;
|
|
15593
16180
|
}
|
|
15594
16181
|
function applyTaskOptions(cmd) {
|
|
15595
|
-
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", "
|
|
16182
|
+
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-steer", "Run all iterations without steering pauses (fully autonomous)").option("--steer-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("--recipe <name>", "Load a workflow recipe from .marathon/recipes/").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);
|
|
15596
16183
|
}
|
|
15597
16184
|
var taskCommand = applyTaskOptions(
|
|
15598
16185
|
new Command10("task").description("Run a multi-session agent task")
|
|
@@ -15642,10 +16229,10 @@ agentsCommand.command("list").description("List all agents").option("--json", "O
|
|
|
15642
16229
|
return;
|
|
15643
16230
|
}
|
|
15644
16231
|
const App = () => {
|
|
15645
|
-
const [items, setItems] =
|
|
15646
|
-
const [error, setError] =
|
|
15647
|
-
const [total, setTotal] =
|
|
15648
|
-
|
|
16232
|
+
const [items, setItems] = useState23(null);
|
|
16233
|
+
const [error, setError] = useState23(null);
|
|
16234
|
+
const [total, setTotal] = useState23();
|
|
16235
|
+
useEffect22(() => {
|
|
15649
16236
|
client.get("/agents", { limit: options.limit }).then((res) => {
|
|
15650
16237
|
setItems(res.data ?? []);
|
|
15651
16238
|
setTotal(getTotalCount(res.pagination));
|
|
@@ -15703,9 +16290,9 @@ agentsCommand.command("get <id>").description("Get agent details").option("--jso
|
|
|
15703
16290
|
return;
|
|
15704
16291
|
}
|
|
15705
16292
|
const App = () => {
|
|
15706
|
-
const [items, setItems] =
|
|
15707
|
-
const [error, setError] =
|
|
15708
|
-
|
|
16293
|
+
const [items, setItems] = useState23(null);
|
|
16294
|
+
const [error, setError] = useState23(null);
|
|
16295
|
+
useEffect22(() => {
|
|
15709
16296
|
client.get(`/agents/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
|
|
15710
16297
|
}, []);
|
|
15711
16298
|
return React10.createElement(DataList, {
|
|
@@ -15755,11 +16342,11 @@ agentsCommand.command("create").description("Create a new agent").requiredOption
|
|
|
15755
16342
|
return;
|
|
15756
16343
|
}
|
|
15757
16344
|
const App = () => {
|
|
15758
|
-
const [loading, setLoading] =
|
|
15759
|
-
const [success, setSuccess] =
|
|
15760
|
-
const [error, setError] =
|
|
15761
|
-
const [result, setResult] =
|
|
15762
|
-
|
|
16345
|
+
const [loading, setLoading] = useState23(true);
|
|
16346
|
+
const [success, setSuccess] = useState23(null);
|
|
16347
|
+
const [error, setError] = useState23(null);
|
|
16348
|
+
const [result, setResult] = useState23(null);
|
|
16349
|
+
useEffect22(() => {
|
|
15763
16350
|
client.post("/agents", {
|
|
15764
16351
|
name: options.name,
|
|
15765
16352
|
description: options.description
|
|
@@ -15806,11 +16393,11 @@ agentsCommand.command("delete <id>").description("Delete an agent").option("--tt
|
|
|
15806
16393
|
return;
|
|
15807
16394
|
}
|
|
15808
16395
|
const App = () => {
|
|
15809
|
-
const [confirmed, setConfirmed] =
|
|
15810
|
-
const [loading, setLoading] =
|
|
15811
|
-
const [success, setSuccess] =
|
|
15812
|
-
const [error, setError] =
|
|
15813
|
-
|
|
16396
|
+
const [confirmed, setConfirmed] = useState23(null);
|
|
16397
|
+
const [loading, setLoading] = useState23(false);
|
|
16398
|
+
const [success, setSuccess] = useState23(null);
|
|
16399
|
+
const [error, setError] = useState23(null);
|
|
16400
|
+
useEffect22(() => {
|
|
15814
16401
|
if (confirmed !== true) return void 0;
|
|
15815
16402
|
setLoading(true);
|
|
15816
16403
|
client.delete(`/agents/${id}`).then(() => {
|
|
@@ -15900,7 +16487,7 @@ import { Command as Command12 } from "commander";
|
|
|
15900
16487
|
import chalk18 from "chalk";
|
|
15901
16488
|
import React11 from "react";
|
|
15902
16489
|
import { render as render11 } from "ink";
|
|
15903
|
-
import { useState as
|
|
16490
|
+
import { useState as useState24, useEffect as useEffect23 } from "react";
|
|
15904
16491
|
var modelsCommand = new Command12("models").description("Manage model configurations");
|
|
15905
16492
|
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) => {
|
|
15906
16493
|
const apiKey = await ensureAuth();
|
|
@@ -15937,10 +16524,10 @@ modelsCommand.command("list").description("List your enabled model configuration
|
|
|
15937
16524
|
return;
|
|
15938
16525
|
}
|
|
15939
16526
|
const App = () => {
|
|
15940
|
-
const [items, setItems] =
|
|
15941
|
-
const [error, setError] =
|
|
15942
|
-
const [total, setTotal] =
|
|
15943
|
-
|
|
16527
|
+
const [items, setItems] = useState24(null);
|
|
16528
|
+
const [error, setError] = useState24(null);
|
|
16529
|
+
const [total, setTotal] = useState24();
|
|
16530
|
+
useEffect23(() => {
|
|
15944
16531
|
client.get("/model-configs").then((res) => {
|
|
15945
16532
|
setItems(res.data ?? []);
|
|
15946
16533
|
setTotal(getTotalCount(res.pagination));
|
|
@@ -16002,9 +16589,9 @@ modelsCommand.command("available").description("List all available models groupe
|
|
|
16002
16589
|
return;
|
|
16003
16590
|
}
|
|
16004
16591
|
const App = () => {
|
|
16005
|
-
const [items, setItems] =
|
|
16006
|
-
const [error, setError] =
|
|
16007
|
-
|
|
16592
|
+
const [items, setItems] = useState24(null);
|
|
16593
|
+
const [error, setError] = useState24(null);
|
|
16594
|
+
useEffect23(() => {
|
|
16008
16595
|
client.get("/model-configs/grouped").then((res) => setItems(res.data ?? [])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
|
|
16009
16596
|
}, []);
|
|
16010
16597
|
return React11.createElement(DataList, {
|
|
@@ -16050,11 +16637,11 @@ modelsCommand.command("enable <modelId>").description("Enable a model by creatin
|
|
|
16050
16637
|
return;
|
|
16051
16638
|
}
|
|
16052
16639
|
const App = () => {
|
|
16053
|
-
const [loading, setLoading] =
|
|
16054
|
-
const [success, setSuccess] =
|
|
16055
|
-
const [error, setError] =
|
|
16056
|
-
const [result, setResult] =
|
|
16057
|
-
|
|
16640
|
+
const [loading, setLoading] = useState24(true);
|
|
16641
|
+
const [success, setSuccess] = useState24(null);
|
|
16642
|
+
const [error, setError] = useState24(null);
|
|
16643
|
+
const [result, setResult] = useState24(null);
|
|
16644
|
+
useEffect23(() => {
|
|
16058
16645
|
client.post("/model-configs", { modelId }).then((data) => {
|
|
16059
16646
|
setResult(data);
|
|
16060
16647
|
setSuccess(true);
|
|
@@ -16098,10 +16685,10 @@ modelsCommand.command("disable <id>").description("Disable a model configuration
|
|
|
16098
16685
|
return;
|
|
16099
16686
|
}
|
|
16100
16687
|
const App = () => {
|
|
16101
|
-
const [loading, setLoading] =
|
|
16102
|
-
const [success, setSuccess] =
|
|
16103
|
-
const [error, setError] =
|
|
16104
|
-
|
|
16688
|
+
const [loading, setLoading] = useState24(true);
|
|
16689
|
+
const [success, setSuccess] = useState24(null);
|
|
16690
|
+
const [error, setError] = useState24(null);
|
|
16691
|
+
useEffect23(() => {
|
|
16105
16692
|
client.patch(`/model-configs/${id}/status`, { enabled: false }).then(() => {
|
|
16106
16693
|
setSuccess(true);
|
|
16107
16694
|
setLoading(false);
|
|
@@ -16138,10 +16725,10 @@ modelsCommand.command("default <id>").description("Set a model configuration as
|
|
|
16138
16725
|
return;
|
|
16139
16726
|
}
|
|
16140
16727
|
const App = () => {
|
|
16141
|
-
const [loading, setLoading] =
|
|
16142
|
-
const [success, setSuccess] =
|
|
16143
|
-
const [error, setError] =
|
|
16144
|
-
|
|
16728
|
+
const [loading, setLoading] = useState24(true);
|
|
16729
|
+
const [success, setSuccess] = useState24(null);
|
|
16730
|
+
const [error, setError] = useState24(null);
|
|
16731
|
+
useEffect23(() => {
|
|
16145
16732
|
client.patch(`/model-configs/${id}/default`, {}).then(() => {
|
|
16146
16733
|
setSuccess(true);
|
|
16147
16734
|
setLoading(false);
|
|
@@ -16182,7 +16769,7 @@ import { Command as Command13 } from "commander";
|
|
|
16182
16769
|
import chalk19 from "chalk";
|
|
16183
16770
|
import React12 from "react";
|
|
16184
16771
|
import { render as render12 } from "ink";
|
|
16185
|
-
import { useState as
|
|
16772
|
+
import { useState as useState25, useEffect as useEffect24 } from "react";
|
|
16186
16773
|
var schedulesCommand = new Command13("schedules").description("Manage schedules");
|
|
16187
16774
|
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) => {
|
|
16188
16775
|
const apiKey = await ensureAuth();
|
|
@@ -16226,10 +16813,10 @@ schedulesCommand.command("list").description("List all schedules").option("--jso
|
|
|
16226
16813
|
return;
|
|
16227
16814
|
}
|
|
16228
16815
|
const App = () => {
|
|
16229
|
-
const [items, setItems] =
|
|
16230
|
-
const [error, setError] =
|
|
16231
|
-
const [total, setTotal] =
|
|
16232
|
-
|
|
16816
|
+
const [items, setItems] = useState25(null);
|
|
16817
|
+
const [error, setError] = useState25(null);
|
|
16818
|
+
const [total, setTotal] = useState25();
|
|
16819
|
+
useEffect24(() => {
|
|
16233
16820
|
client.get("/schedules").then((res) => {
|
|
16234
16821
|
setItems(res.data ?? []);
|
|
16235
16822
|
setTotal(getTotalCount(res.pagination));
|
|
@@ -16292,9 +16879,9 @@ schedulesCommand.command("get <id>").description("Get schedule details").option(
|
|
|
16292
16879
|
return;
|
|
16293
16880
|
}
|
|
16294
16881
|
const App = () => {
|
|
16295
|
-
const [items, setItems] =
|
|
16296
|
-
const [error, setError] =
|
|
16297
|
-
|
|
16882
|
+
const [items, setItems] = useState25(null);
|
|
16883
|
+
const [error, setError] = useState25(null);
|
|
16884
|
+
useEffect24(() => {
|
|
16298
16885
|
client.get(`/schedules/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
|
|
16299
16886
|
}, []);
|
|
16300
16887
|
return React12.createElement(DataList, {
|
|
@@ -16348,11 +16935,11 @@ schedulesCommand.command("create").description("Create a new schedule").required
|
|
|
16348
16935
|
return;
|
|
16349
16936
|
}
|
|
16350
16937
|
const App = () => {
|
|
16351
|
-
const [loading, setLoading] =
|
|
16352
|
-
const [success, setSuccess] =
|
|
16353
|
-
const [error, setError] =
|
|
16354
|
-
const [result, setResult] =
|
|
16355
|
-
|
|
16938
|
+
const [loading, setLoading] = useState25(true);
|
|
16939
|
+
const [success, setSuccess] = useState25(null);
|
|
16940
|
+
const [error, setError] = useState25(null);
|
|
16941
|
+
const [result, setResult] = useState25(null);
|
|
16942
|
+
useEffect24(() => {
|
|
16356
16943
|
client.post("/schedules", {
|
|
16357
16944
|
flowId: options.flow,
|
|
16358
16945
|
cronExpression: options.cron,
|
|
@@ -16403,10 +16990,10 @@ function simpleMutationCommand(name, description, mutationFn, successMsg, loadin
|
|
|
16403
16990
|
return;
|
|
16404
16991
|
}
|
|
16405
16992
|
const App = () => {
|
|
16406
|
-
const [loading, setLoading] =
|
|
16407
|
-
const [success, setSuccess] =
|
|
16408
|
-
const [error, setError] =
|
|
16409
|
-
|
|
16993
|
+
const [loading, setLoading] = useState25(true);
|
|
16994
|
+
const [success, setSuccess] = useState25(null);
|
|
16995
|
+
const [error, setError] = useState25(null);
|
|
16996
|
+
useEffect24(() => {
|
|
16410
16997
|
mutationFn(client, id).then(() => {
|
|
16411
16998
|
setSuccess(true);
|
|
16412
16999
|
setLoading(false);
|
|
@@ -16465,11 +17052,11 @@ schedulesCommand.command("delete <id>").description("Delete a schedule").option(
|
|
|
16465
17052
|
return;
|
|
16466
17053
|
}
|
|
16467
17054
|
const App = () => {
|
|
16468
|
-
const [confirmed, setConfirmed] =
|
|
16469
|
-
const [loading, setLoading] =
|
|
16470
|
-
const [success, setSuccess] =
|
|
16471
|
-
const [error, setError] =
|
|
16472
|
-
|
|
17055
|
+
const [confirmed, setConfirmed] = useState25(null);
|
|
17056
|
+
const [loading, setLoading] = useState25(false);
|
|
17057
|
+
const [success, setSuccess] = useState25(null);
|
|
17058
|
+
const [error, setError] = useState25(null);
|
|
17059
|
+
useEffect24(() => {
|
|
16473
17060
|
if (confirmed !== true) return void 0;
|
|
16474
17061
|
setLoading(true);
|
|
16475
17062
|
client.delete(`/schedules/${id}`).then(() => {
|
|
@@ -16513,7 +17100,7 @@ import { Command as Command14 } from "commander";
|
|
|
16513
17100
|
import chalk20 from "chalk";
|
|
16514
17101
|
import React13 from "react";
|
|
16515
17102
|
import { render as render13 } from "ink";
|
|
16516
|
-
import { useState as
|
|
17103
|
+
import { useState as useState26, useEffect as useEffect25 } from "react";
|
|
16517
17104
|
import { Text as Text28 } from "ink";
|
|
16518
17105
|
import { readFileSync as readFileSync11 } from "fs";
|
|
16519
17106
|
var evalCommand = new Command14("eval").description("Manage evaluations");
|
|
@@ -16558,11 +17145,11 @@ evalCommand.command("submit").description("Submit an eval batch").requiredOption
|
|
|
16558
17145
|
return;
|
|
16559
17146
|
}
|
|
16560
17147
|
const App = () => {
|
|
16561
|
-
const [loading, setLoading] =
|
|
16562
|
-
const [success, setSuccess] =
|
|
16563
|
-
const [error, setError] =
|
|
16564
|
-
const [resultNode, setResultNode] =
|
|
16565
|
-
|
|
17148
|
+
const [loading, setLoading] = useState26(true);
|
|
17149
|
+
const [success, setSuccess] = useState26(null);
|
|
17150
|
+
const [error, setError] = useState26(null);
|
|
17151
|
+
const [resultNode, setResultNode] = useState26(void 0);
|
|
17152
|
+
useEffect25(() => {
|
|
16566
17153
|
const run = async () => {
|
|
16567
17154
|
try {
|
|
16568
17155
|
const data = await client.post("/eval/submit", {
|
|
@@ -16641,11 +17228,11 @@ evalCommand.command("list").description("List eval batches").option("--flow <id>
|
|
|
16641
17228
|
return;
|
|
16642
17229
|
}
|
|
16643
17230
|
const App = () => {
|
|
16644
|
-
const [loading, setLoading] =
|
|
16645
|
-
const [items, setItems] =
|
|
16646
|
-
const [total, setTotal] =
|
|
16647
|
-
const [error, setError] =
|
|
16648
|
-
|
|
17231
|
+
const [loading, setLoading] = useState26(true);
|
|
17232
|
+
const [items, setItems] = useState26(null);
|
|
17233
|
+
const [total, setTotal] = useState26(void 0);
|
|
17234
|
+
const [error, setError] = useState26(null);
|
|
17235
|
+
useEffect25(() => {
|
|
16649
17236
|
const run = async () => {
|
|
16650
17237
|
try {
|
|
16651
17238
|
const data = await client.get("/eval/batches", params);
|
|
@@ -16721,11 +17308,11 @@ evalCommand.command("results <id>").description("Get eval batch results").option
|
|
|
16721
17308
|
return;
|
|
16722
17309
|
}
|
|
16723
17310
|
const App = () => {
|
|
16724
|
-
const [loading, setLoading] =
|
|
16725
|
-
const [success, setSuccess] =
|
|
16726
|
-
const [error, setError] =
|
|
16727
|
-
const [resultNode, setResultNode] =
|
|
16728
|
-
|
|
17311
|
+
const [loading, setLoading] = useState26(true);
|
|
17312
|
+
const [success, setSuccess] = useState26(null);
|
|
17313
|
+
const [error, setError] = useState26(null);
|
|
17314
|
+
const [resultNode, setResultNode] = useState26(void 0);
|
|
17315
|
+
useEffect25(() => {
|
|
16729
17316
|
const run = async () => {
|
|
16730
17317
|
try {
|
|
16731
17318
|
const data = await client.get(`/eval/${id}/results`);
|
|
@@ -16785,10 +17372,10 @@ evalCommand.command("compare <groupId>").description("Compare evals in a group")
|
|
|
16785
17372
|
return;
|
|
16786
17373
|
}
|
|
16787
17374
|
const App = () => {
|
|
16788
|
-
const [loading, setLoading] =
|
|
16789
|
-
const [success, setSuccess] =
|
|
16790
|
-
const [error, setError] =
|
|
16791
|
-
|
|
17375
|
+
const [loading, setLoading] = useState26(true);
|
|
17376
|
+
const [success, setSuccess] = useState26(null);
|
|
17377
|
+
const [error, setError] = useState26(null);
|
|
17378
|
+
useEffect25(() => {
|
|
16792
17379
|
const run = async () => {
|
|
16793
17380
|
try {
|
|
16794
17381
|
const data = await client.post("/eval/compare", { groupId });
|
|
@@ -16820,7 +17407,7 @@ import { Command as Command15 } from "commander";
|
|
|
16820
17407
|
import chalk21 from "chalk";
|
|
16821
17408
|
import React14 from "react";
|
|
16822
17409
|
import { render as render14 } from "ink";
|
|
16823
|
-
import { useState as
|
|
17410
|
+
import { useState as useState27, useEffect as useEffect26 } from "react";
|
|
16824
17411
|
import { Text as Text29 } from "ink";
|
|
16825
17412
|
var apiKeysCommand = new Command15("api-keys").description("Manage API keys");
|
|
16826
17413
|
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) => {
|
|
@@ -16859,11 +17446,11 @@ apiKeysCommand.command("list").description("List your API keys").option("--json"
|
|
|
16859
17446
|
return;
|
|
16860
17447
|
}
|
|
16861
17448
|
const App = () => {
|
|
16862
|
-
const [loading, setLoading] =
|
|
16863
|
-
const [items, setItems] =
|
|
16864
|
-
const [total, setTotal] =
|
|
16865
|
-
const [error, setError] =
|
|
16866
|
-
|
|
17449
|
+
const [loading, setLoading] = useState27(true);
|
|
17450
|
+
const [items, setItems] = useState27(null);
|
|
17451
|
+
const [total, setTotal] = useState27(void 0);
|
|
17452
|
+
const [error, setError] = useState27(null);
|
|
17453
|
+
useEffect26(() => {
|
|
16867
17454
|
const run = async () => {
|
|
16868
17455
|
try {
|
|
16869
17456
|
const data = await client.get("/api-keys");
|
|
@@ -16923,11 +17510,11 @@ apiKeysCommand.command("get <id>").description("Get API key details").option("--
|
|
|
16923
17510
|
return;
|
|
16924
17511
|
}
|
|
16925
17512
|
const App = () => {
|
|
16926
|
-
const [loading, setLoading] =
|
|
16927
|
-
const [success, setSuccess] =
|
|
16928
|
-
const [error, setError] =
|
|
16929
|
-
const [resultNode, setResultNode] =
|
|
16930
|
-
|
|
17513
|
+
const [loading, setLoading] = useState27(true);
|
|
17514
|
+
const [success, setSuccess] = useState27(null);
|
|
17515
|
+
const [error, setError] = useState27(null);
|
|
17516
|
+
const [resultNode, setResultNode] = useState27(void 0);
|
|
17517
|
+
useEffect26(() => {
|
|
16931
17518
|
const run = async () => {
|
|
16932
17519
|
try {
|
|
16933
17520
|
const data = await client.get(`/api-keys/${id}`);
|
|
@@ -16992,11 +17579,11 @@ apiKeysCommand.command("create").description("Create a new API key").requiredOpt
|
|
|
16992
17579
|
return;
|
|
16993
17580
|
}
|
|
16994
17581
|
const App = () => {
|
|
16995
|
-
const [loading, setLoading] =
|
|
16996
|
-
const [success, setSuccess] =
|
|
16997
|
-
const [error, setError] =
|
|
16998
|
-
const [resultNode, setResultNode] =
|
|
16999
|
-
|
|
17582
|
+
const [loading, setLoading] = useState27(true);
|
|
17583
|
+
const [success, setSuccess] = useState27(null);
|
|
17584
|
+
const [error, setError] = useState27(null);
|
|
17585
|
+
const [resultNode, setResultNode] = useState27(void 0);
|
|
17586
|
+
useEffect26(() => {
|
|
17000
17587
|
const run = async () => {
|
|
17001
17588
|
try {
|
|
17002
17589
|
const data = await client.post("/api-keys", {
|
|
@@ -17051,10 +17638,10 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
|
|
|
17051
17638
|
}
|
|
17052
17639
|
if (options.yes) {
|
|
17053
17640
|
const App = () => {
|
|
17054
|
-
const [loading, setLoading] =
|
|
17055
|
-
const [success, setSuccess] =
|
|
17056
|
-
const [error, setError] =
|
|
17057
|
-
|
|
17641
|
+
const [loading, setLoading] = useState27(true);
|
|
17642
|
+
const [success, setSuccess] = useState27(null);
|
|
17643
|
+
const [error, setError] = useState27(null);
|
|
17644
|
+
useEffect26(() => {
|
|
17058
17645
|
const run = async () => {
|
|
17059
17646
|
try {
|
|
17060
17647
|
await client.delete(`/api-keys/${id}`);
|
|
@@ -17094,10 +17681,10 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
|
|
|
17094
17681
|
});
|
|
17095
17682
|
if (!confirmed) return;
|
|
17096
17683
|
const DeleteApp = () => {
|
|
17097
|
-
const [loading, setLoading] =
|
|
17098
|
-
const [success, setSuccess] =
|
|
17099
|
-
const [error, setError] =
|
|
17100
|
-
|
|
17684
|
+
const [loading, setLoading] = useState27(true);
|
|
17685
|
+
const [success, setSuccess] = useState27(null);
|
|
17686
|
+
const [error, setError] = useState27(null);
|
|
17687
|
+
useEffect26(() => {
|
|
17101
17688
|
const run = async () => {
|
|
17102
17689
|
try {
|
|
17103
17690
|
await client.delete(`/api-keys/${id}`);
|
|
@@ -17147,11 +17734,11 @@ apiKeysCommand.command("regenerate <id>").description("Regenerate an API key").o
|
|
|
17147
17734
|
return;
|
|
17148
17735
|
}
|
|
17149
17736
|
const App = () => {
|
|
17150
|
-
const [loading, setLoading] =
|
|
17151
|
-
const [success, setSuccess] =
|
|
17152
|
-
const [error, setError] =
|
|
17153
|
-
const [resultNode, setResultNode] =
|
|
17154
|
-
|
|
17737
|
+
const [loading, setLoading] = useState27(true);
|
|
17738
|
+
const [success, setSuccess] = useState27(null);
|
|
17739
|
+
const [error, setError] = useState27(null);
|
|
17740
|
+
const [resultNode, setResultNode] = useState27(void 0);
|
|
17741
|
+
useEffect26(() => {
|
|
17155
17742
|
const run = async () => {
|
|
17156
17743
|
try {
|
|
17157
17744
|
const data = await client.post(`/api-keys/${id}/regenerate`);
|
|
@@ -17203,10 +17790,10 @@ apiKeysCommand.command("analytics").description("Show API key usage analytics").
|
|
|
17203
17790
|
return;
|
|
17204
17791
|
}
|
|
17205
17792
|
const App = () => {
|
|
17206
|
-
const [loading, setLoading] =
|
|
17207
|
-
const [success, setSuccess] =
|
|
17208
|
-
const [error, setError] =
|
|
17209
|
-
|
|
17793
|
+
const [loading, setLoading] = useState27(true);
|
|
17794
|
+
const [success, setSuccess] = useState27(null);
|
|
17795
|
+
const [error, setError] = useState27(null);
|
|
17796
|
+
useEffect26(() => {
|
|
17210
17797
|
const run = async () => {
|
|
17211
17798
|
try {
|
|
17212
17799
|
const path10 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
|
|
@@ -17239,7 +17826,7 @@ import { Command as Command16 } from "commander";
|
|
|
17239
17826
|
import chalk22 from "chalk";
|
|
17240
17827
|
import React15 from "react";
|
|
17241
17828
|
import { render as render15 } from "ink";
|
|
17242
|
-
import { useState as
|
|
17829
|
+
import { useState as useState28, useEffect as useEffect27 } from "react";
|
|
17243
17830
|
import { Text as Text30 } from "ink";
|
|
17244
17831
|
var analyticsCommand = new Command16("analytics").description("View analytics and execution results");
|
|
17245
17832
|
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) => {
|
|
@@ -17268,11 +17855,11 @@ analyticsCommand.command("stats").description("Show account statistics").option(
|
|
|
17268
17855
|
return;
|
|
17269
17856
|
}
|
|
17270
17857
|
const App = () => {
|
|
17271
|
-
const [loading, setLoading] =
|
|
17272
|
-
const [success, setSuccess] =
|
|
17273
|
-
const [error, setError] =
|
|
17274
|
-
const [resultNode, setResultNode] =
|
|
17275
|
-
|
|
17858
|
+
const [loading, setLoading] = useState28(true);
|
|
17859
|
+
const [success, setSuccess] = useState28(null);
|
|
17860
|
+
const [error, setError] = useState28(null);
|
|
17861
|
+
const [resultNode, setResultNode] = useState28(void 0);
|
|
17862
|
+
useEffect27(() => {
|
|
17276
17863
|
const run = async () => {
|
|
17277
17864
|
try {
|
|
17278
17865
|
const data = await client.get("/analytics/stats");
|
|
@@ -17352,11 +17939,11 @@ analyticsCommand.command("results").description("List execution results").option
|
|
|
17352
17939
|
return;
|
|
17353
17940
|
}
|
|
17354
17941
|
const App = () => {
|
|
17355
|
-
const [loading, setLoading] =
|
|
17356
|
-
const [items, setItems] =
|
|
17357
|
-
const [total, setTotal] =
|
|
17358
|
-
const [error, setError] =
|
|
17359
|
-
|
|
17942
|
+
const [loading, setLoading] = useState28(true);
|
|
17943
|
+
const [items, setItems] = useState28(null);
|
|
17944
|
+
const [total, setTotal] = useState28(void 0);
|
|
17945
|
+
const [error, setError] = useState28(null);
|
|
17946
|
+
useEffect27(() => {
|
|
17360
17947
|
const run = async () => {
|
|
17361
17948
|
try {
|
|
17362
17949
|
const data = await client.get(
|
|
@@ -17401,7 +17988,7 @@ import { Command as Command17 } from "commander";
|
|
|
17401
17988
|
import chalk23 from "chalk";
|
|
17402
17989
|
import React16 from "react";
|
|
17403
17990
|
import { render as render16 } from "ink";
|
|
17404
|
-
import { useState as
|
|
17991
|
+
import { useState as useState29, useEffect as useEffect28 } from "react";
|
|
17405
17992
|
import open5 from "open";
|
|
17406
17993
|
var billingCommand = new Command17("billing").description("View billing and subscription info");
|
|
17407
17994
|
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) => {
|
|
@@ -17447,11 +18034,11 @@ billingCommand.command("status").description("Show current plan and usage").opti
|
|
|
17447
18034
|
return;
|
|
17448
18035
|
}
|
|
17449
18036
|
const App = () => {
|
|
17450
|
-
const [loading, setLoading] =
|
|
17451
|
-
const [success, setSuccess] =
|
|
17452
|
-
const [error, setError] =
|
|
17453
|
-
const [resultNode, setResultNode] =
|
|
17454
|
-
|
|
18037
|
+
const [loading, setLoading] = useState29(true);
|
|
18038
|
+
const [success, setSuccess] = useState29(null);
|
|
18039
|
+
const [error, setError] = useState29(null);
|
|
18040
|
+
const [resultNode, setResultNode] = useState29(void 0);
|
|
18041
|
+
useEffect28(() => {
|
|
17455
18042
|
const run = async () => {
|
|
17456
18043
|
try {
|
|
17457
18044
|
const data = await client.get("/billing/status");
|
|
@@ -17518,11 +18105,11 @@ billingCommand.command("portal").description("Open the billing portal in your br
|
|
|
17518
18105
|
return;
|
|
17519
18106
|
}
|
|
17520
18107
|
const App = () => {
|
|
17521
|
-
const [loading, setLoading] =
|
|
17522
|
-
const [success, setSuccess] =
|
|
17523
|
-
const [error, setError] =
|
|
17524
|
-
const [msg, setMsg] =
|
|
17525
|
-
|
|
18108
|
+
const [loading, setLoading] = useState29(true);
|
|
18109
|
+
const [success, setSuccess] = useState29(null);
|
|
18110
|
+
const [error, setError] = useState29(null);
|
|
18111
|
+
const [msg, setMsg] = useState29("Opening billing portal...");
|
|
18112
|
+
useEffect28(() => {
|
|
17526
18113
|
const run = async () => {
|
|
17527
18114
|
try {
|
|
17528
18115
|
const data = await client.post("/billing/portal");
|
|
@@ -17571,10 +18158,10 @@ billingCommand.command("refresh").description("Refresh plan data from billing pr
|
|
|
17571
18158
|
return;
|
|
17572
18159
|
}
|
|
17573
18160
|
const App = () => {
|
|
17574
|
-
const [loading, setLoading] =
|
|
17575
|
-
const [success, setSuccess] =
|
|
17576
|
-
const [error, setError] =
|
|
17577
|
-
|
|
18161
|
+
const [loading, setLoading] = useState29(true);
|
|
18162
|
+
const [success, setSuccess] = useState29(null);
|
|
18163
|
+
const [error, setError] = useState29(null);
|
|
18164
|
+
useEffect28(() => {
|
|
17578
18165
|
const run = async () => {
|
|
17579
18166
|
try {
|
|
17580
18167
|
await client.post("/billing/refresh");
|
|
@@ -17605,7 +18192,7 @@ import { Command as Command18 } from "commander";
|
|
|
17605
18192
|
import chalk24 from "chalk";
|
|
17606
18193
|
import React17 from "react";
|
|
17607
18194
|
import { render as render17 } from "ink";
|
|
17608
|
-
import { useState as
|
|
18195
|
+
import { useState as useState30, useEffect as useEffect29 } from "react";
|
|
17609
18196
|
import { Text as Text31 } from "ink";
|
|
17610
18197
|
var flowVersionsCommand = new Command18("flow-versions").description(
|
|
17611
18198
|
"Manage flow versions"
|
|
@@ -17642,10 +18229,10 @@ flowVersionsCommand.command("list <flowId>").description("List all versions for
|
|
|
17642
18229
|
return;
|
|
17643
18230
|
}
|
|
17644
18231
|
const App = () => {
|
|
17645
|
-
const [loading, setLoading] =
|
|
17646
|
-
const [items, setItems] =
|
|
17647
|
-
const [error, setError] =
|
|
17648
|
-
|
|
18232
|
+
const [loading, setLoading] = useState30(true);
|
|
18233
|
+
const [items, setItems] = useState30(null);
|
|
18234
|
+
const [error, setError] = useState30(null);
|
|
18235
|
+
useEffect29(() => {
|
|
17649
18236
|
const run = async () => {
|
|
17650
18237
|
try {
|
|
17651
18238
|
const data = await client.get(`/flow-versions/${flowId}`);
|
|
@@ -17703,11 +18290,11 @@ flowVersionsCommand.command("get <flowId> <versionId>").description("Get a speci
|
|
|
17703
18290
|
return;
|
|
17704
18291
|
}
|
|
17705
18292
|
const App = () => {
|
|
17706
|
-
const [loading, setLoading] =
|
|
17707
|
-
const [success, setSuccess] =
|
|
17708
|
-
const [error, setError] =
|
|
17709
|
-
const [resultNode, setResultNode] =
|
|
17710
|
-
|
|
18293
|
+
const [loading, setLoading] = useState30(true);
|
|
18294
|
+
const [success, setSuccess] = useState30(null);
|
|
18295
|
+
const [error, setError] = useState30(null);
|
|
18296
|
+
const [resultNode, setResultNode] = useState30(void 0);
|
|
18297
|
+
useEffect29(() => {
|
|
17711
18298
|
const run = async () => {
|
|
17712
18299
|
try {
|
|
17713
18300
|
const data = await client.get(`/flow-versions/${flowId}/${versionId}`);
|
|
@@ -17769,11 +18356,11 @@ flowVersionsCommand.command("published <flowId>").description("Get the published
|
|
|
17769
18356
|
return;
|
|
17770
18357
|
}
|
|
17771
18358
|
const App = () => {
|
|
17772
|
-
const [loading, setLoading] =
|
|
17773
|
-
const [success, setSuccess] =
|
|
17774
|
-
const [error, setError] =
|
|
17775
|
-
const [resultNode, setResultNode] =
|
|
17776
|
-
|
|
18359
|
+
const [loading, setLoading] = useState30(true);
|
|
18360
|
+
const [success, setSuccess] = useState30(null);
|
|
18361
|
+
const [error, setError] = useState30(null);
|
|
18362
|
+
const [resultNode, setResultNode] = useState30(void 0);
|
|
18363
|
+
useEffect29(() => {
|
|
17777
18364
|
const run = async () => {
|
|
17778
18365
|
try {
|
|
17779
18366
|
const data = await client.get(`/flow-versions/${flowId}/published`);
|
|
@@ -17826,10 +18413,10 @@ flowVersionsCommand.command("publish <flowId>").description("Publish a version")
|
|
|
17826
18413
|
return;
|
|
17827
18414
|
}
|
|
17828
18415
|
const App = () => {
|
|
17829
|
-
const [loading, setLoading] =
|
|
17830
|
-
const [success, setSuccess] =
|
|
17831
|
-
const [error, setError] =
|
|
17832
|
-
|
|
18416
|
+
const [loading, setLoading] = useState30(true);
|
|
18417
|
+
const [success, setSuccess] = useState30(null);
|
|
18418
|
+
const [error, setError] = useState30(null);
|
|
18419
|
+
useEffect29(() => {
|
|
17833
18420
|
const run = async () => {
|
|
17834
18421
|
try {
|
|
17835
18422
|
await client.post(`/flow-versions/${flowId}/publish`, {
|