@helmisatria/mcp-chrome-bridge 1.0.30

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 (129) hide show
  1. package/README.md +183 -0
  2. package/dist/README.md +25 -0
  3. package/dist/agent/attachment-service.d.ts +83 -0
  4. package/dist/agent/attachment-service.js +370 -0
  5. package/dist/agent/attachment-service.js.map +1 -0
  6. package/dist/agent/ccr-detector.d.ts +59 -0
  7. package/dist/agent/ccr-detector.js +311 -0
  8. package/dist/agent/ccr-detector.js.map +1 -0
  9. package/dist/agent/chat-service.d.ts +50 -0
  10. package/dist/agent/chat-service.js +439 -0
  11. package/dist/agent/chat-service.js.map +1 -0
  12. package/dist/agent/db/client.d.ts +26 -0
  13. package/dist/agent/db/client.js +244 -0
  14. package/dist/agent/db/client.js.map +1 -0
  15. package/dist/agent/db/index.d.ts +5 -0
  16. package/dist/agent/db/index.js +22 -0
  17. package/dist/agent/db/index.js.map +1 -0
  18. package/dist/agent/db/schema.d.ts +711 -0
  19. package/dist/agent/db/schema.js +121 -0
  20. package/dist/agent/db/schema.js.map +1 -0
  21. package/dist/agent/directory-picker.d.ts +11 -0
  22. package/dist/agent/directory-picker.js +149 -0
  23. package/dist/agent/directory-picker.js.map +1 -0
  24. package/dist/agent/engines/claude.d.ts +79 -0
  25. package/dist/agent/engines/claude.js +1338 -0
  26. package/dist/agent/engines/claude.js.map +1 -0
  27. package/dist/agent/engines/codex.d.ts +48 -0
  28. package/dist/agent/engines/codex.js +822 -0
  29. package/dist/agent/engines/codex.js.map +1 -0
  30. package/dist/agent/engines/types.d.ts +133 -0
  31. package/dist/agent/engines/types.js +3 -0
  32. package/dist/agent/engines/types.js.map +1 -0
  33. package/dist/agent/message-service.d.ts +56 -0
  34. package/dist/agent/message-service.js +198 -0
  35. package/dist/agent/message-service.js.map +1 -0
  36. package/dist/agent/open-project.d.ts +25 -0
  37. package/dist/agent/open-project.js +469 -0
  38. package/dist/agent/open-project.js.map +1 -0
  39. package/dist/agent/project-service.d.ts +49 -0
  40. package/dist/agent/project-service.js +254 -0
  41. package/dist/agent/project-service.js.map +1 -0
  42. package/dist/agent/project-types.d.ts +27 -0
  43. package/dist/agent/project-types.js +3 -0
  44. package/dist/agent/project-types.js.map +1 -0
  45. package/dist/agent/session-service.d.ts +198 -0
  46. package/dist/agent/session-service.js +292 -0
  47. package/dist/agent/session-service.js.map +1 -0
  48. package/dist/agent/storage.d.ts +27 -0
  49. package/dist/agent/storage.js +73 -0
  50. package/dist/agent/storage.js.map +1 -0
  51. package/dist/agent/stream-manager.d.ts +42 -0
  52. package/dist/agent/stream-manager.js +243 -0
  53. package/dist/agent/stream-manager.js.map +1 -0
  54. package/dist/agent/tool-bridge.d.ts +44 -0
  55. package/dist/agent/tool-bridge.js +50 -0
  56. package/dist/agent/tool-bridge.js.map +1 -0
  57. package/dist/agent/types.d.ts +6 -0
  58. package/dist/agent/types.js +3 -0
  59. package/dist/agent/types.js.map +1 -0
  60. package/dist/cli.d.ts +2 -0
  61. package/dist/cli.js +224 -0
  62. package/dist/cli.js.map +1 -0
  63. package/dist/constant/index.d.ts +60 -0
  64. package/dist/constant/index.js +80 -0
  65. package/dist/constant/index.js.map +1 -0
  66. package/dist/file-handler.d.ts +41 -0
  67. package/dist/file-handler.js +295 -0
  68. package/dist/file-handler.js.map +1 -0
  69. package/dist/index.d.ts +2 -0
  70. package/dist/index.js +35 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/mcp/mcp-server-stdio.d.ts +72 -0
  73. package/dist/mcp/mcp-server-stdio.js +143 -0
  74. package/dist/mcp/mcp-server-stdio.js.map +1 -0
  75. package/dist/mcp/mcp-server.d.ts +36 -0
  76. package/dist/mcp/mcp-server.js +26 -0
  77. package/dist/mcp/mcp-server.js.map +1 -0
  78. package/dist/mcp/register-tools.d.ts +2 -0
  79. package/dist/mcp/register-tools.js +148 -0
  80. package/dist/mcp/register-tools.js.map +1 -0
  81. package/dist/mcp/stdio-config.json +3 -0
  82. package/dist/native-messaging-host.d.ts +42 -0
  83. package/dist/native-messaging-host.js +312 -0
  84. package/dist/native-messaging-host.js.map +1 -0
  85. package/dist/run_host.bat +194 -0
  86. package/dist/run_host.sh +264 -0
  87. package/dist/scripts/browser-config.d.ts +28 -0
  88. package/dist/scripts/browser-config.js +229 -0
  89. package/dist/scripts/browser-config.js.map +1 -0
  90. package/dist/scripts/build.d.ts +1 -0
  91. package/dist/scripts/build.js +126 -0
  92. package/dist/scripts/build.js.map +1 -0
  93. package/dist/scripts/constant.d.ts +4 -0
  94. package/dist/scripts/constant.js +8 -0
  95. package/dist/scripts/constant.js.map +1 -0
  96. package/dist/scripts/doctor.d.ts +70 -0
  97. package/dist/scripts/doctor.js +930 -0
  98. package/dist/scripts/doctor.js.map +1 -0
  99. package/dist/scripts/postinstall.d.ts +2 -0
  100. package/dist/scripts/postinstall.js +246 -0
  101. package/dist/scripts/postinstall.js.map +1 -0
  102. package/dist/scripts/register-dev.d.ts +1 -0
  103. package/dist/scripts/register-dev.js +5 -0
  104. package/dist/scripts/register-dev.js.map +1 -0
  105. package/dist/scripts/register.d.ts +2 -0
  106. package/dist/scripts/register.js +28 -0
  107. package/dist/scripts/register.js.map +1 -0
  108. package/dist/scripts/report.d.ts +96 -0
  109. package/dist/scripts/report.js +686 -0
  110. package/dist/scripts/report.js.map +1 -0
  111. package/dist/scripts/utils.d.ts +64 -0
  112. package/dist/scripts/utils.js +443 -0
  113. package/dist/scripts/utils.js.map +1 -0
  114. package/dist/server/index.d.ts +35 -0
  115. package/dist/server/index.js +312 -0
  116. package/dist/server/index.js.map +1 -0
  117. package/dist/server/routes/agent.d.ts +21 -0
  118. package/dist/server/routes/agent.js +971 -0
  119. package/dist/server/routes/agent.js.map +1 -0
  120. package/dist/server/routes/index.d.ts +4 -0
  121. package/dist/server/routes/index.js +9 -0
  122. package/dist/server/routes/index.js.map +1 -0
  123. package/dist/trace-analyzer.d.ts +14 -0
  124. package/dist/trace-analyzer.js +113 -0
  125. package/dist/trace-analyzer.js.map +1 -0
  126. package/dist/util/logger.d.ts +1 -0
  127. package/dist/util/logger.js +43 -0
  128. package/dist/util/logger.js.map +1 -0
  129. package/package.json +91 -0
