@ccpocket/bridge 1.6.0 → 1.7.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/dist/cli.js +14 -2
- package/dist/cli.js.map +1 -1
- package/dist/doctor.d.ts +49 -0
- package/dist/doctor.js +517 -0
- package/dist/doctor.js.map +1 -0
- package/dist/parser.d.ts +30 -0
- package/dist/parser.js +8 -0
- package/dist/parser.js.map +1 -1
- package/dist/websocket.d.ts +21 -0
- package/dist/websocket.js +214 -3
- package/dist/websocket.js.map +1 -1
- package/dist/worktree.d.ts +2 -0
- package/dist/worktree.js +13 -0
- package/dist/worktree.js.map +1 -1
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { startServer } from "./index.js";
|
|
3
3
|
import { setupLaunchd, uninstallLaunchd } from "./setup-launchd.js";
|
|
4
4
|
const args = process.argv.slice(2);
|
|
5
|
-
// Check for
|
|
5
|
+
// Check for subcommand
|
|
6
6
|
const subcommand = args.find((a) => !a.startsWith("-"));
|
|
7
7
|
function parseFlag(name) {
|
|
8
8
|
const idx = args.indexOf(`--${name}`);
|
|
@@ -13,7 +13,19 @@ function parseFlag(name) {
|
|
|
13
13
|
function hasFlag(name) {
|
|
14
14
|
return args.includes(`--${name}`);
|
|
15
15
|
}
|
|
16
|
-
if (subcommand === "
|
|
16
|
+
if (subcommand === "doctor") {
|
|
17
|
+
// Doctor subcommand: check environment health
|
|
18
|
+
import("./doctor.js")
|
|
19
|
+
.then(({ runDoctor, printReport }) => runDoctor().then((report) => {
|
|
20
|
+
printReport(report);
|
|
21
|
+
process.exit(report.allRequiredPassed ? 0 : 1);
|
|
22
|
+
}))
|
|
23
|
+
.catch((err) => {
|
|
24
|
+
console.error("Doctor failed:", err);
|
|
25
|
+
process.exit(1);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
else if (subcommand === "setup") {
|
|
17
29
|
// launchd setup subcommand
|
|
18
30
|
if (hasFlag("uninstall")) {
|
|
19
31
|
uninstallLaunchd();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEpE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAEpE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEnC,uBAAuB;AACvB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAExD,SAAS,SAAS,CAAC,IAAY;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;IACtC,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC3D,OAAO,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;AACvB,CAAC;AAED,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAED,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;IAC5B,8CAA8C;IAC9C,MAAM,CAAC,aAAa,CAAC;SAClB,IAAI,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,EAAE,CACnC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE;QAC1B,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,CAAC,CAAC,CACH;SACA,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAC;QACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC;KAAM,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;IAClC,2BAA2B;IAC3B,IAAI,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACzB,gBAAgB,EAAE,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,YAAY,CAAC;YACX,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC;YACvB,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC;YACvB,MAAM,EAAE,SAAS,CAAC,SAAS,CAAC;SAC7B,CAAC,CAAC;IACL,CAAC;AACH,CAAC;KAAM,CAAC;IACN,uDAAuD;IACvD,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;IAEpC,IAAI,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC;IACzC,IAAI,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC;IACzC,IAAI,MAAM;QAAE,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,MAAM,CAAC;IAEhD,WAAW,EAAE,CAAC;AAChB,CAAC"}
|
package/dist/doctor.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge Server doctor command.
|
|
3
|
+
*
|
|
4
|
+
* Checks the health of all dependencies and provides actionable guidance
|
|
5
|
+
* when issues are found — similar to `flutter doctor`.
|
|
6
|
+
*/
|
|
7
|
+
export type CheckStatus = "pass" | "fail" | "warn" | "skip";
|
|
8
|
+
export interface CheckResult {
|
|
9
|
+
name: string;
|
|
10
|
+
status: CheckStatus;
|
|
11
|
+
message: string;
|
|
12
|
+
remediation?: string;
|
|
13
|
+
}
|
|
14
|
+
export type CheckCategory = "required" | "optional";
|
|
15
|
+
export interface CheckDefinition {
|
|
16
|
+
name: string;
|
|
17
|
+
category: CheckCategory;
|
|
18
|
+
run: () => Promise<CheckResult>;
|
|
19
|
+
}
|
|
20
|
+
/** Sub-result for each CLI provider (Claude Code / Codex). */
|
|
21
|
+
export interface ProviderResult {
|
|
22
|
+
name: string;
|
|
23
|
+
installed: boolean;
|
|
24
|
+
version?: string;
|
|
25
|
+
authenticated: boolean;
|
|
26
|
+
authMessage?: string;
|
|
27
|
+
remediation?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface DoctorReport {
|
|
30
|
+
results: Array<CheckResult & {
|
|
31
|
+
category: CheckCategory;
|
|
32
|
+
providers?: ProviderResult[];
|
|
33
|
+
}>;
|
|
34
|
+
allRequiredPassed: boolean;
|
|
35
|
+
}
|
|
36
|
+
export declare function checkNodeVersion(): Promise<CheckResult>;
|
|
37
|
+
export declare function checkGit(): Promise<CheckResult>;
|
|
38
|
+
/** Check both Claude Code CLI and Codex CLI. At least one must be installed. */
|
|
39
|
+
export declare function checkCliProviders(): Promise<CheckResult & {
|
|
40
|
+
providers: ProviderResult[];
|
|
41
|
+
}>;
|
|
42
|
+
export declare function checkDependencies(): Promise<CheckResult>;
|
|
43
|
+
export declare function checkPortAvailable(port: number): Promise<CheckResult>;
|
|
44
|
+
export declare function checkTailscale(): Promise<CheckResult>;
|
|
45
|
+
export declare function checkFirebaseConnectivity(): Promise<CheckResult>;
|
|
46
|
+
export declare function checkDataDirectory(): Promise<CheckResult>;
|
|
47
|
+
export declare function checkLaunchdService(): Promise<CheckResult>;
|
|
48
|
+
export declare function runDoctor(): Promise<DoctorReport>;
|
|
49
|
+
export declare function printReport(report: DoctorReport): void;
|
package/dist/doctor.js
ADDED
|
@@ -0,0 +1,517 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge Server doctor command.
|
|
3
|
+
*
|
|
4
|
+
* Checks the health of all dependencies and provides actionable guidance
|
|
5
|
+
* when issues are found — similar to `flutter doctor`.
|
|
6
|
+
*/
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
8
|
+
import { accessSync, constants as fsConstants, existsSync, } from "node:fs";
|
|
9
|
+
import net from "node:net";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
import { join } from "node:path";
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Helper
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
function execQuiet(cmd) {
|
|
16
|
+
return execSync(cmd, { encoding: "utf-8", stdio: ["pipe", "pipe", "pipe"] }).trim();
|
|
17
|
+
}
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Individual checks
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
export async function checkNodeVersion() {
|
|
22
|
+
const version = process.version; // e.g. "v22.5.0"
|
|
23
|
+
const major = parseInt(version.slice(1), 10);
|
|
24
|
+
if (major >= 18) {
|
|
25
|
+
return { name: "Node.js", status: "pass", message: version };
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
name: "Node.js",
|
|
29
|
+
status: "fail",
|
|
30
|
+
message: `${version} (requires >=18.0.0)`,
|
|
31
|
+
remediation: "Install Node.js >=18.0.0: https://nodejs.org/",
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export async function checkGit() {
|
|
35
|
+
try {
|
|
36
|
+
const out = execQuiet("git --version"); // "git version 2.44.0"
|
|
37
|
+
const version = out.replace("git version ", "");
|
|
38
|
+
return { name: "Git", status: "pass", message: `v${version}` };
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return {
|
|
42
|
+
name: "Git",
|
|
43
|
+
status: "fail",
|
|
44
|
+
message: "Not installed",
|
|
45
|
+
remediation: "Install Git: https://git-scm.com/downloads",
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/** Check both Claude Code CLI and Codex CLI. At least one must be installed. */
|
|
50
|
+
export async function checkCliProviders() {
|
|
51
|
+
const providers = [];
|
|
52
|
+
// --- Claude Code CLI ---
|
|
53
|
+
{
|
|
54
|
+
let installed = false;
|
|
55
|
+
let version;
|
|
56
|
+
let authenticated = false;
|
|
57
|
+
let authMessage;
|
|
58
|
+
let remediation;
|
|
59
|
+
try {
|
|
60
|
+
const out = execQuiet("claude --version");
|
|
61
|
+
installed = true;
|
|
62
|
+
version = out.trim().split("\n")[0];
|
|
63
|
+
// Check auth
|
|
64
|
+
try {
|
|
65
|
+
const authOut = execQuiet("claude auth status");
|
|
66
|
+
// If exit code 0, authenticated
|
|
67
|
+
if (authOut.toLowerCase().includes("not logged in") || authOut.toLowerCase().includes("unauthenticated")) {
|
|
68
|
+
authenticated = false;
|
|
69
|
+
authMessage = "Not authenticated";
|
|
70
|
+
remediation = "Run: claude auth login";
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
authenticated = true;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// auth command failed — treat as unauthenticated
|
|
78
|
+
authenticated = false;
|
|
79
|
+
authMessage = "Not authenticated";
|
|
80
|
+
remediation = "Run: claude auth login";
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
remediation = "Install Claude Code: https://docs.anthropic.com/en/docs/claude-code/getting-started";
|
|
85
|
+
}
|
|
86
|
+
providers.push({
|
|
87
|
+
name: "Claude Code CLI",
|
|
88
|
+
installed,
|
|
89
|
+
version,
|
|
90
|
+
authenticated,
|
|
91
|
+
authMessage,
|
|
92
|
+
remediation,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
// --- Codex CLI ---
|
|
96
|
+
{
|
|
97
|
+
let installed = false;
|
|
98
|
+
let version;
|
|
99
|
+
let authenticated = false;
|
|
100
|
+
let authMessage;
|
|
101
|
+
let remediation;
|
|
102
|
+
try {
|
|
103
|
+
const out = execQuiet("codex --version");
|
|
104
|
+
installed = true;
|
|
105
|
+
version = out.trim().split("\n")[0];
|
|
106
|
+
// Codex authenticates via OPENAI_API_KEY env var or ~/.codex/auth.json
|
|
107
|
+
if (process.env.OPENAI_API_KEY) {
|
|
108
|
+
authenticated = true;
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
const authFile = join(homedir(), ".codex", "auth.json");
|
|
112
|
+
if (existsSync(authFile)) {
|
|
113
|
+
authenticated = true;
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
authenticated = false;
|
|
117
|
+
authMessage = "Not authenticated";
|
|
118
|
+
remediation = "Run: codex login";
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
remediation = "Install Codex CLI: https://github.com/openai/codex";
|
|
124
|
+
}
|
|
125
|
+
providers.push({
|
|
126
|
+
name: "Codex CLI",
|
|
127
|
+
installed,
|
|
128
|
+
version,
|
|
129
|
+
authenticated,
|
|
130
|
+
authMessage,
|
|
131
|
+
remediation,
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
const installedCount = providers.filter((p) => p.installed).length;
|
|
135
|
+
const total = providers.length;
|
|
136
|
+
if (installedCount === 0) {
|
|
137
|
+
return {
|
|
138
|
+
name: "CLI providers",
|
|
139
|
+
status: "fail",
|
|
140
|
+
message: "No CLI providers installed",
|
|
141
|
+
remediation: "Install at least one: https://docs.anthropic.com/en/docs/claude-code/getting-started OR https://github.com/openai/codex",
|
|
142
|
+
providers,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
// At least one installed — check if any auth warnings
|
|
146
|
+
const hasAuthWarn = providers.some((p) => p.installed && !p.authenticated);
|
|
147
|
+
return {
|
|
148
|
+
name: "CLI providers",
|
|
149
|
+
status: hasAuthWarn ? "warn" : "pass",
|
|
150
|
+
message: `${installedCount} of ${total} available`,
|
|
151
|
+
providers,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
export async function checkDependencies() {
|
|
155
|
+
// In monorepo setups, node_modules may be hoisted to the workspace root.
|
|
156
|
+
// Use import.meta.resolve() to check if packages are resolvable.
|
|
157
|
+
const requiredPackages = [
|
|
158
|
+
"ws",
|
|
159
|
+
"@anthropic-ai/claude-agent-sdk",
|
|
160
|
+
"@openai/codex-sdk",
|
|
161
|
+
"bonjour-service",
|
|
162
|
+
];
|
|
163
|
+
const missing = [];
|
|
164
|
+
for (const pkg of requiredPackages) {
|
|
165
|
+
try {
|
|
166
|
+
import.meta.resolve(pkg);
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
missing.push(pkg);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
if (missing.length > 0) {
|
|
173
|
+
return {
|
|
174
|
+
name: "npm dependencies",
|
|
175
|
+
status: "fail",
|
|
176
|
+
message: `Missing: ${missing.join(", ")}`,
|
|
177
|
+
remediation: "Run: npm install",
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return { name: "npm dependencies", status: "pass", message: "All packages available" };
|
|
181
|
+
}
|
|
182
|
+
export async function checkPortAvailable(port) {
|
|
183
|
+
return new Promise((resolve) => {
|
|
184
|
+
let resolved = false;
|
|
185
|
+
const done = (result) => {
|
|
186
|
+
if (resolved)
|
|
187
|
+
return;
|
|
188
|
+
resolved = true;
|
|
189
|
+
resolve(result);
|
|
190
|
+
};
|
|
191
|
+
const server = net.createServer();
|
|
192
|
+
server.once("error", (err) => {
|
|
193
|
+
if (err.code === "EADDRINUSE") {
|
|
194
|
+
done({
|
|
195
|
+
name: "Port availability",
|
|
196
|
+
status: "warn",
|
|
197
|
+
message: `Port ${port} is in use`,
|
|
198
|
+
remediation: `Another Bridge may be running, or set BRIDGE_PORT to a different port`,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
done({
|
|
203
|
+
name: "Port availability",
|
|
204
|
+
status: "warn",
|
|
205
|
+
message: `Port ${port} check failed: ${err.code}`,
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
server.listen(port, "127.0.0.1", () => {
|
|
210
|
+
server.close(() => {
|
|
211
|
+
done({
|
|
212
|
+
name: "Port availability",
|
|
213
|
+
status: "pass",
|
|
214
|
+
message: `Port ${port} is available`,
|
|
215
|
+
});
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
// Safety timeout
|
|
219
|
+
setTimeout(() => {
|
|
220
|
+
try {
|
|
221
|
+
server.close();
|
|
222
|
+
}
|
|
223
|
+
catch { /* ignore */ }
|
|
224
|
+
done({
|
|
225
|
+
name: "Port availability",
|
|
226
|
+
status: "warn",
|
|
227
|
+
message: `Port ${port} check timed out`,
|
|
228
|
+
});
|
|
229
|
+
}, 3000);
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
/** Resolve the tailscale CLI binary path (may be inside macOS .app bundle). */
|
|
233
|
+
function tailscaleCmd() {
|
|
234
|
+
// Try bare command first (Linux, Homebrew install, etc.)
|
|
235
|
+
try {
|
|
236
|
+
execQuiet("tailscale version");
|
|
237
|
+
return "tailscale";
|
|
238
|
+
}
|
|
239
|
+
catch { /* not in PATH */ }
|
|
240
|
+
// macOS: Tailscale.app bundles the CLI inside the app
|
|
241
|
+
const macPath = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
|
|
242
|
+
if (existsSync(macPath))
|
|
243
|
+
return macPath;
|
|
244
|
+
throw new Error("tailscale not found");
|
|
245
|
+
}
|
|
246
|
+
export async function checkTailscale() {
|
|
247
|
+
let cmd;
|
|
248
|
+
try {
|
|
249
|
+
cmd = tailscaleCmd();
|
|
250
|
+
}
|
|
251
|
+
catch {
|
|
252
|
+
return {
|
|
253
|
+
name: "Tailscale",
|
|
254
|
+
status: "skip",
|
|
255
|
+
message: "Not installed (optional for remote access)",
|
|
256
|
+
remediation: "Install: https://tailscale.com/download",
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
const out = execQuiet(`${cmd} status`);
|
|
261
|
+
// Extract the Tailscale IP (first IPv4 in output)
|
|
262
|
+
const ipMatch = out.match(/(\d+\.\d+\.\d+\.\d+)/);
|
|
263
|
+
const ip = ipMatch ? ipMatch[1] : "";
|
|
264
|
+
return {
|
|
265
|
+
name: "Tailscale",
|
|
266
|
+
status: "pass",
|
|
267
|
+
message: ip ? `Connected (${ip})` : "Connected",
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
catch {
|
|
271
|
+
return {
|
|
272
|
+
name: "Tailscale",
|
|
273
|
+
status: "warn",
|
|
274
|
+
message: "Installed but not connected",
|
|
275
|
+
remediation: "Run: tailscale up",
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
export async function checkFirebaseConnectivity() {
|
|
280
|
+
// Use a read-only endpoint to avoid creating anonymous accounts as a side effect
|
|
281
|
+
const FIREBASE_API_KEY = "AIzaSyAptNnokWPqJIgv2Lr3I8ETN6bqZb5BGvc";
|
|
282
|
+
const url = `https://identitytoolkit.googleapis.com/v1/accounts:lookup?key=${FIREBASE_API_KEY}`;
|
|
283
|
+
try {
|
|
284
|
+
const response = await fetch(url, {
|
|
285
|
+
method: "POST",
|
|
286
|
+
headers: { "Content-Type": "application/json" },
|
|
287
|
+
body: JSON.stringify({}),
|
|
288
|
+
signal: AbortSignal.timeout(5000),
|
|
289
|
+
});
|
|
290
|
+
// Any response (even 400) means the API is reachable
|
|
291
|
+
if (response.status < 500) {
|
|
292
|
+
return {
|
|
293
|
+
name: "Firebase connectivity",
|
|
294
|
+
status: "pass",
|
|
295
|
+
message: "Firebase Auth API reachable",
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
return {
|
|
299
|
+
name: "Firebase connectivity",
|
|
300
|
+
status: "warn",
|
|
301
|
+
message: `Firebase Auth API returned ${response.status}`,
|
|
302
|
+
remediation: "Push notifications may not work. Check network connectivity.",
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
catch {
|
|
306
|
+
return {
|
|
307
|
+
name: "Firebase connectivity",
|
|
308
|
+
status: "warn",
|
|
309
|
+
message: "Unreachable",
|
|
310
|
+
remediation: "Push notifications will be disabled. Check network connectivity.",
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
export async function checkDataDirectory() {
|
|
315
|
+
const dir = join(homedir(), ".ccpocket");
|
|
316
|
+
if (!existsSync(dir)) {
|
|
317
|
+
return {
|
|
318
|
+
name: "Data directory",
|
|
319
|
+
status: "pass",
|
|
320
|
+
message: "~/.ccpocket/ will be created on first run",
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
try {
|
|
324
|
+
accessSync(dir, fsConstants.R_OK | fsConstants.W_OK);
|
|
325
|
+
return {
|
|
326
|
+
name: "Data directory",
|
|
327
|
+
status: "pass",
|
|
328
|
+
message: "~/.ccpocket/ exists",
|
|
329
|
+
};
|
|
330
|
+
}
|
|
331
|
+
catch {
|
|
332
|
+
return {
|
|
333
|
+
name: "Data directory",
|
|
334
|
+
status: "warn",
|
|
335
|
+
message: "~/.ccpocket/ is not writable",
|
|
336
|
+
remediation: "Fix permissions: chmod u+rw ~/.ccpocket",
|
|
337
|
+
};
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
export async function checkLaunchdService() {
|
|
341
|
+
if (process.platform !== "darwin") {
|
|
342
|
+
return {
|
|
343
|
+
name: "launchd service",
|
|
344
|
+
status: "skip",
|
|
345
|
+
message: "macOS only",
|
|
346
|
+
};
|
|
347
|
+
}
|
|
348
|
+
try {
|
|
349
|
+
const out = execSync("launchctl list", {
|
|
350
|
+
encoding: "utf-8",
|
|
351
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
352
|
+
});
|
|
353
|
+
if (out.includes("com.ccpocket.bridge")) {
|
|
354
|
+
return {
|
|
355
|
+
name: "launchd service",
|
|
356
|
+
status: "pass",
|
|
357
|
+
message: "Registered",
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
return {
|
|
361
|
+
name: "launchd service",
|
|
362
|
+
status: "skip",
|
|
363
|
+
message: "Not registered",
|
|
364
|
+
remediation: "Register with: ccpocket-bridge setup",
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
catch {
|
|
368
|
+
return {
|
|
369
|
+
name: "launchd service",
|
|
370
|
+
status: "skip",
|
|
371
|
+
message: "Unable to check",
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
// ---------------------------------------------------------------------------
|
|
376
|
+
// Runner
|
|
377
|
+
// ---------------------------------------------------------------------------
|
|
378
|
+
function getAllChecks() {
|
|
379
|
+
const port = parseInt(process.env.BRIDGE_PORT ?? "8765", 10);
|
|
380
|
+
return [
|
|
381
|
+
// Required
|
|
382
|
+
{ name: "Node.js", category: "required", run: checkNodeVersion },
|
|
383
|
+
{ name: "Git", category: "required", run: checkGit },
|
|
384
|
+
{ name: "CLI providers", category: "required", run: checkCliProviders },
|
|
385
|
+
{ name: "npm dependencies", category: "required", run: checkDependencies },
|
|
386
|
+
{
|
|
387
|
+
name: "Port availability",
|
|
388
|
+
category: "required",
|
|
389
|
+
run: () => checkPortAvailable(port),
|
|
390
|
+
},
|
|
391
|
+
// Optional
|
|
392
|
+
{ name: "Tailscale", category: "optional", run: checkTailscale },
|
|
393
|
+
{
|
|
394
|
+
name: "Firebase connectivity",
|
|
395
|
+
category: "optional",
|
|
396
|
+
run: checkFirebaseConnectivity,
|
|
397
|
+
},
|
|
398
|
+
{ name: "Data directory", category: "optional", run: checkDataDirectory },
|
|
399
|
+
{
|
|
400
|
+
name: "launchd service",
|
|
401
|
+
category: "optional",
|
|
402
|
+
run: checkLaunchdService,
|
|
403
|
+
},
|
|
404
|
+
];
|
|
405
|
+
}
|
|
406
|
+
export async function runDoctor() {
|
|
407
|
+
const checks = getAllChecks();
|
|
408
|
+
const results = [];
|
|
409
|
+
for (const check of checks) {
|
|
410
|
+
const result = await check.run();
|
|
411
|
+
results.push({ ...result, category: check.category });
|
|
412
|
+
}
|
|
413
|
+
const allRequiredPassed = results
|
|
414
|
+
.filter((r) => r.category === "required")
|
|
415
|
+
.every((r) => r.status === "pass" || r.status === "warn");
|
|
416
|
+
return { results, allRequiredPassed };
|
|
417
|
+
}
|
|
418
|
+
// ---------------------------------------------------------------------------
|
|
419
|
+
// Output formatting
|
|
420
|
+
// ---------------------------------------------------------------------------
|
|
421
|
+
const SYMBOLS_TTY = {
|
|
422
|
+
pass: "\x1b[32m✓\x1b[0m",
|
|
423
|
+
fail: "\x1b[31m✗\x1b[0m",
|
|
424
|
+
warn: "\x1b[33m!\x1b[0m",
|
|
425
|
+
skip: "\x1b[90m-\x1b[0m",
|
|
426
|
+
};
|
|
427
|
+
const SYMBOLS_PLAIN = {
|
|
428
|
+
pass: "[OK]",
|
|
429
|
+
fail: "[FAIL]",
|
|
430
|
+
warn: "[WARN]",
|
|
431
|
+
skip: "[SKIP]",
|
|
432
|
+
};
|
|
433
|
+
function providerStatusIcon(p, sym) {
|
|
434
|
+
if (!p.installed)
|
|
435
|
+
return sym.skip;
|
|
436
|
+
if (!p.authenticated)
|
|
437
|
+
return sym.warn;
|
|
438
|
+
return sym.pass;
|
|
439
|
+
}
|
|
440
|
+
function providerStatusMessage(p) {
|
|
441
|
+
if (!p.installed)
|
|
442
|
+
return "Not installed";
|
|
443
|
+
const parts = [];
|
|
444
|
+
if (p.version)
|
|
445
|
+
parts.push(p.version);
|
|
446
|
+
if (p.authenticated) {
|
|
447
|
+
parts.push("(authenticated)");
|
|
448
|
+
}
|
|
449
|
+
else if (p.authMessage) {
|
|
450
|
+
parts.push(`(${p.authMessage})`);
|
|
451
|
+
}
|
|
452
|
+
return parts.join(" ") || "Installed";
|
|
453
|
+
}
|
|
454
|
+
export function printReport(report) {
|
|
455
|
+
const isTTY = process.stdout.isTTY ?? false;
|
|
456
|
+
const sym = isTTY ? SYMBOLS_TTY : SYMBOLS_PLAIN;
|
|
457
|
+
const NAME_WIDTH = 22;
|
|
458
|
+
console.log("");
|
|
459
|
+
console.log("ccpocket-bridge doctor");
|
|
460
|
+
console.log("======================");
|
|
461
|
+
// Required checks
|
|
462
|
+
const required = report.results.filter((r) => r.category === "required");
|
|
463
|
+
if (required.length > 0) {
|
|
464
|
+
console.log("");
|
|
465
|
+
console.log("Required:");
|
|
466
|
+
for (const r of required) {
|
|
467
|
+
const icon = sym[r.status];
|
|
468
|
+
const nameCol = r.name.padEnd(NAME_WIDTH);
|
|
469
|
+
console.log(` ${icon} ${nameCol} ${r.message}`);
|
|
470
|
+
// Print provider sub-items for CLI providers check
|
|
471
|
+
if (r.providers) {
|
|
472
|
+
for (const p of r.providers) {
|
|
473
|
+
const pIcon = providerStatusIcon(p, sym);
|
|
474
|
+
const pName = p.name.padEnd(NAME_WIDTH);
|
|
475
|
+
console.log(` ${pIcon} ${pName} ${providerStatusMessage(p)}`);
|
|
476
|
+
if (p.remediation) {
|
|
477
|
+
console.log(` → ${p.remediation}`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
else if (r.remediation && (r.status === "fail" || r.status === "warn")) {
|
|
482
|
+
console.log(` → ${r.remediation}`);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
// Optional checks
|
|
487
|
+
const optional = report.results.filter((r) => r.category === "optional");
|
|
488
|
+
if (optional.length > 0) {
|
|
489
|
+
console.log("");
|
|
490
|
+
console.log("Optional:");
|
|
491
|
+
for (const r of optional) {
|
|
492
|
+
const icon = sym[r.status];
|
|
493
|
+
const nameCol = r.name.padEnd(NAME_WIDTH);
|
|
494
|
+
console.log(` ${icon} ${nameCol} ${r.message}`);
|
|
495
|
+
if (r.remediation && (r.status === "fail" || r.status === "warn" || r.status === "skip")) {
|
|
496
|
+
console.log(` → ${r.remediation}`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
}
|
|
500
|
+
// Summary
|
|
501
|
+
console.log("");
|
|
502
|
+
const failCount = report.results.filter((r) => r.status === "fail").length;
|
|
503
|
+
const warnCount = report.results.filter((r) => r.status === "warn").length;
|
|
504
|
+
if (report.allRequiredPassed) {
|
|
505
|
+
const msg = "All required checks passed.";
|
|
506
|
+
console.log(isTTY ? `\x1b[32m${msg}\x1b[0m` : msg);
|
|
507
|
+
}
|
|
508
|
+
else {
|
|
509
|
+
const msg = `${failCount} required check(s) failed.`;
|
|
510
|
+
console.log(isTTY ? `\x1b[31m${msg}\x1b[0m` : msg);
|
|
511
|
+
}
|
|
512
|
+
if (warnCount > 0) {
|
|
513
|
+
console.log(`${warnCount} warning(s).`);
|
|
514
|
+
}
|
|
515
|
+
console.log("");
|
|
516
|
+
}
|
|
517
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../src/doctor.ts"],"names":[],"mappings":"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"}
|