@standardagents/cli 0.10.1-dev.d2d335e → 0.10.1-next.82e11d5
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 +628 -83
- package/dist/index.js.map +1 -1
- package/package.json +7 -3
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
3
|
+
import fs3, { readFileSync } from 'fs';
|
|
4
|
+
import path3, { dirname, resolve } from 'path';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import crypto from 'crypto';
|
|
7
7
|
import readline from 'readline';
|
|
@@ -10,6 +10,7 @@ import chalk from 'chalk';
|
|
|
10
10
|
import { parse, modify, applyEdits } from 'jsonc-parser';
|
|
11
11
|
import { loadFile, writeFile, generateCode } from 'magicast';
|
|
12
12
|
import { addVitePlugin } from 'magicast/helpers';
|
|
13
|
+
import net from 'net';
|
|
13
14
|
|
|
14
15
|
var logger = {
|
|
15
16
|
success: (message) => {
|
|
@@ -1042,23 +1043,23 @@ export default {
|
|
|
1042
1043
|
export { DurableThread, DurableAgentBuilder }
|
|
1043
1044
|
`;
|
|
1044
1045
|
function getProjectName(cwd) {
|
|
1045
|
-
const packageJsonPath =
|
|
1046
|
-
if (
|
|
1046
|
+
const packageJsonPath = path3.join(cwd, "package.json");
|
|
1047
|
+
if (fs3.existsSync(packageJsonPath)) {
|
|
1047
1048
|
try {
|
|
1048
|
-
const pkg2 = JSON.parse(
|
|
1049
|
+
const pkg2 = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
|
|
1049
1050
|
if (pkg2.name) {
|
|
1050
1051
|
return pkg2.name.replace(/^@[^/]+\//, "");
|
|
1051
1052
|
}
|
|
1052
1053
|
} catch {
|
|
1053
1054
|
}
|
|
1054
1055
|
}
|
|
1055
|
-
return
|
|
1056
|
+
return path3.basename(cwd);
|
|
1056
1057
|
}
|
|
1057
1058
|
function findViteConfig(cwd) {
|
|
1058
1059
|
const candidates = ["vite.config.ts", "vite.config.js", "vite.config.mts", "vite.config.mjs"];
|
|
1059
1060
|
for (const candidate of candidates) {
|
|
1060
|
-
const configPath =
|
|
1061
|
-
if (
|
|
1061
|
+
const configPath = path3.join(cwd, candidate);
|
|
1062
|
+
if (fs3.existsSync(configPath)) {
|
|
1062
1063
|
return configPath;
|
|
1063
1064
|
}
|
|
1064
1065
|
}
|
|
@@ -1067,8 +1068,8 @@ function findViteConfig(cwd) {
|
|
|
1067
1068
|
function findWranglerConfig(cwd) {
|
|
1068
1069
|
const candidates = ["wrangler.jsonc", "wrangler.json"];
|
|
1069
1070
|
for (const candidate of candidates) {
|
|
1070
|
-
const configPath =
|
|
1071
|
-
if (
|
|
1071
|
+
const configPath = path3.join(cwd, candidate);
|
|
1072
|
+
if (fs3.existsSync(configPath)) {
|
|
1072
1073
|
return configPath;
|
|
1073
1074
|
}
|
|
1074
1075
|
}
|
|
@@ -1077,7 +1078,7 @@ function findWranglerConfig(cwd) {
|
|
|
1077
1078
|
async function modifyViteConfig(configPath, force) {
|
|
1078
1079
|
try {
|
|
1079
1080
|
const mod = await loadFile(configPath);
|
|
1080
|
-
const code =
|
|
1081
|
+
const code = fs3.readFileSync(configPath, "utf-8");
|
|
1081
1082
|
const hasCloudflare = code.includes("@cloudflare/vite-plugin") || code.includes("cloudflare()");
|
|
1082
1083
|
const hasAgentBuilder = code.includes("@standardagents/builder") || code.includes("agentbuilder()");
|
|
1083
1084
|
if (hasCloudflare && hasAgentBuilder && !force) {
|
|
@@ -1120,7 +1121,7 @@ function createOrUpdateWranglerConfig(cwd, projectName, force) {
|
|
|
1120
1121
|
const existingConfig = findWranglerConfig(cwd);
|
|
1121
1122
|
if (existingConfig && !force) {
|
|
1122
1123
|
try {
|
|
1123
|
-
const text =
|
|
1124
|
+
const text = fs3.readFileSync(existingConfig, "utf-8");
|
|
1124
1125
|
const config = parse(text);
|
|
1125
1126
|
const hasBindings = config.durable_objects?.bindings?.some(
|
|
1126
1127
|
(b) => b.name === "AGENT_BUILDER_THREAD" || b.name === "AGENT_BUILDER"
|
|
@@ -1167,7 +1168,7 @@ function createOrUpdateWranglerConfig(cwd, projectName, force) {
|
|
|
1167
1168
|
}, {});
|
|
1168
1169
|
result = applyEdits(result, edits);
|
|
1169
1170
|
}
|
|
1170
|
-
|
|
1171
|
+
fs3.writeFileSync(existingConfig, result, "utf-8");
|
|
1171
1172
|
logger.success("Updated wrangler.jsonc with Standard Agents configuration");
|
|
1172
1173
|
return true;
|
|
1173
1174
|
} catch (error) {
|
|
@@ -1175,9 +1176,9 @@ function createOrUpdateWranglerConfig(cwd, projectName, force) {
|
|
|
1175
1176
|
return false;
|
|
1176
1177
|
}
|
|
1177
1178
|
}
|
|
1178
|
-
const wranglerPath =
|
|
1179
|
+
const wranglerPath = path3.join(cwd, "wrangler.jsonc");
|
|
1179
1180
|
const sanitizedName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
1180
|
-
|
|
1181
|
+
fs3.writeFileSync(wranglerPath, WRANGLER_TEMPLATE(sanitizedName), "utf-8");
|
|
1181
1182
|
logger.success("Created wrangler.jsonc");
|
|
1182
1183
|
return true;
|
|
1183
1184
|
}
|
|
@@ -1185,33 +1186,33 @@ function getWorkerEntryPoint(cwd) {
|
|
|
1185
1186
|
const wranglerConfig = findWranglerConfig(cwd);
|
|
1186
1187
|
if (wranglerConfig) {
|
|
1187
1188
|
try {
|
|
1188
|
-
const text =
|
|
1189
|
+
const text = fs3.readFileSync(wranglerConfig, "utf-8");
|
|
1189
1190
|
const config = parse(text);
|
|
1190
1191
|
if (config.main) {
|
|
1191
|
-
return
|
|
1192
|
+
return path3.join(cwd, config.main);
|
|
1192
1193
|
}
|
|
1193
1194
|
} catch {
|
|
1194
1195
|
}
|
|
1195
1196
|
}
|
|
1196
|
-
return
|
|
1197
|
+
return path3.join(cwd, "worker", "index.ts");
|
|
1197
1198
|
}
|
|
1198
1199
|
async function createOrUpdateWorkerEntry(cwd, force) {
|
|
1199
1200
|
const entryPath = getWorkerEntryPoint(cwd);
|
|
1200
|
-
const entryDir =
|
|
1201
|
-
if (!
|
|
1202
|
-
|
|
1203
|
-
logger.success(`Created ${
|
|
1204
|
-
}
|
|
1205
|
-
if (!
|
|
1206
|
-
|
|
1207
|
-
logger.success(`Created ${
|
|
1201
|
+
const entryDir = path3.dirname(entryPath);
|
|
1202
|
+
if (!fs3.existsSync(entryDir)) {
|
|
1203
|
+
fs3.mkdirSync(entryDir, { recursive: true });
|
|
1204
|
+
logger.success(`Created ${path3.relative(cwd, entryDir)} directory`);
|
|
1205
|
+
}
|
|
1206
|
+
if (!fs3.existsSync(entryPath)) {
|
|
1207
|
+
fs3.writeFileSync(entryPath, WORKER_INDEX, "utf-8");
|
|
1208
|
+
logger.success(`Created ${path3.relative(cwd, entryPath)}`);
|
|
1208
1209
|
return true;
|
|
1209
1210
|
}
|
|
1210
|
-
const content =
|
|
1211
|
+
const content = fs3.readFileSync(entryPath, "utf-8");
|
|
1211
1212
|
const hasRouter = content.includes("virtual:@standardagents/builder") && content.includes("router");
|
|
1212
1213
|
const hasDurableExports = content.includes("DurableThread") && content.includes("DurableAgentBuilder");
|
|
1213
1214
|
if (hasRouter && hasDurableExports && !force) {
|
|
1214
|
-
logger.info(`${
|
|
1215
|
+
logger.info(`${path3.relative(cwd, entryPath)} already configured`);
|
|
1215
1216
|
return true;
|
|
1216
1217
|
}
|
|
1217
1218
|
try {
|
|
@@ -1239,17 +1240,17 @@ async function createOrUpdateWorkerEntry(cwd, force) {
|
|
|
1239
1240
|
}
|
|
1240
1241
|
const { code } = generateCode(mod);
|
|
1241
1242
|
if (force || !hasRouter) {
|
|
1242
|
-
|
|
1243
|
-
logger.success(`Updated ${
|
|
1243
|
+
fs3.writeFileSync(entryPath, WORKER_INDEX, "utf-8");
|
|
1244
|
+
logger.success(`Updated ${path3.relative(cwd, entryPath)} with Standard Agents router`);
|
|
1244
1245
|
}
|
|
1245
1246
|
return true;
|
|
1246
1247
|
} catch (error) {
|
|
1247
1248
|
if (force) {
|
|
1248
|
-
|
|
1249
|
-
logger.success(`Created ${
|
|
1249
|
+
fs3.writeFileSync(entryPath, WORKER_INDEX, "utf-8");
|
|
1250
|
+
logger.success(`Created ${path3.relative(cwd, entryPath)}`);
|
|
1250
1251
|
return true;
|
|
1251
1252
|
}
|
|
1252
|
-
logger.warning(`Could not automatically modify ${
|
|
1253
|
+
logger.warning(`Could not automatically modify ${path3.relative(cwd, entryPath)}`);
|
|
1253
1254
|
logger.log("");
|
|
1254
1255
|
logger.log("Please ensure your worker entry point includes:");
|
|
1255
1256
|
logger.log("");
|
|
@@ -1268,30 +1269,30 @@ async function createOrUpdateWorkerEntry(cwd, force) {
|
|
|
1268
1269
|
}
|
|
1269
1270
|
}
|
|
1270
1271
|
function createDurableObjects(cwd) {
|
|
1271
|
-
const agentsDir =
|
|
1272
|
-
if (!
|
|
1273
|
-
|
|
1272
|
+
const agentsDir = path3.join(cwd, "agents");
|
|
1273
|
+
if (!fs3.existsSync(agentsDir)) {
|
|
1274
|
+
fs3.mkdirSync(agentsDir, { recursive: true });
|
|
1274
1275
|
}
|
|
1275
|
-
const threadPath =
|
|
1276
|
-
if (!
|
|
1277
|
-
|
|
1276
|
+
const threadPath = path3.join(agentsDir, "Thread.ts");
|
|
1277
|
+
if (!fs3.existsSync(threadPath)) {
|
|
1278
|
+
fs3.writeFileSync(threadPath, THREAD_TS, "utf-8");
|
|
1278
1279
|
logger.success("Created agents/Thread.ts");
|
|
1279
1280
|
} else {
|
|
1280
1281
|
logger.info("agents/Thread.ts already exists");
|
|
1281
1282
|
}
|
|
1282
|
-
const agentBuilderPath =
|
|
1283
|
-
if (!
|
|
1284
|
-
|
|
1283
|
+
const agentBuilderPath = path3.join(agentsDir, "AgentBuilder.ts");
|
|
1284
|
+
if (!fs3.existsSync(agentBuilderPath)) {
|
|
1285
|
+
fs3.writeFileSync(agentBuilderPath, AGENT_BUILDER_TS, "utf-8");
|
|
1285
1286
|
logger.success("Created agents/AgentBuilder.ts");
|
|
1286
1287
|
} else {
|
|
1287
1288
|
logger.info("agents/AgentBuilder.ts already exists");
|
|
1288
1289
|
}
|
|
1289
1290
|
}
|
|
1290
1291
|
function createDirectoriesAndDocs(cwd) {
|
|
1291
|
-
|
|
1292
|
-
const rootDocPath =
|
|
1293
|
-
if (!
|
|
1294
|
-
|
|
1292
|
+
path3.join(cwd, "agents");
|
|
1293
|
+
const rootDocPath = path3.join(cwd, "CLAUDE.md");
|
|
1294
|
+
if (!fs3.existsSync(rootDocPath)) {
|
|
1295
|
+
fs3.writeFileSync(rootDocPath, ROOT_CLAUDE_MD, "utf-8");
|
|
1295
1296
|
logger.success("Created CLAUDE.md");
|
|
1296
1297
|
}
|
|
1297
1298
|
const directories = [
|
|
@@ -1303,26 +1304,26 @@ function createDirectoriesAndDocs(cwd) {
|
|
|
1303
1304
|
{ path: "agents/api", doc: API_CLAUDE_MD }
|
|
1304
1305
|
];
|
|
1305
1306
|
for (const dir of directories) {
|
|
1306
|
-
const dirPath =
|
|
1307
|
-
const docPath =
|
|
1308
|
-
if (!
|
|
1309
|
-
|
|
1307
|
+
const dirPath = path3.join(cwd, dir.path);
|
|
1308
|
+
const docPath = path3.join(dirPath, "CLAUDE.md");
|
|
1309
|
+
if (!fs3.existsSync(dirPath)) {
|
|
1310
|
+
fs3.mkdirSync(dirPath, { recursive: true });
|
|
1310
1311
|
logger.success(`Created ${dir.path}`);
|
|
1311
1312
|
}
|
|
1312
|
-
if (!
|
|
1313
|
-
|
|
1313
|
+
if (!fs3.existsSync(docPath)) {
|
|
1314
|
+
fs3.writeFileSync(docPath, dir.doc, "utf-8");
|
|
1314
1315
|
logger.success(`Created ${dir.path}/CLAUDE.md`);
|
|
1315
1316
|
}
|
|
1316
1317
|
}
|
|
1317
1318
|
}
|
|
1318
1319
|
function updateTsConfig(cwd) {
|
|
1319
|
-
const tsconfigPath =
|
|
1320
|
-
if (!
|
|
1320
|
+
const tsconfigPath = path3.join(cwd, "tsconfig.json");
|
|
1321
|
+
if (!fs3.existsSync(tsconfigPath)) {
|
|
1321
1322
|
logger.info("No tsconfig.json found, skipping TypeScript configuration");
|
|
1322
1323
|
return;
|
|
1323
1324
|
}
|
|
1324
1325
|
try {
|
|
1325
|
-
const text =
|
|
1326
|
+
const text = fs3.readFileSync(tsconfigPath, "utf-8");
|
|
1326
1327
|
const config = parse(text);
|
|
1327
1328
|
let result = text;
|
|
1328
1329
|
const types = config.compilerOptions?.types || [];
|
|
@@ -1344,7 +1345,7 @@ function updateTsConfig(cwd) {
|
|
|
1344
1345
|
result = applyEdits(result, edits);
|
|
1345
1346
|
}
|
|
1346
1347
|
if (newTypes.length > 0 || newIncludes.length > 0) {
|
|
1347
|
-
|
|
1348
|
+
fs3.writeFileSync(tsconfigPath, result, "utf-8");
|
|
1348
1349
|
logger.success("Updated tsconfig.json with Standard Agents types");
|
|
1349
1350
|
} else {
|
|
1350
1351
|
logger.info("tsconfig.json already configured");
|
|
@@ -1365,21 +1366,21 @@ function cleanupViteDefaults(cwd) {
|
|
|
1365
1366
|
];
|
|
1366
1367
|
const dirsToRemove = ["src", "public"];
|
|
1367
1368
|
for (const file of filesToRemove) {
|
|
1368
|
-
const filePath =
|
|
1369
|
-
if (
|
|
1369
|
+
const filePath = path3.join(cwd, file);
|
|
1370
|
+
if (fs3.existsSync(filePath)) {
|
|
1370
1371
|
try {
|
|
1371
|
-
|
|
1372
|
+
fs3.unlinkSync(filePath);
|
|
1372
1373
|
} catch {
|
|
1373
1374
|
}
|
|
1374
1375
|
}
|
|
1375
1376
|
}
|
|
1376
1377
|
for (const dir of dirsToRemove) {
|
|
1377
|
-
const dirPath =
|
|
1378
|
-
if (
|
|
1378
|
+
const dirPath = path3.join(cwd, dir);
|
|
1379
|
+
if (fs3.existsSync(dirPath)) {
|
|
1379
1380
|
try {
|
|
1380
|
-
const files =
|
|
1381
|
+
const files = fs3.readdirSync(dirPath);
|
|
1381
1382
|
if (files.length === 0) {
|
|
1382
|
-
|
|
1383
|
+
fs3.rmdirSync(dirPath);
|
|
1383
1384
|
}
|
|
1384
1385
|
} catch {
|
|
1385
1386
|
}
|
|
@@ -1513,12 +1514,27 @@ function detectPackageManager() {
|
|
|
1513
1514
|
if (userAgent.includes("yarn")) return "yarn";
|
|
1514
1515
|
if (userAgent.includes("bun")) return "bun";
|
|
1515
1516
|
}
|
|
1516
|
-
if (
|
|
1517
|
-
if (
|
|
1518
|
-
if (
|
|
1519
|
-
if (
|
|
1517
|
+
if (fs3.existsSync("pnpm-lock.yaml")) return "pnpm";
|
|
1518
|
+
if (fs3.existsSync("yarn.lock")) return "yarn";
|
|
1519
|
+
if (fs3.existsSync("bun.lockb")) return "bun";
|
|
1520
|
+
if (fs3.existsSync("package-lock.json")) return "npm";
|
|
1520
1521
|
return "npm";
|
|
1521
1522
|
}
|
|
1523
|
+
function getBuilderPackageVersion() {
|
|
1524
|
+
try {
|
|
1525
|
+
const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
|
|
1526
|
+
const pkgPath = path3.resolve(__dirname2, "../../package.json");
|
|
1527
|
+
const pkg2 = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
1528
|
+
const version = pkg2.version;
|
|
1529
|
+
const prereleaseMatch = version.match(/-([a-z]+)\./i);
|
|
1530
|
+
if (prereleaseMatch) {
|
|
1531
|
+
return `@${prereleaseMatch[1]}`;
|
|
1532
|
+
}
|
|
1533
|
+
return `@^${version}`;
|
|
1534
|
+
} catch {
|
|
1535
|
+
return "";
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1522
1538
|
async function selectPackageManager(detected) {
|
|
1523
1539
|
const options = ["npm", "pnpm", "yarn", "bun"];
|
|
1524
1540
|
const detectedIndex = options.indexOf(detected);
|
|
@@ -1600,8 +1616,8 @@ async function init(projectNameArg, options = {}) {
|
|
|
1600
1616
|
logger.error("Project name is required");
|
|
1601
1617
|
process.exit(1);
|
|
1602
1618
|
}
|
|
1603
|
-
const projectPath =
|
|
1604
|
-
if (
|
|
1619
|
+
const projectPath = path3.join(cwd, projectName);
|
|
1620
|
+
if (fs3.existsSync(projectPath)) {
|
|
1605
1621
|
logger.error(`Directory "${projectName}" already exists`);
|
|
1606
1622
|
process.exit(1);
|
|
1607
1623
|
}
|
|
@@ -1633,24 +1649,24 @@ async function init(projectNameArg, options = {}) {
|
|
|
1633
1649
|
logger.error("Failed to create Vite project");
|
|
1634
1650
|
process.exit(1);
|
|
1635
1651
|
}
|
|
1636
|
-
const viteConfigPath =
|
|
1637
|
-
if (!
|
|
1652
|
+
const viteConfigPath = path3.join(projectPath, "vite.config.ts");
|
|
1653
|
+
if (!fs3.existsSync(viteConfigPath)) {
|
|
1638
1654
|
const viteConfigContent = `import { defineConfig } from 'vite'
|
|
1639
1655
|
|
|
1640
1656
|
export default defineConfig({
|
|
1641
1657
|
plugins: [],
|
|
1642
1658
|
})
|
|
1643
1659
|
`;
|
|
1644
|
-
|
|
1660
|
+
fs3.writeFileSync(viteConfigPath, viteConfigContent, "utf-8");
|
|
1645
1661
|
logger.success("Created vite.config.ts");
|
|
1646
1662
|
}
|
|
1647
|
-
const packageJsonPath =
|
|
1648
|
-
if (
|
|
1649
|
-
const packageJson = JSON.parse(
|
|
1663
|
+
const packageJsonPath = path3.join(projectPath, "package.json");
|
|
1664
|
+
if (fs3.existsSync(packageJsonPath)) {
|
|
1665
|
+
const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
|
|
1650
1666
|
const kebabName = toKebabCase(projectName);
|
|
1651
1667
|
if (packageJson.name !== kebabName) {
|
|
1652
1668
|
packageJson.name = kebabName;
|
|
1653
|
-
|
|
1669
|
+
fs3.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf-8");
|
|
1654
1670
|
}
|
|
1655
1671
|
}
|
|
1656
1672
|
logger.log("");
|
|
@@ -1659,11 +1675,12 @@ export default defineConfig({
|
|
|
1659
1675
|
try {
|
|
1660
1676
|
const installCmd = pm === "npm" ? "install" : "add";
|
|
1661
1677
|
const devFlag = pm === "npm" ? "--save-dev" : "-D";
|
|
1678
|
+
const builderVersion = getBuilderPackageVersion();
|
|
1662
1679
|
await runCommand(pm, [
|
|
1663
1680
|
installCmd,
|
|
1664
1681
|
devFlag,
|
|
1665
1682
|
"@cloudflare/vite-plugin",
|
|
1666
|
-
|
|
1683
|
+
`@standardagents/builder${builderVersion}`,
|
|
1667
1684
|
"wrangler",
|
|
1668
1685
|
"zod"
|
|
1669
1686
|
], projectPath);
|
|
@@ -1737,14 +1754,14 @@ export default defineConfig({
|
|
|
1737
1754
|
devVarsLines.push("# OPENAI_API_KEY=your-openai-key");
|
|
1738
1755
|
}
|
|
1739
1756
|
devVarsLines.push("");
|
|
1740
|
-
const devVarsPath =
|
|
1741
|
-
|
|
1757
|
+
const devVarsPath = path3.join(projectPath, ".dev.vars");
|
|
1758
|
+
fs3.writeFileSync(devVarsPath, devVarsLines.join("\n"), "utf-8");
|
|
1742
1759
|
logger.success("Created .dev.vars with encryption key");
|
|
1743
|
-
const gitignorePath =
|
|
1744
|
-
if (
|
|
1745
|
-
const gitignoreContent =
|
|
1760
|
+
const gitignorePath = path3.join(projectPath, ".gitignore");
|
|
1761
|
+
if (fs3.existsSync(gitignorePath)) {
|
|
1762
|
+
const gitignoreContent = fs3.readFileSync(gitignorePath, "utf-8");
|
|
1746
1763
|
if (!gitignoreContent.includes(".dev.vars")) {
|
|
1747
|
-
|
|
1764
|
+
fs3.appendFileSync(gitignorePath, "\n# Local environment variables\n.dev.vars\n");
|
|
1748
1765
|
logger.success("Added .dev.vars to .gitignore");
|
|
1749
1766
|
}
|
|
1750
1767
|
}
|
|
@@ -1766,6 +1783,533 @@ export default defineConfig({
|
|
|
1766
1783
|
logger.log("");
|
|
1767
1784
|
logger.log("For more information, visit: https://standardagents.ai/docs");
|
|
1768
1785
|
}
|
|
1786
|
+
function getReactPackageVersion() {
|
|
1787
|
+
try {
|
|
1788
|
+
const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
|
|
1789
|
+
const pkgPath = path3.resolve(__dirname2, "../package.json");
|
|
1790
|
+
const pkg2 = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
|
|
1791
|
+
const version = pkg2.version;
|
|
1792
|
+
const prereleaseMatch = version.match(/-([a-z]+)\./i);
|
|
1793
|
+
if (prereleaseMatch) {
|
|
1794
|
+
return prereleaseMatch[1];
|
|
1795
|
+
}
|
|
1796
|
+
return `^${version}`;
|
|
1797
|
+
} catch {
|
|
1798
|
+
return "latest";
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
function getChatSourceDir() {
|
|
1802
|
+
const __dirname2 = path3.dirname(fileURLToPath(import.meta.url));
|
|
1803
|
+
return path3.resolve(__dirname2, "../chat");
|
|
1804
|
+
}
|
|
1805
|
+
async function prompt2(question) {
|
|
1806
|
+
const rl = readline.createInterface({
|
|
1807
|
+
input: process.stdin,
|
|
1808
|
+
output: process.stdout
|
|
1809
|
+
});
|
|
1810
|
+
return new Promise((resolve2) => {
|
|
1811
|
+
rl.question(question, (answer) => {
|
|
1812
|
+
rl.close();
|
|
1813
|
+
resolve2(answer.trim());
|
|
1814
|
+
});
|
|
1815
|
+
});
|
|
1816
|
+
}
|
|
1817
|
+
function runCommand2(command, args, cwd) {
|
|
1818
|
+
return new Promise((resolve2, reject) => {
|
|
1819
|
+
const child = spawn(command, args, {
|
|
1820
|
+
cwd,
|
|
1821
|
+
stdio: "inherit",
|
|
1822
|
+
shell: false
|
|
1823
|
+
});
|
|
1824
|
+
child.on("close", (code) => {
|
|
1825
|
+
if (code === 0) {
|
|
1826
|
+
resolve2();
|
|
1827
|
+
} else {
|
|
1828
|
+
reject(new Error(`Command failed with exit code ${code}`));
|
|
1829
|
+
}
|
|
1830
|
+
});
|
|
1831
|
+
child.on("error", reject);
|
|
1832
|
+
});
|
|
1833
|
+
}
|
|
1834
|
+
function detectPackageManager2() {
|
|
1835
|
+
const userAgent = process.env.npm_config_user_agent;
|
|
1836
|
+
if (userAgent) {
|
|
1837
|
+
if (userAgent.includes("pnpm")) return "pnpm";
|
|
1838
|
+
if (userAgent.includes("yarn")) return "yarn";
|
|
1839
|
+
if (userAgent.includes("bun")) return "bun";
|
|
1840
|
+
}
|
|
1841
|
+
if (fs3.existsSync("pnpm-lock.yaml")) return "pnpm";
|
|
1842
|
+
if (fs3.existsSync("yarn.lock")) return "yarn";
|
|
1843
|
+
if (fs3.existsSync("bun.lockb")) return "bun";
|
|
1844
|
+
if (fs3.existsSync("package-lock.json")) return "npm";
|
|
1845
|
+
return "npm";
|
|
1846
|
+
}
|
|
1847
|
+
async function selectPackageManager2(detected) {
|
|
1848
|
+
const options = ["npm", "pnpm", "yarn", "bun"];
|
|
1849
|
+
const detectedIndex = options.indexOf(detected);
|
|
1850
|
+
return new Promise((resolve2) => {
|
|
1851
|
+
const stdin = process.stdin;
|
|
1852
|
+
const stdout = process.stdout;
|
|
1853
|
+
let selectedIndex = detectedIndex;
|
|
1854
|
+
const renderOptions = () => {
|
|
1855
|
+
stdout.write("\x1B[?25l");
|
|
1856
|
+
stdout.write(`\x1B[${options.length + 1}A`);
|
|
1857
|
+
stdout.write("\x1B[0J");
|
|
1858
|
+
stdout.write("Select a package manager:\n");
|
|
1859
|
+
options.forEach((opt, i) => {
|
|
1860
|
+
const marker = i === detectedIndex ? " (detected)" : "";
|
|
1861
|
+
const prefix = i === selectedIndex ? "\x1B[36m\u276F\x1B[0m" : " ";
|
|
1862
|
+
const highlight = i === selectedIndex ? "\x1B[36m" : "\x1B[90m";
|
|
1863
|
+
stdout.write(`${prefix} ${highlight}${opt}${marker}\x1B[0m
|
|
1864
|
+
`);
|
|
1865
|
+
});
|
|
1866
|
+
};
|
|
1867
|
+
stdout.write("Select a package manager:\n");
|
|
1868
|
+
options.forEach((opt, i) => {
|
|
1869
|
+
const marker = i === detectedIndex ? " (detected)" : "";
|
|
1870
|
+
const prefix = i === selectedIndex ? "\x1B[36m\u276F\x1B[0m" : " ";
|
|
1871
|
+
const highlight = i === selectedIndex ? "\x1B[36m" : "\x1B[90m";
|
|
1872
|
+
stdout.write(`${prefix} ${highlight}${opt}${marker}\x1B[0m
|
|
1873
|
+
`);
|
|
1874
|
+
});
|
|
1875
|
+
const wasRaw = stdin.isRaw;
|
|
1876
|
+
if (stdin.isTTY) {
|
|
1877
|
+
stdin.setRawMode(true);
|
|
1878
|
+
}
|
|
1879
|
+
stdin.resume();
|
|
1880
|
+
stdin.setEncoding("utf8");
|
|
1881
|
+
const cleanup = () => {
|
|
1882
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
1883
|
+
stdin.pause();
|
|
1884
|
+
stdin.removeListener("data", onData);
|
|
1885
|
+
stdout.write("\x1B[?25h");
|
|
1886
|
+
};
|
|
1887
|
+
const onData = (key) => {
|
|
1888
|
+
if (key === "\x1B[A" || key === "k") {
|
|
1889
|
+
selectedIndex = (selectedIndex - 1 + options.length) % options.length;
|
|
1890
|
+
renderOptions();
|
|
1891
|
+
} else if (key === "\x1B[B" || key === "j") {
|
|
1892
|
+
selectedIndex = (selectedIndex + 1) % options.length;
|
|
1893
|
+
renderOptions();
|
|
1894
|
+
} else if (key === "\r" || key === "\n") {
|
|
1895
|
+
cleanup();
|
|
1896
|
+
resolve2(options[selectedIndex]);
|
|
1897
|
+
} else if (key === "") {
|
|
1898
|
+
cleanup();
|
|
1899
|
+
stdout.write("\n");
|
|
1900
|
+
process.exit(1);
|
|
1901
|
+
}
|
|
1902
|
+
};
|
|
1903
|
+
stdin.on("data", onData);
|
|
1904
|
+
});
|
|
1905
|
+
}
|
|
1906
|
+
async function selectFramework() {
|
|
1907
|
+
const options = [
|
|
1908
|
+
{ value: "vite", label: "Vite (React + TypeScript)" },
|
|
1909
|
+
{ value: "nextjs", label: "Next.js (App Router)" }
|
|
1910
|
+
];
|
|
1911
|
+
return new Promise((resolve2) => {
|
|
1912
|
+
const stdin = process.stdin;
|
|
1913
|
+
const stdout = process.stdout;
|
|
1914
|
+
let selectedIndex = 0;
|
|
1915
|
+
const renderOptions = () => {
|
|
1916
|
+
stdout.write("\x1B[?25l");
|
|
1917
|
+
stdout.write(`\x1B[${options.length + 1}A`);
|
|
1918
|
+
stdout.write("\x1B[0J");
|
|
1919
|
+
stdout.write("Select a framework:\n");
|
|
1920
|
+
options.forEach((opt, i) => {
|
|
1921
|
+
const prefix = i === selectedIndex ? "\x1B[36m\u276F\x1B[0m" : " ";
|
|
1922
|
+
const highlight = i === selectedIndex ? "\x1B[36m" : "\x1B[90m";
|
|
1923
|
+
stdout.write(`${prefix} ${highlight}${opt.label}\x1B[0m
|
|
1924
|
+
`);
|
|
1925
|
+
});
|
|
1926
|
+
};
|
|
1927
|
+
stdout.write("Select a framework:\n");
|
|
1928
|
+
options.forEach((opt, i) => {
|
|
1929
|
+
const prefix = i === selectedIndex ? "\x1B[36m\u276F\x1B[0m" : " ";
|
|
1930
|
+
const highlight = i === selectedIndex ? "\x1B[36m" : "\x1B[90m";
|
|
1931
|
+
stdout.write(`${prefix} ${highlight}${opt.label}\x1B[0m
|
|
1932
|
+
`);
|
|
1933
|
+
});
|
|
1934
|
+
const wasRaw = stdin.isRaw;
|
|
1935
|
+
if (stdin.isTTY) {
|
|
1936
|
+
stdin.setRawMode(true);
|
|
1937
|
+
}
|
|
1938
|
+
stdin.resume();
|
|
1939
|
+
stdin.setEncoding("utf8");
|
|
1940
|
+
const cleanup = () => {
|
|
1941
|
+
stdin.setRawMode(wasRaw ?? false);
|
|
1942
|
+
stdin.pause();
|
|
1943
|
+
stdin.removeListener("data", onData);
|
|
1944
|
+
stdout.write("\x1B[?25h");
|
|
1945
|
+
};
|
|
1946
|
+
const onData = (key) => {
|
|
1947
|
+
if (key === "\x1B[A" || key === "k") {
|
|
1948
|
+
selectedIndex = (selectedIndex - 1 + options.length) % options.length;
|
|
1949
|
+
renderOptions();
|
|
1950
|
+
} else if (key === "\x1B[B" || key === "j") {
|
|
1951
|
+
selectedIndex = (selectedIndex + 1) % options.length;
|
|
1952
|
+
renderOptions();
|
|
1953
|
+
} else if (key === "\r" || key === "\n") {
|
|
1954
|
+
cleanup();
|
|
1955
|
+
resolve2(options[selectedIndex].value);
|
|
1956
|
+
} else if (key === "") {
|
|
1957
|
+
cleanup();
|
|
1958
|
+
stdout.write("\n");
|
|
1959
|
+
process.exit(1);
|
|
1960
|
+
}
|
|
1961
|
+
};
|
|
1962
|
+
stdin.on("data", onData);
|
|
1963
|
+
});
|
|
1964
|
+
}
|
|
1965
|
+
function isValidUrl(url) {
|
|
1966
|
+
try {
|
|
1967
|
+
new URL(url);
|
|
1968
|
+
return true;
|
|
1969
|
+
} catch {
|
|
1970
|
+
return false;
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
async function isPortOpen(port) {
|
|
1974
|
+
const tryConnect = (host) => {
|
|
1975
|
+
return new Promise((resolve2) => {
|
|
1976
|
+
const socket = new net.Socket();
|
|
1977
|
+
socket.setTimeout(200);
|
|
1978
|
+
socket.on("connect", () => {
|
|
1979
|
+
socket.destroy();
|
|
1980
|
+
resolve2(true);
|
|
1981
|
+
});
|
|
1982
|
+
socket.on("timeout", () => {
|
|
1983
|
+
socket.destroy();
|
|
1984
|
+
resolve2(false);
|
|
1985
|
+
});
|
|
1986
|
+
socket.on("error", () => {
|
|
1987
|
+
socket.destroy();
|
|
1988
|
+
resolve2(false);
|
|
1989
|
+
});
|
|
1990
|
+
socket.connect(port, host);
|
|
1991
|
+
});
|
|
1992
|
+
};
|
|
1993
|
+
if (await tryConnect("127.0.0.1")) return true;
|
|
1994
|
+
if (await tryConnect("::1")) return true;
|
|
1995
|
+
return false;
|
|
1996
|
+
}
|
|
1997
|
+
async function isAgentbuilderInstance(url) {
|
|
1998
|
+
try {
|
|
1999
|
+
const controller = new AbortController();
|
|
2000
|
+
const timeout = setTimeout(() => controller.abort(), 1e3);
|
|
2001
|
+
const response = await fetch(`${url}/api/agents`, {
|
|
2002
|
+
signal: controller.signal,
|
|
2003
|
+
headers: { "Accept": "application/json" }
|
|
2004
|
+
});
|
|
2005
|
+
clearTimeout(timeout);
|
|
2006
|
+
if (response.status === 401) {
|
|
2007
|
+
return true;
|
|
2008
|
+
}
|
|
2009
|
+
if (response.ok) {
|
|
2010
|
+
const data = await response.json();
|
|
2011
|
+
return Array.isArray(data.agents);
|
|
2012
|
+
}
|
|
2013
|
+
return false;
|
|
2014
|
+
} catch {
|
|
2015
|
+
return false;
|
|
2016
|
+
}
|
|
2017
|
+
}
|
|
2018
|
+
async function detectAgentbuilderInstance() {
|
|
2019
|
+
const portsToScan = [
|
|
2020
|
+
5173,
|
|
2021
|
+
5174,
|
|
2022
|
+
5175,
|
|
2023
|
+
5176,
|
|
2024
|
+
5177,
|
|
2025
|
+
5178,
|
|
2026
|
+
5179,
|
|
2027
|
+
5180,
|
|
2028
|
+
3e3,
|
|
2029
|
+
3001,
|
|
2030
|
+
3002,
|
|
2031
|
+
3003,
|
|
2032
|
+
8080,
|
|
2033
|
+
8e3,
|
|
2034
|
+
4e3
|
|
2035
|
+
];
|
|
2036
|
+
logger.log("\x1B[90mScanning for running agentbuilder instance...\x1B[0m");
|
|
2037
|
+
const openPorts = [];
|
|
2038
|
+
await Promise.all(
|
|
2039
|
+
portsToScan.map(async (port) => {
|
|
2040
|
+
if (await isPortOpen(port)) {
|
|
2041
|
+
openPorts.push(port);
|
|
2042
|
+
}
|
|
2043
|
+
})
|
|
2044
|
+
);
|
|
2045
|
+
for (const port of openPorts.sort((a, b) => a - b)) {
|
|
2046
|
+
const url = `http://localhost:${port}`;
|
|
2047
|
+
if (await isAgentbuilderInstance(url)) {
|
|
2048
|
+
return url;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
return null;
|
|
2052
|
+
}
|
|
2053
|
+
function copyDir(src, dest, skip = []) {
|
|
2054
|
+
if (!fs3.existsSync(dest)) {
|
|
2055
|
+
fs3.mkdirSync(dest, { recursive: true });
|
|
2056
|
+
}
|
|
2057
|
+
const entries = fs3.readdirSync(src, { withFileTypes: true });
|
|
2058
|
+
for (const entry of entries) {
|
|
2059
|
+
if (skip.includes(entry.name)) continue;
|
|
2060
|
+
const srcPath = path3.join(src, entry.name);
|
|
2061
|
+
const destPath = path3.join(dest, entry.name);
|
|
2062
|
+
if (entry.isDirectory()) {
|
|
2063
|
+
copyDir(srcPath, destPath, skip);
|
|
2064
|
+
} else {
|
|
2065
|
+
fs3.copyFileSync(srcPath, destPath);
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
async function initChat(projectNameArg, options = {}) {
|
|
2070
|
+
const cwd = process.cwd();
|
|
2071
|
+
const chatSourceDir = getChatSourceDir();
|
|
2072
|
+
if (!fs3.existsSync(chatSourceDir)) {
|
|
2073
|
+
logger.error("Chat source files not found. This CLI installation may be corrupted.");
|
|
2074
|
+
process.exit(1);
|
|
2075
|
+
}
|
|
2076
|
+
logger.log("");
|
|
2077
|
+
logger.info("Scaffolding a frontend chat application...");
|
|
2078
|
+
logger.log("");
|
|
2079
|
+
let projectName = projectNameArg;
|
|
2080
|
+
if (!projectName && !options.yes) {
|
|
2081
|
+
projectName = await prompt2("Project name: ");
|
|
2082
|
+
}
|
|
2083
|
+
if (!projectName) {
|
|
2084
|
+
logger.error("Project name is required");
|
|
2085
|
+
process.exit(1);
|
|
2086
|
+
}
|
|
2087
|
+
const projectPath = path3.join(cwd, projectName);
|
|
2088
|
+
if (fs3.existsSync(projectPath)) {
|
|
2089
|
+
logger.error(`Directory "${projectName}" already exists`);
|
|
2090
|
+
process.exit(1);
|
|
2091
|
+
}
|
|
2092
|
+
let framework;
|
|
2093
|
+
if (options.framework) {
|
|
2094
|
+
framework = options.framework;
|
|
2095
|
+
} else if (options.yes) {
|
|
2096
|
+
framework = "vite";
|
|
2097
|
+
} else {
|
|
2098
|
+
framework = await selectFramework();
|
|
2099
|
+
logger.log("");
|
|
2100
|
+
}
|
|
2101
|
+
let serverUrl;
|
|
2102
|
+
if (options.yes) {
|
|
2103
|
+
serverUrl = "http://localhost:5173";
|
|
2104
|
+
} else {
|
|
2105
|
+
const detectedUrl = await detectAgentbuilderInstance();
|
|
2106
|
+
if (detectedUrl) {
|
|
2107
|
+
logger.success(`Found agentbuilder at ${detectedUrl}`);
|
|
2108
|
+
const urlInput = await prompt2(`Agentbuilder dev server URL [${detectedUrl}]: `);
|
|
2109
|
+
serverUrl = urlInput || detectedUrl;
|
|
2110
|
+
} else {
|
|
2111
|
+
logger.log("\x1B[90mNo running agentbuilder instance found\x1B[0m");
|
|
2112
|
+
const urlInput = await prompt2("Agentbuilder dev server URL [http://localhost:5173]: ");
|
|
2113
|
+
serverUrl = urlInput || "http://localhost:5173";
|
|
2114
|
+
}
|
|
2115
|
+
if (!isValidUrl(serverUrl)) {
|
|
2116
|
+
logger.error("Invalid URL format");
|
|
2117
|
+
process.exit(1);
|
|
2118
|
+
}
|
|
2119
|
+
}
|
|
2120
|
+
const detectedPm = detectPackageManager2();
|
|
2121
|
+
let pm;
|
|
2122
|
+
if (options.yes) {
|
|
2123
|
+
pm = detectedPm;
|
|
2124
|
+
} else {
|
|
2125
|
+
pm = await selectPackageManager2(detectedPm);
|
|
2126
|
+
logger.log("");
|
|
2127
|
+
}
|
|
2128
|
+
logger.log("");
|
|
2129
|
+
logger.info(`Creating ${framework === "vite" ? "Vite" : "Next.js"} project...`);
|
|
2130
|
+
logger.log("");
|
|
2131
|
+
fs3.mkdirSync(projectPath, { recursive: true });
|
|
2132
|
+
const reactVersion = getReactPackageVersion();
|
|
2133
|
+
if (framework === "vite") {
|
|
2134
|
+
await scaffoldVite(projectPath, chatSourceDir, projectName, serverUrl, reactVersion);
|
|
2135
|
+
} else {
|
|
2136
|
+
await scaffoldNextjs(projectPath, chatSourceDir, projectName, serverUrl, reactVersion);
|
|
2137
|
+
}
|
|
2138
|
+
logger.log("");
|
|
2139
|
+
logger.info("Installing dependencies...");
|
|
2140
|
+
logger.log("");
|
|
2141
|
+
try {
|
|
2142
|
+
await runCommand2(pm, pm === "npm" ? ["install"] : ["install"], projectPath);
|
|
2143
|
+
} catch (error) {
|
|
2144
|
+
logger.error("Failed to install dependencies");
|
|
2145
|
+
process.exit(1);
|
|
2146
|
+
}
|
|
2147
|
+
logger.log("");
|
|
2148
|
+
logger.success("Chat UI scaffolded successfully!");
|
|
2149
|
+
logger.log("");
|
|
2150
|
+
logger.info("Starting development server...");
|
|
2151
|
+
logger.log("");
|
|
2152
|
+
const devArgs = pm === "npm" ? ["run", "dev"] : ["dev"];
|
|
2153
|
+
const devProcess = spawn(pm, devArgs, {
|
|
2154
|
+
cwd: projectPath,
|
|
2155
|
+
stdio: ["inherit", "pipe", "pipe"],
|
|
2156
|
+
shell: false
|
|
2157
|
+
});
|
|
2158
|
+
let browserOpened = false;
|
|
2159
|
+
const openBrowser = (url) => {
|
|
2160
|
+
if (browserOpened) return;
|
|
2161
|
+
browserOpened = true;
|
|
2162
|
+
const openCmd = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
2163
|
+
spawn(openCmd, [url], { stdio: "ignore", detached: true }).unref();
|
|
2164
|
+
};
|
|
2165
|
+
devProcess.stdout?.on("data", (data) => {
|
|
2166
|
+
const text = data.toString();
|
|
2167
|
+
process.stdout.write(data);
|
|
2168
|
+
const urlMatch = text.match(/Local:\s+(https?:\/\/localhost:\d+\/?)/);
|
|
2169
|
+
if (urlMatch && !browserOpened) {
|
|
2170
|
+
openBrowser(urlMatch[1]);
|
|
2171
|
+
}
|
|
2172
|
+
});
|
|
2173
|
+
devProcess.stderr?.on("data", (data) => {
|
|
2174
|
+
process.stderr.write(data);
|
|
2175
|
+
});
|
|
2176
|
+
devProcess.on("error", (error) => {
|
|
2177
|
+
logger.error(`Failed to start dev server: ${error.message}`);
|
|
2178
|
+
process.exit(1);
|
|
2179
|
+
});
|
|
2180
|
+
}
|
|
2181
|
+
async function scaffoldVite(projectPath, chatSourceDir, projectName, serverUrl, reactVersion) {
|
|
2182
|
+
copyDir(path3.join(chatSourceDir, "src"), path3.join(projectPath, "src"), []);
|
|
2183
|
+
logger.success("Copied src/");
|
|
2184
|
+
const viteDir = path3.join(chatSourceDir, "vite");
|
|
2185
|
+
fs3.copyFileSync(path3.join(viteDir, "index.html"), path3.join(projectPath, "index.html"));
|
|
2186
|
+
logger.success("Created index.html");
|
|
2187
|
+
fs3.copyFileSync(path3.join(viteDir, "main.tsx"), path3.join(projectPath, "src", "main.tsx"));
|
|
2188
|
+
logger.success("Created src/main.tsx");
|
|
2189
|
+
let viteConfig = fs3.readFileSync(path3.join(viteDir, "vite.config.ts"), "utf-8");
|
|
2190
|
+
viteConfig = `import { defineConfig } from 'vite'
|
|
2191
|
+
import react from '@vitejs/plugin-react'
|
|
2192
|
+
import tailwindcss from '@tailwindcss/vite'
|
|
2193
|
+
|
|
2194
|
+
export default defineConfig({
|
|
2195
|
+
plugins: [
|
|
2196
|
+
react(),
|
|
2197
|
+
tailwindcss(),
|
|
2198
|
+
],
|
|
2199
|
+
})
|
|
2200
|
+
`;
|
|
2201
|
+
fs3.writeFileSync(path3.join(projectPath, "vite.config.ts"), viteConfig, "utf-8");
|
|
2202
|
+
logger.success("Created vite.config.ts");
|
|
2203
|
+
fs3.copyFileSync(path3.join(chatSourceDir, "tsconfig.json"), path3.join(projectPath, "tsconfig.json"));
|
|
2204
|
+
const tsconfig = JSON.parse(fs3.readFileSync(path3.join(projectPath, "tsconfig.json"), "utf-8"));
|
|
2205
|
+
tsconfig.include = ["src"];
|
|
2206
|
+
delete tsconfig.compilerOptions?.paths;
|
|
2207
|
+
fs3.writeFileSync(path3.join(projectPath, "tsconfig.json"), JSON.stringify(tsconfig, null, 2) + "\n", "utf-8");
|
|
2208
|
+
logger.success("Created tsconfig.json");
|
|
2209
|
+
fs3.copyFileSync(path3.join(chatSourceDir, "package.json"), path3.join(projectPath, "package.json"));
|
|
2210
|
+
const pkg2 = JSON.parse(fs3.readFileSync(path3.join(projectPath, "package.json"), "utf-8"));
|
|
2211
|
+
pkg2.name = projectName;
|
|
2212
|
+
pkg2.scripts = {
|
|
2213
|
+
dev: "vite",
|
|
2214
|
+
build: "vite build",
|
|
2215
|
+
preview: "vite preview"
|
|
2216
|
+
};
|
|
2217
|
+
delete pkg2.private;
|
|
2218
|
+
if (pkg2.dependencies?.["@standardagents/react"]) {
|
|
2219
|
+
pkg2.dependencies["@standardagents/react"] = reactVersion;
|
|
2220
|
+
}
|
|
2221
|
+
delete pkg2.dependencies?.["next"];
|
|
2222
|
+
delete pkg2.devDependencies?.["@tailwindcss/postcss"];
|
|
2223
|
+
delete pkg2.devDependencies?.["postcss"];
|
|
2224
|
+
fs3.writeFileSync(path3.join(projectPath, "package.json"), JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
2225
|
+
logger.success("Created package.json");
|
|
2226
|
+
const envContent = `# Agentbuilder connection
|
|
2227
|
+
VITE_AGENTBUILDER_URL=${serverUrl}
|
|
2228
|
+
`;
|
|
2229
|
+
fs3.writeFileSync(path3.join(projectPath, ".env"), envContent, "utf-8");
|
|
2230
|
+
logger.success("Created .env");
|
|
2231
|
+
fs3.writeFileSync(path3.join(projectPath, ".gitignore"), `node_modules
|
|
2232
|
+
dist
|
|
2233
|
+
.env
|
|
2234
|
+
`, "utf-8");
|
|
2235
|
+
logger.success("Created .gitignore");
|
|
2236
|
+
let mainTsx = fs3.readFileSync(path3.join(projectPath, "src", "main.tsx"), "utf-8");
|
|
2237
|
+
mainTsx = mainTsx.replace(/from '\.\.\/src\//g, "from './").replace(/import '\.\.\/src\//g, "import './");
|
|
2238
|
+
fs3.writeFileSync(path3.join(projectPath, "src", "main.tsx"), mainTsx, "utf-8");
|
|
2239
|
+
if (fs3.existsSync(path3.join(viteDir, "favicon.svg"))) {
|
|
2240
|
+
fs3.copyFileSync(path3.join(viteDir, "favicon.svg"), path3.join(projectPath, "favicon.svg"));
|
|
2241
|
+
logger.success("Created favicon.svg");
|
|
2242
|
+
}
|
|
2243
|
+
}
|
|
2244
|
+
async function scaffoldNextjs(projectPath, chatSourceDir, projectName, serverUrl, reactVersion) {
|
|
2245
|
+
copyDir(path3.join(chatSourceDir, "src"), path3.join(projectPath, "src"), []);
|
|
2246
|
+
logger.success("Copied src/");
|
|
2247
|
+
const nextDir = path3.join(chatSourceDir, "next");
|
|
2248
|
+
copyDir(path3.join(nextDir, "app"), path3.join(projectPath, "app"), []);
|
|
2249
|
+
logger.success("Copied app/");
|
|
2250
|
+
fs3.copyFileSync(path3.join(nextDir, "next.config.ts"), path3.join(projectPath, "next.config.ts"));
|
|
2251
|
+
logger.success("Created next.config.ts");
|
|
2252
|
+
fs3.copyFileSync(path3.join(nextDir, "postcss.config.mjs"), path3.join(projectPath, "postcss.config.mjs"));
|
|
2253
|
+
logger.success("Created postcss.config.mjs");
|
|
2254
|
+
const tsconfig = {
|
|
2255
|
+
compilerOptions: {
|
|
2256
|
+
target: "ES2017",
|
|
2257
|
+
lib: ["dom", "dom.iterable", "esnext"],
|
|
2258
|
+
allowJs: true,
|
|
2259
|
+
skipLibCheck: true,
|
|
2260
|
+
strict: true,
|
|
2261
|
+
noEmit: true,
|
|
2262
|
+
esModuleInterop: true,
|
|
2263
|
+
module: "esnext",
|
|
2264
|
+
moduleResolution: "bundler",
|
|
2265
|
+
resolveJsonModule: true,
|
|
2266
|
+
isolatedModules: true,
|
|
2267
|
+
jsx: "preserve",
|
|
2268
|
+
incremental: true,
|
|
2269
|
+
plugins: [{ name: "next" }],
|
|
2270
|
+
paths: {
|
|
2271
|
+
"@/*": ["./src/*"]
|
|
2272
|
+
}
|
|
2273
|
+
},
|
|
2274
|
+
include: ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
|
2275
|
+
exclude: ["node_modules"]
|
|
2276
|
+
};
|
|
2277
|
+
fs3.writeFileSync(path3.join(projectPath, "tsconfig.json"), JSON.stringify(tsconfig, null, 2) + "\n", "utf-8");
|
|
2278
|
+
logger.success("Created tsconfig.json");
|
|
2279
|
+
const pkg2 = JSON.parse(fs3.readFileSync(path3.join(chatSourceDir, "package.json"), "utf-8"));
|
|
2280
|
+
pkg2.name = projectName;
|
|
2281
|
+
pkg2.scripts = {
|
|
2282
|
+
dev: "next dev",
|
|
2283
|
+
build: "next build",
|
|
2284
|
+
start: "next start"
|
|
2285
|
+
};
|
|
2286
|
+
delete pkg2.private;
|
|
2287
|
+
if (pkg2.dependencies?.["@standardagents/react"]) {
|
|
2288
|
+
pkg2.dependencies["@standardagents/react"] = reactVersion;
|
|
2289
|
+
}
|
|
2290
|
+
delete pkg2.devDependencies?.["@tailwindcss/vite"];
|
|
2291
|
+
delete pkg2.devDependencies?.["@vitejs/plugin-react"];
|
|
2292
|
+
delete pkg2.devDependencies?.["vite"];
|
|
2293
|
+
fs3.writeFileSync(path3.join(projectPath, "package.json"), JSON.stringify(pkg2, null, 2) + "\n", "utf-8");
|
|
2294
|
+
logger.success("Created package.json");
|
|
2295
|
+
const envContent = `# Agentbuilder connection
|
|
2296
|
+
NEXT_PUBLIC_AGENTBUILDER_URL=${serverUrl}
|
|
2297
|
+
`;
|
|
2298
|
+
fs3.writeFileSync(path3.join(projectPath, ".env.local"), envContent, "utf-8");
|
|
2299
|
+
logger.success("Created .env.local");
|
|
2300
|
+
fs3.writeFileSync(path3.join(projectPath, ".gitignore"), `node_modules
|
|
2301
|
+
.next
|
|
2302
|
+
out
|
|
2303
|
+
.env.local
|
|
2304
|
+
`, "utf-8");
|
|
2305
|
+
logger.success("Created .gitignore");
|
|
2306
|
+
let layoutTsx = fs3.readFileSync(path3.join(projectPath, "app", "layout.tsx"), "utf-8");
|
|
2307
|
+
layoutTsx = layoutTsx.replace(/from '\.\.\/\.\.\/src\//g, "from '../src/");
|
|
2308
|
+
fs3.writeFileSync(path3.join(projectPath, "app", "layout.tsx"), layoutTsx, "utf-8");
|
|
2309
|
+
let pageTsx = fs3.readFileSync(path3.join(projectPath, "app", "page.tsx"), "utf-8");
|
|
2310
|
+
pageTsx = pageTsx.replace(/from '\.\.\/\.\.\/src\//g, "from '../src/");
|
|
2311
|
+
fs3.writeFileSync(path3.join(projectPath, "app", "page.tsx"), pageTsx, "utf-8");
|
|
2312
|
+
}
|
|
1769
2313
|
|
|
1770
2314
|
// src/index.ts
|
|
1771
2315
|
var __dirname$1 = dirname(fileURLToPath(import.meta.url));
|
|
@@ -1774,6 +2318,7 @@ var program = new Command();
|
|
|
1774
2318
|
program.name("agents").description("CLI tool for Standard Agents / AgentBuilder").version(pkg.version);
|
|
1775
2319
|
program.command("init [project-name]").description("Create a new Standard Agents project (runs create vite, then scaffold)").option("-y, --yes", "Skip prompts and use defaults").option("--template <template>", "Vite template to use", "vanilla-ts").action(init);
|
|
1776
2320
|
program.command("scaffold").description("Add Standard Agents to an existing Vite project").option("--force", "Overwrite existing configuration").action(scaffold);
|
|
2321
|
+
program.command("init-chat [project-name]").description("Scaffold a frontend chat application").option("-y, --yes", "Skip prompts and use defaults").option("--framework <framework>", "Framework to use (vite or nextjs)").action(initChat);
|
|
1777
2322
|
program.parse();
|
|
1778
2323
|
//# sourceMappingURL=index.js.map
|
|
1779
2324
|
//# sourceMappingURL=index.js.map
|