aui-agent-builder 0.3.137 → 0.3.139

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
@@ -160,11 +160,24 @@ aui logout # Clear session and credentials
160
160
  ```bash
161
161
  aui agents # Interactive menu: list, create, switch, import, delete
162
162
  aui agents --list # List all agents in the current account
163
- aui agents --create # Interactive creation (org account name)
163
+ aui agents --create # Create, then auto-import into ./<agent-name> and drop you in
164
164
  aui agents --switch # Switch the active agent in your session
165
165
  aui agents --delete # Interactive: org → account → agent → choose scope (whole / one version / all versions)
166
166
  ```
167
167
 
168
+ **`aui agents --create` is end-to-end.** It creates the agent + its first
169
+ version, **auto-imports it into a new `./<agent-name>` folder** (use `--dir
170
+ <path>` to override), and **drops you into that folder via an interactive
171
+ subshell** so you can start editing immediately — run `exit` to return. The
172
+ creation **mode follows your environment**: `staging` / `custom` → bundle mode,
173
+ `production` / `eu-production` → records mode. Override with `--bundle-mode` /
174
+ `--records-mode`. **Non-interactive creation is create-only:** `--json`,
175
+ piped output, CI, and the agent-builder-bff sandbox skip BOTH the auto-import
176
+ and the subshell and behave like a plain create (set `AUI_AUTO_IMPORT=1` to
177
+ force the import in automation; `AUI_AUTO_IMPORT=0` to disable it in a
178
+ terminal). A child process can't change the parent shell's cwd, which is why
179
+ the interactive case opens a nested shell.
180
+
168
181
  **Non-interactive creation:**
169
182
 
170
183
  ```bash
@@ -177,8 +190,12 @@ aui agents --create --name "My Agent" --account-id <id>
177
190
  # With a specific category (e.g. Amazon, Google Flights)
178
191
  aui agents --create --name "My Agent" --account-id <id> --category Amazon
179
192
 
180
- # Create + v1.0 draft (ready to import, edit, and push)
181
- aui agents --create --name "My Agent" --account-id <id> --draft
193
+ # Import the new agent into a specific folder instead of ./<agent-name>
194
+ aui agents --create --name "My Agent" --account-id <id> --dir ./my-agent
195
+
196
+ # Force a creation mode regardless of environment
197
+ aui agents --create --name "My Agent" --account-id <id> --records-mode
198
+ aui agents --create --name "My Agent" --account-id <id> --bundle-mode
182
199
 
183
200
  # One-step: create + version + publish + activate
184
201
  aui agents --create --name "My Agent" --account-id <id> --full
@@ -511,25 +528,26 @@ aui upgrade # Update to latest version
511
528
  ### Create and Deploy a New Agent
512
529
 
513
530
  ```bash
514
- # Step 1: Create the agent (with a v1.0 draft ready to edit)
515
- aui agents --create --name "Support Agent" --account-id <id> --draft
516
-
517
- # Step 2: Import as local files
518
- aui import-agent
531
+ # Step 1: Create the agent. This also auto-imports it into ./support-agent
532
+ # and drops you into that folder via an interactive subshell — no separate
533
+ # `aui import-agent` needed. (Use --dir to choose a different folder.)
534
+ aui agents --create --name "Support Agent" --account-id <id>
519
535
 
520
- # Step 3: Edit configuration in your editor
521
- cd ./support-agent
536
+ # Step 2: Edit configuration in your editor (you're already in the folder)
522
537
  # → Edit agent.aui.json, tools/*.aui.json, parameters.aui.json, etc.
523
538
 
524
- # Step 4: Validate and push
539
+ # Step 3: Validate and push
525
540
  aui validate
526
541
  aui push
527
542
 
528
- # Step 5: Publish and activate
543
+ # Step 4: Publish and activate
529
544
  aui version publish
530
545
  aui version activate
531
546
  ```
532
547
 
548
+ > Prefer the classic two-step flow? It still works: create with `--json`
549
+ > (which skips the auto-import/subshell), then run `aui import-agent` yourself.
550
+
533
551
  **Creation modes:**
534
552
 
535
553
  ```bash
