@autohq/cli 0.1.158 → 0.1.160

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.
@@ -20829,6 +20829,61 @@ var GithubSyncBindingCreateResponseSchema = external_exports.object({
20829
20829
  var GithubSyncBindingListResponseSchema = external_exports.object({
20830
20830
  bindings: external_exports.array(GithubSyncBindingSchema)
20831
20831
  });
20832
+ var GithubSyncWorkflowInputSchema = external_exports.discriminatedUnion("kind", [
20833
+ external_exports.object({
20834
+ kind: external_exports.literal("pull_request"),
20835
+ bindingId: external_exports.string().trim().min(1),
20836
+ organizationId: OrganizationIdSchema,
20837
+ projectId: ProjectIdSchema,
20838
+ providerGrantId: ProviderGrantIdSchema,
20839
+ installationId: external_exports.string().trim().min(1),
20840
+ repoFullName: GithubSyncRepositoryFullNameSchema,
20841
+ repoId: external_exports.string().trim().min(1).optional(),
20842
+ productionBranch: GithubSyncProductionBranchSchema,
20843
+ autoPath: external_exports.literal(GITHUB_SYNC_AUTO_PATH),
20844
+ pullRequestNumber: external_exports.number().int().positive(),
20845
+ headSha: external_exports.string().trim().min(1),
20846
+ baseSha: external_exports.string().trim().min(1).optional(),
20847
+ baseRef: GithubSyncProductionBranchSchema
20848
+ }),
20849
+ external_exports.object({
20850
+ kind: external_exports.literal("push"),
20851
+ bindingId: external_exports.string().trim().min(1),
20852
+ organizationId: OrganizationIdSchema,
20853
+ projectId: ProjectIdSchema,
20854
+ providerGrantId: ProviderGrantIdSchema,
20855
+ installationId: external_exports.string().trim().min(1),
20856
+ repoFullName: GithubSyncRepositoryFullNameSchema,
20857
+ repoId: external_exports.string().trim().min(1).optional(),
20858
+ productionBranch: GithubSyncProductionBranchSchema,
20859
+ autoPath: external_exports.literal(GITHUB_SYNC_AUTO_PATH),
20860
+ ref: external_exports.string().trim().min(1),
20861
+ branch: GithubSyncProductionBranchSchema,
20862
+ before: external_exports.string().trim().min(1).optional(),
20863
+ after: external_exports.string().trim().min(1)
20864
+ })
20865
+ ]);
20866
+ var GithubSyncWorkflowResultSchema = external_exports.discriminatedUnion("status", [
20867
+ external_exports.object({
20868
+ status: external_exports.literal("skipped"),
20869
+ reason: external_exports.string().trim().min(1)
20870
+ }),
20871
+ external_exports.object({
20872
+ status: external_exports.literal("planned"),
20873
+ changed: external_exports.boolean(),
20874
+ checkRunId: external_exports.number().int().positive().optional()
20875
+ }),
20876
+ external_exports.object({
20877
+ status: external_exports.literal("applied"),
20878
+ changed: external_exports.boolean(),
20879
+ checkRunId: external_exports.number().int().positive().optional()
20880
+ }),
20881
+ external_exports.object({
20882
+ status: external_exports.literal("failed"),
20883
+ message: external_exports.string().trim().min(1),
20884
+ checkRunId: external_exports.number().int().positive().optional()
20885
+ })
20886
+ ]);
20832
20887
 
20833
20888
  // ../../packages/schemas/src/github-credentials.ts
20834
20889
  var CreateRunGithubCredentialRequestSchema = external_exports.object({
@@ -22702,27 +22757,11 @@ var SessionDispatchCommandRecordSchema = external_exports.discriminatedUnion("ki
22702
22757
  ]);
22703
22758
 
22704
22759
  // ../../packages/schemas/src/setup.ts
22705
- var SetupPullRequestFilePathSchema = external_exports.string().trim().min(1).max(255).refine((path2) => !path2.startsWith("/") && !path2.includes(".."), {
22706
- message: "file path must be relative and must not contain .."
22707
- });
22708
- var SetupPullRequestFileSchema = external_exports.object({
22709
- path: SetupPullRequestFilePathSchema,
22710
- content: external_exports.string().min(1).max(256e3)
22711
- });
22712
22760
  var SetupOnboardingPullRequestCreateRequestSchema = external_exports.object({
22713
22761
  githubConnection: external_exports.string().trim().min(1).optional(),
22714
22762
  slackConnection: external_exports.string().trim().min(1).optional(),
22715
22763
  repo: GithubSyncRepositoryFullNameSchema,
22716
- baseBranch: GithubSyncProductionBranchSchema.optional(),
22717
- branchName: GithubSyncProductionBranchSchema.default("auto/setup-onboarding"),
22718
- title: external_exports.string().trim().min(1).max(200).default("Add Auto onboarding agent"),
22719
- body: external_exports.string().trim().max(1e4).optional(),
22720
- files: external_exports.array(SetupPullRequestFileSchema).min(1).max(5).refine(
22721
- (files) => files.some((file2) => file2.path === ".auto/agents/onboarding.yaml"),
22722
- {
22723
- message: "files must include .auto/agents/onboarding.yaml"
22724
- }
22725
- )
22764
+ baseBranch: GithubSyncProductionBranchSchema.optional()
22726
22765
  });
22727
22766
  var SetupOnboardingPullRequestSchema = external_exports.object({
22728
22767
  number: external_exports.number().int().positive(),
@@ -26395,7 +26434,7 @@ Object.assign(lookup, {
26395
26434
  // package.json
26396
26435
  var package_default = {
26397
26436
  name: "@autohq/cli",
26398
- version: "0.1.158",
26437
+ version: "0.1.160",
26399
26438
  license: "SEE LICENSE IN README.md",
26400
26439
  publishConfig: {
26401
26440
  access: "public"
package/dist/index.js CHANGED
@@ -17348,7 +17348,7 @@ var init_connections = __esm({
17348
17348
  });
17349
17349
 
17350
17350
  // ../../packages/schemas/src/github-sync.ts
17351
- var GITHUB_SYNC_AUTO_PATH, GithubSyncRepositoryFullNameSchema, GithubSyncProductionBranchSchema, GithubSyncBindingSchema, GithubSyncBindingCreateRequestSchema, GithubSyncBindingCreateResponseSchema, GithubSyncBindingListResponseSchema;
17351
+ var GITHUB_SYNC_AUTO_PATH, GithubSyncRepositoryFullNameSchema, GithubSyncProductionBranchSchema, GithubSyncBindingSchema, GithubSyncBindingCreateRequestSchema, GithubSyncBindingCreateResponseSchema, GithubSyncBindingListResponseSchema, GithubSyncWorkflowInputSchema, GithubSyncWorkflowResultSchema;
17352
17352
  var init_github_sync = __esm({
17353
17353
  "../../packages/schemas/src/github-sync.ts"() {
17354
17354
  "use strict";
@@ -17390,6 +17390,61 @@ var init_github_sync = __esm({
17390
17390
  GithubSyncBindingListResponseSchema = external_exports.object({
17391
17391
  bindings: external_exports.array(GithubSyncBindingSchema)
17392
17392
  });
17393
+ GithubSyncWorkflowInputSchema = external_exports.discriminatedUnion("kind", [
17394
+ external_exports.object({
17395
+ kind: external_exports.literal("pull_request"),
17396
+ bindingId: external_exports.string().trim().min(1),
17397
+ organizationId: OrganizationIdSchema,
17398
+ projectId: ProjectIdSchema,
17399
+ providerGrantId: ProviderGrantIdSchema,
17400
+ installationId: external_exports.string().trim().min(1),
17401
+ repoFullName: GithubSyncRepositoryFullNameSchema,
17402
+ repoId: external_exports.string().trim().min(1).optional(),
17403
+ productionBranch: GithubSyncProductionBranchSchema,
17404
+ autoPath: external_exports.literal(GITHUB_SYNC_AUTO_PATH),
17405
+ pullRequestNumber: external_exports.number().int().positive(),
17406
+ headSha: external_exports.string().trim().min(1),
17407
+ baseSha: external_exports.string().trim().min(1).optional(),
17408
+ baseRef: GithubSyncProductionBranchSchema
17409
+ }),
17410
+ external_exports.object({
17411
+ kind: external_exports.literal("push"),
17412
+ bindingId: external_exports.string().trim().min(1),
17413
+ organizationId: OrganizationIdSchema,
17414
+ projectId: ProjectIdSchema,
17415
+ providerGrantId: ProviderGrantIdSchema,
17416
+ installationId: external_exports.string().trim().min(1),
17417
+ repoFullName: GithubSyncRepositoryFullNameSchema,
17418
+ repoId: external_exports.string().trim().min(1).optional(),
17419
+ productionBranch: GithubSyncProductionBranchSchema,
17420
+ autoPath: external_exports.literal(GITHUB_SYNC_AUTO_PATH),
17421
+ ref: external_exports.string().trim().min(1),
17422
+ branch: GithubSyncProductionBranchSchema,
17423
+ before: external_exports.string().trim().min(1).optional(),
17424
+ after: external_exports.string().trim().min(1)
17425
+ })
17426
+ ]);
17427
+ GithubSyncWorkflowResultSchema = external_exports.discriminatedUnion("status", [
17428
+ external_exports.object({
17429
+ status: external_exports.literal("skipped"),
17430
+ reason: external_exports.string().trim().min(1)
17431
+ }),
17432
+ external_exports.object({
17433
+ status: external_exports.literal("planned"),
17434
+ changed: external_exports.boolean(),
17435
+ checkRunId: external_exports.number().int().positive().optional()
17436
+ }),
17437
+ external_exports.object({
17438
+ status: external_exports.literal("applied"),
17439
+ changed: external_exports.boolean(),
17440
+ checkRunId: external_exports.number().int().positive().optional()
17441
+ }),
17442
+ external_exports.object({
17443
+ status: external_exports.literal("failed"),
17444
+ message: external_exports.string().trim().min(1),
17445
+ checkRunId: external_exports.number().int().positive().optional()
17446
+ })
17447
+ ]);
17393
17448
  }
17394
17449
  });
17395
17450
 
@@ -19492,33 +19547,17 @@ var init_session_commands = __esm({
19492
19547
  });
19493
19548
 
19494
19549
  // ../../packages/schemas/src/setup.ts
19495
- var SetupPullRequestFilePathSchema, SetupPullRequestFileSchema, SetupOnboardingPullRequestCreateRequestSchema, SetupOnboardingPullRequestSchema, SetupOnboardingPullRequestCreateResponseSchema;
19550
+ var SetupOnboardingPullRequestCreateRequestSchema, SetupOnboardingPullRequestSchema, SetupOnboardingPullRequestCreateResponseSchema;
19496
19551
  var init_setup = __esm({
19497
19552
  "../../packages/schemas/src/setup.ts"() {
19498
19553
  "use strict";
19499
19554
  init_zod();
19500
19555
  init_github_sync();
19501
- SetupPullRequestFilePathSchema = external_exports.string().trim().min(1).max(255).refine((path2) => !path2.startsWith("/") && !path2.includes(".."), {
19502
- message: "file path must be relative and must not contain .."
19503
- });
19504
- SetupPullRequestFileSchema = external_exports.object({
19505
- path: SetupPullRequestFilePathSchema,
19506
- content: external_exports.string().min(1).max(256e3)
19507
- });
19508
19556
  SetupOnboardingPullRequestCreateRequestSchema = external_exports.object({
19509
19557
  githubConnection: external_exports.string().trim().min(1).optional(),
19510
19558
  slackConnection: external_exports.string().trim().min(1).optional(),
19511
19559
  repo: GithubSyncRepositoryFullNameSchema,
19512
- baseBranch: GithubSyncProductionBranchSchema.optional(),
19513
- branchName: GithubSyncProductionBranchSchema.default("auto/setup-onboarding"),
19514
- title: external_exports.string().trim().min(1).max(200).default("Add Auto onboarding agent"),
19515
- body: external_exports.string().trim().max(1e4).optional(),
19516
- files: external_exports.array(SetupPullRequestFileSchema).min(1).max(5).refine(
19517
- (files) => files.some((file2) => file2.path === ".auto/agents/onboarding.yaml"),
19518
- {
19519
- message: "files must include .auto/agents/onboarding.yaml"
19520
- }
19521
- )
19560
+ baseBranch: GithubSyncProductionBranchSchema.optional()
19522
19561
  });
19523
19562
  SetupOnboardingPullRequestSchema = external_exports.object({
19524
19563
  number: external_exports.number().int().positive(),
@@ -20873,6 +20912,17 @@ function createApiClient(input) {
20873
20912
  }
20874
20913
  return GithubSyncBindingListResponseSchema.parse(await response.json());
20875
20914
  },
20915
+ async createSetupOnboardingPullRequest(request, options = {}) {
20916
+ const project = await activeProject();
20917
+ return requestJson(
20918
+ projectApiPath(project, "/setup/onboarding-pr"),
20919
+ {
20920
+ method: "POST",
20921
+ apiBaseUrl: options.apiBaseUrl,
20922
+ body: request
20923
+ }
20924
+ );
20925
+ },
20876
20926
  ...createResourceApi({
20877
20927
  activeProject,
20878
20928
  apiUrl,
@@ -21417,7 +21467,7 @@ var init_package = __esm({
21417
21467
  "package.json"() {
21418
21468
  package_default = {
21419
21469
  name: "@autohq/cli",
21420
- version: "0.1.158",
21470
+ version: "0.1.160",
21421
21471
  license: "SEE LICENSE IN README.md",
21422
21472
  publishConfig: {
21423
21473
  access: "public"
@@ -35123,6 +35173,359 @@ function registerSessionCommands(program, context) {
35123
35173
  );
35124
35174
  }
35125
35175
 
35176
+ // src/commands/setup/actions.ts
35177
+ init_file();
35178
+ init_login();
35179
+ async function setupAction(context, options) {
35180
+ const apiBaseUrl = apiUrlFromOptions(context, options);
35181
+ const client = createContextApiClient(context);
35182
+ await showPitchAndWait(context);
35183
+ await ensureAuthenticated(context, options, apiBaseUrl);
35184
+ const project = await selectProject(context, apiBaseUrl);
35185
+ const github = await selectGithubConnection(context, options, apiBaseUrl);
35186
+ await client.allowConnection("github", project.projectId, {
35187
+ connection: github.name,
35188
+ apiBaseUrl
35189
+ });
35190
+ const repo = await selectRepository(context, github, options.repo);
35191
+ const slack = await selectSlackConnection(context, options, apiBaseUrl);
35192
+ await client.allowConnection("slack", project.projectId, {
35193
+ connection: slack.name,
35194
+ apiBaseUrl
35195
+ });
35196
+ context.writeOutput("");
35197
+ context.writeOutput("Opening the onboarding PR...");
35198
+ const response = await client.createSetupOnboardingPullRequest(
35199
+ {
35200
+ githubConnection: github.name,
35201
+ slackConnection: slack.name,
35202
+ repo
35203
+ },
35204
+ { apiBaseUrl }
35205
+ );
35206
+ context.writeOutput("");
35207
+ context.writeOutput(`Opened PR #${response.pullRequest.number}.`);
35208
+ if (response.pullRequest.url) {
35209
+ context.writeOutput(response.pullRequest.url);
35210
+ }
35211
+ context.writeOutput("");
35212
+ context.writeOutput("Next steps:");
35213
+ context.writeOutput("1. Review and merge the PR.");
35214
+ context.writeOutput(
35215
+ "2. Wait for GitHub Sync to apply the merged `.auto` directory."
35216
+ );
35217
+ context.writeOutput("3. Tag `@auto.onboarding` in Slack to begin.");
35218
+ }
35219
+ async function showPitchAndWait(context) {
35220
+ context.writeOutput(setupPitchText());
35221
+ if (!context.io.canPrompt()) {
35222
+ throw new Error("`auto setup` requires an interactive terminal.");
35223
+ }
35224
+ const readline = createCliReadline({
35225
+ stdin: context.stdin,
35226
+ stdout: context.stdout
35227
+ });
35228
+ try {
35229
+ await readline.question("Press Enter to continue with setup.");
35230
+ } finally {
35231
+ readline.close();
35232
+ }
35233
+ }
35234
+ async function ensureAuthenticated(context, options, apiBaseUrl) {
35235
+ const config2 = readConfig(context.configPath);
35236
+ if (context.env.AUTO_API_TOKEN?.trim() || context.env.AUTO_DEV_USER_ID?.trim() || config2.refreshToken) {
35237
+ return;
35238
+ }
35239
+ context.writeOutput("");
35240
+ context.writeOutput("First, sign in to Auto.");
35241
+ const useDeviceLogin = options.device || options.browser === false;
35242
+ context.writeOutput(
35243
+ useDeviceLogin ? "Starting device login." : "Heads-up: this opens your browser for Auto login and prints the URL as a fallback."
35244
+ );
35245
+ await login({
35246
+ options: {
35247
+ apiUrl: apiBaseUrl,
35248
+ device: useDeviceLogin
35249
+ },
35250
+ env: context.env,
35251
+ fetch: context.fetch,
35252
+ configPath: context.configPath,
35253
+ writeOutput: context.writeOutput,
35254
+ writeError: context.writeError,
35255
+ style: context.io.style
35256
+ });
35257
+ }
35258
+ async function selectProject(context, apiBaseUrl) {
35259
+ const client = createContextApiClient(context);
35260
+ const active = await client.resolveActiveSelection();
35261
+ const projects = (await client.listProjects({ apiBaseUrl })).projects;
35262
+ const activeProject = projects.find(
35263
+ (project) => project.projectId === active.projectId
35264
+ );
35265
+ if (activeProject) {
35266
+ context.writeOutput(
35267
+ `Using active project ${activeProject.organizationName}/${activeProject.projectName}.`
35268
+ );
35269
+ return activeProject;
35270
+ }
35271
+ if (projects.length === 1) {
35272
+ const project = projects[0];
35273
+ setActiveProject(context, {
35274
+ organizationId: project.organizationId,
35275
+ projectId: project.projectId
35276
+ });
35277
+ context.writeOutput(
35278
+ `Using project ${project.organizationName}/${project.projectName}.`
35279
+ );
35280
+ return project;
35281
+ }
35282
+ if (projects.length > 1) {
35283
+ const selected = await chooseFromList(context, {
35284
+ label: "project",
35285
+ items: projects,
35286
+ render: (project) => `${project.organizationName}/${project.projectName} (${project.projectSlug})`
35287
+ });
35288
+ setActiveProject(context, {
35289
+ organizationId: selected.organizationId,
35290
+ projectId: selected.projectId
35291
+ });
35292
+ return selected;
35293
+ }
35294
+ return createInitialProject(context, apiBaseUrl);
35295
+ }
35296
+ async function createInitialProject(context, apiBaseUrl) {
35297
+ const client = createContextApiClient(context);
35298
+ const organizations = (await client.listOrganizations({ apiBaseUrl })).organizations;
35299
+ if (organizations.length === 0) {
35300
+ const organizationName = await askRequired(context, "Organization name: ");
35301
+ const projectName2 = await askRequired(context, "Project name: ");
35302
+ const created2 = await client.createOrganization({
35303
+ organizationName,
35304
+ projectName: projectName2,
35305
+ apiBaseUrl
35306
+ });
35307
+ if (!created2.project) {
35308
+ throw new Error("Organization was created without a project.");
35309
+ }
35310
+ setActiveProject(context, {
35311
+ organizationId: created2.project.organizationId,
35312
+ projectId: created2.project.projectId
35313
+ });
35314
+ return created2.project;
35315
+ }
35316
+ const organization = organizations.length === 1 ? organizations[0] : await chooseFromList(context, {
35317
+ label: "organization",
35318
+ items: organizations,
35319
+ render: organizationLabel
35320
+ });
35321
+ setActiveOrganization(context, organization.organizationId);
35322
+ const projectName = await askRequired(context, "Project name: ");
35323
+ const created = await client.createProject({ projectName, apiBaseUrl });
35324
+ setActiveProject(context, {
35325
+ organizationId: created.project.organizationId,
35326
+ projectId: created.project.projectId
35327
+ });
35328
+ return created.project;
35329
+ }
35330
+ async function selectGithubConnection(context, options, apiBaseUrl) {
35331
+ const existing = await activeConnections(context, "github", apiBaseUrl);
35332
+ if (existing.length === 0) {
35333
+ context.writeOutput("");
35334
+ context.writeOutput(
35335
+ "Next, connect GitHub. Heads-up: this opens your browser to install or authorize the GitHub App."
35336
+ );
35337
+ await connectProviderAction(context, "github", {
35338
+ apiBaseUrl,
35339
+ browser: options.browser,
35340
+ wait: true
35341
+ });
35342
+ return requireSingleConnection(context, "github", apiBaseUrl);
35343
+ }
35344
+ const selected = await selectConnection(context, {
35345
+ provider: "GitHub",
35346
+ selector: options.githubConnection,
35347
+ connections: existing
35348
+ });
35349
+ context.writeOutput(`Using GitHub connection ${selected.name}.`);
35350
+ return selected;
35351
+ }
35352
+ async function selectSlackConnection(context, options, apiBaseUrl) {
35353
+ const existing = await activeConnections(context, "slack", apiBaseUrl);
35354
+ if (existing.length === 0) {
35355
+ context.writeOutput("");
35356
+ context.writeOutput(
35357
+ "Now connect Slack. Heads-up: this opens your browser for Slack OAuth."
35358
+ );
35359
+ await connectProviderAction(context, "slack", {
35360
+ apiBaseUrl,
35361
+ browser: options.browser,
35362
+ wait: true
35363
+ });
35364
+ return requireSingleConnection(context, "slack", apiBaseUrl);
35365
+ }
35366
+ const selected = await selectConnection(context, {
35367
+ provider: "Slack",
35368
+ selector: options.slackConnection,
35369
+ connections: existing
35370
+ });
35371
+ context.writeOutput(`Using Slack connection ${selected.name}.`);
35372
+ return selected;
35373
+ }
35374
+ async function selectRepository(context, github, explicitRepo) {
35375
+ if (explicitRepo) {
35376
+ return explicitRepo;
35377
+ }
35378
+ const selection = github.grant.providerResourceSelection;
35379
+ if (selection.kind === "selected") {
35380
+ const repos = selection.resources.map(
35381
+ (resource) => isRecord3(resource) && typeof resource.fullName === "string" ? resource.fullName : void 0
35382
+ ).filter(isDefined);
35383
+ if (repos.length === 1) {
35384
+ context.writeOutput(`Using GitHub repository ${repos[0]}.`);
35385
+ return repos[0];
35386
+ }
35387
+ if (repos.length > 1) {
35388
+ return chooseFromList(context, {
35389
+ label: "repository",
35390
+ items: repos,
35391
+ render: (repo) => repo
35392
+ });
35393
+ }
35394
+ }
35395
+ return askRequired(
35396
+ context,
35397
+ "GitHub repository to install Auto in (owner/repo): "
35398
+ );
35399
+ }
35400
+ function setupPitchText() {
35401
+ return [
35402
+ "auto lets you program software factories the same way you program CI/CD.",
35403
+ "",
35404
+ "Compose agents and triggers into workflows using simple YAML files, and deploy them into the cloud on merge.",
35405
+ "",
35406
+ "Simple workflows you can build with auto:",
35407
+ "- Ticket / feedback triage and resolution",
35408
+ "- Automated incident / bug response",
35409
+ "- Custom tailored code review agents",
35410
+ "",
35411
+ "Frontier workflows auto can help you explore:",
35412
+ "- Organized fleets of agents on long-horizon tasks",
35413
+ "- Multi-agent autoresearch / optimization loops",
35414
+ "- Agentic BDR and outbound lead engines",
35415
+ "- More ideas we have not dreamed up yet",
35416
+ "",
35417
+ "Before you continue, have two things ready:",
35418
+ "1. A GitHub repository where Auto can add a `.auto/` directory.",
35419
+ "2. A Slack workspace where Auto can install its Slack connection.",
35420
+ "",
35421
+ "If you do not already have a repo and Slack workspace ready to go, create them before continuing.",
35422
+ "",
35423
+ "Auto is in early alpha, and you are one of the very first users. If anything feels confusing, breaks, or sparks an idea, please tell us. That feedback directly shapes the product.",
35424
+ ""
35425
+ ].join("\n");
35426
+ }
35427
+ async function activeConnections(context, provider, apiBaseUrl) {
35428
+ const response = await createContextApiClient(context).listConnections({
35429
+ provider,
35430
+ apiBaseUrl
35431
+ });
35432
+ return response.connections.flatMap(
35433
+ (connection) => activeGrants(connection).map((grant) => ({ name: grant.name, grant }))
35434
+ );
35435
+ }
35436
+ function activeGrants(connection) {
35437
+ return connection.grants.filter((grant) => grant.status === "active");
35438
+ }
35439
+ async function requireSingleConnection(context, provider, apiBaseUrl) {
35440
+ const connections = await activeConnections(context, provider, apiBaseUrl);
35441
+ if (connections.length === 0) {
35442
+ throw new Error(`No active ${provider} connection found after setup.`);
35443
+ }
35444
+ if (connections.length > 1) {
35445
+ return chooseFromList(context, {
35446
+ label: `${provider} connection`,
35447
+ items: connections,
35448
+ render: (connection) => connection.name
35449
+ });
35450
+ }
35451
+ return connections[0];
35452
+ }
35453
+ async function selectConnection(context, input) {
35454
+ if (input.selector) {
35455
+ const selected = input.connections.find(
35456
+ (connection) => connection.name === input.selector || connection.grant.id === input.selector
35457
+ );
35458
+ if (!selected) {
35459
+ throw new Error(
35460
+ `No ${input.provider} connection matched ${input.selector}.`
35461
+ );
35462
+ }
35463
+ return selected;
35464
+ }
35465
+ if (input.connections.length === 1) {
35466
+ return input.connections[0];
35467
+ }
35468
+ context.writeOutput(`Existing ${input.provider} connections:`);
35469
+ return chooseFromList(context, {
35470
+ label: `${input.provider} connection`,
35471
+ items: input.connections,
35472
+ render: (connection) => connectionLabel(connection)
35473
+ });
35474
+ }
35475
+ function connectionLabel(connection) {
35476
+ const selection = connection.grant.providerResourceSelection;
35477
+ const scope = selection.kind === "all" ? "all resources" : `${selection.resources.length} selected resources`;
35478
+ return `${connection.name} (${scope})`;
35479
+ }
35480
+ async function chooseFromList(context, input) {
35481
+ if (!context.io.canPrompt()) {
35482
+ throw new Error(`Multiple ${input.label}s found; rerun with a flag.`);
35483
+ }
35484
+ for (const [index2, item] of input.items.entries()) {
35485
+ context.writeOutput(`${index2 + 1}. ${input.render(item)}`);
35486
+ }
35487
+ const answer = await askRequired(context, `Select ${input.label}: `);
35488
+ const index = Number.parseInt(answer, 10) - 1;
35489
+ if (!Number.isInteger(index) || index < 0 || index >= input.items.length) {
35490
+ throw new Error(`Invalid ${input.label} selection: ${answer}`);
35491
+ }
35492
+ return input.items[index];
35493
+ }
35494
+ async function askRequired(context, question) {
35495
+ if (!context.io.canPrompt()) {
35496
+ throw new Error(`Cannot prompt for ${question.trim()}`);
35497
+ }
35498
+ const readline = createCliReadline({
35499
+ stdin: context.stdin,
35500
+ stdout: context.stdout
35501
+ });
35502
+ try {
35503
+ const answer = (await readline.question(question)).trim();
35504
+ if (!answer) {
35505
+ throw new Error("A non-empty answer is required.");
35506
+ }
35507
+ return answer;
35508
+ } finally {
35509
+ readline.close();
35510
+ }
35511
+ }
35512
+ function organizationLabel(organization) {
35513
+ return `${organization.organizationName} (${organization.organizationSlug})`;
35514
+ }
35515
+ function isRecord3(value) {
35516
+ return typeof value === "object" && value !== null && !Array.isArray(value);
35517
+ }
35518
+ function isDefined(value) {
35519
+ return value !== void 0;
35520
+ }
35521
+
35522
+ // src/commands/setup/commands.ts
35523
+ function registerSetupCommands(program, context) {
35524
+ program.command("setup").description("Launch the interactive first-run setup wizard.").option("--device", "use device authorization for Auto login").option("--no-browser", "do not open authorization URLs in a browser").option("--github-connection <name>", "GitHub connection name or id").option("--repo <owner/repo>", "GitHub repository to install Auto in").option("--slack-connection <name>", "Slack connection name or id").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (options) => {
35525
+ await setupAction(context, options);
35526
+ });
35527
+ }
35528
+
35126
35529
  // src/commands/sync/repo.ts
35127
35530
  import { execFile as execFileWithCallback } from "child_process";
35128
35531
  import { promisify } from "util";
@@ -35418,6 +35821,7 @@ function createProgram(options = {}) {
35418
35821
  registerProjectCommands(program, context);
35419
35822
  registerConnectionCommands(program, context);
35420
35823
  registerSecretCommands(program, context);
35824
+ registerSetupCommands(program, context);
35421
35825
  registerSyncCommands(program, context);
35422
35826
  registerAgentCommands(program, context);
35423
35827
  registerSessionCommands(program, context);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.158",
3
+ "version": "0.1.160",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"