@hasna/skills 0.1.13 → 0.1.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.
Files changed (207) hide show
  1. package/bin/index.js +1743 -420
  2. package/bin/mcp.js +791 -259
  3. package/dist/index.d.ts +5 -2
  4. package/dist/index.js +533 -75
  5. package/dist/lib/config.d.ts +27 -0
  6. package/dist/lib/config.test.d.ts +1 -0
  7. package/dist/lib/installer.d.ts +36 -2
  8. package/dist/lib/registry.d.ts +16 -0
  9. package/dist/lib/scheduler.d.ts +47 -0
  10. package/dist/types/api.d.ts +74 -0
  11. package/package.json +5 -2
  12. package/skills/_common/index.ts +4 -0
  13. package/skills/_common/vision.ts +374 -0
  14. package/skills/skill-academic-journal-matcher/bin/cli.ts +34 -0
  15. package/skills/skill-action-item-router/bin/cli.ts +34 -0
  16. package/skills/skill-ad-creative-generator/bin/cli.ts +34 -0
  17. package/skills/skill-advanced-math/bin/cli.ts +34 -0
  18. package/skills/skill-analyze-data/bin/cli.ts +19 -0
  19. package/skills/skill-anomaly-investigator/bin/cli.ts +34 -0
  20. package/skills/skill-api-test-suite/bin/cli.ts +34 -0
  21. package/skills/skill-apidocs/bin/cli.ts +87 -0
  22. package/skills/skill-audio-cleanup-lab/bin/cli.ts +6 -0
  23. package/skills/skill-audiobook-chapter-proofer/bin/cli.ts +34 -0
  24. package/skills/skill-banner-ad-suite/bin/cli.ts +34 -0
  25. package/skills/skill-benchmark-finder/bin/cli.ts +34 -0
  26. package/skills/skill-bio-sequence-tool/bin/cli.ts +34 -0
  27. package/skills/skill-blog-topic-cluster/bin/cli.ts +34 -0
  28. package/skills/skill-brand-style-guide/bin/cli.ts +19 -0
  29. package/skills/skill-brand-voice-audit/bin/cli.ts +34 -0
  30. package/skills/skill-budget-variance-analyzer/bin/cli.ts +6 -0
  31. package/skills/skill-businessactivity/bin/cli.ts +28 -0
  32. package/skills/skill-calendar-events/bin/cli.ts +34 -0
  33. package/skills/skill-campaign-metric-brief/bin/cli.ts +34 -0
  34. package/skills/skill-campaign-moodboard/bin/cli.ts +34 -0
  35. package/skills/skill-caption-style-stylist/bin/cli.ts +34 -0
  36. package/skills/skill-chemistry-calculator/bin/cli.ts +34 -0
  37. package/skills/skill-churn-risk-notifier/bin/cli.ts +34 -0
  38. package/skills/skill-citation-formatter/bin/cli.ts +34 -0
  39. package/skills/skill-classroom-newsletter-kit/bin/cli.ts +34 -0
  40. package/skills/skill-color-palette-harmonizer/bin/cli.ts +34 -0
  41. package/skills/skill-colorextract/SKILL.md +35 -0
  42. package/skills/skill-colorextract/bun.lock +102 -0
  43. package/skills/skill-colorextract/package.json +13 -0
  44. package/skills/skill-colorextract/src/index.ts +405 -0
  45. package/skills/skill-competitor-ad-analyzer/bin/cli.ts +34 -0
  46. package/skills/skill-compliance-copy-check/bin/cli.ts +34 -0
  47. package/skills/skill-compliance-report-pack/bin/cli.ts +34 -0
  48. package/skills/skill-compress-video/bin/cli.ts +19 -0
  49. package/skills/skill-consolelog/bin/cli.ts +884 -0
  50. package/skills/skill-contract-plainlanguage/bin/cli.ts +34 -0
  51. package/skills/skill-copytone-translator/bin/cli.ts +34 -0
  52. package/skills/skill-create-blog-article/bin/cli.ts +34 -0
  53. package/skills/skill-create-ebook/bin/cli.ts +34 -0
  54. package/skills/skill-crm-note-enhancer/bin/cli.ts +34 -0
  55. package/skills/skill-customer-journey-mapper/bin/cli.ts +34 -0
  56. package/skills/skill-dashboard-builder/bin/cli.ts +34 -0
  57. package/skills/skill-dashboard-narrator/bin/cli.ts +34 -0
  58. package/skills/skill-data-anonymizer/bin/cli.ts +34 -0
  59. package/skills/skill-database-explorer/bin/cli.ts +34 -0
  60. package/skills/skill-dataset-health-check/bin/cli.ts +34 -0
  61. package/skills/skill-decision-journal/bin/cli.ts +34 -0
  62. package/skills/skill-delegation-brief-writer/bin/cli.ts +34 -0
  63. package/skills/skill-destination-briefing/bin/cli.ts +34 -0
  64. package/skills/skill-diff-viewer/bin/cli.ts +34 -0
  65. package/skills/skill-domainpurchase/SKILL.md +46 -0
  66. package/skills/skill-domainpurchase/bin/cli.ts +683 -0
  67. package/skills/skill-domainsearch/SKILL.md +41 -0
  68. package/skills/skill-domainsearch/bin/cli.ts +410 -0
  69. package/skills/skill-educational-resource-finder/bin/cli.ts +34 -0
  70. package/skills/skill-email-campaign/bin/cli.ts +34 -0
  71. package/skills/skill-exam-readiness-check/bin/cli.ts +34 -0
  72. package/skills/skill-experiment-power-calculator/bin/cli.ts +34 -0
  73. package/skills/skill-extract-audio/bin/cli.ts +19 -0
  74. package/skills/skill-extract-frames/bin/cli.ts +34 -0
  75. package/skills/skill-extract-invoice/bin/cli.ts +34 -0
  76. package/skills/skill-family-activity-curator/bin/cli.ts +34 -0
  77. package/skills/skill-faq-packager/bin/cli.ts +34 -0
  78. package/skills/skill-feedback-survey-designer/bin/cli.ts +34 -0
  79. package/skills/skill-field-trip-planner/bin/cli.ts +34 -0
  80. package/skills/skill-file-organizer/bin/cli.ts +34 -0
  81. package/skills/skill-folder-tree/bin/cli.ts +34 -0
  82. package/skills/skill-forecast-scenario-lab/bin/cli.ts +34 -0
  83. package/skills/skill-form-filler/bin/cli.ts +34 -0
  84. package/skills/skill-generate-api-client/bin/cli.ts +34 -0
  85. package/skills/skill-generate-book-cover/bin/cli.ts +34 -0
  86. package/skills/skill-generate-chart/bin/cli.ts +34 -0
  87. package/skills/skill-generate-diagram/bin/cli.ts +34 -0
  88. package/skills/skill-generate-dockerfile/bin/cli.ts +34 -0
  89. package/skills/skill-generate-documentation/bin/cli.ts +34 -0
  90. package/skills/skill-generate-docx/bin/cli.ts +6 -0
  91. package/skills/skill-generate-env/bin/cli.ts +34 -0
  92. package/skills/skill-generate-excel/bin/cli.ts +34 -0
  93. package/skills/skill-generate-favicon/bin/cli.ts +34 -0
  94. package/skills/skill-generate-mock-data/bin/cli.ts +34 -0
  95. package/skills/skill-generate-pdf/bin/cli.ts +6 -0
  96. package/skills/skill-generate-pr-description/bin/cli.ts +34 -0
  97. package/skills/skill-generate-presentation/bin/cli.ts +34 -0
  98. package/skills/skill-generate-qrcode/bin/cli.ts +34 -0
  99. package/skills/skill-generate-regex/bin/cli.ts +34 -0
  100. package/skills/skill-generate-resume/bin/cli.ts +34 -0
  101. package/skills/skill-generate-sitemap/bin/cli.ts +34 -0
  102. package/skills/skill-generate-social-posts/bin/cli.ts +34 -0
  103. package/skills/skill-generate-sql/bin/cli.ts +34 -0
  104. package/skills/skill-gif-maker/bin/cli.ts +34 -0
  105. package/skills/skill-github-manager/bin/cli.ts +34 -0
  106. package/skills/skill-gmail/bin/cli.ts +34 -0
  107. package/skills/skill-goal-quarterly-roadmap/bin/cli.ts +34 -0
  108. package/skills/skill-grant-application-drafter/bin/cli.ts +34 -0
  109. package/skills/skill-grocery-basket-optimizer/bin/cli.ts +34 -0
  110. package/skills/skill-guest-communication-suite/bin/cli.ts +34 -0
  111. package/skills/skill-habit-reflection-digest/bin/cli.ts +34 -0
  112. package/skills/skill-highlight-reel-generator/bin/cli.ts +34 -0
  113. package/skills/skill-homework-feedback-coach/bin/cli.ts +34 -0
  114. package/skills/skill-hook/bunfig.toml +5 -0
  115. package/skills/skill-household-maintenance-mgr/bin/cli.ts +34 -0
  116. package/skills/skill-http-server/bin/cli.ts +34 -0
  117. package/skills/skill-implementation/bunfig.toml +5 -0
  118. package/skills/skill-implementation-agent/bin/cli.ts +34 -0
  119. package/skills/skill-implementation-plan/bin/cli.ts +34 -0
  120. package/skills/skill-implementation-todo/bin/cli.ts +34 -0
  121. package/skills/skill-inbox-priority-planner/bin/cli.ts +34 -0
  122. package/skills/skill-invoice/bin/cli.ts +20 -0
  123. package/skills/skill-invoice-dispute-helper/bin/cli.ts +34 -0
  124. package/skills/skill-itinerary-architect/bin/cli.ts +34 -0
  125. package/skills/skill-jingle-composer/bin/cli.ts +34 -0
  126. package/skills/skill-kpi-digest-generator/bin/cli.ts +34 -0
  127. package/skills/skill-lab-notebook-formatter/bin/cli.ts +34 -0
  128. package/skills/skill-landing-page-copy/bin/cli.ts +34 -0
  129. package/skills/skill-latex-table-generator/bin/cli.ts +34 -0
  130. package/skills/skill-learning-style-profiler/bin/cli.ts +34 -0
  131. package/skills/skill-lesson-plan-customizer/bin/cli.ts +34 -0
  132. package/skills/skill-livestream-runofshow/bin/cli.ts +34 -0
  133. package/skills/skill-longform-structurer/bin/cli.ts +34 -0
  134. package/skills/skill-lorem-generator/bin/cli.ts +34 -0
  135. package/skills/skill-managehook/bin/cli.ts +241 -0
  136. package/skills/skill-managemcp/bin/cli.ts +241 -0
  137. package/skills/skill-manageskill/bin/cli.ts +241 -0
  138. package/skills/skill-markdown-validator/bin/cli.ts +34 -0
  139. package/skills/skill-mcp-builder/bin/cli.ts +34 -0
  140. package/skills/skill-meal-plan-designer/bin/cli.ts +34 -0
  141. package/skills/skill-meeting-insight-summarizer/bin/cli.ts +34 -0
  142. package/skills/skill-merge-pdfs/bin/cli.ts +34 -0
  143. package/skills/skill-microcopy-generator/bin/cli.ts +34 -0
  144. package/skills/skill-mindfulness-prompt-cache/bin/cli.ts +34 -0
  145. package/skills/skill-notion-manager/bin/cli.ts +34 -0
  146. package/skills/skill-onboarding-sequence-builder/bin/cli.ts +34 -0
  147. package/skills/skill-onsite-ops-checklist/bin/cli.ts +34 -0
  148. package/skills/skill-outreach-cadence-designer/bin/cli.ts +34 -0
  149. package/skills/skill-packaging-concept-studio/bin/cli.ts +34 -0
  150. package/skills/skill-packing-plan-pro/bin/cli.ts +34 -0
  151. package/skills/skill-parent-teacher-brief/bin/cli.ts +34 -0
  152. package/skills/skill-partner-kit-assembler/bin/cli.ts +34 -0
  153. package/skills/skill-payroll-change-prepper/bin/cli.ts +34 -0
  154. package/skills/skill-persona-based-adwriter/bin/cli.ts +34 -0
  155. package/skills/skill-persona-generator/bin/cli.ts +34 -0
  156. package/skills/skill-personal-daily-ops/bin/cli.ts +34 -0
  157. package/skills/skill-pet-care-scheduler/bin/cli.ts +34 -0
  158. package/skills/skill-podcast-show-notes/bin/cli.ts +34 -0
  159. package/skills/skill-presentation-theme-maker/bin/cli.ts +34 -0
  160. package/skills/skill-press-release-drafter/bin/cli.ts +34 -0
  161. package/skills/skill-print-collateral-designer/bin/cli.ts +34 -0
  162. package/skills/skill-procurement-scorecard/bin/cli.ts +34 -0
  163. package/skills/skill-product-demo-script/bin/cli.ts +34 -0
  164. package/skills/skill-product-mockup/bin/cli.ts +34 -0
  165. package/skills/skill-project-retro-companion/bin/cli.ts +34 -0
  166. package/skills/skill-proposal-redline-advisor/bin/cli.ts +34 -0
  167. package/skills/skill-regex-tester/bin/cli.ts +34 -0
  168. package/skills/skill-remove-background/bin/cli.ts +34 -0
  169. package/skills/skill-risk-disclosure-kit/bin/cli.ts +34 -0
  170. package/skills/skill-roi-comparison-tool/bin/cli.ts +34 -0
  171. package/skills/skill-sales-call-recapper/bin/cli.ts +34 -0
  172. package/skills/skill-salescopy/bin/cli.ts +20 -0
  173. package/skills/skill-scaffold-project/bin/cli.ts +34 -0
  174. package/skills/skill-scholarship-tracker/bin/cli.ts +34 -0
  175. package/skills/skill-scientific-figure-check/bin/cli.ts +34 -0
  176. package/skills/skill-seating-chart-maker/bin/cli.ts +34 -0
  177. package/skills/skill-security-audit/bin/cli.ts +34 -0
  178. package/skills/skill-seo-brief-builder/bin/cli.ts +34 -0
  179. package/skills/skill-siteanalyze/SKILL.md +25 -0
  180. package/skills/skill-siteanalyze/package.json +13 -0
  181. package/skills/skill-siteanalyze/src/index.ts +592 -0
  182. package/skills/skill-slack-assistant/bin/cli.ts +34 -0
  183. package/skills/skill-sleep-routine-analyzer/bin/cli.ts +34 -0
  184. package/skills/skill-social-media-kit/bin/cli.ts +34 -0
  185. package/skills/skill-split-pdf/bin/cli.ts +34 -0
  186. package/skills/skill-sponsorship-proposal-lab/bin/cli.ts +34 -0
  187. package/skills/skill-spreadsheet-cleanroom/bin/cli.ts +34 -0
  188. package/skills/skill-statistical-test-selector/bin/cli.ts +34 -0
  189. package/skills/skill-stress-relief-playbook/bin/cli.ts +34 -0
  190. package/skills/skill-study-guide-builder/bin/cli.ts +34 -0
  191. package/skills/skill-subscription-spend-watcher/bin/cli.ts +34 -0
  192. package/skills/skill-subtitle/bin/cli.ts +20 -0
  193. package/skills/skill-survey-insight-extractor/bin/cli.ts +34 -0
  194. package/skills/skill-terraform-generator/bin/cli.ts +34 -0
  195. package/skills/skill-testimonial-graphics/bin/cli.ts +34 -0
  196. package/skills/skill-timesheet/bin/cli.ts +47 -0
  197. package/skills/skill-travel-budget-balancer/bin/cli.ts +34 -0
  198. package/skills/skill-validate-config/bin/cli.ts +34 -0
  199. package/skills/skill-video-cut-suggester/bin/cli.ts +34 -0
  200. package/skills/skill-video-downloader/bin/cli.ts +34 -0
  201. package/skills/skill-video-thumbnail/bin/cli.ts +34 -0
  202. package/skills/skill-voiceover-casting-assistant/bin/cli.ts +34 -0
  203. package/skills/skill-watermark/bin/cli.ts +34 -0
  204. package/skills/skill-webcrawling/bin/cli.ts +21 -0
  205. package/skills/skill-webinar-script-coach/bin/cli.ts +34 -0
  206. package/skills/skill-wellness-progress-reporter/bin/cli.ts +34 -0
  207. package/skills/skill-workout-cycle-planner/bin/cli.ts +34 -0
