@supatest/cli 0.0.39 → 0.0.40
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 +86 -61
- 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.40";
|
|
5895
5895
|
}
|
|
5896
5896
|
});
|
|
5897
5897
|
|
|
@@ -7528,10 +7528,11 @@ var init_react = __esm({
|
|
|
7528
7528
|
|
|
7529
7529
|
// src/ui/contexts/SessionContext.tsx
|
|
7530
7530
|
import React, { createContext, useCallback, useContext, useMemo, useRef, useState } from "react";
|
|
7531
|
-
var SessionContext, SessionProvider, useSession;
|
|
7531
|
+
var UsageStatsContext, SessionContext, SessionProvider, useSession, useUsageStats;
|
|
7532
7532
|
var init_SessionContext = __esm({
|
|
7533
7533
|
"src/ui/contexts/SessionContext.tsx"() {
|
|
7534
7534
|
"use strict";
|
|
7535
|
+
UsageStatsContext = createContext(null);
|
|
7535
7536
|
SessionContext = createContext(null);
|
|
7536
7537
|
SessionProvider = ({
|
|
7537
7538
|
children,
|
|
@@ -7671,8 +7672,6 @@ var init_SessionContext = __esm({
|
|
|
7671
7672
|
setTodos,
|
|
7672
7673
|
stats,
|
|
7673
7674
|
updateStats,
|
|
7674
|
-
usageStats,
|
|
7675
|
-
setUsageStats,
|
|
7676
7675
|
isAgentRunning,
|
|
7677
7676
|
setIsAgentRunning,
|
|
7678
7677
|
shouldInterruptAgent,
|
|
@@ -7706,7 +7705,6 @@ var init_SessionContext = __esm({
|
|
|
7706
7705
|
todos,
|
|
7707
7706
|
stats,
|
|
7708
7707
|
updateStats,
|
|
7709
|
-
usageStats,
|
|
7710
7708
|
isAgentRunning,
|
|
7711
7709
|
shouldInterruptAgent,
|
|
7712
7710
|
sessionId,
|
|
@@ -7718,7 +7716,11 @@ var init_SessionContext = __esm({
|
|
|
7718
7716
|
staticRemountKey,
|
|
7719
7717
|
refreshStatic
|
|
7720
7718
|
]);
|
|
7721
|
-
|
|
7719
|
+
const usageStatsValue = useMemo(() => ({
|
|
7720
|
+
usageStats,
|
|
7721
|
+
setUsageStats
|
|
7722
|
+
}), [usageStats]);
|
|
7723
|
+
return /* @__PURE__ */ React.createElement(SessionContext.Provider, { value }, /* @__PURE__ */ React.createElement(UsageStatsContext.Provider, { value: usageStatsValue }, children));
|
|
7722
7724
|
};
|
|
7723
7725
|
useSession = () => {
|
|
7724
7726
|
const context = useContext(SessionContext);
|
|
@@ -7727,6 +7729,13 @@ var init_SessionContext = __esm({
|
|
|
7727
7729
|
}
|
|
7728
7730
|
return context;
|
|
7729
7731
|
};
|
|
7732
|
+
useUsageStats = () => {
|
|
7733
|
+
const context = useContext(UsageStatsContext);
|
|
7734
|
+
if (!context) {
|
|
7735
|
+
throw new Error("useUsageStats must be used within SessionProvider");
|
|
7736
|
+
}
|
|
7737
|
+
return context;
|
|
7738
|
+
};
|
|
7730
7739
|
}
|
|
7731
7740
|
});
|
|
7732
7741
|
|
|
@@ -8621,8 +8630,8 @@ var init_QueuedMessageDisplay = __esm({
|
|
|
8621
8630
|
|
|
8622
8631
|
// src/ui/components/MessageList.tsx
|
|
8623
8632
|
import { Box as Box12, Static } from "ink";
|
|
8624
|
-
import React13, { memo as memo2, useCallback as useCallback2, useMemo as useMemo3
|
|
8625
|
-
var MessageList;
|
|
8633
|
+
import React13, { memo as memo2, useCallback as useCallback2, useMemo as useMemo3 } from "react";
|
|
8634
|
+
var StaticHeader, MessageList;
|
|
8626
8635
|
var init_MessageList = __esm({
|
|
8627
8636
|
"src/ui/components/MessageList.tsx"() {
|
|
8628
8637
|
"use strict";
|
|
@@ -8637,6 +8646,11 @@ var init_MessageList = __esm({
|
|
|
8637
8646
|
init_ToolMessage();
|
|
8638
8647
|
init_UserMessage();
|
|
8639
8648
|
init_QueuedMessageDisplay();
|
|
8649
|
+
StaticHeader = memo2(({ currentFolder, gitBranch, headless, staticRemountKey }) => {
|
|
8650
|
+
const headerItems = useMemo3(() => [{ id: "header" }], []);
|
|
8651
|
+
return /* @__PURE__ */ React13.createElement(Static, { items: headerItems, key: `header-${staticRemountKey}` }, () => /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column", key: "header" }, /* @__PURE__ */ React13.createElement(Header, { currentFolder, gitBranch, headless })));
|
|
8652
|
+
});
|
|
8653
|
+
StaticHeader.displayName = "StaticHeader";
|
|
8640
8654
|
MessageList = memo2(({ terminalWidth, currentFolder, gitBranch, headless = false, queuedTasks = [] }) => {
|
|
8641
8655
|
const { messages, updateMessageById, isAgentRunning, staticRemountKey, toolGroupsExpanded, toggleToolGroups } = useSession();
|
|
8642
8656
|
const handleToggle = useCallback2((id, currentExpanded) => {
|
|
@@ -8738,31 +8752,29 @@ var init_MessageList = __esm({
|
|
|
8738
8752
|
}
|
|
8739
8753
|
return renderMessage(group.messages[0]);
|
|
8740
8754
|
}, [toolGroupsExpanded, toggleToolGroups, handleToggle, renderMessage]);
|
|
8741
|
-
const lastUserMessageIndex = useMemo3(() => {
|
|
8742
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8743
|
-
if (messages[i].type === "user") {
|
|
8744
|
-
return i;
|
|
8745
|
-
}
|
|
8746
|
-
}
|
|
8747
|
-
return -1;
|
|
8748
|
-
}, [messages]);
|
|
8749
8755
|
const hasPendingAssistant = useMemo3(
|
|
8750
8756
|
() => messages.some((m) => m.type === "assistant" && m.isPending),
|
|
8751
8757
|
[messages]
|
|
8752
8758
|
);
|
|
8753
|
-
const completedBoundaryRef = useRef3(-1);
|
|
8754
|
-
const completedBoundaryKey = useMemo3(() => {
|
|
8755
|
-
const currentBoundary = lastUserMessageIndex;
|
|
8756
|
-
if (currentBoundary !== completedBoundaryRef.current) {
|
|
8757
|
-
completedBoundaryRef.current = currentBoundary;
|
|
8758
|
-
return `boundary-${currentBoundary}`;
|
|
8759
|
-
}
|
|
8760
|
-
return `boundary-${completedBoundaryRef.current}`;
|
|
8761
|
-
}, [lastUserMessageIndex]);
|
|
8762
8759
|
const { completedGroups, currentTurnGroups } = useMemo3(() => {
|
|
8763
8760
|
const completed = [];
|
|
8764
8761
|
const currentTurn = [];
|
|
8765
|
-
const
|
|
8762
|
+
const isMessageComplete = (msg) => {
|
|
8763
|
+
switch (msg.type) {
|
|
8764
|
+
case "user":
|
|
8765
|
+
case "error":
|
|
8766
|
+
case "todo":
|
|
8767
|
+
case "thinking":
|
|
8768
|
+
return true;
|
|
8769
|
+
case "tool":
|
|
8770
|
+
return msg.toolResult !== void 0;
|
|
8771
|
+
case "assistant":
|
|
8772
|
+
return !msg.isPending;
|
|
8773
|
+
default:
|
|
8774
|
+
return true;
|
|
8775
|
+
}
|
|
8776
|
+
};
|
|
8777
|
+
const processTurn = (turnMessages, targetArray) => {
|
|
8766
8778
|
let currentToolGroup = [];
|
|
8767
8779
|
const flushToolGroup = () => {
|
|
8768
8780
|
if (currentToolGroup.length === 0) return;
|
|
@@ -8773,7 +8785,7 @@ var init_MessageList = __esm({
|
|
|
8773
8785
|
}
|
|
8774
8786
|
currentToolGroup = [];
|
|
8775
8787
|
};
|
|
8776
|
-
for (const msg of
|
|
8788
|
+
for (const msg of turnMessages) {
|
|
8777
8789
|
if (msg.type === "tool") {
|
|
8778
8790
|
currentToolGroup.push(msg);
|
|
8779
8791
|
} else {
|
|
@@ -8783,38 +8795,46 @@ var init_MessageList = __esm({
|
|
|
8783
8795
|
}
|
|
8784
8796
|
flushToolGroup();
|
|
8785
8797
|
};
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
if (msg
|
|
8790
|
-
|
|
8791
|
-
turnMessages = [];
|
|
8792
|
-
completed.push({ type: "single", messages: [msg] });
|
|
8798
|
+
const completeMessages = [];
|
|
8799
|
+
const inProgressMessages = [];
|
|
8800
|
+
for (const msg of messages) {
|
|
8801
|
+
if (isMessageComplete(msg)) {
|
|
8802
|
+
completeMessages.push(msg);
|
|
8793
8803
|
} else {
|
|
8794
|
-
|
|
8804
|
+
inProgressMessages.push(msg);
|
|
8795
8805
|
}
|
|
8796
8806
|
}
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8807
|
+
let splitIndex = messages.length;
|
|
8808
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
8809
|
+
if (isMessageComplete(messages[i])) {
|
|
8810
|
+
splitIndex = i + 1;
|
|
8811
|
+
break;
|
|
8812
|
+
}
|
|
8800
8813
|
}
|
|
8801
|
-
const
|
|
8802
|
-
|
|
8814
|
+
const finalCompleteMessages = messages.slice(0, splitIndex);
|
|
8815
|
+
const finalInProgressMessages = messages.slice(splitIndex);
|
|
8816
|
+
processTurn(finalCompleteMessages, completed);
|
|
8817
|
+
processTurn(finalInProgressMessages, currentTurn);
|
|
8803
8818
|
return { completedGroups: completed, currentTurnGroups: currentTurn };
|
|
8804
|
-
}, [messages
|
|
8805
|
-
const staticItems = useMemo3(
|
|
8806
|
-
|
|
8807
|
-
...completedGroups.map((group, idx) => {
|
|
8819
|
+
}, [messages]);
|
|
8820
|
+
const staticItems = useMemo3(
|
|
8821
|
+
() => completedGroups.map((group, idx) => {
|
|
8808
8822
|
if (group.type === "group") {
|
|
8809
|
-
return { ...group, _isGroup: true, id: `group-${idx}` };
|
|
8823
|
+
return { ...group, _isGroup: true, id: `group-${group.messages[0]?.id || idx}` };
|
|
8810
8824
|
}
|
|
8811
8825
|
return { ...group.messages[0], _isMessage: true };
|
|
8812
|
-
})
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8826
|
+
}),
|
|
8827
|
+
[completedGroups]
|
|
8828
|
+
);
|
|
8829
|
+
return /* @__PURE__ */ React13.createElement(Box12, { flexDirection: "column" }, /* @__PURE__ */ React13.createElement(
|
|
8830
|
+
StaticHeader,
|
|
8831
|
+
{
|
|
8832
|
+
currentFolder,
|
|
8833
|
+
gitBranch,
|
|
8834
|
+
headless,
|
|
8835
|
+
staticRemountKey
|
|
8817
8836
|
}
|
|
8837
|
+
), staticItems.length > 0 && /* @__PURE__ */ React13.createElement(Static, { items: staticItems, key: `messages-${staticRemountKey}-${toolGroupsExpanded}` }, (item) => {
|
|
8818
8838
|
if (item._isGroup) {
|
|
8819
8839
|
const content2 = renderGroupedMessage(item);
|
|
8820
8840
|
if (!content2) {
|
|
@@ -11042,7 +11062,8 @@ var init_TestSelector = __esm({
|
|
|
11042
11062
|
// Only fetch failed tests
|
|
11043
11063
|
});
|
|
11044
11064
|
setTotalTests(result.total);
|
|
11045
|
-
|
|
11065
|
+
const loadedCount = allTests.length + result.tests.length;
|
|
11066
|
+
setHasMore(result.tests.length === PAGE_SIZE2 && loadedCount < result.total);
|
|
11046
11067
|
setAllTests((prev) => [...prev, ...result.tests]);
|
|
11047
11068
|
} catch (err) {
|
|
11048
11069
|
setError(err instanceof Error ? err.message : String(err));
|
|
@@ -11154,7 +11175,7 @@ var init_TestSelector = __esm({
|
|
|
11154
11175
|
const indicator = isSelected ? "\u25B6 " : " ";
|
|
11155
11176
|
const bgColor = isSelected ? theme.text.accent : void 0;
|
|
11156
11177
|
return /* @__PURE__ */ React21.createElement(Box18, { key: test.id, marginBottom: 0 }, /* @__PURE__ */ React21.createElement(Text16, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "black" : theme.text.primary }, indicator), /* @__PURE__ */ React21.createElement(Text16, { backgroundColor: bgColor, color: isChecked ? "green" : isSelected ? "black" : theme.text.dim }, checkbox), /* @__PURE__ */ React21.createElement(Text16, null, " "), /* @__PURE__ */ React21.createElement(Text16, { backgroundColor: bgColor, bold: isSelected, color: isSelected ? "black" : theme.text.primary }, file, line && /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? "black" : theme.text.dim }, ":", line), /* @__PURE__ */ React21.createElement(Text16, { color: isSelected ? "black" : theme.text.dim }, " - "), title));
|
|
11157
|
-
})), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginTop: 1 }, allTests.length > VISIBLE_ITEMS2 && /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "yellow" }, "Showing ", adjustedStart + 1, "-", adjustedEnd, " of ",
|
|
11178
|
+
})), /* @__PURE__ */ React21.createElement(Box18, { flexDirection: "column", marginTop: 1 }, allTests.length > VISIBLE_ITEMS2 && /* @__PURE__ */ React21.createElement(Box18, { marginBottom: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "yellow" }, "Showing ", adjustedStart + 1, "-", adjustedEnd, " of ", allTests.length, " failed tests", hasMore && !isLoading && /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, " (scroll for more)"))), /* @__PURE__ */ React21.createElement(Box18, null, /* @__PURE__ */ React21.createElement(Text16, { color: theme.text.dim }, /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "\u2191\u2193"), " navigate \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "Space"), " toggle \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "a"), " all \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "n"), " none \u2022 ", /* @__PURE__ */ React21.createElement(Text16, { bold: true }, "Enter"), " fix selected")), selectedTests.size > 0 && /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "green" }, selectedTests.size, " test", selectedTests.size !== 1 ? "s" : "", " selected")), isLoading && /* @__PURE__ */ React21.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React21.createElement(Text16, { color: "cyan" }, "Loading more tests..."))));
|
|
11158
11179
|
};
|
|
11159
11180
|
}
|
|
11160
11181
|
});
|
|
@@ -11454,7 +11475,8 @@ var init_InputPrompt = __esm({
|
|
|
11454
11475
|
onInputChange,
|
|
11455
11476
|
isClaudeMax = false
|
|
11456
11477
|
}, ref) => {
|
|
11457
|
-
const { agentMode, selectedModel, setSelectedModel, isAgentRunning
|
|
11478
|
+
const { agentMode, selectedModel, setSelectedModel, isAgentRunning } = useSession();
|
|
11479
|
+
const { usageStats } = useUsageStats();
|
|
11458
11480
|
const [value, setValue] = useState10("");
|
|
11459
11481
|
const [cursorOffset, setCursorOffset] = useState10(0);
|
|
11460
11482
|
const [allFiles, setAllFiles] = useState10([]);
|
|
@@ -13158,11 +13180,14 @@ async function runInteractive(config2) {
|
|
|
13158
13180
|
stdout: inkStdout,
|
|
13159
13181
|
stderr: inkStderr,
|
|
13160
13182
|
stdin: process.stdin,
|
|
13183
|
+
// Keep alternateBuffer: false for native terminal scrollback and text selection
|
|
13161
13184
|
alternateBuffer: false,
|
|
13162
|
-
// Like Gemini CLI - allows terminal to handle scroll & selection
|
|
13163
13185
|
exitOnCtrlC: false,
|
|
13164
|
-
//
|
|
13165
|
-
|
|
13186
|
+
// Disable incrementalRendering - it doesn't work well without alternateBuffer
|
|
13187
|
+
// and can cause more flickering issues
|
|
13188
|
+
incrementalRendering: false,
|
|
13189
|
+
// Prevent Ink from patching console methods
|
|
13190
|
+
patchConsole: false
|
|
13166
13191
|
}
|
|
13167
13192
|
);
|
|
13168
13193
|
unmountFn = unmount;
|
|
@@ -13212,7 +13237,6 @@ var init_interactive = __esm({
|
|
|
13212
13237
|
setIsAgentRunning,
|
|
13213
13238
|
updateStats,
|
|
13214
13239
|
setTodos,
|
|
13215
|
-
setUsageStats,
|
|
13216
13240
|
shouldInterruptAgent,
|
|
13217
13241
|
setShouldInterruptAgent,
|
|
13218
13242
|
agentMode,
|
|
@@ -13221,6 +13245,7 @@ var init_interactive = __esm({
|
|
|
13221
13245
|
selectedModel,
|
|
13222
13246
|
llmProvider
|
|
13223
13247
|
} = useSession();
|
|
13248
|
+
const { setUsageStats } = useUsageStats();
|
|
13224
13249
|
const agentRef = useRef8(null);
|
|
13225
13250
|
useEffect15(() => {
|
|
13226
13251
|
if (shouldInterruptAgent && agentRef.current) {
|
|
@@ -13333,9 +13358,9 @@ var init_interactive = __esm({
|
|
|
13333
13358
|
addMessage,
|
|
13334
13359
|
loadMessages,
|
|
13335
13360
|
setSessionId: setContextSessionId,
|
|
13336
|
-
setIsAgentRunning
|
|
13337
|
-
setUsageStats
|
|
13361
|
+
setIsAgentRunning
|
|
13338
13362
|
} = useSession();
|
|
13363
|
+
const { setUsageStats } = useUsageStats();
|
|
13339
13364
|
const [sessionId, setSessionId] = React31.useState(initialSessionId);
|
|
13340
13365
|
const [currentTask, setCurrentTask] = React31.useState(config2.task);
|
|
13341
13366
|
const [taskId, setTaskId] = React31.useState(0);
|
|
@@ -13567,9 +13592,9 @@ var HeadlessAgentRunner = ({ config: config2, sessionId, apiClient, onComplete }
|
|
|
13567
13592
|
updateMessageByToolId,
|
|
13568
13593
|
setIsAgentRunning,
|
|
13569
13594
|
updateStats,
|
|
13570
|
-
setTodos
|
|
13571
|
-
setUsageStats
|
|
13595
|
+
setTodos
|
|
13572
13596
|
} = useSession();
|
|
13597
|
+
const { setUsageStats } = useUsageStats();
|
|
13573
13598
|
const agentRef = useRef4(null);
|
|
13574
13599
|
useEffect2(() => {
|
|
13575
13600
|
let isMounted = true;
|