@agentdocumentformat/cli 0.8.2 → 0.8.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 +55 -4
- package/dist/adf.mjs +16 -13
- package/dist/chunks/{App-4AZZJNN2.mjs → App-XOPHZTGN.mjs} +515 -349
- package/dist/chunks/{auth-manager-TBNKCJ45.mjs → auth-manager-2YHTYI3C.mjs} +2 -1
- package/dist/chunks/{build-QF5W473T.mjs → build-BFOCXM5S.mjs} +1 -1
- package/dist/chunks/{chunk-RHBGCOS3.mjs → chunk-22ZGZFOV.mjs} +5 -16
- package/dist/chunks/chunk-26RK7T5L.mjs +20 -0
- package/dist/chunks/{chunk-KCIRFUZH.mjs → chunk-2WIFHJV2.mjs} +2 -2
- package/dist/chunks/{chunk-D7A77SNL.mjs → chunk-3FWPIWYM.mjs} +1 -1
- package/dist/chunks/chunk-4T745GJA.mjs +431 -0
- package/dist/chunks/{chunk-7JZXMDDF.mjs → chunk-7ADDKFT5.mjs} +105 -31
- package/dist/chunks/chunk-A53XYNJL.mjs +26 -0
- package/dist/chunks/{chunk-MZRXFWPQ.mjs → chunk-AN6USKYQ.mjs} +40 -8
- package/dist/chunks/{chunk-2Z7X3UUR.mjs → chunk-DHO5Z6HP.mjs} +14 -12
- package/dist/chunks/{chunk-F5ELW46V.mjs → chunk-GJYMGPH4.mjs} +1 -0
- package/dist/chunks/chunk-HONGRUAE.mjs +175 -0
- package/dist/chunks/{chunk-AEAJDCVK.mjs → chunk-IM5JKLXO.mjs} +1 -1
- package/dist/chunks/chunk-J2N63ZUD.mjs +12 -0
- package/dist/chunks/{chunk-IMVMSU3A.mjs → chunk-JK6K2BMV.mjs} +12 -38
- package/dist/chunks/{chunk-75DC5EWN.mjs → chunk-KBXC5EHK.mjs} +1 -0
- package/dist/chunks/chunk-NRTRTR7C.mjs +43 -0
- package/dist/chunks/{chunk-BS3USVEA.mjs → chunk-P4G5ZEBI.mjs} +1 -1
- package/dist/chunks/{chunk-E7LC6SHP.mjs → chunk-RIAB37IS.mjs} +4 -2
- package/dist/chunks/{chunk-LVF2DRBR.mjs → chunk-TBMQOM7Y.mjs} +247 -610
- package/dist/chunks/{chunk-SOSPQPEN.mjs → chunk-TDRQG5UO.mjs} +1 -162
- package/dist/chunks/{chunk-RJDOVMM4.mjs → chunk-TPA2ITKV.mjs} +49 -33
- package/dist/chunks/{chunk-BHY7QDCM.mjs → chunk-UBWWGUMU.mjs} +1 -0
- package/dist/chunks/{chunk-3AT7IIP7.mjs → chunk-WZ6S3SQP.mjs} +1 -1
- package/dist/chunks/chunk-X6R32YVE.mjs +43 -0
- package/dist/chunks/chunk-XJWGENZ5.mjs +5903 -0
- package/dist/chunks/{chunk-F3WSCAJD.mjs → chunk-XP4U4A2W.mjs} +1 -1
- package/dist/chunks/chunk-XS46KYYY.mjs +31 -0
- package/dist/chunks/{chunk-HBOFZRUS.mjs → chunk-XZQVDY3U.mjs} +9 -1
- package/dist/chunks/chunk-ZECGH3LT.mjs +88 -0
- package/dist/chunks/{claude-subscription-EB4LAAVV.mjs → claude-subscription-42L4YM5L.mjs} +4 -3
- package/dist/chunks/{cli-PCVFB6B4.mjs → cli-JPRYEY4J.mjs} +53 -13
- package/dist/chunks/{commands-KOMPXJZS.mjs → commands-TZW2FSXG.mjs} +5 -2
- package/dist/chunks/context-AZOIJOUG.mjs +5933 -0
- package/dist/chunks/{daemon-HEQ3FUYH.mjs → daemon-DK3KUDZJ.mjs} +3571 -6806
- package/dist/chunks/{daemon-control-MKN7G5M3.mjs → daemon-control-U4OGCAAJ.mjs} +4 -4
- package/dist/chunks/{devtools-H7CI2ZVG.mjs → devtools-AUZWFIPL.mjs} +1 -1
- package/dist/chunks/firewall-service-7RGJN4LD.mjs +163 -0
- package/dist/chunks/{open-3OR6WT4T.mjs → open-T3VGLWGF.mjs} +6 -5
- package/dist/chunks/{pipeline-executor-DRYEEFDR.mjs → pipeline-executor-MHRI7ODL.mjs} +6 -3
- package/dist/chunks/{remote-access-cli-GLEEP7DI.mjs → remote-access-cli-EFVCXFOY.mjs} +22 -6
- package/dist/chunks/{store-55CQSAOX.mjs → store-37YHXFJ6.mjs} +4 -3
- package/dist/chunks/{tui-RAUVFOYY.mjs → tui-NJKGFAKU.mjs} +12 -11
- package/dist/chunks/web-F4XHDGUX.mjs +149 -0
- package/dist/chunks/{whatsapp-YJFFVN4Q.mjs → whatsapp-J7PX7TKT.mjs} +1 -1
- package/package.json +4 -3
- package/web/assets/EditorPanel-5ZGWvexa.js +161 -0
- package/web/assets/MeshGraphView-BZV40eAE.css +1 -0
- package/web/assets/MeshGraphView-Vp2R5TLK.js +23 -0
- package/web/assets/SettingsPage-_uHkBERV.js +6 -0
- package/web/assets/agent-window-B8X7FV4_.js +3 -0
- package/web/assets/agent.store-BHweGGTh.js +1 -0
- package/web/assets/app.store-j_-OuVPe.js +1 -0
- package/web/assets/core-DVezgdzc.js +12 -0
- package/web/assets/css-Z72CF80r.js +1 -0
- package/web/assets/diff-D97Zzqfu.js +1 -0
- package/web/assets/document.store-CMD3_OM0.js +1 -0
- package/web/assets/edit-recovery-Ce8tPQZl.js +3 -0
- package/web/assets/engine-javascript-CuxHA8oH.js +141 -0
- package/web/assets/github-dark-dimmed-DH5Ifo-i.js +1 -0
- package/web/assets/github-light-DAi9KRSo.js +1 -0
- package/web/assets/go-C27-OAKa.js +1 -0
- package/web/assets/html-BlS82ilI.js +1 -0
- package/web/assets/index-B5Eot_tL.js +1 -0
- package/web/assets/index-B5FYMbFc.js +3 -0
- package/web/assets/index-BQIEMvvt.js +2 -0
- package/web/assets/index-C_gf4L3q.js +1 -0
- package/web/assets/index-Ca6bEWGu.js +1 -0
- package/web/assets/index-CuTaWSEs.css +1 -0
- package/web/assets/index-DBFkrLao.js +1 -0
- package/web/assets/index-DF1leTEa.js +11 -0
- package/web/assets/index-DS9H-PJI.js +1 -0
- package/web/assets/index-DkhbLs9K.js +6 -0
- package/web/assets/index-KNnHrO8-.js +13 -0
- package/web/assets/index-nM_Q5x7Q.js +1 -0
- package/web/assets/inter-tight-cyrillic-ext-wght-italic-BJqtfpQe.woff2 +0 -0
- package/web/assets/inter-tight-cyrillic-ext-wght-normal-okcGN4Nq.woff2 +0 -0
- package/web/assets/inter-tight-cyrillic-wght-italic-HmhN1gQv.woff2 +0 -0
- package/web/assets/inter-tight-cyrillic-wght-normal-BS41q_Tv.woff2 +0 -0
- package/web/assets/inter-tight-greek-ext-wght-italic-B_3RbJza.woff2 +0 -0
- package/web/assets/inter-tight-greek-ext-wght-normal-DQgQPNk4.woff2 +0 -0
- package/web/assets/inter-tight-greek-wght-italic-Bb1BGCmL.woff2 +0 -0
- package/web/assets/inter-tight-greek-wght-normal-sS1B39LI.woff2 +0 -0
- package/web/assets/inter-tight-latin-ext-wght-italic-DYqsmiDd.woff2 +0 -0
- package/web/assets/inter-tight-latin-ext-wght-normal-B4u9PlvR.woff2 +0 -0
- package/web/assets/inter-tight-latin-wght-italic-DiXukCDG.woff2 +0 -0
- package/web/assets/inter-tight-latin-wght-normal-DX-nOvPD.woff2 +0 -0
- package/web/assets/inter-tight-vietnamese-wght-italic-CiVF0Juh.woff2 +0 -0
- package/web/assets/inter-tight-vietnamese-wght-normal-TKKdAiBA.woff2 +0 -0
- package/web/assets/javascript-wDzz0qaB.js +1 -0
- package/web/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2 +0 -0
- package/web/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2 +0 -0
- package/web/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2 +0 -0
- package/web/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2 +0 -0
- package/web/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2 +0 -0
- package/web/assets/json-Cp-IABpG.js +1 -0
- package/web/assets/jsx-g9-lgVsj.js +1 -0
- package/web/assets/main-Zf3qnQYd.css +1 -0
- package/web/assets/main-o2ocfqUC.js +319 -0
- package/web/assets/markdown-Cvjx9yec.js +1 -0
- package/web/assets/message-queue.store-ke_rFZAb.js +2 -0
- package/web/assets/module-RjUF93sV.js +716 -0
- package/web/assets/native-48B9X9Wg.js +1 -0
- package/web/assets/orbital-render.worker-BovOTauk.js +1 -0
- package/web/assets/python-B6aJPvgy.js +1 -0
- package/web/assets/react-D-F9gHrJ.js +1 -0
- package/web/assets/rust-DPvrY3IQ.js +1 -0
- package/web/assets/shellscript-Yzrsuije.js +1 -0
- package/web/assets/sql-DkvoVjww.js +1 -0
- package/web/assets/stix-two-text-cyrillic-wght-italic-BzL1BdzR.woff2 +0 -0
- package/web/assets/stix-two-text-cyrillic-wght-normal-CcrOj1MU.woff2 +0 -0
- package/web/assets/stix-two-text-greek-wght-italic-glgrbyRu.woff2 +0 -0
- package/web/assets/stix-two-text-greek-wght-normal-DAdwyhkq.woff2 +0 -0
- package/web/assets/stix-two-text-latin-ext-wght-italic--XhV508b.woff2 +0 -0
- package/web/assets/stix-two-text-latin-ext-wght-normal-BUpo8gM0.woff2 +0 -0
- package/web/assets/stix-two-text-latin-wght-italic-BDl6bBME.woff2 +0 -0
- package/web/assets/stix-two-text-latin-wght-normal-BTZaHlTl.woff2 +0 -0
- package/web/assets/stix-two-text-vietnamese-wght-italic-B1jFRJrJ.woff2 +0 -0
- package/web/assets/stix-two-text-vietnamese-wght-normal-CfS0RdBA.woff2 +0 -0
- package/web/assets/tsx-COt5Ahok.js +1 -0
- package/web/assets/typescript-BPQ3VLAy.js +1 -0
- package/web/assets/window-kind-mxlpdE1l.js +1 -0
- package/web/assets/with-selector-Ot-ZoUn0.js +1 -0
- package/web/assets/yaml-Buea-lGh.js +1 -0
- package/web/index.html +15 -0
|
@@ -4,12 +4,50 @@ import { dirname as __adfDirname } from 'node:path';
|
|
|
4
4
|
const require = __adfCreateRequire(import.meta.url);
|
|
5
5
|
const __filename = __adfFileURLToPath(import.meta.url);
|
|
6
6
|
const __dirname = __adfDirname(__filename);
|
|
7
|
+
import {
|
|
8
|
+
THEMES,
|
|
9
|
+
applyTheme,
|
|
10
|
+
findTheme,
|
|
11
|
+
nextThemeName,
|
|
12
|
+
themeNames
|
|
13
|
+
} from "./chunk-GAZO6UMI.mjs";
|
|
7
14
|
import {
|
|
8
15
|
DaemonClient
|
|
9
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-X6R32YVE.mjs";
|
|
10
17
|
import {
|
|
11
18
|
auth_flow_exports
|
|
12
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-UBWWGUMU.mjs";
|
|
20
|
+
import {
|
|
21
|
+
DaemonError,
|
|
22
|
+
MAIN_LOOP,
|
|
23
|
+
PROMPT_PREFILL_KEY,
|
|
24
|
+
SERVER_STOPPED_TEXT,
|
|
25
|
+
StoreProvider,
|
|
26
|
+
askQuestions,
|
|
27
|
+
emptyTranscript,
|
|
28
|
+
findTracked,
|
|
29
|
+
folderName,
|
|
30
|
+
isAsyncInput,
|
|
31
|
+
isBusyState,
|
|
32
|
+
isCredentialsLocked,
|
|
33
|
+
isTrackedKey,
|
|
34
|
+
parseAskResult,
|
|
35
|
+
parseServer,
|
|
36
|
+
servedText,
|
|
37
|
+
serverBadge,
|
|
38
|
+
serverText,
|
|
39
|
+
shallowEqual,
|
|
40
|
+
shortUrl,
|
|
41
|
+
siteKind,
|
|
42
|
+
siteOf,
|
|
43
|
+
stoppedError,
|
|
44
|
+
stoppedLabel,
|
|
45
|
+
transcriptKey,
|
|
46
|
+
useActions,
|
|
47
|
+
useClient,
|
|
48
|
+
useStore,
|
|
49
|
+
useTuiSelector
|
|
50
|
+
} from "./chunk-TPA2ITKV.mjs";
|
|
13
51
|
import {
|
|
14
52
|
createMouseController,
|
|
15
53
|
getScreenText,
|
|
@@ -104,7 +142,18 @@ import {
|
|
|
104
142
|
validateCredentials,
|
|
105
143
|
validateMcpForm,
|
|
106
144
|
validateProvider
|
|
107
|
-
} from "./chunk-
|
|
145
|
+
} from "./chunk-DHO5Z6HP.mjs";
|
|
146
|
+
import {
|
|
147
|
+
ThemeContext,
|
|
148
|
+
stateColor,
|
|
149
|
+
useTheme
|
|
150
|
+
} from "./chunk-NZLEPJ5M.mjs";
|
|
151
|
+
import {
|
|
152
|
+
require_jsx_runtime
|
|
153
|
+
} from "./chunk-7CV2SA3H.mjs";
|
|
154
|
+
import {
|
|
155
|
+
cjs
|
|
156
|
+
} from "./chunk-SGUTYISF.mjs";
|
|
108
157
|
import {
|
|
109
158
|
WELCOME_INTRO,
|
|
110
159
|
WELCOME_OVERLAY,
|
|
@@ -120,21 +169,23 @@ import {
|
|
|
120
169
|
savePrefs
|
|
121
170
|
} from "./chunk-5QU5VY7N.mjs";
|
|
122
171
|
import {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
themeNames
|
|
128
|
-
} from "./chunk-GAZO6UMI.mjs";
|
|
172
|
+
resource_revision_types_exports
|
|
173
|
+
} from "./chunk-XS46KYYY.mjs";
|
|
174
|
+
import "./chunk-JK6K2BMV.mjs";
|
|
175
|
+
import "./chunk-KBXC5EHK.mjs";
|
|
129
176
|
import {
|
|
130
177
|
context_breakdown_exports,
|
|
131
178
|
guarded_fetch_exports,
|
|
132
179
|
skills_catalog_schema_exports
|
|
133
|
-
} from "./chunk-
|
|
134
|
-
import "./chunk-
|
|
180
|
+
} from "./chunk-XZQVDY3U.mjs";
|
|
181
|
+
import "./chunk-7ADDKFT5.mjs";
|
|
182
|
+
import "./chunk-TDRQG5UO.mjs";
|
|
183
|
+
import "./chunk-NRTRTR7C.mjs";
|
|
184
|
+
import "./chunk-HONGRUAE.mjs";
|
|
135
185
|
import {
|
|
136
186
|
Box_default,
|
|
137
187
|
Text,
|
|
188
|
+
measure_element_default,
|
|
138
189
|
useAnimation,
|
|
139
190
|
use_app_default,
|
|
140
191
|
use_box_metrics_default,
|
|
@@ -143,61 +194,20 @@ import {
|
|
|
143
194
|
use_stdin_default,
|
|
144
195
|
use_stdout_default,
|
|
145
196
|
use_window_size_default
|
|
146
|
-
} from "./chunk-
|
|
147
|
-
import {
|
|
148
|
-
ThemeContext,
|
|
149
|
-
stateColor,
|
|
150
|
-
useTheme
|
|
151
|
-
} from "./chunk-NZLEPJ5M.mjs";
|
|
152
|
-
import {
|
|
153
|
-
DaemonError,
|
|
154
|
-
MAIN_LOOP,
|
|
155
|
-
PROMPT_PREFILL_KEY,
|
|
156
|
-
SERVER_STOPPED_TEXT,
|
|
157
|
-
StoreProvider,
|
|
158
|
-
askQuestion,
|
|
159
|
-
emptyTranscript,
|
|
160
|
-
findTracked,
|
|
161
|
-
folderName,
|
|
162
|
-
isAsyncInput,
|
|
163
|
-
isBusyState,
|
|
164
|
-
isCredentialsLocked,
|
|
165
|
-
isTrackedKey,
|
|
166
|
-
parseServer,
|
|
167
|
-
servedText,
|
|
168
|
-
serverBadge,
|
|
169
|
-
serverText,
|
|
170
|
-
shallowEqual,
|
|
171
|
-
shortUrl,
|
|
172
|
-
siteKind,
|
|
173
|
-
siteOf,
|
|
174
|
-
stoppedError,
|
|
175
|
-
stoppedLabel,
|
|
176
|
-
transcriptKey,
|
|
177
|
-
useActions,
|
|
178
|
-
useClient,
|
|
179
|
-
useStore,
|
|
180
|
-
useTuiSelector
|
|
181
|
-
} from "./chunk-RJDOVMM4.mjs";
|
|
182
|
-
import "./chunk-75DC5EWN.mjs";
|
|
183
|
-
import {
|
|
184
|
-
require_jsx_runtime
|
|
185
|
-
} from "./chunk-7CV2SA3H.mjs";
|
|
186
|
-
import {
|
|
187
|
-
cjs
|
|
188
|
-
} from "./chunk-SGUTYISF.mjs";
|
|
189
|
-
import "./chunk-7JZXMDDF.mjs";
|
|
197
|
+
} from "./chunk-WZ6S3SQP.mjs";
|
|
190
198
|
import {
|
|
191
199
|
require_react
|
|
192
200
|
} from "./chunk-6GJ4QHRI.mjs";
|
|
193
201
|
import {
|
|
194
202
|
ADF_SKILLS_REGISTRY_URL
|
|
195
|
-
} from "./chunk-
|
|
203
|
+
} from "./chunk-RIAB37IS.mjs";
|
|
196
204
|
import "./chunk-UYY5M2PB.mjs";
|
|
197
205
|
import "./chunk-2NAP2ZF7.mjs";
|
|
198
206
|
import "./chunk-LKFHERRV.mjs";
|
|
199
|
-
import "./chunk-
|
|
200
|
-
import "./chunk-
|
|
207
|
+
import "./chunk-ZECGH3LT.mjs";
|
|
208
|
+
import "./chunk-26RK7T5L.mjs";
|
|
209
|
+
import "./chunk-IM5JKLXO.mjs";
|
|
210
|
+
import "./chunk-P4G5ZEBI.mjs";
|
|
201
211
|
import "./chunk-WJGPNHGX.mjs";
|
|
202
212
|
import "./chunk-PAK5JCO2.mjs";
|
|
203
213
|
import "./chunk-ZPB3HYM7.mjs";
|
|
@@ -217,7 +227,7 @@ import {
|
|
|
217
227
|
} from "./chunk-M2RX3S2T.mjs";
|
|
218
228
|
|
|
219
229
|
// src/main/tui/app/App.tsx
|
|
220
|
-
var
|
|
230
|
+
var import_react61 = __toESM(require_react(), 1);
|
|
221
231
|
|
|
222
232
|
// src/main/tui/app/shell-context.ts
|
|
223
233
|
var import_react = __toESM(require_react(), 1);
|
|
@@ -534,7 +544,7 @@ function useShell() {
|
|
|
534
544
|
}
|
|
535
545
|
|
|
536
546
|
// src/main/tui/app/Shell.tsx
|
|
537
|
-
var
|
|
547
|
+
var import_react26 = __toESM(require_react(), 1);
|
|
538
548
|
|
|
539
549
|
// src/main/tui/app/clipboard.ts
|
|
540
550
|
import { spawn } from "node:child_process";
|
|
@@ -971,6 +981,7 @@ function isZeroWidth(ch) {
|
|
|
971
981
|
return cp >= 768 && cp <= 879 || cp >= 8203 && cp <= 8207 || cp >= 65024 && cp <= 65039;
|
|
972
982
|
}
|
|
973
983
|
function displayWidth(text) {
|
|
984
|
+
if (/^[\x00-\x7f]*$/.test(text)) return text.length;
|
|
974
985
|
let width = 0;
|
|
975
986
|
for (let ch of text)
|
|
976
987
|
isZeroWidth(ch) || (width += WIDE.test(ch) ? 2 : 1);
|
|
@@ -2196,7 +2207,11 @@ function Prompt({ width, focused }) {
|
|
|
2196
2207
|
}, []);
|
|
2197
2208
|
let highlighted = Math.min(menuIndex, Math.max(0, menu.length - 1)), submit = (text) => {
|
|
2198
2209
|
let trimmed = text.trim();
|
|
2199
|
-
|
|
2210
|
+
if (!trimmed) {
|
|
2211
|
+
let scope2 = createScope(store, exit);
|
|
2212
|
+
return !config2?.onSubmit || !config2.submitsEmpty?.(scope2) ? !1 : (config2.onSubmit("", { ...scope2, args: [], rest: "" }), !0);
|
|
2213
|
+
}
|
|
2214
|
+
return setHistory((prev) => [...prev.filter((h) => h !== trimmed), trimmed].slice(-HISTORY_LIMIT)), setMenuIndex(0), (async () => {
|
|
2200
2215
|
if (await runSlash(trimmed, registry, store, exit)) return;
|
|
2201
2216
|
let ctx = { ...createScope(store, exit), args: [], rest: trimmed };
|
|
2202
2217
|
if (config2?.onSubmit && await config2.onSubmit(trimmed, ctx)) return;
|
|
@@ -2212,7 +2227,7 @@ function Prompt({ width, focused }) {
|
|
|
2212
2227
|
let summary = store.getState().agents[ctx.agentId]?.summary;
|
|
2213
2228
|
store.actions.toast(`Sent to ${summary?.handle || summary?.name || ctx.agentId} ${theme2.glyph.pointer} ${ctx.loop ?? MAIN_LOOP}`, "success", 2500);
|
|
2214
2229
|
}
|
|
2215
|
-
})(), !0
|
|
2230
|
+
})(), !0;
|
|
2216
2231
|
};
|
|
2217
2232
|
return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Box_default, { flexDirection: "column", width, children: [
|
|
2218
2233
|
menuOpen ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Box_default, { flexDirection: "column", marginBottom: 0, children: menu.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
@@ -3542,8 +3557,25 @@ function NewAgentDialog({ overlay, close, width, height }) {
|
|
|
3542
3557
|
}
|
|
3543
3558
|
|
|
3544
3559
|
// src/main/tui/auth/AuthDialog.tsx
|
|
3560
|
+
var import_react16 = __toESM(require_react(), 1);
|
|
3561
|
+
|
|
3562
|
+
// src/main/tui/ui/Markdown.tsx
|
|
3545
3563
|
var import_react15 = __toESM(require_react(), 1);
|
|
3546
3564
|
|
|
3565
|
+
// src/main/tui/ui/markdown-window.ts
|
|
3566
|
+
function measuredBlockWindow(signatures, measurements, viewport) {
|
|
3567
|
+
let hidden = Array(signatures.length).fill(!1), below = 0, exact = !0, bottom = Math.max(0, viewport.clipBottom), top = bottom + Math.max(1, viewport.height);
|
|
3568
|
+
for (let i = signatures.length - 1; i >= 0; i--) {
|
|
3569
|
+
let m = measurements.get(i);
|
|
3570
|
+
if (!m || m.signature !== signatures[i]) {
|
|
3571
|
+
exact = !1;
|
|
3572
|
+
continue;
|
|
3573
|
+
}
|
|
3574
|
+
hidden[i] = below >= top || exact && below + m.height <= bottom, below += m.height;
|
|
3575
|
+
}
|
|
3576
|
+
return hidden;
|
|
3577
|
+
}
|
|
3578
|
+
|
|
3547
3579
|
// src/main/tui/ui/Markdown.tsx
|
|
3548
3580
|
var import_jsx_runtime17 = __toESM(require_jsx_runtime(), 1);
|
|
3549
3581
|
function parseBlocks(text) {
|
|
@@ -3640,11 +3672,33 @@ function renderBlock(block, index, theme2, color) {
|
|
|
3640
3672
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Inline, { text: block.text, color }, index);
|
|
3641
3673
|
}
|
|
3642
3674
|
}
|
|
3643
|
-
function Markdown({ text, color, raw = !1 }) {
|
|
3644
|
-
let theme2 = useTheme();
|
|
3645
|
-
|
|
3646
|
-
let
|
|
3647
|
-
|
|
3675
|
+
function Markdown({ text, color, raw = !1, viewport }) {
|
|
3676
|
+
let theme2 = useTheme(), [, measured] = (0, import_react15.useReducer)((n) => n + 1, 0), cache = (0, import_react15.useRef)(null), nodes = (0, import_react15.useRef)(/* @__PURE__ */ new Map()), blocks = raw ? [] : parseBlocks(text), signatures = viewport ? blocks.map((block) => JSON.stringify(block)) : [];
|
|
3677
|
+
viewport && (!cache.current || cache.current.width !== viewport.width || cache.current.theme !== theme2 || !text.startsWith(cache.current.text)) && (cache.current = { text, width: viewport.width, theme: theme2, heights: /* @__PURE__ */ new Map() });
|
|
3678
|
+
let heights = cache.current?.heights;
|
|
3679
|
+
cache.current && (cache.current.text = text);
|
|
3680
|
+
let hidden = viewport && heights ? measuredBlockWindow(signatures, heights, viewport) : [];
|
|
3681
|
+
if ((0, import_react15.useLayoutEffect)(() => {
|
|
3682
|
+
if (!viewport || !heights) return;
|
|
3683
|
+
for (let [i, node] of nodes.current)
|
|
3684
|
+
i < signatures.length && heights.set(i, { signature: signatures[i], height: measure_element_default(node).height });
|
|
3685
|
+
for (let i of heights.keys()) i >= signatures.length && heights.delete(i);
|
|
3686
|
+
measuredBlockWindow(signatures, heights, viewport).some((value, i) => value !== hidden[i]) && measured();
|
|
3687
|
+
}), raw) return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Text, { wrap: "wrap", color, children: text });
|
|
3688
|
+
if (!viewport || !heights) return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Box_default, { flexDirection: "column", children: blocks.map((block, i) => renderBlock(block, i, theme2, color)) });
|
|
3689
|
+
let children = [], spacer = 0, flush = (i) => {
|
|
3690
|
+
spacer > 0 && children.push(/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Box_default, { height: spacer, flexShrink: 0 }, `space:${i}`)), spacer = 0;
|
|
3691
|
+
};
|
|
3692
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
3693
|
+
if (hidden[i]) {
|
|
3694
|
+
spacer += heights.get(i).height;
|
|
3695
|
+
continue;
|
|
3696
|
+
}
|
|
3697
|
+
flush(i), children.push(/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Box_default, { flexDirection: "column", flexShrink: 0, ref: (node) => {
|
|
3698
|
+
node ? nodes.current.set(i, node) : nodes.current.delete(i);
|
|
3699
|
+
}, children: renderBlock(blocks[i], i, theme2, color) }, i));
|
|
3700
|
+
}
|
|
3701
|
+
return flush(blocks.length), /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Box_default, { flexDirection: "column", children });
|
|
3648
3702
|
}
|
|
3649
3703
|
|
|
3650
3704
|
// src/main/tui/views/chat/model.ts
|
|
@@ -3872,9 +3926,40 @@ function sayText(item) {
|
|
|
3872
3926
|
let message = inputRecord(item.input)?.message;
|
|
3873
3927
|
return typeof message == "string" ? message : prettyJson(item.input);
|
|
3874
3928
|
}
|
|
3875
|
-
function
|
|
3876
|
-
if (item.result
|
|
3877
|
-
return item.
|
|
3929
|
+
function askAnswers(item) {
|
|
3930
|
+
if (!(item.result === void 0 || item.status === "error"))
|
|
3931
|
+
return parseAskResult(askQuestions(item.input), item.result);
|
|
3932
|
+
}
|
|
3933
|
+
function askFormHeight(questions, w, answers) {
|
|
3934
|
+
return questions.reduce((n, q) => n + wrappedHeight(q.question || " ", w) + (answers ? 1 : 0), 0);
|
|
3935
|
+
}
|
|
3936
|
+
function askFormText(questions, answers) {
|
|
3937
|
+
return questions.map((q, i) => answers ? `${q.question}
|
|
3938
|
+
${answers[i] ?? "(skipped)"}` : q.question).join(`
|
|
3939
|
+
|
|
3940
|
+
`);
|
|
3941
|
+
}
|
|
3942
|
+
function askStep(ask, answers) {
|
|
3943
|
+
let index = Math.min(answers.length, ask.questions.length - 1);
|
|
3944
|
+
return { index, question: ask.questions[index] };
|
|
3945
|
+
}
|
|
3946
|
+
function askHint(q) {
|
|
3947
|
+
return q.options ? `Type ${q.multiple ? "numbers (1,3)" : "a number"}, or your own answer` : "Type your answer";
|
|
3948
|
+
}
|
|
3949
|
+
function readAskReply(q, text) {
|
|
3950
|
+
let reply = text.trim();
|
|
3951
|
+
if (!reply) return { answer: null };
|
|
3952
|
+
let options = q.options;
|
|
3953
|
+
if (!options) return { answer: reply };
|
|
3954
|
+
if (/^\d+(\s*[,\s]\s*\d+)*$/.test(reply)) {
|
|
3955
|
+
let picks = [...new Set(reply.split(/[\s,]+/).map(Number))];
|
|
3956
|
+
if (picks.every((n) => n >= 1 && n <= options.length)) {
|
|
3957
|
+
if (!q.multiple && picks.length > 1) return { error: "This question takes one pick" };
|
|
3958
|
+
let labels = picks.map((n) => options[n - 1].label);
|
|
3959
|
+
return { answer: q.multiple ? labels : labels[0] };
|
|
3960
|
+
}
|
|
3961
|
+
}
|
|
3962
|
+
return { answer: q.multiple ? [reply] : reply };
|
|
3878
3963
|
}
|
|
3879
3964
|
function statusLineText(item, sep4 = "\xB7", arrow = "\u2192") {
|
|
3880
3965
|
let input = inputRecord(item.input);
|
|
@@ -3910,8 +3995,10 @@ function itemHeight(item, width, flags) {
|
|
|
3910
3995
|
switch (view2) {
|
|
3911
3996
|
case "say":
|
|
3912
3997
|
return markdownHeight(sayText(item) || " ", w) + (item.status === "error" ? 1 : 0) + 1;
|
|
3913
|
-
case "ask":
|
|
3914
|
-
|
|
3998
|
+
case "ask": {
|
|
3999
|
+
let answers = askAnswers(item);
|
|
4000
|
+
return 1 + askFormHeight(askQuestions(item.input), w, answers) + (item.result !== void 0 && !answers ? 1 : 0) + 1;
|
|
4001
|
+
}
|
|
3915
4002
|
case "status":
|
|
3916
4003
|
return 2;
|
|
3917
4004
|
case "row":
|
|
@@ -3922,7 +4009,7 @@ function itemHeight(item, width, flags) {
|
|
|
3922
4009
|
case "hil":
|
|
3923
4010
|
return 2 + (item.reason ? 1 : 0) + (item.feedback ? 1 : 0) + (flags.expanded ? wrappedHeight(prettyJson(item.input), w - 4) : 0) + 1;
|
|
3924
4011
|
case "ask":
|
|
3925
|
-
return 1 +
|
|
4012
|
+
return 1 + askFormHeight(item.questions, w) + 1;
|
|
3926
4013
|
case "notice":
|
|
3927
4014
|
return 1;
|
|
3928
4015
|
case "context":
|
|
@@ -3951,12 +4038,8 @@ function itemText(item) {
|
|
|
3951
4038
|
switch (toolView(item)) {
|
|
3952
4039
|
case "say":
|
|
3953
4040
|
return sayText(item);
|
|
3954
|
-
case "ask":
|
|
3955
|
-
|
|
3956
|
-
return answer ? `${askQuestion(item.input)}
|
|
3957
|
-
|
|
3958
|
-
${answer}` : askQuestion(item.input);
|
|
3959
|
-
}
|
|
4041
|
+
case "ask":
|
|
4042
|
+
return askFormText(askQuestions(item.input), askAnswers(item));
|
|
3960
4043
|
default:
|
|
3961
4044
|
return [`${item.name} ${prettyJson(item.input)}`, item.result ?? ""].filter(Boolean).join(`
|
|
3962
4045
|
|
|
@@ -3965,9 +4048,7 @@ ${answer}` : askQuestion(item.input);
|
|
|
3965
4048
|
case "hil":
|
|
3966
4049
|
return `${item.tool} ${prettyJson(item.input)}`;
|
|
3967
4050
|
case "ask":
|
|
3968
|
-
return item.
|
|
3969
|
-
|
|
3970
|
-
${item.answer}` : item.question;
|
|
4051
|
+
return askFormText(item.questions);
|
|
3971
4052
|
case "context":
|
|
3972
4053
|
return item.ownerCommand ? `${item.ownerCommand.command} [${item.ownerCommand.status}${item.ownerCommand.authorized ? ", authorized" : ""}]
|
|
3973
4054
|
${item.text}` : item.text;
|
|
@@ -4090,8 +4171,8 @@ async function signIn(client, provider, signal, handlers) {
|
|
|
4090
4171
|
// src/main/tui/auth/AuthDialog.tsx
|
|
4091
4172
|
var import_jsx_runtime18 = __toESM(require_jsx_runtime(), 1);
|
|
4092
4173
|
function AuthDialog({ overlay, close, width }) {
|
|
4093
|
-
let theme2 = useTheme(), store = useStore(), auth = useTuiSelector((s) => s.auth), props = overlay.props ?? {}, [cursor, setCursor] = (0,
|
|
4094
|
-
(0,
|
|
4174
|
+
let theme2 = useTheme(), store = useStore(), auth = useTuiSelector((s) => s.auth), props = overlay.props ?? {}, [cursor, setCursor] = (0, import_react16.useState)(Math.max(0, SUBSCRIPTIONS.indexOf(props.login ?? "chatgpt"))), [flow, setFlow] = (0, import_react16.useState)({ kind: "list" }), [note, setNote] = (0, import_react16.useState)(null), [pasted, setPasted] = (0, import_react16.useState)(""), abort = (0, import_react16.useRef)(null), dialogWidth = Math.max(50, Math.min(width - 4, 84));
|
|
4175
|
+
(0, import_react16.useEffect)(() => (store.actions.refreshAuth(), props.login && start(props.login), () => abort.current?.abort()), []);
|
|
4095
4176
|
let start = (provider) => {
|
|
4096
4177
|
abort.current?.abort();
|
|
4097
4178
|
let ctrl = new AbortController();
|
|
@@ -4274,11 +4355,11 @@ function TerminalSetupDialog({ close, width, height }) {
|
|
|
4274
4355
|
}
|
|
4275
4356
|
|
|
4276
4357
|
// src/main/tui/setup/WelcomeDialog.tsx
|
|
4277
|
-
var
|
|
4358
|
+
var import_react17 = __toESM(require_react(), 1);
|
|
4278
4359
|
var import_jsx_runtime20 = __toESM(require_jsx_runtime(), 1), LABEL = 21;
|
|
4279
4360
|
function WelcomeDialog({ close, width, height }) {
|
|
4280
|
-
let theme2 = useTheme(), store = useStore(), { registry, exit } = useShell(), identity = useTuiSelector((s) => s.identity), auth = useTuiSelector((s) => s.auth), agents = useTuiSelector((s) => s.agents), agentOrder = useTuiSelector((s) => s.agentOrder), [extras, setExtras] = (0,
|
|
4281
|
-
(0,
|
|
4361
|
+
let theme2 = useTheme(), store = useStore(), { registry, exit } = useShell(), identity = useTuiSelector((s) => s.identity), auth = useTuiSelector((s) => s.auth), agents = useTuiSelector((s) => s.agents), agentOrder = useTuiSelector((s) => s.agentOrder), [extras, setExtras] = (0, import_react17.useState)({ adapters: {}, timers: {} });
|
|
4362
|
+
(0, import_react17.useEffect)(() => {
|
|
4282
4363
|
let live = !0, ids = store.getState().agentOrder;
|
|
4283
4364
|
return Promise.all(ids.map(async (id) => {
|
|
4284
4365
|
let entry = store.getState().agents[id], [config2, timers] = await Promise.all([
|
|
@@ -4296,10 +4377,10 @@ function WelcomeDialog({ close, width, height }) {
|
|
|
4296
4377
|
live = !1;
|
|
4297
4378
|
};
|
|
4298
4379
|
}, [store, agentOrder.join("|")]);
|
|
4299
|
-
let steps = (0,
|
|
4380
|
+
let steps = (0, import_react17.useMemo)(
|
|
4300
4381
|
() => welcomeSteps(welcomeFacts({ identity, auth, agents, agentOrder }, extras)),
|
|
4301
4382
|
[identity, auth, agents, agentOrder, extras]
|
|
4302
|
-
), [index, setIndex] = (0,
|
|
4383
|
+
), [index, setIndex] = (0, import_react17.useState)(() => nextStepIndex(steps)), selected = Math.min(index, steps.length - 1), start = () => {
|
|
4303
4384
|
let step = steps[selected];
|
|
4304
4385
|
close(), step && runSlash(step.run, registry, store, exit);
|
|
4305
4386
|
};
|
|
@@ -4334,10 +4415,10 @@ function WelcomeDialog({ close, width, height }) {
|
|
|
4334
4415
|
}
|
|
4335
4416
|
|
|
4336
4417
|
// src/main/tui/setup/ChannelsDialog.tsx
|
|
4337
|
-
var
|
|
4418
|
+
var import_react19 = __toESM(require_react(), 1);
|
|
4338
4419
|
|
|
4339
4420
|
// src/main/tui/ui/List.tsx
|
|
4340
|
-
var
|
|
4421
|
+
var import_react18 = __toESM(require_react(), 1);
|
|
4341
4422
|
var import_jsx_runtime21 = __toESM(require_jsx_runtime(), 1);
|
|
4342
4423
|
function List(props) {
|
|
4343
4424
|
let {
|
|
@@ -4356,19 +4437,19 @@ function List(props) {
|
|
|
4356
4437
|
active = !0,
|
|
4357
4438
|
emptyText = "Nothing here.",
|
|
4358
4439
|
wheelSelects = !1
|
|
4359
|
-
} = props, theme2 = useTheme(), [internalIndex, setInternalIndex] = (0,
|
|
4440
|
+
} = props, theme2 = useTheme(), [internalIndex, setInternalIndex] = (0, import_react18.useState)(0), [query, setQuery] = (0, import_react18.useState)(""), [filtering, setFiltering] = (0, import_react18.useState)(!1), offsetRef = (0, import_react18.useRef)(0), visible = (0, import_react18.useMemo)(
|
|
4360
4441
|
() => filter && query ? items.filter((item) => filter(item, query)) : items,
|
|
4361
4442
|
[items, filter, query]
|
|
4362
4443
|
), showFilterBar = filtering || query.length > 0, bodyRows = Math.max(1, height - (showFilterBar ? 1 : 0)), perPage = Math.max(1, Math.floor(bodyRows / itemHeight2)), rawIndex = selectedIndex ?? internalIndex, index = visible.length === 0 ? 0 : Math.min(Math.max(0, rawIndex), visible.length - 1), select = (next) => {
|
|
4363
4444
|
let clamped = visible.length === 0 ? 0 : Math.min(Math.max(0, next), visible.length - 1);
|
|
4364
4445
|
selectedIndex === void 0 && setInternalIndex(clamped), onSelectedIndexChange?.(clamped, visible[clamped]);
|
|
4365
4446
|
};
|
|
4366
|
-
(0,
|
|
4447
|
+
(0, import_react18.useEffect)(() => {
|
|
4367
4448
|
rawIndex !== index && visible.length > 0 && select(index);
|
|
4368
4449
|
}, [rawIndex, index, visible.length]);
|
|
4369
|
-
let revealed = (0,
|
|
4450
|
+
let revealed = (0, import_react18.useRef)(null), [, redraw] = (0, import_react18.useState)(0);
|
|
4370
4451
|
revealed.current !== `${index}|${perPage}` && (revealed.current = `${index}|${perPage}`, index < offsetRef.current && (offsetRef.current = index), index >= offsetRef.current + perPage && (offsetRef.current = index - perPage + 1)), offsetRef.current = Math.max(0, Math.min(offsetRef.current, Math.max(0, visible.length - perPage)));
|
|
4371
|
-
let boxRef = (0,
|
|
4452
|
+
let boxRef = (0, import_react18.useRef)(null);
|
|
4372
4453
|
useWheel(boxRef, (delta) => {
|
|
4373
4454
|
if (wheelSelects) {
|
|
4374
4455
|
select(index + delta * WHEEL_STEP);
|
|
@@ -4452,8 +4533,8 @@ function LockedCredential({ name, title, width, confirming, onUnlock, onReplace,
|
|
|
4452
4533
|
// src/main/tui/setup/ChannelsDialog.tsx
|
|
4453
4534
|
var import_jsx_runtime23 = __toESM(require_jsx_runtime(), 1), POLL_MS = 1e3, POLL_FOR_MS = 2e4;
|
|
4454
4535
|
function ChannelsDialog({ overlay, close, width, height }) {
|
|
4455
|
-
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, agentId = props.agentId ?? store.getState().selectedAgentId ?? "", agent2 = useTuiSelector((s) => s.agents[agentId]), who = agent2?.summary.handle || agent2?.summary.name || agentId, entries = (0,
|
|
4456
|
-
(0,
|
|
4536
|
+
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, agentId = props.agentId ?? store.getState().selectedAgentId ?? "", agent2 = useTuiSelector((s) => s.agents[agentId]), who = agent2?.summary.handle || agent2?.summary.name || agentId, entries = (0, import_react19.useMemo)(channelEntries, []), direct = findChannel(props.channel), [step, setStep] = (0, import_react19.useState)(direct ? { kind: "form", entry: direct, editing: !1 } : { kind: "list" }), [index, setIndex] = (0, import_react19.useState)(0), [diag, setDiag] = (0, import_react19.useState)(null), [values, setValues] = (0, import_react19.useState)({}), [errors, setErrors] = (0, import_react19.useState)({}), [formError, setFormError] = (0, import_react19.useState)(null), [stored, setStored] = (0, import_react19.useState)(null), alive = (0, import_react19.useRef)(!0);
|
|
4537
|
+
(0, import_react19.useEffect)(() => () => {
|
|
4457
4538
|
alive.current = !1;
|
|
4458
4539
|
}, []);
|
|
4459
4540
|
let configured = diag ? diag.configured.map((c) => c.type) : configuredChannels(agent2?.config), isOn = (type) => configured.includes(type), stateOf = (type) => adapterLiveState(diag, type), refresh2 = async () => {
|
|
@@ -4464,9 +4545,9 @@ function ChannelsDialog({ overlay, close, width, height }) {
|
|
|
4464
4545
|
return null;
|
|
4465
4546
|
}
|
|
4466
4547
|
};
|
|
4467
|
-
(0,
|
|
4548
|
+
(0, import_react19.useEffect)(() => {
|
|
4468
4549
|
agentId && refresh2();
|
|
4469
|
-
}, [agentId]), (0,
|
|
4550
|
+
}, [agentId]), (0, import_react19.useEffect)(() => {
|
|
4470
4551
|
if (step.kind !== "detail") return;
|
|
4471
4552
|
let stopped = !1, timer, started = Date.now(), tick = async () => {
|
|
4472
4553
|
let d = await refresh2();
|
|
@@ -4724,10 +4805,10 @@ function LiveLine({ state }) {
|
|
|
4724
4805
|
}
|
|
4725
4806
|
|
|
4726
4807
|
// src/main/tui/setup/ProviderDialog.tsx
|
|
4727
|
-
var
|
|
4808
|
+
var import_react21 = __toESM(require_react(), 1);
|
|
4728
4809
|
|
|
4729
4810
|
// src/main/tui/views/inspect/model-picker.tsx
|
|
4730
|
-
var
|
|
4811
|
+
var import_react20 = __toESM(require_react(), 1);
|
|
4731
4812
|
var import_jsx_runtime24 = __toESM(require_jsx_runtime(), 1), MODEL_OVERLAY = "inspect.model";
|
|
4732
4813
|
function providerChoices(providers, auth) {
|
|
4733
4814
|
return providers.map((p) => {
|
|
@@ -4773,8 +4854,8 @@ async function applyModel(store, agentId, loop, choice) {
|
|
|
4773
4854
|
return await actions4.run("Model", (c) => c.putConfig(agentId, next)) ? (await actions4.loadConfig(agentId), actions4.toast(`${who} now runs ${choice.provider}/${choice.model}`, "success"), !0) : !1;
|
|
4774
4855
|
}
|
|
4775
4856
|
function ModelOverlay({ overlay, close, width }) {
|
|
4776
|
-
let theme2 = useTheme(), store = useStore(), agentId = String(overlay.props?.agentId ?? ""), loop = String(overlay.props?.loop ?? MAIN_LOOP), current = currentModel(store.getState(), agentId, loop), [providers, setProviders] = (0,
|
|
4777
|
-
(0,
|
|
4857
|
+
let theme2 = useTheme(), store = useStore(), agentId = String(overlay.props?.agentId ?? ""), loop = String(overlay.props?.loop ?? MAIN_LOOP), current = currentModel(store.getState(), agentId, loop), [providers, setProviders] = (0, import_react20.useState)(null), [models, setModels] = (0, import_react20.useState)(null), [error, setError] = (0, import_react20.useState)(null), [step, setStep] = (0, import_react20.useState)({ kind: "provider" }), [query, setQuery] = (0, import_react20.useState)(""), [index, setIndex] = (0, import_react20.useState)(0);
|
|
4858
|
+
(0, import_react20.useEffect)(() => {
|
|
4778
4859
|
store.client.providers().then(
|
|
4779
4860
|
(d) => {
|
|
4780
4861
|
let list = providerChoices(d.providers, store.getState().auth);
|
|
@@ -4793,7 +4874,7 @@ function ModelOverlay({ overlay, close, width }) {
|
|
|
4793
4874
|
setModels([]), setError(err instanceof Error ? err.message : String(err));
|
|
4794
4875
|
}
|
|
4795
4876
|
);
|
|
4796
|
-
}, providerRows2 = [...loop === MAIN_LOOP ? [] : [{ id: "", name: "inherit", type: "", access: "use the agent\u2019s model", ready: !0 }], ...providers ?? []], shownModels = (0,
|
|
4877
|
+
}, providerRows2 = [...loop === MAIN_LOOP ? [] : [{ id: "", name: "inherit", type: "", access: "use the agent\u2019s model", ready: !0 }], ...providers ?? []], shownModels = (0, import_react20.useMemo)(() => (models ?? []).filter((m) => m.toLowerCase().includes(query.toLowerCase())), [models, query]), apply = (choice) => {
|
|
4797
4878
|
close(), applyModel(store, agentId, loop, choice);
|
|
4798
4879
|
};
|
|
4799
4880
|
useKeys((input, key) => key.escape || key.ctrl && input === "c" ? step.kind === "model" && !(key.ctrl && input === "c") ? query ? (setQuery(""), !0) : (setStep({ kind: "provider" }), setIndex(Math.max(0, providerRows2.findIndex((p) => p.id === step.provider.id))), !0) : (close(), !0) : step.kind !== "model" || key.ctrl || key.meta ? !1 : key.backspace || key.delete ? (setQuery((q) => q.slice(0, -1)), setIndex(0), !0) : key.leftArrow ? (setStep({ kind: "provider" }), !0) : input && !/[\u0000-\u001f\u007f]/.test(input) && !key.return && !key.tab ? (setQuery((q) => q + input), setIndex(0), !0) : !1, { layer: "overlay" });
|
|
@@ -4926,8 +5007,8 @@ var complete = (partial) => ["chatgpt", "grok", "claude"].filter((v) => v.starts
|
|
|
4926
5007
|
// src/main/tui/setup/ProviderDialog.tsx
|
|
4927
5008
|
var import_jsx_runtime25 = __toESM(require_jsx_runtime(), 1), GROUP_LABEL = { subscription: "sign in", api: "API key", local: "local", other: "any URL" };
|
|
4928
5009
|
function ProviderDialog({ overlay, close, width, height }) {
|
|
4929
|
-
let theme2 = useTheme(), store = useStore(), rows = (0,
|
|
4930
|
-
(0,
|
|
5010
|
+
let theme2 = useTheme(), store = useStore(), rows = (0, import_react21.useMemo)(providerRows, []), preset = findProviderRow(String(overlay.props?.preset ?? "")), [step, setStep] = (0, import_react21.useState)(preset && !preset.signIn ? { kind: "form", entry: preset.entry } : { kind: "pick" }), [index, setIndex] = (0, import_react21.useState)(() => Math.max(0, rows.findIndex((r) => r.entry.group === "api"))), [values, setValues] = (0, import_react21.useState)(() => preset && !preset.signIn ? initialValues(preset.entry) : {}), [errors, setErrors] = (0, import_react21.useState)({}), [formError, setFormError] = (0, import_react21.useState)(null), alive = (0, import_react21.useRef)(!0);
|
|
5011
|
+
(0, import_react21.useEffect)(() => () => {
|
|
4931
5012
|
alive.current = !1;
|
|
4932
5013
|
}, []);
|
|
4933
5014
|
let dialogWidth = Math.max(50, Math.min(width - 4, 84)), inner = dialogWidth - 4, choose = (row4) => {
|
|
@@ -5067,20 +5148,20 @@ function initialValues(entry) {
|
|
|
5067
5148
|
}
|
|
5068
5149
|
|
|
5069
5150
|
// src/main/tui/setup/McpDialog.tsx
|
|
5070
|
-
var
|
|
5151
|
+
var import_react22 = __toESM(require_react(), 1);
|
|
5071
5152
|
var import_jsx_runtime26 = __toESM(require_jsx_runtime(), 1);
|
|
5072
5153
|
function McpDialog({ overlay, close, width, height }) {
|
|
5073
|
-
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, agentId = props.agentId ?? store.getState().selectedAgentId ?? "", agent2 = useTuiSelector((s) => s.agents[agentId]), who = agent2?.summary.handle || agent2?.summary.name || agentId, sources2 = (0,
|
|
5154
|
+
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, agentId = props.agentId ?? store.getState().selectedAgentId ?? "", agent2 = useTuiSelector((s) => s.agents[agentId]), who = agent2?.summary.handle || agent2?.summary.name || agentId, sources2 = (0, import_react22.useMemo)(mcpSourceRows, []), [diag, setDiag] = (0, import_react22.useState)(null), [config2, setConfig] = (0, import_react22.useState)(null), [loadError, setLoadError] = (0, import_react22.useState)(null), initial = () => {
|
|
5074
5155
|
if (props.add !== void 0) {
|
|
5075
5156
|
let target2 = parseAddTarget(props.add);
|
|
5076
5157
|
return target2.row ? { kind: "form", row: target2.row } : { kind: "source" };
|
|
5077
5158
|
}
|
|
5078
5159
|
return props.server ? { kind: props.view === "logs" ? "logs" : "detail", name: props.server } : { kind: "list" };
|
|
5079
|
-
}, [step, setStep] = (0,
|
|
5160
|
+
}, [step, setStep] = (0, import_react22.useState)(initial), [index, setIndex] = (0, import_react22.useState)(0), [values, setValues] = (0, import_react22.useState)(() => {
|
|
5080
5161
|
let target2 = parseAddTarget(props.add);
|
|
5081
5162
|
return target2.row ? initialForm(target2.row, target2.value) : {};
|
|
5082
|
-
}), [errors, setErrors] = (0,
|
|
5083
|
-
(0,
|
|
5163
|
+
}), [errors, setErrors] = (0, import_react22.useState)({}), [formError, setFormError] = (0, import_react22.useState)(null), [stored, setStored] = (0, import_react22.useState)(null), pending = (0, import_react22.useRef)(null), alive = (0, import_react22.useRef)(!0);
|
|
5164
|
+
(0, import_react22.useEffect)(() => () => {
|
|
5084
5165
|
alive.current = !1;
|
|
5085
5166
|
}, []);
|
|
5086
5167
|
let direct = props.add !== void 0 || !!props.server, refresh2 = async () => {
|
|
@@ -5092,13 +5173,13 @@ function McpDialog({ overlay, close, width, height }) {
|
|
|
5092
5173
|
alive.current && setLoadError(err instanceof Error ? err.message : String(err));
|
|
5093
5174
|
}
|
|
5094
5175
|
};
|
|
5095
|
-
(0,
|
|
5176
|
+
(0, import_react22.useEffect)(() => {
|
|
5096
5177
|
agentId && refresh2();
|
|
5097
5178
|
}, [agentId]);
|
|
5098
5179
|
let servers = config2?.mcp?.servers ?? [], stateOf = (name2) => diag?.states.find((s) => s.name === name2), serverOf = (name2) => servers.find((s) => s.name === name2), hostAllowed = !!config2?.compute?.host_access, dialogWidth = Math.max(56, Math.min(width - 4, 96)), inner = dialogWidth - 4, back = () => {
|
|
5099
5180
|
direct ? close() : setStep({ kind: "list" });
|
|
5100
5181
|
};
|
|
5101
|
-
(0,
|
|
5182
|
+
(0, import_react22.useEffect)(() => {
|
|
5102
5183
|
config2 && !hostAllowed && values.runOn === "host" && setValues((v) => ({ ...v, runOn: "container" }));
|
|
5103
5184
|
}, [config2, step.kind]);
|
|
5104
5185
|
let restart = async (name2) => {
|
|
@@ -5598,7 +5679,7 @@ function parseEnvPairs(text) {
|
|
|
5598
5679
|
}
|
|
5599
5680
|
|
|
5600
5681
|
// src/main/tui/templates/TemplatesDialog.tsx
|
|
5601
|
-
var
|
|
5682
|
+
var import_react23 = __toESM(require_react(), 1);
|
|
5602
5683
|
|
|
5603
5684
|
// src/main/tui/templates/model.ts
|
|
5604
5685
|
var TEMPLATES_OVERLAY = "templates", SHIPPED_ORDER = ["standard", "sandboxed", "full-access"], INSTANTIATE_RULE = "New agents get everything in a template except its identity and history.", NAME_HINT = "Use letters, digits, dashes, underscores and spaces.", NAME_RULE = /^[A-Za-z0-9 _-]+$/;
|
|
@@ -5915,9 +5996,9 @@ function errorOf(err) {
|
|
|
5915
5996
|
return { message: err instanceof Error ? err.message : String(err) };
|
|
5916
5997
|
}
|
|
5917
5998
|
function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
5918
|
-
let theme2 = useTheme(), store = useStore(), { suspendTerminal } = use_app_default(), props = overlay.props ?? {}, slotKey = `${TEMPLATES_OVERLAY}.dialog:${overlay.id}`, initial = (0,
|
|
5999
|
+
let theme2 = useTheme(), store = useStore(), { suspendTerminal } = use_app_default(), props = overlay.props ?? {}, slotKey = `${TEMPLATES_OVERLAY}.dialog:${overlay.id}`, initial = (0, import_react23.useRef)({ step: props.id ? { kind: "detail", id: props.id } : { kind: "list" }, index: 0, fileIndex: 0, list: null, detail: null, loadError: null, error: null }).current, read = () => store.getState().viewState[slotKey] ?? initial, patch = (next) => store.actions.setViewState(slotKey, { ...read(), ...next }), { step, index, fileIndex, list, detail, loadError, error } = useTuiSelector((s) => s.viewState[slotKey] ?? initial), setList = (value) => patch({ list: value }), setDetail = (value) => patch({ detail: value }), setLoadError = (value) => patch({ loadError: value }), setError = (value) => patch({ error: value }), setStep = (value) => patch({ step: value }), setIndex = (value) => patch({ index: value }), setFileIndex = (value) => patch({ fileIndex: value }), close = () => {
|
|
5919
6000
|
closeOverlay(), store.actions.setViewState(slotKey, null);
|
|
5920
|
-
}, [values, setValues] = (0,
|
|
6001
|
+
}, [values, setValues] = (0, import_react23.useState)({}), [errors, setErrors] = (0, import_react23.useState)({}), dialogWidth = Math.max(56, Math.min(width - 4, 104)), inner = dialogWidth - 4, templates = sortTemplates(list?.templates ?? []), byId = (id) => templates.find((t) => t.id === id), label2 = (id) => byId(id)?.name ?? id, loadList = async () => {
|
|
5921
6002
|
try {
|
|
5922
6003
|
let next = await store.client.templates();
|
|
5923
6004
|
patch({ list: next, loadError: null });
|
|
@@ -5934,11 +6015,11 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
5934
6015
|
}, refresh2 = async (id) => {
|
|
5935
6016
|
await loadList(), id && await loadDetail(id);
|
|
5936
6017
|
};
|
|
5937
|
-
(0,
|
|
6018
|
+
(0, import_react23.useEffect)(() => {
|
|
5938
6019
|
!read().list && !read().loadError && refresh2(props.id);
|
|
5939
6020
|
}, []);
|
|
5940
6021
|
let stepId = "id" in step ? step.id : void 0;
|
|
5941
|
-
(0,
|
|
6022
|
+
(0, import_react23.useEffect)(() => {
|
|
5942
6023
|
(step.kind === "detail" || step.kind === "files") && step.id !== detail?.template?.id && loadDetail(step.id);
|
|
5943
6024
|
}, [step.kind, stepId]);
|
|
5944
6025
|
let act = async (labelText, back, fn) => {
|
|
@@ -6266,7 +6347,7 @@ function TemplatesDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
6266
6347
|
}
|
|
6267
6348
|
|
|
6268
6349
|
// src/main/tui/skills/SkillsDialog.tsx
|
|
6269
|
-
var
|
|
6350
|
+
var import_react24 = __toESM(require_react(), 1);
|
|
6270
6351
|
|
|
6271
6352
|
// src/shared/utils/skill-preview.ts
|
|
6272
6353
|
var skill_preview_exports = {};
|
|
@@ -6587,25 +6668,8 @@ function describeDiff(before, after, preview = 6) {
|
|
|
6587
6668
|
return diff.changes.length > preview && lines.push(` \u2026 ${diff.changes.length - preview} more changed lines`), { summary, lines };
|
|
6588
6669
|
}
|
|
6589
6670
|
|
|
6590
|
-
// src/shared/types/resource-revision.types.ts
|
|
6591
|
-
var resource_revision_types_exports = {};
|
|
6592
|
-
__export(resource_revision_types_exports, {
|
|
6593
|
-
describeWriter: () => describeWriter
|
|
6594
|
-
});
|
|
6595
|
-
function describeWriter(writer2) {
|
|
6596
|
-
if (!writer2) return "someone else";
|
|
6597
|
-
switch (writer2.kind) {
|
|
6598
|
-
case "agent":
|
|
6599
|
-
return "the agent";
|
|
6600
|
-
case "cli":
|
|
6601
|
-
return "the CLI or another API client";
|
|
6602
|
-
case "client":
|
|
6603
|
-
return writer2.client === "studio" ? "another Studio window" : writer2.client === "tui" ? "the terminal app" : `another client (${writer2.client})`;
|
|
6604
|
-
}
|
|
6605
|
-
}
|
|
6606
|
-
|
|
6607
6671
|
// src/main/tui/util/revisions.ts
|
|
6608
|
-
var { describeWriter
|
|
6672
|
+
var { describeWriter } = cjs(resource_revision_types_exports);
|
|
6609
6673
|
function revisionOf(result) {
|
|
6610
6674
|
let revision = result?.revision;
|
|
6611
6675
|
return typeof revision == "number" ? revision : void 0;
|
|
@@ -6616,7 +6680,7 @@ function staleRevisionOf(err) {
|
|
|
6616
6680
|
return body?.code !== "stale_revision" || typeof body.revision != "number" ? null : { revision: body.revision, writer: body.writer ?? null };
|
|
6617
6681
|
}
|
|
6618
6682
|
function changedBy(stale) {
|
|
6619
|
-
return `changed by ${
|
|
6683
|
+
return `changed by ${describeWriter(stale.writer)}`;
|
|
6620
6684
|
}
|
|
6621
6685
|
async function writeOver(write2) {
|
|
6622
6686
|
try {
|
|
@@ -7101,7 +7165,7 @@ async function readLocalPackage(input, cwd = process.cwd()) {
|
|
|
7101
7165
|
// src/main/tui/skills/SkillsDialog.tsx
|
|
7102
7166
|
var import_jsx_runtime28 = __toESM(require_jsx_runtime(), 1), { catalogSourceLabel: catalogSourceLabel2, filterCatalogEntries: filterCatalogEntries2, mergeCatalogResults: mergeCatalogResults2, unindexedHint: unindexedHint2, MAX_SKILL_FILE_BYTES: MAX_SKILL_FILE_BYTES3 } = cjs(skills_panel_exports), { elideMiddle: elideMiddle2 } = cjs(skill_preview_exports), errorText3 = (err) => err instanceof Error ? err.message : String(err);
|
|
7103
7167
|
function SkillsDialog({ overlay, close, width, height }) {
|
|
7104
|
-
let theme2 = useTheme(), store = useStore(), { suspendTerminal } = use_app_default(), props = overlay.props ?? {}, agentId = props.agentId ?? store.getState().selectedAgentId ?? "", agent2 = useTuiSelector((s) => s.agents[agentId]), who = agent2?.summary.handle || agent2?.summary.name || agentId, direct = props.add !== void 0 || !!props.skill, fresh = (0,
|
|
7168
|
+
let theme2 = useTheme(), store = useStore(), { suspendTerminal } = use_app_default(), props = overlay.props ?? {}, agentId = props.agentId ?? store.getState().selectedAgentId ?? "", agent2 = useTuiSelector((s) => s.agents[agentId]), who = agent2?.summary.handle || agent2?.summary.name || agentId, direct = props.add !== void 0 || !!props.skill, fresh = (0, import_react24.useMemo)(() => {
|
|
7105
7169
|
let start = initialStep(props);
|
|
7106
7170
|
return { ...EMPTY_VIEW_STATE, overlayId: overlay.id, step: start.step, query: start.query, extra: start.extra };
|
|
7107
7171
|
}, [overlay.id]), raw = useTuiSelector((s) => s.viewState[SKILLS_OVERLAY]), vs = raw && raw.overlayId === overlay.id ? raw : fresh, read = () => {
|
|
@@ -7113,13 +7177,13 @@ function SkillsDialog({ overlay, close, width, height }) {
|
|
|
7113
7177
|
let base2 = read();
|
|
7114
7178
|
store.actions.setViewState(SKILLS_OVERLAY, { ...base2, ...typeof next == "function" ? next(base2) : next, overlayId: overlay.id });
|
|
7115
7179
|
};
|
|
7116
|
-
(0,
|
|
7180
|
+
(0, import_react24.useEffect)(() => {
|
|
7117
7181
|
(!raw || raw.overlayId !== overlay.id) && patch({});
|
|
7118
7182
|
}, [overlay.id]);
|
|
7119
|
-
let step = vs.step, setStep = (next) => patch({ step: next }), [data, setData] = (0,
|
|
7120
|
-
(0,
|
|
7183
|
+
let step = vs.step, setStep = (next) => patch({ step: next }), [data, setData] = (0, import_react24.useState)(null), [loadError, setLoadError] = (0, import_react24.useState)(null), alive = (0, import_react24.useRef)(!0);
|
|
7184
|
+
(0, import_react24.useEffect)(() => () => {
|
|
7121
7185
|
alive.current = !1;
|
|
7122
|
-
}, []), (0,
|
|
7186
|
+
}, []), (0, import_react24.useEffect)(() => {
|
|
7123
7187
|
if (!agentId) return;
|
|
7124
7188
|
let cancelled = !1;
|
|
7125
7189
|
return loadInstalled(store.client, agentId).then((next) => {
|
|
@@ -7130,13 +7194,13 @@ function SkillsDialog({ overlay, close, width, height }) {
|
|
|
7130
7194
|
cancelled = !0;
|
|
7131
7195
|
};
|
|
7132
7196
|
}, [agentId, vs.rev]);
|
|
7133
|
-
let model2 = (0,
|
|
7197
|
+
let model2 = (0, import_react24.useMemo)(() => data ? buildInstalled(data.files, data.registryText, vs.overrides) : null, [data, vs.overrides]), rows = (0, import_react24.useMemo)(() => model2 ? [
|
|
7134
7198
|
...model2.skills.map((skill) => ({ type: "skill", key: `s:${skill.name}`, skill })),
|
|
7135
7199
|
...model2.problems.map((p) => ({ type: "problem", key: `p:${p.key}`, label: p.label, path: p.path, reason: p.reason, isPackage: p.isPackage }))
|
|
7136
7200
|
] : [], [model2]), bump = () => {
|
|
7137
7201
|
patch((s) => ({ rev: s.rev + 1 })), setTimeout(() => patch((s) => ({ rev: s.rev + 1 })), 700);
|
|
7138
7202
|
}, needsCatalog = step.kind === "catalog" || step.kind === "package" && step.source.type === "catalog";
|
|
7139
|
-
(0,
|
|
7203
|
+
(0, import_react24.useEffect)(() => {
|
|
7140
7204
|
if (!needsCatalog || read().catalog) return;
|
|
7141
7205
|
let extra = read().extra;
|
|
7142
7206
|
patch({ catalog: { loading: !0, sources: extra, results: [] } }), (async () => {
|
|
@@ -7151,18 +7215,18 @@ function SkillsDialog({ overlay, close, width, height }) {
|
|
|
7151
7215
|
}
|
|
7152
7216
|
})();
|
|
7153
7217
|
}, [needsCatalog]);
|
|
7154
|
-
let merged = (0,
|
|
7218
|
+
let merged = (0, import_react24.useMemo)(() => mergeCatalogResults2(vs.catalog?.results ?? []), [vs.catalog?.results]), visible = (0, import_react24.useMemo)(() => filterCatalogEntries2(merged, vs.query), [merged, vs.query]), pkgKey = step.kind === "package" ? packageKey(step.source) : null, pkgState = pkgKey ? vs.packages[pkgKey] : void 0, loadPkg = (force = !1) => {
|
|
7155
7219
|
if (step.kind !== "package" || !pkgKey || !force && read().packages[pkgKey]) return;
|
|
7156
7220
|
let source = step.source;
|
|
7157
7221
|
patch((s) => ({ packages: { ...s.packages, [pkgKey]: { status: "loading" } } })), loadPackage(source).then((result) => {
|
|
7158
7222
|
patch((s) => ({ packages: { ...s.packages, [pkgKey]: result.ok ? { status: "ready", pkg: result.pkg } : { status: "error", error: result.error } } }));
|
|
7159
7223
|
}, (err) => patch((s) => ({ packages: { ...s.packages, [pkgKey]: { status: "error", error: errorText3(err) } } })));
|
|
7160
7224
|
};
|
|
7161
|
-
(0,
|
|
7225
|
+
(0, import_react24.useEffect)(() => {
|
|
7162
7226
|
loadPkg();
|
|
7163
7227
|
}, [pkgKey]);
|
|
7164
|
-
let [doc, setDoc] = (0,
|
|
7165
|
-
(0,
|
|
7228
|
+
let [doc, setDoc] = (0, import_react24.useState)(null), viewPath = step.kind === "view" ? step.path : null;
|
|
7229
|
+
(0, import_react24.useEffect)(() => {
|
|
7166
7230
|
if (!viewPath || !agentId) return;
|
|
7167
7231
|
let cancelled = !1;
|
|
7168
7232
|
return readSkillFile(store.client, agentId, viewPath).then(
|
|
@@ -7399,7 +7463,7 @@ function CatalogRow({ entry, installed, selected, width }) {
|
|
|
7399
7463
|
] });
|
|
7400
7464
|
}
|
|
7401
7465
|
function SkillDoc({ manifest, width, height }) {
|
|
7402
|
-
let theme2 = useTheme(), parts = (0,
|
|
7466
|
+
let theme2 = useTheme(), parts = (0, import_react24.useMemo)(() => previewParts(manifest), [manifest]), [offset, setOffset] = (0, import_react24.useState)(0), innerRef = (0, import_react24.useRef)(null), outerRef = (0, import_react24.useRef)(null), metrics = use_box_metrics_default(innerRef), rows = Math.max(1, height - 1), total = metrics.hasMeasured ? metrics.height : 0, maxOffset = Math.max(0, total - rows), at = Math.min(offset, maxOffset), move = (next) => setOffset(Math.max(0, Math.min(maxOffset, next)));
|
|
7403
7467
|
useWheel(outerRef, (delta) => move(at + delta * WHEEL_STEP), { layer: "overlay" }), useKeys((input, key) => key.upArrow || input === "k" && !key.ctrl ? (move(at - 1), !0) : key.downArrow || input === "j" && !key.ctrl ? (move(at + 1), !0) : key.pageUp ? (move(at - rows), !0) : key.pageDown ? (move(at + rows), !0) : key.home || input === "g" ? (move(0), !0) : key.end || input === "G" ? (move(maxOffset), !0) : !1, { layer: "overlay" });
|
|
7404
7468
|
let keyWidth = Math.min(16, Math.max(4, ...parts.fields.map((f) => f.key.length)) + 1);
|
|
7405
7469
|
return /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Box_default, { ref: outerRef, flexDirection: "column", width, height, marginTop: 1, children: [
|
|
@@ -7416,7 +7480,7 @@ function SkillDoc({ manifest, width, height }) {
|
|
|
7416
7480
|
}
|
|
7417
7481
|
|
|
7418
7482
|
// src/main/tui/context/ContextDialog.tsx
|
|
7419
|
-
var
|
|
7483
|
+
var import_react25 = __toESM(require_react(), 1);
|
|
7420
7484
|
|
|
7421
7485
|
// src/main/tui/context/model.ts
|
|
7422
7486
|
var { resolveLoopThreshold, calibrationNote } = cjs(context_breakdown_exports), CONTEXT_OVERLAY = "context";
|
|
@@ -7486,7 +7550,7 @@ function pressureColor(theme2, percent) {
|
|
|
7486
7550
|
return p === "high" ? theme2.color.error : p === "warn" ? theme2.color.warn : theme2.color.success;
|
|
7487
7551
|
}
|
|
7488
7552
|
function ContextDialog({ overlay, close: closeOverlay, width, height }) {
|
|
7489
|
-
let theme2 = useTheme(), store = useStore(), g = theme2.glyph, props = overlay.props ?? {}, agentId = props.agentId ?? "", slotKey = `${CONTEXT_OVERLAY}.dialog:${overlay.id}`, initial = (0,
|
|
7553
|
+
let theme2 = useTheme(), store = useStore(), g = theme2.glyph, props = overlay.props ?? {}, agentId = props.agentId ?? "", slotKey = `${CONTEXT_OVERLAY}.dialog:${overlay.id}`, initial = (0, import_react25.useRef)({ loop: props.loop || MAIN_LOOP, data: null, error: null, loading: !1, compacting: !1, cursor: null, expanded: null, start: 0, measuredAt: null }).current, read = () => store.getState().viewState[slotKey] ?? initial, alive = () => store.getState().overlays.some((o) => o.id === overlay.id), patch = (next) => {
|
|
7490
7554
|
alive() && store.actions.setViewState(slotKey, { ...read(), ...next });
|
|
7491
7555
|
}, s = useTuiSelector((state) => state.viewState[slotKey] ?? initial), agent2 = useTuiSelector((state) => state.agents[agentId]), close = () => {
|
|
7492
7556
|
closeOverlay(), store.actions.setViewState(slotKey, null);
|
|
@@ -7504,7 +7568,7 @@ function ContextDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
7504
7568
|
}
|
|
7505
7569
|
}
|
|
7506
7570
|
};
|
|
7507
|
-
(0,
|
|
7571
|
+
(0, import_react25.useEffect)(() => {
|
|
7508
7572
|
!read().data && !read().error && load(read().loop), agentId && !store.getState().agents[agentId]?.loops && store.actions.refreshLoops(agentId);
|
|
7509
7573
|
}, []);
|
|
7510
7574
|
let compact2 = async () => {
|
|
@@ -7518,7 +7582,7 @@ function ContextDialog({ overlay, close: closeOverlay, width, height }) {
|
|
|
7518
7582
|
let done = await store.actions.compactLoop(agentId, loop);
|
|
7519
7583
|
patch({ compacting: !1 }), done && await load(loop);
|
|
7520
7584
|
}, categories = s.data?.categories ?? [], cursor = categoryIndex(categories, s.cursor), selected = categories[cursor], rows = contextRows(categories, s.expanded), cursorRow = rows.findIndex((r) => r.kind === "category" && r.category.id === selected?.id), dialogWidth = Math.max(40, Math.min(width - 4, 96)), inner = dialogWidth - 4, rowsHeight = Math.max(3, height - 16), start = windowStart(rows.length, Math.max(0, cursorRow), rowsHeight, s.start);
|
|
7521
|
-
(0,
|
|
7585
|
+
(0, import_react25.useEffect)(() => {
|
|
7522
7586
|
start !== s.start && patch({ start });
|
|
7523
7587
|
}, [start]), useKeys((input, key) => {
|
|
7524
7588
|
if (key.escape) return !1;
|
|
@@ -7729,7 +7793,7 @@ async function copySiteUrl(store, agentId) {
|
|
|
7729
7793
|
}
|
|
7730
7794
|
|
|
7731
7795
|
// src/main/tui/app/Shell.tsx
|
|
7732
|
-
var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1), SIDEBAR_MIN_COLUMNS = 70, PROMPT_ROWS = 3, RESIZE_SETTLE_MS = 150, CLEAR_SCREEN = "\x1B[2J\x1B[H", DOUBLE_ESC_MS = 600, ViewErrorBoundary = class extends
|
|
7796
|
+
var import_jsx_runtime31 = __toESM(require_jsx_runtime(), 1), SIDEBAR_MIN_COLUMNS = 70, PROMPT_ROWS = 3, RESIZE_SETTLE_MS = 150, CLEAR_SCREEN = "\x1B[2J\x1B[H", DOUBLE_ESC_MS = 600, ViewErrorBoundary = class extends import_react26.Component {
|
|
7733
7797
|
state = { error: null };
|
|
7734
7798
|
static getDerivedStateFromError(error) {
|
|
7735
7799
|
return { error };
|
|
@@ -7760,8 +7824,8 @@ function cycleLoop2(store, delta) {
|
|
|
7760
7824
|
store.actions.selectLoop(agentId, loops2[(at + delta + loops2.length) % loops2.length].info.name);
|
|
7761
7825
|
}
|
|
7762
7826
|
function Shell() {
|
|
7763
|
-
let theme2 = useTheme(), store = useStore(), router = useKeyRouter(), { views, exit, reserveRows = 0, reserveColumns = 0 } = useShell(), { columns: windowColumns, rows: windowRows } = use_window_size_default(), columns = Math.max(20, windowColumns - reserveColumns), rows = Math.max(6, windowRows - reserveRows), { write: write2 } = use_stdout_default(), { waitUntilRenderFlush } = use_app_default(), sized = (0,
|
|
7764
|
-
(0,
|
|
7827
|
+
let theme2 = useTheme(), store = useStore(), router = useKeyRouter(), { views, exit, reserveRows = 0, reserveColumns = 0 } = useShell(), { columns: windowColumns, rows: windowRows } = use_window_size_default(), columns = Math.max(20, windowColumns - reserveColumns), rows = Math.max(6, windowRows - reserveRows), { write: write2 } = use_stdout_default(), { waitUntilRenderFlush } = use_app_default(), sized = (0, import_react26.useRef)(`${windowColumns}x${windowRows}`);
|
|
7828
|
+
(0, import_react26.useEffect)(() => {
|
|
7765
7829
|
let size = `${windowColumns}x${windowRows}`;
|
|
7766
7830
|
if (sized.current === size) return;
|
|
7767
7831
|
sized.current = size;
|
|
@@ -7774,23 +7838,23 @@ function Shell() {
|
|
|
7774
7838
|
cancelled = !0, clearTimeout(timer);
|
|
7775
7839
|
};
|
|
7776
7840
|
}, [windowColumns, windowRows]);
|
|
7777
|
-
let activeView = useActiveView(), focus = useFocus(), overlays = useOverlays(), toasts = useToasts(), viewRef = (0,
|
|
7778
|
-
(0,
|
|
7841
|
+
let activeView = useActiveView(), focus = useFocus(), overlays = useOverlays(), toasts = useToasts(), viewRef = (0, import_react26.useRef)(null), sidebarRef = (0, import_react26.useRef)(null), promptRef = (0, import_react26.useRef)(null), sidebarHidden = useTuiSelector((s) => readLayout(s).sidebarHidden), headerRef = (0, import_react26.useRef)(null), headerHits = (0, import_react26.useMemo)(() => createHeaderHits(), []), metrics = use_box_metrics_default(viewRef), quitGuard = (0, import_react26.useMemo)(() => createQuitGuard(), []), lastEscAt = (0, import_react26.useRef)(0), view2 = views.find((v) => v.id === activeView) ?? views[0], showSidebar = !!view2 && !view2.fullWidth && !sidebarHidden && columns >= SIDEBAR_MIN_COLUMNS, sidebarWidth = Math.max(22, Math.min(34, Math.floor(columns * 0.24))), mainWidth = Math.max(10, columns - (showSidebar ? sidebarWidth : 0)), promptShown = !!view2 && view2.prompt !== !1, toastRows = Math.min(3, toasts.length), bodyHeight = Math.max(3, rows - 2 - toastRows), viewHeight = metrics.hasMeasured ? metrics.height : Math.max(1, bodyHeight - (promptShown ? PROMPT_ROWS : 0)), viewWidth = metrics.hasMeasured ? metrics.width : mainWidth, overlayOpen = overlays.length > 0, zones = [...showSidebar ? ["sidebar"] : [], "main", ...promptShown ? ["input"] : []];
|
|
7842
|
+
(0, import_react26.useEffect)(() => {
|
|
7779
7843
|
focus !== "tabs" && !zones.includes(focus) && store.actions.setFocus("main");
|
|
7780
|
-
}, [focus, showSidebar, promptShown]), (0,
|
|
7844
|
+
}, [focus, showSidebar, promptShown]), (0, import_react26.useEffect)(() => {
|
|
7781
7845
|
store.getState().viewState[TABS_CURSOR_KEY] && store.actions.setViewState(TABS_CURSOR_KEY, null);
|
|
7782
7846
|
}, [activeView]);
|
|
7783
|
-
let enterZone = (id) => id === "chat" && views.find((v) => v.id === id)?.prompt !== !1 ? "input" : "main", live = (0,
|
|
7847
|
+
let enterZone = (id) => id === "chat" && views.find((v) => v.id === id)?.prompt !== !1 ? "input" : "main", live = (0, import_react26.useRef)({ columns: windowColumns, rows: windowRows, promptShown });
|
|
7784
7848
|
live.current = { columns: windowColumns, rows: windowRows, promptShown };
|
|
7785
7849
|
let { internal_eventEmitter: stdinEvents } = use_stdin_default();
|
|
7786
|
-
(0,
|
|
7850
|
+
(0, import_react26.useLayoutEffect)(() => {
|
|
7787
7851
|
if (!stdinEvents) return;
|
|
7788
7852
|
let onInput = (data) => noteRawInput(typeof data == "string" ? data : String(data));
|
|
7789
7853
|
return stdinEvents.prependListener("input", onInput), () => {
|
|
7790
7854
|
stdinEvents.removeListener("input", onInput);
|
|
7791
7855
|
};
|
|
7792
|
-
}, [stdinEvents]), (0,
|
|
7793
|
-
let mouseCtl = (0,
|
|
7856
|
+
}, [stdinEvents]), (0, import_react26.useEffect)(() => (setRepaint(() => write2("")), () => setRepaint(null)), [write2]);
|
|
7857
|
+
let mouseCtl = (0, import_react26.useMemo)(() => createMouseController({
|
|
7794
7858
|
now: () => Date.now(),
|
|
7795
7859
|
screen: getScreenText,
|
|
7796
7860
|
paneAt: (x, y) => {
|
|
@@ -8781,10 +8845,10 @@ var url = {
|
|
|
8781
8845
|
], BUILTIN_COMMANDS = { commands, actions };
|
|
8782
8846
|
|
|
8783
8847
|
// src/main/tui/ui/Table.tsx
|
|
8784
|
-
var
|
|
8848
|
+
var import_react27 = __toESM(require_react(), 1);
|
|
8785
8849
|
var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
|
|
8786
8850
|
function Table({ columns, rows, getKey, width, selectedIndex, height, emptyText = "No rows.", onWheel }) {
|
|
8787
|
-
let theme2 = useTheme(), boxRef = (0,
|
|
8851
|
+
let theme2 = useTheme(), boxRef = (0, import_react27.useRef)(null);
|
|
8788
8852
|
useWheel(boxRef, (delta) => onWheel?.(delta), { active: !!onWheel });
|
|
8789
8853
|
let gap = 1, fixed = columns.reduce((sum, c) => sum + (c.width ?? 0), 0), flexible = columns.filter((c) => c.width === void 0), spare = Math.max(0, width - fixed - gap * (columns.length - 1) - 2), share = flexible.length ? Math.floor(spare / flexible.length) : 0, widths = columns.map((c) => c.width ?? Math.max(c.minWidth ?? 6, share)), bodyRows = height === void 0 ? rows.length : Math.max(0, height - 1), selected = selectedIndex ?? -1, start = selected >= bodyRows ? selected - bodyRows + 1 : 0, visible = rows.slice(start, start + bodyRows), line = (cells2) => cells2.join(" ".repeat(gap));
|
|
8790
8854
|
return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Box_default, { ref: boxRef, flexDirection: "column", width, children: [
|
|
@@ -9155,12 +9219,12 @@ var agentsCommand = {
|
|
|
9155
9219
|
};
|
|
9156
9220
|
|
|
9157
9221
|
// src/main/tui/views/fleet/LoadDialog.tsx
|
|
9158
|
-
var
|
|
9222
|
+
var import_react28 = __toESM(require_react(), 1);
|
|
9159
9223
|
import { existsSync as existsSync2, statSync as statSync2 } from "node:fs";
|
|
9160
9224
|
import { sep as sep2 } from "node:path";
|
|
9161
9225
|
var import_jsx_runtime33 = __toESM(require_jsx_runtime(), 1), LAST_DIR_KEY = "fleet.load.lastDir", MAX_CANDIDATES = 8;
|
|
9162
9226
|
function LoadDialog({ overlay, close, width }) {
|
|
9163
|
-
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, [lastDir, setLastDir] = useViewState(LAST_DIR_KEY, ""), [value, setValue] = (0,
|
|
9227
|
+
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, [lastDir, setLastDir] = useViewState(LAST_DIR_KEY, ""), [value, setValue] = (0, import_react28.useState)(props.path ?? (lastDir || `${process.cwd()}${sep2}`)), [candidates, setCandidates] = (0, import_react28.useState)([]), [requireReview, setRequireReview] = (0, import_react28.useState)(!!props.requireReview), [start, setStart] = (0, import_react28.useState)(!!props.start), [problem, setProblem] = (0, import_react28.useState)(null), [warned, setWarned] = (0, import_react28.useState)(null), dialogWidth = Math.max(40, Math.min(width - 4, 90)), submit = (text) => {
|
|
9164
9228
|
let raw = text.trim();
|
|
9165
9229
|
if (!raw)
|
|
9166
9230
|
return setProblem("Type a path to an .adf file"), !1;
|
|
@@ -9243,11 +9307,11 @@ function LoadDialog({ overlay, close, width }) {
|
|
|
9243
9307
|
}
|
|
9244
9308
|
|
|
9245
9309
|
// src/main/tui/views/fleet/TrackDialog.tsx
|
|
9246
|
-
var
|
|
9310
|
+
var import_react30 = __toESM(require_react(), 1);
|
|
9247
9311
|
import { sep as sep3 } from "node:path";
|
|
9248
9312
|
|
|
9249
9313
|
// src/main/tui/views/fleet/FolderAgentsDialog.tsx
|
|
9250
|
-
var
|
|
9314
|
+
var import_react29 = __toESM(require_react(), 1);
|
|
9251
9315
|
var import_jsx_runtime34 = __toESM(require_jsx_runtime(), 1);
|
|
9252
9316
|
function glyphOf(theme2, agent2) {
|
|
9253
9317
|
if (agent2.error || agent2.status === "unreadable") return { glyph: theme2.glyph.cross, color: theme2.color.error };
|
|
@@ -9271,8 +9335,8 @@ function reviewLines2(info) {
|
|
|
9271
9335
|
return triggers.length && lines.push(`Triggers: ${triggers.join(", ")}`), lines;
|
|
9272
9336
|
}
|
|
9273
9337
|
function FolderAgentsDialog({ overlay, close, width, height }) {
|
|
9274
|
-
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, folder = props.folder, [agents, setAgents] = (0,
|
|
9275
|
-
(0,
|
|
9338
|
+
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, folder = props.folder, [agents, setAgents] = (0, import_react29.useState)(props.result?.agents ?? null), [loadError, setLoadError] = (0, import_react29.useState)(null), [cursor, setCursor] = (0, import_react29.useState)(0), [mode, setMode] = (0, import_react29.useState)({ kind: "list" }), [busy, setBusy] = (0, import_react29.useState)(null), [note, setNote] = (0, import_react29.useState)(null), [rev, setRev] = (0, import_react29.useState)(props.result?.agents ? 0 : 1), [pendingReview, setPendingReview] = (0, import_react29.useState)(props.review ?? null), [errors, setErrors] = (0, import_react29.useState)(() => Object.fromEntries((props.result?.agents ?? []).filter((a) => a.error && a.status !== "unreadable").map((a) => [a.filePath, a.error]))), dialogWidth = Math.max(44, Math.min(width - 4, 100)), inner = dialogWidth - 4;
|
|
9339
|
+
(0, import_react29.useEffect)(() => {
|
|
9276
9340
|
if (rev === 0) return;
|
|
9277
9341
|
let live = !0;
|
|
9278
9342
|
return store.client.folderAgents(folder).then(
|
|
@@ -9287,7 +9351,7 @@ function FolderAgentsDialog({ overlay, close, width, height }) {
|
|
|
9287
9351
|
};
|
|
9288
9352
|
}, [rev, folder]);
|
|
9289
9353
|
let rows = (agents ?? []).map((a) => a.status !== "loaded" && !a.error && errors[a.filePath] ? { ...a, error: errors[a.filePath] } : a), at = Math.min(cursor, Math.max(0, rows.length - 1)), selected = rows[at];
|
|
9290
|
-
(0,
|
|
9354
|
+
(0, import_react29.useEffect)(() => {
|
|
9291
9355
|
if (!pendingReview || !agents) return;
|
|
9292
9356
|
let index = rows.findIndex((r) => r.filePath === pendingReview);
|
|
9293
9357
|
setPendingReview(null), !(index < 0) && (setCursor(index), rows[index].status === "needs_review" && openReview(rows[index]));
|
|
@@ -9433,7 +9497,7 @@ function TrackDialog(props) {
|
|
|
9433
9497
|
return props.overlay.props?.folder ? /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(FolderAgentsDialog, { ...props }) : /* @__PURE__ */ (0, import_jsx_runtime35.jsx)(TrackFolderInput, { ...props });
|
|
9434
9498
|
}
|
|
9435
9499
|
function TrackFolderInput({ overlay, close, width }) {
|
|
9436
|
-
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, [lastDir, setLastDir] = useViewState(LAST_DIR_KEY2, ""), [value, setValue] = (0,
|
|
9500
|
+
let theme2 = useTheme(), store = useStore(), props = overlay.props ?? {}, [lastDir, setLastDir] = useViewState(LAST_DIR_KEY2, ""), [value, setValue] = (0, import_react30.useState)(props.path ?? (lastDir || `${process.cwd()}${sep3}`)), [candidates, setCandidates] = (0, import_react30.useState)([]), [problem, setProblem] = (0, import_react30.useState)(null), [busy, setBusy] = (0, import_react30.useState)(!1), dialogWidth = Math.max(40, Math.min(width - 4, 90)), submit = (text) => {
|
|
9437
9501
|
if (busy) return !1;
|
|
9438
9502
|
let raw = text.trim();
|
|
9439
9503
|
if (!raw)
|
|
@@ -9502,10 +9566,10 @@ function TrackFolderInput({ overlay, close, width }) {
|
|
|
9502
9566
|
}
|
|
9503
9567
|
|
|
9504
9568
|
// src/main/tui/views/fleet/UntrackDialog.tsx
|
|
9505
|
-
var
|
|
9569
|
+
var import_react31 = __toESM(require_react(), 1);
|
|
9506
9570
|
var import_jsx_runtime36 = __toESM(require_jsx_runtime(), 1);
|
|
9507
9571
|
function UntrackDialog({ overlay, close, width }) {
|
|
9508
|
-
let theme2 = useTheme(), store = useStore(), path = String(overlay.props?.path ?? ""), [unload, setUnload] = (0,
|
|
9572
|
+
let theme2 = useTheme(), store = useStore(), path = String(overlay.props?.path ?? ""), [unload, setUnload] = (0, import_react31.useState)(!1);
|
|
9509
9573
|
return useKeys((input, key) => key.return || input === "y" || input === "Y" ? (close(), untrackFolder(store, path, unload), !0) : key.escape || input === "n" || input === "N" || key.ctrl && input === "c" ? (close(), !0) : ((input === "u" || input === " ") && setUnload((v) => !v), !0), { layer: "overlay" }), /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(
|
|
9510
9574
|
Modal,
|
|
9511
9575
|
{
|
|
@@ -9899,16 +9963,33 @@ var fleet = {
|
|
|
9899
9963
|
}, fleet_default = fleet;
|
|
9900
9964
|
|
|
9901
9965
|
// src/main/tui/views/chat/index.tsx
|
|
9902
|
-
var
|
|
9966
|
+
var import_react36 = __toESM(require_react(), 1);
|
|
9903
9967
|
|
|
9904
9968
|
// src/main/tui/views/chat/Transcript.tsx
|
|
9905
|
-
var
|
|
9969
|
+
var import_react32 = __toESM(require_react(), 1);
|
|
9906
9970
|
var import_jsx_runtime38 = __toESM(require_jsx_runtime(), 1);
|
|
9907
9971
|
function lineCount(text) {
|
|
9908
9972
|
return text ? text.split(`
|
|
9909
9973
|
`).length : 0;
|
|
9910
9974
|
}
|
|
9911
|
-
function
|
|
9975
|
+
function AskForm({ questions, answers }) {
|
|
9976
|
+
let theme2 = useTheme(), g = theme2.glyph;
|
|
9977
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_jsx_runtime38.Fragment, { children: questions.map((q, i) => {
|
|
9978
|
+
let answer = answers?.[i];
|
|
9979
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "column", children: [
|
|
9980
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { wrap: "wrap", color: theme2.color.text, children: q.question || " " }),
|
|
9981
|
+
answers ? answer != null ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.user, children: [
|
|
9982
|
+
g.pointer,
|
|
9983
|
+
" ",
|
|
9984
|
+
oneLine(answer) || "(empty)"
|
|
9985
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.dim, children: [
|
|
9986
|
+
g.pointer,
|
|
9987
|
+
" skipped"
|
|
9988
|
+
] }) : null
|
|
9989
|
+
] }, i);
|
|
9990
|
+
}) });
|
|
9991
|
+
}
|
|
9992
|
+
function ToolBody({ item, w, expanded, viewportHeight, clipBottom = 0 }) {
|
|
9912
9993
|
let theme2 = useTheme(), g = theme2.glyph, view2 = toolView(item), failed = item.status === "error", status = item.status === "running" ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Spinner, { color: theme2.color.tool }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { color: failed ? theme2.color.error : theme2.color.success, children: failed ? g.cross : g.check }), asyncBadge = isAsyncTool(item) ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { color: theme2.color.dim, children: " [async]" }) : null;
|
|
9913
9994
|
if (expanded && isExpandable(item)) {
|
|
9914
9995
|
let input = capLines(prettyJson(item.input), EXPANDED_TOOL_LINES), ref = shownTaskRef(item), task = ref !== void 0 ? capLines(ref, EXPANDED_TOOL_LINES) : null, result2 = capLines(item.result ?? "", EXPANDED_TOOL_LINES);
|
|
@@ -9959,7 +10040,7 @@ ${g.ellipsis} ${result2.more} more lines` : ""
|
|
|
9959
10040
|
" "
|
|
9960
10041
|
] }),
|
|
9961
10042
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { width: w - 2, flexDirection: "column", children: [
|
|
9962
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Markdown, { text: sayText(item) || " ", color: theme2.color.assistant }),
|
|
10043
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Markdown, { text: sayText(item) || " ", color: theme2.color.assistant, viewport: viewportHeight === void 0 ? void 0 : { width: w - 2, height: viewportHeight + 2, clipBottom: Math.max(0, clipBottom - 1 - (failed ? 1 : 0)) } }),
|
|
9963
10044
|
failed ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.error, children: [
|
|
9964
10045
|
g.cross,
|
|
9965
10046
|
" say failed: ",
|
|
@@ -9969,7 +10050,7 @@ ${g.ellipsis} ${result2.more} more lines` : ""
|
|
|
9969
10050
|
] })
|
|
9970
10051
|
] });
|
|
9971
10052
|
case "ask": {
|
|
9972
|
-
let pending = item.status === "running",
|
|
10053
|
+
let pending = item.status === "running", answers = askAnswers(item), reason2 = toolReason(item);
|
|
9973
10054
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "column", width: w, borderStyle: theme2.ascii ? "classic" : "single", borderLeft: !0, borderRight: !1, borderTop: !1, borderBottom: !1, borderColor: pending ? theme2.color.warn : theme2.color.dim, paddingLeft: 1, children: [
|
|
9974
10055
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
9975
10056
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { bold: !0, color: pending ? theme2.color.warn : theme2.color.muted, children: [
|
|
@@ -9983,11 +10064,11 @@ ${g.ellipsis} ${result2.more} more lines` : ""
|
|
|
9983
10064
|
reason2
|
|
9984
10065
|
] }) : null
|
|
9985
10066
|
] }),
|
|
9986
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
9987
|
-
|
|
9988
|
-
|
|
10067
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(AskForm, { questions: askQuestions(item.input), answers }),
|
|
10068
|
+
item.result !== void 0 && !answers ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.error, children: [
|
|
10069
|
+
g.cross,
|
|
9989
10070
|
" ",
|
|
9990
|
-
oneLine(
|
|
10071
|
+
oneLine(item.result) || "(no detail)"
|
|
9991
10072
|
] }) : null
|
|
9992
10073
|
] });
|
|
9993
10074
|
}
|
|
@@ -10045,7 +10126,7 @@ ${g.ellipsis} ${result2.more} more lines` : ""
|
|
|
10045
10126
|
] }) : null
|
|
10046
10127
|
] });
|
|
10047
10128
|
}
|
|
10048
|
-
function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
10129
|
+
function ItemBody({ item, width, expanded, showThinking, queued, viewportHeight, clipBottom = 0 }) {
|
|
10049
10130
|
let theme2 = useTheme(), g = theme2.glyph, w = Math.max(8, width);
|
|
10050
10131
|
switch (item.kind) {
|
|
10051
10132
|
case "user": {
|
|
@@ -10106,7 +10187,7 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10106
10187
|
" "
|
|
10107
10188
|
] }),
|
|
10108
10189
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { width: w - 2, flexDirection: "column", children: [
|
|
10109
|
-
item.text ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Markdown, { text: item.text, color: theme2.color.assistant }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { children: " " }),
|
|
10190
|
+
item.text ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Markdown, { text: item.text, color: theme2.color.assistant, viewport: viewportHeight === void 0 ? void 0 : { width: w - 2, height: viewportHeight + 2, clipBottom: Math.max(0, clipBottom - 1 - (item.interrupted ? 1 : 0)) } }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { children: " " }),
|
|
10110
10191
|
item.interrupted ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Text, { color: theme2.color.dim, children: "[interrupted]" }) : null
|
|
10111
10192
|
] })
|
|
10112
10193
|
] });
|
|
@@ -10130,7 +10211,7 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10130
10211
|
] });
|
|
10131
10212
|
}
|
|
10132
10213
|
case "tool":
|
|
10133
|
-
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ToolBody, { item, w, expanded });
|
|
10214
|
+
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(ToolBody, { item, w, expanded, viewportHeight, clipBottom });
|
|
10134
10215
|
case "hil": {
|
|
10135
10216
|
let tone = item.status === "pending" ? theme2.color.warn : item.status === "approved" || item.status === "completed" ? theme2.color.success : theme2.color.error;
|
|
10136
10217
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Box_default, { flexDirection: "column", width: w, borderStyle: theme2.ascii ? "classic" : "single", borderLeft: !0, borderRight: !1, borderTop: !1, borderBottom: !1, borderColor: tone, paddingLeft: 1, children: [
|
|
@@ -10168,12 +10249,7 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10168
10249
|
"? ",
|
|
10169
10250
|
item.status === "pending" ? "the agent asks you" : "answered"
|
|
10170
10251
|
] }),
|
|
10171
|
-
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
10172
|
-
item.answer ? /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.user, children: [
|
|
10173
|
-
g.pointer,
|
|
10174
|
-
" ",
|
|
10175
|
-
item.answer
|
|
10176
|
-
] }) : null
|
|
10252
|
+
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(AskForm, { questions: item.questions })
|
|
10177
10253
|
] });
|
|
10178
10254
|
case "notice":
|
|
10179
10255
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(Text, { wrap: "truncate-end", color: item.level === "warn" ? theme2.color.warn : item.event === "marker" ? theme2.color.info : theme2.color.muted, children: [
|
|
@@ -10238,7 +10314,7 @@ function ItemBody({ item, width, expanded, showThinking, queued }) {
|
|
|
10238
10314
|
] });
|
|
10239
10315
|
}
|
|
10240
10316
|
}
|
|
10241
|
-
var TranscriptItemView = (0,
|
|
10317
|
+
var TranscriptItemView = (0, import_react32.memo)(function(props) {
|
|
10242
10318
|
let theme2 = useTheme(), gap = props.item.kind === "notice" || props.item.kind === "context" && !props.expanded ? 0 : 1;
|
|
10243
10319
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Box_default, { flexDirection: "row", width: props.width, marginBottom: gap, flexShrink: 0, children: /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
|
|
10244
10320
|
Box_default,
|
|
@@ -10302,7 +10378,7 @@ function LoopTabs({ agentLabel: agentLabel5, tabs, selected, unseen, pending, wi
|
|
|
10302
10378
|
}
|
|
10303
10379
|
|
|
10304
10380
|
// src/main/tui/views/chat/Dock.tsx
|
|
10305
|
-
var
|
|
10381
|
+
var import_react33 = __toESM(require_react(), 1);
|
|
10306
10382
|
|
|
10307
10383
|
// src/main/tui/views/chat/approvals.ts
|
|
10308
10384
|
var FEEDBACK_OVERLAY = "chat.deny";
|
|
@@ -10326,7 +10402,11 @@ var import_jsx_runtime40 = __toESM(require_jsx_runtime(), 1);
|
|
|
10326
10402
|
function topCard(model2) {
|
|
10327
10403
|
return model2.tasks.length > 0 ? "hil" : model2.asks.length > 0 ? "ask" : model2.suspended ? "suspend" : null;
|
|
10328
10404
|
}
|
|
10329
|
-
var ASK_LINES = 3;
|
|
10405
|
+
var ASK_LINES = 3, ASK_OPTIONS = 6;
|
|
10406
|
+
function askRows(ask, answers, inner) {
|
|
10407
|
+
let { question } = askStep(ask, answers), options = question.options?.length ?? 0, optionRows = Math.min(options, ASK_OPTIONS) + (options > ASK_OPTIONS ? 1 : 0);
|
|
10408
|
+
return 1 + Math.min(ASK_LINES, wrappedHeight(question.question || " ", inner)) + optionRows + 1 + 1;
|
|
10409
|
+
}
|
|
10330
10410
|
function taskReason(task) {
|
|
10331
10411
|
let meta = task.approval_meta;
|
|
10332
10412
|
if (meta)
|
|
@@ -10338,7 +10418,7 @@ function dockHeight(model2, width) {
|
|
|
10338
10418
|
case "hil":
|
|
10339
10419
|
return queued + 2 + 3 + (taskReason(model2.tasks[0]) ? 1 : 0);
|
|
10340
10420
|
case "ask":
|
|
10341
|
-
return queued + 2 +
|
|
10421
|
+
return queued + 2 + askRows(model2.asks[0], model2.askAnswers ?? [], Math.max(8, width - 4));
|
|
10342
10422
|
case "suspend":
|
|
10343
10423
|
return queued + 2 + 2;
|
|
10344
10424
|
default:
|
|
@@ -10346,7 +10426,7 @@ function dockHeight(model2, width) {
|
|
|
10346
10426
|
}
|
|
10347
10427
|
}
|
|
10348
10428
|
function ActionRow({ buttons: all, focused, width, onAction }) {
|
|
10349
|
-
let theme2 = useTheme(), ref = (0,
|
|
10429
|
+
let theme2 = useTheme(), ref = (0, import_react33.useRef)(null), sep4 = ` ${theme2.glyph.sep} `, prefix = focused ? "" : "Shift+Tab: ", spans = [], x = displayWidth(prefix);
|
|
10350
10430
|
for (let [i, button] of all.entries()) {
|
|
10351
10431
|
let text = button.off ? `${button.label}: one-time only` : `${keyLabel(button.keys)} ${button.label}`, start = x + (i > 0 ? displayWidth(sep4) : 0);
|
|
10352
10432
|
if (start + displayWidth(text) > width) break;
|
|
@@ -10423,21 +10503,56 @@ function Dock({ model: model2, width, focused, agentLabel: agentLabel5, onAction
|
|
|
10423
10503
|
].sort((a, b) => (a.off ? 1 : 0) - (b.off ? 1 : 0)))
|
|
10424
10504
|
] }));
|
|
10425
10505
|
})() : null,
|
|
10426
|
-
card === "ask" ?
|
|
10427
|
-
|
|
10428
|
-
|
|
10429
|
-
|
|
10430
|
-
|
|
10431
|
-
|
|
10432
|
-
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10506
|
+
card === "ask" ? (() => {
|
|
10507
|
+
let ask = model2.asks[0], { index, question } = askStep(ask, model2.askAnswers ?? []), options = question.options ?? [], total = ask.questions.length, number = (n) => `${n}.`.padStart(String(options.length).length + 1);
|
|
10508
|
+
return border(theme2.color.warn, /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
10509
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
10510
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { bold: !0, color: theme2.color.warn, children: [
|
|
10511
|
+
"? ",
|
|
10512
|
+
agentLabel5,
|
|
10513
|
+
" asks you"
|
|
10514
|
+
] }),
|
|
10515
|
+
total > 1 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { color: theme2.color.muted, children: [
|
|
10516
|
+
" ",
|
|
10517
|
+
index + 1,
|
|
10518
|
+
"/",
|
|
10519
|
+
total
|
|
10520
|
+
] }) : null,
|
|
10521
|
+
model2.asks.length > 1 ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { color: theme2.color.muted, children: [
|
|
10522
|
+
" (+",
|
|
10523
|
+
model2.asks.length - 1,
|
|
10524
|
+
" more)"
|
|
10525
|
+
] }) : null
|
|
10526
|
+
] }),
|
|
10527
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Box_default, { height: Math.min(ASK_LINES, wrappedHeight(question.question || " ", inner)), overflow: "hidden", children: /* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { wrap: "wrap", color: theme2.color.text, children: question.question }) }),
|
|
10528
|
+
options.slice(0, ASK_OPTIONS).map((option, i) => /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
10529
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { color: theme2.color.accent, children: number(i + 1) }),
|
|
10530
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { color: theme2.color.text, children: [
|
|
10531
|
+
" ",
|
|
10532
|
+
option.label
|
|
10533
|
+
] }),
|
|
10534
|
+
option.description ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { color: theme2.color.dim, children: [
|
|
10535
|
+
" ",
|
|
10536
|
+
option.description
|
|
10537
|
+
] }) : null
|
|
10538
|
+
] }, i)),
|
|
10539
|
+
options.length > ASK_OPTIONS ? /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.dim, children: [
|
|
10540
|
+
g.ellipsis,
|
|
10541
|
+
" ",
|
|
10542
|
+
options.length - ASK_OPTIONS,
|
|
10543
|
+
" more, ",
|
|
10544
|
+
ASK_OPTIONS + 1,
|
|
10545
|
+
"\u2013",
|
|
10546
|
+
options.length,
|
|
10547
|
+
" by number"
|
|
10548
|
+
] }) : null,
|
|
10549
|
+
/* @__PURE__ */ (0, import_jsx_runtime40.jsx)(Text, { wrap: "truncate-end", color: theme2.color.dim, children: askHint(question) }),
|
|
10550
|
+
act([
|
|
10551
|
+
{ keys: "a", label: "answer", action: "answer" },
|
|
10552
|
+
{ keys: "x", label: index > 0 ? "skip the rest" : total > 1 ? "skip all" : "skip", action: "skip" }
|
|
10553
|
+
])
|
|
10554
|
+
] }));
|
|
10555
|
+
})() : null,
|
|
10441
10556
|
card === "suspend" ? border(theme2.color.warn, /* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(import_jsx_runtime40.Fragment, { children: [
|
|
10442
10557
|
/* @__PURE__ */ (0, import_jsx_runtime40.jsxs)(Text, { bold: !0, color: theme2.color.warn, children: [
|
|
10443
10558
|
g.warn,
|
|
@@ -10451,15 +10566,15 @@ function Dock({ model: model2, width, focused, agentLabel: agentLabel5, onAction
|
|
|
10451
10566
|
}
|
|
10452
10567
|
|
|
10453
10568
|
// src/main/tui/views/chat/Footer.tsx
|
|
10454
|
-
var
|
|
10569
|
+
var import_react34 = __toESM(require_react(), 1);
|
|
10455
10570
|
var import_jsx_runtime41 = __toESM(require_jsx_runtime(), 1);
|
|
10456
10571
|
function elapsed(ms) {
|
|
10457
10572
|
let s = Math.max(0, Math.floor(ms / 1e3));
|
|
10458
10573
|
return s < 60 ? `${s}s` : `${Math.floor(s / 60)}m${String(s % 60).padStart(2, "0")}s`;
|
|
10459
10574
|
}
|
|
10460
10575
|
function Footer({ width, running: running2, state, turn, since, model: model2, error, contextPercent }) {
|
|
10461
|
-
let theme2 = useTheme(), g = theme2.glyph, [now, setNow] = (0,
|
|
10462
|
-
(0,
|
|
10576
|
+
let theme2 = useTheme(), g = theme2.glyph, [now, setNow] = (0, import_react34.useState)(Date.now());
|
|
10577
|
+
(0, import_react34.useEffect)(() => {
|
|
10463
10578
|
if (!running2) return;
|
|
10464
10579
|
setNow(Date.now());
|
|
10465
10580
|
let timer = setInterval(() => setNow(Date.now()), 1e3);
|
|
@@ -10543,13 +10658,13 @@ function Footer({ width, running: running2, state, turn, since, model: model2, e
|
|
|
10543
10658
|
}
|
|
10544
10659
|
|
|
10545
10660
|
// src/main/tui/views/chat/overlays.tsx
|
|
10546
|
-
var
|
|
10661
|
+
var import_react35 = __toESM(require_react(), 1);
|
|
10547
10662
|
var import_jsx_runtime42 = __toESM(require_jsx_runtime(), 1), DENY_OVERLAY = "chat.deny", DETAILS_OVERLAY = "chat.approval";
|
|
10548
10663
|
function taskProps(props) {
|
|
10549
10664
|
return props.overlay.props ?? {};
|
|
10550
10665
|
}
|
|
10551
10666
|
function DenyOverlay(props) {
|
|
10552
|
-
let theme2 = useTheme(), actions4 = useActions(), { agentId, taskId, tool } = taskProps(props), [reason, setReason] = (0,
|
|
10667
|
+
let theme2 = useTheme(), actions4 = useActions(), { agentId, taskId, tool } = taskProps(props), [reason, setReason] = (0, import_react35.useState)("");
|
|
10553
10668
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
10554
10669
|
Modal,
|
|
10555
10670
|
{
|
|
@@ -10579,7 +10694,7 @@ function DenyOverlay(props) {
|
|
|
10579
10694
|
}
|
|
10580
10695
|
function ApprovalDetailsOverlay(props) {
|
|
10581
10696
|
let theme2 = useTheme(), actions4 = useActions(), { agentId, taskId, tool } = taskProps(props), agent2 = useAgent(agentId), task = agent2?.pendingTasks.find((t) => t.id === taskId), body = task ? prettyJson(parseArgs(task.args)) : "(no longer pending)", dialogWidth = Math.min(props.width - 4, 96), lines = body.split(`
|
|
10582
|
-
`).flatMap((line) => chunk(line, Math.max(8, dialogWidth - 4))), room = Math.max(4, props.height - 12), [top, setTop] = (0,
|
|
10697
|
+
`).flatMap((line) => chunk(line, Math.max(8, dialogWidth - 4))), room = Math.max(4, props.height - 12), [top, setTop] = (0, import_react35.useState)(0), maxTop = Math.max(0, lines.length - room);
|
|
10583
10698
|
useKeys((input, key) => key.escape ? (props.close(), !0) : input === "y" && task ? (props.close(), actions4.resolveTask(agentId, taskId, "approve"), !0) : input === "a" && task ? (props.close(), alwaysApprove(actions4, agentId, agent2?.summary.handle || agent2?.summary.name || agentId, task), !0) : input === "n" && task ? (props.close(), actions4.resolveTask(agentId, taskId, "deny"), !0) : input === "f" && task ? (props.close(), actions4.pushOverlay({ kind: DENY_OVERLAY, props: { agentId, taskId, tool } }), !0) : key.downArrow || input === "j" ? (setTop((t) => Math.min(maxTop, t + 1)), !0) : key.upArrow || input === "k" ? (setTop((t) => Math.max(0, t - 1)), !0) : key.pageDown ? (setTop((t) => Math.min(maxTop, t + room)), !0) : (key.pageUp && setTop((t) => Math.max(0, t - room)), !0), { layer: "overlay" });
|
|
10584
10699
|
let reason = task ? taskReason(task) : void 0;
|
|
10585
10700
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
|
|
@@ -10619,6 +10734,41 @@ function chunk(line, width) {
|
|
|
10619
10734
|
return out;
|
|
10620
10735
|
}
|
|
10621
10736
|
|
|
10737
|
+
// src/main/tui/views/chat/asks.ts
|
|
10738
|
+
var ASK_PROGRESS_KEY = "chat:askProgress";
|
|
10739
|
+
function progressKey(agentId, loop, requestId) {
|
|
10740
|
+
return `${transcriptKey(agentId, loop)}\0${requestId}`;
|
|
10741
|
+
}
|
|
10742
|
+
function askProgress(state, agentId, loop, ask) {
|
|
10743
|
+
return state.viewState[ASK_PROGRESS_KEY]?.[progressKey(agentId, loop, ask.requestId)] ?? [];
|
|
10744
|
+
}
|
|
10745
|
+
function setProgress(store, key, answers) {
|
|
10746
|
+
let next = { ...store.getState().viewState[ASK_PROGRESS_KEY] };
|
|
10747
|
+
answers ? next[key] = answers : delete next[key], store.actions.setViewState(ASK_PROGRESS_KEY, next);
|
|
10748
|
+
}
|
|
10749
|
+
function pendingAskFor(state, agentId, loop) {
|
|
10750
|
+
if (!agentId) return;
|
|
10751
|
+
let agent2 = state.agents[agentId], asks = pendingAsksFor(agent2, loop, state.transcripts);
|
|
10752
|
+
return topCard({ tasks: pendingTasksFor(agent2, loop), asks, suspended: !1, queued: [] }) === "ask" ? asks[0] : void 0;
|
|
10753
|
+
}
|
|
10754
|
+
async function replyToAsk(store, agentId, loop, ask, text) {
|
|
10755
|
+
let key = progressKey(agentId, loop, ask.requestId), sofar = askProgress(store.getState(), agentId, loop, ask), { index, question } = askStep(ask, sofar), read = readAskReply(question, text);
|
|
10756
|
+
if ("error" in read) {
|
|
10757
|
+
store.actions.toast(read.error, "warn");
|
|
10758
|
+
return;
|
|
10759
|
+
}
|
|
10760
|
+
let answers = [...sofar.slice(0, index), read.answer];
|
|
10761
|
+
if (answers.length < ask.questions.length) {
|
|
10762
|
+
setProgress(store, key, answers);
|
|
10763
|
+
return;
|
|
10764
|
+
}
|
|
10765
|
+
await store.actions.answerAsk(agentId, ask.requestId, answers, ask.loop ?? loop), setProgress(store, key, null);
|
|
10766
|
+
}
|
|
10767
|
+
async function skipAsk(store, agentId, loop, ask) {
|
|
10768
|
+
let sofar = askProgress(store.getState(), agentId, loop, ask);
|
|
10769
|
+
await store.actions.answerAsk(agentId, ask.requestId, ask.questions.map((_, i) => sofar[i] ?? null), ask.loop ?? loop), setProgress(store, progressKey(agentId, loop, ask.requestId), null);
|
|
10770
|
+
}
|
|
10771
|
+
|
|
10622
10772
|
// src/main/tui/views/chat/commands.ts
|
|
10623
10773
|
var TRIGGER_TYPES = ["startup", "timer", "inbox", "outbox", "file_change", "chat", "tool_call", "task_create", "task_complete", "log_entry", "llm_call"];
|
|
10624
10774
|
function readChatState(scope) {
|
|
@@ -10789,22 +10939,22 @@ function LateKeys({ handler, layer }) {
|
|
|
10789
10939
|
return useKeys(handler, { layer }), null;
|
|
10790
10940
|
}
|
|
10791
10941
|
function ChatView({ width: paneWidth, height, focused }) {
|
|
10792
|
-
let width = Math.max(10, paneWidth - 2), theme2 = useTheme(), g = theme2.glyph, store = useStore(), actions4 = useActions(), client = useClient(), agent2 = useSelectedAgent(), stopped = useSelectedTracked(), authNeed = useAuthNeed(agent2?.summary.id), agentId = agent2?.summary.id ?? null, loopName = useSelectedLoop(), loop = useLoop(agentId, loopName), transcript = useTranscript(agentId, loopName), [chat2, setChat] = useViewState(CHAT_VIEW, INITIAL_CHAT_STATE), focusZone = useFocus(), key = agentId ? transcriptKey(agentId, loopName) : "", mountedAt = (0,
|
|
10793
|
-
(0,
|
|
10942
|
+
let width = Math.max(10, paneWidth - 2), theme2 = useTheme(), g = theme2.glyph, store = useStore(), actions4 = useActions(), client = useClient(), agent2 = useSelectedAgent(), stopped = useSelectedTracked(), authNeed = useAuthNeed(agent2?.summary.id), agentId = agent2?.summary.id ?? null, loopName = useSelectedLoop(), loop = useLoop(agentId, loopName), transcript = useTranscript(agentId, loopName), [chat2, setChat] = useViewState(CHAT_VIEW, INITIAL_CHAT_STATE), focusZone = useFocus(), key = agentId ? transcriptKey(agentId, loopName) : "", mountedAt = (0, import_react36.useRef)(Date.now()), [late, setLate] = (0, import_react36.useState)(!1);
|
|
10943
|
+
(0, import_react36.useEffect)(() => {
|
|
10794
10944
|
setLate(!0);
|
|
10795
|
-
}, []), (0,
|
|
10945
|
+
}, []), (0, import_react36.useEffect)(() => {
|
|
10796
10946
|
agentId && actions4.ensureTranscript(agentId, loopName);
|
|
10797
10947
|
}, [agentId, loopName]);
|
|
10798
|
-
let [timers, setTimers] = (0,
|
|
10948
|
+
let [timers, setTimers] = (0, import_react36.useState)({}), refetchTimers = (id) => {
|
|
10799
10949
|
client.timers(id).then((result) => setTimers((prev) => ({ ...prev, [id]: result.timers }))).catch(() => {
|
|
10800
10950
|
setTimers((prev) => prev[id] ? prev : { ...prev, [id]: [] });
|
|
10801
10951
|
});
|
|
10802
10952
|
}, loopCount = agent2?.loops?.length ?? 0;
|
|
10803
|
-
(0,
|
|
10953
|
+
(0, import_react36.useEffect)(() => {
|
|
10804
10954
|
agentId && refetchTimers(agentId);
|
|
10805
10955
|
}, [agentId, loopCount]);
|
|
10806
|
-
let lastEvents = useTuiSelector((s) => s.lastEvents), digested = (0,
|
|
10807
|
-
(0,
|
|
10956
|
+
let lastEvents = useTuiSelector((s) => s.lastEvents), digested = (0, import_react36.useRef)(null), timerAttempts = (0, import_react36.useRef)(/* @__PURE__ */ new Set());
|
|
10957
|
+
(0, import_react36.useEffect)(() => {
|
|
10808
10958
|
let current = store.getState().viewState[CHAT_VIEW] ?? INITIAL_CHAT_STATE;
|
|
10809
10959
|
digested.current || (digested.current = current.digested);
|
|
10810
10960
|
let lookup = (id, timerId) => {
|
|
@@ -10821,7 +10971,7 @@ function ChatView({ width: paneWidth, height, focused }) {
|
|
|
10821
10971
|
for (let a of s.activity) a.agentId === agentId && a.loop !== loopName && UNSEEN_EVENTS.has(a.type) && (out[a.loop] = a.at);
|
|
10822
10972
|
return out;
|
|
10823
10973
|
}, shallowEqual);
|
|
10824
|
-
(0,
|
|
10974
|
+
(0, import_react36.useEffect)(() => {
|
|
10825
10975
|
if (!agentId) return;
|
|
10826
10976
|
let k = transcriptKey(agentId, loopName);
|
|
10827
10977
|
return () => {
|
|
@@ -10830,14 +10980,14 @@ function ChatView({ width: paneWidth, height, focused }) {
|
|
|
10830
10980
|
};
|
|
10831
10981
|
}, [agentId, loopName]);
|
|
10832
10982
|
let transcripts = useTuiSelector((s) => s.transcripts);
|
|
10833
|
-
useTuiSelector((s) => s.web?.server);
|
|
10834
|
-
let site = siteOf(store.getState(), agentId), tabs = loopTabs(agent2), running2 = loopRunning2(agent2, loop) || transcript.live, state = loopStateLabel(agent2, loop, loopName), turn = chat2.turns[key], turnStart = running2 ? turn && turn.endedAt === void 0 ? turn.startedAt : mountedAt.current : null, tasks2 = pendingTasksFor(agent2, loopName), asks = pendingAsksFor(agent2, loopName, transcripts), queued = queuedItems(transcript.items, running2, turnStart), queuedIds = new Set(queued.map((q) => q.id)), dockModel = { tasks: tasks2, asks, suspended: loopName === MAIN_LOOP && agent2?.executorState === "suspended", queued }, unseen = new Set(Object.entries(latest).filter(([name, at]) => at > (chat2.seen[agentId ? transcriptKey(agentId, name) : ""] ?? 0)).map(([name]) => name)), pendingLoops = new Set((agent2?.pendingTasks ?? []).filter((t) => t.status === "pending_approval").map((t) => typeof t.origin == "string" && t.origin.startsWith("loop:") ? t.origin.slice(5) : MAIN_LOOP)), markers = chat2.markers[key], older = transcript.oldestOffset > 0 ? [{ id: "chat:older", at: 0, local: !0, kind: "notice", level: "info", text: transcript.loading ? `loading earlier history${g.ellipsis}` : `${transcript.oldestOffset} earlier rows ${g.sep} scroll up or Home to load` }] : [], items = useMergedItems(transcript.items, markers, older), heightCache = (0,
|
|
10983
|
+
useTuiSelector((s) => s.web?.server), useTuiSelector((s) => s.viewState[ASK_PROGRESS_KEY]);
|
|
10984
|
+
let site = siteOf(store.getState(), agentId), tabs = loopTabs(agent2), running2 = loopRunning2(agent2, loop) || transcript.live, state = loopStateLabel(agent2, loop, loopName), turn = chat2.turns[key], turnStart = running2 ? turn && turn.endedAt === void 0 ? turn.startedAt : mountedAt.current : null, tasks2 = pendingTasksFor(agent2, loopName), asks = pendingAsksFor(agent2, loopName, transcripts), queued = queuedItems(transcript.items, running2, turnStart), queuedIds = new Set(queued.map((q) => q.id)), askAnswers2 = agentId && asks[0] ? askProgress(store.getState(), agentId, loopName, asks[0]) : void 0, dockModel = { tasks: tasks2, asks, askAnswers: askAnswers2, suspended: loopName === MAIN_LOOP && agent2?.executorState === "suspended", queued }, unseen = new Set(Object.entries(latest).filter(([name, at]) => at > (chat2.seen[agentId ? transcriptKey(agentId, name) : ""] ?? 0)).map(([name]) => name)), pendingLoops = new Set((agent2?.pendingTasks ?? []).filter((t) => t.status === "pending_approval").map((t) => typeof t.origin == "string" && t.origin.startsWith("loop:") ? t.origin.slice(5) : MAIN_LOOP)), markers = chat2.markers[key], older = transcript.oldestOffset > 0 ? [{ id: "chat:older", at: 0, local: !0, kind: "notice", level: "info", text: transcript.loading ? `loading earlier history${g.ellipsis}` : `${transcript.oldestOffset} earlier rows ${g.sep} scroll up or Home to load` }] : [], items = useMergedItems(transcript.items, markers, older), heightCache = (0, import_react36.useRef)(/* @__PURE__ */ new WeakMap()), isExpanded = (item) => !!chat2.expanded[`${key}|${item.id}`], heights = items.map((item) => {
|
|
10835
10985
|
let expanded = isExpanded(item), f = `${expanded ? 1 : 0}${chat2.showThinking ? 1 : 0}${queuedIds.has(item.id) ? 1 : 0}`, cached = heightCache.current.get(item);
|
|
10836
10986
|
if (cached && cached.w === width && cached.f === f) return cached.h;
|
|
10837
10987
|
let h = Math.max(1, itemHeight(item, width, { expanded, showThinking: chat2.showThinking }));
|
|
10838
10988
|
return heightCache.current.set(item, { w: width, f, h }), h;
|
|
10839
|
-
}), keys = items.map((item) => item.id), infoRows = 1, dockRows = agentId ? dockHeight(dockModel, width) : 0, paneHeight = Math.max(2, height - 1 - infoRows - 1 - dockRows), offset = offsetOf(chat2.scroll[key], keys, heights), scrolled = offset > 0, viewport = Math.max(1, paneHeight - (scrolled ? 1 : 0)), win = windowAt(heights, offset, viewport), selectedId = chat2.selected[key] ?? null, topVisible = win.start === 0 && heights.slice(0, win.end + 1).reduce((a, b) => a + b, 0) - win.clip <= viewport, loadOlderGuard = (0,
|
|
10840
|
-
(0,
|
|
10989
|
+
}), keys = items.map((item) => item.id), infoRows = 1, dockRows = agentId ? dockHeight(dockModel, width) : 0, paneHeight = Math.max(2, height - 1 - infoRows - 1 - dockRows), offset = offsetOf(chat2.scroll[key], keys, heights), scrolled = offset > 0, viewport = Math.max(1, paneHeight - (scrolled ? 1 : 0)), win = windowAt(heights, offset, viewport), selectedId = chat2.selected[key] ?? null, topVisible = win.start === 0 && heights.slice(0, win.end + 1).reduce((a, b) => a + b, 0) - win.clip <= viewport, loadOlderGuard = (0, import_react36.useRef)("");
|
|
10990
|
+
(0, import_react36.useEffect)(() => {
|
|
10841
10991
|
if (!agentId || !scrolled || !topVisible || transcript.loading || transcript.oldestOffset <= 0) return;
|
|
10842
10992
|
let guard = `${key}:${transcript.oldestOffset}`;
|
|
10843
10993
|
loadOlderGuard.current !== guard && (loadOlderGuard.current = guard, actions4.loadOlder(agentId, loopName));
|
|
@@ -10900,6 +11050,15 @@ function ChatView({ width: paneWidth, height, focused }) {
|
|
|
10900
11050
|
actions4.respondSuspend(agentId, !0);
|
|
10901
11051
|
return;
|
|
10902
11052
|
}
|
|
11053
|
+
if (action === "answer") {
|
|
11054
|
+
actions4.setFocus("input");
|
|
11055
|
+
return;
|
|
11056
|
+
}
|
|
11057
|
+
if (action === "skip") {
|
|
11058
|
+
let ask = asks[0];
|
|
11059
|
+
ask && skipAsk(store, agentId, loopName, ask);
|
|
11060
|
+
return;
|
|
11061
|
+
}
|
|
10903
11062
|
if (action === "shutdown") {
|
|
10904
11063
|
actions4.confirm({ title: "Shut down", message: `Shut ${agentLabel4(agent2)} down instead of resuming?`, danger: !0 }).then((ok) => {
|
|
10905
11064
|
ok && actions4.respondSuspend(agentId, !1);
|
|
@@ -10910,7 +11069,7 @@ function ChatView({ width: paneWidth, height, focused }) {
|
|
|
10910
11069
|
if (!target2) return;
|
|
10911
11070
|
let task = target2.task ?? { id: target2.taskId, tool: target2.tool, args: "{}", status: "pending_approval", created_at: 0 };
|
|
10912
11071
|
action === "approve" ? actions4.resolveTask(agentId, target2.taskId, "approve") : action === "always" ? alwaysApprove(actions4, agentId, agentLabel4(agent2), task) : action === "reject" ? actions4.resolveTask(agentId, target2.taskId, "deny") : action === "feedback" ? rejectWithFeedback(actions4, agentId, task) : actions4.pushOverlay({ kind: DETAILS_OVERLAY, props: { agentId, taskId: target2.taskId, tool: target2.tool } });
|
|
10913
|
-
}, interrupt = () => agentId ? (actions4.interrupt(agentId, loopName), !0) : !1, armed = (0,
|
|
11072
|
+
}, interrupt = () => agentId ? (actions4.interrupt(agentId, loopName), !0) : !1, armed = (0, import_react36.useRef)(null), router = useKeyRouter(), pendingArrow = (0, import_react36.useRef)(null), replaying = (0, import_react36.useRef)(!1), queueArrow = (input, k, items2) => {
|
|
10914
11073
|
let step = k.upArrow ? 1 : -1, pending = pendingArrow.current;
|
|
10915
11074
|
return pending ? (pending.delta += step, pending.count++, !0) : (pendingArrow.current = { input, key: k, delta: step, count: 1, items: items2 }, setImmediate(() => {
|
|
10916
11075
|
let p = pendingArrow.current;
|
|
@@ -10972,11 +11131,11 @@ function ChatView({ width: paneWidth, height, focused }) {
|
|
|
10972
11131
|
let explicit = selectedItem?.kind === "hil" && selectedItem.status === "pending" && selectedItem.taskId === target2.taskId, prior = armed.current;
|
|
10973
11132
|
return explicit || prior && prior.taskId === target2.taskId && prior.key === input && Date.now() - prior.at < APPROVE_ARM_MS ? (armed.current = null, dockAction(input === "y" ? "approve" : "always")) : (armed.current = { taskId: target2.taskId, key: input, at: Date.now() }, actions4.toast(`Press ${input} again to ${input === "y" ? "approve" : "always approve"} ${target2.tool} (${target2.taskId})`, "warn", APPROVE_ARM_MS)), !0;
|
|
10974
11133
|
}
|
|
10975
|
-
return card === "hil" && (input === "n" || input === "f" || input === "v") ? (dockAction(input === "n" ? "reject" : input === "f" ? "feedback" : "details"), !0) : card === "suspend" && (input === "y" || input === "n") ? (dockAction(input === "y" ? "resume" : "shutdown"), !0) : input === "a"
|
|
11134
|
+
return card === "hil" && (input === "n" || input === "f" || input === "v") ? (dockAction(input === "n" ? "reject" : input === "f" ? "feedback" : "details"), !0) : card === "suspend" && (input === "y" || input === "n") ? (dockAction(input === "y" ? "resume" : "shutdown"), !0) : card === "ask" && (input === "a" || input === "x") ? (dockAction(input === "a" ? "answer" : "skip"), !0) : !1;
|
|
10976
11135
|
}, { layer: "main", active: focused }), useKeys((_input, k) => !k.escape || store.getState().focus === "sidebar" ? !1 : running2 ? interrupt() : !1, { layer: "view" });
|
|
10977
|
-
let transcriptRef = (0,
|
|
11136
|
+
let transcriptRef = (0, import_react36.useRef)(null);
|
|
10978
11137
|
useWheel(transcriptRef, (delta) => scrollBy(-delta * WHEEL_STEP), { active: !!agentId });
|
|
10979
|
-
let itemRefs = (0,
|
|
11138
|
+
let itemRefs = (0, import_react36.useRef)(/* @__PURE__ */ new Map());
|
|
10980
11139
|
useClick(transcriptRef, (event) => {
|
|
10981
11140
|
let box = elementRect(transcriptRef.current);
|
|
10982
11141
|
if (!box || event.y >= box.y + viewport) return !1;
|
|
@@ -11040,7 +11199,13 @@ function ChatView({ width: paneWidth, height, focused }) {
|
|
|
11040
11199
|
selected: showSelection && item.id === selectedId,
|
|
11041
11200
|
expanded: isExpanded(item),
|
|
11042
11201
|
showThinking: chat2.showThinking,
|
|
11043
|
-
queued: queuedIds.has(item.id)
|
|
11202
|
+
queued: queuedIds.has(item.id),
|
|
11203
|
+
viewportHeight: (
|
|
11204
|
+
// Raw height estimates can exceed Ink's styled height,
|
|
11205
|
+
// so clipping may extend into earlier visible items.
|
|
11206
|
+
viewport + (item === visible[visible.length - 1] ? 0 : win.clip)
|
|
11207
|
+
),
|
|
11208
|
+
clipBottom: item === visible[visible.length - 1] ? win.clip : 0
|
|
11044
11209
|
}
|
|
11045
11210
|
) }, item.id)) }) }),
|
|
11046
11211
|
scrolled ? /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(Text, { wrap: "truncate-end", color: theme2.color.accent, children: [
|
|
@@ -11060,7 +11225,7 @@ function ChatView({ width: paneWidth, height, focused }) {
|
|
|
11060
11225
|
] });
|
|
11061
11226
|
}
|
|
11062
11227
|
function useMergedItems(items, markers, older) {
|
|
11063
|
-
let cache = (0,
|
|
11228
|
+
let cache = (0, import_react36.useRef)(null), olderKey = older.map((o) => o.kind === "notice" ? o.text : "").join(), c = cache.current;
|
|
11064
11229
|
if (c && c.items === items && c.markers === markers && c.older === olderKey) return c.out;
|
|
11065
11230
|
let out = [...older, ...withMarkers(items, markers)];
|
|
11066
11231
|
return cache.current = { items, markers, older: olderKey, out }, out;
|
|
@@ -11091,16 +11256,12 @@ function infoStyle(key, theme2) {
|
|
|
11091
11256
|
return { color: theme2.color.dim };
|
|
11092
11257
|
}
|
|
11093
11258
|
}
|
|
11094
|
-
function pendingAskFor(state, agentId, loop) {
|
|
11095
|
-
if (agentId)
|
|
11096
|
-
return pendingAsksFor(state.agents[agentId], loop, state.transcripts)[0];
|
|
11097
|
-
}
|
|
11098
11259
|
function placeholder(scope) {
|
|
11099
11260
|
let state = scope.state(), agent2 = scope.agentId ? state.agents[scope.agentId] : void 0, stopped = scope.stoppedKey ? findTracked(state, scope.stoppedKey) : void 0;
|
|
11100
11261
|
if (stopped) return stopped.agent.status === "needs_review" ? `${stopped.agent.name} is stopped and needs review \xB7 Shift+Tab, then s reviews it` : `${stopped.agent.name} is stopped \xB7 a message starts it, then sends \xB7 or Shift+Tab, then s`;
|
|
11101
11262
|
if (!agent2 || !scope.agentId) return "Select an agent (Tab \u2192 sidebar) or type /help";
|
|
11102
11263
|
let label2 = agentLabel4(agent2), target2 = scope.loop === MAIN_LOOP ? label2 : `${label2} \u203A ${scope.loop}`;
|
|
11103
|
-
if (pendingAskFor(state, scope.agentId, scope.loop)) return `Answer ${label2}'s question \xB7 Enter
|
|
11264
|
+
if (pendingAskFor(state, scope.agentId, scope.loop)) return `Answer ${label2}'s question \xB7 Enter on empty skips it`;
|
|
11104
11265
|
let loopState = agent2.loops?.find((l) => l.info.name === scope.loop);
|
|
11105
11266
|
return loopState && !loopState.info.enabled ? `${scope.loop} is disabled \xB7 /loop on ${scope.loop} to enable it` : loopRunning2(agent2, loopState) ? `Message ${target2} \xB7 queued until the turn ends \xB7 Esc interrupts` : `Message ${target2} / commands \xB7 ${keyLabel(newlineKey())} newline`;
|
|
11106
11267
|
}
|
|
@@ -11126,8 +11287,10 @@ var chat = {
|
|
|
11126
11287
|
placeholder,
|
|
11127
11288
|
onSubmit: async (text, ctx) => {
|
|
11128
11289
|
let ask = pendingAskFor(ctx.state(), ctx.agentId, ctx.loop);
|
|
11129
|
-
return !ask || !ctx.agentId ? !1 : (await ctx.
|
|
11290
|
+
return !ask || !ctx.agentId ? !1 : (await replyToAsk(ctx.store, ctx.agentId, ctx.loop, ask, text), !0);
|
|
11130
11291
|
},
|
|
11292
|
+
// Enter on an empty prompt skips the question the dock shows.
|
|
11293
|
+
submitsEmpty: (scope) => !!pendingAskFor(scope.state(), scope.agentId, scope.loop),
|
|
11131
11294
|
historyKey: (scope) => scope.agentId ? transcriptKey(scope.agentId, scope.loop) : "none",
|
|
11132
11295
|
draftKey: (scope) => scope.agentId ? `chat:${transcriptKey(scope.agentId, scope.loop)}` : "chat",
|
|
11133
11296
|
complete: completeFiles
|
|
@@ -11176,7 +11339,8 @@ var chat = {
|
|
|
11176
11339
|
title: "Approvals and questions (the card under the transcript)",
|
|
11177
11340
|
keys: [
|
|
11178
11341
|
{ keys: "y", label: "Approve: press twice, or once on a selected approval \xB7 resume a suspended agent. Mouse mode: click the card\u2019s buttons" },
|
|
11179
|
-
{ keys: "a", label: "Always approve this tool for the agent (twice, then confirm; it won\u2019t ask again). Not offered for protection overrides: those are one-time only \xB7 on a question card: answer it" },
|
|
11342
|
+
{ keys: "a", label: "Always approve this tool for the agent (twice, then confirm; it won\u2019t ask again). Not offered for protection overrides: those are one-time only \xB7 on a question card: answer it in the prompt" },
|
|
11343
|
+
{ keys: "x", label: "On a question card: skip the questions not answered yet and send the answers" },
|
|
11180
11344
|
{ keys: "n", label: "Reject \xB7 shut a suspended agent down (asks)" },
|
|
11181
11345
|
{ keys: "f", label: "Reject with feedback: the agent sees your text" },
|
|
11182
11346
|
{ keys: "v", label: "Full details of the tool call" },
|
|
@@ -11192,7 +11356,7 @@ var chat = {
|
|
|
11192
11356
|
}, chat_default = chat;
|
|
11193
11357
|
|
|
11194
11358
|
// src/main/tui/views/files/index.tsx
|
|
11195
|
-
var
|
|
11359
|
+
var import_react41 = __toESM(require_react(), 1);
|
|
11196
11360
|
|
|
11197
11361
|
// src/main/tui/views/files/state.ts
|
|
11198
11362
|
var VIEW_ID = "files", TABS2 = ["files", "inbox", "outbox", "meta"], INITIAL_STATE = { tab: "files", pane: "list", agents: {} };
|
|
@@ -11352,10 +11516,10 @@ var tabAction = (tab, title, keywords) => ({
|
|
|
11352
11516
|
};
|
|
11353
11517
|
|
|
11354
11518
|
// src/main/tui/views/files/DataTab.tsx
|
|
11355
|
-
var
|
|
11519
|
+
var import_react38 = __toESM(require_react(), 1);
|
|
11356
11520
|
|
|
11357
11521
|
// src/main/tui/views/files/Viewer.tsx
|
|
11358
|
-
var
|
|
11522
|
+
var import_react37 = __toESM(require_react(), 1);
|
|
11359
11523
|
var import_jsx_runtime44 = __toESM(require_jsx_runtime(), 1);
|
|
11360
11524
|
function toneColor3(theme2, tone) {
|
|
11361
11525
|
switch (tone) {
|
|
@@ -11380,11 +11544,11 @@ function toneColor3(theme2, tone) {
|
|
|
11380
11544
|
}
|
|
11381
11545
|
}
|
|
11382
11546
|
function Viewer(props) {
|
|
11383
|
-
let { width, height, active, title, meta = [], notice, name, text, bytes, mime, loading, error, plain: plain2 = !1, resetKey, onBack, onEdit, onOpenExternal, onSaveBack, emptyText } = props, theme2 = useTheme(), [top, setTop] = (0,
|
|
11384
|
-
(0,
|
|
11547
|
+
let { width, height, active, title, meta = [], notice, name, text, bytes, mime, loading, error, plain: plain2 = !1, resetKey, onBack, onEdit, onOpenExternal, onSaveBack, emptyText } = props, theme2 = useTheme(), [top, setTop] = (0, import_react37.useState)(0), [query, setQuery] = (0, import_react37.useState)(""), [typing, setTyping] = (0, import_react37.useState)(!1), [current, setCurrent] = (0, import_react37.useState)(0);
|
|
11548
|
+
(0, import_react37.useEffect)(() => {
|
|
11385
11549
|
setTop(0), setQuery(""), setTyping(!1), setCurrent(0);
|
|
11386
11550
|
}, [resetKey]);
|
|
11387
|
-
let binary = bytes !== void 0, prepared = (0,
|
|
11551
|
+
let binary = bytes !== void 0, prepared = (0, import_react37.useMemo)(() => binary ? { lines: hexDump(bytes), lang: "text", pretty: !1 } : prepareContent(text ?? "", name), [text, bytes, name, binary]), matches = (0, import_react37.useMemo)(() => findMatches(prepared.lines, query), [prepared, query]), currentIndex = matches.length ? Math.min(current, matches.length - 1) : -1, gutter = plain2 ? 0 : String(prepared.lines.length).length + 1, bodyWidth = Math.max(4, width - gutter - 1), { rows, lineStart: lineStart2 } = (0, import_react37.useMemo)(() => {
|
|
11388
11552
|
let styled = styleLines(prepared.lines, prepared.lang), byLine = /* @__PURE__ */ new Map();
|
|
11389
11553
|
matches.forEach((m, i) => {
|
|
11390
11554
|
let list = byLine.get(m.line) ?? [];
|
|
@@ -11406,13 +11570,13 @@ function Viewer(props) {
|
|
|
11406
11570
|
let next = (currentIndex + delta + matches.length) % matches.length;
|
|
11407
11571
|
setCurrent(next), reveal(next);
|
|
11408
11572
|
};
|
|
11409
|
-
(0,
|
|
11573
|
+
(0, import_react37.useEffect)(() => {
|
|
11410
11574
|
if (typing && matches.length > 0) {
|
|
11411
11575
|
let firstVisible = matches.findIndex((m) => (lineStart2[m.line] ?? 0) >= clampedTop), index = firstVisible >= 0 ? firstVisible : 0;
|
|
11412
11576
|
setCurrent(index), reveal(index);
|
|
11413
11577
|
}
|
|
11414
11578
|
}, [query]), useKeys((input, key) => typing ? key.escape ? (setTyping(!1), setQuery(""), !0) : key.return ? (setTyping(!1), !0) : key.backspace || key.delete ? (setQuery((q) => q.slice(0, -1)), !0) : (key.leftArrow || key.rightArrow) && !key.ctrl && !key.shift ? !0 : input && !key.ctrl && !key.meta && !/[\r\n\t]/.test(input) ? (setQuery((q) => q + input), !0) : !1 : (key.ctrl || key.shift) && (key.leftArrow || key.rightArrow) ? !1 : key.upArrow || input === "k" && !key.ctrl ? (scrollTo(clampedTop - 1), !0) : key.downArrow || input === "j" && !key.ctrl ? (scrollTo(clampedTop + 1), !0) : key.pageUp || key.ctrl && input === "u" ? (scrollTo(clampedTop - Math.max(1, bodyRows - 1)), !0) : key.pageDown || input === " " || key.ctrl && input === "d" ? (scrollTo(clampedTop + Math.max(1, bodyRows - 1)), !0) : key.home || input === "g" ? (scrollTo(0), !0) : key.end || input === "G" ? (scrollTo(maxTop), !0) : input === "/" ? (setTyping(!0), setQuery(""), !0) : input === "n" && query ? (jump(1), !0) : input === "N" && query ? (jump(-1), !0) : input === "e" && onEdit ? (onEdit(), !0) : input === "o" && onOpenExternal ? (onOpenExternal(), !0) : input === "s" && onSaveBack ? (onSaveBack(), !0) : key.escape && query ? (setQuery(""), !0) : (key.escape || key.backspace && !key.ctrl && !key.meta) && onBack ? (onBack(), !0) : !1, { layer: "main", active });
|
|
11415
|
-
let boxRef = (0,
|
|
11579
|
+
let boxRef = (0, import_react37.useRef)(null);
|
|
11416
11580
|
useWheel(boxRef, (delta) => scrollTo(clampedTop + delta * WHEEL_STEP));
|
|
11417
11581
|
let visible = rows.slice(clampedTop, clampedTop + bodyRows), lastLine = visible.length ? visible[visible.length - 1].line + 1 : 0, firstLine2 = visible.length ? visible[0].line + 1 : 0, position = rows.length === 0 ? "" : `L${firstLine2}-${lastLine}/${prepared.lines.length}${maxTop > 0 ? ` ${Math.round(clampedTop / maxTop * 100)}%` : ""}`, search = typing ? `/${query}` : query ? `/${query} ${matches.length ? `${currentIndex + 1}/${matches.length}` : "no match"} n/N` : "", header2 = /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
11418
11582
|
/* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Text, { bold: !0, color: active ? theme2.color.accent : theme2.color.text, inverse: theme2.mono && active, children: truncate(title, Math.max(8, width - 20)) }),
|
|
@@ -11564,7 +11728,7 @@ var LIVE_EVENTS = {
|
|
|
11564
11728
|
meta: []
|
|
11565
11729
|
};
|
|
11566
11730
|
function DataTab({ kind, width, height, focused, agentId, agentLabel: agentLabel5, pane, setPane }) {
|
|
11567
|
-
let theme2 = useTheme(), client = useClient(), [records, setRecords] = (0,
|
|
11731
|
+
let theme2 = useTheme(), client = useClient(), [records, setRecords] = (0, import_react38.useState)(null), [error, setError] = (0, import_react38.useState)(null), [filterIndex, setFilterIndex] = (0, import_react38.useState)(0), [cursor, setCursor] = (0, import_react38.useState)(void 0), [loadedAt, setLoadedAt] = (0, import_react38.useState)(null), status = STATUS_FILTERS[kind][filterIndex], reload = (0, import_react38.useCallback)(async () => {
|
|
11568
11732
|
try {
|
|
11569
11733
|
let next;
|
|
11570
11734
|
kind === "inbox" ? next = [...(await client.inbox(agentId, status)).messages].sort((a, b) => b.received_at - a.received_at).map(inboxRecord) : kind === "outbox" ? next = [...(await client.outbox(agentId, status)).messages].sort((a, b) => b.created_at - a.created_at).map(outboxRecord) : next = [...(await client.meta(agentId)).entries].sort((a, b) => a.key.localeCompare(b.key)).map(metaRecord), setRecords(next), setError(null);
|
|
@@ -11573,11 +11737,11 @@ function DataTab({ kind, width, height, focused, agentId, agentLabel: agentLabel
|
|
|
11573
11737
|
}
|
|
11574
11738
|
setLoadedAt(Date.now());
|
|
11575
11739
|
}, [client, agentId, kind, status]);
|
|
11576
|
-
(0,
|
|
11740
|
+
(0, import_react38.useEffect)(() => {
|
|
11577
11741
|
setRecords(null), reload();
|
|
11578
11742
|
}, [reload]);
|
|
11579
|
-
let lastEvents = useTuiSelector((s) => s.lastEvents), seen = (0,
|
|
11580
|
-
(0,
|
|
11743
|
+
let lastEvents = useTuiSelector((s) => s.lastEvents), seen = (0, import_react38.useRef)(lastEvents[lastEvents.length - 1]);
|
|
11744
|
+
(0, import_react38.useEffect)(() => {
|
|
11581
11745
|
let hit = !1;
|
|
11582
11746
|
for (let i = lastEvents.length - 1; i >= 0 && lastEvents[i] !== seen.current; i--)
|
|
11583
11747
|
lastEvents[i].agent_id === agentId && LIVE_EVENTS[kind].includes(lastEvents[i].event_type) && (hit = !0);
|
|
@@ -11687,7 +11851,7 @@ function DataTab({ kind, width, height, focused, agentId, agentLabel: agentLabel
|
|
|
11687
11851
|
}
|
|
11688
11852
|
|
|
11689
11853
|
// src/main/tui/views/files/FilesTab.tsx
|
|
11690
|
-
var
|
|
11854
|
+
var import_react39 = __toESM(require_react(), 1);
|
|
11691
11855
|
|
|
11692
11856
|
// src/main/tui/views/files/external.ts
|
|
11693
11857
|
import { promises as fs4, rmSync, statSync as statSync3 } from "node:fs";
|
|
@@ -11756,7 +11920,9 @@ async function saveBackExternal(deps, target2) {
|
|
|
11756
11920
|
cancelLabel: "Cancel",
|
|
11757
11921
|
danger: !!concurrent
|
|
11758
11922
|
})) return "discarded";
|
|
11759
|
-
let written =
|
|
11923
|
+
let written = await writeOverConflicts(actions4, label2, copy.file, (base2) => actions4.run(`Write ${label2}`, (c) => writeOver(
|
|
11924
|
+
() => copy.binary && target2.kind === "file" ? c.writeFile(agentId, target2.path, { contentBase64: edited.toString("base64"), ...copy.mime ? { mimeType: copy.mime } : {}, ...base2 !== void 0 ? { baseRevision: base2 } : {} }) : writeTarget(c, agentId, target2, edited.toString("utf-8"), base2)
|
|
11925
|
+
)), baseRevision);
|
|
11760
11926
|
return written === "reloaded" ? "discarded" : written ? (copy.original = edited, copy.mtimeMs = (await fs4.stat(copy.file)).mtimeMs, actions4.toast(`Saved ${label2} from the app`, "success"), "written") : (actions4.toast(`Write failed. Your copy is still at ${copy.file}`, "error", 12e3), "failed");
|
|
11761
11927
|
}
|
|
11762
11928
|
|
|
@@ -11776,18 +11942,18 @@ function parentsOf(path) {
|
|
|
11776
11942
|
return parts.map((_p, i) => parts.slice(0, i + 1).join("/"));
|
|
11777
11943
|
}
|
|
11778
11944
|
function FilesTab(props) {
|
|
11779
|
-
let { width, height, focused, agentId, agentLabel: agentLabel5, pane, setPane, agentState, setAgentState, request, clearRequest } = props, theme2 = useTheme(), actions4 = useActions(), client = useClient(), { suspendTerminal } = use_app_default(), [files2, setFiles] = (0,
|
|
11780
|
-
(0,
|
|
11945
|
+
let { width, height, focused, agentId, agentLabel: agentLabel5, pane, setPane, agentState, setAgentState, request, clearRequest } = props, theme2 = useTheme(), actions4 = useActions(), client = useClient(), { suspendTerminal } = use_app_default(), [files2, setFiles] = (0, import_react39.useState)(null), [listError, setListError] = (0, import_react39.useState)(null), [query, setQuery] = (0, import_react39.useState)(""), [filtering, setFiltering] = (0, import_react39.useState)(!1), [content, setContent] = (0, import_react39.useState)({}), [notice, setNotice] = (0, import_react39.useState)(null), [, setTick] = (0, import_react39.useState)(0), busy = (0, import_react39.useRef)(!1), collapsed = (0, import_react39.useMemo)(() => new Set(agentState.collapsed ?? []), [agentState.collapsed]), rows = (0, import_react39.useMemo)(() => buildRows(files2 ?? [], collapsed, query), [files2, collapsed, query]), cursorIndex = Math.max(0, rows.findIndex((r) => r.key === agentState.cursor)), cursorRow = rows[cursorIndex], viewerKey = isOpenable(cursorRow) ? cursorRow.key : agentState.open ?? DOCUMENT_KEY;
|
|
11946
|
+
(0, import_react39.useEffect)(() => {
|
|
11781
11947
|
pane === "viewer" && viewerKey.startsWith("file:") && recordRecentFile(agentId, viewerKey.slice(5));
|
|
11782
11948
|
}, [pane, viewerKey, agentId]);
|
|
11783
|
-
let viewerTarget = targetFromKey(viewerKey), reloadList = (0,
|
|
11949
|
+
let viewerTarget = targetFromKey(viewerKey), reloadList = (0, import_react39.useCallback)(async () => {
|
|
11784
11950
|
try {
|
|
11785
11951
|
let next = await listFiles(client, agentId);
|
|
11786
11952
|
setFiles(next), setListError(null);
|
|
11787
11953
|
} catch (err) {
|
|
11788
11954
|
setListError(err instanceof Error ? err.message : String(err)), setFiles((prev) => prev ?? []);
|
|
11789
11955
|
}
|
|
11790
|
-
}, [client, agentId]), loadContent = (0,
|
|
11956
|
+
}, [client, agentId]), loadContent = (0, import_react39.useCallback)(async (key) => {
|
|
11791
11957
|
let target2 = targetFromKey(key);
|
|
11792
11958
|
if (target2)
|
|
11793
11959
|
try {
|
|
@@ -11797,17 +11963,17 @@ function FilesTab(props) {
|
|
|
11797
11963
|
setContent((prev) => ({ ...prev, [key]: { error: err instanceof Error ? err.message : String(err) } }));
|
|
11798
11964
|
}
|
|
11799
11965
|
}, [client, agentId]);
|
|
11800
|
-
(0,
|
|
11966
|
+
(0, import_react39.useEffect)(() => {
|
|
11801
11967
|
setFiles(null), setContent({}), setNotice(null), reloadList();
|
|
11802
|
-
}, [agentId]), (0,
|
|
11968
|
+
}, [agentId]), (0, import_react39.useEffect)(() => {
|
|
11803
11969
|
if (!viewerTarget || content[viewerKey]) return;
|
|
11804
11970
|
let timer = setTimeout(() => {
|
|
11805
11971
|
loadContent(viewerKey);
|
|
11806
11972
|
}, 90);
|
|
11807
11973
|
return () => clearTimeout(timer);
|
|
11808
11974
|
}, [viewerKey, content[viewerKey] === void 0]);
|
|
11809
|
-
let lastEvents = useTuiSelector((s) => s.lastEvents), seen = (0,
|
|
11810
|
-
(0,
|
|
11975
|
+
let lastEvents = useTuiSelector((s) => s.lastEvents), seen = (0, import_react39.useRef)(lastEvents[lastEvents.length - 1]);
|
|
11976
|
+
(0, import_react39.useEffect)(() => {
|
|
11811
11977
|
let fresh = [];
|
|
11812
11978
|
for (let i = lastEvents.length - 1; i >= 0 && lastEvents[i] !== seen.current; i--) fresh.unshift(lastEvents[i]);
|
|
11813
11979
|
seen.current = lastEvents[lastEvents.length - 1];
|
|
@@ -11832,7 +11998,7 @@ function FilesTab(props) {
|
|
|
11832
11998
|
for (let key of touched) delete next[key];
|
|
11833
11999
|
return next;
|
|
11834
12000
|
});
|
|
11835
|
-
}, [lastEvents]), (0,
|
|
12001
|
+
}, [lastEvents]), (0, import_react39.useEffect)(() => {
|
|
11836
12002
|
let timer = setInterval(() => setTick((t) => t + 1), 15e3);
|
|
11837
12003
|
return () => clearInterval(timer);
|
|
11838
12004
|
}, []);
|
|
@@ -11884,7 +12050,7 @@ function FilesTab(props) {
|
|
|
11884
12050
|
busy.current = !1, setTick((t) => t + 1);
|
|
11885
12051
|
}
|
|
11886
12052
|
}, viewedCopy = viewerTarget ? externalCopy(agentId, viewerTarget) : void 0, copyChanged = viewedCopy ? externalChanged(viewedCopy) : !1;
|
|
11887
|
-
(0,
|
|
12053
|
+
(0, import_react39.useEffect)(() => {
|
|
11888
12054
|
if (!viewedCopy || copyChanged) return;
|
|
11889
12055
|
let timer = setInterval(() => {
|
|
11890
12056
|
externalChanged(viewedCopy) && setTick((t) => t + 1);
|
|
@@ -11957,7 +12123,7 @@ function FilesTab(props) {
|
|
|
11957
12123
|
let next = wantCollapsed ? [...collapsed, row4.path] : [...collapsed].filter((p) => p !== row4.path);
|
|
11958
12124
|
return setAgentState({ collapsed: next }), !0;
|
|
11959
12125
|
};
|
|
11960
|
-
(0,
|
|
12126
|
+
(0, import_react39.useEffect)(() => {
|
|
11961
12127
|
if (request)
|
|
11962
12128
|
if (clearRequest(), request.kind === "open")
|
|
11963
12129
|
reveal(request.key), invalidate(request.key), setPane("viewer");
|
|
@@ -12122,10 +12288,10 @@ function FilesTab(props) {
|
|
|
12122
12288
|
}
|
|
12123
12289
|
|
|
12124
12290
|
// src/main/tui/views/files/InputDialog.tsx
|
|
12125
|
-
var
|
|
12291
|
+
var import_react40 = __toESM(require_react(), 1);
|
|
12126
12292
|
var import_jsx_runtime47 = __toESM(require_jsx_runtime(), 1);
|
|
12127
12293
|
function InputDialog({ overlay, close, width }) {
|
|
12128
|
-
let theme2 = useTheme(), options = overlay.props ?? {}, [value, setValue] = (0,
|
|
12294
|
+
let theme2 = useTheme(), options = overlay.props ?? {}, [value, setValue] = (0, import_react40.useState)(options.initial ?? ""), finish = (result) => {
|
|
12129
12295
|
resolveAsk(overlay.id, result), close();
|
|
12130
12296
|
};
|
|
12131
12297
|
return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
|
|
@@ -12158,13 +12324,13 @@ function InputDialog({ overlay, close, width }) {
|
|
|
12158
12324
|
// src/main/tui/views/files/index.tsx
|
|
12159
12325
|
var import_jsx_runtime48 = __toESM(require_jsx_runtime(), 1), TAB_TITLES = { files: "Files", inbox: "Inbox", outbox: "Outbox", meta: "Meta" };
|
|
12160
12326
|
function FilesView({ width, height, focused }) {
|
|
12161
|
-
let theme2 = useTheme(), store = useStore(), agent2 = useSelectedAgent(), stopped = useSelectedTracked(), loop = useSelectedLoop(), [state, setState] = useViewState(VIEW_ID, INITIAL_STATE), agentId = agent2?.summary.id ?? null, agentLabel5 = agent2 ? agent2.summary.handle || agent2.summary.name : "", patch = (0,
|
|
12327
|
+
let theme2 = useTheme(), store = useStore(), agent2 = useSelectedAgent(), stopped = useSelectedTracked(), loop = useSelectedLoop(), [state, setState] = useViewState(VIEW_ID, INITIAL_STATE), agentId = agent2?.summary.id ?? null, agentLabel5 = agent2 ? agent2.summary.handle || agent2.summary.name : "", patch = (0, import_react41.useCallback)((next) => {
|
|
12162
12328
|
setState({ ...readViewState(store.getState()), ...next });
|
|
12163
|
-
}, [store, setState]), setPane = (0,
|
|
12329
|
+
}, [store, setState]), setPane = (0, import_react41.useCallback)((pane) => patch({ pane }), [patch]), setTab = (tab) => patch({ tab, pane: "list" }), setAgentState = (0, import_react41.useCallback)((next) => {
|
|
12164
12330
|
if (!agentId) return;
|
|
12165
12331
|
let current = readViewState(store.getState());
|
|
12166
12332
|
patch({ agents: { ...current.agents, [agentId]: { ...current.agents[agentId], ...next } } });
|
|
12167
|
-
}, [agentId, store, patch]), clearRequest = (0,
|
|
12333
|
+
}, [agentId, store, patch]), clearRequest = (0, import_react41.useCallback)(() => patch({ request: void 0 }), [patch]);
|
|
12168
12334
|
if (useKeys((input, key) => {
|
|
12169
12335
|
if (key.ctrl || key.meta || key.shift && (key.leftArrow || key.rightArrow)) return !1;
|
|
12170
12336
|
let step = key.rightArrow || input === "]" ? 1 : key.leftArrow || input === "[" ? -1 : 0;
|
|
@@ -12410,7 +12576,7 @@ function row2(cells2, width) {
|
|
|
12410
12576
|
}
|
|
12411
12577
|
|
|
12412
12578
|
// src/main/tui/views/loops/hooks.ts
|
|
12413
|
-
var
|
|
12579
|
+
var import_react42 = __toESM(require_react(), 1);
|
|
12414
12580
|
var LOOPS_REV_KEY = "loops.rev", revCounter = 0;
|
|
12415
12581
|
function bumpLoopsData(actions4, _state) {
|
|
12416
12582
|
actions4.setViewState(LOOPS_REV_KEY, ++revCounter);
|
|
@@ -12431,15 +12597,15 @@ function useEventTick(agentId, types) {
|
|
|
12431
12597
|
});
|
|
12432
12598
|
}
|
|
12433
12599
|
function useNow(ms = 3e4) {
|
|
12434
|
-
let [now, setNow] = (0,
|
|
12435
|
-
return (0,
|
|
12600
|
+
let [now, setNow] = (0, import_react42.useState)(() => Date.now());
|
|
12601
|
+
return (0, import_react42.useEffect)(() => {
|
|
12436
12602
|
let timer = setInterval(() => setNow(Date.now()), ms);
|
|
12437
12603
|
return () => clearInterval(timer);
|
|
12438
12604
|
}, [ms]), now;
|
|
12439
12605
|
}
|
|
12440
12606
|
function useAsyncData(load, deps) {
|
|
12441
|
-
let client = useClient(), [data, setData] = (0,
|
|
12442
|
-
(0,
|
|
12607
|
+
let client = useClient(), [data, setData] = (0, import_react42.useState)(void 0), [error, setError] = (0, import_react42.useState)(void 0), [loading, setLoading] = (0, import_react42.useState)(!1), [nonce2, setNonce] = (0, import_react42.useState)(0), seq = (0, import_react42.useRef)(0);
|
|
12608
|
+
(0, import_react42.useEffect)(() => {
|
|
12443
12609
|
if (!load) {
|
|
12444
12610
|
setData(void 0), setError(void 0), setLoading(!1);
|
|
12445
12611
|
return;
|
|
@@ -12454,7 +12620,7 @@ function useAsyncData(load, deps) {
|
|
|
12454
12620
|
}
|
|
12455
12621
|
);
|
|
12456
12622
|
}, [...deps, nonce2, client]);
|
|
12457
|
-
let reload = (0,
|
|
12623
|
+
let reload = (0, import_react42.useCallback)(() => setNonce((n) => n + 1), []);
|
|
12458
12624
|
return { data, error, loading, reload };
|
|
12459
12625
|
}
|
|
12460
12626
|
var TIMER_EVENTS = ["timer.fired", "config.changed", "agent.loaded"];
|
|
@@ -12464,7 +12630,7 @@ function useAgentTimers(agentId) {
|
|
|
12464
12630
|
}
|
|
12465
12631
|
function useFleetTimers(enabled) {
|
|
12466
12632
|
let rev = useLoopsRev(), tick = useEventTick(void 0, TIMER_EVENTS), agents = useTuiSelector((s) => s.agentOrder.map((id) => `${id}\0${s.agents[id]?.summary.handle || s.agents[id]?.summary.name || id}`).join(`
|
|
12467
|
-
`)), [failures, setFailures] = (0,
|
|
12633
|
+
`)), [failures, setFailures] = (0, import_react42.useState)([]);
|
|
12468
12634
|
return { ...useAsyncData(enabled ? async (c) => {
|
|
12469
12635
|
let list = agents ? agents.split(`
|
|
12470
12636
|
`).map((line) => {
|
|
@@ -13099,7 +13265,7 @@ var TIMERS_TAB_HINTS = [
|
|
|
13099
13265
|
];
|
|
13100
13266
|
|
|
13101
13267
|
// src/main/tui/views/loops/TriggersTab.tsx
|
|
13102
|
-
var
|
|
13268
|
+
var import_react43 = __toESM(require_react(), 1);
|
|
13103
13269
|
|
|
13104
13270
|
// src/main/tui/views/loops/trigger-ops.ts
|
|
13105
13271
|
function diffText(before, after, maxLines = 24) {
|
|
@@ -13142,7 +13308,7 @@ It has no targets yet, so it will not wake anything. Add a target with e.` : "";
|
|
|
13142
13308
|
var import_jsx_runtime52 = __toESM(require_jsx_runtime(), 1);
|
|
13143
13309
|
function TriggersTab({ agentId, width, height, focused, view: view2, setView, tabKeys }) {
|
|
13144
13310
|
let theme2 = useTheme(), actions4 = useActions(), agent2 = useAgent(agentId), runtime3 = useRuntimeTriggers(agentId), config2 = agent2?.config;
|
|
13145
|
-
(0,
|
|
13311
|
+
(0, import_react43.useEffect)(() => {
|
|
13146
13312
|
config2 || actions4.loadConfig(agentId);
|
|
13147
13313
|
}, [agentId, !!config2]);
|
|
13148
13314
|
let label2 = agent2?.summary.handle || agent2?.summary.name || agentId, index = Math.min(view2.triggerIndex, TRIGGER_TYPES2.length - 1), selectedType = TRIGGER_TYPES2[index], selectedCfg = config2?.triggers?.[selectedType], w = width, detailRows = Math.max(0, Math.min(8, height - TRIGGER_TYPES2.length - 5)), listRows = Math.max(1, height - 4 - detailRows - (runtime3.error ? 1 : 0)), runtimeOf = (type) => runtime3.data?.configured.find((c) => c.type === type), cols = (type) => {
|
|
@@ -13310,7 +13476,7 @@ var HISTORY_TAB_HINTS = [
|
|
|
13310
13476
|
];
|
|
13311
13477
|
|
|
13312
13478
|
// src/main/tui/views/loops/LoopWizard.tsx
|
|
13313
|
-
var
|
|
13479
|
+
var import_react44 = __toESM(require_react(), 1);
|
|
13314
13480
|
|
|
13315
13481
|
// src/main/tui/views/loops/templates.ts
|
|
13316
13482
|
var base = [...DEFAULT_NEW_LOOP_TOOLS], LOOP_TEMPLATES = [
|
|
@@ -13418,7 +13584,7 @@ function draftFromValues(v) {
|
|
|
13418
13584
|
return { kind: v.scheduleKind ?? "none", value: String(v.scheduleValue ?? ""), payload: String(v.payload ?? ""), maxRuns: String(v.maxRuns ?? "") };
|
|
13419
13585
|
}
|
|
13420
13586
|
function LoopWizard({ overlay, close, width, height }) {
|
|
13421
|
-
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), agent2 = useAgent(props.agentId), loops2 = useLoops(props.agentId) ?? [], timers = useAgentTimers(props.agentId), { suspendTerminal } = use_app_default(), config2 = agent2?.config, host = hostLoopTools(config2), existing = props.mode === "edit" ? loops2.find((l) => l.info.name === props.name)?.info.config ?? void 0 : void 0, provider = config2?.model?.provider, models = useModelList(props.agentId, provider), takenNames = loops2.map((l) => l.info.name), initialTemplate = props.mode === "create" ? findTemplate(props.template) : void 0, [step, setStep] = (0,
|
|
13587
|
+
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), agent2 = useAgent(props.agentId), loops2 = useLoops(props.agentId) ?? [], timers = useAgentTimers(props.agentId), { suspendTerminal } = use_app_default(), config2 = agent2?.config, host = hostLoopTools(config2), existing = props.mode === "edit" ? loops2.find((l) => l.info.name === props.name)?.info.config ?? void 0 : void 0, provider = config2?.model?.provider, models = useModelList(props.agentId, provider), takenNames = loops2.map((l) => l.info.name), initialTemplate = props.mode === "create" ? findTemplate(props.template) : void 0, [step, setStep] = (0, import_react44.useState)(props.mode === "create" && !initialTemplate ? "template" : "form"), [template, setTemplate] = (0, import_react44.useState)(initialTemplate), [values, setValues] = (0, import_react44.useState)(() => initialValues2(props, existing, initialTemplate, host, takenNames)), [touched, setTouched] = (0, import_react44.useState)(!1), [outcome, setOutcome] = (0, import_react44.useState)(null), dialogWidth = Math.max(40, Math.min(width - 4, 96)), inner = dialogWidth - 4, bodyRows = Math.max(6, height - 8), label2 = agent2 ? agentName3(store.getState(), props.agentId) : props.agentId, wanted = Array.isArray(values.tools) ? values.tools : [], options = toolOptions(host, [...wanted, ...existing?.tools ?? [], ...template?.tools ?? []]), draft = draftFromValues(values), loopName = props.mode === "edit" ? props.name ?? "" : String(values.name ?? ""), schedule = scheduleToTimer(draft, loopName), existingTimers = timers.data ? timersForLoop(timers.data, loopName) : [], errors = (0, import_react44.useMemo)(() => {
|
|
13422
13588
|
let e = {};
|
|
13423
13589
|
props.mode === "create" && (e.name = validateLoopName(String(values.name ?? ""), takenNames) ?? void 0), e.goal = validateGoal(String(values.goal ?? ""), !!values.autostart) ?? void 0;
|
|
13424
13590
|
let compact2 = String(values.compact ?? "").trim();
|
|
@@ -13674,7 +13840,7 @@ function MissingLoop({ title, name, close, width }) {
|
|
|
13674
13840
|
}
|
|
13675
13841
|
|
|
13676
13842
|
// src/main/tui/views/loops/TimerDialog.tsx
|
|
13677
|
-
var
|
|
13843
|
+
var import_react45 = __toESM(require_react(), 1);
|
|
13678
13844
|
var import_jsx_runtime55 = __toESM(require_jsx_runtime(), 1), WHEN_LABEL2 = { none: "When", every: "Every", daily: "Daily at", cron: "Cron", in: "After", at: "At" }, WHEN_HINT2 = {
|
|
13679
13845
|
none: "",
|
|
13680
13846
|
every: "15m, 2h, 1h30m, 1d",
|
|
@@ -13691,13 +13857,13 @@ function choiceOf(scope) {
|
|
|
13691
13857
|
return agent2 && system ? "both" : system ? "system" : "agent";
|
|
13692
13858
|
}
|
|
13693
13859
|
function TimerDialog({ overlay, close, width, height }) {
|
|
13694
|
-
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), agent2 = useAgent(props.agentId), loops2 = useLoops(props.agentId) ?? [], timers = useAgentTimers(props.agentId), existing = props.timerId !== void 0 ? timers.data?.find((t) => t.id === props.timerId) : void 0, editing = props.timerId !== void 0, [values, setValues] = (0,
|
|
13860
|
+
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), agent2 = useAgent(props.agentId), loops2 = useLoops(props.agentId) ?? [], timers = useAgentTimers(props.agentId), existing = props.timerId !== void 0 ? timers.data?.find((t) => t.id === props.timerId) : void 0, editing = props.timerId !== void 0, [values, setValues] = (0, import_react45.useState)(() => editing ? null : initialValues3(void 0, props.loop)), [step, setStep] = (0, import_react45.useState)("form"), [touched, setTouched] = (0, import_react45.useState)(!1), [outcome, setOutcome] = (0, import_react45.useState)([]), current = values ?? (existing ? initialValues3(existing) : null), dialogWidth = Math.max(40, Math.min(width - 4, 90)), inner = dialogWidth - 4, bodyRows = Math.max(6, height - 8), label2 = agentName3(store.getState(), props.agentId), loopNames2 = [MAIN_LOOP, ...loops2.filter((l) => !l.info.isMain).map((l) => l.info.name)];
|
|
13695
13861
|
current && !loopNames2.includes(String(current.loop)) && loopNames2.push(String(current.loop));
|
|
13696
13862
|
let scopeChoice = current?.scope ?? "agent", kind = current?.scheduleKind ?? "every", targetLoop = scopeChoice === "system" ? void 0 : String(current?.loop ?? MAIN_LOOP), result = current ? scheduleToTimer(
|
|
13697
13863
|
{ kind, value: String(current.scheduleValue ?? ""), payload: String(current.payload ?? ""), maxRuns: String(current.maxRuns ?? "") },
|
|
13698
13864
|
targetLoop,
|
|
13699
13865
|
{ scope: scopeOf(scopeChoice), lambda: String(current.lambda ?? "").trim() || void 0 }
|
|
13700
|
-
) : null, input = result?.input ? { ...result.input, ...current?.locked ? { locked: !0 } : {} } : void 0, oldLoop = existing ? timerLoop2(existing) : null, loopChanged = !!existing && (targetLoop ?? null) !== oldLoop && targetLoop !== void 0 && oldLoop !== null, errors = (0,
|
|
13866
|
+
) : null, input = result?.input ? { ...result.input, ...current?.locked ? { locked: !0 } : {} } : void 0, oldLoop = existing ? timerLoop2(existing) : null, loopChanged = !!existing && (targetLoop ?? null) !== oldLoop && targetLoop !== void 0 && oldLoop !== null, errors = (0, import_react45.useMemo)(() => {
|
|
13701
13867
|
let e = {};
|
|
13702
13868
|
return result?.error && (e.scheduleValue = result.error), scopeChoice !== "agent" && !String(current?.lambda ?? "").trim() && (e.lambda = "System-scope timers run a lambda: path/file.ts:functionName"), e;
|
|
13703
13869
|
}, [result?.error, scopeChoice, current?.lambda]), hasErrors = Object.values(errors).some(Boolean), fields = [
|
|
@@ -13822,10 +13988,10 @@ function initialValues3(timer, loop) {
|
|
|
13822
13988
|
}
|
|
13823
13989
|
|
|
13824
13990
|
// src/main/tui/views/loops/TriggerDialog.tsx
|
|
13825
|
-
var
|
|
13991
|
+
var import_react46 = __toESM(require_react(), 1);
|
|
13826
13992
|
var import_jsx_runtime56 = __toESM(require_jsx_runtime(), 1);
|
|
13827
13993
|
function TriggerDialog({ overlay, close, width, height }) {
|
|
13828
|
-
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), loops2 = useLoops(props.agentId) ?? [], loaded = useAsyncData((c) => c.config(props.agentId), [props.agentId]), original = loaded.data?.config.triggers?.[props.type], [draft, setDraft] = (0,
|
|
13994
|
+
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), loops2 = useLoops(props.agentId) ?? [], loaded = useAsyncData((c) => c.config(props.agentId), [props.agentId]), original = loaded.data?.config.triggers?.[props.type], [draft, setDraft] = (0, import_react46.useState)(null), current = draft ?? (loaded.data ? original ?? { enabled: !1, targets: [] } : null), [step, setStep] = (0, import_react46.useState)("targets"), [index, setIndex] = (0, import_react46.useState)(0), [editing, setEditing] = (0, import_react46.useState)(null), [targetValues, setTargetValues] = (0, import_react46.useState)({}), [targetErrors, setTargetErrors] = (0, import_react46.useState)({}), [message, setMessage] = (0, import_react46.useState)(""), dialogWidth = Math.max(44, Math.min(width - 4, 96)), inner = dialogWidth - 4, bodyRows = Math.max(6, height - 8), title = `Trigger ${props.type} ${theme2.glyph.sep} ${agentName3(store.getState(), props.agentId)}`, loopNames2 = [MAIN_LOOP, ...loops2.filter((l) => !l.info.isMain).map((l) => l.info.name)], dirty = !!draft && JSON.stringify(draft) !== JSON.stringify(original ?? { enabled: !1, targets: [] }), [confirmClose, setConfirmClose] = (0, import_react46.useState)(!1), update = (next) => setDraft(next), openTarget = (i) => {
|
|
13829
13995
|
let target2 = i === null ? void 0 : current?.targets[i];
|
|
13830
13996
|
setEditing(i), setTargetValues(targetToValues(target2)), setTargetErrors({}), setStep("target");
|
|
13831
13997
|
}, saveTarget = () => {
|
|
@@ -13981,7 +14147,7 @@ function valuesToTarget(v, base2) {
|
|
|
13981
14147
|
}
|
|
13982
14148
|
|
|
13983
14149
|
// src/main/tui/views/loops/EntryDialog.tsx
|
|
13984
|
-
var
|
|
14150
|
+
var import_react47 = __toESM(require_react(), 1);
|
|
13985
14151
|
var import_jsx_runtime57 = __toESM(require_jsx_runtime(), 1);
|
|
13986
14152
|
function entryLines(entry, width) {
|
|
13987
14153
|
let out = [], push = (text, tone) => {
|
|
@@ -14023,7 +14189,7 @@ function pretty(value) {
|
|
|
14023
14189
|
}
|
|
14024
14190
|
}
|
|
14025
14191
|
function EntryDialog({ overlay, close, width, height }) {
|
|
14026
|
-
let { entry, loop } = overlay.props ?? {}, theme2 = useTheme(), dialogWidth = Math.max(40, Math.min(width - 4, 110)), inner = dialogWidth - 4, rows = Math.max(4, height - 10), lines = entry ? entryLines(entry, inner) : [], [top, setTop] = (0,
|
|
14192
|
+
let { entry, loop } = overlay.props ?? {}, theme2 = useTheme(), dialogWidth = Math.max(40, Math.min(width - 4, 110)), inner = dialogWidth - 4, rows = Math.max(4, height - 10), lines = entry ? entryLines(entry, inner) : [], [top, setTop] = (0, import_react47.useState)(0), maxTop = Math.max(0, lines.length - rows);
|
|
14027
14193
|
if (useKeys((input, key) => key.escape || key.backspace || key.return || input === "q" ? (close(), !0) : key.downArrow || input === "j" ? (setTop((t) => Math.min(maxTop, t + 1)), !0) : key.upArrow || input === "k" ? (setTop((t) => Math.max(0, t - 1)), !0) : key.pageDown || input === " " ? (setTop((t) => Math.min(maxTop, t + rows)), !0) : key.pageUp ? (setTop((t) => Math.max(0, t - rows)), !0) : key.home || input === "g" ? (setTop(0), !0) : ((key.end || input === "G") && setTop(maxTop), !0), { layer: "overlay" }), !entry) return null;
|
|
14028
14194
|
let tokens = formatTokens(entry);
|
|
14029
14195
|
return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(Modal, { title: `${loop} ${theme2.glyph.sep} entry #${entry.seq}`, width: dialogWidth, hints: [{ keys: "up down", label: "scroll" }, { keys: "pgup pgdn", label: "page" }, { keys: "backspace esc", label: "back" }], children: [
|
|
@@ -14051,14 +14217,14 @@ function EntryDialog({ overlay, close, width, height }) {
|
|
|
14051
14217
|
}
|
|
14052
14218
|
|
|
14053
14219
|
// src/main/tui/views/loops/SendDialog.tsx
|
|
14054
|
-
var
|
|
14220
|
+
var import_react48 = __toESM(require_react(), 1);
|
|
14055
14221
|
var import_jsx_runtime58 = __toESM(require_jsx_runtime(), 1);
|
|
14056
14222
|
async function sendToLoop(actions4, agentId, loop, text, agentLabel5) {
|
|
14057
14223
|
let ok = await actions4.sendChat(text, { agentId, loop });
|
|
14058
14224
|
return ok ? actions4.toast(`Sent to ${agentLabel5} ${loop}: turn queued (its reply is in the ${loop} transcript)`, "success") : actions4.toast(`Not sent to ${loop}: see the error in the ${loop} transcript`, "error"), ok;
|
|
14059
14225
|
}
|
|
14060
14226
|
function SendDialog({ overlay, close, width }) {
|
|
14061
|
-
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), loop = useLoop(props.agentId, props.loop), [values, setValues] = (0,
|
|
14227
|
+
let props = overlay.props ?? {}, theme2 = useTheme(), store = useStore(), actions4 = useActions(), loop = useLoop(props.agentId, props.loop), [values, setValues] = (0, import_react48.useState)({ text: props.text ?? "" }), [error, setError] = (0, import_react48.useState)(), label2 = agentName3(store.getState(), props.agentId), dialogWidth = Math.max(40, Math.min(width - 4, 90));
|
|
14062
14228
|
return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Modal, { title: `Send to ${props.loop} ${theme2.glyph.sep} ${label2}`, width: dialogWidth, hints: [{ keys: "enter", label: "send & wake" }, { keys: "esc", label: "cancel" }], children: [
|
|
14063
14229
|
loop && !loop.info.enabled ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(Text, { color: theme2.color.warn, children: [
|
|
14064
14230
|
theme2.glyph.warn,
|
|
@@ -14567,7 +14733,7 @@ function resolutionText(task) {
|
|
|
14567
14733
|
}
|
|
14568
14734
|
|
|
14569
14735
|
// src/main/tui/views/inspect/SettingsTab.tsx
|
|
14570
|
-
var
|
|
14736
|
+
var import_react49 = __toESM(require_react(), 1);
|
|
14571
14737
|
|
|
14572
14738
|
// src/main/tui/views/inspect/settings-model.ts
|
|
14573
14739
|
var TOOL_GROUPS = [
|
|
@@ -15032,16 +15198,16 @@ async function actOnSetting(actions4, agentId, row4, config2) {
|
|
|
15032
15198
|
}
|
|
15033
15199
|
}
|
|
15034
15200
|
function SettingsTab({ agentId, width, height, focused }) {
|
|
15035
|
-
let theme2 = useTheme(), actions4 = useActions(), client = useClient(), agent2 = useAgent(agentId), [inspect3, update] = useInspectState(), [extras, setExtras] = (0,
|
|
15201
|
+
let theme2 = useTheme(), actions4 = useActions(), client = useClient(), agent2 = useAgent(agentId), [inspect3, update] = useInspectState(), [extras, setExtras] = (0, import_react49.useState)({}), config2 = agent2?.config, loopNames2 = [MAIN_LOOP, ...(config2?.loops ?? []).map((l) => l.name)], reload = async (announce = !1) => {
|
|
15036
15202
|
let cfg = await actions4.loadConfig(agentId), names = [MAIN_LOOP, ...(cfg?.loops ?? []).map((l) => l.name)], [context, host] = await Promise.all([
|
|
15037
15203
|
loadContextUsage(client, agentId, names),
|
|
15038
15204
|
client.setting("compute").then((r) => !!r.value?.hostAccessEnabled, () => null)
|
|
15039
15205
|
]);
|
|
15040
15206
|
setExtras({ context, daemonHostAccess: host }), announce && cfg && actions4.toast("Settings reloaded", "info", 1500);
|
|
15041
15207
|
};
|
|
15042
|
-
(0,
|
|
15208
|
+
(0, import_react49.useEffect)(() => {
|
|
15043
15209
|
reload();
|
|
15044
|
-
}, [agentId]), (0,
|
|
15210
|
+
}, [agentId]), (0, import_react49.useEffect)(() => {
|
|
15045
15211
|
config2 && loadContextUsage(client, agentId, loopNames2).then((context) => setExtras((e) => ({ ...e, context })));
|
|
15046
15212
|
}, [loopNames2.join(",")]);
|
|
15047
15213
|
let rows = config2 ? settingRows(config2, extras) : [], index = Math.min(inspect3.settingsIndex ?? 0, Math.max(0, rows.length - 1));
|
|
@@ -15104,7 +15270,7 @@ function SettingsTab({ agentId, width, height, focused }) {
|
|
|
15104
15270
|
}
|
|
15105
15271
|
|
|
15106
15272
|
// src/main/tui/views/inspect/SettingDialogs.tsx
|
|
15107
|
-
var
|
|
15273
|
+
var import_react50 = __toESM(require_react(), 1);
|
|
15108
15274
|
var import_jsx_runtime62 = __toESM(require_jsx_runtime(), 1);
|
|
15109
15275
|
function compactionRows(config2) {
|
|
15110
15276
|
let main = mainThreshold(config2);
|
|
@@ -15123,8 +15289,8 @@ async function applyThreshold(store, agentId, loop, value) {
|
|
|
15123
15289
|
return loop === MAIN_LOOP ? applyChange(actions4, agentId, (cfg) => setMainThreshold(cfg, value), "Compaction") : await actions4.updateLoop(agentId, loop, { compact_threshold: value }) ? (await actions4.loadConfig(agentId), actions4.toast(value === null ? `${loop} inherits main\u2019s threshold again` : `${loop} compacts at ${formatTokens2(value)} tokens`, "success", 2500), !0) : !1;
|
|
15124
15290
|
}
|
|
15125
15291
|
function CompactionOverlay({ overlay, close, width, height }) {
|
|
15126
|
-
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, agentId = String(overlay.props?.agentId ?? ""), agent2 = useAgent(agentId), config2 = agent2?.config, rows = config2 ? compactionRows(config2) : [], initial = Math.max(0, rows.findIndex((r) => r.loop === overlay.props?.loop)), [index, setIndex] = (0,
|
|
15127
|
-
(0,
|
|
15292
|
+
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, agentId = String(overlay.props?.agentId ?? ""), agent2 = useAgent(agentId), config2 = agent2?.config, rows = config2 ? compactionRows(config2) : [], initial = Math.max(0, rows.findIndex((r) => r.loop === overlay.props?.loop)), [index, setIndex] = (0, import_react50.useState)(initial), [editing, setEditing] = (0, import_react50.useState)(null), [draft, setDraft] = (0, import_react50.useState)(""), [error, setError] = (0, import_react50.useState)(null), [context, setContext] = (0, import_react50.useState)({});
|
|
15293
|
+
(0, import_react50.useEffect)(() => {
|
|
15128
15294
|
config2 || actions4.loadConfig(agentId), loadContextUsage(store.client, agentId, [MAIN_LOOP, ...(config2?.loops ?? []).map((l) => l.name)]).then(setContext);
|
|
15129
15295
|
}, [agentId]);
|
|
15130
15296
|
let row4 = rows[Math.min(index, Math.max(0, rows.length - 1))], submit = async (value) => {
|
|
@@ -15207,7 +15373,7 @@ function CompactionOverlay({ overlay, close, width, height }) {
|
|
|
15207
15373
|
);
|
|
15208
15374
|
}
|
|
15209
15375
|
function SettingChoiceOverlay({ overlay, close, width }) {
|
|
15210
|
-
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, agentId = String(overlay.props?.agentId ?? ""), setting = overlay.props?.setting === "send" ? "send" : "visibility", m = useAgent(agentId)?.config?.messaging, options = setting === "send" ? SEND_MODES.map((v) => ({ value: v, hint: SEND_MODE_HINTS[v] })) : VISIBILITY_TIERS.map((v) => ({ value: v, hint: VISIBILITY_HINTS[v] })), current = setting === "send" ? m?.mode ?? "respond_only" : m?.visibility ?? "localhost", [index, setIndex] = (0,
|
|
15376
|
+
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, agentId = String(overlay.props?.agentId ?? ""), setting = overlay.props?.setting === "send" ? "send" : "visibility", m = useAgent(agentId)?.config?.messaging, options = setting === "send" ? SEND_MODES.map((v) => ({ value: v, hint: SEND_MODE_HINTS[v] })) : VISIBILITY_TIERS.map((v) => ({ value: v, hint: VISIBILITY_HINTS[v] })), current = setting === "send" ? m?.mode ?? "respond_only" : m?.visibility ?? "localhost", [index, setIndex] = (0, import_react50.useState)(Math.max(0, options.findIndex((o) => o.value === current))), apply = async (value) => {
|
|
15211
15377
|
close(), value !== current && (setting === "visibility" && (value === "lan" || value === "public") && !await actions4.confirm({
|
|
15212
15378
|
title: `Make the agent reachable ${value === "public" ? "from the internet" : "on the local network"}?`,
|
|
15213
15379
|
message: `Visibility ${value}: ${VISIBILITY_HINTS[value]}. Other agents there can send it messages.`,
|
|
@@ -15437,13 +15603,13 @@ var inspect = {
|
|
|
15437
15603
|
], inspectCommands = { commands: [inspect, model, config, tasks, instructions, tools, compaction, media], actions: actions2 };
|
|
15438
15604
|
|
|
15439
15605
|
// src/main/tui/views/inspect/EventsTab.tsx
|
|
15440
|
-
var
|
|
15606
|
+
var import_react52 = __toESM(require_react(), 1);
|
|
15441
15607
|
|
|
15442
15608
|
// src/main/tui/views/inspect/hooks.ts
|
|
15443
|
-
var
|
|
15609
|
+
var import_react51 = __toESM(require_react(), 1);
|
|
15444
15610
|
function useDaemonData(key, load) {
|
|
15445
|
-
let store = useStore(), [data, setData] = (0,
|
|
15446
|
-
loadRef.current = load, (0,
|
|
15611
|
+
let store = useStore(), [data, setData] = (0, import_react51.useState)(void 0), [error, setError] = (0, import_react51.useState)(void 0), [loading, setLoading] = (0, import_react51.useState)(!1), [loadedAt, setLoadedAt] = (0, import_react51.useState)(void 0), [nonce2, setNonce] = (0, import_react51.useState)(0), loadRef = (0, import_react51.useRef)(load);
|
|
15612
|
+
loadRef.current = load, (0, import_react51.useEffect)(() => {
|
|
15447
15613
|
if (key === null) {
|
|
15448
15614
|
setData(void 0), setError(void 0);
|
|
15449
15615
|
return;
|
|
@@ -15460,12 +15626,12 @@ function useDaemonData(key, load) {
|
|
|
15460
15626
|
cancelled = !0;
|
|
15461
15627
|
};
|
|
15462
15628
|
}, [store, key, nonce2]);
|
|
15463
|
-
let reload = (0,
|
|
15629
|
+
let reload = (0, import_react51.useCallback)(() => setNonce((n) => n + 1), []);
|
|
15464
15630
|
return { data, error, loading, loadedAt, reload };
|
|
15465
15631
|
}
|
|
15466
15632
|
function useAgentName() {
|
|
15467
15633
|
let store = useStore();
|
|
15468
|
-
return (0,
|
|
15634
|
+
return (0, import_react51.useCallback)((agentId) => {
|
|
15469
15635
|
if (!agentId) return "daemon";
|
|
15470
15636
|
let summary = store.getState().agents[agentId]?.summary;
|
|
15471
15637
|
return summary?.handle || summary?.name || agentId.slice(0, 8);
|
|
@@ -15573,7 +15739,7 @@ function eventRow(event) {
|
|
|
15573
15739
|
// src/main/tui/views/inspect/EventsTab.tsx
|
|
15574
15740
|
var import_jsx_runtime63 = __toESM(require_jsx_runtime(), 1), EMPTY2 = [], EVENTS_REFRESH_MS = 100;
|
|
15575
15741
|
function EventsTab({ width, height, focused, filters: stored, update, scope, json: json2 }) {
|
|
15576
|
-
let theme2 = useTheme(), filters = scope === "agent" ? { ...stored, agent: "selected" } : stored, live = useThrottledSelector((s) => s.lastEvents ?? EMPTY2, EVENTS_REFRESH_MS), selectedAgentId = useSelectedAgentId(), selectedLoop = useSelectedLoop(), nameOf = useAgentName(), [frozen, setFrozen] = (0,
|
|
15742
|
+
let theme2 = useTheme(), filters = scope === "agent" ? { ...stored, agent: "selected" } : stored, live = useThrottledSelector((s) => s.lastEvents ?? EMPTY2, EVENTS_REFRESH_MS), selectedAgentId = useSelectedAgentId(), selectedLoop = useSelectedLoop(), nameOf = useAgentName(), [frozen, setFrozen] = (0, import_react52.useState)(null), [clearedAfter, setClearedAfter] = (0, import_react52.useState)(0), [anchor, setAnchor] = (0, import_react52.useState)(null), [pinned, setPinned] = (0, import_react52.useState)(!0), [detail, setDetail] = (0, import_react52.useState)(!1), [editing, setEditing] = (0, import_react52.useState)(null), [draft, setDraft] = (0, import_react52.useState)(filters.types), [query, setQuery] = (0, import_react52.useState)(""), source = frozen ?? live, { types, agent: agent2, loop } = filters, events2 = (0, import_react52.useMemo)(
|
|
15577
15743
|
() => {
|
|
15578
15744
|
let matched = filterEvents(source, { types, agent: agent2, loop, follow: !0 }, { selectedAgentId, selectedLoop });
|
|
15579
15745
|
clearedAfter && (matched = matched.filter((e) => e.timestamp > clearedAfter));
|
|
@@ -15581,10 +15747,10 @@ function EventsTab({ width, height, focused, filters: stored, update, scope, jso
|
|
|
15581
15747
|
return q && (matched = matched.filter((e) => eventRow(e).search.includes(q) || nameOf(e.agent_id).toLowerCase().includes(q))), matched;
|
|
15582
15748
|
},
|
|
15583
15749
|
[source, types, agent2, loop, selectedAgentId, selectedLoop, clearedAfter, query, nameOf]
|
|
15584
|
-
), indexOf = (0,
|
|
15750
|
+
), indexOf = (0, import_react52.useMemo)(() => {
|
|
15585
15751
|
let map = /* @__PURE__ */ new Map();
|
|
15586
15752
|
return events2.forEach((e, i) => map.set(eventKey(e), i)), map;
|
|
15587
|
-
}, [events2]), lastFrozen = frozen?.at(-1), newWhileFrozen = lastFrozen ? live.length - 1 - live.lastIndexOf(lastFrozen) : 0, following = filters.follow && pinned && !frozen, anchored = anchor === null ? -1 : indexOf.get(anchor) ?? -1, index = following || anchored < 0 ? Math.max(0, events2.length - 1) : anchored, current = events2[index], detailRows = detail && current ? Math.max(4, Math.floor((height - 3) / 2)) : 0, listHeight = Math.max(1, height - 2 - (editing ? 1 : 0) - (detailRows ? detailRows + 1 : 0)), nameWidth = 10, loopWidth = 12, typeWidth = 22, agentLabel5 = filters.agent === "selected" || filters.loop === "selected" ? selectedAgentId ? nameOf(selectedAgentId) : "selected (none)" : "all agents", loopLabel = filters.loop === "selected" ? selectedLoop : "all loops", onSelect = (0,
|
|
15753
|
+
}, [events2]), lastFrozen = frozen?.at(-1), newWhileFrozen = lastFrozen ? live.length - 1 - live.lastIndexOf(lastFrozen) : 0, following = filters.follow && pinned && !frozen, anchored = anchor === null ? -1 : indexOf.get(anchor) ?? -1, index = following || anchored < 0 ? Math.max(0, events2.length - 1) : anchored, current = events2[index], detailRows = detail && current ? Math.max(4, Math.floor((height - 3) / 2)) : 0, listHeight = Math.max(1, height - 2 - (editing ? 1 : 0) - (detailRows ? detailRows + 1 : 0)), nameWidth = 10, loopWidth = 12, typeWidth = 22, agentLabel5 = filters.agent === "selected" || filters.loop === "selected" ? selectedAgentId ? nameOf(selectedAgentId) : "selected (none)" : "all agents", loopLabel = filters.loop === "selected" ? selectedLoop : "all loops", onSelect = (0, import_react52.useCallback)((i, item) => {
|
|
15588
15754
|
setAnchor(item ? eventKey(item) : null), setPinned(i >= events2.length - 1);
|
|
15589
15755
|
}, [events2.length]), onKey = (input, key) => key.ctrl || key.meta ? !1 : key.return ? (setDetail((d) => !d), !0) : (key.escape || key.backspace) && detail ? (setDetail(!1), !0) : input === " " ? (frozen ? (setFrozen(null), setPinned(!0)) : setFrozen(live), !0) : input === "a" && scope === "all" ? (update({ agent: filters.agent === "all" ? "selected" : "all", loop: filters.agent === "all" ? filters.loop : "all" }), !0) : input === "l" ? (update({ loop: filters.loop === "all" ? "selected" : "all" }), !0) : input === "t" ? (setDraft(filters.types), setEditing("type"), !0) : input === "/" ? (setDraft(query), setEditing("search"), !0) : key.escape && query ? (setQuery(""), !0) : input === "f" ? (update({ follow: !filters.follow }), setPinned(!0), !0) : input === "c" ? (setClearedAfter(Date.now()), !0) : input === "x" && (filters.types || scope === "all" && filters.agent !== "all" || filters.loop !== "all") ? (update({ types: "", agent: scope === "all" ? "all" : "selected", loop: "all" }), !0) : !1, status = [
|
|
15590
15756
|
frozen ? `paused${newWhileFrozen > 0 ? ` (+${newWhileFrozen} new)` : ""}` : following ? "following" : "scrolled (End follows)",
|
|
@@ -15593,7 +15759,7 @@ function EventsTab({ width, height, focused, filters: stored, update, scope, jso
|
|
|
15593
15759
|
filters.types ? `type: ${filters.types}` : "all types",
|
|
15594
15760
|
query ? `search: ${query}` : "",
|
|
15595
15761
|
clearedAfter ? `cleared ${formatClock(clearedAfter)}` : ""
|
|
15596
|
-
].filter(Boolean).join(` ${theme2.glyph.sep} `), detailLines2 = (0,
|
|
15762
|
+
].filter(Boolean).join(` ${theme2.glyph.sep} `), detailLines2 = (0, import_react52.useMemo)(() => detailRows && current ? valueLines(current, json2).slice(0, detailRows) : [], [detailRows, current, json2]);
|
|
15597
15763
|
return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Box_default, { flexDirection: "column", width, height, children: [
|
|
15598
15764
|
/* @__PURE__ */ (0, import_jsx_runtime63.jsxs)(Text, { wrap: "truncate-end", children: [
|
|
15599
15765
|
/* @__PURE__ */ (0, import_jsx_runtime63.jsx)(Text, { bold: !0, color: theme2.color.live, children: "Umbilical " }),
|
|
@@ -15691,7 +15857,7 @@ function typeColor(theme2, type) {
|
|
|
15691
15857
|
}
|
|
15692
15858
|
|
|
15693
15859
|
// src/main/tui/views/inspect/ConfigTab.tsx
|
|
15694
|
-
var
|
|
15860
|
+
var import_react53 = __toESM(require_react(), 1);
|
|
15695
15861
|
var import_jsx_runtime64 = __toESM(require_jsx_runtime(), 1);
|
|
15696
15862
|
import { promises as fs5 } from "node:fs";
|
|
15697
15863
|
import { tmpdir as tmpdir4 } from "node:os";
|
|
@@ -15760,12 +15926,12 @@ Warning: ${check.warnings.join("; ")}` : ""}`,
|
|
|
15760
15926
|
}
|
|
15761
15927
|
}
|
|
15762
15928
|
function ConfigTab({ agentId, label: label2, width, height, focused }) {
|
|
15763
|
-
let theme2 = useTheme(), actions4 = useActions(), { suspendTerminal } = use_app_default(), agent2 = useAgent(agentId), [inspect3, update] = useInspectState(), [busy, setBusy] = (0,
|
|
15929
|
+
let theme2 = useTheme(), actions4 = useActions(), { suspendTerminal } = use_app_default(), agent2 = useAgent(agentId), [inspect3, update] = useInspectState(), [busy, setBusy] = (0, import_react53.useState)(!1), config2 = agent2?.config, edit = () => {
|
|
15764
15930
|
setBusy(!0), editConfigFlow(agentId, label2, actions4, suspendTerminal).finally(() => setBusy(!1));
|
|
15765
15931
|
};
|
|
15766
|
-
(0,
|
|
15932
|
+
(0, import_react53.useEffect)(() => {
|
|
15767
15933
|
!inspect3.editRequest || busy || (update({ editRequest: void 0 }), edit());
|
|
15768
|
-
}, [inspect3.editRequest]), (0,
|
|
15934
|
+
}, [inspect3.editRequest]), (0, import_react53.useEffect)(() => {
|
|
15769
15935
|
config2 || actions4.loadConfig(agentId);
|
|
15770
15936
|
}, [agentId]), useKeys((input, key) => key.ctrl || key.meta || busy ? !1 : input === "e" ? (edit(), !0) : input === "r" ? (actions4.loadConfig(agentId).then((c) => {
|
|
15771
15937
|
c && actions4.toast("Config reloaded", "info", 1500);
|
|
@@ -15799,7 +15965,7 @@ function ConfigTab({ agentId, label: label2, width, height, focused }) {
|
|
|
15799
15965
|
}
|
|
15800
15966
|
|
|
15801
15967
|
// src/main/tui/views/inspect/DiagTabs.tsx
|
|
15802
|
-
var
|
|
15968
|
+
var import_react54 = __toESM(require_react(), 1);
|
|
15803
15969
|
|
|
15804
15970
|
// src/main/tui/views/inspect/diag-lines.ts
|
|
15805
15971
|
function stamp(at) {
|
|
@@ -15901,7 +16067,7 @@ var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
|
|
|
15901
16067
|
function DiagTab({ agentId, width, height, focused, load, build, hint, prefix, onKey }) {
|
|
15902
16068
|
let theme2 = useTheme(), [inspect3] = useInspectState(), { data, error, loading, loadedAt, reload } = useDaemonData(agentId, load);
|
|
15903
16069
|
useKeys((input, key) => key.ctrl || key.meta ? !1 : input === "r" ? (reload(), !0) : onKey?.(input, key) ?? !1, { layer: "main", active: focused });
|
|
15904
|
-
let lines = (0,
|
|
16070
|
+
let lines = (0, import_react54.useMemo)(() => {
|
|
15905
16071
|
let head = prefix && !inspect3.json ? prefix : [];
|
|
15906
16072
|
return error ? [...head, plain(`Could not load: ${error}`, "error"), plain("r retries.", "muted")] : data === void 0 ? head : inspect3.json ? valueLines(data, !0) : [...head, ...build(data)];
|
|
15907
16073
|
}, [data, error, inspect3.json, build, prefix]);
|
|
@@ -15919,7 +16085,7 @@ function DiagTab({ agentId, width, height, focused, load, build, hint, prefix, o
|
|
|
15919
16085
|
] });
|
|
15920
16086
|
}
|
|
15921
16087
|
function RuntimeTab(props) {
|
|
15922
|
-
let store = useStore(), loops2 = useLoops(props.agentId), build = (0,
|
|
16088
|
+
let store = useStore(), loops2 = useLoops(props.agentId), build = (0, import_react54.useMemo)(() => (d) => runtimeLines(d, loops2), [loops2]), web = useTuiSelector((s) => s.web), config2 = useTuiSelector((s) => s.agents[props.agentId]?.config), site = siteOf(store.getState(), props.agentId), prefix = (0, import_react54.useMemo)(() => site ? siteLines(site) : void 0, [web, config2, props.agentId]);
|
|
15923
16089
|
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(DiagTab, { ...props, load: (c) => c.agentRuntime(props.agentId), build, prefix, onKey: (input, key) => !site || key.ctrl || key.meta ? !1 : input === "w" ? (openSite(store, props.agentId), !0) : input === "W" ? (copySiteUrl(store, props.agentId), !0) : !1, hint: site ? "w open site \xB7 W copy URL" : void 0 });
|
|
15924
16090
|
}
|
|
15925
16091
|
function siteLines(site) {
|
|
@@ -15932,7 +16098,7 @@ function siteLines(site) {
|
|
|
15932
16098
|
return out.push([{ text: " server ", tone: "key" }, { text: serverText(site.server), tone: site.url ? "success" : "muted" }]), out.push([{ text: " serves ", tone: "key" }, { text: servedText(site) }]), out.push(blank()), out;
|
|
15933
16099
|
}
|
|
15934
16100
|
function UsageTab(props) {
|
|
15935
|
-
let agent2 = useAgent(props.agentId), build = (0,
|
|
16101
|
+
let agent2 = useAgent(props.agentId), build = (0, import_react54.useMemo)(() => (d) => usageLines(d, agent2?.tokens, agent2?.lastModel), [agent2?.tokens, agent2?.lastModel]);
|
|
15936
16102
|
return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(DiagTab, { ...props, load: (c) => c.agentUsage(props.agentId), build });
|
|
15937
16103
|
}
|
|
15938
16104
|
function McpTab(props) {
|
|
@@ -15948,7 +16114,7 @@ function IdentityTab(props) {
|
|
|
15948
16114
|
}
|
|
15949
16115
|
var LOG_LIMIT = 200, LOG_POLL_MS = 2e3;
|
|
15950
16116
|
function LogsTab({ agentId, width, height, focused }) {
|
|
15951
|
-
let theme2 = useTheme(), actions4 = useActions(), { client } = useStore(), [inspect3, update] = useInspectState(), follow = inspect3.logsFollow, [logs, setLogs] = (0,
|
|
16117
|
+
let theme2 = useTheme(), actions4 = useActions(), { client } = useStore(), [inspect3, update] = useInspectState(), follow = inspect3.logsFollow, [logs, setLogs] = (0, import_react54.useState)([]), [error, setError] = (0, import_react54.useState)(void 0), [cursor, setCursor] = (0, import_react54.useState)(0), [pinned, setPinned] = (0, import_react54.useState)(!0), [detail, setDetail] = (0, import_react54.useState)(!1), lastId = (0, import_react54.useRef)(0), loadAll = async () => {
|
|
15952
16118
|
let result = await actions4.run("Logs", (c) => c.logs(agentId, { limit: LOG_LIMIT }));
|
|
15953
16119
|
if (!result) {
|
|
15954
16120
|
setError("could not load logs");
|
|
@@ -15957,9 +16123,9 @@ function LogsTab({ agentId, width, height, focused }) {
|
|
|
15957
16123
|
let sorted = [...result.logs].sort((a, b) => a.id - b.id);
|
|
15958
16124
|
lastId.current = sorted.at(-1)?.id ?? 0, setLogs(sorted), setError(void 0);
|
|
15959
16125
|
};
|
|
15960
|
-
(0,
|
|
16126
|
+
(0, import_react54.useEffect)(() => {
|
|
15961
16127
|
lastId.current = 0, setLogs([]), loadAll();
|
|
15962
|
-
}, [agentId]), (0,
|
|
16128
|
+
}, [agentId]), (0, import_react54.useEffect)(() => {
|
|
15963
16129
|
if (!follow) return;
|
|
15964
16130
|
let stopped = !1, timer = setInterval(async () => {
|
|
15965
16131
|
try {
|
|
@@ -16047,8 +16213,8 @@ function parseMaybeJson2(text) {
|
|
|
16047
16213
|
}
|
|
16048
16214
|
var PAGE = 50;
|
|
16049
16215
|
function TablesTab({ agentId, width, height, focused }) {
|
|
16050
|
-
let theme2 = useTheme(), [inspect3] = useInspectState(), tables = useDaemonData(agentId, (c) => c.tables(agentId)), [open2, setOpen] = (0,
|
|
16051
|
-
if ((0,
|
|
16216
|
+
let theme2 = useTheme(), [inspect3] = useInspectState(), tables = useDaemonData(agentId, (c) => c.tables(agentId)), [open2, setOpen] = (0, import_react54.useState)(null), [offset, setOffset] = (0, import_react54.useState)(0), [rowIndex, setRowIndex] = (0, import_react54.useState)(0), [rowDetail, setRowDetail] = (0, import_react54.useState)(!1), rows = useDaemonData(open2 ? `${agentId}:${open2}:${offset}` : null, (c) => c.table(agentId, open2 ?? "", { limit: PAGE, offset })), total = tables.data?.tables.find((t) => t.name === open2)?.row_count;
|
|
16217
|
+
if ((0, import_react54.useEffect)(() => {
|
|
16052
16218
|
setOpen(null), setOffset(0);
|
|
16053
16219
|
}, [agentId]), useKeys((input, key) => {
|
|
16054
16220
|
if (!open2 || key.ctrl || key.meta) return !1;
|
|
@@ -16123,7 +16289,7 @@ function rowKey(row4, all) {
|
|
|
16123
16289
|
}
|
|
16124
16290
|
|
|
16125
16291
|
// src/main/tui/views/inspect/TasksTab.tsx
|
|
16126
|
-
var
|
|
16292
|
+
var import_react55 = __toESM(require_react(), 1);
|
|
16127
16293
|
var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1), TASKS_RELOAD_MS = 250, FILTER_LABEL = {
|
|
16128
16294
|
pending: "pending (awaiting approval or resolve)",
|
|
16129
16295
|
active: "active (pending + running)",
|
|
@@ -16131,7 +16297,7 @@ var import_jsx_runtime66 = __toESM(require_jsx_runtime(), 1), TASKS_RELOAD_MS =
|
|
|
16131
16297
|
};
|
|
16132
16298
|
function useTaskEventReload(agentId, reload) {
|
|
16133
16299
|
let store = useStore();
|
|
16134
|
-
(0,
|
|
16300
|
+
(0, import_react55.useEffect)(() => {
|
|
16135
16301
|
let seen = store.getState().lastEvents.at(-1), timer = null, unsubscribe = store.subscribe(() => {
|
|
16136
16302
|
let events2 = store.getState().lastEvents, last = events2.at(-1);
|
|
16137
16303
|
if (last === seen) return;
|
|
@@ -16151,12 +16317,12 @@ function useTaskEventReload(agentId, reload) {
|
|
|
16151
16317
|
}, [store, agentId, reload]);
|
|
16152
16318
|
}
|
|
16153
16319
|
function TasksTab({ agentId, width, height, focused }) {
|
|
16154
|
-
let theme2 = useTheme(), actions4 = useActions(), agent2 = useAgent(agentId), agentLabel5 = agent2?.summary.handle || agent2?.summary.name || agentId, [inspect3, update] = useInspectState(), filter = inspect3.tasksFilter, [tick, setTick] = (0,
|
|
16155
|
-
useTaskEventReload(agentId, refresh2), (0,
|
|
16320
|
+
let theme2 = useTheme(), actions4 = useActions(), agent2 = useAgent(agentId), agentLabel5 = agent2?.summary.handle || agent2?.summary.name || agentId, [inspect3, update] = useInspectState(), filter = inspect3.tasksFilter, [tick, setTick] = (0, import_react55.useState)(0), refresh2 = (0, import_react55.useMemo)(() => () => setTick((n) => n + 1), []), tasks2 = useDaemonData(`${agentId}:${filter}:${tick}`, (c) => loadTasks(c, agentId, filter)), [selectedId, setSelectedId] = (0, import_react55.useState)(null), [detailId, setDetailId] = (0, import_react55.useState)(null), detail = useDaemonData(detailId ? `${agentId}:${detailId}:${tick}` : null, (c) => c.task(agentId, detailId ?? "")), [editing, setEditing] = (0, import_react55.useState)(!1), [draft, setDraft] = (0, import_react55.useState)(""), [query, setQuery] = (0, import_react55.useState)("");
|
|
16321
|
+
useTaskEventReload(agentId, refresh2), (0, import_react55.useEffect)(() => {
|
|
16156
16322
|
setSelectedId(null), setDetailId(null);
|
|
16157
16323
|
}, [agentId]);
|
|
16158
|
-
let all = (0,
|
|
16159
|
-
(0,
|
|
16324
|
+
let all = (0, import_react55.useMemo)(() => tasks2.data ?? [], [tasks2.data]), visible = (0, import_react55.useMemo)(() => searchTasks(all.filter((t) => matchesFilter(t, filter)), query), [all, filter, query]), found = selectedId ? visible.findIndex((t) => t.id === selectedId) : -1, index = found >= 0 ? found : 0, current = visible[index], adrift = selectedId !== null && found < 0;
|
|
16325
|
+
(0, import_react55.useEffect)(() => {
|
|
16160
16326
|
selectedId === null && visible[0] && setSelectedId(visible[0].id);
|
|
16161
16327
|
}, [selectedId, visible]);
|
|
16162
16328
|
let shown = detailId ? detail.data?.task ?? all.find((t) => t.id === detailId) : void 0, act = (input, task, drifted = !1) => {
|
|
@@ -16316,18 +16482,18 @@ function TasksTab({ agentId, width, height, focused }) {
|
|
|
16316
16482
|
}
|
|
16317
16483
|
|
|
16318
16484
|
// src/main/tui/views/inspect/ToolsDialog.tsx
|
|
16319
|
-
var
|
|
16485
|
+
var import_react56 = __toESM(require_react(), 1);
|
|
16320
16486
|
var import_jsx_runtime67 = __toESM(require_jsx_runtime(), 1);
|
|
16321
16487
|
function stateWords(row4) {
|
|
16322
16488
|
let parts = [row4.enabled ? "enabled" : "disabled"];
|
|
16323
16489
|
return row4.enabled && parts.push(row4.visible ? "in the agent\u2019s tool list" : "hidden from the tool list (still callable from code)"), row4.restricted && parts.push(row4.enabled ? "every LLM call waits for your approval" : "needs approval when enabled"), row4.locked && parts.push("locked: the agent cannot change it"), row4.status && parts.push(`MCP: ${row4.status}${row4.status === "changed" ? " (schema changed, review before enabling)" : ""}`), parts.join(" \xB7 ");
|
|
16324
16490
|
}
|
|
16325
16491
|
function ToolsOverlay({ overlay, close, width, height }) {
|
|
16326
|
-
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, agentId = String(overlay.props?.agentId ?? ""), agent2 = useAgent(agentId), config2 = agent2?.config, [catalog, setCatalog] = (0,
|
|
16327
|
-
(0,
|
|
16492
|
+
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, agentId = String(overlay.props?.agentId ?? ""), agent2 = useAgent(agentId), config2 = agent2?.config, [catalog, setCatalog] = (0, import_react56.useState)(null), [live, setLive] = (0, import_react56.useState)(null), [query, setQuery] = (0, import_react56.useState)(typeof overlay.props?.query == "string" ? overlay.props.query : ""), [typing, setTyping] = (0, import_react56.useState)(!1), [index, setIndex] = (0, import_react56.useState)(0), [busy, setBusy] = (0, import_react56.useState)(0);
|
|
16493
|
+
(0, import_react56.useEffect)(() => {
|
|
16328
16494
|
config2 || actions4.loadConfig(agentId), store.client.agentTools(agentId).then((r) => setCatalog(r.tools), () => setCatalog(null)), store.client.agentMcp(agentId).then(setLive, () => setLive(null));
|
|
16329
16495
|
}, [agentId]);
|
|
16330
|
-
let rows = (0,
|
|
16496
|
+
let rows = (0, import_react56.useMemo)(() => config2 ? filterToolRows(buildToolRows(config2, catalog), query) : [], [config2, catalog, query]), at = Math.min(index, Math.max(0, rows.length - 1)), row4 = rows[at], act = (field) => {
|
|
16331
16497
|
if (!row4) return;
|
|
16332
16498
|
setBusy((n) => n + 1);
|
|
16333
16499
|
let done = () => setBusy((n) => n - 1);
|
|
@@ -16457,17 +16623,17 @@ function ToolsOverlay({ overlay, close, width, height }) {
|
|
|
16457
16623
|
}
|
|
16458
16624
|
|
|
16459
16625
|
// src/main/tui/views/inspect/InstructionsDialog.tsx
|
|
16460
|
-
var
|
|
16626
|
+
var import_react57 = __toESM(require_react(), 1);
|
|
16461
16627
|
var import_jsx_runtime68 = __toESM(require_jsx_runtime(), 1);
|
|
16462
16628
|
function InstructionsOverlay({ overlay, close, width, height }) {
|
|
16463
|
-
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, { suspendTerminal } = use_app_default(), agentId = String(overlay.props?.agentId ?? ""), external = overlay.props?.editor === !0, who = store.getState().agents[agentId]?.summary.handle || store.getState().agents[agentId]?.summary.name || agentId, [original, setOriginal] = (0,
|
|
16629
|
+
let theme2 = useTheme(), store = useStore(), { actions: actions4 } = store, { suspendTerminal } = use_app_default(), agentId = String(overlay.props?.agentId ?? ""), external = overlay.props?.editor === !0, who = store.getState().agents[agentId]?.summary.handle || store.getState().agents[agentId]?.summary.name || agentId, [original, setOriginal] = (0, import_react57.useState)(null), [text, setText] = (0, import_react57.useState)(""), [locked, setLocked] = (0, import_react57.useState)(!1), [busy, setBusy] = (0, import_react57.useState)(external ? `editing in ${editorLabel()}\u2026` : null), closed = (0, import_react57.useRef)(!1), done = () => {
|
|
16464
16630
|
closed.current || (closed.current = !0, close());
|
|
16465
16631
|
}, openEditor = async (from) => {
|
|
16466
16632
|
setBusy(`editing in ${editorLabel()}\u2026`);
|
|
16467
16633
|
let edited = await editInstructionsExternally(actions4, who, from, suspendTerminal);
|
|
16468
16634
|
return setBusy(null), edited ?? null;
|
|
16469
16635
|
};
|
|
16470
|
-
(0,
|
|
16636
|
+
(0, import_react57.useEffect)(() => {
|
|
16471
16637
|
(async () => {
|
|
16472
16638
|
let fresh = await actions4.run("Instructions", (c) => c.config(agentId));
|
|
16473
16639
|
if (!fresh) {
|
|
@@ -16546,13 +16712,13 @@ function InstructionsOverlay({ overlay, close, width, height }) {
|
|
|
16546
16712
|
}
|
|
16547
16713
|
|
|
16548
16714
|
// src/main/tui/views/inspect/overlays.tsx
|
|
16549
|
-
var
|
|
16715
|
+
var import_react58 = __toESM(require_react(), 1);
|
|
16550
16716
|
var import_jsx_runtime69 = __toESM(require_jsx_runtime(), 1);
|
|
16551
16717
|
function ThemeOverlay({ overlay, close, width }) {
|
|
16552
|
-
let theme2 = useTheme(), store = useStore(), requested = typeof overlay.props?.name == "string" ? overlay.props.name : "", currentIndex = Math.max(0, THEMES.findIndex((t) => t.name === theme2.name)), [index, setIndex] = (0,
|
|
16718
|
+
let theme2 = useTheme(), store = useStore(), requested = typeof overlay.props?.name == "string" ? overlay.props.name : "", currentIndex = Math.max(0, THEMES.findIndex((t) => t.name === theme2.name)), [index, setIndex] = (0, import_react58.useState)(currentIndex), apply = (choice) => {
|
|
16553
16719
|
applyTheme(theme2, choice), close(), store.actions.toast(`Theme: ${choice.label}${choice.colors ? "" : " (no color)"}`, "success", 2500);
|
|
16554
16720
|
};
|
|
16555
|
-
if ((0,
|
|
16721
|
+
if ((0, import_react58.useEffect)(() => {
|
|
16556
16722
|
if (!requested) return;
|
|
16557
16723
|
let choice = requested === "next" ? findTheme(nextThemeName(theme2.name)) : findTheme(requested);
|
|
16558
16724
|
choice ? apply(choice) : (close(), store.actions.toast(`No theme "${requested}". Themes: ${THEMES.map((t) => t.name).join(", ")}`, "warn"));
|
|
@@ -16777,7 +16943,7 @@ var inspect2 = {
|
|
|
16777
16943
|
}, inspect_default = inspect2;
|
|
16778
16944
|
|
|
16779
16945
|
// src/main/tui/views/runtime/index.tsx
|
|
16780
|
-
var
|
|
16946
|
+
var import_react60 = __toESM(require_react(), 1);
|
|
16781
16947
|
|
|
16782
16948
|
// src/main/tui/views/runtime/commands.ts
|
|
16783
16949
|
var open = (ctx, tab) => openRuntime(ctx.actions, ctx.state(), { tab }), runtime = {
|
|
@@ -16833,11 +16999,11 @@ var events = {
|
|
|
16833
16999
|
})), runtimeCommands = { commands: commands2, actions: actions3 };
|
|
16834
17000
|
|
|
16835
17001
|
// src/main/tui/views/runtime/FoldersTab.tsx
|
|
16836
|
-
var
|
|
17002
|
+
var import_react59 = __toESM(require_react(), 1);
|
|
16837
17003
|
var import_jsx_runtime71 = __toESM(require_jsx_runtime(), 1), CURSOR_KEY = "runtime.folders.cursor";
|
|
16838
17004
|
function FoldersTab({ width, height, focused }) {
|
|
16839
17005
|
let theme2 = useTheme(), store = useStore(), rev = useTuiSelector((s) => readFolders(s).rev), { data, error, loading, loadedAt, reload } = useDaemonData(`folders:${rev}`, () => loadFolders(store)), [cursor, setCursor] = useViewState(CURSOR_KEY, 0), rows = data ?? [], at = Math.min(cursor, Math.max(0, rows.length - 1));
|
|
16840
|
-
(0,
|
|
17006
|
+
(0, import_react59.useEffect)(() => {
|
|
16841
17007
|
at !== cursor && setCursor(at);
|
|
16842
17008
|
}, [at, cursor, setCursor]), useKeys((input, key) => {
|
|
16843
17009
|
if (key.ctrl || key.meta) return !1;
|
|
@@ -16895,7 +17061,7 @@ var import_jsx_runtime72 = __toESM(require_jsx_runtime(), 1);
|
|
|
16895
17061
|
function ReportTab({ kind, width, height, focused, onKey, hint }) {
|
|
16896
17062
|
let theme2 = useTheme(), store = useStore(), json2 = useStoreJson(), report2 = REPORTS[kind], { data, error, loading, loadedAt, reload } = useDaemonData(kind, (client) => report2.load(client, store.getState()));
|
|
16897
17063
|
useKeys((input, key) => key.ctrl || key.meta ? !1 : input === "r" ? (reload(), !0) : onKey?.(input, key, reload) ?? !1, { layer: "main", active: focused });
|
|
16898
|
-
let lines = (0,
|
|
17064
|
+
let lines = (0, import_react60.useMemo)(() => error ? [plain(`Could not load: ${error}`, "error"), plain("r retries.", "muted")] : data ? json2 ? jsonLines(data.data) : data.lines : [], [data, error, json2]);
|
|
16899
17065
|
return /* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(Box_default, { flexDirection: "column", width, height, children: [
|
|
16900
17066
|
/* @__PURE__ */ (0, import_jsx_runtime72.jsx)(LinesView, { lines, width, height: Math.max(1, height - 1), active: focused, emptyText: loading ? `Asking the daemon at ${store.getState().daemonUrl}\u2026` : "Nothing to show." }),
|
|
16901
17067
|
/* @__PURE__ */ (0, import_jsx_runtime72.jsxs)(Text, { color: theme2.color.dim, wrap: "truncate-end", children: [
|
|
@@ -16923,7 +17089,7 @@ function IdentityTab2({ width, height, focused }) {
|
|
|
16923
17089
|
let choice = choices.find((c) => c.key === input);
|
|
16924
17090
|
return choice ? (openIdentity(store, { mode: choice.mode }), !0) : !1;
|
|
16925
17091
|
}, { layer: "main", active: focused });
|
|
16926
|
-
let lines = (0,
|
|
17092
|
+
let lines = (0, import_react60.useMemo)(() => {
|
|
16927
17093
|
if (!identity) return [plain("This daemon does not report an owner identity (update the daemon).", "muted")];
|
|
16928
17094
|
let badge = identityBadge(identity), { title, next } = onboardingLines(identity), out = [heading(title)];
|
|
16929
17095
|
next && out.push(plain(` ${next}`, "warn")), badge && out.push([{ text: " " }, { text: badge.text, tone: badge.tone === "warn" ? "warn" : "muted" }]), out.push(blank(), ...treeLines(redactSecrets(identity), 2)), out.push(blank(), heading("Actions")), out.push(plain(" Enter identity dialog (status, backup, lock / unlock)", "accent"));
|
|
@@ -17039,9 +17205,9 @@ var VIEWS = [chat_default, files_default, loops_default, inspect_default, fleet_
|
|
|
17039
17205
|
// src/main/tui/app/App.tsx
|
|
17040
17206
|
var import_jsx_runtime73 = __toESM(require_jsx_runtime(), 1);
|
|
17041
17207
|
function App({ store, theme: theme2, views = VIEWS, builtins = [BUILTIN_COMMANDS], onExit, reserveRows = 0, reserveColumns = 0 }) {
|
|
17042
|
-
let app = use_app_default(), router = (0,
|
|
17208
|
+
let app = use_app_default(), router = (0, import_react61.useMemo)(() => createKeyRouter(), []), registry = (0, import_react61.useMemo)(() => collectCommands(views, builtins), [views, builtins]), exit = (0, import_react61.useCallback)(() => {
|
|
17043
17209
|
onExit?.(), app.exit();
|
|
17044
|
-
}, [app, onExit]), shell = (0,
|
|
17210
|
+
}, [app, onExit]), shell = (0, import_react61.useMemo)(() => ({ views, registry, exit, reserveRows, reserveColumns }), [views, registry, exit, reserveRows, reserveColumns]);
|
|
17045
17211
|
return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ThemeContext.Provider, { value: theme2, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(StoreProvider, { store, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(KeyRouterProvider, { router, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(ShellContext.Provider, { value: shell, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(Shell, {}) }) }) }) });
|
|
17046
17212
|
}
|
|
17047
17213
|
export {
|