@agentforge/cli 0.11.4 → 0.11.6
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 +157 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +156 -59
- 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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Command } from 'commander';
|
|
2
2
|
import chalk4 from 'chalk';
|
|
3
|
-
import
|
|
3
|
+
import path12 from 'path';
|
|
4
4
|
import ora from 'ora';
|
|
5
5
|
import inquirer from 'inquirer';
|
|
6
6
|
import fs from 'fs-extra';
|
|
@@ -250,7 +250,7 @@ async function promptToolSetup(defaults = {}) {
|
|
|
250
250
|
};
|
|
251
251
|
}
|
|
252
252
|
var __filename$1 = fileURLToPath(import.meta.url);
|
|
253
|
-
var __dirname$1 =
|
|
253
|
+
var __dirname$1 = path12.dirname(__filename$1);
|
|
254
254
|
async function ensureDir(dir) {
|
|
255
255
|
await fs.ensureDir(dir);
|
|
256
256
|
}
|
|
@@ -268,9 +268,9 @@ async function copyTemplate(templatePath, targetPath, replacements = {}) {
|
|
|
268
268
|
throw new Error(`No files found in template: ${templatePath}`);
|
|
269
269
|
}
|
|
270
270
|
for (const file of files) {
|
|
271
|
-
const sourcePath =
|
|
272
|
-
const destPath =
|
|
273
|
-
await fs.ensureDir(
|
|
271
|
+
const sourcePath = path12.join(templatePath, file);
|
|
272
|
+
const destPath = path12.join(targetPath, file);
|
|
273
|
+
await fs.ensureDir(path12.dirname(destPath));
|
|
274
274
|
let content = await fs.readFile(sourcePath, "utf-8");
|
|
275
275
|
for (const [key, value] of Object.entries(replacements)) {
|
|
276
276
|
content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
|
|
@@ -294,11 +294,11 @@ async function readFile(filePath) {
|
|
|
294
294
|
return fs.readFile(filePath, "utf-8");
|
|
295
295
|
}
|
|
296
296
|
async function writeFile(filePath, content) {
|
|
297
|
-
await fs.ensureDir(
|
|
297
|
+
await fs.ensureDir(path12.dirname(filePath));
|
|
298
298
|
await fs.writeFile(filePath, content);
|
|
299
299
|
}
|
|
300
300
|
function getTemplatePath(template) {
|
|
301
|
-
return
|
|
301
|
+
return path12.join(__dirname$1, "..", "templates", template);
|
|
302
302
|
}
|
|
303
303
|
async function isEmptyDir(dir) {
|
|
304
304
|
if (!await pathExists(dir)) {
|
|
@@ -308,13 +308,13 @@ async function isEmptyDir(dir) {
|
|
|
308
308
|
return files.length === 0;
|
|
309
309
|
}
|
|
310
310
|
async function detectPackageManager(cwd = process.cwd()) {
|
|
311
|
-
if (await fs.pathExists(
|
|
311
|
+
if (await fs.pathExists(path12.join(cwd, "pnpm-lock.yaml"))) {
|
|
312
312
|
return "pnpm";
|
|
313
313
|
}
|
|
314
|
-
if (await fs.pathExists(
|
|
314
|
+
if (await fs.pathExists(path12.join(cwd, "yarn.lock"))) {
|
|
315
315
|
return "yarn";
|
|
316
316
|
}
|
|
317
|
-
if (await fs.pathExists(
|
|
317
|
+
if (await fs.pathExists(path12.join(cwd, "package-lock.json"))) {
|
|
318
318
|
return "npm";
|
|
319
319
|
}
|
|
320
320
|
try {
|
|
@@ -422,7 +422,7 @@ pnpm-debug.log*
|
|
|
422
422
|
.temp/
|
|
423
423
|
.tmp/
|
|
424
424
|
`;
|
|
425
|
-
await fs.writeFile(
|
|
425
|
+
await fs.writeFile(path12.join(cwd, ".gitignore"), gitignore);
|
|
426
426
|
}
|
|
427
427
|
async function createInitialCommit(cwd) {
|
|
428
428
|
await execa("git", ["add", "."], { cwd });
|
|
@@ -437,7 +437,7 @@ async function createCommand(projectName, options) {
|
|
|
437
437
|
logger.error("Project name is required");
|
|
438
438
|
process.exit(1);
|
|
439
439
|
}
|
|
440
|
-
const targetPath =
|
|
440
|
+
const targetPath = path12.join(process.cwd(), projectName);
|
|
441
441
|
if (!await isEmptyDir(targetPath)) {
|
|
442
442
|
logger.error(`Directory ${projectName} already exists and is not empty`);
|
|
443
443
|
process.exit(1);
|
|
@@ -467,7 +467,7 @@ async function createCommand(projectName, options) {
|
|
|
467
467
|
});
|
|
468
468
|
logger.succeedSpinner("Template files copied");
|
|
469
469
|
logger.startSpinner("Updating package.json...");
|
|
470
|
-
const packageJsonPath =
|
|
470
|
+
const packageJsonPath = path12.join(targetPath, "package.json");
|
|
471
471
|
const packageJson = await readJson(packageJsonPath);
|
|
472
472
|
packageJson.name = answers.projectName;
|
|
473
473
|
if (answers.author) {
|
|
@@ -641,8 +641,8 @@ async function agentCreateCommand(name, options) {
|
|
|
641
641
|
logger.info(`Pattern: ${chalk4.cyan(answers.pattern)}`);
|
|
642
642
|
logger.newLine();
|
|
643
643
|
const cwd = process.cwd();
|
|
644
|
-
const agentDir =
|
|
645
|
-
const agentFile =
|
|
644
|
+
const agentDir = path12.join(cwd, "src", "agents");
|
|
645
|
+
const agentFile = path12.join(agentDir, `${answers.name}.ts`);
|
|
646
646
|
logger.startSpinner("Creating agent file...");
|
|
647
647
|
await ensureDir(agentDir);
|
|
648
648
|
const agentContent = generateAgentContent(answers.name, answers.pattern, answers.description);
|
|
@@ -650,8 +650,8 @@ async function agentCreateCommand(name, options) {
|
|
|
650
650
|
logger.succeedSpinner("Agent file created");
|
|
651
651
|
if (answers.generateTests) {
|
|
652
652
|
logger.startSpinner("Creating test file...");
|
|
653
|
-
const testDir =
|
|
654
|
-
const testFile =
|
|
653
|
+
const testDir = path12.join(cwd, "tests", "agents");
|
|
654
|
+
const testFile = path12.join(testDir, `${answers.name}.test.ts`);
|
|
655
655
|
await ensureDir(testDir);
|
|
656
656
|
const testContent = generateTestContent(answers.name, answers.pattern);
|
|
657
657
|
await writeFile(testFile, testContent);
|
|
@@ -810,7 +810,7 @@ async function agentCreateReusableCommand(name, options) {
|
|
|
810
810
|
logger.info(`Description: ${chalk4.gray(answers.description)}`);
|
|
811
811
|
logger.newLine();
|
|
812
812
|
const cwd = process.cwd();
|
|
813
|
-
const agentDir =
|
|
813
|
+
const agentDir = path12.join(cwd, answers.name);
|
|
814
814
|
const agentNameKebab = answers.name;
|
|
815
815
|
const agentNamePascal = kebabToPascal(agentNameKebab);
|
|
816
816
|
const agentNameCamel = kebabToCamel(agentNameKebab);
|
|
@@ -828,12 +828,12 @@ async function agentCreateReusableCommand(name, options) {
|
|
|
828
828
|
await copyTemplate(templatePath, agentDir, replacements);
|
|
829
829
|
logger.succeedSpinner("Agent structure created");
|
|
830
830
|
logger.startSpinner("Organizing files...");
|
|
831
|
-
const
|
|
832
|
-
const srcDir =
|
|
833
|
-
await
|
|
834
|
-
await
|
|
835
|
-
await
|
|
836
|
-
await
|
|
831
|
+
const fs5 = await import('fs-extra');
|
|
832
|
+
const srcDir = path12.join(agentDir, "src");
|
|
833
|
+
await fs5.ensureDir(srcDir);
|
|
834
|
+
await fs5.move(path12.join(agentDir, "index.ts"), path12.join(srcDir, "index.ts"));
|
|
835
|
+
await fs5.move(path12.join(agentDir, "prompt-loader.ts"), path12.join(srcDir, "prompt-loader.ts"));
|
|
836
|
+
await fs5.move(path12.join(agentDir, "index.test.ts"), path12.join(srcDir, "index.test.ts"));
|
|
837
837
|
logger.succeedSpinner("Files organized");
|
|
838
838
|
logger.newLine();
|
|
839
839
|
logger.success(chalk4.bold.green("\u2728 Reusable agent created successfully!"));
|
|
@@ -866,7 +866,7 @@ async function agentListCommand(options) {
|
|
|
866
866
|
try {
|
|
867
867
|
logger.header("\u{1F4CB} List Agents");
|
|
868
868
|
const cwd = process.cwd();
|
|
869
|
-
const agentDir =
|
|
869
|
+
const agentDir = path12.join(cwd, "src", "agents");
|
|
870
870
|
const agentFiles = await findFiles("*.ts", agentDir);
|
|
871
871
|
if (agentFiles.length === 0) {
|
|
872
872
|
logger.warn("No agents found");
|
|
@@ -876,8 +876,8 @@ async function agentListCommand(options) {
|
|
|
876
876
|
logger.info(`Found ${chalk4.cyan(agentFiles.length)} agent(s):
|
|
877
877
|
`);
|
|
878
878
|
for (const file of agentFiles) {
|
|
879
|
-
const agentName =
|
|
880
|
-
const agentPath =
|
|
879
|
+
const agentName = path12.basename(file, ".ts");
|
|
880
|
+
const agentPath = path12.join(agentDir, file);
|
|
881
881
|
if (options.verbose) {
|
|
882
882
|
const content = await readFile(agentPath);
|
|
883
883
|
const pattern = extractPattern(content);
|
|
@@ -921,7 +921,7 @@ async function agentTestCommand(name, options) {
|
|
|
921
921
|
try {
|
|
922
922
|
logger.header("\u{1F9EA} Test Agent");
|
|
923
923
|
const cwd = process.cwd();
|
|
924
|
-
const testFile =
|
|
924
|
+
const testFile = path12.join(cwd, "tests", "agents", `${name}.test.ts`);
|
|
925
925
|
if (!await pathExists(testFile)) {
|
|
926
926
|
logger.error(`Test file not found: ${testFile}`);
|
|
927
927
|
logger.info(`Create tests with: ${chalk4.cyan(`agentforge agent:create ${name} --test`)}`);
|
|
@@ -1072,8 +1072,8 @@ function capitalize2(str) {
|
|
|
1072
1072
|
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
1073
1073
|
}
|
|
1074
1074
|
async function createSingleFileTool(cwd, answers) {
|
|
1075
|
-
const toolDir =
|
|
1076
|
-
const toolFile =
|
|
1075
|
+
const toolDir = path12.join(cwd, "src", "tools");
|
|
1076
|
+
const toolFile = path12.join(toolDir, `${answers.name}.ts`);
|
|
1077
1077
|
logger.startSpinner("Creating tool file...");
|
|
1078
1078
|
await ensureDir(toolDir);
|
|
1079
1079
|
const toolContent = generateToolContent(answers.name, answers.category, answers.description);
|
|
@@ -1081,8 +1081,8 @@ async function createSingleFileTool(cwd, answers) {
|
|
|
1081
1081
|
logger.succeedSpinner("Tool file created");
|
|
1082
1082
|
if (answers.generateTests) {
|
|
1083
1083
|
logger.startSpinner("Creating test file...");
|
|
1084
|
-
const testDir =
|
|
1085
|
-
const testFile =
|
|
1084
|
+
const testDir = path12.join(cwd, "tests", "tools");
|
|
1085
|
+
const testFile = path12.join(testDir, `${answers.name}.test.ts`);
|
|
1086
1086
|
await ensureDir(testDir);
|
|
1087
1087
|
const testContent = generateTestContent2(answers.name);
|
|
1088
1088
|
await writeFile(testFile, testContent);
|
|
@@ -1090,7 +1090,7 @@ async function createSingleFileTool(cwd, answers) {
|
|
|
1090
1090
|
}
|
|
1091
1091
|
}
|
|
1092
1092
|
async function createMultiFileTool(cwd, answers) {
|
|
1093
|
-
const toolDir =
|
|
1093
|
+
const toolDir = path12.join(cwd, "src", "tools", answers.name);
|
|
1094
1094
|
logger.startSpinner("Creating tool directory structure...");
|
|
1095
1095
|
await ensureDir(toolDir);
|
|
1096
1096
|
const templatePath = getTemplatePath("tool-multi");
|
|
@@ -1105,9 +1105,9 @@ async function createMultiFileTool(cwd, answers) {
|
|
|
1105
1105
|
logger.succeedSpinner("Tool directory structure created");
|
|
1106
1106
|
if (!answers.generateTests) {
|
|
1107
1107
|
logger.startSpinner("Cleaning up test files...");
|
|
1108
|
-
const
|
|
1109
|
-
const testDir =
|
|
1110
|
-
await
|
|
1108
|
+
const fs5 = await import('fs-extra');
|
|
1109
|
+
const testDir = path12.join(toolDir, "__tests__");
|
|
1110
|
+
await fs5.remove(testDir);
|
|
1111
1111
|
logger.succeedSpinner("Test files removed");
|
|
1112
1112
|
}
|
|
1113
1113
|
}
|
|
@@ -1115,7 +1115,7 @@ async function toolListCommand(options) {
|
|
|
1115
1115
|
try {
|
|
1116
1116
|
logger.header("\u{1F4CB} List Tools");
|
|
1117
1117
|
const cwd = process.cwd();
|
|
1118
|
-
const toolDir =
|
|
1118
|
+
const toolDir = path12.join(cwd, "src", "tools");
|
|
1119
1119
|
const toolFiles = await findFiles("*.ts", toolDir);
|
|
1120
1120
|
if (toolFiles.length === 0) {
|
|
1121
1121
|
logger.warn("No tools found");
|
|
@@ -1126,7 +1126,7 @@ async function toolListCommand(options) {
|
|
|
1126
1126
|
if (options.category) {
|
|
1127
1127
|
filteredTools = [];
|
|
1128
1128
|
for (const file of toolFiles) {
|
|
1129
|
-
const toolPath =
|
|
1129
|
+
const toolPath = path12.join(toolDir, file);
|
|
1130
1130
|
const content = await readFile(toolPath);
|
|
1131
1131
|
const category = extractCategory(content);
|
|
1132
1132
|
if (category === options.category) {
|
|
@@ -1141,8 +1141,8 @@ async function toolListCommand(options) {
|
|
|
1141
1141
|
logger.info(`Found ${chalk4.cyan(filteredTools.length)} tool(s):
|
|
1142
1142
|
`);
|
|
1143
1143
|
for (const file of filteredTools) {
|
|
1144
|
-
const toolName =
|
|
1145
|
-
const toolPath =
|
|
1144
|
+
const toolName = path12.basename(file, ".ts");
|
|
1145
|
+
const toolPath = path12.join(toolDir, file);
|
|
1146
1146
|
if (options.verbose) {
|
|
1147
1147
|
const content = await readFile(toolPath);
|
|
1148
1148
|
const category = extractCategory(content);
|
|
@@ -1181,7 +1181,7 @@ async function toolTestCommand(name, options) {
|
|
|
1181
1181
|
try {
|
|
1182
1182
|
logger.header("\u{1F9EA} Test Tool");
|
|
1183
1183
|
const cwd = process.cwd();
|
|
1184
|
-
const testFile =
|
|
1184
|
+
const testFile = path12.join(cwd, "tests", "tools", `${name}.test.ts`);
|
|
1185
1185
|
if (!await pathExists(testFile)) {
|
|
1186
1186
|
logger.error(`Test file not found: ${testFile}`);
|
|
1187
1187
|
logger.info(`Create tests with: ${chalk4.cyan(`agentforge tool:create ${name} --test`)}`);
|
|
@@ -1213,28 +1213,36 @@ async function toolPublishCommand(name, options) {
|
|
|
1213
1213
|
logger.warn("Dry run mode - no actual publishing will occur");
|
|
1214
1214
|
logger.newLine();
|
|
1215
1215
|
}
|
|
1216
|
-
const
|
|
1217
|
-
const packageManager = await detectPackageManager(
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1216
|
+
const { toolPath, hasTestScript, hasBuildScript } = await resolveToolPath(name);
|
|
1217
|
+
const packageManager = await detectPackageManager(toolPath);
|
|
1218
|
+
if (hasTestScript) {
|
|
1219
|
+
logger.startSpinner("Running tests...");
|
|
1220
|
+
try {
|
|
1221
|
+
await runScript(toolPath, "test", packageManager);
|
|
1222
|
+
logger.succeedSpinner("Tests passed");
|
|
1223
|
+
} catch (error) {
|
|
1224
|
+
logger.failSpinner("Tests failed");
|
|
1225
|
+
logger.error("Cannot publish tool with failing tests");
|
|
1226
|
+
process.exit(1);
|
|
1227
|
+
}
|
|
1228
|
+
} else {
|
|
1229
|
+
logger.info("\u26A0\uFE0F Skipping tests (no test script found)");
|
|
1226
1230
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1231
|
+
if (hasBuildScript) {
|
|
1232
|
+
logger.startSpinner("Building tool...");
|
|
1233
|
+
try {
|
|
1234
|
+
await runScript(toolPath, "build", packageManager);
|
|
1235
|
+
logger.succeedSpinner("Build completed");
|
|
1236
|
+
} catch (error) {
|
|
1237
|
+
logger.failSpinner("Build failed");
|
|
1238
|
+
process.exit(1);
|
|
1239
|
+
}
|
|
1240
|
+
} else {
|
|
1241
|
+
logger.info("\u26A0\uFE0F Skipping build (no build script found)");
|
|
1234
1242
|
}
|
|
1235
1243
|
logger.startSpinner(options.dryRun ? "Running dry-run publish..." : "Publishing to npm...");
|
|
1236
1244
|
try {
|
|
1237
|
-
await publishPackage(
|
|
1245
|
+
await publishPackage(toolPath, {
|
|
1238
1246
|
tag: options.tag,
|
|
1239
1247
|
access: "public",
|
|
1240
1248
|
dryRun: options.dryRun
|
|
@@ -1277,6 +1285,95 @@ async function toolPublishCommand(name, options) {
|
|
|
1277
1285
|
process.exit(1);
|
|
1278
1286
|
}
|
|
1279
1287
|
}
|
|
1288
|
+
async function resolveToolPath(name) {
|
|
1289
|
+
const cwd = process.cwd();
|
|
1290
|
+
const isScopedPackage = /^@[^/]+\/[^/]+$/.test(name);
|
|
1291
|
+
const isPath = !isScopedPackage && (name.includes("/") || name.includes("\\"));
|
|
1292
|
+
if (isPath) {
|
|
1293
|
+
const absolutePath = path12.isAbsolute(name) ? name : path12.resolve(cwd, name);
|
|
1294
|
+
return await validateToolPath(absolutePath, name);
|
|
1295
|
+
}
|
|
1296
|
+
const cwdPackageJsonPath = path12.join(cwd, "package.json");
|
|
1297
|
+
if (await fs.pathExists(cwdPackageJsonPath)) {
|
|
1298
|
+
const cwdPackageJson = await fs.readJson(cwdPackageJsonPath);
|
|
1299
|
+
if (cwdPackageJson.name === name || cwdPackageJson.name === `@agentforge/${name}`) {
|
|
1300
|
+
return await validateToolPath(cwd, name);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
const unscopedName = isScopedPackage ? name.split("/")[1] : name;
|
|
1304
|
+
const possiblePaths = [
|
|
1305
|
+
path12.join(cwd, "tools", name),
|
|
1306
|
+
path12.join(cwd, "packages", name),
|
|
1307
|
+
path12.join(cwd, name)
|
|
1308
|
+
];
|
|
1309
|
+
if (isScopedPackage) {
|
|
1310
|
+
possiblePaths.push(
|
|
1311
|
+
path12.join(cwd, "tools", unscopedName),
|
|
1312
|
+
path12.join(cwd, "packages", unscopedName),
|
|
1313
|
+
path12.join(cwd, unscopedName)
|
|
1314
|
+
);
|
|
1315
|
+
}
|
|
1316
|
+
for (const possiblePath of possiblePaths) {
|
|
1317
|
+
if (await fs.pathExists(possiblePath)) {
|
|
1318
|
+
const packageJsonPath = path12.join(possiblePath, "package.json");
|
|
1319
|
+
if (await fs.pathExists(packageJsonPath)) {
|
|
1320
|
+
return await validateToolPath(possiblePath, name);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
logger.error(`Could not find tool package: ${chalk4.cyan(name)}`);
|
|
1325
|
+
logger.newLine();
|
|
1326
|
+
logger.info("Tried the following locations:");
|
|
1327
|
+
logger.list([
|
|
1328
|
+
`Current directory (${cwd})`,
|
|
1329
|
+
...possiblePaths.map((p) => path12.relative(cwd, p) || ".")
|
|
1330
|
+
]);
|
|
1331
|
+
logger.newLine();
|
|
1332
|
+
logger.info("Make sure you are either:");
|
|
1333
|
+
logger.list([
|
|
1334
|
+
"In the tool package directory with matching package.json name",
|
|
1335
|
+
"Providing a path to the tool package directory",
|
|
1336
|
+
"Have the tool in a standard location (./tools/<name>, ./packages/<name>)"
|
|
1337
|
+
]);
|
|
1338
|
+
process.exit(1);
|
|
1339
|
+
}
|
|
1340
|
+
async function validateToolPath(toolPath, expectedName) {
|
|
1341
|
+
if (!await fs.pathExists(toolPath)) {
|
|
1342
|
+
logger.error(`Tool directory not found: ${toolPath}`);
|
|
1343
|
+
process.exit(1);
|
|
1344
|
+
}
|
|
1345
|
+
const packageJsonPath = path12.join(toolPath, "package.json");
|
|
1346
|
+
if (!await fs.pathExists(packageJsonPath)) {
|
|
1347
|
+
logger.error(`package.json not found in: ${toolPath}`);
|
|
1348
|
+
logger.info("Tool packages must have a package.json file");
|
|
1349
|
+
process.exit(1);
|
|
1350
|
+
}
|
|
1351
|
+
let packageJson;
|
|
1352
|
+
try {
|
|
1353
|
+
packageJson = await fs.readJson(packageJsonPath);
|
|
1354
|
+
} catch (error) {
|
|
1355
|
+
logger.error(`Failed to read package.json: ${error.message}`);
|
|
1356
|
+
process.exit(1);
|
|
1357
|
+
}
|
|
1358
|
+
if (!packageJson.name) {
|
|
1359
|
+
logger.error('package.json must have a "name" field');
|
|
1360
|
+
process.exit(1);
|
|
1361
|
+
}
|
|
1362
|
+
const packageName = packageJson.name;
|
|
1363
|
+
const nameMatches = packageName === expectedName || packageName === `@agentforge/${expectedName}` || packageName.endsWith(`/${expectedName}`);
|
|
1364
|
+
if (!nameMatches) {
|
|
1365
|
+
logger.warn(`Package name mismatch: expected ${chalk4.cyan(expectedName)}, found ${chalk4.cyan(packageName)}`);
|
|
1366
|
+
logger.info(`Publishing package: ${chalk4.cyan(packageName)}`);
|
|
1367
|
+
logger.newLine();
|
|
1368
|
+
}
|
|
1369
|
+
const hasTestScript = !!packageJson.scripts?.test;
|
|
1370
|
+
const hasBuildScript = !!packageJson.scripts?.build;
|
|
1371
|
+
return {
|
|
1372
|
+
toolPath,
|
|
1373
|
+
hasTestScript,
|
|
1374
|
+
hasBuildScript
|
|
1375
|
+
};
|
|
1376
|
+
}
|
|
1280
1377
|
|
|
1281
1378
|
// src/index.ts
|
|
1282
1379
|
var program = new Command();
|