perplexity-user-mcp 0.8.42 → 0.8.47

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 (134) hide show
  1. package/dist/attachments.d.ts +10 -20
  2. package/dist/browser-window.d.ts +11 -0
  3. package/dist/cf-warmup.d.ts +32 -0
  4. package/dist/checks/browser.d.ts +12 -100
  5. package/dist/checks/config.d.ts +25 -91
  6. package/dist/checks/ide.d.ts +31 -89
  7. package/dist/checks/mcp.d.ts +12 -61
  8. package/dist/checks/native-deps.d.ts +46 -131
  9. package/dist/checks/network.d.ts +13 -71
  10. package/dist/checks/probe.d.ts +37 -92
  11. package/dist/checks/probe.mjs +29 -0
  12. package/dist/checks/profiles.d.ts +13 -99
  13. package/dist/checks/profiles.mjs +35 -0
  14. package/dist/checks/runtime.d.ts +24 -89
  15. package/dist/checks/vault.d.ts +13 -142
  16. package/dist/checks/vault.mjs +6 -11
  17. package/dist/{chunk-WDIW33DA.mjs → chunk-3LUO5ATM.mjs} +1 -1
  18. package/dist/{chunk-HNSPNCFH.mjs → chunk-6CAXNBDD.mjs} +1 -1
  19. package/dist/{chunk-B65IJQZJ.mjs → chunk-6E6XTHTG.mjs} +1 -1
  20. package/dist/{chunk-S677V2JU.mjs → chunk-C5I7KXHK.mjs} +32 -2
  21. package/dist/{chunk-RK4EBZJ3.mjs → chunk-D2ZQGKHM.mjs} +11 -8
  22. package/dist/{chunk-TDXETAQT.mjs → chunk-DKEJZ4FI.mjs} +1 -1
  23. package/dist/{chunk-U7QPUNRH.mjs → chunk-DXR6EEZH.mjs} +26 -7
  24. package/dist/{chunk-HJIXH6CL.mjs → chunk-E3GRJXXJ.mjs} +2 -0
  25. package/dist/{chunk-C3HPFFTD.mjs → chunk-GBHPJ7I7.mjs} +136 -48
  26. package/dist/{chunk-D254EFYB.mjs → chunk-GBI2U336.mjs} +1 -1
  27. package/dist/chunk-GPUGKWXH.mjs +17 -0
  28. package/dist/chunk-KVV3JBSN.mjs +32 -0
  29. package/dist/{chunk-XTRJSV72.mjs → chunk-LGH5BSUY.mjs} +1 -1
  30. package/dist/{chunk-KJFX2ZXR.mjs → chunk-NMKNEEZB.mjs} +1 -1
  31. package/dist/{chunk-T6ARJK2P.mjs → chunk-P6YOLJ5T.mjs} +6 -6
  32. package/dist/{chunk-452DK6OS.mjs → chunk-QXYMYCHC.mjs} +2 -2
  33. package/dist/{chunk-Z4OLYVB2.mjs → chunk-SCZQCV7M.mjs} +1 -1
  34. package/dist/{chunk-FKQ3HP4Q.mjs → chunk-TIWHN4IW.mjs} +1 -1
  35. package/dist/{chunk-V4U3JM4R.mjs → chunk-TSLRTZYR.mjs} +1 -1
  36. package/dist/{chunk-DQQISMYN.mjs → chunk-V4LHDNWJ.mjs} +2 -2
  37. package/dist/{chunk-2FPGJKCA.mjs → chunk-YD25G5AD.mjs} +2 -2
  38. package/dist/cli.d.ts +14 -1317
  39. package/dist/cli.mjs +14 -21
  40. package/dist/client.d.ts +39 -24
  41. package/dist/client.mjs +9 -6
  42. package/dist/cloud-sync.d.ts +65 -42
  43. package/dist/cloud-sync.mjs +9 -8
  44. package/dist/config.d.ts +35 -39
  45. package/dist/config.mjs +3 -3
  46. package/dist/cookie-jar.d.ts +77 -0
  47. package/dist/daemon/attach.d.ts +5 -12
  48. package/dist/daemon/attach.mjs +18 -17
  49. package/dist/daemon/audit.d.ts +5 -7
  50. package/dist/daemon/audit.mjs +2 -2
  51. package/dist/daemon/client-http.d.ts +10 -16
  52. package/dist/daemon/client-http.mjs +18 -17
  53. package/dist/daemon/index.d.ts +17 -14
  54. package/dist/daemon/index.mjs +19 -18
  55. package/dist/daemon/install-tunnel.d.ts +8 -34
  56. package/dist/daemon/install-tunnel.mjs +2 -2
  57. package/dist/daemon/launcher.d.ts +24 -29
  58. package/dist/daemon/launcher.mjs +17 -16
  59. package/dist/daemon/local-tokens.d.ts +23 -0
  60. package/dist/daemon/lockfile.d.ts +10 -12
  61. package/dist/daemon/lockfile.mjs +2 -2
  62. package/dist/daemon/oauth-consent-cache.d.ts +86 -0
  63. package/dist/daemon/oauth-provider.d.ts +132 -0
  64. package/dist/daemon/public-pages.d.ts +9 -0
  65. package/dist/daemon/security.d.ts +52 -0
  66. package/dist/daemon/server.d.ts +12 -83
  67. package/dist/daemon/server.mjs +12 -11
  68. package/dist/daemon/token.d.ts +7 -9
  69. package/dist/daemon/token.mjs +2 -2
  70. package/dist/daemon/tunnel-providers/cloudflared-named-setup.d.ts +140 -0
  71. package/dist/daemon/tunnel-providers/cloudflared-named.d.ts +45 -0
  72. package/dist/daemon/tunnel-providers/cloudflared-quick.d.ts +8 -0
  73. package/dist/daemon/tunnel-providers/index.d.ts +16 -327
  74. package/dist/daemon/tunnel-providers/index.mjs +3 -3
  75. package/dist/daemon/tunnel-providers/ngrok-config.d.ts +18 -0
  76. package/dist/daemon/tunnel-providers/ngrok.d.ts +68 -0
  77. package/dist/daemon/tunnel-providers/types.d.ts +56 -0
  78. package/dist/daemon/tunnel.d.ts +5 -7
  79. package/dist/debug-tracer.d.ts +2 -0
  80. package/dist/doctor-report.d.ts +17 -22
  81. package/dist/doctor.d.ts +12 -44
  82. package/dist/doctor.mjs +2 -2
  83. package/dist/export.d.ts +11 -18
  84. package/dist/export.mjs +4 -4
  85. package/dist/format.d.ts +52 -0
  86. package/dist/fs-utils.d.ts +44 -0
  87. package/dist/health-check.d.ts +1 -108
  88. package/dist/health-check.mjs +3 -3
  89. package/dist/history-store.d.ts +29 -65
  90. package/dist/history-store.mjs +2 -2
  91. package/dist/impit-login-runner.d.ts +1 -469
  92. package/dist/impit-login-runner.mjs +4 -4
  93. package/dist/index.d.ts +25 -149
  94. package/dist/index.mjs +23 -20
  95. package/dist/is-main-module.d.ts +9 -0
  96. package/dist/login-runner.d.ts +1 -333
  97. package/dist/login-runner.mjs +18 -38
  98. package/dist/login.d.ts +5 -0
  99. package/dist/logout.d.ts +2 -28
  100. package/dist/logout.mjs +3 -2
  101. package/dist/manual-login-runner.d.ts +1 -150
  102. package/dist/manual-login-runner.mjs +11 -11
  103. package/dist/{native-deps-IE4B55EL.mjs → native-deps-FCSYDL4W.mjs} +4 -4
  104. package/dist/native-deps.d.ts +36 -0
  105. package/dist/package-version.d.ts +1 -0
  106. package/dist/profiles.d.ts +41 -41
  107. package/dist/profiles.mjs +1 -1
  108. package/dist/prompts.d.ts +2 -0
  109. package/dist/redact.d.ts +14 -142
  110. package/dist/refresh.d.ts +11 -16
  111. package/dist/refresh.mjs +4 -4
  112. package/dist/reinit-watcher.d.ts +15 -24
  113. package/dist/reinit-watcher.mjs +2 -2
  114. package/dist/resources.d.ts +5 -0
  115. package/dist/safe-write.d.ts +16 -0
  116. package/dist/session-metadata.d.ts +45 -0
  117. package/dist/tool-config.d.ts +10 -0
  118. package/dist/tools.d.ts +23 -0
  119. package/dist/tty-prompt.d.ts +18 -34
  120. package/dist/vault.d.ts +114 -34
  121. package/dist/vault.mjs +6 -4
  122. package/dist/viewer-detect.d.ts +2 -4
  123. package/dist/viewers.d.ts +13 -18
  124. package/dist/viewers.mjs +1 -1
  125. package/package.json +2 -2
  126. package/dist/cloud-sync.d-Cqt6y18U.d.ts +0 -42
  127. package/dist/doctor.d-CXmUqOXX.d.ts +0 -43
  128. package/dist/history-store.d-BzjBF2m3.d.ts +0 -65
  129. package/dist/native-deps-BNThFHxa.d.ts +0 -175
  130. package/dist/profiles.d-DqS1oZWr.d.ts +0 -41
  131. package/dist/session-metadata-B9aV_n5g.d.ts +0 -148
  132. package/dist/vault.d-BSJWDLhp.d.ts +0 -37
  133. package/dist/viewer-detect.d-HWGnyFAA.d.ts +0 -4
  134. package/dist/viewers.d-BGCK6sw6.d.ts +0 -10
