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.
Files changed (45) hide show
  1. package/README.md +90 -16
  2. package/dist/blocker.js +2 -2
  3. package/dist/blocker.js.map +1 -1
  4. package/dist/hosts-manager.d.ts.map +1 -1
  5. package/dist/hosts-manager.js +23 -10
  6. package/dist/hosts-manager.js.map +1 -1
  7. package/dist/hosts-manager.test.js +11 -0
  8. package/dist/hosts-manager.test.js.map +1 -1
  9. package/dist/index.js +7 -3
  10. package/dist/index.js.map +1 -1
  11. package/dist/install.js +1 -3
  12. package/dist/install.js.map +1 -1
  13. package/dist/installer/agent-instructions.d.ts.map +1 -1
  14. package/dist/installer/agent-instructions.js +2 -5
  15. package/dist/installer/agent-instructions.js.map +1 -1
  16. package/dist/installer/agents.d.ts.map +1 -1
  17. package/dist/installer/agents.js +9 -29
  18. package/dist/installer/agents.js.map +1 -1
  19. package/dist/installer/claude-desktop-config.d.ts +19 -0
  20. package/dist/installer/claude-desktop-config.d.ts.map +1 -0
  21. package/dist/installer/claude-desktop-config.js +70 -0
  22. package/dist/installer/claude-desktop-config.js.map +1 -0
  23. package/dist/installer/claude-desktop-config.test.d.ts +2 -0
  24. package/dist/installer/claude-desktop-config.test.d.ts.map +1 -0
  25. package/dist/installer/claude-desktop-config.test.js +49 -0
  26. package/dist/installer/claude-desktop-config.test.js.map +1 -0
  27. package/dist/installer/install-log.d.ts +14 -0
  28. package/dist/installer/install-log.d.ts.map +1 -0
  29. package/dist/installer/install-log.js +100 -0
  30. package/dist/installer/install-log.js.map +1 -0
  31. package/dist/installer/relay-provision.d.ts.map +1 -1
  32. package/dist/installer/relay-provision.js +62 -29
  33. package/dist/installer/relay-provision.js.map +1 -1
  34. package/dist/installer/run.d.ts.map +1 -1
  35. package/dist/installer/run.js +30 -17
  36. package/dist/installer/run.js.map +1 -1
  37. package/dist/installer/user-errors.d.ts +8 -0
  38. package/dist/installer/user-errors.d.ts.map +1 -0
  39. package/dist/installer/user-errors.js +61 -0
  40. package/dist/installer/user-errors.js.map +1 -0
  41. package/dist/installer/user-errors.test.d.ts +2 -0
  42. package/dist/installer/user-errors.test.d.ts.map +1 -0
  43. package/dist/installer/user-errors.test.js +15 -0
  44. package/dist/installer/user-errors.test.js.map +1 -0
  45. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/installer/agents.ts"],"names":[],"mappings":"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"}
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=claude-desktop-config.test.d.ts.map
@@ -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":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,0BAA0B,EAC1B,4BAA4B,EAC5B,iCAAiC,EACjC,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AAEpC,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,MAAM,IAAI,GAAG,aAAa,CAAC;IAE3B,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,CAAC,uBAAuB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAClD,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CACrF,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACjD,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CACzE,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0BAA0B,EAAE,GAAG,EAAE;QAClC,MAAM,CAAC,uBAAuB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CACjD,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,4BAA4B,CAAC,CAC9D,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IACjD,EAAE,CAAC,+DAA+D,EAAE,GAAG,EAAE;QACvE,MAAM,MAAM,GAAG,iCAAiC,CAC9C,4CAA4C,EAC5C,UAAU,EACV,QAAQ,CACT,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,OAAO,EAAE,KAAK;YACd,IAAI,EAAE;gBACJ,IAAI;gBACJ,mBAAmB;gBACnB,4CAA4C;gBAC5C,UAAU;gBACV,oBAAoB,0BAA0B,GAAG;aAClD;YACD,GAAG,EAAE;gBACH,CAAC,0BAA0B,CAAC,EAAE,iBAAiB;aAChD;SACF,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,MAAM,MAAM,GAAG,iCAAiC,CAC9C,wCAAwC,EACxC,UAAU,CACX,CAAC;QAEF,MAAM,IAAI,GAAG,MAAM,CAAC,IAAgB,CAAC;QACrC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yBAAyB,EAAE,GAAG,EAAE;QACjC,MAAM,MAAM,GAAG,iCAAiC,CAC9C,4CAA4C,EAC5C,UAAU,EACV,OAAO,CACR,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,MAAM,GAAG,iCAAiC,CAC9C,4CAA4C,EAC5C,UAAU,CACX,CAAC;QAEF,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACzC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;QAC7C,MAAM,CAAC,4BAA4B,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -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":"AAGA,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;AA6BD,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAiBhC;AAED,wBAAsB,wBAAwB,CAAC,MAAM,EAAE;IACrD,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAgC9B"}
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 Error("Relay provision returned incomplete data");
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
- export async function provisionRelayDevice(params) {
18
- const response = await fetch(`${getLicenseApiUrl()}/tunnel/provision`, {
19
- method: "POST",
20
- headers: {
21
- "Content-Type": "application/json",
22
- Authorization: `Bearer ${params.licenseToken}`,
23
- },
24
- body: JSON.stringify({ port: params.port, token: params.licenseToken }),
25
- });
26
- const body = (await response.json());
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
- throw new Error(body.error ?? `Relay provision failed (${response.status})`);
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 fetch(`${getLicenseApiUrl()}/tunnel/provision`, {
34
- method: "POST",
35
- headers: {
36
- "Content-Type": "application/json",
37
- Authorization: `Bearer ${params.licenseToken}`,
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 Error("Relay refresh returned incomplete data");
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":"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"}
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;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAgChD,MAAM,oBAAoB,GAAG,MAAM,CAAC;AACpC,MAAM,YAAY,GAAG,CAAC,CAAC;AAEvB,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,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,YAAY,CACpB,oEAAoE,EACpE,0CAA0C,CAC3C,CAAC;IACJ,CAAC;IAED,OAAO,uBAAuB,CAAC;QAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;QACvC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC;QAC3E,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE;QAC5D,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;QAClC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC;KACtE,CAAC,CAAC;AACL,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,QAAkB;IAElB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACnC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,YAAY,CACpB,+DAA+D,EAC/D,mBAAmB,QAAQ,CAAC,MAAM,yBAAyB,CAC5D,CAAC;IACJ,CAAC;IAED,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAqB,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,YAAY,CACpB,+DAA+D,EAC/D,iBAAiB,QAAQ,CAAC,MAAM,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAC3D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,aAAa,CAC1B,IAA6B,EAC7B,YAAoB;IAEpB,MAAM,GAAG,GAAG,GAAG,gBAAgB,EAAE,mBAAmB,CAAC;IACrD,IAAI,aAAa,GAAG,cAAc,CAAC;IAEnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,YAAY,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC;YACH,OAAO,MAAM,KAAK,CAAC,GAAG,EAAE;gBACtB,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE;oBACP,cAAc,EAAE,kBAAkB;oBAClC,aAAa,EAAE,UAAU,YAAY,EAAE;iBACxC;gBACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;gBAC1B,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,oBAAoB,CAAC;aAClD,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,aAAa;gBACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC;YACpE,IAAI,OAAO,GAAG,YAAY,EAAE,CAAC;gBAC3B,MAAM,KAAK,CAAC,IAAI,GAAG,OAAO,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,YAAY,CACpB,yEAAyE,EACzE,aAAa,CACd,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,QAAkB,EAClB,IAA6B;IAE7B,MAAM,IAAI,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAE3C,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,SAAS,GACb,IAAI,CAAC,KAAK,IAAI,GAAG,IAAI,YAAY,QAAQ,CAAC,MAAM,GAAG,CAAC;QACtD,MAAM,IAAI,YAAY,CACpB,IAAI,CAAC,KAAK,IAAI,CAAC,sDAAsD,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;YACpF,CAAC,CAAC,IAAI,CAAC,KAAK;YACZ,CAAC,CAAC,oEAAoE,EACxE,SAAS,CACV,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAG1C;IACC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,EACjD,MAAM,CAAC,YAAY,CACpB,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,uBAAuB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAClE,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,MAG9C;IACC,MAAM,QAAQ,GAAG,MAAM,aAAa,CAClC;QACE,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,OAAO,EAAE,IAAI;QACb,KAAK,EAAE,MAAM,CAAC,YAAY;KAC3B,EACD,MAAM,CAAC,YAAY,CACpB,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,uBAAuB,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;IAEhE,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACnC,MAAM,IAAI,YAAY,CACpB,oEAAoE,EACpE,wCAAwC,CACzC,CAAC;IACJ,CAAC;IAED,OAAO,uBAAuB,CAAC;QAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC;QAC3E,eAAe,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,QAAQ,IAAI,EAAE;QAC5D,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM;QAClC,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,SAAS,CAAC;KACtE,CAAC,CAAC;AACL,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/installer/run.ts"],"names":[],"mappings":"AA2IA,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,KAAK,CAAC,CAqVjE"}
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"}
@@ -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 Error("Relay credentials missing");
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("Verifying relay is reachable...");
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("Relay connected"));
73
+ verifySpinner.stop(color.green("Your Mac is connected"));
72
74
  }
73
75
  else {
74
- verifySpinner.stop(color.dim("Relay will connect once background service starts"));
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 Error(`Unsupported platform: ${platform.name}`);
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 Error("Hosts-based blocking is not supported on this platform.");
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 Error("Pro license required. Purchase at your dashboard.");
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 Error(`License verification failed: ${status.error ?? "invalid token"}`);
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} domain(s)...`);
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 background service for a clean install.");
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.warn(`${portConflict}. Using port ${resolvedPort} instead.`);
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 relay registration...");
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("Relay registration refreshed"));
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
- refreshSpinner.stop(color.dim("Refreshing relay reprovisioning"));
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("Provisioning relay device...");
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(`Relay device ${relay.deviceId} registered`));
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("Relay connection is active. Enable background MCP on next run to close this terminal."));
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"));