@supatest/cli 0.0.60 → 0.0.62

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 +381 -149
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -20,7 +20,8 @@ var init_config = __esm({
20
20
  const envFile = process.env.ENV_NAME ? `.env.${process.env.ENV_NAME}` : ".env";
21
21
  try {
22
22
  const dotenv = await import("dotenv");
23
- dotenv.config({ path: resolve(process.cwd(), envFile) });
23
+ const cliDir = new URL(".", import.meta.url).pathname;
24
+ dotenv.config({ path: resolve(cliDir, "..", envFile) });
24
25
  } catch (error) {
25
26
  }
26
27
  }
@@ -5887,7 +5888,7 @@ var CLI_VERSION;
5887
5888
  var init_version = __esm({
5888
5889
  "src/version.ts"() {
5889
5890
  "use strict";
5890
- CLI_VERSION = "0.0.60";
5891
+ CLI_VERSION = "0.0.62";
5891
5892
  }
5892
5893
  });
5893
5894
 
@@ -7735,7 +7736,7 @@ ${projectInstructions}`,
7735
7736
  return result;
7736
7737
  }
7737
7738
  async resolveClaudeCodePath() {
7738
- const fs4 = await import("fs/promises");
7739
+ const fs5 = await import("fs/promises");
7739
7740
  let claudeCodePath;
7740
7741
  const require2 = createRequire(import.meta.url);
7741
7742
  const sdkPath = require2.resolve("@anthropic-ai/claude-agent-sdk");
@@ -7746,7 +7747,7 @@ ${projectInstructions}`,
7746
7747
  logger.debug(`[agent] Using SUPATEST_CLAUDE_CODE_PATH override: ${claudeCodePath}`);
7747
7748
  }
7748
7749
  try {
7749
- await fs4.access(claudeCodePath);
7750
+ await fs5.access(claudeCodePath);
7750
7751
  logger.debug(`[agent] Claude Code CLI found: ${claudeCodePath}`);
7751
7752
  } catch {
7752
7753
  const error = `Claude Code executable not found at: ${claudeCodePath}
@@ -8382,61 +8383,275 @@ var init_banner = __esm({
8382
8383
  }
8383
8384
  });
8384
8385
 
8386
+ // src/ui/utils/detect-terminal-theme.ts
8387
+ import { execSync as execSync2 } from "child_process";
8388
+ import * as fs3 from "fs";
8389
+ function parseX11Rgb(r, g, b) {
8390
+ const normalize = (hex) => {
8391
+ const val = Number.parseInt(hex, 16);
8392
+ switch (hex.length) {
8393
+ case 1:
8394
+ return val * 17;
8395
+ // 0xF -> 255
8396
+ case 2:
8397
+ return val;
8398
+ // 0xFF -> 255
8399
+ case 3:
8400
+ return Math.round(val / 16.06);
8401
+ // 0xFFF -> 255
8402
+ case 4:
8403
+ return Math.round(val / 257);
8404
+ // 0xFFFF -> 255
8405
+ default:
8406
+ return val;
8407
+ }
8408
+ };
8409
+ return { r: normalize(r), g: normalize(g), b: normalize(b) };
8410
+ }
8411
+ function luminance(r, g, b) {
8412
+ const [rs, gs, bs] = [r / 255, g / 255, b / 255].map(
8413
+ (c) => c <= 0.03928 ? c / 12.92 : ((c + 0.055) / 1.055) ** 2.4
8414
+ );
8415
+ return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs;
8416
+ }
8417
+ function fromEnvOverride() {
8418
+ const val = process.env.SUPATEST_THEME?.toLowerCase();
8419
+ if (val === "dark" || val === "light") return val;
8420
+ return null;
8421
+ }
8422
+ function fromColorfgbg() {
8423
+ const val = process.env.COLORFGBG;
8424
+ if (!val) return null;
8425
+ const parts = val.split(";");
8426
+ const bg = Number.parseInt(parts[parts.length - 1], 10);
8427
+ if (Number.isNaN(bg)) return null;
8428
+ if (bg >= 0 && bg <= 6) return "dark";
8429
+ if (bg >= 9 && bg <= 15) return "light";
8430
+ return null;
8431
+ }
8432
+ function fromOsc11() {
8433
+ if (!process.stdin.isTTY || !process.stdout.isTTY) return null;
8434
+ if (!process.stdin.setRawMode) return null;
8435
+ let ttyFd = null;
8436
+ try {
8437
+ ttyFd = fs3.openSync("/dev/tty", fs3.constants.O_RDWR | fs3.constants.O_NONBLOCK);
8438
+ process.stdin.setRawMode(true);
8439
+ fs3.writeSync(ttyFd, "\x1B]11;?\x07");
8440
+ const buf = Buffer.alloc(64);
8441
+ let response = "";
8442
+ const startTime = Date.now();
8443
+ const TIMEOUT_MS = 100;
8444
+ while (Date.now() - startTime < TIMEOUT_MS) {
8445
+ try {
8446
+ const bytesRead = fs3.readSync(ttyFd, buf, 0, buf.length, null);
8447
+ if (bytesRead > 0) {
8448
+ response += buf.toString("utf8", 0, bytesRead);
8449
+ if (response.includes("\x07") || response.includes("\x1B\\")) {
8450
+ break;
8451
+ }
8452
+ }
8453
+ } catch {
8454
+ }
8455
+ }
8456
+ process.stdin.setRawMode(false);
8457
+ fs3.closeSync(ttyFd);
8458
+ ttyFd = null;
8459
+ if (!response) return null;
8460
+ const match = response.match(/rgb:([0-9a-fA-F]+)\/([0-9a-fA-F]+)\/([0-9a-fA-F]+)/);
8461
+ if (!match) return null;
8462
+ const rgb = parseX11Rgb(match[1], match[2], match[3]);
8463
+ const lum = luminance(rgb.r, rgb.g, rgb.b);
8464
+ return lum < 0.5 ? "dark" : "light";
8465
+ } catch {
8466
+ return null;
8467
+ } finally {
8468
+ try {
8469
+ process.stdin.setRawMode?.(false);
8470
+ } catch {
8471
+ }
8472
+ if (ttyFd !== null) {
8473
+ try {
8474
+ fs3.closeSync(ttyFd);
8475
+ } catch {
8476
+ }
8477
+ }
8478
+ }
8479
+ }
8480
+ function fromMacOsDarkMode() {
8481
+ if (process.platform !== "darwin") return null;
8482
+ try {
8483
+ const result = execSync2("defaults read -g AppleInterfaceStyle 2>/dev/null", {
8484
+ encoding: "utf8",
8485
+ timeout: 500
8486
+ }).trim();
8487
+ return result === "Dark" ? "dark" : "light";
8488
+ } catch {
8489
+ return "light";
8490
+ }
8491
+ }
8492
+ function detectTerminalTheme() {
8493
+ return fromEnvOverride() ?? fromColorfgbg() ?? fromOsc11() ?? fromMacOsDarkMode() ?? "dark";
8494
+ }
8495
+ var init_detect_terminal_theme = __esm({
8496
+ "src/ui/utils/detect-terminal-theme.ts"() {
8497
+ "use strict";
8498
+ }
8499
+ });
8500
+
8385
8501
  // src/ui/utils/theme.ts
8386
- var theme;
8502
+ var theme_exports = {};
8503
+ __export(theme_exports, {
8504
+ getThemeColor: () => getThemeColor,
8505
+ getThemeMode: () => getThemeMode,
8506
+ initTheme: () => initTheme,
8507
+ setThemeMode: () => setThemeMode,
8508
+ theme: () => theme
8509
+ });
8510
+ function getThemeMode() {
8511
+ return activeMode;
8512
+ }
8513
+ function applyPalette(palette) {
8514
+ for (const section of Object.keys(palette)) {
8515
+ const src = palette[section];
8516
+ const dst = theme[section];
8517
+ for (const key of Object.keys(src)) {
8518
+ dst[key] = src[key];
8519
+ }
8520
+ }
8521
+ }
8522
+ function initTheme() {
8523
+ activeMode = detectTerminalTheme();
8524
+ applyPalette(activeMode === "light" ? lightTheme : darkTheme);
8525
+ return activeMode;
8526
+ }
8527
+ function setThemeMode(mode) {
8528
+ activeMode = mode;
8529
+ applyPalette(mode === "light" ? lightTheme : darkTheme);
8530
+ }
8531
+ function getThemeColor(path5) {
8532
+ const parts = path5.split(".");
8533
+ let current = theme;
8534
+ for (const part of parts) {
8535
+ if (current[part] === void 0) {
8536
+ return theme.text.primary;
8537
+ }
8538
+ current = current[part];
8539
+ }
8540
+ return typeof current === "string" ? current : theme.text.primary;
8541
+ }
8542
+ var darkTheme, lightTheme, theme, activeMode;
8387
8543
  var init_theme = __esm({
8388
8544
  "src/ui/utils/theme.ts"() {
8389
8545
  "use strict";
8390
- theme = {
8391
- // Text colors
8546
+ init_detect_terminal_theme();
8547
+ darkTheme = {
8392
8548
  text: {
8393
8549
  primary: "#FFFFFF",
8394
8550
  secondary: "#A0AEC0",
8395
- dim: "#8C99B2",
8396
- accent: "#38B2AC",
8397
- // Cyan/teal accent
8398
- /** High-contrast background for focused/highlighted items — use with white text */
8551
+ // light gray — readable body text on dark bg
8552
+ dim: "#718096",
8553
+ // medium gray — clearly softer than secondary
8554
+ accent: "#2DD4BF",
8555
+ // brighter teal — stands out for interactive elements
8399
8556
  accentBg: "#1A6B67",
8557
+ // dark teal bg — white text readable on this
8400
8558
  success: "#48BB78",
8401
- error: "#F56565",
8402
- warning: "#ED8936",
8403
- info: "#4299E1"
8559
+ error: "#FC8181",
8560
+ // slightly brighter red — easier to spot on dark bg
8561
+ warning: "#F6AD55",
8562
+ // warmer amber — better visibility on dark
8563
+ info: "#63B3ED"
8564
+ // brighter blue — pops more on dark
8404
8565
  },
8405
- // Background colors (for boxed content)
8406
8566
  bg: {
8407
8567
  primary: "#1A202C",
8408
8568
  secondary: "#2D3748",
8409
8569
  accent: "#234E52"
8410
8570
  },
8411
- // Borders
8412
8571
  border: {
8413
- default: "#8C99B2",
8414
- accent: "#38B2AC",
8415
- error: "#F56565"
8572
+ default: "#4A5568",
8573
+ // darker gray — distinct from text.dim and text.secondary
8574
+ accent: "#2DD4BF",
8575
+ // match text accent
8576
+ error: "#FC8181"
8416
8577
  },
8417
- // Tool/action colors
8418
8578
  tool: {
8419
- read: "#4299E1",
8420
- // Blue
8579
+ read: "#63B3ED",
8580
+ // brighter blue
8421
8581
  write: "#48BB78",
8422
- // Green
8423
- edit: "#ED8936",
8424
- // Orange
8425
- bash: "#38B2AC",
8426
- // Cyan
8427
- search: "#9F7AEA",
8428
- // Purple
8429
- agent: "#ED64A6"
8430
- // Pink
8582
+ edit: "#F6AD55",
8583
+ // warmer amber
8584
+ bash: "#4FD1C5",
8585
+ // lighter teal — distinct from accent
8586
+ search: "#B794F4",
8587
+ // brighter purple
8588
+ agent: "#F687B3"
8589
+ // brighter pink
8431
8590
  },
8432
- // Status colors
8433
8591
  status: {
8434
8592
  pending: "#A0AEC0",
8435
- inProgress: "#ED8936",
8593
+ inProgress: "#F6AD55",
8436
8594
  completed: "#48BB78",
8437
- failed: "#F56565"
8595
+ failed: "#FC8181"
8596
+ }
8597
+ };
8598
+ lightTheme = {
8599
+ text: {
8600
+ primary: "#1A202C",
8601
+ // near-black — high contrast on white
8602
+ secondary: "#2D3748",
8603
+ // dark gray — clearly readable
8604
+ dim: "#4A5568",
8605
+ // medium-dark gray — replaces the too-faint #718096
8606
+ accent: "#0F766E",
8607
+ // deeper teal — punchy on white/light gray
8608
+ accentBg: "#115E59",
8609
+ // dark teal bg — white text must be readable on this
8610
+ success: "#15803D",
8611
+ // dark green — readable on white
8612
+ error: "#B91C1C",
8613
+ // dark red
8614
+ warning: "#B45309",
8615
+ // dark amber
8616
+ info: "#1D4ED8"
8617
+ // dark blue
8618
+ },
8619
+ bg: {
8620
+ primary: "#F7FAFC",
8621
+ secondary: "#E2E8F0",
8622
+ // slightly darker so it's visible as a distinct region
8623
+ accent: "#CCFBF1"
8624
+ },
8625
+ border: {
8626
+ default: "#94A3B8",
8627
+ // slate-400 — visible on white without being heavy
8628
+ accent: "#0F766E",
8629
+ // match text accent
8630
+ error: "#B91C1C"
8631
+ },
8632
+ tool: {
8633
+ read: "#1D4ED8",
8634
+ // dark blue
8635
+ write: "#15803D",
8636
+ // dark green
8637
+ edit: "#B45309",
8638
+ // dark amber
8639
+ bash: "#0F766E",
8640
+ // deep teal
8641
+ search: "#6D28D9",
8642
+ // dark purple
8643
+ agent: "#BE185D"
8644
+ // dark pink
8645
+ },
8646
+ status: {
8647
+ pending: "#4A5568",
8648
+ inProgress: "#B45309",
8649
+ completed: "#15803D",
8650
+ failed: "#B91C1C"
8438
8651
  }
8439
8652
  };
8653
+ theme = { ...darkTheme };
8654
+ activeMode = "dark";
8440
8655
  }
8441
8656
  });
8442
8657
 
@@ -10759,6 +10974,12 @@ import { spawn as spawn3 } from "child_process";
10759
10974
  import crypto3 from "crypto";
10760
10975
  import http from "http";
10761
10976
  import { platform } from "os";
10977
+ function getFrontendUrl() {
10978
+ return process.env.SUPATEST_FRONTEND_URL || "https://code.supatest.ai";
10979
+ }
10980
+ function getApiUrl() {
10981
+ return process.env.SUPATEST_API_URL || "https://code-api.supatest.ai";
10982
+ }
10762
10983
  function escapeHtml(text) {
10763
10984
  return text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;");
10764
10985
  }
@@ -10766,7 +10987,7 @@ function generateState() {
10766
10987
  return crypto3.randomBytes(STATE_LENGTH).toString("hex");
10767
10988
  }
10768
10989
  async function exchangeCodeForToken(code, state) {
10769
- const response = await fetch(`${API_URL}/web/auth/cli-token-exchange`, {
10990
+ const response = await fetch(`${getApiUrl()}/web/auth/cli-token-exchange`, {
10770
10991
  method: "POST",
10771
10992
  headers: { "Content-Type": "application/json" },
10772
10993
  body: JSON.stringify({ code, state })
@@ -10976,7 +11197,7 @@ function buildResultPage(config2) {
10976
11197
  <body>
10977
11198
  <div class="container">
10978
11199
  <div class="logo">
10979
- <img src="${FRONTEND_URL}/logo.png" alt="Supatest Logo" />
11200
+ <img src="${getFrontendUrl()}/logo.png" alt="Supatest Logo" />
10980
11201
  <span class="logo-text">Supatest</span>
10981
11202
  </div>
10982
11203
  <div class="${iconClass}" role="img" aria-label="${iconAriaLabel}">${iconEmoji}</div>
@@ -11047,7 +11268,7 @@ async function loginCommand() {
11047
11268
  `);
