@gjermundgaraba/upup 0.2.0 → 0.3.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 +42 -32
- package/dist/{Tui-PjGIvm7J.mjs → Tui-BiTtZ1EF.mjs} +1898 -1668
- package/dist/grep-worker.mjs +204 -0
- package/dist/io-BGJ4Yp7u.mjs +19 -0
- package/dist/main.mjs +10948 -10278
- package/native/dist/upup-sparkle.json +5 -0
- package/native/dist/upup-sparkle.zip +0 -0
- package/package.json +12 -3
|
@@ -1,10 +1,46 @@
|
|
|
1
|
-
import { a as describeOutcome, c as describeError, d as
|
|
1
|
+
import { a as describeOutcome, c as describeError, d as unauditedKind, i as questionOf, l as isUnauditedUpdate, n as aboutKey, o as changedLines, r as auditKey, s as unauditable, t as Session, u as rowKey } from "./main.mjs";
|
|
2
2
|
import { Deferred, Effect, FiberSet, Stream } from "effect";
|
|
3
3
|
import { spawn } from "node:child_process";
|
|
4
4
|
import { homedir } from "node:os";
|
|
5
|
+
import semver from "semver";
|
|
5
6
|
import { createComponent, createElement, createTextNode, effect, insert, insertNode, memo, render, setProp, use, useKeyboard, usePaste, useTerminalDimensions } from "@opentui/solid";
|
|
6
7
|
import { TextAttributes, createCliRenderer } from "@opentui/core";
|
|
7
8
|
import { For, Match, Show, Switch, createEffect, createMemo, createRenderEffect, createSignal, on, onCleanup, untrack } from "solid-js/dist/solid.js";
|
|
9
|
+
// src/tui/text.ts
|
|
10
|
+
const segmenter = new Intl.Segmenter();
|
|
11
|
+
const graphemes = (text) => Array.from(segmenter.segment(text), ({ segment }) => segment);
|
|
12
|
+
const padded = (text, width, align = "start") => {
|
|
13
|
+
const room = " ".repeat(Math.max(0, width - graphemes(text).length));
|
|
14
|
+
return align === "end" ? `${room}${text}` : `${text}${room}`;
|
|
15
|
+
};
|
|
16
|
+
const cut = (chars, width) => {
|
|
17
|
+
if (chars.length <= width) return chars.join("");
|
|
18
|
+
if (width <= 0) return "";
|
|
19
|
+
return `${chars.slice(0, width - 1).join("")}…`;
|
|
20
|
+
};
|
|
21
|
+
const fit = (text, width, align = "start") => {
|
|
22
|
+
const shown = cut(graphemes(text.replaceAll(/\s+/gu, " ")), width);
|
|
23
|
+
return padded(shown, width, align);
|
|
24
|
+
};
|
|
25
|
+
const clip = (text, width) => graphemes(text).length <= width ? text : cut(graphemes(text.trimEnd()), width);
|
|
26
|
+
const fitName = (text, width) => {
|
|
27
|
+
const chars = graphemes(text);
|
|
28
|
+
if (chars.length <= width) return padded(text, width);
|
|
29
|
+
if (width <= 3) return fit(text, width);
|
|
30
|
+
const slash = chars.indexOf("/");
|
|
31
|
+
const base = chars.slice(slash + 1);
|
|
32
|
+
const scope = chars.slice(0, slash);
|
|
33
|
+
if (text.startsWith("@") && slash > 0 && base.length + 4 <= width) {
|
|
34
|
+
const keep = Math.min(scope.length, width - base.length - 2);
|
|
35
|
+
return padded(`${scope.slice(0, keep).join("")}…/${base.join("")}`, width);
|
|
36
|
+
}
|
|
37
|
+
const head = Math.ceil((width - 1) / 2);
|
|
38
|
+
const tail = width - 1 - head;
|
|
39
|
+
return `${chars.slice(0, head).join("")}…${chars.slice(chars.length - tail).join("")}`;
|
|
40
|
+
};
|
|
41
|
+
const plural = (count, noun) => `${count} ${noun}${count === 1 ? "" : "s"}`;
|
|
42
|
+
const capitalized = (text) => `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
43
|
+
const listed = (names) => names.length <= 3 ? names.join(", ") : `${names.slice(0, 3).join(", ")} and ${names.length - 3} more`;
|
|
8
44
|
// src/tui/keys.ts
|
|
9
45
|
const keys = {
|
|
10
46
|
up: {
|
|
@@ -261,7 +297,7 @@ const describe = (key) => {
|
|
|
261
297
|
return `${key.ctrl ? "ctrl+" : ""}${key.meta ? "meta+" : ""}${key.shift && !single ? "shift+" : ""}${name}`;
|
|
262
298
|
};
|
|
263
299
|
const matches = (binding, key) => binding.keys.includes(describe(key));
|
|
264
|
-
const typed = (key) => !key.ctrl && !key.meta &&
|
|
300
|
+
const typed = (key) => !key.ctrl && !key.meta && graphemes(key.sequence).length === 1 && key.sequence >= " " ? key.sequence : void 0;
|
|
265
301
|
const pasted = (bytes) => new TextDecoder().decode(bytes).replaceAll(/[\r\n]+/gu, "");
|
|
266
302
|
// src/tui/theme.ts
|
|
267
303
|
const dark = {
|
|
@@ -270,13 +306,12 @@ const dark = {
|
|
|
270
306
|
accent: "#8aa9ff",
|
|
271
307
|
onAccent: "#14161c",
|
|
272
308
|
muted: "#9198a8",
|
|
273
|
-
faint: "#7c8496",
|
|
274
309
|
ok: "#8fd694",
|
|
275
310
|
warn: "#f2c46d",
|
|
276
311
|
danger: "#ff8a94",
|
|
277
312
|
info: "#7dd3e8",
|
|
278
|
-
cursor: "#
|
|
279
|
-
selected: "#
|
|
313
|
+
cursor: "#262b3c",
|
|
314
|
+
selected: "#1e212c",
|
|
280
315
|
surface: "#1c1f27",
|
|
281
316
|
chip: "#2e3340",
|
|
282
317
|
rule: "#3a3f4c",
|
|
@@ -288,13 +323,12 @@ const light = {
|
|
|
288
323
|
accent: "#3657d6",
|
|
289
324
|
onAccent: "#ffffff",
|
|
290
325
|
muted: "#5f6878",
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
warn: "#a86a00",
|
|
326
|
+
ok: "#1f7033",
|
|
327
|
+
warn: "#8f5a00",
|
|
294
328
|
danger: "#c8283c",
|
|
295
329
|
info: "#0b7c99",
|
|
296
|
-
cursor: "#
|
|
297
|
-
selected: "#
|
|
330
|
+
cursor: "#e7ebfa",
|
|
331
|
+
selected: "#f5f7fd",
|
|
298
332
|
surface: "#f6f7fa",
|
|
299
333
|
chip: "#e4e7ee",
|
|
300
334
|
rule: "#d3d7e0",
|
|
@@ -333,8 +367,8 @@ const derive = (base, background) => {
|
|
|
333
367
|
const lift = base === light ? "#000000" : "#ffffff";
|
|
334
368
|
return {
|
|
335
369
|
...base,
|
|
336
|
-
cursor: mix(background, base.accent, .
|
|
337
|
-
selected: mix(background, base.accent, .
|
|
370
|
+
cursor: mix(background, base.accent, .12),
|
|
371
|
+
selected: mix(background, base.accent, .05),
|
|
338
372
|
surface: mix(background, lift, .04),
|
|
339
373
|
chip: mix(background, lift, .12),
|
|
340
374
|
rule: mix(background, lift, .16)
|
|
@@ -371,9 +405,6 @@ const theme = {
|
|
|
371
405
|
get muted() {
|
|
372
406
|
return palette().muted;
|
|
373
407
|
},
|
|
374
|
-
get faint() {
|
|
375
|
-
return palette().faint;
|
|
376
|
-
},
|
|
377
408
|
get ok() {
|
|
378
409
|
return palette().ok;
|
|
379
410
|
},
|
|
@@ -406,69 +437,65 @@ const theme = {
|
|
|
406
437
|
// src/tui/Popup.tsx
|
|
407
438
|
const separator = 2;
|
|
408
439
|
const chip = (binding) => ` ${binding.hint ?? ""} `;
|
|
409
|
-
const hintsWidth = (bindings) => bindings.reduce((width, binding, index) => width + (index === 0 ? 0 : separator) +
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
});
|
|
469
|
-
return _el$2;
|
|
470
|
-
})();
|
|
471
|
-
}
|
|
440
|
+
const hintsWidth = (bindings) => bindings.reduce((width, binding, index) => width + (index === 0 ? 0 : separator) + graphemes(chip(binding)).length + 1 + graphemes(binding.description ?? "").length, 0);
|
|
441
|
+
const Key = (props) => (() => {
|
|
442
|
+
var _el$ = createElement("text");
|
|
443
|
+
setProp(_el$, "flexShrink", 0);
|
|
444
|
+
insert(_el$, () => ` ${props.hint} `);
|
|
445
|
+
effect((_p$) => {
|
|
446
|
+
var _v$ = props.color ?? theme.strong, _v$2 = theme.chip, _v$3 = TextAttributes.BOLD;
|
|
447
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$, "fg", _v$, _p$.e));
|
|
448
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$, "bg", _v$2, _p$.t));
|
|
449
|
+
_v$3 !== _p$.a && (_p$.a = setProp(_el$, "attributes", _v$3, _p$.a));
|
|
450
|
+
return _p$;
|
|
451
|
+
}, {
|
|
452
|
+
e: void 0,
|
|
453
|
+
t: void 0,
|
|
454
|
+
a: void 0
|
|
455
|
+
});
|
|
456
|
+
return _el$;
|
|
457
|
+
})();
|
|
458
|
+
const Hints = (props) => (() => {
|
|
459
|
+
var _el$2 = createElement("box");
|
|
460
|
+
setProp(_el$2, "flexDirection", "row");
|
|
461
|
+
setProp(_el$2, "flexShrink", 0);
|
|
462
|
+
insert(_el$2, createComponent(For, {
|
|
463
|
+
get each() {
|
|
464
|
+
return props.bindings;
|
|
465
|
+
},
|
|
466
|
+
children: (binding, index) => (() => {
|
|
467
|
+
var _el$3 = createElement("box"), _el$4 = createElement("text");
|
|
468
|
+
insertNode(_el$3, _el$4);
|
|
469
|
+
setProp(_el$3, "flexDirection", "row");
|
|
470
|
+
setProp(_el$3, "flexShrink", 0);
|
|
471
|
+
insert(_el$3, createComponent(Key, { get hint() {
|
|
472
|
+
return binding.hint ?? "";
|
|
473
|
+
} }), _el$4);
|
|
474
|
+
setProp(_el$4, "flexShrink", 0);
|
|
475
|
+
insert(_el$4, () => ` ${binding.description ?? ""}`);
|
|
476
|
+
effect((_p$) => {
|
|
477
|
+
var _v$6 = index() === 0 ? 0 : separator, _v$7 = theme.muted;
|
|
478
|
+
_v$6 !== _p$.e && (_p$.e = setProp(_el$3, "marginLeft", _v$6, _p$.e));
|
|
479
|
+
_v$7 !== _p$.t && (_p$.t = setProp(_el$4, "fg", _v$7, _p$.t));
|
|
480
|
+
return _p$;
|
|
481
|
+
}, {
|
|
482
|
+
e: void 0,
|
|
483
|
+
t: void 0
|
|
484
|
+
});
|
|
485
|
+
return _el$3;
|
|
486
|
+
})()
|
|
487
|
+
}));
|
|
488
|
+
effect((_p$) => {
|
|
489
|
+
var _v$4 = props.wrap === true ? "wrap" : "no-wrap", _v$5 = props.wrap === true ? "auto" : 1;
|
|
490
|
+
_v$4 !== _p$.e && (_p$.e = setProp(_el$2, "flexWrap", _v$4, _p$.e));
|
|
491
|
+
_v$5 !== _p$.t && (_p$.t = setProp(_el$2, "height", _v$5, _p$.t));
|
|
492
|
+
return _p$;
|
|
493
|
+
}, {
|
|
494
|
+
e: void 0,
|
|
495
|
+
t: void 0
|
|
496
|
+
});
|
|
497
|
+
return _el$2;
|
|
498
|
+
})();
|
|
472
499
|
const toneColor = (tone) => {
|
|
473
500
|
switch (tone) {
|
|
474
501
|
case "accent": return theme.accent;
|
|
@@ -477,12 +504,31 @@ const toneColor = (tone) => {
|
|
|
477
504
|
case "quiet": return theme.muted;
|
|
478
505
|
}
|
|
479
506
|
};
|
|
480
|
-
|
|
507
|
+
const useCompact = () => {
|
|
508
|
+
const dimensions = useTerminalDimensions();
|
|
509
|
+
return () => dimensions().height < 20;
|
|
510
|
+
};
|
|
511
|
+
const frame = 6;
|
|
512
|
+
const popupWidth = (wanted, terminal) => Math.min(wanted, terminal - 4);
|
|
513
|
+
const bodyWidth = (wanted, terminal) => popupWidth(wanted, terminal) - frame;
|
|
514
|
+
const scrollHint = {
|
|
515
|
+
keys: [],
|
|
516
|
+
hint: "↑↓",
|
|
517
|
+
description: "scroll"
|
|
518
|
+
};
|
|
519
|
+
const Popup = (props) => {
|
|
481
520
|
const dimensions = useTerminalDimensions();
|
|
482
|
-
const
|
|
521
|
+
const compact = useCompact();
|
|
522
|
+
const width = () => popupWidth(props.width ?? 64, dimensions().width);
|
|
483
523
|
const color = () => toneColor(props.tone ?? "accent");
|
|
524
|
+
let body;
|
|
525
|
+
useKeyboard((key) => {
|
|
526
|
+
if (props.scrolls !== true) return;
|
|
527
|
+
if (matches(keys.down, key)) body?.scrollBy(1);
|
|
528
|
+
else if (matches(keys.up, key)) body?.scrollBy(-1);
|
|
529
|
+
});
|
|
484
530
|
return (() => {
|
|
485
|
-
var _el$5 = createElement("box"), _el$6 = createElement("box"), _el$7 = createElement("box"), _el$8 = createElement("text"), _el$9 = createElement("text"), _el$1 = createElement("text");
|
|
531
|
+
var _el$5 = createElement("box"), _el$6 = createElement("box"), _el$7 = createElement("box"), _el$8 = createElement("text"), _el$9 = createElement("text"), _el$1 = createElement("scrollbox"), _el$10 = createElement("text");
|
|
486
532
|
insertNode(_el$5, _el$6);
|
|
487
533
|
setProp(_el$5, "position", "absolute");
|
|
488
534
|
setProp(_el$5, "zIndex", 10);
|
|
@@ -500,6 +546,7 @@ function Popup(props) {
|
|
|
500
546
|
insertNode(_el$7, _el$8);
|
|
501
547
|
insertNode(_el$7, _el$9);
|
|
502
548
|
insertNode(_el$7, _el$1);
|
|
549
|
+
insertNode(_el$7, _el$10);
|
|
503
550
|
setProp(_el$7, "flexShrink", 1);
|
|
504
551
|
setProp(_el$7, "overflow", "hidden");
|
|
505
552
|
setProp(_el$7, "flexDirection", "column");
|
|
@@ -507,27 +554,36 @@ function Popup(props) {
|
|
|
507
554
|
setProp(_el$7, "borderStyle", "rounded");
|
|
508
555
|
setProp(_el$7, "paddingLeft", 2);
|
|
509
556
|
setProp(_el$7, "paddingRight", 2);
|
|
510
|
-
setProp(_el$
|
|
557
|
+
setProp(_el$8, "flexShrink", 0);
|
|
511
558
|
insert(_el$8, () => props.title);
|
|
512
559
|
insertNode(_el$9, createTextNode(` `));
|
|
513
|
-
|
|
514
|
-
|
|
560
|
+
setProp(_el$9, "flexShrink", 0);
|
|
561
|
+
use((box) => {
|
|
562
|
+
body = box;
|
|
563
|
+
}, _el$1);
|
|
564
|
+
setProp(_el$1, "flexShrink", 1);
|
|
565
|
+
setProp(_el$1, "minHeight", 1);
|
|
566
|
+
setProp(_el$1, "contentOptions", { minHeight: 0 });
|
|
567
|
+
insert(_el$1, () => props.children);
|
|
568
|
+
insertNode(_el$10, createTextNode(` `));
|
|
569
|
+
setProp(_el$10, "flexShrink", 0);
|
|
515
570
|
insert(_el$7, createComponent(Hints, {
|
|
516
571
|
get bindings() {
|
|
517
|
-
return props.bindings;
|
|
572
|
+
return memo(() => props.scrolls === true)() ? [scrollHint, ...props.bindings] : props.bindings;
|
|
518
573
|
},
|
|
519
574
|
wrap: true
|
|
520
575
|
}), null);
|
|
521
576
|
effect((_p$) => {
|
|
522
|
-
var _v$8 = width() + 2, _v$9 =
|
|
577
|
+
var _v$8 = width() + 2, _v$9 = theme.surface, _v$0 = width(), _v$1 = dimensions().height, _v$10 = color(), _v$11 = theme.surface, _v$12 = compact() ? 0 : 1, _v$13 = props.tone === "quiet" ? theme.strong : color(), _v$14 = TextAttributes.BOLD;
|
|
523
578
|
_v$8 !== _p$.e && (_p$.e = setProp(_el$6, "width", _v$8, _p$.e));
|
|
524
|
-
_v$9 !== _p$.t && (_p$.t = setProp(_el$6, "
|
|
525
|
-
_v$0 !== _p$.a && (_p$.a = setProp(_el$
|
|
526
|
-
_v$1 !== _p$.o && (_p$.o = setProp(_el$7, "
|
|
579
|
+
_v$9 !== _p$.t && (_p$.t = setProp(_el$6, "backgroundColor", _v$9, _p$.t));
|
|
580
|
+
_v$0 !== _p$.a && (_p$.a = setProp(_el$7, "width", _v$0, _p$.a));
|
|
581
|
+
_v$1 !== _p$.o && (_p$.o = setProp(_el$7, "maxHeight", _v$1, _p$.o));
|
|
527
582
|
_v$10 !== _p$.i && (_p$.i = setProp(_el$7, "borderColor", _v$10, _p$.i));
|
|
528
583
|
_v$11 !== _p$.n && (_p$.n = setProp(_el$7, "backgroundColor", _v$11, _p$.n));
|
|
529
|
-
_v$12 !== _p$.s && (_p$.s = setProp(_el$
|
|
530
|
-
_v$13 !== _p$.h && (_p$.h = setProp(_el$8, "
|
|
584
|
+
_v$12 !== _p$.s && (_p$.s = setProp(_el$7, "paddingTop", _v$12, _p$.s));
|
|
585
|
+
_v$13 !== _p$.h && (_p$.h = setProp(_el$8, "fg", _v$13, _p$.h));
|
|
586
|
+
_v$14 !== _p$.r && (_p$.r = setProp(_el$8, "attributes", _v$14, _p$.r));
|
|
531
587
|
return _p$;
|
|
532
588
|
}, {
|
|
533
589
|
e: void 0,
|
|
@@ -537,11 +593,12 @@ function Popup(props) {
|
|
|
537
593
|
i: void 0,
|
|
538
594
|
n: void 0,
|
|
539
595
|
s: void 0,
|
|
540
|
-
h: void 0
|
|
596
|
+
h: void 0,
|
|
597
|
+
r: void 0
|
|
541
598
|
});
|
|
542
599
|
return _el$5;
|
|
543
600
|
})();
|
|
544
|
-
}
|
|
601
|
+
};
|
|
545
602
|
// src/tui/Spinner.tsx
|
|
546
603
|
const frames = [
|
|
547
604
|
"⠋",
|
|
@@ -555,10 +612,14 @@ const frames = [
|
|
|
555
612
|
"⠇",
|
|
556
613
|
"⠏"
|
|
557
614
|
];
|
|
558
|
-
|
|
615
|
+
const Spinner = (props) => {
|
|
559
616
|
const [frame, setFrame] = createSignal(0);
|
|
560
|
-
const timer = setInterval(() =>
|
|
561
|
-
|
|
617
|
+
const timer = setInterval(() => {
|
|
618
|
+
setFrame((at) => (at + 1) % frames.length);
|
|
619
|
+
}, 80);
|
|
620
|
+
onCleanup(() => {
|
|
621
|
+
clearInterval(timer);
|
|
622
|
+
});
|
|
562
623
|
return (() => {
|
|
563
624
|
var _el$ = createElement("text");
|
|
564
625
|
setProp(_el$, "flexShrink", 0);
|
|
@@ -566,24 +627,31 @@ function Spinner(props) {
|
|
|
566
627
|
effect((_$p) => setProp(_el$, "fg", props.color ?? theme.accent, _$p));
|
|
567
628
|
return _el$;
|
|
568
629
|
})();
|
|
569
|
-
}
|
|
630
|
+
};
|
|
570
631
|
// src/tui/Changes.tsx
|
|
571
632
|
const shownLines = 2e3;
|
|
572
633
|
const diffHead = "changes-diff-head";
|
|
573
|
-
const areas =
|
|
574
|
-
to
|
|
575
|
-
"payload-to"
|
|
576
|
-
"wheel-to"
|
|
577
|
-
source
|
|
578
|
-
"repo-to"
|
|
579
|
-
"go-source-to"
|
|
580
|
-
"dependencies-to"
|
|
581
|
-
|
|
634
|
+
const areas = /* @__PURE__ */ new Map([
|
|
635
|
+
["to", "Package"],
|
|
636
|
+
["payload-to", "Payload"],
|
|
637
|
+
["wheel-to", "Wheel"],
|
|
638
|
+
["source", "Source"],
|
|
639
|
+
["repo-to", "Source repository"],
|
|
640
|
+
["go-source-to", "Go source"],
|
|
641
|
+
["dependencies-to", "Dependencies"]
|
|
642
|
+
]);
|
|
582
643
|
const metadata = "Package metadata";
|
|
583
644
|
const generated = "Generated";
|
|
584
|
-
const isGenerated = (path) => path.endsWith(".map") || /\.min\.(js|css)$/u.test(path) || /(
|
|
585
|
-
const areaOf = (section) =>
|
|
586
|
-
|
|
645
|
+
const isGenerated = (path) => path.endsWith(".map") || /\.min\.(?:js|css)$/u.test(path) || /(?:^|\/)chunk-[\w-]*\d[\w-]*\.\w+$/u.test(path) || /(?:^|\/)(?:dist|build|out)\//u.test(path);
|
|
646
|
+
const areaOf = (section) => {
|
|
647
|
+
if (isGenerated(section.path)) return generated;
|
|
648
|
+
if (section.tree === "") return metadata;
|
|
649
|
+
return areas.get(section.tree) ?? section.tree;
|
|
650
|
+
};
|
|
651
|
+
const rank = (area) => {
|
|
652
|
+
if (area === generated) return 2;
|
|
653
|
+
return area === metadata ? 1 : 0;
|
|
654
|
+
};
|
|
587
655
|
const files = (view) => view.sections.map((section) => ({
|
|
588
656
|
section,
|
|
589
657
|
area: areaOf(section),
|
|
@@ -624,11 +692,15 @@ const grades = {
|
|
|
624
692
|
color: () => theme.muted
|
|
625
693
|
}
|
|
626
694
|
};
|
|
627
|
-
const lineColor = (line) =>
|
|
695
|
+
const lineColor = (line) => {
|
|
696
|
+
if (line.startsWith("+")) return theme.ok;
|
|
697
|
+
if (line.startsWith("-")) return theme.danger;
|
|
698
|
+
return line.startsWith("@@") ? theme.info : theme.muted;
|
|
699
|
+
};
|
|
628
700
|
const endings = (from, to) => {
|
|
629
701
|
const left = from.split("/");
|
|
630
702
|
const right = to.split("/");
|
|
631
|
-
for (let count = 2; count < Math.max(left.length, right.length); count
|
|
703
|
+
for (let count = 2; count < Math.max(left.length, right.length); count += 1) {
|
|
632
704
|
const ours = left.slice(-count).join("/");
|
|
633
705
|
const theirs = right.slice(-count).join("/");
|
|
634
706
|
if (ours !== theirs) return [ours, theirs];
|
|
@@ -636,18 +708,23 @@ const endings = (from, to) => {
|
|
|
636
708
|
return [from, to];
|
|
637
709
|
};
|
|
638
710
|
const flags = (section) => [section.binary ? "binary" : "", section.longLine ? "long lines" : ""].filter(Boolean).join(", ");
|
|
639
|
-
|
|
711
|
+
const Diff = (props) => {
|
|
640
712
|
const list = createMemo(() => files(props.view));
|
|
641
713
|
const current = createMemo(() => list()[Math.min(props.at, list().length - 1)]);
|
|
642
714
|
const at = (file) => file.section === current()?.section;
|
|
643
715
|
const next = () => list()[Math.min(props.at, list().length - 1) + 1];
|
|
644
|
-
const totals = () =>
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
716
|
+
const totals = () => {
|
|
717
|
+
let added = 0;
|
|
718
|
+
let removed = 0;
|
|
719
|
+
for (const file of list()) {
|
|
720
|
+
added += file.added;
|
|
721
|
+
removed += file.removed;
|
|
722
|
+
}
|
|
723
|
+
return {
|
|
724
|
+
added,
|
|
725
|
+
removed
|
|
726
|
+
};
|
|
727
|
+
};
|
|
651
728
|
const width = () => Math.max(3, ...list().flatMap((file) => [`${file.added}`.length, `${file.removed}`.length])) + 1;
|
|
652
729
|
const grouped = () => {
|
|
653
730
|
const byArea = /* @__PURE__ */ new Map();
|
|
@@ -764,6 +841,10 @@ function Diff(props) {
|
|
|
764
841
|
children: ([area, entries]) => {
|
|
765
842
|
const folded = () => area === generated && !entries.some(at);
|
|
766
843
|
const window = () => around(entries, entries.findIndex(at));
|
|
844
|
+
const foldMark = () => {
|
|
845
|
+
if (area !== generated) return "";
|
|
846
|
+
return folded() ? "▸ " : "▾ ";
|
|
847
|
+
};
|
|
767
848
|
return (() => {
|
|
768
849
|
var _el$22 = createElement("box"), _el$23 = createElement("box"), _el$24 = createElement("text"), _el$25 = createElement("text");
|
|
769
850
|
insertNode(_el$22, _el$23);
|
|
@@ -774,7 +855,7 @@ function Diff(props) {
|
|
|
774
855
|
setProp(_el$23, "flexDirection", "row");
|
|
775
856
|
setProp(_el$23, "height", 1);
|
|
776
857
|
setProp(_el$24, "flexShrink", 0);
|
|
777
|
-
insert(_el$24, () => `${
|
|
858
|
+
insert(_el$24, () => `${foldMark()}${area}`);
|
|
778
859
|
setProp(_el$25, "flexShrink", 0);
|
|
779
860
|
insert(_el$25, () => ` ${entries.length}`);
|
|
780
861
|
insert(_el$23, createComponent(Show, {
|
|
@@ -801,7 +882,7 @@ function Diff(props) {
|
|
|
801
882
|
var _el$28 = createElement("text");
|
|
802
883
|
insertNode(_el$28, createTextNode(` build output, maps and hashed chunks`));
|
|
803
884
|
setProp(_el$28, "flexShrink", 0);
|
|
804
|
-
effect((_$p) => setProp(_el$28, "fg", theme.
|
|
885
|
+
effect((_$p) => setProp(_el$28, "fg", theme.muted, _$p));
|
|
805
886
|
return _el$28;
|
|
806
887
|
})()
|
|
807
888
|
];
|
|
@@ -820,7 +901,7 @@ function Diff(props) {
|
|
|
820
901
|
get children() {
|
|
821
902
|
var _el$30 = createElement("text");
|
|
822
903
|
insert(_el$30, () => ` … ${window().before} earlier`);
|
|
823
|
-
effect((_$p) => setProp(_el$30, "fg", theme.
|
|
904
|
+
effect((_$p) => setProp(_el$30, "fg", theme.muted, _$p));
|
|
824
905
|
return _el$30;
|
|
825
906
|
}
|
|
826
907
|
}),
|
|
@@ -883,7 +964,7 @@ function Diff(props) {
|
|
|
883
964
|
get children() {
|
|
884
965
|
var _el$31 = createElement("text");
|
|
885
966
|
insert(_el$31, () => ` … ${window().after} more · n/p step through them`);
|
|
886
|
-
effect((_$p) => setProp(_el$31, "fg", theme.
|
|
967
|
+
effect((_$p) => setProp(_el$31, "fg", theme.muted, _$p));
|
|
887
968
|
return _el$31;
|
|
888
969
|
}
|
|
889
970
|
})
|
|
@@ -891,7 +972,7 @@ function Diff(props) {
|
|
|
891
972
|
}
|
|
892
973
|
}), null);
|
|
893
974
|
effect((_p$) => {
|
|
894
|
-
var _v$0 = theme.muted, _v$1 = TextAttributes.BOLD, _v$10 = theme.
|
|
975
|
+
var _v$0 = theme.muted, _v$1 = TextAttributes.BOLD, _v$10 = theme.muted;
|
|
895
976
|
_v$0 !== _p$.e && (_p$.e = setProp(_el$24, "fg", _v$0, _p$.e));
|
|
896
977
|
_v$1 !== _p$.t && (_p$.t = setProp(_el$24, "attributes", _v$1, _p$.t));
|
|
897
978
|
_v$10 !== _p$.a && (_p$.a = setProp(_el$25, "fg", _v$10, _p$.a));
|
|
@@ -989,7 +1070,7 @@ function Diff(props) {
|
|
|
989
1070
|
return () => _c$() ? " previous file (this is the last)" : ` next: ${endings(file().section.path, next()?.section.path ?? "")[1]}`;
|
|
990
1071
|
})());
|
|
991
1072
|
effect((_p$) => {
|
|
992
|
-
var _v$16 = theme.
|
|
1073
|
+
var _v$16 = theme.muted, _v$17 = theme.muted;
|
|
993
1074
|
_v$16 !== _p$.e && (_p$.e = setProp(_el$50, "fg", _v$16, _p$.e));
|
|
994
1075
|
_v$17 !== _p$.t && (_p$.t = setProp(_el$51, "fg", _v$17, _p$.t));
|
|
995
1076
|
return _p$;
|
|
@@ -1046,8 +1127,8 @@ function Diff(props) {
|
|
|
1046
1127
|
});
|
|
1047
1128
|
return _el$;
|
|
1048
1129
|
})();
|
|
1049
|
-
}
|
|
1050
|
-
|
|
1130
|
+
};
|
|
1131
|
+
const Changes = (props) => {
|
|
1051
1132
|
const ready = () => props.loaded?._tag === "Ready" ? props.loaded.value : void 0;
|
|
1052
1133
|
const unavailable = () => props.loaded?._tag === "Unavailable" ? props.loaded.issue : void 0;
|
|
1053
1134
|
return createComponent(Switch, {
|
|
@@ -1058,56 +1139,56 @@ function Changes(props) {
|
|
|
1058
1139
|
},
|
|
1059
1140
|
get fallback() {
|
|
1060
1141
|
return (() => {
|
|
1061
|
-
var _el$
|
|
1062
|
-
insertNode(_el$
|
|
1063
|
-
setProp(_el$
|
|
1064
|
-
setProp(_el$
|
|
1065
|
-
insert(_el$
|
|
1066
|
-
insert(_el$
|
|
1142
|
+
var _el$60 = createElement("box"), _el$61 = createElement("text");
|
|
1143
|
+
insertNode(_el$60, _el$61);
|
|
1144
|
+
setProp(_el$60, "flexDirection", "column");
|
|
1145
|
+
setProp(_el$61, "wrapMode", "word");
|
|
1146
|
+
insert(_el$61, () => `Nothing to compare: ${props.unauditable ?? ""}.`);
|
|
1147
|
+
insert(_el$60, createComponent(Show, {
|
|
1067
1148
|
get when() {
|
|
1068
1149
|
return props.notes;
|
|
1069
1150
|
},
|
|
1070
1151
|
children: (notes) => [
|
|
1071
1152
|
(() => {
|
|
1072
|
-
var _el$
|
|
1073
|
-
insertNode(_el$
|
|
1074
|
-
return _el$
|
|
1153
|
+
var _el$62 = createElement("text");
|
|
1154
|
+
insertNode(_el$62, createTextNode(` `));
|
|
1155
|
+
return _el$62;
|
|
1075
1156
|
})(),
|
|
1076
1157
|
(() => {
|
|
1077
|
-
var _el$
|
|
1078
|
-
insertNode(_el$
|
|
1158
|
+
var _el$64 = createElement("text");
|
|
1159
|
+
insertNode(_el$64, createTextNode(`Release notes`));
|
|
1079
1160
|
effect((_p$) => {
|
|
1080
1161
|
var _v$21 = theme.muted, _v$22 = TextAttributes.BOLD;
|
|
1081
|
-
_v$21 !== _p$.e && (_p$.e = setProp(_el$
|
|
1082
|
-
_v$22 !== _p$.t && (_p$.t = setProp(_el$
|
|
1162
|
+
_v$21 !== _p$.e && (_p$.e = setProp(_el$64, "fg", _v$21, _p$.e));
|
|
1163
|
+
_v$22 !== _p$.t && (_p$.t = setProp(_el$64, "attributes", _v$22, _p$.t));
|
|
1083
1164
|
return _p$;
|
|
1084
1165
|
}, {
|
|
1085
1166
|
e: void 0,
|
|
1086
1167
|
t: void 0
|
|
1087
1168
|
});
|
|
1088
|
-
return _el$
|
|
1169
|
+
return _el$64;
|
|
1089
1170
|
})(),
|
|
1090
1171
|
(() => {
|
|
1091
|
-
var _el$
|
|
1092
|
-
setProp(_el$
|
|
1093
|
-
insert(_el$
|
|
1094
|
-
return _el$
|
|
1172
|
+
var _el$66 = createElement("text");
|
|
1173
|
+
setProp(_el$66, "wrapMode", "word");
|
|
1174
|
+
insert(_el$66, notes);
|
|
1175
|
+
return _el$66;
|
|
1095
1176
|
})()
|
|
1096
1177
|
]
|
|
1097
1178
|
}), null);
|
|
1098
|
-
effect((_$p) => setProp(_el$
|
|
1099
|
-
return _el$
|
|
1179
|
+
effect((_$p) => setProp(_el$61, "fg", theme.muted, _$p));
|
|
1180
|
+
return _el$60;
|
|
1100
1181
|
})();
|
|
1101
1182
|
},
|
|
1102
1183
|
get children() {
|
|
1103
|
-
var _el$
|
|
1104
|
-
insertNode(_el$
|
|
1105
|
-
setProp(_el$
|
|
1106
|
-
setProp(_el$
|
|
1107
|
-
insert(_el$
|
|
1108
|
-
insertNode(_el$
|
|
1109
|
-
effect((_$p) => setProp(_el$
|
|
1110
|
-
return _el$
|
|
1184
|
+
var _el$57 = createElement("box"), _el$58 = createElement("text");
|
|
1185
|
+
insertNode(_el$57, _el$58);
|
|
1186
|
+
setProp(_el$57, "flexDirection", "row");
|
|
1187
|
+
setProp(_el$57, "height", 1);
|
|
1188
|
+
insert(_el$57, createComponent(Spinner, {}), _el$58);
|
|
1189
|
+
insertNode(_el$58, createTextNode(` Preparing the comparison…`));
|
|
1190
|
+
effect((_$p) => setProp(_el$58, "fg", theme.muted, _$p));
|
|
1191
|
+
return _el$57;
|
|
1111
1192
|
}
|
|
1112
1193
|
});
|
|
1113
1194
|
},
|
|
@@ -1118,12 +1199,12 @@ function Changes(props) {
|
|
|
1118
1199
|
return props.loaded?._tag === "Loading";
|
|
1119
1200
|
},
|
|
1120
1201
|
get children() {
|
|
1121
|
-
var _el$53 = createElement("box"), _el$54 = createElement("text");
|
|
1202
|
+
var _el$53 = createElement("box"), _el$54 = createElement("text"), _el$55 = createTextNode(` Downloading, verifying and comparing both versions…`);
|
|
1122
1203
|
insertNode(_el$53, _el$54);
|
|
1123
1204
|
setProp(_el$53, "flexDirection", "row");
|
|
1124
1205
|
setProp(_el$53, "height", 1);
|
|
1125
1206
|
insert(_el$53, createComponent(Spinner, {}), _el$54);
|
|
1126
|
-
insertNode(_el$54,
|
|
1207
|
+
insertNode(_el$54, _el$55);
|
|
1127
1208
|
effect((_$p) => setProp(_el$54, "fg", theme.muted, _$p));
|
|
1128
1209
|
return _el$53;
|
|
1129
1210
|
}
|
|
@@ -1133,11 +1214,11 @@ function Changes(props) {
|
|
|
1133
1214
|
return unavailable();
|
|
1134
1215
|
},
|
|
1135
1216
|
children: (issue) => (() => {
|
|
1136
|
-
var _el$
|
|
1137
|
-
setProp(_el$
|
|
1138
|
-
insert(_el$
|
|
1139
|
-
effect((_$p) => setProp(_el$
|
|
1140
|
-
return _el$
|
|
1217
|
+
var _el$67 = createElement("text");
|
|
1218
|
+
setProp(_el$67, "wrapMode", "word");
|
|
1219
|
+
insert(_el$67, () => `✗ Changes unavailable: ${issue()}`);
|
|
1220
|
+
effect((_$p) => setProp(_el$67, "fg", theme.danger, _$p));
|
|
1221
|
+
return _el$67;
|
|
1141
1222
|
})()
|
|
1142
1223
|
}),
|
|
1143
1224
|
createComponent(Match, {
|
|
@@ -1156,10 +1237,60 @@ function Changes(props) {
|
|
|
1156
1237
|
];
|
|
1157
1238
|
}
|
|
1158
1239
|
});
|
|
1159
|
-
}
|
|
1240
|
+
};
|
|
1241
|
+
// src/tui/Segments.tsx
|
|
1242
|
+
const segment = (color, text, bold = false) => ({
|
|
1243
|
+
text,
|
|
1244
|
+
color,
|
|
1245
|
+
bold
|
|
1246
|
+
});
|
|
1247
|
+
const Segments = (props) => (() => {
|
|
1248
|
+
var _el$ = createElement("box");
|
|
1249
|
+
setProp(_el$, "flexDirection", "row");
|
|
1250
|
+
setProp(_el$, "height", 1);
|
|
1251
|
+
insert(_el$, createComponent(For, {
|
|
1252
|
+
get each() {
|
|
1253
|
+
return props.segments.filter((part) => part.text !== "");
|
|
1254
|
+
},
|
|
1255
|
+
children: (part) => (() => {
|
|
1256
|
+
var _el$2 = createElement("text");
|
|
1257
|
+
setProp(_el$2, "flexShrink", 0);
|
|
1258
|
+
setProp(_el$2, "wrapMode", "none");
|
|
1259
|
+
insert(_el$2, () => part.text);
|
|
1260
|
+
effect((_p$) => {
|
|
1261
|
+
var _v$ = part.color, _v$2 = part.bold === true ? TextAttributes.BOLD : TextAttributes.NONE;
|
|
1262
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$2, "fg", _v$, _p$.e));
|
|
1263
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$2, "attributes", _v$2, _p$.t));
|
|
1264
|
+
return _p$;
|
|
1265
|
+
}, {
|
|
1266
|
+
e: void 0,
|
|
1267
|
+
t: void 0
|
|
1268
|
+
});
|
|
1269
|
+
return _el$2;
|
|
1270
|
+
})()
|
|
1271
|
+
}));
|
|
1272
|
+
effect((_$p) => setProp(_el$, "backgroundColor", props.background ?? theme.none, _$p));
|
|
1273
|
+
return _el$;
|
|
1274
|
+
})();
|
|
1160
1275
|
// src/tui/view.ts
|
|
1161
1276
|
const visibleRows = (group) => group.collapsed === true ? group.kept ?? [] : group.rows;
|
|
1162
1277
|
const byName = (left, right) => left.pkg.name.localeCompare(right.pkg.name) || left.pkg.provider.localeCompare(right.pkg.provider);
|
|
1278
|
+
const providerLabels = /* @__PURE__ */ new Map([
|
|
1279
|
+
["brew", "Homebrew"],
|
|
1280
|
+
["npm-global", "npm -g"],
|
|
1281
|
+
["pnpm-global", "pnpm -g"],
|
|
1282
|
+
["vp-global", "Vite+ global"],
|
|
1283
|
+
["vp-self", "Vite+"],
|
|
1284
|
+
["cargo-install", "cargo install"],
|
|
1285
|
+
["go-install", "go install"],
|
|
1286
|
+
["uv-tool", "uv tool"],
|
|
1287
|
+
["softwareupdate", "Software Update"],
|
|
1288
|
+
["apps", "Apps"],
|
|
1289
|
+
["github-actions", "GitHub Actions"],
|
|
1290
|
+
["node-not-listed", "Node"],
|
|
1291
|
+
["node-pins", "Node.js"]
|
|
1292
|
+
]);
|
|
1293
|
+
const providerLabel = (provider) => providerLabels.get(provider) ?? provider;
|
|
1163
1294
|
const providedBy = (provider, needle) => needle.length >= 2 && `${provider} ${providerLabel(provider)}`.toLowerCase().split(/[^a-z0-9+]+/u).some((word) => word.startsWith(needle));
|
|
1164
1295
|
const groups = (state, filter) => {
|
|
1165
1296
|
const needle = filter.toLowerCase();
|
|
@@ -1207,39 +1338,51 @@ const lines = (grouped) => {
|
|
|
1207
1338
|
_tag: "Heading",
|
|
1208
1339
|
group
|
|
1209
1340
|
},
|
|
1210
|
-
...visibleRows(group).map((row) =>
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1341
|
+
...visibleRows(group).map((row) => {
|
|
1342
|
+
const line = {
|
|
1343
|
+
_tag: "Package",
|
|
1344
|
+
row,
|
|
1345
|
+
index
|
|
1346
|
+
};
|
|
1347
|
+
index += 1;
|
|
1348
|
+
return line;
|
|
1349
|
+
})
|
|
1215
1350
|
]);
|
|
1216
1351
|
};
|
|
1217
1352
|
const reachable = (grouped) => grouped.flatMap(visibleRows);
|
|
1218
|
-
const
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
"vp-global": "Vite+ global",
|
|
1223
|
-
"vp-self": "Vite+",
|
|
1224
|
-
"cargo-install": "cargo install",
|
|
1225
|
-
"go-install": "go install",
|
|
1226
|
-
"uv-tool": "uv tool",
|
|
1227
|
-
softwareupdate: "Software Update",
|
|
1228
|
-
"github-actions": "GitHub Actions"
|
|
1353
|
+
const unauditedLabels = {
|
|
1354
|
+
app: "app update",
|
|
1355
|
+
runtime: "runtime pin",
|
|
1356
|
+
os: "OS update"
|
|
1229
1357
|
};
|
|
1230
|
-
const
|
|
1231
|
-
const
|
|
1232
|
-
const
|
|
1358
|
+
const parts = (version) => version.replace(/^v/u, "").split(/(?<separator>[._+-])/u);
|
|
1359
|
+
const semverPrerelease = (version) => semver.prerelease(version) !== null;
|
|
1360
|
+
const prereleases = {
|
|
1361
|
+
npm: semverPrerelease,
|
|
1362
|
+
crates: semverPrerelease,
|
|
1363
|
+
go: semverPrerelease,
|
|
1364
|
+
"github-actions": semverPrerelease,
|
|
1365
|
+
node: semverPrerelease,
|
|
1366
|
+
pypi: (version) => /\d(?:[-_.]?(?:a|b|c|rc|alpha|beta|pre|preview)\d*|[-_.]?dev\d*)(?:$|[+.-])/iu.test(version)
|
|
1367
|
+
};
|
|
1368
|
+
const bump = (current, target, ecosystem) => {
|
|
1233
1369
|
const from = parts(current);
|
|
1234
1370
|
const to = parts(target);
|
|
1235
1371
|
let at = 0;
|
|
1236
|
-
while (at < to.length && from[at] === to[at]) at
|
|
1372
|
+
while (at < to.length && from[at] === to[at]) at += 1;
|
|
1237
1373
|
const prefix = target.startsWith("v") && current.startsWith("v") ? 1 : 0;
|
|
1238
1374
|
const shared = to.slice(0, at);
|
|
1239
1375
|
const same = target.slice(0, prefix + shared.join("").length);
|
|
1240
1376
|
const changed = target.slice(same.length);
|
|
1241
1377
|
const numbers = to.filter((_, index) => index % 2 === 0);
|
|
1242
|
-
|
|
1378
|
+
const plain = numbers.length >= 2 && numbers.slice(0, 3).every((part) => /^\d+$/u.test(part));
|
|
1379
|
+
if (prereleases[ecosystem]?.(current) === true) return {
|
|
1380
|
+
kind: "prerelease",
|
|
1381
|
+
risk: "major",
|
|
1382
|
+
same,
|
|
1383
|
+
changed
|
|
1384
|
+
};
|
|
1385
|
+
if (!plain) return {
|
|
1243
1386
|
kind: "other",
|
|
1244
1387
|
risk: "other",
|
|
1245
1388
|
same,
|
|
@@ -1260,8 +1403,16 @@ const bump = (current, target) => {
|
|
|
1260
1403
|
changed
|
|
1261
1404
|
};
|
|
1262
1405
|
};
|
|
1263
|
-
const bumpLabel = (change) =>
|
|
1264
|
-
|
|
1406
|
+
const bumpLabel = (change) => {
|
|
1407
|
+
if (change.kind === "other") return "";
|
|
1408
|
+
if (change.kind === "prerelease" || change.risk === change.kind) return change.kind;
|
|
1409
|
+
return `0.x ${change.kind}`;
|
|
1410
|
+
};
|
|
1411
|
+
const bumpTone = (change) => {
|
|
1412
|
+
if (change.risk === "major") return theme.strong;
|
|
1413
|
+
if (change.kind === "patch") return theme.muted;
|
|
1414
|
+
return theme.text;
|
|
1415
|
+
};
|
|
1265
1416
|
const window = (count, height, focus, offset) => {
|
|
1266
1417
|
const page = Math.max(1, height);
|
|
1267
1418
|
const bottom = Math.max(Math.min(offset, focus), focus - page + 1);
|
|
@@ -1323,7 +1474,9 @@ const outcomeIcon = (outcome) => {
|
|
|
1323
1474
|
case "Completed": return "✓";
|
|
1324
1475
|
case "Failed":
|
|
1325
1476
|
case "Unexpected": return "✗";
|
|
1326
|
-
|
|
1477
|
+
case "Excluded":
|
|
1478
|
+
case "NotStarted":
|
|
1479
|
+
case "Stale": return "·";
|
|
1327
1480
|
}
|
|
1328
1481
|
};
|
|
1329
1482
|
const outcomeColor = (outcome) => {
|
|
@@ -1331,7 +1484,9 @@ const outcomeColor = (outcome) => {
|
|
|
1331
1484
|
case "Completed": return theme.ok;
|
|
1332
1485
|
case "Failed":
|
|
1333
1486
|
case "Unexpected": return theme.danger;
|
|
1334
|
-
|
|
1487
|
+
case "Excluded":
|
|
1488
|
+
case "NotStarted":
|
|
1489
|
+
case "Stale": return theme.warn;
|
|
1335
1490
|
}
|
|
1336
1491
|
};
|
|
1337
1492
|
const verdictIcons = {
|
|
@@ -1356,7 +1511,7 @@ const status = (state, row) => {
|
|
|
1356
1511
|
const outcome = state.outcomes[row.key];
|
|
1357
1512
|
if (state.removed[row.key] !== void 0) return {
|
|
1358
1513
|
text: "– removed",
|
|
1359
|
-
color: theme.
|
|
1514
|
+
color: theme.muted
|
|
1360
1515
|
};
|
|
1361
1516
|
if (outcome !== void 0 && (audit === void 0 || ran.has(outcome._tag))) {
|
|
1362
1517
|
if (outcome._tag === "Completed" && auditedAs(state, row.pkg) !== row.pkg) {
|
|
@@ -1382,18 +1537,12 @@ const status = (state, row) => {
|
|
|
1382
1537
|
};
|
|
1383
1538
|
if (row.pkg.target === void 0 || state.recalling) return {
|
|
1384
1539
|
text: "",
|
|
1385
|
-
color: theme.
|
|
1540
|
+
color: theme.muted
|
|
1386
1541
|
};
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
if (isVendorUpdate(row.pkg)) return row.pkg.restart === true ? {
|
|
1392
|
-
text: "OS · restarts",
|
|
1393
|
-
color: theme.faint
|
|
1394
|
-
} : {
|
|
1395
|
-
text: "OS update",
|
|
1396
|
-
color: theme.faint
|
|
1542
|
+
const kind = unauditedKind(row.pkg);
|
|
1543
|
+
if (kind !== void 0) return {
|
|
1544
|
+
text: kind === "os" && row.pkg.restart === true ? "OS · restarts" : unauditedLabels[kind],
|
|
1545
|
+
color: theme.muted
|
|
1397
1546
|
};
|
|
1398
1547
|
if (majorsOf(state, row.pkg).length > 0) return {
|
|
1399
1548
|
text: breakingMark,
|
|
@@ -1401,7 +1550,7 @@ const status = (state, row) => {
|
|
|
1401
1550
|
};
|
|
1402
1551
|
return {
|
|
1403
1552
|
text: "not audited",
|
|
1404
|
-
color: theme.
|
|
1553
|
+
color: theme.muted
|
|
1405
1554
|
};
|
|
1406
1555
|
}
|
|
1407
1556
|
if (audit._tag === "Running") return {
|
|
@@ -1413,22 +1562,321 @@ const status = (state, row) => {
|
|
|
1413
1562
|
text: "✗ audit failed",
|
|
1414
1563
|
color: theme.danger
|
|
1415
1564
|
};
|
|
1416
|
-
const verdict = audit.result.report
|
|
1565
|
+
const { verdict } = audit.result.report;
|
|
1417
1566
|
const installed = auditedAs(state, row.pkg) !== row.pkg;
|
|
1418
1567
|
return {
|
|
1419
1568
|
text: `${verdictIcons[verdict]} ${installed ? "installed" : verdictLabels[verdict]}`,
|
|
1420
1569
|
color: verdictColor(verdict)
|
|
1421
1570
|
};
|
|
1422
1571
|
};
|
|
1423
|
-
const fit = (text, width) => {
|
|
1424
|
-
const chars = [...text.replaceAll(/\s+/gu, " ")];
|
|
1425
|
-
if (chars.length <= width) return chars.join("").padEnd(width);
|
|
1426
|
-
return width <= 1 ? "…".slice(0, width) : `${chars.slice(0, width - 1).join("")}…`;
|
|
1427
|
-
};
|
|
1428
1572
|
const modelLabel = (state, provider, modelId) => {
|
|
1429
1573
|
const choice = state.catalogue?._tag === "Ready" ? state.catalogue.value.find((entry) => entry.provider === provider && entry.modelId === modelId) : void 0;
|
|
1430
1574
|
return choice === void 0 ? `${provider}/${modelId}` : `${choice.providerName} · ${choice.name}`;
|
|
1431
1575
|
};
|
|
1576
|
+
// src/tui/Confirm.tsx
|
|
1577
|
+
const confirmations = {
|
|
1578
|
+
update: {
|
|
1579
|
+
verb: "Update",
|
|
1580
|
+
done: "updated"
|
|
1581
|
+
},
|
|
1582
|
+
uninstall: {
|
|
1583
|
+
verb: "Remove",
|
|
1584
|
+
done: "removed"
|
|
1585
|
+
},
|
|
1586
|
+
audit: {
|
|
1587
|
+
verb: "Audit",
|
|
1588
|
+
done: "audited"
|
|
1589
|
+
}
|
|
1590
|
+
};
|
|
1591
|
+
const flaggedFirst = (pending) => {
|
|
1592
|
+
const flagged = new Set(pending.flagged.map((entry) => entry.row.key));
|
|
1593
|
+
return [...pending.rows.filter((row) => flagged.has(row.key)), ...pending.rows.filter((row) => !flagged.has(row.key))];
|
|
1594
|
+
};
|
|
1595
|
+
const markOf = (pending, row) => {
|
|
1596
|
+
const verdict = pending.flagged.find((entry) => entry.row.key === row.key)?.verdict;
|
|
1597
|
+
const mixed = pending.unaudited.length > 0 && pending.unaudited.length < pending.rows.length;
|
|
1598
|
+
if (verdict === void 0 && pending.unauditable.includes(row.key)) {
|
|
1599
|
+
const restarts = pending.action === "update" && row.pkg.restart === true;
|
|
1600
|
+
return {
|
|
1601
|
+
text: `${unauditedLabels[unauditedKind(row.pkg) ?? "os"]}${restarts ? " · restarts" : ""} · not audited`,
|
|
1602
|
+
color: restarts ? theme.warn : theme.muted
|
|
1603
|
+
};
|
|
1604
|
+
}
|
|
1605
|
+
if (verdict === void 0) {
|
|
1606
|
+
if (pending.action === "update" && !pending.unaudited.includes(row.key)) return {
|
|
1607
|
+
text: `${verdictIcons.ok} ${verdictLabels.ok}`,
|
|
1608
|
+
color: theme.ok
|
|
1609
|
+
};
|
|
1610
|
+
const unread = pending.action === "update" && pending.unaudited.includes(row.key) && (mixed || !pending.auditFirst);
|
|
1611
|
+
if (pending.action === "update" && pending.breaking.includes(row.key)) return {
|
|
1612
|
+
text: `${breakingMark}${unread ? " · not audited" : ""}`,
|
|
1613
|
+
color: theme.warn
|
|
1614
|
+
};
|
|
1615
|
+
return unread ? {
|
|
1616
|
+
text: "not audited",
|
|
1617
|
+
color: theme.muted
|
|
1618
|
+
} : void 0;
|
|
1619
|
+
}
|
|
1620
|
+
if (verdict === "failed") return {
|
|
1621
|
+
text: "✗ audit failed",
|
|
1622
|
+
color: theme.danger
|
|
1623
|
+
};
|
|
1624
|
+
return {
|
|
1625
|
+
text: `${verdictIcons[verdict]} ${verdictLabels[verdict]}`,
|
|
1626
|
+
color: verdictColor(verdict)
|
|
1627
|
+
};
|
|
1628
|
+
};
|
|
1629
|
+
const flaggedSentence = (flagged) => {
|
|
1630
|
+
const only = flagged.length === 1 ? flagged[0] : void 0;
|
|
1631
|
+
if (only !== void 0) return only.verdict === "failed" ? `! ${only.row.pkg.name}'s audit did not complete, so it was not reviewed. Confirming installs it anyway.` : `! ${only.row.pkg.name} was audited: ${verdictLabels[only.verdict]}${only.top === void 0 ? "" : ` (${only.top})`}. Confirming installs it anyway.`;
|
|
1632
|
+
const failed = flagged.filter((entry) => entry.verdict === "failed").length;
|
|
1633
|
+
const reviewed = flagged.length - failed;
|
|
1634
|
+
return `! Of these, ${[...reviewed > 0 ? [`${reviewed} ${reviewed === 1 ? "has" : "have"} an audit warning`] : [], ...failed > 0 ? [`${failed} could not be audited`] : []].join(" and ")}. Confirming installs them anyway.`;
|
|
1635
|
+
};
|
|
1636
|
+
const tone = (pending) => {
|
|
1637
|
+
if (pending.action === "uninstall") return "danger";
|
|
1638
|
+
if (pending.flagged.some((entry) => entry.verdict === "danger")) return "danger";
|
|
1639
|
+
return pending.flagged.length > 0 ? "warn" : "accent";
|
|
1640
|
+
};
|
|
1641
|
+
const signedOut = (state) => {
|
|
1642
|
+
const { setup } = state.preferences;
|
|
1643
|
+
const { catalogue } = state;
|
|
1644
|
+
if (setup === void 0 || catalogue?._tag !== "Ready") return;
|
|
1645
|
+
const choice = catalogue.value.find((entry) => entry.provider === setup.provider && entry.modelId === setup.modelId);
|
|
1646
|
+
return choice === void 0 || choice.signedIn ? void 0 : choice.providerName;
|
|
1647
|
+
};
|
|
1648
|
+
const signIn$1 = {
|
|
1649
|
+
keys: [",", "return"],
|
|
1650
|
+
hint: ",/Enter",
|
|
1651
|
+
description: "sign in"
|
|
1652
|
+
};
|
|
1653
|
+
const widest$1 = (texts) => Math.max(0, ...texts.map((text) => graphemes(text).length));
|
|
1654
|
+
const wantedWidth = 90;
|
|
1655
|
+
const ConfirmPopup = (props) => {
|
|
1656
|
+
const dimensions = useTerminalDimensions();
|
|
1657
|
+
const compact = useCompact();
|
|
1658
|
+
const pending = () => props.pending;
|
|
1659
|
+
const removing = () => pending().action === "uninstall";
|
|
1660
|
+
const unsigned = () => pending().action === "audit" || pending().action === "update" && props.state.preferences.auditFirst && pending().unauditable.length < pending().rows.length ? signedOut(props.state) : void 0;
|
|
1661
|
+
const confirmKey = () => {
|
|
1662
|
+
const verb = confirmations[pending().action].verb.toLowerCase();
|
|
1663
|
+
if (removing()) return keys.confirmRemove;
|
|
1664
|
+
if (unsigned() !== void 0 || pending().flagged.length > 0) return {
|
|
1665
|
+
keys: ["y"],
|
|
1666
|
+
hint: "y",
|
|
1667
|
+
description: `${verb} anyway`
|
|
1668
|
+
};
|
|
1669
|
+
return {
|
|
1670
|
+
...keys.confirm,
|
|
1671
|
+
hint: "y/Enter",
|
|
1672
|
+
description: verb
|
|
1673
|
+
};
|
|
1674
|
+
};
|
|
1675
|
+
const version = (row) => removing() ? row.pkg.current : `→ ${row.pkg.target ?? ""}`;
|
|
1676
|
+
const layout = createMemo(() => {
|
|
1677
|
+
const rows = flaggedFirst(pending());
|
|
1678
|
+
const marks = rows.map((row) => markOf(pending(), row));
|
|
1679
|
+
const versions = Math.min(16, widest$1(rows.map(version)));
|
|
1680
|
+
const verdicts = widest$1(marks.map((mark) => mark?.text ?? ""));
|
|
1681
|
+
const longest = widest$1(rows.map((row) => row.pkg.name));
|
|
1682
|
+
const width = Math.max(64, Math.min(8 + longest + 2 + versions + 2 + verdicts, wantedWidth));
|
|
1683
|
+
const inner = bodyWidth(width, dimensions().width) - 1;
|
|
1684
|
+
const name = Math.max(Math.min(longest, 12), Math.min(longest, inner - 6 - versions - verdicts));
|
|
1685
|
+
return {
|
|
1686
|
+
width,
|
|
1687
|
+
lines: rows.map((row, at) => ({
|
|
1688
|
+
row,
|
|
1689
|
+
version: fit(version(row), versions),
|
|
1690
|
+
mark: marks[at],
|
|
1691
|
+
room: inner - 6 - name - versions
|
|
1692
|
+
})),
|
|
1693
|
+
name
|
|
1694
|
+
};
|
|
1695
|
+
});
|
|
1696
|
+
useKeyboard((key) => {
|
|
1697
|
+
if (unsigned() !== void 0 && matches(signIn$1, key)) props.signIn();
|
|
1698
|
+
else if (matches(confirmKey(), key)) props.confirm();
|
|
1699
|
+
else if (matches(keys.cancel, key)) props.cancel();
|
|
1700
|
+
});
|
|
1701
|
+
const body = () => bodyWidth(layout().width, dimensions().width);
|
|
1702
|
+
const providers = () => [...new Set(pending().rows.map((row) => providerLabel(row.pkg.provider)))].join(", ");
|
|
1703
|
+
const explains = () => !compact();
|
|
1704
|
+
return createComponent(Popup, {
|
|
1705
|
+
get title() {
|
|
1706
|
+
return `${confirmations[pending().action].verb} ${plural(pending().rows.length, "package")}?`;
|
|
1707
|
+
},
|
|
1708
|
+
get width() {
|
|
1709
|
+
return layout().width;
|
|
1710
|
+
},
|
|
1711
|
+
get tone() {
|
|
1712
|
+
return tone(pending());
|
|
1713
|
+
},
|
|
1714
|
+
get bindings() {
|
|
1715
|
+
return [
|
|
1716
|
+
...unsigned() === void 0 ? [] : [signIn$1],
|
|
1717
|
+
confirmKey(),
|
|
1718
|
+
keys.cancel
|
|
1719
|
+
];
|
|
1720
|
+
},
|
|
1721
|
+
scrolls: true,
|
|
1722
|
+
get children() {
|
|
1723
|
+
return [
|
|
1724
|
+
(() => {
|
|
1725
|
+
var _el$ = createElement("text");
|
|
1726
|
+
setProp(_el$, "wrapMode", "none");
|
|
1727
|
+
insert(_el$, () => clip(pending().action === "audit" ? `${props.where} · read-only, nothing will be installed` : `${props.where} · ${providers()}`, body()));
|
|
1728
|
+
effect((_$p) => setProp(_el$, "fg", theme.muted, _$p));
|
|
1729
|
+
return _el$;
|
|
1730
|
+
})(),
|
|
1731
|
+
createComponent(Show, {
|
|
1732
|
+
get when() {
|
|
1733
|
+
return pending().skipped > 0;
|
|
1734
|
+
},
|
|
1735
|
+
get children() {
|
|
1736
|
+
var _el$2 = createElement("text");
|
|
1737
|
+
setProp(_el$2, "wrapMode", "word");
|
|
1738
|
+
insert(_el$2, () => `${pending().skipped} selected ${pending().skipped === 1 ? "package has" : "packages have"} no update and ${pending().skipped === 1 ? "is" : "are"} left out.`);
|
|
1739
|
+
effect((_$p) => setProp(_el$2, "fg", theme.muted, _$p));
|
|
1740
|
+
return _el$2;
|
|
1741
|
+
}
|
|
1742
|
+
}),
|
|
1743
|
+
createComponent(For, {
|
|
1744
|
+
get each() {
|
|
1745
|
+
return pending().refused;
|
|
1746
|
+
},
|
|
1747
|
+
children: (group) => (() => {
|
|
1748
|
+
var _el$10 = createElement("text");
|
|
1749
|
+
setProp(_el$10, "wrapMode", "word");
|
|
1750
|
+
insert(_el$10, () => `! Left out: ${listed(group.names)}. ${capitalized(group.reason)}.`);
|
|
1751
|
+
effect((_$p) => setProp(_el$10, "fg", theme.warn, _$p));
|
|
1752
|
+
return _el$10;
|
|
1753
|
+
})()
|
|
1754
|
+
}),
|
|
1755
|
+
(() => {
|
|
1756
|
+
var _el$3 = createElement("text");
|
|
1757
|
+
insertNode(_el$3, createTextNode(` `));
|
|
1758
|
+
return _el$3;
|
|
1759
|
+
})(),
|
|
1760
|
+
createComponent(Show, {
|
|
1761
|
+
get when() {
|
|
1762
|
+
return memo(() => !!(explains() && pending().action === "update" && props.state.preferences.auditFirst))() && pending().flagged.length + pending().unauditable.length < pending().rows.length;
|
|
1763
|
+
},
|
|
1764
|
+
get children() {
|
|
1765
|
+
var _el$5 = createElement("text");
|
|
1766
|
+
setProp(_el$5, "wrapMode", "word");
|
|
1767
|
+
insert(_el$5, () => pending().flagged.length === 0 && pending().unauditable.length === 0 ? "Each is audited first, and only those the audit finds ok are applied." : "The rest are audited first, and only those the audit finds ok are applied.");
|
|
1768
|
+
effect((_$p) => setProp(_el$5, "fg", theme.muted, _$p));
|
|
1769
|
+
return _el$5;
|
|
1770
|
+
}
|
|
1771
|
+
}),
|
|
1772
|
+
createComponent(Show, {
|
|
1773
|
+
get when() {
|
|
1774
|
+
return memo(() => !!(explains() && pending().action === "update"))() && pending().unauditable.length > 0;
|
|
1775
|
+
},
|
|
1776
|
+
get children() {
|
|
1777
|
+
var _el$6 = createElement("text");
|
|
1778
|
+
setProp(_el$6, "wrapMode", "word");
|
|
1779
|
+
insert(_el$6, () => pending().rows.some((row) => unauditedKind(row.pkg) === "runtime") ? "upup does not audit the runtime versions a project pins: confirming moves them as offered." : "upup does not audit operating-system or app updates: confirming installs them as the vendor offers them, and upup asks for your password if sudo needs it.");
|
|
1780
|
+
effect((_$p) => setProp(_el$6, "fg", theme.muted, _$p));
|
|
1781
|
+
return _el$6;
|
|
1782
|
+
}
|
|
1783
|
+
}),
|
|
1784
|
+
createComponent(Show, {
|
|
1785
|
+
get when() {
|
|
1786
|
+
return pending().flagged.length > 0;
|
|
1787
|
+
},
|
|
1788
|
+
get children() {
|
|
1789
|
+
var _el$7 = createElement("text");
|
|
1790
|
+
setProp(_el$7, "wrapMode", "word");
|
|
1791
|
+
insert(_el$7, () => flaggedSentence(pending().flagged));
|
|
1792
|
+
effect((_$p) => setProp(_el$7, "fg", theme.warn, _$p));
|
|
1793
|
+
return _el$7;
|
|
1794
|
+
}
|
|
1795
|
+
}),
|
|
1796
|
+
createComponent(Show, {
|
|
1797
|
+
get when() {
|
|
1798
|
+
return unsigned();
|
|
1799
|
+
},
|
|
1800
|
+
children: (provider) => (() => {
|
|
1801
|
+
var _el$11 = createElement("text");
|
|
1802
|
+
setProp(_el$11, "wrapMode", "word");
|
|
1803
|
+
setProp(_el$11, "marginBottom", 1);
|
|
1804
|
+
insert(_el$11, () => `! upup is not signed in to ${provider()}, so no model can read this. Press Enter to sign in.`);
|
|
1805
|
+
effect((_$p) => setProp(_el$11, "fg", theme.warn, _$p));
|
|
1806
|
+
return _el$11;
|
|
1807
|
+
})()
|
|
1808
|
+
}),
|
|
1809
|
+
createComponent(Show, {
|
|
1810
|
+
get when() {
|
|
1811
|
+
return pending().action === "audit";
|
|
1812
|
+
},
|
|
1813
|
+
get children() {
|
|
1814
|
+
return [createComponent(Show, {
|
|
1815
|
+
get when() {
|
|
1816
|
+
return explains();
|
|
1817
|
+
},
|
|
1818
|
+
get children() {
|
|
1819
|
+
var _el$8 = createElement("text");
|
|
1820
|
+
insertNode(_el$8, createTextNode(`Both versions are downloaded and verified, and the model reads what changed.`));
|
|
1821
|
+
setProp(_el$8, "wrapMode", "word");
|
|
1822
|
+
effect((_$p) => setProp(_el$8, "fg", theme.muted, _$p));
|
|
1823
|
+
return _el$8;
|
|
1824
|
+
}
|
|
1825
|
+
}), createComponent(Show, {
|
|
1826
|
+
get when() {
|
|
1827
|
+
return props.state.preferences.setup;
|
|
1828
|
+
},
|
|
1829
|
+
children: (setup) => (() => {
|
|
1830
|
+
var _el$12 = createElement("box"), _el$13 = createElement("text"), _el$15 = createElement("text");
|
|
1831
|
+
insertNode(_el$12, _el$13);
|
|
1832
|
+
insertNode(_el$12, _el$15);
|
|
1833
|
+
setProp(_el$12, "flexDirection", "row");
|
|
1834
|
+
setProp(_el$12, "height", 1);
|
|
1835
|
+
setProp(_el$12, "marginTop", 1);
|
|
1836
|
+
insertNode(_el$13, createTextNode(`Model `));
|
|
1837
|
+
setProp(_el$13, "flexShrink", 0);
|
|
1838
|
+
setProp(_el$15, "flexShrink", 0);
|
|
1839
|
+
insert(_el$15, () => clip(`${modelLabel(props.state, setup().provider, setup().modelId)} · ${setup().thinking} thinking`, body() - 7));
|
|
1840
|
+
effect((_p$) => {
|
|
1841
|
+
var _v$ = theme.muted, _v$2 = theme.text;
|
|
1842
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$13, "fg", _v$, _p$.e));
|
|
1843
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$15, "fg", _v$2, _p$.t));
|
|
1844
|
+
return _p$;
|
|
1845
|
+
}, {
|
|
1846
|
+
e: void 0,
|
|
1847
|
+
t: void 0
|
|
1848
|
+
});
|
|
1849
|
+
return _el$12;
|
|
1850
|
+
})()
|
|
1851
|
+
})];
|
|
1852
|
+
}
|
|
1853
|
+
}),
|
|
1854
|
+
createComponent(Show, {
|
|
1855
|
+
get when() {
|
|
1856
|
+
return pending().flagged.length > 0 || pending().action === "audit" || explains() && pending().action === "update" && (props.state.preferences.auditFirst || pending().unauditable.length > 0);
|
|
1857
|
+
},
|
|
1858
|
+
get children() {
|
|
1859
|
+
var _el$0 = createElement("text");
|
|
1860
|
+
insertNode(_el$0, createTextNode(` `));
|
|
1861
|
+
return _el$0;
|
|
1862
|
+
}
|
|
1863
|
+
}),
|
|
1864
|
+
createComponent(For, {
|
|
1865
|
+
get each() {
|
|
1866
|
+
return layout().lines;
|
|
1867
|
+
},
|
|
1868
|
+
children: (line) => createComponent(Segments, { get segments() {
|
|
1869
|
+
return [
|
|
1870
|
+
segment(theme.text, ` ${fitName(line.row.pkg.name, layout().name)}`),
|
|
1871
|
+
segment(theme.strong, ` ${line.version}`),
|
|
1872
|
+
...line.mark === void 0 ? [] : [segment(line.mark.color, ` ${clip(line.mark.text, line.room)}`)]
|
|
1873
|
+
];
|
|
1874
|
+
} })
|
|
1875
|
+
})
|
|
1876
|
+
];
|
|
1877
|
+
}
|
|
1878
|
+
});
|
|
1879
|
+
};
|
|
1432
1880
|
// src/tui/Report.tsx
|
|
1433
1881
|
const severityColor = (severity) => {
|
|
1434
1882
|
switch (severity) {
|
|
@@ -1453,75 +1901,69 @@ const stages = {
|
|
|
1453
1901
|
preparing: "Downloading and verifying the published artifacts…",
|
|
1454
1902
|
auditing: "The model is reading the evidence. Its steps are on the Transcript tab."
|
|
1455
1903
|
};
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
}
|
|
1472
|
-
const pieces = (text) => text.split(/(`[^`\n]+`)/u).map((piece) => piece.startsWith("`") && piece.endsWith("`") && piece.length > 2 ? {
|
|
1904
|
+
const Heading$1 = (props) => (() => {
|
|
1905
|
+
var _el$ = createElement("text");
|
|
1906
|
+
insert(_el$, () => props.children);
|
|
1907
|
+
effect((_p$) => {
|
|
1908
|
+
var _v$ = theme.muted, _v$2 = TextAttributes.BOLD;
|
|
1909
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$, "fg", _v$, _p$.e));
|
|
1910
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$, "attributes", _v$2, _p$.t));
|
|
1911
|
+
return _p$;
|
|
1912
|
+
}, {
|
|
1913
|
+
e: void 0,
|
|
1914
|
+
t: void 0
|
|
1915
|
+
});
|
|
1916
|
+
return _el$;
|
|
1917
|
+
})();
|
|
1918
|
+
const pieces = (text) => text.split(/(?<code>`[^`\n]+`)/u).map((piece) => piece.startsWith("`") && piece.endsWith("`") && piece.length > 2 ? {
|
|
1473
1919
|
code: true,
|
|
1474
1920
|
text: piece.slice(1, -1)
|
|
1475
1921
|
} : {
|
|
1476
1922
|
code: false,
|
|
1477
1923
|
text: piece
|
|
1478
1924
|
});
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
return _el$4;
|
|
1522
|
-
})();
|
|
1523
|
-
}
|
|
1524
|
-
function Done(props) {
|
|
1925
|
+
const Prose = (props) => (() => {
|
|
1926
|
+
var _el$2 = createElement("text");
|
|
1927
|
+
setProp(_el$2, "wrapMode", "word");
|
|
1928
|
+
insert(_el$2, createComponent(For, {
|
|
1929
|
+
get each() {
|
|
1930
|
+
return pieces(props.children);
|
|
1931
|
+
},
|
|
1932
|
+
children: (piece) => piece.code ? (() => {
|
|
1933
|
+
var _el$3 = createElement("span");
|
|
1934
|
+
use((node) => {
|
|
1935
|
+
createRenderEffect(() => {
|
|
1936
|
+
node.fg = theme.info;
|
|
1937
|
+
});
|
|
1938
|
+
}, _el$3);
|
|
1939
|
+
insert(_el$3, () => piece.text);
|
|
1940
|
+
return _el$3;
|
|
1941
|
+
})() : piece.text
|
|
1942
|
+
}));
|
|
1943
|
+
effect((_$p) => setProp(_el$2, "fg", props.color ?? theme.text, _$p));
|
|
1944
|
+
return _el$2;
|
|
1945
|
+
})();
|
|
1946
|
+
const Bullet = (props) => (() => {
|
|
1947
|
+
var _el$4 = createElement("box"), _el$5 = createElement("text"), _el$7 = createElement("box");
|
|
1948
|
+
insertNode(_el$4, _el$5);
|
|
1949
|
+
insertNode(_el$4, _el$7);
|
|
1950
|
+
setProp(_el$4, "flexDirection", "row");
|
|
1951
|
+
insertNode(_el$5, createTextNode(`• `));
|
|
1952
|
+
setProp(_el$5, "flexShrink", 0);
|
|
1953
|
+
setProp(_el$7, "flexGrow", 1);
|
|
1954
|
+
setProp(_el$7, "flexShrink", 1);
|
|
1955
|
+
insert(_el$7, createComponent(Prose, {
|
|
1956
|
+
get color() {
|
|
1957
|
+
return props.color;
|
|
1958
|
+
},
|
|
1959
|
+
get children() {
|
|
1960
|
+
return props.children;
|
|
1961
|
+
}
|
|
1962
|
+
}));
|
|
1963
|
+
effect((_$p) => setProp(_el$5, "fg", theme.muted, _$p));
|
|
1964
|
+
return _el$4;
|
|
1965
|
+
})();
|
|
1966
|
+
const Done = (props) => {
|
|
1525
1967
|
const report = () => props.result.report;
|
|
1526
1968
|
return (() => {
|
|
1527
1969
|
var _el$8 = createElement("box"), _el$9 = createElement("box"), _el$0 = createElement("text"), _el$1 = createElement("text"), _el$10 = createElement("text"), _el$12 = createElement("text"), _el$16 = createElement("text"), _el$18 = createElement("box"), _el$19 = createElement("text");
|
|
@@ -1692,9 +2134,9 @@ function Done(props) {
|
|
|
1692
2134
|
});
|
|
1693
2135
|
return _el$8;
|
|
1694
2136
|
})();
|
|
1695
|
-
}
|
|
2137
|
+
};
|
|
1696
2138
|
const signIn = (issue) => /not configured|sign[ -]?in|log ?in|api key|unauthori[sz]ed|credential|\b401\b|\b403\b/iu.test(issue);
|
|
1697
|
-
|
|
2139
|
+
const Report = (props) => {
|
|
1698
2140
|
const running = () => props.audit?._tag === "Running" ? props.audit : void 0;
|
|
1699
2141
|
const result = () => props.audit?._tag === "Done" ? props.audit.result : void 0;
|
|
1700
2142
|
const reported = () => {
|
|
@@ -1705,6 +2147,11 @@ function Report(props) {
|
|
|
1705
2147
|
const done = result();
|
|
1706
2148
|
return done?._tag === "Failed" ? done : void 0;
|
|
1707
2149
|
};
|
|
2150
|
+
const unaudited = () => {
|
|
2151
|
+
if (props.unauditable !== void 0) return `Nothing to audit: ${props.unauditable}.`;
|
|
2152
|
+
if (props.installed === true) return "This update was installed without an audit, so there is no report.";
|
|
2153
|
+
return "Not audited yet. Press r to have a model review this update.";
|
|
2154
|
+
};
|
|
1708
2155
|
return createComponent(Switch, {
|
|
1709
2156
|
get fallback() {
|
|
1710
2157
|
return createComponent(Prose, {
|
|
@@ -1712,7 +2159,7 @@ function Report(props) {
|
|
|
1712
2159
|
return theme.muted;
|
|
1713
2160
|
},
|
|
1714
2161
|
get children() {
|
|
1715
|
-
return
|
|
2162
|
+
return unaudited();
|
|
1716
2163
|
}
|
|
1717
2164
|
});
|
|
1718
2165
|
},
|
|
@@ -1796,7 +2243,7 @@ function Report(props) {
|
|
|
1796
2243
|
];
|
|
1797
2244
|
}
|
|
1798
2245
|
});
|
|
1799
|
-
}
|
|
2246
|
+
};
|
|
1800
2247
|
// src/tui/Transcript.tsx
|
|
1801
2248
|
const color = (kind) => {
|
|
1802
2249
|
switch (kind) {
|
|
@@ -1807,9 +2254,9 @@ const color = (kind) => {
|
|
|
1807
2254
|
case "retry": return theme.warn;
|
|
1808
2255
|
}
|
|
1809
2256
|
};
|
|
1810
|
-
const heading = /^\*\*(
|
|
1811
|
-
|
|
1812
|
-
const title = () => heading.exec(props.text.trim())?.[
|
|
2257
|
+
const heading = /^\*\*(?<title>.+?)\*\*\s*/u;
|
|
2258
|
+
const Thought = (props) => {
|
|
2259
|
+
const title = () => heading.exec(props.text.trim())?.groups?.["title"];
|
|
1813
2260
|
const body = () => props.text.trim().replace(heading, "").replaceAll("**", "").trim();
|
|
1814
2261
|
return (() => {
|
|
1815
2262
|
var _el$ = createElement("box");
|
|
@@ -1857,12 +2304,12 @@ function Thought(props) {
|
|
|
1857
2304
|
effect((_$p) => setProp(_el$, "marginTop", title() === void 0 ? 0 : 1, _$p));
|
|
1858
2305
|
return _el$;
|
|
1859
2306
|
})();
|
|
1860
|
-
}
|
|
1861
|
-
|
|
2307
|
+
};
|
|
2308
|
+
const Tool = (props) => {
|
|
1862
2309
|
const space = () => props.text.indexOf(" ");
|
|
1863
2310
|
const verb = () => space() < 0 ? props.text : props.text.slice(0, space());
|
|
1864
2311
|
const rest = () => space() < 0 ? "" : props.text.slice(space() + 1);
|
|
1865
|
-
const range = () => /^(
|
|
2312
|
+
const range = () => /^(?<path>.*?)(?<bytes>\s+bytes \S+)$/u.exec(rest());
|
|
1866
2313
|
return createComponent(Show, {
|
|
1867
2314
|
get when() {
|
|
1868
2315
|
return verb() !== "submit_report";
|
|
@@ -1894,7 +2341,7 @@ function Tool(props) {
|
|
|
1894
2341
|
insert(_el$5, () => verb().padEnd(8));
|
|
1895
2342
|
setProp(_el$6, "flexShrink", 1);
|
|
1896
2343
|
setProp(_el$6, "wrapMode", "char");
|
|
1897
|
-
insert(_el$6, () => range()?.[
|
|
2344
|
+
insert(_el$6, () => range()?.groups?.["path"] ?? rest());
|
|
1898
2345
|
insert(_el$4, createComponent(Show, {
|
|
1899
2346
|
get when() {
|
|
1900
2347
|
return range();
|
|
@@ -1902,7 +2349,7 @@ function Tool(props) {
|
|
|
1902
2349
|
children: (found) => (() => {
|
|
1903
2350
|
var _el$0 = createElement("text");
|
|
1904
2351
|
setProp(_el$0, "flexShrink", 0);
|
|
1905
|
-
insert(_el$0, () => found()[
|
|
2352
|
+
insert(_el$0, () => found().groups?.["bytes"]);
|
|
1906
2353
|
effect((_$p) => setProp(_el$0, "fg", theme.muted, _$p));
|
|
1907
2354
|
return _el$0;
|
|
1908
2355
|
})()
|
|
@@ -1931,46 +2378,48 @@ function Tool(props) {
|
|
|
1931
2378
|
return _el$4;
|
|
1932
2379
|
}
|
|
1933
2380
|
});
|
|
1934
|
-
}
|
|
1935
|
-
const runs = (entries) =>
|
|
1936
|
-
const
|
|
1937
|
-
|
|
1938
|
-
last
|
|
1939
|
-
|
|
2381
|
+
};
|
|
2382
|
+
const runs = (entries) => {
|
|
2383
|
+
const list = [];
|
|
2384
|
+
for (const entry of entries) {
|
|
2385
|
+
const last = list.at(-1);
|
|
2386
|
+
if (last !== void 0 && entry.kind === "tool" && last.entry.kind === "tool" && last.entry.text === entry.text) {
|
|
2387
|
+
last.times += 1;
|
|
2388
|
+
continue;
|
|
2389
|
+
}
|
|
2390
|
+
list.push({
|
|
2391
|
+
entry,
|
|
2392
|
+
times: 1
|
|
2393
|
+
});
|
|
1940
2394
|
}
|
|
1941
|
-
return
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
get
|
|
1952
|
-
return
|
|
2395
|
+
return list;
|
|
2396
|
+
};
|
|
2397
|
+
const Lines = (props) => (() => {
|
|
2398
|
+
var _el$1 = createElement("box");
|
|
2399
|
+
setProp(_el$1, "flexDirection", "column");
|
|
2400
|
+
insert(_el$1, createComponent(For, {
|
|
2401
|
+
get each() {
|
|
2402
|
+
return runs(props.entries);
|
|
2403
|
+
},
|
|
2404
|
+
children: (run) => run.entry.kind === "tool" ? createComponent(Tool, {
|
|
2405
|
+
get text() {
|
|
2406
|
+
return run.entry.text;
|
|
1953
2407
|
},
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
}));
|
|
1970
|
-
return _el$1;
|
|
1971
|
-
})();
|
|
1972
|
-
}
|
|
1973
|
-
function Transcript(props) {
|
|
2408
|
+
get times() {
|
|
2409
|
+
return run.times;
|
|
2410
|
+
}
|
|
2411
|
+
}) : createComponent(Thought, {
|
|
2412
|
+
get text() {
|
|
2413
|
+
return run.entry.text;
|
|
2414
|
+
},
|
|
2415
|
+
get kind() {
|
|
2416
|
+
return run.entry.kind;
|
|
2417
|
+
}
|
|
2418
|
+
})
|
|
2419
|
+
}));
|
|
2420
|
+
return _el$1;
|
|
2421
|
+
})();
|
|
2422
|
+
const Transcript = (props) => {
|
|
1974
2423
|
const ready = () => props.stored?._tag === "Ready" ? props.stored.value : void 0;
|
|
1975
2424
|
const unavailable = () => props.stored?._tag === "Unavailable" ? props.stored.issue : void 0;
|
|
1976
2425
|
return createComponent(Switch, {
|
|
@@ -2006,19 +2455,19 @@ function Transcript(props) {
|
|
|
2006
2455
|
},
|
|
2007
2456
|
get fallback() {
|
|
2008
2457
|
return (() => {
|
|
2009
|
-
var _el$
|
|
2010
|
-
insertNode(_el$
|
|
2011
|
-
effect((_$p) => setProp(_el$
|
|
2012
|
-
return _el$
|
|
2458
|
+
var _el$22 = createElement("text");
|
|
2459
|
+
insertNode(_el$22, createTextNode(`✗ The audit failed before the model started.`));
|
|
2460
|
+
effect((_$p) => setProp(_el$22, "fg", theme.danger, _$p));
|
|
2461
|
+
return _el$22;
|
|
2013
2462
|
})();
|
|
2014
2463
|
},
|
|
2015
2464
|
get children() {
|
|
2016
|
-
var _el$18 = createElement("box"), _el$19 = createElement("text");
|
|
2465
|
+
var _el$18 = createElement("box"), _el$19 = createElement("text"), _el$20 = createTextNode(` Preparing the evidence; the model starts next…`);
|
|
2017
2466
|
insertNode(_el$18, _el$19);
|
|
2018
2467
|
setProp(_el$18, "flexDirection", "row");
|
|
2019
2468
|
setProp(_el$18, "height", 1);
|
|
2020
2469
|
insert(_el$18, createComponent(Spinner, {}), _el$19);
|
|
2021
|
-
insertNode(_el$19,
|
|
2470
|
+
insertNode(_el$19, _el$20);
|
|
2022
2471
|
effect((_$p) => setProp(_el$19, "fg", theme.muted, _$p));
|
|
2023
2472
|
return _el$18;
|
|
2024
2473
|
}
|
|
@@ -2068,11 +2517,11 @@ function Transcript(props) {
|
|
|
2068
2517
|
return unavailable();
|
|
2069
2518
|
},
|
|
2070
2519
|
children: (issue) => (() => {
|
|
2071
|
-
var _el$
|
|
2072
|
-
setProp(_el$
|
|
2073
|
-
insert(_el$
|
|
2074
|
-
effect((_$p) => setProp(_el$
|
|
2075
|
-
return _el$
|
|
2520
|
+
var _el$24 = createElement("text");
|
|
2521
|
+
setProp(_el$24, "wrapMode", "word");
|
|
2522
|
+
insert(_el$24, () => `Transcript unavailable: ${issue()}`);
|
|
2523
|
+
effect((_$p) => setProp(_el$24, "fg", theme.muted, _$p));
|
|
2524
|
+
return _el$24;
|
|
2076
2525
|
})()
|
|
2077
2526
|
}),
|
|
2078
2527
|
createComponent(Match, {
|
|
@@ -2086,43 +2535,41 @@ function Transcript(props) {
|
|
|
2086
2535
|
];
|
|
2087
2536
|
}
|
|
2088
2537
|
});
|
|
2089
|
-
}
|
|
2538
|
+
};
|
|
2090
2539
|
// src/tui/Details.tsx
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
});
|
|
2120
|
-
}
|
|
2540
|
+
const Fact = (props) => createComponent(Show, {
|
|
2541
|
+
get when() {
|
|
2542
|
+
return memo(() => props.value !== void 0)() && props.value !== "";
|
|
2543
|
+
},
|
|
2544
|
+
get children() {
|
|
2545
|
+
var _el$ = createElement("box"), _el$2 = createElement("text"), _el$3 = createElement("text");
|
|
2546
|
+
insertNode(_el$, _el$2);
|
|
2547
|
+
insertNode(_el$, _el$3);
|
|
2548
|
+
setProp(_el$, "flexDirection", "row");
|
|
2549
|
+
setProp(_el$2, "width", 13);
|
|
2550
|
+
setProp(_el$2, "flexShrink", 0);
|
|
2551
|
+
insert(_el$2, () => props.label);
|
|
2552
|
+
setProp(_el$3, "flexGrow", 1);
|
|
2553
|
+
setProp(_el$3, "flexShrink", 1);
|
|
2554
|
+
setProp(_el$3, "wrapMode", "word");
|
|
2555
|
+
insert(_el$3, () => props.value ?? "");
|
|
2556
|
+
effect((_p$) => {
|
|
2557
|
+
var _v$ = theme.muted, _v$2 = theme.text;
|
|
2558
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$2, "fg", _v$, _p$.e));
|
|
2559
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$3, "fg", _v$2, _p$.t));
|
|
2560
|
+
return _p$;
|
|
2561
|
+
}, {
|
|
2562
|
+
e: void 0,
|
|
2563
|
+
t: void 0
|
|
2564
|
+
});
|
|
2565
|
+
return _el$;
|
|
2566
|
+
}
|
|
2567
|
+
});
|
|
2121
2568
|
const described = (about) => about?._tag === "Ready" ? about.value.description : void 0;
|
|
2122
2569
|
const months = "Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" ");
|
|
2123
2570
|
const day = (timestamp) => {
|
|
2124
2571
|
const at = new Date(timestamp ?? "");
|
|
2125
|
-
if (Number.isNaN(at.getTime())) return
|
|
2572
|
+
if (Number.isNaN(at.getTime())) return;
|
|
2126
2573
|
const year = at.getFullYear();
|
|
2127
2574
|
const shown = `${months[at.getMonth()] ?? ""} ${at.getDate()}`;
|
|
2128
2575
|
return year === (/* @__PURE__ */ new Date()).getFullYear() ? shown : `${shown} ${year}`;
|
|
@@ -2148,7 +2595,7 @@ const releases = (metadata, versions) => {
|
|
|
2148
2595
|
const apart = gap === void 0 || Number.isNaN(gap) || gap < 0 ? [] : [gap === 0 ? "released the same day" : `released ${gap} day${gap === 1 ? "" : "s"} apart`];
|
|
2149
2596
|
return dated.length === 0 ? void 0 : [...dated.toReversed(), ...apart].join("\n");
|
|
2150
2597
|
};
|
|
2151
|
-
|
|
2598
|
+
const Registry = (props) => {
|
|
2152
2599
|
const versions = () => [props.current, ...props.target === void 0 ? [] : [props.target]];
|
|
2153
2600
|
const ready = () => props.about?._tag === "Ready" ? props.about.value : void 0;
|
|
2154
2601
|
const unavailable = () => props.about?._tag === "Unavailable" ? props.about.issue : void 0;
|
|
@@ -2161,7 +2608,7 @@ function Registry(props) {
|
|
|
2161
2608
|
get children() {
|
|
2162
2609
|
var _el$4 = createElement("text");
|
|
2163
2610
|
insertNode(_el$4, createTextNode(`Looking up the registry…`));
|
|
2164
|
-
effect((_$p) => setProp(_el$4, "fg", theme.
|
|
2611
|
+
effect((_$p) => setProp(_el$4, "fg", theme.muted, _$p));
|
|
2165
2612
|
return _el$4;
|
|
2166
2613
|
}
|
|
2167
2614
|
}),
|
|
@@ -2173,7 +2620,7 @@ function Registry(props) {
|
|
|
2173
2620
|
var _el$6 = createElement("text");
|
|
2174
2621
|
setProp(_el$6, "wrapMode", "word");
|
|
2175
2622
|
insert(_el$6, () => `Registry details unavailable: ${issue()}`);
|
|
2176
|
-
effect((_$p) => setProp(_el$6, "fg", theme.
|
|
2623
|
+
effect((_$p) => setProp(_el$6, "fg", theme.muted, _$p));
|
|
2177
2624
|
return _el$6;
|
|
2178
2625
|
})()
|
|
2179
2626
|
}),
|
|
@@ -2258,9 +2705,9 @@ function Registry(props) {
|
|
|
2258
2705
|
})
|
|
2259
2706
|
];
|
|
2260
2707
|
} });
|
|
2261
|
-
}
|
|
2708
|
+
};
|
|
2262
2709
|
const badge = (tab, audit) => {
|
|
2263
|
-
if (tab !== "report" || audit === void 0) return
|
|
2710
|
+
if (tab !== "report" || audit === void 0) return;
|
|
2264
2711
|
if (audit._tag === "Running") return {
|
|
2265
2712
|
text: "…",
|
|
2266
2713
|
color: theme.accent
|
|
@@ -2269,14 +2716,14 @@ const badge = (tab, audit) => {
|
|
|
2269
2716
|
text: "✗",
|
|
2270
2717
|
color: theme.danger
|
|
2271
2718
|
};
|
|
2272
|
-
const verdict = audit.result.report
|
|
2719
|
+
const { verdict } = audit.result.report;
|
|
2273
2720
|
return {
|
|
2274
2721
|
text: verdictIcons[verdict],
|
|
2275
2722
|
color: verdictColor(verdict)
|
|
2276
2723
|
};
|
|
2277
2724
|
};
|
|
2278
|
-
|
|
2279
|
-
const change = () => props.target === void 0 ? void 0 : bump(props.current, props.target);
|
|
2725
|
+
const Version = (props) => {
|
|
2726
|
+
const change = () => props.target === void 0 ? void 0 : bump(props.current, props.target, props.ecosystem);
|
|
2280
2727
|
return (() => {
|
|
2281
2728
|
var _el$10 = createElement("box"), _el$11 = createElement("text"), _el$12 = createElement("text");
|
|
2282
2729
|
insertNode(_el$10, _el$11);
|
|
@@ -2316,7 +2763,7 @@ function Version(props) {
|
|
|
2316
2763
|
}
|
|
2317
2764
|
}), null);
|
|
2318
2765
|
effect((_p$) => {
|
|
2319
|
-
var _v$5 = theme.
|
|
2766
|
+
var _v$5 = theme.muted, _v$6 = theme.text, _v$7 = theme.strong, _v$8 = TextAttributes.BOLD;
|
|
2320
2767
|
_v$5 !== _p$.e && (_p$.e = setProp(_el$14, "fg", _v$5, _p$.e));
|
|
2321
2768
|
_v$6 !== _p$.t && (_p$.t = setProp(_el$16, "fg", _v$6, _p$.t));
|
|
2322
2769
|
_v$7 !== _p$.a && (_p$.a = setProp(_el$17, "fg", _v$7, _p$.a));
|
|
@@ -2334,7 +2781,7 @@ function Version(props) {
|
|
|
2334
2781
|
setProp(_el$12, "flexShrink", 0);
|
|
2335
2782
|
insert(_el$12, () => ` · ${props.provider}`);
|
|
2336
2783
|
effect((_p$) => {
|
|
2337
|
-
var _v$3 = theme.muted, _v$4 = theme.
|
|
2784
|
+
var _v$3 = theme.muted, _v$4 = theme.muted;
|
|
2338
2785
|
_v$3 !== _p$.e && (_p$.e = setProp(_el$11, "fg", _v$3, _p$.e));
|
|
2339
2786
|
_v$4 !== _p$.t && (_p$.t = setProp(_el$12, "fg", _v$4, _p$.t));
|
|
2340
2787
|
return _p$;
|
|
@@ -2344,7 +2791,7 @@ function Version(props) {
|
|
|
2344
2791
|
});
|
|
2345
2792
|
return _el$10;
|
|
2346
2793
|
})();
|
|
2347
|
-
}
|
|
2794
|
+
};
|
|
2348
2795
|
const headerLines = 5;
|
|
2349
2796
|
const tabs = [
|
|
2350
2797
|
"about",
|
|
@@ -2359,491 +2806,516 @@ const tabTitles = {
|
|
|
2359
2806
|
transcript: "Transcript"
|
|
2360
2807
|
};
|
|
2361
2808
|
const storedTranscript = (audit) => audit?._tag === "Done" && audit.result._tag === "Reported" ? audit.result.file : void 0;
|
|
2362
|
-
const liveTranscript = (audit) =>
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
|
|
2378
|
-
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
|
|
2384
|
-
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
}
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2454
|
-
|
|
2455
|
-
|
|
2456
|
-
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
2472
|
-
|
|
2473
|
-
|
|
2474
|
-
|
|
2475
|
-
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
})
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2809
|
+
const liveTranscript = (audit) => {
|
|
2810
|
+
if (audit?._tag === "Running") return audit.transcript;
|
|
2811
|
+
if (audit?._tag === "Done" && audit.result._tag === "Failed") return audit.result.transcript;
|
|
2812
|
+
};
|
|
2813
|
+
const Details = (props) => (() => {
|
|
2814
|
+
var _el$19 = createElement("box");
|
|
2815
|
+
setProp(_el$19, "flexDirection", "column");
|
|
2816
|
+
setProp(_el$19, "flexGrow", 1);
|
|
2817
|
+
setProp(_el$19, "paddingLeft", 1);
|
|
2818
|
+
setProp(_el$19, "paddingRight", 1);
|
|
2819
|
+
insert(_el$19, createComponent(Show, {
|
|
2820
|
+
get when() {
|
|
2821
|
+
return props.row;
|
|
2822
|
+
},
|
|
2823
|
+
get fallback() {
|
|
2824
|
+
return (() => {
|
|
2825
|
+
var _el$20 = createElement("text");
|
|
2826
|
+
insertNode(_el$20, createTextNode(` `));
|
|
2827
|
+
return _el$20;
|
|
2828
|
+
})();
|
|
2829
|
+
},
|
|
2830
|
+
children: (row) => {
|
|
2831
|
+
const pkg = () => row().pkg;
|
|
2832
|
+
const reviewed = () => auditedAs(props.state, pkg());
|
|
2833
|
+
const notices = () => props.state.providers.flatMap((entry) => entry.notices).filter((notice) => notice.rowKey === row().key);
|
|
2834
|
+
const outcome = () => props.state.outcomes[row().key];
|
|
2835
|
+
const gone = () => props.state.removed[row().key] !== void 0;
|
|
2836
|
+
const nothing = () => gone() ? "it was removed" : unauditable(reviewed());
|
|
2837
|
+
const failure = () => {
|
|
2838
|
+
const latest = outcome();
|
|
2839
|
+
if (latest?._tag !== "Failed" && latest?._tag !== "Unexpected") return;
|
|
2840
|
+
const what = props.state.actions[row().key] === "uninstall" ? "Removal" : "Update";
|
|
2841
|
+
const told = describeOutcome(latest);
|
|
2842
|
+
const whole = `✗ ${what} ${told.charAt(0).toLowerCase()}${told.slice(1)}`;
|
|
2843
|
+
const room = props.width - 4;
|
|
2844
|
+
if (props.tab === "about" || graphemes(whole).length <= room) return whole;
|
|
2845
|
+
return `${graphemes(whole).slice(0, Math.max(10, room - 17)).join("").trimEnd()} … whole on About`;
|
|
2846
|
+
};
|
|
2847
|
+
const installedNote = () => {
|
|
2848
|
+
if (gone()) return "– Removed this week · there is nothing to do";
|
|
2849
|
+
if (reviewed() === pkg()) return " ";
|
|
2850
|
+
if (auditOf(props.state, pkg()) === void 0) return `Updated from ${reviewed().current} · not audited`;
|
|
2851
|
+
return `Updated from ${reviewed().current} · audited before installing`;
|
|
2852
|
+
};
|
|
2853
|
+
const updateLabel = (latest) => {
|
|
2854
|
+
if (props.state.actions[row().key] === "uninstall") return "Removal";
|
|
2855
|
+
if (latest._tag === "Completed") return "Updated";
|
|
2856
|
+
return "Update";
|
|
2857
|
+
};
|
|
2858
|
+
const about = () => props.state.about[aboutKey(pkg())];
|
|
2859
|
+
const reading = () => {
|
|
2860
|
+
const key = auditKey(reviewed(), props.state.mode);
|
|
2861
|
+
const loaded = key === void 0 ? void 0 : props.state.changes[key];
|
|
2862
|
+
if (loaded?._tag !== "Ready") return;
|
|
2863
|
+
const list = files(loaded.value);
|
|
2864
|
+
const file = list[Math.min(props.file, list.length - 1)];
|
|
2865
|
+
if (file === void 0 || list.length < 2) return;
|
|
2866
|
+
return `${position(list, props.file)} · ${file.section.path}`;
|
|
2867
|
+
};
|
|
2868
|
+
const declaration = () => {
|
|
2869
|
+
const declared = pkg().declaration;
|
|
2870
|
+
return declared === void 0 ? void 0 : `${declared.manifest} (${declared.section})`;
|
|
2871
|
+
};
|
|
2872
|
+
return (() => {
|
|
2873
|
+
var _el$22 = createElement("box"), _el$23 = createElement("box"), _el$24 = createElement("text"), _el$25 = createElement("text"), _el$26 = createElement("box"), _el$27 = createElement("text"), _el$28 = createElement("scrollbox");
|
|
2874
|
+
insertNode(_el$22, _el$23);
|
|
2875
|
+
insertNode(_el$22, _el$25);
|
|
2876
|
+
insertNode(_el$22, _el$26);
|
|
2877
|
+
insertNode(_el$22, _el$27);
|
|
2878
|
+
insertNode(_el$22, _el$28);
|
|
2879
|
+
setProp(_el$22, "flexDirection", "column");
|
|
2880
|
+
setProp(_el$22, "flexGrow", 1);
|
|
2881
|
+
insertNode(_el$23, _el$24);
|
|
2882
|
+
setProp(_el$23, "flexDirection", "row");
|
|
2883
|
+
setProp(_el$23, "height", 1);
|
|
2884
|
+
setProp(_el$23, "flexShrink", 0);
|
|
2885
|
+
setProp(_el$24, "wrapMode", "none");
|
|
2886
|
+
setProp(_el$24, "truncate", true);
|
|
2887
|
+
setProp(_el$24, "flexShrink", 1);
|
|
2888
|
+
insert(_el$24, () => pkg().name);
|
|
2889
|
+
insert(_el$23, createComponent(Show, {
|
|
2890
|
+
get when() {
|
|
2891
|
+
return props.position;
|
|
2892
|
+
},
|
|
2893
|
+
children: (rowPosition) => (() => {
|
|
2894
|
+
var _el$32 = createElement("text");
|
|
2895
|
+
setProp(_el$32, "flexShrink", 0);
|
|
2896
|
+
insert(_el$32, () => ` ${rowPosition()}`);
|
|
2897
|
+
effect((_$p) => setProp(_el$32, "fg", theme.muted, _$p));
|
|
2898
|
+
return _el$32;
|
|
2899
|
+
})()
|
|
2900
|
+
}), null);
|
|
2901
|
+
insert(_el$22, createComponent(Version, {
|
|
2902
|
+
get current() {
|
|
2903
|
+
return pkg().current;
|
|
2904
|
+
},
|
|
2905
|
+
get target() {
|
|
2906
|
+
return pkg().target;
|
|
2907
|
+
},
|
|
2908
|
+
get ecosystem() {
|
|
2909
|
+
return pkg().ecosystem;
|
|
2910
|
+
},
|
|
2911
|
+
get provider() {
|
|
2912
|
+
return providerLabel(pkg().provider);
|
|
2913
|
+
}
|
|
2914
|
+
}), _el$25);
|
|
2915
|
+
setProp(_el$25, "flexShrink", 0);
|
|
2916
|
+
setProp(_el$25, "wrapMode", "none");
|
|
2917
|
+
setProp(_el$25, "truncate", true);
|
|
2918
|
+
insert(_el$25, () => failure() ?? installedNote());
|
|
2919
|
+
setProp(_el$26, "flexDirection", "row");
|
|
2920
|
+
setProp(_el$26, "height", 1);
|
|
2921
|
+
setProp(_el$26, "flexShrink", 0);
|
|
2922
|
+
insert(_el$26, createComponent(For, {
|
|
2923
|
+
each: tabs,
|
|
2924
|
+
children: (tab) => (() => {
|
|
2925
|
+
var _el$33 = createElement("box"), _el$34 = createElement("text"), _el$35 = createElement("text");
|
|
2926
|
+
insertNode(_el$33, _el$34);
|
|
2927
|
+
insertNode(_el$33, _el$35);
|
|
2928
|
+
setProp(_el$33, "flexDirection", "row");
|
|
2929
|
+
setProp(_el$33, "flexShrink", 0);
|
|
2930
|
+
setProp(_el$33, "marginRight", 1);
|
|
2931
|
+
setProp(_el$34, "flexShrink", 0);
|
|
2932
|
+
insert(_el$34, () => ` ${tabTitles[tab]}${badge(tab, auditOf(props.state, pkg())) === void 0 ? "" : " "}`);
|
|
2933
|
+
insert(_el$33, createComponent(Show, {
|
|
2934
|
+
get when() {
|
|
2935
|
+
return badge(tab, auditOf(props.state, pkg()));
|
|
2936
|
+
},
|
|
2937
|
+
children: (shown) => (() => {
|
|
2938
|
+
var _el$37 = createElement("text");
|
|
2939
|
+
setProp(_el$37, "flexShrink", 0);
|
|
2940
|
+
insert(_el$37, () => shown().text);
|
|
2941
|
+
effect((_p$) => {
|
|
2942
|
+
var _v$18 = tab === props.tab ? theme.onAccent : shown().color, _v$19 = tab === props.tab ? theme.accent : theme.none;
|
|
2943
|
+
_v$18 !== _p$.e && (_p$.e = setProp(_el$37, "fg", _v$18, _p$.e));
|
|
2944
|
+
_v$19 !== _p$.t && (_p$.t = setProp(_el$37, "bg", _v$19, _p$.t));
|
|
2945
|
+
return _p$;
|
|
2946
|
+
}, {
|
|
2947
|
+
e: void 0,
|
|
2948
|
+
t: void 0
|
|
2949
|
+
});
|
|
2950
|
+
return _el$37;
|
|
2951
|
+
})()
|
|
2952
|
+
}), _el$35);
|
|
2953
|
+
insertNode(_el$35, createTextNode(` `));
|
|
2954
|
+
setProp(_el$35, "flexShrink", 0);
|
|
2955
|
+
effect((_p$) => {
|
|
2956
|
+
var _v$14 = tab === props.tab ? theme.onAccent : theme.muted, _v$15 = tab === props.tab ? theme.accent : theme.none, _v$16 = tab === props.tab ? TextAttributes.BOLD : TextAttributes.NONE, _v$17 = tab === props.tab ? theme.accent : theme.none;
|
|
2957
|
+
_v$14 !== _p$.e && (_p$.e = setProp(_el$34, "fg", _v$14, _p$.e));
|
|
2958
|
+
_v$15 !== _p$.t && (_p$.t = setProp(_el$34, "bg", _v$15, _p$.t));
|
|
2959
|
+
_v$16 !== _p$.a && (_p$.a = setProp(_el$34, "attributes", _v$16, _p$.a));
|
|
2960
|
+
_v$17 !== _p$.o && (_p$.o = setProp(_el$35, "bg", _v$17, _p$.o));
|
|
2961
|
+
return _p$;
|
|
2962
|
+
}, {
|
|
2963
|
+
e: void 0,
|
|
2964
|
+
t: void 0,
|
|
2965
|
+
a: void 0,
|
|
2966
|
+
o: void 0
|
|
2967
|
+
});
|
|
2968
|
+
return _el$33;
|
|
2969
|
+
})()
|
|
2970
|
+
}));
|
|
2971
|
+
setProp(_el$27, "flexShrink", 0);
|
|
2972
|
+
setProp(_el$27, "wrapMode", "none");
|
|
2973
|
+
setProp(_el$27, "truncate", true);
|
|
2974
|
+
insert(_el$27, (() => {
|
|
2975
|
+
var _c$ = memo(() => props.tab === "changes");
|
|
2976
|
+
return () => _c$() ? reading() ?? " " : " ";
|
|
2977
|
+
})());
|
|
2978
|
+
var _ref$ = props.scroller;
|
|
2979
|
+
typeof _ref$ === "function" ? use(_ref$, _el$28) : props.scroller = _el$28;
|
|
2980
|
+
setProp(_el$28, "contentOptions", { paddingRight: 2 });
|
|
2981
|
+
setProp(_el$28, "stickyStart", "bottom");
|
|
2982
|
+
insert(_el$28, createComponent(Switch, { get children() {
|
|
2983
|
+
return [
|
|
2984
|
+
createComponent(Match, {
|
|
2985
|
+
get when() {
|
|
2986
|
+
return props.tab === "about";
|
|
2987
|
+
},
|
|
2988
|
+
get children() {
|
|
2989
|
+
var _el$29 = createElement("box"), _el$30 = createElement("text");
|
|
2990
|
+
insertNode(_el$29, _el$30);
|
|
2991
|
+
setProp(_el$29, "flexDirection", "column");
|
|
2992
|
+
insert(_el$29, createComponent(Show, {
|
|
2993
|
+
get when() {
|
|
2994
|
+
return pkg().description ?? described(about());
|
|
2995
|
+
},
|
|
2996
|
+
children: (description) => (() => {
|
|
2997
|
+
var _el$38 = createElement("text");
|
|
2998
|
+
setProp(_el$38, "wrapMode", "word");
|
|
2999
|
+
insert(_el$38, description);
|
|
3000
|
+
effect((_$p) => setProp(_el$38, "fg", theme.text, _$p));
|
|
3001
|
+
return _el$38;
|
|
3002
|
+
})()
|
|
3003
|
+
}), _el$30);
|
|
3004
|
+
insertNode(_el$30, createTextNode(` `));
|
|
3005
|
+
insert(_el$29, createComponent(Fact, {
|
|
3006
|
+
label: "Provider",
|
|
3007
|
+
get value() {
|
|
3008
|
+
return providerLabel(pkg().provider);
|
|
3009
|
+
}
|
|
3010
|
+
}), null);
|
|
3011
|
+
insert(_el$29, createComponent(Fact, {
|
|
3012
|
+
label: "Ecosystem",
|
|
3013
|
+
get value() {
|
|
3014
|
+
return pkg().ecosystem;
|
|
3015
|
+
}
|
|
3016
|
+
}), null);
|
|
3017
|
+
insert(_el$29, createComponent(Fact, {
|
|
3018
|
+
label: "Artifact",
|
|
3019
|
+
get value() {
|
|
3020
|
+
return pkg().artifact;
|
|
3021
|
+
}
|
|
3022
|
+
}), null);
|
|
3023
|
+
insert(_el$29, createComponent(Fact, {
|
|
3024
|
+
label: "Runtime",
|
|
3025
|
+
get value() {
|
|
3026
|
+
return pkg().runtime;
|
|
3027
|
+
}
|
|
3028
|
+
}), null);
|
|
3029
|
+
insert(_el$29, createComponent(Fact, {
|
|
3030
|
+
label: "Declared in",
|
|
3031
|
+
get value() {
|
|
3032
|
+
return declaration();
|
|
3033
|
+
}
|
|
3034
|
+
}), null);
|
|
3035
|
+
insert(_el$29, createComponent(Fact, {
|
|
3036
|
+
label: "Requires",
|
|
3037
|
+
get value() {
|
|
3038
|
+
return pkg().requires?.join(", ");
|
|
3039
|
+
}
|
|
3040
|
+
}), null);
|
|
3041
|
+
insert(_el$29, createComponent(Fact, {
|
|
3042
|
+
label: "Required by",
|
|
3043
|
+
get value() {
|
|
3044
|
+
return pkg().requiredBy?.join(", ");
|
|
3045
|
+
}
|
|
3046
|
+
}), null);
|
|
3047
|
+
insert(_el$29, createComponent(Show, {
|
|
3048
|
+
get when() {
|
|
3049
|
+
return outcome();
|
|
3050
|
+
},
|
|
3051
|
+
children: (latest) => createComponent(Fact, {
|
|
3052
|
+
get label() {
|
|
3053
|
+
return updateLabel(latest());
|
|
2531
3054
|
},
|
|
2532
|
-
children: (description) => (() => {
|
|
2533
|
-
var _el$38 = createElement("text");
|
|
2534
|
-
setProp(_el$38, "wrapMode", "word");
|
|
2535
|
-
insert(_el$38, description);
|
|
2536
|
-
effect((_$p) => setProp(_el$38, "fg", theme.text, _$p));
|
|
2537
|
-
return _el$38;
|
|
2538
|
-
})()
|
|
2539
|
-
}), _el$30);
|
|
2540
|
-
insertNode(_el$30, createTextNode(` `));
|
|
2541
|
-
insert(_el$29, createComponent(Fact, {
|
|
2542
|
-
label: "Provider",
|
|
2543
|
-
get value() {
|
|
2544
|
-
return providerLabel(pkg().provider);
|
|
2545
|
-
}
|
|
2546
|
-
}), null);
|
|
2547
|
-
insert(_el$29, createComponent(Fact, {
|
|
2548
|
-
label: "Ecosystem",
|
|
2549
|
-
get value() {
|
|
2550
|
-
return pkg().ecosystem;
|
|
2551
|
-
}
|
|
2552
|
-
}), null);
|
|
2553
|
-
insert(_el$29, createComponent(Fact, {
|
|
2554
|
-
label: "Artifact",
|
|
2555
|
-
get value() {
|
|
2556
|
-
return pkg().artifact;
|
|
2557
|
-
}
|
|
2558
|
-
}), null);
|
|
2559
|
-
insert(_el$29, createComponent(Fact, {
|
|
2560
|
-
label: "Runtime",
|
|
2561
|
-
get value() {
|
|
2562
|
-
return pkg().runtime;
|
|
2563
|
-
}
|
|
2564
|
-
}), null);
|
|
2565
|
-
insert(_el$29, createComponent(Fact, {
|
|
2566
|
-
label: "Declared in",
|
|
2567
|
-
get value() {
|
|
2568
|
-
return declaration();
|
|
2569
|
-
}
|
|
2570
|
-
}), null);
|
|
2571
|
-
insert(_el$29, createComponent(Fact, {
|
|
2572
|
-
label: "Requires",
|
|
2573
3055
|
get value() {
|
|
2574
|
-
return
|
|
3056
|
+
return memo(() => !!(latest()._tag === "Completed" && reviewed() !== pkg()))() ? `this session, from ${reviewed().current}` : describeOutcome(latest());
|
|
2575
3057
|
}
|
|
2576
|
-
})
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
3058
|
+
})
|
|
3059
|
+
}), null);
|
|
3060
|
+
insert(_el$29, createComponent(Registry, {
|
|
3061
|
+
get about() {
|
|
3062
|
+
return about();
|
|
3063
|
+
},
|
|
3064
|
+
get current() {
|
|
3065
|
+
return pkg().current;
|
|
3066
|
+
},
|
|
3067
|
+
get target() {
|
|
3068
|
+
return pkg().target;
|
|
3069
|
+
}
|
|
3070
|
+
}), null);
|
|
3071
|
+
insert(_el$29, createComponent(Show, {
|
|
3072
|
+
get when() {
|
|
3073
|
+
return memo(() => pkg().target === void 0)() ? void 0 : pkg().elsewhere;
|
|
3074
|
+
},
|
|
3075
|
+
children: (elsewhere) => (() => {
|
|
3076
|
+
var _el$39 = createElement("box"), _el$40 = createElement("text"), _el$41 = createElement("box"), _el$42 = createElement("text");
|
|
3077
|
+
insertNode(_el$39, _el$40);
|
|
3078
|
+
insertNode(_el$39, _el$41);
|
|
3079
|
+
setProp(_el$39, "flexDirection", "column");
|
|
3080
|
+
setProp(_el$39, "marginTop", 1);
|
|
3081
|
+
setProp(_el$40, "wrapMode", "word");
|
|
3082
|
+
insert(_el$40, () => `${elsewhere().reason.replace(/^./u, (first) => first.toUpperCase())}.`);
|
|
3083
|
+
insertNode(_el$41, _el$42);
|
|
3084
|
+
setProp(_el$41, "flexDirection", "row");
|
|
3085
|
+
setProp(_el$41, "height", 1);
|
|
3086
|
+
insert(_el$41, createComponent(Key, {
|
|
3087
|
+
hint: "o",
|
|
3088
|
+
get color() {
|
|
3089
|
+
return theme.muted;
|
|
2593
3090
|
}
|
|
2594
|
-
})
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
2604
|
-
|
|
2605
|
-
|
|
2606
|
-
})
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
}
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
}
|
|
2721
|
-
})
|
|
2722
|
-
];
|
|
2723
|
-
} }));
|
|
2724
|
-
effect((_p$) => {
|
|
2725
|
-
var _v$9 = theme.strong, _v$0 = TextAttributes.BOLD, _v$1 = failure() === void 0 ? theme.muted : theme.danger, _v$10 = theme.muted, _v$11 = Math.max(1, props.height - headerLines), _v$12 = props.tab === "transcript", _v$13 = { trackOptions: {
|
|
2726
|
-
backgroundColor: theme.surface,
|
|
2727
|
-
foregroundColor: theme.rule
|
|
2728
|
-
} };
|
|
2729
|
-
_v$9 !== _p$.e && (_p$.e = setProp(_el$24, "fg", _v$9, _p$.e));
|
|
2730
|
-
_v$0 !== _p$.t && (_p$.t = setProp(_el$24, "attributes", _v$0, _p$.t));
|
|
2731
|
-
_v$1 !== _p$.a && (_p$.a = setProp(_el$25, "fg", _v$1, _p$.a));
|
|
2732
|
-
_v$10 !== _p$.o && (_p$.o = setProp(_el$27, "fg", _v$10, _p$.o));
|
|
2733
|
-
_v$11 !== _p$.i && (_p$.i = setProp(_el$28, "height", _v$11, _p$.i));
|
|
2734
|
-
_v$12 !== _p$.n && (_p$.n = setProp(_el$28, "stickyScroll", _v$12, _p$.n));
|
|
2735
|
-
_v$13 !== _p$.s && (_p$.s = setProp(_el$28, "verticalScrollbarOptions", _v$13, _p$.s));
|
|
2736
|
-
return _p$;
|
|
2737
|
-
}, {
|
|
2738
|
-
e: void 0,
|
|
2739
|
-
t: void 0,
|
|
2740
|
-
a: void 0,
|
|
2741
|
-
o: void 0,
|
|
2742
|
-
i: void 0,
|
|
2743
|
-
n: void 0,
|
|
2744
|
-
s: void 0
|
|
2745
|
-
});
|
|
2746
|
-
return _el$22;
|
|
2747
|
-
})();
|
|
2748
|
-
}
|
|
2749
|
-
}));
|
|
2750
|
-
effect((_$p) => setProp(_el$19, "maxWidth", props.tab === "about" || props.tab === "report" ? 100 : "100%", _$p));
|
|
2751
|
-
return _el$19;
|
|
2752
|
-
})();
|
|
2753
|
-
}
|
|
3091
|
+
}), _el$42);
|
|
3092
|
+
insert(_el$42, () => ` open ${elsewhere().app}`);
|
|
3093
|
+
effect((_p$) => {
|
|
3094
|
+
var _v$20 = theme.muted, _v$21 = theme.muted;
|
|
3095
|
+
_v$20 !== _p$.e && (_p$.e = setProp(_el$40, "fg", _v$20, _p$.e));
|
|
3096
|
+
_v$21 !== _p$.t && (_p$.t = setProp(_el$42, "fg", _v$21, _p$.t));
|
|
3097
|
+
return _p$;
|
|
3098
|
+
}, {
|
|
3099
|
+
e: void 0,
|
|
3100
|
+
t: void 0
|
|
3101
|
+
});
|
|
3102
|
+
return _el$39;
|
|
3103
|
+
})()
|
|
3104
|
+
}), null);
|
|
3105
|
+
insert(_el$29, createComponent(For, {
|
|
3106
|
+
get each() {
|
|
3107
|
+
return notices();
|
|
3108
|
+
},
|
|
3109
|
+
children: (notice) => (() => {
|
|
3110
|
+
var _el$43 = createElement("text");
|
|
3111
|
+
setProp(_el$43, "wrapMode", "word");
|
|
3112
|
+
insert(_el$43, () => notice.message);
|
|
3113
|
+
effect((_$p) => setProp(_el$43, "fg", theme.warn, _$p));
|
|
3114
|
+
return _el$43;
|
|
3115
|
+
})()
|
|
3116
|
+
}), null);
|
|
3117
|
+
return _el$29;
|
|
3118
|
+
}
|
|
3119
|
+
}),
|
|
3120
|
+
createComponent(Match, {
|
|
3121
|
+
get when() {
|
|
3122
|
+
return props.tab === "changes";
|
|
3123
|
+
},
|
|
3124
|
+
get children() {
|
|
3125
|
+
return createComponent(Changes, {
|
|
3126
|
+
get loaded() {
|
|
3127
|
+
const key = auditKey(reviewed(), props.state.mode);
|
|
3128
|
+
return key === void 0 ? void 0 : props.state.changes[key];
|
|
3129
|
+
},
|
|
3130
|
+
get unauditable() {
|
|
3131
|
+
return nothing();
|
|
3132
|
+
},
|
|
3133
|
+
get notes() {
|
|
3134
|
+
return memo(() => !!gone())() ? void 0 : pkg().notes;
|
|
3135
|
+
},
|
|
3136
|
+
get at() {
|
|
3137
|
+
return props.file;
|
|
3138
|
+
}
|
|
3139
|
+
});
|
|
3140
|
+
}
|
|
3141
|
+
}),
|
|
3142
|
+
createComponent(Match, {
|
|
3143
|
+
get when() {
|
|
3144
|
+
return props.tab === "report";
|
|
3145
|
+
},
|
|
3146
|
+
get children() {
|
|
3147
|
+
return createComponent(Report, {
|
|
3148
|
+
get audit() {
|
|
3149
|
+
return auditOf(props.state, pkg());
|
|
3150
|
+
},
|
|
3151
|
+
get installed() {
|
|
3152
|
+
return reviewed() !== pkg();
|
|
3153
|
+
},
|
|
3154
|
+
get unauditable() {
|
|
3155
|
+
return nothing();
|
|
3156
|
+
},
|
|
3157
|
+
model: (id) => {
|
|
3158
|
+
const slash = id.indexOf("/");
|
|
3159
|
+
return slash === -1 ? id : modelLabel(props.state, id.slice(0, slash), id.slice(slash + 1));
|
|
3160
|
+
}
|
|
3161
|
+
});
|
|
3162
|
+
}
|
|
3163
|
+
}),
|
|
3164
|
+
createComponent(Match, {
|
|
3165
|
+
get when() {
|
|
3166
|
+
return props.tab === "transcript";
|
|
3167
|
+
},
|
|
3168
|
+
get children() {
|
|
3169
|
+
return createComponent(Transcript, {
|
|
3170
|
+
get live() {
|
|
3171
|
+
return liveTranscript(auditOf(props.state, pkg()));
|
|
3172
|
+
},
|
|
3173
|
+
get running() {
|
|
3174
|
+
return auditOf(props.state, pkg())?._tag === "Running";
|
|
3175
|
+
},
|
|
3176
|
+
get stored() {
|
|
3177
|
+
const file = storedTranscript(auditOf(props.state, pkg()));
|
|
3178
|
+
return file === void 0 ? void 0 : props.state.transcripts[file];
|
|
3179
|
+
},
|
|
3180
|
+
get unauditable() {
|
|
3181
|
+
return nothing();
|
|
3182
|
+
}
|
|
3183
|
+
});
|
|
3184
|
+
}
|
|
3185
|
+
})
|
|
3186
|
+
];
|
|
3187
|
+
} }));
|
|
3188
|
+
effect((_p$) => {
|
|
3189
|
+
var _v$9 = theme.strong, _v$0 = TextAttributes.BOLD, _v$1 = failure() === void 0 ? theme.muted : theme.danger, _v$10 = theme.muted, _v$11 = Math.max(1, props.height - headerLines), _v$12 = props.tab === "transcript", _v$13 = { trackOptions: {
|
|
3190
|
+
backgroundColor: theme.surface,
|
|
3191
|
+
foregroundColor: theme.rule
|
|
3192
|
+
} };
|
|
3193
|
+
_v$9 !== _p$.e && (_p$.e = setProp(_el$24, "fg", _v$9, _p$.e));
|
|
3194
|
+
_v$0 !== _p$.t && (_p$.t = setProp(_el$24, "attributes", _v$0, _p$.t));
|
|
3195
|
+
_v$1 !== _p$.a && (_p$.a = setProp(_el$25, "fg", _v$1, _p$.a));
|
|
3196
|
+
_v$10 !== _p$.o && (_p$.o = setProp(_el$27, "fg", _v$10, _p$.o));
|
|
3197
|
+
_v$11 !== _p$.i && (_p$.i = setProp(_el$28, "height", _v$11, _p$.i));
|
|
3198
|
+
_v$12 !== _p$.n && (_p$.n = setProp(_el$28, "stickyScroll", _v$12, _p$.n));
|
|
3199
|
+
_v$13 !== _p$.s && (_p$.s = setProp(_el$28, "verticalScrollbarOptions", _v$13, _p$.s));
|
|
3200
|
+
return _p$;
|
|
3201
|
+
}, {
|
|
3202
|
+
e: void 0,
|
|
3203
|
+
t: void 0,
|
|
3204
|
+
a: void 0,
|
|
3205
|
+
o: void 0,
|
|
3206
|
+
i: void 0,
|
|
3207
|
+
n: void 0,
|
|
3208
|
+
s: void 0
|
|
3209
|
+
});
|
|
3210
|
+
return _el$22;
|
|
3211
|
+
})();
|
|
3212
|
+
}
|
|
3213
|
+
}));
|
|
3214
|
+
effect((_$p) => setProp(_el$19, "maxWidth", props.tab === "about" || props.tab === "report" ? 100 : "100%", _$p));
|
|
3215
|
+
return _el$19;
|
|
3216
|
+
})();
|
|
2754
3217
|
// src/tui/Inventory.tsx
|
|
2755
3218
|
const gap = 2;
|
|
2756
3219
|
const prefix = 4;
|
|
2757
3220
|
const arrow = " → ";
|
|
2758
3221
|
const statusWidth = 14;
|
|
2759
3222
|
const mark = (text) => {
|
|
2760
|
-
const first =
|
|
3223
|
+
const first = graphemes(text)[0] ?? "";
|
|
2761
3224
|
return /\p{L}/u.test(first) ? "·" : first;
|
|
2762
3225
|
};
|
|
2763
|
-
const widest = (values, least, most) => Math.min(most, Math.max(least, ...values.map((value) =>
|
|
3226
|
+
const widest = (values, least, most = Infinity) => Math.min(most, Math.max(least, ...values.map((value) => graphemes(value).length)));
|
|
2764
3227
|
const naturalColumns = (rows, state) => {
|
|
2765
3228
|
const providers = new Set(rows.map((row) => row.pkg.provider));
|
|
2766
3229
|
const statuses = rows.some((row) => row.pkg.target !== void 0 || status(state, row).text !== "");
|
|
2767
3230
|
return {
|
|
2768
3231
|
name: widest(rows.map((row) => row.pkg.name), 22, 40),
|
|
2769
|
-
current: widest(rows.map((row) => row.pkg.current), 10,
|
|
3232
|
+
current: widest(rows.map((row) => row.pkg.current), 10, 24),
|
|
2770
3233
|
target: widest(rows.map((row) => row.pkg.target ?? ""), 0, 24),
|
|
2771
|
-
bump: rows.some((row) => row.pkg.target !== void 0) ? widest(rows.map((row) => row.pkg.target === void 0 ? "" : bumpLabel(bump(row.pkg.current, row.pkg.target))), 4
|
|
3234
|
+
bump: rows.some((row) => row.pkg.target !== void 0) ? widest(rows.map((row) => row.pkg.target === void 0 ? "" : bumpLabel(bump(row.pkg.current, row.pkg.target, row.pkg.ecosystem))), 4) : 0,
|
|
2772
3235
|
provider: providers.size > 1 ? widest(rows.map((row) => providerLabel(row.pkg.provider)), 8, 16) : 0,
|
|
2773
3236
|
status: statuses ? statusWidth : 0
|
|
2774
3237
|
};
|
|
2775
3238
|
};
|
|
2776
3239
|
const optional = (width) => width === 0 ? 0 : gap + width;
|
|
2777
3240
|
const tableWidth = (columns) => prefix + columns.name + gap + columns.current + (columns.target === 0 ? 0 : 3 + columns.target) + optional(columns.bump) + optional(columns.provider) + optional(columns.status);
|
|
2778
|
-
const
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
|
|
2782
|
-
|
|
2783
|
-
return value - cut;
|
|
2784
|
-
};
|
|
2785
|
-
const drop = (width) => {
|
|
2786
|
-
if (excess <= 0 || width === 0) return width;
|
|
2787
|
-
excess -= gap + width;
|
|
2788
|
-
return 0;
|
|
2789
|
-
};
|
|
2790
|
-
const system = mode === "system";
|
|
2791
|
-
const bumpFirst = system ? drop(columns.bump) : void 0;
|
|
2792
|
-
const narrowed = system ? {
|
|
2793
|
-
name: shrink(columns.name, Math.min(columns.name, 24)),
|
|
2794
|
-
target: shrink(columns.target, Math.min(columns.target, 10)),
|
|
2795
|
-
current: shrink(columns.current, 10)
|
|
2796
|
-
} : columns;
|
|
2797
|
-
const provider = drop(columns.provider);
|
|
2798
|
-
const kind = bumpFirst ?? drop(columns.bump);
|
|
2799
|
-
const target = shrink(narrowed.target, Math.min(narrowed.target, 8));
|
|
2800
|
-
const current = shrink(narrowed.current, 8);
|
|
2801
|
-
const roomy = shrink(narrowed.name, Math.min(narrowed.name, 18));
|
|
2802
|
-
const status = shrink(columns.status, Math.min(columns.status, 2));
|
|
2803
|
-
const current2 = excess > 0 && columns.target > 0 ? 0 : current;
|
|
2804
|
-
excess -= current - current2;
|
|
2805
|
-
return {
|
|
2806
|
-
name: roomy - Math.max(0, Math.min(excess, roomy - 8)),
|
|
2807
|
-
current: current2,
|
|
2808
|
-
target,
|
|
2809
|
-
bump: kind,
|
|
2810
|
-
provider,
|
|
2811
|
-
status
|
|
2812
|
-
};
|
|
3241
|
+
const drop = (column) => [column, 0];
|
|
3242
|
+
const nameFloor = {
|
|
3243
|
+
roomy: 24,
|
|
3244
|
+
bothEnds: 18,
|
|
3245
|
+
last: 8
|
|
2813
3246
|
};
|
|
2814
|
-
const
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
while (least > 0 && keeps(fitColumns(columns, least - 1, mode))) least -= 1;
|
|
2818
|
-
return least;
|
|
3247
|
+
const versionFloor = {
|
|
3248
|
+
long: 10,
|
|
3249
|
+
short: 8
|
|
2819
3250
|
};
|
|
2820
|
-
const
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
3251
|
+
const giveWayByMode = {
|
|
3252
|
+
system: {
|
|
3253
|
+
besideDetails: [
|
|
3254
|
+
drop("bump"),
|
|
3255
|
+
["name", nameFloor.roomy],
|
|
3256
|
+
["current", versionFloor.long]
|
|
3257
|
+
],
|
|
3258
|
+
listAlone: [
|
|
3259
|
+
["name", nameFloor.bothEnds],
|
|
3260
|
+
["target", versionFloor.long],
|
|
3261
|
+
drop("provider")
|
|
3262
|
+
]
|
|
3263
|
+
},
|
|
3264
|
+
project: {
|
|
3265
|
+
besideDetails: [
|
|
3266
|
+
drop("provider"),
|
|
3267
|
+
drop("bump"),
|
|
3268
|
+
["name", nameFloor.roomy]
|
|
3269
|
+
],
|
|
3270
|
+
listAlone: [["name", nameFloor.bothEnds]]
|
|
2830
3271
|
}
|
|
2831
|
-
const head = Math.ceil((width - 1) / 2);
|
|
2832
|
-
const tail = width - 1 - head;
|
|
2833
|
-
return `${chars.slice(0, head).join("")}…${chars.slice(chars.length - tail).join("")}`;
|
|
2834
3272
|
};
|
|
3273
|
+
const lastResort = (columns) => {
|
|
3274
|
+
const offersVersion = columns.target > 0;
|
|
3275
|
+
return [
|
|
3276
|
+
["current", versionFloor.short],
|
|
3277
|
+
["target", versionFloor.short],
|
|
3278
|
+
["status", 2],
|
|
3279
|
+
...offersVersion ? [drop("current")] : [],
|
|
3280
|
+
["name", nameFloor.last]
|
|
3281
|
+
];
|
|
3282
|
+
};
|
|
3283
|
+
const giveWay = (columns, width, order) => {
|
|
3284
|
+
const fitted = { ...columns };
|
|
3285
|
+
for (const [column, floor] of order) {
|
|
3286
|
+
const excess = tableWidth(fitted) - width;
|
|
3287
|
+
const value = fitted[column];
|
|
3288
|
+
if (excess <= 0 || value === 0) continue;
|
|
3289
|
+
fitted[column] = floor === 0 ? 0 : value - Math.min(excess, Math.max(0, value - floor));
|
|
3290
|
+
}
|
|
3291
|
+
return fitted;
|
|
3292
|
+
};
|
|
3293
|
+
const fitColumns = (columns, width, mode = "project") => {
|
|
3294
|
+
const { besideDetails, listAlone } = giveWayByMode[mode];
|
|
3295
|
+
return giveWay(columns, width, [
|
|
3296
|
+
...besideDetails,
|
|
3297
|
+
...listAlone,
|
|
3298
|
+
...lastResort(columns)
|
|
3299
|
+
]);
|
|
3300
|
+
};
|
|
3301
|
+
const leastWidth = (columns, mode = "project") => tableWidth(giveWay(columns, 0, giveWayByMode[mode].besideDetails));
|
|
2835
3302
|
const pad = " ".repeat(gap);
|
|
3303
|
+
const targetText = (text, room) => fit(text, room).trimEnd();
|
|
2836
3304
|
const labels = (columns, filled) => [
|
|
2837
|
-
fit("Version", columns.current + (columns.target === 0 ? 0 : 3 + columns.target))
|
|
3305
|
+
`${" ".repeat(Math.max(0, columns.current - 7))}${fit("Version", Math.min(columns.current, 7) + (columns.target === 0 ? 0 : 3 + columns.target))}`,
|
|
2838
3306
|
columns.bump === 0 ? "" : pad + fit(filled.bump ? "Bump" : "", columns.bump),
|
|
2839
3307
|
columns.provider === 0 ? "" : pad + fit("Provider", columns.provider),
|
|
2840
3308
|
columns.status === 0 ? "" : pad + fit(filled.status ? "Status" : "", columns.status)
|
|
2841
3309
|
].join("").trimEnd();
|
|
2842
|
-
|
|
3310
|
+
const Heading = (props) => {
|
|
2843
3311
|
const updates = () => props.group.kind === "updates";
|
|
2844
3312
|
const folds = () => props.group.kind === "current";
|
|
2845
3313
|
const hinted = () => folds() && !props.typing;
|
|
2846
|
-
const
|
|
3314
|
+
const foldMark = () => {
|
|
3315
|
+
if (!folds()) return " ";
|
|
3316
|
+
return props.group.collapsed === true ? "▸ " : "▾ ";
|
|
3317
|
+
};
|
|
3318
|
+
const used = () => 2 + graphemes(props.group.title).length + ` ${props.group.rows.length}`.length + (props.selected > 0 ? ` · ${props.selected} selected`.length : 0) + (hinted() ? ` ${keys.fold.hint ?? ""} show`.length + 2 : 0);
|
|
2847
3319
|
const start = () => prefix + props.columns.name + gap;
|
|
2848
3320
|
return (() => {
|
|
2849
3321
|
var _el$ = createElement("box"), _el$2 = createElement("text"), _el$3 = createElement("text"), _el$4 = createElement("text");
|
|
@@ -2853,10 +3325,7 @@ function Heading(props) {
|
|
|
2853
3325
|
setProp(_el$, "flexDirection", "row");
|
|
2854
3326
|
setProp(_el$, "height", 1);
|
|
2855
3327
|
setProp(_el$2, "flexShrink", 0);
|
|
2856
|
-
insert(_el$2,
|
|
2857
|
-
var _c$ = memo(() => !!folds());
|
|
2858
|
-
return () => _c$() ? props.group.collapsed === true ? "▸ " : "▾ " : " ";
|
|
2859
|
-
})());
|
|
3328
|
+
insert(_el$2, foldMark);
|
|
2860
3329
|
setProp(_el$3, "flexShrink", 0);
|
|
2861
3330
|
insert(_el$3, () => props.group.title);
|
|
2862
3331
|
setProp(_el$4, "flexShrink", 0);
|
|
@@ -2897,7 +3366,7 @@ function Heading(props) {
|
|
|
2897
3366
|
var _el$8 = createElement("text");
|
|
2898
3367
|
setProp(_el$8, "flexShrink", 0);
|
|
2899
3368
|
insert(_el$8, () => props.group.collapsed === true ? " show" : " hide");
|
|
2900
|
-
effect((_$p) => setProp(_el$8, "fg", theme.
|
|
3369
|
+
effect((_$p) => setProp(_el$8, "fg", theme.muted, _$p));
|
|
2901
3370
|
return _el$8;
|
|
2902
3371
|
})()
|
|
2903
3372
|
];
|
|
@@ -2913,12 +3382,12 @@ function Heading(props) {
|
|
|
2913
3382
|
setProp(_el$9, "wrapMode", "none");
|
|
2914
3383
|
setProp(_el$9, "truncate", true);
|
|
2915
3384
|
insert(_el$9, () => " ".repeat(start() - used()) + labels(props.columns, props.filled));
|
|
2916
|
-
effect((_$p) => setProp(_el$9, "fg", theme.
|
|
3385
|
+
effect((_$p) => setProp(_el$9, "fg", theme.muted, _$p));
|
|
2917
3386
|
return _el$9;
|
|
2918
3387
|
}
|
|
2919
3388
|
}), null);
|
|
2920
3389
|
effect((_p$) => {
|
|
2921
|
-
var _v$ = theme.
|
|
3390
|
+
var _v$ = theme.muted, _v$2 = updates() ? theme.accent : theme.muted, _v$3 = TextAttributes.BOLD, _v$4 = theme.muted;
|
|
2922
3391
|
_v$ !== _p$.e && (_p$.e = setProp(_el$2, "fg", _v$, _p$.e));
|
|
2923
3392
|
_v$2 !== _p$.t && (_p$.t = setProp(_el$3, "fg", _v$2, _p$.t));
|
|
2924
3393
|
_v$3 !== _p$.a && (_p$.a = setProp(_el$3, "attributes", _v$3, _p$.a));
|
|
@@ -2932,111 +3401,36 @@ function Heading(props) {
|
|
|
2932
3401
|
});
|
|
2933
3402
|
return _el$;
|
|
2934
3403
|
})();
|
|
2935
|
-
}
|
|
2936
|
-
|
|
2937
|
-
|
|
2938
|
-
|
|
2939
|
-
|
|
2940
|
-
|
|
2941
|
-
|
|
2942
|
-
|
|
2943
|
-
|
|
2944
|
-
|
|
2945
|
-
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
return _el$1;
|
|
2955
|
-
}
|
|
2956
|
-
}),
|
|
2957
|
-
createComponent(Match, {
|
|
2958
|
-
get when() {
|
|
2959
|
-
return memo(() => line._tag === "Heading")() ? line.group : void 0;
|
|
2960
|
-
},
|
|
2961
|
-
children: (group) => createComponent(Heading, {
|
|
2962
|
-
get group() {
|
|
2963
|
-
return group();
|
|
2964
|
-
},
|
|
2965
|
-
get columns() {
|
|
2966
|
-
return props.columns;
|
|
2967
|
-
},
|
|
2968
|
-
get filled() {
|
|
2969
|
-
return {
|
|
2970
|
-
bump: group().kind === "updates",
|
|
2971
|
-
status: visibleRows(group()).some((row) => status(props.state, row).text !== "")
|
|
2972
|
-
};
|
|
2973
|
-
},
|
|
2974
|
-
get typing() {
|
|
2975
|
-
return props.typing;
|
|
2976
|
-
},
|
|
2977
|
-
get selected() {
|
|
2978
|
-
return group().rows.filter((row) => props.state.selected.includes(row.key)).length;
|
|
2979
|
-
}
|
|
2980
|
-
})
|
|
2981
|
-
}),
|
|
2982
|
-
createComponent(Match, {
|
|
2983
|
-
get when() {
|
|
2984
|
-
return line._tag === "Package" ? line : void 0;
|
|
2985
|
-
},
|
|
2986
|
-
children: (found) => createComponent(PackageLine, {
|
|
2987
|
-
get row() {
|
|
2988
|
-
return found().row;
|
|
2989
|
-
},
|
|
2990
|
-
get state() {
|
|
2991
|
-
return props.state;
|
|
2992
|
-
},
|
|
2993
|
-
get columns() {
|
|
2994
|
-
return props.columns;
|
|
2995
|
-
},
|
|
2996
|
-
get focused() {
|
|
2997
|
-
return found().index === props.cursor;
|
|
2998
|
-
}
|
|
2999
|
-
})
|
|
3000
|
-
})
|
|
3001
|
-
];
|
|
3002
|
-
} })
|
|
3003
|
-
}));
|
|
3004
|
-
effect((_$p) => setProp(_el$0, "flexGrow", props.lines.length === 0 ? 0 : 1, _$p));
|
|
3404
|
+
};
|
|
3405
|
+
const Cell = (props) => createComponent(Show, {
|
|
3406
|
+
get when() {
|
|
3407
|
+
return props.text !== "";
|
|
3408
|
+
},
|
|
3409
|
+
get children() {
|
|
3410
|
+
var _el$0 = createElement("text");
|
|
3411
|
+
setProp(_el$0, "flexShrink", 0);
|
|
3412
|
+
setProp(_el$0, "wrapMode", "none");
|
|
3413
|
+
insert(_el$0, () => props.text);
|
|
3414
|
+
effect((_p$) => {
|
|
3415
|
+
var _v$5 = props.color, _v$6 = props.bold === true ? TextAttributes.BOLD : TextAttributes.NONE;
|
|
3416
|
+
_v$5 !== _p$.e && (_p$.e = setProp(_el$0, "fg", _v$5, _p$.e));
|
|
3417
|
+
_v$6 !== _p$.t && (_p$.t = setProp(_el$0, "attributes", _v$6, _p$.t));
|
|
3418
|
+
return _p$;
|
|
3419
|
+
}, {
|
|
3420
|
+
e: void 0,
|
|
3421
|
+
t: void 0
|
|
3422
|
+
});
|
|
3005
3423
|
return _el$0;
|
|
3006
|
-
}
|
|
3007
|
-
}
|
|
3008
|
-
|
|
3009
|
-
return createComponent(Show, {
|
|
3010
|
-
get when() {
|
|
3011
|
-
return props.text !== "";
|
|
3012
|
-
},
|
|
3013
|
-
get children() {
|
|
3014
|
-
var _el$11 = createElement("text");
|
|
3015
|
-
setProp(_el$11, "flexShrink", 0);
|
|
3016
|
-
setProp(_el$11, "wrapMode", "none");
|
|
3017
|
-
insert(_el$11, () => props.text);
|
|
3018
|
-
effect((_p$) => {
|
|
3019
|
-
var _v$5 = props.color, _v$6 = props.bold === true ? TextAttributes.BOLD : TextAttributes.NONE;
|
|
3020
|
-
_v$5 !== _p$.e && (_p$.e = setProp(_el$11, "fg", _v$5, _p$.e));
|
|
3021
|
-
_v$6 !== _p$.t && (_p$.t = setProp(_el$11, "attributes", _v$6, _p$.t));
|
|
3022
|
-
return _p$;
|
|
3023
|
-
}, {
|
|
3024
|
-
e: void 0,
|
|
3025
|
-
t: void 0
|
|
3026
|
-
});
|
|
3027
|
-
return _el$11;
|
|
3028
|
-
}
|
|
3029
|
-
});
|
|
3030
|
-
}
|
|
3031
|
-
function PackageLine(props) {
|
|
3424
|
+
}
|
|
3425
|
+
});
|
|
3426
|
+
const PackageLine = (props) => {
|
|
3032
3427
|
const pkg = () => props.row.pkg;
|
|
3033
3428
|
const selected = () => props.state.selected.includes(props.row.key);
|
|
3034
3429
|
const shown = () => status(props.state, props.row);
|
|
3035
3430
|
const change = () => {
|
|
3036
|
-
const target = pkg()
|
|
3037
|
-
return target === void 0 ? void 0 : bump(pkg().current, target);
|
|
3431
|
+
const { target } = pkg();
|
|
3432
|
+
return target === void 0 ? void 0 : bump(pkg().current, target, pkg().ecosystem);
|
|
3038
3433
|
};
|
|
3039
|
-
const targetText = (text, room) => fit(text, room).trimEnd();
|
|
3040
3434
|
const outcome = () => props.state.outcomes[props.row.key];
|
|
3041
3435
|
const marker = () => {
|
|
3042
3436
|
if (selected()) return {
|
|
@@ -3045,7 +3439,7 @@ function PackageLine(props) {
|
|
|
3045
3439
|
};
|
|
3046
3440
|
if (props.state.removed[props.row.key] !== void 0) return {
|
|
3047
3441
|
text: "–",
|
|
3048
|
-
color: theme.
|
|
3442
|
+
color: theme.muted
|
|
3049
3443
|
};
|
|
3050
3444
|
const done = outcome();
|
|
3051
3445
|
if (done !== void 0) return {
|
|
@@ -3054,14 +3448,31 @@ function PackageLine(props) {
|
|
|
3054
3448
|
};
|
|
3055
3449
|
return {
|
|
3056
3450
|
text: "○",
|
|
3057
|
-
color:
|
|
3451
|
+
color: theme.muted
|
|
3058
3452
|
};
|
|
3059
3453
|
};
|
|
3454
|
+
const background = () => {
|
|
3455
|
+
if (props.focused) return theme.cursor;
|
|
3456
|
+
return selected() ? theme.selected : theme.none;
|
|
3457
|
+
};
|
|
3458
|
+
const nameColor = () => {
|
|
3459
|
+
if (selected()) return theme.accent;
|
|
3460
|
+
if (props.state.removed[props.row.key] !== void 0) return theme.muted;
|
|
3461
|
+
return props.focused ? theme.strong : theme.text;
|
|
3462
|
+
};
|
|
3463
|
+
const bumpText = () => {
|
|
3464
|
+
const changed = change();
|
|
3465
|
+
return changed === void 0 ? "" : bumpLabel(changed);
|
|
3466
|
+
};
|
|
3467
|
+
const bumpColor = () => {
|
|
3468
|
+
const changed = change();
|
|
3469
|
+
return changed === void 0 ? theme.muted : bumpTone(changed);
|
|
3470
|
+
};
|
|
3060
3471
|
return (() => {
|
|
3061
|
-
var _el$
|
|
3062
|
-
setProp(_el$
|
|
3063
|
-
setProp(_el$
|
|
3064
|
-
insert(_el$
|
|
3472
|
+
var _el$1 = createElement("box");
|
|
3473
|
+
setProp(_el$1, "flexDirection", "row");
|
|
3474
|
+
setProp(_el$1, "height", 1);
|
|
3475
|
+
insert(_el$1, createComponent(Cell, {
|
|
3065
3476
|
get text() {
|
|
3066
3477
|
return props.focused ? "▌" : " ";
|
|
3067
3478
|
},
|
|
@@ -3069,13 +3480,13 @@ function PackageLine(props) {
|
|
|
3069
3480
|
return theme.accent;
|
|
3070
3481
|
}
|
|
3071
3482
|
}), null);
|
|
3072
|
-
insert(_el$
|
|
3483
|
+
insert(_el$1, createComponent(Cell, {
|
|
3073
3484
|
text: " ",
|
|
3074
3485
|
get color() {
|
|
3075
3486
|
return theme.text;
|
|
3076
3487
|
}
|
|
3077
3488
|
}), null);
|
|
3078
|
-
insert(_el$
|
|
3489
|
+
insert(_el$1, createComponent(Cell, {
|
|
3079
3490
|
get text() {
|
|
3080
3491
|
return marker().text;
|
|
3081
3492
|
},
|
|
@@ -3084,31 +3495,31 @@ function PackageLine(props) {
|
|
|
3084
3495
|
},
|
|
3085
3496
|
bold: true
|
|
3086
3497
|
}), null);
|
|
3087
|
-
insert(_el$
|
|
3498
|
+
insert(_el$1, createComponent(Cell, {
|
|
3088
3499
|
text: " ",
|
|
3089
3500
|
get color() {
|
|
3090
3501
|
return theme.text;
|
|
3091
3502
|
}
|
|
3092
3503
|
}), null);
|
|
3093
|
-
insert(_el$
|
|
3504
|
+
insert(_el$1, createComponent(Cell, {
|
|
3094
3505
|
get text() {
|
|
3095
3506
|
return fitName(pkg().name, props.columns.name) + pad;
|
|
3096
3507
|
},
|
|
3097
3508
|
get color() {
|
|
3098
|
-
return
|
|
3509
|
+
return nameColor();
|
|
3099
3510
|
},
|
|
3100
3511
|
get bold() {
|
|
3101
3512
|
return selected() || props.focused;
|
|
3102
3513
|
}
|
|
3103
3514
|
}), null);
|
|
3104
|
-
insert(_el$
|
|
3515
|
+
insert(_el$1, createComponent(Show, {
|
|
3105
3516
|
get when() {
|
|
3106
3517
|
return props.columns.current > 0;
|
|
3107
3518
|
},
|
|
3108
3519
|
get children() {
|
|
3109
3520
|
return createComponent(Cell, {
|
|
3110
3521
|
get text() {
|
|
3111
|
-
return fit(pkg().current, props.columns.current);
|
|
3522
|
+
return fit(pkg().current, props.columns.current, "end");
|
|
3112
3523
|
},
|
|
3113
3524
|
get color() {
|
|
3114
3525
|
return theme.muted;
|
|
@@ -3116,7 +3527,7 @@ function PackageLine(props) {
|
|
|
3116
3527
|
});
|
|
3117
3528
|
}
|
|
3118
3529
|
}), null);
|
|
3119
|
-
insert(_el$
|
|
3530
|
+
insert(_el$1, createComponent(Show, {
|
|
3120
3531
|
get when() {
|
|
3121
3532
|
return props.columns.target > 0;
|
|
3122
3533
|
},
|
|
@@ -3136,16 +3547,16 @@ function PackageLine(props) {
|
|
|
3136
3547
|
});
|
|
3137
3548
|
},
|
|
3138
3549
|
children: (changed) => (() => {
|
|
3139
|
-
var _el$
|
|
3140
|
-
setProp(_el$
|
|
3141
|
-
setProp(_el$
|
|
3142
|
-
insert(_el$
|
|
3550
|
+
var _el$10 = createElement("box");
|
|
3551
|
+
setProp(_el$10, "flexDirection", "row");
|
|
3552
|
+
setProp(_el$10, "flexShrink", 0);
|
|
3553
|
+
insert(_el$10, createComponent(Cell, {
|
|
3143
3554
|
text: arrow,
|
|
3144
3555
|
get color() {
|
|
3145
|
-
return theme.
|
|
3556
|
+
return theme.muted;
|
|
3146
3557
|
}
|
|
3147
3558
|
}), null);
|
|
3148
|
-
insert(_el$
|
|
3559
|
+
insert(_el$10, createComponent(Cell, {
|
|
3149
3560
|
get text() {
|
|
3150
3561
|
return targetText(changed().same, props.columns.target);
|
|
3151
3562
|
},
|
|
@@ -3153,39 +3564,39 @@ function PackageLine(props) {
|
|
|
3153
3564
|
return theme.muted;
|
|
3154
3565
|
}
|
|
3155
3566
|
}), null);
|
|
3156
|
-
insert(_el$
|
|
3567
|
+
insert(_el$10, createComponent(Cell, {
|
|
3157
3568
|
get text() {
|
|
3158
|
-
return targetText(changed().changed, Math.max(0, props.columns.target -
|
|
3569
|
+
return targetText(changed().changed, Math.max(0, props.columns.target - graphemes(changed().same).length));
|
|
3159
3570
|
},
|
|
3160
3571
|
get color() {
|
|
3161
3572
|
return theme.strong;
|
|
3162
3573
|
},
|
|
3163
3574
|
bold: true
|
|
3164
3575
|
}), null);
|
|
3165
|
-
insert(_el$
|
|
3576
|
+
insert(_el$10, createComponent(Cell, {
|
|
3166
3577
|
get text() {
|
|
3167
|
-
return " ".repeat(Math.max(0, props.columns.target -
|
|
3578
|
+
return " ".repeat(Math.max(0, props.columns.target - (graphemes(changed().same).length + graphemes(changed().changed).length)));
|
|
3168
3579
|
},
|
|
3169
3580
|
get color() {
|
|
3170
3581
|
return theme.text;
|
|
3171
3582
|
}
|
|
3172
3583
|
}), null);
|
|
3173
|
-
return _el$
|
|
3584
|
+
return _el$10;
|
|
3174
3585
|
})()
|
|
3175
3586
|
});
|
|
3176
3587
|
}
|
|
3177
3588
|
}), null);
|
|
3178
|
-
insert(_el$
|
|
3589
|
+
insert(_el$1, createComponent(Show, {
|
|
3179
3590
|
get when() {
|
|
3180
3591
|
return props.columns.bump > 0;
|
|
3181
3592
|
},
|
|
3182
3593
|
get children() {
|
|
3183
3594
|
return createComponent(Cell, {
|
|
3184
3595
|
get text() {
|
|
3185
|
-
return pad + fit(
|
|
3596
|
+
return pad + fit(bumpText(), props.columns.bump);
|
|
3186
3597
|
},
|
|
3187
3598
|
get color() {
|
|
3188
|
-
return
|
|
3599
|
+
return bumpColor();
|
|
3189
3600
|
},
|
|
3190
3601
|
get bold() {
|
|
3191
3602
|
return change()?.risk === "major";
|
|
@@ -3193,22 +3604,22 @@ function PackageLine(props) {
|
|
|
3193
3604
|
});
|
|
3194
3605
|
}
|
|
3195
3606
|
}), null);
|
|
3196
|
-
insert(_el$
|
|
3607
|
+
insert(_el$1, createComponent(Show, {
|
|
3197
3608
|
get when() {
|
|
3198
3609
|
return props.columns.provider > 0;
|
|
3199
3610
|
},
|
|
3200
3611
|
get children() {
|
|
3201
3612
|
return createComponent(Cell, {
|
|
3202
3613
|
get text() {
|
|
3203
|
-
return pad +
|
|
3614
|
+
return pad + fitName(providerLabel(pkg().provider), props.columns.provider);
|
|
3204
3615
|
},
|
|
3205
3616
|
get color() {
|
|
3206
|
-
return theme.
|
|
3617
|
+
return theme.muted;
|
|
3207
3618
|
}
|
|
3208
3619
|
});
|
|
3209
3620
|
}
|
|
3210
3621
|
}), null);
|
|
3211
|
-
insert(_el$
|
|
3622
|
+
insert(_el$1, createComponent(Show, {
|
|
3212
3623
|
get when() {
|
|
3213
3624
|
return props.columns.status > 0;
|
|
3214
3625
|
},
|
|
@@ -3246,11 +3657,83 @@ function PackageLine(props) {
|
|
|
3246
3657
|
];
|
|
3247
3658
|
}
|
|
3248
3659
|
}), null);
|
|
3249
|
-
effect((_$p) => setProp(_el$
|
|
3250
|
-
return _el$
|
|
3660
|
+
effect((_$p) => setProp(_el$1, "backgroundColor", background(), _$p));
|
|
3661
|
+
return _el$1;
|
|
3662
|
+
})();
|
|
3663
|
+
};
|
|
3664
|
+
const Inventory = (props) => {
|
|
3665
|
+
const visible = () => props.lines.slice(props.offset, props.offset + props.height);
|
|
3666
|
+
return (() => {
|
|
3667
|
+
var _el$11 = createElement("box");
|
|
3668
|
+
setProp(_el$11, "flexDirection", "column");
|
|
3669
|
+
insert(_el$11, createComponent(For, {
|
|
3670
|
+
get each() {
|
|
3671
|
+
return visible();
|
|
3672
|
+
},
|
|
3673
|
+
children: (line) => createComponent(Switch, { get children() {
|
|
3674
|
+
return [
|
|
3675
|
+
createComponent(Match, {
|
|
3676
|
+
get when() {
|
|
3677
|
+
return line._tag === "Gap";
|
|
3678
|
+
},
|
|
3679
|
+
get children() {
|
|
3680
|
+
var _el$12 = createElement("text");
|
|
3681
|
+
insertNode(_el$12, createTextNode(` `));
|
|
3682
|
+
return _el$12;
|
|
3683
|
+
}
|
|
3684
|
+
}),
|
|
3685
|
+
createComponent(Match, {
|
|
3686
|
+
get when() {
|
|
3687
|
+
return memo(() => line._tag === "Heading")() ? line.group : void 0;
|
|
3688
|
+
},
|
|
3689
|
+
children: (group) => createComponent(Heading, {
|
|
3690
|
+
get group() {
|
|
3691
|
+
return group();
|
|
3692
|
+
},
|
|
3693
|
+
get columns() {
|
|
3694
|
+
return props.columns;
|
|
3695
|
+
},
|
|
3696
|
+
get filled() {
|
|
3697
|
+
return {
|
|
3698
|
+
bump: group().kind === "updates",
|
|
3699
|
+
status: visibleRows(group()).some((row) => status(props.state, row).text !== "")
|
|
3700
|
+
};
|
|
3701
|
+
},
|
|
3702
|
+
get typing() {
|
|
3703
|
+
return props.typing;
|
|
3704
|
+
},
|
|
3705
|
+
get selected() {
|
|
3706
|
+
return group().rows.filter((row) => props.state.selected.includes(row.key)).length;
|
|
3707
|
+
}
|
|
3708
|
+
})
|
|
3709
|
+
}),
|
|
3710
|
+
createComponent(Match, {
|
|
3711
|
+
get when() {
|
|
3712
|
+
return line._tag === "Package" ? line : void 0;
|
|
3713
|
+
},
|
|
3714
|
+
children: (found) => createComponent(PackageLine, {
|
|
3715
|
+
get row() {
|
|
3716
|
+
return found().row;
|
|
3717
|
+
},
|
|
3718
|
+
get state() {
|
|
3719
|
+
return props.state;
|
|
3720
|
+
},
|
|
3721
|
+
get columns() {
|
|
3722
|
+
return props.columns;
|
|
3723
|
+
},
|
|
3724
|
+
get focused() {
|
|
3725
|
+
return found().index === props.cursor;
|
|
3726
|
+
}
|
|
3727
|
+
})
|
|
3728
|
+
})
|
|
3729
|
+
];
|
|
3730
|
+
} })
|
|
3731
|
+
}));
|
|
3732
|
+
effect((_$p) => setProp(_el$11, "flexGrow", props.lines.length === 0 ? 0 : 1, _$p));
|
|
3733
|
+
return _el$11;
|
|
3251
3734
|
})();
|
|
3252
|
-
}
|
|
3253
|
-
|
|
3735
|
+
};
|
|
3736
|
+
const Empty = (props) => {
|
|
3254
3737
|
const problems = () => [...props.state.discoveryError === void 0 ? [] : [describeError(props.state.discoveryError)], ...props.state.providers.flatMap((entry) => entry.error === void 0 ? [] : [`${providerLabel(entry.name)}: ${describeError(entry.error)}`])];
|
|
3255
3738
|
return (() => {
|
|
3256
3739
|
var _el$14 = createElement("box");
|
|
@@ -3349,11 +3832,11 @@ function Empty(props) {
|
|
|
3349
3832
|
insert(_el$36, () => ` ${providerLabel(entry.name).padEnd(16)}`);
|
|
3350
3833
|
setProp(_el$37, "flexShrink", 0);
|
|
3351
3834
|
insert(_el$37, (() => {
|
|
3352
|
-
var _c$
|
|
3353
|
-
return () => _c$
|
|
3835
|
+
var _c$ = memo(() => entry.status === "ready");
|
|
3836
|
+
return () => _c$() ? `${entry.packages.length}` : "";
|
|
3354
3837
|
})());
|
|
3355
3838
|
effect((_p$) => {
|
|
3356
|
-
var _v$7 = theme.text, _v$8 = theme.
|
|
3839
|
+
var _v$7 = theme.text, _v$8 = theme.muted;
|
|
3357
3840
|
_v$7 !== _p$.e && (_p$.e = setProp(_el$36, "fg", _v$7, _p$.e));
|
|
3358
3841
|
_v$8 !== _p$.t && (_p$.t = setProp(_el$37, "fg", _v$8, _p$.t));
|
|
3359
3842
|
return _p$;
|
|
@@ -3423,72 +3906,29 @@ function Empty(props) {
|
|
|
3423
3906
|
})(), (() => {
|
|
3424
3907
|
var _el$27 = createElement("text");
|
|
3425
3908
|
insertNode(_el$27, createTextNode(`Press m to see the tools installed on this machine.`));
|
|
3426
|
-
effect((_$p) => setProp(_el$27, "fg", theme.
|
|
3909
|
+
effect((_$p) => setProp(_el$27, "fg", theme.muted, _$p));
|
|
3427
3910
|
return _el$27;
|
|
3428
3911
|
})()];
|
|
3429
3912
|
}
|
|
3430
|
-
}),
|
|
3431
|
-
createComponent(Match, {
|
|
3432
|
-
get when() {
|
|
3433
|
-
return props.state.mode === "system";
|
|
3434
|
-
},
|
|
3435
|
-
get children() {
|
|
3436
|
-
var _el$29 = createElement("text");
|
|
3437
|
-
insertNode(_el$29, createTextNode(`No package managers reported any installed tools.`));
|
|
3438
|
-
effect((_$p) => setProp(_el$29, "fg", theme.text, _$p));
|
|
3439
|
-
return _el$29;
|
|
3440
|
-
}
|
|
3441
|
-
})
|
|
3442
|
-
];
|
|
3443
|
-
} }));
|
|
3444
|
-
return _el$14;
|
|
3445
|
-
})();
|
|
3446
|
-
}
|
|
3447
|
-
// src/tui/Segments.tsx
|
|
3448
|
-
const segment = (color, text, bold = false) => ({
|
|
3449
|
-
text,
|
|
3450
|
-
color,
|
|
3451
|
-
bold
|
|
3452
|
-
});
|
|
3453
|
-
const shrinking = (color, text, bold = false) => ({
|
|
3454
|
-
...segment(color, text, bold),
|
|
3455
|
-
shrink: true
|
|
3456
|
-
});
|
|
3457
|
-
function Segments(props) {
|
|
3458
|
-
return (() => {
|
|
3459
|
-
var _el$ = createElement("box");
|
|
3460
|
-
setProp(_el$, "flexDirection", "row");
|
|
3461
|
-
setProp(_el$, "height", 1);
|
|
3462
|
-
insert(_el$, createComponent(For, {
|
|
3463
|
-
get each() {
|
|
3464
|
-
return props.segments;
|
|
3465
|
-
},
|
|
3466
|
-
children: (part) => (() => {
|
|
3467
|
-
var _el$2 = createElement("text");
|
|
3468
|
-
setProp(_el$2, "wrapMode", "none");
|
|
3469
|
-
insert(_el$2, () => part.text);
|
|
3470
|
-
effect((_p$) => {
|
|
3471
|
-
var _v$ = part.color, _v$2 = part.shrink === true ? 1 : 0, _v$3 = part.shrink === true, _v$4 = part.bold === true ? TextAttributes.BOLD : TextAttributes.NONE;
|
|
3472
|
-
_v$ !== _p$.e && (_p$.e = setProp(_el$2, "fg", _v$, _p$.e));
|
|
3473
|
-
_v$2 !== _p$.t && (_p$.t = setProp(_el$2, "flexShrink", _v$2, _p$.t));
|
|
3474
|
-
_v$3 !== _p$.a && (_p$.a = setProp(_el$2, "truncate", _v$3, _p$.a));
|
|
3475
|
-
_v$4 !== _p$.o && (_p$.o = setProp(_el$2, "attributes", _v$4, _p$.o));
|
|
3476
|
-
return _p$;
|
|
3477
|
-
}, {
|
|
3478
|
-
e: void 0,
|
|
3479
|
-
t: void 0,
|
|
3480
|
-
a: void 0,
|
|
3481
|
-
o: void 0
|
|
3482
|
-
});
|
|
3483
|
-
return _el$2;
|
|
3484
|
-
})()
|
|
3485
|
-
}));
|
|
3486
|
-
effect((_$p) => setProp(_el$, "backgroundColor", props.background ?? theme.none, _$p));
|
|
3487
|
-
return _el$;
|
|
3913
|
+
}),
|
|
3914
|
+
createComponent(Match, {
|
|
3915
|
+
get when() {
|
|
3916
|
+
return props.state.mode === "system";
|
|
3917
|
+
},
|
|
3918
|
+
get children() {
|
|
3919
|
+
var _el$29 = createElement("text");
|
|
3920
|
+
insertNode(_el$29, createTextNode(`No package managers reported any installed tools.`));
|
|
3921
|
+
effect((_$p) => setProp(_el$29, "fg", theme.text, _$p));
|
|
3922
|
+
return _el$29;
|
|
3923
|
+
}
|
|
3924
|
+
})
|
|
3925
|
+
];
|
|
3926
|
+
} }));
|
|
3927
|
+
return _el$14;
|
|
3488
3928
|
})();
|
|
3489
|
-
}
|
|
3929
|
+
};
|
|
3490
3930
|
// src/tui/Password.tsx
|
|
3491
|
-
|
|
3931
|
+
const PasswordPopup = (props) => {
|
|
3492
3932
|
const [entry, setEntry] = createSignal("");
|
|
3493
3933
|
useKeyboard((key) => {
|
|
3494
3934
|
if (key.name === "escape") props.answer(void 0);
|
|
@@ -3503,7 +3943,9 @@ function PasswordPopup(props) {
|
|
|
3503
3943
|
if (char !== void 0) setEntry((text) => text + char);
|
|
3504
3944
|
}
|
|
3505
3945
|
});
|
|
3506
|
-
usePaste((event) =>
|
|
3946
|
+
usePaste((event) => {
|
|
3947
|
+
setEntry((text) => text + pasted(event.bytes));
|
|
3948
|
+
});
|
|
3507
3949
|
return createComponent(Popup, {
|
|
3508
3950
|
title: "Password needed",
|
|
3509
3951
|
tone: "warn",
|
|
@@ -3532,16 +3974,17 @@ function PasswordPopup(props) {
|
|
|
3532
3974
|
})(),
|
|
3533
3975
|
(() => {
|
|
3534
3976
|
var _el$4 = createElement("text");
|
|
3535
|
-
insert(_el$4, () => `${"•".repeat(
|
|
3977
|
+
insert(_el$4, () => `${"•".repeat(graphemes(entry()).length)}▏`);
|
|
3536
3978
|
effect((_$p) => setProp(_el$4, "fg", theme.text, _$p));
|
|
3537
3979
|
return _el$4;
|
|
3538
3980
|
})()
|
|
3539
3981
|
];
|
|
3540
3982
|
}
|
|
3541
3983
|
});
|
|
3542
|
-
}
|
|
3984
|
+
};
|
|
3543
3985
|
// src/tui/Settings.tsx
|
|
3544
3986
|
const listHeight = 10;
|
|
3987
|
+
const width$1 = 84;
|
|
3545
3988
|
const menu = [
|
|
3546
3989
|
"model",
|
|
3547
3990
|
"thinking",
|
|
@@ -3557,7 +4000,7 @@ const binding = (hint, description) => ({
|
|
|
3557
4000
|
hint,
|
|
3558
4001
|
description
|
|
3559
4002
|
});
|
|
3560
|
-
|
|
4003
|
+
const SettingsPopup = (props) => {
|
|
3561
4004
|
const [mode, setMode] = createSignal({ _tag: "Menu" });
|
|
3562
4005
|
const [row, setRow] = createSignal(0);
|
|
3563
4006
|
const [filter, setFilter] = createSignal("");
|
|
@@ -3572,10 +4015,11 @@ function SettingsPopup(props) {
|
|
|
3572
4015
|
const chosen = current();
|
|
3573
4016
|
return chosen !== void 0 && !chosen.signedIn ? chosen : void 0;
|
|
3574
4017
|
};
|
|
3575
|
-
const
|
|
3576
|
-
|
|
3577
|
-
return
|
|
3578
|
-
}
|
|
4018
|
+
const standing = (choice) => {
|
|
4019
|
+
if (choice === current()) return 0;
|
|
4020
|
+
return choice.signedIn ? 1 : 2;
|
|
4021
|
+
};
|
|
4022
|
+
const ordered = createMemo(() => catalogue().toSorted((left, right) => standing(left) - standing(right)));
|
|
3579
4023
|
const matching = createMemo(() => {
|
|
3580
4024
|
const words = filter().toLowerCase().split(/\s+/u).filter(Boolean);
|
|
3581
4025
|
return ordered().filter((choice) => {
|
|
@@ -3678,16 +4122,16 @@ function SettingsPopup(props) {
|
|
|
3678
4122
|
if (char !== void 0) setEntry((text) => text + char);
|
|
3679
4123
|
}
|
|
3680
4124
|
};
|
|
4125
|
+
const cancel = () => {
|
|
4126
|
+
props.run(props.session.closeSignIn);
|
|
4127
|
+
setMode({ _tag: "Picker" });
|
|
4128
|
+
};
|
|
3681
4129
|
const onSignIn = (key, signIn) => {
|
|
3682
|
-
const cancel = () => {
|
|
3683
|
-
props.run(props.session.closeSignIn);
|
|
3684
|
-
setMode({ _tag: "Picker" });
|
|
3685
|
-
};
|
|
3686
4130
|
if (signIn?._tag !== "Working" || signIn.prompt === void 0) {
|
|
3687
4131
|
if (key.name === "escape") cancel();
|
|
3688
4132
|
return;
|
|
3689
4133
|
}
|
|
3690
|
-
const prompt = signIn
|
|
4134
|
+
const { prompt } = signIn;
|
|
3691
4135
|
if (prompt.type === "select") {
|
|
3692
4136
|
if (key.name === "escape") cancel();
|
|
3693
4137
|
else if (key.name === "down") setPicked((index) => Math.min(prompt.options.length - 1, index + 1));
|
|
@@ -3706,22 +4150,32 @@ function SettingsPopup(props) {
|
|
|
3706
4150
|
useKeyboard((key) => {
|
|
3707
4151
|
const now = mode();
|
|
3708
4152
|
switch (now._tag) {
|
|
3709
|
-
case "Menu":
|
|
3710
|
-
|
|
3711
|
-
|
|
3712
|
-
case "
|
|
3713
|
-
|
|
3714
|
-
|
|
3715
|
-
|
|
3716
|
-
|
|
3717
|
-
|
|
3718
|
-
|
|
4153
|
+
case "Menu":
|
|
4154
|
+
onMenu(key);
|
|
4155
|
+
return;
|
|
4156
|
+
case "Picker":
|
|
4157
|
+
onPicker(key);
|
|
4158
|
+
return;
|
|
4159
|
+
case "Method":
|
|
4160
|
+
onMethod(key, now.choice);
|
|
4161
|
+
return;
|
|
4162
|
+
case "Key":
|
|
4163
|
+
onEntry(key, (text) => {
|
|
4164
|
+
if (text.trim() === "") return;
|
|
4165
|
+
props.run(props.session.saveKey(now.choice.provider, text.trim()));
|
|
4166
|
+
setEntry("");
|
|
4167
|
+
setMode({
|
|
4168
|
+
_tag: "SigningIn",
|
|
4169
|
+
choice: now.choice
|
|
4170
|
+
});
|
|
4171
|
+
}, () => {
|
|
4172
|
+
setMode({
|
|
4173
|
+
_tag: "Method",
|
|
4174
|
+
choice: now.choice
|
|
4175
|
+
});
|
|
3719
4176
|
});
|
|
3720
|
-
|
|
3721
|
-
|
|
3722
|
-
choice: now.choice
|
|
3723
|
-
}));
|
|
3724
|
-
case "SigningIn": return onSignIn(key, props.state.signIn);
|
|
4177
|
+
return;
|
|
4178
|
+
case "SigningIn": onSignIn(key, props.state.signIn);
|
|
3725
4179
|
}
|
|
3726
4180
|
});
|
|
3727
4181
|
const modelLabel = () => {
|
|
@@ -3730,27 +4184,38 @@ function SettingsPopup(props) {
|
|
|
3730
4184
|
const known = current();
|
|
3731
4185
|
return known === void 0 ? `${chosen.provider}/${chosen.modelId}` : `${known.providerName} · ${known.name}`;
|
|
3732
4186
|
};
|
|
4187
|
+
const compact = useCompact();
|
|
4188
|
+
const dimensions = useTerminalDimensions();
|
|
4189
|
+
const room = (before) => bodyWidth(width$1, dimensions().width) - before;
|
|
3733
4190
|
const menuLine = (index, label, value, color, help) => (() => {
|
|
3734
|
-
var _el$ = createElement("box")
|
|
3735
|
-
insertNode(_el$, _el$2);
|
|
4191
|
+
var _el$ = createElement("box");
|
|
3736
4192
|
setProp(_el$, "flexDirection", "column");
|
|
3737
|
-
setProp(_el$, "marginBottom", 1);
|
|
3738
4193
|
insert(_el$, createComponent(Segments, { get segments() {
|
|
3739
4194
|
return [
|
|
3740
4195
|
segment(theme.accent, row() === index ? "▌ " : " "),
|
|
3741
4196
|
segment(row() === index ? theme.strong : theme.muted, label.padEnd(14), row() === index),
|
|
3742
|
-
|
|
4197
|
+
segment(color, clip(value, room(16)), true)
|
|
3743
4198
|
];
|
|
3744
|
-
} }),
|
|
3745
|
-
|
|
3746
|
-
|
|
3747
|
-
|
|
3748
|
-
|
|
3749
|
-
|
|
4199
|
+
} }), null);
|
|
4200
|
+
insert(_el$, createComponent(Show, {
|
|
4201
|
+
get when() {
|
|
4202
|
+
return !compact();
|
|
4203
|
+
},
|
|
4204
|
+
get children() {
|
|
4205
|
+
var _el$2 = createElement("box"), _el$3 = createElement("text");
|
|
4206
|
+
insertNode(_el$2, _el$3);
|
|
4207
|
+
setProp(_el$2, "paddingLeft", 16);
|
|
4208
|
+
setProp(_el$2, "paddingRight", 1);
|
|
4209
|
+
setProp(_el$3, "wrapMode", "word");
|
|
4210
|
+
insert(_el$3, help);
|
|
4211
|
+
effect((_$p) => setProp(_el$3, "fg", theme.muted, _$p));
|
|
4212
|
+
return _el$2;
|
|
4213
|
+
}
|
|
4214
|
+
}), null);
|
|
3750
4215
|
effect((_p$) => {
|
|
3751
|
-
var _v$ = row() === index ? theme.cursor : theme.none
|
|
3752
|
-
_v$ !== _p$.e && (_p$.e = setProp(_el$, "
|
|
3753
|
-
_v$2 !== _p$.t && (_p$.t = setProp(_el
|
|
4216
|
+
var _v$ = index === menu.length - 1 ? 0 : 1, _v$2 = row() === index ? theme.cursor : theme.none;
|
|
4217
|
+
_v$ !== _p$.e && (_p$.e = setProp(_el$, "marginBottom", _v$, _p$.e));
|
|
4218
|
+
_v$2 !== _p$.t && (_p$.t = setProp(_el$, "backgroundColor", _v$2, _p$.t));
|
|
3754
4219
|
return _p$;
|
|
3755
4220
|
}, {
|
|
3756
4221
|
e: void 0,
|
|
@@ -3758,7 +4223,7 @@ function SettingsPopup(props) {
|
|
|
3758
4223
|
});
|
|
3759
4224
|
return _el$;
|
|
3760
4225
|
})();
|
|
3761
|
-
const masked = () => "•".repeat(
|
|
4226
|
+
const masked = () => "•".repeat(graphemes(entry()).length);
|
|
3762
4227
|
const method = () => {
|
|
3763
4228
|
const now = mode();
|
|
3764
4229
|
return now._tag === "Method" ? now : void 0;
|
|
@@ -3786,9 +4251,9 @@ function SettingsPopup(props) {
|
|
|
3786
4251
|
const text = pasted(event.bytes);
|
|
3787
4252
|
const now = mode();
|
|
3788
4253
|
if (now._tag === "Picker") {
|
|
3789
|
-
setFilter((
|
|
4254
|
+
setFilter((previous) => previous + text);
|
|
3790
4255
|
setCursor(0);
|
|
3791
|
-
} else if (now._tag === "Key" || now._tag === "SigningIn" && selecting() === void 0) setEntry((
|
|
4256
|
+
} else if (now._tag === "Key" || now._tag === "SigningIn" && selecting() === void 0) setEntry((previous) => previous + text);
|
|
3792
4257
|
});
|
|
3793
4258
|
return createComponent(Switch, { get children() {
|
|
3794
4259
|
return [
|
|
@@ -3799,7 +4264,7 @@ function SettingsPopup(props) {
|
|
|
3799
4264
|
get children() {
|
|
3800
4265
|
return createComponent(Popup, {
|
|
3801
4266
|
title: "Settings",
|
|
3802
|
-
width:
|
|
4267
|
+
width: width$1,
|
|
3803
4268
|
get bindings() {
|
|
3804
4269
|
return [
|
|
3805
4270
|
keys.up,
|
|
@@ -3818,20 +4283,14 @@ function SettingsPopup(props) {
|
|
|
3818
4283
|
return props.state.settingsIssue;
|
|
3819
4284
|
},
|
|
3820
4285
|
children: (issue) => (() => {
|
|
3821
|
-
var _el$
|
|
3822
|
-
setProp(_el$
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
4286
|
+
var _el$6 = createElement("text");
|
|
4287
|
+
setProp(_el$6, "wrapMode", "word");
|
|
4288
|
+
setProp(_el$6, "marginTop", 1);
|
|
4289
|
+
insert(_el$6, issue);
|
|
4290
|
+
effect((_$p) => setProp(_el$6, "fg", theme.danger, _$p));
|
|
4291
|
+
return _el$6;
|
|
3826
4292
|
})()
|
|
3827
|
-
})
|
|
3828
|
-
(() => {
|
|
3829
|
-
var _el$4 = createElement("text");
|
|
3830
|
-
insertNode(_el$4, createTextNode(`Credentials are shared with pi through its auth.json.`));
|
|
3831
|
-
setProp(_el$4, "wrapMode", "word");
|
|
3832
|
-
effect((_$p) => setProp(_el$4, "fg", theme.faint, _$p));
|
|
3833
|
-
return _el$4;
|
|
3834
|
-
})()
|
|
4293
|
+
})
|
|
3835
4294
|
];
|
|
3836
4295
|
}
|
|
3837
4296
|
});
|
|
@@ -3844,7 +4303,7 @@ function SettingsPopup(props) {
|
|
|
3844
4303
|
get children() {
|
|
3845
4304
|
return createComponent(Popup, {
|
|
3846
4305
|
title: "Audit model",
|
|
3847
|
-
width:
|
|
4306
|
+
width: width$1,
|
|
3848
4307
|
get bindings() {
|
|
3849
4308
|
return [
|
|
3850
4309
|
binding("type", "filter"),
|
|
@@ -3855,20 +4314,20 @@ function SettingsPopup(props) {
|
|
|
3855
4314
|
},
|
|
3856
4315
|
get children() {
|
|
3857
4316
|
return [(() => {
|
|
3858
|
-
var _el$
|
|
3859
|
-
insert(_el$
|
|
3860
|
-
effect((_$p) => setProp(_el$
|
|
3861
|
-
return _el$
|
|
4317
|
+
var _el$4 = createElement("text");
|
|
4318
|
+
insert(_el$4, () => `/${filter()}▏`);
|
|
4319
|
+
effect((_$p) => setProp(_el$4, "fg", theme.text, _$p));
|
|
4320
|
+
return _el$4;
|
|
3862
4321
|
})(), createComponent(Show, {
|
|
3863
4322
|
get when() {
|
|
3864
4323
|
return props.state.catalogue?._tag === "Ready";
|
|
3865
4324
|
},
|
|
3866
4325
|
get fallback() {
|
|
3867
4326
|
return (() => {
|
|
3868
|
-
var _el$
|
|
3869
|
-
insertNode(_el$
|
|
3870
|
-
effect((_$p) => setProp(_el$
|
|
3871
|
-
return _el$
|
|
4327
|
+
var _el$7 = createElement("text");
|
|
4328
|
+
insertNode(_el$7, createTextNode(`Reading pi-ai's catalogue…`));
|
|
4329
|
+
effect((_$p) => setProp(_el$7, "fg", theme.muted, _$p));
|
|
4330
|
+
return _el$7;
|
|
3872
4331
|
})();
|
|
3873
4332
|
},
|
|
3874
4333
|
get children() {
|
|
@@ -3882,18 +4341,18 @@ function SettingsPopup(props) {
|
|
|
3882
4341
|
},
|
|
3883
4342
|
get segments() {
|
|
3884
4343
|
return [
|
|
3885
|
-
segment(choice === current() ? theme.accent : theme.
|
|
3886
|
-
segment(choice.signedIn ? theme.ok : theme.
|
|
4344
|
+
segment(choice === current() ? theme.accent : theme.muted, choice === current() ? "● " : " "),
|
|
4345
|
+
segment(choice.signedIn ? theme.ok : theme.muted, choice.signedIn ? "✓ " : " "),
|
|
3887
4346
|
segment(theme.muted, fit(choice.providerName, 22)),
|
|
3888
|
-
|
|
4347
|
+
segment(choice === current() ? theme.strong : theme.text, ` ${clip(choice.name, room(27))}`, choice === current())
|
|
3889
4348
|
];
|
|
3890
4349
|
}
|
|
3891
4350
|
})
|
|
3892
4351
|
}), (() => {
|
|
3893
|
-
var _el$
|
|
3894
|
-
insert(_el$
|
|
3895
|
-
effect((_$p) => setProp(_el$
|
|
3896
|
-
return _el$
|
|
4352
|
+
var _el$5 = createElement("text");
|
|
4353
|
+
insert(_el$5, () => `${matching().length} of ${catalogue().length} models · ✓ signed in · ● current`);
|
|
4354
|
+
effect((_$p) => setProp(_el$5, "fg", theme.muted, _$p));
|
|
4355
|
+
return _el$5;
|
|
3897
4356
|
})()];
|
|
3898
4357
|
}
|
|
3899
4358
|
})];
|
|
@@ -3906,6 +4365,7 @@ function SettingsPopup(props) {
|
|
|
3906
4365
|
return method();
|
|
3907
4366
|
},
|
|
3908
4367
|
children: (chosen) => createComponent(Popup, {
|
|
4368
|
+
width: width$1,
|
|
3909
4369
|
get title() {
|
|
3910
4370
|
return `Sign in to ${chosen().choice.providerName}`;
|
|
3911
4371
|
},
|
|
@@ -3938,6 +4398,7 @@ function SettingsPopup(props) {
|
|
|
3938
4398
|
return entering();
|
|
3939
4399
|
},
|
|
3940
4400
|
children: (keyed) => createComponent(Popup, {
|
|
4401
|
+
width: width$1,
|
|
3941
4402
|
get title() {
|
|
3942
4403
|
return `${keyed().choice.providerName} API key`;
|
|
3943
4404
|
},
|
|
@@ -3946,16 +4407,16 @@ function SettingsPopup(props) {
|
|
|
3946
4407
|
},
|
|
3947
4408
|
get children() {
|
|
3948
4409
|
return [(() => {
|
|
3949
|
-
var _el$
|
|
3950
|
-
insert(_el$
|
|
3951
|
-
effect((_$p) => setProp(_el$
|
|
3952
|
-
return _el$
|
|
4410
|
+
var _el$9 = createElement("text");
|
|
4411
|
+
insert(_el$9, () => `${masked()}▏`);
|
|
4412
|
+
effect((_$p) => setProp(_el$9, "fg", theme.text, _$p));
|
|
4413
|
+
return _el$9;
|
|
3953
4414
|
})(), (() => {
|
|
3954
|
-
var _el$
|
|
3955
|
-
insertNode(_el$
|
|
3956
|
-
setProp(_el$
|
|
3957
|
-
effect((_$p) => setProp(_el$
|
|
3958
|
-
return _el$
|
|
4415
|
+
var _el$0 = createElement("text");
|
|
4416
|
+
insertNode(_el$0, createTextNode(`Saved to pi's auth.json. $VAR and !command values resolve the way pi resolves them.`));
|
|
4417
|
+
setProp(_el$0, "wrapMode", "word");
|
|
4418
|
+
effect((_$p) => setProp(_el$0, "fg", theme.muted, _$p));
|
|
4419
|
+
return _el$0;
|
|
3959
4420
|
})()];
|
|
3960
4421
|
}
|
|
3961
4422
|
})
|
|
@@ -3964,9 +4425,10 @@ function SettingsPopup(props) {
|
|
|
3964
4425
|
get when() {
|
|
3965
4426
|
return signing();
|
|
3966
4427
|
},
|
|
3967
|
-
children: (
|
|
4428
|
+
children: (signingIn) => createComponent(Popup, {
|
|
4429
|
+
width: width$1,
|
|
3968
4430
|
get title() {
|
|
3969
|
-
return `Sign in to ${
|
|
4431
|
+
return `Sign in to ${signingIn().choice.providerName}`;
|
|
3970
4432
|
},
|
|
3971
4433
|
get bindings() {
|
|
3972
4434
|
return [binding("Enter", "submit"), binding("Esc", "cancel")];
|
|
@@ -3978,51 +4440,51 @@ function SettingsPopup(props) {
|
|
|
3978
4440
|
},
|
|
3979
4441
|
get fallback() {
|
|
3980
4442
|
return (() => {
|
|
3981
|
-
var _el$
|
|
3982
|
-
setProp(_el$
|
|
3983
|
-
insert(_el$
|
|
4443
|
+
var _el$10 = createElement("box");
|
|
4444
|
+
setProp(_el$10, "flexDirection", "column");
|
|
4445
|
+
insert(_el$10, createComponent(Show, {
|
|
3984
4446
|
get when() {
|
|
3985
4447
|
return memo(() => (working()?.notices.length ?? 0) === 0)() && prompt() === void 0;
|
|
3986
4448
|
},
|
|
3987
4449
|
get children() {
|
|
3988
|
-
var _el$
|
|
3989
|
-
insertNode(_el$
|
|
3990
|
-
effect((_$p) => setProp(_el$
|
|
3991
|
-
return _el$
|
|
4450
|
+
var _el$11 = createElement("text");
|
|
4451
|
+
insertNode(_el$11, createTextNode(`Working…`));
|
|
4452
|
+
effect((_$p) => setProp(_el$11, "fg", theme.muted, _$p));
|
|
4453
|
+
return _el$11;
|
|
3992
4454
|
}
|
|
3993
4455
|
}), null);
|
|
3994
|
-
insert(_el$
|
|
4456
|
+
insert(_el$10, createComponent(For, {
|
|
3995
4457
|
get each() {
|
|
3996
4458
|
return working()?.notices ?? [];
|
|
3997
4459
|
},
|
|
3998
4460
|
children: (notice) => (() => {
|
|
3999
|
-
var _el$
|
|
4000
|
-
setProp(_el$
|
|
4001
|
-
insert(_el$
|
|
4002
|
-
effect((_$p) => setProp(_el$
|
|
4003
|
-
return _el$
|
|
4461
|
+
var _el$13 = createElement("text");
|
|
4462
|
+
setProp(_el$13, "wrapMode", "char");
|
|
4463
|
+
insert(_el$13, notice);
|
|
4464
|
+
effect((_$p) => setProp(_el$13, "fg", theme.text, _$p));
|
|
4465
|
+
return _el$13;
|
|
4004
4466
|
})()
|
|
4005
4467
|
}), null);
|
|
4006
|
-
insert(_el$
|
|
4468
|
+
insert(_el$10, createComponent(Show, {
|
|
4007
4469
|
get when() {
|
|
4008
4470
|
return prompt();
|
|
4009
4471
|
},
|
|
4010
4472
|
children: (asked) => (() => {
|
|
4011
|
-
var _el$
|
|
4012
|
-
insertNode(_el$
|
|
4013
|
-
setProp(_el$
|
|
4014
|
-
setProp(_el$
|
|
4015
|
-
insert(_el$
|
|
4016
|
-
insert(_el$
|
|
4473
|
+
var _el$14 = createElement("box"), _el$15 = createElement("text");
|
|
4474
|
+
insertNode(_el$14, _el$15);
|
|
4475
|
+
setProp(_el$14, "flexDirection", "column");
|
|
4476
|
+
setProp(_el$15, "wrapMode", "word");
|
|
4477
|
+
insert(_el$15, () => asked().message);
|
|
4478
|
+
insert(_el$14, createComponent(Show, {
|
|
4017
4479
|
get when() {
|
|
4018
4480
|
return selecting();
|
|
4019
4481
|
},
|
|
4020
4482
|
get fallback() {
|
|
4021
4483
|
return (() => {
|
|
4022
|
-
var _el$
|
|
4023
|
-
insert(_el$
|
|
4024
|
-
effect((_$p) => setProp(_el$
|
|
4025
|
-
return _el$
|
|
4484
|
+
var _el$16 = createElement("text");
|
|
4485
|
+
insert(_el$16, () => `${asked().type === "secret" ? masked() : entry()}▏`);
|
|
4486
|
+
effect((_$p) => setProp(_el$16, "fg", theme.text, _$p));
|
|
4487
|
+
return _el$16;
|
|
4026
4488
|
})();
|
|
4027
4489
|
},
|
|
4028
4490
|
children: (select) => createComponent(For, {
|
|
@@ -4034,24 +4496,24 @@ function SettingsPopup(props) {
|
|
|
4034
4496
|
return memo(() => index() === picked())() ? theme.cursor : theme.none;
|
|
4035
4497
|
},
|
|
4036
4498
|
get segments() {
|
|
4037
|
-
return [
|
|
4499
|
+
return [segment(theme.text, ` ${clip(option.label, room(2))}`)];
|
|
4038
4500
|
}
|
|
4039
4501
|
})
|
|
4040
4502
|
})
|
|
4041
4503
|
}), null);
|
|
4042
|
-
effect((_$p) => setProp(_el$
|
|
4043
|
-
return _el$
|
|
4504
|
+
effect((_$p) => setProp(_el$15, "fg", theme.accent, _$p));
|
|
4505
|
+
return _el$14;
|
|
4044
4506
|
})()
|
|
4045
4507
|
}), null);
|
|
4046
|
-
return _el$
|
|
4508
|
+
return _el$10;
|
|
4047
4509
|
})();
|
|
4048
4510
|
},
|
|
4049
4511
|
children: (failed) => (() => {
|
|
4050
|
-
var _el$
|
|
4051
|
-
setProp(_el$
|
|
4052
|
-
insert(_el$
|
|
4053
|
-
effect((_$p) => setProp(_el$
|
|
4054
|
-
return _el$
|
|
4512
|
+
var _el$17 = createElement("text");
|
|
4513
|
+
setProp(_el$17, "wrapMode", "word");
|
|
4514
|
+
insert(_el$17, () => `Sign-in failed: ${failed().issue}`);
|
|
4515
|
+
effect((_$p) => setProp(_el$17, "fg", theme.danger, _$p));
|
|
4516
|
+
return _el$17;
|
|
4055
4517
|
})()
|
|
4056
4518
|
});
|
|
4057
4519
|
}
|
|
@@ -4059,7 +4521,7 @@ function SettingsPopup(props) {
|
|
|
4059
4521
|
})
|
|
4060
4522
|
];
|
|
4061
4523
|
} });
|
|
4062
|
-
}
|
|
4524
|
+
};
|
|
4063
4525
|
// src/tui/App.tsx
|
|
4064
4526
|
const severities = [
|
|
4065
4527
|
"high",
|
|
@@ -4068,89 +4530,58 @@ const severities = [
|
|
|
4068
4530
|
"info"
|
|
4069
4531
|
];
|
|
4070
4532
|
const topFinding = (report) => {
|
|
4071
|
-
const finding =
|
|
4533
|
+
const [finding] = report.findings.toSorted((left, right) => severities.indexOf(left.severity) - severities.indexOf(right.severity));
|
|
4072
4534
|
return finding === void 0 ? void 0 : `${finding.severity}: ${finding.title}`;
|
|
4073
4535
|
};
|
|
4074
4536
|
const leftOut = (rows, why) => {
|
|
4075
|
-
const
|
|
4537
|
+
const byReason = /* @__PURE__ */ new Map();
|
|
4076
4538
|
for (const row of rows) {
|
|
4077
4539
|
const reason = why(row);
|
|
4078
|
-
if (reason !== void 0)
|
|
4540
|
+
if (reason !== void 0) byReason.set(reason, [...byReason.get(reason) ?? [], row.pkg.name]);
|
|
4079
4541
|
}
|
|
4080
|
-
return [...
|
|
4542
|
+
return [...byReason].map(([reason, names]) => ({
|
|
4081
4543
|
names,
|
|
4082
4544
|
reason
|
|
4083
4545
|
}));
|
|
4084
4546
|
};
|
|
4547
|
+
const runTone = (failed, skipped) => {
|
|
4548
|
+
if (failed > 0) return theme.danger;
|
|
4549
|
+
return skipped > 0 ? theme.warn : theme.ok;
|
|
4550
|
+
};
|
|
4551
|
+
const updatesNote = (offered, total, settled) => {
|
|
4552
|
+
if (offered > 0) return plural(offered, "update");
|
|
4553
|
+
if (!settled) return "checking…";
|
|
4554
|
+
return total > 0 ? "all up to date" : "";
|
|
4555
|
+
};
|
|
4556
|
+
const openCommand = (platform) => {
|
|
4557
|
+
if (platform === "darwin") return "open";
|
|
4558
|
+
return platform === "win32" ? "explorer" : "xdg-open";
|
|
4559
|
+
};
|
|
4560
|
+
const essential = 0;
|
|
4561
|
+
const leastStatusRoom = 12;
|
|
4562
|
+
const width = (list) => hintsWidth(list.map(([binding]) => binding));
|
|
4563
|
+
const lowestRanked = (list) => {
|
|
4564
|
+
let worst = 0;
|
|
4565
|
+
for (const [index, [, rank]] of list.entries()) if (rank >= (list[worst]?.[1] ?? 0)) worst = index;
|
|
4566
|
+
return worst;
|
|
4567
|
+
};
|
|
4568
|
+
const fitFooterHints = (hints, room, status) => {
|
|
4569
|
+
const kept = [...hints];
|
|
4570
|
+
const droppable = () => kept.some(([, rank]) => rank > essential);
|
|
4571
|
+
while (droppable() && width(kept) > room - status) kept.splice(lowestRanked(kept), 1);
|
|
4572
|
+
while (kept.length > 0 && width(kept) > room - leastStatusRoom) kept.pop();
|
|
4573
|
+
return kept.map(([binding]) => binding);
|
|
4574
|
+
};
|
|
4085
4575
|
const none = { _tag: "None" };
|
|
4086
4576
|
const sameAnchor = (left, right) => left?.key === right?.key && left?.section === right?.section && left?.index === right?.index;
|
|
4087
|
-
const confirmations = {
|
|
4088
|
-
update: {
|
|
4089
|
-
verb: "Update",
|
|
4090
|
-
done: "updated",
|
|
4091
|
-
tone: "accent"
|
|
4092
|
-
},
|
|
4093
|
-
uninstall: {
|
|
4094
|
-
verb: "Remove",
|
|
4095
|
-
done: "removed",
|
|
4096
|
-
tone: "danger"
|
|
4097
|
-
},
|
|
4098
|
-
audit: {
|
|
4099
|
-
verb: "Audit",
|
|
4100
|
-
done: "audited",
|
|
4101
|
-
tone: "accent"
|
|
4102
|
-
}
|
|
4103
|
-
};
|
|
4104
4577
|
const detailMin = 60;
|
|
4105
4578
|
const listMin = 60;
|
|
4106
4579
|
const chromeLines = 4;
|
|
4107
|
-
const clip = (text, width) => {
|
|
4108
|
-
if (Array.from(text).length <= width) return text;
|
|
4109
|
-
const trimmed = Array.from(text.trimEnd());
|
|
4110
|
-
if (trimmed.length <= width) return trimmed.join("");
|
|
4111
|
-
return width <= 0 ? "" : `${trimmed.slice(0, width - 1).join("")}…`;
|
|
4112
|
-
};
|
|
4113
|
-
const plural = (count, noun) => `${count} ${noun}${count === 1 ? "" : "s"}`;
|
|
4114
|
-
const capitalized = (text) => `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
4115
|
-
const listed = (names) => names.length <= 3 ? names.join(", ") : `${names.slice(0, 3).join(", ")} and ${names.length - 3} more`;
|
|
4116
4580
|
const home = homedir();
|
|
4117
4581
|
const tidy = (path) => home !== "" && (path === home || path.startsWith(`${home}/`)) ? `~${path.slice(home.length)}` : path;
|
|
4118
4582
|
const noticeLimit = 4;
|
|
4119
4583
|
const otherMode = (mode) => mode === "system" ? "project" : "system";
|
|
4120
|
-
const
|
|
4121
|
-
const flagged = new Set(pending.flagged.map((entry) => entry.row.key));
|
|
4122
|
-
return [...pending.rows.filter((row) => flagged.has(row.key)), ...pending.rows.filter((row) => !flagged.has(row.key))];
|
|
4123
|
-
};
|
|
4124
|
-
const confirmColumns = (pending, inner) => {
|
|
4125
|
-
const widest = (texts) => Math.max(0, ...texts.map((text) => Array.from(text).length));
|
|
4126
|
-
const current = Math.min(14, widest(pending.rows.map((row) => row.pkg.current)));
|
|
4127
|
-
const target = pending.action === "uninstall" ? 0 : 3 + Math.min(14, widest(pending.rows.map((row) => row.pkg.target ?? "")));
|
|
4128
|
-
const verdict = widest(pending.rows.map((row) => flaggedVerdict(pending, row).map((part) => part.text).join("")));
|
|
4129
|
-
const room = inner - 2 - 2 - current - target - verdict;
|
|
4130
|
-
const longest = widest(pending.rows.map((row) => row.pkg.name));
|
|
4131
|
-
const name = Math.max(6, Math.min(longest, room));
|
|
4132
|
-
const wanted = 8 + longest + 2 + current + target + verdict;
|
|
4133
|
-
return {
|
|
4134
|
-
name,
|
|
4135
|
-
current,
|
|
4136
|
-
target: Math.max(0, target - 3),
|
|
4137
|
-
wanted
|
|
4138
|
-
};
|
|
4139
|
-
};
|
|
4140
|
-
const flaggedVerdict = (pending, row) => {
|
|
4141
|
-
const verdict = pending.flagged.find((entry) => entry.row.key === row.key)?.verdict;
|
|
4142
|
-
const mixed = pending.unaudited.length > 0 && pending.unaudited.length < pending.rows.length;
|
|
4143
|
-
if (verdict === void 0 && pending.vendor.includes(row.key)) return [segment(theme.faint, ` ${isAppUpdate(row.pkg) ? "app" : "OS"} update · not audited`), ...pending.action === "update" && row.pkg.restart === true ? [segment(theme.warn, " · restarts")] : []];
|
|
4144
|
-
if (verdict === void 0) {
|
|
4145
|
-
if (pending.action === "update" && !pending.unaudited.includes(row.key)) return [segment(theme.ok, ` ${verdictIcons.ok} ${verdictLabels.ok}`)];
|
|
4146
|
-
const unread = pending.action === "update" && pending.unaudited.includes(row.key) && (mixed || !pending.auditFirst);
|
|
4147
|
-
if (pending.action === "update" && pending.breaking.includes(row.key)) return [segment(theme.warn, ` ${breakingMark}`), ...unread ? [segment(theme.faint, " · not audited")] : []];
|
|
4148
|
-
return unread ? [segment(theme.faint, " not audited")] : [];
|
|
4149
|
-
}
|
|
4150
|
-
if (verdict === "failed") return [segment(theme.danger, " ✗ audit failed")];
|
|
4151
|
-
return [segment(verdictColor(verdict), ` ${verdictIcons[verdict]} ${verdictLabels[verdict]}`)];
|
|
4152
|
-
};
|
|
4153
|
-
function App(props) {
|
|
4584
|
+
const App = (props) => {
|
|
4154
4585
|
const dimensions = useTerminalDimensions();
|
|
4155
4586
|
const [anchor, setAnchor] = createSignal(void 0, { equals: sameAnchor });
|
|
4156
4587
|
const [offset, setOffset] = createSignal(0);
|
|
@@ -4159,25 +4590,28 @@ function App(props) {
|
|
|
4159
4590
|
const [overlay, setOverlay] = createSignal(none);
|
|
4160
4591
|
const [quitting, setQuitting] = createSignal(false);
|
|
4161
4592
|
const [tab, setTab] = createSignal("about");
|
|
4162
|
-
const [listTop, setListTop] = createSignal(0);
|
|
4163
4593
|
const [fileAt, setFileAt] = createSignal(0);
|
|
4164
|
-
const [
|
|
4165
|
-
const [runNames, setRunNames] = createSignal(/* @__PURE__ */ new Map());
|
|
4594
|
+
const [run, setRun] = createSignal();
|
|
4166
4595
|
const [toast, setToast] = createSignal();
|
|
4167
4596
|
let toastTimer;
|
|
4168
4597
|
const showToast = (next) => {
|
|
4169
4598
|
clearTimeout(toastTimer);
|
|
4170
4599
|
setToast(next);
|
|
4171
|
-
if (next !== void 0) toastTimer = setTimeout(() =>
|
|
4600
|
+
if (next !== void 0) toastTimer = setTimeout(() => {
|
|
4601
|
+
setToast(void 0);
|
|
4602
|
+
}, 8e3);
|
|
4172
4603
|
};
|
|
4173
|
-
onCleanup(() =>
|
|
4604
|
+
onCleanup(() => {
|
|
4605
|
+
clearTimeout(toastTimer);
|
|
4606
|
+
});
|
|
4174
4607
|
let scroller;
|
|
4175
|
-
let helpScroller;
|
|
4176
4608
|
const loadedOnce = createMemo((was) => !props.state.discovering && (was || !props.state.providers.some((entry) => entry.status === "loading")), false);
|
|
4177
4609
|
const [fold, setFold] = createSignal("auto");
|
|
4178
4610
|
const grouped = createMemo(() => {
|
|
4179
4611
|
const found = groups(props.state, filter());
|
|
4180
|
-
const
|
|
4612
|
+
const updatesToDecideOn = !loadedOnce() || found.some((group) => group.kind === "updates");
|
|
4613
|
+
const foldsUntilToggled = filter() === "" && updatesToDecideOn;
|
|
4614
|
+
const folds = fold() === "auto" ? foldsUntilToggled : fold() === "hidden";
|
|
4181
4615
|
const kept = (row) => props.state.outcomes[row.key] !== void 0 || props.state.selected.includes(row.key);
|
|
4182
4616
|
return found.map((group) => group.kind === "current" && folds ? {
|
|
4183
4617
|
...group,
|
|
@@ -4188,19 +4622,27 @@ function App(props) {
|
|
|
4188
4622
|
const rows = createMemo(() => reachable(grouped()));
|
|
4189
4623
|
const allLines = createMemo(() => lines(grouped()));
|
|
4190
4624
|
const clamp = (index) => Math.max(0, Math.min(index, rows().length - 1));
|
|
4191
|
-
const sectionOf = (row) =>
|
|
4192
|
-
|
|
4193
|
-
|
|
4194
|
-
|
|
4625
|
+
const sectionOf = (row) => {
|
|
4626
|
+
if (props.state.removed[row.key] !== void 0) return "removed";
|
|
4627
|
+
if (row.pkg.target !== void 0) return "updates";
|
|
4628
|
+
return props.state.installed[row.key] === void 0 ? "current" : "updated";
|
|
4629
|
+
};
|
|
4630
|
+
const successorInSection = (held) => {
|
|
4195
4631
|
const all = rows();
|
|
4196
|
-
const index = all.findIndex((row) => row.key === held.key);
|
|
4197
|
-
const row = all[index];
|
|
4198
|
-
if (row !== void 0 && sectionOf(row) === held.section) return index;
|
|
4199
4632
|
const start = all.findIndex((other) => sectionOf(other) === held.section);
|
|
4200
|
-
if (start
|
|
4633
|
+
if (start === -1) return held.section === "updates" ? 0 : clamp(all.length - 1);
|
|
4201
4634
|
const end = all.findLastIndex((other) => sectionOf(other) === held.section);
|
|
4202
4635
|
return Math.min(start + held.index, end);
|
|
4203
4636
|
};
|
|
4637
|
+
const followAnchor = (held) => {
|
|
4638
|
+
const index = rows().findIndex((row) => row.key === held.key);
|
|
4639
|
+
const row = rows()[index];
|
|
4640
|
+
return row !== void 0 && sectionOf(row) === held.section ? index : successorInSection(held);
|
|
4641
|
+
};
|
|
4642
|
+
const cursor = () => {
|
|
4643
|
+
const held = anchor();
|
|
4644
|
+
return held === void 0 ? 0 : followAnchor(held);
|
|
4645
|
+
};
|
|
4204
4646
|
const anchorAt = (index) => {
|
|
4205
4647
|
const row = rows()[index];
|
|
4206
4648
|
if (row === void 0) return;
|
|
@@ -4235,11 +4677,11 @@ function App(props) {
|
|
|
4235
4677
|
}],
|
|
4236
4678
|
...props.state.providers.flatMap((entry) => entry.error === void 0 ? [] : [{
|
|
4237
4679
|
color: theme.danger,
|
|
4238
|
-
message: `✗ ${entry.name}: ${describeError(entry.error)}`
|
|
4680
|
+
message: `✗ ${providerLabel(entry.name)}: ${describeError(entry.error)}`
|
|
4239
4681
|
}]),
|
|
4240
4682
|
...props.state.providers.flatMap((entry) => entry.notices.filter((notice) => notice.rowKey === void 0 || !everyRow().some((row) => row.key === notice.rowKey)).map((notice) => ({
|
|
4241
4683
|
color: theme.warn,
|
|
4242
|
-
message: `! ${entry.name}: ${notice.message}`
|
|
4684
|
+
message: `! ${providerLabel(entry.name)}: ${notice.message}`
|
|
4243
4685
|
})))
|
|
4244
4686
|
].slice(0, noticeLimit);
|
|
4245
4687
|
});
|
|
@@ -4247,7 +4689,7 @@ function App(props) {
|
|
|
4247
4689
|
const fullList = () => Math.max(tableWidth(natural()) + 4, listMin);
|
|
4248
4690
|
const leastList = createMemo(() => Math.max(leastWidth(natural(), props.state.mode) + 4, listMin));
|
|
4249
4691
|
const split = () => dimensions().width >= leastList() + 1 + detailMin;
|
|
4250
|
-
const listWidth = () => Math.
|
|
4692
|
+
const listWidth = () => Math.max(leastList(), Math.min(fullList(), dimensions().width - 1 - detailMin, Math.floor(dimensions().width * .6)));
|
|
4251
4693
|
const contentHeight = () => Math.max(1, dimensions().height - chromeLines - notices().length);
|
|
4252
4694
|
const inventoryWidth = () => split() ? listWidth() : dimensions().width;
|
|
4253
4695
|
const columns = () => fitColumns(natural(), split() ? inventoryWidth() - 2 : inventoryWidth(), props.state.mode);
|
|
@@ -4258,6 +4700,8 @@ function App(props) {
|
|
|
4258
4700
|
return index <= 1 ? 0 : index;
|
|
4259
4701
|
};
|
|
4260
4702
|
const top = () => window(allLines().length, contentHeight(), focusLine(), offset());
|
|
4703
|
+
const places = /* @__PURE__ */ new Map();
|
|
4704
|
+
const [restoring, setRestoring] = createSignal();
|
|
4261
4705
|
const move = (to) => {
|
|
4262
4706
|
setRestoring(void 0);
|
|
4263
4707
|
anchorAt(clamp(to));
|
|
@@ -4284,20 +4728,19 @@ function App(props) {
|
|
|
4284
4728
|
setAnchor(void 0);
|
|
4285
4729
|
setOffset(0);
|
|
4286
4730
|
};
|
|
4287
|
-
const places = /* @__PURE__ */ new Map();
|
|
4288
|
-
const [restoring, setRestoring] = createSignal();
|
|
4289
4731
|
createEffect(() => {
|
|
4290
4732
|
const wanted = restoring();
|
|
4291
4733
|
if (wanted === void 0 || props.state.mode !== wanted.mode) return;
|
|
4292
4734
|
const index = rows().findIndex((row) => row.key === wanted.key);
|
|
4293
|
-
if (index
|
|
4735
|
+
if (index !== -1) {
|
|
4294
4736
|
anchorAt(index);
|
|
4295
4737
|
setOffset(top());
|
|
4296
4738
|
setRestoring(void 0);
|
|
4297
4739
|
} else if (!props.state.discovering && !props.state.providers.some((entry) => entry.status === "loading")) setRestoring(void 0);
|
|
4298
4740
|
});
|
|
4299
|
-
const fire = (effect) =>
|
|
4300
|
-
|
|
4741
|
+
const fire = (effect) => {
|
|
4742
|
+
props.run(effect);
|
|
4743
|
+
};
|
|
4301
4744
|
const shown = (wanted) => {
|
|
4302
4745
|
const row = focused();
|
|
4303
4746
|
return row !== void 0 && showDetails() && tab() === wanted ? row : void 0;
|
|
@@ -4309,7 +4752,7 @@ function App(props) {
|
|
|
4309
4752
|
const compared = createMemo(() => {
|
|
4310
4753
|
const row = shown("changes");
|
|
4311
4754
|
const pkg = row === void 0 ? void 0 : auditedAs(props.state, row.pkg);
|
|
4312
|
-
if (pkg?.target === void 0) return
|
|
4755
|
+
if (pkg?.target === void 0) return;
|
|
4313
4756
|
const key = auditKey(pkg, props.state.mode);
|
|
4314
4757
|
const missing = key !== void 0 && props.state.changes[key] === void 0 && auditOf(props.state, pkg)?._tag !== "Running";
|
|
4315
4758
|
return `${aboutKey(pkg)}${missing ? ":missing" : ""}`;
|
|
@@ -4323,12 +4766,17 @@ function App(props) {
|
|
|
4323
4766
|
if (key !== void 0 && row !== void 0) fire(props.session.describe(row.pkg));
|
|
4324
4767
|
}));
|
|
4325
4768
|
createEffect(on(compared, (key) => {
|
|
4326
|
-
if (key === void 0)
|
|
4769
|
+
if (key === void 0) {
|
|
4770
|
+
fire(props.session.readChanges(void 0));
|
|
4771
|
+
return;
|
|
4772
|
+
}
|
|
4327
4773
|
const timer = setTimeout(() => {
|
|
4328
4774
|
const row = untrack(focused);
|
|
4329
4775
|
fire(props.session.readChanges(row && auditedAs(props.state, row.pkg)));
|
|
4330
4776
|
}, 250);
|
|
4331
|
-
onCleanup(() =>
|
|
4777
|
+
onCleanup(() => {
|
|
4778
|
+
clearTimeout(timer);
|
|
4779
|
+
});
|
|
4332
4780
|
}));
|
|
4333
4781
|
const readTo = /* @__PURE__ */ new Map();
|
|
4334
4782
|
createEffect(on(() => [focused()?.key, tab()], ([key, now], before) => {
|
|
@@ -4349,24 +4797,24 @@ function App(props) {
|
|
|
4349
4797
|
}));
|
|
4350
4798
|
createEffect(on(() => props.state.running, (now, before) => {
|
|
4351
4799
|
if (before !== true || now) return;
|
|
4352
|
-
const
|
|
4353
|
-
|
|
4800
|
+
const last = untrack(run);
|
|
4801
|
+
if (last === void 0) return;
|
|
4802
|
+
const outcomes = last.targets.flatMap((target) => {
|
|
4803
|
+
const outcome = props.state.outcomes[target.key];
|
|
4354
4804
|
return outcome === void 0 ? [] : [outcome];
|
|
4355
4805
|
});
|
|
4356
4806
|
if (outcomes.length === 0) return;
|
|
4357
4807
|
const done = outcomes.filter((outcome) => outcome._tag === "Completed").length;
|
|
4358
4808
|
const failed = outcomes.filter((outcome) => outcome._tag === "Failed" || outcome._tag === "Unexpected").length;
|
|
4359
4809
|
const other = outcomes.length - done - failed;
|
|
4360
|
-
const
|
|
4361
|
-
const
|
|
4362
|
-
const removal = only !== void 0 && props.state.actions[only] === "uninstall";
|
|
4363
|
-
const parts = name !== void 0 && done === 1 ? [removal ? `✓ Removed ${name}` : `✓ ${name} updated`] : [
|
|
4810
|
+
const name = outcomes.length === 1 ? last.targets[0]?.name : void 0;
|
|
4811
|
+
const parts = name !== void 0 && done === 1 ? [last.action === "uninstall" ? `✓ Removed ${name}` : `✓ ${name} updated`] : [
|
|
4364
4812
|
...done > 0 ? [`✓ ${done} done`] : [],
|
|
4365
4813
|
...failed > 0 ? [`✗ ${failed} failed`] : [],
|
|
4366
4814
|
...other > 0 ? [`· ${other} skipped`] : []
|
|
4367
4815
|
];
|
|
4368
4816
|
showToast({
|
|
4369
|
-
color: failed
|
|
4817
|
+
color: runTone(failed, other),
|
|
4370
4818
|
text: parts.join(" ")
|
|
4371
4819
|
});
|
|
4372
4820
|
}));
|
|
@@ -4377,14 +4825,15 @@ function App(props) {
|
|
|
4377
4825
|
const only = finished.length === 1 ? finished[0]?.[1] : void 0;
|
|
4378
4826
|
const row = everyRow().find((entry) => auditOf(props.state, entry.pkg) === only);
|
|
4379
4827
|
if (only?._tag === "Done" && row !== void 0) {
|
|
4380
|
-
const result = only
|
|
4381
|
-
|
|
4828
|
+
const { result } = only;
|
|
4829
|
+
showToast(result._tag === "Failed" ? {
|
|
4382
4830
|
color: theme.danger,
|
|
4383
4831
|
text: `✗ ${row.pkg.name} audit failed`
|
|
4384
4832
|
} : {
|
|
4385
4833
|
color: verdictColor(result.report.verdict),
|
|
4386
4834
|
text: `${verdictIcons[result.report.verdict]} ${row.pkg.name} audited: ${verdictLabels[result.report.verdict]}`
|
|
4387
4835
|
});
|
|
4836
|
+
return;
|
|
4388
4837
|
}
|
|
4389
4838
|
showToast({
|
|
4390
4839
|
color: theme.accent,
|
|
@@ -4397,37 +4846,7 @@ function App(props) {
|
|
|
4397
4846
|
createEffect(() => {
|
|
4398
4847
|
if (tab() === "report" && props.state.catalogue === void 0) fire(props.session.loadCatalogue);
|
|
4399
4848
|
});
|
|
4400
|
-
const confirmWidth = (pending) => Math.min(Math.max(64, Math.min(confirmColumns(pending, 0).wanted, 90)), dimensions().width - 4);
|
|
4401
|
-
const confirmInner = () => {
|
|
4402
|
-
const pending = confirmation();
|
|
4403
|
-
return (pending === void 0 ? 64 : confirmWidth(pending)) - 6;
|
|
4404
|
-
};
|
|
4405
4849
|
const scrollDetails = (direction) => scroller?.scrollBy(direction * Math.max(1, Math.floor(contentHeight() / 2)));
|
|
4406
|
-
const flaggedSentence = (flagged) => {
|
|
4407
|
-
const only = flagged.length === 1 ? flagged[0] : void 0;
|
|
4408
|
-
if (only !== void 0) return only.verdict === "failed" ? `! ${only.row.pkg.name}'s audit did not complete, so it was not reviewed. Confirming installs it anyway.` : `! ${only.row.pkg.name} was audited: ${verdictLabels[only.verdict]}${only.top === void 0 ? "" : ` (${only.top})`}. Confirming installs it anyway.`;
|
|
4409
|
-
const failed = flagged.filter((entry) => entry.verdict === "failed").length;
|
|
4410
|
-
const reviewed = flagged.length - failed;
|
|
4411
|
-
return `! Of these, ${[...reviewed > 0 ? [`${reviewed} ${reviewed === 1 ? "has" : "have"} an audit warning`] : [], ...failed > 0 ? [`${failed} could not be audited`] : []].join(" and ")}. Confirming installs them anyway.`;
|
|
4412
|
-
};
|
|
4413
|
-
const confirmTone = (pending) => {
|
|
4414
|
-
if (pending.action === "uninstall") return "danger";
|
|
4415
|
-
if (pending.flagged.some((entry) => entry.verdict === "danger")) return "danger";
|
|
4416
|
-
return pending.flagged.length > 0 ? "warn" : "accent";
|
|
4417
|
-
};
|
|
4418
|
-
const destination = (pending) => {
|
|
4419
|
-
const providers = [...new Set(pending.rows.map((row) => providerLabel(row.pkg.provider)))].join(", ");
|
|
4420
|
-
const where = props.state.mode === "system" ? "on this machine" : `in ${tidy(props.state.scope)}`;
|
|
4421
|
-
return pending.action === "audit" ? `${where} · read-only, nothing will be installed` : `${where} · ${providers}`;
|
|
4422
|
-
};
|
|
4423
|
-
const signedOut = () => {
|
|
4424
|
-
const setup = props.state.preferences.setup;
|
|
4425
|
-
const catalogue = props.state.catalogue;
|
|
4426
|
-
if (setup === void 0 || catalogue?._tag !== "Ready") return void 0;
|
|
4427
|
-
const choice = catalogue.value.find((entry) => entry.provider === setup.provider && entry.modelId === setup.modelId);
|
|
4428
|
-
return choice === void 0 || choice.signedIn ? void 0 : choice.providerName;
|
|
4429
|
-
};
|
|
4430
|
-
const needsSignIn = (pending) => (pending.action === "audit" || pending.action === "update" && props.state.preferences.auditFirst && pending.vendor.length < pending.rows.length) && signedOut() !== void 0;
|
|
4431
4850
|
const confirm = (action) => {
|
|
4432
4851
|
if (action === "audit" || action === "update" && props.state.preferences.auditFirst) fire(props.session.loadCatalogue);
|
|
4433
4852
|
const focusedRow = focused();
|
|
@@ -4439,7 +4858,11 @@ function App(props) {
|
|
|
4439
4858
|
return;
|
|
4440
4859
|
}
|
|
4441
4860
|
const candidates = selectedRows().length > 0 ? selectedRows() : [focused()].filter((row) => row !== void 0);
|
|
4442
|
-
const why = (row) =>
|
|
4861
|
+
const why = (row) => {
|
|
4862
|
+
if (action === "uninstall") return row.pkg.unremovable;
|
|
4863
|
+
if (action === "audit") return unauditable(row.pkg);
|
|
4864
|
+
return row.pkg.elsewhere?.reason;
|
|
4865
|
+
};
|
|
4443
4866
|
const eligible = action === "uninstall" ? candidates : candidates.filter((row) => row.pkg.target !== void 0);
|
|
4444
4867
|
const refused = eligible.filter((row) => why(row) !== void 0);
|
|
4445
4868
|
const actionable = eligible.filter((row) => why(row) === void 0);
|
|
@@ -4454,32 +4877,30 @@ function App(props) {
|
|
|
4454
4877
|
row,
|
|
4455
4878
|
verdict: "failed"
|
|
4456
4879
|
}];
|
|
4457
|
-
const report = audit.result
|
|
4458
|
-
return report.verdict
|
|
4880
|
+
const { report } = audit.result;
|
|
4881
|
+
return report.verdict === "ok" ? [] : [{
|
|
4459
4882
|
row,
|
|
4460
4883
|
verdict: report.verdict,
|
|
4461
4884
|
top: topFinding(report)
|
|
4462
|
-
}]
|
|
4885
|
+
}];
|
|
4463
4886
|
}) : [];
|
|
4464
|
-
if (actionable.length > 0) {
|
|
4465
|
-
|
|
4466
|
-
|
|
4467
|
-
|
|
4468
|
-
|
|
4469
|
-
|
|
4470
|
-
|
|
4471
|
-
|
|
4472
|
-
|
|
4473
|
-
|
|
4474
|
-
|
|
4475
|
-
|
|
4476
|
-
|
|
4477
|
-
|
|
4478
|
-
|
|
4479
|
-
});
|
|
4480
|
-
} else if (refused.length > 0) {
|
|
4887
|
+
if (actionable.length > 0) setOverlay({
|
|
4888
|
+
_tag: "Confirm",
|
|
4889
|
+
pending: {
|
|
4890
|
+
action,
|
|
4891
|
+
rows: actionable,
|
|
4892
|
+
flagged,
|
|
4893
|
+
auditFirst: props.state.preferences.auditFirst,
|
|
4894
|
+
breaking: action === "update" ? actionable.filter((row) => majorsOf(props.state, row.pkg).length > 0).map((row) => row.key) : [],
|
|
4895
|
+
unaudited: action === "update" ? actionable.filter((row) => !isUnauditedUpdate(row.pkg) && auditOf(props.state, row.pkg)?._tag !== "Done").map((row) => row.key) : [],
|
|
4896
|
+
unauditable: actionable.filter((row) => isUnauditedUpdate(row.pkg)).map((row) => row.key),
|
|
4897
|
+
skipped: candidates.length - actionable.length - refused.length,
|
|
4898
|
+
refused: leftOut(refused, why)
|
|
4899
|
+
}
|
|
4900
|
+
});
|
|
4901
|
+
else if (refused.length > 0) {
|
|
4481
4902
|
const only = refused.length === 1 ? refused[0]?.pkg.name : void 0;
|
|
4482
|
-
const done = confirmations[action]
|
|
4903
|
+
const { done } = confirmations[action];
|
|
4483
4904
|
const opens = refused.some((row) => row.pkg.elsewhere !== void 0);
|
|
4484
4905
|
setOverlay({
|
|
4485
4906
|
_tag: "Notice",
|
|
@@ -4496,7 +4917,10 @@ function App(props) {
|
|
|
4496
4917
|
}
|
|
4497
4918
|
};
|
|
4498
4919
|
const quit = () => {
|
|
4499
|
-
if (!props.state.running)
|
|
4920
|
+
if (!props.state.running) {
|
|
4921
|
+
props.quit();
|
|
4922
|
+
return;
|
|
4923
|
+
}
|
|
4500
4924
|
setQuitting(true);
|
|
4501
4925
|
fire(props.session.stop.pipe(Effect.andThen(props.session.awaitIdle), Effect.andThen(Effect.sync(props.quit))));
|
|
4502
4926
|
};
|
|
@@ -4504,45 +4928,17 @@ function App(props) {
|
|
|
4504
4928
|
if (matches(keys.allow, key)) fire(props.session.answer(true));
|
|
4505
4929
|
else if (matches(keys.deny, key)) fire(props.session.answer(false));
|
|
4506
4930
|
};
|
|
4507
|
-
const
|
|
4508
|
-
|
|
4509
|
-
|
|
4510
|
-
|
|
4511
|
-
|
|
4512
|
-
|
|
4513
|
-
|
|
4514
|
-
|
|
4515
|
-
|
|
4516
|
-
const verb = confirmations[pending.action].verb.toLowerCase();
|
|
4517
|
-
if (pending.action === "uninstall") return keys.confirmRemove;
|
|
4518
|
-
if (needsSignIn(pending) || pending.flagged.length > 0) return {
|
|
4519
|
-
keys: ["y"],
|
|
4520
|
-
hint: "y",
|
|
4521
|
-
description: `${verb} anyway`
|
|
4522
|
-
};
|
|
4523
|
-
return {
|
|
4524
|
-
...keys.confirm,
|
|
4525
|
-
hint: "y/Enter",
|
|
4526
|
-
description: verb
|
|
4527
|
-
};
|
|
4528
|
-
};
|
|
4529
|
-
const onConfirmation = (key, pending) => {
|
|
4530
|
-
const last = Math.max(0, pending.rows.length - listRoom());
|
|
4531
|
-
if (matches(keys.down, key)) setListTop(Math.min(last, shownTop(pending) + 1));
|
|
4532
|
-
else if (matches(keys.up, key)) setListTop(Math.max(0, shownTop(pending) - 1));
|
|
4533
|
-
else if (needsSignIn(pending) && matches(signIn, key)) setOverlay({
|
|
4534
|
-
_tag: "Settings",
|
|
4535
|
-
back: pending
|
|
4931
|
+
const onConfirmation = (pending) => {
|
|
4932
|
+
setOverlay(none);
|
|
4933
|
+
const chosen = pending.rows.map((row) => row.key);
|
|
4934
|
+
if (pending.action !== "audit") setRun({
|
|
4935
|
+
action: pending.action,
|
|
4936
|
+
targets: pending.rows.map((row) => ({
|
|
4937
|
+
key: row.key,
|
|
4938
|
+
name: row.pkg.name
|
|
4939
|
+
}))
|
|
4536
4940
|
});
|
|
4537
|
-
|
|
4538
|
-
setOverlay(none);
|
|
4539
|
-
const chosen = pending.rows.map((row) => row.key);
|
|
4540
|
-
if (pending.action !== "audit") {
|
|
4541
|
-
setLastRun(chosen);
|
|
4542
|
-
setRunNames(new Map(pending.rows.map((row) => [row.key, row.pkg.name])));
|
|
4543
|
-
}
|
|
4544
|
-
fire(pending.action === "audit" ? props.session.audit(chosen) : props.session.run(pending.action, chosen, pending.flagged.map((entry) => entry.row.key)));
|
|
4545
|
-
} else if (matches(keys.cancel, key)) setOverlay(none);
|
|
4941
|
+
fire(pending.action === "audit" ? props.session.audit(chosen) : props.session.run(pending.action, chosen, pending.flagged.map((entry) => entry.row.key)));
|
|
4546
4942
|
};
|
|
4547
4943
|
const onFinding = (key) => {
|
|
4548
4944
|
if (matches(keys.keepFilter, key) && filter() === "") {
|
|
@@ -4556,7 +4952,7 @@ function App(props) {
|
|
|
4556
4952
|
return;
|
|
4557
4953
|
} else if (key.name === "backspace") setFilter((current) => current.slice(0, -1));
|
|
4558
4954
|
else if (key.ctrl && key.name === "u") setFilter("");
|
|
4559
|
-
else if (!key.ctrl && !key.meta &&
|
|
4955
|
+
else if (!key.ctrl && !key.meta && graphemes(key.sequence).length === 1 && key.sequence >= " ") setFilter((current) => current + key.sequence);
|
|
4560
4956
|
else return;
|
|
4561
4957
|
toFirst();
|
|
4562
4958
|
};
|
|
@@ -4582,23 +4978,24 @@ function App(props) {
|
|
|
4582
4978
|
const homepage = about?._tag === "Ready" ? about.value.homepage ?? about.value.repository : void 0;
|
|
4583
4979
|
const url = row?.pkg.elsewhere?.open ?? (homepage !== void 0 && /^https?:\/\//u.test(homepage) ? homepage : void 0);
|
|
4584
4980
|
if (url === void 0) return;
|
|
4585
|
-
const opener = process.platform
|
|
4981
|
+
const opener = openCommand(process.platform);
|
|
4586
4982
|
const child = spawn(opener, [url], {
|
|
4587
4983
|
detached: true,
|
|
4588
4984
|
stdio: "ignore"
|
|
4589
4985
|
});
|
|
4590
|
-
child.on("error", () =>
|
|
4591
|
-
|
|
4592
|
-
|
|
4593
|
-
|
|
4986
|
+
child.on("error", () => {
|
|
4987
|
+
showToast({
|
|
4988
|
+
color: theme.danger,
|
|
4989
|
+
text: `✗ Could not open ${url}`
|
|
4990
|
+
});
|
|
4991
|
+
});
|
|
4594
4992
|
child.unref();
|
|
4595
4993
|
showToast({
|
|
4596
4994
|
color: theme.accent,
|
|
4597
4995
|
text: `Opened ${row?.pkg.elsewhere?.app ?? url}`
|
|
4598
4996
|
});
|
|
4599
4997
|
};
|
|
4600
|
-
const helpColumns = () => dimensions().width >=
|
|
4601
|
-
const helpHeight = () => Math.max(...helpColumns().map((column) => column.reduce((sum, group, index) => sum + group.bindings.length + 1 + (index === 0 ? 0 : 1), 0)));
|
|
4998
|
+
const helpColumns = () => dimensions().width >= 88 ? [help.slice(0, 3), help.slice(3)] : [help];
|
|
4602
4999
|
const onInventory = (key) => {
|
|
4603
5000
|
const page = contentHeight() - 1;
|
|
4604
5001
|
if (reading() && matches(keys.down, key)) scroller?.scrollBy(1);
|
|
@@ -4668,21 +5065,21 @@ function App(props) {
|
|
|
4668
5065
|
};
|
|
4669
5066
|
useKeyboard((key) => {
|
|
4670
5067
|
const asked = question();
|
|
4671
|
-
if (asked !== void 0)
|
|
4672
|
-
|
|
4673
|
-
|
|
4674
|
-
|
|
5068
|
+
if (asked !== void 0) {
|
|
5069
|
+
if (asked._tag !== "Password") onDecision(key);
|
|
5070
|
+
return;
|
|
5071
|
+
}
|
|
5072
|
+
switch (overlay()._tag) {
|
|
5073
|
+
case "Settings":
|
|
5074
|
+
case "Confirm": return;
|
|
4675
5075
|
case "Help":
|
|
4676
|
-
if (matches(keys.down, key)) return helpScroller?.scrollBy(1);
|
|
4677
|
-
if (matches(keys.up, key)) return helpScroller?.scrollBy(-1);
|
|
4678
|
-
if (matches(keys.closeHelp, key)) return setOverlay(none);
|
|
4679
|
-
return;
|
|
4680
|
-
case "Confirm": return onConfirmation(key, now.pending);
|
|
4681
5076
|
case "Notice":
|
|
4682
5077
|
if (matches(keys.closeHelp, key)) setOverlay(none);
|
|
4683
5078
|
return;
|
|
4684
|
-
case "Find":
|
|
4685
|
-
|
|
5079
|
+
case "Find":
|
|
5080
|
+
onFinding(key);
|
|
5081
|
+
return;
|
|
5082
|
+
case "None": onInventory(key);
|
|
4686
5083
|
}
|
|
4687
5084
|
});
|
|
4688
5085
|
usePaste((event) => {
|
|
@@ -4690,18 +5087,17 @@ function App(props) {
|
|
|
4690
5087
|
setFilter((current) => current + pasted(event.bytes));
|
|
4691
5088
|
toFirst();
|
|
4692
5089
|
});
|
|
4693
|
-
const loading = () => props.state.providers.filter((entry) => entry.status === "loading").map((entry) => entry.name);
|
|
5090
|
+
const loading = () => props.state.providers.filter((entry) => entry.status === "loading").map((entry) => providerLabel(entry.name));
|
|
4694
5091
|
const scope = () => {
|
|
4695
5092
|
if (props.state.discovering || props.state.mode === "system") return "";
|
|
4696
5093
|
const path = tidy(props.state.scope);
|
|
4697
5094
|
return dimensions().width < 90 ? path.split("/").at(-1) ?? path : path;
|
|
4698
5095
|
};
|
|
4699
5096
|
const progress = () => {
|
|
4700
|
-
const
|
|
4701
|
-
const done =
|
|
4702
|
-
const total = Math.max(
|
|
4703
|
-
|
|
4704
|
-
return `Working… ${done} of ${total}${name === void 0 ? "" : ` · ${name}`}`;
|
|
5097
|
+
const targets = run()?.targets ?? [];
|
|
5098
|
+
const done = targets.filter((target) => props.state.outcomes[target.key] !== void 0).length;
|
|
5099
|
+
const total = Math.max(targets.length, done + Object.keys(props.state.activity).length);
|
|
5100
|
+
return `${run()?.action === "uninstall" ? "Removing" : "Updating"} ${done} of ${total}`;
|
|
4705
5101
|
};
|
|
4706
5102
|
const auditing = () => Object.values(props.state.audits).filter((audit) => audit._tag === "Running").length;
|
|
4707
5103
|
const summary = () => {
|
|
@@ -4710,16 +5106,19 @@ function App(props) {
|
|
|
4710
5106
|
if (props.state.running) return progress();
|
|
4711
5107
|
const all = rows();
|
|
4712
5108
|
const selected = selectedRows().length;
|
|
4713
|
-
const hidden = selectedRows().filter((row) => !all.some((
|
|
5109
|
+
const hidden = selectedRows().filter((row) => !all.some((visible) => visible.key === row.key)).length;
|
|
4714
5110
|
const total = everyRow().length;
|
|
4715
5111
|
const offeredOverall = everyRow().filter((row) => row.pkg.target !== void 0).length;
|
|
4716
5112
|
const settled = !props.state.discovering && loading().length === 0;
|
|
4717
5113
|
const matched = grouped().reduce((sum, group) => sum + group.rows.length, 0);
|
|
4718
5114
|
const count = filter() === "" ? plural(total, "package") : `${matched} of ${total} match`;
|
|
4719
|
-
const updates =
|
|
5115
|
+
const updates = updatesNote(offeredOverall, total, settled);
|
|
4720
5116
|
const picked = selected === 0 ? "" : ` · ${selected} selected${hidden > 0 ? ` (${hidden} hidden)` : ""}`;
|
|
4721
5117
|
const audits = auditing() > 0 ? `Auditing ${auditing()}… · ` : "";
|
|
4722
|
-
if (dimensions().width < 90)
|
|
5118
|
+
if (dimensions().width < 90) {
|
|
5119
|
+
const unfiltered = updates === "" ? count : updates;
|
|
5120
|
+
return `${audits}${filter() === "" ? unfiltered : `${matched}/${total} match`}${picked}`;
|
|
5121
|
+
}
|
|
4723
5122
|
const position = rows().length > contentHeight() ? ` · ${cursor() + 1}/${rows().length}` : "";
|
|
4724
5123
|
return `${audits}${count}${updates === "" ? "" : ` · ${updates}`}${picked}${position}`;
|
|
4725
5124
|
};
|
|
@@ -4765,13 +5164,14 @@ function App(props) {
|
|
|
4765
5164
|
...keys.nextFile,
|
|
4766
5165
|
description: "file"
|
|
4767
5166
|
}, 3]] : [],
|
|
4768
|
-
...filter()
|
|
4769
|
-
...keys.back,
|
|
4770
|
-
description: "clear filter"
|
|
4771
|
-
}, 0]] : picked ? [[{
|
|
5167
|
+
...filter() === "" && picked ? [[{
|
|
4772
5168
|
...keys.back,
|
|
4773
5169
|
description: "clear checks"
|
|
4774
5170
|
}, 3]] : [],
|
|
5171
|
+
...filter() === "" ? [] : [[{
|
|
5172
|
+
...keys.back,
|
|
5173
|
+
description: "clear filter"
|
|
5174
|
+
}, 0]],
|
|
4775
5175
|
...anything && !record ? [[keys.select, 2]] : [],
|
|
4776
5176
|
...actionable ? [[keys.update, 1]] : [],
|
|
4777
5177
|
...actionable ? [[keys.audit, picked ? 1 : 2]] : [],
|
|
@@ -4789,24 +5189,13 @@ function App(props) {
|
|
|
4789
5189
|
];
|
|
4790
5190
|
};
|
|
4791
5191
|
const footnote = () => {
|
|
4792
|
-
const
|
|
4793
|
-
return
|
|
5192
|
+
const latest = toast();
|
|
5193
|
+
return latest === void 0 ? summary() : `${summary()} ${latest.text}`;
|
|
4794
5194
|
};
|
|
4795
5195
|
const busy = () => props.state.running || auditing() > 0;
|
|
4796
5196
|
const footerRoom = () => dimensions().width - 2 - (busy() ? 2 : 0);
|
|
5197
|
+
const fitted = () => overlay()._tag !== "None" && !finding() ? [] : fitFooterHints(hints(), footerRoom(), graphemes(`${footnote()} `).length);
|
|
4797
5198
|
const statusRoom = () => footerRoom() - hintsWidth(fitted());
|
|
4798
|
-
const fitted = () => {
|
|
4799
|
-
if (overlay()._tag !== "None" && !finding()) return [];
|
|
4800
|
-
const width = (list) => hintsWidth(list.map(([binding]) => binding));
|
|
4801
|
-
const room = footerRoom() - Array.from(`${footnote()} `).length;
|
|
4802
|
-
const shown = [...hints()];
|
|
4803
|
-
while (shown.some(([, rank]) => rank > 0) && width(shown) > room) {
|
|
4804
|
-
const worst = shown.reduce((at, [, rank], index) => rank >= (shown[at]?.[1] ?? 0) ? index : at, 0);
|
|
4805
|
-
shown.splice(worst, 1);
|
|
4806
|
-
}
|
|
4807
|
-
while (shown.length > 0 && width(shown) > footerRoom() - 12) shown.pop();
|
|
4808
|
-
return shown.map(([binding]) => binding);
|
|
4809
|
-
};
|
|
4810
5199
|
return (() => {
|
|
4811
5200
|
var _el$ = createElement("box"), _el$2 = createElement("box"), _el$3 = createElement("text"), _el$5 = createElement("text"), _el$7 = createElement("text"), _el$10 = createElement("text"), _el$12 = createElement("text"), _el$14 = createElement("box"), _el$19 = createElement("text"), _el$21 = createElement("box"), _el$24 = createElement("text"), _el$25 = createElement("box");
|
|
4812
5201
|
insertNode(_el$, _el$2);
|
|
@@ -4832,20 +5221,20 @@ function App(props) {
|
|
|
4832
5221
|
insert(_el$2, createComponent(For, {
|
|
4833
5222
|
each: ["project", "system"],
|
|
4834
5223
|
children: (mode) => (() => {
|
|
4835
|
-
var _el$
|
|
4836
|
-
setProp(_el$
|
|
4837
|
-
setProp(_el$
|
|
4838
|
-
insert(_el$
|
|
5224
|
+
var _el$27 = createElement("text");
|
|
5225
|
+
setProp(_el$27, "flexShrink", 0);
|
|
5226
|
+
setProp(_el$27, "marginRight", 2);
|
|
5227
|
+
insert(_el$27, mode === "project" ? "Project" : "System");
|
|
4839
5228
|
effect((_p$) => {
|
|
4840
|
-
var _v$8 = props.state.mode === mode ? theme.strong : theme.
|
|
4841
|
-
_v$8 !== _p$.e && (_p$.e = setProp(_el$
|
|
4842
|
-
_v$9 !== _p$.t && (_p$.t = setProp(_el$
|
|
5229
|
+
var _v$8 = props.state.mode === mode ? theme.strong : theme.muted, _v$9 = props.state.mode === mode ? TextAttributes.BOLD | TextAttributes.UNDERLINE : TextAttributes.NONE;
|
|
5230
|
+
_v$8 !== _p$.e && (_p$.e = setProp(_el$27, "fg", _v$8, _p$.e));
|
|
5231
|
+
_v$9 !== _p$.t && (_p$.t = setProp(_el$27, "attributes", _v$9, _p$.t));
|
|
4843
5232
|
return _p$;
|
|
4844
5233
|
}, {
|
|
4845
5234
|
e: void 0,
|
|
4846
5235
|
t: void 0
|
|
4847
5236
|
});
|
|
4848
|
-
return _el$
|
|
5237
|
+
return _el$27;
|
|
4849
5238
|
})()
|
|
4850
5239
|
}), _el$7);
|
|
4851
5240
|
insert(_el$2, createComponent(Key, {
|
|
@@ -5027,14 +5416,14 @@ function App(props) {
|
|
|
5027
5416
|
return notices();
|
|
5028
5417
|
},
|
|
5029
5418
|
children: (notice) => (() => {
|
|
5030
|
-
var _el$
|
|
5031
|
-
insertNode(_el$
|
|
5032
|
-
setProp(_el$
|
|
5033
|
-
setProp(_el$
|
|
5034
|
-
setProp(_el$
|
|
5035
|
-
insert(_el$
|
|
5036
|
-
effect((_$p) => setProp(_el$
|
|
5037
|
-
return _el$
|
|
5419
|
+
var _el$28 = createElement("box"), _el$29 = createElement("text");
|
|
5420
|
+
insertNode(_el$28, _el$29);
|
|
5421
|
+
setProp(_el$28, "paddingLeft", 1);
|
|
5422
|
+
setProp(_el$28, "height", 1);
|
|
5423
|
+
setProp(_el$29, "truncate", true);
|
|
5424
|
+
insert(_el$29, () => notice.message);
|
|
5425
|
+
effect((_$p) => setProp(_el$29, "fg", notice.color, _$p));
|
|
5426
|
+
return _el$28;
|
|
5038
5427
|
})()
|
|
5039
5428
|
}), _el$19);
|
|
5040
5429
|
insertNode(_el$19, createTextNode(` `));
|
|
@@ -5065,20 +5454,20 @@ function App(props) {
|
|
|
5065
5454
|
get when() {
|
|
5066
5455
|
return toast();
|
|
5067
5456
|
},
|
|
5068
|
-
children: (
|
|
5069
|
-
var _el$
|
|
5070
|
-
setProp(_el$
|
|
5071
|
-
insert(_el$
|
|
5457
|
+
children: (note) => (() => {
|
|
5458
|
+
var _el$30 = createElement("text");
|
|
5459
|
+
setProp(_el$30, "flexShrink", 0);
|
|
5460
|
+
insert(_el$30, () => clip(`${note().text} `, statusRoom() - graphemes(`${summary()} `).length));
|
|
5072
5461
|
effect((_p$) => {
|
|
5073
|
-
var _v$0 =
|
|
5074
|
-
_v$0 !== _p$.e && (_p$.e = setProp(_el$
|
|
5075
|
-
_v$1 !== _p$.t && (_p$.t = setProp(_el$
|
|
5462
|
+
var _v$0 = note().color, _v$1 = TextAttributes.BOLD;
|
|
5463
|
+
_v$0 !== _p$.e && (_p$.e = setProp(_el$30, "fg", _v$0, _p$.e));
|
|
5464
|
+
_v$1 !== _p$.t && (_p$.t = setProp(_el$30, "attributes", _v$1, _p$.t));
|
|
5076
5465
|
return _p$;
|
|
5077
5466
|
}, {
|
|
5078
5467
|
e: void 0,
|
|
5079
5468
|
t: void 0
|
|
5080
5469
|
});
|
|
5081
|
-
return _el$
|
|
5470
|
+
return _el$30;
|
|
5082
5471
|
})()
|
|
5083
5472
|
}), _el$25);
|
|
5084
5473
|
setProp(_el$25, "flexGrow", 1);
|
|
@@ -5089,187 +5478,27 @@ function App(props) {
|
|
|
5089
5478
|
get when() {
|
|
5090
5479
|
return confirmation();
|
|
5091
5480
|
},
|
|
5092
|
-
children: (pending) => createComponent(
|
|
5093
|
-
get
|
|
5094
|
-
return
|
|
5481
|
+
children: (pending) => createComponent(ConfirmPopup, {
|
|
5482
|
+
get pending() {
|
|
5483
|
+
return pending();
|
|
5095
5484
|
},
|
|
5096
|
-
get
|
|
5097
|
-
return
|
|
5485
|
+
get state() {
|
|
5486
|
+
return props.state;
|
|
5098
5487
|
},
|
|
5099
|
-
get
|
|
5100
|
-
return
|
|
5488
|
+
get where() {
|
|
5489
|
+
return memo(() => props.state.mode === "system")() ? "on this machine" : `in ${tidy(props.state.scope)}`;
|
|
5101
5490
|
},
|
|
5102
|
-
|
|
5103
|
-
|
|
5104
|
-
...needsSignIn(pending()) ? [signIn] : [],
|
|
5105
|
-
confirmKey(pending()),
|
|
5106
|
-
keys.cancel
|
|
5107
|
-
];
|
|
5491
|
+
confirm: () => {
|
|
5492
|
+
onConfirmation(pending());
|
|
5108
5493
|
},
|
|
5109
|
-
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5113
|
-
|
|
5114
|
-
|
|
5115
|
-
|
|
5116
|
-
|
|
5117
|
-
return _el$32;
|
|
5118
|
-
})(),
|
|
5119
|
-
createComponent(Show, {
|
|
5120
|
-
get when() {
|
|
5121
|
-
return pending().skipped > 0;
|
|
5122
|
-
},
|
|
5123
|
-
get children() {
|
|
5124
|
-
var _el$33 = createElement("text");
|
|
5125
|
-
setProp(_el$33, "wrapMode", "word");
|
|
5126
|
-
insert(_el$33, () => `${pending().skipped} selected ${pending().skipped === 1 ? "package has" : "packages have"} no update and ${pending().skipped === 1 ? "is" : "are"} left out.`);
|
|
5127
|
-
effect((_$p) => setProp(_el$33, "fg", theme.muted, _$p));
|
|
5128
|
-
return _el$33;
|
|
5129
|
-
}
|
|
5130
|
-
}),
|
|
5131
|
-
createComponent(For, {
|
|
5132
|
-
get each() {
|
|
5133
|
-
return pending().refused;
|
|
5134
|
-
},
|
|
5135
|
-
children: (group) => (() => {
|
|
5136
|
-
var _el$45 = createElement("text");
|
|
5137
|
-
setProp(_el$45, "wrapMode", "word");
|
|
5138
|
-
insert(_el$45, () => `! Left out: ${listed(group.names)}. ${capitalized(group.reason)}.`);
|
|
5139
|
-
effect((_$p) => setProp(_el$45, "fg", theme.warn, _$p));
|
|
5140
|
-
return _el$45;
|
|
5141
|
-
})()
|
|
5142
|
-
}),
|
|
5143
|
-
(() => {
|
|
5144
|
-
var _el$34 = createElement("text");
|
|
5145
|
-
insertNode(_el$34, createTextNode(` `));
|
|
5146
|
-
return _el$34;
|
|
5147
|
-
})(),
|
|
5148
|
-
createComponent(Show, {
|
|
5149
|
-
get when() {
|
|
5150
|
-
return memo(() => !!(pending().action === "update" && props.state.preferences.auditFirst))() && pending().flagged.length + pending().vendor.length < pending().rows.length;
|
|
5151
|
-
},
|
|
5152
|
-
get children() {
|
|
5153
|
-
var _el$36 = createElement("text");
|
|
5154
|
-
setProp(_el$36, "wrapMode", "word");
|
|
5155
|
-
insert(_el$36, () => pending().flagged.length === 0 && pending().vendor.length === 0 ? "Each is audited first, and only those the audit finds ok are applied." : "The rest are audited first, and only those the audit finds ok are applied.");
|
|
5156
|
-
effect((_$p) => setProp(_el$36, "fg", theme.muted, _$p));
|
|
5157
|
-
return _el$36;
|
|
5158
|
-
}
|
|
5159
|
-
}),
|
|
5160
|
-
createComponent(Show, {
|
|
5161
|
-
get when() {
|
|
5162
|
-
return memo(() => pending().action === "update")() && pending().vendor.length > 0;
|
|
5163
|
-
},
|
|
5164
|
-
get children() {
|
|
5165
|
-
var _el$37 = createElement("text");
|
|
5166
|
-
insertNode(_el$37, createTextNode(`upup does not audit operating-system or app updates: confirming installs them as the vendor offers them, and upup asks for your password if sudo needs it.`));
|
|
5167
|
-
setProp(_el$37, "wrapMode", "word");
|
|
5168
|
-
effect((_$p) => setProp(_el$37, "fg", theme.muted, _$p));
|
|
5169
|
-
return _el$37;
|
|
5170
|
-
}
|
|
5171
|
-
}),
|
|
5172
|
-
createComponent(Show, {
|
|
5173
|
-
get when() {
|
|
5174
|
-
return pending().flagged.length > 0;
|
|
5175
|
-
},
|
|
5176
|
-
get children() {
|
|
5177
|
-
var _el$39 = createElement("text");
|
|
5178
|
-
setProp(_el$39, "wrapMode", "word");
|
|
5179
|
-
insert(_el$39, () => flaggedSentence(pending().flagged));
|
|
5180
|
-
effect((_$p) => setProp(_el$39, "fg", theme.warn, _$p));
|
|
5181
|
-
return _el$39;
|
|
5182
|
-
}
|
|
5183
|
-
}),
|
|
5184
|
-
createComponent(Show, {
|
|
5185
|
-
get when() {
|
|
5186
|
-
return memo(() => !!needsSignIn(pending()))() ? signedOut() : void 0;
|
|
5187
|
-
},
|
|
5188
|
-
children: (provider) => (() => {
|
|
5189
|
-
var _el$46 = createElement("text");
|
|
5190
|
-
setProp(_el$46, "wrapMode", "word");
|
|
5191
|
-
setProp(_el$46, "marginBottom", 1);
|
|
5192
|
-
insert(_el$46, () => `! upup is not signed in to ${provider()}, so no model can read this. Press Enter to sign in.`);
|
|
5193
|
-
effect((_$p) => setProp(_el$46, "fg", theme.warn, _$p));
|
|
5194
|
-
return _el$46;
|
|
5195
|
-
})()
|
|
5196
|
-
}),
|
|
5197
|
-
createComponent(Show, {
|
|
5198
|
-
get when() {
|
|
5199
|
-
return pending().action === "audit";
|
|
5200
|
-
},
|
|
5201
|
-
get children() {
|
|
5202
|
-
return [(() => {
|
|
5203
|
-
var _el$40 = createElement("text");
|
|
5204
|
-
insertNode(_el$40, createTextNode(`Both versions are downloaded and verified, and the model reads what changed.`));
|
|
5205
|
-
setProp(_el$40, "wrapMode", "word");
|
|
5206
|
-
effect((_$p) => setProp(_el$40, "fg", theme.muted, _$p));
|
|
5207
|
-
return _el$40;
|
|
5208
|
-
})(), createComponent(Show, {
|
|
5209
|
-
get when() {
|
|
5210
|
-
return props.state.preferences.setup;
|
|
5211
|
-
},
|
|
5212
|
-
children: (setup) => (() => {
|
|
5213
|
-
var _el$47 = createElement("box"), _el$48 = createElement("text"), _el$50 = createElement("text");
|
|
5214
|
-
insertNode(_el$47, _el$48);
|
|
5215
|
-
insertNode(_el$47, _el$50);
|
|
5216
|
-
setProp(_el$47, "flexDirection", "row");
|
|
5217
|
-
setProp(_el$47, "height", 1);
|
|
5218
|
-
setProp(_el$47, "marginTop", 1);
|
|
5219
|
-
insertNode(_el$48, createTextNode(`Model `));
|
|
5220
|
-
setProp(_el$48, "flexShrink", 0);
|
|
5221
|
-
setProp(_el$50, "flexShrink", 1);
|
|
5222
|
-
setProp(_el$50, "truncate", true);
|
|
5223
|
-
insert(_el$50, () => `${modelName(setup().provider, setup().modelId)} · ${setup().thinking} thinking`);
|
|
5224
|
-
effect((_p$) => {
|
|
5225
|
-
var _v$10 = theme.faint, _v$11 = theme.text;
|
|
5226
|
-
_v$10 !== _p$.e && (_p$.e = setProp(_el$48, "fg", _v$10, _p$.e));
|
|
5227
|
-
_v$11 !== _p$.t && (_p$.t = setProp(_el$50, "fg", _v$11, _p$.t));
|
|
5228
|
-
return _p$;
|
|
5229
|
-
}, {
|
|
5230
|
-
e: void 0,
|
|
5231
|
-
t: void 0
|
|
5232
|
-
});
|
|
5233
|
-
return _el$47;
|
|
5234
|
-
})()
|
|
5235
|
-
})];
|
|
5236
|
-
}
|
|
5237
|
-
}),
|
|
5238
|
-
createComponent(Show, {
|
|
5239
|
-
get when() {
|
|
5240
|
-
return pending().flagged.length > 0 || pending().action === "audit" || pending().action === "update" && (props.state.preferences.auditFirst || pending().vendor.length > 0);
|
|
5241
|
-
},
|
|
5242
|
-
get children() {
|
|
5243
|
-
var _el$42 = createElement("text");
|
|
5244
|
-
insertNode(_el$42, createTextNode(` `));
|
|
5245
|
-
return _el$42;
|
|
5246
|
-
}
|
|
5247
|
-
}),
|
|
5248
|
-
createComponent(For, {
|
|
5249
|
-
get each() {
|
|
5250
|
-
return flaggedFirst(pending()).slice(shownTop(pending()), shownTop(pending()) + listRoom());
|
|
5251
|
-
},
|
|
5252
|
-
children: (row) => createComponent(Segments, { get segments() {
|
|
5253
|
-
return [
|
|
5254
|
-
shrinking(theme.text, ` ${fitName(row.pkg.name, confirmColumns(pending(), confirmInner()).name)}`),
|
|
5255
|
-
segment(theme.muted, ` ${fit(row.pkg.current, confirmColumns(pending(), confirmInner()).current)}`),
|
|
5256
|
-
segment(theme.strong, pending().action === "uninstall" ? "" : ` → ${fit(row.pkg.target ?? "", confirmColumns(pending(), confirmInner()).target)}`),
|
|
5257
|
-
...flaggedVerdict(pending(), row)
|
|
5258
|
-
];
|
|
5259
|
-
} })
|
|
5260
|
-
}),
|
|
5261
|
-
createComponent(Show, {
|
|
5262
|
-
get when() {
|
|
5263
|
-
return pending().rows.length > listRoom();
|
|
5264
|
-
},
|
|
5265
|
-
get children() {
|
|
5266
|
-
var _el$44 = createElement("text");
|
|
5267
|
-
insert(_el$44, () => ` ${shownTop(pending()) + 1}–${Math.min(pending().rows.length, shownTop(pending()) + listRoom())} of ${pending().rows.length} · ↑↓ scroll`);
|
|
5268
|
-
effect((_$p) => setProp(_el$44, "fg", theme.faint, _$p));
|
|
5269
|
-
return _el$44;
|
|
5270
|
-
}
|
|
5271
|
-
})
|
|
5272
|
-
];
|
|
5494
|
+
cancel: () => {
|
|
5495
|
+
setOverlay(none);
|
|
5496
|
+
},
|
|
5497
|
+
signIn: () => {
|
|
5498
|
+
setOverlay({
|
|
5499
|
+
_tag: "Settings",
|
|
5500
|
+
back: pending()
|
|
5501
|
+
});
|
|
5273
5502
|
}
|
|
5274
5503
|
})
|
|
5275
5504
|
}), null);
|
|
@@ -5287,11 +5516,11 @@ function App(props) {
|
|
|
5287
5516
|
return [keys.closeHelp];
|
|
5288
5517
|
},
|
|
5289
5518
|
get children() {
|
|
5290
|
-
var _el$
|
|
5291
|
-
setProp(_el$
|
|
5292
|
-
insert(_el$
|
|
5293
|
-
effect((_$p) => setProp(_el$
|
|
5294
|
-
return _el$
|
|
5519
|
+
var _el$31 = createElement("text");
|
|
5520
|
+
setProp(_el$31, "wrapMode", "word");
|
|
5521
|
+
insert(_el$31, () => notice().text);
|
|
5522
|
+
effect((_$p) => setProp(_el$31, "fg", theme.text, _$p));
|
|
5523
|
+
return _el$31;
|
|
5295
5524
|
}
|
|
5296
5525
|
})
|
|
5297
5526
|
}), null);
|
|
@@ -5305,83 +5534,74 @@ function App(props) {
|
|
|
5305
5534
|
tone: "quiet",
|
|
5306
5535
|
width: 86,
|
|
5307
5536
|
bindings: [{
|
|
5308
|
-
keys: [],
|
|
5309
|
-
hint: "↑↓",
|
|
5310
|
-
description: "scroll"
|
|
5311
|
-
}, {
|
|
5312
5537
|
keys: [],
|
|
5313
5538
|
hint: "Esc",
|
|
5314
5539
|
description: "close"
|
|
5315
5540
|
}],
|
|
5541
|
+
scrolls: true,
|
|
5316
5542
|
get children() {
|
|
5317
|
-
var _el$26 = createElement("
|
|
5318
|
-
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
}, _el$26);
|
|
5322
|
-
setProp(_el$27, "flexDirection", "row");
|
|
5323
|
-
setProp(_el$27, "flexShrink", 0);
|
|
5324
|
-
insert(_el$27, createComponent(For, {
|
|
5543
|
+
var _el$26 = createElement("box");
|
|
5544
|
+
setProp(_el$26, "flexDirection", "row");
|
|
5545
|
+
setProp(_el$26, "flexShrink", 0);
|
|
5546
|
+
insert(_el$26, createComponent(For, {
|
|
5325
5547
|
get each() {
|
|
5326
5548
|
return helpColumns();
|
|
5327
5549
|
},
|
|
5328
5550
|
children: (column) => (() => {
|
|
5329
|
-
var _el$
|
|
5330
|
-
setProp(_el$
|
|
5331
|
-
setProp(_el$
|
|
5332
|
-
setProp(_el$
|
|
5333
|
-
setProp(_el$
|
|
5334
|
-
insert(_el$
|
|
5551
|
+
var _el$32 = createElement("box");
|
|
5552
|
+
setProp(_el$32, "flexDirection", "column");
|
|
5553
|
+
setProp(_el$32, "flexGrow", 1);
|
|
5554
|
+
setProp(_el$32, "flexBasis", 0);
|
|
5555
|
+
setProp(_el$32, "flexShrink", 0);
|
|
5556
|
+
insert(_el$32, createComponent(For, {
|
|
5335
5557
|
each: column,
|
|
5336
5558
|
children: (group, index) => (() => {
|
|
5337
|
-
var _el$
|
|
5338
|
-
insertNode(_el$
|
|
5339
|
-
setProp(_el$
|
|
5340
|
-
setProp(_el$
|
|
5341
|
-
setProp(_el$
|
|
5342
|
-
insert(_el$
|
|
5343
|
-
insert(_el$
|
|
5559
|
+
var _el$33 = createElement("box"), _el$34 = createElement("text");
|
|
5560
|
+
insertNode(_el$33, _el$34);
|
|
5561
|
+
setProp(_el$33, "flexDirection", "column");
|
|
5562
|
+
setProp(_el$33, "flexShrink", 0);
|
|
5563
|
+
setProp(_el$34, "flexShrink", 0);
|
|
5564
|
+
insert(_el$34, () => group.title);
|
|
5565
|
+
insert(_el$33, createComponent(For, {
|
|
5344
5566
|
get each() {
|
|
5345
5567
|
return group.bindings;
|
|
5346
5568
|
},
|
|
5347
5569
|
children: (binding) => (() => {
|
|
5348
|
-
var _el$
|
|
5349
|
-
insertNode(_el$
|
|
5350
|
-
insertNode(_el$
|
|
5351
|
-
setProp(_el$
|
|
5352
|
-
setProp(_el$
|
|
5353
|
-
setProp(_el$
|
|
5354
|
-
setProp(_el$
|
|
5355
|
-
setProp(_el$
|
|
5356
|
-
setProp(_el$
|
|
5357
|
-
insert(_el$
|
|
5570
|
+
var _el$35 = createElement("box"), _el$36 = createElement("box"), _el$37 = createElement("text");
|
|
5571
|
+
insertNode(_el$35, _el$36);
|
|
5572
|
+
insertNode(_el$35, _el$37);
|
|
5573
|
+
setProp(_el$35, "flexDirection", "row");
|
|
5574
|
+
setProp(_el$35, "height", 1);
|
|
5575
|
+
setProp(_el$35, "flexShrink", 0);
|
|
5576
|
+
setProp(_el$36, "width", 13);
|
|
5577
|
+
setProp(_el$36, "flexShrink", 0);
|
|
5578
|
+
setProp(_el$36, "flexDirection", "row");
|
|
5579
|
+
insert(_el$36, createComponent(Key, { get hint() {
|
|
5358
5580
|
return binding.hint ?? "";
|
|
5359
5581
|
} }));
|
|
5360
|
-
setProp(_el$
|
|
5361
|
-
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
return _el$55;
|
|
5582
|
+
setProp(_el$37, "flexShrink", 0);
|
|
5583
|
+
insert(_el$37, () => binding.description ?? "");
|
|
5584
|
+
effect((_$p) => setProp(_el$37, "fg", theme.text, _$p));
|
|
5585
|
+
return _el$35;
|
|
5365
5586
|
})()
|
|
5366
5587
|
}), null);
|
|
5367
5588
|
effect((_p$) => {
|
|
5368
|
-
var _v$
|
|
5369
|
-
_v$
|
|
5370
|
-
_v$
|
|
5371
|
-
_v$
|
|
5589
|
+
var _v$10 = index() === 0 ? 0 : 1, _v$11 = theme.accent, _v$12 = TextAttributes.BOLD;
|
|
5590
|
+
_v$10 !== _p$.e && (_p$.e = setProp(_el$33, "marginTop", _v$10, _p$.e));
|
|
5591
|
+
_v$11 !== _p$.t && (_p$.t = setProp(_el$34, "fg", _v$11, _p$.t));
|
|
5592
|
+
_v$12 !== _p$.a && (_p$.a = setProp(_el$34, "attributes", _v$12, _p$.a));
|
|
5372
5593
|
return _p$;
|
|
5373
5594
|
}, {
|
|
5374
5595
|
e: void 0,
|
|
5375
5596
|
t: void 0,
|
|
5376
5597
|
a: void 0
|
|
5377
5598
|
});
|
|
5378
|
-
return _el$
|
|
5599
|
+
return _el$33;
|
|
5379
5600
|
})()
|
|
5380
5601
|
}));
|
|
5381
|
-
return _el$
|
|
5602
|
+
return _el$32;
|
|
5382
5603
|
})()
|
|
5383
5604
|
}));
|
|
5384
|
-
effect((_$p) => setProp(_el$26, "height", Math.max(3, Math.min(helpHeight(), dimensions().height - 9)), _$p));
|
|
5385
5605
|
return _el$26;
|
|
5386
5606
|
}
|
|
5387
5607
|
});
|
|
@@ -5420,7 +5640,9 @@ function App(props) {
|
|
|
5420
5640
|
get request() {
|
|
5421
5641
|
return request();
|
|
5422
5642
|
},
|
|
5423
|
-
answer: (password) =>
|
|
5643
|
+
answer: (password) => {
|
|
5644
|
+
fire(props.session.answerPassword(password));
|
|
5645
|
+
}
|
|
5424
5646
|
})
|
|
5425
5647
|
}), null);
|
|
5426
5648
|
insert(_el$, createComponent(Show, {
|
|
@@ -5440,11 +5662,11 @@ function App(props) {
|
|
|
5440
5662
|
}, keys.deny];
|
|
5441
5663
|
},
|
|
5442
5664
|
get children() {
|
|
5443
|
-
var _el$
|
|
5444
|
-
setProp(_el$
|
|
5445
|
-
insert(_el$
|
|
5446
|
-
effect((_$p) => setProp(_el$
|
|
5447
|
-
return _el$
|
|
5665
|
+
var _el$38 = createElement("text");
|
|
5666
|
+
setProp(_el$38, "wrapMode", "word");
|
|
5667
|
+
insert(_el$38, () => `${running().app} is open. upup quits it to install its update, then opens it again. Unsaved work in it may be lost.`);
|
|
5668
|
+
effect((_$p) => setProp(_el$38, "fg", theme.text, _$p));
|
|
5669
|
+
return _el$38;
|
|
5448
5670
|
}
|
|
5449
5671
|
})
|
|
5450
5672
|
}), null);
|
|
@@ -5466,36 +5688,36 @@ function App(props) {
|
|
|
5466
5688
|
},
|
|
5467
5689
|
get fallback() {
|
|
5468
5690
|
return [(() => {
|
|
5469
|
-
var _el$
|
|
5470
|
-
setProp(_el$
|
|
5471
|
-
insert(_el$
|
|
5472
|
-
effect((_$p) => setProp(_el$
|
|
5473
|
-
return _el$
|
|
5691
|
+
var _el$42 = createElement("text");
|
|
5692
|
+
setProp(_el$42, "wrapMode", "word");
|
|
5693
|
+
insert(_el$42, () => `${blocked().command} wants to run install scripts that are not allowed:`);
|
|
5694
|
+
effect((_$p) => setProp(_el$42, "fg", theme.text, _$p));
|
|
5695
|
+
return _el$42;
|
|
5474
5696
|
})(), createComponent(For, {
|
|
5475
5697
|
get each() {
|
|
5476
5698
|
return blocked().scripts;
|
|
5477
5699
|
},
|
|
5478
5700
|
children: (script) => (() => {
|
|
5479
|
-
var _el$
|
|
5480
|
-
insert(_el$
|
|
5481
|
-
effect((_$p) => setProp(_el$
|
|
5482
|
-
return _el$
|
|
5701
|
+
var _el$43 = createElement("text");
|
|
5702
|
+
insert(_el$43, ` ${script}`);
|
|
5703
|
+
effect((_$p) => setProp(_el$43, "fg", theme.warn, _$p));
|
|
5704
|
+
return _el$43;
|
|
5483
5705
|
})()
|
|
5484
5706
|
})];
|
|
5485
5707
|
},
|
|
5486
5708
|
get children() {
|
|
5487
5709
|
return [(() => {
|
|
5488
|
-
var _el$
|
|
5489
|
-
setProp(_el$
|
|
5490
|
-
insert(_el$
|
|
5491
|
-
effect((_$p) => setProp(_el$
|
|
5492
|
-
return _el$
|
|
5710
|
+
var _el$39 = createElement("text");
|
|
5711
|
+
setProp(_el$39, "wrapMode", "word");
|
|
5712
|
+
insert(_el$39, () => `${blocked().command} failed in npm's strict-allow-scripts check before installing (an npm bug with new global install folders).`);
|
|
5713
|
+
effect((_$p) => setProp(_el$39, "fg", theme.text, _$p));
|
|
5714
|
+
return _el$39;
|
|
5493
5715
|
})(), (() => {
|
|
5494
|
-
var _el$
|
|
5495
|
-
insertNode(_el$
|
|
5496
|
-
setProp(_el$
|
|
5497
|
-
effect((_$p) => setProp(_el$
|
|
5498
|
-
return _el$
|
|
5716
|
+
var _el$40 = createElement("text");
|
|
5717
|
+
insertNode(_el$40, createTextNode(`Retrying turns the strict check off for this one command, so install scripts not on your allow list may run.`));
|
|
5718
|
+
setProp(_el$40, "wrapMode", "word");
|
|
5719
|
+
effect((_$p) => setProp(_el$40, "fg", theme.warn, _$p));
|
|
5720
|
+
return _el$40;
|
|
5499
5721
|
})()];
|
|
5500
5722
|
}
|
|
5501
5723
|
});
|
|
@@ -5503,7 +5725,7 @@ function App(props) {
|
|
|
5503
5725
|
})
|
|
5504
5726
|
}), null);
|
|
5505
5727
|
effect((_p$) => {
|
|
5506
|
-
var _v$3 = theme.onAccent, _v$4 = theme.accent, _v$5 = TextAttributes.BOLD, _v$6 = theme.
|
|
5728
|
+
var _v$3 = theme.onAccent, _v$4 = theme.accent, _v$5 = TextAttributes.BOLD, _v$6 = theme.muted, _v$7 = props.state.running ? theme.text : theme.muted;
|
|
5507
5729
|
_v$3 !== _p$.e && (_p$.e = setProp(_el$3, "fg", _v$3, _p$.e));
|
|
5508
5730
|
_v$4 !== _p$.t && (_p$.t = setProp(_el$3, "bg", _v$4, _p$.t));
|
|
5509
5731
|
_v$5 !== _p$.a && (_p$.a = setProp(_el$3, "attributes", _v$5, _p$.a));
|
|
@@ -5519,7 +5741,7 @@ function App(props) {
|
|
|
5519
5741
|
});
|
|
5520
5742
|
return _el$;
|
|
5521
5743
|
})();
|
|
5522
|
-
}
|
|
5744
|
+
};
|
|
5523
5745
|
// src/tui/Tui.tsx
|
|
5524
5746
|
const connect = Effect.fn("Tui.connect")(function* (projectDir) {
|
|
5525
5747
|
const session = yield* Session;
|
|
@@ -5549,16 +5771,24 @@ const connect = Effect.fn("Tui.connect")(function* (projectDir) {
|
|
|
5549
5771
|
});
|
|
5550
5772
|
const launch = Effect.fn("Tui.launch")(function* (projectDir) {
|
|
5551
5773
|
const { view, quit, done } = yield* connect(projectDir);
|
|
5552
|
-
const renderer = yield* Effect.acquireRelease(Effect.promise(() => createCliRenderer({ exitOnCtrlC: true })), (
|
|
5774
|
+
const renderer = yield* Effect.acquireRelease(Effect.promise(async () => await createCliRenderer({ exitOnCtrlC: true })), (created) => Effect.sync(() => {
|
|
5775
|
+
created.destroy();
|
|
5776
|
+
}));
|
|
5553
5777
|
renderer.on("destroy", quit);
|
|
5554
|
-
const adopt = Effect.promise(() =>
|
|
5555
|
-
|
|
5778
|
+
const adopt = Effect.promise(async () => {
|
|
5779
|
+
const colors = await renderer.getPalette({ timeout: 300 }).catch(() => void 0);
|
|
5780
|
+
if (colors !== void 0) setBackground(colors.defaultBackground);
|
|
5781
|
+
});
|
|
5782
|
+
setThemeMode(yield* Effect.promise(async () => await renderer.waitForThemeMode(300)));
|
|
5783
|
+
const context = yield* Effect.context();
|
|
5556
5784
|
yield* adopt;
|
|
5557
5785
|
renderer.on("theme_mode", (mode) => {
|
|
5558
5786
|
setThemeMode(mode);
|
|
5559
|
-
Effect.
|
|
5787
|
+
Effect.runPromiseWith(context)(adopt);
|
|
5788
|
+
});
|
|
5789
|
+
yield* Effect.promise(async () => {
|
|
5790
|
+
await render(view, renderer);
|
|
5560
5791
|
});
|
|
5561
|
-
yield* Effect.promise(() => render(view, renderer));
|
|
5562
5792
|
yield* done;
|
|
5563
5793
|
});
|
|
5564
5794
|
export { connect, launch };
|