@skillsmith/mcp-server 0.4.1 → 0.4.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.
- 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 +213 -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 +215 -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 +11 -224
- package/dist/src/context.js.map +1 -1
- package/dist/src/context.types.d.ts +110 -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 +21 -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 +8 -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 +127 -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/get-skill.d.ts.map +1 -1
- package/dist/src/tools/get-skill.js +14 -0
- package/dist/src/tools/get-skill.js.map +1 -1
- package/dist/src/tools/index.d.ts +6 -0
- package/dist/src/tools/index.d.ts.map +1 -1
- package/dist/src/tools/index.js +6 -0
- package/dist/src/tools/index.js.map +1 -1
- package/dist/src/tools/install.d.ts +3 -35
- package/dist/src/tools/install.d.ts.map +1 -1
- package/dist/src/tools/install.helpers.d.ts.map +1 -1
- package/dist/src/tools/install.helpers.js +12 -0
- package/dist/src/tools/install.helpers.js.map +1 -1
- package/dist/src/tools/install.js +57 -86
- 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 +7 -1
- package/dist/src/tools/install.types.d.ts.map +1 -1
- 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 +1 -1
- 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 +65 -50
- 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-updates.d.ts +89 -0
- package/dist/src/tools/skill-updates.d.ts.map +1 -0
- package/dist/src/tools/skill-updates.js +111 -0
- package/dist/src/tools/skill-updates.js.map +1 -0
- package/dist/src/tools/suggest.d.ts +4 -4
- package/dist/src/tools/uninstall.d.ts +1 -1
- package/dist/src/tools/validate.helpers.d.ts.map +1 -1
- package/dist/src/tools/validate.helpers.js +31 -0
- package/dist/src/tools/validate.helpers.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/install.integration.test.js +110 -0
- package/dist/tests/integration/install.integration.test.js.map +1 -1
- package/dist/tests/integration/recommend.integration.test.js +2 -0
- package/dist/tests/integration/recommend.integration.test.js.map +1 -1
- package/dist/tests/integration/setup.d.ts +3 -1
- package/dist/tests/integration/setup.d.ts.map +1 -1
- package/dist/tests/integration/setup.js +4 -1
- package/dist/tests/integration/setup.js.map +1 -1
- package/dist/tests/performance/search-performance.test.js +10 -6
- package/dist/tests/performance/search-performance.test.js.map +1 -1
- package/dist/tests/recommend.test.js +2 -0
- package/dist/tests/recommend.test.js.map +1 -1
- package/dist/tests/unit/install-helpers.test.js +24 -0
- package/dist/tests/unit/install-helpers.test.js.map +1 -1
- package/dist/tests/unit/validate-helpers.test.js +54 -0
- package/dist/tests/unit/validate-helpers.test.js.map +1 -1
- package/package.json +2 -2
- package/server.json +2 -2
|
@@ -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
|
+
trustTier: "verified" | "community" | "experimental";
|
|
26
|
+
skillId: string;
|
|
27
|
+
oldContent: string;
|
|
28
|
+
newContent: string;
|
|
29
|
+
hasLocalModifications: boolean;
|
|
30
|
+
oldRiskScore?: number | undefined;
|
|
31
|
+
newRiskScore?: number | undefined;
|
|
32
|
+
}, {
|
|
33
|
+
skillId: string;
|
|
34
|
+
oldContent: string;
|
|
35
|
+
newContent: string;
|
|
36
|
+
trustTier?: "verified" | "community" | "experimental" | undefined;
|
|
37
|
+
oldRiskScore?: number | undefined;
|
|
38
|
+
newRiskScore?: number | undefined;
|
|
39
|
+
hasLocalModifications?: boolean | 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":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAGpE,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E,uCAAuC;AACvC,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3C,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,sDAAsD,CAAC;IAC3F,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,2BAA2B,CAAC;IACnE,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0BAA0B,CAAC;IAClE,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uCAAuC,CAAC;IACpD,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,QAAQ,EAAE;SACV,QAAQ,CAAC,uCAAuC,CAAC;IACpD,qBAAqB,EAAE,CAAC;SACrB,OAAO,EAAE;SACT,OAAO,CAAC,KAAK,CAAC;SACd,QAAQ,CAAC,6CAA6C,CAAC;IAC1D,SAAS,EAAE,CAAC;SACT,IAAI,CAAC,CAAC,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC,CAAC;SAC/C,OAAO,CAAC,WAAW,CAAC;SACpB,QAAQ,CAAC,qBAAqB,CAAC;CACnC,CAAC,CAAA;AAgBF,+EAA+E;AAC/E,oCAAoC;AACpC,+EAA+E;AAE/E,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,IAAI,EAAE,YAAqB;IAC3B,WAAW,EACT,wEAAwE;QACxE,yEAAyE;QACzE,iDAAiD;QACjD,gEAAgE;IAClE,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,OAAO,EAAE;gBACP,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,sDAAsD;aACpE;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,2BAA2B;aACzC;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,0BAA0B;aACxC;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uCAAuC;aACrD;YACD,YAAY,EAAE;gBACZ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,uCAAuC;aACrD;YACD,qBAAqB,EAAE;gBACrB,IAAI,EAAE,SAAS;gBACf,WAAW,EAAE,6CAA6C;aAC3D;YACD,SAAS,EAAE;gBACT,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,cAAc,CAAC;gBAC/C,WAAW,EAAE,qBAAqB;aACnC;SACF;QACD,QAAQ,EAAE,CAAC,SAAS,EAAE,YAAY,EAAE,YAAY,CAAC;KAClD;CACF,CAAA;AAED,+EAA+E;AAC/E,mEAAmE;AACnE,+EAA+E;AAE/E,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;IAC1C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,MAAM,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,CAAC,EAAE,CAAC;YACN,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;YACzB,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,CAAC,CAAA;QAC1C,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;GAGG;AACH,SAAS,gBAAgB,CAAC,OAAe;IACvC,sCAAsC;IACtC,MAAM,OAAO,GAAG,6BAA6B,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IAC3D,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YAClC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;gBACpB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;gBACxD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;gBAC7C,IAAI,GAAG,KAAK,WAAW,IAAI,KAAK;oBAAE,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAA;YAC5E,CAAC;QACH,CAAC;IACH,CAAC;IAED,iDAAiD;IACjD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,MAAM,YAAY,GAAa,EAAE,CAAA;IAEjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5C,SAAS,GAAG,IAAI,CAAA;YAChB,SAAQ;QACV,CAAC;QACD,IAAI,SAAS,IAAI,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAK;QAC/C,IAAI,SAAS,IAAI,IAAI,CAAC,IAAI,EAAE;YAAE,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;IAC9D,CAAC;IAED,OAAO,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;AAC5E,CAAC;AAED,+EAA+E;AAC/E,0BAA0B;AAC1B,+EAA+E;AAE/E;;;GAGG;AACH,SAAS,sBAAsB,CAAC,UAAkB,EAAE,UAAkB;IACpE,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAA;IACzD,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAA;IACzD,MAAM,QAAQ,GAAa,EAAE,CAAA;IAE7B,KAAK,MAAM,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,gBAAgB,EAAE,CAAC;QAC9C,MAAM,OAAO,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;YACjD,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACpB,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC;AAED,qDAAqD;AACrD,SAAS,oBAAoB,CAAC,OAAe;IAC3C,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAA;IACxC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,IAAI,cAAc,GAAkB,IAAI,CAAA;IACxC,MAAM,SAAS,GAAa,EAAE,CAAA;IAE9B,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YAC5B,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;YACvD,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA;QACtB,CAAC;IACH,CAAC,CAAA;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,CAAC,EAAE,CAAC;YACN,KAAK,EAAE,CAAA;YACP,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC5C,CAAC;aAAM,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YACnC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACtB,CAAC;IACH,CAAC;IACD,KAAK,EAAE,CAAA;IACP,OAAO,MAAM,CAAA;AACf,CAAC;AAED,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAqB,EACrB,QAAqB;IAErB,MAAM,SAAS,GAAG,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,EACJ,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,qBAAqB,EACrB,SAAS,GACV,GAAG,SAAS,CAAA;IAEb,mBAAmB;IACnB,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;IAC/C,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAA;IAE/C,MAAM,eAAe,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IAClG,MAAM,aAAa,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAA;IAChG,MAAM,gBAAgB,GAAG,sBAAsB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IAEvE,wBAAwB;IACxB,MAAM,UAAU,GAAG,cAAc,CAAC,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,CAAC,CAAA;IAErF,eAAe;IACf,MAAM,cAAc,GAClB,OAAO,YAAY,KAAK,QAAQ,IAAI,OAAO,YAAY,KAAK,QAAQ;QAClE,CAAC,CAAC,YAAY,GAAG,YAAY;QAC7B,CAAC,CAAC,IAAI,CAAA;IAEV,MAAM,EAAE,cAAc,EAAE,GAAG,iBAAiB,CAAC;QAC3C,UAAU;QACV,cAAc,EAAE,cAAc,IAAI,SAAS;QAC3C,qBAAqB;QACrB,SAAS;QACT,YAAY,EAAE,gBAAgB,CAAC,UAAU,CAAC,KAAK,IAAI;KACpD,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC,CAAA;IAE9C,OAAO;QACL,KAAK,EAAE,OAAO;QACd,UAAU;QACV,aAAa;QACb,eAAe;QACf,gBAAgB;QAChB,cAAc;QACd,SAAS;QACT,cAAc;KACf,CAAA;AACH,CAAC;AAED,+EAA+E;AAC/E,iCAAiC;AACjC,+EAA+E;AAE/E;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,QAA2B;IAChE,MAAM,KAAK,GAAa,EAAE,CAAA;IAE1B,KAAK,CAAC,IAAI,CAAC,qBAAqB,QAAQ,CAAC,KAAK,QAAQ,CAAC,CAAA;IACvD,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC,CAAA;IAC/D,KAAK,CAAC,IAAI,CAAC,mBAAmB,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAA;IAExD,IAAI,QAAQ,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,cAAc,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;QACrD,KAAK,CAAC,IAAI,CAAC,qBAAqB,MAAM,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAA;IACrE,CAAC;IAED,IAAI,QAAQ,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAA;QAC/B,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,aAAa;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,IAAI,QAAQ,CAAC,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxC,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAA;QACjC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,eAAe;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IAClE,CAAC;IAED,IAAI,QAAQ,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAA;QAClC,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,gBAAgB;YAAE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAA;IACnE,CAAC;IAED,IAAI,QAAQ,CAAC,SAAS,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC,SAAS,EAAE,CAAC,CAAA;IAClD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-diff.test.d.ts","sourceRoot":"","sources":["../../../src/tools/skill-diff.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for skill-diff.ts MCP tool
|
|
3
|
+
* @see SMI-skill-version-tracking Wave 2
|
|
4
|
+
*/
|
|
5
|
+
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
6
|
+
import { executeSkillDiff, skillDiffInputSchema } from './skill-diff.js';
|
|
7
|
+
// ============================================================================
|
|
8
|
+
// Mock context
|
|
9
|
+
// ============================================================================
|
|
10
|
+
const mockContext = {};
|
|
11
|
+
// ============================================================================
|
|
12
|
+
// Fixtures
|
|
13
|
+
// ============================================================================
|
|
14
|
+
const OLD_CONTENT = `---
|
|
15
|
+
name: test-skill
|
|
16
|
+
version: 1.0.0
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Overview
|
|
20
|
+
|
|
21
|
+
A test skill.
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
Run with /test.
|
|
26
|
+
|
|
27
|
+
## Configuration
|
|
28
|
+
|
|
29
|
+
Set env vars.
|
|
30
|
+
`;
|
|
31
|
+
const NEW_CONTENT_MINOR = `---
|
|
32
|
+
name: test-skill
|
|
33
|
+
version: 1.1.0
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Overview
|
|
37
|
+
|
|
38
|
+
A test skill.
|
|
39
|
+
|
|
40
|
+
## Usage
|
|
41
|
+
|
|
42
|
+
Run with /test.
|
|
43
|
+
|
|
44
|
+
## Configuration
|
|
45
|
+
|
|
46
|
+
Set env vars.
|
|
47
|
+
|
|
48
|
+
## Examples
|
|
49
|
+
|
|
50
|
+
Here are some examples.
|
|
51
|
+
`;
|
|
52
|
+
const NEW_CONTENT_MAJOR = `---
|
|
53
|
+
name: test-skill
|
|
54
|
+
version: 2.0.0
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Overview
|
|
58
|
+
|
|
59
|
+
A test skill.
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
Run with /test.
|
|
64
|
+
`;
|
|
65
|
+
const NEW_CONTENT_PATCH = `---
|
|
66
|
+
name: test-skill
|
|
67
|
+
version: 1.0.1
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Overview
|
|
71
|
+
|
|
72
|
+
An updated test skill.
|
|
73
|
+
|
|
74
|
+
## Usage
|
|
75
|
+
|
|
76
|
+
Run with /test now.
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
Updated env vars.
|
|
81
|
+
`;
|
|
82
|
+
const NEW_CONTENT_WITH_CHANGELOG = `---
|
|
83
|
+
name: test-skill
|
|
84
|
+
version: 1.0.1
|
|
85
|
+
changelog: "Fixed a bug in configuration handling"
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Overview
|
|
89
|
+
|
|
90
|
+
An updated test skill.
|
|
91
|
+
|
|
92
|
+
## Usage
|
|
93
|
+
|
|
94
|
+
Run with /test.
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
Updated env vars.
|
|
99
|
+
`;
|
|
100
|
+
// ============================================================================
|
|
101
|
+
// Tests
|
|
102
|
+
// ============================================================================
|
|
103
|
+
describe('executeSkillDiff', () => {
|
|
104
|
+
beforeEach(() => {
|
|
105
|
+
vi.clearAllMocks();
|
|
106
|
+
});
|
|
107
|
+
describe('SkillDiffResponse schema', () => {
|
|
108
|
+
it('returns a valid SkillDiffResponse for a minor update', async () => {
|
|
109
|
+
const result = await executeSkillDiff({
|
|
110
|
+
skillId: 'anthropic/test-skill',
|
|
111
|
+
oldContent: OLD_CONTENT,
|
|
112
|
+
newContent: NEW_CONTENT_MINOR,
|
|
113
|
+
hasLocalModifications: false,
|
|
114
|
+
trustTier: 'community',
|
|
115
|
+
}, mockContext);
|
|
116
|
+
// Verify all required fields are present
|
|
117
|
+
expect(result).toHaveProperty('skill', 'anthropic/test-skill');
|
|
118
|
+
expect(result).toHaveProperty('changeType');
|
|
119
|
+
expect(result).toHaveProperty('sectionsAdded');
|
|
120
|
+
expect(result).toHaveProperty('sectionsRemoved');
|
|
121
|
+
expect(result).toHaveProperty('sectionsModified');
|
|
122
|
+
expect(result).toHaveProperty('riskScoreDelta');
|
|
123
|
+
expect(result).toHaveProperty('changelog');
|
|
124
|
+
expect(result).toHaveProperty('recommendation');
|
|
125
|
+
// Type assertions
|
|
126
|
+
expect(['major', 'minor', 'patch', 'unknown']).toContain(result.changeType);
|
|
127
|
+
expect(Array.isArray(result.sectionsAdded)).toBe(true);
|
|
128
|
+
expect(Array.isArray(result.sectionsRemoved)).toBe(true);
|
|
129
|
+
expect(Array.isArray(result.sectionsModified)).toBe(true);
|
|
130
|
+
expect(['auto-update', 'review-then-update', 'manual-review-required']).toContain(result.recommendation);
|
|
131
|
+
});
|
|
132
|
+
it('detects added sections correctly', async () => {
|
|
133
|
+
const result = await executeSkillDiff({
|
|
134
|
+
skillId: 'test/skill',
|
|
135
|
+
oldContent: OLD_CONTENT,
|
|
136
|
+
newContent: NEW_CONTENT_MINOR,
|
|
137
|
+
hasLocalModifications: false,
|
|
138
|
+
trustTier: 'community',
|
|
139
|
+
}, mockContext);
|
|
140
|
+
expect(result.sectionsAdded).toContain('Examples');
|
|
141
|
+
expect(result.sectionsRemoved).toHaveLength(0);
|
|
142
|
+
});
|
|
143
|
+
it('detects removed sections correctly', async () => {
|
|
144
|
+
const result = await executeSkillDiff({
|
|
145
|
+
skillId: 'test/skill',
|
|
146
|
+
oldContent: OLD_CONTENT,
|
|
147
|
+
newContent: NEW_CONTENT_MAJOR,
|
|
148
|
+
hasLocalModifications: false,
|
|
149
|
+
trustTier: 'community',
|
|
150
|
+
}, mockContext);
|
|
151
|
+
expect(result.sectionsRemoved).toContain('Configuration');
|
|
152
|
+
expect(result.sectionsAdded).toHaveLength(0);
|
|
153
|
+
});
|
|
154
|
+
it('detects modified sections correctly', async () => {
|
|
155
|
+
const result = await executeSkillDiff({
|
|
156
|
+
skillId: 'test/skill',
|
|
157
|
+
oldContent: OLD_CONTENT,
|
|
158
|
+
newContent: NEW_CONTENT_PATCH,
|
|
159
|
+
hasLocalModifications: false,
|
|
160
|
+
trustTier: 'community',
|
|
161
|
+
}, mockContext);
|
|
162
|
+
// Body text changed but no headings added/removed
|
|
163
|
+
expect(result.sectionsRemoved).toHaveLength(0);
|
|
164
|
+
expect(result.sectionsAdded).toHaveLength(0);
|
|
165
|
+
expect(result.sectionsModified.length).toBeGreaterThan(0);
|
|
166
|
+
});
|
|
167
|
+
it('returns riskScoreDelta when scores are provided', async () => {
|
|
168
|
+
const result = await executeSkillDiff({
|
|
169
|
+
skillId: 'test/skill',
|
|
170
|
+
oldContent: OLD_CONTENT,
|
|
171
|
+
newContent: NEW_CONTENT_PATCH,
|
|
172
|
+
oldRiskScore: 10,
|
|
173
|
+
newRiskScore: 30,
|
|
174
|
+
hasLocalModifications: false,
|
|
175
|
+
trustTier: 'community',
|
|
176
|
+
}, mockContext);
|
|
177
|
+
expect(result.riskScoreDelta).toBe(20);
|
|
178
|
+
});
|
|
179
|
+
it('returns null riskScoreDelta when scores are not provided', async () => {
|
|
180
|
+
const result = await executeSkillDiff({
|
|
181
|
+
skillId: 'test/skill',
|
|
182
|
+
oldContent: OLD_CONTENT,
|
|
183
|
+
newContent: NEW_CONTENT_PATCH,
|
|
184
|
+
hasLocalModifications: false,
|
|
185
|
+
trustTier: 'community',
|
|
186
|
+
}, mockContext);
|
|
187
|
+
expect(result.riskScoreDelta).toBeNull();
|
|
188
|
+
});
|
|
189
|
+
it('extracts changelog from frontmatter', async () => {
|
|
190
|
+
const result = await executeSkillDiff({
|
|
191
|
+
skillId: 'test/skill',
|
|
192
|
+
oldContent: OLD_CONTENT,
|
|
193
|
+
newContent: NEW_CONTENT_WITH_CHANGELOG,
|
|
194
|
+
hasLocalModifications: false,
|
|
195
|
+
trustTier: 'community',
|
|
196
|
+
}, mockContext);
|
|
197
|
+
expect(result.changelog).toContain('Fixed a bug');
|
|
198
|
+
});
|
|
199
|
+
it('returns null changelog when none present', async () => {
|
|
200
|
+
const result = await executeSkillDiff({
|
|
201
|
+
skillId: 'test/skill',
|
|
202
|
+
oldContent: OLD_CONTENT,
|
|
203
|
+
newContent: NEW_CONTENT_PATCH,
|
|
204
|
+
hasLocalModifications: false,
|
|
205
|
+
trustTier: 'community',
|
|
206
|
+
}, mockContext);
|
|
207
|
+
expect(result.changelog).toBeNull();
|
|
208
|
+
});
|
|
209
|
+
});
|
|
210
|
+
describe('recommendation based on changeType', () => {
|
|
211
|
+
it('returns auto-update for patch + verified + changelog', async () => {
|
|
212
|
+
const result = await executeSkillDiff({
|
|
213
|
+
skillId: 'test/skill',
|
|
214
|
+
oldContent: OLD_CONTENT,
|
|
215
|
+
newContent: NEW_CONTENT_WITH_CHANGELOG,
|
|
216
|
+
hasLocalModifications: false,
|
|
217
|
+
trustTier: 'verified',
|
|
218
|
+
}, mockContext);
|
|
219
|
+
expect(result.recommendation).toBe('auto-update');
|
|
220
|
+
});
|
|
221
|
+
it('returns manual-review-required for major + local mods + risk increase', async () => {
|
|
222
|
+
const result = await executeSkillDiff({
|
|
223
|
+
skillId: 'test/skill',
|
|
224
|
+
oldContent: OLD_CONTENT,
|
|
225
|
+
newContent: NEW_CONTENT_MAJOR,
|
|
226
|
+
oldRiskScore: 10,
|
|
227
|
+
newRiskScore: 60,
|
|
228
|
+
hasLocalModifications: true,
|
|
229
|
+
trustTier: 'community',
|
|
230
|
+
}, mockContext);
|
|
231
|
+
expect(result.recommendation).toBe('manual-review-required');
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
describe('input validation', () => {
|
|
235
|
+
it('rejects empty skillId', () => {
|
|
236
|
+
expect(() => skillDiffInputSchema.parse({
|
|
237
|
+
skillId: '',
|
|
238
|
+
oldContent: 'old',
|
|
239
|
+
newContent: 'new',
|
|
240
|
+
})).toThrow();
|
|
241
|
+
});
|
|
242
|
+
it('rejects empty oldContent', () => {
|
|
243
|
+
expect(() => skillDiffInputSchema.parse({
|
|
244
|
+
skillId: 'test/skill',
|
|
245
|
+
oldContent: '',
|
|
246
|
+
newContent: 'new',
|
|
247
|
+
})).toThrow();
|
|
248
|
+
});
|
|
249
|
+
it('accepts optional fields', () => {
|
|
250
|
+
const parsed = skillDiffInputSchema.parse({
|
|
251
|
+
skillId: 'test/skill',
|
|
252
|
+
oldContent: 'old content',
|
|
253
|
+
newContent: 'new content',
|
|
254
|
+
});
|
|
255
|
+
expect(parsed.hasLocalModifications).toBe(false);
|
|
256
|
+
expect(parsed.trustTier).toBe('community');
|
|
257
|
+
});
|
|
258
|
+
});
|
|
259
|
+
});
|
|
260
|
+
//# sourceMappingURL=skill-diff.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-diff.test.js","sourceRoot":"","sources":["../../../src/tools/skill-diff.test.ts"],"names":[],"mappings":"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"}
|