@agentforge/cli 0.16.64 → 0.16.66

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.js CHANGED
@@ -1210,123 +1210,27 @@ async function toolTestCommand(name, options) {
1210
1210
  return exitWithCommandError(error, { spinnerFailureText: "Tests failed" });
1211
1211
  }
1212
1212
  }
1213
- async function toolPublishCommand(name, options) {
1214
- try {
1215
- logger.header("\u{1F4E6} Publish Tool");
1216
- logger.info(`Tool: ${chalk4.cyan(name)}`);
1217
- logger.info(`Tag: ${chalk4.cyan(options.tag || "latest")}`);
1218
- logger.info(`Dry run: ${options.dryRun ? "Yes" : "No"}`);
1219
- logger.newLine();
1220
- if (options.dryRun) {
1221
- logger.warn("Dry run mode - no actual publishing will occur");
1222
- logger.newLine();
1223
- }
1224
- const { toolPath, hasTestScript, hasBuildScript } = await resolveToolPath(name);
1225
- const packageManager = await detectPackageManager(toolPath);
1226
- if (hasTestScript) {
1227
- logger.startSpinner("Running tests...");
1228
- try {
1229
- await runScript(toolPath, "test", packageManager);
1230
- logger.succeedSpinner("Tests passed");
1231
- } catch (error) {
1232
- return exitWithCommandError(error, {
1233
- spinnerFailureText: "Tests failed",
1234
- message: "Cannot publish tool with failing tests"
1235
- });
1236
- }
1237
- } else {
1238
- logger.info("\u26A0\uFE0F Skipping tests (no test script found)");
1239
- }
1240
- if (hasBuildScript) {
1241
- logger.startSpinner("Building tool...");
1242
- try {
1243
- await runScript(toolPath, "build", packageManager);
1244
- logger.succeedSpinner("Build completed");
1245
- } catch (error) {
1246
- return exitWithCommandError(error, { spinnerFailureText: "Build failed" });
1247
- }
1248
- } else {
1249
- logger.info("\u26A0\uFE0F Skipping build (no build script found)");
1250
- }
1251
- logger.startSpinner(options.dryRun ? "Running dry-run publish..." : "Publishing to npm...");
1252
- try {
1253
- await publishPackage(toolPath, {
1254
- tag: options.tag,
1255
- access: "public",
1256
- dryRun: options.dryRun
1257
- });
1258
- if (options.dryRun) {
1259
- logger.succeedSpinner("Dry-run completed - no actual publishing occurred");
1260
- } else {
1261
- logger.succeedSpinner("Published to npm");
1262
- }
1263
- } catch (error) {
1264
- const errorMessage = getErrorMessage(error);
1265
- logger.failSpinner("Publishing failed");
1266
- if (errorMessage.includes("ENEEDAUTH") || errorMessage.includes("E401")) {
1267
- logger.error("Not authenticated with npm");
1268
- logger.info("Run: npm login");
1269
- } else if (errorMessage.includes("E403")) {
1270
- logger.error("Permission denied - you may not have access to publish this package");
1271
- logger.info("Check package name and npm organization permissions");
1272
- } else if (errorMessage.includes("EPUBLISHCONFLICT") || errorMessage.includes("E409")) {
1273
- logger.error("Version already published");
1274
- logger.info("Update the version in package.json before publishing");
1275
- } else {
1276
- logger.error(errorMessage);
1277
- }
1278
- return exitWithCommandError(error, {
1279
- logError: false
1280
- });
1281
- }
1282
- logger.newLine();
1283
- if (options.dryRun) {
1284
- logger.success(chalk4.bold.green("\u2728 Dry-run completed successfully!"));
1285
- logger.newLine();
1286
- logger.info("No changes were made. Remove --dry-run to publish for real.");
1287
- } else {
1288
- logger.success(chalk4.bold.green("\u2728 Tool published successfully!"));
1289
- logger.newLine();
1290
- logger.info(`Published ${chalk4.cyan(name)} with tag ${chalk4.cyan(options.tag || "latest")}`);
1291
- logger.info("Users can now install with: npm install " + name);
1292
- }
1293
- } catch (error) {
1294
- return exitWithCommandError(error, { spinnerFailureText: "Publishing failed" });
1295
- }
1296
- }
1297
1213
  async function resolveToolPath(name) {
1298
1214
  const cwd = process.cwd();
1299
1215
  const isScopedPackage = /^@[^/]+\/[^/]+$/.test(name);
1300
1216
  const isPath = !isScopedPackage && (name.includes("/") || name.includes("\\"));
1301
1217
  if (isPath) {
1302
1218
  const absolutePath = path12.isAbsolute(name) ? name : path12.resolve(cwd, name);
1303
- return await validateToolPath(absolutePath, name);
1219
+ return validateToolPath(absolutePath, name);
1304
1220
  }
1305
1221
  const cwdPackageJsonPath = path12.join(cwd, "package.json");
1306
1222
  if (await fs.pathExists(cwdPackageJsonPath)) {
1307
1223
  const cwdPackageJson = await fs.readJson(cwdPackageJsonPath);
1308
1224
  if (cwdPackageJson.name === name || cwdPackageJson.name === `@agentforge/${name}`) {
1309
- return await validateToolPath(cwd, name);
1225
+ return validateToolPath(cwd, name);
1310
1226
  }
1311
1227
  }
1312
- const unscopedName = isScopedPackage ? name.split("/")[1] : name;
1313
- const possiblePaths = [
1314
- path12.join(cwd, "tools", name),
1315
- path12.join(cwd, "packages", name),
1316
- path12.join(cwd, name)
1317
- ];
1318
- if (isScopedPackage) {
1319
- possiblePaths.push(
1320
- path12.join(cwd, "tools", unscopedName),
1321
- path12.join(cwd, "packages", unscopedName),
1322
- path12.join(cwd, unscopedName)
1323
- );
1324
- }
1228
+ const possiblePaths = buildPossiblePaths(cwd, name, isScopedPackage);
1325
1229
  for (const possiblePath of possiblePaths) {
1326
1230
  if (await fs.pathExists(possiblePath)) {
1327
1231
  const packageJsonPath = path12.join(possiblePath, "package.json");
1328
1232
  if (await fs.pathExists(packageJsonPath)) {
1329
- return await validateToolPath(possiblePath, name);
1233
+ return validateToolPath(possiblePath, name);
1330
1234
  }
1331
1235
  }
1332
1236
  }
@@ -1335,7 +1239,7 @@ async function resolveToolPath(name) {
1335
1239
  logger.info("Tried the following locations:");
1336
1240
  logger.list([
1337
1241
  `Current directory (${cwd})`,
1338
- ...possiblePaths.map((p) => path12.relative(cwd, p) || ".")
1242
+ ...possiblePaths.map((possiblePath) => path12.relative(cwd, possiblePath) || ".")
1339
1243
  ]);
1340
1244
  logger.newLine();
1341
1245
  logger.info("Make sure you are either:");
@@ -1346,6 +1250,22 @@ async function resolveToolPath(name) {
1346
1250
  ]);
1347
1251
  return exitWithCommandError(`Could not find tool package: ${name}`, { logError: false });
1348
1252
  }