@@ -28,6 +28,14 @@ export interface AgentsOptions {
28
28
  draft?: boolean;
29
29
  name?: string;
30
30
  category?: string;
31
+ /**
32
+ * After `--create`, auto-import the freshly created agent's latest
33
+ * draft into this directory. When omitted, the import targets the
34
+ * current working directory (`.`). Only the records-mode `--create`
35
+ * flow produces a v1.0 draft to import; bundle-mode / template
36
+ * creates skip the auto-import (nothing to snapshot yet).
37
+ */
38
+ dir?: string;
31
39
  networkId?: string;
32
40
  accountId?: string;
33
41
  switch?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAkCH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA8ED,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgyDvE;AAuQD;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,QAAQ,GAAE,2BAAgC,GACzC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAuIxD"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/commands/agents.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAoCH,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;;;;;;;;;;;OAaG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA8ED,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CA6zDvE;AAuaD;;;;GAIG;AACH;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B;;;;;;;OAOG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,QAAQ,GAAE,2BAAgC,GACzC,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAuIxD"}
@@ -1,4 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { spawnSync } from "child_process";
3
+ import * as path from "path";
2
4
  import { render, Box, Text } from "ink";
3
5
  import inquirer from "inquirer";
4
6
  import chalk from "chalk";
@@ -1096,15 +1098,20 @@ export async function agents(options = {}) {
1096
1098
  //
1097
1099
  // Defaults when nothing is passed:
1098
1100
  // - kind → "regular"
1099
- // - bundle_mode → false (records mode). `aui agents --create`
1100
- // auto-creates a v1.0 draft from the agent
1101
- // scope (`source=agent-scope`), which is
1102
- // records-mode only. A fresh bundle-mode
1103
- // agent has nothing to snapshot, so making
1104
- // bundle-mode the default broke `--create`
1105
- // (and left an un-importable agent behind).
1106
- // Opt into blob-mode explicitly with
1107
- // `--bundle-mode`.
1101
+ // - bundle_mode → ENVIRONMENT-DRIVEN (resolved just below where
1102
+ // `bundleMode` is computed):
1103
+ // production / eu-production false (records
1104
+ // mode the legacy per-entity flow still used
1105
+ // in prod).
1106
+ // staging / custom → true (bundle
1107
+ // mode). `custom` is the staging-v3 backend,
1108
+ // mapped to staging, so it shares the default.
1109
+ // Records-mode regulars auto-snapshot a v1.0 draft
1110
+ // from agent-scope; bundle-mode regulars are
1111
+ // provisioned end-to-end via the Apollo endpoint
1112
+ // (version cloned from a template). Both then
1113
+ // auto-import locally. Override either way with
1114
+ // `--bundle-mode` / `--records-mode`.
1108
1115
  if (opts.bundleMode && opts.recordsMode) {
1109
1116
  renderView(_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(StatusLine, { kind: "error", label: "--bundle-mode and --records-mode are mutually exclusive." }), _jsx(Text, { color: "gray", children: " Pick one — or pass neither to use the default (records-mode)." })] }));
1110
1117
  return;
@@ -1129,10 +1136,32 @@ export async function agents(options = {}) {
1129
1136
  return;
1130
1137
  }
1131
1138
  const kind = opts.template ? "template" : "regular";