@@ -0,0 +1,686 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ /**
4
+ * report.ts
5
+ *
6
+ * Export a diagnostic report for GitHub Issues.
7
+ * Collects system info, doctor output, logs, manifests, and registry info.
8
+ */
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.runReport = runReport;
14
+ const fs_1 = __importDefault(require("fs"));
15
+ const os_1 = __importDefault(require("os"));
16
+ const path_1 = __importDefault(require("path"));
17
+ const child_process_1 = require("child_process");
18
+ const constant_1 = require("./constant");
19
+ const browser_config_1 = require("./browser-config");
20
+ const utils_1 = require("./utils");
21
+ const doctor_1 = require("./doctor");
22
+ const REPORT_SCHEMA_VERSION = 1;
23
+ const DEFAULT_LOG_LINES = 200;
24
+ const DEFAULT_TAIL_BYTES = 256 * 1024;
25
+ const MAX_LOG_FILES = 6;
26
+ const MAX_FULL_LOG_BYTES = 1024 * 1024;
27
+ function stringifyError(err) {
28
+ if (err instanceof Error)
29
+ return err.message;
30
+ return String(err);
31
+ }
32
+ function readPackageJson() {
33
+ try {
34
+ return require('../../package.json');
35
+ }
36
+ catch (_a) {
37
+ return {};
38
+ }
39
+ }
40
+ function getToolVersion() {
41
+ const pkg = readPackageJson();
42
+ const name = typeof pkg.name === 'string' ? pkg.name : constant_1.COMMAND_NAME;
43
+ const version = typeof pkg.version === 'string' ? pkg.version : 'unknown';
44
+ return { name, version };
45
+ }
46
+ function safeOsVersion() {
47
+ try {
48
+ return os_1.default.version();
49
+ }
50
+ catch (_a) {
51
+ return undefined;
52
+ }
53
+ }
54
+ function safeExecVersion(command) {
55
+ try {
56
+ const out = (0, child_process_1.execFileSync)(command, ['-v'], {
57
+ encoding: 'utf8',
58
+ stdio: ['ignore', 'pipe', 'pipe'],
59
+ timeout: 2500,
60
+ windowsHide: true,
61
+ });
62
+ return { version: out.trim() };
63
+ }
64
+ catch (e) {
65
+ return { error: stringifyError(e) };
66
+ }
67
+ }
68
+ function parseIncludeLogsMode(raw) {
69
+ const v = typeof raw === 'string' ? raw.toLowerCase() : '';
70
+ if (v === 'none' || v === 'tail' || v === 'full')
71
+ return v;
72
+ return 'tail';
73
+ }
74
+ function parsePositiveInt(raw, fallback) {
75
+ if (typeof raw === 'number' && Number.isFinite(raw) && raw > 0)
76
+ return Math.floor(raw);
77
+ if (typeof raw === 'string') {
78
+ const parsed = Number.parseInt(raw, 10);
79
+ if (Number.isFinite(parsed) && parsed > 0)
80
+ return parsed;
81
+ }
82
+ return fallback;
83
+ }
84
+ function resolveBrowsers(browserArg) {
85
+ if (!browserArg) {
86
+ const detected = (0, browser_config_1.detectInstalledBrowsers)();
87
+ return detected.length > 0 ? detected : [browser_config_1.BrowserType.CHROME, browser_config_1.BrowserType.CHROMIUM];
88
+ }
89
+ const normalized = browserArg.toLowerCase();
90
+ if (normalized === 'all')
91
+ return [browser_config_1.BrowserType.CHROME, browser_config_1.BrowserType.CHROMIUM];
92
+ if (normalized === 'detect' || normalized === 'auto') {
93
+ const detected = (0, browser_config_1.detectInstalledBrowsers)();
94
+ return detected.length > 0 ? detected : [browser_config_1.BrowserType.CHROME, browser_config_1.BrowserType.CHROMIUM];
95
+ }
96
+ const parsed = (0, browser_config_1.parseBrowserType)(normalized);
97
+ if (!parsed) {
98
+ throw new Error(`Invalid browser: ${browserArg}. Use 'chrome', 'chromium', or 'all'`);
99
+ }
100
+ return [parsed];
101
+ }
102
+ function readJsonSnapshot(filePath) {
103
+ try {
104
+ if (!fs_1.default.existsSync(filePath))
105
+ return { exists: false };
106
+ const raw = fs_1.default.readFileSync(filePath, 'utf8');
107
+ try {
108
+ const json = JSON.parse(raw);
109
+ return { exists: true, json };
110
+ }
111
+ catch (e) {
112
+ return { exists: true, raw, error: `Failed to parse JSON: ${stringifyError(e)}` };
113
+ }
114
+ }
115
+ catch (e) {
116
+ return { exists: fs_1.default.existsSync(filePath), error: stringifyError(e) };
117
+ }
118
+ }
119
+ function collectManifests(browsers) {
120
+ const results = [];
121
+ for (const browser of browsers) {
122
+ const config = (0, browser_config_1.getBrowserConfig)(browser);
123
+ for (const scope of ['user', 'system']) {
124
+ const manifestPath = scope === 'user' ? config.userManifestPath : config.systemManifestPath;
125
+ const snap = readJsonSnapshot(manifestPath);
126
+ results.push({
127
+ browser,
128
+ scope,
129
+ path: manifestPath,
130
+ exists: snap.exists,
131
+ json: snap.json,
132
+ raw: snap.raw,
133
+ error: snap.error,
134
+ });
135
+ }
136
+ }
137
+ return results;
138
+ }
139
+ function readFileTail(filePath, maxBytes, maxLines) {
140
+ const stat = fs_1.default.statSync(filePath);
141
+ const size = stat.size;
142
+ const bytesToRead = Math.min(size, maxBytes);
143
+ const start = Math.max(0, size - bytesToRead);
144
+ const fd = fs_1.default.openSync(filePath, 'r');
145
+ try {
146
+ const buf = Buffer.alloc(bytesToRead);
147
+ fs_1.default.readSync(fd, buf, 0, bytesToRead, start);
148
+ const text = buf.toString('utf8');
149
+ const lines = text.split(/\r?\n/);
150
+ const tail = lines.slice(Math.max(0, lines.length - maxLines));
151
+ return { content: tail.join('\n'), truncated: size > maxBytes || lines.length > maxLines };
152
+ }
153
+ finally {
154
+ fs_1.default.closeSync(fd);
155
+ }
156
+ }
157
+ function readFileLastBytes(filePath, maxBytes) {
158
+ const stat = fs_1.default.statSync(filePath);
159
+ const size = stat.size;
160
+ if (size <= maxBytes) {
161
+ const content = fs_1.default.readFileSync(filePath, 'utf8');
162
+ return { content, truncated: false };
163
+ }
164
+ const bytesToRead = maxBytes;
165
+ const start = Math.max(0, size - bytesToRead);
166
+ const fd = fs_1.default.openSync(filePath, 'r');
167
+ try {
168
+ const buf = Buffer.alloc(bytesToRead);
169
+ fs_1.default.readSync(fd, buf, 0, bytesToRead, start);
170
+ const content = buf.toString('utf8');
171
+ return { content, truncated: true };
172
+ }
173
+ finally {
174
+ fs_1.default.closeSync(fd);
175
+ }
176
+ }
177
+ function collectWrapperLogs(logDir, mode, logLines) {
178
+ if (!fs_1.default.existsSync(logDir)) {
179
+ return { dir: logDir, mode, files: [], error: 'Log directory does not exist' };
180
+ }
181
+ const prefixes = ['native_host_wrapper_', 'native_host_stderr_'];
182
+ let entries = [];
183
+ try {
184
+ entries = fs_1.default.readdirSync(logDir, { withFileTypes: true });
185
+ }
186
+ catch (e) {
187
+ return { dir: logDir, mode, files: [], error: stringifyError(e) };
188
+ }
189
+ const candidates = entries
190
+ .filter((ent) => ent.isFile())
191
+ .map((ent) => ent.name)
192
+ .filter((name) => name.endsWith('.log') && prefixes.some((p) => name.startsWith(p)));
193
+ const filesWithStat = [];
194
+ for (const name of candidates) {
195
+ const fullPath = path_1.default.join(logDir, name);
196
+ try {
197
+ const stat = fs_1.default.statSync(fullPath);
198
+ filesWithStat.push({ name, fullPath, mtimeMs: stat.mtimeMs, size: stat.size });
199
+ }
200
+ catch (_a) {
201
+ // ignore
202
+ }
203
+ }
204
+ filesWithStat.sort((a, b) => b.mtimeMs - a.mtimeMs);
205
+ const selected = filesWithStat.slice(0, MAX_LOG_FILES);
206
+ const snapshots = [];
207
+ for (const file of selected) {
208
+ const snap = {
209
+ name: file.name,
210
+ path: file.fullPath,
211
+ mtime: new Date(file.mtimeMs).toISOString(),
212
+ size: file.size,
213
+ };
214
+ if (mode !== 'none') {
215
+ try {
216
+ if (mode === 'tail') {
217
+ const read = readFileTail(file.fullPath, DEFAULT_TAIL_BYTES, logLines);
218
+ snap.content = read.content;
219
+ snap.truncated = read.truncated;
220
+ snap.note = `Tail: last ${logLines} lines (from last ${DEFAULT_TAIL_BYTES} bytes)`;
221
+ }
222
+ else {
223
+ const read = readFileLastBytes(file.fullPath, MAX_FULL_LOG_BYTES);
224
+ snap.content = read.content;
225
+ snap.truncated = read.truncated;
226
+ snap.note = read.truncated
227
+ ? `Truncated: showing last ${MAX_FULL_LOG_BYTES} bytes`
228
+ : 'Full file';
229
+ }
230
+ }
231
+ catch (e) {
232
+ snap.error = stringifyError(e);
233
+ }
234
+ }
235
+ else {
236
+ snap.note = 'Content omitted';
237
+ }
238
+ snapshots.push(snap);
239
+ }
240
+ return { dir: logDir, mode, files: snapshots };
241
+ }
242
+ function queryWindowsRegistryDefaultValue(registryKey) {
243
+ try {
244
+ const output = (0, child_process_1.execFileSync)('reg', ['query', registryKey, '/ve'], {
245
+ encoding: 'utf8',
246
+ stdio: ['ignore', 'pipe', 'pipe'],
247
+ timeout: 2500,
248
+ windowsHide: true,
249
+ });
250
+ const lines = output
251
+ .split(/\r?\n/)
252
+ .map((l) => l.trim())
253
+ .filter(Boolean);
254
+ for (const line of lines) {
255
+ const match = line.match(/REG_SZ\s+(.*)$/i);
256
+ if (match === null || match === void 0 ? void 0 : match[1])
257
+ return { value: match[1].trim(), raw: output };
258
+ }
259
+ return { raw: output, error: 'No REG_SZ default value found' };
260
+ }
261
+ catch (e) {
262
+ return { error: stringifyError(e) };
263
+ }
264
+ }
265
+ function collectWindowsRegistry(browsers) {
266
+ const entries = [];
267
+ for (const browser of browsers) {
268
+ const config = (0, browser_config_1.getBrowserConfig)(browser);
269
+ const keySpecs = [
270
+ config.registryKey
271
+ ? { key: config.registryKey, scope: 'user', expected: config.userManifestPath }
272
+ : null,
273
+ config.systemRegistryKey
274
+ ? {
275
+ key: config.systemRegistryKey,
276
+ scope: 'system',
277
+ expected: config.systemManifestPath,
278
+ }
279
+ : null,
280
+ ].filter(Boolean);
281
+ for (const spec of keySpecs) {
282
+ const res = queryWindowsRegistryDefaultValue(spec.key);
283
+ entries.push({
284
+ browser,
285
+ scope: spec.scope,
286
+ key: spec.key,
287
+ expectedManifestPath: spec.expected,
288
+ value: res.value,
289
+ raw: res.raw,
290
+ error: res.error,
291
+ });
292
+ }
293
+ }
294
+ return { entries };
295
+ }
296
+ // ============================================================================
297
+ // Redaction
298
+ // ============================================================================
299
+ function escapeRegExp(input) {
300
+ return input.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
301
+ }
302
+ function buildLiteralReplacements() {
303
+ const replacements = [];
304
+ const ignoreCase = process.platform === 'win32';
305
+ const addLiteral = (literal, replacement) => {
306
+ if (!literal)
307
+ return;
308
+ const variants = new Set();
309
+ variants.add(literal);
310
+ variants.add(literal.replace(/\\/g, '/'));
311
+ variants.add(literal.replace(/\//g, '\\'));
312
+ for (const v of variants) {
313
+ if (!v)
314
+ continue;
315
+ replacements.push([new RegExp(escapeRegExp(v), ignoreCase ? 'gi' : 'g'), replacement]);
316
+ }
317
+ };
318
+ addLiteral(os_1.default.homedir(), '<HOME>');
319
+ addLiteral(process.env.USERPROFILE, '<USERPROFILE>');
320
+ addLiteral(process.env.HOME, '<HOME>');
321
+ try {
322
+ const username = os_1.default.userInfo().username;
323
+ if (username) {
324
+ replacements.push([
325
+ new RegExp(`\\b${escapeRegExp(username)}\\b`, ignoreCase ? 'gi' : 'g'),
326
+ '<USER>',
327
+ ]);
328
+ }
329
+ }
330
+ catch (_a) {
331
+ // ignore
332
+ }
333
+ return replacements;
334
+ }
335
+ function createRedactor(enabled) {
336
+ if (!enabled)
337
+ return (s) => s;
338
+ const literalReplacements = buildLiteralReplacements();
339
+ const patternReplacements = [
340
+ // Sensitive key=value patterns (supports JSON-style "key": "value" and env-style KEY=value)
341
+ [
342
+ /(\b[A-Z0-9_]*(?:TOKEN|PASSWORD|SECRET|API_KEY|ACCESS_KEY|PRIVATE_KEY)\b)(\s*["']?\s*[:=]\s*["']?)([^\s"']+)/gi,
343
+ '$1$2<REDACTED>',
344
+ ],
345
+ // HTTP Authorization headers
346
+ [/(Authorization:\s*Bearer\s+)[^\s]+/gi, '$1<REDACTED>'],
347
+ [/(Authorization:\s*Basic\s+)[^\s]+/gi, '$1<REDACTED>'],
348
+ // JSON-style Authorization fields ("Authorization": "Bearer ...")
349
+ [
350
+ /(\bAuthorization\b)(\s*["']?\s*[:=]\s*["']?)(Bearer\s+|Basic\s+)?[^\s"']+/gi,
351
+ '$1$2$3<REDACTED>',
352
+ ],
353
+ // Cookies
354
+ [/(Cookie:\s*)[^\r\n]+/gi, '$1<REDACTED>'],
355
+ [/(Set-Cookie:\s*)[^\r\n]+/gi, '$1<REDACTED>'],
356
+ // JSON-style Cookie fields ("Cookie": "...")
357
+ [/(\b(?:Cookie|Set-Cookie)\b)(\s*["']?\s*[:=]\s*["']?)[^\r\n"']+/gi, '$1$2<REDACTED>'],
358
+ // Common API header patterns (supports JSON-style)
359
+ [
360
+ /(\b(?:x-api-key|api-key|x-auth-token|x-access-token)\b)(\s*["']?\s*[:=]\s*["']?)([^\s"']+)/gi,
361
+ '$1$2<REDACTED>',
362
+ ],
363
+ // Email addresses
364
+ [/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, '<EMAIL>'],
365
+ // User paths (Windows and macOS/Linux)
366
+ [/[A-Z]:\\Users\\[^\\]+/gi, '<USERPROFILE>'],
367
+ [/\/Users\/[^/]+/g, '/Users/<USER>'],
368
+ ];
369
+ return (input) => {
370
+ let out = input;
371
+ for (const [re, replacement] of literalReplacements) {
372
+ out = out.replace(re, replacement);
373
+ }
374
+ for (const [re, replacement] of patternReplacements) {
375
+ out = out.replace(re, replacement);
376
+ }
377
+ return out;
378
+ };
379
+ }
380
+ function redactDeep(value, redact) {
381
+ if (typeof value === 'string')
382
+ return redact(value);
383
+ if (Array.isArray(value))
384
+ return value.map((v) => redactDeep(v, redact));
385
+ if (value && typeof value === 'object') {
386
+ const obj = value;
387
+ const out = {};
388
+ for (const [k, v] of Object.entries(obj)) {
389
+ out[k] = redactDeep(v, redact);
390
+ }
391
+ return out;
392
+ }
393
+ return value;
394
+ }
395
+ // ============================================================================
396
+ // Output Rendering
397
+ // ============================================================================
398
+ function renderMarkdown(report) {
399
+ var _a, _b, _c, _d, _e;
400
+ const lines = [];
401
+ lines.push(`# ${report.tool.name} Diagnostic Report`);
402
+ lines.push('');
403
+ lines.push(`**Generated:** ${report.timestamp}`);
404
+ lines.push(`**Redaction:** ${report.redaction.enabled ? 'enabled (default)' : 'disabled'}`);
405
+ lines.push('');
406
+ lines.push('## Environment');
407
+ lines.push('');
408
+ lines.push(`- **Platform:** ${report.environment.platform} (${report.environment.arch})`);
409
+ lines.push(`- **OS:** ${report.environment.os.type} ${report.environment.os.release}${report.environment.os.version ? ` (${report.environment.os.version})` : ''}`);
410
+ lines.push(`- **Node:** ${report.environment.node.version}`);
411
+ lines.push(`- **Node execPath:** \`${report.environment.node.execPath}\``);
412
+ lines.push(`- **CWD:** \`${report.environment.cwd}\``);
413
+ lines.push('');
414
+ lines.push('## Package Managers');
415
+ lines.push('');
416
+ lines.push(`- **npm:** ${(_a = report.packageManager.npm.version) !== null && _a !== void 0 ? _a : `ERROR: ${(_b = report.packageManager.npm.error) !== null && _b !== void 0 ? _b : 'unknown'}`}`);
417
+ lines.push(`- **pnpm:** ${(_c = report.packageManager.pnpm.version) !== null && _c !== void 0 ? _c : `ERROR: ${(_d = report.packageManager.pnpm.error) !== null && _d !== void 0 ? _d : 'unknown'}`}`);
418
+ lines.push('');
419
+ lines.push('## Relevant Environment Variables');
420
+ lines.push('');
421
+ for (const [k, v] of Object.entries(report.environment.env)) {
422
+ lines.push(`- \`${k}\`: ${v !== null && v !== void 0 ? v : '<unset>'}`);
423
+ }
424
+ lines.push('');
425
+ lines.push('## Doctor Output');
426
+ lines.push('');
427
+ if (report.doctor) {
428
+ lines.push('<details>');
429
+ lines.push('<summary>Click to expand doctor JSON</summary>');
430
+ lines.push('');
431
+ lines.push('```json');
432
+ lines.push(JSON.stringify(report.doctor, null, 2));
433
+ lines.push('```');
434
+ lines.push('</details>');
435
+ }
436
+ else {
437
+ lines.push(`**Doctor failed:** ${(_e = report.doctorError) !== null && _e !== void 0 ? _e : 'unknown error'}`);
438
+ }
439
+ lines.push('');
440
+ lines.push('## Wrapper Logs');
441
+ lines.push('');
442
+ lines.push(`**Log directory:** \`${report.wrapperLogs.dir}\``);
443
+ lines.push(`**Mode:** ${report.wrapperLogs.mode}`);
444
+ if (report.wrapperLogs.error) {
445
+ lines.push(`**Error:** ${report.wrapperLogs.error}`);
446
+ }
447
+ lines.push('');
448
+ if (report.wrapperLogs.files.length === 0) {
449
+ lines.push('No wrapper logs found.');
450
+ }
451
+ else {
452
+ for (const f of report.wrapperLogs.files) {
453
+ lines.push(`### ${f.name}`);
454
+ lines.push('');
455
+ lines.push(`- **Path:** \`${f.path}\``);
456
+ if (f.mtime)
457
+ lines.push(`- **Modified:** ${f.mtime}`);
458
+ if (typeof f.size === 'number')
459
+ lines.push(`- **Size:** ${f.size} bytes`);
460
+ if (f.note)
461
+ lines.push(`- **Note:** ${f.note}`);
462
+ if (f.error) {
463
+ lines.push(`- **Error:** ${f.error}`);
464
+ lines.push('');
465
+ continue;
466
+ }
467
+ if (typeof f.content === 'string') {
468
+ if (f.truncated)
469
+ lines.push('*(Truncated)*');
470
+ lines.push('');
471
+ lines.push('<details>');
472
+ lines.push('<summary>Click to expand log content</summary>');
473
+ lines.push('');
474
+ lines.push('```text');
475
+ lines.push(f.content);
476
+ lines.push('```');
477
+ lines.push('</details>');
478
+ }
479
+ else {
480
+ lines.push('*(Content omitted)*');
481
+ }
482
+ lines.push('');
483
+ }
484
+ }
485
+ lines.push('');
486
+ lines.push('## Manifests');
487
+ lines.push('');
488
+ for (const m of report.manifests) {
489
+ lines.push(`### ${m.browser} (${m.scope})`);
490
+ lines.push('');
491
+ lines.push(`- **Path:** \`${m.path}\``);
492
+ if (!m.exists) {
493
+ lines.push('- **Status:** not found');
494
+ lines.push('');
495
+ continue;
496
+ }
497
+ if (m.error) {
498
+ lines.push(`- **Status:** error (${m.error})`);
499
+ }
500
+ if (m.json !== undefined) {
501
+ lines.push('');
502
+ lines.push('```json');
503
+ lines.push(JSON.stringify(m.json, null, 2));
504
+ lines.push('```');
505
+ }
506
+ else if (typeof m.raw === 'string') {
507
+ lines.push('');
508
+ lines.push('```text');
509
+ lines.push(m.raw);
510
+ lines.push('```');
511
+ }
512
+ lines.push('');
513
+ }
514
+ if (report.windowsRegistry) {
515
+ lines.push('## Windows Registry');
516
+ lines.push('');
517
+ for (const entry of report.windowsRegistry.entries) {
518
+ lines.push(`### ${entry.browser} (${entry.scope})`);
519
+ lines.push('');
520
+ lines.push(`- **Key:** \`${entry.key}\``);
521
+ lines.push(`- **Expected manifest:** \`${entry.expectedManifestPath}\``);
522
+ if (entry.error) {
523
+ lines.push(`- **Error:** ${entry.error}`);
524
+ lines.push('');
525
+ continue;
526
+ }
527
+ if (entry.value)
528
+ lines.push(`- **Default value:** \`${entry.value}\``);
529
+ if (entry.raw) {
530
+ lines.push('');
531
+ lines.push('```text');
532
+ lines.push(entry.raw);
533
+ lines.push('```');
534
+ }
535
+ lines.push('');
536
+ }
537
+ }
538
+ lines.push('---');
539
+ lines.push('');
540
+ lines.push('> If you are opening a GitHub Issue, paste everything above. ' +
541
+ `You can disable redaction with: \`${report.tool.name} report --no-redact\``);
542
+ return lines.join('\n');
543
+ }
544
+ function writeOutput(outputPath, content) {
545
+ if (!outputPath || outputPath === '-' || outputPath.toLowerCase() === 'stdout') {
546
+ process.stdout.write(content);
547
+ return { ok: true, destination: 'stdout' };
548
+ }
549
+ try {
550
+ const resolved = path_1.default.resolve(outputPath);
551
+ fs_1.default.writeFileSync(resolved, content, 'utf8');
552
+ return { ok: true, destination: resolved };
553
+ }
554
+ catch (e) {
555
+ return { ok: false, error: stringifyError(e) };
556
+ }
557
+ }
558
+ function tryCopyToClipboard(text) {
559
+ const spawn = (cmd, args) => {
560
+ var _a;
561
+ const res = (0, child_process_1.spawnSync)(cmd, args, {
562
+ input: text,
563
+ encoding: 'utf8',
564
+ timeout: 3000,
565
+ windowsHide: true,
566
+ });
567
+ if (res.error)
568
+ return { ok: false, error: stringifyError(res.error) };
569
+ if (res.status !== 0)
570
+ return { ok: false, error: `Exit code ${(_a = res.status) !== null && _a !== void 0 ? _a : 'unknown'}` };
571
+ return { ok: true };
572
+ };
573
+ if (process.platform === 'darwin') {
574
+ const r = spawn('pbcopy', []);
575
+ return r.ok ? { ok: true, method: 'pbcopy' } : { ok: false, method: 'pbcopy', error: r.error };
576
+ }
577
+ if (process.platform === 'win32') {
578
+ const r = spawn('clip', []);
579
+ return r.ok ? { ok: true, method: 'clip' } : { ok: false, method: 'clip', error: r.error };
580
+ }
581
+ // Linux: try wl-copy, xclip, xsel
582
+ for (const cmd of [
583
+ { cmd: 'wl-copy', args: [] },
584
+ { cmd: 'xclip', args: ['-selection', 'clipboard'] },
585
+ { cmd: 'xsel', args: ['--clipboard', '--input'] },
586
+ ]) {
587
+ const r = spawn(cmd.cmd, cmd.args);
588
+ if (r.ok)
589
+ return { ok: true, method: cmd.cmd };
590
+ }
591
+ return { ok: false, error: 'No clipboard command available (tried wl-copy, xclip, xsel)' };
592
+ }
593
+ // ============================================================================
594
+ // Main Report Function
595
+ // ============================================================================
596
+ async function runReport(options) {
597
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
598
+ try {
599
+ const includeLogs = parseIncludeLogsMode(options.includeLogs);
600
+ const logLines = parsePositiveInt(options.logLines, DEFAULT_LOG_LINES);
601
+ const redactionEnabled = options.redact !== false;
602
+ const tool = getToolVersion();
603
+ const browsers = resolveBrowsers(options.browser);
604
+ // Collect doctor report
605
+ let doctor;
606
+ let doctorError;
607
+ try {
608
+ doctor = await (0, doctor_1.collectDoctorReport)({
609
+ json: true,
610
+ fix: false,
611
+ browser: options.browser,
612
+ });
613
+ }
614
+ catch (e) {
615
+ doctorError = stringifyError(e);
616
+ }
617
+ // Build the report
618
+ const report = {
619
+ schemaVersion: REPORT_SCHEMA_VERSION,
620
+ timestamp: new Date().toISOString(),
621
+ tool,
622
+ environment: {
623
+ platform: process.platform,
624
+ arch: process.arch,
625
+ node: { version: process.version, execPath: process.execPath },
626
+ os: { type: os_1.default.type(), release: os_1.default.release(), version: safeOsVersion() },
627
+ cwd: process.cwd(),
628
+ env: {
629
+ CHROME_MCP_NODE_PATH: (_a = process.env.CHROME_MCP_NODE_PATH) !== null && _a !== void 0 ? _a : null,
630
+ VOLTA_HOME: (_b = process.env.VOLTA_HOME) !== null && _b !== void 0 ? _b : null,
631
+ ASDF_DATA_DIR: (_c = process.env.ASDF_DATA_DIR) !== null && _c !== void 0 ? _c : null,
632
+ FNM_DIR: (_d = process.env.FNM_DIR) !== null && _d !== void 0 ? _d : null,
633
+ NVM_DIR: (_e = process.env.NVM_DIR) !== null && _e !== void 0 ? _e : null,
634
+ // nvm-windows uses different environment variables
635
+ NVM_HOME: (_f = process.env.NVM_HOME) !== null && _f !== void 0 ? _f : null,
636
+ NVM_SYMLINK: (_g = process.env.NVM_SYMLINK) !== null && _g !== void 0 ? _g : null,
637
+ npm_config_user_agent: (_h = process.env.npm_config_user_agent) !== null && _h !== void 0 ? _h : null,
638
+ },
639
+ },
640
+ packageManager: {
641
+ npm: safeExecVersion('npm'),
642
+ pnpm: safeExecVersion('pnpm'),
643
+ },
644
+ doctor,
645
+ doctorError,
646
+ manifests: collectManifests(browsers),
647
+ wrapperLogs: collectWrapperLogs((0, utils_1.getLogDir)(), includeLogs, logLines),
648
+ windowsRegistry: process.platform === 'win32' ? collectWindowsRegistry(browsers) : undefined,
649
+ redaction: { enabled: redactionEnabled },
650
+ };
651
+ // Apply redaction
652
+ const redact = createRedactor(redactionEnabled);
653
+ const finalReport = redactionEnabled
654
+ ? redactDeep(report, redact)
655
+ : report;
656
+ // Render output
657
+ const output = options.json
658
+ ? JSON.stringify(finalReport, null, 2) + '\n'
659
+ : renderMarkdown(finalReport) + '\n';
660
+ // Write output
661
+ const write = writeOutput(options.output, output);
662
+ if (!write.ok) {
663
+ process.stderr.write(`Failed to write report: ${write.error}\n`);
664
+ process.stdout.write(output);
665
+ }
666
+ else if (write.destination !== 'stdout') {
667
+ process.stderr.write(`Report written to: ${write.destination}\n`);
668
+ }
669
+ // Copy to clipboard if requested
670
+ if (options.copy) {
671
+ const copied = tryCopyToClipboard(output);
672
+ if (copied.ok) {
673
+ process.stderr.write(`Copied to clipboard (${copied.method})\n`);
674
+ }
675
+ else {
676
+ process.stderr.write(`Failed to copy to clipboard: ${(_j = copied.error) !== null && _j !== void 0 ? _j : 'unknown error'}\n`);
677
+ }
678
+ }
679
+ return 0;
680
+ }
681
+ catch (e) {
682
+ process.stderr.write(`Report failed: ${stringifyError(e)}\n`);
683
+ return 1;
684
+ }
685
+ }
686
+ //# sourceMappingURL=report.js.map