@standardagents/cli 0.15.3 → 0.16.1-next.1e58032

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
@@ -6,12 +6,12 @@ import crypto from 'crypto';
6
6
  import os3 from 'os';
7
7
  import net from 'net';
8
8
  import readline from 'readline';
9
- import { spawn, execSync, spawnSync } from 'child_process';
9
+ import { spawn, execFileSync, spawnSync } from 'child_process';
10
10
  import { fileURLToPath, pathToFileURL } from 'url';
11
- import { FIRST_PARTY_PROVIDER_PACKAGES, renderWranglerJson, renderWorkerIndex, renderDurableThread, renderDurableAgentBuilder, ROOT_CLAUDE_MD, AGENTS_CLAUDE_MD, PROMPTS_CLAUDE_MD, MODELS_CLAUDE_MD, TOOLS_CLAUDE_MD, HOOKS_CLAUDE_MD, API_CLAUDE_MD } from '@standardagents/agentbuilder-template';
11
+ import { FIRST_PARTY_PROVIDER_PACKAGES, AGENT_DEFINITIONS_AGENTS_MD, PROMPTS_AGENTS_MD, MODELS_AGENTS_MD, TOOLS_AGENTS_MD, HOOKS_AGENTS_MD, API_AGENTS_MD, renderAgentBuilderSupportFiles, ROOT_AGENTS_MD } from '@standardagents/agentbuilder-template';
12
12
  import chalk from 'chalk';
13
13
  import { parse, modify, applyEdits } from 'jsonc-parser';
14
- import { loadFile, writeFile, generateCode } from 'magicast';
14
+ import { loadFile, writeFile } from 'magicast';
15
15
  import { addVitePlugin } from 'magicast/helpers';
16
16
  import { useState, useMemo } from 'react';
17
17
  import { render, renderToString, Box, Text, useApp, useInput } from 'ink';
@@ -235,30 +235,11 @@ function openBrowser(url) {
235
235
  return false;
236
236
  }
237
237
  }
