@muggleai/telemetry 0.2.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.
- package/PRIVACY.md +52 -0
- package/README.md +86 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +96 -0
- package/dist/client.js.map +1 -0
- package/dist/constants/disclosure.d.ts +2 -0
- package/dist/constants/disclosure.d.ts.map +1 -0
- package/dist/constants/disclosure.js +2 -0
- package/dist/constants/disclosure.js.map +1 -0
- package/dist/constants/env.d.ts +4 -0
- package/dist/constants/env.d.ts.map +1 -0
- package/dist/constants/env.js +4 -0
- package/dist/constants/env.js.map +1 -0
- package/dist/constants/manifest.d.ts +3 -0
- package/dist/constants/manifest.d.ts.map +1 -0
- package/dist/constants/manifest.js +8 -0
- package/dist/constants/manifest.js.map +1 -0
- package/dist/constants/paths.d.ts +6 -0
- package/dist/constants/paths.d.ts.map +1 -0
- package/dist/constants/paths.js +6 -0
- package/dist/constants/paths.js.map +1 -0
- package/dist/data-dir.d.ts +3 -0
- package/dist/data-dir.d.ts.map +1 -0
- package/dist/data-dir.js +13 -0
- package/dist/data-dir.js.map +1 -0
- package/dist/disclosure.d.ts +5 -0
- package/dist/disclosure.d.ts.map +1 -0
- package/dist/disclosure.js +18 -0
- package/dist/disclosure.js.map +1 -0
- package/dist/emit.d.ts +3 -0
- package/dist/emit.d.ts.map +1 -0
- package/dist/emit.js +21 -0
- package/dist/emit.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/install-id.d.ts +3 -0
- package/dist/install-id.d.ts.map +1 -0
- package/dist/install-id.js +50 -0
- package/dist/install-id.js.map +1 -0
- package/dist/opt-out.d.ts +3 -0
- package/dist/opt-out.d.ts.map +1 -0
- package/dist/opt-out.js +16 -0
- package/dist/opt-out.js.map +1 -0
- package/dist/preferences.d.ts +7 -0
- package/dist/preferences.d.ts.map +1 -0
- package/dist/preferences.js +39 -0
- package/dist/preferences.js.map +1 -0
- package/dist/release-manifest.d.ts +7 -0
- package/dist/release-manifest.d.ts.map +1 -0
- package/dist/release-manifest.js +56 -0
- package/dist/release-manifest.js.map +1 -0
- package/dist/types/client.d.ts +15 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/client.js +2 -0
- package/dist/types/client.js.map +1 -0
- package/dist/types/events.d.ts +59 -0
- package/dist/types/events.d.ts.map +1 -0
- package/dist/types/events.js +4 -0
- package/dist/types/events.js.map +1 -0
- package/dist/types/install-id.d.ts +4 -0
- package/dist/types/install-id.d.ts.map +1 -0
- package/dist/types/install-id.js +2 -0
- package/dist/types/install-id.js.map +1 -0
- package/dist/types/preferences.d.ts +6 -0
- package/dist/types/preferences.d.ts.map +1 -0
- package/dist/types/preferences.js +2 -0
- package/dist/types/preferences.js.map +1 -0
- package/dist/types/release-manifest.d.ts +8 -0
- package/dist/types/release-manifest.d.ts.map +1 -0
- package/dist/types/release-manifest.js +2 -0
- package/dist/types/release-manifest.js.map +1 -0
- package/dist/types/user-id.d.ts +4 -0
- package/dist/types/user-id.d.ts.map +1 -0
- package/dist/types/user-id.js +2 -0
- package/dist/types/user-id.js.map +1 -0
- package/dist/user-id.d.ts +2 -0
- package/dist/user-id.d.ts.map +1 -0
- package/dist/user-id.js +23 -0
- package/dist/user-id.js.map +1 -0
- package/package.json +49 -0
package/PRIVACY.md
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Privacy
|
|
2
|
+
|
|
3
|
+
Muggle Test client-side telemetry attaches the following fields to every event sent to Azure Application Insights.
|
|
4
|
+
|
|
5
|
+
## Common properties (every event)
|
|
6
|
+
|
|
7
|
+
| Field | Source | Purpose |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `source` | constant `'client'` | Distinguishes from server-auto-collected request spans |
|
|
10
|
+
| `serviceName` | one of `muggle-mcp`, `muggle-electron`, `muggle-skill` | Which surface emitted the event |
|
|
11
|
+
| `surface` | one of `mcp-local`, `mcp-remote`, `skill`, `electron` | Process surface |
|
|
12
|
+
| `release` | release manifest | Product version |
|
|
13
|
+
| `buildId` | release manifest | CI build identifier |
|
|
14
|
+
| `commitSha` | release manifest | Git commit hash |
|
|
15
|
+
| `buildTime` | release manifest | Build timestamp |
|
|
16
|
+
| `installId` | `~/.muggle-ai/install-id.json` | Opaque per-machine UUID, generated on first run, stable across upgrades, lost on uninstall |
|
|
17
|
+
| `userId` | `~/.muggle-ai/oauth-session.json` (when signed in) | Opaque Auth0 subject identifier, **not** the user's email |
|
|
18
|
+
| `nodeVersion` | `process.version` | Node.js version |
|
|
19
|
+
| `platform` | `process.platform` | OS family (`win32`, `darwin`, `linux`) |
|
|
20
|
+
|
|
21
|
+
## Network-level fields attached by Azure (not by this package)
|
|
22
|
+
|
|
23
|
+
- **Source IP**: Azure App Insights records the originating IP on every event (default SDK behavior). Used for geographic aggregation and abuse detection. We do not strip it.
|
|
24
|
+
|
|
25
|
+
## What we do NOT collect
|
|
26
|
+
|
|
27
|
+
- Personal email address
|
|
28
|
+
- OS username
|
|
29
|
+
- Hostname / machine name
|
|
30
|
+
- Absolute file paths
|
|
31
|
+
- File contents (test scripts, source code, configuration)
|
|
32
|
+
- Browser session contents
|
|
33
|
+
|
|
34
|
+
## How to disable
|
|
35
|
+
|
|
36
|
+
Either:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
echo '{"telemetryEnabled": false}' > ~/.muggle-ai/preferences.json
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Or set:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
export MUGGLE_TELEMETRY_DISABLED=1
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
When disabled, no network requests are made, no events are queued, and no disk cache is written.
|
|
49
|
+
|
|
50
|
+
## Data retention
|
|
51
|
+
|
|
52
|
+
Application Insights resources are owned by Multiplex AI. Retention follows the Azure resource's configured retention policy (default 90 days unless otherwise documented).
|
package/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# @muggleai/telemetry
|
|
2
|
+
|
|
3
|
+
Shared client-side telemetry for Muggle Test. Used by:
|
|
4
|
+
|
|
5
|
+
- **MCP** (`muggle-ai-works/packages/mcps`)
|
|
6
|
+
- **Electron app** (`muggle-ai-teaching-service/packages/electron-app`)
|
|
7
|
+
- **Skills** (`muggle-ai-works` skill bundle) — calls into MCP, which calls this package
|
|
8
|
+
|
|
9
|
+
Sends `customEvents` to Azure Application Insights with consistent identity (`installId`, `userId`, `release`, `buildId`, `commitSha`) and a `source: 'client'` tag so dashboards can separate client-emitted events from server-auto-collected request spans.
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { initTelemetry, track } from "@muggleai/telemetry";
|
|
15
|
+
|
|
16
|
+
initTelemetry({ serviceName: "muggle-mcp", surface: "mcp-local" });
|
|
17
|
+
|
|
18
|
+
track({
|
|
19
|
+
name: "mcp.tool.invoked",
|
|
20
|
+
props: {
|
|
21
|
+
toolName: "muggle-local-execute-replay",
|
|
22
|
+
toolSurface: "local",
|
|
23
|
+
correlationId: "abc-123",
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Connection string
|
|
29
|
+
|
|
30
|
+
Read in this order:
|
|
31
|
+
|
|
32
|
+
1. Explicit `initTelemetry({ connectionString })` argument
|
|
33
|
+
2. `APPLICATIONINSIGHTS_CONNECTION_STRING` env var
|
|
34
|
+
3. `VITE_APPLICATIONINSIGHTS_CONNECTION_STRING` env var (Electron-style)
|
|
35
|
+
|
|
36
|
+
When none is set, `initTelemetry()` becomes a no-op — `track()` calls are silently dropped. This keeps the package safe to import in dev environments.
|
|
37
|
+
|
|
38
|
+
## Opt-out
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import { isTelemetryEnabled, setTelemetryEnabled } from "@muggleai/telemetry";
|
|
42
|
+
|
|
43
|
+
if (!isTelemetryEnabled()) { /* nothing will be sent */ }
|
|
44
|
+
setTelemetryEnabled(false); // persists to ~/.muggle-ai/preferences.json
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Or set the env var `MUGGLE_TELEMETRY_DISABLED=1`.
|
|
48
|
+
|
|
49
|
+
## Disclosure
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
import { getDisclosureCopy, hasShownDisclosure, markDisclosureShown } from "@muggleai/telemetry";
|
|
53
|
+
|
|
54
|
+
if (!hasShownDisclosure()) {
|
|
55
|
+
console.log(getDisclosureCopy());
|
|
56
|
+
markDisclosureShown();
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Privacy
|
|
61
|
+
|
|
62
|
+
See [PRIVACY.md](./PRIVACY.md) for the complete list of fields collected.
|
|
63
|
+
|
|
64
|
+
## Design
|
|
65
|
+
|
|
66
|
+
See `muggle-ai-brain/architecture/2026-05-05-mcp-skill-telemetry-design.md` (private repo).
|
|
67
|
+
|
|
68
|
+
## Development
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm install
|
|
72
|
+
npm test # vitest
|
|
73
|
+
npm run typecheck
|
|
74
|
+
npm run build # tsc → dist/
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Releasing
|
|
78
|
+
|
|
79
|
+
Tag and push:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
git tag v0.2.0
|
|
83
|
+
git push --tags
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
The `publish.yml` workflow verifies (typecheck + tests + build) then publishes to public npm via OIDC trusted publishing. No `NPM_TOKEN` secret required — auth is configured on npmjs.com under the package's Trusted Publisher settings.
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { TelemetryClient } from "applicationinsights";
|
|
2
|
+
import type { InitOptions } from "./types/client.js";
|
|
3
|
+
export type { InitOptions } from "./types/client.js";
|
|
4
|
+
export declare function initTelemetry(options: InitOptions): void;
|
|
5
|
+
export declare function getClient(): TelemetryClient | null;
|
|
6
|
+
export declare function isInitialized(): boolean;
|
|
7
|
+
export declare function resetClientForTests(): void;
|
|
8
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAM3D,OAAO,KAAK,EAAe,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAGlE,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAmCrD,wBAAgB,aAAa,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAwDxD;AAED,wBAAgB,SAAS,IAAI,eAAe,GAAG,IAAI,CAElD;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// AppInsights client setup. One process = one client.
|
|
2
|
+
// Common props attached on every event so server-side queries can filter by
|
|
3
|
+
// `source: 'client'`, `serviceName`, `surface`, `installId`, etc.
|
|
4
|
+
import * as AppInsights from "applicationinsights";
|
|
5
|
+
import { ENV_CONNECTION_STRING, ENV_VITE_CONNECTION_STRING } from "./constants/env.js";
|
|
6
|
+
import { getInstallId } from "./install-id.js";
|
|
7
|
+
import { readReleaseManifest } from "./release-manifest.js";
|
|
8
|
+
import { readUserId } from "./user-id.js";
|
|
9
|
+
let state = null;
|
|
10
|
+
function resolveConnectionString(explicit) {
|
|
11
|
+
if (explicit && explicit.length > 0)
|
|
12
|
+
return explicit;
|
|
13
|
+
return (process.env[ENV_CONNECTION_STRING] ??
|
|
14
|
+
process.env[ENV_VITE_CONNECTION_STRING] ??
|
|
15
|
+
undefined);
|
|
16
|
+
}
|
|
17
|
+
function buildCommonProperties(serviceName, surface) {
|
|
18
|
+
const manifest = readReleaseManifest();
|
|
19
|
+
const props = {
|
|
20
|
+
source: "client",
|
|
21
|
+
serviceName,
|
|
22
|
+
surface,
|
|
23
|
+
release: manifest.release,
|
|
24
|
+
buildId: manifest.buildId,
|
|
25
|
+
commitSha: manifest.commitSha,
|
|
26
|
+
buildTime: manifest.buildTime,
|
|
27
|
+
installId: getInstallId(),
|
|
28
|
+
nodeVersion: process.version,
|
|
29
|
+
platform: process.platform,
|
|
30
|
+
};
|
|
31
|
+
const userId = readUserId();
|
|
32
|
+
if (userId !== undefined)
|
|
33
|
+
props.userId = userId;
|
|
34
|
+
return props;
|
|
35
|
+
}
|
|
36
|
+
export function initTelemetry(options) {
|
|
37
|
+
if (state !== null && state.initialized)
|
|
38
|
+
return;
|
|
39
|
+
const connectionString = resolveConnectionString(options.connectionString);
|
|
40
|
+
if (!connectionString) {
|
|
41
|
+
state = {
|
|
42
|
+
client: null,
|
|
43
|
+
serviceName: options.serviceName,
|
|
44
|
+
surface: options.surface,
|
|
45
|
+
initialized: true,
|
|
46
|
+
};
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
AppInsights.setup(connectionString)
|
|
51
|
+
.setUseDiskRetryCaching(true)
|
|
52
|
+
.setDistributedTracingMode(AppInsights.DistributedTracingModes.AI_AND_W3C)
|
|
53
|
+
.setAutoCollectRequests(false)
|
|
54
|
+
.setAutoCollectPerformance(false, false)
|
|
55
|
+
.setAutoCollectExceptions(true)
|
|
56
|
+
.setAutoCollectDependencies(false)
|
|
57
|
+
.setAutoCollectConsole(false)
|
|
58
|
+
.setSendLiveMetrics(false);
|
|
59
|
+
const client = AppInsights.defaultClient;
|
|
60
|
+
const manifest = readReleaseManifest();
|
|
61
|
+
client.context.tags[client.context.keys.cloudRole] = options.serviceName;
|
|
62
|
+
client.context.tags[client.context.keys.applicationVersion] = manifest.release;
|
|
63
|
+
client.commonProperties = {
|
|
64
|
+
...client.commonProperties,
|
|
65
|
+
...buildCommonProperties(options.serviceName, options.surface),
|
|
66
|
+
};
|
|
67
|
+
AppInsights.start();
|
|
68
|
+
state = {
|
|
69
|
+
client,
|
|
70
|
+
serviceName: options.serviceName,
|
|
71
|
+
surface: options.surface,
|
|
72
|
+
initialized: true,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
console.warn("[muggle-telemetry] init failed; events will be dropped", {
|
|
77
|
+
error: err.message,
|
|
78
|
+
});
|
|
79
|
+
state = {
|
|
80
|
+
client: null,
|
|
81
|
+
serviceName: options.serviceName,
|
|
82
|
+
surface: options.surface,
|
|
83
|
+
initialized: true,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
export function getClient() {
|
|
88
|
+
return state?.client ?? null;
|
|
89
|
+
}
|
|
90
|
+
export function isInitialized() {
|
|
91
|
+
return state?.initialized === true;
|
|
92
|
+
}
|
|
93
|
+
export function resetClientForTests() {
|
|
94
|
+
state = null;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,4EAA4E;AAC5E,kEAAkE;AAElE,OAAO,KAAK,WAAW,MAAM,qBAAqB,CAAC;AAGnD,OAAO,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AACvF,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAG5D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C,IAAI,KAAK,GAAuB,IAAI,CAAC;AAErC,SAAS,uBAAuB,CAAC,QAA4B;IAC3D,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IACrD,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC;QACvC,SAAS,CACV,CAAC;AACJ,CAAC;AAED,SAAS,qBAAqB,CAC5B,WAAwB,EACxB,OAAgB;IAEhB,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;IACvC,MAAM,KAAK,GAA2B;QACpC,MAAM,EAAE,QAAQ;QAChB,WAAW;QACX,OAAO;QACP,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,SAAS,EAAE,QAAQ,CAAC,SAAS;QAC7B,SAAS,EAAE,YAAY,EAAE;QACzB,WAAW,EAAE,OAAO,CAAC,OAAO;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC;IACF,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,MAAM,KAAK,SAAS;QAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC;IAChD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAoB;IAChD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,CAAC,WAAW;QAAE,OAAO;IAEhD,MAAM,gBAAgB,GAAG,uBAAuB,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAE3E,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,KAAK,GAAG;YACN,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,WAAW,EAAE,IAAI;SAClB,CAAC;QACF,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,WAAW,CAAC,KAAK,CAAC,gBAAgB,CAAC;aAChC,sBAAsB,CAAC,IAAI,CAAC;aAC5B,yBAAyB,CAAC,WAAW,CAAC,uBAAuB,CAAC,UAAU,CAAC;aACzE,sBAAsB,CAAC,KAAK,CAAC;aAC7B,yBAAyB,CAAC,KAAK,EAAE,KAAK,CAAC;aACvC,wBAAwB,CAAC,IAAI,CAAC;aAC9B,0BAA0B,CAAC,KAAK,CAAC;aACjC,qBAAqB,CAAC,KAAK,CAAC;aAC5B,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAE7B,MAAM,MAAM,GAAG,WAAW,CAAC,aAAa,CAAC;QACzC,MAAM,QAAQ,GAAG,mBAAmB,EAAE,CAAC;QAEvC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC;QACzE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC;QAE/E,MAAM,CAAC,gBAAgB,GAAG;YACxB,GAAG,MAAM,CAAC,gBAAgB;YAC1B,GAAG,qBAAqB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,OAAO,CAAC;SAC/D,CAAC;QAEF,WAAW,CAAC,KAAK,EAAE,CAAC;QAEpB,KAAK,GAAG;YACN,MAAM;YACN,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,CAAC,IAAI,CAAC,wDAAwD,EAAE;YACrE,KAAK,EAAG,GAAa,CAAC,OAAO;SAC9B,CAAC,CAAC;QACH,KAAK,GAAG;YACN,MAAM,EAAE,IAAI;YACZ,WAAW,EAAE,OAAO,CAAC,WAAW;YAChC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,WAAW,EAAE,IAAI;SAClB,CAAC;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,OAAO,KAAK,EAAE,MAAM,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,KAAK,GAAG,IAAI,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export declare const DISCLOSURE_COPY = "Muggle Test collects anonymous usage telemetry \u2014 which features you use, how long they take, and whether they succeed \u2014 to help us improve the product. We attach an opaque install ID, your account ID (when signed in), and your IP. We do not collect file contents, OS username, hostname, or file paths. To opt out, set telemetryEnabled to false in ~/.muggle-ai/preferences.json or run `muggle preferences set telemetryEnabled false`.";
|
|
2
|
+
//# sourceMappingURL=disclosure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disclosure.d.ts","sourceRoot":"","sources":["../../src/constants/disclosure.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,+bAAub,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export const DISCLOSURE_COPY = `Muggle Test collects anonymous usage telemetry — which features you use, how long they take, and whether they succeed — to help us improve the product. We attach an opaque install ID, your account ID (when signed in), and your IP. We do not collect file contents, OS username, hostname, or file paths. To opt out, set telemetryEnabled to false in ~/.muggle-ai/preferences.json or run \`muggle preferences set telemetryEnabled false\`.`;
|
|
2
|
+
//# sourceMappingURL=disclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disclosure.js","sourceRoot":"","sources":["../../src/constants/disclosure.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,obAAob,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const ENV_CONNECTION_STRING = "APPLICATIONINSIGHTS_CONNECTION_STRING";
|
|
2
|
+
export declare const ENV_VITE_CONNECTION_STRING = "VITE_APPLICATIONINSIGHTS_CONNECTION_STRING";
|
|
3
|
+
export declare const ENV_TELEMETRY_DISABLED = "MUGGLE_TELEMETRY_DISABLED";
|
|
4
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/constants/env.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,qBAAqB,0CAA0C,CAAC;AAE7E,eAAO,MAAM,0BAA0B,+CAA+C,CAAC;AAEvF,eAAO,MAAM,sBAAsB,8BAA8B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/constants/env.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,qBAAqB,GAAG,uCAAuC,CAAC;AAE7E,MAAM,CAAC,MAAM,0BAA0B,GAAG,4CAA4C,CAAC;AAEvF,MAAM,CAAC,MAAM,sBAAsB,GAAG,2BAA2B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/constants/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAEpE,eAAO,MAAM,YAAY,EAAE,eAM1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../../src/constants/manifest.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAoB;IAC3C,OAAO,EAAE,KAAK;IACd,OAAO,EAAE,KAAK;IACd,SAAS,EAAE,KAAK;IAChB,SAAS,EAAE,sBAAsB;IACjC,WAAW,EAAE,qBAAqB;CACnC,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const DATA_DIR_NAME = ".muggle-ai";
|
|
2
|
+
export declare const INSTALL_ID_FILENAME = "install-id.json";
|
|
3
|
+
export declare const PREFS_FILENAME = "preferences.json";
|
|
4
|
+
export declare const OAUTH_SESSION_FILENAME = "oauth-session.json";
|
|
5
|
+
export declare const RELEASE_MANIFEST_FILENAME = "release-manifest.json";
|
|
6
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/constants/paths.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,eAAe,CAAC;AAE1C,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD,eAAO,MAAM,cAAc,qBAAqB,CAAC;AAEjD,eAAO,MAAM,sBAAsB,uBAAuB,CAAC;AAE3D,eAAO,MAAM,yBAAyB,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const DATA_DIR_NAME = ".muggle-ai";
|
|
2
|
+
export const INSTALL_ID_FILENAME = "install-id.json";
|
|
3
|
+
export const PREFS_FILENAME = "preferences.json";
|
|
4
|
+
export const OAUTH_SESSION_FILENAME = "oauth-session.json";
|
|
5
|
+
export const RELEASE_MANIFEST_FILENAME = "release-manifest.json";
|
|
6
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/constants/paths.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,YAAY,CAAC;AAE1C,MAAM,CAAC,MAAM,mBAAmB,GAAG,iBAAiB,CAAC;AAErD,MAAM,CAAC,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAEjD,MAAM,CAAC,MAAM,sBAAsB,GAAG,oBAAoB,CAAC;AAE3D,MAAM,CAAC,MAAM,yBAAyB,GAAG,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-dir.d.ts","sourceRoot":"","sources":["../src/data-dir.ts"],"names":[],"mappings":"AAOA,wBAAgB,UAAU,IAAI,MAAM,CAGnC;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEhE"}
|
package/dist/data-dir.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as os from "node:os";
|
|
2
|
+
import * as path from "node:path";
|
|
3
|
+
import { DATA_DIR_NAME } from "./constants/paths.js";
|
|
4
|
+
let dataDirOverride;
|
|
5
|
+
export function getDataDir() {
|
|
6
|
+
if (dataDirOverride !== undefined)
|
|
7
|
+
return dataDirOverride;
|
|
8
|
+
return path.join(os.homedir(), DATA_DIR_NAME);
|
|
9
|
+
}
|
|
10
|
+
export function setDataDirForTests(dir) {
|
|
11
|
+
dataDirOverride = dir;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=data-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"data-dir.js","sourceRoot":"","sources":["../src/data-dir.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAErD,IAAI,eAAmC,CAAC;AAExC,MAAM,UAAU,UAAU;IACxB,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAC1D,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,aAAa,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAuB;IACxD,eAAe,GAAG,GAAG,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DISCLOSURE_COPY } from "./constants/disclosure.js";
|
|
2
|
+
export declare function getDisclosureCopy(): string;
|
|
3
|
+
export declare function hasShownDisclosure(): boolean;
|
|
4
|
+
export declare function markDisclosureShown(now?: Date): void;
|
|
5
|
+
//# sourceMappingURL=disclosure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disclosure.d.ts","sourceRoot":"","sources":["../src/disclosure.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAI5C;AAED,wBAAgB,mBAAmB,CAAC,GAAG,GAAE,IAAiB,GAAG,IAAI,CAEhE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// First-run telemetry disclosure. Stored in preferences.json so MCP, skills,
|
|
2
|
+
// and Electron all share the same "shown" flag.
|
|
3
|
+
import { DISCLOSURE_COPY } from "./constants/disclosure.js";
|
|
4
|
+
import { preferencesFileExists, readPreferences, updatePreference } from "./preferences.js";
|
|
5
|
+
export { DISCLOSURE_COPY } from "./constants/disclosure.js";
|
|
6
|
+
export function getDisclosureCopy() {
|
|
7
|
+
return DISCLOSURE_COPY;
|
|
8
|
+
}
|
|
9
|
+
export function hasShownDisclosure() {
|
|
10
|
+
if (!preferencesFileExists())
|
|
11
|
+
return false;
|
|
12
|
+
const prefs = readPreferences();
|
|
13
|
+
return typeof prefs.disclosureShownAt === "string" && prefs.disclosureShownAt.length > 0;
|
|
14
|
+
}
|
|
15
|
+
export function markDisclosureShown(now = new Date()) {
|
|
16
|
+
updatePreference("disclosureShownAt", now.toISOString());
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=disclosure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"disclosure.js","sourceRoot":"","sources":["../src/disclosure.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gDAAgD;AAEhD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAE5F,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAE5D,MAAM,UAAU,iBAAiB;IAC/B,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,IAAI,CAAC,qBAAqB,EAAE;QAAE,OAAO,KAAK,CAAC;IAC3C,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,OAAO,OAAO,KAAK,CAAC,iBAAiB,KAAK,QAAQ,IAAI,KAAK,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,CAAC;AAC3F,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,MAAY,IAAI,IAAI,EAAE;IACxD,gBAAgB,CAAC,mBAAmB,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;AAC3D,CAAC"}
|
package/dist/emit.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../src/emit.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,wBAAgB,KAAK,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAYjD"}
|
package/dist/emit.js
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Public emit surface. Opt-out is checked at every track() call so flipping
|
|
2
|
+
// the preference takes effect immediately without restart.
|
|
3
|
+
import { getClient } from "./client.js";
|
|
4
|
+
import { isTelemetryEnabled } from "./opt-out.js";
|
|
5
|
+
export function track(event) {
|
|
6
|
+
if (!isTelemetryEnabled())
|
|
7
|
+
return;
|
|
8
|
+
const client = getClient();
|
|
9
|
+
if (!client)
|
|
10
|
+
return;
|
|
11
|
+
try {
|
|
12
|
+
client.trackEvent({
|
|
13
|
+
name: event.name,
|
|
14
|
+
properties: event.props,
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
// Telemetry must never crash the host process.
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=emit.js.map
|
package/dist/emit.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emit.js","sourceRoot":"","sources":["../src/emit.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,2DAA2D;AAE3D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAGlD,MAAM,UAAU,KAAK,CAAC,KAAqB;IACzC,IAAI,CAAC,kBAAkB,EAAE;QAAE,OAAO;IAClC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,IAAI,CAAC;QACH,MAAM,CAAC,UAAU,CAAC;YAChB,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,UAAU,EAAE,KAAK,CAAC,KAAgC;SACnD,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { initTelemetry, isInitialized, resetClientForTests } from "./client.js";
|
|
2
|
+
export type { InitOptions } from "./types/client.js";
|
|
3
|
+
export { track } from "./emit.js";
|
|
4
|
+
export { isTelemetryEnabled, setTelemetryEnabled } from "./opt-out.js";
|
|
5
|
+
export { DISCLOSURE_COPY, getDisclosureCopy, hasShownDisclosure, markDisclosureShown, } from "./disclosure.js";
|
|
6
|
+
export { getInstallId } from "./install-id.js";
|
|
7
|
+
export { DEV_MANIFEST, readReleaseManifest } from "./release-manifest.js";
|
|
8
|
+
export type { ReleaseManifest } from "./types/release-manifest.js";
|
|
9
|
+
export type { EventName, McpToolCompleted, McpToolInvoked, Outcome, ServiceName, SkillCompleted, SkillInvoked, Surface, SystemDisclosureShown, SystemOptOutChanged, SystemStartup, TelemetryEvent, ToolSurface, Trigger, } from "./types/events.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAChF,YAAY,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC1E,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,YAAY,EACV,SAAS,EACT,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,WAAW,EACX,cAAc,EACd,YAAY,EACZ,OAAO,EACP,qBAAqB,EACrB,mBAAmB,EACnB,aAAa,EACb,cAAc,EACd,WAAW,EACX,OAAO,GACR,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
// Public surface of @muggleai/telemetry.
|
|
2
|
+
export { initTelemetry, isInitialized, resetClientForTests } from "./client.js";
|
|
3
|
+
export { track } from "./emit.js";
|
|
4
|
+
export { isTelemetryEnabled, setTelemetryEnabled } from "./opt-out.js";
|
|
5
|
+
export { DISCLOSURE_COPY, getDisclosureCopy, hasShownDisclosure, markDisclosureShown, } from "./disclosure.js";
|
|
6
|
+
export { getInstallId } from "./install-id.js";
|
|
7
|
+
export { DEV_MANIFEST, readReleaseManifest } from "./release-manifest.js";
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,yCAAyC;AAEzC,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGhF,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEvE,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-id.d.ts","sourceRoot":"","sources":["../src/install-id.ts"],"names":[],"mappings":"AAiCA,wBAAgB,YAAY,IAAI,MAAM,CAuBrC;AAED,wBAAgB,2BAA2B,IAAI,IAAI,CAElD"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Stable opaque per-machine install identifier. Persisted at ~/.muggle-ai/install-id.json.
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { INSTALL_ID_FILENAME } from "./constants/paths.js";
|
|
6
|
+
import { getDataDir } from "./data-dir.js";
|
|
7
|
+
let cachedInstallId;
|
|
8
|
+
function installIdFilePath() {
|
|
9
|
+
return join(getDataDir(), INSTALL_ID_FILENAME);
|
|
10
|
+
}
|
|
11
|
+
function generateAndPersist(filePath) {
|
|
12
|
+
const installId = randomUUID();
|
|
13
|
+
const contents = { installId };
|
|
14
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
15
|
+
writeFileSync(filePath, JSON.stringify(contents, null, 2) + "\n", "utf8");
|
|
16
|
+
return installId;
|
|
17
|
+
}
|
|
18
|
+
function isValid(value) {
|
|
19
|
+
return (typeof value === "object" &&
|
|
20
|
+
value !== null &&
|
|
21
|
+
typeof value.installId === "string" &&
|
|
22
|
+
value.installId.length > 0);
|
|
23
|
+
}
|
|
24
|
+
export function getInstallId() {
|
|
25
|
+
if (cachedInstallId !== undefined)
|
|
26
|
+
return cachedInstallId;
|
|
27
|
+
const filePath = installIdFilePath();
|
|
28
|
+
if (!existsSync(filePath)) {
|
|
29
|
+
cachedInstallId = generateAndPersist(filePath);
|
|
30
|
+
return cachedInstallId;
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const raw = readFileSync(filePath, "utf8");
|
|
34
|
+
const parsed = JSON.parse(raw);
|
|
35
|
+
if (isValid(parsed)) {
|
|
36
|
+
cachedInstallId = parsed.installId;
|
|
37
|
+
return cachedInstallId;
|
|
38
|
+
}
|
|
39
|
+
cachedInstallId = generateAndPersist(filePath);
|
|
40
|
+
return cachedInstallId;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
cachedInstallId = generateAndPersist(filePath);
|
|
44
|
+
return cachedInstallId;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function resetInstallIdCacheForTests() {
|
|
48
|
+
cachedInstallId = undefined;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=install-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-id.js","sourceRoot":"","sources":["../src/install-id.ts"],"names":[],"mappings":"AAAA,2FAA2F;AAE3F,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,IAAI,eAAmC,CAAC;AAExC,SAAS,iBAAiB;IACxB,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,mBAAmB,CAAC,CAAC;AACjD,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAC/B,MAAM,QAAQ,GAAkB,EAAE,SAAS,EAAE,CAAC;IAC9C,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1E,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAQ,KAAiC,CAAC,SAAS,KAAK,QAAQ;QAC/D,KAA+B,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CACtD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,IAAI,eAAe,KAAK,SAAS;QAAE,OAAO,eAAe,CAAC;IAE1D,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IAErC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/C,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACpB,eAAe,GAAG,MAAM,CAAC,SAAS,CAAC;YACnC,OAAO,eAAe,CAAC;QACzB,CAAC;QACD,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/C,OAAO,eAAe,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAC/C,OAAO,eAAe,CAAC;IACzB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,2BAA2B;IACzC,eAAe,GAAG,SAAS,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opt-out.d.ts","sourceRoot":"","sources":["../src/opt-out.ts"],"names":[],"mappings":"AAMA,wBAAgB,kBAAkB,IAAI,OAAO,CAK5C;AAED,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAE1D"}
|
package/dist/opt-out.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Resolves whether telemetry is enabled.
|
|
2
|
+
// Order: env override > preferences.json > default true.
|
|
3
|
+
import { ENV_TELEMETRY_DISABLED } from "./constants/env.js";
|
|
4
|
+
import { readPreferences, updatePreference } from "./preferences.js";
|
|
5
|
+
export function isTelemetryEnabled() {
|
|
6
|
+
if (process.env[ENV_TELEMETRY_DISABLED] === "1")
|
|
7
|
+
return false;
|
|
8
|
+
const prefs = readPreferences();
|
|
9
|
+
if (prefs.telemetryEnabled === false)
|
|
10
|
+
return false;
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
export function setTelemetryEnabled(enabled) {
|
|
14
|
+
updatePreference("telemetryEnabled", enabled);
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=opt-out.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opt-out.js","sourceRoot":"","sources":["../src/opt-out.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,yDAAyD;AAEzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAErE,MAAM,UAAU,kBAAkB;IAChC,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,GAAG;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,IAAI,KAAK,CAAC,gBAAgB,KAAK,KAAK;QAAE,OAAO,KAAK,CAAC;IACnD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,gBAAgB,CAAC,kBAAkB,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Preferences } from "./types/preferences.js";
|
|
2
|
+
export type { Preferences } from "./types/preferences.js";
|
|
3
|
+
export declare function readPreferences(): Preferences;
|
|
4
|
+
export declare function writePreferences(prefs: Preferences): void;
|
|
5
|
+
export declare function updatePreference<K extends keyof Preferences>(key: K, value: Preferences[K]): void;
|
|
6
|
+
export declare function preferencesFileExists(): boolean;
|
|
7
|
+
//# sourceMappingURL=preferences.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../src/preferences.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAE1D,YAAY,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAM1D,wBAAgB,eAAe,IAAI,WAAW,CAa7C;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAIzD;AAED,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,WAAW,EAC1D,GAAG,EAAE,CAAC,EACN,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,GACpB,IAAI,CAIN;AAED,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// Reads and writes ~/.muggle-ai/preferences.json. Used by both opt-out and
|
|
2
|
+
// disclosure to persist user state.
|
|
3
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { PREFS_FILENAME } from "./constants/paths.js";
|
|
6
|
+
import { getDataDir } from "./data-dir.js";
|
|
7
|
+
function prefsFilePath() {
|
|
8
|
+
return join(getDataDir(), PREFS_FILENAME);
|
|
9
|
+
}
|
|
10
|
+
export function readPreferences() {
|
|
11
|
+
const filePath = prefsFilePath();
|
|
12
|
+
if (!existsSync(filePath))
|
|
13
|
+
return {};
|
|
14
|
+
try {
|
|
15
|
+
const raw = readFileSync(filePath, "utf8");
|
|
16
|
+
const parsed = JSON.parse(raw);
|
|
17
|
+
if (typeof parsed === "object" && parsed !== null) {
|
|
18
|
+
return parsed;
|
|
19
|
+
}
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
export function writePreferences(prefs) {
|
|
27
|
+
const filePath = prefsFilePath();
|
|
28
|
+
mkdirSync(dirname(filePath), { recursive: true });
|
|
29
|
+
writeFileSync(filePath, JSON.stringify(prefs, null, 2) + "\n", "utf8");
|
|
30
|
+
}
|
|
31
|
+
export function updatePreference(key, value) {
|
|
32
|
+
const prefs = readPreferences();
|
|
33
|
+
prefs[key] = value;
|
|
34
|
+
writePreferences(prefs);
|
|
35
|
+
}
|
|
36
|
+
export function preferencesFileExists() {
|
|
37
|
+
return existsSync(prefsFilePath());
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=preferences.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.js","sourceRoot":"","sources":["../src/preferences.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,oCAAoC;AAEpC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAK3C,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,UAAU,EAAE,EAAE,cAAc,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IACjC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;YAClD,OAAO,MAAqB,CAAC;QAC/B,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAkB;IACjD,MAAM,QAAQ,GAAG,aAAa,EAAE,CAAC;IACjC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,gBAAgB,CAC9B,GAAM,EACN,KAAqB;IAErB,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;IAChC,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,gBAAgB,CAAC,KAAK,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ReleaseManifest } from "./types/release-manifest.js";
|
|
2
|
+
export { DEV_MANIFEST } from "./constants/manifest.js";
|
|
3
|
+
export type { ReleaseManifest } from "./types/release-manifest.js";
|
|
4
|
+
export declare function readReleaseManifest(): ReleaseManifest;
|
|
5
|
+
export declare function setManifestPathForTests(path: string | undefined): void;
|
|
6
|
+
export declare function resetReleaseManifestCacheForTests(): void;
|
|
7
|
+
//# sourceMappingURL=release-manifest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-manifest.d.ts","sourceRoot":"","sources":["../src/release-manifest.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAyBnE,wBAAgB,mBAAmB,IAAI,eAAe,CAkBrD;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAEtE;AAED,wBAAgB,iCAAiC,IAAI,IAAI,CAExD"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Build-time-generated manifest co-located with the built JS as a sibling
|
|
2
|
+
// `release-manifest.json`. Falls back to DEV_MANIFEST when absent.
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { dirname, join } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { DEV_MANIFEST } from "./constants/manifest.js";
|
|
7
|
+
import { RELEASE_MANIFEST_FILENAME } from "./constants/paths.js";
|
|
8
|
+
export { DEV_MANIFEST } from "./constants/manifest.js";
|
|
9
|
+
const MANIFEST_PATH = (() => {
|
|
10
|
+
try {
|
|
11
|
+
return join(dirname(fileURLToPath(import.meta.url)), RELEASE_MANIFEST_FILENAME);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return RELEASE_MANIFEST_FILENAME;
|
|
15
|
+
}
|
|
16
|
+
})();
|
|
17
|
+
let cachedManifest;
|
|
18
|
+
let manifestPathOverride;
|
|
19
|
+
function isValid(value) {
|
|
20
|
+
if (typeof value !== "object" || value === null)
|
|
21
|
+
return false;
|
|
22
|
+
const m = value;
|
|
23
|
+
return (typeof m.release === "string" &&
|
|
24
|
+
typeof m.buildId === "string" &&
|
|
25
|
+
typeof m.commitSha === "string" &&
|
|
26
|
+
typeof m.buildTime === "string" &&
|
|
27
|
+
typeof m.serviceName === "string");
|
|
28
|
+
}
|
|
29
|
+
export function readReleaseManifest() {
|
|
30
|
+
if (cachedManifest !== undefined)
|
|
31
|
+
return cachedManifest;
|
|
32
|
+
const path = manifestPathOverride ?? MANIFEST_PATH;
|
|
33
|
+
try {
|
|
34
|
+
const raw = readFileSync(path, "utf8");
|
|
35
|
+
const parsed = JSON.parse(raw);
|
|
36
|
+
cachedManifest = isValid(parsed) ? parsed : DEV_MANIFEST;
|
|
37
|
+
return cachedManifest;
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
const code = err.code;
|
|
41
|
+
if (code !== "ENOENT") {
|
|
42
|
+
console.warn("release-manifest: unexpected read error, using DEV fallback", {
|
|
43
|
+
error: err.message,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
cachedManifest = DEV_MANIFEST;
|
|
47
|
+
return cachedManifest;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export function setManifestPathForTests(path) {
|
|
51
|
+
manifestPathOverride = path;
|
|
52
|
+
}
|
|
53
|
+
export function resetReleaseManifestCacheForTests() {
|
|
54
|
+
cachedManifest = undefined;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=release-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-manifest.js","sourceRoot":"","sources":["../src/release-manifest.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,mEAAmE;AAEnE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAGjE,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAGvD,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE;IAC1B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,yBAAyB,CAAC,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,yBAAyB,CAAC;IACnC,CAAC;AACH,CAAC,CAAC,EAAE,CAAC;AAEL,IAAI,cAA2C,CAAC;AAChD,IAAI,oBAAwC,CAAC;AAE7C,SAAS,OAAO,CAAC,KAAc;IAC7B,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,MAAM,CAAC,GAAG,KAAgC,CAAC;IAC3C,OAAO,CACL,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;QAC7B,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ;QAC7B,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;QAC/B,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ;QAC/B,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,CAClC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,cAAc,CAAC;IACxD,MAAM,IAAI,GAAG,oBAAoB,IAAI,aAAa,CAAC;IACnD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACxC,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC;QACzD,OAAO,cAAc,CAAC;IACxB,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,IAAI,GAAI,GAA6B,CAAC,IAAI,CAAC;QACjD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtB,OAAO,CAAC,IAAI,CAAC,6DAA6D,EAAE;gBAC1E,KAAK,EAAG,GAAa,CAAC,OAAO;aAC9B,CAAC,CAAC;QACL,CAAC;QACD,cAAc,GAAG,YAAY,CAAC;QAC9B,OAAO,cAAc,CAAC;IACxB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAwB;IAC9D,oBAAoB,GAAG,IAAI,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,iCAAiC;IAC/C,cAAc,GAAG,SAAS,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { TelemetryClient } from "applicationinsights";
|
|
2
|
+
import type { ServiceName, Surface } from "./events.js";
|
|
3
|
+
export interface InitOptions {
|
|
4
|
+
serviceName: ServiceName;
|
|
5
|
+
surface: Surface;
|
|
6
|
+
/** Override connection string. Falls back to env vars when omitted. */
|
|
7
|
+
connectionString?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ClientState {
|
|
10
|
+
client: TelemetryClient | null;
|
|
11
|
+
serviceName: ServiceName;
|
|
12
|
+
surface: Surface;
|
|
13
|
+
initialized: boolean;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/types/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,eAAe,GAAG,IAAI,CAAC;IAC/B,WAAW,EAAE,WAAW,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/types/client.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
export type Trigger = "user-slash" | "claude-proactive" | "nested-skill";
|
|
2
|
+
export type Outcome = "success" | "error" | "cancelled";
|
|
3
|
+
export type ToolSurface = "local" | "remote";
|
|
4
|
+
export type Surface = "mcp-local" | "mcp-remote" | "skill" | "electron";
|
|
5
|
+
export type ServiceName = "muggle-mcp" | "muggle-electron" | "muggle-skill";
|
|
6
|
+
export type SkillInvoked = {
|
|
7
|
+
name: "skill.invoked";
|
|
8
|
+
props: {
|
|
9
|
+
skillName: string;
|
|
10
|
+
trigger: Trigger;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
export type SkillCompleted = {
|
|
14
|
+
name: "skill.completed";
|
|
15
|
+
props: {
|
|
16
|
+
skillName: string;
|
|
17
|
+
durationMs: number;
|
|
18
|
+
outcome: Outcome;
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export type McpToolInvoked = {
|
|
22
|
+
name: "mcp.tool.invoked";
|
|
23
|
+
props: {
|
|
24
|
+
toolName: string;
|
|
25
|
+
toolSurface: ToolSurface;
|
|
26
|
+
correlationId: string;
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export type McpToolCompleted = {
|
|
30
|
+
name: "mcp.tool.completed";
|
|
31
|
+
props: {
|
|
32
|
+
toolName: string;
|
|
33
|
+
toolSurface: ToolSurface;
|
|
34
|
+
correlationId: string;
|
|
35
|
+
durationMs: number;
|
|
36
|
+
outcome: Outcome;
|
|
37
|
+
errorCode?: string;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
export type SystemStartup = {
|
|
41
|
+
name: "system.startup";
|
|
42
|
+
props: {
|
|
43
|
+
serviceName: ServiceName;
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export type SystemOptOutChanged = {
|
|
47
|
+
name: "system.opt_out_changed";
|
|
48
|
+
props: {
|
|
49
|
+
from: boolean;
|
|
50
|
+
to: boolean;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export type SystemDisclosureShown = {
|
|
54
|
+
name: "system.disclosure_shown";
|
|
55
|
+
props: Record<string, never>;
|
|
56
|
+
};
|
|
57
|
+
export type TelemetryEvent = SkillInvoked | SkillCompleted | McpToolInvoked | McpToolCompleted | SystemStartup | SystemOptOutChanged | SystemDisclosureShown;
|
|
58
|
+
export type EventName = TelemetryEvent["name"];
|
|
59
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,OAAO,GAAG,YAAY,GAAG,kBAAkB,GAAG,cAAc,CAAC;AAEzE,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,WAAW,CAAC;AAExD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,QAAQ,CAAC;AAE7C,MAAM,MAAM,OAAO,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,GAAG,UAAU,CAAC;AAExE,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,iBAAiB,GAAG,cAAc,CAAC;AAE5E,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,eAAe,CAAC;IACtB,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,iBAAiB,CAAC;IACxB,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;KAClB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,kBAAkB,CAAC;IACzB,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,WAAW,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;KACvB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,oBAAoB,CAAC;IAC3B,KAAK,EAAE;QACL,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,WAAW,CAAC;QACzB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,CAAC;QACjB,SAAS,CAAC,EAAE,MAAM,CAAC;KACpB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE,gBAAgB,CAAC;IACvB,KAAK,EAAE;QACL,WAAW,EAAE,WAAW,CAAC;KAC1B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,wBAAwB,CAAC;IAC/B,KAAK,EAAE;QACL,IAAI,EAAE,OAAO,CAAC;QACd,EAAE,EAAE,OAAO,CAAC;KACb,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,IAAI,EAAE,yBAAyB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,cAAc,GACtB,YAAY,GACZ,cAAc,GACd,cAAc,GACd,gBAAgB,GAChB,aAAa,GACb,mBAAmB,GACnB,qBAAqB,CAAC;AAE1B,MAAM,MAAM,SAAS,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/types/events.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,oEAAoE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-id.d.ts","sourceRoot":"","sources":["../../src/types/install-id.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-id.js","sourceRoot":"","sources":["../../src/types/install-id.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.d.ts","sourceRoot":"","sources":["../../src/types/preferences.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preferences.js","sourceRoot":"","sources":["../../src/types/preferences.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-manifest.d.ts","sourceRoot":"","sources":["../../src/types/release-manifest.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;CACrB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"release-manifest.js","sourceRoot":"","sources":["../../src/types/release-manifest.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-id.d.ts","sourceRoot":"","sources":["../../src/types/user-id.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-id.js","sourceRoot":"","sources":["../../src/types/user-id.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-id.d.ts","sourceRoot":"","sources":["../src/user-id.ts"],"names":[],"mappings":"AAUA,wBAAgB,UAAU,IAAI,MAAM,GAAG,SAAS,CAa/C"}
|
package/dist/user-id.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Best-effort read of the opaque userId from the auth session file. Returns
|
|
2
|
+
// undefined when the user is not signed in. Never throws.
|
|
3
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { OAUTH_SESSION_FILENAME } from "./constants/paths.js";
|
|
6
|
+
import { getDataDir } from "./data-dir.js";
|
|
7
|
+
export function readUserId() {
|
|
8
|
+
const filePath = join(getDataDir(), OAUTH_SESSION_FILENAME);
|
|
9
|
+
if (!existsSync(filePath))
|
|
10
|
+
return undefined;
|
|
11
|
+
try {
|
|
12
|
+
const raw = readFileSync(filePath, "utf8");
|
|
13
|
+
const parsed = JSON.parse(raw);
|
|
14
|
+
if (typeof parsed.userId === "string" && parsed.userId.length > 0) {
|
|
15
|
+
return parsed.userId;
|
|
16
|
+
}
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=user-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-id.js","sourceRoot":"","sources":["../src/user-id.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,0DAA0D;AAE1D,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,MAAM,UAAU,UAAU;IACxB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,EAAE,sBAAsB,CAAC,CAAC;IAC5D,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,OAAO,SAAS,CAAC;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAoB,CAAC;QAClD,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClE,OAAO,MAAM,CAAC,MAAM,CAAC;QACvB,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@muggleai/telemetry",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Shared client-side telemetry for Muggle Test (MCP, skills, Electron).",
|
|
5
|
+
"private": false,
|
|
6
|
+
"type": "module",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"PRIVACY.md"
|
|
19
|
+
],
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public",
|
|
22
|
+
"registry": "https://registry.npmjs.org"
|
|
23
|
+
},
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "git+ssh://git@github.com/multiplex-ai/muggle-ai-telemetry.git"
|
|
27
|
+
},
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsc -p tsconfig.build.json",
|
|
30
|
+
"test": "vitest run",
|
|
31
|
+
"test:watch": "vitest",
|
|
32
|
+
"typecheck": "tsc --noEmit",
|
|
33
|
+
"clean": "rimraf dist",
|
|
34
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
35
|
+
},
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"applicationinsights": "^3.14.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.11.0",
|
|
41
|
+
"nock": "^14.0.0",
|
|
42
|
+
"rimraf": "^6.0.1",
|
|
43
|
+
"typescript": "^5.4.0",
|
|
44
|
+
"vitest": "^1.6.0"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=20"
|
|
48
|
+
}
|
|
49
|
+
}
|