skilld 1.5.4 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/README.md +3 -3
  2. package/dist/_chunks/agent.mjs +10 -78
  3. package/dist/_chunks/agent.mjs.map +1 -1
  4. package/dist/_chunks/assemble.mjs +0 -17
  5. package/dist/_chunks/assemble.mjs.map +1 -1
  6. package/dist/_chunks/author.mjs +0 -18
  7. package/dist/_chunks/author.mjs.map +1 -1
  8. package/dist/_chunks/cache.mjs +0 -72
  9. package/dist/_chunks/cache.mjs.map +1 -1
  10. package/dist/_chunks/cache2.mjs +84 -17
  11. package/dist/_chunks/cache2.mjs.map +1 -1
  12. package/dist/_chunks/cli-helpers.mjs +2 -49
  13. package/dist/_chunks/cli-helpers.mjs.map +1 -1
  14. package/dist/_chunks/cli-helpers2.mjs +0 -11
  15. package/dist/_chunks/config.mjs +0 -27
  16. package/dist/_chunks/config.mjs.map +1 -1
  17. package/dist/_chunks/core.mjs +9 -0
  18. package/dist/_chunks/detect.mjs +29 -226
  19. package/dist/_chunks/detect.mjs.map +1 -1
  20. package/dist/_chunks/embedding-cache.mjs +0 -5
  21. package/dist/_chunks/embedding-cache2.mjs +1 -2
  22. package/dist/_chunks/formatting.mjs +0 -6
  23. package/dist/_chunks/formatting.mjs.map +1 -1
  24. package/dist/_chunks/index.d.mts +0 -10
  25. package/dist/_chunks/index.d.mts.map +1 -1
  26. package/dist/_chunks/index2.d.mts +3 -6
  27. package/dist/_chunks/index2.d.mts.map +1 -1
  28. package/dist/_chunks/index3.d.mts +2 -31
  29. package/dist/_chunks/index3.d.mts.map +1 -1
  30. package/dist/_chunks/install.mjs +0 -15
  31. package/dist/_chunks/install.mjs.map +1 -1
  32. package/dist/_chunks/libs/@sinclair/typebox.mjs +0 -444
  33. package/dist/_chunks/libs/@sinclair/typebox.mjs.map +1 -1
  34. package/dist/_chunks/list.mjs +0 -16
  35. package/dist/_chunks/list.mjs.map +1 -1
  36. package/dist/_chunks/lockfile.mjs +1 -10
  37. package/dist/_chunks/lockfile.mjs.map +1 -1
  38. package/dist/_chunks/markdown.mjs +0 -9
  39. package/dist/_chunks/markdown.mjs.map +1 -1
  40. package/dist/_chunks/package-json.mjs +0 -25
  41. package/dist/_chunks/package-json.mjs.map +1 -1
  42. package/dist/_chunks/pool2.mjs +0 -2
  43. package/dist/_chunks/pool2.mjs.map +1 -1
  44. package/dist/_chunks/prepare.mjs +8 -7
  45. package/dist/_chunks/prepare.mjs.map +1 -1
  46. package/dist/_chunks/prepare2.mjs +0 -18
  47. package/dist/_chunks/prepare2.mjs.map +1 -1
  48. package/dist/_chunks/prompts.mjs +1 -102
  49. package/dist/_chunks/prompts.mjs.map +1 -1
  50. package/dist/_chunks/retriv.mjs +23 -24
  51. package/dist/_chunks/retriv.mjs.map +1 -1
  52. package/dist/_chunks/rolldown-runtime.mjs +0 -2
  53. package/dist/_chunks/sanitize.mjs +0 -78
  54. package/dist/_chunks/sanitize.mjs.map +1 -1
  55. package/dist/_chunks/search-interactive.mjs +0 -17
  56. package/dist/_chunks/search-interactive.mjs.map +1 -1
  57. package/dist/_chunks/search.mjs +0 -19
  58. package/dist/_chunks/search2.mjs +3 -12
  59. package/dist/_chunks/search2.mjs.map +1 -1
  60. package/dist/_chunks/setup.mjs +0 -13
  61. package/dist/_chunks/setup.mjs.map +1 -1
  62. package/dist/_chunks/shared.mjs +0 -10
  63. package/dist/_chunks/shared.mjs.map +1 -1
  64. package/dist/_chunks/skills.mjs +2 -2
  65. package/dist/_chunks/skills.mjs.map +1 -1
  66. package/dist/_chunks/sources.mjs +3 -453
  67. package/dist/_chunks/sources.mjs.map +1 -1
  68. package/dist/_chunks/sync-shared.mjs +0 -16
  69. package/dist/_chunks/sync-shared2.mjs +0 -42
  70. package/dist/_chunks/sync-shared2.mjs.map +1 -1
  71. package/dist/_chunks/sync.mjs +1 -21
  72. package/dist/_chunks/sync.mjs.map +1 -1
  73. package/dist/_chunks/sync2.mjs +0 -20
  74. package/dist/_chunks/types.d.mts +0 -2
  75. package/dist/_chunks/types.d.mts.map +1 -1
  76. package/dist/_chunks/uninstall.mjs +0 -25
  77. package/dist/_chunks/uninstall.mjs.map +1 -1
  78. package/dist/_chunks/validate.mjs +0 -7
  79. package/dist/_chunks/validate.mjs.map +1 -1
  80. package/dist/_chunks/wizard.mjs +15 -12
  81. package/dist/_chunks/wizard.mjs.map +1 -1
  82. package/dist/_chunks/yaml.mjs +0 -21
  83. package/dist/_chunks/yaml.mjs.map +1 -1
  84. package/dist/agent/index.d.mts +0 -24
  85. package/dist/agent/index.d.mts.map +1 -1
  86. package/dist/agent/index.mjs +0 -8
  87. package/dist/cache/index.mjs +0 -2
  88. package/dist/cli-entry.mjs +0 -6
  89. package/dist/cli-entry.mjs.map +1 -1
  90. package/dist/cli.mjs +37 -44
  91. package/dist/cli.mjs.map +1 -1
  92. package/dist/index.mjs +0 -6
  93. package/dist/prepare.mjs +0 -12
  94. package/dist/prepare.mjs.map +1 -1
  95. package/dist/retriv/index.mjs +0 -2
  96. package/dist/retriv/worker.d.mts +0 -3
  97. package/dist/retriv/worker.d.mts.map +1 -1
  98. package/dist/retriv/worker.mjs +0 -2
  99. package/dist/retriv/worker.mjs.map +1 -1
  100. package/dist/sources/index.mjs +0 -4
  101. package/package.json +17 -17