package/bin/mcp.js CHANGED
@@ -5,27 +5,46 @@ var __getProtoOf = Object.getPrototypeOf;
5
5
  var __defProp = Object.defineProperty;
6
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ function __accessProp(key) {
9
+ return this[key];
10
+ }
11
+ var __toESMCache_node;
12
+ var __toESMCache_esm;
8
13
  var __toESM = (mod, isNodeMode, target) => {
14
+ var canCache = mod != null && typeof mod === "object";
15
+ if (canCache) {
16
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
17
+ var cached = cache.get(mod);
18
+ if (cached)
19
+ return cached;
20
+ }
9
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
10
22
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
11
23
  for (let key of __getOwnPropNames(mod))
12
24
  if (!__hasOwnProp.call(to, key))
13
25
  __defProp(to, key, {
14
- get: () => mod[key],
26
+ get: __accessProp.bind(mod, key),
15
27
  enumerable: true
16
28
  });
29
+ if (canCache)
30
+ cache.set(mod, to);
17
31
  return to;
18
32
  };
19
33
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
34
+ var __returnValue = (v) => v;
35
+ function __exportSetter(name, newValue) {
36
+ this[name] = __returnValue.bind(null, newValue);
37
+ }
20
38
  var __export = (target, all) => {
21
39
  for (var name in all)
22
40
  __defProp(target, name, {
23
41
  get: all[name],
24
42
  enumerable: true,
25
43
  configurable: true,
26
- set: (newValue) => all[name] = () => newValue
44
+ set: __exportSetter.bind(all, name)
27
45
  });
28
46
  };
47
+ var __require = import.meta.require;
29
48
 
30
49
  // node_modules/ajv/dist/compile/codegen/code.js
