lockin-mcp 1.0.3 → 1.0.4
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 +90 -16
- package/dist/blocker.js +2 -2
- package/dist/blocker.js.map +1 -1
- package/dist/hosts-manager.d.ts.map +1 -1
- package/dist/hosts-manager.js +23 -10
- package/dist/hosts-manager.js.map +1 -1
- package/dist/hosts-manager.test.js +11 -0
- package/dist/hosts-manager.test.js.map +1 -1
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/install.js +1 -3
- package/dist/install.js.map +1 -1
- package/dist/installer/agent-instructions.d.ts.map +1 -1
- package/dist/installer/agent-instructions.js +2 -5
- package/dist/installer/agent-instructions.js.map +1 -1
- package/dist/installer/agents.d.ts.map +1 -1
- package/dist/installer/agents.js +9 -29
- package/dist/installer/agents.js.map +1 -1
- package/dist/installer/claude-desktop-config.d.ts +19 -0
- package/dist/installer/claude-desktop-config.d.ts.map +1 -0
- package/dist/installer/claude-desktop-config.js +70 -0
- package/dist/installer/claude-desktop-config.js.map +1 -0
- package/dist/installer/claude-desktop-config.test.d.ts +2 -0
- package/dist/installer/claude-desktop-config.test.d.ts.map +1 -0
- package/dist/installer/claude-desktop-config.test.js +49 -0
- package/dist/installer/claude-desktop-config.test.js.map +1 -0
- package/dist/installer/install-log.d.ts +14 -0
- package/dist/installer/install-log.d.ts.map +1 -0
- package/dist/installer/install-log.js +100 -0
- package/dist/installer/install-log.js.map +1 -0
- package/dist/installer/relay-provision.d.ts.map +1 -1
- package/dist/installer/relay-provision.js +62 -29
- package/dist/installer/relay-provision.js.map +1 -1
- package/dist/installer/run.d.ts.map +1 -1
- package/dist/installer/run.js +30 -17
- package/dist/installer/run.js.map +1 -1
- package/dist/installer/user-errors.d.ts +8 -0
- package/dist/installer/user-errors.d.ts.map +1 -0
- package/dist/installer/user-errors.js +61 -0
- package/dist/installer/user-errors.js.map +1 -0
- package/dist/installer/user-errors.test.d.ts +2 -0
- package/dist/installer/user-errors.test.d.ts.map +1 -0
- package/dist/installer/user-errors.test.js +15 -0
- package/dist/installer/user-errors.test.js.map +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/installer/agents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/installer/agents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const LOCKIN_CLAUDE_MCP_SERVER_KEY = "lockin-mcp";
|
|
2
|
+
export declare const LOCKIN_CLAUDE_AUTH_ENV_VAR = "LOCKIN_MCP_AUTH_HEADER";
|
|
3
|
+
/** Claude Desktop only launches stdio MCP servers from claude_desktop_config.json. */
|
|
4
|
+
export declare function claudeDesktopConfigPath(platform?: NodeJS.Platform, home?: string): string;
|
|
5
|
+
/**
|
|
6
|
+
* Remote MCP servers must be bridged with mcp-remote. Direct `url` entries are
|
|
7
|
+
* rejected by Claude Desktop and can prevent the app from launching.
|
|
8
|
+
*
|
|
9
|
+
* @see https://modelcontextprotocol.io/docs/develop/connect-local-servers
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildClaudeDesktopMcpServerConfig(mcpUrl: string, authToken?: string, platform?: NodeJS.Platform): Record<string, unknown>;
|
|
12
|
+
export declare function mergeClaudeDesktopMcpConfig(params: {
|
|
13
|
+
configPath: string;
|
|
14
|
+
serverKey?: string;
|
|
15
|
+
mcpUrl: string;
|
|
16
|
+
authToken?: string;
|
|
17
|
+
platform?: NodeJS.Platform;
|
|
18
|
+
}): Promise<void>;
|
|
19
|
+
//# sourceMappingURL=claude-desktop-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-desktop-config.d.ts","sourceRoot":"","sources":["../../src/installer/claude-desktop-config.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,4BAA4B,eAAe,CAAC;AACzD,eAAO,MAAM,0BAA0B,2BAA2B,CAAC;AAEnE,sFAAsF;AACtF,wBAAgB,uBAAuB,CACrC,QAAQ,GAAE,MAAM,CAAC,QAA2B,EAC5C,IAAI,GAAE,MAAkB,GACvB,MAAM,CAeR;AAWD;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,MAAM,EACd,SAAS,CAAC,EAAE,MAAM,EAClB,QAAQ,GAAE,MAAM,CAAC,QAA2B,GAC3C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwBzB;AAED,wBAAsB,2BAA2B,CAAC,MAAM,EAAE;IACxD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;CAC5B,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
export const LOCKIN_CLAUDE_MCP_SERVER_KEY = "lockin-mcp";
|
|
5
|
+
export const LOCKIN_CLAUDE_AUTH_ENV_VAR = "LOCKIN_MCP_AUTH_HEADER";
|
|
6
|
+
/** Claude Desktop only launches stdio MCP servers from claude_desktop_config.json. */
|
|
7
|
+
export function claudeDesktopConfigPath(platform = process.platform, home = homedir()) {
|
|
8
|
+
switch (platform) {
|
|
9
|
+
case "darwin":
|
|
10
|
+
return join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
11
|
+
case "win32":
|
|
12
|
+
return join(home, "AppData", "Roaming", "Claude", "claude_desktop_config.json");
|
|
13
|
+
default:
|
|
14
|
+
return join(home, ".config", "Claude", "claude_desktop_config.json");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function normalizeRemoteMcpUrl(mcpUrl) {
|
|
18
|
+
const trimmed = mcpUrl.replace(/\/$/, "");
|
|
19
|
+
return trimmed.endsWith("/mcp") ? trimmed : `${trimmed}/mcp`;
|
|
20
|
+
}
|
|
21
|
+
function claudeDesktopLaunchCommand(platform = process.platform) {
|
|
22
|
+
return platform === "win32" ? "npx.cmd" : "npx";
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Remote MCP servers must be bridged with mcp-remote. Direct `url` entries are
|
|
26
|
+
* rejected by Claude Desktop and can prevent the app from launching.
|
|
27
|
+
*
|
|
28
|
+
* @see https://modelcontextprotocol.io/docs/develop/connect-local-servers
|
|
29
|
+
*/
|
|
30
|
+
export function buildClaudeDesktopMcpServerConfig(mcpUrl, authToken, platform = process.platform) {
|
|
31
|
+
const args = [
|
|
32
|
+
"-y",
|
|
33
|
+
"mcp-remote@latest",
|
|
34
|
+
normalizeRemoteMcpUrl(mcpUrl),
|
|
35
|
+
];
|
|
36
|
+
const config = {
|
|
37
|
+
command: claudeDesktopLaunchCommand(platform),
|
|
38
|
+
args,
|
|
39
|
+
};
|
|
40
|
+
if (authToken) {
|
|
41
|
+
config.args = [
|
|
42
|
+
...args,
|
|
43
|
+
"--header",
|
|
44
|
+
`Authorization:\${${LOCKIN_CLAUDE_AUTH_ENV_VAR}}`,
|
|
45
|
+
];
|
|
46
|
+
config.env = {
|
|
47
|
+
[LOCKIN_CLAUDE_AUTH_ENV_VAR]: `Bearer ${authToken}`,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
return config;
|
|
51
|
+
}
|
|
52
|
+
export async function mergeClaudeDesktopMcpConfig(params) {
|
|
53
|
+
const serverKey = params.serverKey ?? LOCKIN_CLAUDE_MCP_SERVER_KEY;
|
|
54
|
+
let config = {};
|
|
55
|
+
try {
|
|
56
|
+
const raw = await readFile(params.configPath, "utf8");
|
|
57
|
+
config = JSON.parse(raw);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// new config file
|
|
61
|
+
}
|
|
62
|
+
const servers = config.mcpServers && typeof config.mcpServers === "object"
|
|
63
|
+
? config.mcpServers
|
|
64
|
+
: {};
|
|
65
|
+
servers[serverKey] = buildClaudeDesktopMcpServerConfig(params.mcpUrl, params.authToken, params.platform);
|
|
66
|
+
config.mcpServers = servers;
|
|
67
|
+
await mkdir(dirname(params.configPath), { recursive: true });
|
|
68
|
+
await writeFile(params.configPath, `${JSON.stringify(config, null, 2)}\n`);
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=claude-desktop-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-desktop-config.js","sourceRoot":"","sources":["../../src/installer/claude-desktop-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-desktop-config.test.d.ts","sourceRoot":"","sources":["../../src/installer/claude-desktop-config.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { describe, expect, it } from "vitest";
|
|
3
|
+
import { LOCKIN_CLAUDE_AUTH_ENV_VAR, LOCKIN_CLAUDE_MCP_SERVER_KEY, buildClaudeDesktopMcpServerConfig, claudeDesktopConfigPath, } from "./claude-desktop-config.js";
|
|
4
|
+
describe("claudeDesktopConfigPath", () => {
|
|
5
|
+
const home = "/Users/test";
|
|
6
|
+
it("uses macOS Application Support on darwin", () => {
|
|
7
|
+
expect(claudeDesktopConfigPath("darwin", home)).toBe(join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"));
|
|
8
|
+
});
|
|
9
|
+
it("uses AppData Roaming on Windows", () => {
|
|
10
|
+
expect(claudeDesktopConfigPath("win32", home)).toBe(join(home, "AppData", "Roaming", "Claude", "claude_desktop_config.json"));
|
|
11
|
+
});
|
|
12
|
+
it("uses XDG config on Linux", () => {
|
|
13
|
+
expect(claudeDesktopConfigPath("linux", home)).toBe(join(home, ".config", "Claude", "claude_desktop_config.json"));
|
|
14
|
+
});
|
|
15
|
+
});
|
|
16
|
+
describe("buildClaudeDesktopMcpServerConfig", () => {
|
|
17
|
+
it("bridges remote MCP through mcp-remote with bearer auth in env", () => {
|
|
18
|
+
const config = buildClaudeDesktopMcpServerConfig("https://relay.lockinmcp.com/device/abc/mcp", "mdb_test", "darwin");
|
|
19
|
+
expect(config).toEqual({
|
|
20
|
+
command: "npx",
|
|
21
|
+
args: [
|
|
22
|
+
"-y",
|
|
23
|
+
"mcp-remote@latest",
|
|
24
|
+
"https://relay.lockinmcp.com/device/abc/mcp",
|
|
25
|
+
"--header",
|
|
26
|
+
`Authorization:\${${LOCKIN_CLAUDE_AUTH_ENV_VAR}}`,
|
|
27
|
+
],
|
|
28
|
+
env: {
|
|
29
|
+
[LOCKIN_CLAUDE_AUTH_ENV_VAR]: "Bearer mdb_test",
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
it("appends /mcp when the relay URL omits it", () => {
|
|
34
|
+
const config = buildClaudeDesktopMcpServerConfig("https://relay.lockinmcp.com/device/abc", "mdb_test");
|
|
35
|
+
const args = config.args;
|
|
36
|
+
expect(args[2]).toBe("https://relay.lockinmcp.com/device/abc/mcp");
|
|
37
|
+
});
|
|
38
|
+
it("uses npx.cmd on Windows", () => {
|
|
39
|
+
const config = buildClaudeDesktopMcpServerConfig("https://relay.lockinmcp.com/device/abc/mcp", "mdb_test", "win32");
|
|
40
|
+
expect(config.command).toBe("npx.cmd");
|
|
41
|
+
});
|
|
42
|
+
it("does not emit unsupported url transport fields", () => {
|
|
43
|
+
const config = buildClaudeDesktopMcpServerConfig("https://relay.lockinmcp.com/device/abc/mcp", "mdb_test");
|
|
44
|
+
expect(config).not.toHaveProperty("url");
|
|
45
|
+
expect(config).not.toHaveProperty("headers");
|
|
46
|
+
expect(LOCKIN_CLAUDE_MCP_SERVER_KEY).toBe("lockin-mcp");
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
//# sourceMappingURL=claude-desktop-config.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-desktop-config.test.js","sourceRoot":"","sources":["../../src/installer/claude-desktop-config.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const INSTALL_LOG_FILENAME = "install.log";
|
|
2
|
+
export declare const INSTALL_LOG_DISPLAY = "~/.lockin/install.log";
|
|
3
|
+
export declare const REPORT_PAGE_URL = "https://www.lockinmcp.com/report";
|
|
4
|
+
export declare const MAX_INSTALL_LOG_BYTES = 200000;
|
|
5
|
+
export declare const MAX_UPLOAD_LOG_CHARS = 50000;
|
|
6
|
+
export declare function sanitizeInstallLogLine(value: string): string;
|
|
7
|
+
export declare function getInstallLogPath(): string;
|
|
8
|
+
export declare function appendInstallLog(level: "INFO" | "WARN" | "ERROR", message: string): Promise<void>;
|
|
9
|
+
export declare function readInstallLogTail(maxChars?: number): Promise<string | null>;
|
|
10
|
+
export declare function logInstallSessionStart(): Promise<void>;
|
|
11
|
+
export declare function printInstallFailureHelp(error: unknown): void;
|
|
12
|
+
export declare function recordInstallFailure(error: unknown): Promise<void>;
|
|
13
|
+
export declare function failInstall(error: unknown): Promise<never>;
|
|
14
|
+
//# sourceMappingURL=install-log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-log.d.ts","sourceRoot":"","sources":["../../src/installer/install-log.ts"],"names":[],"mappings":"AASA,eAAO,MAAM,oBAAoB,gBAAgB,CAAC;AAClD,eAAO,MAAM,mBAAmB,0BAAsC,CAAC;AACvE,eAAO,MAAM,eAAe,qCAA+B,CAAC;AAC5D,eAAO,MAAM,qBAAqB,SAAU,CAAC;AAC7C,eAAO,MAAM,oBAAoB,QAAS,CAAC;AAS3C,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAM5D;AAED,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAqBD,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,EAChC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAOf;AAED,wBAAsB,kBAAkB,CACtC,QAAQ,SAAuB,GAC9B,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAUxB;AAED,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC,CAY5D;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,IAAI,CAc5D;AAED,wBAAsB,oBAAoB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAUxE;AAED,wBAAsB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAIhE"}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { appendFile, mkdir, readFile, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import color from "picocolors";
|
|
4
|
+
import { CANONICAL_ORIGIN } from "../brand.js";
|
|
5
|
+
import { getLicenseApiUrl } from "../config.js";
|
|
6
|
+
import { ensureDataDirMigrated, getDataDirPath } from "./data-dir.js";
|
|
7
|
+
import { detectPlatform } from "./platform.js";
|
|
8
|
+
import { toTechnicalDetail, toUserInstallMessage } from "./user-errors.js";
|
|
9
|
+
export const INSTALL_LOG_FILENAME = "install.log";
|
|
10
|
+
export const INSTALL_LOG_DISPLAY = `~/.lockin/${INSTALL_LOG_FILENAME}`;
|
|
11
|
+
export const REPORT_PAGE_URL = `${CANONICAL_ORIGIN}/report`;
|
|
12
|
+
export const MAX_INSTALL_LOG_BYTES = 200_000;
|
|
13
|
+
export const MAX_UPLOAD_LOG_CHARS = 50_000;
|
|
14
|
+
const SECRET_PATTERNS = [
|
|
15
|
+
/\b(mdb_[a-f0-9]{16,})\b/gi,
|
|
16
|
+
/\b(rly_[a-f0-9]{16,})\b/gi,
|
|
17
|
+
/\b(Bearer\s+)[^\s]+/gi,
|
|
18
|
+
/\b(token["']?\s*[:=]\s*["']?)[^"'\s]+/gi,
|
|
19
|
+
];
|
|
20
|
+
export function sanitizeInstallLogLine(value) {
|
|
21
|
+
let sanitized = value;
|
|
22
|
+
for (const pattern of SECRET_PATTERNS) {
|
|
23
|
+
sanitized = sanitized.replace(pattern, "$1[redacted]");
|
|
24
|
+
}
|
|
25
|
+
return sanitized;
|
|
26
|
+
}
|
|
27
|
+
export function getInstallLogPath() {
|
|
28
|
+
return join(getDataDirPath(), INSTALL_LOG_FILENAME);
|
|
29
|
+
}
|
|
30
|
+
function timestamp() {
|
|
31
|
+
return new Date().toISOString();
|
|
32
|
+
}
|
|
33
|
+
async function trimInstallLogIfNeeded(path) {
|
|
34
|
+
try {
|
|
35
|
+
const fileStat = await stat(path);
|
|
36
|
+
if (fileStat.size <= MAX_INSTALL_LOG_BYTES) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const raw = await readFile(path, "utf8");
|
|
40
|
+
const trimmed = raw.slice(-Math.floor(MAX_INSTALL_LOG_BYTES * 0.75));
|
|
41
|
+
await writeFile(path, trimmed, { mode: 0o600 });
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// best effort
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export async function appendInstallLog(level, message) {
|
|
48
|
+
const dir = await ensureDataDirMigrated();
|
|
49
|
+
await mkdir(dir, { recursive: true, mode: 0o700 });
|
|
50
|
+
const path = getInstallLogPath();
|
|
51
|
+
const line = `[${timestamp()}] ${level} ${sanitizeInstallLogLine(message)}\n`;
|
|
52
|
+
await appendFile(path, line, { mode: 0o600 });
|
|
53
|
+
await trimInstallLogIfNeeded(path);
|
|
54
|
+
}
|
|
55
|
+
export async function readInstallLogTail(maxChars = MAX_UPLOAD_LOG_CHARS) {
|
|
56
|
+
try {
|
|
57
|
+
const raw = await readFile(getInstallLogPath(), "utf8");
|
|
58
|
+
if (!raw.trim()) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return raw.length > maxChars ? raw.slice(-maxChars) : raw;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export async function logInstallSessionStart() {
|
|
68
|
+
const platform = detectPlatform();
|
|
69
|
+
await appendInstallLog("INFO", [
|
|
70
|
+
"session_start",
|
|
71
|
+
`platform=${platform.name}`,
|
|
72
|
+
`node=${process.version}`,
|
|
73
|
+
`api=${getLicenseApiUrl()}`,
|
|
74
|
+
`argv=${sanitizeInstallLogLine(process.argv.slice(2).join(" "))}`,
|
|
75
|
+
].join(" | "));
|
|
76
|
+
}
|
|
77
|
+
export function printInstallFailureHelp(error) {
|
|
78
|
+
const message = toUserInstallMessage(error);
|
|
79
|
+
console.error("");
|
|
80
|
+
console.error(color.red("Setup didn't finish"));
|
|
81
|
+
console.error("");
|
|
82
|
+
console.error(` ${message}`);
|
|
83
|
+
console.error("");
|
|
84
|
+
console.error(color.dim(`Need help? ${REPORT_PAGE_URL}`));
|
|
85
|
+
console.error(color.dim(`Attach ${INSTALL_LOG_DISPLAY} on the report form — it helps us fix things faster.`));
|
|
86
|
+
console.error("");
|
|
87
|
+
}
|
|
88
|
+
export async function recordInstallFailure(error) {
|
|
89
|
+
const technical = toTechnicalDetail(error);
|
|
90
|
+
const stack = error instanceof Error && error.stack
|
|
91
|
+
? sanitizeInstallLogLine(error.stack.split("\n").slice(0, 8).join(" | "))
|
|
92
|
+
: undefined;
|
|
93
|
+
await appendInstallLog("ERROR", stack ? `${technical} | ${stack}` : technical);
|
|
94
|
+
}
|
|
95
|
+
export async function failInstall(error) {
|
|
96
|
+
await recordInstallFailure(error);
|
|
97
|
+
printInstallFailureHelp(error);
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=install-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install-log.js","sourceRoot":"","sources":["../../src/installer/install-log.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-provision.d.ts","sourceRoot":"","sources":["../../src/installer/relay-provision.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"relay-provision.d.ts","sourceRoot":"","sources":["../../src/installer/relay-provision.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAiHD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAOhC;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA0B9B"}
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { canonicalizeRelayFields } from "../relay-urls.js";
|
|
2
2
|
import { getLicenseApiUrl } from "../config.js";
|
|
3
|
+
import { InstallError } from "./user-errors.js";
|
|
4
|
+
const PROVISION_TIMEOUT_MS = 30_000;
|
|
5
|
+
const MAX_ATTEMPTS = 3;
|
|
6
|
+
function sleep(ms) {
|
|
7
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
8
|
+
}
|
|
3
9
|
function parseRelayResponse(body) {
|
|
4
10
|
if (!body.deviceId || !body.relayDeviceToken || !body.mcpUrl) {
|
|
5
|
-
throw new
|
|
11
|
+
throw new InstallError("We couldn't connect your Mac to LockIn. Try running install again.", "Relay provision returned incomplete data");
|
|
6
12
|
}
|
|
7
13
|
return canonicalizeRelayFields({
|
|
8
14
|
deviceId: body.deviceId,
|
|
@@ -14,40 +20,67 @@ function parseRelayResponse(body) {
|
|
|
14
20
|
healthUrl: body.healthUrl ?? body.mcpUrl.replace(/\/mcp$/, "/health"),
|
|
15
21
|
});
|
|
16
22
|
}
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
23
|
+
async function readRelayJson(response) {
|
|
24
|
+
const text = await response.text();
|
|
25
|
+
if (!text.trim()) {
|
|
26
|
+
throw new InstallError("Something went wrong on our end. Wait a minute and try again.", `Empty response (${response.status}) from tunnel/provision`);
|
|
27
|
+
}
|
|
28
|
+
try {
|
|
29
|
+
return JSON.parse(text);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
throw new InstallError("Something went wrong on our end. Wait a minute and try again.", `Invalid JSON (${response.status}): ${text.slice(0, 200)}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
async function postProvision(body, licenseToken) {
|
|
36
|
+
const url = `${getLicenseApiUrl()}/tunnel/provision`;
|
|
37
|
+
let lastTechnical = "fetch failed";
|
|
38
|
+
for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt += 1) {
|
|
39
|
+
try {
|
|
40
|
+
return await fetch(url, {
|
|
41
|
+
method: "POST",
|
|
42
|
+
headers: {
|
|
43
|
+
"Content-Type": "application/json",
|
|
44
|
+
Authorization: `Bearer ${licenseToken}`,
|
|
45
|
+
},
|
|
46
|
+
body: JSON.stringify(body),
|
|
47
|
+
signal: AbortSignal.timeout(PROVISION_TIMEOUT_MS),
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
lastTechnical =
|
|
52
|
+
error instanceof Error ? error.message : "Network request failed";
|
|
53
|
+
if (attempt < MAX_ATTEMPTS) {
|
|
54
|
+
await sleep(1000 * attempt);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
throw new InstallError("We couldn't reach LockIn. Check your internet connection and try again.", lastTechnical);
|
|
59
|
+
}
|
|
60
|
+
async function handleProvisionResponse(response, mode) {
|
|
61
|
+
const body = await readRelayJson(response);
|
|
27
62
|
if (!response.ok) {
|
|
28
|
-
|
|
63
|
+
const technical = body.error ?? `${mode} failed (${response.status})`;
|
|
64
|
+
throw new InstallError(body.error && !/MDB_|REGISTRATION|Relay registration|not configured/i.test(body.error)
|
|
65
|
+
? body.error
|
|
66
|
+
: "We couldn't connect your Mac to LockIn. Try running install again.", technical);
|
|
29
67
|
}
|
|
68
|
+
return body;
|
|
69
|
+
}
|
|
70
|
+
export async function provisionRelayDevice(params) {
|
|
71
|
+
const response = await postProvision({ port: params.port, token: params.licenseToken }, params.licenseToken);
|
|
72
|
+
const body = await handleProvisionResponse(response, "provision");
|
|
30
73
|
return parseRelayResponse(body);
|
|
31
74
|
}
|
|
32
75
|
export async function refreshRelayRegistration(params) {
|
|
33
|
-
const response = await
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
body: JSON.stringify({
|
|
40
|
-
port: params.port,
|
|
41
|
-
refresh: true,
|
|
42
|
-
token: params.licenseToken,
|
|
43
|
-
}),
|
|
44
|
-
});
|
|
45
|
-
const body = (await response.json());
|
|
46
|
-
if (!response.ok) {
|
|
47
|
-
throw new Error(body.error ?? `Relay refresh failed (${response.status})`);
|
|
48
|
-
}
|
|
76
|
+
const response = await postProvision({
|
|
77
|
+
port: params.port,
|
|
78
|
+
refresh: true,
|
|
79
|
+
token: params.licenseToken,
|
|
80
|
+
}, params.licenseToken);
|
|
81
|
+
const body = await handleProvisionResponse(response, "refresh");
|
|
49
82
|
if (!body.deviceId || !body.mcpUrl) {
|
|
50
|
-
throw new
|
|
83
|
+
throw new InstallError("We couldn't connect your Mac to LockIn. Try running install again.", "Relay refresh returned incomplete data");
|
|
51
84
|
}
|
|
52
85
|
return canonicalizeRelayFields({
|
|
53
86
|
deviceId: body.deviceId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-provision.js","sourceRoot":"","sources":["../../src/installer/relay-provision.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAgChD,SAAS,kBAAkB,CAAC,IAAsB;IAChD,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC7D,MAAM,IAAI,
|
|
1
|
+
{"version":3,"file":"relay-provision.js","sourceRoot":"","sources":["../../src/installer/relay-provision.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/installer/run.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/installer/run.ts"],"names":[],"mappings":"AAoJA,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAQjE"}
|
package/dist/installer/run.js
CHANGED
|
@@ -23,6 +23,8 @@ import { verifyPublicTunnel, waitForHttp } from "./tunnel.js";
|
|
|
23
23
|
import { attachToTerminal } from "./tty.js";
|
|
24
24
|
import { DATA_DIR_DISPLAY } from "./data-dir.js";
|
|
25
25
|
import { writeSetupManifest } from "./setup-manifest.js";
|
|
26
|
+
import { appendInstallLog, failInstall, logInstallSessionStart, } from "./install-log.js";
|
|
27
|
+
import { InstallError } from "./user-errors.js";
|
|
26
28
|
function createMcpAuthToken(existing) {
|
|
27
29
|
return existing ?? `mdb_${randomBytes(24).toString("hex")}`;
|
|
28
30
|
}
|
|
@@ -54,13 +56,13 @@ async function setupRelayAccess(params) {
|
|
|
54
56
|
};
|
|
55
57
|
}
|
|
56
58
|
if (!params.relayCredentials) {
|
|
57
|
-
throw new
|
|
59
|
+
throw new InstallError("We couldn't connect your Mac to LockIn. Try running install again.", "Relay credentials missing");
|
|
58
60
|
}
|
|
59
61
|
const healthBase = params.relayCredentials.healthUrl
|
|
60
62
|
? params.relayCredentials.healthUrl.replace(/\/health$/, "")
|
|
61
63
|
: `${params.relayCredentials.relayUrl.replace(/\/$/, "")}/device/${params.relayCredentials.deviceId}`;
|
|
62
64
|
const verifySpinner = clack.spinner();
|
|
63
|
-
verifySpinner.start("
|
|
65
|
+
verifySpinner.start("Checking connection...");
|
|
64
66
|
const verification = await verifyPublicTunnel({
|
|
65
67
|
publicBaseUrl: healthBase,
|
|
66
68
|
authToken: params.mcpAuthToken,
|
|
@@ -68,10 +70,10 @@ async function setupRelayAccess(params) {
|
|
|
68
70
|
delayMs: 2000,
|
|
69
71
|
});
|
|
70
72
|
if (verification.healthOk && verification.mcpOk) {
|
|
71
|
-
verifySpinner.stop(color.green("
|
|
73
|
+
verifySpinner.stop(color.green("Your Mac is connected"));
|
|
72
74
|
}
|
|
73
75
|
else {
|
|
74
|
-
verifySpinner.stop(color.
|
|
76
|
+
verifySpinner.stop(color.green("Almost there — finish setup below"));
|
|
75
77
|
}
|
|
76
78
|
const publicMcpUrl = params.relayCredentials.mcpUrl?.replace(/\/mcp$/, "") ?? healthBase;
|
|
77
79
|
return {
|
|
@@ -82,14 +84,23 @@ async function setupRelayAccess(params) {
|
|
|
82
84
|
};
|
|
83
85
|
}
|
|
84
86
|
export async function runInstaller(argv) {
|
|
87
|
+
await logInstallSessionStart();
|
|
88
|
+
try {
|
|
89
|
+
return await runInstallerInner(argv);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
return failInstall(error);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function runInstallerInner(argv) {
|
|
85
96
|
attachToTerminal();
|
|
86
97
|
await ensureNodeVersion();
|
|
87
98
|
const platform = detectPlatform();
|
|
88
99
|
if (platform.id === "unsupported") {
|
|
89
|
-
throw new
|
|
100
|
+
throw new InstallError("LockIn isn't supported on this device yet.", `Unsupported platform: ${platform.name}`);
|
|
90
101
|
}
|
|
91
102
|
if (!platform.isHostsSupported) {
|
|
92
|
-
throw new
|
|
103
|
+
throw new InstallError("LockIn can't block sites on this device yet.", "Hosts-based blocking is not supported on this platform.");
|
|
93
104
|
}
|
|
94
105
|
let options = parseInstallerArgs(argv);
|
|
95
106
|
let license;
|
|
@@ -110,12 +121,12 @@ export async function runInstaller(argv) {
|
|
|
110
121
|
options = sites;
|
|
111
122
|
}
|
|
112
123
|
if (license.tier !== "pro") {
|
|
113
|
-
throw new
|
|
124
|
+
throw new InstallError("LockIn Pro is required. Sign in at lockinmcp.com to continue.", "Pro license required");
|
|
114
125
|
}
|
|
115
126
|
if (license.token) {
|
|
116
127
|
const status = await verifyLicenseInfo(license);
|
|
117
128
|
if (!status.valid) {
|
|
118
|
-
throw new
|
|
129
|
+
throw new InstallError("We couldn't verify your license. Sign in again at lockinmcp.com.", `License verification failed: ${status.error ?? "invalid token"}`);
|
|
119
130
|
}
|
|
120
131
|
}
|
|
121
132
|
const { domains } = summarizeSelections(options);
|
|
@@ -127,7 +138,7 @@ export async function runInstaller(argv) {
|
|
|
127
138
|
}
|
|
128
139
|
const blockSpinner = needsSudo ? null : clack.spinner();
|
|
129
140
|
if (blockSpinner) {
|
|
130
|
-
blockSpinner.start(`Blocking ${domains.length}
|
|
141
|
+
blockSpinner.start(`Blocking ${domains.length} site(s)...`);
|
|
131
142
|
}
|
|
132
143
|
try {
|
|
133
144
|
const result = await blockDomains(domains);
|
|
@@ -154,13 +165,14 @@ export async function runInstaller(argv) {
|
|
|
154
165
|
await uninstallLegacyTunnelLaunchAgents();
|
|
155
166
|
const stoppedBackground = await stopLockInMcpLaunchAgent();
|
|
156
167
|
if (stoppedBackground) {
|
|
157
|
-
clack.log.info("Stopped previous LockIn
|
|
168
|
+
clack.log.info("Stopped previous LockIn session for a clean setup.");
|
|
158
169
|
}
|
|
159
170
|
const portConflict = await describePortConflict(options.port);
|
|
160
171
|
if (portConflict) {
|
|
161
172
|
const resolvedPort = await resolveMcpPort(options.port);
|
|
162
173
|
if (resolvedPort !== options.port) {
|
|
163
|
-
clack.log.
|
|
174
|
+
clack.log.info("Switched to an open port for LockIn.");
|
|
175
|
+
await appendInstallLog("INFO", `port_changed ${options.port} -> ${resolvedPort} (${portConflict})`);
|
|
164
176
|
options.port = resolvedPort;
|
|
165
177
|
}
|
|
166
178
|
}
|
|
@@ -173,7 +185,7 @@ export async function runInstaller(argv) {
|
|
|
173
185
|
let relay = cacheValid ? toRelayProvisionResult(cachedRelay) : null;
|
|
174
186
|
if (cacheValid) {
|
|
175
187
|
const refreshSpinner = clack.spinner();
|
|
176
|
-
refreshSpinner.start("Refreshing
|
|
188
|
+
refreshSpinner.start("Refreshing connection...");
|
|
177
189
|
try {
|
|
178
190
|
const refreshed = await refreshRelayRegistration({
|
|
179
191
|
licenseToken: license.token,
|
|
@@ -187,7 +199,7 @@ export async function runInstaller(argv) {
|
|
|
187
199
|
sseUrl: refreshed.sseUrl,
|
|
188
200
|
healthUrl: refreshed.healthUrl,
|
|
189
201
|
};
|
|
190
|
-
refreshSpinner.stop(color.green("
|
|
202
|
+
refreshSpinner.stop(color.green("Connection ready"));
|
|
191
203
|
await writeRelayCredentials({
|
|
192
204
|
deviceId: cachedRelay.deviceId,
|
|
193
205
|
relayDeviceToken: cachedRelay.relayDeviceToken,
|
|
@@ -200,18 +212,19 @@ export async function runInstaller(argv) {
|
|
|
200
212
|
});
|
|
201
213
|
}
|
|
202
214
|
catch (error) {
|
|
203
|
-
|
|
215
|
+
await appendInstallLog("WARN", `relay_refresh_failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
216
|
+
refreshSpinner.stop(color.dim("Setting up a fresh connection..."));
|
|
204
217
|
relay = null;
|
|
205
218
|
}
|
|
206
219
|
}
|
|
207
220
|
if (!relay) {
|
|
208
221
|
const provisionSpinner = clack.spinner();
|
|
209
|
-
provisionSpinner.start("
|
|
222
|
+
provisionSpinner.start("Connecting your Mac...");
|
|
210
223
|
relay = await provisionRelayDevice({
|
|
211
224
|
licenseToken: license.token,
|
|
212
225
|
port: options.port,
|
|
213
226
|
});
|
|
214
|
-
provisionSpinner.stop(color.green(
|
|
227
|
+
provisionSpinner.stop(color.green("Connected"));
|
|
215
228
|
await writeRelayCredentials({
|
|
216
229
|
deviceId: relay.deviceId,
|
|
217
230
|
relayDeviceToken: relay.relayDeviceToken,
|
|
@@ -328,7 +341,7 @@ export async function runInstaller(argv) {
|
|
|
328
341
|
}
|
|
329
342
|
}
|
|
330
343
|
if (hasRemoteRelay) {
|
|
331
|
-
clack.outro(color.dim("
|
|
344
|
+
clack.outro(color.dim("LockIn is running. Turn on background mode next time to close this window."));
|
|
332
345
|
}
|
|
333
346
|
else {
|
|
334
347
|
clack.outro(color.dim("Keep this terminal open · Ctrl+C to stop"));
|