@@ -4,40 +4,21 @@ import { d as getFilePatterns, f as getPackageRules, i as resolveSkilldCommand }
4
4
  import { a as targets, t as detectInstalledAgents } from "./detect.mjs";
5
5
  import { dirname, join, relative } from "pathe";
6
6
  import { existsSync, lstatSync, mkdirSync, symlinkSync, unlinkSync, writeFileSync } from "node:fs";
7
- //#region src/agent/prompts/optional/budget.ts
8
- /**
9
- * Dynamic budget allocation for skill sections.
10
- *
11
- * Total SKILL.md target is ~500 lines. Overhead (frontmatter, header, search, footer)
12
- * is subtracted to get the available body budget, which is divided among enabled sections.
13
- * When a package has many releases, budgets scale up.
14
- */
15
7
  const TOTAL_TARGET = 500;
16
8
  const DEFAULT_OVERHEAD = 30;
17
- /** Available body lines after overhead is subtracted */
18
9
  function remainingLines(overheadLines) {
19
10
  return TOTAL_TARGET - (overheadLines ?? DEFAULT_OVERHEAD);
20
11
  }
21
- /** Scale max lines based on enabled section count and available remaining space. */
22
12
  function maxLines(min, max, sectionCount, overheadLines) {
23
13
  const remaining = remainingLines(overheadLines);
24
- const sections = Math.max(1, sectionCount ?? 1);
25
- const perSection = Math.floor(remaining / sections);
14
+ const perSection = Math.floor(remaining / Math.max(1, sectionCount ?? 1));
26
15
  const scale = budgetScale(sectionCount);
27
16
  return Math.max(min, Math.min(Math.round(max * scale), perSection));
28
17
  }
