@octavus/cli 0.1.0

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Octavus AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/dist/index.js ADDED
@@ -0,0 +1,593 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/index.ts
4
+ import "dotenv/config";
5
+ import { Command } from "commander";
6
+
7
+ // src/config.ts
8
+ var ConfigError = class extends Error {
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "ConfigError";
12
+ }
13
+ };
14
+ function loadConfig() {
15
+ const apiKey = process.env.OCTAVUS_CLI_API_KEY ?? process.env.OCTAVUS_API_KEY;
16
+ if (!apiKey) {
17
+ throw new ConfigError(
18
+ "No API key found. Set OCTAVUS_CLI_API_KEY or OCTAVUS_API_KEY environment variable."
19
+ );
20
+ }
21
+ const baseUrl = process.env.OCTAVUS_API_URL ?? "https://octavus.ai";
22
+ return { apiKey, baseUrl };
23
+ }
24
+
25
+ // src/agent-files.ts
26
+ import fs from "fs/promises";
27
+ import path from "path";
28
+ import { z } from "zod";
29
+ var agentSettingsSchema = z.object({
30
+ slug: z.string().min(1, "Slug is required"),
31
+ name: z.string().min(1, "Name is required"),
32
+ description: z.string().optional(),
33
+ format: z.enum(["interactive", "generation"])
34
+ });
35
+ var AgentFileError = class extends Error {
36
+ constructor(message, filePath) {
37
+ super(message);
38
+ this.filePath = filePath;
39
+ this.name = "AgentFileError";
40
+ }
41
+ };
42
+ async function readAgentDefinition(agentPath) {
43
+ const resolvedPath = path.resolve(agentPath);
44
+ try {
45
+ const stat = await fs.stat(resolvedPath);
46
+ if (!stat.isDirectory()) {
47
+ throw new AgentFileError(`Not a directory: ${resolvedPath}`);
48
+ }
49
+ } catch (err) {
50
+ if (err.code === "ENOENT") {
51
+ throw new AgentFileError(`Directory not found: ${resolvedPath}`);
52
+ }
53
+ throw err;
54
+ }
55
+ const settingsPath = path.join(resolvedPath, "settings.json");
56
+ const settings = await readSettings(settingsPath);
57
+ const protocolPath = path.join(resolvedPath, "protocol.yaml");
58
+ const protocol = await readProtocol(protocolPath);
59
+ const promptsPath = path.join(resolvedPath, "prompts");
60
+ const prompts = await readPrompts(promptsPath);
61
+ return { settings, protocol, prompts };
62
+ }
63
+ async function readSettings(filePath) {
64
+ try {
65
+ const content = await fs.readFile(filePath, "utf-8");
66
+ const json2 = JSON.parse(content);
67
+ const result = agentSettingsSchema.safeParse(json2);
68
+ if (!result.success) {
69
+ const issues = result.error.issues.map((i) => i.message).join(", ");
70
+ throw new AgentFileError(`Invalid settings.json: ${issues}`, filePath);
71
+ }
72
+ return result.data;
73
+ } catch (err) {
74
+ if (err.code === "ENOENT") {
75
+ throw new AgentFileError("settings.json not found", filePath);
76
+ }
77
+ if (err instanceof SyntaxError) {
78
+ throw new AgentFileError(`Invalid JSON in settings.json: ${err.message}`, filePath);
79
+ }
80
+ throw err;
81
+ }
82
+ }
83
+ async function readProtocol(filePath) {
84
+ try {
85
+ return await fs.readFile(filePath, "utf-8");
86
+ } catch (err) {
87
+ if (err.code === "ENOENT") {
88
+ throw new AgentFileError("protocol.yaml not found", filePath);
89
+ }
90
+ throw err;
91
+ }
92
+ }
93
+ async function readPrompts(promptsDir) {
94
+ const prompts = [];
95
+ try {
96
+ const files = await fs.readdir(promptsDir);
97
+ for (const file of files) {
98
+ if (file.endsWith(".md")) {
99
+ const name = file.replace(/\.md$/, "");
100
+ const content = await fs.readFile(path.join(promptsDir, file), "utf-8");
101
+ prompts.push({ name, content });
102
+ }
103
+ }
104
+ } catch (err) {
105
+ if (err.code !== "ENOENT") {
106
+ throw err;
107
+ }
108
+ }
109
+ return prompts;
110
+ }
111
+
112
+ // src/api.ts
113
+ import { z as z2 } from "zod";
114
+ var ApiError = class extends Error {
115
+ constructor(message, status, code) {
116
+ super(message);
117
+ this.status = status;
118
+ this.code = code;
119
+ this.name = "ApiError";
120
+ }
121
+ };
122
+ var agentSchema = z2.object({
123
+ slug: z2.string(),
124
+ id: z2.string(),
125
+ name: z2.string(),
126
+ description: z2.string().nullable(),
127
+ format: z2.string(),
128
+ createdAt: z2.string(),
129
+ updatedAt: z2.string(),
130
+ projectId: z2.string()
131
+ });
132
+ var agentsResponseSchema = z2.object({
133
+ agents: z2.array(agentSchema)
134
+ });
135
+ var agentDefinitionSchema = z2.object({
136
+ settings: z2.object({
137
+ slug: z2.string(),
138
+ name: z2.string(),
139
+ description: z2.string().optional(),
140
+ format: z2.enum(["interactive", "generation"])
141
+ }),
142
+ protocol: z2.string(),
143
+ prompts: z2.array(z2.object({ name: z2.string(), content: z2.string() })),
144
+ id: z2.string()
145
+ });
146
+ var validationResultSchema = z2.object({
147
+ valid: z2.boolean(),
148
+ errors: z2.array(
149
+ z2.object({
150
+ message: z2.string(),
151
+ path: z2.string().optional(),
152
+ severity: z2.enum(["error", "warning"])
153
+ })
154
+ ),
155
+ warnings: z2.array(
156
+ z2.object({
157
+ message: z2.string(),
158
+ path: z2.string().optional(),
159
+ severity: z2.enum(["error", "warning"])
160
+ })
161
+ )
162
+ });
163
+ var createResponseSchema = z2.object({
164
+ agentId: z2.string(),
165
+ message: z2.string()
166
+ });
167
+ var updateResponseSchema = z2.object({
168
+ agentId: z2.string(),
169
+ message: z2.string()
170
+ });
171
+ var CliApi = class {
172
+ constructor(config) {
173
+ this.config = config;
174
+ }
175
+ /** List all agents in the project */
176
+ async listAgents() {
177
+ const response = await this.request("GET", "/api/agents");
178
+ const data = agentsResponseSchema.parse(response);
179
+ return data.agents;
180
+ }
181
+ /** Get agent by slug */
182
+ async getAgent(slug) {
183
+ try {
184
+ const response = await this.request("GET", `/api/agents/${slug}?by=slug`);
185
+ return agentDefinitionSchema.parse(response);
186
+ } catch (err) {
187
+ if (err instanceof ApiError && err.status === 404) {
188
+ return null;
189
+ }
190
+ throw err;
191
+ }
192
+ }
193
+ /** Validate agent definition (dry-run) */
194
+ async validateAgent(definition) {
195
+ const response = await this.request("POST", "/api/agents/validate", definition);
196
+ return validationResultSchema.parse(response);
197
+ }
198
+ /** Create a new agent */
199
+ async createAgent(definition) {
200
+ const response = await this.request("POST", "/api/agents", definition);
201
+ const data = createResponseSchema.parse(response);
202
+ return data.agentId;
203
+ }
204
+ /** Update an existing agent by slug */
205
+ async updateAgent(slug, definition) {
206
+ const response = await this.request("PATCH", `/api/agents/${slug}?by=slug`, {
207
+ protocol: definition.protocol,
208
+ prompts: definition.prompts
209
+ });
210
+ const data = updateResponseSchema.parse(response);
211
+ return data.agentId;
212
+ }
213
+ /** Sync agent (create or update) */
214
+ async syncAgent(definition) {
215
+ const existing = await this.getAgent(definition.settings.slug);
216
+ if (existing) {
217
+ const agentId2 = await this.updateAgent(definition.settings.slug, definition);
218
+ return { agentId: agentId2, created: false };
219
+ }
220
+ const agentId = await this.createAgent(definition);
221
+ return { agentId, created: true };
222
+ }
223
+ async request(method, path2, body) {
224
+ const url = `${this.config.baseUrl}${path2}`;
225
+ const headers = {
226
+ Authorization: `Bearer ${this.config.apiKey}`
227
+ };
228
+ if (body !== void 0) {
229
+ headers["Content-Type"] = "application/json";
230
+ }
231
+ const response = await fetch(url, {
232
+ method,
233
+ headers,
234
+ body: body !== void 0 ? JSON.stringify(body) : void 0
235
+ });
236
+ const contentType = response.headers.get("content-type");
237
+ const isJson = contentType?.includes("application/json");
238
+ if (!response.ok) {
239
+ if (isJson) {
240
+ const errorData = await response.json();
241
+ throw new ApiError(
242
+ errorData.error ?? `Request failed with status ${response.status}`,
243
+ response.status,
244
+ errorData.code
245
+ );
246
+ }
247
+ throw new ApiError(`Request failed with status ${response.status}`, response.status);
248
+ }
249
+ if (!isJson) {
250
+ throw new ApiError("Expected JSON response", response.status);
251
+ }
252
+ return await response.json();
253
+ }
254
+ };
255
+
256
+ // src/output.ts
257
+ var colors = {
258
+ reset: "\x1B[0m",
259
+ red: "\x1B[31m",
260
+ green: "\x1B[32m",
261
+ yellow: "\x1B[33m",
262
+ blue: "\x1B[34m",
263
+ magenta: "\x1B[35m",
264
+ cyan: "\x1B[36m",
265
+ gray: "\x1B[90m",
266
+ bold: "\x1B[1m"
267
+ };
268
+ function success(message) {
269
+ console.log(`${colors.green}\u2713${colors.reset} ${message}`);
270
+ }
271
+ function error(message) {
272
+ console.error(`${colors.red}\u2717${colors.reset} ${message}`);
273
+ }
274
+ function warning(message) {
275
+ console.log(`${colors.yellow}\u26A0${colors.reset} ${message}`);
276
+ }
277
+ function info(message) {
278
+ console.log(`${colors.blue}\u2139${colors.reset} ${message}`);
279
+ }
280
+ function dim(message) {
281
+ console.log(`${colors.gray}${message}${colors.reset}`);
282
+ }
283
+ function bold(text) {
284
+ return `${colors.bold}${text}${colors.reset}`;
285
+ }
286
+ function cyan(text) {
287
+ return `${colors.cyan}${text}${colors.reset}`;
288
+ }
289
+ function gray(text) {
290
+ return `${colors.gray}${text}${colors.reset}`;
291
+ }
292
+ function keyValue(key, value) {
293
+ console.log(` ${colors.gray}${key}:${colors.reset} ${value}`);
294
+ }
295
+ function tableRow(columns, widths) {
296
+ const formatted = columns.map((col, i) => col.padEnd(widths[i] ?? 20)).join(" ");
297
+ console.log(formatted);
298
+ }
299
+ function separator() {
300
+ console.log();
301
+ }
302
+ function json(data) {
303
+ console.log(JSON.stringify(data, null, 2));
304
+ }
305
+
306
+ // src/commands/validate.ts
307
+ function registerValidateCommand(program2) {
308
+ program2.command("validate <path>").description("Validate agent definition (dry-run, no changes saved)").option("--json", "Output as JSON").option("--quiet", "Suppress non-essential output").action(async (agentPath, options) => {
309
+ try {
310
+ await runValidate(agentPath, options);
311
+ } catch (err) {
312
+ handleError(err, options);
313
+ process.exit(err instanceof ConfigError ? 2 : 1);
314
+ }
315
+ });
316
+ }
317
+ async function runValidate(agentPath, options) {
318
+ const config = loadConfig();
319
+ const api = new CliApi(config);
320
+ if (!options.quiet && !options.json) {
321
+ info(`Reading agent from ${cyan(agentPath)}...`);
322
+ }
323
+ const definition = await readAgentDefinition(agentPath);
324
+ if (!options.quiet && !options.json) {
325
+ info(`Validating ${bold(definition.settings.slug)}...`);
326
+ }
327
+ const result = await api.validateAgent(definition);
328
+ if (options.json) {
329
+ json({
330
+ slug: definition.settings.slug,
331
+ valid: result.valid,
332
+ errors: result.errors,
333
+ warnings: result.warnings
334
+ });
335
+ } else {
336
+ if (result.valid) {
337
+ success(`Agent ${bold(definition.settings.slug)} is valid`);
338
+ } else {
339
+ error(`Agent ${bold(definition.settings.slug)} has validation errors`);
340
+ }
341
+ for (const err of result.errors) {
342
+ const location = err.path ? ` (${gray(err.path)})` : "";
343
+ error(` ${err.message}${location}`);
344
+ }
345
+ for (const warn of result.warnings) {
346
+ const location = warn.path ? ` (${gray(warn.path)})` : "";
347
+ warning(` ${warn.message}${location}`);
348
+ }
349
+ }
350
+ if (!result.valid) {
351
+ process.exit(1);
352
+ }
353
+ }
354
+ function getErrorCode(err) {
355
+ if (err instanceof ConfigError) return "CONFIG_ERROR";
356
+ if (err instanceof AgentFileError) return "FILE_ERROR";
357
+ if (err instanceof ApiError) return "API_ERROR";
358
+ return "UNKNOWN";
359
+ }
360
+ function handleError(err, options) {
361
+ if (options.json === true) {
362
+ json({
363
+ error: err instanceof Error ? err.message : "Unknown error",
364
+ code: getErrorCode(err)
365
+ });
366
+ return;
367
+ }
368
+ if (err instanceof ConfigError) {
369
+ error(err.message);
370
+ } else if (err instanceof AgentFileError) {
371
+ error(err.message);
372
+ if (err.filePath !== void 0) {
373
+ dim(` File: ${err.filePath}`);
374
+ }
375
+ } else if (err instanceof ApiError) {
376
+ error(`API error: ${err.message}`);
377
+ if (err.status !== 0) {
378
+ dim(` Status: ${err.status}`);
379
+ }
380
+ } else if (err instanceof Error) {
381
+ error(err.message);
382
+ } else {
383
+ error("An unknown error occurred");
384
+ }
385
+ }
386
+
387
+ // src/commands/sync.ts
388
+ function registerSyncCommand(program2) {
389
+ program2.command("sync <path>").description("Sync agent to platform (creates or updates)").option("--json", "Output as JSON").option("--quiet", "Suppress non-essential output").action(async (agentPath, options) => {
390
+ try {
391
+ await runSync(agentPath, options);
392
+ } catch (err) {
393
+ handleError2(err, options);
394
+ process.exit(err instanceof ConfigError ? 2 : 1);
395
+ }
396
+ });
397
+ }
398
+ async function runSync(agentPath, options) {
399
+ const config = loadConfig();
400
+ const api = new CliApi(config);
401
+ if (!options.quiet && !options.json) {
402
+ info(`Reading agent from ${cyan(agentPath)}...`);
403
+ }
404
+ const definition = await readAgentDefinition(agentPath);
405
+ if (!options.quiet && !options.json) {
406
+ info(`Syncing ${bold(definition.settings.slug)}...`);
407
+ }
408
+ const result = await api.syncAgent(definition);
409
+ if (options.json) {
410
+ json({
411
+ slug: definition.settings.slug,
412
+ agentId: result.agentId,
413
+ created: result.created
414
+ });
415
+ } else {
416
+ const action = result.created ? "Created" : "Updated";
417
+ success(`${action}: ${bold(definition.settings.slug)}`);
418
+ keyValue("Agent ID", result.agentId);
419
+ }
420
+ }
421
+ function getErrorCode2(err) {
422
+ if (err instanceof ConfigError) return "CONFIG_ERROR";
423
+ if (err instanceof AgentFileError) return "FILE_ERROR";
424
+ if (err instanceof ApiError) return "API_ERROR";
425
+ return "UNKNOWN";
426
+ }
427
+ function handleError2(err, options) {
428
+ if (options.json === true) {
429
+ json({
430
+ error: err instanceof Error ? err.message : "Unknown error",
431
+ code: getErrorCode2(err)
432
+ });
433
+ return;
434
+ }
435
+ if (err instanceof ConfigError) {
436
+ error(err.message);
437
+ } else if (err instanceof AgentFileError) {
438
+ error(err.message);
439
+ if (err.filePath !== void 0) {
440
+ dim(` File: ${err.filePath}`);
441
+ }
442
+ } else if (err instanceof ApiError) {
443
+ error(`API error: ${err.message}`);
444
+ if (err.status !== 0) {
445
+ dim(` Status: ${err.status}`);
446
+ }
447
+ } else if (err instanceof Error) {
448
+ error(err.message);
449
+ } else {
450
+ error("An unknown error occurred");
451
+ }
452
+ }
453
+
454
+ // src/commands/list.ts
455
+ function registerListCommand(program2) {
456
+ program2.command("list").description("List all agents in the project").option("--json", "Output as JSON").option("--quiet", "Suppress non-essential output").action(async (options) => {
457
+ try {
458
+ await runList(options);
459
+ } catch (err) {
460
+ handleError3(err, options);
461
+ process.exit(err instanceof ConfigError ? 2 : 1);
462
+ }
463
+ });
464
+ }
465
+ async function runList(options) {
466
+ const config = loadConfig();
467
+ const api = new CliApi(config);
468
+ const agents = await api.listAgents();
469
+ if (options.json) {
470
+ json({ agents });
471
+ return;
472
+ }
473
+ if (agents.length === 0) {
474
+ info("No agents found");
475
+ return;
476
+ }
477
+ separator();
478
+ tableRow(
479
+ [bold("SLUG"), bold("NAME"), bold("FORMAT"), bold("ID")],
480
+ [20, 30, 12, 36]
481
+ );
482
+ dim("\u2500".repeat(100));
483
+ for (const agent of agents) {
484
+ tableRow([agent.slug, agent.name, agent.format, agent.id], [20, 30, 12, 36]);
485
+ }
486
+ separator();
487
+ dim(`${agents.length} agent(s)`);
488
+ }
489
+ function getErrorCode3(err) {
490
+ if (err instanceof ConfigError) return "CONFIG_ERROR";
491
+ if (err instanceof ApiError) return "API_ERROR";
492
+ return "UNKNOWN";
493
+ }
494
+ function handleError3(err, options) {
495
+ if (options.json === true) {
496
+ json({
497
+ error: err instanceof Error ? err.message : "Unknown error",
498
+ code: getErrorCode3(err)
499
+ });
500
+ return;
501
+ }
502
+ if (err instanceof ConfigError) {
503
+ error(err.message);
504
+ } else if (err instanceof ApiError) {
505
+ error(`API error: ${err.message}`);
506
+ if (err.status !== 0) {
507
+ dim(` Status: ${err.status}`);
508
+ }
509
+ } else if (err instanceof Error) {
510
+ error(err.message);
511
+ } else {
512
+ error("An unknown error occurred");
513
+ }
514
+ }
515
+
516
+ // src/commands/get.ts
517
+ function registerGetCommand(program2) {
518
+ program2.command("get <slug>").description("Get agent details by slug").option("--json", "Output as JSON").option("--quiet", "Suppress non-essential output").action(async (slug, options) => {
519
+ try {
520
+ await runGet(slug, options);
521
+ } catch (err) {
522
+ handleError4(err, options);
523
+ process.exit(err instanceof ConfigError ? 2 : 1);
524
+ }
525
+ });
526
+ }
527
+ async function runGet(slug, options) {
528
+ const config = loadConfig();
529
+ const api = new CliApi(config);
530
+ const agent = await api.getAgent(slug);
531
+ if (!agent) {
532
+ if (options.json) {
533
+ json({ error: `Agent not found: ${slug}`, code: "NOT_FOUND" });
534
+ } else {
535
+ error(`Agent not found: ${slug}`);
536
+ }
537
+ process.exit(1);
538
+ }
539
+ if (options.json) {
540
+ json(agent);
541
+ return;
542
+ }
543
+ separator();
544
+ success(`Agent: ${bold(agent.settings.name)}`);
545
+ separator();
546
+ keyValue("Slug", agent.settings.slug);
547
+ keyValue("ID", agent.id);
548
+ keyValue("Format", agent.settings.format);
549
+ if (agent.settings.description) {
550
+ keyValue("Description", agent.settings.description);
551
+ }
552
+ separator();
553
+ keyValue(
554
+ "Prompts",
555
+ agent.prompts.length > 0 ? agent.prompts.map((p) => p.name).join(", ") : "(none)"
556
+ );
557
+ }
558
+ function getErrorCode4(err) {
559
+ if (err instanceof ConfigError) return "CONFIG_ERROR";
560
+ if (err instanceof ApiError) return "API_ERROR";
561
+ return "UNKNOWN";
562
+ }
563
+ function handleError4(err, options) {
564
+ if (options.json === true) {
565
+ json({
566
+ error: err instanceof Error ? err.message : "Unknown error",
567
+ code: getErrorCode4(err)
568
+ });
569
+ return;
570
+ }
571
+ if (err instanceof ConfigError) {
572
+ error(err.message);
573
+ } else if (err instanceof ApiError) {
574
+ error(`API error: ${err.message}`);
575
+ if (err.status !== 0) {
576
+ dim(` Status: ${err.status}`);
577
+ }
578
+ } else if (err instanceof Error) {
579
+ error(err.message);
580
+ } else {
581
+ error("An unknown error occurred");
582
+ }
583
+ }
584
+
585
+ // src/index.ts
586
+ var program = new Command();
587
+ program.name("octavus").description("CLI for validating and syncing Octavus agent definitions").version("0.1.0");
588
+ registerValidateCommand(program);
589
+ registerSyncCommand(program);
590
+ registerListCommand(program);
591
+ registerGetCommand(program);
592
+ program.parse();
593
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/config.ts","../src/agent-files.ts","../src/api.ts","../src/output.ts","../src/commands/validate.ts","../src/commands/sync.ts","../src/commands/list.ts","../src/commands/get.ts"],"sourcesContent":["/**\n * Octavus CLI - Validate and sync agent definitions\n *\n * Commands:\n * octavus validate <path> - Validate agent definition (dry-run)\n * octavus sync <path> - Sync agent to platform (creates or updates)\n * octavus list - List all agents in the project\n * octavus get <slug> - Get agent details by slug\n *\n * Environment:\n * OCTAVUS_CLI_API_KEY - API key with agent management permissions\n * OCTAVUS_API_KEY - Fallback API key\n * OCTAVUS_API_URL - Optional, defaults to https://octavus.ai\n */\n\n// Load .env file from current working directory\nimport 'dotenv/config';\n\nimport { Command } from 'commander';\nimport { registerValidateCommand } from '@/commands/validate.js';\nimport { registerSyncCommand } from '@/commands/sync.js';\nimport { registerListCommand } from '@/commands/list.js';\nimport { registerGetCommand } from '@/commands/get.js';\n\nconst program = new Command();\n\nprogram\n .name('octavus')\n .description('CLI for validating and syncing Octavus agent definitions')\n .version('0.1.0');\n\n// Register commands\nregisterValidateCommand(program);\nregisterSyncCommand(program);\nregisterListCommand(program);\nregisterGetCommand(program);\n\n// Parse and run\nprogram.parse();\n","/**\n * Configuration loading for the CLI.\n * Handles environment variables and defaults.\n */\n\nexport interface CliConfig {\n apiKey: string;\n baseUrl: string;\n}\n\nexport class ConfigError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ConfigError';\n }\n}\n\n/**\n * Load CLI configuration from environment variables.\n * API key resolution: OCTAVUS_CLI_API_KEY > OCTAVUS_API_KEY\n */\nexport function loadConfig(): CliConfig {\n const apiKey = process.env.OCTAVUS_CLI_API_KEY ?? process.env.OCTAVUS_API_KEY;\n\n if (!apiKey) {\n throw new ConfigError(\n 'No API key found. Set OCTAVUS_CLI_API_KEY or OCTAVUS_API_KEY environment variable.',\n );\n }\n\n const baseUrl = process.env.OCTAVUS_API_URL ?? 'https://octavus.ai';\n\n return { apiKey, baseUrl };\n}\n","/**\n * Agent file reading from filesystem.\n * Reads settings.json, protocol.yaml, and prompts/*.md files.\n */\n\nimport fs from 'node:fs/promises';\nimport path from 'node:path';\nimport { z } from 'zod';\n\n/** Agent settings from settings.json */\nexport interface AgentSettings {\n slug: string;\n name: string;\n description?: string;\n format: 'interactive' | 'generation';\n}\n\n/** Agent prompt from prompts/*.md */\nexport interface AgentPrompt {\n name: string;\n content: string;\n}\n\n/** Complete agent definition read from filesystem */\nexport interface AgentDefinition {\n settings: AgentSettings;\n protocol: string;\n prompts: AgentPrompt[];\n}\n\nconst agentSettingsSchema = z.object({\n slug: z.string().min(1, 'Slug is required'),\n name: z.string().min(1, 'Name is required'),\n description: z.string().optional(),\n format: z.enum(['interactive', 'generation']),\n});\n\nexport class AgentFileError extends Error {\n constructor(\n message: string,\n public readonly filePath?: string,\n ) {\n super(message);\n this.name = 'AgentFileError';\n }\n}\n\n/**\n * Read agent definition from a directory.\n * Expects:\n * - settings.json (required)\n * - protocol.yaml (required)\n * - prompts/*.md (optional)\n */\nexport async function readAgentDefinition(agentPath: string): Promise<AgentDefinition> {\n const resolvedPath = path.resolve(agentPath);\n\n // Check if directory exists\n try {\n const stat = await fs.stat(resolvedPath);\n if (!stat.isDirectory()) {\n throw new AgentFileError(`Not a directory: ${resolvedPath}`);\n }\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n throw new AgentFileError(`Directory not found: ${resolvedPath}`);\n }\n throw err;\n }\n\n // Read settings.json\n const settingsPath = path.join(resolvedPath, 'settings.json');\n const settings = await readSettings(settingsPath);\n\n // Read protocol.yaml\n const protocolPath = path.join(resolvedPath, 'protocol.yaml');\n const protocol = await readProtocol(protocolPath);\n\n // Read prompts\n const promptsPath = path.join(resolvedPath, 'prompts');\n const prompts = await readPrompts(promptsPath);\n\n return { settings, protocol, prompts };\n}\n\nasync function readSettings(filePath: string): Promise<AgentSettings> {\n try {\n const content = await fs.readFile(filePath, 'utf-8');\n const json: unknown = JSON.parse(content);\n const result = agentSettingsSchema.safeParse(json);\n\n if (!result.success) {\n const issues = result.error.issues.map((i) => i.message).join(', ');\n throw new AgentFileError(`Invalid settings.json: ${issues}`, filePath);\n }\n\n return result.data;\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n throw new AgentFileError('settings.json not found', filePath);\n }\n if (err instanceof SyntaxError) {\n throw new AgentFileError(`Invalid JSON in settings.json: ${err.message}`, filePath);\n }\n throw err;\n }\n}\n\nasync function readProtocol(filePath: string): Promise<string> {\n try {\n return await fs.readFile(filePath, 'utf-8');\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n throw new AgentFileError('protocol.yaml not found', filePath);\n }\n throw err;\n }\n}\n\nasync function readPrompts(promptsDir: string): Promise<AgentPrompt[]> {\n const prompts: AgentPrompt[] = [];\n\n try {\n const files = await fs.readdir(promptsDir);\n\n for (const file of files) {\n if (file.endsWith('.md')) {\n const name = file.replace(/\\.md$/, '');\n const content = await fs.readFile(path.join(promptsDir, file), 'utf-8');\n prompts.push({ name, content });\n }\n }\n } catch (err) {\n // No prompts directory is fine\n if ((err as { code?: string }).code !== 'ENOENT') {\n throw err;\n }\n }\n\n return prompts;\n}\n","/**\n * API client for the CLI.\n * Thin wrapper around fetch for Octavus platform API calls.\n */\n\nimport { z } from 'zod';\nimport type { CliConfig } from '@/config.js';\nimport type { AgentDefinition } from '@/agent-files.js';\n\n/** API error response */\nexport class ApiError extends Error {\n constructor(\n message: string,\n public readonly status: number,\n public readonly code?: string,\n ) {\n super(message);\n this.name = 'ApiError';\n }\n}\n\n/** Agent summary from list endpoint */\nexport interface Agent {\n slug: string;\n id: string;\n name: string;\n description: string | null;\n format: string;\n createdAt: string;\n updatedAt: string;\n projectId: string;\n}\n\n/** Full agent definition from get endpoint */\nexport interface AgentDetails {\n settings: {\n slug: string;\n name: string;\n description?: string;\n format: 'interactive' | 'generation';\n };\n protocol: string;\n prompts: { name: string; content: string }[];\n id: string;\n}\n\n/** Validation error detail */\nexport interface ValidationErrorDetail {\n message: string;\n path?: string;\n severity: 'error' | 'warning';\n}\n\n/** Validation result from validate endpoint */\nexport interface ValidationResult {\n valid: boolean;\n errors: ValidationErrorDetail[];\n warnings: ValidationErrorDetail[];\n}\n\n/** Sync result from create/update endpoints */\nexport interface SyncResult {\n agentId: string;\n created: boolean;\n}\n\n// Response schemas for validation\nconst agentSchema = z.object({\n slug: z.string(),\n id: z.string(),\n name: z.string(),\n description: z.string().nullable(),\n format: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n projectId: z.string(),\n});\n\nconst agentsResponseSchema = z.object({\n agents: z.array(agentSchema),\n});\n\nconst agentDefinitionSchema = z.object({\n settings: z.object({\n slug: z.string(),\n name: z.string(),\n description: z.string().optional(),\n format: z.enum(['interactive', 'generation']),\n }),\n protocol: z.string(),\n prompts: z.array(z.object({ name: z.string(), content: z.string() })),\n id: z.string(),\n});\n\nconst validationResultSchema = z.object({\n valid: z.boolean(),\n errors: z.array(\n z.object({\n message: z.string(),\n path: z.string().optional(),\n severity: z.enum(['error', 'warning']),\n }),\n ),\n warnings: z.array(\n z.object({\n message: z.string(),\n path: z.string().optional(),\n severity: z.enum(['error', 'warning']),\n }),\n ),\n});\n\nconst createResponseSchema = z.object({\n agentId: z.string(),\n message: z.string(),\n});\n\nconst updateResponseSchema = z.object({\n agentId: z.string(),\n message: z.string(),\n});\n\nexport class CliApi {\n constructor(private readonly config: CliConfig) {}\n\n /** List all agents in the project */\n async listAgents(): Promise<Agent[]> {\n const response = await this.request('GET', '/api/agents');\n const data = agentsResponseSchema.parse(response);\n return data.agents;\n }\n\n /** Get agent by slug */\n async getAgent(slug: string): Promise<AgentDetails | null> {\n try {\n const response = await this.request('GET', `/api/agents/${slug}?by=slug`);\n return agentDefinitionSchema.parse(response);\n } catch (err) {\n if (err instanceof ApiError && err.status === 404) {\n return null;\n }\n throw err;\n }\n }\n\n /** Validate agent definition (dry-run) */\n async validateAgent(definition: AgentDefinition): Promise<ValidationResult> {\n const response = await this.request('POST', '/api/agents/validate', definition);\n return validationResultSchema.parse(response);\n }\n\n /** Create a new agent */\n async createAgent(definition: AgentDefinition): Promise<string> {\n const response = await this.request('POST', '/api/agents', definition);\n const data = createResponseSchema.parse(response);\n return data.agentId;\n }\n\n /** Update an existing agent by slug */\n async updateAgent(slug: string, definition: AgentDefinition): Promise<string> {\n const response = await this.request('PATCH', `/api/agents/${slug}?by=slug`, {\n protocol: definition.protocol,\n prompts: definition.prompts,\n });\n const data = updateResponseSchema.parse(response);\n return data.agentId;\n }\n\n /** Sync agent (create or update) */\n async syncAgent(definition: AgentDefinition): Promise<SyncResult> {\n const existing = await this.getAgent(definition.settings.slug);\n\n if (existing) {\n const agentId = await this.updateAgent(definition.settings.slug, definition);\n return { agentId, created: false };\n }\n\n const agentId = await this.createAgent(definition);\n return { agentId, created: true };\n }\n\n private async request(method: string, path: string, body?: unknown): Promise<unknown> {\n const url = `${this.config.baseUrl}${path}`;\n\n const headers: Record<string, string> = {\n Authorization: `Bearer ${this.config.apiKey}`,\n };\n\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n }\n\n const response = await fetch(url, {\n method,\n headers,\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n\n const contentType = response.headers.get('content-type');\n const isJson = contentType?.includes('application/json');\n\n if (!response.ok) {\n if (isJson) {\n const errorData = (await response.json()) as { error?: string; code?: string };\n throw new ApiError(\n errorData.error ?? `Request failed with status ${response.status}`,\n response.status,\n errorData.code,\n );\n }\n throw new ApiError(`Request failed with status ${response.status}`, response.status);\n }\n\n if (!isJson) {\n throw new ApiError('Expected JSON response', response.status);\n }\n\n return await response.json();\n }\n}\n","/* eslint-disable no-console */\n/**\n * Terminal output utilities with colors and formatting.\n * Console statements are intentional for CLI output.\n */\n\n// ANSI color codes\nconst colors = {\n reset: '\\x1b[0m',\n red: '\\x1b[31m',\n green: '\\x1b[32m',\n yellow: '\\x1b[33m',\n blue: '\\x1b[34m',\n magenta: '\\x1b[35m',\n cyan: '\\x1b[36m',\n gray: '\\x1b[90m',\n bold: '\\x1b[1m',\n};\n\nexport function success(message: string): void {\n console.log(`${colors.green}✓${colors.reset} ${message}`);\n}\n\nexport function error(message: string): void {\n console.error(`${colors.red}✗${colors.reset} ${message}`);\n}\n\nexport function warning(message: string): void {\n console.log(`${colors.yellow}⚠${colors.reset} ${message}`);\n}\n\nexport function info(message: string): void {\n console.log(`${colors.blue}ℹ${colors.reset} ${message}`);\n}\n\nexport function dim(message: string): void {\n console.log(`${colors.gray}${message}${colors.reset}`);\n}\n\nexport function bold(text: string): string {\n return `${colors.bold}${text}${colors.reset}`;\n}\n\nexport function cyan(text: string): string {\n return `${colors.cyan}${text}${colors.reset}`;\n}\n\nexport function green(text: string): string {\n return `${colors.green}${text}${colors.reset}`;\n}\n\nexport function yellow(text: string): string {\n return `${colors.yellow}${text}${colors.reset}`;\n}\n\nexport function red(text: string): string {\n return `${colors.red}${text}${colors.reset}`;\n}\n\nexport function gray(text: string): string {\n return `${colors.gray}${text}${colors.reset}`;\n}\n\n/**\n * Print a key-value pair with formatting\n */\nexport function keyValue(key: string, value: string): void {\n console.log(` ${colors.gray}${key}:${colors.reset} ${value}`);\n}\n\n/**\n * Print a table row\n */\nexport function tableRow(columns: string[], widths: number[]): void {\n const formatted = columns.map((col, i) => col.padEnd(widths[i] ?? 20)).join(' ');\n console.log(formatted);\n}\n\n/**\n * Print a separator line\n */\nexport function separator(): void {\n console.log();\n}\n\n/**\n * JSON output mode for CI/CD\n */\nexport function json(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n}\n","/**\n * octavus validate <path>\n * Validate agent definition via API (dry-run, no changes saved)\n */\n\nimport type { Command } from 'commander';\nimport { loadConfig, ConfigError } from '@/config.js';\nimport { readAgentDefinition, AgentFileError } from '@/agent-files.js';\nimport { CliApi, ApiError } from '@/api.js';\nimport * as output from '@/output.js';\n\ninterface ValidateOptions {\n json?: boolean;\n quiet?: boolean;\n}\n\nexport function registerValidateCommand(program: Command): void {\n program\n .command('validate <path>')\n .description('Validate agent definition (dry-run, no changes saved)')\n .option('--json', 'Output as JSON')\n .option('--quiet', 'Suppress non-essential output')\n .action(async (agentPath: string, options: ValidateOptions) => {\n try {\n await runValidate(agentPath, options);\n } catch (err) {\n handleError(err, options);\n process.exit(err instanceof ConfigError ? 2 : 1);\n }\n });\n}\n\nasync function runValidate(agentPath: string, options: ValidateOptions): Promise<void> {\n const config = loadConfig();\n const api = new CliApi(config);\n\n // Read agent files\n if (!options.quiet && !options.json) {\n output.info(`Reading agent from ${output.cyan(agentPath)}...`);\n }\n\n const definition = await readAgentDefinition(agentPath);\n\n if (!options.quiet && !options.json) {\n output.info(`Validating ${output.bold(definition.settings.slug)}...`);\n }\n\n // Validate via API\n const result = await api.validateAgent(definition);\n\n // Output results\n if (options.json) {\n output.json({\n slug: definition.settings.slug,\n valid: result.valid,\n errors: result.errors,\n warnings: result.warnings,\n });\n } else {\n if (result.valid) {\n output.success(`Agent ${output.bold(definition.settings.slug)} is valid`);\n } else {\n output.error(`Agent ${output.bold(definition.settings.slug)} has validation errors`);\n }\n\n // Show errors\n for (const err of result.errors) {\n const location = err.path ? ` (${output.gray(err.path)})` : '';\n output.error(` ${err.message}${location}`);\n }\n\n // Show warnings\n for (const warn of result.warnings) {\n const location = warn.path ? ` (${output.gray(warn.path)})` : '';\n output.warning(` ${warn.message}${location}`);\n }\n }\n\n // Exit with error code if validation failed\n if (!result.valid) {\n process.exit(1);\n }\n}\n\nfunction getErrorCode(err: unknown): string {\n if (err instanceof ConfigError) return 'CONFIG_ERROR';\n if (err instanceof AgentFileError) return 'FILE_ERROR';\n if (err instanceof ApiError) return 'API_ERROR';\n return 'UNKNOWN';\n}\n\nfunction handleError(err: unknown, options: ValidateOptions): void {\n if (options.json === true) {\n output.json({\n error: err instanceof Error ? err.message : 'Unknown error',\n code: getErrorCode(err),\n });\n return;\n }\n\n if (err instanceof ConfigError) {\n output.error(err.message);\n } else if (err instanceof AgentFileError) {\n output.error(err.message);\n if (err.filePath !== undefined) {\n output.dim(` File: ${err.filePath}`);\n }\n } else if (err instanceof ApiError) {\n output.error(`API error: ${err.message}`);\n if (err.status !== 0) {\n output.dim(` Status: ${err.status}`);\n }\n } else if (err instanceof Error) {\n output.error(err.message);\n } else {\n output.error('An unknown error occurred');\n }\n}\n","/**\n * octavus sync <path>\n * Sync agent to platform (creates or updates)\n */\n\nimport type { Command } from 'commander';\nimport { loadConfig, ConfigError } from '@/config.js';\nimport { readAgentDefinition, AgentFileError } from '@/agent-files.js';\nimport { CliApi, ApiError } from '@/api.js';\nimport * as output from '@/output.js';\n\ninterface SyncOptions {\n json?: boolean;\n quiet?: boolean;\n}\n\nexport function registerSyncCommand(program: Command): void {\n program\n .command('sync <path>')\n .description('Sync agent to platform (creates or updates)')\n .option('--json', 'Output as JSON')\n .option('--quiet', 'Suppress non-essential output')\n .action(async (agentPath: string, options: SyncOptions) => {\n try {\n await runSync(agentPath, options);\n } catch (err) {\n handleError(err, options);\n process.exit(err instanceof ConfigError ? 2 : 1);\n }\n });\n}\n\nasync function runSync(agentPath: string, options: SyncOptions): Promise<void> {\n const config = loadConfig();\n const api = new CliApi(config);\n\n // Read agent files\n if (!options.quiet && !options.json) {\n output.info(`Reading agent from ${output.cyan(agentPath)}...`);\n }\n\n const definition = await readAgentDefinition(agentPath);\n\n if (!options.quiet && !options.json) {\n output.info(`Syncing ${output.bold(definition.settings.slug)}...`);\n }\n\n // Sync to platform\n const result = await api.syncAgent(definition);\n\n // Output results\n if (options.json) {\n output.json({\n slug: definition.settings.slug,\n agentId: result.agentId,\n created: result.created,\n });\n } else {\n const action = result.created ? 'Created' : 'Updated';\n output.success(`${action}: ${output.bold(definition.settings.slug)}`);\n output.keyValue('Agent ID', result.agentId);\n }\n}\n\nfunction getErrorCode(err: unknown): string {\n if (err instanceof ConfigError) return 'CONFIG_ERROR';\n if (err instanceof AgentFileError) return 'FILE_ERROR';\n if (err instanceof ApiError) return 'API_ERROR';\n return 'UNKNOWN';\n}\n\nfunction handleError(err: unknown, options: SyncOptions): void {\n if (options.json === true) {\n output.json({\n error: err instanceof Error ? err.message : 'Unknown error',\n code: getErrorCode(err),\n });\n return;\n }\n\n if (err instanceof ConfigError) {\n output.error(err.message);\n } else if (err instanceof AgentFileError) {\n output.error(err.message);\n if (err.filePath !== undefined) {\n output.dim(` File: ${err.filePath}`);\n }\n } else if (err instanceof ApiError) {\n output.error(`API error: ${err.message}`);\n if (err.status !== 0) {\n output.dim(` Status: ${err.status}`);\n }\n } else if (err instanceof Error) {\n output.error(err.message);\n } else {\n output.error('An unknown error occurred');\n }\n}\n","/**\n * octavus list\n * List all agents in the project\n */\n\nimport type { Command } from 'commander';\nimport { loadConfig, ConfigError } from '@/config.js';\nimport { CliApi, ApiError } from '@/api.js';\nimport * as output from '@/output.js';\n\ninterface ListOptions {\n json?: boolean;\n quiet?: boolean;\n}\n\nexport function registerListCommand(program: Command): void {\n program\n .command('list')\n .description('List all agents in the project')\n .option('--json', 'Output as JSON')\n .option('--quiet', 'Suppress non-essential output')\n .action(async (options: ListOptions) => {\n try {\n await runList(options);\n } catch (err) {\n handleError(err, options);\n process.exit(err instanceof ConfigError ? 2 : 1);\n }\n });\n}\n\nasync function runList(options: ListOptions): Promise<void> {\n const config = loadConfig();\n const api = new CliApi(config);\n\n const agents = await api.listAgents();\n\n if (options.json) {\n output.json({ agents });\n return;\n }\n\n if (agents.length === 0) {\n output.info('No agents found');\n return;\n }\n\n // Print header\n output.separator();\n output.tableRow(\n [output.bold('SLUG'), output.bold('NAME'), output.bold('FORMAT'), output.bold('ID')],\n [20, 30, 12, 36],\n );\n output.dim('─'.repeat(100));\n\n // Print agents\n for (const agent of agents) {\n output.tableRow([agent.slug, agent.name, agent.format, agent.id], [20, 30, 12, 36]);\n }\n\n output.separator();\n output.dim(`${agents.length} agent(s)`);\n}\n\nfunction getErrorCode(err: unknown): string {\n if (err instanceof ConfigError) return 'CONFIG_ERROR';\n if (err instanceof ApiError) return 'API_ERROR';\n return 'UNKNOWN';\n}\n\nfunction handleError(err: unknown, options: ListOptions): void {\n if (options.json === true) {\n output.json({\n error: err instanceof Error ? err.message : 'Unknown error',\n code: getErrorCode(err),\n });\n return;\n }\n\n if (err instanceof ConfigError) {\n output.error(err.message);\n } else if (err instanceof ApiError) {\n output.error(`API error: ${err.message}`);\n if (err.status !== 0) {\n output.dim(` Status: ${err.status}`);\n }\n } else if (err instanceof Error) {\n output.error(err.message);\n } else {\n output.error('An unknown error occurred');\n }\n}\n","/**\n * octavus get <slug>\n * Get agent details by slug\n */\n\nimport type { Command } from 'commander';\nimport { loadConfig, ConfigError } from '@/config.js';\nimport { CliApi, ApiError } from '@/api.js';\nimport * as output from '@/output.js';\n\ninterface GetOptions {\n json?: boolean;\n quiet?: boolean;\n}\n\nexport function registerGetCommand(program: Command): void {\n program\n .command('get <slug>')\n .description('Get agent details by slug')\n .option('--json', 'Output as JSON')\n .option('--quiet', 'Suppress non-essential output')\n .action(async (slug: string, options: GetOptions) => {\n try {\n await runGet(slug, options);\n } catch (err) {\n handleError(err, options);\n process.exit(err instanceof ConfigError ? 2 : 1);\n }\n });\n}\n\nasync function runGet(slug: string, options: GetOptions): Promise<void> {\n const config = loadConfig();\n const api = new CliApi(config);\n\n const agent = await api.getAgent(slug);\n\n if (!agent) {\n if (options.json) {\n output.json({ error: `Agent not found: ${slug}`, code: 'NOT_FOUND' });\n } else {\n output.error(`Agent not found: ${slug}`);\n }\n process.exit(1);\n }\n\n if (options.json) {\n output.json(agent);\n return;\n }\n\n // Print agent details\n output.separator();\n output.success(`Agent: ${output.bold(agent.settings.name)}`);\n output.separator();\n output.keyValue('Slug', agent.settings.slug);\n output.keyValue('ID', agent.id);\n output.keyValue('Format', agent.settings.format);\n if (agent.settings.description) {\n output.keyValue('Description', agent.settings.description);\n }\n output.separator();\n output.keyValue(\n 'Prompts',\n agent.prompts.length > 0 ? agent.prompts.map((p) => p.name).join(', ') : '(none)',\n );\n}\n\nfunction getErrorCode(err: unknown): string {\n if (err instanceof ConfigError) return 'CONFIG_ERROR';\n if (err instanceof ApiError) return 'API_ERROR';\n return 'UNKNOWN';\n}\n\nfunction handleError(err: unknown, options: GetOptions): void {\n if (options.json === true) {\n output.json({\n error: err instanceof Error ? err.message : 'Unknown error',\n code: getErrorCode(err),\n });\n return;\n }\n\n if (err instanceof ConfigError) {\n output.error(err.message);\n } else if (err instanceof ApiError) {\n output.error(`API error: ${err.message}`);\n if (err.status !== 0) {\n output.dim(` Status: ${err.status}`);\n }\n } else if (err instanceof Error) {\n output.error(err.message);\n } else {\n output.error('An unknown error occurred');\n }\n}\n"],"mappings":"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","names":["json","z","agentId","path","program","program","handleError","getErrorCode","program","handleError","getErrorCode","program","handleError","getErrorCode"]}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@octavus/cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for validating and syncing Octavus agent definitions",
5
+ "license": "MIT",
6
+ "author": "Octavus AI <dev@octavus.ai>",
7
+ "keywords": [
8
+ "octavus",
9
+ "ai",
10
+ "agents",
11
+ "cli",
12
+ "sync",
13
+ "validate"
14
+ ],
15
+ "type": "module",
16
+ "bin": {
17
+ "octavus": "./dist/index.js"
18
+ },
19
+ "main": "./dist/index.js",
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "publishConfig": {
24
+ "access": "public"
25
+ },
26
+ "dependencies": {
27
+ "commander": "^13.1.0",
28
+ "dotenv": "^16.6.1",
29
+ "yaml": "^2.8.0",
30
+ "zod": "^4.1.13"
31
+ },
32
+ "devDependencies": {
33
+ "@types/node": "^22.0.0",
34
+ "tsup": "^8.3.5",
35
+ "typescript": "^5.6.3"
36
+ },
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "dev": "tsup --watch",
40
+ "lint": "eslint src/ --max-warnings 0",
41
+ "lint:fix": "eslint src/ --max-warnings 0 --fix",
42
+ "type-check": "tsc --noEmit",
43
+ "clean": "rm -rf dist .turbo"
44
+ }
45
+ }