@agentforge/cli 0.16.3 → 0.16.4
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/index.cjs +69 -64
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +69 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/templates/api/package.json +2 -2
- package/templates/cli/package.json +2 -2
- package/templates/full/package.json +2 -2
- package/templates/minimal/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -75,6 +75,30 @@ var Logger = class {
|
|
|
75
75
|
}
|
|
76
76
|
};
|
|
77
77
|
var logger = new Logger();
|
|
78
|
+
|
|
79
|
+
// src/utils/command-errors.ts
|
|
80
|
+
function getErrorMessage(error) {
|
|
81
|
+
if (error instanceof Error) {
|
|
82
|
+
return error.message;
|
|
83
|
+
}
|
|
84
|
+
if (typeof error === "string") {
|
|
85
|
+
return error;
|
|
86
|
+
}
|
|
87
|
+
if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") {
|
|
88
|
+
return error.message;
|
|
89
|
+
}
|
|
90
|
+
return String(error);
|
|
91
|
+
}
|
|
92
|
+
function exitWithCommandError(error, options = {}) {
|
|
93
|
+
if (options.spinnerFailureText) {
|
|
94
|
+
logger.failSpinner(options.spinnerFailureText);
|
|
95
|
+
}
|
|
96
|
+
if (options.logError !== false) {
|
|
97
|
+
const message = options.message ?? getErrorMessage(error);
|
|
98
|
+
logger.error(options.prefix ? `${options.prefix}: ${message}` : message);
|
|
99
|
+
}
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
78
102
|
async function promptProjectSetup(defaults = {}) {
|
|
79
103
|
return inquirer.prompt([
|
|
80
104
|
{
|
|
@@ -434,13 +458,11 @@ async function createCommand(projectName, options) {
|
|
|
434
458
|
try {
|
|
435
459
|
logger.header("\u{1F680} Create AgentForge Project");
|
|
436
460
|
if (!projectName) {
|
|
437
|
-
|
|
438
|
-
process.exit(1);
|
|
461
|
+
return exitWithCommandError("Project name is required");
|
|
439
462
|
}
|
|
440
463
|
const targetPath = path12.join(process.cwd(), projectName);
|
|
441
464
|
if (!await isEmptyDir(targetPath)) {
|
|
442
|
-
|
|
443
|
-
process.exit(1);
|
|
465
|
+
return exitWithCommandError(`Directory ${projectName} already exists and is not empty`);
|
|
444
466
|
}
|
|
445
467
|
const answers = await promptProjectSetup({
|
|
446
468
|
projectName,
|
|
@@ -483,7 +505,7 @@ async function createCommand(projectName, options) {
|
|
|
483
505
|
try {
|
|
484
506
|
await installDependencies(targetPath, answers.packageManager);
|
|
485
507
|
logger.succeedSpinner("Dependencies installed");
|
|
486
|
-
} catch
|
|
508
|
+
} catch {
|
|
487
509
|
logger.failSpinner("Failed to install dependencies");
|
|
488
510
|
logger.warn("You can install them manually later");
|
|
489
511
|
}
|
|
@@ -494,7 +516,7 @@ async function createCommand(projectName, options) {
|
|
|
494
516
|
await initGitRepository(targetPath);
|
|
495
517
|
await createInitialCommit(targetPath);
|
|
496
518
|
logger.succeedSpinner("Git repository initialized");
|
|
497
|
-
} catch
|
|
519
|
+
} catch {
|
|
498
520
|
logger.failSpinner("Failed to initialize git");
|
|
499
521
|
logger.warn("You can initialize it manually later");
|
|
500
522
|
}
|
|
@@ -510,8 +532,7 @@ async function createCommand(projectName, options) {
|
|
|
510
532
|
logger.newLine();
|
|
511
533
|
logger.info("Happy coding! \u{1F389}");
|
|
512
534
|
} catch (error) {
|
|
513
|
-
|
|
514
|
-
process.exit(1);
|
|
535
|
+
return exitWithCommandError(error, { prefix: "Failed to create project" });
|
|
515
536
|
}
|
|
516
537
|
}
|
|
517
538
|
|
|
@@ -531,9 +552,9 @@ async function devCommand(options) {
|
|
|
531
552
|
await runScript(cwd, "dev", packageManager);
|
|
532
553
|
logger.succeedSpinner("Development server started");
|
|
533
554
|
} catch (error) {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
555
|
+
return exitWithCommandError(error, {
|
|
556
|
+
spinnerFailureText: "Failed to start development server"
|
|
557
|
+
});
|
|
537
558
|
}
|
|
538
559
|
}
|
|
539
560
|
|
|
@@ -559,9 +580,7 @@ async function buildCommand(options) {
|
|
|
559
580
|
logger.newLine();
|
|
560
581
|
logger.success("\u2728 Production build ready!");
|
|
561
582
|
} catch (error) {
|
|
562
|
-
|
|
563
|
-
logger.error(error.message);
|
|
564
|
-
process.exit(1);
|
|
583
|
+
return exitWithCommandError(error, { spinnerFailureText: "Build failed" });
|
|
565
584
|
}
|
|
566
585
|
}
|
|
567
586
|
|
|
@@ -587,9 +606,7 @@ async function testCommand(options) {
|
|
|
587
606
|
await runScript(cwd, script, packageManager);
|
|
588
607
|
logger.succeedSpinner("Tests completed");
|
|
589
608
|
} catch (error) {
|
|
590
|
-
|
|
591
|
-
logger.error(error.message);
|
|
592
|
-
process.exit(1);
|
|
609
|
+
return exitWithCommandError(error, { spinnerFailureText: "Tests failed" });
|
|
593
610
|
}
|
|
594
611
|
}
|
|
595
612
|
|
|
@@ -606,7 +623,7 @@ async function lintCommand(options) {
|
|
|
606
623
|
try {
|
|
607
624
|
await runScript(cwd, options.fix ? "lint:fix" : "lint", packageManager);
|
|
608
625
|
logger.succeedSpinner("Linting completed");
|
|
609
|
-
} catch
|
|
626
|
+
} catch {
|
|
610
627
|
logger.failSpinner("Linting found issues");
|
|
611
628
|
if (!options.fix) {
|
|
612
629
|
logger.info("Run with --fix to automatically fix issues");
|
|
@@ -617,15 +634,14 @@ async function lintCommand(options) {
|
|
|
617
634
|
try {
|
|
618
635
|
await runScript(cwd, "format", packageManager);
|
|
619
636
|
logger.succeedSpinner("Formatting completed");
|
|
620
|
-
} catch
|
|
637
|
+
} catch {
|
|
621
638
|
logger.failSpinner("Formatting failed");
|
|
622
639
|
}
|
|
623
640
|
}
|
|
624
641
|
logger.newLine();
|
|
625
642
|
logger.success("\u2728 Code quality check completed!");
|
|
626
643
|
} catch (error) {
|
|
627
|
-
|
|
628
|
-
process.exit(1);
|
|
644
|
+
return exitWithCommandError(error);
|
|
629
645
|
}
|
|
630
646
|
}
|
|
631
647
|
async function agentCreateCommand(name, options) {
|
|
@@ -666,8 +682,7 @@ async function agentCreateCommand(name, options) {
|
|
|
666
682
|
answers.generateTests ? `Run ${chalk4.cyan(`pnpm test tests/agents/${answers.name}.test.ts`)} to test your agent` : ""
|
|
667
683
|
].filter(Boolean));
|
|
668
684
|
} catch (error) {
|
|
669
|
-
|
|
670
|
-
process.exit(1);
|
|
685
|
+
return exitWithCommandError(error, { prefix: "Failed to create agent" });
|
|
671
686
|
}
|
|
672
687
|
}
|
|
673
688
|
function generateAgentContent(name, pattern, description) {
|
|
@@ -850,8 +865,7 @@ async function agentCreateReusableCommand(name, options) {
|
|
|
850
865
|
logger.newLine();
|
|
851
866
|
logger.info(chalk4.gray("\u{1F4A1} Tip: See examples/vertical-agents/ for reference implementations"));
|
|
852
867
|
} catch (error) {
|
|
853
|
-
|
|
854
|
-
process.exit(1);
|
|
868
|
+
return exitWithCommandError(error, { prefix: "Failed to create reusable agent" });
|
|
855
869
|
}
|
|
856
870
|
}
|
|
857
871
|
function kebabToPascal(str) {
|
|
@@ -899,8 +913,7 @@ async function agentListCommand(options) {
|
|
|
899
913
|
logger.info(`Use ${chalk4.cyan("--verbose")} for more details`);
|
|
900
914
|
}
|
|
901
915
|
} catch (error) {
|
|
902
|
-
|
|
903
|
-
process.exit(1);
|
|
916
|
+
return exitWithCommandError(error, { prefix: "Failed to list agents" });
|
|
904
917
|
}
|
|
905
918
|
}
|
|
906
919
|
function extractPattern(content) {
|
|
@@ -924,7 +937,7 @@ async function agentTestCommand(name, options) {
|
|
|
924
937
|
if (!await pathExists(testFile)) {
|
|
925
938
|
logger.error(`Test file not found: ${testFile}`);
|
|
926
939
|
logger.info(`Create tests with: ${chalk4.cyan(`agentforge agent:create ${name} --test`)}`);
|
|
927
|
-
|
|
940
|
+
return exitWithCommandError(`Test file not found: ${testFile}`, { logError: false });
|
|
928
941
|
}
|
|
929
942
|
logger.info(`Testing agent: ${chalk4.cyan(name)}`);
|
|
930
943
|
logger.info(`Watch mode: ${options.watch ? "Yes" : "No"}`);
|
|
@@ -936,9 +949,7 @@ async function agentTestCommand(name, options) {
|
|
|
936
949
|
await runScript(cwd, testCommand2, packageManager);
|
|
937
950
|
logger.succeedSpinner("Tests completed");
|
|
938
951
|
} catch (error) {
|
|
939
|
-
|
|
940
|
-
logger.error(error.message);
|
|
941
|
-
process.exit(1);
|
|
952
|
+
return exitWithCommandError(error, { spinnerFailureText: "Tests failed" });
|
|
942
953
|
}
|
|
943
954
|
}
|
|
944
955
|
async function agentDeployCommand(name, options) {
|
|
@@ -972,10 +983,11 @@ async function agentDeployCommand(name, options) {
|
|
|
972
983
|
logger.newLine();
|
|
973
984
|
logger.info(chalk4.dim("For detailed deployment guides, see:"));
|
|
974
985
|
logger.info(chalk4.dim("https://tvscoundrel.github.io/agentforge/guide/advanced/deployment"));
|
|
975
|
-
|
|
986
|
+
return exitWithCommandError("Automated agent deployment is not yet implemented", {
|
|
987
|
+
logError: false
|
|
988
|
+
});
|
|
976
989
|
} catch (error) {
|
|
977
|
-
|
|
978
|
-
process.exit(1);
|
|
990
|
+
return exitWithCommandError(error);
|
|
979
991
|
}
|
|
980
992
|
}
|
|
981
993
|
async function toolCreateCommand(name, options) {
|
|
@@ -1016,8 +1028,7 @@ async function toolCreateCommand(name, options) {
|
|
|
1016
1028
|
];
|
|
1017
1029
|
logger.list(nextSteps.filter(Boolean));
|
|
1018
1030
|
} catch (error) {
|
|
1019
|
-
|
|
1020
|
-
process.exit(1);
|
|
1031
|
+
return exitWithCommandError(error, { prefix: "Failed to create tool" });
|
|
1021
1032
|
}
|
|
1022
1033
|
}
|
|
1023
1034
|
function generateToolContent(name, category, description) {
|
|
@@ -1165,8 +1176,7 @@ async function toolListCommand(options) {
|
|
|
1165
1176
|
logger.info(`Use ${chalk4.cyan("--verbose")} for more details`);
|
|
1166
1177
|
}
|
|
1167
1178
|
} catch (error) {
|
|
1168
|
-
|
|
1169
|
-
process.exit(1);
|
|
1179
|
+
return exitWithCommandError(error, { prefix: "Failed to list tools" });
|
|
1170
1180
|
}
|
|
1171
1181
|
}
|
|
1172
1182
|
function extractCategory(content) {
|
|
@@ -1185,7 +1195,7 @@ async function toolTestCommand(name, options) {
|
|
|
1185
1195
|
if (!await pathExists(testFile)) {
|
|
1186
1196
|
logger.error(`Test file not found: ${testFile}`);
|
|
1187
1197
|
logger.info(`Create tests with: ${chalk4.cyan(`agentforge tool:create ${name} --test`)}`);
|
|
1188
|
-
|
|
1198
|
+
return exitWithCommandError(`Test file not found: ${testFile}`, { logError: false });
|
|
1189
1199
|
}
|
|
1190
1200
|
logger.info(`Testing tool: ${chalk4.cyan(name)}`);
|
|
1191
1201
|
logger.info(`Watch mode: ${options.watch ? "Yes" : "No"}`);
|
|
@@ -1197,9 +1207,7 @@ async function toolTestCommand(name, options) {
|
|
|
1197
1207
|
await runScript(cwd, testCommand2, packageManager);
|
|
1198
1208
|
logger.succeedSpinner("Tests completed");
|
|
1199
1209
|
} catch (error) {
|
|
1200
|
-
|
|
1201
|
-
logger.error(error.message);
|
|
1202
|
-
process.exit(1);
|
|
1210
|
+
return exitWithCommandError(error, { spinnerFailureText: "Tests failed" });
|
|
1203
1211
|
}
|
|
1204
1212
|
}
|
|
1205
1213
|
async function toolPublishCommand(name, options) {
|
|
@@ -1221,9 +1229,10 @@ async function toolPublishCommand(name, options) {
|
|
|
1221
1229
|
await runScript(toolPath, "test", packageManager);
|
|
1222
1230
|
logger.succeedSpinner("Tests passed");
|
|
1223
1231
|
} catch (error) {
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1232
|
+
return exitWithCommandError(error, {
|
|
1233
|
+
spinnerFailureText: "Tests failed",
|
|
1234
|
+
message: "Cannot publish tool with failing tests"
|
|
1235
|
+
});
|
|
1227
1236
|
}
|
|
1228
1237
|
} else {
|
|
1229
1238
|
logger.info("\u26A0\uFE0F Skipping tests (no test script found)");
|
|
@@ -1234,8 +1243,7 @@ async function toolPublishCommand(name, options) {
|
|
|
1234
1243
|
await runScript(toolPath, "build", packageManager);
|
|
1235
1244
|
logger.succeedSpinner("Build completed");
|
|
1236
1245
|
} catch (error) {
|
|
1237
|
-
|
|
1238
|
-
process.exit(1);
|
|
1246
|
+
return exitWithCommandError(error, { spinnerFailureText: "Build failed" });
|
|
1239
1247
|
}
|
|
1240
1248
|
} else {
|
|
1241
1249
|
logger.info("\u26A0\uFE0F Skipping build (no build script found)");
|
|
@@ -1253,20 +1261,23 @@ async function toolPublishCommand(name, options) {
|
|
|
1253
1261
|
logger.succeedSpinner("Published to npm");
|
|
1254
1262
|
}
|
|
1255
1263
|
} catch (error) {
|
|
1264
|
+
const errorMessage = getErrorMessage(error);
|
|
1256
1265
|
logger.failSpinner("Publishing failed");
|
|
1257
|
-
if (
|
|
1266
|
+
if (errorMessage.includes("ENEEDAUTH") || errorMessage.includes("E401")) {
|
|
1258
1267
|
logger.error("Not authenticated with npm");
|
|
1259
1268
|
logger.info("Run: npm login");
|
|
1260
|
-
} else if (
|
|
1269
|
+
} else if (errorMessage.includes("E403")) {
|
|
1261
1270
|
logger.error("Permission denied - you may not have access to publish this package");
|
|
1262
1271
|
logger.info("Check package name and npm organization permissions");
|
|
1263
|
-
} else if (
|
|
1272
|
+
} else if (errorMessage.includes("EPUBLISHCONFLICT") || errorMessage.includes("E409")) {
|
|
1264
1273
|
logger.error("Version already published");
|
|
1265
1274
|
logger.info("Update the version in package.json before publishing");
|
|
1266
1275
|
} else {
|
|
1267
|
-
logger.error(
|
|
1276
|
+
logger.error(errorMessage);
|
|
1268
1277
|
}
|
|
1269
|
-
|
|
1278
|
+
return exitWithCommandError(error, {
|
|
1279
|
+
logError: false
|
|
1280
|
+
});
|
|
1270
1281
|
}
|
|
1271
1282
|
logger.newLine();
|
|
1272
1283
|
if (options.dryRun) {
|
|
@@ -1280,9 +1291,7 @@ async function toolPublishCommand(name, options) {
|
|
|
1280
1291
|
logger.info("Users can now install with: npm install " + name);
|
|
1281
1292
|
}
|
|
1282
1293
|
} catch (error) {
|
|
1283
|
-
|
|
1284
|
-
logger.error(error.message);
|
|
1285
|
-
process.exit(1);
|
|
1294
|
+
return exitWithCommandError(error, { spinnerFailureText: "Publishing failed" });
|
|
1286
1295
|
}
|
|
1287
1296
|
}
|
|
1288
1297
|
async function resolveToolPath(name) {
|
|
@@ -1335,29 +1344,25 @@ async function resolveToolPath(name) {
|
|
|
1335
1344
|
"Providing a path to the tool package directory",
|
|
1336
1345
|
"Have the tool in a standard location (./tools/<name>, ./packages/<name>)"
|
|
1337
1346
|
]);
|
|
1338
|
-
|
|
1347
|
+
return exitWithCommandError(`Could not find tool package: ${name}`, { logError: false });
|
|
1339
1348
|
}
|
|
1340
1349
|
async function validateToolPath(toolPath, expectedName) {
|
|
1341
1350
|
if (!await fs.pathExists(toolPath)) {
|
|
1342
|
-
|
|
1343
|
-
process.exit(1);
|
|
1351
|
+
return exitWithCommandError(`Tool directory not found: ${toolPath}`);
|
|
1344
1352
|
}
|
|
1345
1353
|
const packageJsonPath = path12.join(toolPath, "package.json");
|
|
1346
1354
|
if (!await fs.pathExists(packageJsonPath)) {
|
|
1347
|
-
logger.error(`package.json not found in: ${toolPath}`);
|
|
1348
1355
|
logger.info("Tool packages must have a package.json file");
|
|
1349
|
-
|
|
1356
|
+
return exitWithCommandError(`package.json not found in: ${toolPath}`);
|
|
1350
1357
|
}
|
|
1351
1358
|
let packageJson;
|
|
1352
1359
|
try {
|
|
1353
1360
|
packageJson = await fs.readJson(packageJsonPath);
|
|
1354
1361
|
} catch (error) {
|
|
1355
|
-
|
|
1356
|
-
process.exit(1);
|
|
1362
|
+
return exitWithCommandError(error, { prefix: "Failed to read package.json" });
|
|
1357
1363
|
}
|
|
1358
1364
|
if (!packageJson.name) {
|
|
1359
|
-
|
|
1360
|
-
process.exit(1);
|
|
1365
|
+
return exitWithCommandError('package.json must have a "name" field');
|
|
1361
1366
|
}
|
|
1362
1367
|
const packageName = packageJson.name;
|
|
1363
1368
|
const nameMatches = packageName === expectedName || packageName === `@agentforge/${expectedName}` || packageName.endsWith(`/${expectedName}`);
|