@skillsmith/cli 0.6.2 → 0.6.4

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 (210) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/commands/__meta__/telemetry-coverage.test.d.ts +20 -0
  4. package/dist/src/commands/__meta__/telemetry-coverage.test.d.ts.map +1 -0
  5. package/dist/src/commands/__meta__/telemetry-coverage.test.js +118 -0
  6. package/dist/src/commands/__meta__/telemetry-coverage.test.js.map +1 -0
  7. package/dist/src/commands/ab-test.d.ts +1 -0
  8. package/dist/src/commands/ab-test.d.ts.map +1 -1
  9. package/dist/src/commands/ab-test.js +17 -8
  10. package/dist/src/commands/ab-test.js.map +1 -1
  11. package/dist/src/commands/analyze.d.ts +1 -0
  12. package/dist/src/commands/analyze.d.ts.map +1 -1
  13. package/dist/src/commands/analyze.js +32 -23
  14. package/dist/src/commands/analyze.js.map +1 -1
  15. package/dist/src/commands/audit-collisions.d.ts +1 -4
  16. package/dist/src/commands/audit-collisions.d.ts.map +1 -1
  17. package/dist/src/commands/audit-collisions.js +32 -23
  18. package/dist/src/commands/audit-collisions.js.map +1 -1
  19. package/dist/src/commands/audit-sources.action.d.ts +37 -0
  20. package/dist/src/commands/audit-sources.action.d.ts.map +1 -0
  21. package/dist/src/commands/audit-sources.action.js +300 -0
  22. package/dist/src/commands/audit-sources.action.js.map +1 -0
  23. package/dist/src/commands/audit-sources.d.ts +37 -0
  24. package/dist/src/commands/audit-sources.d.ts.map +1 -0
  25. package/dist/src/commands/audit-sources.js +55 -0
  26. package/dist/src/commands/audit-sources.js.map +1 -0
  27. package/dist/src/commands/audit-sources.test.d.ts +9 -0
  28. package/dist/src/commands/audit-sources.test.d.ts.map +1 -0
  29. package/dist/src/commands/audit-sources.test.js +228 -0
  30. package/dist/src/commands/audit-sources.test.js.map +1 -0
  31. package/dist/src/commands/audit.d.ts +2 -6
  32. package/dist/src/commands/audit.d.ts.map +1 -1
  33. package/dist/src/commands/audit.js +52 -31
  34. package/dist/src/commands/audit.js.map +1 -1
  35. package/dist/src/commands/author/index.d.ts +2 -1
  36. package/dist/src/commands/author/index.d.ts.map +1 -1
  37. package/dist/src/commands/author/index.js +4 -1
  38. package/dist/src/commands/author/index.js.map +1 -1
  39. package/dist/src/commands/author/init.action.d.ts +29 -0
  40. package/dist/src/commands/author/init.action.d.ts.map +1 -0
  41. package/dist/src/commands/author/init.action.js +131 -0
  42. package/dist/src/commands/author/init.action.js.map +1 -0
  43. package/dist/src/commands/author/init.d.ts +0 -14
  44. package/dist/src/commands/author/init.d.ts.map +1 -1
  45. package/dist/src/commands/author/init.js +3 -87
  46. package/dist/src/commands/author/init.js.map +1 -1
  47. package/dist/src/commands/author/mcp-init.d.ts +1 -0
  48. package/dist/src/commands/author/mcp-init.d.ts.map +1 -1
  49. package/dist/src/commands/author/mcp-init.js +21 -13
  50. package/dist/src/commands/author/mcp-init.js.map +1 -1
  51. package/dist/src/commands/author/subagent.d.ts +1 -0
  52. package/dist/src/commands/author/subagent.d.ts.map +1 -1
  53. package/dist/src/commands/author/subagent.js +23 -15
  54. package/dist/src/commands/author/subagent.js.map +1 -1
  55. package/dist/src/commands/author/transform.d.ts +1 -0
  56. package/dist/src/commands/author/transform.d.ts.map +1 -1
  57. package/dist/src/commands/author/transform.js +23 -15
  58. package/dist/src/commands/author/transform.js.map +1 -1
  59. package/dist/src/commands/config.d.ts +2 -0
  60. package/dist/src/commands/config.d.ts.map +1 -1
  61. package/dist/src/commands/config.js +43 -28
  62. package/dist/src/commands/config.js.map +1 -1
  63. package/dist/src/commands/create.d.ts +1 -0
  64. package/dist/src/commands/create.d.ts.map +1 -1
  65. package/dist/src/commands/create.js +28 -19
  66. package/dist/src/commands/create.js.map +1 -1
  67. package/dist/src/commands/diff.d.ts +4 -0
  68. package/dist/src/commands/diff.d.ts.map +1 -1
  69. package/dist/src/commands/diff.js +57 -42
  70. package/dist/src/commands/diff.js.map +1 -1
  71. package/dist/src/commands/diff.test.js +30 -0
  72. package/dist/src/commands/diff.test.js.map +1 -1
  73. package/dist/src/commands/import-local.d.ts +7 -0
  74. package/dist/src/commands/import-local.d.ts.map +1 -1
  75. package/dist/src/commands/import-local.js +43 -34
  76. package/dist/src/commands/import-local.js.map +1 -1
  77. package/dist/src/commands/import.d.ts +6 -0
  78. package/dist/src/commands/import.d.ts.map +1 -1
  79. package/dist/src/commands/import.js +23 -14
  80. package/dist/src/commands/import.js.map +1 -1
  81. package/dist/src/commands/index.d.ts +1 -0
  82. package/dist/src/commands/index.d.ts.map +1 -1
  83. package/dist/src/commands/index.js +2 -0
  84. package/dist/src/commands/index.js.map +1 -1
  85. package/dist/src/commands/info.d.ts +7 -0
  86. package/dist/src/commands/info.d.ts.map +1 -1
  87. package/dist/src/commands/info.js +77 -68
  88. package/dist/src/commands/info.js.map +1 -1
  89. package/dist/src/commands/install-skill.d.ts +3 -0
  90. package/dist/src/commands/install-skill.d.ts.map +1 -1
  91. package/dist/src/commands/install-skill.js +23 -15
  92. package/dist/src/commands/install-skill.js.map +1 -1
  93. package/dist/src/commands/install.d.ts +21 -0
  94. package/dist/src/commands/install.d.ts.map +1 -1
  95. package/dist/src/commands/install.js +154 -139
  96. package/dist/src/commands/install.js.map +1 -1
  97. package/dist/src/commands/login.d.ts +4 -0
  98. package/dist/src/commands/login.d.ts.map +1 -1
  99. package/dist/src/commands/login.js +56 -47
  100. package/dist/src/commands/login.js.map +1 -1
  101. package/dist/src/commands/logout.d.ts +1 -0
  102. package/dist/src/commands/logout.d.ts.map +1 -1
  103. package/dist/src/commands/logout.js +36 -27
  104. package/dist/src/commands/logout.js.map +1 -1
  105. package/dist/src/commands/manage.d.ts +3 -9
  106. package/dist/src/commands/manage.d.ts.map +1 -1
  107. package/dist/src/commands/manage.js +69 -45
  108. package/dist/src/commands/manage.js.map +1 -1
  109. package/dist/src/commands/merge.d.ts +7 -0
  110. package/dist/src/commands/merge.d.ts.map +1 -1
  111. package/dist/src/commands/merge.js +117 -108
  112. package/dist/src/commands/merge.js.map +1 -1
  113. package/dist/src/commands/pin.d.ts +2 -0
  114. package/dist/src/commands/pin.d.ts.map +1 -1
  115. package/dist/src/commands/pin.js +88 -73
  116. package/dist/src/commands/pin.js.map +1 -1
  117. package/dist/src/commands/recommend.d.ts +1 -0
  118. package/dist/src/commands/recommend.d.ts.map +1 -1
  119. package/dist/src/commands/recommend.js +35 -27
  120. package/dist/src/commands/recommend.js.map +1 -1
  121. package/dist/src/commands/search-formatters.d.ts +1 -0
  122. package/dist/src/commands/search-formatters.d.ts.map +1 -1
  123. package/dist/src/commands/search-formatters.js +3 -0
  124. package/dist/src/commands/search-formatters.js.map +1 -1
  125. package/dist/src/commands/search.action.d.ts +16 -0
  126. package/dist/src/commands/search.action.d.ts.map +1 -0
  127. package/dist/src/commands/search.action.js +384 -0
  128. package/dist/src/commands/search.action.js.map +1 -0
  129. package/dist/src/commands/search.d.ts +3 -0
  130. package/dist/src/commands/search.d.ts.map +1 -1
  131. package/dist/src/commands/search.js +5 -343
  132. package/dist/src/commands/search.js.map +1 -1
  133. package/dist/src/commands/sync.action.d.ts +39 -0
  134. package/dist/src/commands/sync.action.d.ts.map +1 -0
  135. package/dist/src/commands/sync.action.js +353 -0
  136. package/dist/src/commands/sync.action.js.map +1 -0
  137. package/dist/src/commands/sync.d.ts +3 -0
  138. package/dist/src/commands/sync.d.ts.map +1 -1
  139. package/dist/src/commands/sync.js +8 -310
  140. package/dist/src/commands/sync.js.map +1 -1
  141. package/dist/src/commands/telemetry.action.d.ts +38 -0
  142. package/dist/src/commands/telemetry.action.d.ts.map +1 -0
  143. package/dist/src/commands/telemetry.action.js +350 -0
  144. package/dist/src/commands/telemetry.action.js.map +1 -0
  145. package/dist/src/commands/telemetry.d.ts +30 -0
  146. package/dist/src/commands/telemetry.d.ts.map +1 -0
  147. package/dist/src/commands/telemetry.helpers.d.ts +58 -0
  148. package/dist/src/commands/telemetry.helpers.d.ts.map +1 -0
  149. package/dist/src/commands/telemetry.helpers.js +173 -0
  150. package/dist/src/commands/telemetry.helpers.js.map +1 -0
  151. package/dist/src/commands/telemetry.helpers.test.d.ts +15 -0
  152. package/dist/src/commands/telemetry.helpers.test.d.ts.map +1 -0
  153. package/dist/src/commands/telemetry.helpers.test.js +240 -0
  154. package/dist/src/commands/telemetry.helpers.test.js.map +1 -0
  155. package/dist/src/commands/telemetry.js +65 -0
  156. package/dist/src/commands/telemetry.js.map +1 -0
  157. package/dist/src/commands/telemetry.test.d.ts +18 -0
  158. package/dist/src/commands/telemetry.test.d.ts.map +1 -0
  159. package/dist/src/commands/telemetry.test.js +401 -0
  160. package/dist/src/commands/telemetry.test.js.map +1 -0
  161. package/dist/src/commands/whoami.d.ts +1 -0
  162. package/dist/src/commands/whoami.d.ts.map +1 -1
  163. package/dist/src/commands/whoami.js +29 -21
  164. package/dist/src/commands/whoami.js.map +1 -1
  165. package/dist/src/index.js +3 -1
  166. package/dist/src/index.js.map +1 -1
  167. package/dist/src/utils/manifest.d.ts +75 -0
  168. package/dist/src/utils/manifest.d.ts.map +1 -1
  169. package/dist/src/utils/manifest.js +78 -0
  170. package/dist/src/utils/manifest.js.map +1 -1
  171. package/dist/src/utils/manifest.test.d.ts +20 -0
  172. package/dist/src/utils/manifest.test.d.ts.map +1 -0
  173. package/dist/src/utils/manifest.test.js +344 -0
  174. package/dist/src/utils/manifest.test.js.map +1 -0
  175. package/dist/src/utils/open-database.d.ts +10 -2
  176. package/dist/src/utils/open-database.d.ts.map +1 -1
  177. package/dist/src/utils/open-database.js +15 -2
  178. package/dist/src/utils/open-database.js.map +1 -1
  179. package/dist/src/utils/skills-directory.d.ts.map +1 -1
  180. package/dist/src/utils/skills-directory.js +5 -1
  181. package/dist/src/utils/skills-directory.js.map +1 -1
  182. package/dist/tests/e2e/audit-sources-apply.test.d.ts +13 -0
  183. package/dist/tests/e2e/audit-sources-apply.test.d.ts.map +1 -0
  184. package/dist/tests/e2e/audit-sources-apply.test.js +166 -0
  185. package/dist/tests/e2e/audit-sources-apply.test.js.map +1 -0
  186. package/dist/tests/e2e/audit-sources-recovery.test.d.ts +15 -0
  187. package/dist/tests/e2e/audit-sources-recovery.test.d.ts.map +1 -0
  188. package/dist/tests/e2e/audit-sources-recovery.test.js +179 -0
  189. package/dist/tests/e2e/audit-sources-recovery.test.js.map +1 -0
  190. package/dist/tests/e2e/audit-sources-roundtrip.test.d.ts +23 -0
  191. package/dist/tests/e2e/audit-sources-roundtrip.test.d.ts.map +1 -0
  192. package/dist/tests/e2e/audit-sources-roundtrip.test.js +107 -0
  193. package/dist/tests/e2e/audit-sources-roundtrip.test.js.map +1 -0
  194. package/dist/tests/e2e/utils/source-recovery-fixture.d.ts +49 -0
  195. package/dist/tests/e2e/utils/source-recovery-fixture.d.ts.map +1 -0
  196. package/dist/tests/e2e/utils/source-recovery-fixture.js +106 -0
  197. package/dist/tests/e2e/utils/source-recovery-fixture.js.map +1 -0
  198. package/dist/tests/embedding-probe-stdio.test.d.ts +11 -0
  199. package/dist/tests/embedding-probe-stdio.test.d.ts.map +1 -0
  200. package/dist/tests/embedding-probe-stdio.test.js +58 -0
  201. package/dist/tests/embedding-probe-stdio.test.js.map +1 -0
  202. package/dist/tests/init.test.js +2 -1
  203. package/dist/tests/init.test.js.map +1 -1
  204. package/dist/tests/install-quarantine.test.d.ts +10 -0
  205. package/dist/tests/install-quarantine.test.d.ts.map +1 -0
  206. package/dist/tests/install-quarantine.test.js +86 -0
  207. package/dist/tests/install-quarantine.test.js.map +1 -0
  208. package/package.json +5 -5
  209. package/templates/skill-telemetry.cmd +16 -0
  210. package/templates/skill-telemetry.sh +199 -0
