agentuity-vscode 0.0.95 → 0.0.97

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.
@@ -0,0 +1,374 @@
1
+ import * as vscode from 'vscode';
2
+ import { getCliClient } from '../../core/cliClient';
3
+ import { getAuthStatus } from '../../core/auth';
4
+ import { hasProject, getCurrentProject } from '../../core/project';
5
+ import { getDevServerManager } from '../devServer';
6
+
7
+ interface AgentuityContextItem extends vscode.ChatContextItem {
8
+ contextType: 'workspace' | 'agents' | 'deployments' | 'devServer' | 'agent-detail';
9
+ agentId?: string;
10
+ }
11
+
12
+ const CONTEXT_PROVIDER_ID = 'agentuity.context';
13
+
14
+ export function registerChatContextProvider(context: vscode.ExtensionContext): void {
15
+ if (!vscode.chat?.registerChatContextProvider) {
16
+ return;
17
+ }
18
+
19
+ try {
20
+ const provider = new AgentuityContextProvider();
21
+
22
+ const disposable = vscode.chat.registerChatContextProvider(
23
+ [
24
+ { language: 'typescript' },
25
+ { language: 'javascript' },
26
+ { pattern: '**/agentuity*.json' },
27
+ ],
28
+ CONTEXT_PROVIDER_ID,
29
+ provider
30
+ );
31
+
32
+ context.subscriptions.push(disposable);
33
+ context.subscriptions.push(provider);
34
+ } catch {
35
+ // Chat context provider API not available
36
+ }
37
+ }
38
+
39
+ class AgentuityContextProvider implements vscode.ChatContextProvider<AgentuityContextItem> {
40
+ private readonly _onDidChangeWorkspaceChatContext = new vscode.EventEmitter<void>();
41
+ readonly onDidChangeWorkspaceChatContext = this._onDidChangeWorkspaceChatContext.event;
42
+
43
+ private _disposables: vscode.Disposable[] = [];
44
+
45
+ constructor() {
46
+ const devServer = getDevServerManager();
47
+ this._disposables.push(
48
+ devServer.onStateChanged(() => {
49
+ this._onDidChangeWorkspaceChatContext.fire();
50
+ })
51
+ );
52
+ }
53
+
54
+ dispose(): void {
55
+ this._onDidChangeWorkspaceChatContext.dispose();
56
+ for (const d of this._disposables) {
57
+ d.dispose();
58
+ }
59
+ }
60
+
61
+ async provideWorkspaceChatContext(
62
+ _token: vscode.CancellationToken
63
+ ): Promise<AgentuityContextItem[]> {
64
+ if (!hasProject()) {
65
+ return [];
66
+ }
67
+
68
+ const items: AgentuityContextItem[] = [];
69
+
70
+ items.push({
71
+ icon: new vscode.ThemeIcon('rocket'),
72
+ label: 'Agentuity Project',
73
+ modelDescription:
74
+ 'Summary of the Agentuity AI agent project including authentication, agents, deployments, and dev server status',
75
+ contextType: 'workspace',
76
+ });
77
+
78
+ return items;
79
+ }
80
+
81
+ async provideChatContextExplicit(
82
+ token: vscode.CancellationToken
83
+ ): Promise<AgentuityContextItem[]> {
84
+ if (!hasProject()) {
85
+ return [];
86
+ }
87
+
88
+ const items: AgentuityContextItem[] = [];
89
+
90
+ items.push({
91
+ icon: new vscode.ThemeIcon('rocket'),
92
+ label: 'Agentuity: Full Project Context',
93
+ modelDescription:
94
+ 'Complete Agentuity project context including all agents, deployments, data stores, and dev server status',
95
+ contextType: 'workspace',
96
+ });
97
+
98
+ items.push({
99
+ icon: new vscode.ThemeIcon('hubot'),
100
+ label: 'Agentuity: Agents',
101
+ modelDescription: 'List of all agents in this Agentuity project with their configuration',
102
+ contextType: 'agents',
103
+ });
104
+
105
+ items.push({
106
+ icon: new vscode.ThemeIcon('cloud-upload'),
107
+ label: 'Agentuity: Deployments',
108
+ modelDescription: 'Recent deployments and their status for this Agentuity project',
109
+ contextType: 'deployments',
110
+ });
111
+
112
+ items.push({
113
+ icon: new vscode.ThemeIcon('server-process'),
114
+ label: 'Agentuity: Dev Server',
115
+ modelDescription: 'Current dev server status and configuration',
116
+ contextType: 'devServer',
117
+ });
118
+
119
+ if (!token.isCancellationRequested) {
120
+ const cli = getCliClient();
121
+ const agentsResult = await cli.listAgents();
122
+
123
+ if (agentsResult.success && agentsResult.data) {
124
+ for (const agent of agentsResult.data) {
125
+ items.push({
126
+ icon: new vscode.ThemeIcon('hubot'),
127
+ label: `Agentuity Agent: ${agent.name}`,
128
+ modelDescription: `Details for the "${agent.name}" agent including configuration, tools, and recent sessions`,
129
+ contextType: 'agent-detail',
130
+ agentId: agent.id,
131
+ });
132
+ }
133
+ }
134
+ }
135
+
136
+ return items;
137
+ }
138
+
139
+ async resolveChatContext(
140
+ item: AgentuityContextItem,
141
+ token: vscode.CancellationToken
142
+ ): Promise<vscode.ChatContextItem> {
143
+ let value: string;
144
+
145
+ switch (item.contextType) {
146
+ case 'workspace':
147
+ value = await this.resolveWorkspaceContext(token);
148
+ break;
149
+ case 'agents':
150
+ value = await this.resolveAgentsContext(token);
151
+ break;
152
+ case 'deployments':
153
+ value = await this.resolveDeploymentsContext(token);
154
+ break;
155
+ case 'devServer':
156
+ value = this.resolveDevServerContext();
157
+ break;
158
+ case 'agent-detail':
159
+ value = await this.resolveAgentDetailContext(item.agentId!, token);
160
+ break;
161
+ default:
162
+ value = 'No context available';
163
+ }
164
+
165
+ return {
166
+ icon: item.icon,
167
+ label: item.label,
168
+ modelDescription: item.modelDescription,
169
+ value,
170
+ };
171
+ }
172
+
173
+ private async resolveWorkspaceContext(token: vscode.CancellationToken): Promise<string> {
174
+ const lines: string[] = ['# Agentuity Project Context', ''];
175
+
176
+ const authStatus = getAuthStatus();
177
+ lines.push('## Authentication');
178
+ if (authStatus.state === 'authenticated' && authStatus.user) {
179
+ lines.push(`- Status: Authenticated`);
180
+ lines.push(`- User: ${authStatus.user.firstName} ${authStatus.user.lastName}`);
181
+ } else {
182
+ lines.push('- Status: Not authenticated');
183
+ }
184
+ lines.push('');
185
+
186
+ const project = getCurrentProject();
187
+ lines.push('## Project');
188
+ if (project) {
189
+ lines.push(`- Project ID: ${project.projectId}`);
190
+ lines.push(`- Organization ID: ${project.orgId}`);
191
+ if (project.region) {
192
+ lines.push(`- Region: ${project.region}`);
193
+ }
194
+ } else {
195
+ lines.push('- No project configuration found');
196
+ }
197
+ lines.push('');
198
+
199
+ lines.push('## Dev Server');
200
+ const devServer = getDevServerManager();
201
+ lines.push(`- Status: ${devServer.getState()}`);
202
+ lines.push('');
203
+
204
+ if (!token.isCancellationRequested && hasProject()) {
205
+ const cli = getCliClient();
206
+
207
+ const agentsResult = await cli.listAgents();
208
+ if (agentsResult.success && agentsResult.data) {
209
+ lines.push(`## Agents (${agentsResult.data.length})`);
210
+ for (const agent of agentsResult.data) {
211
+ lines.push(`- **${agent.name}** (${agent.identifier || agent.id})`);
212
+ if (agent.description) {
213
+ lines.push(` - ${agent.description}`);
214
+ }
215
+ }
216
+ lines.push('');
217
+ }
218
+
219
+ if (!token.isCancellationRequested) {
220
+ const deploymentsResult = await cli.listDeployments();
221
+ if (deploymentsResult.success && deploymentsResult.data) {
222
+ const recent = deploymentsResult.data.slice(0, 5);
223
+ lines.push(
224
+ `## Recent Deployments (${recent.length} of ${deploymentsResult.data.length})`
225
+ );
226
+ for (const dep of recent) {
227
+ const status = dep.active ? 'Active' : dep.state || 'Inactive';
228
+ const date = new Date(dep.createdAt).toLocaleDateString();
229
+ lines.push(`- ${dep.id.substring(0, 8)} - ${status} (${date})`);
230
+ }
231
+ lines.push('');
232
+ }
233
+ }
234
+ }
235
+
236
+ return lines.join('\n');
237
+ }
238
+
239
+ private async resolveAgentsContext(_token: vscode.CancellationToken): Promise<string> {
240
+ if (!hasProject()) {
241
+ return 'No Agentuity project found in workspace.';
242
+ }
243
+
244
+ const cli = getCliClient();
245
+ const result = await cli.listAgents();
246
+
247
+ if (!result.success || !result.data) {
248
+ return `Failed to fetch agents: ${result.error || 'Unknown error'}`;
249
+ }
250
+
251
+ const lines: string[] = [`# Agentuity Agents (${result.data.length})`, ''];
252
+
253
+ for (const agent of result.data) {
254
+ lines.push(`## ${agent.name}`);
255
+ lines.push(`- ID: ${agent.id}`);
256
+ lines.push(`- Identifier: ${agent.identifier || 'N/A'}`);
257
+ if (agent.description) {
258
+ lines.push(`- Description: ${agent.description}`);
259
+ }
260
+ if (agent.metadata?.filename) {
261
+ lines.push(`- Source File: ${agent.metadata.filename}`);
262
+ }
263
+ lines.push('');
264
+ }
265
+
266
+ return lines.join('\n');
267
+ }
268
+
269
+ private async resolveDeploymentsContext(_token: vscode.CancellationToken): Promise<string> {
270
+ if (!hasProject()) {
271
+ return 'No Agentuity project found in workspace.';
272
+ }
273
+
274
+ const cli = getCliClient();
275
+ const result = await cli.listDeployments();
276
+
277
+ if (!result.success || !result.data) {
278
+ return `Failed to fetch deployments: ${result.error || 'Unknown error'}`;
279
+ }
280
+
281
+ const lines: string[] = [`# Agentuity Deployments (${result.data.length})`, ''];
282
+
283
+ for (const dep of result.data.slice(0, 10)) {
284
+ const status = dep.active ? 'Active' : dep.state || 'Inactive';
285
+ const date = new Date(dep.createdAt).toLocaleString();
286
+ lines.push(`## Deployment ${dep.id.substring(0, 8)}`);
287
+ lines.push(`- Full ID: ${dep.id}`);
288
+ lines.push(`- Status: ${status}`);
289
+ lines.push(`- Created: ${date}`);
290
+ if (dep.tags?.length) {
291
+ lines.push(`- Tags: ${dep.tags.join(', ')}`);
292
+ }
293
+ lines.push('');
294
+ }
295
+
296
+ if (result.data.length > 10) {
297
+ lines.push(`*...and ${result.data.length - 10} more deployments*`);
298
+ }
299
+
300
+ return lines.join('\n');
301
+ }
302
+
303
+ private resolveDevServerContext(): string {
304
+ const devServer = getDevServerManager();
305
+ const state = devServer.getState();
306
+
307
+ const lines: string[] = ['# Agentuity Dev Server', ''];
308
+ lines.push(`- Status: ${state}`);
309
+
310
+ if (state === 'running') {
311
+ lines.push('- The dev server is currently running and ready to handle requests');
312
+ lines.push('- Use the Agentuity Workbench to test agents locally');
313
+ } else if (state === 'error') {
314
+ lines.push('- The dev server encountered an error');
315
+ lines.push('- Check the output panel for details');
316
+ } else {
317
+ lines.push('- The dev server is not running');
318
+ lines.push('- Run `agentuity dev` or use the "Start Dev Server" command to start it');
319
+ }
320
+
321
+ return lines.join('\n');
322
+ }
323
+
324
+ private async resolveAgentDetailContext(
325
+ agentId: string,
326
+ token: vscode.CancellationToken
327
+ ): Promise<string> {
328
+ if (!hasProject()) {
329
+ return 'No Agentuity project found in workspace.';
330
+ }
331
+
332
+ const cli = getCliClient();
333
+ const agentsResult = await cli.listAgents();
334
+
335
+ if (!agentsResult.success || !agentsResult.data) {
336
+ return `Failed to fetch agent details: ${agentsResult.error || 'Unknown error'}`;
337
+ }
338
+
339
+ const agent = agentsResult.data.find((a) => a.id === agentId);
340
+ if (!agent) {
341
+ return `Agent with ID ${agentId} not found.`;
342
+ }
343
+
344
+ const lines: string[] = [`# Agent: ${agent.name}`, ''];
345
+ lines.push(`- ID: ${agent.id}`);
346
+ lines.push(`- Identifier: ${agent.identifier || 'N/A'}`);
347
+ if (agent.description) {
348
+ lines.push(`- Description: ${agent.description}`);
349
+ }
350
+ if (agent.metadata?.filename) {
351
+ lines.push(`- Source File: ${agent.metadata.filename}`);
352
+ }
353
+ lines.push('');
354
+
355
+ if (!token.isCancellationRequested) {
356
+ const sessionsResult = await cli.listSessions({ count: 10 });
357
+ if (sessionsResult.success && sessionsResult.data) {
358
+ const recentSessions = sessionsResult.data.slice(0, 5);
359
+ if (recentSessions.length > 0) {
360
+ lines.push(`## Recent Sessions (${recentSessions.length})`);
361
+ for (const session of recentSessions) {
362
+ const status = session.success ? '✓' : '✗';
363
+ const time = new Date(session.created_at).toLocaleString();
364
+ lines.push(
365
+ `- ${status} ${session.id.substring(0, 8)} - ${time} (${session.trigger})`
366
+ );
367
+ }
368
+ }
369
+ }
370
+ }
371
+
372
+ return lines.join('\n');
373
+ }
374
+ }
@@ -1,2 +1,4 @@
1
1
  export { registerChatParticipant } from './agentuityParticipant';
