@skillsmith/core 0.11.4 → 0.11.6
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 +60 -0
- package/README.md +10 -7
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/api/client.d.ts.map +1 -1
- package/dist/src/api/client.js +20 -5
- package/dist/src/api/client.js.map +1 -1
- package/dist/src/api/client.private-registry.d.ts +80 -0
- package/dist/src/api/client.private-registry.d.ts.map +1 -0
- package/dist/src/api/client.private-registry.js +97 -0
- package/dist/src/api/client.private-registry.js.map +1 -0
- package/dist/src/api/client.private-registry.test.d.ts +9 -0
- package/dist/src/api/client.private-registry.test.d.ts.map +1 -0
- package/dist/src/api/client.private-registry.test.js +127 -0
- package/dist/src/api/client.private-registry.test.js.map +1 -0
- package/dist/src/api/client.test.js +39 -0
- package/dist/src/api/client.test.js.map +1 -1
- package/dist/src/api/client.toSkill.test.d.ts +25 -0
- package/dist/src/api/client.toSkill.test.d.ts.map +1 -0
- package/dist/src/api/client.toSkill.test.js +97 -0
- package/dist/src/api/client.toSkill.test.js.map +1 -0
- package/dist/src/api/client.token-refresh.d.ts +8 -0
- package/dist/src/api/client.token-refresh.d.ts.map +1 -1
- package/dist/src/api/client.token-refresh.js +26 -0
- package/dist/src/api/client.token-refresh.js.map +1 -1
- package/dist/src/api/client.token-refresh.test.js +82 -0
- package/dist/src/api/client.token-refresh.test.js.map +1 -1
- package/dist/src/api/index.d.ts +2 -0
- package/dist/src/api/index.d.ts.map +1 -1
- package/dist/src/api/index.js +9 -0
- package/dist/src/api/index.js.map +1 -1
- package/dist/src/api/security-summary.d.ts +73 -0
- package/dist/src/api/security-summary.d.ts.map +1 -0
- package/dist/src/api/security-summary.js +88 -0
- package/dist/src/api/security-summary.js.map +1 -0
- package/dist/src/api/security-summary.test.d.ts +9 -0
- package/dist/src/api/security-summary.test.d.ts.map +1 -0
- package/dist/src/api/security-summary.test.js +94 -0
- package/dist/src/api/security-summary.test.js.map +1 -0
- package/dist/src/compatibility/slugs.d.ts +7 -3
- package/dist/src/compatibility/slugs.d.ts.map +1 -1
- package/dist/src/compatibility/slugs.js +11 -4
- package/dist/src/compatibility/slugs.js.map +1 -1
- package/dist/src/config/config-atomic-write.d.ts +30 -10
- package/dist/src/config/config-atomic-write.d.ts.map +1 -1
- package/dist/src/config/config-atomic-write.js +33 -80
- package/dist/src/config/config-atomic-write.js.map +1 -1
- package/dist/src/config/config-atomic-write.test.d.ts +8 -0
- package/dist/src/config/config-atomic-write.test.d.ts.map +1 -1
- package/dist/src/config/config-atomic-write.test.js +64 -12
- package/dist/src/config/config-atomic-write.test.js.map +1 -1
- package/dist/src/config/owned-lock.acquire.d.ts +53 -0
- package/dist/src/config/owned-lock.acquire.d.ts.map +1 -0
- package/dist/src/config/owned-lock.acquire.js +140 -0
- package/dist/src/config/owned-lock.acquire.js.map +1 -0
- package/dist/src/config/owned-lock.claim.d.ts +84 -0
- package/dist/src/config/owned-lock.claim.d.ts.map +1 -0
- package/dist/src/config/owned-lock.claim.js +310 -0
- package/dist/src/config/owned-lock.claim.js.map +1 -0
- package/dist/src/config/owned-lock.d.ts +113 -0
- package/dist/src/config/owned-lock.d.ts.map +1 -0
- package/dist/src/config/owned-lock.js +121 -0
- package/dist/src/config/owned-lock.js.map +1 -0
- package/dist/src/config/owned-lock.test.d.ts +12 -0
- package/dist/src/config/owned-lock.test.d.ts.map +1 -0
- package/dist/src/config/owned-lock.test.js +412 -0
- package/dist/src/config/owned-lock.test.js.map +1 -0
- package/dist/src/config/owned-lock.types.d.ts +78 -0
- package/dist/src/config/owned-lock.types.d.ts.map +1 -0
- package/dist/src/config/owned-lock.types.js +30 -0
- package/dist/src/config/owned-lock.types.js.map +1 -0
- package/dist/src/db/createDatabase.d.ts.map +1 -1
- package/dist/src/db/createDatabase.js +19 -7
- package/dist/src/db/createDatabase.js.map +1 -1
- package/dist/src/db/drivers/sqljsDriver.d.ts +8 -0
- package/dist/src/db/drivers/sqljsDriver.d.ts.map +1 -1
- package/dist/src/db/drivers/sqljsDriver.js +24 -2
- package/dist/src/db/drivers/sqljsDriver.js.map +1 -1
- package/dist/src/db/migration-runner.d.ts.map +1 -1
- package/dist/src/db/migration-runner.js +23 -2
- package/dist/src/db/migration-runner.js.map +1 -1
- package/dist/src/db/schema.d.ts.map +1 -1
- package/dist/src/db/schema.js +29 -3
- package/dist/src/db/schema.js.map +1 -1
- package/dist/src/embeddings/hnsw-store.exports.d.ts +11 -0
- package/dist/src/embeddings/hnsw-store.exports.d.ts.map +1 -0
- package/dist/src/embeddings/hnsw-store.exports.js +10 -0
- package/dist/src/embeddings/hnsw-store.exports.js.map +1 -0
- package/dist/src/embeddings/index.d.ts +1 -2
- package/dist/src/embeddings/index.d.ts.map +1 -1
- package/dist/src/embeddings/index.js +17 -3
- package/dist/src/embeddings/index.js.map +1 -1
- package/dist/src/embeddings/probe.d.ts.map +1 -1
- package/dist/src/embeddings/probe.js +4 -8
- package/dist/src/embeddings/probe.js.map +1 -1
- package/dist/src/exports/services.d.ts +5 -1
- package/dist/src/exports/services.d.ts.map +1 -1
- package/dist/src/exports/services.js +27 -0
- package/dist/src/exports/services.js.map +1 -1
- package/dist/src/index.d.ts +3 -3
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +9 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/install/index.d.ts +2 -2
- package/dist/src/install/index.d.ts.map +1 -1
- package/dist/src/install/index.js +1 -1
- package/dist/src/install/index.js.map +1 -1
- package/dist/src/install/paths.d.ts +165 -1
- package/dist/src/install/paths.d.ts.map +1 -1
- package/dist/src/install/paths.js +254 -1
- package/dist/src/install/paths.js.map +1 -1
- package/dist/src/install/paths.test.js +174 -2
- package/dist/src/install/paths.test.js.map +1 -1
- package/dist/src/security/scanner/multiline-category-closure.test.d.ts +80 -0
- package/dist/src/security/scanner/multiline-category-closure.test.d.ts.map +1 -0
- package/dist/src/security/scanner/multiline-category-closure.test.js +287 -0
- package/dist/src/security/scanner/multiline-category-closure.test.js.map +1 -0
- package/dist/src/services/context-words.d.ts +40 -0
- package/dist/src/services/context-words.d.ts.map +1 -0
- package/dist/src/services/context-words.js +178 -0
- package/dist/src/services/context-words.js.map +1 -0
- package/dist/src/services/context-words.test.d.ts +2 -0
- package/dist/src/services/context-words.test.d.ts.map +1 -0
- package/dist/src/services/context-words.test.js +94 -0
- package/dist/src/services/context-words.test.js.map +1 -0
- package/dist/src/services/recommend-guard.d.ts +28 -0
- package/dist/src/services/recommend-guard.d.ts.map +1 -0
- package/dist/src/services/recommend-guard.js +34 -0
- package/dist/src/services/recommend-guard.js.map +1 -0
- package/dist/src/services/recommend-guard.test.d.ts +2 -0
- package/dist/src/services/recommend-guard.test.d.ts.map +1 -0
- package/dist/src/services/recommend-guard.test.js +28 -0
- package/dist/src/services/recommend-guard.test.js.map +1 -0
- package/dist/src/services/skill-installation.content.d.ts +96 -0
- package/dist/src/services/skill-installation.content.d.ts.map +1 -0
- package/dist/src/services/skill-installation.content.js +319 -0
- package/dist/src/services/skill-installation.content.js.map +1 -0
- package/dist/src/services/skill-installation.helpers.d.ts +32 -1
- package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
- package/dist/src/services/skill-installation.helpers.js +62 -7
- package/dist/src/services/skill-installation.helpers.js.map +1 -1
- package/dist/src/services/skill-installation.helpers.test.js +108 -2
- package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
- package/dist/src/services/skill-installation.io.d.ts +22 -1
- package/dist/src/services/skill-installation.io.d.ts.map +1 -1
- package/dist/src/services/skill-installation.io.js +110 -6
- package/dist/src/services/skill-installation.io.js.map +1 -1
- package/dist/src/services/skill-installation.service.d.ts +22 -1
- package/dist/src/services/skill-installation.service.d.ts.map +1 -1
- package/dist/src/services/skill-installation.service.js +30 -5
- package/dist/src/services/skill-installation.service.js.map +1 -1
- package/dist/src/services/skill-installation.types.d.ts +42 -1
- package/dist/src/services/skill-installation.types.d.ts.map +1 -1
- package/dist/src/services/skill-installation.types.js.map +1 -1
- package/dist/src/services/skill-manifest.d.ts +21 -0
- package/dist/src/services/skill-manifest.d.ts.map +1 -1
- package/dist/src/services/skill-manifest.js +51 -6
- package/dist/src/services/skill-manifest.js.map +1 -1
- package/dist/src/services/skill-manifest.test.d.ts +2 -0
- package/dist/src/services/skill-manifest.test.d.ts.map +1 -0
- package/dist/src/services/skill-manifest.test.js +202 -0
- package/dist/src/services/skill-manifest.test.js.map +1 -0
- package/dist/src/services/skill-resolution.d.ts +67 -0
- package/dist/src/services/skill-resolution.d.ts.map +1 -0
- package/dist/src/services/skill-resolution.js +67 -0
- package/dist/src/services/skill-resolution.js.map +1 -0
- package/dist/src/services/skill-resolution.test.d.ts +2 -0
- package/dist/src/services/skill-resolution.test.d.ts.map +1 -0
- package/dist/src/services/skill-resolution.test.js +143 -0
- package/dist/src/services/skill-resolution.test.js.map +1 -0
- package/dist/src/types/skill.d.ts +10 -0
- package/dist/src/types/skill.d.ts.map +1 -1
- package/dist/src/types.d.ts +9 -5
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/index.d.ts.map +1 -1
- package/dist/src/utils/index.js +4 -0
- package/dist/src/utils/index.js.map +1 -1
- package/dist/src/utils/quiet-mode.d.ts +21 -0
- package/dist/src/utils/quiet-mode.d.ts.map +1 -0
- package/dist/src/utils/quiet-mode.js +26 -0
- package/dist/src/utils/quiet-mode.js.map +1 -0
- package/dist/tests/EmbeddingService.test.js +58 -1
- package/dist/tests/EmbeddingService.test.js.map +1 -1
- package/dist/tests/SecurityScanner.performance.test.js +5 -2
- package/dist/tests/SecurityScanner.performance.test.js.map +1 -1
- package/dist/tests/db/database-abstraction.test.js +45 -1
- package/dist/tests/db/database-abstraction.test.js.map +1 -1
- package/dist/tests/db/migration-runner-race.test.d.ts +2 -0
- package/dist/tests/db/migration-runner-race.test.d.ts.map +1 -0
- package/dist/tests/db/migration-runner-race.test.js +75 -0
- package/dist/tests/db/migration-runner-race.test.js.map +1 -0
- package/dist/tests/db/schema-async.test.js +37 -1
- package/dist/tests/db/schema-async.test.js.map +1 -1
- package/dist/tests/db/sqljsDriver.test.js +63 -1
- package/dist/tests/db/sqljsDriver.test.js.map +1 -1
- package/dist/tests/helpers/deterministic-dead-pid.d.ts +13 -0
- package/dist/tests/helpers/deterministic-dead-pid.d.ts.map +1 -0
- package/dist/tests/helpers/deterministic-dead-pid.js +31 -0
- package/dist/tests/helpers/deterministic-dead-pid.js.map +1 -0
- package/dist/tests/integration/owned-lock-lost-update.test.d.ts +12 -0
- package/dist/tests/integration/owned-lock-lost-update.test.d.ts.map +1 -0
- package/dist/tests/integration/owned-lock-lost-update.test.js +52 -0
- package/dist/tests/integration/owned-lock-lost-update.test.js.map +1 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts +19 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts.map +1 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.js +177 -0
- package/dist/tests/integration/owned-lock-reclaim-race.test.js.map +1 -0
- package/dist/tests/schema.test.js +43 -1
- package/dist/tests/schema.test.js.map +1 -1
- package/dist/tests/unit/services/skill-installation.content.test.d.ts +10 -0
- package/dist/tests/unit/services/skill-installation.content.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.content.test.js +290 -0
- package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.d.ts +34 -0
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js +246 -0
- package/dist/tests/unit/services/skill-installation.io.client-agent-path.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts +8 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.js +72 -0
- package/dist/tests/unit/services/skill-installation.io.symlink.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.d.ts +17 -0
- package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.js +112 -0
- package/dist/tests/unit/services/skill-installation.service.companion-basedir.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts +15 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js +190 -0
- package/dist/tests/unit/services/skill-installation.service.error-codes.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts +17 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.js +126 -0
- package/dist/tests/unit/services/skill-installation.service.multi-client.test.js.map +1 -0
- package/dist/tests/unit/services/skill-installation.service.test.js +7 -112
- package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
- package/dist/tests/utils/quiet-mode.test.d.ts +12 -0
- package/dist/tests/utils/quiet-mode.test.d.ts.map +1 -0
- package/dist/tests/utils/quiet-mode.test.js +42 -0
- package/dist/tests/utils/quiet-mode.test.js.map +1 -0
- package/package.json +17 -5
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5897 (C-15): Unit coverage for `SkillsmithApiClient.toSkill()`'s
|
|
3
|
+
* security-status field derivation.
|
|
4
|
+
*
|
|
5
|
+
* Previously `toSkill()` hardcoded `riskScore: null, securityFindingsCount: 0,
|
|
6
|
+
* securityScannedAt: null, securityPassed: null` for every API-sourced skill,
|
|
7
|
+
* discarding the real `security_score`/`quarantined`/`last_scanned_at`/
|
|
8
|
+
* `security_findings` fields already present on the `ApiSearchResult` it
|
|
9
|
+
* received — this is why CLI `info`/`search` (which both route through
|
|
10
|
+
* `toSkill()`) could show "Not scanned" for a skill MCP correctly reported
|
|
11
|
+
* as passed. `toSkill()` now derives these fields via the same shared
|
|
12
|
+
* `deriveSecuritySummaryFromApiSkill()` MCP's tools use, so the two surfaces
|
|
13
|
+
* can't re-diverge (see `api/security-summary.test.ts` for derivation-logic
|
|
14
|
+
* coverage — this file only asserts `toSkill()` wires it through correctly).
|
|
15
|
+
*
|
|
16
|
+
* SMI-5897 (Wave 4 fix): imports `ApiSearchResult` from `./client.types.js` —
|
|
17
|
+
* `toSkill()`'s ACTUAL parameter type — not `./types.js`, which declares a
|
|
18
|
+
* different, same-named type (a pre-existing naming collision elsewhere in
|
|
19
|
+
* this codebase, not something fixed globally here). Importing the wrong
|
|
20
|
+
* type, combined with the `as ApiSearchResult` cast this fix also removes,
|
|
21
|
+
* meant the fixture below was never actually type-checked against
|
|
22
|
+
* `toSkill()`'s real input contract.
|
|
23
|
+
*/
|
|
24
|
+
import { describe, it, expect } from 'vitest';
|
|
25
|
+
import { SkillsmithApiClient } from './client.js';
|
|
26
|
+
function makeApiSearchResult(overrides = {}) {
|
|
27
|
+
return {
|
|
28
|
+
id: 'skill-1',
|
|
29
|
+
name: 'commit',
|
|
30
|
+
description: 'A commit skill',
|
|
31
|
+
author: 'anthropic',
|
|
32
|
+
repo_url: 'https://github.com/anthropic/commit',
|
|
33
|
+
quality_score: 90,
|
|
34
|
+
trust_tier: 'verified',
|
|
35
|
+
tags: ['git'],
|
|
36
|
+
stars: 10,
|
|
37
|
+
created_at: '2026-01-01T00:00:00.000Z',
|
|
38
|
+
updated_at: '2026-01-02T00:00:00.000Z',
|
|
39
|
+
installable: true,
|
|
40
|
+
...overrides,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
describe('SkillsmithApiClient.toSkill() — security field derivation (SMI-5897 C-15)', () => {
|
|
44
|
+
it('reports "not scanned" (all-null security fields) when last_scanned_at is null', () => {
|
|
45
|
+
const result = makeApiSearchResult({
|
|
46
|
+
last_scanned_at: null,
|
|
47
|
+
quarantined: false,
|
|
48
|
+
security_score: null,
|
|
49
|
+
security_findings: null,
|
|
50
|
+
});
|
|
51
|
+
const skill = SkillsmithApiClient.toSkill(result);
|
|
52
|
+
expect(skill.securityScannedAt).toBeNull();
|
|
53
|
+
expect(skill.securityPassed).toBeNull();
|
|
54
|
+
expect(skill.riskScore).toBeNull();
|
|
55
|
+
expect(skill.securityFindingsCount).toBe(0);
|
|
56
|
+
});
|
|
57
|
+
it('reports a real passing scan status instead of a hardcoded "not scanned"', () => {
|
|
58
|
+
const result = makeApiSearchResult({
|
|
59
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
60
|
+
quarantined: false,
|
|
61
|
+
security_score: 0,
|
|
62
|
+
security_findings: [],
|
|
63
|
+
});
|
|
64
|
+
const skill = SkillsmithApiClient.toSkill(result);
|
|
65
|
+
// Pre-fix this was unconditionally { securityPassed: null, ... } —
|
|
66
|
+
// the exact CLI/MCP status-mismatch bug (C-15).
|
|
67
|
+
expect(skill.securityPassed).toBe(true);
|
|
68
|
+
expect(skill.securityScannedAt).toBe('2026-06-01T00:00:00.000Z');
|
|
69
|
+
expect(skill.riskScore).toBe(0);
|
|
70
|
+
expect(skill.securityFindingsCount).toBe(0);
|
|
71
|
+
});
|
|
72
|
+
it('reports a failing scan status (quarantined) instead of a hardcoded "not scanned"', () => {
|
|
73
|
+
const result = makeApiSearchResult({
|
|
74
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
75
|
+
quarantined: true,
|
|
76
|
+
security_score: 10,
|
|
77
|
+
security_findings: [{ rule: 'a' }, { rule: 'b' }],
|
|
78
|
+
});
|
|
79
|
+
const skill = SkillsmithApiClient.toSkill(result);
|
|
80
|
+
expect(skill.securityPassed).toBe(false);
|
|
81
|
+
expect(skill.securityFindingsCount).toBe(2);
|
|
82
|
+
expect(skill.riskScore).toBe(10);
|
|
83
|
+
});
|
|
84
|
+
it('preserves riskScore: null (never fabricates 0) for a scanned-but-unscored skill', () => {
|
|
85
|
+
const result = makeApiSearchResult({
|
|
86
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
87
|
+
quarantined: false,
|
|
88
|
+
security_score: null,
|
|
89
|
+
security_findings: null,
|
|
90
|
+
});
|
|
91
|
+
const skill = SkillsmithApiClient.toSkill(result);
|
|
92
|
+
expect(skill.securityPassed).toBeNull();
|
|
93
|
+
expect(skill.riskScore).toBeNull();
|
|
94
|
+
expect(skill.securityScannedAt).toBe('2026-06-01T00:00:00.000Z');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
//# sourceMappingURL=client.toSkill.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.toSkill.test.js","sourceRoot":"","sources":["../../../src/api/client.toSkill.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
export declare function tryRefreshToken(): Promise<string | null>;
|
|
2
2
|
export declare function loadStoredAccessToken(): Promise<string | null>;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve the signed-in user's Supabase access token, refreshing it if it has
|
|
5
|
+
* expired (or is within `TOKEN_EXPIRY_SKEW_MS` of expiring).
|
|
6
|
+
*
|
|
7
|
+
* @returns the access token, or null when no credentials are stored on this
|
|
8
|
+
* machine (or the stored refresh token is no longer valid).
|
|
9
|
+
*/
|
|
10
|
+
export declare function resolveFreshAccessToken(): Promise<string | null>;
|
|
3
11
|
//# sourceMappingURL=client.token-refresh.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.token-refresh.d.ts","sourceRoot":"","sources":["../../../src/api/client.token-refresh.ts"],"names":[],"mappings":"AAOA,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS9D;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIpE"}
|
|
1
|
+
{"version":3,"file":"client.token-refresh.d.ts","sourceRoot":"","sources":["../../../src/api/client.token-refresh.ts"],"names":[],"mappings":"AAOA,wBAAsB,eAAe,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAS9D;AAED,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIpE;AAcD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAKtE"}
|
|
@@ -16,4 +16,30 @@ export async function loadStoredAccessToken() {
|
|
|
16
16
|
return null;
|
|
17
17
|
return creds.accessToken;
|
|
18
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* SMI-5905 Wave 1: refresh a token this many ms before its recorded expiry.
|
|
21
|
+
*
|
|
22
|
+
* Extracted from `packages/mcp-server/src/tools/team-resolver.ts`'s
|
|
23
|
+
* `resolveUserAccessToken()` (originally SMI-4292) so a 2nd consumer (the
|
|
24
|
+
* CLI, via a future private-registry command) can resolve "the signed-in
|
|
25
|
+
* user's fresh access token" without depending on mcp-server. team-resolver.ts
|
|
26
|
+
* now delegates to `resolveFreshAccessToken()` below — same skew constant,
|
|
27
|
+
* same refresh-or-null fallback, no behavior change for its existing callers.
|
|
28
|
+
*/
|
|
29
|
+
const TOKEN_EXPIRY_SKEW_MS = 60_000;
|
|
30
|
+
/**
|
|
31
|
+
* Resolve the signed-in user's Supabase access token, refreshing it if it has
|
|
32
|
+
* expired (or is within `TOKEN_EXPIRY_SKEW_MS` of expiring).
|
|
33
|
+
*
|
|
34
|
+
* @returns the access token, or null when no credentials are stored on this
|
|
35
|
+
* machine (or the stored refresh token is no longer valid).
|
|
36
|
+
*/
|
|
37
|
+
export async function resolveFreshAccessToken() {
|
|
38
|
+
const creds = await loadCredentials();
|
|
39
|
+
if (!creds)
|
|
40
|
+
return null;
|
|
41
|
+
if (Date.now() < creds.expiresAt - TOKEN_EXPIRY_SKEW_MS)
|
|
42
|
+
return creds.accessToken;
|
|
43
|
+
return tryRefreshToken();
|
|
44
|
+
}
|
|
19
45
|
//# sourceMappingURL=client.token-refresh.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.token-refresh.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,gCAAgC,CAAA;AAEvC,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IAEvB,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC9D,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IAE3B,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAA;IACjC,OAAO,SAAS,CAAC,WAAW,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,WAAW,CAAA;AAC1B,CAAC"}
|
|
1
|
+
{"version":3,"file":"client.token-refresh.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,gCAAgC,CAAA;AAEvC,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IAEvB,MAAM,SAAS,GAAG,MAAM,kBAAkB,CAAC,KAAK,CAAC,YAAY,CAAC,CAAA;IAC9D,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAA;IAE3B,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAA;IACjC,OAAO,SAAS,CAAC,WAAW,CAAA;AAC9B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,OAAO,KAAK,CAAC,WAAW,CAAA;AAC1B,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,oBAAoB,GAAG,MAAM,CAAA;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB;IAC3C,MAAM,KAAK,GAAG,MAAM,eAAe,EAAE,CAAA;IACrC,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAA;IACvB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,SAAS,GAAG,oBAAoB;QAAE,OAAO,KAAK,CAAC,WAAW,CAAA;IACjF,OAAO,eAAe,EAAE,CAAA;AAC1B,CAAC"}
|
|
@@ -70,4 +70,86 @@ describe('client.token-refresh', () => {
|
|
|
70
70
|
expect(result).toBeNull();
|
|
71
71
|
});
|
|
72
72
|
});
|
|
73
|
+
// SMI-5905 Wave 1: resolveFreshAccessToken() — extracted from team-resolver.ts's
|
|
74
|
+
// resolveUserAccessToken() (TOKEN_EXPIRY_SKEW_MS=60s). team-resolver.ts now delegates to this
|
|
75
|
+
// function unchanged, so these cases are the authoritative coverage for the skew logic.
|
|
76
|
+
describe('resolveFreshAccessToken (SMI-5905)', () => {
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
vi.clearAllMocks();
|
|
79
|
+
});
|
|
80
|
+
it('RFT-1: returns accessToken directly when well within expiry (no refresh)', async () => {
|
|
81
|
+
const { loadCredentials, refreshAccessToken } = await import('../config/token-credentials.js');
|
|
82
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
83
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
84
|
+
accessToken: 'fresh_at',
|
|
85
|
+
refreshToken: 'fresh_rt',
|
|
86
|
+
expiresAt: Date.now() + 3_600_000, // 1h out — far outside the 60s skew window
|
|
87
|
+
version: 2,
|
|
88
|
+
});
|
|
89
|
+
const result = await resolveFreshAccessToken();
|
|
90
|
+
expect(result).toBe('fresh_at');
|
|
91
|
+
expect(refreshAccessToken).not.toHaveBeenCalled();
|
|
92
|
+
});
|
|
93
|
+
it('RFT-2: returns null when no credentials are stored (no refresh attempted)', async () => {
|
|
94
|
+
const { loadCredentials, refreshAccessToken } = await import('../config/token-credentials.js');
|
|
95
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
96
|
+
vi.mocked(loadCredentials).mockResolvedValue(null);
|
|
97
|
+
const result = await resolveFreshAccessToken();
|
|
98
|
+
expect(result).toBeNull();
|
|
99
|
+
expect(refreshAccessToken).not.toHaveBeenCalled();
|
|
100
|
+
});
|
|
101
|
+
it('RFT-3: expiry-skew boundary — refreshes within the 60s skew window', async () => {
|
|
102
|
+
const { loadCredentials, refreshAccessToken, storeCredentials } = await import('../config/token-credentials.js');
|
|
103
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
104
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
105
|
+
accessToken: 'about_to_expire_at',
|
|
106
|
+
refreshToken: 'still_valid_rt',
|
|
107
|
+
expiresAt: Date.now() + 30_000, // 30s out — inside the 60s skew window
|
|
108
|
+
version: 2,
|
|
109
|
+
});
|
|
110
|
+
vi.mocked(refreshAccessToken).mockResolvedValue({
|
|
111
|
+
accessToken: 'refreshed_at',
|
|
112
|
+
refreshToken: 'refreshed_rt',
|
|
113
|
+
expiresAt: Date.now() + 3_600_000,
|
|
114
|
+
version: 2,
|
|
115
|
+
});
|
|
116
|
+
vi.mocked(storeCredentials).mockResolvedValue(undefined);
|
|
117
|
+
const result = await resolveFreshAccessToken();
|
|
118
|
+
expect(result).toBe('refreshed_at');
|
|
119
|
+
expect(refreshAccessToken).toHaveBeenCalledWith('still_valid_rt');
|
|
120
|
+
expect(storeCredentials).toHaveBeenCalledWith(expect.objectContaining({ accessToken: 'refreshed_at' }));
|
|
121
|
+
});
|
|
122
|
+
it('RFT-4: an already-expired token also refreshes (not just the skew window)', async () => {
|
|
123
|
+
const { loadCredentials, refreshAccessToken, storeCredentials } = await import('../config/token-credentials.js');
|
|
124
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
125
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
126
|
+
accessToken: 'expired_at',
|
|
127
|
+
refreshToken: 'expired_rt',
|
|
128
|
+
expiresAt: Date.now() - 1_000,
|
|
129
|
+
version: 2,
|
|
130
|
+
});
|
|
131
|
+
vi.mocked(refreshAccessToken).mockResolvedValue({
|
|
132
|
+
accessToken: 'new_at',
|
|
133
|
+
refreshToken: 'new_rt',
|
|
134
|
+
expiresAt: Date.now() + 3_600_000,
|
|
135
|
+
version: 2,
|
|
136
|
+
});
|
|
137
|
+
vi.mocked(storeCredentials).mockResolvedValue(undefined);
|
|
138
|
+
const result = await resolveFreshAccessToken();
|
|
139
|
+
expect(result).toBe('new_at');
|
|
140
|
+
});
|
|
141
|
+
it('RFT-5: returns null when the refresh token itself is no longer valid', async () => {
|
|
142
|
+
const { loadCredentials, refreshAccessToken } = await import('../config/token-credentials.js');
|
|
143
|
+
const { resolveFreshAccessToken } = await import('./client.token-refresh.js');
|
|
144
|
+
vi.mocked(loadCredentials).mockResolvedValue({
|
|
145
|
+
accessToken: 'about_to_expire_at',
|
|
146
|
+
refreshToken: 'dead_rt',
|
|
147
|
+
expiresAt: Date.now() + 30_000,
|
|
148
|
+
version: 2,
|
|
149
|
+
});
|
|
150
|
+
vi.mocked(refreshAccessToken).mockResolvedValue(null);
|
|
151
|
+
const result = await resolveFreshAccessToken();
|
|
152
|
+
expect(result).toBeNull();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
73
155
|
//# sourceMappingURL=client.token-refresh.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.token-refresh.test.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.test.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.token-refresh.test.js","sourceRoot":"","sources":["../../../src/api/client.token-refresh.test.ts"],"names":[],"mappings":"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"}
|
package/dist/src/api/index.d.ts
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
* SMI-1300: API types matching OpenAPI spec
|
|
8
8
|
*/
|
|
9
9
|
export { SkillsmithApiClient, createApiClient, generateAnonymousId, ApiClientError, type ApiClientConfig, type ApiResponse, type ApiErrorResponse, type ApiSearchResult, type RecommendationRequest, type TelemetryEvent, } from './client.js';
|
|
10
|
+
export { getPrivateRegistrySkillContent, type PrivateRegistrySkillContent, type PrivateRegistryGetErrorCode, type PrivateRegistryGetResult, type GetPrivateRegistrySkillContentParams, } from './client.private-registry.js';
|
|
10
11
|
export { EventBatcher, createEventBatcher, type EventBatcherOptions, type BatchFlushFn, } from './event-batcher.js';
|
|
12
|
+
export { deriveSecuritySummaryFromApiSkill, deriveSecuritySummaryFromSkillRow, } from './security-summary.js';
|
|
11
13
|
export { ApiCache, createCache, getGlobalCache, DEFAULT_TTL, type CacheConfig, type CacheStats, } from './cache.js';
|
|
12
14
|
export { API_TRUST_TIERS, API_CATEGORIES } from './types.js';
|
|
13
15
|
export type { ApiTrustTier, ApiCategory, ApiProjectType, ApiSkill, ApiSearchResult as OpenApiSearchResult, RecommendedSkill, SearchParams, SearchResponse, SearchResponseMeta, RecommendParams, RecommendResponse, RecommendResponseMeta, SkillResponse, HealthStatus, TelemetryEventType, TelemetryMetadata, TelemetryEventPayload, TelemetryResponse, ApiErrorResponse as OpenApiErrorResponse, RateLimitInfo, ApiClientOptions, ApiResponse as OpenApiResponse, } from './types.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,GACpB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,WAAW,EAChB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,GACpB,MAAM,aAAa,CAAA;AAIpB,OAAO,EACL,8BAA8B,EAC9B,KAAK,2BAA2B,EAChC,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC7B,KAAK,oCAAoC,GAC1C,MAAM,8BAA8B,CAAA;AAGrC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAA;AAO3B,OAAO,EACL,iCAAiC,EACjC,iCAAiC,GAClC,MAAM,uBAAuB,CAAA;AAM9B,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,UAAU,GAChB,MAAM,YAAY,CAAA;AAMnB,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAE5D,YAAY,EAEV,YAAY,EACZ,WAAW,EACX,cAAc,EAEd,QAAQ,EACR,eAAe,IAAI,mBAAmB,EACtC,gBAAgB,EAEhB,YAAY,EACZ,cAAc,EACd,kBAAkB,EAElB,eAAe,EACf,iBAAiB,EACjB,qBAAqB,EAErB,aAAa,EAEb,YAAY,EAEZ,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EAEjB,gBAAgB,IAAI,oBAAoB,EAExC,aAAa,EAEb,gBAAgB,EAEhB,WAAW,IAAI,eAAe,GAC/B,MAAM,YAAY,CAAA"}
|
package/dist/src/api/index.js
CHANGED
|
@@ -10,8 +10,17 @@
|
|
|
10
10
|
// API Client
|
|
11
11
|
// ============================================================================
|
|
12
12
|
export { SkillsmithApiClient, createApiClient, generateAnonymousId, ApiClientError, } from './client.js';
|
|
13
|
+
// SMI-5905 Wave 4: private-registry content fetch — the CLI's only transport
|
|
14
|
+
// to `private_registry_skills.content` (see client.private-registry.ts header).
|
|
15
|
+
export { getPrivateRegistrySkillContent, } from './client.private-registry.js';
|
|
13
16
|
// SMI-4119: Event batching
|
|
14
17
|
export { EventBatcher, createEventBatcher, } from './event-batcher.js';
|
|
18
|
+
// SMI-5897 (C-15): shared security-summary derivation — CLI (`toSkill()`)
|
|
19
|
+
// and MCP tool call sites both import this instead of independently
|
|
20
|
+
// reconstructing the passed/riskScore/findingsCount/scannedAt logic.
|
|
21
|
+
// SMI-5897 (Wave 4 fix): sibling `deriveSecuritySummaryFromSkillRow()` for
|
|
22
|
+
// the local-DB-shaped (pre-computed field) call sites.
|
|
23
|
+
export { deriveSecuritySummaryFromApiSkill, deriveSecuritySummaryFromSkillRow, } from './security-summary.js';
|
|
15
24
|
// ============================================================================
|
|
16
25
|
// API Cache
|
|
17
26
|
// ============================================================================
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,GAOf,MAAM,aAAa,CAAA;AAEpB,2BAA2B;AAC3B,OAAO,EACL,YAAY,EACZ,kBAAkB,GAGnB,MAAM,oBAAoB,CAAA;AAE3B,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,GAGZ,MAAM,YAAY,CAAA;AAEnB,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/api/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E,OAAO,EACL,mBAAmB,EACnB,eAAe,EACf,mBAAmB,EACnB,cAAc,GAOf,MAAM,aAAa,CAAA;AAEpB,6EAA6E;AAC7E,gFAAgF;AAChF,OAAO,EACL,8BAA8B,GAK/B,MAAM,8BAA8B,CAAA;AAErC,2BAA2B;AAC3B,OAAO,EACL,YAAY,EACZ,kBAAkB,GAGnB,MAAM,oBAAoB,CAAA;AAE3B,0EAA0E;AAC1E,oEAAoE;AACpE,qEAAqE;AACrE,2EAA2E;AAC3E,uDAAuD;AACvD,OAAO,EACL,iCAAiC,EACjC,iCAAiC,GAClC,MAAM,uBAAuB,CAAA;AAE9B,+EAA+E;AAC/E,YAAY;AACZ,+EAA+E;AAE/E,OAAO,EACL,QAAQ,EACR,WAAW,EACX,cAAc,EACd,WAAW,GAGZ,MAAM,YAAY,CAAA;AAEnB,+EAA+E;AAC/E,8BAA8B;AAC9B,+EAA+E;AAE/E,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared derivation of a `SecuritySummary` from an API skill row,
|
|
3
|
+
* and from a pre-computed local-DB-shaped skill row.
|
|
4
|
+
* @module @skillsmith/core/api/security-summary
|
|
5
|
+
* @see SMI-4240: original inline derivation in mcp-server's get-skill.ts
|
|
6
|
+
* @see SMI-5562: extracted to mcp-server's utils/security-summary.ts so
|
|
7
|
+
* get-skill.ts, recommend.ts, and search.ts share a single implementation
|
|
8
|
+
* instead of triplicating the logic.
|
|
9
|
+
* @see SMI-5897 (C-15): moved here from mcp-server so `SkillsmithApiClient.toSkill()`
|
|
10
|
+
* (CLI path) can share the exact same derivation instead of hardcoding
|
|
11
|
+
* `riskScore: null, securityFindingsCount: 0, securityScannedAt: null,
|
|
12
|
+
* securityPassed: null` for every API-sourced skill — which caused CLI
|
|
13
|
+
* `info`/`search` to show "Not scanned" for skills MCP correctly reported
|
|
14
|
+
* as passed. Both `toSkill()` and mcp-server's tool call sites now import
|
|
15
|
+
* this one function, so the two surfaces cannot re-diverge.
|
|
16
|
+
* @see SMI-5897 (Wave 4 fix): `deriveSecuritySummaryFromSkillRow()` added
|
|
17
|
+
* alongside `deriveSecuritySummaryFromApiSkill()` — the local-DB-path
|
|
18
|
+
* sibling for the SAME undefined-when-never-scanned contract, but over the
|
|
19
|
+
* pre-computed `securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
20
|
+
* `securityScannedAt` field shape (as opposed to the raw API row's
|
|
21
|
+
* `last_scanned_at`/`quarantined`/`security_score`/`security_findings`
|
|
22
|
+
* columns). `recommend.helpers.ts`'s `buildDbFallbackRecommendation` had
|
|
23
|
+
* this exact ternary inline already; `search.helpers.ts`'s
|
|
24
|
+
* `mapLocalSkillToSearchResult` and `get-skill.ts`'s local-DB branch built
|
|
25
|
+
* the security object unconditionally, violating the contract for a
|
|
26
|
+
* never-scanned skill. All three now share this one function.
|
|
27
|
+
*/
|
|
28
|
+
import type { ApiSkill } from './types.js';
|
|
29
|
+
import type { SecuritySummary } from '../types.js';
|
|
30
|
+
/**
|
|
31
|
+
* Derive a `SecuritySummary` from an API skill row's flat security columns.
|
|
32
|
+
*
|
|
33
|
+
* Returns `undefined` when the skill has never been scanned
|
|
34
|
+
* (`last_scanned_at == null`) — never scanned is a distinct state from
|
|
35
|
+
* "scanned but no verdict" and callers must not conflate the two by
|
|
36
|
+
* shipping a placeholder `{ passed: null, ... }` object for skills that
|
|
37
|
+
* were never scanned at all.
|
|
38
|
+
*
|
|
39
|
+
* `security_findings_count` is not a stored column — `findingsCount` is
|
|
40
|
+
* always derived from the length of the `security_findings` jsonb array
|
|
41
|
+
* (defensively 0 when the value is missing or not an array).
|
|
42
|
+
*
|
|
43
|
+
* @param apiSkill - Object carrying the flat security columns from an
|
|
44
|
+
* `ApiSkill`/`ApiSearchResult` row (registry API response shape).
|
|
45
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
46
|
+
*/
|
|
47
|
+
export declare function deriveSecuritySummaryFromApiSkill(apiSkill: Pick<ApiSkill, 'last_scanned_at' | 'quarantined' | 'security_score' | 'security_findings'>): SecuritySummary | undefined;
|
|
48
|
+
/**
|
|
49
|
+
* Derive a `SecuritySummary` from a local-DB-shaped skill row's PRE-COMPUTED
|
|
50
|
+
* flat security fields (`securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
51
|
+
* `securityScannedAt` — a different shape from {@link deriveSecuritySummaryFromApiSkill}'s
|
|
52
|
+
* raw API-row columns).
|
|
53
|
+
*
|
|
54
|
+
* Same contract as {@link deriveSecuritySummaryFromApiSkill}: returns
|
|
55
|
+
* `undefined` when the skill has never been scanned (`securityScannedAt ==
|
|
56
|
+
* null`) — never scanned is a distinct state from "scanned but no verdict"
|
|
57
|
+
* and callers must not conflate the two by shipping a placeholder
|
|
58
|
+
* `{ passed: null, ... }` object for skills that were never scanned at all.
|
|
59
|
+
* `passed`/`riskScore` pass through RAW — never coerce/default to a
|
|
60
|
+
* fabricated value, which would misread as "confirmed clean/scanned."
|
|
61
|
+
*
|
|
62
|
+
* @param skill - Object carrying the pre-computed flat security fields
|
|
63
|
+
* present on both a local `Skill` repository row and `SkillData`
|
|
64
|
+
* (mcp-server's recommend matcher shape).
|
|
65
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
66
|
+
*/
|
|
67
|
+
export declare function deriveSecuritySummaryFromSkillRow(skill: {
|
|
68
|
+
securityPassed: boolean | null;
|
|
69
|
+
riskScore: number | null;
|
|
70
|
+
securityFindingsCount: number;
|
|
71
|
+
securityScannedAt: string | null;
|
|
72
|
+
}): SecuritySummary | undefined;
|
|
73
|
+
//# sourceMappingURL=security-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.d.ts","sourceRoot":"","sources":["../../../src/api/security-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAC1C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAElD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iCAAiC,CAC/C,QAAQ,EAAE,IAAI,CACZ,QAAQ,EACR,iBAAiB,GAAG,aAAa,GAAG,gBAAgB,GAAG,mBAAmB,CAC3E,GACA,eAAe,GAAG,SAAS,CAa7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iCAAiC,CAAC,KAAK,EAAE;IACvD,cAAc,EAAE,OAAO,GAAG,IAAI,CAAA;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAA;CACjC,GAAG,eAAe,GAAG,SAAS,CAW9B"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Shared derivation of a `SecuritySummary` from an API skill row,
|
|
3
|
+
* and from a pre-computed local-DB-shaped skill row.
|
|
4
|
+
* @module @skillsmith/core/api/security-summary
|
|
5
|
+
* @see SMI-4240: original inline derivation in mcp-server's get-skill.ts
|
|
6
|
+
* @see SMI-5562: extracted to mcp-server's utils/security-summary.ts so
|
|
7
|
+
* get-skill.ts, recommend.ts, and search.ts share a single implementation
|
|
8
|
+
* instead of triplicating the logic.
|
|
9
|
+
* @see SMI-5897 (C-15): moved here from mcp-server so `SkillsmithApiClient.toSkill()`
|
|
10
|
+
* (CLI path) can share the exact same derivation instead of hardcoding
|
|
11
|
+
* `riskScore: null, securityFindingsCount: 0, securityScannedAt: null,
|
|
12
|
+
* securityPassed: null` for every API-sourced skill — which caused CLI
|
|
13
|
+
* `info`/`search` to show "Not scanned" for skills MCP correctly reported
|
|
14
|
+
* as passed. Both `toSkill()` and mcp-server's tool call sites now import
|
|
15
|
+
* this one function, so the two surfaces cannot re-diverge.
|
|
16
|
+
* @see SMI-5897 (Wave 4 fix): `deriveSecuritySummaryFromSkillRow()` added
|
|
17
|
+
* alongside `deriveSecuritySummaryFromApiSkill()` — the local-DB-path
|
|
18
|
+
* sibling for the SAME undefined-when-never-scanned contract, but over the
|
|
19
|
+
* pre-computed `securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
20
|
+
* `securityScannedAt` field shape (as opposed to the raw API row's
|
|
21
|
+
* `last_scanned_at`/`quarantined`/`security_score`/`security_findings`
|
|
22
|
+
* columns). `recommend.helpers.ts`'s `buildDbFallbackRecommendation` had
|
|
23
|
+
* this exact ternary inline already; `search.helpers.ts`'s
|
|
24
|
+
* `mapLocalSkillToSearchResult` and `get-skill.ts`'s local-DB branch built
|
|
25
|
+
* the security object unconditionally, violating the contract for a
|
|
26
|
+
* never-scanned skill. All three now share this one function.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* Derive a `SecuritySummary` from an API skill row's flat security columns.
|
|
30
|
+
*
|
|
31
|
+
* Returns `undefined` when the skill has never been scanned
|
|
32
|
+
* (`last_scanned_at == null`) — never scanned is a distinct state from
|
|
33
|
+
* "scanned but no verdict" and callers must not conflate the two by
|
|
34
|
+
* shipping a placeholder `{ passed: null, ... }` object for skills that
|
|
35
|
+
* were never scanned at all.
|
|
36
|
+
*
|
|
37
|
+
* `security_findings_count` is not a stored column — `findingsCount` is
|
|
38
|
+
* always derived from the length of the `security_findings` jsonb array
|
|
39
|
+
* (defensively 0 when the value is missing or not an array).
|
|
40
|
+
*
|
|
41
|
+
* @param apiSkill - Object carrying the flat security columns from an
|
|
42
|
+
* `ApiSkill`/`ApiSearchResult` row (registry API response shape).
|
|
43
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
44
|
+
*/
|
|
45
|
+
export function deriveSecuritySummaryFromApiSkill(apiSkill) {
|
|
46
|
+
if (apiSkill.last_scanned_at == null) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
passed: apiSkill.quarantined === true ? false : apiSkill.security_score == null ? null : true,
|
|
51
|
+
riskScore: apiSkill.security_score ?? null,
|
|
52
|
+
findingsCount: Array.isArray(apiSkill.security_findings)
|
|
53
|
+
? apiSkill.security_findings.length
|
|
54
|
+
: 0,
|
|
55
|
+
scannedAt: apiSkill.last_scanned_at,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Derive a `SecuritySummary` from a local-DB-shaped skill row's PRE-COMPUTED
|
|
60
|
+
* flat security fields (`securityPassed`/`riskScore`/`securityFindingsCount`/
|
|
61
|
+
* `securityScannedAt` — a different shape from {@link deriveSecuritySummaryFromApiSkill}'s
|
|
62
|
+
* raw API-row columns).
|
|
63
|
+
*
|
|
64
|
+
* Same contract as {@link deriveSecuritySummaryFromApiSkill}: returns
|
|
65
|
+
* `undefined` when the skill has never been scanned (`securityScannedAt ==
|
|
66
|
+
* null`) — never scanned is a distinct state from "scanned but no verdict"
|
|
67
|
+
* and callers must not conflate the two by shipping a placeholder
|
|
68
|
+
* `{ passed: null, ... }` object for skills that were never scanned at all.
|
|
69
|
+
* `passed`/`riskScore` pass through RAW — never coerce/default to a
|
|
70
|
+
* fabricated value, which would misread as "confirmed clean/scanned."
|
|
71
|
+
*
|
|
72
|
+
* @param skill - Object carrying the pre-computed flat security fields
|
|
73
|
+
* present on both a local `Skill` repository row and `SkillData`
|
|
74
|
+
* (mcp-server's recommend matcher shape).
|
|
75
|
+
* @returns The derived summary, or `undefined` when never scanned.
|
|
76
|
+
*/
|
|
77
|
+
export function deriveSecuritySummaryFromSkillRow(skill) {
|
|
78
|
+
if (skill.securityScannedAt == null) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
passed: skill.securityPassed,
|
|
83
|
+
riskScore: skill.riskScore,
|
|
84
|
+
findingsCount: skill.securityFindingsCount,
|
|
85
|
+
scannedAt: skill.securityScannedAt,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=security-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.js","sourceRoot":"","sources":["../../../src/api/security-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAKH;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,iCAAiC,CAC/C,QAGC;IAED,IAAI,QAAQ,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC;QACrC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO;QACL,MAAM,EAAE,QAAQ,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,cAAc,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;QAC7F,SAAS,EAAE,QAAQ,CAAC,cAAc,IAAI,IAAI;QAC1C,aAAa,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC;YACtD,CAAC,CAAC,QAAQ,CAAC,iBAAiB,CAAC,MAAM;YACnC,CAAC,CAAC,CAAC;QACL,SAAS,EAAE,QAAQ,CAAC,eAAe;KACpC,CAAA;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iCAAiC,CAAC,KAKjD;IACC,IAAI,KAAK,CAAC,iBAAiB,IAAI,IAAI,EAAE,CAAC;QACpC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,OAAO;QACL,MAAM,EAAE,KAAK,CAAC,cAAc;QAC5B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,aAAa,EAAE,KAAK,CAAC,qBAAqB;QAC1C,SAAS,EAAE,KAAK,CAAC,iBAAiB;KACnC,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5562: Unit coverage for the shared security-summary derivation helper,
|
|
3
|
+
* extracted from get-skill.ts's inline derivation (SMI-4240).
|
|
4
|
+
* SMI-5897 (C-15): moved from packages/mcp-server/src/utils/security-summary.test.ts
|
|
5
|
+
* to packages/core so the CLI (`SkillsmithApiClient.toSkill()`) and MCP tool
|
|
6
|
+
* call sites share and test one implementation.
|
|
7
|
+
*/
|
|
8
|
+
export {};
|
|
9
|
+
//# sourceMappingURL=security-summary.test.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.test.d.ts","sourceRoot":"","sources":["../../../src/api/security-summary.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SMI-5562: Unit coverage for the shared security-summary derivation helper,
|
|
3
|
+
* extracted from get-skill.ts's inline derivation (SMI-4240).
|
|
4
|
+
* SMI-5897 (C-15): moved from packages/mcp-server/src/utils/security-summary.test.ts
|
|
5
|
+
* to packages/core so the CLI (`SkillsmithApiClient.toSkill()`) and MCP tool
|
|
6
|
+
* call sites share and test one implementation.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, it, expect } from 'vitest';
|
|
9
|
+
import { deriveSecuritySummaryFromApiSkill } from './security-summary.js';
|
|
10
|
+
describe('deriveSecuritySummaryFromApiSkill', () => {
|
|
11
|
+
it('returns undefined when the skill has never been scanned (last_scanned_at null)', () => {
|
|
12
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
13
|
+
last_scanned_at: null,
|
|
14
|
+
quarantined: false,
|
|
15
|
+
security_score: null,
|
|
16
|
+
security_findings: null,
|
|
17
|
+
});
|
|
18
|
+
expect(result).toBeUndefined();
|
|
19
|
+
});
|
|
20
|
+
it('returns undefined when last_scanned_at is undefined', () => {
|
|
21
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
22
|
+
last_scanned_at: undefined,
|
|
23
|
+
quarantined: undefined,
|
|
24
|
+
security_score: undefined,
|
|
25
|
+
security_findings: undefined,
|
|
26
|
+
});
|
|
27
|
+
expect(result).toBeUndefined();
|
|
28
|
+
});
|
|
29
|
+
it('returns passed: false when quarantined, regardless of security_score', () => {
|
|
30
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
31
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
32
|
+
quarantined: true,
|
|
33
|
+
// A low score would otherwise read as "clean" — quarantined must win.
|
|
34
|
+
security_score: 0,
|
|
35
|
+
security_findings: [],
|
|
36
|
+
});
|
|
37
|
+
expect(result?.passed).toBe(false);
|
|
38
|
+
});
|
|
39
|
+
it('returns passed: null when scanned but no security_score is recorded yet', () => {
|
|
40
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
41
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
42
|
+
quarantined: false,
|
|
43
|
+
security_score: null,
|
|
44
|
+
security_findings: null,
|
|
45
|
+
});
|
|
46
|
+
expect(result?.passed).toBeNull();
|
|
47
|
+
expect(result?.riskScore).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
it('returns passed: true for a clean scanned skill with a recorded score', () => {
|
|
50
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
51
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
52
|
+
quarantined: false,
|
|
53
|
+
security_score: 0,
|
|
54
|
+
security_findings: [],
|
|
55
|
+
});
|
|
56
|
+
expect(result).toEqual({
|
|
57
|
+
passed: true,
|
|
58
|
+
riskScore: 0,
|
|
59
|
+
findingsCount: 0,
|
|
60
|
+
scannedAt: '2026-06-01T00:00:00.000Z',
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
it('derives findingsCount from the security_findings array length', () => {
|
|
64
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
65
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
66
|
+
quarantined: false,
|
|
67
|
+
security_score: 42,
|
|
68
|
+
security_findings: [{ rule: 'a' }, { rule: 'b' }, { rule: 'c' }],
|
|
69
|
+
});
|
|
70
|
+
expect(result?.findingsCount).toBe(3);
|
|
71
|
+
});
|
|
72
|
+
it('defaults findingsCount to 0 when security_findings is not an array', () => {
|
|
73
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
74
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
75
|
+
quarantined: false,
|
|
76
|
+
security_score: 10,
|
|
77
|
+
// Defensive non-array case — should never happen at runtime (jsonb column),
|
|
78
|
+
// but the derivation must not throw or miscount.
|
|
79
|
+
security_findings: undefined,
|
|
80
|
+
});
|
|
81
|
+
expect(result?.findingsCount).toBe(0);
|
|
82
|
+
});
|
|
83
|
+
it('passes riskScore through as null (never a fabricated 0) when unscored', () => {
|
|
84
|
+
const result = deriveSecuritySummaryFromApiSkill({
|
|
85
|
+
last_scanned_at: '2026-06-01T00:00:00.000Z',
|
|
86
|
+
quarantined: false,
|
|
87
|
+
security_score: null,
|
|
88
|
+
security_findings: [{ rule: 'pending-review' }],
|
|
89
|
+
});
|
|
90
|
+
expect(result?.riskScore).toBeNull();
|
|
91
|
+
expect(result?.findingsCount).toBe(1);
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
//# sourceMappingURL=security-summary.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"security-summary.test.js","sourceRoot":"","sources":["../../../src/api/security-summary.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,9 +16,13 @@ export type CompatibilitySlug = (typeof COMPATIBILITY_SLUGS)[number];
|
|
|
16
16
|
export declare const COMPATIBILITY_LABELS: Record<CompatibilitySlug, string>;
|
|
17
17
|
/**
|
|
18
18
|
* Slugs that are filterable/browsable but have NO install target yet — the
|
|
19
|
-
* install-client enum (`install/paths.ts` `ClientId`) lacks them.
|
|
20
|
-
* `antigravity
|
|
21
|
-
*
|
|
19
|
+
* install-client enum (`install/paths.ts` `ClientId`) lacks them.
|
|
20
|
+
* `antigravity` was un-deferred (SMI-5982 Wave 6) — it now has a real
|
|
21
|
+
* `ClientId` + `CLIENT_NATIVE_PATHS` entry, so it moved out of this list.
|
|
22
|
+
* `gemini` has no install target (it names a model family, not a distinct
|
|
23
|
+
* install client) and remains browse-only; adding it (if ever justified) is
|
|
24
|
+
* still Phase 2c (SMI-5179). Until then the UI labels `gemini` "browse-only"
|
|
25
|
+
* rather than implying installability.
|
|
22
26
|
*/
|
|
23
27
|
export declare const BROWSE_ONLY_SLUGS: readonly CompatibilitySlug[];
|
|
24
28
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slugs.d.ts","sourceRoot":"","sources":["../../../src/compatibility/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,6FAQtB,CAAA;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpE,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAQlE,CAAA;AAED
|
|
1
|
+
{"version":3,"file":"slugs.d.ts","sourceRoot":"","sources":["../../../src/compatibility/slugs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,6FAA6F;AAC7F,eAAO,MAAM,mBAAmB,6FAQtB,CAAA;AAEV,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEpE,8DAA8D;AAC9D,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAQlE,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,iBAAiB,EAAe,CAAA;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAS1E,CAAA;AAED,+EAA+E;AAC/E,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEvD"}
|