perplexity-user-mcp 0.8.38 → 0.8.42

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 (63) hide show
  1. package/README.md +122 -9
  2. package/dist/checks/vault.d.ts +41 -0
  3. package/dist/checks/vault.mjs +23 -0
  4. package/dist/{chunk-Q2VY4R5F.mjs → chunk-2FPGJKCA.mjs} +2 -2
  5. package/dist/{chunk-ZQFUZPLO.mjs → chunk-452DK6OS.mjs} +2 -2
  6. package/dist/{chunk-OF4DMAPJ.mjs → chunk-B65IJQZJ.mjs} +1 -1
  7. package/dist/{chunk-H4BUAPPO.mjs → chunk-C3HPFFTD.mjs} +4 -4
  8. package/dist/{chunk-LZPLNZ5U.mjs → chunk-D254EFYB.mjs} +1 -1
  9. package/dist/{chunk-Z7DAACGZ.mjs → chunk-DQQISMYN.mjs} +2 -2
  10. package/dist/{chunk-3B276PGG.mjs → chunk-FKQ3HP4Q.mjs} +1 -1
  11. package/dist/{chunk-7JL36EBH.mjs → chunk-HNSPNCFH.mjs} +1 -1
  12. package/dist/{chunk-6EP2BLTV.mjs → chunk-KJFX2ZXR.mjs} +1 -1
  13. package/dist/{chunk-X45O6YD3.mjs → chunk-RK4EBZJ3.mjs} +28 -9
  14. package/dist/{chunk-TQLCLE4L.mjs → chunk-S677V2JU.mjs} +57 -12
  15. package/dist/{chunk-S5VD7WTU.mjs → chunk-T6ARJK2P.mjs} +6 -6
  16. package/dist/{chunk-HTUAQRKH.mjs → chunk-TDXETAQT.mjs} +1 -1
  17. package/dist/{chunk-LKJMLGFP.mjs → chunk-U7QPUNRH.mjs} +2 -2
  18. package/dist/{chunk-PE23RMXY.mjs → chunk-V4U3JM4R.mjs} +1 -1
  19. package/dist/chunk-WDIW33DA.mjs +77 -0
  20. package/dist/{chunk-KCXM2M4B.mjs → chunk-XTRJSV72.mjs} +1 -1
  21. package/dist/{chunk-YUGDOXIN.mjs → chunk-Z4OLYVB2.mjs} +28 -3
  22. package/dist/cli.d.ts +373 -8
  23. package/dist/cli.mjs +280 -9
  24. package/dist/client.mjs +6 -6
  25. package/dist/cloud-sync.mjs +8 -8
  26. package/dist/config.mjs +3 -3
  27. package/dist/daemon/attach.d.ts +7 -1
  28. package/dist/daemon/attach.mjs +19 -17
  29. package/dist/daemon/audit.mjs +2 -2
  30. package/dist/daemon/client-http.mjs +17 -17
  31. package/dist/daemon/index.mjs +18 -18
  32. package/dist/daemon/install-tunnel.mjs +2 -2
  33. package/dist/daemon/launcher.mjs +16 -16
  34. package/dist/daemon/lockfile.mjs +2 -2
  35. package/dist/daemon/server.mjs +11 -11
  36. package/dist/daemon/token.mjs +2 -2
  37. package/dist/daemon/tunnel-providers/index.mjs +3 -3
  38. package/dist/doctor.mjs +2 -2
  39. package/dist/export.mjs +4 -4
  40. package/dist/health-check.d.ts +1 -1
  41. package/dist/health-check.mjs +3 -3
  42. package/dist/history-store.mjs +2 -2
  43. package/dist/impit-login-runner.d.ts +1 -1
  44. package/dist/impit-login-runner.mjs +4 -4
  45. package/dist/index.mjs +57 -22
  46. package/dist/login-runner.d.ts +1 -1
  47. package/dist/login-runner.mjs +3 -3
  48. package/dist/logout.d.ts +1 -1
  49. package/dist/logout.mjs +2 -2
  50. package/dist/manual-login-runner.d.ts +1 -1
  51. package/dist/manual-login-runner.mjs +3 -3
  52. package/dist/{native-deps-YNKXITRY.mjs → native-deps-IE4B55EL.mjs} +4 -4
  53. package/dist/profiles.mjs +1 -1
  54. package/dist/refresh.mjs +4 -4
  55. package/dist/reinit-watcher.d.ts +12 -1
  56. package/dist/reinit-watcher.mjs +4 -2
  57. package/dist/vault.d-BSJWDLhp.d.ts +37 -0
  58. package/dist/vault.mjs +4 -2
  59. package/dist/viewers.mjs +1 -1
  60. package/package.json +2 -2
  61. package/dist/chunk-U3DGFLXZ.mjs +0 -43
  62. package/dist/vault.d-BtRSLZiM.d.ts +0 -8
  63. /package/dist/{chunk-XKSWCEGI.mjs → chunk-HJIXH6CL.mjs} +0 -0
