@runtypelabs/cli 2.16.20 → 2.17.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.
Files changed (2) hide show
  1. package/dist/index.js +1562 -755
  2. package/package.json +5 -5
package/dist/index.js CHANGED
@@ -137,9 +137,9 @@ import chalk41 from "chalk";
137
137
  // src/lib/load-env.ts
138
138
  import { readFileSync } from "fs";
139
139
  import { resolve } from "path";
140
- function loadEnv(path16 = resolve(process.cwd(), ".env")) {
140
+ function loadEnv(path17 = resolve(process.cwd(), ".env")) {
141
141
  try {
142
- const content = readFileSync(path16, "utf8").replace(/\r\n?/g, "\n");
142
+ const content = readFileSync(path17, "utf8").replace(/\r\n?/g, "\n");
143
143
  for (const line of content.split("\n")) {
144
144
  if (!line.trim() || line.trimStart().startsWith("#")) continue;
145
145
  const match = line.match(/^\s*([\w.-]+)\s*=\s*(.*)?\s*$/);
@@ -1381,10 +1381,10 @@ function mergeDefs(...defs) {
1381
1381
  function cloneDef(schema) {
1382
1382
  return mergeDefs(schema._zod.def);
1383
1383
  }
1384
- function getElementAtPath(obj, path16) {
1385
- if (!path16)
1384
+ function getElementAtPath(obj, path17) {
1385
+ if (!path17)
1386
1386
  return obj;
1387
- return path16.reduce((acc, key) => acc?.[key], obj);
1387
+ return path17.reduce((acc, key) => acc?.[key], obj);
1388
1388
  }
1389
1389
  function promiseAllObject(promisesObj) {
1390
1390
  const keys = Object.keys(promisesObj);
@@ -1793,11 +1793,11 @@ function explicitlyAborted(x2, startIndex = 0) {
1793
1793
  }
1794
1794
  return false;
1795
1795
  }
1796
- function prefixIssues(path16, issues) {
1796
+ function prefixIssues(path17, issues) {
1797
1797
  return issues.map((iss) => {
1798
1798
  var _a3;
1799
1799
  (_a3 = iss).path ?? (_a3.path = []);
1800
- iss.path.unshift(path16);
1800
+ iss.path.unshift(path17);
1801
1801
  return iss;
1802
1802
  });
1803
1803
  }
@@ -1944,16 +1944,16 @@ function flattenError(error51, mapper = (issue2) => issue2.message) {
1944
1944
  }
1945
1945
  function formatError(error51, mapper = (issue2) => issue2.message) {
1946
1946
  const fieldErrors = { _errors: [] };
1947
- const processError = (error52, path16 = []) => {
1947
+ const processError = (error52, path17 = []) => {
1948
1948
  for (const issue2 of error52.issues) {
1949
1949
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1950
- issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
1950
+ issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1951
1951
  } else if (issue2.code === "invalid_key") {
1952
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
1952
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1953
1953
  } else if (issue2.code === "invalid_element") {
1954
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
1954
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1955
1955
  } else {
1956
- const fullpath = [...path16, ...issue2.path];
1956
+ const fullpath = [...path17, ...issue2.path];
1957
1957
  if (fullpath.length === 0) {
1958
1958
  fieldErrors._errors.push(mapper(issue2));
1959
1959
  } else {
@@ -1980,17 +1980,17 @@ function formatError(error51, mapper = (issue2) => issue2.message) {
1980
1980
  }
1981
1981
  function treeifyError(error51, mapper = (issue2) => issue2.message) {
1982
1982
  const result = { errors: [] };
1983
- const processError = (error52, path16 = []) => {
1983
+ const processError = (error52, path17 = []) => {
1984
1984
  var _a3, _b;
1985
1985
  for (const issue2 of error52.issues) {
1986
1986
  if (issue2.code === "invalid_union" && issue2.errors.length) {
1987
- issue2.errors.map((issues) => processError({ issues }, [...path16, ...issue2.path]));
1987
+ issue2.errors.map((issues) => processError({ issues }, [...path17, ...issue2.path]));
1988
1988
  } else if (issue2.code === "invalid_key") {
1989
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
1989
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1990
1990
  } else if (issue2.code === "invalid_element") {
1991
- processError({ issues: issue2.issues }, [...path16, ...issue2.path]);
1991
+ processError({ issues: issue2.issues }, [...path17, ...issue2.path]);
1992
1992
  } else {
1993
- const fullpath = [...path16, ...issue2.path];
1993
+ const fullpath = [...path17, ...issue2.path];
1994
1994
  if (fullpath.length === 0) {
1995
1995
  result.errors.push(mapper(issue2));
1996
1996
  continue;
@@ -2022,8 +2022,8 @@ function treeifyError(error51, mapper = (issue2) => issue2.message) {
2022
2022
  }
2023
2023
  function toDotPath(_path) {
2024
2024
  const segs = [];
2025
- const path16 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2026
- for (const seg of path16) {
2025
+ const path17 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
2026
+ for (const seg of path17) {
2027
2027
  if (typeof seg === "number")
2028
2028
  segs.push(`[${seg}]`);
2029
2029
  else if (typeof seg === "symbol")
@@ -14709,13 +14709,13 @@ function resolveRef(ref, ctx) {
14709
14709
  if (!ref.startsWith("#")) {
14710
14710
  throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
14711
14711
  }
14712
- const path16 = ref.slice(1).split("/").filter(Boolean);
14713
- if (path16.length === 0) {
14712
+ const path17 = ref.slice(1).split("/").filter(Boolean);
14713
+ if (path17.length === 0) {
14714
14714
  return ctx.rootSchema;
14715
14715
  }
14716
14716
  const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
14717
- if (path16[0] === defsKey) {
14718
- const key = path16[1];
14717
+ if (path17[0] === defsKey) {
14718
+ const key = path17[1];
14719
14719
  if (!key || !ctx.defs[key]) {
14720
14720
  throw new Error(`Reference not found: ${ref}`);
14721
14721
  }
@@ -15160,8 +15160,8 @@ var apiRoutingDocSchema = external_exports.object({
15160
15160
  });
15161
15161
 
15162
15162
  // ../shared/dist/chunk-3V2W6XMX.mjs
15163
- function getNestedValue(obj, path16) {
15164
- let normalizedPath = path16;
15163
+ function getNestedValue(obj, path17) {
15164
+ let normalizedPath = path17;
15165
15165
  normalizedPath = normalizedPath.replace(/^\$\.?/, "");
15166
15166
  normalizedPath = normalizedPath.replace(/\[(\d+)\]/g, ".$1");
15167
15167
  normalizedPath = normalizedPath.replace(/\[['"]([^'"\]]+)['"]\]/g, ".$1");
@@ -36258,8 +36258,8 @@ var FLAT_ADVANCED_CONFIG_KEYS = {
36258
36258
  var FLAT_ADVANCED_CONFIG_KEY_LIST = Object.keys(
36259
36259
  FLAT_ADVANCED_CONFIG_KEYS
36260
36260
  );
36261
- function createIssue(severity, code, message, path16, suggestedFix) {
36262
- return { code, message, path: path16, severity, ...suggestedFix ? { suggestedFix } : {} };
36261
+ function createIssue(severity, code, message, path17, suggestedFix) {
36262
+ return { code, message, path: path17, severity, ...suggestedFix ? { suggestedFix } : {} };
36263
36263
  }
36264
36264
  function emptyResult() {
36265
36265
  return { valid: true, errors: [], warnings: [], recommendations: [] };
@@ -36965,16 +36965,16 @@ var fullProductObjectTemplateSchema = external_exports.object({
36965
36965
  });
36966
36966
  var FLOW_PREFIX = "flow:";
36967
36967
  var SECRET_PREFIX = "secret:";
36968
- function collectStringLeafPaths(value, path16 = []) {
36968
+ function collectStringLeafPaths(value, path17 = []) {
36969
36969
  if (typeof value === "string") {
36970
- return [{ path: path16, value }];
36970
+ return [{ path: path17, value }];
36971
36971
  }
36972
36972
  if (Array.isArray(value)) {
36973
- return value.flatMap((item, index) => collectStringLeafPaths(item, [...path16, String(index)]));
36973
+ return value.flatMap((item, index) => collectStringLeafPaths(item, [...path17, String(index)]));
36974
36974
  }
36975
36975
  if (value && typeof value === "object") {
36976
36976
  return Object.entries(value).flatMap(
36977
- ([key, nestedValue]) => collectStringLeafPaths(nestedValue, [...path16, key])
36977
+ ([key, nestedValue]) => collectStringLeafPaths(nestedValue, [...path17, key])
36978
36978
  );
36979
36979
  }
36980
36980
  return [];
@@ -38773,7 +38773,7 @@ function buildDashboardUrl(opts) {
38773
38773
  while (base.endsWith("/")) {
38774
38774
  base = base.slice(0, -1);
38775
38775
  }
38776
- const path16 = opts.path.startsWith("/") ? opts.path : `/${opts.path}`;
38776
+ const path17 = opts.path.startsWith("/") ? opts.path : `/${opts.path}`;
38777
38777
  const params = new URLSearchParams();
38778
38778
  if (isValidAccountId(opts.account)) {
38779
38779
  params.set(ACCOUNT_QUERY_PARAM, opts.account);
@@ -38786,7 +38786,7 @@ function buildDashboardUrl(opts) {
38786
38786
  }
38787
38787
  }
38788
38788
  const qs = params.toString();
38789
- return qs ? `${base}${path16}?${qs}` : `${base}${path16}`;
38789
+ return qs ? `${base}${path17}?${qs}` : `${base}${path17}`;
38790
38790
  }
38791
38791
  function parseAccountId(value) {
38792
38792
  if (!value) return null;
@@ -39112,6 +39112,48 @@ var SANDBOX_TTL_OPTIONS = [
39112
39112
  { label: "2 hours", value: 2 * 60 * 60 },
39113
39113
  { label: "Unlimited", value: null }
39114
39114
  ];
39115
+ var APP_MANIFEST_LIMITS = {
39116
+ nameMaxLength: 255,
39117
+ maxFlows: 20,
39118
+ maxAgents: 20,
39119
+ maxDataNamespaces: 20,
39120
+ namespaceMaxLength: 64
39121
+ };
39122
+ var APP_DATA_NAMESPACE_PATTERN = /^[a-z][a-z0-9_]*$/;
39123
+ var appDataGrantSchema = external_exports.object({
39124
+ namespace: external_exports.string().max(APP_MANIFEST_LIMITS.namespaceMaxLength).regex(
39125
+ APP_DATA_NAMESPACE_PATTERN,
39126
+ "Namespace must be a lowercase slug (letters, digits, underscores; starting with a letter)"
39127
+ ),
39128
+ access: external_exports.enum(["read", "read-write"])
39129
+ });
39130
+ var appManifestSchema = external_exports.object({
39131
+ name: external_exports.string().min(1).max(APP_MANIFEST_LIMITS.nameMaxLength),
39132
+ description: external_exports.string().max(2e3).optional(),
39133
+ capabilities: external_exports.object({
39134
+ flows: external_exports.array(external_exports.string()).max(APP_MANIFEST_LIMITS.maxFlows).default([]),
39135
+ agents: external_exports.array(external_exports.string()).max(APP_MANIFEST_LIMITS.maxAgents).default([])
39136
+ }).strict().default({ flows: [], agents: [] }),
39137
+ data: external_exports.array(appDataGrantSchema).max(APP_MANIFEST_LIMITS.maxDataNamespaces).default([]),
39138
+ auth: external_exports.enum(["none", "optional", "required"]).default("none")
39139
+ }).strict();
39140
+ var appRoutingDocSchema = external_exports.object({
39141
+ appId: external_exports.string(),
39142
+ activeVersionId: external_exports.string(),
39143
+ visibility: external_exports.enum(["public", "unlisted"]),
39144
+ status: external_exports.enum(["active", "suspended"]),
39145
+ mode: external_exports.enum(["static", "worker"]),
39146
+ /** R2 prefix the active version's files live under, e.g. `apps/{appId}/{versionId}/`. */
39147
+ r2Prefix: external_exports.string(),
39148
+ /** Public boot config the edge injects as `window.__RUNTYPE_APP__` (no secrets). */
39149
+ bootConfig: external_exports.object({
39150
+ appId: external_exports.string(),
39151
+ versionId: external_exports.string(),
39152
+ apiUrl: external_exports.string(),
39153
+ clientToken: external_exports.string().nullable()
39154
+ }),
39155
+ updatedAt: external_exports.string()
39156
+ });
39115
39157
 
39116
39158
  // src/config/env.ts
39117
39159
  function getApiUrl() {
@@ -39195,7 +39237,7 @@ var isAuthMeResponse = (value) => {
39195
39237
  return false;
39196
39238
  }
39197
39239
  const record2 = value;
39198
- return typeof record2.user_id === "string";
39240
+ return typeof record2.userId === "string";
39199
39241
  };
39200
39242
  var ApiKeyManager = class {
39201
39243
  /**
@@ -39212,7 +39254,7 @@ var ApiKeyManager = class {
39212
39254
  data = await client.post("/auth/cli-token");
39213
39255
  } catch (error51) {
39214
39256
  const message = error51 instanceof Error ? error51.message : String(error51);
39215
- throw new Error(`Authentication failed: ${message}`);
39257
+ throw new Error(`Authentication failed: ${message}`, { cause: error51 });
39216
39258
  }
39217
39259
  if (!isCliTokenResponse(data)) {
39218
39260
  throw new Error("Invalid authentication response format");
@@ -39229,7 +39271,7 @@ var ApiKeyManager = class {
39229
39271
  async validateApiKey(apiKey, apiUrl) {
39230
39272
  const client = createCliClient(apiKey, apiUrl);
39231
39273
  try {
39232
- await client.get("/auth/me");
39274
+ await client.get("/users/profile");
39233
39275
  return true;
39234
39276
  } catch (error51) {
39235
39277
  if (error51 instanceof RuntypeApiError) {
@@ -39584,16 +39626,13 @@ async function loginAction(options) {
39584
39626
  const userData = await apiKeyManager.getCurrentUser(options.apiKey, options.apiUrl);
39585
39627
  await store.saveCredentials({
39586
39628
  apiKey: options.apiKey,
39587
- userId: userData.user_id,
39588
- // @snake-case-ok: API auth/me response
39589
- orgId: userData.org_id ?? void 0,
39590
- // @snake-case-ok: API auth/me response
39629
+ userId: userData.userId,
39630
+ orgId: userData.orgId ?? void 0,
39591
39631
  apiUrl: options.apiUrl || getApiUrl()
39592
39632
  });
39593
39633
  console.log(
39594
39634
  JSON.stringify(
39595
- { status: "authenticated", userId: userData.user_id },
39596
- // @snake-case-ok: API auth/me response
39635
+ { status: "authenticated", userId: userData.userId },
39597
39636
  null,
39598
39637
  2
39599
39638
  )
@@ -39624,13 +39663,11 @@ async function loginAction(options) {
39624
39663
  const userData = await apiKeyManager.getCurrentUser(options.apiKey, options.apiUrl);
39625
39664
  await store.saveCredentials({
39626
39665
  apiKey: options.apiKey,
39627
- userId: userData.user_id,
39628
- // @snake-case-ok: API auth/me response
39629
- orgId: userData.org_id ?? void 0,
39630
- // @snake-case-ok: API auth/me response
39666
+ userId: userData.userId,
39667
+ orgId: userData.orgId ?? void 0,
39631
39668
  apiUrl: options.apiUrl || getApiUrl()
39632
39669
  });
39633
- setUserId(userData.user_id);
39670
+ setUserId(userData.userId);
39634
39671
  setSuccess(true);
39635
39672
  setLoading(false);
39636
39673
  } catch (err) {
@@ -39887,10 +39924,8 @@ authCommand.command("whoami").description("Display current user information").op
39887
39924
  console.log(
39888
39925
  JSON.stringify(
39889
39926
  {
39890
- // @snake-case-ok: API auth/me response uses snake_case
39891
- userId: user.user_id,
39892
- // @snake-case-ok: API auth/me response uses snake_case
39893
- orgId: user.org_id,
39927
+ userId: user.userId,
39928
+ orgId: user.orgId,
39894
39929
  apiUrl: credentials.apiUrl || getApiUrl(),
39895
39930
  billing: billingInfo
39896
39931
  },
@@ -39917,10 +39952,8 @@ authCommand.command("whoami").description("Display current user information").op
39917
39952
  const user = await apiKeyManager.getCurrentUser(credentials.apiKey, credentials.apiUrl);
39918
39953
  const billingInfo = await getBillingInfo(credentials.apiKey, credentials.apiUrl);
39919
39954
  const fields = [
39920
- // @snake-case-ok: API auth/me response uses snake_case
39921
- { label: "User ID", value: user.user_id },
39922
- // @snake-case-ok: API auth/me response uses snake_case
39923
- { label: "Organization", value: user.org_id || "Personal" },
39955
+ { label: "User ID", value: user.userId },
39956
+ { label: "Organization", value: user.orgId || "Personal" },
39924
39957
  { label: "API Key", value: credentials.apiKey.substring(0, 10) + "..." },
39925
39958
  { label: "API URL", value: credentials.apiUrl || getApiUrl() },
39926
39959
  { label: "Created", value: credentials.createdAt },
@@ -39985,13 +40018,13 @@ function parseJsonObject(raw, label) {
39985
40018
  }
39986
40019
  return parsed;
39987
40020
  }
39988
- function readJsonFile(path16, opts = {}) {
40021
+ function readJsonFile(path17, opts = {}) {
39989
40022
  const label = opts.label ?? "file";
39990
40023
  let raw;
39991
40024
  try {
39992
- raw = readFileSync3(path16, "utf-8");
40025
+ raw = readFileSync3(path17, "utf-8");
39993
40026
  } catch {
39994
- console.error(chalk2.red(`Failed to read ${label}: ${path16}`));
40027
+ console.error(chalk2.red(`Failed to read ${label}: ${path17}`));
39995
40028
  process.exit(1);
39996
40029
  }
39997
40030
  const obj = parseJsonObject(raw, label);
@@ -44727,20 +44760,16 @@ var initCommand = new Command13("init").description("Set up Runtype CLI with gui
44727
44760
  const store = new CredentialStore();
44728
44761
  await store.saveCredentials({
44729
44762
  apiKey: options.apiKey,
44730
- // @snake-case-ok: API auth/me response uses snake_case
44731
- userId: userData.user_id,
44732
- // @snake-case-ok: API auth/me response uses snake_case
44733
- orgId: userData.org_id ?? void 0,
44763
+ userId: userData.userId,
44764
+ orgId: userData.orgId ?? void 0,
44734
44765
  apiUrl: options.apiUrl || getApiUrl()
44735
44766
  });
44736
44767
  console.log(
44737
44768
  JSON.stringify(
44738
44769
  {
44739
44770
  status: "authenticated",
44740
- // @snake-case-ok: API auth/me response uses snake_case
44741
- userId: userData.user_id,
44742
- // @snake-case-ok: API auth/me response uses snake_case
44743
- orgId: userData.org_id
44771
+ userId: userData.userId,
44772
+ orgId: userData.orgId
44744
44773
  },
44745
44774
  null,
44746
44775
  2
@@ -44773,10 +44802,8 @@ var initCommand = new Command13("init").description("Set up Runtype CLI with gui
44773
44802
  const store = new CredentialStore();
44774
44803
  await store.saveCredentials({
44775
44804
  apiKey: options.apiKey,
44776
- // @snake-case-ok: API auth/me response uses snake_case
44777
- userId: userData.user_id,
44778
- // @snake-case-ok: API auth/me response uses snake_case
44779
- orgId: userData.org_id ?? void 0,
44805
+ userId: userData.userId,
44806
+ orgId: userData.orgId ?? void 0,
44780
44807
  apiUrl: options.apiUrl || getApiUrl()
44781
44808
  });
44782
44809
  } catch (error51) {
@@ -45224,7 +45251,7 @@ import { Command as Command17 } from "commander";
45224
45251
  import chalk24 from "chalk";
45225
45252
  import React16 from "react";
45226
45253
  import { render as render16 } from "ink";
45227
- import { useState as useState30, useEffect as useEffect27 } from "react";
45254
+ import { useState as useState33, useEffect as useEffect27 } from "react";
45228
45255
  import { processStream as processStream4 } from "@runtypelabs/sdk";
45229
45256
 
45230
45257
  // src/commands/agents-task.ts
@@ -45234,13 +45261,13 @@ import { render as render15 } from "ink";
45234
45261
  import React15 from "react";
45235
45262
 
45236
45263
  // src/ink/marathon/MarathonApp.tsx
45237
- import { useState as useState28, useEffect as useEffect25, useRef as useRef9, useCallback as useCallback8, useMemo as useMemo11 } from "react";
45264
+ import { useState as useState31, useEffect as useEffect25, useRef as useRef9, useCallback as useCallback8, useMemo as useMemo11 } from "react";
45238
45265
  import { execSync } from "child_process";
45239
- import * as fs4 from "fs";
45240
- import * as path4 from "path";
45266
+ import * as fs5 from "fs";
45267
+ import * as path5 from "path";
45241
45268
  import open4 from "open";
45242
- import { Box as Box28, Text as Text29, useApp as useApp4, useInput as useInput11, useStdout as useStdout5 } from "ink";
45243
- import { StatusBar, theme as theme31 } from "@runtypelabs/ink-components";
45269
+ import { Box as Box31, Text as Text32, useApp as useApp4, useInput as useInput14, useStdout as useStdout5 } from "ink";
45270
+ import { StatusBar, theme as theme34 } from "@runtypelabs/ink-components";
45244
45271
 
45245
45272
  // src/ink/marathon/useMarathonStream.ts
45246
45273
  import { useState as useState16, useRef as useRef3, useMemo, useCallback as useCallback2 } from "react";
@@ -46290,10 +46317,10 @@ function SessionHeader({
46290
46317
  borderSegments(infoSegments, infoVisualWidth, rowIdx++)
46291
46318
  ];
46292
46319
  if (previewUrl) {
46293
- const previewText = ` Preview: ${previewUrl}`;
46320
+ const previewText2 = ` Preview: ${previewUrl}`;
46294
46321
  rows.push(borderSegments(
46295
- [{ text: previewText, color: theme9.accent }],
46296
- previewText.length,
46322
+ [{ text: previewText2, color: theme9.accent }],
46323
+ previewText2.length,
46297
46324
  rowIdx++
46298
46325
  ));
46299
46326
  }
@@ -47454,12 +47481,19 @@ var CHECKPOINT_COMMANDS = [
47454
47481
  { key: "/status", desc: "Show subtask completion" },
47455
47482
  { key: "/revert <file>", desc: "Restore file from checkpoint" },
47456
47483
  { key: "/reflect", desc: "Reassess approach" },
47484
+ { key: "/tree", desc: "Browse session branches, switch head" },
47485
+ { key: "/fork", desc: "Branch from an earlier message" },
47457
47486
  { key: "/copy", desc: "Copy session JSON" },
47458
47487
  { key: "/copy-trimmed", desc: "Copy JSON with large payloads trimmed" },
47459
47488
  { key: "/open", desc: "Open state file" },
47460
47489
  { key: "/stop", desc: "Stop the marathon" },
47461
47490
  { key: "/help", desc: "Toggle this help dialog" }
47462
47491
  ];
47492
+ var STEERING_SHORTCUTS = [
47493
+ { key: "Enter", desc: "Queue a steering message while the agent works" },
47494
+ { key: "Tab", desc: "Toggle delivery: next turn / after all work" },
47495
+ { key: "Esc", desc: "Close the composer (keeps your draft)" }
47496
+ ];
47463
47497
  function buildLines(isCheckpoint) {
47464
47498
  const lines = [];
47465
47499
  const sections = [
@@ -47468,6 +47502,7 @@ function buildLines(isCheckpoint) {
47468
47502
  { title: "Reasoning", items: REASONING_SHORTCUTS },
47469
47503
  { title: "Events", items: EVENTS_SHORTCUTS },
47470
47504
  { title: "Files", items: FILES_SHORTCUTS },
47505
+ { title: "Steering (while the agent works)", items: STEERING_SHORTCUTS },
47471
47506
  ...isCheckpoint ? [{ title: "Checkpoint Commands", items: CHECKPOINT_COMMANDS }] : []
47472
47507
  ];
47473
47508
  for (let s = 0; s < sections.length; s++) {
@@ -48146,9 +48181,354 @@ function readSessionEventLog(stateFilePath2, sessionIndex) {
48146
48181
  return events;
48147
48182
  }
48148
48183
 
48184
+ // src/marathon/session-log.ts
48185
+ import * as fs4 from "fs";
48186
+ import * as path4 from "path";
48187
+ import { randomUUID } from "crypto";
48188
+ var TREE_LOG_FORMAT_VERSION = 1;
48189
+ function treeLogPathForStateFile(stateFilePath2) {
48190
+ return `${stateFilePath2.replace(/\.json$/, "")}.tree.jsonl`;
48191
+ }
48192
+ function isTreeLogEntry(value) {
48193
+ if (typeof value !== "object" || value === null) return false;
48194
+ const record2 = value;
48195
+ return record2.v === TREE_LOG_FORMAT_VERSION && typeof record2.id === "string" && (record2.parentId === null || typeof record2.parentId === "string") && typeof record2.ts === "string" && (record2.type === "meta" || record2.type === "delta" || record2.type === "fork" || record2.type === "head") && typeof record2.payload === "object" && record2.payload !== null;
48196
+ }
48197
+ function loadTreeLog(filePath) {
48198
+ let raw;
48199
+ try {
48200
+ raw = fs4.readFileSync(filePath, "utf-8");
48201
+ } catch {
48202
+ return null;
48203
+ }
48204
+ const entries = [];
48205
+ const byId = /* @__PURE__ */ new Map();
48206
+ let headId = null;
48207
+ for (const line of raw.split("\n")) {
48208
+ if (!line.trim()) continue;
48209
+ let parsed;
48210
+ try {
48211
+ parsed = JSON.parse(line);
48212
+ } catch {
48213
+ continue;
48214
+ }
48215
+ if (!isTreeLogEntry(parsed)) continue;
48216
+ if (parsed.parentId !== null && !byId.has(parsed.parentId)) continue;
48217
+ if (parsed.type === "head") {
48218
+ if (byId.has(parsed.payload.headId)) {
48219
+ entries.push(parsed);
48220
+ headId = parsed.payload.headId;
48221
+ }
48222
+ continue;
48223
+ }
48224
+ entries.push(parsed);
48225
+ byId.set(parsed.id, parsed);
48226
+ headId = parsed.id;
48227
+ }
48228
+ if (entries.length === 0) return null;
48229
+ return { filePath, entries, byId, headId };
48230
+ }
48231
+ function appendLine(log, entry) {
48232
+ fs4.mkdirSync(path4.dirname(log.filePath), { recursive: true });
48233
+ fs4.appendFileSync(log.filePath, JSON.stringify(entry) + "\n");
48234
+ log.entries.push(entry);
48235
+ if (entry.type !== "head") {
48236
+ log.byId.set(entry.id, entry);
48237
+ log.headId = entry.id;
48238
+ } else {
48239
+ log.headId = entry.payload.headId;
48240
+ }
48241
+ }
48242
+ function newEntryId() {
48243
+ return `e_${randomUUID()}`;
48244
+ }
48245
+ function createTreeLog(filePath, meta3) {
48246
+ const log = { filePath, entries: [], byId: /* @__PURE__ */ new Map(), headId: null };
48247
+ appendLine(log, {
48248
+ v: TREE_LOG_FORMAT_VERSION,
48249
+ id: newEntryId(),
48250
+ parentId: null,
48251
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
48252
+ type: "meta",
48253
+ payload: meta3
48254
+ });
48255
+ return log;
48256
+ }
48257
+ function appendDelta(log, payload) {
48258
+ const entry = {
48259
+ v: TREE_LOG_FORMAT_VERSION,
48260
+ id: newEntryId(),
48261
+ parentId: log.headId,
48262
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
48263
+ type: "delta",
48264
+ payload
48265
+ };
48266
+ appendLine(log, entry);
48267
+ return entry;
48268
+ }
48269
+ function appendFork(log, fromEntryId, payload) {
48270
+ if (!log.byId.has(fromEntryId)) {
48271
+ throw new Error(`Cannot fork from unknown entry ${fromEntryId}`);
48272
+ }
48273
+ const entry = {
48274
+ v: TREE_LOG_FORMAT_VERSION,
48275
+ id: newEntryId(),
48276
+ parentId: fromEntryId,
48277
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
48278
+ type: "fork",
48279
+ payload
48280
+ };
48281
+ appendLine(log, entry);
48282
+ return entry;
48283
+ }
48284
+ function setHead(log, entryId) {
48285
+ if (!log.byId.has(entryId)) {
48286
+ throw new Error(`Cannot set head to unknown entry ${entryId}`);
48287
+ }
48288
+ appendLine(log, {
48289
+ v: TREE_LOG_FORMAT_VERSION,
48290
+ id: newEntryId(),
48291
+ parentId: null,
48292
+ ts: (/* @__PURE__ */ new Date()).toISOString(),
48293
+ type: "head",
48294
+ payload: { headId: entryId }
48295
+ });
48296
+ }
48297
+ function sameMessage(left, right) {
48298
+ if (left === right) return true;
48299
+ if (left === void 0 || right === void 0) return false;
48300
+ return JSON.stringify(left) === JSON.stringify(right);
48301
+ }
48302
+ function computeMessagesDelta(previous, next) {
48303
+ if (next.length < previous.length) {
48304
+ return { replaceAll: next.map((message) => structuredClone(message)) };
48305
+ }
48306
+ const mutated = [];
48307
+ for (let index = 0; index < previous.length; index++) {
48308
+ if (!sameMessage(previous[index], next[index])) {
48309
+ mutated.push({ index, message: structuredClone(next[index]) });
48310
+ }
48311
+ }
48312
+ if (previous.length > 0 && mutated.length > previous.length / 2) {
48313
+ return { replaceAll: next.map((message) => structuredClone(message)) };
48314
+ }
48315
+ const appended = next.slice(previous.length).map((message) => structuredClone(message));
48316
+ if (mutated.length === 0 && appended.length === 0) return null;
48317
+ return {
48318
+ ...mutated.length > 0 ? { mutated } : {},
48319
+ ...appended.length > 0 ? { appended } : {}
48320
+ };
48321
+ }
48322
+ function applyMessagesDelta(messages, delta) {
48323
+ let result = delta.replaceAll ? [...delta.replaceAll] : messages;
48324
+ if (delta.mutated) {
48325
+ result = [...result];
48326
+ for (const { index, message } of delta.mutated) {
48327
+ result[index] = message;
48328
+ }
48329
+ }
48330
+ if (delta.appended) {
48331
+ result = [...result, ...delta.appended];
48332
+ }
48333
+ return result;
48334
+ }
48335
+ function materializeAtEntry(log, entryId) {
48336
+ const chain = [];
48337
+ let cursor = log.byId.get(entryId);
48338
+ if (!cursor) {
48339
+ throw new Error(`Cannot materialize unknown entry ${entryId}`);
48340
+ }
48341
+ while (cursor) {
48342
+ chain.unshift(cursor);
48343
+ cursor = cursor.parentId !== null ? log.byId.get(cursor.parentId) : void 0;
48344
+ }
48345
+ let meta3 = null;
48346
+ let state = null;
48347
+ let messages = [];
48348
+ for (const entry of chain) {
48349
+ if (entry.type === "meta") {
48350
+ meta3 = entry.payload;
48351
+ } else if (entry.type === "delta") {
48352
+ if (entry.payload.messages) {
48353
+ messages = applyMessagesDelta(messages, entry.payload.messages);
48354
+ }
48355
+ state = entry.payload.state;
48356
+ } else if (entry.type === "fork") {
48357
+ if (entry.payload.truncateAtMessageIndex !== void 0) {
48358
+ messages = messages.slice(0, entry.payload.truncateAtMessageIndex);
48359
+ }
48360
+ }
48361
+ }
48362
+ return { meta: meta3, state, messages };
48363
+ }
48364
+ function materializeAtHead(log) {
48365
+ if (!log.headId) return null;
48366
+ return materializeAtEntry(log, log.headId);
48367
+ }
48368
+ function findCheckpointAtMessageCount(log, entryId, maxMessages) {
48369
+ const chain = [];
48370
+ let cursor = log.byId.get(entryId);
48371
+ if (!cursor) return null;
48372
+ while (cursor) {
48373
+ chain.unshift(cursor);
48374
+ cursor = cursor.parentId !== null ? log.byId.get(cursor.parentId) : void 0;
48375
+ }
48376
+ let messages = [];
48377
+ let firstCheckpoint = null;
48378
+ let anchor = null;
48379
+ for (const entry of chain) {
48380
+ if (entry.type === "fork") {
48381
+ if (entry.payload.truncateAtMessageIndex !== void 0) {
48382
+ messages = messages.slice(0, entry.payload.truncateAtMessageIndex);
48383
+ }
48384
+ continue;
48385
+ }
48386
+ if (entry.type !== "delta") continue;
48387
+ if (entry.payload.messages) {
48388
+ messages = applyMessagesDelta(messages, entry.payload.messages);
48389
+ }
48390
+ firstCheckpoint = firstCheckpoint ?? entry.payload.state;
48391
+ if (messages.length <= maxMessages) {
48392
+ anchor = entry.payload.state;
48393
+ }
48394
+ }
48395
+ return anchor ?? firstCheckpoint;
48396
+ }
48397
+ function toCheckpoint(state) {
48398
+ const {
48399
+ messages: _messages,
48400
+ sessionSnapshots: _snapshots,
48401
+ ...checkpoint
48402
+ } = state;
48403
+ return checkpoint;
48404
+ }
48405
+ var syncStates = /* @__PURE__ */ new Map();
48406
+ function primeTreeLogSyncFromState(stateFilePath2, log, state) {
48407
+ syncStates.set(stateFilePath2, {
48408
+ log,
48409
+ lastMessages: (state.messages ?? []).map((message) => structuredClone(message)),
48410
+ lastCheckpointJson: JSON.stringify(toCheckpoint(state))
48411
+ });
48412
+ }
48413
+ function syncTreeLogWithState(stateFilePath2, state) {
48414
+ try {
48415
+ const logPath = treeLogPathForStateFile(stateFilePath2);
48416
+ let sync = syncStates.get(stateFilePath2);
48417
+ if (!sync || sync.log.filePath !== logPath) {
48418
+ const existing = loadTreeLog(logPath);
48419
+ if (existing) {
48420
+ const materialized = materializeAtHead(existing);
48421
+ sync = {
48422
+ log: existing,
48423
+ lastMessages: materialized?.messages ?? [],
48424
+ lastCheckpointJson: JSON.stringify(materialized?.state ?? null)
48425
+ };
48426
+ } else {
48427
+ const log = createTreeLog(logPath, {
48428
+ taskName: state.taskName,
48429
+ agentId: state.agentId,
48430
+ ...state.originalMessage ? { originalMessage: state.originalMessage } : {}
48431
+ });
48432
+ sync = { log, lastMessages: [], lastCheckpointJson: "null" };
48433
+ }
48434
+ syncStates.set(stateFilePath2, sync);
48435
+ }
48436
+ const nextMessages = state.messages ?? sync.lastMessages;
48437
+ const messagesDelta = computeMessagesDelta(sync.lastMessages, nextMessages);
48438
+ const checkpoint = toCheckpoint(state);
48439
+ const checkpointJson = JSON.stringify(checkpoint);
48440
+ if (!messagesDelta && checkpointJson === sync.lastCheckpointJson) {
48441
+ return;
48442
+ }
48443
+ appendDelta(sync.log, {
48444
+ ...messagesDelta ? { messages: messagesDelta } : {},
48445
+ state: checkpoint
48446
+ });
48447
+ sync.lastMessages = nextMessages.map((message) => structuredClone(message));
48448
+ sync.lastCheckpointJson = checkpointJson;
48449
+ } catch {
48450
+ }
48451
+ }
48452
+
48453
+ // src/marathon/session-tree-view.ts
48454
+ var PREVIEW_LENGTH = 60;
48455
+ function previewText(text, length = PREVIEW_LENGTH) {
48456
+ const collapsed = text.replace(/\s+/g, " ").trim();
48457
+ return collapsed.length > length ? `${collapsed.slice(0, length - 1)}\u2026` : collapsed;
48458
+ }
48459
+ function entryLabel(entry) {
48460
+ if (entry.type === "meta") {
48461
+ const goal = entry.payload.originalMessage;
48462
+ return goal ? `start \xB7 ${previewText(goal)}` : `start \xB7 ${entry.payload.taskName}`;
48463
+ }
48464
+ if (entry.type === "fork") {
48465
+ const where = entry.payload.truncateAtMessageIndex !== void 0 ? ` @ message ${entry.payload.truncateAtMessageIndex}` : "";
48466
+ return entry.payload.label ? `fork${where} \xB7 ${previewText(entry.payload.label)}` : `fork${where}`;
48467
+ }
48468
+ if (entry.type !== "delta") return entry.type;
48469
+ const state = entry.payload.state;
48470
+ const cost = typeof state.totalCost === "number" ? ` \xB7 $${state.totalCost.toFixed(4)}` : "";
48471
+ const output = state.lastOutput ? ` \xB7 ${previewText(state.lastOutput, 48)}` : "";
48472
+ return `session ${state.sessionCount}${cost}${output}`;
48473
+ }
48474
+ function headPathIds(log) {
48475
+ const ids = /* @__PURE__ */ new Set();
48476
+ let cursor = log.headId ? log.byId.get(log.headId) : void 0;
48477
+ while (cursor) {
48478
+ ids.add(cursor.id);
48479
+ cursor = cursor.parentId !== null ? log.byId.get(cursor.parentId) : void 0;
48480
+ }
48481
+ return ids;
48482
+ }
48483
+ function buildTreeView(log) {
48484
+ const childrenByParent = /* @__PURE__ */ new Map();
48485
+ let root;
48486
+ for (const entry of log.entries) {
48487
+ if (entry.type === "head") continue;
48488
+ if (entry.parentId === null) {
48489
+ root = root ?? entry;
48490
+ continue;
48491
+ }
48492
+ const siblings = childrenByParent.get(entry.parentId) ?? [];
48493
+ siblings.push(entry);
48494
+ childrenByParent.set(entry.parentId, siblings);
48495
+ }
48496
+ if (!root) return [];
48497
+ const onHeadPath = headPathIds(log);
48498
+ const rows = [];
48499
+ const visit = (entry, depth) => {
48500
+ rows.push({
48501
+ entryId: entry.id,
48502
+ depth,
48503
+ kind: entry.type,
48504
+ label: entryLabel(entry),
48505
+ isHead: entry.id === log.headId,
48506
+ isOnHeadPath: onHeadPath.has(entry.id)
48507
+ });
48508
+ const children = childrenByParent.get(entry.id) ?? [];
48509
+ for (const child of children) {
48510
+ visit(child, children.length > 1 ? depth + 1 : depth);
48511
+ }
48512
+ };
48513
+ visit(root, 0);
48514
+ return rows;
48515
+ }
48516
+ function listForkCandidates(log) {
48517
+ const materialized = materializeAtHead(log);
48518
+ if (!materialized) return [];
48519
+ const candidates = [];
48520
+ materialized.messages.forEach((message, index) => {
48521
+ if (message.role !== "user") return;
48522
+ const content = typeof message.content === "string" ? message.content : "";
48523
+ if (!content.trim()) return;
48524
+ candidates.push({ messageIndex: index, preview: previewText(content) });
48525
+ });
48526
+ return candidates;
48527
+ }
48528
+
48149
48529
  // src/ink/marathon/CheckpointPrompt.tsx
48150
- import { useState as useState24, useEffect as useEffect21, useRef as useRef8 } from "react";
48151
- import { Box as Box21, Text as Text24 } from "ink";
48530
+ import { useState as useState26, useEffect as useEffect21, useRef as useRef8 } from "react";
48531
+ import { Box as Box23, Text as Text26 } from "ink";
48152
48532
 
48153
48533
  // src/ink/marathon/BlinkingTextInput.tsx
48154
48534
  import { useState as useState20, useEffect as useEffect19, useRef as useRef5 } from "react";
@@ -48282,7 +48662,7 @@ function BlinkingTextInput({
48282
48662
  }
48283
48663
 
48284
48664
  // src/ink/marathon/CheckpointPrompt.tsx
48285
- import { theme as theme23 } from "@runtypelabs/ink-components";
48665
+ import { theme as theme25 } from "@runtypelabs/ink-components";
48286
48666
 
48287
48667
  // src/ink/talk/ModelPicker.tsx
48288
48668
  import { useState as useState21, useMemo as useMemo7, useCallback as useCallback5, useRef as useRef6 } from "react";
@@ -48528,6 +48908,8 @@ var MARATHON_CHECKPOINT_COMMANDS = [
48528
48908
  hasArgs: true
48529
48909
  },
48530
48910
  { name: "/reflect", description: "Open reflection editor to reassess approach", hasArgs: false },
48911
+ { name: "/tree", description: "Browse session branches and switch between them", hasArgs: false },
48912
+ { name: "/fork", description: "Branch the conversation from an earlier message", hasArgs: false },
48531
48913
  { name: "/copy", description: "Copy session JSON to clipboard", hasArgs: false },
48532
48914
  {
48533
48915
  name: "/copy-trimmed",
@@ -49018,10 +49400,147 @@ function CheckpointRecap({
49018
49400
  );
49019
49401
  }
49020
49402
 
49403
+ // src/ink/marathon/TreePanel.tsx
49404
+ import { useState as useState24 } from "react";
49405
+ import { Box as Box21, Text as Text24, useInput as useInput10 } from "ink";
49406
+ import { theme as theme23 } from "@runtypelabs/ink-components";
49407
+ import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
49408
+ var MAX_VISIBLE_ROWS = 12;
49409
+ function TreePanel({ rows, onSelect, onCancel }) {
49410
+ const initialIndex = Math.max(
49411
+ rows.findIndex((row) => row.isHead),
49412
+ 0
49413
+ );
49414
+ const [selectedIndex, setSelectedIndex] = useState24(initialIndex);
49415
+ useInput10((_input, key) => {
49416
+ if (key.escape) {
49417
+ onCancel();
49418
+ return;
49419
+ }
49420
+ if (key.return) {
49421
+ if (rows.length > 0) onSelect(rows[selectedIndex]);
49422
+ return;
49423
+ }
49424
+ if (key.upArrow) {
49425
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : rows.length - 1);
49426
+ return;
49427
+ }
49428
+ if (key.downArrow) {
49429
+ setSelectedIndex((prev) => prev < rows.length - 1 ? prev + 1 : 0);
49430
+ return;
49431
+ }
49432
+ });
49433
+ const windowStart = Math.max(
49434
+ 0,
49435
+ Math.min(selectedIndex - Math.floor(MAX_VISIBLE_ROWS / 2), rows.length - MAX_VISIBLE_ROWS)
49436
+ );
49437
+ const visible = rows.slice(windowStart, windowStart + MAX_VISIBLE_ROWS);
49438
+ return /* @__PURE__ */ jsxs20(
49439
+ Box21,
49440
+ {
49441
+ borderStyle: "single",
49442
+ borderColor: theme23.border,
49443
+ backgroundColor: theme23.surfaceElevated,
49444
+ paddingX: theme23.panelPaddingX,
49445
+ paddingY: theme23.panelPaddingY,
49446
+ flexDirection: "column",
49447
+ children: [
49448
+ /* @__PURE__ */ jsxs20(Box21, { marginBottom: 1, children: [
49449
+ /* @__PURE__ */ jsx24(Text24, { color: theme23.accent, bold: true, children: "Session tree" }),
49450
+ /* @__PURE__ */ jsx24(Text24, { color: theme23.textSubtle, children: ` ${rows.length} entries` })
49451
+ ] }),
49452
+ /* @__PURE__ */ jsx24(Box21, { flexDirection: "column", children: rows.length === 0 ? /* @__PURE__ */ jsx24(Text24, { color: theme23.textSubtle, children: "No session tree yet. It is recorded as the marathon runs." }) : visible.map((row, visibleIndex) => {
49453
+ const index = windowStart + visibleIndex;
49454
+ const isHighlighted = index === selectedIndex;
49455
+ const indicator = isHighlighted ? "\u203A " : " ";
49456
+ const indent = " ".repeat(row.depth);
49457
+ const headMark = row.isHead ? " \u2190 head" : "";
49458
+ const color = isHighlighted ? theme23.accentActive : row.isOnHeadPath ? theme23.textMuted : theme23.textSubtle;
49459
+ return /* @__PURE__ */ jsx24(Box21, { children: /* @__PURE__ */ jsx24(Text24, { color, bold: isHighlighted, children: `${indicator}${indent}${row.label}${headMark}` }) }, row.entryId);
49460
+ }) }),
49461
+ /* @__PURE__ */ jsx24(Box21, { marginTop: 1, children: /* @__PURE__ */ jsx24(Text24, { color: theme23.textSubtle, children: ["\u2191\u2193 navigate", "Enter switch to entry", "Esc cancel"].join(
49462
+ theme23.separator ?? " \xB7 "
49463
+ ) }) })
49464
+ ]
49465
+ }
49466
+ );
49467
+ }
49468
+
49469
+ // src/ink/marathon/ForkPicker.tsx
49470
+ import { useState as useState25 } from "react";
49471
+ import { Box as Box22, Text as Text25, useInput as useInput11 } from "ink";
49472
+ import { theme as theme24 } from "@runtypelabs/ink-components";
49473
+ import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
49474
+ var MAX_VISIBLE_ROWS2 = 10;
49475
+ function ForkPicker({ candidates, onSelect, onCancel }) {
49476
+ const [selectedIndex, setSelectedIndex] = useState25(Math.max(candidates.length - 1, 0));
49477
+ useInput11((_input, key) => {
49478
+ if (key.escape) {
49479
+ onCancel();
49480
+ return;
49481
+ }
49482
+ if (key.return) {
49483
+ if (candidates.length > 0) onSelect(candidates[selectedIndex]);
49484
+ return;
49485
+ }
49486
+ if (key.upArrow) {
49487
+ setSelectedIndex((prev) => prev > 0 ? prev - 1 : candidates.length - 1);
49488
+ return;
49489
+ }
49490
+ if (key.downArrow) {
49491
+ setSelectedIndex((prev) => prev < candidates.length - 1 ? prev + 1 : 0);
49492
+ return;
49493
+ }
49494
+ });
49495
+ const windowStart = Math.max(
49496
+ 0,
49497
+ Math.min(
49498
+ selectedIndex - Math.floor(MAX_VISIBLE_ROWS2 / 2),
49499
+ candidates.length - MAX_VISIBLE_ROWS2
49500
+ )
49501
+ );
49502
+ const visible = candidates.slice(windowStart, windowStart + MAX_VISIBLE_ROWS2);
49503
+ return /* @__PURE__ */ jsxs21(
49504
+ Box22,
49505
+ {
49506
+ borderStyle: "single",
49507
+ borderColor: theme24.border,
49508
+ backgroundColor: theme24.surfaceElevated,
49509
+ paddingX: theme24.panelPaddingX,
49510
+ paddingY: theme24.panelPaddingY,
49511
+ flexDirection: "column",
49512
+ children: [
49513
+ /* @__PURE__ */ jsxs21(Box22, { marginBottom: 1, children: [
49514
+ /* @__PURE__ */ jsx25(Text25, { color: theme24.accent, bold: true, children: "Fork from message" }),
49515
+ /* @__PURE__ */ jsx25(Text25, { color: theme24.textSubtle, children: ` ${candidates.length} user messages` })
49516
+ ] }),
49517
+ /* @__PURE__ */ jsx25(Box22, { flexDirection: "column", children: candidates.length === 0 ? /* @__PURE__ */ jsx25(Text25, { color: theme24.textSubtle, children: "No user messages to fork from yet." }) : visible.map((candidate, visibleIndex) => {
49518
+ const index = windowStart + visibleIndex;
49519
+ const isHighlighted = index === selectedIndex;
49520
+ const indicator = isHighlighted ? "\u203A " : " ";
49521
+ return /* @__PURE__ */ jsx25(Box22, { children: /* @__PURE__ */ jsx25(
49522
+ Text25,
49523
+ {
49524
+ color: isHighlighted ? theme24.accentActive : theme24.textMuted,
49525
+ bold: isHighlighted,
49526
+ children: `${indicator}[${candidate.messageIndex}] ${candidate.preview}`
49527
+ }
49528
+ ) }, candidate.messageIndex);
49529
+ }) }),
49530
+ /* @__PURE__ */ jsx25(Box22, { marginTop: 1, children: /* @__PURE__ */ jsx25(Text25, { color: theme24.textSubtle, children: [
49531
+ "\u2191\u2193 navigate",
49532
+ "Enter fork here",
49533
+ "Esc cancel"
49534
+ ].join(theme24.separator ?? " \xB7 ") }) })
49535
+ ]
49536
+ }
49537
+ );
49538
+ }
49539
+
49021
49540
  // src/ink/marathon/checkpoint-prompt-state.ts
49022
49541
  function shouldPauseCheckpointTimer(state) {
49023
49542
  return Boolean(
49024
- state.isTerminal || state.timeout === 0 || state.isTyping || state.hasPendingChanges || state.showModelPicker || state.showReflectEditor || state.showCommandPicker || state.isReviewing
49543
+ state.isTerminal || state.timeout === 0 || state.isTyping || state.hasPendingChanges || state.showModelPicker || state.showReflectEditor || state.showCommandPicker || state.showTreePanel || state.showForkPicker || state.isReviewing
49025
49544
  );
49026
49545
  }
49027
49546
  function getCheckpointCountdownText(state) {
@@ -49034,32 +49553,38 @@ function getCheckpointCountdownText(state) {
49034
49553
  }
49035
49554
 
49036
49555
  // src/ink/marathon/CheckpointPrompt.tsx
49037
- import { jsx as jsx24, jsxs as jsxs20 } from "react/jsx-runtime";
49556
+ import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
49038
49557
  function CheckpointPrompt({
49039
49558
  onSubmit,
49040
49559
  onToggleHelp,
49041
49560
  onCopySession,
49042
49561
  onCopySessionTrimmed,
49043
49562
  onOpenStateFile,
49563
+ onLoadTreeView,
49564
+ onLoadForkCandidates,
49044
49565
  timeout,
49045
49566
  isTerminal,
49046
49567
  currentModel,
49047
49568
  recap,
49048
49569
  isReviewing = false
49049
49570
  }) {
49050
- const [value, setValue] = useState24("");
49051
- const [remaining, setRemaining] = useState24(timeout);
49052
- const [isTyping, setIsTyping] = useState24(false);
49053
- const [showModelPicker, setShowModelPicker] = useState24(false);
49054
- const [showReflectEditor, setShowReflectEditor] = useState24(false);
49055
- const [showCommandPicker, setShowCommandPicker] = useState24(false);
49056
- const [pendingModel, setPendingModel] = useState24(void 0);
49057
- const [pendingSandbox, setPendingSandbox] = useState24(void 0);
49058
- const [pendingToolsToggle, setPendingToolsToggle] = useState24(false);
49059
- const [pendingStop, setPendingStop] = useState24(false);
49571
+ const [value, setValue] = useState26("");
49572
+ const [remaining, setRemaining] = useState26(timeout);
49573
+ const [isTyping, setIsTyping] = useState26(false);
49574
+ const [showModelPicker, setShowModelPicker] = useState26(false);
49575
+ const [showReflectEditor, setShowReflectEditor] = useState26(false);
49576
+ const [showCommandPicker, setShowCommandPicker] = useState26(false);
49577
+ const [treePanelRows, setTreePanelRows] = useState26(null);
49578
+ const [forkCandidates, setForkCandidates] = useState26(null);
49579
+ const [pendingModel, setPendingModel] = useState26(void 0);
49580
+ const [pendingSandbox, setPendingSandbox] = useState26(void 0);
49581
+ const [pendingToolsToggle, setPendingToolsToggle] = useState26(false);
49582
+ const [pendingStop, setPendingStop] = useState26(false);
49583
+ const [pendingTreeHead, setPendingTreeHead] = useState26(void 0);
49584
+ const [pendingFork, setPendingFork] = useState26(void 0);
49060
49585
  const timerRef = useRef8(null);
49061
- const separator = theme23.separator ?? " \xB7 ";
49062
- const hasPendingChanges = pendingModel !== void 0 || pendingSandbox !== void 0 || pendingToolsToggle || pendingStop;
49586
+ const separator = theme25.separator ?? " \xB7 ";
49587
+ const hasPendingChanges = pendingModel !== void 0 || pendingSandbox !== void 0 || pendingToolsToggle || pendingStop || pendingTreeHead !== void 0 || pendingFork !== void 0;
49063
49588
  const clearInputDraft = () => {
49064
49589
  setValue("");
49065
49590
  setIsTyping(false);
@@ -49070,6 +49595,8 @@ function CheckpointPrompt({
49070
49595
  setPendingSandbox(void 0);
49071
49596
  setPendingToolsToggle(false);
49072
49597
  setPendingStop(false);
49598
+ setPendingTreeHead(void 0);
49599
+ setPendingFork(void 0);
49073
49600
  };
49074
49601
  const submitStagedResult = (action, message) => {
49075
49602
  const result = {
@@ -49077,7 +49604,14 @@ function CheckpointPrompt({
49077
49604
  ...message ? { message } : {},
49078
49605
  ...pendingModel ? { model: pendingModel } : {},
49079
49606
  ...pendingToolsToggle ? { tools: true } : {},
49080
- ...pendingSandbox !== void 0 ? { sandbox: pendingSandbox } : {}
49607
+ ...pendingSandbox !== void 0 ? { sandbox: pendingSandbox } : {},
49608
+ ...pendingTreeHead ? { treeHead: pendingTreeHead.entryId } : {},
49609
+ ...pendingFork ? {
49610
+ fork: {
49611
+ atMessageIndex: pendingFork.atMessageIndex,
49612
+ label: pendingFork.label
49613
+ }
49614
+ } : {}
49081
49615
  };
49082
49616
  resetDraft();
49083
49617
  onSubmit(result);
@@ -49111,6 +49645,8 @@ function CheckpointPrompt({
49111
49645
  showModelPicker,
49112
49646
  showReflectEditor,
49113
49647
  showCommandPicker,
49648
+ showTreePanel: treePanelRows !== null,
49649
+ showForkPicker: forkCandidates !== null,
49114
49650
  isReviewing
49115
49651
  })) {
49116
49652
  if (timerRef.current) {
@@ -49135,7 +49671,7 @@ function CheckpointPrompt({
49135
49671
  timerRef.current = null;
49136
49672
  }
49137
49673
  };
49138
- }, [isTerminal, timeout, isTyping, hasPendingChanges, showModelPicker, showReflectEditor, showCommandPicker, isReviewing, onSubmit]);
49674
+ }, [isTerminal, timeout, isTyping, hasPendingChanges, showModelPicker, showReflectEditor, showCommandPicker, treePanelRows, forkCandidates, isReviewing, onSubmit]);
49139
49675
  const handleSubmit = (text) => {
49140
49676
  const trimmed = text.trim();
49141
49677
  const modelArg = trimmed.startsWith("/model") ? trimmed.slice("/model".length).trim() : "";
@@ -49153,6 +49689,16 @@ function CheckpointPrompt({
49153
49689
  clearInputDraft();
49154
49690
  return;
49155
49691
  }
49692
+ if (trimmed === "/tree") {
49693
+ setTreePanelRows(onLoadTreeView?.() ?? []);
49694
+ clearInputDraft();
49695
+ return;
49696
+ }
49697
+ if (trimmed === "/fork") {
49698
+ setForkCandidates(onLoadForkCandidates?.() ?? []);
49699
+ clearInputDraft();
49700
+ return;
49701
+ }
49156
49702
  if (trimmed === "/copy") {
49157
49703
  onCopySession?.();
49158
49704
  clearInputDraft();
@@ -49231,6 +49777,17 @@ ${trimmed}` : trimmed);
49231
49777
  const handleCommandCancel = () => {
49232
49778
  setShowCommandPicker(false);
49233
49779
  };
49780
+ const handleTreeSelect = (row) => {
49781
+ setTreePanelRows(null);
49782
+ if (row.isHead) return;
49783
+ setPendingFork(void 0);
49784
+ setPendingTreeHead({ entryId: row.entryId, label: row.label });
49785
+ };
49786
+ const handleForkSelect = (candidate) => {
49787
+ setForkCandidates(null);
49788
+ setPendingTreeHead(void 0);
49789
+ setPendingFork({ atMessageIndex: candidate.messageIndex, label: candidate.preview });
49790
+ };
49234
49791
  const countdownText = getCheckpointCountdownText({
49235
49792
  isTerminal,
49236
49793
  timeout,
@@ -49243,7 +49800,9 @@ ${trimmed}` : trimmed);
49243
49800
  ...pendingModel ? [`model ${pendingModel}`] : [],
49244
49801
  ...pendingToolsToggle ? ["toggle tools"] : [],
49245
49802
  ...pendingSandbox !== void 0 ? [pendingSandbox === false ? "disable sandbox" : `sandbox ${pendingSandbox}`] : [],
49246
- ...pendingStop ? ["stop marathon"] : []
49803
+ ...pendingStop ? ["stop marathon"] : [],
49804
+ ...pendingTreeHead ? [`switch to: ${pendingTreeHead.label}`] : [],
49805
+ ...pendingFork ? [`fork @ message ${pendingFork.atMessageIndex}: ${pendingFork.label}`] : []
49247
49806
  ];
49248
49807
  const isCommandDraft = value.trim().startsWith("/");
49249
49808
  const enterHint = (() => {
@@ -49252,43 +49811,57 @@ ${trimmed}` : trimmed);
49252
49811
  if (isTerminal) return "Enter: exit";
49253
49812
  return "Enter: continue";
49254
49813
  })();
49255
- return /* @__PURE__ */ jsxs20(Box21, { flexDirection: "column", flexShrink: 0, children: [
49256
- showCommandPicker ? /* @__PURE__ */ jsx24(
49814
+ return /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", flexShrink: 0, children: [
49815
+ showCommandPicker ? /* @__PURE__ */ jsx26(
49257
49816
  CommandPicker,
49258
49817
  {
49259
49818
  onSelect: handleCommandSelect,
49260
49819
  onCancel: handleCommandCancel
49261
49820
  }
49262
- ) : showModelPicker ? /* @__PURE__ */ jsx24(
49821
+ ) : treePanelRows !== null ? /* @__PURE__ */ jsx26(
49822
+ TreePanel,
49823
+ {
49824
+ rows: treePanelRows,
49825
+ onSelect: handleTreeSelect,
49826
+ onCancel: () => setTreePanelRows(null)
49827
+ }
49828
+ ) : forkCandidates !== null ? /* @__PURE__ */ jsx26(
49829
+ ForkPicker,
49830
+ {
49831
+ candidates: forkCandidates,
49832
+ onSelect: handleForkSelect,
49833
+ onCancel: () => setForkCandidates(null)
49834
+ }
49835
+ ) : showModelPicker ? /* @__PURE__ */ jsx26(
49263
49836
  ModelPicker,
49264
49837
  {
49265
49838
  currentModel,
49266
49839
  onSelect: handleModelSelect,
49267
49840
  onCancel: handleModelCancel
49268
49841
  }
49269
- ) : showReflectEditor ? /* @__PURE__ */ jsx24(
49842
+ ) : showReflectEditor ? /* @__PURE__ */ jsx26(
49270
49843
  ReflectEditor,
49271
49844
  {
49272
49845
  onSubmit: handleReflectSubmit,
49273
49846
  onCancel: handleReflectCancel
49274
49847
  }
49275
- ) : /* @__PURE__ */ jsxs20(
49276
- Box21,
49848
+ ) : /* @__PURE__ */ jsxs22(
49849
+ Box23,
49277
49850
  {
49278
49851
  borderStyle: "bold",
49279
49852
  borderLeft: true,
49280
49853
  borderRight: false,
49281
49854
  borderTop: false,
49282
49855
  borderBottom: false,
49283
- borderColor: theme23.accent,
49284
- backgroundColor: theme23.backgroundDeep,
49856
+ borderColor: theme25.accent,
49857
+ backgroundColor: theme25.backgroundDeep,
49285
49858
  flexDirection: "column",
49286
49859
  paddingX: 1,
49287
49860
  paddingY: 1,
49288
49861
  children: [
49289
- /* @__PURE__ */ jsxs20(Box21, { children: [
49290
- /* @__PURE__ */ jsx24(Text24, { color: theme23.accentActive, children: "> " }),
49291
- /* @__PURE__ */ jsx24(Box21, { flexGrow: 1, children: /* @__PURE__ */ jsx24(
49862
+ /* @__PURE__ */ jsxs22(Box23, { children: [
49863
+ /* @__PURE__ */ jsx26(Text26, { color: theme25.accentActive, children: "> " }),
49864
+ /* @__PURE__ */ jsx26(Box23, { flexGrow: 1, children: /* @__PURE__ */ jsx26(
49292
49865
  BlinkingTextInput,
49293
49866
  {
49294
49867
  value,
@@ -49297,28 +49870,92 @@ ${trimmed}` : trimmed);
49297
49870
  placeholder: isTerminal ? "Send new instructions to continue marathon, or press enter to exit..." : "Guide next iteration..."
49298
49871
  }
49299
49872
  ) }),
49300
- countdownText && /* @__PURE__ */ jsxs20(Text24, { color: theme23.textSubtle, children: [
49873
+ countdownText && /* @__PURE__ */ jsxs22(Text26, { color: theme25.textSubtle, children: [
49301
49874
  " ",
49302
49875
  countdownText
49303
49876
  ] })
49304
49877
  ] }),
49305
- /* @__PURE__ */ jsx24(Text24, { color: theme23.textSubtle, children: [
49878
+ /* @__PURE__ */ jsx26(Text26, { color: theme25.textSubtle, children: [
49306
49879
  enterHint,
49307
49880
  "/: commands",
49308
49881
  "/help"
49309
49882
  ].join(separator) }),
49310
- pendingSummary.length > 0 && /* @__PURE__ */ jsx24(Text24, { color: theme23.textMuted, children: `Pending: ${pendingSummary.join(separator)}` })
49883
+ pendingSummary.length > 0 && /* @__PURE__ */ jsx26(Text26, { color: theme25.textMuted, children: `Pending: ${pendingSummary.join(separator)}` })
49311
49884
  ]
49312
49885
  }
49313
49886
  ),
49314
- /* @__PURE__ */ jsx24(CheckpointRecap, { ...recap, isTerminal })
49887
+ /* @__PURE__ */ jsx26(CheckpointRecap, { ...recap, isTerminal })
49315
49888
  ] });
49316
49889
  }
49317
49890
 
49891
+ // src/ink/marathon/SteerComposer.tsx
49892
+ import { useState as useState27 } from "react";
49893
+ import { Box as Box24, Text as Text27, useInput as useInput12 } from "ink";
49894
+ import { theme as theme26 } from "@runtypelabs/ink-components";
49895
+ import { jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
49896
+ function SteerComposer({ initialDraft = "", onSubmit, onCancel }) {
49897
+ const [value, setValue] = useState27(initialDraft);
49898
+ const [kind, setKind] = useState27("steer");
49899
+ const separator = theme26.separator ?? " \xB7 ";
49900
+ useInput12((_input, key) => {
49901
+ if (key.escape) {
49902
+ onCancel(value);
49903
+ return;
49904
+ }
49905
+ if (key.tab) {
49906
+ setKind((prev) => prev === "steer" ? "follow-up" : "steer");
49907
+ return;
49908
+ }
49909
+ });
49910
+ const handleSubmit = (text) => {
49911
+ const trimmed = text.trim();
49912
+ if (!trimmed) {
49913
+ onCancel("");
49914
+ return;
49915
+ }
49916
+ onSubmit(trimmed, kind);
49917
+ };
49918
+ const kindLabel = kind === "steer" ? "deliver: next turn" : "deliver: after all work";
49919
+ return /* @__PURE__ */ jsxs23(
49920
+ Box24,
49921
+ {
49922
+ borderStyle: "bold",
49923
+ borderLeft: true,
49924
+ borderRight: false,
49925
+ borderTop: false,
49926
+ borderBottom: false,
49927
+ borderColor: theme26.accent,
49928
+ backgroundColor: theme26.backgroundDeep,
49929
+ flexDirection: "column",
49930
+ paddingX: 1,
49931
+ children: [
49932
+ /* @__PURE__ */ jsxs23(Box24, { children: [
49933
+ /* @__PURE__ */ jsx27(Text27, { color: theme26.accentActive, children: "\xBB " }),
49934
+ /* @__PURE__ */ jsx27(Box24, { flexGrow: 1, children: /* @__PURE__ */ jsx27(
49935
+ BlinkingTextInput,
49936
+ {
49937
+ value,
49938
+ onChange: setValue,
49939
+ onSubmit: handleSubmit,
49940
+ placeholder: "Queue a steering message for the agent..."
49941
+ }
49942
+ ) }),
49943
+ /* @__PURE__ */ jsxs23(Text27, { color: theme26.textSubtle, children: [
49944
+ " [",
49945
+ kindLabel,
49946
+ "]"
49947
+ ] })
49948
+ ] }),
49949
+ /* @__PURE__ */ jsx27(Text27, { color: theme26.textSubtle, children: ["Enter: queue", "Tab: delivery timing", "Esc: close (keeps draft)"].join(separator) })
49950
+ ]
49951
+ }
49952
+ );
49953
+ }
49954
+
49318
49955
  // src/ink/marathon/SessionActionMenu.tsx
49319
- import { Box as Box22, Text as Text25, useInput as useInput10 } from "ink";
49320
- import { theme as theme24 } from "@runtypelabs/ink-components";
49321
- import { jsx as jsx25, jsxs as jsxs21 } from "react/jsx-runtime";
49956
+ import { Box as Box25, Text as Text28, useInput as useInput13 } from "ink";
49957
+ import { theme as theme27 } from "@runtypelabs/ink-components";
49958
+ import { jsx as jsx28, jsxs as jsxs24 } from "react/jsx-runtime";
49322
49959
  var MENU_ITEMS = [
49323
49960
  { key: "c", label: "Copy session JSON" },
49324
49961
  { key: "t", label: "Copy trimmed JSON (for LLM context)" },
@@ -49336,7 +49973,7 @@ function SessionActionMenu({
49336
49973
  hasDashboard,
49337
49974
  hasStateFile
49338
49975
  }) {
49339
- useInput10((input, key) => {
49976
+ useInput13((input, key) => {
49340
49977
  if (key.escape) {
49341
49978
  onClose();
49342
49979
  return;
@@ -49362,28 +49999,28 @@ function SessionActionMenu({
49362
49999
  return;
49363
50000
  }
49364
50001
  });
49365
- return /* @__PURE__ */ jsxs21(
49366
- Box22,
50002
+ return /* @__PURE__ */ jsxs24(
50003
+ Box25,
49367
50004
  {
49368
50005
  flexDirection: "column",
49369
50006
  borderStyle: "round",
49370
- borderColor: theme24.accent,
49371
- backgroundColor: theme24.surfaceElevated,
50007
+ borderColor: theme27.accent,
50008
+ backgroundColor: theme27.surfaceElevated,
49372
50009
  paddingX: 2,
49373
50010
  paddingY: 1,
49374
50011
  width: 62,
49375
50012
  children: [
49376
- /* @__PURE__ */ jsx25(Text25, { bold: true, color: theme24.accent, children: "Session" }),
49377
- /* @__PURE__ */ jsx25(Box22, { flexDirection: "column", marginTop: 1, children: MENU_ITEMS.map((item) => {
50013
+ /* @__PURE__ */ jsx28(Text28, { bold: true, color: theme27.accent, children: "Session" }),
50014
+ /* @__PURE__ */ jsx28(Box25, { flexDirection: "column", marginTop: 1, children: MENU_ITEMS.map((item) => {
49378
50015
  const dimmed = item.key === "e" && !hasStateFile || item.key === "f" && !hasStateFile || item.key === "d" && !hasDashboard;
49379
- return /* @__PURE__ */ jsxs21(Text25, { children: [
49380
- /* @__PURE__ */ jsx25(Text25, { color: dimmed ? theme24.textSubtle : theme24.accentActive, children: ` ${item.key} ` }),
49381
- /* @__PURE__ */ jsx25(Text25, { color: dimmed ? theme24.textSubtle : theme24.textMuted, children: item.label })
50016
+ return /* @__PURE__ */ jsxs24(Text28, { children: [
50017
+ /* @__PURE__ */ jsx28(Text28, { color: dimmed ? theme27.textSubtle : theme27.accentActive, children: ` ${item.key} ` }),
50018
+ /* @__PURE__ */ jsx28(Text28, { color: dimmed ? theme27.textSubtle : theme27.textMuted, children: item.label })
49382
50019
  ] }, item.key);
49383
50020
  }) }),
49384
- /* @__PURE__ */ jsxs21(Box22, { marginTop: 1, children: [
49385
- /* @__PURE__ */ jsx25(Text25, { color: theme24.info, children: "Esc" }),
49386
- /* @__PURE__ */ jsx25(Text25, { color: theme24.muted, children: " to close" })
50021
+ /* @__PURE__ */ jsxs24(Box25, { marginTop: 1, children: [
50022
+ /* @__PURE__ */ jsx28(Text28, { color: theme27.info, children: "Esc" }),
50023
+ /* @__PURE__ */ jsx28(Text28, { color: theme27.muted, children: " to close" })
49387
50024
  ] })
49388
50025
  ]
49389
50026
  }
@@ -49549,44 +50186,44 @@ function compactLiveMarathonPayloadForContextExport(payload) {
49549
50186
  }
49550
50187
 
49551
50188
  // src/ink/marathon/UpgradeModal.tsx
49552
- import { Box as Box23, Text as Text26 } from "ink";
49553
- import { theme as theme25 } from "@runtypelabs/ink-components";
49554
- import { jsx as jsx26, jsxs as jsxs22 } from "react/jsx-runtime";
50189
+ import { Box as Box26, Text as Text29 } from "ink";
50190
+ import { theme as theme28 } from "@runtypelabs/ink-components";
50191
+ import { jsx as jsx29, jsxs as jsxs25 } from "react/jsx-runtime";
49555
50192
  function UpgradeModal({ prompt, width }) {
49556
- return /* @__PURE__ */ jsxs22(
49557
- Box23,
50193
+ return /* @__PURE__ */ jsxs25(
50194
+ Box26,
49558
50195
  {
49559
50196
  width,
49560
50197
  flexDirection: "column",
49561
50198
  borderStyle: "round",
49562
- borderColor: theme25.warning,
49563
- backgroundColor: theme25.surfaceElevated,
50199
+ borderColor: theme28.warning,
50200
+ backgroundColor: theme28.surfaceElevated,
49564
50201
  paddingX: 2,
49565
50202
  paddingY: 1,
49566
50203
  children: [
49567
- /* @__PURE__ */ jsx26(Text26, { color: theme25.warning, bold: true, children: "Upgrade available" }),
49568
- /* @__PURE__ */ jsx26(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx26(Text26, { color: theme25.label, children: prompt.message }) }),
49569
- (prompt.code || prompt.limitType || prompt.retryAfter) && /* @__PURE__ */ jsxs22(Box23, { flexDirection: "column", marginTop: 1, children: [
49570
- prompt.code && /* @__PURE__ */ jsxs22(Text26, { color: theme25.muted, children: [
50204
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.warning, bold: true, children: "Upgrade available" }),
50205
+ /* @__PURE__ */ jsx29(Box26, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text29, { color: theme28.label, children: prompt.message }) }),
50206
+ (prompt.code || prompt.limitType || prompt.retryAfter) && /* @__PURE__ */ jsxs25(Box26, { flexDirection: "column", marginTop: 1, children: [
50207
+ prompt.code && /* @__PURE__ */ jsxs25(Text29, { color: theme28.muted, children: [
49571
50208
  "Code: ",
49572
- /* @__PURE__ */ jsx26(Text26, { color: theme25.label, children: prompt.code })
50209
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.label, children: prompt.code })
49573
50210
  ] }),
49574
- prompt.limitType && /* @__PURE__ */ jsxs22(Text26, { color: theme25.muted, children: [
50211
+ prompt.limitType && /* @__PURE__ */ jsxs25(Text29, { color: theme28.muted, children: [
49575
50212
  "Limit: ",
49576
- /* @__PURE__ */ jsx26(Text26, { color: theme25.label, children: prompt.limitType })
50213
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.label, children: prompt.limitType })
49577
50214
  ] }),
49578
- prompt.retryAfter && /* @__PURE__ */ jsxs22(Text26, { color: theme25.muted, children: [
50215
+ prompt.retryAfter && /* @__PURE__ */ jsxs25(Text29, { color: theme28.muted, children: [
49579
50216
  "Retry after: ",
49580
- /* @__PURE__ */ jsx26(Text26, { color: theme25.label, children: prompt.retryAfter })
50217
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.label, children: prompt.retryAfter })
49581
50218
  ] })
49582
50219
  ] }),
49583
- /* @__PURE__ */ jsxs22(Box23, { marginTop: 1, children: [
49584
- /* @__PURE__ */ jsx26(Text26, { color: theme25.info, children: "Enter" }),
49585
- /* @__PURE__ */ jsx26(Text26, { color: theme25.muted, children: " open billing " }),
49586
- /* @__PURE__ */ jsx26(Text26, { color: theme25.info, children: "Esc" }),
49587
- /* @__PURE__ */ jsx26(Text26, { color: theme25.muted, children: " close" })
50220
+ /* @__PURE__ */ jsxs25(Box26, { marginTop: 1, children: [
50221
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.info, children: "Enter" }),
50222
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.muted, children: " open billing " }),
50223
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.info, children: "Esc" }),
50224
+ /* @__PURE__ */ jsx29(Text29, { color: theme28.muted, children: " close" })
49588
50225
  ] }),
49589
- /* @__PURE__ */ jsx26(Box23, { marginTop: 1, children: /* @__PURE__ */ jsx26(Text26, { color: theme25.dimLabel, children: "Opens your dashboard billing page" }) })
50226
+ /* @__PURE__ */ jsx29(Box26, { marginTop: 1, children: /* @__PURE__ */ jsx29(Text29, { color: theme28.dimLabel, children: "Opens your dashboard billing page" }) })
49590
50227
  ]
49591
50228
  }
49592
50229
  );
@@ -49594,14 +50231,14 @@ function UpgradeModal({ prompt, width }) {
49594
50231
 
49595
50232
  // src/ink/marathon/OverviewActivityPane.tsx
49596
50233
  import { memo as memo4 } from "react";
49597
- import { Box as Box25 } from "ink";
49598
- import { theme as theme27 } from "@runtypelabs/ink-components";
50234
+ import { Box as Box28 } from "ink";
50235
+ import { theme as theme30 } from "@runtypelabs/ink-components";
49599
50236
 
49600
50237
  // src/ink/marathon/ToolPanel.tsx
49601
- import { useState as useState25, useEffect as useEffect22, useMemo as useMemo10, memo as memo3 } from "react";
49602
- import { Box as Box24, Text as Text27 } from "ink";
49603
- import { Spinner as Spinner5, theme as theme26 } from "@runtypelabs/ink-components";
49604
- import { Fragment as Fragment3, jsx as jsx27, jsxs as jsxs23 } from "react/jsx-runtime";
50238
+ import { useState as useState28, useEffect as useEffect22, useMemo as useMemo10, memo as memo3 } from "react";
50239
+ import { Box as Box27, Text as Text30 } from "ink";
50240
+ import { Spinner as Spinner5, theme as theme29 } from "@runtypelabs/ink-components";
50241
+ import { Fragment as Fragment3, jsx as jsx30, jsxs as jsxs26 } from "react/jsx-runtime";
49605
50242
  var TOOL_PANEL_TIMER_MS = 500;
49606
50243
  function formatCharCount2(chars) {
49607
50244
  if (chars >= 1e3) {
@@ -49626,9 +50263,9 @@ function formatElapsed2(tool, now) {
49626
50263
  return `${((now - startedAt) / 1e3).toFixed(1)}s`;
49627
50264
  }
49628
50265
  function getStatusColor2(status) {
49629
- if (status === "error") return theme26.danger;
49630
- if (status === "complete") return theme26.success;
49631
- return theme26.accent;
50266
+ if (status === "error") return theme29.danger;
50267
+ if (status === "complete") return theme29.success;
50268
+ return theme29.accent;
49632
50269
  }
49633
50270
  function getPhaseLabel2(tool) {
49634
50271
  if (tool.status === "complete") return "complete";
@@ -49660,7 +50297,7 @@ var ToolPanel = memo3(function ToolPanel2({
49660
50297
  files,
49661
50298
  maxHeight
49662
50299
  }) {
49663
- const [now, setNow] = useState25(Date.now());
50300
+ const [now, setNow] = useState28(Date.now());
49664
50301
  const hasRunning = tools.some((t) => t.status === "running");
49665
50302
  useEffect22(() => {
49666
50303
  if (!hasRunning) return;
@@ -49683,13 +50320,13 @@ var ToolPanel = memo3(function ToolPanel2({
49683
50320
  }, [tools, files, maxHeight, reasoningCharCount]);
49684
50321
  const hiddenToolCount = tools.length - visibleTools.length;
49685
50322
  const hiddenFileCount = (files || []).length - visibleFiles.length;
49686
- return /* @__PURE__ */ jsxs23(Box24, { flexDirection: "column", backgroundColor: theme26.background, children: [
49687
- /* @__PURE__ */ jsx27(Text27, { bold: true, color: theme26.accent, children: "Activity" }),
49688
- reasoningCharCount > 0 && /* @__PURE__ */ jsxs23(Text27, { color: theme26.textMuted, children: [
50323
+ return /* @__PURE__ */ jsxs26(Box27, { flexDirection: "column", backgroundColor: theme29.background, children: [
50324
+ /* @__PURE__ */ jsx30(Text30, { bold: true, color: theme29.accent, children: "Activity" }),
50325
+ reasoningCharCount > 0 && /* @__PURE__ */ jsxs26(Text30, { color: theme29.textMuted, children: [
49689
50326
  "Reasoning: ",
49690
50327
  formatCharCount2(reasoningCharCount)
49691
50328
  ] }),
49692
- hiddenToolCount > 0 && /* @__PURE__ */ jsxs23(Text27, { color: theme26.textSubtle, children: [
50329
+ hiddenToolCount > 0 && /* @__PURE__ */ jsxs26(Text30, { color: theme29.textSubtle, children: [
49693
50330
  " ",
49694
50331
  hiddenToolCount,
49695
50332
  " earlier hidden"
@@ -49698,32 +50335,32 @@ var ToolPanel = memo3(function ToolPanel2({
49698
50335
  const statusColor = getStatusColor2(tool.status);
49699
50336
  const elapsed = formatElapsed2(tool, now);
49700
50337
  const phaseLabel = getPhaseLabel2(tool);
49701
- return /* @__PURE__ */ jsxs23(Box24, { flexDirection: "column", children: [
49702
- /* @__PURE__ */ jsxs23(Box24, { flexDirection: "row", flexWrap: "nowrap", children: [
49703
- /* @__PURE__ */ jsx27(Box24, { width: 2, flexShrink: 0, children: tool.status === "running" ? /* @__PURE__ */ jsx27(Spinner5, { label: "", color: theme26.spinner }) : /* @__PURE__ */ jsx27(Text27, { color: statusColor, children: STATUS_ICONS2[tool.status] || "?" }) }),
49704
- /* @__PURE__ */ jsx27(Box24, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx27(Text27, { color: theme26.text, wrap: "truncate", children: tool.name }) }),
49705
- /* @__PURE__ */ jsxs23(Box24, { flexShrink: 0, children: [
49706
- /* @__PURE__ */ jsxs23(Text27, { color: theme26.textSubtle, children: [
50338
+ return /* @__PURE__ */ jsxs26(Box27, { flexDirection: "column", children: [
50339
+ /* @__PURE__ */ jsxs26(Box27, { flexDirection: "row", flexWrap: "nowrap", children: [
50340
+ /* @__PURE__ */ jsx30(Box27, { width: 2, flexShrink: 0, children: tool.status === "running" ? /* @__PURE__ */ jsx30(Spinner5, { label: "", color: theme29.spinner }) : /* @__PURE__ */ jsx30(Text30, { color: statusColor, children: STATUS_ICONS2[tool.status] || "?" }) }),
50341
+ /* @__PURE__ */ jsx30(Box27, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx30(Text30, { color: theme29.text, wrap: "truncate", children: tool.name }) }),
50342
+ /* @__PURE__ */ jsxs26(Box27, { flexShrink: 0, children: [
50343
+ /* @__PURE__ */ jsxs26(Text30, { color: theme29.textSubtle, children: [
49707
50344
  " ",
49708
50345
  phaseLabel
49709
50346
  ] }),
49710
- /* @__PURE__ */ jsxs23(Text27, { color: theme26.textMuted, children: [
50347
+ /* @__PURE__ */ jsxs26(Text30, { color: theme29.textMuted, children: [
49711
50348
  " ",
49712
50349
  elapsed
49713
50350
  ] })
49714
50351
  ] })
49715
50352
  ] }),
49716
- /* @__PURE__ */ jsxs23(Box24, { flexDirection: "row", flexWrap: "nowrap", children: [
49717
- /* @__PURE__ */ jsx27(Box24, { width: 2, flexShrink: 0 }),
49718
- /* @__PURE__ */ jsx27(Text27, { color: theme26.textSubtle, children: "\u2514 " }),
49719
- /* @__PURE__ */ jsx27(Box24, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx27(Text27, { color: theme26.textMuted, wrap: "truncate", children: tool.inputPreview || "" }) })
50353
+ /* @__PURE__ */ jsxs26(Box27, { flexDirection: "row", flexWrap: "nowrap", children: [
50354
+ /* @__PURE__ */ jsx30(Box27, { width: 2, flexShrink: 0 }),
50355
+ /* @__PURE__ */ jsx30(Text30, { color: theme29.textSubtle, children: "\u2514 " }),
50356
+ /* @__PURE__ */ jsx30(Box27, { flexShrink: 1, flexGrow: 1, children: /* @__PURE__ */ jsx30(Text30, { color: theme29.textMuted, wrap: "truncate", children: tool.inputPreview || "" }) })
49720
50357
  ] })
49721
50358
  ] }, tool.id);
49722
50359
  }),
49723
- visibleFiles.length > 0 && /* @__PURE__ */ jsxs23(Fragment3, { children: [
49724
- /* @__PURE__ */ jsxs23(Box24, { marginTop: 1, children: [
49725
- /* @__PURE__ */ jsx27(Text27, { bold: true, color: theme26.accent, children: "Files" }),
49726
- hiddenFileCount > 0 && /* @__PURE__ */ jsxs23(Text27, { color: theme26.textSubtle, children: [
50360
+ visibleFiles.length > 0 && /* @__PURE__ */ jsxs26(Fragment3, { children: [
50361
+ /* @__PURE__ */ jsxs26(Box27, { marginTop: 1, children: [
50362
+ /* @__PURE__ */ jsx30(Text30, { bold: true, color: theme29.accent, children: "Files" }),
50363
+ hiddenFileCount > 0 && /* @__PURE__ */ jsxs26(Text30, { color: theme29.textSubtle, children: [
49727
50364
  " +",
49728
50365
  hiddenFileCount
49729
50366
  ] })
@@ -49731,9 +50368,9 @@ var ToolPanel = memo3(function ToolPanel2({
49731
50368
  visibleFiles.map((file2) => {
49732
50369
  const icon = FILE_TYPE_ICONS[file2.type] || "\u2022";
49733
50370
  const filename = file2.path.split("/").pop() || file2.path;
49734
- return /* @__PURE__ */ jsxs23(Box24, { flexDirection: "row", flexWrap: "nowrap", children: [
49735
- /* @__PURE__ */ jsx27(Box24, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx27(Text27, { color: file2.type === "written" ? theme26.success : theme26.textMuted, children: icon }) }),
49736
- /* @__PURE__ */ jsx27(Box24, { flexShrink: 1, children: /* @__PURE__ */ jsx27(Text27, { color: theme26.text, wrap: "truncate", children: filename }) })
50371
+ return /* @__PURE__ */ jsxs26(Box27, { flexDirection: "row", flexWrap: "nowrap", children: [
50372
+ /* @__PURE__ */ jsx30(Box27, { width: 2, flexShrink: 0, children: /* @__PURE__ */ jsx30(Text30, { color: file2.type === "written" ? theme29.success : theme29.textMuted, children: icon }) }),
50373
+ /* @__PURE__ */ jsx30(Box27, { flexShrink: 1, children: /* @__PURE__ */ jsx30(Text30, { color: theme29.text, wrap: "truncate", children: filename }) })
49737
50374
  ] }, file2.path);
49738
50375
  })
49739
50376
  ] })
@@ -49743,7 +50380,7 @@ var ToolPanel = memo3(function ToolPanel2({
49743
50380
  });
49744
50381
 
49745
50382
  // src/ink/marathon/OverviewActivityPane.tsx
49746
- import { jsx as jsx28 } from "react/jsx-runtime";
50383
+ import { jsx as jsx31 } from "react/jsx-runtime";
49747
50384
  var OverviewActivityPane = memo4(function OverviewActivityPane2({
49748
50385
  tools,
49749
50386
  reasoningCharCount,
@@ -49752,18 +50389,18 @@ var OverviewActivityPane = memo4(function OverviewActivityPane2({
49752
50389
  stacked = false,
49753
50390
  width
49754
50391
  }) {
49755
- return /* @__PURE__ */ jsx28(
49756
- Box25,
50392
+ return /* @__PURE__ */ jsx31(
50393
+ Box28,
49757
50394
  {
49758
50395
  flexDirection: "column",
49759
50396
  width: stacked ? void 0 : width,
49760
50397
  flexShrink: 0,
49761
50398
  borderStyle: "single",
49762
- borderColor: theme27.border,
49763
- backgroundColor: theme27.background,
49764
- paddingX: theme27.panelPaddingX,
49765
- paddingY: theme27.panelPaddingY,
49766
- children: /* @__PURE__ */ jsx28(
50399
+ borderColor: theme30.border,
50400
+ backgroundColor: theme30.background,
50401
+ paddingX: theme30.panelPaddingX,
50402
+ paddingY: theme30.panelPaddingY,
50403
+ children: /* @__PURE__ */ jsx31(
49767
50404
  ToolPanel,
49768
50405
  {
49769
50406
  tools,
@@ -49778,16 +50415,16 @@ var OverviewActivityPane = memo4(function OverviewActivityPane2({
49778
50415
 
49779
50416
  // src/ink/marathon/OverviewTranscriptPane.tsx
49780
50417
  import { memo as memo5 } from "react";
49781
- import { Box as Box27 } from "ink";
50418
+ import { Box as Box30 } from "ink";
49782
50419
  import { StreamOutput, ErrorDisplay as ErrorDisplay3 } from "@runtypelabs/ink-components";
49783
50420
  import { LoadingAnimation } from "@runtypelabs/terminal-animations";
49784
50421
 
49785
50422
  // src/ink/marathon/ThinkingIndicator.tsx
49786
- import { useState as useState26, useEffect as useEffect23 } from "react";
49787
- import { Spinner as Spinner6, theme as theme28 } from "@runtypelabs/ink-components";
49788
- import { jsx as jsx29 } from "react/jsx-runtime";
50423
+ import { useState as useState29, useEffect as useEffect23 } from "react";
50424
+ import { Spinner as Spinner6, theme as theme31 } from "@runtypelabs/ink-components";
50425
+ import { jsx as jsx32 } from "react/jsx-runtime";
49789
50426
  function ThinkingIndicator({ startedAt }) {
49790
- const [elapsed, setElapsed] = useState26(
50427
+ const [elapsed, setElapsed] = useState29(
49791
50428
  () => startedAt ? Math.floor((Date.now() - startedAt) / 1e3) : 0
49792
50429
  );
49793
50430
  useEffect23(() => {
@@ -49798,13 +50435,13 @@ function ThinkingIndicator({ startedAt }) {
49798
50435
  }, 1e3);
49799
50436
  return () => clearInterval(interval);
49800
50437
  }, [startedAt]);
49801
- return /* @__PURE__ */ jsx29(Spinner6, { label: `Thinking... ${elapsed}s`, color: theme28.textMuted });
50438
+ return /* @__PURE__ */ jsx32(Spinner6, { label: `Thinking... ${elapsed}s`, color: theme31.textMuted });
49802
50439
  }
49803
50440
 
49804
50441
  // src/ink/marathon/ContextCompactionIndicator.tsx
49805
- import { useEffect as useEffect24, useState as useState27 } from "react";
49806
- import { Spinner as Spinner7, theme as theme29 } from "@runtypelabs/ink-components";
49807
- import { jsx as jsx30 } from "react/jsx-runtime";
50442
+ import { useEffect as useEffect24, useState as useState30 } from "react";
50443
+ import { Spinner as Spinner7, theme as theme32 } from "@runtypelabs/ink-components";
50444
+ import { jsx as jsx33 } from "react/jsx-runtime";
49808
50445
  function buildCompactionLabel(compaction, elapsedSeconds) {
49809
50446
  const modeLabel = compaction.mode === "auto" ? "auto" : "manual";
49810
50447
  const strategyLabel = compaction.strategy === "provider_native" ? "native" : "summary";
@@ -49817,7 +50454,7 @@ function buildCompactionLabel(compaction, elapsedSeconds) {
49817
50454
  function ContextCompactionIndicator({
49818
50455
  compaction
49819
50456
  }) {
49820
- const [elapsed, setElapsed] = useState27(
50457
+ const [elapsed, setElapsed] = useState30(
49821
50458
  () => Math.floor((Date.now() - compaction.startedAt) / 1e3)
49822
50459
  );
49823
50460
  useEffect24(() => {
@@ -49828,16 +50465,16 @@ function ContextCompactionIndicator({
49828
50465
  }, 1e3);
49829
50466
  return () => clearInterval(interval);
49830
50467
  }, [compaction.startedAt]);
49831
- return /* @__PURE__ */ jsx30(Spinner7, { label: buildCompactionLabel(compaction, elapsed), color: theme29.warning });
50468
+ return /* @__PURE__ */ jsx33(Spinner7, { label: buildCompactionLabel(compaction, elapsed), color: theme32.warning });
49832
50469
  }
49833
50470
 
49834
50471
  // src/ink/marathon/ReasoningBlock.tsx
49835
- import { Box as Box26, Text as Text28 } from "ink";
49836
- import { theme as theme30 } from "@runtypelabs/ink-components";
49837
- import { jsx as jsx31, jsxs as jsxs24 } from "react/jsx-runtime";
49838
- var REASONING_LABEL_COLOR = theme30.accent;
49839
- var REASONING_TEXT_COLOR = theme30.textMuted;
49840
- var REASONING_HINT_COLOR = theme30.textSubtle;
50472
+ import { Box as Box29, Text as Text31 } from "ink";
50473
+ import { theme as theme33 } from "@runtypelabs/ink-components";
50474
+ import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
50475
+ var REASONING_LABEL_COLOR = theme33.accent;
50476
+ var REASONING_TEXT_COLOR = theme33.textMuted;
50477
+ var REASONING_HINT_COLOR = theme33.textSubtle;
49841
50478
  function renderReasoningLine(line) {
49842
50479
  return line ? `| ${line}` : "|";
49843
50480
  }
@@ -49850,17 +50487,17 @@ function ReasoningBlock({
49850
50487
  }) {
49851
50488
  const label = collapsed ? "Reasoning hidden" : "Reasoning";
49852
50489
  const hint = showToggleHint ? collapsed ? "r to show" : "r to hide" : null;
49853
- return /* @__PURE__ */ jsxs24(Box26, { flexDirection: "column", children: [
49854
- /* @__PURE__ */ jsxs24(Box26, { children: [
49855
- /* @__PURE__ */ jsx31(Text28, { color: REASONING_LABEL_COLOR, children: label }),
49856
- hint && /* @__PURE__ */ jsxs24(Text28, { color: REASONING_HINT_COLOR, children: [
50490
+ return /* @__PURE__ */ jsxs27(Box29, { flexDirection: "column", children: [
50491
+ /* @__PURE__ */ jsxs27(Box29, { children: [
50492
+ /* @__PURE__ */ jsx34(Text31, { color: REASONING_LABEL_COLOR, children: label }),
50493
+ hint && /* @__PURE__ */ jsxs27(Text31, { color: REASONING_HINT_COLOR, children: [
49857
50494
  " (",
49858
50495
  hint,
49859
50496
  ")"
49860
50497
  ] })
49861
50498
  ] }),
49862
- !collapsed && lines.map((line, index) => /* @__PURE__ */ jsx31(
49863
- Text28,
50499
+ !collapsed && lines.map((line, index) => /* @__PURE__ */ jsx34(
50500
+ Text31,
49864
50501
  {
49865
50502
  color: REASONING_TEXT_COLOR,
49866
50503
  wrap: compact ? "truncate" : void 0,
@@ -49868,12 +50505,12 @@ function ReasoningBlock({
49868
50505
  },
49869
50506
  `${index}:${line}`
49870
50507
  )),
49871
- !collapsed && live && /* @__PURE__ */ jsx31(Text28, { color: REASONING_TEXT_COLOR, wrap: compact ? "truncate" : void 0, children: "| ..." })
50508
+ !collapsed && live && /* @__PURE__ */ jsx34(Text31, { color: REASONING_TEXT_COLOR, wrap: compact ? "truncate" : void 0, children: "| ..." })
49872
50509
  ] });
49873
50510
  }
49874
50511
 
49875
50512
  // src/ink/marathon/OverviewTranscriptPane.tsx
49876
- import { Fragment as Fragment4, jsx as jsx32, jsxs as jsxs25 } from "react/jsx-runtime";
50513
+ import { Fragment as Fragment4, jsx as jsx35, jsxs as jsxs28 } from "react/jsx-runtime";
49877
50514
  var UPGRADE_BROWSE_HINT_LINES = [
49878
50515
  "Upgrade modal dismissed.",
49879
50516
  "Use Shift+Left/Right or 1-9 to review previous marathon runs."
@@ -49899,11 +50536,11 @@ var OverviewTranscriptPane = memo5(function OverviewTranscriptPane2({
49899
50536
  error: error51 = null
49900
50537
  }) {
49901
50538
  if (showLoadingAnimation) {
49902
- return /* @__PURE__ */ jsx32(Box27, { flexGrow: 1, minHeight: contentHeight, overflow: "hidden", children: /* @__PURE__ */ jsx32(LoadingAnimation, { width: paneWidth, height: contentHeight }) });
50539
+ return /* @__PURE__ */ jsx35(Box30, { flexGrow: 1, minHeight: contentHeight, overflow: "hidden", children: /* @__PURE__ */ jsx35(LoadingAnimation, { width: paneWidth, height: contentHeight }) });
49903
50540
  }
49904
50541
  const maxScroll = Math.max(0, totalLines - maxVisibleLines);
49905
- return /* @__PURE__ */ jsxs25(Fragment4, { children: [
49906
- hasReasoning && /* @__PURE__ */ jsx32(Box27, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx32(
50542
+ return /* @__PURE__ */ jsxs28(Fragment4, { children: [
50543
+ hasReasoning && /* @__PURE__ */ jsx35(Box30, { flexDirection: "column", marginBottom: reasoningCollapsed ? 0 : 1, children: /* @__PURE__ */ jsx35(
49907
50544
  ReasoningBlock,
49908
50545
  {
49909
50546
  lines: visibleReasoningLines,
@@ -49912,11 +50549,11 @@ var OverviewTranscriptPane = memo5(function OverviewTranscriptPane2({
49912
50549
  showToggleHint: true
49913
50550
  }
49914
50551
  ) }),
49915
- showThinkingIndicator && /* @__PURE__ */ jsx32(ThinkingIndicator, { startedAt: thinkingStartedAt }),
49916
- contextCompaction && /* @__PURE__ */ jsx32(ContextCompactionIndicator, { compaction: contextCompaction }),
49917
- showUpgradeBrowseHint && /* @__PURE__ */ jsx32(Box27, { marginBottom: 1, children: /* @__PURE__ */ jsx32(ReasoningBlock, { lines: UPGRADE_BROWSE_HINT_LINES, compact: true }) }),
49918
- /* @__PURE__ */ jsxs25(Box27, { flexDirection: "row", children: [
49919
- /* @__PURE__ */ jsx32(Box27, { flexDirection: "column", flexGrow: 1, marginRight: 1, children: /* @__PURE__ */ jsx32(
50552
+ showThinkingIndicator && /* @__PURE__ */ jsx35(ThinkingIndicator, { startedAt: thinkingStartedAt }),
50553
+ contextCompaction && /* @__PURE__ */ jsx35(ContextCompactionIndicator, { compaction: contextCompaction }),
50554
+ showUpgradeBrowseHint && /* @__PURE__ */ jsx35(Box30, { marginBottom: 1, children: /* @__PURE__ */ jsx35(ReasoningBlock, { lines: UPGRADE_BROWSE_HINT_LINES, compact: true }) }),
50555
+ /* @__PURE__ */ jsxs28(Box30, { flexDirection: "row", children: [
50556
+ /* @__PURE__ */ jsx35(Box30, { flexDirection: "column", flexGrow: 1, marginRight: 1, children: /* @__PURE__ */ jsx35(
49920
50557
  StreamOutput,
49921
50558
  {
49922
50559
  content,
@@ -49926,7 +50563,7 @@ var OverviewTranscriptPane = memo5(function OverviewTranscriptPane2({
49926
50563
  scrollOffset
49927
50564
  }
49928
50565
  ) }),
49929
- /* @__PURE__ */ jsx32(
50566
+ /* @__PURE__ */ jsx35(
49930
50567
  Scrollbar,
49931
50568
  {
49932
50569
  totalLines,
@@ -49936,7 +50573,7 @@ var OverviewTranscriptPane = memo5(function OverviewTranscriptPane2({
49936
50573
  }
49937
50574
  )
49938
50575
  ] }),
49939
- error51 && /* @__PURE__ */ jsx32(ErrorDisplay3, { error: error51 })
50576
+ error51 && /* @__PURE__ */ jsx35(ErrorDisplay3, { error: error51 })
49940
50577
  ] });
49941
50578
  });
49942
50579
 
@@ -50096,7 +50733,7 @@ function isAllowedCheckpointBrowseKey(key, isBrowsingScreen) {
50096
50733
  }
50097
50734
 
50098
50735
  // src/ink/marathon/MarathonApp.tsx
50099
- import { jsx as jsx33, jsxs as jsxs26 } from "react/jsx-runtime";
50736
+ import { jsx as jsx36, jsxs as jsxs29 } from "react/jsx-runtime";
50100
50737
  var TOOL_PANEL_WIDE = 48;
50101
50738
  var TOOL_PANEL_NARROW = 36;
50102
50739
  var NARROW_THRESHOLD = 100;
@@ -50221,23 +50858,23 @@ function MarathonApp({
50221
50858
  } = useMarathonStream();
50222
50859
  const { exit } = useApp4();
50223
50860
  const { stdout } = useStdout5();
50224
- const separator = theme31.separator ?? " \xB7 ";
50861
+ const separator = theme34.separator ?? " \xB7 ";
50225
50862
  const checkpointResolveRef = useRef9(null);
50226
- const [checkpointRecap, setCheckpointRecap] = useState28(null);
50227
- const [currentModel, setCurrentModel] = useState28(model || "default");
50228
- const [currentSandbox, setCurrentSandbox] = useState28(sandbox);
50229
- const [isTerminalCheckpoint, setIsTerminalCheckpoint] = useState28(false);
50230
- const [currentMilestone, setCurrentMilestone] = useState28(initialCurrentMilestone);
50231
- const [allowInitialInlineLoader, setAllowInitialInlineLoader] = useState28(!suppressInitialInlineLoader);
50232
- const [sessionSnapshots, setSessionSnapshots] = useState28(
50863
+ const [checkpointRecap, setCheckpointRecap] = useState31(null);
50864
+ const [currentModel, setCurrentModel] = useState31(model || "default");
50865
+ const [currentSandbox, setCurrentSandbox] = useState31(sandbox);
50866
+ const [isTerminalCheckpoint, setIsTerminalCheckpoint] = useState31(false);
50867
+ const [currentMilestone, setCurrentMilestone] = useState31(initialCurrentMilestone);
50868
+ const [allowInitialInlineLoader, setAllowInitialInlineLoader] = useState31(!suppressInitialInlineLoader);
50869
+ const [sessionSnapshots, setSessionSnapshots] = useState31(
50233
50870
  () => (initialSessionSnapshots || []).map((snapshot) => cloneSessionSnapshot(snapshot))
50234
50871
  );
50235
50872
  const latestCompletedSessionIndex = sessionSnapshots[sessionSnapshots.length - 1]?.sessionIndex ?? initialSessionCount;
50236
- const [selectedSessionKey, setSelectedSessionKey] = useState28(void 0);
50237
- const [followLatest, setFollowLatest] = useState28(true);
50238
- const [latestUnreadKey, setLatestUnreadKey] = useState28(void 0);
50239
- const [previewUrl, setPreviewUrl] = useState28(initialPreviewUrl);
50240
- const [isCheckpointExploring, setIsCheckpointExploring] = useState28(false);
50873
+ const [selectedSessionKey, setSelectedSessionKey] = useState31(void 0);
50874
+ const [followLatest, setFollowLatest] = useState31(true);
50875
+ const [latestUnreadKey, setLatestUnreadKey] = useState31(void 0);
50876
+ const [previewUrl, setPreviewUrl] = useState31(initialPreviewUrl);
50877
+ const [isCheckpointExploring, setIsCheckpointExploring] = useState31(false);
50241
50878
  const isRunnerAnimating = state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool" || Boolean(state.contextCompaction?.active);
50242
50879
  const isTerminalCheckpointRef = useRef9(false);
50243
50880
  const markCheckpointExploring = useCallback8(() => {
@@ -50245,6 +50882,16 @@ function MarathonApp({
50245
50882
  setIsCheckpointExploring(true);
50246
50883
  }
50247
50884
  }, [state.phase, checkpointRecap]);
50885
+ const handleLoadTreeView = useCallback8(() => {
50886
+ if (!stateFilePath2) return null;
50887
+ const log = loadTreeLog(treeLogPathForStateFile(stateFilePath2));
50888
+ return log ? buildTreeView(log) : null;
50889
+ }, [stateFilePath2]);
50890
+ const handleLoadForkCandidates = useCallback8(() => {
50891
+ if (!stateFilePath2) return null;
50892
+ const log = loadTreeLog(treeLogPathForStateFile(stateFilePath2));
50893
+ return log ? listForkCandidates(log) : null;
50894
+ }, [stateFilePath2]);
50248
50895
  const handleCheckpointSubmit = useCallback8(
50249
50896
  (result) => {
50250
50897
  setIsCheckpointExploring(false);
@@ -50275,6 +50922,17 @@ function MarathonApp({
50275
50922
  streamRef.current = {
50276
50923
  getCallbacks: () => callbacks,
50277
50924
  getState: () => getHydratedState(),
50925
+ drainSteeringQueue: () => {
50926
+ const drained = steeringQueueRef.current.splice(0);
50927
+ if (drained.length > 0) setQueuedSteerCount(0);
50928
+ return drained.length > 0 ? drained : void 0;
50929
+ },
50930
+ hasQueuedSteering: () => steeringQueueRef.current.length > 0,
50931
+ drainFollowUpQueue: () => {
50932
+ const drained = followUpQueueRef.current.splice(0);
50933
+ if (drained.length > 0) setQueuedFollowUpCount(0);
50934
+ return drained.length > 0 ? drained : void 0;
50935
+ },
50278
50936
  appendSessionSnapshot: (snapshot) => {
50279
50937
  setSessionSnapshots((prev) => upsertSessionSnapshots(prev, snapshot));
50280
50938
  const snapshotKey = createSessionTabKey(snapshot.sessionIndex);
@@ -50342,39 +51000,45 @@ function MarathonApp({
50342
51000
  const contentHeight = Math.max(5, terminalRows - chromeRows);
50343
51001
  const isStacked = terminalWidth < STACKED_THRESHOLD;
50344
51002
  const toolPanelWidth = terminalWidth < NARROW_THRESHOLD ? TOOL_PANEL_NARROW : TOOL_PANEL_WIDE;
50345
- const [ctrlCPressed, setCtrlCPressed] = useState28(false);
51003
+ const [ctrlCPressed, setCtrlCPressed] = useState31(false);
50346
51004
  const ctrlCTimeout = useRef9(null);
50347
- const [activeScreen, setActiveScreen] = useState28("overview");
51005
+ const steeringQueueRef = useRef9([]);
51006
+ const followUpQueueRef = useRef9([]);
51007
+ const [queuedSteerCount, setQueuedSteerCount] = useState31(0);
51008
+ const [queuedFollowUpCount, setQueuedFollowUpCount] = useState31(0);
51009
+ const [showSteerComposer, setShowSteerComposer] = useState31(false);
51010
+ const [steerDraft, setSteerDraft] = useState31("");
51011
+ const [activeScreen, setActiveScreen] = useState31("overview");
50348
51012
  const showEventStream = activeScreen === "events";
50349
51013
  const showReasoningPanel = activeScreen === "reasoning";
50350
51014
  const showToolsPanel = activeScreen === "tools";
50351
51015
  const showFilesPanel = activeScreen === "files";
50352
- const [showHelpOverlay, setShowHelpOverlay] = useState28(false);
50353
- const [helpScrollOffset, setHelpScrollOffset] = useState28(0);
50354
- const [showSessionMenu, setShowSessionMenu] = useState28(false);
50355
- const [fileCursor, setFileCursor] = useState28(0);
50356
- const [detailFile, setDetailFile] = useState28(null);
50357
- const [detailFileContent, setDetailFileContent] = useState28(null);
50358
- const [detailFileTotalLines, setDetailFileTotalLines] = useState28(0);
50359
- const [detailFileTruncated, setDetailFileTruncated] = useState28(false);
50360
- const [detailFileSource, setDetailFileSource] = useState28("disk");
50361
- const [fileDetailScrollOffset, setFileDetailScrollOffset] = useState28(0);
50362
- const [scrollOffset, setScrollOffset] = useState28(0);
50363
- const [reasoningCollapsed, setReasoningCollapsed] = useState28(false);
50364
- const [eventCursor, setEventCursor] = useState28(-1);
50365
- const [detailEvent, setDetailEvent] = useState28(null);
50366
- const [detailScrollOffset, setDetailScrollOffset] = useState28(0);
50367
- const [eventTypeFilter, setEventTypeFilter] = useState28(/* @__PURE__ */ new Set());
50368
- const [showEventTypeFilter, setShowEventTypeFilter] = useState28(false);
50369
- const [reasoningScrollOffset, setReasoningScrollOffset] = useState28(0);
50370
- const [toolCursor, setToolCursor] = useState28(-1);
50371
- const [detailToolEntry, setDetailToolEntry] = useState28(null);
50372
- const [toolDetailScrollOffset, setToolDetailScrollOffset] = useState28(0);
50373
- const [goalExpanded, setGoalExpanded] = useState28(false);
50374
- const [upgradeModalDismissed, setUpgradeModalDismissed] = useState28(false);
50375
- const [clipboardFlash, setClipboardFlash] = useState28(null);
51016
+ const [showHelpOverlay, setShowHelpOverlay] = useState31(false);
51017
+ const [helpScrollOffset, setHelpScrollOffset] = useState31(0);
51018
+ const [showSessionMenu, setShowSessionMenu] = useState31(false);
51019
+ const [fileCursor, setFileCursor] = useState31(0);
51020
+ const [detailFile, setDetailFile] = useState31(null);
51021
+ const [detailFileContent, setDetailFileContent] = useState31(null);
51022
+ const [detailFileTotalLines, setDetailFileTotalLines] = useState31(0);
51023
+ const [detailFileTruncated, setDetailFileTruncated] = useState31(false);
51024
+ const [detailFileSource, setDetailFileSource] = useState31("disk");
51025
+ const [fileDetailScrollOffset, setFileDetailScrollOffset] = useState31(0);
51026
+ const [scrollOffset, setScrollOffset] = useState31(0);
51027
+ const [reasoningCollapsed, setReasoningCollapsed] = useState31(false);
51028
+ const [eventCursor, setEventCursor] = useState31(-1);
51029
+ const [detailEvent, setDetailEvent] = useState31(null);
51030
+ const [detailScrollOffset, setDetailScrollOffset] = useState31(0);
51031
+ const [eventTypeFilter, setEventTypeFilter] = useState31(/* @__PURE__ */ new Set());
51032
+ const [showEventTypeFilter, setShowEventTypeFilter] = useState31(false);
51033
+ const [reasoningScrollOffset, setReasoningScrollOffset] = useState31(0);
51034
+ const [toolCursor, setToolCursor] = useState31(-1);
51035
+ const [detailToolEntry, setDetailToolEntry] = useState31(null);
51036
+ const [toolDetailScrollOffset, setToolDetailScrollOffset] = useState31(0);
51037
+ const [goalExpanded, setGoalExpanded] = useState31(false);
51038
+ const [upgradeModalDismissed, setUpgradeModalDismissed] = useState31(false);
51039
+ const [clipboardFlash, setClipboardFlash] = useState31(null);
50376
51040
  const flashTimeout = useRef9(null);
50377
- const [account, setAccount] = useState28(void 0);
51041
+ const [account, setAccount] = useState31(void 0);
50378
51042
  useEffect25(() => {
50379
51043
  let cancelled = false;
50380
51044
  getCurrentAccountId().then((id) => {
@@ -50403,8 +51067,8 @@ function MarathonApp({
50403
51067
  setShowSessionMenu(false);
50404
51068
  try {
50405
51069
  let json2;
50406
- if (stateFilePath2 && fs4.existsSync(stateFilePath2)) {
50407
- json2 = fs4.readFileSync(stateFilePath2, "utf-8");
51070
+ if (stateFilePath2 && fs5.existsSync(stateFilePath2)) {
51071
+ json2 = fs5.readFileSync(stateFilePath2, "utf-8");
50408
51072
  } else {
50409
51073
  json2 = JSON.stringify({
50410
51074
  sessionSnapshots,
@@ -50424,8 +51088,8 @@ function MarathonApp({
50424
51088
  setShowSessionMenu(false);
50425
51089
  try {
50426
51090
  let json2;
50427
- if (stateFilePath2 && fs4.existsSync(stateFilePath2)) {
50428
- const raw = fs4.readFileSync(stateFilePath2, "utf-8");
51091
+ if (stateFilePath2 && fs5.existsSync(stateFilePath2)) {
51092
+ const raw = fs5.readFileSync(stateFilePath2, "utf-8");
50429
51093
  const parsed = JSON.parse(raw);
50430
51094
  json2 = JSON.stringify(compactMarathonStateJsonForContextExport(parsed), null, 2);
50431
51095
  } else {
@@ -50446,7 +51110,7 @@ function MarathonApp({
50446
51110
  }, [sessionSnapshots, state.content, state.reasoning, state.tools, stateFilePath2]);
50447
51111
  const handleOpenStateFile = useCallback8(() => {
50448
51112
  setShowSessionMenu(false);
50449
- if (stateFilePath2 && fs4.existsSync(stateFilePath2)) {
51113
+ if (stateFilePath2 && fs5.existsSync(stateFilePath2)) {
50450
51114
  void open4(stateFilePath2);
50451
51115
  showFlash("Opening state file...");
50452
51116
  } else {
@@ -50675,7 +51339,7 @@ function MarathonApp({
50675
51339
  },
50676
51340
  [filteredEvents]
50677
51341
  );
50678
- useInput11((_input, key) => {
51342
+ useInput14((_input, key) => {
50679
51343
  if (_input === "u" && upgradePrompt) {
50680
51344
  void open4(billingPageUrl);
50681
51345
  setUpgradeModalDismissed(true);
@@ -50706,6 +51370,7 @@ function MarathonApp({
50706
51370
  }
50707
51371
  return;
50708
51372
  }
51373
+ if (showSteerComposer) return;
50709
51374
  if (showEventTypeFilter) return;
50710
51375
  if (showSessionMenu) {
50711
51376
  if (key.escape) {
@@ -50761,6 +51426,10 @@ function MarathonApp({
50761
51426
  if (state.phase === "checkpoint" && checkpointRecap) {
50762
51427
  if (!isAllowedCheckpointBrowseKey({ ...key, input: _input }, showFilesPanel || showEventStream || showToolsPanel)) return;
50763
51428
  }
51429
+ if (key.return && (state.phase === "thinking" || state.phase === "streaming" || state.phase === "tool") && !showFilesPanel && !showEventStream && !showToolsPanel && !showReasoningPanel) {
51430
+ setShowSteerComposer(true);
51431
+ return;
51432
+ }
50764
51433
  if (key.shift && key.leftArrow) {
50765
51434
  markCheckpointExploring();
50766
51435
  selectSessionTab(getAdjacentSessionTabKey(allTabs, selectedSessionKey, -1));
@@ -50840,8 +51509,8 @@ function MarathonApp({
50840
51509
  if (_input === "o" && showFilesPanel) {
50841
51510
  const file2 = detailFile ?? trackedFiles[fileCursor];
50842
51511
  if (file2) {
50843
- const filePath = path4.resolve(file2.path);
50844
- if (fs4.existsSync(filePath)) {
51512
+ const filePath = path5.resolve(file2.path);
51513
+ if (fs5.existsSync(filePath)) {
50845
51514
  void open4(filePath);
50846
51515
  showFlash(`Opening ${file2.path}`);
50847
51516
  } else {
@@ -51225,14 +51894,14 @@ function MarathonApp({
51225
51894
  const overviewTotalLines = useMemo11(() => displayedContent.split("\n").length, [displayedContent]);
51226
51895
  const upgradeModalWidth = Math.max(24, Math.min(terminalWidth - 6, 88));
51227
51896
  const showUpgradeBrowseHint = canBrowseAfterUpgradeError && selectedIsLive && isBlank(displayedContent) && isBlank(displayedReasoning) && displayedTools.length === 0 && displayedEvents.length === 0;
51228
- return /* @__PURE__ */ jsxs26(
51229
- Box28,
51897
+ return /* @__PURE__ */ jsxs29(
51898
+ Box31,
51230
51899
  {
51231
51900
  flexDirection: "column",
51232
51901
  height: terminalRows,
51233
51902
  width: terminalWidth,
51234
51903
  children: [
51235
- /* @__PURE__ */ jsx33(
51904
+ /* @__PURE__ */ jsx36(
51236
51905
  SessionHeader,
51237
51906
  {
51238
51907
  sessionName: taskName,
@@ -51252,8 +51921,8 @@ function MarathonApp({
51252
51921
  currentMilestone
51253
51922
  }
51254
51923
  ),
51255
- /* @__PURE__ */ jsx33(Box28, { marginLeft: 1, children: /* @__PURE__ */ jsx33(ScreenTabs, { activeTab: activeScreen, width: terminalWidth - 1, shortcutHint: "Tab: next screen" }) }),
51256
- hasTabs && /* @__PURE__ */ jsx33(Box28, { width: terminalWidth, marginBottom: 1, marginLeft: 1, children: /* @__PURE__ */ jsx33(
51924
+ /* @__PURE__ */ jsx36(Box31, { marginLeft: 1, children: /* @__PURE__ */ jsx36(ScreenTabs, { activeTab: activeScreen, width: terminalWidth - 1, shortcutHint: "Tab: next screen" }) }),
51925
+ hasTabs && /* @__PURE__ */ jsx36(Box31, { width: terminalWidth, marginBottom: 1, marginLeft: 1, children: /* @__PURE__ */ jsx36(
51257
51926
  SessionTabs,
51258
51927
  {
51259
51928
  tabs: visibleTabs.tabs,
@@ -51262,13 +51931,13 @@ function MarathonApp({
51262
51931
  shortcutHint: allTabs.length > 1 ? "Shift+\u2190/\u2192: select run" : void 0
51263
51932
  }
51264
51933
  ) }),
51265
- showFilesPanel ? /* @__PURE__ */ jsx33(
51266
- Box28,
51934
+ showFilesPanel ? /* @__PURE__ */ jsx36(
51935
+ Box31,
51267
51936
  {
51268
51937
  flexDirection: "column",
51269
51938
  height: adjustedContentHeight,
51270
51939
  overflow: "hidden",
51271
- children: /* @__PURE__ */ jsx33(
51940
+ children: /* @__PURE__ */ jsx36(
51272
51941
  FilesPanel,
51273
51942
  {
51274
51943
  files: trackedFiles,
@@ -51284,13 +51953,13 @@ function MarathonApp({
51284
51953
  }
51285
51954
  )
51286
51955
  }
51287
- ) : showReasoningPanel ? /* @__PURE__ */ jsx33(
51288
- Box28,
51956
+ ) : showReasoningPanel ? /* @__PURE__ */ jsx36(
51957
+ Box31,
51289
51958
  {
51290
51959
  flexDirection: "column",
51291
51960
  height: adjustedContentHeight,
51292
51961
  overflow: "hidden",
51293
- children: /* @__PURE__ */ jsx33(
51962
+ children: /* @__PURE__ */ jsx36(
51294
51963
  ReasoningPanel,
51295
51964
  {
51296
51965
  reasoning: displayedReasoning,
@@ -51300,13 +51969,13 @@ function MarathonApp({
51300
51969
  }
51301
51970
  )
51302
51971
  }
51303
- ) : showEventStream ? /* @__PURE__ */ jsx33(
51304
- Box28,
51972
+ ) : showEventStream ? /* @__PURE__ */ jsx36(
51973
+ Box31,
51305
51974
  {
51306
51975
  flexDirection: "column",
51307
51976
  height: adjustedContentHeight,
51308
51977
  overflow: "hidden",
51309
- children: /* @__PURE__ */ jsx33(
51978
+ children: /* @__PURE__ */ jsx36(
51310
51979
  EventStreamPanel,
51311
51980
  {
51312
51981
  events: filteredEvents,
@@ -51321,13 +51990,13 @@ function MarathonApp({
51321
51990
  }
51322
51991
  )
51323
51992
  }
51324
- ) : showToolsPanel ? /* @__PURE__ */ jsx33(
51325
- Box28,
51993
+ ) : showToolsPanel ? /* @__PURE__ */ jsx36(
51994
+ Box31,
51326
51995
  {
51327
51996
  flexDirection: "column",
51328
51997
  height: adjustedContentHeight,
51329
51998
  overflow: "hidden",
51330
- children: /* @__PURE__ */ jsx33(
51999
+ children: /* @__PURE__ */ jsx36(
51331
52000
  ToolsPanel,
51332
52001
  {
51333
52002
  tools: displayedTools,
@@ -51339,14 +52008,14 @@ function MarathonApp({
51339
52008
  }
51340
52009
  )
51341
52010
  }
51342
- ) : state.phase === "checkpoint" && checkpointRecap ? /* @__PURE__ */ jsxs26(
51343
- Box28,
52011
+ ) : state.phase === "checkpoint" && checkpointRecap ? /* @__PURE__ */ jsxs29(
52012
+ Box31,
51344
52013
  {
51345
52014
  flexDirection: isStacked ? "column" : "row",
51346
52015
  height: adjustedContentHeight,
51347
52016
  children: [
51348
- /* @__PURE__ */ jsxs26(
51349
- Box28,
52017
+ /* @__PURE__ */ jsxs29(
52018
+ Box31,
51350
52019
  {
51351
52020
  flexDirection: "column",
51352
52021
  flexGrow: 1,
@@ -51354,7 +52023,7 @@ function MarathonApp({
51354
52023
  marginLeft: contentMarginLeft,
51355
52024
  marginRight: contentMarginRight,
51356
52025
  children: [
51357
- /* @__PURE__ */ jsx33(Box28, { flexDirection: "row", flexGrow: 1, overflow: "hidden", marginBottom: 1, children: /* @__PURE__ */ jsx33(Box28, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx33(
52026
+ /* @__PURE__ */ jsx36(Box31, { flexDirection: "row", flexGrow: 1, overflow: "hidden", marginBottom: 1, children: /* @__PURE__ */ jsx36(Box31, { flexDirection: "column", flexGrow: 1, children: /* @__PURE__ */ jsx36(
51358
52027
  OverviewTranscriptPane,
51359
52028
  {
51360
52029
  content: displayedContent,
@@ -51367,7 +52036,7 @@ function MarathonApp({
51367
52036
  contentHeight: adjustedContentHeight
51368
52037
  }
51369
52038
  ) }) }),
51370
- /* @__PURE__ */ jsx33(
52039
+ /* @__PURE__ */ jsx36(
51371
52040
  CheckpointPrompt,
51372
52041
  {
51373
52042
  onSubmit: handleCheckpointSubmit,
@@ -51375,6 +52044,8 @@ function MarathonApp({
51375
52044
  onCopySession: handleCopySession,
51376
52045
  onCopySessionTrimmed: handleCopySessionTrimmed,
51377
52046
  onOpenStateFile: handleOpenStateFile,
52047
+ onLoadTreeView: handleLoadTreeView,
52048
+ onLoadForkCandidates: handleLoadForkCandidates,
51378
52049
  timeout: checkpointTimeout ?? 10,
51379
52050
  isTerminal: isTerminalCheckpoint,
51380
52051
  currentModel,
@@ -51386,7 +52057,7 @@ function MarathonApp({
51386
52057
  ]
51387
52058
  }
51388
52059
  ),
51389
- !isStacked && (hasTools || hasReasoning) && /* @__PURE__ */ jsx33(
52060
+ !isStacked && (hasTools || hasReasoning) && /* @__PURE__ */ jsx36(
51390
52061
  OverviewActivityPane,
51391
52062
  {
51392
52063
  tools: displayedTools,
@@ -51398,22 +52069,22 @@ function MarathonApp({
51398
52069
  )
51399
52070
  ]
51400
52071
  }
51401
- ) : /* @__PURE__ */ jsxs26(
51402
- Box28,
52072
+ ) : /* @__PURE__ */ jsxs29(
52073
+ Box31,
51403
52074
  {
51404
52075
  flexDirection: isStacked ? "column" : "row",
51405
52076
  height: adjustedContentHeight,
51406
52077
  overflow: "hidden",
51407
52078
  children: [
51408
- /* @__PURE__ */ jsx33(
51409
- Box28,
52079
+ /* @__PURE__ */ jsx36(
52080
+ Box31,
51410
52081
  {
51411
52082
  flexDirection: "column",
51412
52083
  flexGrow: 1,
51413
52084
  flexShrink: 1,
51414
52085
  marginLeft: contentMarginLeft,
51415
52086
  marginRight: contentMarginRight,
51416
- children: /* @__PURE__ */ jsx33(
52087
+ children: /* @__PURE__ */ jsx36(
51417
52088
  OverviewTranscriptPane,
51418
52089
  {
51419
52090
  content: displayedContent,
@@ -51438,7 +52109,7 @@ function MarathonApp({
51438
52109
  )
51439
52110
  }
51440
52111
  ),
51441
- (hasTools || hasReasoning) && /* @__PURE__ */ jsx33(
52112
+ (hasTools || hasReasoning) && /* @__PURE__ */ jsx36(
51442
52113
  OverviewActivityPane,
51443
52114
  {
51444
52115
  tools: displayedTools,
@@ -51452,8 +52123,8 @@ function MarathonApp({
51452
52123
  ]
51453
52124
  }
51454
52125
  ),
51455
- showHelpOverlay && /* @__PURE__ */ jsx33(
51456
- Box28,
52126
+ showHelpOverlay && /* @__PURE__ */ jsx36(
52127
+ Box31,
51457
52128
  {
51458
52129
  width: terminalWidth,
51459
52130
  marginTop: -adjustedContentHeight,
@@ -51461,8 +52132,8 @@ function MarathonApp({
51461
52132
  justifyContent: "center",
51462
52133
  alignItems: "center",
51463
52134
  flexShrink: 0,
51464
- backgroundColor: theme31.surfaceMuted,
51465
- children: /* @__PURE__ */ jsx33(
52135
+ backgroundColor: theme34.surfaceMuted,
52136
+ children: /* @__PURE__ */ jsx36(
51466
52137
  HelpPanel,
51467
52138
  {
51468
52139
  width: terminalWidth,
@@ -51473,8 +52144,8 @@ function MarathonApp({
51473
52144
  )
51474
52145
  }
51475
52146
  ),
51476
- showEventTypeFilter && /* @__PURE__ */ jsx33(
51477
- Box28,
52147
+ showEventTypeFilter && /* @__PURE__ */ jsx36(
52148
+ Box31,
51478
52149
  {
51479
52150
  width: terminalWidth,
51480
52151
  marginTop: -adjustedContentHeight,
@@ -51482,8 +52153,8 @@ function MarathonApp({
51482
52153
  justifyContent: "center",
51483
52154
  alignItems: "center",
51484
52155
  flexShrink: 0,
51485
- backgroundColor: theme31.surfaceMuted,
51486
- children: /* @__PURE__ */ jsx33(
52156
+ backgroundColor: theme34.surfaceMuted,
52157
+ children: /* @__PURE__ */ jsx36(
51487
52158
  EventTypeFilter,
51488
52159
  {
51489
52160
  eventTypes: stableSeenEventTypesRef.current,
@@ -51498,8 +52169,8 @@ function MarathonApp({
51498
52169
  )
51499
52170
  }
51500
52171
  ),
51501
- showSessionMenu && /* @__PURE__ */ jsx33(
51502
- Box28,
52172
+ showSessionMenu && /* @__PURE__ */ jsx36(
52173
+ Box31,
51503
52174
  {
51504
52175
  width: terminalWidth,
51505
52176
  marginTop: -adjustedContentHeight,
@@ -51507,8 +52178,8 @@ function MarathonApp({
51507
52178
  justifyContent: "center",
51508
52179
  alignItems: "center",
51509
52180
  flexShrink: 0,
51510
- backgroundColor: theme31.surfaceMuted,
51511
- children: /* @__PURE__ */ jsx33(
52181
+ backgroundColor: theme34.surfaceMuted,
52182
+ children: /* @__PURE__ */ jsx36(
51512
52183
  SessionActionMenu,
51513
52184
  {
51514
52185
  onCopySession: handleCopySession,
@@ -51518,13 +52189,13 @@ function MarathonApp({
51518
52189
  onOpenDashboard: handleOpenDashboard,
51519
52190
  onClose: () => setShowSessionMenu(false),
51520
52191
  hasDashboard: !!agentPageUrl,
51521
- hasStateFile: !!stateFilePath2 && fs4.existsSync(stateFilePath2)
52192
+ hasStateFile: !!stateFilePath2 && fs5.existsSync(stateFilePath2)
51522
52193
  }
51523
52194
  )
51524
52195
  }
51525
52196
  ),
51526
- showUpgradeModal && upgradePrompt && /* @__PURE__ */ jsx33(
51527
- Box28,
52197
+ showUpgradeModal && upgradePrompt && /* @__PURE__ */ jsx36(
52198
+ Box31,
51528
52199
  {
51529
52200
  marginTop: -adjustedContentHeight,
51530
52201
  marginBottom: -adjustedContentHeight,
@@ -51532,15 +52203,43 @@ function MarathonApp({
51532
52203
  justifyContent: "center",
51533
52204
  alignItems: "center",
51534
52205
  flexShrink: 0,
51535
- children: /* @__PURE__ */ jsx33(UpgradeModal, { prompt: upgradePrompt, width: upgradeModalWidth })
52206
+ children: /* @__PURE__ */ jsx36(UpgradeModal, { prompt: upgradePrompt, width: upgradeModalWidth })
52207
+ }
52208
+ ),
52209
+ showSteerComposer && /* @__PURE__ */ jsx36(
52210
+ SteerComposer,
52211
+ {
52212
+ initialDraft: steerDraft,
52213
+ onSubmit: (message, kind) => {
52214
+ if (kind === "steer") {
52215
+ steeringQueueRef.current.push(message);
52216
+ setQueuedSteerCount(steeringQueueRef.current.length);
52217
+ } else {
52218
+ followUpQueueRef.current.push(message);
52219
+ setQueuedFollowUpCount(followUpQueueRef.current.length);
52220
+ }
52221
+ setSteerDraft("");
52222
+ setShowSteerComposer(false);
52223
+ },
52224
+ onCancel: (draft) => {
52225
+ setSteerDraft(draft);
52226
+ setShowSteerComposer(false);
52227
+ }
51536
52228
  }
51537
52229
  ),
51538
- /* @__PURE__ */ jsx33(
52230
+ !showSteerComposer && (queuedSteerCount > 0 || queuedFollowUpCount > 0) && /* @__PURE__ */ jsxs29(Text32, { color: theme34.textMuted, children: [
52231
+ " ",
52232
+ [
52233
+ ...queuedSteerCount > 0 ? [`${queuedSteerCount} steering message${queuedSteerCount === 1 ? "" : "s"} queued (delivers next turn)`] : [],
52234
+ ...queuedFollowUpCount > 0 ? [`${queuedFollowUpCount} follow-up queued (after all work)`] : []
52235
+ ].join(separator)
52236
+ ] }),
52237
+ /* @__PURE__ */ jsx36(
51539
52238
  StatusBar,
51540
52239
  {
51541
- left: /* @__PURE__ */ jsxs26(Text29, { color: theme31.textMuted, children: [
52240
+ left: /* @__PURE__ */ jsxs29(Text32, { color: theme34.textMuted, children: [
51542
52241
  `Model: ${currentModel}${currentSandbox ? `${separator}Sandbox: ${currentSandbox}` : ""}`,
51543
- previewUrl && /* @__PURE__ */ jsx33(Text29, { color: theme31.accent, children: `${separator}\x1B]8;;${previewUrl}\x07preview\x1B]8;;\x07` })
52242
+ previewUrl && /* @__PURE__ */ jsx36(Text32, { color: theme34.accent, children: `${separator}\x1B]8;;${previewUrl}\x07preview\x1B]8;;\x07` })
51544
52243
  ] }),
51545
52244
  center: showFilesPanel ? filesCenter : showEventStream ? detailCenter : showToolsPanel ? toolsCenter : void 0,
51546
52245
  right: statusRight
@@ -51552,11 +52251,11 @@ function MarathonApp({
51552
52251
  }
51553
52252
 
51554
52253
  // src/ink/marathon/MarathonStartupShell.tsx
51555
- import { useEffect as useEffect26, useRef as useRef10, useState as useState29 } from "react";
51556
- import { Box as Box29, Text as Text30, useApp as useApp5, useInput as useInput12, useStdout as useStdout6 } from "ink";
51557
- import { theme as theme32 } from "@runtypelabs/ink-components";
52254
+ import { useEffect as useEffect26, useRef as useRef10, useState as useState32 } from "react";
52255
+ import { Box as Box32, Text as Text33, useApp as useApp5, useInput as useInput15, useStdout as useStdout6 } from "ink";
52256
+ import { theme as theme35 } from "@runtypelabs/ink-components";
51558
52257
  import { AnimatedVariant, StartupGridIconCompactLightInverted } from "@runtypelabs/terminal-animations";
51559
- import { jsx as jsx34, jsxs as jsxs27 } from "react/jsx-runtime";
52258
+ import { jsx as jsx37, jsxs as jsxs30 } from "react/jsx-runtime";
51560
52259
  var SCROLL_HINT = "\u2191\u2193 Enter 1-3";
51561
52260
  var PROMPT_COLUMN_MAX = 68;
51562
52261
  var MIN_HOLD_MS = 1500;
@@ -51617,15 +52316,15 @@ function MarathonStartupShell({
51617
52316
  const dismissResolverRef = useRef10(null);
51618
52317
  const transitionPromiseRef = useRef10(null);
51619
52318
  const latestAppPropsRef = useRef10(marathonAppProps);
51620
- const [statusMessage, setStatusMessage] = useState29("preparing marathon");
51621
- const [scene, setScene] = useState29("splash");
51622
- const [transition, setTransition] = useState29(null);
51623
- const [prompt, setPrompt] = useState29(null);
51624
- const [modelChoices, setModelChoices] = useState29(null);
51625
- const [currentModel, setCurrentModel] = useState29("default");
51626
- const [playbookConfirm, setPlaybookConfirm] = useState29(null);
51627
- const [selectedPromptIndex, setSelectedPromptIndex] = useState29(0);
51628
- const [backgroundVariantId] = useState29(
52319
+ const [statusMessage, setStatusMessage] = useState32("preparing marathon");
52320
+ const [scene, setScene] = useState32("splash");
52321
+ const [transition, setTransition] = useState32(null);
52322
+ const [prompt, setPrompt] = useState32(null);
52323
+ const [modelChoices, setModelChoices] = useState32(null);
52324
+ const [currentModel, setCurrentModel] = useState32("default");
52325
+ const [playbookConfirm, setPlaybookConfirm] = useState32(null);
52326
+ const [selectedPromptIndex, setSelectedPromptIndex] = useState32(0);
52327
+ const [backgroundVariantId] = useState32(
51629
52328
  () => STARTUP_BACKGROUND_VARIANTS[Math.floor(Math.random() * STARTUP_BACKGROUND_VARIANTS.length)]
51630
52329
  );
51631
52330
  latestAppPropsRef.current = marathonAppProps;
@@ -51719,7 +52418,7 @@ function MarathonStartupShell({
51719
52418
  startupRef.current = null;
51720
52419
  };
51721
52420
  }, [startupRef]);
51722
- useInput12(
52421
+ useInput15(
51723
52422
  (input, key) => {
51724
52423
  if (key.ctrl && input === "c") {
51725
52424
  process.kill(process.pid, "SIGINT");
@@ -51756,7 +52455,7 @@ function MarathonStartupShell({
51756
52455
  },
51757
52456
  { isActive: scene !== "app" && !playbookConfirm && !modelChoices }
51758
52457
  );
51759
- useInput12(
52458
+ useInput15(
51760
52459
  (input, key) => {
51761
52460
  if (key.ctrl && input === "c") {
51762
52461
  process.kill(process.pid, "SIGINT");
@@ -51825,17 +52524,17 @@ function MarathonStartupShell({
51825
52524
  const selectedChoice = prompt?.choices[selectedPromptIndex];
51826
52525
  const contentWidth = prompt || modelChoices || playbookConfirm ? promptColumnWidth : void 0;
51827
52526
  if (scene === "app" && marathonAppProps) {
51828
- return /* @__PURE__ */ jsx34(MarathonApp, { ...marathonAppProps });
52527
+ return /* @__PURE__ */ jsx37(MarathonApp, { ...marathonAppProps });
51829
52528
  }
51830
- return /* @__PURE__ */ jsxs27(Box29, { width: terminalWidth, height: terminalRows, backgroundColor: theme32.background, children: [
51831
- /* @__PURE__ */ jsx34(
51832
- Box29,
52529
+ return /* @__PURE__ */ jsxs30(Box32, { width: terminalWidth, height: terminalRows, backgroundColor: theme35.background, children: [
52530
+ /* @__PURE__ */ jsx37(
52531
+ Box32,
51833
52532
  {
51834
52533
  position: "absolute",
51835
52534
  width: terminalWidth,
51836
52535
  height: terminalRows,
51837
52536
  overflow: "hidden",
51838
- children: /* @__PURE__ */ jsx34(
52537
+ children: /* @__PURE__ */ jsx37(
51839
52538
  AnimatedVariant,
51840
52539
  {
51841
52540
  variantId: backgroundVariantId,
@@ -51846,8 +52545,8 @@ function MarathonStartupShell({
51846
52545
  )
51847
52546
  }
51848
52547
  ),
51849
- /* @__PURE__ */ jsx34(
51850
- Box29,
52548
+ /* @__PURE__ */ jsx37(
52549
+ Box32,
51851
52550
  {
51852
52551
  position: "absolute",
51853
52552
  width: terminalWidth,
@@ -51856,11 +52555,11 @@ function MarathonStartupShell({
51856
52555
  justifyContent: "flex-start",
51857
52556
  paddingX: 1,
51858
52557
  paddingY: 1,
51859
- children: /* @__PURE__ */ jsx34(StartupGridIconCompactLightInverted, { autoplay: false })
52558
+ children: /* @__PURE__ */ jsx37(StartupGridIconCompactLightInverted, { autoplay: false })
51860
52559
  }
51861
52560
  ),
51862
- version2 && /* @__PURE__ */ jsx34(
51863
- Box29,
52561
+ version2 && /* @__PURE__ */ jsx37(
52562
+ Box32,
51864
52563
  {
51865
52564
  position: "absolute",
51866
52565
  width: terminalWidth,
@@ -51869,30 +52568,30 @@ function MarathonStartupShell({
51869
52568
  justifyContent: "flex-end",
51870
52569
  paddingX: 2,
51871
52570
  paddingY: 1,
51872
- children: /* @__PURE__ */ jsxs27(Text30, { color: theme32.border, children: [
52571
+ children: /* @__PURE__ */ jsxs30(Text33, { color: theme35.border, children: [
51873
52572
  "v",
51874
52573
  version2
51875
52574
  ] })
51876
52575
  }
51877
52576
  ),
51878
- /* @__PURE__ */ jsx34(
51879
- Box29,
52577
+ /* @__PURE__ */ jsx37(
52578
+ Box32,
51880
52579
  {
51881
52580
  width: terminalWidth,
51882
52581
  height: terminalRows,
51883
52582
  flexDirection: "column",
51884
52583
  justifyContent: "center",
51885
52584
  alignItems: "center",
51886
- children: /* @__PURE__ */ jsxs27(
51887
- Box29,
52585
+ children: /* @__PURE__ */ jsxs30(
52586
+ Box32,
51888
52587
  {
51889
52588
  flexDirection: "column",
51890
52589
  alignItems: prompt || modelChoices || playbookConfirm ? "stretch" : "center",
51891
- backgroundColor: theme32.background,
52590
+ backgroundColor: theme35.background,
51892
52591
  paddingX: 2,
51893
52592
  paddingY: 1,
51894
52593
  children: [
51895
- !prompt && !modelChoices && !playbookConfirm && /* @__PURE__ */ jsx34(Text30, { color: theme32.textMuted, children: statusMessage }),
52594
+ !prompt && !modelChoices && !playbookConfirm && /* @__PURE__ */ jsx37(Text33, { color: theme35.textMuted, children: statusMessage }),
51896
52595
  playbookConfirm && !modelChoices && (() => {
51897
52596
  const milestoneCount = playbookConfirm.milestoneNames.length;
51898
52597
  const hasEdits = JSON.stringify(playbookConfirm.milestoneModels) !== JSON.stringify(playbookConfirm.originalModels);
@@ -51901,33 +52600,33 @@ function MarathonStartupShell({
51901
52600
  "Use single model instead",
51902
52601
  ...hasEdits ? ["Discard changes"] : []
51903
52602
  ];
51904
- return /* @__PURE__ */ jsxs27(Box29, { width: contentWidth, flexDirection: "column", marginTop: 1, children: [
51905
- /* @__PURE__ */ jsxs27(Text30, { bold: true, color: theme32.text, children: [
52603
+ return /* @__PURE__ */ jsxs30(Box32, { width: contentWidth, flexDirection: "column", marginTop: 1, children: [
52604
+ /* @__PURE__ */ jsxs30(Text33, { bold: true, color: theme35.text, children: [
51906
52605
  "Playbook: ",
51907
52606
  playbookConfirm.name
51908
52607
  ] }),
51909
- /* @__PURE__ */ jsx34(Box29, { marginTop: 1, flexDirection: "column", children: playbookConfirm.milestoneNames.map((milestone, i) => {
52608
+ /* @__PURE__ */ jsx37(Box32, { marginTop: 1, flexDirection: "column", children: playbookConfirm.milestoneNames.map((milestone, i) => {
51910
52609
  const isSelected = i === playbookConfirm.selectedIndex;
51911
52610
  const model = playbookConfirm.milestoneModels[milestone];
51912
52611
  const wasEdited = model !== playbookConfirm.originalModels[milestone];
51913
- return /* @__PURE__ */ jsxs27(Box29, { children: [
51914
- /* @__PURE__ */ jsx34(Text30, { color: isSelected ? theme32.accent : theme32.textSubtle, children: isSelected ? "\u203A " : " " }),
51915
- /* @__PURE__ */ jsx34(Text30, { color: isSelected ? theme32.text : theme32.textSubtle, bold: isSelected, children: milestone.padEnd(16) }),
51916
- /* @__PURE__ */ jsx34(Text30, { color: isSelected ? theme32.accent : theme32.textMuted, children: model }),
51917
- wasEdited && /* @__PURE__ */ jsx34(Text30, { color: theme32.textSubtle, children: " (edited)" })
52612
+ return /* @__PURE__ */ jsxs30(Box32, { children: [
52613
+ /* @__PURE__ */ jsx37(Text33, { color: isSelected ? theme35.accent : theme35.textSubtle, children: isSelected ? "\u203A " : " " }),
52614
+ /* @__PURE__ */ jsx37(Text33, { color: isSelected ? theme35.text : theme35.textSubtle, bold: isSelected, children: milestone.padEnd(16) }),
52615
+ /* @__PURE__ */ jsx37(Text33, { color: isSelected ? theme35.accent : theme35.textMuted, children: model }),
52616
+ wasEdited && /* @__PURE__ */ jsx37(Text33, { color: theme35.textSubtle, children: " (edited)" })
51918
52617
  ] }, milestone);
51919
52618
  }) }),
51920
- /* @__PURE__ */ jsx34(Box29, { marginTop: 1, flexDirection: "column", children: actions.map((label, ai) => {
52619
+ /* @__PURE__ */ jsx37(Box32, { marginTop: 1, flexDirection: "column", children: actions.map((label, ai) => {
51921
52620
  const isSelected = playbookConfirm.selectedIndex === milestoneCount + ai;
51922
- return /* @__PURE__ */ jsxs27(Box29, { children: [
51923
- /* @__PURE__ */ jsx34(Text30, { color: isSelected ? theme32.accent : theme32.textSubtle, children: isSelected ? "\u203A " : " " }),
51924
- /* @__PURE__ */ jsx34(Text30, { color: isSelected ? theme32.text : theme32.textSubtle, bold: isSelected, children: label })
52621
+ return /* @__PURE__ */ jsxs30(Box32, { children: [
52622
+ /* @__PURE__ */ jsx37(Text33, { color: isSelected ? theme35.accent : theme35.textSubtle, children: isSelected ? "\u203A " : " " }),
52623
+ /* @__PURE__ */ jsx37(Text33, { color: isSelected ? theme35.text : theme35.textSubtle, bold: isSelected, children: label })
51925
52624
  ] }, label);
51926
52625
  }) }),
51927
- /* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text30, { color: theme32.border, children: "\u2191\u2193 navigate \xB7 Enter select" }) })
52626
+ /* @__PURE__ */ jsx37(Box32, { marginTop: 1, children: /* @__PURE__ */ jsx37(Text33, { color: theme35.border, children: "\u2191\u2193 navigate \xB7 Enter select" }) })
51928
52627
  ] });
51929
52628
  })(),
51930
- modelChoices && /* @__PURE__ */ jsx34(Box29, { width: contentWidth, flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsx34(
52629
+ modelChoices && /* @__PURE__ */ jsx37(Box32, { width: contentWidth, flexDirection: "column", marginTop: 1, children: /* @__PURE__ */ jsx37(
51931
52630
  ModelPicker,
51932
52631
  {
51933
52632
  currentModel,
@@ -51945,27 +52644,27 @@ function MarathonStartupShell({
51945
52644
  }
51946
52645
  }
51947
52646
  ) }),
51948
- prompt && /* @__PURE__ */ jsxs27(Box29, { width: contentWidth, flexDirection: "column", marginTop: 1, children: [
51949
- /* @__PURE__ */ jsx34(Text30, { bold: true, color: theme32.text, children: promptShellModel?.heading }),
51950
- promptShellModel?.task && /* @__PURE__ */ jsxs27(Box29, { marginTop: 1, children: [
51951
- /* @__PURE__ */ jsx34(Text30, { color: theme32.textSubtle, children: "task " }),
51952
- /* @__PURE__ */ jsx34(Text30, { color: theme32.text, children: promptShellModel.task })
52647
+ prompt && /* @__PURE__ */ jsxs30(Box32, { width: contentWidth, flexDirection: "column", marginTop: 1, children: [
52648
+ /* @__PURE__ */ jsx37(Text33, { bold: true, color: theme35.text, children: promptShellModel?.heading }),
52649
+ promptShellModel?.task && /* @__PURE__ */ jsxs30(Box32, { marginTop: 1, children: [
52650
+ /* @__PURE__ */ jsx37(Text33, { color: theme35.textSubtle, children: "task " }),
52651
+ /* @__PURE__ */ jsx37(Text33, { color: theme35.text, children: promptShellModel.task })
51953
52652
  ] }),
51954
- promptShellModel?.filePath && /* @__PURE__ */ jsxs27(Box29, { children: [
51955
- /* @__PURE__ */ jsx34(Text30, { color: theme32.textSubtle, children: "state " }),
51956
- /* @__PURE__ */ jsx34(Text30, { color: theme32.textSubtle, children: promptShellModel.filePath })
52653
+ promptShellModel?.filePath && /* @__PURE__ */ jsxs30(Box32, { children: [
52654
+ /* @__PURE__ */ jsx37(Text33, { color: theme35.textSubtle, children: "state " }),
52655
+ /* @__PURE__ */ jsx37(Text33, { color: theme35.textSubtle, children: promptShellModel.filePath })
51957
52656
  ] }),
51958
- promptShellModel?.metaLine && /* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text30, { color: theme32.textSubtle, children: promptShellModel.metaLine }) }),
51959
- /* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text30, { color: theme32.textSubtle, children: prompt.hint }) }),
51960
- /* @__PURE__ */ jsx34(Box29, { flexDirection: "column", marginTop: 1, children: prompt.choices.map((choice, index) => {
52657
+ promptShellModel?.metaLine && /* @__PURE__ */ jsx37(Box32, { marginTop: 1, children: /* @__PURE__ */ jsx37(Text33, { color: theme35.textSubtle, children: promptShellModel.metaLine }) }),
52658
+ /* @__PURE__ */ jsx37(Box32, { marginTop: 1, children: /* @__PURE__ */ jsx37(Text33, { color: theme35.textSubtle, children: prompt.hint }) }),
52659
+ /* @__PURE__ */ jsx37(Box32, { flexDirection: "column", marginTop: 1, children: prompt.choices.map((choice, index) => {
51961
52660
  const isSelected = index === selectedPromptIndex;
51962
- return /* @__PURE__ */ jsxs27(Box29, { marginTop: index === 0 ? 0 : 1, children: [
51963
- /* @__PURE__ */ jsx34(Text30, { color: isSelected ? theme32.accent : theme32.textSubtle, bold: isSelected, children: isSelected ? "\u203A " : " " }),
51964
- /* @__PURE__ */ jsx34(Text30, { color: isSelected ? theme32.text : theme32.textSubtle, bold: isSelected, children: `${index + 1} ${choice.label}` })
52661
+ return /* @__PURE__ */ jsxs30(Box32, { marginTop: index === 0 ? 0 : 1, children: [
52662
+ /* @__PURE__ */ jsx37(Text33, { color: isSelected ? theme35.accent : theme35.textSubtle, bold: isSelected, children: isSelected ? "\u203A " : " " }),
52663
+ /* @__PURE__ */ jsx37(Text33, { color: isSelected ? theme35.text : theme35.textSubtle, bold: isSelected, children: `${index + 1} ${choice.label}` })
51965
52664
  ] }, choice.value);
51966
52665
  }) }),
51967
- selectedChoice && /* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text30, { color: theme32.textSubtle, children: selectedChoice.description }) }),
51968
- /* @__PURE__ */ jsx34(Box29, { marginTop: 1, children: /* @__PURE__ */ jsx34(Text30, { color: theme32.border, children: SCROLL_HINT }) })
52666
+ selectedChoice && /* @__PURE__ */ jsx37(Box32, { marginTop: 1, children: /* @__PURE__ */ jsx37(Text33, { color: theme35.textSubtle, children: selectedChoice.description }) }),
52667
+ /* @__PURE__ */ jsx37(Box32, { marginTop: 1, children: /* @__PURE__ */ jsx37(Text33, { color: theme35.border, children: SCROLL_HINT }) })
51969
52668
  ] })
51970
52669
  ]
51971
52670
  }
@@ -51976,7 +52675,7 @@ function MarathonStartupShell({
51976
52675
  }
51977
52676
 
51978
52677
  // src/commands/agents-task.ts
51979
- import * as fs13 from "fs";
52678
+ import * as fs14 from "fs";
51980
52679
  import {
51981
52680
  RuntypeClient as RuntypeClient2,
51982
52681
  defaultWorkflow,
@@ -51986,14 +52685,14 @@ import {
51986
52685
  } from "@runtypelabs/sdk";
51987
52686
 
51988
52687
  // src/lib/terminal-title.ts
51989
- import path5 from "path";
52688
+ import path6 from "path";
51990
52689
  function setTerminalTitle(title) {
51991
52690
  if (process.stdout.isTTY) {
51992
52691
  process.stdout.write(`\x1B]0;${title}\x07`);
51993
52692
  }
51994
52693
  }
51995
52694
  function getFolderName() {
51996
- return path5.basename(process.cwd());
52695
+ return path6.basename(process.cwd());
51997
52696
  }
51998
52697
  function setCliTitle() {
51999
52698
  setTerminalTitle(`Runtype (${getFolderName()})`);
@@ -52003,30 +52702,30 @@ function setMarathonTitle() {
52003
52702
  }
52004
52703
 
52005
52704
  // src/marathon/checkpoint.ts
52006
- import * as fs6 from "fs";
52007
- import * as path7 from "path";
52705
+ import * as fs7 from "fs";
52706
+ import * as path8 from "path";
52008
52707
 
52009
52708
  // src/config/paths.ts
52010
52709
  import * as os3 from "os";
52011
- import * as path6 from "path";
52710
+ import * as path7 from "path";
52012
52711
  import * as crypto4 from "crypto";
52013
- import * as fs5 from "fs";
52712
+ import * as fs6 from "fs";
52014
52713
  function getRuntypeHomeDir() {
52015
- return process.env.RUNTYPE_STATE_DIR || path6.join(os3.homedir(), ".runtype");
52714
+ return process.env.RUNTYPE_STATE_DIR || path7.join(os3.homedir(), ".runtype");
52016
52715
  }
52017
52716
  function getProjectStateDir(projectDir) {
52018
52717
  const dir = projectDir || process.cwd();
52019
52718
  const hash2 = crypto4.createHash("sha256").update(dir).digest("hex").slice(0, 12);
52020
- const stateDir = path6.join(getRuntypeHomeDir(), "projects", hash2);
52021
- const breadcrumb = path6.join(stateDir, "project-path.txt");
52022
- if (!fs5.existsSync(breadcrumb)) {
52023
- fs5.mkdirSync(stateDir, { recursive: true });
52024
- fs5.writeFileSync(breadcrumb, dir);
52719
+ const stateDir = path7.join(getRuntypeHomeDir(), "projects", hash2);
52720
+ const breadcrumb = path7.join(stateDir, "project-path.txt");
52721
+ if (!fs6.existsSync(breadcrumb)) {
52722
+ fs6.mkdirSync(stateDir, { recursive: true });
52723
+ fs6.writeFileSync(breadcrumb, dir);
52025
52724
  }
52026
52725
  return stateDir;
52027
52726
  }
52028
52727
  function getMarathonStateDir(projectDir) {
52029
- return path6.join(getProjectStateDir(projectDir), "marathons");
52728
+ return path7.join(getProjectStateDir(projectDir), "marathons");
52030
52729
  }
52031
52730
 
52032
52731
  // src/marathon/checkpoint.ts
@@ -52037,12 +52736,12 @@ function stateSafeName(name) {
52037
52736
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
52038
52737
  }
52039
52738
  function marathonArtifactsDir(taskName, stateDir) {
52040
- return path7.join(stateDir || defaultStateDir(), stateSafeName(taskName));
52739
+ return path8.join(stateDir || defaultStateDir(), stateSafeName(taskName));
52041
52740
  }
52042
52741
  function resolveMarathonCheckpointPath(taskName, targetPath, stateDir) {
52043
- const normalizedTargetPath = path7.normalize(targetPath);
52044
- const relativeTargetPath = path7.isAbsolute(normalizedTargetPath) ? path7.relative(process.cwd(), normalizedTargetPath) : normalizedTargetPath;
52045
- return path7.join(
52742
+ const normalizedTargetPath = path8.normalize(targetPath);
52743
+ const relativeTargetPath = path8.isAbsolute(normalizedTargetPath) ? path8.relative(process.cwd(), normalizedTargetPath) : normalizedTargetPath;
52744
+ return path8.join(
52046
52745
  marathonArtifactsDir(taskName, stateDir),
52047
52746
  "checkpoints",
52048
52747
  "original",
@@ -52050,23 +52749,23 @@ function resolveMarathonCheckpointPath(taskName, targetPath, stateDir) {
52050
52749
  );
52051
52750
  }
52052
52751
  function ensureMarathonFileCheckpoint(taskName, targetPath, stateDir) {
52053
- const normalizedTargetPath = path7.resolve(targetPath);
52054
- const relativeTargetPath = path7.relative(process.cwd(), normalizedTargetPath);
52752
+ const normalizedTargetPath = path8.resolve(targetPath);
52753
+ const relativeTargetPath = path8.relative(process.cwd(), normalizedTargetPath);
52055
52754
  if (!relativeTargetPath || relativeTargetPath.startsWith("..")) return void 0;
52056
- if (!fs6.existsSync(normalizedTargetPath)) return void 0;
52057
- if (!fs6.statSync(normalizedTargetPath).isFile()) return void 0;
52755
+ if (!fs7.existsSync(normalizedTargetPath)) return void 0;
52756
+ if (!fs7.statSync(normalizedTargetPath).isFile()) return void 0;
52058
52757
  const normalizedRelativeTargetPath = relativeTargetPath.replace(/\\/g, "/");
52059
52758
  if (normalizedRelativeTargetPath.startsWith(".runtype/")) return void 0;
52060
- if (normalizedTargetPath.startsWith(getRuntypeHomeDir() + path7.sep)) return void 0;
52759
+ if (normalizedTargetPath.startsWith(getRuntypeHomeDir() + path8.sep)) return void 0;
52061
52760
  const checkpointPath = resolveMarathonCheckpointPath(taskName, normalizedTargetPath, stateDir);
52062
- if (fs6.existsSync(checkpointPath)) return checkpointPath;
52063
- fs6.mkdirSync(path7.dirname(checkpointPath), { recursive: true });
52064
- fs6.copyFileSync(normalizedTargetPath, checkpointPath);
52761
+ if (fs7.existsSync(checkpointPath)) return checkpointPath;
52762
+ fs7.mkdirSync(path8.dirname(checkpointPath), { recursive: true });
52763
+ fs7.copyFileSync(normalizedTargetPath, checkpointPath);
52065
52764
  return checkpointPath;
52066
52765
  }
52067
52766
  function restoreMarathonFileCheckpoint(taskName, targetPath, stateDir) {
52068
- const normalizedTargetPath = path7.resolve(targetPath);
52069
- const relativeTargetPath = path7.relative(process.cwd(), normalizedTargetPath);
52767
+ const normalizedTargetPath = path8.resolve(targetPath);
52768
+ const relativeTargetPath = path8.relative(process.cwd(), normalizedTargetPath);
52070
52769
  if (!relativeTargetPath || relativeTargetPath.startsWith("..")) {
52071
52770
  return {
52072
52771
  restored: false,
@@ -52074,15 +52773,15 @@ function restoreMarathonFileCheckpoint(taskName, targetPath, stateDir) {
52074
52773
  };
52075
52774
  }
52076
52775
  const checkpointPath = resolveMarathonCheckpointPath(taskName, normalizedTargetPath, stateDir);
52077
- if (!fs6.existsSync(checkpointPath)) {
52776
+ if (!fs7.existsSync(checkpointPath)) {
52078
52777
  return {
52079
52778
  restored: false,
52080
52779
  checkpointPath,
52081
52780
  error: `No checkpoint found for ${normalizedTargetPath}`
52082
52781
  };
52083
52782
  }
52084
- fs6.mkdirSync(path7.dirname(normalizedTargetPath), { recursive: true });
52085
- fs6.copyFileSync(checkpointPath, normalizedTargetPath);
52783
+ fs7.mkdirSync(path8.dirname(normalizedTargetPath), { recursive: true });
52784
+ fs7.copyFileSync(checkpointPath, normalizedTargetPath);
52086
52785
  return { restored: true, checkpointPath };
52087
52786
  }
52088
52787
 
@@ -52431,8 +53130,8 @@ function isScriptConfigModified(cwd, files) {
52431
53130
  }
52432
53131
 
52433
53132
  // src/marathon/state.ts
52434
- import * as fs7 from "fs";
52435
- import * as path8 from "path";
53133
+ import * as fs8 from "fs";
53134
+ import * as path9 from "path";
52436
53135
  import chalk22 from "chalk";
52437
53136
 
52438
53137
  // src/lib/select-prompt.ts
@@ -52570,7 +53269,7 @@ function stateSafeName2(name) {
52570
53269
  }
52571
53270
  function stateFilePath(name, stateDir) {
52572
53271
  const dir = stateDir || defaultStateDir2();
52573
- return path8.join(dir, `${stateSafeName2(name)}.json`);
53272
+ return path9.join(dir, `${stateSafeName2(name)}.json`);
52574
53273
  }
52575
53274
  function normalizeMarathonStatePath(candidatePath) {
52576
53275
  if (!candidatePath) return void 0;
@@ -52579,15 +53278,15 @@ function normalizeMarathonStatePath(candidatePath) {
52579
53278
  }
52580
53279
  function marathonStatePathExists(candidatePath) {
52581
53280
  if (!candidatePath) return false;
52582
- return fs7.existsSync(path8.resolve(candidatePath));
53281
+ return fs8.existsSync(path9.resolve(candidatePath));
52583
53282
  }
52584
53283
  function isMarathonArtifactStatePath(candidatePath) {
52585
53284
  if (!candidatePath) return false;
52586
53285
  const normalized = normalizeMarathonStatePath(candidatePath)?.toLowerCase();
52587
53286
  if (normalized === ".runtype" || normalized?.startsWith(".runtype/") === true) return true;
52588
- const resolved = path8.resolve(candidatePath);
53287
+ const resolved = path9.resolve(candidatePath);
52589
53288
  const homeStateDir = getRuntypeHomeDir();
52590
- return resolved.startsWith(homeStateDir + path8.sep) || resolved === homeStateDir;
53289
+ return resolved.startsWith(homeStateDir + path9.sep) || resolved === homeStateDir;
52591
53290
  }
52592
53291
  function scoreMarathonCandidatePath(candidatePath) {
52593
53292
  const normalized = candidatePath.toLowerCase();
@@ -52755,15 +53454,15 @@ function sanitizeLoadedMarathonState(state) {
52755
53454
  }
52756
53455
  function loadState(filePath) {
52757
53456
  try {
52758
- const raw = fs7.readFileSync(filePath, "utf-8");
53457
+ const raw = fs8.readFileSync(filePath, "utf-8");
52759
53458
  return sanitizeLoadedMarathonState(JSON.parse(raw));
52760
53459
  } catch {
52761
53460
  return null;
52762
53461
  }
52763
53462
  }
52764
53463
  function saveState(filePath, state, options) {
52765
- const dir = path8.dirname(filePath);
52766
- fs7.mkdirSync(dir, { recursive: true });
53464
+ const dir = path9.dirname(filePath);
53465
+ fs8.mkdirSync(dir, { recursive: true });
52767
53466
  const stateToWrite = options?.stripSnapshotEvents && state.sessionSnapshots?.length ? {
52768
53467
  ...state,
52769
53468
  sessionSnapshots: state.sessionSnapshots.map((snapshot) => ({
@@ -52771,7 +53470,8 @@ function saveState(filePath, state, options) {
52771
53470
  rawEvents: []
52772
53471
  }))
52773
53472
  } : state;
52774
- fs7.writeFileSync(filePath, JSON.stringify(stateToWrite, null, 2));
53473
+ fs8.writeFileSync(filePath, JSON.stringify(stateToWrite, null, 2));
53474
+ syncTreeLogWithState(filePath, state);
52775
53475
  }
52776
53476
  function extractRunTaskResumeState(state) {
52777
53477
  if (!state) return void 0;
@@ -52801,11 +53501,11 @@ function findStateFile(name, stateDir) {
52801
53501
  return stateFilePath(name, stateDir);
52802
53502
  }
52803
53503
  const homePath = stateFilePath(name, getMarathonStateDir());
52804
- if (fs7.existsSync(homePath)) return homePath;
52805
- const oldMarathonPath = stateFilePath(name, path8.join(process.cwd(), ".runtype", "marathons"));
52806
- if (fs7.existsSync(oldMarathonPath)) return oldMarathonPath;
52807
- const oldTaskPath = stateFilePath(name, path8.join(process.cwd(), ".runtype", "tasks"));
52808
- if (fs7.existsSync(oldTaskPath)) return oldTaskPath;
53504
+ if (fs8.existsSync(homePath)) return homePath;
53505
+ const oldMarathonPath = stateFilePath(name, path9.join(process.cwd(), ".runtype", "marathons"));
53506
+ if (fs8.existsSync(oldMarathonPath)) return oldMarathonPath;
53507
+ const oldTaskPath = stateFilePath(name, path9.join(process.cwd(), ".runtype", "tasks"));
53508
+ if (fs8.existsSync(oldTaskPath)) return oldTaskPath;
52809
53509
  return homePath;
52810
53510
  }
52811
53511
  function findLatestStateFile(stateDir) {
@@ -52813,16 +53513,16 @@ function findLatestStateFile(stateDir) {
52813
53513
  // New home-dir location
52814
53514
  getMarathonStateDir(),
52815
53515
  // Old project-dir locations (backward compat)
52816
- path8.join(process.cwd(), ".runtype", "marathons"),
52817
- path8.join(process.cwd(), ".runtype", "tasks")
53516
+ path9.join(process.cwd(), ".runtype", "marathons"),
53517
+ path9.join(process.cwd(), ".runtype", "tasks")
52818
53518
  ];
52819
53519
  let latest = null;
52820
53520
  for (const dir of dirs) {
52821
- if (!fs7.existsSync(dir)) continue;
52822
- const files = fs7.readdirSync(dir).filter((f2) => f2.endsWith(".json"));
53521
+ if (!fs8.existsSync(dir)) continue;
53522
+ const files = fs8.readdirSync(dir).filter((f2) => f2.endsWith(".json"));
52823
53523
  for (const file2 of files) {
52824
- const fullPath = path8.join(dir, file2);
52825
- const stat = fs7.statSync(fullPath);
53524
+ const fullPath = path9.join(dir, file2);
53525
+ const stat = fs8.statSync(fullPath);
52826
53526
  if (!latest || stat.mtimeMs > latest.mtime) {
52827
53527
  latest = { name: file2.replace(".json", ""), filePath: fullPath, mtime: stat.mtimeMs };
52828
53528
  }
@@ -52916,7 +53616,7 @@ async function resolveMarathonStateResolution(options, taskName, filePath, promp
52916
53616
  if (options.fresh) {
52917
53617
  return { action: "fresh" };
52918
53618
  }
52919
- if (!fs7.existsSync(filePath)) {
53619
+ if (!fs8.existsSync(filePath)) {
52920
53620
  return { action: "fresh" };
52921
53621
  }
52922
53622
  if (!allowPrompt) {
@@ -52941,14 +53641,68 @@ function buildResumeCommand(agent, options, parsedSandbox) {
52941
53641
  return `runtype marathon ${agent} --resume${nameFlag}${sessionFlag}${sandboxFlag}`;
52942
53642
  }
52943
53643
 
53644
+ // src/marathon/session-tree-nav.ts
53645
+ function applyCheckpointTreeNavigation(stateFilePath2, navigation) {
53646
+ if (!stateFilePath2) return null;
53647
+ if (!navigation.fork && !navigation.treeHead) return null;
53648
+ const log = loadTreeLog(treeLogPathForStateFile(stateFilePath2));
53649
+ if (!log || !log.headId) return null;
53650
+ const destinationId = navigation.fork ? log.headId : navigation.treeHead;
53651
+ if (!destinationId || !log.byId.has(destinationId)) return null;
53652
+ try {
53653
+ if (!materializeAtEntry(log, destinationId).state) return null;
53654
+ } catch {
53655
+ return null;
53656
+ }
53657
+ try {
53658
+ if (navigation.fork) {
53659
+ appendFork(log, log.headId, {
53660
+ truncateAtMessageIndex: navigation.fork.atMessageIndex,
53661
+ ...navigation.fork.label ? { label: navigation.fork.label } : {}
53662
+ });
53663
+ } else if (navigation.treeHead) {
53664
+ setHead(log, navigation.treeHead);
53665
+ }
53666
+ } catch {
53667
+ return null;
53668
+ }
53669
+ const materialized = materializeAtHead(log);
53670
+ if (!materialized?.state) return null;
53671
+ const anchor = navigation.fork ? findCheckpointAtMessageCount(log, log.headId, navigation.fork.atMessageIndex) : null;
53672
+ const sessionShapedOverrides = anchor && anchor !== materialized.state ? {
53673
+ sessionCount: anchor.sessionCount,
53674
+ sessions: anchor.sessions,
53675
+ lastOutput: anchor.lastOutput,
53676
+ lastStopReason: anchor.lastStopReason
53677
+ } : {};
53678
+ const effectiveSessionCount = sessionShapedOverrides.sessionCount ?? materialized.state.sessionCount;
53679
+ const currentJson = loadState(stateFilePath2);
53680
+ const now = (/* @__PURE__ */ new Date()).toISOString();
53681
+ const { sessionSnapshots: priorSnapshots, ...restJson } = currentJson ?? {};
53682
+ const keptSnapshots = (priorSnapshots ?? []).filter(
53683
+ (snapshot) => snapshot.sessionIndex <= effectiveSessionCount
53684
+ );
53685
+ const mergedState = {
53686
+ ...restJson,
53687
+ ...materialized.state,
53688
+ ...sessionShapedOverrides,
53689
+ messages: materialized.messages,
53690
+ ...keptSnapshots.length > 0 ? { sessionSnapshots: keptSnapshots } : {},
53691
+ updatedAt: now
53692
+ };
53693
+ primeTreeLogSyncFromState(stateFilePath2, log, mergedState);
53694
+ saveState(stateFilePath2, mergedState);
53695
+ return { messages: materialized.messages, mergedState };
53696
+ }
53697
+
52944
53698
  // src/marathon/local-tools.ts
52945
- import * as fs9 from "fs";
52946
- import * as path10 from "path";
53699
+ import * as fs10 from "fs";
53700
+ import * as path11 from "path";
52947
53701
  import { spawnSync } from "child_process";
52948
53702
 
52949
53703
  // src/marathon/repo-discovery.ts
52950
- import * as fs8 from "fs";
52951
- import * as path9 from "path";
53704
+ import * as fs9 from "fs";
53705
+ import * as path10 from "path";
52952
53706
  var IGNORED_REPO_DIRS = /* @__PURE__ */ new Set([
52953
53707
  ".git",
52954
53708
  ".next",
@@ -53046,8 +53800,8 @@ var SEARCH_STOP_WORDS = /* @__PURE__ */ new Set([
53046
53800
  "do"
53047
53801
  ]);
53048
53802
  function normalizeToolPath(toolPath) {
53049
- const resolved = path9.resolve(toolPath || ".");
53050
- return path9.relative(process.cwd(), resolved) || ".";
53803
+ const resolved = path10.resolve(toolPath || ".");
53804
+ return path10.relative(process.cwd(), resolved) || ".";
53051
53805
  }
53052
53806
  function tokenizeSearchQuery(query) {
53053
53807
  return query.toLowerCase().split(/[^a-z0-9./_-]+/g).map((token) => token.trim()).filter((token) => token.length >= 2 && !SEARCH_STOP_WORDS.has(token));
@@ -53056,7 +53810,7 @@ function scoreSearchPath(relativePath) {
53056
53810
  const normalized = relativePath.replace(/\\/g, "/");
53057
53811
  const segments = normalized.split("/");
53058
53812
  const fileName = segments[segments.length - 1] || normalized;
53059
- const extension = path9.extname(fileName).toLowerCase();
53813
+ const extension = path10.extname(fileName).toLowerCase();
53060
53814
  let score = 0;
53061
53815
  if (LOW_SIGNAL_FILE_NAMES.has(fileName)) score -= 50;
53062
53816
  if (segments.some((segment) => LOW_SIGNAL_PATH_SEGMENTS.has(segment))) score -= 15;
@@ -53072,15 +53826,15 @@ function shouldIgnoreRepoEntry(entryPath) {
53072
53826
  const normalized = normalizeToolPath(entryPath).replace(/\\/g, "/");
53073
53827
  if (normalized === ".") return false;
53074
53828
  if (isSensitivePath(normalized)) return true;
53075
- return normalized.split(path9.sep).some((segment) => IGNORED_REPO_DIRS.has(segment));
53829
+ return normalized.split(path10.sep).some((segment) => IGNORED_REPO_DIRS.has(segment));
53076
53830
  }
53077
53831
  function safeReadTextFile(filePath) {
53078
53832
  try {
53079
53833
  const normalized = normalizeToolPath(filePath).replace(/\\/g, "/");
53080
53834
  if (isSensitivePath(normalized)) return null;
53081
- const stat = fs8.statSync(filePath);
53835
+ const stat = fs9.statSync(filePath);
53082
53836
  if (!stat.isFile() || stat.size > MAX_FILE_BYTES_TO_SCAN) return null;
53083
- const buffer = fs8.readFileSync(filePath);
53837
+ const buffer = fs9.readFileSync(filePath);
53084
53838
  if (buffer.includes(0)) return null;
53085
53839
  return buffer.toString("utf-8");
53086
53840
  } catch {
@@ -53088,19 +53842,19 @@ function safeReadTextFile(filePath) {
53088
53842
  }
53089
53843
  }
53090
53844
  function walkRepo(startPath, visitor) {
53091
- if (!fs8.existsSync(startPath) || !fs8.statSync(startPath).isDirectory()) return;
53845
+ if (!fs9.existsSync(startPath) || !fs9.statSync(startPath).isDirectory()) return;
53092
53846
  const stack = [startPath];
53093
53847
  while (stack.length > 0) {
53094
53848
  const currentDir = stack.pop();
53095
53849
  if (!currentDir) continue;
53096
53850
  let entries;
53097
53851
  try {
53098
- entries = fs8.readdirSync(currentDir, { withFileTypes: true });
53852
+ entries = fs9.readdirSync(currentDir, { withFileTypes: true });
53099
53853
  } catch {
53100
53854
  continue;
53101
53855
  }
53102
53856
  for (const entry of entries) {
53103
- const entryPath = path9.join(currentDir, entry.name);
53857
+ const entryPath = path10.join(currentDir, entry.name);
53104
53858
  if (shouldIgnoreRepoEntry(entryPath)) continue;
53105
53859
  const shouldStop = visitor(entryPath, entry);
53106
53860
  if (shouldStop === true) return;
@@ -53138,14 +53892,14 @@ function buildTree(dirPath, maxDepth, depth = 0) {
53138
53892
  if (depth > maxDepth || shouldIgnoreRepoEntry(dirPath)) return [];
53139
53893
  let entries;
53140
53894
  try {
53141
- entries = fs8.readdirSync(dirPath, { withFileTypes: true });
53895
+ entries = fs9.readdirSync(dirPath, { withFileTypes: true });
53142
53896
  } catch (error51) {
53143
53897
  const message = error51 instanceof Error ? error51.message : String(error51);
53144
53898
  return [`${" ".repeat(depth)}[error reading ${normalizeToolPath(dirPath)}: ${message}]`];
53145
53899
  }
53146
53900
  const lines = [];
53147
53901
  for (const entry of entries.sort((a, b) => a.name.localeCompare(b.name))) {
53148
- const entryPath = path9.join(dirPath, entry.name);
53902
+ const entryPath = path10.join(dirPath, entry.name);
53149
53903
  if (shouldIgnoreRepoEntry(entryPath)) continue;
53150
53904
  lines.push(`${" ".repeat(depth)}- ${entry.name}${entry.isDirectory() ? "/" : ""}`);
53151
53905
  if (entry.isDirectory() && depth < maxDepth) {
@@ -53161,40 +53915,40 @@ function stateSafeName3(name) {
53161
53915
  return name.replace(/[^a-zA-Z0-9_-]/g, "_");
53162
53916
  }
53163
53917
  function getOffloadedOutputDir(taskName, stateDir) {
53164
- return path10.join(stateDir || getMarathonStateDir(), stateSafeName3(taskName), "outputs");
53918
+ return path11.join(stateDir || getMarathonStateDir(), stateSafeName3(taskName), "outputs");
53165
53919
  }
53166
53920
  function isPathWithinRoot(targetPath, rootPath) {
53167
- const relativePath = path10.relative(rootPath, targetPath);
53168
- return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
53921
+ const relativePath = path11.relative(rootPath, targetPath);
53922
+ return relativePath === "" || !relativePath.startsWith("..") && !path11.isAbsolute(relativePath);
53169
53923
  }
53170
53924
  function resolveCanonicalToolPath(toolPath, allowMissing) {
53171
- const absolutePath = path10.resolve(toolPath);
53172
- if (fs9.existsSync(absolutePath)) {
53925
+ const absolutePath = path11.resolve(toolPath);
53926
+ if (fs10.existsSync(absolutePath)) {
53173
53927
  return {
53174
- canonicalPath: fs9.realpathSync.native(absolutePath),
53928
+ canonicalPath: fs10.realpathSync.native(absolutePath),
53175
53929
  exists: true
53176
53930
  };
53177
53931
  }
53178
53932
  if (!allowMissing) return null;
53179
53933
  const missingSegments = [];
53180
53934
  let currentPath = absolutePath;
53181
- while (!fs9.existsSync(currentPath)) {
53182
- const parentPath = path10.dirname(currentPath);
53935
+ while (!fs10.existsSync(currentPath)) {
53936
+ const parentPath = path11.dirname(currentPath);
53183
53937
  if (parentPath === currentPath) return null;
53184
- missingSegments.unshift(path10.basename(currentPath));
53938
+ missingSegments.unshift(path11.basename(currentPath));
53185
53939
  currentPath = parentPath;
53186
53940
  }
53187
53941
  return {
53188
- canonicalPath: path10.join(fs9.realpathSync.native(currentPath), ...missingSegments),
53942
+ canonicalPath: path11.join(fs10.realpathSync.native(currentPath), ...missingSegments),
53189
53943
  exists: false
53190
53944
  };
53191
53945
  }
53192
53946
  function canonicalizeAllowedRoot(rootPath) {
53193
- return resolveCanonicalToolPath(rootPath, true)?.canonicalPath || path10.resolve(rootPath);
53947
+ return resolveCanonicalToolPath(rootPath, true)?.canonicalPath || path11.resolve(rootPath);
53194
53948
  }
53195
53949
  function findBlockedWorkspaceSegment(targetPath, workspaceRoot) {
53196
53950
  if (!isPathWithinRoot(targetPath, workspaceRoot)) return void 0;
53197
- const relativePath = path10.relative(workspaceRoot, targetPath).replace(/\\/g, "/");
53951
+ const relativePath = path11.relative(workspaceRoot, targetPath).replace(/\\/g, "/");
53198
53952
  if (!relativePath) return void 0;
53199
53953
  return relativePath.split("/").find((segment) => DIRECT_TOOL_BLOCKED_SEGMENTS.has(segment));
53200
53954
  }
@@ -53207,7 +53961,7 @@ function resolveToolPath(toolPath, options = {}) {
53207
53961
  if (!resolved) {
53208
53962
  return { ok: false, error: `Path does not exist: ${requestedPath}` };
53209
53963
  }
53210
- const workspaceRoot = fs9.realpathSync.native(process.cwd());
53964
+ const workspaceRoot = fs10.realpathSync.native(process.cwd());
53211
53965
  const extraRoots = (options.allowedRoots || []).map((rootPath) => canonicalizeAllowedRoot(rootPath));
53212
53966
  const allowedRoots = [
53213
53967
  ...extraRoots,
@@ -53234,7 +53988,7 @@ function resolveToolPath(toolPath, options = {}) {
53234
53988
  error: `Access denied: ${requestedPath} is inside restricted workspace state (${blockedSegment})`
53235
53989
  };
53236
53990
  }
53237
- const relativeFromWorkspace = path10.relative(workspaceRoot, resolved.canonicalPath).replace(/\\/g, "/");
53991
+ const relativeFromWorkspace = path11.relative(workspaceRoot, resolved.canonicalPath).replace(/\\/g, "/");
53238
53992
  if (isSensitivePath(relativeFromWorkspace)) {
53239
53993
  return {
53240
53994
  ok: false,
@@ -53244,7 +53998,7 @@ function resolveToolPath(toolPath, options = {}) {
53244
53998
  }
53245
53999
  }
53246
54000
  if (resolved.exists) {
53247
- const stat = fs9.statSync(resolved.canonicalPath);
54001
+ const stat = fs10.statSync(resolved.canonicalPath);
53248
54002
  if (options.requireFile && !stat.isFile()) {
53249
54003
  return {
53250
54004
  ok: false,
@@ -53263,12 +54017,12 @@ function resolveToolPath(toolPath, options = {}) {
53263
54017
  return { ok: true, resolvedPath: resolved.canonicalPath };
53264
54018
  }
53265
54019
  function getTaskStateRoot(taskName, stateDir) {
53266
- return path10.join(stateDir || getMarathonStateDir(), stateSafeName3(taskName));
54020
+ return path11.join(stateDir || getMarathonStateDir(), stateSafeName3(taskName));
53267
54021
  }
53268
54022
  function createDefaultLocalTools(context) {
53269
54023
  const taskStateRoot = context?.taskName ? getTaskStateRoot(context.taskName, context.stateDir) : void 0;
53270
- const planDir = context?.taskName ? path10.resolve(`.runtype/marathons/${stateSafeName3(context.taskName)}`) : void 0;
53271
- const planPathDir = context?.planPath ? path10.resolve(path10.dirname(context.planPath)) : void 0;
54024
+ const planDir = context?.taskName ? path11.resolve(`.runtype/marathons/${stateSafeName3(context.taskName)}`) : void 0;
54025
+ const planPathDir = context?.planPath ? path11.resolve(path11.dirname(context.planPath)) : void 0;
53272
54026
  const allowedReadRoots = context?.taskName ? [
53273
54027
  getOffloadedOutputDir(context.taskName, context.stateDir),
53274
54028
  ...taskStateRoot ? [taskStateRoot] : [],
@@ -53289,7 +54043,7 @@ function createDefaultLocalTools(context) {
53289
54043
  allowedRoots: allowedReadRoots
53290
54044
  });
53291
54045
  if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
53292
- return fs9.readFileSync(resolvedPath.resolvedPath, "utf-8");
54046
+ return fs10.readFileSync(resolvedPath.resolvedPath, "utf-8");
53293
54047
  }
53294
54048
  },
53295
54049
  write_file: {
@@ -53308,12 +54062,12 @@ function createDefaultLocalTools(context) {
53308
54062
  });
53309
54063
  if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
53310
54064
  const content = String(args.content || "");
53311
- if (fs9.existsSync(resolvedPath.resolvedPath) && fs9.statSync(resolvedPath.resolvedPath).isDirectory()) {
54065
+ if (fs10.existsSync(resolvedPath.resolvedPath) && fs10.statSync(resolvedPath.resolvedPath).isDirectory()) {
53312
54066
  return `Error: Path is a directory: ${String(args.path || "")}`;
53313
54067
  }
53314
- const dir = path10.dirname(resolvedPath.resolvedPath);
53315
- fs9.mkdirSync(dir, { recursive: true });
53316
- fs9.writeFileSync(resolvedPath.resolvedPath, content);
54068
+ const dir = path11.dirname(resolvedPath.resolvedPath);
54069
+ fs10.mkdirSync(dir, { recursive: true });
54070
+ fs10.writeFileSync(resolvedPath.resolvedPath, content);
53317
54071
  return "ok";
53318
54072
  }
53319
54073
  },
@@ -53328,7 +54082,7 @@ function createDefaultLocalTools(context) {
53328
54082
  requireDirectory: true
53329
54083
  });
53330
54084
  if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
53331
- return fs9.readdirSync(resolvedPath.resolvedPath, { withFileTypes: true }).filter((entry) => !shouldIgnoreRepoEntry(path10.join(resolvedPath.resolvedPath, entry.name))).map((entry) => entry.name).join("\n");
54085
+ return fs10.readdirSync(resolvedPath.resolvedPath, { withFileTypes: true }).filter((entry) => !shouldIgnoreRepoEntry(path11.join(resolvedPath.resolvedPath, entry.name))).map((entry) => entry.name).join("\n");
53332
54086
  }
53333
54087
  },
53334
54088
  search_repo: {
@@ -53477,9 +54231,9 @@ function createDefaultLocalTools(context) {
53477
54231
  }
53478
54232
  function createCheckpointedWriteFileTool(taskName, stateDir, planPath) {
53479
54233
  const taskStateRoot = getTaskStateRoot(taskName, stateDir);
53480
- const planDir = path10.resolve(`.runtype/marathons/${stateSafeName3(taskName)}`);
53481
- const marathonPlanRoot = path10.resolve(".runtype/marathons");
53482
- const planPathDir = planPath ? path10.resolve(path10.dirname(planPath)) : void 0;
54234
+ const planDir = path11.resolve(`.runtype/marathons/${stateSafeName3(taskName)}`);
54235
+ const marathonPlanRoot = path11.resolve(".runtype/marathons");
54236
+ const planPathDir = planPath ? path11.resolve(path11.dirname(planPath)) : void 0;
53483
54237
  const writeAllowedRoots = [taskStateRoot, planDir, marathonPlanRoot, ...planPathDir ? [planPathDir] : []];
53484
54238
  return {
53485
54239
  description: "Write content to a file, creating directories as needed and checkpointing original repo files",
@@ -53499,10 +54253,10 @@ function createCheckpointedWriteFileTool(taskName, stateDir, planPath) {
53499
54253
  if (!resolvedPath.ok) return `Error: ${resolvedPath.error}`;
53500
54254
  const content = String(args.content || "");
53501
54255
  ensureMarathonFileCheckpoint(taskName, resolvedPath.resolvedPath, stateDir);
53502
- const dir = path10.dirname(resolvedPath.resolvedPath);
53503
- fs9.mkdirSync(dir, { recursive: true });
53504
- fs9.writeFileSync(resolvedPath.resolvedPath, content);
53505
- const ext = path10.extname(resolvedPath.resolvedPath).toLowerCase();
54256
+ const dir = path11.dirname(resolvedPath.resolvedPath);
54257
+ fs10.mkdirSync(dir, { recursive: true });
54258
+ fs10.writeFileSync(resolvedPath.resolvedPath, content);
54259
+ const ext = path11.extname(resolvedPath.resolvedPath).toLowerCase();
53506
54260
  if (ext === ".js" || ext === ".jsx") {
53507
54261
  const syntaxError = quickJsSyntaxCheck(content);
53508
54262
  if (syntaxError) {
@@ -53528,9 +54282,9 @@ function quickJsSyntaxCheck(content) {
53528
54282
  }
53529
54283
  function createEditFileTool(taskName, stateDir, planPath) {
53530
54284
  const taskStateRoot = getTaskStateRoot(taskName, stateDir);
53531
- const planDir = path10.resolve(`.runtype/marathons/${stateSafeName3(taskName)}`);
53532
- const marathonPlanRoot = path10.resolve(".runtype/marathons");
53533
- const planPathDir = planPath ? path10.resolve(path10.dirname(planPath)) : void 0;
54285
+ const planDir = path11.resolve(`.runtype/marathons/${stateSafeName3(taskName)}`);
54286
+ const marathonPlanRoot = path11.resolve(".runtype/marathons");
54287
+ const planPathDir = planPath ? path11.resolve(path11.dirname(planPath)) : void 0;
53534
54288
  const writeAllowedRoots = [taskStateRoot, planDir, marathonPlanRoot, ...planPathDir ? [planPathDir] : []];
53535
54289
  return {
53536
54290
  description: "Make a targeted edit to a file by replacing a specific string. Much more efficient than rewriting the entire file with write_file. The old_string must appear exactly once in the file (or use replace_all for global replacement). Always read the file first to get the exact text to replace.",
@@ -53563,7 +54317,7 @@ function createEditFileTool(taskName, stateDir, planPath) {
53563
54317
  if (oldString === newString) return "Error: old_string and new_string are identical";
53564
54318
  let content;
53565
54319
  try {
53566
- content = fs9.readFileSync(resolvedPath.resolvedPath, "utf-8");
54320
+ content = fs10.readFileSync(resolvedPath.resolvedPath, "utf-8");
53567
54321
  } catch {
53568
54322
  return `Error: Could not read file: ${String(args.path || "")}`;
53569
54323
  }
@@ -53580,8 +54334,8 @@ function createEditFileTool(taskName, stateDir, planPath) {
53580
54334
  }
53581
54335
  ensureMarathonFileCheckpoint(taskName, resolvedPath.resolvedPath, stateDir);
53582
54336
  const updated = replaceAll ? content.split(oldString).join(newString) : content.replace(oldString, newString);
53583
- fs9.writeFileSync(resolvedPath.resolvedPath, updated);
53584
- const ext = path10.extname(resolvedPath.resolvedPath).toLowerCase();
54337
+ fs10.writeFileSync(resolvedPath.resolvedPath, updated);
54338
+ const ext = path11.extname(resolvedPath.resolvedPath).toLowerCase();
53585
54339
  if (ext === ".js" || ext === ".jsx") {
53586
54340
  const syntaxError = quickJsSyntaxCheck(updated);
53587
54341
  if (syntaxError) {
@@ -53636,11 +54390,11 @@ function createReadOffloadedOutputTool(taskName, stateDir) {
53636
54390
  if (!/^[a-zA-Z0-9_-]+$/.test(outputId)) {
53637
54391
  return `Error: invalid offloaded output id: ${outputId}`;
53638
54392
  }
53639
- const outputPath = path10.join(getOffloadedOutputDir(taskName, stateDir), `${outputId}.txt`);
53640
- if (!fs9.existsSync(outputPath) || !fs9.statSync(outputPath).isFile()) {
54393
+ const outputPath = path11.join(getOffloadedOutputDir(taskName, stateDir), `${outputId}.txt`);
54394
+ if (!fs10.existsSync(outputPath) || !fs10.statSync(outputPath).isFile()) {
53641
54395
  return `Error: offloaded output not found: ${outputId}`;
53642
54396
  }
53643
- return fs9.readFileSync(outputPath, "utf-8");
54397
+ return fs10.readFileSync(outputPath, "utf-8");
53644
54398
  }
53645
54399
  };
53646
54400
  }
@@ -53942,8 +54696,8 @@ function createLoopDetector(options = {}) {
53942
54696
  }
53943
54697
 
53944
54698
  // src/marathon/context-offload.ts
53945
- import * as fs10 from "fs";
53946
- import * as path11 from "path";
54699
+ import * as fs11 from "fs";
54700
+ import * as path12 from "path";
53947
54701
  var DEFAULT_OUTPUT_THRESHOLD = 2e3;
53948
54702
  var DEFAULT_PREVIEW_LENGTH = 200;
53949
54703
  function buildOffloadedOutputId(toolName) {
@@ -53975,15 +54729,15 @@ function offloadToolOutput(taskName, toolName, output, options = {}, stateDir) {
53975
54729
  return { offloaded: false, content: output };
53976
54730
  }
53977
54731
  const outputId = buildOffloadedOutputId(toolName);
53978
- const dir = path11.join(
54732
+ const dir = path12.join(
53979
54733
  stateDir || defaultStateDir3(),
53980
54734
  stateSafeName4(taskName),
53981
54735
  "outputs"
53982
54736
  );
53983
54737
  const fileName = `${outputId}.txt`;
53984
- const filePath = path11.join(dir, fileName);
53985
- fs10.mkdirSync(dir, { recursive: true });
53986
- fs10.writeFileSync(filePath, output, "utf-8");
54738
+ const filePath = path12.join(dir, fileName);
54739
+ fs11.mkdirSync(dir, { recursive: true });
54740
+ fs11.writeFileSync(filePath, output, "utf-8");
53987
54741
  const preview = output.slice(0, previewLength).replace(/\n/g, " ");
53988
54742
  const reference = [
53989
54743
  `[Output offloaded as ${outputId} \u2014 ${output.length.toLocaleString()} chars stored internally]`,
@@ -54155,20 +54909,20 @@ function resolveAutoCompactTokenThreshold(modelContextLength, rawThreshold, stra
54155
54909
  }
54156
54910
 
54157
54911
  // src/marathon/recipes.ts
54158
- import * as fs11 from "fs";
54159
- import * as path12 from "path";
54912
+ import * as fs12 from "fs";
54913
+ import * as path13 from "path";
54160
54914
  var RULES_DIR = ".marathon/rules";
54161
54915
  function loadRules(cwd) {
54162
54916
  const baseCwd = cwd || process.cwd();
54163
- const rulesDir = path12.resolve(baseCwd, RULES_DIR);
54164
- if (!fs11.existsSync(rulesDir)) return [];
54917
+ const rulesDir = path13.resolve(baseCwd, RULES_DIR);
54918
+ if (!fs12.existsSync(rulesDir)) return [];
54165
54919
  const rules = [];
54166
54920
  try {
54167
- const entries = fs11.readdirSync(rulesDir).filter((f2) => f2.endsWith(".md"));
54921
+ const entries = fs12.readdirSync(rulesDir).filter((f2) => f2.endsWith(".md"));
54168
54922
  for (const entry of entries) {
54169
- const filePath = path12.join(rulesDir, entry);
54923
+ const filePath = path13.join(rulesDir, entry);
54170
54924
  try {
54171
- const raw = fs11.readFileSync(filePath, "utf-8");
54925
+ const raw = fs12.readFileSync(filePath, "utf-8");
54172
54926
  const parsed = parseRuleFile(raw);
54173
54927
  rules.push({ ...parsed, filePath });
54174
54928
  } catch {
@@ -54242,8 +54996,8 @@ function resolveErrorHandlingForPhase(phase, cliFallbackModel, milestoneFallback
54242
54996
  }
54243
54997
 
54244
54998
  // src/marathon/playbook-loader.ts
54245
- import * as fs12 from "fs";
54246
- import * as path13 from "path";
54999
+ import * as fs13 from "fs";
55000
+ import * as path14 from "path";
54247
55001
  import * as os4 from "os";
54248
55002
  import micromatch from "micromatch";
54249
55003
  import { parse as parseYaml } from "yaml";
@@ -54258,20 +55012,20 @@ function getCandidatePaths(nameOrPath, cwd) {
54258
55012
  const home = os4.homedir();
54259
55013
  return [
54260
55014
  // Exact path
54261
- path13.resolve(cwd, nameOrPath),
55015
+ path14.resolve(cwd, nameOrPath),
54262
55016
  // Repo-level
54263
- path13.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
54264
- path13.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
54265
- path13.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.json`),
55017
+ path14.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
55018
+ path14.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
55019
+ path14.resolve(cwd, PLAYBOOKS_DIR, `${nameOrPath}.json`),
54266
55020
  // User-level
54267
- path13.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
54268
- path13.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
54269
- path13.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.json`)
55021
+ path14.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yaml`),
55022
+ path14.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.yml`),
55023
+ path14.resolve(home, PLAYBOOKS_DIR, `${nameOrPath}.json`)
54270
55024
  ];
54271
55025
  }
54272
55026
  function parsePlaybookFile(filePath) {
54273
- const raw = fs12.readFileSync(filePath, "utf-8");
54274
- const ext = path13.extname(filePath).toLowerCase();
55027
+ const raw = fs13.readFileSync(filePath, "utf-8");
55028
+ const ext = path14.extname(filePath).toLowerCase();
54275
55029
  if (ext === ".json") {
54276
55030
  return JSON.parse(raw);
54277
55031
  }
@@ -54413,7 +55167,7 @@ function loadPlaybook(nameOrPath, cwd) {
54413
55167
  const baseCwd = cwd || process.cwd();
54414
55168
  const candidates = getCandidatePaths(nameOrPath, baseCwd);
54415
55169
  for (const candidate of candidates) {
54416
- if (!fs12.existsSync(candidate) || fs12.statSync(candidate).isDirectory()) continue;
55170
+ if (!fs13.existsSync(candidate) || fs13.statSync(candidate).isDirectory()) continue;
54417
55171
  const config3 = parsePlaybookFile(candidate);
54418
55172
  validatePlaybook(config3, candidate);
54419
55173
  const milestoneModels = {};
@@ -54863,7 +55617,7 @@ async function taskAction(agent, options) {
54863
55617
  forcedResumeFilePath = stateResolution.filePath;
54864
55618
  } else {
54865
55619
  resumeRequested = false;
54866
- if (options.fresh && fs13.existsSync(filePath)) {
55620
+ if (options.fresh && fs14.existsSync(filePath)) {
54867
55621
  if (useStartupShell) {
54868
55622
  setStartupStatus("starting fresh");
54869
55623
  } else {
@@ -55301,6 +56055,16 @@ Saving state... done. Session saved to ${filePath}`);
55301
56055
  }
55302
56056
  const checkpointResult = await streamActions.requestCheckpoint(recap);
55303
56057
  applyCheckpointConfig(checkpointResult);
56058
+ const resumeTreeNav = checkpointResult.action !== "stop" ? applyCheckpointTreeNavigation(filePath, checkpointResult) : null;
56059
+ if (resumeTreeNav) {
56060
+ resumeLoadedState = resumeTreeNav.mergedState;
56061
+ previousMessages = resumeTreeNav.messages;
56062
+ resumeState = extractRunTaskResumeState(resumeTreeNav.mergedState);
56063
+ useCompact = false;
56064
+ continuationMessage = "Continue from this point in the conversation.";
56065
+ persistedSessionSnapshots = resumeTreeNav.mergedState.sessionSnapshots ?? [];
56066
+ streamActions.hydrateSessionSnapshots(persistedSessionSnapshots);
56067
+ }
55304
56068
  switch (checkpointResult.action) {
55305
56069
  case "stop":
55306
56070
  streamActions.exit();
@@ -55383,6 +56147,11 @@ Saving state... done. Session saved to ${filePath}`);
55383
56147
  streamCallbacks: currentStreamCallbacks,
55384
56148
  localTools,
55385
56149
  trackProgress: options.track ? taskName : void 0,
56150
+ // Mid-run steering queue (Enter while streaming): the UI owns the
56151
+ // queue; the SDK drains it at session boundaries and ends in-flight
56152
+ // sessions early at local-tool pauses when something is queued.
56153
+ getQueuedUserMessages: () => streamRef.current?.drainSteeringQueue?.(),
56154
+ hasQueuedUserMessages: () => streamRef.current?.hasQueuedSteering?.() ?? false,
55386
56155
  ...resolvedToolIds.length > 0 ? { toolIds: resolvedToolIds } : {},
55387
56156
  ...resolvedWorkflow ? { workflow: resolvedWorkflow } : {},
55388
56157
  // Continuation context (only set on resume or after checkpoint restart)
@@ -55548,6 +56317,17 @@ Saving state... done. Session saved to ${filePath}`);
55548
56317
  };
55549
56318
  const checkpointResult = await currentActions.requestCheckpoint(recap);
55550
56319
  applyCheckpointConfig(checkpointResult);
56320
+ const treeNav = checkpointResult.action !== "stop" ? applyCheckpointTreeNavigation(filePath, checkpointResult) : null;
56321
+ if (treeNav) {
56322
+ lastKnownState = treeNav.mergedState;
56323
+ lastSessionMessages = treeNav.messages;
56324
+ resumeState = extractRunTaskResumeState(treeNav.mergedState);
56325
+ persistedSessionSnapshots = treeNav.mergedState.sessionSnapshots ?? [];
56326
+ currentActions.hydrateSessionSnapshots(persistedSessionSnapshots);
56327
+ taskMessage = checkpointResult.message ?? "Continue from this point in the conversation.";
56328
+ shouldContinue = true;
56329
+ return false;
56330
+ }
55551
56331
  switch (checkpointResult.action) {
55552
56332
  case "stop":
55553
56333
  return false;
@@ -55643,6 +56423,17 @@ Saving state... done. Session saved to ${filePath}`);
55643
56423
  if (options.noCheckpoint) break;
55644
56424
  const currentActions = streamRef.current;
55645
56425
  if (!currentActions) break;
56426
+ const queuedFollowUps = currentActions.drainFollowUpQueue?.();
56427
+ if (queuedFollowUps && queuedFollowUps.length > 0) {
56428
+ currentActions.resetForNewSession();
56429
+ taskMessage = queuedFollowUps.join("\n\n");
56430
+ previousMessages = lastSessionMessages;
56431
+ continuationMessage = taskMessage;
56432
+ useCompact = false;
56433
+ resumeState = extractRunTaskResumeState(lastKnownState);
56434
+ shouldContinue = true;
56435
+ continue;
56436
+ }
55646
56437
  let exitTerminal = false;
55647
56438
  while (!exitTerminal) {
55648
56439
  const knownState2 = lastKnownState;
@@ -55657,6 +56448,22 @@ Saving state... done. Session saved to ${filePath}`);
55657
56448
  };
55658
56449
  const checkpointResult = await currentActions.requestCheckpoint(recap, true);
55659
56450
  applyCheckpointConfig(checkpointResult);
56451
+ const terminalTreeNav = checkpointResult.action !== "stop" ? applyCheckpointTreeNavigation(filePath, checkpointResult) : null;
56452
+ if (terminalTreeNav) {
56453
+ currentActions.resetForNewSession();
56454
+ lastKnownState = terminalTreeNav.mergedState;
56455
+ lastSessionMessages = terminalTreeNav.messages;
56456
+ previousMessages = terminalTreeNav.messages;
56457
+ persistedSessionSnapshots = terminalTreeNav.mergedState.sessionSnapshots ?? [];
56458
+ currentActions.hydrateSessionSnapshots(persistedSessionSnapshots);
56459
+ taskMessage = checkpointResult.message ?? "Continue from this point in the conversation.";
56460
+ continuationMessage = taskMessage;
56461
+ useCompact = false;
56462
+ resumeState = extractRunTaskResumeState(terminalTreeNav.mergedState);
56463
+ shouldContinue = true;
56464
+ exitTerminal = true;
56465
+ continue;
56466
+ }
55660
56467
  switch (checkpointResult.action) {
55661
56468
  case "steer":
55662
56469
  if (checkpointResult.message) {
@@ -55944,9 +56751,9 @@ agentsCommand.command("list").description("List all agents").option("--json", "O
55944
56751
  return;
55945
56752
  }
55946
56753
  const App = () => {
55947
- const [items, setItems] = useState30(null);
55948
- const [error51, setError] = useState30(null);
55949
- const [total, setTotal] = useState30();
56754
+ const [items, setItems] = useState33(null);
56755
+ const [error51, setError] = useState33(null);
56756
+ const [total, setTotal] = useState33();
55950
56757
  useEffect27(() => {
55951
56758
  client.get("/agents", params).then((res) => {
55952
56759
  setItems(res.data ?? []);
@@ -56002,8 +56809,8 @@ agentsCommand.command("get <id>").description("Get agent details").option("--jso
56002
56809
  return;
56003
56810
  }
56004
56811
  const App = () => {
56005
- const [items, setItems] = useState30(null);
56006
- const [error51, setError] = useState30(null);
56812
+ const [items, setItems] = useState33(null);
56813
+ const [error51, setError] = useState33(null);
56007
56814
  useEffect27(() => {
56008
56815
  client.get(`/agents/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
56009
56816
  }, []);
@@ -56054,10 +56861,10 @@ agentsCommand.command("create").description("Create a new agent").requiredOption
56054
56861
  return;
56055
56862
  }
56056
56863
  const App = () => {
56057
- const [loading, setLoading] = useState30(true);
56058
- const [success2, setSuccess] = useState30(null);
56059
- const [error51, setError] = useState30(null);
56060
- const [result, setResult] = useState30(null);
56864
+ const [loading, setLoading] = useState33(true);
56865
+ const [success2, setSuccess] = useState33(null);
56866
+ const [error51, setError] = useState33(null);
56867
+ const [result, setResult] = useState33(null);
56061
56868
  useEffect27(() => {
56062
56869
  client.post("/agents", {
56063
56870
  name: options.name,
@@ -56129,10 +56936,10 @@ agentsCommand.command("update <id>").description("Update an agent").option("-n,
56129
56936
  return;
56130
56937
  }
56131
56938
  const App = () => {
56132
- const [loading, setLoading] = useState30(true);
56133
- const [success2, setSuccess] = useState30(null);
56134
- const [error51, setError] = useState30(null);
56135
- const [result, setResult] = useState30(null);
56939
+ const [loading, setLoading] = useState33(true);
56940
+ const [success2, setSuccess] = useState33(null);
56941
+ const [error51, setError] = useState33(null);
56942
+ const [result, setResult] = useState33(null);
56136
56943
  useEffect27(() => {
56137
56944
  client.put(`/agents/${id}`, body).then((data) => {
56138
56945
  setResult(data);
@@ -56178,10 +56985,10 @@ agentsCommand.command("delete <id>").description("Delete an agent").option("--tt
56178
56985
  return;
56179
56986
  }
56180
56987
  const App = () => {
56181
- const [confirmed, setConfirmed] = useState30(null);
56182
- const [loading, setLoading] = useState30(false);
56183
- const [success2, setSuccess] = useState30(null);
56184
- const [error51, setError] = useState30(null);
56988
+ const [confirmed, setConfirmed] = useState33(null);
56989
+ const [loading, setLoading] = useState33(false);
56990
+ const [success2, setSuccess] = useState33(null);
56991
+ const [error51, setError] = useState33(null);
56185
56992
  useEffect27(() => {
56186
56993
  if (confirmed !== true) return void 0;
56187
56994
  setLoading(true);
@@ -56276,7 +57083,7 @@ import { Command as Command18 } from "commander";
56276
57083
  import chalk25 from "chalk";
56277
57084
  import React17 from "react";
56278
57085
  import { render as render17 } from "ink";
56279
- import { useState as useState31, useEffect as useEffect28 } from "react";
57086
+ import { useState as useState34, useEffect as useEffect28 } from "react";
56280
57087
  var modelsCommand = new Command18("models").description("Manage model configurations");
56281
57088
  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) => {
56282
57089
  const apiKey = await ensureAuth();
@@ -56313,9 +57120,9 @@ modelsCommand.command("list").description("List your enabled model configuration
56313
57120
  return;
56314
57121
  }
56315
57122
  const App = () => {
56316
- const [items, setItems] = useState31(null);
56317
- const [error51, setError] = useState31(null);
56318
- const [total, setTotal] = useState31();
57123
+ const [items, setItems] = useState34(null);
57124
+ const [error51, setError] = useState34(null);
57125
+ const [total, setTotal] = useState34();
56319
57126
  useEffect28(() => {
56320
57127
  client.get("/model-configs").then((res) => {
56321
57128
  setItems(res.data ?? []);
@@ -56378,8 +57185,8 @@ modelsCommand.command("available").description("List all available models groupe
56378
57185
  return;
56379
57186
  }
56380
57187
  const App = () => {
56381
- const [items, setItems] = useState31(null);
56382
- const [error51, setError] = useState31(null);
57188
+ const [items, setItems] = useState34(null);
57189
+ const [error51, setError] = useState34(null);
56383
57190
  useEffect28(() => {
56384
57191
  client.get("/model-configs/grouped").then((res) => setItems(res.data ?? [])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
56385
57192
  }, []);
@@ -56426,10 +57233,10 @@ modelsCommand.command("enable <modelId>").description("Enable a model by creatin
56426
57233
  return;
56427
57234
  }
56428
57235
  const App = () => {
56429
- const [loading, setLoading] = useState31(true);
56430
- const [success2, setSuccess] = useState31(null);
56431
- const [error51, setError] = useState31(null);
56432
- const [result, setResult] = useState31(null);
57236
+ const [loading, setLoading] = useState34(true);
57237
+ const [success2, setSuccess] = useState34(null);
57238
+ const [error51, setError] = useState34(null);
57239
+ const [result, setResult] = useState34(null);
56433
57240
  useEffect28(() => {
56434
57241
  client.post("/model-configs", { modelId }).then((data) => {
56435
57242
  setResult(data);
@@ -56474,9 +57281,9 @@ modelsCommand.command("disable <id>").description("Disable a model configuration
56474
57281
  return;
56475
57282
  }
56476
57283
  const App = () => {
56477
- const [loading, setLoading] = useState31(true);
56478
- const [success2, setSuccess] = useState31(null);
56479
- const [error51, setError] = useState31(null);
57284
+ const [loading, setLoading] = useState34(true);
57285
+ const [success2, setSuccess] = useState34(null);
57286
+ const [error51, setError] = useState34(null);
56480
57287
  useEffect28(() => {
56481
57288
  client.patch(`/model-configs/${id}/status`, { enabled: false }).then(() => {
56482
57289
  setSuccess(true);
@@ -56514,9 +57321,9 @@ modelsCommand.command("default <id>").description("Set a model configuration as
56514
57321
  return;
56515
57322
  }
56516
57323
  const App = () => {
56517
- const [loading, setLoading] = useState31(true);
56518
- const [success2, setSuccess] = useState31(null);
56519
- const [error51, setError] = useState31(null);
57324
+ const [loading, setLoading] = useState34(true);
57325
+ const [success2, setSuccess] = useState34(null);
57326
+ const [error51, setError] = useState34(null);
56520
57327
  useEffect28(() => {
56521
57328
  client.patch(`/model-configs/${id}/default`, {}).then(() => {
56522
57329
  setSuccess(true);
@@ -56558,7 +57365,7 @@ import { Command as Command19 } from "commander";
56558
57365
  import chalk26 from "chalk";
56559
57366
  import React18 from "react";
56560
57367
  import { render as render18 } from "ink";
56561
- import { useState as useState32, useEffect as useEffect29 } from "react";
57368
+ import { useState as useState35, useEffect as useEffect29 } from "react";
56562
57369
  var schedulesCommand = new Command19("schedules").description("Manage schedules");
56563
57370
  schedulesCommand.command("list").description("List all schedules").option("--limit <n>", "Limit results (defaults to the API page size)").option("--cursor <cursor>", "Pagination cursor for the next page").option("--json", "Output as JSON").option("--tty", "Force TTY mode").option("--no-tty", "Force non-TTY mode").action(async (options) => {
56564
57371
  const apiKey = await ensureAuth();
@@ -56604,9 +57411,9 @@ schedulesCommand.command("list").description("List all schedules").option("--lim
56604
57411
  return;
56605
57412
  }
56606
57413
  const App = () => {
56607
- const [items, setItems] = useState32(null);
56608
- const [error51, setError] = useState32(null);
56609
- const [total, setTotal] = useState32();
57414
+ const [items, setItems] = useState35(null);
57415
+ const [error51, setError] = useState35(null);
57416
+ const [total, setTotal] = useState35();
56610
57417
  useEffect29(() => {
56611
57418
  client.get("/schedules", params).then((res) => {
56612
57419
  setItems(res.data ?? []);
@@ -56670,8 +57477,8 @@ schedulesCommand.command("get <id>").description("Get schedule details").option(
56670
57477
  return;
56671
57478
  }
56672
57479
  const App = () => {
56673
- const [items, setItems] = useState32(null);
56674
- const [error51, setError] = useState32(null);
57480
+ const [items, setItems] = useState35(null);
57481
+ const [error51, setError] = useState35(null);
56675
57482
  useEffect29(() => {
56676
57483
  client.get(`/schedules/${id}`).then((res) => setItems([res])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
56677
57484
  }, []);
@@ -56747,8 +57554,8 @@ schedulesCommand.command("runs <id>").description("List run history for a schedu
56747
57554
  return;
56748
57555
  }
56749
57556
  const App = () => {
56750
- const [items, setItems] = useState32(null);
56751
- const [error51, setError] = useState32(null);
57557
+ const [items, setItems] = useState35(null);
57558
+ const [error51, setError] = useState35(null);
56752
57559
  useEffect29(() => {
56753
57560
  client.get(`/schedules/${id}/runs`).then((res) => setItems(res.data ?? [])).catch((err) => setError(err instanceof Error ? err : new Error(String(err))));
56754
57561
  }, []);
@@ -56814,10 +57621,10 @@ schedulesCommand.command("create").description("Create a new recurring schedule
56814
57621
  return;
56815
57622
  }
56816
57623
  const App = () => {
56817
- const [loading, setLoading] = useState32(true);
56818
- const [success2, setSuccess] = useState32(null);
56819
- const [error51, setError] = useState32(null);
56820
- const [result, setResult] = useState32(null);
57624
+ const [loading, setLoading] = useState35(true);
57625
+ const [success2, setSuccess] = useState35(null);
57626
+ const [error51, setError] = useState35(null);
57627
+ const [result, setResult] = useState35(null);
56821
57628
  useEffect29(() => {
56822
57629
  client.post("/schedules", payload).then((data) => {
56823
57630
  setResult(data);
@@ -56896,10 +57703,10 @@ schedulesCommand.command("update <id>").description("Update an existing schedule
56896
57703
  return;
56897
57704
  }
56898
57705
  const App = () => {
56899
- const [loading, setLoading] = useState32(true);
56900
- const [success2, setSuccess] = useState32(null);
56901
- const [error51, setError] = useState32(null);
56902
- const [result, setResult] = useState32(null);
57706
+ const [loading, setLoading] = useState35(true);
57707
+ const [success2, setSuccess] = useState35(null);
57708
+ const [error51, setError] = useState35(null);
57709
+ const [result, setResult] = useState35(null);
56903
57710
  useEffect29(() => {
56904
57711
  client.put(`/schedules/${id}`, body).then((data) => {
56905
57712
  setResult(data);
@@ -56946,9 +57753,9 @@ function simpleMutationCommand(name, description, mutationFn, successMsg, loadin
56946
57753
  return;
56947
57754
  }
56948
57755
  const App = () => {
56949
- const [loading, setLoading] = useState32(true);
56950
- const [success2, setSuccess] = useState32(null);
56951
- const [error51, setError] = useState32(null);
57756
+ const [loading, setLoading] = useState35(true);
57757
+ const [success2, setSuccess] = useState35(null);
57758
+ const [error51, setError] = useState35(null);
56952
57759
  useEffect29(() => {
56953
57760
  mutationFn(client, id).then(() => {
56954
57761
  setSuccess(true);
@@ -57008,10 +57815,10 @@ schedulesCommand.command("delete <id>").description("Delete a schedule").option(
57008
57815
  return;
57009
57816
  }
57010
57817
  const App = () => {
57011
- const [confirmed, setConfirmed] = useState32(null);
57012
- const [loading, setLoading] = useState32(false);
57013
- const [success2, setSuccess] = useState32(null);
57014
- const [error51, setError] = useState32(null);
57818
+ const [confirmed, setConfirmed] = useState35(null);
57819
+ const [loading, setLoading] = useState35(false);
57820
+ const [success2, setSuccess] = useState35(null);
57821
+ const [error51, setError] = useState35(null);
57015
57822
  useEffect29(() => {
57016
57823
  if (confirmed !== true) return void 0;
57017
57824
  setLoading(true);
@@ -57056,16 +57863,16 @@ import { Command as Command20 } from "commander";
57056
57863
  import chalk27 from "chalk";
57057
57864
  import React19 from "react";
57058
57865
  import { render as render19 } from "ink";
57059
- import { useState as useState33, useEffect as useEffect30 } from "react";
57060
- import { Text as Text31 } from "ink";
57061
- import { readFileSync as readFileSync14 } from "fs";
57866
+ import { useState as useState36, useEffect as useEffect30 } from "react";
57867
+ import { Text as Text34 } from "ink";
57868
+ import { readFileSync as readFileSync15 } from "fs";
57062
57869
  var evalCommand = new Command20("eval").description("Manage evaluations");
57063
57870
  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) => {
57064
57871
  const apiKey = await ensureAuth();
57065
57872
  if (!apiKey) return;
57066
57873
  let recordIds;
57067
57874
  try {
57068
- const content = readFileSync14(options.records, "utf-8");
57875
+ const content = readFileSync15(options.records, "utf-8");
57069
57876
  const parsed = JSON.parse(content);
57070
57877
  recordIds = Array.isArray(parsed) ? parsed : parsed.recordIds || parsed.records || [];
57071
57878
  } catch (error51) {
@@ -57101,10 +57908,10 @@ evalCommand.command("submit").description("Submit an eval batch").requiredOption
57101
57908
  return;
57102
57909
  }
57103
57910
  const App = () => {
57104
- const [loading, setLoading] = useState33(true);
57105
- const [success2, setSuccess] = useState33(null);
57106
- const [error51, setError] = useState33(null);
57107
- const [resultNode, setResultNode] = useState33(void 0);
57911
+ const [loading, setLoading] = useState36(true);
57912
+ const [success2, setSuccess] = useState36(null);
57913
+ const [error51, setError] = useState36(null);
57914
+ const [resultNode, setResultNode] = useState36(void 0);
57108
57915
  useEffect30(() => {
57109
57916
  const run2 = async () => {
57110
57917
  try {
@@ -57184,10 +57991,10 @@ evalCommand.command("list").description("List eval batches").option("--flow <id>
57184
57991
  return;
57185
57992
  }
57186
57993
  const App = () => {
57187
- const [loading, setLoading] = useState33(true);
57188
- const [items, setItems] = useState33(null);
57189
- const [total, setTotal] = useState33(void 0);
57190
- const [error51, setError] = useState33(null);
57994
+ const [loading, setLoading] = useState36(true);
57995
+ const [items, setItems] = useState36(null);
57996
+ const [total, setTotal] = useState36(void 0);
57997
+ const [error51, setError] = useState36(null);
57191
57998
  useEffect30(() => {
57192
57999
  const run2 = async () => {
57193
58000
  try {
@@ -57215,7 +58022,7 @@ evalCommand.command("list").description("List eval batches").option("--flow <id>
57215
58022
  const progress = b.totalRecords ? `${b.completedRecords ?? 0}/${b.totalRecords}` : "";
57216
58023
  const statusColor = b.status === "completed" ? "green" : "yellow";
57217
58024
  return React19.createElement(
57218
- Text31,
58025
+ Text34,
57219
58026
  { color: statusColor },
57220
58027
  ` ${b.id} ${name} [${b.status}] ${progress}`
57221
58028
  );
@@ -57264,10 +58071,10 @@ evalCommand.command("results <id>").description("Get eval batch results").option
57264
58071
  return;
57265
58072
  }
57266
58073
  const App = () => {
57267
- const [loading, setLoading] = useState33(true);
57268
- const [success2, setSuccess] = useState33(null);
57269
- const [error51, setError] = useState33(null);
57270
- const [resultNode, setResultNode] = useState33(void 0);
58074
+ const [loading, setLoading] = useState36(true);
58075
+ const [success2, setSuccess] = useState36(null);
58076
+ const [error51, setError] = useState36(null);
58077
+ const [resultNode, setResultNode] = useState36(void 0);
57271
58078
  useEffect30(() => {
57272
58079
  const run2 = async () => {
57273
58080
  try {
@@ -57328,9 +58135,9 @@ evalCommand.command("compare <groupId>").description("Compare evals in a group")
57328
58135
  return;
57329
58136
  }
57330
58137
  const App = () => {
57331
- const [loading, setLoading] = useState33(true);
57332
- const [success2, setSuccess] = useState33(null);
57333
- const [error51, setError] = useState33(null);
58138
+ const [loading, setLoading] = useState36(true);
58139
+ const [success2, setSuccess] = useState36(null);
58140
+ const [error51, setError] = useState36(null);
57334
58141
  useEffect30(() => {
57335
58142
  const run2 = async () => {
57336
58143
  try {
@@ -57363,8 +58170,8 @@ import { Command as Command21 } from "commander";
57363
58170
  import chalk28 from "chalk";
57364
58171
  import React20 from "react";
57365
58172
  import { render as render20 } from "ink";
57366
- import { useState as useState34, useEffect as useEffect31 } from "react";
57367
- import { Text as Text32 } from "ink";
58173
+ import { useState as useState37, useEffect as useEffect31 } from "react";
58174
+ import { Text as Text35 } from "ink";
57368
58175
  var apiKeysCommand = new Command21("api-keys").description("Manage API keys");
57369
58176
  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) => {
57370
58177
  const apiKey = await ensureAuth();
@@ -57402,10 +58209,10 @@ apiKeysCommand.command("list").description("List your API keys").option("--json"
57402
58209
  return;
57403
58210
  }
57404
58211
  const App = () => {
57405
- const [loading, setLoading] = useState34(true);
57406
- const [items, setItems] = useState34(null);
57407
- const [total, setTotal] = useState34(void 0);
57408
- const [error51, setError] = useState34(null);
58212
+ const [loading, setLoading] = useState37(true);
58213
+ const [items, setItems] = useState37(null);
58214
+ const [total, setTotal] = useState37(void 0);
58215
+ const [error51, setError] = useState37(null);
57409
58216
  useEffect31(() => {
57410
58217
  const run2 = async () => {
57411
58218
  try {
@@ -57431,7 +58238,7 @@ apiKeysCommand.command("list").description("List your API keys").option("--json"
57431
58238
  const k2 = item;
57432
58239
  const prefix = k2.prefix ? ` (${k2.prefix}...)` : "";
57433
58240
  const lastUsed = k2.lastUsedAt ? ` last used: ${k2.lastUsedAt}` : "";
57434
- return React20.createElement(Text32, null, ` ${k2.id} ${k2.name}${prefix}${lastUsed}`);
58241
+ return React20.createElement(Text35, null, ` ${k2.id} ${k2.name}${prefix}${lastUsed}`);
57435
58242
  }
57436
58243
  });
57437
58244
  };
@@ -57466,10 +58273,10 @@ apiKeysCommand.command("get <id>").description("Get API key details").option("--
57466
58273
  return;
57467
58274
  }
57468
58275
  const App = () => {
57469
- const [loading, setLoading] = useState34(true);
57470
- const [success2, setSuccess] = useState34(null);
57471
- const [error51, setError] = useState34(null);
57472
- const [resultNode, setResultNode] = useState34(void 0);
58276
+ const [loading, setLoading] = useState37(true);
58277
+ const [success2, setSuccess] = useState37(null);
58278
+ const [error51, setError] = useState37(null);
58279
+ const [resultNode, setResultNode] = useState37(void 0);
57473
58280
  useEffect31(() => {
57474
58281
  const run2 = async () => {
57475
58282
  try {
@@ -57535,10 +58342,10 @@ apiKeysCommand.command("create").description("Create a new API key").requiredOpt
57535
58342
  return;
57536
58343
  }
57537
58344
  const App = () => {
57538
- const [loading, setLoading] = useState34(true);
57539
- const [success2, setSuccess] = useState34(null);
57540
- const [error51, setError] = useState34(null);
57541
- const [resultNode, setResultNode] = useState34(void 0);
58345
+ const [loading, setLoading] = useState37(true);
58346
+ const [success2, setSuccess] = useState37(null);
58347
+ const [error51, setError] = useState37(null);
58348
+ const [resultNode, setResultNode] = useState37(void 0);
57542
58349
  useEffect31(() => {
57543
58350
  const run2 = async () => {
57544
58351
  try {
@@ -57594,9 +58401,9 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
57594
58401
  }
57595
58402
  if (options.yes) {
57596
58403
  const App = () => {
57597
- const [loading, setLoading] = useState34(true);
57598
- const [success2, setSuccess] = useState34(null);
57599
- const [error51, setError] = useState34(null);
58404
+ const [loading, setLoading] = useState37(true);
58405
+ const [success2, setSuccess] = useState37(null);
58406
+ const [error51, setError] = useState37(null);
57600
58407
  useEffect31(() => {
57601
58408
  const run2 = async () => {
57602
58409
  try {
@@ -57637,9 +58444,9 @@ apiKeysCommand.command("delete <id>").description("Delete an API key").option("-
57637
58444
  });
57638
58445
  if (!confirmed) return;
57639
58446
  const DeleteApp = () => {
57640
- const [loading, setLoading] = useState34(true);
57641
- const [success2, setSuccess] = useState34(null);
57642
- const [error51, setError] = useState34(null);
58447
+ const [loading, setLoading] = useState37(true);
58448
+ const [success2, setSuccess] = useState37(null);
58449
+ const [error51, setError] = useState37(null);
57643
58450
  useEffect31(() => {
57644
58451
  const run2 = async () => {
57645
58452
  try {
@@ -57690,10 +58497,10 @@ apiKeysCommand.command("regenerate <id>").description("Regenerate an API key").o
57690
58497
  return;
57691
58498
  }
57692
58499
  const App = () => {
57693
- const [loading, setLoading] = useState34(true);
57694
- const [success2, setSuccess] = useState34(null);
57695
- const [error51, setError] = useState34(null);
57696
- const [resultNode, setResultNode] = useState34(void 0);
58500
+ const [loading, setLoading] = useState37(true);
58501
+ const [success2, setSuccess] = useState37(null);
58502
+ const [error51, setError] = useState37(null);
58503
+ const [resultNode, setResultNode] = useState37(void 0);
57697
58504
  useEffect31(() => {
57698
58505
  const run2 = async () => {
57699
58506
  try {
@@ -57734,8 +58541,8 @@ apiKeysCommand.command("analytics").description("Show API key usage analytics").
57734
58541
  const client = createCliClient(apiKey);
57735
58542
  if (!isTTY(options) || options.json) {
57736
58543
  try {
57737
- const path16 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
57738
- const data = await client.get(path16);
58544
+ const path17 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
58545
+ const data = await client.get(path17);
57739
58546
  printJson(data);
57740
58547
  } catch (error51) {
57741
58548
  const message = error51 instanceof Error ? error51.message : "Unknown error";
@@ -57746,14 +58553,14 @@ apiKeysCommand.command("analytics").description("Show API key usage analytics").
57746
58553
  return;
57747
58554
  }
57748
58555
  const App = () => {
57749
- const [loading, setLoading] = useState34(true);
57750
- const [success2, setSuccess] = useState34(null);
57751
- const [error51, setError] = useState34(null);
58556
+ const [loading, setLoading] = useState37(true);
58557
+ const [success2, setSuccess] = useState37(null);
58558
+ const [error51, setError] = useState37(null);
57752
58559
  useEffect31(() => {
57753
58560
  const run2 = async () => {
57754
58561
  try {
57755
- const path16 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
57756
- const data = await client.get(path16);
58562
+ const path17 = options.key ? `/api-keys/${options.key}/analytics` : "/api-keys/analytics";
58563
+ const data = await client.get(path17);
57757
58564
  printJson(data);
57758
58565
  setSuccess(true);
57759
58566
  setLoading(false);
@@ -57782,8 +58589,8 @@ import { Command as Command22 } from "commander";
57782
58589
  import chalk29 from "chalk";
57783
58590
  import React21 from "react";
57784
58591
  import { render as render21 } from "ink";
57785
- import { useState as useState35, useEffect as useEffect32 } from "react";
57786
- import { Text as Text33 } from "ink";
58592
+ import { useState as useState38, useEffect as useEffect32 } from "react";
58593
+ import { Text as Text36 } from "ink";
57787
58594
  var clientTokensCommand = new Command22("client-tokens").description(
57788
58595
  "Manage client tokens for Persona widget embedding"
57789
58596
  );
@@ -57821,10 +58628,10 @@ clientTokensCommand.command("list").description("List your client tokens").optio
57821
58628
  return;
57822
58629
  }
57823
58630
  const App = () => {
57824
- const [loading, setLoading] = useState35(true);
57825
- const [items, setItems] = useState35(null);
57826
- const [total, setTotal] = useState35(void 0);
57827
- const [error51, setError] = useState35(null);
58631
+ const [loading, setLoading] = useState38(true);
58632
+ const [items, setItems] = useState38(null);
58633
+ const [total, setTotal] = useState38(void 0);
58634
+ const [error51, setError] = useState38(null);
57828
58635
  useEffect32(() => {
57829
58636
  const run2 = async () => {
57830
58637
  try {
@@ -57851,7 +58658,7 @@ clientTokensCommand.command("list").description("List your client tokens").optio
57851
58658
  const t = item;
57852
58659
  const env = t.environment === "live" ? "live" : "test";
57853
58660
  const active = t.isActive ? "" : " (inactive)";
57854
- return React21.createElement(Text33, null, ` ${t.id} ${t.name} [${env}]${active}`);
58661
+ return React21.createElement(Text36, null, ` ${t.id} ${t.name} [${env}]${active}`);
57855
58662
  }
57856
58663
  });
57857
58664
  };
@@ -57897,10 +58704,10 @@ clientTokensCommand.command("get <id>").description("Get client token details").
57897
58704
  return;
57898
58705
  }
57899
58706
  const App = () => {
57900
- const [loading, setLoading] = useState35(true);
57901
- const [success2, setSuccess] = useState35(null);
57902
- const [error51, setError] = useState35(null);
57903
- const [resultNode, setResultNode] = useState35(void 0);
58707
+ const [loading, setLoading] = useState38(true);
58708
+ const [success2, setSuccess] = useState38(null);
58709
+ const [error51, setError] = useState38(null);
58710
+ const [resultNode, setResultNode] = useState38(void 0);
57904
58711
  useEffect32(() => {
57905
58712
  const run2 = async () => {
57906
58713
  try {
@@ -58005,10 +58812,10 @@ clientTokensCommand.command("create").description("Create a new client token").r
58005
58812
  return;
58006
58813
  }
58007
58814
  const App = () => {
58008
- const [loading, setLoading] = useState35(true);
58009
- const [success2, setSuccess] = useState35(null);
58010
- const [error51, setError] = useState35(null);
58011
- const [resultNode, setResultNode] = useState35(void 0);
58815
+ const [loading, setLoading] = useState38(true);
58816
+ const [success2, setSuccess] = useState38(null);
58817
+ const [error51, setError] = useState38(null);
58818
+ const [resultNode, setResultNode] = useState38(void 0);
58012
58819
  useEffect32(() => {
58013
58820
  const run2 = async () => {
58014
58821
  try {
@@ -58066,9 +58873,9 @@ clientTokensCommand.command("delete <id>").description("Delete a client token").
58066
58873
  }
58067
58874
  if (options.yes) {
58068
58875
  const App = () => {
58069
- const [loading, setLoading] = useState35(true);
58070
- const [success2, setSuccess] = useState35(null);
58071
- const [error51, setError] = useState35(null);
58876
+ const [loading, setLoading] = useState38(true);
58877
+ const [success2, setSuccess] = useState38(null);
58878
+ const [error51, setError] = useState38(null);
58072
58879
  useEffect32(() => {
58073
58880
  const run2 = async () => {
58074
58881
  try {
@@ -58109,9 +58916,9 @@ clientTokensCommand.command("delete <id>").description("Delete a client token").
58109
58916
  });
58110
58917
  if (!confirmed) return;
58111
58918
  const DeleteApp = () => {
58112
- const [loading, setLoading] = useState35(true);
58113
- const [success2, setSuccess] = useState35(null);
58114
- const [error51, setError] = useState35(null);
58919
+ const [loading, setLoading] = useState38(true);
58920
+ const [success2, setSuccess] = useState38(null);
58921
+ const [error51, setError] = useState38(null);
58115
58922
  useEffect32(() => {
58116
58923
  const run2 = async () => {
58117
58924
  try {
@@ -58160,10 +58967,10 @@ clientTokensCommand.command("regenerate <id>").description("Regenerate a client
58160
58967
  return;
58161
58968
  }
58162
58969
  const App = () => {
58163
- const [loading, setLoading] = useState35(true);
58164
- const [success2, setSuccess] = useState35(null);
58165
- const [error51, setError] = useState35(null);
58166
- const [resultNode, setResultNode] = useState35(void 0);
58970
+ const [loading, setLoading] = useState38(true);
58971
+ const [success2, setSuccess] = useState38(null);
58972
+ const [error51, setError] = useState38(null);
58973
+ const [resultNode, setResultNode] = useState38(void 0);
58167
58974
  useEffect32(() => {
58168
58975
  const run2 = async () => {
58169
58976
  try {
@@ -58959,8 +59766,8 @@ import { Command as Command24 } from "commander";
58959
59766
  import chalk31 from "chalk";
58960
59767
  import React22 from "react";
58961
59768
  import { render as render22 } from "ink";
58962
- import { useState as useState36, useEffect as useEffect33 } from "react";
58963
- import { Text as Text34 } from "ink";
59769
+ import { useState as useState39, useEffect as useEffect33 } from "react";
59770
+ import { Text as Text37 } from "ink";
58964
59771
  var analyticsCommand = new Command24("analytics").description("View analytics and execution results");
58965
59772
  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) => {
58966
59773
  const apiKey = await ensureAuth();
@@ -58988,10 +59795,10 @@ analyticsCommand.command("stats").description("Show account statistics").option(
58988
59795
  return;
58989
59796
  }
58990
59797
  const App = () => {
58991
- const [loading, setLoading] = useState36(true);
58992
- const [success2, setSuccess] = useState36(null);
58993
- const [error51, setError] = useState36(null);
58994
- const [resultNode, setResultNode] = useState36(void 0);
59798
+ const [loading, setLoading] = useState39(true);
59799
+ const [success2, setSuccess] = useState39(null);
59800
+ const [error51, setError] = useState39(null);
59801
+ const [resultNode, setResultNode] = useState39(void 0);
58995
59802
  useEffect33(() => {
58996
59803
  const run2 = async () => {
58997
59804
  try {
@@ -59072,10 +59879,10 @@ analyticsCommand.command("results").description("List execution results").option
59072
59879
  return;
59073
59880
  }
59074
59881
  const App = () => {
59075
- const [loading, setLoading] = useState36(true);
59076
- const [items, setItems] = useState36(null);
59077
- const [total, setTotal] = useState36(void 0);
59078
- const [error51, setError] = useState36(null);
59882
+ const [loading, setLoading] = useState39(true);
59883
+ const [items, setItems] = useState39(null);
59884
+ const [total, setTotal] = useState39(void 0);
59885
+ const [error51, setError] = useState39(null);
59079
59886
  useEffect33(() => {
59080
59887
  const run2 = async () => {
59081
59888
  try {
@@ -59104,7 +59911,7 @@ analyticsCommand.command("results").description("List execution results").option
59104
59911
  const r = item;
59105
59912
  const statusColor = r.status === "completed" ? "green" : "red";
59106
59913
  return React22.createElement(
59107
- Text34,
59914
+ Text37,
59108
59915
  { color: statusColor },
59109
59916
  ` ${r.id} [${r.status}] flow=${r.flowId} record=${r.recordId}${r.createdAt ? ` ${r.createdAt}` : ""}`
59110
59917
  );
@@ -59121,7 +59928,7 @@ import { Command as Command25 } from "commander";
59121
59928
  import chalk32 from "chalk";
59122
59929
  import React23 from "react";
59123
59930
  import { render as render23 } from "ink";
59124
- import { useState as useState37, useEffect as useEffect34 } from "react";
59931
+ import { useState as useState40, useEffect as useEffect34 } from "react";
59125
59932
  import open6 from "open";
59126
59933
  var billingCommand = new Command25("billing").description("View billing and subscription info");
59127
59934
  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) => {
@@ -59167,10 +59974,10 @@ billingCommand.command("status").description("Show current plan and usage").opti
59167
59974
  return;
59168
59975
  }
59169
59976
  const App = () => {
59170
- const [loading, setLoading] = useState37(true);
59171
- const [success2, setSuccess] = useState37(null);
59172
- const [error51, setError] = useState37(null);
59173
- const [resultNode, setResultNode] = useState37(void 0);
59977
+ const [loading, setLoading] = useState40(true);
59978
+ const [success2, setSuccess] = useState40(null);
59979
+ const [error51, setError] = useState40(null);
59980
+ const [resultNode, setResultNode] = useState40(void 0);
59174
59981
  useEffect34(() => {
59175
59982
  const run2 = async () => {
59176
59983
  try {
@@ -59238,10 +60045,10 @@ billingCommand.command("portal").description("Open the billing portal in your br
59238
60045
  return;
59239
60046
  }
59240
60047
  const App = () => {
59241
- const [loading, setLoading] = useState37(true);
59242
- const [success2, setSuccess] = useState37(null);
59243
- const [error51, setError] = useState37(null);
59244
- const [msg, setMsg] = useState37("Opening billing portal...");
60048
+ const [loading, setLoading] = useState40(true);
60049
+ const [success2, setSuccess] = useState40(null);
60050
+ const [error51, setError] = useState40(null);
60051
+ const [msg, setMsg] = useState40("Opening billing portal...");
59245
60052
  useEffect34(() => {
59246
60053
  const run2 = async () => {
59247
60054
  try {
@@ -59291,9 +60098,9 @@ billingCommand.command("refresh").description("Refresh plan data from billing pr
59291
60098
  return;
59292
60099
  }
59293
60100
  const App = () => {
59294
- const [loading, setLoading] = useState37(true);
59295
- const [success2, setSuccess] = useState37(null);
59296
- const [error51, setError] = useState37(null);
60101
+ const [loading, setLoading] = useState40(true);
60102
+ const [success2, setSuccess] = useState40(null);
60103
+ const [error51, setError] = useState40(null);
59297
60104
  useEffect34(() => {
59298
60105
  const run2 = async () => {
59299
60106
  try {
@@ -59325,8 +60132,8 @@ import { Command as Command26 } from "commander";
59325
60132
  import chalk33 from "chalk";
59326
60133
  import React24 from "react";
59327
60134
  import { render as render24 } from "ink";
59328
- import { useState as useState38, useEffect as useEffect35 } from "react";
59329
- import { Text as Text35 } from "ink";
60135
+ import { useState as useState41, useEffect as useEffect35 } from "react";
60136
+ import { Text as Text38 } from "ink";
59330
60137
  var flowVersionsCommand = new Command26("flow-versions").description(
59331
60138
  "Manage flow versions"
59332
60139
  );
@@ -59362,9 +60169,9 @@ flowVersionsCommand.command("list <flowId>").description("List all versions for
59362
60169
  return;
59363
60170
  }
59364
60171
  const App = () => {
59365
- const [loading, setLoading] = useState38(true);
59366
- const [items, setItems] = useState38(null);
59367
- const [error51, setError] = useState38(null);
60172
+ const [loading, setLoading] = useState41(true);
60173
+ const [items, setItems] = useState41(null);
60174
+ const [error51, setError] = useState41(null);
59368
60175
  useEffect35(() => {
59369
60176
  const run2 = async () => {
59370
60177
  try {
@@ -59388,7 +60195,7 @@ flowVersionsCommand.command("list <flowId>").description("List all versions for
59388
60195
  const v2 = item;
59389
60196
  const publishedTag = v2.published ? " [published]" : "";
59390
60197
  const versionNum = v2.version !== void 0 ? `v${v2.version}` : v2.id;
59391
- return React24.createElement(Text35, null, ` ${v2.id} ${versionNum}${publishedTag}${v2.createdAt ? ` ${v2.createdAt}` : ""}`);
60198
+ return React24.createElement(Text38, null, ` ${v2.id} ${versionNum}${publishedTag}${v2.createdAt ? ` ${v2.createdAt}` : ""}`);
59392
60199
  }
59393
60200
  });
59394
60201
  };
@@ -59423,10 +60230,10 @@ flowVersionsCommand.command("get <flowId> <versionId>").description("Get a speci
59423
60230
  return;
59424
60231
  }
59425
60232
  const App = () => {
59426
- const [loading, setLoading] = useState38(true);
59427
- const [success2, setSuccess] = useState38(null);
59428
- const [error51, setError] = useState38(null);
59429
- const [resultNode, setResultNode] = useState38(void 0);
60233
+ const [loading, setLoading] = useState41(true);
60234
+ const [success2, setSuccess] = useState41(null);
60235
+ const [error51, setError] = useState41(null);
60236
+ const [resultNode, setResultNode] = useState41(void 0);
59430
60237
  useEffect35(() => {
59431
60238
  const run2 = async () => {
59432
60239
  try {
@@ -59489,10 +60296,10 @@ flowVersionsCommand.command("published <flowId>").description("Get the published
59489
60296
  return;
59490
60297
  }
59491
60298
  const App = () => {
59492
- const [loading, setLoading] = useState38(true);
59493
- const [success2, setSuccess] = useState38(null);
59494
- const [error51, setError] = useState38(null);
59495
- const [resultNode, setResultNode] = useState38(void 0);
60299
+ const [loading, setLoading] = useState41(true);
60300
+ const [success2, setSuccess] = useState41(null);
60301
+ const [error51, setError] = useState41(null);
60302
+ const [resultNode, setResultNode] = useState41(void 0);
59496
60303
  useEffect35(() => {
59497
60304
  const run2 = async () => {
59498
60305
  try {
@@ -59546,9 +60353,9 @@ flowVersionsCommand.command("publish <flowId>").description("Publish a version")
59546
60353
  return;
59547
60354
  }
59548
60355
  const App = () => {
59549
- const [loading, setLoading] = useState38(true);
59550
- const [success2, setSuccess] = useState38(null);
59551
- const [error51, setError] = useState38(null);
60356
+ const [loading, setLoading] = useState41(true);
60357
+ const [success2, setSuccess] = useState41(null);
60358
+ const [error51, setError] = useState41(null);
59552
60359
  useEffect35(() => {
59553
60360
  const run2 = async () => {
59554
60361
  try {
@@ -59582,8 +60389,8 @@ import { Command as Command27 } from "commander";
59582
60389
  import chalk34 from "chalk";
59583
60390
  import React25 from "react";
59584
60391
  import { render as render25 } from "ink";
59585
- import { useState as useState39, useEffect as useEffect36 } from "react";
59586
- import { Text as Text36 } from "ink";
60392
+ import { useState as useState42, useEffect as useEffect36 } from "react";
60393
+ import { Text as Text39 } from "ink";
59587
60394
  var agentVersionsCommand = new Command27("agent-versions").description(
59588
60395
  "Manage agent versions"
59589
60396
  );
@@ -59620,10 +60427,10 @@ agentVersionsCommand.command("list <agentId>").description("List all versions fo
59620
60427
  return;
59621
60428
  }
59622
60429
  const App = () => {
59623
- const [loading, setLoading] = useState39(true);
59624
- const [items, setItems] = useState39(null);
59625
- const [publishedId, setPublishedId] = useState39(null);
59626
- const [error51, setError] = useState39(null);
60430
+ const [loading, setLoading] = useState42(true);
60431
+ const [items, setItems] = useState42(null);
60432
+ const [publishedId, setPublishedId] = useState42(null);
60433
+ const [error51, setError] = useState42(null);
59627
60434
  useEffect36(() => {
59628
60435
  const run2 = async () => {
59629
60436
  try {
@@ -59649,7 +60456,7 @@ agentVersionsCommand.command("list <agentId>").description("List all versions fo
59649
60456
  const liveTag = v2.id === publishedId ? " [live]" : "";
59650
60457
  const versionLabel = v2.label || (v2.versionNumber !== void 0 ? `v${v2.versionNumber}` : v2.id);
59651
60458
  return React25.createElement(
59652
- Text36,
60459
+ Text39,
59653
60460
  null,
59654
60461
  ` ${v2.id} ${versionLabel}${liveTag}${v2.createdAt ? ` ${v2.createdAt}` : ""}`
59655
60462
  );
@@ -59689,10 +60496,10 @@ agentVersionsCommand.command("get <agentId> <versionId>").description("Get a spe
59689
60496
  return;
59690
60497
  }
59691
60498
  const App = () => {
59692
- const [loading, setLoading] = useState39(true);
59693
- const [success2, setSuccess] = useState39(null);
59694
- const [error51, setError] = useState39(null);
59695
- const [resultNode, setResultNode] = useState39(void 0);
60499
+ const [loading, setLoading] = useState42(true);
60500
+ const [success2, setSuccess] = useState42(null);
60501
+ const [error51, setError] = useState42(null);
60502
+ const [resultNode, setResultNode] = useState42(void 0);
59696
60503
  useEffect36(() => {
59697
60504
  const run2 = async () => {
59698
60505
  try {
@@ -59759,10 +60566,10 @@ agentVersionsCommand.command("published <agentId>").description("Get the publish
59759
60566
  return;
59760
60567
  }
59761
60568
  const App = () => {
59762
- const [loading, setLoading] = useState39(true);
59763
- const [success2, setSuccess] = useState39(null);
59764
- const [error51, setError] = useState39(null);
59765
- const [resultNode, setResultNode] = useState39(void 0);
60569
+ const [loading, setLoading] = useState42(true);
60570
+ const [success2, setSuccess] = useState42(null);
60571
+ const [error51, setError] = useState42(null);
60572
+ const [resultNode, setResultNode] = useState42(void 0);
59766
60573
  useEffect36(() => {
59767
60574
  const run2 = async () => {
59768
60575
  try {
@@ -59819,9 +60626,9 @@ agentVersionsCommand.command("publish <agentId>").description("Publish a version
59819
60626
  return;
59820
60627
  }
59821
60628
  const App = () => {
59822
- const [loading, setLoading] = useState39(true);
59823
- const [success2, setSuccess] = useState39(null);
59824
- const [error51, setError] = useState39(null);
60629
+ const [loading, setLoading] = useState42(true);
60630
+ const [success2, setSuccess] = useState42(null);
60631
+ const [error51, setError] = useState42(null);
59825
60632
  useEffect36(() => {
59826
60633
  const run2 = async () => {
59827
60634
  try {
@@ -60097,7 +60904,7 @@ var tailCommand = new Command28("tail").description("Stream live execution logs
60097
60904
  // src/commands/validate-product.ts
60098
60905
  import { Command as Command29, Option } from "commander";
60099
60906
  import chalk36 from "chalk";
60100
- import { readFileSync as readFileSync15 } from "fs";
60907
+ import { readFileSync as readFileSync16 } from "fs";
60101
60908
  function createValidateProductCommand() {
60102
60909
  return new Command29("validate-product").description("Validate a product (FPO) or FPO template locally (no API call)").argument(
60103
60910
  "[input]",
@@ -60177,7 +60984,7 @@ async function readInput(input) {
60177
60984
  if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
60178
60985
  return trimmed;
60179
60986
  }
60180
- return readFileSync15(input, "utf-8");
60987
+ return readFileSync16(input, "utf-8");
60181
60988
  }
60182
60989
  async function readStdin() {
60183
60990
  if (process.stdin.isTTY) {
@@ -60279,8 +61086,8 @@ function printIssues(title, issues, color) {
60279
61086
  // src/commands/deploy.ts
60280
61087
  import { Command as Command30 } from "commander";
60281
61088
  import chalk37 from "chalk";
60282
- import * as fs14 from "fs";
60283
- import * as path14 from "path";
61089
+ import * as fs15 from "fs";
61090
+ import * as path15 from "path";
60284
61091
  import { RuntypeApiError as RuntypeApiError4 } from "@runtypelabs/sdk";
60285
61092
  function bashSingleQuote(s) {
60286
61093
  return "'" + s.replace(/'/g, "'\\''") + "'";
@@ -61250,8 +62057,8 @@ var deployCommand = new Command30("deploy").description("Export an agent or flow
61250
62057
  const apiKey = await ensureAuth();
61251
62058
  if (!apiKey) return;
61252
62059
  const client = createCliClient(apiKey);
61253
- const outDir = path14.resolve(options.output);
61254
- const projectName = options.name ?? slugify2(path14.basename(outDir));
62060
+ const outDir = path15.resolve(options.output);
62061
+ const projectName = options.name ?? slugify2(path15.basename(outDir));
61255
62062
  console.log(chalk37.cyan(`
61256
62063
  Scaffolding ${target} deployment to ${outDir}
61257
62064
  `));
@@ -61316,18 +62123,18 @@ Scaffolding ${target} deployment to ${outDir}
61316
62123
  }
61317
62124
  slugSet.add(slug);
61318
62125
  }
61319
- fs14.mkdirSync(path14.join(outDir, "agents"), { recursive: true });
61320
- fs14.mkdirSync(path14.join(outDir, "packages"), { recursive: true });
62126
+ fs15.mkdirSync(path15.join(outDir, "agents"), { recursive: true });
62127
+ fs15.mkdirSync(path15.join(outDir, "packages"), { recursive: true });
61321
62128
  for (const { name, def } of agentDefs) {
61322
62129
  const filename = `${slugify2(name)}.json`;
61323
- fs14.writeFileSync(path14.join(outDir, "agents", filename), JSON.stringify(def, null, 2));
62130
+ fs15.writeFileSync(path15.join(outDir, "agents", filename), JSON.stringify(def, null, 2));
61324
62131
  console.log(` Wrote agents/${filename}`);
61325
62132
  }
61326
62133
  const agentNames = agentDefs.map((a) => a.name);
61327
62134
  let monorepoRoot = process.cwd();
61328
62135
  for (let i = 0; i < 8; i++) {
61329
- if (fs14.existsSync(path14.join(monorepoRoot, "pnpm-workspace.yaml"))) break;
61330
- const parent = path14.dirname(monorepoRoot);
62136
+ if (fs15.existsSync(path15.join(monorepoRoot, "pnpm-workspace.yaml"))) break;
62137
+ const parent = path15.dirname(monorepoRoot);
61331
62138
  if (parent === monorepoRoot) break;
61332
62139
  monorepoRoot = parent;
61333
62140
  }
@@ -61337,35 +62144,35 @@ Scaffolding ${target} deployment to ${outDir}
61337
62144
  }
61338
62145
  const secretNames = Array.from(allSecrets);
61339
62146
  if (target === "cloudflare") {
61340
- fs14.mkdirSync(path14.join(outDir, "src"), { recursive: true });
61341
- fs14.writeFileSync(path14.join(outDir, "src", "index.ts"), workerIndexTs(agentSlugs));
61342
- fs14.writeFileSync(path14.join(outDir, "wrangler.toml"), wranglerToml(projectName));
61343
- fs14.writeFileSync(path14.join(outDir, "package.json"), workerPackageJson(projectName, "workspace:*"));
61344
- fs14.writeFileSync(path14.join(outDir, "tsconfig.json"), workerTsconfigJson());
61345
- const setupPath = path14.join(outDir, "setup.sh");
61346
- fs14.writeFileSync(setupPath, workerSetupSh(monorepoRoot));
61347
- fs14.chmodSync(setupPath, 493);
61348
- fs14.writeFileSync(path14.join(outDir, "README.md"), workerReadme(agentNames, secretNames));
62147
+ fs15.mkdirSync(path15.join(outDir, "src"), { recursive: true });
62148
+ fs15.writeFileSync(path15.join(outDir, "src", "index.ts"), workerIndexTs(agentSlugs));
62149
+ fs15.writeFileSync(path15.join(outDir, "wrangler.toml"), wranglerToml(projectName));
62150
+ fs15.writeFileSync(path15.join(outDir, "package.json"), workerPackageJson(projectName, "workspace:*"));
62151
+ fs15.writeFileSync(path15.join(outDir, "tsconfig.json"), workerTsconfigJson());
62152
+ const setupPath = path15.join(outDir, "setup.sh");
62153
+ fs15.writeFileSync(setupPath, workerSetupSh(monorepoRoot));
62154
+ fs15.chmodSync(setupPath, 493);
62155
+ fs15.writeFileSync(path15.join(outDir, "README.md"), workerReadme(agentNames, secretNames));
61349
62156
  } else if (target === "vercel") {
61350
- fs14.mkdirSync(path14.join(outDir, "api"), { recursive: true });
61351
- fs14.writeFileSync(path14.join(outDir, "api", "[[...route]].ts"), vercelRouteTs(agentSlugs));
61352
- fs14.writeFileSync(path14.join(outDir, "vercel.json"), vercelJson());
61353
- fs14.writeFileSync(path14.join(outDir, "package.json"), vercelPackageJson(projectName, "workspace:*"));
61354
- fs14.writeFileSync(path14.join(outDir, "tsconfig.json"), vercelTsconfigJson());
61355
- const setupPath = path14.join(outDir, "setup.sh");
61356
- fs14.writeFileSync(setupPath, vercelSetupSh(monorepoRoot));
61357
- fs14.chmodSync(setupPath, 493);
61358
- fs14.writeFileSync(path14.join(outDir, "README.md"), vercelReadme(agentNames, secretNames));
62157
+ fs15.mkdirSync(path15.join(outDir, "api"), { recursive: true });
62158
+ fs15.writeFileSync(path15.join(outDir, "api", "[[...route]].ts"), vercelRouteTs(agentSlugs));
62159
+ fs15.writeFileSync(path15.join(outDir, "vercel.json"), vercelJson());
62160
+ fs15.writeFileSync(path15.join(outDir, "package.json"), vercelPackageJson(projectName, "workspace:*"));
62161
+ fs15.writeFileSync(path15.join(outDir, "tsconfig.json"), vercelTsconfigJson());
62162
+ const setupPath = path15.join(outDir, "setup.sh");
62163
+ fs15.writeFileSync(setupPath, vercelSetupSh(monorepoRoot));
62164
+ fs15.chmodSync(setupPath, 493);
62165
+ fs15.writeFileSync(path15.join(outDir, "README.md"), vercelReadme(agentNames, secretNames));
61359
62166
  } else {
61360
- fs14.writeFileSync(path14.join(outDir, "server.ts"), serverTs());
61361
- fs14.writeFileSync(path14.join(outDir, "Dockerfile"), dockerfile());
61362
- fs14.writeFileSync(path14.join(outDir, ".dockerignore"), dockerignore());
61363
- fs14.writeFileSync(path14.join(outDir, "tsconfig.json"), tsconfigJson());
61364
- fs14.writeFileSync(path14.join(outDir, "package.json"), packageJson(projectName, "workspace:*"));
61365
- const setupPath = path14.join(outDir, "setup.sh");
61366
- fs14.writeFileSync(setupPath, setupSh(monorepoRoot));
61367
- fs14.chmodSync(setupPath, 493);
61368
- fs14.writeFileSync(path14.join(outDir, "README.md"), readme(agentNames, secretNames));
62167
+ fs15.writeFileSync(path15.join(outDir, "server.ts"), serverTs());
62168
+ fs15.writeFileSync(path15.join(outDir, "Dockerfile"), dockerfile());
62169
+ fs15.writeFileSync(path15.join(outDir, ".dockerignore"), dockerignore());
62170
+ fs15.writeFileSync(path15.join(outDir, "tsconfig.json"), tsconfigJson());
62171
+ fs15.writeFileSync(path15.join(outDir, "package.json"), packageJson(projectName, "workspace:*"));
62172
+ const setupPath = path15.join(outDir, "setup.sh");
62173
+ fs15.writeFileSync(setupPath, setupSh(monorepoRoot));
62174
+ fs15.chmodSync(setupPath, 493);
62175
+ fs15.writeFileSync(path15.join(outDir, "README.md"), readme(agentNames, secretNames));
61369
62176
  }
61370
62177
  console.log("");
61371
62178
  console.log(chalk37.green(`\u2713 Scaffold written to ${outDir}`));
@@ -61423,19 +62230,19 @@ import { Command as Command31 } from "commander";
61423
62230
  import chalk39 from "chalk";
61424
62231
 
61425
62232
  // src/lib/skills-install.ts
61426
- import { mkdirSync as mkdirSync8, readFileSync as readFileSync16, writeFileSync as writeFileSync7 } from "fs";
61427
- import path15 from "path";
62233
+ import { mkdirSync as mkdirSync9, readFileSync as readFileSync17, writeFileSync as writeFileSync7 } from "fs";
62234
+ import path16 from "path";
61428
62235
  import readline4 from "readline";
61429
62236
  import chalk38 from "chalk";
61430
62237
  var SKILLS_REPO = "runtypelabs/skills";
61431
62238
  var SKILLS_INSTALL_RETRY_HINT = "Retry with `runtype skills install`, or install manually: npx skills add runtypelabs/skills";
61432
62239
  var METADATA_FILENAME = "agents-skills-install.json";
61433
62240
  function metadataPath() {
61434
- return path15.join(getRuntypeHomeDir(), METADATA_FILENAME);
62241
+ return path16.join(getRuntypeHomeDir(), METADATA_FILENAME);
61435
62242
  }
61436
62243
  function readSkillsInstallMetadata() {
61437
62244
  try {
61438
- const raw = readFileSync16(metadataPath(), "utf8");
62245
+ const raw = readFileSync17(metadataPath(), "utf8");
61439
62246
  const parsed = JSON.parse(raw);
61440
62247
  if (typeof parsed === "object" && parsed !== null && !Array.isArray(parsed) && parsed.version === 1 && typeof parsed.accepted === "boolean") {
61441
62248
  return parsed;
@@ -61447,7 +62254,7 @@ function readSkillsInstallMetadata() {
61447
62254
  }
61448
62255
  function writeSkillsInstallMetadata(metadata) {
61449
62256
  try {
61450
- mkdirSync8(path15.dirname(metadataPath()), { recursive: true });
62257
+ mkdirSync9(path16.dirname(metadataPath()), { recursive: true });
61451
62258
  writeFileSync7(metadataPath(), JSON.stringify(metadata, null, 2));
61452
62259
  } catch {
61453
62260
  }