@skillsmith/mcp-server 0.4.8 → 0.4.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/src/index.js CHANGED
@@ -46,7 +46,7 @@ import { checkForUpdates, formatUpdateNotification } from '@skillsmith/core';
46
46
  import { createLicenseMiddleware } from './middleware/license.js';
47
47
  import { createQuotaMiddleware } from './middleware/quota.js';
48
48
  // Package version - keep in sync with package.json
49
- const PACKAGE_VERSION = '0.4.8';
49
+ const PACKAGE_VERSION = '0.4.9';
50
50
  const PACKAGE_NAME = '@skillsmith/mcp-server';
51
51
  import { installBundledSkills, installUserDocs, getUserGuidePath, } from './onboarding/install-assets.js';
52
52
  // SMI-2679: Quota enforcement middleware — module-level singletons, initialized once
@@ -1 +1 @@
1
- {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/tools/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAO1E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAG3C,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAc9F;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,YAAY,EACnB,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,aAAa,CAAC,CAmDxB"}
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/tools/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAEhD,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAO1E,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAA;AAG3C,OAAO,EAAE,kBAAkB,EAAE,KAAK,YAAY,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAA;AAc9F;;;;;;;;;GASG;AACH,wBAAsB,YAAY,CAChC,KAAK,EAAE,YAAY,EACnB,QAAQ,CAAC,EAAE,WAAW,GACrB,OAAO,CAAC,aAAa,CAAC,CA4DxB"}
@@ -13,7 +13,7 @@
13
13
  * - Adds conflict resolution (three-way merge, backup) on top
14
14
  * - Wires onProgress to MCP protocol notifications
15
15
  */
16
- import { SkillInstallationService, } from '@skillsmith/core';
16
+ import { SkillInstallationService, emitInstallEvent, } from '@skillsmith/core';
17
17
  import { getToolContext } from '../context.js';
18
18
  import { loadManifest, lookupSkillFromRegistry } from './install.helpers.js';
19
19
  // SMI-1867: Conflict resolution logic (extracted per governance review)
@@ -77,6 +77,7 @@ export async function installSkill(input, _context) {
77
77
  }
78
78
  }
79
79
  // Delegate to core service
80
+ const installStart = Date.now();
80
81
  const result = await service.install(input.skillId, {
81
82
  force: input.force,
82
83
  skipScan: input.skipScan,
@@ -84,6 +85,13 @@ export async function installSkill(input, _context) {
84
85
  conflictAction: input.conflictAction,
85
86
  confirmed: input.confirmed,
86
87
  });
88
+ // SMI-4182: fire-and-forget install telemetry for usage report funnel
89
+ void emitInstallEvent({
90
+ skillId: input.skillId,
91
+ source: 'mcp',
92
+ success: result.success,
93
+ durationMs: Date.now() - installStart,
94
+ });
87
95
  return result;
88
96
  }
