@autohq/cli 0.1.164 → 0.1.166

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.
@@ -19666,6 +19666,33 @@ var RuntimeBridgeOutputAckSchema = external_exports.object({
19666
19666
  at: external_exports.string().datetime()
19667
19667
  }).strict();
19668
19668
 
19669
+ // ../../packages/schemas/src/account.ts
19670
+ var AccountDeleteRequestSchema = external_exports.object({
19671
+ deleteAdminOrganizations: external_exports.boolean().default(false),
19672
+ confirmation: external_exports.string().trim().min(1)
19673
+ });
19674
+ var AccountDeleteOrganizationSchema = external_exports.object({
19675
+ organizationId: external_exports.string().trim().min(1),
19676
+ organizationSlug: external_exports.string().trim().min(1),
19677
+ organizationName: external_exports.string().trim().min(1),
19678
+ role: external_exports.enum(["admin", "member"]),
19679
+ adminCount: external_exports.number().int().nonnegative(),
19680
+ projectCount: external_exports.number().int().nonnegative()
19681
+ });
19682
+ var AccountDeleteDeletedOrganizationSchema = AccountDeleteOrganizationSchema.extend({
19683
+ deleteReason: external_exports.enum(["last_admin", "delete_admin_orgs"])
19684
+ });
19685
+ var AccountDeleteResponseSchema = external_exports.object({
19686
+ user: external_exports.object({
19687
+ userId: external_exports.string().trim().min(1),
19688
+ primaryEmail: external_exports.string().trim().min(1)
19689
+ }),
19690
+ deletedOrganizations: external_exports.array(AccountDeleteDeletedOrganizationSchema),
19691
+ removedOrganizations: external_exports.array(AccountDeleteOrganizationSchema),
19692
+ deletedProjectCount: external_exports.number().int().nonnegative(),
19693
+ removedProjectMembershipCount: external_exports.number().int().nonnegative()
19694
+ });
19695
+
19669
19696
  // ../../packages/schemas/src/ids.ts
19670
19697
  var OpaqueIdSchema2 = external_exports.string().trim().min(1);
19671
19698
  var ProfileIdSchema = OpaqueIdSchema2.brand();