1132
- // Templates ALWAYS bundle-mode. For regulars, records-mode is the
1133
- // default (so the auto-draft flow can snapshot from agent-scope);
1134
- // --bundle-mode opts into blob-mode.
1135
- const bundleMode = opts.template ? true : opts.bundleMode === true;
1139
+ // ─── Resolve bundle_mode ──────────────────────────────────────────
1140
+ //
1141
+ // Precedence (highest first):
1142
+ // 1. Templates → always bundle-mode (forced).
1143
+ // 2. Explicit --bundle-mode → bundle-mode.
1144
+ // 3. Explicit --records-mode → records-mode.
1145
+ // 4. Otherwise (no flag) → derived from the signed-in
1146
+ // environment (see below).
1147
+ //
1148
+ // Environment-driven default for regulars when neither flag is passed:
1149
+ // - production / eu-production → records-mode (bundle_mode=false).
1150
+ // Prod still runs on the legacy per-entity records flow.
1151
+ // - staging / custom → bundle-mode (bundle_mode=true).
1152
+ // NOTE: `custom` is the staging-v3 backend — it's mapped to
1153
+ // staging, so it gets the same bundle-mode default as staging.
1154
+ //
1155
+ // Override either way with --bundle-mode / --records-mode explicitly.
1156
+ const env = config.environment ?? "staging";
1157
+ const envDefaultsToBundle = !(env === "production" || env === "eu-production");
1158
+ const bundleMode = opts.template
1159
+ ? true
1160
+ : opts.bundleMode === true
1161
+ ? true
1162
+ : opts.recordsMode === true
1163
+ ? false
1164
+ : envDefaultsToBundle;
1136
1165
  const client = new AUIClient({
1137
1166
  baseUrl: config.apiUrl,
1138
1167
  authToken: config.authToken,
@@ -1241,12 +1270,13 @@ export async function agents(options = {}) {
1241
1270
  // publish → activate) to the Apollo provisioning endpoint. The
1242
1271
  // legacy per-step path below is records-mode only.
1243
1272
  if (bundleMode) {
1244
- await createBundledAgentViaApollo({
1273
+ const created = await createBundledAgentViaApollo({
1245
1274
  name: agentName,
1246
1275
  networkCategoryId: categoryId,
1247
1276
  organizationId: client.getOrganizationId(),
1248
1277
  accountId: client.getAccountId(),
1249
1278
  });
1279
+ await autoImportAndEnter(created, opts.dir, agentName);
1250
1280
  return;
1251
1281
  }
1252
1282
  const netSpinner = render(_jsx(Spinner, { label: "Creating agent..." }));
@@ -1383,12 +1413,13 @@ export async function agents(options = {}) {
1383
1413
  // single call, so we skip the legacy per-step path (network create →
1384
1414
  // createAgentOnBackend → draft/full flow) entirely.
1385
1415
  if (bundleMode) {
1386
- await createBundledAgentViaApollo({
1416
+ const created = await createBundledAgentViaApollo({
1387
1417
  name: agentName,
1388
1418
  networkCategoryId: categoryId || "",
1389
1419
  organizationId: client.getOrganizationId(),
1390
1420
  accountId: client.getAccountId(),
1391
1421
  });
1422
+ await autoImportAndEnter(created, opts.dir, agentName);
1392
1423
  return;
1393
1424
  }
1394
1425
  // Create network
@@ -1421,18 +1452,18 @@ export async function agents(options = {}) {
1421
1452
  bundleMode,
1422
1453
  });
1423
1454
  if (result && opts.full) {
1424
- await runFullFlow(result.agentId, bundleMode);
1455
+ await runFullFlow(result.agentId, bundleMode, opts.dir, agentName);
1425
1456
  }
1426
1457
  else if (result) {
1427
1458
  // Draft is the DEFAULT: `aui agents --create` always creates a v1.0
1428
1459
  // draft version, even without `--draft`. The `--draft` flag is kept
1429
1460
  // as an explicit (now redundant) way to ask for the same thing.
1430
1461
  // Use `--full` to also publish + activate in one step.
1431
- await runDraftFlow(result.agentId, bundleMode);
1462
+ await runDraftFlow(result.agentId, bundleMode, opts.dir, agentName);
1432
1463
  }
1433
1464
  }
1434
1465
  }
1435
- async function runDraftFlow(agentId, bundleMode = false) {
1466
+ async function runDraftFlow(agentId, bundleMode = false, dir, agentName) {
1436
1467
  // Bundle-mode (blob) agents can't seed a draft from agent-scope, and a
1437
1468
  // brand-new one has no version to clone from either. Skip the auto-draft
1438
1469
  // and tell the user how to seed it instead of failing with a mode error.
@@ -1448,9 +1479,159 @@ async function runDraftFlow(agentId, bundleMode = false) {
1448
1479
  });
1449
1480
  if (!draft)
1450
1481
  return;
1451
- logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, marginTop: 1, children: [_jsxs(Box, { children: [_jsx(Text, { color: "green", bold: true, children: "✓ " }), _jsx(Text, { bold: true, children: "Draft v1.0 created. Next steps:" })] }), _jsx(Text, { children: " " }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { backgroundColor: "cyan", color: "black", bold: true, children: " 1 " }), _jsx(Text, { bold: true, children: " aui import-agent " }), _jsx(Text, { color: "gray", children: "Download the agent locally" })] }), _jsx(Text, { children: " " }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { backgroundColor: "cyan", color: "black", bold: true, children: " 2 " }), _jsx(Text, { bold: true, children: " aui push " }), _jsx(Text, { color: "gray", children: "Push your edits" })] }), _jsx(Text, { children: " " }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { backgroundColor: "cyan", color: "black", bold: true, children: " 3 " }), _jsx(Text, { bold: true, children: " aui version publish " }), _jsx(Text, { color: "gray", children: "Lock the version" })] }), _jsx(Text, { children: " " }), _jsxs(Box, { children: [_jsx(Text, { children: " " }), _jsx(Text, { backgroundColor: "cyan", color: "black", bold: true, children: " 4 " }), _jsx(Text, { bold: true, children: " aui version activate " }), _jsx(Text, { color: "gray", children: "Go live" })] }), _jsx(Text, { children: " " })] }));
1482
+ logView(_jsx(StatusLine, { kind: "success", label: "Draft v1.0 created." }));
1483
+ // Auto-import the freshly created draft so the user lands in a ready-to-
1484
+ // edit local project without a separate `aui import-agent` step. Defaults
1485
+ // to a new `./<agent-name>` folder; `--dir` overrides the destination.
1486
+ const importedDir = await autoImportLatestDraft(agentId, {
1487
+ versionId: draft.id,
1488
+ dir,
1489
+ agentName,
1490
+ });
1491
+ // Drop the user straight into the new project so they can start working
1492
+ // right away (no manual `cd`). No-op when there's no interactive TTY.
1493
+ if (importedDir)
1494
+ enterProjectShell(importedDir);
1452
1495
  }