11048
11269
  throw error;
11049
11270
  }
11050
- const loginUrl = `${FRONTEND_URL}/cli-login?port=${port}&state=${state}`;
11271
+ const loginUrl = `${getFrontendUrl()}/cli-login?port=${port}&state=${state}`;
11051
11272
  console.log(`Opening browser to: ${loginUrl}`);
11052
11273
  console.log("\nIf your browser doesn't open automatically, please visit the URL above.\n");
11053
11274
  try {
@@ -11085,13 +11306,11 @@ ${loginUrl}
11085
11306
  throw error;
11086
11307
  }
11087
11308
  }
11088
- var LOGIN_RETRY_PORTS, FRONTEND_URL, API_URL, CALLBACK_TIMEOUT_MS, STATE_LENGTH;
11309
+ var LOGIN_RETRY_PORTS, CALLBACK_TIMEOUT_MS, STATE_LENGTH;
11089
11310
  var init_login = __esm({
11090
11311
  "src/commands/login.ts"() {
11091
11312
  "use strict";
11092
11313
  LOGIN_RETRY_PORTS = [8420, 8422, 8423];
11093
- FRONTEND_URL = process.env.SUPATEST_FRONTEND_URL || "https://code.supatest.ai";
11094
- API_URL = process.env.SUPATEST_API_URL || "https://code-api.supatest.ai";
11095
11314
  CALLBACK_TIMEOUT_MS = 3e5;
11096
11315
  STATE_LENGTH = 32;
11097
11316
  }
@@ -12191,7 +12410,7 @@ __export(secret_storage_exports, {
12191
12410
  listSecrets: () => listSecrets,
12192
12411
  setSecret: () => setSecret
12193
12412
  });
12194
- import { promises as fs3 } from "fs";
12413
+ import { promises as fs4 } from "fs";
12195
12414
  import { homedir as homedir7 } from "os";
12196
12415
  import { dirname as dirname2, join as join9 } from "path";
12197
12416
  async function getSecret(key) {
@@ -12223,11 +12442,11 @@ var init_secret_storage = __esm({
12223
12442
  }
12224
12443
  async ensureDirectoryExists() {
12225
12444
  const dir = dirname2(this.secretFilePath);
12226
- await fs3.mkdir(dir, { recursive: true, mode: 448 });
12445
+ await fs4.mkdir(dir, { recursive: true, mode: 448 });
12227
12446
  }
12228
12447
  async loadSecrets() {
12229
12448
  try {
12230
- const data = await fs3.readFile(this.secretFilePath, "utf-8");
12449
+ const data = await fs4.readFile(this.secretFilePath, "utf-8");
12231
12450
  const secrets = JSON.parse(data);
12232
12451
  return new Map(Object.entries(secrets));
12233
12452
  } catch (error) {
@@ -12236,7 +12455,7 @@ var init_secret_storage = __esm({
12236
12455
  return /* @__PURE__ */ new Map();
12237
12456
  }
12238
12457
  try {
12239
- await fs3.unlink(this.secretFilePath);
12458
+ await fs4.unlink(this.secretFilePath);
12240
12459
  } catch {
12241
12460
  }
12242
12461
  return /* @__PURE__ */ new Map();
@@ -12246,7 +12465,7 @@ var init_secret_storage = __esm({
12246
12465
  await this.ensureDirectoryExists();
12247
12466
  const data = Object.fromEntries(secrets);
12248
12467
  const json = JSON.stringify(data, null, 2);
12249
- await fs3.writeFile(this.secretFilePath, json, { mode: 384 });
12468
+ await fs4.writeFile(this.secretFilePath, json, { mode: 384 });
12250
12469
  }
12251
12470
  async getSecret(key) {
12252
12471
  const secrets = await this.loadSecrets();
@@ -12265,7 +12484,7 @@ var init_secret_storage = __esm({
12265
12484
  secrets.delete(key);
12266
12485
  if (secrets.size === 0) {
12267
12486
  try {
12268
- await fs3.unlink(this.secretFilePath);
12487
+ await fs4.unlink(this.secretFilePath);
12269
12488
  } catch (error) {
12270
12489
  const err = error;
12271
12490
  if (err.code !== "ENOENT") {
@@ -13665,7 +13884,7 @@ var init_markdown_builder = __esm({
13665
13884
  });
13666
13885
 
13667
13886
  // src/fix/context-builder.ts
13668
- function getFrontendUrl() {
13887
+ function getFrontendUrl2() {
13669
13888
  return process.env.SUPATEST_FRONTEND_URL || "https://app.supatest.dev";
13670
13889
  }
13671
13890
  function buildQuickFixPrompt(testCount, contextFilePath) {
@@ -13675,7 +13894,7 @@ function buildQuickFixPrompt(testCount, contextFilePath) {
13675
13894
  Error context: ${contextFilePath}`;
13676
13895
  }
13677
13896
  function buildUnderstandAndFixPrompt(failedCount, run, contextFilePath) {
13678
- const frontendUrl = getFrontendUrl();
13897
+ const frontendUrl = getFrontendUrl2();
13679
13898
  const runDetailUrl = `${frontendUrl}/runs/${run.id}`;
13680
13899
  const md = new MarkdownBuilder();
13681
13900
  const failureWord = failedCount === 1 ? "failure" : "failures";
@@ -13719,7 +13938,7 @@ function getAutomateContextPath(cwd, timestamp) {
13719
13938
  return join12(getAutomateContextDir(cwd), `manual-tests-${timestamp}.md`);
13720
13939
  }
13721
13940
  function formatTestForContextFile(test, index) {
13722
- const frontendUrl = getFrontendUrl();
13941
+ const frontendUrl = getFrontendUrl2();
13723
13942
  const md = new MarkdownBuilder();
13724
13943
  md.push(`### Test ${index + 1}: ${test.readableId} \u2014 ${test.title}`);
13725
13944
  if (test.priority) md.push(`- **Priority**: ${test.priority}`);
@@ -13958,7 +14177,7 @@ var init_ConflictResolver = __esm({
13958
14177
  return;
13959
14178
  }
13960
14179
  });
13961
- return /* @__PURE__ */ React19.createElement(Box16, { borderColor: "yellow", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React19.createElement(Text14, { bold: true, color: "yellow" }, "Assignment Conflicts"), /* @__PURE__ */ React19.createElement(Box16, { marginBottom: 1, marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text14, { color: theme.text.dim }, "These tests are already assigned:")), /* @__PURE__ */ React19.createElement(Box16, { flexDirection: "column" }, conflicts.map((conflict, index) => {
14180
+ return /* @__PURE__ */ React19.createElement(Box16, { borderColor: theme.text.warning, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React19.createElement(Text14, { bold: true, color: theme.text.warning }, "Assignment Conflicts"), /* @__PURE__ */ React19.createElement(Box16, { marginBottom: 1, marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text14, { color: theme.text.dim }, "These tests are already assigned:")), /* @__PURE__ */ React19.createElement(Box16, { flexDirection: "column" }, conflicts.map((conflict, index) => {
13962
14181
  const isFocused = index === focusIndex;
13963
14182
  const decision = decisions.get(conflict.testId) ?? "skip";
13964
14183
  const indicator = isFocused ? "\u25B6 " : " ";
@@ -13970,7 +14189,7 @@ var init_ConflictResolver = __esm({
13970
14189
  color: isFocused ? theme.text.primary : theme.text.dim
13971
14190
  },
13972
14191
  indicator,
13973
- /* @__PURE__ */ React19.createElement(Text14, { color: decision === "takeOver" ? "green" : "yellow" }, actionLabel),
14192
+ /* @__PURE__ */ React19.createElement(Text14, { color: decision === "takeOver" ? theme.text.success : theme.text.warning }, actionLabel),
13974
14193
  " ",
13975
14194
  conflict.testFile,
13976
14195
  " - ",
@@ -13986,18 +14205,26 @@ var init_ConflictResolver = __esm({
13986
14205
  // src/ui/components/ManualTestSelector.tsx
13987
14206
  import { Box as Box17, Text as Text15, useInput as useInput2 } from "ink";
13988
14207
  import React20, { useEffect as useEffect6, useRef as useRef6, useState as useState6 } from "react";
13989
- var PAGE_SIZE, VISIBLE_ITEMS, PRIORITY_COLORS, ManualTestSelector;
14208
+ var PAGE_SIZE, VISIBLE_ITEMS, getPriorityColor, ManualTestSelector;
13990
14209
  var init_ManualTestSelector = __esm({
13991
14210
  "src/ui/components/ManualTestSelector.tsx"() {
13992
14211
  "use strict";
13993
14212
  init_theme();
13994
14213
  PAGE_SIZE = 50;
13995
14214
  VISIBLE_ITEMS = 10;
13996
- PRIORITY_COLORS = {
13997
- critical: "red",
13998
- high: "yellow",
13999
- medium: "cyan",
14000
- low: "green"
14215
+ getPriorityColor = (priority) => {
14216
+ switch (priority) {
14217
+ case "critical":
14218
+ return theme.text.error;
14219
+ case "high":
14220
+ return theme.text.warning;
14221
+ case "medium":
14222
+ return theme.text.accent;
14223
+ case "low":
14224
+ return theme.text.success;
14225
+ default:
14226
+ return theme.text.dim;
14227
+ }
14001
14228
  };
14002
14229
  ManualTestSelector = ({
14003
14230
  apiClient,
@@ -14140,19 +14367,19 @@ var init_ManualTestSelector = __esm({
14140
14367
  }
14141
14368
  });
14142
14369
  if (error) {
14143
- return /* @__PURE__ */ React20.createElement(Box17, { borderColor: "red", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: "red" }, "Error Loading Manual Tests"), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, error), /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "ESC"), " to go back")));
14370
+ return /* @__PURE__ */ React20.createElement(Box17, { borderColor: theme.border.error, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: theme.text.error }, "Error Loading Manual Tests"), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, error), /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "ESC"), " to go back")));
14144
14371
  }
14145
14372
  if (allTests.length === 0 && isLoading) {
14146
- return /* @__PURE__ */ React20.createElement(Box17, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: "cyan" }, "Loading Manual Tests..."), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Fetching your manual test catalog"));
14373
+ return /* @__PURE__ */ React20.createElement(Box17, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: theme.text.accent }, "Loading Manual Tests..."), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Fetching your manual test catalog"));
14147
14374
  }
14148
14375
  if (allTests.length === 0 && !isLoading) {
14149
- return /* @__PURE__ */ React20.createElement(Box17, { borderColor: "yellow", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: "yellow" }, "No Manual Tests Found"), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Create manual tests in the dashboard or via MCP first."), /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "ESC"), " to go back")));
14376
+ return /* @__PURE__ */ React20.createElement(Box17, { borderColor: theme.text.warning, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: theme.text.warning }, "No Manual Tests Found"), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Create manual tests in the dashboard or via MCP first."), /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "ESC"), " to go back")));
14150
14377
  }
14151
14378
  const testStartIndex = cursorIndex - 1;
14152
14379
  const adjustedStart = isOnAutomateNext ? 0 : Math.max(0, testStartIndex - Math.floor(VISIBLE_ITEMS / 2));
14153
14380
  const adjustedEnd = Math.min(allTests.length, adjustedStart + VISIBLE_ITEMS);
14154
14381
  const visibleTests = allTests.slice(adjustedStart, adjustedEnd);
14155
- return /* @__PURE__ */ React20.createElement(Box17, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: "cyan" }, "Manual Tests", /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, " \u2022 ", total, " total"), searchQuery && /* @__PURE__ */ React20.createElement(Text15, { color: "yellow" }, ' \u2022 search: "', searchQuery, '"'))), isSearchMode ? /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: "cyan" }, "Search: "), /* @__PURE__ */ React20.createElement(Text15, null, pendingSearch), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "\u2588")) : /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "/"), " to search")), /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(
14382
+ return /* @__PURE__ */ React20.createElement(Box17, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { bold: true, color: theme.text.accent }, "Manual Tests", /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, " \u2022 ", total, " total"), searchQuery && /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.warning }, ' \u2022 search: "', searchQuery, '"'))), isSearchMode ? /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.accent }, "Search: "), /* @__PURE__ */ React20.createElement(Text15, null, pendingSearch), /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "\u2588")) : /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "/"), " to search")), /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(
14156
14383
  Text15,
14157
14384
  {
14158
14385
  backgroundColor: isOnAutomateNext ? theme.text.accentBg : void 0,
@@ -14185,7 +14412,7 @@ var init_ManualTestSelector = __esm({
14185
14412
  Text15,
14186
14413
  {
14187
14414
  backgroundColor: bgColor,
14188
- color: isChecked ? "green" : isSelected ? "white" : theme.text.dim
14415
+ color: isChecked ? theme.text.success : isSelected ? "white" : theme.text.dim
14189
14416
  },
14190
14417
  checkbox
14191
14418
  ), /* @__PURE__ */ React20.createElement(Text15, null, " "), /* @__PURE__ */ React20.createElement(
@@ -14199,14 +14426,14 @@ var init_ManualTestSelector = __esm({
14199
14426
  Text15,
14200
14427
  {
14201
14428
  backgroundColor: bgColor,
14202
- color: isSelected ? "white" : PRIORITY_COLORS[test.priority]
14429
+ color: isSelected ? "white" : getPriorityColor(test.priority)
14203
14430
  },
14204
14431
  " ",
14205
14432
  "[",
14206
14433
  test.priority,
14207
14434
  "]"
14208
14435
  ), test.tags.length > 0 && /* @__PURE__ */ React20.createElement(Text15, { backgroundColor: bgColor, color: isSelected ? "white" : theme.text.dim }, " ", test.tags.slice(0, 2).map((t) => `#${t}`).join(" ")));
14209
- })), /* @__PURE__ */ React20.createElement(Box17, { flexDirection: "column", marginTop: 1 }, allTests.length > VISIBLE_ITEMS && /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: "yellow" }, "Showing ", adjustedStart + 1, "\u2013", adjustedEnd, " of ", allTests.length, hasMore && !isLoading && /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, " (scroll for more)"))), /* @__PURE__ */ React20.createElement(Box17, null, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "\u2191\u2193"), " navigate \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "Space"), " toggle \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "a"), " all \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "n"), " none \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "/"), " search \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "Enter"), " automate selected \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "ESC"), " cancel")), selectedTests.size > 0 && /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: "green" }, selectedTests.size, " test", selectedTests.size !== 1 ? "s" : "", " selected")), isLoading && /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: "cyan" }, "Loading more tests..."))));
14436
+ })), /* @__PURE__ */ React20.createElement(Box17, { flexDirection: "column", marginTop: 1 }, allTests.length > VISIBLE_ITEMS && /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.warning }, "Showing ", adjustedStart + 1, "\u2013", adjustedEnd, " of ", allTests.length, hasMore && !isLoading && /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, " (scroll for more)"))), /* @__PURE__ */ React20.createElement(Box17, null, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.dim }, /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "\u2191\u2193"), " navigate \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "Space"), " toggle \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "a"), " all \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "n"), " none \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "/"), " search \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "Enter"), " automate selected \u2022", " ", /* @__PURE__ */ React20.createElement(Text15, { bold: true }, "ESC"), " cancel")), selectedTests.size > 0 && /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.success }, selectedTests.size, " test", selectedTests.size !== 1 ? "s" : "", " selected")), isLoading && /* @__PURE__ */ React20.createElement(Box17, { marginTop: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color: theme.text.accent }, "Loading more tests..."))));
14210
14437
  };
