@clueprint/mcp 1.1.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.
Files changed (60) hide show
  1. package/README.md +113 -0
  2. package/assets/logo.png +0 -0
  3. package/cli/commands/setup.d.ts +7 -0
  4. package/cli/commands/setup.d.ts.map +1 -0
  5. package/cli/commands/setup.js +248 -0
  6. package/cli/commands/setup.js.map +1 -0
  7. package/cli/commands/start.d.ts +6 -0
  8. package/cli/commands/start.d.ts.map +1 -0
  9. package/cli/commands/start.js +115 -0
  10. package/cli/commands/start.js.map +1 -0
  11. package/cli/commands/status.d.ts +2 -0
  12. package/cli/commands/status.d.ts.map +1 -0
  13. package/cli/commands/status.js +186 -0
  14. package/cli/commands/status.js.map +1 -0
  15. package/cli/index.d.ts +3 -0
  16. package/cli/index.d.ts.map +1 -0
  17. package/cli/index.js +53 -0
  18. package/cli/index.js.map +1 -0
  19. package/cli/ui/banner.d.ts +8 -0
  20. package/cli/ui/banner.d.ts.map +1 -0
  21. package/cli/ui/banner.js +41 -0
  22. package/cli/ui/banner.js.map +1 -0
  23. package/extension/background/index.js +2 -0
  24. package/extension/content/index.js +986 -0
  25. package/extension/devtools/devtools.html +10 -0
  26. package/extension/devtools/devtools.js +1 -0
  27. package/extension/devtools/panel.css +1584 -0
  28. package/extension/devtools/panel.html +16 -0
  29. package/extension/devtools/panel.js +40 -0
  30. package/extension/icons/clueprint.png +0 -0
  31. package/extension/manifest.json +70 -0
  32. package/extension/popup/popup.css +1584 -0
  33. package/extension/popup/popup.html +16 -0
  34. package/extension/popup/popup.js +122 -0
  35. package/extension/styles/overlay.css +111 -0
  36. package/package.json +41 -0
  37. package/server/analysis/format.d.ts +21 -0
  38. package/server/analysis/format.d.ts.map +1 -0
  39. package/server/analysis/format.js +583 -0
  40. package/server/analysis/format.js.map +1 -0
  41. package/server/index.d.ts +7 -0
  42. package/server/index.d.ts.map +1 -0
  43. package/server/index.js +14 -0
  44. package/server/index.js.map +1 -0
  45. package/server/server.d.ts +8 -0
  46. package/server/server.d.ts.map +1 -0
  47. package/server/server.js +417 -0
  48. package/server/server.js.map +1 -0
  49. package/server/shared-state.d.ts +14 -0
  50. package/server/shared-state.d.ts.map +1 -0
  51. package/server/shared-state.js +131 -0
  52. package/server/shared-state.js.map +1 -0
  53. package/server/types/index.d.ts +239 -0
  54. package/server/types/index.d.ts.map +1 -0
  55. package/server/types/index.js +7 -0
  56. package/server/types/index.js.map +1 -0
  57. package/server/websocket.d.ts +55 -0
  58. package/server/websocket.d.ts.map +1 -0
  59. package/server/websocket.js +355 -0
  60. package/server/websocket.js.map +1 -0
