@standardagents/cli 0.13.1 → 0.13.2

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/README.md CHANGED
@@ -35,6 +35,31 @@ pnpm exec agents scaffold
35
35
 
36
36
  Creates the `agents/` directory structure with documentation files.
37
37
 
38
+ ### Install The AgentBuilder Skill
39
+
40
+ ```bash
41
+ npx @standardagents/cli skill
42
+ ```
43
+
44
+ Opens an interactive picker and installs the bundled `agentbuilder` guidance
45
+ into a supported coding agent. Right now that means:
46
+
47
+ - Codex: installs a skill folder into `$CODEX_HOME/skills` or `~/.codex/skills`
48
+ - Claude Code: installs a user subagent into `~/.claude/agents/agentbuilder.md`
49
+
50
+ Use `--force` to overwrite an existing installed copy:
51
+
52
+ ```bash
53
+ npx @standardagents/cli skill --force
54
+ ```
55
+
56
+ Skip the picker with an explicit target:
57
+
58
+ ```bash
59
+ npx @standardagents/cli skill --agent codex
60
+ npx @standardagents/cli skill --agent claude
61
+ ```
62
+
38
63
  ## Manual Configuration
39
64
 
40
65
  If you prefer to configure manually, add the following to your `wrangler.jsonc`:
@@ -15,7 +15,10 @@ export default defineConfig({
15
15
  },
16
16
  },
17
17
  server: {
18
+ host: '0.0.0.0',
18
19
  port: 5174,
20
+ strictPort: true,
21
+ allowedHosts: true,
19
22
  },