29
- /** Scale item count based on enabled section count. */
30
18
  function maxItems(min, max, sectionCount) {
31
19
  const scale = budgetScale(sectionCount);
32
20
  return Math.max(min, Math.round(max * scale));
33
21
  }
34
- /**
35
- * Boost budget for high-churn packages based on API-level release density.
36
- * Combines major/minor release count with current minor version as a churn signal.
37
- *
38
- * @param significantReleases - Count of major/minor releases (patch releases excluded)
39
- * @param minorVersion - Current minor version number (e.g., 15 for v3.15.0)
40
- */
41
22
  function releaseBoost(significantReleases, minorVersion) {
42
23
  const combined = (!significantReleases ? 0 : significantReleases <= 5 ? 0 : significantReleases <= 15 ? 1 : 2) + (!minorVersion ? 0 : minorVersion <= 3 ? 0 : minorVersion <= 10 ? 1 : 2);
43
24
  if (combined <= 0) return 1;
@@ -50,41 +31,32 @@ function budgetScale(sectionCount) {
50
31
  if (sectionCount === 3) return .7;
51
32
  return .6;
52
33
  }
53
- //#endregion
54
- //#region src/agent/prompts/optional/validate.ts
55
- /** Warns if content exceeds 150% of max lines */
56
34
  function checkLineCount(content, max) {
57
35
  const lines = content.split("\n").length;
58
36
  if (lines > Math.round(max * 1.5)) return [{ warning: `Output ${lines} lines exceeds ${max} max by >50%` }];
59
37
  return [];
60
38
  }
61
- /** Warns if content is fewer than 3 lines */
62
39
  function checkSparseness(content) {
63
40
  const lines = content.split("\n").length;
64
41
  if (lines < 3) return [{ warning: `Output only ${lines} lines — likely too sparse` }];
65
42
  return [];
66
43
  }
67
- /** Warns if sourced/bullets ratio is below minRatio */
68
44
  function checkSourceCoverage(content, minRatio = .8) {
69
45
  const bullets = (content.match(/^- /gm) || []).length;
70
46
  const sourced = (content.match(/\[source\]/g) || []).length;
71
47
  if (bullets > 2 && sourced / bullets < minRatio) return [{ warning: `Only ${sourced}/${bullets} items have source citations (need ${Math.round(minRatio * 100)}% coverage)` }];
72
48
  return [];
73
49
  }
74
- /** Warns if source links are missing .skilld/ prefix */
75
50
  function checkSourcePaths(content) {
76
51
  const badPaths = content.match(/\[source\]\(\.\/(docs|issues|discussions|releases|pkg|guide)\//g);
77
52
  if (badPaths?.length) return [{ warning: `${badPaths.length} source links missing .skilld/ prefix` }];
78
53
  return [];
79
54
  }
80
- /** Warns if source links use absolute filesystem paths instead of relative ./.skilld/ paths */
81
55
  function checkAbsolutePaths(content) {
82
56
  const absPaths = content.match(/\[source\]\(\/[^)]+\)/g);
83
57
  if (absPaths?.length) return [{ warning: `${absPaths.length} source links use absolute paths — must use relative ./.skilld/ paths` }];
84
58
  return [];
85
59
  }
86
- //#endregion
87
- //#region src/agent/prompts/optional/api-changes.ts
88
60
  function apiChangesSection({ packageName, version, hasReleases, hasChangelog, hasDocs, hasIssues, hasDiscussions, pkgFiles, features, enabledSectionCount, releaseCount, overheadLines }) {
89
61
  const [, major, minor] = version?.match(/^(\d+)\.(\d+)/) ?? [];
90
62
  const boost = releaseBoost(releaseCount, minor ? Number(minor) : void 0);
@@ -207,8 +179,6 @@ Each item: BREAKING/DEPRECATED/NEW label + API name + what changed + source link
207
179
  ].filter(Boolean)
208
180
  };
209
181
  }
