@skillsmith/core 0.11.4 → 0.11.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (183) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +10 -7
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/src/api/client.d.ts.map +1 -1
  5. package/dist/src/api/client.js +15 -5
  6. package/dist/src/api/client.js.map +1 -1
  7. package/dist/src/api/client.private-registry.d.ts +80 -0
  8. package/dist/src/api/client.private-registry.d.ts.map +1 -0
  9. package/dist/src/api/client.private-registry.js +97 -0
  10. package/dist/src/api/client.private-registry.js.map +1 -0
  11. package/dist/src/api/client.private-registry.test.d.ts +9 -0
  12. package/dist/src/api/client.private-registry.test.d.ts.map +1 -0
  13. package/dist/src/api/client.private-registry.test.js +127 -0
  14. package/dist/src/api/client.private-registry.test.js.map +1 -0
  15. package/dist/src/api/client.toSkill.test.d.ts +25 -0
  16. package/dist/src/api/client.toSkill.test.d.ts.map +1 -0
  17. package/dist/src/api/client.toSkill.test.js +97 -0
  18. package/dist/src/api/client.toSkill.test.js.map +1 -0
  19. package/dist/src/api/client.token-refresh.d.ts +8 -0
  20. package/dist/src/api/client.token-refresh.d.ts.map +1 -1
  21. package/dist/src/api/client.token-refresh.js +26 -0
  22. package/dist/src/api/client.token-refresh.js.map +1 -1
  23. package/dist/src/api/client.token-refresh.test.js +82 -0
  24. package/dist/src/api/client.token-refresh.test.js.map +1 -1
  25. package/dist/src/api/index.d.ts +2 -0
  26. package/dist/src/api/index.d.ts.map +1 -1
  27. package/dist/src/api/index.js +9 -0
  28. package/dist/src/api/index.js.map +1 -1
  29. package/dist/src/api/security-summary.d.ts +73 -0
  30. package/dist/src/api/security-summary.d.ts.map +1 -0
  31. package/dist/src/api/security-summary.js +88 -0
  32. package/dist/src/api/security-summary.js.map +1 -0
  33. package/dist/src/api/security-summary.test.d.ts +9 -0
  34. package/dist/src/api/security-summary.test.d.ts.map +1 -0
  35. package/dist/src/api/security-summary.test.js +94 -0
  36. package/dist/src/api/security-summary.test.js.map +1 -0
  37. package/dist/src/config/config-atomic-write.d.ts +30 -10
  38. package/dist/src/config/config-atomic-write.d.ts.map +1 -1
  39. package/dist/src/config/config-atomic-write.js +33 -80
  40. package/dist/src/config/config-atomic-write.js.map +1 -1
  41. package/dist/src/config/config-atomic-write.test.d.ts +8 -0
  42. package/dist/src/config/config-atomic-write.test.d.ts.map +1 -1
  43. package/dist/src/config/config-atomic-write.test.js +64 -12
  44. package/dist/src/config/config-atomic-write.test.js.map +1 -1
  45. package/dist/src/config/owned-lock.acquire.d.ts +53 -0
  46. package/dist/src/config/owned-lock.acquire.d.ts.map +1 -0
  47. package/dist/src/config/owned-lock.acquire.js +140 -0
  48. package/dist/src/config/owned-lock.acquire.js.map +1 -0
  49. package/dist/src/config/owned-lock.claim.d.ts +84 -0
  50. package/dist/src/config/owned-lock.claim.d.ts.map +1 -0
  51. package/dist/src/config/owned-lock.claim.js +310 -0
  52. package/dist/src/config/owned-lock.claim.js.map +1 -0
  53. package/dist/src/config/owned-lock.d.ts +113 -0
  54. package/dist/src/config/owned-lock.d.ts.map +1 -0
  55. package/dist/src/config/owned-lock.js +121 -0
  56. package/dist/src/config/owned-lock.js.map +1 -0
  57. package/dist/src/config/owned-lock.test.d.ts +12 -0
  58. package/dist/src/config/owned-lock.test.d.ts.map +1 -0
  59. package/dist/src/config/owned-lock.test.js +412 -0
  60. package/dist/src/config/owned-lock.test.js.map +1 -0
  61. package/dist/src/config/owned-lock.types.d.ts +78 -0
  62. package/dist/src/config/owned-lock.types.d.ts.map +1 -0
  63. package/dist/src/config/owned-lock.types.js +30 -0
  64. package/dist/src/config/owned-lock.types.js.map +1 -0
  65. package/dist/src/db/createDatabase.d.ts.map +1 -1
  66. package/dist/src/db/createDatabase.js +19 -7
  67. package/dist/src/db/createDatabase.js.map +1 -1
  68. package/dist/src/embeddings/hnsw-store.exports.d.ts +11 -0
  69. package/dist/src/embeddings/hnsw-store.exports.d.ts.map +1 -0
  70. package/dist/src/embeddings/hnsw-store.exports.js +10 -0
  71. package/dist/src/embeddings/hnsw-store.exports.js.map +1 -0
  72. package/dist/src/embeddings/index.d.ts +1 -2
  73. package/dist/src/embeddings/index.d.ts.map +1 -1
  74. package/dist/src/embeddings/index.js +17 -3
  75. package/dist/src/embeddings/index.js.map +1 -1
  76. package/dist/src/embeddings/probe.d.ts.map +1 -1
  77. package/dist/src/embeddings/probe.js +4 -8
  78. package/dist/src/embeddings/probe.js.map +1 -1
  79. package/dist/src/exports/services.d.ts +4 -1
  80. package/dist/src/exports/services.d.ts.map +1 -1
  81. package/dist/src/exports/services.js +22 -0
  82. package/dist/src/exports/services.js.map +1 -1
  83. package/dist/src/index.d.ts +3 -3
  84. package/dist/src/index.d.ts.map +1 -1
  85. package/dist/src/index.js +9 -3
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/install/index.d.ts +1 -1
  88. package/dist/src/install/index.d.ts.map +1 -1
  89. package/dist/src/install/index.js +1 -1
  90. package/dist/src/install/index.js.map +1 -1
  91. package/dist/src/install/paths.d.ts +10 -0
  92. package/dist/src/install/paths.d.ts.map +1 -1
  93. package/dist/src/install/paths.js +19 -0
  94. package/dist/src/install/paths.js.map +1 -1
  95. package/dist/src/security/scanner/multiline-category-closure.test.d.ts +80 -0
  96. package/dist/src/security/scanner/multiline-category-closure.test.d.ts.map +1 -0
  97. package/dist/src/security/scanner/multiline-category-closure.test.js +287 -0
  98. package/dist/src/security/scanner/multiline-category-closure.test.js.map +1 -0
  99. package/dist/src/services/recommend-guard.d.ts +28 -0
  100. package/dist/src/services/recommend-guard.d.ts.map +1 -0
  101. package/dist/src/services/recommend-guard.js +34 -0
  102. package/dist/src/services/recommend-guard.js.map +1 -0
  103. package/dist/src/services/recommend-guard.test.d.ts +2 -0
  104. package/dist/src/services/recommend-guard.test.d.ts.map +1 -0
  105. package/dist/src/services/recommend-guard.test.js +28 -0
  106. package/dist/src/services/recommend-guard.test.js.map +1 -0
  107. package/dist/src/services/skill-installation.content.d.ts +88 -0
  108. package/dist/src/services/skill-installation.content.d.ts.map +1 -0
  109. package/dist/src/services/skill-installation.content.js +319 -0
  110. package/dist/src/services/skill-installation.content.js.map +1 -0
  111. package/dist/src/services/skill-installation.helpers.d.ts +32 -1
  112. package/dist/src/services/skill-installation.helpers.d.ts.map +1 -1
  113. package/dist/src/services/skill-installation.helpers.js +39 -6
  114. package/dist/src/services/skill-installation.helpers.js.map +1 -1
  115. package/dist/src/services/skill-installation.helpers.test.js +34 -2
  116. package/dist/src/services/skill-installation.helpers.test.js.map +1 -1
  117. package/dist/src/services/skill-installation.io.d.ts.map +1 -1
  118. package/dist/src/services/skill-installation.io.js +74 -1
  119. package/dist/src/services/skill-installation.io.js.map +1 -1
  120. package/dist/src/services/skill-installation.service.d.ts +20 -1
  121. package/dist/src/services/skill-installation.service.d.ts.map +1 -1
  122. package/dist/src/services/skill-installation.service.js +26 -4
  123. package/dist/src/services/skill-installation.service.js.map +1 -1
  124. package/dist/src/services/skill-installation.types.d.ts +42 -1
  125. package/dist/src/services/skill-installation.types.d.ts.map +1 -1
  126. package/dist/src/services/skill-installation.types.js.map +1 -1
  127. package/dist/src/services/skill-resolution.d.ts +67 -0
  128. package/dist/src/services/skill-resolution.d.ts.map +1 -0
  129. package/dist/src/services/skill-resolution.js +67 -0
  130. package/dist/src/services/skill-resolution.js.map +1 -0
  131. package/dist/src/services/skill-resolution.test.d.ts +2 -0
  132. package/dist/src/services/skill-resolution.test.d.ts.map +1 -0
  133. package/dist/src/services/skill-resolution.test.js +143 -0
  134. package/dist/src/services/skill-resolution.test.js.map +1 -0
  135. package/dist/src/utils/index.d.ts +1 -0
  136. package/dist/src/utils/index.d.ts.map +1 -1
  137. package/dist/src/utils/index.js +4 -0
  138. package/dist/src/utils/index.js.map +1 -1
  139. package/dist/src/utils/quiet-mode.d.ts +21 -0
  140. package/dist/src/utils/quiet-mode.d.ts.map +1 -0
  141. package/dist/src/utils/quiet-mode.js +26 -0
  142. package/dist/src/utils/quiet-mode.js.map +1 -0
  143. package/dist/tests/EmbeddingService.test.js +58 -1
  144. package/dist/tests/EmbeddingService.test.js.map +1 -1
  145. package/dist/tests/SecurityScanner.performance.test.js +5 -2
  146. package/dist/tests/SecurityScanner.performance.test.js.map +1 -1
  147. package/dist/tests/db/database-abstraction.test.js +45 -1
  148. package/dist/tests/db/database-abstraction.test.js.map +1 -1
  149. package/dist/tests/helpers/deterministic-dead-pid.d.ts +13 -0
  150. package/dist/tests/helpers/deterministic-dead-pid.d.ts.map +1 -0
  151. package/dist/tests/helpers/deterministic-dead-pid.js +31 -0
  152. package/dist/tests/helpers/deterministic-dead-pid.js.map +1 -0
  153. package/dist/tests/integration/owned-lock-lost-update.test.d.ts +12 -0
  154. package/dist/tests/integration/owned-lock-lost-update.test.d.ts.map +1 -0
  155. package/dist/tests/integration/owned-lock-lost-update.test.js +52 -0
  156. package/dist/tests/integration/owned-lock-lost-update.test.js.map +1 -0
  157. package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts +19 -0
  158. package/dist/tests/integration/owned-lock-reclaim-race.test.d.ts.map +1 -0
  159. package/dist/tests/integration/owned-lock-reclaim-race.test.js +177 -0
  160. package/dist/tests/integration/owned-lock-reclaim-race.test.js.map +1 -0
  161. package/dist/tests/unit/services/skill-installation.content.test.d.ts +10 -0
  162. package/dist/tests/unit/services/skill-installation.content.test.d.ts.map +1 -0
  163. package/dist/tests/unit/services/skill-installation.content.test.js +290 -0
  164. package/dist/tests/unit/services/skill-installation.content.test.js.map +1 -0
  165. package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts +8 -0
  166. package/dist/tests/unit/services/skill-installation.io.symlink.test.d.ts.map +1 -0
  167. package/dist/tests/unit/services/skill-installation.io.symlink.test.js +72 -0
  168. package/dist/tests/unit/services/skill-installation.io.symlink.test.js.map +1 -0
  169. package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts +15 -0
  170. package/dist/tests/unit/services/skill-installation.service.error-codes.test.d.ts.map +1 -0
  171. package/dist/tests/unit/services/skill-installation.service.error-codes.test.js +190 -0
  172. package/dist/tests/unit/services/skill-installation.service.error-codes.test.js.map +1 -0
  173. package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts +17 -0
  174. package/dist/tests/unit/services/skill-installation.service.multi-client.test.d.ts.map +1 -0
  175. package/dist/tests/unit/services/skill-installation.service.multi-client.test.js +126 -0
  176. package/dist/tests/unit/services/skill-installation.service.multi-client.test.js.map +1 -0
  177. package/dist/tests/unit/services/skill-installation.service.test.js +7 -112
  178. package/dist/tests/unit/services/skill-installation.service.test.js.map +1 -1
  179. package/dist/tests/utils/quiet-mode.test.d.ts +12 -0
  180. package/dist/tests/utils/quiet-mode.test.d.ts.map +1 -0
  181. package/dist/tests/utils/quiet-mode.test.js +42 -0
  182. package/dist/tests/utils/quiet-mode.test.js.map +1 -0
  183. package/package.json +17 -5
