@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.
- package/README.md +113 -0
- package/assets/logo.png +0 -0
- package/cli/commands/setup.d.ts +7 -0
- package/cli/commands/setup.d.ts.map +1 -0
- package/cli/commands/setup.js +248 -0
- package/cli/commands/setup.js.map +1 -0
- package/cli/commands/start.d.ts +6 -0
- package/cli/commands/start.d.ts.map +1 -0
- package/cli/commands/start.js +115 -0
- package/cli/commands/start.js.map +1 -0
- package/cli/commands/status.d.ts +2 -0
- package/cli/commands/status.d.ts.map +1 -0
- package/cli/commands/status.js +186 -0
- package/cli/commands/status.js.map +1 -0
- package/cli/index.d.ts +3 -0
- package/cli/index.d.ts.map +1 -0
- package/cli/index.js +53 -0
- package/cli/index.js.map +1 -0
- package/cli/ui/banner.d.ts +8 -0
- package/cli/ui/banner.d.ts.map +1 -0
- package/cli/ui/banner.js +41 -0
- package/cli/ui/banner.js.map +1 -0
- package/extension/background/index.js +2 -0
- package/extension/content/index.js +986 -0
- package/extension/devtools/devtools.html +10 -0
- package/extension/devtools/devtools.js +1 -0
- package/extension/devtools/panel.css +1584 -0
- package/extension/devtools/panel.html +16 -0
- package/extension/devtools/panel.js +40 -0
- package/extension/icons/clueprint.png +0 -0
- package/extension/manifest.json +70 -0
- package/extension/popup/popup.css +1584 -0
- package/extension/popup/popup.html +16 -0
- package/extension/popup/popup.js +122 -0
- package/extension/styles/overlay.css +111 -0
- package/package.json +41 -0
- package/server/analysis/format.d.ts +21 -0
- package/server/analysis/format.d.ts.map +1 -0
- package/server/analysis/format.js +583 -0
- package/server/analysis/format.js.map +1 -0
- package/server/index.d.ts +7 -0
- package/server/index.d.ts.map +1 -0
- package/server/index.js +14 -0
- package/server/index.js.map +1 -0
- package/server/server.d.ts +8 -0
- package/server/server.d.ts.map +1 -0
- package/server/server.js +417 -0
- package/server/server.js.map +1 -0
- package/server/shared-state.d.ts +14 -0
- package/server/shared-state.d.ts.map +1 -0
- package/server/shared-state.js +131 -0
- package/server/shared-state.js.map +1 -0
- package/server/types/index.d.ts +239 -0
- package/server/types/index.d.ts.map +1 -0
- package/server/types/index.js +7 -0
- package/server/types/index.js.map +1 -0
- package/server/websocket.d.ts +55 -0
- package/server/websocket.d.ts.map +1 -0
- package/server/websocket.js +355 -0
- 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 @@
|
|
|
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
|
package/cli/index.js.map
ADDED
|
@@ -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"}
|
package/cli/ui/banner.js
ADDED
|
@@ -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();
|