package/dist/cli.mjs CHANGED
@@ -1,3 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isMainModule
4
+ } from "./chunk-GPUGKWXH.mjs";
5
+ import {
6
+ probeKeychainState
7
+ } from "./chunk-C5I7KXHK.mjs";
8
+ import "./chunk-MTDFKNXX.mjs";
9
+ import "./chunk-E3GRJXXJ.mjs";
1
10
  import "./chunk-4UEJOM6W.mjs";
2
11
 
3
12
  // src/cli.js
@@ -99,23 +108,7 @@ function normalizeExportFormat(value) {
99
108
  return null;
100
109
  }
101
110
  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
- }
111
+ const { available: keychainAvailable, hasKey: keychainHasKey } = await probeKeychainState();
119
112
  const envPassphraseSet = !!process.env.PERPLEXITY_VAULT_PASSPHRASE;
120
113
  const hasTty = process.stdin?.isTTY === true && process.env.PERPLEXITY_MCP_STDIO !== "1";
121
114
  let vaultExists = false;
@@ -776,7 +769,7 @@ Config written to ${config.configPath}`;
776
769
  return { code: browserResult.code, stdout: (flags.json ? browserResult.last : `login finished (${browserResult.code})`) + "\n", stderr: "" };
777
770
  }
778
771
  if (command === "install-speed-boost") {
779
- const { installImpit, getImpitStatus } = await import("./native-deps-IE4B55EL.mjs");
772
+ const { installImpit, getImpitStatus } = await import("./native-deps-FCSYDL4W.mjs");
780
773
  const before = getImpitStatus();
781
774
  if (before.installed && !flags.force) {
782
775
  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}.
@@ -797,7 +790,7 @@ All impit-eligible tools (sync, hydrate, retrieve, export, models, login) will u
797
790
  return { code: 0, stdout: out + "\n", stderr: "" };
798
791
  }
799
792
  if (command === "uninstall-speed-boost") {
800
- const { uninstallImpit, getImpitStatus } = await import("./native-deps-IE4B55EL.mjs");
793
+ const { uninstallImpit, getImpitStatus } = await import("./native-deps-FCSYDL4W.mjs");
801
794
  const before = getImpitStatus();
802
795
  const log = (line) => process.stderr.write(`[speed-boost] ${line}