14211
14438
  }
14212
14439
  });
@@ -14387,7 +14614,7 @@ Press ESC to go back.`
14387
14614
  description: "Start without claiming \u2014 assign later via /manage"
14388
14615
  }
14389
14616
  ];
14390
- return /* @__PURE__ */ React21.createElement(Box18, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: "cyan" }, "Assign ", count, " test", count !== 1 ? "s" : "", " to yourself?")), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginBottom: 1 }, options.map((opt, index) => {
14617
+ return /* @__PURE__ */ React21.createElement(Box18, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: theme.text.accent }, "Assign ", count, " test", count !== 1 ? "s" : "", " to yourself?")), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginBottom: 1 }, options.map((opt, index) => {
14391
14618
  const isSelected = index === assignPromptIndex;
14392
14619
  return /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", key: opt.label }, /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(
14393
14620
  Text16,
@@ -14398,11 +14625,11 @@ Press ESC to go back.`
14398
14625
  },
14399
14626
  isSelected ? "\u25B6 " : " ",
14400
14627
  opt.label
14401
- )), /* @__PURE__ */ React21.createElement(Box18, { marginLeft: 4 }, /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? theme.text.primary : theme.text.dim, dimColor: !isSelected }, opt.description)));
14628
+ )), /* @__PURE__ */ React21.createElement(Box18, { marginLeft: 4 }, /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? theme.text.primary : theme.text.dim }, opt.description)));
14402
14629
  })), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "Enter"), " select \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "ESC"), " back")));
14403
14630
  }
14404
14631
  case "claiming-tests":