@@ -0,0 +1,300 @@
1
+ /**
2
+ * @fileoverview Action implementation for `sklx audit sources`.
3
+ * @module @skillsmith/cli/commands/audit-sources.action
4
+ * @see SMI-5407
5
+ *
6
+ * Wires SourceRecoveryService (with real findCandidatesByName over the CLI DB)
7
+ * and backfillManifest. Applies an already_tracked overlay after recovery (the
8
+ * core service cannot know the current manifest state).
9
+ *
10
+ * Safety:
11
+ * - Dry-run unless --apply.
12
+ * - --apply requires typed phrase `BACKFILL SOURCES` (waived by --yes).
13
+ * - --write-frontmatter requires --force-write-frontmatter and prints a bold
14
+ * stderr WARNING before proceeding.
15
+ *
16
+ * Output:
17
+ * Human: === Skillsmith — Source Recovery === + table + footer summary.
18
+ * --json: { skills, summary } to stdout, no prompts, no file mutation.
19
+ */
20
+ import { input } from '@inquirer/prompts';
21
+ import chalk from 'chalk';
22
+ import { hashContent } from '@skillsmith/core/services/skill-installation-helpers';
23
+ import { SourceRecoveryService, defaultSkillsRoot, backfillManifest, parseRepoUrl, METHOD_LABELS, } from '@skillsmith/core';
24
+ import { withTelemetry } from '@skillsmith/core/telemetry';
25
+ import { openCliDatabase } from '../utils/open-database.js';
26
+ import { loadManifest } from '../utils/manifest.js';
27
+ import { sanitizeError } from '../utils/sanitize.js';
28
+ import { DEFAULT_DB_PATH } from '../config.js';
29
+ // ============================================================================
30
+ // Constants
31
+ // ============================================================================
32
+ const BACKFILL_PHRASE = 'BACKFILL SOURCES';
33
+ const CONFIDENCE_BADGES = {
34
+ exact: '[EXACT]',
35
+ high: '[HIGH]',
36
+ medium: '[MEDIUM]',
37
+ low: '[LOW]',
38
+ 'user-specified': '[SET]',
39
+ unknown: '[-]',
40
+ };
41
+ // ============================================================================
42
+ // Helpers
43
+ // ============================================================================
44
+ /** Parse `--set` pairs like `"dirName=owner/repo"` → Record. */
45
+ function parseSetPairs(pairs) {
46
+ if (!pairs || pairs.length === 0)
47
+ return {};
48
+ const out = {};
49
+ for (const pair of pairs) {
50
+ const eq = pair.indexOf('=');
51
+ if (eq < 1) {
52
+ console.error(chalk.yellow(`[audit sources] ignoring malformed --set pair: ${pair}`));
53
+ continue;
54
+ }
55
+ out[pair.slice(0, eq)] = pair.slice(eq + 1);
56
+ }
57
+ return out;
58
+ }
59
+ /** Parse `minConfidence` CLI value; fall back to `'high'` on unknown input. */
60
+ function parseMinConfidence(value) {
61
+ const valid = ['exact', 'high', 'medium', 'low', 'user-specified'];
62
+ const v = (value ?? 'high');
63
+ return valid.includes(v) ? v : 'high';
64
+ }
65
+ /**
66
+ * Apply the already_tracked overlay: a skill whose manifest entry already has a
67
+ * non-empty source should be marked `already_tracked` (the core service cannot
68
+ * know the current manifest state).
69
+ *
70
+ * Mutates `report.skills` in place and recomputes `report.summary`.
71
+ */
72
+ async function overlayAlreadyTracked(report) {
73
+ const manifest = await loadManifest();
74
+ const installed = manifest.installedSkills ?? {};
75
+ for (const skill of report.skills) {
76
+ const entry = installed[skill.skillName];
77
+ if (entry && typeof entry.source === 'string' && entry.source.trim().length > 0) {
78
+ skill.status = 'already_tracked';
79
+ }
80
+ }
81
+ // Recompute summary totals from mutated statuses.
82
+ report.summary.recovered = 0;
83
+ report.summary.already_tracked = 0;
84
+ report.summary.unknown = 0;
85
+ report.summary.skipped_backup = 0;
86
+ for (const skill of report.skills) {
87
+ report.summary[skill.status] += 1;
88
+ }
89
+ }
90
+ // ============================================================================
91
+ // Output — human-readable
92
+ // ============================================================================
93
+ const COL_SKILL = 24;
94
+ const COL_SOURCE = 46;
95
+ const COL_CONF = 12;
96
+ function pad(s, n) {
97
+ return s.length >= n ? s.slice(0, n - 1) + ' ' : s.padEnd(n);
98
+ }
99
+ function sourceCell(skill) {
100
+ if (skill.status === 'already_tracked')
101
+ return '(already tracked)';
102
+ if (skill.status === 'skipped_backup')
103
+ return '(backup — skipped)';
104
+ if (skill.candidates.length > 1)
105
+ return '(ambiguous)';
106
+ if (!skill.recoveredSource)
107
+ return '(unresolved)';
108
+ return skill.recoveredSource.url;
109
+ }
110
+ function confCell(skill) {
111
+ if (skill.status === 'already_tracked' || skill.status === 'skipped_backup')
112
+ return '-';
113
+ return CONFIDENCE_BADGES[skill.confidence] ?? '?';
114
+ }
115
+ function methodCell(skill) {
116
+ if (skill.status === 'already_tracked' || skill.status === 'skipped_backup')
117
+ return '-';
118
+ if (!skill.method)
119
+ return '-';
120
+ return METHOD_LABELS[skill.method] ?? skill.method;
121
+ }
122
+ function printHumanReport(report, applying) {
123
+ console.log(chalk.bold.blue('\n=== Skillsmith — Source Recovery ===\n'));
124
+ const hdr = pad('skill', COL_SKILL) +
125
+ '| ' +
126
+ pad('source', COL_SOURCE) +
127
+ '| ' +
128
+ pad('confidence', COL_CONF) +
129
+ '| method';
130
+ const sep = '-'.repeat(hdr.length);
131
+ console.log(hdr);
132
+ console.log(sep);
133
+ for (const skill of report.skills) {
134
+ const row = pad(skill.skillName, COL_SKILL) +
135
+ '| ' +
136
+ pad(sourceCell(skill), COL_SOURCE) +
137
+ '| ' +
138
+ pad(confCell(skill), COL_CONF) +
139
+ '| ' +
140
+ methodCell(skill);
141
+ console.log(row);
142
+ // Multi-candidate indented row for ambiguous name matches.
143
+ if (skill.candidates.length > 1) {
144
+ const parts = skill.candidates
145
+ .map((c, i) => `(${i + 1}) ${c.owner}/${c.repo}`)
146
+ .join(' ');
147
+ console.log(chalk.dim(` -> ${parts} [ambiguous — --set or --embedding]`));
148
+ }
149
+ }
150
+ console.log();
151
+ const s = report.summary;
152
+ const exactCount = report.skills.filter((sk) => sk.status === 'recovered' && sk.confidence === 'exact').length;
153
+ const highCount = report.skills.filter((sk) => sk.status === 'recovered' && (sk.confidence === 'high' || sk.confidence === 'user-specified')).length;
154
+ console.log(chalk.bold(`Summary: ${s.total} scanned, ${s.recovered} recovered ` +
155
+ `(${exactCount} exact, ${highCount} high), ` +
156
+ `${s.already_tracked} already-tracked, ` +
157
+ `${s.unknown} unresolved, ` +
158
+ `${s.skipped_backup} backups skipped.`));
159
+ if (!applying) {
160
+ console.log(chalk.dim('Dry run — --apply to backfill.'));
161
+ }
162
+ console.log();
163
+ }
164
+ // ============================================================================
165
+ // Typed-confirmation gate
166
+ // ============================================================================
167
+ async function requireBackfillPhrase() {
168
+ const answer = await input({
169
+ message: `Type ${chalk.bold(BACKFILL_PHRASE)} to confirm writing recovered sources to the manifest`,
170
+ });
171
+ if (answer !== BACKFILL_PHRASE) {
172
+ throw new Error(`Confirmation phrase mismatch — operation aborted. ` + `Must be exactly: ${BACKFILL_PHRASE}`);
173
+ }
174
+ }
175
+ // ============================================================================
176
+ // Main entry
177
+ // ============================================================================
178
+ export async function runAuditSources(options) {
179
+ const skillsRoot = options.skillsRoot ?? defaultSkillsRoot();
180
+ const setOverrides = parseSetPairs(options.set);
181
+ const minConfidence = parseMinConfidence(options.minConfidence);
182
+ // --write-frontmatter requires --force-write-frontmatter.
183
+ if (options.writeFrontmatter && !options.forceWriteFrontmatter) {
184
+ console.error(chalk.red('--write-frontmatter requires --force-write-frontmatter. ' +
185
+ 'Re-run with both flags to modify SKILL.md files inside installed skill directories.'));
186
+ process.exit(1);
187
+ return;
188
+ }
189
+ // Bold warning when frontmatter mutation is armed.
190
+ if (options.writeFrontmatter && options.forceWriteFrontmatter) {
191
+ console.error(chalk.bold.yellow('WARNING: --write-frontmatter will modify SKILL.md files inside ' +
192
+ 'git-tracked skill repos. This operation is irreversible without a git reset.'));
193
+ }
194
+ // Open local DB (required for findCandidatesByName).
195
+ const db = await openCliDatabase(options.db);
196
+ let report;
197
+ try {
198
+ const findCandidatesByName = async (name) => {
199
+ const rows = db
200
+ .prepare('SELECT id, name, repo_url, quality_score FROM skills WHERE name = ?')
201
+ .all(name);
202
+ const candidates = [];
203
+ for (const row of rows) {
204
+ if (!row.repo_url)
205
+ continue;
206
+ try {
207
+ const parsed = parseRepoUrl(row.repo_url);
208
+ candidates.push({
209
+ id: row.id,
210
+ name: row.name,
211
+ owner: parsed.owner,
212
+ repo: parsed.repo,
213
+ url: `https://github.com/${parsed.owner}/${parsed.repo}`,
214
+ qualityScore: row.quality_score ?? 0,
215
+ });
216
+ }
217
+ catch {
218
+ // Non-GitHub repo_url — skip candidate.
219
+ }
220
+ }
221
+ return candidates;
222
+ };
223
+ const service = new SourceRecoveryService({ hashContent, findCandidatesByName });
224
+ report = await service.recoverSources({
225
+ skillsRoot,
226
+ enableEmbedding: options.embedding,
227
+ enableCatalogHint: options.catalogHint,
228
+ });
229
+ }
230
+ finally {
231
+ db.close();
232
+ }
233
+ // Overlay already_tracked status from the current manifest.
234
+ await overlayAlreadyTracked(report);
235
+ // --json: emit raw data, no prompts, no writes.
236
+ if (options.json) {
237
+ process.stdout.write(JSON.stringify({ skills: report.skills, summary: report.summary }, null, 2));
238
+ process.stdout.write('\n');
239
+ return;
240
+ }
241
+ printHumanReport(report, options.apply);
242
+ if (!options.apply)
243
+ return;
244
+ // --apply: confirm and write.
245
+ if (!options.yes) {
246
+ await requireBackfillPhrase();
247
+ }
248
+ const outcome = await backfillManifest(report, {
249
+ minConfidence,
250
+ apply: true,
251
+ setOverrides,
252
+ writeFrontmatter: options.writeFrontmatter,
253
+ });
254
+ if (outcome.written.length > 0) {
255
+ console.log(chalk.green(`Backfilled ${outcome.written.length} skill(s): ${outcome.written.join(', ')}`));
256
+ }
257
+ else {
258
+ console.log(chalk.dim('Nothing new to backfill.'));
259
+ }
260
+ if (outcome.skipped.length > 0) {
261
+ console.log(chalk.dim(`Skipped: ${outcome.skipped.join(', ')}`));
262
+ }
263
+ }
264
+ // ============================================================================
265
+ // withTelemetry-wrapped export (SMI-5127+)
266
+ // ============================================================================
267
+ async function auditSourcesActionImpl(skillsRoot, opts) {
268
+ try {
269
+ await runAuditSources({
270
+ skillsRoot,
271
+ apply: opts['apply'] ?? false,
272
+ yes: opts['yes'] ?? false,
273
+ set: opts['set'],
274
+ minConfidence: opts['minConfidence'] ?? 'high',
275
+ json: opts['json'] ?? false,
276
+ embedding: opts['embedding'] ?? false,
277
+ catalogHint: opts['catalogHint'] ?? false,
278
+ writeFrontmatter: opts['writeFrontmatter'] ?? false,
279
+ forceWriteFrontmatter: opts['forceWriteFrontmatter'] ?? false,
280
+ db: opts['db'] ?? DEFAULT_DB_PATH,
281
+ });
282
+ }
283
+ catch (error) {
284
+ const msg = error instanceof Error ? error.message : sanitizeError(error);
285
+ if (msg.startsWith('Confirmation phrase mismatch')) {
286
+ console.error(chalk.yellow(msg));
287
+ }
288
+ else {
289
+ console.error(chalk.red('Error:'), msg);
290
+ }
291
+ process.exit(1);
292
+ }
293
+ }
294
+ export const auditSourcesAction = withTelemetry(auditSourcesActionImpl, {
295
+ source: 'cli',
296
+ extractSkillId: () => 'audit-sources',
297
+ extractFramework: () => 'cli',
298
+ });
299
+ export { BACKFILL_PHRASE };
300
+ //# sourceMappingURL=audit-sources.action.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-sources.action.js","sourceRoot":"","sources":["../../../src/commands/audit-sources.action.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * @fileoverview `sklx audit sources` — skill source provenance recovery subcommand factory.
3
+ * @module @skillsmith/cli/commands/audit-sources
4
+ * @see SMI-5407
5
+ *
6
+ * Sibling of `sklx audit advisories` and `sklx audit collisions`.
7
+ * Implementation lives in `audit-sources.action.ts` (SMI-5127+ split).
8
+ *
9
+ * Flags:
10
+ * [skillsRoot] Optional positional: override the scan root
11
+ * (default: ~/.claude/skills).
12
+ * --apply Write recovered sources to the manifest.
13
+ * Dry-run when omitted.
14
+ * --yes Skip typed-confirmation gate (requires --apply).
15
+ * --set <pair...> Override: dirName=owner/repo. Repeatable.
16
+ * --min-confidence <c> Minimum confidence to backfill.
17
+ * One of: exact|high|medium|low. Default: high.
18
+ * --json Emit JSON to stdout; no prompts; no file mutation.
19
+ * --embedding Enable embedding tiebreak tier (off by default).
20
+ * --catalog-hint Enable catalog / author hint tier (off by default).
21
+ * --write-frontmatter Write repository: into non-git SKILL.md frontmatter.
22
+ * Requires --force-write-frontmatter.
23
+ * --force-write-frontmatter Confirm SKILL.md mutation (required with
24
+ * --write-frontmatter). Prints a bold warning.
25
+ * -d, --db <path> SQLite database path (default: ~/.skillsmith/skills.db).
26
+ *
27
+ * Community tier (no requireTier call). Read-only by default; --apply enables
28
+ * the manifest write path.
29
+ */
30
+ import { Command } from 'commander';
31
+ /**
32
+ * Build the `audit sources` subcommand. Registered in `createAuditCommand()`
33
+ * beside `advisories` and `collisions`.
34
+ */
35
+ export declare function createAuditSourcesSubcommand(): Command;
36
+ export default createAuditSourcesSubcommand;
37
+ //# sourceMappingURL=audit-sources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-sources.d.ts","sourceRoot":"","sources":["../../../src/commands/audit-sources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAInC;;;GAGG;AACH,wBAAgB,4BAA4B,IAAI,OAAO,CA0BtD;AAED,eAAe,4BAA4B,CAAA"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * @fileoverview `sklx audit sources` — skill source provenance recovery subcommand factory.
3
+ * @module @skillsmith/cli/commands/audit-sources
4
+ * @see SMI-5407
5
+ *
6
+ * Sibling of `sklx audit advisories` and `sklx audit collisions`.
7
+ * Implementation lives in `audit-sources.action.ts` (SMI-5127+ split).
8
+ *
9
+ * Flags:
10
+ * [skillsRoot] Optional positional: override the scan root
11
+ * (default: ~/.claude/skills).
12
+ * --apply Write recovered sources to the manifest.
13
+ * Dry-run when omitted.
14
+ * --yes Skip typed-confirmation gate (requires --apply).
15
+ * --set <pair...> Override: dirName=owner/repo. Repeatable.
16
+ * --min-confidence <c> Minimum confidence to backfill.
17
+ * One of: exact|high|medium|low. Default: high.
18
+ * --json Emit JSON to stdout; no prompts; no file mutation.
19
+ * --embedding Enable embedding tiebreak tier (off by default).
20
+ * --catalog-hint Enable catalog / author hint tier (off by default).
21
+ * --write-frontmatter Write repository: into non-git SKILL.md frontmatter.
22
+ * Requires --force-write-frontmatter.
23
+ * --force-write-frontmatter Confirm SKILL.md mutation (required with
24
+ * --write-frontmatter). Prints a bold warning.
25
+ * -d, --db <path> SQLite database path (default: ~/.skillsmith/skills.db).
26
+ *
27
+ * Community tier (no requireTier call). Read-only by default; --apply enables
28
+ * the manifest write path.
29
+ */
30
+ import { Command } from 'commander';
31
+ import { DEFAULT_DB_PATH } from '../config.js';
32
+ import { auditSourcesAction } from './audit-sources.action.js';
33
+ /**
34
+ * Build the `audit sources` subcommand. Registered in `createAuditCommand()`
35
+ * beside `advisories` and `collisions`.
36
+ */
37
+ export function createAuditSourcesSubcommand() {
38
+ return new Command('sources')
39
+ .description('Recover the canonical GitHub source of locally-installed skills ' +
40
+ 'and optionally backfill ~/.skillsmith/manifest.json')
41
+ .argument('[skillsRoot]', 'Root directory to scan (default: ~/.claude/skills)')
42
+ .option('--apply', 'Write recovered sources to the manifest (dry-run by default)', false)
43
+ .option('--yes', 'Skip typed-confirmation phrase (requires --apply)', false)
44
+ .option('--set <pair...>', 'Override source for a skill: dirName=owner/repo (repeatable)')
45
+ .option('--min-confidence <c>', 'Minimum confidence to backfill: exact|high|medium|low', 'high')
46
+ .option('--json', 'Emit JSON to stdout; no prompts; no file mutation', false)
47
+ .option('--embedding', 'Enable embedding tiebreak tier (off by default)', false)
48
+ .option('--catalog-hint', 'Enable catalog / author hint tier (off by default)', false)
49
+ .option('--write-frontmatter', 'Write repository: into non-git SKILL.md frontmatter (requires --force-write-frontmatter)', false)
50
+ .option('--force-write-frontmatter', 'Confirm SKILL.md mutation — required with --write-frontmatter (prints a bold warning)', false)
51
+ .option('-d, --db <path>', 'Database file path', DEFAULT_DB_PATH)
52
+ .action(auditSourcesAction);
53
+ }
54
+ export default createAuditSourcesSubcommand;
55
+ //# sourceMappingURL=audit-sources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-sources.js","sourceRoot":"","sources":["../../../src/commands/audit-sources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;AAC9C,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAE9D;;;GAGG;AACH,MAAM,UAAU,4BAA4B;IAC1C,OAAO,IAAI,OAAO,CAAC,SAAS,CAAC;SAC1B,WAAW,CACV,kEAAkE;QAChE,qDAAqD,CACxD;SACA,QAAQ,CAAC,cAAc,EAAE,oDAAoD,CAAC;SAC9E,MAAM,CAAC,SAAS,EAAE,8DAA8D,EAAE,KAAK,CAAC;SACxF,MAAM,CAAC,OAAO,EAAE,mDAAmD,EAAE,KAAK,CAAC;SAC3E,MAAM,CAAC,iBAAiB,EAAE,8DAA8D,CAAC;SACzF,MAAM,CAAC,sBAAsB,EAAE,uDAAuD,EAAE,MAAM,CAAC;SAC/F,MAAM,CAAC,QAAQ,EAAE,mDAAmD,EAAE,KAAK,CAAC;SAC5E,MAAM,CAAC,aAAa,EAAE,iDAAiD,EAAE,KAAK,CAAC;SAC/E,MAAM,CAAC,gBAAgB,EAAE,oDAAoD,EAAE,KAAK,CAAC;SACrF,MAAM,CACL,qBAAqB,EACrB,0FAA0F,EAC1F,KAAK,CACN;SACA,MAAM,CACL,2BAA2B,EAC3B,uFAAuF,EACvF,KAAK,CACN;SACA,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,EAAE,eAAe,CAAC;SAChE,MAAM,CAAC,kBAAkB,CAAC,CAAA;AAC/B,CAAC;AAED,eAAe,4BAA4B,CAAA"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @fileoverview Unit tests for `sklx audit sources` CLI command.
3
+ * @see SMI-5407: Skill Source Provenance Recovery
4
+ *
5
+ * Tests the action layer (`runAuditSources`) with injected mocks so the test
6
+ * suite runs fully offline without a real DB or skills directory.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=audit-sources.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-sources.test.d.ts","sourceRoot":"","sources":["../../../src/commands/audit-sources.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * @fileoverview Unit tests for `sklx audit sources` CLI command.
3
+ * @see SMI-5407: Skill Source Provenance Recovery
4
+ *
5
+ * Tests the action layer (`runAuditSources`) with injected mocks so the test
6
+ * suite runs fully offline without a real DB or skills directory.
7
+ */
8
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
9
+ import * as os from 'node:os';
10
+ import * as path from 'node:path';
11
+ // ============================================================================
12
+ // Module mocks — must be declared before the imports that use them
13
+ // ============================================================================
14
+ const mockOpenCliDatabase = vi.fn();
15
+ vi.mock('../utils/open-database.js', () => ({
16
+ openCliDatabase: (...args) => mockOpenCliDatabase(...args),
17
+ }));
18
+ const mockLoadManifest = vi.fn();
19
+ vi.mock('../utils/manifest.js', () => ({
20
+ loadManifest: () => mockLoadManifest(),
21
+ }));
22
+ const mockRecoverSources = vi.fn();
23
+ const mockBackfillManifest = vi.fn();
24
+ vi.mock('@skillsmith/core', async (importOriginal) => {
25
+ const actual = await importOriginal();
26
+ return {
27
+ ...actual,
28
+ // Must be a regular function (not arrow) so `new SourceRecoveryService()` works.
29
+ SourceRecoveryService: function MockSourceRecoveryService() {
30
+ return { recoverSources: (...args) => mockRecoverSources(...args) };
31
+ },
32
+ backfillManifest: (...args) => mockBackfillManifest(...args),
33
+ defaultSkillsRoot: () => path.join(os.homedir(), '.claude', 'skills'),
34
+ };
35
+ });
36
+ // ============================================================================
37
+ // Import after mocks
38
+ // ============================================================================
39
+ import { runAuditSources } from './audit-sources.action.js';
40
+ function makeReport(overrides = {}) {
41
+ return {
42
+ skills: [
43
+ {
44
+ skillName: 'linear',
45
+ installPath: '/home/user/.claude/skills/linear',
46
+ recoveredSource: {
47
+ owner: 'williamsmith',
48
+ repo: 'linear',
49
+ url: 'https://github.com/williamsmith/linear',
50
+ },
51
+ registryId: 'uuid-linear',
52
+ method: 'git-remote',
53
+ confidence: 'exact',
54
+ candidates: [],
55
+ status: 'recovered',
56
+ },
57
+ ],
58
+ summary: { total: 1, recovered: 1, already_tracked: 0, unknown: 0, skipped_backup: 0 },
59
+ ...overrides,
60
+ };
61
+ }
62
+ function makeDb() {
63
+ return {
64
+ prepare: vi.fn().mockReturnValue({ all: vi.fn().mockReturnValue([]) }),
65
+ close: vi.fn(),
66
+ };
67
+ }
68
+ function baseOptions(overrides = {}) {
69
+ return {
70
+ skillsRoot: '/tmp/test-skills',
71
+ apply: false,
72
+ yes: false,
73
+ set: undefined,
74
+ minConfidence: 'high',
75
+ json: false,
76
+ embedding: false,
77
+ catalogHint: false,
78
+ writeFrontmatter: false,
79
+ forceWriteFrontmatter: false,
80
+ db: ':memory:',
81
+ ...overrides,
82
+ };
83
+ }
84
+ // ============================================================================
85
+ // Tests
86
+ // ============================================================================
87
+ describe('runAuditSources', () => {
88
+ beforeEach(() => {
89
+ vi.clearAllMocks();
90
+ mockOpenCliDatabase.mockResolvedValue(makeDb());
91
+ mockLoadManifest.mockResolvedValue({ version: '1.0.0', installedSkills: {} });
92
+ mockRecoverSources.mockResolvedValue(makeReport());
93
+ mockBackfillManifest.mockResolvedValue({ planned: [], written: [], skipped: [] });
94
+ });
95
+ afterEach(() => {
96
+ vi.clearAllMocks();
97
+ });
98
+ // --------------------------------------------------------------------------
99
+ // --json shape + exit 0
100
+ // --------------------------------------------------------------------------
101
+ it('--json emits valid JSON with skills and summary', async () => {
102
+ const report = makeReport();
103
+ mockRecoverSources.mockResolvedValue(report);
104
+ const written = [];
105
+ vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
106
+ if (typeof chunk === 'string')
107
+ written.push(chunk);
108
+ return true;
109
+ });
110
+ await runAuditSources(baseOptions({ json: true }));
111
+ const output = written.join('');
112
+ const parsed = JSON.parse(output);
113
+ expect(Array.isArray(parsed.skills)).toBe(true);
114
+ expect(parsed.summary.total).toBe(1);
115
+ });
116
+ // --------------------------------------------------------------------------
117
+ // Dry-run: default run does NOT write the manifest
118
+ // --------------------------------------------------------------------------
119
+ it('dry-run by default: does not call backfillManifest', async () => {
120
+ const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
121
+ await runAuditSources(baseOptions());
122
+ expect(mockBackfillManifest).not.toHaveBeenCalled();
123
+ logSpy.mockRestore();
124
+ });
125
+ // --------------------------------------------------------------------------
126
+ // already_tracked overlay
127
+ // --------------------------------------------------------------------------
128
+ it('overlays already_tracked when manifest already has a source', async () => {
129
+ mockLoadManifest.mockResolvedValue({
130
+ version: '1.0.0',
131
+ installedSkills: {
132
+ linear: {
133
+ id: 'uuid-linear',
134
+ name: 'linear',
135
+ version: '1.0.0',
136
+ source: 'https://github.com/williamsmith/linear',
137
+ installPath: '/home/user/.claude/skills/linear',
138
+ installedAt: '2024-01-01T00:00:00.000Z',
139
+ lastUpdated: '2024-01-01T00:00:00.000Z',
140
+ },
141
+ },
142
+ });
143
+ const jsonChunks = [];
144
+ vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
145
+ if (typeof chunk === 'string')
146
+ jsonChunks.push(chunk);
147
+ return true;
148
+ });
149
+ await runAuditSources(baseOptions({ json: true }));
150
+ const parsed = JSON.parse(jsonChunks.join(''));
151
+ const alreadyTracked = parsed.skills.find((s) => s.status === 'already_tracked');
152
+ expect(alreadyTracked).toBeDefined();
153
+ expect(parsed.summary.already_tracked).toBe(1);
154
+ });
155
+ // --------------------------------------------------------------------------
156
+ // --apply --yes writes the manifest
157
+ // --------------------------------------------------------------------------
158
+ it('--apply --yes calls backfillManifest with apply: true', async () => {
159
+ mockBackfillManifest.mockResolvedValue({ planned: [], written: ['linear'], skipped: [] });
160
+ const logSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
161
+ await runAuditSources(baseOptions({ apply: true, yes: true }));
162
+ expect(mockBackfillManifest).toHaveBeenCalledWith(expect.objectContaining({ summary: expect.any(Object) }), expect.objectContaining({ apply: true }));
163
+ logSpy.mockRestore();
164
+ });
165
+ // --------------------------------------------------------------------------
166
+ // Multi-candidate row appears in JSON output
167
+ // --------------------------------------------------------------------------
168
+ it('--json includes candidates array when ambiguous (multi-match)', async () => {
169
+ const ambiguousReport = makeReport({
170
+ skills: [
171
+ {
172
+ skillName: 'git-helper',
173
+ installPath: '/home/user/.claude/skills/git-helper',
174
+ recoveredSource: null,
175
+ registryId: null,
176
+ method: 'registry-name',
177
+ confidence: 'low',
178
+ candidates: [
179
+ {
180
+ id: 'id-1',
181
+ name: 'git-helper',
182
+ owner: 'alice',
183
+ repo: 'git-helper',
184
+ url: 'https://github.com/alice/git-helper',
185
+ qualityScore: 80,
186
+ },
187
+ {
188
+ id: 'id-2',
189
+ name: 'git-helper',
190
+ owner: 'bob',
191
+ repo: 'git-helper',
192
+ url: 'https://github.com/bob/git-helper',
193
+ qualityScore: 60,
194
+ },
195
+ ],
196
+ status: 'unknown',
197
+ },
198
+ ],
199
+ summary: { total: 1, recovered: 0, already_tracked: 0, unknown: 1, skipped_backup: 0 },
200
+ });
201
+ mockRecoverSources.mockResolvedValue(ambiguousReport);
202
+ const written = [];
203
+ vi.spyOn(process.stdout, 'write').mockImplementation((chunk) => {
204
+ if (typeof chunk === 'string')
205
+ written.push(chunk);
206
+ return true;
207
+ });
208
+ await runAuditSources(baseOptions({ json: true }));
209
+ const parsed = JSON.parse(written.join(''));
210
+ expect(parsed.skills[0]?.candidates).toHaveLength(2);
211
+ });
212
+ // --------------------------------------------------------------------------
213
+ // --write-frontmatter without --force-write-frontmatter exits non-zero
214
+ // --------------------------------------------------------------------------
215
+ it('--write-frontmatter without --force-write-frontmatter exits with code 1', async () => {
216
+ const exitSpy = vi
217
+ .spyOn(process, 'exit')
218
+ .mockImplementation((_code) => {
219
+ throw new Error('process.exit');
220
+ });
221
+ const errSpy = vi.spyOn(console, 'error').mockImplementation(() => { });
222
+ await expect(runAuditSources(baseOptions({ writeFrontmatter: true, forceWriteFrontmatter: false }))).rejects.toThrow('process.exit');
223
+ expect(exitSpy).toHaveBeenCalledWith(1);
224
+ exitSpy.mockRestore();
225
+ errSpy.mockRestore();
226
+ });
227
+ });
228
+ //# sourceMappingURL=audit-sources.test.js.map