@runtypelabs/cli 1.5.4 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -128,7 +128,7 @@ var init_credential_store = __esm({
128
128
  import { Command as Command20 } from "commander";
129
129
  import chalk25 from "chalk";
130
130
  import { config as loadEnv } from "dotenv";
131
- import { readFileSync as readFileSync9 } from "fs";
131
+ import { readFileSync as readFileSync10 } from "fs";
132
132
  import { dirname as dirname4, join as join6 } from "path";
133
133
  import { fileURLToPath } from "url";
134
134
 
@@ -2937,10 +2937,10 @@ ${userInput}`;
2937
2937
  };
2938
2938
 
2939
2939
  // src/ink/talk/TalkApp.tsx
2940
- import { useState as useState10, useEffect as useEffect9, useRef as useRef4 } from "react";
2940
+ import { useState as useState11, useEffect as useEffect9, useRef as useRef4 } from "react";
2941
2941
  import fs3 from "fs";
2942
2942
  import path3 from "path";
2943
- import { Box as Box11, useApp as useApp3, useInput as useInput7, useStdout } from "ink";
2943
+ import { Box as Box11, useApp as useApp3, useInput as useInput7, useStdout as useStdout2 } from "ink";
2944
2944
  import { StatusBar, ErrorDisplay as ErrorDisplay3, theme as theme12 } from "@runtypelabs/ink-components";
2945
2945
 
2946
2946
  // src/ink/talk/useTalkStream.ts
@@ -3362,29 +3362,114 @@ function ChatInput({
3362
3362
  }
3363
3363
 
3364
3364
  // src/ink/talk/ModelPicker.tsx
3365
- import { Box as Box10, Text as Text11, useInput as useInput6 } from "ink";
3366
- import SelectInput2 from "ink-select-input";
3365
+ import { useState as useState10, useMemo as useMemo2, useCallback as useCallback3 } from "react";
3366
+ import { Box as Box10, Text as Text11, useInput as useInput6, useStdout } from "ink";
3367
+ import TextInput2 from "ink-text-input";
3368
+ import open2 from "open";
3367
3369
  import { theme as theme11 } from "@runtypelabs/ink-components";
3368
3370
  import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
3369
- var MODELS = [
3370
- { label: "Claude Sonnet 4.5", value: "claude-sonnet-4-5" },
3371
- { label: "Claude Haiku 3.5", value: "claude-3-5-haiku" },
3372
- { label: "GPT-5 Mini", value: "gpt-5-mini" },
3373
- { label: "GPT-4.1 Mini", value: "gpt-4.1-mini" },
3374
- { label: "Gemini 3 Flash", value: "gemini-3-flash" },
3375
- { label: "Gemini 2.5 Flash", value: "gemini-2.5-flash" }
3371
+ var ALL_MODELS = [
3372
+ // Anthropic
3373
+ { label: "Claude Opus 4.6", value: "claude-opus-4-6", group: "Anthropic" },
3374
+ { label: "Claude Sonnet 4.6", value: "claude-sonnet-4-6", group: "Anthropic" },
3375
+ { label: "Claude Haiku 4.5", value: "claude-haiku-4-5", group: "Anthropic" },
3376
+ // OpenAI
3377
+ { label: "GPT-5", value: "gpt-5", group: "OpenAI" },
3378
+ { label: "GPT-5 Mini", value: "gpt-5-mini", group: "OpenAI" },
3379
+ { label: "GPT-4.1", value: "gpt-4.1", group: "OpenAI" },
3380
+ { label: "GPT-4.1 Mini", value: "gpt-4.1-mini", group: "OpenAI" },
3381
+ { label: "GPT-4.1 Nano", value: "gpt-4.1-nano", group: "OpenAI" },
3382
+ { label: "GPT-5 Nano", value: "gpt-5-nano", group: "OpenAI" },
3383
+ // Google
3384
+ { label: "Gemini 3.1 Pro", value: "gemini-3.1-pro", group: "Google" },
3385
+ { label: "Gemini 3 Pro Image", value: "gemini-3-pro-image", group: "Google" },
3386
+ { label: "Gemini 3 Flash", value: "gemini-3-flash", group: "Google" },
3387
+ { label: "Gemini 2.5 Pro", value: "gemini-2.5-pro", group: "Google" },
3388
+ { label: "Gemini 2.5 Flash", value: "gemini-2.5-flash", group: "Google" },
3389
+ { label: "Gemini 2.5 Flash Image", value: "gemini-2.5-flash-image", group: "Google" },
3390
+ { label: "Gemini 2.5 Flash-Lite", value: "gemini-2.5-flash-lite", group: "Google" },
3391
+ // xAI
3392
+ { label: "Grok 4", value: "grok-4", group: "xAI" },
3393
+ { label: "Grok 4 Fast", value: "grok-4-fast", group: "xAI" },
3394
+ { label: "Grok 4.1 Fast", value: "grok-4.1-fast", group: "xAI" },
3395
+ // Qwen
3396
+ { label: "Qwen 3.5 Plus", value: "qwen3.5-plus", group: "Qwen" },
3397
+ { label: "Qwen 3.5 35B A3B", value: "qwen3.5-35b-a3b", group: "Qwen" },
3398
+ { label: "Qwen 3.5 Flash", value: "qwen3.5-flash", group: "Qwen" },
3399
+ { label: "Qwen 3 8B", value: "qwen/qwen3-8b", group: "Qwen" }
3376
3400
  ];
3401
+ var MAX_VISIBLE = 12;
3377
3402
  function ModelPicker({ currentModel, onSelect, onCancel }) {
3403
+ const { stdout } = useStdout();
3404
+ const [search, setSearch] = useState10("");
3405
+ const [selectedIndex, setSelectedIndex] = useState10(0);
3406
+ const contentWidth = (stdout?.columns ?? 120) - 4;
3407
+ const pad = useCallback3(
3408
+ (text) => text.length < contentWidth ? text + " ".repeat(contentWidth - text.length) : text,
3409
+ [contentWidth]
3410
+ );
3411
+ const filtered = useMemo2(() => {
3412
+ if (!search.trim()) return ALL_MODELS;
3413
+ const q = search.toLowerCase();
3414
+ return ALL_MODELS.filter(
3415
+ (m) => m.label.toLowerCase().includes(q) || m.value.toLowerCase().includes(q) || m.group.toLowerCase().includes(q)
3416
+ );
3417
+ }, [search]);
3418
+ const handleSearchChange = (value) => {
3419
+ if (value === search) return;
3420
+ setSearch(value);
3421
+ setSelectedIndex(0);
3422
+ };
3378
3423
  useInput6((_input, key) => {
3379
3424
  if (key.escape) {
3380
3425
  onCancel();
3426
+ return;
3427
+ }
3428
+ if (key.return) {
3429
+ if (filtered.length > 0) {
3430
+ onSelect(filtered[selectedIndex].value);
3431
+ }
3432
+ return;
3433
+ }
3434
+ if (key.upArrow) {
3435
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : filtered.length - 1);
3436
+ return;
3437
+ }
3438
+ if (key.downArrow) {
3439
+ setSelectedIndex((prev) => prev < filtered.length - 1 ? prev + 1 : 0);
3440
+ return;
3441
+ }
3442
+ if (key.tab) {
3443
+ void open2(`${getDashboardUrl()}/settings/models`);
3444
+ return;
3381
3445
  }
3382
3446
  });
3383
- const items = MODELS.map((m) => ({
3384
- label: m.value === currentModel ? `${m.label} *` : m.label,
3385
- value: m.value
3386
- }));
3387
- const initialIndex = Math.max(0, MODELS.findIndex((m) => m.value === currentModel));
3447
+ const MODEL_WINDOW = MAX_VISIBLE - 4;
3448
+ const modelWindowStart = Math.max(
3449
+ 0,
3450
+ Math.min(
3451
+ selectedIndex - Math.floor(MODEL_WINDOW / 2),
3452
+ filtered.length - MODEL_WINDOW
3453
+ )
3454
+ );
3455
+ const modelWindowEnd = Math.min(modelWindowStart + MODEL_WINDOW, filtered.length);
3456
+ const rows = [];
3457
+ let lastGroup = "";
3458
+ for (let i = modelWindowStart; i < modelWindowEnd; i++) {
3459
+ const model = filtered[i];
3460
+ if (model.group !== lastGroup) {
3461
+ rows.push({ type: "group", label: model.group });
3462
+ lastGroup = model.group;
3463
+ }
3464
+ rows.push({
3465
+ type: "model",
3466
+ model,
3467
+ isHighlighted: i === selectedIndex,
3468
+ isCurrent: model.value === currentModel
3469
+ });
3470
+ }
3471
+ const showScrollUp = modelWindowStart > 0;
3472
+ const showScrollDown = modelWindowEnd < filtered.length;
3388
3473
  return /* @__PURE__ */ jsxs9(
3389
3474
  Box10,
3390
3475
  {
@@ -3395,18 +3480,44 @@ function ModelPicker({ currentModel, onSelect, onCancel }) {
3395
3480
  paddingY: theme11.panelPaddingY,
3396
3481
  flexDirection: "column",
3397
3482
  children: [
3398
- /* @__PURE__ */ jsx11(Text11, { color: theme11.accent, bold: true, children: "Select Model" }),
3399
- /* @__PURE__ */ jsx11(Text11, { color: theme11.textSubtle, children: "Esc to cancel" }),
3400
- /* @__PURE__ */ jsx11(
3401
- SelectInput2,
3402
- {
3403
- items,
3404
- onSelect: (item) => onSelect(item.value),
3405
- initialIndex,
3406
- indicatorComponent: ThemedSelectIndicator,
3407
- itemComponent: ThemedSelectItem
3483
+ /* @__PURE__ */ jsxs9(Box10, { marginBottom: 1, children: [
3484
+ /* @__PURE__ */ jsx11(Text11, { color: theme11.accent, bold: true, children: "Select Model" }),
3485
+ /* @__PURE__ */ jsxs9(Text11, { color: theme11.textSubtle, children: [
3486
+ " ",
3487
+ filtered.length,
3488
+ " models"
3489
+ ] })
3490
+ ] }),
3491
+ /* @__PURE__ */ jsxs9(Box10, { marginBottom: 1, children: [
3492
+ /* @__PURE__ */ jsx11(Text11, { color: theme11.textSubtle, children: "/ " }),
3493
+ /* @__PURE__ */ jsx11(
3494
+ TextInput2,
3495
+ {
3496
+ value: search,
3497
+ onChange: handleSearchChange,
3498
+ placeholder: "Search models..."
3499
+ }
3500
+ )
3501
+ ] }),
3502
+ /* @__PURE__ */ jsx11(Box10, { height: 1, children: /* @__PURE__ */ jsx11(Text11, { color: theme11.textSubtle, children: pad(showScrollUp ? " ..." : "") }) }),
3503
+ /* @__PURE__ */ jsx11(Box10, { flexDirection: "column", height: MAX_VISIBLE, children: filtered.length === 0 ? /* @__PURE__ */ jsx11(Text11, { color: theme11.textSubtle, children: " No matching models" }) : rows.map((row) => {
3504
+ if (row.type === "group") {
3505
+ return /* @__PURE__ */ jsx11(Box10, { children: /* @__PURE__ */ jsx11(Text11, { color: theme11.textSubtle, dimColor: true, children: pad(` ${row.label}`) }) }, `group-${row.label}`);
3408
3506
  }
3409
- )
3507
+ const { model, isHighlighted, isCurrent } = row;
3508
+ const indicator = isHighlighted ? "\u203A " : " ";
3509
+ const suffix = isCurrent ? " *" : "";
3510
+ return /* @__PURE__ */ jsx11(Box10, { children: /* @__PURE__ */ jsx11(
3511
+ Text11,
3512
+ {
3513
+ color: isHighlighted ? theme11.accentActive : isCurrent ? theme11.accent : theme11.textMuted,
3514
+ bold: isHighlighted,
3515
+ children: pad(`${indicator}${model.label}${suffix}`)
3516
+ }
3517
+ ) }, model.value);
3518
+ }) }),
3519
+ /* @__PURE__ */ jsx11(Box10, { height: 1, children: /* @__PURE__ */ jsx11(Text11, { color: theme11.textSubtle, children: pad(showScrollDown ? " ..." : "") }) }),
3520
+ /* @__PURE__ */ jsx11(Box10, { marginTop: 1, children: /* @__PURE__ */ jsx11(Text11, { color: theme11.textSubtle, children: ["\u2191\u2193 navigate", "Enter select", "Tab manage models", "Esc cancel"].join(theme11.separator ?? " \xB7 ") }) })
3410
3521
  ]
3411
3522
  }
3412
3523
  );
@@ -3430,7 +3541,7 @@ function TalkApp({
3430
3541
  }) {
3431
3542
  const { state, callbacks, reset, contentRef } = useTalkStream();
3432
3543
  const { exit } = useApp3();
3433
- const { stdout } = useStdout();
3544
+ const { stdout } = useStdout2();
3434
3545
  const separator = theme12.separator ?? " \xB7 ";
3435
3546
  useEffect9(() => {
3436
3547
  streamRef.current = {
@@ -3438,16 +3549,16 @@ function TalkApp({
3438
3549
  getState: () => state
3439
3550
  };
3440
3551
  });
3441
- const [messages, setMessages] = useState10([]);
3442
- const [scrollOffset, setScrollOffset] = useState10(0);
3443
- const [enableMarkdown, setEnableMarkdown] = useState10(initialMarkdown);
3444
- const [currentModel, setCurrentModel] = useState10(model);
3445
- const [showModelPicker, setShowModelPicker] = useState10(false);
3552
+ const [messages, setMessages] = useState11([]);
3553
+ const [scrollOffset, setScrollOffset] = useState11(0);
3554
+ const [enableMarkdown, setEnableMarkdown] = useState11(initialMarkdown);
3555
+ const [currentModel, setCurrentModel] = useState11(model);
3556
+ const [showModelPicker, setShowModelPicker] = useState11(false);
3446
3557
  const terminalWidth = stdout?.columns ?? 120;
3447
3558
  const terminalRows = stdout?.rows ?? 40;
3448
3559
  const contentHeight = Math.max(5, terminalRows - CHROME_ROWS);
3449
3560
  const isStreaming = state.phase === "thinking" || state.phase === "streaming";
3450
- const [ctrlCPressed, setCtrlCPressed] = useState10(false);
3561
+ const [ctrlCPressed, setCtrlCPressed] = useState11(false);
3451
3562
  const ctrlCTimeout = useRef4(null);
3452
3563
  function appendSystemMessage(text) {
3453
3564
  setMessages((prev) => [
@@ -3827,8 +3938,8 @@ import { Command as Command8 } from "commander";
3827
3938
  import chalk11 from "chalk";
3828
3939
  import React9 from "react";
3829
3940
  import { render as render7 } from "ink";
3830
- import { useState as useState11, useEffect as useEffect10 } from "react";
3831
- import open2 from "open";
3941
+ import { useState as useState12, useEffect as useEffect10 } from "react";
3942
+ import open3 from "open";
3832
3943
  function displayAgentCard(agentCard) {
3833
3944
  console.log(chalk11.cyan("\nAgent Details:"));
3834
3945
  console.log(` Name: ${agentCard.name}`);
@@ -3967,7 +4078,7 @@ productsCommand.command("init").description("Initialize a product from an extern
3967
4078
  } else {
3968
4079
  console.log(chalk11.cyan("\nOpening browser to complete setup..."));
3969
4080
  }
3970
- await open2(targetUrl);
4081
+ await open3(targetUrl);
3971
4082
  return;
3972
4083
  }
3973
4084
  const createResult = await createProduct(
@@ -4001,11 +4112,11 @@ productsCommand.command("init").description("Initialize a product from an extern
4001
4112
  return;
4002
4113
  }
4003
4114
  const ProductInitApp = () => {
4004
- const [loading, setLoading] = useState11(!!options.from);
4005
- const [loadingLabel, setLoadingLabel] = useState11("Validating URL...");
4006
- const [success, setSuccess] = useState11(null);
4007
- const [error, setError] = useState11(null);
4008
- const [resultNode, setResultNode] = useState11(void 0);
4115
+ const [loading, setLoading] = useState12(!!options.from);
4116
+ const [loadingLabel, setLoadingLabel] = useState12("Validating URL...");
4117
+ const [success, setSuccess] = useState12(null);
4118
+ const [error, setError] = useState12(null);
4119
+ const [resultNode, setResultNode] = useState12(void 0);
4009
4120
  useEffect10(() => {
4010
4121
  if (!options.from) return void 0;
4011
4122
  const run = async () => {
@@ -4029,7 +4140,7 @@ productsCommand.command("init").description("Initialize a product from an extern
4029
4140
  const dashboardUrl2 = getDashboardUrl();
4030
4141
  const encodedUrl = encodeURIComponent(options.from);
4031
4142
  const targetUrl = `${dashboardUrl2}/now?from=${encodedUrl}&cli=true`;
4032
- await open2(targetUrl);
4143
+ await open3(targetUrl);
4033
4144
  setSuccess(true);
4034
4145
  setLoading(false);
4035
4146
  setResultNode(
@@ -4130,10 +4241,10 @@ import { render as render8 } from "ink";
4130
4241
 
4131
4242
  // src/ink/init/InitApp.tsx
4132
4243
  init_credential_store();
4133
- import { useState as useState12, useEffect as useEffect11, useCallback as useCallback3 } from "react";
4244
+ import { useState as useState13, useEffect as useEffect11, useCallback as useCallback4 } from "react";
4134
4245
  import { Box as Box14, Text as Text14, useApp as useApp4, useInput as useInput8 } from "ink";
4135
- import TextInput2 from "ink-text-input";
4136
- import SelectInput3 from "ink-select-input";
4246
+ import TextInput3 from "ink-text-input";
4247
+ import SelectInput2 from "ink-select-input";
4137
4248
  import { Spinner as Spinner4, theme as theme15 } from "@runtypelabs/ink-components";
4138
4249
 
4139
4250
  // src/ink/init/WizardStep.tsx
@@ -4189,7 +4300,7 @@ function getStepNumber(step) {
4189
4300
  }
4190
4301
  function InitApp({ apiUrl, onComplete }) {
4191
4302
  const { exit } = useApp4();
4192
- const [state, setState] = useState12({
4303
+ const [state, setState] = useState13({
4193
4304
  step: 0,
4194
4305
  authMethod: null,
4195
4306
  apiKey: null,
@@ -4205,7 +4316,7 @@ function InitApp({ apiUrl, onComplete }) {
4205
4316
  complete: false,
4206
4317
  createdProductId: null
4207
4318
  });
4208
- const getSummary = useCallback3(() => {
4319
+ const getSummary = useCallback4(() => {
4209
4320
  const answers = [];
4210
4321
  if (state.authMethod) {
4211
4322
  const labels = {
@@ -4276,7 +4387,7 @@ function InitApp({ apiUrl, onComplete }) {
4276
4387
  },
4277
4388
  { isActive: !state.loading && !state.complete }
4278
4389
  );
4279
- const handleAuthMethodSelect = useCallback3(
4390
+ const handleAuthMethodSelect = useCallback4(
4280
4391
  (item) => {
4281
4392
  const method = item.value;
4282
4393
  setState((prev) => ({
@@ -4335,7 +4446,7 @@ function InitApp({ apiUrl, onComplete }) {
4335
4446
  },
4336
4447
  [apiUrl]
4337
4448
  );
4338
- const handleApiKeySubmit = useCallback3(
4449
+ const handleApiKeySubmit = useCallback4(
4339
4450
  (value) => {
4340
4451
  if (!value.trim()) {
4341
4452
  setState((prev) => ({ ...prev, error: "API key is required" }));
@@ -4390,7 +4501,7 @@ function InitApp({ apiUrl, onComplete }) {
4390
4501
  },
4391
4502
  [apiUrl]
4392
4503
  );
4393
- const handleProductChoice = useCallback3(
4504
+ const handleProductChoice = useCallback4(
4394
4505
  (item) => {
4395
4506
  const choice = item.value;
4396
4507
  setState((prev) => ({
@@ -4405,7 +4516,7 @@ function InitApp({ apiUrl, onComplete }) {
4405
4516
  },
4406
4517
  []
4407
4518
  );
4408
- const handleUrlSubmit = useCallback3(
4519
+ const handleUrlSubmit = useCallback4(
4409
4520
  (value) => {
4410
4521
  if (!value.trim()) {
4411
4522
  setState((prev) => ({ ...prev, error: "URL is required" }));
@@ -4472,14 +4583,14 @@ function InitApp({ apiUrl, onComplete }) {
4472
4583
  },
4473
4584
  [apiUrl]
4474
4585
  );
4475
- const handleConfirmCreate = useCallback3((confirmed) => {
4586
+ const handleConfirmCreate = useCallback4((confirmed) => {
4476
4587
  if (!confirmed) {
4477
4588
  setState((prev) => ({ ...prev, step: 8, complete: true }));
4478
4589
  return;
4479
4590
  }
4480
4591
  setState((prev) => ({ ...prev, step: 6 }));
4481
4592
  }, []);
4482
- const handleProductNameSubmit = useCallback3(
4593
+ const handleProductNameSubmit = useCallback4(
4483
4594
  (value) => {
4484
4595
  const name = value.trim() || state.agentCard?.name || "My Product";
4485
4596
  setState((prev) => ({
@@ -4579,7 +4690,7 @@ function InitApp({ apiUrl, onComplete }) {
4579
4690
  children: /* @__PURE__ */ jsxs13(Box14, { flexDirection: "column", children: [
4580
4691
  state.error && /* @__PURE__ */ jsx15(Text14, { color: theme15.error, children: state.error }),
4581
4692
  /* @__PURE__ */ jsx15(
4582
- SelectInput3,
4693
+ SelectInput2,
4583
4694
  {
4584
4695
  items: [
4585
4696
  { label: "Create a new account", value: "signup" },
@@ -4609,7 +4720,7 @@ function InitApp({ apiUrl, onComplete }) {
4609
4720
  state.loading ? /* @__PURE__ */ jsx15(Spinner4, { label: state.loadingLabel }) : /* @__PURE__ */ jsxs13(Box14, { children: [
4610
4721
  /* @__PURE__ */ jsx15(Text14, { color: theme15.muted, children: "> " }),
4611
4722
  /* @__PURE__ */ jsx15(
4612
- TextInput2,
4723
+ TextInput3,
4613
4724
  {
4614
4725
  value: state.apiKeyInput,
4615
4726
  onChange: (value) => setState((prev) => ({
@@ -4650,7 +4761,7 @@ function InitApp({ apiUrl, onComplete }) {
4650
4761
  totalSteps: TOTAL_VISIBLE_STEPS,
4651
4762
  title: "What would you like to do?",
4652
4763
  children: /* @__PURE__ */ jsx15(
4653
- SelectInput3,
4764
+ SelectInput2,
4654
4765
  {
4655
4766
  items: [
4656
4767
  { label: "Import A2A agent URL", value: "url" },
@@ -4677,7 +4788,7 @@ function InitApp({ apiUrl, onComplete }) {
4677
4788
  state.loading ? /* @__PURE__ */ jsx15(Spinner4, { label: state.loadingLabel }) : /* @__PURE__ */ jsxs13(Box14, { children: [
4678
4789
  /* @__PURE__ */ jsx15(Text14, { color: theme15.muted, children: "> " }),
4679
4790
  /* @__PURE__ */ jsx15(
4680
- TextInput2,
4791
+ TextInput3,
4681
4792
  {
4682
4793
  value: state.urlInput,
4683
4794
  onChange: (value) => setState((prev) => ({
@@ -4756,7 +4867,7 @@ function InitApp({ apiUrl, onComplete }) {
4756
4867
  /* @__PURE__ */ jsxs13(Box14, { children: [
4757
4868
  /* @__PURE__ */ jsx15(Text14, { color: theme15.muted, children: "> " }),
4758
4869
  /* @__PURE__ */ jsx15(
4759
- TextInput2,
4870
+ TextInput3,
4760
4871
  {
4761
4872
  value: state.productName,
4762
4873
  onChange: (value) => setState((prev) => ({
@@ -4857,7 +4968,7 @@ function InitApp({ apiUrl, onComplete }) {
4857
4968
  function ConfirmInput({
4858
4969
  onConfirm
4859
4970
  }) {
4860
- const [answered, setAnswered] = useState12(false);
4971
+ const [answered, setAnswered] = useState13(false);
4861
4972
  useInput8(
4862
4973
  (input) => {
4863
4974
  if (answered) return;
@@ -4961,7 +5072,7 @@ import { Command as Command10 } from "commander";
4961
5072
  import chalk12 from "chalk";
4962
5073
  import React11 from "react";
4963
5074
  import { render as render9 } from "ink";
4964
- import { useState as useState13, useEffect as useEffect12 } from "react";
5075
+ import { useState as useState14, useEffect as useEffect12 } from "react";
4965
5076
  import { readFileSync as readFileSync3 } from "fs";
4966
5077
  import { processStream as processStream4 } from "@runtypelabs/sdk";
4967
5078
  var dispatchCommand = new Command10("dispatch").description("Execute a flow or agent via the dispatch API").option("-f, --flow <id>", "Flow ID to execute").option("-a, --agent <id>", "Agent ID to execute").option("-r, --record <id>", "Existing record ID").option("--record-json <file>", "JSON file with record data").option("-m, --message <text>", "Message to send").option("-v, --variable <key=value>", "Set a variable (repeatable)", collectVariables, []).option("--stream", "Stream the response (default)", true).option("--no-stream", "Wait for complete response").option("--json", "Output as JSON").option("--debug", "Show step-level details").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
@@ -5088,9 +5199,9 @@ async function handleNonStreaming(client, payload, options) {
5088
5199
  return;
5089
5200
  }
5090
5201
  const App = () => {
5091
- const [loading, setLoading] = useState13(true);
5092
- const [success, setSuccess] = useState13(null);
5093
- const [error, setError] = useState13(null);
5202
+ const [loading, setLoading] = useState14(true);
5203
+ const [success, setSuccess] = useState14(null);
5204
+ const [error, setError] = useState14(null);
5094
5205
  useEffect12(() => {
5095
5206
  const run = async () => {
5096
5207
  try {
@@ -5141,7 +5252,7 @@ import { Command as Command12 } from "commander";
5141
5252
  import chalk17 from "chalk";
5142
5253
  import React13 from "react";
5143
5254
  import { render as render11 } from "ink";
5144
- import { useState as useState20, useEffect as useEffect18 } from "react";
5255
+ import { useState as useState21, useEffect as useEffect18 } from "react";
5145
5256
  import { processStream as processStream5 } from "@runtypelabs/sdk";
5146
5257
 
5147
5258
  // src/commands/agents-task.ts
@@ -5151,15 +5262,15 @@ import { render as render10 } from "ink";
5151
5262
  import React12 from "react";
5152
5263
 
5153
5264
  // src/ink/marathon/MarathonApp.tsx
5154
- import { useState as useState19, useEffect as useEffect17, useRef as useRef8, useCallback as useCallback6, useMemo as useMemo5 } from "react";
5265
+ import { useState as useState20, useEffect as useEffect17, useRef as useRef8, useCallback as useCallback7, useMemo as useMemo7 } from "react";
5155
5266
  import { execSync } from "child_process";
5156
- import open3 from "open";
5157
- import { Box as Box24, useApp as useApp5, useInput as useInput9, useStdout as useStdout2 } from "ink";
5158
- import { StreamOutput as StreamOutput3, StatusBar as StatusBar2, ErrorDisplay as ErrorDisplay4, theme as theme27 } from "@runtypelabs/ink-components";
5267
+ import open4 from "open";
5268
+ import { Box as Box25, useApp as useApp5, useInput as useInput9, useStdout as useStdout3 } from "ink";
5269
+ import { StreamOutput as StreamOutput3, StatusBar as StatusBar2, ErrorDisplay as ErrorDisplay4, theme as theme28 } from "@runtypelabs/ink-components";
5159
5270
  import { LoadingAnimation } from "@runtypelabs/terminal-animations";
5160
5271
 
5161
5272
  // src/ink/marathon/useMarathonStream.ts
5162
- import { useState as useState14, useRef as useRef5, useMemo as useMemo2, useCallback as useCallback4 } from "react";
5273
+ import { useState as useState15, useRef as useRef5, useMemo as useMemo3, useCallback as useCallback5 } from "react";
5163
5274
 
5164
5275
  // src/ink/marathon/transcript-utils.ts
5165
5276
  function appendTranscriptText(content, delta, previousKind) {
@@ -5187,7 +5298,9 @@ var INITIAL_STATE2 = {
5187
5298
  totalCost: 0,
5188
5299
  currentIteration: 0,
5189
5300
  error: null,
5190
- rawEvents: []
5301
+ rawEvents: [],
5302
+ totalInputTokens: 0,
5303
+ totalOutputTokens: 0
5191
5304
  };
5192
5305
  var MAX_RAW_EVENTS = 500;
5193
5306
  function appendContentLine(content, line) {
@@ -5202,10 +5315,10 @@ function pushRawEvent(prev, type, data) {
5202
5315
  }
5203
5316
  var toolCounter = 0;
5204
5317
  function useMarathonStream() {
5205
- const [state, setState] = useState14(INITIAL_STATE2);
5318
+ const [state, setState] = useState15(INITIAL_STATE2);
5206
5319
  const stateRef = useRef5(state);
5207
5320
  stateRef.current = state;
5208
- const callbacks = useMemo2(
5321
+ const callbacks = useMemo3(
5209
5322
  () => ({
5210
5323
  onAgentStart() {
5211
5324
  setState((prev) => ({
@@ -5303,6 +5416,8 @@ function useMarathonStream() {
5303
5416
  setState((prev) => ({
5304
5417
  ...prev,
5305
5418
  totalCost: event.cost != null ? prev.totalCost + event.cost : prev.totalCost,
5419
+ totalInputTokens: prev.totalInputTokens + (event.tokens?.input ?? 0),
5420
+ totalOutputTokens: prev.totalOutputTokens + (event.tokens?.output ?? 0),
5306
5421
  sessionCount: prev.sessionCount + 1,
5307
5422
  rawEvents: pushRawEvent(prev, "agent_iteration_complete", { ...event })
5308
5423
  }));
@@ -5324,6 +5439,8 @@ function useMarathonStream() {
5324
5439
  phase: "complete",
5325
5440
  content: prev.content || event.finalOutput || "",
5326
5441
  totalCost: event.totalCost != null ? event.totalCost : prev.totalCost,
5442
+ totalInputTokens: event.totalTokens?.input ?? prev.totalInputTokens,
5443
+ totalOutputTokens: event.totalTokens?.output ?? prev.totalOutputTokens,
5327
5444
  rawEvents: pushRawEvent(prev, "agent_complete", { ...event })
5328
5445
  }));
5329
5446
  },
@@ -5338,13 +5455,13 @@ function useMarathonStream() {
5338
5455
  }),
5339
5456
  []
5340
5457
  );
5341
- const reset = useCallback4(() => {
5458
+ const reset = useCallback5(() => {
5342
5459
  setState(INITIAL_STATE2);
5343
5460
  }, []);
5344
- const setSteering = useCallback4(() => {
5461
+ const setSteering = useCallback5(() => {
5345
5462
  setState((prev) => ({ ...prev, phase: "steering" }));
5346
5463
  }, []);
5347
- const resetForNewSession = useCallback4(() => {
5464
+ const resetForNewSession = useCallback5(() => {
5348
5465
  setState((prev) => ({
5349
5466
  ...prev,
5350
5467
  phase: "idle",
@@ -5357,7 +5474,7 @@ function useMarathonStream() {
5357
5474
  error: null
5358
5475
  }));
5359
5476
  }, []);
5360
- const showError = useCallback4((error) => {
5477
+ const showError = useCallback5((error) => {
5361
5478
  setState((prev) => ({
5362
5479
  ...prev,
5363
5480
  phase: "error",
@@ -5373,7 +5490,7 @@ import { Box as Box15, Text as Text15 } from "ink";
5373
5490
  import { theme as theme17 } from "@runtypelabs/ink-components";
5374
5491
 
5375
5492
  // src/ink/marathon/RunnerTrack.tsx
5376
- import { useState as useState15, useEffect as useEffect13, useRef as useRef6, useCallback as useCallback5 } from "react";
5493
+ import { useState as useState16, useEffect as useEffect13, useRef as useRef6, useCallback as useCallback6 } from "react";
5377
5494
  import { theme as theme16 } from "@runtypelabs/ink-components";
5378
5495
  var TRAIL_CHARS = ["\u2022", "\xB7", "."];
5379
5496
  var BORDER_H = "\u2500";
@@ -5393,11 +5510,11 @@ function useRunnerTrack({
5393
5510
  }) {
5394
5511
  const innerWidth = Math.max(4, width - 2);
5395
5512
  const perimeter = innerWidth * 2;
5396
- const [position, setPosition] = useState15(
5513
+ const [position, setPosition] = useState16(
5397
5514
  () => Math.min(initialPosition, perimeter - 1)
5398
5515
  );
5399
- const [laps, setLaps] = useState15(initialLaps);
5400
- const [elapsed, setElapsed] = useState15(0);
5516
+ const [laps, setLaps] = useState16(initialLaps);
5517
+ const [elapsed, setElapsed] = useState16(0);
5401
5518
  const startTimeRef = useRef6(Date.now());
5402
5519
  const onPositionChangeRef = useRef6(onPositionChange);
5403
5520
  onPositionChangeRef.current = onPositionChange;
@@ -5430,7 +5547,7 @@ function useRunnerTrack({
5430
5547
  return () => clearInterval(interval);
5431
5548
  }, [isAnimating, perimeter, laps]);
5432
5549
  const finishPosition = Math.floor(innerWidth / 2);
5433
- const getRowCol = useCallback5(
5550
+ const getRowCol = useCallback6(
5434
5551
  (pos) => {
5435
5552
  if (pos < innerWidth) {
5436
5553
  return { row: "top", col: pos };
@@ -5655,11 +5772,11 @@ function SessionTabs({ tabs, hiddenLeft, hiddenRight }) {
5655
5772
  }
5656
5773
 
5657
5774
  // src/ink/marathon/ThinkingIndicator.tsx
5658
- import { useState as useState16, useEffect as useEffect14 } from "react";
5775
+ import { useState as useState17, useEffect as useEffect14 } from "react";
5659
5776
  import { Spinner as Spinner5, theme as theme19 } from "@runtypelabs/ink-components";
5660
5777
  import { jsx as jsx18 } from "react/jsx-runtime";
5661
5778
  function ThinkingIndicator({ startedAt }) {
5662
- const [elapsed, setElapsed] = useState16(
5779
+ const [elapsed, setElapsed] = useState17(
5663
5780
  () => startedAt ? Math.floor((Date.now() - startedAt) / 1e3) : 0
5664
5781
  );
5665
5782
  useEffect14(() => {
@@ -5674,7 +5791,7 @@ function ThinkingIndicator({ startedAt }) {
5674
5791
  }
5675
5792
 
5676
5793
  // src/ink/marathon/ToolPanel.tsx
5677
- import { useState as useState17, useEffect as useEffect15, useMemo as useMemo3 } from "react";
5794
+ import { useState as useState18, useEffect as useEffect15, useMemo as useMemo4 } from "react";
5678
5795
  import { Box as Box19, Text as Text19 } from "ink";
5679
5796
  import { theme as theme22 } from "@runtypelabs/ink-components";
5680
5797
 
@@ -5773,9 +5890,9 @@ import { jsx as jsx21, jsxs as jsxs17 } from "react/jsx-runtime";
5773
5890
  var ROWS_PER_TOOL = 3;
5774
5891
  var REASONING_PREVIEW_LINES = 4;
5775
5892
  function ToolPanel({ tools, reasoning, maxHeight }) {
5776
- const [now, setNow] = useState17(Date.now());
5893
+ const [now, setNow] = useState18(Date.now());
5777
5894
  const hasRunning = tools.some((t) => t.status === "running");
5778
- const reasoningLines = useMemo3(
5895
+ const reasoningLines = useMemo4(
5779
5896
  () => getVisibleReasoningLines(reasoning || "", REASONING_PREVIEW_LINES),
5780
5897
  [reasoning]
5781
5898
  );
@@ -5786,7 +5903,7 @@ function ToolPanel({ tools, reasoning, maxHeight }) {
5786
5903
  }, 100);
5787
5904
  return () => clearInterval(interval);
5788
5905
  }, [hasRunning]);
5789
- const visibleTools = useMemo3(() => {
5906
+ const visibleTools = useMemo4(() => {
5790
5907
  if (!maxHeight) return tools;
5791
5908
  const reasoningRows = reasoningLines.length > 0 ? 1 + reasoningLines.length + 1 : 0;
5792
5909
  const availableRows = maxHeight - 1 - reasoningRows;
@@ -5808,7 +5925,7 @@ function ToolPanel({ tools, reasoning, maxHeight }) {
5808
5925
  }
5809
5926
 
5810
5927
  // src/ink/marathon/EventStreamPanel.tsx
5811
- import { useMemo as useMemo4 } from "react";
5928
+ import { useMemo as useMemo5 } from "react";
5812
5929
  import { Box as Box20, Text as Text20 } from "ink";
5813
5930
  import { theme as theme23 } from "@runtypelabs/ink-components";
5814
5931
  import { jsx as jsx22, jsxs as jsxs18 } from "react/jsx-runtime";
@@ -5843,7 +5960,7 @@ function EventDetailView({
5843
5960
  scrollOffset = 0
5844
5961
  }) {
5845
5962
  const separator = theme23.separator ?? " \xB7 ";
5846
- const { lines, totalLines } = useMemo4(() => {
5963
+ const { lines, totalLines } = useMemo5(() => {
5847
5964
  const json = JSON.stringify(event.data, null, 2);
5848
5965
  const allLines = json.split("\n");
5849
5966
  const total = allLines.length;
@@ -5901,7 +6018,7 @@ function EventStreamPanel({
5901
6018
  }
5902
6019
  );
5903
6020
  }
5904
- const { rows, hiddenAbove, hiddenBelow } = useMemo4(() => {
6021
+ const { rows, hiddenAbove, hiddenBelow } = useMemo5(() => {
5905
6022
  if (events.length === 0) return { rows: [], hiddenAbove: 0, hiddenBelow: 0 };
5906
6023
  const total = events.length;
5907
6024
  const half = Math.floor(maxVisibleLines / 2);
@@ -5979,16 +6096,258 @@ function EventStreamPanel({
5979
6096
  );
5980
6097
  }
5981
6098
 
5982
- // src/ink/marathon/SteeringPrompt.tsx
5983
- import { useState as useState18, useEffect as useEffect16, useRef as useRef7 } from "react";
5984
- import { Box as Box22, Text as Text22 } from "ink";
5985
- import TextInput3 from "ink-text-input";
5986
- import { theme as theme25 } from "@runtypelabs/ink-components";
5987
-
5988
- // src/ink/marathon/SteeringRecap.tsx
6099
+ // src/ink/marathon/FilesPanel.tsx
6100
+ import { useMemo as useMemo6 } from "react";
5989
6101
  import { Box as Box21, Text as Text21 } from "ink";
5990
6102
  import { theme as theme24 } from "@runtypelabs/ink-components";
5991
6103
  import { jsx as jsx23, jsxs as jsxs19 } from "react/jsx-runtime";
6104
+ var TYPE_COLORS = {
6105
+ plan: theme24.accent,
6106
+ written: theme24.success,
6107
+ read: theme24.textMuted
6108
+ };
6109
+ var TYPE_LABELS = {
6110
+ plan: "plan",
6111
+ written: "write",
6112
+ read: "read"
6113
+ };
6114
+ function shortenPath(filePath, maxWidth) {
6115
+ if (filePath.length <= maxWidth) return filePath;
6116
+ const segments = filePath.split("/");
6117
+ for (let skip = 1; skip < segments.length - 1; skip++) {
6118
+ const shortened = ".../" + segments.slice(skip).join("/");
6119
+ if (shortened.length <= maxWidth) return shortened;
6120
+ }
6121
+ return ".../" + segments[segments.length - 1];
6122
+ }
6123
+ function FileContentView({
6124
+ file,
6125
+ content,
6126
+ totalLines,
6127
+ truncated,
6128
+ maxVisibleLines,
6129
+ scrollOffset = 0
6130
+ }) {
6131
+ const separator = theme24.separator ?? " \xB7 ";
6132
+ const { lines, displayTotalLines } = useMemo6(() => {
6133
+ const allLines = content.split("\n");
6134
+ const total = allLines.length;
6135
+ const clampedOffset = Math.min(scrollOffset, Math.max(0, total - maxVisibleLines));
6136
+ const end = total - clampedOffset;
6137
+ const start = Math.max(0, end - maxVisibleLines);
6138
+ return { lines: allLines.slice(start, end), displayTotalLines: total };
6139
+ }, [content, maxVisibleLines, scrollOffset]);
6140
+ const filename = file.path.split("/").pop() || file.path;
6141
+ return /* @__PURE__ */ jsxs19(
6142
+ Box21,
6143
+ {
6144
+ flexDirection: "column",
6145
+ paddingX: theme24.panelPaddingX,
6146
+ paddingY: theme24.panelPaddingY,
6147
+ children: [
6148
+ /* @__PURE__ */ jsxs19(Box21, { marginBottom: theme24.sectionGap, children: [
6149
+ /* @__PURE__ */ jsx23(Text21, { bold: true, color: theme24.accent, children: filename }),
6150
+ /* @__PURE__ */ jsxs19(Text21, { color: theme24.textSubtle, children: [
6151
+ separator,
6152
+ totalLines,
6153
+ " lines"
6154
+ ] }),
6155
+ truncated && /* @__PURE__ */ jsxs19(Text21, { color: theme24.warning, children: [
6156
+ separator,
6157
+ "truncated"
6158
+ ] }),
6159
+ /* @__PURE__ */ jsxs19(Text21, { color: theme24.textSubtle, children: [
6160
+ separator,
6161
+ "Esc: back"
6162
+ ] }),
6163
+ displayTotalLines > maxVisibleLines && /* @__PURE__ */ jsxs19(Text21, { color: theme24.textSubtle, children: [
6164
+ separator,
6165
+ Math.max(0, displayTotalLines - maxVisibleLines - scrollOffset),
6166
+ " below"
6167
+ ] })
6168
+ ] }),
6169
+ lines.map((line, i) => /* @__PURE__ */ jsx23(Text21, { color: theme24.text, children: line }, i))
6170
+ ]
6171
+ }
6172
+ );
6173
+ }
6174
+ function FilesPanel({
6175
+ files,
6176
+ maxVisibleLines = 50,
6177
+ selectedIndex,
6178
+ detailFile,
6179
+ detailContent,
6180
+ detailTotalLines = 0,
6181
+ detailTruncated = false,
6182
+ detailScrollOffset = 0
6183
+ }) {
6184
+ const separator = theme24.separator ?? " \xB7 ";
6185
+ if (detailFile && detailContent !== null) {
6186
+ return /* @__PURE__ */ jsx23(
6187
+ FileContentView,
6188
+ {
6189
+ file: detailFile,
6190
+ content: detailContent,
6191
+ totalLines: detailTotalLines,
6192
+ truncated: detailTruncated,
6193
+ maxVisibleLines: maxVisibleLines - 2,
6194
+ scrollOffset: detailScrollOffset
6195
+ }
6196
+ );
6197
+ }
6198
+ const { rows, hiddenAbove, hiddenBelow } = useMemo6(() => {
6199
+ if (files.length === 0) return { rows: [], hiddenAbove: 0, hiddenBelow: 0 };
6200
+ const total = files.length;
6201
+ const half = Math.floor(maxVisibleLines / 2);
6202
+ let start = selectedIndex - half;
6203
+ let end = start + maxVisibleLines;
6204
+ if (start < 0) {
6205
+ start = 0;
6206
+ end = Math.min(total, maxVisibleLines);
6207
+ }
6208
+ if (end > total) {
6209
+ end = total;
6210
+ start = Math.max(0, end - maxVisibleLines);
6211
+ }
6212
+ const visible = files.slice(start, end);
6213
+ return {
6214
+ rows: visible.map((file, i) => ({
6215
+ globalIndex: start + i,
6216
+ key: `${start + i}`,
6217
+ file
6218
+ })),
6219
+ hiddenAbove: start,
6220
+ hiddenBelow: total - end
6221
+ };
6222
+ }, [files, maxVisibleLines, selectedIndex]);
6223
+ if (files.length === 0) {
6224
+ return /* @__PURE__ */ jsx23(
6225
+ Box21,
6226
+ {
6227
+ flexDirection: "column",
6228
+ paddingX: theme24.panelPaddingX,
6229
+ paddingY: theme24.panelPaddingY,
6230
+ children: /* @__PURE__ */ jsx23(Text21, { color: theme24.textSubtle, children: "No files tracked yet..." })
6231
+ }
6232
+ );
6233
+ }
6234
+ return /* @__PURE__ */ jsxs19(
6235
+ Box21,
6236
+ {
6237
+ flexDirection: "column",
6238
+ paddingX: theme24.panelPaddingX,
6239
+ paddingY: theme24.panelPaddingY,
6240
+ children: [
6241
+ /* @__PURE__ */ jsxs19(Box21, { marginBottom: 0, children: [
6242
+ /* @__PURE__ */ jsx23(Text21, { bold: true, color: theme24.accent, children: "Files" }),
6243
+ /* @__PURE__ */ jsxs19(Text21, { color: theme24.textSubtle, children: [
6244
+ separator,
6245
+ files.length,
6246
+ " files"
6247
+ ] }),
6248
+ hiddenAbove > 0 && /* @__PURE__ */ jsxs19(Text21, { color: theme24.textSubtle, children: [
6249
+ separator,
6250
+ hiddenAbove,
6251
+ " above"
6252
+ ] }),
6253
+ hiddenBelow > 0 && /* @__PURE__ */ jsxs19(Text21, { color: theme24.textSubtle, children: [
6254
+ separator,
6255
+ hiddenBelow,
6256
+ " below"
6257
+ ] })
6258
+ ] }),
6259
+ rows.map((row) => {
6260
+ const isSelected = row.globalIndex === selectedIndex;
6261
+ const typeColor = TYPE_COLORS[row.file.type] || theme24.text;
6262
+ const typeLabel = TYPE_LABELS[row.file.type] || row.file.type;
6263
+ return /* @__PURE__ */ jsxs19(Box21, { flexDirection: "row", flexWrap: "nowrap", children: [
6264
+ /* @__PURE__ */ jsx23(Box21, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx23(Text21, { color: isSelected ? theme24.accentActive : theme24.textSubtle, children: isSelected ? "\u203A" : " " }) }),
6265
+ /* @__PURE__ */ jsx23(Box21, { width: 8, flexShrink: 0, children: /* @__PURE__ */ jsxs19(Text21, { color: typeColor, children: [
6266
+ "[",
6267
+ typeLabel,
6268
+ "]"
6269
+ ] }) }),
6270
+ /* @__PURE__ */ jsx23(Box21, { flexShrink: 1, children: /* @__PURE__ */ jsx23(
6271
+ Text21,
6272
+ {
6273
+ color: isSelected ? theme24.accentActive : theme24.text,
6274
+ bold: isSelected,
6275
+ wrap: "truncate",
6276
+ children: shortenPath(row.file.path, 80)
6277
+ }
6278
+ ) })
6279
+ ] }, row.key);
6280
+ })
6281
+ ]
6282
+ }
6283
+ );
6284
+ }
6285
+
6286
+ // src/ink/marathon/file-utils.ts
6287
+ import * as fs4 from "fs";
6288
+ function extractTrackedFiles(snapshots, liveTools, planPath) {
6289
+ const fileMap = /* @__PURE__ */ new Map();
6290
+ function processTools(tools) {
6291
+ for (const tool of tools) {
6292
+ if (tool.name !== "write_file" && tool.name !== "read_file") continue;
6293
+ const filePath = tool.parameters?.path;
6294
+ if (!filePath) continue;
6295
+ const isWrite = tool.name === "write_file";
6296
+ const existing = fileMap.get(filePath);
6297
+ if (!existing || isWrite && existing.type === "read") {
6298
+ fileMap.set(filePath, {
6299
+ path: filePath,
6300
+ type: isWrite ? "written" : "read",
6301
+ lastTouchedAt: tool.startedAt
6302
+ });
6303
+ } else if (existing && tool.startedAt > (existing.lastTouchedAt ?? 0)) {
6304
+ existing.lastTouchedAt = tool.startedAt;
6305
+ }
6306
+ }
6307
+ }
6308
+ for (const snapshot of snapshots) {
6309
+ processTools(snapshot.tools);
6310
+ }
6311
+ processTools(liveTools);
6312
+ const result = [];
6313
+ if (planPath) {
6314
+ fileMap.delete(planPath);
6315
+ result.push({ path: planPath, type: "plan" });
6316
+ }
6317
+ const sorted = Array.from(fileMap.values()).sort(
6318
+ (a, b) => (b.lastTouchedAt ?? 0) - (a.lastTouchedAt ?? 0)
6319
+ );
6320
+ result.push(...sorted);
6321
+ return result;
6322
+ }
6323
+ function readFileContent(filePath, maxLines = 5e3) {
6324
+ try {
6325
+ const raw = fs4.readFileSync(filePath, "utf-8");
6326
+ const lines = raw.split("\n");
6327
+ const totalLines = lines.length;
6328
+ if (totalLines > maxLines) {
6329
+ return {
6330
+ content: lines.slice(0, maxLines).join("\n"),
6331
+ totalLines,
6332
+ truncated: true
6333
+ };
6334
+ }
6335
+ return { content: raw, totalLines, truncated: false };
6336
+ } catch {
6337
+ return { content: `Error: Could not read file at ${filePath}`, totalLines: 1, truncated: false };
6338
+ }
6339
+ }
6340
+
6341
+ // src/ink/marathon/SteeringPrompt.tsx
6342
+ import { useState as useState19, useEffect as useEffect16, useRef as useRef7 } from "react";
6343
+ import { Box as Box23, Text as Text23 } from "ink";
6344
+ import TextInput4 from "ink-text-input";
6345
+ import { theme as theme26 } from "@runtypelabs/ink-components";
6346
+
6347
+ // src/ink/marathon/SteeringRecap.tsx
6348
+ import { Box as Box22, Text as Text22 } from "ink";
6349
+ import { theme as theme25 } from "@runtypelabs/ink-components";
6350
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
5992
6351
  function SteeringRecap({
5993
6352
  sessionNumber,
5994
6353
  toolCallsMade,
@@ -5998,19 +6357,19 @@ function SteeringRecap({
5998
6357
  isTerminal
5999
6358
  }) {
6000
6359
  const label = isTerminal ? `\u2713 Session ${sessionNumber} complete` : `Session ${sessionNumber} complete`;
6001
- const separator = theme24.separator ?? " \xB7 ";
6002
- return /* @__PURE__ */ jsxs19(
6003
- Box21,
6360
+ const separator = theme25.separator ?? " \xB7 ";
6361
+ return /* @__PURE__ */ jsxs20(
6362
+ Box22,
6004
6363
  {
6005
6364
  borderStyle: "single",
6006
- borderColor: theme24.border,
6007
- backgroundColor: theme24.background,
6365
+ borderColor: theme25.border,
6366
+ backgroundColor: theme25.background,
6008
6367
  flexDirection: "column",
6009
- paddingX: theme24.panelPaddingX,
6010
- paddingY: theme24.panelPaddingY,
6368
+ paddingX: theme25.panelPaddingX,
6369
+ paddingY: theme25.panelPaddingY,
6011
6370
  children: [
6012
- /* @__PURE__ */ jsx23(Text21, { color: isTerminal ? theme24.accentActive : theme24.accent, children: label }),
6013
- /* @__PURE__ */ jsx23(Text21, { color: theme24.textMuted, children: `Tools: ${toolCallsMade}${separator}Tokens: ${tokensInput}+${tokensOutput}${separator}Cost: $${cost.toFixed(4)}` })
6371
+ /* @__PURE__ */ jsx24(Text22, { color: isTerminal ? theme25.accentActive : theme25.accent, children: label }),
6372
+ /* @__PURE__ */ jsx24(Text22, { color: theme25.textMuted, children: `Tools: ${toolCallsMade}${separator}Tokens: ${tokensInput}+${tokensOutput}${separator}Cost: $${cost.toFixed(4)}` })
6014
6373
  ]
6015
6374
  }
6016
6375
  );
@@ -6037,7 +6396,7 @@ var MARATHON_STEER_COMMANDS = [
6037
6396
  ];
6038
6397
 
6039
6398
  // src/ink/marathon/SteeringPrompt.tsx
6040
- import { Fragment as Fragment2, jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
6399
+ import { Fragment as Fragment2, jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
6041
6400
  function SteeringPrompt({
6042
6401
  onSubmit,
6043
6402
  timeout,
@@ -6046,13 +6405,13 @@ function SteeringPrompt({
6046
6405
  currentSandbox: _currentSandbox,
6047
6406
  recap
6048
6407
  }) {
6049
- const [value, setValue] = useState18("");
6050
- const [remaining, setRemaining] = useState18(timeout);
6051
- const [isTyping, setIsTyping] = useState18(false);
6052
- const [showModelPicker, setShowModelPicker] = useState18(false);
6053
- const [showHelp, setShowHelp] = useState18(false);
6408
+ const [value, setValue] = useState19("");
6409
+ const [remaining, setRemaining] = useState19(timeout);
6410
+ const [isTyping, setIsTyping] = useState19(false);
6411
+ const [showModelPicker, setShowModelPicker] = useState19(false);
6412
+ const [showHelp, setShowHelp] = useState19(false);
6054
6413
  const timerRef = useRef7(null);
6055
- const separator = theme25.separator ?? " \xB7 ";
6414
+ const separator = theme26.separator ?? " \xB7 ";
6056
6415
  useEffect16(() => {
6057
6416
  const title = "Marathon";
6058
6417
  const body = isTerminal ? "Marathon complete" : `Session ${recap?.sessionNumber ?? "?"} complete`;
@@ -6140,20 +6499,20 @@ function SteeringPrompt({
6140
6499
  if (isTyping) return "(paused)";
6141
6500
  return `(${remaining}s)`;
6142
6501
  })();
6143
- return /* @__PURE__ */ jsxs20(Box22, { flexDirection: "column", flexShrink: 0, children: [
6144
- /* @__PURE__ */ jsx24(SteeringRecap, { ...recap, isTerminal }),
6145
- showModelPicker ? /* @__PURE__ */ jsx24(
6502
+ return /* @__PURE__ */ jsxs21(Box23, { flexDirection: "column", flexShrink: 0, children: [
6503
+ /* @__PURE__ */ jsx25(SteeringRecap, { ...recap, isTerminal }),
6504
+ showModelPicker ? /* @__PURE__ */ jsx25(
6146
6505
  ModelPicker,
6147
6506
  {
6148
6507
  currentModel,
6149
6508
  onSelect: handleModelSelect,
6150
6509
  onCancel: handleModelCancel
6151
6510
  }
6152
- ) : /* @__PURE__ */ jsxs20(Fragment2, { children: [
6153
- /* @__PURE__ */ jsxs20(Box22, { children: [
6154
- /* @__PURE__ */ jsx24(Text22, { color: theme25.accentActive, children: "> " }),
6155
- /* @__PURE__ */ jsx24(Box22, { flexGrow: 1, children: /* @__PURE__ */ jsx24(
6156
- TextInput3,
6511
+ ) : /* @__PURE__ */ jsxs21(Fragment2, { children: [
6512
+ /* @__PURE__ */ jsxs21(Box23, { children: [
6513
+ /* @__PURE__ */ jsx25(Text23, { color: theme26.accentActive, children: "> " }),
6514
+ /* @__PURE__ */ jsx25(Box23, { flexGrow: 1, children: /* @__PURE__ */ jsx25(
6515
+ TextInput4,
6157
6516
  {
6158
6517
  value,
6159
6518
  onChange: handleChange,
@@ -6161,12 +6520,12 @@ function SteeringPrompt({
6161
6520
  placeholder: isTerminal ? "Send new instructions to continue marathon, or press enter to exit..." : "Steer next iteration..."
6162
6521
  }
6163
6522
  ) }),
6164
- countdownText && /* @__PURE__ */ jsxs20(Text22, { color: theme25.textSubtle, children: [
6523
+ countdownText && /* @__PURE__ */ jsxs21(Text23, { color: theme26.textSubtle, children: [
6165
6524
  " ",
6166
6525
  countdownText
6167
6526
  ] })
6168
6527
  ] }),
6169
- /* @__PURE__ */ jsx24(Text22, { color: theme25.textSubtle, children: [
6528
+ /* @__PURE__ */ jsx25(Text23, { color: theme26.textSubtle, children: [
6170
6529
  isTerminal ? isTyping ? "Enter: send" : "Enter: exit" : "Enter: continue",
6171
6530
  "/model",
6172
6531
  "/tools",
@@ -6174,7 +6533,7 @@ function SteeringPrompt({
6174
6533
  "/stop",
6175
6534
  "/help"
6176
6535
  ].join(separator) }),
6177
- showHelp && /* @__PURE__ */ jsx24(Box22, { flexDirection: "column", marginTop: theme25.sectionGap, children: MARATHON_STEER_COMMANDS.map((cmd) => /* @__PURE__ */ jsxs20(Text22, { color: theme25.textSubtle, children: [
6536
+ showHelp && /* @__PURE__ */ jsx25(Box23, { flexDirection: "column", marginTop: theme26.sectionGap, children: MARATHON_STEER_COMMANDS.map((cmd) => /* @__PURE__ */ jsxs21(Text23, { color: theme26.textSubtle, children: [
6178
6537
  cmd.name.padEnd(12),
6179
6538
  " ",
6180
6539
  cmd.description
@@ -6184,44 +6543,44 @@ function SteeringPrompt({
6184
6543
  }
6185
6544
 
6186
6545
  // src/ink/marathon/UpgradeModal.tsx
6187
- import { Box as Box23, Text as Text23 } from "ink";
6188
- import { theme as theme26 } from "@runtypelabs/ink-components";
6189
- import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
6546
+ import { Box as Box24, Text as Text24 } from "ink";
6547
+ import { theme as theme27 } from "@runtypelabs/ink-components";
6548
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
6190
6549
  function UpgradeModal({ prompt, width }) {
6191
- return /* @__PURE__ */ jsxs21(
6192
- Box23,
6550
+ return /* @__PURE__ */ jsxs22(
6551
+ Box24,
6193
6552
  {
6194
6553
  width,
6195
6554
  flexDirection: "column",
6196
6555
  borderStyle: "round",
6197
- borderColor: theme26.warning,
6198
- backgroundColor: theme26.surfaceElevated,
6556
+ borderColor: theme27.warning,
6557
+ backgroundColor: theme27.surfaceElevated,
6199
6558
  paddingX: 2,
6200
6559
  paddingY: 1,
6201
6560
  children: [
6202
- /* @__PURE__ */ jsx25(Text23, { color: theme26.warning, bold: true, children: "Upgrade available" }),
6203
- /* @__PURE__ */ jsx25(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx25(Text23, { color: theme26.label, children: prompt.message }) }),
6204
- (prompt.code || prompt.limitType || prompt.retryAfter) && /* @__PURE__ */ jsxs21(Box23, { flexDirection: "column", marginTop: 1, children: [
6205
- prompt.code && /* @__PURE__ */ jsxs21(Text23, { color: theme26.muted, children: [
6561
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.warning, bold: true, children: "Upgrade available" }),
6562
+ /* @__PURE__ */ jsx26(Box24, { marginTop: 1, children: /* @__PURE__ */ jsx26(Text24, { color: theme27.label, children: prompt.message }) }),
6563
+ (prompt.code || prompt.limitType || prompt.retryAfter) && /* @__PURE__ */ jsxs22(Box24, { flexDirection: "column", marginTop: 1, children: [
6564
+ prompt.code && /* @__PURE__ */ jsxs22(Text24, { color: theme27.muted, children: [
6206
6565
  "Code: ",
6207
- /* @__PURE__ */ jsx25(Text23, { color: theme26.label, children: prompt.code })
6566
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.label, children: prompt.code })
6208
6567
  ] }),
6209
- prompt.limitType && /* @__PURE__ */ jsxs21(Text23, { color: theme26.muted, children: [
6568
+ prompt.limitType && /* @__PURE__ */ jsxs22(Text24, { color: theme27.muted, children: [
6210
6569
  "Limit: ",
6211
- /* @__PURE__ */ jsx25(Text23, { color: theme26.label, children: prompt.limitType })
6570
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.label, children: prompt.limitType })
6212
6571
  ] }),
6213
- prompt.retryAfter && /* @__PURE__ */ jsxs21(Text23, { color: theme26.muted, children: [
6572
+ prompt.retryAfter && /* @__PURE__ */ jsxs22(Text24, { color: theme27.muted, children: [
6214
6573
  "Retry after: ",
6215
- /* @__PURE__ */ jsx25(Text23, { color: theme26.label, children: prompt.retryAfter })
6574
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.label, children: prompt.retryAfter })
6216
6575
  ] })
6217
6576
  ] }),
6218
- /* @__PURE__ */ jsxs21(Box23, { marginTop: 1, children: [
6219
- /* @__PURE__ */ jsx25(Text23, { color: theme26.info, children: "Enter" }),
6220
- /* @__PURE__ */ jsx25(Text23, { color: theme26.muted, children: " open billing " }),
6221
- /* @__PURE__ */ jsx25(Text23, { color: theme26.info, children: "Esc" }),
6222
- /* @__PURE__ */ jsx25(Text23, { color: theme26.muted, children: " close" })
6577
+ /* @__PURE__ */ jsxs22(Box24, { marginTop: 1, children: [
6578
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.info, children: "Enter" }),
6579
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.muted, children: " open billing " }),
6580
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.info, children: "Esc" }),
6581
+ /* @__PURE__ */ jsx26(Text24, { color: theme27.muted, children: " close" })
6223
6582
  ] }),
6224
- /* @__PURE__ */ jsx25(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx25(Text23, { color: theme26.dimLabel, children: "Opens your dashboard billing page" }) })
6583
+ /* @__PURE__ */ jsx26(Box24, { marginTop: 1, children: /* @__PURE__ */ jsx26(Text24, { color: theme27.dimLabel, children: "Opens your dashboard billing page" }) })
6225
6584
  ]
6226
6585
  }
6227
6586
  );
@@ -6374,7 +6733,7 @@ function getSessionTabKeyForShortcut(visibleTabs, input) {
6374
6733
  }
6375
6734
 
6376
6735
  // src/ink/marathon/MarathonApp.tsx
6377
- import { Fragment as Fragment3, jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
6736
+ import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
6378
6737
  var TOOL_PANEL_WIDE = 48;
6379
6738
  var TOOL_PANEL_NARROW = 36;
6380
6739
  var NARROW_THRESHOLD = 100;
@@ -6460,6 +6819,7 @@ function MarathonApp({
6460
6819
  showFinish,
6461
6820
  initialRunnerPosition,
6462
6821
  initialRunnerLaps,
6822
+ planPath,
6463
6823
  debug: _debug,
6464
6824
  plainText,
6465
6825
  noSteer: _noSteer,
@@ -6472,25 +6832,25 @@ function MarathonApp({
6472
6832
  }) {
6473
6833
  const { state, callbacks, reset: _reset, setSteering, resetForNewSession, showError } = useMarathonStream();
6474
6834
  const { exit } = useApp5();
6475
- const { stdout } = useStdout2();
6476
- const separator = theme27.separator ?? " \xB7 ";
6835
+ const { stdout } = useStdout3();
6836
+ const separator = theme28.separator ?? " \xB7 ";
6477
6837
  const steeringResolveRef = useRef8(null);
6478
- const [steeringRecap, setSteeringRecap] = useState19(null);
6479
- const [currentModel, setCurrentModel] = useState19(model || "default");
6480
- const [currentSandbox, setCurrentSandbox] = useState19(sandbox);
6481
- const [isTerminalSteering, setIsTerminalSteering] = useState19(false);
6482
- const [sessionSnapshots, setSessionSnapshots] = useState19(
6838
+ const [steeringRecap, setSteeringRecap] = useState20(null);
6839
+ const [currentModel, setCurrentModel] = useState20(model || "default");
6840
+ const [currentSandbox, setCurrentSandbox] = useState20(sandbox);
6841
+ const [isTerminalSteering, setIsTerminalSteering] = useState20(false);
6842
+ const [sessionSnapshots, setSessionSnapshots] = useState20(
6483
6843
  () => (initialSessionSnapshots || []).map((snapshot) => cloneSessionSnapshot(snapshot))
6484
6844
  );
6485
- const [selectedSessionKey, setSelectedSessionKey] = useState19(void 0);
6486
- const [followLatest, setFollowLatest] = useState19(true);
6487
- const [latestUnreadKey, setLatestUnreadKey] = useState19(void 0);
6488
- const [previewUrl, setPreviewUrl] = useState19(void 0);
6489
- const [runnerPosition, setRunnerPosition] = useState19(initialRunnerPosition ?? 0);
6490
- const [runnerLaps, setRunnerLaps] = useState19(initialRunnerLaps ?? 0);
6845
+ const [selectedSessionKey, setSelectedSessionKey] = useState20(void 0);
6846
+ const [followLatest, setFollowLatest] = useState20(true);
6847
+ const [latestUnreadKey, setLatestUnreadKey] = useState20(void 0);
6848
+ const [previewUrl, setPreviewUrl] = useState20(void 0);
6849
+ const [runnerPosition, setRunnerPosition] = useState20(initialRunnerPosition ?? 0);
6850
+ const [runnerLaps, setRunnerLaps] = useState20(initialRunnerLaps ?? 0);
6491
6851
  const runnerPositionRef = useRef8(initialRunnerPosition ?? 0);
6492
6852
  const runnerLapsRef = useRef8(initialRunnerLaps ?? 0);
6493
- const handleRunnerPositionChange = useCallback6((position, laps) => {
6853
+ const handleRunnerPositionChange = useCallback7((position, laps) => {
6494
6854
  setRunnerPosition(position);
6495
6855
  setRunnerLaps(laps);
6496
6856
  runnerPositionRef.current = position;
@@ -6498,7 +6858,7 @@ function MarathonApp({
6498
6858
  }, []);
6499
6859
  const isRunnerAnimating = state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool";
6500
6860
  const isTerminalSteeringRef = useRef8(false);
6501
- const handleSteeringSubmit = useCallback6(
6861
+ const handleSteeringSubmit = useCallback7(
6502
6862
  (result) => {
6503
6863
  if (result.action === "model" && result.model) {
6504
6864
  setCurrentModel(result.model);
@@ -6571,17 +6931,24 @@ function MarathonApp({
6571
6931
  const contentHeight = Math.max(5, terminalRows - chromeRows);
6572
6932
  const isStacked = terminalWidth < STACKED_THRESHOLD;
6573
6933
  const toolPanelWidth = terminalWidth < NARROW_THRESHOLD ? TOOL_PANEL_NARROW : TOOL_PANEL_WIDE;
6574
- const [ctrlCPressed, setCtrlCPressed] = useState19(false);
6934
+ const [ctrlCPressed, setCtrlCPressed] = useState20(false);
6575
6935
  const ctrlCTimeout = useRef8(null);
6576
- const [showEventStream, setShowEventStream] = useState19(false);
6577
- const [scrollOffset, setScrollOffset] = useState19(0);
6578
- const [reasoningCollapsed, setReasoningCollapsed] = useState19(false);
6579
- const [eventCursor, setEventCursor] = useState19(-1);
6580
- const [detailEvent, setDetailEvent] = useState19(null);
6581
- const [detailScrollOffset, setDetailScrollOffset] = useState19(0);
6582
- const [goalExpanded, setGoalExpanded] = useState19(false);
6583
- const [upgradeModalDismissed, setUpgradeModalDismissed] = useState19(false);
6584
- const [clipboardFlash, setClipboardFlash] = useState19(null);
6936
+ const [showEventStream, setShowEventStream] = useState20(false);
6937
+ const [showFilesPanel, setShowFilesPanel] = useState20(false);
6938
+ const [fileCursor, setFileCursor] = useState20(0);
6939
+ const [detailFile, setDetailFile] = useState20(null);
6940
+ const [detailFileContent, setDetailFileContent] = useState20(null);
6941
+ const [detailFileTotalLines, setDetailFileTotalLines] = useState20(0);
6942
+ const [detailFileTruncated, setDetailFileTruncated] = useState20(false);
6943
+ const [fileDetailScrollOffset, setFileDetailScrollOffset] = useState20(0);
6944
+ const [scrollOffset, setScrollOffset] = useState20(0);
6945
+ const [reasoningCollapsed, setReasoningCollapsed] = useState20(false);
6946
+ const [eventCursor, setEventCursor] = useState20(-1);
6947
+ const [detailEvent, setDetailEvent] = useState20(null);
6948
+ const [detailScrollOffset, setDetailScrollOffset] = useState20(0);
6949
+ const [goalExpanded, setGoalExpanded] = useState20(false);
6950
+ const [upgradeModalDismissed, setUpgradeModalDismissed] = useState20(false);
6951
+ const [clipboardFlash, setClipboardFlash] = useState20(null);
6585
6952
  const flashTimeout = useRef8(null);
6586
6953
  const billingPageUrl = billingUrl || `${(dashboardUrl || "https://use.runtype.com").replace(/\/$/, "")}/settings/billing`;
6587
6954
  function showFlash(msg) {
@@ -6591,21 +6958,21 @@ function MarathonApp({
6591
6958
  }
6592
6959
  const latestCompletedSessionIndex = sessionSnapshots[sessionSnapshots.length - 1]?.sessionIndex ?? initialSessionCount;
6593
6960
  const shouldShowLiveTab = state.phase !== "idle" && state.phase !== "steering" && state.phase !== "complete" && (Boolean(state.content) || Boolean(state.reasoning) || state.tools.length > 0 || state.rawEvents.length > 0 || state.phase === "thinking" || state.phase === "error");
6594
- const liveSessionSnapshot = useMemo5(
6961
+ const liveSessionSnapshot = useMemo7(
6595
6962
  () => shouldShowLiveTab ? buildLiveSessionSnapshot(state, latestCompletedSessionIndex + 1, currentModel) : void 0,
6596
6963
  [currentModel, latestCompletedSessionIndex, shouldShowLiveTab, state]
6597
6964
  );
6598
6965
  const liveSessionKey = liveSessionSnapshot ? createSessionTabKey(liveSessionSnapshot.sessionIndex, "live") : void 0;
6599
6966
  const latestSessionKey = getLatestSessionTabKey(sessionSnapshots, liveSessionSnapshot);
6600
- const allTabs = useMemo5(
6967
+ const allTabs = useMemo7(
6601
6968
  () => buildSessionTabs(sessionSnapshots, selectedSessionKey, latestUnreadKey, liveSessionSnapshot),
6602
6969
  [latestUnreadKey, liveSessionSnapshot, selectedSessionKey, sessionSnapshots]
6603
6970
  );
6604
- const visibleTabs = useMemo5(
6971
+ const visibleTabs = useMemo7(
6605
6972
  () => getVisibleSessionTabs(allTabs, selectedSessionKey, terminalWidth),
6606
6973
  [allTabs, selectedSessionKey, terminalWidth]
6607
6974
  );
6608
- const displayedSessionSnapshot = useMemo5(() => {
6975
+ const displayedSessionSnapshot = useMemo7(() => {
6609
6976
  if (!selectedSessionKey) return liveSessionSnapshot ?? sessionSnapshots[sessionSnapshots.length - 1];
6610
6977
  if (selectedSessionKey === liveSessionKey) return liveSessionSnapshot;
6611
6978
  return sessionSnapshots.find(
@@ -6617,15 +6984,19 @@ function MarathonApp({
6617
6984
  const displayedReasoning = displayedSessionSnapshot?.reasoning ?? state.reasoning;
6618
6985
  const displayedTools = displayedSessionSnapshot?.tools ?? state.tools;
6619
6986
  const displayedEvents = displayedSessionSnapshot?.rawEvents ?? state.rawEvents;
6987
+ const trackedFiles = useMemo7(
6988
+ () => extractTrackedFiles(sessionSnapshots, displayedTools, planPath),
6989
+ [sessionSnapshots, displayedTools, planPath]
6990
+ );
6620
6991
  const latestLiveActivityRef = useRef8(void 0);
6621
- const upgradePrompt = useMemo5(() => parseMarathonUpgradePrompt(state.error), [state.error]);
6622
- const upgradePromptKey = useMemo5(
6992
+ const upgradePrompt = useMemo7(() => parseMarathonUpgradePrompt(state.error), [state.error]);
6993
+ const upgradePromptKey = useMemo7(
6623
6994
  () => upgradePrompt ? `${upgradePrompt.message}|${upgradePrompt.code ?? ""}|${upgradePrompt.limitType ?? ""}|${upgradePrompt.retryAfter ?? ""}` : void 0,
6624
6995
  [upgradePrompt]
6625
6996
  );
6626
6997
  const showUpgradeModal = Boolean(upgradePrompt && !upgradeModalDismissed);
6627
6998
  const canBrowseAfterUpgradeError = Boolean(upgradePrompt && !showUpgradeModal);
6628
- const selectSessionTab = useCallback6(
6999
+ const selectSessionTab = useCallback7(
6629
7000
  (nextKey, manual = true) => {
6630
7001
  if (!nextKey) return;
6631
7002
  setSelectedSessionKey(nextKey);
@@ -6696,7 +7067,7 @@ function MarathonApp({
6696
7067
  setEventCursor(displayedEvents.length - 1);
6697
7068
  }
6698
7069
  }, [displayedEvents.length, eventCursor, showEventStream]);
6699
- const navigateToEvent = useCallback6(
7070
+ const navigateToEvent = useCallback7(
6700
7071
  (index) => {
6701
7072
  const clamped = Math.max(0, Math.min(displayedEvents.length - 1, index));
6702
7073
  const evt = displayedEvents[clamped];
@@ -6711,12 +7082,12 @@ function MarathonApp({
6711
7082
  const agentPageUrl = agentId && dashboardUrl ? `${dashboardUrl.replace(/\/$/, "")}/agents/${agentId}` : null;
6712
7083
  useInput9((_input, key) => {
6713
7084
  if (_input === "u" && upgradePrompt) {
6714
- void open3(billingPageUrl);
7085
+ void open4(billingPageUrl);
6715
7086
  setUpgradeModalDismissed(true);
6716
7087
  return;
6717
7088
  }
6718
7089
  if (_input === "o" && agentPageUrl && !(state.phase === "steering" && steeringRecap)) {
6719
- void open3(agentPageUrl);
7090
+ void open4(agentPageUrl);
6720
7091
  return;
6721
7092
  }
6722
7093
  if (key.ctrl && _input === "c") {
@@ -6748,7 +7119,7 @@ function MarathonApp({
6748
7119
  return;
6749
7120
  }
6750
7121
  if (key.return) {
6751
- void open3(billingPageUrl);
7122
+ void open4(billingPageUrl);
6752
7123
  setUpgradeModalDismissed(true);
6753
7124
  return;
6754
7125
  }
@@ -6787,7 +7158,22 @@ function MarathonApp({
6787
7158
  selectSessionTab(shortcutTabKey);
6788
7159
  return;
6789
7160
  }
7161
+ if (_input === "f" && !detailEvent && !detailFile) {
7162
+ setShowFilesPanel((prev) => {
7163
+ const next = !prev;
7164
+ if (next) setShowEventStream(false);
7165
+ return next;
7166
+ });
7167
+ setScrollOffset(0);
7168
+ return;
7169
+ }
6790
7170
  if (key.tab) {
7171
+ if (showFilesPanel) {
7172
+ setShowFilesPanel(false);
7173
+ setDetailFile(null);
7174
+ setDetailFileContent(null);
7175
+ setFileDetailScrollOffset(0);
7176
+ }
6791
7177
  setShowEventStream((prev) => !prev);
6792
7178
  setScrollOffset(0);
6793
7179
  setDetailEvent(null);
@@ -6795,7 +7181,13 @@ function MarathonApp({
6795
7181
  return;
6796
7182
  }
6797
7183
  if (key.escape) {
6798
- if (detailEvent) {
7184
+ if (detailFile) {
7185
+ setDetailFile(null);
7186
+ setDetailFileContent(null);
7187
+ setFileDetailScrollOffset(0);
7188
+ } else if (showFilesPanel) {
7189
+ setShowFilesPanel(false);
7190
+ } else if (detailEvent) {
6799
7191
  setDetailEvent(null);
6800
7192
  setDetailScrollOffset(0);
6801
7193
  } else if (goalExpanded) {
@@ -6811,6 +7203,19 @@ function MarathonApp({
6811
7203
  setReasoningCollapsed((prev) => !prev);
6812
7204
  return;
6813
7205
  }
7206
+ if (_input === "c" && showFilesPanel) {
7207
+ if (detailFile && detailFileContent) {
7208
+ const ok = copyToClipboard(detailFileContent);
7209
+ showFlash(ok ? "Copied content!" : "Copy failed");
7210
+ } else {
7211
+ const file = trackedFiles[fileCursor];
7212
+ if (file) {
7213
+ const ok = copyToClipboard(file.path);
7214
+ showFlash(ok ? "Copied path!" : "Copy failed");
7215
+ }
7216
+ }
7217
+ return;
7218
+ }
6814
7219
  if (_input === "c" && showEventStream) {
6815
7220
  const evt = detailEvent ?? displayedEvents[eventCursor];
6816
7221
  if (evt) {
@@ -6820,6 +7225,24 @@ function MarathonApp({
6820
7225
  }
6821
7226
  return;
6822
7227
  }
7228
+ if (key.return && showFilesPanel && !detailFile) {
7229
+ const file = trackedFiles[fileCursor];
7230
+ if (file) {
7231
+ const { content, totalLines, truncated } = readFileContent(file.path);
7232
+ setDetailFile(file);
7233
+ setDetailFileContent(content);
7234
+ setDetailFileTotalLines(totalLines);
7235
+ setDetailFileTruncated(truncated);
7236
+ setFileDetailScrollOffset(0);
7237
+ }
7238
+ return;
7239
+ }
7240
+ if (key.return && detailFile) {
7241
+ setDetailFile(null);
7242
+ setDetailFileContent(null);
7243
+ setFileDetailScrollOffset(0);
7244
+ return;
7245
+ }
6823
7246
  if (key.return && showEventStream && !detailEvent) {
6824
7247
  const evt = displayedEvents[eventCursor];
6825
7248
  if (evt) {
@@ -6834,7 +7257,11 @@ function MarathonApp({
6834
7257
  return;
6835
7258
  }
6836
7259
  if (key.upArrow) {
6837
- if (showEventStream && detailEvent) {
7260
+ if (showFilesPanel && detailFile) {
7261
+ setFileDetailScrollOffset((prev) => prev + SCROLL_STEP2);
7262
+ } else if (showFilesPanel) {
7263
+ setFileCursor((prev) => Math.max(0, prev - 1));
7264
+ } else if (showEventStream && detailEvent) {
6838
7265
  setDetailScrollOffset((prev) => prev + SCROLL_STEP2);
6839
7266
  } else if (showEventStream) {
6840
7267
  setEventCursor((prev) => Math.max(0, prev - 1));
@@ -6844,7 +7271,11 @@ function MarathonApp({
6844
7271
  return;
6845
7272
  }
6846
7273
  if (key.downArrow) {
6847
- if (showEventStream && detailEvent) {
7274
+ if (showFilesPanel && detailFile) {
7275
+ setFileDetailScrollOffset((prev) => Math.max(0, prev - SCROLL_STEP2));
7276
+ } else if (showFilesPanel) {
7277
+ setFileCursor((prev) => Math.min(trackedFiles.length - 1, prev + 1));
7278
+ } else if (showEventStream && detailEvent) {
6848
7279
  setDetailScrollOffset((prev) => Math.max(0, prev - SCROLL_STEP2));
6849
7280
  } else if (showEventStream) {
6850
7281
  setEventCursor((prev) => Math.min(displayedEvents.length - 1, prev + 1));
@@ -6853,6 +7284,34 @@ function MarathonApp({
6853
7284
  }
6854
7285
  return;
6855
7286
  }
7287
+ if (key.leftArrow && showFilesPanel && detailFile) {
7288
+ const newIndex = Math.max(0, fileCursor - 1);
7289
+ const file = trackedFiles[newIndex];
7290
+ if (file) {
7291
+ setFileCursor(newIndex);
7292
+ const { content, totalLines, truncated } = readFileContent(file.path);
7293
+ setDetailFile(file);
7294
+ setDetailFileContent(content);
7295
+ setDetailFileTotalLines(totalLines);
7296
+ setDetailFileTruncated(truncated);
7297
+ setFileDetailScrollOffset(0);
7298
+ }
7299
+ return;
7300
+ }
7301
+ if (key.rightArrow && showFilesPanel && detailFile) {
7302
+ const newIndex = Math.min(trackedFiles.length - 1, fileCursor + 1);
7303
+ const file = trackedFiles[newIndex];
7304
+ if (file) {
7305
+ setFileCursor(newIndex);
7306
+ const { content, totalLines, truncated } = readFileContent(file.path);
7307
+ setDetailFile(file);
7308
+ setDetailFileContent(content);
7309
+ setDetailFileTotalLines(totalLines);
7310
+ setDetailFileTruncated(truncated);
7311
+ setFileDetailScrollOffset(0);
7312
+ }
7313
+ return;
7314
+ }
6856
7315
  if (key.leftArrow && showEventStream && detailEvent) {
6857
7316
  navigateToEvent(eventCursor - 1);
6858
7317
  return;
@@ -6891,6 +7350,22 @@ function MarathonApp({
6891
7350
  const scrollHint2 = scrollOffset > 0 ? `+${scrollOffset} scroll` : void 0;
6892
7351
  return joinHints("\u2191\u2193: scroll", "Ctrl+C", scrollHint2);
6893
7352
  }
7353
+ if (showFilesPanel && detailFile) {
7354
+ return joinHints(
7355
+ "c: copy content",
7356
+ "\u2190\u2192: prev/next",
7357
+ "Esc: back",
7358
+ "Ctrl+C"
7359
+ );
7360
+ }
7361
+ if (showFilesPanel) {
7362
+ return joinHints(
7363
+ "Enter: view",
7364
+ "c: copy path",
7365
+ "f/Esc: close",
7366
+ "Ctrl+C"
7367
+ );
7368
+ }
6894
7369
  if (showEventStream && detailEvent) {
6895
7370
  return joinHints(
6896
7371
  "Shift+\u2190/\u2192: tabs",
@@ -6917,12 +7392,14 @@ function MarathonApp({
6917
7392
  "Shift+\u2190/\u2192: tabs",
6918
7393
  "1-9: jump",
6919
7394
  "0: latest",
7395
+ "f: files",
6920
7396
  "Tab: events",
6921
7397
  "Ctrl+C",
6922
7398
  scrollHint,
6923
7399
  upgradePrompt ? "u: upgrade" : void 0
6924
7400
  );
6925
7401
  })();
7402
+ const filesCenter = detailFile ? `${detailFile.path.split("/").pop()}${separator}${fileCursor + 1}/${trackedFiles.length}` : `${trackedFiles.length} files`;
6926
7403
  const detailCenter = detailEvent ? `Event detail${separator}${eventCursor + 1}/${displayedEvents.length}` : "Event stream";
6927
7404
  const goalText = goal || "";
6928
7405
  const goalExpandedRows = goalExpanded && goalText.length > terminalWidth - 4 ? Math.ceil(goalText.length / (terminalWidth - 4)) - 1 : 0;
@@ -6935,7 +7412,7 @@ function MarathonApp({
6935
7412
  adjustedContentHeight - reasoningHintRows - reasoningLiveRows - thinkingRows - 3
6936
7413
  );
6937
7414
  const targetReasoningRows = hasReasoning && !reasoningCollapsed ? Math.min(maxReasoningRows, Math.max(3, Math.min(8, Math.floor(adjustedContentHeight * 0.3)))) : 0;
6938
- const visibleReasoningLines = useMemo5(
7415
+ const visibleReasoningLines = useMemo7(
6939
7416
  () => getVisibleReasoningLines(displayedReasoning, targetReasoningRows),
6940
7417
  [displayedReasoning, targetReasoningRows]
6941
7418
  );
@@ -6946,14 +7423,14 @@ function MarathonApp({
6946
7423
  );
6947
7424
  const upgradeModalWidth = Math.max(24, Math.min(terminalWidth - 6, 88));
6948
7425
  const showUpgradeBrowseHint = canBrowseAfterUpgradeError && selectedIsLive && !displayedContent.trim() && !displayedReasoning.trim() && displayedTools.length === 0 && displayedEvents.length === 0;
6949
- return /* @__PURE__ */ jsxs22(
6950
- Box24,
7426
+ return /* @__PURE__ */ jsxs23(
7427
+ Box25,
6951
7428
  {
6952
7429
  flexDirection: "column",
6953
7430
  height: terminalRows,
6954
7431
  width: terminalWidth,
6955
7432
  children: [
6956
- /* @__PURE__ */ jsx26(
7433
+ /* @__PURE__ */ jsx27(
6957
7434
  SessionHeader,
6958
7435
  {
6959
7436
  sessionName: taskName,
@@ -6974,7 +7451,7 @@ function MarathonApp({
6974
7451
  previewUrl
6975
7452
  }
6976
7453
  ),
6977
- hasTabs && /* @__PURE__ */ jsx26(Box24, { width: terminalWidth, marginBottom: 1, children: /* @__PURE__ */ jsx26(
7454
+ hasTabs && /* @__PURE__ */ jsx27(Box25, { width: terminalWidth, marginBottom: 1, children: /* @__PURE__ */ jsx27(
6978
7455
  SessionTabs,
6979
7456
  {
6980
7457
  tabs: visibleTabs.tabs,
@@ -6982,13 +7459,13 @@ function MarathonApp({
6982
7459
  hiddenRight: visibleTabs.hiddenRight
6983
7460
  }
6984
7461
  ) }),
6985
- state.phase === "steering" && steeringRecap ? /* @__PURE__ */ jsxs22(
6986
- Box24,
7462
+ state.phase === "steering" && steeringRecap ? /* @__PURE__ */ jsxs23(
7463
+ Box25,
6987
7464
  {
6988
7465
  flexDirection: "column",
6989
7466
  height: adjustedContentHeight,
6990
7467
  children: [
6991
- /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: /* @__PURE__ */ jsx26(
7468
+ /* @__PURE__ */ jsx27(Box25, { flexDirection: "column", flexGrow: 1, overflow: "hidden", children: /* @__PURE__ */ jsx27(
6992
7469
  StreamOutput3,
6993
7470
  {
6994
7471
  content: displayedContent,
@@ -6998,7 +7475,7 @@ function MarathonApp({
6998
7475
  scrollOffset
6999
7476
  }
7000
7477
  ) }),
7001
- /* @__PURE__ */ jsx26(
7478
+ /* @__PURE__ */ jsx27(
7002
7479
  SteeringPrompt,
7003
7480
  {
7004
7481
  onSubmit: handleSteeringSubmit,
@@ -7011,13 +7488,33 @@ function MarathonApp({
7011
7488
  )
7012
7489
  ]
7013
7490
  }
7014
- ) : showEventStream ? /* @__PURE__ */ jsx26(
7015
- Box24,
7491
+ ) : showFilesPanel ? /* @__PURE__ */ jsx27(
7492
+ Box25,
7493
+ {
7494
+ flexDirection: "column",
7495
+ height: adjustedContentHeight,
7496
+ overflow: "hidden",
7497
+ children: /* @__PURE__ */ jsx27(
7498
+ FilesPanel,
7499
+ {
7500
+ files: trackedFiles,
7501
+ maxVisibleLines: adjustedContentHeight - 1,
7502
+ selectedIndex: fileCursor,
7503
+ detailFile,
7504
+ detailContent: detailFileContent,
7505
+ detailTotalLines: detailFileTotalLines,
7506
+ detailTruncated: detailFileTruncated,
7507
+ detailScrollOffset: fileDetailScrollOffset
7508
+ }
7509
+ )
7510
+ }
7511
+ ) : showEventStream ? /* @__PURE__ */ jsx27(
7512
+ Box25,
7016
7513
  {
7017
7514
  flexDirection: "column",
7018
7515
  height: adjustedContentHeight,
7019
7516
  overflow: "hidden",
7020
- children: /* @__PURE__ */ jsx26(
7517
+ children: /* @__PURE__ */ jsx27(
7021
7518
  EventStreamPanel,
7022
7519
  {
7023
7520
  events: displayedEvents,
@@ -7029,28 +7526,28 @@ function MarathonApp({
7029
7526
  }
7030
7527
  )
7031
7528
  }
7032
- ) : /* @__PURE__ */ jsxs22(
7033
- Box24,
7529
+ ) : /* @__PURE__ */ jsxs23(
7530
+ Box25,
7034
7531
  {
7035
7532
  flexDirection: isStacked ? "column" : "row",
7036
7533
  height: adjustedContentHeight,
7037
7534
  overflow: "hidden",
7038
7535
  children: [
7039
- /* @__PURE__ */ jsx26(
7040
- Box24,
7536
+ /* @__PURE__ */ jsx27(
7537
+ Box25,
7041
7538
  {
7042
7539
  flexDirection: "column",
7043
7540
  flexGrow: 1,
7044
7541
  flexShrink: 1,
7045
7542
  marginLeft: contentMarginLeft,
7046
7543
  marginRight: contentMarginRight,
7047
- children: showLoadingAnimation ? /* @__PURE__ */ jsx26(
7048
- Box24,
7544
+ children: showLoadingAnimation ? /* @__PURE__ */ jsx27(
7545
+ Box25,
7049
7546
  {
7050
7547
  flexGrow: 1,
7051
7548
  minHeight: adjustedContentHeight,
7052
7549
  overflow: "hidden",
7053
- children: /* @__PURE__ */ jsx26(
7550
+ children: /* @__PURE__ */ jsx27(
7054
7551
  LoadingAnimation,
7055
7552
  {
7056
7553
  width: transcriptPaneWidth,
@@ -7058,8 +7555,8 @@ function MarathonApp({
7058
7555
  }
7059
7556
  )
7060
7557
  }
7061
- ) : /* @__PURE__ */ jsxs22(Fragment3, { children: [
7062
- hasReasoning && /* @__PURE__ */ jsx26(Box24, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx26(
7558
+ ) : /* @__PURE__ */ jsxs23(Fragment3, { children: [
7559
+ hasReasoning && /* @__PURE__ */ jsx27(Box25, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx27(
7063
7560
  ReasoningBlock,
7064
7561
  {
7065
7562
  lines: visibleReasoningLines,
@@ -7068,8 +7565,8 @@ function MarathonApp({
7068
7565
  showToggleHint: true
7069
7566
  }
7070
7567
  ) }),
7071
- showThinkingIndicator && /* @__PURE__ */ jsx26(ThinkingIndicator, { startedAt: state.thinkingStartedAt }),
7072
- showUpgradeBrowseHint && /* @__PURE__ */ jsx26(Box24, { marginBottom: 1, children: /* @__PURE__ */ jsx26(
7568
+ showThinkingIndicator && /* @__PURE__ */ jsx27(ThinkingIndicator, { startedAt: state.thinkingStartedAt }),
7569
+ showUpgradeBrowseHint && /* @__PURE__ */ jsx27(Box25, { marginBottom: 1, children: /* @__PURE__ */ jsx27(
7073
7570
  ReasoningBlock,
7074
7571
  {
7075
7572
  lines: [
@@ -7079,7 +7576,7 @@ function MarathonApp({
7079
7576
  compact: true
7080
7577
  }
7081
7578
  ) }),
7082
- /* @__PURE__ */ jsx26(
7579
+ /* @__PURE__ */ jsx27(
7083
7580
  StreamOutput3,
7084
7581
  {
7085
7582
  content: displayedContent,
@@ -7089,22 +7586,22 @@ function MarathonApp({
7089
7586
  scrollOffset
7090
7587
  }
7091
7588
  ),
7092
- selectedIsLive && state.error && !upgradePrompt && /* @__PURE__ */ jsx26(ErrorDisplay4, { error: state.error })
7589
+ selectedIsLive && state.error && !upgradePrompt && /* @__PURE__ */ jsx27(ErrorDisplay4, { error: state.error })
7093
7590
  ] })
7094
7591
  }
7095
7592
  ),
7096
- (hasTools || hasReasoning) && /* @__PURE__ */ jsx26(
7097
- Box24,
7593
+ (hasTools || hasReasoning) && /* @__PURE__ */ jsx27(
7594
+ Box25,
7098
7595
  {
7099
7596
  flexDirection: "column",
7100
7597
  width: isStacked ? void 0 : toolPanelWidth,
7101
7598
  flexShrink: 0,
7102
7599
  borderStyle: "single",
7103
- borderColor: theme27.border,
7104
- backgroundColor: theme27.background,
7105
- paddingX: theme27.panelPaddingX,
7106
- paddingY: theme27.panelPaddingY,
7107
- children: /* @__PURE__ */ jsx26(
7600
+ borderColor: theme28.border,
7601
+ backgroundColor: theme28.background,
7602
+ paddingX: theme28.panelPaddingX,
7603
+ paddingY: theme28.panelPaddingY,
7604
+ children: /* @__PURE__ */ jsx27(
7108
7605
  ToolPanel,
7109
7606
  {
7110
7607
  tools: displayedTools,
@@ -7117,8 +7614,8 @@ function MarathonApp({
7117
7614
  ]
7118
7615
  }
7119
7616
  ),
7120
- showUpgradeModal && upgradePrompt && /* @__PURE__ */ jsx26(
7121
- Box24,
7617
+ showUpgradeModal && upgradePrompt && /* @__PURE__ */ jsx27(
7618
+ Box25,
7122
7619
  {
7123
7620
  marginTop: -adjustedContentHeight,
7124
7621
  marginBottom: -adjustedContentHeight,
@@ -7126,14 +7623,14 @@ function MarathonApp({
7126
7623
  justifyContent: "center",
7127
7624
  alignItems: "center",
7128
7625
  flexShrink: 0,
7129
- children: /* @__PURE__ */ jsx26(UpgradeModal, { prompt: upgradePrompt, width: upgradeModalWidth })
7626
+ children: /* @__PURE__ */ jsx27(UpgradeModal, { prompt: upgradePrompt, width: upgradeModalWidth })
7130
7627
  }
7131
7628
  ),
7132
- /* @__PURE__ */ jsx26(
7629
+ /* @__PURE__ */ jsx27(
7133
7630
  StatusBar2,
7134
7631
  {
7135
7632
  left: `Model: ${currentModel}`,
7136
- center: showEventStream ? detailCenter : currentSandbox ? `Sandbox: ${currentSandbox}` : void 0,
7633
+ center: showFilesPanel ? filesCenter : showEventStream ? detailCenter : currentSandbox ? `Sandbox: ${currentSandbox}` : void 0,
7137
7634
  right: statusRight
7138
7635
  }
7139
7636
  )
@@ -7143,14 +7640,15 @@ function MarathonApp({
7143
7640
  }
7144
7641
 
7145
7642
  // src/commands/agents-task.ts
7146
- import * as fs10 from "fs";
7643
+ import * as fs11 from "fs";
7147
7644
  import {
7148
7645
  RuntypeClient as RuntypeClient2,
7149
- deployWorkflow
7646
+ deployWorkflow,
7647
+ gameWorkflow
7150
7648
  } from "@runtypelabs/sdk";
7151
7649
 
7152
7650
  // src/marathon/checkpoint.ts
7153
- import * as fs4 from "fs";
7651
+ import * as fs5 from "fs";
7154
7652
  import * as path5 from "path";
7155
7653
  function defaultStateDir() {
7156
7654
  return path5.join(process.cwd(), ".runtype", "marathons");
@@ -7175,14 +7673,14 @@ function ensureMarathonFileCheckpoint(taskName, targetPath, stateDir) {
7175
7673
  const normalizedTargetPath = path5.resolve(targetPath);
7176
7674
  const relativeTargetPath = path5.relative(process.cwd(), normalizedTargetPath);
7177
7675
  if (!relativeTargetPath || relativeTargetPath.startsWith("..")) return void 0;
7178
- if (!fs4.existsSync(normalizedTargetPath)) return void 0;
7179
- if (!fs4.statSync(normalizedTargetPath).isFile()) return void 0;
7676
+ if (!fs5.existsSync(normalizedTargetPath)) return void 0;
7677
+ if (!fs5.statSync(normalizedTargetPath).isFile()) return void 0;
7180
7678
  const normalizedRelativeTargetPath = relativeTargetPath.replace(/\\/g, "/");
7181
7679
  if (normalizedRelativeTargetPath.startsWith(".runtype/")) return void 0;
7182
7680
  const checkpointPath = resolveMarathonCheckpointPath(taskName, normalizedTargetPath, stateDir);
7183
- if (fs4.existsSync(checkpointPath)) return checkpointPath;
7184
- fs4.mkdirSync(path5.dirname(checkpointPath), { recursive: true });
7185
- fs4.copyFileSync(normalizedTargetPath, checkpointPath);
7681
+ if (fs5.existsSync(checkpointPath)) return checkpointPath;
7682
+ fs5.mkdirSync(path5.dirname(checkpointPath), { recursive: true });
7683
+ fs5.copyFileSync(normalizedTargetPath, checkpointPath);
7186
7684
  return checkpointPath;
7187
7685
  }
7188
7686
  function restoreMarathonFileCheckpoint(taskName, targetPath, stateDir) {
@@ -7195,15 +7693,15 @@ function restoreMarathonFileCheckpoint(taskName, targetPath, stateDir) {
7195
7693
  };
7196
7694
  }
7197
7695
  const checkpointPath = resolveMarathonCheckpointPath(taskName, normalizedTargetPath, stateDir);
7198
- if (!fs4.existsSync(checkpointPath)) {
7696
+ if (!fs5.existsSync(checkpointPath)) {
7199
7697
  return {
7200
7698
  restored: false,
7201
7699
  checkpointPath,
7202
7700
  error: `No checkpoint found for ${normalizedTargetPath}`
7203
7701
  };
7204
7702
  }
7205
- fs4.mkdirSync(path5.dirname(normalizedTargetPath), { recursive: true });
7206
- fs4.copyFileSync(checkpointPath, normalizedTargetPath);
7703
+ fs5.mkdirSync(path5.dirname(normalizedTargetPath), { recursive: true });
7704
+ fs5.copyFileSync(checkpointPath, normalizedTargetPath);
7207
7705
  return { restored: true, checkpointPath };
7208
7706
  }
7209
7707
 
@@ -7320,7 +7818,7 @@ function isSafeVerificationCommand(command) {
7320
7818
  }
7321
7819
 
7322
7820
  // src/marathon/state.ts
7323
- import * as fs5 from "fs";
7821
+ import * as fs6 from "fs";
7324
7822
  import * as path6 from "path";
7325
7823
  import chalk14 from "chalk";
7326
7824
  function defaultStateDir2() {
@@ -7340,7 +7838,7 @@ function normalizeMarathonStatePath(candidatePath) {
7340
7838
  }
7341
7839
  function marathonStatePathExists(candidatePath) {
7342
7840
  if (!candidatePath) return false;
7343
- return fs5.existsSync(path6.resolve(candidatePath));
7841
+ return fs6.existsSync(path6.resolve(candidatePath));
7344
7842
  }
7345
7843
  function isMarathonArtifactStatePath(candidatePath) {
7346
7844
  if (!candidatePath) return false;
@@ -7508,7 +8006,7 @@ function sanitizeLoadedMarathonState(state) {
7508
8006
  }
7509
8007
  function loadState(filePath) {
7510
8008
  try {
7511
- const raw = fs5.readFileSync(filePath, "utf-8");
8009
+ const raw = fs6.readFileSync(filePath, "utf-8");
7512
8010
  return sanitizeLoadedMarathonState(JSON.parse(raw));
7513
8011
  } catch {
7514
8012
  return null;
@@ -7516,8 +8014,8 @@ function loadState(filePath) {
7516
8014
  }
7517
8015
  function saveState(filePath, state) {
7518
8016
  const dir = path6.dirname(filePath);
7519
- fs5.mkdirSync(dir, { recursive: true });
7520
- fs5.writeFileSync(filePath, JSON.stringify(state, null, 2));
8017
+ fs6.mkdirSync(dir, { recursive: true });
8018
+ fs6.writeFileSync(filePath, JSON.stringify(state, null, 2));
7521
8019
  }
7522
8020
  function extractRunTaskResumeState(state) {
7523
8021
  if (!state) return void 0;
@@ -7542,9 +8040,9 @@ function extractRunTaskResumeState(state) {
7542
8040
  }
7543
8041
  function findStateFile(name, stateDir) {
7544
8042
  const newPath = stateFilePath(name, stateDir || path6.join(process.cwd(), ".runtype", "marathons"));
7545
- if (fs5.existsSync(newPath)) return newPath;
8043
+ if (fs6.existsSync(newPath)) return newPath;
7546
8044
  const oldPath = stateFilePath(name, path6.join(process.cwd(), ".runtype", "tasks"));
7547
- if (fs5.existsSync(oldPath)) return oldPath;
8045
+ if (fs6.existsSync(oldPath)) return oldPath;
7548
8046
  return newPath;
7549
8047
  }
7550
8048
  function findLatestStateFile(stateDir) {
@@ -7554,11 +8052,11 @@ function findLatestStateFile(stateDir) {
7554
8052
  ];
7555
8053
  let latest = null;
7556
8054
  for (const dir of dirs) {
7557
- if (!fs5.existsSync(dir)) continue;
7558
- const files = fs5.readdirSync(dir).filter((f) => f.endsWith(".json"));
8055
+ if (!fs6.existsSync(dir)) continue;
8056
+ const files = fs6.readdirSync(dir).filter((f) => f.endsWith(".json"));
7559
8057
  for (const file of files) {
7560
8058
  const fullPath = path6.join(dir, file);
7561
- const stat = fs5.statSync(fullPath);
8059
+ const stat = fs6.statSync(fullPath);
7562
8060
  if (!latest || stat.mtimeMs > latest.mtime) {
7563
8061
  latest = { name: file.replace(".json", ""), filePath: fullPath, mtime: stat.mtimeMs };
7564
8062
  }
@@ -7649,7 +8147,7 @@ async function resolveMarathonStateResolution(options, taskName, filePath, promp
7649
8147
  if (options.fresh) {
7650
8148
  return { action: "fresh" };
7651
8149
  }
7652
- if (!fs5.existsSync(filePath)) {
8150
+ if (!fs6.existsSync(filePath)) {
7653
8151
  return { action: "fresh" };
7654
8152
  }
7655
8153
  if (!allowPrompt) {
@@ -7786,14 +8284,15 @@ function createSandboxInstructions(provider) {
7786
8284
  "--- Deploy with Preview (Daytona) ---",
7787
8285
  "You also have `deploy_sandbox` to deploy a persistent web server and get a live preview URL.",
7788
8286
  "Call shape:",
7789
- '{ "code": "...", "packageJson": { "dependencies": { "express": "^4.18.2" } }, "language": "typescript", "port": 3000, "startCommand": "npx tsx main.ts" }',
8287
+ '{ "code": "...", "files": { "public/index.html": "..." }, "packageJson": { "dependencies": { "express": "^4.18.2" } }, "language": "typescript", "port": 3000, "startCommand": "npx tsx main.ts" }',
7790
8288
  "Deploy rules:",
7791
8289
  "1. Use this when you need to run a web server (Express, Hono, etc.) that the user can visit in their browser.",
7792
8290
  "2. The `code` is written to main.ts (or main.js/main.py). The `packageJson` object installs dependencies.",
7793
- "3. The server must listen on the specified `port` (default 3000).",
7794
- "4. The sandbox is persistent \u2014 it stays alive across sessions. The same sandbox is reused on subsequent calls.",
7795
- "5. The returned `previewUrl` is a live URL the user can open in their browser.",
7796
- "6. Prefer this over `run_sandbox_code` when building web apps, APIs, or anything with a UI."
8291
+ "3. The `files` parameter writes additional files (path \u2192 content). Use this for HTML/CSS/JS assets instead of embedding them in template literals.",
8292
+ "4. The server must listen on the specified `port` (default 3000).",
8293
+ "5. The sandbox is persistent \u2014 it stays alive across sessions. The same sandbox is reused on subsequent calls.",
8294
+ "6. The returned `previewUrl` is a live URL the user can open in their browser.",
8295
+ "7. Prefer this over `run_sandbox_code` when building web apps, APIs, or anything with a UI."
7797
8296
  ].join("\n");
7798
8297
  }
7799
8298
  function createSandboxLocalTool(client, provider, debugMode) {
@@ -7937,6 +8436,11 @@ function createDeploySandboxLocalTool(client, debugMode) {
7937
8436
  startCommand: {
7938
8437
  type: "string",
7939
8438
  description: "Custom start command (default: auto-detected from language)"
8439
+ },
8440
+ files: {
8441
+ type: "object",
8442
+ description: 'Additional files to write (path \u2192 content), e.g. { "public/index.html": "<html>..." }. Use this for multi-file projects instead of embedding HTML in template literals.',
8443
+ additionalProperties: { type: "string" }
7940
8444
  }
7941
8445
  },
7942
8446
  required: ["code"]
@@ -7952,6 +8456,7 @@ function createDeploySandboxLocalTool(client, debugMode) {
7952
8456
  ...typeof args.language === "string" ? { language: args.language } : {},
7953
8457
  ...typeof args.port === "number" ? { port: args.port } : {},
7954
8458
  ...typeof args.startCommand === "string" ? { startCommand: args.startCommand } : {},
8459
+ ...args.files && typeof args.files === "object" && !Array.isArray(args.files) ? { files: args.files } : {},
7955
8460
  // Reuse existing sandbox if one was created
7956
8461
  ...activeDeploySandboxId ? { sandboxId: activeDeploySandboxId } : {}
7957
8462
  };
@@ -7998,12 +8503,12 @@ async function cleanupDeploySandboxes(client) {
7998
8503
  }
7999
8504
 
8000
8505
  // src/marathon/local-tools.ts
8001
- import * as fs7 from "fs";
8506
+ import * as fs8 from "fs";
8002
8507
  import * as path8 from "path";
8003
8508
  import { spawnSync } from "child_process";
8004
8509
 
8005
8510
  // src/marathon/repo-discovery.ts
8006
- import * as fs6 from "fs";
8511
+ import * as fs7 from "fs";
8007
8512
  import * as path7 from "path";
8008
8513
  var IGNORED_REPO_DIRS = /* @__PURE__ */ new Set([
8009
8514
  ".git",
@@ -8108,9 +8613,9 @@ function shouldIgnoreRepoEntry(entryPath) {
8108
8613
  }
8109
8614
  function safeReadTextFile(filePath) {
8110
8615
  try {
8111
- const stat = fs6.statSync(filePath);
8616
+ const stat = fs7.statSync(filePath);
8112
8617
  if (!stat.isFile() || stat.size > MAX_FILE_BYTES_TO_SCAN) return null;
8113
- const buffer = fs6.readFileSync(filePath);
8618
+ const buffer = fs7.readFileSync(filePath);
8114
8619
  if (buffer.includes(0)) return null;
8115
8620
  return buffer.toString("utf-8");
8116
8621
  } catch {
@@ -8118,14 +8623,14 @@ function safeReadTextFile(filePath) {
8118
8623
  }
8119
8624
  }
8120
8625
  function walkRepo(startPath, visitor) {
8121
- if (!fs6.existsSync(startPath) || !fs6.statSync(startPath).isDirectory()) return;
8626
+ if (!fs7.existsSync(startPath) || !fs7.statSync(startPath).isDirectory()) return;
8122
8627
  const stack = [startPath];
8123
8628
  while (stack.length > 0) {
8124
8629
  const currentDir = stack.pop();
8125
8630
  if (!currentDir) continue;
8126
8631
  let entries;
8127
8632
  try {
8128
- entries = fs6.readdirSync(currentDir, { withFileTypes: true });
8633
+ entries = fs7.readdirSync(currentDir, { withFileTypes: true });
8129
8634
  } catch {
8130
8635
  continue;
8131
8636
  }
@@ -8168,7 +8673,7 @@ function buildTree(dirPath, maxDepth, depth = 0) {
8168
8673
  if (depth > maxDepth || shouldIgnoreRepoEntry(dirPath)) return [];
8169
8674
  let entries;
8170
8675
  try {
8171
- entries = fs6.readdirSync(dirPath, { withFileTypes: true });
8676
+ entries = fs7.readdirSync(dirPath, { withFileTypes: true });
8172
8677
  } catch (error) {
8173
8678
  const message = error instanceof Error ? error.message : String(error);
8174
8679
  return [`${" ".repeat(depth)}[error reading ${normalizeToolPath(dirPath)}: ${message}]`];
@@ -8197,7 +8702,7 @@ var defaultLocalTools = {
8197
8702
  execute: async (args) => {
8198
8703
  const toolFilePath = String(args.path || "");
8199
8704
  if (!toolFilePath) return "Error: path is required";
8200
- return fs7.readFileSync(toolFilePath, "utf-8");
8705
+ return fs8.readFileSync(toolFilePath, "utf-8");
8201
8706
  }
8202
8707
  },
8203
8708
  write_file: {
@@ -8215,8 +8720,8 @@ var defaultLocalTools = {
8215
8720
  if (!toolFilePath) return "Error: path is required";
8216
8721
  const content = String(args.content || "");
8217
8722
  const dir = path8.dirname(toolFilePath);
8218
- fs7.mkdirSync(dir, { recursive: true });
8219
- fs7.writeFileSync(toolFilePath, content);
8723
+ fs8.mkdirSync(dir, { recursive: true });
8724
+ fs8.writeFileSync(toolFilePath, content);
8220
8725
  return "ok";
8221
8726
  }
8222
8727
  },
@@ -8228,7 +8733,7 @@ var defaultLocalTools = {
8228
8733
  },
8229
8734
  execute: async (args) => {
8230
8735
  const dirPath = String(args.path || ".");
8231
- return fs7.readdirSync(dirPath).join("\n");
8736
+ return fs8.readdirSync(dirPath).join("\n");
8232
8737
  }
8233
8738
  },
8234
8739
  search_repo: {
@@ -8255,7 +8760,7 @@ var defaultLocalTools = {
8255
8760
  const query = String(args.query || "").trim();
8256
8761
  if (!query) return "Error: query is required";
8257
8762
  const startPath = path8.resolve(String(args.path || "."));
8258
- if (!fs7.existsSync(startPath)) return `Error: path does not exist: ${startPath}`;
8763
+ if (!fs8.existsSync(startPath)) return `Error: path does not exist: ${startPath}`;
8259
8764
  const maxResults = Math.max(
8260
8765
  1,
8261
8766
  Math.min(100, Number.isFinite(Number(args.maxResults)) ? Math.floor(Number(args.maxResults)) : 20)
@@ -8318,7 +8823,7 @@ var defaultLocalTools = {
8318
8823
  const pattern = String(args.pattern || "").trim();
8319
8824
  if (!pattern) return "Error: pattern is required";
8320
8825
  const startPath = path8.resolve(String(args.path || "."));
8321
- if (!fs7.existsSync(startPath)) return `Error: path does not exist: ${startPath}`;
8826
+ if (!fs8.existsSync(startPath)) return `Error: path does not exist: ${startPath}`;
8322
8827
  const maxResults = Math.max(
8323
8828
  1,
8324
8829
  Math.min(
@@ -8358,8 +8863,8 @@ var defaultLocalTools = {
8358
8863
  },
8359
8864
  execute: async (args) => {
8360
8865
  const dirPath = path8.resolve(String(args.path || "."));
8361
- if (!fs7.existsSync(dirPath)) return `Error: path does not exist: ${dirPath}`;
8362
- if (!fs7.statSync(dirPath).isDirectory()) return `Error: path is not a directory: ${dirPath}`;
8866
+ if (!fs8.existsSync(dirPath)) return `Error: path does not exist: ${dirPath}`;
8867
+ if (!fs8.statSync(dirPath).isDirectory()) return `Error: path is not a directory: ${dirPath}`;
8363
8868
  const maxDepth = Math.max(
8364
8869
  0,
8365
8870
  Math.min(6, Number.isFinite(Number(args.maxDepth)) ? Math.floor(Number(args.maxDepth)) : 2)
@@ -8386,8 +8891,8 @@ function createCheckpointedWriteFileTool(taskName, stateDir) {
8386
8891
  const content = String(args.content || "");
8387
8892
  ensureMarathonFileCheckpoint(taskName, toolFilePath, stateDir);
8388
8893
  const dir = path8.dirname(toolFilePath);
8389
- fs7.mkdirSync(dir, { recursive: true });
8390
- fs7.writeFileSync(toolFilePath, content);
8894
+ fs8.mkdirSync(dir, { recursive: true });
8895
+ fs8.writeFileSync(toolFilePath, content);
8391
8896
  return "ok";
8392
8897
  }
8393
8898
  };
@@ -8582,7 +9087,7 @@ function createLoopDetector(options = {}) {
8582
9087
  }
8583
9088
 
8584
9089
  // src/marathon/context-offload.ts
8585
- import * as fs8 from "fs";
9090
+ import * as fs9 from "fs";
8586
9091
  import * as path9 from "path";
8587
9092
  var DEFAULT_OUTPUT_THRESHOLD = 2e3;
8588
9093
  var DEFAULT_PREVIEW_LENGTH = 200;
@@ -8607,8 +9112,8 @@ function offloadToolOutput(taskName, toolName, output, options = {}, stateDir) {
8607
9112
  );
8608
9113
  const fileName = `${stateSafeName3(toolName)}-${offloadCounter}.txt`;
8609
9114
  const filePath = path9.join(dir, fileName);
8610
- fs8.mkdirSync(dir, { recursive: true });
8611
- fs8.writeFileSync(filePath, output, "utf-8");
9115
+ fs9.mkdirSync(dir, { recursive: true });
9116
+ fs9.writeFileSync(filePath, output, "utf-8");
8612
9117
  const preview = output.slice(0, previewLength).replace(/\n/g, " ");
8613
9118
  const relativePath = path9.relative(process.cwd(), filePath);
8614
9119
  const reference = [
@@ -8632,7 +9137,7 @@ function withOffloading(tool, taskName, toolName, options, stateDir) {
8632
9137
  }
8633
9138
 
8634
9139
  // src/marathon/recipes.ts
8635
- import * as fs9 from "fs";
9140
+ import * as fs10 from "fs";
8636
9141
  import * as path10 from "path";
8637
9142
  var RECIPES_DIR = ".marathon/recipes";
8638
9143
  function loadRecipe(nameOrPath, cwd) {
@@ -8646,9 +9151,9 @@ function loadRecipe(nameOrPath, cwd) {
8646
9151
  path10.resolve(baseCwd, RECIPES_DIR, nameOrPath, "recipe.json")
8647
9152
  ];
8648
9153
  for (const candidate of candidates) {
8649
- if (!fs9.existsSync(candidate)) continue;
9154
+ if (!fs10.existsSync(candidate)) continue;
8650
9155
  try {
8651
- const raw = fs9.readFileSync(candidate, "utf-8");
9156
+ const raw = fs10.readFileSync(candidate, "utf-8");
8652
9157
  const parsed = JSON.parse(raw);
8653
9158
  if (parsed.meta?.name && parsed.meta?.version) {
8654
9159
  return parsed;
@@ -8663,14 +9168,14 @@ var RULES_DIR = ".marathon/rules";
8663
9168
  function loadRules(cwd) {
8664
9169
  const baseCwd = cwd || process.cwd();
8665
9170
  const rulesDir = path10.resolve(baseCwd, RULES_DIR);
8666
- if (!fs9.existsSync(rulesDir)) return [];
9171
+ if (!fs10.existsSync(rulesDir)) return [];
8667
9172
  const rules = [];
8668
9173
  try {
8669
- const entries = fs9.readdirSync(rulesDir).filter((f) => f.endsWith(".md"));
9174
+ const entries = fs10.readdirSync(rulesDir).filter((f) => f.endsWith(".md"));
8670
9175
  for (const entry of entries) {
8671
9176
  const filePath = path10.join(rulesDir, entry);
8672
9177
  try {
8673
- const raw = fs9.readFileSync(filePath, "utf-8");
9178
+ const raw = fs10.readFileSync(filePath, "utf-8");
8674
9179
  const parsed = parseRuleFile(raw);
8675
9180
  rules.push({ ...parsed, filePath });
8676
9181
  } catch {
@@ -8801,7 +9306,7 @@ async function taskAction(agent, options) {
8801
9306
  forcedResumeFilePath = stateResolution.filePath;
8802
9307
  } else {
8803
9308
  resumeRequested = false;
8804
- if (options.fresh && fs10.existsSync(filePath)) {
9309
+ if (options.fresh && fs11.existsSync(filePath)) {
8805
9310
  console.log(chalk16.gray(`Starting fresh and ignoring saved local state at ${filePath}`));
8806
9311
  }
8807
9312
  }
@@ -8963,6 +9468,7 @@ ${rulesContext}`;
8963
9468
  showFinish: !options.noFinish,
8964
9469
  initialRunnerPosition,
8965
9470
  initialRunnerLaps,
9471
+ planPath: lastKnownState?.planPath ?? resumeState?.planPath,
8966
9472
  debug: options.debug,
8967
9473
  plainText: options.plainText ?? false,
8968
9474
  noSteer: options.noSteer ?? false,
@@ -9015,6 +9521,7 @@ Saving state... done. Session saved to ${filePath}`);
9015
9521
  let shouldContinue = true;
9016
9522
  let accumulatedSessions = 0;
9017
9523
  let accumulatedCost = 0;
9524
+ let accumulatedTokens = { input: 0, output: 0 };
9018
9525
  let lastResult = null;
9019
9526
  let lastSessionMessages = [];
9020
9527
  while (shouldContinue) {
@@ -9116,8 +9623,8 @@ Saving state... done. Session saved to ${filePath}`);
9116
9623
  const recap = {
9117
9624
  sessionNumber: adjustedState.sessionCount,
9118
9625
  toolCallsMade: currentActions.getState().tools.length,
9119
- tokensInput: 0,
9120
- tokensOutput: 0,
9626
+ tokensInput: state.totalTokens?.input ?? 0,
9627
+ tokensOutput: state.totalTokens?.output ?? 0,
9121
9628
  cost: state.totalCost,
9122
9629
  outputPreview: adjustedState.lastOutput.slice(0, 100)
9123
9630
  };
@@ -9197,6 +9704,12 @@ Saving state... done. Session saved to ${filePath}`);
9197
9704
  }
9198
9705
  accumulatedSessions += result2.sessionCount;
9199
9706
  accumulatedCost += result2.totalCost;
9707
+ if (result2.totalTokens) {
9708
+ accumulatedTokens = {
9709
+ input: accumulatedTokens.input + result2.totalTokens.input,
9710
+ output: accumulatedTokens.output + result2.totalTokens.output
9711
+ };
9712
+ }
9200
9713
  lastResult = result2;
9201
9714
  if (shouldContinue) {
9202
9715
  previousMessages = lastSessionMessages;
@@ -9215,8 +9728,8 @@ Saving state... done. Session saved to ${filePath}`);
9215
9728
  const recap = {
9216
9729
  sessionNumber: priorSessionCount + accumulatedSessions,
9217
9730
  toolCallsMade: currentActions.getState().tools.length,
9218
- tokensInput: 0,
9219
- tokensOutput: 0,
9731
+ tokensInput: accumulatedTokens.input,
9732
+ tokensOutput: accumulatedTokens.output,
9220
9733
  cost: accumulatedCost,
9221
9734
  outputPreview: terminalPreview.slice(0, 100)
9222
9735
  };
