@skillsmith/mcp-server 0.4.11 → 0.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/README.md +44 -0
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/__tests__/search.test.js +8 -0
  5. package/dist/src/__tests__/search.test.js.map +1 -1
  6. package/dist/src/__tests__/tool-dispatch.envelope.test.d.ts +12 -0
  7. package/dist/src/__tests__/tool-dispatch.envelope.test.d.ts.map +1 -0
  8. package/dist/src/__tests__/tool-dispatch.envelope.test.js +205 -0
  9. package/dist/src/__tests__/tool-dispatch.envelope.test.js.map +1 -0
  10. package/dist/src/__tests__/utils/validation.test.js +7 -0
  11. package/dist/src/__tests__/utils/validation.test.js.map +1 -1
  12. package/dist/src/context.async.d.ts.map +1 -1
  13. package/dist/src/context.async.js +22 -1
  14. package/dist/src/context.async.js.map +1 -1
  15. package/dist/src/index.js +10 -1
  16. package/dist/src/index.js.map +1 -1
  17. package/dist/src/middleware/__tests__/license.gate.test.d.ts +2 -0
  18. package/dist/src/middleware/__tests__/license.gate.test.d.ts.map +1 -0
  19. package/dist/src/middleware/__tests__/license.gate.test.js +74 -0
  20. package/dist/src/middleware/__tests__/license.gate.test.js.map +1 -0
  21. package/dist/src/middleware/license.d.ts +1 -23
  22. package/dist/src/middleware/license.d.ts.map +1 -1
  23. package/dist/src/middleware/license.gate.d.ts +23 -0
  24. package/dist/src/middleware/license.gate.d.ts.map +1 -0
  25. package/dist/src/middleware/license.gate.js +59 -0
  26. package/dist/src/middleware/license.gate.js.map +1 -0
  27. package/dist/src/middleware/license.js +2 -28
  28. package/dist/src/middleware/license.js.map +1 -1
  29. package/dist/src/tool-dispatch.d.ts.map +1 -1
  30. package/dist/src/tool-dispatch.js +58 -19
  31. package/dist/src/tool-dispatch.js.map +1 -1
  32. package/dist/src/tools/compare.types.d.ts +1 -0
  33. package/dist/src/tools/compare.types.d.ts.map +1 -1
  34. package/dist/src/tools/compare.types.js +2 -0
  35. package/dist/src/tools/compare.types.js.map +1 -1
  36. package/dist/src/tools/compliance-tools.d.ts +1 -1
  37. package/dist/src/tools/compliance-tools.d.ts.map +1 -1
  38. package/dist/src/tools/get-skill.js +3 -0
  39. package/dist/src/tools/get-skill.js.map +1 -1
  40. package/dist/src/tools/install.d.ts +9 -3
  41. package/dist/src/tools/install.d.ts.map +1 -1
  42. package/dist/src/tools/install.js +52 -11
  43. package/dist/src/tools/install.js.map +1 -1
  44. package/dist/src/tools/install.test.d.ts +17 -0
  45. package/dist/src/tools/install.test.d.ts.map +1 -0
  46. package/dist/src/tools/install.test.js +237 -0
  47. package/dist/src/tools/install.test.js.map +1 -0
  48. package/dist/src/tools/integration-tools.service.d.ts.map +1 -1
  49. package/dist/src/tools/integration-tools.service.hash.test.d.ts +10 -0
  50. package/dist/src/tools/integration-tools.service.hash.test.d.ts.map +1 -0
  51. package/dist/src/tools/integration-tools.service.hash.test.js +48 -0
  52. package/dist/src/tools/integration-tools.service.hash.test.js.map +1 -0
  53. package/dist/src/tools/integration-tools.service.js +22 -2
  54. package/dist/src/tools/integration-tools.service.js.map +1 -1
  55. package/dist/src/tools/integration-tools.service.test.js +17 -14
  56. package/dist/src/tools/integration-tools.service.test.js.map +1 -1
  57. package/dist/src/tools/integration-tools.stub.d.ts.map +1 -1
  58. package/dist/src/tools/integration-tools.stub.js +3 -5
  59. package/dist/src/tools/integration-tools.stub.js.map +1 -1
  60. package/dist/src/tools/registry-tools.d.ts.map +1 -1
  61. package/dist/src/tools/registry-tools.js +42 -4
  62. package/dist/src/tools/registry-tools.js.map +1 -1
  63. package/dist/src/tools/search.d.ts +1 -1
  64. package/dist/src/tools/search.d.ts.map +1 -1
  65. package/dist/src/tools/search.js +4 -4
  66. package/dist/src/tools/search.js.map +1 -1
  67. package/dist/src/tools/team-resolver.d.ts +29 -0
  68. package/dist/src/tools/team-resolver.d.ts.map +1 -0
  69. package/dist/src/tools/team-resolver.js +46 -0
  70. package/dist/src/tools/team-resolver.js.map +1 -0
  71. package/dist/src/tools/team-resolver.test.d.ts +6 -0
  72. package/dist/src/tools/team-resolver.test.d.ts.map +1 -0
  73. package/dist/src/tools/team-resolver.test.js +73 -0
  74. package/dist/src/tools/team-resolver.test.js.map +1 -0
  75. package/dist/src/tools/team-workspace.d.ts +14 -0
  76. package/dist/src/tools/team-workspace.d.ts.map +1 -1
  77. package/dist/src/tools/team-workspace.js +149 -75
  78. package/dist/src/tools/team-workspace.js.map +1 -1
  79. package/dist/src/tools/team-workspace.live.d.ts +34 -0
  80. package/dist/src/tools/team-workspace.live.d.ts.map +1 -0
  81. package/dist/src/tools/team-workspace.live.js +182 -0
  82. package/dist/src/tools/team-workspace.live.js.map +1 -0
  83. package/dist/src/tools/team-workspace.live.test.d.ts +10 -0
  84. package/dist/src/tools/team-workspace.live.test.d.ts.map +1 -0
  85. package/dist/src/tools/team-workspace.live.test.js +177 -0
  86. package/dist/src/tools/team-workspace.live.test.js.map +1 -0
  87. package/dist/src/tools/team-workspace.stub.d.ts.map +1 -1
  88. package/dist/src/tools/team-workspace.stub.js +3 -1
  89. package/dist/src/tools/team-workspace.stub.js.map +1 -1
  90. package/dist/src/tools/team-workspace.test.d.ts +1 -0
  91. package/dist/src/tools/team-workspace.test.d.ts.map +1 -1
  92. package/dist/src/tools/team-workspace.test.js +43 -1
  93. package/dist/src/tools/team-workspace.test.js.map +1 -1
  94. package/dist/src/utils/validation.d.ts +4 -2
  95. package/dist/src/utils/validation.d.ts.map +1 -1
  96. package/dist/src/utils/validation.js +9 -2
  97. package/dist/src/utils/validation.js.map +1 -1
  98. package/dist/src/validation.d.ts +64 -0
  99. package/dist/src/validation.d.ts.map +1 -0
  100. package/dist/src/validation.js +73 -0
  101. package/dist/src/validation.js.map +1 -0
  102. package/dist/src/validation.test.d.ts +6 -0
  103. package/dist/src/validation.test.d.ts.map +1 -0
  104. package/dist/src/validation.test.js +102 -0
  105. package/dist/src/validation.test.js.map +1 -0
  106. package/package.json +3 -3
  107. package/server.json +3 -7
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { SkillInstallationService, emitInstallEvent, } from '@skillsmith/core';
17
17
  import { getToolContext } from '../context.js';
