skillfish 1.0.1 → 1.0.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/README.md +2 -2
- package/dist/commands/add.js +7 -2
- package/dist/index.js +0 -0
- package/dist/telemetry.d.ts +4 -6
- package/dist/telemetry.js +19 -12
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Install AI agent skills from GitHub with a single command.
|
|
4
4
|
|
|
5
5
|
```bash
|
|
6
|
-
npx skillfish owner/repo
|
|
6
|
+
npx skillfish add owner/repo
|
|
7
7
|
```
|
|
8
8
|
|
|
9
9
|
## Overview
|
|
@@ -159,7 +159,7 @@ This CLI collects anonymous, aggregate install counts to understand skill popula
|
|
|
159
159
|
To opt out, set `DO_NOT_TRACK=1` in your environment:
|
|
160
160
|
|
|
161
161
|
```bash
|
|
162
|
-
DO_NOT_TRACK=1 npx skillfish owner/repo
|
|
162
|
+
DO_NOT_TRACK=1 npx skillfish add owner/repo
|
|
163
163
|
```
|
|
164
164
|
|
|
165
165
|
Telemetry is also automatically disabled in CI environments (`CI=true`).
|
package/dist/commands/add.js
CHANGED
|
@@ -151,6 +151,7 @@ Examples:
|
|
|
151
151
|
// Install each selected skill
|
|
152
152
|
let totalInstalled = 0;
|
|
153
153
|
let totalSkipped = 0;
|
|
154
|
+
const telemetryPromises = [];
|
|
154
155
|
// SECURITY: Ask for confirmation before installation (unless --yes is used)
|
|
155
156
|
// Single confirmation for all selected skills
|
|
156
157
|
if (!trustSource && !jsonMode && isInputTTY()) {
|
|
@@ -221,14 +222,18 @@ Examples:
|
|
|
221
222
|
}
|
|
222
223
|
totalInstalled += result.installed.length;
|
|
223
224
|
totalSkipped += result.skipped.length;
|
|
224
|
-
// Track successful installs (
|
|
225
|
+
// Track successful installs (telemetry with timeout)
|
|
225
226
|
if (result.installed.length > 0) {
|
|
226
227
|
// Construct github value to match skills.github column format: owner/repo/path/to/skill
|
|
227
228
|
const skillDir = skillPath.replace(/\/?SKILL\.md$/i, '').replace(/^\.?\/?/, '');
|
|
228
229
|
const github = skillDir ? `${owner}/${repo}/${skillDir}` : `${owner}/${repo}`;
|
|
229
|
-
trackInstall(github);
|
|
230
|
+
telemetryPromises.push(trackInstall(github));
|
|
230
231
|
}
|
|
231
232
|
}
|
|
233
|
+
// Wait for telemetry to complete (with timeout built into trackInstall)
|
|
234
|
+
if (telemetryPromises.length > 0) {
|
|
235
|
+
await Promise.all(telemetryPromises);
|
|
236
|
+
}
|
|
232
237
|
// Summary
|
|
233
238
|
if (jsonMode) {
|
|
234
239
|
outputJsonAndExit(EXIT_CODES.SUCCESS);
|
package/dist/index.js
CHANGED
|
File without changes
|
package/dist/telemetry.d.ts
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Track a skill install.
|
|
3
|
-
*
|
|
4
|
-
* NOTE: Due to Node.js event loop behavior, this request may not complete
|
|
5
|
-
* if the CLI process exits immediately after calling. This is acceptable
|
|
6
|
-
* for directional metrics (like npm download counts).
|
|
2
|
+
* Track a skill install. Returns a promise that resolves when the request
|
|
3
|
+
* completes (or times out). Never rejects.
|
|
7
4
|
*
|
|
8
5
|
* @param github Full GitHub path (e.g., owner/repo/path/to/skill)
|
|
6
|
+
* @returns Promise that resolves when telemetry is sent (or times out)
|
|
9
7
|
*/
|
|
10
|
-
export declare function trackInstall(github: string): void
|
|
8
|
+
export declare function trackInstall(github: string): Promise<void>;
|
package/dist/telemetry.js
CHANGED
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
const TELEMETRY_URL = 'https://mcpmarket.com/api/telemetry';
|
|
2
|
+
/** Timeout for telemetry requests (ms) */
|
|
3
|
+
const TELEMETRY_TIMEOUT = 2000;
|
|
2
4
|
/**
|
|
3
|
-
* Track a skill install.
|
|
4
|
-
*
|
|
5
|
-
* NOTE: Due to Node.js event loop behavior, this request may not complete
|
|
6
|
-
* if the CLI process exits immediately after calling. This is acceptable
|
|
7
|
-
* for directional metrics (like npm download counts).
|
|
5
|
+
* Track a skill install. Returns a promise that resolves when the request
|
|
6
|
+
* completes (or times out). Never rejects.
|
|
8
7
|
*
|
|
9
8
|
* @param github Full GitHub path (e.g., owner/repo/path/to/skill)
|
|
9
|
+
* @returns Promise that resolves when telemetry is sent (or times out)
|
|
10
10
|
*/
|
|
11
11
|
export function trackInstall(github) {
|
|
12
12
|
try {
|
|
13
|
-
if (process.env.DO_NOT_TRACK === '1' || process.env.CI === 'true')
|
|
14
|
-
return;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
13
|
+
if (process.env.DO_NOT_TRACK === '1' || process.env.CI === 'true') {
|
|
14
|
+
return Promise.resolve();
|
|
15
|
+
}
|
|
16
|
+
if (!github || github.length > 500) {
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
}
|
|
19
|
+
// Race between the fetch and a timeout to ensure we don't block the CLI
|
|
20
|
+
const fetchPromise = fetch(TELEMETRY_URL, {
|
|
19
21
|
method: 'POST',
|
|
20
22
|
headers: { 'Content-Type': 'application/json' },
|
|
21
23
|
body: JSON.stringify({ github }),
|
|
22
|
-
}).catch(() => { });
|
|
24
|
+
}).then(() => { }).catch(() => { });
|
|
25
|
+
const timeoutPromise = new Promise((resolve) => {
|
|
26
|
+
setTimeout(resolve, TELEMETRY_TIMEOUT);
|
|
27
|
+
});
|
|
28
|
+
return Promise.race([fetchPromise, timeoutPromise]);
|
|
23
29
|
}
|
|
24
30
|
catch {
|
|
25
31
|
// Telemetry should never throw
|
|
32
|
+
return Promise.resolve();
|
|
26
33
|
}
|
|
27
34
|
}
|