agent-transport-system 0.7.26 → 0.7.28

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/ats.js CHANGED
@@ -27,7 +27,7 @@ import wrapAnsi from "wrap-ansi";
27
27
  import { Box, Container, Editor, Key, ProcessTerminal, TUI, Text, getEditorKeybindings, matchesKey } from "@mariozechner/pi-tui";
28
28
 
29
29
  //#region package.json
30
- var version = "0.7.26";
30
+ var version = "0.7.28";
31
31
  var package_default = {
32
32
  $schema: "https://www.schemastore.org/package.json",
33
33
  name: "agent-transport-system",
@@ -5459,7 +5459,7 @@ async function getRemoteAuthSessionState(session) {
5459
5459
  }
5460
5460
  function resolveRemoteSessionTimeoutMs(endpoint) {
5461
5461
  const url = parseUrlOrNull$3(endpoint);
5462
- if (url && isLoopbackHostname$3(url.hostname)) return LOOPBACK_REMOTE_SESSION_TIMEOUT_MS;
5462
+ if (url && isLoopbackHostname$4(url.hostname)) return LOOPBACK_REMOTE_SESSION_TIMEOUT_MS;
5463
5463
  return DEFAULT_REMOTE_SESSION_TIMEOUT_MS;
5464
5464
  }
5465
5465
  function parseUrlOrNull$3(value) {
@@ -5469,7 +5469,7 @@ function parseUrlOrNull$3(value) {
5469
5469
  return null;
5470
5470
  }
5471
5471
  }
5472
- function isLoopbackHostname$3(hostname) {
5472
+ function isLoopbackHostname$4(hostname) {
5473
5473
  return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
5474
5474
  }
5475
5475
  function hasActiveSessionPayload(payload) {
@@ -5762,7 +5762,7 @@ async function requireAtsProfilesSession() {
5762
5762
  }
5763
5763
  function resolveAtsProfilesApiTimeoutMs(endpoint) {
5764
5764
  const url = parseUrlOrNull$2(endpoint);
5765
- if (url && isLoopbackHostname$2(url.hostname)) return LOOPBACK_ATS_PROFILES_API_TIMEOUT_MS;
5765
+ if (url && isLoopbackHostname$3(url.hostname)) return LOOPBACK_ATS_PROFILES_API_TIMEOUT_MS;
5766
5766
  return DEFAULT_ATS_PROFILES_API_TIMEOUT_MS;
5767
5767
  }
5768
5768
  function parseUrlOrNull$2(value) {
@@ -5772,7 +5772,7 @@ function parseUrlOrNull$2(value) {
5772
5772
  return null;
5773
5773
  }
5774
5774
  }
5775
- function isLoopbackHostname$2(hostname) {
5775
+ function isLoopbackHostname$3(hostname) {
5776
5776
  return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
5777
5777
  }
5778
5778
  function isSameStoredAuthSession(a, b) {
@@ -5908,11 +5908,11 @@ async function findAtsProfileByNameOrHandle(input) {
5908
5908
  }
5909
5909
  function isLoopbackProfileEndpoint(endpoint) {
5910
5910
  const url = parseUrlOrNull$2(endpoint);
5911
- return Boolean(url && isLoopbackHostname$2(url.hostname) && url.pathname.startsWith("/v1/profiles"));
5911
+ return Boolean(url && isLoopbackHostname$3(url.hostname) && url.pathname.startsWith("/v1/profiles"));
5912
5912
  }
5913
5913
  function isHostedProfilesEndpoint(endpoint) {
5914
5914
  const url = parseUrlOrNull$2(endpoint);
5915
- return Boolean(url && !isLoopbackHostname$2(url.hostname) && url.pathname.startsWith("/v1/profiles"));
5915
+ return Boolean(url && !isLoopbackHostname$3(url.hostname) && url.pathname.startsWith("/v1/profiles"));
5916
5916
  }
5917
5917
  function isRecord$5(value) {
5918
5918
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
@@ -12214,7 +12214,7 @@ function resolveAuthRequestCompatibility(input) {
12214
12214
  const expectedGatewayHost = deriveGatewayHost(authBaseUrl);
12215
12215
  const requestHost = requestUrl.host;
12216
12216
  const authHost = authBaseUrl.host;
12217
- if (isLoopbackHostname$1(requestUrl.hostname) && isLoopbackHostname$1(authBaseUrl.hostname)) return {
12217
+ if (isLoopbackHostname$2(requestUrl.hostname) && isLoopbackHostname$2(authBaseUrl.hostname)) return {
12218
12218
  compatible: true,
12219
12219
  reason: "loopback",
12220
12220
  requestHost,
@@ -12278,7 +12278,7 @@ function parseUrlOrNull$1(value) {
12278
12278
  return null;
12279
12279
  }
12280
12280
  }
12281
- function isLoopbackHostname$1(hostname) {
12281
+ function isLoopbackHostname$2(hostname) {
12282
12282
  return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
12283
12283
  }
12284
12284
  function isSecureTransportProtocol(protocol) {
@@ -45864,6 +45864,7 @@ function renderDaemonReinstallCard(input) {
45864
45864
  }
45865
45865
  function renderDaemonReinstallOutcome(input) {
45866
45866
  emitDaemonReinstallResult(input);
45867
+ if (input.suppressHumanResultCard === true) return;
45867
45868
  renderDaemonReinstallCard(input);
45868
45869
  }
45869
45870
  function createDaemonStartSpinner(input) {
@@ -46180,7 +46181,8 @@ async function runDaemonReinstall(input, options = {}) {
46180
46181
  action: displayAction,
46181
46182
  outcome,
46182
46183
  presenter,
46183
- resolvedView: runtime.resolvedView
46184
+ resolvedView: runtime.resolvedView,
46185
+ suppressHumanResultCard: options.suppressHumanResultCard
46184
46186
  });
46185
46187
  return outcome;
46186
46188
  } catch (error) {
@@ -50171,6 +50173,7 @@ async function runDaemonServiceParticipationInstallAction(input) {
50171
50173
  await runDaemonServiceSafeRefresh({
50172
50174
  atsProfileId: input.input.atsProfileId,
50173
50175
  gatewayUrl: input.input.gatewayUrl,
50176
+ suppressHumanResultCard: input.input.suppressRefreshHumanResultCard,
50174
50177
  view: input.input.view
50175
50178
  });
50176
50179
  return;
@@ -50210,6 +50213,7 @@ async function runDaemonServiceSafeRefresh(input) {
50210
50213
  skipConfirm: true,
50211
50214
  startAfterInstallMode: "always",
50212
50215
  suppressAgentOverview: true,
50216
+ suppressHumanResultCard: input.suppressHumanResultCard,
50213
50217
  suppressInstallOutput: true
50214
50218
  });
50215
50219
  }
@@ -50249,6 +50253,7 @@ async function runDaemonServiceParticipationRefresh(input) {
50249
50253
  const refreshOutcome = await runDaemonServiceSafeRefresh({
50250
50254
  atsProfileId: input.input.atsProfileId,
50251
50255
  gatewayUrl: input.input.gatewayUrl,
50256
+ suppressHumanResultCard: input.input.suppressRefreshHumanResultCard,
50252
50257
  view: input.input.view
50253
50258
  });
50254
50259
  if (refreshOutcome.ok && (refreshOutcome.result === "completed" || refreshOutcome.result === "stopped_safe") && refreshOutcome.serviceState === "stopped") {
@@ -76090,7 +76095,7 @@ function toAuthEndpoint(baseUrl, pathname) {
76090
76095
  }
76091
76096
  function buildSpaceWebUrl(baseUrl, spaceId) {
76092
76097
  const url = new URL(baseUrl);
76093
- if (isLoopbackHostname(url.hostname) && url.port === "8080") url.port = "3000";
76098
+ if (isLoopbackHostname$1(url.hostname) && url.port === "8080") url.port = "3000";
76094
76099
  if (url.hostname === "gateway.ats.sh") {
76095
76100
  url.hostname = "ats.sh";
76096
76101
  url.port = "";
@@ -76103,7 +76108,7 @@ function buildSpaceWebUrl(baseUrl, spaceId) {
76103
76108
  }
76104
76109
  function resolveSpaceCreateAuthCheckTimeoutMs(endpoint) {
76105
76110
  const url = parseUrlOrNull(endpoint);
76106
- if (url && isLoopbackHostname(url.hostname)) return SPACE_CREATE_AUTH_CHECK_LOOPBACK_TIMEOUT_MS;
76111
+ if (url && isLoopbackHostname$1(url.hostname)) return SPACE_CREATE_AUTH_CHECK_LOOPBACK_TIMEOUT_MS;
76107
76112
  return SPACE_CREATE_AUTH_CHECK_TIMEOUT_MS;
76108
76113
  }
76109
76114
  function parseUrlOrNull(value) {
@@ -76113,7 +76118,7 @@ function parseUrlOrNull(value) {
76113
76118
  return null;
76114
76119
  }
76115
76120
  }
76116
- function isLoopbackHostname(hostname) {
76121
+ function isLoopbackHostname$1(hostname) {
76117
76122
  return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
76118
76123
  }
76119
76124
  function emitSpaceCreateSuccessOutput(input) {
@@ -87272,6 +87277,67 @@ function normalizeId(value) {
87272
87277
  return value.trim();
87273
87278
  }
87274
87279
 
87280
+ //#endregion
87281
+ //#region src/ui/setup-human-view.ts
87282
+ async function runWithSetupSpinner(input) {
87283
+ const spinner = createDelayedSpinner({
87284
+ enabled: input.enabled,
87285
+ message: input.message
87286
+ });
87287
+ spinner.start();
87288
+ try {
87289
+ const result = await input.run();
87290
+ spinner.complete();
87291
+ return result;
87292
+ } catch (error) {
87293
+ spinner.fail();
87294
+ throw error;
87295
+ }
87296
+ }
87297
+ function emitSetupHumanHeader(input) {
87298
+ if (input.view !== "human") return;
87299
+ input.presenter.line({
87300
+ code: "setup.header.spacing.start",
87301
+ text: ""
87302
+ });
87303
+ for (const line of renderAtsBrandBlockLines()) input.presenter.line({
87304
+ code: "setup.header.brand",
87305
+ text: line
87306
+ });
87307
+ input.presenter.line({
87308
+ code: "setup.header.spacing.end",
87309
+ text: ""
87310
+ });
87311
+ }
87312
+ function renderSetupStepCard(input) {
87313
+ if (input.view !== "human") return;
87314
+ renderInfoCard({
87315
+ presenter: input.presenter,
87316
+ title: input.title,
87317
+ codePrefix: input.codePrefix,
87318
+ rows: input.rows,
87319
+ sanitize: true,
87320
+ minContentWidth: 52
87321
+ });
87322
+ }
87323
+ function renderSetupAgentHandoffCard(input) {
87324
+ if (input.view !== "human") return;
87325
+ renderInfoCard({
87326
+ presenter: input.presenter,
87327
+ title: "For AI Setup Agents",
87328
+ codePrefix: "setup.complete.agent_handoff.card",
87329
+ rows: [{
87330
+ label: "Structured output",
87331
+ value: `Run ${formatAtsCliCommand(`${input.cliCommandPrefix} setup --view agent`)} to print setup.complete.`
87332
+ }, {
87333
+ label: "Use when",
87334
+ value: "An AI setup agent needs the machine-readable setup facts for follow-up ATS commands."
87335
+ }],
87336
+ sanitize: true,
87337
+ minContentWidth: 52
87338
+ });
87339
+ }
87340
+
87275
87341
  //#endregion
87276
87342
  //#region src/start-foundation/profile-id.ts
87277
87343
  function resolveCliStartFoundationProfileId(profile) {
@@ -87629,6 +87695,7 @@ const PREPARE_SESSION_MAX_RECONNECT_ATTEMPTS = 3;
87629
87695
  const PREPARE_SESSION_RECONNECT_DELAY_MS = 1e3;
87630
87696
  const REPORT_RUNTIME_CONNECTION_MAX_ATTEMPTS = 12;
87631
87697
  const REPORT_RUNTIME_CONNECTION_RETRY_DELAY_MS = 1e3;
87698
+ const BRING_AGENTS_AGENT_SELECTION_PATH = "/app/start/bring-agents/agents";
87632
87699
  const TERMINAL_PREPARE_STEP_ORDER = [
87633
87700
  "prepare_selected_agents",
87634
87701
  "refresh_service",
@@ -87761,14 +87828,82 @@ async function resolveAgentSelection(input) {
87761
87828
  });
87762
87829
  }
87763
87830
  if (hasAgentSelectionBeenSaved(input.snapshot)) return input.snapshot;
87764
- emitHumanStatus(input.input, "Waiting for ATS Web", ["Choose local agents on the setup page.", "Setup will continue here automatically."]);
87831
+ const setupPageUrl = buildPrepareSessionWebSelectionUrl({
87832
+ gatewayUrl: input.input.gatewayUrl,
87833
+ snapshot: input.snapshot
87834
+ });
87835
+ const openedSetupPage = await tryOpenPrepareSessionWebSelectionUrl({
87836
+ input: input.input,
87837
+ setupPageUrl
87838
+ });
87839
+ emitHumanStatus(input.input, "Waiting for ATS Web", [
87840
+ "Choose local agents on the setup page.",
87841
+ ...formatPrepareSessionWebSelectionUrlLines({
87842
+ opened: openedSetupPage,
87843
+ setupPageUrl
87844
+ }),
87845
+ "Setup will continue here automatically."
87846
+ ]);
87765
87847
  return await waitForSnapshotWithProgress({
87766
87848
  input: input.input,
87767
87849
  stream: input.stream,
87768
87850
  predicate: hasAgentSelectionBeenSaved,
87769
- waitingMessage: "Still waiting for your choice in ATS Web. Keep this Terminal open"
87851
+ waitingMessage: formatPrepareSessionWebSelectionWaitingMessage({ setupPageUrl })
87770
87852
  });
87771
87853
  }
87854
+ function buildPrepareSessionWebSelectionUrl(input) {
87855
+ const webBaseUrl = resolvePrepareSessionWebBaseUrl(input.gatewayUrl);
87856
+ if (!webBaseUrl) return null;
87857
+ const url = new URL(BRING_AGENTS_AGENT_SELECTION_PATH, webBaseUrl);
87858
+ url.search = buildPrepareSessionWebSelectionSearch(input.snapshot).toString();
87859
+ return url.toString();
87860
+ }
87861
+ function buildPrepareSessionWebSelectionSearch(snapshot) {
87862
+ const params = new URLSearchParams();
87863
+ params.set("setup", "this-computer");
87864
+ if (snapshot.targetSpaceId && snapshot.humanProfileId) {
87865
+ params.set("returnTo", "space");
87866
+ params.set("spaceId", snapshot.targetSpaceId);
87867
+ params.set("profileId", snapshot.humanProfileId);
87868
+ return params;
87869
+ }
87870
+ params.set("returnTo", "agents");
87871
+ return params;
87872
+ }
87873
+ function resolvePrepareSessionWebBaseUrl(gatewayUrl) {
87874
+ try {
87875
+ const url = new URL(gatewayUrl);
87876
+ if (isLoopbackHostname(url.hostname) && url.port === "8080") url.port = "3000";
87877
+ if (url.hostname === "gateway.ats.sh") {
87878
+ url.hostname = "ats.sh";
87879
+ url.port = "";
87880
+ url.protocol = "https:";
87881
+ }
87882
+ url.pathname = "/";
87883
+ url.search = "";
87884
+ url.hash = "";
87885
+ return url.toString();
87886
+ } catch {
87887
+ return null;
87888
+ }
87889
+ }
87890
+ function isLoopbackHostname(hostname) {
87891
+ const normalizedHostname = hostname.toLowerCase();
87892
+ return normalizedHostname === "localhost" || normalizedHostname === "127.0.0.1" || normalizedHostname === "::1";
87893
+ }
87894
+ async function tryOpenPrepareSessionWebSelectionUrl(input) {
87895
+ if (!(input.setupPageUrl && input.input.runtime.resolvedView === "human" && input.input.interactive && process$1.stdout.isTTY)) return false;
87896
+ return await tryOpenUrl(input.setupPageUrl);
87897
+ }
87898
+ function formatPrepareSessionWebSelectionUrlLines(input) {
87899
+ if (!input.setupPageUrl) return ["Return to ATS Web to finish choosing agents."];
87900
+ if (input.opened) return ["ATS opened the setup page in your browser.", `Setup page: ${input.setupPageUrl}`];
87901
+ return [`Open this setup page: ${input.setupPageUrl}`];
87902
+ }
87903
+ function formatPrepareSessionWebSelectionWaitingMessage(input) {
87904
+ const baseMessage = "Still waiting for your choice in ATS Web. Keep this Terminal open";
87905
+ return input.setupPageUrl ? `${baseMessage}. Setup page: ${input.setupPageUrl}` : baseMessage;
87906
+ }
87772
87907
  function resolveTerminalSelectedLocalAgentIds(input) {
87773
87908
  if (input.selection.mode === "none") return [];
87774
87909
  const catalog = input.snapshot.localAgentCatalog;
@@ -91325,6 +91460,10 @@ async function runSetupUnlocked(input) {
91325
91460
  const presenter = createPresenter(runtime);
91326
91461
  const interactive = canUseInteractivePrompts(runtime);
91327
91462
  const gatewayUrl = await resolveBaseUrl();
91463
+ emitSetupHumanHeader({
91464
+ presenter,
91465
+ view: runtime.resolvedView
91466
+ });
91328
91467
  await maybeLogInWithOneTimeToken({
91329
91468
  ott: input.ott,
91330
91469
  view: input.view
@@ -91335,28 +91474,51 @@ async function runSetupUnlocked(input) {
91335
91474
  promptMessage: "Sign in to ATS before setting up this computer.",
91336
91475
  allowPrompt: interactive
91337
91476
  })) return;
91338
- emitSetupStatus(runtime, "Checking local agents", ["Looking for supported local agents on this computer."]);
91339
- const initialReadiness = await collectStartLocalReadiness({ auth: {
91340
- status: "valid",
91341
- email: null,
91342
- authBaseUrl: null,
91343
- gatewayUrl
91344
- } });
91477
+ const initialReadiness = await runWithSetupSpinner({
91478
+ enabled: runtime.resolvedView === "human",
91479
+ message: "Checking local agents...",
91480
+ run: async () => await collectStartLocalReadiness({ auth: {
91481
+ status: "valid",
91482
+ email: null,
91483
+ authBaseUrl: null,
91484
+ gatewayUrl
91485
+ } })
91486
+ });
91345
91487
  const selectedLocalAgentIds = resolveSetupLocalAgentIds({
91346
91488
  localAgent: input.localAgent,
91347
91489
  localAgents: input.localAgents,
91348
91490
  readiness: initialReadiness
91349
91491
  });
91350
- if (selectedLocalAgentIds.length > 0) {
91351
- emitSetupStatus(runtime, "Connecting local agents", [`Connecting ${selectedLocalAgentIds.length} local agent${selectedLocalAgentIds.length === 1 ? "" : "s"} for ATS.`]);
91352
- assertStartLocalAgentsEnableCompleted(await runStartLocalAgentsEnable({
91492
+ if (selectedLocalAgentIds.length > 0) assertStartLocalAgentsEnableCompleted(await runWithSetupSpinner({
91493
+ enabled: runtime.resolvedView === "human",
91494
+ message: "Connecting local agents...",
91495
+ run: async () => await runStartLocalAgentsEnable({
91353
91496
  agent: selectedLocalAgentIds,
91354
91497
  interactive,
91355
91498
  presentation: "handoff",
91356
91499
  view: input.view
91357
- }));
91358
- }
91359
- emitSetupStatus(runtime, "Starting ATS Service", ["Starting or repairing ATS Service for this computer."]);
91500
+ })
91501
+ }));
91502
+ renderSetupStepCard({
91503
+ presenter,
91504
+ view: runtime.resolvedView,
91505
+ title: "✓ Local Agents",
91506
+ codePrefix: "setup.local_agents.card",
91507
+ rows: [
91508
+ {
91509
+ label: "Status",
91510
+ value: selectedLocalAgentIds.length > 0 ? "Connected" : "No local agents selected"
91511
+ },
91512
+ {
91513
+ label: "Found",
91514
+ value: formatSetupLocalAgentCandidateCount(initialReadiness)
91515
+ },
91516
+ {
91517
+ label: "Selected",
91518
+ value: formatSetupCompleteLocalAgents(selectedLocalAgentIds)
91519
+ }
91520
+ ]
91521
+ });
91360
91522
  const serviceGate = await runDaemonServiceParticipationGate({
91361
91523
  intent: "start",
91362
91524
  presenter,
@@ -91366,11 +91528,36 @@ async function runSetupUnlocked(input) {
91366
91528
  gatewayUrl,
91367
91529
  forcePrompt: true,
91368
91530
  refreshIfAuthSessionChanged: true,
91531
+ suppressRefreshHumanResultCard: true,
91369
91532
  view: input.view
91370
91533
  });
91371
91534
  if (serviceGate.status === "cancelled") return;
91372
91535
  if (serviceGate.status !== "aligned") throw new Error(serviceGate.errorMessage ?? "ATS Service could not be started for setup on this computer.");
91373
91536
  const atsServiceRuntimeIdentity = await syncLocalSetupCurrentDeviceTargetFromServiceContract({ gatewayUrl });
91537
+ renderSetupStepCard({
91538
+ presenter,
91539
+ view: runtime.resolvedView,
91540
+ title: "✓ ATS Service",
91541
+ codePrefix: "setup.service.card",
91542
+ rows: [
91543
+ {
91544
+ label: "Status",
91545
+ value: "Connected"
91546
+ },
91547
+ {
91548
+ label: "What happened",
91549
+ value: "ATS checked the background service and aligned it with this setup."
91550
+ },
91551
+ {
91552
+ label: "Current service",
91553
+ value: formatSetupCompleteService(atsServiceRuntimeIdentity)
91554
+ },
91555
+ {
91556
+ label: "Next",
91557
+ value: "No action is required."
91558
+ }
91559
+ ]
91560
+ });
91374
91561
  const finalReadiness = await collectStartLocalReadiness({ auth: {
91375
91562
  status: "valid",
91376
91563
  email: null,
@@ -91387,8 +91574,31 @@ async function runSetupUnlocked(input) {
91387
91574
  });
91388
91575
  assertSelectedLocalRuntimeReportsAccepted(runtimeReports);
91389
91576
  const routeCatalogSync = selectedLocalAgentIds.length > 0 ? await notifyRouteCatalogAfterSetup({ reason: "setup_local_capabilities_reported" }) : null;
91390
- emitSetupStatus(runtime, "Updating ATS skills", ["Updating ATS skills so local agents use the current ATS instructions."]);
91391
- await ensureSetupManagedSkills({ view: input.view });
91577
+ await runWithSetupSpinner({
91578
+ enabled: runtime.resolvedView === "human",
91579
+ message: "Updating ATS skills...",
91580
+ run: async () => await ensureSetupManagedSkills({ view: input.view })
91581
+ });
91582
+ renderSetupStepCard({
91583
+ presenter,
91584
+ view: runtime.resolvedView,
91585
+ title: "✓ ATS Skills",
91586
+ codePrefix: "setup.skills.card",
91587
+ rows: [
91588
+ {
91589
+ label: "Status",
91590
+ value: "Updated"
91591
+ },
91592
+ {
91593
+ label: "What happened",
91594
+ value: "ATS refreshed the local instructions used by supported agents."
91595
+ },
91596
+ {
91597
+ label: "Next",
91598
+ value: "Local agents can use the current ATS guide."
91599
+ }
91600
+ ]
91601
+ });
91392
91602
  emitSetupComplete({
91393
91603
  gatewayUrl,
91394
91604
  localComponents: await finalizeLocalComponentsSetupSnapshot(),
@@ -91466,10 +91676,6 @@ function assertStartLocalAgentsEnableCompleted(result) {
91466
91676
  async function notifyRouteCatalogAfterSetup(input) {
91467
91677
  return await notifyDaemonRouteCatalogChanged({ reason: input.reason });
91468
91678
  }
91469
- function emitSetupStatus(runtime, title, lines) {
91470
- if (runtime.resolvedView !== "human") return;
91471
- console.log([title, ...lines].join("\n"));
91472
- }
91473
91679
  async function emitSetupCompleteForDelegatedPath(input) {
91474
91680
  const runtime = await resolveRuntimeContext({ view: input.view });
91475
91681
  const presenter = createPresenter(runtime);
@@ -91589,17 +91795,13 @@ function emitSetupComplete(input) {
91589
91795
  if (input.view === "human") {
91590
91796
  renderInfoCard({
91591
91797
  presenter: input.presenter,
91592
- title: "ATS Setup Complete",
91798
+ title: "ATS Setup Complete",
91593
91799
  codePrefix: "setup.complete.card",
91594
91800
  sanitize: true,
91595
91801
  rows: [
91596
91802
  {
91597
- label: "CLI prefix",
91598
- value: cliCommandPrefix
91599
- },
91600
- {
91601
- label: "Lane root",
91602
- value: payload.laneRoot
91803
+ label: "Status",
91804
+ value: "Ready"
91603
91805
  },
91604
91806
  {
91605
91807
  label: "Local agents",
@@ -91613,15 +91815,20 @@ function emitSetupComplete(input) {
91613
91815
  label: "Service",
91614
91816
  value: formatSetupCompleteService(input.atsServiceRuntimeIdentity)
91615
91817
  },
91818
+ {
91819
+ label: "Local components",
91820
+ value: input.localComponents.summaryLabel
91821
+ },
91616
91822
  {
91617
91823
  label: "Next",
91618
91824
  value: nextCommands[1] ?? ""
91619
91825
  }
91620
91826
  ]
91621
91827
  });
91622
- emitHumanSetupCompleteAgentHandoff({
91623
- payload,
91624
- presenter: input.presenter
91828
+ renderSetupAgentHandoffCard({
91829
+ cliCommandPrefix,
91830
+ presenter: input.presenter,
91831
+ view: input.view
91625
91832
  });
91626
91833
  return;
91627
91834
  }
@@ -91678,33 +91885,6 @@ async function finalizeLocalComponentsSetupSnapshot() {
91678
91885
  await writeInstalledLocalComponentsSnapshot({ source: "setup" });
91679
91886
  return await resolveLocalComponentsStatus();
91680
91887
  }
91681
- function emitHumanSetupCompleteAgentHandoff(input) {
91682
- input.presenter.line({
91683
- code: "setup.complete.agent_handoff.heading",
91684
- text: "Agent handoff: setup.complete"
91685
- });
91686
- input.presenter.line({
91687
- code: "setup.complete.agent_handoff.detail",
91688
- text: "Your setup agent can read the structured block below for follow-up commands."
91689
- });
91690
- input.presenter.line({
91691
- code: "setup.complete.agent_handoff.begin",
91692
- text: "-----BEGIN ATS SETUP COMPLETE-----"
91693
- });
91694
- const envelope = {
91695
- type: "result",
91696
- code: "setup.complete",
91697
- payload: input.payload
91698
- };
91699
- for (const line of JSON.stringify(envelope, null, 2).split("\n")) input.presenter.line({
91700
- code: "setup.complete.agent_handoff.json",
91701
- text: line
91702
- });
91703
- input.presenter.line({
91704
- code: "setup.complete.agent_handoff.end",
91705
- text: "-----END ATS SETUP COMPLETE-----"
91706
- });
91707
- }
91708
91888
  function formatSetupCompleteLocalAgents(selectedLocalAgentIds) {
91709
91889
  if (selectedLocalAgentIds.length === 0) return "No local agents selected";
91710
91890
  return `${selectedLocalAgentIds.length} detected: ${selectedLocalAgentIds.join(", ")}`;
@@ -91720,6 +91900,11 @@ function formatSetupCompleteService(atsServiceRuntimeIdentity) {
91720
91900
  if (!atsServiceRuntimeIdentity) return "Not connected";
91721
91901
  return `${atsServiceRuntimeIdentity.runtimeLane} - ${shortenIdentifier(atsServiceRuntimeIdentity.deviceId)}`;
91722
91902
  }
91903
+ function formatSetupLocalAgentCandidateCount(readiness) {
91904
+ const supportedCount = readiness.agents.candidates.filter((candidate) => candidate.selectable).length;
91905
+ if (supportedCount === 0) return "No supported local agents found";
91906
+ return `${supportedCount} supported local agent${supportedCount === 1 ? "" : "s"} found`;
91907
+ }
91723
91908
  function shortenIdentifier(value) {
91724
91909
  if (value.length <= 18) return value;
91725
91910
  return `${value.slice(0, 8)}...${value.slice(-4)}`;