2
2
  export { registerCliTool } from './cliTool';
3
+ export { registerChatContextProvider } from './contextProvider';
4
+ export { registerAgentTools } from './agentTools';
@@ -1,4 +1,6 @@
1
1
  import * as vscode from 'vscode';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
2
4
  import { AgentCodeLensProvider, type AgentCodeLensInfo } from './agentCodeLensProvider';
3
5
  import { getDevServerManager } from '../devServer';
4
6
  import { getCurrentProject } from '../../core/project';
@@ -6,6 +8,59 @@ import { getAgentProvider } from '../agentExplorer';
6
8
 
7
9
  const SESSIONS_BASE_URL = 'https://app-v1.agentuity.com';
8
10
 
11
+ interface BuildMetadataAgent {
12
+ id: string;
13
+ name: string;
14
+ filename: string;
15
+ identifier?: string;
16
+ }
17
+
18
+ interface BuildMetadata {
19
+ agents?: BuildMetadataAgent[];
20
+ }
21
+
22
+ function findAgentIdFromMetadata(
23
+ project: { rootPath: string },
24
+ info: AgentCodeLensInfo
25
+ ): string | undefined {
26
+ try {
27
+ const metadataPath = path.join(project.rootPath, '.agentuity', 'agentuity.metadata.json');
28
+ if (!fs.existsSync(metadataPath)) {
29
+ return undefined;
30
+ }
31
+
32
+ const content = fs.readFileSync(metadataPath, 'utf-8');
33
+ const metadata: BuildMetadata = JSON.parse(content);
34
+
35
+ if (!metadata.agents || metadata.agents.length === 0) {
36
+ return undefined;
37
+ }
38
+
39
+ // Try to match by identifier first
40
+ if (info.identifier) {
41
+ const byIdentifier = metadata.agents.find(
42
+ (a) => a.name === info.identifier || a.identifier === info.identifier
43
+ );
44
+ if (byIdentifier) {
45
+ return byIdentifier.id;
46
+ }
47
+ }
48
+
49
+ // Try to match by filename
50
+ if (info.filePath) {
51
+ const relativePath = path.relative(project.rootPath, info.filePath);
52
+ const byFilename = metadata.agents.find((a) => a.filename === relativePath);
53
+ if (byFilename) {
54
+ return byFilename.id;
55
+ }
56
+ }
57
+
58
+ return undefined;
59
+ } catch {
60
+ return undefined;
61
+ }
62
+ }
63
+
9
64
  export function registerCodeLens(context: vscode.ExtensionContext): AgentCodeLensProvider {
10
65
  const provider = new AgentCodeLensProvider();
11
66
 
@@ -46,8 +101,14 @@ export function registerCodeLens(context: vscode.ExtensionContext): AgentCodeLen
46
101
  .getConfiguration('agentuity')
47
102
  .get<number>('devServer.port', 3500);
48
103
  let url = `http://localhost:${port}/workbench`;
49
- if (info.identifier) {
50
- url += `?agent=${encodeURIComponent(info.identifier)}`;
104
+
105
+ // Get agentId from build metadata
106
+ const project = getCurrentProject();
107
+ if (project) {
108
+ const agentId = findAgentIdFromMetadata(project, info);
109
+ if (agentId) {
110
+ url += `?agent=${encodeURIComponent(agentId)}`;
111
+ }
51
112
  }
52
113
 
53
114
  await vscode.env.openExternal(vscode.Uri.parse(url));
@@ -0,0 +1,252 @@
1
+ import * as vscode from 'vscode';
2
+ import * as path from 'path';
3
+
4
+ const AGENTUITY_DEVELOPER_AGENT = `---
5
+ name: Agentuity Developer
6
+ description: Expert at building and debugging Agentuity AI agents
7
+ tools:
8
+ - agentuity-agents
9
+ - agentuity-status
10
+ - agentuity-sessions
11
+ - agentuity-logs
12
+ - agentuity-dev
13
+ - agentuity-deployments
14
+ ---
15
+
16
+ You are an expert Agentuity developer assistant. You help build, debug, and deploy AI agents using the Agentuity platform.
17
+
18
+ ## Your Capabilities
19
+
20
+ You have access to specialized Agentuity tools:
21
+ - **#agentuity-agents**: List all agents in the project
22
+ - **#agentuity-status**: Get project status (auth, config, dev server, deployments)
23
+ - **#agentuity-sessions**: View recent agent execution sessions
24
+ - **#agentuity-logs**: Get detailed logs for a specific session
25
+ - **#agentuity-dev**: Control the dev server (start/stop/restart/status)
26
+ - **#agentuity-deployments**: List deployment history
27
+
28
+ ## Guidelines
29
+
30
+ 1. **Before making changes**, always check the current project status with #agentuity-status
31
+ 2. **For debugging**, fetch recent sessions and their logs to understand what went wrong
32
+ 3. **For testing**, ensure the dev server is running before suggesting tests
33
+ 4. **For deployment**, verify authentication status first
34
+
35
+ ## Agentuity Agent Structure
36
+
37
+ Agentuity agents are TypeScript/JavaScript files that export a handler:
38
+
39
+ \`\`\`typescript
40
+ import { Agent } from '@agentuity/sdk';
41
+
42
+ export default new Agent({
43
+ name: 'my-agent',
44
+ description: 'What this agent does',
45
+ async handler(request, context) {
46
+ // Agent logic here
47
+ return context.response.text('Hello!');
48
+ }
49
+ });
50
+ \`\`\`
51
+
52
+ ## Common Tasks
53
+
54
+ - **Create agent**: Scaffold a new agent file with proper structure
55
+ - **Debug failures**: Fetch session logs and analyze errors
56
+ - **Test locally**: Start dev server and use the Workbench
57
+ - **Deploy**: Run deployment after verifying all tests pass
58
+ `;
59
+
60
+ const AGENTUITY_REVIEWER_AGENT = `---
61
+ name: Agentuity Reviewer
62
+ description: Reviews Agentuity agent code for best practices and issues
63
+ tools:
64
+ - agentuity-agents
65
+ - agentuity-status
66
+ ---
67
+
68
+ You are an Agentuity code reviewer. You review agent implementations for:
69
+
70
+ ## Review Checklist
71
+
72
+ ### Security
73
+ - [ ] No hardcoded secrets or API keys
74
+ - [ ] Input validation on all user inputs
75
+ - [ ] Proper error handling without leaking sensitive info
76
+
77
+ ### Performance
78
+ - [ ] Efficient use of context and memory
79
+ - [ ] Appropriate timeouts for external calls
80
+ - [ ] No blocking operations in hot paths
81
+
82
+ ### Best Practices
83
+ - [ ] Clear agent name and description
84
+ - [ ] Proper TypeScript types
85
+ - [ ] Meaningful error messages
86
+ - [ ] Appropriate logging levels
87
+
88
+ ### Agentuity-Specific
89
+ - [ ] Correct use of \`context.response\` methods
90
+ - [ ] Proper handling of different content types
91
+ - [ ] Appropriate use of tools and integrations
92
+
93
+ ## Review Output Format
94
+
95
+ Provide feedback in this format:
96
+ 1. **Summary**: Overall assessment
97
+ 2. **Issues**: List of problems found with severity (Critical/Warning/Info)
98
+ 3. **Suggestions**: Improvements to consider
99
+ 4. **Code Examples**: Show corrected code where applicable
100
+ `;
101
+
102
+ const AGENTUITY_DEBUGGER_AGENT = `---
103
+ name: Agentuity Debugger
104
+ description: Diagnoses and fixes issues with Agentuity agents
105
+ tools:
106
+ - agentuity-agents
107
+ - agentuity-status
108
+ - agentuity-sessions
109
+ - agentuity-logs
110
+ - agentuity-dev
111
+ ---
112
+
113
+ You are an Agentuity debugging specialist. Your job is to diagnose and fix issues with AI agents.
114
+
115
+ ## Debugging Workflow
116
+
117
+ 1. **Gather Context**
118
+ - Use #agentuity-status to check project state
119
+ - Use #agentuity-sessions to find recent failures
120
+ - Use #agentuity-logs to get detailed error information
121
+
122
+ 2. **Analyze**
123
+ - Identify error patterns
124
+ - Check for common issues (auth, network, timeouts)
125
+ - Review agent code for bugs
126
+
127
+ 3. **Fix**
128
+ - Propose minimal, targeted fixes
129
+ - Explain the root cause
130
+ - Suggest tests to prevent regression
131
+
132
+ ## Common Issues
133
+
134
+ ### Agent Not Responding
135
+ - Check if dev server is running (#agentuity-dev status)
136
+ - Verify agent is properly exported
137
+ - Check for infinite loops or blocking calls
138
+
139
+ ### Authentication Errors
140
+ - Verify #agentuity-status shows authenticated
141
+ - Check API key configuration
142
+ - Ensure correct environment variables
143
+
144
+ ### Timeout Errors
145
+ - Look for slow external API calls
146
+ - Check for missing await statements
147
+ - Review promise handling
148
+
149
+ ### Response Format Errors
150
+ - Verify correct use of context.response methods
151
+ - Check content-type headers
152
+ - Validate JSON serialization
153
+ `;
154
+
155
+ export async function scaffoldCustomAgents(): Promise<void> {
156
+ const workspaceFolders = vscode.workspace.workspaceFolders;
157
+ if (!workspaceFolders || workspaceFolders.length === 0) {
158
+ vscode.window.showErrorMessage('No workspace folder open. Open a folder first.');
159
+ return;
160
+ }
161
+
162
+ const rootPath = workspaceFolders[0].uri.fsPath;
163
+ const agentsDir = path.join(rootPath, '.github', 'agents');
164
+
165
+ const agents = [
166
+ { name: 'agentuity-developer.agent.md', content: AGENTUITY_DEVELOPER_AGENT },
167
+ { name: 'agentuity-reviewer.agent.md', content: AGENTUITY_REVIEWER_AGENT },
168
+ { name: 'agentuity-debugger.agent.md', content: AGENTUITY_DEBUGGER_AGENT },
169
+ ];
170
+
171
+ const selected = await vscode.window.showQuickPick(
172
+ [
173
+ { label: 'All Agents', description: 'Create all Agentuity custom agents', value: 'all' },
174
+ {
175
+ label: 'Agentuity Developer',
176
+ description: 'Expert at building and debugging agents',
177
+ value: 'developer',
178
+ },
179
+ {
180
+ label: 'Agentuity Reviewer',
181
+ description: 'Reviews agent code for best practices',
182
+ value: 'reviewer',
183
+ },
184
+ {
185
+ label: 'Agentuity Debugger',
186
+ description: 'Diagnoses and fixes agent issues',
187
+ value: 'debugger',
188
+ },
189
+ ],
190
+ {
191
+ placeHolder: 'Select which custom agent(s) to create',
192
+ title: 'Create Agentuity Custom Agents',
193
+ }
194
+ );
195
+
196
+ if (!selected) {
197
+ return;
198
+ }
199
+
200
+ const agentsDirUri = vscode.Uri.file(agentsDir);
201
+
202
+ try {
203
+ await vscode.workspace.fs.createDirectory(agentsDirUri);
204
+ } catch {
205
+ // Directory might already exist
206
+ }
207
+
208
+ const toCreate =
209
+ selected.value === 'all'
210
+ ? agents
211
+ : agents.filter((a) => a.name.includes(selected.value as string));
212
+
213
+ const writtenFiles: vscode.Uri[] = [];
214
+
215
+ for (const agent of toCreate) {
216
+ const filePath = vscode.Uri.file(path.join(agentsDir, agent.name));
217
+
218
+ try {
219
+ await vscode.workspace.fs.stat(filePath);
220
+ const overwrite = await vscode.window.showWarningMessage(
221
+ `${agent.name} already exists. Overwrite?`,
222
+ 'Yes',
223
+ 'No'
224
+ );
225
+ if (overwrite !== 'Yes') {
226
+ continue;
227
+ }
228
+ } catch {
229
+ // File doesn't exist, proceed
230
+ }
231
+
232
+ await vscode.workspace.fs.writeFile(filePath, Buffer.from(agent.content, 'utf-8'));
233
+ writtenFiles.push(filePath);
234
+ }
235
+
236
+ if (writtenFiles.length === 0) {
237
+ vscode.window.showInformationMessage('No custom agents were created.');
238
+ return;
239
+ }
240
+
241
+ vscode.window.showInformationMessage(
242
+ `Created ${writtenFiles.length} custom agent${writtenFiles.length > 1 ? 's' : ''} in .github/agents/`
243
+ );
244
+
245
+ await vscode.window.showTextDocument(writtenFiles[0]);
246
+ }
247
+
248
+ export function registerCustomAgentCommands(context: vscode.ExtensionContext): void {
249
+ context.subscriptions.push(
250
+ vscode.commands.registerCommand('agentuity.createCustomAgents', () => scaffoldCustomAgents())
251
+ );
252
+ }