perplexity-user-mcp 0.8.44 → 0.8.48
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/dist/browser-window.d.ts +10 -0
- package/dist/checks/probe.d.ts +17 -0
- package/dist/checks/probe.mjs +29 -0
- package/dist/{chunk-E75J42W5.mjs → chunk-D2ZQGKHM.mjs} +2 -2
- package/dist/{chunk-WHVJ724K.mjs → chunk-GBHPJ7I7.mjs} +55 -7
- package/dist/chunk-KVV3JBSN.mjs +32 -0
- package/dist/{chunk-2B5OQUXR.mjs → chunk-P6YOLJ5T.mjs} +2 -2
- package/dist/{chunk-FNHYUE22.mjs → chunk-QXYMYCHC.mjs} +2 -2
- package/dist/{chunk-2OVLCZHU.mjs → chunk-SCZQCV7M.mjs} +1 -1
- package/dist/{chunk-2EE7MNP2.mjs → chunk-YD25G5AD.mjs} +1 -1
- package/dist/client.d.ts +12 -0
- package/dist/client.mjs +4 -1
- package/dist/cloud-sync.mjs +3 -2
- package/dist/daemon/attach.mjs +6 -5
- package/dist/daemon/client-http.mjs +6 -5
- package/dist/daemon/index.mjs +7 -6
- package/dist/daemon/launcher.mjs +5 -4
- package/dist/daemon/server.mjs +4 -3
- package/dist/doctor.mjs +1 -1
- package/dist/fs-utils.d.ts +41 -5
- package/dist/index.mjs +7 -6
- package/dist/login-runner.mjs +5 -25
- package/package.json +1 -1
- /package/dist/{chunk-KSNV3ZVY.mjs → chunk-6CAXNBDD.mjs} +0 -0
package/dist/browser-window.d.ts
CHANGED
|
@@ -1 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chromium launch args for the headed login / cookie-grab window.
|
|
3
|
+
*
|
|
4
|
+
* @param {boolean} localOrigin — true when the login target is a local mock
|
|
5
|
+
* origin (127.0.0.1 / localhost). Those runs are already headless with no
|
|
6
|
+
* window, so no positioning is needed.
|
|
7
|
+
* @returns {string[]}
|
|
8
|
+
*/
|
|
9
|
+
export function loginLaunchArgs(localOrigin: boolean): string[];
|
|
1
10
|
export function minimizePageWindow(page: any): Promise<boolean>;
|
|
11
|
+
export const OFFSCREEN_POSITION_ARG: "--window-position=-32000,-32000";
|
package/dist/checks/probe.d.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* True when a LIVE daemon owns the SAME profile's browser session the probe
|
|
3
|
+
* would launch against. The daemon holds the `browser-data` profile via a
|
|
4
|
+
* long-lived launchPersistentContext; an independent probe launching its own
|
|
5
|
+
* context on the SAME --user-data-dir collides on the Chromium singleton lock
|
|
6
|
+
* (issue #8 — Windows exitCode 21). When this returns true the probe must NOT
|
|
7
|
+
* launch its own browser; the daemon's real auth state is already surfaced by
|
|
8
|
+
* the `profiles` check (daemon-status.json).
|
|
9
|
+
*
|
|
10
|
+
* The daemon.lock is global (one daemon) and records no profile, but the
|
|
11
|
+
* daemon follows the active-profile pointer — it only holds the lock for the
|
|
12
|
+
* ACTIVE profile. The probe's PerplexityClient launches against
|
|
13
|
+
* `PERPLEXITY_PROFILE || active`, so a probe explicitly targeting a DIFFERENT
|
|
14
|
+
* profile uses a different browser-data dir and will NOT collide. Guard only
|
|
15
|
+
* when the probe's effective profile matches the active profile.
|
|
16
|
+
*/
|
|
17
|
+
export function liveDaemonOwnsProfile(): boolean;
|
|
1
18
|
export function run(opts?: {}): Promise<{
|
|
2
19
|
category: string;
|
|
3
20
|
name: string;
|
package/dist/checks/probe.mjs
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
isStale,
|
|
3
|
+
read
|
|
4
|
+
} from "../chunk-NMKNEEZB.mjs";
|
|
5
|
+
import {
|
|
6
|
+
getActiveName
|
|
7
|
+
} from "../chunk-E3GRJXXJ.mjs";
|
|
1
8
|
import "../chunk-4UEJOM6W.mjs";
|
|
2
9
|
|
|
3
10
|
// src/checks/probe.js
|
|
4
11
|
var CATEGORY = "probe";
|
|
12
|
+
function liveDaemonOwnsProfile() {
|
|
13
|
+
try {
|
|
14
|
+
const record = read();
|
|
15
|
+
if (!record || isStale(record)) return false;
|
|
16
|
+
const active = getActiveName() ?? "default";
|
|
17
|
+
const probeProfile = process.env.PERPLEXITY_PROFILE ?? active;
|
|
18
|
+
return probeProfile === active;
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
5
23
|
async function defaultSearch({ timeoutMs }) {
|
|
6
24
|
const { PerplexityClient } = await import("../client.mjs");
|
|
7
25
|
const client = new PerplexityClient();
|
|
@@ -38,6 +56,16 @@ async function run(opts = {}) {
|
|
|
38
56
|
if (!opts.probe) {
|
|
39
57
|
return [{ category: CATEGORY, name: "probe-search", status: "skip", message: "skipped (pass --probe to enable)" }];
|
|
40
58
|
}
|
|
59
|
+
const daemonOwns = opts.daemonOwnsOverride ?? liveDaemonOwnsProfile;
|
|
60
|
+
if (daemonOwns()) {
|
|
61
|
+
return [{
|
|
62
|
+
category: CATEGORY,
|
|
63
|
+
name: "probe-search",
|
|
64
|
+
status: "skip",
|
|
65
|
+
message: "skipped \u2014 a live daemon owns this profile's browser session",
|
|
66
|
+
hint: "An independent probe would collide with the daemon on the browser-data profile lock (issue #8). The daemon's live auth state is shown under the 'profiles' check (daemon-status). To run a standalone probe, stop the daemon first, then re-run with --probe."
|
|
67
|
+
}];
|
|
68
|
+
}
|
|
41
69
|
const timeoutMs = opts.timeoutMs ?? 1e4;
|
|
42
70
|
const search = opts.searchOverride ?? defaultSearch;
|
|
43
71
|
try {
|
|
@@ -78,5 +106,6 @@ async function run(opts = {}) {
|
|
|
78
106
|
}
|
|
79
107
|
}
|
|
80
108
|
export {
|
|
109
|
+
liveDaemonOwnsProfile,
|
|
81
110
|
run
|
|
82
111
|
};
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
getPackageVersion,
|
|
15
15
|
startDaemonServer
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-P6YOLJ5T.mjs";
|
|
17
17
|
import {
|
|
18
18
|
ensureToken,
|
|
19
19
|
getTokenPath,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
} from "./chunk-3LUO5ATM.mjs";
|
|
26
26
|
import {
|
|
27
27
|
PerplexityClient
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-GBHPJ7I7.mjs";
|
|
29
29
|
import {
|
|
30
30
|
getActiveName,
|
|
31
31
|
getConfigDir
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import {
|
|
2
|
+
OFFSCREEN_POSITION_ARG
|
|
3
|
+
} from "./chunk-KVV3JBSN.mjs";
|
|
1
4
|
import {
|
|
2
5
|
impitFetchJson,
|
|
3
6
|
isImpitAvailable
|
|
@@ -36,7 +39,7 @@ import { join as join2 } from "path";
|
|
|
36
39
|
// src/fs-utils.js
|
|
37
40
|
import { unlinkSync } from "fs";
|
|
38
41
|
import { join } from "path";
|
|
39
|
-
var SINGLETON_FILES = ["SingletonLock", "SingletonCookie", "SingletonSocket"];
|
|
42
|
+
var SINGLETON_FILES = ["SingletonLock", "SingletonCookie", "SingletonSocket", "lockfile"];
|
|
40
43
|
function clearStaleSingletonLocks(dir) {
|
|
41
44
|
for (const name of SINGLETON_FILES) {
|
|
42
45
|
try {
|
|
@@ -48,6 +51,42 @@ function clearStaleSingletonLocks(dir) {
|
|
|
48
51
|
}
|
|
49
52
|
}
|
|
50
53
|
}
|
|
54
|
+
var defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
55
|
+
var LOCK_CONTENTION_RE = /target page, context or browser has been closed|processsingleton|profile.*(in use|already)|singletonlock|already running|exit(ed)?(?:\s+(?:with\s+)?code)?\s*21\b/i;
|
|
56
|
+
function isLockContentionError(err) {
|
|
57
|
+
if (!err) return false;
|
|
58
|
+
const msg = typeof err === "string" ? err : err.message ?? String(err);
|
|
59
|
+
return LOCK_CONTENTION_RE.test(msg);
|
|
60
|
+
}
|
|
61
|
+
async function launchWithRetry(launch, opts = {}) {
|
|
62
|
+
const {
|
|
63
|
+
retries = 3,
|
|
64
|
+
baseDelayMs = 200,
|
|
65
|
+
sleep = defaultSleep,
|
|
66
|
+
isRetriable = isLockContentionError,
|
|
67
|
+
beforeAttempt
|
|
68
|
+
} = opts;
|
|
69
|
+
let lastErr;
|
|
70
|
+
for (let attempt = 0; attempt <= retries; attempt++) {
|
|
71
|
+
if (beforeAttempt) {
|
|
72
|
+
try {
|
|
73
|
+
beforeAttempt(attempt);
|
|
74
|
+
} catch {
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
try {
|
|
78
|
+
return await launch(attempt);
|
|
79
|
+
} catch (err) {
|
|
80
|
+
lastErr = err;
|
|
81
|
+
if (attempt === retries || !isRetriable(err)) throw err;
|
|
82
|
+
console.error(
|
|
83
|
+
`[perplexity-mcp] Browser launch hit a profile-lock collision (attempt ${attempt + 1}/${retries + 1}); retrying after backoff.`
|
|
84
|
+
);
|
|
85
|
+
await sleep(baseDelayMs * 2 ** attempt);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
throw lastErr;
|
|
89
|
+
}
|
|
51
90
|
|
|
52
91
|
// src/client.ts
|
|
53
92
|
function getActiveProfileName() {
|
|
@@ -102,7 +141,13 @@ function buildLaunchOptions(headless) {
|
|
|
102
141
|
const browser = findBrowser();
|
|
103
142
|
const opts = {
|
|
104
143
|
headless,
|
|
105
|
-
|
|
144
|
+
// The headed branch is the CF-solving bootstrap (Phase 1 / daemon session
|
|
145
|
+
// refresh). It paints a real window, which the user sees flash while they
|
|
146
|
+
// work (issue #9). Position it off-screen so the background refresh is
|
|
147
|
+
// invisible — like the already-headless search path. Headless launches
|
|
148
|
+
// have no window, so the positioning arg is omitted there. We move the
|
|
149
|
+
// window rather than shrink/hide it; see OFFSCREEN_POSITION_ARG.
|
|
150
|
+
args: headless ? STEALTH_ARGS : [...STEALTH_ARGS, OFFSCREEN_POSITION_ARG],
|
|
106
151
|
viewport: headless ? { width: 1920, height: 1080 } : { width: 800, height: 600 },
|
|
107
152
|
userAgent: USER_AGENT,
|
|
108
153
|
// Strip --enable-automation (Playwright default) which is a CF red flag
|
|
@@ -574,9 +619,9 @@ var PerplexityClient = class _PerplexityClient {
|
|
|
574
619
|
}
|
|
575
620
|
console.error("[perplexity-mcp] Launching headless persistent browser...");
|
|
576
621
|
const launchOpts = buildLaunchOptions(true);
|
|
577
|
-
this.context = await
|
|
578
|
-
activePaths.browserData,
|
|
579
|
-
|
|
622
|
+
this.context = await launchWithRetry(
|
|
623
|
+
() => chromium.launchPersistentContext(activePaths.browserData, launchOpts),
|
|
624
|
+
{ beforeAttempt: () => clearStaleSingletonLocks(activePaths.browserData) }
|
|
580
625
|
);
|
|
581
626
|
this.browser = this.context.browser();
|
|
582
627
|
const saved = await getSavedCookies();
|
|
@@ -619,8 +664,10 @@ var PerplexityClient = class _PerplexityClient {
|
|
|
619
664
|
let ctx = null;
|
|
620
665
|
try {
|
|
621
666
|
const browserData = getActivePaths().browserData;
|
|
622
|
-
|
|
623
|
-
|
|
667
|
+
ctx = await launchWithRetry(
|
|
668
|
+
() => chromium.launchPersistentContext(browserData, buildLaunchOptions(false)),
|
|
669
|
+
{ beforeAttempt: () => clearStaleSingletonLocks(browserData) }
|
|
670
|
+
);
|
|
624
671
|
const page = ctx.pages()[0] || await ctx.newPage();
|
|
625
672
|
await page.goto(PERPLEXITY_URL, { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
626
673
|
let cfResolved = false;
|
|
@@ -1980,6 +2027,7 @@ View at: ${PERPLEXITY_URL}/search/${threadSlug}`,
|
|
|
1980
2027
|
|
|
1981
2028
|
export {
|
|
1982
2029
|
readCachedAccountInfoFromDisk,
|
|
2030
|
+
buildLaunchOptions,
|
|
1983
2031
|
listCloudThreadsViaImpit,
|
|
1984
2032
|
getCloudThreadViaImpit,
|
|
1985
2033
|
isExperimentalImpitSearchEnabled,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// src/browser-window.js
|
|
2
|
+
var OFFSCREEN_POSITION_ARG = "--window-position=-32000,-32000";
|
|
3
|
+
function loginLaunchArgs(localOrigin) {
|
|
4
|
+
if (localOrigin) return [];
|
|
5
|
+
return ["--start-minimized", OFFSCREEN_POSITION_ARG];
|
|
6
|
+
}
|
|
7
|
+
async function minimizePageWindow(page) {
|
|
8
|
+
try {
|
|
9
|
+
const context = page?.context?.();
|
|
10
|
+
if (!context || typeof context.newCDPSession !== "function") return false;
|
|
11
|
+
const session = await context.newCDPSession(page);
|
|
12
|
+
try {
|
|
13
|
+
const { windowId } = await session.send("Browser.getWindowForTarget");
|
|
14
|
+
await session.send("Browser.setWindowBounds", {
|
|
15
|
+
windowId,
|
|
16
|
+
bounds: { windowState: "minimized" }
|
|
17
|
+
});
|
|
18
|
+
return true;
|
|
19
|
+
} finally {
|
|
20
|
+
await session.detach().catch(() => {
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {
|
|
29
|
+
OFFSCREEN_POSITION_ARG,
|
|
30
|
+
loginLaunchArgs,
|
|
31
|
+
minimizePageWindow
|
|
32
|
+
};
|
|
@@ -11,13 +11,13 @@ import {
|
|
|
11
11
|
import {
|
|
12
12
|
hydrateCloudHistoryEntry,
|
|
13
13
|
syncCloudHistory
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-YD25G5AD.mjs";
|
|
15
15
|
import {
|
|
16
16
|
PerplexityClient,
|
|
17
17
|
exportThreadViaImpit,
|
|
18
18
|
readCachedAccountInfoFromDisk,
|
|
19
19
|
retrieveThreadViaImpit
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-GBHPJ7I7.mjs";
|
|
21
21
|
import {
|
|
22
22
|
append,
|
|
23
23
|
findPendingByThread,
|
package/dist/client.d.ts
CHANGED
|
@@ -13,6 +13,18 @@ import { type SearchResult, type AccountInfo } from "./config.js";
|
|
|
13
13
|
* (refresh.ts) and by login-runner.js after a fresh login.
|
|
14
14
|
*/
|
|
15
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>;
|
|
16
28
|
export interface ListAskThreadsItem {
|
|
17
29
|
backendUuid: string;
|
|
18
30
|
contextUuid: string;
|
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,7 +8,8 @@ import {
|
|
|
7
8
|
readCachedAccountInfoFromDisk,
|
|
8
9
|
retrieveThreadViaImpit,
|
|
9
10
|
searchPerplexityViaImpit
|
|
10
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GBHPJ7I7.mjs";
|
|
12
|
+
import "./chunk-KVV3JBSN.mjs";
|
|
11
13
|
import "./chunk-V4LHDNWJ.mjs";
|
|
12
14
|
import "./chunk-GBI2U336.mjs";
|
|
13
15
|
import "./chunk-DXR6EEZH.mjs";
|
|
@@ -17,6 +19,7 @@ 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,
|
package/dist/cloud-sync.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import {
|
|
2
2
|
hydrateCloudHistoryEntry,
|
|
3
3
|
syncCloudHistory
|
|
4
|
-
} from "./chunk-
|
|
5
|
-
import "./chunk-
|
|
4
|
+
} from "./chunk-YD25G5AD.mjs";
|
|
5
|
+
import "./chunk-GBHPJ7I7.mjs";
|
|
6
|
+
import "./chunk-KVV3JBSN.mjs";
|
|
6
7
|
import "./chunk-V4LHDNWJ.mjs";
|
|
7
8
|
import "./chunk-6E6XTHTG.mjs";
|
|
8
9
|
import "./chunk-GBI2U336.mjs";
|
package/dist/daemon/attach.mjs
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DaemonAttachError,
|
|
3
3
|
attachToDaemon
|
|
4
|
-
} from "../chunk-
|
|
5
|
-
import "../chunk-
|
|
4
|
+
} from "../chunk-SCZQCV7M.mjs";
|
|
5
|
+
import "../chunk-D2ZQGKHM.mjs";
|
|
6
6
|
import "../chunk-LGH5BSUY.mjs";
|
|
7
7
|
import "../chunk-6YMQVLFX.mjs";
|
|
8
8
|
import "../chunk-TIWHN4IW.mjs";
|
|
9
9
|
import "../chunk-NMKNEEZB.mjs";
|
|
10
|
-
import "../chunk-
|
|
10
|
+
import "../chunk-P6YOLJ5T.mjs";
|
|
11
11
|
import "../chunk-TSLRTZYR.mjs";
|
|
12
12
|
import "../chunk-DKEJZ4FI.mjs";
|
|
13
13
|
import "../chunk-3LUO5ATM.mjs";
|
|
14
|
-
import "../chunk-
|
|
15
|
-
import "../chunk-
|
|
14
|
+
import "../chunk-YD25G5AD.mjs";
|
|
15
|
+
import "../chunk-GBHPJ7I7.mjs";
|
|
16
|
+
import "../chunk-KVV3JBSN.mjs";
|
|
16
17
|
import "../chunk-V4LHDNWJ.mjs";
|
|
17
18
|
import "../chunk-6E6XTHTG.mjs";
|
|
18
19
|
import "../chunk-GBI2U336.mjs";
|
|
@@ -2,18 +2,19 @@ import {
|
|
|
2
2
|
exportHistoryViaDaemon,
|
|
3
3
|
hydrateCloudHistoryEntryViaDaemon,
|
|
4
4
|
syncCloudHistoryViaDaemon
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-QXYMYCHC.mjs";
|
|
6
|
+
import "../chunk-D2ZQGKHM.mjs";
|
|
7
7
|
import "../chunk-LGH5BSUY.mjs";
|
|
8
8
|
import "../chunk-6YMQVLFX.mjs";
|
|
9
9
|
import "../chunk-TIWHN4IW.mjs";
|
|
10
10
|
import "../chunk-NMKNEEZB.mjs";
|
|
11
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-P6YOLJ5T.mjs";
|
|
12
12
|
import "../chunk-TSLRTZYR.mjs";
|
|
13
13
|
import "../chunk-DKEJZ4FI.mjs";
|
|
14
14
|
import "../chunk-3LUO5ATM.mjs";
|
|
15
|
-
import "../chunk-
|
|
16
|
-
import "../chunk-
|
|
15
|
+
import "../chunk-YD25G5AD.mjs";
|
|
16
|
+
import "../chunk-GBHPJ7I7.mjs";
|
|
17
|
+
import "../chunk-KVV3JBSN.mjs";
|
|
17
18
|
import "../chunk-V4LHDNWJ.mjs";
|
|
18
19
|
import "../chunk-6E6XTHTG.mjs";
|
|
19
20
|
import "../chunk-GBI2U336.mjs";
|
package/dist/daemon/index.mjs
CHANGED
|
@@ -2,10 +2,10 @@ import {
|
|
|
2
2
|
exportHistoryViaDaemon,
|
|
3
3
|
hydrateCloudHistoryEntryViaDaemon,
|
|
4
4
|
syncCloudHistoryViaDaemon
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-QXYMYCHC.mjs";
|
|
6
6
|
import {
|
|
7
7
|
attachToDaemon
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-SCZQCV7M.mjs";
|
|
9
9
|
import {
|
|
10
10
|
disableDaemonTunnel,
|
|
11
11
|
enableDaemonTunnel,
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
rotateDaemonToken,
|
|
22
22
|
startDaemon,
|
|
23
23
|
stopDaemon
|
|
24
|
-
} from "../chunk-
|
|
24
|
+
} from "../chunk-D2ZQGKHM.mjs";
|
|
25
25
|
import "../chunk-LGH5BSUY.mjs";
|
|
26
26
|
import {
|
|
27
27
|
extractTunnelUrl,
|
|
@@ -43,7 +43,7 @@ import {
|
|
|
43
43
|
} from "../chunk-NMKNEEZB.mjs";
|
|
44
44
|
import {
|
|
45
45
|
startDaemonServer
|
|
46
|
-
} from "../chunk-
|
|
46
|
+
} from "../chunk-P6YOLJ5T.mjs";
|
|
47
47
|
import {
|
|
48
48
|
appendAuditEntry,
|
|
49
49
|
getAuditLogPath,
|
|
@@ -57,8 +57,9 @@ import {
|
|
|
57
57
|
rotateToken
|
|
58
58
|
} from "../chunk-DKEJZ4FI.mjs";
|
|
59
59
|
import "../chunk-3LUO5ATM.mjs";
|
|
60
|
-
import "../chunk-
|
|
61
|
-
import "../chunk-
|
|
60
|
+
import "../chunk-YD25G5AD.mjs";
|
|
61
|
+
import "../chunk-GBHPJ7I7.mjs";
|
|
62
|
+
import "../chunk-KVV3JBSN.mjs";
|
|
62
63
|
import "../chunk-V4LHDNWJ.mjs";
|
|
63
64
|
import "../chunk-6E6XTHTG.mjs";
|
|
64
65
|
import "../chunk-GBI2U336.mjs";
|
package/dist/daemon/launcher.mjs
CHANGED
|
@@ -13,17 +13,18 @@ import {
|
|
|
13
13
|
rotateDaemonToken,
|
|
14
14
|
startDaemon,
|
|
15
15
|
stopDaemon
|
|
16
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-D2ZQGKHM.mjs";
|
|
17
17
|
import "../chunk-LGH5BSUY.mjs";
|
|
18
18
|
import "../chunk-6YMQVLFX.mjs";
|
|
19
19
|
import "../chunk-TIWHN4IW.mjs";
|
|
20
20
|
import "../chunk-NMKNEEZB.mjs";
|
|
21
|
-
import "../chunk-
|
|
21
|
+
import "../chunk-P6YOLJ5T.mjs";
|
|
22
22
|
import "../chunk-TSLRTZYR.mjs";
|
|
23
23
|
import "../chunk-DKEJZ4FI.mjs";
|
|
24
24
|
import "../chunk-3LUO5ATM.mjs";
|
|
25
|
-
import "../chunk-
|
|
26
|
-
import "../chunk-
|
|
25
|
+
import "../chunk-YD25G5AD.mjs";
|
|
26
|
+
import "../chunk-GBHPJ7I7.mjs";
|
|
27
|
+
import "../chunk-KVV3JBSN.mjs";
|
|
27
28
|
import "../chunk-V4LHDNWJ.mjs";
|
|
28
29
|
import "../chunk-6E6XTHTG.mjs";
|
|
29
30
|
import "../chunk-GBI2U336.mjs";
|
package/dist/daemon/server.mjs
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
resolveRequestResource,
|
|
3
3
|
startDaemonServer
|
|
4
|
-
} from "../chunk-
|
|
4
|
+
} from "../chunk-P6YOLJ5T.mjs";
|
|
5
5
|
import "../chunk-TSLRTZYR.mjs";
|
|
6
6
|
import "../chunk-DKEJZ4FI.mjs";
|
|
7
|
-
import "../chunk-
|
|
8
|
-
import "../chunk-
|
|
7
|
+
import "../chunk-YD25G5AD.mjs";
|
|
8
|
+
import "../chunk-GBHPJ7I7.mjs";
|
|
9
|
+
import "../chunk-KVV3JBSN.mjs";
|
|
9
10
|
import "../chunk-V4LHDNWJ.mjs";
|
|
10
11
|
import "../chunk-6E6XTHTG.mjs";
|
|
11
12
|
import "../chunk-GBI2U336.mjs";
|
package/dist/doctor.mjs
CHANGED
package/dist/fs-utils.d.ts
CHANGED
|
@@ -1,8 +1,44 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Remove stale Chromium
|
|
3
|
-
* user-data-dir. Chromium
|
|
4
|
-
* an active instance, so a stale lock from an
|
|
5
|
-
*
|
|
6
|
-
* and only carry exclusivity (not state), so
|
|
2
|
+
* Remove stale Chromium singleton / profile-lock files from a persistent
|
|
3
|
+
* user-data-dir. Chromium refuses to start (POSIX: silent exit 0; Windows:
|
|
4
|
+
* exit 21) when these files claim an active instance, so a stale lock from an
|
|
5
|
+
* unclean previous exit breaks `launchPersistentContext`. The files are
|
|
6
|
+
* recreated on every launch and only carry exclusivity (not state), so
|
|
7
|
+
* deleting them pre-launch is safe. On Windows a file still held open by a
|
|
8
|
+
* LIVE process cannot be unlinked (EPERM/EACCES) — that throw is swallowed
|
|
9
|
+
* below, and the caller's retry handles the brief post-close release lag.
|
|
7
10
|
*/
|
|
8
11
|
export function clearStaleSingletonLocks(dir: any): void;
|
|
12
|
+
/**
|
|
13
|
+
* True when `err` looks like a transient Chromium profile-lock collision that
|
|
14
|
+
* is worth retrying after clearing stale locks (issue #8).
|
|
15
|
+
* @param {unknown} err
|
|
16
|
+
* @returns {boolean}
|
|
17
|
+
*/
|
|
18
|
+
export function isLockContentionError(err: unknown): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Run `launch` with bounded retry + exponential backoff, retrying ONLY
|
|
21
|
+
* transient lock-contention failures. On Windows, closing a persistent
|
|
22
|
+
* context does not release the profile lock synchronously, so relaunching on
|
|
23
|
+
* the same --user-data-dir can momentarily collide; retrying after clearing
|
|
24
|
+
* stale locks recovers without a full restart (issue #8). Non-lock errors
|
|
25
|
+
* (missing executable, network) are rethrown immediately — no pointless waits.
|
|
26
|
+
*
|
|
27
|
+
* @template T
|
|
28
|
+
* @param {(attempt: number) => Promise<T> | T} launch
|
|
29
|
+
* @param {{
|
|
30
|
+
* retries?: number,
|
|
31
|
+
* baseDelayMs?: number,
|
|
32
|
+
* sleep?: (ms: number) => Promise<void>,
|
|
33
|
+
* isRetriable?: (err: unknown) => boolean,
|
|
34
|
+
* beforeAttempt?: (attempt: number) => void,
|
|
35
|
+
* }} [opts]
|
|
36
|
+
* @returns {Promise<T>}
|
|
37
|
+
*/
|
|
38
|
+
export function launchWithRetry<T>(launch: (attempt: number) => Promise<T> | T, opts?: {
|
|
39
|
+
retries?: number;
|
|
40
|
+
baseDelayMs?: number;
|
|
41
|
+
sleep?: (ms: number) => Promise<void>;
|
|
42
|
+
isRetriable?: (err: unknown) => boolean;
|
|
43
|
+
beforeAttempt?: (attempt: number) => void;
|
|
44
|
+
}): Promise<T>;
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
CATEGORIES,
|
|
4
4
|
formatReportMarkdown,
|
|
5
5
|
runAll
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-6CAXNBDD.mjs";
|
|
7
7
|
import {
|
|
8
8
|
buildIssueBody,
|
|
9
9
|
buildIssueUrl,
|
|
@@ -12,11 +12,11 @@ import {
|
|
|
12
12
|
} from "./chunk-DPGMKSSA.mjs";
|
|
13
13
|
import {
|
|
14
14
|
attachToDaemon
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-SCZQCV7M.mjs";
|
|
16
16
|
import {
|
|
17
17
|
ensureDaemon,
|
|
18
18
|
startDaemon
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-D2ZQGKHM.mjs";
|
|
20
20
|
import "./chunk-LGH5BSUY.mjs";
|
|
21
21
|
import "./chunk-6YMQVLFX.mjs";
|
|
22
22
|
import "./chunk-TIWHN4IW.mjs";
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
registerTools,
|
|
36
36
|
saveToolConfig,
|
|
37
37
|
watchToolConfig
|
|
38
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-P6YOLJ5T.mjs";
|
|
39
39
|
import "./chunk-TSLRTZYR.mjs";
|
|
40
40
|
import "./chunk-DKEJZ4FI.mjs";
|
|
41
41
|
import {
|
|
@@ -49,10 +49,11 @@ import "./chunk-HMKLWVXB.mjs";
|
|
|
49
49
|
import {
|
|
50
50
|
hydrateCloudHistoryEntry,
|
|
51
51
|
syncCloudHistory
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-YD25G5AD.mjs";
|
|
53
53
|
import {
|
|
54
54
|
PerplexityClient
|
|
55
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-GBHPJ7I7.mjs";
|
|
56
|
+
import "./chunk-KVV3JBSN.mjs";
|
|
56
57
|
import {
|
|
57
58
|
getImpitRuntimeDir,
|
|
58
59
|
getModelsCacheInfo,
|
package/dist/login-runner.mjs
CHANGED
|
@@ -6,6 +6,10 @@ import {
|
|
|
6
6
|
import {
|
|
7
7
|
redact
|
|
8
8
|
} from "./chunk-HMKLWVXB.mjs";
|
|
9
|
+
import {
|
|
10
|
+
loginLaunchArgs,
|
|
11
|
+
minimizePageWindow
|
|
12
|
+
} from "./chunk-KVV3JBSN.mjs";
|
|
9
13
|
import {
|
|
10
14
|
resolveBrowserExecutable
|
|
11
15
|
} from "./chunk-DXR6EEZH.mjs";
|
|
@@ -23,30 +27,6 @@ import "./chunk-4UEJOM6W.mjs";
|
|
|
23
27
|
// src/login-runner.js
|
|
24
28
|
import { writeFileSync, existsSync, mkdirSync } from "fs";
|
|
25
29
|
import { chromium } from "patchright";
|
|
26
|
-
|
|
27
|
-
// src/browser-window.js
|
|
28
|
-
async function minimizePageWindow(page) {
|
|
29
|
-
try {
|
|
30
|
-
const context = page?.context?.();
|
|
31
|
-
if (!context || typeof context.newCDPSession !== "function") return false;
|
|
32
|
-
const session = await context.newCDPSession(page);
|
|
33
|
-
try {
|
|
34
|
-
const { windowId } = await session.send("Browser.getWindowForTarget");
|
|
35
|
-
await session.send("Browser.setWindowBounds", {
|
|
36
|
-
windowId,
|
|
37
|
-
bounds: { windowState: "minimized" }
|
|
38
|
-
});
|
|
39
|
-
return true;
|
|
40
|
-
} finally {
|
|
41
|
-
await session.detach().catch(() => {
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
} catch {
|
|
45
|
-
return false;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// src/login-runner.js
|
|
50
30
|
var ORIGIN = process.env.PERPLEXITY_ORIGIN || "https://www.perplexity.ai";
|
|
51
31
|
var LOGIN_PATH = process.env.PERPLEXITY_LOGIN_PATH || "/account";
|
|
52
32
|
var EMAIL = process.env.PERPLEXITY_EMAIL;
|
|
@@ -104,7 +84,7 @@ async function main() {
|
|
|
104
84
|
ignoreHTTPSErrors: true,
|
|
105
85
|
...executablePath ? { executablePath } : {},
|
|
106
86
|
...channel && ["chrome", "msedge", "chromium"].includes(channel) ? { channel } : {},
|
|
107
|
-
args: localOrigin
|
|
87
|
+
args: loginLaunchArgs(localOrigin)
|
|
108
88
|
});
|
|
109
89
|
const page = await ctx.newPage();
|
|
110
90
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "perplexity-user-mcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.48",
|
|
4
4
|
"mcpName": "io.github.Automations-Project/perplexity-user-mcp",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Perplexity AI MCP server — browser automation for search, reasoning, research, and compute. Not affiliated with Perplexity AI, Inc.",
|
|
File without changes
|