@skillsmith/core 0.11.1 → 0.11.3

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 (138) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/README.md +6 -7
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/analysis/McpReferenceExtractor.d.ts +59 -5
  5. package/dist/src/analysis/McpReferenceExtractor.d.ts.map +1 -1
  6. package/dist/src/analysis/McpReferenceExtractor.hardening.test.d.ts +2 -0
  7. package/dist/src/analysis/McpReferenceExtractor.hardening.test.d.ts.map +1 -0
  8. package/dist/src/analysis/McpReferenceExtractor.hardening.test.js +278 -0
  9. package/dist/src/analysis/McpReferenceExtractor.hardening.test.js.map +1 -0
  10. package/dist/src/analysis/McpReferenceExtractor.js +276 -20
  11. package/dist/src/analysis/McpReferenceExtractor.js.map +1 -1
  12. package/dist/src/analysis/McpReferenceExtractor.test.js +4 -0
  13. package/dist/src/analysis/McpReferenceExtractor.test.js.map +1 -1
  14. package/dist/src/config/config-atomic-write.d.ts +58 -0
  15. package/dist/src/config/config-atomic-write.d.ts.map +1 -0
  16. package/dist/src/config/config-atomic-write.js +151 -0
  17. package/dist/src/config/config-atomic-write.js.map +1 -0
  18. package/dist/src/config/config-atomic-write.test.d.ts +9 -0
  19. package/dist/src/config/config-atomic-write.test.d.ts.map +1 -0
  20. package/dist/src/config/config-atomic-write.test.js +92 -0
  21. package/dist/src/config/config-atomic-write.test.js.map +1 -0
  22. package/dist/src/config/device-identity.d.ts +16 -0
  23. package/dist/src/config/device-identity.d.ts.map +1 -1
  24. package/dist/src/config/device-identity.js +82 -14
  25. package/dist/src/config/device-identity.js.map +1 -1
  26. package/dist/src/config/device-identity.test.js +158 -1
  27. package/dist/src/config/device-identity.test.js.map +1 -1
  28. package/dist/src/config/index.d.ts +14 -0
  29. package/dist/src/config/index.d.ts.map +1 -1
  30. package/dist/src/config/index.js +31 -15
  31. package/dist/src/config/index.js.map +1 -1
  32. package/dist/src/exports/services.d.ts +2 -1
  33. package/dist/src/exports/services.d.ts.map +1 -1
  34. package/dist/src/exports/services.js +1 -0
  35. package/dist/src/exports/services.js.map +1 -1
  36. package/dist/src/index.d.ts +2 -1
  37. package/dist/src/index.d.ts.map +1 -1
  38. package/dist/src/index.js +5 -1
  39. package/dist/src/index.js.map +1 -1
  40. package/dist/src/indexer/SwarmIndexer.d.ts +1 -1
  41. package/dist/src/indexer/SwarmIndexer.js +2 -2
  42. package/dist/src/indexer/SwarmIndexer.js.map +1 -1
  43. package/dist/src/install/paths.d.ts +1 -1
  44. package/dist/src/install/paths.d.ts.map +1 -1
  45. package/dist/src/install/paths.js +2 -0
  46. package/dist/src/install/paths.js.map +1 -1
  47. package/dist/src/install/paths.test.js +10 -1
  48. package/dist/src/install/paths.test.js.map +1 -1
  49. package/dist/src/journal/reader.d.ts.map +1 -1
  50. package/dist/src/journal/reader.js +4 -1
  51. package/dist/src/journal/reader.js.map +1 -1
  52. package/dist/src/journal/types.d.ts +13 -3
  53. package/dist/src/journal/types.d.ts.map +1 -1
  54. package/dist/src/journal/types.js +8 -2
  55. package/dist/src/journal/types.js.map +1 -1
  56. package/dist/src/scripts/__tests__/scan-imported-skills.test.js +36 -0
  57. package/dist/src/scripts/__tests__/scan-imported-skills.test.js.map +1 -1
  58. package/dist/src/security/audit-types.d.ts +1 -1
  59. package/dist/src/security/audit-types.d.ts.map +1 -1
  60. package/dist/src/security/audit-types.js.map +1 -1
  61. package/dist/src/security/scanner/SecurityScanner.exec.d.ts +7 -0
  62. package/dist/src/security/scanner/SecurityScanner.exec.d.ts.map +1 -1
  63. package/dist/src/security/scanner/SecurityScanner.exec.js +10 -74
  64. package/dist/src/security/scanner/SecurityScanner.exec.js.map +1 -1
  65. package/dist/src/security/scanner/SecurityScanner.formatters.d.ts +14 -1
  66. package/dist/src/security/scanner/SecurityScanner.formatters.d.ts.map +1 -1
  67. package/dist/src/security/scanner/SecurityScanner.formatters.js +33 -0
  68. package/dist/src/security/scanner/SecurityScanner.formatters.js.map +1 -1
  69. package/dist/src/security/scanner/SecurityScanner.formatters.test.d.ts +9 -0
  70. package/dist/src/security/scanner/SecurityScanner.formatters.test.d.ts.map +1 -0
  71. package/dist/src/security/scanner/SecurityScanner.formatters.test.js +65 -0
  72. package/dist/src/security/scanner/SecurityScanner.formatters.test.js.map +1 -0
  73. package/dist/src/security/scanner/SecurityScanner.helpers.d.ts.map +1 -1
  74. package/dist/src/security/scanner/SecurityScanner.helpers.js +15 -1
  75. package/dist/src/security/scanner/SecurityScanner.helpers.js.map +1 -1
  76. package/dist/src/security/scanner/confusables.d.ts +28 -0
  77. package/dist/src/security/scanner/confusables.d.ts.map +1 -0
  78. package/dist/src/security/scanner/confusables.js +87 -0
  79. package/dist/src/security/scanner/confusables.js.map +1 -0
  80. package/dist/src/security/scanner/confusables.test.d.ts +10 -0
  81. package/dist/src/security/scanner/confusables.test.d.ts.map +1 -0
  82. package/dist/src/security/scanner/confusables.test.js +44 -0
  83. package/dist/src/security/scanner/confusables.test.js.map +1 -0
  84. package/dist/src/security/scanner/index.d.ts +7 -1
  85. package/dist/src/security/scanner/index.d.ts.map +1 -1
  86. package/dist/src/security/scanner/index.js +13 -0
  87. package/dist/src/security/scanner/index.js.map +1 -1
  88. package/dist/src/security/scanner/types.d.ts +14 -1
  89. package/dist/src/security/scanner/types.d.ts.map +1 -1
  90. package/dist/src/security/scanner/typosquat-reference-list.d.ts +54 -0
  91. package/dist/src/security/scanner/typosquat-reference-list.d.ts.map +1 -0
  92. package/dist/src/security/scanner/typosquat-reference-list.js +55 -0
  93. package/dist/src/security/scanner/typosquat-reference-list.js.map +1 -0
  94. package/dist/src/security/scanner/typosquat-reference-list.test.d.ts +5 -0
  95. package/dist/src/security/scanner/typosquat-reference-list.test.d.ts.map +1 -0
  96. package/dist/src/security/scanner/typosquat-reference-list.test.js +52 -0
  97. package/dist/src/security/scanner/typosquat-reference-list.test.js.map +1 -0
  98. package/dist/src/security/scanner/typosquat.d.ts +100 -0
  99. package/dist/src/security/scanner/typosquat.d.ts.map +1 -0
  100. package/dist/src/security/scanner/typosquat.js +256 -0
  101. package/dist/src/security/scanner/typosquat.js.map +1 -0
  102. package/dist/src/security/scanner/typosquat.test.d.ts +12 -0
  103. package/dist/src/security/scanner/typosquat.test.d.ts.map +1 -0
  104. package/dist/src/security/scanner/typosquat.test.js +140 -0
  105. package/dist/src/security/scanner/typosquat.test.js.map +1 -0
  106. package/dist/src/security/scanner/weights.d.ts.map +1 -1
  107. package/dist/src/security/scanner/weights.js +10 -0
  108. package/dist/src/security/scanner/weights.js.map +1 -1
  109. package/dist/src/services/skill-installation.helpers.d.ts +21 -0
  110. package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
  111. package/dist/src/services/skill-installation.helpers.js +46 -2
  112. package/dist/src/services/skill-installation.helpers.js.map +1 -1
  113. package/dist/src/services/skill-installation.helpers.test.d.ts +2 -0
  114. package/dist/src/services/skill-installation.helpers.test.d.ts.map +1 -0
  115. package/dist/src/services/skill-installation.helpers.test.js +80 -0
  116. package/dist/src/services/skill-installation.helpers.test.js.map +1 -0
  117. package/dist/src/sync/inventory-collector.d.ts +15 -4
  118. package/dist/src/sync/inventory-collector.d.ts.map +1 -1
  119. package/dist/src/sync/inventory-collector.js +73 -24
  120. package/dist/src/sync/inventory-collector.js.map +1 -1
  121. package/dist/src/sync/inventory-collector.test.d.ts +15 -1
  122. package/dist/src/sync/inventory-collector.test.d.ts.map +1 -1
  123. package/dist/src/sync/inventory-collector.test.js +75 -5
  124. package/dist/src/sync/inventory-collector.test.js.map +1 -1
  125. package/dist/src/telemetry/tracer-imports.d.ts +1 -1
  126. package/dist/src/telemetry/tracer-imports.js +1 -1
  127. package/dist/src/telemetry/tracer.js +1 -1
  128. package/dist/tests/SecurityScanner.scoring.test.js +60 -0
  129. package/dist/tests/SecurityScanner.scoring.test.js.map +1 -1
  130. package/dist/tests/SwarmIndexer.test.js +4 -5
  131. package/dist/tests/SwarmIndexer.test.js.map +1 -1
  132. package/dist/tests/security/scanner-regression-guard.test.js +1 -0
  133. package/dist/tests/security/scanner-regression-guard.test.js.map +1 -1
  134. package/dist/tests/services/aidefence-feedback.test.js +1 -0
  135. package/dist/tests/services/aidefence-feedback.test.js.map +1 -1
  136. package/dist/tests/skill-scanner/allowlist.test.js +8 -1
  137. package/dist/tests/skill-scanner/allowlist.test.js.map +1 -1
  138. package/package.json +13 -8
