yourskills 0.4.0 → 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.
Files changed (2) hide show
  1. package/dist/main.js +75 -21
  2. 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,6 +941,20 @@ 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;
928
960
  var LABEL_CAP = 22;
@@ -969,6 +1001,7 @@ function CommandPalette({
969
1001
  query,
970
1002
  cursor,
971
1003
  width,
1004
+ chrome = 11,
972
1005
  placeholder = "type a command or search",
973
1006
  emptyMessage = "No matching commands."
974
1007
  }) {
@@ -977,6 +1010,12 @@ function CommandPalette({
977
1010
  const current = rows[cursor];
978
1011
  const interior = width - FRAME_CHROME;
979
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);
980
1019
  return /* @__PURE__ */ jsxs5(Box3, {
981
1020
  flexDirection: "column",
982
1021
  children: [
@@ -998,7 +1037,7 @@ function CommandPalette({
998
1037
  rows.length === 0 ? /* @__PURE__ */ jsx5(Text4, {
999
1038
  dimColor: true,
1000
1039
  children: emptyMessage
1001
- }) : visible.map((group, i) => /* @__PURE__ */ jsxs5(Box3, {
1040
+ }) : paged.map((group, i) => /* @__PURE__ */ jsxs5(Box3, {
1002
1041
  flexDirection: "column",
1003
1042
  children: [
1004
1043
  i > 0 ? /* @__PURE__ */ jsx5(Divider, {
@@ -1485,7 +1524,7 @@ function catalogReport(title, skills) {
1485
1524
  };
1486
1525
  }
1487
1526
  // src/catalog/screens/browser.tsx
1488
- import { Box as Box9, Text as Text11, useApp as useApp5, useInput as useInput5, useWindowSize as useWindowSize2 } from "ink";
1527
+ import { Box as Box9, Text as Text11, useApp as useApp5, useInput as useInput5 } from "ink";
1489
1528
  import { useCallback as useCallback2, useEffect as useEffect6, useMemo as useMemo2, useState as useState7 } from "react";
1490
1529
 
1491
1530
  // src/manifest/manifest.ts
@@ -1597,7 +1636,8 @@ import { createRequire } from "node:module";
1597
1636
  import { dirname as dirname3, join as join5 } from "node:path";
1598
1637
  function skillsAddArgv(location, opts = {}) {
1599
1638
  const path = location.path.replace(/^\/+|\/+$/g, "");
1600
- const spec = `${location.source}${path ? `/${path}` : ""}#${location.ref}`;
1639
+ const at = location.ref ? `#${location.ref}` : "";
1640
+ const spec = `${location.source}${path ? `/${path}` : ""}${at}`;
1601
1641
  const argv = ["add", spec, "--yes"];
1602
1642
  if (opts.scope !== "project")
1603
1643
  argv.push("--global");
@@ -1676,7 +1716,7 @@ function manifestEntryFor(location, reached, bundle) {
1676
1716
  return {
1677
1717
  name: location.skillName,
1678
1718
  externalId: location.externalId,
1679
- ref: location.ref,
1719
+ ref: location.ref ?? "",
1680
1720
  source: location.source,
1681
1721
  path,
1682
1722
  ...bundle ? { bundle } : {},
@@ -1907,7 +1947,7 @@ async function adoptSkills(client, where, plan) {
1907
1947
  if (event.kind === "installed")
1908
1948
  outcome.adopted.push({
1909
1949
  name: event.location.skillName,
1910
- ref: event.location.ref
1950
+ ref: event.location.ref ?? ""
1911
1951
  });
1912
1952
  else if (event.kind === "failed")
1913
1953
  outcome.failed.push({ name: event.name, message: event.message });
@@ -1946,7 +1986,7 @@ function importReport(nearest, plan, outcome) {
1946
1986
  lines.push({
1947
1987
  mark: "ok",
1948
1988
  text: row.name.padEnd(width),
1949
- note: `adopted at ${row.ref.slice(0, 7)}`
1989
+ note: row.ref ? `adopted at ${row.ref.slice(0, 7)}` : "adopted, unpinned"
1950
1990
  });
1951
1991
  for (const name of outcome.pending)
1952
1992
  lines.push({
@@ -2002,7 +2042,8 @@ import { useEffect as useEffect4, useState as useState5 } from "react";
2002
2042
 
2003
2043
  // src/install/lines.ts
2004
2044
  function where(location) {
2005
- return `${location.source}/${location.path}@${location.ref.slice(0, 8)}`;
2045
+ const at = location.ref ? `@${location.ref.slice(0, 8)}` : " (unpinned)";
2046
+ return `${location.source}/${location.path}${at}`;
2006
2047
  }
2007
2048
  function put(lines, name, progress, deprecated = false) {
2008
2049
  const at = lines.findIndex((l) => l.name === name);
@@ -2777,9 +2818,6 @@ function runFor(command, where, connect) {
2777
2818
  // src/catalog/screens/browser.tsx
2778
2819
  import { jsx as jsx13, jsxs as jsxs11 } from "react/jsx-runtime";
2779
2820
  var TABS = ["bundles", "skills"];
2780
- function pageSize(rows) {
2781
- return Math.max(3, Math.min(20, rows - 11));
2782
- }
2783
2821
  function matches(row, query) {
2784
2822
  if (query.length === 0)
2785
2823
  return true;
@@ -2817,7 +2855,6 @@ function BrowserScreen({
2817
2855
  }) {
2818
2856
  const { exit } = useApp5();
2819
2857
  const width = useFrameWidth();
2820
- const { rows: terminalRows } = useWindowSize2();
2821
2858
  const [catalog, setCatalog] = useState7(null);
2822
2859
  const [tab, setTab] = useState7(initialTab);
2823
2860
  const [query, setQuery] = useState7(initialQuery);
@@ -2860,6 +2897,11 @@ function BrowserScreen({
2860
2897
  setCursor((c) => Math.max(0, Math.min(c, visible.length - 1)));
2861
2898
  }, [visible.length]);
2862
2899
  const selected = picked[tab];
2900
+ const { first, size } = useViewport({
2901
+ cursor,
2902
+ total: visible.length,
2903
+ chrome: 11
2904
+ });
2863
2905
  const start = useCallback2(() => {
2864
2906
  const names = selected.size > 0 ? [...selected] : visible[cursor] ? [visible[cursor].name] : [];
2865
2907
  if (names.length === 0)
@@ -2875,9 +2917,9 @@ function BrowserScreen({
2875
2917
  } else if (key.downArrow) {
2876
2918
  setCursor((c) => Math.min(visible.length - 1, c + 1));
2877
2919
  } else if (key.pageUp) {
2878
- setCursor((c) => Math.max(0, c - pageSize(terminalRows)));
2920
+ setCursor((c) => Math.max(0, c - size));
2879
2921
  } else if (key.pageDown) {
2880
- setCursor((c) => Math.min(visible.length - 1, c + pageSize(terminalRows)));
2922
+ setCursor((c) => Math.min(visible.length - 1, c + size));
2881
2923
  } else if (key.tab) {
2882
2924
  setTab((t) => t === "bundles" ? "skills" : "bundles");
2883
2925
  setCursor(0);
@@ -2935,9 +2977,7 @@ function BrowserScreen({
2935
2977
  })
2936
2978
  });
2937
2979
  }
2938
- const size = pageSize(terminalRows);
2939
- const first = Math.max(0, Math.min(cursor - Math.floor(size / 2), visible.length - size));
2940
- const page = visible.slice(Math.max(0, first), Math.max(0, first) + size);
2980
+ const page = visible.slice(first, first + size);
2941
2981
  const names = nameWidth(visible.length > 0 ? visible : catalog[tab]);
2942
2982
  return /* @__PURE__ */ jsx13(Frame, {
2943
2983
  title: "yourskills",
@@ -2974,7 +3014,7 @@ function BrowserScreen({
2974
3014
  width: width - 2,
2975
3015
  names,
2976
3016
  selectable: true,
2977
- cursor: Math.max(0, first) + i === cursor,
3017
+ cursor: first + i === cursor,
2978
3018
  selected: selected.has(row.name)
2979
3019
  }, row.name)),
2980
3020
  /* @__PURE__ */ jsx13(Divider, {
@@ -2984,7 +3024,7 @@ function BrowserScreen({
2984
3024
  children: [
2985
3025
  /* @__PURE__ */ jsx13(Text11, {
2986
3026
  dimColor: true,
2987
- children: `${visible.length > 0 ? cursor + 1 : 0}/${visible.length}`
3027
+ children: position(cursor, visible.length)
2988
3028
  }),
2989
3029
  selected.size > 0 ? /* @__PURE__ */ jsx13(Text11, {
2990
3030
  color: tone.notice,
@@ -5768,7 +5808,7 @@ import { realpathSync } from "node:fs";
5768
5808
  // package.json
5769
5809
  var package_default = {
5770
5810
  name: "yourskills",
5771
- version: "0.4.0",
5811
+ version: "0.4.2",
5772
5812
  description: "Browse, install and keep up to date the agent skills and bundles your team publishes on yourskills.",
5773
5813
  license: "UNLICENSED",
5774
5814
  homepage: "https://yourskills.store",
@@ -8545,11 +8585,20 @@ function PickScreen({
8545
8585
  useEffect8(() => {
8546
8586
  setCursor((c) => Math.max(0, Math.min(c, visible.length - 1)));
8547
8587
  }, [visible.length]);
8588
+ const { first, size } = useViewport({
8589
+ cursor,
8590
+ total: visible.length,
8591
+ chrome: 9
8592
+ });
8548
8593
  useInput6((input, key) => {
8549
8594
  if (key.upArrow) {
8550
8595
  setCursor((c) => Math.max(0, c - 1));
8551
8596
  } else if (key.downArrow) {
8552
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));
8553
8602
  } else if (key.return) {
8554
8603
  const names = picked.size > 0 ? [...picked] : visible[cursor] ? [visible[cursor].name] : [];
8555
8604
  if (names.length > 0)
@@ -8580,6 +8629,7 @@ function PickScreen({
8580
8629
  }
8581
8630
  });
8582
8631
  const names = nameWidth(rows);
8632
+ const page = visible.slice(first, first + size);
8583
8633
  return /* @__PURE__ */ jsx16(Frame, {
8584
8634
  title,
8585
8635
  width,
@@ -8607,12 +8657,12 @@ function PickScreen({
8607
8657
  }) : visible.length === 0 ? /* @__PURE__ */ jsx16(Text14, {
8608
8658
  dimColor: true,
8609
8659
  children: `Nothing matches "${query}".`
8610
- }) : visible.map((row, i) => /* @__PURE__ */ jsx16(SkillRow, {
8660
+ }) : page.map((row, i) => /* @__PURE__ */ jsx16(SkillRow, {
8611
8661
  row,
8612
8662
  width: width - 2,
8613
8663
  names,
8614
8664
  selectable: true,
8615
- cursor: i === cursor,
8665
+ cursor: first + i === cursor,
8616
8666
  selected: single ? row.name === marked : picked.has(row.name)
8617
8667
  }, row.name)),
8618
8668
  /* @__PURE__ */ jsx16(Divider, {
@@ -8620,6 +8670,10 @@ function PickScreen({
8620
8670
  }),
8621
8671
  /* @__PURE__ */ jsxs14(Box12, {
8622
8672
  children: [
8673
+ /* @__PURE__ */ jsx16(Text14, {
8674
+ dimColor: true,
8675
+ children: `${position(cursor, visible.length)} `
8676
+ }),
8623
8677
  picked.size > 0 && !single ? /* @__PURE__ */ jsx16(Text14, {
8624
8678
  color: tone.notice,
8625
8679
  children: `${mark.selected} ${picked.size} marked `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yourskills",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Browse, install and keep up to date the agent skills and bundles your team publishes on yourskills.",
5
5
  "license": "UNLICENSED",
6
6
  "homepage": "https://yourskills.store",