@autohq/cli 0.1.200 → 0.1.202

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.
@@ -19734,6 +19734,7 @@ var AuthScopeSchema = external_exports.enum([
19734
19734
  "secrets:read",
19735
19735
  "secrets:write",
19736
19736
  "secrets:use",
19737
+ "secret-values:read",
19737
19738
  "github:mcp",
19738
19739
  "github:credentials",
19739
19740
  "projects:admin",
@@ -21115,7 +21116,13 @@ var EncryptedSecretValueSchema = external_exports.object({
21115
21116
  dekIv: SecretAesGcmIvSchema,
21116
21117
  dekAuthTag: SecretAesGcmAuthTagSchema
21117
21118
  });
21119
+ var SecretDescriptionSchema = external_exports.string().trim().max(1024);
21118
21120
  var SecretSetRequestSchema = external_exports.object({
21121
+ value: external_exports.string(),
21122
+ description: SecretDescriptionSchema.nullable().optional(),
21123
+ protected: external_exports.boolean().optional()
21124
+ });
21125
+ var SecretRotateRequestSchema = external_exports.object({
21119
21126
  value: external_exports.string()
21120
21127
  });
21121
21128
  var SecretMetadataSchema = external_exports.object({
@@ -21123,8 +21130,12 @@ var SecretMetadataSchema = external_exports.object({
21123
21130
  organizationId: external_exports.string().trim().min(1),
21124
21131
  projectId: external_exports.string().trim().min(1).nullable(),
21125
21132
  name: ResourceNameSchema,
21133
+ description: external_exports.string().nullable(),
21134
+ protected: external_exports.boolean(),
21126
21135
  createdAt: external_exports.string().datetime(),
21127
- updatedAt: external_exports.string().datetime()
21136
+ updatedAt: external_exports.string().datetime(),
21137
+ lastRotatedAt: external_exports.string().datetime().nullable(),
21138
+ lastAccessedAt: external_exports.string().datetime().nullable()
21128
21139
  });
21129
21140
  var SecretSetResponseSchema = external_exports.object({
21130
21141
  secret: SecretMetadataSchema
@@ -21135,6 +21146,10 @@ var SecretListResponseSchema = external_exports.object({
21135
21146
  var SecretDeleteResponseSchema = external_exports.object({
21136
21147
  secret: SecretMetadataSchema
21137
21148
  });
21149
+ var SecretRevealResponseSchema = external_exports.object({
21150
+ secret: SecretMetadataSchema,
21151
+ value: external_exports.string()
21152
+ });
21138
21153
 
21139
21154
  // ../../packages/schemas/src/tools.ts
21140
21155
  var REMOTE_MCP_TRANSPORTS = ["streamable_http"];
@@ -26641,7 +26656,7 @@ Object.assign(lookup, {
26641
26656
  // package.json
26642
26657
  var package_default = {
26643
26658
  name: "@autohq/cli",
26644
- version: "0.1.200",
26659
+ version: "0.1.202",
26645
26660
  license: "SEE LICENSE IN README.md",
26646
26661
  publishConfig: {
26647
26662
  access: "public"
package/dist/index.js CHANGED
@@ -15257,6 +15257,7 @@ var init_auth = __esm({
15257
15257
  "secrets:read",
15258
15258
  "secrets:write",
15259
15259
  "secrets:use",
15260
+ "secret-values:read",
15260
15261
  "github:mcp",
15261
15262
  "github:credentials",
15262
15263
  "projects:admin",
@@ -16789,7 +16790,7 @@ var init_mounts = __esm({
16789
16790
  });
16790
16791
 
16791
16792
  // ../../packages/schemas/src/secrets.ts
16792
- var SECRET_ENCRYPTION_ALGORITHM, SecretEnvNameSchema, SecretCiphertextFieldSchema, SecretAesGcmIvSchema, SecretAesGcmAuthTagSchema, SecretEnvValueSchema, SecretEnvSchema, EncryptedSecretValueSchema, SecretSetRequestSchema, SecretMetadataSchema, SecretSetResponseSchema, SecretListResponseSchema, SecretDeleteResponseSchema;
16793
+ var SECRET_ENCRYPTION_ALGORITHM, SecretEnvNameSchema, SecretCiphertextFieldSchema, SecretAesGcmIvSchema, SecretAesGcmAuthTagSchema, SecretEnvValueSchema, SecretEnvSchema, EncryptedSecretValueSchema, SecretDescriptionSchema, SecretSetRequestSchema, SecretRotateRequestSchema, SecretMetadataSchema, SecretSetResponseSchema, SecretListResponseSchema, SecretDeleteResponseSchema, SecretRevealResponseSchema;
16793
16794
  var init_secrets = __esm({
16794
16795
  "../../packages/schemas/src/secrets.ts"() {
16795
16796
  "use strict";
@@ -16821,7 +16822,13 @@ var init_secrets = __esm({
16821
16822
  dekIv: SecretAesGcmIvSchema,
16822
16823
  dekAuthTag: SecretAesGcmAuthTagSchema
16823
16824
  });
16825
+ SecretDescriptionSchema = external_exports.string().trim().max(1024);
16824
16826
  SecretSetRequestSchema = external_exports.object({
16827
+ value: external_exports.string(),
16828
+ description: SecretDescriptionSchema.nullable().optional(),
16829
+ protected: external_exports.boolean().optional()
16830
+ });
16831
+ SecretRotateRequestSchema = external_exports.object({
16825
16832
  value: external_exports.string()
16826
16833
  });
16827
16834
  SecretMetadataSchema = external_exports.object({
@@ -16829,8 +16836,12 @@ var init_secrets = __esm({
16829
16836
  organizationId: external_exports.string().trim().min(1),
16830
16837
  projectId: external_exports.string().trim().min(1).nullable(),
16831
16838
  name: ResourceNameSchema,
16839
+ description: external_exports.string().nullable(),
16840
+ protected: external_exports.boolean(),
16832
16841
  createdAt: external_exports.string().datetime(),
16833
- updatedAt: external_exports.string().datetime()
16842
+ updatedAt: external_exports.string().datetime(),
16843
+ lastRotatedAt: external_exports.string().datetime().nullable(),
16844
+ lastAccessedAt: external_exports.string().datetime().nullable()
16834
16845
  });
16835
16846
  SecretSetResponseSchema = external_exports.object({
16836
16847
  secret: SecretMetadataSchema
@@ -16841,6 +16852,10 @@ var init_secrets = __esm({
16841
16852
  SecretDeleteResponseSchema = external_exports.object({
16842
16853
  secret: SecretMetadataSchema
16843
16854
  });
16855
+ SecretRevealResponseSchema = external_exports.object({
16856
+ secret: SecretMetadataSchema,
16857
+ value: external_exports.string()
16858
+ });
16844
16859
  }
16845
16860
  });
16846
16861
 
@@ -20568,20 +20583,38 @@ function createApiClient(input) {
20568
20583
  }),
20569
20584
  async setSecret(name, request, options = {}) {
20570
20585
  const organization = await activeOrganization();
20571
- const path2 = options.projectId ? projectApiPath(
20586
+ const path2 = secretPath(
20587
+ organization.organizationId,
20588
+ options.projectId,
20589
+ name
20590
+ );
20591
+ const response = await authenticatedFetch(
20592
+ apiUrl(path2, options.apiBaseUrl),
20572
20593
  {
20573
- organizationId: organization.organizationId,
20574
- projectId: options.projectId
20594
+ method: "PUT",
20595
+ headers: {
20596
+ "content-type": "application/json"
20597
+ },
20598
+ body: JSON.stringify(request)
20575
20599
  },
20576
- `/secrets/${encodeURIComponent(name)}`
20577
- ) : orgApiPath(
20600
+ options.apiBaseUrl
20601
+ );
20602
+ if (!response.ok) {
20603
+ throw new Error(await responseErrorMessage(response));
20604
+ }
20605
+ return SecretSetResponseSchema.parse(await response.json());
20606
+ },
20607
+ async rotateSecret(name, request, options = {}) {
20608
+ const organization = await activeOrganization();
20609
+ const path2 = secretPath(
20578
20610
  organization.organizationId,
20579
- `/secrets/${encodeURIComponent(name)}`
20611
+ options.projectId,
20612
+ name
20580
20613
  );
20581
20614
  const response = await authenticatedFetch(
20582
20615
  apiUrl(path2, options.apiBaseUrl),
20583
20616
  {
20584
- method: "PUT",
20617
+ method: "PATCH",
20585
20618
  headers: {
20586
20619
  "content-type": "application/json"
20587
20620
  },
@@ -20594,6 +20627,19 @@ function createApiClient(input) {
20594
20627
  }
20595
20628
  return SecretSetResponseSchema.parse(await response.json());
20596
20629
  },
20630
+ async revealSecret(name, options = {}) {
20631
+ const organization = await activeOrganization();
20632
+ const path2 = `${secretPath(organization.organizationId, options.projectId, name)}/value`;
20633
+ const response = await authenticatedFetch(
20634
+ apiUrl(path2, options.apiBaseUrl),
20635
+ {},
20636
+ options.apiBaseUrl
20637
+ );
20638
+ if (!response.ok) {
20639
+ throw new Error(await responseErrorMessage(response));
20640
+ }
20641
+ return SecretRevealResponseSchema.parse(await response.json());
20642
+ },
20597
20643
  async listSecrets(options = {}) {
20598
20644
  const organization = await activeOrganization();
20599
20645
  const path2 = options.projectId ? projectApiPath(
@@ -20615,15 +20661,10 @@ function createApiClient(input) {
20615
20661
  },
20616
20662
  async removeSecret(name, options = {}) {
20617
20663
  const organization = await activeOrganization();
20618
- const path2 = options.projectId ? projectApiPath(
20619
- {
20620
- organizationId: organization.organizationId,
20621
- projectId: options.projectId
20622
- },
20623
- `/secrets/${encodeURIComponent(name)}`
20624
- ) : orgApiPath(
20664
+ const path2 = secretPath(
20625
20665
  organization.organizationId,
20626
- `/secrets/${encodeURIComponent(name)}`
20666
+ options.projectId,
20667
+ name
20627
20668
  );
20628
20669
  const response = await authenticatedFetch(
20629
20670
  apiUrl(path2, options.apiBaseUrl),
@@ -21066,6 +21107,10 @@ function createApiClient(input) {
21066
21107
  }
21067
21108
  };
21068
21109
  }
21110
+ function secretPath(organizationId, projectId, name) {
21111
+ const subpath = `/secrets/${encodeURIComponent(name)}`;
21112
+ return projectId ? projectApiPath({ organizationId, projectId }, subpath) : orgApiPath(organizationId, subpath);
21113
+ }
21069
21114
  function runListSearchParams(options) {
21070
21115
  const searchParams = [];
21071
21116
  if (options.includeArchived) {
@@ -21624,7 +21669,7 @@ var init_package = __esm({
21624
21669
  "package.json"() {
21625
21670
  package_default = {
21626
21671
  name: "@autohq/cli",
21627
- version: "0.1.200",
21672
+ version: "0.1.202",
21628
21673
  license: "SEE LICENSE IN README.md",
21629
21674
  publishConfig: {
21630
21675
  access: "public"
@@ -35101,7 +35146,11 @@ async function setSecret(input) {
35101
35146
  });
35102
35147
  const response = await input.client.setSecret(
35103
35148
  input.name,
35104
- { value },
35149
+ {
35150
+ value,
35151
+ ...input.commandOptions.description === void 0 ? {} : { description: input.commandOptions.description },
35152
+ ...resolveProtectedFlag(input.commandOptions)
35153
+ },
35105
35154
  {
35106
35155
  projectId: await secretProjectId(input),
35107
35156
  apiBaseUrl: input.commandOptions.apiBaseUrl
@@ -35109,6 +35158,29 @@ async function setSecret(input) {
35109
35158
  );
35110
35159
  writeSetResponse(response, input);
35111
35160
  }
35161
+ async function rotateSecret(input) {
35162
+ const value = await secretValue({
35163
+ options: input.commandOptions,
35164
+ env: input.context.env,
35165
+ stdin: input.context.stdin
35166
+ });
35167
+ const response = await input.client.rotateSecret(
35168
+ input.name,
35169
+ { value },
35170
+ {
35171
+ projectId: await secretProjectId(input),
35172
+ apiBaseUrl: input.commandOptions.apiBaseUrl
35173
+ }
35174
+ );
35175
+ writeRotateResponse(response, input);
35176
+ }
35177
+ async function revealSecret(input) {
35178
+ const response = await input.client.revealSecret(input.name, {
35179
+ projectId: await secretProjectId(input),
35180
+ apiBaseUrl: input.commandOptions.apiBaseUrl
35181
+ });
35182
+ writeRevealResponse(response, input);
35183
+ }
35112
35184
  async function listSecrets(input) {
35113
35185
  const response = await input.client.listSecrets({
35114
35186
  projectId: await secretProjectId(input),
@@ -35123,11 +35195,24 @@ async function listSecrets(input) {
35123
35195
  return;
35124
35196
  }
35125
35197
  for (const secret of response.secrets) {
35198
+ const flags = secret.protected ? "protected" : "revealable";
35126
35199
  input.context.writeOutput(
35127
- `${secret.name} ${scopeLabel(secret.projectId)} updated ${secret.updatedAt}`
35200
+ `${secret.name} ${scopeLabel(secret.projectId)} ${flags} updated ${secret.updatedAt}`
35128
35201
  );
35129
35202
  }
35130
35203
  }
35204
+ function resolveProtectedFlag(options) {
35205
+ if (options.protected && options.unprotected) {
35206
+ throw new Error("Use only one of --protected or --unprotected.");
35207
+ }
35208
+ if (options.protected) {
35209
+ return { protected: true };
35210
+ }
35211
+ if (options.unprotected) {
35212
+ return { protected: false };
35213
+ }
35214
+ return {};
35215
+ }
35131
35216
  async function removeSecret(input) {
35132
35217
  await confirmDestructiveAction(input.context, {
35133
35218
  message: `This will remove secret "${input.name}".`,
@@ -35200,6 +35285,22 @@ function writeSetResponse(response, input) {
35200
35285
  `secret ${response.secret.name} updated scope=${scopeLabel(response.secret.projectId)}`
35201
35286
  );
35202
35287
  }
35288
+ function writeRotateResponse(response, input) {
35289
+ if (input.commandOptions.json) {
35290
+ input.context.writeOutput(JSON.stringify(response));
35291
+ return;
35292
+ }
35293
+ input.context.writeOutput(
35294
+ `secret ${response.secret.name} rotated scope=${scopeLabel(response.secret.projectId)}`
35295
+ );
35296
+ }
35297
+ function writeRevealResponse(response, input) {
35298
+ if (input.commandOptions.json) {
35299
+ input.context.writeOutput(JSON.stringify(response));
35300
+ return;
35301
+ }
35302
+ input.context.writeOutput(response.value);
35303
+ }
35203
35304
  function writeRemoveResponse(response, input) {
35204
35305
  if (input.commandOptions.json) {
35205
35306
  input.context.writeOutput(JSON.stringify(response));
@@ -35213,12 +35314,62 @@ function scopeLabel(projectId) {
35213
35314
  return projectId ? `project:${projectId}` : "organization";
35214
35315
  }
35215
35316
 
35317
+ // src/commands/secrets/view.ts
35318
+ init_base_url();
35319
+ init_browser();
35320
+ init_file();
35321
+ async function viewSecrets(input) {
35322
+ const scope = await resolveSecretsScope(input);
35323
+ const url2 = secretsSettingsUrl({
35324
+ webBaseUrl: resolveSecretsWebBaseUrl(input),
35325
+ ...scope
35326
+ });
35327
+ input.context.writeOutput(`Opening ${url2}`);
35328
+ (input.openBrowser ?? openBrowser)(url2);
35329
+ }
35330
+ function secretsSettingsUrl(input) {
35331
+ const path2 = input.projectId ? `/orgs/${input.organizationId}/projects/${input.projectId}/settings/secrets` : `/orgs/${input.organizationId}/settings/secrets`;
35332
+ return new URL(path2, input.webBaseUrl).toString();
35333
+ }
35334
+ async function resolveSecretsScope(input) {
35335
+ const client = createContextApiClient(input.context);
35336
+ if (input.commandOptions.project) {
35337
+ const scope = await requireProjectScope({
35338
+ context: input.context,
35339
+ options: input.commandOptions,
35340
+ identifier: input.commandOptions.project,
35341
+ explicitHint: "--project <project>"
35342
+ });
35343
+ const organizationId2 = scope.organizationId ?? (await client.activeOrganization()).organizationId;
35344
+ return { organizationId: organizationId2, projectId: scope.projectId };
35345
+ }
35346
+ const { organizationId } = await client.activeOrganization();
35347
+ return { organizationId };
35348
+ }
35349
+ function resolveSecretsWebBaseUrl(input) {
35350
+ const explicitWebBaseUrl = normalizeApiBaseUrl(
35351
+ input.context.env.AUTO_WEB_BASE_URL
35352
+ );
35353
+ if (explicitWebBaseUrl) {
35354
+ return explicitWebBaseUrl;
35355
+ }
35356
+ const config2 = readConfig(input.context.configPath);
35357
+ return resolveApiBaseUrl({
35358
+ explicit: apiUrlFromOptions(input.context, input.commandOptions),
35359
+ env: input.context.env,
35360
+ configServerUrl: config2.serverUrl
35361
+ });
35362
+ }
35363
+
35216
35364
  // src/commands/secrets/commands.ts
35217
35365
  function registerSecretCommands(program, context) {
35218
35366
  const secrets = program.command("secrets").description("Manage Auto organization and project secrets.");
35219
35367
  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(
35220
35368
  "--from-env <name>",
35221
35369
  "read the secret value from an environment variable"
35370
+ ).option("--description <text>", "human-readable description for the secret").option("--protected", "mark write-only: refuse plaintext reveal (default)").option(
35371
+ "--unprotected",
35372
+ "allow scope-gated plaintext reveal of this secret"
35222
35373
  ).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) => {
35223
35374
  await setSecret({
35224
35375
  client: createContextApiClient(context),
@@ -35227,6 +35378,27 @@ function registerSecretCommands(program, context) {
35227
35378
  name
35228
35379
  });
35229
35380
  });
35381
+ secrets.command("rotate").description("Replace a secret's value without printing it.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--stdin", "read the new secret value from stdin").option("--value <value>", "new secret value").option(
35382
+ "--from-env <name>",
35383
+ "read the new secret value from an environment variable"
35384
+ ).option("--raw", "allow empty values and preserve stdin exactly").option("--json", "print the rotated 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) => {
35385
+ await rotateSecret({
35386
+ client: createContextApiClient(context),
35387
+ commandOptions: withApiBaseUrl(context, commandOptions),
35388
+ context,
35389
+ name
35390
+ });
35391
+ });
35392
+ secrets.command("reveal").description(
35393
+ "Print the decrypted value of a non-protected secret (audited)."
35394
+ ).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) => {
35395
+ await revealSecret({
35396
+ client: createContextApiClient(context),
35397
+ commandOptions: withApiBaseUrl(context, commandOptions),
35398
+ context,
35399
+ name
35400
+ });
35401
+ });
35230
35402
  secrets.command("list").alias("ls").description("List secret metadata.").option("--project <project>", "project id; defaults to organization scope").option("--json", "print secret metadata as JSON").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (commandOptions) => {
35231
35403
  await listSecrets({
35232
35404
  client: createContextApiClient(context),
@@ -35234,6 +35406,9 @@ function registerSecretCommands(program, context) {
35234
35406
  context
35235
35407
  });
35236
35408
  });
35409
+ secrets.command("view").description("Open the web Secrets settings page in your browser.").option("--project <project>", "project id; defaults to organization scope").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (commandOptions) => {
35410
+ await viewSecrets({ commandOptions, context });
35411
+ });
35237
35412
  secrets.command("remove").alias("rm").description("Remove a secret.").argument("<name>", "secret name").option("--project <project>", "project id; defaults to organization scope").option("--json", "print removed secret metadata as JSON").option("-y, --yes", "skip confirmation prompt").option("--api-url <url>", "Auto API base URL").option("--api-base-url <url>", "Auto API base URL").action(async (name, commandOptions) => {
35238
35413
  await removeSecret({
35239
35414
  client: createContextApiClient(context),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@autohq/cli",
3
- "version": "0.1.200",
3
+ "version": "0.1.202",
4
4
  "license": "SEE LICENSE IN README.md",
5
5
  "publishConfig": {
6
6
  "access": "public"