dsh-skill-picker 0.5.13 → 0.5.15

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/lib/client.js CHANGED
@@ -25778,6 +25778,171 @@ function useWorkspaceCwd(props) {
25778
25778
  return typeof cwd === "string" ? cwd : "";
25779
25779
  }
25780
25780
 
25781
+ // src/client/slash-source.js
25782
+ var WRAPPED = "__dshSkillPickerWrappedCandidates";
25783
+ var SKILL_SOURCE = { trigger: "/", name: "skill" };
25784
+ function isSkillSourceWrapped(source) {
25785
+ return source !== null && typeof source === "object" && source[WRAPPED] === true;
25786
+ }
25787
+ var enhancementMode;
25788
+ function slashEnhancementMode() {
25789
+ return enhancementMode;
25790
+ }
25791
+ function isSkillSource(source) {
25792
+ return source !== null && typeof source === "object" && source.trigger === SKILL_SOURCE.trigger && source.name === SKILL_SOURCE.name;
25793
+ }
25794
+ function registryCandidates(service) {
25795
+ const lists = [];
25796
+ const push = (value) => {
25797
+ if (Array.isArray(value) && value.length > 0) lists.push(value);
25798
+ };
25799
+ try {
25800
+ push(service.live?.sources);
25801
+ } catch {
25802
+ }
25803
+ try {
25804
+ if (typeof service.sources === "function") push(service.sources(SKILL_SOURCE.trigger));
25805
+ } catch {
25806
+ }
25807
+ try {
25808
+ if (typeof service.all === "function") push(service.all());
25809
+ } catch {
25810
+ }
25811
+ try {
25812
+ push(service.sources);
25813
+ } catch {
25814
+ }
25815
+ try {
25816
+ if (typeof service.roster?.sources === "function") push(service.roster.sources(SKILL_SOURCE.trigger));
25817
+ } catch {
25818
+ }
25819
+ try {
25820
+ if (typeof service.roster?.all === "function") push(service.roster.all());
25821
+ } catch {
25822
+ }
25823
+ return lists;
25824
+ }
25825
+ function findSkillSource(service) {
25826
+ if (service === null || service === void 0) return void 0;
25827
+ for (const list of registryCandidates(service)) {
25828
+ const found = list.find(isSkillSource);
25829
+ if (found !== void 0) return found;
25830
+ }
25831
+ return void 0;
25832
+ }
25833
+ function wrapSkillSource(source, hooks = {}) {
25834
+ const { rank, order, onPick } = hooks;
25835
+ if (source === null || typeof source !== "object") return void 0;
25836
+ if (isSkillSourceWrapped(source)) return void 0;
25837
+ if (Object.isFrozen(source)) return void 0;
25838
+ const original = {
25839
+ candidates: source.candidates,
25840
+ order: source.order,
25841
+ hadOrder: Object.hasOwn(source, "order"),
25842
+ onPick: source.onPick,
25843
+ hadOnPick: Object.hasOwn(source, "onPick")
25844
+ };
25845
+ const taken = [];
25846
+ const wrappedCandidates = typeof rank === "function" && typeof original.candidates === "function" ? async function candidates(projection, args) {
25847
+ const options = args ?? {};
25848
+ const everything = await original.candidates.call(this, projection, { ...options, query: "" });
25849
+ const query = String(options.query ?? "").trim();
25850
+ if (query === "" || !Array.isArray(everything)) return everything;
25851
+ try {
25852
+ return rank(everything, query);
25853
+ } catch {
25854
+ return everything;
25855
+ }
25856
+ } : void 0;
25857
+ const wrappedPick = typeof onPick === "function" && typeof original.onPick === "function" ? function onPickWrapped(args) {
25858
+ try {
25859
+ const name = args?.candidate?.name;
25860
+ if (typeof name === "string") onPick(name);
25861
+ } catch {
25862
+ }
25863
+ return original.onPick.call(this, args);
25864
+ } : void 0;
25865
+ try {
25866
+ Object.defineProperty(source, WRAPPED, { value: true, enumerable: false, configurable: true });
25867
+ if (wrappedCandidates !== void 0) {
25868
+ source.candidates = wrappedCandidates;
25869
+ taken.push("candidates");
25870
+ }
25871
+ if (typeof order === "number" && source.order !== order) {
25872
+ source.order = order;
25873
+ taken.push("order");
25874
+ }
25875
+ if (wrappedPick !== void 0) {
25876
+ source.onPick = wrappedPick;
25877
+ taken.push("onPick");
25878
+ }
25879
+ } catch {
25880
+ try {
25881
+ delete source[WRAPPED];
25882
+ } catch {
25883
+ }
25884
+ return void 0;
25885
+ }
25886
+ if (taken.length === 0) {
25887
+ try {
25888
+ delete source[WRAPPED];
25889
+ } catch {
25890
+ }
25891
+ return void 0;
25892
+ }
25893
+ enhancementMode = "runtime";
25894
+ return () => {
25895
+ try {
25896
+ if (taken.includes("candidates")) source.candidates = original.candidates;
25897
+ if (taken.includes("order")) {
25898
+ if (original.hadOrder) source.order = original.order;
25899
+ else delete source.order;
25900
+ }
25901
+ if (taken.includes("onPick")) {
25902
+ if (original.hadOnPick) source.onPick = original.onPick;
25903
+ else delete source.onPick;
25904
+ }
25905
+ delete source[WRAPPED];
25906
+ enhancementMode = void 0;
25907
+ } catch {
25908
+ }
25909
+ };
25910
+ }
25911
+ function installSlashFuzzy(inputTriggers, hooks = {}, options = {}) {
25912
+ const maxAttempts = options.attempts ?? 40;
25913
+ const intervalMs = options.intervalMs ?? 250;
25914
+ let restore;
25915
+ let timer;
25916
+ let attempts = 0;
25917
+ let stopped = false;
25918
+ const attempt = () => {
25919
+ if (stopped || restore !== void 0) return;
25920
+ try {
25921
+ const source = findSkillSource(inputTriggers);
25922
+ if (source === void 0) {
25923
+ if (attempts++ < maxAttempts) {
25924
+ timer = setTimeout(attempt, intervalMs);
25925
+ } else {
25926
+ console.warn(`[dsh-skill-picker] / takeover: the official "skill" trigger source was not found after ${maxAttempts} attempts \u2014 the / menu keeps the official matcher. See https://github.com/a735624258/dsh-skill-picker/issues/14`);
25927
+ }
25928
+ return;
25929
+ }
25930
+ restore = wrapSkillSource(source, hooks) ?? (() => {
25931
+ });
25932
+ } catch {
25933
+ restore = () => {
25934
+ };
25935
+ }
25936
+ };
25937
+ attempt();
25938
+ return () => {
25939
+ stopped = true;
25940
+ if (timer !== void 0) clearTimeout(timer);
25941
+ restore?.();
25942
+ restore = void 0;
25943
+ };
25944
+ }
25945
+
25781
25946
  // src/client/index.jsx
