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,777 @@
|
|
|
1
|
+
import * as vscode from 'vscode';
|
|
2
|
+
import { spawn, type ChildProcess } from 'child_process';
|
|
3
|
+
import * as fs from 'fs';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
import * as jsonc from 'jsonc-parser';
|
|
7
|
+
|
|
8
|
+
export interface StructuredCliError {
|
|
9
|
+
_tag?: string;
|
|
10
|
+
message: string;
|
|
11
|
+
code?: string;
|
|
12
|
+
details?: Record<string, unknown>;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface CliResult<T = unknown> {
|
|
16
|
+
success: boolean;
|
|
17
|
+
data?: T;
|
|
18
|
+
error?: string;
|
|
19
|
+
structuredError?: StructuredCliError;
|
|
20
|
+
exitCode: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export interface CliOptions {
|
|
24
|
+
cwd?: string;
|
|
25
|
+
timeout?: number;
|
|
26
|
+
format?: 'json' | 'text';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export class CliClient {
|
|
30
|
+
private outputChannel: vscode.OutputChannel;
|
|
31
|
+
|
|
32
|
+
constructor() {
|
|
33
|
+
this.outputChannel = vscode.window.createOutputChannel('Agentuity CLI');
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Get the CLI executable path from settings, common install locations, or PATH.
|
|
38
|
+
*/
|
|
39
|
+
getCliPath(): string {
|
|
40
|
+
const config = vscode.workspace.getConfiguration('agentuity');
|
|
41
|
+
const customPath = config.get<string>('cliPath');
|
|
42
|
+
if (customPath && customPath.trim() !== '') {
|
|
43
|
+
return customPath;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Check common install location: ~/.agentuity/bin/agentuity
|
|
47
|
+
const homeDir = os.homedir();
|
|
48
|
+
const defaultInstallPath = path.join(homeDir, '.agentuity', 'bin', 'agentuity');
|
|
49
|
+
if (fs.existsSync(defaultInstallPath)) {
|
|
50
|
+
return defaultInstallPath;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Fall back to PATH lookup
|
|
54
|
+
return 'agentuity';
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
private getProjectCwd(): string | undefined {
|
|
58
|
+
const workspaceFolders = vscode.workspace.workspaceFolders;
|
|
59
|
+
if (!workspaceFolders || workspaceFolders.length === 0) {
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
return workspaceFolders[0].uri.fsPath;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Read the region from the project's agentuity.json file.
|
|
67
|
+
*/
|
|
68
|
+
private getProjectRegion(): string | undefined {
|
|
69
|
+
const projectDir = this.getProjectCwd();
|
|
70
|
+
if (!projectDir) return undefined;
|
|
71
|
+
|
|
72
|
+
const configPath = path.join(projectDir, 'agentuity.json');
|
|
73
|
+
if (!fs.existsSync(configPath)) return undefined;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const content = fs.readFileSync(configPath, 'utf-8');
|
|
77
|
+
const config = jsonc.parse(content) as Record<string, unknown>;
|
|
78
|
+
return config.region as string | undefined;
|
|
79
|
+
} catch {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Append --dir flag to args if we have a project directory.
|
|
86
|
+
* Used for commands that accept --dir (those with requires/optional project).
|
|
87
|
+
* The --dir flag is a subcommand option, so it must come after the command.
|
|
88
|
+
*/
|
|
89
|
+
private withProjectDir(args: string[]): string[] {
|
|
90
|
+
const projectDir = this.getProjectCwd();
|
|
91
|
+
if (projectDir) {
|
|
92
|
+
return [...args, '--dir', projectDir];
|
|
93
|
+
}
|
|
94
|
+
return args;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Append --region flag to args using region from agentuity.json.
|
|
99
|
+
* Used for commands that require region but don't accept --dir.
|
|
100
|
+
* The --region flag is a subcommand option, so it must come after the command.
|
|
101
|
+
*/
|
|
102
|
+
private withRegion(args: string[]): string[] {
|
|
103
|
+
const region = this.getProjectRegion();
|
|
104
|
+
if (region) {
|
|
105
|
+
return [...args, '--region', region];
|
|
106
|
+
}
|
|
107
|
+
return args;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Get the environment variables for CLI execution.
|
|
112
|
+
* Sets TERM_PROGRAM=vscode to ensure CLI disables interactive mode.
|
|
113
|
+
*/
|
|
114
|
+
getCliEnv(): NodeJS.ProcessEnv {
|
|
115
|
+
return {
|
|
116
|
+
...process.env,
|
|
117
|
+
TERM_PROGRAM: 'vscode',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Try to parse a structured error from CLI output.
|
|
123
|
+
* The CLI may emit JSON errors with _tag, message, code, and details fields.
|
|
124
|
+
*/
|
|
125
|
+
private tryParseStructuredError(output: string): StructuredCliError | undefined {
|
|
126
|
+
if (!output) return undefined;
|
|
127
|
+
|
|
128
|
+
try {
|
|
129
|
+
const trimmed = output.trim();
|
|
130
|
+
if (!trimmed.startsWith('{')) return undefined;
|
|
131
|
+
|
|
132
|
+
const parsed = JSON.parse(trimmed);
|
|
133
|
+
if (parsed && typeof parsed === 'object' && 'message' in parsed) {
|
|
134
|
+
return {
|
|
135
|
+
_tag: parsed._tag,
|
|
136
|
+
message: parsed.message,
|
|
137
|
+
code: parsed.code,
|
|
138
|
+
details: parsed.details,
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
} catch {
|
|
142
|
+
// Not valid JSON, ignore
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
return undefined;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
async exec<T = unknown>(args: string[], options: CliOptions = {}): Promise<CliResult<T>> {
|
|
149
|
+
const cliPath = this.getCliPath();
|
|
150
|
+
const cwd = options.cwd ?? this.getProjectCwd();
|
|
151
|
+
const timeout = options.timeout ?? 30000;
|
|
152
|
+
|
|
153
|
+
if (options.format === 'json') {
|
|
154
|
+
args = ['--json', ...args];
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return new Promise((resolve) => {
|
|
158
|
+
let stdout = '';
|
|
159
|
+
let stderr = '';
|
|
160
|
+
let resolved = false;
|
|
161
|
+
|
|
162
|
+
const resolveOnce = (result: CliResult<T>) => {
|
|
163
|
+
if (!resolved) {
|
|
164
|
+
resolved = true;
|
|
165
|
+
resolve(result);
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
this.outputChannel.appendLine(`$ ${cliPath} ${args.join(' ')}`);
|
|
170
|
+
|
|
171
|
+
const child: ChildProcess = spawn(cliPath, args, {
|
|
172
|
+
cwd,
|
|
173
|
+
shell: true,
|
|
174
|
+
env: this.getCliEnv(),
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
const timeoutId = setTimeout(() => {
|
|
178
|
+
child.kill();
|
|
179
|
+
resolveOnce({
|
|
180
|
+
success: false,
|
|
181
|
+
error: `Command timed out after ${timeout}ms`,
|
|
182
|
+
exitCode: -1,
|
|
183
|
+
});
|
|
184
|
+
}, timeout);
|
|
185
|
+
|
|
186
|
+
child.stdout?.on('data', (data: Buffer) => {
|
|
187
|
+
stdout += data.toString();
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
child.stderr?.on('data', (data: Buffer) => {
|
|
191
|
+
stderr += data.toString();
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
child.on('error', (err: Error) => {
|
|
195
|
+
clearTimeout(timeoutId);
|
|
196
|
+
this.outputChannel.appendLine(`Error: ${err.message}`);
|
|
197
|
+
resolveOnce({
|
|
198
|
+
success: false,
|
|
199
|
+
error: err.message,
|
|
200
|
+
exitCode: -1,
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
child.on('close', (code: number | null) => {
|
|
205
|
+
clearTimeout(timeoutId);
|
|
206
|
+
const exitCode = code ?? 0;
|
|
207
|
+
|
|
208
|
+
if (stdout) {
|
|
209
|
+
this.outputChannel.appendLine(stdout);
|
|
210
|
+
}
|
|
211
|
+
if (stderr) {
|
|
212
|
+
this.outputChannel.appendLine(`stderr: ${stderr}`);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if (exitCode !== 0) {
|
|
216
|
+
// Try to parse structured error from CLI output
|
|
217
|
+
const structuredError = this.tryParseStructuredError(
|
|
218
|
+
options.format === 'json' ? stdout : stderr || stdout
|
|
219
|
+
);
|
|
220
|
+
resolveOnce({
|
|
221
|
+
success: false,
|
|
222
|
+
error: structuredError?.message || stderr || stdout || `Command failed with exit code ${exitCode}`,
|
|
223
|
+
structuredError,
|
|
224
|
+
exitCode,
|
|
225
|
+
});
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
if (options.format === 'json') {
|
|
230
|
+
try {
|
|
231
|
+
// Handle CLI bug where some commands output JSON twice
|
|
232
|
+
// Try to parse the first valid JSON object/array
|
|
233
|
+
const trimmed = stdout.trim();
|
|
234
|
+
let jsonStr = trimmed;
|
|
235
|
+
|
|
236
|
+
// If output contains multiple JSON values, take the first one
|
|
237
|
+
if (trimmed.startsWith('[') || trimmed.startsWith('{')) {
|
|
238
|
+
const firstChar = trimmed[0];
|
|
239
|
+
const closeChar = firstChar === '[' ? ']' : '}';
|
|
240
|
+
let depth = 0;
|
|
241
|
+
let endIdx = 0;
|
|
242
|
+
|
|
243
|
+
for (let i = 0; i < trimmed.length; i++) {
|
|
244
|
+
if (trimmed[i] === firstChar) depth++;
|
|
245
|
+
if (trimmed[i] === closeChar) depth--;
|
|
246
|
+
if (depth === 0) {
|
|
247
|
+
endIdx = i + 1;
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
if (endIdx > 0) {
|
|
253
|
+
jsonStr = trimmed.substring(0, endIdx);
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const data = JSON.parse(jsonStr) as T;
|
|
258
|
+
resolveOnce({ success: true, data, exitCode });
|
|
259
|
+
} catch {
|
|
260
|
+
resolveOnce({
|
|
261
|
+
success: false,
|
|
262
|
+
error: `Failed to parse JSON: ${stdout}`,
|
|
263
|
+
exitCode,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
} else {
|
|
267
|
+
resolveOnce({
|
|
268
|
+
success: true,
|
|
269
|
+
data: stdout.trim() as unknown as T,
|
|
270
|
+
exitCode,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
async version(): Promise<CliResult<string>> {
|
|
278
|
+
return this.exec<string>(['--version'], { format: 'text' });
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async whoami(): Promise<CliResult<WhoamiResponse>> {
|
|
282
|
+
return this.exec<WhoamiResponse>(['auth', 'whoami'], { format: 'json' });
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
async listAgents(): Promise<CliResult<AgentListResponse>> {
|
|
286
|
+
return this.exec<AgentListResponse>(['cloud', 'agent', 'list'], { format: 'json' });
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async listKvNamespaces(): Promise<CliResult<KvNamespaceListResponse>> {
|
|
290
|
+
return this.exec<KvNamespaceListResponse>(['cloud', 'keyvalue', 'list-namespaces'], {
|
|
291
|
+
format: 'json',
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
async listKvKeys(namespace: string): Promise<CliResult<KvKeysResponse>> {
|
|
296
|
+
return this.exec<KvKeysResponse>(['cloud', 'keyvalue', 'keys', namespace], {
|
|
297
|
+
format: 'json',
|
|
298
|
+
});
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
async getKvValue(namespace: string, key: string): Promise<CliResult<KvGetResponse>> {
|
|
304
|
+
return this.exec<KvGetResponse>(['cloud', 'keyvalue', 'get', namespace, key], {
|
|
305
|
+
format: 'json',
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
async getAiCapabilities(): Promise<CliResult<AiCapabilitiesResponse>> {
|
|
312
|
+
return this.exec<AiCapabilitiesResponse>(['ai', 'capabilities', 'show'], { format: 'json' });
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
async getAiSchema(): Promise<CliResult<AiSchemaResponse>> {
|
|
316
|
+
return this.exec<AiSchemaResponse>(['ai', 'schema', 'show'], { format: 'json' });
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async getAiPrompt(): Promise<CliResult<string>> {
|
|
320
|
+
return this.exec<string>(['ai', 'prompt', 'llm'], { format: 'text' });
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Database methods (require region - pass --region from agentuity.json)
|
|
324
|
+
async listDatabases(): Promise<CliResult<DbListResponse>> {
|
|
325
|
+
return this.exec<DbListResponse>(this.withRegion(['cloud', 'db', 'list']), {
|
|
326
|
+
format: 'json',
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
async getDatabase(name: string): Promise<CliResult<DbInfo>> {
|
|
331
|
+
return this.exec<DbInfo>(this.withRegion(['cloud', 'db', 'get', name]), {
|
|
332
|
+
format: 'json',
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
async getDbLogs(
|
|
337
|
+
name: string,
|
|
338
|
+
opts?: { limit?: number; hasError?: boolean; sessionId?: string }
|
|
339
|
+
): Promise<CliResult<DbQueryLog[]>> {
|
|
340
|
+
const args = ['cloud', 'db', 'logs', name];
|
|
341
|
+
if (opts?.limit) {
|
|
342
|
+
args.push('--limit', String(opts.limit));
|
|
343
|
+
}
|
|
344
|
+
if (opts?.hasError) {
|
|
345
|
+
args.push('--has-error');
|
|
346
|
+
}
|
|
347
|
+
if (opts?.sessionId) {
|
|
348
|
+
args.push('--session-id', opts.sessionId);
|
|
349
|
+
}
|
|
350
|
+
return this.exec<DbQueryLog[]>(this.withRegion(args), { format: 'json', timeout: 60000 });
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
// Storage methods (require region - pass --region from agentuity.json)
|
|
354
|
+
async listStorageBuckets(): Promise<CliResult<StorageListResponse>> {
|
|
355
|
+
return this.exec<StorageListResponse>(this.withRegion(['cloud', 'storage', 'list']), {
|
|
356
|
+
format: 'json',
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async listStorageFiles(
|
|
361
|
+
bucket: string,
|
|
362
|
+
prefix?: string
|
|
363
|
+
): Promise<CliResult<StorageListResponse>> {
|
|
364
|
+
const args = ['cloud', 'storage', 'list', bucket];
|
|
365
|
+
if (prefix) {
|
|
366
|
+
args.push(prefix);
|
|
367
|
+
}
|
|
368
|
+
return this.exec<StorageListResponse>(this.withRegion(args), { format: 'json' });
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
async getStorageFileMetadata(
|
|
372
|
+
bucket: string,
|
|
373
|
+
filename: string
|
|
374
|
+
): Promise<CliResult<StorageFileMetadataResponse>> {
|
|
375
|
+
return this.exec<StorageFileMetadataResponse>(
|
|
376
|
+
this.withRegion(['cloud', 'storage', 'download', bucket, filename, '--metadata']),
|
|
377
|
+
{ format: 'json' }
|
|
378
|
+
);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Stream methods
|
|
382
|
+
async listStreams(opts?: { size?: number; name?: string }): Promise<CliResult<StreamListResponse>> {
|
|
383
|
+
const args = ['cloud', 'stream', 'list'];
|
|
384
|
+
if (opts?.size) {
|
|
385
|
+
args.push('--size', String(opts.size));
|
|
386
|
+
}
|
|
387
|
+
if (opts?.name) {
|
|
388
|
+
args.push('--name', opts.name);
|
|
389
|
+
}
|
|
390
|
+
return this.exec<StreamListResponse>(args, { format: 'json' });
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
async getStream(id: string): Promise<CliResult<StreamInfo>> {
|
|
394
|
+
return this.exec<StreamInfo>(['cloud', 'stream', 'get', id], { format: 'json' });
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
async deleteStream(id: string): Promise<CliResult<void>> {
|
|
398
|
+
return this.exec<void>(['cloud', 'stream', 'delete', id], { format: 'json' });
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// Profile methods
|
|
402
|
+
async getCurrentProfile(): Promise<CliResult<string>> {
|
|
403
|
+
return this.exec<string>(['profile', 'current'], { format: 'json' });
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Vector methods
|
|
407
|
+
async vectorSearch(
|
|
408
|
+
namespace: string,
|
|
409
|
+
query: string,
|
|
410
|
+
opts?: { limit?: number; similarity?: number }
|
|
411
|
+
): Promise<CliResult<VectorSearchResponse>> {
|
|
412
|
+
const args = ['cloud', 'vector', 'search', namespace, query];
|
|
413
|
+
if (opts?.limit) {
|
|
414
|
+
args.push('--limit', String(opts.limit));
|
|
415
|
+
}
|
|
416
|
+
if (opts?.similarity) {
|
|
417
|
+
args.push('--similarity', String(opts.similarity));
|
|
418
|
+
}
|
|
419
|
+
return this.exec<VectorSearchResponse>(args, { format: 'json' });
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
async getVector(namespace: string, key: string): Promise<CliResult<VectorGetResponse>> {
|
|
423
|
+
return this.exec<VectorGetResponse>(['cloud', 'vector', 'get', namespace, key], {
|
|
424
|
+
format: 'json',
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
async deploy(): Promise<CliResult<DeployResponse>> {
|
|
429
|
+
return this.exec<DeployResponse>(['cloud', 'deploy'], { format: 'json', timeout: 120000 });
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
async listDeployments(count?: number): Promise<CliResult<DeploymentListResponse>> {
|
|
433
|
+
const args = ['cloud', 'deployment', 'list'];
|
|
434
|
+
if (count) {
|
|
435
|
+
args.push('--count', String(count));
|
|
436
|
+
}
|
|
437
|
+
return this.exec<DeploymentListResponse>(args, { format: 'json' });
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
async getDeployment(deploymentId: string): Promise<CliResult<DeploymentShowResponse>> {
|
|
441
|
+
return this.exec<DeploymentShowResponse>(['cloud', 'deployment', 'show', deploymentId], {
|
|
442
|
+
format: 'json',
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
async getDeploymentLogs(
|
|
447
|
+
deploymentId: string,
|
|
448
|
+
limit?: number
|
|
449
|
+
): Promise<CliResult<DeploymentLog[]>> {
|
|
450
|
+
const args = ['cloud', 'deployment', 'logs', deploymentId];
|
|
451
|
+
if (limit) {
|
|
452
|
+
args.push('--limit', String(limit));
|
|
453
|
+
}
|
|
454
|
+
return this.exec<DeploymentLog[]>(args, { format: 'json', timeout: 60000 });
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
// Session methods (require region - use --dir to ensure CLI finds agentuity.json)
|
|
458
|
+
async listSessions(opts?: SessionListOptions): Promise<CliResult<SessionListResponse>> {
|
|
459
|
+
const args = ['cloud', 'session', 'list'];
|
|
460
|
+
if (opts?.count) {
|
|
461
|
+
args.push('--count', String(opts.count));
|
|
462
|
+
}
|
|
463
|
+
if (opts?.deploymentId) {
|
|
464
|
+
args.push('--deployment-id', opts.deploymentId);
|
|
465
|
+
}
|
|
466
|
+
if (opts?.agentIdentifier) {
|
|
467
|
+
args.push('--agent-identifier', opts.agentIdentifier);
|
|
468
|
+
}
|
|
469
|
+
if (opts?.success !== undefined) {
|
|
470
|
+
args.push('--success', String(opts.success));
|
|
471
|
+
}
|
|
472
|
+
if (opts?.devmode !== undefined) {
|
|
473
|
+
args.push('--devmode', String(opts.devmode));
|
|
474
|
+
}
|
|
475
|
+
if (opts?.trigger) {
|
|
476
|
+
args.push('--trigger', opts.trigger);
|
|
477
|
+
}
|
|
478
|
+
if (opts?.env) {
|
|
479
|
+
args.push('--env', opts.env);
|
|
480
|
+
}
|
|
481
|
+
return this.exec<SessionListResponse>(this.withProjectDir(args), { format: 'json' });
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
async getSession(sessionId: string): Promise<CliResult<SessionGetResponse>> {
|
|
485
|
+
return this.exec<SessionGetResponse>(
|
|
486
|
+
this.withProjectDir(['cloud', 'session', 'get', sessionId]),
|
|
487
|
+
{ format: 'json' }
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
async getSessionLogs(sessionId: string): Promise<CliResult<SessionLog[]>> {
|
|
492
|
+
return this.exec<SessionLog[]>(
|
|
493
|
+
this.withProjectDir(['cloud', 'session', 'logs', sessionId]),
|
|
494
|
+
{ format: 'json', timeout: 60000 }
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
dispose(): void {
|
|
499
|
+
this.outputChannel.dispose();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
// Auth types
|
|
504
|
+
export interface WhoamiResponse {
|
|
505
|
+
id: string;
|
|
506
|
+
email: string;
|
|
507
|
+
name?: string;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// Agent types
|
|
511
|
+
export interface Agent {
|
|
512
|
+
id: string;
|
|
513
|
+
name: string;
|
|
514
|
+
description?: string;
|
|
515
|
+
identifier?: string;
|
|
516
|
+
metadata?: {
|
|
517
|
+
filename?: string;
|
|
518
|
+
identifier?: string;
|
|
519
|
+
};
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
export type AgentListResponse = Agent[];
|
|
523
|
+
|
|
524
|
+
// KV types
|
|
525
|
+
export type KvNamespaceListResponse = string[];
|
|
526
|
+
|
|
527
|
+
export interface KvKeysResponse {
|
|
528
|
+
namespace: string;
|
|
529
|
+
keys: string[];
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export interface KvGetResponse {
|
|
533
|
+
exists: boolean;
|
|
534
|
+
data: unknown;
|
|
535
|
+
contentType: string;
|
|
536
|
+
}
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
|
|
540
|
+
// Database types
|
|
541
|
+
export interface DbInfo {
|
|
542
|
+
name: string;
|
|
543
|
+
url: string;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
export interface DbListResponse {
|
|
547
|
+
databases: DbInfo[];
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
export interface DbQueryLog {
|
|
551
|
+
timestamp: string;
|
|
552
|
+
command: string;
|
|
553
|
+
sql: string;
|
|
554
|
+
duration: number;
|
|
555
|
+
username: string;
|
|
556
|
+
sessionId?: string;
|
|
557
|
+
error?: string;
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
// Storage types
|
|
561
|
+
export interface StorageBucket {
|
|
562
|
+
bucket_name: string;
|
|
563
|
+
access_key?: string;
|
|
564
|
+
secret_key?: string;
|
|
565
|
+
region?: string;
|
|
566
|
+
endpoint?: string;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
export interface StorageFile {
|
|
570
|
+
key: string;
|
|
571
|
+
size: number;
|
|
572
|
+
lastModified: string;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
export interface StorageListResponse {
|
|
576
|
+
buckets?: StorageBucket[];
|
|
577
|
+
files?: StorageFile[];
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
export interface StorageFileMetadataResponse {
|
|
581
|
+
success: boolean;
|
|
582
|
+
bucket: string;
|
|
583
|
+
filename: string;
|
|
584
|
+
size?: number;
|
|
585
|
+
contentType?: string;
|
|
586
|
+
lastModified?: string;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
// Stream types
|
|
590
|
+
export interface StreamInfo {
|
|
591
|
+
id: string;
|
|
592
|
+
name: string;
|
|
593
|
+
metadata: Record<string, string>;
|
|
594
|
+
url: string;
|
|
595
|
+
sizeBytes: number;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
export interface StreamListResponse {
|
|
599
|
+
streams: StreamInfo[];
|
|
600
|
+
total: number;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// Vector types
|
|
604
|
+
export interface VectorSearchResult {
|
|
605
|
+
id: string;
|
|
606
|
+
key: string;
|
|
607
|
+
similarity: number;
|
|
608
|
+
metadata?: Record<string, unknown>;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
export interface VectorSearchResponse {
|
|
612
|
+
namespace: string;
|
|
613
|
+
query: string;
|
|
614
|
+
results: VectorSearchResult[];
|
|
615
|
+
count: number;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export interface VectorGetResponse {
|
|
619
|
+
exists: boolean;
|
|
620
|
+
key: string;
|
|
621
|
+
id: string;
|
|
622
|
+
document: string;
|
|
623
|
+
metadata?: Record<string, unknown>;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
// AI types
|
|
627
|
+
export interface AiCapabilitiesResponse {
|
|
628
|
+
capabilities: unknown;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
export interface AiSchemaResponse {
|
|
632
|
+
schema: unknown;
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Deploy types
|
|
636
|
+
export interface DeployResponse {
|
|
637
|
+
deploymentId: string;
|
|
638
|
+
url?: string;
|
|
639
|
+
status: string;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
// Deployment types
|
|
643
|
+
export interface Deployment {
|
|
644
|
+
id: string;
|
|
645
|
+
state?: string;
|
|
646
|
+
active: boolean;
|
|
647
|
+
createdAt: string;
|
|
648
|
+
message?: string;
|
|
649
|
+
tags: string[];
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
export type DeploymentListResponse = Deployment[];
|
|
653
|
+
|
|
654
|
+
export interface DeploymentShowResponse {
|
|
655
|
+
id: string;
|
|
656
|
+
state?: string;
|
|
657
|
+
active: boolean;
|
|
658
|
+
createdAt: string;
|
|
659
|
+
updatedAt?: string;
|
|
660
|
+
message?: string;
|
|
661
|
+
tags: string[];
|
|
662
|
+
customDomains?: string[];
|
|
663
|
+
cloudRegion?: string;
|
|
664
|
+
metadata?: {
|
|
665
|
+
git?: {
|
|
666
|
+
repo?: string;
|
|
667
|
+
commit?: string;
|
|
668
|
+
message?: string;
|
|
669
|
+
branch?: string;
|
|
670
|
+
url?: string;
|
|
671
|
+
trigger?: string;
|
|
672
|
+
provider?: string;
|
|
673
|
+
event?: string;
|
|
674
|
+
buildUrl?: string;
|
|
675
|
+
};
|
|
676
|
+
build?: {
|
|
677
|
+
agentuity?: string;
|
|
678
|
+
bun?: string;
|
|
679
|
+
platform?: string;
|
|
680
|
+
arch?: string;
|
|
681
|
+
};
|
|
682
|
+
};
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
export interface DeploymentLog {
|
|
686
|
+
body: string;
|
|
687
|
+
severity: string;
|
|
688
|
+
timestamp: string;
|
|
689
|
+
spanId?: string;
|
|
690
|
+
traceId?: string;
|
|
691
|
+
serviceName?: string;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Session types
|
|
695
|
+
export interface SessionListOptions {
|
|
696
|
+
count?: number;
|
|
697
|
+
deploymentId?: string;
|
|
698
|
+
agentIdentifier?: string;
|
|
699
|
+
success?: boolean;
|
|
700
|
+
devmode?: boolean;
|
|
701
|
+
trigger?: 'api' | 'cron' | 'webhook';
|
|
702
|
+
env?: string;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
export interface Session {
|
|
706
|
+
id: string;
|
|
707
|
+
created_at: string;
|
|
708
|
+
success: boolean;
|
|
709
|
+
duration: number | null;
|
|
710
|
+
method: string;
|
|
711
|
+
url: string;
|
|
712
|
+
trigger: string;
|
|
713
|
+
env: string;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
export type SessionListResponse = Session[];
|
|
717
|
+
|
|
718
|
+
export interface SessionGetResponse {
|
|
719
|
+
id: string;
|
|
720
|
+
created_at: string;
|
|
721
|
+
start_time: string;
|
|
722
|
+
end_time: string | null;
|
|
723
|
+
duration: number | null;
|
|
724
|
+
org_id: string;
|
|
725
|
+
project_id: string;
|
|
726
|
+
deployment_id: string;
|
|
727
|
+
agent_ids: string[];
|
|
728
|
+
trigger: string;
|
|
729
|
+
env: string;
|
|
730
|
+
devmode: boolean;
|
|
731
|
+
pending: boolean;
|
|
732
|
+
success: boolean;
|
|
733
|
+
error: string | null;
|
|
734
|
+
method: string;
|
|
735
|
+
url: string;
|
|
736
|
+
route_id: string;
|
|
737
|
+
thread_id: string;
|
|
738
|
+
agents: Array<{ name: string; identifier: string }>;
|
|
739
|
+
eval_runs: Array<{
|
|
740
|
+
id: string;
|
|
741
|
+
eval_id: string;
|
|
742
|
+
created_at: string;
|
|
743
|
+
pending: boolean;
|
|
744
|
+
success: boolean;
|
|
745
|
+
error: string | null;
|
|
746
|
+
result: string | null;
|
|
747
|
+
}>;
|
|
748
|
+
timeline?: unknown;
|
|
749
|
+
route?: {
|
|
750
|
+
id: string;
|
|
751
|
+
method: string;
|
|
752
|
+
path: string;
|
|
753
|
+
} | null;
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
export interface SessionLog {
|
|
757
|
+
body: string;
|
|
758
|
+
severity: string;
|
|
759
|
+
timestamp: string;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// Singleton
|
|
763
|
+
let _cliClient: CliClient | undefined;
|
|
764
|
+
|
|
765
|
+
export function getCliClient(): CliClient {
|
|
766
|
+
if (!_cliClient) {
|
|
767
|
+
_cliClient = new CliClient();
|
|
768
|
+
}
|
|
769
|
+
return _cliClient;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
export function disposeCliClient(): void {
|
|
773
|
+
if (_cliClient) {
|
|
774
|
+
_cliClient.dispose();
|
|
775
|
+
_cliClient = undefined;
|
|
776
|
+
}
|
|
777
|
+
}
|