@barekey/cli 0.4.0 → 0.5.1

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.
Files changed (60) hide show
  1. package/README.md +53 -12
  2. package/bun.lock +9 -3
  3. package/dist/auth-provider.js +7 -4
  4. package/dist/command-utils.js +6 -6
  5. package/dist/commands/audit.d.ts +2 -0
  6. package/dist/commands/audit.js +47 -0
  7. package/dist/commands/auth.js +31 -9
  8. package/dist/commands/billing.d.ts +2 -0
  9. package/dist/commands/billing.js +59 -0
  10. package/dist/commands/env.js +157 -125
  11. package/dist/commands/init.d.ts +2 -0
  12. package/dist/commands/init.js +32 -0
  13. package/dist/commands/org.d.ts +2 -0
  14. package/dist/commands/org.js +85 -0
  15. package/dist/commands/project.d.ts +2 -0
  16. package/dist/commands/project.js +99 -0
  17. package/dist/commands/stage.d.ts +2 -0
  18. package/dist/commands/stage.js +125 -0
  19. package/dist/commands/target-prompts.d.ts +184 -0
  20. package/dist/commands/target-prompts.js +312 -0
  21. package/dist/commands/typegen.d.ts +2 -2
  22. package/dist/commands/typegen.js +57 -32
  23. package/dist/constants.d.ts +1 -1
  24. package/dist/constants.js +1 -1
  25. package/dist/context/session-id.d.ts +11 -0
  26. package/dist/context/session-id.js +14 -0
  27. package/dist/contracts/index.d.ts +499 -0
  28. package/dist/contracts/index.js +313 -0
  29. package/dist/credentials-store.js +70 -11
  30. package/dist/http.d.ts +34 -0
  31. package/dist/http.js +56 -2
  32. package/dist/index.js +12 -0
  33. package/dist/runtime-config.js +14 -26
  34. package/dist/typegen/core.d.ts +45 -0
  35. package/dist/typegen/core.js +219 -0
  36. package/dist/types.d.ts +5 -3
  37. package/package.json +2 -2
  38. package/src/auth-provider.ts +8 -5
  39. package/src/command-utils.ts +6 -6
  40. package/src/commands/audit.ts +63 -0
  41. package/src/commands/auth.ts +45 -39
  42. package/src/commands/billing.ts +70 -0
  43. package/src/commands/env.ts +211 -218
  44. package/src/commands/init.ts +47 -0
  45. package/src/commands/org.ts +104 -0
  46. package/src/commands/project.ts +130 -0
  47. package/src/commands/stage.ts +167 -0
  48. package/src/commands/target-prompts.ts +357 -0
  49. package/src/commands/typegen.ts +71 -45
  50. package/src/constants.ts +1 -1
  51. package/src/context/session-id.ts +14 -0
  52. package/src/contracts/index.ts +376 -0
  53. package/src/credentials-store.ts +86 -12
  54. package/src/http.ts +78 -2
  55. package/src/index.ts +12 -0
  56. package/src/runtime-config.ts +19 -32
  57. package/src/typegen/core.ts +311 -0
  58. package/src/types.ts +5 -3
  59. package/test/command-utils.test.ts +47 -0
  60. package/test/credentials-store.test.ts +40 -0
