autodebug 0.5.1__py3-none-any.whl
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.
- autodebug/__init__.py +3 -0
- autodebug/__main__.py +11 -0
- autodebug/cli.py +432 -0
- autodebug/connection.py +219 -0
- autodebug/extension/README.md +16 -0
- autodebug/extension/extension.js +40 -0
- autodebug/extension/mcp.js +98 -0
- autodebug/extension/package.json +28 -0
- autodebug/extension/relay.js +570 -0
- autodebug/hub.py +267 -0
- autodebug/install.py +346 -0
- autodebug/mcp_server.py +270 -0
- autodebug/redact.py +38 -0
- autodebug/report.py +107 -0
- autodebug/session.py +828 -0
- autodebug/tools.py +472 -0
- autodebug-0.5.1.dist-info/METADATA +251 -0
- autodebug-0.5.1.dist-info/RECORD +20 -0
- autodebug-0.5.1.dist-info/WHEEL +4 -0
- autodebug-0.5.1.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# AutoDebug
|
|
2
|
+
|
|
3
|
+
Lets an AI agent debug your program with this window's own debugger: build,
|
|
4
|
+
set breakpoints, run, step, read variables, and write a root-cause report into
|
|
5
|
+
your project.
|
|
6
|
+
|
|
7
|
+
- Nothing runs until you click **Approve** in the dialog, which shows the build
|
|
8
|
+
command, preLaunchTask, postDebugTask, the launch configuration as JSON, the
|
|
9
|
+
breakpoints and the limits. Remote hosts and `${input}` / `${command}`
|
|
10
|
+
substitutions are refused. Attach sessions detach and leave the program running.
|
|
11
|
+
- The agent cannot evaluate code or change variables. Secret-looking values are
|
|
12
|
+
hidden from it.
|
|
13
|
+
- The connection is 127.0.0.1 only, protected by a random token.
|
|
14
|
+
|
|
15
|
+
Set up with `autodebug setup vscode` or `autodebug setup cursor`.
|
|
16
|
+
Log: Command Palette → **AutoDebug: Show Log**.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// AutoDebug extension entry point. The relay is in relay.js; the logic is in the Python server.
|
|
3
|
+
const path = require('path');
|
|
4
|
+
const vscode = require('vscode');
|
|
5
|
+
const { Relay } = require('./relay');
|
|
6
|
+
const mcp = require('./mcp');
|
|
7
|
+
|
|
8
|
+
let relay;
|
|
9
|
+
|
|
10
|
+
function activate(context) {
|
|
11
|
+
const output = vscode.window.createOutputChannel('AutoDebug');
|
|
12
|
+
const log = (line) => output.appendLine(`${new Date().toISOString()} ${line}`);
|
|
13
|
+
const status = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 0);
|
|
14
|
+
status.text = '$(debug-alt) AutoDebug';
|
|
15
|
+
status.tooltip = 'AutoDebug is ready. An AI agent can debug here only after you click Approve.';
|
|
16
|
+
status.command = 'autodebug.showLog';
|
|
17
|
+
const folder = vscode.workspace.getConfiguration('autodebug').get('bridgesFolder') || undefined;
|
|
18
|
+
relay = new Relay(vscode, { folder, log });
|
|
19
|
+
context.subscriptions.push(
|
|
20
|
+
output, status,
|
|
21
|
+
vscode.commands.registerCommand('autodebug.showLog', () => output.show()),
|
|
22
|
+
vscode.debug.registerDebugAdapterTrackerFactory('*', { createDebugAdapterTracker: (s) => relay.tracker(s) }),
|
|
23
|
+
vscode.debug.onDidStartDebugSession((s) => relay.sessionStarted(s)),
|
|
24
|
+
vscode.debug.onDidTerminateDebugSession((s) => relay.sessionEnded(s)),
|
|
25
|
+
vscode.workspace.onDidChangeWorkspaceFolders(() => relay.announce()),
|
|
26
|
+
{ dispose: () => relay.stop() },
|
|
27
|
+
);
|
|
28
|
+
relay.start().then(() => status.show(), (error) => log(`could not start: ${error.message}`));
|
|
29
|
+
try {
|
|
30
|
+
mcp.register(vscode, context, { stateFolder: path.dirname(relay.folder), log });
|
|
31
|
+
} catch (error) {
|
|
32
|
+
log(`MCP: could not register the autodebug server: ${error.message}`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function deactivate() {
|
|
37
|
+
return relay && relay.stop();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
module.exports = { activate, deactivate };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// Registers the `autodebug` MCP server with the IDE itself, so the agent gets the tools without an
|
|
3
|
+
// mcp.json entry. `autodebug setup` writes <state folder>/server.json: how to start the server
|
|
4
|
+
// ({command, args, env}). Cursor: vscode.cursor.mcp.registerServer. VS Code 1.101+:
|
|
5
|
+
// vscode.lm.registerMcpServerDefinitionProvider. A window whose mcp.json files already name
|
|
6
|
+
// `autodebug` is left alone, so the agent never sees the tools twice.
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
const os = require('os');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
const NAME = 'autodebug';
|
|
12
|
+
const PROVIDER = 'autodebug.server'; // contributes.mcpServerDefinitionProviders in package.json
|
|
13
|
+
|
|
14
|
+
function readJson(file) {
|
|
15
|
+
try {
|
|
16
|
+
const text = fs.readFileSync(file, 'utf8').replace(/^/, '');
|
|
17
|
+
return JSON.parse(text);
|
|
18
|
+
} catch (_) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** The server.json written by setup, or undefined (with the reason logged) when it is missing or wrong. */
|
|
24
|
+
function serverConfig(stateFolder, log) {
|
|
25
|
+
const file = path.join(stateFolder, 'server.json');
|
|
26
|
+
const data = readJson(file);
|
|
27
|
+
if (!data) {
|
|
28
|
+
log(`MCP: no ${file}; run \`autodebug setup\` to let this window register the autodebug server`);
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
const env = data.env && typeof data.env === 'object' ? data.env : {};
|
|
32
|
+
if (typeof data.command !== 'string' || !Array.isArray(data.args) || !data.args.every((a) => typeof a === 'string')) {
|
|
33
|
+
log(`MCP: ${file} has no command and args; run \`autodebug setup\` again`);
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return { command: data.command, args: data.args, env, version: String(data.version || '') };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** Every mcp.json this IDE reads for the open folders, with the key that holds its servers. */
|
|
40
|
+
function configFiles(ide, folders, userDir, home = os.homedir()) {
|
|
41
|
+
const files = [];
|
|
42
|
+
if (ide === 'cursor') {
|
|
43
|
+
files.push([path.join(home, '.cursor', 'mcp.json'), 'mcpServers']);
|
|
44
|
+
for (const f of folders) files.push([path.join(f, '.cursor', 'mcp.json'), 'mcpServers']);
|
|
45
|
+
} else {
|
|
46
|
+
if (userDir) files.push([path.join(userDir, 'mcp.json'), 'servers']);
|
|
47
|
+
for (const f of folders) {
|
|
48
|
+
files.push([path.join(f, '.vscode', 'mcp.json'), 'servers']);
|
|
49
|
+
files.push([path.join(f, '.mcp.json'), 'mcpServers']);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return files;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function configuredElsewhere(files) {
|
|
56
|
+
return files.find(([file, key]) => {
|
|
57
|
+
const data = readJson(file);
|
|
58
|
+
return Boolean(data && data[key] && typeof data[key] === 'object' && data[key][NAME]);
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Register the server for this window. Returns what happened, for the log and the tests:
|
|
64
|
+
* 'cursor', 'vscode', 'configured' (an mcp.json already has it), 'no-config' or 'unsupported'.
|
|
65
|
+
*/
|
|
66
|
+
function register(vscode, context, { stateFolder, log, home = os.homedir() }) {
|
|
67
|
+
const isCursor = Boolean(vscode.cursor && vscode.cursor.mcp && typeof vscode.cursor.mcp.registerServer === 'function');
|
|
68
|
+
const hasProvider = Boolean(vscode.lm && typeof vscode.lm.registerMcpServerDefinitionProvider === 'function'
|
|
69
|
+
&& typeof vscode.McpStdioServerDefinition === 'function');
|
|
70
|
+
if (!isCursor && !hasProvider) {
|
|
71
|
+
log('MCP: this IDE has no API to register MCP servers; use `autodebug setup` (it writes mcp.json)');
|
|
72
|
+
return 'unsupported';
|
|
73
|
+
}
|
|
74
|
+
const folders = (vscode.workspace.workspaceFolders || []).map((f) => f.uri.fsPath);
|
|
75
|
+
const userDir = context.globalStorageUri ? path.dirname(path.dirname(context.globalStorageUri.fsPath)) : undefined;
|
|
76
|
+
const found = configuredElsewhere(configFiles(isCursor ? 'cursor' : 'vscode', folders, userDir, home));
|
|
77
|
+
if (found) {
|
|
78
|
+
log(`MCP: ${found[0]} already starts autodebug; not registering it a second time`);
|
|
79
|
+
return 'configured';
|
|
80
|
+
}
|
|
81
|
+
const server = serverConfig(stateFolder, log);
|
|
82
|
+
if (!server) return 'no-config';
|
|
83
|
+
if (isCursor) {
|
|
84
|
+
vscode.cursor.mcp.registerServer({ name: NAME, server: { command: server.command, args: server.args, env: server.env } });
|
|
85
|
+
context.subscriptions.push({ dispose: () => { try { vscode.cursor.mcp.unregisterServer(NAME); } catch (_) { /* window closing */ } } });
|
|
86
|
+
log(`MCP: registered autodebug with Cursor (${server.command})`);
|
|
87
|
+
return 'cursor';
|
|
88
|
+
}
|
|
89
|
+
const definition = new vscode.McpStdioServerDefinition('AutoDebug', server.command, server.args, server.env, server.version);
|
|
90
|
+
context.subscriptions.push(vscode.lm.registerMcpServerDefinitionProvider(PROVIDER, {
|
|
91
|
+
provideMcpServerDefinitions: () => [definition],
|
|
92
|
+
resolveMcpServerDefinition: (d) => d,
|
|
93
|
+
}));
|
|
94
|
+
log(`MCP: registered autodebug with VS Code (${server.command})`);
|
|
95
|
+
return 'vscode';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
module.exports = { register, configFiles, serverConfig, NAME, PROVIDER };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "autodebug",
|
|
3
|
+
"displayName": "AutoDebug",
|
|
4
|
+
"description": "Lets an AI agent debug your program with this window's debugger, after you click Approve, and write a root-cause report.",
|
|
5
|
+
"version": "0.5.0",
|
|
6
|
+
"publisher": "SwagatTeejoram",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {"type": "git", "url": "https://github.com/TEEJORAM/AutoDebug"},
|
|
9
|
+
"engines": {"vscode": "^1.80.0"},
|
|
10
|
+
"categories": ["Debuggers", "AI"],
|
|
11
|
+
"extensionKind": ["workspace"],
|
|
12
|
+
"activationEvents": ["onStartupFinished"],
|
|
13
|
+
"main": "./extension.js",
|
|
14
|
+
"contributes": {
|
|
15
|
+
"commands": [{"command": "autodebug.showLog", "title": "AutoDebug: Show Log"}],
|
|
16
|
+
"mcpServerDefinitionProviders": [{"id": "autodebug.server", "label": "AutoDebug"}],
|
|
17
|
+
"configuration": {
|
|
18
|
+
"title": "AutoDebug",
|
|
19
|
+
"properties": {
|
|
20
|
+
"autodebug.bridgesFolder": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"default": "",
|
|
23
|
+
"description": "Folder where this window announces itself to the AutoDebug server. Leave empty for the default."
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|