@skillsmith/cli 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/src/commands/index.d.ts +1 -0
- package/dist/src/commands/index.d.ts.map +1 -1
- package/dist/src/commands/index.js +2 -0
- package/dist/src/commands/index.js.map +1 -1
- package/dist/src/commands/search.d.ts.map +1 -1
- package/dist/src/commands/search.js +11 -0
- package/dist/src/commands/search.js.map +1 -1
- package/dist/src/commands/telemetry.d.ts +38 -0
- package/dist/src/commands/telemetry.d.ts.map +1 -0
- package/dist/src/commands/telemetry.helpers.d.ts +58 -0
- package/dist/src/commands/telemetry.helpers.d.ts.map +1 -0
- package/dist/src/commands/telemetry.helpers.js +173 -0
- package/dist/src/commands/telemetry.helpers.js.map +1 -0
- package/dist/src/commands/telemetry.helpers.test.d.ts +15 -0
- package/dist/src/commands/telemetry.helpers.test.d.ts.map +1 -0
- package/dist/src/commands/telemetry.helpers.test.js +240 -0
- package/dist/src/commands/telemetry.helpers.test.js.map +1 -0
- package/dist/src/commands/telemetry.js +354 -0
- package/dist/src/commands/telemetry.js.map +1 -0
- package/dist/src/commands/telemetry.test.d.ts +18 -0
- package/dist/src/commands/telemetry.test.d.ts.map +1 -0
- package/dist/src/commands/telemetry.test.js +401 -0
- package/dist/src/commands/telemetry.test.js.map +1 -0
- package/dist/src/index.js +3 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/utils/manifest.d.ts +75 -0
- package/dist/src/utils/manifest.d.ts.map +1 -1
- package/dist/src/utils/manifest.js +78 -0
- package/dist/src/utils/manifest.js.map +1 -1
- package/dist/src/utils/manifest.test.d.ts +20 -0
- package/dist/src/utils/manifest.test.d.ts.map +1 -0
- package/dist/src/utils/manifest.test.js +344 -0
- package/dist/src/utils/manifest.test.js.map +1 -0
- package/dist/tests/embedding-probe-stdio.test.d.ts +11 -0
- package/dist/tests/embedding-probe-stdio.test.d.ts.map +1 -0
- package/dist/tests/embedding-probe-stdio.test.js +58 -0
- package/dist/tests/embedding-probe-stdio.test.js.map +1 -0
- package/package.json +4 -3
- package/templates/skill-telemetry.cmd +16 -0
- package/templates/skill-telemetry.sh +199 -0
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Tests for `skillsmith telemetry` subcommands.
|
|
3
|
+
* @module @skillsmith/cli/commands/telemetry.test
|
|
4
|
+
* @see SMI-5021 Wave 3 Step 2 — plan lines 700, 703, 706
|
|
5
|
+
*
|
|
6
|
+
* Covers:
|
|
7
|
+
* enable: fresh manifest → generates id, sets enabled=true; idempotent on re-run
|
|
8
|
+
* disable: enabled manifest → sets enabled=false; anonymousId preserved
|
|
9
|
+
* status: prints expected shape (ID tail only); detects + triggers rotation when backdated >365d
|
|
10
|
+
* reset-id: rotates unconditionally; new id distinct; previous id populated
|
|
11
|
+
* install-hook (mocked): adds PreToolUse+PostToolUse; idempotent; throws on foreign Skill matcher
|
|
12
|
+
* uninstall-hook: removes only Skillsmith entries; preserves foreign hooks
|
|
13
|
+
* install-hook --scope project: writes to ./.claude/settings.json
|
|
14
|
+
*
|
|
15
|
+
* Privacy invariant: idTail() — last 8 chars only, never full id.
|
|
16
|
+
*/
|
|
17
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// fs/promises mock (for manifest.ts)
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
const memfsAsync = {};
|
|
22
|
+
vi.mock('fs/promises', () => ({
|
|
23
|
+
mkdir: vi.fn(async () => undefined),
|
|
24
|
+
writeFile: vi.fn(async (path, content) => {
|
|
25
|
+
memfsAsync[path] = content;
|
|
26
|
+
}),
|
|
27
|
+
rename: vi.fn(async (src, dst) => {
|
|
28
|
+
const content = memfsAsync[src];
|
|
29
|
+
if (content === undefined)
|
|
30
|
+
throw Object.assign(new Error(`ENOENT: ${src}`), { code: 'ENOENT' });
|
|
31
|
+
memfsAsync[dst] = content;
|
|
32
|
+
delete memfsAsync[src];
|
|
33
|
+
}),
|
|
34
|
+
readFile: vi.fn(async (path) => {
|
|
35
|
+
const content = memfsAsync[path];
|
|
36
|
+
if (content === undefined)
|
|
37
|
+
throw Object.assign(new Error(`ENOENT: ${path}`), { code: 'ENOENT' });
|
|
38
|
+
return content;
|
|
39
|
+
}),
|
|
40
|
+
}));
|
|
41
|
+
// ---------------------------------------------------------------------------
|
|
42
|
+
// node:fs mock (for telemetry.helpers.ts — settings.json operations)
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
const memfsSync = {};
|
|
45
|
+
vi.mock('node:fs', () => ({
|
|
46
|
+
existsSync: vi.fn((p) => p in memfsSync),
|
|
47
|
+
readFileSync: vi.fn((path) => {
|
|
48
|
+
const c = memfsSync[path];
|
|
49
|
+
if (c === undefined)
|
|
50
|
+
throw Object.assign(new Error(`ENOENT: ${path}`), { code: 'ENOENT' });
|
|
51
|
+
return c;
|
|
52
|
+
}),
|
|
53
|
+
writeFileSync: vi.fn((path, content) => {
|
|
54
|
+
memfsSync[path] = content;
|
|
55
|
+
}),
|
|
56
|
+
renameSync: vi.fn((src, dst) => {
|
|
57
|
+
const c = memfsSync[src];
|
|
58
|
+
if (c === undefined)
|
|
59
|
+
throw new Error(`ENOENT: ${src}`);
|
|
60
|
+
memfsSync[dst] = c;
|
|
61
|
+
delete memfsSync[src];
|
|
62
|
+
}),
|
|
63
|
+
mkdirSync: vi.fn(() => undefined),
|
|
64
|
+
chmodSync: vi.fn(() => undefined),
|
|
65
|
+
copyFileSync: vi.fn((src, dst) => {
|
|
66
|
+
memfsSync[dst] = memfsSync[src] ?? '# stub hook script';
|
|
67
|
+
}),
|
|
68
|
+
unlinkSync: vi.fn((p) => {
|
|
69
|
+
delete memfsSync[p];
|
|
70
|
+
}),
|
|
71
|
+
readdirSync: vi.fn(() => []),
|
|
72
|
+
statSync: vi.fn(() => ({ mtimeMs: Date.now() - 1000 })),
|
|
73
|
+
}));
|
|
74
|
+
// ---------------------------------------------------------------------------
|
|
75
|
+
// Import after mocks are registered
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
import { runEnable, runDisable, runStatus, runResetId, runInstallHook, runUninstallHook, idTail, } from './telemetry.js';
|
|
78
|
+
import { loadManifest, saveManifest, generateAnonymousId, } from '../utils/manifest.js';
|
|
79
|
+
import { resolveSettingsPath } from './telemetry.helpers.js';
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
// Helpers
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
function daysAgo(n) {
|
|
84
|
+
return new Date(Date.now() - n * 86_400_000).toISOString();
|
|
85
|
+
}
|
|
86
|
+
async function seedManifest(telemetry) {
|
|
87
|
+
await saveManifest({ version: '1.0.0', installedSkills: {}, telemetry });
|
|
88
|
+
}
|
|
89
|
+
function captureConsole() {
|
|
90
|
+
const lines = [];
|
|
91
|
+
const origLog = console.log;
|
|
92
|
+
const origWarn = console.warn;
|
|
93
|
+
const origError = console.error;
|
|
94
|
+
vi.spyOn(console, 'log').mockImplementation((...args) => lines.push(args.join(' ')));
|
|
95
|
+
vi.spyOn(console, 'warn').mockImplementation((...args) => lines.push(args.join(' ')));
|
|
96
|
+
vi.spyOn(console, 'error').mockImplementation((...args) => lines.push(args.join(' ')));
|
|
97
|
+
return {
|
|
98
|
+
lines,
|
|
99
|
+
restore() {
|
|
100
|
+
console.log = origLog;
|
|
101
|
+
console.warn = origWarn;
|
|
102
|
+
console.error = origError;
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
// ---------------------------------------------------------------------------
|
|
107
|
+
// Setup / teardown
|
|
108
|
+
// ---------------------------------------------------------------------------
|
|
109
|
+
beforeEach(() => {
|
|
110
|
+
for (const k of Object.keys(memfsAsync))
|
|
111
|
+
delete memfsAsync[k];
|
|
112
|
+
for (const k of Object.keys(memfsSync))
|
|
113
|
+
delete memfsSync[k];
|
|
114
|
+
vi.clearAllMocks();
|
|
115
|
+
});
|
|
116
|
+
afterEach(() => {
|
|
117
|
+
for (const k of Object.keys(memfsAsync))
|
|
118
|
+
delete memfsAsync[k];
|
|
119
|
+
for (const k of Object.keys(memfsSync))
|
|
120
|
+
delete memfsSync[k];
|
|
121
|
+
vi.restoreAllMocks();
|
|
122
|
+
});
|
|
123
|
+
// ---------------------------------------------------------------------------
|
|
124
|
+
// enable
|
|
125
|
+
// ---------------------------------------------------------------------------
|
|
126
|
+
describe('telemetry enable', () => {
|
|
127
|
+
it('generates an anonymousId and sets enabled=true on fresh manifest', async () => {
|
|
128
|
+
await runEnable();
|
|
129
|
+
const m = await loadManifest();
|
|
130
|
+
expect(m.telemetry?.enabled).toBe(true);
|
|
131
|
+
expect(m.telemetry?.anonymousId).toMatch(/^[0-9a-f]{64}$/);
|
|
132
|
+
expect(m.telemetry?.anonymousIdCreatedAt).toBeDefined();
|
|
133
|
+
expect(m.telemetry?.scope).toBe('personal');
|
|
134
|
+
});
|
|
135
|
+
it('is idempotent — second enable does not change the anonymousId', async () => {
|
|
136
|
+
await runEnable();
|
|
137
|
+
const firstId = (await loadManifest()).telemetry?.anonymousId;
|
|
138
|
+
await runEnable();
|
|
139
|
+
const secondId = (await loadManifest()).telemetry?.anonymousId;
|
|
140
|
+
expect(firstId).toBe(secondId);
|
|
141
|
+
});
|
|
142
|
+
it('does not overwrite an existing anonymousId when re-enabling after disable', async () => {
|
|
143
|
+
const existingId = generateAnonymousId();
|
|
144
|
+
await seedManifest({ enabled: false, anonymousId: existingId });
|
|
145
|
+
await runEnable();
|
|
146
|
+
const m = await loadManifest();
|
|
147
|
+
expect(m.telemetry?.anonymousId).toBe(existingId);
|
|
148
|
+
expect(m.telemetry?.enabled).toBe(true);
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
// ---------------------------------------------------------------------------
|
|
152
|
+
// disable
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
describe('telemetry disable', () => {
|
|
155
|
+
it('sets enabled=false while preserving the anonymousId', async () => {
|
|
156
|
+
const id = generateAnonymousId();
|
|
157
|
+
await seedManifest({ enabled: true, anonymousId: id });
|
|
158
|
+
await runDisable();
|
|
159
|
+
const m = await loadManifest();
|
|
160
|
+
expect(m.telemetry?.enabled).toBe(false);
|
|
161
|
+
// anonymousId must be preserved for re-enable continuity (plan line 719)
|
|
162
|
+
expect(m.telemetry?.anonymousId).toBe(id);
|
|
163
|
+
});
|
|
164
|
+
it('is a no-op when already disabled', async () => {
|
|
165
|
+
await seedManifest({ enabled: false });
|
|
166
|
+
const cap = captureConsole();
|
|
167
|
+
try {
|
|
168
|
+
await runDisable();
|
|
169
|
+
}
|
|
170
|
+
finally {
|
|
171
|
+
cap.restore();
|
|
172
|
+
}
|
|
173
|
+
expect(cap.lines.some((l) => l.includes('already disabled'))).toBe(true);
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
// ---------------------------------------------------------------------------
|
|
177
|
+
// status
|
|
178
|
+
// ---------------------------------------------------------------------------
|
|
179
|
+
describe('telemetry status', () => {
|
|
180
|
+
it('prints anonymousId-tail (last 8 chars) but not the full id', async () => {
|
|
181
|
+
const id = generateAnonymousId();
|
|
182
|
+
await seedManifest({
|
|
183
|
+
enabled: true,
|
|
184
|
+
anonymousId: id,
|
|
185
|
+
anonymousIdCreatedAt: new Date().toISOString(),
|
|
186
|
+
scope: 'personal',
|
|
187
|
+
});
|
|
188
|
+
const cap = captureConsole();
|
|
189
|
+
try {
|
|
190
|
+
await runStatus();
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
cap.restore();
|
|
194
|
+
}
|
|
195
|
+
const output = cap.lines.join('\n');
|
|
196
|
+
// Privacy: tail only
|
|
197
|
+
expect(output).toContain(`...${id.slice(-8)}`);
|
|
198
|
+
// Privacy: full id must not appear
|
|
199
|
+
expect(output).not.toContain(id);
|
|
200
|
+
});
|
|
201
|
+
it('triggers rotation and reports "rotation triggered" when anonymousIdCreatedAt > 365d ago', async () => {
|
|
202
|
+
const oldId = generateAnonymousId();
|
|
203
|
+
await seedManifest({
|
|
204
|
+
enabled: true,
|
|
205
|
+
anonymousId: oldId,
|
|
206
|
+
anonymousIdCreatedAt: daysAgo(400),
|
|
207
|
+
});
|
|
208
|
+
const cap = captureConsole();
|
|
209
|
+
try {
|
|
210
|
+
await runStatus();
|
|
211
|
+
}
|
|
212
|
+
finally {
|
|
213
|
+
cap.restore();
|
|
214
|
+
}
|
|
215
|
+
const output = cap.lines.join('\n');
|
|
216
|
+
expect(output.toLowerCase()).toContain('rotation triggered');
|
|
217
|
+
// The manifest should now have a new id
|
|
218
|
+
const m = await loadManifest();
|
|
219
|
+
expect(m.telemetry?.anonymousId).not.toBe(oldId);
|
|
220
|
+
expect(m.telemetry?.previousAnonymousId).toBe(oldId);
|
|
221
|
+
});
|
|
222
|
+
it('shows enabled=no when telemetry is disabled', async () => {
|
|
223
|
+
await seedManifest({ enabled: false });
|
|
224
|
+
const cap = captureConsole();
|
|
225
|
+
try {
|
|
226
|
+
await runStatus();
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
cap.restore();
|
|
230
|
+
}
|
|
231
|
+
const output = cap.lines.join('\n');
|
|
232
|
+
expect(output).toContain('no');
|
|
233
|
+
expect(output.toLowerCase()).toContain('enabled');
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
// ---------------------------------------------------------------------------
|
|
237
|
+
// reset-id
|
|
238
|
+
// ---------------------------------------------------------------------------
|
|
239
|
+
describe('telemetry reset-id', () => {
|
|
240
|
+
it('rotates unconditionally even when id is young (< 365d)', async () => {
|
|
241
|
+
const currentId = generateAnonymousId();
|
|
242
|
+
await seedManifest({
|
|
243
|
+
enabled: true,
|
|
244
|
+
anonymousId: currentId,
|
|
245
|
+
anonymousIdCreatedAt: new Date().toISOString(), // brand new
|
|
246
|
+
});
|
|
247
|
+
await runResetId();
|
|
248
|
+
const m = await loadManifest();
|
|
249
|
+
expect(m.telemetry?.anonymousId).toBeDefined();
|
|
250
|
+
expect(m.telemetry?.anonymousId).not.toBe(currentId);
|
|
251
|
+
});
|
|
252
|
+
it('populates previousAnonymousId with the old id', async () => {
|
|
253
|
+
const currentId = generateAnonymousId();
|
|
254
|
+
await seedManifest({
|
|
255
|
+
enabled: true,
|
|
256
|
+
anonymousId: currentId,
|
|
257
|
+
anonymousIdCreatedAt: new Date().toISOString(),
|
|
258
|
+
});
|
|
259
|
+
await runResetId();
|
|
260
|
+
const m = await loadManifest();
|
|
261
|
+
expect(m.telemetry?.previousAnonymousId).toBe(currentId);
|
|
262
|
+
});
|
|
263
|
+
it('new id is distinct from current and previous', async () => {
|
|
264
|
+
const currentId = generateAnonymousId();
|
|
265
|
+
const previousId = generateAnonymousId();
|
|
266
|
+
await seedManifest({
|
|
267
|
+
enabled: true,
|
|
268
|
+
anonymousId: currentId,
|
|
269
|
+
previousAnonymousId: previousId,
|
|
270
|
+
anonymousIdCreatedAt: new Date().toISOString(),
|
|
271
|
+
});
|
|
272
|
+
await runResetId();
|
|
273
|
+
const m = await loadManifest();
|
|
274
|
+
const newId = m.telemetry?.anonymousId;
|
|
275
|
+
expect(newId).toBeDefined();
|
|
276
|
+
expect(newId).not.toBe(currentId);
|
|
277
|
+
expect(newId).not.toBe(previousId);
|
|
278
|
+
});
|
|
279
|
+
it('prints new ID tail (not full id) to stdout', async () => {
|
|
280
|
+
const currentId = generateAnonymousId();
|
|
281
|
+
await seedManifest({
|
|
282
|
+
enabled: true,
|
|
283
|
+
anonymousId: currentId,
|
|
284
|
+
anonymousIdCreatedAt: new Date().toISOString(),
|
|
285
|
+
});
|
|
286
|
+
const cap = captureConsole();
|
|
287
|
+
try {
|
|
288
|
+
await runResetId();
|
|
289
|
+
}
|
|
290
|
+
finally {
|
|
291
|
+
cap.restore();
|
|
292
|
+
}
|
|
293
|
+
const m = await loadManifest();
|
|
294
|
+
const newId = m.telemetry?.anonymousId;
|
|
295
|
+
if (!newId)
|
|
296
|
+
throw new Error('telemetry.anonymousId missing after runResetId');
|
|
297
|
+
const output = cap.lines.join('\n');
|
|
298
|
+
// Tail visible
|
|
299
|
+
expect(output).toContain(`...${newId.slice(-8)}`);
|
|
300
|
+
// Full new id NOT in output
|
|
301
|
+
expect(output).not.toContain(newId);
|
|
302
|
+
});
|
|
303
|
+
});
|
|
304
|
+
// Shared constant — used by both install-hook and uninstall-hook describe blocks.
|
|
305
|
+
const HOOK_PATH_TEST = `${process.env['HOME'] ?? '/tmp'}/.skillsmith/hooks/skill-telemetry.sh`;
|
|
306
|
+
// ---------------------------------------------------------------------------
|
|
307
|
+
// install-hook
|
|
308
|
+
// ---------------------------------------------------------------------------
|
|
309
|
+
describe('telemetry install-hook', () => {
|
|
310
|
+
it('adds PreToolUse and PostToolUse Skill entries to empty settings.json', async () => {
|
|
311
|
+
// Seed template in memfsSync so copyFileSync does not throw
|
|
312
|
+
memfsSync['/stub/templates/skill-telemetry.sh'] = '#!/bin/sh\n';
|
|
313
|
+
// Mock existsSync to return true for template path
|
|
314
|
+
const { existsSync } = await import('node:fs');
|
|
315
|
+
existsSync.mockImplementation((p) => {
|
|
316
|
+
if (String(p).includes('skill-telemetry.sh') && !String(p).includes('.skillsmith/hooks'))
|
|
317
|
+
return true;
|
|
318
|
+
return p in memfsSync;
|
|
319
|
+
});
|
|
320
|
+
await runInstallHook({ scope: 'user' });
|
|
321
|
+
const settingsPath = resolveSettingsPath('user');
|
|
322
|
+
const raw = memfsSync[settingsPath];
|
|
323
|
+
expect(raw).toBeDefined();
|
|
324
|
+
const parsed = JSON.parse(raw);
|
|
325
|
+
expect(parsed.hooks.PreToolUse).toHaveLength(1);
|
|
326
|
+
expect(parsed.hooks.PostToolUse).toHaveLength(1);
|
|
327
|
+
});
|
|
328
|
+
it('is idempotent — installing twice does not add duplicate entries', async () => {
|
|
329
|
+
const { existsSync } = await import('node:fs');
|
|
330
|
+
existsSync.mockImplementation((p) => {
|
|
331
|
+
if (String(p).includes('skill-telemetry.sh') && !String(p).includes('.skillsmith/hooks'))
|
|
332
|
+
return true;
|
|
333
|
+
return p in memfsSync;
|
|
334
|
+
});
|
|
335
|
+
await runInstallHook({ scope: 'user' });
|
|
336
|
+
await runInstallHook({ scope: 'user' });
|
|
337
|
+
const settingsPath = resolveSettingsPath('user');
|
|
338
|
+
const parsed = JSON.parse(memfsSync[settingsPath]);
|
|
339
|
+
expect(parsed.hooks.PreToolUse).toHaveLength(1);
|
|
340
|
+
});
|
|
341
|
+
it('uses ./.claude/settings.json when scope is project', async () => {
|
|
342
|
+
const { existsSync } = await import('node:fs');
|
|
343
|
+
existsSync.mockImplementation((p) => {
|
|
344
|
+
if (String(p).includes('skill-telemetry.sh') && !String(p).includes('.skillsmith/hooks'))
|
|
345
|
+
return true;
|
|
346
|
+
return p in memfsSync;
|
|
347
|
+
});
|
|
348
|
+
await runInstallHook({ scope: 'project' });
|
|
349
|
+
const projectPath = resolveSettingsPath('project');
|
|
350
|
+
expect(memfsSync[projectPath]).toBeDefined();
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
// ---------------------------------------------------------------------------
|
|
354
|
+
// uninstall-hook
|
|
355
|
+
// ---------------------------------------------------------------------------
|
|
356
|
+
describe('telemetry uninstall-hook', () => {
|
|
357
|
+
it('removes only Skillsmith entries; does not touch foreign hooks', async () => {
|
|
358
|
+
// Seed settings with a Bash hook + Skillsmith Skill hook
|
|
359
|
+
const settingsPath = resolveSettingsPath('user');
|
|
360
|
+
memfsSync[settingsPath] = JSON.stringify({
|
|
361
|
+
hooks: {
|
|
362
|
+
PreToolUse: [
|
|
363
|
+
{ matcher: 'Bash', hooks: [{ type: 'command', command: 'echo bash' }] },
|
|
364
|
+
{ matcher: 'Skill', hooks: [{ type: 'command', command: `${HOOK_PATH_TEST} pre` }] },
|
|
365
|
+
],
|
|
366
|
+
PostToolUse: [
|
|
367
|
+
{ matcher: 'Skill', hooks: [{ type: 'command', command: `${HOOK_PATH_TEST} post` }] },
|
|
368
|
+
],
|
|
369
|
+
},
|
|
370
|
+
});
|
|
371
|
+
await runUninstallHook({ scope: 'user' });
|
|
372
|
+
const raw = memfsSync[settingsPath];
|
|
373
|
+
expect(raw).toBeDefined();
|
|
374
|
+
const parsed = JSON.parse(raw);
|
|
375
|
+
// Bash hook preserved
|
|
376
|
+
expect(parsed.hooks.PreToolUse.some((e) => e.matcher === 'Bash')).toBe(true);
|
|
377
|
+
// Skill hook removed
|
|
378
|
+
expect(parsed.hooks.PreToolUse.some((e) => e.matcher === 'Skill')).toBe(false);
|
|
379
|
+
expect(parsed.hooks.PostToolUse.some((e) => e.matcher === 'Skill')).toBe(false);
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
// ---------------------------------------------------------------------------
|
|
383
|
+
// idTail — privacy invariant unit test
|
|
384
|
+
// ---------------------------------------------------------------------------
|
|
385
|
+
describe('idTail privacy invariant', () => {
|
|
386
|
+
it('returns only the last 8 characters of the id', () => {
|
|
387
|
+
const id = 'a'.repeat(56) + 'b'.repeat(8);
|
|
388
|
+
expect(idTail(id)).toBe('...bbbbbbbb');
|
|
389
|
+
expect(idTail(id)).not.toContain('a'.repeat(56));
|
|
390
|
+
});
|
|
391
|
+
it('returns (none) when id is undefined', () => {
|
|
392
|
+
expect(idTail(undefined)).toBe('(none)');
|
|
393
|
+
});
|
|
394
|
+
it('never leaks the full SHA-256 hex (64 chars) in the returned string', () => {
|
|
395
|
+
const id = generateAnonymousId();
|
|
396
|
+
const tail = idTail(id);
|
|
397
|
+
expect(tail.length).toBeLessThan(20); // "..." + 8 chars = 11 chars max
|
|
398
|
+
expect(tail).not.toBe(id);
|
|
399
|
+
});
|
|
400
|
+
});
|
|
401
|
+
//# sourceMappingURL=telemetry.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.test.js","sourceRoot":"","sources":["../../../src/commands/telemetry.test.ts"],"names":[],"mappings":"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"}
|
package/dist/src/index.js
CHANGED
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
* - setup: Install skillsmith skill for /skillsmith slash command (SMI-824, renamed from install-skill)
|
|
20
20
|
*/
|
|
21
21
|
import { Command } from 'commander';
|
|
22
|
-
import { createSearchCommand, createListCommand, createUpdateCommand, createRemoveCommand, createInitCommand, createValidateCommand, createPublishCommand, createSubagentCommand, createTransformCommand, createMcpInitCommand, createAnalyzeCommand, createRecommendCommand, createSyncCommand, createInstallCommand, createInstallSkillCommand, createLoginCommand, createLogoutCommand, createWhoamiCommand, createDiffCommand, createPinCommand, createUnpinCommand, createAuditCommand, createCreateCommand, createInfoCommand, createImportCommand, createImportLocalCommand, createConfigCommand, } from './commands/index.js';
|
|
22
|
+
import { createSearchCommand, createListCommand, createUpdateCommand, createRemoveCommand, createInitCommand, createValidateCommand, createPublishCommand, createSubagentCommand, createTransformCommand, createMcpInitCommand, createAnalyzeCommand, createRecommendCommand, createSyncCommand, createInstallCommand, createInstallSkillCommand, createLoginCommand, createLogoutCommand, createWhoamiCommand, createDiffCommand, createPinCommand, createUnpinCommand, createAuditCommand, createCreateCommand, createInfoCommand, createImportCommand, createImportLocalCommand, createConfigCommand, createTelemetryCommand, } from './commands/index.js';
|
|
23
23
|
import { displayStartupHeader } from './utils/license.js';
|
|
24
24
|
import { checkNodeVersion } from './utils/node-version.js';
|
|
25
25
|
import { readFileSync } from 'fs';
|
|
@@ -107,5 +107,7 @@ program.addCommand(createCreateCommand());
|
|
|
107
107
|
program.addCommand(createInfoCommand());
|
|
108
108
|
// SMI-4590 Wave 4 PR 5/6: `sklx config get/set audit_mode`
|
|
109
109
|
program.addCommand(createConfigCommand());
|
|
110
|
+
// SMI-5021 Wave 3: telemetry opt-in + Claude Code hook management
|
|
111
|
+
program.addCommand(createTelemetryCommand());
|
|
110
112
|
program.parse();
|
|
111
113
|
//# sourceMappingURL=index.js.map
|
package/dist/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,oBAAoB,EACpB,qBAAqB,EACrB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,iBAAiB,EACjB,oBAAoB,EACpB,yBAAyB,EACzB,kBAAkB,EAClB,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,kBAAkB,EAClB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* @fileoverview Thin manifest reader for the Skillsmith CLI
|
|
3
3
|
* @module @skillsmith/cli/utils/manifest
|
|
4
4
|
* @see SMI-skill-version-tracking Wave 2
|
|
5
|
+
* @see SMI-5012 Wave 3: telemetry block + annual anonymous_id rotation
|
|
5
6
|
*
|
|
6
7
|
* Reads (and optionally writes) the ~/.skillsmith/manifest.json file.
|
|
7
8
|
* This mirrors the SkillManifest types defined in
|
|
@@ -10,6 +11,14 @@
|
|
|
10
11
|
*
|
|
11
12
|
* The CLI owns its own read path; write operations (pin/unpin) use
|
|
12
13
|
* updateManifestEntry below which does an atomic temp-file rename.
|
|
14
|
+
*
|
|
15
|
+
* Concurrency note (v1): the atomic temp-file rename guarantees readers never
|
|
16
|
+
* see partial writes (POSIX rename(2) is atomic). A full file-lock (proper-lockfile)
|
|
17
|
+
* is NOT used here because proper-lockfile is not in the CLI's dependencies.
|
|
18
|
+
* v1 assumes single-writer-per-process; concurrent writers from the same machine
|
|
19
|
+
* (e.g., two concurrent `skillsmith telemetry` calls) may last-write-wins.
|
|
20
|
+
* This matches the shared-state matrix entry (plan line 715) which notes the
|
|
21
|
+
* proper-lockfile pattern but is aspirational for v2.
|
|
13
22
|
*/
|
|
14
23
|
export interface SkillManifestEntry {
|
|
15
24
|
id: string;
|
|
@@ -28,6 +37,41 @@ export interface SkillManifestEntry {
|
|
|
28
37
|
export interface SkillManifest {
|
|
29
38
|
version: string;
|
|
30
39
|
installedSkills: Record<string, SkillManifestEntry>;
|
|
40
|
+
/** SMI-5012 W3: telemetry opt-in block. Absent on older configs; treated as { enabled: false }. */
|
|
41
|
+
telemetry?: TelemetryManifest;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Telemetry configuration stored in ~/.skillsmith/manifest.json.
|
|
45
|
+
*
|
|
46
|
+
* Schema is additive: older configs without this block continue to load
|
|
47
|
+
* (missing block is treated as { enabled: false } everywhere it is read).
|
|
48
|
+
*
|
|
49
|
+
* anonymous_id rotation policy (U6 / M7):
|
|
50
|
+
* - Generated via SHA-256(crypto.randomUUID()) on first opt-in
|
|
51
|
+
* - Auto-rotates after 365 days (checked on `skillsmith telemetry status`)
|
|
52
|
+
* - One-week overlap window: previous id is retained in previousAnonymousId
|
|
53
|
+
* until previousAnonymousIdRetiredAt so cross-rotation events can be joined
|
|
54
|
+
* - Manual rotation: `skillsmith telemetry reset-id` (SMI-5021)
|
|
55
|
+
*/
|
|
56
|
+
export interface TelemetryManifest {
|
|
57
|
+
/** Whether telemetry is enabled. Always opt-in; default false. */
|
|
58
|
+
enabled: boolean;
|
|
59
|
+
/** SHA-256 hex of a random UUID; 64 hex chars. Present only when enabled. */
|
|
60
|
+
anonymousId?: string;
|
|
61
|
+
/** ISO-8601 date when anonymousId was generated. Enables annual rotation check. */
|
|
62
|
+
anonymousIdCreatedAt?: string;
|
|
63
|
+
/** Previous anonymousId retained for one-week overlap window after rotation. */
|
|
64
|
+
previousAnonymousId?: string;
|
|
65
|
+
/** ISO-8601 date after which previousAnonymousId can be swept. */
|
|
66
|
+
previousAnonymousIdRetiredAt?: string;
|
|
67
|
+
/** Telemetry scope. Default 'personal'. */
|
|
68
|
+
scope?: 'personal' | 'team';
|
|
69
|
+
/** Present when scope === 'team'. */
|
|
70
|
+
teamId?: string;
|
|
71
|
+
/** Override for staging. Default: prod events endpoint. */
|
|
72
|
+
endpoint?: string;
|
|
73
|
+
/** ISO-8601 date when the Claude Code hook was last installed. */
|
|
74
|
+
installedAt?: string;
|
|
31
75
|
}
|
|
32
76
|
export declare const MANIFEST_PATH: string;
|
|
33
77
|
/**
|
|
@@ -43,4 +87,35 @@ export declare function saveManifest(manifest: SkillManifest): Promise<void>;
|
|
|
43
87
|
* Load the manifest, apply an update function, and save atomically.
|
|
44
88
|
*/
|
|
45
89
|
export declare function updateManifestEntry(updateFn: (manifest: SkillManifest) => SkillManifest): Promise<void>;
|
|
90
|
+
/**
|
|
91
|
+
* Generate a new anonymous telemetry id.
|
|
92
|
+
*
|
|
93
|
+
* Returns SHA-256(crypto.randomUUID()) as a 64-character lowercase hex string.
|
|
94
|
+
* The UUID is not stored; only the hash reaches the wire (plan line 719).
|
|
95
|
+
*/
|
|
96
|
+
export declare function generateAnonymousId(): string;
|
|
97
|
+
/**
|
|
98
|
+
* Returns true if the manifest's anonymousId should be rotated.
|
|
99
|
+
*
|
|
100
|
+
* Rotation is triggered when anonymousIdCreatedAt is older than 365 days.
|
|
101
|
+
* Returns false if the field is absent (id was never generated).
|
|
102
|
+
*/
|
|
103
|
+
export declare function shouldRotateAnonymousId(manifest: SkillManifest): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Rotate the anonymous id.
|
|
106
|
+
*
|
|
107
|
+
* Moves the current id to previousAnonymousId with a 7-day retirement window,
|
|
108
|
+
* generates a fresh id, and updates anonymousIdCreatedAt to now.
|
|
109
|
+
* Returns a new TelemetryManifest — does NOT write to disk.
|
|
110
|
+
* Callers must persist via saveManifest / updateManifestEntry.
|
|
111
|
+
*/
|
|
112
|
+
export declare function rotateAnonymousId(manifest: SkillManifest): TelemetryManifest;
|
|
113
|
+
/**
|
|
114
|
+
* Remove previousAnonymousId once its retirement window has passed.
|
|
115
|
+
*
|
|
116
|
+
* Should be called on every `skillsmith telemetry status` run and before
|
|
117
|
+
* each hook-script read. No-op if the window has not yet elapsed or if
|
|
118
|
+
* there is no previous id. Returns a new TelemetryManifest.
|
|
119
|
+
*/
|
|
120
|
+
export declare function sweepExpiredPreviousId(manifest: SkillManifest): TelemetryManifest;
|
|
46
121
|
//# sourceMappingURL=manifest.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/utils/manifest.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/utils/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAWH,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,sEAAsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;CAC3C;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IACnD,mGAAmG;IACnG,SAAS,CAAC,EAAE,iBAAiB,CAAA;CAC9B;AAMD;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,OAAO,EAAE,OAAO,CAAA;IAChB,6EAA6E;IAC7E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,mFAAmF;IACnF,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,gFAAgF;IAChF,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,kEAAkE;IAClE,4BAA4B,CAAC,EAAE,MAAM,CAAA;IACrC,2CAA2C;IAC3C,KAAK,CAAC,EAAE,UAAU,GAAG,MAAM,CAAA;IAC3B,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAA;CACrB;AAOD,eAAO,MAAM,aAAa,QAAwC,CAAA;AAMlE;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAO3D;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAKzE;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,CAAC,QAAQ,EAAE,aAAa,KAAK,aAAa,GACnD,OAAO,CAAC,IAAI,CAAC,CAIf;AAUD;;;;;GAKG;AACH,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAKxE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,aAAa,GAAG,iBAAiB,CAc5E;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,aAAa,GAAG,iBAAiB,CAOjF"}
|