1453
- async function runFullFlow(agentId, bundleMode = false) {
1496
+ /**
1497
+ * Auto-"cd" the user into the freshly imported project by launching an
1498
+ * interactive subshell rooted in that directory — the same pattern used by
1499
+ * `poetry shell`, `nix-shell`, etc. A child process cannot mutate its
1500
+ * parent shell's cwd, so spawning a nested shell is the only way to leave
1501
+ * the user actually sitting inside the new folder, ready to work.
1502
+ *
1503
+ * `dir` MUST be an absolute path — the caller resolves it BEFORE returning
1504
+ * so we don't re-resolve a relative path against an already-changed cwd
1505
+ * (the bug that left users stuck in the original directory).
1506
+ *
1507
+ * Strictly interactive-only and best-effort:
1508
+ * - Skipped unless BOTH stdin and stdout are TTYs (so the agent-builder-bff
1509
+ * sandbox, pipes, and CI never get trapped in a shell that nothing can
1510
+ * `exit`).
1511
+ * - Any spawn failure is swallowed — the import already succeeded, and the
1512
+ * files are sitting in `dir` regardless.
1513
+ */
1514
+ /**
1515
+ * Bundle-mode counterpart to runDraftFlow's tail: given a successful Apollo
1516
+ * provisioning result, auto-import the (already-active) version locally and
1517
+ * drop the user into the project. No-op when provisioning failed (`null`).
1518
+ * Templates never call this — they aren't runtime agents.
1519
+ */
1520
+ async function autoImportAndEnter(created, dir, agentName) {
1521
+ if (!created)
1522
+ return;
1523
+ const importedDir = await autoImportLatestDraft(created.agentId, {
1524
+ versionId: created.activeVersionId,
1525
+ tag: created.activeVersionTag,
1526
+ dir,
1527
+ agentName,
1528
+ });
1529
+ if (importedDir)
1530
+ enterProjectShell(importedDir);
1531
+ }
1532
+ /**
1533
+ * Whether the post-create auto-import + drop-into-project conveniences should
1534
+ * run. They only make sense in a real interactive terminal — non-interactive
1535
+ * creation (agent-builder-bff sandbox, CI, piped/redirected output, `--json`)
1536
+ * must behave exactly like a plain create: no local import, no subshell.
1537
+ *
1538
+ * Resolution order:
1539
+ * 1. JSON mode → never (production contract: no Ink on stdout).
1540
+ * 2. AUI_AUTO_IMPORT=1 / =0 → explicit opt-in / opt-out (automation + tests).
1541
+ * 3. otherwise → only when BOTH stdin and stdout are TTYs.
1542
+ */
1543
+ function isInteractiveSession() {
1544
+ if (isJsonMode())
1545
+ return false;
1546
+ if (process.env.AUI_AUTO_IMPORT === "1")
1547
+ return true;
1548
+ if (process.env.AUI_AUTO_IMPORT === "0")
1549
+ return false;
1550
+ return Boolean(process.stdin.isTTY) && Boolean(process.stdout.isTTY);
1551
+ }
1552
+ function enterProjectShell(dir) {
1553
+ if (!process.stdin.isTTY || !process.stdout.isTTY)
1554
+ return;
1555
+ const isWindows = process.platform === "win32";
1556
+ const shell = process.env.SHELL ||
1557
+ (isWindows ? process.env.COMSPEC || "cmd.exe" : "/bin/bash");
1558
+ logView(_jsx(Box, { paddingX: 1, marginTop: 1, children: _jsx(StatusLine, { kind: "success", label: "Start building your agent!" }) }));
1559
+ try {
1560
+ // `-i` requests an interactive shell on POSIX so rc files load and the
1561
+ // user gets their normal prompt; cmd.exe needs no flag. stdio is
1562
+ // inherited so the nested shell owns the terminal until it exits.
1563
+ spawnSync(shell, isWindows ? [] : ["-i"], {
1564
+ cwd: dir,
1565
+ stdio: "inherit",
1566
+ });
1567
+ }
1568
+ catch {
1569
+ // best-effort — the project is already on disk at `dir`.
1570
+ }
1571
+ }
1572
+ /**
1573
+ * Auto-import the latest draft of a freshly created agent.
1574
+ *
1575
+ * Called right after `versionCreate` seeds the v1.0 draft so `aui agents
1576
+ * --create` lands the user in a ready-to-edit local project without a
1577
+ * separate `aui import-agent` invocation.
1578
+ *
1579
+ * - `dir` provided → import into that exact directory.
1580
+ * - `dir` omitted → import into a NEW `./<agent-name>` folder (a single
1581
+ * self-contained project named after the agent), so
1582
+ * the files are never dumped loose into the cwd.
1583
+ *
1584
+ * Best-effort: a failed import never fails the create (the agent + draft
1585
+ * already exist server-side). We surface a hint to re-run `aui import-agent`
1586
+ * manually instead.
1587
+ *
1588
+ * INTERACTIVE-ONLY: skipped entirely for non-interactive creation (see
1589
+ * `isInteractiveSession`). The non-interactive `aui agents --create …`
1590
+ * commands — agent-builder-bff in its E2B sandbox, CI, piped output, and any
1591
+ * `--json` run — must behave exactly like a plain "create" (no local import,
1592
+ * no subshell), so this returns `null` and the create just reports the new
1593
+ * agent. Real terminals (or an explicit `AUI_AUTO_IMPORT=1`) get the import.
1594
+ */
1595
+ async function autoImportLatestDraft(agentId, opts) {
1596
+ if (!isInteractiveSession())
1597
+ return null;
1598
+ const targetDir = opts.dir || agentFolderName(opts.agentName);
1599
+ // Resolve to an absolute path NOW, against the current cwd, before the
1600
+ // import (which doesn't change cwd) — so the subshell gets an unambiguous
1601
+ // directory and we never re-resolve a relative path twice.
1602
+ const resolvedDir = path.resolve(targetDir);
1603
+ try {
1604
+ const { importAgent } = await import("./import-agent.js");
1605
+ await importAgent(agentId, {
1606
+ dir: targetDir,
1607
+ version: opts.versionId,
1608
+ tag: opts.versionId ? undefined : opts.tag,
1609
+ });
1610
+ return resolvedDir;
1611
+ }
1612
+ catch (error) {
1613
+ logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, marginTop: 1, children: [_jsx(StatusLine, { kind: "warning", label: `Auto-import failed: ${error instanceof Error ? error.message : String(error)}` }), _jsx(Text, { color: "gray", children: ` Import it manually with: aui import-agent --dir ${targetDir}` })] }));
1614
+ return null;
1615
+ }
1616
+ }
1617
+ /**
1618
+ * Build the default auto-import folder name from the agent's chosen name:
1619
+ * a single `./<sanitized-name>` directory under the current working dir.
1620
+ * Mirrors the sanitization `import-agent` uses for its own default folder
1621
+ * so a created-then-imported agent and a manually imported one land in
1622
+ * predictable, matching directory names. Falls back to `./agent` when the
1623
+ * name is missing or sanitizes to empty.
1624
+ */
1625
+ function agentFolderName(agentName) {
1626
+ const safe = (agentName || "")
1627
+ .toLowerCase()
1628
+ .replace(/[\/\\:*?"<>|]/g, "-")
1629
+ .replace(/\s+/g, "-")
1630
+ .replace(/-+/g, "-")
1631
+ .replace(/^-|-$/g, "");
1632
+ return `./${safe || "agent"}`;
1633
+ }
1634
+ async function runFullFlow(agentId, bundleMode = false, dir, agentName) {
1454
1635
  // See runDraftFlow: blob-mode agents can't snapshot from agent-scope.
1455
1636
  if (bundleMode) {
1456
1637
  logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, marginTop: 1, children: [_jsx(StatusLine, { kind: "info", label: "Bundle-mode agent created \u2014 skipping auto version flow (blob-mode has nothing to snapshot yet)." }), _jsx(Text, { color: "gray", children: " Seed it from a template: aui version create --source template --from-template <templateAgentId>" })] }));
@@ -1468,6 +1649,15 @@ async function runFullFlow(agentId, bundleMode = false) {
1468
1649
  await versionPublish(draft.id, agentId);
1469
1650
  // Activate
1470
1651
  await versionActivate(draft.id, agentId);
1652
+ // Auto-import the (now-active) v1.0 locally, mirroring runDraftFlow.
1653
+ const importedDir = await autoImportLatestDraft(agentId, {
1654
+ versionId: draft.id,
1655
+ dir,
1656
+ agentName,
1657
+ });
1658
+ // Drop the user into the new project so they can start working right away.
1659
+ if (importedDir)
1660
+ enterProjectShell(importedDir);
1471
1661
  }
1472
1662
  function logView(node) {
1473
1663
  const inst = render(node);
@@ -1544,11 +1734,13 @@ async function createBundledAgentViaApollo(input) {
1544
1734
  delete session.version_revision_number;
1545
1735
  saveSession(session);
1546
1736
  }
1547
- const activeVersion = (typeof res.active_version_tag === "string" && res.active_version_tag) ||
1548
- (typeof res.active_version_id === "string" && res.active_version_id) ||
1549
- "";
1550
- logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(StatusLine, { kind: "success", label: `${isTemplate ? "Template" : "Bundle agent"} created: ${res.name || input.name}${agentId ? ` (${agentId})` : ""}` }), isTemplate ? (_jsx(Text, { color: "gray", children: ` Use it as a clone source: aui version create --source template --from-template ${agentId || "<templateId>"}` })) : (_jsx(Text, { color: "gray", children: " Apollo provisioned it end-to-end: network → agent → version (from template) → published → activated." })), activeVersion ? (_jsx(StatusLine, { kind: "muted", label: `Active version: ${activeVersion}` })) : null, !isTemplate && agentId ? (_jsx(StatusLine, { kind: "muted", label: "Session updated to this agent." })) : null, !isTemplate ? (_jsxs(_Fragment, { children: [_jsx(Text, { children: " " }), _jsxs(Box, { children: [_jsx(Text, { color: "gray", children: " Next: " }), _jsx(Text, { bold: true, children: "aui import-agent" }), _jsx(Text, { color: "gray", children: " to download it locally." })] })] })) : null] }));
1551
- return agentId ? { agentId } : null;
1737
+ const activeVersionId = typeof res.active_version_id === "string" ? res.active_version_id : undefined;
1738
+ const activeVersionTag = typeof res.active_version_tag === "string" ? res.active_version_tag : undefined;
1739
+ const activeVersion = activeVersionTag || activeVersionId || "";
1740
+ logView(_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(StatusLine, { kind: "success", label: `${isTemplate ? "Template" : "Bundle agent"} created: ${res.name || input.name}${agentId ? ` (${agentId})` : ""}` }), isTemplate ? (_jsx(Text, { color: "gray", children: ` Use it as a clone source: aui version create --source template --from-template ${agentId || "<templateId>"}` })) : (_jsx(Text, { color: "gray", children: " Apollo provisioned it end-to-end: network → agent → version (from template) → published → activated." })), activeVersion ? (_jsx(StatusLine, { kind: "muted", label: `Active version: ${activeVersion}` })) : null, !isTemplate && agentId ? (_jsx(StatusLine, { kind: "muted", label: "Session updated to this agent." })) : null] }));
1741
+ return agentId
1742
+ ? { agentId, activeVersionId, activeVersionTag }
1743
+ : null;
1552
1744
  }
1553
1745
  catch (error) {
1554
1746
  spinner.unmount();