18
+ import { installInputSchema } from './install.types.js';
18
19
  import { loadManifest, lookupSkillFromRegistry } from './install.helpers.js';
19
20
  // SMI-1867: Conflict resolution logic (extracted per governance review)
20
21
  import { checkForConflicts } from './install.conflict.js';
@@ -36,17 +37,57 @@ class McpRegistryLookup {
36
37
  return lookupSkillFromRegistry(skillId, this.context);
37
38
  }
38
39
  }
40
+ /**
41
+ * Build an application-level validation failure result.
42
+ *
43
+ * SMI-4288 / GitHub #599: When an MCP caller passes a malformed argument
44
+ * payload (e.g. `{}`, wrong `skillId` type, invalid `conflictAction` enum),
45
+ * return a structured `InstallResult` with `success: false` rather than
46
+ * throwing. Matches the existing `team-workspace.ts` error-envelope
47
+ * convention (application-level failure, not MCP protocol-level `isError`).
48
+ *
49
+ * @see #599
50
+ */
51
+ function buildValidationError(message) {
52
+ return {
53
+ success: false,
54
+ skillId: '',
55
+ installPath: '',
56
+ error: `Invalid install input: ${message}`,
57
+ };
58
+ }
39
59
  /**
40
60
  * Install a skill from GitHub to the local Claude Code skills directory.
41
61
  *
42
62
  * Delegates core logic to SkillInstallationService from @skillsmith/core.
43
63
  * Adds MCP-specific conflict resolution (three-way merge, backup).
44
64
  *
45
- * @param input - Installation parameters (skillId, force, skipScan)
65
+ * SMI-4288 / GitHub #599: Signature accepts `unknown` so the Zod `safeParse`
66
+ * guard actually runs at the MCP tool boundary. The prior `InstallInput`
67
+ * parameter type made the guard unreachable — callers passed a pre-typed
68
+ * object, leaving the underlying `request.params.arguments` crash surface
69
+ * unprotected when the dispatcher forwards raw args.
70
+ *
71
+ * @param input - Raw MCP tool arguments (unvalidated); parsed via Zod here
46
72
  * @param _context - Optional tool context (falls back to singleton)
47
73
  * @returns Installation result with success status, security report, and dep intel
48
74
  */
