perplexity-user-mcp 0.8.42 → 0.8.44
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/attachments.d.ts +10 -20
- package/dist/browser-window.d.ts +1 -0
- package/dist/cf-warmup.d.ts +32 -0
- package/dist/checks/browser.d.ts +12 -100
- package/dist/checks/config.d.ts +25 -91
- package/dist/checks/ide.d.ts +31 -89
- package/dist/checks/mcp.d.ts +12 -61
- package/dist/checks/native-deps.d.ts +46 -131
- package/dist/checks/network.d.ts +13 -71
- package/dist/checks/probe.d.ts +20 -92
- package/dist/checks/profiles.d.ts +13 -99
- package/dist/checks/profiles.mjs +35 -0
- package/dist/checks/runtime.d.ts +24 -89
- package/dist/checks/vault.d.ts +13 -142
- package/dist/checks/vault.mjs +6 -11
- package/dist/{chunk-T6ARJK2P.mjs → chunk-2B5OQUXR.mjs} +6 -6
- package/dist/{chunk-2FPGJKCA.mjs → chunk-2EE7MNP2.mjs} +2 -2
- package/dist/{chunk-Z4OLYVB2.mjs → chunk-2OVLCZHU.mjs} +1 -1
- package/dist/{chunk-WDIW33DA.mjs → chunk-3LUO5ATM.mjs} +1 -1
- package/dist/{chunk-B65IJQZJ.mjs → chunk-6E6XTHTG.mjs} +1 -1
- package/dist/{chunk-S677V2JU.mjs → chunk-C5I7KXHK.mjs} +32 -2
- package/dist/{chunk-TDXETAQT.mjs → chunk-DKEJZ4FI.mjs} +1 -1
- package/dist/{chunk-U7QPUNRH.mjs → chunk-DXR6EEZH.mjs} +26 -7
- package/dist/{chunk-HJIXH6CL.mjs → chunk-E3GRJXXJ.mjs} +2 -0
- package/dist/{chunk-RK4EBZJ3.mjs → chunk-E75J42W5.mjs} +11 -8
- package/dist/{chunk-452DK6OS.mjs → chunk-FNHYUE22.mjs} +2 -2
- package/dist/{chunk-D254EFYB.mjs → chunk-GBI2U336.mjs} +1 -1
- package/dist/chunk-GPUGKWXH.mjs +17 -0
- package/dist/{chunk-HNSPNCFH.mjs → chunk-KSNV3ZVY.mjs} +1 -1
- package/dist/{chunk-XTRJSV72.mjs → chunk-LGH5BSUY.mjs} +1 -1
- package/dist/{chunk-KJFX2ZXR.mjs → chunk-NMKNEEZB.mjs} +1 -1
- package/dist/{chunk-FKQ3HP4Q.mjs → chunk-TIWHN4IW.mjs} +1 -1
- package/dist/{chunk-V4U3JM4R.mjs → chunk-TSLRTZYR.mjs} +1 -1
- package/dist/{chunk-DQQISMYN.mjs → chunk-V4LHDNWJ.mjs} +2 -2
- package/dist/{chunk-C3HPFFTD.mjs → chunk-WHVJ724K.mjs} +84 -44
- package/dist/cli.d.ts +14 -1317
- package/dist/cli.mjs +14 -21
- package/dist/client.d.ts +27 -24
- package/dist/client.mjs +6 -6
- package/dist/cloud-sync.d.ts +65 -42
- package/dist/cloud-sync.mjs +8 -8
- package/dist/config.d.ts +35 -39
- package/dist/config.mjs +3 -3
- package/dist/cookie-jar.d.ts +77 -0
- package/dist/daemon/attach.d.ts +5 -12
- package/dist/daemon/attach.mjs +17 -17
- package/dist/daemon/audit.d.ts +5 -7
- package/dist/daemon/audit.mjs +2 -2
- package/dist/daemon/client-http.d.ts +10 -16
- package/dist/daemon/client-http.mjs +17 -17
- package/dist/daemon/index.d.ts +17 -14
- package/dist/daemon/index.mjs +18 -18
- package/dist/daemon/install-tunnel.d.ts +8 -34
- package/dist/daemon/install-tunnel.mjs +2 -2
- package/dist/daemon/launcher.d.ts +24 -29
- package/dist/daemon/launcher.mjs +16 -16
- package/dist/daemon/local-tokens.d.ts +23 -0
- package/dist/daemon/lockfile.d.ts +10 -12
- package/dist/daemon/lockfile.mjs +2 -2
- package/dist/daemon/oauth-consent-cache.d.ts +86 -0
- package/dist/daemon/oauth-provider.d.ts +132 -0
- package/dist/daemon/public-pages.d.ts +9 -0
- package/dist/daemon/security.d.ts +52 -0
- package/dist/daemon/server.d.ts +12 -83
- package/dist/daemon/server.mjs +11 -11
- package/dist/daemon/token.d.ts +7 -9
- package/dist/daemon/token.mjs +2 -2
- package/dist/daemon/tunnel-providers/cloudflared-named-setup.d.ts +140 -0
- package/dist/daemon/tunnel-providers/cloudflared-named.d.ts +45 -0
- package/dist/daemon/tunnel-providers/cloudflared-quick.d.ts +8 -0
- package/dist/daemon/tunnel-providers/index.d.ts +16 -327
- package/dist/daemon/tunnel-providers/index.mjs +3 -3
- package/dist/daemon/tunnel-providers/ngrok-config.d.ts +18 -0
- package/dist/daemon/tunnel-providers/ngrok.d.ts +68 -0
- package/dist/daemon/tunnel-providers/types.d.ts +56 -0
- package/dist/daemon/tunnel.d.ts +5 -7
- package/dist/debug-tracer.d.ts +2 -0
- package/dist/doctor-report.d.ts +17 -22
- package/dist/doctor.d.ts +12 -44
- package/dist/doctor.mjs +2 -2
- package/dist/export.d.ts +11 -18
- package/dist/export.mjs +4 -4
- package/dist/format.d.ts +52 -0
- package/dist/fs-utils.d.ts +8 -0
- package/dist/health-check.d.ts +1 -108
- package/dist/health-check.mjs +3 -3
- package/dist/history-store.d.ts +29 -65
- package/dist/history-store.mjs +2 -2
- package/dist/impit-login-runner.d.ts +1 -469
- package/dist/impit-login-runner.mjs +4 -4
- package/dist/index.d.ts +25 -149
- package/dist/index.mjs +22 -20
- package/dist/is-main-module.d.ts +9 -0
- package/dist/login-runner.d.ts +1 -333
- package/dist/login-runner.mjs +13 -13
- package/dist/login.d.ts +5 -0
- package/dist/logout.d.ts +2 -28
- package/dist/logout.mjs +3 -2
- package/dist/manual-login-runner.d.ts +1 -150
- package/dist/manual-login-runner.mjs +11 -11
- package/dist/{native-deps-IE4B55EL.mjs → native-deps-FCSYDL4W.mjs} +4 -4
- package/dist/native-deps.d.ts +36 -0
- package/dist/package-version.d.ts +1 -0
- package/dist/profiles.d.ts +41 -41
- package/dist/profiles.mjs +1 -1
- package/dist/prompts.d.ts +2 -0
- package/dist/redact.d.ts +14 -142
- package/dist/refresh.d.ts +11 -16
- package/dist/refresh.mjs +4 -4
- package/dist/reinit-watcher.d.ts +15 -24
- package/dist/reinit-watcher.mjs +2 -2
- package/dist/resources.d.ts +5 -0
- package/dist/safe-write.d.ts +16 -0
- package/dist/session-metadata.d.ts +45 -0
- package/dist/tool-config.d.ts +10 -0
- package/dist/tools.d.ts +23 -0
- package/dist/tty-prompt.d.ts +18 -34
- package/dist/vault.d.ts +114 -34
- package/dist/vault.mjs +6 -4
- package/dist/viewer-detect.d.ts +2 -4
- package/dist/viewers.d.ts +13 -18
- package/dist/viewers.mjs +1 -1
- package/package.json +2 -2
- package/dist/cloud-sync.d-Cqt6y18U.d.ts +0 -42
- package/dist/doctor.d-CXmUqOXX.d.ts +0 -43
- package/dist/history-store.d-BzjBF2m3.d.ts +0 -65
- package/dist/native-deps-BNThFHxa.d.ts +0 -175
- package/dist/profiles.d-DqS1oZWr.d.ts +0 -41
- package/dist/session-metadata-B9aV_n5g.d.ts +0 -148
- package/dist/vault.d-BSJWDLhp.d.ts +0 -37
- package/dist/viewer-detect.d-HWGnyFAA.d.ts +0 -4
- package/dist/viewers.d-BGCK6sw6.d.ts +0 -10
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-KSNV3ZVY.mjs";
|
|
7
7
|
import {
|
|
8
8
|
buildIssueBody,
|
|
9
9
|
buildIssueUrl,
|
|
@@ -12,15 +12,15 @@ import {
|
|
|
12
12
|
} from "./chunk-DPGMKSSA.mjs";
|
|
13
13
|
import {
|
|
14
14
|
attachToDaemon
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-2OVLCZHU.mjs";
|
|
16
16
|
import {
|
|
17
17
|
ensureDaemon,
|
|
18
18
|
startDaemon
|
|
19
|
-
} from "./chunk-
|
|
20
|
-
import "./chunk-
|
|
19
|
+
} from "./chunk-E75J42W5.mjs";
|
|
20
|
+
import "./chunk-LGH5BSUY.mjs";
|
|
21
21
|
import "./chunk-6YMQVLFX.mjs";
|
|
22
|
-
import "./chunk-
|
|
23
|
-
import "./chunk-
|
|
22
|
+
import "./chunk-TIWHN4IW.mjs";
|
|
23
|
+
import "./chunk-NMKNEEZB.mjs";
|
|
24
24
|
import {
|
|
25
25
|
buildAnswerPreview,
|
|
26
26
|
buildHistoryBody,
|
|
@@ -35,27 +35,30 @@ import {
|
|
|
35
35
|
registerTools,
|
|
36
36
|
saveToolConfig,
|
|
37
37
|
watchToolConfig
|
|
38
|
-
} from "./chunk-
|
|
39
|
-
import "./chunk-
|
|
40
|
-
import "./chunk-
|
|
38
|
+
} from "./chunk-2B5OQUXR.mjs";
|
|
39
|
+
import "./chunk-TSLRTZYR.mjs";
|
|
40
|
+
import "./chunk-DKEJZ4FI.mjs";
|
|
41
41
|
import {
|
|
42
42
|
watchActiveProfile,
|
|
43
43
|
watchReinit
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-3LUO5ATM.mjs";
|
|
45
|
+
import {
|
|
46
|
+
isMainModule
|
|
47
|
+
} from "./chunk-GPUGKWXH.mjs";
|
|
45
48
|
import "./chunk-HMKLWVXB.mjs";
|
|
46
49
|
import {
|
|
47
50
|
hydrateCloudHistoryEntry,
|
|
48
51
|
syncCloudHistory
|
|
49
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-2EE7MNP2.mjs";
|
|
50
53
|
import {
|
|
51
54
|
PerplexityClient
|
|
52
|
-
} from "./chunk-
|
|
55
|
+
} from "./chunk-WHVJ724K.mjs";
|
|
53
56
|
import {
|
|
54
57
|
getImpitRuntimeDir,
|
|
55
58
|
getModelsCacheInfo,
|
|
56
59
|
isImpitAvailable,
|
|
57
60
|
refreshAccountInfo
|
|
58
|
-
} from "./chunk-
|
|
61
|
+
} from "./chunk-V4LHDNWJ.mjs";
|
|
59
62
|
import {
|
|
60
63
|
append,
|
|
61
64
|
countAll,
|
|
@@ -75,24 +78,23 @@ import {
|
|
|
75
78
|
tag,
|
|
76
79
|
update,
|
|
77
80
|
upsertFromCloud
|
|
78
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-6E6XTHTG.mjs";
|
|
79
82
|
import {
|
|
80
83
|
exportThread
|
|
81
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-GBI2U336.mjs";
|
|
82
85
|
import {
|
|
83
86
|
findBrowser
|
|
84
|
-
} from "./chunk-
|
|
87
|
+
} from "./chunk-DXR6EEZH.mjs";
|
|
85
88
|
import {
|
|
86
89
|
getUnsealMaterial
|
|
87
|
-
} from "./chunk-
|
|
90
|
+
} from "./chunk-C5I7KXHK.mjs";
|
|
88
91
|
import "./chunk-MTDFKNXX.mjs";
|
|
89
92
|
import {
|
|
90
93
|
getActiveName
|
|
91
|
-
} from "./chunk-
|
|
94
|
+
} from "./chunk-E3GRJXXJ.mjs";
|
|
92
95
|
import "./chunk-4UEJOM6W.mjs";
|
|
93
96
|
|
|
94
97
|
// src/index.ts
|
|
95
|
-
import { pathToFileURL } from "url";
|
|
96
98
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
97
99
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
98
100
|
var client;
|
|
@@ -228,7 +230,7 @@ async function main() {
|
|
|
228
230
|
await shutdownClientWithTimeout(client);
|
|
229
231
|
}
|
|
230
232
|
}
|
|
231
|
-
if (
|
|
233
|
+
if (isMainModule(import.meta.url)) {
|
|
232
234
|
runEntrypoint().catch(async (error) => {
|
|
233
235
|
console.error("[perplexity-mcp] Fatal error:", error);
|
|
234
236
|
await shutdownClientWithTimeout(client);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Returns true when the importing module is the process entrypoint (i.e. was
|
|
3
|
+
* invoked as `node <script>` or via a bin symlink), false when it was imported
|
|
4
|
+
* by another module.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} metaUrl - The caller's `import.meta.url`
|
|
7
|
+
* @returns {boolean}
|
|
8
|
+
*/
|
|
9
|
+
export function isMainModule(metaUrl: string): boolean;
|
package/dist/login-runner.d.ts
CHANGED
|
@@ -1,333 +1 @@
|
|
|
1
|
-
|
|
2
|
-
import { chromium } from 'patchright';
|
|
3
|
-
import { Vault } from './vault.d-BSJWDLhp.js';
|
|
4
|
-
import { resolveBrowserExecutable } from './config.js';
|
|
5
|
-
import { recordLoginSuccess, getActiveName, getProfilePaths } from './profiles.d-DqS1oZWr.js';
|
|
6
|
-
import { redact } from './redact.js';
|
|
7
|
-
import { c as collectSessionMetadata, b as buildRuntimeEndpoints, p as pageRequest } from './session-metadata-B9aV_n5g.js';
|
|
8
|
-
|
|
9
|
-
async function minimizePageWindow(page) {
|
|
10
|
-
try {
|
|
11
|
-
const context = page?.context?.();
|
|
12
|
-
if (!context || typeof context.newCDPSession !== "function") return false;
|
|
13
|
-
const session = await context.newCDPSession(page);
|
|
14
|
-
try {
|
|
15
|
-
const { windowId } = await session.send("Browser.getWindowForTarget");
|
|
16
|
-
await session.send("Browser.setWindowBounds", {
|
|
17
|
-
windowId,
|
|
18
|
-
bounds: { windowState: "minimized" },
|
|
19
|
-
});
|
|
20
|
-
return true;
|
|
21
|
-
} finally {
|
|
22
|
-
await session.detach().catch(() => {});
|
|
23
|
-
}
|
|
24
|
-
} catch {
|
|
25
|
-
return false;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Auto-OTP login runner. Parent provides email via PERPLEXITY_EMAIL; we
|
|
30
|
-
// drive the real Perplexity email+OTP flow (NextAuth on the live site,
|
|
31
|
-
// legacy /login/* on the local mock), prompt for the six-digit code via
|
|
32
|
-
// IPC, and persist the resulting session into the profile vault.
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const ORIGIN = process.env.PERPLEXITY_ORIGIN || "https://www.perplexity.ai";
|
|
36
|
-
const LOGIN_PATH = process.env.PERPLEXITY_LOGIN_PATH || "/account";
|
|
37
|
-
const EMAIL = process.env.PERPLEXITY_EMAIL;
|
|
38
|
-
const OTP_TIMEOUT_MS = Number(process.env.PERPLEXITY_OTP_TIMEOUT_MS ?? 300_000);
|
|
39
|
-
const CF_TIMEOUT_MS = Number(process.env.PERPLEXITY_CF_TIMEOUT_MS ?? 20_000);
|
|
40
|
-
const MAX_RETRIES = 2;
|
|
41
|
-
|
|
42
|
-
function resolveProfile() {
|
|
43
|
-
return process.env.PERPLEXITY_PROFILE || getActiveName() || "default";
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
function isLocalOrigin(origin) {
|
|
47
|
-
return /^https?:\/\/(127\.0\.0\.1|localhost)(:\d+)?(?:\/|$)/i.test(origin);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
function ipc(msg) { if (process.send) process.send(msg); }
|
|
51
|
-
function emit(obj) { process.stdout.write(JSON.stringify(obj) + "\n"); }
|
|
52
|
-
|
|
53
|
-
async function awaitOtp() {
|
|
54
|
-
return new Promise((resolve, reject) => {
|
|
55
|
-
const timer = setTimeout(() => {
|
|
56
|
-
process.removeListener("message", handler);
|
|
57
|
-
reject(new Error("otp_timeout"));
|
|
58
|
-
}, OTP_TIMEOUT_MS);
|
|
59
|
-
const handler = (m) => {
|
|
60
|
-
if (m && typeof m.otp === "string") {
|
|
61
|
-
clearTimeout(timer);
|
|
62
|
-
process.removeListener("message", handler);
|
|
63
|
-
resolve(m.otp);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
process.on("message", handler);
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async function main() {
|
|
71
|
-
if (!EMAIL) {
|
|
72
|
-
emit({ ok: false, reason: "no_email" });
|
|
73
|
-
process.exit(1);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
const PROFILE = resolveProfile();
|
|
77
|
-
const localOrigin = isLocalOrigin(ORIGIN);
|
|
78
|
-
|
|
79
|
-
let executablePath;
|
|
80
|
-
let channel;
|
|
81
|
-
if (!localOrigin) {
|
|
82
|
-
try {
|
|
83
|
-
({ path: executablePath, channel } = await resolveBrowserExecutable());
|
|
84
|
-
} catch (err) {
|
|
85
|
-
emit({ ok: false, reason: "chrome_missing", error: redact(String(err?.message ?? err)) });
|
|
86
|
-
process.exit(4);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
const browser = await chromium.launch({
|
|
91
|
-
headless: localOrigin,
|
|
92
|
-
...(executablePath ? { executablePath } : {}),
|
|
93
|
-
...(channel && ["chrome", "msedge", "chromium"].includes(channel) ? { channel } : {}),
|
|
94
|
-
args: localOrigin ? [] : ["--start-minimized"],
|
|
95
|
-
});
|
|
96
|
-
const ctx = await browser.newContext({ ignoreHTTPSErrors: true });
|
|
97
|
-
const page = await ctx.newPage();
|
|
98
|
-
|
|
99
|
-
try {
|
|
100
|
-
await page.goto(`${ORIGIN}${LOGIN_PATH}`, { waitUntil: "domcontentloaded", timeout: 30_000 });
|
|
101
|
-
} catch {}
|
|
102
|
-
if (!localOrigin) await minimizePageWindow(page);
|
|
103
|
-
|
|
104
|
-
const ready = await waitForLoginReady(page);
|
|
105
|
-
if (!ready) {
|
|
106
|
-
const title = await page.title().catch(() => "");
|
|
107
|
-
await browser.close().catch(() => {});
|
|
108
|
-
emit({ ok: false, reason: /just a moment/i.test(title) ? "cf_blocked" : "auto_unsupported" });
|
|
109
|
-
process.exit(/just a moment/i.test(title) ? 3 : 2);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const liveAttempt = await startLiveEmailFlow(page);
|
|
113
|
-
let authFlow = liveAttempt;
|
|
114
|
-
if (liveAttempt.kind === "unsupported") {
|
|
115
|
-
authFlow = await startLegacyMockFlow(page);
|
|
116
|
-
}
|
|
117
|
-
if (!localOrigin) await minimizePageWindow(page);
|
|
118
|
-
|
|
119
|
-
if (authFlow.kind === "sso_required") {
|
|
120
|
-
await browser.close().catch(() => {});
|
|
121
|
-
emit({ ok: false, reason: "sso_required" });
|
|
122
|
-
process.exit(2);
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
if (authFlow.kind === "unsupported") {
|
|
126
|
-
await browser.close().catch(() => {});
|
|
127
|
-
emit({ ok: false, reason: "auto_unsupported", detail: authFlow.detail });
|
|
128
|
-
process.exit(2);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (authFlow.kind === "email_rejected") {
|
|
132
|
-
await browser.close().catch(() => {});
|
|
133
|
-
emit({ ok: false, reason: "email_rejected", detail: authFlow.detail });
|
|
134
|
-
process.exit(2);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
138
|
-
ipc({ phase: "awaiting_otp", attempt });
|
|
139
|
-
let otp;
|
|
140
|
-
try {
|
|
141
|
-
otp = await awaitOtp();
|
|
142
|
-
} catch {
|
|
143
|
-
await browser.close().catch(() => {});
|
|
144
|
-
emit({ ok: false, reason: "otp_timeout" });
|
|
145
|
-
process.exit(2);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
const submitResp = await submitOtp(page, authFlow, otp);
|
|
149
|
-
if (submitResp.ok) {
|
|
150
|
-
const allCookies = await ctx.cookies();
|
|
151
|
-
const metadata = await collectSessionMetadata(page, ORIGIN, {
|
|
152
|
-
sessionData: submitResp.sessionData,
|
|
153
|
-
sessionTimeoutMs: 10_000,
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
const vault = new Vault();
|
|
157
|
-
await vault.set(PROFILE, "cookies", JSON.stringify(allCookies));
|
|
158
|
-
if (metadata.sessionData?.user?.email) await vault.set(PROFILE, "email", metadata.sessionData.user.email);
|
|
159
|
-
if (metadata.sessionData?.user?.id) await vault.set(PROFILE, "userId", metadata.sessionData.user.id);
|
|
160
|
-
|
|
161
|
-
const paths = getProfilePaths(PROFILE);
|
|
162
|
-
if (!existsSync(paths.dir)) mkdirSync(paths.dir, { recursive: true });
|
|
163
|
-
writeFileSync(paths.modelsCache, JSON.stringify(metadata.cache, null, 2));
|
|
164
|
-
recordLoginSuccess(PROFILE, { tier: metadata.tier, loginMode: "auto", lastLogin: new Date().toISOString() });
|
|
165
|
-
writeFileSync(paths.reinit, String(Date.now()));
|
|
166
|
-
|
|
167
|
-
await browser.close().catch(() => {});
|
|
168
|
-
emit({ ok: true, tier: metadata.tier, modelCount: Object.keys(metadata.models?.models ?? {}).length });
|
|
169
|
-
process.exit(0);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
if (authFlow.kind === "live") {
|
|
173
|
-
await page.goto(authFlow.verifyUrl, { waitUntil: "domcontentloaded", timeout: 30_000 }).catch(() => {});
|
|
174
|
-
if (!localOrigin) await minimizePageWindow(page);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
if (attempt === MAX_RETRIES) {
|
|
178
|
-
await browser.close().catch(() => {});
|
|
179
|
-
emit({ ok: false, reason: "otp_rejected" });
|
|
180
|
-
process.exit(2);
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
async function waitForLoginReady(page) {
|
|
186
|
-
const started = Date.now();
|
|
187
|
-
while (Date.now() - started < CF_TIMEOUT_MS) {
|
|
188
|
-
if (await page.locator('input[type="email"]').count().catch(() => 0)) {
|
|
189
|
-
return true;
|
|
190
|
-
}
|
|
191
|
-
const title = await page.title().catch(() => "");
|
|
192
|
-
if (title && !/just a moment/i.test(title)) {
|
|
193
|
-
const body = await page.locator("body").innerText().catch(() => "");
|
|
194
|
-
if (/continue with email/i.test(body) || /single sign-on/i.test(body) || /continue/i.test(body)) {
|
|
195
|
-
return true;
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
await page.waitForTimeout(500);
|
|
199
|
-
}
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
async function startLiveEmailFlow(page) {
|
|
204
|
-
const endpoints = buildRuntimeEndpoints(ORIGIN);
|
|
205
|
-
const csrf = await pageRequest(page, endpoints.csrf);
|
|
206
|
-
if (!(csrf.ok && csrf.contentType.includes("json") && csrf.json?.csrfToken)) {
|
|
207
|
-
return {
|
|
208
|
-
kind: "unsupported",
|
|
209
|
-
detail: { step: "csrf", status: csrf.status, contentType: csrf.contentType, error: csrf.error ?? undefined },
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const sso = await pageRequest(page, endpoints.ssoDetails, {
|
|
214
|
-
method: "POST",
|
|
215
|
-
headers: { "content-type": "application/json" },
|
|
216
|
-
body: JSON.stringify({ email: EMAIL }),
|
|
217
|
-
});
|
|
218
|
-
if (sso.ok && sso.json?.organization) {
|
|
219
|
-
return { kind: "sso_required" };
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const redirectUrl = `${ORIGIN}/account?login-source=settings`;
|
|
223
|
-
const signIn = await pageRequest(page, endpoints.signInEmail, {
|
|
224
|
-
method: "POST",
|
|
225
|
-
headers: { "content-type": "application/json" },
|
|
226
|
-
body: JSON.stringify({
|
|
227
|
-
email: EMAIL,
|
|
228
|
-
useNumericOtp: "true",
|
|
229
|
-
csrfToken: csrf.json.csrfToken,
|
|
230
|
-
callbackUrl: `${redirectUrl}#locale=en-US`,
|
|
231
|
-
json: "true",
|
|
232
|
-
}),
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
if (!(signIn.ok && signIn.contentType.includes("json") && signIn.json?.url)) {
|
|
236
|
-
return {
|
|
237
|
-
kind: signIn.status >= 400 && signIn.status < 500 ? "email_rejected" : "unsupported",
|
|
238
|
-
detail: { step: "signin_email", status: signIn.status, contentType: signIn.contentType, error: signIn.error ?? undefined },
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
const verifyUrl = new URL(signIn.json.url, ORIGIN);
|
|
243
|
-
verifyUrl.searchParams.set("email", EMAIL);
|
|
244
|
-
verifyUrl.searchParams.set("redirectUrl", redirectUrl);
|
|
245
|
-
await page.goto(verifyUrl.toString(), { waitUntil: "domcontentloaded", timeout: 30_000 }).catch(() => {});
|
|
246
|
-
|
|
247
|
-
return {
|
|
248
|
-
kind: "live",
|
|
249
|
-
redirectUrl,
|
|
250
|
-
verifyUrl: verifyUrl.toString(),
|
|
251
|
-
};
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
async function startLegacyMockFlow(page) {
|
|
255
|
-
const emailResp = await pageRequest(page, `${ORIGIN}/login/email`, {
|
|
256
|
-
method: "POST",
|
|
257
|
-
headers: { "content-type": "application/json" },
|
|
258
|
-
body: JSON.stringify({ email: EMAIL }),
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
if (emailResp.redirected && (emailResp.url || "").includes("/sso")) {
|
|
262
|
-
return { kind: "sso_required" };
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
const looksUnsupported =
|
|
266
|
-
emailResp.status === 404 ||
|
|
267
|
-
emailResp.status === 405 ||
|
|
268
|
-
emailResp.status >= 500 ||
|
|
269
|
-
!emailResp.contentType.includes("json");
|
|
270
|
-
|
|
271
|
-
if (looksUnsupported) {
|
|
272
|
-
return {
|
|
273
|
-
kind: "unsupported",
|
|
274
|
-
detail: { step: "legacy_email", status: emailResp.status, contentType: emailResp.contentType, error: emailResp.error ?? undefined },
|
|
275
|
-
};
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
if (!emailResp.ok) {
|
|
279
|
-
return { kind: "email_rejected", detail: emailResp.status };
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
return { kind: "legacy" };
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
async function submitOtp(page, flow, otp) {
|
|
286
|
-
if (flow.kind === "legacy") {
|
|
287
|
-
const submitResp = await pageRequest(page, `${ORIGIN}/login/otp`, {
|
|
288
|
-
method: "POST",
|
|
289
|
-
headers: { "content-type": "application/json" },
|
|
290
|
-
body: JSON.stringify({ email: EMAIL, otp }),
|
|
291
|
-
});
|
|
292
|
-
if (submitResp.status !== 200) {
|
|
293
|
-
return { ok: false };
|
|
294
|
-
}
|
|
295
|
-
const metadata = await collectSessionMetadata(page, ORIGIN, { sessionTimeoutMs: 2_000 });
|
|
296
|
-
return { ok: !!metadata.sessionData?.user?.id, sessionData: metadata.sessionData };
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
const endpoints = buildRuntimeEndpoints(ORIGIN);
|
|
300
|
-
const redirectResp = await pageRequest(page, endpoints.otpRedirectLink, {
|
|
301
|
-
method: "POST",
|
|
302
|
-
headers: { "content-type": "application/json" },
|
|
303
|
-
body: JSON.stringify({
|
|
304
|
-
email: EMAIL,
|
|
305
|
-
otp,
|
|
306
|
-
redirectUrl: flow.redirectUrl,
|
|
307
|
-
emailLoginMethod: "web-otp",
|
|
308
|
-
loginSource: null,
|
|
309
|
-
}),
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
if (!(redirectResp.ok && redirectResp.contentType.includes("json") && redirectResp.json?.redirect)) {
|
|
313
|
-
return { ok: false };
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
const callbackUrl = new URL(redirectResp.json.redirect, ORIGIN).toString();
|
|
317
|
-
await page.goto(callbackUrl, { waitUntil: "domcontentloaded", timeout: 30_000 }).catch(() => {});
|
|
318
|
-
const metadata = await collectSessionMetadata(page, ORIGIN, { sessionTimeoutMs: 5_000 });
|
|
319
|
-
return { ok: !!metadata.sessionData?.user?.id, sessionData: metadata.sessionData };
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
main().catch((err) => {
|
|
323
|
-
const msg = err?.message ?? err;
|
|
324
|
-
const stack = err?.stack;
|
|
325
|
-
emit({
|
|
326
|
-
ok: false,
|
|
327
|
-
reason: "crash",
|
|
328
|
-
error: redact(String(msg ?? "unknown error")),
|
|
329
|
-
detail: redact(String(msg ?? "unknown error")),
|
|
330
|
-
...(stack ? { stack: redact(String(stack)) } : {}),
|
|
331
|
-
});
|
|
332
|
-
process.exit(5);
|
|
333
|
-
});
|
|
1
|
+
export {};
|
package/dist/login-runner.mjs
CHANGED
|
@@ -8,16 +8,16 @@ import {
|
|
|
8
8
|
} from "./chunk-HMKLWVXB.mjs";
|
|
9
9
|
import {
|
|
10
10
|
resolveBrowserExecutable
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-DXR6EEZH.mjs";
|
|
12
12
|
import {
|
|
13
13
|
Vault
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-C5I7KXHK.mjs";
|
|
15
15
|
import "./chunk-MTDFKNXX.mjs";
|
|
16
16
|
import {
|
|
17
17
|
getActiveName,
|
|
18
18
|
getProfilePaths,
|
|
19
19
|
recordLoginSuccess
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-E3GRJXXJ.mjs";
|
|
21
21
|
import "./chunk-4UEJOM6W.mjs";
|
|
22
22
|
|
|
23
23
|
// src/login-runner.js
|
|
@@ -87,6 +87,7 @@ async function main() {
|
|
|
87
87
|
process.exit(1);
|
|
88
88
|
}
|
|
89
89
|
const PROFILE = resolveProfile();
|
|
90
|
+
const paths = getProfilePaths(PROFILE);
|
|
90
91
|
const localOrigin = isLocalOrigin(ORIGIN);
|
|
91
92
|
let executablePath;
|
|
92
93
|
let channel;
|
|
@@ -98,13 +99,13 @@ async function main() {
|
|
|
98
99
|
process.exit(4);
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
|
-
const
|
|
102
|
+
const ctx = await chromium.launchPersistentContext(paths.loginBrowserData, {
|
|
102
103
|
headless: localOrigin,
|
|
104
|
+
ignoreHTTPSErrors: true,
|
|
103
105
|
...executablePath ? { executablePath } : {},
|
|
104
106
|
...channel && ["chrome", "msedge", "chromium"].includes(channel) ? { channel } : {},
|
|
105
107
|
args: localOrigin ? [] : ["--start-minimized"]
|
|
106
108
|
});
|
|
107
|
-
const ctx = await browser.newContext({ ignoreHTTPSErrors: true });
|
|
108
109
|
const page = await ctx.newPage();
|
|
109
110
|
try {
|
|
110
111
|
await page.goto(`${ORIGIN}${LOGIN_PATH}`, { waitUntil: "domcontentloaded", timeout: 3e4 });
|
|
@@ -114,7 +115,7 @@ async function main() {
|
|
|
114
115
|
const ready = await waitForLoginReady(page);
|
|
115
116
|
if (!ready) {
|
|
116
117
|
const title = await page.title().catch(() => "");
|
|
117
|
-
await browser
|
|
118
|
+
await ctx.browser()?.close().catch(() => {
|
|
118
119
|
});
|
|
119
120
|
emit({ ok: false, reason: /just a moment/i.test(title) ? "cf_blocked" : "auto_unsupported" });
|
|
120
121
|
process.exit(/just a moment/i.test(title) ? 3 : 2);
|
|
@@ -126,19 +127,19 @@ async function main() {
|
|
|
126
127
|
}
|
|
127
128
|
if (!localOrigin) await minimizePageWindow(page);
|
|
128
129
|
if (authFlow.kind === "sso_required") {
|
|
129
|
-
await browser
|
|
130
|
+
await ctx.browser()?.close().catch(() => {
|
|
130
131
|
});
|
|
131
132
|
emit({ ok: false, reason: "sso_required" });
|
|
132
133
|
process.exit(2);
|
|
133
134
|
}
|
|
134
135
|
if (authFlow.kind === "unsupported") {
|
|
135
|
-
await browser
|
|
136
|
+
await ctx.browser()?.close().catch(() => {
|
|
136
137
|
});
|
|
137
138
|
emit({ ok: false, reason: "auto_unsupported", detail: authFlow.detail });
|
|
138
139
|
process.exit(2);
|
|
139
140
|
}
|
|
140
141
|
if (authFlow.kind === "email_rejected") {
|
|
141
|
-
await browser
|
|
142
|
+
await ctx.browser()?.close().catch(() => {
|
|
142
143
|
});
|
|
143
144
|
emit({ ok: false, reason: "email_rejected", detail: authFlow.detail });
|
|
144
145
|
process.exit(2);
|
|
@@ -149,7 +150,7 @@ async function main() {
|
|
|
149
150
|
try {
|
|
150
151
|
otp = await awaitOtp();
|
|
151
152
|
} catch {
|
|
152
|
-
await browser
|
|
153
|
+
await ctx.browser()?.close().catch(() => {
|
|
153
154
|
});
|
|
154
155
|
emit({ ok: false, reason: "otp_timeout" });
|
|
155
156
|
process.exit(2);
|
|
@@ -165,12 +166,11 @@ async function main() {
|
|
|
165
166
|
await vault.set(PROFILE, "cookies", JSON.stringify(allCookies));
|
|
166
167
|
if (metadata.sessionData?.user?.email) await vault.set(PROFILE, "email", metadata.sessionData.user.email);
|
|
167
168
|
if (metadata.sessionData?.user?.id) await vault.set(PROFILE, "userId", metadata.sessionData.user.id);
|
|
168
|
-
const paths = getProfilePaths(PROFILE);
|
|
169
169
|
if (!existsSync(paths.dir)) mkdirSync(paths.dir, { recursive: true });
|
|
170
170
|
writeFileSync(paths.modelsCache, JSON.stringify(metadata.cache, null, 2));
|
|
171
171
|
recordLoginSuccess(PROFILE, { tier: metadata.tier, loginMode: "auto", lastLogin: (/* @__PURE__ */ new Date()).toISOString() });
|
|
172
172
|
writeFileSync(paths.reinit, String(Date.now()));
|
|
173
|
-
await browser
|
|
173
|
+
await ctx.browser()?.close().catch(() => {
|
|
174
174
|
});
|
|
175
175
|
emit({ ok: true, tier: metadata.tier, modelCount: Object.keys(metadata.models?.models ?? {}).length });
|
|
176
176
|
process.exit(0);
|
|
@@ -181,7 +181,7 @@ async function main() {
|
|
|
181
181
|
if (!localOrigin) await minimizePageWindow(page);
|
|
182
182
|
}
|
|
183
183
|
if (attempt === MAX_RETRIES) {
|
|
184
|
-
await browser
|
|
184
|
+
await ctx.browser()?.close().catch(() => {
|
|
185
185
|
});
|
|
186
186
|
emit({ ok: false, reason: "otp_rejected" });
|
|
187
187
|
process.exit(2);
|
package/dist/login.d.ts
ADDED
package/dist/logout.d.ts
CHANGED
|
@@ -1,28 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import { getActiveName, setActive, getProfilePaths, listProfiles, getProfile } from './profiles.d-DqS1oZWr.js';
|
|
4
|
-
|
|
5
|
-
async function softLogout(name) {
|
|
6
|
-
const vault = new Vault();
|
|
7
|
-
await vault.delete(name, "cookies").catch(() => {});
|
|
8
|
-
const paths = getProfilePaths(name);
|
|
9
|
-
const meta = getProfile(name);
|
|
10
|
-
if (meta) {
|
|
11
|
-
delete meta.lastLogin;
|
|
12
|
-
writeFileSync(paths.meta, JSON.stringify(meta, null, 2) + "\n");
|
|
13
|
-
}
|
|
14
|
-
if (existsSync(paths.dir)) writeFileSync(paths.reinit, String(Date.now()));
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async function hardLogout(name) {
|
|
18
|
-
const paths = getProfilePaths(name);
|
|
19
|
-
if (existsSync(paths.dir)) rmSync(paths.dir, { recursive: true, force: true });
|
|
20
|
-
if (getActiveName() === name) {
|
|
21
|
-
const remaining = listProfiles();
|
|
22
|
-
if (remaining.length > 0) {
|
|
23
|
-
setActive(remaining[0].name);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { hardLogout, softLogout };
|
|
1
|
+
export function softLogout(name: any): Promise<void>;
|
|
2
|
+
export function hardLogout(name: any): Promise<void>;
|
package/dist/logout.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Vault
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-C5I7KXHK.mjs";
|
|
4
4
|
import "./chunk-MTDFKNXX.mjs";
|
|
5
5
|
import {
|
|
6
6
|
createProfile,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
getProfilePaths,
|
|
10
10
|
listProfiles,
|
|
11
11
|
setActive
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-E3GRJXXJ.mjs";
|
|
13
13
|
import "./chunk-4UEJOM6W.mjs";
|
|
14
14
|
|
|
15
15
|
// src/logout.js
|
|
@@ -24,6 +24,7 @@ async function softLogout(name) {
|
|
|
24
24
|
delete meta.lastLogin;
|
|
25
25
|
writeFileSync(paths.meta, JSON.stringify(meta, null, 2) + "\n");
|
|
26
26
|
}
|
|
27
|
+
if (existsSync(paths.loginBrowserData)) rmSync(paths.loginBrowserData, { recursive: true, force: true });
|
|
27
28
|
if (existsSync(paths.dir)) writeFileSync(paths.reinit, String(Date.now()));
|
|
28
29
|
}
|
|
29
30
|
async function hardLogout(name) {
|