@@ -9373,11 +9886,29 @@ Resume: ${buildResumeCommand(agent, options, parsedSandbox)}`
9373
9886
  }
9374
9887
  function detectDeployWorkflow(message, sandboxProvider, resumeState) {
9375
9888
  if (sandboxProvider !== "daytona") return void 0;
9889
+ if (resumeState?.workflowVariant === "game") return gameWorkflow;
9890
+ if (resumeState?.workflowPhase === "design" || resumeState?.workflowPhase === "build" || resumeState?.workflowPhase === "verify") {
9891
+ return gameWorkflow;
9892
+ }
9376
9893
  if (resumeState?.workflowVariant === "deploy") return deployWorkflow;
9377
9894
  if (resumeState?.workflowPhase === "scaffold" || resumeState?.workflowPhase === "deploy") {
9378
9895
  return deployWorkflow;
9379
9896
  }
9380
9897
  const lower = message.toLowerCase();
9898
+ const gamePatterns = [
9899
+ /\b3d\b.*\bgame\b/,
9900
+ /\bgame\b.*\b3d\b/,
9901
+ /\bthree\.?js\b/,
9902
+ /\bphaser\b/,
9903
+ /\bwebgl\b/,
9904
+ /\bplatformer\b/,
9905
+ /\bracing\b.*\bgame\b/,
9906
+ /\bgame\b.*\bracing\b/,
9907
+ /\bgame\b/
9908
+ ];
9909
+ if (gamePatterns.some((p) => p.test(lower))) {
9910
+ return gameWorkflow;
9911
+ }
9381
9912
  const deployPatterns = [
9382
9913
  /\bdeploy\b/,
9383
9914
  /\bsandbox\b/,
@@ -9456,9 +9987,9 @@ agentsCommand.command("list").description("List all agents").option("--json", "O
9456
9987
  return;
9457
9988
  }
9458
9989
  const App = () => {
9459
- const [items, setItems] = useState20(null);
9460
- const [error, setError] = useState20(null);
9461
- const [total, setTotal] = useState20();
9990
+ const [items, setItems] = useState21(null);
9991
+ const [error, setError] = useState21(null);
9992
+ const [total, setTotal] = useState21();
9462
9993
  useEffect18(() => {
9463
9994
  client.get("/agents", { limit: options.limit }).then((res) => {
9464
9995
  setItems(res.data ?? []);
@@ -9517,8 +10048,8 @@ agentsCommand.command("get <id>").description("Get agent details").option("--jso
9517
10048
  return;
9518
10049
  }
9519
10050
  const App = () => {
9520
- const [items, setItems] = useState20(null);
9521
- const [error, setError] = useState20(null);
10051
+ const [items, setItems] = useState21(null);
10052
+ const [error, setError] = useState21(null);
9522
10053
  useEffect18(() => {
9523
10054
  client.get(`/agents/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
