@ganakailabs/cloudeval-cli 0.19.2 → 0.19.4
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/README.md +24 -3
- package/dist/{App-2MBFLELV.js → App-AQAMCM4E.js} +1570 -512
- package/dist/{Banner-3J56KE23.js → Banner-64DOS5YB.js} +3 -3
- package/dist/Onboarding-3NZCPBCO.js +8 -0
- package/dist/{ReportDashboard-6JFJJVRW.js → ReportDashboard-T63UGA7M.js} +1 -1
- package/dist/{chunk-4QIKW5TJ.js → chunk-2D4BE3OS.js} +68 -7
- package/dist/{chunk-3DVPEIVB.js → chunk-2GTSKMHA.js} +2 -2
- package/dist/{chunk-2O7XF47R.js → chunk-HUE4D6RO.js} +1 -1
- package/dist/{chunk-UXX36KJO.js → chunk-L2H4P4BP.js} +2 -2
- package/dist/{chunk-UOCT7M4J.js → chunk-QKZCKI55.js} +8 -6
- package/dist/chunk-RCRNSEQS.js +1014 -0
- package/dist/cli.js +872 -1024
- package/dist/{dist-I4IPYCRC.js → dist-TBAQ5KOK.js} +7 -1
- package/package.json +3 -3
- package/sbom.spdx.json +1 -1
- package/dist/Onboarding-HVCYIPTL.js +0 -8
- package/dist/chunk-TA4WC462.js +0 -174
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildFrontendUrl,
|
|
3
3
|
getFirstNameForDisplay,
|
|
4
|
+
getSession,
|
|
5
|
+
listSessions,
|
|
6
|
+
recordSessionTurn,
|
|
4
7
|
resolveFrontendBaseUrl
|
|
5
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-RCRNSEQS.js";
|
|
6
9
|
import {
|
|
7
10
|
Onboarding
|
|
8
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-2GTSKMHA.js";
|
|
9
12
|
import {
|
|
10
13
|
checkUserStatus,
|
|
11
14
|
completeActiveAssistantMessage,
|
|
@@ -14,8 +17,11 @@ import {
|
|
|
14
17
|
getAuthToken,
|
|
15
18
|
getBillingEntitlement,
|
|
16
19
|
getBillingNotifications,
|
|
20
|
+
getBillingUsageCreditsUsed,
|
|
17
21
|
getBillingUsageLedger,
|
|
18
22
|
getBillingUsageSummary,
|
|
23
|
+
getBundledAgentProfiles,
|
|
24
|
+
getCLIHeaders,
|
|
19
25
|
getCostReportFull,
|
|
20
26
|
getCreditStatus,
|
|
21
27
|
getProjects,
|
|
@@ -23,28 +29,29 @@ import {
|
|
|
23
29
|
getTopUpPacks,
|
|
24
30
|
getWafReportFull,
|
|
25
31
|
initialChatState,
|
|
32
|
+
isExpiredDeviceTokenStreamError,
|
|
26
33
|
listConnections,
|
|
27
34
|
normalizeApiBase,
|
|
28
35
|
reduceChunk,
|
|
29
36
|
runReports,
|
|
30
37
|
streamChat
|
|
31
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-2D4BE3OS.js";
|
|
32
39
|
import {
|
|
33
40
|
Banner
|
|
34
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-L2H4P4BP.js";
|
|
35
42
|
import {
|
|
36
43
|
CLI_VERSION
|
|
37
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-HUE4D6RO.js";
|
|
38
45
|
import {
|
|
39
46
|
raisedButtonStyle,
|
|
40
47
|
terminalTheme
|
|
41
|
-
} from "./chunk-
|
|
48
|
+
} from "./chunk-QKZCKI55.js";
|
|
42
49
|
|
|
43
50
|
// src/ui/App.tsx
|
|
44
51
|
import React8, { useEffect as useEffect4, useMemo, useState as useState4, startTransition } from "react";
|
|
45
52
|
import { Box as Box9, Text as Text10, useApp, useInput as useInput4 } from "ink";
|
|
46
53
|
import { ScrollView } from "ink-scroll-view";
|
|
47
|
-
import { randomUUID } from "crypto";
|
|
54
|
+
import { randomUUID as randomUUID2 } from "crypto";
|
|
48
55
|
import { spawn } from "child_process";
|
|
49
56
|
import { mkdirSync, writeFileSync } from "fs";
|
|
50
57
|
import { join, resolve } from "path";
|
|
@@ -594,7 +601,7 @@ var getTuiKeyBindings = (platform = process.platform) => ({
|
|
|
594
601
|
newline: platform === "darwin" ? "Option+Enter or Ctrl+J newline" : "Alt+Enter or Ctrl+J newline",
|
|
595
602
|
quit: "Ctrl+C quit",
|
|
596
603
|
tabFocus: "Tab focus",
|
|
597
|
-
tabSwitch: "
|
|
604
|
+
tabSwitch: "Arrow keys move focus",
|
|
598
605
|
commandComplete: "Tab completes slash commands",
|
|
599
606
|
historySearch: "Ctrl+R history search",
|
|
600
607
|
cancel: "Esc cancel response",
|
|
@@ -605,15 +612,19 @@ var getTuiKeyBindings = (platform = process.platform) => ({
|
|
|
605
612
|
});
|
|
606
613
|
var getChatInputHelpText = ({
|
|
607
614
|
isCancelling,
|
|
615
|
+
inputActive = true,
|
|
608
616
|
promptCount = 0
|
|
609
617
|
}) => {
|
|
610
618
|
if (isCancelling) {
|
|
611
619
|
return "Esc stop | Ctrl+C quit | /stop | /help";
|
|
612
620
|
}
|
|
621
|
+
if (!inputActive) {
|
|
622
|
+
return "Type to edit | Tab/Arrows controls | 1-8 tabs | /help";
|
|
623
|
+
}
|
|
613
624
|
if (promptCount <= 0) {
|
|
614
|
-
return "Enter send | Ctrl+J newline |
|
|
625
|
+
return "Enter send | Esc controls | Ctrl+J newline | /starter | /help";
|
|
615
626
|
}
|
|
616
|
-
return "Enter send |
|
|
627
|
+
return "Enter send/choose | Esc controls | Tab focus | 1-8 tabs | /help";
|
|
617
628
|
};
|
|
618
629
|
|
|
619
630
|
// src/ui/workspaceTabs.ts
|
|
@@ -692,8 +703,35 @@ var workspaceTabFromPosition = (column, row, areas) => areas.find(
|
|
|
692
703
|
import { Fragment, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
693
704
|
var shouldAnimateInputCursor = ({
|
|
694
705
|
disabled,
|
|
706
|
+
inputActive = true,
|
|
695
707
|
blinkCursor = false
|
|
696
|
-
}) => !disabled && blinkCursor;
|
|
708
|
+
}) => !disabled && inputActive && blinkCursor;
|
|
709
|
+
var shouldBlinkPromptCursor = ({
|
|
710
|
+
animationsEnabled,
|
|
711
|
+
inputActive = true,
|
|
712
|
+
busy = false,
|
|
713
|
+
selectorOpen = false,
|
|
714
|
+
searching = false
|
|
715
|
+
}) => Boolean(animationsEnabled && inputActive && busy && !selectorOpen && !searching);
|
|
716
|
+
var getInputCursorColor = ({
|
|
717
|
+
disabled,
|
|
718
|
+
inputActive = true,
|
|
719
|
+
cursorVisible = true
|
|
720
|
+
}) => {
|
|
721
|
+
if (disabled || !inputActive) {
|
|
722
|
+
return terminalTheme.muted;
|
|
723
|
+
}
|
|
724
|
+
return cursorVisible ? terminalTheme.cursor : terminalTheme.accent;
|
|
725
|
+
};
|
|
726
|
+
var getInputCursorGlyph = ({
|
|
727
|
+
inputActive = true,
|
|
728
|
+
cursorVisible = true
|
|
729
|
+
}) => {
|
|
730
|
+
if (!inputActive) {
|
|
731
|
+
return " ";
|
|
732
|
+
}
|
|
733
|
+
return cursorVisible ? "\u258C" : "\u258F";
|
|
734
|
+
};
|
|
697
735
|
var Scrollbar = ({
|
|
698
736
|
totalRows,
|
|
699
737
|
visibleRows,
|
|
@@ -707,7 +745,7 @@ var Scrollbar = ({
|
|
|
707
745
|
visibleRows - 1,
|
|
708
746
|
Math.max(0, Math.round(startRow / maxStart * (visibleRows - 1)))
|
|
709
747
|
);
|
|
710
|
-
return /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", marginLeft: 1, children: Array.from({ length: visibleRows }, (_, index) => /* @__PURE__ */ jsx5(Text5, { color: index === thumbIndex ? terminalTheme.
|
|
748
|
+
return /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", marginLeft: 1, children: Array.from({ length: visibleRows }, (_, index) => /* @__PURE__ */ jsx5(Text5, { color: index === thumbIndex ? terminalTheme.focus : terminalTheme.muted, children: index === thumbIndex ? "\u2503" : "\u2502" }, index)) });
|
|
711
749
|
};
|
|
712
750
|
var truncateInline = (value, maxLength) => {
|
|
713
751
|
if (value.length <= maxLength) {
|
|
@@ -796,10 +834,13 @@ var getFollowUpRowViewport = ({
|
|
|
796
834
|
};
|
|
797
835
|
};
|
|
798
836
|
var InputBox = ({
|
|
837
|
+
title = "Prompt",
|
|
799
838
|
value,
|
|
800
839
|
onChange,
|
|
801
840
|
onSubmit,
|
|
802
841
|
disabled = false,
|
|
842
|
+
inputActive = true,
|
|
843
|
+
onBlurRequest,
|
|
803
844
|
placeholder = "Ask Cloudeval...",
|
|
804
845
|
followUps = [],
|
|
805
846
|
followUpsLabel = "Follow-ups",
|
|
@@ -810,9 +851,7 @@ var InputBox = ({
|
|
|
810
851
|
helpText,
|
|
811
852
|
actionLabel,
|
|
812
853
|
actionHint,
|
|
813
|
-
actionTone,
|
|
814
854
|
onAction,
|
|
815
|
-
actionDisabled = false,
|
|
816
855
|
minInputRows = DEFAULT_INPUT_MIN_ROWS,
|
|
817
856
|
maxInputRows = DEFAULT_INPUT_MAX_ROWS,
|
|
818
857
|
scrollOffset,
|
|
@@ -825,17 +864,12 @@ var InputBox = ({
|
|
|
825
864
|
const compact = terminalColumns < 78;
|
|
826
865
|
const defaultHelpText = `${keyBindings.submit} | ${keyBindings.newline} | ${keyBindings.quit}`;
|
|
827
866
|
const resolvedHelpText = helpText ?? defaultHelpText;
|
|
828
|
-
const showHeaderRow = followUps.length > 0 || resolvedHelpText.length > 0;
|
|
829
867
|
const followUpViewport = getFollowUpRowViewport({
|
|
830
868
|
followUps,
|
|
831
869
|
focusedFollowUpIndex,
|
|
832
870
|
terminalColumns
|
|
833
871
|
});
|
|
834
|
-
const
|
|
835
|
-
const inputWidth = Math.max(
|
|
836
|
-
20,
|
|
837
|
-
terminalColumns - 14 - (compact ? 0 : actionButtonWidth)
|
|
838
|
-
);
|
|
872
|
+
const inputWidth = Math.max(20, terminalColumns - 8);
|
|
839
873
|
const inputViewport = getInputViewport({
|
|
840
874
|
value,
|
|
841
875
|
width: inputWidth,
|
|
@@ -848,13 +882,13 @@ var InputBox = ({
|
|
|
848
882
|
const startRow = inputViewport.startRow;
|
|
849
883
|
const visibleRows = inputViewport.visibleRows;
|
|
850
884
|
useEffect2(() => {
|
|
851
|
-
if (!shouldAnimateInputCursor({ disabled, blinkCursor })) {
|
|
885
|
+
if (!shouldAnimateInputCursor({ disabled, inputActive, blinkCursor })) {
|
|
852
886
|
setCursorVisible(true);
|
|
853
887
|
return;
|
|
854
888
|
}
|
|
855
889
|
const timer = setInterval(() => setCursorVisible((current) => !current), 520);
|
|
856
890
|
return () => clearInterval(timer);
|
|
857
|
-
}, [blinkCursor, disabled, value]);
|
|
891
|
+
}, [blinkCursor, disabled, inputActive, value]);
|
|
858
892
|
const handleChange = (nextValue) => {
|
|
859
893
|
const cleanedValue = sanitizeTerminalMultilineInput(nextValue);
|
|
860
894
|
const shortcutTab = onTabShortcut ? workspaceTabFromPromptChange(value, cleanedValue) : void 0;
|
|
@@ -900,6 +934,10 @@ var InputBox = ({
|
|
|
900
934
|
onAction();
|
|
901
935
|
return;
|
|
902
936
|
}
|
|
937
|
+
if (key.escape) {
|
|
938
|
+
onBlurRequest?.();
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
903
941
|
if (key.backspace || key.delete) {
|
|
904
942
|
handleChange(value.slice(0, -1));
|
|
905
943
|
return;
|
|
@@ -909,41 +947,35 @@ var InputBox = ({
|
|
|
909
947
|
}
|
|
910
948
|
insertText(input);
|
|
911
949
|
},
|
|
912
|
-
{ isActive: !disabled }
|
|
950
|
+
{ isActive: !disabled && inputActive }
|
|
913
951
|
);
|
|
952
|
+
const cursorGlyph = getInputCursorGlyph({ inputActive, cursorVisible });
|
|
953
|
+
const cursorColor = getInputCursorColor({ disabled, inputActive, cursorVisible });
|
|
954
|
+
const inputBorderColor = disabled ? terminalTheme.muted : followUpsActive || inputActive ? terminalTheme.focus : terminalTheme.muted;
|
|
914
955
|
return /* @__PURE__ */ jsxs4(
|
|
915
956
|
TitledBox,
|
|
916
957
|
{
|
|
917
|
-
title
|
|
958
|
+
title,
|
|
918
959
|
borderStyle: "round",
|
|
919
|
-
borderColor:
|
|
920
|
-
padding:
|
|
960
|
+
borderColor: inputBorderColor,
|
|
961
|
+
padding: 0,
|
|
962
|
+
paddingX: 1,
|
|
921
963
|
children: [
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
{
|
|
925
|
-
flexDirection: compact ? "column" : "row",
|
|
926
|
-
justifyContent: "space-between",
|
|
927
|
-
columnGap: 1,
|
|
928
|
-
children: [
|
|
929
|
-
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: followUps.length ? followUpsLabel : "" }),
|
|
930
|
-
resolvedHelpText ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, wrap: "truncate", children: resolvedHelpText }) : null
|
|
931
|
-
]
|
|
932
|
-
}
|
|
933
|
-
) : null,
|
|
934
|
-
followUps.length ? /* @__PURE__ */ jsxs4(Box4, { flexDirection: "row", columnGap: 1, marginTop: compact ? 1 : 0, children: [
|
|
935
|
-
followUpViewport.clippedStart ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "<--" }) : null,
|
|
964
|
+
followUps.length ? /* @__PURE__ */ jsxs4(Text5, { wrap: "truncate", children: [
|
|
965
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: `${followUpsLabel}: ` }),
|
|
966
|
+
followUpViewport.clippedStart ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "<-- " }) : null,
|
|
936
967
|
followUpViewport.items.map(({ question, index, label }) => {
|
|
937
968
|
const focused = followUpsActive && focusedFollowUpIndex === index;
|
|
938
969
|
return /* @__PURE__ */ jsxs4(
|
|
939
970
|
Text5,
|
|
940
971
|
{
|
|
941
|
-
color: focused ? terminalTheme.
|
|
972
|
+
color: focused ? terminalTheme.focus : void 0,
|
|
942
973
|
bold: focused,
|
|
943
974
|
children: [
|
|
944
975
|
focused ? raisedButtonStyle.activeMarker : raisedButtonStyle.inactiveMarker,
|
|
945
976
|
" ",
|
|
946
|
-
label
|
|
977
|
+
label,
|
|
978
|
+
" "
|
|
947
979
|
]
|
|
948
980
|
},
|
|
949
981
|
`${index}-${question}`
|
|
@@ -952,20 +984,13 @@ var InputBox = ({
|
|
|
952
984
|
followUpViewport.clippedEnd ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, children: "-->" }) : null
|
|
953
985
|
] }) : null,
|
|
954
986
|
/* @__PURE__ */ jsxs4(
|
|
955
|
-
|
|
987
|
+
Box4,
|
|
956
988
|
{
|
|
957
|
-
title: "Input",
|
|
958
989
|
flexDirection: compact ? "column" : "row",
|
|
959
|
-
borderStyle: "single",
|
|
960
|
-
borderColor: disabled ? terminalTheme.muted : terminalTheme.brand,
|
|
961
|
-
padding: 0,
|
|
962
|
-
paddingX: 1,
|
|
963
|
-
marginTop: 1,
|
|
964
990
|
children: [
|
|
965
|
-
/* @__PURE__ */ jsx5(Box4, { flexDirection: "column", flexGrow: 1, children: !value ? /* @__PURE__ */ jsxs4(Text5, {
|
|
966
|
-
/* @__PURE__ */ jsx5(Text5, { color:
|
|
967
|
-
|
|
968
|
-
placeholder
|
|
991
|
+
/* @__PURE__ */ jsx5(Box4, { flexDirection: "column", flexGrow: 1, children: !value ? /* @__PURE__ */ jsxs4(Text5, { wrap: "truncate", children: [
|
|
992
|
+
/* @__PURE__ */ jsx5(Text5, { color: cursorColor, children: cursorGlyph }),
|
|
993
|
+
/* @__PURE__ */ jsx5(Text5, { dimColor: true, children: ` ${placeholder}` })
|
|
969
994
|
] }) : visibleRows.map((line, index) => {
|
|
970
995
|
const isLastValueRow = startRow + index === inputRows.length - 1;
|
|
971
996
|
return /* @__PURE__ */ jsxs4(Text5, { wrap: "truncate", children: [
|
|
@@ -980,7 +1005,7 @@ var InputBox = ({
|
|
|
980
1005
|
children: ghostText ?? ""
|
|
981
1006
|
}
|
|
982
1007
|
),
|
|
983
|
-
/* @__PURE__ */ jsx5(Text5, { color:
|
|
1008
|
+
/* @__PURE__ */ jsx5(Text5, { color: cursorColor, children: cursorGlyph })
|
|
984
1009
|
] }) : null
|
|
985
1010
|
] }, `${startRow}-${index}`);
|
|
986
1011
|
}) }),
|
|
@@ -991,36 +1016,11 @@ var InputBox = ({
|
|
|
991
1016
|
visibleRows: visibleRowCount,
|
|
992
1017
|
startRow
|
|
993
1018
|
}
|
|
994
|
-
)
|
|
995
|
-
actionLabel ? /* @__PURE__ */ jsx5(
|
|
996
|
-
Box4,
|
|
997
|
-
{
|
|
998
|
-
marginLeft: compact ? 0 : 1,
|
|
999
|
-
marginTop: compact ? 1 : 0,
|
|
1000
|
-
justifyContent: compact ? "flex-end" : "center",
|
|
1001
|
-
flexDirection: "row",
|
|
1002
|
-
children: /* @__PURE__ */ jsx5(
|
|
1003
|
-
Box4,
|
|
1004
|
-
{
|
|
1005
|
-
borderStyle: raisedButtonStyle.border,
|
|
1006
|
-
borderColor: actionDisabled ? terminalTheme.muted : actionTone ?? terminalTheme.brand,
|
|
1007
|
-
paddingX: 1,
|
|
1008
|
-
children: /* @__PURE__ */ jsx5(
|
|
1009
|
-
Text5,
|
|
1010
|
-
{
|
|
1011
|
-
bold: !actionDisabled,
|
|
1012
|
-
color: actionDisabled ? terminalTheme.muted : actionTone ?? terminalTheme.brand,
|
|
1013
|
-
children: actionLabel
|
|
1014
|
-
}
|
|
1015
|
-
)
|
|
1016
|
-
}
|
|
1017
|
-
)
|
|
1018
|
-
}
|
|
1019
|
-
) : null
|
|
1019
|
+
)
|
|
1020
1020
|
]
|
|
1021
1021
|
}
|
|
1022
1022
|
),
|
|
1023
|
-
actionHint ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, wrap: "truncate", children: actionHint }) : null,
|
|
1023
|
+
actionHint ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, wrap: "truncate", children: actionHint }) : resolvedHelpText ? /* @__PURE__ */ jsx5(Text5, { dimColor: true, wrap: "truncate", children: resolvedHelpText }) : null,
|
|
1024
1024
|
footerControls ? /* @__PURE__ */ jsx5(Box4, { flexDirection: "column", marginTop: 1, children: footerControls }) : null
|
|
1025
1025
|
]
|
|
1026
1026
|
}
|
|
@@ -1054,7 +1054,7 @@ var Scrollbar2 = ({
|
|
|
1054
1054
|
return /* @__PURE__ */ jsx6(Box5, { flexDirection: "column", marginLeft: 1, flexShrink: 0, width: 1, children: scrollbarLines.map((line, idx) => /* @__PURE__ */ jsx6(
|
|
1055
1055
|
Text6,
|
|
1056
1056
|
{
|
|
1057
|
-
color: line === "\u2588" ? terminalTheme.
|
|
1057
|
+
color: line === "\u2588" ? terminalTheme.focus : terminalTheme.muted,
|
|
1058
1058
|
children: line
|
|
1059
1059
|
},
|
|
1060
1060
|
idx
|
|
@@ -1136,7 +1136,7 @@ function ProjectSelector({
|
|
|
1136
1136
|
Text7,
|
|
1137
1137
|
{
|
|
1138
1138
|
bold: isHighlighted || isSelected,
|
|
1139
|
-
color: isSelected ? terminalTheme.
|
|
1139
|
+
color: isSelected ? terminalTheme.selected : isHighlighted ? terminalTheme.focus : void 0,
|
|
1140
1140
|
children: [
|
|
1141
1141
|
marker,
|
|
1142
1142
|
" ",
|
|
@@ -1207,7 +1207,7 @@ function SelectPanel({
|
|
|
1207
1207
|
Math.max(0, items.length - visibleCount)
|
|
1208
1208
|
);
|
|
1209
1209
|
const visibleItems = items.slice(windowStart, windowStart + visibleCount);
|
|
1210
|
-
return /* @__PURE__ */ jsxs6(TitledBox, { title, borderStyle: "round", borderColor: terminalTheme.
|
|
1210
|
+
return /* @__PURE__ */ jsxs6(TitledBox, { title, borderStyle: "round", borderColor: terminalTheme.focus, padding: 1, children: [
|
|
1211
1211
|
items.length === 0 ? /* @__PURE__ */ jsx8(Text8, { dimColor: true, children: "No options available." }) : visibleItems.map((item, offset) => {
|
|
1212
1212
|
const index = windowStart + offset;
|
|
1213
1213
|
const isHighlighted = index === highlighted;
|
|
@@ -1218,7 +1218,7 @@ function SelectPanel({
|
|
|
1218
1218
|
Text8,
|
|
1219
1219
|
{
|
|
1220
1220
|
bold: isHighlighted || isSelected,
|
|
1221
|
-
color: isSelected ? terminalTheme.
|
|
1221
|
+
color: isSelected ? terminalTheme.selected : isHighlighted ? terminalTheme.focus : void 0,
|
|
1222
1222
|
children: [
|
|
1223
1223
|
marker,
|
|
1224
1224
|
" ",
|
|
@@ -1239,6 +1239,11 @@ function SelectPanel({
|
|
|
1239
1239
|
|
|
1240
1240
|
// src/ui/commandCompletion.ts
|
|
1241
1241
|
var slashCommands = [
|
|
1242
|
+
{
|
|
1243
|
+
name: "/thread",
|
|
1244
|
+
aliases: ["/threads"],
|
|
1245
|
+
description: "Open thread selector or use /thread <title-or-id>."
|
|
1246
|
+
},
|
|
1242
1247
|
{
|
|
1243
1248
|
name: "/project",
|
|
1244
1249
|
aliases: ["/projects"],
|
|
@@ -1254,6 +1259,16 @@ var slashCommands = [
|
|
|
1254
1259
|
aliases: [],
|
|
1255
1260
|
description: "Open mode selector or use /mode ask|agent."
|
|
1256
1261
|
},
|
|
1262
|
+
{
|
|
1263
|
+
name: "/profile",
|
|
1264
|
+
aliases: ["/profiles"],
|
|
1265
|
+
description: "Open Agent Profile selector or use /profile architecture|cost|triage|remediation."
|
|
1266
|
+
},
|
|
1267
|
+
{
|
|
1268
|
+
name: "/starter",
|
|
1269
|
+
aliases: ["/starters"],
|
|
1270
|
+
description: "Show starter prompt selections."
|
|
1271
|
+
},
|
|
1257
1272
|
{
|
|
1258
1273
|
name: "/thinking",
|
|
1259
1274
|
aliases: ["/think"],
|
|
@@ -1342,6 +1357,16 @@ var completePromptInput = (input, context, previous) => {
|
|
|
1342
1357
|
ghostSuffix: toGhostSuffix(trimmed, `/mode ${completion.candidates[0] ?? ""}`)
|
|
1343
1358
|
} : null;
|
|
1344
1359
|
}
|
|
1360
|
+
if (command === "/profile" || command === "/profiles") {
|
|
1361
|
+
const query = normalize(rest);
|
|
1362
|
+
const profileMatches = (context.profiles ?? []).flatMap((item) => item.value ? [item.value] : ["default", "profile"]).filter((value) => normalize(value).startsWith(query));
|
|
1363
|
+
const completion = completeFromCandidates(trimmed, profileMatches, previous);
|
|
1364
|
+
return completion ? {
|
|
1365
|
+
...completion,
|
|
1366
|
+
value: `/profile ${completion.value}`,
|
|
1367
|
+
ghostSuffix: toGhostSuffix(trimmed, `/profile ${completion.candidates[0] ?? ""}`)
|
|
1368
|
+
} : null;
|
|
1369
|
+
}
|
|
1345
1370
|
if (command === "/project" || command === "/projects") {
|
|
1346
1371
|
const query = normalize(rest);
|
|
1347
1372
|
const projectMatches = context.projects.map(projectName).filter((value) => normalize(value).startsWith(query));
|
|
@@ -1352,6 +1377,16 @@ var completePromptInput = (input, context, previous) => {
|
|
|
1352
1377
|
ghostSuffix: toGhostSuffix(trimmed, `/project ${completion.candidates[0] ?? ""}`)
|
|
1353
1378
|
} : null;
|
|
1354
1379
|
}
|
|
1380
|
+
if (command === "/thread" || command === "/threads") {
|
|
1381
|
+
const query = normalize(rest);
|
|
1382
|
+
const threadMatches = (context.threads ?? []).flatMap((item) => [item.value, item.label]).filter((value) => normalize(value).startsWith(query));
|
|
1383
|
+
const completion = completeFromCandidates(trimmed, threadMatches, previous);
|
|
1384
|
+
return completion ? {
|
|
1385
|
+
...completion,
|
|
1386
|
+
value: `/thread ${completion.value}`,
|
|
1387
|
+
ghostSuffix: toGhostSuffix(trimmed, `/thread ${completion.candidates[0] ?? ""}`)
|
|
1388
|
+
} : null;
|
|
1389
|
+
}
|
|
1355
1390
|
return null;
|
|
1356
1391
|
};
|
|
1357
1392
|
var matchOne = (items, query, getValues) => {
|
|
@@ -1385,6 +1420,20 @@ var resolvePromptCommand = (input, context) => {
|
|
|
1385
1420
|
]);
|
|
1386
1421
|
return project ? { type: "setProject", project } : { type: "unknown", message: `No unique project match for '${rest}'.` };
|
|
1387
1422
|
}
|
|
1423
|
+
if (command === "/thread" || command === "/threads") {
|
|
1424
|
+
if (!rest) {
|
|
1425
|
+
return { type: "openSelector", selector: "thread" };
|
|
1426
|
+
}
|
|
1427
|
+
const thread = matchOne(context.threads ?? [], rest, (item) => [
|
|
1428
|
+
item.value,
|
|
1429
|
+
item.label
|
|
1430
|
+
]);
|
|
1431
|
+
return thread ? {
|
|
1432
|
+
type: "setThread",
|
|
1433
|
+
threadId: thread.value,
|
|
1434
|
+
label: thread.label
|
|
1435
|
+
} : { type: "unknown", message: `No unique thread match for '${rest}'.` };
|
|
1436
|
+
}
|
|
1388
1437
|
if (command === "/model" || command === "/models") {
|
|
1389
1438
|
if (!rest) {
|
|
1390
1439
|
return { type: "openSelector", selector: "model" };
|
|
@@ -1409,6 +1458,23 @@ var resolvePromptCommand = (input, context) => {
|
|
|
1409
1458
|
]);
|
|
1410
1459
|
return mode && (mode.value === "ask" || mode.value === "agent") ? { type: "setMode", mode: mode.value, label: mode.label } : { type: "unknown", message: `No unique mode match for '${rest}'.` };
|
|
1411
1460
|
}
|
|
1461
|
+
if (command === "/profile" || command === "/profiles") {
|
|
1462
|
+
if (!rest) {
|
|
1463
|
+
return { type: "openSelector", selector: "profile" };
|
|
1464
|
+
}
|
|
1465
|
+
const profile = matchOne(context.profiles ?? [], rest, (item) => [
|
|
1466
|
+
item.value || "default",
|
|
1467
|
+
item.value ? item.label : "profile"
|
|
1468
|
+
]);
|
|
1469
|
+
return profile ? {
|
|
1470
|
+
type: "setProfile",
|
|
1471
|
+
profileId: profile.value,
|
|
1472
|
+
label: profile.label
|
|
1473
|
+
} : { type: "unknown", message: `No unique profile match for '${rest}'.` };
|
|
1474
|
+
}
|
|
1475
|
+
if (command === "/starter" || command === "/starters") {
|
|
1476
|
+
return { type: "showStarters" };
|
|
1477
|
+
}
|
|
1412
1478
|
if (command === "/thinking" || command === "/think") {
|
|
1413
1479
|
return { type: "toggleThinking" };
|
|
1414
1480
|
}
|
|
@@ -1444,13 +1510,14 @@ var billingSummaryText = (billing, progressWidth = 10) => billing ? `Plan: ${bil
|
|
|
1444
1510
|
})}` : "Plan: loading | Credits: loading";
|
|
1445
1511
|
|
|
1446
1512
|
// src/ui/interactionModel.ts
|
|
1447
|
-
var selectorControls = ["project", "model", "mode"];
|
|
1513
|
+
var selectorControls = ["thread", "project", "model", "mode", "profile"];
|
|
1448
1514
|
var buildControlFocusOrder = ({
|
|
1449
1515
|
hasThinkingSteps,
|
|
1450
1516
|
followUpCount
|
|
1451
1517
|
}) => [
|
|
1452
1518
|
...selectorControls,
|
|
1453
1519
|
...hasThinkingSteps ? ["thinking"] : [],
|
|
1520
|
+
"threadPanel",
|
|
1454
1521
|
...Array.from({ length: followUpCount }, (_, index) => `followup:${index}`)
|
|
1455
1522
|
];
|
|
1456
1523
|
var focusFollowUpIndex = (focus) => {
|
|
@@ -1461,6 +1528,15 @@ var focusFollowUpIndex = (focus) => {
|
|
|
1461
1528
|
return Number.isInteger(index) && index >= 0 ? index : void 0;
|
|
1462
1529
|
};
|
|
1463
1530
|
var isSelectorControlFocus = (focus) => selectorControls.includes(focus);
|
|
1531
|
+
var chatPanelFocusForControl = (focus) => {
|
|
1532
|
+
if (focus === "threadPanel") {
|
|
1533
|
+
return "thread";
|
|
1534
|
+
}
|
|
1535
|
+
if (focusFollowUpIndex(focus) !== void 0) {
|
|
1536
|
+
return "prompt";
|
|
1537
|
+
}
|
|
1538
|
+
return "settings";
|
|
1539
|
+
};
|
|
1464
1540
|
var nextControlFocus = (current, order, direction = 1) => {
|
|
1465
1541
|
if (!order.length) {
|
|
1466
1542
|
return "project";
|
|
@@ -1481,37 +1557,55 @@ var getSelectorControlHitAreas = ({
|
|
|
1481
1557
|
}) => {
|
|
1482
1558
|
const safeTerminalColumns = Math.max(startColumn, terminalColumns);
|
|
1483
1559
|
if (compact) {
|
|
1484
|
-
const
|
|
1485
|
-
|
|
1486
|
-
|
|
1560
|
+
const compactRows = [
|
|
1561
|
+
{ target: "thread", offset: 1 },
|
|
1562
|
+
{ target: "project", offset: 2 },
|
|
1563
|
+
{ target: "model", offset: 4 },
|
|
1564
|
+
{ target: "mode", offset: 5 },
|
|
1565
|
+
{ target: "profile", offset: 6 },
|
|
1566
|
+
...hasThinkingSteps ? [{ target: "thinking", offset: 8 }] : []
|
|
1487
1567
|
];
|
|
1488
|
-
return
|
|
1568
|
+
return compactRows.map(({ target, offset }) => ({
|
|
1489
1569
|
target,
|
|
1490
1570
|
startColumn,
|
|
1491
1571
|
endColumn: safeTerminalColumns,
|
|
1492
|
-
startRow: startRow +
|
|
1493
|
-
endRow: startRow +
|
|
1572
|
+
startRow: startRow + offset,
|
|
1573
|
+
endRow: startRow + offset
|
|
1494
1574
|
}));
|
|
1495
1575
|
}
|
|
1496
1576
|
const fixedAreas = [
|
|
1497
1577
|
{
|
|
1498
|
-
target: "
|
|
1578
|
+
target: "thread",
|
|
1499
1579
|
startColumn,
|
|
1500
1580
|
endColumn: Math.min(safeTerminalColumns, startColumn + 27),
|
|
1501
1581
|
startRow,
|
|
1502
1582
|
endRow: startRow + 2
|
|
1503
1583
|
},
|
|
1504
1584
|
{
|
|
1505
|
-
target: "
|
|
1585
|
+
target: "project",
|
|
1506
1586
|
startColumn: startColumn + 29,
|
|
1507
|
-
endColumn: Math.min(safeTerminalColumns, startColumn +
|
|
1587
|
+
endColumn: Math.min(safeTerminalColumns, startColumn + 56),
|
|
1588
|
+
startRow,
|
|
1589
|
+
endRow: startRow + 2
|
|
1590
|
+
},
|
|
1591
|
+
{
|
|
1592
|
+
target: "model",
|
|
1593
|
+
startColumn: startColumn + 58,
|
|
1594
|
+
endColumn: Math.min(safeTerminalColumns, startColumn + 80),
|
|
1508
1595
|
startRow,
|
|
1509
1596
|
endRow: startRow + 2
|
|
1510
1597
|
},
|
|
1511
1598
|
{
|
|
1512
1599
|
target: "mode",
|
|
1513
|
-
startColumn: startColumn +
|
|
1514
|
-
endColumn: Math.min(safeTerminalColumns, startColumn +
|
|
1600
|
+
startColumn: startColumn + 82,
|
|
1601
|
+
endColumn: Math.min(safeTerminalColumns, startColumn + 100),
|
|
1602
|
+
startRow,
|
|
1603
|
+
endRow: startRow + 2
|
|
1604
|
+
},
|
|
1605
|
+
{
|
|
1606
|
+
target: "profile",
|
|
1607
|
+
startColumn: startColumn + 102,
|
|
1608
|
+
endColumn: Math.min(safeTerminalColumns, startColumn + 124),
|
|
1515
1609
|
startRow,
|
|
1516
1610
|
endRow: startRow + 2
|
|
1517
1611
|
}
|
|
@@ -1519,7 +1613,7 @@ var getSelectorControlHitAreas = ({
|
|
|
1519
1613
|
if (hasThinkingSteps) {
|
|
1520
1614
|
fixedAreas.push({
|
|
1521
1615
|
target: "thinking",
|
|
1522
|
-
startColumn: startColumn +
|
|
1616
|
+
startColumn: startColumn + 126,
|
|
1523
1617
|
endColumn: safeTerminalColumns,
|
|
1524
1618
|
startRow,
|
|
1525
1619
|
endRow: startRow + 2
|
|
@@ -1530,6 +1624,15 @@ var getSelectorControlHitAreas = ({
|
|
|
1530
1624
|
var selectorControlFromMousePosition = (position, areas) => areas.find(
|
|
1531
1625
|
(area) => position.x >= area.startColumn && position.x <= area.endColumn && position.y >= area.startRow && position.y <= area.endRow
|
|
1532
1626
|
)?.target;
|
|
1627
|
+
var isPromptTextInput = (input, key) => {
|
|
1628
|
+
if (!input || key.ctrl || key.meta) {
|
|
1629
|
+
return false;
|
|
1630
|
+
}
|
|
1631
|
+
if (key.return || key.tab || key.escape || key.upArrow || key.downArrow || key.leftArrow || key.rightArrow || key.pageUp || key.pageDown || key.backspace || key.delete) {
|
|
1632
|
+
return false;
|
|
1633
|
+
}
|
|
1634
|
+
return input.length > 0;
|
|
1635
|
+
};
|
|
1533
1636
|
|
|
1534
1637
|
// src/ui/layout.ts
|
|
1535
1638
|
var clamp2 = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
@@ -1567,7 +1670,6 @@ var getResponsiveTuiLayout = (size, options = {}) => {
|
|
|
1567
1670
|
if (options.hasHitl) reservedRows += 7;
|
|
1568
1671
|
if (options.hasSelector) reservedRows += 8;
|
|
1569
1672
|
if (options.isSearching) reservedRows += 3;
|
|
1570
|
-
const minThreadHeight = rows < 20 ? 3 : rows < 28 ? 4 : 6;
|
|
1571
1673
|
const maxThreadHeight = compact ? 14 : 24;
|
|
1572
1674
|
const availableRows = rows - reservedRows;
|
|
1573
1675
|
return {
|
|
@@ -1575,18 +1677,20 @@ var getResponsiveTuiLayout = (size, options = {}) => {
|
|
|
1575
1677
|
paddingX: compact ? 0 : 1,
|
|
1576
1678
|
selectorLimit: compact ? 6 : 8,
|
|
1577
1679
|
showBanner,
|
|
1578
|
-
threadHeight: clamp2(availableRows,
|
|
1680
|
+
threadHeight: clamp2(availableRows, 1, maxThreadHeight)
|
|
1579
1681
|
};
|
|
1580
1682
|
};
|
|
1683
|
+
var getMiddleViewportRows = (size, options = {}) => {
|
|
1684
|
+
const rows = normalizeDimension(size.rows, 32);
|
|
1685
|
+
const headerRows = Math.max(0, Math.ceil(options.headerRows ?? 0));
|
|
1686
|
+
const footerRows = Math.max(0, Math.ceil(options.footerRows ?? 0));
|
|
1687
|
+
const safetyRows = Math.max(0, Math.ceil(options.safetyRows ?? 2));
|
|
1688
|
+
return Math.max(1, Math.floor(rows) - headerRows - footerRows - safetyRows);
|
|
1689
|
+
};
|
|
1690
|
+
var getFramedBodyRows = (frameRows, chromeRows = 4) => Math.max(1, Math.floor(frameRows) - Math.max(0, Math.ceil(chromeRows)));
|
|
1581
1691
|
var getPromptInputRowBudget = (size) => {
|
|
1582
1692
|
const rows = normalizeDimension(size.rows, 32);
|
|
1583
|
-
|
|
1584
|
-
return 4;
|
|
1585
|
-
}
|
|
1586
|
-
if (rows < 38) {
|
|
1587
|
-
return 6;
|
|
1588
|
-
}
|
|
1589
|
-
return clamp2(Math.floor(rows * 0.22), 8, 16);
|
|
1693
|
+
return clamp2(Math.floor(rows * 0.13), 4, 8);
|
|
1590
1694
|
};
|
|
1591
1695
|
var shouldUseSplitChatLayout = (size) => {
|
|
1592
1696
|
const columns = normalizeDimension(size.columns, 100);
|
|
@@ -1857,10 +1961,11 @@ var getStarterPrompts = ({
|
|
|
1857
1961
|
};
|
|
1858
1962
|
var getPromptSuggestions = ({
|
|
1859
1963
|
latestFollowUps,
|
|
1860
|
-
messages,
|
|
1964
|
+
messages: _messages,
|
|
1861
1965
|
mode,
|
|
1862
1966
|
project,
|
|
1863
|
-
limit
|
|
1967
|
+
limit,
|
|
1968
|
+
showStarters = false
|
|
1864
1969
|
}) => {
|
|
1865
1970
|
const followUps = latestFollowUps.map((prompt) => prompt.trim()).filter(Boolean);
|
|
1866
1971
|
if (followUps.length) {
|
|
@@ -1870,8 +1975,7 @@ var getPromptSuggestions = ({
|
|
|
1870
1975
|
prompts: followUps
|
|
1871
1976
|
};
|
|
1872
1977
|
}
|
|
1873
|
-
|
|
1874
|
-
if (!hasUserMessages) {
|
|
1978
|
+
if (showStarters) {
|
|
1875
1979
|
return {
|
|
1876
1980
|
kind: "starter",
|
|
1877
1981
|
label: "Starters",
|
|
@@ -1885,6 +1989,193 @@ var getPromptSuggestions = ({
|
|
|
1885
1989
|
};
|
|
1886
1990
|
};
|
|
1887
1991
|
|
|
1992
|
+
// src/ui/sessionThreads.ts
|
|
1993
|
+
import { randomUUID } from "crypto";
|
|
1994
|
+
var timestampFromIso = (value, fallbackOffset) => {
|
|
1995
|
+
const parsed = Date.parse(value);
|
|
1996
|
+
return Number.isFinite(parsed) ? parsed : Date.now() + fallbackOffset;
|
|
1997
|
+
};
|
|
1998
|
+
var relativeThreadAge = (value, now = Date.now()) => {
|
|
1999
|
+
if (!value) {
|
|
2000
|
+
return void 0;
|
|
2001
|
+
}
|
|
2002
|
+
const parsed = Date.parse(value);
|
|
2003
|
+
if (!Number.isFinite(parsed)) {
|
|
2004
|
+
return void 0;
|
|
2005
|
+
}
|
|
2006
|
+
const diffMs = Math.max(0, now - parsed);
|
|
2007
|
+
const minutes = Math.floor(diffMs / 6e4);
|
|
2008
|
+
if (minutes < 1) {
|
|
2009
|
+
return "now";
|
|
2010
|
+
}
|
|
2011
|
+
if (minutes < 60) {
|
|
2012
|
+
return `${minutes}m`;
|
|
2013
|
+
}
|
|
2014
|
+
const hours = Math.floor(minutes / 60);
|
|
2015
|
+
if (hours < 24) {
|
|
2016
|
+
return `${hours}h`;
|
|
2017
|
+
}
|
|
2018
|
+
const days = Math.floor(hours / 24);
|
|
2019
|
+
if (days < 7) {
|
|
2020
|
+
return `${days}d`;
|
|
2021
|
+
}
|
|
2022
|
+
const weeks = Math.floor(days / 7);
|
|
2023
|
+
if (weeks < 5) {
|
|
2024
|
+
return `${weeks}w`;
|
|
2025
|
+
}
|
|
2026
|
+
const months = Math.floor(days / 30);
|
|
2027
|
+
if (months < 12) {
|
|
2028
|
+
return `${months}mo`;
|
|
2029
|
+
}
|
|
2030
|
+
return `${Math.floor(days / 365)}y`;
|
|
2031
|
+
};
|
|
2032
|
+
var titleWithAge = (title, age) => {
|
|
2033
|
+
if (!age) {
|
|
2034
|
+
return truncateForTerminal(title, 72);
|
|
2035
|
+
}
|
|
2036
|
+
const suffix = ` \xB7 ${age}`;
|
|
2037
|
+
return `${truncateForTerminal(title, Math.max(12, 72 - suffix.length))}${suffix}`;
|
|
2038
|
+
};
|
|
2039
|
+
var createdAgeDescription = (age) => age ? age === "now" ? "created now" : `created ${age} ago` : void 0;
|
|
2040
|
+
var sessionDescription = (session, age) => {
|
|
2041
|
+
const project = session.projectName || session.projectId;
|
|
2042
|
+
const messages = `${session.messageCount} message${session.messageCount === 1 ? "" : "s"}`;
|
|
2043
|
+
return [createdAgeDescription(age), project, messages].filter(Boolean).join(" \xB7 ");
|
|
2044
|
+
};
|
|
2045
|
+
var remoteTitle = (thread) => {
|
|
2046
|
+
const title = String(thread.title || "").trim();
|
|
2047
|
+
const preview = String(thread.last_message_preview || "").trim();
|
|
2048
|
+
return title || preview || thread.thread_id;
|
|
2049
|
+
};
|
|
2050
|
+
var remoteDescription = (thread, age) => {
|
|
2051
|
+
const project = thread.project_name || thread.project_id;
|
|
2052
|
+
const count = Number(thread.message_count ?? 0);
|
|
2053
|
+
const messages = `${count} message${count === 1 ? "" : "s"}`;
|
|
2054
|
+
const source = thread.is_archived ? "Cloud thread \xB7 archived" : "Cloud thread";
|
|
2055
|
+
return [source, createdAgeDescription(age), project, messages].filter(Boolean).join(" \xB7 ");
|
|
2056
|
+
};
|
|
2057
|
+
var extractMessageText = (content) => {
|
|
2058
|
+
if (typeof content === "string") {
|
|
2059
|
+
return content;
|
|
2060
|
+
}
|
|
2061
|
+
if (Array.isArray(content)) {
|
|
2062
|
+
return content.map((part) => {
|
|
2063
|
+
if (typeof part === "string") {
|
|
2064
|
+
return part;
|
|
2065
|
+
}
|
|
2066
|
+
if (part && typeof part === "object") {
|
|
2067
|
+
const record = part;
|
|
2068
|
+
if (typeof record.text === "string") {
|
|
2069
|
+
return record.text;
|
|
2070
|
+
}
|
|
2071
|
+
if (typeof record.content === "string") {
|
|
2072
|
+
return record.content;
|
|
2073
|
+
}
|
|
2074
|
+
}
|
|
2075
|
+
return "";
|
|
2076
|
+
}).filter(Boolean).join(" ");
|
|
2077
|
+
}
|
|
2078
|
+
if (content && typeof content === "object") {
|
|
2079
|
+
const record = content;
|
|
2080
|
+
if (typeof record.text === "string") {
|
|
2081
|
+
return record.text;
|
|
2082
|
+
}
|
|
2083
|
+
if (typeof record.content === "string") {
|
|
2084
|
+
return record.content;
|
|
2085
|
+
}
|
|
2086
|
+
}
|
|
2087
|
+
return "";
|
|
2088
|
+
};
|
|
2089
|
+
var timestampFromValue = (value, fallback) => {
|
|
2090
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
2091
|
+
return value;
|
|
2092
|
+
}
|
|
2093
|
+
if (typeof value === "string") {
|
|
2094
|
+
const parsed = Date.parse(value);
|
|
2095
|
+
if (Number.isFinite(parsed)) {
|
|
2096
|
+
return parsed;
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
return fallback;
|
|
2100
|
+
};
|
|
2101
|
+
var remoteThreadMessagesToChatMessages = (history) => {
|
|
2102
|
+
const rawMessages = history.messages_page ?? history.thread_messages ?? history.messages ?? [];
|
|
2103
|
+
return rawMessages.map((raw, index) => {
|
|
2104
|
+
if (!raw || typeof raw !== "object") {
|
|
2105
|
+
return null;
|
|
2106
|
+
}
|
|
2107
|
+
const message = raw;
|
|
2108
|
+
const role = String(message.role || "").toLowerCase();
|
|
2109
|
+
if (role !== "user" && role !== "assistant") {
|
|
2110
|
+
return null;
|
|
2111
|
+
}
|
|
2112
|
+
const timestamp = timestampFromValue(
|
|
2113
|
+
message.timestamp ?? message.created_at ?? message.createdAt,
|
|
2114
|
+
Date.now() + index
|
|
2115
|
+
);
|
|
2116
|
+
const followUps = message.followUpQuestions ?? message.follow_up_questions;
|
|
2117
|
+
return {
|
|
2118
|
+
id: String(
|
|
2119
|
+
message.id ?? message.message_id ?? message.assistant_message_id ?? `${history.thread_id}-${index}-${randomUUID()}`
|
|
2120
|
+
),
|
|
2121
|
+
role,
|
|
2122
|
+
content: extractMessageText(message.content),
|
|
2123
|
+
thinkingSteps: Array.isArray(message.thinkingSteps) ? message.thinkingSteps : Array.isArray(message.thinking_steps) ? message.thinking_steps : void 0,
|
|
2124
|
+
followUpQuestions: Array.isArray(followUps) ? followUps.map((item) => String(item)).filter(Boolean) : void 0,
|
|
2125
|
+
createdAt: timestamp,
|
|
2126
|
+
updatedAt: timestampFromValue(message.updated_at ?? message.updatedAt, timestamp)
|
|
2127
|
+
};
|
|
2128
|
+
}).filter((message) => Boolean(message));
|
|
2129
|
+
};
|
|
2130
|
+
var localSessionMessagesToChatMessages = (session) => session.messages.map((message, index) => ({
|
|
2131
|
+
id: `${session.threadId}-${index}-${randomUUID()}`,
|
|
2132
|
+
role: message.role,
|
|
2133
|
+
content: message.content,
|
|
2134
|
+
createdAt: timestampFromIso(message.createdAt, index)
|
|
2135
|
+
}));
|
|
2136
|
+
var buildThreadSelectItems = (sessions, activeThreadId, remoteThreads = [], options = {}) => [
|
|
2137
|
+
{
|
|
2138
|
+
label: "New thread",
|
|
2139
|
+
value: { kind: "new" },
|
|
2140
|
+
description: activeThreadId ? "Start a fresh CloudEval chat thread." : "Current selection."
|
|
2141
|
+
},
|
|
2142
|
+
...remoteThreads.map((thread) => {
|
|
2143
|
+
const age = relativeThreadAge(thread.created_at ?? thread.updated_at, options.now);
|
|
2144
|
+
return {
|
|
2145
|
+
label: titleWithAge(remoteTitle(thread), age),
|
|
2146
|
+
value: { kind: "remote", thread },
|
|
2147
|
+
description: remoteDescription(thread, age)
|
|
2148
|
+
};
|
|
2149
|
+
}),
|
|
2150
|
+
...sessions.filter(
|
|
2151
|
+
(session) => !remoteThreads.some((thread) => thread.thread_id === session.threadId)
|
|
2152
|
+
).map((session) => {
|
|
2153
|
+
const age = relativeThreadAge(session.createdAt ?? session.updatedAt, options.now);
|
|
2154
|
+
return {
|
|
2155
|
+
label: titleWithAge(session.title, age),
|
|
2156
|
+
value: { kind: "session", session },
|
|
2157
|
+
description: `Local session \xB7 ${sessionDescription(session, age)}`
|
|
2158
|
+
};
|
|
2159
|
+
})
|
|
2160
|
+
];
|
|
2161
|
+
var threadPanelTitle = ({
|
|
2162
|
+
session,
|
|
2163
|
+
remoteThread,
|
|
2164
|
+
threadId,
|
|
2165
|
+
hasMessages
|
|
2166
|
+
}) => {
|
|
2167
|
+
if (session?.title) {
|
|
2168
|
+
return truncateForTerminal(session.title, 70);
|
|
2169
|
+
}
|
|
2170
|
+
if (remoteThread) {
|
|
2171
|
+
return truncateForTerminal(remoteTitle(remoteThread), 70);
|
|
2172
|
+
}
|
|
2173
|
+
if (threadId) {
|
|
2174
|
+
return truncateForTerminal(threadId, 70);
|
|
2175
|
+
}
|
|
2176
|
+
return hasMessages ? "Current chat" : "New thread";
|
|
2177
|
+
};
|
|
2178
|
+
|
|
1888
2179
|
// src/ui/overviewDashboard.ts
|
|
1889
2180
|
var toRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
1890
2181
|
var asNumber = (value) => {
|
|
@@ -2878,6 +3169,11 @@ var loadWorkspacePanelData = async ({
|
|
|
2878
3169
|
})
|
|
2879
3170
|
);
|
|
2880
3171
|
}
|
|
3172
|
+
if (data.entitlement) {
|
|
3173
|
+
data.creditStatus = deps.getCreditStatus(data.entitlement, {
|
|
3174
|
+
reportedUsedCredits: deps.getBillingUsageCreditsUsed?.(data.usageSummary)
|
|
3175
|
+
});
|
|
3176
|
+
}
|
|
2881
3177
|
if (deps.getBillingUsageLedger) {
|
|
2882
3178
|
await capture(
|
|
2883
3179
|
"ledger",
|
|
@@ -3015,6 +3311,17 @@ var firstNumber4 = (value, keys) => {
|
|
|
3015
3311
|
}
|
|
3016
3312
|
return void 0;
|
|
3017
3313
|
};
|
|
3314
|
+
var billingUsageTrendValues = (usageSummary) => {
|
|
3315
|
+
const record = toRecord4(usageSummary);
|
|
3316
|
+
const buckets = directArray2(record?.buckets);
|
|
3317
|
+
const bucketValues = buckets.map((bucket) => firstNumber4(bucket, ["credits_used", "total_credits", "credits"])).filter((value) => value !== void 0);
|
|
3318
|
+
if (bucketValues.length) {
|
|
3319
|
+
return bucketValues;
|
|
3320
|
+
}
|
|
3321
|
+
const totals = toRecord4(record?.totals);
|
|
3322
|
+
const total = firstNumber4(totals ?? usageSummary, ["credits_used", "total_credits", "credits"]);
|
|
3323
|
+
return total !== void 0 ? [total] : allNumbers(usageSummary);
|
|
3324
|
+
};
|
|
3018
3325
|
var formatNumber3 = (value) => value === void 0 ? "-" : new Intl.NumberFormat("en-US", { maximumFractionDigits: 2 }).format(
|
|
3019
3326
|
value
|
|
3020
3327
|
);
|
|
@@ -3389,7 +3696,7 @@ var HelpLegend = ({
|
|
|
3389
3696
|
label: "tabs",
|
|
3390
3697
|
color: terminalTheme.brand
|
|
3391
3698
|
},
|
|
3392
|
-
{ key: "
|
|
3699
|
+
{ key: "Arrows", label: "move focus", color: terminalTheme.brand },
|
|
3393
3700
|
{ key: "R", label: "refresh", color: terminalTheme.warning },
|
|
3394
3701
|
{ key: "O", label: "open", color: terminalTheme.success },
|
|
3395
3702
|
{ key: "D", label: "download", color: terminalTheme.success },
|
|
@@ -3486,7 +3793,7 @@ var BillingView = ({ state, compact, terminalColumns, frontendUrl }) => {
|
|
|
3486
3793
|
const creditStatus = toRecord4(state.data.creditStatus);
|
|
3487
3794
|
const entitlement = toRecord4(state.data.entitlement);
|
|
3488
3795
|
const plan = toRecord4(entitlement?.plan);
|
|
3489
|
-
const usageValues =
|
|
3796
|
+
const usageValues = billingUsageTrendValues(state.data.usageSummary);
|
|
3490
3797
|
const ledger = directArray2(state.data.ledger);
|
|
3491
3798
|
const invoices = directArray2(state.data.billingInfo);
|
|
3492
3799
|
const topups = directArray2(state.data.topups);
|
|
@@ -4131,7 +4438,7 @@ var OptionsView = ({
|
|
|
4131
4438
|
workspaceTabs.length,
|
|
4132
4439
|
" jump tabs | ",
|
|
4133
4440
|
keys.tabSwitch,
|
|
4134
|
-
"
|
|
4441
|
+
" |",
|
|
4135
4442
|
" ",
|
|
4136
4443
|
keys.refresh,
|
|
4137
4444
|
" | ",
|
|
@@ -4215,14 +4522,14 @@ var WorkspaceTabBar = ({ activeTab, showBrand = false, billingSummary }) => {
|
|
|
4215
4522
|
Box8,
|
|
4216
4523
|
{
|
|
4217
4524
|
borderStyle: active ? "bold" : raisedButtonStyle.border,
|
|
4218
|
-
borderColor: active ? terminalTheme.
|
|
4525
|
+
borderColor: active ? terminalTheme.focus : terminalTheme.muted,
|
|
4219
4526
|
paddingX: 1,
|
|
4220
4527
|
marginRight: 1,
|
|
4221
4528
|
children: /* @__PURE__ */ jsxs7(
|
|
4222
4529
|
Text9,
|
|
4223
4530
|
{
|
|
4224
4531
|
bold: active,
|
|
4225
|
-
color: active ? terminalTheme.
|
|
4532
|
+
color: active ? terminalTheme.focus : void 0,
|
|
4226
4533
|
children: [
|
|
4227
4534
|
active ? raisedButtonStyle.activeMarker : raisedButtonStyle.inactiveMarker,
|
|
4228
4535
|
" ",
|
|
@@ -4242,12 +4549,103 @@ var WorkspacePanel = (props) => {
|
|
|
4242
4549
|
const compact = props.terminalColumns < 88;
|
|
4243
4550
|
const state = props.state;
|
|
4244
4551
|
const animate = props.animate ?? true;
|
|
4552
|
+
const framed = props.framed ?? true;
|
|
4245
4553
|
const connections = directArray2(state.data.connections);
|
|
4246
4554
|
const isInitialLoading = state.status === "loading";
|
|
4247
4555
|
const isBackgroundRefreshing = Boolean(
|
|
4248
4556
|
state.isRefreshing && !isInitialLoading
|
|
4249
4557
|
);
|
|
4250
|
-
|
|
4558
|
+
const content = /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
4559
|
+
state.loadedAt && !isInitialLoading && !isBackgroundRefreshing ? /* @__PURE__ */ jsx9(Box8, { flexDirection: "row", justifyContent: "flex-end", children: /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
|
|
4560
|
+
"loaded ",
|
|
4561
|
+
new Date(state.loadedAt).toLocaleTimeString()
|
|
4562
|
+
] }) }) : null,
|
|
4563
|
+
isInitialLoading ? /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
|
|
4564
|
+
/* @__PURE__ */ jsx9(Spinner, { type: "dots", animate }),
|
|
4565
|
+
/* @__PURE__ */ jsx9(Text9, { color: terminalTheme.brand, children: "Loading real API data..." })
|
|
4566
|
+
] }) : null,
|
|
4567
|
+
isBackgroundRefreshing ? /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
|
|
4568
|
+
/* @__PURE__ */ jsx9(Spinner, { type: "dots", animate }),
|
|
4569
|
+
/* @__PURE__ */ jsx9(Text9, { color: terminalTheme.brand, children: "Refreshing in background, showing cached data..." })
|
|
4570
|
+
] }) : null,
|
|
4571
|
+
state.status === "error" ? /* @__PURE__ */ jsx9(
|
|
4572
|
+
TitledBox,
|
|
4573
|
+
{
|
|
4574
|
+
title: "Backend Data Unavailable",
|
|
4575
|
+
borderStyle: "single",
|
|
4576
|
+
borderColor: terminalTheme.danger,
|
|
4577
|
+
padding: 0,
|
|
4578
|
+
paddingX: 1,
|
|
4579
|
+
children: /* @__PURE__ */ jsxs7(Text9, { color: terminalTheme.danger, wrap: "wrap", children: [
|
|
4580
|
+
" ",
|
|
4581
|
+
state.error ?? "Unable to load this tab."
|
|
4582
|
+
] })
|
|
4583
|
+
}
|
|
4584
|
+
) : null,
|
|
4585
|
+
state.warnings.length ? /* @__PURE__ */ jsxs7(
|
|
4586
|
+
TitledBox,
|
|
4587
|
+
{
|
|
4588
|
+
title: "Backend Warnings",
|
|
4589
|
+
borderStyle: "single",
|
|
4590
|
+
borderColor: terminalTheme.warning,
|
|
4591
|
+
padding: 0,
|
|
4592
|
+
paddingX: 1,
|
|
4593
|
+
children: [
|
|
4594
|
+
state.warnings.slice(0, 4).map((warning) => /* @__PURE__ */ jsx9(Text9, { color: terminalTheme.warning, wrap: "truncate", children: cleanBackendWarning(warning, props.terminalColumns) }, warning)),
|
|
4595
|
+
state.warnings.length > 4 ? /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
|
|
4596
|
+
"+",
|
|
4597
|
+
state.warnings.length - 4,
|
|
4598
|
+
" more warning(s)"
|
|
4599
|
+
] }) : null
|
|
4600
|
+
]
|
|
4601
|
+
}
|
|
4602
|
+
) : null,
|
|
4603
|
+
props.tab === "overview" ? /* @__PURE__ */ jsx9(
|
|
4604
|
+
OverviewView,
|
|
4605
|
+
{
|
|
4606
|
+
state,
|
|
4607
|
+
projects: props.projects,
|
|
4608
|
+
selectedProject: props.selectedProject,
|
|
4609
|
+
compact,
|
|
4610
|
+
terminalColumns: props.terminalColumns,
|
|
4611
|
+
tablePage: props.tablePage
|
|
4612
|
+
}
|
|
4613
|
+
) : null,
|
|
4614
|
+
props.tab === "reports" ? /* @__PURE__ */ jsx9(
|
|
4615
|
+
ReportsView,
|
|
4616
|
+
{
|
|
4617
|
+
state,
|
|
4618
|
+
projects: props.projects,
|
|
4619
|
+
selectedProject: props.selectedProject,
|
|
4620
|
+
compact,
|
|
4621
|
+
terminalColumns: props.terminalColumns,
|
|
4622
|
+
tablePage: props.tablePage
|
|
4623
|
+
}
|
|
4624
|
+
) : null,
|
|
4625
|
+
props.tab === "projects" ? /* @__PURE__ */ jsx9(
|
|
4626
|
+
ProjectsView,
|
|
4627
|
+
{
|
|
4628
|
+
projects: props.projects,
|
|
4629
|
+
selectedProject: props.selectedProject
|
|
4630
|
+
}
|
|
4631
|
+
) : null,
|
|
4632
|
+
props.tab === "connections" ? /* @__PURE__ */ jsx9(ConnectionsView, { connections }) : null,
|
|
4633
|
+
props.tab === "billing" ? /* @__PURE__ */ jsx9(
|
|
4634
|
+
BillingView,
|
|
4635
|
+
{
|
|
4636
|
+
state,
|
|
4637
|
+
compact,
|
|
4638
|
+
terminalColumns: props.terminalColumns,
|
|
4639
|
+
frontendUrl: props.frontendUrl
|
|
4640
|
+
}
|
|
4641
|
+
) : null,
|
|
4642
|
+
props.tab === "options" ? /* @__PURE__ */ jsx9(OptionsView, { ...props }) : null,
|
|
4643
|
+
props.tab === "help" ? /* @__PURE__ */ jsx9(HelpView, {}) : null
|
|
4644
|
+
] });
|
|
4645
|
+
if (!framed) {
|
|
4646
|
+
return /* @__PURE__ */ jsx9(Box8, { flexDirection: "column", gap: 1, children: content });
|
|
4647
|
+
}
|
|
4648
|
+
return /* @__PURE__ */ jsx9(
|
|
4251
4649
|
TitledBox,
|
|
4252
4650
|
{
|
|
4253
4651
|
title: workspaceTabLabels[props.tab],
|
|
@@ -4255,93 +4653,7 @@ var WorkspacePanel = (props) => {
|
|
|
4255
4653
|
borderColor: terminalTheme.muted,
|
|
4256
4654
|
padding: 1,
|
|
4257
4655
|
gap: 1,
|
|
4258
|
-
children:
|
|
4259
|
-
state.loadedAt && !isInitialLoading && !isBackgroundRefreshing ? /* @__PURE__ */ jsx9(Box8, { flexDirection: "row", justifyContent: "flex-end", children: /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
|
|
4260
|
-
"loaded ",
|
|
4261
|
-
new Date(state.loadedAt).toLocaleTimeString()
|
|
4262
|
-
] }) }) : null,
|
|
4263
|
-
isInitialLoading ? /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
|
|
4264
|
-
/* @__PURE__ */ jsx9(Spinner, { type: "dots", animate }),
|
|
4265
|
-
/* @__PURE__ */ jsx9(Text9, { color: terminalTheme.brand, children: "Loading real API data..." })
|
|
4266
|
-
] }) : null,
|
|
4267
|
-
isBackgroundRefreshing ? /* @__PURE__ */ jsxs7(Box8, { flexDirection: "row", gap: 1, children: [
|
|
4268
|
-
/* @__PURE__ */ jsx9(Spinner, { type: "dots", animate }),
|
|
4269
|
-
/* @__PURE__ */ jsx9(Text9, { color: terminalTheme.brand, children: "Refreshing in background, showing cached data..." })
|
|
4270
|
-
] }) : null,
|
|
4271
|
-
state.status === "error" ? /* @__PURE__ */ jsx9(
|
|
4272
|
-
TitledBox,
|
|
4273
|
-
{
|
|
4274
|
-
title: "Backend Data Unavailable",
|
|
4275
|
-
borderStyle: "single",
|
|
4276
|
-
borderColor: terminalTheme.danger,
|
|
4277
|
-
padding: 0,
|
|
4278
|
-
paddingX: 1,
|
|
4279
|
-
children: /* @__PURE__ */ jsxs7(Text9, { color: terminalTheme.danger, wrap: "wrap", children: [
|
|
4280
|
-
" ",
|
|
4281
|
-
state.error ?? "Unable to load this tab."
|
|
4282
|
-
] })
|
|
4283
|
-
}
|
|
4284
|
-
) : null,
|
|
4285
|
-
state.warnings.length ? /* @__PURE__ */ jsxs7(
|
|
4286
|
-
TitledBox,
|
|
4287
|
-
{
|
|
4288
|
-
title: "Backend Warnings",
|
|
4289
|
-
borderStyle: "single",
|
|
4290
|
-
borderColor: terminalTheme.warning,
|
|
4291
|
-
padding: 0,
|
|
4292
|
-
paddingX: 1,
|
|
4293
|
-
children: [
|
|
4294
|
-
state.warnings.slice(0, 4).map((warning) => /* @__PURE__ */ jsx9(Text9, { color: terminalTheme.warning, wrap: "truncate", children: cleanBackendWarning(warning, props.terminalColumns) }, warning)),
|
|
4295
|
-
state.warnings.length > 4 ? /* @__PURE__ */ jsxs7(Text9, { dimColor: true, children: [
|
|
4296
|
-
"+",
|
|
4297
|
-
state.warnings.length - 4,
|
|
4298
|
-
" more warning(s)"
|
|
4299
|
-
] }) : null
|
|
4300
|
-
]
|
|
4301
|
-
}
|
|
4302
|
-
) : null,
|
|
4303
|
-
props.tab === "overview" ? /* @__PURE__ */ jsx9(
|
|
4304
|
-
OverviewView,
|
|
4305
|
-
{
|
|
4306
|
-
state,
|
|
4307
|
-
projects: props.projects,
|
|
4308
|
-
selectedProject: props.selectedProject,
|
|
4309
|
-
compact,
|
|
4310
|
-
terminalColumns: props.terminalColumns,
|
|
4311
|
-
tablePage: props.tablePage
|
|
4312
|
-
}
|
|
4313
|
-
) : null,
|
|
4314
|
-
props.tab === "reports" ? /* @__PURE__ */ jsx9(
|
|
4315
|
-
ReportsView,
|
|
4316
|
-
{
|
|
4317
|
-
state,
|
|
4318
|
-
projects: props.projects,
|
|
4319
|
-
selectedProject: props.selectedProject,
|
|
4320
|
-
compact,
|
|
4321
|
-
terminalColumns: props.terminalColumns,
|
|
4322
|
-
tablePage: props.tablePage
|
|
4323
|
-
}
|
|
4324
|
-
) : null,
|
|
4325
|
-
props.tab === "projects" ? /* @__PURE__ */ jsx9(
|
|
4326
|
-
ProjectsView,
|
|
4327
|
-
{
|
|
4328
|
-
projects: props.projects,
|
|
4329
|
-
selectedProject: props.selectedProject
|
|
4330
|
-
}
|
|
4331
|
-
) : null,
|
|
4332
|
-
props.tab === "connections" ? /* @__PURE__ */ jsx9(ConnectionsView, { connections }) : null,
|
|
4333
|
-
props.tab === "billing" ? /* @__PURE__ */ jsx9(
|
|
4334
|
-
BillingView,
|
|
4335
|
-
{
|
|
4336
|
-
state,
|
|
4337
|
-
compact,
|
|
4338
|
-
terminalColumns: props.terminalColumns,
|
|
4339
|
-
frontendUrl: props.frontendUrl
|
|
4340
|
-
}
|
|
4341
|
-
) : null,
|
|
4342
|
-
props.tab === "options" ? /* @__PURE__ */ jsx9(OptionsView, { ...props }) : null,
|
|
4343
|
-
props.tab === "help" ? /* @__PURE__ */ jsx9(HelpView, {}) : null
|
|
4344
|
-
]
|
|
4656
|
+
children: content
|
|
4345
4657
|
}
|
|
4346
4658
|
);
|
|
4347
4659
|
};
|
|
@@ -4350,13 +4662,12 @@ var WorkspacePanel = (props) => {
|
|
|
4350
4662
|
var truthyEnv = (value) => value !== void 0 && /^(1|true|yes|on)$/i.test(value);
|
|
4351
4663
|
var shouldEnableTuiAnimations = ({
|
|
4352
4664
|
disableAnim = false,
|
|
4353
|
-
forceAnim = false,
|
|
4354
4665
|
env = process.env
|
|
4355
4666
|
} = {}) => {
|
|
4356
4667
|
if (disableAnim || truthyEnv(env.CLOUDEVAL_NO_ANIM)) {
|
|
4357
4668
|
return false;
|
|
4358
4669
|
}
|
|
4359
|
-
return
|
|
4670
|
+
return true;
|
|
4360
4671
|
};
|
|
4361
4672
|
|
|
4362
4673
|
// src/ui/App.tsx
|
|
@@ -4371,7 +4682,7 @@ var defaultUser = { id: "cli-user", name: "CLI User" };
|
|
|
4371
4682
|
var getUserNameFromToken = async (token) => {
|
|
4372
4683
|
if (!token) return "You";
|
|
4373
4684
|
try {
|
|
4374
|
-
const { extractEmailFromToken } = await import("./dist-
|
|
4685
|
+
const { extractEmailFromToken } = await import("./dist-TBAQ5KOK.js");
|
|
4375
4686
|
const email = extractEmailFromToken(token);
|
|
4376
4687
|
return getFirstNameForDisplay({ email: email ?? void 0 });
|
|
4377
4688
|
} catch {
|
|
@@ -4384,8 +4695,21 @@ var defaultProject = {
|
|
|
4384
4695
|
user_id: "cli-user",
|
|
4385
4696
|
cloud_provider: "azure"
|
|
4386
4697
|
};
|
|
4387
|
-
var selectorOrder = ["project", "model", "mode"];
|
|
4698
|
+
var selectorOrder = ["thread", "project", "model", "mode", "profile"];
|
|
4388
4699
|
var dropdownIndicator = "\u25BE";
|
|
4700
|
+
var bundledAgentProfiles = getBundledAgentProfiles();
|
|
4701
|
+
var agentProfileItems = [
|
|
4702
|
+
{
|
|
4703
|
+
label: "Profile",
|
|
4704
|
+
value: "",
|
|
4705
|
+
description: "Default CloudEval chat flow without an Agent Profile."
|
|
4706
|
+
},
|
|
4707
|
+
...bundledAgentProfiles.map((profile) => ({
|
|
4708
|
+
label: profile.display_name,
|
|
4709
|
+
value: profile.id,
|
|
4710
|
+
description: profile.personality
|
|
4711
|
+
}))
|
|
4712
|
+
];
|
|
4389
4713
|
var workspaceTabDescriptions = {
|
|
4390
4714
|
chat: "Ask questions, run agent workflows, and inspect project context.",
|
|
4391
4715
|
overview: "Portfolio dashboard with project health, cost, WAF, and report signals.",
|
|
@@ -4416,6 +4740,7 @@ var modeItems = [
|
|
|
4416
4740
|
}
|
|
4417
4741
|
];
|
|
4418
4742
|
var commandNotice = (candidates) => candidates.length > 1 ? `Completions: ${candidates.join(" | ")}` : `Completed: ${candidates[0]}`;
|
|
4743
|
+
var isStarterSlashCommandInput = (value) => /^\/starters?(?:\s*)?$/i.test(value.trim());
|
|
4419
4744
|
var modelNameFromRaw = (raw) => {
|
|
4420
4745
|
if (typeof raw === "string") return raw;
|
|
4421
4746
|
if (!raw || typeof raw !== "object") return void 0;
|
|
@@ -4454,8 +4779,10 @@ var mergeModelItems = (fetchedItems, cliModel) => {
|
|
|
4454
4779
|
return Array.from(merged.values());
|
|
4455
4780
|
};
|
|
4456
4781
|
var delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
|
4457
|
-
var billingHeaderFromEntitlement = (entitlement) => {
|
|
4458
|
-
const creditStatus = getCreditStatus(entitlement
|
|
4782
|
+
var billingHeaderFromEntitlement = (entitlement, usageSummary) => {
|
|
4783
|
+
const creditStatus = getCreditStatus(entitlement, {
|
|
4784
|
+
reportedUsedCredits: getBillingUsageCreditsUsed(usageSummary)
|
|
4785
|
+
});
|
|
4459
4786
|
if (!creditStatus) {
|
|
4460
4787
|
return null;
|
|
4461
4788
|
}
|
|
@@ -4643,8 +4970,10 @@ var estimatePromptControlRows = ({
|
|
|
4643
4970
|
compact,
|
|
4644
4971
|
hasThinkingSteps
|
|
4645
4972
|
}) => {
|
|
4646
|
-
|
|
4647
|
-
|
|
4973
|
+
if (compact) {
|
|
4974
|
+
return 2 + selectorOrder.length + 2;
|
|
4975
|
+
}
|
|
4976
|
+
return 3;
|
|
4648
4977
|
};
|
|
4649
4978
|
var estimatePromptPanelRows = ({
|
|
4650
4979
|
inputRows,
|
|
@@ -4653,11 +4982,10 @@ var estimatePromptPanelRows = ({
|
|
|
4653
4982
|
hasThinkingSteps,
|
|
4654
4983
|
includeControls = true
|
|
4655
4984
|
}) => {
|
|
4656
|
-
const outerChromeRows =
|
|
4657
|
-
const
|
|
4658
|
-
const
|
|
4659
|
-
|
|
4660
|
-
return outerChromeRows + topHelpRows + suggestionRows + inputBoxRows + footerRows;
|
|
4985
|
+
const outerChromeRows = 2;
|
|
4986
|
+
const inputRowsWithHint = inputRows + 1;
|
|
4987
|
+
const footerRows = includeControls ? 1 + estimatePromptControlRows({ compact, hasThinkingSteps }) : 0;
|
|
4988
|
+
return outerChromeRows + suggestionRows + inputRowsWithHint + footerRows;
|
|
4661
4989
|
};
|
|
4662
4990
|
var useTerminalSize = () => {
|
|
4663
4991
|
const [size, setSize] = useState4(() => readTerminalSize());
|
|
@@ -4675,6 +5003,16 @@ var isMouseTrackingEnabled = () => {
|
|
|
4675
5003
|
return value !== "0" && value !== "false" && value !== "no";
|
|
4676
5004
|
};
|
|
4677
5005
|
var oneLine = (value) => value.replace(/\s+/g, " ").trim();
|
|
5006
|
+
var collapseRepeatedAssistantText = (value) => {
|
|
5007
|
+
const trimmed = value.trim();
|
|
5008
|
+
if (!trimmed || trimmed.length % 2 !== 0) {
|
|
5009
|
+
return value;
|
|
5010
|
+
}
|
|
5011
|
+
const midpoint = trimmed.length / 2;
|
|
5012
|
+
const first = trimmed.slice(0, midpoint);
|
|
5013
|
+
const second = trimmed.slice(midpoint);
|
|
5014
|
+
return first === second ? first : value;
|
|
5015
|
+
};
|
|
4678
5016
|
var enableTerminalMouse = () => {
|
|
4679
5017
|
if (!process.stdin.isTTY || !process.stdout.isTTY) {
|
|
4680
5018
|
return () => {
|
|
@@ -4734,16 +5072,24 @@ var summarizeThinkingSteps = (message) => {
|
|
|
4734
5072
|
};
|
|
4735
5073
|
var selectorValueText = ({
|
|
4736
5074
|
kind,
|
|
5075
|
+
selectedThreadTitle,
|
|
4737
5076
|
selectedProject,
|
|
4738
5077
|
selectedModel,
|
|
4739
|
-
selectedMode
|
|
5078
|
+
selectedMode,
|
|
5079
|
+
selectedAgentProfileLabel
|
|
4740
5080
|
}) => {
|
|
5081
|
+
if (kind === "thread") {
|
|
5082
|
+
return selectedThreadTitle;
|
|
5083
|
+
}
|
|
4741
5084
|
if (kind === "project") {
|
|
4742
5085
|
return selectedProject?.name ?? defaultProject.name;
|
|
4743
5086
|
}
|
|
4744
5087
|
if (kind === "model") {
|
|
4745
5088
|
return selectedModel || "auto";
|
|
4746
5089
|
}
|
|
5090
|
+
if (kind === "profile") {
|
|
5091
|
+
return selectedAgentProfileLabel;
|
|
5092
|
+
}
|
|
4747
5093
|
return selectedMode;
|
|
4748
5094
|
};
|
|
4749
5095
|
var QueuePanel = ({ messages, compact, terminalColumns }) => {
|
|
@@ -4785,9 +5131,11 @@ var QueuePanel = ({ messages, compact, terminalColumns }) => {
|
|
|
4785
5131
|
};
|
|
4786
5132
|
var PromptControlBar = ({
|
|
4787
5133
|
focused,
|
|
5134
|
+
selectedThreadTitle,
|
|
4788
5135
|
selectedProject,
|
|
4789
5136
|
selectedModel,
|
|
4790
5137
|
selectedMode,
|
|
5138
|
+
selectedAgentProfileLabel,
|
|
4791
5139
|
hasThinkingSteps,
|
|
4792
5140
|
thinkingExpanded,
|
|
4793
5141
|
thinkingSummary,
|
|
@@ -4799,6 +5147,80 @@ var PromptControlBar = ({
|
|
|
4799
5147
|
animate
|
|
4800
5148
|
}) => {
|
|
4801
5149
|
const controlGap = compact ? 0 : 1;
|
|
5150
|
+
const compactGroups = [
|
|
5151
|
+
{ label: "Session", controls: ["thread", "project"] },
|
|
5152
|
+
{ label: "Run", controls: ["model", "mode", "profile"] }
|
|
5153
|
+
];
|
|
5154
|
+
const showActivity = hasThinkingSteps || busy || statusText !== "Idle";
|
|
5155
|
+
if (compact) {
|
|
5156
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", gap: 0, children: [
|
|
5157
|
+
compactGroups.map((group, index) => /* @__PURE__ */ jsxs8(
|
|
5158
|
+
Box9,
|
|
5159
|
+
{
|
|
5160
|
+
flexDirection: "column",
|
|
5161
|
+
gap: 0,
|
|
5162
|
+
marginTop: index === 0 ? 0 : 1,
|
|
5163
|
+
children: [
|
|
5164
|
+
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: group.label }),
|
|
5165
|
+
group.controls.map((kind) => {
|
|
5166
|
+
const isFocused = focused === kind;
|
|
5167
|
+
const label = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
5168
|
+
const rawValue = selectorValueText({
|
|
5169
|
+
kind,
|
|
5170
|
+
selectedThreadTitle,
|
|
5171
|
+
selectedProject,
|
|
5172
|
+
selectedModel,
|
|
5173
|
+
selectedMode,
|
|
5174
|
+
selectedAgentProfileLabel
|
|
5175
|
+
});
|
|
5176
|
+
const valueLimit = Math.max(14, terminalColumns - label.length - 8);
|
|
5177
|
+
const value = truncateForTerminal(rawValue, valueLimit);
|
|
5178
|
+
return /* @__PURE__ */ jsxs8(
|
|
5179
|
+
Text10,
|
|
5180
|
+
{
|
|
5181
|
+
color: isFocused ? terminalTheme.focus : void 0,
|
|
5182
|
+
bold: isFocused,
|
|
5183
|
+
wrap: "truncate",
|
|
5184
|
+
children: [
|
|
5185
|
+
isFocused ? raisedButtonStyle.activeMarker : raisedButtonStyle.inactiveMarker,
|
|
5186
|
+
" ",
|
|
5187
|
+
label,
|
|
5188
|
+
" [",
|
|
5189
|
+
value,
|
|
5190
|
+
"] ",
|
|
5191
|
+
dropdownIndicator
|
|
5192
|
+
]
|
|
5193
|
+
},
|
|
5194
|
+
kind
|
|
5195
|
+
);
|
|
5196
|
+
})
|
|
5197
|
+
]
|
|
5198
|
+
},
|
|
5199
|
+
group.label
|
|
5200
|
+
)),
|
|
5201
|
+
showActivity ? /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", gap: 0, marginTop: 1, children: [
|
|
5202
|
+
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "Activity" }),
|
|
5203
|
+
hasThinkingSteps ? /* @__PURE__ */ jsxs8(
|
|
5204
|
+
Text10,
|
|
5205
|
+
{
|
|
5206
|
+
color: focused === "thinking" ? terminalTheme.focus : void 0,
|
|
5207
|
+
bold: focused === "thinking",
|
|
5208
|
+
wrap: "truncate",
|
|
5209
|
+
children: [
|
|
5210
|
+
focused === "thinking" ? raisedButtonStyle.activeMarker : raisedButtonStyle.inactiveMarker,
|
|
5211
|
+
" ",
|
|
5212
|
+
"Reasoning: ",
|
|
5213
|
+
thinkingExpanded ? "open" : thinkingSummary
|
|
5214
|
+
]
|
|
5215
|
+
}
|
|
5216
|
+
) : null,
|
|
5217
|
+
/* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", gap: 1, children: [
|
|
5218
|
+
busy ? /* @__PURE__ */ jsx10(Spinner, { type: "line", animate }) : null,
|
|
5219
|
+
/* @__PURE__ */ jsx10(Text10, { color: statusColor, children: statusText })
|
|
5220
|
+
] })
|
|
5221
|
+
] }) : null
|
|
5222
|
+
] });
|
|
5223
|
+
}
|
|
4802
5224
|
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", gap: 0, children: [
|
|
4803
5225
|
/* @__PURE__ */ jsx10(Text10, { dimColor: true, children: "Settings" }),
|
|
4804
5226
|
/* @__PURE__ */ jsxs8(Box9, { flexDirection: compact ? "column" : "row", gap: controlGap, flexWrap: "wrap", children: [
|
|
@@ -4807,9 +5229,11 @@ var PromptControlBar = ({
|
|
|
4807
5229
|
const label = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
4808
5230
|
const rawValue = selectorValueText({
|
|
4809
5231
|
kind,
|
|
5232
|
+
selectedThreadTitle,
|
|
4810
5233
|
selectedProject,
|
|
4811
5234
|
selectedModel,
|
|
4812
|
-
selectedMode
|
|
5235
|
+
selectedMode,
|
|
5236
|
+
selectedAgentProfileLabel
|
|
4813
5237
|
});
|
|
4814
5238
|
const valueLimit = compact ? Math.max(18, terminalColumns - label.length - 8) : kind === "project" ? 30 : 20;
|
|
4815
5239
|
const value = truncateForTerminal(rawValue, valueLimit);
|
|
@@ -4817,9 +5241,9 @@ var PromptControlBar = ({
|
|
|
4817
5241
|
Box9,
|
|
4818
5242
|
{
|
|
4819
5243
|
borderStyle: raisedButtonStyle.border,
|
|
4820
|
-
borderColor: isFocused ? terminalTheme.
|
|
5244
|
+
borderColor: isFocused ? terminalTheme.focus : terminalTheme.muted,
|
|
4821
5245
|
paddingX: 1,
|
|
4822
|
-
children: /* @__PURE__ */ jsxs8(Text10, { color: isFocused ? terminalTheme.
|
|
5246
|
+
children: /* @__PURE__ */ jsxs8(Text10, { color: isFocused ? terminalTheme.focus : void 0, bold: isFocused, children: [
|
|
4823
5247
|
isFocused ? raisedButtonStyle.activeMarker : raisedButtonStyle.inactiveMarker,
|
|
4824
5248
|
" ",
|
|
4825
5249
|
label,
|
|
@@ -4836,12 +5260,12 @@ var PromptControlBar = ({
|
|
|
4836
5260
|
Box9,
|
|
4837
5261
|
{
|
|
4838
5262
|
borderStyle: raisedButtonStyle.border,
|
|
4839
|
-
borderColor: focused === "thinking" ? terminalTheme.
|
|
5263
|
+
borderColor: focused === "thinking" ? terminalTheme.focus : terminalTheme.muted,
|
|
4840
5264
|
paddingX: 1,
|
|
4841
5265
|
children: /* @__PURE__ */ jsxs8(
|
|
4842
5266
|
Text10,
|
|
4843
5267
|
{
|
|
4844
|
-
color: focused === "thinking" ? terminalTheme.
|
|
5268
|
+
color: focused === "thinking" ? terminalTheme.focus : void 0,
|
|
4845
5269
|
bold: focused === "thinking",
|
|
4846
5270
|
children: [
|
|
4847
5271
|
focused === "thinking" ? raisedButtonStyle.activeMarker : raisedButtonStyle.inactiveMarker,
|
|
@@ -4862,57 +5286,58 @@ var PromptControlBar = ({
|
|
|
4862
5286
|
};
|
|
4863
5287
|
var ChatContextPanel = ({
|
|
4864
5288
|
width,
|
|
5289
|
+
height,
|
|
5290
|
+
active,
|
|
4865
5291
|
focused,
|
|
4866
5292
|
selectedProject,
|
|
5293
|
+
selectedThreadTitle,
|
|
4867
5294
|
selectedModel,
|
|
4868
5295
|
selectedMode,
|
|
5296
|
+
selectedAgentProfileLabel,
|
|
4869
5297
|
hasThinkingSteps,
|
|
4870
5298
|
thinkingExpanded,
|
|
4871
5299
|
thinkingSummary,
|
|
4872
5300
|
statusText,
|
|
4873
5301
|
statusColor,
|
|
4874
5302
|
busy,
|
|
4875
|
-
animate
|
|
4876
|
-
threadId
|
|
5303
|
+
animate
|
|
4877
5304
|
}) => {
|
|
4878
|
-
|
|
4879
|
-
return /* @__PURE__ */ jsxs8(
|
|
5305
|
+
return /* @__PURE__ */ jsx10(
|
|
4880
5306
|
TitledBox,
|
|
4881
5307
|
{
|
|
4882
|
-
title: "
|
|
5308
|
+
title: "Settings",
|
|
4883
5309
|
borderStyle: "round",
|
|
4884
|
-
borderColor: terminalTheme.muted,
|
|
5310
|
+
borderColor: active ? terminalTheme.focus : terminalTheme.muted,
|
|
4885
5311
|
padding: 1,
|
|
4886
5312
|
width,
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
|
|
4902
|
-
|
|
4903
|
-
|
|
4904
|
-
|
|
4905
|
-
|
|
4906
|
-
|
|
4907
|
-
|
|
4908
|
-
]
|
|
5313
|
+
height,
|
|
5314
|
+
children: /* @__PURE__ */ jsx10(
|
|
5315
|
+
PromptControlBar,
|
|
5316
|
+
{
|
|
5317
|
+
focused,
|
|
5318
|
+
selectedThreadTitle,
|
|
5319
|
+
selectedProject,
|
|
5320
|
+
selectedModel,
|
|
5321
|
+
selectedMode,
|
|
5322
|
+
selectedAgentProfileLabel,
|
|
5323
|
+
hasThinkingSteps,
|
|
5324
|
+
thinkingExpanded,
|
|
5325
|
+
thinkingSummary,
|
|
5326
|
+
compact: true,
|
|
5327
|
+
terminalColumns: Math.max(24, width - 4),
|
|
5328
|
+
statusText,
|
|
5329
|
+
statusColor,
|
|
5330
|
+
busy,
|
|
5331
|
+
animate
|
|
5332
|
+
}
|
|
5333
|
+
)
|
|
4909
5334
|
}
|
|
4910
5335
|
);
|
|
4911
5336
|
};
|
|
4912
5337
|
var BottomControls = ({ tab }) => /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", justifyContent: "space-between", children: [
|
|
4913
5338
|
/* @__PURE__ */ jsxs8(Text10, { dimColor: true, children: [
|
|
4914
5339
|
/* @__PURE__ */ jsx10(Text10, { color: terminalTheme.brand, bold: true, children: "Keys" }),
|
|
4915
|
-
/* @__PURE__ */ jsx10(Text10, { children: " \u2191/\u2193 scroll | PgUp/PgDn scroll | [/] table page | " }),
|
|
5340
|
+
/* @__PURE__ */ jsx10(Text10, { children: " \u2191/\u2193 move or scroll | PgUp/PgDn scroll | [/] table page | " }),
|
|
4916
5341
|
/* @__PURE__ */ jsx10(Text10, { color: terminalTheme.brand, bold: true, children: "D" }),
|
|
4917
5342
|
/* @__PURE__ */ jsx10(Text10, { children: " download | " }),
|
|
4918
5343
|
/* @__PURE__ */ jsx10(Text10, { color: terminalTheme.brand, bold: true, children: "R" }),
|
|
@@ -4960,7 +5385,7 @@ var HitlPanel = ({ hitl, questionIndex, optionIndex, answers, frontendUrl }) =>
|
|
|
4960
5385
|
return /* @__PURE__ */ jsxs8(
|
|
4961
5386
|
Text10,
|
|
4962
5387
|
{
|
|
4963
|
-
color: highlighted ? terminalTheme.
|
|
5388
|
+
color: highlighted ? terminalTheme.focus : selected ? terminalTheme.selected : void 0,
|
|
4964
5389
|
dimColor: !highlighted && !selected,
|
|
4965
5390
|
bold: highlighted,
|
|
4966
5391
|
inverse: highlighted,
|
|
@@ -4994,6 +5419,7 @@ var App = ({
|
|
|
4994
5419
|
initialMode = "ask",
|
|
4995
5420
|
initialTab,
|
|
4996
5421
|
initialProjectId,
|
|
5422
|
+
configProfile,
|
|
4997
5423
|
frontendUrl,
|
|
4998
5424
|
debug = false,
|
|
4999
5425
|
disableBanner = false,
|
|
@@ -5007,6 +5433,8 @@ var App = ({
|
|
|
5007
5433
|
const [loaderStep, setLoaderStep] = useState4(0);
|
|
5008
5434
|
const [bootError, setBootError] = useState4();
|
|
5009
5435
|
const [input, setInput] = useState4("");
|
|
5436
|
+
const [promptInputActive, setPromptInputActive] = useState4(true);
|
|
5437
|
+
const [starterSelectionsOpen, setStarterSelectionsOpen] = useState4(false);
|
|
5010
5438
|
const [promptInputScrollOffset, setPromptInputScrollOffset] = useState4(0);
|
|
5011
5439
|
const [authToken, setAuthToken] = useState4(accessKey);
|
|
5012
5440
|
const [chatState, setChatState] = useState4({
|
|
@@ -5019,6 +5447,7 @@ var App = ({
|
|
|
5019
5447
|
const [selectedProject, setSelectedProject] = useState4(null);
|
|
5020
5448
|
const [selectedModel, setSelectedModel] = useState4(model ?? "");
|
|
5021
5449
|
const [selectedMode, setSelectedMode] = useState4(initialMode);
|
|
5450
|
+
const [selectedAgentProfileId, setSelectedAgentProfileId] = useState4("");
|
|
5022
5451
|
const [activeWorkspaceTab, setActiveWorkspaceTab] = useState4(
|
|
5023
5452
|
() => normalizeWorkspaceTab(initialTab)
|
|
5024
5453
|
);
|
|
@@ -5034,6 +5463,10 @@ var App = ({
|
|
|
5034
5463
|
}
|
|
5035
5464
|
return fallbackModels;
|
|
5036
5465
|
});
|
|
5466
|
+
const [localSessions, setLocalSessions] = useState4([]);
|
|
5467
|
+
const [remoteThreads, setRemoteThreads] = useState4([]);
|
|
5468
|
+
const [loadingSessions, setLoadingSessions] = useState4(false);
|
|
5469
|
+
const [loadingRemoteThreads, setLoadingRemoteThreads] = useState4(false);
|
|
5037
5470
|
const [activeSelector, setActiveSelector] = useState4(null);
|
|
5038
5471
|
const [selectingProject, setSelectingProject] = useState4(false);
|
|
5039
5472
|
const [loadingProjects, setLoadingProjects] = useState4(false);
|
|
@@ -5055,11 +5488,19 @@ var App = ({
|
|
|
5055
5488
|
const [workspaceScrollOffset, setWorkspaceScrollOffset] = useState4(0);
|
|
5056
5489
|
const [workspaceContentHeight, setWorkspaceContentHeight] = useState4(0);
|
|
5057
5490
|
const [workspaceViewportHeight, setWorkspaceViewportHeight] = useState4(14);
|
|
5491
|
+
const [chatMiddleScrollOffset, setChatMiddleScrollOffset] = useState4(0);
|
|
5492
|
+
const [chatMiddleContentHeight, setChatMiddleContentHeight] = useState4(0);
|
|
5493
|
+
const [chatMiddleViewportHeight, setChatMiddleViewportHeight] = useState4(12);
|
|
5058
5494
|
const apiBase = useMemo(() => normalizeApiBase(baseUrl), [baseUrl]);
|
|
5059
5495
|
const frontendBaseUrl = useMemo(
|
|
5060
5496
|
() => resolveFrontendBaseUrl2(apiBase, frontendUrl),
|
|
5061
5497
|
[apiBase, frontendUrl]
|
|
5062
5498
|
);
|
|
5499
|
+
const selectedAgentProfile = useMemo(
|
|
5500
|
+
() => bundledAgentProfiles.find((profile) => profile.id === selectedAgentProfileId),
|
|
5501
|
+
[selectedAgentProfileId]
|
|
5502
|
+
);
|
|
5503
|
+
const selectedAgentProfileLabel = selectedAgentProfile?.display_name ?? "Profile";
|
|
5063
5504
|
const frontendThreadUrl = useMemo(
|
|
5064
5505
|
() => buildFrontendThreadUrl(frontendBaseUrl, chatState.threadId),
|
|
5065
5506
|
[frontendBaseUrl, chatState.threadId]
|
|
@@ -5077,10 +5518,12 @@ var App = ({
|
|
|
5077
5518
|
const billingHeaderRefreshKey = workspaceRefreshKeys.billing ?? 0;
|
|
5078
5519
|
const scrollViewRef = React8.useRef(null);
|
|
5079
5520
|
const workspaceScrollViewRef = React8.useRef(null);
|
|
5521
|
+
const chatMiddleScrollViewRef = React8.useRef(null);
|
|
5080
5522
|
const controllerRef = React8.useRef(null);
|
|
5081
5523
|
const queueRef = React8.useRef([]);
|
|
5082
5524
|
const completionCycleRef = React8.useRef();
|
|
5083
5525
|
const previousWorkspaceTabRef = React8.useRef(activeWorkspaceTab);
|
|
5526
|
+
const hydratedThreadRef = React8.useRef();
|
|
5084
5527
|
const [isLoggingIn, setIsLoggingIn] = useState4(false);
|
|
5085
5528
|
const [expandedThinkingMessageIds, setExpandedThinkingMessageIds] = useState4(
|
|
5086
5529
|
() => /* @__PURE__ */ new Set()
|
|
@@ -5104,10 +5547,31 @@ var App = ({
|
|
|
5104
5547
|
const [searchQuery, setSearchQuery] = useState4("");
|
|
5105
5548
|
const terminalSize = useTerminalSize();
|
|
5106
5549
|
const mouseTrackingEnabled = isMouseTrackingEnabled();
|
|
5107
|
-
const
|
|
5108
|
-
|
|
5109
|
-
|
|
5110
|
-
|
|
5550
|
+
const selectedLocalSession = useMemo(
|
|
5551
|
+
() => localSessions.find((session) => session.threadId === chatState.threadId),
|
|
5552
|
+
[chatState.threadId, localSessions]
|
|
5553
|
+
);
|
|
5554
|
+
const selectedRemoteThread = useMemo(
|
|
5555
|
+
() => remoteThreads.find((thread) => thread.thread_id === chatState.threadId),
|
|
5556
|
+
[chatState.threadId, remoteThreads]
|
|
5557
|
+
);
|
|
5558
|
+
const selectedThreadTitle = useMemo(
|
|
5559
|
+
() => threadPanelTitle({
|
|
5560
|
+
session: selectedLocalSession,
|
|
5561
|
+
remoteThread: selectedRemoteThread,
|
|
5562
|
+
threadId: chatState.threadId,
|
|
5563
|
+
hasMessages: chatState.messages.length > 0
|
|
5564
|
+
}),
|
|
5565
|
+
[chatState.messages.length, chatState.threadId, selectedLocalSession, selectedRemoteThread]
|
|
5566
|
+
);
|
|
5567
|
+
const threadSelectItems = useMemo(
|
|
5568
|
+
() => buildThreadSelectItems(localSessions, chatState.threadId, remoteThreads),
|
|
5569
|
+
[chatState.threadId, localSessions, remoteThreads]
|
|
5570
|
+
);
|
|
5571
|
+
const checkHealth = useMemo(() => {
|
|
5572
|
+
return async (token) => {
|
|
5573
|
+
try {
|
|
5574
|
+
const headers = {
|
|
5111
5575
|
"X-Client-Type": "cloudeval-cli",
|
|
5112
5576
|
"X-Client-Version": CLI_VERSION
|
|
5113
5577
|
};
|
|
@@ -5135,9 +5599,211 @@ var App = ({
|
|
|
5135
5599
|
() => ({
|
|
5136
5600
|
projects: projects.length ? projects : selectedProject ? [selectedProject] : [defaultProject],
|
|
5137
5601
|
models: modelItems,
|
|
5138
|
-
modes: modeItems
|
|
5602
|
+
modes: modeItems,
|
|
5603
|
+
threads: threadSelectItems.map((item) => ({
|
|
5604
|
+
label: item.label,
|
|
5605
|
+
value: item.value.kind === "remote" ? item.value.thread.thread_id : item.value.kind === "session" ? item.value.session.threadId : "new",
|
|
5606
|
+
description: item.description
|
|
5607
|
+
})),
|
|
5608
|
+
profiles: agentProfileItems
|
|
5139
5609
|
}),
|
|
5140
|
-
[modelItems, projects, selectedProject]
|
|
5610
|
+
[modelItems, projects, selectedProject, threadSelectItems]
|
|
5611
|
+
);
|
|
5612
|
+
const refreshLocalSessions = React8.useCallback(async () => {
|
|
5613
|
+
setLoadingSessions(true);
|
|
5614
|
+
try {
|
|
5615
|
+
setLocalSessions(await listSessions(24, configProfile));
|
|
5616
|
+
} finally {
|
|
5617
|
+
setLoadingSessions(false);
|
|
5618
|
+
}
|
|
5619
|
+
}, [configProfile]);
|
|
5620
|
+
const resolveThreadApiToken = React8.useCallback(async () => {
|
|
5621
|
+
if (accessKey) {
|
|
5622
|
+
return accessKey;
|
|
5623
|
+
}
|
|
5624
|
+
try {
|
|
5625
|
+
const token = await getAuthToken({ baseUrl: apiBase });
|
|
5626
|
+
setAuthToken(token);
|
|
5627
|
+
return token;
|
|
5628
|
+
} catch {
|
|
5629
|
+
return authToken;
|
|
5630
|
+
}
|
|
5631
|
+
}, [accessKey, apiBase, authToken]);
|
|
5632
|
+
const fetchThreadApiJson = React8.useCallback(
|
|
5633
|
+
async (path) => {
|
|
5634
|
+
const token = await resolveThreadApiToken();
|
|
5635
|
+
if (!token) {
|
|
5636
|
+
throw new Error("No authentication token is available.");
|
|
5637
|
+
}
|
|
5638
|
+
const response = await fetch(`${apiBase}${path}`, {
|
|
5639
|
+
headers: getCLIHeaders(token)
|
|
5640
|
+
});
|
|
5641
|
+
if (!response.ok) {
|
|
5642
|
+
const detail = await response.text().catch(() => "");
|
|
5643
|
+
throw new Error(
|
|
5644
|
+
`Thread request failed with status ${response.status} ${response.statusText}${detail ? `: ${detail.slice(0, 240)}` : ""}`
|
|
5645
|
+
);
|
|
5646
|
+
}
|
|
5647
|
+
return response.json();
|
|
5648
|
+
},
|
|
5649
|
+
[apiBase, resolveThreadApiToken]
|
|
5650
|
+
);
|
|
5651
|
+
const refreshRemoteThreads = React8.useCallback(async () => {
|
|
5652
|
+
setLoadingRemoteThreads(true);
|
|
5653
|
+
try {
|
|
5654
|
+
const payload = await fetchThreadApiJson(
|
|
5655
|
+
"/chat/threads?limit=50&offset=0&include_archived=true"
|
|
5656
|
+
);
|
|
5657
|
+
const threads = Array.isArray(payload) ? payload : Array.isArray(payload?.threads) ? payload.threads : Array.isArray(payload?.data) ? payload.data : [];
|
|
5658
|
+
setRemoteThreads(
|
|
5659
|
+
threads.filter(
|
|
5660
|
+
(thread) => Boolean(
|
|
5661
|
+
thread && typeof thread === "object" && typeof thread.thread_id === "string"
|
|
5662
|
+
)
|
|
5663
|
+
)
|
|
5664
|
+
);
|
|
5665
|
+
} finally {
|
|
5666
|
+
setLoadingRemoteThreads(false);
|
|
5667
|
+
}
|
|
5668
|
+
}, [fetchThreadApiJson]);
|
|
5669
|
+
const refreshBillingHeader = React8.useCallback(() => {
|
|
5670
|
+
setWorkspaceRefreshKeys((current) => ({
|
|
5671
|
+
...current,
|
|
5672
|
+
billing: (current.billing ?? 0) + 1
|
|
5673
|
+
}));
|
|
5674
|
+
}, []);
|
|
5675
|
+
const loadRemoteThreadHistory = React8.useCallback(
|
|
5676
|
+
async (threadId) => {
|
|
5677
|
+
const payload = await fetchThreadApiJson(
|
|
5678
|
+
`/chat/threads/${encodeURIComponent(threadId)}?message_limit=80`
|
|
5679
|
+
);
|
|
5680
|
+
return payload;
|
|
5681
|
+
},
|
|
5682
|
+
[fetchThreadApiJson]
|
|
5683
|
+
);
|
|
5684
|
+
const restoreLocalSession = React8.useCallback(
|
|
5685
|
+
(session, options = {}) => {
|
|
5686
|
+
const messages = localSessionMessagesToChatMessages(session);
|
|
5687
|
+
setChatState((prev) => ({
|
|
5688
|
+
...initialChatState,
|
|
5689
|
+
status: "idle",
|
|
5690
|
+
debug: prev.debug,
|
|
5691
|
+
threadId: session.threadId,
|
|
5692
|
+
messages
|
|
5693
|
+
}));
|
|
5694
|
+
if (session.model) {
|
|
5695
|
+
setSelectedModel(session.model);
|
|
5696
|
+
}
|
|
5697
|
+
if (session.projectId) {
|
|
5698
|
+
const matchingProject = projects.find((project) => project.id === session.projectId);
|
|
5699
|
+
if (matchingProject) {
|
|
5700
|
+
setSelectedProject(matchingProject);
|
|
5701
|
+
}
|
|
5702
|
+
}
|
|
5703
|
+
setActiveSelector(null);
|
|
5704
|
+
autoExpandedThinkingMessageIdsRef.current.clear();
|
|
5705
|
+
setExpandedThinkingMessageIds(/* @__PURE__ */ new Set());
|
|
5706
|
+
setTimeout(() => scrollViewRef.current?.scrollToBottom(), 0);
|
|
5707
|
+
if (!options.silent) {
|
|
5708
|
+
setNotice(`Loaded thread: ${truncateForTerminal(session.title, 90)}`);
|
|
5709
|
+
}
|
|
5710
|
+
},
|
|
5711
|
+
[projects]
|
|
5712
|
+
);
|
|
5713
|
+
const restoreRemoteThread = React8.useCallback(
|
|
5714
|
+
async (thread, options = {}) => {
|
|
5715
|
+
setNotice(`Loading thread: ${truncateForTerminal(thread.title || thread.thread_id, 90)}`);
|
|
5716
|
+
const history = await loadRemoteThreadHistory(thread.thread_id);
|
|
5717
|
+
const messages = remoteThreadMessagesToChatMessages(history);
|
|
5718
|
+
const threadId = history.thread_id || thread.thread_id;
|
|
5719
|
+
const hydratedSummary = {
|
|
5720
|
+
...thread,
|
|
5721
|
+
thread_id: threadId,
|
|
5722
|
+
title: history.title || history.thread_head?.title || thread.title,
|
|
5723
|
+
updated_at: history.updated_at || history.thread_head?.updated_at || thread.updated_at,
|
|
5724
|
+
created_at: history.created_at || history.thread_head?.created_at || thread.created_at,
|
|
5725
|
+
message_count: history.message_count ?? history.thread_head?.message_count ?? thread.message_count ?? messages.length,
|
|
5726
|
+
project_id: history.project_id || history.thread_head?.project_id || thread.project_id,
|
|
5727
|
+
project_name: history.project_name || history.thread_head?.project_name || thread.project_name,
|
|
5728
|
+
model: history.model || history.thread_head?.model || thread.model
|
|
5729
|
+
};
|
|
5730
|
+
setRemoteThreads((current) => {
|
|
5731
|
+
const withoutCurrent = current.filter((item) => item.thread_id !== threadId);
|
|
5732
|
+
return [hydratedSummary, ...withoutCurrent];
|
|
5733
|
+
});
|
|
5734
|
+
setChatState((prev) => ({
|
|
5735
|
+
...initialChatState,
|
|
5736
|
+
status: "idle",
|
|
5737
|
+
debug: prev.debug,
|
|
5738
|
+
threadId,
|
|
5739
|
+
messages
|
|
5740
|
+
}));
|
|
5741
|
+
const nextModel = history.model || history.thread_head?.model || thread.model;
|
|
5742
|
+
if (nextModel) {
|
|
5743
|
+
setSelectedModel(nextModel);
|
|
5744
|
+
}
|
|
5745
|
+
const projectId = history.project_id || history.thread_head?.project_id || thread.project_id;
|
|
5746
|
+
if (projectId) {
|
|
5747
|
+
const matchingProject = projects.find((project) => project.id === projectId);
|
|
5748
|
+
if (matchingProject) {
|
|
5749
|
+
setSelectedProject(matchingProject);
|
|
5750
|
+
}
|
|
5751
|
+
}
|
|
5752
|
+
setActiveSelector(null);
|
|
5753
|
+
autoExpandedThinkingMessageIdsRef.current.clear();
|
|
5754
|
+
setExpandedThinkingMessageIds(/* @__PURE__ */ new Set());
|
|
5755
|
+
setTimeout(() => scrollViewRef.current?.scrollToBottom(), 0);
|
|
5756
|
+
if (!options.silent) {
|
|
5757
|
+
setNotice(
|
|
5758
|
+
`Loaded thread: ${truncateForTerminal(
|
|
5759
|
+
history.title || history.thread_head?.title || thread.title || thread.thread_id,
|
|
5760
|
+
90
|
|
5761
|
+
)}`
|
|
5762
|
+
);
|
|
5763
|
+
}
|
|
5764
|
+
},
|
|
5765
|
+
[loadRemoteThreadHistory, projects]
|
|
5766
|
+
);
|
|
5767
|
+
const startNewThread = React8.useCallback(() => {
|
|
5768
|
+
if (isBusyStatus(chatState.status) || controllerRef.current) {
|
|
5769
|
+
setNotice("Stop the running response before switching threads.");
|
|
5770
|
+
return;
|
|
5771
|
+
}
|
|
5772
|
+
queueRef.current = [];
|
|
5773
|
+
setQueuedMessages([]);
|
|
5774
|
+
setChatState((prev) => ({
|
|
5775
|
+
...initialChatState,
|
|
5776
|
+
status: "idle",
|
|
5777
|
+
debug: prev.debug,
|
|
5778
|
+
threadId: void 0,
|
|
5779
|
+
messages: []
|
|
5780
|
+
}));
|
|
5781
|
+
hydratedThreadRef.current = void 0;
|
|
5782
|
+
setActiveSelector(null);
|
|
5783
|
+
autoExpandedThinkingMessageIdsRef.current.clear();
|
|
5784
|
+
setExpandedThinkingMessageIds(/* @__PURE__ */ new Set());
|
|
5785
|
+
setNotice("Started a new thread.");
|
|
5786
|
+
setTimeout(() => scrollViewRef.current?.scrollToTop(), 0);
|
|
5787
|
+
}, [chatState.status]);
|
|
5788
|
+
const selectThread = React8.useCallback(
|
|
5789
|
+
(choice) => {
|
|
5790
|
+
if (choice.kind === "new") {
|
|
5791
|
+
startNewThread();
|
|
5792
|
+
return;
|
|
5793
|
+
}
|
|
5794
|
+
if (isBusyStatus(chatState.status) || controllerRef.current) {
|
|
5795
|
+
setNotice("Stop the running response before switching threads.");
|
|
5796
|
+
return;
|
|
5797
|
+
}
|
|
5798
|
+
if (choice.kind === "remote") {
|
|
5799
|
+
void restoreRemoteThread(choice.thread).catch((error) => {
|
|
5800
|
+
setNotice(`Could not load thread: ${error?.message ?? "Unknown error"}`);
|
|
5801
|
+
});
|
|
5802
|
+
return;
|
|
5803
|
+
}
|
|
5804
|
+
restoreLocalSession(choice.session);
|
|
5805
|
+
},
|
|
5806
|
+
[chatState.status, restoreLocalSession, restoreRemoteThread, startNewThread]
|
|
5141
5807
|
);
|
|
5142
5808
|
const selectProjectForUser = async (token, user) => {
|
|
5143
5809
|
setLoadingProjects(true);
|
|
@@ -5187,6 +5853,55 @@ var App = ({
|
|
|
5187
5853
|
}
|
|
5188
5854
|
return enableTerminalMouse();
|
|
5189
5855
|
}, [mouseTrackingEnabled, phase]);
|
|
5856
|
+
useEffect4(() => {
|
|
5857
|
+
if (phase !== "ready") {
|
|
5858
|
+
return;
|
|
5859
|
+
}
|
|
5860
|
+
void refreshLocalSessions().catch((error) => {
|
|
5861
|
+
setNotice(`Local threads unavailable: ${error?.message ?? "Unknown error"}`);
|
|
5862
|
+
});
|
|
5863
|
+
void refreshRemoteThreads().catch((error) => {
|
|
5864
|
+
setNotice(`Cloud threads unavailable: ${error?.message ?? "Unknown error"}`);
|
|
5865
|
+
});
|
|
5866
|
+
}, [phase, refreshLocalSessions, refreshRemoteThreads]);
|
|
5867
|
+
useEffect4(() => {
|
|
5868
|
+
if (phase !== "ready" || !chatState.threadId || chatState.messages.length > 0 || hydratedThreadRef.current === chatState.threadId) {
|
|
5869
|
+
return;
|
|
5870
|
+
}
|
|
5871
|
+
const threadId = chatState.threadId;
|
|
5872
|
+
hydratedThreadRef.current = threadId;
|
|
5873
|
+
void getSession(threadId, configProfile).then((session) => {
|
|
5874
|
+
if (session) {
|
|
5875
|
+
restoreLocalSession(session, { silent: true });
|
|
5876
|
+
return;
|
|
5877
|
+
}
|
|
5878
|
+
return loadRemoteThreadHistory(threadId).then(
|
|
5879
|
+
(history) => restoreRemoteThread(
|
|
5880
|
+
{
|
|
5881
|
+
thread_id: history.thread_id || threadId,
|
|
5882
|
+
title: history.title,
|
|
5883
|
+
updated_at: history.updated_at,
|
|
5884
|
+
created_at: history.created_at,
|
|
5885
|
+
message_count: history.message_count ?? history.messages_page?.length ?? history.thread_messages?.length ?? history.messages?.length ?? 0,
|
|
5886
|
+
project_id: history.project_id,
|
|
5887
|
+
project_name: history.project_name,
|
|
5888
|
+
model: history.model
|
|
5889
|
+
},
|
|
5890
|
+
{ silent: true }
|
|
5891
|
+
)
|
|
5892
|
+
);
|
|
5893
|
+
}).catch((error) => {
|
|
5894
|
+
setNotice(`Could not load thread history: ${error?.message ?? "Unknown error"}`);
|
|
5895
|
+
});
|
|
5896
|
+
}, [
|
|
5897
|
+
chatState.messages.length,
|
|
5898
|
+
chatState.threadId,
|
|
5899
|
+
configProfile,
|
|
5900
|
+
loadRemoteThreadHistory,
|
|
5901
|
+
phase,
|
|
5902
|
+
restoreLocalSession,
|
|
5903
|
+
restoreRemoteThread
|
|
5904
|
+
]);
|
|
5190
5905
|
useEffect4(() => {
|
|
5191
5906
|
if (phase !== "ready") {
|
|
5192
5907
|
return;
|
|
@@ -5204,11 +5919,21 @@ var App = ({
|
|
|
5204
5919
|
return;
|
|
5205
5920
|
}
|
|
5206
5921
|
setBillingHeaderError(void 0);
|
|
5207
|
-
|
|
5922
|
+
const usageRange = thirtyDayUsageRange();
|
|
5923
|
+
Promise.all([
|
|
5924
|
+
getBillingEntitlement({ baseUrl: apiBase, authToken }),
|
|
5925
|
+
getBillingUsageSummary({
|
|
5926
|
+
baseUrl: apiBase,
|
|
5927
|
+
authToken,
|
|
5928
|
+
startAt: usageRange.startAt,
|
|
5929
|
+
endAt: usageRange.endAt,
|
|
5930
|
+
granularity: "day"
|
|
5931
|
+
}).catch(() => null)
|
|
5932
|
+
]).then(([entitlement, usageSummary]) => {
|
|
5208
5933
|
if (cancelled) {
|
|
5209
5934
|
return;
|
|
5210
5935
|
}
|
|
5211
|
-
setBillingHeader(billingHeaderFromEntitlement(entitlement));
|
|
5936
|
+
setBillingHeader(billingHeaderFromEntitlement(entitlement, usageSummary));
|
|
5212
5937
|
}).catch((error) => {
|
|
5213
5938
|
if (cancelled) {
|
|
5214
5939
|
return;
|
|
@@ -5239,7 +5964,7 @@ var App = ({
|
|
|
5239
5964
|
setIsLoggingIn(true);
|
|
5240
5965
|
setLoaderStep(1);
|
|
5241
5966
|
try {
|
|
5242
|
-
const { login } = await import("./dist-
|
|
5967
|
+
const { login } = await import("./dist-TBAQ5KOK.js");
|
|
5243
5968
|
const newToken = await login(baseUrl, {
|
|
5244
5969
|
headless: Boolean(process.env.SSH_TTY || process.env.CI)
|
|
5245
5970
|
});
|
|
@@ -5435,7 +6160,8 @@ var App = ({
|
|
|
5435
6160
|
getSubscriptionBillingInfo,
|
|
5436
6161
|
getTopUpPacks,
|
|
5437
6162
|
getBillingNotifications,
|
|
5438
|
-
getCreditStatus
|
|
6163
|
+
getCreditStatus,
|
|
6164
|
+
getBillingUsageCreditsUsed
|
|
5439
6165
|
}
|
|
5440
6166
|
});
|
|
5441
6167
|
if (!cancelled) {
|
|
@@ -5528,7 +6254,7 @@ var App = ({
|
|
|
5528
6254
|
};
|
|
5529
6255
|
const appendUserMessage = (content, options) => {
|
|
5530
6256
|
const message = {
|
|
5531
|
-
id: options?.id ??
|
|
6257
|
+
id: options?.id ?? randomUUID2(),
|
|
5532
6258
|
role: "user",
|
|
5533
6259
|
content,
|
|
5534
6260
|
queued: options?.queued,
|
|
@@ -5629,7 +6355,7 @@ var App = ({
|
|
|
5629
6355
|
const enqueueMessage = (text) => {
|
|
5630
6356
|
const trimmed = text.trim();
|
|
5631
6357
|
if (!trimmed) return;
|
|
5632
|
-
const queued = { id:
|
|
6358
|
+
const queued = { id: randomUUID2(), text: trimmed };
|
|
5633
6359
|
queueRef.current.push(queued);
|
|
5634
6360
|
syncQueueState();
|
|
5635
6361
|
appendUserMessage(trimmed, { id: queued.id, queued: true });
|
|
@@ -5737,6 +6463,15 @@ var App = ({
|
|
|
5737
6463
|
hasActiveResponse ? "Response canceled. Esc or /stop cancels running chat." : "No running response to cancel."
|
|
5738
6464
|
);
|
|
5739
6465
|
};
|
|
6466
|
+
const selectAgentProfileById = (profileId, label) => {
|
|
6467
|
+
setSelectedAgentProfileId(profileId);
|
|
6468
|
+
if (profileId) {
|
|
6469
|
+
setSelectedMode("agent");
|
|
6470
|
+
setNotice(`Profile selected: ${label}. Mode set to Agent.`);
|
|
6471
|
+
return;
|
|
6472
|
+
}
|
|
6473
|
+
setNotice("Agent Profile cleared. Default chat flow active.");
|
|
6474
|
+
};
|
|
5740
6475
|
const handlePromptSubmit = (value) => {
|
|
5741
6476
|
const cleanedValue = sanitizeTerminalMultilineInput(value);
|
|
5742
6477
|
const promptCommand = resolvePromptCommand(cleanedValue, promptCompletionContext);
|
|
@@ -5751,13 +6486,43 @@ var App = ({
|
|
|
5751
6486
|
setSelectedProject(promptCommand.project);
|
|
5752
6487
|
setNotice(`Project selected: ${promptCommand.project.name}`);
|
|
5753
6488
|
return;
|
|
6489
|
+
case "setThread": {
|
|
6490
|
+
if (promptCommand.threadId === "new") {
|
|
6491
|
+
startNewThread();
|
|
6492
|
+
return;
|
|
6493
|
+
}
|
|
6494
|
+
const remoteThread = remoteThreads.find(
|
|
6495
|
+
(candidate) => candidate.thread_id === promptCommand.threadId
|
|
6496
|
+
);
|
|
6497
|
+
if (remoteThread) {
|
|
6498
|
+
selectThread({ kind: "remote", thread: remoteThread });
|
|
6499
|
+
return;
|
|
6500
|
+
}
|
|
6501
|
+
const session = localSessions.find(
|
|
6502
|
+
(candidate) => candidate.threadId === promptCommand.threadId
|
|
6503
|
+
);
|
|
6504
|
+
if (!session) {
|
|
6505
|
+
setNotice(`Thread not loaded: ${promptCommand.label}`);
|
|
6506
|
+
return;
|
|
6507
|
+
}
|
|
6508
|
+
selectThread({ kind: "session", session });
|
|
6509
|
+
return;
|
|
6510
|
+
}
|
|
5754
6511
|
case "setModel":
|
|
5755
6512
|
setSelectedModel(promptCommand.model);
|
|
5756
6513
|
setNotice(`Model selected: ${promptCommand.label}`);
|
|
5757
6514
|
return;
|
|
5758
6515
|
case "setMode":
|
|
5759
6516
|
setSelectedMode(promptCommand.mode);
|
|
5760
|
-
|
|
6517
|
+
if (promptCommand.mode === "ask") {
|
|
6518
|
+
setSelectedAgentProfileId("");
|
|
6519
|
+
}
|
|
6520
|
+
setNotice(
|
|
6521
|
+
promptCommand.mode === "ask" ? "Mode selected: Ask. Agent Profile cleared." : `Mode selected: ${promptCommand.label}`
|
|
6522
|
+
);
|
|
6523
|
+
return;
|
|
6524
|
+
case "setProfile":
|
|
6525
|
+
selectAgentProfileById(promptCommand.profileId, promptCommand.label);
|
|
5761
6526
|
return;
|
|
5762
6527
|
case "toggleThinking":
|
|
5763
6528
|
toggleLatestThinking();
|
|
@@ -5772,6 +6537,12 @@ var App = ({
|
|
|
5772
6537
|
setActiveWorkspaceTab("help");
|
|
5773
6538
|
setNotice(void 0);
|
|
5774
6539
|
return;
|
|
6540
|
+
case "showStarters":
|
|
6541
|
+
setStarterSelectionsOpen(true);
|
|
6542
|
+
setPromptInputActive(true);
|
|
6543
|
+
setFocusedControl("followup:0");
|
|
6544
|
+
setNotice("Starter selections shown. Use Tab/Enter or click a starter.");
|
|
6545
|
+
return;
|
|
5775
6546
|
case "unknown":
|
|
5776
6547
|
setNotice(promptCommand.message);
|
|
5777
6548
|
return;
|
|
@@ -5797,6 +6568,10 @@ var App = ({
|
|
|
5797
6568
|
const handlePromptChange = (value) => {
|
|
5798
6569
|
const cleanedValue = sanitizeTerminalMultilineInput(value);
|
|
5799
6570
|
completionCycleRef.current = void 0;
|
|
6571
|
+
setPromptInputActive(true);
|
|
6572
|
+
if (!isStarterSlashCommandInput(cleanedValue)) {
|
|
6573
|
+
setStarterSelectionsOpen(false);
|
|
6574
|
+
}
|
|
5800
6575
|
setPromptInputScrollOffset(
|
|
5801
6576
|
getInputViewport({
|
|
5802
6577
|
value: cleanedValue,
|
|
@@ -5833,15 +6608,15 @@ var App = ({
|
|
|
5833
6608
|
return;
|
|
5834
6609
|
}
|
|
5835
6610
|
}
|
|
5836
|
-
const threadId = chatState.threadId ??
|
|
6611
|
+
const threadId = chatState.threadId ?? randomUUID2();
|
|
5837
6612
|
const now = Date.now();
|
|
5838
6613
|
const userMessage = options.hitlResume || options.queuedMessageId ? void 0 : {
|
|
5839
|
-
id:
|
|
6614
|
+
id: randomUUID2(),
|
|
5840
6615
|
role: "user",
|
|
5841
6616
|
content: trimmed,
|
|
5842
6617
|
createdAt: now
|
|
5843
6618
|
};
|
|
5844
|
-
|
|
6619
|
+
const prepareConnectingState = (prev) => ({
|
|
5845
6620
|
...prev,
|
|
5846
6621
|
threadId,
|
|
5847
6622
|
status: "connecting",
|
|
@@ -5861,7 +6636,12 @@ var App = ({
|
|
|
5861
6636
|
updatedAt: now
|
|
5862
6637
|
} : m.role === "assistant" && m.pending && !options.hitlResume ? { ...m, pending: false, updatedAt: now } : m
|
|
5863
6638
|
).concat(userMessage ? [userMessage] : [])
|
|
5864
|
-
})
|
|
6639
|
+
});
|
|
6640
|
+
let latestChatState = prepareConnectingState(chatState);
|
|
6641
|
+
setChatState((prev) => {
|
|
6642
|
+
latestChatState = prepareConnectingState(prev);
|
|
6643
|
+
return latestChatState;
|
|
6644
|
+
});
|
|
5865
6645
|
const ctrl = new AbortController();
|
|
5866
6646
|
controllerRef.current = ctrl;
|
|
5867
6647
|
let shouldDrainQueue = false;
|
|
@@ -5870,6 +6650,8 @@ var App = ({
|
|
|
5870
6650
|
let rafId = null;
|
|
5871
6651
|
let lastUpdateTime = Date.now();
|
|
5872
6652
|
let sawHitlRequest = false;
|
|
6653
|
+
let streamToken = token;
|
|
6654
|
+
let retriedAfterAuthRefresh = false;
|
|
5873
6655
|
const flushChunks = (immediate = false) => {
|
|
5874
6656
|
if (pendingChunks.length === 0) {
|
|
5875
6657
|
rafId = null;
|
|
@@ -5879,6 +6661,9 @@ var App = ({
|
|
|
5879
6661
|
pendingChunks = [];
|
|
5880
6662
|
rafId = null;
|
|
5881
6663
|
lastUpdateTime = Date.now();
|
|
6664
|
+
for (const chunk of chunksToProcess) {
|
|
6665
|
+
latestChatState = reduceChunk(latestChatState, chunk);
|
|
6666
|
+
}
|
|
5882
6667
|
const applyChunks = () => {
|
|
5883
6668
|
setChatState((prev) => {
|
|
5884
6669
|
let state = prev;
|
|
@@ -5904,39 +6689,59 @@ var App = ({
|
|
|
5904
6689
|
rafId = setTimeout(flushChunks, minInterval - timeSinceLastUpdate);
|
|
5905
6690
|
}
|
|
5906
6691
|
};
|
|
5907
|
-
|
|
5908
|
-
|
|
5909
|
-
|
|
5910
|
-
|
|
5911
|
-
|
|
5912
|
-
|
|
5913
|
-
|
|
5914
|
-
|
|
5915
|
-
|
|
5916
|
-
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5921
|
-
|
|
5922
|
-
|
|
5923
|
-
|
|
5924
|
-
|
|
5925
|
-
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
6692
|
+
while (true) {
|
|
6693
|
+
try {
|
|
6694
|
+
for await (const chunk of streamChat({
|
|
6695
|
+
baseUrl,
|
|
6696
|
+
authToken: streamToken,
|
|
6697
|
+
message: options.hitlResume ? "" : trimmed,
|
|
6698
|
+
threadId,
|
|
6699
|
+
user: {
|
|
6700
|
+
id: selectedProject?.user_id ?? currentUserId ?? defaultUser.id,
|
|
6701
|
+
name: userName
|
|
6702
|
+
},
|
|
6703
|
+
project: selectedProject ?? (currentUserId ? { ...defaultProject, user_id: currentUserId } : defaultProject),
|
|
6704
|
+
settings: {
|
|
6705
|
+
...selectedModel ? { model: selectedModel } : {},
|
|
6706
|
+
mode: selectedMode
|
|
6707
|
+
},
|
|
6708
|
+
agentProfileId: selectedAgentProfileId || void 0,
|
|
6709
|
+
streamingMode: debug ? "DEBUG" : "USER",
|
|
6710
|
+
signal: ctrl.signal,
|
|
6711
|
+
debug,
|
|
6712
|
+
hitlResume: options.hitlResume,
|
|
6713
|
+
completeAfterResponse: true,
|
|
6714
|
+
responseCompletionGraceMs: 5e3
|
|
6715
|
+
})) {
|
|
6716
|
+
if (chunk.type === "hitl_request") {
|
|
6717
|
+
sawHitlRequest = true;
|
|
6718
|
+
pendingChunks.push(chunk);
|
|
6719
|
+
if (rafId !== null) {
|
|
6720
|
+
clearTimeout(rafId);
|
|
6721
|
+
rafId = null;
|
|
6722
|
+
}
|
|
6723
|
+
flushChunks(true);
|
|
6724
|
+
break;
|
|
6725
|
+
}
|
|
6726
|
+
pendingChunks.push(chunk);
|
|
6727
|
+
scheduleFlush();
|
|
5934
6728
|
}
|
|
5935
|
-
flushChunks(true);
|
|
5936
6729
|
break;
|
|
6730
|
+
} catch (error) {
|
|
6731
|
+
if (!accessKey && !retriedAfterAuthRefresh && isExpiredDeviceTokenStreamError(error)) {
|
|
6732
|
+
retriedAfterAuthRefresh = true;
|
|
6733
|
+
if (rafId !== null) {
|
|
6734
|
+
clearTimeout(rafId);
|
|
6735
|
+
rafId = null;
|
|
6736
|
+
}
|
|
6737
|
+
pendingChunks = [];
|
|
6738
|
+
streamToken = await getAuthToken({ baseUrl, forceRefresh: true });
|
|
6739
|
+
setAuthToken(streamToken);
|
|
6740
|
+
setNotice("Session refreshed. Retrying your request...");
|
|
6741
|
+
continue;
|
|
6742
|
+
}
|
|
6743
|
+
throw error;
|
|
5937
6744
|
}
|
|
5938
|
-
pendingChunks.push(chunk);
|
|
5939
|
-
scheduleFlush();
|
|
5940
6745
|
}
|
|
5941
6746
|
if (rafId !== null) {
|
|
5942
6747
|
clearTimeout(rafId);
|
|
@@ -5946,7 +6751,26 @@ var App = ({
|
|
|
5946
6751
|
setNotice(`Action required. Answer in CLI or open frontend: ${frontendThreadUrl}`);
|
|
5947
6752
|
} else {
|
|
5948
6753
|
shouldDrainQueue = true;
|
|
6754
|
+
latestChatState = completeActiveAssistantMessage(latestChatState);
|
|
5949
6755
|
setChatState((prev) => completeActiveAssistantMessage(prev));
|
|
6756
|
+
const finalMessage = [...latestChatState.messages].reverse().find((message) => message.role === "assistant");
|
|
6757
|
+
const finalResponse = collapseRepeatedAssistantText(finalMessage?.content ?? "");
|
|
6758
|
+
if (trimmed && finalResponse.trim()) {
|
|
6759
|
+
try {
|
|
6760
|
+
await recordSessionTurn({
|
|
6761
|
+
threadId,
|
|
6762
|
+
question: trimmed,
|
|
6763
|
+
response: finalResponse,
|
|
6764
|
+
project: selectedProject ? { id: selectedProject.id, name: selectedProject.name } : void 0,
|
|
6765
|
+
model: selectedModel,
|
|
6766
|
+
profile: configProfile
|
|
6767
|
+
});
|
|
6768
|
+
void refreshLocalSessions().catch(() => void 0);
|
|
6769
|
+
void refreshRemoteThreads().catch(() => void 0);
|
|
6770
|
+
} catch (error) {
|
|
6771
|
+
setNotice(`Response complete. Local thread history was not saved: ${error?.message ?? "Unknown error"}`);
|
|
6772
|
+
}
|
|
6773
|
+
}
|
|
5950
6774
|
}
|
|
5951
6775
|
} catch (error) {
|
|
5952
6776
|
const isAbort = ctrl.signal.aborted || error?.name === "AbortError" || error?.message === "This operation was aborted";
|
|
@@ -5977,6 +6801,7 @@ var App = ({
|
|
|
5977
6801
|
if (controllerRef.current === ctrl) {
|
|
5978
6802
|
controllerRef.current = null;
|
|
5979
6803
|
}
|
|
6804
|
+
refreshBillingHeader();
|
|
5980
6805
|
if (shouldDrainQueue && queueRef.current.length > 0) {
|
|
5981
6806
|
setTimeout(dequeueAndSend, 0);
|
|
5982
6807
|
}
|
|
@@ -5992,12 +6817,14 @@ var App = ({
|
|
|
5992
6817
|
const hasThinkingSteps = Boolean(latestThinkingMessage);
|
|
5993
6818
|
const hasCancellableReasoning = hasCancellableAssistantWork(chatState.messages);
|
|
5994
6819
|
const latestFollowUps = latestAssistant?.followUpQuestions?.filter(Boolean) ?? [];
|
|
6820
|
+
const starterSlashCommandActive = isStarterSlashCommandInput(input);
|
|
5995
6821
|
const promptSuggestions = getPromptSuggestions({
|
|
5996
6822
|
latestFollowUps,
|
|
5997
6823
|
messages: chatState.messages,
|
|
5998
6824
|
mode: selectedMode,
|
|
5999
6825
|
project: selectedProject,
|
|
6000
|
-
limit: terminalSize.columns < 110 ? 3 : 4
|
|
6826
|
+
limit: terminalSize.columns < 110 ? 3 : 4,
|
|
6827
|
+
showStarters: starterSelectionsOpen || starterSlashCommandActive
|
|
6001
6828
|
});
|
|
6002
6829
|
const visiblePromptSuggestions = promptSuggestions.prompts.slice(
|
|
6003
6830
|
0,
|
|
@@ -6032,7 +6859,9 @@ var App = ({
|
|
|
6032
6859
|
visiblePromptSuggestions.length
|
|
6033
6860
|
);
|
|
6034
6861
|
const splitChatLayout = shouldUseSplitChatLayout(terminalSize);
|
|
6862
|
+
const promptControlsCompact = terminalSize.columns < 96;
|
|
6035
6863
|
const focusedFollowUpIndex = focusFollowUpIndex(focusedControl);
|
|
6864
|
+
const activeChatPanel = chatPanelFocusForControl(focusedControl);
|
|
6036
6865
|
const controlFocusOrder = buildControlFocusOrder({
|
|
6037
6866
|
hasThinkingSteps,
|
|
6038
6867
|
followUpCount: visiblePromptSuggestions.length
|
|
@@ -6072,16 +6901,9 @@ var App = ({
|
|
|
6072
6901
|
24,
|
|
6073
6902
|
splitChatLayout ? (chatThreadPanelWidth ?? chatAvailableWidth) - 8 : chatAvailableWidth - 8
|
|
6074
6903
|
);
|
|
6075
|
-
const chatThreadHeight = Math.max(1, tuiLayout.threadHeight - bottomControlsRows);
|
|
6076
6904
|
const activeWorkspacePanelState = workspacePanelStore[activeWorkspaceTab] ?? createWorkspacePanelState(activeWorkspaceTab, "loading");
|
|
6077
6905
|
const activeTablePage = tablePageByTab[activeWorkspaceTab] ?? 0;
|
|
6078
6906
|
const bannerRenderedRows = bannerDisabled ? 0 : estimateBannerRows({ detailsCount: headerDetails.length, columns: bannerContentColumns });
|
|
6079
|
-
const workspaceHeaderRows = bannerRenderedRows + 3 + (notice ? 1 : 0);
|
|
6080
|
-
const workspaceFooterRows = bottomControlsRows + 1 + (activeSelector === "project" ? tuiLayout.selectorLimit + 4 : 0);
|
|
6081
|
-
const workspacePanelViewportRows = Math.max(
|
|
6082
|
-
3,
|
|
6083
|
-
terminalSize.rows - workspaceHeaderRows - workspaceFooterRows
|
|
6084
|
-
);
|
|
6085
6907
|
const workspaceContentWidth = Math.max(24, terminalSize.columns - tuiLayout.paddingX * 2 - 3);
|
|
6086
6908
|
const workspaceTabStartRow = useMemo(() => {
|
|
6087
6909
|
const rootContentStartRow = 1;
|
|
@@ -6107,10 +6929,55 @@ var App = ({
|
|
|
6107
6929
|
}),
|
|
6108
6930
|
[terminalSize.columns, tuiLayout.paddingX, workspaceTabStartRow]
|
|
6109
6931
|
);
|
|
6932
|
+
const workspaceTabButtonRows = useMemo(() => {
|
|
6933
|
+
if (!workspaceTabHitAreas.length) {
|
|
6934
|
+
return 0;
|
|
6935
|
+
}
|
|
6936
|
+
const firstRow = Math.min(...workspaceTabHitAreas.map((area) => area.startRow));
|
|
6937
|
+
const lastRow = Math.max(...workspaceTabHitAreas.map((area) => area.endRow));
|
|
6938
|
+
return Math.max(0, lastRow - firstRow + 1);
|
|
6939
|
+
}, [workspaceTabHitAreas]);
|
|
6940
|
+
const workspaceTabBarRows = (bannerDisabled ? 3 : 0) + workspaceTabButtonRows + 1 + (bannerDisabled ? 1 : 0);
|
|
6941
|
+
const promptPanelRows = estimatePromptPanelRows({
|
|
6942
|
+
inputRows: promptInputRows,
|
|
6943
|
+
suggestionRows: promptSuggestionRows,
|
|
6944
|
+
compact: promptControlsCompact,
|
|
6945
|
+
hasThinkingSteps,
|
|
6946
|
+
includeControls: !splitChatLayout
|
|
6947
|
+
});
|
|
6948
|
+
const searchPromptPanelRows = estimatePromptPanelRows({
|
|
6949
|
+
inputRows: promptInputRows,
|
|
6950
|
+
suggestionRows: 0,
|
|
6951
|
+
compact: promptControlsCompact,
|
|
6952
|
+
hasThinkingSteps: false,
|
|
6953
|
+
includeControls: false
|
|
6954
|
+
});
|
|
6955
|
+
const workspaceHeaderRows = bannerRenderedRows + workspaceTabBarRows + 2 + (notice ? 1 : 0);
|
|
6956
|
+
const workspaceFooterRows = bottomControlsRows + (activeSelector === "project" ? tuiLayout.selectorLimit + 4 : 0);
|
|
6957
|
+
const workspacePanelViewportRows = getMiddleViewportRows(terminalSize, {
|
|
6958
|
+
headerRows: workspaceHeaderRows,
|
|
6959
|
+
footerRows: workspaceFooterRows
|
|
6960
|
+
});
|
|
6961
|
+
const workspacePanelBodyRows = getFramedBodyRows(workspacePanelViewportRows);
|
|
6962
|
+
const workspacePanelOverflowing = workspaceContentHeight > workspaceViewportHeight;
|
|
6963
|
+
const workspacePanelBodyWidth = Math.max(
|
|
6964
|
+
24,
|
|
6965
|
+
workspaceContentWidth - (workspacePanelOverflowing ? 7 : 5)
|
|
6966
|
+
);
|
|
6967
|
+
const chatHeaderRows = bannerRenderedRows + workspaceTabBarRows + 2;
|
|
6968
|
+
const chatFooterRows = bottomControlsRows + (isSearching ? searchPromptPanelRows : activeSelector ? 0 : promptPanelRows);
|
|
6969
|
+
const chatMiddleViewportRows = getMiddleViewportRows(terminalSize, {
|
|
6970
|
+
headerRows: chatHeaderRows,
|
|
6971
|
+
footerRows: chatFooterRows
|
|
6972
|
+
});
|
|
6973
|
+
const chatMiddleAuxiliaryRows = (isSearching ? 3 : 0) + (queuedMessages.length > 0 ? 4 : 0) + (notice ? 1 : 0) + (errorText ? 5 : 0) + (chatState.status === "hitl_waiting" && chatState.hitl?.waiting ? 7 : 0) + (activeSelector ? tuiLayout.selectorLimit + 4 : 0);
|
|
6974
|
+
const chatMainPanelRows = Math.max(4, chatMiddleViewportRows - chatMiddleAuxiliaryRows);
|
|
6975
|
+
const chatThreadHeight = getFramedBodyRows(chatMainPanelRows);
|
|
6976
|
+
const chatMiddleOverflowing = chatMiddleContentHeight > chatMiddleViewportHeight;
|
|
6110
6977
|
const selectorControlStartRow = useMemo(
|
|
6111
6978
|
() => {
|
|
6112
6979
|
if (!splitChatLayout) {
|
|
6113
|
-
return Math.max(1, terminalSize.rows - (
|
|
6980
|
+
return Math.max(1, terminalSize.rows - (promptControlsCompact ? 7 : 5));
|
|
6114
6981
|
}
|
|
6115
6982
|
const auxiliaryRows = (isSearching ? 3 : 0) + (queuedMessages.length > 0 ? 4 : 0) + (notice ? 1 : 0) + (errorText ? 5 : 0);
|
|
6116
6983
|
return workspaceTabStartRow + 9 + auxiliaryRows;
|
|
@@ -6122,13 +6989,13 @@ var App = ({
|
|
|
6122
6989
|
queuedMessages.length,
|
|
6123
6990
|
splitChatLayout,
|
|
6124
6991
|
terminalSize.rows,
|
|
6125
|
-
|
|
6992
|
+
promptControlsCompact,
|
|
6126
6993
|
workspaceTabStartRow
|
|
6127
6994
|
]
|
|
6128
6995
|
);
|
|
6129
6996
|
const selectorControlHitAreas = useMemo(
|
|
6130
6997
|
() => getSelectorControlHitAreas({
|
|
6131
|
-
compact:
|
|
6998
|
+
compact: promptControlsCompact || splitChatLayout,
|
|
6132
6999
|
hasThinkingSteps,
|
|
6133
7000
|
startColumn: tuiLayout.paddingX + 1,
|
|
6134
7001
|
startRow: selectorControlStartRow,
|
|
@@ -6140,7 +7007,7 @@ var App = ({
|
|
|
6140
7007
|
selectorControlStartRow,
|
|
6141
7008
|
splitChatLayout,
|
|
6142
7009
|
terminalSize.columns,
|
|
6143
|
-
|
|
7010
|
+
promptControlsCompact,
|
|
6144
7011
|
tuiLayout.paddingX
|
|
6145
7012
|
]
|
|
6146
7013
|
);
|
|
@@ -6150,7 +7017,7 @@ var App = ({
|
|
|
6150
7017
|
terminalSize.rows - estimatePromptPanelRows({
|
|
6151
7018
|
inputRows: promptInputRows,
|
|
6152
7019
|
suggestionRows: promptSuggestionRows,
|
|
6153
|
-
compact:
|
|
7020
|
+
compact: promptControlsCompact,
|
|
6154
7021
|
hasThinkingSteps,
|
|
6155
7022
|
includeControls: !splitChatLayout
|
|
6156
7023
|
}) + 1
|
|
@@ -6160,7 +7027,7 @@ var App = ({
|
|
|
6160
7027
|
promptInputRows,
|
|
6161
7028
|
promptSuggestionRows,
|
|
6162
7029
|
terminalSize.rows,
|
|
6163
|
-
|
|
7030
|
+
promptControlsCompact,
|
|
6164
7031
|
splitChatLayout
|
|
6165
7032
|
]
|
|
6166
7033
|
);
|
|
@@ -6174,12 +7041,15 @@ var App = ({
|
|
|
6174
7041
|
previousWorkspaceTabRef.current = activeWorkspaceTab;
|
|
6175
7042
|
setScrollOffset(0);
|
|
6176
7043
|
setContentHeight(0);
|
|
7044
|
+
setChatMiddleScrollOffset(0);
|
|
7045
|
+
setChatMiddleContentHeight(0);
|
|
6177
7046
|
setWorkspaceScrollOffset(0);
|
|
6178
7047
|
setWorkspaceContentHeight(0);
|
|
6179
7048
|
}
|
|
6180
7049
|
if (activeWorkspaceTab !== "chat") {
|
|
6181
7050
|
setTimeout(() => workspaceScrollViewRef.current?.scrollToTop(), 0);
|
|
6182
7051
|
} else {
|
|
7052
|
+
setTimeout(() => chatMiddleScrollViewRef.current?.scrollToTop(), 0);
|
|
6183
7053
|
setTimeout(() => scrollViewRef.current?.scrollToTop(), 0);
|
|
6184
7054
|
}
|
|
6185
7055
|
}, [activeWorkspaceTab]);
|
|
@@ -6189,6 +7059,7 @@ var App = ({
|
|
|
6189
7059
|
return;
|
|
6190
7060
|
}
|
|
6191
7061
|
setInput("");
|
|
7062
|
+
setStarterSelectionsOpen(false);
|
|
6192
7063
|
completionCycleRef.current = void 0;
|
|
6193
7064
|
const noticePrefix = promptSuggestions.kind === "starter" ? "Starter" : "Follow-up";
|
|
6194
7065
|
setNotice(`${noticePrefix} queued: ${truncateForTerminal(oneLine(question), 90)}`);
|
|
@@ -6207,6 +7078,10 @@ var App = ({
|
|
|
6207
7078
|
toggleLatestThinking();
|
|
6208
7079
|
return;
|
|
6209
7080
|
}
|
|
7081
|
+
if (focusedControl === "threadPanel") {
|
|
7082
|
+
setNotice("Thread selected. Use arrows, Page Up/Down, or mouse wheel to scroll.");
|
|
7083
|
+
return;
|
|
7084
|
+
}
|
|
6210
7085
|
const followUpIndex = focusFollowUpIndex(focusedControl);
|
|
6211
7086
|
if (followUpIndex !== void 0) {
|
|
6212
7087
|
submitFollowUp(followUpIndex);
|
|
@@ -6244,6 +7119,11 @@ var App = ({
|
|
|
6244
7119
|
setNotice(void 0);
|
|
6245
7120
|
return;
|
|
6246
7121
|
}
|
|
7122
|
+
if (splitChatLayout && mouseEvent.y >= selectorControlStartRow && mouseEvent.y < promptPanelStartRow && mouseEvent.x >= tuiLayout.paddingX + chatContextPanelWidth + chatSplitGap) {
|
|
7123
|
+
setFocusedControl("threadPanel");
|
|
7124
|
+
setNotice(void 0);
|
|
7125
|
+
return;
|
|
7126
|
+
}
|
|
6247
7127
|
}
|
|
6248
7128
|
if (mouseEvent.released) {
|
|
6249
7129
|
return;
|
|
@@ -6251,7 +7131,7 @@ var App = ({
|
|
|
6251
7131
|
if (!visiblePromptSuggestions.length) {
|
|
6252
7132
|
return;
|
|
6253
7133
|
}
|
|
6254
|
-
const promptAreaTop =
|
|
7134
|
+
const promptAreaTop = promptPanelStartRow;
|
|
6255
7135
|
if (mouseEvent.y < promptAreaTop) {
|
|
6256
7136
|
return;
|
|
6257
7137
|
}
|
|
@@ -6296,7 +7176,11 @@ var App = ({
|
|
|
6296
7176
|
);
|
|
6297
7177
|
} else if (activeWorkspaceTab !== "chat") {
|
|
6298
7178
|
workspaceScrollViewRef.current?.scrollBy(mouseWheelDelta);
|
|
7179
|
+
} else if (chatMiddleOverflowing) {
|
|
7180
|
+
setFocusedControl("threadPanel");
|
|
7181
|
+
chatMiddleScrollViewRef.current?.scrollBy(mouseWheelDelta);
|
|
6299
7182
|
} else {
|
|
7183
|
+
setFocusedControl("threadPanel");
|
|
6300
7184
|
scrollViewRef.current?.scrollBy(mouseWheelDelta);
|
|
6301
7185
|
}
|
|
6302
7186
|
} else {
|
|
@@ -6309,7 +7193,7 @@ var App = ({
|
|
|
6309
7193
|
return;
|
|
6310
7194
|
}
|
|
6311
7195
|
const lowerInput = inputKey.toLowerCase();
|
|
6312
|
-
if (phase === "ready" && !input.trim()) {
|
|
7196
|
+
if (phase === "ready" && (!input.trim() || !promptInputActive)) {
|
|
6313
7197
|
const shortcutTab = workspaceTabFromShortcut(inputKey);
|
|
6314
7198
|
if (shortcutTab) {
|
|
6315
7199
|
setActiveWorkspaceTab(shortcutTab);
|
|
@@ -6441,7 +7325,7 @@ var App = ({
|
|
|
6441
7325
|
}
|
|
6442
7326
|
return;
|
|
6443
7327
|
}
|
|
6444
|
-
if ((key.tab || inputKey === " ") && input.trimStart().startsWith("/")) {
|
|
7328
|
+
if (promptInputActive && (key.tab || inputKey === " ") && input.trimStart().startsWith("/")) {
|
|
6445
7329
|
const completion = completePromptInput(
|
|
6446
7330
|
input,
|
|
6447
7331
|
promptCompletionContext,
|
|
@@ -6468,7 +7352,7 @@ var App = ({
|
|
|
6468
7352
|
}
|
|
6469
7353
|
return;
|
|
6470
7354
|
}
|
|
6471
|
-
if (key.rightArrow && !key.ctrl && !key.meta && promptGhostSuffix) {
|
|
7355
|
+
if (promptInputActive && key.rightArrow && !key.ctrl && !key.meta && promptGhostSuffix) {
|
|
6472
7356
|
const nextValue = `${input}${promptGhostSuffix}`;
|
|
6473
7357
|
setInput(nextValue);
|
|
6474
7358
|
setPromptInputScrollOffset(
|
|
@@ -6515,7 +7399,7 @@ var App = ({
|
|
|
6515
7399
|
return;
|
|
6516
7400
|
}
|
|
6517
7401
|
}
|
|
6518
|
-
if (phase === "ready" && !input.trim()) {
|
|
7402
|
+
if (phase === "ready" && (!input.trim() || !promptInputActive)) {
|
|
6519
7403
|
if (key.tab || inputKey === " ") {
|
|
6520
7404
|
setFocusedControl((current) => nextControlFocus(current, controlFocusOrder));
|
|
6521
7405
|
return;
|
|
@@ -6528,6 +7412,30 @@ var App = ({
|
|
|
6528
7412
|
setFocusedControl((current) => nextControlFocus(current, controlFocusOrder));
|
|
6529
7413
|
return;
|
|
6530
7414
|
}
|
|
7415
|
+
if (key.upArrow && !key.ctrl && !key.meta && !key.shift) {
|
|
7416
|
+
if (focusedControl === "threadPanel") {
|
|
7417
|
+
if (chatMiddleOverflowing) {
|
|
7418
|
+
chatMiddleScrollViewRef.current?.scrollBy(-1);
|
|
7419
|
+
} else {
|
|
7420
|
+
scrollViewRef.current?.scrollBy(-1);
|
|
7421
|
+
}
|
|
7422
|
+
} else {
|
|
7423
|
+
setFocusedControl((current) => nextControlFocus(current, controlFocusOrder, -1));
|
|
7424
|
+
}
|
|
7425
|
+
return;
|
|
7426
|
+
}
|
|
7427
|
+
if (key.downArrow && !key.ctrl && !key.meta && !key.shift) {
|
|
7428
|
+
if (focusedControl === "threadPanel") {
|
|
7429
|
+
if (chatMiddleOverflowing) {
|
|
7430
|
+
chatMiddleScrollViewRef.current?.scrollBy(1);
|
|
7431
|
+
} else {
|
|
7432
|
+
scrollViewRef.current?.scrollBy(1);
|
|
7433
|
+
}
|
|
7434
|
+
} else {
|
|
7435
|
+
setFocusedControl((current) => nextControlFocus(current, controlFocusOrder));
|
|
7436
|
+
}
|
|
7437
|
+
return;
|
|
7438
|
+
}
|
|
6531
7439
|
if (key.return && !key.meta && !key.ctrl) {
|
|
6532
7440
|
handleFocusedControlEnter();
|
|
6533
7441
|
return;
|
|
@@ -6535,38 +7443,86 @@ var App = ({
|
|
|
6535
7443
|
}
|
|
6536
7444
|
if (phase === "ready") {
|
|
6537
7445
|
if (key.ctrl && key.upArrow) {
|
|
6538
|
-
|
|
7446
|
+
setFocusedControl("threadPanel");
|
|
7447
|
+
if (chatMiddleOverflowing) {
|
|
7448
|
+
chatMiddleScrollViewRef.current?.scrollBy(-1);
|
|
7449
|
+
} else {
|
|
7450
|
+
scrollViewRef.current?.scrollBy(-1);
|
|
7451
|
+
}
|
|
6539
7452
|
return;
|
|
6540
7453
|
}
|
|
6541
7454
|
if (key.ctrl && key.downArrow) {
|
|
6542
|
-
|
|
7455
|
+
setFocusedControl("threadPanel");
|
|
7456
|
+
if (chatMiddleOverflowing) {
|
|
7457
|
+
chatMiddleScrollViewRef.current?.scrollBy(1);
|
|
7458
|
+
} else {
|
|
7459
|
+
scrollViewRef.current?.scrollBy(1);
|
|
7460
|
+
}
|
|
6543
7461
|
return;
|
|
6544
7462
|
}
|
|
6545
|
-
if (!input.trim() && key.upArrow && !key.ctrl && !key.meta && !key.shift) {
|
|
6546
|
-
|
|
7463
|
+
if ((!input.trim() || !promptInputActive) && key.upArrow && !key.ctrl && !key.meta && !key.shift) {
|
|
7464
|
+
setFocusedControl("threadPanel");
|
|
7465
|
+
if (chatMiddleOverflowing) {
|
|
7466
|
+
chatMiddleScrollViewRef.current?.scrollBy(-1);
|
|
7467
|
+
} else {
|
|
7468
|
+
scrollViewRef.current?.scrollBy(-1);
|
|
7469
|
+
}
|
|
6547
7470
|
return;
|
|
6548
7471
|
}
|
|
6549
|
-
if (!input.trim() && key.downArrow && !key.ctrl && !key.meta && !key.shift) {
|
|
6550
|
-
|
|
7472
|
+
if ((!input.trim() || !promptInputActive) && key.downArrow && !key.ctrl && !key.meta && !key.shift) {
|
|
7473
|
+
setFocusedControl("threadPanel");
|
|
7474
|
+
if (chatMiddleOverflowing) {
|
|
7475
|
+
chatMiddleScrollViewRef.current?.scrollBy(1);
|
|
7476
|
+
} else {
|
|
7477
|
+
scrollViewRef.current?.scrollBy(1);
|
|
7478
|
+
}
|
|
6551
7479
|
return;
|
|
6552
7480
|
}
|
|
6553
7481
|
if (key.pageUp && !key.ctrl && !key.meta) {
|
|
6554
|
-
|
|
7482
|
+
setFocusedControl("threadPanel");
|
|
7483
|
+
if (chatMiddleOverflowing) {
|
|
7484
|
+
chatMiddleScrollViewRef.current?.scrollBy(
|
|
7485
|
+
-Math.max(1, Math.floor(chatMiddleViewportHeight * 0.8))
|
|
7486
|
+
);
|
|
7487
|
+
} else {
|
|
7488
|
+
scrollViewRef.current?.scrollBy(-Math.max(1, Math.floor(viewportHeight * 0.8)));
|
|
7489
|
+
}
|
|
6555
7490
|
return;
|
|
6556
7491
|
}
|
|
6557
7492
|
if (key.pageDown && !key.ctrl && !key.meta) {
|
|
6558
|
-
|
|
7493
|
+
setFocusedControl("threadPanel");
|
|
7494
|
+
if (chatMiddleOverflowing) {
|
|
7495
|
+
chatMiddleScrollViewRef.current?.scrollBy(
|
|
7496
|
+
Math.max(1, Math.floor(chatMiddleViewportHeight * 0.8))
|
|
7497
|
+
);
|
|
7498
|
+
} else {
|
|
7499
|
+
scrollViewRef.current?.scrollBy(Math.max(1, Math.floor(viewportHeight * 0.8)));
|
|
7500
|
+
}
|
|
6559
7501
|
return;
|
|
6560
7502
|
}
|
|
6561
7503
|
if (key.ctrl && inputKey.toLowerCase() === "h" && inputKey.toLowerCase() !== "l") {
|
|
6562
|
-
|
|
7504
|
+
setFocusedControl("threadPanel");
|
|
7505
|
+
if (chatMiddleOverflowing) {
|
|
7506
|
+
chatMiddleScrollViewRef.current?.scrollToTop();
|
|
7507
|
+
} else {
|
|
7508
|
+
scrollViewRef.current?.scrollToTop();
|
|
7509
|
+
}
|
|
6563
7510
|
return;
|
|
6564
7511
|
}
|
|
6565
7512
|
if (key.ctrl && inputKey.toLowerCase() === "e") {
|
|
6566
|
-
|
|
7513
|
+
setFocusedControl("threadPanel");
|
|
7514
|
+
if (chatMiddleOverflowing) {
|
|
7515
|
+
chatMiddleScrollViewRef.current?.scrollToBottom();
|
|
7516
|
+
} else {
|
|
7517
|
+
scrollViewRef.current?.scrollToBottom();
|
|
7518
|
+
}
|
|
6567
7519
|
return;
|
|
6568
7520
|
}
|
|
6569
7521
|
}
|
|
7522
|
+
if (phase === "ready" && activeWorkspaceTab === "chat" && !promptInputActive && !activeSelector && !isSearching && isPromptTextInput(inputKey, key)) {
|
|
7523
|
+
handlePromptChange(`${input}${inputKey}`);
|
|
7524
|
+
return;
|
|
7525
|
+
}
|
|
6570
7526
|
if (key.escape && (controllerRef.current || isBusyStatus(chatState.status) || hasCancellableAssistantWork(chatState.messages))) {
|
|
6571
7527
|
stopActiveChat();
|
|
6572
7528
|
}
|
|
@@ -6588,7 +7544,7 @@ var App = ({
|
|
|
6588
7544
|
{ isActive: phase === "ready" }
|
|
6589
7545
|
);
|
|
6590
7546
|
if (phase === "boot") {
|
|
6591
|
-
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, children: [
|
|
7547
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, height: terminalSize.rows, children: [
|
|
6592
7548
|
/* @__PURE__ */ jsx10(Banner, { disable: bannerDisabled, details: headerDetails, terminalColumns: bannerContentColumns }),
|
|
6593
7549
|
isLoggingIn ? /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", gap: 1, padding: 1, children: [
|
|
6594
7550
|
/* @__PURE__ */ jsx10(Text10, { color: terminalTheme.brand, bold: true, children: "Signing in..." }),
|
|
@@ -6617,7 +7573,7 @@ var App = ({
|
|
|
6617
7573
|
);
|
|
6618
7574
|
}
|
|
6619
7575
|
if (phase === "error") {
|
|
6620
|
-
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", padding: 1, children: [
|
|
7576
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", padding: 1, height: terminalSize.rows, children: [
|
|
6621
7577
|
/* @__PURE__ */ jsx10(Text10, { color: terminalTheme.danger, children: "Failed to start CLI." }),
|
|
6622
7578
|
/* @__PURE__ */ jsx10(Text10, { children: bootError ?? "Unknown error" }),
|
|
6623
7579
|
/* @__PURE__ */ jsxs8(Text10, { children: [
|
|
@@ -6645,11 +7601,12 @@ var App = ({
|
|
|
6645
7601
|
const threadPanel = /* @__PURE__ */ jsx10(
|
|
6646
7602
|
TitledBox,
|
|
6647
7603
|
{
|
|
6648
|
-
title:
|
|
7604
|
+
title: selectedThreadTitle,
|
|
6649
7605
|
borderStyle: "round",
|
|
6650
|
-
borderColor: terminalTheme.muted,
|
|
7606
|
+
borderColor: activeChatPanel === "thread" ? terminalTheme.focus : terminalTheme.muted,
|
|
6651
7607
|
padding: 1,
|
|
6652
7608
|
width: chatThreadPanelWidth,
|
|
7609
|
+
height: chatMainPanelRows,
|
|
6653
7610
|
children: /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", children: [
|
|
6654
7611
|
/* @__PURE__ */ jsx10(Box9, { flexShrink: 1, width: threadContentWidth, children: /* @__PURE__ */ jsx10(
|
|
6655
7612
|
ScrollView,
|
|
@@ -6702,13 +7659,15 @@ var App = ({
|
|
|
6702
7659
|
PromptControlBar,
|
|
6703
7660
|
{
|
|
6704
7661
|
focused: focusedControl,
|
|
7662
|
+
selectedThreadTitle,
|
|
6705
7663
|
selectedProject,
|
|
6706
7664
|
selectedModel,
|
|
6707
7665
|
selectedMode,
|
|
7666
|
+
selectedAgentProfileLabel,
|
|
6708
7667
|
hasThinkingSteps,
|
|
6709
7668
|
thinkingExpanded,
|
|
6710
7669
|
thinkingSummary,
|
|
6711
|
-
compact:
|
|
7670
|
+
compact: promptControlsCompact,
|
|
6712
7671
|
terminalColumns: terminalSize.columns,
|
|
6713
7672
|
statusText: chatStatusText,
|
|
6714
7673
|
statusColor: chatStatusColor,
|
|
@@ -6721,7 +7680,7 @@ var App = ({
|
|
|
6721
7680
|
label: `${p.name} (${p.cloud_provider ?? "cloud"})${p.name === "Playground" ? " [Playground]" : ""}`,
|
|
6722
7681
|
value: p
|
|
6723
7682
|
}));
|
|
6724
|
-
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, gap: 0, children: [
|
|
7683
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, gap: 0, height: terminalSize.rows, children: [
|
|
6725
7684
|
/* @__PURE__ */ jsx10(Banner, { disable: bannerDisabled, details: headerDetails, terminalColumns: bannerContentColumns }),
|
|
6726
7685
|
/* @__PURE__ */ jsx10(Text10, { children: "Select a project to chat with:" }),
|
|
6727
7686
|
loadingProjects ? /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", gap: 1, children: [
|
|
@@ -6743,7 +7702,7 @@ var App = ({
|
|
|
6743
7702
|
] });
|
|
6744
7703
|
}
|
|
6745
7704
|
if (activeWorkspaceTab !== "chat") {
|
|
6746
|
-
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, gap: 0, children: [
|
|
7705
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, gap: 0, height: terminalSize.rows, children: [
|
|
6747
7706
|
/* @__PURE__ */ jsx10(Banner, { disable: bannerDisabled, details: headerDetails, terminalColumns: bannerContentColumns }),
|
|
6748
7707
|
/* @__PURE__ */ jsx10(
|
|
6749
7708
|
WorkspaceTabBar,
|
|
@@ -6755,43 +7714,56 @@ var App = ({
|
|
|
6755
7714
|
),
|
|
6756
7715
|
/* @__PURE__ */ jsx10(Text10, { dimColor: true, wrap: "wrap", children: workspaceTabDescriptions[activeWorkspaceTab] }),
|
|
6757
7716
|
notice ? /* @__PURE__ */ jsx10(Text10, { dimColor: true, wrap: "wrap", children: notice }) : null,
|
|
6758
|
-
/* @__PURE__ */
|
|
6759
|
-
|
|
6760
|
-
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
7717
|
+
/* @__PURE__ */ jsx10(
|
|
7718
|
+
TitledBox,
|
|
7719
|
+
{
|
|
7720
|
+
title: workspaceTabLabels[activeWorkspaceTab],
|
|
7721
|
+
borderStyle: "round",
|
|
7722
|
+
borderColor: terminalTheme.muted,
|
|
7723
|
+
padding: 1,
|
|
7724
|
+
marginTop: 1,
|
|
7725
|
+
height: workspacePanelViewportRows,
|
|
7726
|
+
width: workspaceContentWidth,
|
|
7727
|
+
children: /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", children: [
|
|
7728
|
+
/* @__PURE__ */ jsx10(Box9, { flexShrink: 1, width: workspacePanelBodyWidth, children: /* @__PURE__ */ jsx10(
|
|
7729
|
+
ScrollView,
|
|
6769
7730
|
{
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
7731
|
+
ref: workspaceScrollViewRef,
|
|
7732
|
+
height: workspacePanelBodyRows,
|
|
7733
|
+
onScroll: (offset) => setWorkspaceScrollOffset(offset),
|
|
7734
|
+
onContentHeightChange: (height) => setWorkspaceContentHeight(height),
|
|
7735
|
+
onViewportSizeChange: (size) => setWorkspaceViewportHeight(size.height),
|
|
7736
|
+
children: /* @__PURE__ */ jsx10(
|
|
7737
|
+
WorkspacePanel,
|
|
7738
|
+
{
|
|
7739
|
+
tab: activeWorkspaceTab,
|
|
7740
|
+
state: activeWorkspacePanelState,
|
|
7741
|
+
projects,
|
|
7742
|
+
selectedProject,
|
|
7743
|
+
currentUserId,
|
|
7744
|
+
selectedModel,
|
|
7745
|
+
selectedMode,
|
|
7746
|
+
apiBase,
|
|
7747
|
+
frontendUrl: workspaceFrontendUrl,
|
|
7748
|
+
terminalColumns: workspacePanelBodyWidth,
|
|
7749
|
+
tablePage: activeTablePage,
|
|
7750
|
+
animate: animationsEnabled,
|
|
7751
|
+
framed: false
|
|
7752
|
+
}
|
|
7753
|
+
)
|
|
6782
7754
|
}
|
|
6783
|
-
)
|
|
6784
|
-
|
|
6785
|
-
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
|
|
6792
|
-
}
|
|
6793
|
-
|
|
6794
|
-
|
|
7755
|
+
) }),
|
|
7756
|
+
workspacePanelOverflowing ? /* @__PURE__ */ jsx10(
|
|
7757
|
+
Scrollbar2,
|
|
7758
|
+
{
|
|
7759
|
+
scrollOffset: workspaceScrollOffset,
|
|
7760
|
+
contentHeight: workspaceContentHeight,
|
|
7761
|
+
viewportHeight: workspaceViewportHeight
|
|
7762
|
+
}
|
|
7763
|
+
) : null
|
|
7764
|
+
] })
|
|
7765
|
+
}
|
|
7766
|
+
),
|
|
6795
7767
|
/* @__PURE__ */ jsx10(BottomControls, { tab: activeWorkspaceTab }),
|
|
6796
7768
|
activeSelector === "project" ? /* @__PURE__ */ jsx10(
|
|
6797
7769
|
SelectPanel,
|
|
@@ -6819,7 +7791,7 @@ var App = ({
|
|
|
6819
7791
|
) : null
|
|
6820
7792
|
] });
|
|
6821
7793
|
}
|
|
6822
|
-
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, gap: 0, children: [
|
|
7794
|
+
return /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", paddingX: tuiLayout.paddingX, paddingY: 0, gap: 0, height: terminalSize.rows, children: [
|
|
6823
7795
|
/* @__PURE__ */ jsx10(Banner, { disable: bannerDisabled, details: headerDetails, terminalColumns: bannerContentColumns }),
|
|
6824
7796
|
/* @__PURE__ */ jsx10(
|
|
6825
7797
|
WorkspaceTabBar,
|
|
@@ -6829,150 +7801,224 @@ var App = ({
|
|
|
6829
7801
|
billingSummary: bannerDisabled ? billingHeader : void 0
|
|
6830
7802
|
}
|
|
6831
7803
|
),
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
{
|
|
6835
|
-
title: "Search",
|
|
6836
|
-
borderStyle: "double",
|
|
6837
|
-
borderColor: terminalTheme.warning,
|
|
6838
|
-
padding: 0,
|
|
6839
|
-
paddingX: 1,
|
|
6840
|
-
children: /* @__PURE__ */ jsxs8(Text10, { children: [
|
|
6841
|
-
"Found: ",
|
|
6842
|
-
displayedMessages.length,
|
|
6843
|
-
" matches"
|
|
6844
|
-
] })
|
|
6845
|
-
}
|
|
6846
|
-
) : null,
|
|
6847
|
-
queuedMessages.length > 0 ? /* @__PURE__ */ jsx10(
|
|
6848
|
-
QueuePanel,
|
|
6849
|
-
{
|
|
6850
|
-
messages: queuedMessages,
|
|
6851
|
-
compact: tuiLayout.compact,
|
|
6852
|
-
terminalColumns: terminalSize.columns
|
|
6853
|
-
}
|
|
6854
|
-
) : null,
|
|
6855
|
-
notice ? /* @__PURE__ */ jsx10(Text10, { dimColor: true, wrap: "wrap", children: notice }) : null,
|
|
6856
|
-
errorText ? /* @__PURE__ */ jsxs8(
|
|
6857
|
-
TitledBox,
|
|
6858
|
-
{
|
|
6859
|
-
title: "Error Details",
|
|
6860
|
-
borderStyle: "round",
|
|
6861
|
-
borderColor: terminalTheme.danger,
|
|
6862
|
-
padding: 0,
|
|
6863
|
-
paddingX: 1,
|
|
6864
|
-
marginTop: 1,
|
|
6865
|
-
children: [
|
|
6866
|
-
/* @__PURE__ */ jsx10(Text10, { color: terminalTheme.danger, wrap: "wrap", children: errorText }),
|
|
6867
|
-
!hasThinkingSteps ? /* @__PURE__ */ jsx10(Text10, { dimColor: true, wrap: "wrap", children: "No thinking steps were received before the backend returned this error." }) : null
|
|
6868
|
-
]
|
|
6869
|
-
}
|
|
6870
|
-
) : null,
|
|
6871
|
-
splitChatLayout ? /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", columnGap: chatSplitGap, children: [
|
|
7804
|
+
/* @__PURE__ */ jsx10(Text10, { dimColor: true, wrap: "wrap", children: workspaceTabDescriptions.chat }),
|
|
7805
|
+
/* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", marginTop: 1, children: [
|
|
6872
7806
|
/* @__PURE__ */ jsx10(
|
|
6873
|
-
|
|
7807
|
+
Box9,
|
|
6874
7808
|
{
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6884
|
-
|
|
6885
|
-
|
|
6886
|
-
|
|
6887
|
-
|
|
7809
|
+
flexShrink: 1,
|
|
7810
|
+
width: Math.max(24, chatAvailableWidth - (chatMiddleOverflowing ? 2 : 0)),
|
|
7811
|
+
children: /* @__PURE__ */ jsx10(
|
|
7812
|
+
ScrollView,
|
|
7813
|
+
{
|
|
7814
|
+
ref: chatMiddleScrollViewRef,
|
|
7815
|
+
height: chatMiddleViewportRows,
|
|
7816
|
+
onScroll: (offset) => setChatMiddleScrollOffset(offset),
|
|
7817
|
+
onContentHeightChange: (height) => setChatMiddleContentHeight(height),
|
|
7818
|
+
onViewportSizeChange: (size) => setChatMiddleViewportHeight(size.height),
|
|
7819
|
+
children: /* @__PURE__ */ jsxs8(Box9, { flexDirection: "column", children: [
|
|
7820
|
+
isSearching ? /* @__PURE__ */ jsx10(
|
|
7821
|
+
TitledBox,
|
|
7822
|
+
{
|
|
7823
|
+
title: "Search",
|
|
7824
|
+
borderStyle: "double",
|
|
7825
|
+
borderColor: terminalTheme.warning,
|
|
7826
|
+
padding: 0,
|
|
7827
|
+
paddingX: 1,
|
|
7828
|
+
children: /* @__PURE__ */ jsxs8(Text10, { children: [
|
|
7829
|
+
"Found: ",
|
|
7830
|
+
displayedMessages.length,
|
|
7831
|
+
" matches"
|
|
7832
|
+
] })
|
|
7833
|
+
}
|
|
7834
|
+
) : null,
|
|
7835
|
+
queuedMessages.length > 0 ? /* @__PURE__ */ jsx10(
|
|
7836
|
+
QueuePanel,
|
|
7837
|
+
{
|
|
7838
|
+
messages: queuedMessages,
|
|
7839
|
+
compact: tuiLayout.compact,
|
|
7840
|
+
terminalColumns: terminalSize.columns
|
|
7841
|
+
}
|
|
7842
|
+
) : null,
|
|
7843
|
+
notice ? /* @__PURE__ */ jsx10(Text10, { dimColor: true, wrap: "wrap", children: notice }) : null,
|
|
7844
|
+
errorText ? /* @__PURE__ */ jsxs8(
|
|
7845
|
+
TitledBox,
|
|
7846
|
+
{
|
|
7847
|
+
title: "Error Details",
|
|
7848
|
+
borderStyle: "round",
|
|
7849
|
+
borderColor: terminalTheme.danger,
|
|
7850
|
+
padding: 0,
|
|
7851
|
+
paddingX: 1,
|
|
7852
|
+
marginTop: 1,
|
|
7853
|
+
children: [
|
|
7854
|
+
/* @__PURE__ */ jsx10(Text10, { color: terminalTheme.danger, wrap: "wrap", children: errorText }),
|
|
7855
|
+
!hasThinkingSteps ? /* @__PURE__ */ jsx10(Text10, { dimColor: true, wrap: "wrap", children: "No thinking steps were received before the backend returned this error." }) : null
|
|
7856
|
+
]
|
|
7857
|
+
}
|
|
7858
|
+
) : null,
|
|
7859
|
+
splitChatLayout ? /* @__PURE__ */ jsxs8(Box9, { flexDirection: "row", columnGap: chatSplitGap, children: [
|
|
7860
|
+
/* @__PURE__ */ jsx10(
|
|
7861
|
+
ChatContextPanel,
|
|
7862
|
+
{
|
|
7863
|
+
width: chatContextPanelWidth,
|
|
7864
|
+
height: chatMainPanelRows,
|
|
7865
|
+
active: activeChatPanel === "settings",
|
|
7866
|
+
focused: focusedControl,
|
|
7867
|
+
selectedThreadTitle,
|
|
7868
|
+
selectedProject,
|
|
7869
|
+
selectedModel,
|
|
7870
|
+
selectedMode,
|
|
7871
|
+
selectedAgentProfileLabel,
|
|
7872
|
+
hasThinkingSteps,
|
|
7873
|
+
thinkingExpanded,
|
|
7874
|
+
thinkingSummary,
|
|
7875
|
+
statusText: chatStatusText,
|
|
7876
|
+
statusColor: chatStatusColor,
|
|
7877
|
+
busy: chatBusy,
|
|
7878
|
+
animate: animationsEnabled
|
|
7879
|
+
}
|
|
7880
|
+
),
|
|
7881
|
+
threadPanel
|
|
7882
|
+
] }) : threadPanel,
|
|
7883
|
+
chatState.status === "hitl_waiting" && chatState.hitl?.waiting ? /* @__PURE__ */ jsx10(
|
|
7884
|
+
HitlPanel,
|
|
7885
|
+
{
|
|
7886
|
+
hitl: chatState.hitl,
|
|
7887
|
+
questionIndex: hitlQuestionIndex,
|
|
7888
|
+
optionIndex: hitlOptionIndex,
|
|
7889
|
+
answers: hitlAnswers,
|
|
7890
|
+
frontendUrl: frontendThreadUrl
|
|
7891
|
+
}
|
|
7892
|
+
) : null,
|
|
7893
|
+
activeSelector === "thread" ? /* @__PURE__ */ jsx10(
|
|
7894
|
+
SelectPanel,
|
|
7895
|
+
{
|
|
7896
|
+
title: "Select Thread",
|
|
7897
|
+
items: loadingSessions || loadingRemoteThreads ? [
|
|
7898
|
+
{
|
|
7899
|
+
label: "Loading threads...",
|
|
7900
|
+
value: { kind: "new" },
|
|
7901
|
+
description: "Reading CloudEval threads and local CLI history."
|
|
7902
|
+
}
|
|
7903
|
+
] : threadSelectItems,
|
|
7904
|
+
selectedIndex: Math.max(
|
|
7905
|
+
0,
|
|
7906
|
+
threadSelectItems.findIndex(
|
|
7907
|
+
(item) => item.value.kind === "remote" && item.value.thread.thread_id === chatState.threadId || item.value.kind === "session" && item.value.session.threadId === chatState.threadId
|
|
7908
|
+
)
|
|
7909
|
+
),
|
|
7910
|
+
onSubmit: (item) => selectThread(item.value),
|
|
7911
|
+
onCancel: () => setActiveSelector(null),
|
|
7912
|
+
limit: tuiLayout.selectorLimit
|
|
7913
|
+
}
|
|
7914
|
+
) : null,
|
|
7915
|
+
activeSelector === "project" ? /* @__PURE__ */ jsx10(
|
|
7916
|
+
SelectPanel,
|
|
7917
|
+
{
|
|
7918
|
+
title: "Select Project",
|
|
7919
|
+
items: (projects.length ? projects : [defaultProject]).map((project) => ({
|
|
7920
|
+
label: `${project.name} (${project.cloud_provider ?? "cloud"})`,
|
|
7921
|
+
value: project,
|
|
7922
|
+
description: project.id
|
|
7923
|
+
})),
|
|
7924
|
+
selectedIndex: Math.max(
|
|
7925
|
+
0,
|
|
7926
|
+
(projects.length ? projects : [defaultProject]).findIndex(
|
|
7927
|
+
(project) => project.id === (selectedProject ?? defaultProject).id
|
|
7928
|
+
)
|
|
7929
|
+
),
|
|
7930
|
+
onSubmit: (item) => {
|
|
7931
|
+
setSelectedProject(item.value);
|
|
7932
|
+
setActiveSelector(null);
|
|
7933
|
+
},
|
|
7934
|
+
onCancel: () => setActiveSelector(null),
|
|
7935
|
+
limit: tuiLayout.selectorLimit
|
|
7936
|
+
}
|
|
7937
|
+
) : null,
|
|
7938
|
+
activeSelector === "model" ? /* @__PURE__ */ jsx10(
|
|
7939
|
+
SelectPanel,
|
|
7940
|
+
{
|
|
7941
|
+
title: "Select Model",
|
|
7942
|
+
items: modelItems,
|
|
7943
|
+
selectedIndex: Math.max(
|
|
7944
|
+
0,
|
|
7945
|
+
modelItems.findIndex((item) => item.value === selectedModel)
|
|
7946
|
+
),
|
|
7947
|
+
onSubmit: (item) => {
|
|
7948
|
+
setSelectedModel(item.value);
|
|
7949
|
+
setActiveSelector(null);
|
|
7950
|
+
},
|
|
7951
|
+
onCancel: () => setActiveSelector(null),
|
|
7952
|
+
limit: tuiLayout.selectorLimit
|
|
7953
|
+
}
|
|
7954
|
+
) : null,
|
|
7955
|
+
activeSelector === "mode" ? /* @__PURE__ */ jsx10(
|
|
7956
|
+
SelectPanel,
|
|
7957
|
+
{
|
|
7958
|
+
title: "Select Mode",
|
|
7959
|
+
items: modeItems,
|
|
7960
|
+
selectedIndex: Math.max(
|
|
7961
|
+
0,
|
|
7962
|
+
modeItems.findIndex((item) => item.value === selectedMode)
|
|
7963
|
+
),
|
|
7964
|
+
onSubmit: (item) => {
|
|
7965
|
+
setSelectedMode(item.value);
|
|
7966
|
+
if (item.value === "ask") {
|
|
7967
|
+
setSelectedAgentProfileId("");
|
|
7968
|
+
}
|
|
7969
|
+
setNotice(
|
|
7970
|
+
item.value === "ask" ? "Mode selected: Ask. Agent Profile cleared." : `Mode selected: ${item.label}`
|
|
7971
|
+
);
|
|
7972
|
+
setActiveSelector(null);
|
|
7973
|
+
},
|
|
7974
|
+
onCancel: () => setActiveSelector(null),
|
|
7975
|
+
limit: tuiLayout.selectorLimit
|
|
7976
|
+
}
|
|
7977
|
+
) : null,
|
|
7978
|
+
activeSelector === "profile" ? /* @__PURE__ */ jsx10(
|
|
7979
|
+
SelectPanel,
|
|
7980
|
+
{
|
|
7981
|
+
title: "Select Agent Profile",
|
|
7982
|
+
items: agentProfileItems,
|
|
7983
|
+
selectedIndex: Math.max(
|
|
7984
|
+
0,
|
|
7985
|
+
agentProfileItems.findIndex((item) => item.value === selectedAgentProfileId)
|
|
7986
|
+
),
|
|
7987
|
+
onSubmit: (item) => {
|
|
7988
|
+
selectAgentProfileById(item.value, item.label);
|
|
7989
|
+
setActiveSelector(null);
|
|
7990
|
+
},
|
|
7991
|
+
onCancel: () => setActiveSelector(null),
|
|
7992
|
+
limit: tuiLayout.selectorLimit
|
|
7993
|
+
}
|
|
7994
|
+
) : null
|
|
7995
|
+
] })
|
|
7996
|
+
}
|
|
7997
|
+
)
|
|
6888
7998
|
}
|
|
6889
7999
|
),
|
|
6890
|
-
|
|
6891
|
-
|
|
6892
|
-
|
|
6893
|
-
|
|
6894
|
-
|
|
6895
|
-
|
|
6896
|
-
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
frontendUrl: frontendThreadUrl
|
|
6900
|
-
}
|
|
6901
|
-
) : null,
|
|
6902
|
-
activeSelector === "project" ? /* @__PURE__ */ jsx10(
|
|
6903
|
-
SelectPanel,
|
|
6904
|
-
{
|
|
6905
|
-
title: "Select Project",
|
|
6906
|
-
items: (projects.length ? projects : [defaultProject]).map((project) => ({
|
|
6907
|
-
label: `${project.name} (${project.cloud_provider ?? "cloud"})`,
|
|
6908
|
-
value: project,
|
|
6909
|
-
description: project.id
|
|
6910
|
-
})),
|
|
6911
|
-
selectedIndex: Math.max(
|
|
6912
|
-
0,
|
|
6913
|
-
(projects.length ? projects : [defaultProject]).findIndex(
|
|
6914
|
-
(project) => project.id === (selectedProject ?? defaultProject).id
|
|
6915
|
-
)
|
|
6916
|
-
),
|
|
6917
|
-
onSubmit: (item) => {
|
|
6918
|
-
setSelectedProject(item.value);
|
|
6919
|
-
setActiveSelector(null);
|
|
6920
|
-
},
|
|
6921
|
-
onCancel: () => setActiveSelector(null),
|
|
6922
|
-
limit: tuiLayout.selectorLimit
|
|
6923
|
-
}
|
|
6924
|
-
) : null,
|
|
6925
|
-
activeSelector === "model" ? /* @__PURE__ */ jsx10(
|
|
6926
|
-
SelectPanel,
|
|
6927
|
-
{
|
|
6928
|
-
title: "Select Model",
|
|
6929
|
-
items: modelItems,
|
|
6930
|
-
selectedIndex: Math.max(
|
|
6931
|
-
0,
|
|
6932
|
-
modelItems.findIndex((item) => item.value === selectedModel)
|
|
6933
|
-
),
|
|
6934
|
-
onSubmit: (item) => {
|
|
6935
|
-
setSelectedModel(item.value);
|
|
6936
|
-
setActiveSelector(null);
|
|
6937
|
-
},
|
|
6938
|
-
onCancel: () => setActiveSelector(null),
|
|
6939
|
-
limit: tuiLayout.selectorLimit
|
|
6940
|
-
}
|
|
6941
|
-
) : null,
|
|
6942
|
-
activeSelector === "mode" ? /* @__PURE__ */ jsx10(
|
|
6943
|
-
SelectPanel,
|
|
6944
|
-
{
|
|
6945
|
-
title: "Select Mode",
|
|
6946
|
-
items: modeItems,
|
|
6947
|
-
selectedIndex: Math.max(
|
|
6948
|
-
0,
|
|
6949
|
-
modeItems.findIndex((item) => item.value === selectedMode)
|
|
6950
|
-
),
|
|
6951
|
-
onSubmit: (item) => {
|
|
6952
|
-
setSelectedMode(item.value);
|
|
6953
|
-
setActiveSelector(null);
|
|
6954
|
-
},
|
|
6955
|
-
onCancel: () => setActiveSelector(null),
|
|
6956
|
-
limit: tuiLayout.selectorLimit
|
|
6957
|
-
}
|
|
6958
|
-
) : null,
|
|
8000
|
+
chatMiddleOverflowing ? /* @__PURE__ */ jsx10(
|
|
8001
|
+
Scrollbar2,
|
|
8002
|
+
{
|
|
8003
|
+
scrollOffset: chatMiddleScrollOffset,
|
|
8004
|
+
contentHeight: chatMiddleContentHeight,
|
|
8005
|
+
viewportHeight: chatMiddleViewportHeight
|
|
8006
|
+
}
|
|
8007
|
+
) : null
|
|
8008
|
+
] }),
|
|
6959
8009
|
isSearching ? /* @__PURE__ */ jsx10(
|
|
6960
|
-
|
|
8010
|
+
InputBox,
|
|
6961
8011
|
{
|
|
6962
8012
|
title: "Search History",
|
|
6963
|
-
|
|
6964
|
-
|
|
6965
|
-
|
|
6966
|
-
|
|
6967
|
-
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
},
|
|
6973
|
-
placeholder: "Type to filter history..."
|
|
6974
|
-
}
|
|
6975
|
-
)
|
|
8013
|
+
value: searchQuery,
|
|
8014
|
+
onChange: setSearchQuery,
|
|
8015
|
+
onSubmit: () => {
|
|
8016
|
+
},
|
|
8017
|
+
placeholder: "Type to filter history...",
|
|
8018
|
+
onBlurRequest: () => {
|
|
8019
|
+
setIsSearching(false);
|
|
8020
|
+
setSearchQuery("");
|
|
8021
|
+
}
|
|
6976
8022
|
}
|
|
6977
8023
|
) : activeSelector ? null : /* @__PURE__ */ jsx10(
|
|
6978
8024
|
InputBox,
|
|
@@ -6982,9 +8028,15 @@ var App = ({
|
|
|
6982
8028
|
onSubmit: handlePromptSubmit,
|
|
6983
8029
|
ghostText: promptGhostSuffix,
|
|
6984
8030
|
disabled: Boolean(activeSelector),
|
|
8031
|
+
inputActive: promptInputActive,
|
|
8032
|
+
onBlurRequest: () => {
|
|
8033
|
+
setPromptInputActive(false);
|
|
8034
|
+
completionCycleRef.current = void 0;
|
|
8035
|
+
},
|
|
6985
8036
|
onTabShortcut: (tab) => {
|
|
6986
8037
|
setActiveWorkspaceTab(tab);
|
|
6987
8038
|
setActiveSelector(null);
|
|
8039
|
+
setStarterSelectionsOpen(false);
|
|
6988
8040
|
setNotice(void 0);
|
|
6989
8041
|
setInput("");
|
|
6990
8042
|
},
|
|
@@ -6996,14 +8048,21 @@ var App = ({
|
|
|
6996
8048
|
scrollOffset: promptInputViewport.startRow,
|
|
6997
8049
|
minInputRows: promptInputRowBudget,
|
|
6998
8050
|
maxInputRows: promptInputRowBudget,
|
|
8051
|
+
blinkCursor: shouldBlinkPromptCursor({
|
|
8052
|
+
animationsEnabled,
|
|
8053
|
+
inputActive: promptInputActive,
|
|
8054
|
+
busy: chatBusy,
|
|
8055
|
+
selectorOpen: Boolean(activeSelector),
|
|
8056
|
+
searching: isSearching
|
|
8057
|
+
}),
|
|
6999
8058
|
footerControls: promptFooterControls,
|
|
7000
8059
|
helpText: "",
|
|
7001
|
-
actionLabel: promptActionIsCancel ? "ESC to cancel" :
|
|
8060
|
+
actionLabel: promptActionIsCancel ? "ESC to cancel" : void 0,
|
|
7002
8061
|
actionHint: getChatInputHelpText({
|
|
7003
8062
|
isCancelling: promptActionIsCancel,
|
|
8063
|
+
inputActive: promptInputActive,
|
|
7004
8064
|
promptCount: visiblePromptSuggestions.length
|
|
7005
8065
|
}),
|
|
7006
|
-
actionTone: promptActionIsCancel ? terminalTheme.warning : terminalTheme.brand,
|
|
7007
8066
|
onAction: () => {
|
|
7008
8067
|
if (promptActionIsCancel) {
|
|
7009
8068
|
stopActiveChat();
|
|
@@ -7011,7 +8070,6 @@ var App = ({
|
|
|
7011
8070
|
}
|
|
7012
8071
|
handlePromptSubmit(input);
|
|
7013
8072
|
},
|
|
7014
|
-
actionDisabled: !promptActionIsCancel && !input.trim(),
|
|
7015
8073
|
placeholder: chatState.status === "hitl_waiting" ? "Answer HITL prompt, or /open for frontend..." : isBusyStatus(chatState.status) ? "Response in progress. Enter queues next message..." : "Ask Cloudeval..."
|
|
7016
8074
|
}
|
|
7017
8075
|
),
|