@supatest/cli 0.0.61 → 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.
- package/dist/index.js +365 -138
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5888,7 +5888,7 @@ var CLI_VERSION;
|
|
|
5888
5888
|
var init_version = __esm({
|
|
5889
5889
|
"src/version.ts"() {
|
|
5890
5890
|
"use strict";
|
|
5891
|
-
CLI_VERSION = "0.0.
|
|
5891
|
+
CLI_VERSION = "0.0.62";
|
|
5892
5892
|
}
|
|
5893
5893
|
});
|
|
5894
5894
|
|
|
@@ -7736,7 +7736,7 @@ ${projectInstructions}`,
|
|
|
7736
7736
|
return result;
|
|
7737
7737
|
}
|
|
7738
7738
|
async resolveClaudeCodePath() {
|
|
7739
|
-
const
|
|
7739
|
+
const fs5 = await import("fs/promises");
|
|
7740
7740
|
let claudeCodePath;
|
|
7741
7741
|
const require2 = createRequire(import.meta.url);
|
|
7742
7742
|
const sdkPath = require2.resolve("@anthropic-ai/claude-agent-sdk");
|
|
@@ -7747,7 +7747,7 @@ ${projectInstructions}`,
|
|
|
7747
7747
|
logger.debug(`[agent] Using SUPATEST_CLAUDE_CODE_PATH override: ${claudeCodePath}`);
|
|
7748
7748
|
}
|
|
7749
7749
|
try {
|
|
7750
|
-
await
|
|
7750
|
+
await fs5.access(claudeCodePath);
|
|
7751
7751
|
logger.debug(`[agent] Claude Code CLI found: ${claudeCodePath}`);
|
|
7752
7752
|
} catch {
|
|
7753
7753
|
const error = `Claude Code executable not found at: ${claudeCodePath}
|
|
@@ -8383,61 +8383,275 @@ var init_banner = __esm({
|
|
|
8383
8383
|
}
|
|
8384
8384
|
});
|
|
8385
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
|
+
|
|
8386
8501
|
// src/ui/utils/theme.ts
|
|
8387
|
-
var
|
|
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;
|
|
8388
8543
|
var init_theme = __esm({
|
|
8389
8544
|
"src/ui/utils/theme.ts"() {
|
|
8390
8545
|
"use strict";
|
|
8391
|
-
|
|
8392
|
-
|
|
8546
|
+
init_detect_terminal_theme();
|
|
8547
|
+
darkTheme = {
|
|
8393
8548
|
text: {
|
|
8394
8549
|
primary: "#FFFFFF",
|
|
8395
8550
|
secondary: "#A0AEC0",
|
|
8396
|
-
|
|
8397
|
-
|
|
8398
|
-
//
|
|
8399
|
-
|
|
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
|
|
8400
8556
|
accentBg: "#1A6B67",
|
|
8557
|
+
// dark teal bg — white text readable on this
|
|
8401
8558
|
success: "#48BB78",
|
|
8402
|
-
error: "#
|
|
8403
|
-
|
|
8404
|
-
|
|
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
|
|
8405
8565
|
},
|
|
8406
|
-
// Background colors (for boxed content)
|
|
8407
8566
|
bg: {
|
|
8408
8567
|
primary: "#1A202C",
|
|
8409
8568
|
secondary: "#2D3748",
|
|
8410
8569
|
accent: "#234E52"
|
|
8411
8570
|
},
|
|
8412
|
-
// Borders
|
|
8413
8571
|
border: {
|
|
8414
|
-
default: "#
|
|
8415
|
-
|
|
8416
|
-
|
|
8572
|
+
default: "#4A5568",
|
|
8573
|
+
// darker gray — distinct from text.dim and text.secondary
|
|
8574
|
+
accent: "#2DD4BF",
|
|
8575
|
+
// match text accent
|
|
8576
|
+
error: "#FC8181"
|
|
8417
8577
|
},
|
|
8418
|
-
// Tool/action colors
|
|
8419
8578
|
tool: {
|
|
8420
|
-
read: "#
|
|
8421
|
-
//
|
|
8579
|
+
read: "#63B3ED",
|
|
8580
|
+
// brighter blue
|
|
8422
8581
|
write: "#48BB78",
|
|
8423
|
-
|
|
8424
|
-
|
|
8425
|
-
|
|
8426
|
-
|
|
8427
|
-
|
|
8428
|
-
|
|
8429
|
-
|
|
8430
|
-
|
|
8431
|
-
// 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
|
|
8432
8590
|
},
|
|
8433
|
-
// Status colors
|
|
8434
8591
|
status: {
|
|
8435
8592
|
pending: "#A0AEC0",
|
|
8436
|
-
inProgress: "#
|
|
8593
|
+
inProgress: "#F6AD55",
|
|
8437
8594
|
completed: "#48BB78",
|
|
8438
|
-
failed: "#
|
|
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"
|
|
8439
8651
|
}
|
|
8440
8652
|
};
|
|
8653
|
+
theme = { ...darkTheme };
|
|
8654
|
+
activeMode = "dark";
|
|
8441
8655
|
}
|
|
8442
8656
|
});
|
|
8443
8657
|
|
|
@@ -12196,7 +12410,7 @@ __export(secret_storage_exports, {
|
|
|
12196
12410
|
listSecrets: () => listSecrets,
|
|
12197
12411
|
setSecret: () => setSecret
|
|
12198
12412
|
});
|
|
12199
|
-
import { promises as
|
|
12413
|
+
import { promises as fs4 } from "fs";
|
|
12200
12414
|
import { homedir as homedir7 } from "os";
|
|
12201
12415
|
import { dirname as dirname2, join as join9 } from "path";
|
|
12202
12416
|
async function getSecret(key) {
|
|
@@ -12228,11 +12442,11 @@ var init_secret_storage = __esm({
|
|
|
12228
12442
|
}
|
|
12229
12443
|
async ensureDirectoryExists() {
|
|
12230
12444
|
const dir = dirname2(this.secretFilePath);
|
|
12231
|
-
await
|
|
12445
|
+
await fs4.mkdir(dir, { recursive: true, mode: 448 });
|
|
12232
12446
|
}
|
|
12233
12447
|
async loadSecrets() {
|
|
12234
12448
|
try {
|
|
12235
|
-
const data = await
|
|
12449
|
+
const data = await fs4.readFile(this.secretFilePath, "utf-8");
|
|
12236
12450
|
const secrets = JSON.parse(data);
|
|
12237
12451
|
return new Map(Object.entries(secrets));
|
|
12238
12452
|
} catch (error) {
|
|
@@ -12241,7 +12455,7 @@ var init_secret_storage = __esm({
|
|
|
12241
12455
|
return /* @__PURE__ */ new Map();
|
|
12242
12456
|
}
|
|
12243
12457
|
try {
|
|
12244
|
-
await
|
|
12458
|
+
await fs4.unlink(this.secretFilePath);
|
|
12245
12459
|
} catch {
|
|
12246
12460
|
}
|
|
12247
12461
|
return /* @__PURE__ */ new Map();
|
|
@@ -12251,7 +12465,7 @@ var init_secret_storage = __esm({
|
|
|
12251
12465
|
await this.ensureDirectoryExists();
|
|
12252
12466
|
const data = Object.fromEntries(secrets);
|
|
12253
12467
|
const json = JSON.stringify(data, null, 2);
|
|
12254
|
-
await
|
|
12468
|
+
await fs4.writeFile(this.secretFilePath, json, { mode: 384 });
|
|
12255
12469
|
}
|
|
12256
12470
|
async getSecret(key) {
|
|
12257
12471
|
const secrets = await this.loadSecrets();
|
|
@@ -12270,7 +12484,7 @@ var init_secret_storage = __esm({
|
|
|
12270
12484
|
secrets.delete(key);
|
|
12271
12485
|
if (secrets.size === 0) {
|
|
12272
12486
|
try {
|
|
12273
|
-
await
|
|
12487
|
+
await fs4.unlink(this.secretFilePath);
|
|
12274
12488
|
} catch (error) {
|
|
12275
12489
|
const err = error;
|
|
12276
12490
|
if (err.code !== "ENOENT") {
|
|
@@ -13963,7 +14177,7 @@ var init_ConflictResolver = __esm({
|
|
|
13963
14177
|
return;
|
|
13964
14178
|
}
|
|
13965
14179
|
});
|
|
13966
|
-
return /* @__PURE__ */ React19.createElement(Box16, { borderColor:
|
|
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) => {
|
|
13967
14181
|
const isFocused = index === focusIndex;
|
|
13968
14182
|
const decision = decisions.get(conflict.testId) ?? "skip";
|
|
13969
14183
|
const indicator = isFocused ? "\u25B6 " : " ";
|
|
@@ -13975,7 +14189,7 @@ var init_ConflictResolver = __esm({
|
|
|
13975
14189
|
color: isFocused ? theme.text.primary : theme.text.dim
|
|
13976
14190
|
},
|
|
13977
14191
|
indicator,
|
|
13978
|
-
/* @__PURE__ */ React19.createElement(Text14, { color: decision === "takeOver" ?
|
|
14192
|
+
/* @__PURE__ */ React19.createElement(Text14, { color: decision === "takeOver" ? theme.text.success : theme.text.warning }, actionLabel),
|
|
13979
14193
|
" ",
|
|
13980
14194
|
conflict.testFile,
|
|
13981
14195
|
" - ",
|
|
@@ -13991,18 +14205,26 @@ var init_ConflictResolver = __esm({
|
|
|
13991
14205
|
// src/ui/components/ManualTestSelector.tsx
|
|
13992
14206
|
import { Box as Box17, Text as Text15, useInput as useInput2 } from "ink";
|
|
13993
14207
|
import React20, { useEffect as useEffect6, useRef as useRef6, useState as useState6 } from "react";
|
|
13994
|
-
var PAGE_SIZE, VISIBLE_ITEMS,
|
|
14208
|
+
var PAGE_SIZE, VISIBLE_ITEMS, getPriorityColor, ManualTestSelector;
|
|
13995
14209
|
var init_ManualTestSelector = __esm({
|
|
13996
14210
|
"src/ui/components/ManualTestSelector.tsx"() {
|
|
13997
14211
|
"use strict";
|
|
13998
14212
|
init_theme();
|
|
13999
14213
|
PAGE_SIZE = 50;
|
|
14000
14214
|
VISIBLE_ITEMS = 10;
|
|
14001
|
-
|
|
14002
|
-
|
|
14003
|
-
|
|
14004
|
-
|
|
14005
|
-
|
|
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
|
+
}
|
|
14006
14228
|
};
|
|
14007
14229
|
ManualTestSelector = ({
|
|
14008
14230
|
apiClient,
|
|
@@ -14145,19 +14367,19 @@ var init_ManualTestSelector = __esm({
|
|
|
14145
14367
|
}
|
|
14146
14368
|
});
|
|
14147
14369
|
if (error) {
|
|
14148
|
-
return /* @__PURE__ */ React20.createElement(Box17, { borderColor:
|
|
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")));
|
|
14149
14371
|
}
|
|
14150
14372
|
if (allTests.length === 0 && isLoading) {
|
|
14151
|
-
return /* @__PURE__ */ React20.createElement(Box17, { borderColor:
|
|
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"));
|
|
14152
14374
|
}
|
|
14153
14375
|
if (allTests.length === 0 && !isLoading) {
|
|
14154
|
-
return /* @__PURE__ */ React20.createElement(Box17, { borderColor:
|
|
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")));
|
|
14155
14377
|
}
|
|
14156
14378
|
const testStartIndex = cursorIndex - 1;
|
|
14157
14379
|
const adjustedStart = isOnAutomateNext ? 0 : Math.max(0, testStartIndex - Math.floor(VISIBLE_ITEMS / 2));
|
|
14158
14380
|
const adjustedEnd = Math.min(allTests.length, adjustedStart + VISIBLE_ITEMS);
|
|
14159
14381
|
const visibleTests = allTests.slice(adjustedStart, adjustedEnd);
|
|
14160
|
-
return /* @__PURE__ */ React20.createElement(Box17, { borderColor:
|
|
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(
|
|
14161
14383
|
Text15,
|
|
14162
14384
|
{
|
|
14163
14385
|
backgroundColor: isOnAutomateNext ? theme.text.accentBg : void 0,
|
|
@@ -14190,7 +14412,7 @@ var init_ManualTestSelector = __esm({
|
|
|
14190
14412
|
Text15,
|
|
14191
14413
|
{
|
|
14192
14414
|
backgroundColor: bgColor,
|
|
14193
|
-
color: isChecked ?
|
|
14415
|
+
color: isChecked ? theme.text.success : isSelected ? "white" : theme.text.dim
|
|
14194
14416
|
},
|
|
14195
14417
|
checkbox
|
|
14196
14418
|
), /* @__PURE__ */ React20.createElement(Text15, null, " "), /* @__PURE__ */ React20.createElement(
|
|
@@ -14204,14 +14426,14 @@ var init_ManualTestSelector = __esm({
|
|
|
14204
14426
|
Text15,
|
|
14205
14427
|
{
|
|
14206
14428
|
backgroundColor: bgColor,
|
|
14207
|
-
color: isSelected ? "white" :
|
|
14429
|
+
color: isSelected ? "white" : getPriorityColor(test.priority)
|
|
14208
14430
|
},
|
|
14209
14431
|
" ",
|
|
14210
14432
|
"[",
|
|
14211
14433
|
test.priority,
|
|
14212
14434
|
"]"
|
|
14213
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(" ")));
|
|
14214
|
-
})), /* @__PURE__ */ React20.createElement(Box17, { flexDirection: "column", marginTop: 1 }, allTests.length > VISIBLE_ITEMS && /* @__PURE__ */ React20.createElement(Box17, { marginBottom: 1 }, /* @__PURE__ */ React20.createElement(Text15, { color:
|
|
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..."))));
|
|
14215
14437
|
};
|
|
14216
14438
|
}
|
|
14217
14439
|
});
|
|
@@ -14392,7 +14614,7 @@ Press ESC to go back.`
|
|
|
14392
14614
|
description: "Start without claiming \u2014 assign later via /manage"
|
|
14393
14615
|
}
|
|
14394
14616
|
];
|
|
14395
|
-
return /* @__PURE__ */ React21.createElement(Box18, { borderColor:
|
|
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) => {
|
|
14396
14618
|
const isSelected = index === assignPromptIndex;
|
|
14397
14619
|
return /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", key: opt.label }, /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(
|
|
14398
14620
|
Text16,
|
|
@@ -14403,11 +14625,11 @@ Press ESC to go back.`
|
|
|
14403
14625
|
},
|
|
14404
14626
|
isSelected ? "\u25B6 " : " ",
|
|
14405
14627
|
opt.label
|
|
14406
|
-
)), /* @__PURE__ */ React21.createElement(Box18, { marginLeft: 4 }, /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? theme.text.primary : theme.text.dim
|
|
14628
|
+
)), /* @__PURE__ */ React21.createElement(Box18, { marginLeft: 4 }, /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? theme.text.primary : theme.text.dim }, opt.description)));
|
|
14407
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")));
|
|
14408
14630
|
}
|
|
14409
14631
|
case "claiming-tests":
|
|
14410
|
-
return /* @__PURE__ */ React21.createElement(Box18, { borderColor:
|
|
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...")));
|
|
14411
14633
|
case "resolve-conflicts":
|
|
14412
14634
|
return /* @__PURE__ */ React21.createElement(
|
|
14413
14635
|
ConflictResolver,
|
|
@@ -14418,11 +14640,11 @@ Press ESC to go back.`
|
|
|
14418
14640
|
}
|
|
14419
14641
|
);
|
|
14420
14642
|
case "loading-details":
|
|
14421
|
-
return /* @__PURE__ */ React21.createElement(Box18, { borderColor:
|
|
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...")));
|
|
14422
14644
|
case "automating":
|
|
14423
|
-
return /* @__PURE__ */ React21.createElement(Box18, { borderColor:
|
|
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...")));
|
|
14424
14646
|
case "error":
|
|
14425
|
-
return /* @__PURE__ */ React21.createElement(Box18, { borderColor:
|
|
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")));
|
|
14426
14648
|
default:
|
|
14427
14649
|
return null;
|
|
14428
14650
|
}
|
|
@@ -14895,13 +15117,13 @@ var init_RunSelector = __esm({
|
|
|
14895
15117
|
}
|
|
14896
15118
|
});
|
|
14897
15119
|
if (error) {
|
|
14898
|
-
return /* @__PURE__ */ React23.createElement(Box20, { borderColor:
|
|
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")));
|
|
14899
15121
|
}
|
|
14900
15122
|
if (allRuns.length === 0 && isLoading) {
|
|
14901
|
-
return /* @__PURE__ */ React23.createElement(Box20, { borderColor:
|
|
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"));
|
|
14902
15124
|
}
|
|
14903
15125
|
if (allRuns.length === 0 && !isLoading) {
|
|
14904
|
-
return /* @__PURE__ */ React23.createElement(Box20, { borderColor:
|
|
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")));
|
|
14905
15127
|
}
|
|
14906
15128
|
let startIndex;
|
|
14907
15129
|
let endIndex;
|
|
@@ -14922,7 +15144,7 @@ var init_RunSelector = __esm({
|
|
|
14922
15144
|
(run) => run.status === "errored" || (run.summary?.failed ?? 0) > 0
|
|
14923
15145
|
).length;
|
|
14924
15146
|
const runningCount = allRuns.filter((run) => run.status === "running").length;
|
|
14925
|
-
return /* @__PURE__ */ React23.createElement(Box20, { borderColor:
|
|
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) => {
|
|
14926
15148
|
const actualIndex = startIndex + index;
|
|
14927
15149
|
const isSelected = actualIndex === selectedIndex;
|
|
14928
15150
|
const branch = run.git?.branch || "-";
|
|
@@ -14997,7 +15219,7 @@ var init_RunSelector = __esm({
|
|
|
14997
15219
|
formatDurationMs(run.durationMs, run.status),
|
|
14998
15220
|
DURATION_COL_WIDTH
|
|
14999
15221
|
)), /* @__PURE__ */ React23.createElement(Text18, { backgroundColor: bgColor, color: defaultColor }, WIDE_GAP), /* @__PURE__ */ React23.createElement(Text18, { backgroundColor: bgColor, color: mutedColor }, formatCell(createdAgo, CREATED_COL_WIDTH)));
|
|
15000
|
-
})), /* @__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:
|
|
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..."))));
|
|
15001
15223
|
};
|
|
15002
15224
|
}
|
|
15003
15225
|
});
|
|
@@ -15259,13 +15481,13 @@ var init_TestSelector = __esm({
|
|
|
15259
15481
|
}
|
|
15260
15482
|
});
|
|
15261
15483
|
if (error) {
|
|
15262
|
-
return /* @__PURE__ */ React24.createElement(Box21, { borderColor:
|
|
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")));
|
|
15263
15485
|
}
|
|
15264
15486
|
if (allTests.length === 0 && isLoading) {
|
|
15265
|
-
return /* @__PURE__ */ React24.createElement(Box21, { borderColor:
|
|
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"));
|
|
15266
15488
|
}
|
|
15267
15489
|
if (allTests.length === 0 && !isLoading) {
|
|
15268
|
-
return /* @__PURE__ */ React24.createElement(Box21, { borderColor:
|
|
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")));
|
|
15269
15491
|
}
|
|
15270
15492
|
const testStartIndex = Math.max(0, cursorIndex - 1);
|
|
15271
15493
|
const adjustedStart = isOnFixNext10 ? 0 : Math.max(0, testStartIndex - Math.floor(VISIBLE_ITEMS3 / 2));
|
|
@@ -15275,7 +15497,7 @@ var init_TestSelector = __esm({
|
|
|
15275
15497
|
const commit = run.git?.commit?.slice(0, 7) || "";
|
|
15276
15498
|
const failedCount = run.summary?.failed ?? 0;
|
|
15277
15499
|
const flakyCount = run.summary?.flaky ?? 0;
|
|
15278
|
-
return /* @__PURE__ */ React24.createElement(Box21, { borderColor:
|
|
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(
|
|
15279
15501
|
Text19,
|
|
15280
15502
|
{
|
|
15281
15503
|
backgroundColor: isOnFixNext10 ? theme.text.accentBg : void 0,
|
|
@@ -15284,7 +15506,7 @@ var init_TestSelector = __esm({
|
|
|
15284
15506
|
},
|
|
15285
15507
|
isOnFixNext10 ? EXPANSION.COLLAPSED : " ",
|
|
15286
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" : ""}]`
|
|
15287
|
-
)), /* @__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:
|
|
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 ? (
|
|
15288
15510
|
// File Grouping Mode
|
|
15289
15511
|
fileGroups.map((group, index) => {
|
|
15290
15512
|
const itemIndex = index + 1;
|
|
@@ -15294,7 +15516,7 @@ var init_TestSelector = __esm({
|
|
|
15294
15516
|
const fileName = group.file.split("/").pop() || group.file;
|
|
15295
15517
|
const allSelected = group.availableCount > 0 && group.tests.filter((t) => !assignedTestIds.has(t.id)).every((t) => selectedTests.has(t.id));
|
|
15296
15518
|
const someSelected = group.tests.filter((t) => !assignedTestIds.has(t.id)).some((t) => selectedTests.has(t.id));
|
|
15297
|
-
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:
|
|
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) => {
|
|
15298
15520
|
const line = test.location?.line || "";
|
|
15299
15521
|
const title = test.title;
|
|
15300
15522
|
const isAssigned = assignedTestIds.has(test.id);
|
|
@@ -15317,9 +15539,9 @@ var init_TestSelector = __esm({
|
|
|
15317
15539
|
const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
|
|
15318
15540
|
const bgColor = isSelected ? theme.text.accentBg : void 0;
|
|
15319
15541
|
const displayAssignee = assignment?.assignedToName || assignment?.assignedTo || "";
|
|
15320
|
-
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:
|
|
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));
|
|
15321
15543
|
})
|
|
15322
|
-
)), /* @__PURE__ */ React24.createElement(Box21, { flexDirection: "column", marginTop: 1 }, !groupByFile && filteredTests.length > VISIBLE_ITEMS3 && /* @__PURE__ */ React24.createElement(Box21, { marginBottom: 1 }, /* @__PURE__ */ React24.createElement(Text19, { color:
|
|
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..."))));
|
|
15323
15545
|
};
|
|
15324
15546
|
}
|
|
15325
15547
|
});
|
|
@@ -15670,7 +15892,7 @@ Press ESC to go back and try again.`);
|
|
|
15670
15892
|
case "select-tests":
|
|
15671
15893
|
if (!selectedRun) return null;
|
|
15672
15894
|
if (!assignmentsLoaded) {
|
|
15673
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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"));
|
|
15674
15896
|
}
|
|
15675
15897
|
return /* @__PURE__ */ React25.createElement(
|
|
15676
15898
|
TestSelector,
|
|
@@ -15697,7 +15919,7 @@ Press ESC to go back and try again.`);
|
|
|
15697
15919
|
description: "Agent fixes everything automatically"
|
|
15698
15920
|
}
|
|
15699
15921
|
];
|
|
15700
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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) => {
|
|
15701
15923
|
const isSelected = index === modeSelectionIndex;
|
|
15702
15924
|
const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
|
|
15703
15925
|
return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", gap: 0, key: mode.label }, /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(
|
|
@@ -15712,8 +15934,7 @@ Press ESC to go back and try again.`);
|
|
|
15712
15934
|
)), /* @__PURE__ */ React25.createElement(Box22, { marginLeft: 4 }, /* @__PURE__ */ React25.createElement(
|
|
15713
15935
|
Text20,
|
|
15714
15936
|
{
|
|
15715
|
-
color: isSelected ? theme.text.primary : theme.text.dim
|
|
15716
|
-
dimColor: !isSelected
|
|
15937
|
+
color: isSelected ? theme.text.primary : theme.text.dim
|
|
15717
15938
|
},
|
|
15718
15939
|
mode.description
|
|
15719
15940
|
)));
|
|
@@ -15731,7 +15952,7 @@ Press ESC to go back and try again.`);
|
|
|
15731
15952
|
description: "Fix without claiming \u2014 you can assign later via /manage"
|
|
15732
15953
|
}
|
|
15733
15954
|
];
|
|
15734
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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) => {
|
|
15735
15956
|
const isSelected = index === assignPromptIndex;
|
|
15736
15957
|
const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
|
|
15737
15958
|
return /* @__PURE__ */ React25.createElement(Box22, { flexDirection: "column", gap: 0, key: option.label }, /* @__PURE__ */ React25.createElement(Box22, null, /* @__PURE__ */ React25.createElement(
|
|
@@ -15746,15 +15967,14 @@ Press ESC to go back and try again.`);
|
|
|
15746
15967
|
)), /* @__PURE__ */ React25.createElement(Box22, { marginLeft: 4 }, /* @__PURE__ */ React25.createElement(
|
|
15747
15968
|
Text20,
|
|
15748
15969
|
{
|
|
15749
|
-
color: isSelected ? theme.text.primary : theme.text.dim
|
|
15750
|
-
dimColor: !isSelected
|
|
15970
|
+
color: isSelected ? theme.text.primary : theme.text.dim
|
|
15751
15971
|
},
|
|
15752
15972
|
option.description
|
|
15753
15973
|
)));
|
|
15754
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")));
|
|
15755
15975
|
}
|
|
15756
15976
|
case "claiming-tests":
|
|
15757
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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...")));
|
|
15758
15978
|
case "resolve-conflicts":
|
|
15759
15979
|
return /* @__PURE__ */ React25.createElement(
|
|
15760
15980
|
ConflictResolver,
|
|
@@ -15766,17 +15986,17 @@ Press ESC to go back and try again.`);
|
|
|
15766
15986
|
);
|
|
15767
15987
|
case "loading-details":
|
|
15768
15988
|
if (loadError) {
|
|
15769
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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")));
|
|
15770
15990
|
}
|
|
15771
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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")));
|
|
15772
15992
|
case "error":
|
|
15773
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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")));
|
|
15774
15994
|
case "fixing": {
|
|
15775
15995
|
const modeLabel = workflowMode === "fix" ? "Analyzing & Fixing" : "Fixing";
|
|
15776
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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...")));
|
|
15777
15997
|
}
|
|
15778
15998
|
case "complete":
|
|
15779
|
-
return /* @__PURE__ */ React25.createElement(Box22, { borderColor:
|
|
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...")));
|
|
15780
16000
|
default:
|
|
15781
16001
|
return null;
|
|
15782
16002
|
}
|
|
@@ -16030,26 +16250,26 @@ var init_ModelSelector = __esm({
|
|
|
16030
16250
|
});
|
|
16031
16251
|
|
|
16032
16252
|
// src/ui/components/InputPrompt.tsx
|
|
16253
|
+
import { execSync as execSync6 } from "child_process";
|
|
16033
16254
|
import path4 from "path";
|
|
16034
|
-
import { execSync as execSync5 } from "child_process";
|
|
16035
16255
|
import chalk5 from "chalk";
|
|
16036
16256
|
import { Box as Box24, Text as Text23 } from "ink";
|
|
16037
16257
|
import React28, { forwardRef, memo as memo3, useEffect as useEffect11, useImperativeHandle, useRef as useRef9, useState as useState14 } from "react";
|
|
16038
16258
|
function readClipboard() {
|
|
16039
16259
|
try {
|
|
16040
16260
|
if (process.platform === "win32") {
|
|
16041
|
-
return
|
|
16261
|
+
return execSync6('powershell.exe -NoProfile -Command "Get-Clipboard"', {
|
|
16042
16262
|
encoding: "utf8",
|
|
16043
16263
|
timeout: 2e3
|
|
16044
16264
|
}).replace(/\r\n/g, "\n").replace(/\r/g, "\n").replace(/\n$/, "");
|
|
16045
16265
|
}
|
|
16046
16266
|
if (process.platform === "darwin") {
|
|
16047
|
-
return
|
|
16267
|
+
return execSync6("pbpaste", { encoding: "utf8", timeout: 2e3 });
|
|
16048
16268
|
}
|
|
16049
16269
|
try {
|
|
16050
|
-
return
|
|
16270
|
+
return execSync6("xclip -selection clipboard -o", { encoding: "utf8", timeout: 2e3 });
|
|
16051
16271
|
} catch {
|
|
16052
|
-
return
|
|
16272
|
+
return execSync6("xsel --clipboard --output", { encoding: "utf8", timeout: 2e3 });
|
|
16053
16273
|
}
|
|
16054
16274
|
} catch {
|
|
16055
16275
|
return null;
|
|
@@ -16914,7 +17134,7 @@ var init_ManageFlow = __esm({
|
|
|
16914
17134
|
};
|
|
16915
17135
|
switch (step) {
|
|
16916
17136
|
case "menu":
|
|
16917
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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) => {
|
|
16918
17138
|
const isSelected = index === menuIndex;
|
|
16919
17139
|
const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
|
|
16920
17140
|
return /* @__PURE__ */ React29.createElement(Box25, { flexDirection: "column", key: option.label }, /* @__PURE__ */ React29.createElement(
|
|
@@ -16930,12 +17150,12 @@ var init_ManageFlow = __esm({
|
|
|
16930
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"));
|
|
16931
17151
|
case "my-work":
|
|
16932
17152
|
if (myWorkLoading) {
|
|
16933
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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..."));
|
|
16934
17154
|
}
|
|
16935
17155
|
if (!myWorkData || myWorkData.assignments.length === 0) {
|
|
16936
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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")));
|
|
16937
17157
|
}
|
|
16938
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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")));
|
|
16939
17159
|
case "assign-run":
|
|
16940
17160
|
return /* @__PURE__ */ React29.createElement(
|
|
16941
17161
|
RunSelector,
|
|
@@ -16961,13 +17181,13 @@ var init_ManageFlow = __esm({
|
|
|
16961
17181
|
);
|
|
16962
17182
|
case "assign-to": {
|
|
16963
17183
|
if (assigneesLoading) {
|
|
16964
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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..."));
|
|
16965
17185
|
}
|
|
16966
17186
|
const options = assignees.map((a) => ({
|
|
16967
17187
|
label: a.name || a.email,
|
|
16968
17188
|
description: `${a.email} (${a.activeTests} active)`
|
|
16969
17189
|
}));
|
|
16970
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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) => {
|
|
16971
17191
|
const isSelected = index === assigneeIndex;
|
|
16972
17192
|
const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
|
|
16973
17193
|
return /* @__PURE__ */ React29.createElement(Box25, { key: opt.label }, /* @__PURE__ */ React29.createElement(
|
|
@@ -16992,15 +17212,15 @@ var init_ManageFlow = __esm({
|
|
|
16992
17212
|
}
|
|
16993
17213
|
);
|
|
16994
17214
|
case "assign-done":
|
|
16995
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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")));
|
|
16996
17216
|
case "unassign-list": {
|
|
16997
17217
|
if (unassignLoading) {
|
|
16998
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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..."));
|
|
16999
17219
|
}
|
|
17000
17220
|
if (allAssignments.length === 0) {
|
|
17001
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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")));
|
|
17002
17222
|
}
|
|
17003
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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) => {
|
|
17004
17224
|
const isFocused = index === unassignIndex;
|
|
17005
17225
|
const isSelected = unassignSelections.has(index);
|
|
17006
17226
|
const indicator = isFocused ? EXPANSION.COLLAPSED : " ";
|
|
@@ -17023,7 +17243,7 @@ var init_ManageFlow = __esm({
|
|
|
17023
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")));
|
|
17024
17244
|
}
|
|
17025
17245
|
case "unassign-done":
|
|
17026
|
-
return /* @__PURE__ */ React29.createElement(Box25, { borderColor:
|
|
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")));
|
|
17027
17247
|
default:
|
|
17028
17248
|
return null;
|
|
17029
17249
|
}
|
|
@@ -17365,8 +17585,7 @@ var init_PlanApprovalSelector = __esm({
|
|
|
17365
17585
|
)), /* @__PURE__ */ React33.createElement(Box29, { marginLeft: 4 }, /* @__PURE__ */ React33.createElement(
|
|
17366
17586
|
Text28,
|
|
17367
17587
|
{
|
|
17368
|
-
color: isSelected ? theme.text.primary : theme.text.dim
|
|
17369
|
-
dimColor: !isSelected
|
|
17588
|
+
color: isSelected ? theme.text.primary : theme.text.dim
|
|
17370
17589
|
},
|
|
17371
17590
|
option.description
|
|
17372
17591
|
)));
|
|
@@ -17435,15 +17654,15 @@ var init_ProjectSelector = __esm({
|
|
|
17435
17654
|
return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color: theme.text.accent }, "Loading projects..."));
|
|
17436
17655
|
}
|
|
17437
17656
|
if (error) {
|
|
17438
|
-
return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color:
|
|
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"));
|
|
17439
17658
|
}
|
|
17440
17659
|
if (projects.length === 0) {
|
|
17441
|
-
return /* @__PURE__ */ React34.createElement(Box30, { flexDirection: "column", paddingX: 1 }, /* @__PURE__ */ React34.createElement(Text29, { color:
|
|
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"));
|
|
17442
17661
|
}
|
|
17443
|
-
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, {
|
|
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) => {
|
|
17444
17663
|
const isSelected = index === selectedIndex;
|
|
17445
17664
|
const isCurrent = project.id === currentProjectId;
|
|
17446
|
-
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, {
|
|
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"));
|
|
17447
17666
|
}));
|
|
17448
17667
|
};
|
|
17449
17668
|
}
|
|
@@ -17633,8 +17852,7 @@ var init_QuestionSelector = __esm({
|
|
|
17633
17852
|
)), /* @__PURE__ */ React36.createElement(Box31, { marginLeft: multiSelect ? 6 : 4 }, /* @__PURE__ */ React36.createElement(
|
|
17634
17853
|
Text31,
|
|
17635
17854
|
{
|
|
17636
|
-
color: isSelected ? theme.text.primary : theme.text.dim
|
|
17637
|
-
dimColor: !isSelected
|
|
17855
|
+
color: isSelected ? theme.text.primary : theme.text.dim
|
|
17638
17856
|
},
|
|
17639
17857
|
option.description
|
|
17640
17858
|
)));
|
|
@@ -17717,13 +17935,13 @@ var init_SessionSelector = __esm({
|
|
|
17717
17935
|
}
|
|
17718
17936
|
});
|
|
17719
17937
|
if (error) {
|
|
17720
|
-
return /* @__PURE__ */ React37.createElement(Box32, { borderColor:
|
|
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")));
|
|
17721
17939
|
}
|
|
17722
17940
|
if (allSessions.length === 0 && isLoading) {
|
|
17723
|
-
return /* @__PURE__ */ React37.createElement(Box32, { borderColor:
|
|
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"));
|
|
17724
17942
|
}
|
|
17725
17943
|
if (allSessions.length === 0 && !isLoading) {
|
|
17726
|
-
return /* @__PURE__ */ React37.createElement(Box32, { borderColor:
|
|
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")));
|
|
17727
17945
|
}
|
|
17728
17946
|
const VISIBLE_ITEMS4 = 10;
|
|
17729
17947
|
let startIndex;
|
|
@@ -17743,7 +17961,7 @@ var init_SessionSelector = __esm({
|
|
|
17743
17961
|
const visibleSessions = allSessions.slice(startIndex, endIndex);
|
|
17744
17962
|
const MAX_TITLE_WIDTH = 50;
|
|
17745
17963
|
const PREFIX_WIDTH = 6;
|
|
17746
|
-
return /* @__PURE__ */ React37.createElement(Box32, { borderColor:
|
|
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) => {
|
|
17747
17965
|
const actualIndex = startIndex + index;
|
|
17748
17966
|
const isSelected = actualIndex === selectedIndex;
|
|
17749
17967
|
const title = item.session.title || "Untitled session";
|
|
@@ -17764,11 +17982,11 @@ var init_SessionSelector = __esm({
|
|
|
17764
17982
|
dateStr = `${sessionDate.toLocaleDateString([], { month: "numeric", day: "numeric" })} ${sessionDate.toLocaleTimeString([], { hour: "numeric", minute: "2-digit" })}`;
|
|
17765
17983
|
}
|
|
17766
17984
|
const prefix = item.prefix.padEnd(PREFIX_WIDTH, " ");
|
|
17767
|
-
const prefixColor = item.prefix === "[Me]" ?
|
|
17985
|
+
const prefixColor = item.prefix === "[Me]" ? theme.text.accent : theme.text.warning;
|
|
17768
17986
|
const indicator = isSelected ? EXPANSION.COLLAPSED : " ";
|
|
17769
17987
|
const bgColor = isSelected ? theme.text.accentBg : void 0;
|
|
17770
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, ")"));
|
|
17771
|
-
})), /* @__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:
|
|
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..."))));
|
|
17772
17990
|
};
|
|
17773
17991
|
}
|
|
17774
17992
|
});
|
|
@@ -17817,7 +18035,7 @@ var init_useOverlayEscapeGuard = __esm({
|
|
|
17817
18035
|
});
|
|
17818
18036
|
|
|
17819
18037
|
// src/ui/App.tsx
|
|
17820
|
-
import { execSync as
|
|
18038
|
+
import { execSync as execSync7 } from "child_process";
|
|
17821
18039
|
import { homedir as homedir9 } from "os";
|
|
17822
18040
|
import { Box as Box33, Text as Text33, useApp as useApp2, useStdout as useStdout2 } from "ink";
|
|
17823
18041
|
import Spinner4 from "ink-spinner";
|
|
@@ -17863,7 +18081,7 @@ var init_App = __esm({
|
|
|
17863
18081
|
init_theme();
|
|
17864
18082
|
getGitBranch2 = () => {
|
|
17865
18083
|
try {
|
|
17866
|
-
return
|
|
18084
|
+
return execSync7("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
|
|
17867
18085
|
} catch {
|
|
17868
18086
|
return "";
|
|
17869
18087
|
}
|
|
@@ -17958,8 +18176,7 @@ var init_App = __esm({
|
|
|
17958
18176
|
config2.projectId = project.id;
|
|
17959
18177
|
apiClient.setProjectId(project.id);
|
|
17960
18178
|
saveSupatestSettings(config2.cwd || process.cwd(), {
|
|
17961
|
-
projectId: project.slug
|
|
17962
|
-
projectName: project.name
|
|
18179
|
+
projectId: project.slug
|
|
17963
18180
|
});
|
|
17964
18181
|
} else if (result.projects.length > 1) {
|
|
17965
18182
|
addMessage({
|
|
@@ -18056,8 +18273,7 @@ var init_App = __esm({
|
|
|
18056
18273
|
setSavedProjectSlug(void 0);
|
|
18057
18274
|
config2.projectId = void 0;
|
|
18058
18275
|
saveSupatestSettings(config2.cwd || process.cwd(), {
|
|
18059
|
-
projectId: void 0
|
|
18060
|
-
projectName: void 0
|
|
18276
|
+
projectId: void 0
|
|
18061
18277
|
});
|
|
18062
18278
|
setAuthState("unauthenticated" /* Unauthenticated */);
|
|
18063
18279
|
addMessage({
|
|
@@ -18491,8 +18707,7 @@ Make sure the file exists and is a valid image (png, jpg, gif, webp, bmp, svg).`
|
|
|
18491
18707
|
apiClient.setProjectId(project.id);
|
|
18492
18708
|
}
|
|
18493
18709
|
saveSupatestSettings(config2.cwd || process.cwd(), {
|
|
18494
|
-
projectId: project.slug
|
|
18495
|
-
projectName: project.name
|
|
18710
|
+
projectId: project.slug
|
|
18496
18711
|
});
|
|
18497
18712
|
addMessage({
|
|
18498
18713
|
type: "assistant",
|
|
@@ -19041,7 +19256,7 @@ Make sure the file exists and is a valid image (png, jpg, gif, webp, bmp, svg).`
|
|
|
19041
19256
|
onInputChange: handleInputChange,
|
|
19042
19257
|
onSubmit: stableHandleSubmitTask,
|
|
19043
19258
|
placeholder: "Enter your task...",
|
|
19044
|
-
projectName: currentProject?.
|
|
19259
|
+
projectName: currentProject?.slug,
|
|
19045
19260
|
ref: inputPromptRef,
|
|
19046
19261
|
selectedModel,
|
|
19047
19262
|
setSelectedModel
|
|
@@ -19684,13 +19899,13 @@ await init_agent();
|
|
|
19684
19899
|
init_react();
|
|
19685
19900
|
init_MessageList();
|
|
19686
19901
|
init_SessionContext();
|
|
19687
|
-
import { execSync as
|
|
19902
|
+
import { execSync as execSync3 } from "child_process";
|
|
19688
19903
|
import { homedir as homedir5 } from "os";
|
|
19689
19904
|
import { Box as Box13, useApp } from "ink";
|
|
19690
19905
|
import React14, { useEffect as useEffect2, useRef as useRef4, useState as useState3 } from "react";
|
|
19691
19906
|
var getGitBranch = () => {
|
|
19692
19907
|
try {
|
|
19693
|
-
return
|
|
19908
|
+
return execSync3("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
|
|
19694
19909
|
} catch {
|
|
19695
19910
|
return "";
|
|
19696
19911
|
}
|
|
@@ -19948,10 +20163,13 @@ async function runAgent(config2) {
|
|
|
19948
20163
|
});
|
|
19949
20164
|
}
|
|
19950
20165
|
|
|
20166
|
+
// src/index.ts
|
|
20167
|
+
init_theme();
|
|
20168
|
+
|
|
19951
20169
|
// src/utils/auto-update.ts
|
|
19952
20170
|
init_version();
|
|
19953
20171
|
init_error_logger();
|
|
19954
|
-
import { execSync as
|
|
20172
|
+
import { execSync as execSync4, spawn as spawn2 } from "child_process";
|
|
19955
20173
|
import latestVersion from "latest-version";
|
|
19956
20174
|
import { gt } from "semver";
|
|
19957
20175
|
var UPDATE_CHECK_TIMEOUT = 3e3;
|
|
@@ -19977,7 +20195,7 @@ async function checkAndAutoUpdate() {
|
|
|
19977
20195
|
Updating Supatest CLI ${CLI_VERSION} \u2192 ${latest}...`);
|
|
19978
20196
|
try {
|
|
19979
20197
|
try {
|
|
19980
|
-
const npmPrefix =
|
|
20198
|
+
const npmPrefix = execSync4("npm config get prefix", { encoding: "utf-8" }).trim();
|
|
19981
20199
|
if (process.platform === "win32") {
|
|
19982
20200
|
const { rmSync, readdirSync: readdirSync2 } = await import("fs");
|
|
19983
20201
|
const modulesDir = `${npmPrefix}\\node_modules\\@supatest`;
|
|
@@ -19986,24 +20204,24 @@ Updating Supatest CLI ${CLI_VERSION} \u2192 ${latest}...`);
|
|
|
19986
20204
|
rmSync(`${modulesDir}\\${entry}`, { recursive: true, force: true });
|
|
19987
20205
|
}
|
|
19988
20206
|
} else {
|
|
19989
|
-
|
|
20207
|
+
execSync4(`rm -rf ${npmPrefix}/lib/node_modules/@supatest/.cli-* 2>/dev/null || true`);
|
|
19990
20208
|
}
|
|
19991
20209
|
} catch {
|
|
19992
20210
|
}
|
|
19993
20211
|
try {
|
|
19994
|
-
|
|
20212
|
+
execSync4("npm update -g @supatest/cli", {
|
|
19995
20213
|
stdio: "inherit",
|
|
19996
20214
|
timeout: INSTALL_TIMEOUT
|
|
19997
20215
|
});
|
|
19998
20216
|
} catch {
|
|
19999
|
-
|
|
20217
|
+
execSync4("npm install -g @supatest/cli@latest --force", {
|
|
20000
20218
|
stdio: "inherit",
|
|
20001
20219
|
timeout: INSTALL_TIMEOUT
|
|
20002
20220
|
});
|
|
20003
20221
|
}
|
|
20004
20222
|
let updateVerified = false;
|
|
20005
20223
|
try {
|
|
20006
|
-
const installedVersion =
|
|
20224
|
+
const installedVersion = execSync4("npm ls -g @supatest/cli --json 2>/dev/null", {
|
|
20007
20225
|
encoding: "utf-8"
|
|
20008
20226
|
});
|
|
20009
20227
|
const parsed = JSON.parse(installedVersion);
|
|
@@ -20049,7 +20267,7 @@ init_logger();
|
|
|
20049
20267
|
|
|
20050
20268
|
// src/utils/node-version.ts
|
|
20051
20269
|
init_logger();
|
|
20052
|
-
import { execSync as
|
|
20270
|
+
import { execSync as execSync5 } from "child_process";
|
|
20053
20271
|
var MINIMUM_NODE_VERSION2 = 18;
|
|
20054
20272
|
function parseVersion2(versionString) {
|
|
20055
20273
|
const cleaned = versionString.trim().replace(/^v/, "");
|
|
@@ -20066,7 +20284,7 @@ function parseVersion2(versionString) {
|
|
|
20066
20284
|
}
|
|
20067
20285
|
function getNodeVersion2() {
|
|
20068
20286
|
try {
|
|
20069
|
-
const versionOutput =
|
|
20287
|
+
const versionOutput = execSync5("node --version", {
|
|
20070
20288
|
encoding: "utf-8",
|
|
20071
20289
|
stdio: ["ignore", "pipe", "ignore"]
|
|
20072
20290
|
});
|
|
@@ -20189,9 +20407,18 @@ program.name("supatest").description(
|
|
|
20189
20407
|
).option(
|
|
20190
20408
|
"--claude-max-iterations <number>",
|
|
20191
20409
|
"[Deprecated] Alias for --max-iterations"
|
|
20192
|
-
).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) => {
|
|
20193
20411
|
try {
|
|
20194
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
|
+
}
|
|
20195
20422
|
await checkAndAutoUpdate();
|
|
20196
20423
|
const isHeadlessMode = options.headless || process.stdin.isTTY === false;
|
|
20197
20424
|
if (options.verbose) {
|
|
@@ -20210,9 +20437,9 @@ program.name("supatest").description(
|
|
|
20210
20437
|
logs = stdinContent;
|
|
20211
20438
|
}
|
|
20212
20439
|
if (options.logs) {
|
|
20213
|
-
const
|
|
20440
|
+
const fs5 = await import("fs/promises");
|
|
20214
20441
|
try {
|
|
20215
|
-
logs = await
|
|
20442
|
+
logs = await fs5.readFile(options.logs, "utf-8");
|
|
20216
20443
|
} catch (error) {
|
|
20217
20444
|
logger.error(`Failed to read log file: ${options.logs}`);
|
|
20218
20445
|
process.exit(1);
|