perplexity-user-mcp 0.8.36

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.
Files changed (125) hide show
  1. package/README.md +192 -0
  2. package/dist/attachments.d.ts +20 -0
  3. package/dist/attachments.mjs +43 -0
  4. package/dist/checks/browser.d.ts +100 -0
  5. package/dist/checks/browser.mjs +89 -0
  6. package/dist/checks/config.d.ts +91 -0
  7. package/dist/checks/config.mjs +88 -0
  8. package/dist/checks/ide.d.ts +89 -0
  9. package/dist/checks/ide.mjs +80 -0
  10. package/dist/checks/mcp.d.ts +61 -0
  11. package/dist/checks/mcp.mjs +56 -0
  12. package/dist/checks/native-deps.d.ts +131 -0
  13. package/dist/checks/native-deps.mjs +115 -0
  14. package/dist/checks/network.d.ts +71 -0
  15. package/dist/checks/network.mjs +70 -0
  16. package/dist/checks/probe.d.ts +93 -0
  17. package/dist/checks/probe.mjs +82 -0
  18. package/dist/checks/profiles.d.ts +99 -0
  19. package/dist/checks/profiles.mjs +90 -0
  20. package/dist/checks/runtime.d.ts +89 -0
  21. package/dist/checks/runtime.mjs +90 -0
  22. package/dist/checks/vault.d.ts +101 -0
  23. package/dist/checks/vault.mjs +90 -0
  24. package/dist/chunk-3B276PGG.mjs +115 -0
  25. package/dist/chunk-4UEJOM6W.mjs +9 -0
  26. package/dist/chunk-6EP2BLTV.mjs +205 -0
  27. package/dist/chunk-6YMQVLFX.mjs +146 -0
  28. package/dist/chunk-7JL36EBH.mjs +118 -0
  29. package/dist/chunk-DPGMKSSA.mjs +57 -0
  30. package/dist/chunk-H4BUAPPO.mjs +1950 -0
  31. package/dist/chunk-HMKLWVXB.mjs +109 -0
  32. package/dist/chunk-HTUAQRKH.mjs +125 -0
  33. package/dist/chunk-HU5B4FXS.mjs +139 -0
  34. package/dist/chunk-KCXM2M4B.mjs +1006 -0
  35. package/dist/chunk-LKJMLGFP.mjs +237 -0
  36. package/dist/chunk-LZPLNZ5U.mjs +67 -0
  37. package/dist/chunk-MTDFKNXX.mjs +19 -0
  38. package/dist/chunk-OF4DMAPJ.mjs +511 -0
  39. package/dist/chunk-PE23RMXY.mjs +43 -0
  40. package/dist/chunk-Q2VY4R5F.mjs +175 -0
  41. package/dist/chunk-S5VD7WTU.mjs +2540 -0
  42. package/dist/chunk-SVPRB62V.mjs +106 -0
  43. package/dist/chunk-TQLCLE4L.mjs +345 -0
  44. package/dist/chunk-U3DGFLXZ.mjs +43 -0
  45. package/dist/chunk-X45O6YD3.mjs +688 -0
  46. package/dist/chunk-XKSWCEGI.mjs +168 -0
  47. package/dist/chunk-Z7DAACGZ.mjs +534 -0
  48. package/dist/chunk-ZQFUZPLO.mjs +257 -0
  49. package/dist/cli.d.ts +952 -0
  50. package/dist/cli.mjs +827 -0
  51. package/dist/client.d.ts +355 -0
  52. package/dist/client.mjs +27 -0
  53. package/dist/cloud-sync.d-Cqt6y18U.d.ts +42 -0
  54. package/dist/cloud-sync.d.ts +42 -0
  55. package/dist/cloud-sync.mjs +17 -0
  56. package/dist/config.d.ts +186 -0
  57. package/dist/config.mjs +54 -0
  58. package/dist/daemon/attach.d.ts +36 -0
  59. package/dist/daemon/attach.mjs +25 -0
  60. package/dist/daemon/audit.d.ts +23 -0
  61. package/dist/daemon/audit.mjs +12 -0
  62. package/dist/daemon/client-http.d.ts +42 -0
  63. package/dist/daemon/client-http.mjs +29 -0
  64. package/dist/daemon/index.d.ts +14 -0
  65. package/dist/daemon/index.mjs +110 -0
  66. package/dist/daemon/install-tunnel.d.ts +46 -0
  67. package/dist/daemon/install-tunnel.mjs +14 -0
  68. package/dist/daemon/launcher.d.ts +163 -0
  69. package/dist/daemon/launcher.mjs +50 -0
  70. package/dist/daemon/lockfile.d.ts +29 -0
  71. package/dist/daemon/lockfile.mjs +18 -0
  72. package/dist/daemon/server.d.ts +159 -0
  73. package/dist/daemon/server.mjs +20 -0
  74. package/dist/daemon/token.d.ts +17 -0
  75. package/dist/daemon/token.mjs +17 -0
  76. package/dist/daemon/tunnel-providers/index.d.ts +330 -0
  77. package/dist/daemon/tunnel-providers/index.mjs +57 -0
  78. package/dist/daemon/tunnel.d.ts +23 -0
  79. package/dist/daemon/tunnel.mjs +9 -0
  80. package/dist/doctor-report.d.ts +24 -0
  81. package/dist/doctor-report.mjs +14 -0
  82. package/dist/doctor.d-CXmUqOXX.d.ts +43 -0
  83. package/dist/doctor.d.ts +44 -0
  84. package/dist/doctor.mjs +16 -0
  85. package/dist/export.d.ts +19 -0
  86. package/dist/export.mjs +15 -0
  87. package/dist/health-check.d.ts +108 -0
  88. package/dist/health-check.mjs +92 -0
  89. package/dist/history-store.d-BzjBF2m3.d.ts +65 -0
  90. package/dist/history-store.d.ts +65 -0
  91. package/dist/history-store.mjs +48 -0
  92. package/dist/impit-login-runner.d.ts +469 -0
  93. package/dist/impit-login-runner.mjs +685 -0
  94. package/dist/index.d.ts +159 -0
  95. package/dist/index.mjs +236 -0
  96. package/dist/login-runner.d.ts +333 -0
  97. package/dist/login-runner.mjs +320 -0
  98. package/dist/logout.d.ts +28 -0
  99. package/dist/logout.mjs +45 -0
  100. package/dist/manual-login-runner.d.ts +150 -0
  101. package/dist/manual-login-runner.mjs +146 -0
  102. package/dist/native-deps-BNThFHxa.d.ts +175 -0
  103. package/dist/native-deps-YNKXITRY.mjs +139 -0
  104. package/dist/profiles.d-DqS1oZWr.d.ts +41 -0
  105. package/dist/profiles.d.ts +41 -0
  106. package/dist/profiles.mjs +33 -0
  107. package/dist/redact.d.ts +159 -0
  108. package/dist/redact.mjs +11 -0
  109. package/dist/refresh.d.ts +118 -0
  110. package/dist/refresh.mjs +21 -0
  111. package/dist/reinit-watcher.d.ts +15 -0
  112. package/dist/reinit-watcher.mjs +8 -0
  113. package/dist/session-metadata-B9aV_n5g.d.ts +148 -0
  114. package/dist/tty-prompt.d.ts +44 -0
  115. package/dist/tty-prompt.mjs +39 -0
  116. package/dist/vault.d-BtRSLZiM.d.ts +8 -0
  117. package/dist/vault.d.ts +37 -0
  118. package/dist/vault.mjs +21 -0
  119. package/dist/viewer-detect.d-HWGnyFAA.d.ts +4 -0
  120. package/dist/viewer-detect.d.ts +4 -0
  121. package/dist/viewer-detect.mjs +37 -0
  122. package/dist/viewers.d-BGCK6sw6.d.ts +10 -0
  123. package/dist/viewers.d.ts +18 -0
  124. package/dist/viewers.mjs +122 -0
  125. package/package.json +152 -0
