yourskills 0.1.2 → 0.1.3
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 +22 -8
- package/dist/main.js +2533 -878
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -49,7 +49,13 @@ async function resolveAgents(flagAgents) {
|
|
|
49
49
|
return config.agents ?? [];
|
|
50
50
|
}
|
|
51
51
|
// src/settings/keys.ts
|
|
52
|
-
var CONFIG_KEYS = [
|
|
52
|
+
var CONFIG_KEYS = [
|
|
53
|
+
"scope",
|
|
54
|
+
"agents",
|
|
55
|
+
"server",
|
|
56
|
+
"track",
|
|
57
|
+
"autoUpdate"
|
|
58
|
+
];
|
|
53
59
|
function isConfigKey(key) {
|
|
54
60
|
return CONFIG_KEYS.includes(key);
|
|
55
61
|
}
|
|
@@ -65,6 +71,8 @@ function configValue(config, key) {
|
|
|
65
71
|
return config.serverUrl ?? UNSET;
|
|
66
72
|
case "track":
|
|
67
73
|
return config.track === undefined ? UNSET : String(config.track);
|
|
74
|
+
case "autoUpdate":
|
|
75
|
+
return String(config.autoUpdate !== false);
|
|
68
76
|
}
|
|
69
77
|
}
|
|
70
78
|
function setConfigValue(config, key, value) {
|
|
@@ -125,6 +133,17 @@ function setConfigValue(config, key, value) {
|
|
|
125
133
|
const track = value === "true";
|
|
126
134
|
return { ok: true, config: { ...config, track }, shown: String(track) };
|
|
127
135
|
}
|
|
136
|
+
case "autoUpdate": {
|
|
137
|
+
if (value !== "true" && value !== "false") {
|
|
138
|
+
return { ok: false, message: "autoUpdate must be `true` or `false`." };
|
|
139
|
+
}
|
|
140
|
+
const autoUpdate = value === "true";
|
|
141
|
+
return {
|
|
142
|
+
ok: true,
|
|
143
|
+
config: { ...config, autoUpdate },
|
|
144
|
+
shown: String(autoUpdate)
|
|
145
|
+
};
|
|
146
|
+
}
|
|
128
147
|
}
|
|
129
148
|
}
|
|
130
149
|
function configLines(config) {
|
|
@@ -367,17 +386,25 @@ async function requireToken(server) {
|
|
|
367
386
|
async function hasSession() {
|
|
368
387
|
return Boolean((await readConfig()).token);
|
|
369
388
|
}
|
|
389
|
+
async function localAccount(server) {
|
|
390
|
+
const config = await readConfig();
|
|
391
|
+
return {
|
|
392
|
+
signedIn: Boolean(config.token),
|
|
393
|
+
email: config.userEmail ?? null,
|
|
394
|
+
server: serverUrl(config, server)
|
|
395
|
+
};
|
|
396
|
+
}
|
|
370
397
|
// src/auth/screens/gate.tsx
|
|
371
|
-
import { Box as
|
|
398
|
+
import { Box as Box6, Text as Text8, useApp as useApp2, useInput as useInput3 } from "ink";
|
|
372
399
|
import {
|
|
373
400
|
useCallback,
|
|
374
401
|
useEffect as useEffect3,
|
|
375
402
|
useMemo,
|
|
376
|
-
useState as
|
|
403
|
+
useState as useState4
|
|
377
404
|
} from "react";
|
|
378
405
|
|
|
379
|
-
// src/ui/
|
|
380
|
-
import {
|
|
406
|
+
// src/ui/back.tsx
|
|
407
|
+
import { useInput } from "ink";
|
|
381
408
|
|
|
382
409
|
// ../../packages/ui/src/lib/ascii.ts
|
|
383
410
|
var DEFAULT_ASCII_CHARS = {
|
|
@@ -502,23 +529,157 @@ function clip(text, width) {
|
|
|
502
529
|
return width <= 1 ? text.slice(0, width) : `${text.slice(0, width - 1)}~`;
|
|
503
530
|
}
|
|
504
531
|
|
|
532
|
+
// ../../packages/skills/src/lifecycle.ts
|
|
533
|
+
var LIFECYCLES = [
|
|
534
|
+
{ status: "active", word: "active", glyph: "#", tone: "state-active" },
|
|
535
|
+
{
|
|
536
|
+
status: "experimental",
|
|
537
|
+
word: "experimental",
|
|
538
|
+
glyph: "?",
|
|
539
|
+
tone: "state-experimental"
|
|
540
|
+
},
|
|
541
|
+
{
|
|
542
|
+
status: "deprecated",
|
|
543
|
+
word: "deprecated",
|
|
544
|
+
glyph: "x",
|
|
545
|
+
tone: "state-deprecated"
|
|
546
|
+
}
|
|
547
|
+
];
|
|
548
|
+
var LIFECYCLE_ORDER = LIFECYCLES.map((lifecycle) => lifecycle.status);
|
|
549
|
+
var BY_STATUS = new Map(LIFECYCLES.map((lifecycle) => [lifecycle.status, lifecycle]));
|
|
550
|
+
function lifecycleOf(status) {
|
|
551
|
+
const lifecycle = BY_STATUS.get(status);
|
|
552
|
+
if (!lifecycle) {
|
|
553
|
+
throw new Error(`No lifecycle vocabulary for "${status}". Add it to LIFECYCLES.`);
|
|
554
|
+
}
|
|
555
|
+
return lifecycle;
|
|
556
|
+
}
|
|
557
|
+
// src/ui/rows.tsx
|
|
558
|
+
import { Box as Box2, Text as Text2 } from "ink";
|
|
559
|
+
import { jsx as jsx2, jsxs as jsxs2, Fragment } from "react/jsx-runtime";
|
|
560
|
+
function lifecycleTag(status) {
|
|
561
|
+
if (!status || status === "active")
|
|
562
|
+
return "";
|
|
563
|
+
return `[${lifecycleOf(status).word}]`;
|
|
564
|
+
}
|
|
565
|
+
function lifecycleColor(status) {
|
|
566
|
+
return stateTone[lifecycleOf(status ?? "active").tone];
|
|
567
|
+
}
|
|
568
|
+
var GUTTER = 4;
|
|
569
|
+
var GAP = 2;
|
|
570
|
+
function nameWidth(rows, max = 28) {
|
|
571
|
+
return Math.min(max, Math.max(8, ...rows.map((r) => r.name.length)));
|
|
572
|
+
}
|
|
573
|
+
function SkillRow({
|
|
574
|
+
row,
|
|
575
|
+
width,
|
|
576
|
+
names,
|
|
577
|
+
cursor,
|
|
578
|
+
selected,
|
|
579
|
+
selectable = false
|
|
580
|
+
}) {
|
|
581
|
+
const tag = lifecycleTag(row.status);
|
|
582
|
+
const meta = row.count !== undefined ? `${row.count} skills` : tag;
|
|
583
|
+
const gutter = selectable ? GUTTER : 0;
|
|
584
|
+
const rest = width - gutter - names - GAP - (meta ? meta.length + GAP : 0);
|
|
585
|
+
return /* @__PURE__ */ jsxs2(Box2, {
|
|
586
|
+
children: [
|
|
587
|
+
selectable ? /* @__PURE__ */ jsx2(Text2, {
|
|
588
|
+
color: cursor ? "cyan" : undefined,
|
|
589
|
+
children: `${cursor ? mark.cursor : " "} ${selected ? mark.selected : mark.unselected} `
|
|
590
|
+
}) : null,
|
|
591
|
+
/* @__PURE__ */ jsx2(Text2, {
|
|
592
|
+
bold: cursor,
|
|
593
|
+
color: lifecycleColor(row.status),
|
|
594
|
+
children: clip(row.name, names).padEnd(names)
|
|
595
|
+
}),
|
|
596
|
+
/* @__PURE__ */ jsx2(Text2, {
|
|
597
|
+
children: " ".repeat(GAP)
|
|
598
|
+
}),
|
|
599
|
+
/* @__PURE__ */ jsx2(Text2, {
|
|
600
|
+
dimColor: true,
|
|
601
|
+
children: clip(row.description ?? "", Math.max(rest, 0))
|
|
602
|
+
}),
|
|
603
|
+
meta ? /* @__PURE__ */ jsxs2(Fragment, {
|
|
604
|
+
children: [
|
|
605
|
+
/* @__PURE__ */ jsx2(Text2, {
|
|
606
|
+
children: " ".repeat(GAP)
|
|
607
|
+
}),
|
|
608
|
+
/* @__PURE__ */ jsx2(Text2, {
|
|
609
|
+
color: lifecycleColor(row.status),
|
|
610
|
+
dimColor: !tag,
|
|
611
|
+
children: meta
|
|
612
|
+
})
|
|
613
|
+
]
|
|
614
|
+
}) : null
|
|
615
|
+
]
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
function Hints({ hints }) {
|
|
619
|
+
return /* @__PURE__ */ jsx2(Box2, {
|
|
620
|
+
children: hints.map(([key, label], i) => /* @__PURE__ */ jsxs2(Text2, {
|
|
621
|
+
children: [
|
|
622
|
+
i > 0 ? /* @__PURE__ */ jsx2(Text2, {
|
|
623
|
+
dimColor: true,
|
|
624
|
+
children: " "
|
|
625
|
+
}) : null,
|
|
626
|
+
/* @__PURE__ */ jsx2(Text2, {
|
|
627
|
+
color: "cyan",
|
|
628
|
+
children: key
|
|
629
|
+
}),
|
|
630
|
+
/* @__PURE__ */ jsx2(Text2, {
|
|
631
|
+
dimColor: true,
|
|
632
|
+
children: ` ${label}`
|
|
633
|
+
})
|
|
634
|
+
]
|
|
635
|
+
}, key))
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// src/ui/back.tsx
|
|
640
|
+
import { jsx as jsx3, jsxs as jsxs3, Fragment as Fragment2 } from "react/jsx-runtime";
|
|
641
|
+
function Back({
|
|
642
|
+
width,
|
|
643
|
+
onBack,
|
|
644
|
+
extra = []
|
|
645
|
+
}) {
|
|
646
|
+
useInput((input, key) => {
|
|
647
|
+
if (key.escape || input === "x")
|
|
648
|
+
onBack?.();
|
|
649
|
+
}, { isActive: Boolean(onBack) });
|
|
650
|
+
if (!onBack)
|
|
651
|
+
return null;
|
|
652
|
+
return /* @__PURE__ */ jsxs3(Fragment2, {
|
|
653
|
+
children: [
|
|
654
|
+
/* @__PURE__ */ jsx3(Divider, {
|
|
655
|
+
width
|
|
656
|
+
}),
|
|
657
|
+
/* @__PURE__ */ jsx3(Hints, {
|
|
658
|
+
hints: [...extra, ["esc/x", "back"]]
|
|
659
|
+
})
|
|
660
|
+
]
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
// src/ui/command.tsx
|
|
664
|
+
import { Box as Box3, Text as Text4 } from "ink";
|
|
665
|
+
|
|
505
666
|
// src/ui/text-input.tsx
|
|
506
|
-
import { Text as
|
|
507
|
-
import { jsx as
|
|
667
|
+
import { Text as Text3 } from "ink";
|
|
668
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
508
669
|
function SearchInput({
|
|
509
670
|
value,
|
|
510
671
|
placeholder = "",
|
|
511
672
|
focus = true
|
|
512
673
|
}) {
|
|
513
|
-
return /* @__PURE__ */
|
|
674
|
+
return /* @__PURE__ */ jsxs4(Text3, {
|
|
514
675
|
children: [
|
|
515
|
-
value.length > 0 ? /* @__PURE__ */
|
|
676
|
+
value.length > 0 ? /* @__PURE__ */ jsx4(Text3, {
|
|
516
677
|
children: value
|
|
517
|
-
}) : /* @__PURE__ */
|
|
678
|
+
}) : /* @__PURE__ */ jsx4(Text3, {
|
|
518
679
|
dimColor: true,
|
|
519
680
|
children: placeholder
|
|
520
681
|
}),
|
|
521
|
-
focus ? /* @__PURE__ */
|
|
682
|
+
focus ? /* @__PURE__ */ jsx4(Text3, {
|
|
522
683
|
color: tone.primary,
|
|
523
684
|
children: "_"
|
|
524
685
|
}) : null
|
|
@@ -527,7 +688,7 @@ function SearchInput({
|
|
|
527
688
|
}
|
|
528
689
|
|
|
529
690
|
// src/ui/command.tsx
|
|
530
|
-
import { jsx as
|
|
691
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
531
692
|
function filterCommands(groups, query) {
|
|
532
693
|
if (query.length === 0)
|
|
533
694
|
return groups;
|
|
@@ -541,28 +702,28 @@ function flattenCommands(groups) {
|
|
|
541
702
|
return groups.flatMap((group) => group.items);
|
|
542
703
|
}
|
|
543
704
|
var POINTER = 2;
|
|
544
|
-
var
|
|
705
|
+
var GAP2 = 2;
|
|
545
706
|
function CommandRow({
|
|
546
707
|
item,
|
|
547
708
|
width,
|
|
548
709
|
active
|
|
549
710
|
}) {
|
|
550
711
|
const hint = item.hint ?? "";
|
|
551
|
-
const room = width - POINTER - (hint ? hint.length +
|
|
712
|
+
const room = width - POINTER - (hint ? hint.length + GAP2 : 0);
|
|
552
713
|
const label = clip(item.label, Math.max(room, 0));
|
|
553
714
|
const gap = Math.max(width - POINTER - label.length - hint.length, hint ? 1 : 0);
|
|
554
|
-
return /* @__PURE__ */
|
|
715
|
+
return /* @__PURE__ */ jsxs5(Text4, {
|
|
555
716
|
children: [
|
|
556
|
-
/* @__PURE__ */
|
|
717
|
+
/* @__PURE__ */ jsx5(Text4, {
|
|
557
718
|
color: tone.primary,
|
|
558
719
|
children: `${active ? mark.cursor : " "} `
|
|
559
720
|
}),
|
|
560
|
-
/* @__PURE__ */
|
|
721
|
+
/* @__PURE__ */ jsx5(Text4, {
|
|
561
722
|
bold: active,
|
|
562
723
|
color: active ? tone.primary : undefined,
|
|
563
724
|
children: label
|
|
564
725
|
}),
|
|
565
|
-
/* @__PURE__ */
|
|
726
|
+
/* @__PURE__ */ jsx5(Text4, {
|
|
566
727
|
dimColor: true,
|
|
567
728
|
children: `${" ".repeat(gap)}${hint}`
|
|
568
729
|
})
|
|
@@ -581,38 +742,38 @@ function CommandPalette({
|
|
|
581
742
|
const rows = flattenCommands(visible);
|
|
582
743
|
const current = rows[cursor];
|
|
583
744
|
const interior = width - FRAME_CHROME;
|
|
584
|
-
return /* @__PURE__ */
|
|
745
|
+
return /* @__PURE__ */ jsxs5(Box3, {
|
|
585
746
|
flexDirection: "column",
|
|
586
747
|
children: [
|
|
587
|
-
/* @__PURE__ */
|
|
748
|
+
/* @__PURE__ */ jsxs5(Box3, {
|
|
588
749
|
children: [
|
|
589
|
-
/* @__PURE__ */
|
|
750
|
+
/* @__PURE__ */ jsx5(Text4, {
|
|
590
751
|
color: tone.primary,
|
|
591
752
|
children: "> "
|
|
592
753
|
}),
|
|
593
|
-
/* @__PURE__ */
|
|
754
|
+
/* @__PURE__ */ jsx5(SearchInput, {
|
|
594
755
|
value: query,
|
|
595
756
|
placeholder
|
|
596
757
|
})
|
|
597
758
|
]
|
|
598
759
|
}),
|
|
599
|
-
/* @__PURE__ */
|
|
760
|
+
/* @__PURE__ */ jsx5(Divider, {
|
|
600
761
|
width
|
|
601
762
|
}),
|
|
602
|
-
rows.length === 0 ? /* @__PURE__ */
|
|
763
|
+
rows.length === 0 ? /* @__PURE__ */ jsx5(Text4, {
|
|
603
764
|
dimColor: true,
|
|
604
765
|
children: emptyMessage
|
|
605
|
-
}) : visible.map((group, i) => /* @__PURE__ */
|
|
766
|
+
}) : visible.map((group, i) => /* @__PURE__ */ jsxs5(Box3, {
|
|
606
767
|
flexDirection: "column",
|
|
607
768
|
children: [
|
|
608
|
-
i > 0 ? /* @__PURE__ */
|
|
769
|
+
i > 0 ? /* @__PURE__ */ jsx5(Divider, {
|
|
609
770
|
width
|
|
610
771
|
}) : null,
|
|
611
|
-
/* @__PURE__ */
|
|
772
|
+
/* @__PURE__ */ jsx5(Text4, {
|
|
612
773
|
dimColor: true,
|
|
613
774
|
children: group.group.toUpperCase()
|
|
614
775
|
}),
|
|
615
|
-
group.items.map((item) => /* @__PURE__ */
|
|
776
|
+
group.items.map((item) => /* @__PURE__ */ jsx5(CommandRow, {
|
|
616
777
|
item,
|
|
617
778
|
width: interior,
|
|
618
779
|
active: item.value === current?.value
|
|
@@ -622,143 +783,147 @@ function CommandPalette({
|
|
|
622
783
|
]
|
|
623
784
|
});
|
|
624
785
|
}
|
|
625
|
-
//
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
}
|
|
640
|
-
];
|
|
641
|
-
var LIFECYCLE_ORDER = LIFECYCLES.map((lifecycle) => lifecycle.status);
|
|
642
|
-
var BY_STATUS = new Map(LIFECYCLES.map((lifecycle) => [lifecycle.status, lifecycle]));
|
|
643
|
-
function lifecycleOf(status) {
|
|
644
|
-
const lifecycle = BY_STATUS.get(status);
|
|
645
|
-
if (!lifecycle) {
|
|
646
|
-
throw new Error(`No lifecycle vocabulary for "${status}". Add it to LIFECYCLES.`);
|
|
647
|
-
}
|
|
648
|
-
return lifecycle;
|
|
649
|
-
}
|
|
650
|
-
// src/ui/rows.tsx
|
|
651
|
-
import { Box as Box3, Text as Text4 } from "ink";
|
|
652
|
-
import { jsx as jsx4, jsxs as jsxs4, Fragment } from "react/jsx-runtime";
|
|
653
|
-
function lifecycleTag(status) {
|
|
654
|
-
if (!status || status === "active")
|
|
655
|
-
return "";
|
|
656
|
-
return `[${lifecycleOf(status).word}]`;
|
|
657
|
-
}
|
|
658
|
-
function lifecycleColor(status) {
|
|
659
|
-
return stateTone[lifecycleOf(status ?? "active").tone];
|
|
660
|
-
}
|
|
661
|
-
var GUTTER = 4;
|
|
662
|
-
var GAP2 = 2;
|
|
663
|
-
function nameWidth(rows, max = 28) {
|
|
664
|
-
return Math.min(max, Math.max(8, ...rows.map((r) => r.name.length)));
|
|
665
|
-
}
|
|
666
|
-
function SkillRow({
|
|
667
|
-
row,
|
|
668
|
-
width,
|
|
669
|
-
names,
|
|
670
|
-
cursor,
|
|
671
|
-
selected,
|
|
672
|
-
selectable = false
|
|
786
|
+
// src/ui/confirm.tsx
|
|
787
|
+
import { Box as Box4, Text as Text5, useInput as useInput2 } from "ink";
|
|
788
|
+
import { useState } from "react";
|
|
789
|
+
import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
790
|
+
function ConfirmScreen({
|
|
791
|
+
title,
|
|
792
|
+
headline,
|
|
793
|
+
lines,
|
|
794
|
+
notes = [],
|
|
795
|
+
yes,
|
|
796
|
+
no,
|
|
797
|
+
argv,
|
|
798
|
+
onYes,
|
|
799
|
+
onNo
|
|
673
800
|
}) {
|
|
674
|
-
const
|
|
675
|
-
const
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
children: clip(row.name, names).padEnd(names)
|
|
688
|
-
}),
|
|
689
|
-
/* @__PURE__ */ jsx4(Text4, {
|
|
690
|
-
children: " ".repeat(GAP2)
|
|
691
|
-
}),
|
|
692
|
-
/* @__PURE__ */ jsx4(Text4, {
|
|
693
|
-
dimColor: true,
|
|
694
|
-
children: clip(row.description ?? "", Math.max(rest, 0))
|
|
695
|
-
}),
|
|
696
|
-
meta ? /* @__PURE__ */ jsxs4(Fragment, {
|
|
697
|
-
children: [
|
|
698
|
-
/* @__PURE__ */ jsx4(Text4, {
|
|
699
|
-
children: " ".repeat(GAP2)
|
|
700
|
-
}),
|
|
701
|
-
/* @__PURE__ */ jsx4(Text4, {
|
|
702
|
-
color: lifecycleColor(row.status),
|
|
703
|
-
dimColor: !tag,
|
|
704
|
-
children: meta
|
|
705
|
-
})
|
|
706
|
-
]
|
|
707
|
-
}) : null
|
|
708
|
-
]
|
|
801
|
+
const width = useFrameWidth();
|
|
802
|
+
const [choice, setChoice] = useState("yes");
|
|
803
|
+
useInput2((input, key) => {
|
|
804
|
+
if (key.upArrow || key.downArrow) {
|
|
805
|
+
setChoice((c) => c === "yes" ? "no" : "yes");
|
|
806
|
+
} else if (key.return) {
|
|
807
|
+
if (choice === "yes")
|
|
808
|
+
onYes();
|
|
809
|
+
else
|
|
810
|
+
onNo();
|
|
811
|
+
} else if (key.escape || input === "x") {
|
|
812
|
+
onNo();
|
|
813
|
+
}
|
|
709
814
|
});
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
815
|
+
const interior = width - FRAME_CHROME;
|
|
816
|
+
const row = (label, active, hint) => {
|
|
817
|
+
const room = interior - 2 - (hint ? hint.length + 2 : 0);
|
|
818
|
+
const text = clip(label, Math.max(room, 0));
|
|
819
|
+
const gap = Math.max(interior - 2 - text.length - (hint?.length ?? 0), 1);
|
|
820
|
+
return /* @__PURE__ */ jsxs6(Text5, {
|
|
714
821
|
children: [
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
children: "
|
|
718
|
-
})
|
|
719
|
-
/* @__PURE__ */
|
|
720
|
-
|
|
721
|
-
|
|
822
|
+
/* @__PURE__ */ jsx6(Text5, {
|
|
823
|
+
color: tone.primary,
|
|
824
|
+
children: `${active ? mark.cursor : " "} `
|
|
825
|
+
}),
|
|
826
|
+
/* @__PURE__ */ jsx6(Text5, {
|
|
827
|
+
bold: active,
|
|
828
|
+
color: active ? tone.primary : undefined,
|
|
829
|
+
children: text
|
|
722
830
|
}),
|
|
723
|
-
/* @__PURE__ */
|
|
831
|
+
hint ? /* @__PURE__ */ jsx6(Text5, {
|
|
724
832
|
dimColor: true,
|
|
725
|
-
children:
|
|
726
|
-
})
|
|
833
|
+
children: `${" ".repeat(gap)}${hint}`
|
|
834
|
+
}) : null
|
|
727
835
|
]
|
|
728
|
-
}
|
|
836
|
+
});
|
|
837
|
+
};
|
|
838
|
+
return /* @__PURE__ */ jsxs6(Frame, {
|
|
839
|
+
title,
|
|
840
|
+
width,
|
|
841
|
+
children: [
|
|
842
|
+
/* @__PURE__ */ jsxs6(Box4, {
|
|
843
|
+
flexDirection: "column",
|
|
844
|
+
children: [
|
|
845
|
+
/* @__PURE__ */ jsx6(Text5, {
|
|
846
|
+
color: tone.notice,
|
|
847
|
+
children: clip(headline, interior)
|
|
848
|
+
}),
|
|
849
|
+
/* @__PURE__ */ jsx6(Text5, {
|
|
850
|
+
children: " "
|
|
851
|
+
}),
|
|
852
|
+
lines.map((line) => /* @__PURE__ */ jsxs6(Text5, {
|
|
853
|
+
children: [
|
|
854
|
+
/* @__PURE__ */ jsx6(Text5, {
|
|
855
|
+
color: line.mark === "fail" ? tone.danger : undefined,
|
|
856
|
+
children: line.mark === "none" ? " " : `${MARK[line.mark]} `
|
|
857
|
+
}),
|
|
858
|
+
/* @__PURE__ */ jsx6(Text5, {
|
|
859
|
+
children: clip(line.text, interior - 2)
|
|
860
|
+
}),
|
|
861
|
+
line.note ? /* @__PURE__ */ jsx6(Text5, {
|
|
862
|
+
dimColor: true,
|
|
863
|
+
children: clip(` ${line.note}`, Math.max(interior - 2 - line.text.length, 0))
|
|
864
|
+
}) : null
|
|
865
|
+
]
|
|
866
|
+
}, `${line.mark}:${line.text}`)),
|
|
867
|
+
notes.length > 0 ? /* @__PURE__ */ jsx6(Text5, {
|
|
868
|
+
children: " "
|
|
869
|
+
}) : null,
|
|
870
|
+
notes.map((note) => /* @__PURE__ */ jsx6(Text5, {
|
|
871
|
+
dimColor: true,
|
|
872
|
+
children: clip(note, interior)
|
|
873
|
+
}, note)),
|
|
874
|
+
/* @__PURE__ */ jsx6(Text5, {
|
|
875
|
+
children: " "
|
|
876
|
+
}),
|
|
877
|
+
row(yes, choice === "yes", argv),
|
|
878
|
+
row(no, choice === "no")
|
|
879
|
+
]
|
|
880
|
+
}),
|
|
881
|
+
/* @__PURE__ */ jsx6(Divider, {
|
|
882
|
+
width
|
|
883
|
+
}),
|
|
884
|
+
/* @__PURE__ */ jsx6(Hints, {
|
|
885
|
+
hints: [
|
|
886
|
+
["^v", "choose"],
|
|
887
|
+
["enter", choice === "yes" ? yes : no],
|
|
888
|
+
["esc", no]
|
|
889
|
+
]
|
|
890
|
+
})
|
|
891
|
+
]
|
|
729
892
|
});
|
|
730
893
|
}
|
|
894
|
+
var MARK = { ok: mark.ok, fail: mark.fail, pending: mark.pending };
|
|
731
895
|
// src/ui/spinner.tsx
|
|
732
|
-
import { Text as
|
|
733
|
-
import { useEffect, useState } from "react";
|
|
734
|
-
import { jsx as
|
|
896
|
+
import { Text as Text6 } from "ink";
|
|
897
|
+
import { useEffect, useState as useState2 } from "react";
|
|
898
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
735
899
|
var FRAMES = ["-", "\\", "|", "/"];
|
|
736
900
|
var INTERVAL_MS = 90;
|
|
737
901
|
function Spinner() {
|
|
738
|
-
const [frame, setFrame] =
|
|
902
|
+
const [frame, setFrame] = useState2(0);
|
|
739
903
|
useEffect(() => {
|
|
740
904
|
const timer = setInterval(() => setFrame((f) => (f + 1) % FRAMES.length), INTERVAL_MS);
|
|
741
905
|
return () => clearInterval(timer);
|
|
742
906
|
}, []);
|
|
743
|
-
return /* @__PURE__ */
|
|
907
|
+
return /* @__PURE__ */ jsx7(Text6, {
|
|
744
908
|
color: tone.primary,
|
|
745
909
|
children: FRAMES[frame]
|
|
746
910
|
});
|
|
747
911
|
}
|
|
748
912
|
// src/auth/screens/login.tsx
|
|
749
|
-
import { Box as
|
|
750
|
-
import { useEffect as useEffect2, useState as
|
|
751
|
-
import { jsx as
|
|
913
|
+
import { Box as Box5, Text as Text7, useApp } from "ink";
|
|
914
|
+
import { useEffect as useEffect2, useState as useState3 } from "react";
|
|
915
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
752
916
|
function minutesLeft(expiresAt) {
|
|
753
917
|
return Math.max(0, Math.ceil((expiresAt - Date.now()) / 60000));
|
|
754
918
|
}
|
|
755
919
|
function LoginScreen({
|
|
756
920
|
onError,
|
|
757
|
-
onDone
|
|
921
|
+
onDone,
|
|
922
|
+
onBack
|
|
758
923
|
}) {
|
|
759
924
|
const { exit } = useApp();
|
|
760
925
|
const width = useFrameWidth();
|
|
761
|
-
const [state, setState] =
|
|
926
|
+
const [state, setState] = useState3({ phase: "starting" });
|
|
762
927
|
useEffect2(() => {
|
|
763
928
|
let live = true;
|
|
764
929
|
(async () => {
|
|
@@ -789,16 +954,16 @@ function LoginScreen({
|
|
|
789
954
|
};
|
|
790
955
|
}, [exit, onError, onDone]);
|
|
791
956
|
if (state.phase === "done") {
|
|
792
|
-
return /* @__PURE__ */
|
|
957
|
+
return /* @__PURE__ */ jsx8(Frame, {
|
|
793
958
|
title: "login",
|
|
794
959
|
width,
|
|
795
|
-
children: /* @__PURE__ */
|
|
960
|
+
children: /* @__PURE__ */ jsxs7(Text7, {
|
|
796
961
|
children: [
|
|
797
|
-
/* @__PURE__ */
|
|
962
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
798
963
|
color: "green",
|
|
799
964
|
children: mark.ok
|
|
800
965
|
}),
|
|
801
|
-
/* @__PURE__ */
|
|
966
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
802
967
|
children: ` Logged in${state.email ? ` as ${state.email}` : ""}.`
|
|
803
968
|
})
|
|
804
969
|
]
|
|
@@ -806,66 +971,78 @@ function LoginScreen({
|
|
|
806
971
|
});
|
|
807
972
|
}
|
|
808
973
|
if (state.phase === "starting") {
|
|
809
|
-
return /* @__PURE__ */
|
|
974
|
+
return /* @__PURE__ */ jsxs7(Frame, {
|
|
810
975
|
title: "login",
|
|
811
976
|
width,
|
|
812
|
-
children:
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
977
|
+
children: [
|
|
978
|
+
/* @__PURE__ */ jsxs7(Text7, {
|
|
979
|
+
children: [
|
|
980
|
+
/* @__PURE__ */ jsx8(Spinner, {}),
|
|
981
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
982
|
+
dimColor: true,
|
|
983
|
+
children: " Requesting a device code..."
|
|
984
|
+
})
|
|
985
|
+
]
|
|
986
|
+
}),
|
|
987
|
+
/* @__PURE__ */ jsx8(Back, {
|
|
988
|
+
width,
|
|
989
|
+
onBack
|
|
990
|
+
})
|
|
991
|
+
]
|
|
821
992
|
});
|
|
822
993
|
}
|
|
823
994
|
const { prompt } = state;
|
|
824
|
-
return /* @__PURE__ */
|
|
995
|
+
return /* @__PURE__ */ jsxs7(Frame, {
|
|
825
996
|
title: "login",
|
|
826
997
|
width,
|
|
827
|
-
children:
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
998
|
+
children: [
|
|
999
|
+
/* @__PURE__ */ jsxs7(Box5, {
|
|
1000
|
+
flexDirection: "column",
|
|
1001
|
+
children: [
|
|
1002
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
1003
|
+
dimColor: true,
|
|
1004
|
+
children: "Open this URL in your browser:"
|
|
1005
|
+
}),
|
|
1006
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
1007
|
+
color: tone.primary,
|
|
1008
|
+
children: prompt.verificationUri
|
|
1009
|
+
}),
|
|
1010
|
+
/* @__PURE__ */ jsx8(Box5, {
|
|
1011
|
+
height: 1
|
|
1012
|
+
}),
|
|
1013
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
1014
|
+
dimColor: true,
|
|
1015
|
+
children: "and enter the code:"
|
|
1016
|
+
}),
|
|
1017
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
1018
|
+
bold: true,
|
|
1019
|
+
color: tone.notice,
|
|
1020
|
+
children: prompt.userCode
|
|
1021
|
+
}),
|
|
1022
|
+
/* @__PURE__ */ jsx8(Box5, {
|
|
1023
|
+
height: 1
|
|
1024
|
+
}),
|
|
1025
|
+
/* @__PURE__ */ jsxs7(Text7, {
|
|
1026
|
+
children: [
|
|
1027
|
+
/* @__PURE__ */ jsx8(Spinner, {}),
|
|
1028
|
+
/* @__PURE__ */ jsx8(Text7, {
|
|
1029
|
+
dimColor: true,
|
|
1030
|
+
children: ` Waiting for approval — expires in ${minutesLeft(prompt.expiresAt)} min`
|
|
1031
|
+
})
|
|
1032
|
+
]
|
|
1033
|
+
})
|
|
1034
|
+
]
|
|
1035
|
+
}),
|
|
1036
|
+
/* @__PURE__ */ jsx8(Back, {
|
|
1037
|
+
width,
|
|
1038
|
+
onBack
|
|
1039
|
+
})
|
|
1040
|
+
]
|
|
864
1041
|
});
|
|
865
1042
|
}
|
|
866
1043
|
|
|
867
1044
|
// src/auth/screens/gate.tsx
|
|
868
|
-
import { jsx as
|
|
1045
|
+
import { jsx as jsx9, jsxs as jsxs8, Fragment as Fragment3 } from "react/jsx-runtime";
|
|
869
1046
|
function AuthGate({
|
|
870
1047
|
title,
|
|
871
1048
|
build,
|
|
@@ -875,7 +1052,7 @@ function AuthGate({
|
|
|
875
1052
|
}) {
|
|
876
1053
|
const { exit } = useApp2();
|
|
877
1054
|
const width = useFrameWidth();
|
|
878
|
-
const [phase, setPhase] =
|
|
1055
|
+
const [phase, setPhase] = useState4({ kind: "checking" });
|
|
879
1056
|
const open = useCallback(() => {
|
|
880
1057
|
connect().then((client) => {
|
|
881
1058
|
process.exitCode = 0;
|
|
@@ -899,7 +1076,7 @@ function AuthGate({
|
|
|
899
1076
|
live = false;
|
|
900
1077
|
};
|
|
901
1078
|
}, [check, open, onError]);
|
|
902
|
-
|
|
1079
|
+
useInput3((input, key) => {
|
|
903
1080
|
if (input === "l")
|
|
904
1081
|
setPhase({ kind: "logging-in" });
|
|
905
1082
|
if (input === "q" || key.escape)
|
|
@@ -907,67 +1084,67 @@ function AuthGate({
|
|
|
907
1084
|
}, { isActive: phase.kind === "blocked" });
|
|
908
1085
|
const child = useMemo(() => phase.kind === "ready" ? build(phase.client) : null, [phase, build]);
|
|
909
1086
|
if (phase.kind === "ready")
|
|
910
|
-
return /* @__PURE__ */
|
|
1087
|
+
return /* @__PURE__ */ jsx9(Fragment3, {
|
|
911
1088
|
children: child
|
|
912
1089
|
});
|
|
913
1090
|
if (phase.kind === "logging-in")
|
|
914
|
-
return /* @__PURE__ */
|
|
1091
|
+
return /* @__PURE__ */ jsx9(LoginScreen, {
|
|
915
1092
|
onError,
|
|
916
1093
|
onDone: open
|
|
917
1094
|
});
|
|
918
1095
|
if (phase.kind === "checking")
|
|
919
|
-
return /* @__PURE__ */
|
|
1096
|
+
return /* @__PURE__ */ jsx9(Frame, {
|
|
920
1097
|
title,
|
|
921
1098
|
width,
|
|
922
|
-
children: /* @__PURE__ */
|
|
1099
|
+
children: /* @__PURE__ */ jsxs8(Text8, {
|
|
923
1100
|
children: [
|
|
924
|
-
/* @__PURE__ */
|
|
925
|
-
/* @__PURE__ */
|
|
1101
|
+
/* @__PURE__ */ jsx9(Spinner, {}),
|
|
1102
|
+
/* @__PURE__ */ jsx9(Text8, {
|
|
926
1103
|
dimColor: true,
|
|
927
1104
|
children: " Checking session..."
|
|
928
1105
|
})
|
|
929
1106
|
]
|
|
930
1107
|
})
|
|
931
1108
|
});
|
|
932
|
-
return /* @__PURE__ */
|
|
1109
|
+
return /* @__PURE__ */ jsx9(Frame, {
|
|
933
1110
|
title,
|
|
934
1111
|
width,
|
|
935
|
-
children: /* @__PURE__ */
|
|
1112
|
+
children: /* @__PURE__ */ jsxs8(Box6, {
|
|
936
1113
|
flexDirection: "column",
|
|
937
1114
|
children: [
|
|
938
|
-
/* @__PURE__ */
|
|
1115
|
+
/* @__PURE__ */ jsxs8(Text8, {
|
|
939
1116
|
children: [
|
|
940
|
-
/* @__PURE__ */
|
|
1117
|
+
/* @__PURE__ */ jsx9(Text8, {
|
|
941
1118
|
color: tone.notice,
|
|
942
1119
|
children: mark.fail
|
|
943
1120
|
}),
|
|
944
|
-
/* @__PURE__ */
|
|
1121
|
+
/* @__PURE__ */ jsx9(Text8, {
|
|
945
1122
|
children: ` Not signed in — ${title} needs a session.`
|
|
946
1123
|
})
|
|
947
1124
|
]
|
|
948
1125
|
}),
|
|
949
|
-
/* @__PURE__ */
|
|
950
|
-
/* @__PURE__ */
|
|
1126
|
+
/* @__PURE__ */ jsx9(Blank, {}),
|
|
1127
|
+
/* @__PURE__ */ jsxs8(Text8, {
|
|
951
1128
|
dimColor: true,
|
|
952
1129
|
children: [
|
|
953
1130
|
"press ",
|
|
954
|
-
/* @__PURE__ */
|
|
1131
|
+
/* @__PURE__ */ jsx9(Text8, {
|
|
955
1132
|
color: tone.primary,
|
|
956
1133
|
children: "l"
|
|
957
1134
|
}),
|
|
958
1135
|
" to log in, ",
|
|
959
|
-
/* @__PURE__ */
|
|
1136
|
+
/* @__PURE__ */ jsx9(Text8, {
|
|
960
1137
|
color: tone.primary,
|
|
961
1138
|
children: "q"
|
|
962
1139
|
}),
|
|
963
1140
|
" to quit"
|
|
964
1141
|
]
|
|
965
1142
|
}),
|
|
966
|
-
/* @__PURE__ */
|
|
1143
|
+
/* @__PURE__ */ jsxs8(Text8, {
|
|
967
1144
|
dimColor: true,
|
|
968
1145
|
children: [
|
|
969
1146
|
"or run ",
|
|
970
|
-
/* @__PURE__ */
|
|
1147
|
+
/* @__PURE__ */ jsx9(Text8, {
|
|
971
1148
|
color: tone.primary,
|
|
972
1149
|
children: "yourskills login"
|
|
973
1150
|
}),
|
|
@@ -979,8 +1156,8 @@ function AuthGate({
|
|
|
979
1156
|
});
|
|
980
1157
|
}
|
|
981
1158
|
// src/catalog/screens/browser.tsx
|
|
982
|
-
import { Box as
|
|
983
|
-
import { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo2, useState as
|
|
1159
|
+
import { Box as Box8, Text as Text10, useApp as useApp4, useInput as useInput4, useWindowSize as useWindowSize2 } from "ink";
|
|
1160
|
+
import { useCallback as useCallback2, useEffect as useEffect5, useMemo as useMemo2, useState as useState6 } from "react";
|
|
984
1161
|
|
|
985
1162
|
// src/install/install.ts
|
|
986
1163
|
import { spawn } from "node:child_process";
|
|
@@ -1193,6 +1370,57 @@ async function* installResolution(entries, opts, bundle) {
|
|
|
1193
1370
|
yield* installTargets(entry.locations, opts, bundle);
|
|
1194
1371
|
}
|
|
1195
1372
|
}
|
|
1373
|
+
|
|
1374
|
+
// src/install/update.ts
|
|
1375
|
+
function update(client, bundle, opts = {}) {
|
|
1376
|
+
return installBundle(client, bundle, opts);
|
|
1377
|
+
}
|
|
1378
|
+
function updateScope(bundles, loose) {
|
|
1379
|
+
return [
|
|
1380
|
+
bundles > 0 ? `${bundles} ${bundles === 1 ? "bundle" : "bundles"}` : "",
|
|
1381
|
+
loose > 0 ? `${loose} loose ${loose === 1 ? "skill" : "skills"}` : ""
|
|
1382
|
+
].filter(Boolean).join(" and ");
|
|
1383
|
+
}
|
|
1384
|
+
function looseSkills(manifest) {
|
|
1385
|
+
return Object.values(manifest.skills).filter((entry) => !entry.bundle).map((entry) => entry.name);
|
|
1386
|
+
}
|
|
1387
|
+
async function* updateTracked(client, manifest, opts = {}, all = false) {
|
|
1388
|
+
for (const bundle of Object.keys(manifest.bundles)) {
|
|
1389
|
+
yield* installBundle(client, bundle, opts);
|
|
1390
|
+
}
|
|
1391
|
+
const loose = all ? looseSkills(manifest) : [];
|
|
1392
|
+
if (loose.length > 0)
|
|
1393
|
+
yield* install(client, loose, opts);
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
// src/install/empty.ts
|
|
1397
|
+
function nothingTracked(nearest, kind, all = false) {
|
|
1398
|
+
const has = kind === "install" ? Object.keys(nearest.manifest.skills).length > 0 : Object.keys(nearest.manifest.bundles).length > 0 || all && looseSkills(nearest.manifest).length > 0;
|
|
1399
|
+
if (has)
|
|
1400
|
+
return null;
|
|
1401
|
+
return {
|
|
1402
|
+
title: kind,
|
|
1403
|
+
lines: [
|
|
1404
|
+
{
|
|
1405
|
+
mark: "none",
|
|
1406
|
+
text: kind === "install" ? "Nothing recorded to install yet." : "No bundles tracked here yet.",
|
|
1407
|
+
note: nearest.path
|
|
1408
|
+
}
|
|
1409
|
+
],
|
|
1410
|
+
json: { manifest: nearest.path, skills: [], bundles: [] },
|
|
1411
|
+
next: { command: "yourskills browse", why: "pick something to install" }
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
// src/install/options.ts
|
|
1415
|
+
async function resolveInstallOptions(opts) {
|
|
1416
|
+
const { scope, manifestPath } = await resolveScope({ flag: opts.scope });
|
|
1417
|
+
const path = scope === "project" && manifestPath ? manifestPath : manifestPathFor(scope);
|
|
1418
|
+
return {
|
|
1419
|
+
scope,
|
|
1420
|
+
agents: await resolveAgents(opts.agents),
|
|
1421
|
+
manifest: { path, scope }
|
|
1422
|
+
};
|
|
1423
|
+
}
|
|
1196
1424
|
// src/install/reinstall.ts
|
|
1197
1425
|
function targetOf(entry) {
|
|
1198
1426
|
return {
|
|
@@ -1255,9 +1483,9 @@ async function removeSkills(names, manifest, manifestPath, opts = {}) {
|
|
|
1255
1483
|
};
|
|
1256
1484
|
}
|
|
1257
1485
|
// src/install/screens/installer.tsx
|
|
1258
|
-
import { Box as
|
|
1259
|
-
import { useEffect as useEffect4, useState as
|
|
1260
|
-
import { jsx as
|
|
1486
|
+
import { Box as Box7, Text as Text9, useApp as useApp3 } from "ink";
|
|
1487
|
+
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
1488
|
+
import { jsx as jsx10, jsxs as jsxs9, Fragment as Fragment4 } from "react/jsx-runtime";
|
|
1261
1489
|
function where(location) {
|
|
1262
1490
|
return `${location.source}/${location.path}@${location.ref.slice(0, 8)}`;
|
|
1263
1491
|
}
|
|
@@ -1306,76 +1534,76 @@ function InstallLine({ line, width }) {
|
|
|
1306
1534
|
const name = clip(line.name, names).padEnd(names);
|
|
1307
1535
|
switch (line.state) {
|
|
1308
1536
|
case "resolving":
|
|
1309
|
-
return /* @__PURE__ */
|
|
1537
|
+
return /* @__PURE__ */ jsxs9(Text9, {
|
|
1310
1538
|
children: [
|
|
1311
|
-
/* @__PURE__ */
|
|
1312
|
-
/* @__PURE__ */
|
|
1539
|
+
/* @__PURE__ */ jsx10(Spinner, {}),
|
|
1540
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1313
1541
|
children: ` ${name}`
|
|
1314
1542
|
}),
|
|
1315
|
-
/* @__PURE__ */
|
|
1543
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1316
1544
|
dimColor: true,
|
|
1317
1545
|
children: "resolving..."
|
|
1318
1546
|
})
|
|
1319
1547
|
]
|
|
1320
1548
|
});
|
|
1321
1549
|
case "installing":
|
|
1322
|
-
return /* @__PURE__ */
|
|
1550
|
+
return /* @__PURE__ */ jsxs9(Text9, {
|
|
1323
1551
|
children: [
|
|
1324
|
-
/* @__PURE__ */
|
|
1325
|
-
/* @__PURE__ */
|
|
1552
|
+
/* @__PURE__ */ jsx10(Spinner, {}),
|
|
1553
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1326
1554
|
children: ` ${name}`
|
|
1327
1555
|
}),
|
|
1328
|
-
/* @__PURE__ */
|
|
1556
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1329
1557
|
dimColor: true,
|
|
1330
1558
|
children: clip(line.where, width - names - 3)
|
|
1331
1559
|
})
|
|
1332
1560
|
]
|
|
1333
1561
|
});
|
|
1334
1562
|
case "installed":
|
|
1335
|
-
return /* @__PURE__ */
|
|
1563
|
+
return /* @__PURE__ */ jsxs9(Text9, {
|
|
1336
1564
|
children: [
|
|
1337
|
-
/* @__PURE__ */
|
|
1565
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1338
1566
|
color: "green",
|
|
1339
1567
|
children: mark.ok
|
|
1340
1568
|
}),
|
|
1341
|
-
/* @__PURE__ */
|
|
1569
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1342
1570
|
children: ` ${name}`
|
|
1343
1571
|
}),
|
|
1344
|
-
/* @__PURE__ */
|
|
1572
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1345
1573
|
dimColor: true,
|
|
1346
1574
|
children: clip(line.where, width - names - 3)
|
|
1347
1575
|
}),
|
|
1348
|
-
line.deprecated ? /* @__PURE__ */
|
|
1576
|
+
line.deprecated ? /* @__PURE__ */ jsx10(Text9, {
|
|
1349
1577
|
color: lifecycleColor("deprecated"),
|
|
1350
1578
|
children: ` ${lifecycleTag("deprecated")}`
|
|
1351
1579
|
}) : null
|
|
1352
1580
|
]
|
|
1353
1581
|
});
|
|
1354
1582
|
case "pending":
|
|
1355
|
-
return /* @__PURE__ */
|
|
1583
|
+
return /* @__PURE__ */ jsxs9(Box7, {
|
|
1356
1584
|
flexDirection: "column",
|
|
1357
1585
|
children: [
|
|
1358
|
-
/* @__PURE__ */
|
|
1586
|
+
/* @__PURE__ */ jsxs9(Text9, {
|
|
1359
1587
|
children: [
|
|
1360
|
-
/* @__PURE__ */
|
|
1588
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1361
1589
|
color: tone.notice,
|
|
1362
1590
|
children: mark.pending
|
|
1363
1591
|
}),
|
|
1364
|
-
/* @__PURE__ */
|
|
1592
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1365
1593
|
children: ` ${name}`
|
|
1366
1594
|
}),
|
|
1367
|
-
/* @__PURE__ */
|
|
1595
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1368
1596
|
color: tone.notice,
|
|
1369
1597
|
children: "not in your registry yet"
|
|
1370
1598
|
})
|
|
1371
1599
|
]
|
|
1372
1600
|
}),
|
|
1373
|
-
line.vendor.prUrl ? /* @__PURE__ */
|
|
1601
|
+
line.vendor.prUrl ? /* @__PURE__ */ jsxs9(Text9, {
|
|
1374
1602
|
children: [
|
|
1375
|
-
/* @__PURE__ */
|
|
1603
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1376
1604
|
children: " "
|
|
1377
1605
|
}),
|
|
1378
|
-
/* @__PURE__ */
|
|
1606
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1379
1607
|
color: tone.primary,
|
|
1380
1608
|
children: line.vendor.prUrl
|
|
1381
1609
|
})
|
|
@@ -1384,26 +1612,26 @@ function InstallLine({ line, width }) {
|
|
|
1384
1612
|
]
|
|
1385
1613
|
});
|
|
1386
1614
|
case "failed":
|
|
1387
|
-
return /* @__PURE__ */
|
|
1615
|
+
return /* @__PURE__ */ jsxs9(Box7, {
|
|
1388
1616
|
flexDirection: "column",
|
|
1389
1617
|
children: [
|
|
1390
|
-
/* @__PURE__ */
|
|
1618
|
+
/* @__PURE__ */ jsxs9(Text9, {
|
|
1391
1619
|
children: [
|
|
1392
|
-
/* @__PURE__ */
|
|
1620
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1393
1621
|
color: tone.danger,
|
|
1394
1622
|
children: mark.fail
|
|
1395
1623
|
}),
|
|
1396
|
-
/* @__PURE__ */
|
|
1624
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1397
1625
|
children: ` ${name}`
|
|
1398
1626
|
}),
|
|
1399
|
-
/* @__PURE__ */
|
|
1627
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1400
1628
|
color: tone.danger,
|
|
1401
1629
|
children: clip(line.message, width - names - 3)
|
|
1402
1630
|
})
|
|
1403
1631
|
]
|
|
1404
1632
|
}),
|
|
1405
1633
|
line.detail ? line.detail.split(`
|
|
1406
|
-
`).slice(-3).map((d) => /* @__PURE__ */
|
|
1634
|
+
`).slice(-3).map((d) => /* @__PURE__ */ jsx10(Text9, {
|
|
1407
1635
|
dimColor: true,
|
|
1408
1636
|
children: clip(` ${d}`, width)
|
|
1409
1637
|
}, d)) : null
|
|
@@ -1415,13 +1643,15 @@ function Installer({
|
|
|
1415
1643
|
title,
|
|
1416
1644
|
stream,
|
|
1417
1645
|
onDone,
|
|
1418
|
-
exitWhenDone = true
|
|
1646
|
+
exitWhenDone = true,
|
|
1647
|
+
onBack,
|
|
1648
|
+
plan
|
|
1419
1649
|
}) {
|
|
1420
1650
|
const { exit } = useApp3();
|
|
1421
1651
|
const width = useFrameWidth();
|
|
1422
|
-
const [lines, setLines] =
|
|
1423
|
-
const [error, setError] =
|
|
1424
|
-
const [done, setDone] =
|
|
1652
|
+
const [lines, setLines] = useState5([]);
|
|
1653
|
+
const [error, setError] = useState5(null);
|
|
1654
|
+
const [done, setDone] = useState5(false);
|
|
1425
1655
|
useEffect4(() => {
|
|
1426
1656
|
let live = true;
|
|
1427
1657
|
(async () => {
|
|
@@ -1452,51 +1682,86 @@ function Installer({
|
|
|
1452
1682
|
};
|
|
1453
1683
|
}, [stream, onDone, exit, exitWhenDone]);
|
|
1454
1684
|
const pending = lines.filter((l) => l.state === "pending");
|
|
1455
|
-
|
|
1685
|
+
const installed = lines.filter((l) => l.state === "installed").length;
|
|
1686
|
+
const failed = lines.filter((l) => l.state === "failed").length;
|
|
1687
|
+
return /* @__PURE__ */ jsxs9(Frame, {
|
|
1456
1688
|
title,
|
|
1457
1689
|
width,
|
|
1458
|
-
children:
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1690
|
+
children: [
|
|
1691
|
+
/* @__PURE__ */ jsxs9(Box7, {
|
|
1692
|
+
flexDirection: "column",
|
|
1693
|
+
children: [
|
|
1694
|
+
plan ? /* @__PURE__ */ jsx10(Text9, {
|
|
1695
|
+
dimColor: true,
|
|
1696
|
+
children: clip(plan, width - 4)
|
|
1697
|
+
}) : null,
|
|
1698
|
+
lines.length === 0 && !error ? /* @__PURE__ */ jsxs9(Text9, {
|
|
1699
|
+
children: [
|
|
1700
|
+
/* @__PURE__ */ jsx10(Spinner, {}),
|
|
1701
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1702
|
+
dimColor: true,
|
|
1703
|
+
children: " Resolving..."
|
|
1704
|
+
})
|
|
1705
|
+
]
|
|
1706
|
+
}) : null,
|
|
1707
|
+
lines.map((line) => /* @__PURE__ */ jsx10(InstallLine, {
|
|
1708
|
+
line,
|
|
1709
|
+
width: width - 2
|
|
1710
|
+
}, line.name)),
|
|
1711
|
+
error ? /* @__PURE__ */ jsx10(Text9, {
|
|
1712
|
+
color: tone.danger,
|
|
1713
|
+
children: `${mark.fail} ${error}`
|
|
1714
|
+
}) : null,
|
|
1715
|
+
done && lines.length > 0 ? /* @__PURE__ */ jsxs9(Fragment4, {
|
|
1716
|
+
children: [
|
|
1717
|
+
/* @__PURE__ */ jsx10(Divider, {
|
|
1718
|
+
width
|
|
1719
|
+
}),
|
|
1720
|
+
/* @__PURE__ */ jsxs9(Text9, {
|
|
1721
|
+
children: [
|
|
1722
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1723
|
+
color: "green",
|
|
1724
|
+
children: `${installed} installed`
|
|
1725
|
+
}),
|
|
1726
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1727
|
+
color: pending.length > 0 ? tone.notice : undefined,
|
|
1728
|
+
dimColor: pending.length === 0,
|
|
1729
|
+
children: ` ${pending.length} pending`
|
|
1730
|
+
}),
|
|
1731
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1732
|
+
color: failed > 0 ? tone.danger : undefined,
|
|
1733
|
+
dimColor: failed === 0,
|
|
1734
|
+
children: ` ${failed} failed`
|
|
1735
|
+
})
|
|
1736
|
+
]
|
|
1737
|
+
})
|
|
1738
|
+
]
|
|
1739
|
+
}) : null,
|
|
1740
|
+
done && pending.length > 0 ? /* @__PURE__ */ jsxs9(Fragment4, {
|
|
1741
|
+
children: [
|
|
1742
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1743
|
+
color: tone.notice,
|
|
1744
|
+
children: pending.length === 1 ? "1 skill is waiting on a pull request." : `${pending.length} skills are waiting on a pull request.`
|
|
1745
|
+
}),
|
|
1746
|
+
/* @__PURE__ */ jsx10(Text9, {
|
|
1747
|
+
dimColor: true,
|
|
1748
|
+
children: "Merge it, then run this command again."
|
|
1749
|
+
})
|
|
1750
|
+
]
|
|
1751
|
+
}) : null
|
|
1752
|
+
]
|
|
1753
|
+
}),
|
|
1754
|
+
done || error !== null ? /* @__PURE__ */ jsx10(Back, {
|
|
1755
|
+
width,
|
|
1756
|
+
onBack
|
|
1757
|
+
}) : null
|
|
1758
|
+
]
|
|
1495
1759
|
});
|
|
1496
1760
|
}
|
|
1497
1761
|
async function installPlain(stream) {
|
|
1498
1762
|
const pending = [];
|
|
1499
1763
|
let failed = 0;
|
|
1764
|
+
let installed = 0;
|
|
1500
1765
|
for await (const event of stream) {
|
|
1501
1766
|
switch (event.kind) {
|
|
1502
1767
|
case "resolving":
|
|
@@ -1508,6 +1773,7 @@ async function installPlain(stream) {
|
|
|
1508
1773
|
console.log(`${event.location.skillName} ${where(event.location)}`);
|
|
1509
1774
|
break;
|
|
1510
1775
|
case "installed":
|
|
1776
|
+
installed += 1;
|
|
1511
1777
|
break;
|
|
1512
1778
|
case "pending":
|
|
1513
1779
|
console.log(pendingMessage(event.vendor));
|
|
@@ -1521,25 +1787,13 @@ async function installPlain(stream) {
|
|
|
1521
1787
|
break;
|
|
1522
1788
|
}
|
|
1523
1789
|
}
|
|
1524
|
-
|
|
1525
|
-
}
|
|
1526
|
-
// src/install/update.ts
|
|
1527
|
-
function update(client, bundle, opts = {}) {
|
|
1528
|
-
return installBundle(client, bundle, opts);
|
|
1529
|
-
}
|
|
1530
|
-
function looseSkills(manifest) {
|
|
1531
|
-
return Object.values(manifest.skills).filter((entry) => !entry.bundle).map((entry) => entry.name);
|
|
1532
|
-
}
|
|
1533
|
-
async function* updateTracked(client, manifest, opts = {}, all = false) {
|
|
1534
|
-
for (const bundle of Object.keys(manifest.bundles)) {
|
|
1535
|
-
yield* installBundle(client, bundle, opts);
|
|
1790
|
+
if (pending.length > 0 || failed > 0) {
|
|
1791
|
+
console.log(`${installed} installed, ${pending.length} pending, ${failed} failed`);
|
|
1536
1792
|
}
|
|
1537
|
-
|
|
1538
|
-
if (loose.length > 0)
|
|
1539
|
-
yield* install(client, loose, opts);
|
|
1793
|
+
return { pending, failed };
|
|
1540
1794
|
}
|
|
1541
1795
|
// src/catalog/screens/browser.tsx
|
|
1542
|
-
import { jsx as
|
|
1796
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1543
1797
|
var TABS = ["bundles", "skills"];
|
|
1544
1798
|
function pageSize(rows) {
|
|
1545
1799
|
return Math.max(3, Math.min(20, rows - 11));
|
|
@@ -1551,18 +1805,18 @@ function matches(row, query) {
|
|
|
1551
1805
|
return row.name.toLowerCase().includes(q) || (row.description ?? "").toLowerCase().includes(q);
|
|
1552
1806
|
}
|
|
1553
1807
|
function TabBar({ active }) {
|
|
1554
|
-
return /* @__PURE__ */
|
|
1555
|
-
children: TABS.map((tab, i) => /* @__PURE__ */
|
|
1808
|
+
return /* @__PURE__ */ jsx11(Box8, {
|
|
1809
|
+
children: TABS.map((tab, i) => /* @__PURE__ */ jsxs10(Text10, {
|
|
1556
1810
|
children: [
|
|
1557
|
-
i > 0 ? /* @__PURE__ */
|
|
1811
|
+
i > 0 ? /* @__PURE__ */ jsx11(Text10, {
|
|
1558
1812
|
dimColor: true,
|
|
1559
1813
|
children: " "
|
|
1560
1814
|
}) : null,
|
|
1561
|
-
tab === active ? /* @__PURE__ */
|
|
1815
|
+
tab === active ? /* @__PURE__ */ jsx11(Text10, {
|
|
1562
1816
|
bold: true,
|
|
1563
1817
|
color: tone.primary,
|
|
1564
1818
|
children: `[${tab}]`
|
|
1565
|
-
}) : /* @__PURE__ */
|
|
1819
|
+
}) : /* @__PURE__ */ jsx11(Text10, {
|
|
1566
1820
|
dimColor: true,
|
|
1567
1821
|
children: ` ${tab} `
|
|
1568
1822
|
})
|
|
@@ -1575,20 +1829,22 @@ function BrowserScreen({
|
|
|
1575
1829
|
opts,
|
|
1576
1830
|
onError,
|
|
1577
1831
|
onSummary,
|
|
1578
|
-
onExit
|
|
1832
|
+
onExit,
|
|
1833
|
+
initialTab = "bundles",
|
|
1834
|
+
initialQuery = ""
|
|
1579
1835
|
}) {
|
|
1580
1836
|
const { exit } = useApp4();
|
|
1581
1837
|
const width = useFrameWidth();
|
|
1582
1838
|
const { rows: terminalRows } = useWindowSize2();
|
|
1583
|
-
const [catalog, setCatalog] =
|
|
1584
|
-
const [tab, setTab] =
|
|
1585
|
-
const [query, setQuery] =
|
|
1586
|
-
const [cursor, setCursor] =
|
|
1587
|
-
const [picked, setPicked] =
|
|
1839
|
+
const [catalog, setCatalog] = useState6(null);
|
|
1840
|
+
const [tab, setTab] = useState6(initialTab);
|
|
1841
|
+
const [query, setQuery] = useState6(initialQuery);
|
|
1842
|
+
const [cursor, setCursor] = useState6(0);
|
|
1843
|
+
const [picked, setPicked] = useState6({
|
|
1588
1844
|
bundles: new Set,
|
|
1589
1845
|
skills: new Set
|
|
1590
1846
|
});
|
|
1591
|
-
const [running, setRunning] =
|
|
1847
|
+
const [running, setRunning] = useState6(null);
|
|
1592
1848
|
useEffect5(() => {
|
|
1593
1849
|
let live = true;
|
|
1594
1850
|
Promise.all([client.skills.list.query({}), client.bundles.list.query()]).then(([skills, bundles]) => {
|
|
@@ -1631,7 +1887,7 @@ function BrowserScreen({
|
|
|
1631
1887
|
names: names2
|
|
1632
1888
|
});
|
|
1633
1889
|
}, [selected, visible, cursor, tab]);
|
|
1634
|
-
|
|
1890
|
+
useInput4((input, key) => {
|
|
1635
1891
|
if (key.upArrow) {
|
|
1636
1892
|
setCursor((c) => Math.max(0, c - 1));
|
|
1637
1893
|
} else if (key.downArrow) {
|
|
@@ -1675,7 +1931,7 @@ function BrowserScreen({
|
|
|
1675
1931
|
if (running) {
|
|
1676
1932
|
const names2 = running.names;
|
|
1677
1933
|
const stream = tab === "bundles" ? () => installBundle(client, names2[0], opts) : () => install(client, names2, opts);
|
|
1678
|
-
return /* @__PURE__ */
|
|
1934
|
+
return /* @__PURE__ */ jsx11(Installer, {
|
|
1679
1935
|
title: running.title,
|
|
1680
1936
|
stream,
|
|
1681
1937
|
exitWhenDone: true,
|
|
@@ -1683,13 +1939,13 @@ function BrowserScreen({
|
|
|
1683
1939
|
});
|
|
1684
1940
|
}
|
|
1685
1941
|
if (!catalog) {
|
|
1686
|
-
return /* @__PURE__ */
|
|
1942
|
+
return /* @__PURE__ */ jsx11(Frame, {
|
|
1687
1943
|
title: "yourskills",
|
|
1688
1944
|
width,
|
|
1689
|
-
children: /* @__PURE__ */
|
|
1945
|
+
children: /* @__PURE__ */ jsxs10(Text10, {
|
|
1690
1946
|
children: [
|
|
1691
|
-
/* @__PURE__ */
|
|
1692
|
-
/* @__PURE__ */
|
|
1947
|
+
/* @__PURE__ */ jsx11(Spinner, {}),
|
|
1948
|
+
/* @__PURE__ */ jsx11(Text10, {
|
|
1693
1949
|
dimColor: true,
|
|
1694
1950
|
children: " Loading your registry..."
|
|
1695
1951
|
})
|
|
@@ -1701,37 +1957,37 @@ function BrowserScreen({
|
|
|
1701
1957
|
const first = Math.max(0, Math.min(cursor - Math.floor(size / 2), visible.length - size));
|
|
1702
1958
|
const page = visible.slice(Math.max(0, first), Math.max(0, first) + size);
|
|
1703
1959
|
const names = nameWidth(visible.length > 0 ? visible : catalog[tab]);
|
|
1704
|
-
return /* @__PURE__ */
|
|
1960
|
+
return /* @__PURE__ */ jsx11(Frame, {
|
|
1705
1961
|
title: "yourskills",
|
|
1706
1962
|
width,
|
|
1707
|
-
children: /* @__PURE__ */
|
|
1963
|
+
children: /* @__PURE__ */ jsxs10(Box8, {
|
|
1708
1964
|
flexDirection: "column",
|
|
1709
1965
|
children: [
|
|
1710
|
-
/* @__PURE__ */
|
|
1966
|
+
/* @__PURE__ */ jsx11(TabBar, {
|
|
1711
1967
|
active: tab
|
|
1712
1968
|
}),
|
|
1713
|
-
/* @__PURE__ */
|
|
1969
|
+
/* @__PURE__ */ jsx11(Divider, {
|
|
1714
1970
|
width
|
|
1715
1971
|
}),
|
|
1716
|
-
/* @__PURE__ */
|
|
1972
|
+
/* @__PURE__ */ jsxs10(Box8, {
|
|
1717
1973
|
children: [
|
|
1718
|
-
/* @__PURE__ */
|
|
1974
|
+
/* @__PURE__ */ jsx11(Text10, {
|
|
1719
1975
|
color: tone.primary,
|
|
1720
1976
|
children: "search> "
|
|
1721
1977
|
}),
|
|
1722
|
-
/* @__PURE__ */
|
|
1978
|
+
/* @__PURE__ */ jsx11(SearchInput, {
|
|
1723
1979
|
value: query,
|
|
1724
1980
|
placeholder: "type to filter"
|
|
1725
1981
|
})
|
|
1726
1982
|
]
|
|
1727
1983
|
}),
|
|
1728
|
-
/* @__PURE__ */
|
|
1984
|
+
/* @__PURE__ */ jsx11(Divider, {
|
|
1729
1985
|
width
|
|
1730
1986
|
}),
|
|
1731
|
-
page.length === 0 ? /* @__PURE__ */
|
|
1987
|
+
page.length === 0 ? /* @__PURE__ */ jsx11(Text10, {
|
|
1732
1988
|
dimColor: true,
|
|
1733
1989
|
children: `No ${tab} match "${query}".`
|
|
1734
|
-
}) : page.map((row, i) => /* @__PURE__ */
|
|
1990
|
+
}) : page.map((row, i) => /* @__PURE__ */ jsx11(SkillRow, {
|
|
1735
1991
|
row,
|
|
1736
1992
|
width: width - 2,
|
|
1737
1993
|
names,
|
|
@@ -1739,23 +1995,23 @@ function BrowserScreen({
|
|
|
1739
1995
|
cursor: Math.max(0, first) + i === cursor,
|
|
1740
1996
|
selected: selected.has(row.name)
|
|
1741
1997
|
}, row.name)),
|
|
1742
|
-
/* @__PURE__ */
|
|
1998
|
+
/* @__PURE__ */ jsx11(Divider, {
|
|
1743
1999
|
width
|
|
1744
2000
|
}),
|
|
1745
|
-
/* @__PURE__ */
|
|
2001
|
+
/* @__PURE__ */ jsxs10(Box8, {
|
|
1746
2002
|
children: [
|
|
1747
|
-
/* @__PURE__ */
|
|
2003
|
+
/* @__PURE__ */ jsx11(Text10, {
|
|
1748
2004
|
dimColor: true,
|
|
1749
2005
|
children: `${visible.length > 0 ? cursor + 1 : 0}/${visible.length}`
|
|
1750
2006
|
}),
|
|
1751
|
-
selected.size > 0 ? /* @__PURE__ */
|
|
2007
|
+
selected.size > 0 ? /* @__PURE__ */ jsx11(Text10, {
|
|
1752
2008
|
color: tone.notice,
|
|
1753
2009
|
children: ` ${selected.size} selected`
|
|
1754
2010
|
}) : null,
|
|
1755
|
-
/* @__PURE__ */
|
|
2011
|
+
/* @__PURE__ */ jsx11(Text10, {
|
|
1756
2012
|
children: " "
|
|
1757
2013
|
}),
|
|
1758
|
-
/* @__PURE__ */
|
|
2014
|
+
/* @__PURE__ */ jsx11(Hints, {
|
|
1759
2015
|
hints: [
|
|
1760
2016
|
["^v", "move"],
|
|
1761
2017
|
["space", "select"],
|
|
@@ -1771,9 +2027,9 @@ function BrowserScreen({
|
|
|
1771
2027
|
});
|
|
1772
2028
|
}
|
|
1773
2029
|
// src/catalog/screens/catalog.tsx
|
|
1774
|
-
import { Box as
|
|
1775
|
-
import { useEffect as useEffect6, useState as
|
|
1776
|
-
import { jsx as
|
|
2030
|
+
import { Box as Box9, Text as Text11, useApp as useApp5 } from "ink";
|
|
2031
|
+
import { useEffect as useEffect6, useState as useState7 } from "react";
|
|
2032
|
+
import { jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1777
2033
|
function CatalogScreen({
|
|
1778
2034
|
title,
|
|
1779
2035
|
load,
|
|
@@ -1781,7 +2037,7 @@ function CatalogScreen({
|
|
|
1781
2037
|
}) {
|
|
1782
2038
|
const { exit } = useApp5();
|
|
1783
2039
|
const width = useFrameWidth();
|
|
1784
|
-
const [rows, setRows] =
|
|
2040
|
+
const [rows, setRows] = useState7(null);
|
|
1785
2041
|
useEffect6(() => {
|
|
1786
2042
|
let live = true;
|
|
1787
2043
|
load().then((result) => {
|
|
@@ -1798,13 +2054,13 @@ function CatalogScreen({
|
|
|
1798
2054
|
};
|
|
1799
2055
|
}, [load, exit, onError]);
|
|
1800
2056
|
if (rows === null) {
|
|
1801
|
-
return /* @__PURE__ */
|
|
2057
|
+
return /* @__PURE__ */ jsx12(Frame, {
|
|
1802
2058
|
title,
|
|
1803
2059
|
width,
|
|
1804
|
-
children: /* @__PURE__ */
|
|
2060
|
+
children: /* @__PURE__ */ jsxs11(Text11, {
|
|
1805
2061
|
children: [
|
|
1806
|
-
/* @__PURE__ */
|
|
1807
|
-
/* @__PURE__ */
|
|
2062
|
+
/* @__PURE__ */ jsx12(Spinner, {}),
|
|
2063
|
+
/* @__PURE__ */ jsx12(Text11, {
|
|
1808
2064
|
dimColor: true,
|
|
1809
2065
|
children: " Loading..."
|
|
1810
2066
|
})
|
|
@@ -1813,22 +2069,22 @@ function CatalogScreen({
|
|
|
1813
2069
|
});
|
|
1814
2070
|
}
|
|
1815
2071
|
if (rows.length === 0) {
|
|
1816
|
-
return /* @__PURE__ */
|
|
2072
|
+
return /* @__PURE__ */ jsx12(Frame, {
|
|
1817
2073
|
title,
|
|
1818
2074
|
width,
|
|
1819
|
-
children: /* @__PURE__ */
|
|
2075
|
+
children: /* @__PURE__ */ jsx12(Text11, {
|
|
1820
2076
|
dimColor: true,
|
|
1821
2077
|
children: "No skills found."
|
|
1822
2078
|
})
|
|
1823
2079
|
});
|
|
1824
2080
|
}
|
|
1825
2081
|
const names = nameWidth(rows);
|
|
1826
|
-
return /* @__PURE__ */
|
|
2082
|
+
return /* @__PURE__ */ jsx12(Frame, {
|
|
1827
2083
|
title,
|
|
1828
2084
|
width,
|
|
1829
|
-
children: /* @__PURE__ */
|
|
2085
|
+
children: /* @__PURE__ */ jsx12(Box9, {
|
|
1830
2086
|
flexDirection: "column",
|
|
1831
|
-
children: rows.map((row) => /* @__PURE__ */
|
|
2087
|
+
children: rows.map((row) => /* @__PURE__ */ jsx12(SkillRow, {
|
|
1832
2088
|
row,
|
|
1833
2089
|
width: width - 2,
|
|
1834
2090
|
names
|
|
@@ -2007,6 +2263,75 @@ async function doctorReport(nearest, server) {
|
|
|
2007
2263
|
failed: checks.some((check) => !check.ok)
|
|
2008
2264
|
};
|
|
2009
2265
|
}
|
|
2266
|
+
// src/errors.ts
|
|
2267
|
+
function isUnauthorized(error) {
|
|
2268
|
+
if (!(error instanceof Error))
|
|
2269
|
+
return false;
|
|
2270
|
+
const data = error.data;
|
|
2271
|
+
if (data?.code === "UNAUTHORIZED" || data?.httpStatus === 401)
|
|
2272
|
+
return true;
|
|
2273
|
+
return error.message.startsWith("Not logged in") || error.message.startsWith("Session is no longer valid");
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
class CliError extends Error {
|
|
2277
|
+
why;
|
|
2278
|
+
next;
|
|
2279
|
+
code;
|
|
2280
|
+
constructor(what, detail = {}) {
|
|
2281
|
+
super(what);
|
|
2282
|
+
this.name = "CliError";
|
|
2283
|
+
this.why = detail.why;
|
|
2284
|
+
this.next = detail.next;
|
|
2285
|
+
this.code = detail.code ?? EXIT.failed;
|
|
2286
|
+
}
|
|
2287
|
+
}
|
|
2288
|
+
var EXIT = {
|
|
2289
|
+
ok: 0,
|
|
2290
|
+
failed: 1,
|
|
2291
|
+
usage: 2,
|
|
2292
|
+
session: 3
|
|
2293
|
+
};
|
|
2294
|
+
var EXIT_CODES = [
|
|
2295
|
+
[EXIT.ok, "done"],
|
|
2296
|
+
[
|
|
2297
|
+
EXIT.failed,
|
|
2298
|
+
"something did not land: a failed install, a pending pull request"
|
|
2299
|
+
],
|
|
2300
|
+
[EXIT.usage, "the command line was wrong; the last line says the spelling"],
|
|
2301
|
+
[EXIT.session, "needs a session: run `yourskills login`"]
|
|
2302
|
+
];
|
|
2303
|
+
var LOGIN = "yourskills login";
|
|
2304
|
+
function describeError(error) {
|
|
2305
|
+
if (error instanceof CliError) {
|
|
2306
|
+
return {
|
|
2307
|
+
lines: shape(error.message, error.why, error.next),
|
|
2308
|
+
code: error.code
|
|
2309
|
+
};
|
|
2310
|
+
}
|
|
2311
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2312
|
+
if (isUnauthorized(error)) {
|
|
2313
|
+
return {
|
|
2314
|
+
lines: shape("you are not signed in", message.startsWith("Session") ? "the registry no longer accepts the token on this machine" : "the catalog needs a session, and there is no token on this machine", LOGIN),
|
|
2315
|
+
code: EXIT.session
|
|
2316
|
+
};
|
|
2317
|
+
}
|
|
2318
|
+
if (/fetch failed|ECONNREFUSED|ENOTFOUND|timed? ?out/i.test(message)) {
|
|
2319
|
+
return {
|
|
2320
|
+
lines: shape("could not reach the registry", message, "check your connection, then run the same command again"),
|
|
2321
|
+
code: EXIT.failed
|
|
2322
|
+
};
|
|
2323
|
+
}
|
|
2324
|
+
return { lines: shape(message), code: EXIT.failed };
|
|
2325
|
+
}
|
|
2326
|
+
function shape(what, why, next) {
|
|
2327
|
+
const lines = [what];
|
|
2328
|
+
if (why)
|
|
2329
|
+
lines.push(` ${why}`);
|
|
2330
|
+
if (next)
|
|
2331
|
+
lines.push(` ${next}`);
|
|
2332
|
+
return lines;
|
|
2333
|
+
}
|
|
2334
|
+
|
|
2010
2335
|
// src/hooks/adapters.ts
|
|
2011
2336
|
import { homedir as homedir3 } from "node:os";
|
|
2012
2337
|
import { join as join6 } from "node:path";
|
|
@@ -2023,7 +2348,8 @@ var UPDATE_CHECK_ENTRY = {
|
|
|
2023
2348
|
kind: "update-check",
|
|
2024
2349
|
event: "SessionStart",
|
|
2025
2350
|
matcher: "startup|resume",
|
|
2026
|
-
command: `${BINARY} hook session-start
|
|
2351
|
+
command: `${BINARY} hook session-start`,
|
|
2352
|
+
timeout: 120
|
|
2027
2353
|
};
|
|
2028
2354
|
var USAGE_ENTRY = {
|
|
2029
2355
|
kind: "usage",
|
|
@@ -2061,57 +2387,294 @@ function agentForEvent(kind, event) {
|
|
|
2061
2387
|
const owner = HOOK_ADAPTERS.find((adapter) => adapter.entries.some((entry) => entry.kind === kind && entry.event === event));
|
|
2062
2388
|
return owner?.agent ?? "unknown";
|
|
2063
2389
|
}
|
|
2064
|
-
// src/
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2390
|
+
// ../../packages/bundles/src/drift.ts
|
|
2391
|
+
var SHORT_SHA = 7;
|
|
2392
|
+
function namesSameCommit(prefix, full) {
|
|
2393
|
+
const short = prefix.trim().toLowerCase();
|
|
2394
|
+
const long = full.trim().toLowerCase();
|
|
2395
|
+
if (short === long)
|
|
2396
|
+
return true;
|
|
2397
|
+
return short.length >= SHORT_SHA && long.startsWith(short);
|
|
2398
|
+
}
|
|
2071
2399
|
|
|
2072
|
-
//
|
|
2073
|
-
var
|
|
2074
|
-
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
}
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2400
|
+
// src/installed/installed.ts
|
|
2401
|
+
var shortRef = (ref) => ref.slice(0, SHORT_SHA);
|
|
2402
|
+
function installedRows(nearest) {
|
|
2403
|
+
return Object.values(nearest.manifest.skills).map((entry) => ({
|
|
2404
|
+
name: entry.name,
|
|
2405
|
+
ref: entry.ref,
|
|
2406
|
+
bundle: entry.bundle ?? null,
|
|
2407
|
+
scope: nearest.manifest.scope
|
|
2408
|
+
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
2409
|
+
}
|
|
2410
|
+
function columns(rows) {
|
|
2411
|
+
const names = Math.max(...rows.map((r) => r.name.length));
|
|
2412
|
+
const bundles = Math.max(...rows.map((r) => (r.bundle ?? "-").length));
|
|
2413
|
+
return rows.map((row) => ({
|
|
2414
|
+
mark: "none",
|
|
2415
|
+
text: `${row.name.padEnd(names)} ${shortRef(row.ref)}`,
|
|
2416
|
+
note: `${(row.bundle ?? "-").padEnd(bundles)} ${row.scope}`
|
|
2417
|
+
}));
|
|
2418
|
+
}
|
|
2419
|
+
function installedReport(nearest) {
|
|
2420
|
+
const rows = installedRows(nearest);
|
|
2421
|
+
const lines = rows.length === 0 ? [
|
|
2422
|
+
{
|
|
2423
|
+
mark: "none",
|
|
2424
|
+
text: "Nothing installed. Run `yourskills bundle <name>` or `yourskills add <skill>`.",
|
|
2425
|
+
note: nearest.path
|
|
2091
2426
|
}
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
}
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2427
|
+
] : columns(rows);
|
|
2428
|
+
return {
|
|
2429
|
+
title: "installed",
|
|
2430
|
+
lines,
|
|
2431
|
+
json: {
|
|
2432
|
+
manifest: nearest.path,
|
|
2433
|
+
scope: nearest.manifest.scope,
|
|
2434
|
+
skills: rows
|
|
2435
|
+
},
|
|
2436
|
+
...rows.length === 0 ? {
|
|
2437
|
+
next: {
|
|
2438
|
+
command: "yourskills browse",
|
|
2439
|
+
why: "pick something to install"
|
|
2440
|
+
}
|
|
2441
|
+
} : {}
|
|
2442
|
+
};
|
|
2443
|
+
}
|
|
2444
|
+
// src/installed/outdated.ts
|
|
2445
|
+
function hasMoved(installed, available) {
|
|
2446
|
+
return !(namesSameCommit(available, installed) || namesSameCommit(installed, available));
|
|
2447
|
+
}
|
|
2448
|
+
function drift(manifest, pins, catalog) {
|
|
2449
|
+
const byExternalId = new Map(catalog.map((row) => [row.externalId, row]));
|
|
2450
|
+
const byName = new Map(catalog.map((row) => [row.name, row]));
|
|
2451
|
+
const moved = [];
|
|
2452
|
+
const unknown = [];
|
|
2453
|
+
for (const entry of Object.values(manifest.skills)) {
|
|
2454
|
+
const row = byExternalId.get(entry.externalId) ?? byName.get(entry.name);
|
|
2455
|
+
if (!row) {
|
|
2456
|
+
unknown.push(entry.name);
|
|
2457
|
+
continue;
|
|
2458
|
+
}
|
|
2459
|
+
const pin = entry.bundle ? pins.find((p) => p.bundle === entry.bundle && p.skillId === row.id) : undefined;
|
|
2460
|
+
const available = pin?.pinnedSha ?? row.currentSha;
|
|
2461
|
+
if (!hasMoved(entry.ref, available))
|
|
2462
|
+
continue;
|
|
2463
|
+
moved.push({
|
|
2464
|
+
name: entry.name,
|
|
2465
|
+
bundle: entry.bundle ?? null,
|
|
2466
|
+
installed: entry.ref,
|
|
2467
|
+
available,
|
|
2468
|
+
deprecated: pin?.deprecated ?? row.status === "deprecated"
|
|
2469
|
+
});
|
|
2470
|
+
}
|
|
2471
|
+
moved.sort((a, b) => a.name.localeCompare(b.name));
|
|
2472
|
+
return { moved, unknown };
|
|
2473
|
+
}
|
|
2474
|
+
async function driftNow(client, nearest) {
|
|
2475
|
+
const [pins, catalog] = await Promise.all([
|
|
2476
|
+
client.bundles.pins.query(),
|
|
2477
|
+
client.skills.list.query({})
|
|
2478
|
+
]);
|
|
2479
|
+
return drift(nearest.manifest, pins, catalog);
|
|
2480
|
+
}
|
|
2481
|
+
async function outdatedReport(client, nearest, quiet = false) {
|
|
2482
|
+
let report;
|
|
2483
|
+
try {
|
|
2484
|
+
report = await driftNow(client, nearest);
|
|
2485
|
+
} catch (error) {
|
|
2486
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2487
|
+
return {
|
|
2488
|
+
title: "outdated",
|
|
2489
|
+
lines: [
|
|
2490
|
+
{ mark: "fail", text: "Could not reach the registry.", note: message }
|
|
2491
|
+
],
|
|
2492
|
+
json: { manifest: nearest.path, error: message },
|
|
2493
|
+
silent: quiet
|
|
2494
|
+
};
|
|
2495
|
+
}
|
|
2496
|
+
const lines = report.moved.map((row) => ({
|
|
2497
|
+
mark: "pending",
|
|
2498
|
+
text: `${row.name} ${shortRef(row.installed)} -> ${shortRef(row.available)}`,
|
|
2499
|
+
note: [row.bundle ?? "-", row.deprecated ? "[deprecated]" : ""].filter(Boolean).join(" ")
|
|
2500
|
+
}));
|
|
2501
|
+
for (const name of report.unknown) {
|
|
2502
|
+
lines.push({
|
|
2503
|
+
mark: "fail",
|
|
2504
|
+
text: name,
|
|
2505
|
+
note: "no longer in your registry"
|
|
2506
|
+
});
|
|
2507
|
+
}
|
|
2508
|
+
const current = report.moved.length === 0 && report.unknown.length === 0;
|
|
2509
|
+
if (current && !quiet) {
|
|
2510
|
+
lines.push({
|
|
2511
|
+
mark: "ok",
|
|
2512
|
+
text: "Everything is at the ref your registry pins."
|
|
2513
|
+
});
|
|
2514
|
+
}
|
|
2515
|
+
return {
|
|
2516
|
+
title: "outdated",
|
|
2517
|
+
lines,
|
|
2518
|
+
json: {
|
|
2519
|
+
manifest: nearest.path,
|
|
2520
|
+
outdated: report.moved,
|
|
2521
|
+
unknown: report.unknown
|
|
2522
|
+
},
|
|
2523
|
+
silent: quiet && current,
|
|
2524
|
+
...report.moved.length > 0 ? {
|
|
2525
|
+
next: {
|
|
2526
|
+
command: "yourskills update --all",
|
|
2527
|
+
why: "install what moved"
|
|
2528
|
+
}
|
|
2529
|
+
} : {}
|
|
2530
|
+
};
|
|
2531
|
+
}
|
|
2532
|
+
// src/hooks/emit.ts
|
|
2533
|
+
function describe(outcome) {
|
|
2534
|
+
switch (outcome.kind) {
|
|
2535
|
+
case "quiet":
|
|
2536
|
+
return [];
|
|
2537
|
+
case "signed-out":
|
|
2538
|
+
return [
|
|
2539
|
+
"yourskills: your sign-in has expired, so your skills are no longer kept up to date.",
|
|
2540
|
+
" run: yourskills login"
|
|
2541
|
+
];
|
|
2542
|
+
case "behind": {
|
|
2543
|
+
const lines = [
|
|
2544
|
+
`yourskills: ${count(outcome.moved.length, "skill")} ${outcome.moved.length === 1 ? "has" : "have"} a newer version in your registry (autoUpdate is off)`
|
|
2545
|
+
];
|
|
2546
|
+
for (const row of outcome.moved) {
|
|
2547
|
+
lines.push(` ${row.name} ${shortRef(row.installed)} -> ${shortRef(row.available)}${row.deprecated ? " [deprecated]" : ""}`);
|
|
2548
|
+
}
|
|
2549
|
+
lines.push(" run: yourskills update --all");
|
|
2550
|
+
return lines;
|
|
2551
|
+
}
|
|
2552
|
+
case "updated": {
|
|
2553
|
+
const { applied, failed } = outcome;
|
|
2554
|
+
const lines = [
|
|
2555
|
+
applied.length > 0 ? `yourskills: updated ${count(applied.length, "skill")} to what your registry pins; ${applied.length === 1 ? "it is" : "they are"} live in this session.` : `yourskills: could not update ${count(failed.length, "skill")}`
|
|
2556
|
+
];
|
|
2557
|
+
for (const row of applied) {
|
|
2558
|
+
lines.push(` ${row.name} ${row.from} -> ${row.to}`);
|
|
2559
|
+
}
|
|
2560
|
+
for (const row of failed) {
|
|
2561
|
+
lines.push(` ${row.name} failed: ${row.message}`);
|
|
2562
|
+
}
|
|
2563
|
+
if (applied.length > 0)
|
|
2564
|
+
lines.push(` recorded in ${outcome.manifest}`);
|
|
2565
|
+
if (failed.length > 0)
|
|
2566
|
+
lines.push(" run: yourskills doctor");
|
|
2567
|
+
return lines;
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
function describeForModel(outcome) {
|
|
2572
|
+
switch (outcome.kind) {
|
|
2573
|
+
case "quiet":
|
|
2574
|
+
return [];
|
|
2575
|
+
case "signed-out":
|
|
2576
|
+
return [
|
|
2577
|
+
"yourskills: the user's session with the skills registry has expired, so installed skills are no longer being updated. The user has been told to run `yourskills login`; it is their call."
|
|
2578
|
+
];
|
|
2579
|
+
case "behind": {
|
|
2580
|
+
const lines = [
|
|
2581
|
+
`yourskills: ${count(outcome.moved.length, "installed skill")} ${outcome.moved.length === 1 ? "is" : "are"} behind the registry. Automatic updates are off; the user has been told and it is their call whether to run \`yourskills update --all\`.`
|
|
2582
|
+
];
|
|
2583
|
+
for (const row of outcome.moved) {
|
|
2584
|
+
lines.push(` ${row.name} installed ${shortRef(row.installed)}, registry pins ${shortRef(row.available)}${row.deprecated ? " [deprecated]" : ""}`);
|
|
2585
|
+
}
|
|
2586
|
+
return lines;
|
|
2587
|
+
}
|
|
2588
|
+
case "updated": {
|
|
2589
|
+
const { applied, failed } = outcome;
|
|
2590
|
+
const lines = [];
|
|
2591
|
+
if (applied.length > 0) {
|
|
2592
|
+
lines.push(`yourskills updated ${count(applied.length, "installed skill")} on disk at the start of this session. The contents changed: re-read a skill before relying on what you remember of it.`);
|
|
2593
|
+
for (const row of applied) {
|
|
2594
|
+
lines.push(` ${row.name} ${row.from} -> ${row.to}`);
|
|
2595
|
+
}
|
|
2596
|
+
lines.push(` recorded in ${outcome.manifest}`);
|
|
2597
|
+
}
|
|
2598
|
+
if (failed.length > 0) {
|
|
2599
|
+
lines.push(`yourskills could not update ${count(failed.length, "installed skill")}; the version on disk is unchanged. The user has been told.`);
|
|
2600
|
+
for (const row of failed) {
|
|
2601
|
+
lines.push(` ${row.name} ${row.message}`);
|
|
2602
|
+
}
|
|
2603
|
+
}
|
|
2604
|
+
return lines;
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
}
|
|
2608
|
+
function count(n, noun) {
|
|
2609
|
+
return `${n} ${noun}${n === 1 ? "" : "s"}`;
|
|
2610
|
+
}
|
|
2611
|
+
function emit(outcome) {
|
|
2612
|
+
const lines = describe(outcome);
|
|
2613
|
+
if (lines.length === 0)
|
|
2614
|
+
return;
|
|
2615
|
+
const installed = outcome.kind === "updated" && outcome.applied.length > 0;
|
|
2616
|
+
console.log(JSON.stringify({
|
|
2617
|
+
systemMessage: lines.join(`
|
|
2618
|
+
`),
|
|
2619
|
+
hookSpecificOutput: {
|
|
2620
|
+
hookEventName: "SessionStart",
|
|
2621
|
+
additionalContext: describeForModel(outcome).join(`
|
|
2622
|
+
`),
|
|
2623
|
+
...installed ? { reloadSkills: true } : {}
|
|
2624
|
+
}
|
|
2625
|
+
}));
|
|
2626
|
+
}
|
|
2627
|
+
// src/hooks/ensure.ts
|
|
2628
|
+
import { existsSync as existsSync3 } from "node:fs";
|
|
2629
|
+
|
|
2630
|
+
// src/usage/queue.ts
|
|
2631
|
+
import { mkdirSync as mkdirSync3 } from "node:fs";
|
|
2632
|
+
import { appendFile, readFile as readFile3, rm, stat, writeFile as writeFile2 } from "node:fs/promises";
|
|
2633
|
+
import { join as join7 } from "node:path";
|
|
2634
|
+
|
|
2635
|
+
// ../../node_modules/.bun/@trpc+client@11.18.0+acc6907a906fa511/node_modules/@trpc/client/dist/objectSpread2-BvkFp-_Y.mjs
|
|
2636
|
+
var __create = Object.create;
|
|
2637
|
+
var __defProp = Object.defineProperty;
|
|
2638
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
2639
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2640
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
2641
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
2642
|
+
var __commonJS = (cb, mod) => function() {
|
|
2643
|
+
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
|
|
2644
|
+
};
|
|
2645
|
+
var __copyProps = (to, from, except, desc) => {
|
|
2646
|
+
if (from && typeof from === "object" || typeof from === "function")
|
|
2647
|
+
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key;i < n; i++) {
|
|
2648
|
+
key = keys[i];
|
|
2649
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
2650
|
+
__defProp(to, key, {
|
|
2651
|
+
get: ((k) => from[k]).bind(null, key),
|
|
2652
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
2653
|
+
});
|
|
2654
|
+
}
|
|
2655
|
+
return to;
|
|
2656
|
+
};
|
|
2657
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
2658
|
+
value: mod,
|
|
2659
|
+
enumerable: true
|
|
2660
|
+
}) : target, mod));
|
|
2661
|
+
var require_typeof = __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/typeof.js"(exports, module) {
|
|
2662
|
+
function _typeof$2(o) {
|
|
2663
|
+
"@babel/helpers - typeof";
|
|
2664
|
+
return module.exports = _typeof$2 = typeof Symbol == "function" && typeof Symbol.iterator == "symbol" ? function(o$1) {
|
|
2665
|
+
return typeof o$1;
|
|
2666
|
+
} : function(o$1) {
|
|
2667
|
+
return o$1 && typeof Symbol == "function" && o$1.constructor === Symbol && o$1 !== Symbol.prototype ? "symbol" : typeof o$1;
|
|
2668
|
+
}, module.exports.__esModule = true, module.exports["default"] = module.exports, _typeof$2(o);
|
|
2669
|
+
}
|
|
2670
|
+
module.exports = _typeof$2, module.exports.__esModule = true, module.exports["default"] = module.exports;
|
|
2671
|
+
} });
|
|
2672
|
+
var require_toPrimitive = __commonJS({ "../../node_modules/.pnpm/@oxc-project+runtime@0.72.2/node_modules/@oxc-project/runtime/src/helpers/toPrimitive.js"(exports, module) {
|
|
2673
|
+
var _typeof$1 = require_typeof()["default"];
|
|
2674
|
+
function toPrimitive$1(t, r) {
|
|
2675
|
+
if (_typeof$1(t) != "object" || !t)
|
|
2676
|
+
return t;
|
|
2677
|
+
var e = t[Symbol.toPrimitive];
|
|
2115
2678
|
if (e !== undefined) {
|
|
2116
2679
|
var i = e.call(t, r || "default");
|
|
2117
2680
|
if (_typeof$1(i) != "object")
|
|
@@ -2879,10 +3442,10 @@ function dataLoader(batchLoader) {
|
|
|
2879
3442
|
}
|
|
2880
3443
|
function allAbortSignals(...signals) {
|
|
2881
3444
|
const ac = new AbortController;
|
|
2882
|
-
const
|
|
3445
|
+
const count2 = signals.length;
|
|
2883
3446
|
let abortedCount = 0;
|
|
2884
3447
|
const onAbort = () => {
|
|
2885
|
-
if (++abortedCount ===
|
|
3448
|
+
if (++abortedCount === count2)
|
|
2886
3449
|
ac.abort();
|
|
2887
3450
|
};
|
|
2888
3451
|
for (const signal of signals)
|
|
@@ -3457,6 +4020,55 @@ var import_awaitAsyncGenerator = __toESM(require_awaitAsyncGenerator(), 1);
|
|
|
3457
4020
|
var import_wrapAsyncGenerator = __toESM(require_wrapAsyncGenerator(), 1);
|
|
3458
4021
|
var import_objectSpread29 = __toESM(require_objectSpread2(), 1);
|
|
3459
4022
|
|
|
4023
|
+
// src/errors.ts
|
|
4024
|
+
function isUnauthorized2(error) {
|
|
4025
|
+
if (!(error instanceof Error))
|
|
4026
|
+
return false;
|
|
4027
|
+
const data = error.data;
|
|
4028
|
+
if (data?.code === "UNAUTHORIZED" || data?.httpStatus === 401)
|
|
4029
|
+
return true;
|
|
4030
|
+
return error.message.startsWith("Not logged in") || error.message.startsWith("Session is no longer valid");
|
|
4031
|
+
}
|
|
4032
|
+
var EXIT2 = {
|
|
4033
|
+
ok: 0,
|
|
4034
|
+
failed: 1,
|
|
4035
|
+
usage: 2,
|
|
4036
|
+
session: 3
|
|
4037
|
+
};
|
|
4038
|
+
var EXIT_CODES2 = [
|
|
4039
|
+
[EXIT2.ok, "done"],
|
|
4040
|
+
[
|
|
4041
|
+
EXIT2.failed,
|
|
4042
|
+
"something did not land: a failed install, a pending pull request"
|
|
4043
|
+
],
|
|
4044
|
+
[EXIT2.usage, "the command line was wrong; the last line says the spelling"],
|
|
4045
|
+
[EXIT2.session, "needs a session: run `yourskills login`"]
|
|
4046
|
+
];
|
|
4047
|
+
function closest(word, candidates, maxDistance = 2) {
|
|
4048
|
+
let best;
|
|
4049
|
+
for (const candidate of candidates) {
|
|
4050
|
+
const distance = edits(word.toLowerCase(), candidate.toLowerCase());
|
|
4051
|
+
if (distance <= maxDistance && (!best || distance < best.distance)) {
|
|
4052
|
+
best = { word: candidate, distance };
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
return best?.word;
|
|
4056
|
+
}
|
|
4057
|
+
function edits(a, b) {
|
|
4058
|
+
const rows = a.length + 1;
|
|
4059
|
+
const cols = b.length + 1;
|
|
4060
|
+
let previous = Array.from({ length: cols }, (_, j2) => j2);
|
|
4061
|
+
for (let i = 1;i < rows; i++) {
|
|
4062
|
+
const current = [i];
|
|
4063
|
+
for (let j2 = 1;j2 < cols; j2++) {
|
|
4064
|
+
const cost = a[i - 1] === b[j2 - 1] ? 0 : 1;
|
|
4065
|
+
current[j2] = Math.min(previous[j2] + 1, current[j2 - 1] + 1, previous[j2 - 1] + cost);
|
|
4066
|
+
}
|
|
4067
|
+
previous = current;
|
|
4068
|
+
}
|
|
4069
|
+
return previous[cols - 1];
|
|
4070
|
+
}
|
|
4071
|
+
|
|
3460
4072
|
// src/client.ts
|
|
3461
4073
|
async function createClient(server) {
|
|
3462
4074
|
const { token, base } = await requireToken(server);
|
|
@@ -3638,17 +4250,25 @@ function addHooks(settings, entries) {
|
|
|
3638
4250
|
const hooks = { ...next.hooks ?? {} };
|
|
3639
4251
|
const groups = [...hooks[entry.event] ?? []];
|
|
3640
4252
|
const ours = groups.findIndex((group) => group.matcher === entry.matcher && groupIsOurs(group));
|
|
4253
|
+
const ourCommand = {
|
|
4254
|
+
type: "command",
|
|
4255
|
+
command: entry.command,
|
|
4256
|
+
...entry.timeout === undefined ? {} : { timeout: entry.timeout }
|
|
4257
|
+
};
|
|
3641
4258
|
if (ours === -1) {
|
|
3642
|
-
groups.push({
|
|
3643
|
-
matcher: entry.matcher,
|
|
3644
|
-
hooks: [{ type: "command", command: entry.command }]
|
|
3645
|
-
});
|
|
4259
|
+
groups.push({ matcher: entry.matcher, hooks: [ourCommand] });
|
|
3646
4260
|
} else {
|
|
3647
4261
|
const group = groups[ours];
|
|
3648
4262
|
const commands = [...group.hooks ?? []];
|
|
3649
|
-
|
|
3650
|
-
|
|
3651
|
-
|
|
4263
|
+
const at = commands.findIndex((hook) => hook.command === entry.command);
|
|
4264
|
+
if (at === -1) {
|
|
4265
|
+
commands.push(ourCommand);
|
|
4266
|
+
} else {
|
|
4267
|
+
const existing = commands[at];
|
|
4268
|
+
if (existing.timeout === entry.timeout)
|
|
4269
|
+
continue;
|
|
4270
|
+
commands[at] = { ...existing, ...ourCommand };
|
|
4271
|
+
}
|
|
3652
4272
|
groups[ours] = { ...group, hooks: commands };
|
|
3653
4273
|
}
|
|
3654
4274
|
hooks[entry.event] = groups;
|
|
@@ -3755,17 +4375,16 @@ async function registerInto(adapter) {
|
|
|
3755
4375
|
return { agent: adapter.agent, path, entries: wanted };
|
|
3756
4376
|
}
|
|
3757
4377
|
function linesFor(registered) {
|
|
4378
|
+
const agents2 = registered.map((r) => r.agent).join(", ");
|
|
3758
4379
|
const lines = [
|
|
3759
|
-
|
|
4380
|
+
`+ yourskills will check your skills once a day, when ${agents2} starts, and update what moved`
|
|
3760
4381
|
];
|
|
3761
|
-
for (const { agent, path
|
|
3762
|
-
|
|
3763
|
-
lines.push(` ${agent} ${entry.event}(${entry.matcher}) ${path}`);
|
|
3764
|
-
}
|
|
4382
|
+
for (const { agent, path } of registered) {
|
|
4383
|
+
lines.push(` ${agent} ${path}`);
|
|
3765
4384
|
}
|
|
3766
|
-
lines.push(" undo
|
|
4385
|
+
lines.push(" undo with: yourskills hooks uninstall");
|
|
3767
4386
|
if (!trackingDisabledByEnv()) {
|
|
3768
|
-
lines.push(" usage counting stays off;
|
|
4387
|
+
lines.push(" usage counting stays off; turn it on with: yourskills hooks install --track");
|
|
3769
4388
|
}
|
|
3770
4389
|
return lines;
|
|
3771
4390
|
}
|
|
@@ -3865,8 +4484,12 @@ async function installInto(adapter, optedIn) {
|
|
|
3865
4484
|
result.installed.push(entry.kind);
|
|
3866
4485
|
}
|
|
3867
4486
|
const merged = addHooks(file.settings, wanted);
|
|
3868
|
-
|
|
4487
|
+
const changed = serialiseSettings(merged, file.indent) !== serialiseSettings(file.settings, file.indent);
|
|
4488
|
+
if (changed)
|
|
3869
4489
|
await writeSettingsFile(path, merged, file.indent);
|
|
4490
|
+
if (changed && result.already.length > 0) {
|
|
4491
|
+
result.repaired = result.already;
|
|
4492
|
+
result.already = [];
|
|
3870
4493
|
}
|
|
3871
4494
|
return result;
|
|
3872
4495
|
}
|
|
@@ -3887,6 +4510,13 @@ function linesFor2(result) {
|
|
|
3887
4510
|
note: result.path ?? ""
|
|
3888
4511
|
});
|
|
3889
4512
|
}
|
|
4513
|
+
for (const kind of result.repaired ?? []) {
|
|
4514
|
+
lines.push({
|
|
4515
|
+
mark: "ok",
|
|
4516
|
+
text: `${result.agent} ${kind}`,
|
|
4517
|
+
note: `updated ${result.path ?? ""}`.trim()
|
|
4518
|
+
});
|
|
4519
|
+
}
|
|
3890
4520
|
for (const kind of result.already) {
|
|
3891
4521
|
lines.push({
|
|
3892
4522
|
mark: "ok",
|
|
@@ -4048,141 +4678,116 @@ async function hooksStatus() {
|
|
|
4048
4678
|
json: { track: optedIn, agents: agents2 }
|
|
4049
4679
|
};
|
|
4050
4680
|
}
|
|
4051
|
-
//
|
|
4052
|
-
var
|
|
4053
|
-
|
|
4054
|
-
|
|
4055
|
-
|
|
4056
|
-
if (
|
|
4681
|
+
// src/hooks/session.ts
|
|
4682
|
+
var CHECK_BUDGET_MS = 5000;
|
|
4683
|
+
var UPDATE_BUDGET_MS = 90000;
|
|
4684
|
+
var DAY_MS = 86400000;
|
|
4685
|
+
function updateCheckDue(last, now = Date.now()) {
|
|
4686
|
+
if (!last)
|
|
4057
4687
|
return true;
|
|
4058
|
-
|
|
4688
|
+
const at = Date.parse(last);
|
|
4689
|
+
return Number.isNaN(at) || now - at >= DAY_MS;
|
|
4059
4690
|
}
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4063
|
-
|
|
4064
|
-
|
|
4065
|
-
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
scope: nearest.manifest.scope
|
|
4069
|
-
})).sort((a, b) => a.name.localeCompare(b.name));
|
|
4691
|
+
function withBudget(work, ms) {
|
|
4692
|
+
return Promise.race([
|
|
4693
|
+
work,
|
|
4694
|
+
new Promise((resolve3) => {
|
|
4695
|
+
const timer = setTimeout(() => resolve3(undefined), ms);
|
|
4696
|
+
timer.unref?.();
|
|
4697
|
+
})
|
|
4698
|
+
]);
|
|
4070
4699
|
}
|
|
4071
|
-
function
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
}));
|
|
4700
|
+
async function check(client, nearest) {
|
|
4701
|
+
try {
|
|
4702
|
+
const report = await driftNow(client, nearest);
|
|
4703
|
+
return { ok: true, moved: report.moved };
|
|
4704
|
+
} catch (error) {
|
|
4705
|
+
return { ok: false, signedOut: isUnauthorized2(error) };
|
|
4706
|
+
}
|
|
4079
4707
|
}
|
|
4080
|
-
function
|
|
4081
|
-
const
|
|
4082
|
-
const
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4708
|
+
async function applyUpdates(client, nearest, moved, deadline) {
|
|
4709
|
+
const opts = { scope: nearest.scope };
|
|
4710
|
+
const wanted = new Map(moved.map((row) => [row.name, row]));
|
|
4711
|
+
const applied = [];
|
|
4712
|
+
const failed = [];
|
|
4713
|
+
const consume = async (label, stream) => {
|
|
4714
|
+
try {
|
|
4715
|
+
await drain(stream);
|
|
4716
|
+
} catch (error) {
|
|
4717
|
+
failed.push({
|
|
4718
|
+
name: label,
|
|
4719
|
+
message: error instanceof Error ? error.message : String(error)
|
|
4720
|
+
});
|
|
4087
4721
|
}
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4093
|
-
|
|
4094
|
-
|
|
4095
|
-
|
|
4722
|
+
};
|
|
4723
|
+
const drain = async (stream) => {
|
|
4724
|
+
for await (const event of stream) {
|
|
4725
|
+
if (event.kind === "installed") {
|
|
4726
|
+
const row = wanted.get(event.location.skillName);
|
|
4727
|
+
if (row) {
|
|
4728
|
+
applied.push({
|
|
4729
|
+
name: row.name,
|
|
4730
|
+
from: shortRef(row.installed),
|
|
4731
|
+
to: shortRef(row.available)
|
|
4732
|
+
});
|
|
4733
|
+
}
|
|
4734
|
+
} else if (event.kind === "failed" && wanted.has(event.name)) {
|
|
4735
|
+
failed.push({ name: event.name, message: event.message });
|
|
4736
|
+
}
|
|
4096
4737
|
}
|
|
4097
4738
|
};
|
|
4739
|
+
const bundles = [
|
|
4740
|
+
...new Set(moved.map((row) => row.bundle).filter((name) => !!name))
|
|
4741
|
+
].sort();
|
|
4742
|
+
const loose = moved.filter((row) => !row.bundle).map((row) => row.name).sort();
|
|
4743
|
+
for (const bundle of bundles) {
|
|
4744
|
+
if (Date.now() > deadline)
|
|
4745
|
+
break;
|
|
4746
|
+
await consume(bundle, installBundle(client, bundle, opts));
|
|
4747
|
+
}
|
|
4748
|
+
if (loose.length > 0 && Date.now() <= deadline) {
|
|
4749
|
+
await consume(loose.join(", "), install(client, loose, opts));
|
|
4750
|
+
}
|
|
4751
|
+
if (applied.length === 0 && failed.length === 0)
|
|
4752
|
+
return { kind: "quiet" };
|
|
4753
|
+
return { kind: "updated", applied, failed, manifest: nearest.path };
|
|
4098
4754
|
}
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
}
|
|
4103
|
-
function drift(manifest, pins, catalog) {
|
|
4104
|
-
const byExternalId = new Map(catalog.map((row) => [row.externalId, row]));
|
|
4105
|
-
const byName = new Map(catalog.map((row) => [row.name, row]));
|
|
4106
|
-
const moved = [];
|
|
4107
|
-
const unknown = [];
|
|
4108
|
-
for (const entry of Object.values(manifest.skills)) {
|
|
4109
|
-
const row = byExternalId.get(entry.externalId) ?? byName.get(entry.name);
|
|
4110
|
-
if (!row) {
|
|
4111
|
-
unknown.push(entry.name);
|
|
4112
|
-
continue;
|
|
4113
|
-
}
|
|
4114
|
-
const pin = entry.bundle ? pins.find((p) => p.bundle === entry.bundle && p.skillId === row.id) : undefined;
|
|
4115
|
-
const available = pin?.pinnedSha ?? row.currentSha;
|
|
4116
|
-
if (!hasMoved(entry.ref, available))
|
|
4117
|
-
continue;
|
|
4118
|
-
moved.push({
|
|
4119
|
-
name: entry.name,
|
|
4120
|
-
bundle: entry.bundle ?? null,
|
|
4121
|
-
installed: entry.ref,
|
|
4122
|
-
available,
|
|
4123
|
-
deprecated: pin?.deprecated ?? row.status === "deprecated"
|
|
4124
|
-
});
|
|
4755
|
+
async function sessionStart(now = new Date) {
|
|
4756
|
+
const config = await readConfig();
|
|
4757
|
+
if (!updateCheckDue(config.lastUpdateCheck, now.getTime())) {
|
|
4758
|
+
return { kind: "quiet" };
|
|
4125
4759
|
}
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
}
|
|
4129
|
-
|
|
4130
|
-
let
|
|
4131
|
-
let catalog;
|
|
4760
|
+
await writeConfig({ ...config, lastUpdateCheck: now.toISOString() });
|
|
4761
|
+
if (!config.token)
|
|
4762
|
+
return { kind: "quiet" };
|
|
4763
|
+
let client;
|
|
4764
|
+
let nearest;
|
|
4132
4765
|
try {
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
}
|
|
4138
|
-
|
|
4139
|
-
return {
|
|
4140
|
-
|
|
4141
|
-
|
|
4142
|
-
|
|
4143
|
-
|
|
4144
|
-
|
|
4145
|
-
|
|
4146
|
-
};
|
|
4147
|
-
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
text: `${row.name} ${shortRef(row.installed)} -> ${shortRef(row.available)}`,
|
|
4152
|
-
note: [row.bundle ?? "-", row.deprecated ? "[deprecated]" : ""].filter(Boolean).join(" ")
|
|
4153
|
-
}));
|
|
4154
|
-
for (const name of report.unknown) {
|
|
4155
|
-
lines.push({
|
|
4156
|
-
mark: "fail",
|
|
4157
|
-
text: name,
|
|
4158
|
-
note: "no longer in your registry"
|
|
4159
|
-
});
|
|
4160
|
-
}
|
|
4161
|
-
const current = report.moved.length === 0 && report.unknown.length === 0;
|
|
4162
|
-
if (current && !quiet) {
|
|
4163
|
-
lines.push({
|
|
4164
|
-
mark: "ok",
|
|
4165
|
-
text: "Everything is at the ref your registry pins."
|
|
4166
|
-
});
|
|
4167
|
-
}
|
|
4168
|
-
return {
|
|
4169
|
-
title: "outdated",
|
|
4170
|
-
lines,
|
|
4171
|
-
json: {
|
|
4172
|
-
manifest: nearest.path,
|
|
4173
|
-
outdated: report.moved,
|
|
4174
|
-
unknown: report.unknown
|
|
4175
|
-
},
|
|
4176
|
-
silent: quiet && current
|
|
4177
|
-
};
|
|
4766
|
+
client = await createClient();
|
|
4767
|
+
nearest = await nearestManifest();
|
|
4768
|
+
} catch {
|
|
4769
|
+
return { kind: "quiet" };
|
|
4770
|
+
}
|
|
4771
|
+
if (Object.keys(nearest.manifest.skills).length === 0)
|
|
4772
|
+
return { kind: "quiet" };
|
|
4773
|
+
const found = await withBudget(check(client, nearest), CHECK_BUDGET_MS);
|
|
4774
|
+
if (!found)
|
|
4775
|
+
return { kind: "quiet" };
|
|
4776
|
+
if (!found.ok)
|
|
4777
|
+
return found.signedOut ? { kind: "signed-out" } : { kind: "quiet" };
|
|
4778
|
+
if (found.moved.length === 0)
|
|
4779
|
+
return { kind: "quiet" };
|
|
4780
|
+
if (config.autoUpdate === false) {
|
|
4781
|
+
return { kind: "behind", moved: found.moved, manifest: nearest.path };
|
|
4782
|
+
}
|
|
4783
|
+
return applyUpdates(client, nearest, found.moved, Date.now() + UPDATE_BUDGET_MS);
|
|
4178
4784
|
}
|
|
4785
|
+
|
|
4179
4786
|
// src/hooks/run.ts
|
|
4180
4787
|
function isHookEventName(value) {
|
|
4181
4788
|
return value === "session-start" || value === "post-tool-use";
|
|
4182
4789
|
}
|
|
4183
4790
|
var STDIN_BUDGET_MS = 2000;
|
|
4184
|
-
var SESSION_BUDGET_MS = 5000;
|
|
4185
|
-
var DAY_MS = 86400000;
|
|
4186
4791
|
async function readStdin() {
|
|
4187
4792
|
if (process.stdin.isTTY)
|
|
4188
4793
|
return {};
|
|
@@ -4235,46 +4840,19 @@ async function queueInvocation(payload, now = new Date) {
|
|
|
4235
4840
|
await appendEvent(event);
|
|
4236
4841
|
return event;
|
|
4237
4842
|
}
|
|
4238
|
-
function updateCheckDue(last, now = Date.now()) {
|
|
4239
|
-
if (!last)
|
|
4240
|
-
return true;
|
|
4241
|
-
const at = Date.parse(last);
|
|
4242
|
-
return Number.isNaN(at) || now - at >= DAY_MS;
|
|
4243
|
-
}
|
|
4244
|
-
async function sessionStart() {
|
|
4245
|
-
await flushQuietly();
|
|
4246
|
-
const config = await readConfig();
|
|
4247
|
-
if (!updateCheckDue(config.lastUpdateCheck))
|
|
4248
|
-
return;
|
|
4249
|
-
await writeConfig({ ...config, lastUpdateCheck: new Date().toISOString() });
|
|
4250
|
-
const client = await createClient();
|
|
4251
|
-
const nearest = await nearestManifest();
|
|
4252
|
-
const report = await outdatedReport(client, nearest, true);
|
|
4253
|
-
if (!report.silent && report.lines.length > 0) {
|
|
4254
|
-
const moved = report.json.outdated?.length ?? 0;
|
|
4255
|
-
if (moved > 0) {
|
|
4256
|
-
console.log(`yourskills: ${moved} skill(s) behind your registry — run \`yourskills update\``);
|
|
4257
|
-
}
|
|
4258
|
-
}
|
|
4259
|
-
}
|
|
4260
4843
|
async function runHook(event) {
|
|
4261
4844
|
try {
|
|
4262
4845
|
const payload = await readStdin();
|
|
4263
4846
|
if (event === "post-tool-use")
|
|
4264
4847
|
await queueInvocation(payload);
|
|
4265
4848
|
else
|
|
4266
|
-
await
|
|
4849
|
+
await runSessionStart();
|
|
4267
4850
|
} catch {}
|
|
4268
4851
|
process.exitCode = 0;
|
|
4269
4852
|
}
|
|
4270
|
-
function
|
|
4271
|
-
|
|
4272
|
-
|
|
4273
|
-
new Promise((resolve3) => {
|
|
4274
|
-
const timer = setTimeout(() => resolve3(undefined), ms);
|
|
4275
|
-
timer.unref?.();
|
|
4276
|
-
})
|
|
4277
|
-
]);
|
|
4853
|
+
async function runSessionStart() {
|
|
4854
|
+
await flushQuietly();
|
|
4855
|
+
emit(await sessionStart());
|
|
4278
4856
|
}
|
|
4279
4857
|
// src/org/org.ts
|
|
4280
4858
|
var authBase2 = (base) => `${base.replace(/\/$/, "")}/api/auth`;
|
|
@@ -4386,68 +4964,138 @@ async function orgSwitchReport(name, server) {
|
|
|
4386
4964
|
};
|
|
4387
4965
|
}
|
|
4388
4966
|
// src/report.ts
|
|
4967
|
+
function nextLine(next) {
|
|
4968
|
+
return `next ${next.command} ${next.why}`;
|
|
4969
|
+
}
|
|
4389
4970
|
function plainLine(line2, glyph) {
|
|
4390
4971
|
const head = line2.mark === "none" ? "" : `${glyph[line2.mark]} `;
|
|
4391
4972
|
return `${head}${line2.text}${line2.note ? ` ${line2.note}` : ""}`;
|
|
4392
4973
|
}
|
|
4393
4974
|
// src/shell/commands.ts
|
|
4394
|
-
function
|
|
4395
|
-
return
|
|
4396
|
-
|
|
4397
|
-
|
|
4398
|
-
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
|
|
4403
|
-
|
|
4404
|
-
|
|
4405
|
-
|
|
4406
|
-
|
|
4407
|
-
|
|
4408
|
-
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
{ value: "installed.remove", label: "remove", hint: "remove <skill>" }
|
|
4415
|
-
]
|
|
4416
|
-
},
|
|
4417
|
-
{
|
|
4418
|
-
group: "Account",
|
|
4419
|
-
items: [
|
|
4420
|
-
{ value: "account.login", label: "login", hint: "login" },
|
|
4421
|
-
{ value: "account.logout", label: "logout", hint: "logout" },
|
|
4422
|
-
{ value: "account.whoami", label: "whoami", hint: "whoami" },
|
|
4423
|
-
{ value: "account.org", label: "switch org", hint: "org <name>" }
|
|
4424
|
-
]
|
|
4425
|
-
},
|
|
4426
|
-
{
|
|
4427
|
-
group: "Setup",
|
|
4428
|
-
items: [
|
|
4429
|
-
{
|
|
4430
|
-
value: "setup.scope",
|
|
4431
|
-
label: "scope",
|
|
4432
|
-
hint: "config set scope project"
|
|
4433
|
-
},
|
|
4434
|
-
{
|
|
4435
|
-
value: "setup.agents",
|
|
4436
|
-
label: "agents",
|
|
4437
|
-
hint: "config set agents <name>"
|
|
4438
|
-
},
|
|
4439
|
-
{ value: "setup.doctor", label: "doctor", hint: "doctor" }
|
|
4440
|
-
]
|
|
4975
|
+
function count2(n, one, many = `${one}s`) {
|
|
4976
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
4977
|
+
}
|
|
4978
|
+
function describe2(value, facts) {
|
|
4979
|
+
switch (value) {
|
|
4980
|
+
case undefined:
|
|
4981
|
+
return "";
|
|
4982
|
+
case "catalog.bundles":
|
|
4983
|
+
return "browse the bundles your registry publishes, and install one";
|
|
4984
|
+
case "catalog.skills":
|
|
4985
|
+
return "browse every skill in your registry, and install any of them";
|
|
4986
|
+
case "catalog.search":
|
|
4987
|
+
return "filter the same catalog by name and description";
|
|
4988
|
+
case "installed.list":
|
|
4989
|
+
return `show the ${count2(facts.skills, "skill")} recorded in ${facts.manifest}`;
|
|
4990
|
+
case "installed.update": {
|
|
4991
|
+
const scope = updateScope(facts.bundles, facts.loose);
|
|
4992
|
+
if (scope === "")
|
|
4993
|
+
return "nothing is tracked here to update";
|
|
4994
|
+
return `re-install ${scope} at what the registry blesses today`;
|
|
4441
4995
|
}
|
|
4442
|
-
|
|
4996
|
+
case "installed.outdated":
|
|
4997
|
+
return `check your ${count2(facts.skills, "installed skill")} against the registry — reads only, changes nothing`;
|
|
4998
|
+
case "installed.remove":
|
|
4999
|
+
return `pick which of the ${count2(facts.skills, "skill")} to delete from this machine; it asks before it does`;
|
|
5000
|
+
case "account.login":
|
|
5001
|
+
return "sign in with a code you enter in your browser";
|
|
5002
|
+
case "account.logout":
|
|
5003
|
+
return "forget the token on this machine and revoke it server-side";
|
|
5004
|
+
case "account.whoami":
|
|
5005
|
+
return "ask the server who this token belongs to";
|
|
5006
|
+
case "account.org":
|
|
5007
|
+
return "list the organizations you can switch this machine to";
|
|
5008
|
+
case "setup.scope":
|
|
5009
|
+
return `where installs land: ${facts.scope} right now`;
|
|
5010
|
+
case "setup.agents":
|
|
5011
|
+
return "which agents a skill is written for when it is installed";
|
|
5012
|
+
case "setup.doctor":
|
|
5013
|
+
return "check the stock CLI, the manifest and the session in one pass";
|
|
5014
|
+
}
|
|
5015
|
+
}
|
|
5016
|
+
var CATALOG = [
|
|
5017
|
+
{ value: "catalog.bundles", label: "browse bundles", hint: "browse" },
|
|
5018
|
+
{ value: "catalog.skills", label: "browse skills", hint: "list" },
|
|
5019
|
+
{ value: "catalog.search", label: "search", hint: "search <query>" }
|
|
5020
|
+
];
|
|
5021
|
+
var INSTALLED = {
|
|
5022
|
+
list: { value: "installed.list", label: "list installed", hint: "installed" },
|
|
5023
|
+
update: {
|
|
5024
|
+
value: "installed.update",
|
|
5025
|
+
label: "update all",
|
|
5026
|
+
hint: "update --all"
|
|
5027
|
+
},
|
|
5028
|
+
outdated: {
|
|
5029
|
+
value: "installed.outdated",
|
|
5030
|
+
label: "outdated",
|
|
5031
|
+
hint: "outdated"
|
|
5032
|
+
},
|
|
5033
|
+
remove: {
|
|
5034
|
+
value: "installed.remove",
|
|
5035
|
+
label: "remove",
|
|
5036
|
+
hint: "remove <skill>"
|
|
5037
|
+
}
|
|
5038
|
+
};
|
|
5039
|
+
var ACCOUNT = {
|
|
5040
|
+
login: { value: "account.login", label: "login", hint: "login" },
|
|
5041
|
+
logout: { value: "account.logout", label: "logout", hint: "logout" },
|
|
5042
|
+
whoami: { value: "account.whoami", label: "whoami", hint: "whoami" },
|
|
5043
|
+
org: { value: "account.org", label: "switch org", hint: "org <name>" }
|
|
5044
|
+
};
|
|
5045
|
+
var SETUP = [
|
|
5046
|
+
{ value: "setup.scope", label: "scope", hint: "config set scope project" },
|
|
5047
|
+
{ value: "setup.agents", label: "agents", hint: "config set agents <name>" },
|
|
5048
|
+
{ value: "setup.doctor", label: "doctor", hint: "doctor" }
|
|
5049
|
+
];
|
|
5050
|
+
function paletteGroups(facts) {
|
|
5051
|
+
const groups = [];
|
|
5052
|
+
if (facts.signedIn)
|
|
5053
|
+
groups.push({ group: "Catalog", items: CATALOG });
|
|
5054
|
+
const installed = [];
|
|
5055
|
+
if (facts.skills > 0) {
|
|
5056
|
+
installed.push(INSTALLED.list);
|
|
5057
|
+
if (facts.signedIn)
|
|
5058
|
+
installed.push(INSTALLED.update, INSTALLED.outdated);
|
|
5059
|
+
installed.push(INSTALLED.remove);
|
|
5060
|
+
}
|
|
5061
|
+
if (installed.length > 0)
|
|
5062
|
+
groups.push({ group: "Installed", items: installed });
|
|
5063
|
+
groups.push({
|
|
5064
|
+
group: "Account",
|
|
5065
|
+
items: facts.signedIn ? [ACCOUNT.logout, ACCOUNT.whoami, ACCOUNT.org] : [ACCOUNT.login]
|
|
5066
|
+
});
|
|
5067
|
+
groups.push({ group: "Setup", items: SETUP });
|
|
5068
|
+
return groups;
|
|
5069
|
+
}
|
|
5070
|
+
// src/shell/facts.ts
|
|
5071
|
+
import { existsSync as existsSync5 } from "node:fs";
|
|
5072
|
+
async function paletteFacts(scope, server) {
|
|
5073
|
+
const [account, nearest, config] = await Promise.all([
|
|
5074
|
+
localAccount(server),
|
|
5075
|
+
nearestManifest(scope),
|
|
5076
|
+
readConfig()
|
|
5077
|
+
]);
|
|
5078
|
+
const skills = Object.keys(nearest.manifest.skills).length;
|
|
5079
|
+
return {
|
|
5080
|
+
signedIn: account.signedIn,
|
|
5081
|
+
email: account.email,
|
|
5082
|
+
server: account.server,
|
|
5083
|
+
firstRun: !account.signedIn && skills === 0 && !config.welcomed,
|
|
5084
|
+
agentsOnDisk: HOOK_ADAPTERS.filter((adapter) => existsSync5(adapter.home())).map((adapter) => adapter.agent),
|
|
5085
|
+
scope: nearest.scope,
|
|
5086
|
+
manifest: nearest.path,
|
|
5087
|
+
skills,
|
|
5088
|
+
bundles: Object.keys(nearest.manifest.bundles).length,
|
|
5089
|
+
loose: looseSkills(nearest.manifest).length
|
|
5090
|
+
};
|
|
4443
5091
|
}
|
|
4444
5092
|
// src/shell/screens/home.tsx
|
|
4445
|
-
import { Box as
|
|
4446
|
-
import { useCallback as useCallback3, useEffect as
|
|
5093
|
+
import { Box as Box14, Text as Text16, useApp as useApp7, useInput as useInput8 } from "ink";
|
|
5094
|
+
import { useCallback as useCallback3, useEffect as useEffect9, useMemo as useMemo4, useRef, useState as useState11 } from "react";
|
|
4447
5095
|
// src/screens.tsx
|
|
4448
|
-
import { Box as
|
|
4449
|
-
import { useEffect as useEffect7, useState as
|
|
4450
|
-
import { jsx as
|
|
5096
|
+
import { Box as Box10, Text as Text12, useApp as useApp6, useInput as useInput5 } from "ink";
|
|
5097
|
+
import { useEffect as useEffect7, useState as useState8 } from "react";
|
|
5098
|
+
import { jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
4451
5099
|
var MARKS = {
|
|
4452
5100
|
ok: { glyph: mark.ok, color: "green" },
|
|
4453
5101
|
fail: { glyph: mark.fail, color: tone.danger },
|
|
@@ -4458,16 +5106,16 @@ function ReportRow({ line: line2, width }) {
|
|
|
4458
5106
|
const { glyph, color } = MARKS[line2.mark];
|
|
4459
5107
|
const head = line2.mark === "none" ? "" : `${glyph} `;
|
|
4460
5108
|
const room = width - FRAME_CHROME - head.length;
|
|
4461
|
-
return /* @__PURE__ */
|
|
5109
|
+
return /* @__PURE__ */ jsxs12(Text12, {
|
|
4462
5110
|
children: [
|
|
4463
|
-
head ? /* @__PURE__ */
|
|
5111
|
+
head ? /* @__PURE__ */ jsx13(Text12, {
|
|
4464
5112
|
color,
|
|
4465
5113
|
children: head
|
|
4466
5114
|
}) : null,
|
|
4467
|
-
/* @__PURE__ */
|
|
5115
|
+
/* @__PURE__ */ jsx13(Text12, {
|
|
4468
5116
|
children: clip(line2.text, room)
|
|
4469
5117
|
}),
|
|
4470
|
-
line2.note ? /* @__PURE__ */
|
|
5118
|
+
line2.note ? /* @__PURE__ */ jsx13(Text12, {
|
|
4471
5119
|
dimColor: true,
|
|
4472
5120
|
children: clip(` ${line2.note}`, Math.max(room - line2.text.length, 0))
|
|
4473
5121
|
}) : null
|
|
@@ -4479,11 +5127,14 @@ function ReportScreen({
|
|
|
4479
5127
|
load,
|
|
4480
5128
|
onError,
|
|
4481
5129
|
onReport,
|
|
4482
|
-
exitWhenDone = true
|
|
5130
|
+
exitWhenDone = true,
|
|
5131
|
+
onBack,
|
|
5132
|
+
working = "Working...",
|
|
5133
|
+
onNext
|
|
4483
5134
|
}) {
|
|
4484
5135
|
const { exit } = useApp6();
|
|
4485
5136
|
const width = useFrameWidth();
|
|
4486
|
-
const [report, setReport] =
|
|
5137
|
+
const [report, setReport] = useState8(null);
|
|
4487
5138
|
useEffect7(() => {
|
|
4488
5139
|
let live = true;
|
|
4489
5140
|
load().then((result) => {
|
|
@@ -4503,29 +5154,632 @@ function ReportScreen({
|
|
|
4503
5154
|
if (report && exitWhenDone)
|
|
4504
5155
|
exit();
|
|
4505
5156
|
}, [report, exit, exitWhenDone]);
|
|
4506
|
-
|
|
5157
|
+
const next = report?.next;
|
|
5158
|
+
useInput5((input) => {
|
|
5159
|
+
if (input === "n" && next)
|
|
5160
|
+
onNext?.(next.command);
|
|
5161
|
+
}, { isActive: Boolean(onNext && next) });
|
|
5162
|
+
return /* @__PURE__ */ jsxs12(Frame, {
|
|
5163
|
+
title,
|
|
5164
|
+
width,
|
|
5165
|
+
children: [
|
|
5166
|
+
report ? /* @__PURE__ */ jsxs12(Box10, {
|
|
5167
|
+
flexDirection: "column",
|
|
5168
|
+
children: [
|
|
5169
|
+
report.lines.map((line2) => /* @__PURE__ */ jsx13(ReportRow, {
|
|
5170
|
+
line: line2,
|
|
5171
|
+
width
|
|
5172
|
+
}, `${line2.mark}:${line2.text}`)),
|
|
5173
|
+
next ? /* @__PURE__ */ jsxs12(Text12, {
|
|
5174
|
+
children: [
|
|
5175
|
+
/* @__PURE__ */ jsx13(Text12, {
|
|
5176
|
+
dimColor: true,
|
|
5177
|
+
children: "next "
|
|
5178
|
+
}),
|
|
5179
|
+
/* @__PURE__ */ jsx13(Text12, {
|
|
5180
|
+
color: tone.primary,
|
|
5181
|
+
children: next.command
|
|
5182
|
+
}),
|
|
5183
|
+
/* @__PURE__ */ jsx13(Text12, {
|
|
5184
|
+
dimColor: true,
|
|
5185
|
+
children: clip(` ${next.why}`, width - FRAME_CHROME)
|
|
5186
|
+
})
|
|
5187
|
+
]
|
|
5188
|
+
}) : null
|
|
5189
|
+
]
|
|
5190
|
+
}) : /* @__PURE__ */ jsxs12(Text12, {
|
|
5191
|
+
children: [
|
|
5192
|
+
/* @__PURE__ */ jsx13(Spinner, {}),
|
|
5193
|
+
/* @__PURE__ */ jsx13(Text12, {
|
|
5194
|
+
dimColor: true,
|
|
5195
|
+
children: ` ${working}`
|
|
5196
|
+
})
|
|
5197
|
+
]
|
|
5198
|
+
}),
|
|
5199
|
+
/* @__PURE__ */ jsx13(Back, {
|
|
5200
|
+
width,
|
|
5201
|
+
onBack,
|
|
5202
|
+
extra: onNext && next ? [["n", "run next"]] : []
|
|
5203
|
+
})
|
|
5204
|
+
]
|
|
5205
|
+
});
|
|
5206
|
+
}
|
|
5207
|
+
|
|
5208
|
+
// src/args.ts
|
|
5209
|
+
var COMMAND_WORDS = [
|
|
5210
|
+
"browse",
|
|
5211
|
+
"login",
|
|
5212
|
+
"logout",
|
|
5213
|
+
"whoami",
|
|
5214
|
+
"org",
|
|
5215
|
+
"list",
|
|
5216
|
+
"search",
|
|
5217
|
+
"bundle",
|
|
5218
|
+
"add",
|
|
5219
|
+
"install",
|
|
5220
|
+
"remove",
|
|
5221
|
+
"update",
|
|
5222
|
+
"installed",
|
|
5223
|
+
"outdated",
|
|
5224
|
+
"doctor",
|
|
5225
|
+
"config",
|
|
5226
|
+
"hooks",
|
|
5227
|
+
"help",
|
|
5228
|
+
"version"
|
|
5229
|
+
];
|
|
5230
|
+
function configCommand(rest) {
|
|
5231
|
+
const [action, key, ...value] = rest;
|
|
5232
|
+
if (action === undefined || action === "get") {
|
|
5233
|
+
return { kind: "config", action: "get", ...key ? { key } : {} };
|
|
5234
|
+
}
|
|
5235
|
+
if (action !== "set") {
|
|
5236
|
+
return {
|
|
5237
|
+
kind: "error",
|
|
5238
|
+
message: `config takes get or set, not ${action}: yourskills config get [key]`
|
|
5239
|
+
};
|
|
5240
|
+
}
|
|
5241
|
+
if (!key) {
|
|
5242
|
+
return {
|
|
5243
|
+
kind: "error",
|
|
5244
|
+
message: "config set needs a key: yourskills config set <key> <value>"
|
|
5245
|
+
};
|
|
5246
|
+
}
|
|
5247
|
+
if (value.length === 0) {
|
|
5248
|
+
return {
|
|
5249
|
+
kind: "error",
|
|
5250
|
+
message: `config set needs a value: yourskills config set ${key} <value>`
|
|
5251
|
+
};
|
|
5252
|
+
}
|
|
5253
|
+
return { kind: "config", action: "set", key, value: value.join(" ") };
|
|
5254
|
+
}
|
|
5255
|
+
function hooksCommand(rest, agent, track) {
|
|
5256
|
+
const action = rest[0] ?? "status";
|
|
5257
|
+
if (action !== "install" && action !== "uninstall" && action !== "status") {
|
|
5258
|
+
return {
|
|
5259
|
+
kind: "error",
|
|
5260
|
+
message: `hooks takes install, uninstall or status, not ${action}`
|
|
5261
|
+
};
|
|
5262
|
+
}
|
|
5263
|
+
return {
|
|
5264
|
+
kind: "hooks",
|
|
5265
|
+
action,
|
|
5266
|
+
...agent ? { agent } : {},
|
|
5267
|
+
...track === undefined ? {} : { track }
|
|
5268
|
+
};
|
|
5269
|
+
}
|
|
5270
|
+
function parseArgv(args, interactive = true) {
|
|
5271
|
+
const opts = {};
|
|
5272
|
+
const positional = [];
|
|
5273
|
+
let plain = !interactive;
|
|
5274
|
+
let json = false;
|
|
5275
|
+
let all = false;
|
|
5276
|
+
let quiet = false;
|
|
5277
|
+
let server;
|
|
5278
|
+
let track;
|
|
5279
|
+
const done = (command2) => ({
|
|
5280
|
+
command: command2,
|
|
5281
|
+
output: { plain, json },
|
|
5282
|
+
...server ? { server } : {}
|
|
5283
|
+
});
|
|
5284
|
+
for (let i = 0;i < args.length; i++) {
|
|
5285
|
+
const arg = args[i];
|
|
5286
|
+
if (arg === "-h" || arg === "--help")
|
|
5287
|
+
return done({ kind: "help" });
|
|
5288
|
+
if (arg === "-v" || arg === "--version")
|
|
5289
|
+
return done({ kind: "version" });
|
|
5290
|
+
if (arg === "--plain") {
|
|
5291
|
+
plain = true;
|
|
5292
|
+
} else if (arg === "--json") {
|
|
5293
|
+
json = true;
|
|
5294
|
+
plain = true;
|
|
5295
|
+
} else if (arg === "-g" || arg === "--global") {
|
|
5296
|
+
opts.scope = "global";
|
|
5297
|
+
} else if (arg === "-p" || arg === "--project") {
|
|
5298
|
+
opts.scope = "project";
|
|
5299
|
+
} else if (arg === "--all") {
|
|
5300
|
+
all = true;
|
|
5301
|
+
} else if (arg === "-q" || arg === "--quiet") {
|
|
5302
|
+
quiet = true;
|
|
5303
|
+
} else if (arg === "--track") {
|
|
5304
|
+
track = true;
|
|
5305
|
+
} else if (arg === "--no-track") {
|
|
5306
|
+
track = false;
|
|
5307
|
+
} else if (arg === "--server") {
|
|
5308
|
+
const value = args[++i];
|
|
5309
|
+
if (!value)
|
|
5310
|
+
return done({ kind: "error", message: "--server requires a URL" });
|
|
5311
|
+
server = value;
|
|
5312
|
+
} else if (arg === "-a" || arg === "--agent") {
|
|
5313
|
+
const value = args[++i];
|
|
5314
|
+
if (!value)
|
|
5315
|
+
return done({
|
|
5316
|
+
kind: "error",
|
|
5317
|
+
message: "--agent requires an agent name"
|
|
5318
|
+
});
|
|
5319
|
+
opts.agents = [...opts.agents ?? [], value];
|
|
5320
|
+
} else if (arg.startsWith("-")) {
|
|
5321
|
+
return done({
|
|
5322
|
+
kind: "error",
|
|
5323
|
+
message: `unknown option ${arg}`,
|
|
5324
|
+
next: "yourskills --help"
|
|
5325
|
+
});
|
|
5326
|
+
} else {
|
|
5327
|
+
positional.push(arg);
|
|
5328
|
+
}
|
|
5329
|
+
}
|
|
5330
|
+
const [command, ...rest] = positional;
|
|
5331
|
+
switch (command) {
|
|
5332
|
+
case undefined:
|
|
5333
|
+
return done(plain ? { kind: "help" } : { kind: "home" });
|
|
5334
|
+
case "help":
|
|
5335
|
+
return done({ kind: "help" });
|
|
5336
|
+
case "version":
|
|
5337
|
+
return done({ kind: "version" });
|
|
5338
|
+
case "browse":
|
|
5339
|
+
return done(plain ? {
|
|
5340
|
+
kind: "error",
|
|
5341
|
+
message: "browse needs a terminal; use `list` or `search` instead"
|
|
5342
|
+
} : { kind: "browse" });
|
|
5343
|
+
case "login":
|
|
5344
|
+
return done({ kind: "login" });
|
|
5345
|
+
case "logout":
|
|
5346
|
+
return done({ kind: "logout" });
|
|
5347
|
+
case "whoami":
|
|
5348
|
+
return done({ kind: "whoami" });
|
|
5349
|
+
case "list":
|
|
5350
|
+
return done({ kind: "list" });
|
|
5351
|
+
case "search":
|
|
5352
|
+
return done(rest.length > 0 ? { kind: "search", query: rest.join(" ") } : {
|
|
5353
|
+
kind: "error",
|
|
5354
|
+
message: "search needs a query: yourskills search <query>"
|
|
5355
|
+
});
|
|
5356
|
+
case "add":
|
|
5357
|
+
return done(rest.length > 0 ? { kind: "add", names: rest, opts } : {
|
|
5358
|
+
kind: "error",
|
|
5359
|
+
message: "add needs at least one skill: yourskills add <skill...>"
|
|
5360
|
+
});
|
|
5361
|
+
case "install":
|
|
5362
|
+
return done(rest.length > 0 ? { kind: "add", names: rest, opts } : { kind: "install", opts });
|
|
5363
|
+
case "remove":
|
|
5364
|
+
return done(rest.length > 0 ? { kind: "remove", names: rest, opts } : {
|
|
5365
|
+
kind: "error",
|
|
5366
|
+
message: "remove needs at least one skill: yourskills remove <skill...>"
|
|
5367
|
+
});
|
|
5368
|
+
case "installed":
|
|
5369
|
+
return done({ kind: "installed" });
|
|
5370
|
+
case "outdated":
|
|
5371
|
+
return done({ kind: "outdated", ...quiet ? { quiet: true } : {} });
|
|
5372
|
+
case "doctor":
|
|
5373
|
+
return done({ kind: "doctor" });
|
|
5374
|
+
case "org":
|
|
5375
|
+
return done(rest[0] ? { kind: "org", name: rest[0] } : { kind: "org" });
|
|
5376
|
+
case "config":
|
|
5377
|
+
return done(configCommand(rest));
|
|
5378
|
+
case "hooks":
|
|
5379
|
+
return done(hooksCommand(rest, opts.agents?.[0], track));
|
|
5380
|
+
case "hook": {
|
|
5381
|
+
const event = rest[0];
|
|
5382
|
+
return done(event && isHookEventName(event) ? { kind: "hook", event } : {
|
|
5383
|
+
kind: "error",
|
|
5384
|
+
message: "hook takes session-start or post-tool-use"
|
|
5385
|
+
});
|
|
5386
|
+
}
|
|
5387
|
+
case "bundle":
|
|
5388
|
+
return done(rest[0] ? { kind: "bundle", name: rest[0], opts } : {
|
|
5389
|
+
kind: "error",
|
|
5390
|
+
message: "bundle needs a name: yourskills bundle <name>"
|
|
5391
|
+
});
|
|
5392
|
+
case "update":
|
|
5393
|
+
return done({
|
|
5394
|
+
kind: "update",
|
|
5395
|
+
...rest[0] ? { bundle: rest[0] } : {},
|
|
5396
|
+
...all ? { all: true } : {},
|
|
5397
|
+
opts
|
|
5398
|
+
});
|
|
5399
|
+
default: {
|
|
5400
|
+
const guess = closest(command, COMMAND_WORDS);
|
|
5401
|
+
return done({
|
|
5402
|
+
kind: "error",
|
|
5403
|
+
message: `unknown command ${command}`,
|
|
5404
|
+
...guess ? { why: `did you mean ${guess}?`, next: `yourskills ${guess}` } : { next: "yourskills --help" }
|
|
5405
|
+
});
|
|
5406
|
+
}
|
|
5407
|
+
}
|
|
5408
|
+
}
|
|
5409
|
+
|
|
5410
|
+
// src/shell/typed.ts
|
|
5411
|
+
var RUNNABLE = new Set([
|
|
5412
|
+
"browse",
|
|
5413
|
+
"login",
|
|
5414
|
+
"logout",
|
|
5415
|
+
"whoami",
|
|
5416
|
+
"org",
|
|
5417
|
+
"list",
|
|
5418
|
+
"search",
|
|
5419
|
+
"add",
|
|
5420
|
+
"bundle",
|
|
5421
|
+
"install",
|
|
5422
|
+
"remove",
|
|
5423
|
+
"update",
|
|
5424
|
+
"installed",
|
|
5425
|
+
"outdated",
|
|
5426
|
+
"doctor",
|
|
5427
|
+
"config",
|
|
5428
|
+
"hooks"
|
|
5429
|
+
]);
|
|
5430
|
+
function typedCommand(query) {
|
|
5431
|
+
const words = query.trim().split(/\s+/).filter(Boolean);
|
|
5432
|
+
if (words.length === 0)
|
|
5433
|
+
return null;
|
|
5434
|
+
if (words[0] === "yourskills")
|
|
5435
|
+
words.shift();
|
|
5436
|
+
if (words.length === 0)
|
|
5437
|
+
return null;
|
|
5438
|
+
const { command } = parseArgv(words, true);
|
|
5439
|
+
if (command.kind !== "error" && !RUNNABLE.has(command.kind))
|
|
5440
|
+
return null;
|
|
5441
|
+
return { command, text: words.join(" ") };
|
|
5442
|
+
}
|
|
5443
|
+
function runnable(typed) {
|
|
5444
|
+
return typed !== null && typed.command.kind !== "error";
|
|
5445
|
+
}
|
|
5446
|
+
function count3(n, one, many = `${one}s`) {
|
|
5447
|
+
return `${n} ${n === 1 ? one : many}`;
|
|
5448
|
+
}
|
|
5449
|
+
function where2(scope, facts) {
|
|
5450
|
+
return (scope ?? facts.scope) === "project" ? "into this project" : "everywhere on this computer";
|
|
5451
|
+
}
|
|
5452
|
+
function describeCommand(command, facts) {
|
|
5453
|
+
switch (command.kind) {
|
|
5454
|
+
case "add":
|
|
5455
|
+
return `install ${count3(command.names.length, "skill")} ${where2(command.opts.scope, facts)}: ${command.names.join(", ")}`;
|
|
5456
|
+
case "bundle":
|
|
5457
|
+
return `install the bundle ${command.name} ${where2(command.opts.scope, facts)}, at the refs your registry pins today`;
|
|
5458
|
+
case "install":
|
|
5459
|
+
return facts.skills > 0 ? `re-install the ${count3(facts.skills, "skill")} recorded in ${facts.manifest}, at their recorded refs` : "nothing is recorded here to re-install";
|
|
5460
|
+
case "update": {
|
|
5461
|
+
if (command.bundle)
|
|
5462
|
+
return `re-install ${command.bundle} at what the registry blesses today`;
|
|
5463
|
+
const scope = updateScope(facts.bundles, command.all ? facts.loose : 0);
|
|
5464
|
+
return scope === "" ? "nothing is tracked here to update" : `re-install ${scope} at what the registry blesses today`;
|
|
5465
|
+
}
|
|
5466
|
+
case "remove":
|
|
5467
|
+
return `delete ${command.names.join(", ")} from disk and from ${facts.manifest} (asks first)`;
|
|
5468
|
+
case "installed":
|
|
5469
|
+
return describe2("installed.list", facts);
|
|
5470
|
+
case "outdated":
|
|
5471
|
+
return describe2("installed.outdated", facts);
|
|
5472
|
+
case "doctor":
|
|
5473
|
+
return describe2("setup.doctor", facts);
|
|
5474
|
+
case "whoami":
|
|
5475
|
+
return describe2("account.whoami", facts);
|
|
5476
|
+
case "logout":
|
|
5477
|
+
return describe2("account.logout", facts);
|
|
5478
|
+
case "login":
|
|
5479
|
+
return describe2("account.login", facts);
|
|
5480
|
+
case "org":
|
|
5481
|
+
return command.name ? `switch this machine to the organization ${command.name}` : describe2("account.org", facts);
|
|
5482
|
+
case "config":
|
|
5483
|
+
return command.action === "set" ? `set ${command.key} to ${command.value} in your config file` : command.key ? `show the stored ${command.key}` : "show every stored setting";
|
|
5484
|
+
case "hooks":
|
|
5485
|
+
return command.action === "install" ? "register our hooks in your agents' settings, so skills stay updated" : command.action === "uninstall" ? "remove our hooks from your agents' settings, leaving every other hook alone" : "show which agents carry our hooks, and where";
|
|
5486
|
+
case "list":
|
|
5487
|
+
return describe2("catalog.skills", facts);
|
|
5488
|
+
case "search":
|
|
5489
|
+
return `open the catalog filtered on "${command.query}"`;
|
|
5490
|
+
case "browse":
|
|
5491
|
+
return describe2("catalog.bundles", facts);
|
|
5492
|
+
case "error":
|
|
5493
|
+
return command.why ? `${command.message}, ${command.why}` : command.message;
|
|
5494
|
+
case "home":
|
|
5495
|
+
case "help":
|
|
5496
|
+
case "version":
|
|
5497
|
+
case "hook":
|
|
5498
|
+
return "";
|
|
5499
|
+
}
|
|
5500
|
+
}
|
|
5501
|
+
|
|
5502
|
+
// src/shell/screens/keys.tsx
|
|
5503
|
+
import { Box as Box11, Text as Text13 } from "ink";
|
|
5504
|
+
import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
5505
|
+
var KEYS = [
|
|
5506
|
+
["^ v", "move the cursor", "move, or scroll"],
|
|
5507
|
+
["enter", "run the highlighted row", "confirm the layer's action"],
|
|
5508
|
+
["tab", "complete the prompt from the row", "switch tab in the browser"],
|
|
5509
|
+
["space", "types into the prompt", "mark a row in a list"],
|
|
5510
|
+
["n", "types into the prompt", "run the next step a report suggests"],
|
|
5511
|
+
["esc", "clear the prompt, then quit", "back one layer"],
|
|
5512
|
+
["x", "types into the prompt", "back, where there is no prompt"],
|
|
5513
|
+
["?", "this", "this"],
|
|
5514
|
+
["ctrl-c", "quit now", "quit now"]
|
|
5515
|
+
];
|
|
5516
|
+
function KeysScreen({ onBack }) {
|
|
5517
|
+
const width = useFrameWidth();
|
|
5518
|
+
const interior = width - FRAME_CHROME;
|
|
5519
|
+
const key = 8;
|
|
5520
|
+
const half = Math.floor((interior - key) / 2);
|
|
5521
|
+
return /* @__PURE__ */ jsxs13(Frame, {
|
|
5522
|
+
title: "keys",
|
|
5523
|
+
width,
|
|
5524
|
+
children: [
|
|
5525
|
+
/* @__PURE__ */ jsxs13(Box11, {
|
|
5526
|
+
flexDirection: "column",
|
|
5527
|
+
children: [
|
|
5528
|
+
/* @__PURE__ */ jsxs13(Text13, {
|
|
5529
|
+
children: [
|
|
5530
|
+
/* @__PURE__ */ jsx14(Text13, {
|
|
5531
|
+
dimColor: true,
|
|
5532
|
+
children: "".padEnd(key)
|
|
5533
|
+
}),
|
|
5534
|
+
/* @__PURE__ */ jsx14(Text13, {
|
|
5535
|
+
dimColor: true,
|
|
5536
|
+
children: "at the prompt".padEnd(half)
|
|
5537
|
+
}),
|
|
5538
|
+
/* @__PURE__ */ jsx14(Text13, {
|
|
5539
|
+
dimColor: true,
|
|
5540
|
+
children: "in a layer"
|
|
5541
|
+
})
|
|
5542
|
+
]
|
|
5543
|
+
}),
|
|
5544
|
+
KEYS.map(([k, root, layer]) => /* @__PURE__ */ jsxs13(Text13, {
|
|
5545
|
+
children: [
|
|
5546
|
+
/* @__PURE__ */ jsx14(Text13, {
|
|
5547
|
+
color: tone.primary,
|
|
5548
|
+
children: k.padEnd(key)
|
|
5549
|
+
}),
|
|
5550
|
+
/* @__PURE__ */ jsx14(Text13, {
|
|
5551
|
+
children: clip(root, half - 2).padEnd(half)
|
|
5552
|
+
}),
|
|
5553
|
+
/* @__PURE__ */ jsx14(Text13, {
|
|
5554
|
+
children: clip(layer, interior - key - half)
|
|
5555
|
+
})
|
|
5556
|
+
]
|
|
5557
|
+
}, k))
|
|
5558
|
+
]
|
|
5559
|
+
}),
|
|
5560
|
+
/* @__PURE__ */ jsx14(Back, {
|
|
5561
|
+
width,
|
|
5562
|
+
onBack
|
|
5563
|
+
})
|
|
5564
|
+
]
|
|
5565
|
+
});
|
|
5566
|
+
}
|
|
5567
|
+
|
|
5568
|
+
// src/shell/screens/picker.tsx
|
|
5569
|
+
import { Box as Box12, Text as Text14, useInput as useInput6 } from "ink";
|
|
5570
|
+
import { useEffect as useEffect8, useMemo as useMemo3, useState as useState9 } from "react";
|
|
5571
|
+
import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
5572
|
+
function PickScreen({
|
|
5573
|
+
title,
|
|
5574
|
+
rows: rows2,
|
|
5575
|
+
empty,
|
|
5576
|
+
verb,
|
|
5577
|
+
onPick,
|
|
5578
|
+
onBack
|
|
5579
|
+
}) {
|
|
5580
|
+
const width = useFrameWidth();
|
|
5581
|
+
const [query, setQuery] = useState9("");
|
|
5582
|
+
const [cursor, setCursor] = useState9(0);
|
|
5583
|
+
const [picked, setPicked] = useState9(new Set);
|
|
5584
|
+
const visible = useMemo3(() => {
|
|
5585
|
+
if (query.length === 0)
|
|
5586
|
+
return rows2;
|
|
5587
|
+
const q = query.toLowerCase();
|
|
5588
|
+
return rows2.filter((row) => row.name.toLowerCase().includes(q) || (row.description ?? "").toLowerCase().includes(q));
|
|
5589
|
+
}, [rows2, query]);
|
|
5590
|
+
useEffect8(() => {
|
|
5591
|
+
setCursor((c) => Math.max(0, Math.min(c, visible.length - 1)));
|
|
5592
|
+
}, [visible.length]);
|
|
5593
|
+
useInput6((input, key) => {
|
|
5594
|
+
if (key.upArrow) {
|
|
5595
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
5596
|
+
} else if (key.downArrow) {
|
|
5597
|
+
setCursor((c) => Math.min(visible.length - 1, c + 1));
|
|
5598
|
+
} else if (key.return) {
|
|
5599
|
+
const names2 = picked.size > 0 ? [...picked] : visible[cursor] ? [visible[cursor].name] : [];
|
|
5600
|
+
if (names2.length > 0)
|
|
5601
|
+
onPick(names2);
|
|
5602
|
+
} else if (key.escape) {
|
|
5603
|
+
if (query.length > 0)
|
|
5604
|
+
setQuery("");
|
|
5605
|
+
else
|
|
5606
|
+
onBack();
|
|
5607
|
+
} else if (key.backspace || key.delete) {
|
|
5608
|
+
setQuery((q) => q.slice(0, -1));
|
|
5609
|
+
setCursor(0);
|
|
5610
|
+
} else if (input === " ") {
|
|
5611
|
+
const row = visible[cursor];
|
|
5612
|
+
if (!row)
|
|
5613
|
+
return;
|
|
5614
|
+
setPicked((current) => {
|
|
5615
|
+
const next = new Set(current);
|
|
5616
|
+
if (next.has(row.name))
|
|
5617
|
+
next.delete(row.name);
|
|
5618
|
+
else
|
|
5619
|
+
next.add(row.name);
|
|
5620
|
+
return next;
|
|
5621
|
+
});
|
|
5622
|
+
} else if (input && !key.ctrl && !key.meta) {
|
|
5623
|
+
setQuery((q) => q + input);
|
|
5624
|
+
setCursor(0);
|
|
5625
|
+
}
|
|
5626
|
+
});
|
|
5627
|
+
const names = nameWidth(rows2);
|
|
5628
|
+
return /* @__PURE__ */ jsx15(Frame, {
|
|
4507
5629
|
title,
|
|
4508
5630
|
width,
|
|
4509
|
-
children:
|
|
5631
|
+
children: /* @__PURE__ */ jsxs14(Box12, {
|
|
4510
5632
|
flexDirection: "column",
|
|
4511
|
-
children:
|
|
4512
|
-
|
|
5633
|
+
children: [
|
|
5634
|
+
/* @__PURE__ */ jsxs14(Box12, {
|
|
5635
|
+
children: [
|
|
5636
|
+
/* @__PURE__ */ jsx15(Text14, {
|
|
5637
|
+
color: tone.primary,
|
|
5638
|
+
children: "> "
|
|
5639
|
+
}),
|
|
5640
|
+
/* @__PURE__ */ jsx15(SearchInput, {
|
|
5641
|
+
value: query,
|
|
5642
|
+
placeholder: "type to filter"
|
|
5643
|
+
})
|
|
5644
|
+
]
|
|
5645
|
+
}),
|
|
5646
|
+
/* @__PURE__ */ jsx15(Divider, {
|
|
5647
|
+
width
|
|
5648
|
+
}),
|
|
5649
|
+
rows2.length === 0 ? /* @__PURE__ */ jsx15(Text14, {
|
|
5650
|
+
dimColor: true,
|
|
5651
|
+
children: empty
|
|
5652
|
+
}) : visible.length === 0 ? /* @__PURE__ */ jsx15(Text14, {
|
|
5653
|
+
dimColor: true,
|
|
5654
|
+
children: `Nothing matches "${query}".`
|
|
5655
|
+
}) : visible.map((row, i) => /* @__PURE__ */ jsx15(SkillRow, {
|
|
5656
|
+
row,
|
|
5657
|
+
width: width - 2,
|
|
5658
|
+
names,
|
|
5659
|
+
selectable: true,
|
|
5660
|
+
cursor: i === cursor,
|
|
5661
|
+
selected: picked.has(row.name)
|
|
5662
|
+
}, row.name)),
|
|
5663
|
+
/* @__PURE__ */ jsx15(Divider, {
|
|
5664
|
+
width
|
|
5665
|
+
}),
|
|
5666
|
+
/* @__PURE__ */ jsxs14(Box12, {
|
|
5667
|
+
children: [
|
|
5668
|
+
picked.size > 0 ? /* @__PURE__ */ jsx15(Text14, {
|
|
5669
|
+
color: tone.notice,
|
|
5670
|
+
children: `${mark.selected} ${picked.size} marked `
|
|
5671
|
+
}) : null,
|
|
5672
|
+
/* @__PURE__ */ jsx15(Hints, {
|
|
5673
|
+
hints: [
|
|
5674
|
+
["^v", "move"],
|
|
5675
|
+
["space", "mark"],
|
|
5676
|
+
["enter", verb],
|
|
5677
|
+
["esc", query ? "clear" : "back"]
|
|
5678
|
+
]
|
|
5679
|
+
})
|
|
5680
|
+
]
|
|
5681
|
+
})
|
|
5682
|
+
]
|
|
5683
|
+
})
|
|
5684
|
+
});
|
|
5685
|
+
}
|
|
5686
|
+
|
|
5687
|
+
// src/shell/screens/welcome.tsx
|
|
5688
|
+
import { Box as Box13, Text as Text15, useInput as useInput7 } from "ink";
|
|
5689
|
+
import { useState as useState10 } from "react";
|
|
5690
|
+
import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
5691
|
+
function WelcomeScreen({
|
|
5692
|
+
agents: agents2,
|
|
5693
|
+
onStart,
|
|
5694
|
+
onSkip
|
|
5695
|
+
}) {
|
|
5696
|
+
const width = useFrameWidth();
|
|
5697
|
+
const interior = width - FRAME_CHROME;
|
|
5698
|
+
const [choice, setChoice] = useState10("start");
|
|
5699
|
+
useInput7((_input, key) => {
|
|
5700
|
+
if (key.upArrow || key.downArrow) {
|
|
5701
|
+
setChoice((c) => c === "start" ? "skip" : "start");
|
|
5702
|
+
} else if (key.return) {
|
|
5703
|
+
if (choice === "start")
|
|
5704
|
+
onStart();
|
|
5705
|
+
else
|
|
5706
|
+
onSkip();
|
|
5707
|
+
} else if (key.escape) {
|
|
5708
|
+
onSkip();
|
|
5709
|
+
}
|
|
5710
|
+
});
|
|
5711
|
+
const found = agents2.length > 0 ? `found on this machine: ${agents2.join(", ")}` : "none found yet; the catalog will ask";
|
|
5712
|
+
const steps = [
|
|
5713
|
+
["1", "sign in", "a code you enter in your browser"],
|
|
5714
|
+
["2", "pick your tools", found],
|
|
5715
|
+
["3", "get skills", "the bundle your team uses"]
|
|
5716
|
+
];
|
|
5717
|
+
const row = (label, hint, active) => {
|
|
5718
|
+
const gap = Math.max(interior - 2 - label.length - hint.length, 1);
|
|
5719
|
+
return /* @__PURE__ */ jsxs15(Text15, {
|
|
5720
|
+
children: [
|
|
5721
|
+
/* @__PURE__ */ jsx16(Text15, {
|
|
5722
|
+
color: tone.primary,
|
|
5723
|
+
children: `${active ? mark.cursor : " "} `
|
|
5724
|
+
}),
|
|
5725
|
+
/* @__PURE__ */ jsx16(Text15, {
|
|
5726
|
+
bold: active,
|
|
5727
|
+
color: active ? tone.primary : undefined,
|
|
5728
|
+
children: label
|
|
5729
|
+
}),
|
|
5730
|
+
/* @__PURE__ */ jsx16(Text15, {
|
|
5731
|
+
dimColor: true,
|
|
5732
|
+
children: `${" ".repeat(gap)}${hint}`
|
|
5733
|
+
})
|
|
5734
|
+
]
|
|
5735
|
+
});
|
|
5736
|
+
};
|
|
5737
|
+
return /* @__PURE__ */ jsxs15(Frame, {
|
|
5738
|
+
title: "yourskills",
|
|
5739
|
+
width,
|
|
5740
|
+
children: [
|
|
5741
|
+
/* @__PURE__ */ jsxs15(Box13, {
|
|
5742
|
+
flexDirection: "column",
|
|
5743
|
+
children: [
|
|
5744
|
+
/* @__PURE__ */ jsx16(Text15, {
|
|
5745
|
+
children: "Welcome. Three steps, about a minute."
|
|
5746
|
+
}),
|
|
5747
|
+
/* @__PURE__ */ jsx16(Blank, {}),
|
|
5748
|
+
steps.map(([n, what, how]) => /* @__PURE__ */ jsxs15(Text15, {
|
|
5749
|
+
children: [
|
|
5750
|
+
/* @__PURE__ */ jsx16(Text15, {
|
|
5751
|
+
color: tone.primary,
|
|
5752
|
+
children: `${n} `
|
|
5753
|
+
}),
|
|
5754
|
+
/* @__PURE__ */ jsx16(Text15, {
|
|
5755
|
+
children: what.padEnd(16)
|
|
5756
|
+
}),
|
|
5757
|
+
/* @__PURE__ */ jsx16(Text15, {
|
|
5758
|
+
dimColor: true,
|
|
5759
|
+
children: clip(how, interior - 19)
|
|
5760
|
+
})
|
|
5761
|
+
]
|
|
5762
|
+
}, n)),
|
|
5763
|
+
/* @__PURE__ */ jsx16(Blank, {}),
|
|
5764
|
+
row("start", "", choice === "start"),
|
|
5765
|
+
row("skip, I know what I am doing", "yourskills login", choice === "skip")
|
|
5766
|
+
]
|
|
5767
|
+
}),
|
|
5768
|
+
/* @__PURE__ */ jsx16(Divider, {
|
|
4513
5769
|
width
|
|
4514
|
-
},
|
|
4515
|
-
|
|
4516
|
-
|
|
4517
|
-
|
|
4518
|
-
|
|
4519
|
-
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
]
|
|
4523
|
-
})
|
|
5770
|
+
}),
|
|
5771
|
+
/* @__PURE__ */ jsx16(Hints, {
|
|
5772
|
+
hints: [
|
|
5773
|
+
["enter", choice === "start" ? "start" : "skip"],
|
|
5774
|
+
["esc", "skip"]
|
|
5775
|
+
]
|
|
5776
|
+
})
|
|
5777
|
+
]
|
|
4524
5778
|
});
|
|
4525
5779
|
}
|
|
4526
5780
|
|
|
4527
5781
|
// src/shell/screens/home.tsx
|
|
4528
|
-
import { jsx as
|
|
5782
|
+
import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4529
5783
|
function failure(title, error) {
|
|
4530
5784
|
const message = error instanceof Error ? error.message : String(error);
|
|
4531
5785
|
return {
|
|
@@ -4549,23 +5803,88 @@ function identityReport(who) {
|
|
|
4549
5803
|
json: { ...who }
|
|
4550
5804
|
};
|
|
4551
5805
|
}
|
|
5806
|
+
function hostOf(server) {
|
|
5807
|
+
try {
|
|
5808
|
+
return new URL(server).host;
|
|
5809
|
+
} catch {
|
|
5810
|
+
return server;
|
|
5811
|
+
}
|
|
5812
|
+
}
|
|
5813
|
+
function removeArgv(names, opts) {
|
|
5814
|
+
return `yourskills remove ${names.join(" ")}${opts.scope === "project" ? " --project" : ""}`;
|
|
5815
|
+
}
|
|
5816
|
+
function AccountLine({ facts, width }) {
|
|
5817
|
+
const right = `${facts.scope} ${facts.skills} installed`;
|
|
5818
|
+
const head = facts.signedIn ? facts.email ?? "signed in" : "not signed in";
|
|
5819
|
+
const room = Math.max(width - FRAME_CHROME - right.length - 2, 12);
|
|
5820
|
+
const tail = facts.signedIn ? ` ${hostOf(facts.server)}` : " — the catalog needs a session";
|
|
5821
|
+
const spare = room - 2 - head.length;
|
|
5822
|
+
return /* @__PURE__ */ jsxs16(Box14, {
|
|
5823
|
+
width: width - FRAME_CHROME,
|
|
5824
|
+
justifyContent: "space-between",
|
|
5825
|
+
children: [
|
|
5826
|
+
/* @__PURE__ */ jsxs16(Text16, {
|
|
5827
|
+
children: [
|
|
5828
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
5829
|
+
color: facts.signedIn ? "green" : tone.notice,
|
|
5830
|
+
children: facts.signedIn ? mark.ok : mark.fail
|
|
5831
|
+
}),
|
|
5832
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
5833
|
+
color: facts.signedIn ? undefined : tone.notice,
|
|
5834
|
+
children: ` ${clip(head, room - 2)}`
|
|
5835
|
+
}),
|
|
5836
|
+
spare >= tail.length ? /* @__PURE__ */ jsx17(Text16, {
|
|
5837
|
+
dimColor: true,
|
|
5838
|
+
children: tail
|
|
5839
|
+
}) : null
|
|
5840
|
+
]
|
|
5841
|
+
}),
|
|
5842
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
5843
|
+
dimColor: true,
|
|
5844
|
+
children: right
|
|
5845
|
+
})
|
|
5846
|
+
]
|
|
5847
|
+
});
|
|
5848
|
+
}
|
|
5849
|
+
var RUN = "run";
|
|
4552
5850
|
function HomeScreen({
|
|
4553
5851
|
opts,
|
|
5852
|
+
facts: initial,
|
|
5853
|
+
reload,
|
|
4554
5854
|
server,
|
|
4555
5855
|
openClient,
|
|
4556
5856
|
onError,
|
|
4557
|
-
onSummary
|
|
5857
|
+
onSummary,
|
|
5858
|
+
onWelcomed = async () => {
|
|
5859
|
+
return;
|
|
5860
|
+
}
|
|
4558
5861
|
}) {
|
|
4559
5862
|
const { exit } = useApp7();
|
|
4560
5863
|
const width = useFrameWidth();
|
|
4561
|
-
const
|
|
4562
|
-
const
|
|
4563
|
-
const [
|
|
4564
|
-
const [
|
|
4565
|
-
const [
|
|
4566
|
-
const [
|
|
4567
|
-
const
|
|
4568
|
-
|
|
5864
|
+
const [facts, setFacts] = useState11(initial);
|
|
5865
|
+
const groups = useMemo4(() => paletteGroups(facts), [facts]);
|
|
5866
|
+
const [query, setQuery] = useState11("");
|
|
5867
|
+
const [cursor, setCursor] = useState11(0);
|
|
5868
|
+
const [route, setRoute] = useState11(null);
|
|
5869
|
+
const [client, setClient] = useState11(null);
|
|
5870
|
+
const [refused, setRefused] = useState11(null);
|
|
5871
|
+
const [welcome, setWelcome] = useState11(initial.firstRun);
|
|
5872
|
+
const [wizard, setWizard] = useState11(false);
|
|
5873
|
+
const typed = useMemo4(() => typedCommand(query), [query]);
|
|
5874
|
+
const visible = useMemo4(() => {
|
|
5875
|
+
const filtered = filterCommands(groups, query);
|
|
5876
|
+
if (!runnable(typed))
|
|
5877
|
+
return filtered;
|
|
5878
|
+
return [
|
|
5879
|
+
{
|
|
5880
|
+
group: "Run",
|
|
5881
|
+
items: [{ value: RUN, label: typed.text, hint: "enter to run" }]
|
|
5882
|
+
},
|
|
5883
|
+
...filtered
|
|
5884
|
+
];
|
|
5885
|
+
}, [groups, query, typed]);
|
|
5886
|
+
const rows2 = useMemo4(() => flattenCommands(visible), [visible]);
|
|
5887
|
+
useEffect9(() => {
|
|
4569
5888
|
setCursor((c) => Math.max(0, Math.min(c, rows2.length - 1)));
|
|
4570
5889
|
}, [rows2.length]);
|
|
4571
5890
|
const held = useRef(null);
|
|
@@ -4573,9 +5892,10 @@ function HomeScreen({
|
|
|
4573
5892
|
held.current ??= await openClient();
|
|
4574
5893
|
return held.current;
|
|
4575
5894
|
}, [openClient]);
|
|
4576
|
-
const answering = useCallback3((title, load) => ({
|
|
5895
|
+
const answering = useCallback3((title, working, load) => ({
|
|
4577
5896
|
kind: "report",
|
|
4578
5897
|
title,
|
|
5898
|
+
working,
|
|
4579
5899
|
load: async () => {
|
|
4580
5900
|
try {
|
|
4581
5901
|
return await load();
|
|
@@ -4584,77 +5904,239 @@ function HomeScreen({
|
|
|
4584
5904
|
}
|
|
4585
5905
|
}
|
|
4586
5906
|
}), []);
|
|
4587
|
-
const
|
|
4588
|
-
|
|
4589
|
-
|
|
4590
|
-
|
|
4591
|
-
|
|
5907
|
+
const signOut = useCallback3(async () => {
|
|
5908
|
+
await logout();
|
|
5909
|
+
held.current = null;
|
|
5910
|
+
setClient(null);
|
|
5911
|
+
return {
|
|
5912
|
+
title: "logout",
|
|
5913
|
+
lines: [{ mark: "ok", text: "Logged out." }],
|
|
5914
|
+
json: { ok: true }
|
|
5915
|
+
};
|
|
5916
|
+
}, []);
|
|
5917
|
+
const routeForCommand = useCallback3(async (command) => {
|
|
5918
|
+
const plan = describeCommand(command, facts);
|
|
5919
|
+
switch (command.kind) {
|
|
5920
|
+
case "login":
|
|
5921
|
+
return { kind: "login" };
|
|
5922
|
+
case "browse":
|
|
4592
5923
|
return { kind: "browse" };
|
|
4593
|
-
case "
|
|
4594
|
-
return
|
|
4595
|
-
case "
|
|
5924
|
+
case "list":
|
|
5925
|
+
return { kind: "browse", tab: "skills" };
|
|
5926
|
+
case "search":
|
|
5927
|
+
return { kind: "browse", tab: "skills", query: command.query };
|
|
5928
|
+
case "add": {
|
|
5929
|
+
const resolved = await resolveInstallOptions(command.opts);
|
|
4596
5930
|
return {
|
|
4597
5931
|
kind: "install",
|
|
4598
|
-
title: "
|
|
5932
|
+
title: "add",
|
|
5933
|
+
plan,
|
|
4599
5934
|
stream: async function* stream() {
|
|
4600
|
-
|
|
4601
|
-
yield* updateTracked(await connect(), nearest.manifest, opts, true);
|
|
5935
|
+
yield* install(await connect(), command.names, resolved);
|
|
4602
5936
|
}
|
|
4603
5937
|
};
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
return
|
|
4608
|
-
|
|
5938
|
+
}
|
|
5939
|
+
case "bundle": {
|
|
5940
|
+
const resolved = await resolveInstallOptions(command.opts);
|
|
5941
|
+
return {
|
|
5942
|
+
kind: "install",
|
|
5943
|
+
title: `bundle: ${command.name}`,
|
|
5944
|
+
plan,
|
|
5945
|
+
stream: async function* stream() {
|
|
5946
|
+
yield* installBundle(await connect(), command.name, resolved);
|
|
5947
|
+
}
|
|
5948
|
+
};
|
|
5949
|
+
}
|
|
5950
|
+
case "install": {
|
|
5951
|
+
const resolved = await resolveInstallOptions(command.opts);
|
|
5952
|
+
const nearest = await nearestManifest(resolved.scope);
|
|
5953
|
+
const empty2 = nothingTracked(nearest, "install");
|
|
5954
|
+
if (empty2)
|
|
5955
|
+
return answering("install", plan, async () => empty2);
|
|
5956
|
+
return {
|
|
5957
|
+
kind: "install",
|
|
5958
|
+
title: "install",
|
|
5959
|
+
plan,
|
|
5960
|
+
stream: () => reinstall(nearest.manifest, resolved)
|
|
5961
|
+
};
|
|
5962
|
+
}
|
|
5963
|
+
case "update": {
|
|
5964
|
+
const resolved = await resolveInstallOptions(command.opts);
|
|
5965
|
+
if (command.bundle) {
|
|
5966
|
+
const name = command.bundle;
|
|
4609
5967
|
return {
|
|
4610
|
-
|
|
4611
|
-
title:
|
|
4612
|
-
|
|
4613
|
-
|
|
4614
|
-
|
|
4615
|
-
|
|
4616
|
-
},
|
|
4617
|
-
...report.lines
|
|
4618
|
-
]
|
|
5968
|
+
kind: "install",
|
|
5969
|
+
title: `update: ${name}`,
|
|
5970
|
+
plan,
|
|
5971
|
+
stream: async function* stream() {
|
|
5972
|
+
yield* update(await connect(), name, resolved);
|
|
5973
|
+
}
|
|
4619
5974
|
};
|
|
4620
|
-
}
|
|
5975
|
+
}
|
|
5976
|
+
const nearest = await nearestManifest(resolved.scope);
|
|
5977
|
+
const all = command.all ?? false;
|
|
5978
|
+
const empty2 = nothingTracked(nearest, "update", all);
|
|
5979
|
+
if (empty2)
|
|
5980
|
+
return answering("update", plan, async () => empty2);
|
|
5981
|
+
return {
|
|
5982
|
+
kind: "install",
|
|
5983
|
+
title: "update",
|
|
5984
|
+
plan,
|
|
5985
|
+
stream: async function* stream() {
|
|
5986
|
+
yield* updateTracked(await connect(), nearest.manifest, resolved, all);
|
|
5987
|
+
}
|
|
5988
|
+
};
|
|
5989
|
+
}
|
|
5990
|
+
case "remove": {
|
|
5991
|
+
const resolved = await resolveInstallOptions(command.opts);
|
|
5992
|
+
return {
|
|
5993
|
+
kind: "confirm",
|
|
5994
|
+
names: command.names,
|
|
5995
|
+
nearest: await nearestManifest(resolved.scope),
|
|
5996
|
+
opts: resolved
|
|
5997
|
+
};
|
|
5998
|
+
}
|
|
5999
|
+
case "installed":
|
|
6000
|
+
return answering("installed", plan, async () => installedReport(await nearestManifest(opts.scope)));
|
|
6001
|
+
case "outdated":
|
|
6002
|
+
return answering("outdated", plan, async () => outdatedReport(await connect(), await nearestManifest(opts.scope)));
|
|
6003
|
+
case "doctor":
|
|
6004
|
+
return answering("doctor", plan, async () => doctorReport(await nearestManifest(opts.scope), server));
|
|
6005
|
+
case "org":
|
|
6006
|
+
return answering("org", plan, () => command.name ? orgSwitchReport(command.name, server) : orgListReport(server));
|
|
6007
|
+
case "config":
|
|
6008
|
+
return answering("config", plan, () => command.action === "get" ? configGet(command.key) : configSet(command.key, command.value));
|
|
6009
|
+
case "whoami":
|
|
6010
|
+
return answering("whoami", plan, async () => identityReport(await whoami(server)));
|
|
6011
|
+
case "logout":
|
|
6012
|
+
return answering("logout", plan, signOut);
|
|
6013
|
+
case "hooks":
|
|
6014
|
+
return answering("hooks", plan, () => command.action === "install" ? hooksInstall({
|
|
6015
|
+
...command.agent ? { agent: command.agent } : {},
|
|
6016
|
+
...command.track === undefined ? {} : { track: command.track }
|
|
6017
|
+
}) : command.action === "uninstall" ? hooksUninstall(command.agent ? { agent: command.agent } : {}) : hooksStatus());
|
|
6018
|
+
case "error":
|
|
6019
|
+
case "home":
|
|
6020
|
+
case "help":
|
|
6021
|
+
case "version":
|
|
6022
|
+
case "hook":
|
|
6023
|
+
return null;
|
|
6024
|
+
}
|
|
6025
|
+
}, [answering, connect, facts, opts, server, signOut]);
|
|
6026
|
+
const routeFor = useCallback3(async (value) => {
|
|
6027
|
+
switch (value) {
|
|
6028
|
+
case "catalog.bundles":
|
|
6029
|
+
return { kind: "browse" };
|
|
6030
|
+
case "catalog.skills":
|
|
6031
|
+
case "catalog.search":
|
|
6032
|
+
return { kind: "browse", tab: "skills" };
|
|
6033
|
+
case "installed.list":
|
|
6034
|
+
return routeForCommand({ kind: "installed" });
|
|
6035
|
+
case "installed.update":
|
|
6036
|
+
return routeForCommand({ kind: "update", all: true, opts: {} });
|
|
6037
|
+
case "installed.outdated":
|
|
6038
|
+
return routeForCommand({ kind: "outdated" });
|
|
6039
|
+
case "installed.remove": {
|
|
6040
|
+
const nearest = await nearestManifest(opts.scope);
|
|
6041
|
+
return {
|
|
6042
|
+
kind: "pick",
|
|
6043
|
+
rows: installedRows(nearest).map((row) => ({
|
|
6044
|
+
name: row.name,
|
|
6045
|
+
description: `${row.bundle ?? "loose"} ${shortRef(row.ref)}`
|
|
6046
|
+
}))
|
|
6047
|
+
};
|
|
6048
|
+
}
|
|
4621
6049
|
case "account.login":
|
|
4622
6050
|
return { kind: "login" };
|
|
4623
6051
|
case "account.logout":
|
|
4624
|
-
return
|
|
4625
|
-
await logout();
|
|
4626
|
-
held.current = null;
|
|
4627
|
-
setClient(null);
|
|
4628
|
-
return {
|
|
4629
|
-
title: "logout",
|
|
4630
|
-
lines: [{ mark: "ok", text: "Logged out." }],
|
|
4631
|
-
json: { ok: true }
|
|
4632
|
-
};
|
|
4633
|
-
});
|
|
6052
|
+
return routeForCommand({ kind: "logout" });
|
|
4634
6053
|
case "account.whoami":
|
|
4635
|
-
return
|
|
6054
|
+
return routeForCommand({ kind: "whoami" });
|
|
4636
6055
|
case "account.org":
|
|
4637
|
-
return
|
|
6056
|
+
return routeForCommand({ kind: "org" });
|
|
4638
6057
|
case "setup.scope":
|
|
4639
|
-
return
|
|
6058
|
+
return routeForCommand({
|
|
6059
|
+
kind: "config",
|
|
6060
|
+
action: "get",
|
|
6061
|
+
key: "scope"
|
|
6062
|
+
});
|
|
4640
6063
|
case "setup.agents":
|
|
4641
|
-
return
|
|
6064
|
+
return routeForCommand({
|
|
6065
|
+
kind: "config",
|
|
6066
|
+
action: "get",
|
|
6067
|
+
key: "agents"
|
|
6068
|
+
});
|
|
4642
6069
|
case "setup.doctor":
|
|
4643
|
-
return
|
|
6070
|
+
return routeForCommand({ kind: "doctor" });
|
|
4644
6071
|
}
|
|
4645
|
-
}, [
|
|
6072
|
+
}, [opts.scope, routeForCommand]);
|
|
6073
|
+
const open = useCallback3((pending, title) => {
|
|
6074
|
+
pending.then((next) => {
|
|
6075
|
+
if (next)
|
|
6076
|
+
setRoute(next);
|
|
6077
|
+
}).catch((error) => {
|
|
6078
|
+
setRoute(answering(title, "", async () => failure(title, error)));
|
|
6079
|
+
});
|
|
6080
|
+
}, [answering]);
|
|
6081
|
+
const runText = useCallback3((text) => {
|
|
6082
|
+
const parsed = typedCommand(text);
|
|
6083
|
+
if (!runnable(parsed))
|
|
6084
|
+
return;
|
|
6085
|
+
open(routeForCommand(parsed.command), parsed.text);
|
|
6086
|
+
}, [open, routeForCommand]);
|
|
6087
|
+
const current = rows2[cursor];
|
|
4646
6088
|
const activate = useCallback3(() => {
|
|
4647
6089
|
const item = rows2[cursor];
|
|
4648
6090
|
if (!item)
|
|
4649
6091
|
return;
|
|
4650
6092
|
item.onSelect?.();
|
|
4651
|
-
|
|
4652
|
-
|
|
6093
|
+
if (item.value === RUN) {
|
|
6094
|
+
if (runnable(typed))
|
|
6095
|
+
open(routeForCommand(typed.command), typed.text);
|
|
6096
|
+
return;
|
|
6097
|
+
}
|
|
6098
|
+
open(routeFor(item.value), item.label);
|
|
6099
|
+
}, [rows2, cursor, typed, open, routeFor, routeForCommand]);
|
|
6100
|
+
const complete = useCallback3(() => {
|
|
6101
|
+
const item = rows2[cursor]?.value === RUN ? rows2[cursor + 1] : rows2[cursor];
|
|
6102
|
+
if (!item?.hint)
|
|
6103
|
+
return;
|
|
6104
|
+
const bare = item.hint.replace(/<[^>]+>/g, "").trimEnd();
|
|
6105
|
+
setQuery(item.hint.includes("<") ? `${bare} ` : bare);
|
|
6106
|
+
setCursor(0);
|
|
6107
|
+
}, [rows2, cursor]);
|
|
4653
6108
|
const back = useCallback3(() => {
|
|
4654
6109
|
setRoute(null);
|
|
4655
6110
|
setRefused(null);
|
|
4656
|
-
|
|
4657
|
-
|
|
6111
|
+
setQuery("");
|
|
6112
|
+
setCursor(0);
|
|
6113
|
+
reload().then(setFacts).catch(() => {
|
|
6114
|
+
return;
|
|
6115
|
+
});
|
|
6116
|
+
}, [reload]);
|
|
6117
|
+
const afterLogin = useCallback3(() => {
|
|
6118
|
+
if (!wizard) {
|
|
6119
|
+
back();
|
|
6120
|
+
return;
|
|
6121
|
+
}
|
|
6122
|
+
setWizard(false);
|
|
6123
|
+
setRefused(null);
|
|
6124
|
+
reload().then((next) => {
|
|
6125
|
+
setFacts(next);
|
|
6126
|
+
setRoute({ kind: "browse" });
|
|
6127
|
+
}).catch(() => setRoute(null));
|
|
6128
|
+
}, [wizard, back, reload]);
|
|
6129
|
+
const leaveWelcome = useCallback3((start) => {
|
|
6130
|
+
setWelcome(false);
|
|
6131
|
+
onWelcomed().catch(() => {
|
|
6132
|
+
return;
|
|
6133
|
+
});
|
|
6134
|
+
if (start) {
|
|
6135
|
+
setWizard(true);
|
|
6136
|
+
setRoute({ kind: "login" });
|
|
6137
|
+
}
|
|
6138
|
+
}, [onWelcomed]);
|
|
6139
|
+
useEffect9(() => {
|
|
4658
6140
|
if (route?.kind !== "browse" || client || refused)
|
|
4659
6141
|
return;
|
|
4660
6142
|
let live = true;
|
|
@@ -4669,14 +6151,15 @@ function HomeScreen({
|
|
|
4669
6151
|
live = false;
|
|
4670
6152
|
};
|
|
4671
6153
|
}, [route, client, refused, connect]);
|
|
4672
|
-
|
|
4673
|
-
useInput3((input, key) => {
|
|
6154
|
+
useInput8((input, key) => {
|
|
4674
6155
|
if (key.upArrow) {
|
|
4675
6156
|
setCursor((c) => Math.max(0, c - 1));
|
|
4676
6157
|
} else if (key.downArrow) {
|
|
4677
6158
|
setCursor((c) => Math.min(rows2.length - 1, c + 1));
|
|
4678
6159
|
} else if (key.return) {
|
|
4679
6160
|
activate();
|
|
6161
|
+
} else if (key.tab) {
|
|
6162
|
+
complete();
|
|
4680
6163
|
} else if (key.escape) {
|
|
4681
6164
|
if (query.length > 0)
|
|
4682
6165
|
setQuery("");
|
|
@@ -4685,104 +6168,192 @@ function HomeScreen({
|
|
|
4685
6168
|
} else if (key.backspace || key.delete) {
|
|
4686
6169
|
setQuery((q) => q.slice(0, -1));
|
|
4687
6170
|
setCursor(0);
|
|
6171
|
+
} else if (input === "?" && query.length === 0) {
|
|
6172
|
+
setRoute({ kind: "keys" });
|
|
4688
6173
|
} else if (input && !key.ctrl && !key.meta) {
|
|
4689
6174
|
setQuery((q) => q + input);
|
|
4690
6175
|
setCursor(0);
|
|
4691
6176
|
}
|
|
4692
|
-
}, { isActive: route === null });
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
6177
|
+
}, { isActive: route === null && !welcome });
|
|
6178
|
+
if (welcome) {
|
|
6179
|
+
return /* @__PURE__ */ jsx17(WelcomeScreen, {
|
|
6180
|
+
agents: facts.agentsOnDisk,
|
|
6181
|
+
onStart: () => leaveWelcome(true),
|
|
6182
|
+
onSkip: () => leaveWelcome(false)
|
|
6183
|
+
});
|
|
6184
|
+
}
|
|
4697
6185
|
if (route?.kind === "login") {
|
|
4698
|
-
return /* @__PURE__ */
|
|
6186
|
+
return /* @__PURE__ */ jsx17(LoginScreen, {
|
|
4699
6187
|
onError,
|
|
4700
|
-
onDone:
|
|
6188
|
+
onDone: afterLogin,
|
|
6189
|
+
onBack: back
|
|
6190
|
+
});
|
|
6191
|
+
}
|
|
6192
|
+
if (route?.kind === "keys") {
|
|
6193
|
+
return /* @__PURE__ */ jsx17(KeysScreen, {
|
|
6194
|
+
onBack: back
|
|
4701
6195
|
});
|
|
4702
6196
|
}
|
|
4703
6197
|
if (route?.kind === "report") {
|
|
4704
|
-
return /* @__PURE__ */
|
|
6198
|
+
return /* @__PURE__ */ jsx17(ReportScreen, {
|
|
4705
6199
|
title: route.title,
|
|
4706
6200
|
load: route.load,
|
|
6201
|
+
working: route.working,
|
|
4707
6202
|
onError,
|
|
4708
|
-
exitWhenDone: false
|
|
6203
|
+
exitWhenDone: false,
|
|
6204
|
+
onBack: back,
|
|
6205
|
+
onNext: runText
|
|
4709
6206
|
});
|
|
4710
6207
|
}
|
|
4711
6208
|
if (route?.kind === "install") {
|
|
4712
|
-
return /* @__PURE__ */
|
|
6209
|
+
return /* @__PURE__ */ jsx17(Installer, {
|
|
4713
6210
|
title: route.title,
|
|
4714
6211
|
stream: route.stream,
|
|
6212
|
+
plan: route.plan,
|
|
4715
6213
|
exitWhenDone: false,
|
|
4716
|
-
onDone: onSummary
|
|
6214
|
+
onDone: onSummary,
|
|
6215
|
+
onBack: back
|
|
6216
|
+
});
|
|
6217
|
+
}
|
|
6218
|
+
if (route?.kind === "pick") {
|
|
6219
|
+
return /* @__PURE__ */ jsx17(PickScreen, {
|
|
6220
|
+
title: "remove",
|
|
6221
|
+
rows: route.rows,
|
|
6222
|
+
empty: "Nothing installed here.",
|
|
6223
|
+
verb: "remove",
|
|
6224
|
+
onPick: (names) => {
|
|
6225
|
+
open(routeForCommand({ kind: "remove", names, opts: {} }), "remove");
|
|
6226
|
+
},
|
|
6227
|
+
onBack: back
|
|
6228
|
+
});
|
|
6229
|
+
}
|
|
6230
|
+
if (route?.kind === "confirm") {
|
|
6231
|
+
const { names, nearest, opts: resolved } = route;
|
|
6232
|
+
const lines = names.map((name) => {
|
|
6233
|
+
const entry = nearest.manifest.skills[name];
|
|
6234
|
+
return entry ? {
|
|
6235
|
+
mark: "fail",
|
|
6236
|
+
text: name,
|
|
6237
|
+
note: entry.agents.length > 0 ? entry.agents.join(", ") : ""
|
|
6238
|
+
} : {
|
|
6239
|
+
mark: "none",
|
|
6240
|
+
text: name,
|
|
6241
|
+
note: "not installed here, nothing to delete"
|
|
6242
|
+
};
|
|
6243
|
+
});
|
|
6244
|
+
const known = names.filter((name) => nearest.manifest.skills[name]);
|
|
6245
|
+
return /* @__PURE__ */ jsx17(ConfirmScreen, {
|
|
6246
|
+
title: "remove",
|
|
6247
|
+
headline: `You are about to delete ${known.length === 1 ? "1 skill" : `${known.length} skills`}`,
|
|
6248
|
+
lines,
|
|
6249
|
+
notes: [
|
|
6250
|
+
`The list of what is installed is updated too: ${nearest.path}`,
|
|
6251
|
+
`Nothing on ${hostOf(facts.server)} changes.`
|
|
6252
|
+
],
|
|
6253
|
+
yes: "delete them",
|
|
6254
|
+
no: "keep them",
|
|
6255
|
+
argv: removeArgv(names, resolved),
|
|
6256
|
+
onYes: () => setRoute(answering("remove", describeCommand({ kind: "remove", names, opts: resolved }, facts), () => removeSkills(names, nearest.manifest, nearest.path, resolved))),
|
|
6257
|
+
onNo: back
|
|
4717
6258
|
});
|
|
4718
6259
|
}
|
|
4719
6260
|
if (route?.kind === "browse") {
|
|
4720
6261
|
if (refused) {
|
|
4721
|
-
return /* @__PURE__ */
|
|
6262
|
+
return /* @__PURE__ */ jsxs16(Frame, {
|
|
4722
6263
|
title: "browse",
|
|
4723
6264
|
width,
|
|
4724
|
-
children:
|
|
4725
|
-
|
|
4726
|
-
|
|
4727
|
-
|
|
4728
|
-
|
|
4729
|
-
|
|
4730
|
-
|
|
4731
|
-
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
6265
|
+
children: [
|
|
6266
|
+
/* @__PURE__ */ jsxs16(Box14, {
|
|
6267
|
+
flexDirection: "column",
|
|
6268
|
+
children: [
|
|
6269
|
+
/* @__PURE__ */ jsxs16(Text16, {
|
|
6270
|
+
children: [
|
|
6271
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
6272
|
+
color: tone.danger,
|
|
6273
|
+
children: mark.fail
|
|
6274
|
+
}),
|
|
6275
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
6276
|
+
children: ` ${refused}`
|
|
6277
|
+
})
|
|
6278
|
+
]
|
|
6279
|
+
}),
|
|
6280
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
6281
|
+
dimColor: true,
|
|
6282
|
+
children: "Pick `login` from the palette, then try again."
|
|
6283
|
+
})
|
|
6284
|
+
]
|
|
6285
|
+
}),
|
|
6286
|
+
/* @__PURE__ */ jsx17(Back, {
|
|
6287
|
+
width,
|
|
6288
|
+
onBack: back
|
|
6289
|
+
})
|
|
6290
|
+
]
|
|
4744
6291
|
});
|
|
4745
6292
|
}
|
|
4746
6293
|
if (!client) {
|
|
4747
|
-
return /* @__PURE__ */
|
|
6294
|
+
return /* @__PURE__ */ jsxs16(Frame, {
|
|
4748
6295
|
title: "browse",
|
|
4749
6296
|
width,
|
|
4750
|
-
children:
|
|
4751
|
-
|
|
4752
|
-
|
|
4753
|
-
|
|
4754
|
-
|
|
4755
|
-
|
|
4756
|
-
|
|
4757
|
-
|
|
4758
|
-
|
|
6297
|
+
children: [
|
|
6298
|
+
/* @__PURE__ */ jsxs16(Text16, {
|
|
6299
|
+
children: [
|
|
6300
|
+
/* @__PURE__ */ jsx17(Spinner, {}),
|
|
6301
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
6302
|
+
dimColor: true,
|
|
6303
|
+
children: " Connecting..."
|
|
6304
|
+
})
|
|
6305
|
+
]
|
|
6306
|
+
}),
|
|
6307
|
+
/* @__PURE__ */ jsx17(Back, {
|
|
6308
|
+
width,
|
|
6309
|
+
onBack: back
|
|
6310
|
+
})
|
|
6311
|
+
]
|
|
4759
6312
|
});
|
|
4760
6313
|
}
|
|
4761
|
-
return /* @__PURE__ */
|
|
6314
|
+
return /* @__PURE__ */ jsx17(BrowserScreen, {
|
|
4762
6315
|
client,
|
|
4763
6316
|
opts,
|
|
4764
6317
|
onError,
|
|
4765
6318
|
onSummary,
|
|
4766
|
-
onExit: back
|
|
6319
|
+
onExit: back,
|
|
6320
|
+
...route.tab ? { initialTab: route.tab } : {},
|
|
6321
|
+
...route.query ? { initialQuery: route.query } : {}
|
|
4767
6322
|
});
|
|
4768
6323
|
}
|
|
4769
|
-
|
|
6324
|
+
const description = current?.value === RUN && runnable(typed) ? describeCommand(typed.command, facts) : current ? describe2(current.value, facts) : typed ? describeCommand(typed.command, facts) : "";
|
|
6325
|
+
const empty = typed?.command.kind === "error" && typed.command.next ? `${mark.fail} ${typed.command.message} try: ${typed.command.next.replace(/^yourskills /, "")}` : "No matching commands.";
|
|
6326
|
+
return /* @__PURE__ */ jsxs16(Frame, {
|
|
4770
6327
|
title: "yourskills",
|
|
4771
6328
|
width,
|
|
4772
6329
|
children: [
|
|
4773
|
-
/* @__PURE__ */
|
|
4774
|
-
|
|
6330
|
+
/* @__PURE__ */ jsx17(AccountLine, {
|
|
6331
|
+
facts,
|
|
6332
|
+
width
|
|
6333
|
+
}),
|
|
6334
|
+
/* @__PURE__ */ jsx17(Divider, {
|
|
6335
|
+
width
|
|
6336
|
+
}),
|
|
6337
|
+
/* @__PURE__ */ jsx17(CommandPalette, {
|
|
6338
|
+
groups: visible,
|
|
4775
6339
|
query,
|
|
4776
6340
|
cursor,
|
|
4777
|
-
width
|
|
6341
|
+
width,
|
|
6342
|
+
emptyMessage: empty
|
|
4778
6343
|
}),
|
|
4779
|
-
/* @__PURE__ */
|
|
6344
|
+
/* @__PURE__ */ jsx17(Divider, {
|
|
4780
6345
|
width
|
|
4781
6346
|
}),
|
|
4782
|
-
/* @__PURE__ */
|
|
6347
|
+
/* @__PURE__ */ jsx17(Text16, {
|
|
6348
|
+
dimColor: true,
|
|
6349
|
+
children: clip(description, width - FRAME_CHROME)
|
|
6350
|
+
}),
|
|
6351
|
+
/* @__PURE__ */ jsx17(Hints, {
|
|
4783
6352
|
hints: [
|
|
4784
6353
|
["^v", "move"],
|
|
4785
|
-
["
|
|
6354
|
+
["tab", "complete"],
|
|
6355
|
+
["enter", current?.value === RUN ? "run" : "open"],
|
|
6356
|
+
["?", "keys"],
|
|
4786
6357
|
["esc", query ? "clear" : "quit"]
|
|
4787
6358
|
]
|
|
4788
6359
|
})
|
|
@@ -4790,6 +6361,27 @@ function HomeScreen({
|
|
|
4790
6361
|
});
|
|
4791
6362
|
}
|
|
4792
6363
|
// src/args.ts
|
|
6364
|
+
var COMMAND_WORDS2 = [
|
|
6365
|
+
"browse",
|
|
6366
|
+
"login",
|
|
6367
|
+
"logout",
|
|
6368
|
+
"whoami",
|
|
6369
|
+
"org",
|
|
6370
|
+
"list",
|
|
6371
|
+
"search",
|
|
6372
|
+
"bundle",
|
|
6373
|
+
"add",
|
|
6374
|
+
"install",
|
|
6375
|
+
"remove",
|
|
6376
|
+
"update",
|
|
6377
|
+
"installed",
|
|
6378
|
+
"outdated",
|
|
6379
|
+
"doctor",
|
|
6380
|
+
"config",
|
|
6381
|
+
"hooks",
|
|
6382
|
+
"help",
|
|
6383
|
+
"version"
|
|
6384
|
+
];
|
|
4793
6385
|
var HELP = `yourskills — install skills from your organization's registry
|
|
4794
6386
|
|
|
4795
6387
|
Usage: yourskills <command> [options]
|
|
@@ -4815,9 +6407,9 @@ Commands:
|
|
|
4815
6407
|
outdated Report skills whose registry pin has moved
|
|
4816
6408
|
doctor Check the server, the session, the agents, the manifest
|
|
4817
6409
|
config get [key] Show the stored settings, or one of them
|
|
4818
|
-
config set <key> <val> Set one: scope, agents, server, track
|
|
6410
|
+
config set <key> <val> Set one: scope, agents, server, track, autoUpdate
|
|
4819
6411
|
hooks status Show which agents carry our hooks, and where
|
|
4820
|
-
hooks install Register them:
|
|
6412
|
+
hooks install Register them: the session update, and usage if opted in
|
|
4821
6413
|
hooks uninstall Remove ours, leaving every other hook alone
|
|
4822
6414
|
|
|
4823
6415
|
Options:
|
|
@@ -4836,8 +6428,15 @@ Options:
|
|
|
4836
6428
|
|
|
4837
6429
|
Environment:
|
|
4838
6430
|
YOURSKILLS_URL Registry base URL (default api.yourskills.store)
|
|
4839
|
-
YOURSKILLS_NO_TRACK Set to 1 to disable usage counting outright
|
|
4840
|
-
|
|
6431
|
+
YOURSKILLS_NO_TRACK Set to 1 to disable usage counting outright
|
|
6432
|
+
YOURSKILLS_DEBUG Set to 1 to print the stack behind an error
|
|
6433
|
+
|
|
6434
|
+
Exit codes:
|
|
6435
|
+
0 Done
|
|
6436
|
+
1 Something did not land: a failed install, a pending pull request
|
|
6437
|
+
2 The command line was wrong; the last line says the spelling
|
|
6438
|
+
3 Needs a session: run yourskills login`;
|
|
6439
|
+
function configCommand2(rest) {
|
|
4841
6440
|
const [action, key, ...value] = rest;
|
|
4842
6441
|
if (action === undefined || action === "get") {
|
|
4843
6442
|
return { kind: "config", action: "get", ...key ? { key } : {} };
|
|
@@ -4862,7 +6461,7 @@ function configCommand(rest) {
|
|
|
4862
6461
|
}
|
|
4863
6462
|
return { kind: "config", action: "set", key, value: value.join(" ") };
|
|
4864
6463
|
}
|
|
4865
|
-
function
|
|
6464
|
+
function hooksCommand2(rest, agent, track) {
|
|
4866
6465
|
const action = rest[0] ?? "status";
|
|
4867
6466
|
if (action !== "install" && action !== "uninstall" && action !== "status") {
|
|
4868
6467
|
return {
|
|
@@ -4877,7 +6476,7 @@ function hooksCommand(rest, agent, track) {
|
|
|
4877
6476
|
...track === undefined ? {} : { track }
|
|
4878
6477
|
};
|
|
4879
6478
|
}
|
|
4880
|
-
function
|
|
6479
|
+
function parseArgv2(args, interactive = true) {
|
|
4881
6480
|
const opts = {};
|
|
4882
6481
|
const positional = [];
|
|
4883
6482
|
let plain = !interactive;
|
|
@@ -4928,7 +6527,11 @@ function parseArgv(args, interactive = true) {
|
|
|
4928
6527
|
});
|
|
4929
6528
|
opts.agents = [...opts.agents ?? [], value];
|
|
4930
6529
|
} else if (arg.startsWith("-")) {
|
|
4931
|
-
return done({
|
|
6530
|
+
return done({
|
|
6531
|
+
kind: "error",
|
|
6532
|
+
message: `unknown option ${arg}`,
|
|
6533
|
+
next: "yourskills --help"
|
|
6534
|
+
});
|
|
4932
6535
|
} else {
|
|
4933
6536
|
positional.push(arg);
|
|
4934
6537
|
}
|
|
@@ -4980,9 +6583,9 @@ function parseArgv(args, interactive = true) {
|
|
|
4980
6583
|
case "org":
|
|
4981
6584
|
return done(rest[0] ? { kind: "org", name: rest[0] } : { kind: "org" });
|
|
4982
6585
|
case "config":
|
|
4983
|
-
return done(
|
|
6586
|
+
return done(configCommand2(rest));
|
|
4984
6587
|
case "hooks":
|
|
4985
|
-
return done(
|
|
6588
|
+
return done(hooksCommand2(rest, opts.agents?.[0], track));
|
|
4986
6589
|
case "hook": {
|
|
4987
6590
|
const event = rest[0];
|
|
4988
6591
|
return done(event && isHookEventName(event) ? { kind: "hook", event } : {
|
|
@@ -5002,8 +6605,14 @@ function parseArgv(args, interactive = true) {
|
|
|
5002
6605
|
...all ? { all: true } : {},
|
|
5003
6606
|
opts
|
|
5004
6607
|
});
|
|
5005
|
-
default:
|
|
5006
|
-
|
|
6608
|
+
default: {
|
|
6609
|
+
const guess = closest(command, COMMAND_WORDS2);
|
|
6610
|
+
return done({
|
|
6611
|
+
kind: "error",
|
|
6612
|
+
message: `unknown command ${command}`,
|
|
6613
|
+
...guess ? { why: `did you mean ${guess}?`, next: `yourskills ${guess}` } : { next: "yourskills --help" }
|
|
6614
|
+
});
|
|
6615
|
+
}
|
|
5007
6616
|
}
|
|
5008
6617
|
}
|
|
5009
6618
|
|
|
@@ -5021,9 +6630,9 @@ async function createClient2(server) {
|
|
|
5021
6630
|
}
|
|
5022
6631
|
|
|
5023
6632
|
// src/screens.tsx
|
|
5024
|
-
import { Box as
|
|
5025
|
-
import { useEffect as
|
|
5026
|
-
import { jsx as
|
|
6633
|
+
import { Box as Box15, Text as Text17, useApp as useApp8, useInput as useInput9 } from "ink";
|
|
6634
|
+
import { useEffect as useEffect10, useState as useState12 } from "react";
|
|
6635
|
+
import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
5027
6636
|
var HELP_COLUMN = 26;
|
|
5028
6637
|
function WhoamiScreen({
|
|
5029
6638
|
load,
|
|
@@ -5031,8 +6640,8 @@ function WhoamiScreen({
|
|
|
5031
6640
|
}) {
|
|
5032
6641
|
const { exit } = useApp8();
|
|
5033
6642
|
const width = useFrameWidth();
|
|
5034
|
-
const [who, setWho] =
|
|
5035
|
-
|
|
6643
|
+
const [who, setWho] = useState12(null);
|
|
6644
|
+
useEffect10(() => {
|
|
5036
6645
|
let live = true;
|
|
5037
6646
|
load().then((result) => {
|
|
5038
6647
|
if (!live)
|
|
@@ -5048,13 +6657,13 @@ function WhoamiScreen({
|
|
|
5048
6657
|
};
|
|
5049
6658
|
}, [load, exit, onError]);
|
|
5050
6659
|
if (!who) {
|
|
5051
|
-
return /* @__PURE__ */
|
|
6660
|
+
return /* @__PURE__ */ jsx18(Frame, {
|
|
5052
6661
|
title: "whoami",
|
|
5053
6662
|
width,
|
|
5054
|
-
children: /* @__PURE__ */
|
|
6663
|
+
children: /* @__PURE__ */ jsxs17(Text17, {
|
|
5055
6664
|
children: [
|
|
5056
|
-
/* @__PURE__ */
|
|
5057
|
-
/* @__PURE__ */
|
|
6665
|
+
/* @__PURE__ */ jsx18(Spinner, {}),
|
|
6666
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5058
6667
|
dimColor: true,
|
|
5059
6668
|
children: " Checking session..."
|
|
5060
6669
|
})
|
|
@@ -5062,44 +6671,44 @@ function WhoamiScreen({
|
|
|
5062
6671
|
})
|
|
5063
6672
|
});
|
|
5064
6673
|
}
|
|
5065
|
-
return /* @__PURE__ */
|
|
6674
|
+
return /* @__PURE__ */ jsx18(Frame, {
|
|
5066
6675
|
title: "whoami",
|
|
5067
6676
|
width,
|
|
5068
|
-
children: /* @__PURE__ */
|
|
6677
|
+
children: /* @__PURE__ */ jsxs17(Box15, {
|
|
5069
6678
|
flexDirection: "column",
|
|
5070
6679
|
children: [
|
|
5071
|
-
/* @__PURE__ */
|
|
6680
|
+
/* @__PURE__ */ jsxs17(Text17, {
|
|
5072
6681
|
children: [
|
|
5073
|
-
/* @__PURE__ */
|
|
6682
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5074
6683
|
dimColor: true,
|
|
5075
6684
|
children: "user "
|
|
5076
6685
|
}),
|
|
5077
|
-
/* @__PURE__ */
|
|
6686
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5078
6687
|
children: who.user
|
|
5079
6688
|
})
|
|
5080
6689
|
]
|
|
5081
6690
|
}),
|
|
5082
|
-
/* @__PURE__ */
|
|
6691
|
+
/* @__PURE__ */ jsxs17(Text17, {
|
|
5083
6692
|
children: [
|
|
5084
|
-
/* @__PURE__ */
|
|
6693
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5085
6694
|
dimColor: true,
|
|
5086
6695
|
children: "org "
|
|
5087
6696
|
}),
|
|
5088
|
-
who.org ? /* @__PURE__ */
|
|
6697
|
+
who.org ? /* @__PURE__ */ jsx18(Text17, {
|
|
5089
6698
|
children: who.org
|
|
5090
|
-
}) : /* @__PURE__ */
|
|
6699
|
+
}) : /* @__PURE__ */ jsx18(Text17, {
|
|
5091
6700
|
color: tone.notice,
|
|
5092
6701
|
children: "none — set an active organization in the web UI"
|
|
5093
6702
|
})
|
|
5094
6703
|
]
|
|
5095
6704
|
}),
|
|
5096
|
-
/* @__PURE__ */
|
|
6705
|
+
/* @__PURE__ */ jsxs17(Text17, {
|
|
5097
6706
|
children: [
|
|
5098
|
-
/* @__PURE__ */
|
|
6707
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5099
6708
|
dimColor: true,
|
|
5100
6709
|
children: "server "
|
|
5101
6710
|
}),
|
|
5102
|
-
/* @__PURE__ */
|
|
6711
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5103
6712
|
color: tone.primary,
|
|
5104
6713
|
children: who.server
|
|
5105
6714
|
})
|
|
@@ -5115,17 +6724,17 @@ function NoticeScreen({
|
|
|
5115
6724
|
}) {
|
|
5116
6725
|
const { exit } = useApp8();
|
|
5117
6726
|
const width = useFrameWidth();
|
|
5118
|
-
|
|
5119
|
-
return /* @__PURE__ */
|
|
6727
|
+
useEffect10(exit, [exit]);
|
|
6728
|
+
return /* @__PURE__ */ jsx18(Frame, {
|
|
5120
6729
|
title,
|
|
5121
6730
|
width,
|
|
5122
|
-
children: /* @__PURE__ */
|
|
6731
|
+
children: /* @__PURE__ */ jsxs17(Text17, {
|
|
5123
6732
|
children: [
|
|
5124
|
-
/* @__PURE__ */
|
|
6733
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5125
6734
|
color: "green",
|
|
5126
6735
|
children: mark.ok
|
|
5127
6736
|
}),
|
|
5128
|
-
/* @__PURE__ */
|
|
6737
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5129
6738
|
children: ` ${message}`
|
|
5130
6739
|
})
|
|
5131
6740
|
]
|
|
@@ -5142,16 +6751,16 @@ function ReportRow2({ line: line2, width }) {
|
|
|
5142
6751
|
const { glyph, color } = MARKS2[line2.mark];
|
|
5143
6752
|
const head = line2.mark === "none" ? "" : `${glyph} `;
|
|
5144
6753
|
const room = width - FRAME_CHROME - head.length;
|
|
5145
|
-
return /* @__PURE__ */
|
|
6754
|
+
return /* @__PURE__ */ jsxs17(Text17, {
|
|
5146
6755
|
children: [
|
|
5147
|
-
head ? /* @__PURE__ */
|
|
6756
|
+
head ? /* @__PURE__ */ jsx18(Text17, {
|
|
5148
6757
|
color,
|
|
5149
6758
|
children: head
|
|
5150
6759
|
}) : null,
|
|
5151
|
-
/* @__PURE__ */
|
|
6760
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5152
6761
|
children: clip(line2.text, room)
|
|
5153
6762
|
}),
|
|
5154
|
-
line2.note ? /* @__PURE__ */
|
|
6763
|
+
line2.note ? /* @__PURE__ */ jsx18(Text17, {
|
|
5155
6764
|
dimColor: true,
|
|
5156
6765
|
children: clip(` ${line2.note}`, Math.max(room - line2.text.length, 0))
|
|
5157
6766
|
}) : null
|
|
@@ -5163,12 +6772,15 @@ function ReportScreen2({
|
|
|
5163
6772
|
load,
|
|
5164
6773
|
onError,
|
|
5165
6774
|
onReport,
|
|
5166
|
-
exitWhenDone = true
|
|
6775
|
+
exitWhenDone = true,
|
|
6776
|
+
onBack,
|
|
6777
|
+
working = "Working...",
|
|
6778
|
+
onNext
|
|
5167
6779
|
}) {
|
|
5168
6780
|
const { exit } = useApp8();
|
|
5169
6781
|
const width = useFrameWidth();
|
|
5170
|
-
const [report, setReport] =
|
|
5171
|
-
|
|
6782
|
+
const [report, setReport] = useState12(null);
|
|
6783
|
+
useEffect10(() => {
|
|
5172
6784
|
let live = true;
|
|
5173
6785
|
load().then((result) => {
|
|
5174
6786
|
if (!live)
|
|
@@ -5183,28 +6795,58 @@ function ReportScreen2({
|
|
|
5183
6795
|
live = false;
|
|
5184
6796
|
};
|
|
5185
6797
|
}, [load, onError, onReport]);
|
|
5186
|
-
|
|
6798
|
+
useEffect10(() => {
|
|
5187
6799
|
if (report && exitWhenDone)
|
|
5188
6800
|
exit();
|
|
5189
6801
|
}, [report, exit, exitWhenDone]);
|
|
5190
|
-
|
|
6802
|
+
const next = report?.next;
|
|
6803
|
+
useInput9((input) => {
|
|
6804
|
+
if (input === "n" && next)
|
|
6805
|
+
onNext?.(next.command);
|
|
6806
|
+
}, { isActive: Boolean(onNext && next) });
|
|
6807
|
+
return /* @__PURE__ */ jsxs17(Frame, {
|
|
5191
6808
|
title,
|
|
5192
6809
|
width,
|
|
5193
|
-
children:
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5205
|
-
|
|
5206
|
-
|
|
5207
|
-
|
|
6810
|
+
children: [
|
|
6811
|
+
report ? /* @__PURE__ */ jsxs17(Box15, {
|
|
6812
|
+
flexDirection: "column",
|
|
6813
|
+
children: [
|
|
6814
|
+
report.lines.map((line2) => /* @__PURE__ */ jsx18(ReportRow2, {
|
|
6815
|
+
line: line2,
|
|
6816
|
+
width
|
|
6817
|
+
}, `${line2.mark}:${line2.text}`)),
|
|
6818
|
+
next ? /* @__PURE__ */ jsxs17(Text17, {
|
|
6819
|
+
children: [
|
|
6820
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
6821
|
+
dimColor: true,
|
|
6822
|
+
children: "next "
|
|
6823
|
+
}),
|
|
6824
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
6825
|
+
color: tone.primary,
|
|
6826
|
+
children: next.command
|
|
6827
|
+
}),
|
|
6828
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
6829
|
+
dimColor: true,
|
|
6830
|
+
children: clip(` ${next.why}`, width - FRAME_CHROME)
|
|
6831
|
+
})
|
|
6832
|
+
]
|
|
6833
|
+
}) : null
|
|
6834
|
+
]
|
|
6835
|
+
}) : /* @__PURE__ */ jsxs17(Text17, {
|
|
6836
|
+
children: [
|
|
6837
|
+
/* @__PURE__ */ jsx18(Spinner, {}),
|
|
6838
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
6839
|
+
dimColor: true,
|
|
6840
|
+
children: ` ${working}`
|
|
6841
|
+
})
|
|
6842
|
+
]
|
|
6843
|
+
}),
|
|
6844
|
+
/* @__PURE__ */ jsx18(Back, {
|
|
6845
|
+
width,
|
|
6846
|
+
onBack,
|
|
6847
|
+
extra: onNext && next ? [["n", "run next"]] : []
|
|
6848
|
+
})
|
|
6849
|
+
]
|
|
5208
6850
|
});
|
|
5209
6851
|
}
|
|
5210
6852
|
function numberedLines(text) {
|
|
@@ -5214,26 +6856,26 @@ function numberedLines(text) {
|
|
|
5214
6856
|
function HelpScreen({ text }) {
|
|
5215
6857
|
const { exit } = useApp8();
|
|
5216
6858
|
const width = useFrameWidth();
|
|
5217
|
-
|
|
5218
|
-
return /* @__PURE__ */
|
|
6859
|
+
useEffect10(exit, [exit]);
|
|
6860
|
+
return /* @__PURE__ */ jsx18(Frame, {
|
|
5219
6861
|
title: "yourskills",
|
|
5220
6862
|
width,
|
|
5221
|
-
children: /* @__PURE__ */
|
|
6863
|
+
children: /* @__PURE__ */ jsx18(Box15, {
|
|
5222
6864
|
flexDirection: "column",
|
|
5223
6865
|
children: numberedLines(text).map(({ id, line: line2 }) => {
|
|
5224
6866
|
if (line2.length === 0)
|
|
5225
|
-
return /* @__PURE__ */
|
|
6867
|
+
return /* @__PURE__ */ jsx18(Blank, {}, id);
|
|
5226
6868
|
if (!line2.startsWith(" "))
|
|
5227
|
-
return /* @__PURE__ */
|
|
6869
|
+
return /* @__PURE__ */ jsx18(Text17, {
|
|
5228
6870
|
children: clip(line2, width - FRAME_CHROME)
|
|
5229
6871
|
}, id);
|
|
5230
|
-
return /* @__PURE__ */
|
|
6872
|
+
return /* @__PURE__ */ jsxs17(Text17, {
|
|
5231
6873
|
children: [
|
|
5232
|
-
/* @__PURE__ */
|
|
6874
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5233
6875
|
color: tone.primary,
|
|
5234
6876
|
children: line2.slice(0, HELP_COLUMN)
|
|
5235
6877
|
}),
|
|
5236
|
-
/* @__PURE__ */
|
|
6878
|
+
/* @__PURE__ */ jsx18(Text17, {
|
|
5237
6879
|
dimColor: true,
|
|
5238
6880
|
children: clip(line2.slice(HELP_COLUMN), width - FRAME_CHROME - HELP_COLUMN)
|
|
5239
6881
|
})
|
|
@@ -5246,7 +6888,7 @@ function HelpScreen({ text }) {
|
|
|
5246
6888
|
// package.json
|
|
5247
6889
|
var package_default = {
|
|
5248
6890
|
name: "yourskills",
|
|
5249
|
-
version: "0.1.
|
|
6891
|
+
version: "0.1.3",
|
|
5250
6892
|
description: "Browse, install and keep up to date the agent skills and bundles your team publishes on yourskills.",
|
|
5251
6893
|
license: "UNLICENSED",
|
|
5252
6894
|
homepage: "https://yourskills.store",
|
|
@@ -5303,7 +6945,7 @@ var package_default = {
|
|
|
5303
6945
|
var VERSION = package_default.version ?? "0.0.0-dev";
|
|
5304
6946
|
|
|
5305
6947
|
// src/main.tsx
|
|
5306
|
-
import { jsx as
|
|
6948
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
5307
6949
|
function applySummary(summary) {
|
|
5308
6950
|
if (summary.pending.length > 0 || summary.failed > 0)
|
|
5309
6951
|
process.exitCode = 1;
|
|
@@ -5314,7 +6956,7 @@ var PLAIN_MARKS = {
|
|
|
5314
6956
|
pending: mark.pending,
|
|
5315
6957
|
none: ""
|
|
5316
6958
|
};
|
|
5317
|
-
function
|
|
6959
|
+
function emit2(report, output) {
|
|
5318
6960
|
if (report.failed)
|
|
5319
6961
|
process.exitCode = 1;
|
|
5320
6962
|
if (output.json) {
|
|
@@ -5325,6 +6967,8 @@ function emit(report, output) {
|
|
|
5325
6967
|
return;
|
|
5326
6968
|
for (const line2 of report.lines)
|
|
5327
6969
|
console.log(plainLine(line2, PLAIN_MARKS));
|
|
6970
|
+
if (report.next)
|
|
6971
|
+
console.log(nextLine(report.next));
|
|
5328
6972
|
}
|
|
5329
6973
|
function toRows(skills) {
|
|
5330
6974
|
return skills.map((s) => ({
|
|
@@ -5354,15 +6998,6 @@ function catalogReport(title, skills) {
|
|
|
5354
6998
|
json: { skills }
|
|
5355
6999
|
};
|
|
5356
7000
|
}
|
|
5357
|
-
async function resolveInstallOptions(opts) {
|
|
5358
|
-
const { scope, manifestPath } = await resolveScope({ flag: opts.scope });
|
|
5359
|
-
const path = scope === "project" && manifestPath ? manifestPath : manifestPathFor(scope);
|
|
5360
|
-
return {
|
|
5361
|
-
scope,
|
|
5362
|
-
agents: await resolveAgents(opts.agents),
|
|
5363
|
-
manifest: { path, scope }
|
|
5364
|
-
};
|
|
5365
|
-
}
|
|
5366
7001
|
var INVITES_HOOKS = new Set([
|
|
5367
7002
|
"login",
|
|
5368
7003
|
"add",
|
|
@@ -5388,22 +7023,6 @@ async function prepare(command) {
|
|
|
5388
7023
|
function nearestFor(opts) {
|
|
5389
7024
|
return nearestManifest(opts.scope);
|
|
5390
7025
|
}
|
|
5391
|
-
function nothingTracked(nearest, kind, all = false) {
|
|
5392
|
-
const has = kind === "install" ? Object.keys(nearest.manifest.skills).length > 0 : Object.keys(nearest.manifest.bundles).length > 0 || all && looseSkills(nearest.manifest).length > 0;
|
|
5393
|
-
if (has)
|
|
5394
|
-
return null;
|
|
5395
|
-
return {
|
|
5396
|
-
title: kind,
|
|
5397
|
-
lines: [
|
|
5398
|
-
{
|
|
5399
|
-
mark: "none",
|
|
5400
|
-
text: kind === "install" ? "Nothing recorded to install. Run `yourskills bundle <name>` first." : "No bundles tracked here. Run `yourskills bundle <name>` first.",
|
|
5401
|
-
note: nearest.path
|
|
5402
|
-
}
|
|
5403
|
-
],
|
|
5404
|
-
json: { manifest: nearest.path, skills: [], bundles: [] }
|
|
5405
|
-
};
|
|
5406
|
-
}
|
|
5407
7026
|
async function runPlain(command, output, server) {
|
|
5408
7027
|
switch (command.kind) {
|
|
5409
7028
|
case "help":
|
|
@@ -5412,12 +7031,25 @@ async function runPlain(command, output, server) {
|
|
|
5412
7031
|
case "version":
|
|
5413
7032
|
console.log(VERSION);
|
|
5414
7033
|
return;
|
|
7034
|
+
case "error":
|
|
7035
|
+
throw new CliError(command.message, {
|
|
7036
|
+
...command.why ? { why: command.why } : {},
|
|
7037
|
+
...command.next ? { next: command.next } : {},
|
|
7038
|
+
code: EXIT.usage
|
|
7039
|
+
});
|
|
5415
7040
|
case "home":
|
|
5416
7041
|
case "browse":
|
|
5417
|
-
|
|
5418
|
-
|
|
7042
|
+
throw new CliError(`${command.kind === "home" ? "the palette" : "browse"} needs a terminal`, {
|
|
7043
|
+
why: "stdout is not a terminal, so there is nothing to draw the frame into",
|
|
7044
|
+
next: "yourskills list, or yourskills search <query>",
|
|
7045
|
+
code: EXIT.usage
|
|
7046
|
+
});
|
|
5419
7047
|
case "login":
|
|
5420
|
-
throw new
|
|
7048
|
+
throw new CliError("login needs a terminal", {
|
|
7049
|
+
why: "the device code has to be read by a person",
|
|
7050
|
+
next: "sign in on a machine with a terminal, then copy ~/.config/yourskills/config.json",
|
|
7051
|
+
code: EXIT.usage
|
|
7052
|
+
});
|
|
5421
7053
|
case "logout":
|
|
5422
7054
|
await logout();
|
|
5423
7055
|
console.log("Logged out.");
|
|
@@ -5432,7 +7064,7 @@ async function runPlain(command, output, server) {
|
|
|
5432
7064
|
case "search": {
|
|
5433
7065
|
const client = await createClient2(server);
|
|
5434
7066
|
const skills = command.kind === "list" ? await client.skills.list.query({}) : await client.skills.search.query({ q: command.query });
|
|
5435
|
-
|
|
7067
|
+
emit2(catalogReport(command.kind === "list" ? "skills" : `search: ${command.query}`, skills), output);
|
|
5436
7068
|
return;
|
|
5437
7069
|
}
|
|
5438
7070
|
case "add":
|
|
@@ -5445,7 +7077,7 @@ async function runPlain(command, output, server) {
|
|
|
5445
7077
|
const nearest = await nearestFor(command.opts);
|
|
5446
7078
|
const empty = nothingTracked(nearest, "install");
|
|
5447
7079
|
if (empty) {
|
|
5448
|
-
|
|
7080
|
+
emit2(empty, output);
|
|
5449
7081
|
return;
|
|
5450
7082
|
}
|
|
5451
7083
|
applySummary(await installPlain(reinstall(nearest.manifest, command.opts)));
|
|
@@ -5459,7 +7091,7 @@ async function runPlain(command, output, server) {
|
|
|
5459
7091
|
const nearest = await nearestFor(command.opts);
|
|
5460
7092
|
const empty = nothingTracked(nearest, "update", command.all ?? false);
|
|
5461
7093
|
if (empty) {
|
|
5462
|
-
|
|
7094
|
+
emit2(empty, output);
|
|
5463
7095
|
return;
|
|
5464
7096
|
}
|
|
5465
7097
|
applySummary(await installPlain(updateTracked(await createClient2(server), nearest.manifest, command.opts, command.all ?? false)));
|
|
@@ -5467,26 +7099,26 @@ async function runPlain(command, output, server) {
|
|
|
5467
7099
|
}
|
|
5468
7100
|
case "remove": {
|
|
5469
7101
|
const nearest = await nearestFor(command.opts);
|
|
5470
|
-
|
|
7102
|
+
emit2(await removeSkills(command.names, nearest.manifest, nearest.path, command.opts), output);
|
|
5471
7103
|
return;
|
|
5472
7104
|
}
|
|
5473
7105
|
case "installed":
|
|
5474
|
-
|
|
7106
|
+
emit2(installedReport(await nearestManifest()), output);
|
|
5475
7107
|
return;
|
|
5476
7108
|
case "outdated":
|
|
5477
|
-
|
|
7109
|
+
emit2(await outdatedReport(await createClient2(server), await nearestManifest(), command.quiet ?? false), output);
|
|
5478
7110
|
return;
|
|
5479
7111
|
case "doctor":
|
|
5480
|
-
|
|
7112
|
+
emit2(await doctorReport(await nearestManifest(), server), output);
|
|
5481
7113
|
return;
|
|
5482
7114
|
case "org":
|
|
5483
|
-
|
|
7115
|
+
emit2(command.name ? await orgSwitchReport(command.name, server) : await orgListReport(server), output);
|
|
5484
7116
|
return;
|
|
5485
7117
|
case "config":
|
|
5486
|
-
|
|
7118
|
+
emit2(command.action === "get" ? await configGet(command.key) : await configSet(command.key, command.value), output);
|
|
5487
7119
|
return;
|
|
5488
7120
|
case "hooks":
|
|
5489
|
-
|
|
7121
|
+
emit2(await hooksReport(command), output);
|
|
5490
7122
|
return;
|
|
5491
7123
|
case "hook":
|
|
5492
7124
|
await runHook(command.event);
|
|
@@ -5504,13 +7136,13 @@ function hooksReport(command) {
|
|
|
5504
7136
|
return hooksStatus();
|
|
5505
7137
|
}
|
|
5506
7138
|
async function screenFor(command, fail, summarise, report, server) {
|
|
5507
|
-
const gate = (title, build) => /* @__PURE__ */
|
|
7139
|
+
const gate = (title, build) => /* @__PURE__ */ jsx19(AuthGate, {
|
|
5508
7140
|
title,
|
|
5509
7141
|
build,
|
|
5510
7142
|
connect: () => createClient2(server),
|
|
5511
7143
|
onError: fail
|
|
5512
7144
|
});
|
|
5513
|
-
const local = (title, load) => /* @__PURE__ */
|
|
7145
|
+
const local = (title, load) => /* @__PURE__ */ jsx19(ReportScreen2, {
|
|
5514
7146
|
title,
|
|
5515
7147
|
load,
|
|
5516
7148
|
onError: fail,
|
|
@@ -5518,40 +7150,44 @@ async function screenFor(command, fail, summarise, report, server) {
|
|
|
5518
7150
|
});
|
|
5519
7151
|
switch (command.kind) {
|
|
5520
7152
|
case "help":
|
|
5521
|
-
return /* @__PURE__ */
|
|
7153
|
+
return /* @__PURE__ */ jsx19(HelpScreen, {
|
|
5522
7154
|
text: HELP
|
|
5523
7155
|
});
|
|
5524
7156
|
case "version":
|
|
5525
|
-
return /* @__PURE__ */
|
|
7157
|
+
return /* @__PURE__ */ jsx19(NoticeScreen, {
|
|
5526
7158
|
title: "version",
|
|
5527
7159
|
message: VERSION
|
|
5528
7160
|
});
|
|
5529
7161
|
case "error":
|
|
5530
|
-
throw new
|
|
7162
|
+
throw new CliError(command.message, {
|
|
7163
|
+
...command.why ? { why: command.why } : {},
|
|
7164
|
+
...command.next ? { next: command.next } : {},
|
|
7165
|
+
code: EXIT.usage
|
|
7166
|
+
});
|
|
5531
7167
|
case "login":
|
|
5532
|
-
return /* @__PURE__ */
|
|
7168
|
+
return /* @__PURE__ */ jsx19(LoginScreen, {
|
|
5533
7169
|
onError: fail
|
|
5534
7170
|
});
|
|
5535
7171
|
case "logout":
|
|
5536
7172
|
await logout();
|
|
5537
|
-
return /* @__PURE__ */
|
|
7173
|
+
return /* @__PURE__ */ jsx19(NoticeScreen, {
|
|
5538
7174
|
title: "logout",
|
|
5539
7175
|
message: "Logged out."
|
|
5540
7176
|
});
|
|
5541
7177
|
case "whoami":
|
|
5542
|
-
return gate("whoami", () => /* @__PURE__ */
|
|
7178
|
+
return gate("whoami", () => /* @__PURE__ */ jsx19(WhoamiScreen, {
|
|
5543
7179
|
load: () => whoami(server),
|
|
5544
7180
|
onError: fail
|
|
5545
7181
|
}));
|
|
5546
7182
|
case "list":
|
|
5547
|
-
return gate("skills", (client) => /* @__PURE__ */
|
|
7183
|
+
return gate("skills", (client) => /* @__PURE__ */ jsx19(CatalogScreen, {
|
|
5548
7184
|
title: "skills",
|
|
5549
7185
|
load: async () => toRows(await client.skills.list.query({})),
|
|
5550
7186
|
onError: fail
|
|
5551
7187
|
}));
|
|
5552
7188
|
case "search": {
|
|
5553
7189
|
const q = command.query;
|
|
5554
|
-
return gate(`search: ${q}`, (client) => /* @__PURE__ */
|
|
7190
|
+
return gate(`search: ${q}`, (client) => /* @__PURE__ */ jsx19(CatalogScreen, {
|
|
5555
7191
|
title: `search: ${q}`,
|
|
5556
7192
|
load: async () => toRows(await client.skills.search.query({ q })),
|
|
5557
7193
|
onError: fail
|
|
@@ -5559,17 +7195,27 @@ async function screenFor(command, fail, summarise, report, server) {
|
|
|
5559
7195
|
}
|
|
5560
7196
|
case "home": {
|
|
5561
7197
|
const opts = await resolveInstallOptions({});
|
|
5562
|
-
|
|
7198
|
+
const reload = () => paletteFacts(opts.scope, server);
|
|
7199
|
+
return /* @__PURE__ */ jsx19(HomeScreen, {
|
|
5563
7200
|
opts,
|
|
7201
|
+
facts: await reload(),
|
|
7202
|
+
reload,
|
|
5564
7203
|
server,
|
|
5565
7204
|
openClient: () => createClient2(server),
|
|
5566
7205
|
onError: fail,
|
|
5567
|
-
onSummary: summarise
|
|
7206
|
+
onSummary: summarise,
|
|
7207
|
+
onWelcomed: async () => {
|
|
7208
|
+
const config = await readConfig();
|
|
7209
|
+
await writeConfig({
|
|
7210
|
+
...config,
|
|
7211
|
+
welcomed: new Date().toISOString()
|
|
7212
|
+
});
|
|
7213
|
+
}
|
|
5568
7214
|
});
|
|
5569
7215
|
}
|
|
5570
7216
|
case "browse": {
|
|
5571
7217
|
const opts = await resolveInstallOptions({});
|
|
5572
|
-
return gate("browse", (client) => /* @__PURE__ */
|
|
7218
|
+
return gate("browse", (client) => /* @__PURE__ */ jsx19(BrowserScreen, {
|
|
5573
7219
|
client,
|
|
5574
7220
|
opts,
|
|
5575
7221
|
onError: fail,
|
|
@@ -5577,13 +7223,13 @@ async function screenFor(command, fail, summarise, report, server) {
|
|
|
5577
7223
|
}));
|
|
5578
7224
|
}
|
|
5579
7225
|
case "add":
|
|
5580
|
-
return gate("add", (client) => /* @__PURE__ */
|
|
7226
|
+
return gate("add", (client) => /* @__PURE__ */ jsx19(Installer, {
|
|
5581
7227
|
title: "add",
|
|
5582
7228
|
stream: () => install(client, command.names, command.opts),
|
|
5583
7229
|
onDone: summarise
|
|
5584
7230
|
}));
|
|
5585
7231
|
case "bundle":
|
|
5586
|
-
return gate(`bundle: ${command.name}`, (client) => /* @__PURE__ */
|
|
7232
|
+
return gate(`bundle: ${command.name}`, (client) => /* @__PURE__ */ jsx19(Installer, {
|
|
5587
7233
|
title: `bundle: ${command.name}`,
|
|
5588
7234
|
stream: () => installBundle(client, command.name, command.opts),
|
|
5589
7235
|
onDone: summarise
|
|
@@ -5593,7 +7239,7 @@ async function screenFor(command, fail, summarise, report, server) {
|
|
|
5593
7239
|
const empty = nothingTracked(nearest, "install");
|
|
5594
7240
|
if (empty)
|
|
5595
7241
|
return local("install", async () => empty);
|
|
5596
|
-
return /* @__PURE__ */
|
|
7242
|
+
return /* @__PURE__ */ jsx19(Installer, {
|
|
5597
7243
|
title: "install",
|
|
5598
7244
|
stream: () => reinstall(nearest.manifest, command.opts),
|
|
5599
7245
|
onDone: summarise
|
|
@@ -5602,7 +7248,7 @@ async function screenFor(command, fail, summarise, report, server) {
|
|
|
5602
7248
|
case "update": {
|
|
5603
7249
|
if (command.bundle) {
|
|
5604
7250
|
const name = command.bundle;
|
|
5605
|
-
return gate(`update: ${name}`, (client) => /* @__PURE__ */
|
|
7251
|
+
return gate(`update: ${name}`, (client) => /* @__PURE__ */ jsx19(Installer, {
|
|
5606
7252
|
title: `update: ${name}`,
|
|
5607
7253
|
stream: () => update(client, name, command.opts),
|
|
5608
7254
|
onDone: summarise
|
|
@@ -5612,8 +7258,10 @@ async function screenFor(command, fail, summarise, report, server) {
|
|
|
5612
7258
|
const empty = nothingTracked(nearest, "update", command.all ?? false);
|
|
5613
7259
|
if (empty)
|
|
5614
7260
|
return local("update", async () => empty);
|
|
5615
|
-
|
|
7261
|
+
const scope = updateScope(Object.keys(nearest.manifest.bundles).length, command.all ? looseSkills(nearest.manifest).length : 0);
|
|
7262
|
+
return gate("update", (client) => /* @__PURE__ */ jsx19(Installer, {
|
|
5616
7263
|
title: "update",
|
|
7264
|
+
plan: `updating ${scope} to what the registry blesses today`,
|
|
5617
7265
|
stream: () => updateTracked(client, nearest.manifest, command.opts, command.all ?? false),
|
|
5618
7266
|
onDone: summarise
|
|
5619
7267
|
}));
|
|
@@ -5633,14 +7281,15 @@ async function screenFor(command, fail, summarise, report, server) {
|
|
|
5633
7281
|
case "hook":
|
|
5634
7282
|
throw new Error("hooks are not interactive");
|
|
5635
7283
|
case "outdated":
|
|
5636
|
-
return gate("outdated", (client) => /* @__PURE__ */
|
|
7284
|
+
return gate("outdated", (client) => /* @__PURE__ */ jsx19(ReportScreen2, {
|
|
5637
7285
|
title: "outdated",
|
|
7286
|
+
working: "Checking what you have installed against the registry...",
|
|
5638
7287
|
load: async () => outdatedReport(client, await nearestManifest(), command.quiet),
|
|
5639
7288
|
onError: fail,
|
|
5640
7289
|
onReport: report
|
|
5641
7290
|
}));
|
|
5642
7291
|
case "org":
|
|
5643
|
-
return gate("org", () => /* @__PURE__ */
|
|
7292
|
+
return gate("org", () => /* @__PURE__ */ jsx19(ReportScreen2, {
|
|
5644
7293
|
title: "org",
|
|
5645
7294
|
load: () => command.name ? orgSwitchReport(command.name, server) : orgListReport(server),
|
|
5646
7295
|
onError: fail,
|
|
@@ -5674,7 +7323,7 @@ function isEntrypoint() {
|
|
|
5674
7323
|
}
|
|
5675
7324
|
if (isEntrypoint()) {
|
|
5676
7325
|
const interactive = Boolean(process.stdout.isTTY);
|
|
5677
|
-
const parsed =
|
|
7326
|
+
const parsed = parseArgv2(process.argv.slice(2), interactive);
|
|
5678
7327
|
const { output, server } = parsed;
|
|
5679
7328
|
try {
|
|
5680
7329
|
const command = await prepare(parsed.command);
|
|
@@ -5688,7 +7337,13 @@ if (isEntrypoint()) {
|
|
|
5688
7337
|
console.log(line2);
|
|
5689
7338
|
}
|
|
5690
7339
|
} catch (error) {
|
|
5691
|
-
|
|
5692
|
-
|
|
7340
|
+
const { lines, code } = describeError(error);
|
|
7341
|
+
const [what, ...rest] = lines;
|
|
7342
|
+
console.error(`${mark.fail} ${what}`);
|
|
7343
|
+
for (const line2 of rest)
|
|
7344
|
+
console.error(line2);
|
|
7345
|
+
if (process.env.YOURSKILLS_DEBUG === "1" && error instanceof Error)
|
|
7346
|
+
console.error(error.stack);
|
|
7347
|
+
process.exit(code);
|
|
5693
7348
|
}
|
|
5694
7349
|
}
|