perplexity-user-mcp 0.8.36
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -0
- package/dist/attachments.d.ts +20 -0
- package/dist/attachments.mjs +43 -0
- package/dist/checks/browser.d.ts +100 -0
- package/dist/checks/browser.mjs +89 -0
- package/dist/checks/config.d.ts +91 -0
- package/dist/checks/config.mjs +88 -0
- package/dist/checks/ide.d.ts +89 -0
- package/dist/checks/ide.mjs +80 -0
- package/dist/checks/mcp.d.ts +61 -0
- package/dist/checks/mcp.mjs +56 -0
- package/dist/checks/native-deps.d.ts +131 -0
- package/dist/checks/native-deps.mjs +115 -0
- package/dist/checks/network.d.ts +71 -0
- package/dist/checks/network.mjs +70 -0
- package/dist/checks/probe.d.ts +93 -0
- package/dist/checks/probe.mjs +82 -0
- package/dist/checks/profiles.d.ts +99 -0
- package/dist/checks/profiles.mjs +90 -0
- package/dist/checks/runtime.d.ts +89 -0
- package/dist/checks/runtime.mjs +90 -0
- package/dist/checks/vault.d.ts +101 -0
- package/dist/checks/vault.mjs +90 -0
- package/dist/chunk-3B276PGG.mjs +115 -0
- package/dist/chunk-4UEJOM6W.mjs +9 -0
- package/dist/chunk-6EP2BLTV.mjs +205 -0
- package/dist/chunk-6YMQVLFX.mjs +146 -0
- package/dist/chunk-7JL36EBH.mjs +118 -0
- package/dist/chunk-DPGMKSSA.mjs +57 -0
- package/dist/chunk-H4BUAPPO.mjs +1950 -0
- package/dist/chunk-HMKLWVXB.mjs +109 -0
- package/dist/chunk-HTUAQRKH.mjs +125 -0
- package/dist/chunk-HU5B4FXS.mjs +139 -0
- package/dist/chunk-KCXM2M4B.mjs +1006 -0
- package/dist/chunk-LKJMLGFP.mjs +237 -0
- package/dist/chunk-LZPLNZ5U.mjs +67 -0
- package/dist/chunk-MTDFKNXX.mjs +19 -0
- package/dist/chunk-OF4DMAPJ.mjs +511 -0
- package/dist/chunk-PE23RMXY.mjs +43 -0
- package/dist/chunk-Q2VY4R5F.mjs +175 -0
- package/dist/chunk-S5VD7WTU.mjs +2540 -0
- package/dist/chunk-SVPRB62V.mjs +106 -0
- package/dist/chunk-TQLCLE4L.mjs +345 -0
- package/dist/chunk-U3DGFLXZ.mjs +43 -0
- package/dist/chunk-X45O6YD3.mjs +688 -0
- package/dist/chunk-XKSWCEGI.mjs +168 -0
- package/dist/chunk-Z7DAACGZ.mjs +534 -0
- package/dist/chunk-ZQFUZPLO.mjs +257 -0
- package/dist/cli.d.ts +952 -0
- package/dist/cli.mjs +827 -0
- package/dist/client.d.ts +355 -0
- package/dist/client.mjs +27 -0
- package/dist/cloud-sync.d-Cqt6y18U.d.ts +42 -0
- package/dist/cloud-sync.d.ts +42 -0
- package/dist/cloud-sync.mjs +17 -0
- package/dist/config.d.ts +186 -0
- package/dist/config.mjs +54 -0
- package/dist/daemon/attach.d.ts +36 -0
- package/dist/daemon/attach.mjs +25 -0
- package/dist/daemon/audit.d.ts +23 -0
- package/dist/daemon/audit.mjs +12 -0
- package/dist/daemon/client-http.d.ts +42 -0
- package/dist/daemon/client-http.mjs +29 -0
- package/dist/daemon/index.d.ts +14 -0
- package/dist/daemon/index.mjs +110 -0
- package/dist/daemon/install-tunnel.d.ts +46 -0
- package/dist/daemon/install-tunnel.mjs +14 -0
- package/dist/daemon/launcher.d.ts +163 -0
- package/dist/daemon/launcher.mjs +50 -0
- package/dist/daemon/lockfile.d.ts +29 -0
- package/dist/daemon/lockfile.mjs +18 -0
- package/dist/daemon/server.d.ts +159 -0
- package/dist/daemon/server.mjs +20 -0
- package/dist/daemon/token.d.ts +17 -0
- package/dist/daemon/token.mjs +17 -0
- package/dist/daemon/tunnel-providers/index.d.ts +330 -0
- package/dist/daemon/tunnel-providers/index.mjs +57 -0
- package/dist/daemon/tunnel.d.ts +23 -0
- package/dist/daemon/tunnel.mjs +9 -0
- package/dist/doctor-report.d.ts +24 -0
- package/dist/doctor-report.mjs +14 -0
- package/dist/doctor.d-CXmUqOXX.d.ts +43 -0
- package/dist/doctor.d.ts +44 -0
- package/dist/doctor.mjs +16 -0
- package/dist/export.d.ts +19 -0
- package/dist/export.mjs +15 -0
- package/dist/health-check.d.ts +108 -0
- package/dist/health-check.mjs +92 -0
- package/dist/history-store.d-BzjBF2m3.d.ts +65 -0
- package/dist/history-store.d.ts +65 -0
- package/dist/history-store.mjs +48 -0
- package/dist/impit-login-runner.d.ts +469 -0
- package/dist/impit-login-runner.mjs +685 -0
- package/dist/index.d.ts +159 -0
- package/dist/index.mjs +236 -0
- package/dist/login-runner.d.ts +333 -0
- package/dist/login-runner.mjs +320 -0
- package/dist/logout.d.ts +28 -0
- package/dist/logout.mjs +45 -0
- package/dist/manual-login-runner.d.ts +150 -0
- package/dist/manual-login-runner.mjs +146 -0
- package/dist/native-deps-BNThFHxa.d.ts +175 -0
- package/dist/native-deps-YNKXITRY.mjs +139 -0
- package/dist/profiles.d-DqS1oZWr.d.ts +41 -0
- package/dist/profiles.d.ts +41 -0
- package/dist/profiles.mjs +33 -0
- package/dist/redact.d.ts +159 -0
- package/dist/redact.mjs +11 -0
- package/dist/refresh.d.ts +118 -0
- package/dist/refresh.mjs +21 -0
- package/dist/reinit-watcher.d.ts +15 -0
- package/dist/reinit-watcher.mjs +8 -0
- package/dist/session-metadata-B9aV_n5g.d.ts +148 -0
- package/dist/tty-prompt.d.ts +44 -0
- package/dist/tty-prompt.mjs +39 -0
- package/dist/vault.d-BtRSLZiM.d.ts +8 -0
- package/dist/vault.d.ts +37 -0
- package/dist/vault.mjs +21 -0
- package/dist/viewer-detect.d-HWGnyFAA.d.ts +4 -0
- package/dist/viewer-detect.d.ts +4 -0
- package/dist/viewer-detect.mjs +37 -0
- package/dist/viewers.d-BGCK6sw6.d.ts +10 -0
- package/dist/viewers.d.ts +18 -0
- package/dist/viewers.mjs +122 -0
- package/package.json +152 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
type DoctorStatus = "pass" | "warn" | "fail" | "skip";
|
|
2
|
+
|
|
3
|
+
type DoctorCategory =
|
|
4
|
+
| "runtime" | "config" | "profiles" | "vault" | "browser"
|
|
5
|
+
| "native-deps" | "network" | "ide" | "mcp" | "probe";
|
|
6
|
+
|
|
7
|
+
interface DoctorCheck {
|
|
8
|
+
category: DoctorCategory;
|
|
9
|
+
name: string;
|
|
10
|
+
status: DoctorStatus;
|
|
11
|
+
message: string;
|
|
12
|
+
detail?: Record<string, unknown>;
|
|
13
|
+
hint?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DoctorReport {
|
|
17
|
+
overall: DoctorStatus;
|
|
18
|
+
generatedAt: string;
|
|
19
|
+
durationMs: number;
|
|
20
|
+
activeProfile: string | null;
|
|
21
|
+
probeRan: boolean;
|
|
22
|
+
byCategory: Record<DoctorCategory, {
|
|
23
|
+
status: DoctorStatus;
|
|
24
|
+
checks: DoctorCheck[];
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface RunAllOpts {
|
|
29
|
+
configDir?: string;
|
|
30
|
+
profile?: string;
|
|
31
|
+
probe?: boolean;
|
|
32
|
+
allProfiles?: boolean;
|
|
33
|
+
ideStatuses?: Record<string, unknown>;
|
|
34
|
+
baseDir?: string;
|
|
35
|
+
injected?: Partial<Record<DoctorCategory, DoctorCheck[]>>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare const CATEGORIES: ReadonlyArray<DoctorCategory>;
|
|
39
|
+
declare function exitCodeFor(report: { overall: DoctorStatus }): number;
|
|
40
|
+
declare function runAll(opts?: RunAllOpts): Promise<DoctorReport>;
|
|
41
|
+
declare function formatReportMarkdown(report: DoctorReport): string;
|
|
42
|
+
|
|
43
|
+
export { CATEGORIES, type DoctorCategory, type DoctorCheck, type DoctorReport, type DoctorStatus, type RunAllOpts, exitCodeFor, formatReportMarkdown, runAll };
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
type DoctorStatus = "pass" | "warn" | "fail" | "skip";
|
|
2
|
+
|
|
3
|
+
type DoctorCategory =
|
|
4
|
+
| "runtime" | "config" | "profiles" | "vault" | "browser"
|
|
5
|
+
| "native-deps" | "network" | "ide" | "mcp" | "probe";
|
|
6
|
+
|
|
7
|
+
interface DoctorCheck {
|
|
8
|
+
category: DoctorCategory;
|
|
9
|
+
name: string;
|
|
10
|
+
status: DoctorStatus;
|
|
11
|
+
message: string;
|
|
12
|
+
detail?: Record<string, unknown>;
|
|
13
|
+
hint?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface DoctorReport {
|
|
17
|
+
overall: DoctorStatus;
|
|
18
|
+
generatedAt: string;
|
|
19
|
+
durationMs: number;
|
|
20
|
+
activeProfile: string | null;
|
|
21
|
+
probeRan: boolean;
|
|
22
|
+
byCategory: Record<DoctorCategory, {
|
|
23
|
+
status: DoctorStatus;
|
|
24
|
+
checks: DoctorCheck[];
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface RunAllOpts {
|
|
29
|
+
configDir?: string;
|
|
30
|
+
profile?: string;
|
|
31
|
+
probe?: boolean;
|
|
32
|
+
allProfiles?: boolean;
|
|
33
|
+
ideStatuses?: Record<string, unknown>;
|
|
34
|
+
baseDir?: string;
|
|
35
|
+
injected?: Partial<Record<DoctorCategory, DoctorCheck[]>>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare const CATEGORIES: ReadonlyArray<DoctorCategory>;
|
|
39
|
+
declare function rollupStatus(statuses: DoctorStatus[]): DoctorStatus;
|
|
40
|
+
declare function exitCodeFor(report: { overall: DoctorStatus }): number;
|
|
41
|
+
declare function runAll(opts?: RunAllOpts): Promise<DoctorReport>;
|
|
42
|
+
declare function formatReportMarkdown(report: DoctorReport): string;
|
|
43
|
+
|
|
44
|
+
export { CATEGORIES, type DoctorCategory, type DoctorCheck, type DoctorReport, type DoctorStatus, type RunAllOpts, exitCodeFor, formatReportMarkdown, rollupStatus, runAll };
|
package/dist/doctor.mjs
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
CATEGORIES,
|
|
3
|
+
exitCodeFor,
|
|
4
|
+
formatReportMarkdown,
|
|
5
|
+
rollupStatus,
|
|
6
|
+
runAll
|
|
7
|
+
} from "./chunk-7JL36EBH.mjs";
|
|
8
|
+
import "./chunk-XKSWCEGI.mjs";
|
|
9
|
+
import "./chunk-4UEJOM6W.mjs";
|
|
10
|
+
export {
|
|
11
|
+
CATEGORIES,
|
|
12
|
+
exitCodeFor,
|
|
13
|
+
formatReportMarkdown,
|
|
14
|
+
rollupStatus,
|
|
15
|
+
runAll
|
|
16
|
+
};
|
package/dist/export.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
type ExportFormat = "pdf" | "markdown" | "docx";
|
|
2
|
+
|
|
3
|
+
interface ExportResult {
|
|
4
|
+
buffer: Buffer;
|
|
5
|
+
filename: string;
|
|
6
|
+
contentType: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
declare const FORMAT_TO_CONTENT_TYPE: Record<ExportFormat, string>;
|
|
10
|
+
declare function resolveExportApiFormat(format: ExportFormat): "pdf" | "md" | "docx";
|
|
11
|
+
declare function exportThread(options: {
|
|
12
|
+
entryUuid: string;
|
|
13
|
+
format: ExportFormat;
|
|
14
|
+
fetchImpl?: (input: string, init?: RequestInit) => Promise<Response>;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
headers?: HeadersInit;
|
|
17
|
+
}): Promise<ExportResult>;
|
|
18
|
+
|
|
19
|
+
export { type ExportFormat, type ExportResult, FORMAT_TO_CONTENT_TYPE, exportThread, resolveExportApiFormat };
|
package/dist/export.mjs
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FORMAT_TO_CONTENT_TYPE,
|
|
3
|
+
exportThread,
|
|
4
|
+
resolveExportApiFormat
|
|
5
|
+
} from "./chunk-LZPLNZ5U.mjs";
|
|
6
|
+
import "./chunk-LKJMLGFP.mjs";
|
|
7
|
+
import "./chunk-TQLCLE4L.mjs";
|
|
8
|
+
import "./chunk-MTDFKNXX.mjs";
|
|
9
|
+
import "./chunk-XKSWCEGI.mjs";
|
|
10
|
+
import "./chunk-4UEJOM6W.mjs";
|
|
11
|
+
export {
|
|
12
|
+
FORMAT_TO_CONTENT_TYPE,
|
|
13
|
+
exportThread,
|
|
14
|
+
resolveExportApiFormat
|
|
15
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { chromium } from 'patchright';
|
|
3
|
+
import { Vault } from './vault.d-BtRSLZiM.js';
|
|
4
|
+
import { getProfilePaths, getActiveName } from './profiles.d-DqS1oZWr.js';
|
|
5
|
+
import { getOrCreateContext, findBrowser } from './config.js';
|
|
6
|
+
import { redact } from './redact.js';
|
|
7
|
+
import { c as collectSessionMetadata } from './session-metadata-B9aV_n5g.js';
|
|
8
|
+
|
|
9
|
+
// Spawnable health-check runner. Reads the active profile's vault cookies,
|
|
10
|
+
// launches a NON-persistent Chromium, injects cookies, probes auth + rest
|
|
11
|
+
// endpoints, writes models-cache.json on success, emits one JSON line,
|
|
12
|
+
// and exits. Never touches the long-lived MCP server's browser profile dir.
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
const ORIGIN = process.env.PERPLEXITY_ORIGIN || "https://www.perplexity.ai";
|
|
16
|
+
const LOGIN_PATH = process.env.PERPLEXITY_LOGIN_PATH || "/account";
|
|
17
|
+
|
|
18
|
+
function resolveProfile() {
|
|
19
|
+
return process.env.PERPLEXITY_PROFILE || getActiveName() || "default";
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Launch a browser suitable for the health check. Respects
|
|
24
|
+
* PERPLEXITY_BROWSER_CHANNEL / PERPLEXITY_BROWSER_PATH overrides from the
|
|
25
|
+
* extension's AuthManager.
|
|
26
|
+
*/
|
|
27
|
+
async function launchHealthBrowser() {
|
|
28
|
+
const probe = findBrowser();
|
|
29
|
+
return chromium.launch({
|
|
30
|
+
headless: true,
|
|
31
|
+
...(probe ? { executablePath: probe.path } : {}),
|
|
32
|
+
...(probe && ["chrome", "msedge", "chromium"].includes(probe.channel)
|
|
33
|
+
? { channel: probe.channel }
|
|
34
|
+
: {}),
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function main() {
|
|
39
|
+
const PROFILE = resolveProfile();
|
|
40
|
+
const vault = new Vault();
|
|
41
|
+
const cookiesRaw = await vault.get(PROFILE, "cookies").catch(() => null);
|
|
42
|
+
if (!cookiesRaw) {
|
|
43
|
+
emit({ valid: false, reason: "no_cookies" });
|
|
44
|
+
process.exit(2);
|
|
45
|
+
}
|
|
46
|
+
const cookies = JSON.parse(cookiesRaw);
|
|
47
|
+
if (!Array.isArray(cookies) || cookies.length === 0) {
|
|
48
|
+
emit({ valid: false, reason: "no_cookies" });
|
|
49
|
+
process.exit(2);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const browser = await launchHealthBrowser();
|
|
53
|
+
let result;
|
|
54
|
+
try {
|
|
55
|
+
const ctx = await getOrCreateContext(browser);
|
|
56
|
+
// Patchright's addCookies wants EITHER url OR (domain+path), not both.
|
|
57
|
+
// Pass cookies with domain/url already set through untouched; only
|
|
58
|
+
// synthesize a url from ORIGIN when neither is present. Additionally,
|
|
59
|
+
// Chromium rejects `__Secure-`-prefixed cookies with `secure:false` —
|
|
60
|
+
// force the flag so imports from other tools stay usable (Chromium
|
|
61
|
+
// treats localhost/127.0.0.1 as secure origins, so the cookie will
|
|
62
|
+
// still be delivered over plain HTTP in tests).
|
|
63
|
+
const normalized = cookies.map((c) => {
|
|
64
|
+
const withSecure = c.name?.startsWith("__Secure-") ? { ...c, secure: true } : c;
|
|
65
|
+
return (withSecure.url || withSecure.domain) ? withSecure : { ...withSecure, url: `${ORIGIN}${withSecure.path ?? "/"}` };
|
|
66
|
+
});
|
|
67
|
+
await ctx.addCookies(normalized);
|
|
68
|
+
const page = await ctx.newPage();
|
|
69
|
+
// Navigate to an origin URL so page-context fetches are same-origin
|
|
70
|
+
// (required for `credentials: "include"` to attach the cookies we just
|
|
71
|
+
// injected). The default path `/account` exists on production; mock
|
|
72
|
+
// integration tests override via PERPLEXITY_LOGIN_PATH to point at the
|
|
73
|
+
// mock's `/login` route.
|
|
74
|
+
await page.goto(`${ORIGIN}${LOGIN_PATH}`, { waitUntil: "domcontentloaded" }).catch(() => {});
|
|
75
|
+
|
|
76
|
+
const metadata = await collectSessionMetadata(page, ORIGIN, { sessionTimeoutMs: 4_000 });
|
|
77
|
+
|
|
78
|
+
if (!metadata.sessionData?.user?.id) {
|
|
79
|
+
result = { valid: false, reason: "expired" };
|
|
80
|
+
} else {
|
|
81
|
+
result = {
|
|
82
|
+
valid: true,
|
|
83
|
+
tier: metadata.tier,
|
|
84
|
+
modelCount: Object.keys(metadata.models?.models ?? {}).length,
|
|
85
|
+
rateLimits: metadata.rateLimits ?? null,
|
|
86
|
+
};
|
|
87
|
+
try {
|
|
88
|
+
const paths = getProfilePaths(PROFILE);
|
|
89
|
+
if (!existsSync(paths.dir)) mkdirSync(paths.dir, { recursive: true });
|
|
90
|
+
writeFileSync(paths.modelsCache, JSON.stringify(metadata.cache, null, 2));
|
|
91
|
+
} catch {}
|
|
92
|
+
}
|
|
93
|
+
} finally {
|
|
94
|
+
await browser.close().catch(() => {});
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
emit(result);
|
|
98
|
+
process.exit(result.valid ? 0 : 2);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function emit(obj) {
|
|
102
|
+
process.stdout.write(JSON.stringify(obj) + "\n");
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
main().catch((err) => {
|
|
106
|
+
emit({ valid: false, reason: "crash", error: redact(String(err?.message ?? err)) });
|
|
107
|
+
process.exit(5);
|
|
108
|
+
});
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {
|
|
2
|
+
collectSessionMetadata
|
|
3
|
+
} from "./chunk-HU5B4FXS.mjs";
|
|
4
|
+
import {
|
|
5
|
+
redact
|
|
6
|
+
} from "./chunk-HMKLWVXB.mjs";
|
|
7
|
+
import {
|
|
8
|
+
findBrowser,
|
|
9
|
+
getOrCreateContext
|
|
10
|
+
} from "./chunk-LKJMLGFP.mjs";
|
|
11
|
+
import {
|
|
12
|
+
Vault
|
|
13
|
+
} from "./chunk-TQLCLE4L.mjs";
|
|
14
|
+
import "./chunk-MTDFKNXX.mjs";
|
|
15
|
+
import {
|
|
16
|
+
getActiveName,
|
|
17
|
+
getProfilePaths
|
|
18
|
+
} from "./chunk-XKSWCEGI.mjs";
|
|
19
|
+
import "./chunk-4UEJOM6W.mjs";
|
|
20
|
+
|
|
21
|
+
// src/health-check.js
|
|
22
|
+
import { writeFileSync, existsSync, mkdirSync } from "fs";
|
|
23
|
+
import { chromium } from "patchright";
|
|
24
|
+
var ORIGIN = process.env.PERPLEXITY_ORIGIN || "https://www.perplexity.ai";
|
|
25
|
+
var LOGIN_PATH = process.env.PERPLEXITY_LOGIN_PATH || "/account";
|
|
26
|
+
function resolveProfile() {
|
|
27
|
+
return process.env.PERPLEXITY_PROFILE || getActiveName() || "default";
|
|
28
|
+
}
|
|
29
|
+
async function launchHealthBrowser() {
|
|
30
|
+
const probe = findBrowser();
|
|
31
|
+
return chromium.launch({
|
|
32
|
+
headless: true,
|
|
33
|
+
...probe ? { executablePath: probe.path } : {},
|
|
34
|
+
...probe && ["chrome", "msedge", "chromium"].includes(probe.channel) ? { channel: probe.channel } : {}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async function main() {
|
|
38
|
+
const PROFILE = resolveProfile();
|
|
39
|
+
const vault = new Vault();
|
|
40
|
+
const cookiesRaw = await vault.get(PROFILE, "cookies").catch(() => null);
|
|
41
|
+
if (!cookiesRaw) {
|
|
42
|
+
emit({ valid: false, reason: "no_cookies" });
|
|
43
|
+
process.exit(2);
|
|
44
|
+
}
|
|
45
|
+
const cookies = JSON.parse(cookiesRaw);
|
|
46
|
+
if (!Array.isArray(cookies) || cookies.length === 0) {
|
|
47
|
+
emit({ valid: false, reason: "no_cookies" });
|
|
48
|
+
process.exit(2);
|
|
49
|
+
}
|
|
50
|
+
const browser = await launchHealthBrowser();
|
|
51
|
+
let result;
|
|
52
|
+
try {
|
|
53
|
+
const ctx = await getOrCreateContext(browser);
|
|
54
|
+
const normalized = cookies.map((c) => {
|
|
55
|
+
const withSecure = c.name?.startsWith("__Secure-") ? { ...c, secure: true } : c;
|
|
56
|
+
return withSecure.url || withSecure.domain ? withSecure : { ...withSecure, url: `${ORIGIN}${withSecure.path ?? "/"}` };
|
|
57
|
+
});
|
|
58
|
+
await ctx.addCookies(normalized);
|
|
59
|
+
const page = await ctx.newPage();
|
|
60
|
+
await page.goto(`${ORIGIN}${LOGIN_PATH}`, { waitUntil: "domcontentloaded" }).catch(() => {
|
|
61
|
+
});
|
|
62
|
+
const metadata = await collectSessionMetadata(page, ORIGIN, { sessionTimeoutMs: 4e3 });
|
|
63
|
+
if (!metadata.sessionData?.user?.id) {
|
|
64
|
+
result = { valid: false, reason: "expired" };
|
|
65
|
+
} else {
|
|
66
|
+
result = {
|
|
67
|
+
valid: true,
|
|
68
|
+
tier: metadata.tier,
|
|
69
|
+
modelCount: Object.keys(metadata.models?.models ?? {}).length,
|
|
70
|
+
rateLimits: metadata.rateLimits ?? null
|
|
71
|
+
};
|
|
72
|
+
try {
|
|
73
|
+
const paths = getProfilePaths(PROFILE);
|
|
74
|
+
if (!existsSync(paths.dir)) mkdirSync(paths.dir, { recursive: true });
|
|
75
|
+
writeFileSync(paths.modelsCache, JSON.stringify(metadata.cache, null, 2));
|
|
76
|
+
} catch {
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
} finally {
|
|
80
|
+
await browser.close().catch(() => {
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
emit(result);
|
|
84
|
+
process.exit(result.valid ? 0 : 2);
|
|
85
|
+
}
|
|
86
|
+
function emit(obj) {
|
|
87
|
+
process.stdout.write(JSON.stringify(obj) + "\n");
|
|
88
|
+
}
|
|
89
|
+
main().catch((err) => {
|
|
90
|
+
emit({ valid: false, reason: "crash", error: redact(String(err?.message ?? err)) });
|
|
91
|
+
process.exit(5);
|
|
92
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { HistoryItem, HistoryEntryDetail } from '@perplexity-user-mcp/shared';
|
|
2
|
+
|
|
3
|
+
interface HistoryStoreEntryInput extends Partial<HistoryItem> {
|
|
4
|
+
tool: string;
|
|
5
|
+
query: string;
|
|
6
|
+
body?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface RebuildIndexResult {
|
|
10
|
+
scanned: number;
|
|
11
|
+
recovered: number;
|
|
12
|
+
skipped: number;
|
|
13
|
+
items: Array<HistoryItem & { filename: string }>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const HISTORY_LIMIT: number;
|
|
17
|
+
declare function getHistoryDir(): string;
|
|
18
|
+
declare function getAttachmentsRoot(): string;
|
|
19
|
+
declare function getIndexPath(): string;
|
|
20
|
+
declare function append(entry: HistoryStoreEntryInput): HistoryItem;
|
|
21
|
+
declare function update(id: string, patch?: Partial<HistoryStoreEntryInput> & { body?: string }): HistoryItem | null;
|
|
22
|
+
declare function list(options?: {
|
|
23
|
+
limit?: number;
|
|
24
|
+
status?: "completed" | "pending" | "failed";
|
|
25
|
+
tool?: string;
|
|
26
|
+
tools?: string[];
|
|
27
|
+
filter?: string;
|
|
28
|
+
}): HistoryItem[];
|
|
29
|
+
declare function get(id: string): HistoryEntryDetail | null;
|
|
30
|
+
declare function deleteEntry(id: string): boolean;
|
|
31
|
+
declare function pin(id: string, pinned: boolean): HistoryItem | null;
|
|
32
|
+
declare function tag(id: string, tags: string[]): HistoryItem | null;
|
|
33
|
+
declare function rebuildIndex(): RebuildIndexResult;
|
|
34
|
+
declare function getMdPath(id: string): string | null;
|
|
35
|
+
declare function getAttachmentsDir(id: string): string | null;
|
|
36
|
+
declare function findPendingByThread(threadSlug: string): HistoryItem | null;
|
|
37
|
+
declare function countAll(): number;
|
|
38
|
+
declare function appendHistory(entry: HistoryStoreEntryInput): HistoryItem;
|
|
39
|
+
declare function readHistory(limit?: number): HistoryItem[];
|
|
40
|
+
|
|
41
|
+
interface CloudUpsertMeta {
|
|
42
|
+
backendUuid: string;
|
|
43
|
+
query?: string;
|
|
44
|
+
answerPreview?: string;
|
|
45
|
+
createdAt?: string;
|
|
46
|
+
threadUrl?: string;
|
|
47
|
+
threadSlug?: string | null;
|
|
48
|
+
readWriteToken?: string | null;
|
|
49
|
+
mode?: string | null;
|
|
50
|
+
model?: string | null;
|
|
51
|
+
sourceCount?: number;
|
|
52
|
+
status?: "completed" | "pending" | "failed";
|
|
53
|
+
tool?: string;
|
|
54
|
+
tier?: HistoryItem["tier"];
|
|
55
|
+
language?: string | null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare function findByBackendUuid(backendUuid: string | null | undefined): (HistoryItem & { filename: string }) | null;
|
|
59
|
+
declare function upsertFromCloud(meta: CloudUpsertMeta): { action: "inserted" | "updated" | "skipped-local"; id: string };
|
|
60
|
+
declare function hydrateCloudEntry(
|
|
61
|
+
id: string,
|
|
62
|
+
payload: { body?: string; sources?: HistoryItem["sources"]; attachments?: HistoryItem["attachments"]; answerPreview?: string; sourceCount?: number },
|
|
63
|
+
): HistoryItem | null;
|
|
64
|
+
|
|
65
|
+
export { type CloudUpsertMeta, HISTORY_LIMIT, type HistoryStoreEntryInput, type RebuildIndexResult, append, appendHistory, countAll, deleteEntry, findByBackendUuid, findPendingByThread, get, getAttachmentsDir, getAttachmentsRoot, getHistoryDir, getIndexPath, getMdPath, hydrateCloudEntry, list, pin, readHistory, rebuildIndex, tag, update, upsertFromCloud };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { HistoryItem, HistoryEntryDetail } from '@perplexity-user-mcp/shared';
|
|
2
|
+
|
|
3
|
+
interface HistoryStoreEntryInput extends Partial<HistoryItem> {
|
|
4
|
+
tool: string;
|
|
5
|
+
query: string;
|
|
6
|
+
body?: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface RebuildIndexResult {
|
|
10
|
+
scanned: number;
|
|
11
|
+
recovered: number;
|
|
12
|
+
skipped: number;
|
|
13
|
+
items: Array<HistoryItem & { filename: string }>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare const HISTORY_LIMIT: number;
|
|
17
|
+
declare function getHistoryDir(): string;
|
|
18
|
+
declare function getAttachmentsRoot(): string;
|
|
19
|
+
declare function getIndexPath(): string;
|
|
20
|
+
declare function append(entry: HistoryStoreEntryInput): HistoryItem;
|
|
21
|
+
declare function update(id: string, patch?: Partial<HistoryStoreEntryInput> & { body?: string }): HistoryItem | null;
|
|
22
|
+
declare function list(options?: {
|
|
23
|
+
limit?: number;
|
|
24
|
+
status?: "completed" | "pending" | "failed";
|
|
25
|
+
tool?: string;
|
|
26
|
+
tools?: string[];
|
|
27
|
+
filter?: string;
|
|
28
|
+
}): HistoryItem[];
|
|
29
|
+
declare function get(id: string): HistoryEntryDetail | null;
|
|
30
|
+
declare function deleteEntry(id: string): boolean;
|
|
31
|
+
declare function pin(id: string, pinned: boolean): HistoryItem | null;
|
|
32
|
+
declare function tag(id: string, tags: string[]): HistoryItem | null;
|
|
33
|
+
declare function rebuildIndex(): RebuildIndexResult;
|
|
34
|
+
declare function getMdPath(id: string): string | null;
|
|
35
|
+
declare function getAttachmentsDir(id: string): string | null;
|
|
36
|
+
declare function findPendingByThread(threadSlug: string): HistoryItem | null;
|
|
37
|
+
declare function countAll(): number;
|
|
38
|
+
declare function appendHistory(entry: HistoryStoreEntryInput): HistoryItem;
|
|
39
|
+
declare function readHistory(limit?: number): HistoryItem[];
|
|
40
|
+
|
|
41
|
+
interface CloudUpsertMeta {
|
|
42
|
+
backendUuid: string;
|
|
43
|
+
query?: string;
|
|
44
|
+
answerPreview?: string;
|
|
45
|
+
createdAt?: string;
|
|
46
|
+
threadUrl?: string;
|
|
47
|
+
threadSlug?: string | null;
|
|
48
|
+
readWriteToken?: string | null;
|
|
49
|
+
mode?: string | null;
|
|
50
|
+
model?: string | null;
|
|
51
|
+
sourceCount?: number;
|
|
52
|
+
status?: "completed" | "pending" | "failed";
|
|
53
|
+
tool?: string;
|
|
54
|
+
tier?: HistoryItem["tier"];
|
|
55
|
+
language?: string | null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
declare function findByBackendUuid(backendUuid: string | null | undefined): (HistoryItem & { filename: string }) | null;
|
|
59
|
+
declare function upsertFromCloud(meta: CloudUpsertMeta): { action: "inserted" | "updated" | "skipped-local"; id: string };
|
|
60
|
+
declare function hydrateCloudEntry(
|
|
61
|
+
id: string,
|
|
62
|
+
payload: { body?: string; sources?: HistoryItem["sources"]; attachments?: HistoryItem["attachments"]; answerPreview?: string; sourceCount?: number },
|
|
63
|
+
): HistoryItem | null;
|
|
64
|
+
|
|
65
|
+
export { type CloudUpsertMeta, HISTORY_LIMIT, type HistoryStoreEntryInput, type RebuildIndexResult, append, appendHistory, countAll, deleteEntry, findByBackendUuid, findPendingByThread, get, getAttachmentsDir, getAttachmentsRoot, getHistoryDir, getIndexPath, getMdPath, hydrateCloudEntry, list, pin, readHistory, rebuildIndex, tag, update, upsertFromCloud };
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import {
|
|
2
|
+
HISTORY_LIMIT,
|
|
3
|
+
append,
|
|
4
|
+
appendHistory,
|
|
5
|
+
countAll,
|
|
6
|
+
deleteEntry,
|
|
7
|
+
findByBackendUuid,
|
|
8
|
+
findPendingByThread,
|
|
9
|
+
get,
|
|
10
|
+
getAttachmentsDir,
|
|
11
|
+
getAttachmentsRoot,
|
|
12
|
+
getHistoryDir,
|
|
13
|
+
getIndexPath,
|
|
14
|
+
getMdPath,
|
|
15
|
+
hydrateCloudEntry,
|
|
16
|
+
list,
|
|
17
|
+
pin,
|
|
18
|
+
readHistory,
|
|
19
|
+
rebuildIndex,
|
|
20
|
+
tag,
|
|
21
|
+
update,
|
|
22
|
+
upsertFromCloud
|
|
23
|
+
} from "./chunk-OF4DMAPJ.mjs";
|
|
24
|
+
import "./chunk-XKSWCEGI.mjs";
|
|
25
|
+
import "./chunk-4UEJOM6W.mjs";
|
|
26
|
+
export {
|
|
27
|
+
HISTORY_LIMIT,
|
|
28
|
+
append,
|
|
29
|
+
appendHistory,
|
|
30
|
+
countAll,
|
|
31
|
+
deleteEntry,
|
|
32
|
+
findByBackendUuid,
|
|
33
|
+
findPendingByThread,
|
|
34
|
+
get,
|
|
35
|
+
getAttachmentsDir,
|
|
36
|
+
getAttachmentsRoot,
|
|
37
|
+
getHistoryDir,
|
|
38
|
+
getIndexPath,
|
|
39
|
+
getMdPath,
|
|
40
|
+
hydrateCloudEntry,
|
|
41
|
+
list,
|
|
42
|
+
pin,
|
|
43
|
+
readHistory,
|
|
44
|
+
rebuildIndex,
|
|
45
|
+
tag,
|
|
46
|
+
update,
|
|
47
|
+
upsertFromCloud
|
|
48
|
+
};
|