gigadrive 2.4.4 → 2.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.
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ import { Effect as Effect27, Layer, LogLevel, Logger } from "effect";
9
9
  // package.json
10
10
  var package_default = {
11
11
  name: "gigadrive",
12
- version: "2.4.4",
12
+ version: "2.5.1",
13
13
  repository: {
14
14
  type: "git",
15
15
  url: "https://github.com/Gigadrive/sdk.git",
@@ -154,6 +154,13 @@ var ApplicationNotFoundError = class extends Schema.TaggedError()(
154
154
  }
155
155
  ) {
156
156
  };
157
+ var NoOrganizationsFoundError = class extends Schema.TaggedError()(
158
+ "NoOrganizationsFoundError",
159
+ {
160
+ message: Schema.String
161
+ }
162
+ ) {
163
+ };
157
164
  var EnvFileReadError = class extends Schema.TaggedError()("EnvFileReadError", {
158
165
  message: Schema.String,
159
166
  cause: Schema.optional(Schema.String)
@@ -490,8 +497,11 @@ var CLI_SCOPES = [
490
497
  "openid",
491
498
  "profile",
492
499
  "email",
500
+ // Platform discovery used for zero-config application onboarding
501
+ "platform:organizations:read",
493
502
  // Network API capabilities
494
503
  "network:applications:read",
504
+ "network:applications:write",
495
505
  "network:env_vars:read",
496
506
  "network:env_vars:write",
497
507
  "network:env_vars:delete",
@@ -500,11 +510,6 @@ var CLI_SCOPES = [
500
510
  "network:deployments:trigger",
501
511
  "network:ai_gateway:chat",
502
512
  "network:ai_gateway:models",
503
- "network:ai_gateway:usage:read",
504
- "network:ai_gateway:budgets:read",
505
- "network:ai_gateway:budgets:write",
506
- "network:ai_gateway:policies:read",
507
- "network:ai_gateway:policies:write",
508
513
  // Provisioning local-dev API credentials
509
514
  "platform:api_keys:read",
510
515
  "platform:api_keys:write",
@@ -1083,13 +1088,13 @@ var readStdin = Effect6.async((resume) => {
1083
1088
  stdin.resume();
1084
1089
  });
1085
1090
  var readJsonInput = (file) => Effect6.gen(function* () {
1086
- const path = Option4.getOrUndefined(file);
1091
+ const path2 = Option4.getOrUndefined(file);
1087
1092
  let raw;
1088
- if (path === void 0 || path === "-") {
1093
+ if (path2 === void 0 || path2 === "-") {
1089
1094
  raw = yield* readStdin;
1090
1095
  } else {
1091
1096
  const fs = yield* FileSystem3.FileSystem;
1092
- raw = yield* fs.readFileString(path, "utf8").pipe(Effect6.mapError((e) => new ApiRequestError({ message: `Failed to read ${path}: ${String(e)}` })));
1097
+ raw = yield* fs.readFileString(path2, "utf8").pipe(Effect6.mapError((e) => new ApiRequestError({ message: `Failed to read ${path2}: ${String(e)}` })));
1093
1098
  }
1094
1099
  return yield* Effect6.try({
1095
1100
  try: () => JSON.parse(raw),
@@ -1309,14 +1314,30 @@ var aiCommand = aiBase.pipe(
1309
1314
  // src/commands/apps/index.ts
1310
1315
  import { Command as Command2, Options as Options2 } from "@effect/cli";
1311
1316
  import { Console as Console3, Effect as Effect7, Option as Option5 } from "effect";
1312
- var orgOption2 = Options2.text("org").pipe(
1317
+ var listOrgOption = Options2.text("org").pipe(
1313
1318
  Options2.withAlias("o"),
1314
1319
  Options2.withDescription("Only list applications belonging to this organization ID"),
1315
1320
  Options2.optional
1316
1321
  );
1322
+ var createOrgOption = Options2.text("org").pipe(
1323
+ Options2.withAlias("o"),
1324
+ Options2.withDescription("Organization ID that will own the application")
1325
+ );
1326
+ var nameOption = Options2.text("name").pipe(
1327
+ Options2.withAlias("n"),
1328
+ Options2.withDescription("Application display name")
1329
+ );
1330
+ var slugOption = Options2.text("slug").pipe(
1331
+ Options2.withDescription("Optional lowercase application slug"),
1332
+ Options2.optional
1333
+ );
1334
+ var rootDirectoryOption = Options2.text("root-directory").pipe(
1335
+ Options2.withDescription("Optional project directory relative to the repository root"),
1336
+ Options2.optional
1337
+ );
1317
1338
  var appsListCommand = Command2.make(
1318
1339
  "list",
1319
- { org: orgOption2 },
1340
+ { org: listOrgOption },
1320
1341
  ({ org }) => Effect7.gen(function* () {
1321
1342
  const apiClient = yield* ApiClientService;
1322
1343
  const organizationId = Option5.getOrUndefined(org);
@@ -1339,8 +1360,35 @@ ${total} application(s).`);
1339
1360
  })
1340
1361
  )
1341
1362
  );
1363
+ var appsCreateCommand = Command2.make(
1364
+ "create",
1365
+ { org: createOrgOption, name: nameOption, slug: slugOption, rootDirectory: rootDirectoryOption },
1366
+ ({ org, name, slug, rootDirectory }) => Effect7.gen(function* () {
1367
+ const apiClient = yield* ApiClientService;
1368
+ const application = yield* apiClient.request(
1369
+ (client) => client.applications.create({
1370
+ organizationId: org,
1371
+ name,
1372
+ ...Option5.match(slug, { onNone: () => ({}), onSome: (value) => ({ slug: value }) }),
1373
+ ...Option5.match(rootDirectory, {
1374
+ onNone: () => ({}),
1375
+ onSome: (value) => ({ rootDirectory: value })
1376
+ })
1377
+ })
1378
+ );
1379
+ yield* Console3.log(`Created application ${application.name} (${application.id}).`);
1380
+ yield* Console3.log(`Run "gigadrive link --app ${application.id}" to link the current directory.`);
1381
+ }).pipe(
1382
+ Effect7.catchTags({
1383
+ NotAuthenticatedError: (err) => Console3.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
1384
+ Effect7.andThen(Effect7.fail(err))
1385
+ ),
1386
+ ApiRequestError: (err) => Console3.error(`Failed to create application: ${err.message}`).pipe(Effect7.andThen(Effect7.fail(err)))
1387
+ })
1388
+ )
1389
+ );
1342
1390
  var appsBase = Command2.make("apps", {}, () => Effect7.void);
1343
- var appsCommand = appsBase.pipe(Command2.withSubcommands([appsListCommand]));
1391
+ var appsCommand = appsBase.pipe(Command2.withSubcommands([appsListCommand, appsCreateCommand]));
1344
1392
 
1345
1393
  // src/commands/build/index.ts
1346
1394
  import { Command as Command3 } from "@effect/cli";
@@ -1636,7 +1684,7 @@ var appOption2 = Options3.text("app").pipe(
1636
1684
  Options3.withDescription("Filter by application ID (defaults to the linked application)"),
1637
1685
  Options3.optional
1638
1686
  );
1639
- var orgOption3 = Options3.text("org").pipe(
1687
+ var orgOption2 = Options3.text("org").pipe(
1640
1688
  Options3.withAlias("o"),
1641
1689
  Options3.withDescription("Filter by organization ID"),
1642
1690
  Options3.optional
@@ -1656,7 +1704,7 @@ var resolveApplicationFilter = (app) => Option6.match(app, {
1656
1704
  });
1657
1705
  var deploymentsListCommand = Command6.make(
1658
1706
  "list",
1659
- { app: appOption2, org: orgOption3, status: statusOption },
1707
+ { app: appOption2, org: orgOption2, status: statusOption },
1660
1708
  ({ app, org, status }) => Effect13.gen(function* () {
1661
1709
  const apiClient = yield* ApiClientService;
1662
1710
  const applicationId = yield* resolveApplicationFilter(app);
@@ -1950,7 +1998,7 @@ var appOption3 = Options4.text("app").pipe(
1950
1998
  Options4.withDescription("Operate on this application (overrides the linked application)"),
1951
1999
  Options4.optional
1952
2000
  );
1953
- var orgOption4 = Options4.text("org").pipe(
2001
+ var orgOption3 = Options4.text("org").pipe(
1954
2002
  Options4.withAlias("o"),
1955
2003
  Options4.withDescription("Operate on this organization instead of an application"),
1956
2004
  Options4.optional
@@ -1999,7 +2047,7 @@ var resolveScope = (app, org) => Effect17.gen(function* () {
1999
2047
  });
2000
2048
  var envListCommand = Command7.make(
2001
2049
  "list",
2002
- { app: appOption3, org: orgOption4 },
2050
+ { app: appOption3, org: orgOption3 },
2003
2051
  ({ app, org }) => Effect17.gen(function* () {
2004
2052
  const apiClient = yield* ApiClientService;
2005
2053
  const scope = yield* resolveScope(app, org);
@@ -2026,7 +2074,7 @@ var envListCommand = Command7.make(
2026
2074
  );
2027
2075
  var envSetCommand = Command7.make(
2028
2076
  "set",
2029
- { keyValue: keyValueArg, app: appOption3, org: orgOption4, sensitive: sensitiveOption, env: envIdOption },
2077
+ { keyValue: keyValueArg, app: appOption3, org: orgOption3, sensitive: sensitiveOption, env: envIdOption },
2030
2078
  ({ keyValue, app, org, sensitive, env }) => Effect17.gen(function* () {
2031
2079
  const separator = keyValue.indexOf("=");
2032
2080
  if (separator <= 0) {
@@ -2059,7 +2107,7 @@ var envSetCommand = Command7.make(
2059
2107
  );
2060
2108
  var envRmCommand = Command7.make(
2061
2109
  "rm",
2062
- { keyOrId: keyOrIdArg, app: appOption3, org: orgOption4 },
2110
+ { keyOrId: keyOrIdArg, app: appOption3, org: orgOption3 },
2063
2111
  ({ keyOrId, app, org }) => Effect17.gen(function* () {
2064
2112
  const apiClient = yield* ApiClientService;
2065
2113
  const scope = yield* resolveScope(app, org);
@@ -2173,14 +2221,14 @@ var appOption4 = Options5.text("app").pipe(
2173
2221
  Options5.withDescription("Application ID to link (skips the interactive picker)"),
2174
2222
  Options5.optional
2175
2223
  );
2176
- var orgOption5 = Options5.text("org").pipe(
2224
+ var orgOption4 = Options5.text("org").pipe(
2177
2225
  Options5.withAlias("o"),
2178
2226
  Options5.withDescription("Only list applications belonging to this organization ID"),
2179
2227
  Options5.optional
2180
2228
  );
2181
2229
  var linkCommand = Command8.make(
2182
2230
  "link",
2183
- { app: appOption4, org: orgOption5 },
2231
+ { app: appOption4, org: orgOption4 },
2184
2232
  ({ app, org }) => Effect18.gen(function* () {
2185
2233
  const apiClient = yield* ApiClientService;
2186
2234
  const projectLink = yield* ProjectLinkService;
@@ -2300,11 +2348,12 @@ import { Command as Command12 } from "@effect/cli";
2300
2348
  import { Effect as Effect24 } from "effect";
2301
2349
 
2302
2350
  // src/commands/platform/deploy/index.ts
2303
- import { Command as Command11, Options as Options6 } from "@effect/cli";
2351
+ import { Command as Command11, Options as Options6, Prompt as Prompt3 } from "@effect/cli";
2304
2352
  import { FileSystem as FileSystem9, Path as Path8 } from "@effect/platform";
2305
2353
  import { formatFileSize } from "@gigadrive/commons";
2306
2354
  import { Console as Console11, Duration as Duration2, Effect as Effect23, Option as Option12, Schedule, Stream } from "effect";
2307
2355
  import * as os4 from "os";
2356
+ import * as path from "path";
2308
2357
 
2309
2358
  // src/services/archive.ts
2310
2359
  import { FileSystem as FileSystem8, Path as Path7 } from "@effect/platform";
@@ -2314,7 +2363,15 @@ import { Effect as Effect21 } from "effect";
2314
2363
  import ignore from "ignore";
2315
2364
  import * as nodeFs from "fs";
2316
2365
  import * as nodeFsPromises from "fs/promises";
2317
- var IGNORE_FILE_NAMES = [".gigadriveignore", ".vercelignore", ".dockerignore", ".nowignore"];
2366
+ var IGNORE_FILE_NAMES = [".gitignore", ".dockerignore", ".nowignore", ".vercelignore", ".gigadriveignore"];
2367
+ var MANAGED_IGNORE_PATTERNS = [
2368
+ ".git/",
2369
+ "**/.git/",
2370
+ "node_modules/",
2371
+ "**/node_modules/",
2372
+ "**/.DS_Store",
2373
+ "**/Thumbs.db"
2374
+ ];
2318
2375
  var readIgnoreFile = (fs, ignorePath) => fs.readFileString(ignorePath, "utf8").pipe(
2319
2376
  Effect21.map((content) => content.split("\n").filter((line) => line.trim() !== "")),
2320
2377
  Effect21.catchAll(() => Effect21.succeed([]))
@@ -2345,19 +2402,23 @@ var collectIgnorePatterns = (fs, pathService, dir, baseDir, ignoreRules) => Effe
2345
2402
  }
2346
2403
  }
2347
2404
  }).pipe(Effect21.catchAll(() => Effect21.void));
2348
- var initializeIgnoreRules = (fs, pathService, baseDir) => Effect21.gen(function* () {
2405
+ var initializeIgnoreRules = (fs, pathService, baseDir, useIgnoreFiles, useManagedIgnore) => Effect21.gen(function* () {
2349
2406
  const ignoreRules = ignore();
2350
- ignoreRules.add([".git/", "**/.DS_Store", "**/Thumbs.db"]);
2351
- for (const ignoreFileName of IGNORE_FILE_NAMES) {
2352
- const ignoreFilePath = pathService.join(baseDir, ignoreFileName);
2353
- const patterns = yield* readIgnoreFile(fs, ignoreFilePath);
2354
- if (patterns.length > 0) {
2355
- ignoreRules.add(
2356
- patterns.map((pattern) => pattern.startsWith("!") ? `!${pattern.slice(1)}` : pattern)
2357
- );
2407
+ if (useManagedIgnore) {
2408
+ ignoreRules.add(MANAGED_IGNORE_PATTERNS);
2409
+ }
2410
+ if (useIgnoreFiles) {
2411
+ for (const ignoreFileName of IGNORE_FILE_NAMES) {
2412
+ const ignoreFilePath = pathService.join(baseDir, ignoreFileName);
2413
+ const patterns = yield* readIgnoreFile(fs, ignoreFilePath);
2414
+ if (patterns.length > 0) {
2415
+ ignoreRules.add(
2416
+ patterns.map((pattern) => pattern.startsWith("!") ? `!${pattern.slice(1)}` : pattern)
2417
+ );
2418
+ }
2358
2419
  }
2420
+ yield* collectIgnorePatterns(fs, pathService, baseDir, baseDir, ignoreRules);
2359
2421
  }
2360
- yield* collectIgnorePatterns(fs, pathService, baseDir, baseDir, ignoreRules);
2361
2422
  return ignoreRules;
2362
2423
  });
2363
2424
  var getFilesToInclude = (fs, pathService, dir, ignoreRules) => Effect21.gen(function* () {
@@ -2394,7 +2455,13 @@ var ArchiveService = class extends Effect21.Service()("ArchiveService", {
2394
2455
  yield* Effect21.annotateCurrentSpan("inputDir", inputDir);
2395
2456
  yield* Effect21.annotateCurrentSpan("outputFile", outputFile);
2396
2457
  yield* Effect21.log("Creating zip archive", { inputDir, outputFile });
2397
- const ignoreRules = options.useIgnoreFiles !== false ? yield* initializeIgnoreRules(fs, pathService, inputDir) : ignore();
2458
+ const ignoreRules = yield* initializeIgnoreRules(
2459
+ fs,
2460
+ pathService,
2461
+ inputDir,
2462
+ options.useIgnoreFiles !== false,
2463
+ options.useManagedIgnore !== false
2464
+ );
2398
2465
  const filesToInclude = options.whitelist ? yield* Effect21.tryPromise({
2399
2466
  try: () => Promise.all(
2400
2467
  options.whitelist.map((file) => getFilesForPattern(file, inputDir, options.excludeFiles ?? []))
@@ -2575,22 +2642,83 @@ var appOption5 = Options6.text("app").pipe(
2575
2642
  Options6.withDescription("Application ID to deploy to (overrides the linked application)"),
2576
2643
  Options6.optional
2577
2644
  );
2645
+ var orgOption5 = Options6.text("org").pipe(
2646
+ Options6.withAlias("o"),
2647
+ Options6.withDescription("Organization ID to use when automatically creating an application"),
2648
+ Options6.optional
2649
+ );
2650
+ var nameOption2 = Options6.text("name").pipe(
2651
+ Options6.withAlias("n"),
2652
+ Options6.withDescription("Application name to use when automatically creating an application"),
2653
+ Options6.optional
2654
+ );
2655
+ var createAndLinkDeploymentApplication = (input) => Effect23.gen(function* () {
2656
+ const projectLink = yield* ProjectLinkService;
2657
+ const apiClient = yield* ApiClientService;
2658
+ const { items: organizations } = yield* apiClient.request((client) => client.organizations.list());
2659
+ const availableOrganizations = Option12.match(input.org, {
2660
+ onNone: () => organizations,
2661
+ onSome: (organizationId) => organizations.filter((organization2) => organization2.id === organizationId)
2662
+ });
2663
+ if (availableOrganizations.length === 0) {
2664
+ return yield* new NoOrganizationsFoundError({
2665
+ message: Option12.match(input.org, {
2666
+ onNone: () => 'No organization is available for this deployment. Create an organization, then run "gigadrive deploy" again.',
2667
+ onSome: (organizationId) => `Organization "${organizationId}" was not found among your organizations.`
2668
+ })
2669
+ });
2670
+ }
2671
+ const organization = availableOrganizations.length === 1 ? availableOrganizations[0] : yield* Prompt3.run(
2672
+ Prompt3.select({
2673
+ message: "Select an organization for this application",
2674
+ choices: availableOrganizations.map((candidate) => ({
2675
+ title: candidate.name,
2676
+ value: candidate
2677
+ }))
2678
+ })
2679
+ );
2680
+ const inferredName = path.basename(input.cwd) || "Application";
2681
+ const applicationName = Option12.match(input.name, {
2682
+ onNone: () => inferredName,
2683
+ onSome: (name) => name
2684
+ }).trim();
2685
+ const application = yield* apiClient.request(
2686
+ (client) => client.applications.create({
2687
+ organizationId: organization.id,
2688
+ name: applicationName || inferredName
2689
+ })
2690
+ );
2691
+ yield* projectLink.save(input.cwd, {
2692
+ applicationId: application.id,
2693
+ organizationId: organization.id
2694
+ });
2695
+ yield* Console11.log(`Created and linked application ${application.name} (${application.id}).`);
2696
+ return application.id;
2697
+ });
2698
+ var resolveLinkedDeploymentApplication = (input) => Effect23.gen(function* () {
2699
+ const projectLink = yield* ProjectLinkService;
2700
+ const existingLink = yield* projectLink.load(input.cwd);
2701
+ return yield* Option12.match(existingLink, {
2702
+ onNone: () => createAndLinkDeploymentApplication(input),
2703
+ onSome: (link) => Effect23.succeed(link.applicationId)
2704
+ });
2705
+ });
2706
+ var resolveDeploymentApplication = (input) => Option12.match(input.app, {
2707
+ onNone: () => resolveLinkedDeploymentApplication(input),
2708
+ onSome: Effect23.succeed
2709
+ });
2578
2710
  var deployCommand = Command11.make(
2579
2711
  "deploy",
2580
- { app: appOption5 },
2581
- ({ app }) => Effect23.gen(function* () {
2712
+ { app: appOption5, org: orgOption5, name: nameOption2 },
2713
+ ({ app, org, name }) => Effect23.gen(function* () {
2582
2714
  const projectConfig = yield* ProjectConfigService;
2583
2715
  const deploymentApi = yield* DeploymentApiService;
2584
2716
  const archiveService = yield* ArchiveService;
2585
- const projectLink = yield* ProjectLinkService;
2586
2717
  const pathService = yield* Path8.Path;
2587
2718
  const cwd = process.cwd();
2588
- const applicationId = yield* Option12.match(app, {
2589
- onSome: (id) => Effect23.succeed(id),
2590
- onNone: () => projectLink.resolve(cwd).pipe(Effect23.map((link) => link.applicationId))
2591
- });
2592
2719
  yield* Effect23.log("Starting deploy command");
2593
2720
  const { config } = yield* projectConfig.resolve(cwd);
2721
+ const applicationId = yield* resolveDeploymentApplication({ app, org, name, cwd });
2594
2722
  yield* Console11.log("Creating deployment...");
2595
2723
  const deploymentId = yield* deploymentApi.createDeployment(applicationId);
2596
2724
  yield* Console11.log(`Deployment ID: ${deploymentId}`);
@@ -2598,9 +2726,7 @@ var deployCommand = Command11.make(
2598
2726
  const archivePath = pathService.join(os4.tmpdir(), `project-${Date.now()}.zip`);
2599
2727
  const archive = yield* archiveService.createZipArchive(config.userArchive?.rootOverwrite || cwd, archivePath, {
2600
2728
  whitelist: config.userArchive?.fileWhitelist,
2601
- excludeFiles: config.excludeFiles,
2602
- useIgnoreFiles: false,
2603
- useManagedIgnore: false
2729
+ excludeFiles: config.excludeFiles
2604
2730
  });
2605
2731
  yield* Console11.log(`Archive created (${formatFileSize(archive.size)})`);
2606
2732
  yield* Console11.log("Uploading archive...");
@@ -2610,8 +2736,14 @@ var deployCommand = Command11.make(
2610
2736
  yield* pollDeployment(deploymentId);
2611
2737
  }).pipe(
2612
2738
  Effect23.catchTags({
2613
- ProjectNotLinkedError: (err) => Console11.error(err.message).pipe(Effect23.andThen(Effect23.fail(err))),
2739
+ QuitException: () => Console11.log("Cancelled."),
2740
+ NotAuthenticatedError: (err) => Console11.error('You are not logged in. Run "gigadrive login" to authenticate.').pipe(
2741
+ Effect23.andThen(Effect23.fail(err))
2742
+ ),
2743
+ ApiRequestError: (err) => Console11.error(`Application setup failed: ${err.message}`).pipe(Effect23.andThen(Effect23.fail(err))),
2744
+ NoOrganizationsFoundError: (err) => Console11.error(err.message).pipe(Effect23.andThen(Effect23.fail(err))),
2614
2745
  ProjectLinkReadError: (err) => Console11.error(err.message).pipe(Effect23.andThen(Effect23.fail(err))),
2746
+ ProjectLinkWriteError: (err) => Console11.error(err.message).pipe(Effect23.andThen(Effect23.fail(err))),
2615
2747
  ConfigNotFoundError: (err) => Console11.error(err.message).pipe(Effect23.andThen(Effect23.fail(err))),
2616
2748
  ConfigParseError: (err) => Console11.error(`Config parse error: ${err.message}`).pipe(Effect23.andThen(Effect23.fail(err))),
2617
2749
  ConfigValidationError: (err) => Effect23.gen(function* () {
@@ -2727,7 +2859,7 @@ var platformBase = Command12.make("platform", {}, () => Effect24.void);
2727
2859
  var platformCommand = platformBase.pipe(Command12.withSubcommands([deployCommand]));
2728
2860
 
2729
2861
  // src/commands/setup/index.ts
2730
- import { Args as Args4, Command as Command13, Options as Options7, Prompt as Prompt3 } from "@effect/cli";
2862
+ import { Args as Args4, Command as Command13, Options as Options7, Prompt as Prompt4 } from "@effect/cli";
2731
2863
  import { Console as Console12, Effect as Effect25, Option as Option13 } from "effect";
2732
2864
  var fileArg2 = Args4.text({ name: "file" }).pipe(
2733
2865
  Args4.withDescription("Output file to write (default: .env.local)"),
@@ -2805,8 +2937,8 @@ var setupCommand = Command13.make(
2805
2937
  } else if (apps.length === 1) {
2806
2938
  chosen = apps[0];
2807
2939
  } else {
2808
- chosen = yield* Prompt3.run(
2809
- Prompt3.select({
2940
+ chosen = yield* Prompt4.run(
2941
+ Prompt4.select({
2810
2942
  message: "Select an application to set up",
2811
2943
  choices: apps.map((a) => ({ title: `${a.name} (${a.organization.name})`, value: a }))
2812
2944
  })
@@ -2823,8 +2955,8 @@ var setupCommand = Command13.make(
2823
2955
  );
2824
2956
  const existing = yield* envFile.read(target);
2825
2957
  if (Option13.isSome(existing) && !yes) {
2826
- const overwrite = yield* Prompt3.run(
2827
- Prompt3.confirm({ message: `${target} already exists. Overwrite?`, initial: false })
2958
+ const overwrite = yield* Prompt4.run(
2959
+ Prompt4.confirm({ message: `${target} already exists. Overwrite?`, initial: false })
2828
2960
  );
2829
2961
  if (!overwrite) {
2830
2962
  return yield* Console12.log("Cancelled.");
@@ -2902,6 +3034,7 @@ var gigadrive = Command15.make("gigadrive", {}, () => Effect27.void).pipe(
2902
3034
  aiCommand,
2903
3035
  buildCommand,
2904
3036
  debugCommand,
3037
+ deployCommand,
2905
3038
  platformCommand,
2906
3039
  setupCommand
2907
3040
  ])