@skillsmith/mcp-server 0.4.2 → 0.4.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.
- package/README.md +11 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/__tests__/LocalIndexer.test.js +158 -0
- package/dist/src/__tests__/LocalIndexer.test.js.map +1 -1
- package/dist/src/__tests__/compare.test.d.ts +8 -0
- package/dist/src/__tests__/compare.test.d.ts.map +1 -0
- package/dist/src/__tests__/compare.test.js +162 -0
- package/dist/src/__tests__/compare.test.js.map +1 -0
- package/dist/src/__tests__/context.async.test.d.ts +8 -0
- package/dist/src/__tests__/context.async.test.d.ts.map +1 -0
- package/dist/src/__tests__/context.async.test.js +223 -0
- package/dist/src/__tests__/context.async.test.js.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.builders.test.d.ts +10 -0
- package/dist/src/__tests__/middleware/errorFormatter.builders.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/errorFormatter.builders.test.js +93 -0
- package/dist/src/__tests__/middleware/errorFormatter.builders.test.js.map +1 -0
- package/dist/src/__tests__/middleware/license-renewal.test.d.ts +10 -0
- package/dist/src/__tests__/middleware/license-renewal.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/license-renewal.test.js +152 -0
- package/dist/src/__tests__/middleware/license-renewal.test.js.map +1 -0
- package/dist/src/__tests__/middleware/quota-helpers.test.d.ts +9 -0
- package/dist/src/__tests__/middleware/quota-helpers.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/quota-helpers.test.js +105 -0
- package/dist/src/__tests__/middleware/quota-helpers.test.js.map +1 -0
- package/dist/src/__tests__/middleware/quota.test.d.ts +12 -0
- package/dist/src/__tests__/middleware/quota.test.d.ts.map +1 -0
- package/dist/src/__tests__/middleware/quota.test.js +189 -0
- package/dist/src/__tests__/middleware/quota.test.js.map +1 -0
- package/dist/src/__tests__/recommend-online-path.test.d.ts +10 -0
- package/dist/src/__tests__/recommend-online-path.test.d.ts.map +1 -0
- package/dist/src/__tests__/recommend-online-path.test.js +225 -0
- package/dist/src/__tests__/recommend-online-path.test.js.map +1 -0
- package/dist/src/__tests__/recommend.test.d.ts +2 -0
- package/dist/src/__tests__/recommend.test.d.ts.map +1 -1
- package/dist/src/__tests__/recommend.test.js +14 -2
- package/dist/src/__tests__/recommend.test.js.map +1 -1
- package/dist/src/__tests__/search-online-path.test.d.ts +10 -0
- package/dist/src/__tests__/search-online-path.test.d.ts.map +1 -0
- package/dist/src/__tests__/search-online-path.test.js +140 -0
- package/dist/src/__tests__/search-online-path.test.js.map +1 -0
- package/dist/src/__tests__/search.test.js +153 -5
- package/dist/src/__tests__/search.test.js.map +1 -1
- package/dist/src/context/project-detector.d.ts.map +1 -1
- package/dist/src/context/project-detector.js +1 -0
- package/dist/src/context/project-detector.js.map +1 -1
- package/dist/src/context.async.d.ts +48 -0
- package/dist/src/context.async.d.ts.map +1 -0
- package/dist/src/context.async.js +217 -0
- package/dist/src/context.async.js.map +1 -0
- package/dist/src/context.d.ts +5 -145
- package/dist/src/context.d.ts.map +1 -1
- package/dist/src/context.helpers.d.ts +25 -0
- package/dist/src/context.helpers.d.ts.map +1 -0
- package/dist/src/context.helpers.js +49 -0
- package/dist/src/context.helpers.js.map +1 -0
- package/dist/src/context.js +13 -228
- package/dist/src/context.js.map +1 -1
- package/dist/src/context.types.d.ts +112 -0
- package/dist/src/context.types.d.ts.map +1 -0
- package/dist/src/context.types.js +10 -0
- package/dist/src/context.types.js.map +1 -0
- package/dist/src/health/readinessCheck.d.ts +1 -1
- package/dist/src/health/readinessCheck.d.ts.map +1 -1
- package/dist/src/index.js +25 -152
- package/dist/src/index.js.map +1 -1
- package/dist/src/indexer/FrontmatterParser.d.ts +6 -0
- package/dist/src/indexer/FrontmatterParser.d.ts.map +1 -1
- package/dist/src/indexer/FrontmatterParser.js +15 -0
- package/dist/src/indexer/FrontmatterParser.js.map +1 -1
- package/dist/src/indexer/LocalIndexer.d.ts +4 -0
- package/dist/src/indexer/LocalIndexer.d.ts.map +1 -1
- package/dist/src/indexer/LocalIndexer.js +3 -0
- package/dist/src/indexer/LocalIndexer.js.map +1 -1
- package/dist/src/middleware/degradation.d.ts.map +1 -1
- package/dist/src/middleware/degradation.js +8 -0
- package/dist/src/middleware/degradation.js.map +1 -1
- package/dist/src/middleware/errorFormatter.builders.d.ts +49 -0
- package/dist/src/middleware/errorFormatter.builders.d.ts.map +1 -0
- package/dist/src/middleware/errorFormatter.builders.js +237 -0
- package/dist/src/middleware/errorFormatter.builders.js.map +1 -0
- package/dist/src/middleware/errorFormatter.d.ts +5 -100
- package/dist/src/middleware/errorFormatter.d.ts.map +1 -1
- package/dist/src/middleware/errorFormatter.js +16 -238
- package/dist/src/middleware/errorFormatter.js.map +1 -1
- package/dist/src/middleware/errorFormatter.types.d.ts +81 -0
- package/dist/src/middleware/errorFormatter.types.d.ts.map +1 -0
- package/dist/src/middleware/errorFormatter.types.js +34 -0
- package/dist/src/middleware/errorFormatter.types.js.map +1 -0
- package/dist/src/middleware/toolFeatureMapping.d.ts +1 -1
- package/dist/src/middleware/toolFeatureMapping.d.ts.map +1 -1
- package/dist/src/middleware/toolFeatureMapping.js +10 -0
- package/dist/src/middleware/toolFeatureMapping.js.map +1 -1
- package/dist/src/tool-dispatch.d.ts +27 -0
- package/dist/src/tool-dispatch.d.ts.map +1 -0
- package/dist/src/tool-dispatch.js +142 -0
- package/dist/src/tool-dispatch.js.map +1 -0
- package/dist/src/tools/LocalSkillSearch.d.ts.map +1 -1
- package/dist/src/tools/LocalSkillSearch.js +4 -0
- package/dist/src/tools/LocalSkillSearch.js.map +1 -1
- package/dist/src/tools/compare.types.d.ts +5 -1
- package/dist/src/tools/compare.types.d.ts.map +1 -1
- package/dist/src/tools/compare.types.js.map +1 -1
- package/dist/src/tools/get-skill.d.ts.map +1 -1
- package/dist/src/tools/get-skill.js +30 -0
- package/dist/src/tools/get-skill.js.map +1 -1
- package/dist/src/tools/index.d.ts +8 -0
- package/dist/src/tools/index.d.ts.map +1 -1
- package/dist/src/tools/index.js +8 -0
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/install.d.ts +7 -58
- package/dist/src/tools/install.d.ts.map +1 -1
- package/dist/src/tools/install.dep-helpers.d.ts +41 -0
- package/dist/src/tools/install.dep-helpers.d.ts.map +1 -0
- package/dist/src/tools/install.dep-helpers.js +68 -0
- package/dist/src/tools/install.dep-helpers.js.map +1 -0
- package/dist/src/tools/install.dep-helpers.test.d.ts +6 -0
- package/dist/src/tools/install.dep-helpers.test.d.ts.map +1 -0
- package/dist/src/tools/install.dep-helpers.test.js +109 -0
- package/dist/src/tools/install.dep-helpers.test.js.map +1 -0
- package/dist/src/tools/install.js +49 -109
- package/dist/src/tools/install.js.map +1 -1
- package/dist/src/tools/install.optimize.d.ts +46 -0
- package/dist/src/tools/install.optimize.d.ts.map +1 -0
- package/dist/src/tools/install.optimize.js +67 -0
- package/dist/src/tools/install.optimize.js.map +1 -0
- package/dist/src/tools/install.tool.d.ts +44 -0
- package/dist/src/tools/install.tool.d.ts.map +1 -0
- package/dist/src/tools/install.tool.js +44 -0
- package/dist/src/tools/install.tool.js.map +1 -0
- package/dist/src/tools/install.types.d.ts +14 -1
- package/dist/src/tools/install.types.d.ts.map +1 -1
- package/dist/src/tools/install.types.js.map +1 -1
- package/dist/src/tools/outdated.d.ts +101 -0
- package/dist/src/tools/outdated.d.ts.map +1 -0
- package/dist/src/tools/outdated.js +214 -0
- package/dist/src/tools/outdated.js.map +1 -0
- package/dist/src/tools/outdated.test.d.ts +6 -0
- package/dist/src/tools/outdated.test.d.ts.map +1 -0
- package/dist/src/tools/outdated.test.js +287 -0
- package/dist/src/tools/outdated.test.js.map +1 -0
- package/dist/src/tools/recommend.d.ts +2 -4
- package/dist/src/tools/recommend.d.ts.map +1 -1
- package/dist/src/tools/recommend.format.d.ts +28 -0
- package/dist/src/tools/recommend.format.d.ts.map +1 -0
- package/dist/src/tools/recommend.format.js +111 -0
- package/dist/src/tools/recommend.format.js.map +1 -0
- package/dist/src/tools/recommend.js +6 -97
- package/dist/src/tools/recommend.js.map +1 -1
- package/dist/src/tools/recommend.types.d.ts +2 -2
- package/dist/src/tools/search.d.ts +24 -21
- package/dist/src/tools/search.d.ts.map +1 -1
- package/dist/src/tools/search.formatter.d.ts +30 -0
- package/dist/src/tools/search.formatter.d.ts.map +1 -0
- package/dist/src/tools/search.formatter.js +64 -0
- package/dist/src/tools/search.formatter.js.map +1 -0
- package/dist/src/tools/search.js +55 -54
- package/dist/src/tools/search.js.map +1 -1
- package/dist/src/tools/skill-audit.d.ts +98 -0
- package/dist/src/tools/skill-audit.d.ts.map +1 -0
- package/dist/src/tools/skill-audit.js +105 -0
- package/dist/src/tools/skill-audit.js.map +1 -0
- package/dist/src/tools/skill-audit.test.d.ts +6 -0
- package/dist/src/tools/skill-audit.test.d.ts.map +1 -0
- package/dist/src/tools/skill-audit.test.js +121 -0
- package/dist/src/tools/skill-audit.test.js.map +1 -0
- package/dist/src/tools/skill-diff.d.ts +107 -0
- package/dist/src/tools/skill-diff.d.ts.map +1 -0
- package/dist/src/tools/skill-diff.js +268 -0
- package/dist/src/tools/skill-diff.js.map +1 -0
- package/dist/src/tools/skill-diff.test.d.ts +6 -0
- package/dist/src/tools/skill-diff.test.d.ts.map +1 -0
- package/dist/src/tools/skill-diff.test.js +260 -0
- package/dist/src/tools/skill-diff.test.js.map +1 -0
- package/dist/src/tools/skill-pack-audit.d.ts +96 -0
- package/dist/src/tools/skill-pack-audit.d.ts.map +1 -0
- package/dist/src/tools/skill-pack-audit.js +183 -0
- package/dist/src/tools/skill-pack-audit.js.map +1 -0
- package/dist/src/tools/skill-updates.d.ts +1 -1
- package/dist/src/tools/skill-updates.d.ts.map +1 -1
- package/dist/src/tools/uninstall.d.ts.map +1 -1
- package/dist/src/tools/uninstall.js +9 -0
- package/dist/src/tools/uninstall.js.map +1 -1
- package/dist/src/tools/validate.d.ts.map +1 -1
- package/dist/src/tools/validate.dep.test.d.ts +6 -0
- package/dist/src/tools/validate.dep.test.d.ts.map +1 -0
- package/dist/src/tools/validate.dep.test.js +77 -0
- package/dist/src/tools/validate.dep.test.js.map +1 -0
- package/dist/src/tools/validate.helpers.d.ts +12 -0
- package/dist/src/tools/validate.helpers.d.ts.map +1 -1
- package/dist/src/tools/validate.helpers.js +90 -19
- package/dist/src/tools/validate.helpers.js.map +1 -1
- package/dist/src/tools/validate.js +3 -1
- package/dist/src/tools/validate.js.map +1 -1
- package/dist/src/utils/validation.d.ts +13 -0
- package/dist/src/utils/validation.d.ts.map +1 -1
- package/dist/src/utils/validation.js +27 -0
- package/dist/src/utils/validation.js.map +1 -1
- package/dist/tests/health.test.js +4 -4
- package/dist/tests/health.test.js.map +1 -1
- package/dist/tests/integration/recommend.integration.test.js +3 -0
- package/dist/tests/integration/recommend.integration.test.js.map +1 -1
- package/dist/tests/integration/setup.d.ts +4 -1
- package/dist/tests/integration/setup.d.ts.map +1 -1
- package/dist/tests/integration/setup.js +6 -1
- package/dist/tests/integration/setup.js.map +1 -1
- package/dist/tests/integration/validate.integration.test.js +4 -2
- package/dist/tests/integration/validate.integration.test.js.map +1 -1
- package/dist/tests/recommend.test.js +3 -0
- package/dist/tests/recommend.test.js.map +1 -1
- package/dist/tests/unit/skill-pack-audit.test.d.ts +8 -0
- package/dist/tests/unit/skill-pack-audit.test.d.ts.map +1 -0
- package/dist/tests/unit/skill-pack-audit.test.js +342 -0
- package/dist/tests/unit/skill-pack-audit.test.js.map +1 -0
- package/dist/tests/unit/validate-helpers.test.js +99 -2
- package/dist/tests/unit/validate-helpers.test.js.map +1 -1
- package/dist/tests/validate.test.js +4 -0
- package/dist/tests/validate.test.js.map +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview skill_audit MCP tool — check skills for security advisories
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/skill-audit
|
|
4
|
+
* @see SMI-skill-version-tracking Wave 3
|
|
5
|
+
*
|
|
6
|
+
* Returns a summary of active security advisories for installed skills.
|
|
7
|
+
* The advisory system is in early access — advisories are published by the
|
|
8
|
+
* Skillsmith team as security issues are identified.
|
|
9
|
+
*
|
|
10
|
+
* Tier gate: Team (skill_security_audit feature flag).
|
|
11
|
+
* Community and Individual users receive a graceful license error response.
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { AdvisoryRepository } from '@skillsmith/core';
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Input / Output types
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/**
|
|
19
|
+
* Input schema for skill_audit tool
|
|
20
|
+
*/
|
|
21
|
+
export const skillAuditInputSchema = z.object({
|
|
22
|
+
/** Optional filter — check only the specified skill IDs */
|
|
23
|
+
skillIds: z
|
|
24
|
+
.array(z.string().min(1))
|
|
25
|
+
.optional()
|
|
26
|
+
.describe('Specific skill IDs to audit (omit to audit all skills with advisories)'),
|
|
27
|
+
});
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// Tool schema (MCP tool definition)
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* MCP tool definition for skill_audit
|
|
33
|
+
*/
|
|
34
|
+
export const skillAuditToolSchema = {
|
|
35
|
+
name: 'skill_audit',
|
|
36
|
+
description: 'Check installed skills for known security advisories. ' +
|
|
37
|
+
'Requires Team tier or higher (skill_security_audit feature). ' +
|
|
38
|
+
'The advisory system is in early access — the Skillsmith team publishes advisories ' +
|
|
39
|
+
'as security issues are identified. Run `skillsmith sync` to fetch the latest advisories.',
|
|
40
|
+
inputSchema: {
|
|
41
|
+
type: 'object',
|
|
42
|
+
properties: {
|
|
43
|
+
skillIds: {
|
|
44
|
+
type: 'array',
|
|
45
|
+
items: { type: 'string' },
|
|
46
|
+
description: 'Specific skill IDs to audit (omit to return all skills with active advisories).',
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
required: [],
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
// ============================================================================
|
|
53
|
+
// Execution
|
|
54
|
+
// ============================================================================
|
|
55
|
+
/**
|
|
56
|
+
* Execute the skill_audit tool.
|
|
57
|
+
*
|
|
58
|
+
* Reads active advisories from skill_advisories table (migration v6).
|
|
59
|
+
* When the table is empty, returns an early-access message instead of
|
|
60
|
+
* an empty result so users understand the system is operational but
|
|
61
|
+
* advisory data has not yet been synced.
|
|
62
|
+
*
|
|
63
|
+
* @param input Validated tool input
|
|
64
|
+
* @param context Tool context with database connection
|
|
65
|
+
* @returns SkillAuditResponse with advisory data or early-access message
|
|
66
|
+
*/
|
|
67
|
+
export async function executeSkillAudit(input, context) {
|
|
68
|
+
const advisoryRepo = new AdvisoryRepository(context.db);
|
|
69
|
+
// Fetch advisories — filter by skillIds if provided
|
|
70
|
+
let advisories;
|
|
71
|
+
if (input.skillIds && input.skillIds.length > 0) {
|
|
72
|
+
advisories = input.skillIds.flatMap((id) => advisoryRepo.getAdvisoriesForSkill(id));
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
advisories = advisoryRepo.getActiveAdvisories();
|
|
76
|
+
}
|
|
77
|
+
// No advisories in DB — early-access message
|
|
78
|
+
if (advisories.length === 0) {
|
|
79
|
+
return {
|
|
80
|
+
advisoriesAvailable: false,
|
|
81
|
+
message: 'Advisory system is in early access — the Skillsmith team publishes advisories as ' +
|
|
82
|
+
'security issues are identified. Run `skillsmith sync` to fetch the latest.',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
// Build summary counts
|
|
86
|
+
const summary = { critical: 0, high: 0, medium: 0, low: 0, total: 0 };
|
|
87
|
+
for (const adv of advisories) {
|
|
88
|
+
summary[adv.severity]++;
|
|
89
|
+
summary.total++;
|
|
90
|
+
}
|
|
91
|
+
// Build per-advisory entries
|
|
92
|
+
const entries = advisories.map((adv) => ({
|
|
93
|
+
skillName: adv.skillId,
|
|
94
|
+
severity: adv.severity,
|
|
95
|
+
title: adv.title,
|
|
96
|
+
id: adv.id,
|
|
97
|
+
fixAvailable: Boolean(adv.patchedVersions),
|
|
98
|
+
}));
|
|
99
|
+
return {
|
|
100
|
+
advisoriesAvailable: true,
|
|
101
|
+
summary,
|
|
102
|
+
advisories: entries,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
//# sourceMappingURL=skill-audit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-audit.js","sourceRoot":"","sources":["../../../src/tools/skill-audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AAGrD,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,2DAA2D;IAC3D,QAAQ,EAAE,CAAC;SACR,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACxB,QAAQ,EAAE;SACV,QAAQ,CAAC,wEAAwE,CAAC;CACtF,CAAC,CAAA;AA6CF,+EAA+E;AAC/E,oCAAoC;AACpC,+EAA+E;AAE/E;;GAEG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,IAAI,EAAE,aAAsB;IAC5B,WAAW,EACT,wDAAwD;QACxD,+DAA+D;QAC/D,oFAAoF;QACpF,0FAA0F;IAC5F,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,QAAQ,EAAE;gBACR,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACzB,WAAW,EACT,iFAAiF;aACpF;SACF;QACD,QAAQ,EAAE,EAAE;KACb;CACF,CAAA;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAsB,EACtB,OAAoB;IAEpB,MAAM,YAAY,GAAG,IAAI,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAEvD,oDAAoD;IACpD,IAAI,UAAU,CAAA;IACd,IAAI,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAChD,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,YAAY,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAA;IACrF,CAAC;SAAM,CAAC;QACN,UAAU,GAAG,YAAY,CAAC,mBAAmB,EAAE,CAAA;IACjD,CAAC;IAED,6CAA6C;IAC7C,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,mBAAmB,EAAE,KAAK;YAC1B,OAAO,EACL,mFAAmF;gBACnF,4EAA4E;SAC/E,CAAA;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,OAAO,GAAoB,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAA;IACtF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAA;QACvB,OAAO,CAAC,KAAK,EAAE,CAAA;IACjB,CAAC;IAED,6BAA6B;IAC7B,MAAM,OAAO,GAAoB,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACxD,SAAS,EAAE,GAAG,CAAC,OAAO;QACtB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;KAC3C,CAAC,CAAC,CAAA;IAEH,OAAO;QACL,mBAAmB,EAAE,IAAI;QACzB,OAAO;QACP,UAAU,EAAE,OAAO;KACpB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-audit.test.d.ts","sourceRoot":"","sources":["../../../src/tools/skill-audit.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Unit tests for skill_audit MCP tool
|
|
3
|
+
* @see SMI-skill-version-tracking Wave 3
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
6
|
+
import { AdvisoryRepository } from '@skillsmith/core';
|
|
7
|
+
import { createTestDatabase, closeDatabase } from '../../../core/tests/helpers/database.js';
|
|
8
|
+
import { executeSkillAudit } from './skill-audit.js';
|
|
9
|
+
// ============================================================================
|
|
10
|
+
// Helpers
|
|
11
|
+
// ============================================================================
|
|
12
|
+
function makeAdvisory(overrides = {}) {
|
|
13
|
+
return {
|
|
14
|
+
id: 'SSA-2026-001',
|
|
15
|
+
skillId: 'community/commit-helper',
|
|
16
|
+
severity: 'high',
|
|
17
|
+
title: 'Prompt injection in commit-helper',
|
|
18
|
+
description: 'A security advisory for testing.',
|
|
19
|
+
publishedAt: '2026-01-15T00:00:00Z',
|
|
20
|
+
...overrides,
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
function makeContext(db) {
|
|
24
|
+
return { db };
|
|
25
|
+
}
|
|
26
|
+
// ============================================================================
|
|
27
|
+
// Tests
|
|
28
|
+
// ============================================================================
|
|
29
|
+
describe('executeSkillAudit', () => {
|
|
30
|
+
let db;
|
|
31
|
+
let advisoryRepo;
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
db = createTestDatabase();
|
|
34
|
+
advisoryRepo = new AdvisoryRepository(db);
|
|
35
|
+
});
|
|
36
|
+
afterEach(() => {
|
|
37
|
+
closeDatabase(db);
|
|
38
|
+
});
|
|
39
|
+
// --------------------------------------------------------------------------
|
|
40
|
+
// Empty database — early-access message
|
|
41
|
+
// --------------------------------------------------------------------------
|
|
42
|
+
it('returns advisoriesAvailable: false with early-access message when DB has no advisories', async () => {
|
|
43
|
+
const result = await executeSkillAudit({}, makeContext(db));
|
|
44
|
+
expect(result.advisoriesAvailable).toBe(false);
|
|
45
|
+
expect(result.message).toContain('early access');
|
|
46
|
+
expect(result.message).toContain('skillsmith sync');
|
|
47
|
+
expect(result.summary).toBeUndefined();
|
|
48
|
+
expect(result.advisories).toBeUndefined();
|
|
49
|
+
});
|
|
50
|
+
// --------------------------------------------------------------------------
|
|
51
|
+
// With advisories
|
|
52
|
+
// --------------------------------------------------------------------------
|
|
53
|
+
it('returns advisoriesAvailable: true with summary and entries when advisories exist', async () => {
|
|
54
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({ id: 'SSA-2026-001', severity: 'critical' }));
|
|
55
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({ id: 'SSA-2026-002', severity: 'high', skillId: 'community/other-skill' }));
|
|
56
|
+
const result = await executeSkillAudit({}, makeContext(db));
|
|
57
|
+
expect(result.advisoriesAvailable).toBe(true);
|
|
58
|
+
expect(result.message).toBeUndefined();
|
|
59
|
+
expect(result.summary).toBeDefined();
|
|
60
|
+
expect(result.summary.total).toBe(2);
|
|
61
|
+
expect(result.summary.critical).toBe(1);
|
|
62
|
+
expect(result.summary.high).toBe(1);
|
|
63
|
+
expect(result.summary.medium).toBe(0);
|
|
64
|
+
expect(result.summary.low).toBe(0);
|
|
65
|
+
expect(result.advisories).toHaveLength(2);
|
|
66
|
+
});
|
|
67
|
+
it('sets fixAvailable: true when patchedVersions is present', async () => {
|
|
68
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({ patchedVersions: '[">=1.2.0"]' }));
|
|
69
|
+
const result = await executeSkillAudit({}, makeContext(db));
|
|
70
|
+
expect(result.advisories[0].fixAvailable).toBe(true);
|
|
71
|
+
});
|
|
72
|
+
it('sets fixAvailable: false when patchedVersions is absent', async () => {
|
|
73
|
+
advisoryRepo.upsertAdvisory(makeAdvisory());
|
|
74
|
+
const result = await executeSkillAudit({}, makeContext(db));
|
|
75
|
+
expect(result.advisories[0].fixAvailable).toBe(false);
|
|
76
|
+
});
|
|
77
|
+
// --------------------------------------------------------------------------
|
|
78
|
+
// skillIds filter
|
|
79
|
+
// --------------------------------------------------------------------------
|
|
80
|
+
it('filters by skillIds when provided', async () => {
|
|
81
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({ id: 'SSA-2026-010', skillId: 'community/skill-a' }));
|
|
82
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({ id: 'SSA-2026-011', skillId: 'community/skill-b' }));
|
|
83
|
+
const result = await executeSkillAudit({ skillIds: ['community/skill-a'] }, makeContext(db));
|
|
84
|
+
expect(result.advisoriesAvailable).toBe(true);
|
|
85
|
+
expect(result.advisories).toHaveLength(1);
|
|
86
|
+
expect(result.advisories[0].skillName).toBe('community/skill-a');
|
|
87
|
+
});
|
|
88
|
+
it('returns early-access message when skillIds filter matches no advisories', async () => {
|
|
89
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({ skillId: 'community/skill-a' }));
|
|
90
|
+
const result = await executeSkillAudit({ skillIds: ['community/nonexistent'] }, makeContext(db));
|
|
91
|
+
expect(result.advisoriesAvailable).toBe(false);
|
|
92
|
+
expect(result.message).toContain('early access');
|
|
93
|
+
});
|
|
94
|
+
// --------------------------------------------------------------------------
|
|
95
|
+
// Withdrawn advisories excluded
|
|
96
|
+
// --------------------------------------------------------------------------
|
|
97
|
+
it('excludes withdrawn advisories from results', async () => {
|
|
98
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({ id: 'SSA-2026-020' }));
|
|
99
|
+
advisoryRepo.withdrawAdvisory('SSA-2026-020');
|
|
100
|
+
const result = await executeSkillAudit({}, makeContext(db));
|
|
101
|
+
expect(result.advisoriesAvailable).toBe(false);
|
|
102
|
+
});
|
|
103
|
+
// --------------------------------------------------------------------------
|
|
104
|
+
// Advisory entry fields
|
|
105
|
+
// --------------------------------------------------------------------------
|
|
106
|
+
it('maps advisory fields correctly to entry shape', async () => {
|
|
107
|
+
advisoryRepo.upsertAdvisory(makeAdvisory({
|
|
108
|
+
id: 'SSA-2026-030',
|
|
109
|
+
skillId: 'community/commit-helper',
|
|
110
|
+
severity: 'critical',
|
|
111
|
+
title: 'Test advisory',
|
|
112
|
+
}));
|
|
113
|
+
const result = await executeSkillAudit({}, makeContext(db));
|
|
114
|
+
const entry = result.advisories[0];
|
|
115
|
+
expect(entry.id).toBe('SSA-2026-030');
|
|
116
|
+
expect(entry.skillName).toBe('community/commit-helper');
|
|
117
|
+
expect(entry.severity).toBe('critical');
|
|
118
|
+
expect(entry.title).toBe('Test advisory');
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
//# sourceMappingURL=skill-audit.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-audit.test.js","sourceRoot":"","sources":["../../../src/tools/skill-audit.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview skill_diff MCP tool — section-level diff between skill versions
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/skill-diff
|
|
4
|
+
* @see SMI-skill-version-tracking Wave 2
|
|
5
|
+
*
|
|
6
|
+
* Returns a structured JSON diff of heading-level (H2/H3) sections between
|
|
7
|
+
* the locally-installed SKILL.md and the latest version recorded in the
|
|
8
|
+
* skill_versions table. Avoids raw unified diffs — human language is used
|
|
9
|
+
* for section names instead.
|
|
10
|
+
*
|
|
11
|
+
* Tier gate: Individual (version_tracking feature flag).
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import type { ToolContext } from '../context.js';
|
|
15
|
+
/** Input schema for skill_diff tool */
|
|
16
|
+
export declare const skillDiffInputSchema: z.ZodObject<{
|
|
17
|
+
skillId: z.ZodString;
|
|
18
|
+
oldContent: z.ZodString;
|
|
19
|
+
newContent: z.ZodString;
|
|
20
|
+
oldRiskScore: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
newRiskScore: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
hasLocalModifications: z.ZodDefault<z.ZodBoolean>;
|
|
23
|
+
trustTier: z.ZodDefault<z.ZodEnum<["verified", "community", "experimental"]>>;
|
|
24
|
+
}, "strip", z.ZodTypeAny, {
|
|
25
|
+
skillId: string;
|
|
26
|
+
oldContent: string;
|
|
27
|
+
newContent: string;
|
|
28
|
+
hasLocalModifications: boolean;
|
|
29
|
+
trustTier: "community" | "verified" | "experimental";
|
|
30
|
+
oldRiskScore?: number | undefined;
|
|
31
|
+
newRiskScore?: number | undefined;
|
|
32
|
+
}, {
|
|
33
|
+
skillId: string;
|
|
34
|
+
oldContent: string;
|
|
35
|
+
newContent: string;
|
|
36
|
+
oldRiskScore?: number | undefined;
|
|
37
|
+
newRiskScore?: number | undefined;
|
|
38
|
+
hasLocalModifications?: boolean | undefined;
|
|
39
|
+
trustTier?: "community" | "verified" | "experimental" | undefined;
|
|
40
|
+
}>;
|
|
41
|
+
export type SkillDiffInput = z.infer<typeof skillDiffInputSchema>;
|
|
42
|
+
/** Structured section-level diff response */
|
|
43
|
+
export interface SkillDiffResponse {
|
|
44
|
+
skill: string;
|
|
45
|
+
changeType: 'major' | 'minor' | 'patch' | 'unknown';
|
|
46
|
+
sectionsAdded: string[];
|
|
47
|
+
sectionsRemoved: string[];
|
|
48
|
+
sectionsModified: string[];
|
|
49
|
+
riskScoreDelta: number | null;
|
|
50
|
+
changelog: string | null;
|
|
51
|
+
recommendation: 'auto-update' | 'review-then-update' | 'manual-review-required';
|
|
52
|
+
}
|
|
53
|
+
export declare const skillDiffToolSchema: {
|
|
54
|
+
name: "skill_diff";
|
|
55
|
+
description: string;
|
|
56
|
+
inputSchema: {
|
|
57
|
+
type: "object";
|
|
58
|
+
properties: {
|
|
59
|
+
skillId: {
|
|
60
|
+
type: string;
|
|
61
|
+
description: string;
|
|
62
|
+
};
|
|
63
|
+
oldContent: {
|
|
64
|
+
type: string;
|
|
65
|
+
description: string;
|
|
66
|
+
};
|
|
67
|
+
newContent: {
|
|
68
|
+
type: string;
|
|
69
|
+
description: string;
|
|
70
|
+
};
|
|
71
|
+
oldRiskScore: {
|
|
72
|
+
type: string;
|
|
73
|
+
description: string;
|
|
74
|
+
};
|
|
75
|
+
newRiskScore: {
|
|
76
|
+
type: string;
|
|
77
|
+
description: string;
|
|
78
|
+
};
|
|
79
|
+
hasLocalModifications: {
|
|
80
|
+
type: string;
|
|
81
|
+
description: string;
|
|
82
|
+
};
|
|
83
|
+
trustTier: {
|
|
84
|
+
type: string;
|
|
85
|
+
enum: string[];
|
|
86
|
+
description: string;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
required: string[];
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
/**
|
|
93
|
+
* Execute the skill_diff tool.
|
|
94
|
+
*
|
|
95
|
+
* Computes a section-level diff using heading analysis and delegates change
|
|
96
|
+
* classification and risk scoring to core utilities.
|
|
97
|
+
*
|
|
98
|
+
* @param input Validated tool input
|
|
99
|
+
* @param _context Tool context (unused — diff is purely content-based)
|
|
100
|
+
* @returns SkillDiffResponse with section diff and risk recommendation
|
|
101
|
+
*/
|
|
102
|
+
export declare function executeSkillDiff(input: SkillDiffInput, _context: ToolContext): Promise<SkillDiffResponse>;
|
|
103
|
+
/**
|
|
104
|
+
* Format a SkillDiffResponse as human-readable text
|
|
105
|
+
*/
|
|
106
|
+
export declare function formatSkillDiffResults(response: SkillDiffResponse): string;
|
|
107
|
+
//# sourceMappingURL=skill-diff.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-diff.d.ts","sourceRoot":"","sources":["../../../src/tools/skill-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAMhD,uCAAuC;AACvC,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;EA0B/B,CAAA;AAEF,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AAEjE,6CAA6C;AAC7C,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,CAAA;IACnD,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,cAAc,EAAE,aAAa,GAAG,oBAAoB,GAAG,wBAAwB,CAAA;CAChF;AAMD,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0C/B,CAAA;AA8GD;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,cAAc,EACrB,QAAQ,EAAE,WAAW,GACpB,OAAO,CAAC,iBAAiB,CAAC,CAiD5B;AAMD;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,CAgC1E"}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview skill_diff MCP tool — section-level diff between skill versions
|
|
3
|
+
* @module @skillsmith/mcp-server/tools/skill-diff
|
|
4
|
+
* @see SMI-skill-version-tracking Wave 2
|
|
5
|
+
*
|
|
6
|
+
* Returns a structured JSON diff of heading-level (H2/H3) sections between
|
|
7
|
+
* the locally-installed SKILL.md and the latest version recorded in the
|
|
8
|
+
* skill_versions table. Avoids raw unified diffs — human language is used
|
|
9
|
+
* for section names instead.
|
|
10
|
+
*
|
|
11
|
+
* Tier gate: Individual (version_tracking feature flag).
|
|
12
|
+
*/
|
|
13
|
+
import { z } from 'zod';
|
|
14
|
+
import { classifyChange, computeUpdateRisk } from '@skillsmith/core';
|
|
15
|
+
// ============================================================================
|
|
16
|
+
// Input / Output types
|
|
17
|
+
// ============================================================================
|
|
18
|
+
/** Input schema for skill_diff tool */
|
|
19
|
+
export const skillDiffInputSchema = z.object({
|
|
20
|
+
skillId: z.string().min(1).describe('Registry skill identifier (e.g. "author/skill-name")'),
|
|
21
|
+
oldContent: z.string().min(1).describe('Previous SKILL.md content'),
|
|
22
|
+
newContent: z.string().min(1).describe('Updated SKILL.md content'),
|
|
23
|
+
oldRiskScore: z
|
|
24
|
+
.number()
|
|
25
|
+
.int()
|
|
26
|
+
.min(0)
|
|
27
|
+
.max(100)
|
|
28
|
+
.optional()
|
|
29
|
+
.describe('Risk score of the old version (0–100)'),
|
|
30
|
+
newRiskScore: z
|
|
31
|
+
.number()
|
|
32
|
+
.int()
|
|
33
|
+
.min(0)
|
|
34
|
+
.max(100)
|
|
35
|
+
.optional()
|
|
36
|
+
.describe('Risk score of the new version (0–100)'),
|
|
37
|
+
hasLocalModifications: z
|
|
38
|
+
.boolean()
|
|
39
|
+
.default(false)
|
|
40
|
+
.describe('Whether the installed skill has local edits'),
|
|
41
|
+
trustTier: z
|
|
42
|
+
.enum(['verified', 'community', 'experimental'])
|
|
43
|
+
.default('community')
|
|
44
|
+
.describe('Registry trust tier'),
|
|
45
|
+
});
|
|
46
|
+
// ============================================================================
|
|
47
|
+
// Tool schema (MCP tool definition)
|
|
48
|
+
// ============================================================================
|
|
49
|
+
export const skillDiffToolSchema = {
|
|
50
|
+
name: 'skill_diff',
|
|
51
|
+
description: 'Show a section-level diff between two versions of an installed skill. ' +
|
|
52
|
+
'Returns added, removed, and modified headings along with a change type ' +
|
|
53
|
+
'(major/minor/patch) and update recommendation. ' +
|
|
54
|
+
'Requires Individual tier or higher (version_tracking feature).',
|
|
55
|
+
inputSchema: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: {
|
|
58
|
+
skillId: {
|
|
59
|
+
type: 'string',
|
|
60
|
+
description: 'Registry skill identifier (e.g. "author/skill-name")',
|
|
61
|
+
},
|
|
62
|
+
oldContent: {
|
|
63
|
+
type: 'string',
|
|
64
|
+
description: 'Previous SKILL.md content',
|
|
65
|
+
},
|
|
66
|
+
newContent: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description: 'Updated SKILL.md content',
|
|
69
|
+
},
|
|
70
|
+
oldRiskScore: {
|
|
71
|
+
type: 'number',
|
|
72
|
+
description: 'Risk score of the old version (0–100)',
|
|
73
|
+
},
|
|
74
|
+
newRiskScore: {
|
|
75
|
+
type: 'number',
|
|
76
|
+
description: 'Risk score of the new version (0–100)',
|
|
77
|
+
},
|
|
78
|
+
hasLocalModifications: {
|
|
79
|
+
type: 'boolean',
|
|
80
|
+
description: 'Whether the installed skill has local edits',
|
|
81
|
+
},
|
|
82
|
+
trustTier: {
|
|
83
|
+
type: 'string',
|
|
84
|
+
enum: ['verified', 'community', 'experimental'],
|
|
85
|
+
description: 'Registry trust tier',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
required: ['skillId', 'oldContent', 'newContent'],
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
// ============================================================================
|
|
92
|
+
// Heading extraction (local — same algorithm as change-classifier)
|
|
93
|
+
// ============================================================================
|
|
94
|
+
function extractHeadings(content) {
|
|
95
|
+
const headings = new Map();
|
|
96
|
+
for (const line of content.split('\n')) {
|
|
97
|
+
const m = /^#{2,3}\s+(.+)/.exec(line);
|
|
98
|
+
if (m) {
|
|
99
|
+
const title = m[1].trim();
|
|
100
|
+
headings.set(title.toLowerCase(), title);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return headings;
|
|
104
|
+
}
|
|
105
|
+
// ============================================================================
|
|
106
|
+
// Changelog extraction
|
|
107
|
+
// ============================================================================
|
|
108
|
+
/**
|
|
109
|
+
* Extract changelog text from frontmatter or from a ## Changelog section.
|
|
110
|
+
* Returns null if none found.
|
|
111
|
+
*/
|
|
112
|
+
function extractChangelog(content) {
|
|
113
|
+
// Frontmatter: changelog: "some text"
|
|
114
|
+
const fmMatch = /^---\r?\n([\s\S]*?)\r?\n---/.exec(content);
|
|
115
|
+
if (fmMatch) {
|
|
116
|
+
for (const line of fmMatch[1].split('\n')) {
|
|
117
|
+
const colonIdx = line.indexOf(':');
|
|
118
|
+
if (colonIdx !== -1) {
|
|
119
|
+
const key = line.slice(0, colonIdx).trim().toLowerCase();
|
|
120
|
+
const value = line.slice(colonIdx + 1).trim();
|
|
121
|
+
if (key === 'changelog' && value)
|
|
122
|
+
return value.replace(/^["']|["']$/g, '');
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// Body: lines under ## Changelog / ## Change Log
|
|
127
|
+
const lines = content.split('\n');
|
|
128
|
+
let inSection = false;
|
|
129
|
+
const sectionLines = [];
|
|
130
|
+
for (const line of lines) {
|
|
131
|
+
if (/^#{1,3}\s+change[\s-]?log/i.test(line)) {
|
|
132
|
+
inSection = true;
|
|
133
|
+
continue;
|
|
134
|
+
}
|
|
135
|
+
if (inSection && /^#{1,3}\s+/.test(line))
|
|
136
|
+
break;
|
|
137
|
+
if (inSection && line.trim())
|
|
138
|
+
sectionLines.push(line.trim());
|
|
139
|
+
}
|
|
140
|
+
return sectionLines.length > 0 ? sectionLines.slice(0, 5).join(' ') : null;
|
|
141
|
+
}
|
|
142
|
+
// ============================================================================
|
|
143
|
+
// Section-body comparison
|
|
144
|
+
// ============================================================================
|
|
145
|
+
/**
|
|
146
|
+
* Determine which sections (present in both old and new) have changed body
|
|
147
|
+
* content. Returns section titles (canonical form) that were modified.
|
|
148
|
+
*/
|
|
149
|
+
function detectModifiedSections(oldContent, newContent) {
|
|
150
|
+
const oldSectionBodies = extractSectionBodies(oldContent);
|
|
151
|
+
const newSectionBodies = extractSectionBodies(newContent);
|
|
152
|
+
const modified = [];
|
|
153
|
+
for (const [key, oldBody] of oldSectionBodies) {
|
|
154
|
+
const newBody = newSectionBodies.get(key);
|
|
155
|
+
if (newBody !== undefined && newBody !== oldBody) {
|
|
156
|
+
modified.push(key);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return modified;
|
|
160
|
+
}
|
|
161
|
+
/** Build a map of heading (lowercase) → body text */
|
|
162
|
+
function extractSectionBodies(content) {
|
|
163
|
+
const result = new Map();
|
|
164
|
+
const lines = content.split('\n');
|
|
165
|
+
let currentHeading = null;
|
|
166
|
+
const bodyLines = [];
|
|
167
|
+
const flush = () => {
|
|
168
|
+
if (currentHeading !== null) {
|
|
169
|
+
result.set(currentHeading, bodyLines.join('\n').trim());
|
|
170
|
+
bodyLines.length = 0;
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
for (const line of lines) {
|
|
174
|
+
const m = /^#{2,3}\s+(.+)/.exec(line);
|
|
175
|
+
if (m) {
|
|
176
|
+
flush();
|
|
177
|
+
currentHeading = m[1].trim().toLowerCase();
|
|
178
|
+
}
|
|
179
|
+
else if (currentHeading !== null) {
|
|
180
|
+
bodyLines.push(line);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
flush();
|
|
184
|
+
return result;
|
|
185
|
+
}
|
|
186
|
+
// ============================================================================
|
|
187
|
+
// Execution
|
|
188
|
+
// ============================================================================
|
|
189
|
+
/**
|
|
190
|
+
* Execute the skill_diff tool.
|
|
191
|
+
*
|
|
192
|
+
* Computes a section-level diff using heading analysis and delegates change
|
|
193
|
+
* classification and risk scoring to core utilities.
|
|
194
|
+
*
|
|
195
|
+
* @param input Validated tool input
|
|
196
|
+
* @param _context Tool context (unused — diff is purely content-based)
|
|
197
|
+
* @returns SkillDiffResponse with section diff and risk recommendation
|
|
198
|
+
*/
|
|
199
|
+
export async function executeSkillDiff(input, _context) {
|
|
200
|
+
const validated = skillDiffInputSchema.parse(input);
|
|
201
|
+
const { skillId, oldContent, newContent, oldRiskScore, newRiskScore, hasLocalModifications, trustTier, } = validated;
|
|
202
|
+
// Heading analysis
|
|
203
|
+
const oldHeadings = extractHeadings(oldContent);
|
|
204
|
+
const newHeadings = extractHeadings(newContent);
|
|
205
|
+
const sectionsRemoved = [...oldHeadings.values()].filter((t) => !newHeadings.has(t.toLowerCase()));
|
|
206
|
+
const sectionsAdded = [...newHeadings.values()].filter((t) => !oldHeadings.has(t.toLowerCase()));
|
|
207
|
+
const sectionsModified = detectModifiedSections(oldContent, newContent);
|
|
208
|
+
// Change classification
|
|
209
|
+
const changeType = classifyChange(oldContent, newContent, oldRiskScore, newRiskScore);
|
|
210
|
+
// Risk scoring
|
|
211
|
+
const riskScoreDelta = typeof oldRiskScore === 'number' && typeof newRiskScore === 'number'
|
|
212
|
+
? newRiskScore - oldRiskScore
|
|
213
|
+
: null;
|
|
214
|
+
const { recommendation } = computeUpdateRisk({
|
|
215
|
+
changeType,
|
|
216
|
+
riskScoreDelta: riskScoreDelta ?? undefined,
|
|
217
|
+
hasLocalModifications,
|
|
218
|
+
trustTier,
|
|
219
|
+
hasChangelog: extractChangelog(newContent) !== null,
|
|
220
|
+
});
|
|
221
|
+
const changelog = extractChangelog(newContent);
|
|
222
|
+
return {
|
|
223
|
+
skill: skillId,
|
|
224
|
+
changeType,
|
|
225
|
+
sectionsAdded,
|
|
226
|
+
sectionsRemoved,
|
|
227
|
+
sectionsModified,
|
|
228
|
+
riskScoreDelta,
|
|
229
|
+
changelog,
|
|
230
|
+
recommendation,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
// ============================================================================
|
|
234
|
+
// Format (for CLI / text output)
|
|
235
|
+
// ============================================================================
|
|
236
|
+
/**
|
|
237
|
+
* Format a SkillDiffResponse as human-readable text
|
|
238
|
+
*/
|
|
239
|
+
export function formatSkillDiffResults(response) {
|
|
240
|
+
const lines = [];
|
|
241
|
+
lines.push(`\n=== Skill Diff: ${response.skill} ===\n`);
|
|
242
|
+
lines.push(`Change type: ${response.changeType.toUpperCase()}`);
|
|
243
|
+
lines.push(`Recommendation: ${response.recommendation}`);
|
|
244
|
+
if (response.riskScoreDelta !== null) {
|
|
245
|
+
const prefix = response.riskScoreDelta > 0 ? '+' : '';
|
|
246
|
+
lines.push(`Risk score delta: ${prefix}${response.riskScoreDelta}`);
|
|
247
|
+
}
|
|
248
|
+
if (response.sectionsAdded.length > 0) {
|
|
249
|
+
lines.push('\nSections added:');
|
|
250
|
+
for (const s of response.sectionsAdded)
|
|
251
|
+
lines.push(` + ${s}`);
|
|
252
|
+
}
|
|
253
|
+
if (response.sectionsRemoved.length > 0) {
|
|
254
|
+
lines.push('\nSections removed:');
|
|
255
|
+
for (const s of response.sectionsRemoved)
|
|
256
|
+
lines.push(` - ${s}`);
|
|
257
|
+
}
|
|
258
|
+
if (response.sectionsModified.length > 0) {
|
|
259
|
+
lines.push('\nSections modified:');
|
|
260
|
+
for (const s of response.sectionsModified)
|
|
261
|
+
lines.push(` ~ ${s}`);
|
|
262
|
+
}
|
|
263
|
+
if (response.changelog) {
|
|
264
|
+
lines.push(`\nChangelog: ${response.changelog}`);
|
|
265
|
+
}
|
|
266
|
+
return lines.join('\n');
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=skill-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-diff.js","sourceRoot":"","sources":["../../../src/tools/skill-diff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-diff.test.d.ts","sourceRoot":"","sources":["../../../src/tools/skill-diff.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|