9524
10055
  }, []);
@@ -9569,10 +10100,10 @@ agentsCommand.command("create").description("Create a new agent").requiredOption
9569
10100
  return;
9570
10101
  }
9571
10102
  const App = () => {
9572
- const [loading, setLoading] = useState20(true);
9573
- const [success, setSuccess] = useState20(null);
9574
- const [error, setError] = useState20(null);
9575
- const [result, setResult] = useState20(null);
10103
+ const [loading, setLoading] = useState21(true);
10104
+ const [success, setSuccess] = useState21(null);
10105
+ const [error, setError] = useState21(null);
10106
+ const [result, setResult] = useState21(null);
9576
10107
  useEffect18(() => {
9577
10108
  client.post("/agents", {
9578
10109
  name: options.name,
@@ -9620,10 +10151,10 @@ agentsCommand.command("delete <id>").description("Delete an agent").option("--tt
9620
10151
  return;
9621
10152
  }
9622
10153
  const App = () => {
9623
- const [confirmed, setConfirmed] = useState20(null);
9624
- const [loading, setLoading] = useState20(false);
9625
- const [success, setSuccess] = useState20(null);
9626
- const [error, setError] = useState20(null);
10154
+ const [confirmed, setConfirmed] = useState21(null);
10155
+ const [loading, setLoading] = useState21(false);
10156
+ const [success, setSuccess] = useState21(null);
10157
+ const [error, setError] = useState21(null);
9627
10158
  useEffect18(() => {
9628
10159
  if (confirmed !== true) return void 0;
9629
10160
  setLoading(true);
@@ -9714,7 +10245,7 @@ import { Command as Command13 } from "commander";
9714
10245
  import chalk18 from "chalk";
9715
10246
  import React14 from "react";
9716
10247
  import { render as render12 } from "ink";
9717
- import { useState as useState21, useEffect as useEffect19 } from "react";
10248
+ import { useState as useState22, useEffect as useEffect19 } from "react";
9718
10249
  var modelsCommand = new Command13("models").description("Manage model configurations");
9719
10250
  modelsCommand.command("list").description("List your enabled model configurations").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
9720
10251
  const apiKey = await ensureAuth();
@@ -9751,9 +10282,9 @@ modelsCommand.command("list").description("List your enabled model configuration
9751
10282
  return;
9752
10283
  }
9753
10284
  const App = () => {
9754
- const [items, setItems] = useState21(null);
9755
- const [error, setError] = useState21(null);
9756
- const [total, setTotal] = useState21();
10285
+ const [items, setItems] = useState22(null);
10286
+ const [error, setError] = useState22(null);
10287
+ const [total, setTotal] = useState22();
9757
10288
  useEffect19(() => {
9758
10289
  client.get("/model-configs").then((res) => {
9759
10290
  setItems(res.data ?? []);
@@ -9816,8 +10347,8 @@ modelsCommand.command("available").description("List all available models groupe
9816
10347
  return;
9817
10348
  }
9818
10349
  const App = () => {
9819
- const [items, setItems] = useState21(null);
9820
- const [error, setError] = useState21(null);
10350
+ const [items, setItems] = useState22(null);
10351
+ const [error, setError] = useState22(null);
9821
10352
  useEffect19(() => {
9822
10353
  client.get("/model-configs/grouped").then((res) => setItems(res.data ?? [])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
9823
10354
  }, []);
@@ -9864,10 +10395,10 @@ modelsCommand.command("enable <modelId>").description("Enable a model by creatin
9864
10395
  return;
9865
10396
  }
9866
10397
  const App = () => {
9867
- const [loading, setLoading] = useState21(true);
9868
- const [success, setSuccess] = useState21(null);
9869
- const [error, setError] = useState21(null);
9870
- const [result, setResult] = useState21(null);
10398
+ const [loading, setLoading] = useState22(true);
10399
+ const [success, setSuccess] = useState22(null);
10400
+ const [error, setError] = useState22(null);
10401
+ const [result, setResult] = useState22(null);
9871
10402
  useEffect19(() => {
9872
10403
  client.post("/model-configs", { modelId }).then((data) => {
9873
10404
  setResult(data);
@@ -9912,9 +10443,9 @@ modelsCommand.command("disable <id>").description("Disable a model configuration
9912
10443
  return;
9913
10444
  }
9914
10445
  const App = () => {
9915
- const [loading, setLoading] = useState21(true);
9916
- const [success, setSuccess] = useState21(null);
9917
- const [error, setError] = useState21(null);
10446
+ const [loading, setLoading] = useState22(true);
10447
+ const [success, setSuccess] = useState22(null);
10448
+ const [error, setError] = useState22(null);
9918
10449
  useEffect19(() => {
9919
10450
  client.patch(`/model-configs/${id}/status`, { enabled: false }).then(() => {
9920
10451
  setSuccess(true);
@@ -9952,9 +10483,9 @@ modelsCommand.command("default <id>").description("Set a model configuration as
9952
10483
  return;
9953
10484
  }
9954
10485
  const App = () => {
9955
- const [loading, setLoading] = useState21(true);
9956
- const [success, setSuccess] = useState21(null);
9957
- const [error, setError] = useState21(null);
10486
+ const [loading, setLoading] = useState22(true);
10487
+ const [success, setSuccess] = useState22(null);
10488
+ const [error, setError] = useState22(null);
9958
10489
  useEffect19(() => {
9959
10490
  client.patch(`/model-configs/${id}/default`, {}).then(() => {
9960
10491
  setSuccess(true);
@@ -9996,7 +10527,7 @@ import { Command as Command14 } from "commander";
9996
10527
  import chalk19 from "chalk";
9997
10528
  import React15 from "react";
9998
10529
  import { render as render13 } from "ink";
9999
- import { useState as useState22, useEffect as useEffect20 } from "react";
10530
+ import { useState as useState23, useEffect as useEffect20 } from "react";
10000
10531
  var schedulesCommand = new Command14("schedules").description("Manage schedules");
10001
10532
  schedulesCommand.command("list").description("List all schedules").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
10002
10533
  const apiKey = await ensureAuth();
@@ -10040,9 +10571,9 @@ schedulesCommand.command("list").description("List all schedules").option("--jso
10040
10571
  return;
10041
10572
  }
10042
10573
  const App = () => {
10043
- const [items, setItems] = useState22(null);
10044
- const [error, setError] = useState22(null);
10045
- const [total, setTotal] = useState22();
10574
+ const [items, setItems] = useState23(null);
10575
+ const [error, setError] = useState23(null);
10576
+ const [total, setTotal] = useState23();
10046
10577
  useEffect20(() => {
10047
10578
  client.get("/schedules").then((res) => {
10048
10579
  setItems(res.data ?? []);
@@ -10106,8 +10637,8 @@ schedulesCommand.command("get <id>").description("Get schedule details").option(
10106
10637
  return;
10107
10638
  }
10108
10639
  const App = () => {
10109
- const [items, setItems] = useState22(null);
10110
- const [error, setError] = useState22(null);
10640
+ const [items, setItems] = useState23(null);
10641
+ const [error, setError] = useState23(null);
10111
10642
  useEffect20(() => {
10112
10643
  client.get(`/schedules/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
10113
10644
  }, []);
@@ -10162,10 +10693,10 @@ schedulesCommand.command("create").description("Create a new schedule").required
10162
10693
  return;
10163
10694
  }
10164
10695
  const App = () => {
10165
- const [loading, setLoading] = useState22(true);
10166
- const [success, setSuccess] = useState22(null);
10167
- const [error, setError] = useState22(null);
10168
- const [result, setResult] = useState22(null);
10696
+ const [loading, setLoading] = useState23(true);
10697
+ const [success, setSuccess] = useState23(null);
10698
+ const [error, setError] = useState23(null);
10699
+ const [result, setResult] = useState23(null);
10169
10700
  useEffect20(() => {
10170
10701
  client.post("/schedules", {
10171
10702
  flowId: options.flow,
@@ -10217,9 +10748,9 @@ function simpleMutationCommand(name, description, mutationFn, successMsg, loadin
10217
10748
  return;
10218
10749
  }
10219
10750
  const App = () => {
10220
- const [loading, setLoading] = useState22(true);
10221
- const [success, setSuccess] = useState22(null);
10222
- const [error, setError] = useState22(null);
10751
+ const [loading, setLoading] = useState23(true);
10752
+ const [success, setSuccess] = useState23(null);
10753
+ const [error, setError] = useState23(null);
10223
10754
  useEffect20(() => {
10224
10755
  mutationFn(client, id).then(() => {
10225
10756
  setSuccess(true);
@@ -10279,10 +10810,10 @@ schedulesCommand.command("delete <id>").description("Delete a schedule").option(
10279
10810
  return;
10280
10811
  }
10281
10812
  const App = () => {
10282
- const [confirmed, setConfirmed] = useState22(null);
10283
- const [loading, setLoading] = useState22(false);
10284
- const [success, setSuccess] = useState22(null);
10285
- const [error, setError] = useState22(null);
10813
+ const [confirmed, setConfirmed] = useState23(null);
10814
+ const [loading, setLoading] = useState23(false);
10815
+ const [success, setSuccess] = useState23(null);
10816
+ const [error, setError] = useState23(null);
10286
10817
  useEffect20(() => {
10287
10818
  if (confirmed !== true) return void 0;
10288
10819
  setLoading(true);
@@ -10327,16 +10858,16 @@ import { Command as Command15 } from "commander";
10327
10858
  import chalk20 from "chalk";
10328
10859
  import React16 from "react";
10329
10860
  import { render as render14 } from "ink";
10330
- import { useState as useState23, useEffect as useEffect21 } from "react";
10331
- import { Text as Text24 } from "ink";
10332
- import { readFileSync as readFileSync8 } from "fs";
10861
+ import { useState as useState24, useEffect as useEffect21 } from "react";
10862
+ import { Text as Text25 } from "ink";
10863
+ import { readFileSync as readFileSync9 } from "fs";
10333
10864
  var evalCommand = new Command15("eval").description("Manage evaluations");
10334
10865
  evalCommand.command("submit").description("Submit an eval batch").requiredOption("-f, --flow <id>", "Flow ID to evaluate").requiredOption("-r, --records <file>", "JSON file with record IDs").option("-n, --name <name>", "Eval batch name").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
10335
10866
  const apiKey = await ensureAuth();
10336
10867
  if (!apiKey) return;
10337
10868
  let recordIds;
10338
10869
  try {
10339
- const content = readFileSync8(options.records, "utf-8");
10870
+ const content = readFileSync9(options.records, "utf-8");
10340
10871
  const parsed = JSON.parse(content);
10341
10872
  recordIds = Array.isArray(parsed) ? parsed : parsed.recordIds || parsed.records || [];
10342
10873
  } catch (error) {
@@ -10372,10 +10903,10 @@ evalCommand.command("submit").description("Submit an eval batch").requiredOption
10372
10903
  return;
10373
10904
  }
10374
10905
  const App = () => {
10375
- const [loading, setLoading] = useState23(true);
10376
- const [success, setSuccess] = useState23(null);
10377
- const [error, setError] = useState23(null);
10378
- const [resultNode, setResultNode] = useState23(void 0);
10906
+ const [loading, setLoading] = useState24(true);
10907
+ const [success, setSuccess] = useState24(null);
10908
+ const [error, setError] = useState24(null);
10909
+ const [resultNode, setResultNode] = useState24(void 0);
10379
10910
  useEffect21(() => {
10380
10911
  const run = async () => {
10381
10912
  try {
@@ -10455,10 +10986,10 @@ evalCommand.command("list").description("List eval batches").option("--flow <id>
10455
10986
  return;
10456
10987
  }
10457
10988
  const App = () => {
10458
- const [loading, setLoading] = useState23(true);
10459
- const [items, setItems] = useState23(null);
10460
- const [total, setTotal] = useState23(void 0);
10461
- const [error, setError] = useState23(null);
10989
+ const [loading, setLoading] = useState24(true);
10990
+ const [items, setItems] = useState24(null);
10991
+ const [total, setTotal] = useState24(void 0);
10992
+ const [error, setError] = useState24(null);
10462
10993
  useEffect21(() => {
10463
10994
  const run = async () => {
10464
10995
  try {
@@ -10486,7 +11017,7 @@ evalCommand.command("list").description("List eval batches").option("--flow <id>
10486
11017
  const progress = b.totalRecords ? `${b.completedRecords ?? 0}/${b.totalRecords}` : "";
10487
11018
  const statusColor = b.status === "completed" ? "green" : "yellow";
10488
11019
  return React16.createElement(
10489
- Text24,
11020
+ Text25,
10490
11021
  { color: statusColor },
10491
11022
  ` ${b.id} ${name} [${b.status}] ${progress}`
10492
11023
  );
@@ -10535,10 +11066,10 @@ evalCommand.command("results <id>").description("Get eval batch results").option
10535
11066
  return;
10536
11067
  }
10537
11068
  const App = () => {
10538
- const [loading, setLoading] = useState23(true);
10539
- const [success, setSuccess] = useState23(null);
10540
- const [error, setError] = useState23(null);
10541
- const [resultNode, setResultNode] = useState23(void 0);
11069
+ const [loading, setLoading] = useState24(true);
11070
+ const [success, setSuccess] = useState24(null);
11071
+ const [error, setError] = useState24(null);
11072
+ const [resultNode, setResultNode] = useState24(void 0);
10542
11073
  useEffect21(() => {
10543
11074
  const run = async () => {
10544
11075
  try {
@@ -10599,9 +11130,9 @@ evalCommand.command("compare <groupId>").description("Compare evals in a group")
10599
11130
  return;
10600
11131
  }
10601
11132
  const App = () => {
10602
- const [loading, setLoading] = useState23(true);
10603
- const [success, setSuccess] = useState23(null);
10604
- const [error, setError] = useState23(null);
11133
+ const [loading, setLoading] = useState24(true);
11134
+ const [success, setSuccess] = useState24(null);
11135
+ const [error, setError] = useState24(null);
10605
11136
  useEffect21(() => {
10606
11137
  const run = async () => {
10607
11138
  try {
@@ -10634,8 +11165,8 @@ import { Command as Command16 } from "commander";
10634
11165
  import chalk21 from "chalk";
10635
11166
  import React17 from "react";
10636
11167
  import { render as render15 } from "ink";
10637
- import { useState as useState24, useEffect as useEffect22 } from "react";
10638
- import { Text as Text25 } from "ink";
11168
+ import { useState as useState25, useEffect as useEffect22 } from "react";
11169
+ import { Text as Text26 } from "ink";
10639
11170
  var apiKeysCommand = new Command16("api-keys").description("Manage API keys");
10640
11171
  apiKeysCommand.command("list").description("List your API keys").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
10641
11172
  const apiKey = await ensureAuth();
@@ -10673,10 +11204,10 @@ apiKeysCommand.command("list").description("List your API keys").option("--json"
10673
11204
  return;
10674
11205
  }
10675
11206
  const App = () => {
10676
- const [loading, setLoading] = useState24(true);
10677
- const [items, setItems] = useState24(null);
10678
- const [total, setTotal] = useState24(void 0);
10679
- const [error, setError] = useState24(null);
11207
+ const [loading, setLoading] = useState25(true);
11208
+ const [items, setItems] = useState25(null);
11209
+ const [total, setTotal] = useState25(void 0);
11210
+ const [error, setError] = useState25(null);
10680
11211
  useEffect22(() => {
10681
11212
  const run = async () => {
10682
11213
  try {
@@ -10702,7 +11233,7 @@ apiKeysCommand.command("list").description("List your API keys").option("--json"
10702
11233
  const k = item;
10703
11234
  const prefix = k.prefix ? ` (${k.prefix}...)` : "";
10704
11235
  const lastUsed = k.lastUsedAt ? ` last used: ${k.lastUsedAt}` : "";
10705
- return React17.createElement(Text25, null, ` ${k.id} ${k.name}${prefix}${lastUsed}`);
11236
+ return React17.createElement(Text26, null, ` ${k.id} ${k.name}${prefix}${lastUsed}`);
10706
11237
  }
10707
11238
  });
10708
11239
  };
@@ -10737,10 +11268,10 @@ apiKeysCommand.command("get <id>").description("Get API key details").option("--
10737
11268
  return;
10738
11269
  }
10739
11270
  const App = () => {
10740
- const [loading, setLoading] = useState24(true);
10741
- const [success, setSuccess] = useState24(null);
10742
- const [error, setError] = useState24(null);
10743
- const [resultNode, setResultNode] = useState24(void 0);
11271
+ const [loading, setLoading] = useState25(true);
11272
+ const [success, setSuccess] = useState25(null);
11273
+ const [error, setError] = useState25(null);
11274
+ const [resultNode, setResultNode] = useState25(void 0);
10744
11275
  useEffect22(() => {
10745
11276
  const run = async () => {
10746
11277
  try {
@@ -10806,10 +11337,10 @@ apiKeysCommand.command("create").description("Create a new API key").requiredOpt
10806
11337
  return;
10807
11338
  }
10808
11339
  const App = () => {
10809
- const [loading, setLoading] = useState24(true);
10810
- const [success, setSuccess] = useState24(null);
10811
- const [error, setError] = useState24(null);
10812
- const [resultNode, setResultNode] = useState24(void 0);
11340
+ const [loading, setLoading] = useState25(true);
11341
+ const [success, setSuccess] = useState25(null);
11342
+ const [error, setError] = useState25(null);
11343
+ const [resultNode, setResultNode] = useState25(void 0);
10813
11344
  useEffect22(() => {
10814
11345
  const run = async () => {
10815
11346
  try {
@@ -10865,9 +11396,9 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
10865
11396
  }
10866
11397
  if (options.yes) {
10867
11398
  const App = () => {
10868
- const [loading, setLoading] = useState24(true);
10869
- const [success, setSuccess] = useState24(null);
10870
- const [error, setError] = useState24(null);
11399
+ const [loading, setLoading] = useState25(true);
11400
+ const [success, setSuccess] = useState25(null);
11401
+ const [error, setError] = useState25(null);
10871
11402
  useEffect22(() => {
10872
11403
  const run = async () => {
10873
11404
  try {
@@ -10908,9 +11439,9 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
10908
11439
  });
10909
11440
  if (!confirmed) return;
10910
11441
  const DeleteApp = () => {
10911
- const [loading, setLoading] = useState24(true);
10912
- const [success, setSuccess] = useState24(null);
10913
- const [error, setError] = useState24(null);
11442
+ const [loading, setLoading] = useState25(true);
11443
+ const [success, setSuccess] = useState25(null);
11444
+ const [error, setError] = useState25(null);
10914
11445
  useEffect22(() => {
10915
11446
  const run = async () => {
10916
11447
  try {
@@ -10961,10 +11492,10 @@ apiKeysCommand.command("regenerate <id>").description("Regenerate an API key").o
10961
11492
  return;
10962
11493
  }
10963
11494
  const App = () => {
10964
- const [loading, setLoading] = useState24(true);
10965
- const [success, setSuccess] = useState24(null);
10966
- const [error, setError] = useState24(null);
10967
- const [resultNode, setResultNode] = useState24(void 0);
11495
+ const [loading, setLoading] = useState25(true);
11496
+ const [success, setSuccess] = useState25(null);
11497
+ const [error, setError] = useState25(null);
11498
+ const [resultNode, setResultNode] = useState25(void 0);
10968
11499
  useEffect22(() => {
10969
11500
  const run = async () => {
10970
11501
  try {
@@ -11017,9 +11548,9 @@ apiKeysCommand.command("analytics").description("Show API key usage analytics").
11017
11548
  return;
11018
11549
  }
11019
11550
  const App = () => {
11020
- const [loading, setLoading] = useState24(true);
11021
- const [success, setSuccess] = useState24(null);
11022
- const [error, setError] = useState24(null);
11551
+ const [loading, setLoading] = useState25(true);
11552
+ const [success, setSuccess] = useState25(null);
11553
+ const [error, setError] = useState25(null);
11023
11554
  useEffect22(() => {
11024
11555
  const run = async () => {
11025
11556
  try {
@@ -11053,8 +11584,8 @@ import { Command as Command17 } from "commander";
11053
11584
  import chalk22 from "chalk";
11054
11585
  import React18 from "react";
11055
11586
  import { render as render16 } from "ink";
11056
- import { useState as useState25, useEffect as useEffect23 } from "react";
11057
- import { Text as Text26 } from "ink";
11587
+ import { useState as useState26, useEffect as useEffect23 } from "react";
11588
+ import { Text as Text27 } from "ink";
11058
11589
  var analyticsCommand = new Command17("analytics").description("View analytics and execution results");
11059
11590
  analyticsCommand.command("stats").description("Show account statistics").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
11060
11591
  const apiKey = await ensureAuth();
@@ -11082,10 +11613,10 @@ analyticsCommand.command("stats").description("Show account statistics").option(
11082
11613
  return;
11083
11614
  }
11084
11615
  const App = () => {
11085
- const [loading, setLoading] = useState25(true);
11086
- const [success, setSuccess] = useState25(null);
11087
- const [error, setError] = useState25(null);
11088
- const [resultNode, setResultNode] = useState25(void 0);
11616
+ const [loading, setLoading] = useState26(true);
11617
+ const [success, setSuccess] = useState26(null);
11618
+ const [error, setError] = useState26(null);
11619
+ const [resultNode, setResultNode] = useState26(void 0);
11089
11620
  useEffect23(() => {
11090
11621
  const run = async () => {
11091
11622
  try {
@@ -11166,10 +11697,10 @@ analyticsCommand.command("results").description("List execution results").option
11166
11697
  return;
11167
11698
  }
11168
11699
  const App = () => {
11169
- const [loading, setLoading] = useState25(true);
11170
- const [items, setItems] = useState25(null);
11171
- const [total, setTotal] = useState25(void 0);
11172
- const [error, setError] = useState25(null);
11700
+ const [loading, setLoading] = useState26(true);
11701
+ const [items, setItems] = useState26(null);
11702
+ const [total, setTotal] = useState26(void 0);
11703
+ const [error, setError] = useState26(null);
11173
11704
  useEffect23(() => {
11174
11705
  const run = async () => {
11175
11706
  try {
@@ -11198,7 +11729,7 @@ analyticsCommand.command("results").description("List execution results").option
11198
11729
  const r = item;
11199
11730
  const statusColor = r.status === "completed" ? "green" : "red";
11200
11731
  return React18.createElement(
11201
- Text26,
11732
+ Text27,
11202
11733
  { color: statusColor },
11203
11734
  ` ${r.id} [${r.status}] flow=${r.flowId} record=${r.recordId}${r.createdAt ? ` ${r.createdAt}` : ""}`
11204
11735
  );
@@ -11215,8 +11746,8 @@ import { Command as Command18 } from "commander";
11215
11746
  import chalk23 from "chalk";
11216
11747
  import React19 from "react";
11217
11748
  import { render as render17 } from "ink";
11218
- import { useState as useState26, useEffect as useEffect24 } from "react";
11219
- import open4 from "open";
11749
+ import { useState as useState27, useEffect as useEffect24 } from "react";
11750
+ import open5 from "open";
11220
11751
  var billingCommand = new Command18("billing").description("View billing and subscription info");
11221
11752
  billingCommand.command("status").description("Show current plan and usage").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
11222
11753
  const apiKey = await ensureAuth();
@@ -11261,10 +11792,10 @@ billingCommand.command("status").description("Show current plan and usage").opti
11261
11792
  return;
11262
11793
  }
11263
11794
  const App = () => {
11264
- const [loading, setLoading] = useState26(true);
11265
- const [success, setSuccess] = useState26(null);
11266
- const [error, setError] = useState26(null);
11267
- const [resultNode, setResultNode] = useState26(void 0);
11795
+ const [loading, setLoading] = useState27(true);
11796
+ const [success, setSuccess] = useState27(null);
11797
+ const [error, setError] = useState27(null);
11798
+ const [resultNode, setResultNode] = useState27(void 0);
11268
11799
  useEffect24(() => {
11269
11800
  const run = async () => {
11270
11801
  try {
@@ -11319,7 +11850,7 @@ billingCommand.command("portal").description("Open the billing portal in your br
11319
11850
  if (data.url) {
11320
11851
  console.log("Opening billing portal...");
11321
11852
  console.log(data.url);
11322
- await open4(data.url);
11853
+ await open5(data.url);
11323
11854
  } else {
11324
11855
  console.log("No portal URL returned. You may need to set up billing first.");
11325
11856
  }
@@ -11332,16 +11863,16 @@ billingCommand.command("portal").description("Open the billing portal in your br
11332
11863
  return;
11333
11864
  }
11334
11865
  const App = () => {
11335
- const [loading, setLoading] = useState26(true);
11336
- const [success, setSuccess] = useState26(null);
11337
- const [error, setError] = useState26(null);
11338
- const [msg, setMsg] = useState26("Opening billing portal...");
11866
+ const [loading, setLoading] = useState27(true);
11867
+ const [success, setSuccess] = useState27(null);
11868
+ const [error, setError] = useState27(null);
11869
+ const [msg, setMsg] = useState27("Opening billing portal...");
11339
11870
  useEffect24(() => {
11340
11871
  const run = async () => {
11341
11872
  try {
11342
11873
  const data = await client.post("/billing/portal");
11343
11874
  if (data.url) {
11344
- await open4(data.url);
11875
+ await open5(data.url);
11345
11876
  setMsg("Billing portal opened in browser");
11346
11877
  setSuccess(true);
11347
11878
  } else {
@@ -11385,9 +11916,9 @@ billingCommand.command("refresh").description("Refresh plan data from billing pr
11385
11916
  return;
11386
11917
  }
11387
11918
  const App = () => {
11388
- const [loading, setLoading] = useState26(true);
11389
- const [success, setSuccess] = useState26(null);
11390
- const [error, setError] = useState26(null);
11919
+ const [loading, setLoading] = useState27(true);
11920
+ const [success, setSuccess] = useState27(null);
11921
+ const [error, setError] = useState27(null);
11391
11922
  useEffect24(() => {
11392
11923
  const run = async () => {
11393
11924
  try {
@@ -11419,8 +11950,8 @@ import { Command as Command19 } from "commander";
11419
11950
  import chalk24 from "chalk";
11420
11951
  import React20 from "react";
11421
11952
  import { render as render18 } from "ink";
11422
- import { useState as useState27, useEffect as useEffect25 } from "react";
11423
- import { Text as Text27 } from "ink";
11953
+ import { useState as useState28, useEffect as useEffect25 } from "react";
11954
+ import { Text as Text28 } from "ink";
11424
11955
  var flowVersionsCommand = new Command19("flow-versions").description(
11425
11956
  "Manage flow versions"
11426
11957
  );
@@ -11456,9 +11987,9 @@ flowVersionsCommand.command("list <flowId>").description("List all versions for
11456
11987
  return;
11457
11988
  }
11458
11989
  const App = () => {
11459
- const [loading, setLoading] = useState27(true);
11460
- const [items, setItems] = useState27(null);
11461
- const [error, setError] = useState27(null);
11990
+ const [loading, setLoading] = useState28(true);
11991
+ const [items, setItems] = useState28(null);
11992
+ const [error, setError] = useState28(null);
11462
11993
  useEffect25(() => {
11463
11994
  const run = async () => {
11464
11995
  try {
@@ -11482,7 +12013,7 @@ flowVersionsCommand.command("list <flowId>").description("List all versions for
11482
12013
  const v = item;
11483
12014
  const publishedTag = v.published ? " [published]" : "";
11484
12015
  const versionNum = v.version !== void 0 ? `v${v.version}` : v.id;
11485
- return React20.createElement(Text27, null, ` ${v.id} ${versionNum}${publishedTag}${v.createdAt ? ` ${v.createdAt}` : ""}`);
12016
+ return React20.createElement(Text28, null, ` ${v.id} ${versionNum}${publishedTag}${v.createdAt ? ` ${v.createdAt}` : ""}`);
11486
12017
  }
11487
12018
  });
11488
12019
  };
@@ -11517,10 +12048,10 @@ flowVersionsCommand.command("get <flowId> <versionId>").description("Get a speci
11517
12048
  return;
11518
12049
  }
11519
12050
  const App = () => {
11520
- const [loading, setLoading] = useState27(true);
11521
- const [success, setSuccess] = useState27(null);
11522
- const [error, setError] = useState27(null);
11523
- const [resultNode, setResultNode] = useState27(void 0);
12051
+ const [loading, setLoading] = useState28(true);
12052
+ const [success, setSuccess] = useState28(null);
12053
+ const [error, setError] = useState28(null);
12054
+ const [resultNode, setResultNode] = useState28(void 0);
11524
12055
  useEffect25(() => {
11525
12056
  const run = async () => {
11526
12057
  try {
@@ -11583,10 +12114,10 @@ flowVersionsCommand.command("published <flowId>").description("Get the published
11583
12114
  return;
11584
12115
  }
11585
12116
  const App = () => {
11586
- const [loading, setLoading] = useState27(true);
11587
- const [success, setSuccess] = useState27(null);
11588
- const [error, setError] = useState27(null);
11589
- const [resultNode, setResultNode] = useState27(void 0);
12117
+ const [loading, setLoading] = useState28(true);
12118
+ const [success, setSuccess] = useState28(null);
12119
+ const [error, setError] = useState28(null);
12120
+ const [resultNode, setResultNode] = useState28(void 0);
11590
12121
  useEffect25(() => {
11591
12122
  const run = async () => {
11592
12123
  try {
@@ -11640,9 +12171,9 @@ flowVersionsCommand.command("publish <flowId>").description("Publish a version")
11640
12171
  return;
11641
12172
  }
11642
12173
  const App = () => {
11643
- const [loading, setLoading] = useState27(true);
11644
- const [success, setSuccess] = useState27(null);
11645
- const [error, setError] = useState27(null);
12174
+ const [loading, setLoading] = useState28(true);
12175
+ const [success, setSuccess] = useState28(null);
12176
+ const [error, setError] = useState28(null);
11646
12177
  useEffect25(() => {
11647
12178
  const run = async () => {
11648
12179
  try {
@@ -11677,7 +12208,7 @@ loadEnv();
11677
12208
  function getPackageVersion() {
11678
12209
  try {
11679
12210
  const pkgPath = join6(dirname4(fileURLToPath(import.meta.url)), "..", "package.json");
11680
- const pkg = JSON.parse(readFileSync9(pkgPath, "utf-8"));
12211
+ const pkg = JSON.parse(readFileSync10(pkgPath, "utf-8"));
11681
12212
  return pkg.version || "0.0.0";
11682
12213
  } catch {
11683
12214
  return "0.0.0";