@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.
- package/dist/agent-bridge.js +43 -1
- package/dist/index.js +414 -39
- package/package.json +1 -1
package/dist/agent-bridge.js
CHANGED
|
@@ -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.
|
|
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
|
-
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
25426
|
+
await sleep3(1e3, abort.signal);
|
|
25338
25427
|
continue;
|
|
25339
25428
|
}
|
|
25340
|
-
await
|
|
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
|
|
25482
|
+
await sleep3(1e3, abort.signal);
|
|
25394
25483
|
continue;
|
|
25395
25484
|
}
|
|
25396
|
-
await
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
"
|
|
35540
|
+
"Review and merge the PR. Auto will wait here and detect when the onboarding agent has been applied."
|
|
35241
35541
|
);
|
|
35242
|
-
context
|
|
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
|
|
36148
|
+
new Option4("--format <format>", "output format").choices([
|
|
35774
36149
|
"text",
|
|
35775
36150
|
"json",
|
|
35776
36151
|
"stream-json",
|