89
97
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/tools/install.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/tools/install.ts"],"names":[],"mappings":"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"}
@@ -21,8 +21,8 @@ export declare const publishInputSchema: z.ZodObject<{
21
21
  /** Add claude-skill topic for registry discovery */
22
22
  add_topic: z.ZodDefault<z.ZodBoolean>;
23
23
  }, "strip", z.ZodTypeAny, {
24
- visibility: "public" | "private";
25
24
  skill_path: string;
25
+ visibility: "public" | "private";
26
26
  check_references: boolean;
27
27
  create_repo: boolean;
28
28
  add_topic: boolean;
@@ -18,18 +18,22 @@
18
18
  * Community users see a graceful license error response, never a hard throw.
19
19
  */
20
20
  import { z } from 'zod';
21
+ import type { NamespaceFlag, TriggerQuality } from './skill-pack-audit.types.js';
21
22
  import type { ToolContext } from '../context.js';
22
23
  /**
23
24
  * Input schema for skill_pack_audit tool
24
25
  */
25
26
  export declare const skillPackAuditInputSchema: z.ZodObject<{
26
27
  pack_path: z.ZodString;
28
+ check_trigger_quality: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
27
29
  }, "strip", z.ZodTypeAny, {
28
30
  pack_path: string;
31
+ check_trigger_quality: boolean;
29
32
  }, {
30
33
  pack_path: string;
34
+ check_trigger_quality?: boolean | undefined;
31
35
  }>;
32
- export type SkillPackAuditInput = z.infer<typeof skillPackAuditInputSchema>;
36
+ export type SkillPackAuditInput = z.input<typeof skillPackAuditInputSchema>;
33
37
  /**
34
38
  * Drift status for a single skill in the pack
35
39
  */
@@ -63,6 +67,18 @@ export interface SkillPackAuditResponse {
63
67
  noRegistryDataCount: number;
64
68
  /** Per-skill audit results, sorted alphabetically by name */
65
69
  skills: PackSkillEntry[];
70
+ /**
71
+ * SMI-4124: Trigger-quality analysis across the pack (generic trigger words
72
+ * in skill names/descriptions). Present when `check_trigger_quality` is `true`
73
+ * (default). Omitted when the caller explicitly opts out.
74
+ */
75
+ triggerQuality?: TriggerQuality;
76
+ /**
77
+ * SMI-4124: Namespace-quality flag on the pack itself. Present (possibly
78
+ * `null`) when `check_trigger_quality` is `true`. `null` = clean pack name.
79
+ * Omitted when the caller opts out.
80
+ */
81
+ namespaceQuality?: NamespaceFlag | null;
66
82
  }
67
83
  /**
68
84
  * MCP tool definition for skill_pack_audit
@@ -77,6 +93,11 @@ export declare const skillPackAuditToolSchema: {
77
93
  type: string;
78
94
  description: string;
79
95
  };
96
+ check_trigger_quality: {
97
+ type: string;
98
+ default: boolean;
99
+ description: string;
100
+ };
80
101
  };
81
102
  required: string[];
82
103
  };
@@ -1 +1 @@
1
- {"version":3,"file":"skill-pack-audit.d.ts","sourceRoot":"","sources":["../../../src/tools/skill-pack-audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAMhD;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;EAQpC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE3E;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,UAAU,GACV,OAAO,GACP,kBAAkB,GAClB,iBAAiB,CAAA;AAErB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,6EAA6E;IAC7E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,gFAAgF;IAChF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,mBAAmB;IACnB,MAAM,EAAE,eAAe,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAA;IAClB,sFAAsF;IACtF,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,mBAAmB,EAAE,MAAM,CAAA;IAC3B,6DAA6D;IAC7D,MAAM,EAAE,cAAc,EAAE,CAAA;CACzB;AAMD;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;CAkBpC,CAAA;AA4BD;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,mBAAmB,EAC1B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAuGjC"}
1
+ {"version":3,"file":"skill-pack-audit.d.ts","sourceRoot":"","sources":["../../../src/tools/skill-pack-audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAUvB,OAAO,KAAK,EAEV,aAAa,EACb,cAAc,EAEf,MAAM,6BAA6B,CAAA;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAMhD;;GAEG;AACH,eAAO,MAAM,yBAAyB;;;;;;;;;EAiBpC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAE3E;;GAEG;AACH,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,UAAU,GACV,OAAO,GACP,kBAAkB,GAClB,iBAAiB,CAAA;AAErB;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0EAA0E;IAC1E,IAAI,EAAE,MAAM,CAAA;IACZ,6EAA6E;IAC7E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,0EAA0E;IAC1E,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,gFAAgF;IAChF,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;IACtB,mBAAmB;IACnB,MAAM,EAAE,eAAe,CAAA;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAA;IAChB,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAA;IAClB,sFAAsF;IACtF,UAAU,EAAE,MAAM,CAAA;IAClB,6DAA6D;IAC7D,mBAAmB,EAAE,MAAM,CAAA;IAC3B,6DAA6D;IAC7D,MAAM,EAAE,cAAc,EAAE,CAAA;IACxB;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,aAAa,GAAG,IAAI,CAAA;CACxC;AAMD;;GAEG;AACH,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;CA6BpC,CAAA;AA4BD;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,mBAAmB,EAC1B,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,sBAAsB,CAAC,CAkNjC"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * @fileoverview Generic trigger-word + namespace detection helpers for
3
+ * `skill_pack_audit`.
4
+ * @module @skillsmith/mcp-server/tools/skill-pack-audit.helpers
5
+ * @see SMI-4124
6
+ *
7
+ * Pure functions — no I/O, no database access. Tested via
8
+ * `tests/unit/skill-pack-audit.test.ts`.
9
+ */
10
+ import type { GenericTriggersStoplist } from '@skillsmith/core';
11
+ import type { GenericWordFlag, NamespaceFlag } from './skill-pack-audit.types.js';
12
+ /**
13
+ * Detect generic trigger words in a skill's name and description.
14
+ *
15
+ * - Skill-name hits produce `severity: 'error'` (unconditional false-trigger magnet).
16
+ * - Description hits produce `severity: 'warning'`.
17
+ * - `suggested` is `${packDomain}-${token}` when a pack domain is available,
18
+ * otherwise `null`.
19
+ *
20
+ * @param description - Raw description value from frontmatter (may be string
21
+ * or string[] from block-scalar parsing, or other).
22
+ * @param skillName - Skill's `name` frontmatter value (falls back to dir name).
23
+ * @param packDomain - Inferred pack domain, or `null` when indeterminate.
24
+ * @param stoplist - Curated stoplist from `@skillsmith/core`.
25
+ * @returns Flags (name errors first, then description warnings).
26
+ */
27
+ export declare function detectGenericTriggerWords(description: unknown, skillName: string, packDomain: string | null, stoplist: GenericTriggersStoplist): GenericWordFlag[];
28
+ /**
29
+ * Aggregate per-skill `tags` across a pack to derive a pack domain.
30
+ *
31
+ * Priority:
32
+ * 1. If `packName` ends with `-skills` and is not itself generic, strip the
33
+ * suffix and return the prefix (e.g. `planning-skills` → `planning`).
34
+ * 2. Otherwise, compute the mode of non-generic tags across all skills.
35
+ * 3. Returns `null` when no domain can be inferred with confidence.
36
+ *
37
+ * @param packName - Pack directory name.
38
+ * @param allSkills - Per-skill tag arrays (undefined / non-array → ignored).
39
+ * @param stoplist - Curated stoplist (for generic-tag filtering).
40
+ */
41
+ export declare function derivePackDomain(packName: string, allSkills: Array<{
42
+ tags?: unknown;
43
+ }>, stoplist: GenericTriggersStoplist): string | null;
44
+ /**
45
+ * Detect a generic pack namespace.
46
+ *
47
+ * @returns NamespaceFlag when the pack name matches a generic namespace,
48
+ * otherwise null.
49
+ */
50
+ export declare function detectGenericNamespace(packName: string, allSkills: Array<{
51
+ tags?: unknown;
52
+ }>, stoplist: GenericTriggersStoplist): NamespaceFlag | null;
53
+ //# sourceMappingURL=skill-pack-audit.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-pack-audit.helpers.d.ts","sourceRoot":"","sources":["../../../src/tools/skill-pack-audit.helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAA;AAE/D,OAAO,KAAK,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AA4BjF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,OAAO,EACpB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,QAAQ,EAAE,uBAAuB,GAChC,eAAe,EAAE,CAqDnB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACpC,QAAQ,EAAE,uBAAuB,GAChC,MAAM,GAAG,IAAI,CAyCf;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACpC,QAAQ,EAAE,uBAAuB,GAChC,aAAa,GAAG,IAAI,CAqBtB"}
@@ -0,0 +1,181 @@
1
+ /**
2
+ * @fileoverview Generic trigger-word + namespace detection helpers for
3
+ * `skill_pack_audit`.
4
+ * @module @skillsmith/mcp-server/tools/skill-pack-audit.helpers
5
+ * @see SMI-4124
6
+ *
7
+ * Pure functions — no I/O, no database access. Tested via
8
+ * `tests/unit/skill-pack-audit.test.ts`.
9
+ */
10
+ import { FIELD_LIMITS } from './validate.types.js';
11
+ /**
12
+ * Coerce a description value into a plain string. `parseYamlFrontmatter` returns
13
+ * block-scalar (`description: |`) values as `string[]`, so we join with spaces.
14
+ * Non-string/non-string-array values yield an empty string.
15
+ */
16
+ function coerceDescription(description) {
17
+ if (typeof description === 'string')
18
+ return description;
19
+ if (Array.isArray(description)) {
20
+ return description.filter((item) => typeof item === 'string').join(' ');
21
+ }
22
+ return '';
23
+ }
24
+ /** Split cleaned description text into lowercase word tokens. */
25
+ function tokenizeForTriggers(text) {
26
+ // Clamp to the same limit `validate` enforces to prevent quadratic scans
27
+ // on malicious oversized frontmatter.
28
+ const clamped = text.slice(0, FIELD_LIMITS.description);
29
+ // Strip common punctuation / markdown, collapse whitespace.
30
+ return clamped
31
+ .toLowerCase()
32
+ .replace(/[^a-z0-9\s-]/g, ' ')
33
+ .split(/\s+/)
34
+ .filter((t) => t.length > 0);
35
+ }
36
+ /**
37
+ * Detect generic trigger words in a skill's name and description.
38
+ *
39
+ * - Skill-name hits produce `severity: 'error'` (unconditional false-trigger magnet).
40
+ * - Description hits produce `severity: 'warning'`.
41
+ * - `suggested` is `${packDomain}-${token}` when a pack domain is available,
42
+ * otherwise `null`.
43
+ *
44
+ * @param description - Raw description value from frontmatter (may be string
45
+ * or string[] from block-scalar parsing, or other).
46
+ * @param skillName - Skill's `name` frontmatter value (falls back to dir name).
47
+ * @param packDomain - Inferred pack domain, or `null` when indeterminate.
48
+ * @param stoplist - Curated stoplist from `@skillsmith/core`.
49
+ * @returns Flags (name errors first, then description warnings).
50
+ */
51
+ export function detectGenericTriggerWords(description, skillName, packDomain, stoplist) {
52
+ const flags = [];
53
+ const triggerSet = new Set(stoplist.triggerWords.map((w) => w.toLowerCase()));
54
+ // Name check (error): tokenize on non-alphanumerics so "spec-builder" flags both.
55
+ const nameTokens = new Set(skillName
56
+ .toLowerCase()
57
+ .split(/[^a-z0-9]+/)
58
+ .filter((t) => t.length > 0));
59
+ for (const token of nameTokens) {
60
+ if (triggerSet.has(token)) {
61
+ flags.push({
62
+ token,
63
+ location: 'name',
64
+ severity: 'error',
65
+ suggested: packDomain ? `${packDomain}-${token}` : null,
66
+ reason: `Skill name contains generic trigger word "${token}". ` +
67
+ `This causes Claude's skill-trigger heuristic to misfire on unrelated prompts. ` +
68
+ (packDomain
69
+ ? `Rename to "${packDomain}-${token}" to qualify the scope.`
70
+ : `Qualify with a domain prefix (e.g. "planning-${token}").`),
71
+ });
72
+ }
73
+ }
74
+ // Description check (warning): full-text tokenization.
75
+ const descText = coerceDescription(description);
76
+ if (descText.length > 0) {
77
+ const descTokens = tokenizeForTriggers(descText);
78
+ const seen = new Set();
79
+ for (const token of descTokens) {
80
+ if (seen.has(token))
81
+ continue;
82
+ if (nameTokens.has(token))
83
+ continue; // already flagged as name error
84
+ if (triggerSet.has(token)) {
85
+ seen.add(token);
86
+ flags.push({
87
+ token,
88
+ location: 'description',
89
+ severity: 'warning',
90
+ suggested: packDomain ? `${packDomain}-${token}` : null,
91
+ reason: `Description contains generic trigger word "${token}". ` +
92
+ `Consider rewording or qualifying the skill's activation phrasing to ` +
93
+ `avoid false-positive skill triggers.`,
94
+ });
95
+ }
96
+ }
97
+ }
98
+ return flags;
99
+ }
100
+ /**
101
+ * Aggregate per-skill `tags` across a pack to derive a pack domain.
102
+ *
103
+ * Priority:
104
+ * 1. If `packName` ends with `-skills` and is not itself generic, strip the
105
+ * suffix and return the prefix (e.g. `planning-skills` → `planning`).
106
+ * 2. Otherwise, compute the mode of non-generic tags across all skills.
107
+ * 3. Returns `null` when no domain can be inferred with confidence.
108
+ *
109
+ * @param packName - Pack directory name.
110
+ * @param allSkills - Per-skill tag arrays (undefined / non-array → ignored).
111
+ * @param stoplist - Curated stoplist (for generic-tag filtering).
112
+ */
113
+ export function derivePackDomain(packName, allSkills, stoplist) {
114
+ const genericNamespaces = new Set(stoplist.namespaces.map((n) => n.toLowerCase()));
115
+ const genericWords = new Set(stoplist.triggerWords.map((w) => w.toLowerCase()));
116
+ // Strategy 1: strip `-skills` suffix from non-generic pack name.
117
+ const lowerPack = packName.toLowerCase();
118
+ if (lowerPack.endsWith('-skills') && !genericNamespaces.has(lowerPack)) {
119
+ const prefix = lowerPack.slice(0, -'-skills'.length);
120
+ if (prefix.length > 0 && !genericNamespaces.has(prefix) && !genericWords.has(prefix)) {
121
+ return prefix;
122
+ }
123
+ }
124
+ // Strategy 2: mode of per-skill tags.
125
+ const counts = new Map();
126
+ for (const skill of allSkills) {
127
+ if (!Array.isArray(skill.tags))
128
+ continue;
129
+ for (const raw of skill.tags) {
130
+ if (typeof raw !== 'string')
131
+ continue;
132
+ const tag = raw.toLowerCase().trim();
133
+ if (tag.length === 0)
134
+ continue;
135
+ if (genericNamespaces.has(tag) || genericWords.has(tag))
136
+ continue;
137
+ counts.set(tag, (counts.get(tag) ?? 0) + 1);
138
+ }
139
+ }
140
+ if (counts.size === 0)
141
+ return null;
142
+ let bestTag = null;
143
+ let bestCount = 0;
144
+ for (const [tag, count] of counts) {
145
+ if (count > bestCount) {
146
+ bestTag = tag;
147
+ bestCount = count;
148
+ }
149
+ }
150
+ // Require the mode to cover at least 2 skills (or the only skill) to avoid
151
+ // picking random one-offs.
152
+ const minSkills = allSkills.length >= 2 ? 2 : 1;
153
+ return bestCount >= minSkills ? bestTag : null;
154
+ }
155
+ /**
156
+ * Detect a generic pack namespace.
157
+ *
158
+ * @returns NamespaceFlag when the pack name matches a generic namespace,
159
+ * otherwise null.
160
+ */
161
+ export function detectGenericNamespace(packName, allSkills, stoplist) {
162
+ const lowerPack = packName.toLowerCase();
163
+ const genericNamespaces = new Set(stoplist.namespaces.map((n) => n.toLowerCase()));
164
+ if (!genericNamespaces.has(lowerPack))
165
+ return null;
166
+ const domain = derivePackDomain(packName, allSkills, stoplist);
167
+ const suggested = domain ? `${domain}-skills` : null;
168
+ const reason = suggested
169
+ ? `Pack name "${packName}" is a generic namespace. Rename to "${suggested}" ` +
170
+ `to reflect its domain (inferred from per-skill tags).`
171
+ : `Pack name "${packName}" is a generic namespace and per-skill tags do not ` +
172
+ `converge on a clear domain. Rename to "<domain>-skills" where <domain> is ` +
173
+ `a specific scope (e.g. "planning-skills", "cicd-skills").`;
174
+ return {
175
+ packName,
176
+ severity: 'warning',
177
+ suggested,
178
+ reason,
179
+ };
180
+ }
181
+ //# sourceMappingURL=skill-pack-audit.helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"skill-pack-audit.helpers.js","sourceRoot":"","sources":["../../../src/tools/skill-pack-audit.helpers.ts"],"names":[],"mappings":"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"}
@@ -19,9 +19,10 @@
19
19
  */
20
20
  import { z } from 'zod';
21
21
  import { promises as fs } from 'fs';
22
- import { join, resolve, sep } from 'path';
23
- import { SkillsmithError, ErrorCodes } from '@skillsmith/core';
22
+ import { basename, join, resolve, sep } from 'path';
23
+ import { SkillsmithError, ErrorCodes, GENERIC_TRIGGERS } from '@skillsmith/core';
24
24
  import { parseYamlFrontmatter, hasPathTraversal } from './validate.helpers.js';
25
+ import { detectGenericTriggerWords, detectGenericNamespace, derivePackDomain, } from './skill-pack-audit.helpers.js';
25
26
  // ============================================================================
26
27
  // Input / Output types
27
28
  // ============================================================================
@@ -34,6 +35,13 @@ export const skillPackAuditInputSchema = z.object({
34
35
  .min(1)
35
36
  .describe('Absolute path to the skill pack root directory. ' +
36
37
  'Must contain a skills/ subdirectory with skill folders each containing SKILL.md.'),
38
+ check_trigger_quality: z
39
+ .boolean()
40
+ .optional()
41
+ .default(true)
42
+ .describe('When true (default), also flag generic trigger words in skill name/description ' +
43
+ 'and generic pack namespaces with rename suggestions. Set false for ' +
44
+ 'version-drift-only audits (legacy response shape). SMI-4124.'),
37
45
  });
38
46
  // ============================================================================
39
47
  // Tool schema (MCP tool definition)
@@ -43,9 +51,12 @@ export const skillPackAuditInputSchema = z.object({
43
51
  */
44
52
  export const skillPackAuditToolSchema = {
45
53
  name: 'skill_pack_audit',
46
- description: 'Audit a skill pack directory for version drift by comparing each bundled SKILL.md ' +
47
- 'version against the Skillsmith registry cache. Reports which skills are current, ' +
48
- 'outdated, ahead, or missing from the registry. ' +
54
+ description: 'Audit a skill pack directory for (a) version drift bundled SKILL.md versions vs. ' +
55
+ 'the Skillsmith registry cache and (b) trigger-quality issues — generic trigger ' +
56
+ 'words in skill names/descriptions and generic pack namespaces that misfire ' +
57
+ "Claude's skill-trigger heuristic (SMI-4124). Response is additive: new " +
58
+ 'triggerQuality and namespaceQuality fields appear when check_trigger_quality is ' +
59
+ 'true (default); existing fields (skills, driftCount, etc.) are unchanged. ' +
49
60
  'Requires Individual tier or higher.',
50
61
  inputSchema: {
51
62
  type: 'object',
@@ -54,6 +65,13 @@ export const skillPackAuditToolSchema = {
54
65
  type: 'string',
55
66
  description: 'Absolute path to the skill pack root directory (must contain a skills/ subdirectory).',
56
67
  },
68
+ check_trigger_quality: {
69
+ type: 'boolean',
70
+ default: true,
71
+ description: 'When true (default), also flag generic trigger words and generic pack ' +
72
+ 'namespaces with rename suggestions. Set false for version-drift-only audits ' +
73
+ '(legacy response shape — triggerQuality and namespaceQuality fields omitted).',
74
+ },
57
75
  },
58
76
  required: ['pack_path'],
59
77
  },
@@ -100,6 +118,8 @@ export async function executeSkillPackAudit(input, context) {
100
118
  }
101
119
  const packPath = resolve(input.pack_path);
102
120
  const skillsDir = join(packPath, 'skills');
121
+ const packName = basename(packPath);
122
+ const checkTriggerQuality = input.check_trigger_quality !== false;
103
123
  // Discover subdirectories in skills/
104
124
  let skillDirNames;
105
125
  try {
@@ -113,6 +133,10 @@ export async function executeSkillPackAudit(input, context) {
113
133
  throw new SkillsmithError(ErrorCodes.VALIDATION_INVALID_TYPE, `Pack contains ${skillDirNames.length} skill directories; maximum is 500`);
114
134
  }
115
135
  const skills = [];
136
+ // SMI-4124: parallel accumulators for trigger-quality analysis.
137
+ // We keep these outside PackSkillEntry to preserve the legacy response shape
138
+ // for callers who opt out of trigger-quality via check_trigger_quality: false.
139
+ const skillMeta = [];
116
140
  for (const dirName of skillDirNames) {
117
141
  const skillMdPath = join(skillsDir, dirName, 'SKILL.md');
118
142
  let resolvedMdPath;
@@ -168,16 +192,109 @@ export async function executeSkillPackAudit(input, context) {
168
192
  status = 'ahead';
169
193
  }
170
194
  skills.push({ name, bundledVersion, registryVersion, skillId, status });
195
+ // Capture description/tags for SMI-4124 trigger-quality analysis. We read
196
+ // these out of metadata (already parsed) regardless of the flag, since the
197
+ // cost is trivial; the analysis itself is gated below.
198
+ skillMeta.push({
199
+ name,
200
+ description: metadata?.description,
201
+ tags: metadata?.tags,
202
+ });
171
203
  }
172
204
  skills.sort((a, b) => a.name.localeCompare(b.name));
173
205
  const driftCount = skills.filter((s) => s.status === 'outdated' || s.status === 'ahead').length;
174
206
  const noRegistryDataCount = skills.filter((s) => s.status === 'no_registry_data').length;
207
+ // SMI-4124: Trigger-quality + namespace analysis (additive response growth).
208
+ // When the caller opts out, we omit both fields so the response shape matches
209
+ // the pre-extension contract byte-for-byte.
210
+ if (!checkTriggerQuality) {
211
+ return {
212
+ packPath,
213
+ skillCount: skills.length,
214
+ driftCount,
215
+ noRegistryDataCount,
216
+ skills,
217
+ };
218
+ }
219
+ const stoplist = GENERIC_TRIGGERS;
220
+ const packDomain = derivePackDomain(packName, skillMeta, stoplist);
221
+ // Per-skill flags (sorted alphabetically by skill name to match `skills`).
222
+ const sortedMeta = [...skillMeta].sort((a, b) => a.name.localeCompare(b.name));
223
+ const triggerEntries = [];
224
+ const nameFlagsByToken = new Map();
225
+ for (const meta of sortedMeta) {
226
+ const flags = detectGenericTriggerWords(meta.description, meta.name, packDomain, stoplist);
227
+ if (flags.length > 0) {
228
+ triggerEntries.push({ id: meta.name, flags });
229
+ // Track name-level flags so we can dedup against a namespace hit below.
230
+ for (const flag of flags) {
231
+ if (flag.location === 'name') {
232
+ const list = nameFlagsByToken.get(flag.token) ?? [];
233
+ list.push(flag);
234
+ nameFlagsByToken.set(flag.token, list);
235
+ }
236
+ }
237
+ }
238
+ }
239
+ // Namespace flag + dedup: if the pack name is generic AND a skill-name flag
240
+ // exists for the same root token, drop the duplicate skill-name error and
241
+ // fold its reason into the namespace warning's reason.
242
+ let namespaceFlag = detectGenericNamespace(packName, skillMeta, stoplist);
243
+ if (namespaceFlag) {
244
+ const packToken = packName.toLowerCase();
245
+ // Check if any skill-name flag shares a token with the pack name. Typical
246
+ // case: pack "skills" and a skill named "skills" — not common — but also
247
+ // covers partial-token overlap like pack "tools" and skill "build-tools"
248
+ // (namespace covers the generic concern; skill-name flag is redundant).
249
+ const overlappingTokens = [];
250
+ for (const [token] of nameFlagsByToken) {
251
+ if (packToken === token || packToken.includes(token) || token.includes(packToken)) {
252
+ overlappingTokens.push(token);
253
+ }
254
+ }
255
+ if (overlappingTokens.length > 0) {
256
+ // Remove the overlapping name flags from triggerEntries.
257
+ for (let i = triggerEntries.length - 1; i >= 0; i--) {
258
+ const entry = triggerEntries[i];
259
+ entry.flags = entry.flags.filter((f) => !(f.location === 'name' && overlappingTokens.includes(f.token)));
260
+ if (entry.flags.length === 0) {
261
+ triggerEntries.splice(i, 1);
262
+ }
263
+ }
264
+ // Merge the removed-flag reasoning into the namespace reason.
265
+ namespaceFlag = {
266
+ ...namespaceFlag,
267
+ reason: namespaceFlag.reason +
268
+ ` Also applies to skill(s) whose name contains the same generic token(s): ` +
269
+ overlappingTokens.map((t) => `"${t}"`).join(', ') +
270
+ ` — resolved by renaming the pack namespace.`,
271
+ };
272
+ }
273
+ }
274
+ let totalFlags = 0;
275
+ let errorCount = 0;
276
+ let warningCount = 0;
277
+ for (const entry of triggerEntries) {
278
+ for (const flag of entry.flags) {
279
+ totalFlags++;
280
+ if (flag.severity === 'error')
281
+ errorCount++;
282
+ else
283
+ warningCount++;
284
+ }
285
+ }
286
+ const triggerQuality = {
287
+ skills: triggerEntries,
288
+ summary: { totalFlags, errorCount, warningCount },
289
+ };
175
290
  return {
176
291
  packPath,
177
292
  skillCount: skills.length,
178
293
  driftCount,
179
294
  noRegistryDataCount,
180
295
  skills,
296
+ triggerQuality,
297
+ namespaceQuality: namespaceFlag,
181
298
  };
182
299
  }
183
300
  //# sourceMappingURL=skill-pack-audit.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"skill-pack-audit.js","sourceRoot":"","sources":["../../../src/tools/skill-pack-audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"skill-pack-audit.js","sourceRoot":"","sources":["../../../src/tools/skill-pack-audit.ts"],"names":[],"mappings":"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"}