@agentforge/cli 0.18.1 → 0.18.3

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 CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  var commander = require('commander');
4
4
  var chalk4 = require('chalk');
5
- var path12 = require('path');
5
+ var path11 = require('path');
6
6
  var ora = require('ora');
7
7
  var inquirer = require('inquirer');
8
8
  var fs = require('fs-extra');
@@ -14,7 +14,7 @@ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentS
14
14
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
15
15
 
16
16
  var chalk4__default = /*#__PURE__*/_interopDefault(chalk4);
17
- var path12__default = /*#__PURE__*/_interopDefault(path12);
17
+ var path11__default = /*#__PURE__*/_interopDefault(path11);
18
18
  var ora__default = /*#__PURE__*/_interopDefault(ora);
19
19
  var inquirer__default = /*#__PURE__*/_interopDefault(inquirer);
20
20
  var fs__default = /*#__PURE__*/_interopDefault(fs);
@@ -285,7 +285,7 @@ async function promptToolSetup(defaults = {}) {
285
285
  };
286
286
  }
287
287
  var __filename$1 = url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
288
- var __dirname$1 = path12__default.default.dirname(__filename$1);
288
+ var __dirname$1 = path11__default.default.dirname(__filename$1);
289
289
  async function ensureDir(dir) {
290
290
  await fs__default.default.ensureDir(dir);
291
291
  }
@@ -303,9 +303,9 @@ async function copyTemplate(templatePath, targetPath, replacements = {}) {
303
303
  throw new Error(`No files found in template: ${templatePath}`);
304
304
  }