@@ -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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"}
@@ -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;AAGpB,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,KAAK,mBAAmB,EACxB,KAAK,YAAY,GAClB,MAAM,oBAAoB,CAAA;AAM3B,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"}
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"}
@@ -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":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC7C,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAA;AAEzE,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,gFAAgF,EAAE,GAAG,EAAE;QACxF,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,IAAI;YACrB,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,IAAI;YACpB,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC7D,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,SAAS;YAC1B,WAAW,EAAE,SAAS;YACtB,cAAc,EAAE,SAAS;YACzB,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,aAAa,EAAE,CAAA;IAChC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,IAAI;YACjB,sEAAsE;YACtE,cAAc,EAAE,CAAC;YACjB,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACpC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,yEAAyE,EAAE,GAAG,EAAE;QACjF,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,IAAI;YACpB,iBAAiB,EAAE,IAAI;SACxB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAA;QACjC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAA;IACtC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,sEAAsE,EAAE,GAAG,EAAE;QAC9E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,CAAC;YACjB,iBAAiB,EAAE,EAAE;SACtB,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,MAAM,EAAE,IAAI;YACZ,SAAS,EAAE,CAAC;YACZ,aAAa,EAAE,CAAC;YAChB,SAAS,EAAE,0BAA0B;SACtC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,EAAE;YAClB,iBAAiB,EAAE,CAAC,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;SACjE,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,oEAAoE,EAAE,GAAG,EAAE;QAC5E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,EAAE;YAClB,4EAA4E;YAC5E,iDAAiD;YACjD,iBAAiB,EAAE,SAAS;SAC7B,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,uEAAuE,EAAE,GAAG,EAAE;QAC/E,MAAM,MAAM,GAAG,iCAAiC,CAAC;YAC/C,eAAe,EAAE,0BAA0B;YAC3C,WAAW,EAAE,KAAK;YAClB,cAAc,EAAE,IAAI;YACpB,iBAAiB,EAAE,CAAC,EAAE,IAAI,EAAE,gBAAgB,EAAE,CAAC;SAChD,CAAC,CAAA;QAEF,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,QAAQ,EAAE,CAAA;QACpC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
@@ -17,9 +17,17 @@
17
17
  * principle observe a partially-written file.