25782
25947
  var import_jsx_runtime = require("react/jsx-runtime");
25783
25948
  var inject = ["slots", "connection", "sessions", "inputTriggers"];
@@ -25882,6 +26047,25 @@ function matchRank(skill, q) {
25882
26047
  if (py.includes(q)) return 3;
25883
26048
  return 4;
25884
26049
  }
26050
+ function rankPickerItems(items, query) {
26051
+ const ordered = groupByPinned(
26052
+ Array.isArray(items) ? items : [],
26053
+ loadUsage(),
26054
+ loadPinned()
26055
+ ).flatMap((group) => group.items);
26056
+ const q = String(query ?? "").trim().toLowerCase();
26057
+ if (q === "") return ordered;
26058
+ const order = new Map(ordered.map((skill, index) => [skill.name, index]));
26059
+ const targets = ordered.map((s) => ({
26060
+ s,
26061
+ search: `${s.name} ${s.description ?? ""} ${skillPinyinText(s.name, s.description ?? "")}`
26062
+ }));
26063
+ return fuzzysort_default.go(q, targets, {
26064
+ key: "search",
26065
+ limit: 30,
26066
+ threshold: -1e4
26067
+ }).filter((r) => r.score > 0).map((r) => r.obj.s).filter((s) => matchRank(s, q) < 4).sort((a, b) => matchRank(a, q) - matchRank(b, q) || (order.get(a.name) ?? 0) - (order.get(b.name) ?? 0));
26068
+ }
25885
26069
  var buttonStyle = {
25886
26070
  display: "inline-flex",
25887
26071
  alignItems: "center",
@@ -26238,7 +26422,15 @@ function SkillPickerButton(props) {
26238
26422
  ] }, group.title);
26239
26423
  });
26240
26424
  })() }),