210
- //#endregion
211
- //#region src/agent/prompts/optional/best-practices.ts
212
182
  function bestPracticesSection({ packageName, hasIssues, hasDiscussions, hasReleases, hasChangelog, hasDocs, pkgFiles, features, enabledSectionCount, releaseCount, version, overheadLines }) {
213
183
  const [, , minor] = version?.match(/^(\d+)\.(\d+)/) ?? [];
214
184
  const boost = 1 + (releaseBoost(releaseCount, minor ? Number(minor) : void 0) - 1) * .5;
@@ -300,8 +270,6 @@ Each item: markdown list item (-) + ${packageName}-specific pattern + why it's p
300
270
  ]
301
271
  };
302
272
  }
303
- //#endregion
304
- //#region src/agent/prompts/optional/custom.ts
305
273
  function customSection({ heading, body }, enabledSectionCount, overheadLines) {
306
274
  const customMaxLines = maxLines(50, 80, enabledSectionCount, overheadLines);
307
275
  return {
@@ -324,25 +292,19 @@ Content addressing the user's instructions above, using concise examples and sou
324
292
  rules: [`- **Custom section "${heading}":** MAX ${customMaxLines} lines, use \`## ${heading}\` heading`]
325
293
  };
326
294
  }
327
- //#endregion
328
- //#region src/agent/prompts/prompt.ts
329
- /** Output file per section (inside .skilld/) */
330
295
  const SECTION_OUTPUT_FILES = {
331
296
  "best-practices": "_BEST_PRACTICES.md",
332
297
  "api-changes": "_API_CHANGES.md",
333
298
  "custom": "_CUSTOM.md"
334
299
  };
335
- /** Merge order for final SKILL.md body */
336
300
  const SECTION_MERGE_ORDER = [
337
301
  "api-changes",
338
302
  "best-practices",
339
303
  "custom"
340
304
  ];
341
- /** Wrap section content with HTML comment markers for targeted re-assembly */
342
305
  function wrapSection(section, content) {
343
306
  return `<!-- skilld:${section} -->\n${content}\n<!-- /skilld:${section} -->`;
344
307
  }
