agentuity-vscode 0.0.86
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/.vscode/launch.json +26 -0
- package/.vscode/tasks.json +22 -0
- package/.vscodeignore +22 -0
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/package.json +476 -0
- package/resources/icon.png +0 -0
- package/resources/icon.svg +1 -0
- package/src/core/auth.ts +128 -0
- package/src/core/baseTreeDataProvider.ts +92 -0
- package/src/core/cliClient.ts +777 -0
- package/src/core/index.ts +5 -0
- package/src/core/project.ts +98 -0
- package/src/core/readonlyDocument.ts +57 -0
- package/src/core/service.ts +208 -0
- package/src/extension.ts +260 -0
- package/src/features/agentExplorer/agentTreeData.ts +149 -0
- package/src/features/agentExplorer/index.ts +105 -0
- package/src/features/chat/agentuityParticipant.ts +838 -0
- package/src/features/chat/cliTool.ts +91 -0
- package/src/features/chat/index.ts +2 -0
- package/src/features/codeLens/agentCodeLensProvider.ts +116 -0
- package/src/features/codeLens/index.ts +132 -0
- package/src/features/dataExplorer/dataTreeData.ts +480 -0
- package/src/features/dataExplorer/index.ts +362 -0
- package/src/features/deploymentExplorer/deploymentTreeData.ts +238 -0
- package/src/features/deploymentExplorer/index.ts +107 -0
- package/src/features/devServer/devServerManager.ts +258 -0
- package/src/features/devServer/index.ts +52 -0
- package/src/features/workbench/index.ts +19 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
import { getCliClient } from '../../core/cliClient';
|
|
3
|
+
|
|
4
|
+
const DESTRUCTIVE_PATTERNS = [
|
|
5
|
+
/^auth\s+logout/i,
|
|
6
|
+
/\bdelete\b/i,
|
|
7
|
+
/\bremove\b/i,
|
|
8
|
+
/\bdestroy\b/i,
|
|
9
|
+
/\bdrop\b/i,
|
|
10
|
+
];
|
|
11
|
+
|
|
12
|
+
const CONFIRMATION_PATTERNS = [/^cloud\s+deploy/i];
|
|
13
|
+
|
|
14
|
+
export interface CliToolInput {
|
|
15
|
+
command: string;
|
|
16
|
+
jsonOutput?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class AgentuityCliTool implements vscode.LanguageModelTool<CliToolInput> {
|
|
20
|
+
async invoke(
|
|
21
|
+
options: vscode.LanguageModelToolInvocationOptions<CliToolInput>,
|
|
22
|
+
_token: vscode.CancellationToken
|
|
23
|
+
): Promise<vscode.LanguageModelToolResult> {
|
|
24
|
+
const { command, jsonOutput = true } = options.input;
|
|
25
|
+
|
|
26
|
+
if (!command || command.trim() === '') {
|
|
27
|
+
throw new Error('Command is required. Provide an agentuity CLI subcommand.');
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
for (const pattern of DESTRUCTIVE_PATTERNS) {
|
|
31
|
+
if (pattern.test(command)) {
|
|
32
|
+
throw new Error(
|
|
33
|
+
`Destructive command detected: "${command}". This command is not allowed via the AI assistant. Please run it manually in the terminal.`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const args = command.split(/\s+/).filter((arg) => arg.length > 0);
|
|
39
|
+
|
|
40
|
+
const cli = getCliClient();
|
|
41
|
+
const result = await cli.exec(args, { format: jsonOutput ? 'json' : 'text' });
|
|
42
|
+
|
|
43
|
+
if (!result.success) {
|
|
44
|
+
throw new Error(`CLI command failed: ${result.error}`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const output =
|
|
48
|
+
typeof result.data === 'string' ? result.data : JSON.stringify(result.data, null, 2);
|
|
49
|
+
|
|
50
|
+
return new vscode.LanguageModelToolResult([new vscode.LanguageModelTextPart(output)]);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async prepareInvocation(
|
|
54
|
+
options: vscode.LanguageModelToolInvocationPrepareOptions<CliToolInput>,
|
|
55
|
+
_token: vscode.CancellationToken
|
|
56
|
+
): Promise<vscode.PreparedToolInvocation | undefined> {
|
|
57
|
+
const { command } = options.input;
|
|
58
|
+
|
|
59
|
+
for (const pattern of CONFIRMATION_PATTERNS) {
|
|
60
|
+
if (pattern.test(command)) {
|
|
61
|
+
return {
|
|
62
|
+
invocationMessage: `Run deployment command: \`agentuity ${command}\``,
|
|
63
|
+
confirmationMessages: {
|
|
64
|
+
title: 'Deploy to Agentuity Cloud',
|
|
65
|
+
message: new vscode.MarkdownString(
|
|
66
|
+
`This will deploy your project to Agentuity Cloud.\n\n\`\`\`bash\nagentuity ${command}\n\`\`\`\n\nDo you want to continue?`
|
|
67
|
+
),
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {
|
|
74
|
+
invocationMessage: `Running: \`agentuity ${command}\``,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function registerCliTool(context: vscode.ExtensionContext): void {
|
|
80
|
+
if (!vscode.lm?.registerTool) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
const tool = new AgentuityCliTool();
|
|
86
|
+
const disposable = vscode.lm.registerTool('agentuity_run_cli', tool);
|
|
87
|
+
context.subscriptions.push(disposable);
|
|
88
|
+
} catch {
|
|
89
|
+
// LM API not available
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
|
|
3
|
+
export class AgentCodeLensProvider implements vscode.CodeLensProvider {
|
|
4
|
+
private _onDidChangeCodeLenses = new vscode.EventEmitter<void>();
|
|
5
|
+
readonly onDidChangeCodeLenses = this._onDidChangeCodeLenses.event;
|
|
6
|
+
|
|
7
|
+
// Match both: createAgent('name', { and createAgent({
|
|
8
|
+
private createAgentRegex = /createAgent\s*\(/g;
|
|
9
|
+
|
|
10
|
+
refresh(): void {
|
|
11
|
+
this._onDidChangeCodeLenses.fire();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
provideCodeLenses(
|
|
15
|
+
document: vscode.TextDocument,
|
|
16
|
+
_token: vscode.CancellationToken
|
|
17
|
+
): vscode.CodeLens[] | Thenable<vscode.CodeLens[]> {
|
|
18
|
+
const codeLenses: vscode.CodeLens[] = [];
|
|
19
|
+
const text = document.getText();
|
|
20
|
+
|
|
21
|
+
let match: RegExpExecArray | null;
|
|
22
|
+
this.createAgentRegex.lastIndex = 0;
|
|
23
|
+
|
|
24
|
+
while ((match = this.createAgentRegex.exec(text)) !== null) {
|
|
25
|
+
const position = document.positionAt(match.index);
|
|
26
|
+
const range = new vscode.Range(position, position);
|
|
27
|
+
|
|
28
|
+
const agentInfo = this.extractAgentInfo(document, match.index);
|
|
29
|
+
|
|
30
|
+
codeLenses.push(
|
|
31
|
+
new vscode.CodeLens(range, {
|
|
32
|
+
title: '$(play) Open in Workbench',
|
|
33
|
+
command: 'agentuity.codeLens.openInWorkbench',
|
|
34
|
+
arguments: [agentInfo],
|
|
35
|
+
tooltip: 'Open this agent in the Agentuity Workbench (requires dev server running)',
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
codeLenses.push(
|
|
40
|
+
new vscode.CodeLens(range, {
|
|
41
|
+
title: '$(pulse) View Sessions',
|
|
42
|
+
command: 'agentuity.codeLens.viewSessions',
|
|
43
|
+
arguments: [agentInfo],
|
|
44
|
+
tooltip: 'View sessions for this agent',
|
|
45
|
+
})
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
return codeLenses;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
private extractAgentInfo(
|
|
53
|
+
document: vscode.TextDocument,
|
|
54
|
+
startIndex: number
|
|
55
|
+
): AgentCodeLensInfo {
|
|
56
|
+
const text = document.getText();
|
|
57
|
+
const afterCreateAgent = text.substring(startIndex);
|
|
58
|
+
|
|
59
|
+
let name: string | undefined;
|
|
60
|
+
let identifier: string | undefined;
|
|
61
|
+
|
|
62
|
+
// Try to match createAgent('identifier', { pattern (first arg is the identifier)
|
|
63
|
+
const firstArgMatch = afterCreateAgent.match(/createAgent\s*\(\s*['"`]([^'"`]+)['"`]/);
|
|
64
|
+
if (firstArgMatch) {
|
|
65
|
+
identifier = firstArgMatch[1];
|
|
66
|
+
name = firstArgMatch[1];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Also check for name property in the config object
|
|
70
|
+
const nameMatch = afterCreateAgent.match(/name\s*:\s*['"`]([^'"`]+)['"`]/);
|
|
71
|
+
if (nameMatch) {
|
|
72
|
+
name = nameMatch[1];
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Check for explicit identifier property (overrides first arg)
|
|
76
|
+
const identifierMatch = afterCreateAgent.match(/identifier\s*:\s*['"`]([^'"`]+)['"`]/);
|
|
77
|
+
if (identifierMatch) {
|
|
78
|
+
identifier = identifierMatch[1];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Fallback: derive identifier from file path
|
|
82
|
+
if (!identifier) {
|
|
83
|
+
const relativePath = vscode.workspace.asRelativePath(document.uri);
|
|
84
|
+
const pathParts = relativePath.split('/');
|
|
85
|
+
const agentsIndex = pathParts.indexOf('agents');
|
|
86
|
+
if (agentsIndex !== -1 && agentsIndex < pathParts.length - 1) {
|
|
87
|
+
const agentPathParts = pathParts.slice(agentsIndex + 1);
|
|
88
|
+
const lastPart = agentPathParts[agentPathParts.length - 1];
|
|
89
|
+
if (lastPart === 'agent.ts' || lastPart === 'index.ts') {
|
|
90
|
+
agentPathParts.pop();
|
|
91
|
+
} else {
|
|
92
|
+
agentPathParts[agentPathParts.length - 1] = lastPart.replace(/\.(ts|js)$/, '');
|
|
93
|
+
}
|
|
94
|
+
if (agentPathParts.length > 0) {
|
|
95
|
+
identifier = agentPathParts.join('/');
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
name,
|
|
102
|
+
identifier,
|
|
103
|
+
filePath: document.uri.fsPath,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
dispose(): void {
|
|
108
|
+
this._onDidChangeCodeLenses.dispose();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface AgentCodeLensInfo {
|
|
113
|
+
name?: string;
|
|
114
|
+
identifier?: string;
|
|
115
|
+
filePath: string;
|
|
116
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
import { AgentCodeLensProvider, type AgentCodeLensInfo } from './agentCodeLensProvider';
|
|
3
|
+
import { getDevServerManager } from '../devServer';
|
|
4
|
+
import { getCurrentProject } from '../../core/project';
|
|
5
|
+
import { getAgentProvider } from '../agentExplorer';
|
|
6
|
+
|
|
7
|
+
const SESSIONS_BASE_URL = 'https://app-v1.agentuity.com';
|
|
8
|
+
|
|
9
|
+
export function registerCodeLens(context: vscode.ExtensionContext): AgentCodeLensProvider {
|
|
10
|
+
const provider = new AgentCodeLensProvider();
|
|
11
|
+
|
|
12
|
+
const selector: vscode.DocumentSelector = [
|
|
13
|
+
{ language: 'typescript', scheme: 'file' },
|
|
14
|
+
{ language: 'javascript', scheme: 'file' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
context.subscriptions.push(
|
|
18
|
+
vscode.languages.registerCodeLensProvider(selector, provider)
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
context.subscriptions.push(
|
|
22
|
+
vscode.commands.registerCommand(
|
|
23
|
+
'agentuity.codeLens.openInWorkbench',
|
|
24
|
+
async (info: AgentCodeLensInfo) => {
|
|
25
|
+
const devServer = getDevServerManager();
|
|
26
|
+
|
|
27
|
+
if (devServer.getState() !== 'running') {
|
|
28
|
+
const action = await vscode.window.showWarningMessage(
|
|
29
|
+
'Dev server is not running. Start it to open the Workbench.',
|
|
30
|
+
'Start Dev Server',
|
|
31
|
+
'Cancel'
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
if (action === 'Start Dev Server') {
|
|
35
|
+
await vscode.commands.executeCommand('agentuity.dev.start');
|
|
36
|
+
await waitForDevServer(5000);
|
|
37
|
+
|
|
38
|
+
if (devServer.getState() !== 'running') {
|
|
39
|
+
vscode.window.showErrorMessage('Failed to start dev server');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const port = vscode.workspace.getConfiguration('agentuity').get<number>('devServer.port', 3500);
|
|
48
|
+
let url = `http://localhost:${port}/workbench`;
|
|
49
|
+
if (info.identifier) {
|
|
50
|
+
url += `?agent=${encodeURIComponent(info.identifier)}`;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
await vscode.env.openExternal(vscode.Uri.parse(url));
|
|
54
|
+
}
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
context.subscriptions.push(
|
|
59
|
+
vscode.commands.registerCommand(
|
|
60
|
+
'agentuity.codeLens.viewSessions',
|
|
61
|
+
async (info: AgentCodeLensInfo) => {
|
|
62
|
+
const project = getCurrentProject();
|
|
63
|
+
if (!project) {
|
|
64
|
+
vscode.window.showErrorMessage('No Agentuity project found');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (!info.identifier) {
|
|
69
|
+
vscode.window.showErrorMessage('Could not determine agent identifier');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const agentProvider = getAgentProvider();
|
|
74
|
+
if (!agentProvider) {
|
|
75
|
+
vscode.window.showErrorMessage('Agent explorer not initialized');
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const agent = agentProvider.findAgentByIdentifier(info.identifier);
|
|
80
|
+
|
|
81
|
+
if (!agent) {
|
|
82
|
+
vscode.window.showWarningMessage(
|
|
83
|
+
`Agent "${info.identifier}" not found. Deploy your project first to view sessions.`
|
|
84
|
+
);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const url = `${SESSIONS_BASE_URL}/projects/${project.projectId}/sessions?agent=${agent.id}`;
|
|
89
|
+
await vscode.env.openExternal(vscode.Uri.parse(url));
|
|
90
|
+
}
|
|
91
|
+
)
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const devServer = getDevServerManager();
|
|
95
|
+
devServer.onStateChanged(() => {
|
|
96
|
+
provider.refresh();
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
context.subscriptions.push({ dispose: () => provider.dispose() });
|
|
100
|
+
|
|
101
|
+
return provider;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function waitForDevServer(timeoutMs: number): Promise<boolean> {
|
|
105
|
+
const devServer = getDevServerManager();
|
|
106
|
+
|
|
107
|
+
return new Promise((resolve) => {
|
|
108
|
+
if (devServer.getState() === 'running') {
|
|
109
|
+
resolve(true);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const timeout = setTimeout(() => {
|
|
114
|
+
disposable.dispose();
|
|
115
|
+
resolve(false);
|
|
116
|
+
}, timeoutMs);
|
|
117
|
+
|
|
118
|
+
const disposable = devServer.onStateChanged((state) => {
|
|
119
|
+
if (state === 'running') {
|
|
120
|
+
clearTimeout(timeout);
|
|
121
|
+
disposable.dispose();
|
|
122
|
+
resolve(true);
|
|
123
|
+
} else if (state === 'error' || state === 'stopped') {
|
|
124
|
+
clearTimeout(timeout);
|
|
125
|
+
disposable.dispose();
|
|
126
|
+
resolve(false);
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export { AgentCodeLensProvider, type AgentCodeLensInfo };
|