@runtypelabs/cli 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1894 -1181
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -990,6 +990,9 @@ var require_generated_model_routing = __commonJS({
|
|
|
990
990
|
"grok-4-fast-reasoning": ["vercel"],
|
|
991
991
|
"grok-4.1-fast-non-reasoning": ["vercel"],
|
|
992
992
|
"grok-4.1-fast-reasoning": ["vercel"],
|
|
993
|
+
"grok-4.20-multi-agent-beta": ["vercel"],
|
|
994
|
+
"grok-4.20-non-reasoning-beta": ["vercel"],
|
|
995
|
+
"grok-4.20-reasoning-beta": ["vercel"],
|
|
993
996
|
"grok-beta": ["xai"],
|
|
994
997
|
"grok-code-fast-1": ["vercel", "xai"],
|
|
995
998
|
"grok-vision-beta": ["xai"],
|
|
@@ -1030,6 +1033,7 @@ var require_generated_model_routing = __commonJS({
|
|
|
1030
1033
|
"Llama-4-Scout-17B-16E-Instruct": ["togetherai"],
|
|
1031
1034
|
"longcat-flash-chat": ["vercel"],
|
|
1032
1035
|
"longcat-flash-thinking": ["vercel"],
|
|
1036
|
+
"longcat-flash-thinking-2601": ["vercel"],
|
|
1033
1037
|
"magistral-medium": ["vercel"],
|
|
1034
1038
|
"magistral-small": ["vercel"],
|
|
1035
1039
|
"mercury-2": ["vercel"],
|
|
@@ -1115,7 +1119,6 @@ var require_generated_model_routing = __commonJS({
|
|
|
1115
1119
|
"openchat-3.5-1210": ["togetherai"],
|
|
1116
1120
|
"OpenHermes-2-Mistral-7B": ["togetherai"],
|
|
1117
1121
|
"OpenHermes-2p5-Mistral-7B": ["togetherai"],
|
|
1118
|
-
"orchestrator-8b": ["mixlayer"],
|
|
1119
1122
|
"phi-2": ["togetherai"],
|
|
1120
1123
|
"pixtral-12b": ["vercel"],
|
|
1121
1124
|
"pixtral-large": ["vercel"],
|
|
@@ -1140,10 +1143,6 @@ var require_generated_model_routing = __commonJS({
|
|
|
1140
1143
|
"Qwen2.5-Coder-32B-Instruct": ["togetherai"],
|
|
1141
1144
|
"Qwen2.5-VL-72B-Instruct": ["togetherai"],
|
|
1142
1145
|
"qwen3-235b-a22b-thinking": ["vercel"],
|
|
1143
|
-
"qwen3-30b-a3b-instruct": ["mixlayer"],
|
|
1144
|
-
"qwen3-30b-a3b-thinking": ["mixlayer"],
|
|
1145
|
-
"qwen3-32b": ["mixlayer"],
|
|
1146
|
-
"qwen3-8b": ["mixlayer"],
|
|
1147
1146
|
"qwen3-coder": ["vercel"],
|
|
1148
1147
|
"qwen3-coder-30b-a3b": ["vercel"],
|
|
1149
1148
|
"qwen3-coder-next": ["vercel"],
|
|
@@ -1158,6 +1157,8 @@ var require_generated_model_routing = __commonJS({
|
|
|
1158
1157
|
"qwen3-next-80b-a3b-thinking": ["vercel"],
|
|
1159
1158
|
"qwen3-vl-instruct": ["vercel"],
|
|
1160
1159
|
"qwen3-vl-thinking": ["vercel"],
|
|
1160
|
+
"qwen3.5-122b-a10b": ["mixlayer"],
|
|
1161
|
+
"qwen3.5-27b": ["mixlayer"],
|
|
1161
1162
|
"qwen3.5-35b-a3b": ["mixlayer"],
|
|
1162
1163
|
"qwen3.5-397b-a17b": ["mixlayer"],
|
|
1163
1164
|
"qwen3.5-9b": ["mixlayer"],
|
|
@@ -1432,6 +1433,9 @@ var require_generated_model_routing = __commonJS({
|
|
|
1432
1433
|
"grok-4": ["vercel", "xai"],
|
|
1433
1434
|
"grok-4-1-fast-non-reasoning": ["vercel"],
|
|
1434
1435
|
"grok-4-1-fast-reasoning": ["vercel"],
|
|
1436
|
+
"grok-4-20-multi-agent-beta": ["vercel"],
|
|
1437
|
+
"grok-4-20-non-reasoning-beta": ["vercel"],
|
|
1438
|
+
"grok-4-20-reasoning-beta": ["vercel"],
|
|
1435
1439
|
"grok-4-fast": ["xai"],
|
|
1436
1440
|
"grok-4-fast-non-reasoning": ["vercel"],
|
|
1437
1441
|
"grok-4-fast-reasoning": ["vercel"],
|
|
@@ -1467,6 +1471,7 @@ var require_generated_model_routing = __commonJS({
|
|
|
1467
1471
|
"llama3-3-70b": ["vercel"],
|
|
1468
1472
|
"longcat-flash": ["vercel"],
|
|
1469
1473
|
"longcat-flash-chat": ["vercel"],
|
|
1474
|
+
"longcat-flash-thinking-2601": ["vercel"],
|
|
1470
1475
|
"magistral-medium": ["vercel"],
|
|
1471
1476
|
"magistral-small": ["vercel"],
|
|
1472
1477
|
"mercury-2": ["vercel"],
|
|
@@ -1552,7 +1557,6 @@ var require_generated_model_routing = __commonJS({
|
|
|
1552
1557
|
"openchat-3-5-1210": ["togetherai"],
|
|
1553
1558
|
"openhermes-2-mistral-7b": ["togetherai"],
|
|
1554
1559
|
"openhermes-2p5-mistral-7b": ["togetherai"],
|
|
1555
|
-
"orchestrator-8b": ["mixlayer"],
|
|
1556
1560
|
"phi-2": ["togetherai"],
|
|
1557
1561
|
"pixtral-12b": ["vercel"],
|
|
1558
1562
|
"pixtral-large": ["vercel"],
|
|
@@ -1576,15 +1580,14 @@ var require_generated_model_routing = __commonJS({
|
|
|
1576
1580
|
"qwen2-5-coder-32b-instruct": ["togetherai"],
|
|
1577
1581
|
"qwen2-5-vl-72b-instruct": ["togetherai"],
|
|
1578
1582
|
"qwen3-235b-a22b": ["vercel"],
|
|
1579
|
-
"qwen3-
|
|
1580
|
-
"qwen3-
|
|
1581
|
-
"qwen3-
|
|
1583
|
+
"qwen3-32b": ["vercel"],
|
|
1584
|
+
"qwen3-5-122b-a10b": ["mixlayer"],
|
|
1585
|
+
"qwen3-5-27b": ["mixlayer"],
|
|
1582
1586
|
"qwen3-5-35b-a3b": ["mixlayer"],
|
|
1583
1587
|
"qwen3-5-397b-a17b": ["mixlayer"],
|
|
1584
1588
|
"qwen3-5-9b": ["mixlayer"],
|
|
1585
1589
|
"qwen3-5-flash": ["vercel"],
|
|
1586
1590
|
"qwen3-5-plus": ["vercel"],
|
|
1587
|
-
"qwen3-8b": ["mixlayer"],
|
|
1588
1591
|
"qwen3-coder": ["vercel"],
|
|
1589
1592
|
"qwen3-coder-30b-a3b": ["vercel"],
|
|
1590
1593
|
"qwen3-coder-next": ["vercel"],
|
|
@@ -2649,6 +2652,15 @@ var require_generated_model_routing = __commonJS({
|
|
|
2649
2652
|
"grok-4-1-fast-reasoning": {
|
|
2650
2653
|
"vercel": "xai/grok-4.1-fast-reasoning"
|
|
2651
2654
|
},
|
|
2655
|
+
"grok-4-20-multi-agent-beta": {
|
|
2656
|
+
"vercel": "xai/grok-4.20-multi-agent-beta"
|
|
2657
|
+
},
|
|
2658
|
+
"grok-4-20-non-reasoning-beta": {
|
|
2659
|
+
"vercel": "xai/grok-4.20-non-reasoning-beta"
|
|
2660
|
+
},
|
|
2661
|
+
"grok-4-20-reasoning-beta": {
|
|
2662
|
+
"vercel": "xai/grok-4.20-reasoning-beta"
|
|
2663
|
+
},
|
|
2652
2664
|
"grok-4-fast": {
|
|
2653
2665
|
"xai": "x/grok-4-fast"
|
|
2654
2666
|
},
|
|
@@ -2664,6 +2676,15 @@ var require_generated_model_routing = __commonJS({
|
|
|
2664
2676
|
"grok-4.1-fast-reasoning": {
|
|
2665
2677
|
"vercel": "xai/grok-4.1-fast-reasoning"
|
|
2666
2678
|
},
|
|
2679
|
+
"grok-4.20-multi-agent-beta": {
|
|
2680
|
+
"vercel": "xai/grok-4.20-multi-agent-beta"
|
|
2681
|
+
},
|
|
2682
|
+
"grok-4.20-non-reasoning-beta": {
|
|
2683
|
+
"vercel": "xai/grok-4.20-non-reasoning-beta"
|
|
2684
|
+
},
|
|
2685
|
+
"grok-4.20-reasoning-beta": {
|
|
2686
|
+
"vercel": "xai/grok-4.20-reasoning-beta"
|
|
2687
|
+
},
|
|
2667
2688
|
"grok-beta": {
|
|
2668
2689
|
"xai": "grok-beta"
|
|
2669
2690
|
},
|
|
@@ -2830,6 +2851,9 @@ var require_generated_model_routing = __commonJS({
|
|
|
2830
2851
|
"longcat-flash-thinking": {
|
|
2831
2852
|
"vercel": "meituan/longcat-flash-thinking"
|
|
2832
2853
|
},
|
|
2854
|
+
"longcat-flash-thinking-2601": {
|
|
2855
|
+
"vercel": "meituan/longcat-flash-thinking-2601"
|
|
2856
|
+
},
|
|
2833
2857
|
"magistral-medium": {
|
|
2834
2858
|
"vercel": "mistral/magistral-medium"
|
|
2835
2859
|
},
|
|
@@ -3195,9 +3219,6 @@ var require_generated_model_routing = __commonJS({
|
|
|
3195
3219
|
"OpenHermes-2p5-Mistral-7B": {
|
|
3196
3220
|
"togetherai": "teknium/OpenHermes-2p5-Mistral-7B"
|
|
3197
3221
|
},
|
|
3198
|
-
"orchestrator-8b": {
|
|
3199
|
-
"mixlayer": "nvidia/orchestrator-8b"
|
|
3200
|
-
},
|
|
3201
3222
|
"phi-2": {
|
|
3202
3223
|
"togetherai": "microsoft/phi-2"
|
|
3203
3224
|
},
|
|
@@ -3321,19 +3342,15 @@ var require_generated_model_routing = __commonJS({
|
|
|
3321
3342
|
"qwen3-235b-a22b-thinking": {
|
|
3322
3343
|
"vercel": "alibaba/qwen3-235b-a22b-thinking"
|
|
3323
3344
|
},
|
|
3324
|
-
"qwen3-30b-a3b": {
|
|
3325
|
-
"mixlayer": "qwen/qwen3-30b-a3b-thinking"
|
|
3326
|
-
},
|
|
3327
|
-
"qwen3-30b-a3b-instruct": {
|
|
3328
|
-
"mixlayer": "qwen/qwen3-30b-a3b-instruct"
|
|
3329
|
-
},
|
|
3330
|
-
"qwen3-30b-a3b-thinking": {
|
|
3331
|
-
"mixlayer": "qwen/qwen3-30b-a3b-thinking"
|
|
3332
|
-
},
|
|
3333
3345
|
"qwen3-32b": {
|
|
3334
|
-
"mixlayer": "qwen/qwen3-32b",
|
|
3335
3346
|
"vercel": "alibaba/qwen-3-32b"
|
|
3336
3347
|
},
|
|
3348
|
+
"qwen3-5-122b-a10b": {
|
|
3349
|
+
"mixlayer": "qwen/qwen3.5-122b-a10b"
|
|
3350
|
+
},
|
|
3351
|
+
"qwen3-5-27b": {
|
|
3352
|
+
"mixlayer": "qwen/qwen3.5-27b"
|
|
3353
|
+
},
|
|
3337
3354
|
"qwen3-5-35b-a3b": {
|
|
3338
3355
|
"mixlayer": "qwen/qwen3.5-35b-a3b"
|
|
3339
3356
|
},
|
|
@@ -3349,9 +3366,6 @@ var require_generated_model_routing = __commonJS({
|
|
|
3349
3366
|
"qwen3-5-plus": {
|
|
3350
3367
|
"vercel": "alibaba/qwen3.5-plus"
|
|
3351
3368
|
},
|
|
3352
|
-
"qwen3-8b": {
|
|
3353
|
-
"mixlayer": "qwen/qwen3-8b"
|
|
3354
|
-
},
|
|
3355
3369
|
"qwen3-coder": {
|
|
3356
3370
|
"vercel": "alibaba/qwen3-coder"
|
|
3357
3371
|
},
|
|
@@ -3403,6 +3417,12 @@ var require_generated_model_routing = __commonJS({
|
|
|
3403
3417
|
"qwen3-vl-thinking": {
|
|
3404
3418
|
"vercel": "alibaba/qwen3-vl-thinking"
|
|
3405
3419
|
},
|
|
3420
|
+
"qwen3.5-122b-a10b": {
|
|
3421
|
+
"mixlayer": "qwen/qwen3.5-122b-a10b"
|
|
3422
|
+
},
|
|
3423
|
+
"qwen3.5-27b": {
|
|
3424
|
+
"mixlayer": "qwen/qwen3.5-27b"
|
|
3425
|
+
},
|
|
3406
3426
|
"qwen3.5-35b-a3b": {
|
|
3407
3427
|
"mixlayer": "qwen/qwen3.5-35b-a3b"
|
|
3408
3428
|
},
|
|
@@ -8327,9 +8347,8 @@ import { useState as useState22, useEffect as useEffect20, useRef as useRef8, us
|
|
|
8327
8347
|
import { execSync } from "child_process";
|
|
8328
8348
|
import * as fs4 from "fs";
|
|
8329
8349
|
import open4 from "open";
|
|
8330
|
-
import { Box as
|
|
8331
|
-
import {
|
|
8332
|
-
import { LoadingAnimation } from "@runtypelabs/terminal-animations";
|
|
8350
|
+
import { Box as Box28, Text as Text28, useApp as useApp4, useInput as useInput11, useStdout as useStdout5 } from "ink";
|
|
8351
|
+
import { StatusBar, theme as theme31 } from "@runtypelabs/ink-components";
|
|
8333
8352
|
|
|
8334
8353
|
// src/ink/marathon/useMarathonStream.ts
|
|
8335
8354
|
import { useState as useState10, useRef as useRef3, useMemo, useCallback as useCallback2 } from "react";
|
|
@@ -8382,21 +8401,155 @@ var INITIAL_STATE = {
|
|
|
8382
8401
|
contextCompaction: null
|
|
8383
8402
|
};
|
|
8384
8403
|
var MAX_RAW_EVENTS = 15e3;
|
|
8404
|
+
var TOOL_PREVIEW_FIELD_LIMIT = 2;
|
|
8405
|
+
var TOOL_PREVIEW_VALUE_MAX_CHARS = 48;
|
|
8406
|
+
var TOOL_PREVIEW_MAX_CHARS = 120;
|
|
8407
|
+
var HEAVY_PREVIEW_KEYS = /* @__PURE__ */ new Set([
|
|
8408
|
+
"content",
|
|
8409
|
+
"code",
|
|
8410
|
+
"script",
|
|
8411
|
+
"body",
|
|
8412
|
+
"prompt",
|
|
8413
|
+
"input",
|
|
8414
|
+
"stdout",
|
|
8415
|
+
"stderr",
|
|
8416
|
+
"output",
|
|
8417
|
+
"text",
|
|
8418
|
+
"diff",
|
|
8419
|
+
"patch",
|
|
8420
|
+
"html",
|
|
8421
|
+
"markdown"
|
|
8422
|
+
]);
|
|
8423
|
+
var HEAVY_EVENT_FIELDS = ["parameters", "result", "finalOutput"];
|
|
8424
|
+
var INLINE_TOOL_NAMES = /* @__PURE__ */ new Set(["write_file", "read_file"]);
|
|
8425
|
+
var MAX_INLINE_TOOL_STRING_CHARS = 160;
|
|
8426
|
+
var MAX_INLINE_TOOL_KEYS = 6;
|
|
8385
8427
|
function appendContentLine(content, line) {
|
|
8386
8428
|
if (!content) return line;
|
|
8387
8429
|
const separator = content.endsWith("\n") ? "" : "\n";
|
|
8388
8430
|
return `${content}${separator}${line}`;
|
|
8389
8431
|
}
|
|
8390
|
-
function
|
|
8391
|
-
|
|
8392
|
-
|
|
8393
|
-
|
|
8394
|
-
|
|
8395
|
-
|
|
8432
|
+
function truncatePreviewText(text, maxChars = TOOL_PREVIEW_VALUE_MAX_CHARS) {
|
|
8433
|
+
if (text.length <= maxChars) return text;
|
|
8434
|
+
return `${text.slice(0, Math.max(0, maxChars - 1))}\u2026`;
|
|
8435
|
+
}
|
|
8436
|
+
function clampPreview(preview) {
|
|
8437
|
+
if (preview.length <= TOOL_PREVIEW_MAX_CHARS) return preview;
|
|
8438
|
+
return `${preview.slice(0, Math.max(0, TOOL_PREVIEW_MAX_CHARS - 1))}\u2026`;
|
|
8439
|
+
}
|
|
8440
|
+
function isLargeToolValue(value) {
|
|
8441
|
+
if (typeof value === "string") return value.length > MAX_INLINE_TOOL_STRING_CHARS;
|
|
8442
|
+
if (Array.isArray(value)) {
|
|
8443
|
+
return value.length > 8 || value.some((item) => item != null && typeof item === "object");
|
|
8444
|
+
}
|
|
8445
|
+
if (value && typeof value === "object") {
|
|
8446
|
+
return Object.keys(value).length > MAX_INLINE_TOOL_KEYS;
|
|
8447
|
+
}
|
|
8448
|
+
return false;
|
|
8449
|
+
}
|
|
8450
|
+
function shouldKeepToolPayloadInline(toolName, payload) {
|
|
8451
|
+
if (payload == null) return false;
|
|
8452
|
+
if (INLINE_TOOL_NAMES.has(toolName)) return true;
|
|
8453
|
+
if (typeof payload === "string") return payload.length <= MAX_INLINE_TOOL_STRING_CHARS;
|
|
8454
|
+
if (typeof payload !== "object") return true;
|
|
8455
|
+
const entries = Object.entries(payload);
|
|
8456
|
+
if (entries.length > MAX_INLINE_TOOL_KEYS) return false;
|
|
8457
|
+
return entries.every(([key, value]) => !HEAVY_PREVIEW_KEYS.has(key) && !isLargeToolValue(value));
|
|
8458
|
+
}
|
|
8459
|
+
function buildPersistedEventData(data, listData) {
|
|
8460
|
+
if (!listData) return data;
|
|
8461
|
+
const omittedFields = HEAVY_EVENT_FIELDS.filter((field) => data[field] !== void 0);
|
|
8462
|
+
if (omittedFields.length === 0) return data;
|
|
8463
|
+
return {
|
|
8464
|
+
...listData,
|
|
8465
|
+
omittedFields
|
|
8466
|
+
};
|
|
8467
|
+
}
|
|
8468
|
+
function setStoredToolPayloadField(payloads, toolId, field, value) {
|
|
8469
|
+
const next = { ...payloads.get(toolId) ?? {} };
|
|
8470
|
+
if (value === void 0) {
|
|
8471
|
+
delete next[field];
|
|
8472
|
+
} else {
|
|
8473
|
+
next[field] = value;
|
|
8474
|
+
}
|
|
8475
|
+
if (next.parameters === void 0 && next.result === void 0 && next.streamedInput === void 0) {
|
|
8476
|
+
payloads.delete(toolId);
|
|
8477
|
+
} else {
|
|
8478
|
+
payloads.set(toolId, next);
|
|
8479
|
+
}
|
|
8480
|
+
}
|
|
8481
|
+
function prioritizePreviewEntries(entries) {
|
|
8482
|
+
const light = [];
|
|
8483
|
+
const heavy = [];
|
|
8484
|
+
for (const entry of entries) {
|
|
8485
|
+
if (HEAVY_PREVIEW_KEYS.has(entry[0])) {
|
|
8486
|
+
heavy.push(entry);
|
|
8487
|
+
} else {
|
|
8488
|
+
light.push(entry);
|
|
8489
|
+
}
|
|
8490
|
+
}
|
|
8491
|
+
return [...light, ...heavy].slice(0, TOOL_PREVIEW_FIELD_LIMIT);
|
|
8492
|
+
}
|
|
8493
|
+
function stringifyPreviewValue(value) {
|
|
8494
|
+
if (typeof value === "string") return JSON.stringify(truncatePreviewText(value));
|
|
8495
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
8496
|
+
if (value === null) return "null";
|
|
8497
|
+
if (Array.isArray(value)) return "[...]";
|
|
8498
|
+
if (typeof value === "object") return "{...}";
|
|
8499
|
+
return JSON.stringify(truncatePreviewText(String(value)));
|
|
8500
|
+
}
|
|
8501
|
+
function buildPreviewFromParameters(parameters) {
|
|
8502
|
+
if (!parameters) return void 0;
|
|
8503
|
+
const entries = Object.entries(parameters).filter(([, value]) => value !== void 0);
|
|
8504
|
+
if (entries.length === 0) return void 0;
|
|
8505
|
+
return clampPreview(prioritizePreviewEntries(entries).map(([key, value]) => `${key}=${stringifyPreviewValue(value)}`).join(" "));
|
|
8506
|
+
}
|
|
8507
|
+
function buildPreviewFromStreamedInput(input) {
|
|
8508
|
+
const scanWindow = input.length > 500 ? input.slice(0, 500) : input;
|
|
8509
|
+
const matches = Array.from(
|
|
8510
|
+
scanWindow.matchAll(/"([^"]+)"\s*:\s*("[^"\\]*(?:\\.[^"\\]*)*"|true|false|null|-?\d+(?:\.\d+)?)/g)
|
|
8511
|
+
);
|
|
8512
|
+
if (matches.length === 0) return void 0;
|
|
8513
|
+
return clampPreview(prioritizePreviewEntries(matches.map((match) => {
|
|
8514
|
+
const [, key, rawValue] = match;
|
|
8515
|
+
let value = rawValue;
|
|
8516
|
+
if (value.startsWith('"')) {
|
|
8517
|
+
try {
|
|
8518
|
+
value = JSON.stringify(truncatePreviewText(JSON.parse(value)));
|
|
8519
|
+
} catch {
|
|
8520
|
+
value = truncatePreviewText(value);
|
|
8521
|
+
}
|
|
8396
8522
|
}
|
|
8523
|
+
return [key, value];
|
|
8524
|
+
})).map((match) => {
|
|
8525
|
+
const [key, value] = match;
|
|
8526
|
+
return `${key}=${value}`;
|
|
8527
|
+
}).join(" "));
|
|
8528
|
+
}
|
|
8529
|
+
function buildToolPreview(params) {
|
|
8530
|
+
if (params.existingPreview && params.streamedInput) return params.existingPreview;
|
|
8531
|
+
return (params.streamedInput ? buildPreviewFromStreamedInput(params.streamedInput) : void 0) || buildPreviewFromParameters(params.parameters);
|
|
8532
|
+
}
|
|
8533
|
+
function pushRawEvent(eventsRef, type, data, writer, listData) {
|
|
8534
|
+
const event = { timestamp: Date.now(), type, data, ...listData ? { listData } : {} };
|
|
8535
|
+
if (writer?.current) {
|
|
8536
|
+
const w = writer.current;
|
|
8537
|
+
const jsonlEvent = {
|
|
8538
|
+
timestamp: event.timestamp,
|
|
8539
|
+
type: event.type,
|
|
8540
|
+
data: buildPersistedEventData(event.data, listData)
|
|
8541
|
+
};
|
|
8542
|
+
setTimeout(() => {
|
|
8543
|
+
try {
|
|
8544
|
+
w(jsonlEvent);
|
|
8545
|
+
} catch {
|
|
8546
|
+
}
|
|
8547
|
+
}, 0);
|
|
8548
|
+
}
|
|
8549
|
+
eventsRef.current.push(event);
|
|
8550
|
+
if (eventsRef.current.length > MAX_RAW_EVENTS) {
|
|
8551
|
+
eventsRef.current = eventsRef.current.slice(-MAX_RAW_EVENTS);
|
|
8397
8552
|
}
|
|
8398
|
-
const events = [...prev.rawEvents, event];
|
|
8399
|
-
return events.length > MAX_RAW_EVENTS ? events.slice(-MAX_RAW_EVENTS) : events;
|
|
8400
8553
|
}
|
|
8401
8554
|
function formatContextCompactionCompleteLine(event) {
|
|
8402
8555
|
const modeLabel = event.mode === "auto" ? "automatically" : "with compact mode";
|
|
@@ -8418,27 +8571,57 @@ function formatContextNoticeLine(event) {
|
|
|
8418
8571
|
var toolCounter = 0;
|
|
8419
8572
|
function useMarathonStream() {
|
|
8420
8573
|
const [state, setState] = useState10(INITIAL_STATE);
|
|
8574
|
+
const rawEventsRef = useRef3([]);
|
|
8421
8575
|
const stateRef = useRef3(state);
|
|
8422
8576
|
stateRef.current = state;
|
|
8423
8577
|
const eventWriterRef = useRef3(null);
|
|
8578
|
+
const toolPayloadsRef = useRef3(/* @__PURE__ */ new Map());
|
|
8579
|
+
const hydrateToolEntry = useCallback2((tool) => {
|
|
8580
|
+
const payload = toolPayloadsRef.current.get(tool.id);
|
|
8581
|
+
if (!payload) return tool;
|
|
8582
|
+
return {
|
|
8583
|
+
...tool,
|
|
8584
|
+
...payload.parameters !== void 0 ? { parameters: payload.parameters } : {},
|
|
8585
|
+
...payload.result !== void 0 ? { result: payload.result } : {},
|
|
8586
|
+
...payload.streamedInput !== void 0 ? { streamedInput: payload.streamedInput } : {}
|
|
8587
|
+
};
|
|
8588
|
+
}, []);
|
|
8589
|
+
const getHydratedState = useCallback2(
|
|
8590
|
+
() => ({
|
|
8591
|
+
...stateRef.current,
|
|
8592
|
+
tools: stateRef.current.tools.map((tool) => hydrateToolEntry(tool)),
|
|
8593
|
+
rawEvents: rawEventsRef.current
|
|
8594
|
+
}),
|
|
8595
|
+
[hydrateToolEntry]
|
|
8596
|
+
);
|
|
8424
8597
|
const callbacks = useMemo(
|
|
8425
8598
|
() => ({
|
|
8426
8599
|
onAgentStart() {
|
|
8600
|
+
pushRawEvent(rawEventsRef, "agent_start", {}, eventWriterRef);
|
|
8427
8601
|
setState((prev) => ({
|
|
8428
8602
|
...prev,
|
|
8429
8603
|
phase: "thinking",
|
|
8430
|
-
thinkingStartedAt: Date.now()
|
|
8431
|
-
rawEvents: pushRawEvent(prev, "agent_start", {}, eventWriterRef)
|
|
8604
|
+
thinkingStartedAt: Date.now()
|
|
8432
8605
|
}));
|
|
8433
8606
|
},
|
|
8434
8607
|
onIterationStart(event) {
|
|
8608
|
+
pushRawEvent(rawEventsRef, "agent_iteration_start", { ...event }, eventWriterRef);
|
|
8435
8609
|
setState((prev) => ({
|
|
8436
8610
|
...prev,
|
|
8437
|
-
currentIteration: event.iteration
|
|
8438
|
-
rawEvents: pushRawEvent(prev, "agent_iteration_start", { ...event }, eventWriterRef)
|
|
8611
|
+
currentIteration: event.iteration
|
|
8439
8612
|
}));
|
|
8440
8613
|
},
|
|
8441
8614
|
onTurnDelta(event) {
|
|
8615
|
+
pushRawEvent(
|
|
8616
|
+
rawEventsRef,
|
|
8617
|
+
"agent_turn_delta",
|
|
8618
|
+
{
|
|
8619
|
+
contentType: event.contentType,
|
|
8620
|
+
delta: event.delta,
|
|
8621
|
+
deltaLength: event.delta.length
|
|
8622
|
+
},
|
|
8623
|
+
eventWriterRef
|
|
8624
|
+
);
|
|
8442
8625
|
setState((prev) => ({
|
|
8443
8626
|
...prev,
|
|
8444
8627
|
...event.contentType === "text" ? {
|
|
@@ -8446,29 +8629,70 @@ function useMarathonStream() {
|
|
|
8446
8629
|
content: appendTranscriptText(prev.content, event.delta, prev.lastTranscriptKind),
|
|
8447
8630
|
lastTranscriptKind: "text",
|
|
8448
8631
|
thinkingStartedAt: null
|
|
8632
|
+
} : event.contentType === "tool_input" ? {
|
|
8633
|
+
phase: "tool",
|
|
8634
|
+
thinkingStartedAt: null
|
|
8449
8635
|
} : {
|
|
8450
8636
|
phase: "thinking",
|
|
8451
8637
|
reasoning: prev.reasoning + event.delta,
|
|
8452
8638
|
thinkingStartedAt: prev.thinkingStartedAt ?? Date.now()
|
|
8453
|
-
}
|
|
8454
|
-
rawEvents: pushRawEvent(prev, "agent_turn_delta", {
|
|
8455
|
-
contentType: event.contentType,
|
|
8456
|
-
delta: event.delta,
|
|
8457
|
-
deltaLength: event.delta.length
|
|
8458
|
-
}, eventWriterRef)
|
|
8639
|
+
}
|
|
8459
8640
|
}));
|
|
8460
8641
|
},
|
|
8461
8642
|
onTurnComplete(event) {
|
|
8643
|
+
pushRawEvent(rawEventsRef, "agent_turn_complete", { ...event }, eventWriterRef);
|
|
8462
8644
|
setState((prev) => ({
|
|
8463
8645
|
...prev,
|
|
8464
|
-
totalCost: event.cost != null ? prev.totalCost + event.cost : prev.totalCost
|
|
8465
|
-
rawEvents: pushRawEvent(prev, "agent_turn_complete", { ...event }, eventWriterRef)
|
|
8646
|
+
totalCost: event.cost != null ? prev.totalCost + event.cost : prev.totalCost
|
|
8466
8647
|
}));
|
|
8467
8648
|
},
|
|
8468
8649
|
onToolStart(event) {
|
|
8469
|
-
const
|
|
8650
|
+
const { parameters: _params, ...listData } = event;
|
|
8651
|
+
pushRawEvent(rawEventsRef, "agent_tool_start", { ...event }, eventWriterRef, listData);
|
|
8470
8652
|
setState((prev) => {
|
|
8653
|
+
const existingIndex = prev.tools.findIndex(
|
|
8654
|
+
(tool) => tool.sourceToolCallId === event.toolCallId && tool.status === "running"
|
|
8655
|
+
);
|
|
8656
|
+
const nextPhase = event.parameters ? "executing" : "input_streaming";
|
|
8657
|
+
if (existingIndex >= 0) {
|
|
8658
|
+
const tools = prev.tools.map((tool, index) => {
|
|
8659
|
+
if (index !== existingIndex) return tool;
|
|
8660
|
+
const hydratedTool = hydrateToolEntry(tool);
|
|
8661
|
+
const parameters = event.parameters ?? hydratedTool.parameters;
|
|
8662
|
+
const streamedInput = hydratedTool.streamedInput;
|
|
8663
|
+
const inlineParameters2 = parameters && shouldKeepToolPayloadInline(event.toolName, parameters) ? parameters : void 0;
|
|
8664
|
+
setStoredToolPayloadField(
|
|
8665
|
+
toolPayloadsRef.current,
|
|
8666
|
+
tool.id,
|
|
8667
|
+
"parameters",
|
|
8668
|
+
inlineParameters2 ? void 0 : parameters
|
|
8669
|
+
);
|
|
8670
|
+
return {
|
|
8671
|
+
...tool,
|
|
8672
|
+
name: event.toolName,
|
|
8673
|
+
toolType: event.toolType,
|
|
8674
|
+
parameters: inlineParameters2,
|
|
8675
|
+
phase: nextPhase,
|
|
8676
|
+
inputPreview: buildToolPreview({ streamedInput, parameters, existingPreview: tool.inputPreview })
|
|
8677
|
+
};
|
|
8678
|
+
});
|
|
8679
|
+
return {
|
|
8680
|
+
...prev,
|
|
8681
|
+
phase: "tool",
|
|
8682
|
+
thinkingStartedAt: null,
|
|
8683
|
+
tools
|
|
8684
|
+
};
|
|
8685
|
+
}
|
|
8686
|
+
const uniqueId = `tool-${++toolCounter}`;
|
|
8471
8687
|
const sequence = prev.tools.length + 1;
|
|
8688
|
+
const inputPreview = buildToolPreview({ parameters: event.parameters });
|
|
8689
|
+
const inlineParameters = event.parameters && shouldKeepToolPayloadInline(event.toolName, event.parameters) ? event.parameters : void 0;
|
|
8690
|
+
setStoredToolPayloadField(
|
|
8691
|
+
toolPayloadsRef.current,
|
|
8692
|
+
uniqueId,
|
|
8693
|
+
"parameters",
|
|
8694
|
+
inlineParameters ? void 0 : event.parameters
|
|
8695
|
+
);
|
|
8472
8696
|
return {
|
|
8473
8697
|
...prev,
|
|
8474
8698
|
phase: "tool",
|
|
@@ -8484,25 +8708,104 @@ function useMarathonStream() {
|
|
|
8484
8708
|
name: event.toolName,
|
|
8485
8709
|
toolType: event.toolType,
|
|
8486
8710
|
status: "running",
|
|
8487
|
-
|
|
8711
|
+
phase: nextPhase,
|
|
8712
|
+
parameters: inlineParameters,
|
|
8713
|
+
inputPreview,
|
|
8488
8714
|
startedAt: Date.now()
|
|
8489
8715
|
}
|
|
8490
|
-
]
|
|
8491
|
-
|
|
8716
|
+
]
|
|
8717
|
+
};
|
|
8718
|
+
});
|
|
8719
|
+
},
|
|
8720
|
+
onToolInputDelta(event) {
|
|
8721
|
+
pushRawEvent(rawEventsRef, "agent_tool_input_delta", { ...event }, eventWriterRef);
|
|
8722
|
+
setState((prev) => {
|
|
8723
|
+
let matched = false;
|
|
8724
|
+
const tools = prev.tools.map((tool) => {
|
|
8725
|
+
if (matched || tool.sourceToolCallId !== event.toolCallId || tool.status !== "running") {
|
|
8726
|
+
return tool;
|
|
8727
|
+
}
|
|
8728
|
+
matched = true;
|
|
8729
|
+
const hydratedTool = hydrateToolEntry(tool);
|
|
8730
|
+
const streamedInput = `${hydratedTool.streamedInput || ""}${event.delta || ""}`;
|
|
8731
|
+
const inlineStreamedInput = shouldKeepToolPayloadInline(tool.name, streamedInput) ? streamedInput : void 0;
|
|
8732
|
+
setStoredToolPayloadField(
|
|
8733
|
+
toolPayloadsRef.current,
|
|
8734
|
+
tool.id,
|
|
8735
|
+
"streamedInput",
|
|
8736
|
+
inlineStreamedInput ? void 0 : streamedInput
|
|
8737
|
+
);
|
|
8738
|
+
return {
|
|
8739
|
+
...tool,
|
|
8740
|
+
phase: "input_streaming",
|
|
8741
|
+
streamedInput: inlineStreamedInput,
|
|
8742
|
+
inputPreview: buildToolPreview({ streamedInput, parameters: hydratedTool.parameters, existingPreview: tool.inputPreview })
|
|
8743
|
+
};
|
|
8744
|
+
});
|
|
8745
|
+
return {
|
|
8746
|
+
...prev,
|
|
8747
|
+
phase: "tool",
|
|
8748
|
+
thinkingStartedAt: null,
|
|
8749
|
+
tools
|
|
8750
|
+
};
|
|
8751
|
+
});
|
|
8752
|
+
},
|
|
8753
|
+
onToolInputComplete(event) {
|
|
8754
|
+
pushRawEvent(rawEventsRef, "agent_tool_input_complete", { ...event }, eventWriterRef);
|
|
8755
|
+
setState((prev) => {
|
|
8756
|
+
let matched = false;
|
|
8757
|
+
const tools = prev.tools.map((tool) => {
|
|
8758
|
+
if (matched || tool.sourceToolCallId !== event.toolCallId || tool.status !== "running") {
|
|
8759
|
+
return tool;
|
|
8760
|
+
}
|
|
8761
|
+
matched = true;
|
|
8762
|
+
const parameters = event.parameters;
|
|
8763
|
+
const inlineParameters = parameters && shouldKeepToolPayloadInline(tool.name, parameters) ? parameters : void 0;
|
|
8764
|
+
setStoredToolPayloadField(
|
|
8765
|
+
toolPayloadsRef.current,
|
|
8766
|
+
tool.id,
|
|
8767
|
+
"parameters",
|
|
8768
|
+
inlineParameters ? void 0 : parameters
|
|
8769
|
+
);
|
|
8770
|
+
return {
|
|
8771
|
+
...tool,
|
|
8772
|
+
phase: "executing",
|
|
8773
|
+
parameters: inlineParameters,
|
|
8774
|
+
inputPreview: buildToolPreview({ streamedInput: hydrateToolEntry(tool).streamedInput, parameters, existingPreview: tool.inputPreview })
|
|
8775
|
+
};
|
|
8776
|
+
});
|
|
8777
|
+
return {
|
|
8778
|
+
...prev,
|
|
8779
|
+
phase: "tool",
|
|
8780
|
+
thinkingStartedAt: null,
|
|
8781
|
+
tools
|
|
8492
8782
|
};
|
|
8493
8783
|
});
|
|
8494
8784
|
},
|
|
8785
|
+
onToolDelta(event) {
|
|
8786
|
+
pushRawEvent(rawEventsRef, "agent_tool_delta", { ...event }, eventWriterRef);
|
|
8787
|
+
},
|
|
8495
8788
|
onToolComplete(event) {
|
|
8789
|
+
const { result: _result, ...listData } = event;
|
|
8790
|
+
pushRawEvent(rawEventsRef, "agent_tool_complete", { ...event }, eventWriterRef, listData);
|
|
8496
8791
|
setState((prev) => {
|
|
8497
8792
|
let matched = false;
|
|
8498
8793
|
const tools = prev.tools.map((t) => {
|
|
8499
8794
|
if (!matched && t.sourceToolCallId === event.toolCallId && t.status === "running") {
|
|
8500
8795
|
matched = true;
|
|
8796
|
+
const inlineResult = shouldKeepToolPayloadInline(t.name, event.result) ? event.result : void 0;
|
|
8797
|
+
setStoredToolPayloadField(
|
|
8798
|
+
toolPayloadsRef.current,
|
|
8799
|
+
t.id,
|
|
8800
|
+
"result",
|
|
8801
|
+
inlineResult === void 0 ? event.result : void 0
|
|
8802
|
+
);
|
|
8501
8803
|
return {
|
|
8502
8804
|
...t,
|
|
8503
8805
|
status: event.success ? "complete" : "error",
|
|
8806
|
+
phase: "executing",
|
|
8504
8807
|
executionTime: event.executionTime,
|
|
8505
|
-
result:
|
|
8808
|
+
result: inlineResult
|
|
8506
8809
|
};
|
|
8507
8810
|
}
|
|
8508
8811
|
return t;
|
|
@@ -8510,19 +8813,18 @@ function useMarathonStream() {
|
|
|
8510
8813
|
return {
|
|
8511
8814
|
...prev,
|
|
8512
8815
|
phase: "streaming",
|
|
8513
|
-
tools
|
|
8514
|
-
rawEvents: pushRawEvent(prev, "agent_tool_complete", { ...event }, eventWriterRef)
|
|
8816
|
+
tools
|
|
8515
8817
|
};
|
|
8516
8818
|
});
|
|
8517
8819
|
},
|
|
8518
8820
|
onIterationComplete(event) {
|
|
8821
|
+
pushRawEvent(rawEventsRef, "agent_iteration_complete", { ...event }, eventWriterRef);
|
|
8519
8822
|
setState((prev) => ({
|
|
8520
8823
|
...prev,
|
|
8521
8824
|
totalCost: event.cost != null ? prev.totalCost + event.cost : prev.totalCost,
|
|
8522
8825
|
totalInputTokens: prev.totalInputTokens + (event.tokens?.input ?? 0),
|
|
8523
8826
|
totalOutputTokens: prev.totalOutputTokens + (event.tokens?.output ?? 0),
|
|
8524
|
-
sessionCount: prev.sessionCount + 1
|
|
8525
|
-
rawEvents: pushRawEvent(prev, "agent_iteration_complete", { ...event }, eventWriterRef)
|
|
8827
|
+
sessionCount: prev.sessionCount + 1
|
|
8526
8828
|
}));
|
|
8527
8829
|
},
|
|
8528
8830
|
onAgentPaused(event) {
|
|
@@ -8536,6 +8838,8 @@ function useMarathonStream() {
|
|
|
8536
8838
|
} catch {
|
|
8537
8839
|
}
|
|
8538
8840
|
}
|
|
8841
|
+
const { parameters: _awaitParamsRaw, ...awaitListData } = event;
|
|
8842
|
+
pushRawEvent(rawEventsRef, "agent_await", { ...event }, eventWriterRef, awaitListData);
|
|
8539
8843
|
setState((prev) => ({
|
|
8540
8844
|
...prev,
|
|
8541
8845
|
phase: "tool",
|
|
@@ -8544,48 +8848,140 @@ function useMarathonStream() {
|
|
|
8544
8848
|
if (t.status !== "running") return t;
|
|
8545
8849
|
const isMatch = !event.toolId || t.sourceToolCallId === event.toolId || event.toolName != null && t.name === event.toolName;
|
|
8546
8850
|
if (!isMatch) return t;
|
|
8851
|
+
const hydratedTool = hydrateToolEntry(t);
|
|
8852
|
+
const parameters = awaitParams ?? hydratedTool.parameters;
|
|
8853
|
+
const streamedInput = hydratedTool.streamedInput;
|
|
8854
|
+
const inlineParameters = parameters && shouldKeepToolPayloadInline(t.name, parameters) ? parameters : void 0;
|
|
8855
|
+
setStoredToolPayloadField(
|
|
8856
|
+
toolPayloadsRef.current,
|
|
8857
|
+
t.id,
|
|
8858
|
+
"parameters",
|
|
8859
|
+
inlineParameters ? void 0 : parameters
|
|
8860
|
+
);
|
|
8547
8861
|
return {
|
|
8548
8862
|
...t,
|
|
8549
|
-
|
|
8550
|
-
|
|
8551
|
-
|
|
8552
|
-
|
|
8863
|
+
localToolCallId: event.toolId,
|
|
8864
|
+
phase: "executing_locally",
|
|
8865
|
+
localExecutionStartedAt: Date.now(),
|
|
8866
|
+
parameters: inlineParameters,
|
|
8867
|
+
inputPreview: buildToolPreview({
|
|
8868
|
+
streamedInput,
|
|
8869
|
+
parameters,
|
|
8870
|
+
existingPreview: t.inputPreview
|
|
8871
|
+
})
|
|
8872
|
+
};
|
|
8873
|
+
})
|
|
8874
|
+
}));
|
|
8875
|
+
},
|
|
8876
|
+
onLocalToolExecutionStart(event) {
|
|
8877
|
+
const { parameters: _params, ...listData } = event;
|
|
8878
|
+
pushRawEvent(rawEventsRef, "local_tool_execution_start", { ...event }, eventWriterRef, listData);
|
|
8879
|
+
setState((prev) => ({
|
|
8880
|
+
...prev,
|
|
8881
|
+
phase: "tool",
|
|
8882
|
+
thinkingStartedAt: null,
|
|
8883
|
+
tools: prev.tools.map((tool) => {
|
|
8884
|
+
const isMatch = tool.status === "running" && (tool.localToolCallId === event.toolCallId || tool.sourceToolCallId === event.toolCallId || tool.name === event.toolName);
|
|
8885
|
+
if (!isMatch) return tool;
|
|
8886
|
+
const inlineParameters = event.parameters && shouldKeepToolPayloadInline(tool.name, event.parameters) ? event.parameters : void 0;
|
|
8887
|
+
setStoredToolPayloadField(
|
|
8888
|
+
toolPayloadsRef.current,
|
|
8889
|
+
tool.id,
|
|
8890
|
+
"parameters",
|
|
8891
|
+
inlineParameters ? void 0 : event.parameters
|
|
8892
|
+
);
|
|
8893
|
+
return {
|
|
8894
|
+
...tool,
|
|
8895
|
+
localToolCallId: event.toolCallId,
|
|
8896
|
+
phase: "executing_locally",
|
|
8897
|
+
localExecutionStartedAt: Date.parse(event.startedAt) || Date.now(),
|
|
8898
|
+
parameters: inlineParameters,
|
|
8899
|
+
inputPreview: buildToolPreview({
|
|
8900
|
+
streamedInput: hydrateToolEntry(tool).streamedInput,
|
|
8901
|
+
parameters: event.parameters,
|
|
8902
|
+
existingPreview: tool.inputPreview
|
|
8903
|
+
})
|
|
8904
|
+
};
|
|
8905
|
+
})
|
|
8906
|
+
}));
|
|
8907
|
+
},
|
|
8908
|
+
onLocalToolExecutionComplete(event) {
|
|
8909
|
+
const { result: _result, parameters: _params, ...listData } = event;
|
|
8910
|
+
pushRawEvent(rawEventsRef, "local_tool_execution_complete", { ...event }, eventWriterRef, listData);
|
|
8911
|
+
setState((prev) => ({
|
|
8912
|
+
...prev,
|
|
8913
|
+
tools: prev.tools.map((tool) => {
|
|
8914
|
+
const isMatch = tool.status === "running" && (tool.localToolCallId === event.toolCallId || tool.sourceToolCallId === event.toolCallId || tool.name === event.toolName);
|
|
8915
|
+
if (!isMatch) return tool;
|
|
8916
|
+
const inlineParameters = event.parameters && shouldKeepToolPayloadInline(tool.name, event.parameters) ? event.parameters : void 0;
|
|
8917
|
+
const inlineResult = shouldKeepToolPayloadInline(tool.name, event.result) ? event.result : void 0;
|
|
8918
|
+
setStoredToolPayloadField(
|
|
8919
|
+
toolPayloadsRef.current,
|
|
8920
|
+
tool.id,
|
|
8921
|
+
"parameters",
|
|
8922
|
+
inlineParameters ? void 0 : event.parameters
|
|
8923
|
+
);
|
|
8924
|
+
setStoredToolPayloadField(
|
|
8925
|
+
toolPayloadsRef.current,
|
|
8926
|
+
tool.id,
|
|
8927
|
+
"result",
|
|
8928
|
+
inlineResult === void 0 ? event.result : void 0
|
|
8929
|
+
);
|
|
8930
|
+
return {
|
|
8931
|
+
...tool,
|
|
8932
|
+
status: event.success ? "complete" : "error",
|
|
8933
|
+
phase: "executing",
|
|
8934
|
+
parameters: inlineParameters,
|
|
8935
|
+
result: inlineResult,
|
|
8936
|
+
executionTime: event.durationMs
|
|
8553
8937
|
};
|
|
8554
|
-
})
|
|
8555
|
-
rawEvents: pushRawEvent(prev, "agent_await", { ...event }, eventWriterRef)
|
|
8938
|
+
})
|
|
8556
8939
|
}));
|
|
8557
8940
|
},
|
|
8558
8941
|
onAgentComplete(event) {
|
|
8942
|
+
const { finalOutput: _output, ...listData } = event;
|
|
8943
|
+
pushRawEvent(rawEventsRef, "agent_complete", { ...event }, eventWriterRef, listData);
|
|
8559
8944
|
setState((prev) => ({
|
|
8560
8945
|
...prev,
|
|
8561
8946
|
phase: "complete",
|
|
8562
8947
|
content: prev.content || event.finalOutput || "",
|
|
8563
|
-
//
|
|
8948
|
+
// If any running local tools remain, close them out using the best
|
|
8949
|
+
// duration we have available from local execution state.
|
|
8564
8950
|
tools: prev.tools.map(
|
|
8565
|
-
(t) => t.status === "running" ? {
|
|
8951
|
+
(t) => t.status === "running" ? {
|
|
8952
|
+
...t,
|
|
8953
|
+
status: "complete",
|
|
8954
|
+
executionTime: Date.now() - (t.localExecutionStartedAt ?? t.startedAt)
|
|
8955
|
+
} : t
|
|
8566
8956
|
),
|
|
8567
8957
|
totalCost: event.totalCost != null ? event.totalCost : prev.totalCost,
|
|
8568
8958
|
totalInputTokens: event.totalTokens?.input ?? prev.totalInputTokens,
|
|
8569
|
-
totalOutputTokens: event.totalTokens?.output ?? prev.totalOutputTokens
|
|
8570
|
-
rawEvents: pushRawEvent(prev, "agent_complete", { ...event }, eventWriterRef)
|
|
8959
|
+
totalOutputTokens: event.totalTokens?.output ?? prev.totalOutputTokens
|
|
8571
8960
|
}));
|
|
8572
8961
|
},
|
|
8573
8962
|
onError(event) {
|
|
8963
|
+
pushRawEvent(rawEventsRef, "agent_error", { ...event }, eventWriterRef);
|
|
8574
8964
|
setState((prev) => ({
|
|
8575
8965
|
...prev,
|
|
8576
8966
|
phase: "error",
|
|
8577
8967
|
error: new Error(event.error.message),
|
|
8578
8968
|
// Mark any still-running tools as errored so spinners stop
|
|
8579
8969
|
tools: prev.tools.map(
|
|
8580
|
-
(t) => t.status === "running" ? {
|
|
8581
|
-
|
|
8582
|
-
|
|
8970
|
+
(t) => t.status === "running" ? {
|
|
8971
|
+
...t,
|
|
8972
|
+
status: "error",
|
|
8973
|
+
executionTime: Date.now() - (t.localExecutionStartedAt ?? t.startedAt)
|
|
8974
|
+
} : t
|
|
8975
|
+
)
|
|
8583
8976
|
}));
|
|
8584
8977
|
}
|
|
8585
8978
|
}),
|
|
8586
8979
|
[]
|
|
8980
|
+
// rawEventsRef and eventWriterRef are stable refs — safe to omit
|
|
8587
8981
|
);
|
|
8588
8982
|
const reset = useCallback2(() => {
|
|
8983
|
+
rawEventsRef.current = [];
|
|
8984
|
+
toolPayloadsRef.current.clear();
|
|
8589
8985
|
setState(INITIAL_STATE);
|
|
8590
8986
|
}, []);
|
|
8591
8987
|
const setCheckpoint = useCallback2(() => {
|
|
@@ -8600,6 +8996,7 @@ function useMarathonStream() {
|
|
|
8600
8996
|
}));
|
|
8601
8997
|
}, []);
|
|
8602
8998
|
const startContextCompaction = useCallback2((event) => {
|
|
8999
|
+
pushRawEvent(rawEventsRef, "marathon_context_compaction_start", { ...event }, eventWriterRef);
|
|
8603
9000
|
setState((prev) => ({
|
|
8604
9001
|
...prev,
|
|
8605
9002
|
contextCompaction: {
|
|
@@ -8617,28 +9014,28 @@ function useMarathonStream() {
|
|
|
8617
9014
|
afterTokens: event.afterTokens,
|
|
8618
9015
|
breakdown: event.breakdown,
|
|
8619
9016
|
startedAt: Date.now()
|
|
8620
|
-
}
|
|
8621
|
-
rawEvents: pushRawEvent(prev, "marathon_context_compaction_start", { ...event }, eventWriterRef)
|
|
9017
|
+
}
|
|
8622
9018
|
}));
|
|
8623
9019
|
}, []);
|
|
8624
9020
|
const finishContextCompaction = useCallback2((event) => {
|
|
9021
|
+
pushRawEvent(rawEventsRef, "marathon_context_compaction_complete", { ...event }, eventWriterRef);
|
|
8625
9022
|
setState((prev) => ({
|
|
8626
9023
|
...prev,
|
|
8627
9024
|
contextCompaction: null,
|
|
8628
9025
|
content: appendContentLine(prev.content, formatContextCompactionCompleteLine(event)),
|
|
8629
|
-
lastTranscriptKind: "text"
|
|
8630
|
-
rawEvents: pushRawEvent(prev, "marathon_context_compaction_complete", { ...event }, eventWriterRef)
|
|
9026
|
+
lastTranscriptKind: "text"
|
|
8631
9027
|
}));
|
|
8632
9028
|
}, []);
|
|
8633
9029
|
const reportContextNotice = useCallback2((event) => {
|
|
9030
|
+
pushRawEvent(rawEventsRef, "marathon_context_notice", { ...event }, eventWriterRef);
|
|
8634
9031
|
setState((prev) => ({
|
|
8635
9032
|
...prev,
|
|
8636
9033
|
content: appendContentLine(prev.content, formatContextNoticeLine(event)),
|
|
8637
|
-
lastTranscriptKind: "text"
|
|
8638
|
-
rawEvents: pushRawEvent(prev, "marathon_context_notice", { ...event }, eventWriterRef)
|
|
9034
|
+
lastTranscriptKind: "text"
|
|
8639
9035
|
}));
|
|
8640
9036
|
}, []);
|
|
8641
9037
|
const resetForNewSession = useCallback2(() => {
|
|
9038
|
+
toolPayloadsRef.current.clear();
|
|
8642
9039
|
setState((prev) => ({
|
|
8643
9040
|
...prev,
|
|
8644
9041
|
phase: "idle",
|
|
@@ -8653,11 +9050,11 @@ function useMarathonStream() {
|
|
|
8653
9050
|
}));
|
|
8654
9051
|
}, []);
|
|
8655
9052
|
const showError = useCallback2((error) => {
|
|
9053
|
+
pushRawEvent(rawEventsRef, "agent_error", { message: error.message }, eventWriterRef);
|
|
8656
9054
|
setState((prev) => ({
|
|
8657
9055
|
...prev,
|
|
8658
9056
|
phase: "error",
|
|
8659
|
-
error
|
|
8660
|
-
rawEvents: pushRawEvent(prev, "agent_error", { message: error.message }, eventWriterRef)
|
|
9057
|
+
error
|
|
8661
9058
|
}));
|
|
8662
9059
|
}, []);
|
|
8663
9060
|
const setEventWriter = useCallback2((writer) => {
|
|
@@ -8665,7 +9062,10 @@ function useMarathonStream() {
|
|
|
8665
9062
|
}, []);
|
|
8666
9063
|
return {
|
|
8667
9064
|
state,
|
|
9065
|
+
rawEventsRef,
|
|
8668
9066
|
callbacks,
|
|
9067
|
+
getHydratedState,
|
|
9068
|
+
hydrateToolEntry,
|
|
8669
9069
|
reset,
|
|
8670
9070
|
setCheckpoint,
|
|
8671
9071
|
markPendingStart,
|
|
@@ -9083,189 +9483,76 @@ function ScreenTabs({ activeTab, width, shortcutHint }) {
|
|
|
9083
9483
|
] });
|
|
9084
9484
|
}
|
|
9085
9485
|
|
|
9086
|
-
// src/ink/marathon/
|
|
9087
|
-
import { useState as useState12, useEffect as useEffect12 } from "react";
|
|
9088
|
-
import {
|
|
9486
|
+
// src/ink/marathon/ToolsPanel.tsx
|
|
9487
|
+
import { useState as useState12, useEffect as useEffect12, useMemo as useMemo2, memo } from "react";
|
|
9488
|
+
import { Box as Box11, Text as Text12 } from "ink";
|
|
9489
|
+
import { Spinner as Spinner4, theme as theme13 } from "@runtypelabs/ink-components";
|
|
9490
|
+
|
|
9491
|
+
// src/ink/marathon/Scrollbar.tsx
|
|
9492
|
+
import { Box as Box10, Text as Text11 } from "ink";
|
|
9493
|
+
import { theme as theme12 } from "@runtypelabs/ink-components";
|
|
9089
9494
|
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
9090
|
-
function
|
|
9091
|
-
|
|
9092
|
-
|
|
9093
|
-
);
|
|
9094
|
-
|
|
9095
|
-
|
|
9096
|
-
|
|
9097
|
-
const
|
|
9098
|
-
|
|
9099
|
-
|
|
9100
|
-
return () => clearInterval(interval);
|
|
9101
|
-
}, [startedAt]);
|
|
9102
|
-
return /* @__PURE__ */ jsx11(Spinner4, { label: `Thinking... ${elapsed}s`, color: theme12.textMuted });
|
|
9495
|
+
function Scrollbar({ totalLines, visibleLines, scrollOffset, height }) {
|
|
9496
|
+
if (totalLines <= visibleLines) return null;
|
|
9497
|
+
const maxScroll = Math.max(0, totalLines - visibleLines);
|
|
9498
|
+
const clampedOffset = Math.min(scrollOffset, maxScroll);
|
|
9499
|
+
const thumbSize = Math.max(1, Math.round(visibleLines / totalLines * height));
|
|
9500
|
+
const thumbStart = maxScroll > 0 ? Math.round(clampedOffset / maxScroll * (height - thumbSize)) : 0;
|
|
9501
|
+
return /* @__PURE__ */ jsx11(Box10, { flexDirection: "column", marginLeft: 1, children: Array.from({ length: height }, (_, i) => {
|
|
9502
|
+
const isThumb = i >= thumbStart && i < thumbStart + thumbSize;
|
|
9503
|
+
return /* @__PURE__ */ jsx11(Text11, { color: isThumb ? theme12.textMuted : theme12.border, children: isThumb ? "\u2588" : "\u2502" }, i);
|
|
9504
|
+
}) });
|
|
9103
9505
|
}
|
|
9104
9506
|
|
|
9105
|
-
// src/ink/marathon/
|
|
9106
|
-
import {
|
|
9107
|
-
|
|
9108
|
-
|
|
9109
|
-
|
|
9110
|
-
|
|
9111
|
-
|
|
9112
|
-
|
|
9113
|
-
|
|
9114
|
-
|
|
9115
|
-
}
|
|
9116
|
-
|
|
9117
|
-
|
|
9118
|
-
|
|
9119
|
-
|
|
9120
|
-
|
|
9121
|
-
|
|
9122
|
-
|
|
9123
|
-
)
|
|
9124
|
-
|
|
9125
|
-
|
|
9126
|
-
|
|
9127
|
-
const
|
|
9128
|
-
|
|
9129
|
-
|
|
9130
|
-
|
|
9131
|
-
}, [compaction.startedAt]);
|
|
9132
|
-
return /* @__PURE__ */ jsx12(Spinner5, { label: buildCompactionLabel(compaction, elapsed), color: theme13.warning });
|
|
9507
|
+
// src/ink/marathon/ToolsPanel.tsx
|
|
9508
|
+
import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
9509
|
+
function getVisibleToolWindow(total, selectedIndex, maxVisibleLines) {
|
|
9510
|
+
const toolSlots = Math.floor(maxVisibleLines / 2);
|
|
9511
|
+
const half = Math.floor(toolSlots / 2);
|
|
9512
|
+
let start = selectedIndex - half;
|
|
9513
|
+
let end = start + toolSlots;
|
|
9514
|
+
if (start < 0) {
|
|
9515
|
+
start = 0;
|
|
9516
|
+
end = Math.min(total, toolSlots);
|
|
9517
|
+
}
|
|
9518
|
+
if (end > total) {
|
|
9519
|
+
end = total;
|
|
9520
|
+
start = Math.max(0, end - toolSlots);
|
|
9521
|
+
}
|
|
9522
|
+
return { start, end };
|
|
9523
|
+
}
|
|
9524
|
+
function visibleToolsFingerprint(tools, selectedIndex, maxVisibleLines) {
|
|
9525
|
+
if (tools.length === 0) return `0:${selectedIndex}:${maxVisibleLines}`;
|
|
9526
|
+
const { start, end } = getVisibleToolWindow(tools.length, selectedIndex, maxVisibleLines);
|
|
9527
|
+
let fp = `${tools.length}:${selectedIndex}:${maxVisibleLines}:${start}:${end}`;
|
|
9528
|
+
for (let i = start; i < end; i++) {
|
|
9529
|
+
const tool = tools[i];
|
|
9530
|
+
fp += `|${tool.id}:${tool.name}:${tool.status}:${tool.phase ?? ""}:${tool.inputPreview ?? ""}:${tool.executionTime ?? ""}:${tool.startedAt}:${tool.localExecutionStartedAt ?? ""}`;
|
|
9531
|
+
}
|
|
9532
|
+
return fp;
|
|
9133
9533
|
}
|
|
9134
|
-
|
|
9135
|
-
|
|
9136
|
-
|
|
9137
|
-
import { Box as Box10, Text as Text11 } from "ink";
|
|
9138
|
-
import { Spinner as Spinner6, theme as theme14 } from "@runtypelabs/ink-components";
|
|
9139
|
-
import { Fragment, jsx as jsx13, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
9140
|
-
function formatCharCount(chars) {
|
|
9141
|
-
if (chars >= 1e3) {
|
|
9142
|
-
return `${(chars / 1e3).toFixed(1)}k chars`;
|
|
9534
|
+
function formatElapsed(tool, now) {
|
|
9535
|
+
if (tool.executionTime != null) {
|
|
9536
|
+
return `${(tool.executionTime / 1e3).toFixed(1)}s`;
|
|
9143
9537
|
}
|
|
9144
|
-
|
|
9538
|
+
const startedAt = tool.localExecutionStartedAt ?? tool.startedAt;
|
|
9539
|
+
return `${((now - startedAt) / 1e3).toFixed(1)}s`;
|
|
9145
9540
|
}
|
|
9146
9541
|
var STATUS_ICONS = {
|
|
9147
9542
|
complete: "\u2713",
|
|
9148
9543
|
error: "\u2717"
|
|
9149
9544
|
};
|
|
9150
|
-
var FILE_TYPE_ICONS = {
|
|
9151
|
-
written: "\u270E",
|
|
9152
|
-
read: "\u2022",
|
|
9153
|
-
plan: "\u2691"
|
|
9154
|
-
};
|
|
9155
|
-
function formatElapsed(tool, now) {
|
|
9156
|
-
if (tool.executionTime != null) {
|
|
9157
|
-
return `${(tool.executionTime / 1e3).toFixed(1)}s`;
|
|
9158
|
-
}
|
|
9159
|
-
return `${((now - tool.startedAt) / 1e3).toFixed(1)}s`;
|
|
9160
|
-
}
|
|
9161
9545
|
function getStatusColor(status) {
|
|
9162
|
-
if (status === "error") return
|
|
9163
|
-
if (status === "complete") return
|
|
9164
|
-
return
|
|
9546
|
+
if (status === "error") return theme13.danger;
|
|
9547
|
+
if (status === "complete") return theme13.success;
|
|
9548
|
+
return theme13.accent;
|
|
9165
9549
|
}
|
|
9166
|
-
function
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
|
|
9170
|
-
|
|
9171
|
-
|
|
9172
|
-
return () => clearInterval(interval);
|
|
9173
|
-
}, [hasRunning]);
|
|
9174
|
-
const { visibleTools, visibleFiles } = useMemo2(() => {
|
|
9175
|
-
if (!maxHeight) return { visibleTools: tools, visibleFiles: files || [] };
|
|
9176
|
-
const reasoningRows = reasoning && reasoning.length > 0 ? 1 : 0;
|
|
9177
|
-
const headerRows = 1;
|
|
9178
|
-
const filesList = files || [];
|
|
9179
|
-
const fileHeaderRows = filesList.length > 0 ? 2 : 0;
|
|
9180
|
-
const availableRows = maxHeight - headerRows - reasoningRows - fileHeaderRows;
|
|
9181
|
-
const fileRows = filesList.length > 0 ? Math.min(filesList.length, Math.max(3, Math.floor(availableRows * 0.3))) : 0;
|
|
9182
|
-
const toolRows = Math.max(1, availableRows - fileRows);
|
|
9183
|
-
const vTools = tools.length <= toolRows ? tools : tools.slice(-toolRows);
|
|
9184
|
-
const vFiles = filesList.length <= fileRows ? filesList : filesList.slice(-fileRows);
|
|
9185
|
-
return { visibleTools: vTools, visibleFiles: vFiles };
|
|
9186
|
-
}, [tools, files, maxHeight, reasoning]);
|
|
9187
|
-
const hiddenToolCount = tools.length - visibleTools.length;
|
|
9188
|
-
const hiddenFileCount = (files || []).length - visibleFiles.length;
|
|
9189
|
-
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "column", backgroundColor: theme14.background, children: [
|
|
9190
|
-
/* @__PURE__ */ jsx13(Text11, { bold: true, color: theme14.accent, children: "Activity" }),
|
|
9191
|
-
reasoning && reasoning.length > 0 && /* @__PURE__ */ jsxs10(Text11, { color: theme14.textMuted, children: [
|
|
9192
|
-
"Reasoning: ",
|
|
9193
|
-
formatCharCount(reasoning.length)
|
|
9194
|
-
] }),
|
|
9195
|
-
hiddenToolCount > 0 && /* @__PURE__ */ jsxs10(Text11, { color: theme14.textSubtle, children: [
|
|
9196
|
-
" ",
|
|
9197
|
-
hiddenToolCount,
|
|
9198
|
-
" earlier hidden"
|
|
9199
|
-
] }),
|
|
9200
|
-
visibleTools.map((tool) => {
|
|
9201
|
-
const statusColor = getStatusColor(tool.status);
|
|
9202
|
-
const elapsed = formatElapsed(tool, now);
|
|
9203
|
-
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9204
|
-
/* @__PURE__ */ jsx13(Box10, { width: 2, flexShrink: 0, children: tool.status === "running" ? /* @__PURE__ */ jsx13(Spinner6, { label: "", color: theme14.spinner }) : /* @__PURE__ */ jsx13(Text11, { color: statusColor, children: STATUS_ICONS[tool.status] || "?" }) }),
|
|
9205
|
-
/* @__PURE__ */ jsx13(Box10, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx13(Text11, { color: theme14.text, wrap: "truncate", children: tool.name }) }),
|
|
9206
|
-
/* @__PURE__ */ jsx13(Box10, { flexShrink: 0, children: /* @__PURE__ */ jsxs10(Text11, { color: theme14.textMuted, children: [
|
|
9207
|
-
" ",
|
|
9208
|
-
elapsed
|
|
9209
|
-
] }) })
|
|
9210
|
-
] }, tool.id);
|
|
9211
|
-
}),
|
|
9212
|
-
visibleFiles.length > 0 && /* @__PURE__ */ jsxs10(Fragment, { children: [
|
|
9213
|
-
/* @__PURE__ */ jsxs10(Box10, { marginTop: 1, children: [
|
|
9214
|
-
/* @__PURE__ */ jsx13(Text11, { bold: true, color: theme14.accent, children: "Files" }),
|
|
9215
|
-
hiddenFileCount > 0 && /* @__PURE__ */ jsxs10(Text11, { color: theme14.textSubtle, children: [
|
|
9216
|
-
" +",
|
|
9217
|
-
hiddenFileCount
|
|
9218
|
-
] })
|
|
9219
|
-
] }),
|
|
9220
|
-
visibleFiles.map((file) => {
|
|
9221
|
-
const icon = FILE_TYPE_ICONS[file.type] || "\u2022";
|
|
9222
|
-
const filename = file.path.split("/").pop() || file.path;
|
|
9223
|
-
return /* @__PURE__ */ jsxs10(Box10, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9224
|
-
/* @__PURE__ */ jsx13(Box10, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text11, { color: file.type === "written" ? theme14.success : theme14.textMuted, children: icon }) }),
|
|
9225
|
-
/* @__PURE__ */ jsx13(Box10, { flexShrink: 1, children: /* @__PURE__ */ jsx13(Text11, { color: theme14.text, wrap: "truncate", children: filename }) })
|
|
9226
|
-
] }, file.path);
|
|
9227
|
-
})
|
|
9228
|
-
] })
|
|
9229
|
-
] });
|
|
9230
|
-
}
|
|
9231
|
-
|
|
9232
|
-
// src/ink/marathon/ToolsPanel.tsx
|
|
9233
|
-
import { useState as useState15, useEffect as useEffect15, useMemo as useMemo3 } from "react";
|
|
9234
|
-
import { Box as Box12, Text as Text13 } from "ink";
|
|
9235
|
-
import { Spinner as Spinner7, theme as theme16 } from "@runtypelabs/ink-components";
|
|
9236
|
-
|
|
9237
|
-
// src/ink/marathon/Scrollbar.tsx
|
|
9238
|
-
import { Box as Box11, Text as Text12 } from "ink";
|
|
9239
|
-
import { theme as theme15 } from "@runtypelabs/ink-components";
|
|
9240
|
-
import { jsx as jsx14 } from "react/jsx-runtime";
|
|
9241
|
-
function Scrollbar({ totalLines, visibleLines, scrollOffset, height }) {
|
|
9242
|
-
if (totalLines <= visibleLines) return null;
|
|
9243
|
-
const maxScroll = Math.max(0, totalLines - visibleLines);
|
|
9244
|
-
const clampedOffset = Math.min(scrollOffset, maxScroll);
|
|
9245
|
-
const thumbSize = Math.max(1, Math.round(visibleLines / totalLines * height));
|
|
9246
|
-
const thumbStart = maxScroll > 0 ? Math.round(clampedOffset / maxScroll * (height - thumbSize)) : 0;
|
|
9247
|
-
return /* @__PURE__ */ jsx14(Box11, { flexDirection: "column", marginLeft: 1, children: Array.from({ length: height }, (_, i) => {
|
|
9248
|
-
const isThumb = i >= thumbStart && i < thumbStart + thumbSize;
|
|
9249
|
-
return /* @__PURE__ */ jsx14(Text12, { color: isThumb ? theme15.textMuted : theme15.border, children: isThumb ? "\u2588" : "\u2502" }, i);
|
|
9250
|
-
}) });
|
|
9251
|
-
}
|
|
9252
|
-
|
|
9253
|
-
// src/ink/marathon/ToolsPanel.tsx
|
|
9254
|
-
import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
9255
|
-
function formatElapsed2(tool, now) {
|
|
9256
|
-
if (tool.executionTime != null) {
|
|
9257
|
-
return `${(tool.executionTime / 1e3).toFixed(1)}s`;
|
|
9258
|
-
}
|
|
9259
|
-
return `${((now - tool.startedAt) / 1e3).toFixed(1)}s`;
|
|
9260
|
-
}
|
|
9261
|
-
var STATUS_ICONS2 = {
|
|
9262
|
-
complete: "\u2713",
|
|
9263
|
-
error: "\u2717"
|
|
9264
|
-
};
|
|
9265
|
-
function getStatusColor2(status) {
|
|
9266
|
-
if (status === "error") return theme16.danger;
|
|
9267
|
-
if (status === "complete") return theme16.success;
|
|
9268
|
-
return theme16.accent;
|
|
9550
|
+
function getPhaseLabel(tool) {
|
|
9551
|
+
if (tool.status === "complete") return "complete";
|
|
9552
|
+
if (tool.status === "error") return "error";
|
|
9553
|
+
if (tool.phase === "input_streaming") return "assembling input";
|
|
9554
|
+
if (tool.phase === "executing_locally") return "executing locally";
|
|
9555
|
+
return "running";
|
|
9269
9556
|
}
|
|
9270
9557
|
function wrapLines(lines, width) {
|
|
9271
9558
|
if (width <= 0) return lines;
|
|
@@ -9283,6 +9570,16 @@ function wrapLines(lines, width) {
|
|
|
9283
9570
|
}
|
|
9284
9571
|
function buildToolDetailSections(tool) {
|
|
9285
9572
|
const sections = [];
|
|
9573
|
+
sections.push(`Status: ${getPhaseLabel(tool)}`);
|
|
9574
|
+
if (tool.inputPreview) {
|
|
9575
|
+
sections.push(`Preview: ${tool.inputPreview}`);
|
|
9576
|
+
sections.push("");
|
|
9577
|
+
}
|
|
9578
|
+
if (tool.streamedInput) {
|
|
9579
|
+
sections.push("Streamed input:");
|
|
9580
|
+
sections.push(tool.streamedInput);
|
|
9581
|
+
sections.push("");
|
|
9582
|
+
}
|
|
9286
9583
|
if (tool.parameters && Object.keys(tool.parameters).length > 0) {
|
|
9287
9584
|
sections.push("Parameters:");
|
|
9288
9585
|
sections.push(JSON.stringify(tool.parameters, null, 2));
|
|
@@ -9316,57 +9613,52 @@ function ToolDetailView({
|
|
|
9316
9613
|
scrollOffset = 0,
|
|
9317
9614
|
width = 120
|
|
9318
9615
|
}) {
|
|
9319
|
-
const separator =
|
|
9320
|
-
const statusColor =
|
|
9321
|
-
const
|
|
9322
|
-
|
|
9323
|
-
|
|
9324
|
-
|
|
9325
|
-
|
|
9326
|
-
|
|
9327
|
-
return { lines: allLines.slice(start, end), totalLines: total, clampedOffset: clamped };
|
|
9328
|
-
}, [tool, maxVisibleLines, scrollOffset, width]);
|
|
9329
|
-
return /* @__PURE__ */ jsxs11(
|
|
9330
|
-
Box12,
|
|
9331
|
-
{
|
|
9332
|
-
flexDirection: "column",
|
|
9333
|
-
paddingX: theme16.panelPaddingX,
|
|
9334
|
-
paddingY: theme16.panelPaddingY,
|
|
9335
|
-
children: [
|
|
9336
|
-
/* @__PURE__ */ jsxs11(Box12, { marginBottom: theme16.sectionGap, children: [
|
|
9337
|
-
tool.status === "running" ? /* @__PURE__ */ jsx15(Spinner7, { label: "", color: theme16.spinner }) : /* @__PURE__ */ jsx15(Text13, { color: statusColor, children: STATUS_ICONS2[tool.status] || "?" }),
|
|
9338
|
-
/* @__PURE__ */ jsx15(Text13, { color: theme16.textMuted, children: ` [${tool.sequence}] ` }),
|
|
9339
|
-
/* @__PURE__ */ jsx15(Text13, { bold: true, color: theme16.text, children: tool.name }),
|
|
9340
|
-
/* @__PURE__ */ jsxs11(Text13, { color: theme16.textMuted, children: [
|
|
9341
|
-
" ",
|
|
9342
|
-
formatElapsed2(tool, now)
|
|
9343
|
-
] }),
|
|
9344
|
-
/* @__PURE__ */ jsxs11(Text13, { color: theme16.textSubtle, children: [
|
|
9345
|
-
separator,
|
|
9346
|
-
"c: copy"
|
|
9347
|
-
] }),
|
|
9348
|
-
/* @__PURE__ */ jsxs11(Text13, { color: theme16.textSubtle, children: [
|
|
9349
|
-
separator,
|
|
9350
|
-
"Esc: close"
|
|
9351
|
-
] })
|
|
9352
|
-
] }),
|
|
9353
|
-
/* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", flexGrow: 1, children: [
|
|
9354
|
-
/* @__PURE__ */ jsx15(Box12, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx15(Text13, { color: theme16.text, wrap: "truncate", children: line }, i)) }),
|
|
9355
|
-
/* @__PURE__ */ jsx15(
|
|
9356
|
-
Scrollbar,
|
|
9357
|
-
{
|
|
9358
|
-
totalLines,
|
|
9359
|
-
visibleLines: maxVisibleLines,
|
|
9360
|
-
scrollOffset: clampedOffset,
|
|
9361
|
-
height: lines.length
|
|
9362
|
-
}
|
|
9363
|
-
)
|
|
9364
|
-
] })
|
|
9365
|
-
]
|
|
9366
|
-
}
|
|
9616
|
+
const separator = theme13.separator ?? " \xB7 ";
|
|
9617
|
+
const statusColor = getStatusColor(tool.status);
|
|
9618
|
+
const allLines = useMemo2(() => getToolDetailLines(tool, width), [tool, width]);
|
|
9619
|
+
const totalLines = allLines.length;
|
|
9620
|
+
const clampedOffset = Math.min(scrollOffset, Math.max(0, totalLines - maxVisibleLines));
|
|
9621
|
+
const lines = useMemo2(
|
|
9622
|
+
() => allLines.slice(clampedOffset, clampedOffset + maxVisibleLines),
|
|
9623
|
+
[allLines, clampedOffset, maxVisibleLines]
|
|
9367
9624
|
);
|
|
9625
|
+
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", paddingX: theme13.panelPaddingX, paddingY: theme13.panelPaddingY, children: [
|
|
9626
|
+
/* @__PURE__ */ jsxs10(Box11, { marginBottom: theme13.sectionGap, children: [
|
|
9627
|
+
tool.status === "running" ? /* @__PURE__ */ jsx12(Spinner4, { label: "", color: theme13.spinner }) : /* @__PURE__ */ jsx12(Text12, { color: statusColor, children: STATUS_ICONS[tool.status] || "?" }),
|
|
9628
|
+
/* @__PURE__ */ jsx12(Text12, { color: theme13.textMuted, children: ` [${tool.sequence}] ` }),
|
|
9629
|
+
/* @__PURE__ */ jsx12(Text12, { bold: true, color: theme13.text, children: tool.name }),
|
|
9630
|
+
/* @__PURE__ */ jsxs10(Text12, { color: theme13.textMuted, children: [
|
|
9631
|
+
separator,
|
|
9632
|
+
getPhaseLabel(tool)
|
|
9633
|
+
] }),
|
|
9634
|
+
/* @__PURE__ */ jsxs10(Text12, { color: theme13.textMuted, children: [
|
|
9635
|
+
" ",
|
|
9636
|
+
formatElapsed(tool, now)
|
|
9637
|
+
] }),
|
|
9638
|
+
/* @__PURE__ */ jsxs10(Text12, { color: theme13.textSubtle, children: [
|
|
9639
|
+
separator,
|
|
9640
|
+
"c: copy"
|
|
9641
|
+
] }),
|
|
9642
|
+
/* @__PURE__ */ jsxs10(Text12, { color: theme13.textSubtle, children: [
|
|
9643
|
+
separator,
|
|
9644
|
+
"Esc: close"
|
|
9645
|
+
] })
|
|
9646
|
+
] }),
|
|
9647
|
+
/* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", flexGrow: 1, children: [
|
|
9648
|
+
/* @__PURE__ */ jsx12(Box11, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx12(Text12, { color: theme13.text, wrap: "truncate", children: line }, i)) }),
|
|
9649
|
+
/* @__PURE__ */ jsx12(
|
|
9650
|
+
Scrollbar,
|
|
9651
|
+
{
|
|
9652
|
+
totalLines,
|
|
9653
|
+
visibleLines: maxVisibleLines,
|
|
9654
|
+
scrollOffset: clampedOffset,
|
|
9655
|
+
height: lines.length
|
|
9656
|
+
}
|
|
9657
|
+
)
|
|
9658
|
+
] })
|
|
9659
|
+
] });
|
|
9368
9660
|
}
|
|
9369
|
-
|
|
9661
|
+
var ToolsPanel = memo(function ToolsPanel2({
|
|
9370
9662
|
tools,
|
|
9371
9663
|
maxVisibleLines = 50,
|
|
9372
9664
|
selectedIndex,
|
|
@@ -9374,40 +9666,36 @@ function ToolsPanel({
|
|
|
9374
9666
|
detailScrollOffset = 0,
|
|
9375
9667
|
width = 120
|
|
9376
9668
|
}) {
|
|
9377
|
-
const separator =
|
|
9378
|
-
const [now, setNow] =
|
|
9669
|
+
const separator = theme13.separator ?? " \xB7 ";
|
|
9670
|
+
const [now, setNow] = useState12(Date.now());
|
|
9379
9671
|
const hasRunning = tools.some((t) => t.status === "running");
|
|
9380
|
-
|
|
9672
|
+
useEffect12(() => {
|
|
9381
9673
|
if (!hasRunning) return;
|
|
9382
9674
|
const interval = setInterval(() => setNow(Date.now()), 100);
|
|
9383
9675
|
return () => clearInterval(interval);
|
|
9384
9676
|
}, [hasRunning]);
|
|
9385
|
-
const { rows, hiddenAbove } =
|
|
9677
|
+
const { rows, hiddenAbove } = useMemo2(() => {
|
|
9386
9678
|
if (tools.length === 0) return { rows: [], hiddenAbove: 0 };
|
|
9387
|
-
const
|
|
9388
|
-
const half = Math.floor(maxVisibleLines / 2);
|
|
9389
|
-
let start = selectedIndex - half;
|
|
9390
|
-
let end = start + maxVisibleLines;
|
|
9391
|
-
if (start < 0) {
|
|
9392
|
-
start = 0;
|
|
9393
|
-
end = Math.min(total, maxVisibleLines);
|
|
9394
|
-
}
|
|
9395
|
-
if (end > total) {
|
|
9396
|
-
end = total;
|
|
9397
|
-
start = Math.max(0, end - maxVisibleLines);
|
|
9398
|
-
}
|
|
9679
|
+
const { start, end } = getVisibleToolWindow(tools.length, selectedIndex, maxVisibleLines);
|
|
9399
9680
|
const visible = tools.slice(start, end);
|
|
9400
9681
|
return {
|
|
9401
9682
|
rows: visible.map((tool, i) => ({
|
|
9402
9683
|
globalIndex: start + i,
|
|
9403
9684
|
key: tool.id,
|
|
9404
|
-
tool
|
|
9685
|
+
status: tool.status,
|
|
9686
|
+
phase: tool.phase,
|
|
9687
|
+
sequence: tool.sequence,
|
|
9688
|
+
name: tool.name,
|
|
9689
|
+
inputPreview: tool.inputPreview,
|
|
9690
|
+
executionTime: tool.executionTime,
|
|
9691
|
+
startedAt: tool.startedAt,
|
|
9692
|
+
localExecutionStartedAt: tool.localExecutionStartedAt
|
|
9405
9693
|
})),
|
|
9406
9694
|
hiddenAbove: start
|
|
9407
9695
|
};
|
|
9408
9696
|
}, [tools, maxVisibleLines, selectedIndex]);
|
|
9409
9697
|
if (detailTool) {
|
|
9410
|
-
return /* @__PURE__ */
|
|
9698
|
+
return /* @__PURE__ */ jsx12(
|
|
9411
9699
|
ToolDetailView,
|
|
9412
9700
|
{
|
|
9413
9701
|
tool: detailTool,
|
|
@@ -9419,102 +9707,125 @@ function ToolsPanel({
|
|
|
9419
9707
|
);
|
|
9420
9708
|
}
|
|
9421
9709
|
if (tools.length === 0) {
|
|
9422
|
-
return /* @__PURE__ */
|
|
9423
|
-
|
|
9424
|
-
|
|
9425
|
-
|
|
9426
|
-
|
|
9427
|
-
|
|
9428
|
-
|
|
9429
|
-
|
|
9430
|
-
|
|
9431
|
-
|
|
9432
|
-
|
|
9433
|
-
|
|
9434
|
-
|
|
9435
|
-
|
|
9436
|
-
|
|
9437
|
-
|
|
9438
|
-
|
|
9439
|
-
|
|
9440
|
-
|
|
9441
|
-
|
|
9442
|
-
|
|
9443
|
-
|
|
9444
|
-
|
|
9710
|
+
return /* @__PURE__ */ jsx12(Box11, { flexDirection: "column", paddingX: theme13.panelPaddingX, paddingY: theme13.panelPaddingY, children: /* @__PURE__ */ jsx12(Text12, { color: theme13.textSubtle, children: "No tool calls yet..." }) });
|
|
9711
|
+
}
|
|
9712
|
+
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", paddingX: theme13.panelPaddingX, paddingY: theme13.panelPaddingY, children: [
|
|
9713
|
+
/* @__PURE__ */ jsxs10(Box11, { marginBottom: 0, children: [
|
|
9714
|
+
/* @__PURE__ */ jsx12(Text12, { bold: true, color: theme13.accent, children: "Tools" }),
|
|
9715
|
+
/* @__PURE__ */ jsxs10(Text12, { color: theme13.textSubtle, children: [
|
|
9716
|
+
separator,
|
|
9717
|
+
tools.length,
|
|
9718
|
+
" calls"
|
|
9719
|
+
] })
|
|
9720
|
+
] }),
|
|
9721
|
+
/* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", children: [
|
|
9722
|
+
/* @__PURE__ */ jsx12(Box11, { flexDirection: "column", flexGrow: 1, children: rows.map((row) => {
|
|
9723
|
+
const isSelected = row.globalIndex === selectedIndex;
|
|
9724
|
+
const statusColor = getStatusColor(row.status);
|
|
9725
|
+
const elapsed = formatElapsed({
|
|
9726
|
+
status: row.status,
|
|
9727
|
+
phase: row.phase,
|
|
9728
|
+
sequence: row.sequence,
|
|
9729
|
+
name: row.name,
|
|
9730
|
+
startedAt: row.startedAt,
|
|
9731
|
+
localExecutionStartedAt: row.localExecutionStartedAt,
|
|
9732
|
+
executionTime: row.executionTime
|
|
9733
|
+
}, now);
|
|
9734
|
+
const phaseLabel = getPhaseLabel({
|
|
9735
|
+
status: row.status,
|
|
9736
|
+
phase: row.phase
|
|
9737
|
+
});
|
|
9738
|
+
return /* @__PURE__ */ jsxs10(Box11, { flexDirection: "column", children: [
|
|
9739
|
+
/* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9740
|
+
/* @__PURE__ */ jsx12(Box11, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx12(Text12, { color: isSelected ? theme13.accentActive : theme13.textSubtle, children: isSelected ? "\u203A" : " " }) }),
|
|
9741
|
+
/* @__PURE__ */ jsx12(Box11, { width: 2, flexShrink: 0, children: row.status === "running" ? /* @__PURE__ */ jsx12(Spinner4, { label: "", color: theme13.spinner }) : /* @__PURE__ */ jsx12(Text12, { color: statusColor, children: STATUS_ICONS[row.status] || "?" }) }),
|
|
9742
|
+
/* @__PURE__ */ jsx12(Box11, { width: 5, flexShrink: 0, children: /* @__PURE__ */ jsxs10(Text12, { color: theme13.textMuted, children: [
|
|
9743
|
+
"[",
|
|
9744
|
+
row.sequence,
|
|
9745
|
+
"] "
|
|
9746
|
+
] }) }),
|
|
9747
|
+
/* @__PURE__ */ jsx12(Box11, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx12(
|
|
9748
|
+
Text12,
|
|
9749
|
+
{
|
|
9750
|
+
color: isSelected ? theme13.accentActive : theme13.text,
|
|
9751
|
+
bold: isSelected,
|
|
9752
|
+
wrap: "truncate",
|
|
9753
|
+
children: row.name
|
|
9754
|
+
}
|
|
9755
|
+
) }),
|
|
9756
|
+
/* @__PURE__ */ jsx12(Box11, { width: 24, flexShrink: 0, justifyContent: "flex-end", children: /* @__PURE__ */ jsx12(Text12, { color: theme13.textMuted, children: `${phaseLabel} ${elapsed}` }) })
|
|
9757
|
+
] }),
|
|
9758
|
+
/* @__PURE__ */ jsxs10(Box11, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9759
|
+
/* @__PURE__ */ jsx12(Box11, { width: 9, flexShrink: 0 }),
|
|
9760
|
+
/* @__PURE__ */ jsx12(Text12, { color: theme13.textSubtle, children: "\u2514 " }),
|
|
9761
|
+
/* @__PURE__ */ jsx12(Box11, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx12(Text12, { color: theme13.textMuted, wrap: "truncate", children: row.inputPreview || "" }) })
|
|
9445
9762
|
] })
|
|
9446
|
-
] })
|
|
9447
|
-
|
|
9448
|
-
|
|
9449
|
-
|
|
9450
|
-
|
|
9451
|
-
|
|
9452
|
-
|
|
9453
|
-
|
|
9454
|
-
|
|
9455
|
-
|
|
9456
|
-
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
{
|
|
9463
|
-
color: isSelected ? theme16.accentActive : theme16.text,
|
|
9464
|
-
bold: isSelected,
|
|
9465
|
-
wrap: "truncate",
|
|
9466
|
-
children: row.tool.name
|
|
9467
|
-
}
|
|
9468
|
-
) }),
|
|
9469
|
-
/* @__PURE__ */ jsx15(Box12, { width: 7, flexShrink: 0, justifyContent: "flex-end", children: /* @__PURE__ */ jsx15(Text13, { color: theme16.textMuted, children: elapsed }) })
|
|
9470
|
-
] }, row.key);
|
|
9471
|
-
}) }),
|
|
9472
|
-
/* @__PURE__ */ jsx15(
|
|
9473
|
-
Scrollbar,
|
|
9474
|
-
{
|
|
9475
|
-
totalLines: tools.length,
|
|
9476
|
-
visibleLines: rows.length,
|
|
9477
|
-
scrollOffset: hiddenAbove,
|
|
9478
|
-
height: rows.length
|
|
9479
|
-
}
|
|
9480
|
-
)
|
|
9481
|
-
] })
|
|
9482
|
-
]
|
|
9483
|
-
}
|
|
9484
|
-
);
|
|
9485
|
-
}
|
|
9763
|
+
] }, row.key);
|
|
9764
|
+
}) }),
|
|
9765
|
+
/* @__PURE__ */ jsx12(
|
|
9766
|
+
Scrollbar,
|
|
9767
|
+
{
|
|
9768
|
+
totalLines: tools.length * 2,
|
|
9769
|
+
visibleLines: rows.length * 2,
|
|
9770
|
+
scrollOffset: hiddenAbove * 2,
|
|
9771
|
+
height: rows.length * 2
|
|
9772
|
+
}
|
|
9773
|
+
)
|
|
9774
|
+
] })
|
|
9775
|
+
] });
|
|
9776
|
+
}, (prev, next) => {
|
|
9777
|
+
return visibleToolsFingerprint(prev.tools, prev.selectedIndex, prev.maxVisibleLines ?? 50) === visibleToolsFingerprint(next.tools, next.selectedIndex, next.maxVisibleLines ?? 50) && prev.detailTool === next.detailTool && prev.detailScrollOffset === next.detailScrollOffset && prev.width === next.width;
|
|
9778
|
+
});
|
|
9486
9779
|
|
|
9487
9780
|
// src/ink/marathon/EventStreamPanel.tsx
|
|
9488
|
-
import { useMemo as
|
|
9489
|
-
import { Box as
|
|
9490
|
-
import { theme as
|
|
9491
|
-
import { jsx as
|
|
9781
|
+
import { useMemo as useMemo3, memo as memo2 } from "react";
|
|
9782
|
+
import { Box as Box12, Text as Text13 } from "ink";
|
|
9783
|
+
import { theme as theme14 } from "@runtypelabs/ink-components";
|
|
9784
|
+
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
9492
9785
|
var EVENT_COLORS = {
|
|
9493
|
-
agent_start:
|
|
9494
|
-
agent_complete:
|
|
9495
|
-
agent_error:
|
|
9496
|
-
agent_await:
|
|
9497
|
-
agent_iteration_start:
|
|
9498
|
-
agent_iteration_complete:
|
|
9499
|
-
agent_turn_delta:
|
|
9500
|
-
agent_turn_complete:
|
|
9501
|
-
agent_tool_start:
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9786
|
+
agent_start: theme14.success,
|
|
9787
|
+
agent_complete: theme14.success,
|
|
9788
|
+
agent_error: theme14.danger,
|
|
9789
|
+
agent_await: theme14.warning,
|
|
9790
|
+
agent_iteration_start: theme14.accent,
|
|
9791
|
+
agent_iteration_complete: theme14.accent,
|
|
9792
|
+
agent_turn_delta: theme14.textMuted,
|
|
9793
|
+
agent_turn_complete: theme14.accentActive,
|
|
9794
|
+
agent_tool_start: theme14.warning,
|
|
9795
|
+
agent_tool_delta: theme14.warning,
|
|
9796
|
+
agent_tool_complete: theme14.warning,
|
|
9797
|
+
local_tool_execution_start: theme14.warning,
|
|
9798
|
+
local_tool_execution_complete: theme14.warning,
|
|
9799
|
+
marathon_context_compaction_start: theme14.warning,
|
|
9800
|
+
marathon_context_compaction_complete: theme14.success,
|
|
9801
|
+
marathon_context_notice: theme14.warning
|
|
9506
9802
|
};
|
|
9507
9803
|
function formatTimestamp(ts, start) {
|
|
9508
9804
|
if (!start) return "0.000s";
|
|
9509
9805
|
const elapsed = (ts - start) / 1e3;
|
|
9510
9806
|
return `${elapsed.toFixed(3)}s`;
|
|
9511
9807
|
}
|
|
9808
|
+
var eventDataCache = /* @__PURE__ */ new WeakMap();
|
|
9809
|
+
var EVENT_SUMMARY_MAX_CHARS = 140;
|
|
9810
|
+
var HEAVY_FIELDS = /* @__PURE__ */ new Set(["result", "parameters", "finalOutput"]);
|
|
9512
9811
|
function formatEventData(data) {
|
|
9513
|
-
const
|
|
9514
|
-
|
|
9812
|
+
const cached = eventDataCache.get(data);
|
|
9813
|
+
if (cached !== void 0) return cached;
|
|
9814
|
+
const filtered = {};
|
|
9815
|
+
for (const key of Object.keys(data)) {
|
|
9816
|
+
if (key === "type") continue;
|
|
9817
|
+
if (HEAVY_FIELDS.has(key)) continue;
|
|
9818
|
+
filtered[key] = data[key];
|
|
9819
|
+
}
|
|
9515
9820
|
const keys = Object.keys(filtered);
|
|
9516
|
-
if (keys.length === 0)
|
|
9517
|
-
|
|
9821
|
+
if (keys.length === 0) {
|
|
9822
|
+
eventDataCache.set(data, "");
|
|
9823
|
+
return "";
|
|
9824
|
+
}
|
|
9825
|
+
const result = JSON.stringify(filtered);
|
|
9826
|
+
const summary = result.length > EVENT_SUMMARY_MAX_CHARS ? `${result.slice(0, EVENT_SUMMARY_MAX_CHARS - 1)}\u2026` : result;
|
|
9827
|
+
eventDataCache.set(data, summary);
|
|
9828
|
+
return summary;
|
|
9518
9829
|
}
|
|
9519
9830
|
function formatEventDetailCopyText(event, startTime) {
|
|
9520
9831
|
return `${formatTimestamp(event.timestamp, startTime)} ${event.type}
|
|
@@ -9547,41 +9858,40 @@ function EventDetailView({
|
|
|
9547
9858
|
scrollOffset = 0,
|
|
9548
9859
|
width = 120
|
|
9549
9860
|
}) {
|
|
9550
|
-
const separator =
|
|
9551
|
-
const
|
|
9552
|
-
|
|
9553
|
-
|
|
9554
|
-
|
|
9555
|
-
|
|
9556
|
-
|
|
9557
|
-
|
|
9558
|
-
|
|
9559
|
-
|
|
9560
|
-
|
|
9561
|
-
Box13,
|
|
9861
|
+
const separator = theme14.separator ?? " \xB7 ";
|
|
9862
|
+
const allLines = useMemo3(() => getEventDetailLines(event, width), [event, width]);
|
|
9863
|
+
const totalLines = allLines.length;
|
|
9864
|
+
const clampedOffset = Math.min(scrollOffset, Math.max(0, totalLines - maxVisibleLines));
|
|
9865
|
+
const lines = useMemo3(
|
|
9866
|
+
() => allLines.slice(clampedOffset, clampedOffset + maxVisibleLines),
|
|
9867
|
+
[allLines, clampedOffset, maxVisibleLines]
|
|
9868
|
+
);
|
|
9869
|
+
const color = EVENT_COLORS[event.type] || theme14.text;
|
|
9870
|
+
return /* @__PURE__ */ jsxs11(
|
|
9871
|
+
Box12,
|
|
9562
9872
|
{
|
|
9563
9873
|
flexDirection: "column",
|
|
9564
|
-
paddingX:
|
|
9565
|
-
paddingY:
|
|
9874
|
+
paddingX: theme14.panelPaddingX,
|
|
9875
|
+
paddingY: theme14.panelPaddingY,
|
|
9566
9876
|
children: [
|
|
9567
|
-
/* @__PURE__ */
|
|
9568
|
-
/* @__PURE__ */
|
|
9877
|
+
/* @__PURE__ */ jsxs11(Box12, { marginBottom: theme14.sectionGap, children: [
|
|
9878
|
+
/* @__PURE__ */ jsxs11(Text13, { color: theme14.textMuted, children: [
|
|
9569
9879
|
formatTimestamp(event.timestamp, startTime),
|
|
9570
9880
|
" "
|
|
9571
9881
|
] }),
|
|
9572
|
-
/* @__PURE__ */
|
|
9573
|
-
/* @__PURE__ */
|
|
9882
|
+
/* @__PURE__ */ jsx13(Text13, { bold: true, color, children: event.type }),
|
|
9883
|
+
/* @__PURE__ */ jsxs11(Text13, { color: theme14.textSubtle, children: [
|
|
9574
9884
|
separator,
|
|
9575
9885
|
"c: copy"
|
|
9576
9886
|
] }),
|
|
9577
|
-
/* @__PURE__ */
|
|
9887
|
+
/* @__PURE__ */ jsxs11(Text13, { color: theme14.textSubtle, children: [
|
|
9578
9888
|
separator,
|
|
9579
9889
|
"Esc: close"
|
|
9580
9890
|
] })
|
|
9581
9891
|
] }),
|
|
9582
|
-
/* @__PURE__ */
|
|
9583
|
-
/* @__PURE__ */
|
|
9584
|
-
/* @__PURE__ */
|
|
9892
|
+
/* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", flexGrow: 1, children: [
|
|
9893
|
+
/* @__PURE__ */ jsx13(Box12, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx13(Text13, { color: theme14.text, wrap: "truncate", children: line }, i)) }),
|
|
9894
|
+
/* @__PURE__ */ jsx13(
|
|
9585
9895
|
Scrollbar,
|
|
9586
9896
|
{
|
|
9587
9897
|
totalLines,
|
|
@@ -9595,7 +9905,7 @@ function EventDetailView({
|
|
|
9595
9905
|
}
|
|
9596
9906
|
);
|
|
9597
9907
|
}
|
|
9598
|
-
|
|
9908
|
+
var EventStreamPanel = memo2(function EventStreamPanel2({
|
|
9599
9909
|
events,
|
|
9600
9910
|
startTime,
|
|
9601
9911
|
maxVisibleLines = 50,
|
|
@@ -9606,8 +9916,8 @@ function EventStreamPanel({
|
|
|
9606
9916
|
activeFilterCount = 0,
|
|
9607
9917
|
totalTypeCount = 0
|
|
9608
9918
|
}) {
|
|
9609
|
-
const separator =
|
|
9610
|
-
const { rows, hiddenAbove } =
|
|
9919
|
+
const separator = theme14.separator ?? " \xB7 ";
|
|
9920
|
+
const { rows, hiddenAbove } = useMemo3(() => {
|
|
9611
9921
|
if (events.length === 0) return { rows: [], hiddenAbove: 0 };
|
|
9612
9922
|
const total = events.length;
|
|
9613
9923
|
const half = Math.floor(maxVisibleLines / 2);
|
|
@@ -9628,14 +9938,14 @@ function EventStreamPanel({
|
|
|
9628
9938
|
key: `${start + i}`,
|
|
9629
9939
|
time: formatTimestamp(evt.timestamp, startTime),
|
|
9630
9940
|
type: evt.type,
|
|
9631
|
-
color: EVENT_COLORS[evt.type] ||
|
|
9632
|
-
data: formatEventData(evt.data)
|
|
9941
|
+
color: EVENT_COLORS[evt.type] || theme14.text,
|
|
9942
|
+
data: formatEventData(evt.listData ?? evt.data)
|
|
9633
9943
|
})),
|
|
9634
9944
|
hiddenAbove: start
|
|
9635
9945
|
};
|
|
9636
9946
|
}, [events, startTime, maxVisibleLines, selectedIndex]);
|
|
9637
9947
|
if (detailEvent) {
|
|
9638
|
-
return /* @__PURE__ */
|
|
9948
|
+
return /* @__PURE__ */ jsx13(
|
|
9639
9949
|
EventDetailView,
|
|
9640
9950
|
{
|
|
9641
9951
|
event: detailEvent,
|
|
@@ -9647,46 +9957,46 @@ function EventStreamPanel({
|
|
|
9647
9957
|
);
|
|
9648
9958
|
}
|
|
9649
9959
|
if (events.length === 0) {
|
|
9650
|
-
return /* @__PURE__ */
|
|
9651
|
-
|
|
9960
|
+
return /* @__PURE__ */ jsx13(
|
|
9961
|
+
Box12,
|
|
9652
9962
|
{
|
|
9653
9963
|
flexDirection: "column",
|
|
9654
|
-
paddingX:
|
|
9655
|
-
paddingY:
|
|
9656
|
-
children: /* @__PURE__ */
|
|
9964
|
+
paddingX: theme14.panelPaddingX,
|
|
9965
|
+
paddingY: theme14.panelPaddingY,
|
|
9966
|
+
children: /* @__PURE__ */ jsx13(Text13, { color: theme14.textSubtle, children: "Waiting for events..." })
|
|
9657
9967
|
}
|
|
9658
9968
|
);
|
|
9659
9969
|
}
|
|
9660
|
-
return /* @__PURE__ */
|
|
9661
|
-
|
|
9970
|
+
return /* @__PURE__ */ jsxs11(
|
|
9971
|
+
Box12,
|
|
9662
9972
|
{
|
|
9663
9973
|
flexDirection: "column",
|
|
9664
|
-
paddingX:
|
|
9665
|
-
paddingY:
|
|
9974
|
+
paddingX: theme14.panelPaddingX,
|
|
9975
|
+
paddingY: theme14.panelPaddingY,
|
|
9666
9976
|
children: [
|
|
9667
|
-
/* @__PURE__ */
|
|
9668
|
-
/* @__PURE__ */
|
|
9669
|
-
/* @__PURE__ */
|
|
9977
|
+
/* @__PURE__ */ jsxs11(Box12, { marginBottom: 0, children: [
|
|
9978
|
+
/* @__PURE__ */ jsx13(Text13, { bold: true, color: theme14.accent, children: "Event Stream" }),
|
|
9979
|
+
/* @__PURE__ */ jsxs11(Text13, { color: theme14.textSubtle, children: [
|
|
9670
9980
|
separator,
|
|
9671
9981
|
events.length,
|
|
9672
9982
|
" events",
|
|
9673
9983
|
activeFilterCount > 0 && ` (${activeFilterCount}/${totalTypeCount} types)`
|
|
9674
9984
|
] }),
|
|
9675
|
-
/* @__PURE__ */
|
|
9676
|
-
/* @__PURE__ */
|
|
9677
|
-
/* @__PURE__ */
|
|
9985
|
+
/* @__PURE__ */ jsx13(Text13, { color: theme14.textSubtle, children: separator }),
|
|
9986
|
+
/* @__PURE__ */ jsx13(Text13, { color: theme14.info, children: "f" }),
|
|
9987
|
+
/* @__PURE__ */ jsx13(Text13, { color: theme14.textSubtle, children: ": filter" })
|
|
9678
9988
|
] }),
|
|
9679
|
-
/* @__PURE__ */
|
|
9680
|
-
/* @__PURE__ */
|
|
9989
|
+
/* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", children: [
|
|
9990
|
+
/* @__PURE__ */ jsx13(Box12, { flexDirection: "column", flexGrow: 1, children: rows.map((row) => {
|
|
9681
9991
|
const isSelected = row.globalIndex === selectedIndex;
|
|
9682
|
-
return /* @__PURE__ */
|
|
9683
|
-
/* @__PURE__ */
|
|
9684
|
-
/* @__PURE__ */
|
|
9685
|
-
/* @__PURE__ */
|
|
9686
|
-
/* @__PURE__ */
|
|
9992
|
+
return /* @__PURE__ */ jsxs11(Box12, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
9993
|
+
/* @__PURE__ */ jsx13(Box12, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text13, { color: isSelected ? theme14.accentActive : theme14.textSubtle, children: isSelected ? "\u203A" : " " }) }),
|
|
9994
|
+
/* @__PURE__ */ jsx13(Box12, { width: 9, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text13, { color: theme14.textMuted, children: row.time }) }),
|
|
9995
|
+
/* @__PURE__ */ jsx13(Box12, { width: 32, flexShrink: 0, children: /* @__PURE__ */ jsx13(Text13, { color: isSelected ? theme14.accentActive : row.color, bold: isSelected, children: row.type }) }),
|
|
9996
|
+
/* @__PURE__ */ jsx13(Box12, { flexShrink: 1, children: /* @__PURE__ */ jsx13(Text13, { color: theme14.textMuted, wrap: "truncate", children: row.data }) })
|
|
9687
9997
|
] }, row.key);
|
|
9688
9998
|
}) }),
|
|
9689
|
-
/* @__PURE__ */
|
|
9999
|
+
/* @__PURE__ */ jsx13(
|
|
9690
10000
|
Scrollbar,
|
|
9691
10001
|
{
|
|
9692
10002
|
totalLines: events.length,
|
|
@@ -9699,18 +10009,20 @@ function EventStreamPanel({
|
|
|
9699
10009
|
]
|
|
9700
10010
|
}
|
|
9701
10011
|
);
|
|
9702
|
-
}
|
|
10012
|
+
}, (prev, next) => {
|
|
10013
|
+
return prev.events.length === next.events.length && prev.selectedIndex === next.selectedIndex && prev.maxVisibleLines === next.maxVisibleLines && prev.startTime === next.startTime && prev.detailEvent === next.detailEvent && prev.detailScrollOffset === next.detailScrollOffset && prev.width === next.width && prev.activeFilterCount === next.activeFilterCount && prev.totalTypeCount === next.totalTypeCount;
|
|
10014
|
+
});
|
|
9703
10015
|
|
|
9704
10016
|
// src/ink/marathon/EventTypeFilter.tsx
|
|
9705
|
-
import { useState as
|
|
9706
|
-
import { Box as
|
|
9707
|
-
import { theme as
|
|
9708
|
-
import { jsx as
|
|
10017
|
+
import { useState as useState13, useCallback as useCallback4 } from "react";
|
|
10018
|
+
import { Box as Box13, Text as Text14, useInput as useInput5, useStdout } from "ink";
|
|
10019
|
+
import { theme as theme15 } from "@runtypelabs/ink-components";
|
|
10020
|
+
import { jsx as jsx14, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
9709
10021
|
var MAX_VISIBLE = 14;
|
|
9710
10022
|
function EventTypeFilter({ eventTypes, selectedTypes, onApply, onCancel }) {
|
|
9711
10023
|
const { stdout } = useStdout();
|
|
9712
|
-
const [localSelected, setLocalSelected] =
|
|
9713
|
-
const [selectedIndex, setSelectedIndex] =
|
|
10024
|
+
const [localSelected, setLocalSelected] = useState13(() => new Set(selectedTypes));
|
|
10025
|
+
const [selectedIndex, setSelectedIndex] = useState13(0);
|
|
9714
10026
|
const contentWidth = (stdout?.columns ?? 120) - 4;
|
|
9715
10027
|
const pad = useCallback4(
|
|
9716
10028
|
(text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text,
|
|
@@ -9769,60 +10081,60 @@ function EventTypeFilter({ eventTypes, selectedTypes, onApply, onCancel }) {
|
|
|
9769
10081
|
return;
|
|
9770
10082
|
}
|
|
9771
10083
|
});
|
|
9772
|
-
const separator =
|
|
9773
|
-
return /* @__PURE__ */
|
|
9774
|
-
|
|
10084
|
+
const separator = theme15.separator ?? " \xB7 ";
|
|
10085
|
+
return /* @__PURE__ */ jsxs12(
|
|
10086
|
+
Box13,
|
|
9775
10087
|
{
|
|
9776
10088
|
borderStyle: "single",
|
|
9777
|
-
borderColor:
|
|
9778
|
-
backgroundColor:
|
|
9779
|
-
paddingX:
|
|
9780
|
-
paddingY:
|
|
10089
|
+
borderColor: theme15.border,
|
|
10090
|
+
backgroundColor: theme15.surfaceElevated,
|
|
10091
|
+
paddingX: theme15.panelPaddingX,
|
|
10092
|
+
paddingY: theme15.panelPaddingY,
|
|
9781
10093
|
flexDirection: "column",
|
|
9782
10094
|
children: [
|
|
9783
|
-
/* @__PURE__ */
|
|
9784
|
-
/* @__PURE__ */
|
|
9785
|
-
/* @__PURE__ */
|
|
10095
|
+
/* @__PURE__ */ jsxs12(Box13, { marginBottom: 1, children: [
|
|
10096
|
+
/* @__PURE__ */ jsx14(Text14, { color: theme15.accent, bold: true, children: "Filter Event Types" }),
|
|
10097
|
+
/* @__PURE__ */ jsxs12(Text14, { color: theme15.textSubtle, children: [
|
|
9786
10098
|
" ",
|
|
9787
10099
|
localSelected.size === 0 ? "all" : `${localSelected.size}/${eventTypes.length}`
|
|
9788
10100
|
] })
|
|
9789
10101
|
] }),
|
|
9790
|
-
/* @__PURE__ */
|
|
9791
|
-
/* @__PURE__ */
|
|
10102
|
+
/* @__PURE__ */ jsx14(Box13, { height: 1, children: /* @__PURE__ */ jsx14(Text14, { color: theme15.textSubtle, children: pad(showScrollUp ? " ..." : "") }) }),
|
|
10103
|
+
/* @__PURE__ */ jsx14(Box13, { flexDirection: "column", height: MAX_VISIBLE, children: eventTypes.length === 0 ? /* @__PURE__ */ jsx14(Text14, { color: theme15.textSubtle, children: pad(" No event types") }) : visibleTypes.map((type, i) => {
|
|
9792
10104
|
const globalIndex = windowStart + i;
|
|
9793
10105
|
const isHighlighted = globalIndex === selectedIndex;
|
|
9794
10106
|
const isChecked = localSelected.has(type);
|
|
9795
|
-
const color = EVENT_COLORS[type] ||
|
|
10107
|
+
const color = EVENT_COLORS[type] || theme15.text;
|
|
9796
10108
|
const checkbox = isChecked ? "[\u2713]" : "[ ]";
|
|
9797
10109
|
const indicator = isHighlighted ? "\u203A " : " ";
|
|
9798
|
-
return /* @__PURE__ */
|
|
9799
|
-
/* @__PURE__ */
|
|
9800
|
-
|
|
10110
|
+
return /* @__PURE__ */ jsxs12(Box13, { children: [
|
|
10111
|
+
/* @__PURE__ */ jsx14(
|
|
10112
|
+
Text14,
|
|
9801
10113
|
{
|
|
9802
|
-
color: isHighlighted ?
|
|
10114
|
+
color: isHighlighted ? theme15.accentActive : theme15.textMuted,
|
|
9803
10115
|
bold: isHighlighted,
|
|
9804
10116
|
children: indicator
|
|
9805
10117
|
}
|
|
9806
10118
|
),
|
|
9807
|
-
/* @__PURE__ */
|
|
10119
|
+
/* @__PURE__ */ jsxs12(Text14, { color: isHighlighted ? theme15.accentActive : theme15.textSubtle, children: [
|
|
9808
10120
|
checkbox,
|
|
9809
10121
|
" "
|
|
9810
10122
|
] }),
|
|
9811
|
-
/* @__PURE__ */
|
|
10123
|
+
/* @__PURE__ */ jsx14(Text14, { color: isHighlighted ? theme15.accentActive : color, children: pad(type) })
|
|
9812
10124
|
] }, type);
|
|
9813
10125
|
}) }),
|
|
9814
|
-
/* @__PURE__ */
|
|
9815
|
-
/* @__PURE__ */
|
|
10126
|
+
/* @__PURE__ */ jsx14(Box13, { height: 1, children: /* @__PURE__ */ jsx14(Text14, { color: theme15.textSubtle, children: pad(showScrollDown ? " ..." : "") }) }),
|
|
10127
|
+
/* @__PURE__ */ jsx14(Box13, { marginTop: 1, children: /* @__PURE__ */ jsx14(Text14, { color: theme15.textSubtle, children: ["Space toggle", "a: all/none", "Enter apply", "Esc cancel"].join(separator) }) })
|
|
9816
10128
|
]
|
|
9817
10129
|
}
|
|
9818
10130
|
);
|
|
9819
10131
|
}
|
|
9820
10132
|
|
|
9821
10133
|
// src/ink/marathon/ReasoningPanel.tsx
|
|
9822
|
-
import { useMemo as
|
|
9823
|
-
import { Box as
|
|
9824
|
-
import { theme as
|
|
9825
|
-
import { jsx as
|
|
10134
|
+
import { useMemo as useMemo4 } from "react";
|
|
10135
|
+
import { Box as Box14, Text as Text15 } from "ink";
|
|
10136
|
+
import { theme as theme16 } from "@runtypelabs/ink-components";
|
|
10137
|
+
import { jsx as jsx15, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
9826
10138
|
function wrapLines3(lines, width) {
|
|
9827
10139
|
if (width <= 0) return lines;
|
|
9828
10140
|
const result = [];
|
|
@@ -9837,7 +10149,7 @@ function wrapLines3(lines, width) {
|
|
|
9837
10149
|
}
|
|
9838
10150
|
return result;
|
|
9839
10151
|
}
|
|
9840
|
-
function
|
|
10152
|
+
function formatCharCount(chars) {
|
|
9841
10153
|
if (chars >= 1e3) {
|
|
9842
10154
|
return `${(chars / 1e3).toFixed(1)}k`;
|
|
9843
10155
|
}
|
|
@@ -9854,50 +10166,51 @@ function ReasoningPanel({
|
|
|
9854
10166
|
scrollOffset = 0,
|
|
9855
10167
|
width = 120
|
|
9856
10168
|
}) {
|
|
9857
|
-
const separator =
|
|
9858
|
-
const
|
|
9859
|
-
|
|
9860
|
-
|
|
9861
|
-
|
|
9862
|
-
|
|
9863
|
-
|
|
9864
|
-
|
|
9865
|
-
|
|
9866
|
-
|
|
9867
|
-
|
|
9868
|
-
|
|
9869
|
-
|
|
9870
|
-
|
|
10169
|
+
const separator = theme16.separator ?? " \xB7 ";
|
|
10170
|
+
const trimmedReasoning = useMemo4(() => reasoning.trimEnd(), [reasoning]);
|
|
10171
|
+
const allLines = useMemo4(
|
|
10172
|
+
() => trimmedReasoning ? getReasoningLines(trimmedReasoning, width) : [],
|
|
10173
|
+
[trimmedReasoning, width]
|
|
10174
|
+
);
|
|
10175
|
+
const totalLines = allLines.length;
|
|
10176
|
+
const clampedOffset = Math.min(scrollOffset, Math.max(0, totalLines - maxVisibleLines));
|
|
10177
|
+
const lines = useMemo4(
|
|
10178
|
+
() => allLines.slice(clampedOffset, clampedOffset + maxVisibleLines),
|
|
10179
|
+
[allLines, clampedOffset, maxVisibleLines]
|
|
10180
|
+
);
|
|
10181
|
+
if (!trimmedReasoning) {
|
|
10182
|
+
return /* @__PURE__ */ jsx15(
|
|
10183
|
+
Box14,
|
|
9871
10184
|
{
|
|
9872
10185
|
flexDirection: "column",
|
|
9873
|
-
paddingX:
|
|
9874
|
-
paddingY:
|
|
9875
|
-
children: /* @__PURE__ */
|
|
10186
|
+
paddingX: theme16.panelPaddingX,
|
|
10187
|
+
paddingY: theme16.panelPaddingY,
|
|
10188
|
+
children: /* @__PURE__ */ jsx15(Text15, { color: theme16.textSubtle, children: "No reasoning yet..." })
|
|
9876
10189
|
}
|
|
9877
10190
|
);
|
|
9878
10191
|
}
|
|
9879
|
-
return /* @__PURE__ */
|
|
9880
|
-
|
|
10192
|
+
return /* @__PURE__ */ jsxs13(
|
|
10193
|
+
Box14,
|
|
9881
10194
|
{
|
|
9882
10195
|
flexDirection: "column",
|
|
9883
|
-
paddingX:
|
|
9884
|
-
paddingY:
|
|
10196
|
+
paddingX: theme16.panelPaddingX,
|
|
10197
|
+
paddingY: theme16.panelPaddingY,
|
|
9885
10198
|
children: [
|
|
9886
|
-
/* @__PURE__ */
|
|
9887
|
-
/* @__PURE__ */
|
|
9888
|
-
/* @__PURE__ */
|
|
10199
|
+
/* @__PURE__ */ jsxs13(Box14, { marginBottom: 0, children: [
|
|
10200
|
+
/* @__PURE__ */ jsx15(Text15, { bold: true, color: theme16.accent, children: "Reasoning" }),
|
|
10201
|
+
/* @__PURE__ */ jsxs13(Text15, { color: theme16.textSubtle, children: [
|
|
9889
10202
|
separator,
|
|
9890
|
-
|
|
10203
|
+
formatCharCount(reasoning.length),
|
|
9891
10204
|
" chars"
|
|
9892
10205
|
] }),
|
|
9893
|
-
/* @__PURE__ */
|
|
10206
|
+
/* @__PURE__ */ jsxs13(Text15, { color: theme16.textSubtle, children: [
|
|
9894
10207
|
separator,
|
|
9895
10208
|
"c: copy"
|
|
9896
10209
|
] })
|
|
9897
10210
|
] }),
|
|
9898
|
-
/* @__PURE__ */
|
|
9899
|
-
/* @__PURE__ */
|
|
9900
|
-
/* @__PURE__ */
|
|
10211
|
+
/* @__PURE__ */ jsxs13(Box14, { flexDirection: "row", flexGrow: 1, children: [
|
|
10212
|
+
/* @__PURE__ */ jsx15(Box14, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx15(Text15, { color: theme16.textMuted, wrap: "truncate", children: line || " " }, i)) }),
|
|
10213
|
+
/* @__PURE__ */ jsx15(
|
|
9901
10214
|
Scrollbar,
|
|
9902
10215
|
{
|
|
9903
10216
|
totalLines,
|
|
@@ -9913,14 +10226,14 @@ function ReasoningPanel({
|
|
|
9913
10226
|
}
|
|
9914
10227
|
|
|
9915
10228
|
// src/ink/marathon/FilesPanel.tsx
|
|
9916
|
-
import { useMemo as
|
|
9917
|
-
import { Box as
|
|
9918
|
-
import { theme as
|
|
9919
|
-
import { jsx as
|
|
10229
|
+
import { useMemo as useMemo5 } from "react";
|
|
10230
|
+
import { Box as Box15, Text as Text16 } from "ink";
|
|
10231
|
+
import { theme as theme17, renderMarkdownToTerminal } from "@runtypelabs/ink-components";
|
|
10232
|
+
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
9920
10233
|
var TYPE_COLORS = {
|
|
9921
|
-
plan:
|
|
9922
|
-
written:
|
|
9923
|
-
read:
|
|
10234
|
+
plan: theme17.accent,
|
|
10235
|
+
written: theme17.success,
|
|
10236
|
+
read: theme17.textMuted
|
|
9924
10237
|
};
|
|
9925
10238
|
var TYPE_LABELS = {
|
|
9926
10239
|
plan: "plan",
|
|
@@ -9937,6 +10250,7 @@ function shortenPath(filePath, maxWidth) {
|
|
|
9937
10250
|
return ".../" + segments[segments.length - 1];
|
|
9938
10251
|
}
|
|
9939
10252
|
var ANSI_RE = /\x1B\[[0-9;]*m/g;
|
|
10253
|
+
var ANSI_TEST_RE = /\x1B\[[0-9;]*m/;
|
|
9940
10254
|
function visibleLength(str) {
|
|
9941
10255
|
return str.replace(ANSI_RE, "").length;
|
|
9942
10256
|
}
|
|
@@ -9947,7 +10261,7 @@ function wrapLines4(lines, width) {
|
|
|
9947
10261
|
if (visibleLength(line) <= width) {
|
|
9948
10262
|
result.push(line);
|
|
9949
10263
|
} else {
|
|
9950
|
-
if (!
|
|
10264
|
+
if (!ANSI_TEST_RE.test(line)) {
|
|
9951
10265
|
for (let i = 0; i < line.length; i += width) {
|
|
9952
10266
|
result.push(line.slice(i, i + width));
|
|
9953
10267
|
}
|
|
@@ -9998,55 +10312,59 @@ function FileContentView({
|
|
|
9998
10312
|
scrollOffset = 0,
|
|
9999
10313
|
width = 120
|
|
10000
10314
|
}) {
|
|
10001
|
-
const separator =
|
|
10315
|
+
const separator = theme17.separator ?? " \xB7 ";
|
|
10002
10316
|
const contentWidth = Math.max(20, width - 4);
|
|
10003
10317
|
const isMd = isMarkdownFile(file.path);
|
|
10004
|
-
const
|
|
10005
|
-
|
|
10006
|
-
|
|
10007
|
-
|
|
10008
|
-
|
|
10009
|
-
|
|
10010
|
-
|
|
10011
|
-
|
|
10012
|
-
|
|
10013
|
-
|
|
10318
|
+
const displayContent = useMemo5(
|
|
10319
|
+
() => isMd ? renderMarkdownToTerminal(content) : content,
|
|
10320
|
+
[content, isMd]
|
|
10321
|
+
);
|
|
10322
|
+
const allLines = useMemo5(
|
|
10323
|
+
() => wrapLines4(displayContent.split("\n"), contentWidth),
|
|
10324
|
+
[displayContent, contentWidth]
|
|
10325
|
+
);
|
|
10326
|
+
const displayTotalLines = allLines.length;
|
|
10327
|
+
const clampedOffset = Math.min(scrollOffset, Math.max(0, displayTotalLines - maxVisibleLines));
|
|
10328
|
+
const lines = useMemo5(
|
|
10329
|
+
() => allLines.slice(clampedOffset, clampedOffset + maxVisibleLines),
|
|
10330
|
+
[allLines, clampedOffset, maxVisibleLines]
|
|
10331
|
+
);
|
|
10014
10332
|
const filename = file.path.split("/").pop() || file.path;
|
|
10015
|
-
return /* @__PURE__ */
|
|
10016
|
-
|
|
10333
|
+
return /* @__PURE__ */ jsxs14(
|
|
10334
|
+
Box15,
|
|
10017
10335
|
{
|
|
10018
10336
|
flexDirection: "column",
|
|
10019
|
-
paddingX:
|
|
10020
|
-
paddingY:
|
|
10337
|
+
paddingX: theme17.panelPaddingX,
|
|
10338
|
+
paddingY: theme17.panelPaddingY,
|
|
10021
10339
|
flexGrow: 1,
|
|
10022
10340
|
children: [
|
|
10023
|
-
/* @__PURE__ */
|
|
10024
|
-
/* @__PURE__ */
|
|
10025
|
-
/* @__PURE__ */
|
|
10341
|
+
/* @__PURE__ */ jsxs14(Box15, { marginBottom: theme17.sectionGap, children: [
|
|
10342
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, color: theme17.accent, children: filename }),
|
|
10343
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme17.textSubtle, children: [
|
|
10026
10344
|
separator,
|
|
10027
10345
|
totalLines,
|
|
10028
10346
|
" lines"
|
|
10029
10347
|
] }),
|
|
10030
|
-
truncated && /* @__PURE__ */
|
|
10348
|
+
truncated && /* @__PURE__ */ jsxs14(Text16, { color: theme17.warning, children: [
|
|
10031
10349
|
separator,
|
|
10032
10350
|
"truncated"
|
|
10033
10351
|
] }),
|
|
10034
|
-
source === "tool" && /* @__PURE__ */
|
|
10352
|
+
source === "tool" && /* @__PURE__ */ jsxs14(Text16, { color: theme17.textSubtle, children: [
|
|
10035
10353
|
separator,
|
|
10036
10354
|
"from tool call"
|
|
10037
10355
|
] }),
|
|
10038
|
-
/* @__PURE__ */
|
|
10356
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme17.textSubtle, children: [
|
|
10039
10357
|
separator,
|
|
10040
10358
|
"c: copy"
|
|
10041
10359
|
] }),
|
|
10042
|
-
/* @__PURE__ */
|
|
10360
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme17.textSubtle, children: [
|
|
10043
10361
|
separator,
|
|
10044
10362
|
"Esc: back"
|
|
10045
10363
|
] })
|
|
10046
10364
|
] }),
|
|
10047
|
-
/* @__PURE__ */
|
|
10048
|
-
/* @__PURE__ */
|
|
10049
|
-
/* @__PURE__ */
|
|
10365
|
+
/* @__PURE__ */ jsxs14(Box15, { flexDirection: "row", flexGrow: 1, children: [
|
|
10366
|
+
/* @__PURE__ */ jsx16(Box15, { flexDirection: "column", flexGrow: 1, children: lines.map((line, i) => /* @__PURE__ */ jsx16(Text16, { color: theme17.text, wrap: "truncate", children: line || " " }, i)) }),
|
|
10367
|
+
/* @__PURE__ */ jsx16(
|
|
10050
10368
|
Scrollbar,
|
|
10051
10369
|
{
|
|
10052
10370
|
totalLines: displayTotalLines,
|
|
@@ -10072,9 +10390,9 @@ function FilesPanel({
|
|
|
10072
10390
|
detailScrollOffset = 0,
|
|
10073
10391
|
width = 120
|
|
10074
10392
|
}) {
|
|
10075
|
-
const separator =
|
|
10393
|
+
const separator = theme17.separator ?? " \xB7 ";
|
|
10076
10394
|
if (detailFile && detailContent !== null) {
|
|
10077
|
-
return /* @__PURE__ */
|
|
10395
|
+
return /* @__PURE__ */ jsx16(
|
|
10078
10396
|
FileContentView,
|
|
10079
10397
|
{
|
|
10080
10398
|
file: detailFile,
|
|
@@ -10089,7 +10407,7 @@ function FilesPanel({
|
|
|
10089
10407
|
);
|
|
10090
10408
|
}
|
|
10091
10409
|
const pathMaxWidth = Math.max(20, width - 14);
|
|
10092
|
-
const { rows, hiddenAbove } =
|
|
10410
|
+
const { rows, hiddenAbove } = useMemo5(() => {
|
|
10093
10411
|
if (files.length === 0) return { rows: [], hiddenAbove: 0 };
|
|
10094
10412
|
const total = files.length;
|
|
10095
10413
|
const half = Math.floor(maxVisibleLines / 2);
|
|
@@ -10114,47 +10432,47 @@ function FilesPanel({
|
|
|
10114
10432
|
};
|
|
10115
10433
|
}, [files, maxVisibleLines, selectedIndex]);
|
|
10116
10434
|
if (files.length === 0) {
|
|
10117
|
-
return /* @__PURE__ */
|
|
10118
|
-
|
|
10435
|
+
return /* @__PURE__ */ jsx16(
|
|
10436
|
+
Box15,
|
|
10119
10437
|
{
|
|
10120
10438
|
flexDirection: "column",
|
|
10121
|
-
paddingX:
|
|
10122
|
-
paddingY:
|
|
10123
|
-
children: /* @__PURE__ */
|
|
10439
|
+
paddingX: theme17.panelPaddingX,
|
|
10440
|
+
paddingY: theme17.panelPaddingY,
|
|
10441
|
+
children: /* @__PURE__ */ jsx16(Text16, { color: theme17.textSubtle, children: "No files tracked yet..." })
|
|
10124
10442
|
}
|
|
10125
10443
|
);
|
|
10126
10444
|
}
|
|
10127
|
-
return /* @__PURE__ */
|
|
10128
|
-
|
|
10445
|
+
return /* @__PURE__ */ jsxs14(
|
|
10446
|
+
Box15,
|
|
10129
10447
|
{
|
|
10130
10448
|
flexDirection: "column",
|
|
10131
|
-
paddingX:
|
|
10132
|
-
paddingY:
|
|
10449
|
+
paddingX: theme17.panelPaddingX,
|
|
10450
|
+
paddingY: theme17.panelPaddingY,
|
|
10133
10451
|
children: [
|
|
10134
|
-
/* @__PURE__ */
|
|
10135
|
-
/* @__PURE__ */
|
|
10136
|
-
/* @__PURE__ */
|
|
10452
|
+
/* @__PURE__ */ jsxs14(Box15, { marginBottom: 0, children: [
|
|
10453
|
+
/* @__PURE__ */ jsx16(Text16, { bold: true, color: theme17.accent, children: "Files" }),
|
|
10454
|
+
/* @__PURE__ */ jsxs14(Text16, { color: theme17.textSubtle, children: [
|
|
10137
10455
|
separator,
|
|
10138
10456
|
files.length,
|
|
10139
10457
|
" files"
|
|
10140
10458
|
] })
|
|
10141
10459
|
] }),
|
|
10142
|
-
/* @__PURE__ */
|
|
10143
|
-
/* @__PURE__ */
|
|
10460
|
+
/* @__PURE__ */ jsxs14(Box15, { flexDirection: "row", children: [
|
|
10461
|
+
/* @__PURE__ */ jsx16(Box15, { flexDirection: "column", flexGrow: 1, children: rows.map((row) => {
|
|
10144
10462
|
const isSelected = row.globalIndex === selectedIndex;
|
|
10145
|
-
const typeColor = TYPE_COLORS[row.file.type] ||
|
|
10463
|
+
const typeColor = TYPE_COLORS[row.file.type] || theme17.text;
|
|
10146
10464
|
const typeLabel = TYPE_LABELS[row.file.type] || row.file.type;
|
|
10147
|
-
return /* @__PURE__ */
|
|
10148
|
-
/* @__PURE__ */
|
|
10149
|
-
/* @__PURE__ */
|
|
10465
|
+
return /* @__PURE__ */ jsxs14(Box15, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
10466
|
+
/* @__PURE__ */ jsx16(Box15, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx16(Text16, { color: isSelected ? theme17.accentActive : theme17.textSubtle, children: isSelected ? "\u203A" : " " }) }),
|
|
10467
|
+
/* @__PURE__ */ jsx16(Box15, { width: 8, flexShrink: 0, children: /* @__PURE__ */ jsxs14(Text16, { color: typeColor, children: [
|
|
10150
10468
|
"[",
|
|
10151
10469
|
typeLabel,
|
|
10152
10470
|
"]"
|
|
10153
10471
|
] }) }),
|
|
10154
|
-
/* @__PURE__ */
|
|
10155
|
-
|
|
10472
|
+
/* @__PURE__ */ jsx16(Box15, { flexShrink: 1, children: /* @__PURE__ */ jsx16(
|
|
10473
|
+
Text16,
|
|
10156
10474
|
{
|
|
10157
|
-
color: isSelected ?
|
|
10475
|
+
color: isSelected ? theme17.accentActive : theme17.text,
|
|
10158
10476
|
bold: isSelected,
|
|
10159
10477
|
wrap: "truncate",
|
|
10160
10478
|
children: shortenPath(row.file.path, pathMaxWidth)
|
|
@@ -10162,7 +10480,7 @@ function FilesPanel({
|
|
|
10162
10480
|
) })
|
|
10163
10481
|
] }, row.key);
|
|
10164
10482
|
}) }),
|
|
10165
|
-
/* @__PURE__ */
|
|
10483
|
+
/* @__PURE__ */ jsx16(
|
|
10166
10484
|
Scrollbar,
|
|
10167
10485
|
{
|
|
10168
10486
|
totalLines: files.length,
|
|
@@ -10178,10 +10496,10 @@ function FilesPanel({
|
|
|
10178
10496
|
}
|
|
10179
10497
|
|
|
10180
10498
|
// src/ink/marathon/HelpPanel.tsx
|
|
10181
|
-
import { useMemo as
|
|
10182
|
-
import { Box as
|
|
10183
|
-
import { theme as
|
|
10184
|
-
import { Fragment
|
|
10499
|
+
import { useMemo as useMemo6 } from "react";
|
|
10500
|
+
import { Box as Box16, Text as Text17 } from "ink";
|
|
10501
|
+
import { theme as theme18 } from "@runtypelabs/ink-components";
|
|
10502
|
+
import { Fragment, jsx as jsx17, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
10185
10503
|
var NAVIGATION_SHORTCUTS = [
|
|
10186
10504
|
{ key: "Tab", desc: "Next screen" },
|
|
10187
10505
|
{ key: "Esc", desc: "Back / close detail / close help" },
|
|
@@ -10252,37 +10570,37 @@ function HelpPanel({ width, height, isCheckpoint, scrollOffset }) {
|
|
|
10252
10570
|
const dialogWidth = Math.min(width - 4, 60);
|
|
10253
10571
|
const contentHeight = Math.min(height - 2, isCheckpoint ? 38 : 28) - 8;
|
|
10254
10572
|
const visibleRows = Math.max(1, contentHeight);
|
|
10255
|
-
const allLines =
|
|
10573
|
+
const allLines = useMemo6(() => buildLines(isCheckpoint), [isCheckpoint]);
|
|
10256
10574
|
const maxScroll = Math.max(0, allLines.length - visibleRows);
|
|
10257
10575
|
const clampedOffset = Math.min(scrollOffset, maxScroll);
|
|
10258
10576
|
const visibleLines = allLines.slice(clampedOffset, clampedOffset + visibleRows);
|
|
10259
|
-
return /* @__PURE__ */
|
|
10260
|
-
|
|
10577
|
+
return /* @__PURE__ */ jsxs15(
|
|
10578
|
+
Box16,
|
|
10261
10579
|
{
|
|
10262
10580
|
width: dialogWidth,
|
|
10263
10581
|
height: Math.min(height - 2, isCheckpoint ? 38 : 28),
|
|
10264
10582
|
flexDirection: "column",
|
|
10265
10583
|
borderStyle: "round",
|
|
10266
|
-
borderColor:
|
|
10267
|
-
backgroundColor:
|
|
10584
|
+
borderColor: theme18.accent,
|
|
10585
|
+
backgroundColor: theme18.surfaceElevated,
|
|
10268
10586
|
paddingX: 2,
|
|
10269
10587
|
paddingY: 1,
|
|
10270
10588
|
children: [
|
|
10271
|
-
/* @__PURE__ */
|
|
10272
|
-
/* @__PURE__ */
|
|
10273
|
-
/* @__PURE__ */
|
|
10589
|
+
/* @__PURE__ */ jsx17(Text17, { bold: true, color: theme18.accent, children: "Keyboard Shortcuts" }),
|
|
10590
|
+
/* @__PURE__ */ jsxs15(Box16, { flexDirection: "row", flexGrow: 1, marginTop: 1, children: [
|
|
10591
|
+
/* @__PURE__ */ jsx17(Box16, { flexDirection: "column", flexGrow: 1, children: visibleLines.map((line, idx) => {
|
|
10274
10592
|
if (line.type === "header") {
|
|
10275
|
-
return /* @__PURE__ */
|
|
10593
|
+
return /* @__PURE__ */ jsx17(Text17, { bold: true, color: theme18.accentActive, children: line.title }, idx);
|
|
10276
10594
|
}
|
|
10277
10595
|
if (line.type === "item") {
|
|
10278
|
-
return /* @__PURE__ */
|
|
10279
|
-
/* @__PURE__ */
|
|
10280
|
-
/* @__PURE__ */
|
|
10596
|
+
return /* @__PURE__ */ jsxs15(Text17, { children: [
|
|
10597
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.textSubtle, children: ` ${line.key.padEnd(16)}` }),
|
|
10598
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.textMuted, children: line.desc })
|
|
10281
10599
|
] }, idx);
|
|
10282
10600
|
}
|
|
10283
|
-
return /* @__PURE__ */
|
|
10601
|
+
return /* @__PURE__ */ jsx17(Text17, { children: " " }, idx);
|
|
10284
10602
|
}) }),
|
|
10285
|
-
/* @__PURE__ */
|
|
10603
|
+
/* @__PURE__ */ jsx17(
|
|
10286
10604
|
Scrollbar,
|
|
10287
10605
|
{
|
|
10288
10606
|
totalLines: allLines.length,
|
|
@@ -10292,15 +10610,15 @@ function HelpPanel({ width, height, isCheckpoint, scrollOffset }) {
|
|
|
10292
10610
|
}
|
|
10293
10611
|
)
|
|
10294
10612
|
] }),
|
|
10295
|
-
/* @__PURE__ */
|
|
10296
|
-
/* @__PURE__ */
|
|
10297
|
-
/* @__PURE__ */
|
|
10298
|
-
/* @__PURE__ */
|
|
10299
|
-
/* @__PURE__ */
|
|
10300
|
-
isCheckpoint && /* @__PURE__ */
|
|
10301
|
-
/* @__PURE__ */
|
|
10302
|
-
/* @__PURE__ */
|
|
10303
|
-
/* @__PURE__ */
|
|
10613
|
+
/* @__PURE__ */ jsxs15(Box16, { marginTop: 1, children: [
|
|
10614
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.info, children: "Esc" }),
|
|
10615
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.muted, children: " or " }),
|
|
10616
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.info, children: "?" }),
|
|
10617
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.muted, children: " to close" }),
|
|
10618
|
+
isCheckpoint && /* @__PURE__ */ jsxs15(Fragment, { children: [
|
|
10619
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.muted, children: " (use " }),
|
|
10620
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.info, children: "/help" }),
|
|
10621
|
+
/* @__PURE__ */ jsx17(Text17, { color: theme18.muted, children: " during checkpoint)" })
|
|
10304
10622
|
] })
|
|
10305
10623
|
] })
|
|
10306
10624
|
]
|
|
@@ -10736,20 +11054,37 @@ function createEventLogWriter(stateFilePath2, initialSessionIndex) {
|
|
|
10736
11054
|
let sessionIndex = initialSessionIndex;
|
|
10737
11055
|
let currentPath = path3.join(eventsDir, sessionFileName(sessionIndex));
|
|
10738
11056
|
let dirCreated = false;
|
|
11057
|
+
let stream = null;
|
|
10739
11058
|
function ensureDir() {
|
|
10740
11059
|
if (!dirCreated) {
|
|
10741
11060
|
fs3.mkdirSync(eventsDir, { recursive: true });
|
|
10742
11061
|
dirCreated = true;
|
|
10743
11062
|
}
|
|
10744
11063
|
}
|
|
11064
|
+
function ensureStream() {
|
|
11065
|
+
if (!stream || stream.destroyed) {
|
|
11066
|
+
ensureDir();
|
|
11067
|
+
stream = fs3.createWriteStream(currentPath, { flags: "a" });
|
|
11068
|
+
stream.on("error", () => {
|
|
11069
|
+
});
|
|
11070
|
+
}
|
|
11071
|
+
}
|
|
10745
11072
|
return {
|
|
10746
11073
|
append(event) {
|
|
10747
|
-
|
|
10748
|
-
|
|
11074
|
+
ensureStream();
|
|
11075
|
+
stream.write(JSON.stringify(event) + "\n");
|
|
10749
11076
|
},
|
|
10750
11077
|
flush() {
|
|
11078
|
+
if (stream && !stream.destroyed) {
|
|
11079
|
+
stream.end();
|
|
11080
|
+
stream = null;
|
|
11081
|
+
}
|
|
10751
11082
|
},
|
|
10752
11083
|
setSessionIndex(nextIndex) {
|
|
11084
|
+
if (stream && !stream.destroyed) {
|
|
11085
|
+
stream.end();
|
|
11086
|
+
stream = null;
|
|
11087
|
+
}
|
|
10753
11088
|
sessionIndex = nextIndex;
|
|
10754
11089
|
currentPath = path3.join(eventsDir, sessionFileName(sessionIndex));
|
|
10755
11090
|
}
|
|
@@ -10774,14 +11109,14 @@ function readSessionEventLog(stateFilePath2, sessionIndex) {
|
|
|
10774
11109
|
}
|
|
10775
11110
|
|
|
10776
11111
|
// src/ink/marathon/CheckpointPrompt.tsx
|
|
10777
|
-
import { useState as
|
|
10778
|
-
import { Box as
|
|
11112
|
+
import { useState as useState18, useEffect as useEffect16, useRef as useRef7 } from "react";
|
|
11113
|
+
import { Box as Box21, Text as Text23 } from "ink";
|
|
10779
11114
|
|
|
10780
11115
|
// src/ink/marathon/BlinkingTextInput.tsx
|
|
10781
|
-
import { useState as
|
|
10782
|
-
import { Text as
|
|
11116
|
+
import { useState as useState14, useEffect as useEffect13, useRef as useRef5 } from "react";
|
|
11117
|
+
import { Text as Text18, useInput as useInput6 } from "ink";
|
|
10783
11118
|
import chalk12 from "chalk";
|
|
10784
|
-
import { jsx as
|
|
11119
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
10785
11120
|
var CURSOR_BLINK_MS = 800;
|
|
10786
11121
|
function BlinkingTextInput({
|
|
10787
11122
|
value: originalValue,
|
|
@@ -10794,14 +11129,14 @@ function BlinkingTextInput({
|
|
|
10794
11129
|
onChange,
|
|
10795
11130
|
onSubmit
|
|
10796
11131
|
}) {
|
|
10797
|
-
const [state, setState] =
|
|
11132
|
+
const [state, setState] = useState14({
|
|
10798
11133
|
cursorOffset: (originalValue || "").length,
|
|
10799
11134
|
cursorWidth: 0
|
|
10800
11135
|
});
|
|
10801
|
-
const [blinkVisible, setBlinkVisible] =
|
|
11136
|
+
const [blinkVisible, setBlinkVisible] = useState14(true);
|
|
10802
11137
|
const blinkRef = useRef5(null);
|
|
10803
11138
|
const { cursorOffset, cursorWidth } = state;
|
|
10804
|
-
|
|
11139
|
+
useEffect13(() => {
|
|
10805
11140
|
if (!focus || !showCursor || !blinkCursor) {
|
|
10806
11141
|
setBlinkVisible(true);
|
|
10807
11142
|
return;
|
|
@@ -10816,10 +11151,10 @@ function BlinkingTextInput({
|
|
|
10816
11151
|
}
|
|
10817
11152
|
};
|
|
10818
11153
|
}, [focus, showCursor, blinkCursor]);
|
|
10819
|
-
|
|
11154
|
+
useEffect13(() => {
|
|
10820
11155
|
setBlinkVisible(true);
|
|
10821
11156
|
}, [originalValue, cursorOffset]);
|
|
10822
|
-
|
|
11157
|
+
useEffect13(() => {
|
|
10823
11158
|
setState((previousState) => {
|
|
10824
11159
|
if (!focus || !showCursor) {
|
|
10825
11160
|
return previousState;
|
|
@@ -10905,19 +11240,19 @@ function BlinkingTextInput({
|
|
|
10905
11240
|
},
|
|
10906
11241
|
{ isActive: focus }
|
|
10907
11242
|
);
|
|
10908
|
-
return /* @__PURE__ */
|
|
11243
|
+
return /* @__PURE__ */ jsx18(Text18, { children: placeholder ? value.length > 0 ? renderedValue : renderedPlaceholder : renderedValue });
|
|
10909
11244
|
}
|
|
10910
11245
|
|
|
10911
11246
|
// src/ink/marathon/CheckpointPrompt.tsx
|
|
10912
|
-
import { theme as
|
|
11247
|
+
import { theme as theme23 } from "@runtypelabs/ink-components";
|
|
10913
11248
|
|
|
10914
11249
|
// src/ink/talk/ModelPicker.tsx
|
|
10915
|
-
import { useState as
|
|
10916
|
-
import { Box as
|
|
11250
|
+
import { useState as useState15, useMemo as useMemo7, useCallback as useCallback5, useEffect as useEffect14 } from "react";
|
|
11251
|
+
import { Box as Box17, Text as Text19, useInput as useInput7, useStdout as useStdout2 } from "ink";
|
|
10917
11252
|
import TextInput2 from "ink-text-input";
|
|
10918
11253
|
import open3 from "open";
|
|
10919
|
-
import { theme as
|
|
10920
|
-
import { jsx as
|
|
11254
|
+
import { theme as theme19 } from "@runtypelabs/ink-components";
|
|
11255
|
+
import { jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
10921
11256
|
var DEFAULT_MODELS = [
|
|
10922
11257
|
// Anthropic
|
|
10923
11258
|
{ label: "Claude Opus 4.6", value: "claude-opus-4-6", group: "Anthropic" },
|
|
@@ -10951,21 +11286,21 @@ var DEFAULT_MODELS = [
|
|
|
10951
11286
|
var MAX_VISIBLE2 = 12;
|
|
10952
11287
|
function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
10953
11288
|
const { stdout } = useStdout2();
|
|
10954
|
-
const [search, setSearch] =
|
|
11289
|
+
const [search, setSearch] = useState15("");
|
|
10955
11290
|
const availableModels = models && models.length > 0 ? models : DEFAULT_MODELS;
|
|
10956
11291
|
const contentWidth = (stdout?.columns ?? 120) - 4;
|
|
10957
11292
|
const pad = useCallback5(
|
|
10958
11293
|
(text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text,
|
|
10959
11294
|
[contentWidth]
|
|
10960
11295
|
);
|
|
10961
|
-
const filtered =
|
|
11296
|
+
const filtered = useMemo7(() => {
|
|
10962
11297
|
if (!search.trim()) return availableModels;
|
|
10963
11298
|
const q = search.toLowerCase();
|
|
10964
11299
|
return availableModels.filter(
|
|
10965
11300
|
(m) => m.label.toLowerCase().includes(q) || m.value.toLowerCase().includes(q) || m.group.toLowerCase().includes(q)
|
|
10966
11301
|
);
|
|
10967
11302
|
}, [availableModels, search]);
|
|
10968
|
-
const [selectedIndex, setSelectedIndex] =
|
|
11303
|
+
const [selectedIndex, setSelectedIndex] = useState15(() => {
|
|
10969
11304
|
const currentIndex = availableModels.findIndex((model) => model.value === currentModel);
|
|
10970
11305
|
return currentIndex >= 0 ? currentIndex : 0;
|
|
10971
11306
|
});
|
|
@@ -10974,7 +11309,7 @@ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
|
10974
11309
|
setSearch(value);
|
|
10975
11310
|
setSelectedIndex(0);
|
|
10976
11311
|
};
|
|
10977
|
-
|
|
11312
|
+
useEffect14(() => {
|
|
10978
11313
|
if (!search.trim()) {
|
|
10979
11314
|
const currentIndex = filtered.findIndex((model) => model.value === currentModel);
|
|
10980
11315
|
setSelectedIndex(currentIndex >= 0 ? currentIndex : 0);
|
|
@@ -11032,27 +11367,27 @@ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
|
11032
11367
|
}
|
|
11033
11368
|
const showScrollUp = modelWindowStart > 0;
|
|
11034
11369
|
const showScrollDown = modelWindowEnd < filtered.length;
|
|
11035
|
-
return /* @__PURE__ */
|
|
11036
|
-
|
|
11370
|
+
return /* @__PURE__ */ jsxs16(
|
|
11371
|
+
Box17,
|
|
11037
11372
|
{
|
|
11038
11373
|
borderStyle: "single",
|
|
11039
|
-
borderColor:
|
|
11040
|
-
backgroundColor:
|
|
11041
|
-
paddingX:
|
|
11042
|
-
paddingY:
|
|
11374
|
+
borderColor: theme19.border,
|
|
11375
|
+
backgroundColor: theme19.surfaceElevated,
|
|
11376
|
+
paddingX: theme19.panelPaddingX,
|
|
11377
|
+
paddingY: theme19.panelPaddingY,
|
|
11043
11378
|
flexDirection: "column",
|
|
11044
11379
|
children: [
|
|
11045
|
-
/* @__PURE__ */
|
|
11046
|
-
/* @__PURE__ */
|
|
11047
|
-
/* @__PURE__ */
|
|
11380
|
+
/* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
|
|
11381
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme19.accent, bold: true, children: "Select Model" }),
|
|
11382
|
+
/* @__PURE__ */ jsxs16(Text19, { color: theme19.textSubtle, children: [
|
|
11048
11383
|
" ",
|
|
11049
11384
|
filtered.length,
|
|
11050
11385
|
" models"
|
|
11051
11386
|
] })
|
|
11052
11387
|
] }),
|
|
11053
|
-
/* @__PURE__ */
|
|
11054
|
-
/* @__PURE__ */
|
|
11055
|
-
/* @__PURE__ */
|
|
11388
|
+
/* @__PURE__ */ jsxs16(Box17, { marginBottom: 1, children: [
|
|
11389
|
+
/* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: "/ " }),
|
|
11390
|
+
/* @__PURE__ */ jsx19(
|
|
11056
11391
|
TextInput2,
|
|
11057
11392
|
{
|
|
11058
11393
|
value: search,
|
|
@@ -11061,35 +11396,35 @@ function ModelPicker({ currentModel, onSelect, onCancel, models }) {
|
|
|
11061
11396
|
}
|
|
11062
11397
|
)
|
|
11063
11398
|
] }),
|
|
11064
|
-
/* @__PURE__ */
|
|
11065
|
-
/* @__PURE__ */
|
|
11399
|
+
/* @__PURE__ */ jsx19(Box17, { height: 1, children: /* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: pad(showScrollUp ? " ..." : "") }) }),
|
|
11400
|
+
/* @__PURE__ */ jsx19(Box17, { flexDirection: "column", height: MAX_VISIBLE2, children: filtered.length === 0 ? /* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: " No matching models" }) : rows.map((row) => {
|
|
11066
11401
|
if (row.type === "group") {
|
|
11067
|
-
return /* @__PURE__ */
|
|
11402
|
+
return /* @__PURE__ */ jsx19(Box17, { children: /* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, dimColor: true, children: pad(` ${row.label}`) }) }, `group-${row.label}`);
|
|
11068
11403
|
}
|
|
11069
11404
|
const { model, isHighlighted, isCurrent } = row;
|
|
11070
11405
|
const indicator = isHighlighted ? "\u203A " : " ";
|
|
11071
11406
|
const suffix = isCurrent ? " *" : "";
|
|
11072
|
-
return /* @__PURE__ */
|
|
11073
|
-
|
|
11407
|
+
return /* @__PURE__ */ jsx19(Box17, { children: /* @__PURE__ */ jsx19(
|
|
11408
|
+
Text19,
|
|
11074
11409
|
{
|
|
11075
|
-
color: isHighlighted ?
|
|
11410
|
+
color: isHighlighted ? theme19.accentActive : isCurrent ? theme19.accent : theme19.textMuted,
|
|
11076
11411
|
bold: isHighlighted,
|
|
11077
11412
|
children: pad(`${indicator}${model.label}${suffix}`)
|
|
11078
11413
|
}
|
|
11079
11414
|
) }, model.value);
|
|
11080
11415
|
}) }),
|
|
11081
|
-
/* @__PURE__ */
|
|
11082
|
-
/* @__PURE__ */
|
|
11416
|
+
/* @__PURE__ */ jsx19(Box17, { height: 1, children: /* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: pad(showScrollDown ? " ..." : "") }) }),
|
|
11417
|
+
/* @__PURE__ */ jsx19(Box17, { marginTop: 1, children: /* @__PURE__ */ jsx19(Text19, { color: theme19.textSubtle, children: ["\u2191\u2193 navigate", "Enter select", "Tab manage models", "Esc cancel"].join(theme19.separator ?? " \xB7 ") }) })
|
|
11083
11418
|
]
|
|
11084
11419
|
}
|
|
11085
11420
|
);
|
|
11086
11421
|
}
|
|
11087
11422
|
|
|
11088
11423
|
// src/ink/marathon/CommandPicker.tsx
|
|
11089
|
-
import { useState as
|
|
11090
|
-
import { Box as
|
|
11424
|
+
import { useState as useState16, useMemo as useMemo8, useCallback as useCallback6 } from "react";
|
|
11425
|
+
import { Box as Box18, Text as Text20, useInput as useInput8, useStdout as useStdout3 } from "ink";
|
|
11091
11426
|
import TextInput3 from "ink-text-input";
|
|
11092
|
-
import { theme as
|
|
11427
|
+
import { theme as theme20 } from "@runtypelabs/ink-components";
|
|
11093
11428
|
|
|
11094
11429
|
// src/ink/marathon/types.ts
|
|
11095
11430
|
var MARATHON_CHECKPOINT_COMMANDS = [
|
|
@@ -11115,17 +11450,17 @@ var MARATHON_CHECKPOINT_COMMANDS = [
|
|
|
11115
11450
|
];
|
|
11116
11451
|
|
|
11117
11452
|
// src/ink/marathon/CommandPicker.tsx
|
|
11118
|
-
import { jsx as
|
|
11453
|
+
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
11119
11454
|
function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
11120
11455
|
const { stdout } = useStdout3();
|
|
11121
|
-
const [search, setSearch] =
|
|
11122
|
-
const [selectedIndex, setSelectedIndex] =
|
|
11456
|
+
const [search, setSearch] = useState16(initialFilter);
|
|
11457
|
+
const [selectedIndex, setSelectedIndex] = useState16(0);
|
|
11123
11458
|
const contentWidth = (stdout?.columns ?? 120) - 4;
|
|
11124
11459
|
const pad = useCallback6(
|
|
11125
11460
|
(text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text,
|
|
11126
11461
|
[contentWidth]
|
|
11127
11462
|
);
|
|
11128
|
-
const filtered =
|
|
11463
|
+
const filtered = useMemo8(() => {
|
|
11129
11464
|
if (!search.trim()) return MARATHON_CHECKPOINT_COMMANDS;
|
|
11130
11465
|
const q = search.toLowerCase();
|
|
11131
11466
|
return MARATHON_CHECKPOINT_COMMANDS.filter(
|
|
@@ -11157,27 +11492,27 @@ function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
|
11157
11492
|
return;
|
|
11158
11493
|
}
|
|
11159
11494
|
});
|
|
11160
|
-
return /* @__PURE__ */
|
|
11161
|
-
|
|
11495
|
+
return /* @__PURE__ */ jsxs17(
|
|
11496
|
+
Box18,
|
|
11162
11497
|
{
|
|
11163
11498
|
borderStyle: "single",
|
|
11164
|
-
borderColor:
|
|
11165
|
-
backgroundColor:
|
|
11166
|
-
paddingX:
|
|
11167
|
-
paddingY:
|
|
11499
|
+
borderColor: theme20.border,
|
|
11500
|
+
backgroundColor: theme20.surfaceElevated,
|
|
11501
|
+
paddingX: theme20.panelPaddingX,
|
|
11502
|
+
paddingY: theme20.panelPaddingY,
|
|
11168
11503
|
flexDirection: "column",
|
|
11169
11504
|
children: [
|
|
11170
|
-
/* @__PURE__ */
|
|
11171
|
-
/* @__PURE__ */
|
|
11172
|
-
/* @__PURE__ */
|
|
11505
|
+
/* @__PURE__ */ jsxs17(Box18, { marginBottom: 1, children: [
|
|
11506
|
+
/* @__PURE__ */ jsx20(Text20, { color: theme20.accent, bold: true, children: "Commands" }),
|
|
11507
|
+
/* @__PURE__ */ jsxs17(Text20, { color: theme20.textSubtle, children: [
|
|
11173
11508
|
" ",
|
|
11174
11509
|
filtered.length,
|
|
11175
11510
|
" available"
|
|
11176
11511
|
] })
|
|
11177
11512
|
] }),
|
|
11178
|
-
/* @__PURE__ */
|
|
11179
|
-
/* @__PURE__ */
|
|
11180
|
-
/* @__PURE__ */
|
|
11513
|
+
/* @__PURE__ */ jsxs17(Box18, { marginBottom: 1, children: [
|
|
11514
|
+
/* @__PURE__ */ jsx20(Text20, { color: theme20.textSubtle, children: "/ " }),
|
|
11515
|
+
/* @__PURE__ */ jsx20(
|
|
11181
11516
|
TextInput3,
|
|
11182
11517
|
{
|
|
11183
11518
|
value: search,
|
|
@@ -11186,29 +11521,29 @@ function CommandPicker({ onSelect, onCancel, initialFilter = "" }) {
|
|
|
11186
11521
|
}
|
|
11187
11522
|
)
|
|
11188
11523
|
] }),
|
|
11189
|
-
/* @__PURE__ */
|
|
11524
|
+
/* @__PURE__ */ jsx20(Box18, { flexDirection: "column", children: filtered.length === 0 ? /* @__PURE__ */ jsx20(Text20, { color: theme20.textSubtle, children: pad(" No matching commands") }) : filtered.map((cmd, index) => {
|
|
11190
11525
|
const isHighlighted = index === selectedIndex;
|
|
11191
11526
|
const indicator = isHighlighted ? "\u203A " : " ";
|
|
11192
11527
|
const nameCol = cmd.name.padEnd(14);
|
|
11193
|
-
return /* @__PURE__ */
|
|
11194
|
-
|
|
11528
|
+
return /* @__PURE__ */ jsx20(Box18, { children: /* @__PURE__ */ jsx20(
|
|
11529
|
+
Text20,
|
|
11195
11530
|
{
|
|
11196
|
-
color: isHighlighted ?
|
|
11531
|
+
color: isHighlighted ? theme20.accentActive : theme20.textMuted,
|
|
11197
11532
|
bold: isHighlighted,
|
|
11198
11533
|
children: pad(`${indicator}${nameCol}${cmd.description}`)
|
|
11199
11534
|
}
|
|
11200
11535
|
) }, cmd.name);
|
|
11201
11536
|
}) }),
|
|
11202
|
-
/* @__PURE__ */
|
|
11537
|
+
/* @__PURE__ */ jsx20(Box18, { marginTop: 1, children: /* @__PURE__ */ jsx20(Text20, { color: theme20.textSubtle, children: ["\u2191\u2193 navigate", "Enter select", "Esc cancel"].join(theme20.separator ?? " \xB7 ") }) })
|
|
11203
11538
|
]
|
|
11204
11539
|
}
|
|
11205
11540
|
);
|
|
11206
11541
|
}
|
|
11207
11542
|
|
|
11208
11543
|
// src/ink/marathon/TextArea.tsx
|
|
11209
|
-
import { useState as
|
|
11210
|
-
import { Box as
|
|
11211
|
-
import { theme as
|
|
11544
|
+
import { useState as useState17, useCallback as useCallback7, useRef as useRef6, useEffect as useEffect15, useMemo as useMemo9 } from "react";
|
|
11545
|
+
import { Box as Box19, Text as Text21, useInput as useInput9, useStdout as useStdout4 } from "ink";
|
|
11546
|
+
import { theme as theme21 } from "@runtypelabs/ink-components";
|
|
11212
11547
|
|
|
11213
11548
|
// src/ink/marathon/text-area-editing.ts
|
|
11214
11549
|
function ensureLines(lines) {
|
|
@@ -11272,7 +11607,7 @@ function deleteToLineStart(lines, cursor) {
|
|
|
11272
11607
|
}
|
|
11273
11608
|
|
|
11274
11609
|
// src/ink/marathon/TextArea.tsx
|
|
11275
|
-
import { jsx as
|
|
11610
|
+
import { jsx as jsx21, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
11276
11611
|
function splitLines(text) {
|
|
11277
11612
|
const lines = text.split("\n");
|
|
11278
11613
|
return lines.length === 0 ? [""] : lines;
|
|
@@ -11290,20 +11625,20 @@ function TextArea({
|
|
|
11290
11625
|
const { stdout } = useStdout4();
|
|
11291
11626
|
const terminalWidth = stdout?.columns ?? 120;
|
|
11292
11627
|
const contentWidth = Math.max(20, terminalWidth - 6);
|
|
11293
|
-
const separator =
|
|
11294
|
-
const [lines, setLines] =
|
|
11295
|
-
const [cursor, setCursor] =
|
|
11628
|
+
const separator = theme21.separator ?? " \xB7 ";
|
|
11629
|
+
const [lines, setLines] = useState17(() => splitLines(defaultValue));
|
|
11630
|
+
const [cursor, setCursor] = useState17(() => {
|
|
11296
11631
|
const l = splitLines(defaultValue);
|
|
11297
11632
|
return { line: l.length - 1, col: l[l.length - 1].length };
|
|
11298
11633
|
});
|
|
11299
|
-
const [scrollOffset, setScrollOffset] =
|
|
11300
|
-
const [blinkVisible, setBlinkVisible] =
|
|
11634
|
+
const [scrollOffset, setScrollOffset] = useState17(0);
|
|
11635
|
+
const [blinkVisible, setBlinkVisible] = useState17(true);
|
|
11301
11636
|
const blinkRef = useRef6(null);
|
|
11302
11637
|
const linesRef = useRef6(lines);
|
|
11303
11638
|
linesRef.current = lines;
|
|
11304
11639
|
const cursorRef = useRef6(cursor);
|
|
11305
11640
|
cursorRef.current = cursor;
|
|
11306
|
-
|
|
11641
|
+
useEffect15(() => {
|
|
11307
11642
|
blinkRef.current = setInterval(() => {
|
|
11308
11643
|
setBlinkVisible((v) => !v);
|
|
11309
11644
|
}, CURSOR_BLINK_MS);
|
|
@@ -11314,10 +11649,10 @@ function TextArea({
|
|
|
11314
11649
|
}
|
|
11315
11650
|
};
|
|
11316
11651
|
}, []);
|
|
11317
|
-
|
|
11652
|
+
useEffect15(() => {
|
|
11318
11653
|
setBlinkVisible(true);
|
|
11319
11654
|
}, [lines, cursor]);
|
|
11320
|
-
|
|
11655
|
+
useEffect15(() => {
|
|
11321
11656
|
const visibleStart = scrollOffset;
|
|
11322
11657
|
const visibleEnd = scrollOffset + maxHeight - 1;
|
|
11323
11658
|
if (cursor.line < visibleStart) {
|
|
@@ -11442,7 +11777,7 @@ function TextArea({
|
|
|
11442
11777
|
[cursor, onCancel, onSubmit, maxHeight]
|
|
11443
11778
|
);
|
|
11444
11779
|
useInput9(handleInput);
|
|
11445
|
-
const visibleLines =
|
|
11780
|
+
const visibleLines = useMemo9(() => {
|
|
11446
11781
|
const start = scrollOffset;
|
|
11447
11782
|
const end = Math.min(start + maxHeight, lines.length);
|
|
11448
11783
|
const result = [];
|
|
@@ -11459,28 +11794,28 @@ function TextArea({
|
|
|
11459
11794
|
}
|
|
11460
11795
|
return result;
|
|
11461
11796
|
}, [lines, cursor, scrollOffset, maxHeight]);
|
|
11462
|
-
return /* @__PURE__ */
|
|
11463
|
-
/* @__PURE__ */
|
|
11464
|
-
|
|
11797
|
+
return /* @__PURE__ */ jsxs18(Box19, { flexDirection: "column", children: [
|
|
11798
|
+
/* @__PURE__ */ jsxs18(
|
|
11799
|
+
Box19,
|
|
11465
11800
|
{
|
|
11466
11801
|
borderStyle: "single",
|
|
11467
|
-
borderColor:
|
|
11468
|
-
backgroundColor:
|
|
11802
|
+
borderColor: theme21.borderActive,
|
|
11803
|
+
backgroundColor: theme21.surface,
|
|
11469
11804
|
flexDirection: "column",
|
|
11470
11805
|
paddingX: 1,
|
|
11471
11806
|
children: [
|
|
11472
|
-
title && /* @__PURE__ */
|
|
11473
|
-
/* @__PURE__ */
|
|
11474
|
-
/* @__PURE__ */
|
|
11807
|
+
title && /* @__PURE__ */ jsxs18(Box19, { marginBottom: 1, children: [
|
|
11808
|
+
/* @__PURE__ */ jsx21(Text21, { color: theme21.accent, bold: true, children: title }),
|
|
11809
|
+
/* @__PURE__ */ jsxs18(Text21, { color: theme21.textSubtle, children: [
|
|
11475
11810
|
" ",
|
|
11476
11811
|
lines.length,
|
|
11477
11812
|
" lines"
|
|
11478
11813
|
] })
|
|
11479
11814
|
] }),
|
|
11480
|
-
/* @__PURE__ */
|
|
11481
|
-
/* @__PURE__ */
|
|
11482
|
-
/* @__PURE__ */
|
|
11483
|
-
vl.hasCursor ? /* @__PURE__ */
|
|
11815
|
+
/* @__PURE__ */ jsxs18(Box19, { flexDirection: "row", height: maxHeight, children: [
|
|
11816
|
+
/* @__PURE__ */ jsx21(Box19, { flexDirection: "column", flexGrow: 1, children: visibleLines.map((vl, idx) => /* @__PURE__ */ jsxs18(Box19, { children: [
|
|
11817
|
+
/* @__PURE__ */ jsx21(Text21, { color: theme21.textSubtle, children: vl.lineIndex >= 0 ? `${String(vl.lineIndex + 1).padStart(3)} ` : " " }),
|
|
11818
|
+
vl.hasCursor ? /* @__PURE__ */ jsx21(
|
|
11484
11819
|
CursorLine,
|
|
11485
11820
|
{
|
|
11486
11821
|
content: vl.content,
|
|
@@ -11488,9 +11823,9 @@ function TextArea({
|
|
|
11488
11823
|
maxWidth: contentWidth - 6,
|
|
11489
11824
|
visible: blinkVisible
|
|
11490
11825
|
}
|
|
11491
|
-
) : /* @__PURE__ */
|
|
11826
|
+
) : /* @__PURE__ */ jsx21(Text21, { color: theme21.text, children: vl.content.slice(0, contentWidth - 6) })
|
|
11492
11827
|
] }, idx)) }),
|
|
11493
|
-
/* @__PURE__ */
|
|
11828
|
+
/* @__PURE__ */ jsx21(
|
|
11494
11829
|
Scrollbar,
|
|
11495
11830
|
{
|
|
11496
11831
|
totalLines: lines.length,
|
|
@@ -11503,7 +11838,7 @@ function TextArea({
|
|
|
11503
11838
|
]
|
|
11504
11839
|
}
|
|
11505
11840
|
),
|
|
11506
|
-
/* @__PURE__ */
|
|
11841
|
+
/* @__PURE__ */ jsx21(Text21, { color: theme21.textSubtle, children: [
|
|
11507
11842
|
"Ctrl+S: submit",
|
|
11508
11843
|
"Esc: cancel",
|
|
11509
11844
|
"Enter: newline",
|
|
@@ -11523,22 +11858,22 @@ function CursorLine({
|
|
|
11523
11858
|
const before = truncated.slice(0, col);
|
|
11524
11859
|
const cursorChar = truncated[col] ?? " ";
|
|
11525
11860
|
const after = truncated.slice(col + 1);
|
|
11526
|
-
return /* @__PURE__ */
|
|
11527
|
-
/* @__PURE__ */
|
|
11528
|
-
visible ? /* @__PURE__ */
|
|
11529
|
-
/* @__PURE__ */
|
|
11861
|
+
return /* @__PURE__ */ jsxs18(Text21, { children: [
|
|
11862
|
+
/* @__PURE__ */ jsx21(Text21, { color: theme21.text, children: before }),
|
|
11863
|
+
visible ? /* @__PURE__ */ jsx21(Text21, { color: theme21.background, backgroundColor: theme21.accentActive, children: cursorChar }) : /* @__PURE__ */ jsx21(Text21, { color: theme21.text, children: cursorChar }),
|
|
11864
|
+
/* @__PURE__ */ jsx21(Text21, { color: theme21.text, children: after })
|
|
11530
11865
|
] });
|
|
11531
11866
|
}
|
|
11532
11867
|
|
|
11533
11868
|
// src/ink/marathon/ReflectEditor.tsx
|
|
11534
|
-
import { jsx as
|
|
11869
|
+
import { jsx as jsx22 } from "react/jsx-runtime";
|
|
11535
11870
|
var DEFAULT_REFLECT_PROMPT = `Before continuing, step back and reflect:
|
|
11536
11871
|
- What has been accomplished so far?
|
|
11537
11872
|
- What isn't working or is blocking progress?
|
|
11538
11873
|
- What approach should be taken next and why?
|
|
11539
11874
|
- Are there any assumptions that should be reconsidered?`;
|
|
11540
11875
|
function ReflectEditor({ onSubmit, onCancel, maxHeight = 10 }) {
|
|
11541
|
-
return /* @__PURE__ */
|
|
11876
|
+
return /* @__PURE__ */ jsx22(
|
|
11542
11877
|
TextArea,
|
|
11543
11878
|
{
|
|
11544
11879
|
title: "Reflect",
|
|
@@ -11551,9 +11886,9 @@ function ReflectEditor({ onSubmit, onCancel, maxHeight = 10 }) {
|
|
|
11551
11886
|
}
|
|
11552
11887
|
|
|
11553
11888
|
// src/ink/marathon/CheckpointRecap.tsx
|
|
11554
|
-
import { Box as
|
|
11555
|
-
import { theme as
|
|
11556
|
-
import { jsx as
|
|
11889
|
+
import { Box as Box20, Text as Text22 } from "ink";
|
|
11890
|
+
import { theme as theme22 } from "@runtypelabs/ink-components";
|
|
11891
|
+
import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
11557
11892
|
function formatTokenCount2(value) {
|
|
11558
11893
|
return value.toLocaleString("en-US");
|
|
11559
11894
|
}
|
|
@@ -11568,26 +11903,26 @@ function CheckpointRecap({
|
|
|
11568
11903
|
isTerminal
|
|
11569
11904
|
}) {
|
|
11570
11905
|
const label = isTerminal ? `\u2713 Session ${sessionNumber} complete` : `Session ${sessionNumber} complete`;
|
|
11571
|
-
const separator =
|
|
11906
|
+
const separator = theme22.separator ?? " \xB7 ";
|
|
11572
11907
|
const usageSummary = [
|
|
11573
11908
|
`Tools: ${toolCallsMade}`,
|
|
11574
11909
|
`Tokens: ${formatTokenCount2(tokensInput)} in${separator}${formatTokenCount2(tokensOutput)} out`,
|
|
11575
11910
|
...reasoningTokens && reasoningTokens > 0 ? [`Reasoning: ${formatTokenCount2(reasoningTokens)}`] : [],
|
|
11576
11911
|
`Cost: $${cost.toFixed(4)}`
|
|
11577
11912
|
].join(separator);
|
|
11578
|
-
return /* @__PURE__ */
|
|
11579
|
-
|
|
11913
|
+
return /* @__PURE__ */ jsxs19(
|
|
11914
|
+
Box20,
|
|
11580
11915
|
{
|
|
11581
11916
|
borderStyle: "single",
|
|
11582
|
-
borderColor:
|
|
11583
|
-
backgroundColor:
|
|
11917
|
+
borderColor: theme22.border,
|
|
11918
|
+
backgroundColor: theme22.background,
|
|
11584
11919
|
flexDirection: "column",
|
|
11585
|
-
paddingX:
|
|
11586
|
-
paddingY:
|
|
11920
|
+
paddingX: theme22.panelPaddingX,
|
|
11921
|
+
paddingY: theme22.panelPaddingY,
|
|
11587
11922
|
children: [
|
|
11588
|
-
/* @__PURE__ */
|
|
11589
|
-
/* @__PURE__ */
|
|
11590
|
-
historyWarning && /* @__PURE__ */
|
|
11923
|
+
/* @__PURE__ */ jsx23(Text22, { color: isTerminal ? theme22.accentActive : theme22.accent, children: label }),
|
|
11924
|
+
/* @__PURE__ */ jsx23(Text22, { color: theme22.textMuted, children: usageSummary }),
|
|
11925
|
+
historyWarning && /* @__PURE__ */ jsx23(Text22, { color: theme22.warning, children: historyWarning })
|
|
11591
11926
|
]
|
|
11592
11927
|
}
|
|
11593
11928
|
);
|
|
@@ -11609,7 +11944,7 @@ function getCheckpointCountdownText(state) {
|
|
|
11609
11944
|
}
|
|
11610
11945
|
|
|
11611
11946
|
// src/ink/marathon/CheckpointPrompt.tsx
|
|
11612
|
-
import { jsx as
|
|
11947
|
+
import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
11613
11948
|
function CheckpointPrompt({
|
|
11614
11949
|
onSubmit,
|
|
11615
11950
|
onToggleHelp,
|
|
@@ -11621,18 +11956,18 @@ function CheckpointPrompt({
|
|
|
11621
11956
|
recap,
|
|
11622
11957
|
isReviewing = false
|
|
11623
11958
|
}) {
|
|
11624
|
-
const [value, setValue] =
|
|
11625
|
-
const [remaining, setRemaining] =
|
|
11626
|
-
const [isTyping, setIsTyping] =
|
|
11627
|
-
const [showModelPicker, setShowModelPicker] =
|
|
11628
|
-
const [showReflectEditor, setShowReflectEditor] =
|
|
11629
|
-
const [showCommandPicker, setShowCommandPicker] =
|
|
11630
|
-
const [pendingModel, setPendingModel] =
|
|
11631
|
-
const [pendingSandbox, setPendingSandbox] =
|
|
11632
|
-
const [pendingToolsToggle, setPendingToolsToggle] =
|
|
11633
|
-
const [pendingStop, setPendingStop] =
|
|
11959
|
+
const [value, setValue] = useState18("");
|
|
11960
|
+
const [remaining, setRemaining] = useState18(timeout);
|
|
11961
|
+
const [isTyping, setIsTyping] = useState18(false);
|
|
11962
|
+
const [showModelPicker, setShowModelPicker] = useState18(false);
|
|
11963
|
+
const [showReflectEditor, setShowReflectEditor] = useState18(false);
|
|
11964
|
+
const [showCommandPicker, setShowCommandPicker] = useState18(false);
|
|
11965
|
+
const [pendingModel, setPendingModel] = useState18(void 0);
|
|
11966
|
+
const [pendingSandbox, setPendingSandbox] = useState18(void 0);
|
|
11967
|
+
const [pendingToolsToggle, setPendingToolsToggle] = useState18(false);
|
|
11968
|
+
const [pendingStop, setPendingStop] = useState18(false);
|
|
11634
11969
|
const timerRef = useRef7(null);
|
|
11635
|
-
const separator =
|
|
11970
|
+
const separator = theme23.separator ?? " \xB7 ";
|
|
11636
11971
|
const hasPendingChanges = pendingModel !== void 0 || pendingSandbox !== void 0 || pendingToolsToggle || pendingStop;
|
|
11637
11972
|
const clearInputDraft = () => {
|
|
11638
11973
|
setValue("");
|
|
@@ -11656,7 +11991,7 @@ function CheckpointPrompt({
|
|
|
11656
11991
|
resetDraft();
|
|
11657
11992
|
onSubmit(result);
|
|
11658
11993
|
};
|
|
11659
|
-
|
|
11994
|
+
useEffect16(() => {
|
|
11660
11995
|
const title = "Marathon";
|
|
11661
11996
|
const body = isTerminal ? "Marathon complete" : `Session ${recap?.sessionNumber ?? "?"} complete`;
|
|
11662
11997
|
process.stderr.write(`\x1B]777;notify;${title};${body}\x07`);
|
|
@@ -11676,7 +12011,7 @@ function CheckpointPrompt({
|
|
|
11676
12011
|
setIsTyping(false);
|
|
11677
12012
|
}
|
|
11678
12013
|
};
|
|
11679
|
-
|
|
12014
|
+
useEffect16(() => {
|
|
11680
12015
|
if (shouldPauseCheckpointTimer({
|
|
11681
12016
|
isTerminal,
|
|
11682
12017
|
timeout,
|
|
@@ -11821,43 +12156,43 @@ ${trimmed}` : trimmed);
|
|
|
11821
12156
|
if (isTerminal) return "Enter: exit";
|
|
11822
12157
|
return "Enter: continue";
|
|
11823
12158
|
})();
|
|
11824
|
-
return /* @__PURE__ */
|
|
11825
|
-
showCommandPicker ? /* @__PURE__ */
|
|
12159
|
+
return /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", flexShrink: 0, children: [
|
|
12160
|
+
showCommandPicker ? /* @__PURE__ */ jsx24(
|
|
11826
12161
|
CommandPicker,
|
|
11827
12162
|
{
|
|
11828
12163
|
onSelect: handleCommandSelect,
|
|
11829
12164
|
onCancel: handleCommandCancel
|
|
11830
12165
|
}
|
|
11831
|
-
) : showModelPicker ? /* @__PURE__ */
|
|
12166
|
+
) : showModelPicker ? /* @__PURE__ */ jsx24(
|
|
11832
12167
|
ModelPicker,
|
|
11833
12168
|
{
|
|
11834
12169
|
currentModel,
|
|
11835
12170
|
onSelect: handleModelSelect,
|
|
11836
12171
|
onCancel: handleModelCancel
|
|
11837
12172
|
}
|
|
11838
|
-
) : showReflectEditor ? /* @__PURE__ */
|
|
12173
|
+
) : showReflectEditor ? /* @__PURE__ */ jsx24(
|
|
11839
12174
|
ReflectEditor,
|
|
11840
12175
|
{
|
|
11841
12176
|
onSubmit: handleReflectSubmit,
|
|
11842
12177
|
onCancel: handleReflectCancel
|
|
11843
12178
|
}
|
|
11844
|
-
) : /* @__PURE__ */
|
|
11845
|
-
|
|
12179
|
+
) : /* @__PURE__ */ jsxs20(
|
|
12180
|
+
Box21,
|
|
11846
12181
|
{
|
|
11847
12182
|
borderStyle: "bold",
|
|
11848
12183
|
borderLeft: true,
|
|
11849
12184
|
borderRight: false,
|
|
11850
12185
|
borderTop: false,
|
|
11851
12186
|
borderBottom: false,
|
|
11852
|
-
borderColor:
|
|
11853
|
-
backgroundColor:
|
|
12187
|
+
borderColor: theme23.accent,
|
|
12188
|
+
backgroundColor: theme23.backgroundDeep,
|
|
11854
12189
|
flexDirection: "column",
|
|
11855
12190
|
paddingX: 1,
|
|
11856
12191
|
paddingY: 1,
|
|
11857
12192
|
children: [
|
|
11858
|
-
/* @__PURE__ */
|
|
11859
|
-
/* @__PURE__ */
|
|
11860
|
-
/* @__PURE__ */
|
|
12193
|
+
/* @__PURE__ */ jsxs20(Box21, { children: [
|
|
12194
|
+
/* @__PURE__ */ jsx24(Text23, { color: theme23.accentActive, children: "> " }),
|
|
12195
|
+
/* @__PURE__ */ jsx24(Box21, { flexGrow: 1, children: /* @__PURE__ */ jsx24(
|
|
11861
12196
|
BlinkingTextInput,
|
|
11862
12197
|
{
|
|
11863
12198
|
value,
|
|
@@ -11866,100 +12201,383 @@ ${trimmed}` : trimmed);
|
|
|
11866
12201
|
placeholder: isTerminal ? "Send new instructions to continue marathon, or press enter to exit..." : "Guide next iteration..."
|
|
11867
12202
|
}
|
|
11868
12203
|
) }),
|
|
11869
|
-
countdownText && /* @__PURE__ */
|
|
12204
|
+
countdownText && /* @__PURE__ */ jsxs20(Text23, { color: theme23.textSubtle, children: [
|
|
12205
|
+
" ",
|
|
12206
|
+
countdownText
|
|
12207
|
+
] })
|
|
12208
|
+
] }),
|
|
12209
|
+
/* @__PURE__ */ jsx24(Text23, { color: theme23.textSubtle, children: [
|
|
12210
|
+
enterHint,
|
|
12211
|
+
"/: commands",
|
|
12212
|
+
"/help"
|
|
12213
|
+
].join(separator) }),
|
|
12214
|
+
pendingSummary.length > 0 && /* @__PURE__ */ jsx24(Text23, { color: theme23.textMuted, children: `Pending: ${pendingSummary.join(separator)}` })
|
|
12215
|
+
]
|
|
12216
|
+
}
|
|
12217
|
+
),
|
|
12218
|
+
/* @__PURE__ */ jsx24(CheckpointRecap, { ...recap, isTerminal })
|
|
12219
|
+
] });
|
|
12220
|
+
}
|
|
12221
|
+
|
|
12222
|
+
// src/ink/marathon/SessionActionMenu.tsx
|
|
12223
|
+
import { Box as Box22, Text as Text24, useInput as useInput10 } from "ink";
|
|
12224
|
+
import { theme as theme24 } from "@runtypelabs/ink-components";
|
|
12225
|
+
import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
|
|
12226
|
+
var MENU_ITEMS = [
|
|
12227
|
+
{ key: "c", label: "Copy session JSON" },
|
|
12228
|
+
{ key: "o", label: "Open session JSON in editor" },
|
|
12229
|
+
{ key: "f", label: "Open marathon folder in file manager" },
|
|
12230
|
+
{ key: "d", label: "Open agent in Runtype dashboard" }
|
|
12231
|
+
];
|
|
12232
|
+
function SessionActionMenu({
|
|
12233
|
+
onCopySession,
|
|
12234
|
+
onOpenStateFile,
|
|
12235
|
+
onOpenFolder,
|
|
12236
|
+
onOpenDashboard,
|
|
12237
|
+
onClose,
|
|
12238
|
+
hasDashboard,
|
|
12239
|
+
hasStateFile
|
|
12240
|
+
}) {
|
|
12241
|
+
useInput10((input, key) => {
|
|
12242
|
+
if (key.escape) {
|
|
12243
|
+
onClose();
|
|
12244
|
+
return;
|
|
12245
|
+
}
|
|
12246
|
+
if (input === "c") {
|
|
12247
|
+
onCopySession();
|
|
12248
|
+
return;
|
|
12249
|
+
}
|
|
12250
|
+
if (input === "o" && hasStateFile) {
|
|
12251
|
+
onOpenStateFile();
|
|
12252
|
+
return;
|
|
12253
|
+
}
|
|
12254
|
+
if (input === "f" && hasStateFile) {
|
|
12255
|
+
onOpenFolder();
|
|
12256
|
+
return;
|
|
12257
|
+
}
|
|
12258
|
+
if (input === "d" && hasDashboard) {
|
|
12259
|
+
onOpenDashboard();
|
|
12260
|
+
return;
|
|
12261
|
+
}
|
|
12262
|
+
});
|
|
12263
|
+
return /* @__PURE__ */ jsxs21(
|
|
12264
|
+
Box22,
|
|
12265
|
+
{
|
|
12266
|
+
flexDirection: "column",
|
|
12267
|
+
borderStyle: "round",
|
|
12268
|
+
borderColor: theme24.accent,
|
|
12269
|
+
backgroundColor: theme24.surfaceElevated,
|
|
12270
|
+
paddingX: 2,
|
|
12271
|
+
paddingY: 1,
|
|
12272
|
+
width: 50,
|
|
12273
|
+
children: [
|
|
12274
|
+
/* @__PURE__ */ jsx25(Text24, { bold: true, color: theme24.accent, children: "Session" }),
|
|
12275
|
+
/* @__PURE__ */ jsx25(Box22, { flexDirection: "column", marginTop: 1, children: MENU_ITEMS.map((item) => {
|
|
12276
|
+
const dimmed = item.key === "o" && !hasStateFile || item.key === "f" && !hasStateFile || item.key === "d" && !hasDashboard;
|
|
12277
|
+
return /* @__PURE__ */ jsxs21(Text24, { children: [
|
|
12278
|
+
/* @__PURE__ */ jsx25(Text24, { color: dimmed ? theme24.textSubtle : theme24.accentActive, children: ` ${item.key} ` }),
|
|
12279
|
+
/* @__PURE__ */ jsx25(Text24, { color: dimmed ? theme24.textSubtle : theme24.textMuted, children: item.label })
|
|
12280
|
+
] }, item.key);
|
|
12281
|
+
}) }),
|
|
12282
|
+
/* @__PURE__ */ jsxs21(Box22, { marginTop: 1, children: [
|
|
12283
|
+
/* @__PURE__ */ jsx25(Text24, { color: theme24.info, children: "Esc" }),
|
|
12284
|
+
/* @__PURE__ */ jsx25(Text24, { color: theme24.muted, children: " to close" })
|
|
12285
|
+
] })
|
|
12286
|
+
]
|
|
12287
|
+
}
|
|
12288
|
+
);
|
|
12289
|
+
}
|
|
12290
|
+
|
|
12291
|
+
// src/ink/marathon/UpgradeModal.tsx
|
|
12292
|
+
import { Box as Box23, Text as Text25 } from "ink";
|
|
12293
|
+
import { theme as theme25 } from "@runtypelabs/ink-components";
|
|
12294
|
+
import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
12295
|
+
function UpgradeModal({ prompt, width }) {
|
|
12296
|
+
return /* @__PURE__ */ jsxs22(
|
|
12297
|
+
Box23,
|
|
12298
|
+
{
|
|
12299
|
+
width,
|
|
12300
|
+
flexDirection: "column",
|
|
12301
|
+
borderStyle: "round",
|
|
12302
|
+
borderColor: theme25.warning,
|
|
12303
|
+
backgroundColor: theme25.surfaceElevated,
|
|
12304
|
+
paddingX: 2,
|
|
12305
|
+
paddingY: 1,
|
|
12306
|
+
children: [
|
|
12307
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.warning, bold: true, children: "Upgrade available" }),
|
|
12308
|
+
/* @__PURE__ */ jsx26(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx26(Text25, { color: theme25.label, children: prompt.message }) }),
|
|
12309
|
+
(prompt.code || prompt.limitType || prompt.retryAfter) && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", marginTop: 1, children: [
|
|
12310
|
+
prompt.code && /* @__PURE__ */ jsxs22(Text25, { color: theme25.muted, children: [
|
|
12311
|
+
"Code: ",
|
|
12312
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.label, children: prompt.code })
|
|
12313
|
+
] }),
|
|
12314
|
+
prompt.limitType && /* @__PURE__ */ jsxs22(Text25, { color: theme25.muted, children: [
|
|
12315
|
+
"Limit: ",
|
|
12316
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.label, children: prompt.limitType })
|
|
12317
|
+
] }),
|
|
12318
|
+
prompt.retryAfter && /* @__PURE__ */ jsxs22(Text25, { color: theme25.muted, children: [
|
|
12319
|
+
"Retry after: ",
|
|
12320
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.label, children: prompt.retryAfter })
|
|
12321
|
+
] })
|
|
12322
|
+
] }),
|
|
12323
|
+
/* @__PURE__ */ jsxs22(Box23, { marginTop: 1, children: [
|
|
12324
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.info, children: "Enter" }),
|
|
12325
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.muted, children: " open billing " }),
|
|
12326
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.info, children: "Esc" }),
|
|
12327
|
+
/* @__PURE__ */ jsx26(Text25, { color: theme25.muted, children: " close" })
|
|
12328
|
+
] }),
|
|
12329
|
+
/* @__PURE__ */ jsx26(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx26(Text25, { color: theme25.dimLabel, children: "Opens your dashboard billing page" }) })
|
|
12330
|
+
]
|
|
12331
|
+
}
|
|
12332
|
+
);
|
|
12333
|
+
}
|
|
12334
|
+
|
|
12335
|
+
// src/ink/marathon/OverviewActivityPane.tsx
|
|
12336
|
+
import { memo as memo4 } from "react";
|
|
12337
|
+
import { Box as Box25 } from "ink";
|
|
12338
|
+
import { theme as theme27 } from "@runtypelabs/ink-components";
|
|
12339
|
+
|
|
12340
|
+
// src/ink/marathon/ToolPanel.tsx
|
|
12341
|
+
import { useState as useState19, useEffect as useEffect17, useMemo as useMemo10, memo as memo3 } from "react";
|
|
12342
|
+
import { Box as Box24, Text as Text26 } from "ink";
|
|
12343
|
+
import { Spinner as Spinner5, theme as theme26 } from "@runtypelabs/ink-components";
|
|
12344
|
+
import { Fragment as Fragment2, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
12345
|
+
var TOOL_PANEL_TIMER_MS = 500;
|
|
12346
|
+
function formatCharCount2(chars) {
|
|
12347
|
+
if (chars >= 1e3) {
|
|
12348
|
+
return `${(chars / 1e3).toFixed(1)}k chars`;
|
|
12349
|
+
}
|
|
12350
|
+
return `${chars} chars`;
|
|
12351
|
+
}
|
|
12352
|
+
var STATUS_ICONS2 = {
|
|
12353
|
+
complete: "\u2713",
|
|
12354
|
+
error: "\u2717"
|
|
12355
|
+
};
|
|
12356
|
+
var FILE_TYPE_ICONS = {
|
|
12357
|
+
written: "\u270E",
|
|
12358
|
+
read: "\u2022",
|
|
12359
|
+
plan: "\u2691"
|
|
12360
|
+
};
|
|
12361
|
+
function formatElapsed2(tool, now) {
|
|
12362
|
+
if (tool.executionTime != null) {
|
|
12363
|
+
return `${(tool.executionTime / 1e3).toFixed(1)}s`;
|
|
12364
|
+
}
|
|
12365
|
+
const startedAt = tool.localExecutionStartedAt ?? tool.startedAt;
|
|
12366
|
+
return `${((now - startedAt) / 1e3).toFixed(1)}s`;
|
|
12367
|
+
}
|
|
12368
|
+
function getStatusColor2(status) {
|
|
12369
|
+
if (status === "error") return theme26.danger;
|
|
12370
|
+
if (status === "complete") return theme26.success;
|
|
12371
|
+
return theme26.accent;
|
|
12372
|
+
}
|
|
12373
|
+
function getPhaseLabel2(tool) {
|
|
12374
|
+
if (tool.status === "complete") return "complete";
|
|
12375
|
+
if (tool.status === "error") return "error";
|
|
12376
|
+
if (tool.phase === "input_streaming") return "assembling input";
|
|
12377
|
+
if (tool.phase === "executing_locally") return "executing locally";
|
|
12378
|
+
return "running";
|
|
12379
|
+
}
|
|
12380
|
+
function toolsFingerprint(tools) {
|
|
12381
|
+
const tail = tools.length <= 10 ? tools : tools.slice(-10);
|
|
12382
|
+
let fp = String(tools.length);
|
|
12383
|
+
for (const t of tail) {
|
|
12384
|
+
fp += `|${t.id}:${t.name}:${t.status}:${t.phase ?? ""}:${t.inputPreview ?? ""}`;
|
|
12385
|
+
}
|
|
12386
|
+
return fp;
|
|
12387
|
+
}
|
|
12388
|
+
function filesFingerprint(files) {
|
|
12389
|
+
if (!files || files.length === 0) return "0";
|
|
12390
|
+
const tail = files.length <= 10 ? files : files.slice(-10);
|
|
12391
|
+
let fp = String(files.length);
|
|
12392
|
+
for (const file of tail) {
|
|
12393
|
+
fp += `|${file.path}:${file.type}`;
|
|
12394
|
+
}
|
|
12395
|
+
return fp;
|
|
12396
|
+
}
|
|
12397
|
+
var ToolPanel = memo3(function ToolPanel2({
|
|
12398
|
+
tools,
|
|
12399
|
+
reasoningCharCount = 0,
|
|
12400
|
+
files,
|
|
12401
|
+
maxHeight
|
|
12402
|
+
}) {
|
|
12403
|
+
const [now, setNow] = useState19(Date.now());
|
|
12404
|
+
const hasRunning = tools.some((t) => t.status === "running");
|
|
12405
|
+
useEffect17(() => {
|
|
12406
|
+
if (!hasRunning) return;
|
|
12407
|
+
const interval = setInterval(() => setNow(Date.now()), TOOL_PANEL_TIMER_MS);
|
|
12408
|
+
return () => clearInterval(interval);
|
|
12409
|
+
}, [hasRunning]);
|
|
12410
|
+
const { visibleTools, visibleFiles } = useMemo10(() => {
|
|
12411
|
+
if (!maxHeight) return { visibleTools: tools, visibleFiles: files || [] };
|
|
12412
|
+
const reasoningRows = reasoningCharCount > 0 ? 1 : 0;
|
|
12413
|
+
const headerRows = 1;
|
|
12414
|
+
const filesList = files || [];
|
|
12415
|
+
const fileHeaderRows = filesList.length > 0 ? 2 : 0;
|
|
12416
|
+
const availableRows = maxHeight - headerRows - reasoningRows - fileHeaderRows;
|
|
12417
|
+
const fileRows = filesList.length > 0 ? Math.min(filesList.length, Math.max(3, Math.floor(availableRows * 0.3))) : 0;
|
|
12418
|
+
const toolRows = Math.max(1, availableRows - fileRows);
|
|
12419
|
+
const toolSlots = Math.floor(toolRows / 2);
|
|
12420
|
+
const vTools = tools.length <= toolSlots ? tools : tools.slice(-toolSlots);
|
|
12421
|
+
const vFiles = filesList.length <= fileRows ? filesList : filesList.slice(-fileRows);
|
|
12422
|
+
return { visibleTools: vTools, visibleFiles: vFiles };
|
|
12423
|
+
}, [tools, files, maxHeight, reasoningCharCount]);
|
|
12424
|
+
const hiddenToolCount = tools.length - visibleTools.length;
|
|
12425
|
+
const hiddenFileCount = (files || []).length - visibleFiles.length;
|
|
12426
|
+
return /* @__PURE__ */ jsxs23(Box24, { flexDirection: "column", backgroundColor: theme26.background, children: [
|
|
12427
|
+
/* @__PURE__ */ jsx27(Text26, { bold: true, color: theme26.accent, children: "Activity" }),
|
|
12428
|
+
reasoningCharCount > 0 && /* @__PURE__ */ jsxs23(Text26, { color: theme26.textMuted, children: [
|
|
12429
|
+
"Reasoning: ",
|
|
12430
|
+
formatCharCount2(reasoningCharCount)
|
|
12431
|
+
] }),
|
|
12432
|
+
hiddenToolCount > 0 && /* @__PURE__ */ jsxs23(Text26, { color: theme26.textSubtle, children: [
|
|
12433
|
+
" ",
|
|
12434
|
+
hiddenToolCount,
|
|
12435
|
+
" earlier hidden"
|
|
12436
|
+
] }),
|
|
12437
|
+
visibleTools.map((tool) => {
|
|
12438
|
+
const statusColor = getStatusColor2(tool.status);
|
|
12439
|
+
const elapsed = formatElapsed2(tool, now);
|
|
12440
|
+
const phaseLabel = getPhaseLabel2(tool);
|
|
12441
|
+
return /* @__PURE__ */ jsxs23(Box24, { flexDirection: "column", children: [
|
|
12442
|
+
/* @__PURE__ */ jsxs23(Box24, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
12443
|
+
/* @__PURE__ */ jsx27(Box24, { width: 2, flexShrink: 0, children: tool.status === "running" ? /* @__PURE__ */ jsx27(Spinner5, { label: "", color: theme26.spinner }) : /* @__PURE__ */ jsx27(Text26, { color: statusColor, children: STATUS_ICONS2[tool.status] || "?" }) }),
|
|
12444
|
+
/* @__PURE__ */ jsx27(Box24, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx27(Text26, { color: theme26.text, wrap: "truncate", children: tool.name }) }),
|
|
12445
|
+
/* @__PURE__ */ jsxs23(Box24, { flexShrink: 0, children: [
|
|
12446
|
+
/* @__PURE__ */ jsxs23(Text26, { color: theme26.textSubtle, children: [
|
|
11870
12447
|
" ",
|
|
11871
|
-
|
|
12448
|
+
phaseLabel
|
|
12449
|
+
] }),
|
|
12450
|
+
/* @__PURE__ */ jsxs23(Text26, { color: theme26.textMuted, children: [
|
|
12451
|
+
" ",
|
|
12452
|
+
elapsed
|
|
11872
12453
|
] })
|
|
11873
|
-
] })
|
|
11874
|
-
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
|
|
11878
|
-
|
|
11879
|
-
|
|
11880
|
-
|
|
11881
|
-
|
|
11882
|
-
|
|
11883
|
-
|
|
12454
|
+
] })
|
|
12455
|
+
] }),
|
|
12456
|
+
/* @__PURE__ */ jsxs23(Box24, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
12457
|
+
/* @__PURE__ */ jsx27(Box24, { width: 2, flexShrink: 0 }),
|
|
12458
|
+
/* @__PURE__ */ jsx27(Text26, { color: theme26.textSubtle, children: "\u2514 " }),
|
|
12459
|
+
/* @__PURE__ */ jsx27(Box24, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx27(Text26, { color: theme26.textMuted, wrap: "truncate", children: tool.inputPreview || "" }) })
|
|
12460
|
+
] })
|
|
12461
|
+
] }, tool.id);
|
|
12462
|
+
}),
|
|
12463
|
+
visibleFiles.length > 0 && /* @__PURE__ */ jsxs23(Fragment2, { children: [
|
|
12464
|
+
/* @__PURE__ */ jsxs23(Box24, { marginTop: 1, children: [
|
|
12465
|
+
/* @__PURE__ */ jsx27(Text26, { bold: true, color: theme26.accent, children: "Files" }),
|
|
12466
|
+
hiddenFileCount > 0 && /* @__PURE__ */ jsxs23(Text26, { color: theme26.textSubtle, children: [
|
|
12467
|
+
" +",
|
|
12468
|
+
hiddenFileCount
|
|
12469
|
+
] })
|
|
12470
|
+
] }),
|
|
12471
|
+
visibleFiles.map((file) => {
|
|
12472
|
+
const icon = FILE_TYPE_ICONS[file.type] || "\u2022";
|
|
12473
|
+
const filename = file.path.split("/").pop() || file.path;
|
|
12474
|
+
return /* @__PURE__ */ jsxs23(Box24, { flexDirection: "row", flexWrap: "nowrap", children: [
|
|
12475
|
+
/* @__PURE__ */ jsx27(Box24, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx27(Text26, { color: file.type === "written" ? theme26.success : theme26.textMuted, children: icon }) }),
|
|
12476
|
+
/* @__PURE__ */ jsx27(Box24, { flexShrink: 1, children: /* @__PURE__ */ jsx27(Text26, { color: theme26.text, wrap: "truncate", children: filename }) })
|
|
12477
|
+
] }, file.path);
|
|
12478
|
+
})
|
|
12479
|
+
] })
|
|
11884
12480
|
] });
|
|
11885
|
-
}
|
|
12481
|
+
}, (prev, next) => {
|
|
12482
|
+
return toolsFingerprint(prev.tools) === toolsFingerprint(next.tools) && prev.maxHeight === next.maxHeight && (prev.reasoningCharCount ?? 0) === (next.reasoningCharCount ?? 0) && filesFingerprint(prev.files) === filesFingerprint(next.files);
|
|
12483
|
+
});
|
|
11886
12484
|
|
|
11887
|
-
// src/ink/marathon/
|
|
11888
|
-
import {
|
|
11889
|
-
|
|
11890
|
-
|
|
11891
|
-
|
|
11892
|
-
|
|
11893
|
-
|
|
11894
|
-
|
|
11895
|
-
|
|
11896
|
-
];
|
|
11897
|
-
function SessionActionMenu({
|
|
11898
|
-
onCopySession,
|
|
11899
|
-
onOpenStateFile,
|
|
11900
|
-
onOpenFolder,
|
|
11901
|
-
onOpenDashboard,
|
|
11902
|
-
onClose,
|
|
11903
|
-
hasDashboard,
|
|
11904
|
-
hasStateFile
|
|
12485
|
+
// src/ink/marathon/OverviewActivityPane.tsx
|
|
12486
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
12487
|
+
var OverviewActivityPane = memo4(function OverviewActivityPane2({
|
|
12488
|
+
tools,
|
|
12489
|
+
reasoningCharCount,
|
|
12490
|
+
files,
|
|
12491
|
+
maxHeight,
|
|
12492
|
+
stacked = false,
|
|
12493
|
+
width
|
|
11905
12494
|
}) {
|
|
11906
|
-
|
|
11907
|
-
|
|
11908
|
-
onClose();
|
|
11909
|
-
return;
|
|
11910
|
-
}
|
|
11911
|
-
if (input === "c") {
|
|
11912
|
-
onCopySession();
|
|
11913
|
-
return;
|
|
11914
|
-
}
|
|
11915
|
-
if (input === "o" && hasStateFile) {
|
|
11916
|
-
onOpenStateFile();
|
|
11917
|
-
return;
|
|
11918
|
-
}
|
|
11919
|
-
if (input === "f" && hasStateFile) {
|
|
11920
|
-
onOpenFolder();
|
|
11921
|
-
return;
|
|
11922
|
-
}
|
|
11923
|
-
if (input === "d" && hasDashboard) {
|
|
11924
|
-
onOpenDashboard();
|
|
11925
|
-
return;
|
|
11926
|
-
}
|
|
11927
|
-
});
|
|
11928
|
-
return /* @__PURE__ */ jsxs22(
|
|
11929
|
-
Box23,
|
|
12495
|
+
return /* @__PURE__ */ jsx28(
|
|
12496
|
+
Box25,
|
|
11930
12497
|
{
|
|
11931
12498
|
flexDirection: "column",
|
|
11932
|
-
|
|
11933
|
-
|
|
11934
|
-
|
|
11935
|
-
|
|
11936
|
-
|
|
11937
|
-
|
|
11938
|
-
|
|
11939
|
-
|
|
11940
|
-
|
|
11941
|
-
|
|
11942
|
-
|
|
11943
|
-
|
|
11944
|
-
|
|
11945
|
-
|
|
11946
|
-
}
|
|
11947
|
-
|
|
11948
|
-
/* @__PURE__ */ jsx28(Text25, { color: theme27.info, children: "Esc" }),
|
|
11949
|
-
/* @__PURE__ */ jsx28(Text25, { color: theme27.muted, children: " to close" })
|
|
11950
|
-
] })
|
|
11951
|
-
]
|
|
12499
|
+
width: stacked ? void 0 : width,
|
|
12500
|
+
flexShrink: 0,
|
|
12501
|
+
borderStyle: "single",
|
|
12502
|
+
borderColor: theme27.border,
|
|
12503
|
+
backgroundColor: theme27.background,
|
|
12504
|
+
paddingX: theme27.panelPaddingX,
|
|
12505
|
+
paddingY: theme27.panelPaddingY,
|
|
12506
|
+
children: /* @__PURE__ */ jsx28(
|
|
12507
|
+
ToolPanel,
|
|
12508
|
+
{
|
|
12509
|
+
tools,
|
|
12510
|
+
reasoningCharCount,
|
|
12511
|
+
files,
|
|
12512
|
+
maxHeight
|
|
12513
|
+
}
|
|
12514
|
+
)
|
|
11952
12515
|
}
|
|
11953
12516
|
);
|
|
12517
|
+
});
|
|
12518
|
+
|
|
12519
|
+
// src/ink/marathon/OverviewTranscriptPane.tsx
|
|
12520
|
+
import { memo as memo5 } from "react";
|
|
12521
|
+
import { Box as Box27 } from "ink";
|
|
12522
|
+
import { StreamOutput, ErrorDisplay as ErrorDisplay3 } from "@runtypelabs/ink-components";
|
|
12523
|
+
import { LoadingAnimation } from "@runtypelabs/terminal-animations";
|
|
12524
|
+
|
|
12525
|
+
// src/ink/marathon/ThinkingIndicator.tsx
|
|
12526
|
+
import { useState as useState20, useEffect as useEffect18 } from "react";
|
|
12527
|
+
import { Spinner as Spinner6, theme as theme28 } from "@runtypelabs/ink-components";
|
|
12528
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
12529
|
+
function ThinkingIndicator({ startedAt }) {
|
|
12530
|
+
const [elapsed, setElapsed] = useState20(
|
|
12531
|
+
() => startedAt ? Math.floor((Date.now() - startedAt) / 1e3) : 0
|
|
12532
|
+
);
|
|
12533
|
+
useEffect18(() => {
|
|
12534
|
+
const start = startedAt ?? Date.now();
|
|
12535
|
+
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
12536
|
+
const interval = setInterval(() => {
|
|
12537
|
+
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
12538
|
+
}, 1e3);
|
|
12539
|
+
return () => clearInterval(interval);
|
|
12540
|
+
}, [startedAt]);
|
|
12541
|
+
return /* @__PURE__ */ jsx29(Spinner6, { label: `Thinking... ${elapsed}s`, color: theme28.textMuted });
|
|
12542
|
+
}
|
|
12543
|
+
|
|
12544
|
+
// src/ink/marathon/ContextCompactionIndicator.tsx
|
|
12545
|
+
import { useEffect as useEffect19, useState as useState21 } from "react";
|
|
12546
|
+
import { Spinner as Spinner7, theme as theme29 } from "@runtypelabs/ink-components";
|
|
12547
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
12548
|
+
function buildCompactionLabel(compaction, elapsedSeconds) {
|
|
12549
|
+
const modeLabel = compaction.mode === "auto" ? "auto" : "manual";
|
|
12550
|
+
const strategyLabel = compaction.strategy === "provider_native" ? "native" : "summary";
|
|
12551
|
+
const thresholdLabel = formatCompactionThresholdLabel(compaction);
|
|
12552
|
+
if (thresholdLabel) {
|
|
12553
|
+
return `Compacting context for session ${compaction.sessionIndex} (${modeLabel}, ${strategyLabel}, ${thresholdLabel})... ${elapsedSeconds}s`;
|
|
12554
|
+
}
|
|
12555
|
+
return `Compacting context for session ${compaction.sessionIndex} (${modeLabel}, ${strategyLabel})... ${elapsedSeconds}s`;
|
|
12556
|
+
}
|
|
12557
|
+
function ContextCompactionIndicator({
|
|
12558
|
+
compaction
|
|
12559
|
+
}) {
|
|
12560
|
+
const [elapsed, setElapsed] = useState21(
|
|
12561
|
+
() => Math.floor((Date.now() - compaction.startedAt) / 1e3)
|
|
12562
|
+
);
|
|
12563
|
+
useEffect19(() => {
|
|
12564
|
+
const start = compaction.startedAt;
|
|
12565
|
+
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
12566
|
+
const interval = setInterval(() => {
|
|
12567
|
+
setElapsed(Math.floor((Date.now() - start) / 1e3));
|
|
12568
|
+
}, 1e3);
|
|
12569
|
+
return () => clearInterval(interval);
|
|
12570
|
+
}, [compaction.startedAt]);
|
|
12571
|
+
return /* @__PURE__ */ jsx30(Spinner7, { label: buildCompactionLabel(compaction, elapsed), color: theme29.warning });
|
|
11954
12572
|
}
|
|
11955
12573
|
|
|
11956
12574
|
// src/ink/marathon/ReasoningBlock.tsx
|
|
11957
|
-
import { Box as
|
|
11958
|
-
import { theme as
|
|
11959
|
-
import { jsx as
|
|
11960
|
-
var REASONING_LABEL_COLOR =
|
|
11961
|
-
var REASONING_TEXT_COLOR =
|
|
11962
|
-
var REASONING_HINT_COLOR =
|
|
12575
|
+
import { Box as Box26, Text as Text27 } from "ink";
|
|
12576
|
+
import { theme as theme30 } from "@runtypelabs/ink-components";
|
|
12577
|
+
import { jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
12578
|
+
var REASONING_LABEL_COLOR = theme30.accent;
|
|
12579
|
+
var REASONING_TEXT_COLOR = theme30.textMuted;
|
|
12580
|
+
var REASONING_HINT_COLOR = theme30.textSubtle;
|
|
11963
12581
|
function renderReasoningLine(line) {
|
|
11964
12582
|
return line ? `| ${line}` : "|";
|
|
11965
12583
|
}
|
|
@@ -11972,17 +12590,17 @@ function ReasoningBlock({
|
|
|
11972
12590
|
}) {
|
|
11973
12591
|
const label = collapsed ? "Reasoning hidden" : "Reasoning";
|
|
11974
12592
|
const hint = showToggleHint ? collapsed ? "r to show" : "r to hide" : null;
|
|
11975
|
-
return /* @__PURE__ */
|
|
11976
|
-
/* @__PURE__ */
|
|
11977
|
-
/* @__PURE__ */
|
|
11978
|
-
hint && /* @__PURE__ */
|
|
12593
|
+
return /* @__PURE__ */ jsxs24(Box26, { flexDirection: "column", children: [
|
|
12594
|
+
/* @__PURE__ */ jsxs24(Box26, { children: [
|
|
12595
|
+
/* @__PURE__ */ jsx31(Text27, { color: REASONING_LABEL_COLOR, children: label }),
|
|
12596
|
+
hint && /* @__PURE__ */ jsxs24(Text27, { color: REASONING_HINT_COLOR, children: [
|
|
11979
12597
|
" (",
|
|
11980
12598
|
hint,
|
|
11981
12599
|
")"
|
|
11982
12600
|
] })
|
|
11983
12601
|
] }),
|
|
11984
|
-
!collapsed && lines.map((line, index) => /* @__PURE__ */
|
|
11985
|
-
|
|
12602
|
+
!collapsed && lines.map((line, index) => /* @__PURE__ */ jsx31(
|
|
12603
|
+
Text27,
|
|
11986
12604
|
{
|
|
11987
12605
|
color: REASONING_TEXT_COLOR,
|
|
11988
12606
|
wrap: compact ? "truncate" : void 0,
|
|
@@ -11990,53 +12608,77 @@ function ReasoningBlock({
|
|
|
11990
12608
|
},
|
|
11991
12609
|
`${index}:${line}`
|
|
11992
12610
|
)),
|
|
11993
|
-
!collapsed && live && /* @__PURE__ */
|
|
12611
|
+
!collapsed && live && /* @__PURE__ */ jsx31(Text27, { color: REASONING_TEXT_COLOR, wrap: compact ? "truncate" : void 0, children: "| ..." })
|
|
11994
12612
|
] });
|
|
11995
12613
|
}
|
|
11996
12614
|
|
|
11997
|
-
// src/ink/marathon/
|
|
11998
|
-
import {
|
|
11999
|
-
|
|
12000
|
-
|
|
12001
|
-
|
|
12002
|
-
|
|
12003
|
-
|
|
12004
|
-
|
|
12005
|
-
|
|
12006
|
-
|
|
12007
|
-
|
|
12008
|
-
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
|
|
12013
|
-
|
|
12014
|
-
|
|
12015
|
-
|
|
12016
|
-
|
|
12017
|
-
|
|
12018
|
-
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
}
|
|
12038
|
-
|
|
12039
|
-
}
|
|
12615
|
+
// src/ink/marathon/OverviewTranscriptPane.tsx
|
|
12616
|
+
import { Fragment as Fragment3, jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
12617
|
+
var UPGRADE_BROWSE_HINT_LINES = [
|
|
12618
|
+
"Upgrade modal dismissed.",
|
|
12619
|
+
"Use Shift+Left/Right or 1-9 to review previous marathon runs."
|
|
12620
|
+
];
|
|
12621
|
+
var OverviewTranscriptPane = memo5(function OverviewTranscriptPane2({
|
|
12622
|
+
content,
|
|
12623
|
+
enableMarkdown,
|
|
12624
|
+
isStreaming,
|
|
12625
|
+
maxVisibleLines,
|
|
12626
|
+
scrollOffset,
|
|
12627
|
+
totalLines,
|
|
12628
|
+
paneWidth,
|
|
12629
|
+
contentHeight,
|
|
12630
|
+
showLoadingAnimation = false,
|
|
12631
|
+
hasReasoning = false,
|
|
12632
|
+
visibleReasoningLines = [],
|
|
12633
|
+
reasoningCollapsed = false,
|
|
12634
|
+
reasoningLive = false,
|
|
12635
|
+
showThinkingIndicator = false,
|
|
12636
|
+
thinkingStartedAt,
|
|
12637
|
+
contextCompaction = null,
|
|
12638
|
+
showUpgradeBrowseHint = false,
|
|
12639
|
+
error = null
|
|
12640
|
+
}) {
|
|
12641
|
+
if (showLoadingAnimation) {
|
|
12642
|
+
return /* @__PURE__ */ jsx32(Box27, { flexGrow: 1, minHeight: contentHeight, overflow: "hidden", children: /* @__PURE__ */ jsx32(LoadingAnimation, { width: paneWidth, height: contentHeight }) });
|
|
12643
|
+
}
|
|
12644
|
+
const maxScroll = Math.max(0, totalLines - maxVisibleLines);
|
|
12645
|
+
return /* @__PURE__ */ jsxs25(Fragment3, { children: [
|
|
12646
|
+
hasReasoning && /* @__PURE__ */ jsx32(Box27, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx32(
|
|
12647
|
+
ReasoningBlock,
|
|
12648
|
+
{
|
|
12649
|
+
lines: visibleReasoningLines,
|
|
12650
|
+
live: reasoningLive,
|
|
12651
|
+
collapsed: reasoningCollapsed,
|
|
12652
|
+
showToggleHint: true
|
|
12653
|
+
}
|
|
12654
|
+
) }),
|
|
12655
|
+
showThinkingIndicator && /* @__PURE__ */ jsx32(ThinkingIndicator, { startedAt: thinkingStartedAt }),
|
|
12656
|
+
contextCompaction && /* @__PURE__ */ jsx32(ContextCompactionIndicator, { compaction: contextCompaction }),
|
|
12657
|
+
showUpgradeBrowseHint && /* @__PURE__ */ jsx32(Box27, { marginBottom: 1, children: /* @__PURE__ */ jsx32(ReasoningBlock, { lines: UPGRADE_BROWSE_HINT_LINES, compact: true }) }),
|
|
12658
|
+
/* @__PURE__ */ jsxs25(Box27, { flexDirection: "row", children: [
|
|
12659
|
+
/* @__PURE__ */ jsx32(Box27, { flexDirection: "column", flexGrow: 1, marginRight: 1, children: /* @__PURE__ */ jsx32(
|
|
12660
|
+
StreamOutput,
|
|
12661
|
+
{
|
|
12662
|
+
content,
|
|
12663
|
+
isStreaming,
|
|
12664
|
+
enableMarkdown,
|
|
12665
|
+
maxVisibleLines,
|
|
12666
|
+
scrollOffset
|
|
12667
|
+
}
|
|
12668
|
+
) }),
|
|
12669
|
+
/* @__PURE__ */ jsx32(
|
|
12670
|
+
Scrollbar,
|
|
12671
|
+
{
|
|
12672
|
+
totalLines,
|
|
12673
|
+
visibleLines: maxVisibleLines,
|
|
12674
|
+
scrollOffset: maxScroll - Math.min(scrollOffset, maxScroll),
|
|
12675
|
+
height: maxVisibleLines
|
|
12676
|
+
}
|
|
12677
|
+
)
|
|
12678
|
+
] }),
|
|
12679
|
+
error && /* @__PURE__ */ jsx32(ErrorDisplay3, { error })
|
|
12680
|
+
] });
|
|
12681
|
+
});
|
|
12040
12682
|
|
|
12041
12683
|
// src/ink/marathon/upgrade-modal-utils.ts
|
|
12042
12684
|
var UPGRADE_LIMIT_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -12192,7 +12834,7 @@ function isAllowedCheckpointBrowseKey(key, isBrowsingScreen) {
|
|
|
12192
12834
|
}
|
|
12193
12835
|
|
|
12194
12836
|
// src/ink/marathon/MarathonApp.tsx
|
|
12195
|
-
import {
|
|
12837
|
+
import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
12196
12838
|
var TOOL_PANEL_WIDE = 48;
|
|
12197
12839
|
var TOOL_PANEL_NARROW = 36;
|
|
12198
12840
|
var NARROW_THRESHOLD = 100;
|
|
@@ -12211,22 +12853,23 @@ function cloneSessionSnapshot(snapshot) {
|
|
|
12211
12853
|
...tool.parameters ? { parameters: structuredClone(tool.parameters) } : {},
|
|
12212
12854
|
...tool.result !== void 0 ? { result: structuredClone(tool.result) } : {}
|
|
12213
12855
|
})),
|
|
12214
|
-
rawEvents: snapshot.rawEvents
|
|
12215
|
-
...event,
|
|
12216
|
-
data: structuredClone(event.data)
|
|
12217
|
-
}))
|
|
12856
|
+
rawEvents: [...snapshot.rawEvents]
|
|
12218
12857
|
};
|
|
12219
12858
|
}
|
|
12220
12859
|
function upsertSessionSnapshots(snapshots, nextSnapshot) {
|
|
12221
|
-
const
|
|
12222
|
-
|
|
12223
|
-
|
|
12224
|
-
|
|
12225
|
-
|
|
12226
|
-
|
|
12860
|
+
const cloned = cloneSessionSnapshot(nextSnapshot);
|
|
12861
|
+
const existingIndex = snapshots.findIndex((s) => s.sessionIndex === nextSnapshot.sessionIndex);
|
|
12862
|
+
if (existingIndex >= 0) {
|
|
12863
|
+
const result2 = [...snapshots];
|
|
12864
|
+
result2[existingIndex] = cloned;
|
|
12865
|
+
return result2;
|
|
12866
|
+
}
|
|
12867
|
+
const result = [...snapshots, cloned];
|
|
12868
|
+
result.sort((left, right) => left.sessionIndex - right.sessionIndex);
|
|
12869
|
+
return result;
|
|
12227
12870
|
}
|
|
12228
|
-
function buildLiveSessionSnapshot(liveState, sessionIndex, model) {
|
|
12229
|
-
const hasLiveState = liveState.phase === "thinking" || Boolean(liveState.content) || Boolean(liveState.reasoning) || liveState.tools.length > 0 ||
|
|
12871
|
+
function buildLiveSessionSnapshot(liveState, rawEvents, sessionIndex, model) {
|
|
12872
|
+
const hasLiveState = liveState.phase === "thinking" || Boolean(liveState.content) || Boolean(liveState.reasoning) || liveState.tools.length > 0 || rawEvents.length > 0 || Boolean(liveState.contextCompaction?.active);
|
|
12230
12873
|
if (!hasLiveState) return void 0;
|
|
12231
12874
|
return {
|
|
12232
12875
|
sessionIndex,
|
|
@@ -12235,15 +12878,8 @@ function buildLiveSessionSnapshot(liveState, sessionIndex, model) {
|
|
|
12235
12878
|
cost: liveState.totalCost,
|
|
12236
12879
|
content: liveState.content,
|
|
12237
12880
|
reasoning: liveState.reasoning,
|
|
12238
|
-
tools: liveState.tools
|
|
12239
|
-
|
|
12240
|
-
...tool.parameters ? { parameters: structuredClone(tool.parameters) } : {},
|
|
12241
|
-
...tool.result !== void 0 ? { result: structuredClone(tool.result) } : {}
|
|
12242
|
-
})),
|
|
12243
|
-
rawEvents: liveState.rawEvents.map((event) => ({
|
|
12244
|
-
...event,
|
|
12245
|
-
data: structuredClone(event.data)
|
|
12246
|
-
}))
|
|
12881
|
+
tools: liveState.tools,
|
|
12882
|
+
rawEvents
|
|
12247
12883
|
};
|
|
12248
12884
|
}
|
|
12249
12885
|
function copyToClipboard(text) {
|
|
@@ -12264,8 +12900,15 @@ function copyToClipboard(text) {
|
|
|
12264
12900
|
return false;
|
|
12265
12901
|
}
|
|
12266
12902
|
}
|
|
12903
|
+
function isBlank(s) {
|
|
12904
|
+
for (let i = 0; i < s.length; i++) {
|
|
12905
|
+
const c = s.charCodeAt(i);
|
|
12906
|
+
if (c !== 32 && c !== 9 && c !== 10 && c !== 13) return false;
|
|
12907
|
+
}
|
|
12908
|
+
return true;
|
|
12909
|
+
}
|
|
12267
12910
|
function shouldShowMarathonLoadingAnimation(params) {
|
|
12268
|
-
return params.allowInitialInlineLoader &&
|
|
12911
|
+
return params.allowInitialInlineLoader && isBlank(params.content) && isBlank(params.reasoning) && params.toolCount === 0 && (params.phase === "idle" || params.phase === "thinking");
|
|
12269
12912
|
}
|
|
12270
12913
|
function MarathonApp({
|
|
12271
12914
|
taskName,
|
|
@@ -12298,7 +12941,10 @@ function MarathonApp({
|
|
|
12298
12941
|
}) {
|
|
12299
12942
|
const {
|
|
12300
12943
|
state,
|
|
12944
|
+
rawEventsRef,
|
|
12301
12945
|
callbacks,
|
|
12946
|
+
getHydratedState,
|
|
12947
|
+
hydrateToolEntry,
|
|
12302
12948
|
reset: _reset,
|
|
12303
12949
|
setCheckpoint,
|
|
12304
12950
|
markPendingStart,
|
|
@@ -12311,7 +12957,7 @@ function MarathonApp({
|
|
|
12311
12957
|
} = useMarathonStream();
|
|
12312
12958
|
const { exit } = useApp4();
|
|
12313
12959
|
const { stdout } = useStdout5();
|
|
12314
|
-
const separator =
|
|
12960
|
+
const separator = theme31.separator ?? " \xB7 ";
|
|
12315
12961
|
const checkpointResolveRef = useRef8(null);
|
|
12316
12962
|
const [checkpointRecap, setCheckpointRecap] = useState22(null);
|
|
12317
12963
|
const [currentModel, setCurrentModel] = useState22(model || "default");
|
|
@@ -12364,7 +13010,7 @@ function MarathonApp({
|
|
|
12364
13010
|
useEffect20(() => {
|
|
12365
13011
|
streamRef.current = {
|
|
12366
13012
|
getCallbacks: () => callbacks,
|
|
12367
|
-
getState: () =>
|
|
13013
|
+
getState: () => getHydratedState(),
|
|
12368
13014
|
appendSessionSnapshot: (snapshot) => {
|
|
12369
13015
|
setSessionSnapshots((prev) => upsertSessionSnapshots(prev, snapshot));
|
|
12370
13016
|
const snapshotKey = createSessionTabKey(snapshot.sessionIndex);
|
|
@@ -12421,7 +13067,7 @@ function MarathonApp({
|
|
|
12421
13067
|
setCheckpoint,
|
|
12422
13068
|
showError,
|
|
12423
13069
|
startContextCompaction,
|
|
12424
|
-
|
|
13070
|
+
getHydratedState,
|
|
12425
13071
|
streamRef,
|
|
12426
13072
|
resetForNewSession
|
|
12427
13073
|
]);
|
|
@@ -12483,7 +13129,7 @@ function MarathonApp({
|
|
|
12483
13129
|
content: state.content,
|
|
12484
13130
|
reasoning: state.reasoning,
|
|
12485
13131
|
tools: state.tools,
|
|
12486
|
-
rawEvents:
|
|
13132
|
+
rawEvents: rawEventsRef.current
|
|
12487
13133
|
}, null, 2);
|
|
12488
13134
|
}
|
|
12489
13135
|
const ok = copyToClipboard(json);
|
|
@@ -12491,7 +13137,7 @@ function MarathonApp({
|
|
|
12491
13137
|
} catch {
|
|
12492
13138
|
showFlash("Copy failed");
|
|
12493
13139
|
}
|
|
12494
|
-
}, [sessionSnapshots, state.content, state.reasoning, state.tools,
|
|
13140
|
+
}, [sessionSnapshots, state.content, state.reasoning, state.tools, stateFilePath2]);
|
|
12495
13141
|
const handleOpenStateFile = useCallback8(() => {
|
|
12496
13142
|
setShowSessionMenu(false);
|
|
12497
13143
|
if (stateFilePath2 && fs4.existsSync(stateFilePath2)) {
|
|
@@ -12517,10 +13163,11 @@ function MarathonApp({
|
|
|
12517
13163
|
void open4(agentPageUrl);
|
|
12518
13164
|
}
|
|
12519
13165
|
}, [agentPageUrl]);
|
|
12520
|
-
const shouldShowLiveTab = Boolean(state.contextCompaction?.active) || state.phase !== "idle" && state.phase !== "checkpoint" && state.phase !== "complete" && (Boolean(state.content) || Boolean(state.reasoning) || state.tools.length > 0 ||
|
|
13166
|
+
const shouldShowLiveTab = Boolean(state.contextCompaction?.active) || state.phase !== "idle" && state.phase !== "checkpoint" && state.phase !== "complete" && (Boolean(state.content) || Boolean(state.reasoning) || state.tools.length > 0 || rawEventsRef.current.length > 0 || state.phase === "thinking" || state.phase === "error");
|
|
12521
13167
|
const liveSessionSnapshot = useMemo11(
|
|
12522
|
-
() => shouldShowLiveTab ? buildLiveSessionSnapshot(state, latestCompletedSessionIndex + 1, currentModel) : void 0,
|
|
13168
|
+
() => shouldShowLiveTab ? buildLiveSessionSnapshot(state, rawEventsRef.current, latestCompletedSessionIndex + 1, currentModel) : void 0,
|
|
12523
13169
|
[currentModel, latestCompletedSessionIndex, shouldShowLiveTab, state]
|
|
13170
|
+
// rawEventsRef.current is read directly — the memo re-evaluates because `state` changes on every event
|
|
12524
13171
|
);
|
|
12525
13172
|
const liveSessionKey = liveSessionSnapshot ? createSessionTabKey(liveSessionSnapshot.sessionIndex, "live") : void 0;
|
|
12526
13173
|
const latestSessionKey = getLatestSessionTabKey(sessionSnapshots, liveSessionSnapshot);
|
|
@@ -12544,26 +13191,63 @@ function MarathonApp({
|
|
|
12544
13191
|
const displayedContent = displayedSessionSnapshot?.content ?? state.content;
|
|
12545
13192
|
const displayedReasoning = displayedSessionSnapshot?.reasoning ?? state.reasoning;
|
|
12546
13193
|
const displayedTools = displayedSessionSnapshot?.tools ?? state.tools;
|
|
13194
|
+
const liveRawEvents = rawEventsRef.current;
|
|
12547
13195
|
const displayedEvents = useMemo11(() => {
|
|
12548
13196
|
const snapshotEvents = displayedSessionSnapshot?.rawEvents;
|
|
12549
13197
|
if (snapshotEvents && snapshotEvents.length > 0) return snapshotEvents;
|
|
12550
13198
|
if (displayedSessionSnapshot && displayedSessionSnapshot.status !== "live" && stateFilePath2 && snapshotEvents?.length === 0) {
|
|
12551
13199
|
return readSessionEventLog(stateFilePath2, displayedSessionSnapshot.sessionIndex);
|
|
12552
13200
|
}
|
|
12553
|
-
return snapshotEvents ??
|
|
12554
|
-
}, [displayedSessionSnapshot,
|
|
12555
|
-
const
|
|
12556
|
-
|
|
12557
|
-
|
|
12558
|
-
|
|
13201
|
+
return snapshotEvents ?? liveRawEvents;
|
|
13202
|
+
}, [displayedSessionSnapshot, liveRawEvents, stateFilePath2]);
|
|
13203
|
+
const seenTypesRef = useRef8({
|
|
13204
|
+
set: /* @__PURE__ */ new Set(),
|
|
13205
|
+
lastLen: 0,
|
|
13206
|
+
eventsRef: null
|
|
13207
|
+
});
|
|
13208
|
+
const seenEventTypes = useMemo11(() => {
|
|
13209
|
+
const cache = seenTypesRef.current;
|
|
13210
|
+
if (cache.eventsRef !== displayedEvents) {
|
|
13211
|
+
cache.set = /* @__PURE__ */ new Set();
|
|
13212
|
+
cache.lastLen = 0;
|
|
13213
|
+
cache.eventsRef = displayedEvents;
|
|
13214
|
+
}
|
|
13215
|
+
const prevSize = cache.set.size;
|
|
13216
|
+
for (let i = cache.lastLen; i < displayedEvents.length; i++) {
|
|
13217
|
+
cache.set.add(displayedEvents[i].type);
|
|
13218
|
+
}
|
|
13219
|
+
cache.lastLen = displayedEvents.length;
|
|
13220
|
+
if (cache.set.size !== prevSize || prevSize === 0) {
|
|
13221
|
+
return Array.from(cache.set).sort();
|
|
13222
|
+
}
|
|
13223
|
+
return void 0;
|
|
13224
|
+
}, [displayedEvents]);
|
|
13225
|
+
const stableSeenEventTypesRef = useRef8([]);
|
|
13226
|
+
if (seenEventTypes !== void 0) {
|
|
13227
|
+
stableSeenEventTypesRef.current = seenEventTypes;
|
|
13228
|
+
}
|
|
12559
13229
|
const filteredEvents = useMemo11(
|
|
12560
13230
|
() => eventTypeFilter.size === 0 ? displayedEvents : displayedEvents.filter((e) => eventTypeFilter.has(e.type)),
|
|
12561
13231
|
[displayedEvents, eventTypeFilter]
|
|
12562
13232
|
);
|
|
12563
|
-
const
|
|
12564
|
-
() =>
|
|
12565
|
-
[
|
|
13233
|
+
const fileToolFingerprint = useMemo11(
|
|
13234
|
+
() => displayedTools.filter((t) => t.name === "write_file" || t.name === "read_file").map((t) => `${t.id}:${t.name}:${String(t.parameters?.path ?? "")}:${t.startedAt}`).join("|"),
|
|
13235
|
+
[displayedTools]
|
|
12566
13236
|
);
|
|
13237
|
+
const trackedFilesCacheRef = useRef8({
|
|
13238
|
+
snapshots: null,
|
|
13239
|
+
fingerprint: "",
|
|
13240
|
+
planPath: void 0,
|
|
13241
|
+
value: []
|
|
13242
|
+
});
|
|
13243
|
+
const trackedFilesCache = trackedFilesCacheRef.current;
|
|
13244
|
+
if (trackedFilesCache.snapshots !== sessionSnapshots || trackedFilesCache.fingerprint !== fileToolFingerprint || trackedFilesCache.planPath !== planPath) {
|
|
13245
|
+
trackedFilesCache.snapshots = sessionSnapshots;
|
|
13246
|
+
trackedFilesCache.fingerprint = fileToolFingerprint;
|
|
13247
|
+
trackedFilesCache.planPath = planPath;
|
|
13248
|
+
trackedFilesCache.value = extractTrackedFiles(sessionSnapshots, displayedTools, planPath);
|
|
13249
|
+
}
|
|
13250
|
+
const trackedFiles = trackedFilesCache.value;
|
|
12567
13251
|
const latestLiveActivityRef = useRef8(void 0);
|
|
12568
13252
|
const upgradePrompt = useMemo11(() => parseMarathonUpgradePrompt(state.error), [state.error]);
|
|
12569
13253
|
const upgradePromptKey = useMemo11(
|
|
@@ -12614,7 +13298,7 @@ function MarathonApp({
|
|
|
12614
13298
|
setUpgradeModalDismissed(false);
|
|
12615
13299
|
}, [upgradePromptKey]);
|
|
12616
13300
|
useEffect20(() => {
|
|
12617
|
-
const liveActivityKey = liveSessionSnapshot ? `${liveSessionSnapshot.sessionIndex}:${state.phase}:${state.content.length}:${state.reasoning.length}:${state.tools.length}:${
|
|
13301
|
+
const liveActivityKey = liveSessionSnapshot ? `${liveSessionSnapshot.sessionIndex}:${state.phase}:${state.content.length}:${state.reasoning.length}:${state.tools.length}:${rawEventsRef.current.length}` : void 0;
|
|
12618
13302
|
if (!liveActivityKey) {
|
|
12619
13303
|
latestLiveActivityRef.current = void 0;
|
|
12620
13304
|
return;
|
|
@@ -12629,7 +13313,6 @@ function MarathonApp({
|
|
|
12629
13313
|
liveSessionSnapshot,
|
|
12630
13314
|
state.content.length,
|
|
12631
13315
|
state.phase,
|
|
12632
|
-
state.rawEvents.length,
|
|
12633
13316
|
state.reasoning.length,
|
|
12634
13317
|
state.tools.length
|
|
12635
13318
|
]);
|
|
@@ -12653,14 +13336,9 @@ function MarathonApp({
|
|
|
12653
13336
|
}
|
|
12654
13337
|
setPreviewUrl(void 0);
|
|
12655
13338
|
}, [displayedTools, selectedIsLive, followLatest, state.phase]);
|
|
12656
|
-
useEffect20(() => {
|
|
12657
|
-
if (showEventStream && filteredEvents.length > 0 && eventCursor === -1) {
|
|
12658
|
-
setEventCursor(filteredEvents.length - 1);
|
|
12659
|
-
}
|
|
12660
|
-
}, [filteredEvents.length, eventCursor, showEventStream]);
|
|
12661
13339
|
useEffect20(() => {
|
|
12662
13340
|
if (allowInitialInlineLoader) return;
|
|
12663
|
-
const hasVisibleSessionActivity =
|
|
13341
|
+
const hasVisibleSessionActivity = !isBlank(state.content) || !isBlank(state.reasoning) || state.tools.length > 0 || state.error !== null;
|
|
12664
13342
|
if (hasVisibleSessionActivity) {
|
|
12665
13343
|
setAllowInitialInlineLoader(true);
|
|
12666
13344
|
}
|
|
@@ -12701,7 +13379,7 @@ function MarathonApp({
|
|
|
12701
13379
|
content: state.content,
|
|
12702
13380
|
reasoning: state.reasoning,
|
|
12703
13381
|
tools: state.tools,
|
|
12704
|
-
rawEvents:
|
|
13382
|
+
rawEvents: rawEventsRef.current,
|
|
12705
13383
|
sessionSnapshots
|
|
12706
13384
|
});
|
|
12707
13385
|
exit();
|
|
@@ -12858,7 +13536,8 @@ function MarathonApp({
|
|
|
12858
13536
|
return;
|
|
12859
13537
|
}
|
|
12860
13538
|
if (_input === "c" && showEventStream) {
|
|
12861
|
-
const
|
|
13539
|
+
const eCursor = eventCursor === -1 ? filteredEvents.length - 1 : eventCursor;
|
|
13540
|
+
const evt = detailEvent ?? filteredEvents[eCursor];
|
|
12862
13541
|
if (evt) {
|
|
12863
13542
|
const payload = detailEvent ? formatEventDetailCopyText(evt, filteredEvents[0]?.timestamp ?? null) : JSON.stringify(evt.data, null, 2);
|
|
12864
13543
|
const ok = copyToClipboard(payload);
|
|
@@ -12874,7 +13553,8 @@ function MarathonApp({
|
|
|
12874
13553
|
return;
|
|
12875
13554
|
}
|
|
12876
13555
|
if (_input === "c" && showToolsPanel) {
|
|
12877
|
-
const
|
|
13556
|
+
const selectedTool = displayedTools[toolCursor];
|
|
13557
|
+
const tool = detailToolEntry ?? (selectedTool ? hydrateToolEntry(selectedTool) : void 0);
|
|
12878
13558
|
if (tool) {
|
|
12879
13559
|
const payload = detailToolEntry ? formatToolDetailCopyText(tool) : JSON.stringify({ name: tool.name, parameters: tool.parameters, result: tool.result }, null, 2);
|
|
12880
13560
|
const ok = copyToClipboard(payload);
|
|
@@ -12902,7 +13582,8 @@ function MarathonApp({
|
|
|
12902
13582
|
return;
|
|
12903
13583
|
}
|
|
12904
13584
|
if (key.return && showEventStream && !detailEvent) {
|
|
12905
|
-
const
|
|
13585
|
+
const eCursor = eventCursor === -1 ? filteredEvents.length - 1 : eventCursor;
|
|
13586
|
+
const evt = filteredEvents[eCursor];
|
|
12906
13587
|
if (evt) {
|
|
12907
13588
|
setDetailEvent(evt);
|
|
12908
13589
|
setDetailScrollOffset(0);
|
|
@@ -12917,7 +13598,7 @@ function MarathonApp({
|
|
|
12917
13598
|
if (key.return && showToolsPanel && !detailToolEntry) {
|
|
12918
13599
|
const tool = displayedTools[toolCursor];
|
|
12919
13600
|
if (tool) {
|
|
12920
|
-
setDetailToolEntry(tool);
|
|
13601
|
+
setDetailToolEntry(hydrateToolEntry(tool));
|
|
12921
13602
|
setToolDetailScrollOffset(0);
|
|
12922
13603
|
}
|
|
12923
13604
|
return;
|
|
@@ -12944,9 +13625,12 @@ function MarathonApp({
|
|
|
12944
13625
|
} else if (showEventStream && detailEvent) {
|
|
12945
13626
|
setDetailScrollOffset((prev) => Math.max(0, prev - SCROLL_STEP));
|
|
12946
13627
|
} else if (showEventStream) {
|
|
12947
|
-
setEventCursor((prev) =>
|
|
13628
|
+
setEventCursor((prev) => {
|
|
13629
|
+
const eff = prev === -1 ? filteredEvents.length - 1 : prev;
|
|
13630
|
+
return Math.max(0, eff - 1);
|
|
13631
|
+
});
|
|
12948
13632
|
} else {
|
|
12949
|
-
const contentLines =
|
|
13633
|
+
const contentLines = overviewTotalLines * 2;
|
|
12950
13634
|
const visibleRows = state.phase === "checkpoint" && checkpointRecap ? adjustedContentHeight - checkpointPromptRows : transcriptRows;
|
|
12951
13635
|
const maxOverviewScroll = Math.max(0, contentLines - visibleRows);
|
|
12952
13636
|
setScrollOffset((prev) => Math.min(prev + SCROLL_STEP, maxOverviewScroll));
|
|
@@ -12958,29 +13642,26 @@ function MarathonApp({
|
|
|
12958
13642
|
markCheckpointExploring();
|
|
12959
13643
|
}
|
|
12960
13644
|
if (showReasoningPanel) {
|
|
12961
|
-
const
|
|
12962
|
-
const maxReasoningScroll = Math.max(0, totalReasoningLines - (adjustedContentHeight - 3));
|
|
13645
|
+
const maxReasoningScroll = Math.max(0, reasoningDetailLineCount - (adjustedContentHeight - 3));
|
|
12963
13646
|
setReasoningScrollOffset((prev) => Math.min(prev + SCROLL_STEP, maxReasoningScroll));
|
|
12964
13647
|
} else if (showFilesPanel && detailFile && detailFileContent) {
|
|
12965
|
-
const
|
|
12966
|
-
const maxFileScroll = Math.max(0, renderedLines - (adjustedContentHeight - 3));
|
|
13648
|
+
const maxFileScroll = Math.max(0, fileDetailRenderedLineCount - (adjustedContentHeight - 3));
|
|
12967
13649
|
setFileDetailScrollOffset((prev) => Math.min(prev + SCROLL_STEP, maxFileScroll));
|
|
12968
13650
|
} else if (showFilesPanel) {
|
|
12969
13651
|
setFileCursor((prev) => Math.min(trackedFiles.length - 1, prev + 1));
|
|
12970
13652
|
} else if (showToolsPanel && detailToolEntry) {
|
|
12971
|
-
const
|
|
12972
|
-
const maxToolScroll = Math.max(0, totalToolLines - (adjustedContentHeight - 3));
|
|
13653
|
+
const maxToolScroll = Math.max(0, toolDetailLineCount - (adjustedContentHeight - 3));
|
|
12973
13654
|
setToolDetailScrollOffset((prev) => Math.min(prev + SCROLL_STEP, maxToolScroll));
|
|
12974
13655
|
} else if (showToolsPanel) {
|
|
12975
13656
|
setToolCursor((prev) => Math.min(displayedTools.length - 1, prev + 1));
|
|
12976
13657
|
} else if (showEventStream && detailEvent) {
|
|
12977
|
-
const
|
|
12978
|
-
const json = JSON.stringify(detailEvent.data, null, 2);
|
|
12979
|
-
const wrappedLines = json.split("\n").reduce((count, line) => count + (line.length <= wrapWidth ? 1 : Math.ceil(line.length / wrapWidth)), 0);
|
|
12980
|
-
const maxEventScroll = Math.max(0, wrappedLines - (adjustedContentHeight - 3));
|
|
13658
|
+
const maxEventScroll = Math.max(0, eventDetailLineCount - (adjustedContentHeight - 3));
|
|
12981
13659
|
setDetailScrollOffset((prev) => Math.min(prev + SCROLL_STEP, maxEventScroll));
|
|
12982
13660
|
} else if (showEventStream) {
|
|
12983
|
-
setEventCursor((prev) =>
|
|
13661
|
+
setEventCursor((prev) => {
|
|
13662
|
+
const eff = prev === -1 ? filteredEvents.length - 1 : prev;
|
|
13663
|
+
return Math.min(filteredEvents.length - 1, eff + 1);
|
|
13664
|
+
});
|
|
12984
13665
|
} else {
|
|
12985
13666
|
setScrollOffset((prev) => Math.max(0, prev - SCROLL_STEP));
|
|
12986
13667
|
}
|
|
@@ -12989,11 +13670,17 @@ function MarathonApp({
|
|
|
12989
13670
|
if (showEventStream && !detailEvent) {
|
|
12990
13671
|
const pageSize = Math.max(1, adjustedContentHeight - 3);
|
|
12991
13672
|
if (key.pageUp) {
|
|
12992
|
-
setEventCursor((prev) =>
|
|
13673
|
+
setEventCursor((prev) => {
|
|
13674
|
+
const eff = prev === -1 ? filteredEvents.length - 1 : prev;
|
|
13675
|
+
return Math.max(0, eff - pageSize);
|
|
13676
|
+
});
|
|
12993
13677
|
return;
|
|
12994
13678
|
}
|
|
12995
13679
|
if (key.pageDown) {
|
|
12996
|
-
setEventCursor((prev) =>
|
|
13680
|
+
setEventCursor((prev) => {
|
|
13681
|
+
const eff = prev === -1 ? filteredEvents.length - 1 : prev;
|
|
13682
|
+
return Math.min(filteredEvents.length - 1, eff + pageSize);
|
|
13683
|
+
});
|
|
12997
13684
|
return;
|
|
12998
13685
|
}
|
|
12999
13686
|
if (key.home) {
|
|
@@ -13001,7 +13688,7 @@ function MarathonApp({
|
|
|
13001
13688
|
return;
|
|
13002
13689
|
}
|
|
13003
13690
|
if (key.end) {
|
|
13004
|
-
setEventCursor(
|
|
13691
|
+
setEventCursor(-1);
|
|
13005
13692
|
return;
|
|
13006
13693
|
}
|
|
13007
13694
|
}
|
|
@@ -13040,7 +13727,7 @@ function MarathonApp({
|
|
|
13040
13727
|
const tool = displayedTools[newIndex];
|
|
13041
13728
|
if (tool) {
|
|
13042
13729
|
setToolCursor(newIndex);
|
|
13043
|
-
setDetailToolEntry(tool);
|
|
13730
|
+
setDetailToolEntry(hydrateToolEntry(tool));
|
|
13044
13731
|
setToolDetailScrollOffset(0);
|
|
13045
13732
|
}
|
|
13046
13733
|
return;
|
|
@@ -13050,17 +13737,19 @@ function MarathonApp({
|
|
|
13050
13737
|
const tool = displayedTools[newIndex];
|
|
13051
13738
|
if (tool) {
|
|
13052
13739
|
setToolCursor(newIndex);
|
|
13053
|
-
setDetailToolEntry(tool);
|
|
13740
|
+
setDetailToolEntry(hydrateToolEntry(tool));
|
|
13054
13741
|
setToolDetailScrollOffset(0);
|
|
13055
13742
|
}
|
|
13056
13743
|
return;
|
|
13057
13744
|
}
|
|
13058
13745
|
if (key.leftArrow && showEventStream && detailEvent) {
|
|
13059
|
-
|
|
13746
|
+
const eCursor = eventCursor === -1 ? filteredEvents.length - 1 : eventCursor;
|
|
13747
|
+
navigateToEvent(eCursor - 1);
|
|
13060
13748
|
return;
|
|
13061
13749
|
}
|
|
13062
13750
|
if (key.rightArrow && showEventStream && detailEvent) {
|
|
13063
|
-
|
|
13751
|
+
const eCursor = eventCursor === -1 ? filteredEvents.length - 1 : eventCursor;
|
|
13752
|
+
navigateToEvent(eCursor + 1);
|
|
13064
13753
|
return;
|
|
13065
13754
|
}
|
|
13066
13755
|
});
|
|
@@ -13074,9 +13763,10 @@ function MarathonApp({
|
|
|
13074
13763
|
const totalCost = initialCost + state.totalCost;
|
|
13075
13764
|
const hasTabs = allTabs.length > 0;
|
|
13076
13765
|
const hasTools = displayedTools.length > 0;
|
|
13077
|
-
const hasReasoning =
|
|
13766
|
+
const hasReasoning = !isBlank(displayedReasoning);
|
|
13078
13767
|
const showThinkingIndicator = selectedIsLive && state.phase === "thinking" && !hasReasoning;
|
|
13079
13768
|
const showContextCompactionIndicator = selectedIsLive && Boolean(state.contextCompaction?.active);
|
|
13769
|
+
const reasoningCharCount = displayedReasoning.length;
|
|
13080
13770
|
const showLoadingAnimation = !showContextCompactionIndicator && shouldShowMarathonLoadingAnimation({
|
|
13081
13771
|
allowInitialInlineLoader,
|
|
13082
13772
|
content: displayedContent,
|
|
@@ -13163,7 +13853,7 @@ function MarathonApp({
|
|
|
13163
13853
|
);
|
|
13164
13854
|
})();
|
|
13165
13855
|
const filesCenter = detailFile ? `${detailFile.path.split("/").pop()}${separator}${fileCursor + 1}/${trackedFiles.length}` : `${trackedFiles.length} files`;
|
|
13166
|
-
const detailCenter = detailEvent ? `Event detail${separator}${eventCursor + 1}/${filteredEvents.length}` : "Event stream";
|
|
13856
|
+
const detailCenter = detailEvent ? `Event detail${separator}${eventCursor === -1 ? filteredEvents.length : eventCursor + 1}/${filteredEvents.length}` : "Event stream";
|
|
13167
13857
|
const toolsCenter = detailToolEntry ? `Tool detail${separator}${toolCursor + 1}/${displayedTools.length}` : `${displayedTools.length} tool calls`;
|
|
13168
13858
|
const goalText = goal || "";
|
|
13169
13859
|
const goalExpandedRows = goalExpanded && goalText.length > terminalWidth - 4 ? Math.ceil(goalText.length / (terminalWidth - 4)) - 1 : 0;
|
|
@@ -13188,16 +13878,33 @@ function MarathonApp({
|
|
|
13188
13878
|
3,
|
|
13189
13879
|
adjustedContentHeight - reasoningHintRows - reasoningBodyRows - reasoningLiveRows - thinkingRows - compactionIndicatorRows
|
|
13190
13880
|
);
|
|
13881
|
+
const reasoningDetailLineCount = useMemo11(() => {
|
|
13882
|
+
const trimmed = displayedReasoning.trimEnd();
|
|
13883
|
+
return trimmed ? getReasoningLines(trimmed, terminalWidth).length : 0;
|
|
13884
|
+
}, [displayedReasoning, terminalWidth]);
|
|
13885
|
+
const fileDetailRenderedLineCount = useMemo11(
|
|
13886
|
+
() => detailFile && detailFileContent ? getFileRenderedLineCount(detailFile.path, detailFileContent, terminalWidth) : 0,
|
|
13887
|
+
[detailFile, detailFileContent, terminalWidth]
|
|
13888
|
+
);
|
|
13889
|
+
const toolDetailLineCount = useMemo11(
|
|
13890
|
+
() => detailToolEntry ? getToolDetailLines(detailToolEntry, terminalWidth).length : 0,
|
|
13891
|
+
[detailToolEntry, terminalWidth]
|
|
13892
|
+
);
|
|
13893
|
+
const eventDetailLineCount = useMemo11(
|
|
13894
|
+
() => detailEvent ? getEventDetailLines(detailEvent, terminalWidth).length : 0,
|
|
13895
|
+
[detailEvent, terminalWidth]
|
|
13896
|
+
);
|
|
13897
|
+
const overviewTotalLines = useMemo11(() => displayedContent.split("\n").length, [displayedContent]);
|
|
13191
13898
|
const upgradeModalWidth = Math.max(24, Math.min(terminalWidth - 6, 88));
|
|
13192
|
-
const showUpgradeBrowseHint = canBrowseAfterUpgradeError && selectedIsLive &&
|
|
13193
|
-
return /* @__PURE__ */
|
|
13194
|
-
|
|
13899
|
+
const showUpgradeBrowseHint = canBrowseAfterUpgradeError && selectedIsLive && isBlank(displayedContent) && isBlank(displayedReasoning) && displayedTools.length === 0 && displayedEvents.length === 0;
|
|
13900
|
+
return /* @__PURE__ */ jsxs26(
|
|
13901
|
+
Box28,
|
|
13195
13902
|
{
|
|
13196
13903
|
flexDirection: "column",
|
|
13197
13904
|
height: terminalRows,
|
|
13198
13905
|
width: terminalWidth,
|
|
13199
13906
|
children: [
|
|
13200
|
-
/* @__PURE__ */
|
|
13907
|
+
/* @__PURE__ */ jsx33(
|
|
13201
13908
|
SessionHeader,
|
|
13202
13909
|
{
|
|
13203
13910
|
sessionName: taskName,
|
|
@@ -13217,8 +13924,8 @@ function MarathonApp({
|
|
|
13217
13924
|
currentMilestone
|
|
13218
13925
|
}
|
|
13219
13926
|
),
|
|
13220
|
-
/* @__PURE__ */
|
|
13221
|
-
hasTabs && /* @__PURE__ */
|
|
13927
|
+
/* @__PURE__ */ jsx33(Box28, { marginLeft: 1, children: /* @__PURE__ */ jsx33(ScreenTabs, { activeTab: activeScreen, width: terminalWidth - 1, shortcutHint: "Tab: next screen" }) }),
|
|
13928
|
+
hasTabs && /* @__PURE__ */ jsx33(Box28, { width: terminalWidth, marginBottom: 1, marginLeft: 1, children: /* @__PURE__ */ jsx33(
|
|
13222
13929
|
SessionTabs,
|
|
13223
13930
|
{
|
|
13224
13931
|
tabs: visibleTabs.tabs,
|
|
@@ -13227,13 +13934,13 @@ function MarathonApp({
|
|
|
13227
13934
|
shortcutHint: allTabs.length > 1 ? "Shift+\u2190/\u2192: select run" : void 0
|
|
13228
13935
|
}
|
|
13229
13936
|
) }),
|
|
13230
|
-
showFilesPanel ? /* @__PURE__ */
|
|
13231
|
-
|
|
13937
|
+
showFilesPanel ? /* @__PURE__ */ jsx33(
|
|
13938
|
+
Box28,
|
|
13232
13939
|
{
|
|
13233
13940
|
flexDirection: "column",
|
|
13234
13941
|
height: adjustedContentHeight,
|
|
13235
13942
|
overflow: "hidden",
|
|
13236
|
-
children: /* @__PURE__ */
|
|
13943
|
+
children: /* @__PURE__ */ jsx33(
|
|
13237
13944
|
FilesPanel,
|
|
13238
13945
|
{
|
|
13239
13946
|
files: trackedFiles,
|
|
@@ -13249,13 +13956,13 @@ function MarathonApp({
|
|
|
13249
13956
|
}
|
|
13250
13957
|
)
|
|
13251
13958
|
}
|
|
13252
|
-
) : showReasoningPanel ? /* @__PURE__ */
|
|
13253
|
-
|
|
13959
|
+
) : showReasoningPanel ? /* @__PURE__ */ jsx33(
|
|
13960
|
+
Box28,
|
|
13254
13961
|
{
|
|
13255
13962
|
flexDirection: "column",
|
|
13256
13963
|
height: adjustedContentHeight,
|
|
13257
13964
|
overflow: "hidden",
|
|
13258
|
-
children: /* @__PURE__ */
|
|
13965
|
+
children: /* @__PURE__ */ jsx33(
|
|
13259
13966
|
ReasoningPanel,
|
|
13260
13967
|
{
|
|
13261
13968
|
reasoning: displayedReasoning,
|
|
@@ -13265,34 +13972,34 @@ function MarathonApp({
|
|
|
13265
13972
|
}
|
|
13266
13973
|
)
|
|
13267
13974
|
}
|
|
13268
|
-
) : showEventStream ? /* @__PURE__ */
|
|
13269
|
-
|
|
13975
|
+
) : showEventStream ? /* @__PURE__ */ jsx33(
|
|
13976
|
+
Box28,
|
|
13270
13977
|
{
|
|
13271
13978
|
flexDirection: "column",
|
|
13272
13979
|
height: adjustedContentHeight,
|
|
13273
13980
|
overflow: "hidden",
|
|
13274
|
-
children: /* @__PURE__ */
|
|
13981
|
+
children: /* @__PURE__ */ jsx33(
|
|
13275
13982
|
EventStreamPanel,
|
|
13276
13983
|
{
|
|
13277
13984
|
events: filteredEvents,
|
|
13278
13985
|
startTime: filteredEvents[0]?.timestamp ?? null,
|
|
13279
13986
|
maxVisibleLines: adjustedContentHeight - 1,
|
|
13280
|
-
selectedIndex: eventCursor,
|
|
13987
|
+
selectedIndex: eventCursor === -1 ? filteredEvents.length - 1 : eventCursor,
|
|
13281
13988
|
detailEvent,
|
|
13282
13989
|
detailScrollOffset,
|
|
13283
13990
|
width: terminalWidth,
|
|
13284
13991
|
activeFilterCount: eventTypeFilter.size,
|
|
13285
|
-
totalTypeCount:
|
|
13992
|
+
totalTypeCount: stableSeenEventTypesRef.current.length
|
|
13286
13993
|
}
|
|
13287
13994
|
)
|
|
13288
13995
|
}
|
|
13289
|
-
) : showToolsPanel ? /* @__PURE__ */
|
|
13290
|
-
|
|
13996
|
+
) : showToolsPanel ? /* @__PURE__ */ jsx33(
|
|
13997
|
+
Box28,
|
|
13291
13998
|
{
|
|
13292
13999
|
flexDirection: "column",
|
|
13293
14000
|
height: adjustedContentHeight,
|
|
13294
14001
|
overflow: "hidden",
|
|
13295
|
-
children: /* @__PURE__ */
|
|
14002
|
+
children: /* @__PURE__ */ jsx33(
|
|
13296
14003
|
ToolsPanel,
|
|
13297
14004
|
{
|
|
13298
14005
|
tools: displayedTools,
|
|
@@ -13304,14 +14011,14 @@ function MarathonApp({
|
|
|
13304
14011
|
}
|
|
13305
14012
|
)
|
|
13306
14013
|
}
|
|
13307
|
-
) : state.phase === "checkpoint" && checkpointRecap ? /* @__PURE__ */
|
|
13308
|
-
|
|
14014
|
+
) : state.phase === "checkpoint" && checkpointRecap ? /* @__PURE__ */ jsxs26(
|
|
14015
|
+
Box28,
|
|
13309
14016
|
{
|
|
13310
14017
|
flexDirection: isStacked ? "column" : "row",
|
|
13311
14018
|
height: adjustedContentHeight,
|
|
13312
14019
|
children: [
|
|
13313
|
-
/* @__PURE__ */
|
|
13314
|
-
|
|
14020
|
+
/* @__PURE__ */ jsxs26(
|
|
14021
|
+
Box28,
|
|
13315
14022
|
{
|
|
13316
14023
|
flexDirection: "column",
|
|
13317
14024
|
flexGrow: 1,
|
|
@@ -13319,33 +14026,20 @@ function MarathonApp({
|
|
|
13319
14026
|
marginLeft: contentMarginLeft,
|
|
13320
14027
|
marginRight: contentMarginRight,
|
|
13321
14028
|
children: [
|
|
13322
|
-
/* @__PURE__ */
|
|
13323
|
-
|
|
13324
|
-
|
|
13325
|
-
|
|
13326
|
-
|
|
13327
|
-
|
|
13328
|
-
|
|
13329
|
-
|
|
13330
|
-
|
|
13331
|
-
|
|
13332
|
-
|
|
13333
|
-
|
|
13334
|
-
|
|
13335
|
-
|
|
13336
|
-
const checkpointMaxScroll = Math.max(0, checkpointTotalLines - checkpointVisibleRows);
|
|
13337
|
-
return /* @__PURE__ */ jsx31(
|
|
13338
|
-
Scrollbar,
|
|
13339
|
-
{
|
|
13340
|
-
totalLines: checkpointTotalLines,
|
|
13341
|
-
visibleLines: checkpointVisibleRows,
|
|
13342
|
-
scrollOffset: checkpointMaxScroll - Math.min(scrollOffset, checkpointMaxScroll),
|
|
13343
|
-
height: checkpointVisibleRows
|
|
13344
|
-
}
|
|
13345
|
-
);
|
|
13346
|
-
})()
|
|
13347
|
-
] }),
|
|
13348
|
-
/* @__PURE__ */ jsx31(
|
|
14029
|
+
/* @__PURE__ */ jsx33(Box28, { flexDirection: "row", flexGrow: 1, overflow: "hidden", marginBottom: 1, children: /* @__PURE__ */ jsx33(Box28, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx33(
|
|
14030
|
+
OverviewTranscriptPane,
|
|
14031
|
+
{
|
|
14032
|
+
content: displayedContent,
|
|
14033
|
+
enableMarkdown: !plainText,
|
|
14034
|
+
isStreaming: false,
|
|
14035
|
+
maxVisibleLines: adjustedContentHeight - checkpointPromptRows - 1,
|
|
14036
|
+
scrollOffset,
|
|
14037
|
+
totalLines: overviewTotalLines,
|
|
14038
|
+
paneWidth: transcriptPaneWidth,
|
|
14039
|
+
contentHeight: adjustedContentHeight
|
|
14040
|
+
}
|
|
14041
|
+
) }) }),
|
|
14042
|
+
/* @__PURE__ */ jsx33(
|
|
13349
14043
|
CheckpointPrompt,
|
|
13350
14044
|
{
|
|
13351
14045
|
onSubmit: handleCheckpointSubmit,
|
|
@@ -13363,137 +14057,74 @@ function MarathonApp({
|
|
|
13363
14057
|
]
|
|
13364
14058
|
}
|
|
13365
14059
|
),
|
|
13366
|
-
!isStacked && (hasTools || hasReasoning) && /* @__PURE__ */
|
|
13367
|
-
|
|
14060
|
+
!isStacked && (hasTools || hasReasoning) && /* @__PURE__ */ jsx33(
|
|
14061
|
+
OverviewActivityPane,
|
|
13368
14062
|
{
|
|
13369
|
-
|
|
13370
|
-
|
|
13371
|
-
|
|
13372
|
-
|
|
13373
|
-
|
|
13374
|
-
backgroundColor: theme30.background,
|
|
13375
|
-
paddingX: theme30.panelPaddingX,
|
|
13376
|
-
paddingY: theme30.panelPaddingY,
|
|
13377
|
-
children: /* @__PURE__ */ jsx31(
|
|
13378
|
-
ToolPanel,
|
|
13379
|
-
{
|
|
13380
|
-
tools: displayedTools,
|
|
13381
|
-
reasoning: displayedReasoning,
|
|
13382
|
-
files: trackedFiles,
|
|
13383
|
-
maxHeight: adjustedContentHeight - 2
|
|
13384
|
-
}
|
|
13385
|
-
)
|
|
14063
|
+
tools: displayedTools,
|
|
14064
|
+
reasoningCharCount,
|
|
14065
|
+
files: trackedFiles,
|
|
14066
|
+
maxHeight: adjustedContentHeight - 2,
|
|
14067
|
+
width: toolPanelWidth
|
|
13386
14068
|
}
|
|
13387
14069
|
)
|
|
13388
14070
|
]
|
|
13389
14071
|
}
|
|
13390
|
-
) : /* @__PURE__ */
|
|
13391
|
-
|
|
14072
|
+
) : /* @__PURE__ */ jsxs26(
|
|
14073
|
+
Box28,
|
|
13392
14074
|
{
|
|
13393
14075
|
flexDirection: isStacked ? "column" : "row",
|
|
13394
14076
|
height: adjustedContentHeight,
|
|
13395
14077
|
overflow: "hidden",
|
|
13396
14078
|
children: [
|
|
13397
|
-
/* @__PURE__ */
|
|
13398
|
-
|
|
14079
|
+
/* @__PURE__ */ jsx33(
|
|
14080
|
+
Box28,
|
|
13399
14081
|
{
|
|
13400
14082
|
flexDirection: "column",
|
|
13401
14083
|
flexGrow: 1,
|
|
13402
14084
|
flexShrink: 1,
|
|
13403
14085
|
marginLeft: contentMarginLeft,
|
|
13404
14086
|
marginRight: contentMarginRight,
|
|
13405
|
-
children:
|
|
13406
|
-
|
|
14087
|
+
children: /* @__PURE__ */ jsx33(
|
|
14088
|
+
OverviewTranscriptPane,
|
|
13407
14089
|
{
|
|
13408
|
-
|
|
13409
|
-
|
|
13410
|
-
|
|
13411
|
-
|
|
13412
|
-
|
|
13413
|
-
|
|
13414
|
-
|
|
13415
|
-
|
|
13416
|
-
|
|
13417
|
-
|
|
14090
|
+
content: displayedContent,
|
|
14091
|
+
enableMarkdown: !plainText,
|
|
14092
|
+
isStreaming: selectedIsLive && state.phase === "streaming",
|
|
14093
|
+
maxVisibleLines: transcriptRows,
|
|
14094
|
+
scrollOffset,
|
|
14095
|
+
totalLines: overviewTotalLines,
|
|
14096
|
+
paneWidth: transcriptPaneWidth,
|
|
14097
|
+
contentHeight: adjustedContentHeight,
|
|
14098
|
+
showLoadingAnimation,
|
|
14099
|
+
hasReasoning,
|
|
14100
|
+
visibleReasoningLines,
|
|
14101
|
+
reasoningCollapsed,
|
|
14102
|
+
reasoningLive: selectedIsLive && state.phase === "thinking" && !reasoningCollapsed,
|
|
14103
|
+
showThinkingIndicator,
|
|
14104
|
+
thinkingStartedAt: state.thinkingStartedAt,
|
|
14105
|
+
contextCompaction: showContextCompactionIndicator ? state.contextCompaction : null,
|
|
14106
|
+
showUpgradeBrowseHint,
|
|
14107
|
+
error: selectedIsLive && !upgradePrompt ? state.error : null
|
|
13418
14108
|
}
|
|
13419
|
-
)
|
|
13420
|
-
hasReasoning && /* @__PURE__ */ jsx31(Box26, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx31(
|
|
13421
|
-
ReasoningBlock,
|
|
13422
|
-
{
|
|
13423
|
-
lines: visibleReasoningLines,
|
|
13424
|
-
live: selectedIsLive && state.phase === "thinking" && !reasoningCollapsed,
|
|
13425
|
-
collapsed: reasoningCollapsed,
|
|
13426
|
-
showToggleHint: true
|
|
13427
|
-
}
|
|
13428
|
-
) }),
|
|
13429
|
-
showThinkingIndicator && /* @__PURE__ */ jsx31(ThinkingIndicator, { startedAt: state.thinkingStartedAt }),
|
|
13430
|
-
showContextCompactionIndicator && state.contextCompaction && /* @__PURE__ */ jsx31(ContextCompactionIndicator, { compaction: state.contextCompaction }),
|
|
13431
|
-
showUpgradeBrowseHint && /* @__PURE__ */ jsx31(Box26, { marginBottom: 1, children: /* @__PURE__ */ jsx31(
|
|
13432
|
-
ReasoningBlock,
|
|
13433
|
-
{
|
|
13434
|
-
lines: [
|
|
13435
|
-
"Upgrade modal dismissed.",
|
|
13436
|
-
"Use Shift+Left/Right or 1-9 to review previous marathon runs."
|
|
13437
|
-
],
|
|
13438
|
-
compact: true
|
|
13439
|
-
}
|
|
13440
|
-
) }),
|
|
13441
|
-
/* @__PURE__ */ jsxs25(Box26, { flexDirection: "row", children: [
|
|
13442
|
-
/* @__PURE__ */ jsx31(Box26, { flexDirection: "column", flexGrow: 1, marginRight: 1, children: /* @__PURE__ */ jsx31(
|
|
13443
|
-
StreamOutput,
|
|
13444
|
-
{
|
|
13445
|
-
content: displayedContent,
|
|
13446
|
-
isStreaming: selectedIsLive && state.phase === "streaming",
|
|
13447
|
-
enableMarkdown: !plainText,
|
|
13448
|
-
maxVisibleLines: transcriptRows,
|
|
13449
|
-
scrollOffset
|
|
13450
|
-
}
|
|
13451
|
-
) }),
|
|
13452
|
-
(() => {
|
|
13453
|
-
const overviewTotalLines = displayedContent.split("\n").length;
|
|
13454
|
-
const overviewMaxScroll = Math.max(0, overviewTotalLines - transcriptRows);
|
|
13455
|
-
return /* @__PURE__ */ jsx31(
|
|
13456
|
-
Scrollbar,
|
|
13457
|
-
{
|
|
13458
|
-
totalLines: overviewTotalLines,
|
|
13459
|
-
visibleLines: transcriptRows,
|
|
13460
|
-
scrollOffset: overviewMaxScroll - Math.min(scrollOffset, overviewMaxScroll),
|
|
13461
|
-
height: transcriptRows
|
|
13462
|
-
}
|
|
13463
|
-
);
|
|
13464
|
-
})()
|
|
13465
|
-
] }),
|
|
13466
|
-
selectedIsLive && state.error && !upgradePrompt && /* @__PURE__ */ jsx31(ErrorDisplay3, { error: state.error })
|
|
13467
|
-
] })
|
|
14109
|
+
)
|
|
13468
14110
|
}
|
|
13469
14111
|
),
|
|
13470
|
-
(hasTools || hasReasoning) && /* @__PURE__ */
|
|
13471
|
-
|
|
14112
|
+
(hasTools || hasReasoning) && /* @__PURE__ */ jsx33(
|
|
14113
|
+
OverviewActivityPane,
|
|
13472
14114
|
{
|
|
13473
|
-
|
|
13474
|
-
|
|
13475
|
-
|
|
13476
|
-
|
|
13477
|
-
|
|
13478
|
-
|
|
13479
|
-
paddingX: theme30.panelPaddingX,
|
|
13480
|
-
paddingY: theme30.panelPaddingY,
|
|
13481
|
-
children: /* @__PURE__ */ jsx31(
|
|
13482
|
-
ToolPanel,
|
|
13483
|
-
{
|
|
13484
|
-
tools: displayedTools,
|
|
13485
|
-
reasoning: displayedReasoning,
|
|
13486
|
-
files: trackedFiles,
|
|
13487
|
-
maxHeight: adjustedContentHeight - 2
|
|
13488
|
-
}
|
|
13489
|
-
)
|
|
14115
|
+
tools: displayedTools,
|
|
14116
|
+
reasoningCharCount,
|
|
14117
|
+
files: trackedFiles,
|
|
14118
|
+
maxHeight: adjustedContentHeight - 2,
|
|
14119
|
+
stacked: isStacked,
|
|
14120
|
+
width: toolPanelWidth
|
|
13490
14121
|
}
|
|
13491
14122
|
)
|
|
13492
14123
|
]
|
|
13493
14124
|
}
|
|
13494
14125
|
),
|
|
13495
|
-
showHelpOverlay && /* @__PURE__ */
|
|
13496
|
-
|
|
14126
|
+
showHelpOverlay && /* @__PURE__ */ jsx33(
|
|
14127
|
+
Box28,
|
|
13497
14128
|
{
|
|
13498
14129
|
width: terminalWidth,
|
|
13499
14130
|
marginTop: -adjustedContentHeight,
|
|
@@ -13501,8 +14132,8 @@ function MarathonApp({
|
|
|
13501
14132
|
justifyContent: "center",
|
|
13502
14133
|
alignItems: "center",
|
|
13503
14134
|
flexShrink: 0,
|
|
13504
|
-
backgroundColor:
|
|
13505
|
-
children: /* @__PURE__ */
|
|
14135
|
+
backgroundColor: theme31.surfaceMuted,
|
|
14136
|
+
children: /* @__PURE__ */ jsx33(
|
|
13506
14137
|
HelpPanel,
|
|
13507
14138
|
{
|
|
13508
14139
|
width: terminalWidth,
|
|
@@ -13513,8 +14144,8 @@ function MarathonApp({
|
|
|
13513
14144
|
)
|
|
13514
14145
|
}
|
|
13515
14146
|
),
|
|
13516
|
-
showEventTypeFilter && /* @__PURE__ */
|
|
13517
|
-
|
|
14147
|
+
showEventTypeFilter && /* @__PURE__ */ jsx33(
|
|
14148
|
+
Box28,
|
|
13518
14149
|
{
|
|
13519
14150
|
width: terminalWidth,
|
|
13520
14151
|
marginTop: -adjustedContentHeight,
|
|
@@ -13522,11 +14153,11 @@ function MarathonApp({
|
|
|
13522
14153
|
justifyContent: "center",
|
|
13523
14154
|
alignItems: "center",
|
|
13524
14155
|
flexShrink: 0,
|
|
13525
|
-
backgroundColor:
|
|
13526
|
-
children: /* @__PURE__ */
|
|
14156
|
+
backgroundColor: theme31.surfaceMuted,
|
|
14157
|
+
children: /* @__PURE__ */ jsx33(
|
|
13527
14158
|
EventTypeFilter,
|
|
13528
14159
|
{
|
|
13529
|
-
eventTypes:
|
|
14160
|
+
eventTypes: stableSeenEventTypesRef.current,
|
|
13530
14161
|
selectedTypes: eventTypeFilter,
|
|
13531
14162
|
onApply: (selected) => {
|
|
13532
14163
|
setEventTypeFilter(selected);
|
|
@@ -13538,8 +14169,8 @@ function MarathonApp({
|
|
|
13538
14169
|
)
|
|
13539
14170
|
}
|
|
13540
14171
|
),
|
|
13541
|
-
showSessionMenu && /* @__PURE__ */
|
|
13542
|
-
|
|
14172
|
+
showSessionMenu && /* @__PURE__ */ jsx33(
|
|
14173
|
+
Box28,
|
|
13543
14174
|
{
|
|
13544
14175
|
width: terminalWidth,
|
|
13545
14176
|
marginTop: -adjustedContentHeight,
|
|
@@ -13547,8 +14178,8 @@ function MarathonApp({
|
|
|
13547
14178
|
justifyContent: "center",
|
|
13548
14179
|
alignItems: "center",
|
|
13549
14180
|
flexShrink: 0,
|
|
13550
|
-
backgroundColor:
|
|
13551
|
-
children: /* @__PURE__ */
|
|
14181
|
+
backgroundColor: theme31.surfaceMuted,
|
|
14182
|
+
children: /* @__PURE__ */ jsx33(
|
|
13552
14183
|
SessionActionMenu,
|
|
13553
14184
|
{
|
|
13554
14185
|
onCopySession: handleCopySession,
|
|
@@ -13562,8 +14193,8 @@ function MarathonApp({
|
|
|
13562
14193
|
)
|
|
13563
14194
|
}
|
|
13564
14195
|
),
|
|
13565
|
-
showUpgradeModal && upgradePrompt && /* @__PURE__ */
|
|
13566
|
-
|
|
14196
|
+
showUpgradeModal && upgradePrompt && /* @__PURE__ */ jsx33(
|
|
14197
|
+
Box28,
|
|
13567
14198
|
{
|
|
13568
14199
|
marginTop: -adjustedContentHeight,
|
|
13569
14200
|
marginBottom: -adjustedContentHeight,
|
|
@@ -13571,15 +14202,15 @@ function MarathonApp({
|
|
|
13571
14202
|
justifyContent: "center",
|
|
13572
14203
|
alignItems: "center",
|
|
13573
14204
|
flexShrink: 0,
|
|
13574
|
-
children: /* @__PURE__ */
|
|
14205
|
+
children: /* @__PURE__ */ jsx33(UpgradeModal, { prompt: upgradePrompt, width: upgradeModalWidth })
|
|
13575
14206
|
}
|
|
13576
14207
|
),
|
|
13577
|
-
/* @__PURE__ */
|
|
14208
|
+
/* @__PURE__ */ jsx33(
|
|
13578
14209
|
StatusBar,
|
|
13579
14210
|
{
|
|
13580
|
-
left: /* @__PURE__ */
|
|
14211
|
+
left: /* @__PURE__ */ jsxs26(Text28, { color: theme31.textMuted, children: [
|
|
13581
14212
|
`Model: ${currentModel}${currentSandbox ? `${separator}Sandbox: ${currentSandbox}` : ""}`,
|
|
13582
|
-
previewUrl && /* @__PURE__ */
|
|
14213
|
+
previewUrl && /* @__PURE__ */ jsx33(Text28, { color: theme31.accent, children: `${separator}\x1B]8;;${previewUrl}\x07preview\x1B]8;;\x07` })
|
|
13583
14214
|
] }),
|
|
13584
14215
|
center: showFilesPanel ? filesCenter : showEventStream ? detailCenter : showToolsPanel ? toolsCenter : void 0,
|
|
13585
14216
|
right: statusRight
|
|
@@ -13592,10 +14223,10 @@ function MarathonApp({
|
|
|
13592
14223
|
|
|
13593
14224
|
// src/ink/marathon/MarathonStartupShell.tsx
|
|
13594
14225
|
import { useEffect as useEffect21, useRef as useRef9, useState as useState23 } from "react";
|
|
13595
|
-
import { Box as
|
|
13596
|
-
import { theme as
|
|
14226
|
+
import { Box as Box29, Text as Text29, useApp as useApp5, useInput as useInput12, useStdout as useStdout6 } from "ink";
|
|
14227
|
+
import { theme as theme32 } from "@runtypelabs/ink-components";
|
|
13597
14228
|
import { AnimatedVariant, StartupGridIconCompactLightInverted } from "@runtypelabs/terminal-animations";
|
|
13598
|
-
import { jsx as
|
|
14229
|
+
import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
13599
14230
|
var SCROLL_HINT = "\u2191\u2193 Enter 1-3";
|
|
13600
14231
|
var PROMPT_COLUMN_MAX = 68;
|
|
13601
14232
|
var MIN_HOLD_MS = 1500;
|
|
@@ -13863,17 +14494,17 @@ function MarathonStartupShell({
|
|
|
13863
14494
|
const selectedChoice = prompt?.choices[selectedPromptIndex];
|
|
13864
14495
|
const contentWidth = prompt || modelChoices || playbookConfirm ? promptColumnWidth : void 0;
|
|
13865
14496
|
if (scene === "app" && marathonAppProps) {
|
|
13866
|
-
return /* @__PURE__ */
|
|
14497
|
+
return /* @__PURE__ */ jsx34(MarathonApp, { ...marathonAppProps });
|
|
13867
14498
|
}
|
|
13868
|
-
return /* @__PURE__ */
|
|
13869
|
-
/* @__PURE__ */
|
|
13870
|
-
|
|
14499
|
+
return /* @__PURE__ */ jsxs27(Box29, { width: terminalWidth, height: terminalRows, backgroundColor: theme32.background, children: [
|
|
14500
|
+
/* @__PURE__ */ jsx34(
|
|
14501
|
+
Box29,
|
|
13871
14502
|
{
|
|
13872
14503
|
position: "absolute",
|
|
13873
14504
|
width: terminalWidth,
|
|
13874
14505
|
height: terminalRows,
|
|
13875
14506
|
overflow: "hidden",
|
|
13876
|
-
children: /* @__PURE__ */
|
|
14507
|
+
children: /* @__PURE__ */ jsx34(
|
|
13877
14508
|
AnimatedVariant,
|
|
13878
14509
|
{
|
|
13879
14510
|
variantId: backgroundVariantId,
|
|
@@ -13883,8 +14514,8 @@ function MarathonStartupShell({
|
|
|
13883
14514
|
)
|
|
13884
14515
|
}
|
|
13885
14516
|
),
|
|
13886
|
-
/* @__PURE__ */
|
|
13887
|
-
|
|
14517
|
+
/* @__PURE__ */ jsx34(
|
|
14518
|
+
Box29,
|
|
13888
14519
|
{
|
|
13889
14520
|
position: "absolute",
|
|
13890
14521
|
width: terminalWidth,
|
|
@@ -13893,27 +14524,27 @@ function MarathonStartupShell({
|
|
|
13893
14524
|
justifyContent: "flex-start",
|
|
13894
14525
|
paddingX: 1,
|
|
13895
14526
|
paddingY: 1,
|
|
13896
|
-
children: /* @__PURE__ */
|
|
14527
|
+
children: /* @__PURE__ */ jsx34(StartupGridIconCompactLightInverted, { autoplay: false })
|
|
13897
14528
|
}
|
|
13898
14529
|
),
|
|
13899
|
-
/* @__PURE__ */
|
|
13900
|
-
|
|
14530
|
+
/* @__PURE__ */ jsx34(
|
|
14531
|
+
Box29,
|
|
13901
14532
|
{
|
|
13902
14533
|
width: terminalWidth,
|
|
13903
14534
|
height: terminalRows,
|
|
13904
14535
|
flexDirection: "column",
|
|
13905
14536
|
justifyContent: "center",
|
|
13906
14537
|
alignItems: "center",
|
|
13907
|
-
children: /* @__PURE__ */
|
|
13908
|
-
|
|
14538
|
+
children: /* @__PURE__ */ jsxs27(
|
|
14539
|
+
Box29,
|
|
13909
14540
|
{
|
|
13910
14541
|
flexDirection: "column",
|
|
13911
14542
|
alignItems: prompt || modelChoices || playbookConfirm ? "stretch" : "center",
|
|
13912
|
-
backgroundColor:
|
|
14543
|
+
backgroundColor: theme32.background,
|
|
13913
14544
|
paddingX: 2,
|
|
13914
14545
|
paddingY: 1,
|
|
13915
14546
|
children: [
|
|
13916
|
-
!prompt && !modelChoices && !playbookConfirm && /* @__PURE__ */
|
|
14547
|
+
!prompt && !modelChoices && !playbookConfirm && /* @__PURE__ */ jsx34(Text29, { color: theme32.textMuted, children: statusMessage }),
|
|
13917
14548
|
playbookConfirm && !modelChoices && (() => {
|
|
13918
14549
|
const milestoneCount = playbookConfirm.milestoneNames.length;
|
|
13919
14550
|
const hasEdits = JSON.stringify(playbookConfirm.milestoneModels) !== JSON.stringify(playbookConfirm.originalModels);
|
|
@@ -13922,33 +14553,33 @@ function MarathonStartupShell({
|
|
|
13922
14553
|
"Use single model instead",
|
|
13923
14554
|
...hasEdits ? ["Discard changes"] : []
|
|
13924
14555
|
];
|
|
13925
|
-
return /* @__PURE__ */
|
|
13926
|
-
/* @__PURE__ */
|
|
14556
|
+
return /* @__PURE__ */ jsxs27(Box29, { width: contentWidth, flexDirection: "column", marginTop: 1, children: [
|
|
14557
|
+
/* @__PURE__ */ jsxs27(Text29, { bold: true, color: theme32.text, children: [
|
|
13927
14558
|
"Playbook: ",
|
|
13928
14559
|
playbookConfirm.name
|
|
13929
14560
|
] }),
|
|
13930
|
-
/* @__PURE__ */
|
|
14561
|
+
/* @__PURE__ */ jsx34(Box29, { marginTop: 1, flexDirection: "column", children: playbookConfirm.milestoneNames.map((milestone, i) => {
|
|
13931
14562
|
const isSelected = i === playbookConfirm.selectedIndex;
|
|
13932
14563
|
const model = playbookConfirm.milestoneModels[milestone];
|
|
13933
14564
|
const wasEdited = model !== playbookConfirm.originalModels[milestone];
|
|
13934
|
-
return /* @__PURE__ */
|
|
13935
|
-
/* @__PURE__ */
|
|
13936
|
-
/* @__PURE__ */
|
|
13937
|
-
/* @__PURE__ */
|
|
13938
|
-
wasEdited && /* @__PURE__ */
|
|
14565
|
+
return /* @__PURE__ */ jsxs27(Box29, { children: [
|
|
14566
|
+
/* @__PURE__ */ jsx34(Text29, { color: isSelected ? theme32.accent : theme32.textSubtle, children: isSelected ? "\u203A " : " " }),
|
|
14567
|
+
/* @__PURE__ */ jsx34(Text29, { color: isSelected ? theme32.text : theme32.textSubtle, bold: isSelected, children: milestone.padEnd(16) }),
|
|
14568
|
+
/* @__PURE__ */ jsx34(Text29, { color: isSelected ? theme32.accent : theme32.textMuted, children: model }),
|
|
14569
|
+
wasEdited && /* @__PURE__ */ jsx34(Text29, { color: theme32.textSubtle, children: " (edited)" })
|
|
13939
14570
|
] }, milestone);
|
|
13940
14571
|
}) }),
|
|
13941
|
-
/* @__PURE__ */
|
|
14572
|
+
/* @__PURE__ */ jsx34(Box29, { marginTop: 1, flexDirection: "column", children: actions.map((label, ai) => {
|
|
13942
14573
|
const isSelected = playbookConfirm.selectedIndex === milestoneCount + ai;
|
|
13943
|
-
return /* @__PURE__ */
|
|
13944
|
-
/* @__PURE__ */
|
|
13945
|
-
/* @__PURE__ */
|
|
14574
|
+
return /* @__PURE__ */ jsxs27(Box29, { children: [
|
|
14575
|
+
/* @__PURE__ */ jsx34(Text29, { color: isSelected ? theme32.accent : theme32.textSubtle, children: isSelected ? "\u203A " : " " }),
|
|
14576
|
+
/* @__PURE__ */ jsx34(Text29, { color: isSelected ? theme32.text : theme32.textSubtle, bold: isSelected, children: label })
|
|
13946
14577
|
] }, label);
|
|
13947
14578
|
}) }),
|
|
13948
|
-
/* @__PURE__ */
|
|
14579
|
+
/* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text29, { color: theme32.border, children: "\u2191\u2193 navigate \xB7 Enter select" }) })
|
|
13949
14580
|
] });
|
|
13950
14581
|
})(),
|
|
13951
|
-
modelChoices && /* @__PURE__ */
|
|
14582
|
+
modelChoices && /* @__PURE__ */ jsx34(Box29, { width: contentWidth, flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsx34(
|
|
13952
14583
|
ModelPicker,
|
|
13953
14584
|
{
|
|
13954
14585
|
currentModel,
|
|
@@ -13966,27 +14597,27 @@ function MarathonStartupShell({
|
|
|
13966
14597
|
}
|
|
13967
14598
|
}
|
|
13968
14599
|
) }),
|
|
13969
|
-
prompt && /* @__PURE__ */
|
|
13970
|
-
/* @__PURE__ */
|
|
13971
|
-
promptShellModel?.task && /* @__PURE__ */
|
|
13972
|
-
/* @__PURE__ */
|
|
13973
|
-
/* @__PURE__ */
|
|
14600
|
+
prompt && /* @__PURE__ */ jsxs27(Box29, { width: contentWidth, flexDirection: "column", marginTop: 1, children: [
|
|
14601
|
+
/* @__PURE__ */ jsx34(Text29, { bold: true, color: theme32.text, children: promptShellModel?.heading }),
|
|
14602
|
+
promptShellModel?.task && /* @__PURE__ */ jsxs27(Box29, { marginTop: 1, children: [
|
|
14603
|
+
/* @__PURE__ */ jsx34(Text29, { color: theme32.textSubtle, children: "task " }),
|
|
14604
|
+
/* @__PURE__ */ jsx34(Text29, { color: theme32.text, children: promptShellModel.task })
|
|
13974
14605
|
] }),
|
|
13975
|
-
promptShellModel?.filePath && /* @__PURE__ */
|
|
13976
|
-
/* @__PURE__ */
|
|
13977
|
-
/* @__PURE__ */
|
|
14606
|
+
promptShellModel?.filePath && /* @__PURE__ */ jsxs27(Box29, { children: [
|
|
14607
|
+
/* @__PURE__ */ jsx34(Text29, { color: theme32.textSubtle, children: "state " }),
|
|
14608
|
+
/* @__PURE__ */ jsx34(Text29, { color: theme32.textSubtle, children: promptShellModel.filePath })
|
|
13978
14609
|
] }),
|
|
13979
|
-
promptShellModel?.metaLine && /* @__PURE__ */
|
|
13980
|
-
/* @__PURE__ */
|
|
13981
|
-
/* @__PURE__ */
|
|
14610
|
+
promptShellModel?.metaLine && /* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text29, { color: theme32.textSubtle, children: promptShellModel.metaLine }) }),
|
|
14611
|
+
/* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text29, { color: theme32.textSubtle, children: prompt.hint }) }),
|
|
14612
|
+
/* @__PURE__ */ jsx34(Box29, { flexDirection: "column", marginTop: 1, children: prompt.choices.map((choice, index) => {
|
|
13982
14613
|
const isSelected = index === selectedPromptIndex;
|
|
13983
|
-
return /* @__PURE__ */
|
|
13984
|
-
/* @__PURE__ */
|
|
13985
|
-
/* @__PURE__ */
|
|
14614
|
+
return /* @__PURE__ */ jsxs27(Box29, { marginTop: index === 0 ? 0 : 1, children: [
|
|
14615
|
+
/* @__PURE__ */ jsx34(Text29, { color: isSelected ? theme32.accent : theme32.textSubtle, bold: isSelected, children: isSelected ? "\u203A " : " " }),
|
|
14616
|
+
/* @__PURE__ */ jsx34(Text29, { color: isSelected ? theme32.text : theme32.textSubtle, bold: isSelected, children: `${index + 1} ${choice.label}` })
|
|
13986
14617
|
] }, choice.value);
|
|
13987
14618
|
}) }),
|
|
13988
|
-
selectedChoice && /* @__PURE__ */
|
|
13989
|
-
/* @__PURE__ */
|
|
14619
|
+
selectedChoice && /* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text29, { color: theme32.textSubtle, children: selectedChoice.description }) }),
|
|
14620
|
+
/* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text29, { color: theme32.border, children: SCROLL_HINT }) })
|
|
13990
14621
|
] })
|
|
13991
14622
|
]
|
|
13992
14623
|
}
|
|
@@ -16050,6 +16681,39 @@ function buildMarathonClientHeaders(devPlanOverride) {
|
|
|
16050
16681
|
...devPlanOverride ? { "X-Dev-Plan-Override": devPlanOverride } : {}
|
|
16051
16682
|
};
|
|
16052
16683
|
}
|
|
16684
|
+
function normalizeMarathonAgentArgument(agent) {
|
|
16685
|
+
const trimmed = agent.trim();
|
|
16686
|
+
if (trimmed.length < 2) return trimmed;
|
|
16687
|
+
const matchingQuotePairs = [
|
|
16688
|
+
['"', '"'],
|
|
16689
|
+
["'", "'"],
|
|
16690
|
+
["\u201C", "\u201D"],
|
|
16691
|
+
["\u2018", "\u2019"]
|
|
16692
|
+
];
|
|
16693
|
+
for (const [openQuote, closeQuote] of matchingQuotePairs) {
|
|
16694
|
+
if (trimmed.startsWith(openQuote) && trimmed.endsWith(closeQuote)) {
|
|
16695
|
+
const unwrapped = trimmed.slice(openQuote.length, trimmed.length - closeQuote.length).trim();
|
|
16696
|
+
return unwrapped || trimmed;
|
|
16697
|
+
}
|
|
16698
|
+
}
|
|
16699
|
+
return trimmed;
|
|
16700
|
+
}
|
|
16701
|
+
function buildMarathonAutoCreatedAgentBootstrap(agentName, options = {}) {
|
|
16702
|
+
const normalizedModel = options.model?.trim();
|
|
16703
|
+
const normalizedToolIds = [...new Set((options.toolIds || []).map((toolId) => toolId.trim()).filter(Boolean))];
|
|
16704
|
+
const config2 = normalizedModel || normalizedToolIds.length > 0 ? {
|
|
16705
|
+
...normalizedModel ? { model: normalizedModel } : {},
|
|
16706
|
+
...normalizedToolIds.length > 0 ? {
|
|
16707
|
+
tools: {
|
|
16708
|
+
toolIds: normalizedToolIds
|
|
16709
|
+
}
|
|
16710
|
+
} : {}
|
|
16711
|
+
} : void 0;
|
|
16712
|
+
return {
|
|
16713
|
+
description: `Powering a marathon for ${agentName}`,
|
|
16714
|
+
...config2 ? { config: config2 } : {}
|
|
16715
|
+
};
|
|
16716
|
+
}
|
|
16053
16717
|
var DEFAULT_TOOL_OUTPUT_WARNING_CHARS = 4e4;
|
|
16054
16718
|
var DEFAULT_TOOL_OUTPUT_OFFLOAD_CHARS = 1e5;
|
|
16055
16719
|
function parseCompactStrategy(value) {
|
|
@@ -16087,6 +16751,7 @@ function resolveToolOutputGuardrails(rawThreshold) {
|
|
|
16087
16751
|
};
|
|
16088
16752
|
}
|
|
16089
16753
|
async function taskAction(agent, options) {
|
|
16754
|
+
const normalizedAgent = normalizeMarathonAgentArgument(agent);
|
|
16090
16755
|
if (!options.resume && !options.goal) {
|
|
16091
16756
|
console.error(chalk16.red("Error: -g, --goal <text> is required for new tasks"));
|
|
16092
16757
|
console.log(chalk16.gray(" Use --resume to continue an existing task without a new goal"));
|
|
@@ -16187,8 +16852,9 @@ async function taskAction(agent, options) {
|
|
|
16187
16852
|
}
|
|
16188
16853
|
process.exit(1);
|
|
16189
16854
|
};
|
|
16190
|
-
let agentId =
|
|
16191
|
-
|
|
16855
|
+
let agentId = normalizedAgent;
|
|
16856
|
+
let autoCreatedAgent = false;
|
|
16857
|
+
if (!normalizedAgent.startsWith("agent_")) {
|
|
16192
16858
|
if (useStartupShell) {
|
|
16193
16859
|
setStartupStatus("looking up agent");
|
|
16194
16860
|
} else {
|
|
@@ -16197,7 +16863,7 @@ async function taskAction(agent, options) {
|
|
|
16197
16863
|
try {
|
|
16198
16864
|
const list = await client.agents.list();
|
|
16199
16865
|
const found = list.data.find(
|
|
16200
|
-
(a) => a.name.toLowerCase() ===
|
|
16866
|
+
(a) => a.name.toLowerCase() === normalizedAgent.toLowerCase()
|
|
16201
16867
|
);
|
|
16202
16868
|
if (found) {
|
|
16203
16869
|
agentId = found.id;
|
|
@@ -16208,13 +16874,14 @@ async function taskAction(agent, options) {
|
|
|
16208
16874
|
}
|
|
16209
16875
|
} else {
|
|
16210
16876
|
if (useStartupShell) {
|
|
16211
|
-
setStartupStatus(`creating agent ${
|
|
16877
|
+
setStartupStatus(`creating agent ${normalizedAgent}`);
|
|
16212
16878
|
} else {
|
|
16213
|
-
console.log(chalk16.gray(`Creating agent "${
|
|
16879
|
+
console.log(chalk16.gray(`Creating agent "${normalizedAgent}"...`));
|
|
16214
16880
|
}
|
|
16215
16881
|
try {
|
|
16216
|
-
const created = await client.agents.create({ name:
|
|
16882
|
+
const created = await client.agents.create({ name: normalizedAgent });
|
|
16217
16883
|
agentId = created.id;
|
|
16884
|
+
autoCreatedAgent = true;
|
|
16218
16885
|
if (useStartupShell) {
|
|
16219
16886
|
setStartupStatus(`agent created: ${agentId}`);
|
|
16220
16887
|
} else {
|
|
@@ -16223,7 +16890,7 @@ async function taskAction(agent, options) {
|
|
|
16223
16890
|
} catch (createErr) {
|
|
16224
16891
|
const errMsg = createErr instanceof Error ? createErr.message : String(createErr);
|
|
16225
16892
|
await failBeforeMain([
|
|
16226
|
-
chalk16.red(`Failed to create agent "${
|
|
16893
|
+
chalk16.red(`Failed to create agent "${normalizedAgent}"`),
|
|
16227
16894
|
chalk16.red(errMsg)
|
|
16228
16895
|
]);
|
|
16229
16896
|
}
|
|
@@ -16474,7 +17141,9 @@ async function taskAction(agent, options) {
|
|
|
16474
17141
|
const remainingCost = maxCost ? maxCost - priorCost : void 0;
|
|
16475
17142
|
const baseMessage = options.goal || (resumeRequested ? "Continue the task." : "");
|
|
16476
17143
|
const sandboxPrompt = parsedSandbox ? createSandboxInstructions(parsedSandbox) : "";
|
|
16477
|
-
const
|
|
17144
|
+
const sandboxWorkflowSelection = playbookWorkflow ? void 0 : resolveSandboxWorkflowSelection(baseMessage, parsedSandbox, resumeState);
|
|
17145
|
+
parsedSandbox = sandboxWorkflowSelection?.sandboxProvider ?? parsedSandbox;
|
|
17146
|
+
const resolvedWorkflow = playbookWorkflow ?? sandboxWorkflowSelection?.workflow;
|
|
16478
17147
|
const DEFAULT_MILESTONE_NAMES = ["research", "planning", "execution"];
|
|
16479
17148
|
const EXTERNAL_MILESTONE_NAMES = ["research", "report"];
|
|
16480
17149
|
const detectedVariant = resumeState?.workflowVariant ?? defaultWorkflow.classifyVariant?.(baseMessage);
|
|
@@ -16494,6 +17163,26 @@ ${rulesContext}`;
|
|
|
16494
17163
|
defaultModel: options.model
|
|
16495
17164
|
}, playbookMilestoneModels);
|
|
16496
17165
|
if (resolvedModel) options.model = resolvedModel;
|
|
17166
|
+
if (autoCreatedAgent) {
|
|
17167
|
+
const bootstrapPayload = buildMarathonAutoCreatedAgentBootstrap(normalizedAgent, {
|
|
17168
|
+
model: options.model || agentConfigModel || defaultConfiguredModel,
|
|
17169
|
+
toolIds: resolvedToolIds
|
|
17170
|
+
});
|
|
17171
|
+
try {
|
|
17172
|
+
await client.agents.update(agentId, bootstrapPayload);
|
|
17173
|
+
} catch (error) {
|
|
17174
|
+
const warningMessage = error instanceof Error ? error.message : String(error);
|
|
17175
|
+
if (useStartupShell) {
|
|
17176
|
+
setStartupStatus("warning: could not persist initial agent settings");
|
|
17177
|
+
} else {
|
|
17178
|
+
console.log(
|
|
17179
|
+
chalk16.yellow(
|
|
17180
|
+
`Warning: created agent "${normalizedAgent}" but could not persist initial marathon settings (${warningMessage})`
|
|
17181
|
+
)
|
|
17182
|
+
);
|
|
17183
|
+
}
|
|
17184
|
+
}
|
|
17185
|
+
}
|
|
16497
17186
|
let localTools = buildLocalTools(client, parsedSandbox, options, {
|
|
16498
17187
|
taskName,
|
|
16499
17188
|
stateDir: options.stateDir
|
|
@@ -17190,8 +17879,7 @@ ${details}`);
|
|
|
17190
17879
|
}
|
|
17191
17880
|
return resolved;
|
|
17192
17881
|
}
|
|
17193
|
-
function
|
|
17194
|
-
if (sandboxProvider !== "daytona") return void 0;
|
|
17882
|
+
function detectSandboxWorkflow(message, resumeState) {
|
|
17195
17883
|
if (resumeState?.workflowVariant === "game") return gameWorkflow;
|
|
17196
17884
|
if (resumeState?.workflowPhase === "design" || resumeState?.workflowPhase === "build" || resumeState?.workflowPhase === "verify") {
|
|
17197
17885
|
return gameWorkflow;
|
|
@@ -17220,10 +17908,16 @@ function detectDeployWorkflow(message, sandboxProvider, resumeState) {
|
|
|
17220
17908
|
/\bsandbox\b/,
|
|
17221
17909
|
/\bpreview\s*url\b/,
|
|
17222
17910
|
/\blive\s*preview\b/,
|
|
17223
|
-
/\bhost
|
|
17224
|
-
/\b(?:app|server|api|site)\b.*\bhost
|
|
17225
|
-
/\
|
|
17226
|
-
/\
|
|
17911
|
+
/\bhost(?:ed|ing)?\b.*\b(?:app|server|api|site)\b/,
|
|
17912
|
+
/\b(?:app|server|api|site)\b.*\bhost(?:ed|ing)?\b/,
|
|
17913
|
+
/\b(?:run|launch|start)\b.*\b(?:app|server|api|site|web\s*app|web\s*server)\b/,
|
|
17914
|
+
/\bnpx\s+serve\b/,
|
|
17915
|
+
/\bserve(?:d|s|ing)?\b.*\b(?:app|site|preview|route|routes|localhost|url|urls)\b/,
|
|
17916
|
+
/\b(?:route|routes|preview|localhost|url|urls)\b.*\bserve(?:d|s|ing)?\b/,
|
|
17917
|
+
/\bverify\b.*\b(?:route|routes|preview|localhost|url|urls)\b/,
|
|
17918
|
+
/\bmulti[-\s]route\b/,
|
|
17919
|
+
/\b(?:serve|start|run|listen)\b.{0,40}\bport\s*\d{2,5}\b/,
|
|
17920
|
+
/\bport\s*\d{2,5}\b.{0,40}\b(?:serve|server|preview|localhost|route|routes)\b/
|
|
17227
17921
|
];
|
|
17228
17922
|
if (deployPatterns.some((p) => p.test(lower))) {
|
|
17229
17923
|
return deployWorkflow;
|
|
@@ -17233,15 +17927,34 @@ function detectDeployWorkflow(message, sandboxProvider, resumeState) {
|
|
|
17233
17927
|
/\bcreate\b.*\b(?:web\s*app|website|api|server|express|hono|fastify)\b/,
|
|
17234
17928
|
/\bmake\b.*\b(?:web\s*app|website|api|server|express|hono|fastify)\b/
|
|
17235
17929
|
];
|
|
17236
|
-
const
|
|
17237
|
-
/\b(?:file|repo|repository|codebase|project|directory|folder)\b/,
|
|
17238
|
-
/\b(?:edit|modify|update|fix|refactor|change)\b/
|
|
17930
|
+
const repoEditPatterns = [
|
|
17931
|
+
/\b(?:edit|modify|update|fix|refactor|change|patch|rename|remove)\b.*\b(?:file|files|repo|repository|codebase|project|directory|folder|component|module|page|route|router)\b/,
|
|
17932
|
+
/\b(?:file|files|repo|repository|codebase|project|directory|folder|component|module|page|route|router)\b.*\b(?:edit|modify|update|fix|refactor|change|patch|rename|remove)\b/
|
|
17239
17933
|
];
|
|
17240
|
-
if (webAppPatterns.some((p) => p.test(lower)) && !
|
|
17934
|
+
if (webAppPatterns.some((p) => p.test(lower)) && !repoEditPatterns.some((p) => p.test(lower))) {
|
|
17241
17935
|
return deployWorkflow;
|
|
17242
17936
|
}
|
|
17243
17937
|
return void 0;
|
|
17244
17938
|
}
|
|
17939
|
+
function resolveSandboxWorkflowSelection(message, sandboxProvider, resumeState) {
|
|
17940
|
+
if (sandboxProvider && sandboxProvider !== "daytona") {
|
|
17941
|
+
return {
|
|
17942
|
+
workflow: void 0,
|
|
17943
|
+
sandboxProvider
|
|
17944
|
+
};
|
|
17945
|
+
}
|
|
17946
|
+
const workflow = detectSandboxWorkflow(message, resumeState);
|
|
17947
|
+
if (!workflow) {
|
|
17948
|
+
return {
|
|
17949
|
+
workflow: void 0,
|
|
17950
|
+
sandboxProvider
|
|
17951
|
+
};
|
|
17952
|
+
}
|
|
17953
|
+
return {
|
|
17954
|
+
workflow,
|
|
17955
|
+
sandboxProvider: sandboxProvider ?? "daytona"
|
|
17956
|
+
};
|
|
17957
|
+
}
|
|
17245
17958
|
function applyTaskOptions(cmd) {
|
|
17246
17959
|
return cmd.argument("<agent>", "Agent ID or name").option("-g, --goal <text>", "Goal message for the agent").option("--max-sessions <n>", "Maximum sessions", "50").option("--max-cost <n>", "Budget in USD").option("--model <modelId>", "Model ID to use (overrides agent config)").option("--name <name>", "Task name (used for state file, defaults to agent name)").option("--session <name>", "Resume a specific session by name").option("--state-dir <path>", "Directory for state files (default: ~/.runtype/projects/<hash>/marathons/)").option("--resume [message]", "Resume from existing local state, optionally with a new message").option("--fresh", "Start a new run and ignore any existing local state for this task").option("--compact", "Force compact-summary resume mode instead of replaying full history").option("--compact-strategy <strategy>", "Compaction strategy: auto (default), provider_native, or summary_fallback").option("--compact-threshold <value>", "Auto-compact when estimated context crosses this threshold (default: 80% fallback, 90% native; accepts percent like 90% or absolute token count like 120000)").option("--compact-instructions <text>", "Extra instructions for what a compact summary must preserve").option("--no-auto-compact", "Disable automatic context-aware history compaction").option("--track", "Sync progress to a Runtype record (visible in dashboard)").option("--debug", "Show debug output from each session").option("--json", "Output final result as JSON").option("--sandbox <provider>", "Enable sandbox code execution tool (cloudflare-worker, quickjs, or daytona)").option("--no-local-tools", "Disable built-in local tool execution (read_file, write_file, list_directory)").option("-t, --tools <tools...>", "Enable built-in tools (e.g., exa, firecrawl, dalle, openai_web_search, anthropic_web_search)").option("--plain-text", "Disable markdown rendering in output").option("--no-checkpoint", "Run all iterations without checkpoint pauses (fully autonomous)").option("--checkpoint-timeout <seconds>", "Auto-continue timeout in seconds (default: 10)", "10").option("--planning-model <modelId>", "Model to use during research/planning phases").option("--execution-model <modelId>", "Model to use during execution phase").option("--playbook <name>", "Load a playbook from .runtype/marathons/playbooks/").option("--offload-threshold <chars>", 'Offload tool outputs larger than this to files (default: 100000; use "off" or "0" to disable guardrails)').option("--tool-context <mode>", "Tool result storage: hot-tail (default), observation-mask, or full-inline").option("--tool-window <window>", 'Compaction window: "session" (default) or a number for last-N tool results (e.g. 10)').option("--runner-char <char>", "Custom runner emoji (default: \u{1F3C3})").option("--finish-char <char>", "Custom finish line emoji (default: \u{1F3C1})").option("--no-runner", "Hide the runner emoji from the header border").option("--no-finish", "Hide the finish line emoji from the header border").action(taskAction);
|
|
17247
17960
|
}
|