@autohq/cli 0.1.364 → 0.1.366

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.
@@ -23492,7 +23492,7 @@ Object.assign(lookup, {
23492
23492
  // package.json
23493
23493
  var package_default = {
23494
23494
  name: "@autohq/cli",
23495
- version: "0.1.364",
23495
+ version: "0.1.366",
23496
23496
  license: "SEE LICENSE IN README.md",
23497
23497
  publishConfig: {
23498
23498
  access: "public"
@@ -26200,11 +26200,48 @@ var EncryptedSecretValueSchema = external_exports.object({
26200
26200
  dekAuthTag: SecretAesGcmAuthTagSchema
26201
26201
  });
26202
26202
  var SecretDescriptionSchema = external_exports.string().trim().max(1024);
26203
+ var SECRET_IDLE_EXPIRY_MAX_SECONDS = 10 * 365 * 24 * 60 * 60;
26204
+ var SecretExpiresAtSchema = external_exports.string().datetime({ offset: true });
26205
+ var SecretIdleExpirySecondsSchema = external_exports.number().int().min(1).max(SECRET_IDLE_EXPIRY_MAX_SECONDS);
26206
+ var SECRET_BINDING_HOST_PATTERN = /^(?=.{1,253}$)([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
26207
+ var SECRET_BINDING_HEADER_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
26208
+ var SECRET_BINDING_FORBIDDEN_HEADERS = /* @__PURE__ */ new Set([
26209
+ "connection",
26210
+ "content-length",
26211
+ "host",
26212
+ "transfer-encoding"
26213
+ ]);
26214
+ var SecretBindingHostSchema = external_exports.string().trim().toLowerCase().regex(
26215
+ SECRET_BINDING_HOST_PATTERN,
26216
+ "Binding hosts must be exact lowercase hostnames (no wildcards, schemes, ports, or paths)"
26217
+ );
26218
+ var SecretBindingHeaderSchema = external_exports.string().trim().min(1).max(128).regex(SECRET_BINDING_HEADER_PATTERN, "Invalid HTTP header name").refine(
26219
+ (header) => !SECRET_BINDING_FORBIDDEN_HEADERS.has(header.toLowerCase()),
26220
+ "This header cannot carry a secret binding"
26221
+ );
26222
+ var SecretBindingSchema = external_exports.object({
26223
+ hosts: external_exports.array(SecretBindingHostSchema).min(1).max(16),
26224
+ header: SecretBindingHeaderSchema,
26225
+ format: external_exports.string().min(1).max(256).refine(
26226
+ (format) => format.includes("{value}"),
26227
+ "Binding format must contain the {value} placeholder"
26228
+ ).optional()
26229
+ });
26203
26230
  var SecretSetRequestSchema = external_exports.object({
26204
26231
  value: external_exports.string(),
26205
26232
  description: SecretDescriptionSchema.nullable().optional(),
26206
- protected: external_exports.boolean().optional()
26207
- });
26233
+ protected: external_exports.boolean().optional(),
26234
+ binding: SecretBindingSchema.nullable().optional(),
26235
+ expiresAt: SecretExpiresAtSchema.nullable().optional(),
26236
+ idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
26237
+ });
26238
+ var SecretExpiryUpdateRequestSchema = external_exports.object({
26239
+ expiresAt: SecretExpiresAtSchema.nullable().optional(),
26240
+ idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
26241
+ }).refine(
26242
+ (input) => input.expiresAt !== void 0 || input.idleExpirySeconds !== void 0,
26243
+ { message: "Provide expiresAt and/or idleExpirySeconds" }
26244
+ );
26208
26245
  var SecretRotateRequestSchema = external_exports.object({
26209
26246
  value: external_exports.string()
26210
26247
  });
@@ -26215,10 +26252,21 @@ var SecretMetadataSchema = external_exports.object({
26215
26252
  name: ResourceNameSchema,
26216
26253
  description: external_exports.string().nullable(),
26217
26254
  protected: external_exports.boolean(),
26255
+ // Defaulted rather than required so a newer client parsing an older
26256
+ // server's metadata (deploy skew) treats an absent binding as unbound.
26257
+ binding: SecretBindingSchema.nullable().default(null),
26218
26258
  createdAt: external_exports.string().datetime(),
26219
26259
  updatedAt: external_exports.string().datetime(),
26220
26260
  lastRotatedAt: external_exports.string().datetime().nullable(),
26221
- lastAccessedAt: external_exports.string().datetime().nullable()
26261
+ lastAccessedAt: external_exports.string().datetime().nullable(),
26262
+ // Like binding, defaulted for deploy skew: an older server that never sends
26263
+ // expiry fields parses as a secret that never expires.
26264
+ expiresAt: external_exports.string().datetime().nullable().default(null),
26265
+ idleExpirySeconds: external_exports.number().int().nullable().default(null),
26266
+ // Computed server-side: true when expiresAt has passed or the secret has
26267
+ // been unused past idleExpirySeconds. Expired secrets resolve as absent
26268
+ // everywhere but stay listed so operators can see and delete them.
26269
+ expired: external_exports.boolean().default(false)
26222
26270
  });
26223
26271
  var SecretSetResponseSchema = external_exports.object({
26224
26272
  secret: SecretMetadataSchema
@@ -26229,6 +26277,9 @@ var SecretListResponseSchema = external_exports.object({
26229
26277
  var SecretDeleteResponseSchema = external_exports.object({
26230
26278
  secret: SecretMetadataSchema
26231
26279
  });
26280
+ var SecretExpiryUpdateResponseSchema = external_exports.object({
26281
+ secret: SecretMetadataSchema
26282
+ });
26232
26283
  var SecretRevealResponseSchema = external_exports.object({
26233
26284
  secret: SecretMetadataSchema,
26234
26285
  value: external_exports.string()
package/dist/index.js CHANGED
@@ -17599,7 +17599,7 @@ var init_mounts = __esm({
17599
17599
  });
17600
17600
 
17601
17601
  // ../../packages/schemas/src/secrets.ts
17602
- var SECRET_ENCRYPTION_ALGORITHM, SecretEnvNameSchema, SecretCiphertextFieldSchema, SecretAesGcmIvSchema, SecretAesGcmAuthTagSchema, SecretEnvValueSchema, SecretEnvSchema, EncryptedSecretValueSchema, SecretDescriptionSchema, SecretSetRequestSchema, SecretRotateRequestSchema, SecretMetadataSchema, SecretSetResponseSchema, SecretListResponseSchema, SecretDeleteResponseSchema, SecretRevealResponseSchema;
17602
+ var SECRET_ENCRYPTION_ALGORITHM, SecretEnvNameSchema, SecretCiphertextFieldSchema, SecretAesGcmIvSchema, SecretAesGcmAuthTagSchema, SecretEnvValueSchema, SecretEnvSchema, EncryptedSecretValueSchema, SecretDescriptionSchema, SECRET_IDLE_EXPIRY_MAX_SECONDS, SecretExpiresAtSchema, SecretIdleExpirySecondsSchema, SECRET_BINDING_HOST_PATTERN, SECRET_BINDING_HEADER_PATTERN, SECRET_BINDING_FORBIDDEN_HEADERS, SecretBindingHostSchema, SecretBindingHeaderSchema, SecretBindingSchema, SecretSetRequestSchema, SecretExpiryUpdateRequestSchema, SecretRotateRequestSchema, SecretMetadataSchema, SecretSetResponseSchema, SecretListResponseSchema, SecretDeleteResponseSchema, SecretExpiryUpdateResponseSchema, SecretRevealResponseSchema;
17603
17603
  var init_secrets = __esm({
17604
17604
  "../../packages/schemas/src/secrets.ts"() {
17605
17605
  "use strict";
@@ -17632,11 +17632,48 @@ var init_secrets = __esm({
17632
17632
  dekAuthTag: SecretAesGcmAuthTagSchema
17633
17633
  });
17634
17634
  SecretDescriptionSchema = external_exports.string().trim().max(1024);
17635
+ SECRET_IDLE_EXPIRY_MAX_SECONDS = 10 * 365 * 24 * 60 * 60;
17636
+ SecretExpiresAtSchema = external_exports.string().datetime({ offset: true });
17637
+ SecretIdleExpirySecondsSchema = external_exports.number().int().min(1).max(SECRET_IDLE_EXPIRY_MAX_SECONDS);
17638
+ SECRET_BINDING_HOST_PATTERN = /^(?=.{1,253}$)([a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z]([a-z0-9-]{0,61}[a-z0-9])?$/;
17639
+ SECRET_BINDING_HEADER_PATTERN = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
17640
+ SECRET_BINDING_FORBIDDEN_HEADERS = /* @__PURE__ */ new Set([
17641
+ "connection",
17642
+ "content-length",
17643
+ "host",
17644
+ "transfer-encoding"
17645
+ ]);
17646
+ SecretBindingHostSchema = external_exports.string().trim().toLowerCase().regex(
17647
+ SECRET_BINDING_HOST_PATTERN,
17648
+ "Binding hosts must be exact lowercase hostnames (no wildcards, schemes, ports, or paths)"
17649
+ );
17650
+ SecretBindingHeaderSchema = external_exports.string().trim().min(1).max(128).regex(SECRET_BINDING_HEADER_PATTERN, "Invalid HTTP header name").refine(
17651
+ (header) => !SECRET_BINDING_FORBIDDEN_HEADERS.has(header.toLowerCase()),
17652
+ "This header cannot carry a secret binding"
17653
+ );
17654
+ SecretBindingSchema = external_exports.object({
17655
+ hosts: external_exports.array(SecretBindingHostSchema).min(1).max(16),
17656
+ header: SecretBindingHeaderSchema,
17657
+ format: external_exports.string().min(1).max(256).refine(
17658
+ (format) => format.includes("{value}"),
17659
+ "Binding format must contain the {value} placeholder"
17660
+ ).optional()
17661
+ });
17635
17662
  SecretSetRequestSchema = external_exports.object({
17636
17663
  value: external_exports.string(),
17637
17664
  description: SecretDescriptionSchema.nullable().optional(),
17638
- protected: external_exports.boolean().optional()
17639
- });
17665
+ protected: external_exports.boolean().optional(),
17666
+ binding: SecretBindingSchema.nullable().optional(),
17667
+ expiresAt: SecretExpiresAtSchema.nullable().optional(),
17668
+ idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
17669
+ });
17670
+ SecretExpiryUpdateRequestSchema = external_exports.object({
17671
+ expiresAt: SecretExpiresAtSchema.nullable().optional(),
17672
+ idleExpirySeconds: SecretIdleExpirySecondsSchema.nullable().optional()
17673
+ }).refine(
17674
+ (input) => input.expiresAt !== void 0 || input.idleExpirySeconds !== void 0,
17675
+ { message: "Provide expiresAt and/or idleExpirySeconds" }
17676
+ );
17640
17677
  SecretRotateRequestSchema = external_exports.object({
17641
17678
  value: external_exports.string()
17642
17679
  });
@@ -17647,10 +17684,21 @@ var init_secrets = __esm({
17647
17684
  name: ResourceNameSchema,
17648
17685
  description: external_exports.string().nullable(),
17649
17686
  protected: external_exports.boolean(),
17687
+ // Defaulted rather than required so a newer client parsing an older
17688
+ // server's metadata (deploy skew) treats an absent binding as unbound.
17689
+ binding: SecretBindingSchema.nullable().default(null),
17650
17690
  createdAt: external_exports.string().datetime(),
17651
17691
  updatedAt: external_exports.string().datetime(),
17652
17692
  lastRotatedAt: external_exports.string().datetime().nullable(),
17653
- lastAccessedAt: external_exports.string().datetime().nullable()
17693
+ lastAccessedAt: external_exports.string().datetime().nullable(),
17694
+ // Like binding, defaulted for deploy skew: an older server that never sends
17695
+ // expiry fields parses as a secret that never expires.
17696
+ expiresAt: external_exports.string().datetime().nullable().default(null),
17697
+ idleExpirySeconds: external_exports.number().int().nullable().default(null),
17698
+ // Computed server-side: true when expiresAt has passed or the secret has
17699
+ // been unused past idleExpirySeconds. Expired secrets resolve as absent
17700
+ // everywhere but stay listed so operators can see and delete them.
17701
+ expired: external_exports.boolean().default(false)
17654
17702
  });
17655
17703
  SecretSetResponseSchema = external_exports.object({
17656
17704
  secret: SecretMetadataSchema
@@ -17661,6 +17709,9 @@ var init_secrets = __esm({
17661
17709
  SecretDeleteResponseSchema = external_exports.object({
17662
17710
  secret: SecretMetadataSchema
17663
17711
  });
17712
+ SecretExpiryUpdateResponseSchema = external_exports.object({
17713
+ secret: SecretMetadataSchema
17714
+ });
17664
17715
  SecretRevealResponseSchema = external_exports.object({
17665
17716
  secret: SecretMetadataSchema,
17666
17717
  value: external_exports.string()
@@ -30511,6 +30562,25 @@ function createApiClient(input) {
30511
30562
  }
30512
30563
  return SecretSetResponseSchema.parse(await response.json());
30513
30564
  },
30565
+ async updateSecretExpiry(name, request, options = {}) {
30566
+ const organization = await activeOrganization();
30567
+ const path2 = `${secretPath(organization.organizationId, options.projectId, name)}/expiry`;
30568
+ const response = await authenticatedFetch(
30569
+ apiUrl(path2, options.apiBaseUrl),
30570
+ {
30571
+ method: "PATCH",
30572
+ headers: {
30573
+ "content-type": "application/json"
30574
+ },
30575
+ body: JSON.stringify(request)
30576
+ },
30577
+ options.apiBaseUrl
30578
+ );
30579
+ if (!response.ok) {
30580
+ throw new Error(await responseErrorMessage(response));
30581
+ }
30582
+ return SecretExpiryUpdateResponseSchema.parse(await response.json());
30583
+ },
30514
30584
  async revealSecret(name, options = {}) {
30515
30585
  const organization = await activeOrganization();
30516
30586
  const path2 = `${secretPath(organization.organizationId, options.projectId, name)}/value`;
@@ -31577,7 +31647,7 @@ var init_package = __esm({
31577
31647
  "package.json"() {
31578
31648
  package_default = {
31579
31649
  name: "@autohq/cli",
31580
- version: "0.1.364",
31650
+ version: "0.1.366",
31581
31651
  license: "SEE LICENSE IN README.md",
31582
31652
  publishConfig: {
31583
31653
  access: "public"
@@ -50019,6 +50089,7 @@ function memberLine2(member, style) {
50019
50089
  }
50020
50090
 
50021
50091
  // src/commands/secrets/actions.ts
50092
+ init_src();
50022
50093
  async function setSecret(input) {
50023
50094
  const value = await secretValue({
50024
50095
  options: input.commandOptions,
@@ -50030,7 +50101,9 @@ async function setSecret(input) {
50030
50101
  {
50031
50102
  value,
50032
50103
  ...input.commandOptions.description === void 0 ? {} : { description: input.commandOptions.description },
50033
- ...resolveProtectedFlag(input.commandOptions)
50104
+ ...resolveProtectedFlag(input.commandOptions),
50105
+ ...resolveExpiryFields(input.commandOptions),
50106
+ ...resolveBindingFlags(input.commandOptions)
50034
50107
  },
50035
50108
  {
50036
50109
  projectId: await secretProjectId(input),
@@ -50055,6 +50128,17 @@ async function rotateSecret(input) {
50055
50128
  );
50056
50129
  writeRotateResponse(response, input);
50057
50130
  }
50131
+ async function updateSecretExpiry(input) {
50132
+ const fields = resolveExpiryFields(input.commandOptions);
50133
+ if (fields.expiresAt === void 0 && fields.idleExpirySeconds === void 0) {
50134
+ throw new Error("Provide --expires-at and/or --idle-expiry.");
50135
+ }
50136
+ const response = await input.client.updateSecretExpiry(input.name, fields, {
50137
+ projectId: await secretProjectId(input),
50138
+ apiBaseUrl: input.commandOptions.apiBaseUrl
50139
+ });
50140
+ writeExpiryResponse(response, input);
50141
+ }
50058
50142
  async function revealSecret(input) {
50059
50143
  const response = await input.client.revealSecret(input.name, {
50060
50144
  projectId: await secretProjectId(input),
@@ -50077,9 +50161,23 @@ async function listSecrets(input) {
50077
50161
  }
50078
50162
  for (const secret of response.secrets) {
50079
50163
  const flags = secret.protected ? "protected" : "revealable";
50080
- input.context.writeOutput(
50081
- `${secret.name} ${scopeLabel(secret.projectId)} ${flags} updated ${secret.updatedAt}`
50082
- );
50164
+ const parts = [
50165
+ secret.name,
50166
+ scopeLabel(secret.projectId),
50167
+ flags,
50168
+ `updated ${secret.updatedAt}`
50169
+ ];
50170
+ if (secret.expired) {
50171
+ parts.push("expired");
50172
+ } else {
50173
+ if (secret.expiresAt !== null) {
50174
+ parts.push(`expires ${secret.expiresAt}`);
50175
+ }
50176
+ if (secret.idleExpirySeconds !== null) {
50177
+ parts.push(`idle-expiry ${secret.idleExpirySeconds}s`);
50178
+ }
50179
+ }
50180
+ input.context.writeOutput(parts.join(" "));
50083
50181
  }
50084
50182
  }
50085
50183
  function resolveProtectedFlag(options) {
@@ -50094,6 +50192,67 @@ function resolveProtectedFlag(options) {
50094
50192
  }
50095
50193
  return {};
50096
50194
  }
50195
+ function parseExpiresAt(input) {
50196
+ if (input === "never") {
50197
+ return null;
50198
+ }
50199
+ const parsed = new Date(input);
50200
+ if (Number.isNaN(parsed.getTime())) {
50201
+ throw new Error(
50202
+ `Invalid --expires-at value "${input}". Use an ISO 8601 timestamp or "never".`
50203
+ );
50204
+ }
50205
+ return parsed.toISOString();
50206
+ }
50207
+ function parseIdleExpiry(input) {
50208
+ if (input === "never") {
50209
+ return null;
50210
+ }
50211
+ const match = /^(\d+)(s|m|h|d)?$/.exec(input);
50212
+ if (!match) {
50213
+ throw new Error(
50214
+ `Invalid --idle-expiry value "${input}". Use seconds or a duration like 30d, 12h, 90m, 3600s, or "never".`
50215
+ );
50216
+ }
50217
+ const unitSeconds = { s: 1, m: 60, h: 3600, d: 86400 }[match[2] ?? "s"] ?? 1;
50218
+ const seconds = Number(match[1]) * unitSeconds;
50219
+ if (seconds < 1 || seconds > SECRET_IDLE_EXPIRY_MAX_SECONDS) {
50220
+ throw new Error(
50221
+ `--idle-expiry must be between 1 second and ${SECRET_IDLE_EXPIRY_MAX_SECONDS} seconds (10 years).`
50222
+ );
50223
+ }
50224
+ return seconds;
50225
+ }
50226
+ function resolveExpiryFields(options) {
50227
+ return {
50228
+ ...options.expiresAt === void 0 ? {} : { expiresAt: parseExpiresAt(options.expiresAt) },
50229
+ ...options.idleExpiry === void 0 ? {} : { idleExpirySeconds: parseIdleExpiry(options.idleExpiry) }
50230
+ };
50231
+ }
50232
+ function resolveBindingFlags(options) {
50233
+ const hasBindingFlags = (options.bindHost?.length ?? 0) > 0 || options.bindHeader !== void 0 || options.bindFormat !== void 0;
50234
+ if (options.unbind) {
50235
+ if (hasBindingFlags) {
50236
+ throw new Error("Use either --unbind or the --bind-* flags, not both.");
50237
+ }
50238
+ return { binding: null };
50239
+ }
50240
+ if (!hasBindingFlags) {
50241
+ return {};
50242
+ }
50243
+ if (!options.bindHost?.length || options.bindHeader === void 0) {
50244
+ throw new Error(
50245
+ "Binding a secret requires at least one --bind-host and a --bind-header."
50246
+ );
50247
+ }
50248
+ return {
50249
+ binding: {
50250
+ hosts: options.bindHost,
50251
+ header: options.bindHeader,
50252
+ ...options.bindFormat === void 0 ? {} : { format: options.bindFormat }
50253
+ }
50254
+ };
50255
+ }
50097
50256
  async function removeSecret(input) {
50098
50257
  await confirmDestructiveAction(input.context, {
50099
50258
  message: `This will remove secret "${input.name}".`,
@@ -50175,6 +50334,16 @@ function writeRotateResponse(response, input) {
50175
50334
  `secret ${response.secret.name} rotated scope=${scopeLabel(response.secret.projectId)}`
50176
50335
  );
50177
50336
  }
50337
+ function writeExpiryResponse(response, input) {
50338
+ if (input.commandOptions.json) {
50339
+ input.context.writeOutput(JSON.stringify(response));
50340
+ return;
50341
+ }
50342
+ const idle = response.secret.idleExpirySeconds === null ? "never" : `${response.secret.idleExpirySeconds}s`;
50343
+ input.context.writeOutput(
50344
+ `secret ${response.secret.name} expiry updated scope=${scopeLabel(response.secret.projectId)} expires=${response.secret.expiresAt ?? "never"} idle=${idle}`
50345
+ );
50346
+ }
50178
50347
  function writeRevealResponse(response, input) {
50179
50348
  if (input.commandOptions.json) {
50180
50349
  input.context.writeOutput(JSON.stringify(response));
@@ -50248,10 +50417,27 @@ function registerSecretCommands(program, context) {
50248
50417
  secrets.command("set").description("Create or update a secret without printing its value.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--stdin", "read the secret value from stdin").option("--value <value>", "secret value").option(
50249
50418
  "--from-env <name>",
50250
50419
  "read the secret value from an environment variable"
50251
- ).option("--description <text>", "human-readable description for the secret").option("--protected", "mark write-only: refuse plaintext reveal (default)").option(
50420
+ ).option("--description <text>", "human-readable description for the secret").option(
50421
+ "--bind-host <host>",
50422
+ "bind the secret to an exact destination host (repeatable); bound secrets are injected at the sandbox edge instead of entering the sandbox",
50423
+ (host, hosts) => [...hosts, host],
50424
+ []
50425
+ ).option(
50426
+ "--bind-header <header>",
50427
+ "HTTP header the bound secret is injected into (e.g. Authorization)"
50428
+ ).option(
50429
+ "--bind-format <format>",
50430
+ 'header value template around the secret, e.g. "Bearer {value}"'
50431
+ ).option("--unbind", "clear an existing destination binding").option("--protected", "mark write-only: refuse plaintext reveal (default)").option(
50252
50432
  "--unprotected",
50253
50433
  "allow scope-gated plaintext reveal of this secret"
50254
- ).option("--raw", "allow empty values and preserve stdin exactly").option("--json", "print the updated secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
50434
+ ).option("--raw", "allow empty values and preserve stdin exactly").option(
50435
+ "--expires-at <timestamp>",
50436
+ 'absolute expiry as an ISO 8601 timestamp, or "never" to clear'
50437
+ ).option(
50438
+ "--idle-expiry <duration>",
50439
+ 'expire after this long unused (seconds or 30d/12h/90m/3600s), or "never" to clear'
50440
+ ).option("--json", "print the updated secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
50255
50441
  await setSecret({
50256
50442
  client: createContextApiClient(context),
50257
50443
  commandOptions: withApiBaseUrl(context, commandOptions),
@@ -50270,6 +50456,20 @@ function registerSecretCommands(program, context) {
50270
50456
  name
50271
50457
  });
50272
50458
  });
50459
+ secrets.command("expiry").description("Update a secret's expiry without changing its value.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option(
50460
+ "--expires-at <timestamp>",
50461
+ 'absolute expiry as an ISO 8601 timestamp, or "never" to clear'
50462
+ ).option(
50463
+ "--idle-expiry <duration>",
50464
+ 'expire after this long unused (seconds or 30d/12h/90m/3600s), or "never" to clear'
50465
+ ).option("--json", "print the updated secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
50466
+ await updateSecretExpiry({
50467
+ client: createContextApiClient(context),
50468
+ commandOptions: withApiBaseUrl(context, commandOptions),
50469
+ context,
50470
+ name
50471
+ });
50472
+ });
50273
50473
  secrets.command("reveal").description(
50274
50474
  "Print the decrypted value of a non-protected secret (audited)."
50275
50475
  ).argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--json", "print the secret value and metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.364",
3
+ "version": "0.1.366",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"