49
75
  export async function installSkill(input, _context) {
76
+ // SMI-4288 / #599: Zod validation boundary. Unlike the previous typed
77
+ // signature, this runs at every call site (tool-dispatch, runFirstTimeSetup,
78
+ // integration tests). Validation failures return a structured InstallResult
79
+ // instead of throwing, preserving the MCP application-level error envelope.
80
+ const parsed = installInputSchema.safeParse(input);
81
+ if (!parsed.success) {
82
+ const message = parsed.error.issues
83
+ .map((issue) => {
84
+ const path = issue.path.length > 0 ? issue.path.join('.') : '<root>';
85
+ return `${path}: ${issue.message}`;
86
+ })
87
+ .join('; ');
88
+ return buildValidationError(message);
89
+ }
90
+ const validInput = parsed.data;
50
91
  const context = _context ?? getToolContext();
51
92
  // SMI-3483: Create core service instance with MCP context wiring
52
93
  // SMI-3873: aiDefenceFeedback omitted -- MCP server cannot call Ruflo tools.
@@ -60,13 +101,13 @@ export async function installSkill(input, _context) {
60
101
  });
61
102
  // SMI-1867: Pre-flight conflict check for reinstall with force
62
103
  // This is MCP-specific (three-way merge UI, backup, storeOriginal)