31
50
  var require_code = __commonJS((exports) => {
@@ -6277,7 +6296,7 @@ var require_formats = __commonJS((exports) => {
6277
6296
  }
6278
6297
  var TIME = /^(\d\d):(\d\d):(\d\d(?:\.\d+)?)(z|([+-])(\d\d)(?::?(\d\d))?)?$/i;
6279
6298
  function getTime(strictTimeZone) {
6280
- return function time(str) {
6299
+ return function time3(str) {
6281
6300
  const matches = TIME.exec(str);
6282
6301
  if (!matches)
6283
6302
  return false;
@@ -6490,7 +6509,7 @@ var require_dist = __commonJS((exports, module) => {
6490
6509
  exports.default = formatsPlugin;
6491
6510
  });
6492
6511
 
6493
- // node_modules/zod/v3/helpers/util.js
6512
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/helpers/util.js
6494
6513
  var util;
6495
6514
  (function(util2) {
6496
6515
  util2.assertEqual = (_) => {};
@@ -6621,7 +6640,7 @@ var getParsedType = (data) => {
6621
6640
  }
6622
6641
  };
6623
6642
 
6624
- // node_modules/zod/v3/ZodError.js
6643
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/ZodError.js
6625
6644
  var ZodIssueCode = util.arrayToEnum([
6626
6645
  "invalid_type",
6627
6646
  "invalid_literal",
@@ -6735,7 +6754,7 @@ ZodError.create = (issues) => {
6735
6754
  return error;
6736
6755
  };
6737
6756
 
6738
- // node_modules/zod/v3/locales/en.js
6757
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/locales/en.js
6739
6758
  var errorMap = (issue, _ctx) => {
6740
6759
  let message;
6741
6760
  switch (issue.code) {
@@ -6838,13 +6857,13 @@ var errorMap = (issue, _ctx) => {
6838
6857
  };
6839
6858
  var en_default = errorMap;
6840
6859
 
6841
- // node_modules/zod/v3/errors.js
6860
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/errors.js
6842
6861
  var overrideErrorMap = en_default;
6843
6862
  function getErrorMap() {
6844
6863
  return overrideErrorMap;
6845
6864
  }
6846
6865
 
6847
- // node_modules/zod/v3/helpers/parseUtil.js
6866
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/helpers/parseUtil.js
6848
6867
  var makeIssue = (params) => {
6849
6868
  const { data, path, errorMaps, issueData } = params;
6850
6869
  const fullPath = [...path, ...issueData.path || []];
@@ -6950,14 +6969,14 @@ var isDirty = (x) => x.status === "dirty";
6950
6969
  var isValid = (x) => x.status === "valid";
6951
6970
  var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
6952
6971
 
6953
- // node_modules/zod/v3/helpers/errorUtil.js
6972
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/helpers/errorUtil.js
6954
6973
  var errorUtil;
6955
6974
  (function(errorUtil2) {
6956
6975
  errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
6957
6976
  errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
6958
6977
  })(errorUtil || (errorUtil = {}));
6959
6978
 
6960
- // node_modules/zod/v3/types.js
6979
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v3/types.js
6961
6980
  class ParseInputLazyPath {
6962
6981
  constructor(parent, value, path, key) {
6963
6982
  this._cachedPath = [];
@@ -10301,7 +10320,7 @@ var nullableType = ZodNullable.create;
10301
10320
  var preprocessType = ZodEffects.createWithPreprocess;
10302
10321
  var pipelineType = ZodPipeline.create;
10303
10322
 
10304
- // node_modules/zod/v4/core/index.js
10323
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/index.js
10305
10324
  var exports_core2 = {};
10306
10325
  __export(exports_core2, {
10307
10326
  version: () => version,
@@ -10579,7 +10598,7 @@ __export(exports_core2, {
10579
10598
  $ZodAny: () => $ZodAny
10580
10599
  });
10581
10600
 
10582
- // node_modules/zod/v4/core/core.js
10601
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/core.js
10583
10602
  var NEVER = Object.freeze({
10584
10603
  status: "aborted"
10585
10604
  });
@@ -10655,7 +10674,7 @@ function config(newConfig) {
10655
10674
  Object.assign(globalConfig, newConfig);
10656
10675
  return globalConfig;
10657
10676
  }
10658
- // node_modules/zod/v4/core/util.js
10677
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/util.js
10659
10678
  var exports_util = {};
10660
10679
  __export(exports_util, {
10661
10680
  unwrapMessage: () => unwrapMessage,
@@ -11329,7 +11348,7 @@ class Class {
11329
11348
  constructor(..._args) {}
11330
11349
  }
11331
11350
 
11332
- // node_modules/zod/v4/core/errors.js
11351
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/errors.js
11333
11352
  var initializer = (inst, def) => {
11334
11353
  inst.name = "$ZodError";
11335
11354
  Object.defineProperty(inst, "_zod", {
@@ -11466,7 +11485,7 @@ function prettifyError(error) {
11466
11485
  `);
11467
11486
  }
11468
11487
 
11469
- // node_modules/zod/v4/core/parse.js
11488
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/parse.js
11470
11489
  var _parse = (_Err) => (schema, value, _ctx, _params) => {
11471
11490
  const ctx = _ctx ? Object.assign(_ctx, { async: false }) : { async: false };
11472
11491
  const result = schema._zod.run({ value, issues: [] }, ctx);
@@ -11553,7 +11572,7 @@ var _safeDecodeAsync = (_Err) => async (schema, value, _ctx) => {
11553
11572
  return _safeParseAsync(_Err)(schema, value, _ctx);
11554
11573
  };
11555
11574
  var safeDecodeAsync = /* @__PURE__ */ _safeDecodeAsync($ZodRealError);
11556
- // node_modules/zod/v4/core/regexes.js
11575
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/regexes.js
11557
11576
  var exports_regexes = {};
11558
11577
  __export(exports_regexes, {
11559
11578
  xid: () => xid,
@@ -11710,7 +11729,7 @@ var sha512_hex = /^[0-9a-fA-F]{128}$/;
11710
11729
  var sha512_base64 = /* @__PURE__ */ fixedBase64(86, "==");
11711
11730
  var sha512_base64url = /* @__PURE__ */ fixedBase64url(86);
11712
11731
 
11713
- // node_modules/zod/v4/core/checks.js
11732
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/checks.js
11714
11733
  var $ZodCheck = /* @__PURE__ */ $constructor("$ZodCheck", (inst, def) => {
11715
11734
  var _a;
11716
11735
  inst._zod ?? (inst._zod = {});
@@ -12257,7 +12276,7 @@ var $ZodCheckOverwrite = /* @__PURE__ */ $constructor("$ZodCheckOverwrite", (ins
12257
12276
  };
12258
12277
  });
12259
12278
 
12260
- // node_modules/zod/v4/core/doc.js
12279
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/doc.js
12261
12280
  class Doc {
12262
12281
  constructor(args = []) {
12263
12282
  this.content = [];
@@ -12295,14 +12314,14 @@ class Doc {
12295
12314
  }
12296
12315
  }
12297
12316
 
12298
- // node_modules/zod/v4/core/versions.js
12317
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/versions.js
12299
12318
  var version = {
12300
12319
  major: 4,
12301
12320
  minor: 3,
12302
12321
  patch: 6
12303
12322
  };
12304
12323
 
12305
- // node_modules/zod/v4/core/schemas.js
12324
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/schemas.js
12306
12325
  var $ZodType = /* @__PURE__ */ $constructor("$ZodType", (inst, def) => {
12307
12326
  var _a;
12308
12327
  inst ?? (inst = {});
@@ -14264,7 +14283,7 @@ function handleRefineResult(result, payload, input, inst) {
14264
14283
  payload.issues.push(issue(_iss));
14265
14284
  }
14266
14285
  }
14267
- // node_modules/zod/v4/locales/index.js
14286
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/index.js
14268
14287
  var exports_locales = {};
14269
14288
  __export(exports_locales, {
14270
14289
  zhTW: () => zh_TW_default,
@@ -14318,7 +14337,7 @@ __export(exports_locales, {
14318
14337
  ar: () => ar_default
14319
14338
  });
14320
14339
 
14321
- // node_modules/zod/v4/locales/ar.js
14340
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ar.js
14322
14341
  var error = () => {
14323
14342
  const Sizable = {
14324
14343
  string: { unit: "\u062D\u0631\u0641", verb: "\u0623\u0646 \u064A\u062D\u0648\u064A" },
@@ -14424,7 +14443,7 @@ function ar_default() {
14424
14443
  localeError: error()
14425
14444
  };
14426
14445
  }
14427
- // node_modules/zod/v4/locales/az.js
14446
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/az.js
14428
14447
  var error2 = () => {
14429
14448
  const Sizable = {
14430
14449
  string: { unit: "simvol", verb: "olmal\u0131d\u0131r" },
@@ -14529,7 +14548,7 @@ function az_default() {
14529
14548
  localeError: error2()
14530
14549
  };
14531
14550
  }
14532
- // node_modules/zod/v4/locales/be.js
14551
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/be.js
14533
14552
  function getBelarusianPlural(count, one, few, many) {
14534
14553
  const absCount = Math.abs(count);
14535
14554
  const lastDigit = absCount % 10;
@@ -14685,7 +14704,7 @@ function be_default() {
14685
14704
  localeError: error3()
14686
14705
  };
14687
14706
  }
14688
- // node_modules/zod/v4/locales/bg.js
14707
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/bg.js
14689
14708
  var error4 = () => {
14690
14709
  const Sizable = {
14691
14710
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0430", verb: "\u0434\u0430 \u0441\u044A\u0434\u044A\u0440\u0436\u0430" },
@@ -14805,7 +14824,7 @@ function bg_default() {
14805
14824
  localeError: error4()
14806
14825
  };
14807
14826
  }
14808
- // node_modules/zod/v4/locales/ca.js
14827
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ca.js
14809
14828
  var error5 = () => {
14810
14829
  const Sizable = {
14811
14830
  string: { unit: "car\xE0cters", verb: "contenir" },
@@ -14912,7 +14931,7 @@ function ca_default() {
14912
14931
  localeError: error5()
14913
14932
  };
14914
14933
  }
14915
- // node_modules/zod/v4/locales/cs.js
14934
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/cs.js
14916
14935
  var error6 = () => {
14917
14936
  const Sizable = {
14918
14937
  string: { unit: "znak\u016F", verb: "m\xEDt" },
@@ -15023,7 +15042,7 @@ function cs_default() {
15023
15042
  localeError: error6()
15024
15043
  };
15025
15044
  }
15026
- // node_modules/zod/v4/locales/da.js
15045
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/da.js
15027
15046
  var error7 = () => {
15028
15047
  const Sizable = {
15029
15048
  string: { unit: "tegn", verb: "havde" },
@@ -15138,7 +15157,7 @@ function da_default() {
15138
15157
  localeError: error7()
15139
15158
  };
15140
15159
  }
15141
- // node_modules/zod/v4/locales/de.js
15160
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/de.js
15142
15161
  var error8 = () => {
15143
15162
  const Sizable = {
15144
15163
  string: { unit: "Zeichen", verb: "zu haben" },
@@ -15246,7 +15265,7 @@ function de_default() {
15246
15265
  localeError: error8()
15247
15266
  };
15248
15267
  }
15249
- // node_modules/zod/v4/locales/en.js
15268
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/en.js
15250
15269
  var error9 = () => {
15251
15270
  const Sizable = {
15252
15271
  string: { unit: "characters", verb: "to have" },
@@ -15352,7 +15371,7 @@ function en_default2() {
15352
15371
  localeError: error9()
15353
15372
  };
15354
15373
  }
15355
- // node_modules/zod/v4/locales/eo.js
15374
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/eo.js
15356
15375
  var error10 = () => {
15357
15376
  const Sizable = {
15358
15377
  string: { unit: "karaktrojn", verb: "havi" },
@@ -15461,7 +15480,7 @@ function eo_default() {
15461
15480
  localeError: error10()
15462
15481
  };
15463
15482
  }
15464
- // node_modules/zod/v4/locales/es.js
15483
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/es.js
15465
15484
  var error11 = () => {
15466
15485
  const Sizable = {
15467
15486
  string: { unit: "caracteres", verb: "tener" },
@@ -15593,7 +15612,7 @@ function es_default() {
15593
15612
  localeError: error11()
15594
15613
  };
15595
15614
  }
15596
- // node_modules/zod/v4/locales/fa.js
15615
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/fa.js
15597
15616
  var error12 = () => {
15598
15617
  const Sizable = {
15599
15618
  string: { unit: "\u06A9\u0627\u0631\u0627\u06A9\u062A\u0631", verb: "\u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u062F" },
@@ -15707,7 +15726,7 @@ function fa_default() {
15707
15726
  localeError: error12()
15708
15727
  };
15709
15728
  }
15710
- // node_modules/zod/v4/locales/fi.js
15729
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/fi.js
15711
15730
  var error13 = () => {
15712
15731
  const Sizable = {
15713
15732
  string: { unit: "merkki\xE4", subject: "merkkijonon" },
@@ -15819,7 +15838,7 @@ function fi_default() {
15819
15838
  localeError: error13()
15820
15839
  };
15821
15840
  }
15822
- // node_modules/zod/v4/locales/fr.js
15841
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/fr.js
15823
15842
  var error14 = () => {
15824
15843
  const Sizable = {
15825
15844
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -15927,7 +15946,7 @@ function fr_default() {
15927
15946
  localeError: error14()
15928
15947
  };
15929
15948
  }
15930
- // node_modules/zod/v4/locales/fr-CA.js
15949
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/fr-CA.js
15931
15950
  var error15 = () => {
15932
15951
  const Sizable = {
15933
15952
  string: { unit: "caract\xE8res", verb: "avoir" },
@@ -16034,7 +16053,7 @@ function fr_CA_default() {
16034
16053
  localeError: error15()
16035
16054
  };
16036
16055
  }
16037
- // node_modules/zod/v4/locales/he.js
16056
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/he.js
16038
16057
  var error16 = () => {
16039
16058
  const TypeNames = {
16040
16059
  string: { label: "\u05DE\u05D7\u05E8\u05D5\u05D6\u05EA", gender: "f" },
@@ -16227,7 +16246,7 @@ function he_default() {
16227
16246
  localeError: error16()
16228
16247
  };
16229
16248
  }
16230
- // node_modules/zod/v4/locales/hu.js
16249
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/hu.js
16231
16250
  var error17 = () => {
16232
16251
  const Sizable = {
16233
16252
  string: { unit: "karakter", verb: "legyen" },
@@ -16335,7 +16354,7 @@ function hu_default() {
16335
16354
  localeError: error17()
16336
16355
  };
16337
16356
  }
16338
- // node_modules/zod/v4/locales/hy.js
16357
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/hy.js
16339
16358
  function getArmenianPlural(count, one, many) {
16340
16359
  return Math.abs(count) === 1 ? one : many;
16341
16360
  }
@@ -16482,7 +16501,7 @@ function hy_default() {
16482
16501
  localeError: error18()
16483
16502
  };
16484
16503
  }
16485
- // node_modules/zod/v4/locales/id.js
16504
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/id.js
16486
16505
  var error19 = () => {
16487
16506
  const Sizable = {
16488
16507
  string: { unit: "karakter", verb: "memiliki" },
@@ -16588,7 +16607,7 @@ function id_default() {
16588
16607
  localeError: error19()
16589
16608
  };
16590
16609
  }
16591
- // node_modules/zod/v4/locales/is.js
16610
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/is.js
16592
16611
  var error20 = () => {
16593
16612
  const Sizable = {
16594
16613
  string: { unit: "stafi", verb: "a\xF0 hafa" },
@@ -16697,7 +16716,7 @@ function is_default() {
16697
16716
  localeError: error20()
16698
16717
  };
16699
16718
  }
16700
- // node_modules/zod/v4/locales/it.js
16719
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/it.js
16701
16720
  var error21 = () => {
16702
16721
  const Sizable = {
16703
16722
  string: { unit: "caratteri", verb: "avere" },
@@ -16805,7 +16824,7 @@ function it_default() {
16805
16824
  localeError: error21()
16806
16825
  };
16807
16826
  }
16808
- // node_modules/zod/v4/locales/ja.js
16827
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ja.js
16809
16828
  var error22 = () => {
16810
16829
  const Sizable = {
16811
16830
  string: { unit: "\u6587\u5B57", verb: "\u3067\u3042\u308B" },
@@ -16912,7 +16931,7 @@ function ja_default() {
16912
16931
  localeError: error22()
16913
16932
  };
16914
16933
  }
16915
- // node_modules/zod/v4/locales/ka.js
16934
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ka.js
16916
16935
  var error23 = () => {
16917
16936
  const Sizable = {
16918
16937
  string: { unit: "\u10E1\u10D8\u10DB\u10D1\u10DD\u10DA\u10DD", verb: "\u10E3\u10DC\u10D3\u10D0 \u10E8\u10D4\u10D8\u10EA\u10D0\u10D5\u10D3\u10D4\u10E1" },
@@ -17024,7 +17043,7 @@ function ka_default() {
17024
17043
  localeError: error23()
17025
17044
  };
17026
17045
  }
17027
- // node_modules/zod/v4/locales/km.js
17046
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/km.js
17028
17047
  var error24 = () => {
17029
17048
  const Sizable = {
17030
17049
  string: { unit: "\u178F\u17BD\u17A2\u1780\u17D2\u179F\u179A", verb: "\u1782\u17BD\u179A\u1798\u17B6\u1793" },
@@ -17135,11 +17154,11 @@ function km_default() {
17135
17154
  };
17136
17155
  }
17137
17156
 
17138
- // node_modules/zod/v4/locales/kh.js
17157
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/kh.js
17139
17158
  function kh_default() {
17140
17159
  return km_default();
17141
17160
  }
17142
- // node_modules/zod/v4/locales/ko.js
17161
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ko.js
17143
17162
  var error25 = () => {
17144
17163
  const Sizable = {
17145
17164
  string: { unit: "\uBB38\uC790", verb: "to have" },
@@ -17250,7 +17269,7 @@ function ko_default() {
17250
17269
  localeError: error25()
17251
17270
  };
17252
17271
  }
17253
- // node_modules/zod/v4/locales/lt.js
17272
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/lt.js
17254
17273
  var capitalizeFirstCharacter = (text) => {
17255
17274
  return text.charAt(0).toUpperCase() + text.slice(1);
17256
17275
  };
@@ -17453,7 +17472,7 @@ function lt_default() {
17453
17472
  localeError: error26()
17454
17473
  };
17455
17474
  }
17456
- // node_modules/zod/v4/locales/mk.js
17475
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/mk.js
17457
17476
  var error27 = () => {
17458
17477
  const Sizable = {
17459
17478
  string: { unit: "\u0437\u043D\u0430\u0446\u0438", verb: "\u0434\u0430 \u0438\u043C\u0430\u0430\u0442" },
@@ -17562,7 +17581,7 @@ function mk_default() {
17562
17581
  localeError: error27()
17563
17582
  };
17564
17583
  }
17565
- // node_modules/zod/v4/locales/ms.js
17584
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ms.js
17566
17585
  var error28 = () => {
17567
17586
  const Sizable = {
17568
17587
  string: { unit: "aksara", verb: "mempunyai" },
@@ -17669,7 +17688,7 @@ function ms_default() {
17669
17688
  localeError: error28()
17670
17689
  };
17671
17690
  }
17672
- // node_modules/zod/v4/locales/nl.js
17691
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/nl.js
17673
17692
  var error29 = () => {
17674
17693
  const Sizable = {
17675
17694
  string: { unit: "tekens", verb: "heeft" },
@@ -17779,7 +17798,7 @@ function nl_default() {
17779
17798
  localeError: error29()
17780
17799
  };
17781
17800
  }
17782
- // node_modules/zod/v4/locales/no.js
17801
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/no.js
17783
17802
  var error30 = () => {
17784
17803
  const Sizable = {
17785
17804
  string: { unit: "tegn", verb: "\xE5 ha" },
@@ -17887,7 +17906,7 @@ function no_default() {
17887
17906
  localeError: error30()
17888
17907
  };
17889
17908
  }
17890
- // node_modules/zod/v4/locales/ota.js
17909
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ota.js
17891
17910
  var error31 = () => {
17892
17911
  const Sizable = {
17893
17912
  string: { unit: "harf", verb: "olmal\u0131d\u0131r" },
@@ -17996,7 +18015,7 @@ function ota_default() {
17996
18015
  localeError: error31()
17997
18016
  };
17998
18017
  }
17999
- // node_modules/zod/v4/locales/ps.js
18018
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ps.js
18000
18019
  var error32 = () => {
18001
18020
  const Sizable = {
18002
18021
  string: { unit: "\u062A\u0648\u06A9\u064A", verb: "\u0648\u0644\u0631\u064A" },
@@ -18110,7 +18129,7 @@ function ps_default() {
18110
18129
  localeError: error32()
18111
18130
  };
18112
18131
  }
18113
- // node_modules/zod/v4/locales/pl.js
18132
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/pl.js
18114
18133
  var error33 = () => {
18115
18134
  const Sizable = {
18116
18135
  string: { unit: "znak\xF3w", verb: "mie\u0107" },
@@ -18219,7 +18238,7 @@ function pl_default() {
18219
18238
  localeError: error33()
18220
18239
  };
18221
18240
  }
18222
- // node_modules/zod/v4/locales/pt.js
18241
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/pt.js
18223
18242
  var error34 = () => {
18224
18243
  const Sizable = {
18225
18244
  string: { unit: "caracteres", verb: "ter" },
@@ -18327,7 +18346,7 @@ function pt_default() {
18327
18346
  localeError: error34()
18328
18347
  };
18329
18348
  }
18330
- // node_modules/zod/v4/locales/ru.js
18349
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ru.js
18331
18350
  function getRussianPlural(count, one, few, many) {
18332
18351
  const absCount = Math.abs(count);
18333
18352
  const lastDigit = absCount % 10;
@@ -18483,7 +18502,7 @@ function ru_default() {
18483
18502
  localeError: error35()
18484
18503
  };
18485
18504
  }
18486
- // node_modules/zod/v4/locales/sl.js
18505
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/sl.js
18487
18506
  var error36 = () => {
18488
18507
  const Sizable = {
18489
18508
  string: { unit: "znakov", verb: "imeti" },
@@ -18592,7 +18611,7 @@ function sl_default() {
18592
18611
  localeError: error36()
18593
18612
  };
18594
18613
  }
18595
- // node_modules/zod/v4/locales/sv.js
18614
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/sv.js
18596
18615
  var error37 = () => {
18597
18616
  const Sizable = {
18598
18617
  string: { unit: "tecken", verb: "att ha" },
@@ -18702,7 +18721,7 @@ function sv_default() {
18702
18721
  localeError: error37()
18703
18722
  };
18704
18723
  }
18705
- // node_modules/zod/v4/locales/ta.js
18724
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ta.js
18706
18725
  var error38 = () => {
18707
18726
  const Sizable = {
18708
18727
  string: { unit: "\u0B8E\u0BB4\u0BC1\u0BA4\u0BCD\u0BA4\u0BC1\u0B95\u0BCD\u0B95\u0BB3\u0BCD", verb: "\u0B95\u0BCA\u0BA3\u0BCD\u0B9F\u0BBF\u0BB0\u0BC1\u0B95\u0BCD\u0B95 \u0BB5\u0BC7\u0BA3\u0BCD\u0B9F\u0BC1\u0BAE\u0BCD" },
@@ -18812,7 +18831,7 @@ function ta_default() {
18812
18831
  localeError: error38()
18813
18832
  };
18814
18833
  }
18815
- // node_modules/zod/v4/locales/th.js
18834
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/th.js
18816
18835
  var error39 = () => {
18817
18836
  const Sizable = {
18818
18837
  string: { unit: "\u0E15\u0E31\u0E27\u0E2D\u0E31\u0E01\u0E29\u0E23", verb: "\u0E04\u0E27\u0E23\u0E21\u0E35" },
@@ -18922,7 +18941,7 @@ function th_default() {
18922
18941
  localeError: error39()
18923
18942
  };
18924
18943
  }
18925
- // node_modules/zod/v4/locales/tr.js
18944
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/tr.js
18926
18945
  var error40 = () => {
18927
18946
  const Sizable = {
18928
18947
  string: { unit: "karakter", verb: "olmal\u0131" },
@@ -19027,7 +19046,7 @@ function tr_default() {
19027
19046
  localeError: error40()
19028
19047
  };
19029
19048
  }
19030
- // node_modules/zod/v4/locales/uk.js
19049
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/uk.js
19031
19050
  var error41 = () => {
19032
19051
  const Sizable = {
19033
19052
  string: { unit: "\u0441\u0438\u043C\u0432\u043E\u043B\u0456\u0432", verb: "\u043C\u0430\u0442\u0438\u043C\u0435" },
@@ -19136,11 +19155,11 @@ function uk_default() {
19136
19155
  };
19137
19156
  }
19138
19157
 
19139
- // node_modules/zod/v4/locales/ua.js
19158
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ua.js
19140
19159
  function ua_default() {
19141
19160
  return uk_default();
19142
19161
  }
19143
- // node_modules/zod/v4/locales/ur.js
19162
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/ur.js
19144
19163
  var error42 = () => {
19145
19164
  const Sizable = {
19146
19165
  string: { unit: "\u062D\u0631\u0648\u0641", verb: "\u06C1\u0648\u0646\u0627" },
@@ -19250,7 +19269,7 @@ function ur_default() {
19250
19269
  localeError: error42()
19251
19270
  };
19252
19271
  }
19253
- // node_modules/zod/v4/locales/uz.js
19272
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/uz.js
19254
19273
  var error43 = () => {
19255
19274
  const Sizable = {
19256
19275
  string: { unit: "belgi", verb: "bo\u2018lishi kerak" },
@@ -19359,7 +19378,7 @@ function uz_default() {
19359
19378
  localeError: error43()
19360
19379
  };
19361
19380
  }
19362
- // node_modules/zod/v4/locales/vi.js
19381
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/vi.js
19363
19382
  var error44 = () => {
19364
19383
  const Sizable = {
19365
19384
  string: { unit: "k\xFD t\u1EF1", verb: "c\xF3" },
@@ -19467,7 +19486,7 @@ function vi_default() {
19467
19486
  localeError: error44()
19468
19487
  };
19469
19488
  }
19470
- // node_modules/zod/v4/locales/zh-CN.js
19489
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/zh-CN.js
19471
19490
  var error45 = () => {
19472
19491
  const Sizable = {
19473
19492
  string: { unit: "\u5B57\u7B26", verb: "\u5305\u542B" },
@@ -19576,7 +19595,7 @@ function zh_CN_default() {
19576
19595
  localeError: error45()
19577
19596
  };
19578
19597
  }
19579
- // node_modules/zod/v4/locales/zh-TW.js
19598
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/zh-TW.js
19580
19599
  var error46 = () => {
19581
19600
  const Sizable = {
19582
19601
  string: { unit: "\u5B57\u5143", verb: "\u64C1\u6709" },
@@ -19683,7 +19702,7 @@ function zh_TW_default() {
19683
19702
  localeError: error46()
19684
19703
  };
19685
19704
  }
19686
- // node_modules/zod/v4/locales/yo.js
19705
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/locales/yo.js
19687
19706
  var error47 = () => {
19688
19707
  const Sizable = {
19689
19708
  string: { unit: "\xE0mi", verb: "n\xED" },
@@ -19790,7 +19809,7 @@ function yo_default() {
19790
19809
  localeError: error47()
19791
19810
  };
19792
19811
  }
19793
- // node_modules/zod/v4/core/registries.js
19812
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/registries.js
19794
19813
  var _a;
19795
19814
  var $output = Symbol("ZodOutput");
19796
19815
  var $input = Symbol("ZodInput");
@@ -19840,7 +19859,7 @@ function registry() {
19840
19859
  }
19841
19860
  (_a = globalThis).__zod_globalRegistry ?? (_a.__zod_globalRegistry = registry());
19842
19861
  var globalRegistry = globalThis.__zod_globalRegistry;
19843
- // node_modules/zod/v4/core/api.js
19862
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/api.js
19844
19863
  function _string(Class2, params) {
19845
19864
  return new Class2({
19846
19865
  type: "string",
@@ -20760,7 +20779,7 @@ function _stringFormat(Class2, format, fnOrRegex, _params = {}) {
20760
20779
  const inst = new Class2(def);
20761
20780
  return inst;
20762
20781
  }
20763
- // node_modules/zod/v4/core/to-json-schema.js
20782
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/to-json-schema.js
20764
20783
  function initializeContext(params) {
20765
20784
  let target = params?.target ?? "draft-2020-12";
20766
20785
  if (target === "draft-4")
@@ -21105,7 +21124,7 @@ var createStandardJSONSchemaMethod = (schema, io, processors = {}) => (params) =
21105
21124
  extractDefs(ctx, schema);
21106
21125
  return finalize(ctx, schema);
21107
21126
  };
21108
- // node_modules/zod/v4/core/json-schema-processors.js
21127
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/json-schema-processors.js
21109
21128
  var formatMap = {
21110
21129
  guid: "uuid",
21111
21130
  url: "uri",
@@ -21650,7 +21669,7 @@ function toJSONSchema(input, params) {
21650
21669
  extractDefs(ctx, input);
21651
21670
  return finalize(ctx, input);
21652
21671
  }
21653
- // node_modules/zod/v4/core/json-schema-generator.js
21672
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/json-schema-generator.js
21654
21673
  class JSONSchemaGenerator {
21655
21674
  get metadataRegistry() {
21656
21675
  return this.ctx.metadataRegistry;
@@ -21709,9 +21728,9 @@ class JSONSchemaGenerator {
21709
21728
  return plainResult;
21710
21729
  }
21711
21730
  }
21712
- // node_modules/zod/v4/core/json-schema.js
21731
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/core/json-schema.js
21713
21732
  var exports_json_schema = {};
21714
- // node_modules/zod/v4/mini/schemas.js
21733
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/mini/schemas.js
21715
21734
  var ZodMiniType = /* @__PURE__ */ $constructor("ZodMiniType", (inst, def) => {
21716
21735
  if (!inst._zod)
21717
21736
  throw new Error("Uninitialized schema in ZodMiniType.");
@@ -21897,7 +21916,7 @@ function getLiteralValue(schema) {
21897
21916
  return;
21898
21917
  }
21899
21918
 
21900
- // node_modules/zod/v4/classic/external.js
21919
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
21901
21920
  var exports_external = {};
21902
21921
  __export(exports_external, {
21903
21922
  xor: () => xor,
@@ -22138,7 +22157,7 @@ __export(exports_external, {
22138
22157
  $brand: () => $brand
22139
22158
  });
22140
22159
 
22141
- // node_modules/zod/v4/classic/schemas.js
22160
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/schemas.js
22142
22161
  var exports_schemas2 = {};
22143
22162
  __export(exports_schemas2, {
22144
22163
  xor: () => xor,
@@ -22307,7 +22326,7 @@ __export(exports_schemas2, {
22307
22326
  ZodAny: () => ZodAny2
22308
22327
  });
22309
22328
 
22310
- // node_modules/zod/v4/classic/checks.js
22329
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/checks.js
22311
22330
  var exports_checks2 = {};
22312
22331
  __export(exports_checks2, {
22313
22332
  uppercase: () => _uppercase,
@@ -22341,7 +22360,7 @@ __export(exports_checks2, {
22341
22360
  endsWith: () => _endsWith
22342
22361
  });
22343
22362
 
22344
- // node_modules/zod/v4/classic/iso.js
22363
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/iso.js
22345
22364
  var exports_iso2 = {};
22346
22365
  __export(exports_iso2, {
22347
22366
  time: () => time2,
@@ -22382,7 +22401,7 @@ function duration2(params) {
22382
22401
  return _isoDuration(ZodISODuration, params);
22383
22402
  }
22384
22403
 
22385
- // node_modules/zod/v4/classic/errors.js
22404
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/errors.js
22386
22405
  var initializer2 = (inst, issues) => {
22387
22406
  $ZodError.init(inst, issues);
22388
22407
  inst.name = "ZodError";
@@ -22417,7 +22436,7 @@ var ZodRealError = $constructor("ZodError", initializer2, {
22417
22436
  Parent: Error
22418
22437
  });
22419
22438
 
22420
- // node_modules/zod/v4/classic/parse.js
22439
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/parse.js
22421
22440
  var parse4 = /* @__PURE__ */ _parse(ZodRealError);
22422
22441
  var parseAsync2 = /* @__PURE__ */ _parseAsync(ZodRealError);
22423
22442
  var safeParse3 = /* @__PURE__ */ _safeParse(ZodRealError);
@@ -22431,7 +22450,7 @@ var safeDecode2 = /* @__PURE__ */ _safeDecode(ZodRealError);
22431
22450
  var safeEncodeAsync2 = /* @__PURE__ */ _safeEncodeAsync(ZodRealError);
22432
22451
  var safeDecodeAsync2 = /* @__PURE__ */ _safeDecodeAsync(ZodRealError);
22433
22452
 
22434
- // node_modules/zod/v4/classic/schemas.js
22453
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/schemas.js
22435
22454
  var ZodType2 = /* @__PURE__ */ $constructor("ZodType", (inst, def) => {
22436
22455
  $ZodType.init(inst, def);
22437
22456
  Object.assign(inst["~standard"], {
@@ -23507,7 +23526,7 @@ function json(params) {
23507
23526
  function preprocess(fn, schema) {
23508
23527
  return pipe(transform(fn), schema);
23509
23528
  }
23510
- // node_modules/zod/v4/classic/compat.js
23529
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/compat.js
23511
23530
  var ZodIssueCode2 = {
23512
23531
  invalid_type: "invalid_type",
23513
23532
  too_big: "too_big",
@@ -23531,7 +23550,7 @@ function getErrorMap2() {
23531
23550
  }
23532
23551
  var ZodFirstPartyTypeKind2;
23533
23552
  (function(ZodFirstPartyTypeKind3) {})(ZodFirstPartyTypeKind2 || (ZodFirstPartyTypeKind2 = {}));
23534
- // node_modules/zod/v4/classic/from-json-schema.js
23553
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/from-json-schema.js
23535
23554
  var z = {
23536
23555
  ...exports_schemas2,
23537
23556
  ...exports_checks2,
@@ -23992,7 +24011,7 @@ function fromJSONSchema(schema, params) {
23992
24011
  };
23993
24012
  return convertSchema(schema, ctx);
23994
24013
  }
23995
- // node_modules/zod/v4/classic/coerce.js
24014
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/coerce.js
23996
24015
  var exports_coerce2 = {};
23997
24016
  __export(exports_coerce2, {
23998
24017
  string: () => string3,
@@ -24017,7 +24036,7 @@ function date4(params) {
24017
24036
  return _coercedDate(ZodDate2, params);
24018
24037
  }
24019
24038
 
24020
- // node_modules/zod/v4/classic/external.js
24039
+ // ../../../../hasnastudio/hasnastudio-alumia/platform/platformdev/platform-alumia/node_modules/.pnpm/zod@4.3.6/node_modules/zod/v4/classic/external.js
24021
24040
  config(en_default2());
24022
24041
 
24023
24042
  // node_modules/@modelcontextprotocol/sdk/dist/esm/types.js
@@ -27028,62 +27047,6 @@ class ExperimentalServerTasks {
27028
27047
  requestStream(request, resultSchema, options) {
27029
27048
  return this._server.requestStream(request, resultSchema, options);
27030
27049
  }
27031
- createMessageStream(params, options) {
27032
- const clientCapabilities = this._server.getClientCapabilities();
27033
- if ((params.tools || params.toolChoice) && !clientCapabilities?.sampling?.tools) {
27034
- throw new Error("Client does not support sampling tools capability.");
27035
- }
27036
- if (params.messages.length > 0) {
27037
- const lastMessage = params.messages[params.messages.length - 1];
27038
- const lastContent = Array.isArray(lastMessage.content) ? lastMessage.content : [lastMessage.content];
27039
- const hasToolResults = lastContent.some((c) => c.type === "tool_result");
27040
- const previousMessage = params.messages.length > 1 ? params.messages[params.messages.length - 2] : undefined;
27041
- const previousContent = previousMessage ? Array.isArray(previousMessage.content) ? previousMessage.content : [previousMessage.content] : [];
27042
- const hasPreviousToolUse = previousContent.some((c) => c.type === "tool_use");
27043
- if (hasToolResults) {
27044
- if (lastContent.some((c) => c.type !== "tool_result")) {
27045
- throw new Error("The last message must contain only tool_result content if any is present");
27046
- }
27047
- if (!hasPreviousToolUse) {
27048
- throw new Error("tool_result blocks are not matching any tool_use from the previous message");
27049
- }
27050
- }
27051
- if (hasPreviousToolUse) {
27052
- const toolUseIds = new Set(previousContent.filter((c) => c.type === "tool_use").map((c) => c.id));
27053
- const toolResultIds = new Set(lastContent.filter((c) => c.type === "tool_result").map((c) => c.toolUseId));
27054
- if (toolUseIds.size !== toolResultIds.size || ![...toolUseIds].every((id) => toolResultIds.has(id))) {
27055
- throw new Error("ids of tool_result blocks and tool_use blocks from previous message do not match");
27056
- }
27057
- }
27058
- }
27059
- return this.requestStream({
27060
- method: "sampling/createMessage",
27061
- params
27062
- }, CreateMessageResultSchema, options);
27063
- }
27064
- elicitInputStream(params, options) {
27065
- const clientCapabilities = this._server.getClientCapabilities();
27066
- const mode = params.mode ?? "form";
27067
- switch (mode) {
27068
- case "url": {
27069
- if (!clientCapabilities?.elicitation?.url) {
27070
- throw new Error("Client does not support url elicitation.");
27071
- }
27072
- break;
27073
- }
27074
- case "form": {
27075
- if (!clientCapabilities?.elicitation?.form) {
27076
- throw new Error("Client does not support form elicitation.");
27077
- }
27078
- break;
27079
- }
27080
- }
27081
- const normalizedParams = mode === "form" && params.mode === undefined ? { ...params, mode: "form" } : params;
27082
- return this.requestStream({
27083
- method: "elicitation/create",
27084
- params: normalizedParams
27085
- }, ElicitResultSchema, options);
27086
- }
27087
27050
  async getTask(taskId, options) {
27088
27051
  return this._server.getTask({ taskId }, options);
27089
27052
  }
@@ -28598,13 +28561,12 @@ class StdioServerTransport {
28598
28561
  }
28599
28562
 
28600
28563
  // src/mcp/index.ts
28601
- import { existsSync as existsSync3, readdirSync as readdirSync3, statSync as statSync2 } from "fs";
28602
- import { join as join3 } from "path";
28603
- import { homedir as homedir2 } from "os";
28564
+ import { existsSync as existsSync5, readdirSync as readdirSync4, statSync as statSync2 } from "fs";
28565
+ import { join as join5 } from "path";
28604
28566
  // package.json
28605
28567
  var package_default = {
28606
28568
  name: "@hasna/skills",
28607
- version: "0.1.13",
28569
+ version: "0.1.15",
28608
28570
  description: "Skills library for AI coding agents",
28609
28571
  type: "module",
28610
28572
  bin: {
@@ -28627,9 +28589,12 @@ var package_default = {
28627
28589
  main: "./dist/index.js",
28628
28590
  types: "./dist/index.d.ts",
28629
28591
  scripts: {
28630
- build: "bun build ./src/cli/index.tsx --outdir ./bin --target bun --external ink --external react --external chalk && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/index.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
28592
+ clean: "rm -rf bin/ dist/",
28593
+ build: "bun run clean && bun build ./src/cli/index.tsx --outdir ./bin --target bun --external ink --external react --external chalk && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/index.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
28631
28594
  test: "bun test",
28632
28595
  dev: "bun run ./src/cli/index.tsx",
28596
+ "dev:watch": "bun --watch run ./src/cli/index.tsx",
28597
+ "dev:mcp": "bun --watch run ./src/mcp/index.ts",
28633
28598
  typecheck: "tsc --noEmit",
28634
28599
  prepublishOnly: "bun run build",
28635
28600
  "dashboard:dev": "cd dashboard && bun run dev",
@@ -28685,6 +28650,9 @@ var package_default = {
28685
28650
  };
28686
28651
 
28687
28652
  // src/lib/registry.ts
28653
+ import { existsSync, readFileSync, readdirSync } from "fs";
28654
+ import { join } from "path";
28655
+ import { homedir } from "os";
28688
28656
  var CATEGORIES = [
28689
28657
  "Development Tools",
28690
28658
  "Business & Marketing",
@@ -29721,6 +29689,20 @@ var SKILLS = [
29721
29689
  category: "Design & Branding",
29722
29690
  tags: ["testimonials", "graphics", "social-proof", "marketing"]
29723
29691
  },
29692
+ {
29693
+ name: "colorextract",
29694
+ displayName: "Color Extract",
29695
+ description: "Extract complete color palettes from screenshots and images using Claude Vision. Outputs open-styles compatible profiles.",
29696
+ category: "Design & Branding",
29697
+ tags: ["colors", "palette", "design", "vision", "screenshot", "extract", "open-styles"]
29698
+ },
29699
+ {
29700
+ name: "siteanalyze",
29701
+ displayName: "Site Analyze",
29702
+ description: "Analyze any website's design system \u2014 detects shadcn/ui, Tailwind, extracts colors, typography, and components via Playwright + Claude Vision.",
29703
+ category: "Design & Branding",
29704
+ tags: ["design", "shadcn", "tailwind", "colors", "typography", "playwright", "analysis", "open-styles"]
29705
+ },
29724
29706
  {
29725
29707
  name: "browse",
29726
29708
  displayName: "Browse",
@@ -30121,8 +30103,87 @@ var SKILLS = [
30121
30103
  tags: ["seating", "chart", "events", "venues"]
30122
30104
  }
30123
30105
  ];
30106
+ function parseSkillMdFrontmatter(content) {
30107
+ const match = content.match(/^---\n([\s\S]*?)\n---/);
30108
+ if (!match)
30109
+ return null;
30110
+ const result = {};
30111
+ for (const line of match[1].split(`
30112
+ `)) {
30113
+ const colon = line.indexOf(":");
30114
+ if (colon === -1)
30115
+ continue;
30116
+ const key = line.slice(0, colon).trim();
30117
+ const value = line.slice(colon + 1).trim();
30118
+ if (!key || !value)
30119
+ continue;
30120
+ if (key === "name")
30121
+ result.name = value;
30122
+ else if (key === "description")
30123
+ result.description = value;
30124
+ else if (key === "displayName" || key === "display_name")
30125
+ result.displayName = value;
30126
+ else if (key === "category")
30127
+ result.category = value;
30128
+ else if (key === "tags") {
30129
+ result.tags = value.replace(/[\[\]]/g, "").split(",").map((t) => t.trim()).filter(Boolean);
30130
+ }
30131
+ }
30132
+ return Object.keys(result).length > 0 ? result : null;
30133
+ }
30134
+ function discoverSkillsInDir(dir) {
30135
+ if (!existsSync(dir))
30136
+ return [];
30137
+ const result = [];
30138
+ try {
30139
+ const entries = readdirSync(dir, { withFileTypes: true });
30140
+ for (const entry of entries) {
30141
+ if (!entry.isDirectory())
30142
+ continue;
30143
+ const skillMdPath = join(dir, entry.name, "SKILL.md");
30144
+ if (!existsSync(skillMdPath))
30145
+ continue;
30146
+ let content;
30147
+ try {
30148
+ content = readFileSync(skillMdPath, "utf-8");
30149
+ } catch {
30150
+ continue;
30151
+ }
30152
+ const fm = parseSkillMdFrontmatter(content);
30153
+ if (!fm?.name)
30154
+ continue;
30155
+ const name = fm.name.replace(/^skill-/, "");
30156
+ result.push({
30157
+ name,
30158
+ displayName: fm.displayName || name.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()),
30159
+ description: fm.description || "",
30160
+ category: fm.category || "Development Tools",
30161
+ tags: fm.tags || [],
30162
+ source: "custom"
30163
+ });
30164
+ }
30165
+ } catch {}
30166
+ return result;
30167
+ }
30168
+ var _registryCache = null;
30169
+ var _registryCacheTime = 0;
30170
+ var REGISTRY_CACHE_TTL = 5000;
30171
+ function loadRegistry(cwd) {
30172
+ const now = Date.now();
30173
+ if (_registryCache && now - _registryCacheTime < REGISTRY_CACHE_TTL) {
30174
+ return _registryCache;
30175
+ }
30176
+ const official = SKILLS.map((s) => ({ ...s, source: "official" }));
30177
+ const globalCustom = discoverSkillsInDir(join(homedir(), ".skills"));
30178
+ const projectCustom = discoverSkillsInDir(join(cwd || process.cwd(), ".skills", "custom-skills"));
30179
+ const customNames = new Set([...globalCustom, ...projectCustom].map((s) => s.name));
30180
+ const filtered = official.filter((s) => !customNames.has(s.name));
30181
+ _registryCache = [...filtered, ...globalCustom, ...projectCustom];
30182
+ _registryCacheTime = now;
30183
+ return _registryCache;
30184
+ }
30124
30185
  function getSkillsByCategory(category) {
30125
- return SKILLS.filter((s) => s.category === category);
30186
+ return loadRegistry().filter((s) => s.category === category);
30126
30187
  }
30127
30188
  function editDistance(a, b) {
30128
30189
  if (a === b)
@@ -30168,7 +30229,7 @@ function searchSkills(query) {
30168
30229
  if (words.length === 0)
30169
30230
  return [];
30170
30231
  const scored = [];
30171
- for (const skill of SKILLS) {
30232
+ for (const skill of loadRegistry()) {
30172
30233
  const nameLower = skill.name.toLowerCase();
30173
30234
  const displayNameLower = skill.displayName.toLowerCase();
30174
30235
  const descriptionLower = skill.description.toLowerCase();
@@ -30204,13 +30265,28 @@ function searchSkills(query) {
30204
30265
  return scored.map((s) => s.skill);
30205
30266
  }
30206
30267
  function getSkill(name) {
30207
- return SKILLS.find((s) => s.name === name);
30268
+ return loadRegistry().find((s) => s.name === name);
30269
+ }
30270
+ function levenshtein(a, b) {
30271
+ const m = a.length, n = b.length;
30272
+ const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_2, j) => i === 0 ? j : j === 0 ? i : 0));
30273
+ for (let i = 1;i <= m; i++) {
30274
+ for (let j = 1;j <= n; j++) {
30275
+ dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
30276
+ }
30277
+ }
30278
+ return dp[m][n];
30279
+ }
30280
+ function findSimilarSkills(query, maxResults = 3) {
30281
+ const q = query.toLowerCase();
30282
+ const scored = loadRegistry().map((s) => ({ name: s.name, dist: levenshtein(q, s.name.toLowerCase()) })).filter((s) => s.dist <= Math.max(3, Math.floor(q.length / 2))).sort((a, b) => a.dist - b.dist);
30283
+ return scored.slice(0, maxResults).map((s) => s.name);
30208
30284
  }
30209
30285
 
30210
30286
  // src/lib/installer.ts
30211
- import { existsSync, cpSync, mkdirSync, writeFileSync, rmSync, readdirSync, statSync, readFileSync } from "fs";
30212
- import { join, dirname } from "path";
30213
- import { homedir } from "os";
30287
+ import { existsSync as existsSync2, cpSync, mkdirSync, writeFileSync, rmSync, readdirSync as readdirSync2, statSync, readFileSync as readFileSync2, accessSync, constants } from "fs";
30288
+ import { join as join2, dirname } from "path";
30289
+ import { homedir as homedir2 } from "os";
30214
30290
  import { fileURLToPath } from "url";
30215
30291
 
30216
30292
  // src/lib/utils.ts
@@ -30223,33 +30299,33 @@ var __dirname2 = dirname(fileURLToPath(import.meta.url));
30223
30299
  function findSkillsDir() {
30224
30300
  let dir = __dirname2;
30225
30301
  for (let i = 0;i < 5; i++) {
30226
- const candidate = join(dir, "skills");
30227
- if (existsSync(candidate)) {
30302
+ const candidate = join2(dir, "skills");
30303
+ if (existsSync2(candidate) && !dir.includes(".skills")) {
30228
30304
  return candidate;
30229
30305
  }
30230
30306
  dir = dirname(dir);
30231
30307
  }
30232
- return join(__dirname2, "..", "skills");
30308
+ return join2(__dirname2, "..", "skills");
30233
30309
  }
30234
30310
  var SKILLS_DIR = findSkillsDir();
30235
30311
  function getSkillPath(name) {
30236
30312
  const skillName = normalizeSkillName(name);
30237
- return join(SKILLS_DIR, skillName);
30313
+ return join2(SKILLS_DIR, skillName);
30238
30314
  }
30239
30315
  function installSkill(name, options = {}) {
30240
30316
  const { targetDir = process.cwd(), overwrite = false } = options;
30241
30317
  const skillName = normalizeSkillName(name);
30242
30318
  const sourcePath = getSkillPath(name);
30243
- const destDir = join(targetDir, ".skills");
30244
- const destPath = join(destDir, skillName);
30245
- if (!existsSync(sourcePath)) {
30319
+ const destDir = join2(targetDir, ".skills");
30320
+ const destPath = join2(destDir, skillName);
30321
+ if (!existsSync2(sourcePath)) {
30246
30322
  return {
30247
30323
  skill: name,
30248
30324
  success: false,
30249
30325
  error: `Skill '${name}' not found`
30250
30326
  };
30251
30327
  }
30252
- if (existsSync(destPath) && !overwrite) {
30328
+ if (existsSync2(destPath) && !overwrite) {
30253
30329
  return {
30254
30330
  skill: name,
30255
30331
  success: false,
@@ -30258,10 +30334,10 @@ function installSkill(name, options = {}) {
30258
30334
  };
30259
30335
  }
30260
30336
  try {
30261
- if (!existsSync(destDir)) {
30337
+ if (!existsSync2(destDir)) {
30262
30338
  mkdirSync(destDir, { recursive: true });
30263
30339
  }
30264
- if (existsSync(destPath) && overwrite) {
30340
+ if (existsSync2(destPath) && overwrite) {
30265
30341
  rmSync(destPath, { recursive: true, force: true });
30266
30342
  }
30267
30343
  cpSync(sourcePath, destPath, {
@@ -30272,6 +30348,7 @@ function installSkill(name, options = {}) {
30272
30348
  }
30273
30349
  });
30274
30350
  updateSkillsIndex(destDir);
30351
+ recordInstall(destDir, name);
30275
30352
  const meta3 = getSkill(name);
30276
30353
  if (meta3?.dependencies && meta3.dependencies.length > 0) {
30277
30354
  const installed = getInstalledSkills(targetDir);
@@ -30296,8 +30373,10 @@ function installSkill(name, options = {}) {
30296
30373
  }
30297
30374
  }
30298
30375
  function updateSkillsIndex(skillsDir) {
30299
- const indexPath = join(skillsDir, "index.ts");
30300
- const skills = readdirSync(skillsDir).filter((f) => f.startsWith("skill-") && !f.includes("."));
30376
+ const indexPath = join2(skillsDir, "index.ts");
30377
+ const meta3 = loadMeta(skillsDir);
30378
+ const disabledSet = new Set(meta3.disabled || []);
30379
+ const skills = readdirSync2(skillsDir).filter((f) => f.startsWith("skill-") && !f.includes(".") && !disabledSet.has(f.replace("skill-", "")));
30301
30380
  const exports = skills.map((s) => {
30302
30381
  const name = s.replace("skill-", "").replace(/-/g, "_");
30303
30382
  return `export * as ${name} from './${s}/src/index.js';`;
@@ -30312,28 +30391,70 @@ ${exports}
30312
30391
  `;
30313
30392
  writeFileSync(indexPath, content);
30314
30393
  }
30394
+ function getMetaPath(skillsDir) {
30395
+ return join2(skillsDir, ".meta.json");
30396
+ }
30397
+ function loadMeta(skillsDir) {
30398
+ const metaPath = getMetaPath(skillsDir);
30399
+ if (existsSync2(metaPath)) {
30400
+ try {
30401
+ return JSON.parse(readFileSync2(metaPath, "utf-8"));
30402
+ } catch {}
30403
+ }
30404
+ return { skills: {} };
30405
+ }
30406
+ function saveMeta(skillsDir, meta3) {
30407
+ writeFileSync(getMetaPath(skillsDir), JSON.stringify(meta3, null, 2));
30408
+ }
30409
+ function recordInstall(skillsDir, name) {
30410
+ const meta3 = loadMeta(skillsDir);
30411
+ const skillName = normalizeSkillName(name);
30412
+ let version2 = "unknown";
30413
+ try {
30414
+ const pkgPath = join2(skillsDir, skillName, "package.json");
30415
+ if (existsSync2(pkgPath)) {
30416
+ const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
30417
+ version2 = pkg.version || "unknown";
30418
+ }
30419
+ } catch {}
30420
+ meta3.skills[name] = { installedAt: new Date().toISOString(), version: version2 };
30421
+ saveMeta(skillsDir, meta3);
30422
+ }
30423
+ function recordRemove(skillsDir, name) {
30424
+ const meta3 = loadMeta(skillsDir);
30425
+ delete meta3.skills[name];
30426
+ saveMeta(skillsDir, meta3);
30427
+ }
30315
30428
  function getInstalledSkills(targetDir = process.cwd()) {
30316
- const skillsDir = join(targetDir, ".skills");
30317
- if (!existsSync(skillsDir)) {
30429
+ const skillsDir = join2(targetDir, ".skills");
30430
+ if (!existsSync2(skillsDir)) {
30318
30431
  return [];
30319
30432
  }
30320
- return readdirSync(skillsDir).filter((f) => {
30321
- const fullPath = join(skillsDir, f);
30433
+ return readdirSync2(skillsDir).filter((f) => {
30434
+ const fullPath = join2(skillsDir, f);
30322
30435
  return f.startsWith("skill-") && statSync(fullPath).isDirectory();
30323
30436
  }).map((f) => f.replace("skill-", ""));
30324
30437
  }
30325
30438
  function removeSkill(name, targetDir = process.cwd()) {
30326
30439
  const skillName = normalizeSkillName(name);
30327
- const skillsDir = join(targetDir, ".skills");
30328
- const skillPath = join(skillsDir, skillName);
30329
- if (!existsSync(skillPath)) {
30440
+ const skillsDir = join2(targetDir, ".skills");
30441
+ const skillPath = join2(skillsDir, skillName);
30442
+ if (!existsSync2(skillPath)) {
30330
30443
  return false;
30331
30444
  }
30332
30445
  rmSync(skillPath, { recursive: true, force: true });
30333
30446
  updateSkillsIndex(skillsDir);
30447
+ recordRemove(skillsDir, name);
30334
30448
  return true;
30335
30449
  }
30336
- var AGENT_TARGETS = ["claude", "codex", "gemini"];
30450
+ var AGENT_TARGETS = ["claude", "codex", "gemini", "pi", "opencode"];
30451
+ var AGENT_LABELS = {
30452
+ claude: "Claude Code",
30453
+ codex: "Codex CLI",
30454
+ gemini: "Gemini CLI",
30455
+ pi: "pi.dev",
30456
+ opencode: "OpenCode"
30457
+ };
30337
30458
  function resolveAgents(agentArg) {
30338
30459
  if (agentArg === "all")
30339
30460
  return [...AGENT_TARGETS];
@@ -30344,27 +30465,31 @@ function resolveAgents(agentArg) {
30344
30465
  return [agent];
30345
30466
  }
30346
30467
  function getAgentSkillsDir(agent, scope = "global", projectDir) {
30347
- const agentDir = `.${agent}`;
30348
- if (scope === "project") {
30349
- return join(projectDir || process.cwd(), agentDir, "skills");
30468
+ const base = projectDir || process.cwd();
30469
+ switch (agent) {
30470
+ case "pi":
30471
+ return scope === "project" ? join2(base, ".pi", "skills") : join2(homedir2(), ".pi", "agent", "skills");
30472
+ case "opencode":
30473
+ return scope === "project" ? join2(base, ".opencode", "skills") : join2(homedir2(), ".opencode", "skills");
30474
+ default:
30475
+ return scope === "project" ? join2(base, `.${agent}`, "skills") : join2(homedir2(), `.${agent}`, "skills");
30350
30476
  }
30351
- return join(homedir(), agentDir, "skills");
30352
30477
  }
30353
30478
  function getAgentSkillPath(name, agent, scope = "global", projectDir) {
30354
30479
  const skillName = normalizeSkillName(name);
30355
- return join(getAgentSkillsDir(agent, scope, projectDir), skillName);
30480
+ return join2(getAgentSkillsDir(agent, scope, projectDir), skillName);
30356
30481
  }
30357
30482
  function installSkillForAgent(name, options, generateSkillMd) {
30358
30483
  const { agent, scope = "global", projectDir } = options;
30359
30484
  const skillName = normalizeSkillName(name);
30360
30485
  const sourcePath = getSkillPath(name);
30361
- if (!existsSync(sourcePath)) {
30486
+ if (!existsSync2(sourcePath)) {
30362
30487
  return { skill: name, success: false, error: `Skill '${name}' not found` };
30363
30488
  }
30364
30489
  let skillMdContent = null;
30365
- const skillMdPath = join(sourcePath, "SKILL.md");
30366
- if (existsSync(skillMdPath)) {
30367
- skillMdContent = readFileSync(skillMdPath, "utf-8");
30490
+ const skillMdPath = join2(sourcePath, "SKILL.md");
30491
+ if (existsSync2(skillMdPath)) {
30492
+ skillMdContent = readFileSync2(skillMdPath, "utf-8");
30368
30493
  } else if (generateSkillMd) {
30369
30494
  skillMdContent = generateSkillMd(name);
30370
30495
  }
@@ -30372,9 +30497,28 @@ function installSkillForAgent(name, options, generateSkillMd) {
30372
30497
  return { skill: name, success: false, error: `No SKILL.md found and could not generate one for '${name}'` };
30373
30498
  }
30374
30499
  const destDir = getAgentSkillPath(name, agent, scope, projectDir);
30500
+ if (scope === "global") {
30501
+ const agentBaseDir = agent === "pi" ? join2(homedir2(), ".pi", "agent") : join2(homedir2(), `.${agent}`);
30502
+ if (!existsSync2(agentBaseDir)) {
30503
+ return {
30504
+ skill: name,
30505
+ success: false,
30506
+ error: `Agent directory ${agentBaseDir} does not exist. Is ${AGENT_LABELS[agent]} installed?`
30507
+ };
30508
+ }
30509
+ try {
30510
+ accessSync(agentBaseDir, constants.W_OK);
30511
+ } catch {
30512
+ return {
30513
+ skill: name,
30514
+ success: false,
30515
+ error: `Agent directory ${agentBaseDir} is not writable. Check permissions.`
30516
+ };
30517
+ }
30518
+ }
30375
30519
  try {
30376
30520
  mkdirSync(destDir, { recursive: true });
30377
- writeFileSync(join(destDir, "SKILL.md"), skillMdContent);
30521
+ writeFileSync(join2(destDir, "SKILL.md"), skillMdContent);
30378
30522
  return { skill: name, success: true, path: destDir };
30379
30523
  } catch (error48) {
30380
30524
  return {
@@ -30387,7 +30531,7 @@ function installSkillForAgent(name, options, generateSkillMd) {
30387
30531
  function removeSkillForAgent(name, options) {
30388
30532
  const { agent, scope = "global", projectDir } = options;
30389
30533
  const destDir = getAgentSkillPath(name, agent, scope, projectDir);
30390
- if (!existsSync(destDir)) {
30534
+ if (!existsSync2(destDir)) {
30391
30535
  return false;
30392
30536
  }
30393
30537
  rmSync(destDir, { recursive: true, force: true });
@@ -30395,16 +30539,16 @@ function removeSkillForAgent(name, options) {
30395
30539
  }
30396
30540
 
30397
30541
  // src/lib/skillinfo.ts
30398
- import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync as readdirSync2 } from "fs";
30399
- import { join as join2 } from "path";
30542
+ import { existsSync as existsSync3, readFileSync as readFileSync3, readdirSync as readdirSync3 } from "fs";
30543
+ import { join as join3 } from "path";
30400
30544
  function getSkillDocs(name) {
30401
30545
  const skillPath = getSkillPath(name);
30402
- if (!existsSync2(skillPath))
30546
+ if (!existsSync3(skillPath))
30403
30547
  return null;
30404
30548
  return {
30405
- skillMd: readIfExists(join2(skillPath, "SKILL.md")),
30406
- readme: readIfExists(join2(skillPath, "README.md")),
30407
- claudeMd: readIfExists(join2(skillPath, "CLAUDE.md"))
30549
+ skillMd: readIfExists(join3(skillPath, "SKILL.md")),
30550
+ readme: readIfExists(join3(skillPath, "README.md")),
30551
+ claudeMd: readIfExists(join3(skillPath, "CLAUDE.md"))
30408
30552
  };
30409
30553
  }
30410
30554
  function getSkillBestDoc(name) {
@@ -30415,11 +30559,11 @@ function getSkillBestDoc(name) {
30415
30559
  }
30416
30560
  function getSkillRequirements(name) {
30417
30561
  const skillPath = getSkillPath(name);
30418
- if (!existsSync2(skillPath))
30562
+ if (!existsSync3(skillPath))
30419
30563
  return null;
30420
30564
  const texts = [];
30421
30565
  for (const file2 of ["SKILL.md", "README.md", "CLAUDE.md", ".env.example", ".env.local.example"]) {
30422
- const content = readIfExists(join2(skillPath, file2));
30566
+ const content = readIfExists(join3(skillPath, file2));
30423
30567
  if (content)
30424
30568
  texts.push(content);
30425
30569
  }
@@ -30446,10 +30590,10 @@ function getSkillRequirements(name) {
30446
30590
  }
30447
30591
  let cliCommand = null;
30448
30592
  let dependencies = {};
30449
- const pkgPath = join2(skillPath, "package.json");
30450
- if (existsSync2(pkgPath)) {
30593
+ const pkgPath = join3(skillPath, "package.json");
30594
+ if (existsSync3(pkgPath)) {
30451
30595
  try {
30452
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
30596
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
30453
30597
  if (pkg.bin) {
30454
30598
  const binKeys = Object.keys(pkg.bin);
30455
30599
  if (binKeys.length > 0)
@@ -30469,25 +30613,25 @@ async function runSkill(name, args, options = {}) {
30469
30613
  const skillName = normalizeSkillName(name);
30470
30614
  let skillPath;
30471
30615
  if (options.installed) {
30472
- skillPath = join2(process.cwd(), ".skills", skillName);
30616
+ skillPath = join3(process.cwd(), ".skills", skillName);
30473
30617
  } else {
30474
- const installedPath = join2(process.cwd(), ".skills", skillName);
30475
- if (existsSync2(installedPath)) {
30618
+ const installedPath = join3(process.cwd(), ".skills", skillName);
30619
+ if (existsSync3(installedPath)) {
30476
30620
  skillPath = installedPath;
30477
30621
  } else {
30478
30622
  skillPath = getSkillPath(name);
30479
30623
  }
30480
30624
  }
30481
- if (!existsSync2(skillPath)) {
30625
+ if (!existsSync3(skillPath)) {
30482
30626
  return { exitCode: 1, error: `Skill '${name}' not found` };
30483
30627
  }
30484
- const pkgPath = join2(skillPath, "package.json");
30485
- if (!existsSync2(pkgPath)) {
30628
+ const pkgPath = join3(skillPath, "package.json");
30629
+ if (!existsSync3(pkgPath)) {
30486
30630
  return { exitCode: 1, error: `No package.json in skill '${name}'` };
30487
30631
  }
30488
30632
  let entryPoint;
30489
30633
  try {
30490
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
30634
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
30491
30635
  if (pkg.bin) {
30492
30636
  const binValues = Object.values(pkg.bin);
30493
30637
  entryPoint = binValues[0];
@@ -30501,12 +30645,12 @@ async function runSkill(name, args, options = {}) {
30501
30645
  } catch {
30502
30646
  return { exitCode: 1, error: `Failed to parse package.json for skill '${name}'` };
30503
30647
  }
30504
- const entryPath = join2(skillPath, entryPoint);
30505
- if (!existsSync2(entryPath)) {
30648
+ const entryPath = join3(skillPath, entryPoint);
30649
+ if (!existsSync3(entryPath)) {
30506
30650
  return { exitCode: 1, error: `Entry point '${entryPoint}' not found in skill '${name}'` };
30507
30651
  }
30508
- const nodeModules = join2(skillPath, "node_modules");
30509
- if (!existsSync2(nodeModules)) {
30652
+ const nodeModules = join3(skillPath, "node_modules");
30653
+ if (!existsSync3(nodeModules)) {
30510
30654
  const install = Bun.spawn(["bun", "install", "--no-save"], {
30511
30655
  cwd: skillPath,
30512
30656
  stdout: "pipe",
@@ -30523,12 +30667,99 @@ async function runSkill(name, args, options = {}) {
30523
30667
  const exitCode = await proc.exited;
30524
30668
  return { exitCode };
30525
30669
  }
30670
+ function detectProjectSkills(cwd = process.cwd()) {
30671
+ const pkgPath = join3(cwd, "package.json");
30672
+ if (!existsSync3(pkgPath)) {
30673
+ const alwaysRecommend = ["implementation-plan", "write", "deepresearch"];
30674
+ const recommended2 = alwaysRecommend.map((name) => loadRegistry().find((s) => s.name === name)).filter((s) => s !== undefined);
30675
+ return { detected: [], recommended: recommended2 };
30676
+ }
30677
+ let pkg;
30678
+ try {
30679
+ pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
30680
+ } catch {
30681
+ const alwaysRecommend = ["implementation-plan", "write", "deepresearch"];
30682
+ const recommended2 = alwaysRecommend.map((name) => loadRegistry().find((s) => s.name === name)).filter((s) => s !== undefined);
30683
+ return { detected: [], recommended: recommended2 };
30684
+ }
30685
+ const allDeps = {
30686
+ ...pkg.dependencies,
30687
+ ...pkg.devDependencies
30688
+ };
30689
+ const depNames = Object.keys(allDeps);
30690
+ const detected = [];
30691
+ const recommendedNames = new Set;
30692
+ for (const name of ["implementation-plan", "write", "deepresearch"]) {
30693
+ recommendedNames.add(name);
30694
+ }
30695
+ const frontendDeps = ["next", "react", "vue", "svelte", "nuxt", "@nuxtjs/nuxt"];
30696
+ for (const dep of frontendDeps) {
30697
+ if (depNames.some((d) => d === dep || d.startsWith(`${dep}/`))) {
30698
+ detected.push(dep);
30699
+ for (const name of ["image", "generate-favicon", "seo-brief-builder"]) {
30700
+ recommendedNames.add(name);
30701
+ }
30702
+ break;
30703
+ }
30704
+ }
30705
+ const backendDeps = ["express", "fastify", "hono", "koa", "@hono/hono"];
30706
+ for (const dep of backendDeps) {
30707
+ if (depNames.some((d) => d === dep || d.startsWith(`${dep}/`))) {
30708
+ detected.push(dep);
30709
+ for (const name of ["api-test-suite", "apidocs"]) {
30710
+ recommendedNames.add(name);
30711
+ }
30712
+ break;
30713
+ }
30714
+ }
30715
+ const aiDeps = ["@anthropic-ai/sdk", "openai", "@openai/openai", "anthropic"];
30716
+ for (const dep of aiDeps) {
30717
+ if (depNames.includes(dep)) {
30718
+ detected.push(dep);
30719
+ for (const name of ["deepresearch", "webcrawling"]) {
30720
+ recommendedNames.add(name);
30721
+ }
30722
+ break;
30723
+ }
30724
+ }
30725
+ if (depNames.includes("stripe")) {
30726
+ detected.push("stripe");
30727
+ recommendedNames.add("invoice");
30728
+ }
30729
+ const emailDeps = ["nodemailer", "@sendgrid/mail", "@sendgrid/client"];
30730
+ for (const dep of emailDeps) {
30731
+ if (depNames.includes(dep)) {
30732
+ detected.push(dep);
30733
+ for (const name of ["gmail", "email-campaign"]) {
30734
+ recommendedNames.add(name);
30735
+ }
30736
+ break;
30737
+ }
30738
+ }
30739
+ const testDeps = ["vitest", "jest", "mocha", "@jest/core"];
30740
+ for (const dep of testDeps) {
30741
+ if (depNames.includes(dep)) {
30742
+ detected.push(dep);
30743
+ recommendedNames.add("api-test-suite");
30744
+ break;
30745
+ }
30746
+ }
30747
+ if (depNames.includes("typescript")) {
30748
+ detected.push("typescript");
30749
+ for (const name of ["scaffold-project", "deploy"]) {
30750
+ recommendedNames.add(name);
30751
+ }
30752
+ }
30753
+ const uniqueDetected = Array.from(new Set(detected));
30754
+ const recommended = Array.from(recommendedNames).map((name) => loadRegistry().find((s) => s.name === name)).filter((s) => s !== undefined);
30755
+ return { detected: uniqueDetected, recommended };
30756
+ }
30526
30757
  function generateSkillMd(name) {
30527
30758
  const meta3 = getSkill(name);
30528
30759
  if (!meta3)
30529
30760
  return null;
30530
30761
  const skillPath = getSkillPath(name);
30531
- if (!existsSync2(skillPath))
30762
+ if (!existsSync3(skillPath))
30532
30763
  return null;
30533
30764
  const frontmatter = [
30534
30765
  "---",
@@ -30537,13 +30768,13 @@ function generateSkillMd(name) {
30537
30768
  "---"
30538
30769
  ].join(`
30539
30770
  `);
30540
- const readme = readIfExists(join2(skillPath, "README.md"));
30541
- const claudeMd = readIfExists(join2(skillPath, "CLAUDE.md"));
30771
+ const readme = readIfExists(join3(skillPath, "README.md"));
30772
+ const claudeMd = readIfExists(join3(skillPath, "CLAUDE.md"));
30542
30773
  let cliCommand = null;
30543
- const pkgPath = join2(skillPath, "package.json");
30544
- if (existsSync2(pkgPath)) {
30774
+ const pkgPath = join3(skillPath, "package.json");
30775
+ if (existsSync3(pkgPath)) {
30545
30776
  try {
30546
- const pkg = JSON.parse(readFileSync2(pkgPath, "utf-8"));
30777
+ const pkg = JSON.parse(readFileSync3(pkgPath, "utf-8"));
30547
30778
  if (pkg.bin) {
30548
30779
  const binKeys = Object.keys(pkg.bin);
30549
30780
  if (binKeys.length > 0)
@@ -30618,13 +30849,141 @@ function extractEnvVars(text) {
30618
30849
  }
30619
30850
  function readIfExists(path) {
30620
30851
  try {
30621
- if (existsSync2(path)) {
30622
- return readFileSync2(path, "utf-8");
30852
+ if (existsSync3(path)) {
30853
+ return readFileSync3(path, "utf-8");
30623
30854
  }
30624
30855
  } catch {}
30625
30856
  return null;
30626
30857
  }
30627
30858
 
30859
+ // src/lib/scheduler.ts
30860
+ import { existsSync as existsSync4, readFileSync as readFileSync4, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
30861
+ import { join as join4 } from "path";
30862
+ function getSchedulesPath(targetDir = process.cwd()) {
30863
+ return join4(targetDir, ".skills", "schedules.json");
30864
+ }
30865
+ function loadSchedules(targetDir = process.cwd()) {
30866
+ const path = getSchedulesPath(targetDir);
30867
+ if (existsSync4(path)) {
30868
+ try {
30869
+ return JSON.parse(readFileSync4(path, "utf-8"));
30870
+ } catch {}
30871
+ }
30872
+ return { version: 1, schedules: [] };
30873
+ }
30874
+ function saveSchedules(data, targetDir = process.cwd()) {
30875
+ const path = getSchedulesPath(targetDir);
30876
+ const dir = join4(targetDir, ".skills");
30877
+ if (!existsSync4(dir))
30878
+ mkdirSync2(dir, { recursive: true });
30879
+ writeFileSync2(path, JSON.stringify(data, null, 2));
30880
+ }
30881
+ function validateCron(expr) {
30882
+ const fields = expr.trim().split(/\s+/);
30883
+ if (fields.length !== 5) {
30884
+ return { valid: false, error: `Expected 5 fields, got ${fields.length}. Format: "minute hour day-of-month month day-of-week"` };
30885
+ }
30886
+ return { valid: true };
30887
+ }
30888
+ function getNextRun(cron, from = new Date) {
30889
+ const { valid } = validateCron(cron);
30890
+ if (!valid)
30891
+ return null;
30892
+ const [minuteF, hourF, domF, monthF, dowF] = cron.trim().split(/\s+/);
30893
+ function parseField(f, min, max) {
30894
+ if (f === "*")
30895
+ return Array.from({ length: max - min + 1 }, (_, i) => i + min);
30896
+ if (f.startsWith("*/")) {
30897
+ const step = parseInt(f.slice(2));
30898
+ if (isNaN(step))
30899
+ return [];
30900
+ const vals = [];
30901
+ for (let i = min;i <= max; i += step)
30902
+ vals.push(i);
30903
+ return vals;
30904
+ }
30905
+ return f.split(",").flatMap((part) => {
30906
+ if (part.includes("-")) {
30907
+ const [lo, hi] = part.split("-").map(Number);
30908
+ return Array.from({ length: hi - lo + 1 }, (_, i) => i + lo);
30909
+ }
30910
+ const n = parseInt(part);
30911
+ return isNaN(n) ? [] : [n];
30912
+ });
30913
+ }
30914
+ const minutes = parseField(minuteF, 0, 59);
30915
+ const hours = parseField(hourF, 0, 23);
30916
+ const doms = parseField(domF, 1, 31);
30917
+ const months = parseField(monthF, 1, 12);
30918
+ const dows = parseField(dowF, 0, 6);
30919
+ const candidate = new Date(from);
30920
+ candidate.setSeconds(0, 0);
30921
+ candidate.setMinutes(candidate.getMinutes() + 1);
30922
+ const limit = new Date(from);
30923
+ limit.setFullYear(limit.getFullYear() + 1);
30924
+ while (candidate < limit) {
30925
+ const month = candidate.getMonth() + 1;
30926
+ const dom = candidate.getDate();
30927
+ const dow = candidate.getDay();
30928
+ const hour = candidate.getHours();
30929
+ const minute = candidate.getMinutes();
30930
+ if (!months.includes(month)) {
30931
+ candidate.setMonth(candidate.getMonth() + 1, 1);
30932
+ candidate.setHours(0, 0, 0, 0);
30933
+ continue;
30934
+ }
30935
+ if (!doms.includes(dom) || !dows.includes(dow)) {
30936
+ candidate.setDate(candidate.getDate() + 1);
30937
+ candidate.setHours(0, 0, 0, 0);
30938
+ continue;
30939
+ }
30940
+ if (!hours.includes(hour)) {
30941
+ candidate.setHours(candidate.getHours() + 1, 0, 0, 0);
30942
+ continue;
30943
+ }
30944
+ if (!minutes.includes(minute)) {
30945
+ candidate.setMinutes(candidate.getMinutes() + 1, 0, 0);
30946
+ continue;
30947
+ }
30948
+ return new Date(candidate);
30949
+ }
30950
+ return null;
30951
+ }
30952
+ function addSchedule(skill, cron, options = {}) {
30953
+ const { valid, error: error48 } = validateCron(cron);
30954
+ if (!valid)
30955
+ return { schedule: null, error: error48 };
30956
+ const data = loadSchedules(options.targetDir);
30957
+ const id = `${skill}-${Date.now()}`;
30958
+ const now = new Date;
30959
+ const nextRun = getNextRun(cron, now);
30960
+ const schedule = {
30961
+ id,
30962
+ name: options.name || `${skill} (${cron})`,
30963
+ skill,
30964
+ cron,
30965
+ args: options.args,
30966
+ enabled: true,
30967
+ createdAt: now.toISOString(),
30968
+ nextRun: nextRun?.toISOString()
30969
+ };
30970
+ data.schedules.push(schedule);
30971
+ saveSchedules(data, options.targetDir);
30972
+ return { schedule };
30973
+ }
30974
+ function listSchedules(targetDir) {
30975
+ return loadSchedules(targetDir).schedules;
30976
+ }
30977
+ function removeSchedule(idOrName, targetDir) {
30978
+ const data = loadSchedules(targetDir);
30979
+ const before = data.schedules.length;
30980
+ data.schedules = data.schedules.filter((s) => s.id !== idOrName && s.name !== idOrName);
30981
+ if (data.schedules.length === before)
30982
+ return false;
30983
+ saveSchedules(data, targetDir);
30984
+ return true;
30985
+ }
30986
+
30628
30987
  // src/mcp/index.ts
30629
30988
  var server = new McpServer({
30630
30989
  name: "skills",
@@ -30633,30 +30992,90 @@ var server = new McpServer({
30633
30992
  function stripNulls(obj) {
30634
30993
  return Object.fromEntries(Object.entries(obj).filter(([, v]) => v !== null && v !== undefined && !(Array.isArray(v) && v.length === 0)));
30635
30994
  }
30995
+ var searchCache = new Map;
30996
+ var CACHE_MAX = 100;
30997
+ function cacheGet(key) {
30998
+ return searchCache.get(key);
30999
+ }
31000
+ function cacheSet(key, value) {
31001
+ if (searchCache.size >= CACHE_MAX) {
31002
+ const first = searchCache.keys().next().value;
31003
+ if (first !== undefined)
31004
+ searchCache.delete(first);
31005
+ }
31006
+ searchCache.set(key, value);
31007
+ }
31008
+ function cacheClear() {
31009
+ searchCache.clear();
31010
+ }
31011
+ function mcpError(code, message, suggestions) {
31012
+ const obj = { code, message };
31013
+ if (suggestions && suggestions.length > 0)
31014
+ obj.suggestions = suggestions;
31015
+ return {
31016
+ content: [{ type: "text", text: JSON.stringify(obj) }],
31017
+ isError: true
31018
+ };
31019
+ }
30636
31020
  server.registerTool("list_skills", {
30637
31021
  title: "List Skills",
30638
- description: "List skills. Returns {name,category} by default; detail:true for full objects.",
31022
+ description: "List skills. Returns {name,category} by default; detail:true for full objects. Supports limit/offset pagination.",
30639
31023
  inputSchema: {
30640
31024
  category: exports_external.string().optional(),
30641
- detail: exports_external.boolean().optional()
31025
+ detail: exports_external.boolean().optional(),
31026
+ limit: exports_external.number().optional(),
31027
+ offset: exports_external.number().optional()
31028
+ }
31029
+ }, async ({ category, detail, limit, offset }) => {
31030
+ const skills = category ? getSkillsByCategory(category) : loadRegistry();
31031
+ const mapped = detail ? skills : skills.map((s) => ({ name: s.name, category: s.category }));
31032
+ if (limit !== undefined || offset !== undefined) {
31033
+ const start = offset || 0;
31034
+ const sliced = limit !== undefined ? mapped.slice(start, start + limit) : mapped.slice(start);
31035
+ return {
31036
+ content: [{ type: "text", text: JSON.stringify({ skills: sliced, total: mapped.length, offset: start, limit: limit ?? null }) }]
31037
+ };
30642
31038
  }
30643
- }, async ({ category, detail }) => {
30644
- const skills = category ? getSkillsByCategory(category) : SKILLS;
30645
- const result = detail ? skills : skills.map((s) => ({ name: s.name, category: s.category }));
30646
31039
  return {
30647
- content: [{ type: "text", text: JSON.stringify(result) }]
31040
+ content: [{ type: "text", text: JSON.stringify(mapped) }]
31041
+ };
31042
+ });
31043
+ server.registerTool("list_installed_skills", {
31044
+ title: "List Installed Skills",
31045
+ description: "List skills installed in the current project's .skills/ directory.",
31046
+ inputSchema: {
31047
+ directory: exports_external.string().optional()
31048
+ }
31049
+ }, async ({ directory }) => {
31050
+ const dir = directory || process.cwd();
31051
+ const installed = getInstalledSkills(dir);
31052
+ return {
31053
+ content: [{ type: "text", text: JSON.stringify({ directory: dir, count: installed.length, skills: installed }) }]
30648
31054
  };
30649
31055
  });
30650
31056
  server.registerTool("search_skills", {
30651
31057
  title: "Search Skills",
30652
- description: "Search skills by name, description, or tags. Returns compact list by default.",
31058
+ description: "Search skills by name, description, or tags. Returns compact list by default. Supports limit/offset pagination.",
30653
31059
  inputSchema: {
30654
31060
  query: exports_external.string(),
30655
- detail: exports_external.boolean().optional()
30656
- }
30657
- }, async ({ query, detail }) => {
30658
- const results = searchSkills(query);
31061
+ detail: exports_external.boolean().optional(),
31062
+ limit: exports_external.number().optional(),
31063
+ offset: exports_external.number().optional()
31064
+ }
31065
+ }, async ({ query, detail, limit, offset }) => {
31066
+ const cacheKey = `${query}:${detail ?? false}`;
31067
+ const cached2 = cacheGet(cacheKey);
31068
+ const results = cached2 ? cached2 : searchSkills(query);
31069
+ if (!cached2)
31070
+ cacheSet(cacheKey, results);
30659
31071
  const out = detail ? results : results.map((s) => ({ name: s.name, category: s.category }));
31072
+ if (limit !== undefined || offset !== undefined) {
31073
+ const start = offset || 0;
31074
+ const sliced = limit !== undefined ? out.slice(start, start + limit) : out.slice(start);
31075
+ return {
31076
+ content: [{ type: "text", text: JSON.stringify({ skills: sliced, total: out.length, offset: start, limit: limit ?? null }) }]
31077
+ };
31078
+ }
30660
31079
  return {
30661
31080
  content: [{ type: "text", text: JSON.stringify(out) }]
30662
31081
  };
@@ -30670,7 +31089,7 @@ server.registerTool("get_skill_info", {
30670
31089
  }, async ({ name }) => {
30671
31090
  const skill = getSkill(name);
30672
31091
  if (!skill) {
30673
- return { content: [{ type: "text", text: `Skill '${name}' not found` }], isError: true };
31092
+ return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
30674
31093
  }
30675
31094
  const reqs = getSkillRequirements(name);
30676
31095
  const result = stripNulls({ ...skill, ...reqs });
@@ -30687,13 +31106,13 @@ server.registerTool("get_skill_docs", {
30687
31106
  }, async ({ name }) => {
30688
31107
  const doc2 = getSkillBestDoc(name);
30689
31108
  if (!doc2) {
30690
- return { content: [{ type: "text", text: `No documentation found for '${name}'` }], isError: true };
31109
+ return mcpError("NO_DOCS", `No documentation found for '${name}'`);
30691
31110
  }
30692
31111
  return { content: [{ type: "text", text: doc2 }] };
30693
31112
  });
30694
31113
  server.registerTool("install_skill", {
30695
31114
  title: "Install Skill",
30696
- description: "Install a skill to .skills/ or to an agent dir (for: claude|codex|gemini|all).",
31115
+ description: "Install a skill to .skills/ or to an agent dir (for: claude|codex|gemini|pi|opencode|all).",
30697
31116
  inputSchema: {
30698
31117
  name: exports_external.string(),
30699
31118
  for: exports_external.string().optional(),
@@ -30705,10 +31124,7 @@ server.registerTool("install_skill", {
30705
31124
  try {
30706
31125
  agents = resolveAgents(agentArg);
30707
31126
  } catch (err) {
30708
- return {
30709
- content: [{ type: "text", text: err.message }],
30710
- isError: true
30711
- };
31127
+ return mcpError("INVALID_AGENT", err.message, [...AGENT_TARGETS, "all"]);
30712
31128
  }
30713
31129
  const results = agents.map((a) => installSkillForAgent(name, { agent: a, scope: scope || "global" }, generateSkillMd));
30714
31130
  return {
@@ -30717,6 +31133,8 @@ server.registerTool("install_skill", {
30717
31133
  };
30718
31134
  }
30719
31135
  const result = installSkill(name);
31136
+ if (result.success)
31137
+ cacheClear();
30720
31138
  return {
30721
31139
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
30722
31140
  isError: !result.success
@@ -30734,8 +31152,7 @@ server.registerTool("install_category", {
30734
31152
  const matchedCategory = CATEGORIES.find((c) => c.toLowerCase() === category.toLowerCase());
30735
31153
  if (!matchedCategory) {
30736
31154
  return {
30737
- content: [{ type: "text", text: `Unknown category: ${category}. Available: ${CATEGORIES.join(", ")}` }],
30738
- isError: true
31155
+ ...mcpError("UNKNOWN_CATEGORY", `Unknown category: ${category}`, CATEGORIES.slice())
30739
31156
  };
30740
31157
  }
30741
31158
  const categorySkills = getSkillsByCategory(matchedCategory);
@@ -30745,10 +31162,7 @@ server.registerTool("install_category", {
30745
31162
  try {
30746
31163
  agents = resolveAgents(agentArg);
30747
31164
  } catch (err) {
30748
- return {
30749
- content: [{ type: "text", text: err.message }],
30750
- isError: true
30751
- };
31165
+ return mcpError("INVALID_AGENT", err.message, [...AGENT_TARGETS, "all"]);
30752
31166
  }
30753
31167
  const results2 = [];
30754
31168
  for (const name of names) {
@@ -30782,10 +31196,7 @@ server.registerTool("remove_skill", {
30782
31196
  try {
30783
31197
  agents = resolveAgents(agentArg);
30784
31198
  } catch (err) {
30785
- return {
30786
- content: [{ type: "text", text: err.message }],
30787
- isError: true
30788
- };
31199
+ return mcpError("INVALID_AGENT", err.message, [...AGENT_TARGETS, "all"]);
30789
31200
  }
30790
31201
  const results = agents.map((a) => ({
30791
31202
  skill: name,
@@ -30797,6 +31208,8 @@ server.registerTool("remove_skill", {
30797
31208
  };
30798
31209
  }
30799
31210
  const removed = removeSkill(name);
31211
+ if (removed)
31212
+ cacheClear();
30800
31213
  return {
30801
31214
  content: [{ type: "text", text: JSON.stringify({ skill: name, removed }, null, 2) }]
30802
31215
  };
@@ -30816,7 +31229,7 @@ server.registerTool("list_tags", {
30816
31229
  description: "List all unique skill tags with occurrence counts."
30817
31230
  }, async () => {
30818
31231
  const tagCounts = new Map;
30819
- for (const skill of SKILLS) {
31232
+ for (const skill of loadRegistry()) {
30820
31233
  for (const tag of skill.tags) {
30821
31234
  tagCounts.set(tag, (tagCounts.get(tag) ?? 0) + 1);
30822
31235
  }
@@ -30833,7 +31246,7 @@ server.registerTool("get_requirements", {
30833
31246
  }, async ({ name }) => {
30834
31247
  const reqs = getSkillRequirements(name);
30835
31248
  if (!reqs) {
30836
- return { content: [{ type: "text", text: `Skill '${name}' not found` }], isError: true };
31249
+ return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
30837
31250
  }
30838
31251
  return { content: [{ type: "text", text: JSON.stringify(reqs, null, 2) }] };
30839
31252
  });
@@ -30847,7 +31260,7 @@ server.registerTool("run_skill", {
30847
31260
  }, async ({ name, args }) => {
30848
31261
  const skill = getSkill(name);
30849
31262
  if (!skill) {
30850
- return { content: [{ type: "text", text: `Skill '${name}' not found` }], isError: true };
31263
+ return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
30851
31264
  }
30852
31265
  const result = await runSkill(name, args || []);
30853
31266
  if (result.error) {
@@ -30890,10 +31303,7 @@ server.registerTool("import_skills", {
30890
31303
  try {
30891
31304
  agents = resolveAgents(agentArg);
30892
31305
  } catch (err) {
30893
- return {
30894
- content: [{ type: "text", text: err.message }],
30895
- isError: true
30896
- };
31306
+ return mcpError("INVALID_AGENT", err.message, [...AGENT_TARGETS, "all"]);
30897
31307
  }
30898
31308
  for (const name of skillList) {
30899
31309
  const agentResults = agents.map((a) => installSkillForAgent(name, { agent: a, scope: scope || "global" }, generateSkillMd));
@@ -30921,21 +31331,20 @@ server.registerTool("whoami", {
30921
31331
  const version2 = package_default.version;
30922
31332
  const cwd = process.cwd();
30923
31333
  const installed = getInstalledSkills();
30924
- const agentNames = ["claude", "codex", "gemini"];
30925
31334
  const agents = [];
30926
- for (const agent of agentNames) {
30927
- const agentSkillsPath = join3(homedir2(), `.${agent}`, "skills");
30928
- const exists = existsSync3(agentSkillsPath);
31335
+ for (const agent of AGENT_TARGETS) {
31336
+ const agentSkillsPath = getAgentSkillsDir(agent, "global");
31337
+ const exists = existsSync5(agentSkillsPath);
30929
31338
  let skillCount = 0;
30930
31339
  if (exists) {
30931
31340
  try {
30932
- skillCount = readdirSync3(agentSkillsPath).filter((f) => {
30933
- const full = join3(agentSkillsPath, f);
31341
+ skillCount = readdirSync4(agentSkillsPath).filter((f) => {
31342
+ const full = join5(agentSkillsPath, f);
30934
31343
  return f.startsWith("skill-") && statSync2(full).isDirectory();
30935
31344
  }).length;
30936
31345
  } catch {}
30937
31346
  }
30938
- agents.push({ agent, path: agentSkillsPath, exists, skillCount });
31347
+ agents.push({ agent, label: AGENT_LABELS[agent], path: agentSkillsPath, exists, skillCount });
30939
31348
  }
30940
31349
  const skillsDir = getSkillPath("image").replace(/[/\\][^/\\]*$/, "");
30941
31350
  const result = {
@@ -30948,12 +31357,107 @@ server.registerTool("whoami", {
30948
31357
  };
30949
31358
  return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
30950
31359
  });
31360
+ server.registerTool("schedule_skill", {
31361
+ title: "Schedule Skill",
31362
+ description: "Add a cron schedule to run a skill at a recurring time. Cron format: 'minute hour dom month dow' (e.g. '0 9 * * *' = daily at 9am).",
31363
+ inputSchema: {
31364
+ skill: exports_external.string(),
31365
+ cron: exports_external.string(),
31366
+ name: exports_external.string().optional(),
31367
+ args: exports_external.array(exports_external.string()).optional()
31368
+ }
31369
+ }, async ({ skill, cron, name, args }) => {
31370
+ const { schedule, error: error48 } = addSchedule(skill, cron, { name, args });
31371
+ if (error48 || !schedule) {
31372
+ return { content: [{ type: "text", text: JSON.stringify({ error: error48 || "Failed to add schedule" }) }] };
31373
+ }
31374
+ return { content: [{ type: "text", text: JSON.stringify(schedule, null, 2) }] };
31375
+ });
31376
+ server.registerTool("list_schedules", {
31377
+ title: "List Schedules",
31378
+ description: "List all scheduled skill runs.",
31379
+ inputSchema: {}
31380
+ }, async () => {
31381
+ const schedules = listSchedules();
31382
+ return { content: [{ type: "text", text: JSON.stringify(schedules, null, 2) }] };
31383
+ });
31384
+ server.registerTool("remove_schedule", {
31385
+ title: "Remove Schedule",
31386
+ description: "Remove a schedule by its ID or name.",
31387
+ inputSchema: {
31388
+ id_or_name: exports_external.string()
31389
+ }
31390
+ }, async ({ id_or_name }) => {
31391
+ const removed = removeSchedule(id_or_name);
31392
+ return { content: [{ type: "text", text: JSON.stringify({ removed, id_or_name }) }] };
31393
+ });
31394
+ server.registerTool("detect_project_skills", {
31395
+ title: "Detect Project Skills",
31396
+ description: "Detect project type from package.json and return recommended skills based on dependencies.",
31397
+ inputSchema: {
31398
+ directory: exports_external.string().optional()
31399
+ }
31400
+ }, async ({ directory }) => {
31401
+ const cwd = directory || process.cwd();
31402
+ const { detected, recommended } = detectProjectSkills(cwd);
31403
+ return {
31404
+ content: [{
31405
+ type: "text",
31406
+ text: JSON.stringify({
31407
+ directory: cwd,
31408
+ detected,
31409
+ recommended: recommended.map((s) => ({ name: s.name, displayName: s.displayName, description: s.description, category: s.category }))
31410
+ }, null, 2)
31411
+ }]
31412
+ };
31413
+ });
31414
+ server.registerTool("validate_skill", {
31415
+ title: "Validate Skill",
31416
+ description: "Check a skill's structure: SKILL.md, package.json with bin entry, tsconfig.json, src/index.ts. Returns validation result with list of issues.",
31417
+ inputSchema: {
31418
+ name: exports_external.string()
31419
+ }
31420
+ }, async ({ name }) => {
31421
+ const skillPath = getSkillPath(name);
31422
+ const issues = [];
31423
+ if (!existsSync5(skillPath)) {
31424
+ return {
31425
+ content: [{ type: "text", text: JSON.stringify({ name, valid: false, issues: [`Skill directory not found: ${skillPath}`] }) }]
31426
+ };
31427
+ }
31428
+ if (!existsSync5(join5(skillPath, "SKILL.md")))
31429
+ issues.push("Missing SKILL.md");
31430
+ if (!existsSync5(join5(skillPath, "tsconfig.json")))
31431
+ issues.push("Missing tsconfig.json");
31432
+ const pkgPath = join5(skillPath, "package.json");
31433
+ if (!existsSync5(pkgPath)) {
31434
+ issues.push("Missing package.json");
31435
+ } else {
31436
+ try {
31437
+ const pkg = JSON.parse(__require("fs").readFileSync(pkgPath, "utf-8"));
31438
+ if (!pkg.bin || Object.keys(pkg.bin).length === 0)
31439
+ issues.push("package.json missing 'bin' entry");
31440
+ } catch {
31441
+ issues.push("package.json is invalid JSON");
31442
+ }
31443
+ }
31444
+ const srcDir = join5(skillPath, "src");
31445
+ if (!existsSync5(srcDir)) {
31446
+ issues.push("Missing src/ directory");
31447
+ } else if (!existsSync5(join5(srcDir, "index.ts"))) {
31448
+ issues.push("Missing src/index.ts");
31449
+ }
31450
+ const valid = issues.length === 0;
31451
+ return {
31452
+ content: [{ type: "text", text: JSON.stringify({ name, valid, path: skillPath, issues }) }]
31453
+ };
31454
+ });
30951
31455
  server.registerResource("Skills Registry", "skills://registry", {
30952
31456
  description: "Compact skill list [{name,category}]. Use skills://{name} for detail."
30953
31457
  }, async () => ({
30954
31458
  contents: [{
30955
31459
  uri: "skills://registry",
30956
- text: JSON.stringify(SKILLS.map((s) => ({ name: s.name, category: s.category }))),
31460
+ text: JSON.stringify(loadRegistry().map((s) => ({ name: s.name, category: s.category }))),
30957
31461
  mimeType: "application/json"
30958
31462
  }]
30959
31463
  }));
@@ -30978,6 +31482,7 @@ server.registerTool("search_tools", {
30978
31482
  }, async ({ query }) => {
30979
31483
  const all = [
30980
31484
  "list_skills",
31485
+ "list_installed_skills",
30981
31486
  "search_skills",
30982
31487
  "get_skill_info",
30983
31488
  "get_skill_docs",
@@ -31004,6 +31509,7 @@ server.registerTool("describe_tools", {
31004
31509
  }, async ({ names }) => {
31005
31510
  const descriptions = {
31006
31511
  list_skills: "List skills {name,category}. Params: category?, detail?",
31512
+ list_installed_skills: "List installed skills in .skills/. Params: directory?",
31007
31513
  search_skills: "Search skills by name/tags. Params: query, detail?",
31008
31514
  get_skill_info: "Get skill metadata and env vars. Params: name",
31009
31515
  get_skill_docs: "Get skill documentation. Params: name",
@@ -31022,6 +31528,32 @@ server.registerTool("describe_tools", {
31022
31528
  `);
31023
31529
  return { content: [{ type: "text", text: result }] };
31024
31530
  });
31531
+ var _agentReg = new Map;
31532
+ server.tool("register_agent", "Register this agent session. Returns agent_id for use in heartbeat/set_focus.", { name: exports_external.string(), session_id: exports_external.string().optional() }, async (a) => {
31533
+ const existing = [..._agentReg.values()].find((x) => x.name === a.name);
31534
+ if (existing) {
31535
+ existing.last_seen_at = new Date().toISOString();
31536
+ return { content: [{ type: "text", text: JSON.stringify(existing) }] };
31537
+ }
31538
+ const id = Math.random().toString(36).slice(2, 10);
31539
+ const ag = { id, name: a.name, last_seen_at: new Date().toISOString() };
31540
+ _agentReg.set(id, ag);
31541
+ return { content: [{ type: "text", text: JSON.stringify(ag) }] };
31542
+ });
31543
+ server.tool("heartbeat", "Update last_seen_at to signal agent is active.", { agent_id: exports_external.string() }, async (a) => {
31544
+ const ag = _agentReg.get(a.agent_id);
31545
+ if (!ag)
31546
+ return { content: [{ type: "text", text: `Agent not found: ${a.agent_id}` }], isError: true };
31547
+ ag.last_seen_at = new Date().toISOString();
31548
+ return { content: [{ type: "text", text: `\u2665 ${ag.name} \u2014 active` }] };
31549
+ });
31550
+ server.tool("set_focus", "Set active project context for this agent session.", { agent_id: exports_external.string(), project_id: exports_external.string().optional() }, async (a) => {
31551
+ const ag = _agentReg.get(a.agent_id);
31552
+ if (!ag)
31553
+ return { content: [{ type: "text", text: `Agent not found: ${a.agent_id}` }], isError: true };
31554
+ ag.project_id = a.project_id;
31555
+ return { content: [{ type: "text", text: a.project_id ? `Focus: ${a.project_id}` : "Focus cleared" }] };
31556
+ });
31025
31557
  async function main() {
31026
31558
  const transport = new StdioServerTransport;
31027
31559
  await server.connect(transport);