18
18
  *
19
19
  * This module fixes both:
20
- * - {@link acquireConfigLock} serializes ALL writers (cross-process, via a
21
- * create-exclusive `.lock` sentinel file) so a caller's full
22
- * read-modify-write sequence is one atomic critical section.
20
+ * - {@link acquireConfigLock} serializes ALL writers (cross-process) so a
21
+ * caller's full read-modify-write sequence is one atomic critical
22
+ * section. SMI-5883 Wave 2: this is now a thin wrapper over the shared
23
+ * two-level {@link acquireOwnedLock} primitive (`owned-lock.ts`) —
24
+ * staleness is determined by OWNER LIVENESS (not file age), and a stale
25
+ * lock is reclaimed only from inside a second, strict-no-auto-reclaim
26
+ * lock that serializes reclaim decisions. The prior age-based
27
+ * `STALE_LOCK_AGE_MS` force-clear is REMOVED, not tuned — a lock held
28
+ * legitimately longer than any timeout now correctly times out instead
29
+ * of being force-cleared out from under its live holder. See
30
+ * `owned-lock.ts`'s module docstring for the full soundness argument.
23
31
  * - {@link atomicWriteFile} writes to a temp file in the same directory,
24
32
  * then `renameSync`s it into place — POSIX guarantees `rename(2)` is
