@standardagents/cli 0.10.1-dev.cea2b66 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { Command } from 'commander';
3
- import fs, { readFileSync } from 'fs';
4
- import path, { dirname, resolve } from 'path';
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 = path.join(cwd, "package.json");
1046
- if (fs.existsSync(packageJsonPath)) {
1046
+ const packageJsonPath = path3.join(cwd, "package.json");
1047
+ if (fs3.existsSync(packageJsonPath)) {
1047
1048
  try {
1048
- const pkg2 = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
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 path.basename(cwd);
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 = path.join(cwd, candidate);
1061
- if (fs.existsSync(configPath)) {
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 = path.join(cwd, candidate);
1071
- if (fs.existsSync(configPath)) {
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 = fs.readFileSync(configPath, "utf-8");
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 = fs.readFileSync(existingConfig, "utf-8");
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
- fs.writeFileSync(existingConfig, result, "utf-8");
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 = path.join(cwd, "wrangler.jsonc");
1179
+ const wranglerPath = path3.join(cwd, "wrangler.jsonc");
1179
1180
  const sanitizedName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
1180
- fs.writeFileSync(wranglerPath, WRANGLER_TEMPLATE(sanitizedName), "utf-8");
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 = fs.readFileSync(wranglerConfig, "utf-8");
1189
+ const text = fs3.readFileSync(wranglerConfig, "utf-8");
1189
1190
  const config = parse(text);
1190
1191
  if (config.main) {
1191
- return path.join(cwd, config.main);
1192
+ return path3.join(cwd, config.main);
1192
1193
  }
1193
1194
  } catch {
1194
1195
  }
1195
1196
  }
1196
- return path.join(cwd, "worker", "index.ts");
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 = path.dirname(entryPath);
1201
- if (!fs.existsSync(entryDir)) {
1202
- fs.mkdirSync(entryDir, { recursive: true });
1203
- logger.success(`Created ${path.relative(cwd, entryDir)} directory`);
1204
- }
1205
- if (!fs.existsSync(entryPath)) {
1206
- fs.writeFileSync(entryPath, WORKER_INDEX, "utf-8");
1207
- logger.success(`Created ${path.relative(cwd, entryPath)}`);
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 = fs.readFileSync(entryPath, "utf-8");
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(`${path.relative(cwd, entryPath)} already configured`);
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
- fs.writeFileSync(entryPath, WORKER_INDEX, "utf-8");
1243
- logger.success(`Updated ${path.relative(cwd, entryPath)} with Standard Agents router`);
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
- fs.writeFileSync(entryPath, WORKER_INDEX, "utf-8");
1249
- logger.success(`Created ${path.relative(cwd, entryPath)}`);
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 ${path.relative(cwd, entryPath)}`);
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 = path.join(cwd, "agents");
1272
- if (!fs.existsSync(agentsDir)) {
1273
- fs.mkdirSync(agentsDir, { recursive: true });
1272
+ const agentsDir = path3.join(cwd, "agents");
1273
+ if (!fs3.existsSync(agentsDir)) {
1274
+ fs3.mkdirSync(agentsDir, { recursive: true });
1274
1275
  }
1275
- const threadPath = path.join(agentsDir, "Thread.ts");
1276
- if (!fs.existsSync(threadPath)) {
1277
- fs.writeFileSync(threadPath, THREAD_TS, "utf-8");
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 = path.join(agentsDir, "AgentBuilder.ts");
1283
- if (!fs.existsSync(agentBuilderPath)) {
1284
- fs.writeFileSync(agentBuilderPath, AGENT_BUILDER_TS, "utf-8");
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
- path.join(cwd, "agents");
1292
- const rootDocPath = path.join(cwd, "CLAUDE.md");
1293
- if (!fs.existsSync(rootDocPath)) {
1294
- fs.writeFileSync(rootDocPath, ROOT_CLAUDE_MD, "utf-8");
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 = path.join(cwd, dir.path);
1307
- const docPath = path.join(dirPath, "CLAUDE.md");
1308
- if (!fs.existsSync(dirPath)) {
1309
- fs.mkdirSync(dirPath, { recursive: true });
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 (!fs.existsSync(docPath)) {
1313
- fs.writeFileSync(docPath, dir.doc, "utf-8");
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 = path.join(cwd, "tsconfig.json");
1320
- if (!fs.existsSync(tsconfigPath)) {
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 = fs.readFileSync(tsconfigPath, "utf-8");
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
- fs.writeFileSync(tsconfigPath, result, "utf-8");
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 = path.join(cwd, file);
1369
- if (fs.existsSync(filePath)) {
1369
+ const filePath = path3.join(cwd, file);
1370
+ if (fs3.existsSync(filePath)) {
1370
1371
  try {
1371
- fs.unlinkSync(filePath);
1372
+ fs3.unlinkSync(filePath);
1372
1373
  } catch {
1373
1374
  }
1374
1375
  }
1375
1376
  }
1376
1377
  for (const dir of dirsToRemove) {
1377
- const dirPath = path.join(cwd, dir);
1378
- if (fs.existsSync(dirPath)) {
1378
+ const dirPath = path3.join(cwd, dir);
1379
+ if (fs3.existsSync(dirPath)) {
1379
1380
  try {
1380
- const files = fs.readdirSync(dirPath);
1381
+ const files = fs3.readdirSync(dirPath);
1381
1382
  if (files.length === 0) {
1382
- fs.rmdirSync(dirPath);
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 (fs.existsSync("pnpm-lock.yaml")) return "pnpm";
1517
- if (fs.existsSync("yarn.lock")) return "yarn";
1518
- if (fs.existsSync("bun.lockb")) return "bun";
1519
- if (fs.existsSync("package-lock.json")) return "npm";
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 = path.join(cwd, projectName);
1604
- if (fs.existsSync(projectPath)) {
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 = path.join(projectPath, "vite.config.ts");
1637
- if (!fs.existsSync(viteConfigPath)) {
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
- fs.writeFileSync(viteConfigPath, viteConfigContent, "utf-8");
1660
+ fs3.writeFileSync(viteConfigPath, viteConfigContent, "utf-8");
1645
1661
  logger.success("Created vite.config.ts");
1646
1662
  }
1647
- const packageJsonPath = path.join(projectPath, "package.json");
1648
- if (fs.existsSync(packageJsonPath)) {
1649
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
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
- fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + "\n", "utf-8");
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
- "@standardagents/builder",
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 = path.join(projectPath, ".dev.vars");
1741
- fs.writeFileSync(devVarsPath, devVarsLines.join("\n"), "utf-8");
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 = path.join(projectPath, ".gitignore");
1744
- if (fs.existsSync(gitignorePath)) {
1745
- const gitignoreContent = fs.readFileSync(gitignorePath, "utf-8");
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
- fs.appendFileSync(gitignorePath, "\n# Local environment variables\n.dev.vars\n");
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