@supatest/cli 0.0.37 → 0.0.39
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 +112 -87
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5891,7 +5891,7 @@ var CLI_VERSION;
|
|
|
5891
5891
|
var init_version = __esm({
|
|
5892
5892
|
"src/version.ts"() {
|
|
5893
5893
|
"use strict";
|
|
5894
|
-
CLI_VERSION = "0.0.
|
|
5894
|
+
CLI_VERSION = "0.0.39";
|
|
5895
5895
|
}
|
|
5896
5896
|
});
|
|
5897
5897
|
|
|
@@ -5963,7 +5963,7 @@ var init_error_logger = __esm({
|
|
|
5963
5963
|
"src/utils/error-logger.ts"() {
|
|
5964
5964
|
"use strict";
|
|
5965
5965
|
init_version();
|
|
5966
|
-
SUPATEST_DIR = path2.join(os2.homedir(), ".supatest");
|
|
5966
|
+
SUPATEST_DIR = process.platform === "win32" ? path2.join(os2.tmpdir(), ".supatest") : path2.join(os2.homedir(), ".supatest");
|
|
5967
5967
|
LOGS_DIR = path2.join(SUPATEST_DIR, "logs");
|
|
5968
5968
|
ERROR_LOG_FILE = path2.join(LOGS_DIR, "error.log");
|
|
5969
5969
|
MAX_LOG_SIZE = 5 * 1024 * 1024;
|
|
@@ -7527,7 +7527,7 @@ var init_react = __esm({
|
|
|
7527
7527
|
});
|
|
7528
7528
|
|
|
7529
7529
|
// src/ui/contexts/SessionContext.tsx
|
|
7530
|
-
import React, { createContext, useCallback, useContext, useMemo, useState } from "react";
|
|
7530
|
+
import React, { createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
|
|
7531
7531
|
var SessionContext, SessionProvider, useSession;
|
|
7532
7532
|
var init_SessionContext = __esm({
|
|
7533
7533
|
"src/ui/contexts/SessionContext.tsx"() {
|
|
@@ -7573,12 +7573,25 @@ var init_SessionContext = __esm({
|
|
|
7573
7573
|
},
|
|
7574
7574
|
[allToolsExpanded]
|
|
7575
7575
|
);
|
|
7576
|
+
const pendingUpdateRef = useRef(null);
|
|
7577
|
+
const updateScheduledRef = useRef(false);
|
|
7576
7578
|
const updateLastMessage = useCallback((updates) => {
|
|
7577
|
-
|
|
7578
|
-
|
|
7579
|
-
|
|
7580
|
-
|
|
7581
|
-
|
|
7579
|
+
pendingUpdateRef.current = pendingUpdateRef.current ? { ...pendingUpdateRef.current, ...updates } : updates;
|
|
7580
|
+
if (!updateScheduledRef.current) {
|
|
7581
|
+
updateScheduledRef.current = true;
|
|
7582
|
+
setTimeout(() => {
|
|
7583
|
+
updateScheduledRef.current = false;
|
|
7584
|
+
const pending = pendingUpdateRef.current;
|
|
7585
|
+
pendingUpdateRef.current = null;
|
|
7586
|
+
if (pending) {
|
|
7587
|
+
setMessages((prev) => {
|
|
7588
|
+
if (prev.length === 0) return prev;
|
|
7589
|
+
const last = prev[prev.length - 1];
|
|
7590
|
+
return [...prev.slice(0, -1), { ...last, ...pending }];
|
|
7591
|
+
});
|
|
7592
|
+
}
|
|
7593
|
+
}, 0);
|
|
7594
|
+
}
|
|
7582
7595
|
}, []);
|
|
7583
7596
|
const updateMessageById = useCallback((id, updates) => {
|
|
7584
7597
|
setMessages((prev) => {
|
|
@@ -8248,48 +8261,36 @@ var init_ErrorMessage = __esm({
|
|
|
8248
8261
|
// src/ui/components/messages/LoadingMessage.tsx
|
|
8249
8262
|
import { Box as Box5, Text as Text5 } from "ink";
|
|
8250
8263
|
import Spinner2 from "ink-spinner";
|
|
8251
|
-
import React6, { useEffect, useState as useState2 } from "react";
|
|
8252
|
-
var LOADING_MESSAGES,
|
|
8264
|
+
import React6, { memo, useEffect, useRef as useRef2, useState as useState2 } from "react";
|
|
8265
|
+
var LOADING_MESSAGES, TEXT_ROTATION_INTERVAL_MS, LoadingMessage;
|
|
8253
8266
|
var init_LoadingMessage = __esm({
|
|
8254
8267
|
"src/ui/components/messages/LoadingMessage.tsx"() {
|
|
8255
8268
|
"use strict";
|
|
8256
8269
|
init_theme();
|
|
8257
8270
|
LOADING_MESSAGES = [
|
|
8258
|
-
"
|
|
8259
|
-
"
|
|
8260
|
-
"
|
|
8261
|
-
"Testing theories...",
|
|
8262
|
-
"Making magic...",
|
|
8263
|
-
"Multiplying matrices..."
|
|
8271
|
+
"Thinking...",
|
|
8272
|
+
"Working...",
|
|
8273
|
+
"Processing..."
|
|
8264
8274
|
];
|
|
8265
|
-
|
|
8266
|
-
|
|
8267
|
-
LoadingMessage = ({ headless = false }) => {
|
|
8275
|
+
TEXT_ROTATION_INTERVAL_MS = 3e3;
|
|
8276
|
+
LoadingMessage = memo(({ headless = false }) => {
|
|
8268
8277
|
const [messageIndex, setMessageIndex] = useState2(0);
|
|
8269
|
-
const
|
|
8278
|
+
const intervalRef = useRef2(null);
|
|
8270
8279
|
const message = LOADING_MESSAGES[messageIndex];
|
|
8271
8280
|
useEffect(() => {
|
|
8272
|
-
|
|
8281
|
+
intervalRef.current = setInterval(() => {
|
|
8273
8282
|
setMessageIndex((prev) => (prev + 1) % LOADING_MESSAGES.length);
|
|
8274
|
-
setShimmerPosition(0);
|
|
8275
8283
|
}, TEXT_ROTATION_INTERVAL_MS);
|
|
8276
8284
|
return () => {
|
|
8277
|
-
|
|
8285
|
+
if (intervalRef.current) {
|
|
8286
|
+
clearInterval(intervalRef.current);
|
|
8287
|
+
intervalRef.current = null;
|
|
8288
|
+
}
|
|
8278
8289
|
};
|
|
8279
8290
|
}, []);
|
|
8280
|
-
|
|
8281
|
-
|
|
8282
|
-
|
|
8283
|
-
}, SHIMMER_INTERVAL_MS);
|
|
8284
|
-
return () => {
|
|
8285
|
-
clearInterval(shimmerInterval);
|
|
8286
|
-
};
|
|
8287
|
-
}, [message.length]);
|
|
8288
|
-
const before = message.slice(0, shimmerPosition);
|
|
8289
|
-
const current = message[shimmerPosition] || "";
|
|
8290
|
-
const after = message.slice(shimmerPosition + 1);
|
|
8291
|
-
return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React6.createElement(Box5, { width: 2 }, /* @__PURE__ */ React6.createElement(Text5, { color: theme.text.accent }, /* @__PURE__ */ React6.createElement(Spinner2, { type: "dots" }))), /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React6.createElement(Text5, null, /* @__PURE__ */ React6.createElement(Text5, { color: theme.text.primary }, before), /* @__PURE__ */ React6.createElement(Text5, { bold: true, color: theme.text.accent }, current), /* @__PURE__ */ React6.createElement(Text5, { color: theme.text.primary }, after), !headless && /* @__PURE__ */ React6.createElement(Text5, { color: theme.text.primary }, " (esc to interrupt)"))));
|
|
8292
|
-
};
|
|
8291
|
+
return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "row", marginTop: 1 }, /* @__PURE__ */ React6.createElement(Box5, { width: 2 }, /* @__PURE__ */ React6.createElement(Text5, { color: theme.text.accent }, /* @__PURE__ */ React6.createElement(Spinner2, { type: "dots" }))), /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column", flexGrow: 1 }, /* @__PURE__ */ React6.createElement(Text5, null, /* @__PURE__ */ React6.createElement(Text5, { color: theme.text.primary }, message), !headless && /* @__PURE__ */ React6.createElement(Text5, { color: theme.text.dim }, " (esc to interrupt)"))));
|
|
8292
|
+
});
|
|
8293
|
+
LoadingMessage.displayName = "LoadingMessage";
|
|
8293
8294
|
}
|
|
8294
8295
|
});
|
|
8295
8296
|
|
|
@@ -8620,7 +8621,7 @@ var init_QueuedMessageDisplay = __esm({
|
|
|
8620
8621
|
|
|
8621
8622
|
// src/ui/components/MessageList.tsx
|
|
8622
8623
|
import { Box as Box12, Static } from "ink";
|
|
8623
|
-
import React13, { useMemo as
|
|
8624
|
+
import React13, { memo as memo2, useCallback as useCallback2, useMemo as useMemo3, useRef as useRef3 } from "react";
|
|
8624
8625
|
var MessageList;
|
|
8625
8626
|
var init_MessageList = __esm({
|
|
8626
8627
|
"src/ui/components/MessageList.tsx"() {
|
|
@@ -8636,9 +8637,12 @@ var init_MessageList = __esm({
|
|
|
8636
8637
|
init_ToolMessage();
|
|
8637
8638
|
init_UserMessage();
|
|
8638
8639
|
init_QueuedMessageDisplay();
|
|
8639
|
-
MessageList = ({ terminalWidth, currentFolder, gitBranch, headless = false, queuedTasks = [] }) => {
|
|
8640
|
+
MessageList = memo2(({ terminalWidth, currentFolder, gitBranch, headless = false, queuedTasks = [] }) => {
|
|
8640
8641
|
const { messages, updateMessageById, isAgentRunning, staticRemountKey, toolGroupsExpanded, toggleToolGroups } = useSession();
|
|
8641
|
-
const
|
|
8642
|
+
const handleToggle = useCallback2((id, currentExpanded) => {
|
|
8643
|
+
updateMessageById(id, { isExpanded: !currentExpanded });
|
|
8644
|
+
}, [updateMessageById]);
|
|
8645
|
+
const renderMessage = useCallback2((message, isInGroup = false) => {
|
|
8642
8646
|
switch (message.type) {
|
|
8643
8647
|
case "user":
|
|
8644
8648
|
return /* @__PURE__ */ React13.createElement(UserMessage, { key: message.id, text: message.content });
|
|
@@ -8662,7 +8666,7 @@ var init_MessageList = __esm({
|
|
|
8662
8666
|
input: message.toolInput,
|
|
8663
8667
|
isExpanded: message.isExpanded,
|
|
8664
8668
|
key: message.id,
|
|
8665
|
-
onToggle: (id) =>
|
|
8669
|
+
onToggle: (id) => handleToggle(id, message.isExpanded),
|
|
8666
8670
|
result: message.toolResult,
|
|
8667
8671
|
toolName: message.toolName || "Unknown"
|
|
8668
8672
|
}
|
|
@@ -8676,7 +8680,7 @@ var init_MessageList = __esm({
|
|
|
8676
8680
|
input: message.toolInput,
|
|
8677
8681
|
isExpanded: message.isExpanded,
|
|
8678
8682
|
key: message.id,
|
|
8679
|
-
onToggle: (id) =>
|
|
8683
|
+
onToggle: (id) => handleToggle(id, message.isExpanded),
|
|
8680
8684
|
result: message.toolResult,
|
|
8681
8685
|
toolName: message.toolName || "Unknown"
|
|
8682
8686
|
}
|
|
@@ -8689,7 +8693,7 @@ var init_MessageList = __esm({
|
|
|
8689
8693
|
id: message.id,
|
|
8690
8694
|
isExpanded: message.isExpanded,
|
|
8691
8695
|
key: message.id,
|
|
8692
|
-
onToggle: (id) =>
|
|
8696
|
+
onToggle: (id) => handleToggle(id, message.isExpanded)
|
|
8693
8697
|
}
|
|
8694
8698
|
);
|
|
8695
8699
|
case "error":
|
|
@@ -8706,8 +8710,8 @@ var init_MessageList = __esm({
|
|
|
8706
8710
|
default:
|
|
8707
8711
|
return null;
|
|
8708
8712
|
}
|
|
8709
|
-
};
|
|
8710
|
-
const renderGroupedMessage = (group) => {
|
|
8713
|
+
}, [terminalWidth, handleToggle]);
|
|
8714
|
+
const renderGroupedMessage = useCallback2((group) => {
|
|
8711
8715
|
if (group.type === "group") {
|
|
8712
8716
|
return /* @__PURE__ */ React13.createElement(
|
|
8713
8717
|
ToolGroup,
|
|
@@ -8718,7 +8722,7 @@ var init_MessageList = __esm({
|
|
|
8718
8722
|
onToggleTool: (id) => {
|
|
8719
8723
|
const msg = group.messages.find((m) => m.id === id);
|
|
8720
8724
|
if (msg) {
|
|
8721
|
-
|
|
8725
|
+
handleToggle(id, msg.isExpanded);
|
|
8722
8726
|
}
|
|
8723
8727
|
},
|
|
8724
8728
|
tools: group.messages.map((msg) => ({
|
|
@@ -8733,8 +8737,8 @@ var init_MessageList = __esm({
|
|
|
8733
8737
|
);
|
|
8734
8738
|
}
|
|
8735
8739
|
return renderMessage(group.messages[0]);
|
|
8736
|
-
};
|
|
8737
|
-
const lastUserMessageIndex =
|
|
8740
|
+
}, [toolGroupsExpanded, toggleToolGroups, handleToggle, renderMessage]);
|
|
8741
|
+
const lastUserMessageIndex = useMemo3(() => {
|
|
8738
8742
|
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8739
8743
|
if (messages[i].type === "user") {
|
|
8740
8744
|
return i;
|
|
@@ -8742,12 +8746,12 @@ var init_MessageList = __esm({
|
|
|
8742
8746
|
}
|
|
8743
8747
|
return -1;
|
|
8744
8748
|
}, [messages]);
|
|
8745
|
-
const hasPendingAssistant =
|
|
8749
|
+
const hasPendingAssistant = useMemo3(
|
|
8746
8750
|
() => messages.some((m) => m.type === "assistant" && m.isPending),
|
|
8747
8751
|
[messages]
|
|
8748
8752
|
);
|
|
8749
|
-
const completedBoundaryRef =
|
|
8750
|
-
const completedBoundaryKey =
|
|
8753
|
+
const completedBoundaryRef = useRef3(-1);
|
|
8754
|
+
const completedBoundaryKey = useMemo3(() => {
|
|
8751
8755
|
const currentBoundary = lastUserMessageIndex;
|
|
8752
8756
|
if (currentBoundary !== completedBoundaryRef.current) {
|
|
8753
8757
|
completedBoundaryRef.current = currentBoundary;
|
|
@@ -8755,7 +8759,7 @@ var init_MessageList = __esm({
|
|
|
8755
8759
|
}
|
|
8756
8760
|
return `boundary-${completedBoundaryRef.current}`;
|
|
8757
8761
|
}, [lastUserMessageIndex]);
|
|
8758
|
-
const { completedGroups, currentTurnGroups } =
|
|
8762
|
+
const { completedGroups, currentTurnGroups } = useMemo3(() => {
|
|
8759
8763
|
const completed = [];
|
|
8760
8764
|
const currentTurn = [];
|
|
8761
8765
|
const processTurn = (turnMessages2, targetArray) => {
|
|
@@ -8798,7 +8802,7 @@ var init_MessageList = __esm({
|
|
|
8798
8802
|
processTurn(currentTurnMessages, currentTurn);
|
|
8799
8803
|
return { completedGroups: completed, currentTurnGroups: currentTurn };
|
|
8800
8804
|
}, [messages, lastUserMessageIndex, completedBoundaryKey]);
|
|
8801
|
-
const staticItems =
|
|
8805
|
+
const staticItems = useMemo3(() => [
|
|
8802
8806
|
{ id: "header", type: "header" },
|
|
8803
8807
|
...completedGroups.map((group, idx) => {
|
|
8804
8808
|
if (group.type === "group") {
|
|
@@ -8807,7 +8811,7 @@ var init_MessageList = __esm({
|
|
|
8807
8811
|
return { ...group.messages[0], _isMessage: true };
|
|
8808
8812
|
})
|
|
8809
8813
|
], [completedGroups]);
|
|
8810
|
-
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React13.createElement(Static, { items: staticItems, key:
|
|
8814
|
+
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React13.createElement(Static, { items: staticItems, key: staticRemountKey }, (item) => {
|
|
8811
8815
|
if (item.type === "header") {
|
|
8812
8816
|
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", key: "header" }, /* @__PURE__ */ React13.createElement(Header, { currentFolder, gitBranch, headless }));
|
|
8813
8817
|
}
|
|
@@ -8830,7 +8834,8 @@ var init_MessageList = __esm({
|
|
|
8830
8834
|
}
|
|
8831
8835
|
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", key: group.type === "group" ? `current-group-${idx}` : group.messages[0].id, width: "100%" }, content);
|
|
8832
8836
|
}), /* @__PURE__ */ React13.createElement(QueuedMessageDisplay, { messageQueue: queuedTasks }), isAgentRunning && !hasPendingAssistant && /* @__PURE__ */ React13.createElement(LoadingMessage, { headless, key: "loading" }), /* @__PURE__ */ React13.createElement(Box12, { height: 1 }));
|
|
8833
|
-
};
|
|
8837
|
+
});
|
|
8838
|
+
MessageList.displayName = "MessageList";
|
|
8834
8839
|
}
|
|
8835
8840
|
});
|
|
8836
8841
|
|
|
@@ -10121,10 +10126,10 @@ var init_mouse = __esm({
|
|
|
10121
10126
|
import { useStdin as useStdin2 } from "ink";
|
|
10122
10127
|
import React17, {
|
|
10123
10128
|
createContext as createContext2,
|
|
10124
|
-
useCallback as
|
|
10129
|
+
useCallback as useCallback3,
|
|
10125
10130
|
useContext as useContext2,
|
|
10126
10131
|
useEffect as useEffect4,
|
|
10127
|
-
useRef as
|
|
10132
|
+
useRef as useRef5
|
|
10128
10133
|
} from "react";
|
|
10129
10134
|
function charLengthAt(str, i) {
|
|
10130
10135
|
if (str.length <= i) {
|
|
@@ -10411,16 +10416,16 @@ function KeypressProvider({
|
|
|
10411
10416
|
debugKeystrokeLogging
|
|
10412
10417
|
}) {
|
|
10413
10418
|
const { stdin, setRawMode } = useStdin2();
|
|
10414
|
-
const subscribers =
|
|
10415
|
-
const subscribe =
|
|
10419
|
+
const subscribers = useRef5(/* @__PURE__ */ new Set()).current;
|
|
10420
|
+
const subscribe = useCallback3(
|
|
10416
10421
|
(handler) => subscribers.add(handler),
|
|
10417
10422
|
[subscribers]
|
|
10418
10423
|
);
|
|
10419
|
-
const unsubscribe =
|
|
10424
|
+
const unsubscribe = useCallback3(
|
|
10420
10425
|
(handler) => subscribers.delete(handler),
|
|
10421
10426
|
[subscribers]
|
|
10422
10427
|
);
|
|
10423
|
-
const broadcast =
|
|
10428
|
+
const broadcast = useCallback3(
|
|
10424
10429
|
(key) => subscribers.forEach((handler) => handler(key)),
|
|
10425
10430
|
[subscribers]
|
|
10426
10431
|
);
|
|
@@ -11426,8 +11431,8 @@ var init_ModelSelector = __esm({
|
|
|
11426
11431
|
import path5 from "path";
|
|
11427
11432
|
import chalk4 from "chalk";
|
|
11428
11433
|
import { Box as Box21, Text as Text19 } from "ink";
|
|
11429
|
-
import React24, { forwardRef, useEffect as useEffect9, useImperativeHandle, useState as useState10 } from "react";
|
|
11430
|
-
var InputPrompt;
|
|
11434
|
+
import React24, { forwardRef, memo as memo3, useEffect as useEffect9, useImperativeHandle, useState as useState10 } from "react";
|
|
11435
|
+
var InputPromptInner, InputPrompt;
|
|
11431
11436
|
var init_InputPrompt = __esm({
|
|
11432
11437
|
"src/ui/components/InputPrompt.tsx"() {
|
|
11433
11438
|
"use strict";
|
|
@@ -11438,7 +11443,7 @@ var init_InputPrompt = __esm({
|
|
|
11438
11443
|
init_file_completion();
|
|
11439
11444
|
init_theme();
|
|
11440
11445
|
init_ModelSelector();
|
|
11441
|
-
|
|
11446
|
+
InputPromptInner = forwardRef(({
|
|
11442
11447
|
onSubmit,
|
|
11443
11448
|
placeholder = "Enter your task (press Enter to submit, Shift+Enter for new line)...",
|
|
11444
11449
|
disabled = false,
|
|
@@ -11449,7 +11454,7 @@ var init_InputPrompt = __esm({
|
|
|
11449
11454
|
onInputChange,
|
|
11450
11455
|
isClaudeMax = false
|
|
11451
11456
|
}, ref) => {
|
|
11452
|
-
const {
|
|
11457
|
+
const { agentMode, selectedModel, setSelectedModel, isAgentRunning, usageStats } = useSession();
|
|
11453
11458
|
const [value, setValue] = useState10("");
|
|
11454
11459
|
const [cursorOffset, setCursorOffset] = useState10(0);
|
|
11455
11460
|
const [allFiles, setAllFiles] = useState10([]);
|
|
@@ -11733,6 +11738,8 @@ var init_InputPrompt = __esm({
|
|
|
11733
11738
|
})), !hasContent && disabled && /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim, italic: true }, "Waiting for agent to complete...")))
|
|
11734
11739
|
), /* @__PURE__ */ React24.createElement(Box21, { justifyContent: "space-between", paddingX: 1 }, /* @__PURE__ */ React24.createElement(Box21, { gap: 2 }, /* @__PURE__ */ React24.createElement(Box21, null, /* @__PURE__ */ React24.createElement(Text19, { color: agentMode === "plan" ? theme.status.inProgress : theme.text.dim }, agentMode === "plan" ? "\u23F8 plan" : "\u25B6 build"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " (shift+tab)")), /* @__PURE__ */ React24.createElement(Box21, null, /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, "model:"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.info }, getModelDisplayName(selectedModel)), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " (Cost: "), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.info }, getModelCostLabel(selectedModel)), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, ") (shift+m)"))), /* @__PURE__ */ React24.createElement(Box21, null, /* @__PURE__ */ React24.createElement(Text19, { color: usageStats && usageStats.contextPct >= 90 ? theme.text.error : usageStats && usageStats.contextPct >= 75 ? theme.text.warning : theme.text.dim }, usageStats?.contextPct ?? 0, "% context used"), /* @__PURE__ */ React24.createElement(Text19, { color: theme.text.dim }, " ", "(", usageStats ? usageStats.inputTokens >= 1e3 ? `${(usageStats.inputTokens / 1e3).toFixed(1)}K` : usageStats.inputTokens : 0, " / ", usageStats ? usageStats.contextWindow >= 1e3 ? `${(usageStats.contextWindow / 1e3).toFixed(0)}K` : usageStats.contextWindow : "200K", ")"))));
|
|
11735
11740
|
});
|
|
11741
|
+
InputPromptInner.displayName = "InputPromptInner";
|
|
11742
|
+
InputPrompt = memo3(InputPromptInner);
|
|
11736
11743
|
InputPrompt.displayName = "InputPrompt";
|
|
11737
11744
|
}
|
|
11738
11745
|
});
|
|
@@ -12228,18 +12235,18 @@ var init_useModeToggle = __esm({
|
|
|
12228
12235
|
});
|
|
12229
12236
|
|
|
12230
12237
|
// src/ui/hooks/useOverlayEscapeGuard.ts
|
|
12231
|
-
import { useCallback as
|
|
12238
|
+
import { useCallback as useCallback4, useMemo as useMemo4, useRef as useRef6 } from "react";
|
|
12232
12239
|
var useOverlayEscapeGuard;
|
|
12233
12240
|
var init_useOverlayEscapeGuard = __esm({
|
|
12234
12241
|
"src/ui/hooks/useOverlayEscapeGuard.ts"() {
|
|
12235
12242
|
"use strict";
|
|
12236
12243
|
useOverlayEscapeGuard = ({ overlays, suppressionMs = 250 }) => {
|
|
12237
|
-
const suppressUntilRef =
|
|
12238
|
-
const markOverlayClosed =
|
|
12244
|
+
const suppressUntilRef = useRef6(0);
|
|
12245
|
+
const markOverlayClosed = useCallback4(() => {
|
|
12239
12246
|
suppressUntilRef.current = Date.now() + suppressionMs;
|
|
12240
12247
|
}, [suppressionMs]);
|
|
12241
|
-
const isCancelSuppressed =
|
|
12242
|
-
const isOverlayOpen =
|
|
12248
|
+
const isCancelSuppressed = useCallback4(() => Date.now() < suppressUntilRef.current, []);
|
|
12249
|
+
const isOverlayOpen = useMemo4(() => overlays.some(Boolean), [overlays]);
|
|
12243
12250
|
return { isOverlayOpen, isCancelSuppressed, markOverlayClosed };
|
|
12244
12251
|
};
|
|
12245
12252
|
}
|
|
@@ -12250,7 +12257,7 @@ import { execSync as execSync6 } from "child_process";
|
|
|
12250
12257
|
import { homedir as homedir8 } from "os";
|
|
12251
12258
|
import { Box as Box27, Text as Text25, useApp as useApp2, useStdout as useStdout2 } from "ink";
|
|
12252
12259
|
import Spinner4 from "ink-spinner";
|
|
12253
|
-
import React30, { useEffect as useEffect13, useRef as
|
|
12260
|
+
import React30, { useCallback as useCallback5, useEffect as useEffect13, useRef as useRef7, useState as useState16 } from "react";
|
|
12254
12261
|
var getGitBranch2, getCurrentFolder2, AppContent, App;
|
|
12255
12262
|
var init_App = __esm({
|
|
12256
12263
|
"src/ui/App.tsx"() {
|
|
@@ -12302,15 +12309,15 @@ var init_App = __esm({
|
|
|
12302
12309
|
AppContent = ({ config: config2, sessionId, webUrl, queuedTasks = [], onExit, onSubmitTask, apiClient, onResumeSession, onClearSession }) => {
|
|
12303
12310
|
const { exit } = useApp2();
|
|
12304
12311
|
const { stdout } = useStdout2();
|
|
12305
|
-
const { addMessage, clearMessages, isAgentRunning,
|
|
12312
|
+
const { addMessage, clearMessages, isAgentRunning, setSessionId, setWebUrl, setShouldInterruptAgent, setIsAgentRunning, toggleAllToolOutputs, allToolsExpanded, selectedModel, setSelectedModel, refreshStatic, toggleToolGroups, llmProvider, setLlmProvider } = useSession();
|
|
12306
12313
|
useModeToggle();
|
|
12307
12314
|
const [terminalWidth, setTerminalWidth] = useState16(process.stdout.columns || 80);
|
|
12308
12315
|
const [showInput, setShowInput] = useState16(true);
|
|
12309
12316
|
const [gitBranch] = useState16(() => getGitBranch2());
|
|
12310
12317
|
const [currentFolder] = useState16(() => getCurrentFolder2(config2.cwd));
|
|
12311
|
-
const
|
|
12318
|
+
const hasInputContentRef = useRef7(false);
|
|
12312
12319
|
const [exitWarning, setExitWarning] = useState16(null);
|
|
12313
|
-
const inputPromptRef =
|
|
12320
|
+
const inputPromptRef = useRef7(null);
|
|
12314
12321
|
const [showSessionSelector, setShowSessionSelector] = useState16(false);
|
|
12315
12322
|
const [showModelSelector, setShowModelSelector] = useState16(false);
|
|
12316
12323
|
const [showProviderSelector, setShowProviderSelector] = useState16(false);
|
|
@@ -12560,7 +12567,7 @@ var init_App = __esm({
|
|
|
12560
12567
|
setShowAuthDialog(true);
|
|
12561
12568
|
return;
|
|
12562
12569
|
}
|
|
12563
|
-
|
|
12570
|
+
hasInputContentRef.current = false;
|
|
12564
12571
|
setExitWarning(null);
|
|
12565
12572
|
if (!isAgentRunning) {
|
|
12566
12573
|
addMessage({
|
|
@@ -12573,6 +12580,9 @@ var init_App = __esm({
|
|
|
12573
12580
|
onSubmitTask(task);
|
|
12574
12581
|
}
|
|
12575
12582
|
};
|
|
12583
|
+
const handleInputChange = useCallback5((val) => {
|
|
12584
|
+
hasInputContentRef.current = val.trim().length > 0;
|
|
12585
|
+
}, []);
|
|
12576
12586
|
const handleSessionSelect = async (session) => {
|
|
12577
12587
|
setShowSessionSelector(false);
|
|
12578
12588
|
setIsLoadingSession(true);
|
|
@@ -12790,7 +12800,7 @@ var init_App = __esm({
|
|
|
12790
12800
|
markOverlayClosed();
|
|
12791
12801
|
setShowMcpServers(true);
|
|
12792
12802
|
};
|
|
12793
|
-
const isInitialMount =
|
|
12803
|
+
const isInitialMount = useRef7(true);
|
|
12794
12804
|
useEffect13(() => {
|
|
12795
12805
|
const handleResize = () => {
|
|
12796
12806
|
setTerminalWidth(process.stdout.columns || 80);
|
|
@@ -12839,8 +12849,9 @@ var init_App = __esm({
|
|
|
12839
12849
|
} else if (exitWarning) {
|
|
12840
12850
|
exit();
|
|
12841
12851
|
onExit(true);
|
|
12842
|
-
} else if (showInput &&
|
|
12852
|
+
} else if (showInput && hasInputContentRef.current) {
|
|
12843
12853
|
inputPromptRef.current?.clear();
|
|
12854
|
+
hasInputContentRef.current = false;
|
|
12844
12855
|
setExitWarning("Press Ctrl+C again to exit");
|
|
12845
12856
|
setTimeout(() => setExitWarning(null), 1500);
|
|
12846
12857
|
} else {
|
|
@@ -12953,7 +12964,7 @@ var init_App = __esm({
|
|
|
12953
12964
|
cwd: config2.cwd,
|
|
12954
12965
|
gitBranch,
|
|
12955
12966
|
isClaudeMax: !!config2.oauthToken,
|
|
12956
|
-
onInputChange:
|
|
12967
|
+
onInputChange: handleInputChange,
|
|
12957
12968
|
onSubmit: handleSubmitTask,
|
|
12958
12969
|
placeholder: "Enter your task...",
|
|
12959
12970
|
ref: inputPromptRef
|
|
@@ -12998,7 +13009,7 @@ __export(interactive_exports, {
|
|
|
12998
13009
|
runInteractive: () => runInteractive
|
|
12999
13010
|
});
|
|
13000
13011
|
import { render as render2 } from "ink";
|
|
13001
|
-
import React31, { useEffect as useEffect15, useRef as
|
|
13012
|
+
import React31, { useEffect as useEffect15, useRef as useRef8 } from "react";
|
|
13002
13013
|
function getToolDescription2(toolName, input) {
|
|
13003
13014
|
switch (toolName) {
|
|
13004
13015
|
case "Read":
|
|
@@ -13149,7 +13160,9 @@ async function runInteractive(config2) {
|
|
|
13149
13160
|
stdin: process.stdin,
|
|
13150
13161
|
alternateBuffer: false,
|
|
13151
13162
|
// Like Gemini CLI - allows terminal to handle scroll & selection
|
|
13152
|
-
exitOnCtrlC: false
|
|
13163
|
+
exitOnCtrlC: false,
|
|
13164
|
+
// Reduce flickering by using incremental updates (only changed lines, not entire screen)
|
|
13165
|
+
incrementalRendering: true
|
|
13153
13166
|
}
|
|
13154
13167
|
);
|
|
13155
13168
|
unmountFn = unmount;
|
|
@@ -13208,7 +13221,7 @@ var init_interactive = __esm({
|
|
|
13208
13221
|
selectedModel,
|
|
13209
13222
|
llmProvider
|
|
13210
13223
|
} = useSession();
|
|
13211
|
-
const agentRef =
|
|
13224
|
+
const agentRef = useRef8(null);
|
|
13212
13225
|
useEffect15(() => {
|
|
13213
13226
|
if (shouldInterruptAgent && agentRef.current) {
|
|
13214
13227
|
agentRef.current.abort();
|
|
@@ -13531,7 +13544,7 @@ init_SessionContext();
|
|
|
13531
13544
|
import { execSync as execSync2 } from "child_process";
|
|
13532
13545
|
import { homedir as homedir4 } from "os";
|
|
13533
13546
|
import { Box as Box13, useApp } from "ink";
|
|
13534
|
-
import React14, { useEffect as useEffect2, useRef as
|
|
13547
|
+
import React14, { useEffect as useEffect2, useRef as useRef4, useState as useState3 } from "react";
|
|
13535
13548
|
var getGitBranch = () => {
|
|
13536
13549
|
try {
|
|
13537
13550
|
return execSync2("git rev-parse --abbrev-ref HEAD", { encoding: "utf8" }).trim();
|
|
@@ -13557,7 +13570,7 @@ var HeadlessAgentRunner = ({ config: config2, sessionId, apiClient, onComplete }
|
|
|
13557
13570
|
setTodos,
|
|
13558
13571
|
setUsageStats
|
|
13559
13572
|
} = useSession();
|
|
13560
|
-
const agentRef =
|
|
13573
|
+
const agentRef = useRef4(null);
|
|
13561
13574
|
useEffect2(() => {
|
|
13562
13575
|
let isMounted = true;
|
|
13563
13576
|
const runAgent2 = async () => {
|
|
@@ -13645,7 +13658,7 @@ var HeadlessAppContent = ({
|
|
|
13645
13658
|
const [gitBranch] = useState3(() => getGitBranch());
|
|
13646
13659
|
const [currentFolder] = useState3(() => getCurrentFolder());
|
|
13647
13660
|
const [terminalWidth, setTerminalWidth] = useState3(process.stdout.columns || 80);
|
|
13648
|
-
const hasCompletedRef =
|
|
13661
|
+
const hasCompletedRef = useRef4(false);
|
|
13649
13662
|
useEffect2(() => {
|
|
13650
13663
|
setSessionId(sessionId);
|
|
13651
13664
|
if (webUrl) {
|
|
@@ -13813,10 +13826,22 @@ async function checkAndAutoUpdate() {
|
|
|
13813
13826
|
console.log(`
|
|
13814
13827
|
Updating Supatest CLI ${CLI_VERSION} \u2192 ${latest}...`);
|
|
13815
13828
|
try {
|
|
13816
|
-
|
|
13817
|
-
|
|
13818
|
-
|
|
13819
|
-
}
|
|
13829
|
+
try {
|
|
13830
|
+
const npmPrefix = execSync3("npm config get prefix", { encoding: "utf-8" }).trim();
|
|
13831
|
+
execSync3(`rm -rf ${npmPrefix}/lib/node_modules/@supatest/.cli-* 2>/dev/null || true`);
|
|
13832
|
+
} catch {
|
|
13833
|
+
}
|
|
13834
|
+
try {
|
|
13835
|
+
execSync3("npm update -g @supatest/cli", {
|
|
13836
|
+
stdio: "inherit",
|
|
13837
|
+
timeout: INSTALL_TIMEOUT
|
|
13838
|
+
});
|
|
13839
|
+
} catch {
|
|
13840
|
+
execSync3("npm install -g @supatest/cli@latest --force", {
|
|
13841
|
+
stdio: "inherit",
|
|
13842
|
+
timeout: INSTALL_TIMEOUT
|
|
13843
|
+
});
|
|
13844
|
+
}
|
|
13820
13845
|
console.log("\u2713 Updated successfully\n");
|
|
13821
13846
|
const child = spawn(process.argv[0], process.argv.slice(1), {
|
|
13822
13847
|
stdio: "inherit",
|