@@ -0,0 +1,125 @@
1
+ import { cancel, confirm, isCancel, text } from "@clack/prompts";
2
+ import { toJsonOutput } from "../command-utils.js";
3
+ import { createStageForProject, deleteStageForProject, listStagesForProject, promptForOrganizationSlug, promptForProjectSlug, promptForStageSlug, renameStageForProject, } from "./target-prompts.js";
4
+ async function promptForStageName(name) {
5
+ const existing = name?.trim();
6
+ if (existing && existing.length > 0) {
7
+ return existing;
8
+ }
9
+ if (!process.stdout.isTTY) {
10
+ throw new Error("Stage name is required in non-interactive mode.");
11
+ }
12
+ const prompted = await text({
13
+ message: "What’s the name of this stage?",
14
+ validate: (value) => (value.trim().length > 0 ? undefined : "Stage name is required."),
15
+ });
16
+ if (isCancel(prompted)) {
17
+ cancel("Command canceled.");
18
+ process.exit(0);
19
+ }
20
+ return prompted.trim();
21
+ }
22
+ async function runStageList(options) {
23
+ const orgSlug = await promptForOrganizationSlug(options.org);
24
+ const projectSlug = await promptForProjectSlug(orgSlug, options.project);
25
+ const stages = await listStagesForProject(orgSlug, projectSlug);
26
+ if (options.json) {
27
+ toJsonOutput(true, stages);
28
+ return;
29
+ }
30
+ if (stages.length === 0) {
31
+ console.log("No stages found.");
32
+ return;
33
+ }
34
+ for (const stage of stages) {
35
+ console.log(`${stage.name} (${stage.slug}) variables=${stage.variableCount}`);
36
+ }
37
+ }
38
+ async function runStageCreate(name, options) {
39
+ const orgSlug = await promptForOrganizationSlug(options.org);
40
+ const projectSlug = await promptForProjectSlug(orgSlug, options.project);
41
+ const stageName = await promptForStageName(name);
42
+ const stage = await createStageForProject(orgSlug, projectSlug, stageName);
43
+ if (options.json) {
44
+ toJsonOutput(true, stage);
45
+ return;
46
+ }
47
+ console.log(`Created stage ${stage.name} (${stage.slug}).`);
48
+ }
49
+ export function registerStageCommands(program) {
50
+ const stage = program.command("stage").description("Stage management");
51
+ stage
52
+ .command("list")
53
+ .description("List stages in a project")
54
+ .option("--org <slug>", "Organization slug")
55
+ .option("--project <slug>", "Project slug")
56
+ .option("--json", "Machine-readable output", false)
57
+ .action(async (options) => {
58
+ await runStageList(options);
59
+ });
60
+ stage
61
+ .command("create")
62
+ .description("Create a stage")
63
+ .argument("[name]", "Stage name")
64
+ .option("--org <slug>", "Organization slug")
65
+ .option("--project <slug>", "Project slug")
66
+ .option("--json", "Machine-readable output", false)
67
+ .action(async (name, options) => {
68
+ await runStageCreate(name, options);
69
+ });
70
+ stage
71
+ .command("rename")
72
+ .description("Rename a stage")
73
+ .argument("[slug]", "Stage slug")
74
+ .argument("[name]", "New stage display name")
75
+ .option("--org <slug>", "Organization slug")
76
+ .option("--project <slug>", "Project slug")
77
+ .option("--json", "Machine-readable output", false)
78
+ .action(async (slug, name, options) => {
79
+ const orgSlug = await promptForOrganizationSlug(options.org);
80
+ const projectSlug = await promptForProjectSlug(orgSlug, options.project);
81
+ const stageSlug = await promptForStageSlug(orgSlug, projectSlug, slug);
82
+ const stageName = await promptForStageName(name);
83
+ const stage = await renameStageForProject(orgSlug, projectSlug, stageSlug, stageName);
84
+ if (options.json) {
85
+ toJsonOutput(true, stage);
86
+ return;
87
+ }
88
+ console.log(`Renamed stage ${stage.slug} to ${stage.name}.`);
89
+ });
90
+ stage
91
+ .command("delete")
92
+ .description("Delete a stage")
93
+ .argument("[slug]", "Stage slug")
94
+ .option("--org <slug>", "Organization slug")
95
+ .option("--project <slug>", "Project slug")
96
+ .option("--yes", "Skip confirmation prompt", false)
97
+ .option("--json", "Machine-readable output", false)
98
+ .action(async (slug, options) => {
99
+ const orgSlug = await promptForOrganizationSlug(options.org);
100
+ const projectSlug = await promptForProjectSlug(orgSlug, options.project);
101
+ const stageSlug = await promptForStageSlug(orgSlug, projectSlug, slug);
102
+ if (!options.yes) {
103
+ if (!process.stdout.isTTY) {
104
+ throw new Error("Stage deletion requires --yes in non-interactive mode.");
105
+ }
106
+ const confirmed = await confirm({
107
+ message: `Delete stage ${stageSlug}?`,
108
+ initialValue: false,
109
+ });
110
+ if (isCancel(confirmed)) {
111
+ cancel("Command canceled.");
112
+ process.exit(0);
113
+ }
114
+ if (!confirmed) {
115
+ throw new Error("Delete canceled.");
116
+ }
117
+ }
118
+ const response = await deleteStageForProject(orgSlug, projectSlug, stageSlug);
119
+ if (options.json) {
120
+ toJsonOutput(true, response);
121
+ return;
122
+ }
123
+ console.log(`Deleted stage ${response.deletedStageSlug}.`);
124
+ });
125
+ }
@@ -0,0 +1,184 @@
1
+ /**
2
+ * Loads organizations for the current CLI user.
3
+ *
4
+ * @returns The accessible organizations for the signed-in user.
5
+ * @remarks Interactive command flows use this to avoid any hidden org-scoped auth fallback.
6
+ * @lastModified 2026-03-19
7
+ * @author GPT-5.4
8
+ */
9
+ export declare function listOrganizationsForCurrentUser(): Promise<readonly {
10
+ readonly name: string;
11
+ readonly id: string;
12
+ readonly slug: string;
13
+ readonly role: string;
14
+ readonly imageUrl: string;
15
+ }[]>;
16
+ /**
17
+ * Loads projects for one organization.
18
+ *
19
+ * @param orgSlug The organization slug to inspect.
20
+ * @returns The projects for the organization.
21
+ * @remarks Project-scoped CLI flows call the same backend contract as `barekey init`.
22
+ * @lastModified 2026-03-19
23
+ * @author GPT-5.4
24
+ */
25
+ export declare function listProjectsForOrganization(orgSlug: string): Promise<readonly {
26
+ readonly orgId: string;
27
+ readonly orgSlug: string;
28
+ readonly name: string;
29
+ readonly createdAtMs: number;
30
+ readonly updatedAtMs: number;
31
+ readonly id: string;
32
+ readonly slug: string;
33
+ readonly slugBase: string;
34
+ readonly createdByClerkUserId: string;
35
+ readonly secretCount: number;
36
+ }[]>;
37
+ /**
38
+ * Loads stages for one project.
39
+ *
40
+ * @param orgSlug The organization slug to inspect.
41
+ * @param projectSlug The project slug to inspect.
42
+ * @returns The stages for the selected project.
43
+ * @remarks Stage prompts use this to drive repo initialization and stage management flows.
44
+ * @lastModified 2026-03-19
45
+ * @author GPT-5.4
46
+ */
47
+ export declare function listStagesForProject(orgSlug: string, projectSlug: string): Promise<readonly {
48
+ readonly orgId: string;
49
+ readonly name: string;
50
+ readonly createdAtMs: number;
51
+ readonly updatedAtMs: number;
52
+ readonly id: string;
53
+ readonly slug: string;
54
+ readonly projectId: string;
55
+ readonly isDefault: boolean;
56
+ readonly variableCount: number;
57
+ }[]>;
58
+ /**
59
+ * Creates one project for one organization.
60
+ *
61
+ * @param orgSlug The organization slug that should own the project.
62
+ * @param name The project name to create.
63
+ * @returns The created project summary.
64
+ * @remarks CLI project-create flows use this helper so the command stays a thin prompt wrapper.
65
+ * @lastModified 2026-03-19
66
+ * @author GPT-5.4
67
+ */
68
+ export declare function createProjectForOrganization(orgSlug: string, name: string): Promise<{
69
+ readonly orgId: string;
70
+ readonly orgSlug: string;
71
+ readonly name: string;
72
+ readonly createdAtMs: number;
73
+ readonly updatedAtMs: number;
74
+ readonly id: string;
75
+ readonly slug: string;
76
+ readonly slugBase: string;
77
+ readonly createdByClerkUserId: string;
78
+ }>;
79
+ /**
80
+ * Deletes one project for one organization.
81
+ *
82
+ * @param orgSlug The organization slug that owns the project.
83
+ * @param projectSlug The project slug to delete.
84
+ * @returns The deleted project payload.
85
+ * @remarks Destructive project flows use this shared helper so command handlers stay focused on prompts and output.
86
+ * @lastModified 2026-03-19
87
+ * @author GPT-5.4
88
+ */
89
+ export declare function deleteProjectForOrganization(orgSlug: string, projectSlug: string): Promise<{
90
+ readonly deletedProjectId: string;
91
+ readonly deletedProjectSlug: string;
92
+ }>;
93
+ /**
94
+ * Creates one stage for one project.
95
+ *
96
+ * @param orgSlug The organization slug that owns the project.
97
+ * @param projectSlug The project slug that should receive the stage.
98
+ * @param name The stage name to create.
99
+ * @returns The created stage summary.
100
+ * @remarks CLI stage-create flows use this helper so the command stays a thin prompt wrapper.
101
+ * @lastModified 2026-03-19
102
+ * @author GPT-5.4
103
+ */
104
+ export declare function createStageForProject(orgSlug: string, projectSlug: string, name: string): Promise<{
105
+ readonly orgId: string;
106
+ readonly name: string;
107
+ readonly createdAtMs: number;
108
+ readonly updatedAtMs: number;
109
+ readonly id: string;
110
+ readonly slug: string;
111
+ readonly projectId: string;
112
+ readonly isDefault: boolean;
113
+ readonly variableCount: number;
114
+ }>;
115
+ /**
116
+ * Renames one stage for one project.
117
+ *
118
+ * @param orgSlug The organization slug that owns the project.
119
+ * @param projectSlug The project slug that owns the stage.
120
+ * @param stageSlug The stage slug to rename.
121
+ * @param name The next display name for the stage.
122
+ * @returns The updated stage summary.
123
+ * @remarks Stage rename keeps immutable slugs and only patches the display name.
124
+ * @lastModified 2026-03-19
125
+ * @author GPT-5.4
126
+ */
127
+ export declare function renameStageForProject(orgSlug: string, projectSlug: string, stageSlug: string, name: string): Promise<{
128
+ readonly orgId: string;
129
+ readonly name: string;
130
+ readonly createdAtMs: number;
131
+ readonly updatedAtMs: number;
132
+ readonly id: string;
133
+ readonly slug: string;
134
+ readonly projectId: string;
135
+ readonly isDefault: boolean;
136
+ readonly variableCount: number;
137
+ }>;
138
+ /**
139
+ * Deletes one stage for one project.
140
+ *
141
+ * @param orgSlug The organization slug that owns the project.
142
+ * @param projectSlug The project slug that owns the stage.
143
+ * @param stageSlug The stage slug to delete.
144
+ * @returns The deleted stage payload.
145
+ * @remarks Destructive stage flows use this helper so command handlers stay prompt-focused.
146
+ * @lastModified 2026-03-19
147
+ * @author GPT-5.4
148
+ */
149
+ export declare function deleteStageForProject(orgSlug: string, projectSlug: string, stageSlug: string): Promise<{
150
+ readonly deletedStageSlug: string;
151
+ }>;
152
+ /**
153
+ * Resolves one organization target from an explicit flag or an interactive selection.
154
+ *
155
+ * @param orgSlug The optionally supplied organization slug.
156
+ * @returns The resolved organization slug.
157
+ * @remarks Non-interactive runs must provide the target explicitly or via local repo config higher up the call stack.
158
+ * @lastModified 2026-03-19
159
+ * @author GPT-5.4
160
+ */
161
+ export declare function promptForOrganizationSlug(orgSlug: string | undefined): Promise<string>;
162
+ /**
163
+ * Resolves one project target from an explicit flag or an interactive selection.
164
+ *
165
+ * @param orgSlug The owning organization slug.
166
+ * @param projectSlug The optionally supplied project slug.
167
+ * @returns The resolved project slug.
168
+ * @remarks This intentionally loads live project choices instead of guessing from auth state.
169
+ * @lastModified 2026-03-19
170
+ * @author GPT-5.4
171
+ */
172
+ export declare function promptForProjectSlug(orgSlug: string, projectSlug: string | undefined): Promise<string>;
173
+ /**
174
+ * Resolves one stage target from an explicit flag or an interactive selection.
175
+ *
176
+ * @param orgSlug The owning organization slug.
177
+ * @param projectSlug The owning project slug.
178
+ * @param stageSlug The optionally supplied stage slug.
179
+ * @returns The resolved stage slug.
180
+ * @remarks This is used by `barekey init` so local repo setup can be a guided flow.
181
+ * @lastModified 2026-03-19
182
+ * @author GPT-5.4
183
+ */
184
+ export declare function promptForStageSlug(orgSlug: string, projectSlug: string, stageSlug: string | undefined): Promise<string>;
@@ -0,0 +1,312 @@
1
+ import { cancel, isCancel, select } from "@clack/prompts";
2
+ import { createCliAuthProvider } from "../auth-provider.js";
3
+ import { requireLocalSession } from "../command-utils.js";
4
+ import { OrganizationsResponseSchema, ProjectCreateResponseSchema, ProjectDeleteResponseSchema, ProjectsListResponseSchema, StageCreateResponseSchema, StageDeleteResponseSchema, StageRenameResponseSchema, StagesListResponseSchema, } from "../contracts/index.js";
5
+ import { getJson, postJson } from "../http.js";
6
+ async function resolveManagementAccess() {
7
+ const local = await requireLocalSession();
8
+ const authProvider = createCliAuthProvider();
9
+ const accessToken = await authProvider.getAccessToken();
10
+ return {
11
+ local,
12
+ accessToken,
13
+ };
14
+ }
15
+ /**
16
+ * Loads organizations for the current CLI user.
17
+ *
18
+ * @returns The accessible organizations for the signed-in user.
19
+ * @remarks Interactive command flows use this to avoid any hidden org-scoped auth fallback.
20
+ * @lastModified 2026-03-19
21
+ * @author GPT-5.4
22
+ */
23
+ export async function listOrganizationsForCurrentUser() {
24
+ const { local, accessToken } = await resolveManagementAccess();
25
+ const response = await getJson({
26
+ baseUrl: local.baseUrl,
27
+ path: "/v1/cli/orgs",
28
+ accessToken,
29
+ schema: OrganizationsResponseSchema,
30
+ });
31
+ return response.organizations;
32
+ }
33
+ /**
34
+ * Loads projects for one organization.
35
+ *
36
+ * @param orgSlug The organization slug to inspect.
37
+ * @returns The projects for the organization.
38
+ * @remarks Project-scoped CLI flows call the same backend contract as `barekey init`.
39
+ * @lastModified 2026-03-19
40
+ * @author GPT-5.4
41
+ */
42
+ export async function listProjectsForOrganization(orgSlug) {
43
+ const { local, accessToken } = await resolveManagementAccess();
44
+ const response = await postJson({
45
+ baseUrl: local.baseUrl,
46
+ path: "/v1/cli/projects/list",
47
+ accessToken,
48
+ payload: {
49
+ orgSlug,
50
+ },
51
+ schema: ProjectsListResponseSchema,
52
+ });
53
+ return response.projects;
54
+ }
55
+ /**
56
+ * Loads stages for one project.
57
+ *
58
+ * @param orgSlug The organization slug to inspect.
59
+ * @param projectSlug The project slug to inspect.
60
+ * @returns The stages for the selected project.
61
+ * @remarks Stage prompts use this to drive repo initialization and stage management flows.
62
+ * @lastModified 2026-03-19
63
+ * @author GPT-5.4
64
+ */
65
+ export async function listStagesForProject(orgSlug, projectSlug) {
66
+ const { local, accessToken } = await resolveManagementAccess();
67
+ const response = await postJson({
68
+ baseUrl: local.baseUrl,
69
+ path: "/v1/cli/stages/list",
70
+ accessToken,
71
+ payload: {
72
+ orgSlug,
73
+ projectSlug,
74
+ },
75
+ schema: StagesListResponseSchema,
76
+ });
77
+ return response.stages;
78
+ }
79
+ /**
80
+ * Creates one project for one organization.
81
+ *
82
+ * @param orgSlug The organization slug that should own the project.
83
+ * @param name The project name to create.
84
+ * @returns The created project summary.
85
+ * @remarks CLI project-create flows use this helper so the command stays a thin prompt wrapper.
86
+ * @lastModified 2026-03-19
87
+ * @author GPT-5.4
88
+ */
89
+ export async function createProjectForOrganization(orgSlug, name) {
90
+ const { local, accessToken } = await resolveManagementAccess();
91
+ const response = await postJson({
92
+ baseUrl: local.baseUrl,
93
+ path: "/v1/cli/projects/create",
94
+ accessToken,
95
+ payload: {
96
+ orgSlug,
97
+ name,
98
+ },
99
+ schema: ProjectCreateResponseSchema,
100
+ });
101
+ return response.project;
102
+ }
103
+ /**
104
+ * Deletes one project for one organization.
105
+ *
106
+ * @param orgSlug The organization slug that owns the project.
107
+ * @param projectSlug The project slug to delete.
108
+ * @returns The deleted project payload.
109
+ * @remarks Destructive project flows use this shared helper so command handlers stay focused on prompts and output.
110
+ * @lastModified 2026-03-19
111
+ * @author GPT-5.4
112
+ */
113
+ export async function deleteProjectForOrganization(orgSlug, projectSlug) {
114
+ const { local, accessToken } = await resolveManagementAccess();
115
+ return await postJson({
116
+ baseUrl: local.baseUrl,
117
+ path: "/v1/cli/projects/delete",
118
+ accessToken,
119
+ payload: {
120
+ orgSlug,
121
+ projectSlug,
122
+ },
123
+ schema: ProjectDeleteResponseSchema,
124
+ });
125
+ }
126
+ /**
127
+ * Creates one stage for one project.
128
+ *
129
+ * @param orgSlug The organization slug that owns the project.
130
+ * @param projectSlug The project slug that should receive the stage.
131
+ * @param name The stage name to create.
132
+ * @returns The created stage summary.
133
+ * @remarks CLI stage-create flows use this helper so the command stays a thin prompt wrapper.
134
+ * @lastModified 2026-03-19
135
+ * @author GPT-5.4
136
+ */
137
+ export async function createStageForProject(orgSlug, projectSlug, name) {
138
+ const { local, accessToken } = await resolveManagementAccess();
139
+ const response = await postJson({
140
+ baseUrl: local.baseUrl,
141
+ path: "/v1/cli/stages/create",
142
+ accessToken,
143
+ payload: {
144
+ orgSlug,
145
+ projectSlug,
146
+ name,
147
+ },
148
+ schema: StageCreateResponseSchema,
149
+ });
150
+ return response.stage;
151
+ }
152
+ /**
153
+ * Renames one stage for one project.
154
+ *
155
+ * @param orgSlug The organization slug that owns the project.
156
+ * @param projectSlug The project slug that owns the stage.
157
+ * @param stageSlug The stage slug to rename.
158
+ * @param name The next display name for the stage.
159
+ * @returns The updated stage summary.
160
+ * @remarks Stage rename keeps immutable slugs and only patches the display name.
161
+ * @lastModified 2026-03-19
162
+ * @author GPT-5.4
163
+ */
164
+ export async function renameStageForProject(orgSlug, projectSlug, stageSlug, name) {
165
+ const { local, accessToken } = await resolveManagementAccess();
166
+ const response = await postJson({
167
+ baseUrl: local.baseUrl,
168
+ path: "/v1/cli/stages/rename",
169
+ accessToken,
170
+ payload: {
171
+ orgSlug,
172
+ projectSlug,
173
+ stageSlug,
174
+ name,
175
+ },
176
+ schema: StageRenameResponseSchema,
177
+ });
178
+ return response.stage;
179
+ }
180
+ /**
181
+ * Deletes one stage for one project.
182
+ *
183
+ * @param orgSlug The organization slug that owns the project.
184
+ * @param projectSlug The project slug that owns the stage.
185
+ * @param stageSlug The stage slug to delete.
186
+ * @returns The deleted stage payload.
187
+ * @remarks Destructive stage flows use this helper so command handlers stay prompt-focused.
188
+ * @lastModified 2026-03-19
189
+ * @author GPT-5.4
190
+ */
191
+ export async function deleteStageForProject(orgSlug, projectSlug, stageSlug) {
192
+ const { local, accessToken } = await resolveManagementAccess();
193
+ return await postJson({
194
+ baseUrl: local.baseUrl,
195
+ path: "/v1/cli/stages/delete",
196
+ accessToken,
197
+ payload: {
198
+ orgSlug,
199
+ projectSlug,
200
+ stageSlug,
201
+ },
202
+ schema: StageDeleteResponseSchema,
203
+ });
204
+ }
205
+ /**
206
+ * Resolves one organization target from an explicit flag or an interactive selection.
207
+ *
208
+ * @param orgSlug The optionally supplied organization slug.
209
+ * @returns The resolved organization slug.
210
+ * @remarks Non-interactive runs must provide the target explicitly or via local repo config higher up the call stack.
211
+ * @lastModified 2026-03-19
212
+ * @author GPT-5.4
213
+ */
214
+ export async function promptForOrganizationSlug(orgSlug) {
215
+ const explicit = orgSlug?.trim();
216
+ if (explicit && explicit.length > 0) {
217
+ return explicit;
218
+ }
219
+ if (!process.stdout.isTTY) {
220
+ throw new Error("Organization slug is required in non-interactive mode.");
221
+ }
222
+ const organizations = await listOrganizationsForCurrentUser();
223
+ if (organizations.length === 0) {
224
+ throw new Error("No organizations found. Create one first with barekey org create.");
225
+ }
226
+ const selected = await select({
227
+ message: "Which organization should Barekey use?",
228
+ options: organizations.map((organization) => ({
229
+ value: organization.slug,
230
+ label: organization.name,
231
+ hint: organization.slug,
232
+ })),
233
+ });
234
+ if (isCancel(selected)) {
235
+ cancel("Command canceled.");
236
+ process.exit(0);
237
+ }
238
+ return selected;
239
+ }
240
+ /**
241
+ * Resolves one project target from an explicit flag or an interactive selection.
242
+ *
243
+ * @param orgSlug The owning organization slug.
244
+ * @param projectSlug The optionally supplied project slug.
245
+ * @returns The resolved project slug.
246
+ * @remarks This intentionally loads live project choices instead of guessing from auth state.
247
+ * @lastModified 2026-03-19
248
+ * @author GPT-5.4
249
+ */
250
+ export async function promptForProjectSlug(orgSlug, projectSlug) {
251
+ const explicit = projectSlug?.trim();
252
+ if (explicit && explicit.length > 0) {
253
+ return explicit;
254
+ }
255
+ if (!process.stdout.isTTY) {
256
+ throw new Error("Project slug is required in non-interactive mode.");
257
+ }
258
+ const projects = await listProjectsForOrganization(orgSlug);
259
+ if (projects.length === 0) {
260
+ throw new Error("No projects found. Create one first with barekey project create.");
261
+ }
262
+ const selected = await select({
263
+ message: "Which project should Barekey use?",
264
+ options: projects.map((project) => ({
265
+ value: project.slug,
266
+ label: project.name,
267
+ hint: project.slug,
268
+ })),
269
+ });
270
+ if (isCancel(selected)) {
271
+ cancel("Command canceled.");
272
+ process.exit(0);
273
+ }
274
+ return selected;
275
+ }
276
+ /**
277
+ * Resolves one stage target from an explicit flag or an interactive selection.
278
+ *
279
+ * @param orgSlug The owning organization slug.
280
+ * @param projectSlug The owning project slug.
281
+ * @param stageSlug The optionally supplied stage slug.
282
+ * @returns The resolved stage slug.
283
+ * @remarks This is used by `barekey init` so local repo setup can be a guided flow.
284
+ * @lastModified 2026-03-19
285
+ * @author GPT-5.4
286
+ */
287
+ export async function promptForStageSlug(orgSlug, projectSlug, stageSlug) {
288
+ const explicit = stageSlug?.trim();
289
+ if (explicit && explicit.length > 0) {
290
+ return explicit;
291
+ }
292
+ if (!process.stdout.isTTY) {
293
+ throw new Error("Stage slug is required in non-interactive mode.");
294
+ }
295
+ const stages = await listStagesForProject(orgSlug, projectSlug);
296
+ if (stages.length === 0) {
297
+ throw new Error("No stages found. Create one first with barekey stage create.");
298
+ }
299
+ const selected = await select({
300
+ message: "Which stage should Barekey use?",
301
+ options: stages.map((stage) => ({
302
+ value: stage.slug,
303
+ label: stage.name,
304
+ hint: stage.slug,
305
+ })),
306
+ });
307
+ if (isCancel(selected)) {
308
+ cancel("Command canceled.");
309
+ process.exit(0);
310
+ }
311
+ return selected;
312
+ }
@@ -1,6 +1,6 @@
1
- import type { BarekeyTypegenResult } from "@barekey/sdk/server";
2
1
  import { Command } from "commander";
3
- export declare function formatTypegenResultMessage(result: BarekeyTypegenResult): string;
2
+ import { type CliTypegenResult } from "../typegen/core.js";
3
+ export declare function formatTypegenResultMessage(result: CliTypegenResult): string;
4
4
  export declare function formatTypegenWatchStartedMessage(input: {
5
5
  organization: string;
6
6
  project: string;