1253
+ function buildPossiblePaths(cwd, name, isScopedPackage) {
1254
+ const possiblePaths = [
1255
+ path12.join(cwd, "tools", name),
1256
+ path12.join(cwd, "packages", name),
1257
+ path12.join(cwd, name)
1258
+ ];
1259
+ if (isScopedPackage) {
1260
+ const unscopedName = name.split("/")[1];
1261
+ possiblePaths.push(
1262
+ path12.join(cwd, "tools", unscopedName),
1263
+ path12.join(cwd, "packages", unscopedName),
1264
+ path12.join(cwd, unscopedName)
1265
+ );
1266
+ }
1267
+ return possiblePaths;
1268
+ }
1349
1269
  async function validateToolPath(toolPath, expectedName) {
1350
1270
  if (!await fs.pathExists(toolPath)) {
1351
1271
  return exitWithCommandError(`Tool directory not found: ${toolPath}`);
@@ -1364,20 +1284,136 @@ async function validateToolPath(toolPath, expectedName) {
1364
1284
  if (!packageJson.name) {
1365
1285
  return exitWithCommandError('package.json must have a "name" field');
1366
1286
  }
1367
- const packageName = packageJson.name;
1287
+ logPackageNameMismatch(expectedName, packageJson.name);
1288
+ return {
1289
+ toolPath,
1290
+ hasTestScript: !!packageJson.scripts?.test,
1291
+ hasBuildScript: !!packageJson.scripts?.build
1292
+ };
1293
+ }
1294
+ function logPackageNameMismatch(expectedName, packageName) {
1368
1295
  const nameMatches = packageName === expectedName || packageName === `@agentforge/${expectedName}` || packageName.endsWith(`/${expectedName}`);
1369
1296
  if (!nameMatches) {
1370
1297
  logger.warn(`Package name mismatch: expected ${chalk4.cyan(expectedName)}, found ${chalk4.cyan(packageName)}`);
1371
1298
  logger.info(`Publishing package: ${chalk4.cyan(packageName)}`);
1372
1299
  logger.newLine();
1373
1300
  }
1374
- const hasTestScript = !!packageJson.scripts?.test;
1375
- const hasBuildScript = !!packageJson.scripts?.build;
1376
- return {
1301
+ }
1302
+
1303
+ // src/commands/tool/publish-preflight.ts
1304
+ async function runPublishPreflight(toolPath, packageManager, toolInfo) {
1305
+ await runOptionalScript({
1306
+ enabled: toolInfo.hasTestScript,
1307
+ skipMessage: "\u26A0\uFE0F Skipping tests (no test script found)",
1308
+ startMessage: "Running tests...",
1309
+ successMessage: "Tests passed",
1310
+ scriptName: "test",
1377
1311
  toolPath,
1378
- hasTestScript,
1379
- hasBuildScript
1380
- };
1312
+ packageManager,
1313
+ failureOptions: {
1314
+ spinnerFailureText: "Tests failed",
1315
+ message: "Cannot publish tool with failing tests"
1316
+ }
1317
+ });
1318
+ await runOptionalScript({
1319
+ enabled: toolInfo.hasBuildScript,
1320
+ skipMessage: "\u26A0\uFE0F Skipping build (no build script found)",
1321
+ startMessage: "Building tool...",
1322
+ successMessage: "Build completed",
1323
+ scriptName: "build",
1324
+ toolPath,
1325
+ packageManager,
1326
+ failureOptions: {
1327
+ spinnerFailureText: "Build failed"
1328
+ }
1329
+ });
1330
+ }
1331
+ async function runOptionalScript(options) {
1332
+ if (!options.enabled) {
1333
+ logger.info(options.skipMessage);
1334
+ return;
1335
+ }
1336
+ logger.startSpinner(options.startMessage);
1337
+ try {
1338
+ await runScript(options.toolPath, options.scriptName, options.packageManager);
1339
+ logger.succeedSpinner(options.successMessage);
1340
+ } catch (error) {
1341
+ return exitWithCommandError(error, options.failureOptions);
1342
+ }
1343
+ }
1344
+ async function publishToolPackage(toolPath, options) {
1345
+ logger.startSpinner(options.dryRun ? "Running dry-run publish..." : "Publishing to npm...");
1346
+ try {
1347
+ await publishPackage(toolPath, {
1348
+ tag: options.tag,
1349
+ access: "public",
1350
+ dryRun: options.dryRun
1351
+ });
1352
+ logger.succeedSpinner(
1353
+ options.dryRun ? "Dry-run completed - no actual publishing occurred" : "Published to npm"
1354
+ );
1355
+ } catch (error) {
1356
+ const errorMessage = getErrorMessage(error);
1357
+ logger.failSpinner("Publishing failed");
1358
+ logPublishError(errorMessage);
1359
+ return exitWithCommandError(error, { logError: false });
1360
+ }
1361
+ }
1362
+ function logPublishSummary(name, options) {
1363
+ logger.newLine();
1364
+ if (options.dryRun) {
1365
+ logger.success(chalk4.bold.green("\u2728 Dry-run completed successfully!"));
1366
+ logger.newLine();
1367
+ logger.info("No changes were made. Remove --dry-run to publish for real.");
1368
+ return;
1369
+ }
1370
+ logger.success(chalk4.bold.green("\u2728 Tool published successfully!"));
1371
+ logger.newLine();
1372
+ logger.info(`Published ${chalk4.cyan(name)} with tag ${chalk4.cyan(options.tag || "latest")}`);
1373
+ logger.info("Users can now install with: npm install " + name);
1374
+ }
1375
+ function logPublishError(errorMessage) {
1376
+ if (errorMessage.includes("ENEEDAUTH") || errorMessage.includes("E401")) {
1377
+ logger.error("Not authenticated with npm");
1378
+ logger.info("Run: npm login");
1379
+ return;
1380
+ }
1381
+ if (errorMessage.includes("E403")) {
1382
+ logger.error("Permission denied - you may not have access to publish this package");
1383
+ logger.info("Check package name and npm organization permissions");
1384
+ return;
1385
+ }
1386
+ if (errorMessage.includes("EPUBLISHCONFLICT") || errorMessage.includes("E409")) {
1387
+ logger.error("Version already published");
1388
+ logger.info("Update the version in package.json before publishing");
1389
+ return;
1390
+ }
1391
+ logger.error(errorMessage);
1392
+ }
1393
+
1394
+ // src/commands/tool/publish.ts
1395
+ async function toolPublishCommand(name, options) {
1396
+ try {
1397
+ logPublishHeader(name, options);
1398
+ const toolInfo = await resolveToolPath(name);
1399
+ const packageManager = await detectPackageManager(toolInfo.toolPath);
1400
+ await runPublishPreflight(toolInfo.toolPath, packageManager, toolInfo);
1401
+ await publishToolPackage(toolInfo.toolPath, options);
1402
+ logPublishSummary(name, options);
1403
+ } catch (error) {
1404
+ return exitWithCommandError(error, { spinnerFailureText: "Publishing failed" });
1405
+ }
1406
+ }
1407
+ function logPublishHeader(name, options) {
1408
+ logger.header("\u{1F4E6} Publish Tool");
1409
+ logger.info(`Tool: ${chalk4.cyan(name)}`);
1410
+ logger.info(`Tag: ${chalk4.cyan(options.tag || "latest")}`);
1411
+ logger.info(`Dry run: ${options.dryRun ? "Yes" : "No"}`);
1412
+ logger.newLine();
1413
+ if (options.dryRun) {
1414
+ logger.warn("Dry run mode - no actual publishing will occur");
1415
+ logger.newLine();
1416
+ }
1381
1417
  }
1382
1418
 
1383
1419
  // src/index.ts