@skillsmith/core 0.7.2 → 0.8.0

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 (33) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/src/embeddings/probe.d.ts +62 -0
  4. package/dist/src/embeddings/probe.d.ts.map +1 -0
  5. package/dist/src/embeddings/probe.js +89 -0
  6. package/dist/src/embeddings/probe.js.map +1 -0
  7. package/dist/src/index.d.ts +1 -1
  8. package/dist/src/index.js +1 -1
  9. package/dist/src/telemetry/index.d.ts +2 -1
  10. package/dist/src/telemetry/index.d.ts.map +1 -1
  11. package/dist/src/telemetry/index.js +4 -1
  12. package/dist/src/telemetry/index.js.map +1 -1
  13. package/dist/src/telemetry/posthog.d.ts +19 -1
  14. package/dist/src/telemetry/posthog.d.ts.map +1 -1
  15. package/dist/src/telemetry/posthog.js +14 -0
  16. package/dist/src/telemetry/posthog.js.map +1 -1
  17. package/dist/src/telemetry/wrap.bench.d.ts +13 -0
  18. package/dist/src/telemetry/wrap.bench.d.ts.map +1 -0
  19. package/dist/src/telemetry/wrap.bench.js +41 -0
  20. package/dist/src/telemetry/wrap.bench.js.map +1 -0
  21. package/dist/src/telemetry/wrap.d.ts +75 -0
  22. package/dist/src/telemetry/wrap.d.ts.map +1 -0
  23. package/dist/src/telemetry/wrap.js +124 -0
  24. package/dist/src/telemetry/wrap.js.map +1 -0
  25. package/dist/src/telemetry/wrap.test.d.ts +14 -0
  26. package/dist/src/telemetry/wrap.test.d.ts.map +1 -0
  27. package/dist/src/telemetry/wrap.test.js +283 -0
  28. package/dist/src/telemetry/wrap.test.js.map +1 -0
  29. package/dist/tests/embeddings/probe.test.d.ts +13 -0
  30. package/dist/tests/embeddings/probe.test.d.ts.map +1 -0
  31. package/dist/tests/embeddings/probe.test.js +154 -0
  32. package/dist/tests/embeddings/probe.test.js.map +1 -0
  33. package/package.json +11 -1