14405
- return /* @__PURE__ */ React21.createElement(Box18, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: "cyan" }, "Claiming Tests..."), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "Assigning ", selectedTests.length, " test", selectedTests.length !== 1 ? "s" : "", " to you...")));
14632
+ return /* @__PURE__ */ React21.createElement(Box18, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: theme.text.accent }, "Claiming Tests..."), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "Assigning ", selectedTests.length, " test", selectedTests.length !== 1 ? "s" : "", " to you...")));
14406
14633
  case "resolve-conflicts":
14407
14634
  return /* @__PURE__ */ React21.createElement(
14408
14635
  ConflictResolver,
@@ -14413,11 +14640,11 @@ Press ESC to go back.`
14413
14640
  }
14414
14641
  );
14415
14642
  case "loading-details":
14416
- return /* @__PURE__ */ React21.createElement(Box18, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: "cyan" }, "Preparing Context..."), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "Writing test specs to context file...")));
14643
+ return /* @__PURE__ */ React21.createElement(Box18, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: theme.text.accent }, "Preparing Context..."), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "Writing test specs to context file...")));
14417
14644
  case "automating":
14418
- return /* @__PURE__ */ React21.createElement(Box18, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: "cyan" }, "Automating ", selectedTests.length, " Test", selectedTests.length !== 1 ? "s" : "", "..."), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginTop: 1 }, selectedTests.slice(0, 10).map((test, i) => /* @__PURE__ */ React21.createElement(Box18, { key: test.id }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, i + 1, ". ", test.readableId, " \u2014 ", test.title, test.priority && /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, " [", test.priority, "]")))), selectedTests.length > 10 && /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "... and ", selectedTests.length - 10, " more")), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "The agent will analyze each test spec and write automated test code...")));
14645
+ return /* @__PURE__ */ React21.createElement(Box18, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: theme.text.accent }, "Automating ", selectedTests.length, " Test", selectedTests.length !== 1 ? "s" : "", "..."), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginTop: 1 }, selectedTests.slice(0, 10).map((test, i) => /* @__PURE__ */ React21.createElement(Box18, { key: test.id }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, i + 1, ". ", test.readableId, " \u2014 ", test.title, test.priority && /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, " [", test.priority, "]")))), selectedTests.length > 10 && /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "... and ", selectedTests.length - 10, " more")), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "The agent will analyze each test spec and write automated test code...")));
14419
14646
  case "error":
14420
- return /* @__PURE__ */ React21.createElement(Box18, { borderColor: "red", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: "red" }, "Error"), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, loadError)), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "ESC"), " to go back")));
14647
+ return /* @__PURE__ */ React21.createElement(Box18, { borderColor: theme.border.error, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React21.createElement(Text16, { bold: true, color: theme.text.error }, "Error"), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, loadError)), /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "ESC"), " to go back")));
14421
14648
  default:
14422
14649
  return null;
14423
14650
  }
@@ -14668,7 +14895,7 @@ function formatTestForContextFile2(ctx, index, runId, frontendUrl, assignment) {
14668
14895
  return md.build();
14669
14896
  }
14670
14897
  function buildContextFileContent(tests, run, assignments) {
14671
- const frontendUrl = getFrontendUrl();
14898
+ const frontendUrl = getFrontendUrl2();
14672
14899
  const runDetailUrl = `${frontendUrl}/runs/${run.id}`;
14673
14900
  const md = new MarkdownBuilder();
14674
14901
  md.heading(1, `Fix Context: Run ${run.readableId || run.id}`);
@@ -14890,13 +15117,13 @@ var init_RunSelector = __esm({
14890
15117
  }
14891
15118
  });
14892
15119
  if (error) {
14893
- return /* @__PURE__ */ React23.createElement(Box20, { borderColor: "red", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: "red" }, "Error Loading Runs"), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, error), /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "ESC"), " to cancel")));
15120
+ return /* @__PURE__ */ React23.createElement(Box20, { borderColor: theme.border.error, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.error }, "Error Loading Runs"), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, error), /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "ESC"), " to cancel")));
14894
15121
  }
14895
15122
  if (allRuns.length === 0 && isLoading) {
14896
- return /* @__PURE__ */ React23.createElement(Box20, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: "cyan" }, "Loading Runs..."), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Fetching test runs from the server"));
15123
+ return /* @__PURE__ */ React23.createElement(Box20, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.accent }, "Loading Runs..."), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Fetching test runs from the server"));
14897
15124
  }
14898
15125
  if (allRuns.length === 0 && !isLoading) {
14899
- return /* @__PURE__ */ React23.createElement(Box20, { borderColor: "yellow", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: "yellow" }, "No Runs Found"), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "No test runs available. Run your tests with the Supatest reporter first."), /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "ESC"), " to cancel")));
15126
+ return /* @__PURE__ */ React23.createElement(Box20, { borderColor: theme.text.warning, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.warning }, "No Runs Found"), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "No test runs available. Run your tests with the Supatest reporter first."), /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "ESC"), " to cancel")));
14900
15127
  }
14901
15128
  let startIndex;
14902
15129
  let endIndex;
@@ -14917,7 +15144,7 @@ var init_RunSelector = __esm({
14917
15144
  (run) => run.status === "errored" || (run.summary?.failed ?? 0) > 0
14918
15145
  ).length;
14919
15146
  const runningCount = allRuns.filter((run) => run.status === "running").length;
14920
- return /* @__PURE__ */ React23.createElement(Box20, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: "cyan" }, "Select a Run to Fix")), /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Loaded ", allRuns.length, totalRuns > allRuns.length ? ` of ${totalRuns}` : "", " runs \u2022", " ", failedOrErroredCount, " with failures \u2022 ", runningCount, " running")), /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("RUN", RUN_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("STATUS", STATUS_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("BRANCH", BRANCH_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("COMMIT", COMMIT_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCellRight("PASS", PASS_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCellRight("FAIL", FAIL_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCellRight("FLAKY", FLAKY_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("DURATION", DURATION_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("CREATED", CREATED_COL_WIDTH))), /* @__PURE__ */ React23.createElement(Box20, { flexDirection: "column" }, visibleRuns.map((run, index) => {
15147
+ return /* @__PURE__ */ React23.createElement(Box20, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.accent }, "Select a Run to Fix")), /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Loaded ", allRuns.length, totalRuns > allRuns.length ? ` of ${totalRuns}` : "", " runs \u2022", " ", failedOrErroredCount, " with failures \u2022 ", runningCount, " running")), /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("RUN", RUN_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("STATUS", STATUS_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("BRANCH", BRANCH_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("COMMIT", COMMIT_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCellRight("PASS", PASS_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCellRight("FAIL", FAIL_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, " "), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCellRight("FLAKY", FLAKY_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("DURATION", DURATION_COL_WIDTH)), /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.secondary }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { bold: true, color: theme.text.secondary }, formatCell("CREATED", CREATED_COL_WIDTH))), /* @__PURE__ */ React23.createElement(Box20, { flexDirection: "column" }, visibleRuns.map((run, index) => {
14921
15148
  const actualIndex = startIndex + index;
14922
15149
  const isSelected = actualIndex === selectedIndex;
14923
15150
  const branch = run.git?.branch || "-";
@@ -14992,7 +15219,7 @@ var init_RunSelector = __esm({
14992
15219
  formatDurationMs(run.durationMs, run.status),
14993
15220
  DURATION_COL_WIDTH
14994
15221
  )), /* @__PURE__ */ React23.createElement(Text18, { backgroundColor: bgColor, color: defaultColor }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { backgroundColor: bgColor, color: mutedColor }, formatCell(createdAgo, CREATED_COL_WIDTH)));
14995
- })), /* @__PURE__ */ React23.createElement(Box20, { flexDirection: "column", marginTop: 1 }, (allRuns.length > VISIBLE_ITEMS2 || totalRuns > allRuns.length) && /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: "yellow" }, "Showing ", startIndex + 1, "-", endIndex, " of ", totalRuns || allRuns.length, " runs", hasMore && !isLoading && /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, " \u2022 Scroll for more"))), /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Use ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "\u2191\u2193"), " to navigate \u2022 ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "Enter"), " to select \u2022 ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "ESC"), " to cancel")), isLoading && /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: "cyan" }, "Loading more runs..."))));
15222
+ })), /* @__PURE__ */ React23.createElement(Box20, { flexDirection: "column", marginTop: 1 }, (allRuns.length > VISIBLE_ITEMS2 || totalRuns > allRuns.length) && /* @__PURE__ */ React23.createElement(Box20, { marginBottom: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.warning }, "Showing ", startIndex + 1, "-", endIndex, " of ", totalRuns || allRuns.length, " runs", hasMore && !isLoading && /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, " \u2022 Scroll for more"))), /* @__PURE__ */ React23.createElement(Box20, null, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.dim }, "Use ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "\u2191\u2193"), " to navigate \u2022 ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "Enter"), " to select \u2022 ", /* @__PURE__ */ React23.createElement(Text18, { bold: true }, "ESC"), " to cancel")), isLoading && /* @__PURE__ */ React23.createElement(Box20, { marginTop: 1 }, /* @__PURE__ */ React23.createElement(Text18, { color: theme.text.accent }, "Loading more runs..."))));
14996
15223
  };
14997
15224
  }
14998
15225
  });
@@ -15254,13 +15481,13 @@ var init_TestSelector = __esm({
15254
15481
  }
15255
15482
  });
15256
15483
  if (error) {
15257
- return /* @__PURE__ */ React24.createElement(Box21, { borderColor: "red", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: "red" }, "Error Loading Tests"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, error), /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "ESC"), " to go back")));
15484
+ return /* @__PURE__ */ React24.createElement(Box21, { borderColor: theme.border.error, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: theme.text.error }, "Error Loading Tests"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, error), /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "ESC"), " to go back")));
15258
15485
  }
15259
15486
  if (allTests.length === 0 && isLoading) {
15260
- return /* @__PURE__ */ React24.createElement(Box21, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: "cyan" }, "Loading Failed Tests..."), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "Fetching failed tests for this run"));
15487
+ return /* @__PURE__ */ React24.createElement(Box21, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: theme.text.accent }, "Loading Failed Tests..."), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "Fetching failed tests for this run"));
15261
15488
  }
15262
15489
  if (allTests.length === 0 && !isLoading) {
15263
- return /* @__PURE__ */ React24.createElement(Box21, { borderColor: "green", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: "green" }, "No Failed Tests"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "All tests passed in this run. Nothing to fix!"), /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "ESC"), " to go back")));
15490
+ return /* @__PURE__ */ React24.createElement(Box21, { borderColor: theme.text.success, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: theme.text.success }, "No Failed Tests"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "All tests passed in this run. Nothing to fix!"), /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "ESC"), " to go back")));
15264
15491
  }
15265
15492
  const testStartIndex = Math.max(0, cursorIndex - 1);
15266
15493
  const adjustedStart = isOnFixNext10 ? 0 : Math.max(0, testStartIndex - Math.floor(VISIBLE_ITEMS3 / 2));
@@ -15270,7 +15497,7 @@ var init_TestSelector = __esm({
15270
15497
  const commit = run.git?.commit?.slice(0, 7) || "";
15271
15498
  const failedCount = run.summary?.failed ?? 0;
15272
15499
  const flakyCount = run.summary?.flaky ?? 0;
15273
- return /* @__PURE__ */ React24.createElement(Box21, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: "cyan" }, "Run: ", branch, commit && /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " @ ", commit), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: "red" }, failedCount, " failed"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: "magenta" }, flakyCount, " flaky"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: "green" }, availableCount, " avail"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: "yellow" }, assignedCount, " working"))), isSearchMode ? /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: "cyan" }, "Search: "), /* @__PURE__ */ React24.createElement(Text19, null, pendingSearch), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "\u2588 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "(Enter to confirm, ESC to clear)")) : /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "[", showAvailableOnly ? "x" : " ", "] ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "t"), " avail only", " ", "[", groupByFile ? "x" : " ", "] ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "f"), " group files", " ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "/"), " search", searchQuery ? /* @__PURE__ */ React24.createElement(Text19, { color: "yellow" }, ' "', searchQuery, '"') : null)), /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(
15500
+ return /* @__PURE__ */ React24.createElement(Box21, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { bold: true, color: theme.text.accent }, "Run: ", branch, commit && /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " @ ", commit), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.error }, failedCount, " failed"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, flakyCount, " flaky"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.success }, availableCount, " avail"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, assignedCount, " working"))), isSearchMode ? /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.accent }, "Search: "), /* @__PURE__ */ React24.createElement(Text19, null, pendingSearch), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "\u2588 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "(Enter to confirm, ESC to clear)")) : /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "[", showAvailableOnly ? "x" : " ", "] ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "t"), " avail only", " ", "[", groupByFile ? "x" : " ", "] ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "f"), " group files", " ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "/"), " search", searchQuery ? /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, ' "', searchQuery, '"') : null)), /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "column" }, /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(
15274
15501
  Text19,
15275
15502
  {
15276
15503
  backgroundColor: isOnFixNext10 ? theme.text.accentBg : void 0,
@@ -15279,7 +15506,7 @@ var init_TestSelector = __esm({
15279
15506
  },
15280
15507
  isOnFixNext10 ? EXPANSION.COLLAPSED : " ",
15281
15508
  availableCount === 0 ? /* @__PURE__ */ React24.createElement(Text19, { color: isOnFixNext10 ? "white" : theme.text.dim }, "[No Available Tests]") : `[Fix Next ${Math.min(10, availableCount)} Available Test${Math.min(10, availableCount) !== 1 ? "s" : ""}]`
15282
- )), /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), filteredTests.length === 0 && !isLoading && /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: "yellow" }, showAvailableOnly ? `All ${allTests.length} test${allTests.length !== 1 ? "s" : ""} already assigned. Press t to show all.` : "No tests match the current filters.")), groupByFile ? (
15509
+ )), /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500")), filteredTests.length === 0 && !isLoading && /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, showAvailableOnly ? `All ${allTests.length} test${allTests.length !== 1 ? "s" : ""} already assigned. Press t to show all.` : "No tests match the current filters.")), groupByFile ? (
15283
15510
  // File Grouping Mode
15284
15511
  fileGroups.map((group, index) => {
15285
15512
  const itemIndex = index + 1;
@@ -15289,7 +15516,7 @@ var init_TestSelector = __esm({
15289
15516
  const fileName = group.file.split("/").pop() || group.file;
15290
15517
  const allSelected = group.availableCount > 0 && group.tests.filter((t) => !assignedTestIds.has(t.id)).every((t) => selectedTests.has(t.id));
15291
15518
  const someSelected = group.tests.filter((t) => !assignedTestIds.has(t.id)).some((t) => selectedTests.has(t.id));
15292
- return /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "column", key: group.file, marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Box21, null, /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : theme.text.primary }, indicator), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, color: allSelected ? "green" : someSelected ? "yellow" : isSelected ? "white" : theme.text.dim }, "[", allSelected ? "\u2713" : someSelected ? "\u2297" : " ", "]"), /* @__PURE__ */ React24.createElement(Text19, null, " "), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : theme.text.primary }, fileName), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: "green" }, group.availableCount, " available"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: "yellow" }, group.assignedCount, " working"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, group.tests.length, " total")), isSelected && group.tests.length <= 5 && /* @__PURE__ */ React24.createElement(Box21, { marginLeft: 2 }, group.tests.map((test) => {
15519
+ return /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "column", key: group.file, marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Box21, null, /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : theme.text.primary }, indicator), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, color: allSelected ? "green" : someSelected ? "yellow" : isSelected ? "white" : theme.text.dim }, "[", allSelected ? "\u2713" : someSelected ? "\u2297" : " ", "]"), /* @__PURE__ */ React24.createElement(Text19, null, " "), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : theme.text.primary }, fileName), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.success }, group.availableCount, " available"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, group.assignedCount, " working"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, group.tests.length, " total")), isSelected && group.tests.length <= 5 && /* @__PURE__ */ React24.createElement(Box21, { marginLeft: 2 }, group.tests.map((test) => {
15293
15520
  const line = test.location?.line || "";
15294
15521
  const title = test.title;
15295
15522
  const isAssigned = assignedTestIds.has(test.id);
@@ -15312,9 +15539,9 @@ var init_TestSelector = __esm({
15312
15539
  const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
15313
15540
  const bgColor = isSelected ? theme.text.accentBg : void 0;
15314
15541
  const displayAssignee = assignment?.assignedToName || assignment?.assignedTo || "";
15315
- return /* @__PURE__ */ React24.createElement(Box21, { key: test.id, marginBottom: 0 }, /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : isAssigned ? theme.text.dim : theme.text.primary }, indicator), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, color: isAssigned ? theme.text.dim : isChecked ? "green" : isSelected ? "white" : theme.text.dim }, isAssigned ? "\u{1F504}" : checkbox), /* @__PURE__ */ React24.createElement(Text19, null, " "), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : isAssigned ? theme.text.dim : theme.text.primary }, file, line && /* @__PURE__ */ React24.createElement(Text19, { color: isSelected ? "white" : theme.text.dim }, ":", line), isAssigned && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: "yellow" }, displayAssignee)), /* @__PURE__ */ React24.createElement(Text19, { color: isSelected ? "white" : theme.text.dim }, " - "), title));
15542
+ return /* @__PURE__ */ React24.createElement(Box21, { key: test.id, marginBottom: 0 }, /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : isAssigned ? theme.text.dim : theme.text.primary }, indicator), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, color: isAssigned ? theme.text.dim : isChecked ? "green" : isSelected ? "white" : theme.text.dim }, isAssigned ? "\u{1F504}" : checkbox), /* @__PURE__ */ React24.createElement(Text19, null, " "), /* @__PURE__ */ React24.createElement(Text19, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : isAssigned ? theme.text.dim : theme.text.primary }, file, line && /* @__PURE__ */ React24.createElement(Text19, { color: isSelected ? "white" : theme.text.dim }, ":", line), isAssigned && /* @__PURE__ */ React24.createElement(React24.Fragment, null, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, displayAssignee)), /* @__PURE__ */ React24.createElement(Text19, { color: isSelected ? "white" : theme.text.dim }, " - "), title));
15316
15543
  })
15317
- )), /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "column", marginTop: 1 }, !groupByFile && filteredTests.length > VISIBLE_ITEMS3 && /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: "yellow" }, "Showing ", adjustedStart + 1, "-", adjustedEnd, " of ", filteredTests.length, " ", showAvailableOnly ? "available" : "", " tests", hasMore && !isLoading && /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " (scroll for more)"))), groupByFile && /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: "yellow" }, "Showing ", fileGroups.length, " file", fileGroups.length !== 1 ? "s" : "", " \u2022 ", filteredTests.length, " total test", filteredTests.length !== 1 ? "s" : "")), /* @__PURE__ */ React24.createElement(Box21, null, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "Space"), " toggle \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "n"), " none \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "s"), " next 10 \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "/"), " search \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "f"), " group files \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "t"), " filter \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "Enter"), " fix selected")), selectedTests.size > 0 && /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: "green" }, selectedTests.size, " test", selectedTests.size !== 1 ? "s" : "", " selected")), isLoading && /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: "cyan" }, "Loading more tests..."))));
15544
+ )), /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "column", marginTop: 1 }, !groupByFile && filteredTests.length > VISIBLE_ITEMS3 && /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, "Showing ", adjustedStart + 1, "-", adjustedEnd, " of ", filteredTests.length, " ", showAvailableOnly ? "available" : "", " tests", hasMore && !isLoading && /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " (scroll for more)"))), groupByFile && /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.warning }, "Showing ", fileGroups.length, " file", fileGroups.length !== 1 ? "s" : "", " \u2022 ", filteredTests.length, " total test", filteredTests.length !== 1 ? "s" : "")), /* @__PURE__ */ React24.createElement(Box21, null, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "Space"), " toggle \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "n"), " none \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "s"), " next 10 \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "/"), " search \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "f"), " group files \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "t"), " filter \u2022 ", /* @__PURE__ */ React24.createElement(Text19, { bold: true }, "Enter"), " fix selected")), selectedTests.size > 0 && /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.success }, selectedTests.size, " test", selectedTests.size !== 1 ? "s" : "", " selected")), isLoading && /* @__PURE__ */ React24.createElement(Box21, { marginTop: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.accent }, "Loading more tests..."))));
15318
15545
  };
15319
15546
  }
15320
15547
  });
@@ -15665,7 +15892,7 @@ Press ESC to go back and try again.`);
15665
15892
  case "select-tests":