package/dist/cli.mjs CHANGED
@@ -63,6 +63,7 @@ var KNOWN_COMMANDS = /* @__PURE__ */ new Set([
63
63
  "status",
64
64
  "doctor",
65
65
  "install-browser",
66
+ "setup-vault",
66
67
  "install-speed-boost",
67
68
  "uninstall-speed-boost",
68
69
  "speed-boost-status",
@@ -97,6 +98,215 @@ function normalizeExportFormat(value) {
97
98
  if (value === "markdown" || value === "pdf" || value === "docx") return value;
98
99
  return null;
99
100
  }
101
+ async function probeVaultState({ profile } = {}) {
102
+ let keychainAvailable = false;
103
+ let keychainHasKey = false;
104
+ try {
105
+ const mod = await import("keytar");
106
+ const keytar = mod.default ?? mod;
107
+ if (keytar && typeof keytar.getPassword === "function") {
108
+ keychainAvailable = true;
109
+ try {
110
+ const hex = await keytar.getPassword("perplexity-user-mcp", "vault-master-key");
111
+ keychainHasKey = !!hex;
112
+ } catch {
113
+ keychainHasKey = false;
114
+ }
115
+ }
116
+ } catch {
117
+ keychainAvailable = false;
118
+ }
119
+ const envPassphraseSet = !!process.env.PERPLEXITY_VAULT_PASSPHRASE;
120
+ const hasTty = process.stdin?.isTTY === true && process.env.PERPLEXITY_MCP_STDIO !== "1";
121
+ let vaultExists = false;
122
+ let vaultDecryptsOk = null;
123
+ let decryptError = null;
124
+ if (profile) {
125
+ try {
126
+ const { getProfilePaths } = await import("./profiles.mjs");
127
+ const { existsSync: existsSync2 } = await import("fs");
128
+ vaultExists = existsSync2(getProfilePaths(profile).vault);
129
+ if (vaultExists && (keychainAvailable || envPassphraseSet)) {
130
+ const { Vault, __resetKeyCache } = await import("./vault.mjs");
131
+ __resetKeyCache();
132
+ try {
133
+ await new Vault().get(profile, "cookies");
134
+ vaultDecryptsOk = true;
135
+ } catch (err) {
136
+ vaultDecryptsOk = false;
137
+ decryptError = err instanceof Error ? err.message : String(err);
138
+ }
139
+ }
140
+ } catch (err) {
141
+ decryptError = err instanceof Error ? err.message : String(err);
142
+ }
143
+ }
144
+ return {
145
+ platform: process.platform,
146
+ keychainAvailable,
147
+ keychainHasKey,
148
+ envPassphraseSet,
149
+ hasTty,
150
+ vaultExists,
151
+ vaultDecryptsOk,
152
+ decryptError
153
+ };
154
+ }
155
+ async function checkVaultUnseal() {
156
+ const state = await probeVaultState();
157
+ if (state.keychainAvailable || state.envPassphraseSet || state.hasTty) {
158
+ return {
159
+ ok: true,
160
+ hasKeychain: state.keychainAvailable,
161
+ envPass: state.envPassphraseSet,
162
+ hasTty: state.hasTty
163
+ };
164
+ }
165
+ const isLinux = state.platform === "linux";
166
+ const isMac = state.platform === "darwin";
167
+ const isWin = state.platform === "win32";
168
+ const hint = isLinux ? "Install libsecret + gnome-keyring (Debian/Ubuntu: `sudo apt install libsecret-1-0 gnome-keyring`; Fedora: `sudo dnf install libsecret gnome-keyring`), OR run `npx perplexity-user-mcp setup-vault` to generate a passphrase and get persistence snippets for your shell / MCP-client config." : isMac ? "Keychain Access should be available on macOS \u2014 keytar usually loads here. If you still see this, run `npx perplexity-user-mcp setup-vault` for a generated passphrase + persistence snippets." : isWin ? "Credential Manager is always available on Windows \u2014 keytar usually loads here. If you still see this, run `npx perplexity-user-mcp setup-vault` for a generated passphrase + persistence snippets." : "Run `npx perplexity-user-mcp setup-vault` for a generated passphrase + persistence snippets.";
169
+ return {
170
+ ok: false,
171
+ hasKeychain: false,
172
+ envPass: false,
173
+ hasTty: false,
174
+ reason: "no_unseal_material",
175
+ hint
176
+ };
177
+ }
178
+ async function generatePassphrase() {
179
+ const { randomBytes } = await import("crypto");
180
+ return randomBytes(32).toString("base64url");
181
+ }
182
+ function buildPersistenceSnippets(passphrase) {
183
+ const platform = process.platform;
184
+ const snippets = [];
185
+ snippets.push({
186
+ title: "MCP client env block (preferred \u2014 scoped to one client only)",
187
+ detail: "Edit your MCP client's config (Cursor: ~/.cursor/mcp.json, Claude Desktop: claude_desktop_config.json, Codex CLI: ~/.codex/config.toml, etc.). Add an `env` field next to `command`/`args`:",
188
+ code: `{
189
+ "mcpServers": {
190
+ "Perplexity": {
191
+ "command": "npx",
192
+ "args": ["-y", "perplexity-user-mcp"],
193
+ "env": {
194
+ "PERPLEXITY_VAULT_PASSPHRASE": "${passphrase}"
195
+ }
196
+ }
197
+ }
198
+ }`
199
+ });
200
+ if (platform === "win32") {
201
+ snippets.push({
202
+ title: "Windows \u2014 PowerShell user environment (persistent)",
203
+ detail: "Sets the variable for your user account; persists across reboots. Open PowerShell and run:",
204
+ code: `[Environment]::SetEnvironmentVariable("PERPLEXITY_VAULT_PASSPHRASE", "${passphrase}", "User")`
205
+ });
206
+ snippets.push({
207
+ title: "Windows \u2014 cmd.exe (persistent)",
208
+ detail: "Equivalent for cmd.exe users:",
209
+ code: `setx PERPLEXITY_VAULT_PASSPHRASE "${passphrase}"`
210
+ });
211
+ } else if (platform === "darwin") {
212
+ snippets.push({
213
+ title: "macOS \u2014 zsh (default since Catalina)",
214
+ detail: "Append to ~/.zshrc and restart your terminal:",
215
+ code: `echo 'export PERPLEXITY_VAULT_PASSPHRASE='\\''${passphrase}'\\''' >> ~/.zshrc`
216
+ });
217
+ snippets.push({
218
+ title: "macOS \u2014 bash (legacy)",
219
+ detail: "If you use bash instead, append to ~/.bash_profile:",
220
+ code: `echo 'export PERPLEXITY_VAULT_PASSPHRASE='\\''${passphrase}'\\''' >> ~/.bash_profile`
221
+ });
222
+ } else {
223
+ snippets.push({
224
+ title: "Linux \u2014 bash",
225
+ detail: "Append to ~/.bashrc and restart your terminal (or `source ~/.bashrc`):",
226
+ code: `echo 'export PERPLEXITY_VAULT_PASSPHRASE='\\''${passphrase}'\\''' >> ~/.bashrc`
227
+ });
228
+ snippets.push({
229
+ title: "Linux \u2014 zsh",
230
+ detail: "If you use zsh, append to ~/.zshrc:",
231
+ code: `echo 'export PERPLEXITY_VAULT_PASSPHRASE='\\''${passphrase}'\\''' >> ~/.zshrc`
232
+ });
233
+ snippets.push({
234
+ title: "Linux \u2014 systemd unit (for daemon deployments)",
235
+ detail: "If you run perplexity-user-mcp as a systemd service, add to the [Service] block:",
236
+ code: `Environment=PERPLEXITY_VAULT_PASSPHRASE=${passphrase}`
237
+ });
238
+ }
239
+ return snippets;
240
+ }
241
+ function renderSetupVaultReport({ state, recommendation, passphrase, snippets }) {
242
+ const lines = [];
243
+ const tick = "\u2713";
244
+ const cross = "\u2717";
245
+ const warn = "!";
246
+ lines.push("Vault setup status:");
247
+ lines.push(` ${state.keychainAvailable ? tick : cross} OS keychain ${state.keychainAvailable ? "available" : "unavailable"}${state.keychainHasKey ? " (master key persisted)" : state.keychainAvailable ? " (no master key yet \u2014 will be generated on first login)" : ""}`);
248
+ lines.push(` ${state.envPassphraseSet ? tick : cross} PERPLEXITY_VAULT_PASSPHRASE ${state.envPassphraseSet ? "is set" : "is not set"}`);
249
+ if (state.vaultExists) {
250
+ if (state.vaultDecryptsOk === true) {
251
+ lines.push(` ${tick} vault.enc decrypts cleanly with the active unseal material`);
252
+ } else if (state.vaultDecryptsOk === false) {
253
+ lines.push(` ${cross} vault.enc cannot be decrypted \u2014 ${state.decryptError ?? "unknown error"}`);
254
+ }
255
+ }
256
+ if (state.keychainAvailable && state.envPassphraseSet) {
257
+ lines.push(` ${warn} both keychain and env var are set \u2014 keychain wins at runtime; the env var is a fallback`);
258
+ }
259
+ lines.push("");
260
+ lines.push(`Recommendation: ${recommendation.message}`);
261
+ if (passphrase) {
262
+ lines.push("");
263
+ lines.push("Generated passphrase (256 bits, base64url):");
264
+ lines.push(` ${passphrase}`);
265
+ lines.push("");
266
+ lines.push("\u26A0 Save this somewhere safe \u2014 losing it means losing access to vaults written under it.");
267
+ lines.push("");
268
+ lines.push("Pick ONE persistence method below:");
269
+ snippets.forEach((s, i) => {
270
+ lines.push("");
271
+ lines.push(`${i + 1}. ${s.title}`);
272
+ if (s.detail) lines.push(` ${s.detail}`);
273
+ lines.push("");
274
+ const indent = " ";
275
+ lines.push(s.code.split("\n").map((l) => indent + l).join("\n"));
276
+ });
277
+ lines.push("");
278
+ lines.push("After applying ONE of those, run `npx perplexity-user-mcp doctor` to verify the unseal-verify check passes.");
279
+ }
280
+ return lines.join("\n");
281
+ }
282
+ function recommendVaultSetup(state) {
283
+ if (state.vaultExists && state.vaultDecryptsOk === false) {
284
+ return {
285
+ status: "decrypt_broken",
286
+ message: "Existing vault.enc cannot be decrypted with any available unseal material. The blob was likely written under a since-rotated keychain key or PERPLEXITY_VAULT_PASSPHRASE. Run `npx perplexity-user-mcp logout --purge --profile <name>` and log in again to write a fresh vault. (v0.8.40+ self-heals this on the next login by quarantining the bad blob.)",
287
+ generatePassphrase: false
288
+ };
289
+ }
290
+ if (state.keychainAvailable) {
291
+ return {
292
+ status: "ok_keychain",
293
+ message: state.keychainHasKey ? "OS keychain holds the master key \u2014 nothing to do." : "OS keychain is available; the master key will be generated and persisted there on your first login. Nothing to do.",
294
+ generatePassphrase: false
295
+ };
296
+ }
297
+ if (state.envPassphraseSet) {
298
+ return {
299
+ status: "ok_envvar",
300
+ message: "PERPLEXITY_VAULT_PASSPHRASE is set; the vault will use it. (For better UX, install an OS keychain so the env var becomes optional \u2014 see https://github.com/Automations-Project/VSCode-Perplexity-MCP for platform docs.)",
301
+ generatePassphrase: false
302
+ };
303
+ }
304
+ return {
305
+ status: "setup_needed",
306
+ message: "No keychain available and no PERPLEXITY_VAULT_PASSPHRASE set. Generating a strong passphrase and showing persistence snippets below.",
307
+ generatePassphrase: true
308
+ };
309
+ }
100
310
  async function openTarget(target) {
101
311
  if (process.platform === "win32") {
102
312
  const escaped = String(target).replace(/'/g, "''");
@@ -192,12 +402,27 @@ Run --help for usage.` };
192
402
  const { attachToDaemon } = await import("./daemon/attach.mjs");
193
403
  const ensureTimeoutRaw = flags["ensure-timeout-ms"];
194
404
  const ensureTimeoutMs = typeof ensureTimeoutRaw === "string" && /^\d+$/.test(ensureTimeoutRaw) ? Number(ensureTimeoutRaw) : void 0;
195
- await attachToDaemon({
196
- configDir: process.env.PERPLEXITY_CONFIG_DIR,
197
- clientId: "daemon-attach-cli",
198
- fallbackStdio: !!flags["fallback-stdio"],
199
- ensureTimeoutMs
200
- });
405
+ try {
406
+ await attachToDaemon({
407
+ configDir: process.env.PERPLEXITY_CONFIG_DIR,
408
+ clientId: "daemon-attach-cli",
409
+ fallbackStdio: !!flags["fallback-stdio"],
410
+ ensureTimeoutMs
411
+ });
412
+ } catch (err) {
413
+ if (err && err.code === "DAEMON_UNREACHABLE") {
414
+ let stderr = "Perplexity MCP: cannot reach the extension-managed daemon.\n";
415
+ const remediation = Array.isArray(err.remediation) ? err.remediation : [];
416
+ for (const line of remediation) {
417
+ stderr += " \u2022 " + line + "\n";
418
+ }
419
+ if (err.cause && err.cause.message) {
420
+ stderr += "Underlying error: " + err.cause.message + "\n";
421
+ }
422
+ return { code: 2, stdout: "", stderr };
423
+ }
424
+ throw err;
425
+ }
201
426
  return { code: 0, stdout: "", stderr: "" };
202
427
  }
203
428
  if (command === "daemon:install-tunnel") {
@@ -410,9 +635,40 @@ Config written to ${config.configPath}`;
410
635
  const body = flags.json ? JSON.stringify({ ok: true, active, profiles }) : profiles.length === 0 ? "No profiles yet. Run `add-account` to create one." : profiles.map((p) => `${p.name === active ? "* " : " "}${p.name} [${p.tier ?? "?"}] mode=${p.loginMode ?? "?"} lastLogin=${p.lastLogin ?? "never"}`).join("\n");
411
636
  return { code: 0, stdout: body + "\n", stderr: "" };
412
637
  }
638
+ if (command === "setup-vault") {
639
+ const profile = flags.profile ?? (await import("./profiles.mjs")).getActiveName() ?? null;
640
+ const state = await probeVaultState({ profile });
641
+ const recommendation = recommendVaultSetup(state);
642
+ let passphrase = null;
643
+ let snippets = [];
644
+ if (recommendation.generatePassphrase && !flags["probe-only"]) {
645
+ passphrase = await generatePassphrase();
646
+ snippets = buildPersistenceSnippets(passphrase);
647
+ }
648
+ if (flags.json) {
649
+ const body = JSON.stringify({
650
+ ok: true,
651
+ state,
652
+ recommendation: { status: recommendation.status, message: recommendation.message },
653
+ passphrase: passphrase ?? null,
654
+ snippets: snippets.map((s) => ({ title: s.title, detail: s.detail, code: s.code }))
655
+ });
656
+ return { code: 0, stdout: body + "\n", stderr: "" };
657
+ }
658
+ const report = renderSetupVaultReport({ state, recommendation, passphrase, snippets });
659
+ return { code: 0, stdout: report + "\n", stderr: "" };
660
+ }
413
661
  if (command === "add-account") {
414
662
  const name = flags.name ?? (await import("./profiles.mjs")).suggestNextDefaultName();
415
663
  const mode = flags.mode ?? "manual";
664
+ if (!flags["skip-vault-check"]) {
665
+ const unseal = await checkVaultUnseal();
666
+ if (!unseal.ok) {
667
+ const msg2 = `No vault unseal path configured. ${unseal.hint}`;
668
+ const body = flags.json ? JSON.stringify({ ok: false, reason: unseal.reason, hint: unseal.hint }) : "";
669
+ return { code: 1, stdout: body + (body ? "\n" : ""), stderr: msg2 + "\n" };
670
+ }
671
+ }
416
672
  try {
417
673
  const { createProfile } = await import("./profiles.mjs");
418
674
  const profile = createProfile(name, { loginMode: mode });
@@ -461,6 +717,14 @@ Config written to ${config.configPath}`;
461
717
  const { fork } = await import("child_process");
462
718
  const mode = flags.mode ?? "manual";
463
719
  const profile = flags.profile ?? (await import("./profiles.mjs")).getActiveName() ?? "default";
720
+ if (!flags["plain-cookies"] && !flags["skip-vault-check"]) {
721
+ const unseal = await checkVaultUnseal();
722
+ if (!unseal.ok) {
723
+ const msg2 = `No vault unseal path configured for profile '${profile}'. ${unseal.hint}`;
724
+ const body = flags.json ? JSON.stringify({ ok: false, reason: unseal.reason, hint: unseal.hint, profile }) : "";
725
+ return { code: 1, stdout: body + (body ? "\n" : ""), stderr: msg2 + "\n" };
726
+ }
727
+ }
464
728
  const env = { ...process.env, PERPLEXITY_PROFILE: profile };
465
729
  if (mode === "auto") {
466
730
  if (!flags.email) return { code: 1, stdout: "", stderr: "`--email` required for --mode auto.\n" };
@@ -512,7 +776,7 @@ Config written to ${config.configPath}`;
512
776
  return { code: browserResult.code, stdout: (flags.json ? browserResult.last : `login finished (${browserResult.code})`) + "\n", stderr: "" };
513
777
  }
514
778
  if (command === "install-speed-boost") {
515
- const { installImpit, getImpitStatus } = await import("./native-deps-YNKXITRY.mjs");
779
+ const { installImpit, getImpitStatus } = await import("./native-deps-IE4B55EL.mjs");
516
780
  const before = getImpitStatus();
517
781
  if (before.installed && !flags.force) {
518
782
  const msg2 = flags.json ? JSON.stringify({ ok: true, alreadyInstalled: true, version: before.version, runtimeDir: before.runtimeDir }) : `Speed Boost (impit ${before.version ?? "?"}) already installed at ${before.runtimeDir}.
@@ -533,7 +797,7 @@ All impit-eligible tools (sync, hydrate, retrieve, export, models, login) will u
533
797
  return { code: 0, stdout: out + "\n", stderr: "" };
534
798
  }
535
799
  if (command === "uninstall-speed-boost") {
536
- const { uninstallImpit, getImpitStatus } = await import("./native-deps-YNKXITRY.mjs");
800
+ const { uninstallImpit, getImpitStatus } = await import("./native-deps-IE4B55EL.mjs");
537
801
  const before = getImpitStatus();
538
802
  const log = (line) => process.stderr.write(`[speed-boost] ${line}
539
803
  `);
@@ -547,7 +811,7 @@ All impit-eligible tools (sync, hydrate, retrieve, export, models, login) will u
547
811
  return { code: 0, stdout: out + "\n", stderr: "" };
548
812
  }
549
813
  if (command === "speed-boost-status") {
550
- const { getImpitStatus } = await import("./native-deps-YNKXITRY.mjs");
814
+ const { getImpitStatus } = await import("./native-deps-IE4B55EL.mjs");
551
815
  const status = getImpitStatus();
552
816
  if (flags.json) {
553
817
  return { code: 0, stdout: JSON.stringify(status) + "\n", stderr: "" };
@@ -758,6 +1022,13 @@ Usage:
758
1022
  npx perplexity-user-mcp status [--profile X] [--all]
759
1023
  npx perplexity-user-mcp doctor [--profile X] [--probe] [--all] [--report]
760
1024
  npx perplexity-user-mcp install-browser
1025
+ npx perplexity-user-mcp setup-vault [--profile X] [--json] [--probe-only]
1026
+ Probe the vault unseal chain (OS keychain / PERPLEXITY_VAULT_PASSPHRASE)
1027
+ and, when neither is configured, generate a strong passphrase and print
1028
+ cross-platform persistence snippets (PowerShell / setx / zsh / bash /
1029
+ systemd / MCP-client env block). Read-only \u2014 never writes any file.
1030
+ Cross-platform: Windows, macOS, Linux. Add --probe-only to skip
1031
+ passphrase generation and just report state.
761
1032
  npx perplexity-user-mcp install-speed-boost [--force] [--json]
762
1033
  npx perplexity-user-mcp uninstall-speed-boost [--json]
763
1034
  npx perplexity-user-mcp speed-boost-status [--json]
package/dist/client.mjs CHANGED
@@ -7,13 +7,13 @@ import {
7
7
  readCachedAccountInfoFromDisk,
8
8
  retrieveThreadViaImpit,
9
9
  searchPerplexityViaImpit
10
- } from "./chunk-H4BUAPPO.mjs";
11
- import "./chunk-Z7DAACGZ.mjs";
12
- import "./chunk-LZPLNZ5U.mjs";
13
- import "./chunk-LKJMLGFP.mjs";
14
- import "./chunk-TQLCLE4L.mjs";
10
+ } from "./chunk-C3HPFFTD.mjs";
11
+ import "./chunk-DQQISMYN.mjs";
12
+ import "./chunk-D254EFYB.mjs";
13
+ import "./chunk-U7QPUNRH.mjs";
14
+ import "./chunk-S677V2JU.mjs";
15
15
  import "./chunk-MTDFKNXX.mjs";
16
- import "./chunk-XKSWCEGI.mjs";
16
+ import "./chunk-HJIXH6CL.mjs";
17
17
  import "./chunk-4UEJOM6W.mjs";
18
18
  export {
19
19
  PerplexityClient,
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  hydrateCloudHistoryEntry,
3
3
  syncCloudHistory
4
- } from "./chunk-Q2VY4R5F.mjs";
5
- import "./chunk-H4BUAPPO.mjs";
6
- import "./chunk-Z7DAACGZ.mjs";
7
- import "./chunk-OF4DMAPJ.mjs";
8
- import "./chunk-LZPLNZ5U.mjs";
9
- import "./chunk-LKJMLGFP.mjs";
10
- import "./chunk-TQLCLE4L.mjs";
4
+ } from "./chunk-2FPGJKCA.mjs";
5
+ import "./chunk-C3HPFFTD.mjs";
6
+ import "./chunk-DQQISMYN.mjs";
7
+ import "./chunk-B65IJQZJ.mjs";
8
+ import "./chunk-D254EFYB.mjs";
9
+ import "./chunk-U7QPUNRH.mjs";
10
+ import "./chunk-S677V2JU.mjs";
11
11
  import "./chunk-MTDFKNXX.mjs";
12
- import "./chunk-XKSWCEGI.mjs";
12
+ import "./chunk-HJIXH6CL.mjs";
13
13
  import "./chunk-4UEJOM6W.mjs";
14
14
  export {
15
15
  hydrateCloudHistoryEntry,
package/dist/config.mjs CHANGED
@@ -22,10 +22,10 @@ import {
22
22
  getSavedCookies,
23
23
  hasStoredLogin,
24
24
  resolveBrowserExecutable
25
- } from "./chunk-LKJMLGFP.mjs";
26
- import "./chunk-TQLCLE4L.mjs";
25
+ } from "./chunk-U7QPUNRH.mjs";
26
+ import "./chunk-S677V2JU.mjs";
27
27
  import "./chunk-MTDFKNXX.mjs";
28
- import "./chunk-XKSWCEGI.mjs";
28
+ import "./chunk-HJIXH6CL.mjs";
29
29
  import "./chunk-4UEJOM6W.mjs";
30
30
  export {
31
31
  ASI_ACCESS_ENDPOINT,
@@ -5,6 +5,12 @@ import '../config.js';
5
5
  import 'patchright';
6
6
  import './lockfile.js';
7
7
 
8
+ declare class DaemonAttachError extends Error {
9
+ readonly code = "DAEMON_UNREACHABLE";
10
+ readonly remediation: readonly string[];
11
+ readonly cause?: unknown;
12
+ constructor(message: string, remediation: readonly string[], cause?: unknown);
13
+ }
8
14
  interface AttachToDaemonOptions {
9
15
  configDir?: string;
10
16
  stdin?: Readable;
@@ -33,4 +39,4 @@ interface AttachToDaemonOptions {
33
39
  }
34
40
  declare function attachToDaemon(options?: AttachToDaemonOptions): Promise<void>;
35
41
 
36
- export { type AttachToDaemonOptions, attachToDaemon };
42
+ export { type AttachToDaemonOptions, DaemonAttachError, attachToDaemon };
@@ -1,25 +1,27 @@
1
1
  import {
2
+ DaemonAttachError,
2
3
  attachToDaemon
3
- } from "../chunk-YUGDOXIN.mjs";
4
- import "../chunk-X45O6YD3.mjs";
5
- import "../chunk-KCXM2M4B.mjs";
4
+ } from "../chunk-Z4OLYVB2.mjs";
5
+ import "../chunk-RK4EBZJ3.mjs";
6
+ import "../chunk-XTRJSV72.mjs";
6
7
  import "../chunk-6YMQVLFX.mjs";
7
- import "../chunk-3B276PGG.mjs";
8
- import "../chunk-6EP2BLTV.mjs";
9
- import "../chunk-S5VD7WTU.mjs";
10
- import "../chunk-PE23RMXY.mjs";
11
- import "../chunk-HTUAQRKH.mjs";
12
- import "../chunk-U3DGFLXZ.mjs";
13
- import "../chunk-Q2VY4R5F.mjs";
14
- import "../chunk-H4BUAPPO.mjs";
15
- import "../chunk-Z7DAACGZ.mjs";
16
- import "../chunk-OF4DMAPJ.mjs";
17
- import "../chunk-LZPLNZ5U.mjs";
18
- import "../chunk-LKJMLGFP.mjs";
19
- import "../chunk-TQLCLE4L.mjs";
8
+ import "../chunk-FKQ3HP4Q.mjs";
9
+ import "../chunk-KJFX2ZXR.mjs";
10
+ import "../chunk-T6ARJK2P.mjs";
11
+ import "../chunk-V4U3JM4R.mjs";
12
+ import "../chunk-TDXETAQT.mjs";
13
+ import "../chunk-WDIW33DA.mjs";
14
+ import "../chunk-2FPGJKCA.mjs";
15
+ import "../chunk-C3HPFFTD.mjs";
16
+ import "../chunk-DQQISMYN.mjs";
17
+ import "../chunk-B65IJQZJ.mjs";
18
+ import "../chunk-D254EFYB.mjs";
19
+ import "../chunk-U7QPUNRH.mjs";
20
+ import "../chunk-S677V2JU.mjs";
20
21
  import "../chunk-MTDFKNXX.mjs";
21
- import "../chunk-XKSWCEGI.mjs";
22
+ import "../chunk-HJIXH6CL.mjs";
22
23
  import "../chunk-4UEJOM6W.mjs";
23
24
  export {
25
+ DaemonAttachError,
24
26
  attachToDaemon
25
27
  };
@@ -2,8 +2,8 @@ import {
2
2
  appendAuditEntry,
3
3
  getAuditLogPath,
4
4
  readAuditTail
5
- } from "../chunk-PE23RMXY.mjs";
6
- import "../chunk-XKSWCEGI.mjs";
5
+ } from "../chunk-V4U3JM4R.mjs";
6
+ import "../chunk-HJIXH6CL.mjs";
7
7
  import "../chunk-4UEJOM6W.mjs";
8
8
  export {
9
9
  appendAuditEntry,
@@ -2,25 +2,25 @@ import {
2
2
  exportHistoryViaDaemon,
3
3
  hydrateCloudHistoryEntryViaDaemon,
4
4
  syncCloudHistoryViaDaemon
5
- } from "../chunk-ZQFUZPLO.mjs";
6
- import "../chunk-X45O6YD3.mjs";
7
- import "../chunk-KCXM2M4B.mjs";
5
+ } from "../chunk-452DK6OS.mjs";
6
+ import "../chunk-RK4EBZJ3.mjs";
7
+ import "../chunk-XTRJSV72.mjs";
8
8
  import "../chunk-6YMQVLFX.mjs";
9
- import "../chunk-3B276PGG.mjs";
10
- import "../chunk-6EP2BLTV.mjs";
11
- import "../chunk-S5VD7WTU.mjs";
12
- import "../chunk-PE23RMXY.mjs";
13
- import "../chunk-HTUAQRKH.mjs";
14
- import "../chunk-U3DGFLXZ.mjs";
15
- import "../chunk-Q2VY4R5F.mjs";
16
- import "../chunk-H4BUAPPO.mjs";
17
- import "../chunk-Z7DAACGZ.mjs";
18
- import "../chunk-OF4DMAPJ.mjs";
19
- import "../chunk-LZPLNZ5U.mjs";
20
- import "../chunk-LKJMLGFP.mjs";
21
- import "../chunk-TQLCLE4L.mjs";
9
+ import "../chunk-FKQ3HP4Q.mjs";
10
+ import "../chunk-KJFX2ZXR.mjs";
11
+ import "../chunk-T6ARJK2P.mjs";
12
+ import "../chunk-V4U3JM4R.mjs";
13
+ import "../chunk-TDXETAQT.mjs";
14
+ import "../chunk-WDIW33DA.mjs";
15
+ import "../chunk-2FPGJKCA.mjs";
16
+ import "../chunk-C3HPFFTD.mjs";
17
+ import "../chunk-DQQISMYN.mjs";
18
+ import "../chunk-B65IJQZJ.mjs";
19
+ import "../chunk-D254EFYB.mjs";
20
+ import "../chunk-U7QPUNRH.mjs";
21
+ import "../chunk-S677V2JU.mjs";
22
22
  import "../chunk-MTDFKNXX.mjs";
23
- import "../chunk-XKSWCEGI.mjs";
23
+ import "../chunk-HJIXH6CL.mjs";
24
24
  import "../chunk-4UEJOM6W.mjs";
25
25
  export {
26
26
  exportHistoryViaDaemon,
@@ -2,10 +2,10 @@ import {
2
2
  exportHistoryViaDaemon,
3
3
  hydrateCloudHistoryEntryViaDaemon,
4
4
  syncCloudHistoryViaDaemon
5
- } from "../chunk-ZQFUZPLO.mjs";
5
+ } from "../chunk-452DK6OS.mjs";
6
6
  import {
7
7
  attachToDaemon
8
- } from "../chunk-YUGDOXIN.mjs";
8
+ } from "../chunk-Z4OLYVB2.mjs";
9
9
  import {
10
10
  disableDaemonTunnel,
11
11
  enableDaemonTunnel,
@@ -21,8 +21,8 @@ import {
21
21
  rotateDaemonToken,
22
22
  startDaemon,
23
23
  stopDaemon
24
- } from "../chunk-X45O6YD3.mjs";
25
- import "../chunk-KCXM2M4B.mjs";
24
+ } from "../chunk-RK4EBZJ3.mjs";
25
+ import "../chunk-XTRJSV72.mjs";
26
26
  import {
27
27
  extractTunnelUrl,
28
28
  startTunnel
@@ -32,7 +32,7 @@ import {
32
32
  getTunnelBinaryPath,
33
33
  installCloudflared,
34
34
  resolvePinnedAssetKey
35
- } from "../chunk-3B276PGG.mjs";
35
+ } from "../chunk-FKQ3HP4Q.mjs";
36
36
  import {
37
37
  acquire,
38
38
  getLockfilePath,
@@ -40,32 +40,32 @@ import {
40
40
  read,
41
41
  release,
42
42
  replace
43
- } from "../chunk-6EP2BLTV.mjs";
43
+ } from "../chunk-KJFX2ZXR.mjs";
44
44
  import {
45
45
  startDaemonServer
46
- } from "../chunk-S5VD7WTU.mjs";
46
+ } from "../chunk-T6ARJK2P.mjs";
47
47
  import {
48
48
  appendAuditEntry,
49
49
  getAuditLogPath,
50
50
  readAuditTail
51
- } from "../chunk-PE23RMXY.mjs";
51
+ } from "../chunk-V4U3JM4R.mjs";
52
52
  import {
53
53
  ensureToken,
54
54
  generateBearerToken,
55
55
  getTokenPath,
56
56
  readToken,
57
57
  rotateToken
58
- } from "../chunk-HTUAQRKH.mjs";
59
- import "../chunk-U3DGFLXZ.mjs";
60
- import "../chunk-Q2VY4R5F.mjs";
61
- import "../chunk-H4BUAPPO.mjs";
62
- import "../chunk-Z7DAACGZ.mjs";
63
- import "../chunk-OF4DMAPJ.mjs";
64
- import "../chunk-LZPLNZ5U.mjs";
65
- import "../chunk-LKJMLGFP.mjs";
66
- import "../chunk-TQLCLE4L.mjs";
58
+ } from "../chunk-TDXETAQT.mjs";
59
+ import "../chunk-WDIW33DA.mjs";
60
+ import "../chunk-2FPGJKCA.mjs";
61
+ import "../chunk-C3HPFFTD.mjs";
62
+ import "../chunk-DQQISMYN.mjs";
63
+ import "../chunk-B65IJQZJ.mjs";
64
+ import "../chunk-D254EFYB.mjs";
65
+ import "../chunk-U7QPUNRH.mjs";
66
+ import "../chunk-S677V2JU.mjs";
67
67
  import "../chunk-MTDFKNXX.mjs";
68
- import "../chunk-XKSWCEGI.mjs";
68
+ import "../chunk-HJIXH6CL.mjs";
69
69
  import "../chunk-4UEJOM6W.mjs";
70
70
  export {
71
71
  acquire,
@@ -3,8 +3,8 @@ import {
3
3
  getTunnelBinaryPath,
4
4
  installCloudflared,
5
5
  resolvePinnedAssetKey
6
- } from "../chunk-3B276PGG.mjs";
7
- import "../chunk-XKSWCEGI.mjs";
6
+ } from "../chunk-FKQ3HP4Q.mjs";
7
+ import "../chunk-HJIXH6CL.mjs";
8
8
  import "../chunk-4UEJOM6W.mjs";
9
9
  export {
10
10
  getPinnedCloudflaredVersion,
@@ -13,24 +13,24 @@ import {
13
13
  rotateDaemonToken,
14
14
  startDaemon,
15
15
  stopDaemon
16
- } from "../chunk-X45O6YD3.mjs";
17
- import "../chunk-KCXM2M4B.mjs";
16
+ } from "../chunk-RK4EBZJ3.mjs";
17
+ import "../chunk-XTRJSV72.mjs";
18
18
  import "../chunk-6YMQVLFX.mjs";
19
- import "../chunk-3B276PGG.mjs";
20
- import "../chunk-6EP2BLTV.mjs";
21
- import "../chunk-S5VD7WTU.mjs";
22
- import "../chunk-PE23RMXY.mjs";
23
- import "../chunk-HTUAQRKH.mjs";
24
- import "../chunk-U3DGFLXZ.mjs";
25
- import "../chunk-Q2VY4R5F.mjs";
26
- import "../chunk-H4BUAPPO.mjs";
27
- import "../chunk-Z7DAACGZ.mjs";
28
- import "../chunk-OF4DMAPJ.mjs";
29
- import "../chunk-LZPLNZ5U.mjs";
30
- import "../chunk-LKJMLGFP.mjs";
31
- import "../chunk-TQLCLE4L.mjs";
19
+ import "../chunk-FKQ3HP4Q.mjs";
20
+ import "../chunk-KJFX2ZXR.mjs";
21
+ import "../chunk-T6ARJK2P.mjs";
22
+ import "../chunk-V4U3JM4R.mjs";
23
+ import "../chunk-TDXETAQT.mjs";
24
+ import "../chunk-WDIW33DA.mjs";
25
+ import "../chunk-2FPGJKCA.mjs";
26
+ import "../chunk-C3HPFFTD.mjs";
27
+ import "../chunk-DQQISMYN.mjs";
28
+ import "../chunk-B65IJQZJ.mjs";
29
+ import "../chunk-D254EFYB.mjs";
30
+ import "../chunk-U7QPUNRH.mjs";
31
+ import "../chunk-S677V2JU.mjs";
32
32
  import "../chunk-MTDFKNXX.mjs";
33
- import "../chunk-XKSWCEGI.mjs";
33
+ import "../chunk-HJIXH6CL.mjs";
34
34
  import "../chunk-4UEJOM6W.mjs";
35
35
  export {
36
36
  disableDaemonTunnel,