@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 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 "setup" subcommand
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 === "setup") {
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,+BAA+B;AAC/B,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,OAAO,EAAE,CAAC;IAC3B,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"}
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"}
@@ -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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"}