25
33
  * atomic, so a concurrent reader (which never needs the lock — only
@@ -27,14 +35,26 @@
27
35
  * never a torn write.
28
36
  */
29
37
  /**
30
- * Acquire an exclusive, cross-process lock guarding `configPath`.
38
+ * Acquire an exclusive, cross-process lock guarding `configPath`. Thin
39
+ * wrapper over {@link acquireOwnedLock} (SMI-5883 Wave 2) — preserves this
40
+ * function's signature and its `${configPath}.lock` path so no caller needs
41
+ * to change. Behaviour deltas vs the pre-SMI-5883 implementation (each
42
+ * covered by a test in `config-atomic-write.test.ts`):
31
43
  *
32
- * Uses atomic create-exclusive (the `wx` flag fails with `EEXIST` if the
33
- * lock file already exists) as the mutual-exclusion primitive: portable
34
- * (identical behavior on macOS/Linux/Windows) and needs no extra
35
- * dependency. Retries with a short backoff until `LOCK_ACQUIRE_TIMEOUT_MS`
36
- * elapses. If the held lock is older than `STALE_LOCK_AGE_MS` it is assumed
37
- * abandoned by a crashed process and force-cleared once, then retried.
44
+ * 1. A stale lock is cleared on OWNER DEATH, not on AGE. A lock held by a
45
+ * live process for longer than the old 10s threshold is no longer
46
+ * force-cleared it now correctly waits, then times out.
47
+ * 2. A legacy bare-PID lock (this module's OWN pre-SMI-5883 on-disk format)
48
+ * is no longer cleared at all `StuckLockError { reason:
49
+ * 'unreclaimable_legacy' }` (D-5: a legacy claim carries no `host`, so
50
+ * "dead on this host" cannot establish "dead").
51
+ * 3. The on-disk lock content changes from a bare PID to a v1 JSON record.
52
+ * No in-repo consumer parses it directly (only this module's own
53
+ * `acquireConfigLock`/release touch the file).
54
+ * 4. The timeout message keeps the stable prefix "Timed out waiting for
55
+ * config lock" (via `label: 'config lock'`) so existing assertions
56
+ * still match, with the failure reason and the manual unstick procedure
57
+ * appended.
38
58
  *
39
59
  * @param configPath - Path to the config file being guarded (NOT the lock
40
60
  * file itself — the lock file is `${configPath}.lock`).
@@ -1 +1 @@
1
- {"version":3,"file":"config-atomic-write.d.ts","sourceRoot":"","sources":["../../../src/config/config-atomic-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AA2CH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAgC,GAC1C,MAAM,IAAI,CAmDZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAarF"}
1
+ {"version":3,"file":"config-atomic-write.d.ts","sourceRoot":"","sources":["../../../src/config/config-atomic-write.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAeH;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,EAClB,SAAS,GAAE,MAAgC,GAC1C,MAAM,IAAI,CAEZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAarF"}