20
23
  build: {
21
24
  outDir: '../dist/vite',
package/dist/index.js CHANGED
@@ -11,6 +11,8 @@ import { loadFile, writeFile, generateCode } from 'magicast';
11
11
  import { addVitePlugin } from 'magicast/helpers';
12
12
  import net from 'net';
13
13
  import { fileURLToPath } from 'url';
14
+ import os from 'os';
15
+ import { copySkill, readSkillFile } from '@standardagents/skill';
14
16
 
15
17
  var logger = {
16
18
  success: (message) => {
@@ -227,7 +229,7 @@ Models define which LLM provider and model to use for prompts.
227
229
  | Property | Type | Required | Description |
228
230
  |----------|------|----------|-------------|
229
231
  | \`name\` | \`string\` | Yes | Unique identifier for this model configuration |
230
- | \`provider\` | \`'openai' \\| 'anthropic' \\| 'openrouter' \\| 'google' \\| 'cerebras'\` | Yes | LLM provider |
232
+ | \`provider\` | \`'openai' \\| 'anthropic' \\| 'openrouter' \\| 'google' \\| 'cerebras' \\| 'groq' \\| 'xai'\` | Yes | LLM provider |
231
233
  | \`model\` | \`string\` | Yes | Model ID sent to provider API |
232
234
  | \`fallbacks\` | \`string[]\` | No | Fallback model names to try if primary fails |
233
235
  | \`inputPrice\` | \`number\` | No | Cost per 1M input tokens (USD) |
@@ -266,10 +268,12 @@ Set these environment variables in \`.dev.vars\` (local) or Cloudflare secrets (
266
268
  | Provider | Environment Variable |
267
269
  |----------|---------------------|
268
270
  | Cerebras | \`CEREBRAS_API_KEY\` |
271
+ | Groq | \`GROQ_API_KEY\` |
269
272
  | OpenAI | \`OPENAI_API_KEY\` |
270
273
  | Anthropic | \`ANTHROPIC_API_KEY\` |
271
274
  | OpenRouter | \`OPENROUTER_API_KEY\` |
272
275
  | Google | \`GOOGLE_API_KEY\` |
276
+ | xAI | \`XAI_API_KEY\` |
273
277
 
274
278
  ## Fallback Strategy
275
279
 
@@ -298,7 +302,8 @@ export default defineModel({
298
302
 
299
303
  - **Name by use case**, not model ID (e.g., \`fast\`, \`default\`, \`heavy\`)
300
304
  - **Configure fallbacks** for production reliability
301
- - **Set pricing** for cost tracking in logs
305
+ - **Set pricing** for cost tracking in logs when your provider or runtime does not supply it automatically
306
+ - **Cerebras note:** documented Cerebras models have built-in fallback pricing for request logs, but custom/private Cerebras models should still set \`inputPrice\` and \`outputPrice\`
302
307
  - **Use environment variables** for API keys, never hardcode
303
308
 
304
309
  ## Documentation
@@ -1815,11 +1820,14 @@ function detectPackageManager() {
1815
1820
  if (fs3.existsSync("package-lock.json")) return "npm";
1816
1821
  return "npm";
1817
1822
  }
1818
- function getPackageVersion() {
1823
+ function getWorkspacePackageVersion() {
1819
1824
  if (process.env.STANDARDAGENTS_WORKSPACE === "1") {
1820
1825
  return "workspace:*";
1821
1826
  }
1822
- return "0.13.1";
1827
+ return "0.13.2";
1828
+ }
1829
+ function getSipPackageVersion() {
1830
+ return "1.0.1";
1823
1831
  }
1824
1832
  async function selectPackageManager(detected) {
1825
1833
  const options = ["npm", "pnpm", "yarn", "bun"];
@@ -1963,17 +1971,29 @@ export default defineConfig({
1963
1971
  logger.info("Step 2: Configuring environment variables...");
1964
1972
  logger.log("");
1965
1973
  const encryptionKey = crypto.randomBytes(32).toString("hex");
1974
+ let cloudflareToken = "";
1975
+ let cloudflareAccountId = "";
1966
1976
  let cerebrasKey = "";
1977
+ let googleKey = "";
1978
+ let groqKey = "";
1967
1979
  let openrouterKey = "";
1968
1980
  let openaiKey = "";
1981
+ let xaiKey = "";
1969
1982
  let adminPassword = "";
1970
1983
  if (!options.yes) {
1971
1984
  logger.log("API keys are optional but required to use AI models.");
1972
1985
  logger.log("You can add them later by editing .dev.vars");
1973
1986
  logger.log("");
1987
+ cloudflareToken = await prompt("Cloudflare Workers AI API token (optional, press Enter to skip): ");
1988
+ if (cloudflareToken) {
1989
+ cloudflareAccountId = await prompt("Cloudflare Account ID: ");
1990
+ }
1974
1991
  cerebrasKey = await prompt("Cerebras API key (optional, press Enter to skip): ");
1992
+ googleKey = await prompt("Google Gemini API key (optional, press Enter to skip): ");
1993
+ groqKey = await prompt("Groq API key (optional, press Enter to skip): ");
1975
1994
  openrouterKey = await prompt("OpenRouter API key (optional, press Enter to skip): ");
1976
1995
  openaiKey = await prompt("OpenAI API key (optional, press Enter to skip): ");
1996
+ xaiKey = await prompt("xAI API key (optional, press Enter to skip): ");
1977
1997
  logger.log("");
1978
1998
  logger.log("Set a temporary admin password for development access.");
1979
1999
  logger.log('Press Enter to use the default password "admin".');
@@ -2003,7 +2023,8 @@ export default defineConfig({
2003
2023
  try {
2004
2024
  const installCmd = pm === "npm" ? "install" : "add";
2005
2025
  const devFlag = pm === "npm" ? "--save-dev" : "-D";
2006
- const packageVersion = getPackageVersion();
2026
+ const workspacePackageVersion = getWorkspacePackageVersion();
2027
+ const sipPackageVersion = getSipPackageVersion();
2007
2028
  await runCommand(pm, [
2008
2029
  installCmd,
2009
2030
  devFlag,
@@ -2011,19 +2032,31 @@ export default defineConfig({
2011
2032
  "wrangler"
2012
2033
  ], projectPath);
2013
2034
  const deps = [
2014
- `@standardagents/builder@${packageVersion}`,
2015
- `@standardagents/spec@${packageVersion}`,
2016
- `@standardagents/sip@${packageVersion}`,
2035
+ `@standardagents/builder@${workspacePackageVersion}`,
2036
+ `@standardagents/spec@${workspacePackageVersion}`,
2037
+ `@standardagents/sip@${sipPackageVersion}`,
2017
2038
  "zod"
2018
2039
  ];
2040
+ if (cloudflareToken) {
2041
+ deps.push(`@standardagents/cloudflare@${workspacePackageVersion}`);
2042
+ }
2019
2043
  if (cerebrasKey) {
2020
- deps.push(`@standardagents/cerebras@${packageVersion}`);
2044
+ deps.push(`@standardagents/cerebras@${workspacePackageVersion}`);
2045
+ }
2046
+ if (googleKey) {
2047
+ deps.push(`@standardagents/google@${workspacePackageVersion}`);
2048
+ }
2049
+ if (groqKey) {
2050
+ deps.push(`@standardagents/groq@${workspacePackageVersion}`);
2021
2051
  }
2022
2052
  if (openaiKey) {
2023
- deps.push(`@standardagents/openai@${packageVersion}`);
2053
+ deps.push(`@standardagents/openai@${workspacePackageVersion}`);
2024
2054
  }
2025
2055
  if (openrouterKey) {
2026
- deps.push(`@standardagents/openrouter@${packageVersion}`);
2056
+ deps.push(`@standardagents/openrouter@${workspacePackageVersion}`);
2057
+ }
2058
+ if (xaiKey) {
2059
+ deps.push(`@standardagents/xai@${workspacePackageVersion}`);
2027
2060
  }
2028
2061
  await runCommand(pm, [installCmd, ...deps], projectPath);
2029
2062
  } catch (error) {
@@ -2052,11 +2085,28 @@ export default defineConfig({
2052
2085
  "# AI Provider API Keys",
2053
2086
  "# Uncomment and add your keys as needed"
2054
2087
  ];
2088
+ if (cloudflareToken) {
2089
+ devVarsLines.push(`CLOUDFLARE_API_TOKEN=${cloudflareToken}`);
2090
+ devVarsLines.push(`CLOUDFLARE_ACCOUNT_ID=${cloudflareAccountId}`);
2091
+ } else {
2092
+ devVarsLines.push("# CLOUDFLARE_API_TOKEN=your-cloudflare-workers-ai-token");
2093
+ devVarsLines.push("# CLOUDFLARE_ACCOUNT_ID=your-cloudflare-account-id");
2094
+ }
2055
2095
  if (cerebrasKey) {
2056
2096
  devVarsLines.push(`CEREBRAS_API_KEY=${cerebrasKey}`);
2057
2097
  } else {
2058
2098
  devVarsLines.push("# CEREBRAS_API_KEY=your-cerebras-key");
2059
2099
  }
2100
+ if (googleKey) {
2101
+ devVarsLines.push(`GOOGLE_API_KEY=${googleKey}`);
2102
+ } else {
2103
+ devVarsLines.push("# GOOGLE_API_KEY=your-google-gemini-key");
2104
+ }
2105
+ if (groqKey) {
2106
+ devVarsLines.push(`GROQ_API_KEY=${groqKey}`);
2107
+ } else {
2108
+ devVarsLines.push("# GROQ_API_KEY=your-groq-key");
2109
+ }
2060
2110
  if (openrouterKey) {
2061
2111
  devVarsLines.push(`OPENROUTER_API_KEY=${openrouterKey}`);
2062
2112
  } else {
@@ -2067,6 +2117,11 @@ export default defineConfig({
2067
2117
  } else {
2068
2118
  devVarsLines.push("# OPENAI_API_KEY=your-openai-key");
2069
2119
  }
2120
+ if (xaiKey) {
2121
+ devVarsLines.push(`XAI_API_KEY=${xaiKey}`);
2122
+ } else {
2123
+ devVarsLines.push("# XAI_API_KEY=your-xai-key");
2124
+ }
2070
2125
  devVarsLines.push("");
2071
2126
  const devVarsPath = path3.join(projectPath, ".dev.vars");
2072
2127
  fs3.writeFileSync(devVarsPath, devVarsLines.join("\n"), "utf-8");
@@ -3337,10 +3392,188 @@ async function deploy(options) {
3337
3392
  process.exit(1);
3338
3393
  }
3339
3394
  }
3395
+ var DEFAULT_SKILL_NAME = "agentbuilder";
3396
+ function resolveCodexHome(env = process.env, homeDir = os.homedir()) {
3397
+ return env.CODEX_HOME || path3.join(homeDir, ".codex");
3398
+ }
3399
+ function resolveClaudeHome(homeDir = os.homedir()) {
3400
+ return path3.join(homeDir, ".claude");
3401
+ }
3402
+ function expandHomePath(inputPath, homeDir = os.homedir()) {
3403
+ if (inputPath === "~") {
3404
+ return homeDir;
3405
+ }
3406
+ if (inputPath.startsWith("~/")) {
3407
+ return path3.join(homeDir, inputPath.slice(2));
3408
+ }
3409
+ return inputPath;
3410
+ }
3411
+ function buildInstallTargets(options = {}, env = process.env, homeDir = os.homedir()) {
3412
+ const customRoot = options.dir ? path3.resolve(expandHomePath(options.dir, homeDir)) : null;
3413
+ const codexHome = resolveCodexHome(env, homeDir);
3414
+ const claudeHome = resolveClaudeHome(homeDir);
3415
+ return [
3416
+ {
3417
+ id: "codex",
3418
+ label: "Codex",
3419
+ summary: "Install as a Codex skill folder",
3420
+ detected: fs3.existsSync(codexHome),
3421
+ installPath: customRoot ?? path3.join(codexHome, "skills")
3422
+ },
3423
+ {
3424
+ id: "claude",
3425
+ label: "Claude Code",
3426
+ summary: "Install as a Claude Code user subagent",
3427
+ detected: fs3.existsSync(claudeHome),
3428
+ installPath: customRoot ?? path3.join(claudeHome, "agents")
3429
+ }
3430
+ ];
3431
+ }
3432
+ function resolveSelectedTarget(targetId, options = {}, env = process.env, homeDir = os.homedir()) {
3433
+ const target = buildInstallTargets(options, env, homeDir).find(
3434
+ (candidate) => candidate.id === targetId
3435
+ );
3436
+ if (!target) {
3437
+ throw new Error(`Unknown install target "${targetId}".`);
3438
+ }
3439
+ return target;
3440
+ }
3441
+ function buildClaudeSubagentMarkdown(skillName, description, body) {
3442
+ const normalizedBody = body.replace(/^\uFEFF/, "").trim();
3443
+ return [
3444
+ "---",
3445
+ `name: ${skillName}`,
3446
+ `description: ${description}`,
3447
+ "---",
3448
+ "",
3449
+ normalizedBody,
3450
+ ""
3451
+ ].join("\n");
3452
+ }
3453
+ async function selectInstallTarget(targets) {
3454
+ return new Promise((resolve) => {
3455
+ const stdin = process.stdin;
3456
+ const stdout = process.stdout;
3457
+ let selectedIndex = 0;
3458
+ const render = (initial = false) => {
3459
+ const lines = [];
3460
+ lines.push("Choose where to install the AgentBuilder skill:");
3461
+ lines.push("");
3462
+ for (let i = 0; i < targets.length; i++) {
3463
+ const target = targets[i];
3464
+ const isSelected = i === selectedIndex;
3465
+ const cursor = isSelected ? "\x1B[36m\u276F\x1B[0m" : " ";
3466
+ const title = isSelected ? "\x1B[36m" : "\x1B[90m";
3467
+ const detection = target.detected ? "\x1B[32m(detected)\x1B[0m" : "\x1B[90m(not found yet)\x1B[0m";
3468
+ lines.push(`${cursor} ${title}${target.label}\x1B[0m ${detection}`);
3469
+ lines.push(` ${target.summary}`);
3470
+ lines.push(` ${target.installPath}`);
3471
+ lines.push("");
3472
+ }
3473
+ lines.push("Use arrows to move, Enter to install, Ctrl+C to cancel.");
3474
+ if (!initial) {
3475
+ stdout.write("\x1B[?25l");
3476
+ stdout.write(`\x1B[${lines.length}A`);
3477
+ stdout.write("\x1B[0J");
3478
+ }
3479
+ stdout.write(lines.join("\n") + "\n");
3480
+ };
3481
+ render(true);
3482
+ const wasRaw = stdin.isRaw;
3483
+ if (stdin.isTTY) {
3484
+ stdin.setRawMode(true);
3485
+ }
3486
+ stdin.resume();
3487
+ stdin.setEncoding("utf8");
3488
+ const cleanup = () => {
3489
+ stdin.setRawMode(wasRaw ?? false);
3490
+ stdin.pause();
3491
+ stdin.removeListener("data", onData);
3492
+ stdout.write("\x1B[?25h");
3493
+ };
3494
+ const onData = (key) => {
3495
+ if (key === "\x1B[A" || key === "k") {
3496
+ selectedIndex = (selectedIndex - 1 + targets.length) % targets.length;
3497
+ render();
3498
+ } else if (key === "\x1B[B" || key === "j") {
3499
+ selectedIndex = (selectedIndex + 1) % targets.length;
3500
+ render();
3501
+ } else if (key === "\r" || key === "\n") {
3502
+ cleanup();
3503
+ resolve(targets[selectedIndex]);
3504
+ } else if (key === "") {
3505
+ cleanup();
3506
+ stdout.write("\n");
3507
+ process.exit(1);
3508
+ }
3509
+ };
3510
+ stdin.on("data", onData);
3511
+ });
3512
+ }
3513
+ async function installBundledSkill(targetId, skillName = DEFAULT_SKILL_NAME, options = {}) {
3514
+ const target = resolveSelectedTarget(targetId, options);
3515
+ if (target.id === "codex") {
3516
+ const targetDir = path3.join(target.installPath, skillName);
3517
+ if (fs3.existsSync(targetDir) && !options.force) {
3518
+ throw new Error(
3519
+ `Skill already exists at ${targetDir}. Re-run with --force to overwrite it.`
3520
+ );
3521
+ }
3522
+ return copySkill(skillName, target.installPath, {
3523
+ overwrite: options.force ?? false
3524
+ });
3525
+ }
3526
+ const targetFile = path3.join(target.installPath, `${skillName}.md`);
3527
+ if (fs3.existsSync(targetFile) && !options.force) {
3528
+ throw new Error(
3529
+ `Claude subagent already exists at ${targetFile}. Re-run with --force to overwrite it.`
3530
+ );
3531
+ }
3532
+ const skillBody = await readSkillFile(skillName);
3533
+ const subagentMarkdown = buildClaudeSubagentMarkdown(
3534
+ skillName,
3535
+ "Use for Standard Agents and AgentBuilder architecture, composition, subagent design, and implementation work.",
3536
+ skillBody
3537
+ );
3538
+ fs3.mkdirSync(target.installPath, { recursive: true });
3539
+ fs3.writeFileSync(targetFile, subagentMarkdown, "utf8");
3540
+ return targetFile;
3541
+ }
3542
+ function isInteractiveTerminal() {
3543
+ return Boolean(process.stdin.isTTY && process.stdout.isTTY);
3544
+ }
3545
+ async function skill(options = {}) {
3546
+ try {
3547
+ const selectedTarget = options.agent ? resolveSelectedTarget(options.agent, options) : isInteractiveTerminal() ? await selectInstallTarget(buildInstallTargets(options)) : resolveSelectedTarget("codex", options);
3548
+ logger.log("");
3549
+ logger.info(`Installing AgentBuilder skill into ${selectedTarget.label}...`);
3550
+ const installedPath = await installBundledSkill(
3551
+ selectedTarget.id,
3552
+ DEFAULT_SKILL_NAME,
3553
+ options
3554
+ );
3555
+ logger.success(`Installed ${DEFAULT_SKILL_NAME} into ${selectedTarget.label}`);
3556
+ logger.log("");
3557
+ logger.log(`Path: ${installedPath}`);
3558
+ logger.log("");
3559
+ logger.log("Next steps:");
3560
+ if (selectedTarget.id === "codex") {
3561
+ logger.log(" Restart Codex if it is already running");
3562
+ logger.log(` Edit ${path3.join(installedPath, "SKILL.md")} to continue customizing the skill`);
3563
+ } else {
3564
+ logger.log(" Restart Claude Code if it is already running");
3565
+ logger.log(` Edit ${installedPath} to continue customizing the subagent`);
3566
+ }
3567
+ } catch (error) {
3568
+ logger.log("");
3569
+ logger.error(error instanceof Error ? error.message : "Failed to install skill");
3570
+ process.exit(1);
3571
+ }
3572
+ }
3340
3573
 
3341
3574
  // src/index.ts
3342
3575
  var program = new Command();
3343
- program.name("agents").description("CLI tool for Standard Agents / AgentBuilder").version("0.13.1");
3576
+ program.name("agents").description("CLI tool for Standard Agents / AgentBuilder").version("0.13.2");
3344
3577
  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);
3345
3578
  program.command("scaffold").description("Add Standard Agents to an existing Vite project").option("--force", "Overwrite existing configuration").action(scaffold);
3346
3579
  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);
@@ -3348,6 +3581,7 @@ program.command("pack [agent-name]").description("Pack an agent with all its dep
3348
3581
  program.command("unpack [package]").description("Unpack a packed agent to the local agents directory").option("--no-signatures", "Remove package signatures (fully editable)").action(unpack);
3349
3582
  program.command("list-packed").description("List all discovered packed agents").action(listPacked);
3350
3583
  program.command("deploy").description("Build and deploy your project to the Standard Agents platform").option("--api-key <key>", "Platform API key (overrides PLATFORM_API_KEY env var)").option("--endpoint <url>", "Platform API endpoint (default: https://api.standardagents.ai)").action(deploy);
3584
+ program.command("skill").description("Install the bundled AgentBuilder guidance into a supported coding agent").option("--agent <target>", "Install target: codex or claude").option("--dir <path>", "Install directory override for the selected target").option("--force", "Overwrite an existing installed skill").action(skill);
3351
3585
  program.parse();
3352
3586
  //# sourceMappingURL=index.js.map
3353
3587
  //# sourceMappingURL=index.js.map