@opencode-cockpit/shell 0.1.5 → 0.2.0
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 +100 -10
- package/dist/agent/plugin.js +180 -0
- package/dist/agent/tools/index.js +23 -0
- package/dist/agent/tools/list.js +68 -0
- package/dist/agent/tools/read.js +59 -0
- package/dist/agent/tools/restart.js +44 -0
- package/dist/agent/tools/send.js +71 -0
- package/dist/agent/tools/shared.js +94 -0
- package/dist/agent/tools/start.js +140 -0
- package/dist/agent/tools/stop.js +42 -0
- package/dist/agent/tools/wait.js +79 -0
- package/dist/agent/tools/watch-args.js +12 -0
- package/dist/agent/tools/watch.js +74 -0
- package/dist/core/config.js +97 -0
- package/dist/{tools → core}/find.js +3 -0
- package/dist/core/kind.js +31 -0
- package/dist/server.js +2 -152
- package/dist/tui/{badge.js → components/badge.js} +1 -1
- package/dist/tui/{console.js → components/console.js} +270 -139
- package/dist/tui/{dock.js → components/dock.js} +75 -19
- package/dist/tui/{sidebar.js → components/sidebar.js} +16 -1
- package/dist/tui/dialogs.js +163 -0
- package/dist/tui/index.js +35 -94
- package/dist/tui/lib/details.js +23 -0
- package/dist/tui/lib/search.js +39 -0
- package/dist/tui/lib/update.js +58 -0
- package/dist/tui/{view.js → lib/view.js} +38 -1
- package/dist/tui/{store.js → state/store.js} +4 -2
- package/package.json +4 -5
- package/types/agent/plugin.d.ts +12 -0
- package/types/agent/tools/index.d.ts +5 -0
- package/types/agent/tools/list.d.ts +3 -0
- package/types/agent/tools/read.d.ts +3 -0
- package/types/agent/tools/restart.d.ts +3 -0
- package/types/agent/tools/send.d.ts +3 -0
- package/types/agent/tools/shared.d.ts +40 -0
- package/types/agent/tools/start.d.ts +3 -0
- package/types/agent/tools/stop.d.ts +3 -0
- package/types/agent/tools/wait.d.ts +3 -0
- package/types/agent/tools/watch-args.d.ts +10 -0
- package/types/agent/tools/watch.d.ts +3 -0
- package/types/core/config.d.ts +59 -0
- package/types/{tools → core}/find.d.ts +5 -0
- package/types/core/kind.d.ts +9 -0
- package/types/server.d.ts +2 -12
- package/types/tui/{console.d.ts → components/console.d.ts} +7 -1
- package/types/tui/{dock.d.ts → components/dock.d.ts} +3 -1
- package/types/tui/{sidebar.d.ts → components/sidebar.d.ts} +1 -1
- package/types/tui/dialogs.d.ts +10 -0
- package/types/tui/index.d.ts +3 -9
- package/types/tui/lib/details.d.ts +3 -0
- package/types/tui/lib/search.d.ts +7 -0
- package/types/tui/lib/update.d.ts +25 -0
- package/types/tui/{view.d.ts → lib/view.d.ts} +14 -1
- package/types/tui/{store.d.ts → state/store.d.ts} +9 -0
- package/dist/tools/index.js +0 -433
- package/types/tools/index.d.ts +0 -17
- /package/dist/{tools → agent/tools}/keys.js +0 -0
- /package/dist/{tools → core}/format.js +0 -0
- /package/dist/tui/{keys.js → lib/keys.js} +0 -0
- /package/types/{tools → agent/tools}/keys.d.ts +0 -0
- /package/types/{tools → core}/format.d.ts +0 -0
- /package/types/tui/{badge.d.ts → components/badge.d.ts} +0 -0
- /package/types/tui/{keys.d.ts → lib/keys.d.ts} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { use as _$use } from "@opentui/solid";
|
|
2
1
|
import { memo as _$memo } from "@opentui/solid";
|
|
2
|
+
import { use as _$use } from "@opentui/solid";
|
|
3
3
|
import { effect as _$effect } from "@opentui/solid";
|
|
4
4
|
import { createTextNode as _$createTextNode } from "@opentui/solid";
|
|
5
5
|
import { insertNode as _$insertNode } from "@opentui/solid";
|
|
@@ -12,20 +12,17 @@ import { createElement as _$createElement } from "@opentui/solid";
|
|
|
12
12
|
import { useBindings } from "@opentui/keymap/solid";
|
|
13
13
|
import { useTerminalDimensions } from "@opentui/solid";
|
|
14
14
|
import { createEffect, createMemo, createSignal, For, on, onCleanup, Show } from "solid-js";
|
|
15
|
+
import { detailRows } from "../lib/details.js";
|
|
16
|
+
import { isReleaseKey, keyToBytes } from "../lib/keys.js";
|
|
17
|
+
import { friendlyError, splitMatches } from "../lib/search.js";
|
|
18
|
+
import { displayCommand, kindColor, kindOf, relativeCwd, statusDetail, tailLines, tailRuns, truncate, watchColor, watchLabel, wrapText } from "../lib/view.js";
|
|
19
|
+
import { useScreen } from "../state/store.js";
|
|
15
20
|
import { Badge } from "./badge.js";
|
|
16
|
-
import { isReleaseKey, keyToBytes } from "./keys.js";
|
|
17
|
-
import { useScreen } from "./store.js";
|
|
18
|
-
import { displayCommand, kindColor, kindOf, relativeCwd, statusDetail, tailLines, truncate, wrapText } from "./view.js";
|
|
19
21
|
/** Daemon errors name ids and internal states; say what happened instead. */
|
|
20
|
-
function friendlyError(err) {
|
|
21
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
22
|
-
if (/is (exited|killed|failed)$/.test(message)) return "the shell is no longer running";
|
|
23
|
-
if (/not found$/.test(message)) return "that shell was already removed";
|
|
24
|
-
if (/connection|not running|did not start/.test(message)) return "lost connection to cockpitd, retrying";
|
|
25
|
-
return message;
|
|
26
|
-
}
|
|
27
22
|
const COMMAND_LINES = 3;
|
|
28
23
|
|
|
24
|
+
/** Splits a line into plain and matching parts so a filtered log can highlight what matched. */
|
|
25
|
+
|
|
29
26
|
/**
|
|
30
27
|
* Keyboard-first shell console in an overlay. Normal mode: single-key actions. Typing mode:
|
|
31
28
|
* every key goes to the program (ctrl+c included); ctrl+] returns to normal mode.
|
|
@@ -34,10 +31,14 @@ export function Console(props) {
|
|
|
34
31
|
const theme = () => props.api.theme.current;
|
|
35
32
|
const dims = useTerminalDimensions();
|
|
36
33
|
const shell = () => props.store.selected();
|
|
37
|
-
const [view, setView] = createSignal("screen");
|
|
34
|
+
const [view, setView] = createSignal(props.defaultView ?? "screen");
|
|
38
35
|
const [typing, setTyping] = createSignal(props.typing ?? false);
|
|
39
36
|
const [log, setLog] = createSignal([]);
|
|
40
37
|
const [notice, setNotice] = createSignal();
|
|
38
|
+
/** Applied log filter, and the query being typed for it. */
|
|
39
|
+
const [filter, setFilter] = createSignal("");
|
|
40
|
+
const [searching, setSearching] = createSignal(false);
|
|
41
|
+
const [draft, setDraft] = createSignal("");
|
|
41
42
|
const {
|
|
42
43
|
screen
|
|
43
44
|
} = useScreen(props.store, () => shell()?.id);
|
|
@@ -96,14 +97,17 @@ export function Console(props) {
|
|
|
96
97
|
};
|
|
97
98
|
|
|
98
99
|
// Log view: reload on selection, view switch and new output.
|
|
99
|
-
createEffect(on([() => shell()?.id, view, () => screen()], () => {
|
|
100
|
+
createEffect(on([() => shell()?.id, view, filter, () => screen()], () => {
|
|
100
101
|
const id = shell()?.id;
|
|
101
102
|
if (!id || view() !== "log") return;
|
|
103
|
+
// The daemon greps server-side, so filtering a 40k-line log costs one call, not a transfer.
|
|
102
104
|
void client.call("shell.read", {
|
|
103
105
|
id,
|
|
104
106
|
tail: 2000,
|
|
105
|
-
limit: 2000
|
|
106
|
-
|
|
107
|
+
limit: 2000,
|
|
108
|
+
grep: filter() || undefined,
|
|
109
|
+
ignoreCase: true
|
|
110
|
+
}).then(page => setLog(page.lines)).catch(() => setLog([]));
|
|
107
111
|
}));
|
|
108
112
|
|
|
109
113
|
// Typing mode: size the PTY to what we show, then forward every key.
|
|
@@ -121,6 +125,24 @@ export function Console(props) {
|
|
|
121
125
|
if (typing() && !running()) setTyping(false);
|
|
122
126
|
});
|
|
123
127
|
const release = props.api.keymap.intercept("key", ctx => {
|
|
128
|
+
// Search takes keys first: a typed query must reach neither the program nor the dialog.
|
|
129
|
+
if (searching()) {
|
|
130
|
+
const event = ctx.event;
|
|
131
|
+
ctx.consume({
|
|
132
|
+
preventDefault: true,
|
|
133
|
+
stopPropagation: true
|
|
134
|
+
});
|
|
135
|
+
if (event.name === "escape") return setSearching(false);
|
|
136
|
+
if (event.name === "return" || event.name === "enter") {
|
|
137
|
+
setFilter(draft().trim());
|
|
138
|
+
return setSearching(false);
|
|
139
|
+
}
|
|
140
|
+
if (event.name === "backspace") return setDraft(value => value.slice(0, -1));
|
|
141
|
+
if (event.sequence && !event.ctrl && !event.meta && event.sequence >= " ") {
|
|
142
|
+
setDraft(value => value + event.sequence);
|
|
143
|
+
}
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
124
146
|
if (!typing()) return;
|
|
125
147
|
const event = ctx.event;
|
|
126
148
|
ctx.consume({
|
|
@@ -188,18 +210,35 @@ export function Console(props) {
|
|
|
188
210
|
}, {
|
|
189
211
|
name: "cockpit.console.clear",
|
|
190
212
|
title: "Clear finished shells",
|
|
191
|
-
run: () =>
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
213
|
+
run: () => {
|
|
214
|
+
if (finished() === 0) {
|
|
215
|
+
flash("nothing to clear: no finished shells", "info", 2500);
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
act("clear", async () => {
|
|
219
|
+
const n = await props.store.clearFinished();
|
|
220
|
+
return `cleared ${n} finished shell${n === 1 ? "" : "s"}`;
|
|
221
|
+
});
|
|
222
|
+
}
|
|
199
223
|
}, {
|
|
200
224
|
name: "cockpit.console.view",
|
|
201
225
|
title: "Toggle screen/log",
|
|
202
226
|
run: () => setView(v => v === "log" ? "screen" : "log")
|
|
227
|
+
}, {
|
|
228
|
+
name: "cockpit.console.search",
|
|
229
|
+
title: "Search this shell's log",
|
|
230
|
+
run: () => {
|
|
231
|
+
setView("log");
|
|
232
|
+
setDraft(filter());
|
|
233
|
+
setSearching(true);
|
|
234
|
+
}
|
|
235
|
+
}, {
|
|
236
|
+
name: "cockpit.console.searchClear",
|
|
237
|
+
title: "Clear the log filter",
|
|
238
|
+
run: () => {
|
|
239
|
+
setFilter("");
|
|
240
|
+
setDraft("");
|
|
241
|
+
}
|
|
203
242
|
}, {
|
|
204
243
|
name: "cockpit.console.details",
|
|
205
244
|
title: "Toggle details",
|
|
@@ -261,14 +300,18 @@ export function Console(props) {
|
|
|
261
300
|
key: "shift+d",
|
|
262
301
|
cmd: "cockpit.console.clear",
|
|
263
302
|
desc: "Clear finished"
|
|
264
|
-
}, {
|
|
265
|
-
key: "a",
|
|
266
|
-
cmd: "cockpit.console.all",
|
|
267
|
-
desc: "All"
|
|
268
303
|
}, {
|
|
269
304
|
key: "tab",
|
|
270
305
|
cmd: "cockpit.console.view",
|
|
271
306
|
desc: "Screen/log"
|
|
307
|
+
}, {
|
|
308
|
+
key: "/",
|
|
309
|
+
cmd: "cockpit.console.search",
|
|
310
|
+
desc: "Search log"
|
|
311
|
+
}, {
|
|
312
|
+
key: "backspace",
|
|
313
|
+
cmd: "cockpit.console.searchClear",
|
|
314
|
+
desc: "Clear filter"
|
|
272
315
|
}, {
|
|
273
316
|
key: "?,shift+/",
|
|
274
317
|
cmd: "cockpit.console.details",
|
|
@@ -308,26 +351,38 @@ export function Console(props) {
|
|
|
308
351
|
}]
|
|
309
352
|
}));
|
|
310
353
|
const screenText = createMemo(() => tailLines(screen()?.text, bodyRows(), bodyCols()));
|
|
354
|
+
// Colour when the daemon sent styled rows; the plain text stays the fallback.
|
|
355
|
+
const screenRuns = createMemo(() => props.colors === false ? [] : tailRuns(screen()?.styled, bodyRows(), bodyCols()));
|
|
311
356
|
const details = createMemo(() => shell() ? detailRows(shell(), props.store.now(), bodyCols()) : []);
|
|
312
357
|
const bodyHeight = createMemo(() => {
|
|
313
358
|
if (typing()) return bodyRows();
|
|
314
359
|
const content = view() === "log" ? log().length : view() === "details" ? details().length : screenText().split("\n").length;
|
|
315
360
|
return Math.min(bodyRows(), Math.max(6, content));
|
|
316
361
|
});
|
|
362
|
+
const finished = createMemo(() => props.store.shells().filter(s => s.status !== "running").length);
|
|
317
363
|
const position = createMemo(() => {
|
|
318
|
-
const list = props.store.
|
|
364
|
+
const list = props.store.shells();
|
|
319
365
|
const index = list.findIndex(x => x.id === shell()?.id);
|
|
320
|
-
|
|
321
|
-
return list.length > 1 || hidden > 0 ? `${index + 1}/${list.length}${hidden ? ` +${hidden}` : ""}` : "";
|
|
366
|
+
return list.length > 1 ? `${index + 1}/${list.length}` : "";
|
|
322
367
|
});
|
|
323
368
|
// Only the keys that do something for the selected shell.
|
|
369
|
+
/** Only the keys that do something right now: no sidebar concepts, no actions with no target. */
|
|
324
370
|
const hint = createMemo(() => {
|
|
371
|
+
if (searching()) return `search: ${draft()}▏· enter filters · esc cancels`;
|
|
325
372
|
if (typing()) return "TYPING: keys go to the shell (ctrl+c included) · ctrl+] stop typing";
|
|
326
|
-
const next = view() === "log" ? "screen" : "log";
|
|
327
373
|
const wide = dims().width >= 110;
|
|
328
|
-
const
|
|
329
|
-
const
|
|
330
|
-
|
|
374
|
+
const label = (long, short) => wide ? long : short;
|
|
375
|
+
const keys = [];
|
|
376
|
+
if (!shell()) return ["n new", "esc close"].join(" · ");
|
|
377
|
+
keys.push(...(running() ? [label("i type", "i"), label("c ^C", "c"), label("r restart", "r"), label("x stop", "x")] : [label("r run again", "r"), label("d remove", "d")]));
|
|
378
|
+
if (view() === "log" && filter()) keys.push(label("backspace clear filter", "⌫ filter"));
|
|
379
|
+
keys.push(label(`tab ${view() === "log" ? "screen" : "log"}`, "tab"));
|
|
380
|
+
if (view() !== "details") keys.push(label("/ search log", "/"));
|
|
381
|
+
keys.push(label("? details", "?"));
|
|
382
|
+
if (props.store.shells().length > 1) keys.push(label("[ ] switch", "[ ]"));
|
|
383
|
+
if (finished() > 0) keys.push(label("D clear done", "D"));
|
|
384
|
+
keys.push(label("n new", "n"), "esc");
|
|
385
|
+
return keys.join(" · ");
|
|
331
386
|
});
|
|
332
387
|
return (() => {
|
|
333
388
|
var _el$ = _$createElement("box"),
|
|
@@ -375,10 +430,10 @@ export function Console(props) {
|
|
|
375
430
|
_el$0 = _$createTextNode(` `),
|
|
376
431
|
_el$1 = _$createElement("b"),
|
|
377
432
|
_el$10 = _$createElement("box"),
|
|
378
|
-
_el$
|
|
433
|
+
_el$14 = _$createElement("text");
|
|
379
434
|
_$insertNode(_el$8, _el$9);
|
|
380
435
|
_$insertNode(_el$8, _el$10);
|
|
381
|
-
_$insertNode(_el$8, _el$
|
|
436
|
+
_$insertNode(_el$8, _el$14);
|
|
382
437
|
_$setProp(_el$8, "height", 1);
|
|
383
438
|
_$setProp(_el$8, "flexShrink", 0);
|
|
384
439
|
_$setProp(_el$8, "flexDirection", "row");
|
|
@@ -400,14 +455,31 @@ export function Console(props) {
|
|
|
400
455
|
_$setProp(_el$9, "flexShrink", 1);
|
|
401
456
|
_$insert(_el$1, () => truncate(s().title, Math.max(10, bodyCols() - 50)));
|
|
402
457
|
_$setProp(_el$10, "flexGrow", 1);
|
|
403
|
-
_$
|
|
404
|
-
|
|
405
|
-
|
|
458
|
+
_$insert(_el$8, _$createComponent(Show, {
|
|
459
|
+
get when() {
|
|
460
|
+
return watchLabel(s());
|
|
461
|
+
},
|
|
462
|
+
get children() {
|
|
463
|
+
var _el$11 = _$createElement("text"),
|
|
464
|
+
_el$12 = _$createTextNode(` `),
|
|
465
|
+
_el$13 = _$createTextNode(` `);
|
|
466
|
+
_$insertNode(_el$11, _el$12);
|
|
467
|
+
_$insertNode(_el$11, _el$13);
|
|
468
|
+
_$setProp(_el$11, "wrapMode", "none");
|
|
469
|
+
_$setProp(_el$11, "flexShrink", 0);
|
|
470
|
+
_$insert(_el$11, () => watchLabel(s()), _el$13);
|
|
471
|
+
_$effect(_$p => _$setProp(_el$11, "fg", watchColor(theme(), s()), _$p));
|
|
472
|
+
return _el$11;
|
|
473
|
+
}
|
|
474
|
+
}), _el$14);
|
|
475
|
+
_$setProp(_el$14, "wrapMode", "none");
|
|
476
|
+
_$setProp(_el$14, "flexShrink", 0);
|
|
477
|
+
_$insert(_el$14, () => [statusDetail(s(), props.store.now()), s().run > 1 ? `run ${s().run}` : "", position()].filter(Boolean).join(" · "));
|
|
406
478
|
_$effect(_p$ => {
|
|
407
479
|
var _v$3 = theme().text,
|
|
408
480
|
_v$4 = theme().textMuted;
|
|
409
481
|
_v$3 !== _p$.e && (_p$.e = _$setProp(_el$9, "fg", _v$3, _p$.e));
|
|
410
|
-
_v$4 !== _p$.t && (_p$.t = _$setProp(_el$
|
|
482
|
+
_v$4 !== _p$.t && (_p$.t = _$setProp(_el$14, "fg", _v$4, _p$.t));
|
|
411
483
|
return _p$;
|
|
412
484
|
}, {
|
|
413
485
|
e: undefined,
|
|
@@ -419,167 +491,240 @@ export function Console(props) {
|
|
|
419
491
|
return commandLines();
|
|
420
492
|
},
|
|
421
493
|
children: (line, index) => (() => {
|
|
422
|
-
var _el$
|
|
423
|
-
_el$
|
|
424
|
-
_$insertNode(_el$
|
|
425
|
-
_$setProp(_el$
|
|
426
|
-
_$setProp(_el$
|
|
427
|
-
_$insert(_el$
|
|
428
|
-
_$insert(_el$
|
|
494
|
+
var _el$23 = _$createElement("text"),
|
|
495
|
+
_el$24 = _$createElement("span");
|
|
496
|
+
_$insertNode(_el$23, _el$24);
|
|
497
|
+
_$setProp(_el$23, "wrapMode", "none");
|
|
498
|
+
_$setProp(_el$23, "flexShrink", 0);
|
|
499
|
+
_$insert(_el$24, () => index() === 0 ? "$ " : " ");
|
|
500
|
+
_$insert(_el$23, line, null);
|
|
429
501
|
_$effect(_p$ => {
|
|
430
502
|
var _v$7 = theme().text,
|
|
431
503
|
_v$8 = {
|
|
432
504
|
fg: theme().textMuted
|
|
433
505
|
};
|
|
434
|
-
_v$7 !== _p$.e && (_p$.e = _$setProp(_el$
|
|
435
|
-
_v$8 !== _p$.t && (_p$.t = _$setProp(_el$
|
|
506
|
+
_v$7 !== _p$.e && (_p$.e = _$setProp(_el$23, "fg", _v$7, _p$.e));
|
|
507
|
+
_v$8 !== _p$.t && (_p$.t = _$setProp(_el$24, "style", _v$8, _p$.t));
|
|
436
508
|
return _p$;
|
|
437
509
|
}, {
|
|
438
510
|
e: undefined,
|
|
439
511
|
t: undefined
|
|
440
512
|
});
|
|
441
|
-
return _el$
|
|
513
|
+
return _el$23;
|
|
442
514
|
})()
|
|
443
515
|
}), _$createComponent(Show, {
|
|
444
516
|
get when() {
|
|
445
517
|
return folder();
|
|
446
518
|
},
|
|
447
519
|
get children() {
|
|
448
|
-
var _el$
|
|
449
|
-
_$setProp(_el$
|
|
450
|
-
_$setProp(_el$
|
|
451
|
-
_$insert(_el$
|
|
452
|
-
_$effect(_$p => _$setProp(_el$
|
|
453
|
-
return _el$
|
|
520
|
+
var _el$15 = _$createElement("text");
|
|
521
|
+
_$setProp(_el$15, "wrapMode", "none");
|
|
522
|
+
_$setProp(_el$15, "flexShrink", 0);
|
|
523
|
+
_$insert(_el$15, () => truncate(`in ${folder()}`, bodyCols()));
|
|
524
|
+
_$effect(_$p => _$setProp(_el$15, "fg", theme().textMuted, _$p));
|
|
525
|
+
return _el$15;
|
|
454
526
|
}
|
|
455
527
|
}), _$createComponent(Show, {
|
|
456
528
|
get when() {
|
|
457
529
|
return failure();
|
|
458
530
|
},
|
|
459
531
|
children: summary => (() => {
|
|
460
|
-
var _el$
|
|
461
|
-
_$setProp(_el$
|
|
462
|
-
_$setProp(_el$
|
|
463
|
-
_$insert(_el$
|
|
464
|
-
_$effect(_$p => _$setProp(_el$
|
|
465
|
-
return _el$
|
|
532
|
+
var _el$25 = _$createElement("text");
|
|
533
|
+
_$setProp(_el$25, "wrapMode", "none");
|
|
534
|
+
_$setProp(_el$25, "flexShrink", 0);
|
|
535
|
+
_$insert(_el$25, () => truncate(`${kindOf(s()) === "fail" ? "error" : "last output"}: ${summary()}`, bodyCols()));
|
|
536
|
+
_$effect(_$p => _$setProp(_el$25, "fg", kindColor(theme(), kindOf(s())), _$p));
|
|
537
|
+
return _el$25;
|
|
466
538
|
})()
|
|
467
539
|
}), (() => {
|
|
468
|
-
var _el$
|
|
469
|
-
_$setProp(_el$
|
|
470
|
-
_$setProp(_el$
|
|
471
|
-
_$setProp(_el$
|
|
472
|
-
_$setProp(_el$
|
|
473
|
-
_$setProp(_el$
|
|
474
|
-
_$setProp(_el$
|
|
475
|
-
_$insert(_el$
|
|
540
|
+
var _el$16 = _$createElement("box");
|
|
541
|
+
_$setProp(_el$16, "flexShrink", 0);
|
|
542
|
+
_$setProp(_el$16, "marginTop", 1);
|
|
543
|
+
_$setProp(_el$16, "marginBottom", 1);
|
|
544
|
+
_$setProp(_el$16, "border", ["left"]);
|
|
545
|
+
_$setProp(_el$16, "paddingLeft", 1);
|
|
546
|
+
_$setProp(_el$16, "overflow", "hidden");
|
|
547
|
+
_$insert(_el$16, _$createComponent(Show, {
|
|
476
548
|
get when() {
|
|
477
549
|
return view() === "screen";
|
|
478
550
|
},
|
|
479
551
|
get children() {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
552
|
+
return _$createComponent(Show, {
|
|
553
|
+
get when() {
|
|
554
|
+
return screenRuns().length > 0;
|
|
555
|
+
},
|
|
556
|
+
get fallback() {
|
|
557
|
+
return (() => {
|
|
558
|
+
var _el$26 = _$createElement("text");
|
|
559
|
+
_$setProp(_el$26, "wrapMode", "none");
|
|
560
|
+
_$insert(_el$26, () => screenText() || " ");
|
|
561
|
+
_$effect(_$p => _$setProp(_el$26, "fg", theme().text, _$p));
|
|
562
|
+
return _el$26;
|
|
563
|
+
})();
|
|
564
|
+
},
|
|
565
|
+
get children() {
|
|
566
|
+
var _el$17 = _$createElement("box");
|
|
567
|
+
_$setProp(_el$17, "flexDirection", "column");
|
|
568
|
+
_$insert(_el$17, _$createComponent(For, {
|
|
569
|
+
get each() {
|
|
570
|
+
return screenRuns();
|
|
571
|
+
},
|
|
572
|
+
children: row => (() => {
|
|
573
|
+
var _el$27 = _$createElement("text"),
|
|
574
|
+
_el$28 = _$createTextNode(` `);
|
|
575
|
+
_$insertNode(_el$27, _el$28);
|
|
576
|
+
_$setProp(_el$27, "wrapMode", "none");
|
|
577
|
+
_$insert(_el$27, _$createComponent(For, {
|
|
578
|
+
each: row,
|
|
579
|
+
children: run => (() => {
|
|
580
|
+
var _el$29 = _$createElement("span");
|
|
581
|
+
_$insert(_el$29, () => run.text);
|
|
582
|
+
_$effect(_$p => _$setProp(_el$29, "style", {
|
|
583
|
+
fg: run.fg,
|
|
584
|
+
bg: run.bg,
|
|
585
|
+
bold: run.bold,
|
|
586
|
+
italic: run.italic
|
|
587
|
+
}, _$p));
|
|
588
|
+
return _el$29;
|
|
589
|
+
})()
|
|
590
|
+
}), _el$28);
|
|
591
|
+
_$effect(_$p => _$setProp(_el$27, "fg", theme().text, _$p));
|
|
592
|
+
return _el$27;
|
|
593
|
+
})()
|
|
594
|
+
}));
|
|
595
|
+
return _el$17;
|
|
596
|
+
}
|
|
597
|
+
});
|
|
485
598
|
}
|
|
486
599
|
}), null);
|
|
487
|
-
_$insert(_el$
|
|
600
|
+
_$insert(_el$16, _$createComponent(Show, {
|
|
488
601
|
get when() {
|
|
489
602
|
return view() === "details";
|
|
490
603
|
},
|
|
491
604
|
get children() {
|
|
492
|
-
var _el$
|
|
493
|
-
_$setProp(_el$
|
|
494
|
-
_$insert(_el$
|
|
605
|
+
var _el$18 = _$createElement("box");
|
|
606
|
+
_$setProp(_el$18, "flexDirection", "column");
|
|
607
|
+
_$insert(_el$18, _$createComponent(For, {
|
|
495
608
|
get each() {
|
|
496
609
|
return details();
|
|
497
610
|
},
|
|
498
611
|
children: ([key, value]) => (() => {
|
|
499
|
-
var _el$
|
|
500
|
-
_el$
|
|
501
|
-
_$insertNode(_el$
|
|
502
|
-
_$setProp(_el$
|
|
503
|
-
_$insert(_el$
|
|
504
|
-
_$insert(_el$
|
|
612
|
+
var _el$30 = _$createElement("text"),
|
|
613
|
+
_el$31 = _$createElement("span");
|
|
614
|
+
_$insertNode(_el$30, _el$31);
|
|
615
|
+
_$setProp(_el$30, "wrapMode", "none");
|
|
616
|
+
_$insert(_el$31, () => key.padEnd(10));
|
|
617
|
+
_$insert(_el$30, value, null);
|
|
505
618
|
_$effect(_p$ => {
|
|
506
619
|
var _v$9 = theme().text,
|
|
507
620
|
_v$0 = {
|
|
508
621
|
fg: theme().textMuted
|
|
509
622
|
};
|
|
510
|
-
_v$9 !== _p$.e && (_p$.e = _$setProp(_el$
|
|
511
|
-
_v$0 !== _p$.t && (_p$.t = _$setProp(_el$
|
|
623
|
+
_v$9 !== _p$.e && (_p$.e = _$setProp(_el$30, "fg", _v$9, _p$.e));
|
|
624
|
+
_v$0 !== _p$.t && (_p$.t = _$setProp(_el$31, "style", _v$0, _p$.t));
|
|
512
625
|
return _p$;
|
|
513
626
|
}, {
|
|
514
627
|
e: undefined,
|
|
515
628
|
t: undefined
|
|
516
629
|
});
|
|
517
|
-
return _el$
|
|
630
|
+
return _el$30;
|
|
518
631
|
})()
|
|
519
632
|
}));
|
|
520
|
-
return _el$
|
|
633
|
+
return _el$18;
|
|
521
634
|
}
|
|
522
635
|
}), null);
|
|
523
|
-
_$insert(_el$
|
|
636
|
+
_$insert(_el$16, _$createComponent(Show, {
|
|
524
637
|
get when() {
|
|
525
638
|
return view() === "log";
|
|
526
639
|
},
|
|
527
640
|
get children() {
|
|
528
|
-
var _el$
|
|
641
|
+
var _el$19 = _$createElement("scrollbox");
|
|
529
642
|
_$use(el => {
|
|
530
643
|
scroll = el;
|
|
531
|
-
}, _el$
|
|
532
|
-
_$setProp(_el$
|
|
533
|
-
_$setProp(_el$
|
|
534
|
-
_$setProp(_el$
|
|
535
|
-
_$setProp(_el$
|
|
644
|
+
}, _el$19);
|
|
645
|
+
_$setProp(_el$19, "flexGrow", 1);
|
|
646
|
+
_$setProp(_el$19, "stickyScroll", true);
|
|
647
|
+
_$setProp(_el$19, "stickyStart", "bottom");
|
|
648
|
+
_$setProp(_el$19, "verticalScrollbarOptions", {
|
|
536
649
|
visible: false
|
|
537
650
|
});
|
|
538
|
-
_$setProp(_el$
|
|
651
|
+
_$setProp(_el$19, "horizontalScrollbarOptions", {
|
|
539
652
|
visible: false
|
|
540
653
|
});
|
|
541
|
-
_$insert(_el$
|
|
654
|
+
_$insert(_el$19, _$createComponent(For, {
|
|
542
655
|
get each() {
|
|
543
656
|
return log();
|
|
544
657
|
},
|
|
545
658
|
children: line => (() => {
|
|
546
|
-
var _el$
|
|
547
|
-
_el$
|
|
548
|
-
_el$
|
|
549
|
-
_$insertNode(_el$
|
|
550
|
-
_$setProp(_el$
|
|
551
|
-
_$insertNode(_el$
|
|
552
|
-
_$insert(_el$
|
|
553
|
-
_$insert(_el$
|
|
659
|
+
var _el$32 = _$createElement("text"),
|
|
660
|
+
_el$33 = _$createElement("span"),
|
|
661
|
+
_el$34 = _$createTextNode(` `);
|
|
662
|
+
_$insertNode(_el$32, _el$33);
|
|
663
|
+
_$setProp(_el$32, "wrapMode", "none");
|
|
664
|
+
_$insertNode(_el$33, _el$34);
|
|
665
|
+
_$insert(_el$33, () => String(line.n).padStart(5), _el$34);
|
|
666
|
+
_$insert(_el$32, _$createComponent(For, {
|
|
667
|
+
get each() {
|
|
668
|
+
return splitMatches(truncate(line.text, bodyCols() - 7), filter());
|
|
669
|
+
},
|
|
670
|
+
children: part => part.match ? (() => {
|
|
671
|
+
var _el$35 = _$createElement("span");
|
|
672
|
+
_$insert(_el$35, () => part.text);
|
|
673
|
+
_$effect(_$p => _$setProp(_el$35, "style", {
|
|
674
|
+
fg: theme().background,
|
|
675
|
+
bg: theme().warning
|
|
676
|
+
}, _$p));
|
|
677
|
+
return _el$35;
|
|
678
|
+
})() : (() => {
|
|
679
|
+
var _el$36 = _$createElement("span");
|
|
680
|
+
_$insert(_el$36, () => part.text);
|
|
681
|
+
return _el$36;
|
|
682
|
+
})()
|
|
683
|
+
}), null);
|
|
554
684
|
_$effect(_p$ => {
|
|
555
685
|
var _v$1 = theme().text,
|
|
556
686
|
_v$10 = {
|
|
557
687
|
fg: theme().textMuted
|
|
558
688
|
};
|
|
559
|
-
_v$1 !== _p$.e && (_p$.e = _$setProp(_el$
|
|
560
|
-
_v$10 !== _p$.t && (_p$.t = _$setProp(_el$
|
|
689
|
+
_v$1 !== _p$.e && (_p$.e = _$setProp(_el$32, "fg", _v$1, _p$.e));
|
|
690
|
+
_v$10 !== _p$.t && (_p$.t = _$setProp(_el$33, "style", _v$10, _p$.t));
|
|
561
691
|
return _p$;
|
|
562
692
|
}, {
|
|
563
693
|
e: undefined,
|
|
564
694
|
t: undefined
|
|
565
695
|
});
|
|
566
|
-
return _el$
|
|
696
|
+
return _el$32;
|
|
567
697
|
})()
|
|
568
|
-
}));
|
|
569
|
-
|
|
698
|
+
}), null);
|
|
699
|
+
_$insert(_el$19, _$createComponent(Show, {
|
|
700
|
+
get when() {
|
|
701
|
+
return _$memo(() => !!filter())() && log().length === 0;
|
|
702
|
+
},
|
|
703
|
+
get children() {
|
|
704
|
+
var _el$20 = _$createElement("text"),
|
|
705
|
+
_el$21 = _$createTextNode(`no lines match "`),
|
|
706
|
+
_el$22 = _$createTextNode(`"`);
|
|
707
|
+
_$insertNode(_el$20, _el$21);
|
|
708
|
+
_$insertNode(_el$20, _el$22);
|
|
709
|
+
_$insert(_el$20, filter, _el$22);
|
|
710
|
+
_$effect(_$p => _$setProp(_el$20, "fg", theme().textMuted, _$p));
|
|
711
|
+
return _el$20;
|
|
712
|
+
}
|
|
713
|
+
}), null);
|
|
714
|
+
return _el$19;
|
|
570
715
|
}
|
|
571
716
|
}), null);
|
|
572
717
|
_$effect(_p$ => {
|
|
573
718
|
var _v$5 = bodyHeight(),
|
|
574
719
|
_v$6 = typing() ? theme().accent : theme().border;
|
|
575
|
-
_v$5 !== _p$.e && (_p$.e = _$setProp(_el$
|
|
576
|
-
_v$6 !== _p$.t && (_p$.t = _$setProp(_el$
|
|
720
|
+
_v$5 !== _p$.e && (_p$.e = _$setProp(_el$16, "height", _v$5, _p$.e));
|
|
721
|
+
_v$6 !== _p$.t && (_p$.t = _$setProp(_el$16, "borderColor", _v$6, _p$.t));
|
|
577
722
|
return _p$;
|
|
578
723
|
}, {
|
|
579
724
|
e: undefined,
|
|
580
725
|
t: undefined
|
|
581
726
|
});
|
|
582
|
-
return _el$
|
|
727
|
+
return _el$16;
|
|
583
728
|
})()]
|
|
584
729
|
}), _el$2);
|
|
585
730
|
_$setProp(_el$2, "height", 1);
|
|
@@ -592,37 +737,23 @@ export function Console(props) {
|
|
|
592
737
|
},
|
|
593
738
|
get fallback() {
|
|
594
739
|
return (() => {
|
|
595
|
-
var _el$
|
|
596
|
-
_$setProp(_el$
|
|
597
|
-
_$insert(_el$
|
|
598
|
-
_$effect(_$p => _$setProp(_el$
|
|
599
|
-
return _el$
|
|
740
|
+
var _el$37 = _$createElement("text");
|
|
741
|
+
_$setProp(_el$37, "wrapMode", "none");
|
|
742
|
+
_$insert(_el$37, () => truncate(hint(), bodyCols()));
|
|
743
|
+
_$effect(_$p => _$setProp(_el$37, "fg", typing() ? theme().accent : theme().textMuted, _$p));
|
|
744
|
+
return _el$37;
|
|
600
745
|
})();
|
|
601
746
|
},
|
|
602
747
|
children: n => (() => {
|
|
603
|
-
var _el$
|
|
604
|
-
_$setProp(_el$
|
|
605
|
-
_$insert(_el$
|
|
606
|
-
_$effect(_$p => _$setProp(_el$
|
|
607
|
-
return _el$
|
|
748
|
+
var _el$38 = _$createElement("text");
|
|
749
|
+
_$setProp(_el$38, "wrapMode", "none");
|
|
750
|
+
_$insert(_el$38, () => truncate(n().text, bodyCols()));
|
|
751
|
+
_$effect(_$p => _$setProp(_el$38, "fg", n().tone === "error" ? theme().error : n().tone === "success" ? theme().success : theme().warning, _$p));
|
|
752
|
+
return _el$38;
|
|
608
753
|
})()
|
|
609
754
|
}));
|
|
610
755
|
return _el$;
|
|
611
756
|
})();
|
|
612
757
|
}
|
|
613
758
|
|
|
614
|
-
/** Everything about a shell, with the full command wrapped rather than cut. */
|
|
615
|
-
function detailRows(s, now, cols) {
|
|
616
|
-
const width = Math.max(10, cols - 11);
|
|
617
|
-
const rows = [];
|
|
618
|
-
for (const [i, line] of wrapText(displayCommand(s), width, 12).entries()) rows.push([i === 0 ? "command" : "", line]);
|
|
619
|
-
rows.push(["folder", s.cwd]);
|
|
620
|
-
rows.push(["status", `${s.status}${s.exitCode !== undefined ? ` (exit ${s.exitCode})` : ""}${s.signal ? ` (${s.signal})` : ""}`]);
|
|
621
|
-
rows.push(["timing", statusDetail(s, now)]);
|
|
622
|
-
rows.push(["started", new Date(s.startedAt).toLocaleString()]);
|
|
623
|
-
if (s.summary) rows.push(["summary", truncate(s.summary, width)]);
|
|
624
|
-
rows.push(["id", `${s.id} · run ${s.run}${s.pid ? ` · pid ${s.pid}` : ""}`]);
|
|
625
|
-
rows.push(["owner", s.owner.session ? `agent session ${s.owner.session}` : "you"]);
|
|
626
|
-
rows.push(["output", `${s.lines.last} lines · ${Math.round(s.bytes / 1024)} KiB`]);
|
|
627
|
-
return rows;
|
|
628
|
-
}
|
|
759
|
+
/** Everything about a shell, with the full command wrapped rather than cut. */
|