803
796
  `);
@@ -811,7 +804,7 @@ All impit-eligible tools (sync, hydrate, retrieve, export, models, login) will u
811
804
  return { code: 0, stdout: out + "\n", stderr: "" };
812
805
  }
813
806
  if (command === "speed-boost-status") {
814
- const { getImpitStatus } = await import("./native-deps-IE4B55EL.mjs");
807
+ const { getImpitStatus } = await import("./native-deps-FCSYDL4W.mjs");
815
808
  const status = getImpitStatus();
816
809
  if (flags.json) {
817
810
  return { code: 0, stdout: JSON.stringify(status) + "\n", stderr: "" };
@@ -1084,7 +1077,7 @@ Notes:
1084
1077
  Environment:
1085
1078
  PERPLEXITY_NO_DAEMON=1 'daemon attach' runs in-process stdio (bypass daemon)
1086
1079
  `;
1087
- if (import.meta.url === pathToFileURL(process.argv[1]).href) {
1080
+ if (isMainModule(import.meta.url)) {
1088
1081
  const parsed = parseArgs(process.argv.slice(2));
1089
1082
  routeCommand(parsed).then((res) => {
1090
1083
  if (res.stdout) process.stdout.write(res.stdout);
package/dist/client.d.ts CHANGED
@@ -1,12 +1,9 @@
1
- import { AccountInfo, SearchResult } from './config.js';
2
- import 'patchright';
3
-
4
1
  /**
5
2
  * Perplexity Web API client — uses Playwright persistent browser context.
6
3
  * Login (headed) and MCP server (headless) share the same browser profile directory,
7
4
  * so Cloudflare cf_clearance and all state persist between runs.
8
5
  */
9
-
6
+ import { type SearchResult, type AccountInfo } from "./config.js";
10
7
  /**
11
8
  * Read the on-disk AccountInfo cache for the active profile without
12
9
  * touching the browser or the network. Returns null when the cache file
@@ -15,8 +12,20 @@ import 'patchright';
15
12
  * runs — the cache is written by every successful refresh tier
16
13
  * (refresh.ts) and by login-runner.js after a fresh login.
17
14
  */
18
- declare function readCachedAccountInfoFromDisk(): AccountInfo | null;
19
- interface ListAskThreadsItem {
15
+ export declare function readCachedAccountInfoFromDisk(): AccountInfo | null;
16
+ /**
17
+ * Build launch options for Playwright persistent context.
18
+ *
19
+ * Uses the first available system browser (Chrome > Edge > Chromium > Brave)
20
+ * for best Cloudflare fingerprinting, falling back to patchright's bundled
21
+ * Chromium. The resolved `channel` is passed through so Patchright can apply
22
+ * channel-specific stealth tweaks (important for msedge on Windows).
23
+ *
24
+ * @internal Exported only so unit tests can assert the headed/headless arg
25
+ * branches; not part of the supported `perplexity-user-mcp/client` API.
26
+ */
27
+ export declare function buildLaunchOptions(headless: boolean): Record<string, any>;
28
+ export interface ListAskThreadsItem {
20
29
  backendUuid: string;
21
30
  contextUuid: string;
22
31
  slug: string;
@@ -33,11 +42,11 @@ interface ListAskThreadsItem {
33
42
  threadStatus: string;
34
43
  readWriteToken: string | null;
35
44
  }
36
- interface ListAskThreadsResult {
45
+ export interface ListAskThreadsResult {
37
46
  items: ListAskThreadsItem[];
38
47
  total: number;
39
48
  }
40
- interface ListAskThreadsOpts {
49
+ export interface ListAskThreadsOpts {
41
50
  limit?: number;
42
51
  offset?: number;
43
52
  searchTerm?: string;
@@ -50,11 +59,11 @@ interface ListAskThreadsOpts {
50
59
  * doesn't yield a parseable 200. Lets callers (cloud-sync, the class method)
51
60
  * fall back to the browser path on any miss.
52
61
  */
53
- declare function listCloudThreadsViaImpit(opts?: ListAskThreadsOpts): Promise<ListAskThreadsResult | null>;
54
- interface GetCloudThreadOpts {
62
+ export declare function listCloudThreadsViaImpit(opts?: ListAskThreadsOpts): Promise<ListAskThreadsResult | null>;
63
+ export interface GetCloudThreadOpts {
55
64
  limit?: number;
56
65
  }
57
- interface CloudThreadEntry {
66
+ export interface CloudThreadEntry {
58
67
  backendUuid: string;
59
68
  queryStr: string;
60
69
  answer: string;
@@ -72,7 +81,7 @@ interface CloudThreadEntry {
72
81
  createdAt: string;
73
82
  status: string;
74
83
  }
75
- interface GetCloudThreadResult {
84
+ export interface GetCloudThreadResult {
76
85
  entries: CloudThreadEntry[];
77
86
  thread: {
78
87
  slug: string;
@@ -88,8 +97,8 @@ interface GetCloudThreadResult {
88
97
  * miss (returns null) — the caller will hit the browser path which will
89
98
  * surface the 404 as a hard error.
90
99
  */
91
- declare function getCloudThreadViaImpit(slug: string, opts?: GetCloudThreadOpts): Promise<GetCloudThreadResult | null>;
92
- interface BuildSearchRequestOpts {
100
+ export declare function getCloudThreadViaImpit(slug: string, opts?: GetCloudThreadOpts): Promise<GetCloudThreadResult | null>;
101
+ export interface BuildSearchRequestOpts {
93
102
  query: string;
94
103
  modelPreference: string;
95
104
  mode: string;
@@ -100,15 +109,15 @@ interface BuildSearchRequestOpts {
100
109
  readWriteToken?: string | null;
101
110
  };
102
111
  }
103
- declare function isExperimentalImpitSearchEnabled(): boolean;
112
+ export declare function isExperimentalImpitSearchEnabled(): boolean;
104
113
  /**
105
114
  * Browser-free search via impit. Returns null on any failure (impit not
106
115
  * installed, no session cookie, non-200, parse error) so callers can fall
107
116
  * back to the browser path. Same SSE response format as the in-page fetch
108
117
  * — parsed by `PerplexityClient.parseSSEText`.
109
118
  */
110
- declare function searchPerplexityViaImpit(opts: BuildSearchRequestOpts): Promise<SearchResult | null>;
111
- interface RetrieveThreadViaImpitOpts {
119
+ export declare function searchPerplexityViaImpit(opts: BuildSearchRequestOpts): Promise<SearchResult | null>;
120
+ export interface RetrieveThreadViaImpitOpts {
112
121
  threadSlug: string;
113
122
  backendUuid: string | null;
114
123
  readWriteToken: string | null;
@@ -126,13 +135,13 @@ interface RetrieveThreadViaImpitOpts {
126
135
  * attached files we return null so the caller forces a browser session
127
136
  * which can drive `downloadASIFiles` via the page's APIRequestContext.
128
137
  */
129
- declare function retrieveThreadViaImpit(opts: RetrieveThreadViaImpitOpts): Promise<SearchResult | null>;
130
- interface ExportThreadViaImpitOpts {
138
+ export declare function retrieveThreadViaImpit(opts: RetrieveThreadViaImpitOpts): Promise<SearchResult | null>;
139
+ export interface ExportThreadViaImpitOpts {
131
140
  threadSlug?: string | null;
132
141
  entryUuid?: string | null;
133
142
  format: "pdf" | "markdown" | "docx";
134
143
  }
135
- interface ExportThreadResult {
144
+ export interface ExportThreadResult {
136
145
  buffer: Buffer;
137
146
  filename: string;
138
147
  contentType: string;
@@ -144,8 +153,8 @@ interface ExportThreadResult {
144
153
  * page-context export. Markdown export is intentionally not supported here
145
154
  * — the caller assembles markdown locally from the saved history entry.
146
155
  */
147
- declare function exportThreadViaImpit(opts: ExportThreadViaImpitOpts): Promise<ExportThreadResult | null>;
148
- declare class PerplexityClient {
156
+ export declare function exportThreadViaImpit(opts: ExportThreadViaImpitOpts): Promise<ExportThreadResult | null>;
157
+ export declare class PerplexityClient {
149
158
  private browser;
150
159
  private context;
151
160
  private page;
@@ -350,6 +359,12 @@ declare class PerplexityClient {
350
359
  */
351
360
  getCloudThread(slug: string, opts?: GetCloudThreadOpts): Promise<GetCloudThreadResult>;
352
361
  shutdown(): Promise<void>;
362
+ private daemonTier;
363
+ /**
364
+ * Write daemon-status.json so the extension UI can show live auth state
365
+ * instead of relying on the stale models-cache.json snapshot.
366
+ * @param startedAt - Date.now() captured at the start of init/reinit
367
+ * @param error - error message if init threw, null on success or shutdown
368
+ */
369
+ private writeDaemonStatus;
353
370
  }
354
-
355
- export { type BuildSearchRequestOpts, type CloudThreadEntry, type ExportThreadResult, type ExportThreadViaImpitOpts, type GetCloudThreadOpts, type GetCloudThreadResult, type ListAskThreadsItem, type ListAskThreadsOpts, type ListAskThreadsResult, PerplexityClient, type RetrieveThreadViaImpitOpts, exportThreadViaImpit, getCloudThreadViaImpit, isExperimentalImpitSearchEnabled, listCloudThreadsViaImpit, readCachedAccountInfoFromDisk, retrieveThreadViaImpit, searchPerplexityViaImpit };
package/dist/client.mjs CHANGED
@@ -1,5 +1,6 @@
1
1
  import {
2
2
  PerplexityClient,
3
+ buildLaunchOptions,
3
4
  exportThreadViaImpit,
4
5
  getCloudThreadViaImpit,
5
6
  isExperimentalImpitSearchEnabled,
@@ -7,16 +8,18 @@ import {
7
8
  readCachedAccountInfoFromDisk,
8
9
  retrieveThreadViaImpit,
9
10
  searchPerplexityViaImpit
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";
11
+ } from "./chunk-GBHPJ7I7.mjs";
12
+ import "./chunk-KVV3JBSN.mjs";
13
+ import "./chunk-V4LHDNWJ.mjs";
14
+ import "./chunk-GBI2U336.mjs";
15
+ import "./chunk-DXR6EEZH.mjs";
16
+ import "./chunk-C5I7KXHK.mjs";
15
17
  import "./chunk-MTDFKNXX.mjs";
16
- import "./chunk-HJIXH6CL.mjs";
18
+ import "./chunk-E3GRJXXJ.mjs";
17
19
  import "./chunk-4UEJOM6W.mjs";
18
20
  export {
19
21
  PerplexityClient,
22
+ buildLaunchOptions,
20
23
  exportThreadViaImpit,
21
24
  getCloudThreadViaImpit,
22
25
  isExperimentalImpitSearchEnabled,
@@ -1,42 +1,65 @@
1
- import { PerplexityClient } from './client.js';
2
- import './config.js';
3
- import 'patchright';
4
-
5
- interface CloudSyncProgressEvent {
6
- phase: "starting" | "syncing" | "done" | "cancelled" | "error";
7
- fetched?: number;
8
- total?: number;
9
- inserted?: number;
10
- updated?: number;
11
- skipped?: number;
12
- error?: string;
13
- }
14
-
15
- interface CloudSyncOptions {
16
- client?: PerplexityClient;
17
- getClient?: () => Promise<PerplexityClient>;
18
- onProgress?: (evt: CloudSyncProgressEvent) => void;
19
- pageSize?: number;
20
- signal?: AbortSignal;
21
- }
22
-
23
- interface CloudSyncResult {
24
- fetched: number;
25
- total: number;
26
- inserted: number;
27
- updated: number;
28
- skipped: number;
29
- cancelled: boolean;
30
- }
31
-
32
- declare function syncCloudHistory(opts?: CloudSyncOptions): Promise<CloudSyncResult>;
33
-
34
- declare function hydrateCloudHistoryEntry(
35
- historyId: string,
36
- opts?: {
37
- client?: PerplexityClient;
38
- getClient?: () => Promise<PerplexityClient>;
39
- },
40
- ): Promise<{ action: "skipped-local" | "skipped-hydrated" | "hydrated"; id?: string }>;
41
-
42
- export { type CloudSyncOptions, type CloudSyncProgressEvent, type CloudSyncResult, hydrateCloudHistoryEntry, syncCloudHistory };
1
+ /**
2
+ * Sync the user's Perplexity library (all ask threads) into local history.
3
+ * Merges by backend_uuid. Never touches local MCP-originated entries or the
4
+ * bodies of already-hydrated cloud entries.
5
+ *
6
+ * Per-page strategy: try impit first (no browser); on miss, lazily acquire
7
+ * the client (init() or caller-provided getClient) and use the browser path
8
+ * for the remainder of the sync. The first impit miss in a run sticks —
9
+ * we don't ping-pong between paths.
10
+ *
11
+ * @param {object} opts
12
+ * @param {PerplexityClient} [opts.client] Pre-initialized client. If supplied, the impit fast path is skipped (the caller has already paid for init).
13
+ * @param {() => Promise<PerplexityClient>} [opts.getClient] Lazy getter. Called only when the impit path misses, so the browser is never spawned in the all-impit happy path.
14
+ * @param {(evt: { phase: string; fetched?: number; total?: number; inserted?: number; updated?: number; skipped?: number; error?: string }) => void} [opts.onProgress]
15
+ * @param {number} [opts.pageSize=1000]
16
+ * @param {AbortSignal} [opts.signal]
17
+ */
18
+ export function syncCloudHistory(opts?: {
19
+ client?: PerplexityClient | undefined;
20
+ getClient?: (() => Promise<PerplexityClient>) | undefined;
21
+ onProgress?: ((evt: {
22
+ phase: string;
23
+ fetched?: number;
24
+ total?: number;
25
+ inserted?: number;
26
+ updated?: number;
27
+ skipped?: number;
28
+ error?: string;
29
+ }) => void) | undefined;
30
+ pageSize?: number | undefined;
31
+ signal?: AbortSignal | undefined;
32
+ }): Promise<{
33
+ cancelled: boolean;
34
+ fetched: number;
35
+ total: number;
36
+ inserted: number;
37
+ updated: number;
38
+ skipped: number;
39
+ }>;
40
+ /**
41
+ * Lazy-hydrate a single cloud entry — fetch full thread content and
42
+ * replace the stub body. No-op if the entry is already hydrated or
43
+ * isn't a cloud entry.
44
+ *
45
+ * Tries the impit fast path first (no browser launch). If that misses,
46
+ * lazy-acquires the daemon's client (or constructs one) and falls back
47
+ * to the browser path. The first impit miss in a hydrate run sticks for
48
+ * any subsequent steps in this same call (there's only one fetch, so
49
+ * this is a no-op in practice but keeps the semantics consistent with
50
+ * syncCloudHistory).
51
+ *
52
+ * @param {string} historyId
53
+ * @param {object} [opts]
54
+ * @param {PerplexityClient} [opts.client] Pre-init'd client. Skips impit fast path (caller already paid for init).
55
+ * @param {() => Promise<PerplexityClient>} [opts.getClient] Lazy getter. Only called if impit misses.
56
+ * @returns {Promise<{ action: "skipped-local" | "skipped-hydrated" | "hydrated"; id?: string }>}
57
+ */
58
+ export function hydrateCloudHistoryEntry(historyId: string, opts?: {
59
+ client?: PerplexityClient | undefined;
60
+ getClient?: (() => Promise<PerplexityClient>) | undefined;
61
+ }): Promise<{
62
+ action: "skipped-local" | "skipped-hydrated" | "hydrated";
63
+ id?: string;
64
+ }>;
65
+ import { PerplexityClient } from "./client.js";
@@ -1,15 +1,16 @@
1
1
  import {
2
2
  hydrateCloudHistoryEntry,
3
3
  syncCloudHistory
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";
4
+ } from "./chunk-YD25G5AD.mjs";
5
+ import "./chunk-GBHPJ7I7.mjs";
6
+ import "./chunk-KVV3JBSN.mjs";
7
+ import "./chunk-V4LHDNWJ.mjs";
8
+ import "./chunk-6E6XTHTG.mjs";
9
+ import "./chunk-GBI2U336.mjs";
10
+ import "./chunk-DXR6EEZH.mjs";
11
+ import "./chunk-C5I7KXHK.mjs";
11
12
  import "./chunk-MTDFKNXX.mjs";
12
- import "./chunk-HJIXH6CL.mjs";
13
+ import "./chunk-E3GRJXXJ.mjs";
13
14
  import "./chunk-4UEJOM6W.mjs";
14
15
  export {
15
16
  hydrateCloudHistoryEntry,
package/dist/config.d.ts CHANGED
@@ -1,30 +1,28 @@
1
- import * as patchright from 'patchright';
2
-
3
- declare const PERPLEXITY_URL = "https://www.perplexity.ai";
4
- declare const AUTH_SESSION_ENDPOINT = "https://www.perplexity.ai/api/auth/session";
5
- declare const QUERY_ENDPOINT = "https://www.perplexity.ai/rest/sse/perplexity_ask";
6
- declare const MODELS_CONFIG_ENDPOINT = "https://www.perplexity.ai/rest/models/config?config_schema=v1&version=2.18&source=default";
7
- declare const ASI_ACCESS_ENDPOINT = "https://www.perplexity.ai/rest/billing/asi-access-decision?version=2.18&source=default";
8
- declare const RATE_LIMIT_ENDPOINT = "https://www.perplexity.ai/rest/rate-limit/status?version=2.18&source=default";
9
- declare const EXPERIMENTS_ENDPOINT = "https://www.perplexity.ai/rest/experiments/attributes?version=2.18&source=default";
10
- declare const USER_INFO_ENDPOINT = "https://www.perplexity.ai/rest/user/info?version=2.18&source=default";
11
- declare const THREAD_ENDPOINT: (slug: string) => string;
12
- declare const CONFIG_DIR: string;
1
+ export declare const PERPLEXITY_URL = "https://www.perplexity.ai";
2
+ export declare const AUTH_SESSION_ENDPOINT = "https://www.perplexity.ai/api/auth/session";
3
+ export declare const QUERY_ENDPOINT = "https://www.perplexity.ai/rest/sse/perplexity_ask";
4
+ export declare const MODELS_CONFIG_ENDPOINT = "https://www.perplexity.ai/rest/models/config?config_schema=v1&version=2.18&source=default";
5
+ export declare const ASI_ACCESS_ENDPOINT = "https://www.perplexity.ai/rest/billing/asi-access-decision?version=2.18&source=default";
6
+ export declare const RATE_LIMIT_ENDPOINT = "https://www.perplexity.ai/rest/rate-limit/status?version=2.18&source=default";
7
+ export declare const EXPERIMENTS_ENDPOINT = "https://www.perplexity.ai/rest/experiments/attributes?version=2.18&source=default";
8
+ export declare const USER_INFO_ENDPOINT = "https://www.perplexity.ai/rest/user/info?version=2.18&source=default";
9
+ export declare const THREAD_ENDPOINT: (slug: string) => string;
10
+ export declare const CONFIG_DIR: string;
13
11
  /**
14
12
  * Cookies file path for the active profile (legacy fallback only — real
15
13
  * storage is the encrypted vault now). Profile-aware, evaluated at call time.
16
14
  */
17
- declare function getCookiesFile(): string;
15
+ export declare function getCookiesFile(): string;
18
16
  /**
19
17
  * Browser persistent-context directory for the active profile.
20
18
  * Profile-aware, evaluated at call time.
21
19
  */
22
- declare function getBrowserDataDir(): string;
23
- declare const COOKIES_FILE: string;
24
- declare const STORAGE_STATE_FILE: string;
25
- declare const BROWSER_DATA_DIR: string;
26
- type BrowserChannel = "chrome" | "msedge" | "chromium" | "bundled";
27
- interface BrowserInfo {
20
+ export declare function getBrowserDataDir(): string;
21
+ export declare const COOKIES_FILE: string;
22
+ export declare const STORAGE_STATE_FILE: string;
23
+ export declare const BROWSER_DATA_DIR: string;
24
+ export type BrowserChannel = "chrome" | "msedge" | "chromium" | "bundled";
25
+ export interface BrowserInfo {
28
26
  /** Absolute path to a browser executable. */
29
27
  path: string;
30
28
  /** Channel passed to Patchright's launch APIs. */
@@ -40,7 +38,7 @@ interface BrowserInfo {
40
38
  * PERPLEXITY_BROWSER_CHANNEL — chrome | msedge | chromium (defaults to "chrome")
41
39
  * PERPLEXITY_CHROME_PATH — legacy alias for PERPLEXITY_BROWSER_PATH
42
40
  */
43
- declare function findBrowser(): BrowserInfo | null;
41
+ export declare function findBrowser(): BrowserInfo | null;
44
42
  /**
45
43
  * Pick a usable BrowserContext from a Patchright Browser. Kept as a small
46
44
  * helper for any future CDP-connect path (e.g. attaching to a remote Chrome
@@ -48,12 +46,12 @@ declare function findBrowser(): BrowserInfo | null;
48
46
  * is empty until we call `newContext`, which then runs unchanged with the
49
47
  * caller's options (viewport, userAgent, etc).
50
48
  */
51
- declare function getOrCreateContext(browser: patchright.Browser, options?: Parameters<patchright.Browser["newContext"]>[0]): Promise<patchright.BrowserContext>;
49
+ export declare function getOrCreateContext(browser: import("patchright").Browser, options?: Parameters<import("patchright").Browser["newContext"]>[0]): Promise<import("patchright").BrowserContext>;
52
50
  /**
53
51
  * Find the real Chrome executable on the system.
54
52
  * Returns the path or null if not found.
55
53
  */
56
- declare function findChromeExecutable(): string | null;
54
+ export declare function findChromeExecutable(): string | null;
57
55
  /**
58
56
  * Resolve a browser executable the client can launch.
59
57
  *
@@ -66,20 +64,20 @@ declare function findChromeExecutable(): string | null;
66
64
  * The returned `channel` field is additive and safe to ignore by legacy
67
65
  * callers that only destructure `{ path }`.
68
66
  */
69
- declare function resolveBrowserExecutable(): Promise<{
67
+ export declare function resolveBrowserExecutable(): Promise<{
70
68
  path: string;
71
69
  channel: BrowserChannel;
72
70
  source: "system-chrome" | "system-edge" | "system-chromium" | "system-brave" | "bundled-chromium";
73
71
  }>;
74
- declare const DEFAULT_HEADERS: Record<string, string>;
75
- declare const SUPPORTED_BLOCK_USE_CASES: string[];
76
- interface ModelInfo {
72
+ export declare const DEFAULT_HEADERS: Record<string, string>;
73
+ export declare const SUPPORTED_BLOCK_USE_CASES: string[];
74
+ export interface ModelInfo {
77
75
  description: string;
78
76
  mode: string;
79
77
  provider: string | null;
80
78
  label?: string;
81
79
  }
82
- interface ModelConfigEntry {
80
+ export interface ModelConfigEntry {
83
81
  label: string;
84
82
  description: string;
85
83
  subheading: string | null;
@@ -91,18 +89,18 @@ interface ModelConfigEntry {
91
89
  audience?: string | null;
92
90
  is_default?: boolean;
93
91
  }
94
- interface ModelsConfigResponse {
92
+ export interface ModelsConfigResponse {
95
93
  models: Record<string, ModelInfo>;
96
94
  config: ModelConfigEntry[];
97
95
  default_models: Record<string, string>;
98
96
  agentic_research_compare_models?: string[];
99
97
  }
100
- interface ASIAccessResponse {
98
+ export interface ASIAccessResponse {
101
99
  can_use_computer: boolean;
102
100
  can_access_org_credits_page: boolean;
103
101
  can_enable_topup: boolean;
104
102
  }
105
- interface RateLimitResponse {
103
+ export interface RateLimitResponse {
106
104
  modes: Record<string, {
107
105
  available: boolean;
108
106
  remaining_detail: {
@@ -118,13 +116,13 @@ interface RateLimitResponse {
118
116
  };
119
117
  }>;
120
118
  }
121
- interface UserInfoResponse {
119
+ export interface UserInfoResponse {
122
120
  has_non_public_email?: boolean;
123
121
  is_enterprise?: boolean;
124
122
  is_gov?: boolean;
125
123
  is_student?: boolean;
126
124
  }
127
- interface AccountInfo {
125
+ export interface AccountInfo {
128
126
  isPro: boolean;
129
127
  isMax: boolean;
130
128
  isEnterprise: boolean;
@@ -132,7 +130,7 @@ interface AccountInfo {
132
130
  modelsConfig: ModelsConfigResponse | null;
133
131
  rateLimits: RateLimitResponse | null;
134
132
  }
135
- interface ASIFile {
133
+ export interface ASIFile {
136
134
  filename: string;
137
135
  assetType: string;
138
136
  url: string;
@@ -140,7 +138,7 @@ interface ASIFile {
140
138
  size?: number;
141
139
  mediaType?: string;
142
140
  }
143
- interface SearchResult {
141
+ export interface SearchResult {
144
142
  answer: string;
145
143
  reasoning?: string;
146
144
  sources: Array<{
@@ -166,7 +164,7 @@ interface SearchResult {
166
164
  /**
167
165
  * Build cookie string from env vars or saved cookies file for Playwright context.
168
166
  */
169
- interface PlaywrightCookie {
167
+ export interface PlaywrightCookie {
170
168
  name: string;
171
169
  value: string;
172
170
  domain: string;
@@ -175,12 +173,10 @@ interface PlaywrightCookie {
175
173
  httpOnly?: boolean;
176
174
  sameSite?: "Strict" | "Lax" | "None";
177
175
  }
178
- declare function getSavedCookies(): Promise<PlaywrightCookie[]>;
176
+ export declare function getSavedCookies(): Promise<PlaywrightCookie[]>;
179
177
  /**
180
178
  * Check whether the active profile has stored login cookies in its vault.
181
179
  * Extension has its own filesystem-based `hasStoredLogin` in session.ts that
182
180
  * inspects COOKIES_FILE / BROWSER_DATA_DIR — this one is vault-aware.
183
181
  */
184
- declare function hasStoredLogin(): Promise<boolean>;
185
-
186
- export { type ASIAccessResponse, type ASIFile, ASI_ACCESS_ENDPOINT, AUTH_SESSION_ENDPOINT, type AccountInfo, BROWSER_DATA_DIR, type BrowserChannel, type BrowserInfo, CONFIG_DIR, COOKIES_FILE, DEFAULT_HEADERS, EXPERIMENTS_ENDPOINT, MODELS_CONFIG_ENDPOINT, type ModelConfigEntry, type ModelInfo, type ModelsConfigResponse, PERPLEXITY_URL, type PlaywrightCookie, QUERY_ENDPOINT, RATE_LIMIT_ENDPOINT, type RateLimitResponse, STORAGE_STATE_FILE, SUPPORTED_BLOCK_USE_CASES, type SearchResult, THREAD_ENDPOINT, USER_INFO_ENDPOINT, type UserInfoResponse, findBrowser, findChromeExecutable, getBrowserDataDir, getCookiesFile, getOrCreateContext, getSavedCookies, hasStoredLogin, resolveBrowserExecutable };
182
+ export declare function hasStoredLogin(): Promise<boolean>;
package/dist/config.mjs CHANGED
@@ -22,10 +22,10 @@ import {
22
22
  getSavedCookies,
23
23
  hasStoredLogin,
24
24
  resolveBrowserExecutable
25
- } from "./chunk-U7QPUNRH.mjs";
26
- import "./chunk-S677V2JU.mjs";
25
+ } from "./chunk-DXR6EEZH.mjs";
26
+ import "./chunk-C5I7KXHK.mjs";
27
27
  import "./chunk-MTDFKNXX.mjs";
28
- import "./chunk-HJIXH6CL.mjs";
28
+ import "./chunk-E3GRJXXJ.mjs";
29
29
  import "./chunk-4UEJOM6W.mjs";
30
30
  export {
31
31
  ASI_ACCESS_ENDPOINT,
@@ -0,0 +1,77 @@
1
+ export class CookieJar {
2
+ /**
3
+ * @param {PlaywrightCookie[]} [initialCookies]
4
+ */
5
+ constructor(initialCookies?: PlaywrightCookie[]);
6
+ /** @type {Map<string, ReturnType<typeof entryFromPlaywright>>} */
7
+ _store: Map<string, ReturnType<typeof entryFromPlaywright>>;
8
+ /**
9
+ * Apply one or more Set-Cookie headers from a response. Accepts either a
10
+ * single string or an array (e.g. `res.headers.getSetCookie?.()` /
11
+ * `res.headers.raw()['set-cookie']`).
12
+ *
13
+ * @param {string|string[]|null|undefined} header
14
+ * @param {string} requestUrl
15
+ */
16
+ consumeSetCookieHeader(header: string | string[] | null | undefined, requestUrl: string): void;
17
+ /**
18
+ * Build a `Cookie:` header value for `requestUrl`. Returns "" if no cookies
19
+ * apply (so the caller can do `if (h) headers.cookie = h`).
20
+ *
21
+ * @param {string} requestUrl
22
+ * @returns {string}
23
+ */
24
+ buildCookieHeader(requestUrl: string): string;
25
+ /**
26
+ * Snapshot of every cookie in the jar (including expired ones — callers that
27
+ * persist to disk want the full set so a refresh can simply overwrite).
28
+ *
29
+ * @returns {PlaywrightCookie[]}
30
+ */
31
+ toPlaywrightShape(): PlaywrightCookie[];
32
+ /**
33
+ * Explicit setter, mostly for tests and for the rare case where the caller
34
+ * already has a fully-formed cookie record (e.g. seeding cf_clearance from
35
+ * the vault). `attributes` may include any of the PlaywrightCookie fields
36
+ * except name/value.
37
+ *
38
+ * @param {string} name
39
+ * @param {string} value
40
+ * @param {Partial<PlaywrightCookie> & { hostOnly?: boolean }} [attributes]
41
+ */
42
+ set(name: string, value: string, attributes?: Partial<PlaywrightCookie> & {
43
+ hostOnly?: boolean;
44
+ }): void;
45
+ }
46
+ export type PlaywrightCookie = {
47
+ name: string;
48
+ value: string;
49
+ domain: string;
50
+ path: string;
51
+ /**
52
+ * Unix epoch seconds; -1 for session cookies (Patchright convention).
53
+ */
54
+ expires?: number | undefined;
55
+ secure?: boolean | undefined;
56
+ httpOnly?: boolean | undefined;
57
+ sameSite?: "Strict" | "Lax" | "None" | undefined;
58
+ };
59
+ /**
60
+ * Coerce a PlaywrightCookie back into the internal entry shape. Used by
61
+ * the constructor and `set()`. We always produce hostOnly=false when domain
62
+ * starts with `.` in the source array (Patchright emits leading-dot domains
63
+ * for domain cookies); strip the dot here so the rest of the matching logic
64
+ * runs on a normalised form.
65
+ */
66
+ declare function entryFromPlaywright(c: any): {
67
+ name: string;
68
+ value: string;
69
+ domain: any;
70
+ path: any;
71
+ expires: any;
72
+ secure: boolean;
73
+ httpOnly: boolean;
74
+ sameSite: any;
75
+ hostOnly: boolean;
76
+ };
77
+ export {};