suzi-cli 0.1.13 → 0.1.14
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/dist/commands/accounts.d.ts.map +1 -1
- package/dist/commands/accounts.js +27 -7
- package/dist/commands/accounts.js.map +1 -1
- package/dist/commands/agent.d.ts +45 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +991 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/debug.d.ts.map +1 -1
- package/dist/commands/debug.js +124 -41
- package/dist/commands/debug.js.map +1 -1
- package/dist/commands/list-actions.d.ts.map +1 -1
- package/dist/commands/list-actions.js +35 -4
- package/dist/commands/list-actions.js.map +1 -1
- package/dist/commands/list-triggers.d.ts.map +1 -1
- package/dist/commands/list-triggers.js +38 -10
- package/dist/commands/list-triggers.js.map +1 -1
- package/dist/commands/portfolio.d.ts.map +1 -1
- package/dist/commands/portfolio.js +113 -14
- package/dist/commands/portfolio.js.map +1 -1
- package/dist/commands/preferences.d.ts.map +1 -1
- package/dist/commands/preferences.js +119 -26
- package/dist/commands/preferences.js.map +1 -1
- package/dist/commands/run.d.ts +4 -0
- package/dist/commands/run.d.ts.map +1 -1
- package/dist/commands/run.js +8 -305
- package/dist/commands/run.js.map +1 -1
- package/dist/commands/transactions.d.ts.map +1 -1
- package/dist/commands/transactions.js +18 -4
- package/dist/commands/transactions.js.map +1 -1
- package/dist/index.js +29 -26
- package/dist/index.js.map +1 -1
- package/dist/utils/agent-picker.d.ts +16 -0
- package/dist/utils/agent-picker.d.ts.map +1 -0
- package/dist/utils/agent-picker.js +83 -0
- package/dist/utils/agent-picker.js.map +1 -0
- package/dist/utils/resolver.d.ts +35 -0
- package/dist/utils/resolver.d.ts.map +1 -0
- package/dist/utils/resolver.js +157 -0
- package/dist/utils/resolver.js.map +1 -0
- package/dist/utils/tty.d.ts +26 -0
- package/dist/utils/tty.d.ts.map +1 -0
- package/dist/utils/tty.js +50 -0
- package/dist/utils/tty.js.map +1 -0
- package/dist/utils/ui.d.ts +4 -0
- package/dist/utils/ui.d.ts.map +1 -1
- package/dist/utils/ui.js +9 -0
- package/dist/utils/ui.js.map +1 -1
- package/package.json +1 -1
- package/dist/commands/agents.d.ts +0 -3
- package/dist/commands/agents.d.ts.map +0 -1
- package/dist/commands/agents.js +0 -309
- package/dist/commands/agents.js.map +0 -1
- package/dist/commands/deploy.d.ts +0 -3
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js +0 -174
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/validate.d.ts +0 -3
- package/dist/commands/validate.d.ts.map +0 -1
- package/dist/commands/validate.js +0 -165
- package/dist/commands/validate.js.map +0 -1
|
@@ -0,0 +1,991 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.registerAgentCommand = registerAgentCommand;
|
|
40
|
+
exports.listAgentsCommand = listAgentsCommand;
|
|
41
|
+
exports.viewAgentCommand = viewAgentCommand;
|
|
42
|
+
exports.deployAgentCommand = deployAgentCommand;
|
|
43
|
+
exports.validateAgentCommand = validateAgentCommand;
|
|
44
|
+
exports.activateAgentCommand = activateAgentCommand;
|
|
45
|
+
exports.deactivateAgentCommand = deactivateAgentCommand;
|
|
46
|
+
exports.executeAgentCommand = executeAgentCommand;
|
|
47
|
+
exports.logsAgentCommand = logsAgentCommand;
|
|
48
|
+
exports.codeAgentCommand = codeAgentCommand;
|
|
49
|
+
exports.deleteAgentCommand = deleteAgentCommand;
|
|
50
|
+
const commander_1 = require("commander");
|
|
51
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
52
|
+
const cli_table3_1 = __importDefault(require("cli-table3"));
|
|
53
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
54
|
+
const fs_1 = __importDefault(require("fs"));
|
|
55
|
+
const path_1 = __importDefault(require("path"));
|
|
56
|
+
const api_1 = require("../lib/api");
|
|
57
|
+
const ui_1 = require("../utils/ui");
|
|
58
|
+
const memory_1 = require("../lib/memory");
|
|
59
|
+
const tty_1 = require("../utils/tty");
|
|
60
|
+
const agent_picker_1 = require("../utils/agent-picker");
|
|
61
|
+
function registerAgentCommand(program) {
|
|
62
|
+
const agent = program
|
|
63
|
+
.command('agents')
|
|
64
|
+
.description('Manage agents (list, view, deploy, activate, execute, logs, etc.)');
|
|
65
|
+
// suzi agents (default: list)
|
|
66
|
+
agent
|
|
67
|
+
.action(async (opts) => {
|
|
68
|
+
// Default action is list
|
|
69
|
+
await listAgentsCommand(opts);
|
|
70
|
+
});
|
|
71
|
+
// suzi agents list
|
|
72
|
+
agent
|
|
73
|
+
.command('list')
|
|
74
|
+
.description('List all agents')
|
|
75
|
+
.option('--json', 'Output as JSON')
|
|
76
|
+
.action(async (opts) => {
|
|
77
|
+
await listAgentsCommand(opts);
|
|
78
|
+
});
|
|
79
|
+
// suzi agents view [id]
|
|
80
|
+
agent
|
|
81
|
+
.command('view [id]')
|
|
82
|
+
.description('View agent details')
|
|
83
|
+
.option('--json', 'Output as JSON')
|
|
84
|
+
.action(async (id, opts) => {
|
|
85
|
+
await viewAgentCommand(id, opts);
|
|
86
|
+
});
|
|
87
|
+
// suzi agents deploy [file]
|
|
88
|
+
agent
|
|
89
|
+
.command('deploy [file]')
|
|
90
|
+
.description('Deploy an agent from a TypeScript file')
|
|
91
|
+
.option('-t, --title <title>', 'Agent title')
|
|
92
|
+
.option('-d, --description <desc>', 'Agent description')
|
|
93
|
+
.option('--update <agentId>', 'Update an existing agent instead of creating new')
|
|
94
|
+
.option('--activate', 'Activate the agent after deploying')
|
|
95
|
+
.option('--json', 'Output as JSON')
|
|
96
|
+
.action(async (file, opts) => {
|
|
97
|
+
await deployAgentCommand(file, opts);
|
|
98
|
+
});
|
|
99
|
+
// suzi agents validate [file]
|
|
100
|
+
agent
|
|
101
|
+
.command('validate [file]')
|
|
102
|
+
.description('Validate an agent TypeScript file without deploying')
|
|
103
|
+
.option('--json', 'Output as JSON')
|
|
104
|
+
.action(async (file, opts) => {
|
|
105
|
+
await validateAgentCommand(file, opts);
|
|
106
|
+
});
|
|
107
|
+
// suzi agents run <action>
|
|
108
|
+
agent
|
|
109
|
+
.command('run <action>')
|
|
110
|
+
.description('Execute an action directly (e.g. suzi agents run polymarket.get_market_price --tokenID 0x123)')
|
|
111
|
+
.allowUnknownOption()
|
|
112
|
+
.allowExcessArguments(true)
|
|
113
|
+
.option('--json-params <params>', 'Pass all parameters as a JSON string')
|
|
114
|
+
.option('--output <format>', 'Output format: pretty (default) or json', 'pretty')
|
|
115
|
+
.option('--dry-run', 'Preview the request payload without executing')
|
|
116
|
+
.action(async (action, opts) => {
|
|
117
|
+
// Delegate to existing run command logic
|
|
118
|
+
const { registerRunCommand } = await Promise.resolve().then(() => __importStar(require('./run')));
|
|
119
|
+
const tempProgram = new commander_1.Command();
|
|
120
|
+
registerRunCommand(tempProgram);
|
|
121
|
+
// Re-parse args for run command
|
|
122
|
+
const runArgs = ['node', 'suzi', 'run', action, ...process.argv.slice(process.argv.indexOf(action) + 1)];
|
|
123
|
+
await tempProgram.parseAsync(runArgs);
|
|
124
|
+
});
|
|
125
|
+
// suzi agents activate [id]
|
|
126
|
+
agent
|
|
127
|
+
.command('activate [id]')
|
|
128
|
+
.description('Activate an agent')
|
|
129
|
+
.option('--json', 'Output as JSON')
|
|
130
|
+
.action(async (id, opts) => {
|
|
131
|
+
await activateAgentCommand(id, opts);
|
|
132
|
+
});
|
|
133
|
+
// suzi agents deactivate [id]
|
|
134
|
+
agent
|
|
135
|
+
.command('deactivate [id]')
|
|
136
|
+
.description('Deactivate an agent (stops execution)')
|
|
137
|
+
.option('-f, --force', 'Skip confirmation')
|
|
138
|
+
.option('--json', 'Output as JSON')
|
|
139
|
+
.action(async (id, opts) => {
|
|
140
|
+
await deactivateAgentCommand(id, opts);
|
|
141
|
+
});
|
|
142
|
+
// suzi agents execute [id]
|
|
143
|
+
agent
|
|
144
|
+
.command('execute [id] [trigger]')
|
|
145
|
+
.description('Manually execute an agent trigger')
|
|
146
|
+
.option('--json', 'Output as JSON')
|
|
147
|
+
.action(async (id, trigger, opts) => {
|
|
148
|
+
await executeAgentCommand(id, trigger, opts);
|
|
149
|
+
});
|
|
150
|
+
// suzi agents logs [id]
|
|
151
|
+
agent
|
|
152
|
+
.command('logs [id]')
|
|
153
|
+
.description('View agent logs')
|
|
154
|
+
.option('-n, --limit <n>', 'Number of log entries', '20')
|
|
155
|
+
.option('--level <level>', 'Filter by level (info|warn|error|debug)')
|
|
156
|
+
.option('--json', 'Output as JSON')
|
|
157
|
+
.action(async (id, opts) => {
|
|
158
|
+
await logsAgentCommand(id, opts);
|
|
159
|
+
});
|
|
160
|
+
// suzi agents code [id]
|
|
161
|
+
agent
|
|
162
|
+
.command('code [id]')
|
|
163
|
+
.description('View agent source code')
|
|
164
|
+
.option('--json', 'Output as JSON')
|
|
165
|
+
.action(async (id, opts) => {
|
|
166
|
+
await codeAgentCommand(id, opts);
|
|
167
|
+
});
|
|
168
|
+
// suzi agents delete [id]
|
|
169
|
+
agent
|
|
170
|
+
.command('delete [id]')
|
|
171
|
+
.description('Delete an agent')
|
|
172
|
+
.option('-f, --force', 'Skip confirmation')
|
|
173
|
+
.option('--json', 'Output as JSON')
|
|
174
|
+
.action(async (id, opts) => {
|
|
175
|
+
await deleteAgentCommand(id, opts);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
// ============================================================================
|
|
179
|
+
// Command Implementations
|
|
180
|
+
// ============================================================================
|
|
181
|
+
async function listAgentsCommand(opts) {
|
|
182
|
+
if (!(0, ui_1.requireAuth)())
|
|
183
|
+
return;
|
|
184
|
+
const jsonMode = opts?.json || false;
|
|
185
|
+
const spinner = (0, tty_1.createSpinner)('Loading agents...', jsonMode);
|
|
186
|
+
spinner?.start();
|
|
187
|
+
const resp = await (0, api_1.get)('/api/agent?limit=50');
|
|
188
|
+
if (!resp.ok) {
|
|
189
|
+
spinner?.fail();
|
|
190
|
+
const msg = `Failed to load agents: ${resp.data?.error || 'Unknown error'}`;
|
|
191
|
+
if (jsonMode) {
|
|
192
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
193
|
+
}
|
|
194
|
+
else {
|
|
195
|
+
(0, ui_1.error)(msg);
|
|
196
|
+
}
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
spinner?.stop();
|
|
200
|
+
const agentList = resp.data.agents || [];
|
|
201
|
+
if (jsonMode) {
|
|
202
|
+
(0, tty_1.outputJson)({ success: true, data: { agents: agentList, count: agentList.length } });
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
if (agentList.length === 0) {
|
|
206
|
+
(0, ui_1.header)('Agents');
|
|
207
|
+
console.log();
|
|
208
|
+
(0, ui_1.info)('No agents found. Create one with `suzi agents deploy <file>`.');
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
(0, ui_1.header)(`Agents (${agentList.length})`);
|
|
212
|
+
console.log();
|
|
213
|
+
const table = new cli_table3_1.default({
|
|
214
|
+
head: [
|
|
215
|
+
chalk_1.default.gray('#'),
|
|
216
|
+
chalk_1.default.gray('Name'),
|
|
217
|
+
chalk_1.default.gray('Status'),
|
|
218
|
+
chalk_1.default.gray('ID'),
|
|
219
|
+
chalk_1.default.gray('Created'),
|
|
220
|
+
],
|
|
221
|
+
style: { head: [], border: ['gray'] },
|
|
222
|
+
});
|
|
223
|
+
for (let i = 0; i < agentList.length; i++) {
|
|
224
|
+
const agent = agentList[i];
|
|
225
|
+
table.push([
|
|
226
|
+
ui_1.colors.muted(String(i + 1)),
|
|
227
|
+
chalk_1.default.bold(agent.title || 'Untitled'),
|
|
228
|
+
(0, ui_1.statusBadge)(agent.status),
|
|
229
|
+
agent.id,
|
|
230
|
+
ui_1.colors.muted(new Date(agent.createdAt).toLocaleDateString()),
|
|
231
|
+
]);
|
|
232
|
+
}
|
|
233
|
+
console.log(table.toString());
|
|
234
|
+
}
|
|
235
|
+
async function viewAgentCommand(idOrName, opts) {
|
|
236
|
+
if (!(0, ui_1.requireAuth)())
|
|
237
|
+
return;
|
|
238
|
+
const jsonMode = opts?.json || false;
|
|
239
|
+
const agent = await (0, agent_picker_1.fetchAndPickAgent)(idOrName, jsonMode);
|
|
240
|
+
if (!agent)
|
|
241
|
+
return;
|
|
242
|
+
// Fetch full details
|
|
243
|
+
const spinner = (0, tty_1.createSpinner)('Loading agent details...', jsonMode);
|
|
244
|
+
spinner?.start();
|
|
245
|
+
const resp = await (0, api_1.get)(`/api/agent/${agent.id}`);
|
|
246
|
+
if (!resp.ok) {
|
|
247
|
+
spinner?.fail();
|
|
248
|
+
const msg = `Failed to load agent: ${resp.data?.error || 'Unknown error'}`;
|
|
249
|
+
if (jsonMode) {
|
|
250
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
(0, ui_1.error)(msg);
|
|
254
|
+
}
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
spinner?.stop();
|
|
258
|
+
const fullAgent = resp.data;
|
|
259
|
+
// Fetch resources
|
|
260
|
+
const resResp = await (0, api_1.get)(`/api/agent/${agent.id}/resources`);
|
|
261
|
+
const resources = resResp.ok ? resResp.data?.resources || [] : [];
|
|
262
|
+
if (jsonMode) {
|
|
263
|
+
(0, tty_1.outputJson)({ success: true, data: { agent: fullAgent, resources } });
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
// Pretty output
|
|
267
|
+
(0, ui_1.header)(fullAgent.title || 'Untitled Agent');
|
|
268
|
+
console.log();
|
|
269
|
+
(0, ui_1.label)('ID', fullAgent.id);
|
|
270
|
+
(0, ui_1.label)('Status', (0, ui_1.statusBadge)(fullAgent.status));
|
|
271
|
+
(0, ui_1.label)('Description', fullAgent.description || ui_1.colors.muted('None'));
|
|
272
|
+
(0, ui_1.label)('Created', new Date(fullAgent.createdAt).toLocaleString());
|
|
273
|
+
(0, ui_1.label)('Updated', new Date(fullAgent.updatedAt).toLocaleString());
|
|
274
|
+
// Show spec info
|
|
275
|
+
if (fullAgent.spec) {
|
|
276
|
+
const spec = (0, ui_1.safeParseJSON)(fullAgent.spec);
|
|
277
|
+
console.log();
|
|
278
|
+
console.log(ui_1.colors.muted(' Agent Spec:'));
|
|
279
|
+
if (spec.meta) {
|
|
280
|
+
(0, ui_1.label)(' Version', spec.meta.version || 'N/A');
|
|
281
|
+
}
|
|
282
|
+
if (spec.triggers) {
|
|
283
|
+
const triggerNames = Object.keys(spec.triggers);
|
|
284
|
+
(0, ui_1.label)(' Triggers', triggerNames.join(', ') || 'None');
|
|
285
|
+
}
|
|
286
|
+
if (spec.resources) {
|
|
287
|
+
const resourceTypes = Object.entries(spec.resources)
|
|
288
|
+
.map(([key, val]) => {
|
|
289
|
+
const type = typeof val === 'string' ? val : (val?.type || 'unknown');
|
|
290
|
+
return `${key}(${type})`;
|
|
291
|
+
})
|
|
292
|
+
.join(', ');
|
|
293
|
+
(0, ui_1.label)(' Resources', resourceTypes || 'None');
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
// Show resources
|
|
297
|
+
if (resources.length > 0) {
|
|
298
|
+
console.log();
|
|
299
|
+
console.log(ui_1.colors.muted(' Wallet Resources:'));
|
|
300
|
+
for (const res of resources) {
|
|
301
|
+
(0, ui_1.label)(` ${res.walletType.toUpperCase()}`, res.address || 'N/A');
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
console.log();
|
|
305
|
+
(0, ui_1.divider)();
|
|
306
|
+
}
|
|
307
|
+
async function deployAgentCommand(file, opts) {
|
|
308
|
+
if (!(0, ui_1.requireAuth)())
|
|
309
|
+
return;
|
|
310
|
+
const jsonMode = opts?.json || false;
|
|
311
|
+
// Find the agent file
|
|
312
|
+
let filePath = file;
|
|
313
|
+
if (!filePath) {
|
|
314
|
+
// Look for common agent file patterns in current directory
|
|
315
|
+
const candidates = [
|
|
316
|
+
'agent.ts',
|
|
317
|
+
'src/agent.ts',
|
|
318
|
+
'index.ts',
|
|
319
|
+
'src/index.ts',
|
|
320
|
+
];
|
|
321
|
+
for (const candidate of candidates) {
|
|
322
|
+
const resolved = path_1.default.resolve(process.cwd(), candidate);
|
|
323
|
+
if (fs_1.default.existsSync(resolved)) {
|
|
324
|
+
filePath = resolved;
|
|
325
|
+
break;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
if (!filePath) {
|
|
329
|
+
const msg = 'No agent file found. Specify a file path.';
|
|
330
|
+
if (jsonMode) {
|
|
331
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
332
|
+
}
|
|
333
|
+
else {
|
|
334
|
+
(0, ui_1.error)(msg);
|
|
335
|
+
(0, ui_1.info)('Looked for: ' + candidates.join(', '));
|
|
336
|
+
}
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
const resolvedPath = path_1.default.resolve(process.cwd(), filePath);
|
|
341
|
+
if (!fs_1.default.existsSync(resolvedPath)) {
|
|
342
|
+
const msg = `File not found: ${resolvedPath}`;
|
|
343
|
+
if (jsonMode) {
|
|
344
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
(0, ui_1.error)(msg);
|
|
348
|
+
}
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
const source = fs_1.default.readFileSync(resolvedPath, 'utf-8');
|
|
352
|
+
if (!source.includes('defineAgent')) {
|
|
353
|
+
const msg = 'File does not appear to be a Suzi agent (missing defineAgent).';
|
|
354
|
+
if (jsonMode) {
|
|
355
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
(0, ui_1.error)(msg);
|
|
359
|
+
(0, ui_1.info)('Agent files must export `defineAgent({...})`.');
|
|
360
|
+
}
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
if (!jsonMode) {
|
|
364
|
+
(0, ui_1.header)('Deploy Agent');
|
|
365
|
+
console.log();
|
|
366
|
+
(0, ui_1.label)('File', path_1.default.relative(process.cwd(), resolvedPath));
|
|
367
|
+
(0, ui_1.label)('Size', `${source.length} bytes`);
|
|
368
|
+
console.log();
|
|
369
|
+
}
|
|
370
|
+
// Determine title
|
|
371
|
+
let title = opts?.title;
|
|
372
|
+
if (!title && !opts?.update && !jsonMode && (0, tty_1.shouldUseInteractive)()) {
|
|
373
|
+
// Try to extract from source
|
|
374
|
+
const metaMatch = source.match(/name:\s*['"]([^'"]+)['"]/);
|
|
375
|
+
if (metaMatch) {
|
|
376
|
+
title = metaMatch[1];
|
|
377
|
+
}
|
|
378
|
+
else {
|
|
379
|
+
const answers = await inquirer_1.default.prompt([
|
|
380
|
+
{
|
|
381
|
+
type: 'input',
|
|
382
|
+
name: 'title',
|
|
383
|
+
message: 'Agent title:',
|
|
384
|
+
default: path_1.default.basename(resolvedPath, path_1.default.extname(resolvedPath)),
|
|
385
|
+
},
|
|
386
|
+
]);
|
|
387
|
+
title = answers.title;
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const spinner = (0, tty_1.createSpinner)('Deploying agent...', jsonMode);
|
|
391
|
+
spinner?.start();
|
|
392
|
+
try {
|
|
393
|
+
let resp;
|
|
394
|
+
if (opts?.update) {
|
|
395
|
+
// Update existing agent
|
|
396
|
+
if (spinner)
|
|
397
|
+
spinner.text = 'Updating agent...';
|
|
398
|
+
resp = await (0, api_1.put)(`/api/agent/${opts.update}`, {
|
|
399
|
+
code: source,
|
|
400
|
+
...(title ? { title } : {}),
|
|
401
|
+
...(opts?.description ? { description: opts.description } : {}),
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
else {
|
|
405
|
+
// Create new agent
|
|
406
|
+
if (spinner)
|
|
407
|
+
spinner.text = 'Creating agent...';
|
|
408
|
+
resp = await (0, api_1.post)('/api/agent', {
|
|
409
|
+
code: source,
|
|
410
|
+
title: title || 'CLI Agent',
|
|
411
|
+
...(opts?.description ? { description: opts.description } : {}),
|
|
412
|
+
});
|
|
413
|
+
}
|
|
414
|
+
if (!resp.ok) {
|
|
415
|
+
spinner?.fail();
|
|
416
|
+
const errorMsg = resp.data?.error || resp.data?.message || 'Unknown error';
|
|
417
|
+
const details = resp.data?.details;
|
|
418
|
+
if (jsonMode) {
|
|
419
|
+
(0, tty_1.outputJson)({ success: false, error: errorMsg, data: { details } });
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
(0, ui_1.error)(`Deploy failed: ${errorMsg}`);
|
|
423
|
+
if (details) {
|
|
424
|
+
console.log(ui_1.colors.muted(` ${details}`));
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
(0, memory_1.appendLearning)({ category: 'error', message: `Deploy failed: ${errorMsg}`, command: 'agent deploy' });
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const agentData = resp.data;
|
|
431
|
+
// Activate if requested
|
|
432
|
+
if (opts?.activate) {
|
|
433
|
+
if (spinner)
|
|
434
|
+
spinner.text = 'Activating agent...';
|
|
435
|
+
const activateResp = await (0, api_1.post)(`/api/agent/${agentData.id}/activate`);
|
|
436
|
+
if (activateResp.ok) {
|
|
437
|
+
agentData.status = 'active';
|
|
438
|
+
}
|
|
439
|
+
else {
|
|
440
|
+
const activateError = activateResp.data?.error || activateResp.data?.message || 'Unknown error';
|
|
441
|
+
if (jsonMode) {
|
|
442
|
+
(0, tty_1.outputJson)({ success: true, data: { agent: agentData, activationError: activateError } });
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
spinner?.warn(`Agent deployed but activation failed: ${activateError}`);
|
|
446
|
+
}
|
|
447
|
+
(0, memory_1.appendLearning)({ category: 'error', message: `Post-deploy activation failed: ${activateError}`, command: 'agent deploy --activate', agentId: agentData.id });
|
|
448
|
+
return;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
spinner?.succeed(opts?.update ? 'Agent updated!' : 'Agent created!');
|
|
452
|
+
if (jsonMode) {
|
|
453
|
+
(0, tty_1.outputJson)({ success: true, data: { agent: agentData } });
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
console.log();
|
|
457
|
+
(0, ui_1.label)('Agent ID', agentData.id);
|
|
458
|
+
(0, ui_1.label)('Title', agentData.title || 'Untitled');
|
|
459
|
+
(0, ui_1.label)('Status', (0, ui_1.statusBadge)(agentData.status));
|
|
460
|
+
if (agentData.spec) {
|
|
461
|
+
const spec = (0, ui_1.safeParseJSON)(agentData.spec);
|
|
462
|
+
if (spec.triggers) {
|
|
463
|
+
(0, ui_1.label)('Triggers', Object.keys(spec.triggers).join(', '));
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
// Show action validation warnings
|
|
467
|
+
if (agentData.actionValidation?.issues?.length > 0) {
|
|
468
|
+
console.log();
|
|
469
|
+
(0, ui_1.warn)('Action validation issues:');
|
|
470
|
+
for (const issue of agentData.actionValidation.issues) {
|
|
471
|
+
if (issue.type === 'unknown_protocol') {
|
|
472
|
+
console.log(` ${ui_1.colors.warning('⚠')} Unknown protocol: ${chalk_1.default.bold(issue.protocol)} ${ui_1.colors.muted(`(line ${issue.line})`)}`);
|
|
473
|
+
}
|
|
474
|
+
else if (issue.type === 'unknown_action') {
|
|
475
|
+
console.log(` ${ui_1.colors.warning('⚠')} Unknown action: ${chalk_1.default.bold(issue.protocol + '.' + issue.action)} ${ui_1.colors.muted(`(line ${issue.line})`)}`);
|
|
476
|
+
}
|
|
477
|
+
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
478
|
+
console.log(` ${ui_1.colors.muted('Did you mean:')} ${issue.suggestions.join(', ')}`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
console.log();
|
|
482
|
+
(0, ui_1.info)('Run `suzi agents validate` for detailed validation.');
|
|
483
|
+
}
|
|
484
|
+
console.log();
|
|
485
|
+
(0, ui_1.divider)();
|
|
486
|
+
if (agentData.status === 'draft') {
|
|
487
|
+
(0, ui_1.info)('Activate with: `suzi agents activate ' + agentData.id + '`');
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
catch (err) {
|
|
491
|
+
spinner?.fail();
|
|
492
|
+
const msg = `Deploy error: ${err.message}`;
|
|
493
|
+
if (jsonMode) {
|
|
494
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
495
|
+
}
|
|
496
|
+
else {
|
|
497
|
+
(0, ui_1.error)(msg);
|
|
498
|
+
}
|
|
499
|
+
(0, memory_1.appendLearning)({ category: 'error', message: msg, command: 'agent deploy' });
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
async function validateAgentCommand(file, opts) {
|
|
503
|
+
if (!(0, ui_1.requireAuth)())
|
|
504
|
+
return;
|
|
505
|
+
const jsonMode = opts?.json || false;
|
|
506
|
+
// Resolve file path
|
|
507
|
+
let filePath = file;
|
|
508
|
+
if (!filePath && !jsonMode && (0, tty_1.shouldUseInteractive)()) {
|
|
509
|
+
const cwd = process.cwd();
|
|
510
|
+
const scanDirs = [cwd, path_1.default.join(cwd, 'src')];
|
|
511
|
+
const agentFiles = [];
|
|
512
|
+
for (const dir of scanDirs) {
|
|
513
|
+
if (!fs_1.default.existsSync(dir))
|
|
514
|
+
continue;
|
|
515
|
+
for (const entry of fs_1.default.readdirSync(dir)) {
|
|
516
|
+
if (!entry.endsWith('.ts'))
|
|
517
|
+
continue;
|
|
518
|
+
const full = path_1.default.join(dir, entry);
|
|
519
|
+
try {
|
|
520
|
+
const content = fs_1.default.readFileSync(full, 'utf-8');
|
|
521
|
+
if (content.includes('defineAgent')) {
|
|
522
|
+
agentFiles.push(full);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
catch {
|
|
526
|
+
// skip unreadable files
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (agentFiles.length === 0) {
|
|
531
|
+
(0, ui_1.error)('No agent files found in current directory.');
|
|
532
|
+
(0, ui_1.info)('Create a .ts file with `defineAgent({...})` or specify a path.');
|
|
533
|
+
return;
|
|
534
|
+
}
|
|
535
|
+
if (agentFiles.length === 1) {
|
|
536
|
+
filePath = agentFiles[0];
|
|
537
|
+
}
|
|
538
|
+
else {
|
|
539
|
+
const { selected } = await inquirer_1.default.prompt([
|
|
540
|
+
{
|
|
541
|
+
type: 'list',
|
|
542
|
+
name: 'selected',
|
|
543
|
+
message: 'Select an agent file to validate:',
|
|
544
|
+
choices: agentFiles.map(f => ({
|
|
545
|
+
name: path_1.default.relative(cwd, f),
|
|
546
|
+
value: f,
|
|
547
|
+
})),
|
|
548
|
+
},
|
|
549
|
+
]);
|
|
550
|
+
filePath = selected;
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
if (!filePath) {
|
|
554
|
+
const msg = 'File path required in non-interactive mode.';
|
|
555
|
+
if (jsonMode) {
|
|
556
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
557
|
+
}
|
|
558
|
+
else {
|
|
559
|
+
(0, ui_1.error)(msg);
|
|
560
|
+
}
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
const resolvedPath = path_1.default.resolve(process.cwd(), filePath);
|
|
564
|
+
if (!fs_1.default.existsSync(resolvedPath)) {
|
|
565
|
+
const msg = `File not found: ${resolvedPath}`;
|
|
566
|
+
if (jsonMode) {
|
|
567
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
568
|
+
}
|
|
569
|
+
else {
|
|
570
|
+
(0, ui_1.error)(msg);
|
|
571
|
+
}
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
const source = fs_1.default.readFileSync(resolvedPath, 'utf-8');
|
|
575
|
+
if (!source.includes('defineAgent')) {
|
|
576
|
+
const msg = 'File does not appear to be a Suzi agent (missing defineAgent).';
|
|
577
|
+
if (jsonMode) {
|
|
578
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
579
|
+
}
|
|
580
|
+
else {
|
|
581
|
+
(0, ui_1.error)(msg);
|
|
582
|
+
(0, ui_1.info)('Agent files must export `defineAgent({...})`.');
|
|
583
|
+
}
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
if (!jsonMode) {
|
|
587
|
+
(0, ui_1.header)('Validate Agent');
|
|
588
|
+
console.log();
|
|
589
|
+
(0, ui_1.label)('File', path_1.default.relative(process.cwd(), resolvedPath));
|
|
590
|
+
(0, ui_1.label)('Size', `${Buffer.byteLength(source, 'utf8')} bytes`);
|
|
591
|
+
console.log();
|
|
592
|
+
}
|
|
593
|
+
const spinner = (0, tty_1.createSpinner)('Validating agent...', jsonMode);
|
|
594
|
+
spinner?.start();
|
|
595
|
+
try {
|
|
596
|
+
const resp = await (0, api_1.post)('/api/agent/validate', { code: source });
|
|
597
|
+
if (!resp.ok) {
|
|
598
|
+
spinner?.fail();
|
|
599
|
+
const errorData = resp.data;
|
|
600
|
+
const msg = errorData?.message || 'Compilation error';
|
|
601
|
+
const details = errorData?.details;
|
|
602
|
+
if (jsonMode) {
|
|
603
|
+
(0, tty_1.outputJson)({ success: false, error: msg, data: { details } });
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
(0, ui_1.error)(msg);
|
|
607
|
+
if (details) {
|
|
608
|
+
console.log(ui_1.colors.muted(` ${details}`));
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
const data = resp.data;
|
|
614
|
+
if (jsonMode) {
|
|
615
|
+
(0, tty_1.outputJson)({ success: true, data });
|
|
616
|
+
return;
|
|
617
|
+
}
|
|
618
|
+
if (data.valid) {
|
|
619
|
+
spinner?.succeed('Agent is valid!');
|
|
620
|
+
}
|
|
621
|
+
else {
|
|
622
|
+
spinner?.fail('Validation issues found');
|
|
623
|
+
process.exitCode = 1;
|
|
624
|
+
}
|
|
625
|
+
console.log();
|
|
626
|
+
// Show spec summary
|
|
627
|
+
if (data.spec) {
|
|
628
|
+
if (data.spec.meta?.name) {
|
|
629
|
+
(0, ui_1.label)('Name', data.spec.meta.name);
|
|
630
|
+
}
|
|
631
|
+
(0, ui_1.label)('Triggers', Object.keys(data.spec.triggers || {}).join(', ') || 'none');
|
|
632
|
+
if (data.spec.resources) {
|
|
633
|
+
(0, ui_1.label)('Resources', Object.keys(data.spec.resources).join(', '));
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
// Show valid action references
|
|
637
|
+
const refs = data.actions?.references || [];
|
|
638
|
+
const issues = data.actions?.issues || [];
|
|
639
|
+
const issueKeys = new Set(issues.flatMap((i) => {
|
|
640
|
+
const keys = [`${i.protocol}.${i.action || ''}`];
|
|
641
|
+
if (i.type === 'unknown_protocol') {
|
|
642
|
+
keys.push(i.protocol);
|
|
643
|
+
}
|
|
644
|
+
return keys;
|
|
645
|
+
}));
|
|
646
|
+
if (refs.length > 0) {
|
|
647
|
+
console.log();
|
|
648
|
+
console.log(ui_1.colors.highlight(' Actions used:'));
|
|
649
|
+
for (const ref of refs) {
|
|
650
|
+
const key = `${ref.protocol}.${ref.action}`;
|
|
651
|
+
if (!issueKeys.has(key) && !issueKeys.has(ref.protocol)) {
|
|
652
|
+
console.log(` ${ui_1.colors.success('✓')} ${key} ${ui_1.colors.muted(`(line ${ref.line})`)}`);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
// Show issues
|
|
657
|
+
if (issues.length > 0) {
|
|
658
|
+
console.log();
|
|
659
|
+
console.log(ui_1.colors.error(' Issues:'));
|
|
660
|
+
for (const issue of issues) {
|
|
661
|
+
if (issue.type === 'unknown_protocol') {
|
|
662
|
+
console.log(` ${ui_1.colors.error('✕')} Unknown protocol: ${ui_1.colors.highlight(issue.protocol)} ${ui_1.colors.muted(`(line ${issue.line})`)}`);
|
|
663
|
+
}
|
|
664
|
+
else if (issue.type === 'unknown_action') {
|
|
665
|
+
console.log(` ${ui_1.colors.error('✕')} Unknown action: ${ui_1.colors.highlight(issue.protocol + '.' + issue.action)} ${ui_1.colors.muted(`(line ${issue.line})`)}`);
|
|
666
|
+
}
|
|
667
|
+
if (issue.suggestions && issue.suggestions.length > 0) {
|
|
668
|
+
console.log(` ${ui_1.colors.muted('Did you mean:')} ${issue.suggestions.join(', ')}`);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
console.log();
|
|
673
|
+
(0, ui_1.divider)();
|
|
674
|
+
if (data.valid) {
|
|
675
|
+
(0, ui_1.info)('Ready to deploy: `suzi agents deploy ' + path_1.default.relative(process.cwd(), resolvedPath) + '`');
|
|
676
|
+
}
|
|
677
|
+
else {
|
|
678
|
+
(0, ui_1.warn)('Fix the issues above before deploying.');
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
catch (err) {
|
|
682
|
+
spinner?.fail();
|
|
683
|
+
const msg = `Validation error: ${err.message}`;
|
|
684
|
+
if (jsonMode) {
|
|
685
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
686
|
+
}
|
|
687
|
+
else {
|
|
688
|
+
(0, ui_1.error)(msg);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
}
|
|
692
|
+
async function activateAgentCommand(idOrName, opts) {
|
|
693
|
+
if (!(0, ui_1.requireAuth)())
|
|
694
|
+
return;
|
|
695
|
+
const jsonMode = opts?.json || false;
|
|
696
|
+
const agent = await (0, agent_picker_1.fetchAndPickAgent)(idOrName, jsonMode);
|
|
697
|
+
if (!agent)
|
|
698
|
+
return;
|
|
699
|
+
const spinner = (0, tty_1.createSpinner)('Activating agent...', jsonMode);
|
|
700
|
+
spinner?.start();
|
|
701
|
+
const resp = await (0, api_1.post)(`/api/agent/${agent.id}/activate`);
|
|
702
|
+
if (!resp.ok) {
|
|
703
|
+
spinner?.fail();
|
|
704
|
+
const errorMsg = resp.data?.error || resp.data?.message || 'Unknown error';
|
|
705
|
+
if (jsonMode) {
|
|
706
|
+
(0, tty_1.outputJson)({ success: false, error: errorMsg });
|
|
707
|
+
}
|
|
708
|
+
else {
|
|
709
|
+
(0, ui_1.error)(`Failed to activate: ${errorMsg}`);
|
|
710
|
+
}
|
|
711
|
+
(0, memory_1.appendLearning)({ category: 'error', message: `Activate failed: ${errorMsg}`, command: 'agent activate', agentId: agent.id });
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
spinner?.succeed();
|
|
715
|
+
if (jsonMode) {
|
|
716
|
+
(0, tty_1.outputJson)({ success: true, data: { agentId: agent.id, status: 'active' } });
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
(0, ui_1.success)(`Agent ${agent.id.slice(0, 8)}... activated.`);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
async function deactivateAgentCommand(idOrName, opts) {
|
|
723
|
+
if (!(0, ui_1.requireAuth)())
|
|
724
|
+
return;
|
|
725
|
+
const jsonMode = opts?.json || false;
|
|
726
|
+
const agent = await (0, agent_picker_1.fetchAndPickAgent)(idOrName, jsonMode);
|
|
727
|
+
if (!agent)
|
|
728
|
+
return;
|
|
729
|
+
// Confirmation prompt for destructive action
|
|
730
|
+
if (!opts?.force && !jsonMode && (0, tty_1.shouldUseInteractive)()) {
|
|
731
|
+
const answers = await inquirer_1.default.prompt([
|
|
732
|
+
{
|
|
733
|
+
type: 'confirm',
|
|
734
|
+
name: 'confirm',
|
|
735
|
+
message: `Deactivate "${agent.title || 'Untitled'}"? This will stop all triggers and scheduled executions.`,
|
|
736
|
+
default: false,
|
|
737
|
+
},
|
|
738
|
+
]);
|
|
739
|
+
if (!answers.confirm) {
|
|
740
|
+
(0, ui_1.info)('Cancelled.');
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
const spinner = (0, tty_1.createSpinner)('Deactivating agent...', jsonMode);
|
|
745
|
+
spinner?.start();
|
|
746
|
+
const resp = await (0, api_1.post)(`/api/agent/${agent.id}/deactivate`);
|
|
747
|
+
if (!resp.ok) {
|
|
748
|
+
spinner?.fail();
|
|
749
|
+
const errorMsg = resp.data?.error || resp.data?.message || 'Unknown error';
|
|
750
|
+
if (jsonMode) {
|
|
751
|
+
(0, tty_1.outputJson)({ success: false, error: errorMsg });
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
(0, ui_1.error)(`Failed to deactivate: ${errorMsg}`);
|
|
755
|
+
}
|
|
756
|
+
(0, memory_1.appendLearning)({ category: 'error', message: `Deactivate failed: ${errorMsg}`, command: 'agent deactivate', agentId: agent.id });
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
759
|
+
spinner?.succeed();
|
|
760
|
+
if (jsonMode) {
|
|
761
|
+
(0, tty_1.outputJson)({ success: true, data: { agentId: agent.id, status: 'inactive' } });
|
|
762
|
+
}
|
|
763
|
+
else {
|
|
764
|
+
(0, ui_1.success)(`Agent ${agent.id.slice(0, 8)}... deactivated.`);
|
|
765
|
+
}
|
|
766
|
+
}
|
|
767
|
+
async function executeAgentCommand(idOrName, trigger, opts) {
|
|
768
|
+
if (!(0, ui_1.requireAuth)())
|
|
769
|
+
return;
|
|
770
|
+
const jsonMode = opts?.json || false;
|
|
771
|
+
const agent = await (0, agent_picker_1.fetchAndPickAgent)(idOrName, jsonMode);
|
|
772
|
+
if (!agent)
|
|
773
|
+
return;
|
|
774
|
+
// If no trigger specified, fetch agent to find manual triggers
|
|
775
|
+
let triggerName = trigger;
|
|
776
|
+
if (!triggerName) {
|
|
777
|
+
const agentResp = await (0, api_1.get)(`/api/agent/${agent.id}`);
|
|
778
|
+
if (agentResp.ok && agentResp.data?.spec) {
|
|
779
|
+
const spec = (0, ui_1.safeParseJSON)(agentResp.data.spec);
|
|
780
|
+
const triggers = Object.keys(spec.triggers || {});
|
|
781
|
+
if (triggers.length === 0) {
|
|
782
|
+
const msg = 'No triggers found on this agent.';
|
|
783
|
+
if (jsonMode) {
|
|
784
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
785
|
+
}
|
|
786
|
+
else {
|
|
787
|
+
(0, ui_1.error)(msg);
|
|
788
|
+
}
|
|
789
|
+
return;
|
|
790
|
+
}
|
|
791
|
+
if (triggers.length === 1) {
|
|
792
|
+
triggerName = triggers[0];
|
|
793
|
+
}
|
|
794
|
+
else if (!jsonMode && (0, tty_1.shouldUseInteractive)()) {
|
|
795
|
+
const answers = await inquirer_1.default.prompt([
|
|
796
|
+
{
|
|
797
|
+
type: 'list',
|
|
798
|
+
name: 'trigger',
|
|
799
|
+
message: 'Select a trigger to execute:',
|
|
800
|
+
choices: triggers,
|
|
801
|
+
},
|
|
802
|
+
]);
|
|
803
|
+
triggerName = answers.trigger;
|
|
804
|
+
}
|
|
805
|
+
else {
|
|
806
|
+
const msg = 'Multiple triggers available. Specify trigger name.';
|
|
807
|
+
if (jsonMode) {
|
|
808
|
+
(0, tty_1.outputJson)({ success: false, error: msg, data: { triggers } });
|
|
809
|
+
}
|
|
810
|
+
else {
|
|
811
|
+
(0, ui_1.error)(msg);
|
|
812
|
+
(0, ui_1.info)('Available triggers: ' + triggers.join(', '));
|
|
813
|
+
}
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
else {
|
|
818
|
+
const msg = 'Could not fetch agent spec.';
|
|
819
|
+
if (jsonMode) {
|
|
820
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
821
|
+
}
|
|
822
|
+
else {
|
|
823
|
+
(0, ui_1.error)(msg + ' Specify trigger name explicitly.');
|
|
824
|
+
}
|
|
825
|
+
return;
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
const spinner = (0, tty_1.createSpinner)(`Executing trigger "${triggerName}"...`, jsonMode);
|
|
829
|
+
spinner?.start();
|
|
830
|
+
const resp = await (0, api_1.post)(`/api/agent/${agent.id}/execute`, {
|
|
831
|
+
triggerName: triggerName,
|
|
832
|
+
});
|
|
833
|
+
if (!resp.ok) {
|
|
834
|
+
spinner?.fail();
|
|
835
|
+
const errorMsg = resp.data?.error || resp.data?.message || 'Unknown error';
|
|
836
|
+
if (jsonMode) {
|
|
837
|
+
(0, tty_1.outputJson)({ success: false, error: errorMsg });
|
|
838
|
+
}
|
|
839
|
+
else {
|
|
840
|
+
(0, ui_1.error)(`Execution failed: ${errorMsg}`);
|
|
841
|
+
}
|
|
842
|
+
(0, memory_1.appendLearning)({ category: 'error', message: `Execution failed: ${errorMsg}`, command: 'agent execute', agentId: agent.id });
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
845
|
+
spinner?.succeed();
|
|
846
|
+
if (jsonMode) {
|
|
847
|
+
(0, tty_1.outputJson)({ success: true, data: { executionId: resp.data.executionId } });
|
|
848
|
+
}
|
|
849
|
+
else {
|
|
850
|
+
(0, ui_1.success)(`Execution started. Run ID: ${resp.data.executionId || 'N/A'}`);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
async function logsAgentCommand(idOrName, opts) {
|
|
854
|
+
if (!(0, ui_1.requireAuth)())
|
|
855
|
+
return;
|
|
856
|
+
const jsonMode = opts?.json || false;
|
|
857
|
+
const agent = await (0, agent_picker_1.fetchAndPickAgent)(idOrName, jsonMode);
|
|
858
|
+
if (!agent)
|
|
859
|
+
return;
|
|
860
|
+
const spinner = (0, tty_1.createSpinner)('Loading logs...', jsonMode);
|
|
861
|
+
spinner?.start();
|
|
862
|
+
let path = `/api/agent/${agent.id}/logs?limit=${opts?.limit || 20}`;
|
|
863
|
+
if (opts?.level)
|
|
864
|
+
path += `&level=${opts.level}`;
|
|
865
|
+
const resp = await (0, api_1.get)(path);
|
|
866
|
+
if (!resp.ok) {
|
|
867
|
+
spinner?.fail();
|
|
868
|
+
const msg = `Failed to load logs: ${resp.data?.error || 'Unknown error'}`;
|
|
869
|
+
if (jsonMode) {
|
|
870
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
871
|
+
}
|
|
872
|
+
else {
|
|
873
|
+
(0, ui_1.error)(msg);
|
|
874
|
+
}
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
spinner?.stop();
|
|
878
|
+
const logs = resp.data.logs || [];
|
|
879
|
+
if (jsonMode) {
|
|
880
|
+
(0, tty_1.outputJson)({ success: true, data: { logs, count: logs.length } });
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
if (logs.length === 0) {
|
|
884
|
+
(0, ui_1.info)('No logs found.');
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
(0, ui_1.header)(`Agent Logs (${logs.length})`);
|
|
888
|
+
console.log();
|
|
889
|
+
for (const log of logs) {
|
|
890
|
+
const levelColor = log.level === 'error'
|
|
891
|
+
? chalk_1.default.red
|
|
892
|
+
: log.level === 'warn'
|
|
893
|
+
? chalk_1.default.yellow
|
|
894
|
+
: log.level === 'debug'
|
|
895
|
+
? chalk_1.default.gray
|
|
896
|
+
: chalk_1.default.white;
|
|
897
|
+
const ts = new Date(log.createdAt).toLocaleTimeString();
|
|
898
|
+
console.log(` ${ui_1.colors.muted(ts)} ${levelColor(`[${log.level}]`)} ${log.log}`);
|
|
899
|
+
}
|
|
900
|
+
}
|
|
901
|
+
async function codeAgentCommand(idOrName, opts) {
|
|
902
|
+
if (!(0, ui_1.requireAuth)())
|
|
903
|
+
return;
|
|
904
|
+
const jsonMode = opts?.json || false;
|
|
905
|
+
const agent = await (0, agent_picker_1.fetchAndPickAgent)(idOrName, jsonMode);
|
|
906
|
+
if (!agent)
|
|
907
|
+
return;
|
|
908
|
+
const spinner = (0, tty_1.createSpinner)('Loading agent code...', jsonMode);
|
|
909
|
+
spinner?.start();
|
|
910
|
+
const resp = await (0, api_1.get)(`/api/agent/${agent.id}`);
|
|
911
|
+
if (!resp.ok) {
|
|
912
|
+
spinner?.fail();
|
|
913
|
+
const msg = `Agent not found: ${resp.data?.error || resp.data?.message || 'Unknown error'}`;
|
|
914
|
+
if (jsonMode) {
|
|
915
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
916
|
+
}
|
|
917
|
+
else {
|
|
918
|
+
(0, ui_1.error)(msg);
|
|
919
|
+
}
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
spinner?.stop();
|
|
923
|
+
const agentData = resp.data;
|
|
924
|
+
if (!agentData.source) {
|
|
925
|
+
const msg = 'No source code found for this agent.';
|
|
926
|
+
if (jsonMode) {
|
|
927
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
928
|
+
}
|
|
929
|
+
else {
|
|
930
|
+
(0, ui_1.info)(msg);
|
|
931
|
+
}
|
|
932
|
+
return;
|
|
933
|
+
}
|
|
934
|
+
if (jsonMode) {
|
|
935
|
+
(0, tty_1.outputJson)({ success: true, data: { source: agentData.source, title: agentData.title } });
|
|
936
|
+
return;
|
|
937
|
+
}
|
|
938
|
+
(0, ui_1.header)(agentData.title || 'Untitled Agent');
|
|
939
|
+
console.log();
|
|
940
|
+
const lines = agentData.source.split('\n');
|
|
941
|
+
for (let i = 0; i < lines.length; i++) {
|
|
942
|
+
const lineNum = ui_1.colors.muted(String(i + 1).padStart(4));
|
|
943
|
+
console.log(`${lineNum} ${lines[i]}`);
|
|
944
|
+
}
|
|
945
|
+
console.log();
|
|
946
|
+
console.log(ui_1.colors.muted(` ${lines.length} lines`));
|
|
947
|
+
}
|
|
948
|
+
async function deleteAgentCommand(idOrName, opts) {
|
|
949
|
+
if (!(0, ui_1.requireAuth)())
|
|
950
|
+
return;
|
|
951
|
+
const jsonMode = opts?.json || false;
|
|
952
|
+
const agent = await (0, agent_picker_1.fetchAndPickAgent)(idOrName, jsonMode);
|
|
953
|
+
if (!agent)
|
|
954
|
+
return;
|
|
955
|
+
if (!opts?.force && !jsonMode && (0, tty_1.shouldUseInteractive)()) {
|
|
956
|
+
const answers = await inquirer_1.default.prompt([
|
|
957
|
+
{
|
|
958
|
+
type: 'confirm',
|
|
959
|
+
name: 'confirm',
|
|
960
|
+
message: `Are you sure you want to delete agent ${agent.id.slice(0, 8)}...?`,
|
|
961
|
+
default: false,
|
|
962
|
+
},
|
|
963
|
+
]);
|
|
964
|
+
if (!answers.confirm) {
|
|
965
|
+
(0, ui_1.info)('Cancelled.');
|
|
966
|
+
return;
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
const spinner = (0, tty_1.createSpinner)('Deleting agent...', jsonMode);
|
|
970
|
+
spinner?.start();
|
|
971
|
+
const resp = await (0, api_1.del)(`/api/agent/${agent.id}`);
|
|
972
|
+
if (!resp.ok) {
|
|
973
|
+
spinner?.fail();
|
|
974
|
+
const msg = `Failed to delete: ${resp.data?.error || 'Unknown error'}`;
|
|
975
|
+
if (jsonMode) {
|
|
976
|
+
(0, tty_1.outputJson)({ success: false, error: msg });
|
|
977
|
+
}
|
|
978
|
+
else {
|
|
979
|
+
(0, ui_1.error)(msg);
|
|
980
|
+
}
|
|
981
|
+
return;
|
|
982
|
+
}
|
|
983
|
+
spinner?.succeed();
|
|
984
|
+
if (jsonMode) {
|
|
985
|
+
(0, tty_1.outputJson)({ success: true, data: { agentId: agent.id, deleted: true } });
|
|
986
|
+
}
|
|
987
|
+
else {
|
|
988
|
+
(0, ui_1.success)(`Agent ${agent.id.slice(0, 8)}... deleted.`);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
//# sourceMappingURL=agent.js.map
|