@skillsmith/mcp-server 0.5.1 → 0.5.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/CHANGELOG.md +32 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/__tests__/LocalIndexer.empty-dir.test.d.ts +21 -0
- package/dist/src/__tests__/LocalIndexer.empty-dir.test.d.ts.map +1 -0
- package/dist/src/__tests__/LocalIndexer.empty-dir.test.js +38 -0
- package/dist/src/__tests__/LocalIndexer.empty-dir.test.js.map +1 -0
- package/dist/src/__tests__/get-skill.test.js +5 -0
- package/dist/src/__tests__/get-skill.test.js.map +1 -1
- package/dist/src/__tests__/recommend-online-path.test.js +2 -0
- package/dist/src/__tests__/recommend-online-path.test.js.map +1 -1
- package/dist/src/__tests__/recommend.test.js +10 -2
- package/dist/src/__tests__/recommend.test.js.map +1 -1
- package/dist/src/__tests__/search-installable.test.d.ts +11 -0
- package/dist/src/__tests__/search-installable.test.d.ts.map +1 -0
- package/dist/src/__tests__/search-installable.test.js +154 -0
- package/dist/src/__tests__/search-installable.test.js.map +1 -0
- package/dist/src/__tests__/search-online-path.test.js +1 -0
- package/dist/src/__tests__/search-online-path.test.js.map +1 -1
- package/dist/src/__tests__/search.test.js +3 -0
- package/dist/src/__tests__/search.test.js.map +1 -1
- package/dist/src/cli-flags.d.ts +20 -0
- package/dist/src/cli-flags.d.ts.map +1 -0
- package/dist/src/cli-flags.js +36 -0
- package/dist/src/cli-flags.js.map +1 -0
- package/dist/src/index.js +23 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/middleware/license.gate.d.ts +2 -2
- package/dist/src/middleware/license.gate.d.ts.map +1 -1
- package/dist/src/middleware/license.gate.js +43 -1
- package/dist/src/middleware/license.gate.js.map +1 -1
- package/dist/src/middleware/telemetry-consent.d.ts +88 -0
- package/dist/src/middleware/telemetry-consent.d.ts.map +1 -0
- package/dist/src/middleware/telemetry-consent.js +177 -0
- package/dist/src/middleware/telemetry-consent.js.map +1 -0
- package/dist/src/middleware/telemetry-consent.test.d.ts +12 -0
- package/dist/src/middleware/telemetry-consent.test.d.ts.map +1 -0
- package/dist/src/middleware/telemetry-consent.test.js +291 -0
- package/dist/src/middleware/telemetry-consent.test.js.map +1 -0
- package/dist/src/tools/LocalSkillSearch.d.ts.map +1 -1
- package/dist/src/tools/LocalSkillSearch.js +3 -0
- package/dist/src/tools/LocalSkillSearch.js.map +1 -1
- package/dist/src/tools/__meta__/telemetry-coverage.test.d.ts +25 -0
- package/dist/src/tools/__meta__/telemetry-coverage.test.d.ts.map +1 -0
- package/dist/src/tools/__meta__/telemetry-coverage.test.js +210 -0
- package/dist/src/tools/__meta__/telemetry-coverage.test.js.map +1 -0
- package/dist/src/tools/analytics.d.ts +15 -28
- package/dist/src/tools/analytics.d.ts.map +1 -1
- package/dist/src/tools/analytics.js +26 -4
- package/dist/src/tools/analytics.js.map +1 -1
- package/dist/src/tools/analytics.supabase.service.d.ts +103 -0
- package/dist/src/tools/analytics.supabase.service.d.ts.map +1 -0
- package/dist/src/tools/analytics.supabase.service.js +171 -0
- package/dist/src/tools/analytics.supabase.service.js.map +1 -0
- package/dist/src/tools/analytics.supabase.service.test.d.ts +10 -0
- package/dist/src/tools/analytics.supabase.service.test.d.ts.map +1 -0
- package/dist/src/tools/analytics.supabase.service.test.js +375 -0
- package/dist/src/tools/analytics.supabase.service.test.js.map +1 -0
- package/dist/src/tools/analyze.d.ts +6 -19
- package/dist/src/tools/analyze.d.ts.map +1 -1
- package/dist/src/tools/analyze.js +8 -1
- package/dist/src/tools/analyze.js.map +1 -1
- package/dist/src/tools/apply-namespace-rename.d.ts +1 -8
- package/dist/src/tools/apply-namespace-rename.d.ts.map +1 -1
- package/dist/src/tools/apply-namespace-rename.js +8 -1
- package/dist/src/tools/apply-namespace-rename.js.map +1 -1
- package/dist/src/tools/apply-recommended-edit.d.ts +1 -6
- package/dist/src/tools/apply-recommended-edit.d.ts.map +1 -1
- package/dist/src/tools/apply-recommended-edit.js +8 -1
- package/dist/src/tools/apply-recommended-edit.js.map +1 -1
- package/dist/src/tools/audit-tools.d.ts +20 -3
- package/dist/src/tools/audit-tools.d.ts.map +1 -1
- package/dist/src/tools/audit-tools.js +20 -3
- package/dist/src/tools/audit-tools.js.map +1 -1
- package/dist/src/tools/compare.d.ts +7 -23
- package/dist/src/tools/compare.d.ts.map +1 -1
- package/dist/src/tools/compare.js +12 -5
- package/dist/src/tools/compare.js.map +1 -1
- package/dist/src/tools/compare.types.js +3 -3
- package/dist/src/tools/compare.types.js.map +1 -1
- package/dist/src/tools/compliance-tools.d.ts +5 -1
- package/dist/src/tools/compliance-tools.d.ts.map +1 -1
- package/dist/src/tools/compliance-tools.js +8 -1
- package/dist/src/tools/compliance-tools.js.map +1 -1
- package/dist/src/tools/get-skill.d.ts +6 -25
- package/dist/src/tools/get-skill.d.ts.map +1 -1
- package/dist/src/tools/get-skill.js +30 -10
- package/dist/src/tools/get-skill.js.map +1 -1
- package/dist/src/tools/index-local.d.ts +1 -15
- package/dist/src/tools/index-local.d.ts.map +1 -1
- package/dist/src/tools/index-local.js +8 -1
- package/dist/src/tools/index-local.js.map +1 -1
- package/dist/src/tools/install.d.ts +1 -17
- package/dist/src/tools/install.d.ts.map +1 -1
- package/dist/src/tools/install.js +8 -1
- package/dist/src/tools/install.js.map +1 -1
- package/dist/src/tools/install.tool.js +1 -1
- package/dist/src/tools/install.tool.js.map +1 -1
- package/dist/src/tools/integration-tools.d.ts +14 -2
- package/dist/src/tools/integration-tools.d.ts.map +1 -1
- package/dist/src/tools/integration-tools.js +14 -2
- package/dist/src/tools/integration-tools.js.map +1 -1
- package/dist/src/tools/outdated.d.ts +3 -14
- package/dist/src/tools/outdated.d.ts.map +1 -1
- package/dist/src/tools/outdated.js +8 -1
- package/dist/src/tools/outdated.js.map +1 -1
- package/dist/src/tools/outdated.test.js +3 -0
- package/dist/src/tools/outdated.test.js.map +1 -1
- package/dist/src/tools/publish-private.d.ts +4 -7
- package/dist/src/tools/publish-private.d.ts.map +1 -1
- package/dist/src/tools/publish-private.js +8 -1
- package/dist/src/tools/publish-private.js.map +1 -1
- package/dist/src/tools/publish.d.ts +9 -11
- package/dist/src/tools/publish.d.ts.map +1 -1
- package/dist/src/tools/publish.js +8 -1
- package/dist/src/tools/publish.js.map +1 -1
- package/dist/src/tools/rbac-tools.d.ts +20 -3
- package/dist/src/tools/rbac-tools.d.ts.map +1 -1
- package/dist/src/tools/rbac-tools.js +20 -3
- package/dist/src/tools/rbac-tools.js.map +1 -1
- package/dist/src/tools/rbac-tools.test.js +2 -0
- package/dist/src/tools/rbac-tools.test.js.map +1 -1
- package/dist/src/tools/recommend.d.ts +9 -9
- package/dist/src/tools/recommend.d.ts.map +1 -1
- package/dist/src/tools/recommend.js +8 -1
- package/dist/src/tools/recommend.js.map +1 -1
- package/dist/src/tools/recommend.types.js +1 -1
- package/dist/src/tools/recommend.types.js.map +1 -1
- package/dist/src/tools/registry-tools.d.ts +10 -8
- package/dist/src/tools/registry-tools.d.ts.map +1 -1
- package/dist/src/tools/registry-tools.js +14 -2
- package/dist/src/tools/registry-tools.js.map +1 -1
- package/dist/src/tools/search.d.ts +9 -42
- package/dist/src/tools/search.d.ts.map +1 -1
- package/dist/src/tools/search.formatter.d.ts.map +1 -1
- package/dist/src/tools/search.formatter.js +4 -0
- package/dist/src/tools/search.formatter.js.map +1 -1
- package/dist/src/tools/search.js +51 -30
- package/dist/src/tools/search.js.map +1 -1
- package/dist/src/tools/skill-audit.d.ts +3 -13
- package/dist/src/tools/skill-audit.d.ts.map +1 -1
- package/dist/src/tools/skill-audit.js +8 -1
- package/dist/src/tools/skill-audit.js.map +1 -1
- package/dist/src/tools/skill-diff.d.ts +9 -11
- package/dist/src/tools/skill-diff.d.ts.map +1 -1
- package/dist/src/tools/skill-diff.js +8 -1
- package/dist/src/tools/skill-diff.js.map +1 -1
- package/dist/src/tools/skill-inventory-audit.d.ts +1 -6
- package/dist/src/tools/skill-inventory-audit.d.ts.map +1 -1
- package/dist/src/tools/skill-inventory-audit.js +8 -1
- package/dist/src/tools/skill-inventory-audit.js.map +1 -1
- package/dist/src/tools/skill-pack-audit.d.ts +4 -12
- package/dist/src/tools/skill-pack-audit.d.ts.map +1 -1
- package/dist/src/tools/skill-pack-audit.js +8 -1
- package/dist/src/tools/skill-pack-audit.js.map +1 -1
- package/dist/src/tools/skill-rescan.d.ts +3 -11
- package/dist/src/tools/skill-rescan.d.ts.map +1 -1
- package/dist/src/tools/skill-rescan.js +8 -1
- package/dist/src/tools/skill-rescan.js.map +1 -1
- package/dist/src/tools/skill-rescan.test.js +2 -0
- package/dist/src/tools/skill-rescan.test.js.map +1 -1
- package/dist/src/tools/skill-updates.d.ts +3 -12
- package/dist/src/tools/skill-updates.d.ts.map +1 -1
- package/dist/src/tools/skill-updates.js +8 -1
- package/dist/src/tools/skill-updates.js.map +1 -1
- package/dist/src/tools/sso-tools.d.ts +9 -8
- package/dist/src/tools/sso-tools.d.ts.map +1 -1
- package/dist/src/tools/sso-tools.js +14 -2
- package/dist/src/tools/sso-tools.js.map +1 -1
- package/dist/src/tools/suggest.d.ts +10 -18
- package/dist/src/tools/suggest.d.ts.map +1 -1
- package/dist/src/tools/suggest.js +10 -3
- package/dist/src/tools/suggest.js.map +1 -1
- package/dist/src/tools/team-workspace.d.ts +11 -16
- package/dist/src/tools/team-workspace.d.ts.map +1 -1
- package/dist/src/tools/team-workspace.js +14 -2
- package/dist/src/tools/team-workspace.js.map +1 -1
- package/dist/src/tools/uninstall.d.ts +4 -10
- package/dist/src/tools/uninstall.d.ts.map +1 -1
- package/dist/src/tools/uninstall.js +9 -2
- package/dist/src/tools/uninstall.js.map +1 -1
- package/dist/src/tools/validate.d.ts +5 -23
- package/dist/src/tools/validate.d.ts.map +1 -1
- package/dist/src/tools/validate.js +8 -1
- package/dist/src/tools/validate.js.map +1 -1
- package/dist/src/validation.d.ts +2 -2
- package/dist/src/validation.d.ts.map +1 -1
- package/dist/src/validation.js +6 -0
- package/dist/src/validation.js.map +1 -1
- package/dist/src/webhooks/stripe-webhook-endpoint.d.ts +28 -1
- package/dist/src/webhooks/stripe-webhook-endpoint.d.ts.map +1 -1
- package/dist/src/webhooks/stripe-webhook-endpoint.js.map +1 -1
- package/dist/tests/cli-flags.test.d.ts +2 -0
- package/dist/tests/cli-flags.test.d.ts.map +1 -0
- package/dist/tests/cli-flags.test.js +33 -0
- package/dist/tests/cli-flags.test.js.map +1 -0
- package/dist/tests/compare.test.js +3 -0
- package/dist/tests/compare.test.js.map +1 -1
- package/dist/tests/e2e/compare.e2e.test.js +3 -1
- package/dist/tests/e2e/compare.e2e.test.js.map +1 -1
- package/dist/tests/e2e/recommend.e2e.test.js +6 -1
- package/dist/tests/e2e/recommend.e2e.test.js.map +1 -1
- package/dist/tests/e2e/skill-flow.e2e.test.js +8 -0
- package/dist/tests/e2e/skill-flow.e2e.test.js.map +1 -1
- package/dist/tests/e2e/suggest.e2e.test.js +5 -1
- package/dist/tests/e2e/suggest.e2e.test.js.map +1 -1
- package/dist/tests/integration/analyze.integration.test.js +7 -0
- package/dist/tests/integration/analyze.integration.test.js.map +1 -1
- package/dist/tests/integration/recommend.integration.test.js +6 -0
- package/dist/tests/integration/recommend.integration.test.js.map +1 -1
- package/dist/tests/integration/validate.integration.test.js +7 -1
- package/dist/tests/integration/validate.integration.test.js.map +1 -1
- package/dist/tests/performance/search-performance.test.js +9 -1
- package/dist/tests/performance/search-performance.test.js.map +1 -1
- package/dist/tests/recommend.test.js +11 -2
- package/dist/tests/recommend.test.js.map +1 -1
- package/dist/tests/startup-probe.test.d.ts +17 -0
- package/dist/tests/startup-probe.test.d.ts.map +1 -0
- package/dist/tests/startup-probe.test.js +214 -0
- package/dist/tests/startup-probe.test.js.map +1 -0
- package/dist/tests/tool-descriptions.test.js +1 -1
- package/dist/tests/tool-descriptions.test.js.map +1 -1
- package/dist/tests/unit/skill-pack-audit.test.js +14 -1
- package/dist/tests/unit/skill-pack-audit.test.js.map +1 -1
- package/dist/tests/validate.test.js +28 -8
- package/dist/tests/validate.test.js.map +1 -1
- package/package.json +3 -11
- package/server.json +2 -2
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4805: startup CLI-flag handling for the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* `@skillsmith/mcp-server` is a stdio-driven MCP server — when invoked directly
|
|
5
|
+
* (`npx -y @skillsmith/mcp-server --version`) the MCP SDK otherwise swallows
|
|
6
|
+
* argv and the process starts the server instead of printing the version.
|
|
7
|
+
*
|
|
8
|
+
* `resolveStartupFlag` is a pure function so it can be unit-tested without
|
|
9
|
+
* importing `index.ts` (whose module body calls `main()` on load).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a recognized startup flag to the text that should be printed.
|
|
13
|
+
*
|
|
14
|
+
* @param argv - Arguments after `node script` (i.e. `process.argv.slice(2)`).
|
|
15
|
+
* @param version - The package version, printed for `--version` / `-v`.
|
|
16
|
+
* @returns The text to print before exiting, or `null` when no recognized
|
|
17
|
+
* startup flag is present and the server should start normally.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolveStartupFlag(argv: string[], version: string): string | null;
|
|
20
|
+
//# sourceMappingURL=cli-flags.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-flags.d.ts","sourceRoot":"","sources":["../../src/cli-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBjF"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-4805: startup CLI-flag handling for the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* `@skillsmith/mcp-server` is a stdio-driven MCP server — when invoked directly
|
|
5
|
+
* (`npx -y @skillsmith/mcp-server --version`) the MCP SDK otherwise swallows
|
|
6
|
+
* argv and the process starts the server instead of printing the version.
|
|
7
|
+
*
|
|
8
|
+
* `resolveStartupFlag` is a pure function so it can be unit-tested without
|
|
9
|
+
* importing `index.ts` (whose module body calls `main()` on load).
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Resolve a recognized startup flag to the text that should be printed.
|
|
13
|
+
*
|
|
14
|
+
* @param argv - Arguments after `node script` (i.e. `process.argv.slice(2)`).
|
|
15
|
+
* @param version - The package version, printed for `--version` / `-v`.
|
|
16
|
+
* @returns The text to print before exiting, or `null` when no recognized
|
|
17
|
+
* startup flag is present and the server should start normally.
|
|
18
|
+
*/
|
|
19
|
+
export function resolveStartupFlag(argv, version) {
|
|
20
|
+
if (argv.includes('--version') || argv.includes('-v')) {
|
|
21
|
+
return version;
|
|
22
|
+
}
|
|
23
|
+
if (argv.includes('--help') || argv.includes('-h')) {
|
|
24
|
+
return [
|
|
25
|
+
'Skillsmith MCP server.',
|
|
26
|
+
'Run via your MCP client (Claude Code, Cursor, etc.) — no direct CLI invocation needed.',
|
|
27
|
+
'',
|
|
28
|
+
'Flags:',
|
|
29
|
+
' --version, -v print the version and exit',
|
|
30
|
+
' --help, -h print this help and exit',
|
|
31
|
+
' --docs, -d open the documentation',
|
|
32
|
+
].join('\n');
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=cli-flags.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli-flags.js","sourceRoot":"","sources":["../../src/cli-flags.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAc,EAAE,OAAe;IAChE,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACtD,OAAO,OAAO,CAAA;IAChB,CAAC;IACD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO;YACL,wBAAwB;YACxB,wFAAwF;YACxF,EAAE;YACF,QAAQ;YACR,8CAA8C;YAC9C,4CAA4C;YAC5C,0CAA0C;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACd,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC"}
|
package/dist/src/index.js
CHANGED
|
@@ -43,10 +43,15 @@ import { complianceReportToolSchema } from './tools/compliance-tools.js';
|
|
|
43
43
|
import { dispatchToolCall } from './tool-dispatch.js';
|
|
44
44
|
import { isFirstRun, markFirstRunComplete, getWelcomeMessage, TIER1_SKILLS, } from './onboarding/first-run.js';
|
|
45
45
|
import { checkForUpdates, formatUpdateNotification } from '@skillsmith/core';
|
|
46
|
+
// SMI-5039: probe extracted from this file to @skillsmith/core/embeddings/probe.
|
|
47
|
+
// The call site (before server.connect) is unchanged; only the implementation
|
|
48
|
+
// moved so doc-retrieval-mcp + cli can share the same audited probe contract.
|
|
49
|
+
import { probeEmbeddingCapability } from '@skillsmith/core/embeddings/probe';
|
|
46
50
|
import { createLicenseMiddleware } from './middleware/license.js';
|
|
47
51
|
import { createQuotaMiddleware } from './middleware/quota.js';
|
|
52
|
+
import { resolveStartupFlag } from './cli-flags.js';
|
|
48
53
|
// Package version - keep in sync with package.json
|
|
49
|
-
const PACKAGE_VERSION = '0.5.
|
|
54
|
+
const PACKAGE_VERSION = '0.5.3';
|
|
50
55
|
const PACKAGE_NAME = '@skillsmith/mcp-server';
|
|
51
56
|
import { installBundledSkills, installUserDocs, getUserGuidePath, } from './onboarding/install-assets.js';
|
|
52
57
|
// SMI-2679: Quota enforcement middleware — module-level singletons, initialized once
|
|
@@ -286,8 +291,20 @@ function runStartupDiagnostics() {
|
|
|
286
291
|
console.error(`[Skillsmith] Warning: Could not resolve @skillsmith/core: ${msg}`);
|
|
287
292
|
}
|
|
288
293
|
}
|
|
294
|
+
// SMI-5009 (origin) / SMI-5039 (extraction): the embedding capability probe
|
|
295
|
+
// now lives in @skillsmith/core/embeddings/probe. See that file for the
|
|
296
|
+
// contract (hard 2 s timeout, try/catch wrapper, stderr-only, never throws).
|
|
297
|
+
// Call site below preserved verbatim — invoke before server.connect(transport).
|
|
289
298
|
// Start server
|
|
290
299
|
async function main() {
|
|
300
|
+
// SMI-4805: --version / --help must short-circuit before diagnostics, DB
|
|
301
|
+
// init, or the stdio server start — otherwise the flag is swallowed by the
|
|
302
|
+
// MCP SDK's stdio mode and the server runs instead of printing + exiting.
|
|
303
|
+
const startupFlagOutput = resolveStartupFlag(process.argv.slice(2), PACKAGE_VERSION);
|
|
304
|
+
if (startupFlagOutput !== null) {
|
|
305
|
+
console.log(startupFlagOutput);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
291
308
|
// SMI-2163: Run startup diagnostics before anything else
|
|
292
309
|
runStartupDiagnostics();
|
|
293
310
|
// Handle --docs flag
|
|
@@ -338,6 +355,11 @@ async function main() {
|
|
|
338
355
|
// Silent failure - don't block server startup
|
|
339
356
|
});
|
|
340
357
|
}
|
|
358
|
+
// SMI-5009: probe embedding capability BEFORE serving any requests so the
|
|
359
|
+
// module-load cache is warm and the first user search request doesn't race
|
|
360
|
+
// with cold transformers initialisation. Probe is hard-bounded at 2s and
|
|
361
|
+
// can never throw — see probeEmbeddingCapability for guarantees.
|
|
362
|
+
await probeEmbeddingCapability();
|
|
341
363
|
const transport = new StdioServerTransport();
|
|
342
364
|
await server.connect(transport);
|
|
343
365
|
console.error('Skillsmith MCP server running');
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEpC,uDAAuD;AACvD,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAA;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAA;AAElG,wDAAwD;AACxD,OAAO,EAAE,mBAAmB,EAAoB,MAAM,cAAc,CAAA;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AACzD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAA;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAA;AACtE,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,EAAE,uBAAuB,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAA;AACzF,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAA;AACrE,OAAO,EACL,gCAAgC,EAChC,yBAAyB,EACzB,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AACpF,OAAO,EACL,gCAAgC,EAChC,+BAA+B,GAChC,MAAM,2BAA2B,CAAA;AAClC,OAAO,EACL,oBAAoB,EACpB,wBAAwB,EACxB,0BAA0B,GAC3B,MAAM,uBAAuB,CAAA;AAC9B,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAA;AACjG,OAAO,EAAE,0BAA0B,EAAE,MAAM,6BAA6B,CAAA;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,GACb,MAAM,2BAA2B,CAAA;AAClC,OAAO,EAAE,eAAe,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAA;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAA;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { ZodTypeAny, TypeOf } from 'zod';
|
|
3
3
|
import type { ToolContext } from '../context.types.js';
|
|
4
4
|
import type { QuotaMiddleware } from './quota-types.js';
|
|
5
5
|
import type { LicenseMiddleware } from './license.js';
|
|
@@ -33,5 +33,5 @@ export declare function createProfileIncompleteResponse(): {
|
|
|
33
33
|
}>;
|
|
34
34
|
isError: true;
|
|
35
35
|
};
|
|
36
|
-
export declare function withLicenseAndQuota<
|
|
36
|
+
export declare function withLicenseAndQuota<S extends ZodTypeAny>(toolName: string, args: Record<string, unknown> | undefined, schema: S, handler: (input: TypeOf<S>, ctx: ToolContext) => Promise<unknown>, toolContext: ToolContext, licenseMiddleware: LicenseMiddleware, quotaMiddleware: QuotaMiddleware): Promise<CallToolResult>;
|
|
37
37
|
//# sourceMappingURL=license.gate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"license.gate.d.ts","sourceRoot":"","sources":["../../../src/middleware/license.gate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"license.gate.d.ts","sourceRoot":"","sources":["../../../src/middleware/license.gate.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAA;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,KAAK,CAAA;AAC7C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAIvD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAMrD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,+BAA+B,SAAS,CAAA;AA8CrD,wBAAgB,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,cAAc,CAIlD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE;IACpC,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC,GAAG,cAAc,CAEjB;AAID,wBAAgB,+BAA+B,IAAI;IACjD,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC9C,OAAO,EAAE,IAAI,CAAA;CACd,CAoBA;AASD,wBAAsB,mBAAmB,CAAC,CAAC,SAAS,UAAU,EAC5D,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EACzC,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,WAAW,KAAK,OAAO,CAAC,OAAO,CAAC,EACjE,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,iBAAiB,EACpC,eAAe,EAAE,eAAe,GAC/B,OAAO,CAAC,cAAc,CAAC,CA8DzB"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { safeParseOrError } from '../validation.js';
|
|
2
2
|
import { ApiClientError, SkillsmithError, ErrorCodes } from '@skillsmith/core';
|
|
3
|
+
import { setEmissionGate } from '@skillsmith/core/telemetry';
|
|
3
4
|
import { createLicenseErrorResponse } from './license.js';
|
|
5
|
+
import { resolveConsent, annotateResponseWithConsent } from './telemetry-consent.js';
|
|
4
6
|
const COMPLETE_PROFILE_URL = 'https://skillsmith.app/complete-profile';
|
|
5
7
|
/**
|
|
6
8
|
* SMI-4463: JSON-RPC error code for monthly_quota_exceeded.
|
|
@@ -78,6 +80,9 @@ export function createProfileIncompleteResponse() {
|
|
|
78
80
|
// response. Note: checkAndTrack runs before the handler (quota IS decremented even
|
|
79
81
|
// for profile_incomplete errors, because the QuotaMiddleware has no split check/track
|
|
80
82
|
// API). A future improvement (SMI-4403) could add a checkOnly + track-on-success path.
|
|
83
|
+
// SMI-5037: parameterise over the schema type `S` (see validation.ts) so the
|
|
84
|
+
// signature is stable across zod v3 (locked, used by CI) and v4 (hoisted in
|
|
85
|
+
// drifted dev installs). `TypeOf<S>` derives the handler input from the schema.
|
|
81
86
|
export async function withLicenseAndQuota(toolName, args, schema, handler, toolContext, licenseMiddleware, quotaMiddleware) {
|
|
82
87
|
const parsed = safeParseOrError(schema, args, toolName);
|
|
83
88
|
if (!parsed.ok)
|
|
@@ -89,8 +94,37 @@ export async function withLicenseAndQuota(toolName, args, schema, handler, toolC
|
|
|
89
94
|
const quotaResult = await quotaMiddleware.checkAndTrack(toolName, licenseInfo);
|
|
90
95
|
if (!quotaResult.allowed)
|
|
91
96
|
return errResponse(quotaMiddleware.buildExceededResponse(quotaResult));
|
|
97
|
+
// SMI-5019 W2.S4: resolve telemetry-consent state in parallel with the
|
|
98
|
+
// tool handler. The consent surface for MCP-only clients is the web
|
|
99
|
+
// dashboard at TELEMETRY_PRIVACY_URL; first call from an unrecognised
|
|
100
|
+
// anonymous_id surfaces `consent_required:true` in the response envelope.
|
|
101
|
+
// Resolution failure is fail-safe (consent required, telemetry suppressed).
|
|
102
|
+
//
|
|
103
|
+
// SMI-5019 wire-in: we await consent BEFORE installing the emission gate so
|
|
104
|
+
// the gate predicate can be a sync boolean snapshot — the
|
|
105
|
+
// `@skillsmith/core/telemetry` `withTelemetry` HOF calls the gate inside a
|
|
106
|
+
// sync `finally` block, so an async predicate would be unsound. The
|
|
107
|
+
// `resolveConsent` call is process-cached, so this await is one round-trip
|
|
108
|
+
// on first call for a given anonymous_id and zero-cost on subsequent calls.
|
|
109
|
+
const consent = await resolveConsent(toolContext.distinctId);
|
|
110
|
+
// Install a per-request emission gate so `withTelemetry` only emits when
|
|
111
|
+
// this anonymous_id's consent has resolved AND is enabled. The gate is
|
|
112
|
+
// reset to `undefined` (default-suppress) in `finally` so it never leaks
|
|
113
|
+
// emission permission to the next request.
|
|
114
|
+
//
|
|
115
|
+
// Multi-tenancy caveat: this gate is module-scoped at the
|
|
116
|
+
// `@skillsmith/core/telemetry` layer, so two CONCURRENT requests in the same
|
|
117
|
+
// process from DIFFERENT anonymous_ids would observe the gate of whichever
|
|
118
|
+
// one ran setEmissionGate most recently. The v1 MCP server is single-tenant
|
|
119
|
+
// (one stdio subprocess per user), so this is correct today. A future
|
|
120
|
+
// multi-tenant transport (e.g. a shared HTTP server fronting many users)
|
|
121
|
+
// MUST switch this to `AsyncLocalStorage`-backed per-request state — see
|
|
122
|
+
// the matching caveat in `packages/core/src/telemetry/wrap.ts`.
|
|
123
|
+
const emit = consent.enabled;
|
|
124
|
+
setEmissionGate(() => emit);
|
|
92
125
|
try {
|
|
93
|
-
|
|
126
|
+
const handlerResult = await handler(parsed.data, toolContext);
|
|
127
|
+
return annotateResponseWithConsent(ok(handlerResult), consent);
|
|
94
128
|
}
|
|
95
129
|
catch (err) {
|
|
96
130
|
if (err instanceof ApiClientError &&
|
|
@@ -106,5 +140,13 @@ export async function withLicenseAndQuota(toolName, args, schema, handler, toolC
|
|
|
106
140
|
}
|
|
107
141
|
throw err;
|
|
108
142
|
}
|
|
143
|
+
finally {
|
|
144
|
+
// SMI-5019 wire-in: revert to default-suppress so a misconfigured next
|
|
145
|
+
// request can't inherit this request's emission permission. The
|
|
146
|
+
// `withTelemetry` HOF's finally has already fired by now (the handler
|
|
147
|
+
// awaited above, including its synchronous-finally emit path), so
|
|
148
|
+
// clearing the gate here only affects subsequent requests.
|
|
149
|
+
setEmissionGate(undefined);
|
|
150
|
+
}
|
|
109
151
|
}
|
|
110
152
|
//# sourceMappingURL=license.gate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"license.gate.js","sourceRoot":"","sources":["../../../src/middleware/license.gate.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"license.gate.js","sourceRoot":"","sources":["../../../src/middleware/license.gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry Consent Gate — SMI-5019 W2.S4
|
|
3
|
+
*
|
|
4
|
+
* For MCP-only clients (Cursor, Continue, Copilot users without a CLI install)
|
|
5
|
+
* we cannot rely on a CLI first-run prompt or a VS Code toast. Per user
|
|
6
|
+
* decision U5 in the implementation plan, the consent surface is the web
|
|
7
|
+
* dashboard at https://skillsmith.app/account/telemetry.
|
|
8
|
+
*
|
|
9
|
+
* This module supplies the MCP-side half of that flow:
|
|
10
|
+
*
|
|
11
|
+
* 1. On every tool call, resolve the calling anonymous_id's preference from
|
|
12
|
+
* `user_telemetry_preferences` (RLS-scoped via the same anon-key client
|
|
13
|
+
* used elsewhere in this package).
|
|
14
|
+
* 2. If the row is missing, signal `consent_required:true` + the privacy URL
|
|
15
|
+
* in the response envelope so the client can prompt the user to open the
|
|
16
|
+
* dashboard.
|
|
17
|
+
* 3. Cache the resolved state per process (Map keyed by anonymous_id) so
|
|
18
|
+
* repeated calls within a session don't re-query, and so two parallel
|
|
19
|
+
* calls from the same unrecognized anonymous_id observe identical state.
|
|
20
|
+
* 4. Suppress telemetry writes (consult `shouldEmitTelemetry`) for that
|
|
21
|
+
* anonymous_id until the preference resolves to `enabled:true`.
|
|
22
|
+
*
|
|
23
|
+
* SMI-5016 (`packages/core/src/telemetry/wrap.ts`) and SMI-5017 (tool /
|
|
24
|
+
* command dispatchers) are wave-sibling deliverables — this module
|
|
25
|
+
* deliberately stays out of those files.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Canonical absolute URL of the consent dashboard. Must remain stable across
|
|
29
|
+
* surfaces so MCP clients can deep-link to a known landing page.
|
|
30
|
+
*/
|
|
31
|
+
export declare const TELEMETRY_PRIVACY_URL = "https://skillsmith.app/account/telemetry";
|
|
32
|
+
/**
|
|
33
|
+
* Result of resolving the consent state for a given anonymous_id.
|
|
34
|
+
*/
|
|
35
|
+
export interface ConsentState {
|
|
36
|
+
/** True iff a preference row was found AND `enabled = true`. */
|
|
37
|
+
enabled: boolean;
|
|
38
|
+
/**
|
|
39
|
+
* True iff there is no row for this anonymous_id yet (the user hasn't
|
|
40
|
+
* visited the consent page). Surface this in the response envelope so the
|
|
41
|
+
* client can prompt the user.
|
|
42
|
+
*/
|
|
43
|
+
consentRequired: boolean;
|
|
44
|
+
/** Stable URL to direct the user to when `consentRequired` is true. */
|
|
45
|
+
privacyUrl: string;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Resolve the consent state for `anonymousId`, caching the result for the
|
|
49
|
+
* lifetime of the process. Concurrent calls share one in-flight query.
|
|
50
|
+
*
|
|
51
|
+
* Passing `null`/`undefined`/empty triggers the no-id branch — telemetry is
|
|
52
|
+
* suppressed but no prompt is shown (there's nothing to link the user's
|
|
53
|
+
* eventual web-dashboard choice back to).
|
|
54
|
+
*/
|
|
55
|
+
export declare function resolveConsent(anonymousId: string | null | undefined): Promise<ConsentState>;
|
|
56
|
+
/**
|
|
57
|
+
* Convenience: true iff telemetry may be emitted for this anonymous_id.
|
|
58
|
+
* Wraps `resolveConsent` for callers that only need the boolean.
|
|
59
|
+
*/
|
|
60
|
+
export declare function shouldEmitTelemetry(anonymousId: string | null | undefined): Promise<boolean>;
|
|
61
|
+
/**
|
|
62
|
+
* Invalidate the cache entry for `anonymousId`. Called by the consent page
|
|
63
|
+
* after a successful save would, in a future iteration, ping an MCP refresh
|
|
64
|
+
* endpoint — for now this is exposed for tests and for the explicit
|
|
65
|
+
* resync-on-rotate UI in the consent page.
|
|
66
|
+
*/
|
|
67
|
+
export declare function invalidateConsentCache(anonymousId?: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* Augment an existing MCP tool response with a `consent_required` envelope
|
|
70
|
+
* when the user has not yet visited the consent page.
|
|
71
|
+
*
|
|
72
|
+
* The MCP `CallToolResult` shape is `{ content: [{ type: 'text', text: <json> }] }`.
|
|
73
|
+
* We parse `text`, splice in the consent fields, and re-serialize. If parsing
|
|
74
|
+
* fails for any reason (binary content, malformed payload), we return the
|
|
75
|
+
* response untouched — telemetry consent is a soft signal and must never
|
|
76
|
+
* corrupt a successful tool result.
|
|
77
|
+
*
|
|
78
|
+
* Idempotent: calling this twice on the same response is a no-op once the
|
|
79
|
+
* fields are already present.
|
|
80
|
+
*/
|
|
81
|
+
export declare function annotateResponseWithConsent<T extends {
|
|
82
|
+
content?: unknown;
|
|
83
|
+
}>(response: T, consent: ConsentState): T;
|
|
84
|
+
/**
|
|
85
|
+
* Test-only helper. Not exported from the package index.
|
|
86
|
+
*/
|
|
87
|
+
export declare function _resetConsentCacheForTests(): void;
|
|
88
|
+
//# sourceMappingURL=telemetry-consent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-consent.d.ts","sourceRoot":"","sources":["../../../src/middleware/telemetry-consent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH;;;GAGG;AACH,eAAO,MAAM,qBAAqB,6CAA6C,CAAA;AAE/E;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAA;IACxB,uEAAuE;IACvE,UAAU,EAAE,MAAM,CAAA;CACnB;AA6ED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,CAS5F;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GACrC,OAAO,CAAC,OAAO,CAAC,CAIlB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAMjE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CAAC,CAAC,SAAS;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,EACzE,QAAQ,EAAE,CAAC,EACX,OAAO,EAAE,YAAY,GACpB,CAAC,CA8BH;AAED;;GAEG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAEjD"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry Consent Gate — SMI-5019 W2.S4
|
|
3
|
+
*
|
|
4
|
+
* For MCP-only clients (Cursor, Continue, Copilot users without a CLI install)
|
|
5
|
+
* we cannot rely on a CLI first-run prompt or a VS Code toast. Per user
|
|
6
|
+
* decision U5 in the implementation plan, the consent surface is the web
|
|
7
|
+
* dashboard at https://skillsmith.app/account/telemetry.
|
|
8
|
+
*
|
|
9
|
+
* This module supplies the MCP-side half of that flow:
|
|
10
|
+
*
|
|
11
|
+
* 1. On every tool call, resolve the calling anonymous_id's preference from
|
|
12
|
+
* `user_telemetry_preferences` (RLS-scoped via the same anon-key client
|
|
13
|
+
* used elsewhere in this package).
|
|
14
|
+
* 2. If the row is missing, signal `consent_required:true` + the privacy URL
|
|
15
|
+
* in the response envelope so the client can prompt the user to open the
|
|
16
|
+
* dashboard.
|
|
17
|
+
* 3. Cache the resolved state per process (Map keyed by anonymous_id) so
|
|
18
|
+
* repeated calls within a session don't re-query, and so two parallel
|
|
19
|
+
* calls from the same unrecognized anonymous_id observe identical state.
|
|
20
|
+
* 4. Suppress telemetry writes (consult `shouldEmitTelemetry`) for that
|
|
21
|
+
* anonymous_id until the preference resolves to `enabled:true`.
|
|
22
|
+
*
|
|
23
|
+
* SMI-5016 (`packages/core/src/telemetry/wrap.ts`) and SMI-5017 (tool /
|
|
24
|
+
* command dispatchers) are wave-sibling deliverables — this module
|
|
25
|
+
* deliberately stays out of those files.
|
|
26
|
+
*/
|
|
27
|
+
import { getSupabaseClient } from '../supabase-client.js';
|
|
28
|
+
/**
|
|
29
|
+
* Canonical absolute URL of the consent dashboard. Must remain stable across
|
|
30
|
+
* surfaces so MCP clients can deep-link to a known landing page.
|
|
31
|
+
*/
|
|
32
|
+
export const TELEMETRY_PRIVACY_URL = 'https://skillsmith.app/account/telemetry';
|
|
33
|
+
/**
|
|
34
|
+
* Per-process cache keyed by anonymous_id. We deliberately use a single shared
|
|
35
|
+
* Map so two parallel `withConsentGate` invocations for the same
|
|
36
|
+
* anonymous_id observe identical state — the constraint flagged in the spec.
|
|
37
|
+
*
|
|
38
|
+
* Stored value is a Promise (not the resolved ConsentState) so concurrent
|
|
39
|
+
* lookups share one in-flight Supabase query.
|
|
40
|
+
*/
|
|
41
|
+
const consentCache = new Map();
|
|
42
|
+
const DEFAULT_CONSENT_REQUIRED = {
|
|
43
|
+
enabled: false,
|
|
44
|
+
consentRequired: true,
|
|
45
|
+
privacyUrl: TELEMETRY_PRIVACY_URL,
|
|
46
|
+
};
|
|
47
|
+
const DEFAULT_NO_ID = {
|
|
48
|
+
enabled: false,
|
|
49
|
+
consentRequired: false,
|
|
50
|
+
privacyUrl: TELEMETRY_PRIVACY_URL,
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Look up the consent row for `anonymousId` and translate it into a
|
|
54
|
+
* `ConsentState`. Falls back to "consent required" on any error so we never
|
|
55
|
+
* silently emit telemetry from an unknown identity.
|
|
56
|
+
*/
|
|
57
|
+
async function fetchConsentState(anonymousId) {
|
|
58
|
+
let client;
|
|
59
|
+
try {
|
|
60
|
+
client = (await getSupabaseClient());
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Supabase isn't configured in this environment (e.g. offline CLI run);
|
|
64
|
+
// safest interpretation is "no consent → no emit" but also "no need to
|
|
65
|
+
// prompt the user" because the network surface isn't reachable anyway.
|
|
66
|
+
return { ...DEFAULT_NO_ID };
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const { data, error } = await client
|
|
70
|
+
.from('user_telemetry_preferences')
|
|
71
|
+
.select('enabled')
|
|
72
|
+
.eq('anonymous_id', anonymousId)
|
|
73
|
+
.maybeSingle();
|
|
74
|
+
if (error || !data) {
|
|
75
|
+
return { ...DEFAULT_CONSENT_REQUIRED };
|
|
76
|
+
}
|
|
77
|
+
return {
|
|
78
|
+
enabled: data.enabled === true,
|
|
79
|
+
consentRequired: false,
|
|
80
|
+
privacyUrl: TELEMETRY_PRIVACY_URL,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return { ...DEFAULT_CONSENT_REQUIRED };
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Resolve the consent state for `anonymousId`, caching the result for the
|
|
89
|
+
* lifetime of the process. Concurrent calls share one in-flight query.
|
|
90
|
+
*
|
|
91
|
+
* Passing `null`/`undefined`/empty triggers the no-id branch — telemetry is
|
|
92
|
+
* suppressed but no prompt is shown (there's nothing to link the user's
|
|
93
|
+
* eventual web-dashboard choice back to).
|
|
94
|
+
*/
|
|
95
|
+
export function resolveConsent(anonymousId) {
|
|
96
|
+
if (!anonymousId) {
|
|
97
|
+
return Promise.resolve({ ...DEFAULT_NO_ID });
|
|
98
|
+
}
|
|
99
|
+
const cached = consentCache.get(anonymousId);
|
|
100
|
+
if (cached)
|
|
101
|
+
return cached;
|
|
102
|
+
const promise = fetchConsentState(anonymousId);
|
|
103
|
+
consentCache.set(anonymousId, promise);
|
|
104
|
+
return promise;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Convenience: true iff telemetry may be emitted for this anonymous_id.
|
|
108
|
+
* Wraps `resolveConsent` for callers that only need the boolean.
|
|
109
|
+
*/
|
|
110
|
+
export async function shouldEmitTelemetry(anonymousId) {
|
|
111
|
+
if (!anonymousId)
|
|
112
|
+
return false;
|
|
113
|
+
const state = await resolveConsent(anonymousId);
|
|
114
|
+
return state.enabled;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Invalidate the cache entry for `anonymousId`. Called by the consent page
|
|
118
|
+
* after a successful save would, in a future iteration, ping an MCP refresh
|
|
119
|
+
* endpoint — for now this is exposed for tests and for the explicit
|
|
120
|
+
* resync-on-rotate UI in the consent page.
|
|
121
|
+
*/
|
|
122
|
+
export function invalidateConsentCache(anonymousId) {
|
|
123
|
+
if (anonymousId === undefined) {
|
|
124
|
+
consentCache.clear();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
consentCache.delete(anonymousId);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Augment an existing MCP tool response with a `consent_required` envelope
|
|
131
|
+
* when the user has not yet visited the consent page.
|
|
132
|
+
*
|
|
133
|
+
* The MCP `CallToolResult` shape is `{ content: [{ type: 'text', text: <json> }] }`.
|
|
134
|
+
* We parse `text`, splice in the consent fields, and re-serialize. If parsing
|
|
135
|
+
* fails for any reason (binary content, malformed payload), we return the
|
|
136
|
+
* response untouched — telemetry consent is a soft signal and must never
|
|
137
|
+
* corrupt a successful tool result.
|
|
138
|
+
*
|
|
139
|
+
* Idempotent: calling this twice on the same response is a no-op once the
|
|
140
|
+
* fields are already present.
|
|
141
|
+
*/
|
|
142
|
+
export function annotateResponseWithConsent(response, consent) {
|
|
143
|
+
if (!consent.consentRequired)
|
|
144
|
+
return response;
|
|
145
|
+
const content = response.content;
|
|
146
|
+
if (!Array.isArray(content) || content.length === 0)
|
|
147
|
+
return response;
|
|
148
|
+
const first = content[0];
|
|
149
|
+
if (!first || first.type !== 'text' || typeof first.text !== 'string')
|
|
150
|
+
return response;
|
|
151
|
+
let parsed;
|
|
152
|
+
try {
|
|
153
|
+
parsed = JSON.parse(first.text);
|
|
154
|
+
}
|
|
155
|
+
catch {
|
|
156
|
+
return response;
|
|
157
|
+
}
|
|
158
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
159
|
+
return response;
|
|
160
|
+
}
|
|
161
|
+
const annotated = parsed;
|
|
162
|
+
// Idempotency: if the caller has already added these, leave them alone.
|
|
163
|
+
if ('consent_required' in annotated && 'privacy_url' in annotated)
|
|
164
|
+
return response;
|
|
165
|
+
annotated.consent_required = true;
|
|
166
|
+
annotated.privacy_url = consent.privacyUrl;
|
|
167
|
+
const nextContent = [...content];
|
|
168
|
+
nextContent[0] = { ...first, text: JSON.stringify(annotated, null, 2) };
|
|
169
|
+
return { ...response, content: nextContent };
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Test-only helper. Not exported from the package index.
|
|
173
|
+
*/
|
|
174
|
+
export function _resetConsentCacheForTests() {
|
|
175
|
+
consentCache.clear();
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=telemetry-consent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-consent.js","sourceRoot":"","sources":["../../../src/middleware/telemetry-consent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for the telemetry consent gate — SMI-5019 W2
|
|
3
|
+
*
|
|
4
|
+
* Mocking style matches analytics.supabase.service.test.ts:
|
|
5
|
+
* vi.mock('../supabase-client.js') at module scope, then
|
|
6
|
+
* vi.mocked(getSupabaseClient).mockResolvedValue / mockRejectedValue per test.
|
|
7
|
+
*
|
|
8
|
+
* `_resetConsentCacheForTests()` is called in beforeEach so every test starts
|
|
9
|
+
* with an empty process-level cache.
|
|
10
|
+
*/
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=telemetry-consent.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry-consent.test.d.ts","sourceRoot":"","sources":["../../../src/middleware/telemetry-consent.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG"}
|