238
- function getScaffoldCompatibilityDate() {
239
- return "2025-08-13";
240
- }
241
238
  function getScaffoldStandardAgentsVersion() {
242
239
  if (process.env.STANDARDAGENTS_WORKSPACE === "1") {
243
240
  return "workspace:*";
244
241
  }
245
- return "0.15.3";
246
- }
247
- function getScaffoldCloudflareVitePluginVersion() {
248
- return "^1.17.0";
249
- }
250
- function getProjectName(cwd) {
251
- const packageJsonPath = path7.join(cwd, "package.json");
252
- if (fs3.existsSync(packageJsonPath)) {
253
- try {
254
- const pkg = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
255
- if (pkg.name) {
256
- return pkg.name.replace(/^@[^/]+\//, "");
257
- }
258
- } catch {
259
- }
260
- }
261
- return path7.basename(cwd);
242
+ return "0.16.1-next.1e58032";
262
243
  }
263
244
  function findViteConfig(cwd) {
264
245
  const candidates = ["vite.config.ts", "vite.config.js", "vite.config.mts", "vite.config.mjs"];
@@ -270,16 +251,6 @@ function findViteConfig(cwd) {
270
251
  }
271
252
  return null;
272
253
  }
273
- function findWranglerConfig(cwd) {
274
- const candidates = ["wrangler.jsonc", "wrangler.json"];
275
- for (const candidate of candidates) {
276
- const configPath = path7.join(cwd, candidate);
277
- if (fs3.existsSync(configPath)) {
278
- return configPath;
279
- }
280
- }
281
- return null;
282
- }
283
254
  function dependencySectionFor(pkg, packageName, fallback) {
284
255
  if (pkg.dependencies?.[packageName] !== void 0) return "dependencies";
285
256
  if (pkg.devDependencies?.[packageName] !== void 0) return "devDependencies";
@@ -294,27 +265,20 @@ function setPackageDependency(packageJsonText, section, packageName, version) {
294
265
  function updatePackageDependencies(cwd, versions = {}) {
295
266
  const packageJsonPath = path7.join(cwd, "package.json");
296
267
  if (!fs3.existsSync(packageJsonPath)) {
297
- logger.warning("No package.json found. Install @standardagents/builder and @cloudflare/vite-plugin manually.");
268
+ logger.warning("No package.json found. Install @standardagents/builder manually.");
298
269
  return false;
299
270
  }
300
271
  try {
301
272
  const text = fs3.readFileSync(packageJsonPath, "utf-8");
302
273
  const pkg = JSON.parse(text);
303
274
  const desiredBuilderVersion = versions.standardAgents ?? getScaffoldStandardAgentsVersion();
304
- const desiredCloudflareVersion = versions.cloudflareVitePlugin ?? getScaffoldCloudflareVitePluginVersion();
305
275
  const builderSection = dependencySectionFor(pkg, "@standardagents/builder", "dependencies");
306
- const cloudflareSection = dependencySectionFor(pkg, "@cloudflare/vite-plugin", "devDependencies");
307
276
  let result = text;
308
277
  let changed = false;
309
278
  if (pkg[builderSection]?.["@standardagents/builder"] !== desiredBuilderVersion) {
310
279
  result = setPackageDependency(result, builderSection, "@standardagents/builder", desiredBuilderVersion);
311
280
  changed = true;
312
281
  }
313
- const currentAfterBuilder = JSON.parse(result);
314
- if (currentAfterBuilder[cloudflareSection]?.["@cloudflare/vite-plugin"] !== desiredCloudflareVersion) {
315
- result = setPackageDependency(result, cloudflareSection, "@cloudflare/vite-plugin", desiredCloudflareVersion);
316
- changed = true;
317
- }
318
282
  if (!changed) {
319
283
  logger.info("package.json already has current Standard Agents dependencies");
320
284
  return true;
@@ -332,28 +296,18 @@ async function modifyViteConfig(configPath, force) {
332
296
  try {
333
297
  const mod = await loadFile(configPath);
334
298
  const code = fs3.readFileSync(configPath, "utf-8");
335
- const hasCloudflare = code.includes("@cloudflare/vite-plugin") || code.includes("cloudflare()");
336
- const hasAgentBuilder = code.includes("@standardagents/builder") || code.includes("agentbuilder()");
337
- if (hasCloudflare && hasAgentBuilder && !force) {
338
- logger.info("Vite config already includes Standard Agents plugins");
299
+ const hasAgentBuilder = code.includes("@standardagents/builder") || code.includes("builder()") || code.includes("agentbuilder()");
300
+ if (hasAgentBuilder && !force) {
301
+ logger.info("Vite config already includes builder plugin");
339
302
  return true;
340
303
  }
341
304
  if (!hasAgentBuilder || force) {
342
305
  addVitePlugin(mod, {
343
306
  from: "@standardagents/builder",
344
- imported: "agentbuilder",
345
- constructor: "agentbuilder",
346
- options: { mountPoint: "/" }
347
- });
348
- logger.success("Added agentbuilder plugin to vite.config");
349
- }
350
- if (!hasCloudflare || force) {
351
- addVitePlugin(mod, {
352
- from: "@cloudflare/vite-plugin",
353
- imported: "cloudflare",
354
- constructor: "cloudflare"
307
+ imported: "builder",
308
+ constructor: "builder"
355
309
  });
356
- logger.success("Added cloudflare plugin to vite.config");
310
+ logger.success("Added builder plugin to vite.config");
357
311
  }
358
312
  await writeFile(mod, configPath);
359
313
  return true;
@@ -362,257 +316,42 @@ async function modifyViteConfig(configPath, force) {
362
316
  logger.log("");
363
317
  logger.log("Please manually add the following to your vite.config.ts:");
364
318
  logger.log("");
365
- logger.log(` import { agentbuilder } from '@standardagents/builder'`);
366
- logger.log(` import { cloudflare } from '@cloudflare/vite-plugin'`);
319
+ logger.log(` import { builder } from '@standardagents/builder'`);
367
320
  logger.log("");
368
- logger.log(` plugins: [agentbuilder({ mountPoint: '/' }), cloudflare()]`);
321
+ logger.log(` plugins: [builder()]`);
369
322
  logger.log("");
370
323
  return false;
371
324
  }
372
325
  }
373
- function createOrUpdateWranglerConfig(cwd, projectName, force) {
374
- const existingConfig = findWranglerConfig(cwd);
375
- if (existingConfig && !force) {
376
- try {
377
- const text = fs3.readFileSync(existingConfig, "utf-8");
378
- const config = parse(text);
379
- const hasBindings = config.durable_objects?.bindings?.some(
380
- (b) => b.name === "AGENT_BUILDER_THREAD" || b.name === "AGENT_BUILDER"
381
- );
382
- const hasCodeLoader = config.worker_loaders?.some(
383
- (loader) => loader.binding === "AGENT_BUILDER_CODE_LOADER"
384
- );
385
- const hasCodeCompatibilityDate = config.vars?.AGENT_BUILDER_CODE_COMPATIBILITY_DATE === getScaffoldCompatibilityDate();
386
- const hasCtxExportsFlag = Array.isArray(config.compatibility_flags) ? config.compatibility_flags.includes("enable_ctx_exports") : false;
387
- if (hasBindings && hasCodeLoader && hasCodeCompatibilityDate && hasCtxExportsFlag) {
388
- logger.info("wrangler.jsonc already configured for Standard Agents");
389
- return true;
390
- }
391
- let result = text;
392
- if (!hasCodeLoader) {
393
- const loaders = [...config.worker_loaders || [], { binding: "AGENT_BUILDER_CODE_LOADER" }];
394
- const edits = modify(result, ["worker_loaders"], loaders, {});
395
- result = applyEdits(result, edits);
396
- }
397
- if (!hasCodeCompatibilityDate) {
398
- const vars = {
399
- ...config.vars || {},
400
- AGENT_BUILDER_CODE_COMPATIBILITY_DATE: getScaffoldCompatibilityDate()
401
- };
402
- const edits = modify(result, ["vars"], vars, {});
403
- result = applyEdits(result, edits);
404
- }
405
- if (!hasCtxExportsFlag) {
406
- const flags = Array.isArray(config.compatibility_flags) ? [...config.compatibility_flags, "enable_ctx_exports"] : ["nodejs_compat", "enable_ctx_exports"];
407
- const edits = modify(result, ["compatibility_flags"], flags, {});
408
- result = applyEdits(result, edits);
409
- }
410
- if (!config.durable_objects) {
411
- const edits = modify(result, ["durable_objects"], {
412
- bindings: [
413
- { name: "AGENT_BUILDER_THREAD", class_name: "DurableThread" },
414
- { name: "AGENT_BUILDER", class_name: "DurableAgentBuilder" }
415
- ]
416
- }, {});
417
- result = applyEdits(result, edits);
418
- } else {
419
- const bindings = config.durable_objects.bindings || [];
420
- if (!bindings.some((b) => b.name === "AGENT_BUILDER_THREAD")) {
421
- bindings.push({ name: "AGENT_BUILDER_THREAD", class_name: "DurableThread" });
422
- }
423
- if (!bindings.some((b) => b.name === "AGENT_BUILDER")) {
424
- bindings.push({ name: "AGENT_BUILDER", class_name: "DurableAgentBuilder" });
425
- }
426
- const edits = modify(result, ["durable_objects", "bindings"], bindings, {});
427
- result = applyEdits(result, edits);
428
- }
429
- if (!config.migrations) {
430
- const edits = modify(result, ["migrations"], [
431
- { tag: "v1", new_sqlite_classes: ["DurableThread"] },
432
- { tag: "v2", new_sqlite_classes: ["DurableAgentBuilder"] }
433
- ], {});
434
- result = applyEdits(result, edits);
435
- }
436
- if (!config.main || !config.main.includes("worker")) {
437
- const edits = modify(result, ["main"], "worker/index.ts", {});
438
- result = applyEdits(result, edits);
439
- }
440
- if (!config.assets) {
441
- const edits = modify(result, ["assets"], {
442
- directory: "dist/client",
443
- not_found_handling: "single-page-application",
444
- binding: "ASSETS",
445
- run_worker_first: ["/**"]
446
- }, {});
447
- result = applyEdits(result, edits);
448
- }
449
- fs3.writeFileSync(existingConfig, result, "utf-8");
450
- logger.success("Updated wrangler.jsonc with Standard Agents configuration");
451
- return true;
452
- } catch (error) {
453
- logger.warning(`Could not update wrangler config: ${error}`);
454
- return false;
455
- }
456
- }
457
- const wranglerPath = path7.join(cwd, "wrangler.jsonc");
458
- const sanitizedName = projectName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
459
- fs3.writeFileSync(
460
- wranglerPath,
461
- renderWranglerJson({
462
- projectName: sanitizedName,
463
- compatibilityDate: getScaffoldCompatibilityDate()
464
- }),
465
- "utf-8"
466
- );
467
- logger.success("Created wrangler.jsonc");
468
- return true;
469
- }
470
- function getWorkerEntryPoint(cwd) {
471
- const wranglerConfig = findWranglerConfig(cwd);
472
- if (wranglerConfig) {
473
- try {
474
- const text = fs3.readFileSync(wranglerConfig, "utf-8");
475
- const config = parse(text);
476
- if (config.main) {
477
- return path7.join(cwd, config.main);
478
- }
479
- } catch {
480
- }
481
- }
482
- return path7.join(cwd, "worker", "index.ts");
483
- }
484
- async function createOrUpdateWorkerEntry(cwd, force) {
485
- const entryPath = getWorkerEntryPoint(cwd);
486
- const entryDir = path7.dirname(entryPath);
487
- if (!fs3.existsSync(entryDir)) {
488
- fs3.mkdirSync(entryDir, { recursive: true });
489
- logger.success(`Created ${path7.relative(cwd, entryDir)} directory`);
490
- }
491
- if (!fs3.existsSync(entryPath)) {
492
- fs3.writeFileSync(entryPath, renderWorkerIndex(), "utf-8");
493
- logger.success(`Created ${path7.relative(cwd, entryPath)}`);
494
- return true;
495
- }
496
- const content = fs3.readFileSync(entryPath, "utf-8");
497
- const hasRouter = content.includes("virtual:@standardagents/builder") && content.includes("router");
498
- const hasDurableExports = content.includes("DurableThread") && content.includes("DurableAgentBuilder");
499
- const hasCodeBridge = content.includes("CodeExecutionBridge");
500
- if (hasRouter && hasDurableExports && hasCodeBridge && !force) {
501
- logger.info(`${path7.relative(cwd, entryPath)} already configured`);
502
- return true;
503
- }
504
- if (hasRouter && hasDurableExports && !hasCodeBridge && !force) {
505
- fs3.writeFileSync(
506
- entryPath,
507
- `${content.trimEnd()}
508
-
509
- export { CodeExecutionBridge } from "virtual:@standardagents/builder"
510
- `,
511
- "utf-8"
512
- );
513
- logger.success(`Updated ${path7.relative(cwd, entryPath)} with CodeExecutionBridge export`);
514
- return true;
515
- }
516
- try {
517
- const mod = await loadFile(entryPath);
518
- if (!content.includes("virtual:@standardagents/builder") || force) {
519
- mod.imports.$add({
520
- from: "virtual:@standardagents/builder",
521
- imported: "router",
522
- local: "router"
523
- });
524
- }
525
- if (!content.includes("'../agents/Thread'") || force) {
526
- mod.imports.$add({
527
- from: "../agents/Thread",
528
- imported: "default",
529
- local: "DurableThread"
530
- });
531
- }
532
- if (!content.includes("'../agents/AgentBuilder'") || force) {
533
- mod.imports.$add({
534
- from: "../agents/AgentBuilder",
535
- imported: "default",
536
- local: "DurableAgentBuilder"
537
- });
538
- }
539
- const { code } = generateCode(mod);
540
- if (force || !hasRouter) {
541
- fs3.writeFileSync(entryPath, renderWorkerIndex(), "utf-8");
542
- logger.success(`Updated ${path7.relative(cwd, entryPath)} with Standard Agents router`);
326
+ function createDirectoriesAndDocs(cwd) {
327
+ function writeAgentsDocWithClaudeSymlink(dirPath, doc, label) {
328
+ const agentsDocPath = path7.join(dirPath, "AGENTS.md");
329
+ const claudeDocPath = path7.join(dirPath, "CLAUDE.md");
330
+ if (!fs3.existsSync(agentsDocPath)) {
331
+ fs3.writeFileSync(agentsDocPath, doc, "utf-8");
332
+ logger.success(`Created ${label}/AGENTS.md`);
543
333
  }
544
- return true;
545
- } catch (error) {
546
- if (force) {
547
- fs3.writeFileSync(entryPath, renderWorkerIndex(), "utf-8");
548
- logger.success(`Created ${path7.relative(cwd, entryPath)}`);
549
- return true;
334
+ if (!fs3.existsSync(claudeDocPath)) {
335
+ fs3.symlinkSync("AGENTS.md", claudeDocPath);
336
+ logger.success(`Created ${label}/CLAUDE.md symlink`);
550
337
  }
551
- logger.warning(`Could not automatically modify ${path7.relative(cwd, entryPath)}`);
552
- logger.log("");
553
- logger.log("Please ensure your worker entry point includes:");
554
- logger.log("");
555
- logger.log(` import { router } from "virtual:@standardagents/builder"`);
556
- logger.log(` import DurableThread from '../agents/Thread';`);
557
- logger.log(` import DurableAgentBuilder from '../agents/AgentBuilder';`);
558
- logger.log("");
559
- logger.log(" // In your fetch handler:");
560
- logger.log(" const res = router(request, env)");
561
- logger.log(" if (res) return res");
562
- logger.log("");
563
- logger.log(" // Export Durable Objects:");
564
- logger.log(" export { DurableThread, DurableAgentBuilder }");
565
- logger.log(' export { CodeExecutionBridge } from "virtual:@standardagents/builder"');
566
- logger.log("");
567
- return false;
568
- }
569
- }
570
- function createDurableObjects(cwd) {
571
- const agentsDir = path7.join(cwd, "agents");
572
- if (!fs3.existsSync(agentsDir)) {
573
- fs3.mkdirSync(agentsDir, { recursive: true });
574
- }
575
- const threadPath = path7.join(agentsDir, "Thread.ts");
576
- if (!fs3.existsSync(threadPath)) {
577
- fs3.writeFileSync(threadPath, renderDurableThread(), "utf-8");
578
- logger.success("Created agents/Thread.ts");
579
- } else {
580
- logger.info("agents/Thread.ts already exists");
581
- }
582
- const agentBuilderPath = path7.join(agentsDir, "AgentBuilder.ts");
583
- if (!fs3.existsSync(agentBuilderPath)) {
584
- fs3.writeFileSync(agentBuilderPath, renderDurableAgentBuilder(), "utf-8");
585
- logger.success("Created agents/AgentBuilder.ts");
586
- } else {
587
- logger.info("agents/AgentBuilder.ts already exists");
588
- }
589
- }
590
- function createDirectoriesAndDocs(cwd) {
591
- path7.join(cwd, "agents");
592
- const rootDocPath = path7.join(cwd, "CLAUDE.md");
593
- if (!fs3.existsSync(rootDocPath)) {
594
- fs3.writeFileSync(rootDocPath, ROOT_CLAUDE_MD, "utf-8");
595
- logger.success("Created CLAUDE.md");
596
338
  }
339
+ writeAgentsDocWithClaudeSymlink(cwd, ROOT_AGENTS_MD, ".");
597
340
  const directories = [
598
- { path: "agents/agents", doc: AGENTS_CLAUDE_MD },
599
- { path: "agents/prompts", doc: PROMPTS_CLAUDE_MD },
600
- { path: "agents/models", doc: MODELS_CLAUDE_MD },
601
- { path: "agents/tools", doc: TOOLS_CLAUDE_MD },
602
- { path: "agents/hooks", doc: HOOKS_CLAUDE_MD },
603
- { path: "agents/api", doc: API_CLAUDE_MD }
341
+ { path: "agents/agents", doc: AGENT_DEFINITIONS_AGENTS_MD },
342
+ { path: "agents/prompts", doc: PROMPTS_AGENTS_MD },
343
+ { path: "agents/models", doc: MODELS_AGENTS_MD },
344
+ { path: "agents/tools", doc: TOOLS_AGENTS_MD },
345
+ { path: "agents/hooks", doc: HOOKS_AGENTS_MD },
346
+ { path: "agents/api", doc: API_AGENTS_MD }
604
347
  ];
605
348
  for (const dir of directories) {
606
349
  const dirPath = path7.join(cwd, dir.path);
607
- const docPath = path7.join(dirPath, "CLAUDE.md");
608
350
  if (!fs3.existsSync(dirPath)) {
609
351
  fs3.mkdirSync(dirPath, { recursive: true });
610
352
  logger.success(`Created ${dir.path}`);
611
353
  }
612
- if (!fs3.existsSync(docPath)) {
613
- fs3.writeFileSync(docPath, dir.doc, "utf-8");
614
- logger.success(`Created ${dir.path}/CLAUDE.md`);
615
- }
354
+ writeAgentsDocWithClaudeSymlink(dirPath, dir.doc, dir.path);
616
355
  }
617
356
  }
618
357
  function updateTsConfig(cwd) {
@@ -627,7 +366,6 @@ function updateTsConfig(cwd) {
627
366
  let result = text;
628
367
  const types = config.compilerOptions?.types || [];
629
368
  const newTypes = [
630
- "./worker-configuration.d.ts",
631
369
  "./.agents/types.d.ts",
632
370
  "./.agents/virtual-module.d.ts"
633
371
  ].filter((t) => !types.includes(t));
@@ -637,7 +375,7 @@ function updateTsConfig(cwd) {
637
375
  result = applyEdits(result, edits);
638
376
  }
639
377
  const include = config.include || [];
640
- const newIncludes = ["worker", "agents"].filter((i) => !include.includes(i));
378
+ const newIncludes = ["agents", ".agents", "vite.config.ts"].filter((i) => !include.includes(i));
641
379
  if (newIncludes.length > 0) {
642
380
  const allIncludes = [...include, ...newIncludes];
643
381
  const edits = modify(result, ["include"], allIncludes, {});
@@ -661,9 +399,14 @@ function cleanupViteDefaults(cwd) {
661
399
  "src/typescript.svg",
662
400
  "src/vite-env.d.ts",
663
401
  "index.html",
664
- "public/vite.svg"
402
+ "public/vite.svg",
403
+ "wrangler.jsonc",
404
+ "wrangler.json",
405
+ "worker/index.ts",
406
+ "agents/Thread.ts",
407
+ "agents/AgentBuilder.ts"
665
408
  ];
666
- const dirsToRemove = ["src", "public"];
409
+ const dirsToRemove = ["src", "public", "worker"];
667
410
  for (const file of filesToRemove) {
668
411
  const filePath = path7.join(cwd, file);
669
412
  if (fs3.existsSync(filePath)) {
@@ -688,7 +431,6 @@ function cleanupViteDefaults(cwd) {
688
431
  }
689
432
  async function scaffold(options = {}) {
690
433
  const cwd = process.cwd();
691
- const projectName = getProjectName(cwd);
692
434
  const force = options.force || false;
693
435
  logger.info("Scaffolding Standard Agents...");
694
436
  logger.log("");
@@ -696,12 +438,9 @@ async function scaffold(options = {}) {
696
438
  if (viteConfigPath) {
697
439
  await modifyViteConfig(viteConfigPath, force);
698
440
  } else {
699
- logger.warning("No vite.config found. Please create one with cloudflare and agentbuilder plugins.");
441
+ logger.warning("No vite.config found. Please create one with the agentbuilder plugin.");
700
442
  }
701
443
  updatePackageDependencies(cwd);
702
- createOrUpdateWranglerConfig(cwd, projectName, force);
703
- await createOrUpdateWorkerEntry(cwd, force);
704
- createDurableObjects(cwd);
705
444
  createDirectoriesAndDocs(cwd);
706
445
  updateTsConfig(cwd);
707
446
  if (force) {
@@ -712,18 +451,17 @@ async function scaffold(options = {}) {
712
451
  logger.log("");
713
452
  logger.log("Your project structure:");
714
453
  logger.log("");
715
- logger.log(" CLAUDE.md # Architecture documentation");
454
+ logger.log(" AGENTS.md # Architecture documentation");
455
+ logger.log(" CLAUDE.md -> AGENTS.md # Compatibility symlink");
456
+ logger.log(" vite.config.ts # Uses builder(); Cloudflare config is generated");
457
+ logger.log(" tsconfig.json # Includes agents and generated .agents types");
716
458
  logger.log(" agents/");
717
- logger.log(" \u251C\u2500\u2500 Thread.ts # Durable Object for threads");
718
- logger.log(" \u251C\u2500\u2500 AgentBuilder.ts # Durable Object for agent state");
719
459
  logger.log(" \u251C\u2500\u2500 agents/ # Agent definitions");
720
460
  logger.log(" \u251C\u2500\u2500 prompts/ # Prompt definitions");
721
461
  logger.log(" \u251C\u2500\u2500 models/ # Model configurations");
722
462
  logger.log(" \u251C\u2500\u2500 tools/ # Custom tools");
723
463
  logger.log(" \u251C\u2500\u2500 hooks/ # Lifecycle hooks");
724
464
  logger.log(" \u2514\u2500\u2500 api/ # Thread API endpoints");
725
- logger.log(" worker/");
726
- logger.log(" \u2514\u2500\u2500 index.ts # Cloudflare Worker entry point");
727
465
  logger.log("");
728
466
  }
729
467
  var STAGE_LABELS = {
@@ -1251,7 +989,6 @@ var GENERATED_STANDARD_AGENTS_PACKAGES = [
1251
989
  "@standardagents/spec",
1252
990
  ...FIRST_PARTY_PROVIDER_PACKAGES
1253
991
  ];
1254
- var PLATFORM_RUNTIME_PACKAGE = "@standardagents/platform-runtime";
1255
992
  var PACKAGE_MANAGERS = ["npm", "pnpm", "yarn", "bun"];
1256
993
  var MISSING_PLATFORM_PROJECT_NAME_MESSAGE = "The platform did not return a project name. Please run the init command again to start a new project setup.";
1257
994
  var LEGACY_BOOTSTRAP_RESPONSE_MESSAGE = "The platform returned an older onboarding response. Please run the init command again to start a new project setup.";
@@ -1458,20 +1195,33 @@ ${details}`));
1458
1195
  child.on("error", reject);
1459
1196
  });
1460
1197
  }
1461
- function runCommandQuiet(command, args, cwd) {
1462
- return new Promise((resolve, reject) => {
1463
- const child = spawn(command, args, {
1464
- cwd,
1465
- stdio: "ignore",
1466
- shell: false,
1467
- detached: true
1468
- });
1469
- child.on("error", reject);
1470
- child.on("spawn", () => {
1471
- child.unref();
1472
- resolve();
1473
- });
1198
+ var DEV_SERVER_LOG_FILE = ".agentbuilder-dev.log";
1199
+ function startDetachedDevServer(command, args, cwd) {
1200
+ const logPath = path7.join(cwd, DEV_SERVER_LOG_FILE);
1201
+ const logFd = fs3.openSync(logPath, "w");
1202
+ const child = spawn(command, args, {
1203
+ cwd,
1204
+ stdio: ["ignore", logFd, logFd],
1205
+ shell: false,
1206
+ detached: true
1474
1207
  });
1208
+ child.unref();
1209
+ fs3.closeSync(logFd);
1210
+ return { logPath };
1211
+ }
1212
+ function readLogTail(logPath, maxLines = 20) {
1213
+ try {
1214
+ const text = fs3.readFileSync(logPath, "utf-8").trimEnd();
1215
+ if (!text) return "";
1216
+ return text.split("\n").slice(-maxLines).join("\n");
1217
+ } catch {
1218
+ return "";
1219
+ }
1220
+ }
1221
+ function devCommandHint(packageManager) {
1222
+ if (packageManager === "npm") return "npm run dev";
1223
+ if (packageManager === "bun") return "bun run dev";
1224
+ return `${packageManager} dev`;
1475
1225
  }
1476
1226
  function canConnectToPort(port) {
1477
1227
  return new Promise((resolve) => {
@@ -1497,17 +1247,17 @@ function buildDevServerCommand(packageManager, port) {
1497
1247
  const viteArgs = ["--host", "127.0.0.1", "--port", String(port), "--strictPort"];
1498
1248
  return packageManager === "npm" ? ["run", "dev", "--", ...viteArgs] : ["dev", ...viteArgs];
1499
1249
  }
1500
- async function waitForLocalDevServer(url) {
1501
- const deadline = Date.now() + 3e4;
1250
+ async function waitForLocalDevServer(url, timeoutMs = 6e4) {
1251
+ const deadline = Date.now() + timeoutMs;
1502
1252
  while (Date.now() < deadline) {
1503
1253
  try {
1504
1254
  const response = await fetch(url, { cache: "no-store" });
1505
- if (response.ok) return;
1255
+ if (response.ok) return true;
1506
1256
  } catch {
1507
1257
  }
1508
1258
  await sleep(500);
1509
1259
  }
1510
- throw new Error(`Local dev server did not become ready at ${url}`);
1260
+ return false;
1511
1261
  }
1512
1262
  function sleep(ms) {
1513
1263
  return new Promise((resolve) => setTimeout(resolve, ms));
@@ -1540,7 +1290,8 @@ function isStandardAgentsProjectDir(targetPath) {
1540
1290
  if (!fs3.existsSync(agentsDir) || !fs3.statSync(agentsDir).isDirectory()) {
1541
1291
  return false;
1542
1292
  }
1543
- return hasBuilderDependency(targetPath);
1293
+ if (hasBuilderDependency(targetPath)) return true;
1294
+ return fs3.existsSync(path7.join(targetPath, "vite.config.ts")) && fs3.existsSync(path7.join(targetPath, "tsconfig.json"));
1544
1295
  }
1545
1296
  async function resolveProjectTarget(cwd, initialProjectName, options, promptProjectName = prompt) {
1546
1297
  if (!initialProjectName && isStandardAgentsProjectDir(cwd)) {
@@ -1785,7 +1536,7 @@ async function ensurePlatformAuth(options, quietLogs = false, context = {}) {
1785
1536
  return { connected: true, mode: "standardagents" };
1786
1537
  }
1787
1538
  function getCliVersion() {
1788
- return "0.15.3";
1539
+ return "0.16.1-next.1e58032";
1789
1540
  }
1790
1541
  function getSipVersion() {
1791
1542
  return "1.0.1";
@@ -1868,18 +1619,14 @@ function validateWorkspacePackageDir(packageName, packageDir) {
1868
1619
  );
1869
1620
  }
1870
1621
  }
1871
- function rewriteStandardAgentsDependenciesForWorkspace(projectPath, workspaceRoot, extraPackageDirs = {}) {
1622
+ function rewriteStandardAgentsDependenciesForWorkspace(projectPath, workspaceRoot) {
1872
1623
  const packageJsonPath = path7.join(projectPath, "package.json");
1873
1624
  const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
1874
1625
  const dependencies = packageJson.dependencies ?? {};
1875
1626
  const linkedPackages = [];
1876
- const packageNames = [
1877
- ...GENERATED_STANDARD_AGENTS_PACKAGES,
1878
- ...Object.keys(extraPackageDirs)
1879
- ];
1880
- for (const packageName of packageNames) {
1627
+ for (const packageName of GENERATED_STANDARD_AGENTS_PACKAGES) {
1881
1628
  if (!(packageName in dependencies)) continue;
1882
- const packageDir = extraPackageDirs[packageName] ?? workspacePackageDir(workspaceRoot, packageName);
1629
+ const packageDir = workspacePackageDir(workspaceRoot, packageName);
1883
1630
  validateWorkspacePackageDir(packageName, packageDir);
1884
1631
  dependencies[packageName] = `link:${packageDir}`;
1885
1632
  linkedPackages.push(packageName);
@@ -1891,40 +1638,6 @@ function rewriteStandardAgentsDependenciesForWorkspace(projectPath, workspaceRoo
1891
1638
  }
1892
1639
  return linkedPackages;
1893
1640
  }
1894
- function resolvePlatformRuntimePackageDir() {
1895
- const explicitRoot = process.env.STANDARDAGENTS_PLATFORM_RUNTIME_ROOT?.trim();
1896
- if (!explicitRoot) return null;
1897
- const packageDir = path7.resolve(explicitRoot);
1898
- validateWorkspacePackageDir(PLATFORM_RUNTIME_PACKAGE, packageDir);
1899
- return packageDir;
1900
- }
1901
- function addProjectDependency(projectPath, packageName, version) {
1902
- const packageJsonPath = path7.join(projectPath, "package.json");
1903
- const packageJson = JSON.parse(fs3.readFileSync(packageJsonPath, "utf-8"));
1904
- packageJson.dependencies = {
1905
- ...packageJson.dependencies ?? {},
1906
- [packageName]: packageJson.dependencies?.[packageName] ?? version
1907
- };
1908
- fs3.writeFileSync(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
1909
- `, "utf-8");
1910
- }
1911
- function ensurePlatformRuntimeRegistration(projectPath) {
1912
- const workerIndexPath = path7.join(projectPath, "worker", "index.ts");
1913
- if (!fs3.existsSync(workerIndexPath)) return false;
1914
- const source = fs3.readFileSync(workerIndexPath, "utf-8");
1915
- if (source.includes(`from "${PLATFORM_RUNTIME_PACKAGE}"`) || source.includes(`from '${PLATFORM_RUNTIME_PACKAGE}'`)) {
1916
- return false;
1917
- }
1918
- const registration = [
1919
- `import { ProviderRegistry } from "@standardagents/builder/runtime"`,
1920
- `import { createProviderFromEnv } from "${PLATFORM_RUNTIME_PACKAGE}"`,
1921
- "",
1922
- "ProviderRegistry.setProviderOverride(createProviderFromEnv)",
1923
- ""
1924
- ].join("\n");
1925
- fs3.writeFileSync(workerIndexPath, `${registration}${source}`, "utf-8");
1926
- return true;
1927
- }
1928
1641
  function preparePlatformProjectDependencies(projectPath, packageManager) {
1929
1642
  if (process.env.STANDARDAGENTS_WORKSPACE !== "1") {
1930
1643
  return [];
@@ -1936,14 +1649,7 @@ function preparePlatformProjectDependencies(projectPath, packageManager) {
1936
1649
  if (!workspaceRoot) {
1937
1650
  throw new Error("STANDARDAGENTS_WORKSPACE=1 was set, but no Standard Agents workspace root was found");
1938
1651
  }
1939
- const extraPackageDirs = {};
1940
- const platformRuntimePackageDir = resolvePlatformRuntimePackageDir();
1941
- if (platformRuntimePackageDir) {
1942
- addProjectDependency(projectPath, PLATFORM_RUNTIME_PACKAGE, "workspace:*");
1943
- ensurePlatformRuntimeRegistration(projectPath);
1944
- extraPackageDirs[PLATFORM_RUNTIME_PACKAGE] = platformRuntimePackageDir;
1945
- }
1946
- return rewriteStandardAgentsDependenciesForWorkspace(projectPath, workspaceRoot, extraPackageDirs);
1652
+ return rewriteStandardAgentsDependenciesForWorkspace(projectPath, workspaceRoot);
1947
1653
  }
1948
1654
  function shellQuote(value) {
1949
1655
  return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
@@ -2135,6 +1841,43 @@ function resolvePlatformProjectDirectoryName(project, requestedProjectName) {
2135
1841
  function resolvePlatformProjectPackageManager(projectPackageManager, requestedPackageManager) {
2136
1842
  return resolvePackageManager(projectPackageManager ?? void 0, requestedPackageManager);
2137
1843
  }
1844
+ function sanitizeGitRemoteUrl(remoteUrl) {
1845
+ try {
1846
+ const url = new URL(remoteUrl);
1847
+ url.username = "";
1848
+ url.password = "";
1849
+ return url.toString();
1850
+ } catch {
1851
+ return remoteUrl.replace(/\/\/[^/@\s]+@/, "//");
1852
+ }
1853
+ }
1854
+ function cloneDisplayUrl(project) {
1855
+ return project.repo_html_url || sanitizeGitRemoteUrl(project.repo_clone_url);
1856
+ }
1857
+ function gitCloneArgs(project, projectName) {
1858
+ const args = [];
1859
+ if (project.git_extra_header) {
1860
+ args.push("-c", `http.extraHeader=${project.git_extra_header}`);
1861
+ }
1862
+ args.push("clone", project.repo_clone_url, projectName);
1863
+ return args;
1864
+ }
1865
+ function platformGitCredentialHelperCommand(cliEntry = process.argv[1] ?? "") {
1866
+ if (process.env.STANDARDAGENTS_WORKSPACE === "1" && cliEntry && fs3.existsSync(cliEntry)) {
1867
+ return `!node ${shellQuote(path7.resolve(cliEntry))} git-credential`;
1868
+ }
1869
+ if (process.env.STANDARD_AGENTS_GIT_HELPER?.trim()) {
1870
+ return process.env.STANDARD_AGENTS_GIT_HELPER.trim();
1871
+ }
1872
+ const cliVersion = getCliVersion();
1873
+ {
1874
+ return `!npx -y @standardagents/cli@${cliVersion} git-credential`;
1875
+ }
1876
+ }
1877
+ async function configurePlatformGitCredentialHelper(projectPath) {
1878
+ await runCommand("git", ["config", "credential.helper", platformGitCredentialHelperCommand()], projectPath);
1879
+ await runCommand("git", ["config", "credential.useHttpPath", "true"], projectPath);
1880
+ }
2138
1881
  function isRetryablePlatformAuthStatus(status) {
2139
1882
  return status === 502 || status === 503 || status === 504;
2140
1883
  }
@@ -2230,6 +1973,71 @@ function upsertEnvLine(lines, key, value) {
2230
1973
  function hasEnvLine(lines, key) {
2231
1974
  return lines.some((line) => line.startsWith(`${key}=`));
2232
1975
  }
1976
+ function appendGitignoreEntries(projectPath, heading, entries) {
1977
+ const gitignorePath = path7.join(projectPath, ".gitignore");
1978
+ const gitignoreContent = fs3.existsSync(gitignorePath) ? fs3.readFileSync(gitignorePath, "utf-8") : "";
1979
+ const existingEntries = new Set(gitignoreContent.split(/\r?\n/));
1980
+ const missingEntries = entries.filter((entry) => !existingEntries.has(entry));
1981
+ if (missingEntries.length === 0) return;
1982
+ const prefix = gitignoreContent.length === 0 ? "" : gitignoreContent.endsWith("\n") ? "\n" : "\n\n";
1983
+ fs3.appendFileSync(gitignorePath, `${prefix}${heading}
1984
+ ${missingEntries.join("\n")}
1985
+ `);
1986
+ }
1987
+ function writeStandardAgentsSupportFiles(projectPath, params) {
1988
+ const written = [];
1989
+ for (const supportFile of renderAgentBuilderSupportFiles({
1990
+ projectName: params.projectName,
1991
+ packageManager: params.packageManager,
1992
+ versions: {
1993
+ standardAgents: getCliVersion(),
1994
+ sip: getSipVersion()
1995
+ }
1996
+ })) {
1997
+ const targetPath = path7.join(projectPath, supportFile.path);
1998
+ if (fs3.existsSync(targetPath)) continue;
1999
+ fs3.mkdirSync(path7.dirname(targetPath), { recursive: true });
2000
+ fs3.writeFileSync(targetPath, supportFile.content, "utf-8");
2001
+ written.push(supportFile.path);
2002
+ }
2003
+ if (written.includes("package.json")) {
2004
+ appendGitignoreEntries(projectPath, "# Standard Agents generated local support files", [
2005
+ "package.json",
2006
+ "package-lock.json",
2007
+ "pnpm-lock.yaml",
2008
+ "yarn.lock",
2009
+ "bun.lock",
2010
+ "bun.lockb",
2011
+ "node_modules"
2012
+ ]);
2013
+ }
2014
+ appendGitignoreEntries(projectPath, "# Standard Agents local dev state", [
2015
+ ".agents",
2016
+ ".wrangler",
2017
+ "dist"
2018
+ ]);
2019
+ return written;
2020
+ }
2021
+ function supportFiles(options = {}) {
2022
+ let packageManager;
2023
+ try {
2024
+ packageManager = resolvePackageManager(options.packageManager, detectPackageManager());
2025
+ } catch (error) {
2026
+ logger.error(error instanceof Error ? error.message : String(error));
2027
+ process.exit(1);
2028
+ }
2029
+ const cwd = process.cwd();
2030
+ const projectName = normalizeProjectName(options.projectName ?? path7.basename(cwd)) || "standard-agents";
2031
+ const written = writeStandardAgentsSupportFiles(cwd, {
2032
+ projectName,
2033
+ packageManager
2034
+ });
2035
+ if (written.length === 0) {
2036
+ logger.info("Standard Agents local support files already exist");
2037
+ return;
2038
+ }
2039
+ logger.success(`Wrote Standard Agents local support files: ${written.join(", ")}`);
2040
+ }
2233
2041
  function writeStandardAgentsEnv(projectPath, params) {
2234
2042
  const envPath = path7.join(projectPath, ".dev.vars");
2235
2043
  const existing = fs3.existsSync(envPath) ? fs3.readFileSync(envPath, "utf-8") : "";
@@ -2258,21 +2066,42 @@ function writeStandardAgentsEnv(projectPath, params) {
2258
2066
  lines = upsertEnvLine(lines, "PLATFORM_ENDPOINT", params.platformEndpoint);
2259
2067
  lines = upsertEnvLine(lines, "STANDARD_AGENTS_API_URL", params.platformEndpoint);
2260
2068
  fs3.writeFileSync(envPath, lines.join("\n").replace(/\n{3,}/g, "\n\n").trim() + "\n", "utf-8");
2261
- const gitignorePath = path7.join(projectPath, ".gitignore");
2262
- const gitignoreContent = fs3.existsSync(gitignorePath) ? fs3.readFileSync(gitignorePath, "utf-8") : "";
2263
- if (!gitignoreContent.split(/\r?\n/).includes(".dev.vars")) {
2264
- const prefix = gitignoreContent.length === 0 ? "" : gitignoreContent.endsWith("\n") ? "\n" : "\n\n";
2265
- fs3.appendFileSync(gitignorePath, `${prefix}# Standard Agents local platform token
2266
- .dev.vars
2267
- `);
2268
- }
2069
+ appendGitignoreEntries(projectPath, "# Standard Agents local platform token", [".dev.vars"]);
2269
2070
  return envPath;
2270
2071
  }
2072
+ async function resolveBootstrapProject(endpoint, code, fetchImpl = fetch) {
2073
+ const consumed = await exchangeBootstrapCode(endpoint, code, fetchImpl);
2074
+ const cookie = consumed.session_cookie;
2075
+ const listResponse = await fetchImpl(`${endpoint}/projects`, {
2076
+ headers: { Accept: "application/json", Cookie: cookie }
2077
+ });
2078
+ if (!listResponse.ok) {
2079
+ throw new Error(`Could not load your Standard Agents instance (${listResponse.status}).`);
2080
+ }
2081
+ const listBody = await listResponse.json().catch(() => ({}));
2082
+ const projectId = listBody.projects?.find(
2083
+ (entry) => typeof entry?.id === "string"
2084
+ )?.id;
2085
+ if (!projectId) {
2086
+ throw new Error("No Standard Agents instance found for this account. Create one in the dashboard first.");
2087
+ }
2088
+ const handoffResponse = await fetchImpl(`${endpoint}/projects/${projectId}/cli-handoff`, {
2089
+ method: "POST",
2090
+ headers: { Accept: "application/json", "Content-Type": "application/json", Cookie: cookie },
2091
+ body: "{}"
2092
+ });
2093
+ if (!handoffResponse.ok) {
2094
+ const text = await handoffResponse.text().catch(() => "");
2095
+ throw new Error(`Could not prepare your instance for local setup (${handoffResponse.status})${text ? `: ${text}` : ""}`);
2096
+ }
2097
+ const handoffBody = await handoffResponse.json().catch(() => ({}));
2098
+ if (!handoffBody.project?.repo_clone_url || !handoffBody.project.api_key) {
2099
+ throw new Error("Instance handoff response was missing clone details.");
2100
+ }
2101
+ return handoffBody.project;
2102
+ }
2271
2103
  async function runPlatformInit(projectNameArg, options) {
2272
2104
  const cwd = process.cwd();
2273
- if (options.bootstrap) {
2274
- logger.warning("Legacy bootstrap codes now continue through browser onboarding.");
2275
- }
2276
2105
  let pm;
2277
2106
  try {
2278
2107
  pm = resolvePackageManager(options.packageManager, detectPackageManager());
@@ -2286,23 +2115,34 @@ async function runPlatformInit(projectNameArg, options) {
2286
2115
  process.exit(1);
2287
2116
  }
2288
2117
  const endpoint = normalizeApiUrl(options.apiUrl || options.endpoint);
2289
- logger.info("Opening Standard Agents platform signup/login...");
2290
- let session;
2291
- try {
2292
- session = await startPlatformCliSession({
2293
- endpoint,
2294
- projectName: requestedProjectName,
2295
- packageManager: pm
2118
+ let project;
2119
+ if (options.bootstrap?.trim()) {
2120
+ logger.info("Connecting to your Standard Agents instance...");
2121
+ try {
2122
+ project = await resolveBootstrapProject(endpoint, options.bootstrap.trim());
2123
+ } catch (error) {
2124
+ logger.error(error instanceof Error ? error.message : String(error));
2125
+ process.exit(1);
2126
+ }
2127
+ } else {
2128
+ logger.info("Opening Standard Agents platform signup/login...");
2129
+ let session;
2130
+ try {
2131
+ session = await startPlatformCliSession({
2132
+ endpoint,
2133
+ projectName: requestedProjectName,
2134
+ packageManager: pm
2135
+ });
2136
+ } catch (error) {
2137
+ logger.error(error instanceof Error ? error.message : String(error));
2138
+ process.exit(1);
2139
+ }
2140
+ openUrl(session.auth_url);
2141
+ logger.info("Finish the browser steps. I will stay here and continue automatically.");
2142
+ project = await waitForPlatformProject(session, (progress) => {
2143
+ logger.info(progress.message);
2296
2144
  });
2297
- } catch (error) {
2298
- logger.error(error instanceof Error ? error.message : String(error));
2299
- process.exit(1);
2300
2145
  }
2301
- openUrl(session.auth_url);
2302
- logger.info("Finish the browser steps. I will stay here and continue automatically.");
2303
- const project = await waitForPlatformProject(session, (progress) => {
2304
- logger.info(progress.message);
2305
- });
2306
2146
  const projectName = resolvePlatformProjectDirectoryName(project, requestedProjectName);
2307
2147
  const projectPackageManager = resolvePlatformProjectPackageManager(project.package_manager, pm);
2308
2148
  const projectPath = path7.join(cwd, projectName);
@@ -2311,28 +2151,77 @@ async function runPlatformInit(projectNameArg, options) {
2311
2151
  process.exit(1);
2312
2152
  }
2313
2153
  logger.success("Browser setup complete.");
2314
- logger.info(`Cloning ${project.repo_clone_url}...`);
2315
- await runCommand("git", ["clone", project.repo_clone_url, projectName], cwd);
2154
+ logger.info(`Cloning ${cloneDisplayUrl(project)}...`);
2155
+ await runCommand("git", gitCloneArgs(project, projectName), cwd);
2156
+ if (project.git_extra_header && project.repo_html_url) {
2157
+ await runCommand("git", ["remote", "set-url", "origin", project.repo_html_url], projectPath);
2158
+ }
2159
+ const supportFiles2 = writeStandardAgentsSupportFiles(projectPath, {
2160
+ projectName: project.name || projectName,
2161
+ packageManager: projectPackageManager
2162
+ });
2163
+ if (supportFiles2.length > 0) {
2164
+ logger.success(`Wrote generated local support files: ${supportFiles2.join(", ")}.`);
2165
+ }
2316
2166
  const envPath = writeStandardAgentsEnv(projectPath, {
2317
2167
  apiKey: project.api_key,
2318
2168
  platformEndpoint: endpoint
2319
2169
  });
2320
2170
  logger.success(`Wrote Standard Agents credentials to ${path7.relative(cwd, envPath)}.`);
2171
+ if (project.git_extra_header) {
2172
+ await configurePlatformGitCredentialHelper(projectPath);
2173
+ logger.success("Configured git credentials for the platform repository.");
2174
+ }
2321
2175
  const linkedPackages = preparePlatformProjectDependencies(projectPath, projectPackageManager);
2322
2176
  if (linkedPackages.length > 0) {
2323
2177
  logger.info(`Workspace mode detected: linked ${linkedPackages.length} Standard Agents packages locally.`);
2324
2178
  }
2325
2179
  logger.info(`Installing dependencies with ${projectPackageManager}...`);
2326
2180
  await runCommand(projectPackageManager, ["install"], projectPath);
2181
+ const repoUrl = project.repo_html_url ?? project.repo_clone_url;
2182
+ const tokenLocation = path7.relative(cwd, envPath);
2183
+ if (options.dev === false) {
2184
+ logger.success("Your Standard Agents instance is ready.");
2185
+ logger.log(`Repository: ${repoUrl}`);
2186
+ logger.log(`Local token: ${tokenLocation}`);
2187
+ logger.log("");
2188
+ logger.log("Start it whenever you like:");
2189
+ logger.log(` cd ${projectName}`);
2190
+ logger.log(` ${devCommandHint(projectPackageManager)}`);
2191
+ return;
2192
+ }
2327
2193
  const devPort = await findAvailablePort(5173);
2328
2194
  const devUrl = `http://127.0.0.1:${devPort}`;
2329
2195
  logger.info(`Starting local dev server at ${devUrl}...`);
2330
- await runCommandQuiet(projectPackageManager, buildDevServerCommand(projectPackageManager, devPort), projectPath);
2331
- await waitForLocalDevServer(devUrl);
2332
- openUrl(devUrl);
2333
- logger.success("Project is connected to Standard Agents.");
2334
- logger.log(`Repository: ${project.repo_html_url ?? project.repo_clone_url}`);
2335
- logger.log(`Local token written to ${path7.relative(cwd, envPath)}`);
2196
+ const { logPath } = startDetachedDevServer(
2197
+ projectPackageManager,
2198
+ buildDevServerCommand(projectPackageManager, devPort),
2199
+ projectPath
2200
+ );
2201
+ const ready = await waitForLocalDevServer(devUrl);
2202
+ if (ready) {
2203
+ openUrl(devUrl);
2204
+ logger.success("Project is connected to Standard Agents.");
2205
+ logger.log(`Repository: ${repoUrl}`);
2206
+ logger.log(`Dev server: ${devUrl}`);
2207
+ logger.log(`Local token: ${tokenLocation}`);
2208
+ return;
2209
+ }
2210
+ logger.warning(`The dev server didn't respond at ${devUrl} within 60s.`);
2211
+ const tail = readLogTail(logPath);
2212
+ if (tail) {
2213
+ logger.log("");
2214
+ logger.log(`Last dev server output (full log: ${path7.relative(cwd, logPath)}):`);
2215
+ logger.log(tail);
2216
+ }
2217
+ logger.log("");
2218
+ logger.success("Your Standard Agents instance is cloned, configured, and ready.");
2219
+ logger.log(`Repository: ${repoUrl}`);
2220
+ logger.log(`Local token: ${tokenLocation}`);
2221
+ logger.log("");
2222
+ logger.log("Once any error above is resolved, start it with:");
2223
+ logger.log(` cd ${projectName}`);
2224
+ logger.log(` ${devCommandHint(projectPackageManager)}`);
2336
2225
  }
2337
2226
  async function init(projectNameArg, options = {}) {
2338
2227
  if (!options.local) {
@@ -2625,17 +2514,10 @@ export default defineConfig({
2625
2514
  }
2626
2515
  try {
2627
2516
  const installCmd = pm === "npm" ? "install" : "add";
2628
- const devFlag = pm === "npm" ? "--save-dev" : "-D";
2629
2517
  if (packageSpecifier === "workspace:*") {
2630
2518
  logInfo("Using local workspace @standardagents/* packages (workspace:*).");
2631
2519
  }
2632
2520
  await withTuiSpinner(initTuiMode, "Installing dependencies...", async () => {
2633
- await runCommand(pm, [
2634
- installCmd,
2635
- devFlag,
2636
- "@cloudflare/vite-plugin",
2637
- "wrangler"
2638
- ], projectPath, { quiet: initTuiMode });
2639
2521
  const standardAgentsPackage = (packageName) => `${packageName}@${resolveStandardAgentsPackageSpecifier(packageName, packageSpecifier)}`;
2640
2522
  const deps = [
2641
2523
  standardAgentsPackage("@standardagents/builder"),
@@ -2752,14 +2634,6 @@ export default defineConfig({
2752
2634
  logSuccess("Added .dev.vars to .gitignore");
2753
2635
  }
2754
2636
  }
2755
- logInfo("Refreshing wrangler type bindings...");
2756
- try {
2757
- await withTuiSpinner(initTuiMode, "Generating wrangler types...", async () => {
2758
- await runCommand("npx", ["wrangler", "types"], projectPath, { quiet: initTuiMode });
2759
- });
2760
- } catch (error) {
2761
- logWarning('Could not generate types automatically. Run "npx wrangler types" manually.');
2762
- }
2763
2637
  const nextRunCommand = resolvePostInitRunCommand(pm, projectPath, packageSpecifier === "workspace:*");
2764
2638
  if (initTuiMode) {
2765
2639
  clearTerminalScreen();
@@ -2856,8 +2730,19 @@ async function loginWithBootstrap(projectPath, options, fetchImpl = fetch) {
2856
2730
  }
2857
2731
  throw new Error("Bootstrap code required. Run: npx @standardagents/cli login --bootstrap <code>");
2858
2732
  }
2733
+ const state = await consumeBootstrapLogin({ ...options, endpoint, bootstrap: bootstrapCode }, fetchImpl);
2734
+ persistBootstrapState(projectPath, state);
2735
+ syncProjectAuthEnv(projectPath, endpoint, state);
2736
+ return { state, reused: false };
2737
+ }
2738
+ async function consumeBootstrapLogin(options, fetchImpl = fetch) {
2739
+ const endpoint = resolvePlatformEndpoint({ endpoint: options.endpoint });
2740
+ const bootstrapCode = options.bootstrap?.trim();
2741
+ if (!bootstrapCode) {
2742
+ throw new Error("Bootstrap code required. Run: npx @standardagents/cli login --bootstrap <code>");
2743
+ }
2859
2744
  const consumed = await exchangeBootstrapCode(endpoint, bootstrapCode, fetchImpl);
2860
- const state = {
2745
+ return {
2861
2746
  version: 1,
2862
2747
  endpoint,
2863
2748
  authenticated_at: Date.now(),
@@ -2865,9 +2750,6 @@ async function loginWithBootstrap(projectPath, options, fetchImpl = fetch) {
2865
2750
  user: consumed.user,
2866
2751
  account: consumed.account
2867
2752
  };
2868
- persistBootstrapState(projectPath, state);
2869
- syncProjectAuthEnv(projectPath, endpoint, state);
2870
- return { state, reused: false };
2871
2753
  }
2872
2754
  async function loginWithPlatform(options) {
2873
2755
  const endpoint = resolvePlatformEndpoint({ endpoint: options.endpoint });
@@ -3050,12 +2932,31 @@ function readCliAuthState() {
3050
2932
  const parsed = JSON.parse(fs3.readFileSync(file, "utf8"));
3051
2933
  return {
3052
2934
  active_org_id: parsed.active_org_id ?? null,
3053
- orgs: parsed.orgs ?? {}
2935
+ orgs: parsed.orgs ?? {},
2936
+ git_auth: parseCliGitAuthRecord(parsed.git_auth)
3054
2937
  };
3055
2938
  } catch {
3056
2939
  return { active_org_id: null, orgs: {} };
3057
2940
  }
3058
2941
  }
2942
+ function parseCliGitAuthRecord(value) {
2943
+ if (!value || typeof value !== "object") return null;
2944
+ const candidate = value;
2945
+ if (candidate.version !== 1) return null;
2946
+ if (typeof candidate.endpoint !== "string" || typeof candidate.session_cookie !== "string" || typeof candidate.account_id !== "string" || typeof candidate.user_id !== "string" || typeof candidate.user_email !== "string" || typeof candidate.updated_at !== "number") {
2947
+ return null;
2948
+ }
2949
+ return {
2950
+ version: 1,
2951
+ endpoint: candidate.endpoint,
2952
+ session_cookie: candidate.session_cookie,
2953
+ account_id: candidate.account_id,
2954
+ account_slug: typeof candidate.account_slug === "string" ? candidate.account_slug : void 0,
2955
+ user_id: candidate.user_id,
2956
+ user_email: candidate.user_email,
2957
+ updated_at: candidate.updated_at
2958
+ };
2959
+ }
3059
2960
  function writeCliAuthState(state) {
3060
2961
  ensureStateDir();
3061
2962
  fs3.writeFileSync(stateFilePath(), JSON.stringify(state, null, 2) + "\n", "utf8");
@@ -3064,6 +2965,25 @@ function hasStoredCliAuth() {
3064
2965
  const state = readCliAuthState();
3065
2966
  return Object.keys(state.orgs).length > 0;
3066
2967
  }
2968
+ function saveCliGitAuth(input) {
2969
+ const state = readCliAuthState();
2970
+ const record = {
2971
+ version: 1,
2972
+ endpoint: input.endpoint.replace(/\/+$/, ""),
2973
+ session_cookie: input.sessionCookie,
2974
+ account_id: input.account.id,
2975
+ account_slug: input.account.slug,
2976
+ user_id: input.user.id,
2977
+ user_email: input.user.email,
2978
+ updated_at: Date.now()
2979
+ };
2980
+ state.git_auth = record;
2981
+ writeCliAuthState(state);
2982
+ return record;
2983
+ }
2984
+ function resolveCliGitAuth() {
2985
+ return readCliAuthState().git_auth ?? null;
2986
+ }
3067
2987
  function resolveTargetOrgId(state, orgInput) {
3068
2988
  if (orgInput) {
3069
2989
  const trimmed = orgInput.trim();
@@ -3948,14 +3868,14 @@ async function pack(agentName, options) {
3948
3868
  sharedWith: agent.sharedWith
3949
3869
  });
3950
3870
  }
3951
- for (const prompt4 of analysis.constituents.prompts) {
3871
+ for (const prompt5 of analysis.constituents.prompts) {
3952
3872
  selectionItems.push({
3953
- name: prompt4.name,
3873
+ name: prompt5.name,
3954
3874
  type: "prompt",
3955
- filePath: prompt4.filePath,
3956
- mode: prompt4.sharedWith.length > 0 ? "copy" : "extract",
3957
- isShared: prompt4.sharedWith.length > 0,
3958
- sharedWith: prompt4.sharedWith
3875
+ filePath: prompt5.filePath,
3876
+ mode: prompt5.sharedWith.length > 0 ? "copy" : "extract",
3877
+ isShared: prompt5.sharedWith.length > 0,
3878
+ sharedWith: prompt5.sharedWith
3959
3879
  });
3960
3880
  }
3961
3881
  for (const tool of analysis.constituents.tools) {
@@ -4163,349 +4083,74 @@ async function listPacked() {
4163
4083
  console.log("");
4164
4084
  }
4165
4085
  }
4166
- var DEFAULT_ENDPOINT = "https://api.standardagents.ai";
4167
- var FREE_TIER_BUNDLE_LIMIT = 5 * 1024 * 1024;
4168
- function parseEnvFile(content) {
4169
- const result = {};
4170
- for (const line of content.split("\n")) {
4171
- const trimmed = line.trim();
4172
- if (!trimmed || trimmed.startsWith("#")) continue;
4173
- const eqIndex = trimmed.indexOf("=");
4174
- if (eqIndex === -1) continue;
4175
- const key = trimmed.slice(0, eqIndex).trim();
4176
- let value = trimmed.slice(eqIndex + 1).trim();
4177
- if (value.startsWith('"') && value.endsWith('"')) {
4178
- value = value.slice(1, -1).replace(/\\"/g, '"');
4179
- } else if (value.startsWith("'") && value.endsWith("'")) {
4180
- value = value.slice(1, -1);
4181
- }
4182
- result[key] = value;
4183
- }
4184
- return result;
4185
- }
4186
- function compareVersions(a, b) {
4187
- const [coreA, preA] = a.replace(/^v/, "").split("-", 2);
4188
- const [coreB, preB] = b.replace(/^v/, "").split("-", 2);
4189
- const partsA = coreA.split(".").map(Number);
4190
- const partsB = coreB.split(".").map(Number);
4191
- for (let i = 0; i < 3; i++) {
4192
- const va = partsA[i] ?? 0;
4193
- const vb = partsB[i] ?? 0;
4194
- if (va < vb) return -1;
4195
- if (va > vb) return 1;
4196
- }
4197
- if (preA && !preB) return -1;
4198
- if (!preA && preB) return 1;
4199
- return 0;
4200
- }
4201
- function validateBundleSize(sizeBytes) {
4202
- if (sizeBytes > FREE_TIER_BUNDLE_LIMIT) {
4203
- return `Bundle size (${formatBytes(sizeBytes)}) exceeds the free tier limit (${formatBytes(FREE_TIER_BUNDLE_LIMIT)}). A paid plan may be required.`;
4204
- }
4205
- return null;
4206
- }
4207
- function createManifest(agents, builderVersion) {
4208
- return {
4209
- agents,
4210
- builder_version: builderVersion
4211
- };
4212
- }
4213
- function formatBytes(bytes) {
4214
- if (bytes < 1024) return `${bytes} B`;
4215
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
4216
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
4217
- }
4218
- function formatDeployError(response) {
4219
- if (response.error) {
4220
- return `${response.error.code}: ${response.error.message}`;
4221
- }
4222
- if (response.errors && response.errors.length > 0) {
4223
- return response.errors.join("\n");
4086
+ var ARTIFACT_DEPLOY_REMOTE_NAME = "origin";
4087
+ function normalizeGitRemoteHost(remote) {
4088
+ try {
4089
+ return new URL(remote).hostname.toLowerCase();
4090
+ } catch {
4091
+ return null;
4224
4092
  }
4225
- return "Unknown error";
4226
- }
4227
- function detectProject() {
4228
- const hasWranglerJsonc = fs3.existsSync("wrangler.jsonc") || fs3.existsSync("wrangler.json");
4229
- const hasAgentsDir = fs3.existsSync("agents/agents");
4230
- return hasWranglerJsonc || hasAgentsDir;
4231
4093
  }
4232
- function loadEnvFileVars(projectPath) {
4233
- const envPath = path7.join(projectPath, ".env");
4234
- if (!fs3.existsSync(envPath)) return {};
4235
- return parseEnvFile(fs3.readFileSync(envPath, "utf-8"));
4094
+ function isStandardAgentsArtifactRemote(remote) {
4095
+ const host = normalizeGitRemoteHost(remote);
4096
+ if (!host) return false;
4097
+ return host === "standardagents.ai" || host.endsWith(".standardagents.ai") || host === "standardagentbuilder.com" || host.endsWith(".standardagentbuilder.com") || host === "artifacts.cloudflare.net" || host.endsWith(".artifacts.cloudflare.net") || host === "artifacts.cloudflare.com" || host.endsWith(".artifacts.cloudflare.com") || host === "git.cloudflare.com";
4236
4098
  }
4237
- function resolveEndpoint(options, envFileVars) {
4238
- return options.endpoint || process.env.PLATFORM_ENDPOINT || envFileVars.PLATFORM_ENDPOINT || DEFAULT_ENDPOINT;
4099
+ function gitOutput(args) {
4100
+ return execFileSync("git", args, {
4101
+ encoding: "utf-8",
4102
+ stdio: ["ignore", "pipe", "pipe"]
4103
+ }).trim();
4239
4104
  }
4240
- function authHeadersForDeploy(auth) {
4241
- if (auth.kind === "session-cookie") {
4242
- return { Cookie: auth.cookie };
4243
- }
4244
- return { Authorization: `Bearer ${auth.apiKey}` };
4245
- }
4246
- function resolveDeployAuth(options, projectPath = process.cwd()) {
4247
- const envFileVars = loadEnvFileVars(projectPath);
4248
- const endpoint = resolveEndpoint(options, envFileVars);
4249
- if (options.apiKey?.trim()) {
4250
- return { endpoint, auth: { kind: "api-key", apiKey: options.apiKey.trim() } };
4251
- }
4252
- const bootstrap = loadBootstrapState(projectPath);
4253
- if (bootstrap?.endpoint === endpoint && bootstrap.session_cookie) {
4254
- return {
4255
- endpoint,
4256
- auth: {
4257
- kind: "session-cookie",
4258
- cookie: bootstrap.session_cookie
4259
- }
4260
- };
4261
- }
4262
- const apiKey = process.env.PLATFORM_API_KEY || envFileVars.PLATFORM_API_KEY;
4263
- if (apiKey) {
4264
- return { endpoint, auth: { kind: "api-key", apiKey } };
4265
- }
4266
- if (bootstrap?.endpoint === endpoint && !bootstrap.session_cookie) {
4105
+ function resolveArtifactGitDeployTarget(runner = gitOutput, remoteName = ARTIFACT_DEPLOY_REMOTE_NAME) {
4106
+ const remoteUrl = runner(["remote", "get-url", remoteName]).trim();
4107
+ if (!isStandardAgentsArtifactRemote(remoteUrl)) {
4267
4108
  throw new Error(
4268
- "Stored org session is from an older CLI version and cannot deploy. Run `agents logout` then `agents login --bootstrap <code>`."
4109
+ `Remote "${remoteName}" is not a Standard Agents Artifacts remote. Deployments now run from pushes to platform-owned repositories.`
4269
4110
  );
4270
4111
  }
4271
- throw new Error(
4272
- "No local deploy auth found. Run `agents login --bootstrap <code>` (interactive) or pass --api-key (automation)."
4273
- );
4274
- }
4275
- function discoverAgents() {
4276
- const agentsDir = "agents/agents";
4277
- if (!fs3.existsSync(agentsDir)) return [];
4278
- const scriptExtensions = /* @__PURE__ */ new Set([".ts", ".tsx", ".js", ".jsx", ".mts", ".mjs"]);
4279
- const files = fs3.readdirSync(agentsDir).filter((f) => scriptExtensions.has(path7.extname(f)));
4280
- return files.map((file) => {
4281
- const filePath = path7.join(agentsDir, file);
4282
- const realPath = fs3.realpathSync(filePath);
4283
- if (!realPath.startsWith(fs3.realpathSync("."))) {
4284
- return path7.basename(file, path7.extname(file));
4285
- }
4286
- const content = fs3.readFileSync(filePath, "utf-8");
4287
- const nameMatch = content.match(/defineAgent\s*\(\s*\{[\s\S]*?\bname\s*:\s*['"]([^'"]+)['"]/);
4288
- return nameMatch ? nameMatch[1] : path7.basename(file, path7.extname(file));
4289
- });
4290
- }
4291
- function getBuilderVersion() {
4292
- const searchPaths = [
4293
- "node_modules/@standardagents/builder/package.json",
4294
- "../node_modules/@standardagents/builder/package.json"
4295
- ];
4296
- for (const p of searchPaths) {
4297
- if (fs3.existsSync(p)) {
4298
- const pkg = JSON.parse(fs3.readFileSync(p, "utf-8"));
4299
- return pkg.version;
4300
- }
4301
- }
4302
- throw new Error("Could not find @standardagents/builder. Is it installed?");
4303
- }
4304
- function detectPackageManager3() {
4305
- const userAgent = process.env.npm_config_user_agent;
4306
- if (userAgent) {
4307
- if (userAgent.includes("pnpm")) return "pnpm";
4308
- if (userAgent.includes("yarn")) return "yarn";
4309
- if (userAgent.includes("bun")) return "bun";
4310
- }
4311
- if (fs3.existsSync("pnpm-lock.yaml")) return "pnpm";
4312
- if (fs3.existsSync("yarn.lock")) return "yarn";
4313
- if (fs3.existsSync("bun.lockb") || fs3.existsSync("bun.lock")) return "bun";
4314
- return "npm";
4315
- }
4316
- function buildProject(endpoint) {
4317
- const pm = detectPackageManager3();
4318
- const buildCmd = pm === "npm" ? "npx vite build" : `${pm} exec vite build`;
4319
- execSync(buildCmd, {
4320
- stdio: "inherit",
4321
- env: {
4322
- ...process.env,
4323
- STANDARD_AGENTS_API_URL: endpoint,
4324
- PLATFORM_ENDPOINT: endpoint
4325
- }
4326
- });
4327
- }
4328
- function findWorkerBundle() {
4329
- const searchDirs = [".wrangler/tmp", "dist"];
4330
- for (const dir of searchDirs) {
4331
- if (!fs3.existsSync(dir)) continue;
4332
- const bundle = findBundleInDir(dir);
4333
- if (bundle) return bundle;
4112
+ const branch = runner(["rev-parse", "--abbrev-ref", "HEAD"]).trim();
4113
+ if (!branch || branch === "HEAD") {
4114
+ throw new Error("Cannot deploy from a detached HEAD. Check out a branch before pushing.");
4334
4115
  }
4335
- throw new Error(
4336
- "Could not find Worker bundle in build output.\nExpected build output in .wrangler/tmp/ or dist/.\nMake sure `vite build` completed successfully."
4337
- );
4338
- }
4339
- function findBundleInDir(dir) {
4340
- const entries = fs3.readdirSync(dir, { withFileTypes: true });
4341
- const jsFiles = entries.filter((e) => e.isFile() && (e.name.endsWith(".js") || e.name.endsWith(".mjs")));
4342
- jsFiles.sort((a, b) => {
4343
- const aIsIndex = a.name === "index.js" || a.name === "index.mjs" ? 0 : 1;
4344
- const bIsIndex = b.name === "index.js" || b.name === "index.mjs" ? 0 : 1;
4345
- if (aIsIndex !== bIsIndex) return aIsIndex - bIsIndex;
4346
- const aSize = fs3.statSync(path7.join(dir, a.name)).size;
4347
- const bSize = fs3.statSync(path7.join(dir, b.name)).size;
4348
- return bSize - aSize;
4349
- });
4350
- for (const entry of jsFiles) {
4351
- const fullPath = path7.join(dir, entry.name);
4352
- const content = fs3.readFileSync(fullPath);
4353
- if (content.length > 0 && content.toString("utf-8", 0, 1e4).includes("export")) {
4354
- return { bundlePath: fullPath, bundleContent: content };
4355
- }
4356
- }
4357
- for (const entry of entries) {
4358
- if (entry.isDirectory() && entry.name !== "client" && entry.name !== "node_modules") {
4359
- const result = findBundleInDir(path7.join(dir, entry.name));
4360
- if (result) return result;
4361
- }
4362
- }
4363
- return null;
4364
- }
4365
- async function checkPlatformVersion(endpoint, builderVersion, authHeaders = {}) {
4366
- const res = await fetch(`${endpoint}/manifest`, { headers: authHeaders });
4367
- if (!res.ok) {
4368
- throw new Error(`Failed to check platform version: ${res.status} ${res.statusText}`);
4369
- }
4370
- const manifest = await res.json();
4371
- if (compareVersions(builderVersion, manifest.minimum_builder_version) < 0) {
4372
- throw new Error(
4373
- `Builder version ${builderVersion} is below the platform minimum (${manifest.minimum_builder_version}).
4374
- Please upgrade @standardagents/builder:
4375
- npm install @standardagents/builder@latest`
4376
- );
4377
- }
4378
- return manifest;
4116
+ return {
4117
+ remoteName,
4118
+ remoteUrl,
4119
+ branch,
4120
+ refspec: `HEAD:${branch}`
4121
+ };
4379
4122
  }
4380
- async function uploadDeploy(endpoint, auth, bundleContent, manifest, builderVersion) {
4381
- const formData = new FormData();
4382
- formData.append("bundle", new Blob([new Uint8Array(bundleContent)], { type: "application/javascript" }), "index.js");
4383
- formData.append("manifest", new Blob([JSON.stringify(manifest)], { type: "application/json" }), "manifest.json");
4384
- formData.append("builder_version", builderVersion);
4385
- formData.append("agent_count", String(manifest.agents.length));
4386
- const res = await fetch(`${endpoint}/deploys`, {
4387
- method: "POST",
4388
- headers: typeof auth === "string" ? authHeadersForDeploy({ kind: "api-key", apiKey: auth }) : authHeadersForDeploy(auth),
4389
- body: formData
4123
+ function pushArtifactRemote(target) {
4124
+ execFileSync("git", ["push", target.remoteName, target.refspec], {
4125
+ stdio: "inherit"
4390
4126
  });
4391
- let body;
4392
- try {
4393
- body = await res.json();
4394
- } catch {
4395
- throw new Error(`Deploy failed (${res.status}): Invalid response from server`);
4396
- }
4397
- if (!res.ok) {
4398
- const errorMsg = formatDeployError(body);
4399
- throw new Error(`Deploy failed (${res.status}): ${errorMsg}`);
4400
- }
4401
- return body;
4402
4127
  }
4403
- async function deploy(options) {
4128
+ async function deploy() {
4404
4129
  console.log("");
4405
4130
  logger.info(`${chalk.bold("Standard Agents Deploy")}
4406
4131
  `);
4407
- if (!detectProject()) {
4408
- logger.error("This does not appear to be a Standard Agents project.");
4409
- logger.info("Run this command from a directory with wrangler.jsonc and agents/agents/.");
4410
- process.exit(1);
4411
- }
4412
- let endpoint;
4413
- let auth;
4414
- try {
4415
- ({ endpoint, auth } = resolveDeployAuth(options));
4416
- } catch (err) {
4417
- logger.error(err.message);
4418
- process.exit(1);
4419
- }
4420
- logger.success(
4421
- auth.kind === "session-cookie" ? "Configuration loaded (org-scoped session auth)" : "Configuration loaded (API key auth)"
4422
- );
4423
- const agents = discoverAgents();
4424
- if (agents.length === 0) {
4425
- const agentsDir = path7.resolve("agents/agents");
4426
- logger.error(`No deployable agents found in ${agentsDir}.`);
4427
- if (!fs3.existsSync(agentsDir)) {
4428
- logger.info("Create agents/agents/ and add at least one file exporting defineAgent(...).");
4429
- } else {
4430
- const visibleEntries = fs3.readdirSync(agentsDir).filter((entry) => !entry.startsWith("."));
4431
- if (visibleEntries.length === 0) {
4432
- logger.info("agents/agents/ exists but is empty. Add at least one agent file.");
4433
- } else {
4434
- const preview = visibleEntries.slice(0, 5).join(", ");
4435
- const suffix = visibleEntries.length > 5 ? ", ..." : "";
4436
- logger.info(`Found non-hidden entries in agents/agents/: ${preview}${suffix}`);
4437
- }
4438
- }
4439
- logger.info(`Current working directory: ${process.cwd()}`);
4440
- logger.info("Run deploy from your project root where agents/agents/ lives.");
4441
- process.exit(1);
4442
- }
4443
- logger.success(`Found ${agents.length} agent${agents.length === 1 ? "" : "s"}: ${agents.join(", ")}`);
4444
- let builderVersion;
4445
- try {
4446
- builderVersion = getBuilderVersion();
4447
- } catch (err) {
4448
- logger.error(err.message);
4449
- process.exit(1);
4450
- }
4451
- logger.info(`Builder version: ${builderVersion}`);
4452
- try {
4453
- const platformManifest = await checkPlatformVersion(endpoint, builderVersion, authHeadersForDeploy(auth));
4454
- if (compareVersions(builderVersion, platformManifest.latest_builder_version) < 0) {
4455
- logger.warning(
4456
- `A newer builder version is available (${platformManifest.latest_builder_version}). Consider upgrading.`
4457
- );
4458
- }
4459
- } catch (err) {
4460
- logger.error(err.message);
4461
- process.exit(1);
4462
- }
4463
- logger.info("Building project...\n");
4464
- try {
4465
- buildProject(endpoint);
4466
- } catch {
4467
- console.log("");
4468
- logger.error("Build failed. See output above for details.");
4469
- process.exit(1);
4470
- }
4471
- console.log("");
4472
- logger.success("Build complete");
4473
- let bundlePath;
4474
- let bundleContent;
4475
- try {
4476
- ({ bundlePath, bundleContent } = findWorkerBundle());
4477
- } catch (err) {
4478
- logger.error(err.message);
4479
- process.exit(1);
4480
- }
4481
- const manifest = createManifest(agents, builderVersion);
4482
- logger.success(`Bundle: ${bundlePath} (${formatBytes(bundleContent.length)})`);
4483
- const sizeWarning = validateBundleSize(bundleContent.length);
4484
- if (sizeWarning) {
4485
- logger.warning(sizeWarning);
4486
- }
4487
- logger.info("Uploading...");
4132
+ let target;
4488
4133
  try {
4489
- const result = await uploadDeploy(endpoint, auth, bundleContent, manifest, builderVersion);
4490
- console.log("");
4491
- logger.success(chalk.bold("Deploy successful!"));
4492
- console.log(` Deploy ID: ${result.deploy.id}`);
4493
- console.log(` Status: ${result.deploy.status}`);
4494
- const organizationSlug = result.deploy.organization?.slug ?? result.deploy.org_slug;
4495
- if (organizationSlug) {
4496
- console.log(` URL: https://${organizationSlug}.standardagents.ai`);
4497
- }
4498
- console.log("");
4134
+ target = resolveArtifactGitDeployTarget();
4499
4135
  } catch (err) {
4500
4136
  logger.error(err.message);
4137
+ logger.info("Run this command from a clone created by Standard Agents, or push to the platform git remote manually.");
4501
4138
  process.exit(1);
4502
4139
  }
4140
+ logger.info("Deployments build on the Standard Agents platform from Artifacts git pushes.");
4141
+ logger.log(`Remote: ${target.remoteUrl}`);
4142
+ logger.log(`Branch: ${target.branch}`);
4143
+ logger.log("");
4144
+ pushArtifactRemote(target);
4145
+ logger.success("Push complete. The platform build runner will deploy this commit from the Artifacts push event.");
4503
4146
  }
4504
4147
  var PROJECT_SIGNAL_PATHS = [
4505
4148
  ".agents",
4506
- "wrangler.jsonc",
4507
- "worker",
4508
- "agents"
4149
+ "agents",
4150
+ "vite.config.ts",
4151
+ "vite.config.js",
4152
+ "vite.config.mts",
4153
+ "vite.config.mjs"
4509
4154
  ];
4510
4155
  function hasProjectSignals(cwd) {
4511
4156
  const hits = PROJECT_SIGNAL_PATHS.filter((signal) => fs3.existsSync(path7.join(cwd, signal))).length;
@@ -4568,7 +4213,7 @@ function getHomeActions(context) {
4568
4213
  {
4569
4214
  id: "deploy",
4570
4215
  label: "Deploy",
4571
- description: "Build and deploy this linked project to StandardAgents.",
4216
+ description: "Push this linked project to StandardAgents for a platform build.",
4572
4217
  argv: ["deploy"]
4573
4218
  },
4574
4219
  {
@@ -4924,7 +4569,7 @@ function isOpaqueModelId(modelId) {
4924
4569
  function getProviderDefinition(name) {
4925
4570
  return PROVIDER_DEFINITIONS.find((provider) => provider.name === name);
4926
4571
  }
4927
- function parseEnvFile2(content) {
4572
+ function parseEnvFile(content) {
4928
4573
  const result = {};
4929
4574
  for (const line of content.split("\n")) {
4930
4575
  const trimmed = line.trim();
@@ -5028,7 +4673,7 @@ function loadProjectEnv(projectRoot, processEnv = process.env) {
5028
4673
  for (const fileName of envFiles) {
5029
4674
  const filePath = path7.join(projectRoot, fileName);
5030
4675
  if (!fs3.existsSync(filePath)) continue;
5031
- Object.assign(result, parseEnvFile2(fs3.readFileSync(filePath, "utf8")));
4676
+ Object.assign(result, parseEnvFile(fs3.readFileSync(filePath, "utf8")));
5032
4677
  }
5033
4678
  for (const [key, value] of Object.entries(processEnv)) {
5034
4679
  if (typeof value === "string") {
@@ -5279,6 +4924,224 @@ async function availableModels(options = {}) {
5279
4924
  writeError(message);
5280
4925
  }
5281
4926
  }
4927
+ function parseKeyValueLines(input) {
4928
+ const result = {};
4929
+ for (const line of input.split(/\r?\n/)) {
4930
+ if (!line.trim()) continue;
4931
+ const index = line.indexOf("=");
4932
+ if (index <= 0) continue;
4933
+ result[line.slice(0, index)] = line.slice(index + 1);
4934
+ }
4935
+ return result;
4936
+ }
4937
+ function findDotDevVars(startDir = process.cwd()) {
4938
+ let current = path7.resolve(startDir);
4939
+ while (true) {
4940
+ const candidate = path7.join(current, ".dev.vars");
4941
+ if (fs3.existsSync(candidate)) return candidate;
4942
+ const parent = path7.dirname(current);
4943
+ if (parent === current) return null;
4944
+ current = parent;
4945
+ }
4946
+ }
4947
+ function normalizeEndpoint(value) {
4948
+ return value.replace(/\/+$/, "");
4949
+ }
4950
+ function normalizeGitHost(host) {
4951
+ return host.trim().toLowerCase().replace(/:\d+$/, "");
4952
+ }
4953
+ function isStandardAgentsGitHost(host) {
4954
+ const normalized = normalizeGitHost(host);
4955
+ return normalized === "standardagents.ai" || normalized.endsWith(".standardagents.ai") || normalized === "standardagentbuilder.com" || normalized.endsWith(".standardagentbuilder.com") || normalized === "artifacts.cloudflare.net" || normalized.endsWith(".artifacts.cloudflare.net") || normalized === "artifacts.cloudflare.com" || normalized.endsWith(".artifacts.cloudflare.com") || normalized === "git.cloudflare.com";
4956
+ }
4957
+ function loadLocalConfig(options) {
4958
+ const envPath = findDotDevVars(options.startDir);
4959
+ const fileVars = envPath ? parseKeyValueLines(fs3.readFileSync(envPath, "utf-8")) : {};
4960
+ const endpoint = normalizeEndpoint(
4961
+ options.endpoint || process.env.STANDARD_AGENTS_API_URL || process.env.PLATFORM_ENDPOINT || fileVars.STANDARD_AGENTS_API_URL || fileVars.PLATFORM_ENDPOINT || ""
4962
+ );
4963
+ const apiKey = process.env.STANDARD_AGENTS_API_KEY || fileVars.STANDARD_AGENTS_API_KEY || "";
4964
+ if (endpoint && apiKey) {
4965
+ return { endpoint, auth: { kind: "api-key", apiKey } };
4966
+ }
4967
+ const cookie = process.env.STANDARD_AGENTS_SESSION_COOKIE || process.env.STANDARDAGENTS_BOOTSTRAP_SESSION_COOKIE || fileVars.STANDARDAGENTS_BOOTSTRAP_SESSION_COOKIE || "";
4968
+ if (endpoint && cookie) {
4969
+ return { endpoint, auth: { kind: "session-cookie", cookie } };
4970
+ }
4971
+ const globalAuth = resolveCliGitAuth();
4972
+ if (!globalAuth) return null;
4973
+ const requestedEndpoint = endpoint || normalizeEndpoint(options.endpoint || "");
4974
+ if (requestedEndpoint && requestedEndpoint !== globalAuth.endpoint) {
4975
+ return null;
4976
+ }
4977
+ return {
4978
+ endpoint: globalAuth.endpoint,
4979
+ auth: { kind: "session-cookie", cookie: globalAuth.session_cookie }
4980
+ };
4981
+ }
4982
+ function remoteFromCredentialRequest(request) {
4983
+ if (!request.protocol || !request.host) return null;
4984
+ if (!isStandardAgentsGitHost(request.host)) return null;
4985
+ const repoPath = request.path ? `/${request.path.replace(/^\/+/, "")}` : "";
4986
+ return `${request.protocol}://${normalizeGitHost(request.host)}${repoPath}`;
4987
+ }
4988
+ async function readStdin() {
4989
+ const chunks = [];
4990
+ for await (const chunk of process.stdin) {
4991
+ chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
4992
+ }
4993
+ return Buffer.concat(chunks).toString("utf-8");
4994
+ }
4995
+ async function gitCredential(operation, options = {}) {
4996
+ if (operation !== "get") return;
4997
+ const config = loadLocalConfig(options);
4998
+ if (!config) return;
4999
+ const input = options.input ?? await readStdin();
5000
+ const remote = remoteFromCredentialRequest(parseKeyValueLines(input));
5001
+ if (!remote) return;
5002
+ const fetchImpl = options.fetchImpl ?? fetch;
5003
+ const headers = {
5004
+ "Content-Type": "application/json"
5005
+ };
5006
+ if (config.auth.kind === "api-key") {
5007
+ headers.Authorization = `Bearer ${config.auth.apiKey}`;
5008
+ } else {
5009
+ headers.Cookie = config.auth.cookie;
5010
+ }
5011
+ const response = await fetchImpl(`${config.endpoint}/projects/git-token`, {
5012
+ method: "POST",
5013
+ headers,
5014
+ body: JSON.stringify({ remote, scope: "write" })
5015
+ }).catch(() => null);
5016
+ if (!response?.ok) return;
5017
+ const body = await response.json().catch(() => null);
5018
+ const tokenSecret = body?.artifact_git?.token_secret;
5019
+ if (!tokenSecret) return;
5020
+ const write = options.write ?? ((text) => {
5021
+ process.stdout.write(text);
5022
+ });
5023
+ write(`username=x
5024
+ password=${tokenSecret}
5025
+
5026
+ `);
5027
+ }
5028
+ var DEFAULT_GIT_HELPER_COMMAND = "!npx -y @standardagents/cli@latest git-credential";
5029
+ function prompt4(question) {
5030
+ const rl = readline.createInterface({
5031
+ input: process.stdin,
5032
+ output: process.stdout
5033
+ });
5034
+ return new Promise((resolve) => {
5035
+ rl.question(question, (answer) => {
5036
+ rl.close();
5037
+ resolve(answer.trim());
5038
+ });
5039
+ });
5040
+ }
5041
+ function defaultGitRunner(args) {
5042
+ const result = spawnSync("git", args, { encoding: "utf8" });
5043
+ return {
5044
+ status: result.status,
5045
+ stdout: result.stdout || "",
5046
+ stderr: result.stderr || ""
5047
+ };
5048
+ }
5049
+ function runGit(args, runner) {
5050
+ const result = runner(args);
5051
+ if (result.status !== 0) {
5052
+ throw new Error(result.stderr.trim() || `git ${args.join(" ")} failed`);
5053
+ }
5054
+ return result;
5055
+ }
5056
+ function configureStandardAgentsGitCredentials(options = {}) {
5057
+ const runner = options.gitRunner ?? defaultGitRunner;
5058
+ const helperCommand = options.helperCommand?.trim() || process.env.STANDARD_AGENTS_GIT_HELPER || DEFAULT_GIT_HELPER_COMMAND;
5059
+ const existing = runGit(["config", "--global", "--get-all", "credential.helper"], runner).stdout.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
5060
+ let helperAdded = false;
5061
+ if (!existing.includes(helperCommand)) {
5062
+ runGit(["config", "--global", "--add", "credential.helper", helperCommand], runner);
5063
+ helperAdded = true;
5064
+ }
5065
+ runGit(["config", "--global", "credential.useHttpPath", "true"], runner);
5066
+ return { helperCommand, helperAdded };
5067
+ }
5068
+ async function completeBrowserGitLogin(options, endpoint) {
5069
+ let authAppUrl = resolvePlatformAuthBrowserUrl(endpoint);
5070
+ let sessionId = null;
5071
+ let wsUrl = null;
5072
+ let wsExpiresAt = 0;
5073
+ try {
5074
+ const started = await startCliAuthSession(endpoint);
5075
+ sessionId = started.session_id;
5076
+ authAppUrl = started.auth_url;
5077
+ wsUrl = started.ws_url;
5078
+ wsExpiresAt = started.expires_at;
5079
+ } catch (error) {
5080
+ const message = error instanceof Error ? error.message : "Failed to start realtime auth session";
5081
+ logger.warning(`${message} Switching to manual bootstrap command entry.`);
5082
+ }
5083
+ logger.log(`Auth app: ${authAppUrl}`);
5084
+ if (options.open !== false) {
5085
+ const opened = openBrowser(authAppUrl);
5086
+ if (opened) {
5087
+ logger.info("Opened browser for authentication.");
5088
+ } else {
5089
+ logger.warning("Could not automatically open browser. Open the URL above manually.");
5090
+ }
5091
+ }
5092
+ if (wsUrl && wsExpiresAt > 0) {
5093
+ try {
5094
+ const completion = await waitForCliAuthCompletion(wsUrl, wsExpiresAt);
5095
+ return consumeBootstrapLogin({ ...options, endpoint, bootstrap: completion.bootstrapCode });
5096
+ } catch (error) {
5097
+ const message = error instanceof Error ? error.message : "Realtime auth handoff failed";
5098
+ logger.warning(`${message} Enter bootstrap code manually to continue.`);
5099
+ }
5100
+ }
5101
+ if (!process.stdin.isTTY) {
5102
+ throw new Error("Non-interactive shell detected. Run: npx @standardagents/cli git-login --bootstrap <code>");
5103
+ }
5104
+ const input = await prompt4("Bootstrap code or command: ");
5105
+ const bootstrapCode = parseBootstrapCodeInput(input);
5106
+ if (!bootstrapCode) {
5107
+ if (sessionId) {
5108
+ await cancelCliAuthSession(endpoint, sessionId);
5109
+ }
5110
+ throw new Error("No bootstrap code provided. Run: npx @standardagents/cli git-login --bootstrap <code>");
5111
+ }
5112
+ if (sessionId) {
5113
+ await cancelCliAuthSession(endpoint, sessionId);
5114
+ }
5115
+ return consumeBootstrapLogin({ ...options, endpoint, bootstrap: bootstrapCode });
5116
+ }
5117
+ async function gitLogin(options = {}) {
5118
+ const endpoint = resolvePlatformEndpoint({ endpoint: options.endpoint });
5119
+ logger.log("");
5120
+ logger.info("Starting Standard Agents Git authentication...");
5121
+ logger.log(`Platform API: ${endpoint}`);
5122
+ const state = options.bootstrap?.trim() ? await consumeBootstrapLogin({ ...options, endpoint, bootstrap: options.bootstrap.trim() }) : await completeBrowserGitLogin(options, endpoint);
5123
+ if (!state.session_cookie) {
5124
+ throw new Error("Platform login did not return a session cookie for Git authentication.");
5125
+ }
5126
+ const record = saveCliGitAuth({
5127
+ endpoint,
5128
+ sessionCookie: state.session_cookie,
5129
+ account: state.account,
5130
+ user: state.user
5131
+ });
5132
+ let configured = null;
5133
+ if (options.config !== false) {
5134
+ configured = configureStandardAgentsGitCredentials(options);
5135
+ }
5136
+ logger.log("");
5137
+ logger.success("Git authentication configured.");
5138
+ logger.log(`Account: ${record.account_id}${record.account_slug ? ` (${record.account_slug})` : ""}`);
5139
+ logger.log(`User: ${record.user_email}`);
5140
+ if (configured) {
5141
+ logger.log(`Credential helper: ${configured.helperCommand}${configured.helperAdded ? "" : " (already installed)"}`);
5142
+ }
5143
+ logger.log("");
5144
+ }
5282
5145
 
5283
5146
  // src/index.ts
5284
5147
  async function settleStdinForInitHandoff(stdin = process.stdin) {
@@ -5299,8 +5162,8 @@ async function settleStdinForInitHandoff(stdin = process.stdin) {
5299
5162
  }
5300
5163
  }
5301
5164
  var program = new Command();
5302
- program.name("agents").description("CLI tool for Standard Agents / AgentBuilder").version("0.15.3");
5303
- program.command("init [project-name]").description("Create a new Standard Agents project").option("-y, --yes", "Skip prompts and use defaults").option("--local", "Use local project scaffolding instead of browser platform onboarding").option("--cli", "Use classic line-by-line CLI prompts instead of the TUI wizard").option("--api-url <url>", "Standard Agents platform API URL").option("--endpoint <url>", "Platform API endpoint for auth/bootstrap exchange").option("--package-manager <manager>", "Package manager for generated project: npm, pnpm, yarn, or bun").option("--template <template>", "Vite template to use", "vanilla-ts").option("--workspace", "Install @standardagents packages as workspace:* (local pnpm workspace development)").addOption(new Option("--bootstrap <code>", "Exchange a web onboarding bootstrap code")).action(init);
5165
+ program.name("agents").description("CLI tool for Standard Agents / AgentBuilder").version("0.16.1-next.1e58032");
5166
+ program.command("init [project-name]").description("Create a new Standard Agents project").option("-y, --yes", "Skip prompts and use defaults").option("--local", "Use local project scaffolding instead of browser platform onboarding").option("--cli", "Use classic line-by-line CLI prompts instead of the TUI wizard").option("--api-url <url>", "Standard Agents platform API URL").option("--endpoint <url>", "Platform API endpoint for auth/bootstrap exchange").option("--package-manager <manager>", "Package manager for generated project: npm, pnpm, yarn, or bun").option("--template <template>", "Vite template to use", "vanilla-ts").option("--workspace", "Install @standardagents packages as workspace:* (local pnpm workspace development)").option("--no-dev", "Clone and configure the project without starting the dev server").addOption(new Option("--bootstrap <code>", "Exchange a web onboarding bootstrap code")).action(init);
5304
5167
  program.command("login").description("Authenticate this machine (or use --bootstrap for project bootstrap auth)").option("--bootstrap <code>", "Bootstrap code from web onboarding").option("--endpoint <url>", "Platform API endpoint (default: https://api.standardagents.ai)").option("--no-open", "Do not auto-open browser URL").action(login);
5305
5168
  program.command("logout").description("Clear stored StandardAgents auth and local org-scoped project auth").option("--org <org-id-or-slug>", "Org ID or slug to logout (defaults to active org)").option("--endpoint <url>", "Platform API endpoint (default: https://api.standardagents.ai)").action(logout);
5306
5169
  program.command("scaffold").description("Add Standard Agents to an existing Vite project").option("--force", "Overwrite existing configuration").action(scaffold);
@@ -5308,7 +5171,10 @@ program.command("init-chat [project-name]").description("Scaffold a frontend cha
5308
5171
  program.command("pack [agent-name]").description("Pack an agent with all its dependencies").option("--output <dir>", "Output directory (default: agents/packed)").option("--npm", "Generate npm-ready package structure").option("--version <version>", "Package version (default: 1.0.0)").option("--no-remove", "Keep original files after packing").option("--no-interactive", "Skip interactive item mode selector").action(pack);
5309
5172
  program.command("unpack [package]").description("Unpack a packed agent to the local agents directory").option("--no-signatures", "Remove package signatures (fully editable)").action(unpack);
5310
5173
  program.command("list-packed").description("List all discovered packed agents").action(listPacked);
5311
- program.command("deploy").description("Build and deploy your project to the Standard Agents platform").option("--api-key <key>", "Platform API key (overrides STANDARD_AGENTS_API_KEY env var)").option("--endpoint <url>", "Platform API endpoint (default: https://api.standardagents.ai)").action(deploy);
5174
+ program.command("deploy").description("Push the current branch to the Standard Agents Artifacts remote").action(deploy);
5175
+ program.command("git-credential <operation>").description("Git credential helper for Standard Agents platform repositories").option("--endpoint <url>", "Platform API endpoint").action(gitCredential);
5176
+ program.command("git-login").description("Authenticate Git for Standard Agents platform repositories").option("--bootstrap <code>", "Bootstrap code from web onboarding").option("--endpoint <url>", "Platform API endpoint (default: https://api.standardagents.ai)").option("--helper-command <command>", "Credential helper command to add to global git config").option("--no-config", "Store Git auth but do not update global git config").option("--no-open", "Do not auto-open browser URL").action(gitLogin);
5177
+ program.command("support-files").description("Write generated local support files for a Standard Agents platform repository").option("--project-name <name>", "Project name to use in the generated package manifest").option("--package-manager <manager>", "Package manager: npm, pnpm, yarn, or bun").action(supportFiles);
5312
5178
  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);
5313
5179
  program.command("current-models").description("Print the live curated model guide from standardagentspec.com").option("--url <url>", "Override the models markdown URL").action(currentModels);
5314
5180
  program.command("available-models").description("List every available model for one configured provider in the current project").option("--provider <provider>", "Provider to query, for example cerebras or openai").action(availableModels);