@@ -0,0 +1,186 @@
1
+ import * as p from '@clack/prompts';
2
+ import pc from 'picocolors';
3
+ import { existsSync, readFileSync } from 'fs';
4
+ import { join, dirname } from 'path';
5
+ import { homedir } from 'os';
6
+ import { fileURLToPath } from 'url';
7
+ const __dirname = dirname(fileURLToPath(import.meta.url));
8
+ export async function status() {
9
+ p.intro(pc.bgCyan(pc.black(' clueprint status ')));
10
+ const checks = [];
11
+ const projectRoot = findProjectRoot();
12
+ // Check 1: Project found
13
+ if (!projectRoot) {
14
+ p.log.error('Clueprint project not found');
15
+ p.log.message(pc.dim('Run this command from within the clueprint directory'));
16
+ p.outro(pc.red('Status check failed'));
17
+ return;
18
+ }
19
+ checks.push({
20
+ name: 'Project',
21
+ status: 'ok',
22
+ message: `Found at ${projectRoot}`,
23
+ });
24
+ // Check 2: Dependencies installed
25
+ const nodeModulesExists = existsSync(join(projectRoot, 'node_modules'));
26
+ const extensionNodeModules = existsSync(join(projectRoot, 'packages/chrome-extension/node_modules'));
27
+ if (nodeModulesExists && extensionNodeModules) {
28
+ checks.push({
29
+ name: 'Dependencies',
30
+ status: 'ok',
31
+ message: 'Installed',
32
+ });
33
+ }
34
+ else {
35
+ checks.push({
36
+ name: 'Dependencies',
37
+ status: 'error',
38
+ message: 'Not installed',
39
+ hint: 'Run: pnpm install',
40
+ });
41
+ }
42
+ // Check 3: Extension built
43
+ const extensionDist = join(projectRoot, 'packages/chrome-extension/dist');
44
+ const manifestExists = existsSync(join(extensionDist, 'manifest.json'));
45
+ if (existsSync(extensionDist) && manifestExists) {
46
+ checks.push({
47
+ name: 'Chrome Extension',
48
+ status: 'ok',
49
+ message: 'Built',
50
+ });
51
+ }
52
+ else {
53
+ checks.push({
54
+ name: 'Chrome Extension',
55
+ status: 'error',
56
+ message: 'Not built',
57
+ hint: 'Run: pnpm run build:extension',
58
+ });
59
+ }
60
+ // Check 4: MCP server built
61
+ const mcpDist = join(projectRoot, 'packages/mcp-server/dist');
62
+ const mcpIndexExists = existsSync(join(mcpDist, 'index.js'));
63
+ if (existsSync(mcpDist) && mcpIndexExists) {
64
+ checks.push({
65
+ name: 'MCP Server',
66
+ status: 'ok',
67
+ message: 'Built',
68
+ });
69
+ }
70
+ else {
71
+ checks.push({
72
+ name: 'MCP Server',
73
+ status: 'error',
74
+ message: 'Not built',
75
+ hint: 'Run: pnpm run build:server',
76
+ });
77
+ }
78
+ // Check 5: Claude Code MCP configuration
79
+ const claudeConfigPath = join(homedir(), '.claude', 'claude_desktop_config.json');
80
+ if (existsSync(claudeConfigPath)) {
81
+ try {
82
+ const config = JSON.parse(readFileSync(claudeConfigPath, 'utf-8'));
83
+ const mcpServers = config.mcpServers || {};
84
+ if (mcpServers['clueprint']) {
85
+ const serverConfig = mcpServers['clueprint'];
86
+ const serverPath = serverConfig.args?.[0] || 'unknown';
87
+ const serverExists = existsSync(serverPath);
88
+ if (serverExists) {
89
+ checks.push({
90
+ name: 'Claude Code MCP',
91
+ status: 'ok',
92
+ message: 'Configured',
93
+ });
94
+ }
95
+ else {
96
+ checks.push({
97
+ name: 'Claude Code MCP',
98
+ status: 'warning',
99
+ message: 'Server path not found',
100
+ hint: `Expected: ${serverPath}`,
101
+ });
102
+ }
103
+ }
104
+ else {
105
+ checks.push({
106
+ name: 'Claude Code MCP',
107
+ status: 'warning',
108
+ message: 'Not configured',
109
+ hint: 'Run: clueprint setup',
110
+ });
111
+ }
112
+ }
113
+ catch {
114
+ checks.push({
115
+ name: 'Claude Code MCP',
116
+ status: 'warning',
117
+ message: 'Config parse error',
118
+ hint: 'Check ~/.claude/claude_desktop_config.json',
119
+ });
120
+ }
121
+ }
122
+ else {
123
+ checks.push({
124
+ name: 'Claude Code MCP',
125
+ status: 'warning',
126
+ message: 'Not configured',
127
+ hint: 'Run: clueprint setup',
128
+ });
129
+ }
130
+ // Print checks
131
+ console.log();
132
+ for (const check of checks) {
133
+ const icon = check.status === 'ok'
134
+ ? pc.green('')
135
+ : check.status === 'warning'
136
+ ? pc.yellow('')
137
+ : pc.red('');
138
+ const name = pc.bold(check.name.padEnd(18));
139
+ const message = check.status === 'ok'
140
+ ? pc.green(check.message)
141
+ : check.status === 'warning'
142
+ ? pc.yellow(check.message)
143
+ : pc.red(check.message);
144
+ console.log(` ${icon} ${name} ${message}`);
145
+ if (check.hint) {
146
+ console.log(` ${pc.dim(check.hint)}`);
147
+ }
148
+ }
149
+ console.log();
150
+ // Summary
151
+ const errors = checks.filter(c => c.status === 'error').length;
152
+ const warnings = checks.filter(c => c.status === 'warning').length;
153
+ if (errors === 0 && warnings === 0) {
154
+ p.outro(pc.green('All systems go!'));
155
+ }
156
+ else if (errors > 0) {
157
+ p.outro(pc.red(`${errors} issue${errors > 1 ? 's' : ''} found. Run: clueprint setup`));
158
+ }
159
+ else {
160
+ p.outro(pc.yellow(`${warnings} warning${warnings > 1 ? 's' : ''}`));
161
+ }
162
+ }
163
+ function findProjectRoot() {
164
+ let dir = process.cwd();
165
+ while (dir !== '/') {
166
+ const packageJson = join(dir, 'package.json');
167
+ if (existsSync(packageJson)) {
168
+ try {
169
+ const pkg = JSON.parse(readFileSync(packageJson, 'utf-8'));
170
+ if (pkg.name === 'clueprint' || existsSync(join(dir, 'packages/chrome-extension'))) {
171
+ return dir;
172
+ }
173
+ }
174
+ catch {
175
+ // Continue searching
176
+ }
177
+ }
178
+ dir = dirname(dir);
179
+ }
180
+ const globalRoot = join(__dirname, '../../../../..');
181
+ if (existsSync(join(globalRoot, 'packages/chrome-extension'))) {
182
+ return globalRoot;
183
+ }
184
+ return null;
185
+ }
186
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
package/cli/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/cli/index.js ADDED
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import gradient from 'gradient-string';
4
+ import pc from 'picocolors';
5
+ import { setup } from './commands/setup.js';
6
+ import { status } from './commands/status.js';
7
+ const BANNER = `
8
+ _ _ _
9
+ ___ | | _ _ ___ _ __ (_) _ __ | |_
10
+ / __|| | | | | | / _ \\ | '_ \\ | || '_ \\ | __|
11
+ | (__ | | | |_| | | __/ | |_) || || | | || |_
12
+ \\___||_| \\__,_| \\___| | .__/ |_||_| |_| \\__|
13
+ |_|
14
+ `;
15
+ function printBanner() {
16
+ const clueprintGradient = gradient(['#7c3aed', '#06b6d4']);
17
+ console.log(clueprintGradient.multiline(BANNER));
18
+ console.log(pc.dim(' Browser visibility for AI assistants\n'));
19
+ }
20
+ const program = new Command();
21
+ program
22
+ .name('clueprint')
23
+ .description('Browser visibility for AI assistants')
24
+ .version('0.1.0');
25
+ program
26
+ .command('setup')
27
+ .description('Set up Clueprint (build extension, configure MCP)')
28
+ .option('--skip-build', 'Skip building the extension')
29
+ .option('--skip-mcp', 'Skip MCP configuration')
30
+ .action(async (options) => {
31
+ await setup(options);
32
+ });
33
+ program
34
+ .command('status')
35
+ .description('Check Clueprint installation status')
36
+ .action(async () => {
37
+ await status();
38
+ });
39
+ program
40
+ .command('start')
41
+ .description('Start the MCP server')
42
+ .option('-p, --port <port>', 'Port to run the server on', '7007')
43
+ .action(async (options) => {
44
+ const { startServer } = await import('./commands/start.js');
45
+ await startServer(options);
46
+ });
47
+ // Default command (no args) shows help with banner
48
+ if (process.argv.length === 2) {
49
+ printBanner();
50
+ program.help();
51
+ }
52
+ program.parse();
53
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,MAAM,MAAM,GAAG;;;;;;;CAOd,CAAC;AAEF,SAAS,WAAW;IAClB,MAAM,iBAAiB,GAAG,QAAQ,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,sCAAsC,CAAC;KACnD,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,mDAAmD,CAAC;KAChE,MAAM,CAAC,cAAc,EAAE,6BAA6B,CAAC;KACrD,MAAM,CAAC,YAAY,EAAE,wBAAwB,CAAC;KAC9C,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,KAAK,CAAC,OAAO,CAAC,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,qCAAqC,CAAC;KAClD,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,MAAM,EAAE,CAAC;AACjB,CAAC,CAAC,CAAC;AAEL,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sBAAsB,CAAC;KACnC,MAAM,CAAC,mBAAmB,EAAE,2BAA2B,EAAE,MAAM,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;IAC5D,MAAM,WAAW,CAAC,OAAO,CAAC,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEL,mDAAmD;AACnD,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;IAC9B,WAAW,EAAE,CAAC;IACd,OAAO,CAAC,IAAI,EAAE,CAAC;AACjB,CAAC;AAED,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,8 @@
1
+ export declare function printBanner(): void;
2
+ export declare function printStep(step: number, total: number, message: string): void;
3
+ export declare function printSuccess(message: string): void;
4
+ export declare function printError(message: string): void;
5
+ export declare function printWarning(message: string): void;
6
+ export declare function printInfo(message: string): void;
7
+ export declare function printDim(message: string): void;
8
+ //# sourceMappingURL=banner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAgBA,wBAAgB,WAAW,IAAI,IAAI,CAQlC;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAG5E;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAEhD;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAElD;AAED,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE/C;AAED,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAE9C"}
@@ -0,0 +1,41 @@
1
+ import gradient from 'gradient-string';
2
+ import chalk from 'chalk';
3
+ const BANNER = `
4
+ _____ _ _ _
5
+ / ____| | (_) | |
6
+ | | | |_ _ ___ _ __ _ __ _ _ __ | |_
7
+ | | | | | | |/ _ \\ '_ \\| '__| | '_ \\| __|
8
+ | |____| | |_| | __/ |_) | | | | | | | |_
9
+ \\_____|_|\\__,_|\\___| .__/|_| |_|_| |_|\\__|
10
+ | |
11
+ |_|
12
+ `;
13
+ const TAGLINE = 'Browser visibility for AI assistants';
14
+ export function printBanner() {
15
+ // Use a nice gradient (purple to cyan like Astro)
16
+ const clueprintGradient = gradient(['#7c3aed', '#06b6d4']);
17
+ console.log();
18
+ console.log(clueprintGradient.multiline(BANNER));
19
+ console.log(chalk.dim(` ${TAGLINE}`));
20
+ console.log();
21
+ }
22
+ export function printStep(step, total, message) {
23
+ const prefix = chalk.dim(`[${step}/${total}]`);
24
+ console.log(`${prefix} ${message}`);
25
+ }
26
+ export function printSuccess(message) {
27
+ console.log(chalk.green('✓'), message);
28
+ }
29
+ export function printError(message) {
30
+ console.log(chalk.red('✗'), message);
31
+ }
32
+ export function printWarning(message) {
33
+ console.log(chalk.yellow('!'), message);
34
+ }
35
+ export function printInfo(message) {
36
+ console.log(chalk.blue('i'), message);
37
+ }
38
+ export function printDim(message) {
39
+ console.log(chalk.dim(message));
40
+ }
41
+ //# sourceMappingURL=banner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"banner.js","sourceRoot":"","sources":["../../src/ui/banner.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,MAAM,MAAM,GAAG;;;;;;;;;CASd,CAAC;AAEF,MAAM,OAAO,GAAG,sCAAsC,CAAC;AAEvD,MAAM,UAAU,WAAW;IACzB,kDAAkD;IAClD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,CAAC;IAE3D,OAAO,CAAC,GAAG,EAAE,CAAC;IACd,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,KAAa,EAAE,OAAe;IACpE,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,OAAe;IACxC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,OAAe;IACvC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,OAAe;IACtC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,2 @@
1
+ var b={inspectShortcut:"Alt+Click",freeSelectShortcut:"Ctrl+Shift+Drag",captureConsole:!0,captureNetwork:!0,capturePerformance:!0,maxConsoleEntries:50,maxNetworkEntries:50,cssDetailLevel:1,screenshotQuality:.7,screenshotMaxWidth:800,serverPort:7007};var n={isActive:!1,isRecording:!1,isBuffering:!1,currentSelection:null,currentRecording:null,snapshots:new Map,consoleBuffer:[],networkBuffer:[],mcpConnected:!1},l=null,c=[],g=[],h=null,D=3e4,p=null;var C=3e3,R="ws-keepalive",E={...b};function A(){console.log("[AI DevTools] Background service worker started"),F(),chrome.storage.local.get("isBuffering").then(({isBuffering:e})=>{e&&N()}),S(),chrome.runtime.onMessage.addListener(G),chrome.commands.onCommand.addListener(L),chrome.tabs.onUpdated.addListener(M),chrome.action.onClicked.addListener(B),chrome.alarms.create(R,{periodInMinutes:.5}),chrome.alarms.onAlarm.addListener(e=>{e.name===R&&(!p||p.readyState===WebSocket.CLOSED||p.readyState===WebSocket.CLOSING)&&S()})}async function F(){try{let e=await chrome.storage.sync.get("settings");e.settings&&(E={...b,...e.settings})}catch(e){console.warn("[AI DevTools] Failed to load settings:",e)}}function S(){if(!(p?.readyState===WebSocket.OPEN||p?.readyState===WebSocket.CONNECTING))try{p=new WebSocket(`ws://localhost:${E.serverPort}`),p.onopen=()=>{console.log("[AI DevTools] Connected to MCP server"),n.mcpConnected=!0,T()},p.onclose=()=>{console.log("[AI DevTools] Disconnected from MCP server"),n.mcpConnected=!1,p=null,T(),setTimeout(S,C)},p.onerror=e=>{console.warn("[AI DevTools] WebSocket error:",e)},p.onmessage=e=>{P(JSON.parse(e.data))}}catch(e){console.warn("[AI DevTools] Failed to connect to MCP server:",e),setTimeout(S,C)}}function d(e){p?.readyState===WebSocket.OPEN&&p.send(JSON.stringify(e))}function P(e){switch(e.type){case"GET_SELECTION":d({type:"SELECTION_RESPONSE",id:e.id,payload:n.currentSelection});break;case"GET_DIAGNOSTICS":V().then(s=>{d({type:"DIAGNOSTICS_RESPONSE",id:e.id,payload:s})});break;case"START_RECORDING":k(),d({type:"RECORDING_STARTED",id:e.id});break;case"STOP_RECORDING":let t=v();d({type:"RECORDING_RESPONSE",id:e.id,payload:t});break;case"GET_RECORDING":d({type:"RECORDING_RESPONSE",id:e.id,payload:n.currentRecording});break;case"SNAPSHOT_DOM":q(e.payload).then(s=>{d({type:"SNAPSHOT_RESPONSE",id:e.id,payload:s})});break;case"DIFF_SNAPSHOTS":let o=H(e.payload);d({type:"DIFF_RESPONSE",id:e.id,payload:o});break;case"GET_RECENT_ACTIVITY":d({type:"RECENT_ACTIVITY_RESPONSE",id:e.id,payload:I()});break;case"PING":d({type:"PONG",id:e.id});break}}function G(e,t,o){switch(e.type){case"ELEMENT_SELECTED":n.currentSelection=e.payload,d({type:"ELEMENT_SELECTED",payload:n.currentSelection}),n.isRecording&&l&&c.push({time:Date.now()-l,type:"element_select",data:{selector:e.payload.element.selector}}),m("element_select",{selector:e.payload.element.selector}),o({success:!0});break;case"REGION_SELECTED":n.currentSelection=e.payload,d({type:"REGION_SELECTED",payload:n.currentSelection}),o({success:!0});break;case"GET_BROWSER_CONTEXT":o({errors:n.consoleBuffer.filter(a=>a.type==="error"),networkFailures:n.networkBuffer.filter(a=>a.status&&a.status>=400)});break;case"CONSOLE_EVENT":let s=e.payload;for(n.consoleBuffer.push(s);n.consoleBuffer.length>E.maxConsoleEntries;)n.consoleBuffer.shift();n.isRecording&&l&&c.push({time:Date.now()-l,type:`console_${s.type}`,data:{message:s.message,source:s.source}}),m(`console_${s.type}`,{message:s.message,source:s.source}),o({success:!0});break;case"NETWORK_EVENT":let r=e.payload;for(n.networkBuffer.push(r);n.networkBuffer.length>E.maxNetworkEntries;)n.networkBuffer.shift();if(n.isRecording&&l){let a=r.status&&r.status>=400?"network_error":"network_response";c.push({time:Date.now()-l,type:a,data:{url:r.url,method:r.method,status:r.status,statusText:r.statusText}})}m(r.status&&r.status>=400?"network_error":"network_response",{url:r.url,method:r.method,status:r.status,statusText:r.statusText}),o({success:!0});break;case"INTERACTION_EVENT":if(n.isRecording&&l){let a=e.payload;c.push({time:Date.now()-l,type:a.type,data:a.data})}{let a=e.payload;m(a.type,a.data)}o({success:!0});break;case"CAPTURE_SCREENSHOT":return $(t.tab?.id).then(a=>{o({dataUrl:a})}),!0;case"GET_STATUS":o({isActive:n.isActive,isRecording:n.isRecording,isBuffering:n.isBuffering,hasSelection:n.currentSelection!==null,mcpConnected:n.mcpConnected});break;case"START_RECORDING":k(),o({success:!0});break;case"STOP_RECORDING":let u=v();d({type:"RECORDING_STOPPED",payload:u}),o({success:!0,recording:u});break;case"CONTENT_READY":n.isActive=!0,o({success:!0});break;case"TOGGLE_BUFFER":n.isBuffering?W():N(),o({success:!0,isBuffering:n.isBuffering});break;case"SEND_BUFFER":let i=I();i&&(n.currentRecording=i,d({type:"BUFFER_RECORDING",payload:i})),o({success:!0,recording:i});break;default:o({error:"Unknown message type"})}return!0}async function L(e){let[t]=await chrome.tabs.query({active:!0,currentWindow:!0});if(t?.id)switch(e){case"toggle-inspect":chrome.tabs.sendMessage(t.id,{type:"TOGGLE_INSPECT"}).catch(()=>{});break;case"toggle-region":chrome.tabs.sendMessage(t.id,{type:"TOGGLE_REGION"}).catch(()=>{});break}}async function B(e){if(e.id)try{await chrome.tabs.sendMessage(e.id,{type:"TOGGLE_INSPECT"})}catch(t){console.warn("[AI DevTools] Failed to toggle inspect mode:",t)}}function M(e,t,o){t.status==="loading"&&(n.currentSelection=null,n.isRecording&&l&&c.push({time:Date.now()-l,type:t.url?"navigation":"refresh",data:{url:t.url}}),m(t.url?"navigation":"refresh",{url:t.url}))}async function $(e){try{return await chrome.tabs.captureVisibleTab(void 0,{format:"jpeg",quality:Math.round(E.screenshotQuality*100)})}catch(t){return console.warn("[AI DevTools] Screenshot capture failed:",t),null}}async function k(){n.isRecording=!0,l=Date.now(),c=[],n.currentRecording=null;try{let[e]=await chrome.tabs.query({active:!0,currentWindow:!0});e&&c.push({time:0,type:"navigation",data:{url:e.url,title:e.title,event:"recording_start"}})}catch{}_({type:"RECORDING_STARTED"})}function v(){if(!n.isRecording||!l)return null;let e=Date.now()-l,t={totalEvents:c.length,clicks:c.filter(r=>r.type==="click").length,inputs:c.filter(r=>r.type==="input").length,scrolls:c.filter(r=>r.type==="scroll").length,navigations:c.filter(r=>r.type==="navigation"||r.type==="refresh").length,networkRequests:c.filter(r=>r.type==="network_request"||r.type==="network_response").length,networkErrors:c.filter(r=>r.type==="network_error").length,consoleErrors:c.filter(r=>r.type==="console_error").length,layoutShifts:c.filter(r=>r.type==="layout_shift").length},o=O(c,e),s={mode:"flow",duration:e,startTime:l,events:c,finalSelection:n.currentSelection||void 0,summary:t,diagnosis:o};return n.isRecording=!1,n.currentRecording=s,l=null,c=[],_({type:"RECORDING_STOPPED"}),s}function N(){n.isBuffering=!0,g=[],h=setInterval(w,5e3),chrome.storage.local.set({isBuffering:!0}),T()}function W(){n.isBuffering=!1,g=[],h&&(clearInterval(h),h=null),chrome.storage.local.set({isBuffering:!1}),T()}function w(){let e=Date.now()-D,t=g.findIndex(o=>o.time>=e);t>0?g=g.slice(t):t===-1&&g.length>0&&(g=[])}function m(e,t){n.isBuffering&&(g.push({time:Date.now(),type:e,data:t}),g.length>5e3&&w())}function I(){if(w(),g.length===0)return null;let e=g[0].time,o=g[g.length-1].time-e,s=g.map(i=>({...i,time:i.time-e})),r={totalEvents:s.length,clicks:s.filter(i=>i.type==="click").length,inputs:s.filter(i=>i.type==="input").length,scrolls:s.filter(i=>i.type==="scroll").length,navigations:s.filter(i=>i.type==="navigation"||i.type==="refresh").length,networkRequests:s.filter(i=>i.type==="network_request"||i.type==="network_response").length,networkErrors:s.filter(i=>i.type==="network_error").length,consoleErrors:s.filter(i=>i.type==="console_error").length,layoutShifts:s.filter(i=>i.type==="layout_shift").length},u=O(s,o);return{mode:"flow",duration:o,startTime:e,events:s,summary:r,diagnosis:u}}function O(e,t){let o=e.filter(a=>a.type==="console_error"||a.type==="network_error"),s=e.filter(a=>a.type==="click"),r="No obvious issues detected",u;for(let a of s){let f=o.filter(y=>y.time>a.time&&y.time<a.time+1e3);if(f.length>0){r=`Error occurred after clicking ${a.data.selector||"element"}`,u=f[0].data.message;break}}let i=e.slice(0,10).map(a=>{let f=(a.time/1e3).toFixed(1),y=U(a.type),x=z(a);return`${f}s ${y} ${x}`}).join(`
2
+ `);return{suspectedIssue:r,timeline:i,rootCause:u}}function U(e){return{refresh:"\u{1F504}",navigation:"\u{1F504}",click:"\u{1F5B1}\uFE0F",input:"\u2328\uFE0F",scroll:"\u{1F4DC}",network_request:"\u{1F4E4}",network_response:"\u2705",network_error:"\u274C",console_log:"\u{1F4DD}",console_warn:"\u26A0\uFE0F",console_error:"\u274C",dom_mutation:"\u{1F500}",layout_shift:"\u{1F4D0}",element_select:"\u{1F446}",form_submit:"\u{1F4CB}",keypress:"\u2328\uFE0F",mouse_move:"\u{1F50D}"}[e]||"\u2022"}function z(e){let t=e.data;switch(e.type){case"click":let o=t.text?`"${t.text.slice(0,40)}"`:t.selector||"element";return`CLICK ${t.role||""} ${o} at (${t.x}, ${t.y})`;case"scroll":let s=t.nearSection?` near "${t.nearSection.slice(0,30)}"`:"";return`SCROLL ${t.direction||""} to ${t.scrollPercent||0}%${s}`;case"input":return`INPUT ${t.inputType||"text"} "${t.label||t.selector||""}" (${t.valueLength||0} chars)`;case"form_submit":return`SUBMIT ${t.method} form \u2192 ${t.action||"same page"} (${t.fieldCount} fields)`;case"keypress":return`KEY ${t.combo||t.key} on ${t.target||"page"}`;case"mouse_move":return`HOVER ${t.role||""} ${t.target||""} at (${t.x}, ${t.y})`;case"navigation":return t.event==="recording_start"?`START on "${t.title||"page"}" (${t.url})`:`NAVIGATE \u2192 ${t.url||"unknown"}`;case"refresh":return"REFRESH page";case"network_response":let r=t.url?.split("?")[0]?.split("/").slice(-2).join("/")||t.url;return`${t.method} /${r} \u2192 ${t.status}`;case"network_error":let u=t.url?.split("?")[0]?.split("/").slice(-2).join("/")||t.url;return`${t.method} /${u} \u2192 ${t.status} FAILED: "${t.statusText}"`;case"console_error":return`ERROR: "${t.message?.slice(0,80)}"`;case"console_warn":return`WARN: "${t.message?.slice(0,60)}"`;default:return e.type.toUpperCase()}}async function V(){try{let[e]=await chrome.tabs.query({active:!0,currentWindow:!0});return e?.id?await chrome.tabs.sendMessage(e.id,{type:"GET_DIAGNOSTICS"}):null}catch(e){return console.warn("[AI DevTools] Failed to get diagnostics:",e),null}}async function q(e){try{let[t]=await chrome.tabs.query({active:!0,currentWindow:!0});if(!t?.id)return null;let o=await chrome.tabs.sendMessage(t.id,{type:"SNAPSHOT_DOM",payload:e});if(o){let s=o;return n.snapshots.set(s.id,s),s}return null}catch(t){return console.warn("[AI DevTools] Failed to snapshot DOM:",t),null}}function H(e){let t=n.snapshots.get(e.before),o=n.snapshots.get(e.after);if(!t||!o)return{error:"Snapshot not found"};let s=[];for(let[r,u]of t.elements){let i=o.elements.get(r);if(!i)s.push({selector:r,type:"removed"});else{let a=j(u.classes,i.classes),f=u.size.width!==i.size.width||u.size.height!==i.size.height;(a.added.length||a.removed.length||f)&&s.push({selector:r,type:"changed",changes:{classes:a.added.length||a.removed.length?a:void 0,size:f?{before:u.size,after:i.size}:void 0}})}}for(let[r]of o.elements)t.elements.has(r)||s.push({selector:r,type:"added"});return{before:e.before,after:e.after,changes:s}}function j(e,t){let o=new Set(e),s=new Set(t);return{added:t.filter(r=>!o.has(r)),removed:e.filter(r=>!s.has(r))}}async function _(e){let t=await chrome.tabs.query({});for(let o of t)o.id&&chrome.tabs.sendMessage(o.id,e).catch(()=>{})}function T(){let e={type:"STATUS_UPDATE",isActive:n.isActive,isRecording:n.isRecording,isBuffering:n.isBuffering,mcpConnected:n.mcpConnected};_(e),chrome.runtime.sendMessage(e).catch(()=>{})}A();