15666
15893
  if (!selectedRun) return null;
15667
15894
  if (!assignmentsLoaded) {
15668
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, "Loading..."), /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Fetching assignment data for this run"));
15895
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.accent }, "Loading..."), /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Fetching assignment data for this run"));
15669
15896
  }
15670
15897
  return /* @__PURE__ */ React25.createElement(
15671
15898
  TestSelector,
@@ -15692,7 +15919,7 @@ Press ESC to go back and try again.`);
15692
15919
  description: "Agent fixes everything automatically"
15693
15920
  }
15694
15921
  ];
15695
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, branch, commit && /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, " @ ", commit), /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React25.createElement(Text20, { color: "green" }, testCount, " test", testCount !== 1 ? "s" : "", " selected"))), /* @__PURE__ */ React25.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.primary }, "Which mode would you like to proceed with?")), /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", marginBottom: 1 }, modes.map((mode, index) => {
15922
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.accent }, branch, commit && /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, " @ ", commit), /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, " \u2022 "), /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.success }, testCount, " test", testCount !== 1 ? "s" : "", " selected"))), /* @__PURE__ */ React25.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.primary }, "Which mode would you like to proceed with?")), /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", marginBottom: 1 }, modes.map((mode, index) => {
15696
15923
  const isSelected = index === modeSelectionIndex;
15697
15924
  const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
15698
15925
  return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", gap: 0, key: mode.label }, /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(
@@ -15707,8 +15934,7 @@ Press ESC to go back and try again.`);
15707
15934
  )), /* @__PURE__ */ React25.createElement(Box22, { marginLeft: 4 }, /* @__PURE__ */ React25.createElement(
15708
15935
  Text20,
15709
15936
  {
15710
- color: isSelected ? theme.text.primary : theme.text.dim,
15711
- dimColor: !isSelected
15937
+ color: isSelected ? theme.text.primary : theme.text.dim
15712
15938
  },
15713
15939
  mode.description
15714
15940
  )));
