lockin-mcp 1.0.0
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 +349 -0
- package/assets/icon-256.png +0 -0
- package/assets/icon-32.png +0 -0
- package/assets/icon.svg +4 -0
- package/dist/blocker.d.ts +23 -0
- package/dist/blocker.d.ts.map +1 -0
- package/dist/blocker.js +184 -0
- package/dist/blocker.js.map +1 -0
- package/dist/brand.d.ts +12 -0
- package/dist/brand.d.ts.map +1 -0
- package/dist/brand.js +12 -0
- package/dist/brand.js.map +1 -0
- package/dist/hosts-manager.d.ts +14 -0
- package/dist/hosts-manager.d.ts.map +1 -0
- package/dist/hosts-manager.js +233 -0
- package/dist/hosts-manager.js.map +1 -0
- package/dist/hosts-manager.test.d.ts +2 -0
- package/dist/hosts-manager.test.d.ts.map +1 -0
- package/dist/hosts-manager.test.js +19 -0
- package/dist/hosts-manager.test.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +296 -0
- package/dist/index.js.map +1 -0
- package/dist/install.d.ts +3 -0
- package/dist/install.d.ts.map +1 -0
- package/dist/install.js +15 -0
- package/dist/install.js.map +1 -0
- package/dist/installer/agent-instructions.d.ts +25 -0
- package/dist/installer/agent-instructions.d.ts.map +1 -0
- package/dist/installer/agent-instructions.js +36 -0
- package/dist/installer/agent-instructions.js.map +1 -0
- package/dist/installer/agents.d.ts +9 -0
- package/dist/installer/agents.d.ts.map +1 -0
- package/dist/installer/agents.js +223 -0
- package/dist/installer/agents.js.map +1 -0
- package/dist/installer/background-service.d.ts +11 -0
- package/dist/installer/background-service.d.ts.map +1 -0
- package/dist/installer/background-service.js +47 -0
- package/dist/installer/background-service.js.map +1 -0
- package/dist/installer/clipboard.d.ts +2 -0
- package/dist/installer/clipboard.d.ts.map +1 -0
- package/dist/installer/clipboard.js +28 -0
- package/dist/installer/clipboard.js.map +1 -0
- package/dist/installer/daemon-linux.d.ts +10 -0
- package/dist/installer/daemon-linux.d.ts.map +1 -0
- package/dist/installer/daemon-linux.js +66 -0
- package/dist/installer/daemon-linux.js.map +1 -0
- package/dist/installer/daemon-windows.d.ts +10 -0
- package/dist/installer/daemon-windows.d.ts.map +1 -0
- package/dist/installer/daemon-windows.js +88 -0
- package/dist/installer/daemon-windows.js.map +1 -0
- package/dist/installer/daemon.d.ts +10 -0
- package/dist/installer/daemon.d.ts.map +1 -0
- package/dist/installer/daemon.js +96 -0
- package/dist/installer/daemon.js.map +1 -0
- package/dist/installer/hosts-sudo.d.ts +6 -0
- package/dist/installer/hosts-sudo.d.ts.map +1 -0
- package/dist/installer/hosts-sudo.js +111 -0
- package/dist/installer/hosts-sudo.js.map +1 -0
- package/dist/installer/legacy-tunnels.d.ts +2 -0
- package/dist/installer/legacy-tunnels.d.ts.map +1 -0
- package/dist/installer/legacy-tunnels.js +27 -0
- package/dist/installer/legacy-tunnels.js.map +1 -0
- package/dist/installer/license.d.ts +9 -0
- package/dist/installer/license.d.ts.map +1 -0
- package/dist/installer/license.js +193 -0
- package/dist/installer/license.js.map +1 -0
- package/dist/installer/mcp-cleanup.d.ts +3 -0
- package/dist/installer/mcp-cleanup.d.ts.map +1 -0
- package/dist/installer/mcp-cleanup.js +28 -0
- package/dist/installer/mcp-cleanup.js.map +1 -0
- package/dist/installer/platform.d.ts +7 -0
- package/dist/installer/platform.d.ts.map +1 -0
- package/dist/installer/platform.js +76 -0
- package/dist/installer/platform.js.map +1 -0
- package/dist/installer/poke-daemon.d.ts +14 -0
- package/dist/installer/poke-daemon.d.ts.map +1 -0
- package/dist/installer/poke-daemon.js +161 -0
- package/dist/installer/poke-daemon.js.map +1 -0
- package/dist/installer/poke.d.ts +43 -0
- package/dist/installer/poke.d.ts.map +1 -0
- package/dist/installer/poke.js +154 -0
- package/dist/installer/poke.js.map +1 -0
- package/dist/installer/port.d.ts +6 -0
- package/dist/installer/port.d.ts.map +1 -0
- package/dist/installer/port.js +76 -0
- package/dist/installer/port.js.map +1 -0
- package/dist/installer/presets.d.ts +5 -0
- package/dist/installer/presets.d.ts.map +1 -0
- package/dist/installer/presets.js +22 -0
- package/dist/installer/presets.js.map +1 -0
- package/dist/installer/prompts.d.ts +8 -0
- package/dist/installer/prompts.d.ts.map +1 -0
- package/dist/installer/prompts.js +128 -0
- package/dist/installer/prompts.js.map +1 -0
- package/dist/installer/relay-credentials.d.ts +26 -0
- package/dist/installer/relay-credentials.d.ts.map +1 -0
- package/dist/installer/relay-credentials.js +75 -0
- package/dist/installer/relay-credentials.js.map +1 -0
- package/dist/installer/relay-provision.d.ts +26 -0
- package/dist/installer/relay-provision.d.ts.map +1 -0
- package/dist/installer/relay-provision.js +57 -0
- package/dist/installer/relay-provision.js.map +1 -0
- package/dist/installer/run.d.ts +2 -0
- package/dist/installer/run.d.ts.map +1 -0
- package/dist/installer/run.js +365 -0
- package/dist/installer/run.js.map +1 -0
- package/dist/installer/tty.d.ts +7 -0
- package/dist/installer/tty.d.ts.map +1 -0
- package/dist/installer/tty.js +37 -0
- package/dist/installer/tty.js.map +1 -0
- package/dist/installer/tui.d.ts +14 -0
- package/dist/installer/tui.d.ts.map +1 -0
- package/dist/installer/tui.js +150 -0
- package/dist/installer/tui.js.map +1 -0
- package/dist/installer/tunnel-daemon.d.ts +13 -0
- package/dist/installer/tunnel-daemon.d.ts.map +1 -0
- package/dist/installer/tunnel-daemon.js +129 -0
- package/dist/installer/tunnel-daemon.js.map +1 -0
- package/dist/installer/tunnel-provision.d.ts +14 -0
- package/dist/installer/tunnel-provision.d.ts.map +1 -0
- package/dist/installer/tunnel-provision.js +31 -0
- package/dist/installer/tunnel-provision.js.map +1 -0
- package/dist/installer/tunnel.d.ts +12 -0
- package/dist/installer/tunnel.d.ts.map +1 -0
- package/dist/installer/tunnel.js +91 -0
- package/dist/installer/tunnel.js.map +1 -0
- package/dist/installer/types.d.ts +59 -0
- package/dist/installer/types.d.ts.map +1 -0
- package/dist/installer/types.js +2 -0
- package/dist/installer/types.js.map +1 -0
- package/dist/license-check.d.ts +12 -0
- package/dist/license-check.d.ts.map +1 -0
- package/dist/license-check.js +59 -0
- package/dist/license-check.js.map +1 -0
- package/dist/license-guard.d.ts +14 -0
- package/dist/license-guard.d.ts.map +1 -0
- package/dist/license-guard.js +56 -0
- package/dist/license-guard.js.map +1 -0
- package/dist/license-guard.test.d.ts +2 -0
- package/dist/license-guard.test.d.ts.map +1 -0
- package/dist/license-guard.test.js +34 -0
- package/dist/license-guard.test.js.map +1 -0
- package/dist/relay-client.d.ts +32 -0
- package/dist/relay-client.d.ts.map +1 -0
- package/dist/relay-client.js +249 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/relay-types.d.ts +30 -0
- package/dist/relay-types.d.ts.map +1 -0
- package/dist/relay-types.js +2 -0
- package/dist/relay-types.js.map +1 -0
- package/dist/relay-urls.d.ts +22 -0
- package/dist/relay-urls.d.ts.map +1 -0
- package/dist/relay-urls.js +57 -0
- package/dist/relay-urls.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +164 -0
- package/dist/server.js.map +1 -0
- package/dist/state.d.ts +12 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +91 -0
- package/dist/state.js.map +1 -0
- package/dist/types.d.ts +40 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +41 -0
- package/dist/types.js.map +1 -0
- package/dist/types.test.d.ts +2 -0
- package/dist/types.test.d.ts.map +1 -0
- package/dist/types.test.js +13 -0
- package/dist/types.test.js.map +1 -0
- package/install.ps1 +41 -0
- package/install.sh +39 -0
- package/package.json +64 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { access, mkdir, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { promisify } from "node:util";
|
|
4
|
+
import { execFile } from "node:child_process";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { getInstallDir } from "./platform.js";
|
|
7
|
+
const execFileAsync = promisify(execFile);
|
|
8
|
+
const LAUNCH_LABEL = "com.lockin.mcp";
|
|
9
|
+
function escapeXml(value) {
|
|
10
|
+
return value
|
|
11
|
+
.replace(/&/g, "&")
|
|
12
|
+
.replace(/</g, "<")
|
|
13
|
+
.replace(/>/g, ">")
|
|
14
|
+
.replace(/"/g, """);
|
|
15
|
+
}
|
|
16
|
+
export async function installLaunchAgent(params) {
|
|
17
|
+
const logDir = getInstallDir();
|
|
18
|
+
await mkdir(logDir, { recursive: true });
|
|
19
|
+
const stdoutLog = join(logDir, "mcp.stdout.log");
|
|
20
|
+
const stderrLog = join(logDir, "mcp.stderr.log");
|
|
21
|
+
const plistPath = join(homedir(), "Library", "LaunchAgents", `${LAUNCH_LABEL}.plist`);
|
|
22
|
+
await mkdir(dirname(plistPath), { recursive: true });
|
|
23
|
+
const envEntries = [];
|
|
24
|
+
if (params.authToken) {
|
|
25
|
+
envEntries.push(["MDB_MCP_AUTH_TOKEN", params.authToken]);
|
|
26
|
+
}
|
|
27
|
+
if (params.relayUrl) {
|
|
28
|
+
envEntries.push(["MDB_RELAY_URL", params.relayUrl]);
|
|
29
|
+
}
|
|
30
|
+
if (params.deviceId) {
|
|
31
|
+
envEntries.push(["MDB_DEVICE_ID", params.deviceId]);
|
|
32
|
+
}
|
|
33
|
+
if (params.relayDeviceToken) {
|
|
34
|
+
envEntries.push(["MDB_RELAY_DEVICE_TOKEN", params.relayDeviceToken]);
|
|
35
|
+
}
|
|
36
|
+
if (process.env.MDB_LICENSE_API_URL) {
|
|
37
|
+
envEntries.push(["MDB_LICENSE_API_URL", process.env.MDB_LICENSE_API_URL]);
|
|
38
|
+
}
|
|
39
|
+
if (process.env.MDB_APP_URL) {
|
|
40
|
+
envEntries.push(["MDB_APP_URL", process.env.MDB_APP_URL]);
|
|
41
|
+
}
|
|
42
|
+
envEntries.push(["MDB_HTTP_PORT", String(params.port)]);
|
|
43
|
+
const envBlock = envEntries.length > 0
|
|
44
|
+
? `<key>EnvironmentVariables</key>
|
|
45
|
+
<dict>
|
|
46
|
+
${envEntries
|
|
47
|
+
.map(([key, value]) => `<key>${escapeXml(key)}</key>\n <string>${escapeXml(value)}</string>`)
|
|
48
|
+
.join("\n ")}
|
|
49
|
+
</dict>
|
|
50
|
+
`
|
|
51
|
+
: "";
|
|
52
|
+
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
53
|
+
<!DOCTYPE plist PUBLIC "-//XML PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
54
|
+
<plist version="1.0">
|
|
55
|
+
<dict>
|
|
56
|
+
<key>Label</key>
|
|
57
|
+
<string>${LAUNCH_LABEL}</string>
|
|
58
|
+
<key>ProgramArguments</key>
|
|
59
|
+
<array>
|
|
60
|
+
<string>${escapeXml(process.execPath)}</string>
|
|
61
|
+
<string>${escapeXml(params.serverEntry)}</string>
|
|
62
|
+
<string>--http</string>
|
|
63
|
+
<string>--port</string>
|
|
64
|
+
<string>${params.port}</string>
|
|
65
|
+
</array>
|
|
66
|
+
${envBlock}
|
|
67
|
+
<key>KeepAlive</key>
|
|
68
|
+
<true/>
|
|
69
|
+
<key>ThrottleInterval</key>
|
|
70
|
+
<integer>30</integer>
|
|
71
|
+
<key>RunAtLoad</key>
|
|
72
|
+
<true/>
|
|
73
|
+
<key>StandardOutPath</key>
|
|
74
|
+
<string>${escapeXml(stdoutLog)}</string>
|
|
75
|
+
<key>StandardErrorPath</key>
|
|
76
|
+
<string>${escapeXml(stderrLog)}</string>
|
|
77
|
+
</dict>
|
|
78
|
+
</plist>
|
|
79
|
+
`;
|
|
80
|
+
await writeFile(plistPath, plist, { mode: 0o644 });
|
|
81
|
+
const guiDomain = `gui/${process.getuid?.() ?? process.env.UID ?? "501"}`;
|
|
82
|
+
await execFileAsync("launchctl", ["bootout", guiDomain, plistPath]).catch(() => undefined);
|
|
83
|
+
await execFileAsync("launchctl", ["bootstrap", guiDomain, plistPath]);
|
|
84
|
+
return plistPath;
|
|
85
|
+
}
|
|
86
|
+
export async function isLaunchAgentInstalled() {
|
|
87
|
+
const plistPath = join(homedir(), "Library", "LaunchAgents", `${LAUNCH_LABEL}.plist`);
|
|
88
|
+
try {
|
|
89
|
+
await access(plistPath);
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/installer/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare function getHostsUpdaterScriptPath(): string;
|
|
2
|
+
export declare function ensureHostsUpdaterScript(): Promise<string>;
|
|
3
|
+
export declare function canUpdateHostsPasswordless(): Promise<boolean>;
|
|
4
|
+
export declare function writeHostsViaPasswordlessScript(tempPath: string): Promise<boolean>;
|
|
5
|
+
export declare function promptInstallHostsSudoers(): Promise<void>;
|
|
6
|
+
//# sourceMappingURL=hosts-sudo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts-sudo.d.ts","sourceRoot":"","sources":["../../src/installer/hosts-sudo.ts"],"names":[],"mappings":"AAuCA,wBAAgB,yBAAyB,IAAI,MAAM,CAElD;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,MAAM,CAAC,CAKhE;AAED,wBAAsB,0BAA0B,IAAI,OAAO,CAAC,OAAO,CAAC,CAYnE;AAED,wBAAsB,+BAA+B,CACnD,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,CAAC,CAWlB;AAED,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,IAAI,CAAC,CAuD/D"}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { execFile, spawn } from "node:child_process";
|
|
2
|
+
import { access, chmod, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import * as clack from "@clack/prompts";
|
|
7
|
+
import color from "picocolors";
|
|
8
|
+
import { getInstallDir } from "./platform.js";
|
|
9
|
+
const execFileAsync = promisify(execFile);
|
|
10
|
+
const SUDOERS_FILENAME = "lockin-mcp-hosts";
|
|
11
|
+
function buildUpdateHostsScript() {
|
|
12
|
+
const dnsFlush = process.platform === "darwin"
|
|
13
|
+
? `/usr/sbin/dscacheutil -flushcache 2>/dev/null || true
|
|
14
|
+
/usr/bin/killall -HUP mDNSResponder 2>/dev/null || true`
|
|
15
|
+
: process.platform === "linux"
|
|
16
|
+
? `command -v resolvectl >/dev/null && resolvectl flush-caches 2>/dev/null || true
|
|
17
|
+
command -v systemd-resolve >/dev/null && systemd-resolve --flush-caches 2>/dev/null || true
|
|
18
|
+
command -v nscd >/dev/null && nscd -i hosts 2>/dev/null || true`
|
|
19
|
+
: "";
|
|
20
|
+
const hostsDest = process.platform === "win32"
|
|
21
|
+
? 'C:\\Windows\\System32\\drivers\\etc\\hosts'
|
|
22
|
+
: "/etc/hosts";
|
|
23
|
+
return `#!/bin/bash
|
|
24
|
+
set -euo pipefail
|
|
25
|
+
if [[ $# -ne 1 ]]; then
|
|
26
|
+
echo "Usage: update-hosts.sh <source-file>" >&2
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
cp "$1" ${hostsDest}
|
|
30
|
+
${dnsFlush}
|
|
31
|
+
`;
|
|
32
|
+
}
|
|
33
|
+
export function getHostsUpdaterScriptPath() {
|
|
34
|
+
return join(getInstallDir(), "update-hosts.sh");
|
|
35
|
+
}
|
|
36
|
+
export async function ensureHostsUpdaterScript() {
|
|
37
|
+
const scriptPath = getHostsUpdaterScriptPath();
|
|
38
|
+
await writeFile(scriptPath, buildUpdateHostsScript(), { mode: 0o755 });
|
|
39
|
+
await chmod(scriptPath, 0o755);
|
|
40
|
+
return scriptPath;
|
|
41
|
+
}
|
|
42
|
+
export async function canUpdateHostsPasswordless() {
|
|
43
|
+
if (process.platform === "win32") {
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
const scriptPath = getHostsUpdaterScriptPath();
|
|
47
|
+
try {
|
|
48
|
+
await access(scriptPath);
|
|
49
|
+
const { stdout } = await execFileAsync("sudo", ["-n", "-l"]);
|
|
50
|
+
return stdout.includes(scriptPath);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
export async function writeHostsViaPasswordlessScript(tempPath) {
|
|
57
|
+
if (process.platform === "win32") {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
const scriptPath = await ensureHostsUpdaterScript();
|
|
61
|
+
try {
|
|
62
|
+
await execFileAsync("sudo", ["-n", scriptPath, tempPath]);
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export async function promptInstallHostsSudoers() {
|
|
70
|
+
if (process.platform !== "darwin" && process.platform !== "linux") {
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
if (await canUpdateHostsPasswordless()) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const scriptPath = await ensureHostsUpdaterScript();
|
|
77
|
+
const username = process.env.USER ?? process.env.LOGNAME ?? homedir().split("/").pop() ?? "";
|
|
78
|
+
const sudoersPath = `/etc/sudoers.d/${SUDOERS_FILENAME}`;
|
|
79
|
+
const sudoersLine = `${username} ALL=(ALL) NOPASSWD: ${scriptPath}`;
|
|
80
|
+
const choice = await clack.confirm({
|
|
81
|
+
message: "Save sudo password for hosts updates? (one-time setup — agents won't prompt again)",
|
|
82
|
+
initialValue: true,
|
|
83
|
+
});
|
|
84
|
+
if (clack.isCancel(choice) || !choice) {
|
|
85
|
+
clack.log.info(color.dim("Skipped. Your OS may cache sudo for a few minutes; you'll be prompted when blocks change."));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const tempSudoers = `/tmp/${SUDOERS_FILENAME}-${process.pid}`;
|
|
89
|
+
await writeFile(tempSudoers, `${sudoersLine}\n`, "utf8");
|
|
90
|
+
await new Promise((resolve, reject) => {
|
|
91
|
+
const child = spawn("sudo", ["cp", tempSudoers, sudoersPath], {
|
|
92
|
+
stdio: "inherit",
|
|
93
|
+
});
|
|
94
|
+
child.on("error", reject);
|
|
95
|
+
child.on("close", (code) => {
|
|
96
|
+
if (code === 0) {
|
|
97
|
+
resolve();
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
reject(new Error(`sudo cp exited with code ${code ?? 1}`));
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
await execFileAsync("sudo", ["chmod", "0440", sudoersPath]);
|
|
104
|
+
if (await canUpdateHostsPasswordless()) {
|
|
105
|
+
clack.log.success("Hosts updates won't ask for your password again.");
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
clack.log.warn(`Could not verify passwordless hosts updates. You can add this line manually:\n${color.dim(sudoersLine)}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
//# sourceMappingURL=hosts-sudo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hosts-sudo.js","sourceRoot":"","sources":["../../src/installer/hosts-sudo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-tunnels.d.ts","sourceRoot":"","sources":["../../src/installer/legacy-tunnels.ts"],"names":[],"mappings":"AAaA,wBAAsB,iCAAiC,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBvE"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { access } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
const LEGACY_LAUNCH_LABELS = [
|
|
8
|
+
"com.lockin.cloudflared",
|
|
9
|
+
"com.lockin.poke-tunnel",
|
|
10
|
+
];
|
|
11
|
+
export async function uninstallLegacyTunnelLaunchAgents() {
|
|
12
|
+
if (process.platform !== "darwin") {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const guiDomain = `gui/${process.getuid?.() ?? process.env.UID ?? "501"}`;
|
|
16
|
+
for (const label of LEGACY_LAUNCH_LABELS) {
|
|
17
|
+
const plistPath = join(homedir(), "Library", "LaunchAgents", `${label}.plist`);
|
|
18
|
+
try {
|
|
19
|
+
await access(plistPath);
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
continue;
|
|
23
|
+
}
|
|
24
|
+
await execFileAsync("launchctl", ["bootout", guiDomain, plistPath]).catch(() => undefined);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=legacy-tunnels.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy-tunnels.js","sourceRoot":"","sources":["../../src/installer/legacy-tunnels.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAE1C,MAAM,oBAAoB,GAAG;IAC3B,wBAAwB;IACxB,wBAAwB;CACzB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,iCAAiC;IACrD,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO;IACT,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC;IAE1E,KAAK,MAAM,KAAK,IAAI,oBAAoB,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,IAAI,CACpB,OAAO,EAAE,EACT,SAAS,EACT,cAAc,EACd,GAAG,KAAK,QAAQ,CACjB,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QAED,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CACvE,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LicenseInfo } from "./types.js";
|
|
2
|
+
export declare function loadCachedLicense(): Promise<LicenseInfo | null>;
|
|
3
|
+
export declare function verifyLicenseKey(key: string): Promise<LicenseInfo>;
|
|
4
|
+
export declare function verifyViaBrowserLogin(): Promise<LicenseInfo>;
|
|
5
|
+
export declare function resolveLicense(options: {
|
|
6
|
+
licenseKey?: string;
|
|
7
|
+
useBrowserLogin: boolean;
|
|
8
|
+
}): Promise<LicenseInfo>;
|
|
9
|
+
//# sourceMappingURL=license.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.d.ts","sourceRoot":"","sources":["../../src/installer/license.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,WAAW,EAAe,MAAM,YAAY,CAAC;AA+C3D,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAoBrE;AA0CD,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAexE;AA8DD,wBAAsB,qBAAqB,IAAI,OAAO,CAAC,WAAW,CAAC,CAoClE;AAWD,wBAAsB,cAAc,CAAC,OAAO,EAAE;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,OAAO,CAAC;CAC1B,GAAG,OAAO,CAAC,WAAW,CAAC,CAwBvB"}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import * as clack from "@clack/prompts";
|
|
2
|
+
import color from "picocolors";
|
|
3
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { openBrowser, getInstallDir } from "./platform.js";
|
|
6
|
+
const LICENSE_API_URL = process.env.MDB_LICENSE_API_URL ??
|
|
7
|
+
"http://localhost:3001/api/v1";
|
|
8
|
+
const LICENSE_FILE = "license.json";
|
|
9
|
+
function licensePath() {
|
|
10
|
+
return join(getInstallDir(), LICENSE_FILE);
|
|
11
|
+
}
|
|
12
|
+
function purchaseUrl() {
|
|
13
|
+
const appUrl = process.env.MDB_APP_URL ?? "http://localhost:3001";
|
|
14
|
+
return `${appUrl}/signup?redirect=checkout`;
|
|
15
|
+
}
|
|
16
|
+
export async function loadCachedLicense() {
|
|
17
|
+
try {
|
|
18
|
+
const raw = await readFile(licensePath(), "utf8");
|
|
19
|
+
const stored = JSON.parse(raw);
|
|
20
|
+
if (stored.expiresAt && stored.expiresAt < Date.now()) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
if (stored.tier !== "pro") {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
tier: stored.tier,
|
|
28
|
+
method: "cached",
|
|
29
|
+
token: stored.token,
|
|
30
|
+
email: stored.email,
|
|
31
|
+
expiresAt: stored.expiresAt,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function saveLicense(license) {
|
|
39
|
+
await mkdir(getInstallDir(), { recursive: true });
|
|
40
|
+
const stored = {
|
|
41
|
+
...license,
|
|
42
|
+
savedAt: Date.now(),
|
|
43
|
+
};
|
|
44
|
+
await writeFile(licensePath(), `${JSON.stringify(stored, null, 2)}\n`, {
|
|
45
|
+
mode: 0o600,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function verifyLicenseKeyRemote(key) {
|
|
49
|
+
try {
|
|
50
|
+
const response = await fetch(`${LICENSE_API_URL}/license/verify`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: { "Content-Type": "application/json" },
|
|
53
|
+
body: JSON.stringify({ license_key: key }),
|
|
54
|
+
});
|
|
55
|
+
if (!response.ok) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
const data = (await response.json());
|
|
59
|
+
if (!data.valid || data.tier !== "pro") {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
tier: "pro",
|
|
64
|
+
method: "license_key",
|
|
65
|
+
token: data.token,
|
|
66
|
+
email: data.email,
|
|
67
|
+
expiresAt: data.expires_at,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export async function verifyLicenseKey(key) {
|
|
75
|
+
const trimmed = key.trim();
|
|
76
|
+
if (!trimmed) {
|
|
77
|
+
throw new Error("License key cannot be empty");
|
|
78
|
+
}
|
|
79
|
+
const remote = await verifyLicenseKeyRemote(trimmed);
|
|
80
|
+
if (remote) {
|
|
81
|
+
await saveLicense(remote);
|
|
82
|
+
return remote;
|
|
83
|
+
}
|
|
84
|
+
throw new Error(`Invalid license key. Get a Pro key at ${purchaseUrl()} or sign in via browser.`);
|
|
85
|
+
}
|
|
86
|
+
async function startDeviceAuth() {
|
|
87
|
+
const response = await fetch(`${LICENSE_API_URL}/oauth/device`, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: { "Content-Type": "application/json" },
|
|
90
|
+
body: JSON.stringify({
|
|
91
|
+
client_id: "mac-distraction-blocker-installer",
|
|
92
|
+
scope: "pro",
|
|
93
|
+
}),
|
|
94
|
+
});
|
|
95
|
+
if (!response.ok) {
|
|
96
|
+
throw new Error(`License service unavailable (${response.status})`);
|
|
97
|
+
}
|
|
98
|
+
return (await response.json());
|
|
99
|
+
}
|
|
100
|
+
async function pollDeviceToken(deviceCode) {
|
|
101
|
+
const response = await fetch(`${LICENSE_API_URL}/oauth/token`, {
|
|
102
|
+
method: "POST",
|
|
103
|
+
headers: { "Content-Type": "application/json" },
|
|
104
|
+
body: JSON.stringify({
|
|
105
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
106
|
+
device_code: deviceCode,
|
|
107
|
+
client_id: "mac-distraction-blocker-installer",
|
|
108
|
+
}),
|
|
109
|
+
});
|
|
110
|
+
const data = (await response.json());
|
|
111
|
+
if (data.error === "authorization_pending") {
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
114
|
+
if (data.error) {
|
|
115
|
+
throw new Error(data.error);
|
|
116
|
+
}
|
|
117
|
+
if (!data.access_token) {
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
if (data.tier !== "pro") {
|
|
121
|
+
throw new Error(`Pro license required. Purchase at ${purchaseUrl()}`);
|
|
122
|
+
}
|
|
123
|
+
const license = {
|
|
124
|
+
tier: "pro",
|
|
125
|
+
method: "browser",
|
|
126
|
+
token: data.access_token,
|
|
127
|
+
email: data.email,
|
|
128
|
+
expiresAt: data.expires_in
|
|
129
|
+
? Date.now() + data.expires_in * 1000
|
|
130
|
+
: undefined,
|
|
131
|
+
};
|
|
132
|
+
await saveLicense(license);
|
|
133
|
+
return license;
|
|
134
|
+
}
|
|
135
|
+
export async function verifyViaBrowserLogin() {
|
|
136
|
+
const device = await startDeviceAuth();
|
|
137
|
+
const loginUrl = device.verification_uri_complete ??
|
|
138
|
+
`${device.verification_uri}?user_code=${encodeURIComponent(device.user_code)}`;
|
|
139
|
+
clack.note([
|
|
140
|
+
`${color.bold("Code")} ${color.cyan(device.user_code)}`,
|
|
141
|
+
"",
|
|
142
|
+
color.dim("Opening browser automatically..."),
|
|
143
|
+
color.dim(loginUrl),
|
|
144
|
+
].join("\n"), "Sign in to verify");
|
|
145
|
+
await openBrowser(loginUrl);
|
|
146
|
+
const spinner = clack.spinner();
|
|
147
|
+
spinner.start("Waiting for browser approval...");
|
|
148
|
+
const deadline = Date.now() + device.expires_in * 1000;
|
|
149
|
+
while (Date.now() < deadline) {
|
|
150
|
+
await sleep(device.interval * 1000);
|
|
151
|
+
const license = await pollDeviceToken(device.device_code);
|
|
152
|
+
if (license) {
|
|
153
|
+
spinner.stop(color.green(`Verified as ${license.email ?? "Pro user"}`));
|
|
154
|
+
return license;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
spinner.stop(color.red("Timed out"));
|
|
158
|
+
throw new Error(`Browser login timed out. Purchase a license at ${purchaseUrl()} or try again.`);
|
|
159
|
+
}
|
|
160
|
+
async function clearCachedLicense() {
|
|
161
|
+
try {
|
|
162
|
+
const { unlink } = await import("node:fs/promises");
|
|
163
|
+
await unlink(licensePath());
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
// ignore missing file
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
export async function resolveLicense(options) {
|
|
170
|
+
const cached = await loadCachedLicense();
|
|
171
|
+
if (cached?.token) {
|
|
172
|
+
const { verifyTokenWithBackend } = await import("../license-check.js");
|
|
173
|
+
const status = await verifyTokenWithBackend(cached.token);
|
|
174
|
+
if (status.valid) {
|
|
175
|
+
return cached;
|
|
176
|
+
}
|
|
177
|
+
await clearCachedLicense();
|
|
178
|
+
}
|
|
179
|
+
else if (cached) {
|
|
180
|
+
await clearCachedLicense();
|
|
181
|
+
}
|
|
182
|
+
if (options.licenseKey) {
|
|
183
|
+
return verifyLicenseKey(options.licenseKey);
|
|
184
|
+
}
|
|
185
|
+
if (options.useBrowserLogin) {
|
|
186
|
+
return verifyViaBrowserLogin();
|
|
187
|
+
}
|
|
188
|
+
throw new Error(`Pro license required. Purchase at ${purchaseUrl()} or use --license-key.`);
|
|
189
|
+
}
|
|
190
|
+
function sleep(ms) {
|
|
191
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=license.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"license.js","sourceRoot":"","sources":["../../src/installer/license.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,gBAAgB,CAAC;AACxC,OAAO,KAAK,MAAM,YAAY,CAAC;AAC/B,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG3D,MAAM,eAAe,GACnB,OAAO,CAAC,GAAG,CAAC,mBAAmB;IAC/B,8BAA8B,CAAC;AACjC,MAAM,YAAY,GAAG,cAAc,CAAC;AAiCpC,SAAS,WAAW;IAClB,OAAO,IAAI,CAAC,aAAa,EAAE,EAAE,YAAY,CAAC,CAAC;AAC7C,CAAC;AAED,SAAS,WAAW;IAClB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,uBAAuB,CAAC;IAClE,OAAO,GAAG,MAAM,2BAA2B,CAAC;AAC9C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;QAChD,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;YACtD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,IAAI,MAAM,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YAC1B,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,IAAI,EAAE,MAAM,CAAC,IAAI;YACjB,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,KAAK,EAAE,MAAM,CAAC,KAAK;YACnB,SAAS,EAAE,MAAM,CAAC,SAAS;SAC5B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAoB;IAC7C,MAAM,KAAK,CAAC,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAClD,MAAM,MAAM,GAAkB;QAC5B,GAAG,OAAO;QACV,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;KACpB,CAAC;IACF,MAAM,SAAS,CAAC,WAAW,EAAE,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE;QACrE,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,GAAW;IAC/C,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,eAAe,iBAAiB,EAAE;YAChE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC;SAC3C,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAsB,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;YACvC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO;YACL,IAAI,EAAE,KAAK;YACX,MAAM,EAAE,aAAa;YACrB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,SAAS,EAAE,IAAI,CAAC,UAAU;SAC3B,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,GAAW;IAChD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACjD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,OAAO,CAAC,CAAC;IACrD,IAAI,MAAM,EAAE,CAAC;QACX,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,IAAI,KAAK,CACb,yCAAyC,WAAW,EAAE,0BAA0B,CACjF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,eAAe;IAC5B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,eAAe,eAAe,EAAE;QAC9D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,SAAS,EAAE,mCAAmC;YAC9C,KAAK,EAAE,KAAK;SACb,CAAC;KACH,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;AACxD,CAAC;AAED,KAAK,UAAU,eAAe,CAC5B,UAAkB;IAElB,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,eAAe,cAAc,EAAE;QAC7D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,UAAU,EAAE,8CAA8C;YAC1D,WAAW,EAAE,UAAU;YACvB,SAAS,EAAE,mCAAmC;SAC/C,CAAC;KACH,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;IAC5D,IAAI,IAAI,CAAC,KAAK,KAAK,uBAAuB,EAAE,CAAC;QAC3C,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CACb,qCAAqC,WAAW,EAAE,EAAE,CACrD,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAgB;QAC3B,IAAI,EAAE,KAAK;QACX,MAAM,EAAE,SAAS;QACjB,KAAK,EAAE,IAAI,CAAC,YAAY;QACxB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,SAAS,EAAE,IAAI,CAAC,UAAU;YACxB,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,GAAG,IAAI;YACrC,CAAC,CAAC,SAAS;KACd,CAAC;IACF,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB;IACzC,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAC;IAEvC,MAAM,QAAQ,GACZ,MAAM,CAAC,yBAAyB;QAChC,GAAG,MAAM,CAAC,gBAAgB,cAAc,kBAAkB,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;IAEjF,KAAK,CAAC,IAAI,CACR;QACE,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE;QACxD,EAAE;QACF,KAAK,CAAC,GAAG,CAAC,kCAAkC,CAAC;QAC7C,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC;KACpB,CAAC,IAAI,CAAC,IAAI,CAAC,EACZ,mBAAmB,CACpB,CAAC;IAEF,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAC;IAE5B,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAEjD,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,UAAU,GAAG,IAAI,CAAC;IACvD,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,KAAK,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,CAAC;QACpC,MAAM,OAAO,GAAG,MAAM,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;QAC1D,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,OAAO,CAAC,KAAK,IAAI,UAAU,EAAE,CAAC,CAAC,CAAC;YACxE,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC;IACrC,MAAM,IAAI,KAAK,CACb,kDAAkD,WAAW,EAAE,gBAAgB,CAChF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,kBAAkB;IAC/B,IAAI,CAAC;QACH,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACpD,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9B,CAAC;IAAC,MAAM,CAAC;QACP,sBAAsB;IACxB,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAGpC;IACC,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACzC,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;QAClB,MAAM,EAAE,sBAAsB,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACvE,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC1D,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,kBAAkB,EAAE,CAAC;IAC7B,CAAC;SAAM,IAAI,MAAM,EAAE,CAAC;QAClB,MAAM,kBAAkB,EAAE,CAAC;IAC7B,CAAC;IAED,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;QAC5B,OAAO,qBAAqB,EAAE,CAAC;IACjC,CAAC;IAED,MAAM,IAAI,KAAK,CACb,qCAAqC,WAAW,EAAE,wBAAwB,CAC3E,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-cleanup.d.ts","sourceRoot":"","sources":["../../src/installer/mcp-cleanup.ts"],"names":[],"mappings":"AAaA,yFAAyF;AACzF,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAwBjE"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { access } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
const LAUNCH_LABEL = "com.lockin.mcp";
|
|
8
|
+
function sleep(ms) {
|
|
9
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
10
|
+
}
|
|
11
|
+
/** Stop the LockIn MCP LaunchAgent so reinstall uses a clean port + relay connection. */
|
|
12
|
+
export async function stopLockInMcpLaunchAgent() {
|
|
13
|
+
if (process.platform !== "darwin") {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
const plistPath = join(homedir(), "Library", "LaunchAgents", `${LAUNCH_LABEL}.plist`);
|
|
17
|
+
try {
|
|
18
|
+
await access(plistPath);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
const guiDomain = `gui/${process.getuid?.() ?? process.env.UID ?? "501"}`;
|
|
24
|
+
await execFileAsync("launchctl", ["bootout", guiDomain, plistPath]).catch(() => undefined);
|
|
25
|
+
await sleep(800);
|
|
26
|
+
return true;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=mcp-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-cleanup.js","sourceRoot":"","sources":["../../src/installer/mcp-cleanup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,YAAY,GAAG,gBAAgB,CAAC;AAEtC,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,wBAAwB;IAC5C,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,SAAS,GAAG,IAAI,CACpB,OAAO,EAAE,EACT,SAAS,EACT,cAAc,EACd,GAAG,YAAY,QAAQ,CACxB,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,SAAS,GAAG,OAAO,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,KAAK,EAAE,CAAC;IAC1E,MAAM,aAAa,CAAC,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CACvE,GAAG,EAAE,CAAC,SAAS,CAChB,CAAC;IACF,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IACjB,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { PlatformInfo } from "./types.js";
|
|
2
|
+
export declare function detectPlatform(): PlatformInfo;
|
|
3
|
+
export declare function ensureNodeVersion(minMajor?: number): Promise<void>;
|
|
4
|
+
export declare function commandExists(command: string): Promise<boolean>;
|
|
5
|
+
export declare function openBrowser(url: string): Promise<void>;
|
|
6
|
+
export declare function getInstallDir(): string;
|
|
7
|
+
//# sourceMappingURL=platform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.d.ts","sourceRoot":"","sources":["../../src/installer/platform.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAc,MAAM,YAAY,CAAC;AAI3D,wBAAgB,cAAc,IAAI,YAAY,CA6B7C;AAED,wBAAsB,iBAAiB,CAAC,QAAQ,SAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAQpE;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWrE;AAED,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAmB5D;AAED,wBAAgB,aAAa,IAAI,MAAM,CAGtC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
export function detectPlatform() {
|
|
5
|
+
const platform = process.platform;
|
|
6
|
+
switch (platform) {
|
|
7
|
+
case "darwin":
|
|
8
|
+
return {
|
|
9
|
+
id: "darwin",
|
|
10
|
+
name: "macOS",
|
|
11
|
+
isHostsSupported: true,
|
|
12
|
+
};
|
|
13
|
+
case "linux":
|
|
14
|
+
return {
|
|
15
|
+
id: "linux",
|
|
16
|
+
name: "Linux",
|
|
17
|
+
isHostsSupported: true,
|
|
18
|
+
};
|
|
19
|
+
case "win32":
|
|
20
|
+
return {
|
|
21
|
+
id: "win32",
|
|
22
|
+
name: "Windows",
|
|
23
|
+
isHostsSupported: true,
|
|
24
|
+
};
|
|
25
|
+
default:
|
|
26
|
+
return {
|
|
27
|
+
id: "unsupported",
|
|
28
|
+
name: process.platform,
|
|
29
|
+
isHostsSupported: false,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
export async function ensureNodeVersion(minMajor = 18) {
|
|
34
|
+
const version = process.versions.node;
|
|
35
|
+
const major = Number(version.split(".")[0]);
|
|
36
|
+
if (!Number.isFinite(major) || major < minMajor) {
|
|
37
|
+
throw new Error(`Node.js ${minMajor}+ is required (found ${version}). Install from https://nodejs.org/`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function commandExists(command) {
|
|
41
|
+
try {
|
|
42
|
+
if (process.platform === "win32") {
|
|
43
|
+
await execFileAsync("where", [command]);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
await execFileAsync("sh", ["-c", `command -v ${command}`]);
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
export async function openBrowser(url) {
|
|
55
|
+
const platform = process.platform;
|
|
56
|
+
const commands = platform === "darwin"
|
|
57
|
+
? [["open", [url]]]
|
|
58
|
+
: platform === "win32"
|
|
59
|
+
? [["cmd", ["/c", "start", "", url]]]
|
|
60
|
+
: [["xdg-open", [url]]];
|
|
61
|
+
for (const [cmd, args] of commands) {
|
|
62
|
+
try {
|
|
63
|
+
await execFileAsync(cmd, args);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// try next opener
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
console.log(`Open this URL in your browser:\n ${url}`);
|
|
71
|
+
}
|
|
72
|
+
export function getInstallDir() {
|
|
73
|
+
const home = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
74
|
+
return `${home}/.mac-distraction-blocker`;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=platform.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform.js","sourceRoot":"","sources":["../../src/installer/platform.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function pokeConfigDir(): string;
|
|
2
|
+
export declare function isPokeLoggedIn(): Promise<boolean>;
|
|
3
|
+
export declare function ensurePokeCli(installDir: string): Promise<string>;
|
|
4
|
+
export declare function writePokeTunnelScript(params: {
|
|
5
|
+
port: number;
|
|
6
|
+
integrationName?: string;
|
|
7
|
+
}): Promise<string>;
|
|
8
|
+
export declare function installPokeTunnelLaunchAgent(params: {
|
|
9
|
+
port: number;
|
|
10
|
+
integrationName?: string;
|
|
11
|
+
}): Promise<string>;
|
|
12
|
+
export declare function isPokeTunnelLaunchAgentInstalled(): Promise<boolean>;
|
|
13
|
+
export declare function uninstallPokeTunnelLaunchAgent(): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=poke-daemon.d.ts.map
|