@alisaitteke/photoshop-mcp 1.3.0 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -59
- package/dist/analytics/client-ip.d.ts +5 -0
- package/dist/analytics/client-ip.d.ts.map +1 -0
- package/dist/analytics/client-ip.js +39 -0
- package/dist/analytics/client-ip.js.map +1 -0
- package/dist/analytics/events.d.ts +2 -0
- package/dist/analytics/events.d.ts.map +1 -1
- package/dist/analytics/events.js +55 -8
- package/dist/analytics/events.js.map +1 -1
- package/dist/analytics/index.d.ts +9 -3
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +15 -1
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/locale.d.ts +6 -0
- package/dist/analytics/locale.d.ts.map +1 -0
- package/dist/analytics/locale.js +19 -0
- package/dist/analytics/locale.js.map +1 -0
- package/dist/analytics/mcp-session.d.ts +12 -0
- package/dist/analytics/mcp-session.d.ts.map +1 -0
- package/dist/analytics/mcp-session.js +118 -0
- package/dist/analytics/mcp-session.js.map +1 -0
- package/dist/analytics/noop.d.ts +1 -0
- package/dist/analytics/noop.d.ts.map +1 -1
- package/dist/analytics/noop.js +3 -0
- package/dist/analytics/noop.js.map +1 -1
- package/dist/analytics/pageview.d.ts +3 -0
- package/dist/analytics/pageview.d.ts.map +1 -0
- package/dist/analytics/pageview.js +31 -0
- package/dist/analytics/pageview.js.map +1 -0
- package/dist/analytics/posthog-node.d.ts +3 -0
- package/dist/analytics/posthog-node.d.ts.map +1 -1
- package/dist/analytics/posthog-node.js +23 -1
- package/dist/analytics/posthog-node.js.map +1 -1
- package/dist/analytics/runtime-env.d.ts +5 -0
- package/dist/analytics/runtime-env.d.ts.map +1 -0
- package/dist/analytics/runtime-env.js +63 -0
- package/dist/analytics/runtime-env.js.map +1 -0
- package/dist/analytics/types.d.ts +2 -0
- package/dist/analytics/types.d.ts.map +1 -1
- package/dist/core/server.d.ts +2 -0
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +42 -6
- package/dist/core/server.js.map +1 -1
- package/dist/core/session.d.ts +1 -0
- package/dist/core/session.d.ts.map +1 -1
- package/dist/core/session.js +12 -1
- package/dist/core/session.js.map +1 -1
- package/dist/errors/envelope.d.ts +1 -1
- package/dist/errors/envelope.d.ts.map +1 -1
- package/dist/errors/envelope.js +37 -4
- package/dist/errors/envelope.js.map +1 -1
- package/dist/index.js +41 -5
- package/dist/index.js.map +1 -1
- package/dist/ui/cli.js +7 -1
- package/dist/ui/cli.js.map +1 -1
- package/dist/ui/server.d.ts.map +1 -1
- package/dist/ui/server.js +2 -1
- package/dist/ui/server.js.map +1 -1
- package/dist/ui/store/db.js +2 -2
- package/dist/ui/store/db.js.map +1 -1
- package/package.json +1 -1
- package/web/dist/assets/index-n0ymP-Cw.js +249 -0
- package/web/dist/index.html +1 -1
- package/web/dist/assets/index-BuJJLllx.js +0 -249
package/README.md
CHANGED
|
@@ -644,65 +644,9 @@ MIT
|
|
|
644
644
|
|
|
645
645
|
## Anonymous Usage Analytics
|
|
646
646
|
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
### What we collect
|
|
652
|
-
|
|
653
|
-
- App version, operating system, and Node.js version
|
|
654
|
-
- Startup signals (MCP server or UI server started, Photoshop detected or not)
|
|
655
|
-
- Setup funnel events (provider chosen, auth method, validation success/failure
|
|
656
|
-
codes — not credentials)
|
|
657
|
-
- Generic UI events (app loaded, onboarding completed)
|
|
658
|
-
|
|
659
|
-
Events use a random anonymous identifier stored locally at
|
|
660
|
-
`~/.photoshop-mcp/` (SQLite `kv` table and/or `analytics-store.json`). We do
|
|
661
|
-
**not** call `identify()` — no person profiles are created for anonymous usage
|
|
662
|
-
(`person_profiles: identified_only`).
|
|
663
|
-
|
|
664
|
-
### What we do **not** collect (unless you opt into beta team sharing)
|
|
665
|
-
|
|
666
|
-
- API keys or OAuth tokens
|
|
667
|
-
- Chat messages, prompts, or model responses **by default**
|
|
668
|
-
- Photoshop document or layer names, file paths, or image content
|
|
669
|
-
- CLI account labels, email addresses, or other account identifiers
|
|
670
|
-
- Tool call arguments or results
|
|
671
|
-
|
|
672
|
-
### Beta team content sharing (opt-in)
|
|
673
|
-
|
|
674
|
-
On first launch of the standalone UI, you are asked whether you want to **join the
|
|
675
|
-
beta team**. This is separate from anonymous usage analytics above.
|
|
676
|
-
|
|
677
|
-
If you accept:
|
|
678
|
-
|
|
679
|
-
- Your **prompts**, **assistant responses**, **reasoning text**, and **tool names**
|
|
680
|
-
(not arguments or results) may be sent to PostHog after each chat turn
|
|
681
|
-
- Content is truncated for very long messages
|
|
682
|
-
- Requires anonymous analytics to remain enabled
|
|
683
|
-
|
|
684
|
-
If you decline, no chat content is logged. You can change this later in
|
|
685
|
-
**Settings → General → Privacy → Beta team content sharing**.
|
|
686
|
-
|
|
687
|
-
Existing installs that have not answered yet are prompted once on the next launch.
|
|
688
|
-
|
|
689
|
-
### Processor and hosting
|
|
690
|
-
|
|
691
|
-
Analytics are processed by [PostHog](https://posthog.com/). Events are sent to a
|
|
692
|
-
managed reverse proxy at `https://a.alisait.com`; the PostHog project UI is
|
|
693
|
-
hosted in the EU (`https://eu.posthog.com`). See the
|
|
694
|
-
[PostHog privacy policy](https://posthog.com/privacy) for how PostHog handles
|
|
695
|
-
data on their side.
|
|
696
|
-
|
|
697
|
-
### How to opt out
|
|
698
|
-
|
|
699
|
-
1. **Standalone UI:** Settings → General → Privacy → set **Anonymous usage
|
|
700
|
-
analytics** to **Off** (also disables beta content sharing).
|
|
701
|
-
2. **Beta content only:** Settings → General → Privacy → set **Beta team content
|
|
702
|
-
sharing** to **Off** (anonymous analytics can stay on).
|
|
703
|
-
3. **Environment variable:** set `POSTHOG_DISABLED=1` before starting
|
|
704
|
-
`photoshop-mcp` or `photoshop-mcp-ui` (disables all analytics for that
|
|
705
|
-
process and persists opt-out in local storage).
|
|
647
|
+
Anonymous, aggregated usage events are collected by default to improve the
|
|
648
|
+
product. You can opt out at any time. Full details:
|
|
649
|
+
[`docs/anonymous-usage-analytics.md`](docs/anonymous-usage-analytics.md).
|
|
706
650
|
|
|
707
651
|
## Acknowledgments
|
|
708
652
|
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Best-effort client IP from an incoming HTTP request (may be loopback for local UI). */
|
|
2
|
+
export declare function resolveClientIp(headers: Headers): string | undefined;
|
|
3
|
+
/** GeoIP enrichment only makes sense for a routable public client address. */
|
|
4
|
+
export declare function isPublicClientIp(ip: string | undefined): boolean;
|
|
5
|
+
//# sourceMappingURL=client-ip.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-ip.d.ts","sourceRoot":"","sources":["../../src/analytics/client-ip.ts"],"names":[],"mappings":"AAYA,0FAA0F;AAC1F,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAapE;AAED,8EAA8E;AAC9E,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAGhE"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
function isLoopbackOrPrivateIp(ip) {
|
|
2
|
+
const normalized = ip.trim().toLowerCase();
|
|
3
|
+
if (!normalized)
|
|
4
|
+
return true;
|
|
5
|
+
if (normalized === '::1' || normalized === 'localhost')
|
|
6
|
+
return true;
|
|
7
|
+
if (normalized.startsWith('127.'))
|
|
8
|
+
return true;
|
|
9
|
+
if (normalized.startsWith('10.'))
|
|
10
|
+
return true;
|
|
11
|
+
if (normalized.startsWith('192.168.'))
|
|
12
|
+
return true;
|
|
13
|
+
if (/^172\.(1[6-9]|2\d|3[01])\./.test(normalized))
|
|
14
|
+
return true;
|
|
15
|
+
if (normalized.startsWith('fc') || normalized.startsWith('fd'))
|
|
16
|
+
return true;
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
/** Best-effort client IP from an incoming HTTP request (may be loopback for local UI). */
|
|
20
|
+
export function resolveClientIp(headers) {
|
|
21
|
+
const candidates = [
|
|
22
|
+
headers.get('cf-connecting-ip'),
|
|
23
|
+
headers.get('x-real-ip'),
|
|
24
|
+
...(headers.get('x-forwarded-for')?.split(',') ?? []),
|
|
25
|
+
];
|
|
26
|
+
for (const raw of candidates) {
|
|
27
|
+
const ip = raw?.trim();
|
|
28
|
+
if (ip)
|
|
29
|
+
return ip;
|
|
30
|
+
}
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
/** GeoIP enrichment only makes sense for a routable public client address. */
|
|
34
|
+
export function isPublicClientIp(ip) {
|
|
35
|
+
if (!ip)
|
|
36
|
+
return false;
|
|
37
|
+
return !isLoopbackOrPrivateIp(ip);
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=client-ip.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-ip.js","sourceRoot":"","sources":["../../src/analytics/client-ip.ts"],"names":[],"mappings":"AAAA,SAAS,qBAAqB,CAAC,EAAU;IACvC,MAAM,UAAU,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC3C,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAC7B,IAAI,UAAU,KAAK,KAAK,IAAI,UAAU,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IACpE,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/C,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,IAAI,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,4BAA4B,CAAC,IAAI,CAAC,UAAU,CAAC;QAAE,OAAO,IAAI,CAAC;IAC/D,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5E,OAAO,KAAK,CAAC;AACf,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,MAAM,UAAU,GAAG;QACjB,OAAO,CAAC,GAAG,CAAC,kBAAkB,CAAC;QAC/B,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC;QACxB,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;KACtD,CAAC;IAEF,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,EAAE,GAAG,GAAG,EAAE,IAAI,EAAE,CAAC;QACvB,IAAI,EAAE;YAAE,OAAO,EAAE,CAAC;IACpB,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,gBAAgB,CAAC,EAAsB;IACrD,IAAI,CAAC,EAAE;QAAE,OAAO,KAAK,CAAC;IACtB,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
export declare function sanitizeAnalyticsProperties(properties: Record<string, unknown> | undefined): Record<string, string | number | boolean>;
|
|
2
2
|
export declare function buildRuntimeProperties(properties: Record<string, unknown> | undefined): Record<string, string | number | boolean>;
|
|
3
|
+
/** Person-profile fields merged on PostHog identify() — includes install-level hardware signals. */
|
|
4
|
+
export declare function buildPersonIdentifyProperties(properties?: Record<string, unknown>): Record<string, string | number | boolean>;
|
|
3
5
|
//# sourceMappingURL=events.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/analytics/events.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/analytics/events.ts"],"names":[],"mappings":"AA6FA,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC9C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAa3C;AAED,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC9C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAO3C;AAED,oGAAoG;AACpG,wBAAgB,6BAA6B,CAC3C,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAK3C"}
|
package/dist/analytics/events.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getServerAnalyticsContext } from './context.js';
|
|
2
2
|
import { getLaunchMethod } from './launch-method.js';
|
|
3
|
+
import { buildAnonymousRuntimeEnv, getTotalRamGb } from './runtime-env.js';
|
|
3
4
|
const BLOCKED_PROPERTY_KEYS = new Set([
|
|
4
5
|
'api_key',
|
|
5
6
|
'apikey',
|
|
@@ -29,6 +30,7 @@ const ALLOWED_PROPERTY_KEYS = new Set([
|
|
|
29
30
|
'ok',
|
|
30
31
|
'error_code',
|
|
31
32
|
'photoshop_detected',
|
|
33
|
+
'photoshop_connected',
|
|
32
34
|
'action_plan_enabled',
|
|
33
35
|
'event_source',
|
|
34
36
|
'port',
|
|
@@ -43,33 +45,78 @@ const ALLOWED_PROPERTY_KEYS = new Set([
|
|
|
43
45
|
'beta_telemetry_opt_in',
|
|
44
46
|
'theme',
|
|
45
47
|
'launch_method',
|
|
48
|
+
'browser_language',
|
|
49
|
+
'browser_timezone',
|
|
50
|
+
'browser_locale_region',
|
|
51
|
+
'system_locale',
|
|
52
|
+
'system_locale_region',
|
|
53
|
+
'system_locale_language',
|
|
54
|
+
'system_timezone',
|
|
55
|
+
'os_type',
|
|
56
|
+
'os_release',
|
|
57
|
+
'cpu_count',
|
|
58
|
+
'memory_gb',
|
|
59
|
+
'total_ram_gb',
|
|
60
|
+
'photoshop_version',
|
|
61
|
+
'node_major',
|
|
62
|
+
'is_electron',
|
|
63
|
+
'photoshop_path_configured',
|
|
64
|
+
'custom_data_dir_configured',
|
|
65
|
+
'tool_name',
|
|
66
|
+
'duration_ms',
|
|
67
|
+
'usage_surface',
|
|
68
|
+
'shutdown_reason',
|
|
69
|
+
'tools_registered_count',
|
|
70
|
+
'prompt_name',
|
|
71
|
+
'tools_called_count',
|
|
72
|
+
'tools_error_count',
|
|
73
|
+
'unique_tools_count',
|
|
74
|
+
'tool_usage_summary',
|
|
75
|
+
'error_codes_summary',
|
|
76
|
+
'batch_flush_reason',
|
|
46
77
|
]);
|
|
78
|
+
const POSTHOG_RESERVED_PROPERTY_KEYS = new Set([
|
|
79
|
+
'$current_url',
|
|
80
|
+
'$pathname',
|
|
81
|
+
'$screen_name',
|
|
82
|
+
]);
|
|
83
|
+
function isAllowedAnalyticsPropertyKey(key) {
|
|
84
|
+
const normalized = key.toLowerCase();
|
|
85
|
+
if (BLOCKED_PROPERTY_KEYS.has(normalized))
|
|
86
|
+
return false;
|
|
87
|
+
if (ALLOWED_PROPERTY_KEYS.has(normalized))
|
|
88
|
+
return true;
|
|
89
|
+
return POSTHOG_RESERVED_PROPERTY_KEYS.has(key);
|
|
90
|
+
}
|
|
47
91
|
export function sanitizeAnalyticsProperties(properties) {
|
|
48
92
|
if (!properties)
|
|
49
93
|
return {};
|
|
50
94
|
const out = {};
|
|
51
95
|
for (const [key, value] of Object.entries(properties)) {
|
|
52
|
-
|
|
53
|
-
if (BLOCKED_PROPERTY_KEYS.has(normalized))
|
|
54
|
-
continue;
|
|
55
|
-
if (!ALLOWED_PROPERTY_KEYS.has(normalized))
|
|
96
|
+
if (!isAllowedAnalyticsPropertyKey(key))
|
|
56
97
|
continue;
|
|
57
98
|
if (value === null || value === undefined)
|
|
58
99
|
continue;
|
|
59
100
|
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
60
|
-
|
|
101
|
+
const outKey = POSTHOG_RESERVED_PROPERTY_KEYS.has(key) ? key : key.toLowerCase();
|
|
102
|
+
out[outKey] = value;
|
|
61
103
|
}
|
|
62
104
|
}
|
|
63
105
|
return out;
|
|
64
106
|
}
|
|
65
107
|
export function buildRuntimeProperties(properties) {
|
|
66
108
|
return {
|
|
67
|
-
|
|
68
|
-
arch: process.arch,
|
|
69
|
-
node_version: process.version,
|
|
109
|
+
...buildAnonymousRuntimeEnv(),
|
|
70
110
|
launch_method: getLaunchMethod(),
|
|
71
111
|
...getServerAnalyticsContext(),
|
|
72
112
|
...sanitizeAnalyticsProperties(properties),
|
|
73
113
|
};
|
|
74
114
|
}
|
|
115
|
+
/** Person-profile fields merged on PostHog identify() — includes install-level hardware signals. */
|
|
116
|
+
export function buildPersonIdentifyProperties(properties) {
|
|
117
|
+
return buildRuntimeProperties({
|
|
118
|
+
total_ram_gb: getTotalRamGb(),
|
|
119
|
+
...properties,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
75
122
|
//# sourceMappingURL=events.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/analytics/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/analytics/events.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import { captureBetaChatTurn } from './beta-telemetry.js';
|
|
2
2
|
import { getBetaTelemetryState, setBetaTelemetryChoice } from './identity.js';
|
|
3
|
+
import { endMcpAnalyticsSession, recordMcpToolCall, startMcpAnalyticsSession } from './mcp-session.js';
|
|
4
|
+
import { captureMcpPageleave, captureMcpPageview } from './pageview.js';
|
|
3
5
|
import { getAnalytics, resetAnalyticsProvider } from './provider.js';
|
|
4
|
-
import type { AnalyticsEvent, AnalyticsProvider, AnalyticsRuntimeConfig, BetaTelemetryState } from './types.js';
|
|
6
|
+
import type { AnalyticsEvent, AnalyticsProvider, AnalyticsRuntimeConfig, BetaTelemetryState, UsageSurface } from './types.js';
|
|
7
|
+
export type { McpShutdownReason } from './mcp-session.js';
|
|
8
|
+
/** Persist the install ID and register one anonymous PostHog person per process. */
|
|
9
|
+
export declare function ensureAnalyticsIdentity(): void;
|
|
5
10
|
export declare function capture(name: string, properties?: Record<string, unknown>): void;
|
|
11
|
+
export declare function identifyAnalyticsPerson(properties?: Record<string, unknown>): void;
|
|
6
12
|
export declare function shutdownAnalytics(): Promise<void>;
|
|
7
13
|
export declare function getAnalyticsRuntimeConfig(): AnalyticsRuntimeConfig;
|
|
8
|
-
export { captureBetaChatTurn, getAnalytics, getBetaTelemetryState, resetAnalyticsProvider, setBetaTelemetryChoice, };
|
|
9
|
-
export type { AnalyticsEvent, AnalyticsProvider, AnalyticsRuntimeConfig, BetaTelemetryState };
|
|
14
|
+
export { captureBetaChatTurn, captureMcpPageleave, captureMcpPageview, endMcpAnalyticsSession, getAnalytics, getBetaTelemetryState, recordMcpToolCall, resetAnalyticsProvider, setBetaTelemetryChoice, startMcpAnalyticsSession, };
|
|
15
|
+
export type { AnalyticsEvent, AnalyticsProvider, AnalyticsRuntimeConfig, BetaTelemetryState, UsageSurface, };
|
|
10
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAQ1D,OAAO,EACL,qBAAqB,EAGrB,sBAAsB,EACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAA2B,MAAM,eAAe,CAAC;AAC9F,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAQ1D,OAAO,EACL,qBAAqB,EAGrB,sBAAsB,EACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAA2B,MAAM,eAAe,CAAC;AAC9F,OAAO,KAAK,EACV,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,YAAY,EACb,MAAM,YAAY,CAAC;AACpB,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAE1D,oFAAoF;AACpF,wBAAgB,uBAAuB,IAAI,IAAI,CAI9C;AAED,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,IAAI,CAMN;AAED,wBAAgB,uBAAuB,CACrC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,IAAI,CAGN;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEvD;AAED,wBAAgB,yBAAyB,IAAI,sBAAsB,CAYlE;AAED,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,CAAC;AACF,YAAY,EACV,cAAc,EACd,iBAAiB,EACjB,sBAAsB,EACtB,kBAAkB,EAClB,YAAY,GACb,CAAC"}
|
package/dist/analytics/index.js
CHANGED
|
@@ -2,7 +2,16 @@ import { captureBetaChatTurn } from './beta-telemetry.js';
|
|
|
2
2
|
import { hasPostHogKey, resolvePostHogApiHost, resolvePostHogKey, resolvePostHogUiHost, } from './config.js';
|
|
3
3
|
import { buildRuntimeProperties } from './events.js';
|
|
4
4
|
import { getBetaTelemetryState, getOrCreateDistinctId, isAnalyticsEnabled, setBetaTelemetryChoice, } from './identity.js';
|
|
5
|
+
import { endMcpAnalyticsSession, recordMcpToolCall, startMcpAnalyticsSession, } from './mcp-session.js';
|
|
6
|
+
import { captureMcpPageleave, captureMcpPageview } from './pageview.js';
|
|
5
7
|
import { getAnalytics, resetAnalyticsProvider, shutdownAnalyticsClient } from './provider.js';
|
|
8
|
+
/** Persist the install ID and register one anonymous PostHog person per process. */
|
|
9
|
+
export function ensureAnalyticsIdentity() {
|
|
10
|
+
if (!isAnalyticsEnabled() || !hasPostHogKey())
|
|
11
|
+
return;
|
|
12
|
+
getOrCreateDistinctId();
|
|
13
|
+
getAnalytics();
|
|
14
|
+
}
|
|
6
15
|
export function capture(name, properties) {
|
|
7
16
|
if (!isAnalyticsEnabled() || !hasPostHogKey())
|
|
8
17
|
return;
|
|
@@ -11,6 +20,11 @@ export function capture(name, properties) {
|
|
|
11
20
|
properties: buildRuntimeProperties(properties),
|
|
12
21
|
});
|
|
13
22
|
}
|
|
23
|
+
export function identifyAnalyticsPerson(properties) {
|
|
24
|
+
if (!isAnalyticsEnabled() || !hasPostHogKey())
|
|
25
|
+
return;
|
|
26
|
+
getAnalytics().identify(properties);
|
|
27
|
+
}
|
|
14
28
|
export async function shutdownAnalytics() {
|
|
15
29
|
await shutdownAnalyticsClient();
|
|
16
30
|
}
|
|
@@ -27,5 +41,5 @@ export function getAnalyticsRuntimeConfig() {
|
|
|
27
41
|
betaTelemetryPromptAnswered: beta.betaTelemetryPromptAnswered,
|
|
28
42
|
};
|
|
29
43
|
}
|
|
30
|
-
export { captureBetaChatTurn, getAnalytics, getBetaTelemetryState, resetAnalyticsProvider, setBetaTelemetryChoice, };
|
|
44
|
+
export { captureBetaChatTurn, captureMcpPageleave, captureMcpPageview, endMcpAnalyticsSession, getAnalytics, getBetaTelemetryState, recordMcpToolCall, resetAnalyticsProvider, setBetaTelemetryChoice, startMcpAnalyticsSession, };
|
|
31
45
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/analytics/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC1D,OAAO,EACL,aAAa,EACb,qBAAqB,EACrB,iBAAiB,EACjB,oBAAoB,GACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,qBAAqB,EACrB,qBAAqB,EACrB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,sBAAsB,EACtB,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,YAAY,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAU9F,oFAAoF;AACpF,MAAM,UAAU,uBAAuB;IACrC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO;IACtD,qBAAqB,EAAE,CAAC;IACxB,YAAY,EAAE,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,OAAO,CACrB,IAAY,EACZ,UAAoC;IAEpC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO;IACtD,YAAY,EAAE,CAAC,OAAO,CAAC;QACrB,IAAI;QACJ,UAAU,EAAE,sBAAsB,CAAC,UAAU,CAAC;KAC/C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,UAAoC;IAEpC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO;IACtD,YAAY,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,MAAM,uBAAuB,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,yBAAyB;IACvC,MAAM,OAAO,GAAG,kBAAkB,EAAE,IAAI,aAAa,EAAE,CAAC;IACxD,MAAM,IAAI,GAAG,qBAAqB,EAAE,CAAC;IACrC,OAAO;QACL,OAAO;QACP,GAAG,EAAE,iBAAiB,EAAE;QACxB,OAAO,EAAE,qBAAqB,EAAE;QAChC,MAAM,EAAE,oBAAoB,EAAE;QAC9B,UAAU,EAAE,qBAAqB,EAAE;QACnC,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,2BAA2B,EAAE,IAAI,CAAC,2BAA2B;KAC9D,CAAC;AACJ,CAAC;AAED,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,kBAAkB,EAClB,sBAAsB,EACtB,YAAY,EACZ,qBAAqB,EACrB,iBAAiB,EACjB,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,GACzB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function getSystemLocale(): string;
|
|
2
|
+
/** Region subtag from a BCP-47 locale (e.g. en-US -> US, tr-TR -> TR). */
|
|
3
|
+
export declare function resolveLocaleRegion(locale: string): string | undefined;
|
|
4
|
+
/** Primary language subtag from a BCP-47 locale (e.g. en-US -> en, tr-TR -> tr). */
|
|
5
|
+
export declare function resolveLocaleLanguage(locale: string): string | undefined;
|
|
6
|
+
//# sourceMappingURL=locale.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale.d.ts","sourceRoot":"","sources":["../../src/analytics/locale.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,IAAI,MAAM,CAMxC;AAED,0EAA0E;AAC1E,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGtE;AAED,oFAAoF;AACpF,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGxE"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export function getSystemLocale() {
|
|
2
|
+
try {
|
|
3
|
+
return Intl.DateTimeFormat().resolvedOptions().locale;
|
|
4
|
+
}
|
|
5
|
+
catch {
|
|
6
|
+
return 'unknown';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
/** Region subtag from a BCP-47 locale (e.g. en-US -> US, tr-TR -> TR). */
|
|
10
|
+
export function resolveLocaleRegion(locale) {
|
|
11
|
+
const match = locale.trim().match(/-([A-Za-z]{2})\b/);
|
|
12
|
+
return match?.[1]?.toUpperCase();
|
|
13
|
+
}
|
|
14
|
+
/** Primary language subtag from a BCP-47 locale (e.g. en-US -> en, tr-TR -> tr). */
|
|
15
|
+
export function resolveLocaleLanguage(locale) {
|
|
16
|
+
const primary = locale.trim().split('-')[0]?.toLowerCase();
|
|
17
|
+
return primary || undefined;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=locale.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"locale.js","sourceRoot":"","sources":["../../src/analytics/locale.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,MAAM,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,mBAAmB,CAAC,MAAc;IAChD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IACtD,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;AACnC,CAAC;AAED,oFAAoF;AACpF,MAAM,UAAU,qBAAqB,CAAC,MAAc;IAClD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC;IAC3D,OAAO,OAAO,IAAI,SAAS,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type McpShutdownReason = 'sigint' | 'sigterm' | 'error' | 'stdio_closed';
|
|
2
|
+
export type McpToolBatchFlushReason = 'idle' | 'shutdown';
|
|
3
|
+
export declare function flushMcpToolBatch(reason: McpToolBatchFlushReason): void;
|
|
4
|
+
export declare function startMcpAnalyticsSession(): void;
|
|
5
|
+
export declare function recordMcpToolCall(params: {
|
|
6
|
+
toolName: string;
|
|
7
|
+
ok: boolean;
|
|
8
|
+
errorCode?: string;
|
|
9
|
+
durationMs: number;
|
|
10
|
+
}): void;
|
|
11
|
+
export declare function endMcpAnalyticsSession(reason: McpShutdownReason): void;
|
|
12
|
+
//# sourceMappingURL=mcp-session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-session.d.ts","sourceRoot":"","sources":["../../src/analytics/mcp-session.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,iBAAiB,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,GAAG,cAAc,CAAC;AAChF,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,UAAU,CAAC;AA6D1D,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,IAAI,CA4BvE;AAUD,wBAAgB,wBAAwB,IAAI,IAAI,CAE/C;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,IAAI,CAuBP;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,iBAAiB,GAAG,IAAI,CActE"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { hasPostHogKey } from './config.js';
|
|
2
|
+
import { buildRuntimeProperties } from './events.js';
|
|
3
|
+
import { isAnalyticsEnabled } from './identity.js';
|
|
4
|
+
import { captureMcpPageleave } from './pageview.js';
|
|
5
|
+
import { getAnalytics } from './provider.js';
|
|
6
|
+
/** Flush batched tool usage after this idle gap (proxy for end of an agent turn). */
|
|
7
|
+
const IDLE_FLUSH_MS = 30_000;
|
|
8
|
+
const MAX_SUMMARY_LENGTH = 4_000;
|
|
9
|
+
let startedAt = null;
|
|
10
|
+
let toolBatch = new Map();
|
|
11
|
+
let idleFlushTimer = null;
|
|
12
|
+
function captureMcpEvent(name, properties) {
|
|
13
|
+
if (!isAnalyticsEnabled() || !hasPostHogKey())
|
|
14
|
+
return;
|
|
15
|
+
getAnalytics().capture({
|
|
16
|
+
name,
|
|
17
|
+
properties: buildRuntimeProperties(properties),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function clearIdleFlushTimer() {
|
|
21
|
+
if (!idleFlushTimer)
|
|
22
|
+
return;
|
|
23
|
+
clearTimeout(idleFlushTimer);
|
|
24
|
+
idleFlushTimer = null;
|
|
25
|
+
}
|
|
26
|
+
function formatUsageSummary(batch) {
|
|
27
|
+
const parts = [...batch.entries()]
|
|
28
|
+
.sort((a, b) => b[1].ok + b[1].fail - (a[1].ok + a[1].fail))
|
|
29
|
+
.map(([name, entry]) => `${name}:${entry.ok + entry.fail}`);
|
|
30
|
+
let summary = parts.join(',');
|
|
31
|
+
if (summary.length > MAX_SUMMARY_LENGTH) {
|
|
32
|
+
summary = `${summary.slice(0, MAX_SUMMARY_LENGTH)}…`;
|
|
33
|
+
}
|
|
34
|
+
return summary;
|
|
35
|
+
}
|
|
36
|
+
function formatErrorCodesSummary(batch) {
|
|
37
|
+
const totals = new Map();
|
|
38
|
+
for (const entry of batch.values()) {
|
|
39
|
+
for (const [code, count] of entry.errors) {
|
|
40
|
+
totals.set(code, (totals.get(code) ?? 0) + count);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
if (totals.size === 0)
|
|
44
|
+
return undefined;
|
|
45
|
+
return [...totals.entries()]
|
|
46
|
+
.sort((a, b) => b[1] - a[1])
|
|
47
|
+
.map(([code, count]) => `${code}:${count}`)
|
|
48
|
+
.join(',');
|
|
49
|
+
}
|
|
50
|
+
export function flushMcpToolBatch(reason) {
|
|
51
|
+
if (toolBatch.size === 0)
|
|
52
|
+
return;
|
|
53
|
+
let toolsCalledCount = 0;
|
|
54
|
+
let toolsErrorCount = 0;
|
|
55
|
+
let totalDurationMs = 0;
|
|
56
|
+
for (const entry of toolBatch.values()) {
|
|
57
|
+
toolsCalledCount += entry.ok + entry.fail;
|
|
58
|
+
toolsErrorCount += entry.fail;
|
|
59
|
+
totalDurationMs += entry.durationMs;
|
|
60
|
+
}
|
|
61
|
+
const errorCodesSummary = formatErrorCodesSummary(toolBatch);
|
|
62
|
+
captureMcpEvent('mcp_tool_batch', {
|
|
63
|
+
tools_called_count: toolsCalledCount,
|
|
64
|
+
tools_error_count: toolsErrorCount,
|
|
65
|
+
unique_tools_count: toolBatch.size,
|
|
66
|
+
tool_usage_summary: formatUsageSummary(toolBatch),
|
|
67
|
+
...(errorCodesSummary ? { error_codes_summary: errorCodesSummary } : {}),
|
|
68
|
+
batch_flush_reason: reason,
|
|
69
|
+
duration_ms: totalDurationMs,
|
|
70
|
+
event_source: 'mcp',
|
|
71
|
+
});
|
|
72
|
+
toolBatch.clear();
|
|
73
|
+
clearIdleFlushTimer();
|
|
74
|
+
}
|
|
75
|
+
function scheduleIdleFlush() {
|
|
76
|
+
clearIdleFlushTimer();
|
|
77
|
+
idleFlushTimer = setTimeout(() => {
|
|
78
|
+
idleFlushTimer = null;
|
|
79
|
+
flushMcpToolBatch('idle');
|
|
80
|
+
}, IDLE_FLUSH_MS);
|
|
81
|
+
}
|
|
82
|
+
export function startMcpAnalyticsSession() {
|
|
83
|
+
startedAt = Date.now();
|
|
84
|
+
}
|
|
85
|
+
export function recordMcpToolCall(params) {
|
|
86
|
+
const existing = toolBatch.get(params.toolName) ?? {
|
|
87
|
+
ok: 0,
|
|
88
|
+
fail: 0,
|
|
89
|
+
errors: new Map(),
|
|
90
|
+
durationMs: 0,
|
|
91
|
+
};
|
|
92
|
+
if (params.ok) {
|
|
93
|
+
existing.ok += 1;
|
|
94
|
+
}
|
|
95
|
+
else {
|
|
96
|
+
existing.fail += 1;
|
|
97
|
+
if (params.errorCode) {
|
|
98
|
+
existing.errors.set(params.errorCode, (existing.errors.get(params.errorCode) ?? 0) + 1);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
existing.durationMs += params.durationMs;
|
|
102
|
+
toolBatch.set(params.toolName, existing);
|
|
103
|
+
scheduleIdleFlush();
|
|
104
|
+
}
|
|
105
|
+
export function endMcpAnalyticsSession(reason) {
|
|
106
|
+
flushMcpToolBatch('shutdown');
|
|
107
|
+
const durationMs = startedAt !== null ? Date.now() - startedAt : 0;
|
|
108
|
+
captureMcpPageleave(durationMs, reason);
|
|
109
|
+
captureMcpEvent('mcp_session_ended', {
|
|
110
|
+
duration_ms: durationMs,
|
|
111
|
+
shutdown_reason: reason,
|
|
112
|
+
event_source: 'mcp',
|
|
113
|
+
});
|
|
114
|
+
startedAt = null;
|
|
115
|
+
toolBatch.clear();
|
|
116
|
+
clearIdleFlushTimer();
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=mcp-session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-session.js","sourceRoot":"","sources":["../../src/analytics/mcp-session.ts"],"names":[],"mappings":"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"}
|
package/dist/analytics/noop.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AnalyticsEvent, AnalyticsProvider } from './types.js';
|
|
2
2
|
export declare class NoopAnalyticsProvider implements AnalyticsProvider {
|
|
3
3
|
capture(_event: AnalyticsEvent): void;
|
|
4
|
+
identify(_properties?: Record<string, unknown>): void;
|
|
4
5
|
shutdown(): Promise<void>;
|
|
5
6
|
}
|
|
6
7
|
//# sourceMappingURL=noop.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noop.d.ts","sourceRoot":"","sources":["../../src/analytics/noop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpE,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAI/
|
|
1
|
+
{"version":3,"file":"noop.d.ts","sourceRoot":"","sources":["../../src/analytics/noop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpE,qBAAa,qBAAsB,YAAW,iBAAiB;IAC7D,OAAO,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI;IAIrC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAI/C,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAGhC"}
|
package/dist/analytics/noop.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noop.js","sourceRoot":"","sources":["../../src/analytics/noop.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,qBAAqB;IAChC,OAAO,CAAC,MAAsB;QAC5B,sBAAsB;IACxB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,sBAAsB;IACxB,CAAC;CACF"}
|
|
1
|
+
{"version":3,"file":"noop.js","sourceRoot":"","sources":["../../src/analytics/noop.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,qBAAqB;IAChC,OAAO,CAAC,MAAsB;QAC5B,sBAAsB;IACxB,CAAC;IAED,QAAQ,CAAC,WAAqC;QAC5C,sBAAsB;IACxB,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,sBAAsB;IACxB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageview.d.ts","sourceRoot":"","sources":["../../src/analytics/pageview.ts"],"names":[],"mappings":"AAkBA,wBAAgB,kBAAkB,IAAI,IAAI,CAOzC;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAQ5E"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { hasPostHogKey } from './config.js';
|
|
2
|
+
import { buildRuntimeProperties } from './events.js';
|
|
3
|
+
import { isAnalyticsEnabled } from './identity.js';
|
|
4
|
+
import { getAnalytics } from './provider.js';
|
|
5
|
+
const MCP_VIRTUAL_URL = 'photoshop-mcp://mcp';
|
|
6
|
+
function capturePageEvent(name, properties) {
|
|
7
|
+
if (!isAnalyticsEnabled() || !hasPostHogKey())
|
|
8
|
+
return;
|
|
9
|
+
getAnalytics().capture({
|
|
10
|
+
name,
|
|
11
|
+
properties: buildRuntimeProperties(properties),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export function captureMcpPageview() {
|
|
15
|
+
capturePageEvent('$pageview', {
|
|
16
|
+
$current_url: MCP_VIRTUAL_URL,
|
|
17
|
+
$pathname: '/mcp',
|
|
18
|
+
usage_surface: 'mcp',
|
|
19
|
+
event_source: 'mcp',
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
export function captureMcpPageleave(durationMs, reason) {
|
|
23
|
+
capturePageEvent('$pageleave', {
|
|
24
|
+
$current_url: MCP_VIRTUAL_URL,
|
|
25
|
+
duration_ms: durationMs,
|
|
26
|
+
shutdown_reason: reason,
|
|
27
|
+
usage_surface: 'mcp',
|
|
28
|
+
event_source: 'mcp',
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=pageview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pageview.js","sourceRoot":"","sources":["../../src/analytics/pageview.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,eAAe,GAAG,qBAAqB,CAAC;AAE9C,SAAS,gBAAgB,CACvB,IAAY,EACZ,UAAmC;IAEnC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,aAAa,EAAE;QAAE,OAAO;IACtD,YAAY,EAAE,CAAC,OAAO,CAAC;QACrB,IAAI;QACJ,UAAU,EAAE,sBAAsB,CAAC,UAAU,CAAC;KAC/C,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,kBAAkB;IAChC,gBAAgB,CAAC,WAAW,EAAE;QAC5B,YAAY,EAAE,eAAe;QAC7B,SAAS,EAAE,MAAM;QACjB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,UAAkB,EAAE,MAAc;IACpE,gBAAgB,CAAC,YAAY,EAAE;QAC7B,YAAY,EAAE,eAAe;QAC7B,WAAW,EAAE,UAAU;QACvB,eAAe,EAAE,MAAM;QACvB,aAAa,EAAE,KAAK;QACpB,YAAY,EAAE,KAAK;KACpB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -2,7 +2,10 @@ import type { AnalyticsEvent, AnalyticsProvider } from './types.js';
|
|
|
2
2
|
export declare class PostHogNodeProvider implements AnalyticsProvider {
|
|
3
3
|
private client;
|
|
4
4
|
private logger;
|
|
5
|
+
private distinctId;
|
|
5
6
|
constructor();
|
|
7
|
+
private identifyPerson;
|
|
8
|
+
identify(properties?: Record<string, unknown>): void;
|
|
6
9
|
capture(event: AnalyticsEvent): void;
|
|
7
10
|
shutdown(): Promise<void>;
|
|
8
11
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"posthog-node.d.ts","sourceRoot":"","sources":["../../src/analytics/posthog-node.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"posthog-node.d.ts","sourceRoot":"","sources":["../../src/analytics/posthog-node.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEpE,qBAAa,mBAAoB,YAAW,iBAAiB;IAC3D,OAAO,CAAC,MAAM,CAAU;IACxB,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,UAAU,CAAS;;IAc3B,OAAO,CAAC,cAAc;IAItB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAYpD,OAAO,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI;IAa9B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAOhC"}
|