@@ -15726,7 +15952,7 @@ Press ESC to go back and try again.`);
15726
15952
  description: "Fix without claiming \u2014 you can assign later via /manage"
15727
15953
  }
15728
15954
  ];
15729
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, "Assign these tests to yourself?")), /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", marginBottom: 1 }, assignOptions.map((option, index) => {
15955
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Box22, { marginBottom: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.accent }, "Assign these tests to yourself?")), /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", marginBottom: 1 }, assignOptions.map((option, index) => {
15730
15956
  const isSelected = index === assignPromptIndex;
15731
15957
  const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
15732
15958
  return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", gap: 0, key: option.label }, /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(
@@ -15741,15 +15967,14 @@ Press ESC to go back and try again.`);
15741
15967
  )), /* @__PURE__ */ React25.createElement(Box22, { marginLeft: 4 }, /* @__PURE__ */ React25.createElement(
15742
15968
  Text20,
15743
15969
  {
15744
- color: isSelected ? theme.text.primary : theme.text.dim,
15745
- dimColor: !isSelected
15970
+ color: isSelected ? theme.text.primary : theme.text.dim
15746
15971
  },
15747
15972
  option.description
15748
15973
  )));
15749
15974
  })), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, /* @__PURE__ */ React25.createElement(Text20, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React25.createElement(Text20, { bold: true }, "Enter"), " select \u2022 ", /* @__PURE__ */ React25.createElement(Text20, { bold: true }, "ESC"), " back")));
15750
15975
  }
15751
15976
  case "claiming-tests":
15752
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, "Claiming Tests..."), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Assigning ", selectedTests.length, " test", selectedTests.length !== 1 ? "s" : "", " to you...")));
15977
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.accent }, "Claiming Tests..."), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Assigning ", selectedTests.length, " test", selectedTests.length !== 1 ? "s" : "", " to you...")));
15753
15978
  case "resolve-conflicts":