63
- if (input.force && input.conflictAction) {
104
+ if (validInput.force && validInput.conflictAction) {
64
105
  try {
65
106
  const manifest = await loadManifest();
66
- const skillName = extractSkillName(input.skillId);
107
+ const skillName = extractSkillName(validInput.skillId);
67
108
  if (manifest.installedSkills[skillName]) {
68
109
  const installPath = manifest.installedSkills[skillName].installPath;
69
- const conflictCheck = await checkForConflicts(skillName, installPath, manifest, input.conflictAction, input.skillId);
110
+ const conflictCheck = await checkForConflicts(skillName, installPath, manifest, validInput.conflictAction, validInput.skillId);
70
111
  if (!conflictCheck.shouldProceed) {
71
112
  return conflictCheck.earlyReturn;
72
113
  }
@@ -78,16 +119,16 @@ export async function installSkill(input, _context) {
78
119
  }
79
120
  // Delegate to core service
80
121
  const installStart = Date.now();
81
- const result = await service.install(input.skillId, {
82
- force: input.force,
83
- skipScan: input.skipScan,
84
- skipOptimize: input.skipOptimize,
85
- conflictAction: input.conflictAction,
86
- confirmed: input.confirmed,
122
+ const result = await service.install(validInput.skillId, {
123
+ force: validInput.force,
124
+ skipScan: validInput.skipScan,
125
+ skipOptimize: validInput.skipOptimize,
126
+ conflictAction: validInput.conflictAction,
127
+ confirmed: validInput.confirmed,
87
128
  });
88
129
  // SMI-4182: fire-and-forget install telemetry for usage report funnel
89
130
  void emitInstallEvent({
90
- skillId: input.skillId,
131
+ skillId: validInput.skillId,
91
132
  source: 'mcp',
92
133
  success: result.success,
93
134
  durationMs: Date.now() - installStart,
@@ -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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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * @fileoverview Unit tests for install_skill MCP tool Zod boundary guard
3
+ * @see SMI-4288: Zod validation guard at MCP tool boundary
4
+ * @see https://github.com/smith-horn/skillsmith/issues/599
5
+ *
6
+ * These tests cover the behaviour introduced by the signature change from
7
+ * `installSkill(input: InstallInput, ...)` to `installSkill(input: unknown, ...)`.
8
+ * The guard protects against malformed MCP payloads (e.g. `{}`,
9
+ * `{ skillId: 123 }`, invalid enum) reaching the core installation service.
10
+ *
11
+ * The happy path mocks `@skillsmith/core` so no real filesystem or network
12
+ * work happens — this file is a unit test for the tool-boundary validation
13
+ * shim, not an integration test for the install flow itself (that lives
14
+ * in `tests/integration/install.integration.test.ts`).
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=install.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.test.d.ts","sourceRoot":"","sources":["../../../src/tools/install.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * @fileoverview Unit tests for install_skill MCP tool Zod boundary guard
3
+ * @see SMI-4288: Zod validation guard at MCP tool boundary
4
+ * @see https://github.com/smith-horn/skillsmith/issues/599
5
+ *
6
+ * These tests cover the behaviour introduced by the signature change from
7
+ * `installSkill(input: InstallInput, ...)` to `installSkill(input: unknown, ...)`.
8
+ * The guard protects against malformed MCP payloads (e.g. `{}`,
9
+ * `{ skillId: 123 }`, invalid enum) reaching the core installation service.
10
+ *
11
+ * The happy path mocks `@skillsmith/core` so no real filesystem or network
12
+ * work happens — this file is a unit test for the tool-boundary validation
13
+ * shim, not an integration test for the install flow itself (that lives
14
+ * in `tests/integration/install.integration.test.ts`).
15
+ */
16
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
17
+ // SMI-4288: Mock the core service so the happy-path test exercises only the
18
+ // Zod gate + delegation. `vi.hoisted` is required because `vi.mock` is
19
+ // hoisted above regular `const` declarations and would otherwise reference
20
+ // the stubs before they are initialised.
21
+ const { mockInstall, mockEmitInstallEvent } = vi.hoisted(() => ({
22
+ mockInstall: vi.fn(),
23
+ mockEmitInstallEvent: vi.fn(),
24
+ }));
25
+ vi.mock('@skillsmith/core', async (importActual) => {
26
+ const actual = await importActual();
27
+ class MockSkillInstallationService {
28
+ install = mockInstall;
29
+ }
30
+ return {
31
+ ...actual,
32
+ SkillInstallationService: MockSkillInstallationService,
33
+ emitInstallEvent: mockEmitInstallEvent,
34
+ };
35
+ });
36
+ // Prevent getToolContext() from throwing when no context is passed — the
37
+ // installSkill helper calls it before delegating. A minimal stub is enough
38
+ // because the mocked SkillInstallationService ignores the params.
39
+ vi.mock('../context.js', () => ({
40
+ getToolContext: vi.fn().mockReturnValue({
41
+ db: {},
42
+ skillRepository: {},
43
+ skillDependencyRepository: {},
44
+ coInstallRepository: undefined,
45
+ sessionInstalledSkillIds: [],
46
+ }),
47
+ }));
48
+ // SMI-4288: Mock install.helpers so the conflict-preflight path exercises
49
+ // deterministic behaviour. Each test configures loadManifest explicitly.
50
+ const { mockLoadManifest, mockLookupSkillFromRegistry } = vi.hoisted(() => ({
51
+ mockLoadManifest: vi.fn(),
52
+ mockLookupSkillFromRegistry: vi.fn(),
53
+ }));
54
+ vi.mock('./install.helpers.js', () => ({
55
+ loadManifest: mockLoadManifest,
56
+ lookupSkillFromRegistry: mockLookupSkillFromRegistry,
57
+ }));
58
+ // Conflict check helper — return a shouldProceed:true stub so the flow
59
+ // falls through to the core service unless a test overrides.
60
+ const { mockCheckForConflicts } = vi.hoisted(() => ({
61
+ mockCheckForConflicts: vi.fn(),
62
+ }));
63
+ vi.mock('./install.conflict.js', () => ({
64
+ checkForConflicts: mockCheckForConflicts,
65
+ }));
66
+ import { installSkill } from './install.js';
67
+ const HAPPY_RESULT = {
68
+ success: true,
69
+ skillId: 'owner/repo/test-skill',
70
+ installPath: '/tmp/mock/test-skill',
71
+ };
72
+ describe('installSkill() Zod boundary guard (SMI-4288 / #599)', () => {
73
+ beforeEach(() => {
74
+ mockInstall.mockReset();
75
+ mockEmitInstallEvent.mockReset();
76
+ mockLoadManifest.mockReset();
77
+ mockLookupSkillFromRegistry.mockReset();
78
+ mockCheckForConflicts.mockReset();
79
+ mockInstall.mockResolvedValue(HAPPY_RESULT);
80
+ // By default no conflict preflight interception.
81
+ mockLoadManifest.mockResolvedValue({ version: '1', installedSkills: {} });
82
+ mockCheckForConflicts.mockResolvedValue({ shouldProceed: true });
83
+ });
84
+ afterEach(() => {
85
+ vi.clearAllMocks();
86
+ });
87
+ describe('happy path', () => {
88
+ it('delegates a valid InstallInput to SkillInstallationService.install', async () => {
89
+ const result = await installSkill({
90
+ skillId: 'owner/repo/test-skill',
91
+ force: false,
92
+ skipScan: true,
93
+ skipOptimize: true,
94
+ confirmed: true,
95
+ });
96
+ expect(result).toEqual(HAPPY_RESULT);
97
+ expect(mockInstall).toHaveBeenCalledTimes(1);
98
+ expect(mockInstall).toHaveBeenCalledWith('owner/repo/test-skill', {
99
+ force: false,
100
+ skipScan: true,
101
+ skipOptimize: true,
102
+ conflictAction: undefined,
103
+ confirmed: true,
104
+ });
105
+ });
106
+ });
107
+ describe('validation failures return structured InstallResult', () => {
108
+ it('rejects undefined input with success: false and surfaces the Zod issue', async () => {
109
+ const result = await installSkill(undefined);
110
+ expect(result.success).toBe(false);
111
+ expect(result.skillId).toBe('');
112
+ expect(result.installPath).toBe('');
113
+ expect(result.error).toBeDefined();
114
+ expect(result.error).toContain('Invalid install input');
115
+ // Core service must never be invoked when validation fails.
116
+ expect(mockInstall).not.toHaveBeenCalled();
117
+ });
118
+ it('rejects input missing skillId', async () => {
119
+ const result = await installSkill({});
120
+ expect(result.success).toBe(false);
121
+ expect(result.error).toContain('Invalid install input');
122
+ expect(result.error).toContain('skillId');
123
+ expect(mockInstall).not.toHaveBeenCalled();
124
+ });
125
+ it('rejects input with non-string skillId', async () => {
126
+ const result = await installSkill({ skillId: 123 });
127
+ expect(result.success).toBe(false);
128
+ expect(result.error).toContain('Invalid install input');
129
+ expect(result.error).toContain('skillId');
130
+ expect(mockInstall).not.toHaveBeenCalled();
131
+ });
132
+ it('rejects input with invalid conflictAction enum value', async () => {
133
+ const result = await installSkill({
134
+ skillId: 'owner/repo/test-skill',
135
+ conflictAction: 'stomp',
136
+ });
137
+ expect(result.success).toBe(false);
138
+ expect(result.error).toContain('Invalid install input');
139
+ expect(result.error).toContain('conflictAction');
140
+ expect(mockInstall).not.toHaveBeenCalled();
141
+ });
142
+ it('rejects empty-string skillId (min(1) constraint)', async () => {
143
+ const result = await installSkill({ skillId: '' });
144
+ expect(result.success).toBe(false);
145
+ expect(result.error).toContain('Invalid install input');
146
+ expect(mockInstall).not.toHaveBeenCalled();
147
+ });
148
+ });
149
+ describe('pre-existing failure paths still work after guard', () => {
150
+ it('surfaces a service-level failure result untouched', async () => {
151
+ const serviceFailure = {
152
+ success: false,
153
+ skillId: 'owner/repo/test-skill',
154
+ installPath: '',
155
+ error: 'Skill indexed for discovery only',
156
+ };
157
+ mockInstall.mockResolvedValueOnce(serviceFailure);
158
+ const result = await installSkill({
159
+ skillId: 'owner/repo/test-skill',
160
+ skipScan: true,
161
+ });
162
+ expect(result).toEqual(serviceFailure);
163
+ expect(result.error).toBe('Skill indexed for discovery only');
164
+ });
165
+ });
166
+ describe('conflict preflight path (force + conflictAction)', () => {
167
+ it('returns the early-exit conflict result when checkForConflicts signals stop', async () => {
168
+ const conflictResult = {
169
+ success: false,
170
+ skillId: 'owner/repo/test-skill',
171
+ installPath: '/existing/path',
172
+ error: 'User cancelled due to local modifications',
173
+ };
174
+ mockLoadManifest.mockResolvedValueOnce({
175
+ version: '1',
176
+ installedSkills: {
177
+ 'test-skill': {
178
+ id: 'owner/repo/test-skill',
179
+ name: 'test-skill',
180
+ version: '1.0.0',
181
+ source: 'registry',
182
+ installPath: '/existing/path',
183
+ installedAt: '2026-01-01T00:00:00Z',
184
+ lastUpdated: '2026-01-01T00:00:00Z',
185
+ },
186
+ },
187
+ });
188
+ mockCheckForConflicts.mockResolvedValueOnce({
189
+ shouldProceed: false,
190
+ earlyReturn: conflictResult,
191
+ });
192
+ const result = await installSkill({
193
+ skillId: 'owner/repo/test-skill',
194
+ force: true,
195
+ conflictAction: 'cancel',
196
+ });
197
+ expect(result).toEqual(conflictResult);
198
+ expect(mockCheckForConflicts).toHaveBeenCalledTimes(1);
199
+ expect(mockInstall).not.toHaveBeenCalled();
200
+ });
201
+ it('falls through to core install when manifest lookup throws', async () => {
202
+ // Conflict preflight swallows errors and continues with normal install.
203
+ mockLoadManifest.mockRejectedValueOnce(new Error('manifest missing'));
204
+ const result = await installSkill({
205
+ skillId: 'owner/repo/test-skill',
206
+ force: true,
207
+ conflictAction: 'overwrite',
208
+ });
209
+ expect(result).toEqual(HAPPY_RESULT);
210
+ expect(mockInstall).toHaveBeenCalledTimes(1);
211
+ });
212
+ it('resolves bare skillId (no slash) via extractSkillName', async () => {
213
+ mockLoadManifest.mockResolvedValueOnce({
214
+ version: '1',
215
+ installedSkills: {
216
+ 'bare-name': {
217
+ id: 'bare-name',
218
+ name: 'bare-name',
219
+ version: '1.0.0',
220
+ source: 'registry',
221
+ installPath: '/x',
222
+ installedAt: '2026-01-01T00:00:00Z',
223
+ lastUpdated: '2026-01-01T00:00:00Z',
224
+ },
225
+ },
226
+ });
227
+ const result = await installSkill({
228
+ skillId: 'bare-name',
229
+ force: true,
230
+ conflictAction: 'overwrite',
231
+ });
232
+ expect(result).toEqual(HAPPY_RESULT);
233
+ expect(mockCheckForConflicts).toHaveBeenCalledWith('bare-name', '/x', expect.objectContaining({ installedSkills: expect.any(Object) }), 'overwrite', 'bare-name');
234
+ });
235
+ });
236
+ });
237
+ //# sourceMappingURL=install.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.test.js","sourceRoot":"","sources":["../../../src/tools/install.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"integration-tools.service.d.ts","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAA+B,MAAM,wBAAwB,CAAA;AAM7F,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAA;IACzC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;CACjF;AAED,UAAU,oBAAoB;IAC5B,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,oBAAoB,CAAA;IAC1D,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,oBAAoB,CAAA;IAC1D,MAAM,IAAI,oBAAoB,CAAA;IAC9B,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAAA;IAC9C,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAAA;IACxD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,oBAAoB,CAAA;IACrD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,oBAAoB,CAAA;IAC9E,MAAM,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI,CAAA;CACzD;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACpC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAClC;AAED,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAA;IACtC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAClC;AAuBD,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5E;AAiDD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,GACb,kBAAkB,CAwPpB"}
1
+ {"version":3,"file":"integration-tools.service.d.ts","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,kBAAkB,EAA+B,MAAM,wBAAwB,CAAA;AAM7F,2DAA2D;AAC3D,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAA;IACzC,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAA;CACjF;AAED,UAAU,oBAAoB;IAC5B,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,oBAAoB,CAAA;IAC1D,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,oBAAoB,CAAA;IAC1D,MAAM,IAAI,oBAAoB,CAAA;IAC9B,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,oBAAoB,CAAA;IAC9C,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,oBAAoB,CAAA;IACxD,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,oBAAoB,CAAA;IACrD,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,oBAAoB,CAAA;IAC9E,MAAM,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACvC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,IAAI,CAAA;CACzD;AAED,UAAU,oBAAoB;IAC5B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACpC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAClC;AAED,UAAU,kBAAkB;IAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,IAAI,CAAA;IACtC,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;CAClC;AA8CD,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED,yDAAyD;AACzD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5E;AAiDD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,cAAc,EACxB,MAAM,EAAE,MAAM,GACb,kBAAkB,CAwPpB"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @fileoverview Tests for hashApiKey and its env-var-backed HMAC secret.
3
+ * Extracted from integration-tools.service.test.ts to keep that file under
4
+ * the 500-line cap (SMI-2162). The rest of the integration-tools test
5
+ * suite still sets the env var via its own top-level beforeAll/afterAll.
6
+ *
7
+ * @see SMI-4503: Rotate KEY_HMAC_SECRET to env var
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=integration-tools.service.hash.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-tools.service.hash.test.d.ts","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.hash.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * @fileoverview Tests for hashApiKey and its env-var-backed HMAC secret.
3
+ * Extracted from integration-tools.service.test.ts to keep that file under
4
+ * the 500-line cap (SMI-2162). The rest of the integration-tools test
5
+ * suite still sets the env var via its own top-level beforeAll/afterAll.
6
+ *
7
+ * @see SMI-4503: Rotate KEY_HMAC_SECRET to env var
8
+ */
9
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
10
+ import { createHmac } from 'node:crypto';
11
+ import { hashApiKey } from './integration-tools.service.js';
12
+ const TEST_HMAC_SECRET = 'test-hmac-secret-for-vitest-only-32chars-minimum-padding-padding-padding';
13
+ const ORIGINAL_HMAC_SECRET = process.env.SKILLSMITH_API_KEY_HMAC_SECRET;
14
+ beforeAll(() => {
15
+ process.env.SKILLSMITH_API_KEY_HMAC_SECRET = TEST_HMAC_SECRET;
16
+ });
17
+ afterAll(() => {
18
+ if (ORIGINAL_HMAC_SECRET === undefined)
19
+ delete process.env.SKILLSMITH_API_KEY_HMAC_SECRET;
20
+ else
21
+ process.env.SKILLSMITH_API_KEY_HMAC_SECRET = ORIGINAL_HMAC_SECRET;
22
+ });
23
+ describe('hashApiKey', () => {
24
+ it('should produce a deterministic SHA-256 HMAC hex hash', () => {
25
+ const key = 'sk_int_testkey123';
26
+ const hash = hashApiKey(key);
27
+ const expected = createHmac('sha256', TEST_HMAC_SECRET).update(key).digest('hex');
28
+ expect(hash).toBe(expected);
29
+ expect(hash).toHaveLength(64);
30
+ });
31
+ it('should produce different hashes for different keys', () => {
32
+ expect(hashApiKey('key-a')).not.toBe(hashApiKey('key-b'));
33
+ });
34
+ describe('boot validation', () => {
35
+ afterAll(() => {
36
+ process.env.SKILLSMITH_API_KEY_HMAC_SECRET = TEST_HMAC_SECRET;
37
+ });
38
+ it('should fail fast when SKILLSMITH_API_KEY_HMAC_SECRET is missing', () => {
39
+ delete process.env.SKILLSMITH_API_KEY_HMAC_SECRET;
40
+ expect(() => hashApiKey('any-key')).toThrow(/SKILLSMITH_API_KEY_HMAC_SECRET/);
41
+ });
42
+ it('should fail fast when secret is shorter than 32 characters', () => {
43
+ process.env.SKILLSMITH_API_KEY_HMAC_SECRET = 'too-short';
44
+ expect(() => hashApiKey('any-key')).toThrow(/32\+ character/);
45
+ });
46
+ });
47
+ });
48
+ //# sourceMappingURL=integration-tools.service.hash.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integration-tools.service.hash.test.js","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.hash.test.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAClE,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAE3D,MAAM,gBAAgB,GAAG,0EAA0E,CAAA;AACnG,MAAM,oBAAoB,GAAG,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAA;AAEvE,SAAS,CAAC,GAAG,EAAE;IACb,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,gBAAgB,CAAA;AAC/D,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,GAAG,EAAE;IACZ,IAAI,oBAAoB,KAAK,SAAS;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAA;;QACpF,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,oBAAoB,CAAA;AACxE,CAAC,CAAC,CAAA;AAEF,QAAQ,CAAC,YAAY,EAAE,GAAG,EAAE;IAC1B,EAAE,CAAC,sDAAsD,EAAE,GAAG,EAAE;QAC9D,MAAM,GAAG,GAAG,mBAAmB,CAAA;QAC/B,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAA;QAE5B,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;QACjF,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QAC3B,MAAM,CAAC,IAAI,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC,CAAA;IAC/B,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oDAAoD,EAAE,GAAG,EAAE;QAC5D,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;IAC3D,CAAC,CAAC,CAAA;IAEF,QAAQ,CAAC,iBAAiB,EAAE,GAAG,EAAE;QAC/B,QAAQ,CAAC,GAAG,EAAE;YACZ,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,gBAAgB,CAAA;QAC/D,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;YACzE,OAAO,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAA;YACjD,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,gCAAgC,CAAC,CAAA;QAC/E,CAAC,CAAC,CAAA;QAEF,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;YACpE,OAAO,CAAC,GAAG,CAAC,8BAA8B,GAAG,WAAW,CAAA;YACxD,MAAM,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAA;QAC/D,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -13,13 +13,33 @@ import { validateExternalUrl } from '../utils/url-validator.js';
13
13
  // ============================================================================
14
14
  // Constants
15
15
  // ============================================================================
16
- const KEY_HMAC_SECRET = 'skillsmith-api-key';
17
16
  const TEST_RATE_LIMIT_MS = 60_000;
18
17
  const TEST_DELIVERY_TIMEOUT_MS = 10_000;
19
18
  const API_KEY_PREFIX_LENGTH = 15; // "sk_int_" (7) + 8 chars
20
19
  // ============================================================================
21
20
  // Crypto helpers
22
21
  // ============================================================================
22
+ /**
23
+ * HMAC key for hashing integration API keys. Read from
24
+ * `SKILLSMITH_API_KEY_HMAC_SECRET` at first use (lazy so process.env writes from
25
+ * the test harness or boot-time loaders apply). Replaces a previously
26
+ * hardcoded constant (CodeQL js/insufficient-password-hash, CWE-916) — a known
27
+ * static key meant a leaked api_keys table could be reverse-cracked offline.
28
+ *
29
+ * Must be the same value across every MCP host that creates or verifies
30
+ * integration API keys; threat model + distribution channel matches
31
+ * SUPABASE_SERVICE_ROLE_KEY (only Team+ admins touching the integrations
32
+ * surface need it).
33
+ */
34
+ function getKeyHmacSecret() {
35
+ const secret = process.env.SKILLSMITH_API_KEY_HMAC_SECRET;
36
+ if (!secret || secret.length < 32) {
37
+ throw new Error('SKILLSMITH_API_KEY_HMAC_SECRET must be set to a 32+ character random ' +
38
+ 'secret before integration tools can be used. ' +
39
+ 'Generate one via: openssl rand -base64 48');
40
+ }
41
+ return secret;
42
+ }
23
43
  function generateSigningSecret() {
24
44
  return 'whsec_' + randomBytes(32).toString('hex');
25
45
  }
@@ -28,7 +48,7 @@ function generateApiKey() {
28
48
  }
29
49
  /** Hash an API key for storage (one-way) */
30
50
  export function hashApiKey(key) {
31
- return createHmac('sha256', KEY_HMAC_SECRET).update(key).digest('hex');
51
+ return createHmac('sha256', getKeyHmacSecret()).update(key).digest('hex');
32
52
  }
33
53
  /** Compute HMAC-SHA256 signature for webhook delivery */
34
54
  export function computeHmacSignature(secret, payload) {
@@ -1 +1 @@
1
- {"version":3,"file":"integration-tools.service.js","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"integration-tools.service.js","sourceRoot":"","sources":["../../../src/tools/integration-tools.service.ts"],"names":[],"mappings":"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"}
@@ -4,9 +4,23 @@
4
4
  *
5
5
  * All tests mock the Supabase client — no real database needed.
6
6
  */
7
- import { describe, it, expect, vi, beforeEach } from 'vitest';
7
+ import { describe, it, expect, vi, beforeAll, beforeEach, afterAll } from 'vitest';
8
8
  import { createHmac } from 'node:crypto';
9
9
  import { createRealIntegrationService, hashApiKey, computeHmacSignature, } from './integration-tools.service.js';
10
+ // SMI-4503: hashApiKey reads SKILLSMITH_API_KEY_HMAC_SECRET from env. All tests
11
+ // in this file must run with the secret set; the per-describe block below
12
+ // covers the env-var-missing failure mode in isolation.
13
+ const TEST_HMAC_SECRET = 'test-hmac-secret-for-vitest-only-32chars-minimum-padding-padding-padding';
14
+ const ORIGINAL_HMAC_SECRET = process.env.SKILLSMITH_API_KEY_HMAC_SECRET;
15
+ beforeAll(() => {
16
+ process.env.SKILLSMITH_API_KEY_HMAC_SECRET = TEST_HMAC_SECRET;
17
+ });
18
+ afterAll(() => {
19
+ if (ORIGINAL_HMAC_SECRET === undefined)
20
+ delete process.env.SKILLSMITH_API_KEY_HMAC_SECRET;
21
+ else
22
+ process.env.SKILLSMITH_API_KEY_HMAC_SECRET = ORIGINAL_HMAC_SECRET;
23
+ });
10
24
  // ============================================================================
11
25
  // Supabase mock factory
12
26
  // ============================================================================
@@ -39,20 +53,9 @@ function createMockSupabase(resolvedValue = { data: null, error: null }) {
39
53
  const TEAM_ID = 'team-001';
40
54
  // ============================================================================
41
55
  // Crypto helper tests
56
+ // hashApiKey + env-var boot-validation tests live in
57
+ // integration-tools.service.hash.test.ts (SMI-2162 file-length companion).
42
58
  // ============================================================================
43
- describe('hashApiKey', () => {
44
- it('should produce a deterministic SHA-256 HMAC hex hash', () => {
45
- const key = 'sk_int_testkey123';
46
- const hash = hashApiKey(key);
47
- // Verify it matches raw crypto
48
- const expected = createHmac('sha256', 'skillsmith-api-key').update(key).digest('hex');
49
- expect(hash).toBe(expected);
50
- expect(hash).toHaveLength(64);
51
- });
52
- it('should produce different hashes for different keys', () => {
53
- expect(hashApiKey('key-a')).not.toBe(hashApiKey('key-b'));
54
- });
55
- });
56
59
  describe('computeHmacSignature', () => {
57
60
  it('should produce correct HMAC-SHA256 signature', () => {
58
61
  const secret = 'whsec_abc123';