@@ -0,0 +1,283 @@
1
+ /**
2
+ * SMI-5016: Unit tests for withTelemetry HOF + isTelemetered registry.
3
+ *
4
+ * Covers the shared-state matrix invariants from plan line 720:
5
+ * - function-decl wrap
6
+ * - arrow-const export wrap (H3 critical case)
7
+ * - double-register idempotency (Set dedupes by reference)
8
+ * - isTelemetered true/false
9
+ * - emit-on-throw (success:false, then re-throw)
10
+ * - telemetry emit failure does NOT affect wrapped fn
11
+ * - per-request framework (H4 — not memoised)
12
+ */
13
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
14
+ import { withTelemetry, isTelemetered, setEmissionGate } from './wrap.js';
15
+ // ---------------------------------------------------------------------------
16
+ // Mock trackSkillInvoke so tests run without a live PostHog instance
17
+ // ---------------------------------------------------------------------------
18
+ vi.mock('./posthog.js', () => ({
19
+ trackSkillInvoke: vi.fn(),
20
+ }));
21
+ import { trackSkillInvoke } from './posthog.js';
22
+ const mockTrack = vi.mocked(trackSkillInvoke);
23
+ beforeEach(() => {
24
+ mockTrack.mockReset();
25
+ // SMI-5019 wire-in: default is now suppress-when-no-gate. Install a permissive
26
+ // gate so the legacy SMI-5016 tests below (which predate the consent gate)
27
+ // continue to assert against emit behaviour. The new emission-gate describe
28
+ // block at the bottom overrides this per-case.
29
+ setEmissionGate(() => true);
30
+ });
31
+ afterEach(() => {
32
+ // Reset to default-suppress so a leaked gate from one test does not flow
33
+ // into the next file's tests or pollute the per-process module state.
34
+ setEmissionGate(undefined);
35
+ });
36
+ // ---------------------------------------------------------------------------
37
+ // Helpers
38
+ // ---------------------------------------------------------------------------
39
+ const BASE_OPTS = {
40
+ source: 'mcp-tool',
41
+ extractSkillId: () => 'test/skill',
42
+ };
43
+ // ---------------------------------------------------------------------------
44
+ // 1. Function-declaration wrap
45
+ // ---------------------------------------------------------------------------
46
+ describe('function-declaration wrap', () => {
47
+ it('wraps a named function declaration and registers it', async () => {
48
+ function myHandler(x) {
49
+ return x * 2;
50
+ }
51
+ const wrapped = withTelemetry(myHandler, BASE_OPTS);
52
+ expect(isTelemetered(wrapped)).toBe(true);
53
+ expect(isTelemetered(myHandler)).toBe(false);
54
+ const result = await wrapped(3);
55
+ expect(result).toBe(6);
56
+ expect(mockTrack).toHaveBeenCalledOnce();
57
+ expect(mockTrack).toHaveBeenCalledWith(expect.objectContaining({ skillId: 'test/skill', success: true }));
58
+ });
59
+ });
60
+ // ---------------------------------------------------------------------------
61
+ // 2. Arrow-const export wrap (H3 critical case)
62
+ // ---------------------------------------------------------------------------
63
+ describe('arrow-const export wrap', () => {
64
+ it('wraps an arrow-const and registers the returned function (not the original)', async () => {
65
+ // This is the exact pattern that plan review change H3 was about:
66
+ // arrow-const exports cannot be mutated, so the registry MUST track the
67
+ // returned wrappedFn, not mutate the original.
68
+ const originalFn = (v) => v.toUpperCase();
69
+ const wrappedExport = withTelemetry(originalFn, BASE_OPTS);
70
+ // The returned function is telemetered; the original is not.
71
+ expect(isTelemetered(wrappedExport)).toBe(true);
72
+ expect(isTelemetered(originalFn)).toBe(false);
73
+ const result = await wrappedExport('hello');
74
+ expect(result).toBe('HELLO');
75
+ expect(mockTrack).toHaveBeenCalledOnce();
76
+ });
77
+ });
78
+ // ---------------------------------------------------------------------------
79
+ // 3. Double-register idempotency
80
+ // ---------------------------------------------------------------------------
81
+ describe('double-register', () => {
82
+ it('re-wrapping the same RETURNED function adds no new entries (Set dedupes by ref)', () => {
83
+ const original = () => 'value';
84
+ const w1 = withTelemetry(original, BASE_OPTS);
85
+ // Capture Set size after first wrap
86
+ expect(isTelemetered(w1)).toBe(true);
87
+ // Now attempt to re-wrap the *returned* function.
88
+ // The Set already contains w1, so adding it again is a no-op by Set semantics.
89
+ const w2 = withTelemetry(w1, BASE_OPTS);
90
+ // w2 is a NEW wrapper around w1 — both are in the Set, but w1 wasn't
91
+ // added a second time. isTelemetered(w1) is still true, and w2 is also true.
92
+ expect(isTelemetered(w1)).toBe(true);
93
+ expect(isTelemetered(w2)).toBe(true);
94
+ });
95
+ it('wrapping the same original fn twice produces two distinct wrapped fns, both registered', () => {
96
+ const original = () => 'x';
97
+ const wa = withTelemetry(original, BASE_OPTS);
98
+ const wb = withTelemetry(original, BASE_OPTS);
99
+ // Different wrapper references
100
+ expect(wa).not.toBe(wb);
101
+ expect(isTelemetered(wa)).toBe(true);
102
+ expect(isTelemetered(wb)).toBe(true);
103
+ // Original still not in registry
104
+ expect(isTelemetered(original)).toBe(false);
105
+ });
106
+ });
107
+ // ---------------------------------------------------------------------------
108
+ // 4. isTelemetered true/false
109
+ // ---------------------------------------------------------------------------
110
+ describe('isTelemetered', () => {
111
+ it('returns false for an arbitrary unwrapped function', () => {
112
+ const plain = () => { };
113
+ expect(isTelemetered(plain)).toBe(false);
114
+ });
115
+ it('returns true only for the wrapped return value', () => {
116
+ const original = () => 42;
117
+ const result = withTelemetry(original, BASE_OPTS);
118
+ expect(isTelemetered(result)).toBe(true);
119
+ expect(isTelemetered(original)).toBe(false);
120
+ });
121
+ });
122
+ // ---------------------------------------------------------------------------
123
+ // 5. Emit happens even on thrown errors
124
+ // ---------------------------------------------------------------------------
125
+ describe('emit-on-throw', () => {
126
+ it('emits with success:false and re-throws when handler throws', async () => {
127
+ const boom = () => {
128
+ throw new Error('handler exploded');
129
+ };
130
+ const wrappedBoom = withTelemetry(boom, BASE_OPTS);
131
+ await expect(wrappedBoom()).rejects.toThrow('handler exploded');
132
+ expect(mockTrack).toHaveBeenCalledOnce();
133
+ expect(mockTrack).toHaveBeenCalledWith(expect.objectContaining({ success: false, skillId: 'test/skill' }));
134
+ });
135
+ });
136
+ // ---------------------------------------------------------------------------
137
+ // 6. Telemetry emission failure does NOT affect wrapped fn
138
+ // ---------------------------------------------------------------------------
139
+ describe('emit-failure survival', () => {
140
+ it('returns the handler result even when trackSkillInvoke throws', async () => {
141
+ mockTrack.mockImplementation(() => {
142
+ throw new Error('PostHog is down');
143
+ });
144
+ const stable = () => 'still works';
145
+ const wrappedStable = withTelemetry(stable, BASE_OPTS);
146
+ const result = await wrappedStable();
147
+ expect(result).toBe('still works');
148
+ // trackSkillInvoke was called (and threw), but the wrapper swallowed it.
149
+ expect(mockTrack).toHaveBeenCalledOnce();
150
+ });
151
+ });
152
+ // ---------------------------------------------------------------------------
153
+ // 7. Per-request framework value (H4 — not memoised)
154
+ // ---------------------------------------------------------------------------
155
+ describe('per-request framework', () => {
156
+ it('reflects opts.extractFramework return value at each call independently', async () => {
157
+ let frameValue = 'cursor';
158
+ const handler = () => 'ok';
159
+ const wrappedWithFramework = withTelemetry(handler, {
160
+ ...BASE_OPTS,
161
+ extractFramework: () => frameValue,
162
+ });
163
+ await wrappedWithFramework();
164
+ expect(mockTrack).toHaveBeenLastCalledWith(expect.objectContaining({ framework: 'cursor' }));
165
+ // Mutate the frame value — simulates a different client on the same server
166
+ frameValue = 'copilot';
167
+ mockTrack.mockReset();
168
+ await wrappedWithFramework();
169
+ expect(mockTrack).toHaveBeenLastCalledWith(expect.objectContaining({ framework: 'copilot' }));
170
+ });
171
+ it('defaults framework to "unknown" when extractFramework is not provided', async () => {
172
+ const handler = () => 'ok';
173
+ const wrappedNoFrame = withTelemetry(handler, BASE_OPTS // no extractFramework
174
+ );
175
+ await wrappedNoFrame();
176
+ expect(mockTrack).toHaveBeenCalledWith(expect.objectContaining({ framework: 'unknown' }));
177
+ });
178
+ });
179
+ // ---------------------------------------------------------------------------
180
+ // 8. Overhead gate (Risk #7 — p99 < 1ms per wrapped call)
181
+ // ---------------------------------------------------------------------------
182
+ describe('overhead gate (risk #7)', () => {
183
+ it('p99 per-call overhead is < 1ms over 10 000 iterations', async () => {
184
+ const ITERATIONS = 10_000;
185
+ const noopHandler = async () => 42;
186
+ const wrappedNoop = withTelemetry(noopHandler, {
187
+ source: 'mcp-tool',
188
+ extractSkillId: () => 'bench/skill',
189
+ });
190
+ // JIT warm-up — stabilise before measuring
191
+ for (let i = 0; i < 100; i++) {
192
+ await wrappedNoop();
193
+ }
194
+ mockTrack.mockReset();
195
+ const elapsed = [];
196
+ for (let i = 0; i < ITERATIONS; i++) {
197
+ const t0 = performance.now();
198
+ await wrappedNoop();
199
+ elapsed.push(performance.now() - t0);
200
+ }
201
+ elapsed.sort((a, b) => a - b);
202
+ const p99 = elapsed[Math.ceil(ITERATIONS * 0.99) - 1];
203
+ const mean = elapsed.reduce((s, v) => s + v, 0) / ITERATIONS;
204
+ // Risk #7 gate: p99 must be below 1ms
205
+ expect(p99).toBeLessThan(1);
206
+ // Sanity gate: mean overhead should be well below 0.5ms
207
+ expect(mean).toBeLessThan(0.5);
208
+ expect(mockTrack).toHaveBeenCalledTimes(ITERATIONS);
209
+ });
210
+ });
211
+ // ---------------------------------------------------------------------------
212
+ // 9. Emission gate (SMI-5019 wire-in)
213
+ // ---------------------------------------------------------------------------
214
+ //
215
+ // These tests verify the privacy-safe default-suppress contract:
216
+ //
217
+ // - No gate installed → withTelemetry must NOT call trackSkillInvoke
218
+ // - Gate returns true → emit
219
+ // - Gate returns false → suppress
220
+ // - Gate is evaluated per-call (not memoised), so a toggling predicate
221
+ // produces different outcomes on consecutive calls
222
+ //
223
+ // The outer `beforeEach` installs a permissive gate for the legacy tests;
224
+ // these cases override that gate explicitly per-case.
225
+ describe('emission gate (SMI-5019 wire-in)', () => {
226
+ beforeEach(() => {
227
+ // Override the outer permissive gate — start each case with no gate
228
+ // installed, so the default-suppress behaviour is the natural baseline.
229
+ setEmissionGate(undefined);
230
+ });
231
+ it('default-suppress: no gate installed → no emit', async () => {
232
+ const handler = () => 'ok';
233
+ const wrappedFn = withTelemetry(handler, BASE_OPTS);
234
+ const result = await wrappedFn();
235
+ expect(result).toBe('ok');
236
+ expect(mockTrack).not.toHaveBeenCalled();
237
+ });
238
+ it('gate returns true → emit', async () => {
239
+ setEmissionGate(() => true);
240
+ const handler = () => 'ok';
241
+ const wrappedFn = withTelemetry(handler, BASE_OPTS);
242
+ await wrappedFn();
243
+ expect(mockTrack).toHaveBeenCalledOnce();
244
+ expect(mockTrack).toHaveBeenCalledWith(expect.objectContaining({ skillId: 'test/skill', success: true }));
245
+ });
246
+ it('gate returns false → no emit', async () => {
247
+ setEmissionGate(() => false);
248
+ const handler = () => 'ok';
249
+ const wrappedFn = withTelemetry(handler, BASE_OPTS);
250
+ await wrappedFn();
251
+ expect(mockTrack).not.toHaveBeenCalled();
252
+ });
253
+ it('gate is evaluated per-call (toggling predicate produces emit then no-emit)', async () => {
254
+ // Toggle true → false across the two invocations. Verifies the gate is
255
+ // NOT memoised at install time — each call queries it fresh, matching
256
+ // the per-call extractFramework contract (H4).
257
+ let nextReturn = true;
258
+ setEmissionGate(() => {
259
+ const value = nextReturn;
260
+ nextReturn = !nextReturn;
261
+ return value;
262
+ });
263
+ const handler = () => 'ok';
264
+ const wrappedFn = withTelemetry(handler, BASE_OPTS);
265
+ await wrappedFn();
266
+ expect(mockTrack).toHaveBeenCalledOnce();
267
+ mockTrack.mockReset();
268
+ await wrappedFn();
269
+ expect(mockTrack).not.toHaveBeenCalled();
270
+ });
271
+ it('gate is also consulted on throw — no emit when suppressed even if handler fails', async () => {
272
+ // Reinforces the privacy-safe invariant: a throwing handler must not
273
+ // smuggle telemetry past a suppressing gate via the finally block.
274
+ setEmissionGate(() => false);
275
+ const boom = () => {
276
+ throw new Error('handler exploded');
277
+ };
278
+ const wrappedBoom = withTelemetry(boom, BASE_OPTS);
279
+ await expect(wrappedBoom()).rejects.toThrow('handler exploded');
280
+ expect(mockTrack).not.toHaveBeenCalled();
281
+ });
282
+ });
283
+ //# sourceMappingURL=wrap.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wrap.test.js","sourceRoot":"","sources":["../../../src/telemetry/wrap.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * SMI-5039: Unit tests for the canonical `probeEmbeddingCapability` helper in
3
+ * `@skillsmith/core/embeddings/probe`. Mirrors the shape of the legacy
4
+ * `packages/mcp-server/tests/startup-probe.test.ts` unit tier (SMI-5009) but
5
+ * exercises the real exported function — not an inline copy — so the four
6
+ * consumers (mcp-server, doc-retrieval-mcp server/cli, cli) all share the
7
+ * same audited behavior.
8
+ *
9
+ * The mcp-server integration tier (spawn-based) is preserved separately to
10
+ * pin the MCP stdio invariant — see SMI-5009 for the rationale.
11
+ */
12
+ export {};
13
+ //# sourceMappingURL=probe.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.test.d.ts","sourceRoot":"","sources":["../../../tests/embeddings/probe.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG"}
@@ -0,0 +1,154 @@
1
+ /**
2
+ * SMI-5039: Unit tests for the canonical `probeEmbeddingCapability` helper in
3
+ * `@skillsmith/core/embeddings/probe`. Mirrors the shape of the legacy
4
+ * `packages/mcp-server/tests/startup-probe.test.ts` unit tier (SMI-5009) but
5
+ * exercises the real exported function — not an inline copy — so the four
6
+ * consumers (mcp-server, doc-retrieval-mcp server/cli, cli) all share the
7
+ * same audited behavior.
8
+ *
9
+ * The mcp-server integration tier (spawn-based) is preserved separately to
10
+ * pin the MCP stdio invariant — see SMI-5009 for the rationale.
11
+ */
12
+ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
13
+ import { EmbeddingService } from '../../src/embeddings/index.js';
14
+ import { probeEmbeddingCapability } from '../../src/embeddings/probe.js';
15
+ describe('SMI-5039 probeEmbeddingCapability — success path', () => {
16
+ let checkSpy;
17
+ beforeEach(() => {
18
+ checkSpy = vi.spyOn(EmbeddingService, 'checkAvailability');
19
+ // Spy on getTransformersLoadError to prevent any accidental real-module
20
+ // access during the test even though the success path never reads it.
21
+ vi.spyOn(EmbeddingService, 'getTransformersLoadError');
22
+ });
23
+ afterEach(() => {
24
+ vi.restoreAllMocks();
25
+ delete process.env['SKILLSMITH_QUIET'];
26
+ });
27
+ it('is silent when real embeddings are available', async () => {
28
+ checkSpy.mockResolvedValue(true);
29
+ const logs = [];
30
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m) });
31
+ expect(logs).toEqual([]);
32
+ });
33
+ });
34
+ describe('SMI-5039 probeEmbeddingCapability — mock fallback path', () => {
35
+ let checkSpy;
36
+ let getErrSpy;
37
+ beforeEach(() => {
38
+ checkSpy = vi.spyOn(EmbeddingService, 'checkAvailability');
39
+ getErrSpy = vi.spyOn(EmbeddingService, 'getTransformersLoadError');
40
+ });
41
+ afterEach(() => {
42
+ vi.restoreAllMocks();
43
+ delete process.env['SKILLSMITH_QUIET'];
44
+ });
45
+ it('logs structured mock-fallback warning with reason when checkAvailability returns false', async () => {
46
+ checkSpy.mockResolvedValue(false);
47
+ getErrSpy.mockReturnValue(new Error('ENOENT: cannot find module @huggingface/transformers'));
48
+ const logs = [];
49
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m) });
50
+ expect(logs).toHaveLength(1);
51
+ expect(logs[0]).toMatch(/\[skillsmith\] embeddings: mock \(transformers unavailable: ENOENT: cannot find module @huggingface\/transformers/);
52
+ // Remediation hint MUST be present.
53
+ expect(logs[0]).toContain('install @huggingface/transformers');
54
+ expect(logs[0]).toContain('SKILLSMITH_USE_MOCK_EMBEDDINGS=true');
55
+ });
56
+ it('falls back to "module-load-failed" when no load error is recorded', async () => {
57
+ checkSpy.mockResolvedValue(false);
58
+ getErrSpy.mockReturnValue(null);
59
+ const logs = [];
60
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m) });
61
+ expect(logs).toHaveLength(1);
62
+ expect(logs[0]).toContain('transformers unavailable: module-load-failed');
63
+ });
64
+ });
65
+ describe('SMI-5039 probeEmbeddingCapability — timeout path', () => {
66
+ let checkSpy;
67
+ let getErrSpy;
68
+ beforeEach(() => {
69
+ checkSpy = vi.spyOn(EmbeddingService, 'checkAvailability');
70
+ getErrSpy = vi.spyOn(EmbeddingService, 'getTransformersLoadError');
71
+ });
72
+ afterEach(() => {
73
+ vi.restoreAllMocks();
74
+ delete process.env['SKILLSMITH_QUIET'];
75
+ });
76
+ it('emits probe-timeout line and returns within the bound when checkAvailability hangs', async () => {
77
+ // Hangs forever — only the timeout sentinel should resolve.
78
+ checkSpy.mockImplementation(() => new Promise(() => undefined));
79
+ getErrSpy.mockReturnValue(null);
80
+ const logs = [];
81
+ const start = Date.now();
82
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m), timeoutMs: 100 });
83
+ const elapsed = Date.now() - start;
84
+ expect(logs).toHaveLength(1);
85
+ expect(logs[0]).toMatch(/embeddings: mock \(transformers unavailable: probe-timeout/);
86
+ // Must complete within a small multiple of the timeout — proves the
87
+ // hard-bound holds even when checkAvailability never resolves.
88
+ expect(elapsed).toBeLessThan(2000);
89
+ });
90
+ });
91
+ describe('SMI-5039 probeEmbeddingCapability — error path', () => {
92
+ let checkSpy;
93
+ let getErrSpy;
94
+ beforeEach(() => {
95
+ checkSpy = vi.spyOn(EmbeddingService, 'checkAvailability');
96
+ getErrSpy = vi.spyOn(EmbeddingService, 'getTransformersLoadError');
97
+ });
98
+ afterEach(() => {
99
+ vi.restoreAllMocks();
100
+ delete process.env['SKILLSMITH_QUIET'];
101
+ });
102
+ it('catches a thrown error and logs probe-failed without rethrowing', async () => {
103
+ checkSpy.mockRejectedValue(new Error('boom'));
104
+ getErrSpy.mockReturnValue(null);
105
+ const logs = [];
106
+ await expect(probeEmbeddingCapability({ logger: (m) => logs.push(m) })).resolves.toBeUndefined();
107
+ expect(logs).toHaveLength(1);
108
+ expect(logs[0]).toMatch(/embeddings: probe-failed \(boom/);
109
+ expect(logs[0]).toContain('install @huggingface/transformers');
110
+ });
111
+ });
112
+ describe('SMI-5039 probeEmbeddingCapability — quiet mode', () => {
113
+ let checkSpy;
114
+ let getErrSpy;
115
+ beforeEach(() => {
116
+ checkSpy = vi.spyOn(EmbeddingService, 'checkAvailability');
117
+ getErrSpy = vi.spyOn(EmbeddingService, 'getTransformersLoadError');
118
+ });
119
+ afterEach(() => {
120
+ vi.restoreAllMocks();
121
+ delete process.env['SKILLSMITH_QUIET'];
122
+ });
123
+ it('suppresses the warning when opts.quiet=true', async () => {
124
+ checkSpy.mockResolvedValue(false);
125
+ getErrSpy.mockReturnValue(new Error('boom'));
126
+ const logs = [];
127
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m), quiet: true });
128
+ expect(logs).toEqual([]);
129
+ });
130
+ it('suppresses the warning when SKILLSMITH_QUIET=true', async () => {
131
+ checkSpy.mockResolvedValue(false);
132
+ getErrSpy.mockReturnValue(new Error('boom'));
133
+ process.env['SKILLSMITH_QUIET'] = 'true';
134
+ const logs = [];
135
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m) });
136
+ expect(logs).toEqual([]);
137
+ });
138
+ it('honors SKILLSMITH_QUIET=1 (numeric truthy)', async () => {
139
+ checkSpy.mockResolvedValue(false);
140
+ getErrSpy.mockReturnValue(new Error('boom'));
141
+ process.env['SKILLSMITH_QUIET'] = '1';
142
+ const logs = [];
143
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m) });
144
+ expect(logs).toEqual([]);
145
+ });
146
+ it('does NOT suppress when SKILLSMITH_QUIET is unset and quiet=false', async () => {
147
+ checkSpy.mockResolvedValue(false);
148
+ getErrSpy.mockReturnValue(new Error('boom'));
149
+ const logs = [];
150
+ await probeEmbeddingCapability({ logger: (m) => logs.push(m), quiet: false });
151
+ expect(logs).toHaveLength(1);
152
+ });
153
+ });
154
+ //# sourceMappingURL=probe.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"probe.test.js","sourceRoot":"","sources":["../../../tests/embeddings/probe.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skillsmith/core",
3
- "version": "0.7.2",
3
+ "version": "0.8.0",
4
4
  "description": "Core types and utilities for Skillsmith",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -21,6 +21,11 @@
21
21
  "import": "./dist/src/embeddings/index.js",
22
22
  "default": "./dist/src/embeddings/index.js"
23
23
  },
24
+ "./embeddings/probe": {
25
+ "types": "./dist/src/embeddings/probe.d.ts",
26
+ "import": "./dist/src/embeddings/probe.js",
27
+ "default": "./dist/src/embeddings/probe.js"
28
+ },
24
29
  "./testing": {
25
30
  "types": "./dist/src/testing/index.d.ts",
26
31
  "import": "./dist/src/testing/index.js",
@@ -60,6 +65,11 @@
60
65
  "types": "./dist/src/skills/index-local.d.ts",
61
66
  "import": "./dist/src/skills/index-local.js",
62
67
  "default": "./dist/src/skills/index-local.js"
68
+ },
69
+ "./telemetry": {
70
+ "types": "./dist/src/telemetry/index.d.ts",
71
+ "import": "./dist/src/telemetry/index.js",
72
+ "default": "./dist/src/telemetry/index.js"
63
73
  }
64
74
  },
65
75
  "scripts": {