15754
15979
  return /* @__PURE__ */ React25.createElement(
15755
15980
  ConflictResolver,
@@ -15761,17 +15986,17 @@ Press ESC to go back and try again.`);
15761
15986
  );
15762
15987
  case "loading-details":
15763
15988
  if (loadError) {
15764
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "red", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "red" }, "Error Loading Test Details"), /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, loadError), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React25.createElement(Text20, { bold: true }, "ESC"), " to go back")));
15989
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.error, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.error }, "Error Loading Test Details"), /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, loadError), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React25.createElement(Text20, { bold: true }, "ESC"), " to go back")));
15765
15990
  }
15766
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, "Loading Test Details..."), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Fetching error messages, stack traces, and execution steps...")), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: "yellow" }, loadingProgress.current, " / ", loadingProgress.total, " tests loaded")));
15991
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.accent }, "Loading Test Details..."), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Fetching error messages, stack traces, and execution steps...")), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.warning }, loadingProgress.current, " / ", loadingProgress.total, " tests loaded")));
15767
15992
  case "error":
15768
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "red", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "red" }, "Error"), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, loadError)), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React25.createElement(Text20, { bold: true }, "ESC"), " to go back")));
15993
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.error, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.error }, "Error"), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, loadError)), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React25.createElement(Text20, { bold: true }, "ESC"), " to go back")));
15769
15994
  case "fixing": {
15770
15995
  const modeLabel = workflowMode === "fix" ? "Analyzing & Fixing" : "Fixing";
15771
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "cyan" }, modeLabel, " ", selectedTests.length, " Test", selectedTests.length !== 1 ? "s" : "", "..."), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, selectedTests.slice(0, 10).map((test, index) => /* @__PURE__ */ React25.createElement(Box22, { key: test.id }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, index + 1, ". ", test.file.split("/").pop(), ":", test.location?.line || "", " - ", test.title))), selectedTests.length > 10 && /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "... and ", selectedTests.length - 10, " more"))), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, workflowMode === "fix" ? "The agent will analyze all failures, present findings, and guide you through fixing..." : "The agent will now analyze and fix each test...")));
15996
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.accent }, modeLabel, " ", selectedTests.length, " Test", selectedTests.length !== 1 ? "s" : "", "..."), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, selectedTests.slice(0, 10).map((test, index) => /* @__PURE__ */ React25.createElement(Box22, { key: test.id }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, index + 1, ". ", test.file.split("/").pop(), ":", test.location?.line || "", " - ", test.title))), selectedTests.length > 10 && /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "... and ", selectedTests.length - 10, " more"))), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, workflowMode === "fix" ? "The agent will analyze all failures, present findings, and guide you through fixing..." : "The agent will now analyze and fix each test...")));
15772
15997
  }
15773
15998
  case "complete":
15774
- return /* @__PURE__ */ React25.createElement(Box22, { borderColor: "green", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: "green" }, "Tests Marked as Complete"), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "\u2713 ", selectedTests.length, " test", selectedTests.length !== 1 ? "s have" : " has", " been marked as fixed")), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Press any key to continue...")));
15999
+ return /* @__PURE__ */ React25.createElement(Box22, { borderColor: theme.text.success, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React25.createElement(Text20, { bold: true, color: theme.text.success }, "Tests Marked as Complete"), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "\u2713 ", selectedTests.length, " test", selectedTests.length !== 1 ? "s have" : " has", " been marked as fixed")), /* @__PURE__ */ React25.createElement(Box22, { marginTop: 1 }, /* @__PURE__ */ React25.createElement(Text20, { color: theme.text.dim }, "Press any key to continue...")));
15775
16000
  default:
15776
16001
  return null;
15777
16002
  }
@@ -16025,26 +16250,26 @@ var init_ModelSelector = __esm({
16025
16250
  });
16026
16251
 
16027
16252
  // src/ui/components/InputPrompt.tsx
16253
+ import { execSync as execSync6 } from "child_process";
16028
16254
  import path4 from "path";
16029
- import { execSync as execSync5 } from "child_process";
16030
16255
  import chalk5 from "chalk";
16031
16256
  import { Box as Box24, Text as Text23 } from "ink";
16032
16257
  import React28, { forwardRef, memo as memo3, useEffect as useEffect11, useImperativeHandle, useRef as useRef9, useState as useState14 } from "react";
16033
16258
  function readClipboard() {
16034
16259
  try {
16035
16260
  if (process.platform === "win32") {
16036
- return execSync5('powershell.exe -NoProfile -Command "Get-Clipboard"', {
16261
+ return execSync6('powershell.exe -NoProfile -Command "Get-Clipboard"', {
16037
16262
  encoding: "utf8",
16038
16263
  timeout: 2e3
16039
16264
  }).replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\n$/, "");
16040
16265
  }
16041
16266
  if (process.platform === "darwin") {
16042
- return execSync5("pbpaste", { encoding: "utf8", timeout: 2e3 });
16267
+ return execSync6("pbpaste", { encoding: "utf8", timeout: 2e3 });
16043
16268
  }
16044
16269
  try {
16045
- return execSync5("xclip -selection clipboard -o", { encoding: "utf8", timeout: 2e3 });
16270
+ return execSync6("xclip -selection clipboard -o", { encoding: "utf8", timeout: 2e3 });
16046
16271
  } catch {
16047
- return execSync5("xsel --clipboard --output", { encoding: "utf8", timeout: 2e3 });
16272
+ return execSync6("xsel --clipboard --output", { encoding: "utf8", timeout: 2e3 });
16048
16273
  }
16049
16274
  } catch {
16050
16275
  return null;
@@ -16909,7 +17134,7 @@ var init_ManageFlow = __esm({
16909
17134
  };
16910
17135
  switch (step) {
16911
17136
  case "menu":
16912
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "Work Management"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginBottom: 1, marginTop: 1 }, MANAGE_MENU_OPTIONS.map((option, index) => {
17137
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "Work Management"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginBottom: 1, marginTop: 1 }, MANAGE_MENU_OPTIONS.map((option, index) => {
16913
17138
  const isSelected = index === menuIndex;
16914
17139
  const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
16915
17140
  return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", key: option.label }, /* @__PURE__ */ React29.createElement(
@@ -16925,12 +17150,12 @@ var init_ManageFlow = __esm({
16925
17150
  })), /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "Enter"), " select \u2022 ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " close"));
16926
17151
  case "my-work":
16927
17152
  if (myWorkLoading) {
16928
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "Loading..."));
17153
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "Loading..."));
16929
17154
  }
16930
17155
  if (!myWorkData || myWorkData.assignments.length === 0) {
16931
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "My Work"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "No active assignments")), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to go back")));
17156
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "My Work"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "No active assignments")), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to go back")));
16932
17157
  }
16933
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "My Work"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, myWorkData.stats.assigned, " assigned | ", myWorkData.stats.completed, " completed | ", myWorkData.stats.failed, " failed")), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginTop: 1 }, myWorkData.assignments.map((a) => /* @__PURE__ */ React29.createElement(Box25, { key: a.id }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.primary }, a.test.file, " - ", a.test.title, " ", /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, formatTimeAgo(a.assignedAt)))))), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to go back")));
17158
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "My Work"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, myWorkData.stats.assigned, " assigned | ", myWorkData.stats.completed, " completed | ", myWorkData.stats.failed, " failed")), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginTop: 1 }, myWorkData.assignments.map((a) => /* @__PURE__ */ React29.createElement(Box25, { key: a.id }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.primary }, a.test.file, " - ", a.test.title, " ", /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, formatTimeAgo(a.assignedAt)))))), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to go back")));
16934
17159
  case "assign-run":
16935
17160
  return /* @__PURE__ */ React29.createElement(
16936
17161
  RunSelector,
@@ -16956,13 +17181,13 @@ var init_ManageFlow = __esm({
16956
17181
  );
16957
17182
  case "assign-to": {
16958
17183
  if (assigneesLoading) {
16959
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "Loading team members..."));
17184
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "Loading team members..."));
16960
17185
  }
16961
17186
  const options = assignees.map((a) => ({
16962
17187
  label: a.name || a.email,
16963
17188
  description: `${a.email} (${a.activeTests} active)`
16964
17189
  }));
16965
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "Assign to whom?"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginBottom: 1, marginTop: 1 }, options.map((opt, index) => {
17190
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "Assign to whom?"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginBottom: 1, marginTop: 1 }, options.map((opt, index) => {
16966
17191
  const isSelected = index === assigneeIndex;
16967
17192
  const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
16968
17193
  return /* @__PURE__ */ React29.createElement(Box25, { key: opt.label }, /* @__PURE__ */ React29.createElement(
@@ -16987,15 +17212,15 @@ var init_ManageFlow = __esm({
16987
17212
  }
16988
17213
  );
16989
17214
  case "assign-done":
16990
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "green", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "green" }, "Done"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.primary }, assignMessage)), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "Enter"), " or ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to return to menu")));
17215
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.text.success, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.success }, "Done"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.primary }, assignMessage)), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "Enter"), " or ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to return to menu")));
16991
17216
  case "unassign-list": {
16992
17217
  if (unassignLoading) {
16993
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "Loading assignments..."));
17218
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "Loading assignments..."));
16994
17219
  }
16995
17220
  if (allAssignments.length === 0) {
16996
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "Unassign"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "No active assignments")), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to go back")));
17221
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "Unassign"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "No active assignments")), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to go back")));
16997
17222
  }
16998
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "cyan" }, "Active Assignments (", allAssignments.length, ")"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginTop: 1 }, allAssignments.map((a, index) => {
17223
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.accent }, "Active Assignments (", allAssignments.length, ")"), /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", marginTop: 1 }, allAssignments.map((a, index) => {
16999
17224
  const isFocused = index === unassignIndex;
17000
17225
  const isSelected = unassignSelections.has(index);
17001
17226
  const indicator = isFocused ? EXPANSION.COLLAPSED : " ";
@@ -17018,7 +17243,7 @@ var init_ManageFlow = __esm({
17018
17243
  })), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "Space"), " toggle \u2022 ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "Enter"), " release selected \u2022 ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " back")));
17019
17244
  }
17020
17245
  case "unassign-done":
17021
- return /* @__PURE__ */ React29.createElement(Box25, { borderColor: "green", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: "green" }, "Done"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.primary }, unassignMessage)), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "Enter"), " or ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to return to menu")));
17246
+ return /* @__PURE__ */ React29.createElement(Box25, { borderColor: theme.text.success, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React29.createElement(Text24, { bold: true, color: theme.text.success }, "Done"), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.primary }, unassignMessage)), /* @__PURE__ */ React29.createElement(Box25, { marginTop: 1 }, /* @__PURE__ */ React29.createElement(Text24, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "Enter"), " or ", /* @__PURE__ */ React29.createElement(Text24, { bold: true }, "ESC"), " to return to menu")));
17022
17247
  default:
17023
17248
  return null;
17024
17249
  }
@@ -17360,8 +17585,7 @@ var init_PlanApprovalSelector = __esm({
17360
17585
  )), /* @__PURE__ */ React33.createElement(Box29, { marginLeft: 4 }, /* @__PURE__ */ React33.createElement(
17361
17586
  Text28,
17362
17587
  {
17363
- color: isSelected ? theme.text.primary : theme.text.dim,
17364
- dimColor: !isSelected
17588
+ color: isSelected ? theme.text.primary : theme.text.dim
17365
17589
  },
17366
17590
  option.description
17367
17591
  )));
@@ -17430,15 +17654,15 @@ var init_ProjectSelector = __esm({
17430
17654
  return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.accent }, "Loading projects..."));
17431
17655
  }
17432
17656
  if (error) {
17433
- return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color: "red" }, "Failed to load projects: ", error), /* @__PURE__ */ React34.createElement(Text29, { dimColor: true }, "Press Esc to cancel"));
17657
+ return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.error }, "Failed to load projects: ", error), /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.dim }, "Press Esc to cancel"));
17434
17658
  }
17435
17659
  if (projects.length === 0) {
17436
- return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color: "yellow" }, "No projects found. Create one at your dashboard first."), /* @__PURE__ */ React34.createElement(Text29, { dimColor: true }, "Press Esc to cancel"));
17660
+ return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.warning }, "No projects found. Create one at your dashboard first."), /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.dim }, "Press Esc to cancel"));
17437
17661
  }
17438
- return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Box30, { marginBottom: 1 }, /* @__PURE__ */ React34.createElement(Text29, { bold: true, color: theme.text.accent }, "Select a project"), /* @__PURE__ */ React34.createElement(Text29, { dimColor: true }, " (\u2191\u2193 navigate, Enter select, Esc cancel)")), projects.map((project, index) => {
17662
+ return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Box30, { marginBottom: 1 }, /* @__PURE__ */ React34.createElement(Text29, { bold: true, color: theme.text.accent }, "Select a project"), /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.dim }, " (\u2191\u2193 navigate, Enter select, Esc cancel)")), projects.map((project, index) => {
17439
17663
  const isSelected = index === selectedIndex;
17440
17664
  const isCurrent = project.id === currentProjectId;
17441
- return /* @__PURE__ */ React34.createElement(Box30, { key: project.id }, /* @__PURE__ */ React34.createElement(Text29, { color: isSelected ? theme.text.accent : void 0 }, isSelected ? "\u276F " : " "), /* @__PURE__ */ React34.createElement(Text29, { bold: isSelected, color: isSelected ? theme.text.accent : void 0 }, project.name), /* @__PURE__ */ React34.createElement(Text29, { dimColor: true }, " (", project.slug, ")"), isCurrent && /* @__PURE__ */ React34.createElement(Text29, { color: "green" }, " \u2713"));
17665
+ return /* @__PURE__ */ React34.createElement(Box30, { key: project.id }, /* @__PURE__ */ React34.createElement(Text29, { color: isSelected ? theme.text.accent : void 0 }, isSelected ? "\u276F " : " "), /* @__PURE__ */ React34.createElement(Text29, { bold: isSelected, color: isSelected ? theme.text.accent : void 0 }, project.name), /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.dim }, " (", project.slug, ")"), isCurrent && /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.success }, " \u2713"));
17442
17666
  }));
17443
17667
  };
17444
17668
  }
@@ -17628,8 +17852,7 @@ var init_QuestionSelector = __esm({
17628
17852
  )), /* @__PURE__ */ React36.createElement(Box31, { marginLeft: multiSelect ? 6 : 4 }, /* @__PURE__ */ React36.createElement(
17629
17853
  Text31,
17630
17854
  {
17631
- color: isSelected ? theme.text.primary : theme.text.dim,
17632
- dimColor: !isSelected
17855
+ color: isSelected ? theme.text.primary : theme.text.dim
17633
17856
  },
17634
17857
  option.description
17635
17858
  )));
@@ -17712,13 +17935,13 @@ var init_SessionSelector = __esm({
17712
17935
  }
17713
17936
  });
17714
17937
  if (error) {
17715
- return /* @__PURE__ */ React37.createElement(Box32, { borderColor: "red", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: "red" }, "Error Loading Sessions"), /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, error), /* @__PURE__ */ React37.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "ESC"), " to cancel")));
17938
+ return /* @__PURE__ */ React37.createElement(Box32, { borderColor: theme.border.error, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: theme.text.error }, "Error Loading Sessions"), /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, error), /* @__PURE__ */ React37.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "ESC"), " to cancel")));
17716
17939
  }
17717
17940
  if (allSessions.length === 0 && isLoading) {
17718
- return /* @__PURE__ */ React37.createElement(Box32, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: "cyan" }, "Loading Sessions..."), /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Fetching your sessions from the server"));
17941
+ return /* @__PURE__ */ React37.createElement(Box32, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: theme.text.accent }, "Loading Sessions..."), /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Fetching your sessions from the server"));
17719
17942
  }
17720
17943
  if (allSessions.length === 0 && !isLoading) {
17721
- return /* @__PURE__ */ React37.createElement(Box32, { borderColor: "yellow", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: "yellow" }, "No Sessions Found"), /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "No previous sessions available. Start a new session!"), /* @__PURE__ */ React37.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "ESC"), " to cancel")));
17944
+ return /* @__PURE__ */ React37.createElement(Box32, { borderColor: theme.text.warning, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: theme.text.warning }, "No Sessions Found"), /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "No previous sessions available. Start a new session!"), /* @__PURE__ */ React37.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Press ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "ESC"), " to cancel")));
17722
17945
  }
17723
17946
  const VISIBLE_ITEMS4 = 10;
17724
17947
  let startIndex;
@@ -17738,7 +17961,7 @@ var init_SessionSelector = __esm({
17738
17961
  const visibleSessions = allSessions.slice(startIndex, endIndex);
17739
17962
  const MAX_TITLE_WIDTH = 50;
17740
17963
  const PREFIX_WIDTH = 6;
17741
- return /* @__PURE__ */ React37.createElement(Box32, { borderColor: "cyan", borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Box32, { marginBottom: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: "cyan" }, "Select a Session to Resume")), /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, visibleSessions.map((item, index) => {
17964
+ return /* @__PURE__ */ React37.createElement(Box32, { borderColor: theme.border.accent, borderStyle: "round", flexDirection: "column", padding: 1 }, /* @__PURE__ */ React37.createElement(Box32, { marginBottom: 1 }, /* @__PURE__ */ React37.createElement(Text32, { bold: true, color: theme.text.accent }, "Select a Session to Resume")), /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column" }, visibleSessions.map((item, index) => {
17742
17965
  const actualIndex = startIndex + index;
17743
17966
  const isSelected = actualIndex === selectedIndex;
17744
17967
  const title = item.session.title || "Untitled session";
@@ -17759,11 +17982,11 @@ var init_SessionSelector = __esm({
17759
17982
  dateStr = `${sessionDate.toLocaleDateString([], { month: "numeric", day: "numeric" })} ${sessionDate.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" })}`;
17760
17983
  }
17761
17984
  const prefix = item.prefix.padEnd(PREFIX_WIDTH, " ");
17762
- const prefixColor = item.prefix === "[Me]" ? "cyan" : "yellow";
17985
+ const prefixColor = item.prefix === "[Me]" ? theme.text.accent : theme.text.warning;
17763
17986
  const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
17764
17987
  const bgColor = isSelected ? theme.text.accentBg : void 0;
17765
17988
  return /* @__PURE__ */ React37.createElement(Box32, { key: item.session.id, width: "100%" }, /* @__PURE__ */ React37.createElement(Text32, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : theme.text.primary }, indicator), /* @__PURE__ */ React37.createElement(Text32, { backgroundColor: bgColor, bold: isSelected, color: prefixColor }, prefix), /* @__PURE__ */ React37.createElement(Text32, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "white" : theme.text.primary }, displayTitle), /* @__PURE__ */ React37.createElement(Text32, { backgroundColor: bgColor, color: theme.text.dim }, "(", dateStr, ")"));
17766
- })), /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column", marginTop: 1 }, (allSessions.length > VISIBLE_ITEMS4 || totalSessions > allSessions.length) && /* @__PURE__ */ React37.createElement(Box32, { marginBottom: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: "yellow" }, "Showing ", startIndex + 1, "-", endIndex, " of ", totalSessions || allSessions.length, " sessions", hasMore && !isLoading && /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, " \u2022 Scroll for more"))), /* @__PURE__ */ React37.createElement(Box32, null, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Use ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "\u2191\u2193"), " to navigate \u2022 ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "Enter"), " to select \u2022 ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "ESC"), " to cancel")), isLoading && /* @__PURE__ */ React37.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: "cyan" }, "Loading more sessions..."))));
17989
+ })), /* @__PURE__ */ React37.createElement(Box32, { flexDirection: "column", marginTop: 1 }, (allSessions.length > VISIBLE_ITEMS4 || totalSessions > allSessions.length) && /* @__PURE__ */ React37.createElement(Box32, { marginBottom: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.warning }, "Showing ", startIndex + 1, "-", endIndex, " of ", totalSessions || allSessions.length, " sessions", hasMore && !isLoading && /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, " \u2022 Scroll for more"))), /* @__PURE__ */ React37.createElement(Box32, null, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.dim }, "Use ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "\u2191\u2193"), " to navigate \u2022 ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "Enter"), " to select \u2022 ", /* @__PURE__ */ React37.createElement(Text32, { bold: true }, "ESC"), " to cancel")), isLoading && /* @__PURE__ */ React37.createElement(Box32, { marginTop: 1 }, /* @__PURE__ */ React37.createElement(Text32, { color: theme.text.accent }, "Loading more sessions..."))));
17767
17990
  };
