yourskills 0.3.1 → 0.4.2
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/dist/main.js +297 -40
- package/package.json +1 -1
package/dist/main.js
CHANGED
|
@@ -909,6 +909,24 @@ function SearchInput({
|
|
|
909
909
|
});
|
|
910
910
|
}
|
|
911
911
|
|
|
912
|
+
// src/ui/viewport.ts
|
|
913
|
+
import { useWindowSize as useWindowSize2 } from "ink";
|
|
914
|
+
var MIN_ROWS = 3;
|
|
915
|
+
var MAX_ROWS = 20;
|
|
916
|
+
function useViewport({
|
|
917
|
+
cursor,
|
|
918
|
+
total,
|
|
919
|
+
chrome
|
|
920
|
+
}) {
|
|
921
|
+
const { rows } = useWindowSize2();
|
|
922
|
+
const size = Math.max(MIN_ROWS, Math.min(MAX_ROWS, rows - chrome));
|
|
923
|
+
const first = Math.max(0, Math.min(cursor - Math.floor(size / 2), total - size));
|
|
924
|
+
return { first, size };
|
|
925
|
+
}
|
|
926
|
+
function position(cursor, total) {
|
|
927
|
+
return `${total > 0 ? cursor + 1 : 0}/${total}`;
|
|
928
|
+
}
|
|
929
|
+
|
|
912
930
|
// src/ui/command.tsx
|
|
913
931
|
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
914
932
|
function filterCommands(groups, query) {
|
|
@@ -923,17 +941,40 @@ function filterCommands(groups, query) {
|
|
|
923
941
|
function flattenCommands(groups) {
|
|
924
942
|
return groups.flatMap((group) => group.items);
|
|
925
943
|
}
|
|
944
|
+
function windowGroups(groups, first, count) {
|
|
945
|
+
const out = [];
|
|
946
|
+
let index = 0;
|
|
947
|
+
for (const group of groups) {
|
|
948
|
+
const items = group.items.filter((_, i) => {
|
|
949
|
+
const row = index + i;
|
|
950
|
+
return row >= first && row < first + count;
|
|
951
|
+
});
|
|
952
|
+
index += group.items.length;
|
|
953
|
+
if (items.length > 0)
|
|
954
|
+
out.push({ group: group.group, items });
|
|
955
|
+
}
|
|
956
|
+
return out;
|
|
957
|
+
}
|
|
926
958
|
var POINTER = 2;
|
|
927
959
|
var GAP2 = 2;
|
|
960
|
+
var LABEL_CAP = 22;
|
|
961
|
+
function valueColumn(items) {
|
|
962
|
+
return Math.min(items.reduce((wide, item) => Math.max(wide, item.label.length), 0), LABEL_CAP);
|
|
963
|
+
}
|
|
928
964
|
function CommandRow({
|
|
929
965
|
item,
|
|
930
966
|
width,
|
|
967
|
+
column,
|
|
931
968
|
active
|
|
932
969
|
}) {
|
|
933
970
|
const hint = item.hint ?? "";
|
|
934
971
|
const room = width - POINTER - (hint ? hint.length + GAP2 : 0);
|
|
935
972
|
const label = clip(item.label, Math.max(room, 0));
|
|
936
|
-
const
|
|
973
|
+
const shows = item.shows ?? "";
|
|
974
|
+
const pad = Math.max(column - label.length, 0) + GAP2;
|
|
975
|
+
const value = shows && label.length + pad + shows.length <= room ? shows : "";
|
|
976
|
+
const left = label.length + (value ? pad + value.length : 0);
|
|
977
|
+
const gap = Math.max(width - POINTER - left - hint.length, hint ? 1 : 0);
|
|
937
978
|
return /* @__PURE__ */ jsxs5(Text4, {
|
|
938
979
|
children: [
|
|
939
980
|
/* @__PURE__ */ jsx5(Text4, {
|
|
@@ -945,6 +986,9 @@ function CommandRow({
|
|
|
945
986
|
color: active ? tone.primary : undefined,
|
|
946
987
|
children: label
|
|
947
988
|
}),
|
|
989
|
+
value ? /* @__PURE__ */ jsx5(Text4, {
|
|
990
|
+
children: `${" ".repeat(pad)}${value}`
|
|
991
|
+
}) : null,
|
|
948
992
|
/* @__PURE__ */ jsx5(Text4, {
|
|
949
993
|
dimColor: true,
|
|
950
994
|
children: `${" ".repeat(gap)}${hint}`
|
|
@@ -957,6 +1001,7 @@ function CommandPalette({
|
|
|
957
1001
|
query,
|
|
958
1002
|
cursor,
|
|
959
1003
|
width,
|
|
1004
|
+
chrome = 11,
|
|
960
1005
|
placeholder = "type a command or search",
|
|
961
1006
|
emptyMessage = "No matching commands."
|
|
962
1007
|
}) {
|
|
@@ -964,6 +1009,13 @@ function CommandPalette({
|
|
|
964
1009
|
const rows = flattenCommands(visible);
|
|
965
1010
|
const current = rows[cursor];
|
|
966
1011
|
const interior = width - FRAME_CHROME;
|
|
1012
|
+
const column = valueColumn(rows);
|
|
1013
|
+
const { first, size } = useViewport({
|
|
1014
|
+
cursor,
|
|
1015
|
+
total: rows.length,
|
|
1016
|
+
chrome: chrome + Math.max(0, visible.length * 2 - 1)
|
|
1017
|
+
});
|
|
1018
|
+
const paged = windowGroups(visible, first, size);
|
|
967
1019
|
return /* @__PURE__ */ jsxs5(Box3, {
|
|
968
1020
|
flexDirection: "column",
|
|
969
1021
|
children: [
|
|
@@ -985,7 +1037,7 @@ function CommandPalette({
|
|
|
985
1037
|
rows.length === 0 ? /* @__PURE__ */ jsx5(Text4, {
|
|
986
1038
|
dimColor: true,
|
|
987
1039
|
children: emptyMessage
|
|
988
|
-
}) :
|
|
1040
|
+
}) : paged.map((group, i) => /* @__PURE__ */ jsxs5(Box3, {
|
|
989
1041
|
flexDirection: "column",
|
|
990
1042
|
children: [
|
|
991
1043
|
i > 0 ? /* @__PURE__ */ jsx5(Divider, {
|
|
@@ -998,6 +1050,7 @@ function CommandPalette({
|
|
|
998
1050
|
group.items.map((item) => /* @__PURE__ */ jsx5(CommandRow, {
|
|
999
1051
|
item,
|
|
1000
1052
|
width: interior,
|
|
1053
|
+
column,
|
|
1001
1054
|
active: item.value === current?.value
|
|
1002
1055
|
}, item.value))
|
|
1003
1056
|
]
|
|
@@ -1471,7 +1524,7 @@ function catalogReport(title, skills) {
|
|
|
1471
1524
|
};
|
|
1472
1525
|
}
|
|
1473
1526
|
// src/catalog/screens/browser.tsx
|
|
1474
|
-
import { Box as Box9, Text as Text11, useApp as useApp5, useInput as useInput5
|
|
1527
|
+
import { Box as Box9, Text as Text11, useApp as useApp5, useInput as useInput5 } from "ink";
|
|
1475
1528
|
import { useCallback as useCallback2, useEffect as useEffect6, useMemo as useMemo2, useState as useState7 } from "react";
|
|
1476
1529
|
|
|
1477
1530
|
// src/manifest/manifest.ts
|
|
@@ -1583,7 +1636,8 @@ import { createRequire } from "node:module";
|
|
|
1583
1636
|
import { dirname as dirname3, join as join5 } from "node:path";
|
|
1584
1637
|
function skillsAddArgv(location, opts = {}) {
|
|
1585
1638
|
const path = location.path.replace(/^\/+|\/+$/g, "");
|
|
1586
|
-
const
|
|
1639
|
+
const at = location.ref ? `#${location.ref}` : "";
|
|
1640
|
+
const spec = `${location.source}${path ? `/${path}` : ""}${at}`;
|
|
1587
1641
|
const argv = ["add", spec, "--yes"];
|
|
1588
1642
|
if (opts.scope !== "project")
|
|
1589
1643
|
argv.push("--global");
|
|
@@ -1662,7 +1716,7 @@ function manifestEntryFor(location, reached, bundle) {
|
|
|
1662
1716
|
return {
|
|
1663
1717
|
name: location.skillName,
|
|
1664
1718
|
externalId: location.externalId,
|
|
1665
|
-
ref: location.ref,
|
|
1719
|
+
ref: location.ref ?? "",
|
|
1666
1720
|
source: location.source,
|
|
1667
1721
|
path,
|
|
1668
1722
|
...bundle ? { bundle } : {},
|
|
@@ -1893,7 +1947,7 @@ async function adoptSkills(client, where, plan) {
|
|
|
1893
1947
|
if (event.kind === "installed")
|
|
1894
1948
|
outcome.adopted.push({
|
|
1895
1949
|
name: event.location.skillName,
|
|
1896
|
-
ref: event.location.ref
|
|
1950
|
+
ref: event.location.ref ?? ""
|
|
1897
1951
|
});
|
|
1898
1952
|
else if (event.kind === "failed")
|
|
1899
1953
|
outcome.failed.push({ name: event.name, message: event.message });
|
|
@@ -1932,7 +1986,7 @@ function importReport(nearest, plan, outcome) {
|
|
|
1932
1986
|
lines.push({
|
|
1933
1987
|
mark: "ok",
|
|
1934
1988
|
text: row.name.padEnd(width),
|
|
1935
|
-
note: `adopted at ${row.ref.slice(0, 7)}`
|
|
1989
|
+
note: row.ref ? `adopted at ${row.ref.slice(0, 7)}` : "adopted, unpinned"
|
|
1936
1990
|
});
|
|
1937
1991
|
for (const name of outcome.pending)
|
|
1938
1992
|
lines.push({
|
|
@@ -1988,7 +2042,8 @@ import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
|
1988
2042
|
|
|
1989
2043
|
// src/install/lines.ts
|
|
1990
2044
|
function where(location) {
|
|
1991
|
-
|
|
2045
|
+
const at = location.ref ? `@${location.ref.slice(0, 8)}` : " (unpinned)";
|
|
2046
|
+
return `${location.source}/${location.path}${at}`;
|
|
1992
2047
|
}
|
|
1993
2048
|
function put(lines, name, progress, deprecated = false) {
|
|
1994
2049
|
const at = lines.findIndex((l) => l.name === name);
|
|
@@ -2763,9 +2818,6 @@ function runFor(command, where, connect) {
|
|
|
2763
2818
|
// src/catalog/screens/browser.tsx
|
|
2764
2819
|
import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2765
2820
|
var TABS = ["bundles", "skills"];
|
|
2766
|
-
function pageSize(rows) {
|
|
2767
|
-
return Math.max(3, Math.min(20, rows - 11));
|
|
2768
|
-
}
|
|
2769
2821
|
function matches(row, query) {
|
|
2770
2822
|
if (query.length === 0)
|
|
2771
2823
|
return true;
|
|
@@ -2803,7 +2855,6 @@ function BrowserScreen({
|
|
|
2803
2855
|
}) {
|
|
2804
2856
|
const { exit } = useApp5();
|
|
2805
2857
|
const width = useFrameWidth();
|
|
2806
|
-
const { rows: terminalRows } = useWindowSize2();
|
|
2807
2858
|
const [catalog, setCatalog] = useState7(null);
|
|
2808
2859
|
const [tab, setTab] = useState7(initialTab);
|
|
2809
2860
|
const [query, setQuery] = useState7(initialQuery);
|
|
@@ -2846,6 +2897,11 @@ function BrowserScreen({
|
|
|
2846
2897
|
setCursor((c) => Math.max(0, Math.min(c, visible.length - 1)));
|
|
2847
2898
|
}, [visible.length]);
|
|
2848
2899
|
const selected = picked[tab];
|
|
2900
|
+
const { first, size } = useViewport({
|
|
2901
|
+
cursor,
|
|
2902
|
+
total: visible.length,
|
|
2903
|
+
chrome: 11
|
|
2904
|
+
});
|
|
2849
2905
|
const start = useCallback2(() => {
|
|
2850
2906
|
const names = selected.size > 0 ? [...selected] : visible[cursor] ? [visible[cursor].name] : [];
|
|
2851
2907
|
if (names.length === 0)
|
|
@@ -2861,9 +2917,9 @@ function BrowserScreen({
|
|
|
2861
2917
|
} else if (key.downArrow) {
|
|
2862
2918
|
setCursor((c) => Math.min(visible.length - 1, c + 1));
|
|
2863
2919
|
} else if (key.pageUp) {
|
|
2864
|
-
setCursor((c) => Math.max(0, c -
|
|
2920
|
+
setCursor((c) => Math.max(0, c - size));
|
|
2865
2921
|
} else if (key.pageDown) {
|
|
2866
|
-
setCursor((c) => Math.min(visible.length - 1, c +
|
|
2922
|
+
setCursor((c) => Math.min(visible.length - 1, c + size));
|
|
2867
2923
|
} else if (key.tab) {
|
|
2868
2924
|
setTab((t) => t === "bundles" ? "skills" : "bundles");
|
|
2869
2925
|
setCursor(0);
|
|
@@ -2921,9 +2977,7 @@ function BrowserScreen({
|
|
|
2921
2977
|
})
|
|
2922
2978
|
});
|
|
2923
2979
|
}
|
|
2924
|
-
const
|
|
2925
|
-
const first = Math.max(0, Math.min(cursor - Math.floor(size / 2), visible.length - size));
|
|
2926
|
-
const page = visible.slice(Math.max(0, first), Math.max(0, first) + size);
|
|
2980
|
+
const page = visible.slice(first, first + size);
|
|
2927
2981
|
const names = nameWidth(visible.length > 0 ? visible : catalog[tab]);
|
|
2928
2982
|
return /* @__PURE__ */ jsx13(Frame, {
|
|
2929
2983
|
title: "yourskills",
|
|
@@ -2960,7 +3014,7 @@ function BrowserScreen({
|
|
|
2960
3014
|
width: width - 2,
|
|
2961
3015
|
names,
|
|
2962
3016
|
selectable: true,
|
|
2963
|
-
cursor:
|
|
3017
|
+
cursor: first + i === cursor,
|
|
2964
3018
|
selected: selected.has(row.name)
|
|
2965
3019
|
}, row.name)),
|
|
2966
3020
|
/* @__PURE__ */ jsx13(Divider, {
|
|
@@ -2970,7 +3024,7 @@ function BrowserScreen({
|
|
|
2970
3024
|
children: [
|
|
2971
3025
|
/* @__PURE__ */ jsx13(Text11, {
|
|
2972
3026
|
dimColor: true,
|
|
2973
|
-
children:
|
|
3027
|
+
children: position(cursor, visible.length)
|
|
2974
3028
|
}),
|
|
2975
3029
|
selected.size > 0 ? /* @__PURE__ */ jsx13(Text11, {
|
|
2976
3030
|
color: tone.notice,
|
|
@@ -5754,7 +5808,7 @@ import { realpathSync } from "node:fs";
|
|
|
5754
5808
|
// package.json
|
|
5755
5809
|
var package_default = {
|
|
5756
5810
|
name: "yourskills",
|
|
5757
|
-
version: "0.
|
|
5811
|
+
version: "0.4.2",
|
|
5758
5812
|
description: "Browse, install and keep up to date the agent skills and bundles your team publishes on yourskills.",
|
|
5759
5813
|
license: "UNLICENSED",
|
|
5760
5814
|
homepage: "https://yourskills.store",
|
|
@@ -6934,6 +6988,7 @@ function noSuchPass(id, passes) {
|
|
|
6934
6988
|
};
|
|
6935
6989
|
}
|
|
6936
6990
|
// src/commands/facts.ts
|
|
6991
|
+
var NO_FEED = {};
|
|
6937
6992
|
function count2(n, one, many = `${one}s`) {
|
|
6938
6993
|
return `${n} ${n === 1 ? one : many}`;
|
|
6939
6994
|
}
|
|
@@ -7026,6 +7081,7 @@ var TABLE = {
|
|
|
7026
7081
|
value: "catalog.bundles",
|
|
7027
7082
|
label: "browse bundles",
|
|
7028
7083
|
hint: "browse",
|
|
7084
|
+
shows: (facts) => facts.feed.bundles === undefined ? "" : count2(facts.feed.bundles, "bundle"),
|
|
7029
7085
|
when: (facts) => facts.signedIn,
|
|
7030
7086
|
opens: { kind: "browse" }
|
|
7031
7087
|
}
|
|
@@ -7132,6 +7188,7 @@ var TABLE = {
|
|
|
7132
7188
|
value: "account.org",
|
|
7133
7189
|
label: "switch org",
|
|
7134
7190
|
hint: "org <name>",
|
|
7191
|
+
shows: (facts) => facts.feed.organizations === undefined ? "" : facts.feed.organizations <= 1 ? "only this one" : count2(facts.feed.organizations - 1, "other"),
|
|
7135
7192
|
when: (facts) => facts.signedIn,
|
|
7136
7193
|
says: (facts) => facts.organization ? `switch this machine out of ${facts.organization}` : "choose which organization this machine installs from"
|
|
7137
7194
|
}
|
|
@@ -7156,6 +7213,7 @@ var TABLE = {
|
|
|
7156
7213
|
value: "catalog.skills",
|
|
7157
7214
|
label: "browse skills",
|
|
7158
7215
|
hint: "list",
|
|
7216
|
+
shows: (facts) => facts.feed.skills === undefined ? "" : count2(facts.feed.skills, "skill"),
|
|
7159
7217
|
when: (facts) => facts.signedIn,
|
|
7160
7218
|
opens: { kind: "list" }
|
|
7161
7219
|
}
|
|
@@ -7333,6 +7391,7 @@ var TABLE = {
|
|
|
7333
7391
|
value: "installed.update",
|
|
7334
7392
|
label: "update all",
|
|
7335
7393
|
hint: "update --all",
|
|
7394
|
+
shows: (facts) => updateScope(facts.bundles, facts.loose),
|
|
7336
7395
|
when: (facts) => facts.skills > 0 && facts.signedIn,
|
|
7337
7396
|
opens: { kind: "update", all: true }
|
|
7338
7397
|
}
|
|
@@ -7422,6 +7481,7 @@ var TABLE = {
|
|
|
7422
7481
|
value: "installed.list",
|
|
7423
7482
|
label: "list installed",
|
|
7424
7483
|
hint: "installed",
|
|
7484
|
+
shows: (facts) => count2(facts.skills, "skill"),
|
|
7425
7485
|
when: (facts) => facts.skills > 0,
|
|
7426
7486
|
opens: { kind: "installed" }
|
|
7427
7487
|
}
|
|
@@ -7451,6 +7511,7 @@ var TABLE = {
|
|
|
7451
7511
|
value: "installed.outdated",
|
|
7452
7512
|
label: "outdated",
|
|
7453
7513
|
hint: "outdated",
|
|
7514
|
+
shows: (facts) => facts.feed.outdated === undefined ? "" : facts.feed.outdated === 0 ? "all current" : `${facts.feed.outdated} behind`,
|
|
7454
7515
|
when: (facts) => facts.skills > 0 && facts.signedIn,
|
|
7455
7516
|
opens: { kind: "outdated" }
|
|
7456
7517
|
}
|
|
@@ -7485,6 +7546,7 @@ var TABLE = {
|
|
|
7485
7546
|
value: "catalog.pending",
|
|
7486
7547
|
label: "waiting for a review",
|
|
7487
7548
|
hint: "pending",
|
|
7549
|
+
shows: (facts) => facts.feed.pending === undefined ? "" : facts.feed.pending === 0 ? "none open" : `${facts.feed.pending} open`,
|
|
7488
7550
|
when: (facts) => facts.signedIn,
|
|
7489
7551
|
opens: { kind: "pending" }
|
|
7490
7552
|
}
|
|
@@ -7591,20 +7653,21 @@ var TABLE = {
|
|
|
7591
7653
|
value: "setup.scope",
|
|
7592
7654
|
label: "scope",
|
|
7593
7655
|
hint: "config set scope project",
|
|
7594
|
-
|
|
7656
|
+
shows: (facts) => facts.scope,
|
|
7595
7657
|
says: (facts) => `where installs land: ${facts.scope} right now`
|
|
7596
7658
|
},
|
|
7597
7659
|
{
|
|
7598
7660
|
value: "setup.agents",
|
|
7599
7661
|
label: "agents",
|
|
7600
7662
|
hint: "config set agents <name>",
|
|
7601
|
-
|
|
7602
|
-
says: () => "which agents
|
|
7663
|
+
shows: (facts) => facts.agents.length > 0 ? count2(facts.agents.length, "agent") : "unset",
|
|
7664
|
+
says: (facts) => facts.agents.length > 0 ? `which agents an install writes for: ${facts.agents.join(", ")}` : "which agents an install writes for; nothing pinned, so `skills` looks"
|
|
7603
7665
|
},
|
|
7604
7666
|
{
|
|
7605
7667
|
value: "setup.explain",
|
|
7606
7668
|
label: "explain",
|
|
7607
7669
|
hint: "config get --explain",
|
|
7670
|
+
shows: (facts) => `${count2(facts.settings, "setting")} set`,
|
|
7608
7671
|
opens: { kind: "config", action: "get", explain: true }
|
|
7609
7672
|
}
|
|
7610
7673
|
],
|
|
@@ -7682,6 +7745,7 @@ var TABLE = {
|
|
|
7682
7745
|
value: "setup.upgrade",
|
|
7683
7746
|
label: "upgrade",
|
|
7684
7747
|
hint: "upgrade",
|
|
7748
|
+
shows: (facts) => facts.feed.upgrade === undefined ? "" : facts.feed.upgrade === null ? "up to date" : `${facts.feed.upgrade} is out`,
|
|
7685
7749
|
opens: { kind: "upgrade" }
|
|
7686
7750
|
}
|
|
7687
7751
|
],
|
|
@@ -7778,6 +7842,9 @@ function refuseCommand(command) {
|
|
|
7778
7842
|
code: EXIT.usage
|
|
7779
7843
|
});
|
|
7780
7844
|
}
|
|
7845
|
+
function doorShows(door, facts) {
|
|
7846
|
+
return door.shows?.(facts) ?? "";
|
|
7847
|
+
}
|
|
7781
7848
|
function doorSays(door, facts) {
|
|
7782
7849
|
if (door.opens === undefined)
|
|
7783
7850
|
return door.says(facts);
|
|
@@ -8079,13 +8146,19 @@ var PALETTE = [
|
|
|
8079
8146
|
]
|
|
8080
8147
|
}
|
|
8081
8148
|
];
|
|
8082
|
-
function item(door) {
|
|
8083
|
-
|
|
8149
|
+
function item(door, facts) {
|
|
8150
|
+
const shows = doorShows(door, facts);
|
|
8151
|
+
return {
|
|
8152
|
+
value: door.value,
|
|
8153
|
+
label: door.label,
|
|
8154
|
+
hint: door.hint,
|
|
8155
|
+
...shows ? { shows } : {}
|
|
8156
|
+
};
|
|
8084
8157
|
}
|
|
8085
8158
|
function paletteGroups(facts) {
|
|
8086
8159
|
const groups = [];
|
|
8087
8160
|
for (const place of PALETTE) {
|
|
8088
|
-
const items = place.doors.map((value) => DOORS[value]).filter((door) => door.when?.(facts) ?? true).map(item);
|
|
8161
|
+
const items = place.doors.map((value) => DOORS[value]).filter((door) => door.when?.(facts) ?? true).map((door) => item(door, facts));
|
|
8089
8162
|
if (items.length > 0)
|
|
8090
8163
|
groups.push({ group: place.group, items });
|
|
8091
8164
|
}
|
|
@@ -8113,13 +8186,59 @@ async function paletteFacts(scope, server) {
|
|
|
8113
8186
|
manifest: nearest.path,
|
|
8114
8187
|
skills,
|
|
8115
8188
|
bundles: Object.keys(nearest.manifest.bundles).length,
|
|
8116
|
-
loose: looseSkills(nearest.manifest).length
|
|
8189
|
+
loose: looseSkills(nearest.manifest).length,
|
|
8190
|
+
settings: CONFIG_KEYS.filter((key) => configValue(config, key) !== UNSET).length,
|
|
8191
|
+
feed: NO_FEED
|
|
8117
8192
|
};
|
|
8118
8193
|
}
|
|
8119
8194
|
// src/shell/screens/home.tsx
|
|
8120
8195
|
import { Box as Box14, Text as Text16, useApp as useApp7, useInput as useInput8 } from "ink";
|
|
8121
8196
|
import { useCallback as useCallback3, useEffect as useEffect9, useMemo as useMemo4, useRef, useState as useState11 } from "react";
|
|
8122
8197
|
|
|
8198
|
+
// src/shell/feed.ts
|
|
8199
|
+
async function feedFacts(client, where, server) {
|
|
8200
|
+
const installed = Object.keys(where.manifest.skills).length > 0;
|
|
8201
|
+
const [skills, bundles, passes, drift, orgs] = await Promise.allSettled([
|
|
8202
|
+
client.skills.list.query({}),
|
|
8203
|
+
client.bundles.list.query({}),
|
|
8204
|
+
client.mirror.passes.query(),
|
|
8205
|
+
installed ? driftNow(client, where) : Promise.resolve(null),
|
|
8206
|
+
organizationChoices(server)
|
|
8207
|
+
]);
|
|
8208
|
+
return {
|
|
8209
|
+
...skills.status === "fulfilled" ? { skills: skills.value.length } : {},
|
|
8210
|
+
...bundles.status === "fulfilled" ? { bundles: bundles.value.length } : {},
|
|
8211
|
+
...passes.status === "fulfilled" ? { pending: passes.value.length } : {},
|
|
8212
|
+
...drift.status === "fulfilled" && drift.value ? { outdated: drift.value.moved.length } : {},
|
|
8213
|
+
...orgs.status === "fulfilled" ? { organizations: orgs.value.length } : {}
|
|
8214
|
+
};
|
|
8215
|
+
}
|
|
8216
|
+
|
|
8217
|
+
// src/shell/probe.ts
|
|
8218
|
+
var importProbe = async (where) => {
|
|
8219
|
+
const found = await listInstalled(where.scope);
|
|
8220
|
+
const recorded = new Set(Object.keys(where.manifest.skills));
|
|
8221
|
+
const news = found.filter((skill) => !recorded.has(skill.name)).length;
|
|
8222
|
+
if (found.length === 0)
|
|
8223
|
+
return "nothing on this machine to adopt";
|
|
8224
|
+
return news === 0 ? `${count2(found.length, "skill")} on this machine, all recorded here already` : `${count2(found.length, "skill")} on this machine, ${news} not recorded here`;
|
|
8225
|
+
};
|
|
8226
|
+
var doctorProbe = async (where, server) => {
|
|
8227
|
+
const checks = await diagnose(where, {
|
|
8228
|
+
local: true,
|
|
8229
|
+
...server ? { server } : {}
|
|
8230
|
+
});
|
|
8231
|
+
const bad = checks.filter((check) => !check.ok);
|
|
8232
|
+
return bad.length === 0 ? `${count2(checks.length, "local check")}, all passing` : `${bad.length} of ${checks.length} local checks failing: ${bad.map((check) => check.name).join(", ")}`;
|
|
8233
|
+
};
|
|
8234
|
+
var PROBES = {
|
|
8235
|
+
"setup.import": importProbe,
|
|
8236
|
+
"setup.doctor": doctorProbe
|
|
8237
|
+
};
|
|
8238
|
+
function probeFor(value) {
|
|
8239
|
+
return value ? PROBES[value] : undefined;
|
|
8240
|
+
}
|
|
8241
|
+
|
|
8123
8242
|
// src/args.ts
|
|
8124
8243
|
function configCommand2(rest, explain) {
|
|
8125
8244
|
const [action, key, ...value] = rest;
|
|
@@ -8449,13 +8568,14 @@ function PickScreen({
|
|
|
8449
8568
|
verb,
|
|
8450
8569
|
single = false,
|
|
8451
8570
|
marked,
|
|
8571
|
+
preset,
|
|
8452
8572
|
onPick,
|
|
8453
8573
|
onBack
|
|
8454
8574
|
}) {
|
|
8455
8575
|
const width = useFrameWidth();
|
|
8456
8576
|
const [query, setQuery] = useState9("");
|
|
8457
8577
|
const [cursor, setCursor] = useState9(0);
|
|
8458
|
-
const [picked, setPicked] = useState9(new Set);
|
|
8578
|
+
const [picked, setPicked] = useState9(() => new Set(preset ?? []));
|
|
8459
8579
|
const visible = useMemo3(() => {
|
|
8460
8580
|
if (query.length === 0)
|
|
8461
8581
|
return rows;
|
|
@@ -8465,11 +8585,20 @@ function PickScreen({
|
|
|
8465
8585
|
useEffect8(() => {
|
|
8466
8586
|
setCursor((c) => Math.max(0, Math.min(c, visible.length - 1)));
|
|
8467
8587
|
}, [visible.length]);
|
|
8588
|
+
const { first, size } = useViewport({
|
|
8589
|
+
cursor,
|
|
8590
|
+
total: visible.length,
|
|
8591
|
+
chrome: 9
|
|
8592
|
+
});
|
|
8468
8593
|
useInput6((input, key) => {
|
|
8469
8594
|
if (key.upArrow) {
|
|
8470
8595
|
setCursor((c) => Math.max(0, c - 1));
|
|
8471
8596
|
} else if (key.downArrow) {
|
|
8472
8597
|
setCursor((c) => Math.min(visible.length - 1, c + 1));
|
|
8598
|
+
} else if (key.pageUp) {
|
|
8599
|
+
setCursor((c) => Math.max(0, c - size));
|
|
8600
|
+
} else if (key.pageDown) {
|
|
8601
|
+
setCursor((c) => Math.min(visible.length - 1, c + size));
|
|
8473
8602
|
} else if (key.return) {
|
|
8474
8603
|
const names = picked.size > 0 ? [...picked] : visible[cursor] ? [visible[cursor].name] : [];
|
|
8475
8604
|
if (names.length > 0)
|
|
@@ -8500,6 +8629,7 @@ function PickScreen({
|
|
|
8500
8629
|
}
|
|
8501
8630
|
});
|
|
8502
8631
|
const names = nameWidth(rows);
|
|
8632
|
+
const page = visible.slice(first, first + size);
|
|
8503
8633
|
return /* @__PURE__ */ jsx16(Frame, {
|
|
8504
8634
|
title,
|
|
8505
8635
|
width,
|
|
@@ -8527,12 +8657,12 @@ function PickScreen({
|
|
|
8527
8657
|
}) : visible.length === 0 ? /* @__PURE__ */ jsx16(Text14, {
|
|
8528
8658
|
dimColor: true,
|
|
8529
8659
|
children: `Nothing matches "${query}".`
|
|
8530
|
-
}) :
|
|
8660
|
+
}) : page.map((row, i) => /* @__PURE__ */ jsx16(SkillRow, {
|
|
8531
8661
|
row,
|
|
8532
8662
|
width: width - 2,
|
|
8533
8663
|
names,
|
|
8534
8664
|
selectable: true,
|
|
8535
|
-
cursor: i === cursor,
|
|
8665
|
+
cursor: first + i === cursor,
|
|
8536
8666
|
selected: single ? row.name === marked : picked.has(row.name)
|
|
8537
8667
|
}, row.name)),
|
|
8538
8668
|
/* @__PURE__ */ jsx16(Divider, {
|
|
@@ -8540,6 +8670,10 @@ function PickScreen({
|
|
|
8540
8670
|
}),
|
|
8541
8671
|
/* @__PURE__ */ jsxs14(Box12, {
|
|
8542
8672
|
children: [
|
|
8673
|
+
/* @__PURE__ */ jsx16(Text14, {
|
|
8674
|
+
dimColor: true,
|
|
8675
|
+
children: `${position(cursor, visible.length)} `
|
|
8676
|
+
}),
|
|
8543
8677
|
picked.size > 0 && !single ? /* @__PURE__ */ jsx16(Text14, {
|
|
8544
8678
|
color: tone.notice,
|
|
8545
8679
|
children: `${mark.selected} ${picked.size} marked `
|
|
@@ -8663,11 +8797,30 @@ function failure(title, error) {
|
|
|
8663
8797
|
json: { error: message }
|
|
8664
8798
|
};
|
|
8665
8799
|
}
|
|
8800
|
+
var HEAD_FLOOR = 14;
|
|
8801
|
+
var AGENTS_FLOOR = 9;
|
|
8802
|
+
function agentsIn(agents, room) {
|
|
8803
|
+
if (agents.length === 0)
|
|
8804
|
+
return "agents unset";
|
|
8805
|
+
const full = agents.join(",");
|
|
8806
|
+
if (full.length <= room)
|
|
8807
|
+
return full;
|
|
8808
|
+
for (let keep = agents.length - 1;keep > 0; keep--) {
|
|
8809
|
+
const text = `${agents.slice(0, keep).join(",")} +${agents.length - keep}`;
|
|
8810
|
+
if (text.length <= room)
|
|
8811
|
+
return text;
|
|
8812
|
+
}
|
|
8813
|
+
return `${agents.length} agents`;
|
|
8814
|
+
}
|
|
8666
8815
|
function AccountLine({ facts, width }) {
|
|
8667
|
-
const agents = facts.agents.length > 0 ? facts.agents.join(",") : "agents unset";
|
|
8668
|
-
const right = `${agents} ${facts.scope} ${facts.skills} installed`;
|
|
8669
8816
|
const head = facts.signedIn ? facts.email ?? "signed in" : "not signed in";
|
|
8670
|
-
const
|
|
8817
|
+
const stat = `${facts.scope} ${facts.skills} installed`;
|
|
8818
|
+
const inner = width - FRAME_CHROME;
|
|
8819
|
+
const spent = Math.min(head.length, 24) + 2 + stat.length + 4;
|
|
8820
|
+
const forAgents = inner - spent;
|
|
8821
|
+
const agents = forAgents >= AGENTS_FLOOR ? agentsIn(facts.agents, forAgents) : "";
|
|
8822
|
+
const right = agents ? `${agents} ${stat}` : stat;
|
|
8823
|
+
const room = Math.max(inner - right.length - 2, HEAD_FLOOR);
|
|
8671
8824
|
const tail = facts.signedIn ? ` ${hostOf(facts.server)}` : " — the catalog needs a session";
|
|
8672
8825
|
const org = facts.signedIn && facts.organization ? ` ${facts.organization}` : "";
|
|
8673
8826
|
const spare = room - 2 - head.length;
|
|
@@ -8699,7 +8852,7 @@ function AccountLine({ facts, width }) {
|
|
|
8699
8852
|
}),
|
|
8700
8853
|
/* @__PURE__ */ jsx18(Text16, {
|
|
8701
8854
|
dimColor: true,
|
|
8702
|
-
children: right
|
|
8855
|
+
children: clip(right, inner - room)
|
|
8703
8856
|
})
|
|
8704
8857
|
]
|
|
8705
8858
|
});
|
|
@@ -8715,7 +8868,9 @@ function StaleLine({ stale, width }) {
|
|
|
8715
8868
|
});
|
|
8716
8869
|
}
|
|
8717
8870
|
var RUN = "run";
|
|
8871
|
+
var REST_MS = 250;
|
|
8718
8872
|
var ASK_NPM = () => upgradeCheck();
|
|
8873
|
+
var ASK_REGISTRY = feedFacts;
|
|
8719
8874
|
var NO_EXIT_CODE = () => {
|
|
8720
8875
|
return;
|
|
8721
8876
|
};
|
|
@@ -8731,19 +8886,20 @@ function HomeScreen({
|
|
|
8731
8886
|
onWelcomed = async () => {
|
|
8732
8887
|
return;
|
|
8733
8888
|
},
|
|
8734
|
-
checkUpgrade = ASK_NPM
|
|
8889
|
+
checkUpgrade = ASK_NPM,
|
|
8890
|
+
loadFeed = ASK_REGISTRY,
|
|
8891
|
+
probes: probeSet = probeFor
|
|
8735
8892
|
}) {
|
|
8736
8893
|
const { exit } = useApp7();
|
|
8737
8894
|
const width = useFrameWidth();
|
|
8738
8895
|
const [facts, setFacts] = useState11(initial);
|
|
8739
8896
|
const [where, setWhere] = useState11(initialWhere);
|
|
8740
|
-
const groups = useMemo4(() => paletteGroups(facts), [facts]);
|
|
8741
8897
|
const [query, setQuery] = useState11("");
|
|
8742
8898
|
const [cursor, setCursor] = useState11(0);
|
|
8743
8899
|
const [route, setRoute] = useState11(null);
|
|
8744
8900
|
const [welcome, setWelcome] = useState11(initial.firstRun);
|
|
8745
8901
|
const [wizard, setWizard] = useState11(false);
|
|
8746
|
-
const [stale, setStale] = useState11(
|
|
8902
|
+
const [stale, setStale] = useState11(undefined);
|
|
8747
8903
|
useEffect9(() => {
|
|
8748
8904
|
let live = true;
|
|
8749
8905
|
checkUpgrade().then((found) => {
|
|
@@ -8756,6 +8912,17 @@ function HomeScreen({
|
|
|
8756
8912
|
live = false;
|
|
8757
8913
|
};
|
|
8758
8914
|
}, [checkUpgrade]);
|
|
8915
|
+
const [feed, setFeed] = useState11(NO_FEED);
|
|
8916
|
+
const [probes, setProbes] = useState11({});
|
|
8917
|
+
const [probing, setProbing] = useState11(null);
|
|
8918
|
+
const shown = useMemo4(() => ({
|
|
8919
|
+
...facts,
|
|
8920
|
+
feed: {
|
|
8921
|
+
...feed,
|
|
8922
|
+
...stale === undefined ? {} : { upgrade: stale ? stale.latest : null }
|
|
8923
|
+
}
|
|
8924
|
+
}), [facts, feed, stale]);
|
|
8925
|
+
const groups = useMemo4(() => paletteGroups(shown), [shown]);
|
|
8759
8926
|
const typed = useMemo4(() => typedCommand(query), [query]);
|
|
8760
8927
|
const visible = useMemo4(() => {
|
|
8761
8928
|
const filtered = filterCommands(groups, query);
|
|
@@ -8778,6 +8945,20 @@ function HomeScreen({
|
|
|
8778
8945
|
held.current ??= await openClient();
|
|
8779
8946
|
return held.current;
|
|
8780
8947
|
}, [openClient]);
|
|
8948
|
+
useEffect9(() => {
|
|
8949
|
+
if (!facts.signedIn)
|
|
8950
|
+
return;
|
|
8951
|
+
let live = true;
|
|
8952
|
+
connect().then((client) => loadFeed(client, where, server)).then((found) => {
|
|
8953
|
+
if (live)
|
|
8954
|
+
setFeed(found);
|
|
8955
|
+
}).catch(() => {
|
|
8956
|
+
return;
|
|
8957
|
+
});
|
|
8958
|
+
return () => {
|
|
8959
|
+
live = false;
|
|
8960
|
+
};
|
|
8961
|
+
}, [facts.signedIn, connect, loadFeed, where, server]);
|
|
8781
8962
|
const checkSession = useCallback3(async () => facts.signedIn, [facts.signedIn]);
|
|
8782
8963
|
const answering = useCallback3((title, working, load) => ({
|
|
8783
8964
|
kind: "report",
|
|
@@ -8873,6 +9054,52 @@ function HomeScreen({
|
|
|
8873
9054
|
verb: "remove",
|
|
8874
9055
|
command: (names) => ({ kind: "remove", names })
|
|
8875
9056
|
};
|
|
9057
|
+
case "setup.scope":
|
|
9058
|
+
return {
|
|
9059
|
+
kind: "pick",
|
|
9060
|
+
title: "scope",
|
|
9061
|
+
rows: [
|
|
9062
|
+
{
|
|
9063
|
+
name: "global",
|
|
9064
|
+
description: "installs land in your home directory, where every project sees them"
|
|
9065
|
+
},
|
|
9066
|
+
{
|
|
9067
|
+
name: "project",
|
|
9068
|
+
description: "installs land in this project's yourskills.json, and travel with the repo"
|
|
9069
|
+
}
|
|
9070
|
+
],
|
|
9071
|
+
empty: "",
|
|
9072
|
+
verb: "set",
|
|
9073
|
+
single: true,
|
|
9074
|
+
marked: facts.scope,
|
|
9075
|
+
command: (names) => ({
|
|
9076
|
+
kind: "config",
|
|
9077
|
+
action: "set",
|
|
9078
|
+
key: "scope",
|
|
9079
|
+
value: names[0] ?? ""
|
|
9080
|
+
})
|
|
9081
|
+
};
|
|
9082
|
+
case "setup.agents": {
|
|
9083
|
+
const valid = await knownAgents() ?? [];
|
|
9084
|
+
const onDisk = new Set(facts.agentsOnDisk);
|
|
9085
|
+
return {
|
|
9086
|
+
kind: "pick",
|
|
9087
|
+
title: "agents",
|
|
9088
|
+
rows: valid.map((name) => ({
|
|
9089
|
+
name,
|
|
9090
|
+
description: onDisk.has(name) ? "on this machine" : ""
|
|
9091
|
+
})),
|
|
9092
|
+
empty: "Could not ask the `skills` CLI which agent names it accepts. Run `yourskills doctor`.",
|
|
9093
|
+
verb: "set",
|
|
9094
|
+
preset: facts.agents,
|
|
9095
|
+
command: (names) => ({
|
|
9096
|
+
kind: "config",
|
|
9097
|
+
action: "set",
|
|
9098
|
+
key: "agents",
|
|
9099
|
+
value: names.join(",")
|
|
9100
|
+
})
|
|
9101
|
+
};
|
|
9102
|
+
}
|
|
8876
9103
|
case "account.org": {
|
|
8877
9104
|
const orgs = await organizationChoices(server);
|
|
8878
9105
|
const active = orgs.find((org) => org.active)?.name;
|
|
@@ -8891,7 +9118,7 @@ function HomeScreen({
|
|
|
8891
9118
|
};
|
|
8892
9119
|
}
|
|
8893
9120
|
}
|
|
8894
|
-
}, [where, server]);
|
|
9121
|
+
}, [where, server, facts]);
|
|
8895
9122
|
const routeForDoor = useCallback3(async (door) => door.opens === undefined ? ownRoute(door.value) : routeForCommand(door.opens), [ownRoute, routeForCommand]);
|
|
8896
9123
|
const open = useCallback3((pending, title) => {
|
|
8897
9124
|
pending.then((next) => {
|
|
@@ -8908,6 +9135,29 @@ function HomeScreen({
|
|
|
8908
9135
|
open(routeForCommand(parsed.command), parsed.text);
|
|
8909
9136
|
}, [open, routeForCommand]);
|
|
8910
9137
|
const current = rows[cursor];
|
|
9138
|
+
useEffect9(() => {
|
|
9139
|
+
const value = current?.value;
|
|
9140
|
+
const probe = probeSet(value);
|
|
9141
|
+
if (!value || !probe || probes[value] !== undefined)
|
|
9142
|
+
return;
|
|
9143
|
+
let live = true;
|
|
9144
|
+
const timer = setTimeout(() => {
|
|
9145
|
+
setProbing(value);
|
|
9146
|
+
probe(where, server).then((text) => {
|
|
9147
|
+
if (live)
|
|
9148
|
+
setProbes((was) => ({ ...was, [value]: text }));
|
|
9149
|
+
}).catch(() => {
|
|
9150
|
+
return;
|
|
9151
|
+
}).finally(() => {
|
|
9152
|
+
if (live)
|
|
9153
|
+
setProbing(null);
|
|
9154
|
+
});
|
|
9155
|
+
}, REST_MS);
|
|
9156
|
+
return () => {
|
|
9157
|
+
live = false;
|
|
9158
|
+
clearTimeout(timer);
|
|
9159
|
+
};
|
|
9160
|
+
}, [current?.value, probes, probeSet, where, server]);
|
|
8911
9161
|
const activate = useCallback3(() => {
|
|
8912
9162
|
const item = rows[cursor];
|
|
8913
9163
|
if (!item)
|
|
@@ -8934,6 +9184,7 @@ function HomeScreen({
|
|
|
8934
9184
|
setRoute(null);
|
|
8935
9185
|
setQuery("");
|
|
8936
9186
|
setCursor(0);
|
|
9187
|
+
setProbes({});
|
|
8937
9188
|
reload().then(setFacts).catch(() => {
|
|
8938
9189
|
return;
|
|
8939
9190
|
});
|
|
@@ -9049,6 +9300,7 @@ function HomeScreen({
|
|
|
9049
9300
|
verb: picked.verb,
|
|
9050
9301
|
...picked.single ? { single: true } : {},
|
|
9051
9302
|
...picked.marked ? { marked: picked.marked } : {},
|
|
9303
|
+
...picked.preset ? { preset: picked.preset } : {},
|
|
9052
9304
|
onPick: (names) => {
|
|
9053
9305
|
open(routeForCommand(picked.command(names)), picked.title);
|
|
9054
9306
|
},
|
|
@@ -9081,14 +9333,15 @@ function HomeScreen({
|
|
|
9081
9333
|
});
|
|
9082
9334
|
}
|
|
9083
9335
|
const highlighted = current ? doorFor(current.value) : undefined;
|
|
9084
|
-
const description = current?.value === RUN && runnable(typed) ? say(typed.command,
|
|
9336
|
+
const description = current?.value === RUN && runnable(typed) ? say(typed.command, shown) : highlighted ? doorSays(highlighted, shown) : typed ? say(typed.command, shown) : "";
|
|
9337
|
+
const found = current ? probes[current.value] ?? (probing === current.value ? "looking..." : "") : "";
|
|
9085
9338
|
const empty = typed?.command.kind === "error" && typed.command.next ? `${mark.fail} ${typed.command.message} try: ${typed.command.next.replace(/^yourskills /, "")}` : "No matching commands.";
|
|
9086
9339
|
return /* @__PURE__ */ jsxs16(Frame, {
|
|
9087
9340
|
title: "yourskills",
|
|
9088
9341
|
width,
|
|
9089
9342
|
children: [
|
|
9090
9343
|
/* @__PURE__ */ jsx18(AccountLine, {
|
|
9091
|
-
facts,
|
|
9344
|
+
facts: shown,
|
|
9092
9345
|
width
|
|
9093
9346
|
}),
|
|
9094
9347
|
stale ? /* @__PURE__ */ jsx18(StaleLine, {
|
|
@@ -9112,6 +9365,10 @@ function HomeScreen({
|
|
|
9112
9365
|
dimColor: true,
|
|
9113
9366
|
children: clip(description, width - FRAME_CHROME)
|
|
9114
9367
|
}),
|
|
9368
|
+
/* @__PURE__ */ jsx18(Text16, {
|
|
9369
|
+
dimColor: true,
|
|
9370
|
+
children: found ? clip(` ${found}`, width - FRAME_CHROME) : " "
|
|
9371
|
+
}),
|
|
9115
9372
|
/* @__PURE__ */ jsx18(Hints, {
|
|
9116
9373
|
hints: [
|
|
9117
9374
|
["^v", "move"],
|
package/package.json
CHANGED