26241
- source === "host" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: sourceBadgeStyle, title: "\u5B98\u65B9\u6280\u80FD API \u4E0D\u53EF\u7528\uFF0C\u5217\u8868\u6765\u81EA\u672C\u5730\u76EE\u5F55\u626B\u63CF\uFF08\u4E0E\u5B98\u65B9 / \u8865\u5168\u540C\u6E90\uFF09", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: sourceBadgeTextStyle, children: "\u672C\u5730\u626B\u63CF" }) })
26425
+ source === "host" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: sourceBadgeStyle, title: "\u5B98\u65B9\u6280\u80FD API \u4E0D\u53EF\u7528\uFF0C\u5217\u8868\u6765\u81EA\u672C\u5730\u76EE\u5F55\u626B\u63CF\uFF08\u4E0E\u5B98\u65B9 / \u8865\u5168\u540C\u6E90\uFF09", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: sourceBadgeTextStyle, children: "\u672C\u5730\u626B\u63CF" }) }),
26426
+ slashEnhancementMode() === "runtime" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
26427
+ "div",
26428
+ {
26429
+ style: sourceBadgeStyle,
26430
+ title: "`/` \u83DC\u5355\u7684\u6A21\u7CCA+\u62FC\u97F3\u641C\u7D22\u7531\u672C\u63D2\u4EF6\u5728\u8FD0\u884C\u65F6\u63A5\u7BA1\u5B98\u65B9\u6280\u80FD\u6E90\uFF08\u4E0D\u4F9D\u8D56\u6539\u5199\u4EFB\u4F55\u6587\u4EF6\uFF0Cissue #14\uFF09",
26431
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: sourceBadgeTextStyle, children: "/ \u589E\u5F3A\uFF1A\u8FD0\u884C\u65F6\u63A5\u7BA1" })
26432
+ }
26433
+ )
26242
26434
  ] })
26243
26435
  ] })
26244
26436
  ] });
@@ -26291,40 +26483,40 @@ function apply(ctx) {
26291
26483
  unsubscribeLegacyCwd();
26292
26484
  };
26293
26485
  }, "dsh-skill-picker: composer input slot");
26486
+ const trackPick = (name) => {
26487
+ const usage = loadUsage();
26488
+ const nextUsage = { ...usage, [name]: { count: (usage[name]?.count ?? 0) + 1, lastUsed: Date.now() } };
26489
+ saveUsage(nextUsage);
26490
+ try {
26491
+ window.dispatchEvent(new CustomEvent("dsh-skill-picker:usage-updated"));
26492
+ } catch {
26493
+ }
26494
+ };
26294
26495
  ctx.effect(() => {
26295
26496
  const fuzzyMatch = (skills, query = "") => {
26296
26497
  const visible = (Array.isArray(skills) ? skills : []).filter(isUserFacingSkill);
26297
- const ordered = groupByPinned(visible, loadUsage(), loadPinned()).flatMap((group) => group.items);
26298
- const q = String(query).trim().toLowerCase();
26299
- if (q === "") return ordered;
26300
- const rankByName = new Map(ordered.map((skill, index) => [skill.name, index]));
26301
- const targets = ordered.map((s) => ({
26302
- s,
26303
- search: `${s.name} ${s.description ?? ""} ${skillPinyinText(s.name, s.description ?? "")}`
26304
- }));
26305
- const results = fuzzysort_default.go(q, targets, {
26306
- key: "search",
26307
- limit: 30,
26308
- threshold: -1e4
26309
- });
26310
- return results.filter((r) => r.score > 0).map((r) => r.obj.s).filter((s) => matchRank(s, q) < 4).sort((a, b) => matchRank(a, q) - matchRank(b, q) || (rankByName.get(a.name) ?? 0) - (rankByName.get(b.name) ?? 0));
26498
+ return rankPickerItems(visible, query);
26311
26499
  };
26312
26500
  window.__dshSkillPickerFuzzy = fuzzyMatch;
26313
- const trackPick = (name) => {
26314
- const usage = loadUsage();
26315
- const nextUsage = { ...usage, [name]: { count: (usage[name]?.count ?? 0) + 1, lastUsed: Date.now() } };
26316
- saveUsage(nextUsage);
26317
- try {
26318
- window.dispatchEvent(new CustomEvent("dsh-skill-picker:usage-updated"));
26319
- } catch {
26320
- }
26321
- };
26322
26501
  window.__dshSkillPickerTrack = trackPick;
26323
26502
  return () => {
26324
26503
  if (window.__dshSkillPickerFuzzy === fuzzyMatch) delete window.__dshSkillPickerFuzzy;
26325
26504
  if (window.__dshSkillPickerTrack === trackPick) delete window.__dshSkillPickerTrack;
26326
26505
  };
26327
26506
  }, "dsh-skill-picker: fuzzy matcher for official / source");
26507
+ ctx.effect(() => {
26508
+ const inputTriggers = ctx.inputTriggers ?? ctx.get?.("inputTriggers");
26509
+ if (inputTriggers === void 0) return () => {
26510
+ };
26511
+ return installSlashFuzzy(inputTriggers, {
26512
+ // Rank the official display items ({name, description}) by the same rule
26513
+ // the bolt panel uses, so the two lists agree on order as well as match.
26514
+ rank: (items, query) => rankPickerItems(items, query),
26515
+ // `order: 2` (official) → `-1`: the skill group sorts above commands.
26516
+ order: -1,
26517
+ onPick: trackPick
26518
+ });
26519
+ }, "dsh-skill-picker: runtime takeover of the official / skill source");
26328
26520
  }
26329
26521
  return module.exports; } });
26330
26522
  //# sourceMappingURL=client.js.map