345
- /** Extract marker-delimited sections from existing SKILL.md */
346
308
  function extractMarkedSections(md) {
347
309
  const sections = /* @__PURE__ */ new Map();
348
310
  for (const section of SECTION_MERGE_ORDER) {
@@ -357,10 +319,6 @@ function extractMarkedSections(md) {
357
319
  }
358
320
  return sections;
359
321
  }
360
- /**
361
- * Group files by parent directory with counts
362
- * e.g. `/path/to/docs/api/ (15 .md files)`
363
- */
364
322
  function formatDocTree(files) {
365
323
  const dirs = /* @__PURE__ */ new Map();
366
324
  for (const f of files) {
@@ -390,7 +348,6 @@ Use \`${cmd} search "query" -p ${packageName}\` as your primary research tool
390
348
 
391
349
  ${table}`;
392
350
  }
393
- /** Shared preamble: Security, references table, Quality Principles, doc tree */
394
351
  function buildPreamble(opts) {
395
352
  const { packageName, skillDir, hasIssues, hasDiscussions, hasReleases, hasChangelog, docFiles, docsType = "docs", hasShippedDocs = false, versionContext } = opts;
396
353
  const docsSection = docFiles?.length ? `<external-docs>\n**Documentation** (use Read tool to explore):\n${formatDocTree(docFiles)}\n</external-docs>` : "";
@@ -424,19 +381,12 @@ function getSectionDef(section, ctx, customPrompt) {
424
381
  case "custom": return customPrompt ? customSection(customPrompt, ctx.enabledSectionCount, ctx.overheadLines) : null;
425
382
  }
426
383
  }
427
- /**
428
- * Get the validate function for a section using default context (validators use fixed thresholds).
429
- * Returns null if section has no validator.
430
- */
431
384
  function getSectionValidator(section) {
432
385
  return getSectionDef(section, { packageName: "" }, section === "custom" ? {
433
386
  heading: "Custom",
434
387
  body: ""
435
388
  } : void 0)?.validate ?? null;
436
389
  }
437
- /**
438
- * Build prompt for a single section
439
- */
440
390
  function buildSectionPrompt(opts) {
441
391
  const { packageName, hasIssues, hasDiscussions, hasReleases, hasChangelog, version, section, customPrompt, skillDir } = opts;
442
392
  const versionContext = version ? ` v${version}` : "";
@@ -502,9 +452,6 @@ Write your final output to the file \`${skillDir}/.skilld/${outputFile}\` using
502
452
  After writing, run \`${cmd} validate ${skillDir}/.skilld/${outputFile}\` and fix any warnings before finishing. If unavailable, use \`${fallbackCmd} validate ${skillDir}/.skilld/${outputFile}\`.
503
453
  `;
504
454
  }
505
- /**
506
- * Build prompts for all selected sections, sharing the computed preamble
507
- */
508
455
  function buildAllSectionPrompts(opts) {
509
456
  const result = /* @__PURE__ */ new Map();
510
457
  for (const section of opts.sections) {
@@ -517,14 +464,6 @@ function buildAllSectionPrompts(opts) {
517
464
  }
518
465
  return result;
519
466
  }
520
- /**
521
- * Transform an agent-specific prompt into a portable prompt for any LLM.
522
- * - Rewrites .skilld/ paths → ./references/
523
- * - Strips ## Output section (file-writing instructions)
524
- * - Strips skilld search/validate instructions
525
- * - Replaces tool-specific language with generic equivalents
526
- * - Strips agent-specific rules
527
- */
528
467
  function portabilizePrompt(prompt, section) {
529
468
  let out = prompt;
530
469
  out = out.replace(/`[^`]*\/\.skilld\//g, (m) => m.replace(/[^`]*\/\.skilld\//, "./references/"));
@@ -551,31 +490,12 @@ function portabilizePrompt(prompt, section) {
551
490
  out = out.replace(/\n{3,}/g, "\n\n");
552
491
  return out;
553
492
  }
554
- //#endregion
555
- //#region src/agent/install.ts
556
- /**
557
- * Sanitize skill name for filesystem
558
- */
559
493
  function sanitizeName(name) {
560
494
  return name.toLowerCase().replace(/[^a-z0-9._]+/g, "-").replace(/^[.\-]+|[.\-]+$/g, "").slice(0, 255) || "unnamed-skill";
561
495
  }
562
- /**
563
- * Compute skill directory name from package name with -skilld suffix.
564
- * No collisions for monorepo packages (each gets a unique name).
565
- *
566
- * Examples:
567
- * vue → vue-skilld
568
- * @unhead/vue → unhead-vue-skilld
569
- * @unhead/react → unhead-react-skilld
570
- */
571
496
  function computeSkillDirName(packageName) {
572
497
  return `${sanitizeName(packageName)}-skilld`;
573
498
  }
574
- /**
575
- * Install a skill directly to agent skill directories.
576
- * When agents are explicitly specified, creates directories as needed.
577
- * When falling back to auto-detection, only writes to agents whose skills dir already exists.
578
- */
579
499
  function installSkillForAgents(skillName, skillContent, options = {}) {
580
500
  const isGlobal = options.global ?? false;
581
501
  const cwd = options.cwd || process.cwd();
@@ -625,12 +545,6 @@ function installSkillForAgents(skillName, skillContent, options = {}) {
625
545
  paths
626
546
  };
627
547
  }
628
- /**
629
- * Create a relative symlink from the target agent's skills dir to the shared .skills/ dir.
630
- * Only creates directories for the explicit target agent; other agents must already have
631
- * their skills dir present. This prevents skilld from polluting projects with dirs
632
- * for agents the user doesn't use (e.g. .gemini/, .agent/).
633
- */
634
548
  function linkSkillToAgents(skillName, sharedDir, cwd, agentType) {
635
549
  const targetAgents = agentType ? [[agentType, targets[agentType]]] : Object.entries(targets);
636
550
  const linkedDirs = /* @__PURE__ */ new Set();
@@ -661,9 +575,6 @@ function linkSkillToAgents(skillName, sharedDir, cwd, agentType) {
661
575
  linkedDirs.add(agentSkillsDir);
662
576
  }
663
577
  }
664
- /**
665
- * Remove per-agent symlinks for a skill when removing from shared dir.
666
- */
667
578
  function unlinkSkillFromAgents(skillName, cwd, agentType) {
668
579
  const targetAgents = agentType ? [[agentType, targets[agentType]]] : Object.entries(targets);
669
580
  for (const [, agent] of targetAgents) {
@@ -673,8 +584,6 @@ function unlinkSkillFromAgents(skillName, cwd, agentType) {
673
584
  } catch {}
674
585
  }
675
586
  }
676
- //#endregion
677
- //#region src/agent/prompts/skill.ts
678
587
  function generateSkillMd(opts) {
679
588
  const header = generatePackageHeader(opts);
680
589
  const search = !opts.eject && opts.features?.search !== false ? generateSearchBlock(opts.name) : "";
@@ -687,7 +596,6 @@ function generateSkillMd(opts) {
687
596
  const footer = generateFooter(opts.relatedSkills);
688
597
  return sanitizeMarkdown(repairMarkdown(`${generateFrontmatter(opts)}${content}\n${footer}`));
689
598
  }
690
- /** Format ISO date as short absolute date: "Jan 2025", "Dec 2024" */
691
599
  function formatShortDate(isoDate) {
692
600
  const date = new Date(isoDate);
693
601
  if (Number.isNaN(date.getTime())) return "";
@@ -739,10 +647,6 @@ function generatePackageHeader({ name, version, distTags, repoUrl, hasIssues, ha
739
647
  if (refs.length > 0) lines.push(`**References:** ${refs.join(" • ")}`);
740
648
  return lines.join("\n");
741
649
  }
742
- /**
743
- * Expand a package name into keyword variants for better trigger matching.
744
- * e.g. "@nuxt/ui" → ["nuxt ui", "nuxt/ui"], "vue-router" → ["vue router"]
745
- */
746
650
  function expandPackageName(name) {
747
651
  const variants = /* @__PURE__ */ new Set();
748
652
  const unscoped = name.replace(/^@/, "");
@@ -757,10 +661,6 @@ function expandPackageName(name) {
757
661
  variants.delete(name);
758
662
  return [...variants];
759
663
  }
760
- /**
761
- * Extract and expand GitHub repo name into keyword variants.
762
- * e.g. "motion-v" → ["motion-v", "motion v"]
763
- */
764
664
  function expandRepoName(repoUrl) {
765
665
  const variants = /* @__PURE__ */ new Set();
766
666
  const repoName = repoUrl.startsWith("http") ? repoUrl.split("/").pop() : repoUrl.split("/").pop();
@@ -820,7 +720,6 @@ function generateFooter(relatedSkills) {
820
720
  if (relatedSkills.length === 0) return "";
821
721
  return `\nRelated: ${relatedSkills.join(", ")}\n`;
822
722
  }
823
- //#endregion
824
723
  export { sanitizeName as a, SECTION_OUTPUT_FILES as c, extractMarkedSections as d, getSectionValidator as f, maxLines as g, maxItems as h, linkSkillToAgents as i, buildAllSectionPrompts as l, wrapSection as m, computeSkillDirName as n, unlinkSkillFromAgents as o, portabilizePrompt as p, installSkillForAgents as r, SECTION_MERGE_ORDER as s, generateSkillMd as t, buildSectionPrompt as u };
825
724
 
826
725
  //# sourceMappingURL=prompts.mjs.map