@@ -22779,6 +22806,21 @@ var SetupOnboardingPullRequestSchema = external_exports.object({
22779
22806
  var SetupOnboardingPullRequestCreateResponseSchema = external_exports.object({
22780
22807
  pullRequest: SetupOnboardingPullRequestSchema
22781
22808
  });
22809
+ var SetupOnboardingPullRequestStatusRequestSchema = external_exports.object({
22810
+ githubConnection: external_exports.string().trim().min(1).optional(),
22811
+ repo: GithubSyncRepositoryFullNameSchema,
22812
+ pullRequestNumber: external_exports.coerce.number().int().positive()
22813
+ });
22814
+ var SetupOnboardingPullRequestStatusResponseSchema = external_exports.object({
22815
+ pullRequest: external_exports.object({
22816
+ merged: external_exports.boolean(),
22817
+ state: external_exports.string().trim().min(1)
22818
+ }),
22819
+ apply: external_exports.object({
22820
+ applied: external_exports.boolean()
22821
+ }),
22822
+ ready: external_exports.boolean()
22823
+ });
22782
22824
 
22783
22825
  // ../../packages/schemas/src/runtimes.ts
22784
22826
  var RuntimeRecordSchema = external_exports.object({
@@ -26440,7 +26482,7 @@ Object.assign(lookup, {
26440
26482
  // package.json
26441
26483
  var package_default = {
26442
26484
  name: "@autohq/cli",
26443
- version: "0.1.164",
26485
+ version: "0.1.166",
26444
26486
  license: "SEE LICENSE IN README.md",
26445
26487
  publishConfig: {
26446
26488
  access: "public"
package/dist/index.js CHANGED
@@ -363,23 +363,25 @@ async function createOAuthLoopbackCallback(input) {
363
363
  );
364
364
  return;
365
365
  }
366
- const code = url2.searchParams.get("code");
367
- if (!code) {
366
+ const code = url2.searchParams.get("code") ?? "";
367
+ const sensitiveActionToken = url2.searchParams.get("sensitive_action_token") ?? void 0;
368
+ if (!code && !sensitiveActionToken) {
368
369
  response.writeHead(400, { "content-type": "text/html; charset=utf-8" });
369
370
  endThenSettle(
370
371
  response,
371
372
  renderOAuthLoopbackPage({
372
373
  status: "failure",
373
374
  eyebrow: "Auto",
374
- title: "Missing authorization code",
375
+ title: "Missing authorization result",
375
376
  message: "Return to your terminal to retry the authorization flow."
376
377
  }),
377
- () => rejectResult(new Error("Missing authorization code"))
378
+ () => rejectResult(new Error("Missing authorization result"))
378
379
  );
379
380
  return;
380
381
  }
381
382
  const result2 = {
382
383
  code,
384
+ sensitiveActionToken,
383
385
  organizationName: url2.searchParams.get("organization_name") ?? void 0,
384
386
  projectName: url2.searchParams.get("project_name") ?? void 0,
385
387
  state: url2.searchParams.get("state") ?? void 0
@@ -16060,6 +16062,40 @@ var init_zod = __esm({
16060
16062
  }
16061
16063
  });
16062
16064
 
16065
+ // ../../packages/schemas/src/account.ts
16066
+ var AccountDeleteRequestSchema, AccountDeleteOrganizationSchema, AccountDeleteDeletedOrganizationSchema, AccountDeleteResponseSchema;
16067
+ var init_account = __esm({
16068
+ "../../packages/schemas/src/account.ts"() {
16069
+ "use strict";
16070
+ init_zod();
16071
+ AccountDeleteRequestSchema = external_exports.object({
16072
+ deleteAdminOrganizations: external_exports.boolean().default(false),
16073
+ confirmation: external_exports.string().trim().min(1)
16074
+ });
16075
+ AccountDeleteOrganizationSchema = external_exports.object({
16076
+ organizationId: external_exports.string().trim().min(1),
16077
+ organizationSlug: external_exports.string().trim().min(1),
16078
+ organizationName: external_exports.string().trim().min(1),
16079
+ role: external_exports.enum(["admin", "member"]),
16080
+ adminCount: external_exports.number().int().nonnegative(),
16081
+ projectCount: external_exports.number().int().nonnegative()
16082
+ });
16083
+ AccountDeleteDeletedOrganizationSchema = AccountDeleteOrganizationSchema.extend({
16084
+ deleteReason: external_exports.enum(["last_admin", "delete_admin_orgs"])
16085
+ });
16086
+ AccountDeleteResponseSchema = external_exports.object({
16087
+ user: external_exports.object({
16088
+ userId: external_exports.string().trim().min(1),
16089
+ primaryEmail: external_exports.string().trim().min(1)
16090
+ }),
16091
+ deletedOrganizations: external_exports.array(AccountDeleteDeletedOrganizationSchema),
16092
+ removedOrganizations: external_exports.array(AccountDeleteOrganizationSchema),
16093
+ deletedProjectCount: external_exports.number().int().nonnegative(),
16094
+ removedProjectMembershipCount: external_exports.number().int().nonnegative()
16095
+ });
16096
+ }
16097
+ });
16098
+
16063
16099
  // ../../packages/schemas/src/ids.ts
16064
16100
  var OpaqueIdSchema, ProfileIdSchema, EnvironmentIdSchema, IdentityIdSchema, ConnectionIdSchema, ExternalAccountIdSchema, OrganizationIdSchema, ProjectIdSchema, ProviderGrantIdSchema, ServiceAccountIdSchema, AgentIdSchema, SessionIdSchema, SessionCommandIdSchema, RuntimeIdSchema, RuntimeBridgeLeaseIdSchema, EnvironmentSetupTemplateIdSchema, UserIdSchema;
16065
16101
  var init_ids = __esm({
@@ -19553,7 +19589,7 @@ var init_session_commands = __esm({
19553
19589
  });
19554
19590
 
19555
19591
  // ../../packages/schemas/src/setup.ts
19556
- var SetupOnboardingPullRequestCreateRequestSchema, SetupOnboardingPullRequestSchema, SetupOnboardingPullRequestCreateResponseSchema;
19592
+ var SetupOnboardingPullRequestCreateRequestSchema, SetupOnboardingPullRequestSchema, SetupOnboardingPullRequestCreateResponseSchema, SetupOnboardingPullRequestStatusRequestSchema, SetupOnboardingPullRequestStatusResponseSchema;
19557
19593
  var init_setup = __esm({
19558
19594
  "../../packages/schemas/src/setup.ts"() {
19559
19595
  "use strict";
@@ -19575,6 +19611,21 @@ var init_setup = __esm({
19575
19611
  SetupOnboardingPullRequestCreateResponseSchema = external_exports.object({
19576
19612
  pullRequest: SetupOnboardingPullRequestSchema
19577
19613
  });
19614
+ SetupOnboardingPullRequestStatusRequestSchema = external_exports.object({
19615
+ githubConnection: external_exports.string().trim().min(1).optional(),
19616
+ repo: GithubSyncRepositoryFullNameSchema,
19617
+ pullRequestNumber: external_exports.coerce.number().int().positive()
19618
+ });
19619
+ SetupOnboardingPullRequestStatusResponseSchema = external_exports.object({
19620
+ pullRequest: external_exports.object({
19621
+ merged: external_exports.boolean(),
19622
+ state: external_exports.string().trim().min(1)
19623
+ }),
19624
+ apply: external_exports.object({
19625
+ applied: external_exports.boolean()
19626
+ }),
19627
+ ready: external_exports.boolean()
19628
+ });
19578
19629
  }
19579
19630
  });
19580
19631
 
@@ -19619,6 +19670,7 @@ var init_temporal = __esm({
19619
19670
  var init_src = __esm({
19620
19671
  "../../packages/schemas/src/index.ts"() {
19621
19672
  "use strict";
19673
+ init_account();
19622
19674
  init_auth();
19623
19675
  init_chat();
19624
19676
  init_claude_code();
@@ -20603,6 +20655,26 @@ function createApiClient(input) {
20603
20655
  }
20604
20656
  return AuthWhoamiResponseSchema.parse(await response.json());
20605
20657
  },
20658
+ async deleteAccount(inputOptions) {
20659
+ const response = await bootstrapFetch(
20660
+ apiUrl(apiPath("/account"), inputOptions.apiBaseUrl),
20661
+ {
20662
+ method: "DELETE",
20663
+ headers: {
20664
+ "content-type": "application/json",
20665
+ "x-auto-sensitive-action-token": inputOptions.sensitiveActionToken
20666
+ },
20667
+ body: JSON.stringify({
20668
+ deleteAdminOrganizations: inputOptions.deleteAdminOrganizations,
20669
+ confirmation: inputOptions.confirmation
20670
+ })
20671
+ }
20672
+ );
20673
+ if (!response.ok) {
20674
+ throw new Error(await responseErrorMessage(response));
20675
+ }
20676
+ return AccountDeleteResponseSchema.parse(await response.json());
20677
+ },
20606
20678
  async listProjects(options = {}) {
20607
20679
  return fetchProjects2(options.apiBaseUrl);
20608
20680
  },
@@ -20948,6 +21020,23 @@ function createApiClient(input) {
20948
21020
  }
20949
21021
  );
20950
21022
  },
21023
+ async getSetupOnboardingPullRequestStatus(request, options = {}) {
21024
+ const project = await activeProject();
21025
+ const searchParams = [
21026
+ ["repo", request.repo],
21027
+ ["pullRequestNumber", String(request.pullRequestNumber)]
21028
+ ];
21029
+ if (request.githubConnection) {
21030
+ searchParams.push(["githubConnection", request.githubConnection]);
21031
+ }
21032
+ return requestJson(
21033
+ projectApiPath(project, "/setup/onboarding-pr"),
21034
+ {
21035
+ apiBaseUrl: options.apiBaseUrl,
21036
+ searchParams
21037
+ }
21038
+ );
21039
+ },
20951
21040
  ...createResourceApi({
20952
21041
  activeProject,
20953
21042
  apiUrl,
@@ -21492,7 +21581,7 @@ var init_package = __esm({
21492
21581
  "package.json"() {
21493
21582
  package_default = {
21494
21583
  name: "@autohq/cli",
21495
- version: "0.1.164",
21584
+ version: "0.1.166",
21496
21585
  license: "SEE LICENSE IN README.md",
21497
21586
  publishConfig: {
21498
21587
  access: "public"
@@ -25334,10 +25423,10 @@ function ConversationView({
25334
25423
  return;
25335
25424
  }
25336
25425
  setStatus("failed");
25337
- await sleep2(1e3, abort.signal);
25426
+ await sleep3(1e3, abort.signal);
25338
25427
  continue;
25339
25428
  }
25340
- await sleep2(250, abort.signal);
25429
+ await sleep3(250, abort.signal);
25341
25430
  }
25342
25431
  })();
25343
25432
  void client.getSession(sessionId, { apiBaseUrl: apiUrl }).then(applyRunSnapshot).catch(() => void 0);
@@ -25390,10 +25479,10 @@ function ConversationView({
25390
25479
  createdAt: (/* @__PURE__ */ new Date()).toISOString()
25391
25480
  })
25392
25481
  );
25393
- await sleep2(1e3, abort.signal);
25482
+ await sleep3(1e3, abort.signal);
25394
25483
  continue;
25395
25484
  }
25396
- await sleep2(250, abort.signal);
25485
+ await sleep3(250, abort.signal);
25397
25486
  }
25398
25487
  })();
25399
25488
  return () => {
@@ -25861,7 +25950,7 @@ function formatDuration(event) {
25861
25950
  }
25862
25951
  return `${(event.durationMs / 1e3).toFixed(1)}s`;
25863
25952
  }
25864
- function sleep2(ms, signal) {
25953
+ function sleep3(ms, signal) {
25865
25954
  if (signal.aborted) {
25866
25955
  return Promise.resolve();
25867
25956
  }
@@ -29449,11 +29538,12 @@ var init_launcher = __esm({
29449
29538
 
29450
29539
  // src/cli/program.ts
29451
29540
  import { existsSync as existsSync4 } from "fs";
29452
- import { Command, Option as Option3 } from "commander";
29541
+ import { Command, Option as Option4 } from "commander";
29453
29542
 
29454
29543
  // src/commands/account/commands.ts
29455
29544
  init_base_url();
29456
29545
  init_login();
29546
+ import { Option } from "commander";
29457
29547
 
29458
29548
  // src/commands/auth/profile.ts
29459
29549
  import { existsSync, rmSync } from "fs";
@@ -29754,6 +29844,210 @@ function formatScopeActions(actions) {
29754
29844
  return ordered.join("+");
29755
29845
  }
29756
29846
 
29847
+ // src/commands/account/delete.ts
29848
+ init_base_url();
29849
+ init_http();
29850
+ init_browser();
29851
+ init_file();
29852
+ init_loopback();
29853
+
29854
+ // src/lib/stdio/readline.ts
29855
+ import { createInterface } from "readline/promises";
29856
+ function createCliReadline(input) {
29857
+ return createInterface({
29858
+ input: input.stdin,
29859
+ output: input.stdout,
29860
+ terminal: Boolean(input.stdin.isTTY)
29861
+ });
29862
+ }
29863
+
29864
+ // src/commands/account/delete.ts
29865
+ async function deleteAccount(input) {
29866
+ const { context, options } = input;
29867
+ const config2 = readConfig(context.configPath);
29868
+ const confirmationTarget = config2.userEmail ?? options.confirm;
29869
+ if (!confirmationTarget) {
29870
+ throw new Error(
29871
+ "Cannot determine the account email. Re-run with --confirm <email>."
29872
+ );
29873
+ }
29874
+ const confirmation = await accountDeletionConfirmation({
29875
+ context,
29876
+ email: confirmationTarget,
29877
+ options
29878
+ });
29879
+ const apiBaseUrl = resolveApiBaseUrl({
29880
+ explicit: [options.apiUrl, context.globalApiUrl?.()],
29881
+ env: context.env,
29882
+ configServerUrl: config2.serverUrl
29883
+ });
29884
+ const sensitiveActionToken = options.sensitiveActionToken ?? (options.device ? await authorizeSensitiveActionDevice({
29885
+ context,
29886
+ apiBaseUrl
29887
+ }) : await authorizeSensitiveActionLoopback({
29888
+ context,
29889
+ apiBaseUrl,
29890
+ email: confirmationTarget
29891
+ }));
29892
+ const client = createContextApiClient(context);
29893
+ const deleted = await client.deleteAccount({
29894
+ deleteAdminOrganizations: Boolean(options.deleteAdminOrgs),
29895
+ confirmation,
29896
+ sensitiveActionToken,
29897
+ apiBaseUrl
29898
+ });
29899
+ context.writeOutput(
29900
+ context.io.style.success(`Deleted account ${deleted.user.primaryEmail}.`)
29901
+ );
29902
+ if (deleted.deletedOrganizations.length > 0) {
29903
+ context.writeOutput(
29904
+ `Deleted ${deleted.deletedOrganizations.length} organization(s) and ${deleted.deletedProjectCount} project(s).`
29905
+ );
29906
+ }
29907
+ if (deleted.removedOrganizations.length > 0) {
29908
+ context.writeOutput(
29909
+ `Removed account memberships from ${deleted.removedOrganizations.length} organization(s).`
29910
+ );
29911
+ }
29912
+ if (deleted.removedProjectMembershipCount > 0) {
29913
+ context.writeOutput(
29914
+ `Removed ${deleted.removedProjectMembershipCount} project membership(s).`
29915
+ );
29916
+ }
29917
+ logout(context);
29918
+ }
29919
+ async function accountDeletionConfirmation(input) {
29920
+ if (input.options.yes) {
29921
+ if (!input.options.confirm) {
29922
+ throw new Error(
29923
+ "Pass --confirm <email> with --yes to delete an account non-interactively."
29924
+ );
29925
+ }
29926
+ return input.options.confirm;
29927
+ }
29928
+ if (!input.context.stdin.isTTY) {
29929
+ throw new Error(
29930
+ "Account deletion requires an interactive terminal, or --yes --confirm <email>."
29931
+ );
29932
+ }
29933
+ const rl = createCliReadline({
29934
+ stdin: input.context.stdin,
29935
+ stdout: input.context.stdout
29936
+ });
29937
+ try {
29938
+ input.context.writeOutput(
29939
+ `This will permanently delete the Auto account ${input.email}.`
29940
+ );
29941
+ input.context.writeOutput(
29942
+ input.options.deleteAdminOrgs ? "Organizations where this account is an admin will be deleted, including their projects and resources." : "Organizations where this account is the last admin will be deleted; other organizations will keep their data."
29943
+ );
29944
+ input.context.writeOutput(
29945
+ "Connections, tokens, identities, and account-scoped access will be removed."
29946
+ );
29947
+ await requireYes(rl, "Delete this Auto account? Type yes to continue: ");
29948
+ await requireYes(rl, "This cannot be undone. Type yes to continue: ");
29949
+ const confirmation = input.options.confirm ?? await rl.question(`Type ${input.email} to permanently delete: `);
29950
+ if (confirmation.trim() !== input.email) {
29951
+ throw new Error(
29952
+ "Account deletion cancelled: confirmation did not match."
29953
+ );
29954
+ }
29955
+ return confirmation.trim();
29956
+ } finally {
29957
+ rl.close();
29958
+ }
29959
+ }
29960
+ async function authorizeSensitiveActionLoopback(input) {
29961
+ const callback = await createOAuthLoopbackCallback({
29962
+ successHtml: () => renderOAuthLoopbackPage({
29963
+ status: "success",
29964
+ eyebrow: "Auto CLI",
29965
+ title: "Account deletion confirmed",
29966
+ message: "Auto received the fresh browser authorization. The CLI will finish deleting the account from your terminal.",
29967
+ details: [{ label: "Account", value: input.email }]
29968
+ }),
29969
+ failureHtml: () => renderOAuthLoopbackPage({
29970
+ status: "failure",
29971
+ eyebrow: "Auto CLI",
29972
+ title: "Account deletion confirmation failed",
29973
+ message: "The browser authorization did not complete. Return to your terminal to retry or inspect the error.",
29974
+ details: [{ label: "Account", value: input.email }]
29975
+ })
29976
+ });
29977
+ try {
29978
+ const authorizeUrl = new URL("/auth/cli", input.apiBaseUrl);
29979
+ authorizeUrl.searchParams.set("purpose", "sensitive_action");
29980
+ authorizeUrl.searchParams.set("redirect_uri", callback.redirectUri);
29981
+ input.context.writeOutput(
29982
+ `Opening ${input.context.io.style.url(authorizeUrl.toString())}`
29983
+ );
29984
+ input.context.writeOutput(
29985
+ input.context.io.style.dim(
29986
+ "Log in in your browser to confirm account deletion."
29987
+ )
29988
+ );
29989
+ openBrowser(authorizeUrl.toString());
29990
+ const result = await callback.result;
29991
+ if (!result.sensitiveActionToken) {
29992
+ throw new Error("Missing sensitive action authorization token");
29993
+ }
29994
+ return result.sensitiveActionToken;
29995
+ } finally {
29996
+ callback.close();
29997
+ }
29998
+ }
29999
+ async function authorizeSensitiveActionDevice(input) {
30000
+ const device = await postJson(
30001
+ input.context.fetch,
30002
+ `${input.apiBaseUrl}/api/v1/auth/device/code`,
30003
+ {
30004
+ purpose: "sensitive_action",
30005
+ action: "account_delete"
30006
+ }
30007
+ );
30008
+ input.context.writeOutput(
30009
+ `Open ${input.context.io.style.url(device.verification_uri)} and enter ${input.context.io.style.label(
30010
+ device.user_code
30011
+ )}`
30012
+ );
30013
+ input.context.writeOutput(
30014
+ `${input.context.io.style.label("Device code:")} ${input.context.io.style.id(
30015
+ device.device_code
30016
+ )}`
30017
+ );
30018
+ const deadline = Date.now() + device.expires_in * 1e3;
30019
+ let firstAttempt = true;
30020
+ while (Date.now() < deadline) {
30021
+ if (!firstAttempt) {
30022
+ await sleep2(Math.max(0, device.interval) * 1e3);
30023
+ }
30024
+ firstAttempt = false;
30025
+ try {
30026
+ const token2 = await postJson(input.context.fetch, `${input.apiBaseUrl}/api/v1/auth/cli/token`, {
30027
+ grant_type: "urn:auto:params:oauth:grant-type:sensitive_action_device_code",
30028
+ action: "account_delete",
30029
+ device_code: device.device_code
30030
+ });
30031
+ return token2.sensitive_action_token;
30032
+ } catch (error51) {
30033
+ if (error51 instanceof Error && error51.message === "authorization_pending") {
30034
+ continue;
30035
+ }
30036
+ throw error51;
30037
+ }
30038
+ }
30039
+ throw new Error("Device authorization expired before approval.");
30040
+ }
30041
+ async function requireYes(rl, prompt) {
30042
+ const answer = await rl.question(prompt);
30043
+ if (answer.trim() !== "yes") {
30044
+ throw new Error("Account deletion cancelled.");
30045
+ }
30046
+ }
30047
+ async function sleep2(ms) {
30048
+ await new Promise((resolve3) => setTimeout(resolve3, ms));
30049
+ }
30050
+
29757
30051
  // src/commands/account/commands.ts
29758
30052
  function registerAccountCommands(program, context) {
29759
30053
  const account = program.command("account").description("Manage stored account profiles.");
@@ -29783,6 +30077,17 @@ function registerAccountCommands(program, context) {
29783
30077
  (accountRef, options) => switchAccount(context, accountRef, options)
29784
30078
  );
29785
30079
  account.command("remove").description("Remove a stored account profile.").argument("<name>", "Profile name to remove").action((name) => removeProfile(context, name));
30080
+ account.command("delete").description("Permanently delete the signed-in Auto account.").option("--api-url <url>", "Auto web server URL").option(
30081
+ "--delete-admin-orgs",
30082
+ "delete organizations where this account is an admin"
30083
+ ).option("--device", "use device authorization for fresh confirmation").option("--yes", "skip interactive yes/no prompts").option("--confirm <email>", "account email required for deletion").addOption(
30084
+ new Option(
30085
+ "--sensitive-action-token <token>",
30086
+ "fresh sensitive action authorization token"
30087
+ ).hideHelp()
30088
+ ).action(
30089
+ (options) => deleteAccount({ context, options })
30090
+ );
29786
30091
  }
29787
30092
 
29788
30093
  // src/commands/agent-bridge/git-credentials.ts
@@ -31766,16 +32071,6 @@ import { existsSync as existsSync3, mkdtempSync, writeFileSync as writeFileSync3
31766
32071
  import { homedir as homedir3, tmpdir } from "os";
31767
32072
  import { join as join4 } from "path";
31768
32073
 
31769
- // src/lib/stdio/readline.ts
31770
- import { createInterface } from "readline/promises";
31771
- function createCliReadline(input) {
31772
- return createInterface({
31773
- input: input.stdin,
31774
- output: input.stdout,
31775
- terminal: Boolean(input.stdin.isTTY)
31776
- });
31777
- }
31778
-
31779
32074
  // src/lib/stdio/secret.ts
31780
32075
  async function questionSecret(context, prompt) {
31781
32076
  const readline = createCliReadline(context);
@@ -31846,7 +32141,7 @@ async function connectAgentPresence2(input) {
31846
32141
  );
31847
32142
  return;
31848
32143
  }
31849
- const sleep3 = input.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
32144
+ const sleep4 = input.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
31850
32145
  const openBrowser2 = input.openBrowser ?? openBrowser;
31851
32146
  const now3 = input.now ?? Date.now;
31852
32147
  const pollIntervalMs = input.pollIntervalMs ?? POLL_INTERVAL_MS;
@@ -31860,7 +32155,7 @@ async function connectAgentPresence2(input) {
31860
32155
  const deadline = now3() + pollTimeoutMs;
31861
32156
  let realized = false;
31862
32157
  while (now3() < deadline) {
31863
- await sleep3(pollIntervalMs);
32158
+ await sleep4(pollIntervalMs);
31864
32159
  const presence = await input.client.getAgentPresence(
31865
32160
  { name: input.agent },
31866
32161
  options
@@ -32613,11 +32908,11 @@ async function activeGrantIds(input) {
32613
32908
  );
32614
32909
  }
32615
32910
  async function waitForNewGrant(input, knownGrantIds) {
32616
- const sleep3 = input.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
32911
+ const sleep4 = input.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms)));
32617
32912
  const now3 = input.now ?? Date.now;
32618
32913
  const deadline = now3() + (input.pollTimeoutMs ?? POLL_TIMEOUT_MS2);
32619
32914
  while (now3() < deadline) {
32620
- await sleep3(input.pollIntervalMs ?? POLL_INTERVAL_MS2);
32915
+ await sleep4(input.pollIntervalMs ?? POLL_INTERVAL_MS2);
32621
32916
  const result = await input.client.listConnections({
32622
32917
  provider: input.provider,
32623
32918
  apiBaseUrl: input.apiBaseUrl
@@ -33463,7 +33758,7 @@ function registerOnboardCommands(program, context) {
33463
33758
  }
33464
33759
 
33465
33760
  // src/commands/orgs/commands.ts
33466
- import { Option } from "commander";
33761
+ import { Option as Option2 } from "commander";
33467
33762
  function registerOrganizationCommands(program, context) {
33468
33763
  const orgs = program.command("orgs").description("Manage the active organization.");
33469
33764
  orgs.command("use").argument("<organization>").option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").description("Set the active organization.").action(
@@ -33535,7 +33830,7 @@ function registerOrganizationCommands(program, context) {
33535
33830
  }
33536
33831
  });
33537
33832
  orgs.command("invite").description("Invite a user to the active organization by email.").requiredOption("--email <email>", "Email address to invite").addOption(
33538
- new Option("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
33833
+ new Option2("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
33539
33834
  ).option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
33540
33835
  const response = await createDirectoryClient(
33541
33836
  context
@@ -33570,7 +33865,7 @@ function registerOrganizationCommands(program, context) {
33570
33865
  }
33571
33866
  });
33572
33867
  members.command("add").description("Invite a user to the active organization by email.").requiredOption("--email <email>", "Email address to invite").addOption(
33573
- new Option("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
33868
+ new Option2("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
33574
33869
  ).option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
33575
33870
  const response = await createDirectoryClient(
33576
33871
  context
@@ -33588,7 +33883,7 @@ function registerOrganizationCommands(program, context) {
33588
33883
  );
33589
33884
  });
33590
33885
  members.command("set-role").description("Set an existing active organization member's role.").requiredOption("--email <email>", "Email address of an existing member").addOption(
33591
- new Option("--role <role>", "Membership role").choices(["admin", "member"]).makeOptionMandatory()
33886
+ new Option2("--role <role>", "Membership role").choices(["admin", "member"]).makeOptionMandatory()
33592
33887
  ).option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
33593
33888
  const response = await createDirectoryClient(
33594
33889
  context
@@ -33634,7 +33929,7 @@ function memberLine(member, style) {
33634
33929
  }
33635
33930
 
33636
33931
  // src/commands/projects/commands.ts
33637
- import { Option as Option2 } from "commander";
33932
+ import { Option as Option3 } from "commander";
33638
33933
  init_active_project();
33639
33934
  init_file();
33640
33935
 
@@ -33721,7 +34016,7 @@ function registerProjectCommands(program, context) {
33721
34016
  }
33722
34017
  });
33723
34018
  projects.command("invite").description("Invite a user to the active project by email.").requiredOption("--email <email>", "Email address to invite").addOption(
33724
- new Option2("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
34019
+ new Option3("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
33725
34020
  ).option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
33726
34021
  const response = await createDirectoryClient(context).inviteProjectMember(
33727
34022
  {
@@ -33752,7 +34047,7 @@ function registerProjectCommands(program, context) {
33752
34047
  }
33753
34048
  });
33754
34049
  members.command("add").description("Invite a user to the active project by email.").requiredOption("--email <email>", "Email address to invite").addOption(
33755
- new Option2("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
34050
+ new Option3("--role <role>", "Membership role").choices(["admin", "member"]).default("member")
33756
34051
  ).option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
33757
34052
  const response = await createDirectoryClient(context).addProjectMember({
33758
34053
  email: options.email,
@@ -33768,7 +34063,7 @@ function registerProjectCommands(program, context) {
33768
34063
  );
33769
34064
  });
33770
34065
  members.command("set-role").description("Set an existing active project member's role.").requiredOption("--email <email>", "Email address of an existing member").addOption(
33771
- new Option2("--role <role>", "Membership role").choices(["admin", "member"]).makeOptionMandatory()
34066
+ new Option3("--role <role>", "Membership role").choices(["admin", "member"]).makeOptionMandatory()
33772
34067
  ).option("--api-url <url>", "Auto API base URL").option("--server <url>", "Auto web server URL").action(async (options) => {
33773
34068
  const response = await createDirectoryClient(
33774
34069
  context
@@ -35199,8 +35494,12 @@ function registerSessionCommands(program, context) {
35199
35494
  }
35200
35495
 
35201
35496
  // src/commands/setup/actions.ts
35497
+ init_browser();
35202
35498
  init_file();
35203
35499
  init_login();
35500
+ var SETUP_STATUS_POLL_INTERVAL_MS = 5e3;
35501
+ var SETUP_STATUS_HINT_EVERY_POLLS = 12;
35502
+ var SETUP_STATUS_MAX_CONSECUTIVE_ERRORS = 12;
35204
35503
  async function setupAction(context, options) {
35205
35504
  const apiBaseUrl = apiUrlFromOptions(context, options);
35206
35505
  const client = createContextApiClient(context);
@@ -35231,15 +35530,26 @@ async function setupAction(context, options) {
35231
35530
  context.writeOutput("");
35232
35531
  context.writeOutput(`Opened PR #${response.pullRequest.number}.`);
35233
35532
  if (response.pullRequest.url) {
35533
+ if (options.browser !== false) {
35534
+ (options.openBrowser ?? openBrowser)(response.pullRequest.url);
35535
+ }
35234
35536
  context.writeOutput(response.pullRequest.url);
35235
35537
  }
35236
35538
  context.writeOutput("");
35237
- context.writeOutput("Next steps:");
35238
- context.writeOutput("1. Review and merge the PR.");
35239
35539
  context.writeOutput(
35240
- "2. Wait for GitHub Sync to apply the merged `.auto` directory."
35540
+ "Review and merge the PR. Auto will wait here and detect when the onboarding agent has been applied."
35241
35541
  );
35242
- context.writeOutput("3. Tag `@auto.onboarding` in Slack to begin.");
35542
+ await waitForOnboardingReady(context, client, {
35543
+ apiBaseUrl,
35544
+ githubConnection: github.name,
35545
+ repo,
35546
+ pullRequestNumber: response.pullRequest.number,
35547
+ pollIntervalMs: options.statusPollIntervalMs,
35548
+ sleep: options.sleep
35549
+ });
35550
+ context.writeOutput("");
35551
+ context.writeOutput("Onboarding is ready.");
35552
+ context.writeOutput("Tag `@auto.onboarding` in Slack to begin.");
35243
35553
  }
35244
35554
  async function showPitchAndWait(context) {
35245
35555
  context.writeOutput(setupPitchText());
@@ -35534,6 +35844,68 @@ async function askRequired(context, question) {
35534
35844
  readline.close();
35535
35845
  }
35536
35846
  }
35847
+ async function waitForOnboardingReady(context, client, input) {
35848
+ const sleep4 = input.sleep ?? defaultSleep;
35849
+ const pollIntervalMs = input.pollIntervalMs ?? SETUP_STATUS_POLL_INTERVAL_MS;
35850
+ let reportedMerged = false;
35851
+ let reportedApplied = false;
35852
+ let pollCount = 0;
35853
+ let consecutiveStatusErrors = 0;
35854
+ for (; ; ) {
35855
+ pollCount += 1;
35856
+ const status = await client.getSetupOnboardingPullRequestStatus(
35857
+ {
35858
+ githubConnection: input.githubConnection,
35859
+ repo: input.repo,
35860
+ pullRequestNumber: input.pullRequestNumber
35861
+ },
35862
+ { apiBaseUrl: input.apiBaseUrl }
35863
+ ).catch((error51) => {
35864
+ consecutiveStatusErrors += 1;
35865
+ if (consecutiveStatusErrors === 1) {
35866
+ context.writeOutput(
35867
+ "Status check failed; retrying while the onboarding PR remains open."
35868
+ );
35869
+ }
35870
+ if (consecutiveStatusErrors >= SETUP_STATUS_MAX_CONSECUTIVE_ERRORS) {
35871
+ throw error51;
35872
+ }
35873
+ return void 0;
35874
+ });
35875
+ if (!status) {
35876
+ await sleep4(pollIntervalMs);
35877
+ continue;
35878
+ }
35879
+ consecutiveStatusErrors = 0;
35880
+ if (!status.pullRequest.merged && status.pullRequest.state === "closed") {
35881
+ throw new Error(
35882
+ "The onboarding PR was closed without being merged. Re-run `auto setup` to open it again."
35883
+ );
35884
+ }
35885
+ if (!status.pullRequest.merged && status.pullRequest.state !== "open") {
35886
+ throw new Error(
35887
+ `The onboarding PR is in unexpected state "${status.pullRequest.state}". Check the PR, then rerun \`auto setup\` if needed.`
35888
+ );
35889
+ }
35890
+ if (status.pullRequest.merged && !reportedMerged) {
35891
+ context.writeOutput("Detected PR merge.");
35892
+ reportedMerged = true;
35893
+ }
35894
+ if (status.apply.applied && !reportedApplied) {
35895
+ context.writeOutput("Detected GitHub Sync apply.");
35896
+ reportedApplied = true;
35897
+ }
35898
+ if (status.ready) {
35899
+ return;
35900
+ }
35901
+ if (pollCount % SETUP_STATUS_HINT_EVERY_POLLS === 0) {
35902
+ context.writeOutput(
35903
+ status.pullRequest.merged ? "Still waiting for GitHub Sync to apply the onboarding agent..." : "Still waiting for the onboarding PR to be merged..."
35904
+ );
35905
+ }
35906
+ await sleep4(pollIntervalMs);
35907
+ }
35908
+ }
35537
35909
  function organizationLabel(organization) {
35538
35910
  return `${organization.organizationName} (${organization.organizationSlug})`;
35539
35911
  }
@@ -35543,6 +35915,9 @@ function isRecord3(value) {
35543
35915
  function isDefined(value) {
35544
35916
  return value !== void 0;
35545
35917
  }
35918
+ function defaultSleep(delayMs) {
35919
+ return new Promise((resolve3) => setTimeout(resolve3, delayMs));
35920
+ }
35546
35921
 
35547
35922
  // src/commands/setup/commands.ts
35548
35923
  function registerSetupCommands(program, context) {
@@ -35770,7 +36145,7 @@ function createProgram(options = {}) {
35770
36145
  const program = new Command();
35771
36146
  context.globalApiUrl = () => program.opts().apiUrl;
35772
36147
  program.name("auto").description("Auto CLI.").version(cliVersion).addOption(
35773
- new Option3("--format <format>", "output format").choices([
36148
+ new Option4("--format <format>", "output format").choices([
35774
36149
  "text",
35775
36150
  "json",
35776
36151
  "stream-json",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.164",
3
+ "version": "0.1.166",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"