@alisaitteke/photoshop-mcp 1.2.0 → 1.3.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/README.md +94 -2
- package/dist/analytics/beta-telemetry.d.ts +11 -0
- package/dist/analytics/beta-telemetry.d.ts.map +1 -0
- package/dist/analytics/beta-telemetry.js +47 -0
- package/dist/analytics/beta-telemetry.js.map +1 -0
- package/dist/analytics/config.d.ts +6 -0
- package/dist/analytics/config.d.ts.map +1 -0
- package/dist/analytics/config.js +23 -0
- package/dist/analytics/config.js.map +1 -0
- package/dist/analytics/context.d.ts +2 -0
- package/dist/analytics/context.d.ts.map +1 -0
- package/dist/analytics/context.js +13 -0
- package/dist/analytics/context.js.map +1 -0
- package/dist/analytics/events.d.ts +3 -0
- package/dist/analytics/events.d.ts.map +1 -0
- package/dist/analytics/events.js +75 -0
- package/dist/analytics/events.js.map +1 -0
- package/dist/analytics/identity.d.ts +9 -0
- package/dist/analytics/identity.d.ts.map +1 -0
- package/dist/analytics/identity.js +166 -0
- package/dist/analytics/identity.js.map +1 -0
- package/dist/analytics/index.d.ts +10 -0
- package/dist/analytics/index.d.ts.map +1 -0
- package/dist/analytics/index.js +31 -0
- package/dist/analytics/index.js.map +1 -0
- package/dist/analytics/launch-method.d.ts +4 -0
- package/dist/analytics/launch-method.d.ts.map +1 -0
- package/dist/analytics/launch-method.js +33 -0
- package/dist/analytics/launch-method.js.map +1 -0
- package/dist/analytics/noop.d.ts +6 -0
- package/dist/analytics/noop.d.ts.map +1 -0
- package/dist/analytics/noop.js +9 -0
- package/dist/analytics/noop.js.map +1 -0
- package/dist/analytics/posthog-node.d.ts +9 -0
- package/dist/analytics/posthog-node.d.ts.map +1 -0
- package/dist/analytics/posthog-node.js +36 -0
- package/dist/analytics/posthog-node.js.map +1 -0
- package/dist/analytics/provider.d.ts +5 -0
- package/dist/analytics/provider.d.ts.map +1 -0
- package/dist/analytics/provider.js +27 -0
- package/dist/analytics/provider.js.map +1 -0
- package/dist/analytics/types.d.ts +23 -0
- package/dist/analytics/types.d.ts.map +1 -0
- package/dist/analytics/types.js +2 -0
- package/dist/analytics/types.js.map +1 -0
- package/dist/core/server.d.ts +1 -0
- package/dist/core/server.d.ts.map +1 -1
- package/dist/core/server.js +3 -0
- package/dist/core/server.js.map +1 -1
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -1
- package/dist/platform/macos-detector.js +4 -4
- package/dist/platform/macos-detector.js.map +1 -1
- package/dist/platform/macos-executor.js +1 -1
- package/dist/platform/macos-executor.js.map +1 -1
- package/dist/platform/windows-detector.js +4 -4
- package/dist/platform/windows-detector.js.map +1 -1
- package/dist/platform/windows-executor.js +2 -2
- package/dist/platform/windows-executor.js.map +1 -1
- package/dist/ui/agent/action-plan.d.ts +19 -0
- package/dist/ui/agent/action-plan.d.ts.map +1 -0
- package/dist/ui/agent/action-plan.js +552 -0
- package/dist/ui/agent/action-plan.js.map +1 -0
- package/dist/ui/agent/api-key.d.ts.map +1 -1
- package/dist/ui/agent/api-key.js +22 -4
- package/dist/ui/agent/api-key.js.map +1 -1
- package/dist/ui/agent/claude-account.d.ts.map +1 -1
- package/dist/ui/agent/claude-account.js +26 -12
- package/dist/ui/agent/claude-account.js.map +1 -1
- package/dist/ui/agent/gemini-account.d.ts.map +1 -1
- package/dist/ui/agent/gemini-account.js +14 -4
- package/dist/ui/agent/gemini-account.js.map +1 -1
- package/dist/ui/agent/shared.d.ts +26 -1
- package/dist/ui/agent/shared.d.ts.map +1 -1
- package/dist/ui/agent/shared.js +61 -0
- package/dist/ui/agent/shared.js.map +1 -1
- package/dist/ui/agent.d.ts +1 -0
- package/dist/ui/agent.d.ts.map +1 -1
- package/dist/ui/agent.js +36 -0
- package/dist/ui/agent.js.map +1 -1
- package/dist/ui/cli.js +10 -1
- package/dist/ui/cli.js.map +1 -1
- package/dist/ui/config.d.ts +6 -1
- package/dist/ui/config.d.ts.map +1 -1
- package/dist/ui/config.js +1 -12
- package/dist/ui/config.js.map +1 -1
- package/dist/ui/server.d.ts.map +1 -1
- package/dist/ui/server.js +102 -6
- package/dist/ui/server.js.map +1 -1
- package/dist/ui/store/chats.d.ts +11 -0
- package/dist/ui/store/chats.d.ts.map +1 -1
- package/dist/ui/store/chats.js.map +1 -1
- package/package.json +4 -2
- package/web/dist/assets/index-BgiXf1Jy.css +1 -0
- package/web/dist/assets/index-BuJJLllx.js +249 -0
- package/web/dist/index.html +9 -3
- package/web/dist/assets/index-BN0tu4e6.css +0 -1
- package/web/dist/assets/index-Cf7sH5RM.js +0 -138
package/README.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
# Photoshop MCP Server
|
|
2
2
|
|
|
3
|
-
*v1.1+ — recipe workflows, fewer round-trips, snappier sessions.*
|
|
3
|
+
*v1.1+ — recipe workflows, fewer round-trips, snappier sessions. Standalone UI ships **Action Plan (beta)** for plan-then-execute runs.*
|
|
4
4
|
|
|
5
5
|
> **Note:** This is an unofficial, community-maintained project and is not affiliated with or endorsed by Adobe Inc.
|
|
6
6
|
|
|
7
7
|
[](https://www.npmjs.com/package/@alisaitteke/photoshop-mcp)
|
|
8
|
+
[](#action-plan-beta)
|
|
8
9
|
[](https://opensource.org/licenses/MIT)
|
|
9
10
|
[](https://www.typescriptlang.org/)
|
|
10
11
|
[]()
|
|
11
12
|
|
|
12
|
-
A Model Context Protocol (MCP) server that enables AI assistants like Claude and Cursor to control Adobe Photoshop programmatically. This allows you to create designs, manipulate images, and automate Photoshop workflows through natural language commands while working in your IDE — or through the bundled **standalone web UI**, which supports both API keys and CLI subscription accounts (Claude Code / Gemini CLI).
|
|
13
|
+
A Model Context Protocol (MCP) server that enables AI assistants like Claude and Cursor to control Adobe Photoshop programmatically. This allows you to create designs, manipulate images, and automate Photoshop workflows through natural language commands while working in your IDE — or through the bundled **standalone web UI**, which supports both API keys and CLI subscription accounts (Claude Code / Gemini CLI). The UI also offers an opt-in **Action Plan (beta)** mode that plans every Photoshop step in one LLM call, then runs them in a single pass.
|
|
13
14
|
|
|
14
15
|
## 🖥️ Standalone UI (no IDE required)
|
|
15
16
|
|
|
@@ -52,6 +53,29 @@ CLI subscription account (Anthropic and Google):
|
|
|
52
53
|
You can switch auth method per provider in Settings without losing the other
|
|
53
54
|
credential (e.g. keep an API key while trying CLI account, then switch back).
|
|
54
55
|
|
|
56
|
+
### Action Plan (beta)
|
|
57
|
+
|
|
58
|
+
An optional execution mode in the standalone web UI for **API key auth only**
|
|
59
|
+
(`cli_account` always uses the default agentic flow). Turn it on with the
|
|
60
|
+
**Action Plan** toggle next to the model selector in the composer.
|
|
61
|
+
|
|
62
|
+
Instead of a per-step ReAct loop (model → tool → model → tool …), Action Plan:
|
|
63
|
+
|
|
64
|
+
1. Makes **one** planning LLM call that outputs an ordered todo list of
|
|
65
|
+
Photoshop MCP tool calls with parameters.
|
|
66
|
+
2. Executes those tools **directly** in sequence — no extra model round-trips
|
|
67
|
+
between steps.
|
|
68
|
+
3. On a failed step or unresolved dependency, runs a bounded **repair** loop
|
|
69
|
+
(re-plans only the remaining steps, up to 3 times).
|
|
70
|
+
|
|
71
|
+
The plan appears as a live todo list above the tool-call cards, with per-step
|
|
72
|
+
status (`pending` → `running` → `done` / `error`). Plans are persisted in chat
|
|
73
|
+
history so they survive reload. The toggle is off by default; the existing
|
|
74
|
+
agentic flow is unchanged when Action Plan is disabled.
|
|
75
|
+
|
|
76
|
+
Good for multi-step prompts such as *"remove the background and export for web"*
|
|
77
|
+
where you want fewer model calls and faster end-to-end execution.
|
|
78
|
+
|
|
55
79
|
### What happens on first launch
|
|
56
80
|
|
|
57
81
|
1. Pick a provider and choose **API key** or **Uses your account**.
|
|
@@ -426,6 +450,8 @@ Never guess — read get_state after a failure and propose the next single step.
|
|
|
426
450
|
|
|
427
451
|
- **Standalone web UI** — local chat interface (`photoshop-mcp-ui`); API key or CLI
|
|
428
452
|
subscription auth per provider (Anthropic, Google)
|
|
453
|
+
- **Action Plan (beta)** — opt-in plan-then-execute mode in the web UI (API key
|
|
454
|
+
only): one planning call, direct tool execution, bounded repair on failure
|
|
429
455
|
- **Works on both Windows and macOS**
|
|
430
456
|
- **Supports Photoshop 2012-2025+**
|
|
431
457
|
- **ExtendScript API**: Universal compatibility via AppleScript/COM automation
|
|
@@ -499,6 +525,10 @@ Add to your Claude Desktop config (`~/Library/Application Support/Claude/claude_
|
|
|
499
525
|
|
|
500
526
|
- `PHOTOSHOP_PATH`: (Optional) Specify custom Photoshop installation path
|
|
501
527
|
- `LOG_LEVEL`: Logging level (0=DEBUG, 1=INFO, 2=WARN, 3=ERROR)
|
|
528
|
+
- `POSTHOG_DISABLED`: Set to `1` or `true` to disable anonymous usage analytics entirely
|
|
529
|
+
- `POSTHOG_KEY`: (Optional) Override the PostHog project key used for analytics
|
|
530
|
+
- `POSTHOG_API_HOST`: (Optional) PostHog ingest host (default: `https://a.alisait.com`)
|
|
531
|
+
- `POSTHOG_UI_HOST`: (Optional) PostHog UI host for dashboard links (default: `https://eu.posthog.com`)
|
|
502
532
|
|
|
503
533
|
## Available Tools
|
|
504
534
|
|
|
@@ -612,6 +642,68 @@ Contributions are welcome! Please read [CONTRIBUTING.md](CONTRIBUTING.md) before
|
|
|
612
642
|
|
|
613
643
|
MIT
|
|
614
644
|
|
|
645
|
+
## Anonymous Usage Analytics
|
|
646
|
+
|
|
647
|
+
This project collects **anonymous, aggregated usage events** to understand how the
|
|
648
|
+
MCP server and standalone UI are used and to improve the product. Analytics are
|
|
649
|
+
**enabled by default** and can be turned off at any time.
|
|
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).
|
|
706
|
+
|
|
615
707
|
## Acknowledgments
|
|
616
708
|
|
|
617
709
|
- Built with the [Model Context Protocol SDK](https://github.com/modelcontextprotocol/sdk)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface BetaChatTurnInput {
|
|
2
|
+
providerId: string;
|
|
3
|
+
model: string;
|
|
4
|
+
authMethod: string;
|
|
5
|
+
userPrompt: string;
|
|
6
|
+
assistantText: string;
|
|
7
|
+
assistantReasoning?: string;
|
|
8
|
+
toolNames: string[];
|
|
9
|
+
}
|
|
10
|
+
export declare function captureBetaChatTurn(input: BetaChatTurnInput): void;
|
|
11
|
+
//# sourceMappingURL=beta-telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beta-telemetry.d.ts","sourceRoot":"","sources":["../../src/analytics/beta-telemetry.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,SAAS,EAAE,MAAM,EAAE,CAAC;CACrB;AAYD,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,CAgClE"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { isAnalyticsEnabled, isBetaTelemetryOptIn } from './identity.js';
|
|
2
|
+
import { getLaunchMethod } from './launch-method.js';
|
|
3
|
+
import { getAnalytics } from './provider.js';
|
|
4
|
+
const MAX_TEXT_LENGTH = 16_000;
|
|
5
|
+
const TRUNCATION_SUFFIX = '…[truncated]';
|
|
6
|
+
function truncateText(value) {
|
|
7
|
+
if (!value)
|
|
8
|
+
return undefined;
|
|
9
|
+
if (value.length <= MAX_TEXT_LENGTH)
|
|
10
|
+
return value;
|
|
11
|
+
return `${value.slice(0, MAX_TEXT_LENGTH)}${TRUNCATION_SUFFIX}`;
|
|
12
|
+
}
|
|
13
|
+
function uniqueToolNames(names) {
|
|
14
|
+
return [...new Set(names.map((name) => name.trim()).filter(Boolean))];
|
|
15
|
+
}
|
|
16
|
+
export function captureBetaChatTurn(input) {
|
|
17
|
+
if (!isAnalyticsEnabled() || !isBetaTelemetryOptIn())
|
|
18
|
+
return;
|
|
19
|
+
const assistantText = input.assistantText.trim();
|
|
20
|
+
const assistantReasoning = input.assistantReasoning?.trim() ?? '';
|
|
21
|
+
const hasAssistantContent = assistantText.length > 0 ||
|
|
22
|
+
assistantReasoning.length > 0 ||
|
|
23
|
+
input.toolNames.length > 0;
|
|
24
|
+
if (!hasAssistantContent)
|
|
25
|
+
return;
|
|
26
|
+
const toolNames = uniqueToolNames(input.toolNames);
|
|
27
|
+
getAnalytics().capture({
|
|
28
|
+
name: 'beta_chat_turn',
|
|
29
|
+
properties: {
|
|
30
|
+
os: process.platform,
|
|
31
|
+
arch: process.arch,
|
|
32
|
+
node_version: process.version,
|
|
33
|
+
launch_method: getLaunchMethod(),
|
|
34
|
+
event_source: 'server',
|
|
35
|
+
provider_id: input.providerId,
|
|
36
|
+
auth_method: input.authMethod,
|
|
37
|
+
model: input.model,
|
|
38
|
+
user_prompt: truncateText(input.userPrompt.trim()) ?? '',
|
|
39
|
+
assistant_text: truncateText(assistantText) ?? '',
|
|
40
|
+
...(assistantReasoning
|
|
41
|
+
? { assistant_reasoning: truncateText(assistantReasoning) }
|
|
42
|
+
: {}),
|
|
43
|
+
...(toolNames.length > 0 ? { tool_names: toolNames.join(',') } : {}),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=beta-telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beta-telemetry.js","sourceRoot":"","sources":["../../src/analytics/beta-telemetry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7C,MAAM,eAAe,GAAG,MAAM,CAAC;AAC/B,MAAM,iBAAiB,GAAG,cAAc,CAAC;AAYzC,SAAS,YAAY,CAAC,KAAyB;IAC7C,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,IAAI,KAAK,CAAC,MAAM,IAAI,eAAe;QAAE,OAAO,KAAK,CAAC;IAClD,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,GAAG,iBAAiB,EAAE,CAAC;AAClE,CAAC;AAED,SAAS,eAAe,CAAC,KAAe;IACtC,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAwB;IAC1D,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,oBAAoB,EAAE;QAAE,OAAO;IAE7D,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC;IACjD,MAAM,kBAAkB,GAAG,KAAK,CAAC,kBAAkB,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAClE,MAAM,mBAAmB,GACvB,aAAa,CAAC,MAAM,GAAG,CAAC;QACxB,kBAAkB,CAAC,MAAM,GAAG,CAAC;QAC7B,KAAK,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,mBAAmB;QAAE,OAAO;IAEjC,MAAM,SAAS,GAAG,eAAe,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;IAEnD,YAAY,EAAE,CAAC,OAAO,CAAC;QACrB,IAAI,EAAE,gBAAgB;QACtB,UAAU,EAAE;YACV,EAAE,EAAE,OAAO,CAAC,QAAQ;YACpB,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,YAAY,EAAE,OAAO,CAAC,OAAO;YAC7B,aAAa,EAAE,eAAe,EAAE;YAChC,YAAY,EAAE,QAAQ;YACtB,WAAW,EAAE,KAAK,CAAC,UAAU;YAC7B,WAAW,EAAE,KAAK,CAAC,UAAU;YAC7B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,WAAW,EAAE,YAAY,CAAC,KAAK,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE;YACxD,cAAc,EAAE,YAAY,CAAC,aAAa,CAAC,IAAI,EAAE;YACjD,GAAG,CAAC,kBAAkB;gBACpB,CAAC,CAAC,EAAE,mBAAmB,EAAE,YAAY,CAAC,kBAAkB,CAAC,EAAE;gBAC3D,CAAC,CAAC,EAAE,CAAC;YACP,GAAG,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACrE;KACF,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function isPostHogDisabledByEnv(): boolean;
|
|
2
|
+
export declare function resolvePostHogKey(): string;
|
|
3
|
+
export declare function resolvePostHogApiHost(): string;
|
|
4
|
+
export declare function resolvePostHogUiHost(): string;
|
|
5
|
+
export declare function hasPostHogKey(): boolean;
|
|
6
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/analytics/config.ts"],"names":[],"mappings":"AASA,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,wBAAgB,aAAa,IAAI,OAAO,CAEvC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const DEFAULT_POSTHOG_KEY = 'phc_mejq4ZZ8jTNZPiusjh7vHyPzWYinzsDwVJW43SM5FEcg';
|
|
2
|
+
const DEFAULT_API_HOST = 'https://a.alisait.com';
|
|
3
|
+
const DEFAULT_UI_HOST = 'https://eu.posthog.com';
|
|
4
|
+
function envTruthy(name) {
|
|
5
|
+
const value = process.env[name]?.trim().toLowerCase();
|
|
6
|
+
return value === '1' || value === 'true' || value === 'yes';
|
|
7
|
+
}
|
|
8
|
+
export function isPostHogDisabledByEnv() {
|
|
9
|
+
return envTruthy('POSTHOG_DISABLED');
|
|
10
|
+
}
|
|
11
|
+
export function resolvePostHogKey() {
|
|
12
|
+
return process.env.POSTHOG_KEY?.trim() || DEFAULT_POSTHOG_KEY;
|
|
13
|
+
}
|
|
14
|
+
export function resolvePostHogApiHost() {
|
|
15
|
+
return process.env.POSTHOG_API_HOST?.trim() || DEFAULT_API_HOST;
|
|
16
|
+
}
|
|
17
|
+
export function resolvePostHogUiHost() {
|
|
18
|
+
return process.env.POSTHOG_UI_HOST?.trim() || DEFAULT_UI_HOST;
|
|
19
|
+
}
|
|
20
|
+
export function hasPostHogKey() {
|
|
21
|
+
return resolvePostHogKey().length > 0;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/analytics/config.ts"],"names":[],"mappings":"AAAA,MAAM,mBAAmB,GAAG,kDAAkD,CAAC;AAC/E,MAAM,gBAAgB,GAAG,uBAAuB,CAAC;AACjD,MAAM,eAAe,GAAG,wBAAwB,CAAC;AAEjD,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtD,OAAO,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,KAAK,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,sBAAsB;IACpC,OAAO,SAAS,CAAC,kBAAkB,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,IAAI,EAAE,IAAI,mBAAmB,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,qBAAqB;IACnC,OAAO,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,IAAI,EAAE,IAAI,gBAAgB,CAAC;AAClE,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,IAAI,eAAe,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,iBAAiB,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC;AACxC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/analytics/context.ts"],"names":[],"mappings":"AAGA,wBAAgB,yBAAyB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CASnE"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { loadConfig } from '../ui/config.js';
|
|
2
|
+
import { isAnalyticsEnabled, isBetaTelemetryOptIn } from './identity.js';
|
|
3
|
+
export function getServerAnalyticsContext() {
|
|
4
|
+
const config = loadConfig();
|
|
5
|
+
const analyticsEnabled = isAnalyticsEnabled();
|
|
6
|
+
return {
|
|
7
|
+
privacy_mode: !analyticsEnabled,
|
|
8
|
+
analytics_enabled: analyticsEnabled,
|
|
9
|
+
beta_telemetry_opt_in: isBetaTelemetryOptIn(),
|
|
10
|
+
action_plan_enabled: Boolean(config.actionPlanBeta),
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/analytics/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAEzE,MAAM,UAAU,yBAAyB;IACvC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,gBAAgB,GAAG,kBAAkB,EAAE,CAAC;IAC9C,OAAO;QACL,YAAY,EAAE,CAAC,gBAAgB;QAC/B,iBAAiB,EAAE,gBAAgB;QACnC,qBAAqB,EAAE,oBAAoB,EAAE;QAC7C,mBAAmB,EAAE,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC;KACpD,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export declare function sanitizeAnalyticsProperties(properties: Record<string, unknown> | undefined): Record<string, string | number | boolean>;
|
|
2
|
+
export declare function buildRuntimeProperties(properties: Record<string, unknown> | undefined): Record<string, string | number | boolean>;
|
|
3
|
+
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/analytics/events.ts"],"names":[],"mappings":"AAiDA,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC9C,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAc3C;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,CAS3C"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { getServerAnalyticsContext } from './context.js';
|
|
2
|
+
import { getLaunchMethod } from './launch-method.js';
|
|
3
|
+
const BLOCKED_PROPERTY_KEYS = new Set([
|
|
4
|
+
'api_key',
|
|
5
|
+
'apikey',
|
|
6
|
+
'key',
|
|
7
|
+
'token',
|
|
8
|
+
'secret',
|
|
9
|
+
'password',
|
|
10
|
+
'email',
|
|
11
|
+
'account_label',
|
|
12
|
+
'cli_path',
|
|
13
|
+
'path',
|
|
14
|
+
'file_path',
|
|
15
|
+
'filepath',
|
|
16
|
+
'message',
|
|
17
|
+
'content',
|
|
18
|
+
'prompt',
|
|
19
|
+
'chat_id',
|
|
20
|
+
'session_id',
|
|
21
|
+
]);
|
|
22
|
+
const ALLOWED_PROPERTY_KEYS = new Set([
|
|
23
|
+
'app_version',
|
|
24
|
+
'os',
|
|
25
|
+
'arch',
|
|
26
|
+
'node_version',
|
|
27
|
+
'provider_id',
|
|
28
|
+
'auth_method',
|
|
29
|
+
'ok',
|
|
30
|
+
'error_code',
|
|
31
|
+
'photoshop_detected',
|
|
32
|
+
'action_plan_enabled',
|
|
33
|
+
'event_source',
|
|
34
|
+
'port',
|
|
35
|
+
'host',
|
|
36
|
+
'no_open',
|
|
37
|
+
'has_auth',
|
|
38
|
+
'has_custom_path',
|
|
39
|
+
'opted_out',
|
|
40
|
+
'opted_in',
|
|
41
|
+
'privacy_mode',
|
|
42
|
+
'analytics_enabled',
|
|
43
|
+
'beta_telemetry_opt_in',
|
|
44
|
+
'theme',
|
|
45
|
+
'launch_method',
|
|
46
|
+
]);
|
|
47
|
+
export function sanitizeAnalyticsProperties(properties) {
|
|
48
|
+
if (!properties)
|
|
49
|
+
return {};
|
|
50
|
+
const out = {};
|
|
51
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
52
|
+
const normalized = key.toLowerCase();
|
|
53
|
+
if (BLOCKED_PROPERTY_KEYS.has(normalized))
|
|
54
|
+
continue;
|
|
55
|
+
if (!ALLOWED_PROPERTY_KEYS.has(normalized))
|
|
56
|
+
continue;
|
|
57
|
+
if (value === null || value === undefined)
|
|
58
|
+
continue;
|
|
59
|
+
if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
|
|
60
|
+
out[normalized] = value;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return out;
|
|
64
|
+
}
|
|
65
|
+
export function buildRuntimeProperties(properties) {
|
|
66
|
+
return {
|
|
67
|
+
os: process.platform,
|
|
68
|
+
arch: process.arch,
|
|
69
|
+
node_version: process.version,
|
|
70
|
+
launch_method: getLaunchMethod(),
|
|
71
|
+
...getServerAnalyticsContext(),
|
|
72
|
+
...sanitizeAnalyticsProperties(properties),
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +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;AAErD,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,SAAS;IACT,QAAQ;IACR,KAAK;IACL,OAAO;IACP,QAAQ;IACR,UAAU;IACV,OAAO;IACP,eAAe;IACf,UAAU;IACV,MAAM;IACN,WAAW;IACX,UAAU;IACV,SAAS;IACT,SAAS;IACT,QAAQ;IACR,SAAS;IACT,YAAY;CACb,CAAC,CAAC;AAEH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC;IACpC,aAAa;IACb,IAAI;IACJ,MAAM;IACN,cAAc;IACd,aAAa;IACb,aAAa;IACb,IAAI;IACJ,YAAY;IACZ,oBAAoB;IACpB,qBAAqB;IACrB,cAAc;IACd,MAAM;IACN,MAAM;IACN,SAAS;IACT,UAAU;IACV,iBAAiB;IACjB,WAAW;IACX,UAAU;IACV,cAAc;IACd,mBAAmB;IACnB,uBAAuB;IACvB,OAAO;IACP,eAAe;CAChB,CAAC,CAAC;AAEH,MAAM,UAAU,2BAA2B,CACzC,UAA+C;IAE/C,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAC;IAE3B,MAAM,GAAG,GAA8C,EAAE,CAAC;IAC1D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACtD,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,SAAS;QACpD,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,SAAS;QACrD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QACpD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YACzF,GAAG,CAAC,UAAU,CAAC,GAAG,KAAK,CAAC;QAC1B,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,sBAAsB,CACpC,UAA+C;IAE/C,OAAO;QACL,EAAE,EAAE,OAAO,CAAC,QAAQ;QACpB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,YAAY,EAAE,OAAO,CAAC,OAAO;QAC7B,aAAa,EAAE,eAAe,EAAE;QAChC,GAAG,yBAAyB,EAAE;QAC9B,GAAG,2BAA2B,CAAC,UAAU,CAAC;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { BetaTelemetryState } from './types.js';
|
|
2
|
+
export declare function getOrCreateDistinctId(): string;
|
|
3
|
+
export declare function isAnalyticsOptedOut(): boolean;
|
|
4
|
+
export declare function setAnalyticsOptOut(optedOut: boolean): void;
|
|
5
|
+
export declare function isAnalyticsEnabled(): boolean;
|
|
6
|
+
export declare function getBetaTelemetryState(): BetaTelemetryState;
|
|
7
|
+
export declare function isBetaTelemetryOptIn(): boolean;
|
|
8
|
+
export declare function setBetaTelemetryChoice(optedIn: boolean): void;
|
|
9
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/analytics/identity.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAwFrD,wBAAgB,qBAAqB,IAAI,MAAM,CAsB9C;AAED,wBAAgB,mBAAmB,IAAI,OAAO,CAO7C;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAI1D;AAED,wBAAgB,kBAAkB,IAAI,OAAO,CAE5C;AAqBD,wBAAgB,qBAAqB,IAAI,kBAAkB,CAW1D;AAED,wBAAgB,oBAAoB,IAAI,OAAO,CAE9C;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAS7D"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { getPhotoshopMcpHomeDir } from '../lib/export-paths.js';
|
|
5
|
+
import { kvGet, kvSet } from '../ui/store/kv.js';
|
|
6
|
+
import { isPostHogDisabledByEnv } from './config.js';
|
|
7
|
+
const DISTINCT_ID_KEY = 'analytics_distinct_id';
|
|
8
|
+
const OPT_OUT_KEY = 'analytics_opt_out';
|
|
9
|
+
const BETA_TELEMETRY_OPT_IN_KEY = 'beta_telemetry_opt_in';
|
|
10
|
+
const BETA_TELEMETRY_PROMPT_ANSWERED_KEY = 'beta_telemetry_prompt_answered';
|
|
11
|
+
const STORE_FILE = 'analytics-store.json';
|
|
12
|
+
let memoryDistinctId = null;
|
|
13
|
+
let dbAvailable = null;
|
|
14
|
+
function getStorePath() {
|
|
15
|
+
return join(getPhotoshopMcpHomeDir(), STORE_FILE);
|
|
16
|
+
}
|
|
17
|
+
function readFileStore() {
|
|
18
|
+
try {
|
|
19
|
+
const raw = readFileSync(getStorePath(), 'utf8');
|
|
20
|
+
return JSON.parse(raw);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function writeFileStore(store) {
|
|
27
|
+
const dir = getPhotoshopMcpHomeDir();
|
|
28
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
29
|
+
writeFileSync(getStorePath(), JSON.stringify(store), { mode: 0o600 });
|
|
30
|
+
}
|
|
31
|
+
function canUseKv() {
|
|
32
|
+
if (dbAvailable === false)
|
|
33
|
+
return false;
|
|
34
|
+
try {
|
|
35
|
+
kvGet('__analytics_probe__');
|
|
36
|
+
dbAvailable = true;
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
dbAvailable = false;
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function readDistinctIdFromKv() {
|
|
45
|
+
if (!canUseKv())
|
|
46
|
+
return undefined;
|
|
47
|
+
try {
|
|
48
|
+
return kvGet(DISTINCT_ID_KEY);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
dbAvailable = false;
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function writeDistinctIdToKv(id) {
|
|
56
|
+
if (!canUseKv())
|
|
57
|
+
return;
|
|
58
|
+
try {
|
|
59
|
+
kvSet(DISTINCT_ID_KEY, id);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
dbAvailable = false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function readOptOutFromKv() {
|
|
66
|
+
if (!canUseKv())
|
|
67
|
+
return undefined;
|
|
68
|
+
try {
|
|
69
|
+
return kvGet(OPT_OUT_KEY);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
dbAvailable = false;
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function writeOptOutToKv(optedOut) {
|
|
77
|
+
if (!canUseKv())
|
|
78
|
+
return;
|
|
79
|
+
try {
|
|
80
|
+
kvSet(OPT_OUT_KEY, optedOut);
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
dbAvailable = false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function getOrCreateDistinctId() {
|
|
87
|
+
if (memoryDistinctId)
|
|
88
|
+
return memoryDistinctId;
|
|
89
|
+
const fromKv = readDistinctIdFromKv();
|
|
90
|
+
if (fromKv) {
|
|
91
|
+
memoryDistinctId = fromKv;
|
|
92
|
+
return fromKv;
|
|
93
|
+
}
|
|
94
|
+
const fromFile = readFileStore().distinctId;
|
|
95
|
+
if (fromFile) {
|
|
96
|
+
memoryDistinctId = fromFile;
|
|
97
|
+
writeDistinctIdToKv(fromFile);
|
|
98
|
+
return fromFile;
|
|
99
|
+
}
|
|
100
|
+
const id = randomUUID();
|
|
101
|
+
memoryDistinctId = id;
|
|
102
|
+
writeDistinctIdToKv(id);
|
|
103
|
+
const store = readFileStore();
|
|
104
|
+
writeFileStore({ ...store, distinctId: id });
|
|
105
|
+
return id;
|
|
106
|
+
}
|
|
107
|
+
export function isAnalyticsOptedOut() {
|
|
108
|
+
if (isPostHogDisabledByEnv())
|
|
109
|
+
return true;
|
|
110
|
+
const fromKv = readOptOutFromKv();
|
|
111
|
+
if (fromKv !== undefined)
|
|
112
|
+
return fromKv;
|
|
113
|
+
return readFileStore().optedOut === true;
|
|
114
|
+
}
|
|
115
|
+
export function setAnalyticsOptOut(optedOut) {
|
|
116
|
+
writeOptOutToKv(optedOut);
|
|
117
|
+
const store = readFileStore();
|
|
118
|
+
writeFileStore({ ...store, optedOut });
|
|
119
|
+
}
|
|
120
|
+
export function isAnalyticsEnabled() {
|
|
121
|
+
return !isAnalyticsOptedOut();
|
|
122
|
+
}
|
|
123
|
+
function readBooleanFromKv(key) {
|
|
124
|
+
if (!canUseKv())
|
|
125
|
+
return undefined;
|
|
126
|
+
try {
|
|
127
|
+
return kvGet(key);
|
|
128
|
+
}
|
|
129
|
+
catch {
|
|
130
|
+
dbAvailable = false;
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function writeBooleanToKv(key, value) {
|
|
135
|
+
if (!canUseKv())
|
|
136
|
+
return;
|
|
137
|
+
try {
|
|
138
|
+
kvSet(key, value);
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
dbAvailable = false;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
export function getBetaTelemetryState() {
|
|
145
|
+
const fromKvOptIn = readBooleanFromKv(BETA_TELEMETRY_OPT_IN_KEY);
|
|
146
|
+
const fromKvAnswered = readBooleanFromKv(BETA_TELEMETRY_PROMPT_ANSWERED_KEY);
|
|
147
|
+
const fileStore = readFileStore();
|
|
148
|
+
return {
|
|
149
|
+
betaTelemetryOptIn: fromKvOptIn ?? fileStore.betaTelemetryOptIn ?? false,
|
|
150
|
+
betaTelemetryPromptAnswered: fromKvAnswered ?? fileStore.betaTelemetryPromptAnswered ?? false,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
export function isBetaTelemetryOptIn() {
|
|
154
|
+
return getBetaTelemetryState().betaTelemetryOptIn;
|
|
155
|
+
}
|
|
156
|
+
export function setBetaTelemetryChoice(optedIn) {
|
|
157
|
+
writeBooleanToKv(BETA_TELEMETRY_OPT_IN_KEY, optedIn);
|
|
158
|
+
writeBooleanToKv(BETA_TELEMETRY_PROMPT_ANSWERED_KEY, true);
|
|
159
|
+
const store = readFileStore();
|
|
160
|
+
writeFileStore({
|
|
161
|
+
...store,
|
|
162
|
+
betaTelemetryOptIn: optedIn,
|
|
163
|
+
betaTelemetryPromptAnswered: true,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/analytics/identity.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { captureBetaChatTurn } from './beta-telemetry.js';
|
|
2
|
+
import { getBetaTelemetryState, setBetaTelemetryChoice } from './identity.js';
|
|
3
|
+
import { getAnalytics, resetAnalyticsProvider } from './provider.js';
|
|
4
|
+
import type { AnalyticsEvent, AnalyticsProvider, AnalyticsRuntimeConfig, BetaTelemetryState } from './types.js';
|
|
5
|
+
export declare function capture(name: string, properties?: Record<string, unknown>): void;
|
|
6
|
+
export declare function shutdownAnalytics(): Promise<void>;
|
|
7
|
+
export declare function getAnalyticsRuntimeConfig(): AnalyticsRuntimeConfig;
|
|
8
|
+
export { captureBetaChatTurn, getAnalytics, getBetaTelemetryState, resetAnalyticsProvider, setBetaTelemetryChoice, };
|
|
9
|
+
export type { AnalyticsEvent, AnalyticsProvider, AnalyticsRuntimeConfig, BetaTelemetryState };
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +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,EACnB,MAAM,YAAY,CAAC;AAEpB,wBAAgB,OAAO,CACrB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACnC,IAAI,CAMN;AAED,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEvD;AAED,wBAAgB,yBAAyB,IAAI,sBAAsB,CAYlE;AAED,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,GACvB,CAAC;AACF,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { captureBetaChatTurn } from './beta-telemetry.js';
|
|
2
|
+
import { hasPostHogKey, resolvePostHogApiHost, resolvePostHogKey, resolvePostHogUiHost, } from './config.js';
|
|
3
|
+
import { buildRuntimeProperties } from './events.js';
|
|
4
|
+
import { getBetaTelemetryState, getOrCreateDistinctId, isAnalyticsEnabled, setBetaTelemetryChoice, } from './identity.js';
|
|
5
|
+
import { getAnalytics, resetAnalyticsProvider, shutdownAnalyticsClient } from './provider.js';
|
|
6
|
+
export function capture(name, properties) {
|
|
7
|
+
if (!isAnalyticsEnabled() || !hasPostHogKey())
|
|
8
|
+
return;
|
|
9
|
+
getAnalytics().capture({
|
|
10
|
+
name,
|
|
11
|
+
properties: buildRuntimeProperties(properties),
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export async function shutdownAnalytics() {
|
|
15
|
+
await shutdownAnalyticsClient();
|
|
16
|
+
}
|
|
17
|
+
export function getAnalyticsRuntimeConfig() {
|
|
18
|
+
const enabled = isAnalyticsEnabled() && hasPostHogKey();
|
|
19
|
+
const beta = getBetaTelemetryState();
|
|
20
|
+
return {
|
|
21
|
+
enabled,
|
|
22
|
+
key: resolvePostHogKey(),
|
|
23
|
+
apiHost: resolvePostHogApiHost(),
|
|
24
|
+
uiHost: resolvePostHogUiHost(),
|
|
25
|
+
distinctId: getOrCreateDistinctId(),
|
|
26
|
+
betaTelemetryOptIn: beta.betaTelemetryOptIn,
|
|
27
|
+
betaTelemetryPromptAnswered: beta.betaTelemetryPromptAnswered,
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
export { captureBetaChatTurn, getAnalytics, getBetaTelemetryState, resetAnalyticsProvider, setBetaTelemetryChoice, };
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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;AAQ9F,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,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,YAAY,EACZ,qBAAqB,EACrB,sBAAsB,EACtB,sBAAsB,GACvB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launch-method.d.ts","sourceRoot":"","sources":["../../src/analytics/launch-method.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,SAAS,CAAC;AAuB9D,wBAAgB,mBAAmB,CACjC,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,IAAI,GAAE,MAAM,EAAiB,GAC5B,YAAY,CAWd;AAED,wBAAgB,eAAe,IAAI,YAAY,CAK9C"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
let cachedLaunchMethod = null;
|
|
2
|
+
function isNpxInvocation(npmExecPath, npmCommand) {
|
|
3
|
+
if (npmCommand === 'exec' || npmCommand === 'exec-run')
|
|
4
|
+
return true;
|
|
5
|
+
const normalizedPath = npmExecPath.toLowerCase();
|
|
6
|
+
return (normalizedPath.includes('/npx/') ||
|
|
7
|
+
normalizedPath.includes('\\npx\\') ||
|
|
8
|
+
/(?:^|[/\\])npx(?:\.cmd)?$/i.test(npmExecPath));
|
|
9
|
+
}
|
|
10
|
+
function isNpmScriptInvocation(npmCommand) {
|
|
11
|
+
return (npmCommand === 'run-script' ||
|
|
12
|
+
npmCommand === 'run' ||
|
|
13
|
+
Boolean(process.env.npm_lifecycle_event?.trim()));
|
|
14
|
+
}
|
|
15
|
+
export function resolveLaunchMethod(env = process.env, argv = process.argv) {
|
|
16
|
+
const npmExecPath = env.npm_execpath?.trim() ?? '';
|
|
17
|
+
const npmCommand = env.npm_command?.trim() ?? '';
|
|
18
|
+
if (isNpxInvocation(npmExecPath, npmCommand))
|
|
19
|
+
return 'npx';
|
|
20
|
+
if (isNpmScriptInvocation(npmCommand))
|
|
21
|
+
return 'npm';
|
|
22
|
+
const execPath = argv[0]?.trim() ?? '';
|
|
23
|
+
if (/node|tsx|bun/i.test(execPath))
|
|
24
|
+
return 'node';
|
|
25
|
+
return 'unknown';
|
|
26
|
+
}
|
|
27
|
+
export function getLaunchMethod() {
|
|
28
|
+
if (!cachedLaunchMethod) {
|
|
29
|
+
cachedLaunchMethod = resolveLaunchMethod();
|
|
30
|
+
}
|
|
31
|
+
return cachedLaunchMethod;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=launch-method.js.map
|