@better-update/cli 0.10.1 → 0.11.0

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
@@ -27,7 +27,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
27
27
 
28
28
  //#endregion
29
29
  //#region package.json
30
- var version = "0.10.1";
30
+ var version = "0.11.0";
31
31
 
32
32
  //#endregion
33
33
  //#region src/lib/interactive-mode.ts
@@ -1127,37 +1127,51 @@ var DevicesGroup = class extends HttpApiGroup.make("devices").add(HttpApiEndpoin
1127
1127
 
1128
1128
  //#endregion
1129
1129
  //#region ../../packages/api/src/domain/env-var.ts
1130
- const EnvVarVisibility = Schema.Literal("plaintext", "sensitive", "secret");
1130
+ const EnvVarVisibility = Schema.Literal("plaintext", "sensitive");
1131
+ const EnvVarScope = Schema.Literal("project", "global");
1132
+ const EnvVarEnvironment = Schema.Literal("development", "preview", "production");
1133
+ const EnvVarListScope = Schema.Literal("all", "project", "global");
1131
1134
  var EnvVar = class extends Schema.Class("EnvVar")({
1132
1135
  id: Id,
1133
1136
  organizationId: Id,
1134
- projectId: Id,
1135
- environment: Schema.String,
1137
+ projectId: Schema.NullOr(Id),
1138
+ scope: EnvVarScope,
1136
1139
  key: Schema.String,
1137
1140
  visibility: EnvVarVisibility,
1138
1141
  value: Schema.NullOr(Schema.String),
1142
+ environments: Schema.Array(EnvVarEnvironment),
1143
+ overridesGlobal: Schema.optional(Schema.Boolean),
1139
1144
  createdAt: DateTimeString,
1140
1145
  updatedAt: DateTimeString
1141
1146
  }) {};
1142
1147
  const EnvVarKey = Schema.String.pipe(Schema.pattern(/^[A-Z][A-Z0-9_]*$/u), Schema.maxLength(256));
1143
1148
  const EnvVarValue = Schema.String.pipe(Schema.maxLength(32768));
1144
- const EnvVarEnvironment = Schema.String.pipe(Schema.minLength(1), Schema.maxLength(64));
1149
+ const EnvVarEnvironmentArray = Schema.Array(EnvVarEnvironment).pipe(Schema.minItems(1));
1145
1150
  const CreateEnvVarBody = Schema.Struct({
1146
- projectId: Id,
1147
- environment: EnvVarEnvironment,
1151
+ scope: EnvVarScope,
1152
+ projectId: Schema.optional(Id),
1153
+ environments: EnvVarEnvironmentArray,
1148
1154
  key: EnvVarKey,
1149
1155
  value: EnvVarValue,
1150
1156
  visibility: EnvVarVisibility
1151
1157
  });
1152
1158
  const UpdateEnvVarBody = Schema.Struct({
1153
1159
  value: Schema.optional(EnvVarValue),
1160
+ visibility: Schema.optional(EnvVarVisibility),
1161
+ environments: Schema.optional(EnvVarEnvironmentArray)
1162
+ });
1163
+ const BulkImportEntry = Schema.Struct({
1164
+ key: EnvVarKey,
1165
+ value: EnvVarValue,
1154
1166
  visibility: Schema.optional(EnvVarVisibility)
1155
1167
  });
1156
1168
  const BulkImportEnvVarsBody = Schema.Struct({
1157
- projectId: Id,
1158
- environment: EnvVarEnvironment,
1159
- content: Schema.String.pipe(Schema.maxLength(4e6)),
1160
- visibility: EnvVarVisibility
1169
+ scope: EnvVarScope,
1170
+ projectId: Schema.optional(Id),
1171
+ environments: EnvVarEnvironmentArray,
1172
+ content: Schema.optional(Schema.String.pipe(Schema.maxLength(4e6))),
1173
+ entries: Schema.optional(Schema.Array(BulkImportEntry).pipe(Schema.maxItems(100))),
1174
+ visibility: Schema.optional(EnvVarVisibility)
1161
1175
  });
1162
1176
  const BulkImportResult = Schema.Struct({
1163
1177
  created: Schema.Number,
@@ -1172,7 +1186,7 @@ const EnvVarExportItem = Schema.Struct({
1172
1186
  });
1173
1187
  const EnvVarExportResult = Schema.Struct({
1174
1188
  items: Schema.Array(EnvVarExportItem),
1175
- environment: Schema.String
1189
+ environment: EnvVarEnvironment
1176
1190
  });
1177
1191
 
1178
1192
  //#endregion
@@ -1180,32 +1194,34 @@ const EnvVarExportResult = Schema.Struct({
1180
1194
  const idParam$5 = HttpApiSchema.param("id", Schema.String);
1181
1195
  var EnvVarsGroup = class extends HttpApiGroup.make("env-vars").add(HttpApiEndpoint.post("create", "/api/env-vars").setPayload(CreateEnvVarBody).addSuccess(EnvVar, { status: 201 }).addError(BadRequest).addError(Conflict).annotateContext(OpenApi.annotations({
1182
1196
  title: "Create environment variable",
1183
- description: "Create a new environment variable for a project"
1197
+ description: "Create a new environment variable. Scope can be 'project' (requires projectId) or 'global' (organization-wide)."
1184
1198
  }))).add(HttpApiEndpoint.get("list", "/api/env-vars").setUrlParams(Schema.Struct({
1185
- projectId: Id,
1186
- environment: Schema.optional(Schema.String),
1199
+ scope: Schema.optional(EnvVarListScope),
1200
+ projectId: Schema.optional(Id),
1201
+ environments: Schema.optional(Schema.String),
1202
+ search: Schema.optional(Schema.String),
1187
1203
  ...PaginationParams.fields
1188
- })).addSuccess(Schema.Struct({ items: Schema.Array(EnvVar) })).annotateContext(OpenApi.annotations({
1204
+ })).addSuccess(Schema.Struct({ items: Schema.Array(EnvVar) })).addError(BadRequest).annotateContext(OpenApi.annotations({
1189
1205
  title: "List environment variables",
1190
- description: "List environment variables with optional filters"
1206
+ description: "List environment variables. scope=all merges project + global vars with project overrides. environments is a comma-separated list. search matches key substring."
1191
1207
  }))).add(HttpApiEndpoint.get("get")`/api/env-vars/${idParam$5}`.addSuccess(EnvVar).annotateContext(OpenApi.annotations({
1192
1208
  title: "Get environment variable",
1193
1209
  description: "Get an environment variable by ID"
1194
1210
  }))).add(HttpApiEndpoint.patch("update")`/api/env-vars/${idParam$5}`.setPayload(UpdateEnvVarBody).addSuccess(EnvVar).addError(BadRequest).annotateContext(OpenApi.annotations({
1195
1211
  title: "Update environment variable",
1196
- description: "Update an environment variable's value or visibility"
1212
+ description: "Update value, visibility, or assigned environments"
1197
1213
  }))).add(HttpApiEndpoint.del("delete")`/api/env-vars/${idParam$5}`.addSuccess(DeleteEnvVarResult).annotateContext(OpenApi.annotations({
1198
1214
  title: "Delete environment variable",
1199
1215
  description: "Delete an environment variable"
1200
1216
  }))).add(HttpApiEndpoint.post("bulkImport", "/api/env-vars/bulk-import").setPayload(BulkImportEnvVarsBody).addSuccess(BulkImportResult).addError(BadRequest).annotateContext(OpenApi.annotations({
1201
1217
  title: "Bulk import environment variables",
1202
- description: "Import environment variables from a dotenv-formatted string. Supports KEY=VALUE format with # comments. Quoted values (single/double) are unquoted. Multiline values are not supported."
1218
+ description: "Import variables from a dotenv-formatted string. Applies to all selected environments. Supports KEY=VALUE format with # comments. Quoted values (single/double) are unquoted. Multiline values are not supported."
1203
1219
  }))).add(HttpApiEndpoint.get("export", "/api/env-vars/export").setUrlParams(Schema.Struct({
1204
1220
  projectId: Id,
1205
- environment: Schema.String
1221
+ environment: EnvVarEnvironment
1206
1222
  })).addSuccess(EnvVarExportResult).addError(Forbidden).annotateContext(OpenApi.annotations({
1207
1223
  title: "Export environment variables",
1208
- description: "Export environment variables for a project environment"
1224
+ description: "Export environment variables for a project environment. Global org-scoped vars are merged in; project values override globals on key collision."
1209
1225
  }))).addError(NotFound).addError(Forbidden).addError(BadRequest).annotateContext(OpenApi.annotations({
1210
1226
  title: "Environment Variables",
1211
1227
  description: "Manage environment variables for project builds and deployments"
@@ -3891,14 +3907,19 @@ const clearBuildCaches = (projectRoot) => Effect.gen(function* () {
3891
3907
 
3892
3908
  //#endregion
3893
3909
  //#region src/lib/env-exporter.ts
3910
+ const coerceEnvironment = (raw) => raw === "development" || raw === "preview" || raw === "production" ? raw : void 0;
3894
3911
  /**
3895
3912
  * Pull environment variables for a project + environment and flatten them into
3896
3913
  * a key/value map. Returns an empty map when the project has no variables.
3897
3914
  */
3898
- const pullEnvVars = (api, { projectId, environment }) => api["env-vars"].export({ urlParams: {
3899
- projectId,
3900
- environment
3901
- } }).pipe(Effect.map((result) => Object.fromEntries(result.items.map((item) => [item.key, item.value]))), Effect.mapError((cause) => new EnvExportError({ message: `Failed to export environment variables for "${environment}": ${String(cause)}` })));
3915
+ const pullEnvVars = (api, { projectId, environment }) => {
3916
+ const validated = coerceEnvironment(environment);
3917
+ if (!validated) return Effect.fail(new EnvExportError({ message: `Invalid environment "${environment}". Must be one of: development, preview, production.` }));
3918
+ return api["env-vars"].export({ urlParams: {
3919
+ projectId,
3920
+ environment: validated
3921
+ } }).pipe(Effect.map((result) => Object.fromEntries(result.items.map((item) => [item.key, item.value]))), Effect.mapError((cause) => new EnvExportError({ message: `Failed to export environment variables for "${environment}": ${String(cause)}` })));
3922
+ };
3902
3923
 
3903
3924
  //#endregion
3904
3925
  //#region src/lib/git-context.ts
@@ -10058,36 +10079,45 @@ const envErrorExtras = {
10058
10079
  SystemError: 6,
10059
10080
  BadArgument: 6
10060
10081
  };
10082
+ const isEnvironmentName = (value) => value === "development" || value === "preview" || value === "production";
10083
+ const parseEnvironmentsArg = (raw) => Effect.gen(function* () {
10084
+ const tokens = raw.split(",").map((token) => token.trim()).filter((token) => token.length > 0);
10085
+ if (tokens.length === 0) return yield* new InvalidArgumentError({ message: "Provide at least one environment (development, preview, production)." });
10086
+ const seen = /* @__PURE__ */ new Set();
10087
+ yield* Effect.forEach(tokens, (token) => Effect.gen(function* () {
10088
+ if (!isEnvironmentName(token)) return yield* new InvalidArgumentError({ message: `Invalid environment "${token}". Must be one of: development, preview, production.` });
10089
+ seen.add(token);
10090
+ }), { discard: true });
10091
+ return [...seen];
10092
+ });
10093
+ const parseSingleEnvironmentArg = (raw) => Effect.gen(function* () {
10094
+ if (!isEnvironmentName(raw)) return yield* new InvalidArgumentError({ message: `Invalid environment "${raw}". Must be one of: development, preview, production.` });
10095
+ return raw;
10096
+ });
10097
+ const formatEnvironments = (environments) => [...environments].toSorted((left, right) => left.localeCompare(right)).join(",");
10061
10098
 
10062
10099
  //#endregion
10063
10100
  //#region src/commands/env/delete.ts
10064
10101
  const deleteCommand$2 = defineCommand({
10065
10102
  meta: {
10066
10103
  name: "delete",
10067
- description: "Delete an environment variable by key"
10068
- },
10069
- args: {
10070
- key: {
10071
- type: "positional",
10072
- required: true,
10073
- description: "Env var key"
10074
- },
10075
- environment: {
10076
- type: "string",
10077
- default: "production",
10078
- description: "Target environment"
10079
- }
10104
+ description: "Delete a project env var by key"
10080
10105
  },
10106
+ args: { key: {
10107
+ type: "positional",
10108
+ required: true,
10109
+ description: "Env var key"
10110
+ } },
10081
10111
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10082
10112
  const projectId = yield* readProjectId;
10083
10113
  const api = yield* apiClient;
10084
10114
  const match = (yield* api["env-vars"].list({ urlParams: {
10085
10115
  projectId,
10086
- environment: args.environment
10116
+ scope: "project"
10087
10117
  } })).items.find((item) => item.key === args.key);
10088
- if (!match) return yield* new EnvResourceNotFoundError({ message: `Environment variable ${args.key} not found in ${args.environment}` });
10118
+ if (!match) return yield* new EnvResourceNotFoundError({ message: `Project env var "${args.key}" not found.` });
10089
10119
  yield* api["env-vars"].delete({ path: { id: match.id } });
10090
- yield* Console.log(`Deleted ${args.key} from ${args.environment}`);
10120
+ yield* Console.log(`Deleted ${args.key}`);
10091
10121
  }), envErrorExtras)
10092
10122
  });
10093
10123
 
@@ -10139,11 +10169,12 @@ const execCommand = defineCommand({
10139
10169
  } },
10140
10170
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10141
10171
  const [bin, rest] = yield* splitTrailing(getExecTrailingArgv());
10172
+ const environment = yield* parseSingleEnvironmentArg(args.environment);
10142
10173
  const projectId = yield* readProjectId;
10143
10174
  const api = yield* apiClient;
10144
10175
  const runtime = yield* CliRuntime;
10145
10176
  const baseEnv = yield* runtime.commandEnvironment();
10146
- const pulled = yield* pullForExec(api, projectId, args.environment);
10177
+ const pulled = yield* pullForExec(api, projectId, environment);
10147
10178
  const cmd = Command.make(bin, ...rest).pipe(Command.env({
10148
10179
  ...baseEnv,
10149
10180
  ...pulled
@@ -10163,13 +10194,14 @@ const exportCommand = defineCommand({
10163
10194
  args: { environment: {
10164
10195
  type: "string",
10165
10196
  default: "production",
10166
- description: "Target environment"
10197
+ description: "Target environment (development, preview, production)"
10167
10198
  } },
10168
10199
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10200
+ const environment = yield* parseSingleEnvironmentArg(args.environment);
10169
10201
  const projectId = yield* readProjectId;
10170
10202
  const result = yield* (yield* apiClient)["env-vars"].export({ urlParams: {
10171
10203
  projectId,
10172
- environment: args.environment
10204
+ environment
10173
10205
  } });
10174
10206
  for (const item of result.items) {
10175
10207
  const escaped = item.value.replaceAll("'", String.raw`'\''`);
@@ -10195,7 +10227,8 @@ const getCommand$1 = defineCommand({
10195
10227
  yield* printKeyValue([
10196
10228
  ["ID", envVar.id],
10197
10229
  ["Key", envVar.key],
10198
- ["Environment", envVar.environment],
10230
+ ["Scope", envVar.scope],
10231
+ ["Environments", formatEnvironments(envVar.environments)],
10199
10232
  ["Visibility", envVar.visibility],
10200
10233
  ["Value", envVar.visibility === "plaintext" ? envVar.value ?? "" : "******"],
10201
10234
  ["Created", envVar.createdAt],
@@ -10220,25 +10253,23 @@ const importCommand = defineCommand({
10220
10253
  environment: {
10221
10254
  type: "string",
10222
10255
  default: "production",
10223
- description: "Target environment"
10256
+ description: "Target environments (comma-separated, e.g. development,production). Default: production"
10224
10257
  },
10225
10258
  visibility: {
10226
10259
  type: "enum",
10227
- options: [
10228
- "plaintext",
10229
- "sensitive",
10230
- "secret"
10231
- ],
10260
+ options: ["plaintext", "sensitive"],
10232
10261
  default: "plaintext",
10233
10262
  description: "Visibility applied to all imported values"
10234
10263
  }
10235
10264
  },
10236
10265
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10237
10266
  const content = yield* (yield* FileSystem.FileSystem).readFileString(args.file);
10267
+ const environments = yield* parseEnvironmentsArg(args.environment);
10238
10268
  const projectId = yield* readProjectId;
10239
10269
  const result = yield* (yield* apiClient)["env-vars"].bulkImport({ payload: {
10270
+ scope: "project",
10240
10271
  projectId,
10241
- environment: args.environment,
10272
+ environments,
10242
10273
  content,
10243
10274
  visibility: args.visibility
10244
10275
  } });
@@ -10253,25 +10284,44 @@ const listCommand$2 = defineCommand({
10253
10284
  name: "list",
10254
10285
  description: "List environment variables"
10255
10286
  },
10256
- args: { environment: {
10257
- type: "string",
10258
- description: "Filter by environment"
10259
- } },
10287
+ args: {
10288
+ environments: {
10289
+ type: "string",
10290
+ description: "Filter by environments (comma-separated, e.g. development,production). Default: all"
10291
+ },
10292
+ scope: {
10293
+ type: "enum",
10294
+ options: [
10295
+ "all",
10296
+ "project",
10297
+ "global"
10298
+ ],
10299
+ description: "Filter by scope (default: all — merged with global override resolution)"
10300
+ },
10301
+ search: {
10302
+ type: "string",
10303
+ description: "Filter by key substring (case-insensitive)"
10304
+ }
10305
+ },
10260
10306
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10261
10307
  const projectId = yield* readProjectId;
10262
10308
  const api = yield* apiClient;
10263
- const envFilter = args.environment ? { environment: args.environment } : {};
10309
+ const urlParams = {
10310
+ projectId,
10311
+ ...args.scope ? { scope: args.scope } : {},
10312
+ ...args.environments ? { environments: args.environments } : {},
10313
+ ...args.search ? { search: args.search } : {}
10314
+ };
10264
10315
  yield* printList([
10265
10316
  "Key",
10266
- "Environment",
10317
+ "Environments",
10318
+ "Scope",
10267
10319
  "Visibility",
10268
10320
  "Value"
10269
- ], (yield* api["env-vars"].list({ urlParams: {
10270
- projectId,
10271
- ...envFilter
10272
- } })).items.map((item) => [
10321
+ ], (yield* api["env-vars"].list({ urlParams })).items.map((item) => [
10273
10322
  item.key,
10274
- item.environment,
10323
+ formatEnvironments(item.environments),
10324
+ item.overridesGlobal ? `${item.scope} (overrides global)` : item.scope,
10275
10325
  item.visibility,
10276
10326
  item.visibility === "plaintext" ? item.value ?? "" : "••••••"
10277
10327
  ]), "No environment variables found.");
@@ -10288,13 +10338,14 @@ const pullCommand = defineCommand({
10288
10338
  args: { environment: {
10289
10339
  type: "string",
10290
10340
  default: "production",
10291
- description: "Target environment"
10341
+ description: "Target environment (development, preview, production)"
10292
10342
  } },
10293
10343
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10344
+ const environment = yield* parseSingleEnvironmentArg(args.environment);
10294
10345
  const projectId = yield* readProjectId;
10295
10346
  const result = yield* (yield* apiClient)["env-vars"].export({ urlParams: {
10296
10347
  projectId,
10297
- environment: args.environment
10348
+ environment
10298
10349
  } });
10299
10350
  for (const item of result.items) {
10300
10351
  const escaped = item.value.replaceAll("'", String.raw`'\''`);
@@ -10342,7 +10393,7 @@ const pushCommand = defineCommand({
10342
10393
  environment: {
10343
10394
  type: "string",
10344
10395
  default: "production",
10345
- description: "Target environment"
10396
+ description: "Target environments (comma-separated, e.g. development,production). Default: production"
10346
10397
  },
10347
10398
  force: {
10348
10399
  type: "boolean",
@@ -10355,11 +10406,12 @@ const pushCommand = defineCommand({
10355
10406
  yield* printHuman(`No valid KEY=VALUE entries found in ${args.file}.`);
10356
10407
  return;
10357
10408
  }
10409
+ const environments = yield* parseEnvironmentsArg(args.environment);
10358
10410
  const projectId = yield* readProjectId;
10359
10411
  const api = yield* apiClient;
10360
10412
  const existingResp = yield* api["env-vars"].list({ urlParams: {
10361
10413
  projectId,
10362
- environment: args.environment
10414
+ scope: "project"
10363
10415
  } });
10364
10416
  const existingByKey = new Map(existingResp.items.map((item) => [item.key, item]));
10365
10417
  const conflicts = parsed.filter((entry) => existingByKey.has(entry.key));
@@ -10379,8 +10431,9 @@ const pushCommand = defineCommand({
10379
10431
  });
10380
10432
  const skipped = conflicts.length - entriesToOverwrite.length;
10381
10433
  yield* Effect.forEach(newEntries, (entry) => api["env-vars"].create({ payload: {
10434
+ scope: "project",
10382
10435
  projectId,
10383
- environment: args.environment,
10436
+ environments,
10384
10437
  key: entry.key,
10385
10438
  value: entry.value,
10386
10439
  visibility: entry.visibility
@@ -10392,11 +10445,12 @@ const pushCommand = defineCommand({
10392
10445
  path: { id: existing.id },
10393
10446
  payload: {
10394
10447
  value: entry.value,
10395
- visibility: entry.visibility
10448
+ visibility: entry.visibility,
10449
+ environments
10396
10450
  }
10397
10451
  });
10398
10452
  }, { concurrency: 4 });
10399
- yield* printHuman(`Pushed to ${args.environment}: ${String(newEntries.length)} created, ${String(entriesToOverwrite.length)} updated${skipped > 0 ? `, ${String(skipped)} skipped` : ""}.`);
10453
+ yield* printHuman(`Pushed to ${formatEnvironments(environments)}: ${String(newEntries.length)} created, ${String(entriesToOverwrite.length)} updated${skipped > 0 ? `, ${String(skipped)} skipped` : ""}.`);
10400
10454
  }), envErrorExtras)
10401
10455
  });
10402
10456
 
@@ -10405,7 +10459,7 @@ const pushCommand = defineCommand({
10405
10459
  const setCommand$1 = defineCommand({
10406
10460
  meta: {
10407
10461
  name: "set",
10408
- description: "Create or update an environment variable"
10462
+ description: "Create or update a project-scoped environment variable"
10409
10463
  },
10410
10464
  args: {
10411
10465
  keyValue: {
@@ -10416,47 +10470,46 @@ const setCommand$1 = defineCommand({
10416
10470
  environment: {
10417
10471
  type: "string",
10418
10472
  default: "production",
10419
- description: "Target environment"
10473
+ description: "Target environments (comma-separated, e.g. development,production). Default: production"
10420
10474
  },
10421
10475
  visibility: {
10422
10476
  type: "enum",
10423
- options: [
10424
- "plaintext",
10425
- "sensitive",
10426
- "secret"
10427
- ],
10477
+ options: ["plaintext", "sensitive"],
10428
10478
  default: "plaintext",
10429
10479
  description: "Value visibility"
10430
10480
  }
10431
10481
  },
10432
10482
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10433
10483
  const { key, value } = yield* parseKeyValue(args.keyValue);
10434
- const { environment } = args;
10484
+ const environments = yield* parseEnvironmentsArg(args.environment);
10435
10485
  const { visibility } = args;
10436
10486
  const projectId = yield* readProjectId;
10437
10487
  const api = yield* apiClient;
10438
10488
  const match = (yield* api["env-vars"].list({ urlParams: {
10439
10489
  projectId,
10440
- environment
10490
+ scope: "project"
10441
10491
  } })).items.find((item) => item.key === key);
10492
+ const label = formatEnvironments(environments);
10442
10493
  if (match) {
10443
10494
  yield* api["env-vars"].update({
10444
10495
  path: { id: match.id },
10445
10496
  payload: {
10446
10497
  value,
10447
- visibility
10498
+ visibility,
10499
+ environments
10448
10500
  }
10449
10501
  });
10450
- yield* Console.log(`Updated ${key} in ${environment}`);
10502
+ yield* Console.log(`Updated ${key} (environments: ${label})`);
10451
10503
  } else {
10452
10504
  yield* api["env-vars"].create({ payload: {
10505
+ scope: "project",
10453
10506
  projectId,
10454
- environment,
10507
+ environments,
10455
10508
  key,
10456
10509
  value,
10457
10510
  visibility
10458
10511
  } });
10459
- yield* Console.log(`Created ${key} in ${environment}`);
10512
+ yield* Console.log(`Created ${key} (environments: ${label})`);
10460
10513
  }
10461
10514
  }), envErrorExtras)
10462
10515
  });
@@ -10466,7 +10519,7 @@ const setCommand$1 = defineCommand({
10466
10519
  const updateCommand$1 = defineCommand({
10467
10520
  meta: {
10468
10521
  name: "update",
10469
- description: "Update an env var's value or visibility"
10522
+ description: "Update a project env var's value, visibility, or environments"
10470
10523
  },
10471
10524
  args: {
10472
10525
  key: {
@@ -10480,32 +10533,29 @@ const updateCommand$1 = defineCommand({
10480
10533
  },
10481
10534
  visibility: {
10482
10535
  type: "enum",
10483
- options: [
10484
- "plaintext",
10485
- "sensitive",
10486
- "secret"
10487
- ],
10536
+ options: ["plaintext", "sensitive"],
10488
10537
  description: "New visibility (leave unset to keep current)"
10489
10538
  },
10490
- environment: {
10539
+ environments: {
10491
10540
  type: "string",
10492
- default: "production",
10493
- description: "Target environment"
10541
+ description: "New environments assignment (comma-separated, e.g. development,production). Leave unset to keep current."
10494
10542
  }
10495
10543
  },
10496
10544
  run: async ({ args }) => runEffect(Effect.gen(function* () {
10497
- const { key, value, visibility, environment } = args;
10498
- if (value === void 0 && visibility === void 0) return yield* new InvalidArgumentError({ message: "Pass --value, --visibility, or both. Nothing to update otherwise." });
10545
+ const { key, value, visibility, environments } = args;
10546
+ if (value === void 0 && visibility === void 0 && environments === void 0) return yield* new InvalidArgumentError({ message: "Pass --value, --visibility, --environments (or any combination). Nothing to update otherwise." });
10499
10547
  const projectId = yield* readProjectId;
10500
10548
  const api = yield* apiClient;
10501
10549
  const match = (yield* api["env-vars"].list({ urlParams: {
10502
10550
  projectId,
10503
- environment
10551
+ scope: "project"
10504
10552
  } })).items.find((item) => item.key === key);
10505
- if (!match) return yield* new EnvResourceNotFoundError({ message: `Env var "${key}" not found in environment "${environment}".` });
10553
+ if (!match) return yield* new EnvResourceNotFoundError({ message: `Env var "${key}" not found in project.` });
10554
+ const envList = environments ? yield* parseEnvironmentsArg(environments) : void 0;
10506
10555
  const payload = {
10507
10556
  ...value === void 0 ? {} : { value },
10508
- ...visibility === void 0 ? {} : { visibility }
10557
+ ...visibility === void 0 ? {} : { visibility },
10558
+ ...envList ? { environments: envList } : {}
10509
10559
  };
10510
10560
  yield* api["env-vars"].update({
10511
10561
  path: { id: match.id },
@@ -10514,7 +10564,8 @@ const updateCommand$1 = defineCommand({
10514
10564
  const changed = [];
10515
10565
  if (value !== void 0) changed.push("value");
10516
10566
  if (visibility !== void 0) changed.push("visibility");
10517
- yield* printHuman(`Updated ${changed.join(" + ")} for ${key} in ${environment}.`);
10567
+ if (envList) changed.push("environments");
10568
+ yield* printHuman(`Updated ${changed.join(" + ")} for ${key}.`);
10518
10569
  }), envErrorExtras)
10519
10570
  });
10520
10571