@@ -0,0 +1,256 @@
1
+ /**
2
+ * Typosquat / impersonation detector for skill names
3
+ * @module @skillsmith/core/security/scanner/typosquat
4
+ *
5
+ * SMI-595: no Levenshtein-distance / character-substitution / homoglyph
6
+ * name-comparison detector against a popular-skill-name list existed
7
+ * anywhere in this codebase prior to this module — content-based scanning
8
+ * (`SecurityScanner`) cannot catch a name-only impersonation attempt where
9
+ * the skill's actual content is benign (e.g. `anthopic/claude-helper` or
10
+ * `аnthropic/skill` with a Cyrillic `а`).
11
+ *
12
+ * Three independent checks, deliberately NOT conflated:
13
+ *
14
+ * 1. **Exact-skeleton impersonation** — fires ONLY on exact confusable-folded
15
+ * equality to a reference name, never on substring/affix match. This is a
16
+ * deliberately narrow rule: `anthropic-community-mcp`, `unofficial-claude-
17
+ * tools`, `awesome-gemini-skills` are normal, non-malicious community
18
+ * naming conventions that happen to contain a brand token and must NOT be
19
+ * blocked by this rule.
20
+ * 2. **Levenshtein edit-distance ≤2** — catches near-miss variants
21
+ * (`anthropc`, `anthropic1`, `anthropci`) that don't fold to an exact
22
+ * skeleton match but are still suspiciously close to a reference name.
23
+ * 3. **Authority-claiming affix** — INDEPENDENT of #1: a candidate containing
24
+ * a reference brand token PLUS an affix that claims official status
25
+ * (`-official`, `-verified`, `-authentic`, `-genuine`) is flagged
26
+ * regardless of whether it passes the exact-skeleton check, because the
27
+ * affix itself is the impersonation vector. Benign functional affixes
28
+ * (`-mcp`, `-tools`, `-community`) do NOT trigger this — they simply
29
+ * aren't in the curated affix list.
30
+ *
31
+ * Consumer-surface decision (Wave 1 Step 6): the install-time scanner path
32
+ * (risk-score wiring — see types.ts/weights.ts/SecurityScanner.helpers.ts) is
33
+ * the primary *enforcement* surface (blocks/warns before a skill lands on
34
+ * disk). `skill_audit` (existing MCP tool) is the recommended primary
35
+ * *consumer-facing* surface for on-demand querying of typosquat status on an
36
+ * already-installed skill — live-wiring that tool to this detector is
37
+ * deferred to a filed follow-up (SMI-5711), out of this wave's scope.
38
+ *
39
+ * Integration note: `SecurityScanner.scan()` takes `content` only, not a
40
+ * skill name/author — this wave does NOT change that signature or thread a
41
+ * live reference list through `scripts/skill-scanner/scanner.ts`'s scan
42
+ * pipeline (that would require sourcing real HIGH_TRUST_OWNERS-published
43
+ * skill data and real install-count data, which is a live-data/infra
44
+ * integration, not a detector-design concern). This module is a
45
+ * self-contained, fully-tested unit ready to be wired into that pipeline as a
46
+ * follow-up.
47
+ */
48
+ import { confusableSkeleton } from './confusables.js';
49
+ // ============================================================================
50
+ // Brand aliases (§3)
51
+ // ============================================================================
52
+ /**
53
+ * Brand names that are NOT derivable from `HIGH_TRUST_OWNERS`' GitHub owner
54
+ * slugs (`signal-of-intent.ts`) or from the installed-skill corpus at all —
55
+ * the product/brand a typosquat would actually target (`anthropic`, `claude`,
56
+ * `gemini`) differs from the GitHub org slug that publishes it (`anthropics`,
57
+ * `google-gemini`). Folded into the reference list
58
+ * (`typosquat-reference-list.ts`) as bare-brand reference entries, and also
59
+ * used as the curated "brand token" corpus for the authority-claiming-affix
60
+ * check below (§1 rule 3) — a narrower, independent check from the
61
+ * exact-skeleton rule (§1 rule 1).
62
+ *
63
+ * Values cross-checked against `HIGH_TRUST_OWNERS`
64
+ * (`packages/core/src/scripts/github-import/signal-of-intent.ts`) — kept in
65
+ * sync manually, same convention as that file's own documented
66
+ * cross-boundary-import constraint.
67
+ */
68
+ export const BRAND_ALIASES = {
69
+ anthropic: 'anthropics',
70
+ claude: 'anthropics',
71
+ gemini: 'google-gemini',
72
+ copilot: 'microsoft',
73
+ vercel: 'vercel-labs',
74
+ salesforce: 'SalesforceCommerceCloud',
75
+ };
76
+ // ============================================================================
77
+ // Authority-claiming affixes (§1 rule 3 / Change #5)
78
+ // ============================================================================
79
+ /**
80
+ * A small, curated "claims official status" affix list. Deliberately narrow —
81
+ * benign functional affixes (`mcp`, `tools`, `community`, `helper`, ...)
82
+ * simply aren't in this list, so they never trigger this check.
83
+ */
84
+ const AUTHORITY_CLAIMING_AFFIXES = new Set([
85
+ 'official',
86
+ 'verified',
87
+ 'authentic',
88
+ 'genuine',
89
+ ]);
90
+ /** Minimum reference-name length considered for the Levenshtein check (§1 rule 2).
91
+ * Guards against noisy false positives on very short brand tokens where an
92
+ * edit distance of 2 covers a large fraction of unrelated short words. */
93
+ const MIN_LEVENSHTEIN_REFERENCE_LENGTH = 6;
94
+ /** Maximum Levenshtein edit distance considered a typosquat variant. */
95
+ const MAX_LEVENSHTEIN_DISTANCE = 2;
96
+ // ============================================================================
97
+ // Folding / tokenization helpers
98
+ // ============================================================================
99
+ /**
100
+ * Fold a candidate/reference name through the confusable-skeleton map, then
101
+ * NFKC, then lowercase — the comparison key used by the exact-skeleton and
102
+ * Levenshtein checks (§1 rules 1 and 2).
103
+ */
104
+ function foldSkillName(raw) {
105
+ return confusableSkeleton(raw).normalize('NFKC').toLowerCase();
106
+ }
107
+ /** Split a name into lowercase alphanumeric tokens on any separator. */
108
+ function tokenize(raw) {
109
+ return raw
110
+ .toLowerCase()
111
+ .split(/[^a-z0-9]+/i)
112
+ .filter((t) => t.length > 0);
113
+ }
114
+ // ============================================================================
115
+ // Levenshtein distance
116
+ // ============================================================================
117
+ /**
118
+ * Standard iterative-DP Levenshtein edit distance (insertion/deletion/
119
+ * substitution). Inputs here are short skill-name strings, so an O(n*m) table
120
+ * is more than fast enough — no early-exit optimization needed.
121
+ */
122
+ export function levenshteinDistance(a, b) {
123
+ if (a === b)
124
+ return 0;
125
+ const aLen = a.length;
126
+ const bLen = b.length;
127
+ if (aLen === 0)
128
+ return bLen;
129
+ if (bLen === 0)
130
+ return aLen;
131
+ let prevRow = new Array(bLen + 1);
132
+ let currRow = new Array(bLen + 1);
133
+ for (let j = 0; j <= bLen; j++)
134
+ prevRow[j] = j;
135
+ for (let i = 1; i <= aLen; i++) {
136
+ currRow[0] = i;
137
+ for (let j = 1; j <= bLen; j++) {
138
+ const cost = a[i - 1] === b[j - 1] ? 0 : 1;
139
+ currRow[j] = Math.min(prevRow[j] + 1, // deletion
140
+ currRow[j - 1] + 1, // insertion
141
+ prevRow[j - 1] + cost // substitution
142
+ );
143
+ }
144
+ ;
145
+ [prevRow, currRow] = [currRow, prevRow];
146
+ }
147
+ return prevRow[bLen];
148
+ }
149
+ // ============================================================================
150
+ // Detector
151
+ // ============================================================================
152
+ /**
153
+ * Run all three checks against a single candidate skill name/id. Returns
154
+ * RAW findings (uncapped severity) — callers apply
155
+ * `applyTyposquatEnforcementMode()` before surfacing them, per the
156
+ * `typosquatEnforcementMode` rollout config (§6).
157
+ *
158
+ * `referenceNames` should already be lowercase (as produced by
159
+ * `buildTyposquatReferenceList()` in `typosquat-reference-list.ts`).
160
+ */
161
+ export function scanTyposquat(candidateName, referenceNames) {
162
+ const findings = [];
163
+ const candidateLower = candidateName.toLowerCase();
164
+ const foldedCandidate = foldSkillName(candidateName);
165
+ // ---- Rule 1: exact-skeleton impersonation --------------------------------
166
+ // Fires ONLY when folding changed something meaningful (a confusable
167
+ // substitution / fullwidth / math-alphanumeric fold occurred) AND the
168
+ // folded form exactly equals a reference name. A candidate whose lowercase
169
+ // form already equals the reference (pure case difference, or the
170
+ // candidate IS the reference) is not an impersonation attempt.
171
+ for (const reference of referenceNames) {
172
+ if (foldedCandidate === reference && candidateLower !== reference) {
173
+ findings.push({
174
+ type: 'typosquat',
175
+ severity: 'critical',
176
+ confidence: 'high',
177
+ message: `Skill name folds to the same confusable-skeleton as a well-known reference name ("${reference}") but is not byte-identical to it.`,
178
+ location: candidateName,
179
+ category: 'typosquat:impersonation-exact-skeleton',
180
+ });
181
+ break;
182
+ }
183
+ }
184
+ // ---- Rule 2: Levenshtein edit-distance <= 2 ------------------------------
185
+ // Skipped once rule 1 already fired for this candidate (distance 0 in
186
+ // folded space is rule 1's job, not rule 2's — no double-counting).
187
+ if (findings.length === 0) {
188
+ for (const reference of referenceNames) {
189
+ if (reference.length < MIN_LEVENSHTEIN_REFERENCE_LENGTH)
190
+ continue;
191
+ // Cheap length-delta pre-filter before the O(n*m) DP.
192
+ if (Math.abs(foldedCandidate.length - reference.length) > MAX_LEVENSHTEIN_DISTANCE)
193
+ continue;
194
+ const distance = levenshteinDistance(foldedCandidate, reference);
195
+ if (distance > 0 && distance <= MAX_LEVENSHTEIN_DISTANCE) {
196
+ findings.push({
197
+ type: 'typosquat',
198
+ severity: 'high',
199
+ confidence: 'medium',
200
+ message: `Skill name is an edit-distance-${distance} variant of a well-known reference name ("${reference}").`,
201
+ location: candidateName,
202
+ category: 'typosquat:levenshtein',
203
+ });
204
+ break;
205
+ }
206
+ }
207
+ }
208
+ // ---- Rule 3: authority-claiming affix (independent of rule 1) -----------
209
+ const tokens = tokenize(candidateName);
210
+ const hasBrandToken = tokens.some((t) => Object.prototype.hasOwnProperty.call(BRAND_ALIASES, t));
211
+ const hasAuthorityAffix = tokens.some((t) => AUTHORITY_CLAIMING_AFFIXES.has(t));
212
+ if (hasBrandToken && hasAuthorityAffix) {
213
+ findings.push({
214
+ type: 'typosquat',
215
+ severity: 'critical',
216
+ confidence: 'high',
217
+ message: `Skill name combines a known brand token with an affix that claims official/verified status.`,
218
+ location: candidateName,
219
+ category: 'typosquat:authority-affix',
220
+ });
221
+ }
222
+ return findings;
223
+ }
224
+ // ============================================================================
225
+ // Enforcement mode (§6)
226
+ // ============================================================================
227
+ /** SMI-595: default rollout mode — shadow mode, matching the
228
+ * `concurrency-audit-pr.yml` precedent (shadow for a period, then promote). */
229
+ export const DEFAULT_TYPOSQUAT_ENFORCEMENT_MODE = 'warn';
230
+ /** Resolve the effective enforcement mode, applying the default when unset. */
231
+ export function resolveTyposquatEnforcementMode(mode) {
232
+ return mode ?? DEFAULT_TYPOSQUAT_ENFORCEMENT_MODE;
233
+ }
234
+ const DOWNGRADE_TO_MEDIUM = new Set(['high', 'critical']);
235
+ /**
236
+ * Apply the rollout mode to raw typosquat findings:
237
+ * - `off` — discard all findings.
238
+ * - `warn` — cap severity at `medium` regardless of the raw detector's
239
+ * confidence (confidence is left untouched — only severity is capped).
240
+ * - `block` — pass findings through at their raw severity.
241
+ */
242
+ export function applyTyposquatEnforcementMode(findings, mode = DEFAULT_TYPOSQUAT_ENFORCEMENT_MODE) {
243
+ if (mode === 'off')
244
+ return [];
245
+ if (mode === 'warn') {
246
+ return findings.map((finding) => DOWNGRADE_TO_MEDIUM.has(finding.severity) ? { ...finding, severity: 'medium' } : finding);
247
+ }
248
+ return findings;
249
+ }
250
+ /**
251
+ * Convenience one-shot: detect + apply the enforcement mode in a single call.
252
+ */
253
+ export function detectTyposquat(candidateName, referenceNames, mode = DEFAULT_TYPOSQUAT_ENFORCEMENT_MODE) {
254
+ return applyTyposquatEnforcementMode(scanTyposquat(candidateName, referenceNames), mode);
255
+ }
256
+ //# sourceMappingURL=typosquat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typosquat.js","sourceRoot":"","sources":["../../../../src/security/scanner/typosquat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AAGH,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAIrD,+EAA+E;AAC/E,qBAAqB;AACrB,+EAA+E;AAE/E;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,MAAM,aAAa,GAAqC;IAC7D,SAAS,EAAE,YAAY;IACvB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,eAAe;IACvB,OAAO,EAAE,WAAW;IACpB,MAAM,EAAE,aAAa;IACrB,UAAU,EAAE,yBAAyB;CACtC,CAAA;AAED,+EAA+E;AAC/E,qDAAqD;AACrD,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,0BAA0B,GAAwB,IAAI,GAAG,CAAC;IAC9D,UAAU;IACV,UAAU;IACV,WAAW;IACX,SAAS;CACV,CAAC,CAAA;AAEF;;2EAE2E;AAC3E,MAAM,gCAAgC,GAAG,CAAC,CAAA;AAE1C,wEAAwE;AACxE,MAAM,wBAAwB,GAAG,CAAC,CAAA;AAElC,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;AAE/E;;;;GAIG;AACH,SAAS,aAAa,CAAC,GAAW;IAChC,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAA;AAChE,CAAC;AAED,wEAAwE;AACxE,SAAS,QAAQ,CAAC,GAAW;IAC3B,OAAO,GAAG;SACP,WAAW,EAAE;SACb,KAAK,CAAC,aAAa,CAAC;SACpB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;AAChC,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,CAAS,EAAE,CAAS;IACtD,IAAI,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,CAAA;IACrB,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAA;IACrB,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAA;IACrB,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAC3B,IAAI,IAAI,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IAE3B,IAAI,OAAO,GAAG,IAAI,KAAK,CAAS,IAAI,GAAG,CAAC,CAAC,CAAA;IACzC,IAAI,OAAO,GAAG,IAAI,KAAK,CAAS,IAAI,GAAG,CAAC,CAAC,CAAA;IACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAE9C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1C,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,GAAG,CACnB,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,WAAW;YAC3B,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,YAAY;YAChC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,eAAe;aACtC,CAAA;QACH,CAAC;QACD,CAAC;QAAA,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;IAC1C,CAAC;IAED,OAAO,OAAO,CAAC,IAAI,CAAC,CAAA;AACtB,CAAC;AAED,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E;;;;;;;;GAQG;AACH,MAAM,UAAU,aAAa,CAC3B,aAAqB,EACrB,cAAmC;IAEnC,MAAM,QAAQ,GAAsB,EAAE,CAAA;IACtC,MAAM,cAAc,GAAG,aAAa,CAAC,WAAW,EAAE,CAAA;IAClD,MAAM,eAAe,GAAG,aAAa,CAAC,aAAa,CAAC,CAAA;IAEpD,6EAA6E;IAC7E,qEAAqE;IACrE,sEAAsE;IACtE,2EAA2E;IAC3E,kEAAkE;IAClE,+DAA+D;IAC/D,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;QACvC,IAAI,eAAe,KAAK,SAAS,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;YAClE,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,WAAW;gBACjB,QAAQ,EAAE,UAAU;gBACpB,UAAU,EAAE,MAAM;gBAClB,OAAO,EAAE,qFAAqF,SAAS,qCAAqC;gBAC5I,QAAQ,EAAE,aAAa;gBACvB,QAAQ,EAAE,wCAAwC;aACnD,CAAC,CAAA;YACF,MAAK;QACP,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,sEAAsE;IACtE,oEAAoE;IACpE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,KAAK,MAAM,SAAS,IAAI,cAAc,EAAE,CAAC;YACvC,IAAI,SAAS,CAAC,MAAM,GAAG,gCAAgC;gBAAE,SAAQ;YACjE,sDAAsD;YACtD,IAAI,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,wBAAwB;gBAAE,SAAQ;YAC5F,MAAM,QAAQ,GAAG,mBAAmB,CAAC,eAAe,EAAE,SAAS,CAAC,CAAA;YAChE,IAAI,QAAQ,GAAG,CAAC,IAAI,QAAQ,IAAI,wBAAwB,EAAE,CAAC;gBACzD,QAAQ,CAAC,IAAI,CAAC;oBACZ,IAAI,EAAE,WAAW;oBACjB,QAAQ,EAAE,MAAM;oBAChB,UAAU,EAAE,QAAQ;oBACpB,OAAO,EAAE,kCAAkC,QAAQ,6CAA6C,SAAS,KAAK;oBAC9G,QAAQ,EAAE,aAAa;oBACvB,QAAQ,EAAE,uBAAuB;iBAClC,CAAC,CAAA;gBACF,MAAK;YACP,CAAC;QACH,CAAC;IACH,CAAC;IAED,4EAA4E;IAC5E,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,CAAA;IACtC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAA;IAChG,MAAM,iBAAiB,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,0BAA0B,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAC/E,IAAI,aAAa,IAAI,iBAAiB,EAAE,CAAC;QACvC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,WAAW;YACjB,QAAQ,EAAE,UAAU;YACpB,UAAU,EAAE,MAAM;YAClB,OAAO,EAAE,6FAA6F;YACtG,QAAQ,EAAE,aAAa;YACvB,QAAQ,EAAE,2BAA2B;SACtC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,+EAA+E;AAC/E,wBAAwB;AACxB,+EAA+E;AAE/E;gFACgF;AAChF,MAAM,CAAC,MAAM,kCAAkC,GAA6B,MAAM,CAAA;AAElF,+EAA+E;AAC/E,MAAM,UAAU,+BAA+B,CAC7C,IAA+B;IAE/B,OAAO,IAAI,IAAI,kCAAkC,CAAA;AACnD,CAAC;AAED,MAAM,mBAAmB,GAA6C,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAA;AAEnG;;;;;;GAMG;AACH,MAAM,UAAU,6BAA6B,CAC3C,QAA2B,EAC3B,OAAiC,kCAAkC;IAEnE,IAAI,IAAI,KAAK,KAAK;QAAE,OAAO,EAAE,CAAA;IAC7B,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;QACpB,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAC9B,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CACzF,CAAA;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAC7B,aAAqB,EACrB,cAAmC,EACnC,OAAiC,kCAAkC;IAEnE,OAAO,6BAA6B,CAAC,aAAa,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE,IAAI,CAAC,CAAA;AAC1F,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * SMI-595: typosquat.ts — detector tests.
3
+ *
4
+ * Covers the Wave 1 acceptance criteria directly:
5
+ * - exact-skeleton impersonation (fires on exact fold match only, never
6
+ * substring/affix)
7
+ * - Levenshtein edit-distance <= 2
8
+ * - authority-claiming affix, independent of the exact-skeleton rule
9
+ * - enforcement-mode severity capping
10
+ */
11
+ export {};
12
+ //# sourceMappingURL=typosquat.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typosquat.test.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/typosquat.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * SMI-595: typosquat.ts — detector tests.
3
+ *
4
+ * Covers the Wave 1 acceptance criteria directly:
5
+ * - exact-skeleton impersonation (fires on exact fold match only, never
6
+ * substring/affix)
7
+ * - Levenshtein edit-distance <= 2
8
+ * - authority-claiming affix, independent of the exact-skeleton rule
9
+ * - enforcement-mode severity capping
10
+ */
11
+ import { describe, it, expect } from 'vitest';
12
+ import { BRAND_ALIASES, levenshteinDistance, scanTyposquat, applyTyposquatEnforcementMode, resolveTyposquatEnforcementMode, detectTyposquat, DEFAULT_TYPOSQUAT_ENFORCEMENT_MODE, } from './typosquat.js';
13
+ import { HIGH_TRUST_OWNERS } from '../../scripts/github-import/signal-of-intent.js';
14
+ const findByCategory = (findings, category) => findings.filter((f) => f.category === category);
15
+ describe('BRAND_ALIASES (SMI-595 §3)', () => {
16
+ it('maps every alias to a real HIGH_TRUST_OWNERS entry', () => {
17
+ for (const owner of Object.values(BRAND_ALIASES)) {
18
+ expect(HIGH_TRUST_OWNERS.has(owner)).toBe(true);
19
+ }
20
+ });
21
+ it('keys are lowercase brand tokens', () => {
22
+ for (const brand of Object.keys(BRAND_ALIASES)) {
23
+ expect(brand).toBe(brand.toLowerCase());
24
+ }
25
+ });
26
+ });
27
+ describe('levenshteinDistance', () => {
28
+ it('is 0 for identical strings', () => {
29
+ expect(levenshteinDistance('anthropic', 'anthropic')).toBe(0);
30
+ });
31
+ it('counts a single substitution as distance 1', () => {
32
+ expect(levenshteinDistance('claude-code', 'claude-cude')).toBe(1);
33
+ });
34
+ it('counts a single deletion as distance 1', () => {
35
+ expect(levenshteinDistance('claude-code', 'claude-cod')).toBe(1);
36
+ });
37
+ it('matches the classic kitten/sitting example (distance 3)', () => {
38
+ expect(levenshteinDistance('kitten', 'sitting')).toBe(3);
39
+ });
40
+ });
41
+ describe('scanTyposquat — exact-skeleton impersonation (rule 1)', () => {
42
+ it('flags a homoglyph-substituted exact match (Cyrillic а for Latin a)', () => {
43
+ const referenceNames = new Set(['anthropic']);
44
+ const findings = scanTyposquat('аnthropic', referenceNames); // Cyrillic а (U+0430)
45
+ expect(findByCategory(findings, 'typosquat:impersonation-exact-skeleton')).toHaveLength(1);
46
+ expect(findings[0].severity).toBe('critical');
47
+ expect(findings[0].confidence).toBe('high');
48
+ });
49
+ it('does NOT flag a substring match (anthropic-community-tools) by this rule alone', () => {
50
+ const referenceNames = new Set(['anthropic']);
51
+ const findings = scanTyposquat('anthropic-community-tools', referenceNames);
52
+ expect(findByCategory(findings, 'typosquat:impersonation-exact-skeleton')).toHaveLength(0);
53
+ // and, more strongly for this specific case, no other rule fires either
54
+ // (no Levenshtein-range match, no authority-claiming affix present).
55
+ expect(findings).toHaveLength(0);
56
+ });
57
+ it('does NOT flag a pure case difference (not a confusable substitution)', () => {
58
+ const referenceNames = new Set(['anthropic']);
59
+ const findings = scanTyposquat('Anthropic', referenceNames);
60
+ expect(findByCategory(findings, 'typosquat:impersonation-exact-skeleton')).toHaveLength(0);
61
+ });
62
+ it('does NOT flag the reference name matching itself', () => {
63
+ const referenceNames = new Set(['anthropic']);
64
+ const findings = scanTyposquat('anthropic', referenceNames);
65
+ expect(findings).toHaveLength(0);
66
+ });
67
+ });
68
+ describe('scanTyposquat — Levenshtein edit-distance <= 2 (rule 2)', () => {
69
+ const referenceNames = new Set(['claude-code']); // models a HIGH_TRUST_OWNERS-published skill name
70
+ it('flags an edit-distance-1 variant', () => {
71
+ const findings = scanTyposquat('claude-cod', referenceNames);
72
+ expect(findByCategory(findings, 'typosquat:levenshtein')).toHaveLength(1);
73
+ expect(findings[0].severity).toBe('high');
74
+ });
75
+ it('flags an edit-distance-2 variant', () => {
76
+ const findings = scanTyposquat('claude-cudo', referenceNames); // 2 substitutions
77
+ expect(findByCategory(findings, 'typosquat:levenshtein')).toHaveLength(1);
78
+ });
79
+ it('does NOT flag an edit-distance-3+ variant (same length, no shared characters)', () => {
80
+ const findings = scanTyposquat('zzzzzzzzzzz', referenceNames); // same length as "claude-code" (11)
81
+ expect(findByCategory(findings, 'typosquat:levenshtein')).toHaveLength(0);
82
+ });
83
+ it('does NOT flag an unrelated name', () => {
84
+ const findings = scanTyposquat('a-totally-unrelated-skill-name', referenceNames);
85
+ expect(findings).toHaveLength(0);
86
+ });
87
+ });
88
+ describe('scanTyposquat — authority-claiming affix, independent of rule 1 (Change #5)', () => {
89
+ // Same base brand token ("anthropic") used for both the flagged and
90
+ // not-flagged cases, proving the two checks are genuinely independent.
91
+ const referenceNames = new Set(['anthropic']);
92
+ it('flags a brand token + authority-claiming affix (anthropic-mcp-official)', () => {
93
+ const findings = scanTyposquat('anthropic-mcp-official', referenceNames);
94
+ expect(findByCategory(findings, 'typosquat:authority-affix')).toHaveLength(1);
95
+ expect(findings.find((f) => f.category === 'typosquat:authority-affix')?.severity).toBe('critical');
96
+ });
97
+ it('does NOT flag a brand token + benign functional affix (anthropic-mcp)', () => {
98
+ const findings = scanTyposquat('anthropic-mcp', referenceNames);
99
+ expect(findings).toHaveLength(0);
100
+ });
101
+ it('does NOT flag a brand token + benign functional affix (anthropic-tools)', () => {
102
+ const findings = scanTyposquat('anthropic-tools', referenceNames);
103
+ expect(findings).toHaveLength(0);
104
+ });
105
+ it('does NOT flag other claimed-authority affixes without a brand token', () => {
106
+ const findings = scanTyposquat('totally-unrelated-official', referenceNames);
107
+ expect(findings).toHaveLength(0);
108
+ });
109
+ });
110
+ describe('applyTyposquatEnforcementMode / resolveTyposquatEnforcementMode (§6)', () => {
111
+ it('defaults to warn', () => {
112
+ expect(DEFAULT_TYPOSQUAT_ENFORCEMENT_MODE).toBe('warn');
113
+ expect(resolveTyposquatEnforcementMode(undefined)).toBe('warn');
114
+ });
115
+ it('resolves an explicit mode unchanged', () => {
116
+ expect(resolveTyposquatEnforcementMode('block')).toBe('block');
117
+ expect(resolveTyposquatEnforcementMode('off')).toBe('off');
118
+ });
119
+ it('warn mode caps critical/high severity at medium, regardless of raw confidence', () => {
120
+ const raw = scanTyposquat('anthropic-mcp-official', new Set(['anthropic']));
121
+ expect(raw[0].severity).toBe('critical'); // raw, uncapped
122
+ const capped = applyTyposquatEnforcementMode(raw, 'warn');
123
+ expect(capped[0].severity).toBe('medium');
124
+ expect(capped[0].confidence).toBe('high'); // confidence is untouched, only severity is capped
125
+ });
126
+ it('off mode discards all findings', () => {
127
+ const raw = scanTyposquat('anthropic-mcp-official', new Set(['anthropic']));
128
+ expect(applyTyposquatEnforcementMode(raw, 'off')).toHaveLength(0);
129
+ });
130
+ it('block mode passes findings through at raw severity', () => {
131
+ const raw = scanTyposquat('anthropic-mcp-official', new Set(['anthropic']));
132
+ const passed = applyTyposquatEnforcementMode(raw, 'block');
133
+ expect(passed[0].severity).toBe('critical');
134
+ });
135
+ it('detectTyposquat is a one-shot detect + apply-mode convenience wrapper, defaulting to warn', () => {
136
+ const findings = detectTyposquat('anthropic-mcp-official', new Set(['anthropic']));
137
+ expect(findings[0].severity).toBe('medium');
138
+ });
139
+ });
140
+ //# sourceMappingURL=typosquat.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"typosquat.test.js","sourceRoot":"","sources":["../../../../src/security/scanner/typosquat.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"weights.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/weights.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAK7D,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAkBnD,CAAA"}
1
+ {"version":3,"file":"weights.d.ts","sourceRoot":"","sources":["../../../../src/security/scanner/weights.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAElD;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAK7D,CAAA;AAED;;GAEG;AACH,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA4BnD,CAAA"}
@@ -33,5 +33,15 @@ export const CATEGORY_WEIGHTS = {
33
33
  // on its own (50 * 2.0 * 1.0 = 100 -> capped 100 -> * 0.40 = 40).
34
34
  code_execution: 2.0,
35
35
  obfuscated_directive: 2.0,
36
+ // SMI-595: a naming-similarity heuristic is advisory, not damning on its own —
37
+ // deliberately the same tier as sensitive_path/url, NOT the 1.7-2.0 tier used
38
+ // for jailbreak/exfiltration-class findings. Paired with the 0.04 coefficient
39
+ // in calculateRiskScore (the same coefficient already used for
40
+ // sensitivePaths/externalUrls/ssrf): a single medium-severity, high-confidence
41
+ // finding scores 15 * 1.2 * 1.0 = 18 -> contributes 18 * 0.04 = 0.72 (rounds to
42
+ // ~1) to the total; a saturated breakdown (capped at 100) contributes 4 —
43
+ // comfortably under the riskThreshold: 40 quarantine cutoff on its own. See the
44
+ // stacked-risk test in SecurityScanner.scoring.test.ts.
45
+ typosquat: 1.2,
36
46
  };
37
47
  //# sourceMappingURL=weights.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"weights.js","sourceRoot":"","sources":["../../../../src/security/scanner/weights.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAqC;IAChE,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE,EAAE;CACb,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,SAAS,EAAE,GAAG;IACd,kBAAkB,EAAE,GAAG;IACvB,cAAc,EAAE,GAAG;IACnB,iBAAiB,EAAE,GAAG;IACtB,oBAAoB,EAAE,GAAG;IACzB,kBAAkB,EAAE,GAAG;IACvB,cAAc,EAAE,GAAG;IACnB,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,GAAG,EAAE,iDAAiD;IAClE,IAAI,EAAE,GAAG,EAAE,uCAAuC;IAClD,GAAG,EAAE,GAAG,EAAE,8CAA8C;IACxD,8EAA8E;IAC9E,iFAAiF;IACjF,kFAAkF;IAClF,kEAAkE;IAClE,cAAc,EAAE,GAAG;IACnB,oBAAoB,EAAE,GAAG;CAC1B,CAAA"}
1
+ {"version":3,"file":"weights.js","sourceRoot":"","sources":["../../../../src/security/scanner/weights.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAqC;IAChE,GAAG,EAAE,CAAC;IACN,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,EAAE;IACR,QAAQ,EAAE,EAAE;CACb,CAAA;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA2B;IACtD,SAAS,EAAE,GAAG;IACd,kBAAkB,EAAE,GAAG;IACvB,cAAc,EAAE,GAAG;IACnB,iBAAiB,EAAE,GAAG;IACtB,oBAAoB,EAAE,GAAG;IACzB,kBAAkB,EAAE,GAAG;IACvB,cAAc,EAAE,GAAG;IACnB,GAAG,EAAE,GAAG;IACR,UAAU,EAAE,GAAG,EAAE,iDAAiD;IAClE,IAAI,EAAE,GAAG,EAAE,uCAAuC;IAClD,GAAG,EAAE,GAAG,EAAE,8CAA8C;IACxD,8EAA8E;IAC9E,iFAAiF;IACjF,kFAAkF;IAClF,kEAAkE;IAClE,cAAc,EAAE,GAAG;IACnB,oBAAoB,EAAE,GAAG;IACzB,+EAA+E;IAC/E,8EAA8E;IAC9E,8EAA8E;IAC9E,+DAA+D;IAC/D,+EAA+E;IAC/E,gFAAgF;IAChF,0EAA0E;IAC1E,gFAAgF;IAChF,wDAAwD;IACxD,SAAS,EAAE,GAAG;CACf,CAAA"}
@@ -26,6 +26,27 @@ export interface OptimizationResult {
26
26
  }
27
27
  export declare function hashContent(content: string): string;
28
28
  export declare function generateTips(skillName: string, optimizationInfo: OptimizationInfo): string[];
29
+ /**
30
+ * Read the MCP server names registered in the consuming project's
31
+ * `.mcp.json` (SMI-5676). Used to cross-check `extractMcpReferences`
32
+ * candidates against what's *actually* configured, so a stale/renamed
33
+ * reference (e.g. `claude-flow` after this project's own rename to `ruflo`)
34
+ * gets tagged `unregistered` in `serverResolutions` instead of silently
35
+ * asserted as a real dependency — without ever dropping a candidate that
36
+ * simply isn't installed *yet*.
37
+ *
38
+ * Fails open: returns `undefined` (not `[]`) when `.mcp.json` is missing,
39
+ * unreadable, or unparseable — `extractMcpReferences` treats `undefined` as
40
+ * "no information available" (`serverResolutions` = `'unknown'`), whereas
41
+ * `[]` would mean "zero servers registered", incorrectly tagging every real
42
+ * candidate `unregistered`.
43
+ *
44
+ * @param projectRoot - Directory to look for `.mcp.json` in (defaults to
45
+ * `process.cwd()`, matching the convention used elsewhere in the codebase
46
+ * for locating a consuming project's config, e.g.
47
+ * `packages/mcp-server/src/context/project-detector.ts`).
48
+ */
49
+ export declare function getRegisteredMcpServers(projectRoot?: string): string[] | undefined;
29
50
  export declare function extractDepIntel(skillMdContent: string): DepIntelResult;
30
51
  /**
31
52
  * Extract + persist dependency intelligence for a skill.
@@ -1 +1 @@
1
- {"version":3,"file":"skill-installation.helpers.d.ts","sourceRoot":"","sources":["../../../src/services/skill-installation.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,8CAA8C,CAAA;AAI7F,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAA;AAE3D,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,+CAA+C,CAAA;AAC/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EAChB,MAAM,+BAA+B,CAAA;AAGtC,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAA;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AAE1D,4DAA4D;AAC5D,MAAM,WAAW,kBAAkB;IACjC,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC3D,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,eAAe,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,gBAAgB,EAAE,gBAAgB,CAAA;CACnC;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAsB5F;AAED,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc,CAWtE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,yBAAyB,EAC/B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,cAAc,CAAC,cAAc,CAAC,GACvC,MAAM,CA2BR;AAED,2EAA2E;AAC3E,wBAAsB,gBAAgB,CAAC,MAAM,EAAE;IAC7C,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,OAAO,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,eAAe,CAAA;IACzB,mBAAmB,EAAE,yBAAyB,CAAA;IAC9C,UAAU,EAAE,gBAAgB,CAAA;CAC7B,GAAG,OAAO,CAAC,eAAe,CAAC,CAuF3B;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,QAAQ,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,cAAc,EAAE,MAAM,GACrB,OAAO,CAAC,kBAAkB,CAAC,CA8C7B;AAiBD,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAO3D;AAGD,uEAAuE;AACvE,wBAAgB,4BAA4B,CAAC,MAAM,EAAE;IACnD,UAAU,EAAE,UAAU,GAAG,SAAS,CAAA;IAClC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,OAAO,CAAA;IACnB,SAAS,EAAE,OAAO,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,OAAO,CAAA;CACrB,GAAG,MAAM,CAYT;AAED,kEAAkE;AAClE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,WAAW,EAAE,0BAA0B,GAAG,SAAS,CAAA;IACnD,OAAO,EAAE,MAAM,CAAA;IACf,UAAU,EAAE,UAAU,CAAA;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAA;CACzC,GAAG,IAAI,CAcP"}
1
+ {"version":3,"file":"skill-installation.helpers.d.ts","sourceRoot":"","sources":["../../../src/services/skill-installation.helpers.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@
7
7
  * file to meet the 500-line standard.
8
8
  */
9
9
  import * as fs from 'fs/promises';
10
+ import { existsSync, readFileSync } from 'fs';
10
11
  import * as path from 'path';
11
12
  import { createHash } from 'crypto';
12
13
  import { extractMcpReferences } from '../analysis/McpReferenceExtractor.js';
@@ -39,10 +40,53 @@ export function generateTips(skillName, optimizationInfo) {
39
40
  tips.push('', 'To uninstall: use the uninstall_skill tool');
40
41
  return tips;
41
42
  }
43
+ /**
44
+ * Read the MCP server names registered in the consuming project's
45
+ * `.mcp.json` (SMI-5676). Used to cross-check `extractMcpReferences`
46
+ * candidates against what's *actually* configured, so a stale/renamed
47
+ * reference (e.g. `claude-flow` after this project's own rename to `ruflo`)
48
+ * gets tagged `unregistered` in `serverResolutions` instead of silently
49
+ * asserted as a real dependency — without ever dropping a candidate that
50
+ * simply isn't installed *yet*.
51
+ *
52
+ * Fails open: returns `undefined` (not `[]`) when `.mcp.json` is missing,
53
+ * unreadable, or unparseable — `extractMcpReferences` treats `undefined` as
54
+ * "no information available" (`serverResolutions` = `'unknown'`), whereas
55
+ * `[]` would mean "zero servers registered", incorrectly tagging every real
56
+ * candidate `unregistered`.
57
+ *
58
+ * @param projectRoot - Directory to look for `.mcp.json` in (defaults to
59
+ * `process.cwd()`, matching the convention used elsewhere in the codebase
60
+ * for locating a consuming project's config, e.g.
61
+ * `packages/mcp-server/src/context/project-detector.ts`).
62
+ */
63
+ export function getRegisteredMcpServers(projectRoot = process.cwd()) {
64
+ const mcpJsonPath = path.join(projectRoot, '.mcp.json');
65
+ if (!existsSync(mcpJsonPath))
66
+ return undefined;
67
+ try {
68
+ const raw = readFileSync(mcpJsonPath, 'utf-8');
69
+ const parsed = JSON.parse(raw);
70
+ if (!parsed || typeof parsed !== 'object')
71
+ return undefined;
72
+ const mcpServers = parsed.mcpServers;
73
+ if (!mcpServers || typeof mcpServers !== 'object' || Array.isArray(mcpServers)) {
74
+ return undefined;
75
+ }
76
+ return Object.keys(mcpServers);
77
+ }
78
+ catch {
79
+ return undefined;
80
+ }
81
+ }
42
82
  export function extractDepIntel(skillMdContent) {
43
- const mcpResult = extractMcpReferences(skillMdContent);
83
+ const mcpResult = extractMcpReferences(skillMdContent, getRegisteredMcpServers());
44
84
  const warnings = [];
45
85
  for (const server of mcpResult.highConfidenceServers) {
86
+ // Don't warn about a server we positively confirmed IS configured —
87
+ // only flag servers we couldn't confirm (unregistered/unknown).
88
+ if (mcpResult.serverResolutions?.[server] === 'registered')
89
+ continue;
46
90
  warnings.push("MCP server '" + server + "' is referenced but may not be configured");
47
91
  }
48
92
  return {
@@ -64,7 +108,7 @@ export function extractDepIntel(skillMdContent) {
64
108
  * value directly.
65
109
  */
66
110
  export function persistDependencies(repo, skillId, content, declared) {
67
- const mcpResult = extractMcpReferences(content);
111
+ const mcpResult = extractMcpReferences(content, getRegisteredMcpServers());
68
112
  const merged = mergeDependencies(declared, mcpResult);
69
113
  if (merged.length === 0)
70
114
  return 0;
@@ -1 +1 @@
1
- {"version":3,"file":"skill-installation.helpers.js","sourceRoot":"","sources":["../../../src/services/skill-installation.helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill-installation.helpers.js","sourceRoot":"","sources":["../../../src/services/skill-installation.helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=skill-installation.helpers.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-installation.helpers.test.d.ts","sourceRoot":"","sources":["../../../src/services/skill-installation.helpers.test.ts"],"names":[],"mappings":""}