305
305
  for (const file of files) {
306
- const sourcePath = path12__default.default.join(templatePath, file);
307
- const destPath = path12__default.default.join(targetPath, file);
308
- await fs__default.default.ensureDir(path12__default.default.dirname(destPath));
306
+ const sourcePath = path11__default.default.join(templatePath, file);
307
+ const destPath = path11__default.default.join(targetPath, file);
308
+ await fs__default.default.ensureDir(path11__default.default.dirname(destPath));
309
309
  let content = await fs__default.default.readFile(sourcePath, "utf-8");
310
310
  for (const [key, value] of Object.entries(replacements)) {
311
311
  content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
@@ -329,11 +329,11 @@ async function readFile(filePath) {
329
329
  return fs__default.default.readFile(filePath, "utf-8");
330
330
  }
331
331
  async function writeFile(filePath, content) {
332
- await fs__default.default.ensureDir(path12__default.default.dirname(filePath));
332
+ await fs__default.default.ensureDir(path11__default.default.dirname(filePath));
333
333
  await fs__default.default.writeFile(filePath, content);
334
334
  }
335
335
  function getTemplatePath(template) {
336
- return path12__default.default.join(__dirname$1, "..", "templates", template);
336
+ return path11__default.default.join(__dirname$1, "..", "templates", template);
337
337
  }
338
338
  async function isEmptyDir(dir) {
339
339
  if (!await pathExists(dir)) {
@@ -343,13 +343,13 @@ async function isEmptyDir(dir) {
343
343
  return files.length === 0;
344
344
  }
345
345
  async function detectPackageManager(cwd = process.cwd()) {
346
- if (await fs__default.default.pathExists(path12__default.default.join(cwd, "pnpm-lock.yaml"))) {
346
+ if (await fs__default.default.pathExists(path11__default.default.join(cwd, "pnpm-lock.yaml"))) {
347
347
  return "pnpm";
348
348
  }
349
- if (await fs__default.default.pathExists(path12__default.default.join(cwd, "yarn.lock"))) {
349
+ if (await fs__default.default.pathExists(path11__default.default.join(cwd, "yarn.lock"))) {
350
350
  return "yarn";
351
351
  }
352
- if (await fs__default.default.pathExists(path12__default.default.join(cwd, "package-lock.json"))) {
352
+ if (await fs__default.default.pathExists(path11__default.default.join(cwd, "package-lock.json"))) {
353
353
  return "npm";
354
354
  }
355
355
  try {
@@ -457,7 +457,7 @@ pnpm-debug.log*
457
457
  .temp/
458
458
  .tmp/
459
459
  `;
460
- await fs__default.default.writeFile(path12__default.default.join(cwd, ".gitignore"), gitignore);
460
+ await fs__default.default.writeFile(path11__default.default.join(cwd, ".gitignore"), gitignore);
461
461
  }
462
462
  async function createInitialCommit(cwd) {
463
463
  await execa.execa("git", ["add", "."], { cwd });
@@ -471,7 +471,7 @@ async function createCommand(projectName, options) {
471
471
  if (!projectName) {
472
472
  return exitWithCommandError("Project name is required");
473
473
  }
474
- const targetPath = path12__default.default.join(process.cwd(), projectName);
474
+ const targetPath = path11__default.default.join(process.cwd(), projectName);
475
475
  if (!await isEmptyDir(targetPath)) {
476
476
  return exitWithCommandError(`Directory ${projectName} already exists and is not empty`);
477
477
  }
@@ -500,7 +500,7 @@ async function createCommand(projectName, options) {
500
500
  });
501
501
  logger.succeedSpinner("Template files copied");
502
502
  logger.startSpinner("Updating package.json...");
503
- const packageJsonPath = path12__default.default.join(targetPath, "package.json");
503
+ const packageJsonPath = path11__default.default.join(targetPath, "package.json");
504
504
  const packageJson = await readJson(packageJsonPath);
505
505
  packageJson.name = answers.projectName;
506
506
  if (answers.author) {
@@ -668,8 +668,8 @@ async function agentCreateCommand(name, options) {
668
668
  logger.info(`Pattern: ${chalk4__default.default.cyan(answers.pattern)}`);
669
669
  logger.newLine();
670
670
  const cwd = process.cwd();
671
- const agentDir = path12__default.default.join(cwd, "src", "agents");
672
- const agentFile = path12__default.default.join(agentDir, `${answers.name}.ts`);
671
+ const agentDir = path11__default.default.join(cwd, "src", "agents");
672
+ const agentFile = path11__default.default.join(agentDir, `${answers.name}.ts`);
673
673
  logger.startSpinner("Creating agent file...");
674
674
  await ensureDir(agentDir);
675
675
  const agentContent = generateAgentContent(answers.name, answers.pattern, answers.description);
@@ -677,8 +677,8 @@ async function agentCreateCommand(name, options) {
677
677
  logger.succeedSpinner("Agent file created");
678
678
  if (answers.generateTests) {
679
679
  logger.startSpinner("Creating test file...");
680
- const testDir = path12__default.default.join(cwd, "tests", "agents");
681
- const testFile = path12__default.default.join(testDir, `${answers.name}.test.ts`);
680
+ const testDir = path11__default.default.join(cwd, "tests", "agents");
681
+ const testFile = path11__default.default.join(testDir, `${answers.name}.test.ts`);
682
682
  await ensureDir(testDir);
683
683
  const testContent = generateTestContent(answers.name, answers.pattern);
684
684
  await writeFile(testFile, testContent);
@@ -836,7 +836,7 @@ async function agentCreateReusableCommand(name, options) {
836
836
  logger.info(`Description: ${chalk4__default.default.gray(answers.description)}`);
837
837
  logger.newLine();
838
838
  const cwd = process.cwd();
839
- const agentDir = path12__default.default.join(cwd, answers.name);
839
+ const agentDir = path11__default.default.join(cwd, answers.name);
840
840
  const agentNameKebab = answers.name;
841
841
  const agentNamePascal = kebabToPascal(agentNameKebab);
842
842
  const agentNameCamel = kebabToCamel(agentNameKebab);
@@ -855,10 +855,10 @@ async function agentCreateReusableCommand(name, options) {
855
855
  logger.succeedSpinner("Agent structure created");
856
856
  logger.startSpinner("Organizing files...");
857
857
  const fs5 = await import('fs-extra');
858
- const srcDir = path12__default.default.join(agentDir, "src");
858
+ const srcDir = path11__default.default.join(agentDir, "src");
859
859
  await fs5.ensureDir(srcDir);
860
- await fs5.move(path12__default.default.join(agentDir, "index.ts"), path12__default.default.join(srcDir, "index.ts"));
861
- await fs5.move(path12__default.default.join(agentDir, "index.test.ts"), path12__default.default.join(srcDir, "index.test.ts"));
860
+ await fs5.move(path11__default.default.join(agentDir, "index.ts"), path11__default.default.join(srcDir, "index.ts"));
861
+ await fs5.move(path11__default.default.join(agentDir, "index.test.ts"), path11__default.default.join(srcDir, "index.test.ts"));
862
862
  logger.succeedSpinner("Files organized");
863
863
  logger.newLine();
864
864
  logger.success(chalk4__default.default.bold.green("\u2728 Reusable agent created successfully!"));
@@ -890,7 +890,7 @@ async function agentListCommand(options) {
890
890
  try {
891
891
  logger.header("\u{1F4CB} List Agents");
892
892
  const cwd = process.cwd();
893
- const agentDir = path12__default.default.join(cwd, "src", "agents");
893
+ const agentDir = path11__default.default.join(cwd, "src", "agents");
894
894
  const agentFiles = await findFiles("*.ts", agentDir);
895
895
  if (agentFiles.length === 0) {
896
896
  logger.warn("No agents found");
@@ -900,8 +900,8 @@ async function agentListCommand(options) {
900
900
  logger.info(`Found ${chalk4__default.default.cyan(agentFiles.length)} agent(s):
901
901
  `);
902
902
  for (const file of agentFiles) {
903
- const agentName = path12__default.default.basename(file, ".ts");
904
- const agentPath = path12__default.default.join(agentDir, file);
903
+ const agentName = path11__default.default.basename(file, ".ts");
904
+ const agentPath = path11__default.default.join(agentDir, file);
905
905
  if (options.verbose) {
906
906
  const content = await readFile(agentPath);
907
907
  const pattern = extractPattern(content);
@@ -940,17 +940,17 @@ function extractDescription(content) {
940
940
  const match = content.match(/\/\*\*\s*\n\s*\*\s*(.+?)\s*\n/);
941
941
  return match ? match[1] : null;
942
942
  }
943
- async function agentTestCommand(name, options) {
943
+ async function runNamedTestCommand(name, options, convention) {
944
944
  try {
945
- logger.header("\u{1F9EA} Test Agent");
945
+ logger.header(`\u{1F9EA} Test ${convention.noun}`);
946
946
  const cwd = process.cwd();
947
- const testFile = path12__default.default.join(cwd, "tests", "agents", `${name}.test.ts`);
947
+ const testFile = path11__default.default.join(cwd, "tests", convention.testDirectory, `${name}.test.ts`);
948
948
  if (!await pathExists(testFile)) {
949
949
  logger.error(`Test file not found: ${testFile}`);
950
- logger.info(`Create tests with: ${chalk4__default.default.cyan(`agentforge agent:create ${name} --test`)}`);
950
+ logger.info(`Create tests with: ${chalk4__default.default.cyan(convention.creationHint)}`);
951
951
  return exitWithCommandError(`Test file not found: ${testFile}`, { logError: false });
952
952
  }
953
- logger.info(`Testing agent: ${chalk4__default.default.cyan(name)}`);
953
+ logger.info(`Testing ${convention.noun.toLowerCase()}: ${chalk4__default.default.cyan(name)}`);
954
954
  logger.info(`Watch mode: ${options.watch ? "Yes" : "No"}`);
955
955
  logger.newLine();
956
956
  const packageManager = await detectPackageManager(cwd);
@@ -963,6 +963,15 @@ async function agentTestCommand(name, options) {
963
963
  return exitWithCommandError(error, { spinnerFailureText: "Tests failed" });
964
964
  }
965
965
  }
966
+
967
+ // src/commands/agent/test.ts
968
+ async function agentTestCommand(name, options) {
969
+ return runNamedTestCommand(name, options, {
970
+ noun: "Agent",
971
+ testDirectory: "agents",
972
+ creationHint: `agentforge agent:create ${name} --test`
973
+ });
974
+ }
966
975
  async function agentDeployCommand(name, options) {
967
976
  try {
968
977
  logger.header("\u{1F680} Deploy Agent");
@@ -1093,8 +1102,8 @@ function capitalize2(str) {
1093
1102
  return str.charAt(0).toUpperCase() + str.slice(1);
1094
1103
  }
1095
1104
  async function createSingleFileTool(cwd, answers) {
1096
- const toolDir = path12__default.default.join(cwd, "src", "tools");
1097
- const toolFile = path12__default.default.join(toolDir, `${answers.name}.ts`);
1105
+ const toolDir = path11__default.default.join(cwd, "src", "tools");
1106
+ const toolFile = path11__default.default.join(toolDir, `${answers.name}.ts`);
1098
1107
  logger.startSpinner("Creating tool file...");
1099
1108
  await ensureDir(toolDir);
1100
1109
  const toolContent = generateToolContent(answers.name, answers.category, answers.description);
@@ -1102,8 +1111,8 @@ async function createSingleFileTool(cwd, answers) {
1102
1111
  logger.succeedSpinner("Tool file created");
1103
1112
  if (answers.generateTests) {
1104
1113
  logger.startSpinner("Creating test file...");
1105
- const testDir = path12__default.default.join(cwd, "tests", "tools");
1106
- const testFile = path12__default.default.join(testDir, `${answers.name}.test.ts`);
1114
+ const testDir = path11__default.default.join(cwd, "tests", "tools");
1115
+ const testFile = path11__default.default.join(testDir, `${answers.name}.test.ts`);
1107
1116
  await ensureDir(testDir);
1108
1117
  const testContent = generateTestContent2(answers.name);
1109
1118
  await writeFile(testFile, testContent);
@@ -1111,7 +1120,7 @@ async function createSingleFileTool(cwd, answers) {
1111
1120
  }
1112
1121
  }
1113
1122
  async function createMultiFileTool(cwd, answers) {
1114
- const toolDir = path12__default.default.join(cwd, "src", "tools", answers.name);
1123
+ const toolDir = path11__default.default.join(cwd, "src", "tools", answers.name);
1115
1124
  logger.startSpinner("Creating tool directory structure...");
1116
1125
  await ensureDir(toolDir);
1117
1126
  const templatePath = getTemplatePath("tool-multi");
@@ -1128,7 +1137,7 @@ async function createMultiFileTool(cwd, answers) {
1128
1137
  if (!answers.generateTests) {
1129
1138
  logger.startSpinner("Cleaning up test files...");
1130
1139
  const fs5 = await import('fs-extra');
1131
- const testDir = path12__default.default.join(toolDir, "__tests__");
1140
+ const testDir = path11__default.default.join(toolDir, "__tests__");
1132
1141
  await fs5.remove(testDir);
1133
1142
  logger.succeedSpinner("Test files removed");
1134
1143
  }
@@ -1137,7 +1146,7 @@ async function toolListCommand(options) {
1137
1146
  try {
1138
1147
  logger.header("\u{1F4CB} List Tools");
1139
1148
  const cwd = process.cwd();
1140
- const toolDir = path12__default.default.join(cwd, "src", "tools");
1149
+ const toolDir = path11__default.default.join(cwd, "src", "tools");
1141
1150
  const toolFiles = await findFiles("*.ts", toolDir);
1142
1151
  if (toolFiles.length === 0) {
1143
1152
  logger.warn("No tools found");
@@ -1148,7 +1157,7 @@ async function toolListCommand(options) {
1148
1157
  if (options.category) {
1149
1158
  filteredTools = [];
1150
1159
  for (const file of toolFiles) {
1151
- const toolPath = path12__default.default.join(toolDir, file);
1160
+ const toolPath = path11__default.default.join(toolDir, file);
1152
1161
  const content = await readFile(toolPath);
1153
1162
  const category = extractCategory(content);
1154
1163
  if (category === options.category) {
@@ -1163,8 +1172,8 @@ async function toolListCommand(options) {
1163
1172
  logger.info(`Found ${chalk4__default.default.cyan(filteredTools.length)} tool(s):
1164
1173
  `);
1165
1174
  for (const file of filteredTools) {
1166
- const toolName = path12__default.default.basename(file, ".ts");
1167
- const toolPath = path12__default.default.join(toolDir, file);
1175
+ const toolName = path11__default.default.basename(file, ".ts");
1176
+ const toolPath = path11__default.default.join(toolDir, file);
1168
1177
  if (options.verbose) {
1169
1178
  const content = await readFile(toolPath);
1170
1179
  const category = extractCategory(content);
@@ -1198,38 +1207,24 @@ function extractDescription2(content) {
1198
1207
  const match = content.match(/\/\*\*\s*\n\s*\*\s*(.+?)\s*\n/);
1199
1208
  return match ? match[1] : null;
1200
1209
  }
1210
+
1211
+ // src/commands/tool/test.ts
1201
1212
  async function toolTestCommand(name, options) {
1202
- try {
1203
- logger.header("\u{1F9EA} Test Tool");
1204
- const cwd = process.cwd();
1205
- const testFile = path12__default.default.join(cwd, "tests", "tools", `${name}.test.ts`);
1206
- if (!await pathExists(testFile)) {
1207
- logger.error(`Test file not found: ${testFile}`);
1208
- logger.info(`Create tests with: ${chalk4__default.default.cyan(`agentforge tool:create ${name} --test`)}`);
1209
- return exitWithCommandError(`Test file not found: ${testFile}`, { logError: false });
1210
- }
1211
- logger.info(`Testing tool: ${chalk4__default.default.cyan(name)}`);
1212
- logger.info(`Watch mode: ${options.watch ? "Yes" : "No"}`);
1213
- logger.newLine();
1214
- const packageManager = await detectPackageManager(cwd);
1215
- logger.startSpinner("Running tests...");
1216
- const testCommand2 = options.watch ? "test:watch" : "test";
1217
- process.env.TEST_FILE = testFile;
1218
- await runScript(cwd, testCommand2, packageManager);
1219
- logger.succeedSpinner("Tests completed");
1220
- } catch (error) {
1221
- return exitWithCommandError(error, { spinnerFailureText: "Tests failed" });
1222
- }
1213
+ return runNamedTestCommand(name, options, {
1214
+ noun: "Tool",
1215
+ testDirectory: "tools",
1216
+ creationHint: `agentforge tool:create ${name} --test`
1217
+ });
1223
1218
  }
1224
1219
  async function resolveToolPath(name) {
1225
1220
  const cwd = process.cwd();
1226
1221
  const isScopedPackage = /^@[^/]+\/[^/]+$/.test(name);
1227
1222
  const isPath = !isScopedPackage && (name.includes("/") || name.includes("\\"));
1228
1223
  if (isPath) {
1229
- const absolutePath = path12__default.default.isAbsolute(name) ? name : path12__default.default.resolve(cwd, name);
1224
+ const absolutePath = path11__default.default.isAbsolute(name) ? name : path11__default.default.resolve(cwd, name);
1230
1225
  return validateToolPath(absolutePath, name);
1231
1226
  }
1232
- const cwdPackageJsonPath = path12__default.default.join(cwd, "package.json");
1227
+ const cwdPackageJsonPath = path11__default.default.join(cwd, "package.json");
1233
1228
  if (await fs__default.default.pathExists(cwdPackageJsonPath)) {
1234
1229
  const cwdPackageJson = await fs__default.default.readJson(cwdPackageJsonPath);
1235
1230
  if (cwdPackageJson.name === name || cwdPackageJson.name === `@agentforge/${name}`) {
@@ -1239,7 +1234,7 @@ async function resolveToolPath(name) {
1239
1234
  const possiblePaths = buildPossiblePaths(cwd, name, isScopedPackage);
1240
1235
  for (const possiblePath of possiblePaths) {
1241
1236
  if (await fs__default.default.pathExists(possiblePath)) {
1242
- const packageJsonPath = path12__default.default.join(possiblePath, "package.json");
1237
+ const packageJsonPath = path11__default.default.join(possiblePath, "package.json");
1243
1238
  if (await fs__default.default.pathExists(packageJsonPath)) {
1244
1239
  return validateToolPath(possiblePath, name);
1245
1240
  }
@@ -1250,7 +1245,7 @@ async function resolveToolPath(name) {
1250
1245
  logger.info("Tried the following locations:");
1251
1246
  logger.list([
1252
1247
  `Current directory (${cwd})`,
1253
- ...possiblePaths.map((possiblePath) => path12__default.default.relative(cwd, possiblePath) || ".")
1248
+ ...possiblePaths.map((possiblePath) => path11__default.default.relative(cwd, possiblePath) || ".")
1254
1249
  ]);
1255
1250
  logger.newLine();
1256
1251
  logger.info("Make sure you are either:");
@@ -1263,16 +1258,16 @@ async function resolveToolPath(name) {
1263
1258
  }
1264
1259
  function buildPossiblePaths(cwd, name, isScopedPackage) {
1265
1260
  const possiblePaths = [
1266
- path12__default.default.join(cwd, "tools", name),
1267
- path12__default.default.join(cwd, "packages", name),
1268
- path12__default.default.join(cwd, name)
1261
+ path11__default.default.join(cwd, "tools", name),
1262
+ path11__default.default.join(cwd, "packages", name),
1263
+ path11__default.default.join(cwd, name)
1269
1264
  ];
1270
1265
  if (isScopedPackage) {
1271
1266
  const unscopedName = name.split("/")[1];
1272
1267
  possiblePaths.push(
1273
- path12__default.default.join(cwd, "tools", unscopedName),
1274
- path12__default.default.join(cwd, "packages", unscopedName),
1275
- path12__default.default.join(cwd, unscopedName)
1268
+ path11__default.default.join(cwd, "tools", unscopedName),
1269
+ path11__default.default.join(cwd, "packages", unscopedName),
1270
+ path11__default.default.join(cwd, unscopedName)
1276
1271
  );
1277
1272
  }
1278
1273
  return possiblePaths;
@@ -1281,7 +1276,7 @@ async function validateToolPath(toolPath, expectedName) {
1281
1276
  if (!await fs__default.default.pathExists(toolPath)) {
1282
1277
  return exitWithCommandError(`Tool directory not found: ${toolPath}`);
1283
1278
  }
1284
- const packageJsonPath = path12__default.default.join(toolPath, "package.json");
1279
+ const packageJsonPath = path11__default.default.join(toolPath, "package.json");
1285
1280
  if (!await fs__default.default.pathExists(packageJsonPath)) {
1286
1281
  logger.info("Tool packages must have a package.json file");
1287
1282
  return exitWithCommandError(`package.json not found in: ${toolPath}`);