17768
17991
  }
17769
17992
  });
@@ -17812,7 +18035,7 @@ var init_useOverlayEscapeGuard = __esm({
17812
18035
  });
17813
18036
 
17814
18037
  // src/ui/App.tsx
17815
- import { execSync as execSync6 } from "child_process";
18038
+ import { execSync as execSync7 } from "child_process";
17816
18039
  import { homedir as homedir9 } from "os";
17817
18040
  import { Box as Box33, Text as Text33, useApp as useApp2, useStdout as useStdout2 } from "ink";
17818
18041
  import Spinner4 from "ink-spinner";
@@ -17858,7 +18081,7 @@ var init_App = __esm({
17858
18081
  init_theme();
17859
18082
  getGitBranch2 = () => {
17860
18083
  try {
17861
- return execSync6("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
18084
+ return execSync7("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
17862
18085
  } catch {
17863
18086
  return "";
17864
18087
  }
@@ -17953,8 +18176,7 @@ var init_App = __esm({
17953
18176
  config2.projectId = project.id;
17954
18177
  apiClient.setProjectId(project.id);
17955
18178
  saveSupatestSettings(config2.cwd || process.cwd(), {
17956
- projectId: project.slug,
17957
- projectName: project.name
18179
+ projectId: project.slug
17958
18180
  });
17959
18181
  } else if (result.projects.length > 1) {
17960
18182
  addMessage({
@@ -18051,8 +18273,7 @@ var init_App = __esm({
18051
18273
  setSavedProjectSlug(void 0);
18052
18274
  config2.projectId = void 0;
18053
18275
  saveSupatestSettings(config2.cwd || process.cwd(), {
18054
- projectId: void 0,
18055
- projectName: void 0
18276
+ projectId: void 0
18056
18277
  });
18057
18278
  setAuthState("unauthenticated" /* Unauthenticated */);
18058
18279
  addMessage({
@@ -18486,8 +18707,7 @@ Make sure the file exists and is a valid image (png, jpg, gif, webp, bmp, svg).`
18486
18707
  apiClient.setProjectId(project.id);
18487
18708
  }
18488
18709
  saveSupatestSettings(config2.cwd || process.cwd(), {
18489
- projectId: project.slug,
18490
- projectName: project.name
18710
+ projectId: project.slug
18491
18711
  });
18492
18712
  addMessage({
18493
18713
  type: "assistant",
@@ -19036,7 +19256,7 @@ Make sure the file exists and is a valid image (png, jpg, gif, webp, bmp, svg).`
19036
19256
  onInputChange: handleInputChange,
19037
19257
  onSubmit: stableHandleSubmitTask,
19038
19258
  placeholder: "Enter your task...",
19039
- projectName: currentProject?.name,
19259
+ projectName: currentProject?.slug,
19040
19260
  ref: inputPromptRef,
19041
19261
  selectedModel,
19042
19262
  setSelectedModel
@@ -19679,13 +19899,13 @@ await init_agent();
19679
19899
  init_react();
19680
19900
  init_MessageList();
19681
19901
  init_SessionContext();
19682
- import { execSync as execSync2 } from "child_process";
19902
+ import { execSync as execSync3 } from "child_process";
19683
19903
  import { homedir as homedir5 } from "os";
19684
19904
  import { Box as Box13, useApp } from "ink";
19685
19905
  import React14, { useEffect as useEffect2, useRef as useRef4, useState as useState3 } from "react";
19686
19906
  var getGitBranch = () => {
19687
19907
  try {
19688
- return execSync2("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
19908
+ return execSync3("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
19689
19909
  } catch {
19690
19910
  return "";
19691
19911
  }
@@ -19943,10 +20163,13 @@ async function runAgent(config2) {
19943
20163
  });
19944
20164
  }
19945
20165
 
20166
+ // src/index.ts
20167
+ init_theme();
20168
+
19946
20169
  // src/utils/auto-update.ts
19947
20170
  init_version();
19948
20171
  init_error_logger();
19949
- import { execSync as execSync3, spawn as spawn2 } from "child_process";
20172
+ import { execSync as execSync4, spawn as spawn2 } from "child_process";
19950
20173
  import latestVersion from "latest-version";
19951
20174
  import { gt } from "semver";
19952
20175
  var UPDATE_CHECK_TIMEOUT = 3e3;
@@ -19972,7 +20195,7 @@ async function checkAndAutoUpdate() {
19972
20195
  Updating Supatest CLI ${CLI_VERSION} \u2192 ${latest}...`);
19973
20196
  try {
19974
20197
  try {
19975
- const npmPrefix = execSync3("npm config get prefix", { encoding: "utf-8" }).trim();
20198
+ const npmPrefix = execSync4("npm config get prefix", { encoding: "utf-8" }).trim();
19976
20199
  if (process.platform === "win32") {
19977
20200
  const { rmSync, readdirSync: readdirSync2 } = await import("fs");
19978
20201
  const modulesDir = `${npmPrefix}\\node_modules\\@supatest`;
@@ -19981,24 +20204,24 @@ Updating Supatest CLI ${CLI_VERSION} \u2192 ${latest}...`);
19981
20204
  rmSync(`${modulesDir}\\${entry}`, { recursive: true, force: true });
19982
20205
  }
19983
20206
  } else {
19984
- execSync3(`rm -rf ${npmPrefix}/lib/node_modules/@supatest/.cli-* 2>/dev/null || true`);
20207
+ execSync4(`rm -rf ${npmPrefix}/lib/node_modules/@supatest/.cli-* 2>/dev/null || true`);
19985
20208
  }
19986
20209
  } catch {
19987
20210
  }
19988
20211
  try {
19989
- execSync3("npm update -g @supatest/cli", {
20212
+ execSync4("npm update -g @supatest/cli", {
19990
20213
  stdio: "inherit",
19991
20214
  timeout: INSTALL_TIMEOUT
19992
20215
  });
19993
20216
  } catch {
19994
- execSync3("npm install -g @supatest/cli@latest --force", {
20217
+ execSync4("npm install -g @supatest/cli@latest --force", {
19995
20218
  stdio: "inherit",
19996
20219
  timeout: INSTALL_TIMEOUT
19997
20220
  });
19998
20221
  }
19999
20222
  let updateVerified = false;
20000
20223
  try {
20001
- const installedVersion = execSync3("npm ls -g @supatest/cli --json 2>/dev/null", {
20224
+ const installedVersion = execSync4("npm ls -g @supatest/cli --json 2>/dev/null", {
20002
20225
  encoding: "utf-8"
20003
20226
  });
20004
20227
  const parsed = JSON.parse(installedVersion);
@@ -20044,7 +20267,7 @@ init_logger();
20044
20267
 
20045
20268
  // src/utils/node-version.ts
20046
20269
  init_logger();
20047
- import { execSync as execSync4 } from "child_process";
20270
+ import { execSync as execSync5 } from "child_process";
20048
20271
  var MINIMUM_NODE_VERSION2 = 18;
20049
20272
  function parseVersion2(versionString) {
20050
20273
  const cleaned = versionString.trim().replace(/^v/, "");
@@ -20061,7 +20284,7 @@ function parseVersion2(versionString) {
20061
20284
  }
20062
20285
  function getNodeVersion2() {
20063
20286
  try {
20064
- const versionOutput = execSync4("node --version", {
20287
+ const versionOutput = execSync5("node --version", {
20065
20288
  encoding: "utf-8",
20066
20289
  stdio: ["ignore", "pipe", "ignore"]
20067
20290
  });
@@ -20184,9 +20407,18 @@ program.name("supatest").description(
20184
20407
  ).option(
20185
20408
  "--claude-max-iterations <number>",
20186
20409
  "[Deprecated] Alias for --max-iterations"
20187
- ).option("--supatest-api-key <key>", "Supatest API key (or use SUPATEST_API_KEY env)").option("--supatest-api-url <url>", "Supatest API URL (or use SUPATEST_API_URL env, defaults to https://code-api.supatest.ai)").option("--headless", "Run in headless mode (for CI/CD, minimal output)").option("--mode <mode>", "Agent mode for headless: fix (default), build, plan, test-feature, or report").option("--verbose", "Enable verbose logging").option("--model <model>", "Model to use (or use ANTHROPIC_MODEL_NAME env). Use 'small', 'medium', or 'premium' for tier-based selection").action(async (task, options) => {
20410
+ ).option("--supatest-api-key <key>", "Supatest API key (or use SUPATEST_API_KEY env)").option("--supatest-api-url <url>", "Supatest API URL (or use SUPATEST_API_URL env, defaults to https://code-api.supatest.ai)").option("--theme <mode>", "Color theme: auto (default), dark, or light", "auto").option("--headless", "Run in headless mode (for CI/CD, minimal output)").option("--mode <mode>", "Agent mode for headless: fix (default), build, plan, test-feature, or report").option("--verbose", "Enable verbose logging").option("--model <model>", "Model to use (or use ANTHROPIC_MODEL_NAME env). Use 'small', 'medium', or 'premium' for tier-based selection").action(async (task, options) => {
20188
20411
  try {
20189
20412
  checkNodeVersion2();
20413
+ if (options.theme && options.theme !== "auto") {
20414
+ const mode = options.theme;
20415
+ const { setThemeMode: setThemeMode2 } = await Promise.resolve().then(() => (init_theme(), theme_exports));
20416
+ setThemeMode2(mode);
20417
+ logger.debug(`Terminal theme set via --theme flag: ${mode}`);
20418
+ } else {
20419
+ const detectedTheme = initTheme();
20420
+ logger.debug(`Terminal theme detected: ${detectedTheme}`);
20421
+ }
20190
20422
  await checkAndAutoUpdate();
20191
20423
  const isHeadlessMode = options.headless || process.stdin.isTTY === false;
20192
20424
  if (options.verbose) {
@@ -20205,9 +20437,9 @@ program.name("supatest").description(
20205
20437
  logs = stdinContent;
20206
20438
  }
20207
20439
  if (options.logs) {
20208
- const fs4 = await import("fs/promises");
20440
+ const fs5 = await import("fs/promises");
20209
20441
  try {
20210
- logs = await fs4.readFile(options.logs, "utf-8");
20442
+ logs = await fs5.readFile(options.logs, "utf-8");
20211
20443
  } catch (error) {
20212
20444
  logger.error(`Failed to read log file: ${options.logs}`);
20213
20445
  process.exit(1);