@@ -0,0 +1,37 @@
1
+ declare function encryptBlob(plaintext: Buffer, key: Buffer): Buffer;
2
+ declare function decryptBlob(blob: Buffer, key: Buffer): Buffer;
3
+ declare function __resetKeyCache(): void;
4
+ declare function getMasterKey(): Promise<Buffer>;
5
+
6
+ /**
7
+ * TEST SEAM — drop scrypt cost during tests by overriding the (logN, r, p)
8
+ * parameters used at write time. Reads always use the params embedded in the
9
+ * blob, regardless of any override.
10
+ *
11
+ * Cleared by `__resetKeyCache()` so tests do not leak state across files.
12
+ * MUST NOT be called from production code paths. The decrypt-time floor
13
+ * check (logN >= SCRYPT_LOGN_FLOOR) remains enforced unconditionally.
14
+ */
15
+ declare function __setKdfParamsForTest(params: { logN: number; r: number; p: number }): void;
16
+
17
+ /**
18
+ * Sibling of `getMasterKey()` introduced with the v2 vault format. Returns
19
+ * the unseal context WITHOUT prematurely deriving the HKDF key — for v2
20
+ * blobs, key derivation needs the salt embedded in each blob, so it can no
21
+ * longer happen up front. Cached just like `_keyCache`; cleared by
22
+ * `__resetKeyCache()`.
23
+ */
24
+ type UnsealMaterial =
25
+ | { kind: "key"; key: Buffer }
26
+ | { kind: "passphrase"; passphrase: string };
27
+
28
+ declare function getUnsealMaterial(): Promise<UnsealMaterial>;
29
+
30
+ declare class Vault {
31
+ get(profile: string, key: string): Promise<string | null>;
32
+ set(profile: string, key: string, value: string): Promise<void>;
33
+ delete(profile: string, key: string): Promise<void>;
34
+ deleteAll(profile: string): Promise<void>;
35
+ }
36
+
37
+ export { type UnsealMaterial, Vault, __resetKeyCache, __setKdfParamsForTest, decryptBlob, encryptBlob, getMasterKey, getUnsealMaterial };
package/dist/vault.mjs ADDED
@@ -0,0 +1,21 @@
1
+ import {
2
+ Vault,
3
+ __resetKeyCache,
4
+ __setKdfParamsForTest,
5
+ decryptBlob,
6
+ encryptBlob,
7
+ getMasterKey,
8
+ getUnsealMaterial
9
+ } from "./chunk-TQLCLE4L.mjs";
10
+ import "./chunk-MTDFKNXX.mjs";
11
+ import "./chunk-XKSWCEGI.mjs";
12
+ import "./chunk-4UEJOM6W.mjs";
13
+ export {
14
+ Vault,
15
+ __resetKeyCache,
16
+ __setKdfParamsForTest,
17
+ decryptBlob,
18
+ encryptBlob,
19
+ getMasterKey,
20
+ getUnsealMaterial
21
+ };
@@ -0,0 +1,4 @@
1
+ declare function detectViewer(id: string): Promise<boolean>;
2
+ declare function detectAllViewers(): Promise<Record<string, boolean>>;
3
+
4
+ export { detectAllViewers, detectViewer };
@@ -0,0 +1,4 @@
1
+ declare function detectViewer(id: string): Promise<boolean>;
2
+ declare function detectAllViewers(): Promise<Record<string, boolean>>;
3
+
4
+ export { detectAllViewers, detectViewer };
@@ -0,0 +1,37 @@
1
+ import "./chunk-4UEJOM6W.mjs";
2
+
3
+ // src/viewer-detect.js
4
+ import { promisify } from "util";
5
+ import { execFile as execFileCallback } from "child_process";
6
+ var execFile = promisify(execFileCallback);
7
+ var VIEWER_BINARIES = {
8
+ obsidian: process.platform === "win32" ? "obsidian.exe" : "obsidian",
9
+ typora: process.platform === "win32" ? "typora.exe" : "typora",
10
+ logseq: process.platform === "win32" ? "logseq.exe" : "logseq"
11
+ };
12
+ async function detectBinary(binary) {
13
+ const command = process.platform === "win32" ? "where" : "which";
14
+ try {
15
+ const { stdout } = await execFile(command, [binary]);
16
+ return stdout.trim().length > 0;
17
+ } catch {
18
+ return false;
19
+ }
20
+ }
21
+ async function detectViewer(id) {
22
+ const binary = VIEWER_BINARIES[id];
23
+ if (!binary) {
24
+ return false;
25
+ }
26
+ return detectBinary(binary);
27
+ }
28
+ async function detectAllViewers() {
29
+ const entries = await Promise.all(
30
+ Object.keys(VIEWER_BINARIES).map(async (id) => [id, await detectViewer(id)])
31
+ );
32
+ return Object.fromEntries(entries);
33
+ }
34
+ export {
35
+ detectAllViewers,
36
+ detectViewer
37
+ };
@@ -0,0 +1,10 @@
1
+ import { ExternalViewer } from '@perplexity-user-mcp/shared';
2
+
3
+ declare function listViewers(overrides?: ExternalViewer[]): ExternalViewer[];
4
+ declare function buildViewerUrl(options: {
5
+ viewer: ExternalViewer;
6
+ mdPath: string;
7
+ profile?: string;
8
+ }): string;
9
+
10
+ export { buildViewerUrl, listViewers };
@@ -0,0 +1,18 @@
1
+ import { ExternalViewer } from '@perplexity-user-mcp/shared';
2
+
3
+ declare function listViewers(overrides?: ExternalViewer[]): ExternalViewer[];
4
+ declare function loadViewerConfig(): ExternalViewer[];
5
+ declare function saveViewerConfig(viewer: ExternalViewer): ExternalViewer;
6
+ declare function substituteViewerTemplate(viewer: ExternalViewer, values: Record<string, string>): string;
7
+ declare function ensureObsidianBridge(options: {
8
+ mdPath: string;
9
+ viewer: ExternalViewer;
10
+ profile?: string;
11
+ }): string;
12
+ declare function buildViewerUrl(options: {
13
+ viewer: ExternalViewer;
14
+ mdPath: string;
15
+ profile?: string;
16
+ }): string;
17
+
18
+ export { buildViewerUrl, ensureObsidianBridge, listViewers, loadViewerConfig, saveViewerConfig, substituteViewerTemplate };
@@ -0,0 +1,122 @@
1
+ import {
2
+ getActiveName,
3
+ getConfigDir,
4
+ getProfilePaths
5
+ } from "./chunk-XKSWCEGI.mjs";
6
+ import "./chunk-4UEJOM6W.mjs";
7
+
8
+ // src/viewers.js
9
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "fs";
10
+ import { dirname, join, relative, resolve } from "path";
11
+ var BUILTIN_VIEWERS = [
12
+ {
13
+ id: "obsidian",
14
+ label: "Obsidian",
15
+ urlTemplate: "obsidian://open?vault={vaultName}&file={relPath}",
16
+ needsVaultBridge: true
17
+ },
18
+ {
19
+ id: "typora",
20
+ label: "Typora",
21
+ urlTemplate: "typora://{absPath}",
22
+ needsVaultBridge: false
23
+ },
24
+ {
25
+ id: "logseq",
26
+ label: "Logseq",
27
+ urlTemplate: "logseq://graph/{graphName}?page={filenameNoExt}",
28
+ needsVaultBridge: true
29
+ }
30
+ ];
31
+ function listViewers(overrides = []) {
32
+ const resolvedOverrides = overrides.length > 0 ? overrides : loadViewerConfig();
33
+ const byId = new Map(BUILTIN_VIEWERS.map((viewer) => [viewer.id, {
34
+ ...viewer,
35
+ detected: false,
36
+ enabled: false
37
+ }]));
38
+ for (const viewer of resolvedOverrides) {
39
+ byId.set(viewer.id, { ...byId.get(viewer.id), ...viewer });
40
+ }
41
+ return [...byId.values()];
42
+ }
43
+ function getConfigPath() {
44
+ return join(getConfigDir(), "config.json");
45
+ }
46
+ function readConfig() {
47
+ if (!existsSync(getConfigPath())) {
48
+ return {};
49
+ }
50
+ try {
51
+ return JSON.parse(readFileSync(getConfigPath(), "utf8"));
52
+ } catch {
53
+ return {};
54
+ }
55
+ }
56
+ function writeConfig(nextConfig) {
57
+ mkdirSync(dirname(getConfigPath()), { recursive: true });
58
+ const tempPath = `${getConfigPath()}.tmp`;
59
+ writeFileSync(tempPath, `${JSON.stringify(nextConfig, null, 2)}
60
+ `, "utf8");
61
+ renameSync(tempPath, getConfigPath());
62
+ }
63
+ function loadViewerConfig() {
64
+ const config = readConfig();
65
+ return Array.isArray(config.mdViewers) ? config.mdViewers : [];
66
+ }
67
+ function saveViewerConfig(viewer) {
68
+ const config = readConfig();
69
+ const current = Array.isArray(config.mdViewers) ? config.mdViewers : [];
70
+ const next = [...current.filter((item) => item?.id !== viewer.id), viewer];
71
+ writeConfig({ ...config, mdViewers: next });
72
+ return viewer;
73
+ }
74
+ function substituteViewerTemplate(viewer, values) {
75
+ const requiredSafe = ["absPath", "relPath", "vault", "vaultName", "filename", "filenameNoExt", "profile", "graphName"];
76
+ const safeValues = Object.fromEntries(requiredSafe.map((key) => [key, encodeURIComponent(String(values?.[key] ?? ""))]));
77
+ return viewer.urlTemplate.replace(/\{([a-zA-Z0-9]+)\}/g, (_, key) => safeValues[key] ?? "");
78
+ }
79
+ function ensureObsidianBridge(options) {
80
+ const { mdPath, viewer, profile = process.env.PERPLEXITY_PROFILE || getActiveName() || "default" } = options;
81
+ if (!viewer?.vaultPath || !viewer?.vaultName) {
82
+ throw new Error("Obsidian viewer requires vaultPath and vaultName.");
83
+ }
84
+ const historyDir = getProfilePaths(profile).history;
85
+ const relPath = relative(historyDir, mdPath);
86
+ if (relPath.startsWith("..")) {
87
+ throw new Error("Refusing to bridge a markdown file outside the profile history directory.");
88
+ }
89
+ const bridgePath = resolve(join(viewer.vaultPath, "Perplexity", profile, relPath));
90
+ mkdirSync(dirname(bridgePath), { recursive: true });
91
+ copyFileSync(mdPath, bridgePath);
92
+ return bridgePath;
93
+ }
94
+ function buildViewerUrl(options) {
95
+ const {
96
+ viewer,
97
+ mdPath,
98
+ profile = process.env.PERPLEXITY_PROFILE || getActiveName() || "default"
99
+ } = options;
100
+ const activePath = viewer.needsVaultBridge ? ensureObsidianBridge({ mdPath, viewer, profile }) : mdPath;
101
+ const relPath = relative(getConfigDir(), activePath).replace(/\\/g, "/");
102
+ const filename = activePath.split(/[\\/]/).pop() ?? "entry.md";
103
+ const filenameNoExt = filename.replace(/\.[^.]+$/, "");
104
+ return substituteViewerTemplate(viewer, {
105
+ absPath: activePath,
106
+ relPath,
107
+ vault: viewer.vaultPath ?? "",
108
+ vaultName: viewer.vaultName ?? "",
109
+ filename,
110
+ filenameNoExt,
111
+ profile,
112
+ graphName: viewer.graphName ?? ""
113
+ });
114
+ }
115
+ export {
116
+ buildViewerUrl,
117
+ ensureObsidianBridge,
118
+ listViewers,
119
+ loadViewerConfig,
120
+ saveViewerConfig,
121
+ substituteViewerTemplate
122
+ };
package/package.json ADDED
@@ -0,0 +1,152 @@
1
+ {
2
+ "name": "perplexity-user-mcp",
3
+ "version": "0.8.36",
4
+ "mcpName": "io.github.Automations-Project/perplexity-user-mcp",
5
+ "type": "module",
6
+ "description": "Perplexity AI MCP server — browser automation for search, reasoning, research, and compute. Not affiliated with Perplexity AI, Inc.",
7
+ "author": {
8
+ "name": "Nskha",
9
+ "url": "https://github.com/automations-Project"
10
+ },
11
+ "license": "MIT",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/Automations-Project/VSCode-Perplexity-MCP.git",
15
+ "directory": "packages/mcp-server"
16
+ },
17
+ "homepage": "https://github.com/Automations-Project/VSCode-Perplexity-MCP/tree/main/packages/mcp-server#readme",
18
+ "bugs": {
19
+ "url": "https://github.com/Automations-Project/VSCode-Perplexity-MCP/issues"
20
+ },
21
+ "funding": [
22
+ {
23
+ "type": "github",
24
+ "url": "https://github.com/sponsors/automations-Project"
25
+ },
26
+ {
27
+ "type": "individual",
28
+ "url": "https://github.com/Automations-Project/VSCode-Perplexity-MCP"
29
+ }
30
+ ],
31
+ "publishConfig": {
32
+ "access": "public",
33
+ "provenance": true
34
+ },
35
+ "engines": {
36
+ "node": ">=20"
37
+ },
38
+ "keywords": [
39
+ "perplexity",
40
+ "mcp",
41
+ "model-context-protocol",
42
+ "mcp-server",
43
+ "ai",
44
+ "search",
45
+ "research",
46
+ "reasoning",
47
+ "claude",
48
+ "cursor",
49
+ "windsurf",
50
+ "browser-automation",
51
+ "patchright"
52
+ ],
53
+ "bin": {
54
+ "perplexity-user-mcp": "./dist/cli.mjs"
55
+ },
56
+ "main": "dist/index.mjs",
57
+ "types": "dist/index.d.ts",
58
+ "exports": {
59
+ ".": {
60
+ "types": "./dist/index.d.ts",
61
+ "import": "./dist/index.mjs"
62
+ },
63
+ "./client": {
64
+ "types": "./dist/client.d.ts",
65
+ "import": "./dist/client.mjs"
66
+ },
67
+ "./history-store": {
68
+ "types": "./dist/history-store.d.ts",
69
+ "import": "./dist/history-store.mjs"
70
+ },
71
+ "./attachments": {
72
+ "types": "./dist/attachments.d.ts",
73
+ "import": "./dist/attachments.mjs"
74
+ },
75
+ "./export": {
76
+ "types": "./dist/export.d.ts",
77
+ "import": "./dist/export.mjs"
78
+ },
79
+ "./viewers": {
80
+ "types": "./dist/viewers.d.ts",
81
+ "import": "./dist/viewers.mjs"
82
+ },
83
+ "./viewer-detect": {
84
+ "types": "./dist/viewer-detect.d.ts",
85
+ "import": "./dist/viewer-detect.mjs"
86
+ },
87
+ "./config": {
88
+ "types": "./dist/config.d.ts",
89
+ "import": "./dist/config.mjs"
90
+ },
91
+ "./refresh": {
92
+ "types": "./dist/refresh.d.ts",
93
+ "import": "./dist/refresh.mjs"
94
+ },
95
+ "./logout": {
96
+ "types": "./dist/logout.d.ts",
97
+ "import": "./dist/logout.mjs"
98
+ },
99
+ "./profiles": {
100
+ "types": "./dist/profiles.d.ts",
101
+ "import": "./dist/profiles.mjs"
102
+ },
103
+ "./doctor": {
104
+ "types": "./dist/doctor.d.ts",
105
+ "import": "./dist/doctor.mjs"
106
+ },
107
+ "./redact": {
108
+ "types": "./dist/redact.d.ts",
109
+ "import": "./dist/redact.mjs"
110
+ },
111
+ "./daemon": {
112
+ "types": "./dist/daemon/index.d.ts",
113
+ "import": "./dist/daemon/index.mjs"
114
+ },
115
+ "./daemon/tunnel-providers": {
116
+ "types": "./dist/daemon/tunnel-providers/index.d.ts",
117
+ "import": "./dist/daemon/tunnel-providers/index.mjs"
118
+ }
119
+ },
120
+ "files": [
121
+ "dist/**/*.mjs",
122
+ "dist/**/*.d.ts",
123
+ "dist/**/*.js",
124
+ "README.md",
125
+ "LICENSE",
126
+ "CHANGELOG.md"
127
+ ],
128
+ "scripts": {
129
+ "build": "tsup",
130
+ "typecheck": "tsc -p tsconfig.json --noEmit",
131
+ "test": "cd ../.. && npx vitest run packages/mcp-server/test",
132
+ "test:coverage": "cd ../.. && npx vitest run --coverage packages/mcp-server/test"
133
+ },
134
+ "dependencies": {
135
+ "@modelcontextprotocol/sdk": "^1.29.0",
136
+ "@ngrok/ngrok": "^1.7.0",
137
+ "express": "^5.2.1",
138
+ "got-scraping": "^4.2.1",
139
+ "gray-matter": "^4.0.3",
140
+ "helmet": "^8.1.0",
141
+ "patchright": "^1.59.4",
142
+ "zod": "^3.24.0"
143
+ },
144
+ "optionalDependencies": {
145
+ "keytar": "^7.9.0"
146
+ },
147
+ "devDependencies": {
148
+ "@types/node": "^22.0.0",
149
+ "tsup": "^8.5.1",
150
+ "typescript": "^5.7.0"
151
+ }
152
+ }