@anythingai/cli 0.1.1 → 0.1.2

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/js/bin.mjs CHANGED
@@ -3069,7 +3069,7 @@ function errorCodeFromHttpStatus(status) {
3069
3069
 
3070
3070
  //#endregion
3071
3071
  //#region package.json
3072
- var version = "0.1.1";
3072
+ var version = "0.1.2";
3073
3073
 
3074
3074
  //#endregion
3075
3075
  //#region generated/core/bodySerializer.gen.ts
@@ -4140,6 +4140,19 @@ const deleteV0ApiProjectsByProjectGroupIdAssetsByAssetId = (options) => (options
4140
4140
  ...options
4141
4141
  });
4142
4142
  /**
4143
+ * Delete a database
4144
+ *
4145
+ * Soft-deletes a user database and schedules permanent removal of the underlying infrastructure after a 30-day grace period.
4146
+ */
4147
+ const deleteV0ApiDatabasesByDatabaseId = (options) => (options.client ?? client).delete({
4148
+ security: [{
4149
+ scheme: "basic",
4150
+ type: "http"
4151
+ }],
4152
+ url: "/v0/api/databases/{databaseId}",
4153
+ ...options
4154
+ });
4155
+ /**
4143
4156
  * Get a single database
4144
4157
  *
4145
4158
  * Returns details for a specific user database.
@@ -4736,6 +4749,12 @@ var AnythingApiClient = class {
4736
4749
  path: { databaseId }
4737
4750
  }));
4738
4751
  }
4752
+ async deleteDatabase({ databaseId }) {
4753
+ return this.toResult(await deleteV0ApiDatabasesByDatabaseId({
4754
+ client: this.client,
4755
+ path: { databaseId }
4756
+ }));
4757
+ }
4739
4758
  async addDomain({ organizationId, domain, projectGroupId }) {
4740
4759
  return this.toResult(await postV0ApiDomains({
4741
4760
  client: this.client,
@@ -4790,12 +4809,17 @@ var AnythingApiClient = class {
4790
4809
  });
4791
4810
  }
4792
4811
  async inviteMember({ organizationId, email, role }) {
4812
+ const normalizedRole = role !== null ? toMemberRole(role) : null;
4813
+ if (role !== null && normalizedRole === null) return err({
4814
+ message: `Invalid role: ${role}. Expected one of owner, admin, editor, viewer.`,
4815
+ status: 400
4816
+ });
4793
4817
  return this.toResult(await postV0ApiOrganizationsByOrganizationIdInvites({
4794
4818
  client: this.client,
4795
4819
  path: { organizationId },
4796
4820
  body: {
4797
4821
  email,
4798
- ...role !== null ? { role } : {}
4822
+ ...normalizedRole !== null ? { role: normalizedRole } : {}
4799
4823
  }
4800
4824
  }));
4801
4825
  }
@@ -4876,13 +4900,13 @@ function extractErrorCode(details) {
4876
4900
  const parsed = DetailsWithCodeSchema.safeParse(details);
4877
4901
  return parsed.success ? parsed.data.code : null;
4878
4902
  }
4879
- function outputError({ argv, command, error, hint, exitCode }) {
4903
+ function outputError({ argv, command, error, hint, exitCode, buildLogs, code: codeOverride }) {
4880
4904
  const status = "status" in error ? error.status ?? null : null;
4881
4905
  const details = "details" in error ? error.details : void 0;
4882
4906
  const retryAfter = "retryAfter" in error && typeof error.retryAfter === "number" ? error.retryAfter : null;
4883
4907
  const resolvedHint = hint ?? ("hint" in error && typeof error.hint === "string" ? error.hint : void 0);
4884
4908
  process.exitCode = exitCode ?? exitCodeFromHttpStatus(status);
4885
- const code = extractErrorCode(details) ?? (status === null && exitCode !== void 0 ? errorCodeFromExitCode(exitCode) : errorCodeFromHttpStatus(status));
4909
+ const code = codeOverride ?? extractErrorCode(details) ?? (status === null && exitCode !== void 0 ? errorCodeFromExitCode(exitCode) : errorCodeFromHttpStatus(status));
4886
4910
  if (argv.json || argv.quiet) {
4887
4911
  console.error(JSON.stringify({
4888
4912
  ok: false,
@@ -4891,7 +4915,8 @@ function outputError({ argv, command, error, hint, exitCode }) {
4891
4915
  code,
4892
4916
  message: error.message,
4893
4917
  ...resolvedHint ? { hint: resolvedHint } : {},
4894
- ...retryAfter !== null ? { retry_after_seconds: retryAfter } : {}
4918
+ ...retryAfter !== null ? { retry_after_seconds: retryAfter } : {},
4919
+ ...buildLogs ? { buildLogs } : {}
4895
4920
  }
4896
4921
  }, null, 2));
4897
4922
  return;
@@ -4903,6 +4928,7 @@ function outputError({ argv, command, error, hint, exitCode }) {
4903
4928
  });
4904
4929
  if (retryAfter !== null) console.error(` ${styleText("dim", `Retry after ${retryAfter}s`)}`);
4905
4930
  if (resolvedHint) console.error(` ${styleText("dim", resolvedHint)}`);
4931
+ if (buildLogs) console.error(`\n${styleText("dim", "Build logs:")}\n${buildLogs}`);
4906
4932
  }
4907
4933
  function outputValidationError({ argv, command, message, hint }) {
4908
4934
  outputError({
@@ -5110,15 +5136,15 @@ const list$2 = {
5110
5136
  });
5111
5137
  return;
5112
5138
  }
5113
- if (argv.quiet) {
5114
- for (const asset of result.value.assets) console.log(asset.id);
5115
- return;
5116
- }
5117
- if (outputSuccess({
5139
+ if (argv.json && outputSuccess({
5118
5140
  argv,
5119
5141
  command,
5120
5142
  data: result.value
5121
5143
  })) return;
5144
+ if (argv.quiet) {
5145
+ for (const asset of result.value.assets) console.log(asset.id);
5146
+ return;
5147
+ }
5122
5148
  const { assets } = result.value;
5123
5149
  if (assets.length === 0) {
5124
5150
  console.log("No assets found.");
@@ -5214,7 +5240,7 @@ const assetsCommand = {
5214
5240
 
5215
5241
  //#endregion
5216
5242
  //#region src/commands/dev.ts
5217
- const COMMAND$26 = "dev";
5243
+ const COMMAND$27 = "dev";
5218
5244
  const devCommand = {
5219
5245
  command: "dev [state]",
5220
5246
  describe: "Toggle local dev mode so commands target your local dev stack",
@@ -5234,7 +5260,7 @@ const devCommand = {
5234
5260
  const apiUrl = resolveApiUrl({ apiUrl: argv.apiUrl });
5235
5261
  if (outputSuccess({
5236
5262
  argv,
5237
- command: COMMAND$26,
5263
+ command: COMMAND$27,
5238
5264
  data: {
5239
5265
  devMode: enabled,
5240
5266
  apiUrl
@@ -5774,7 +5800,7 @@ const authCommand = {
5774
5800
 
5775
5801
  //#endregion
5776
5802
  //#region src/commands/database-connect.ts
5777
- const COMMAND$25 = "databases connect";
5803
+ const COMMAND$26 = "databases connect";
5778
5804
  function maskConnectionString(connectionString) {
5779
5805
  return connectionString.replace(/(\/\/[^:/?#@]+:)[^@/?#]*(@)/, "$1****$2");
5780
5806
  }
@@ -5798,7 +5824,7 @@ const databaseConnectCommand = {
5798
5824
  if (config.isErr()) {
5799
5825
  outputError({
5800
5826
  argv,
5801
- command: COMMAND$25,
5827
+ command: COMMAND$26,
5802
5828
  error: {
5803
5829
  message: config.error.message,
5804
5830
  status: null
@@ -5811,7 +5837,7 @@ const databaseConnectCommand = {
5811
5837
  if (result.isErr()) {
5812
5838
  outputError({
5813
5839
  argv,
5814
- command: COMMAND$25,
5840
+ command: COMMAND$26,
5815
5841
  error: result.error
5816
5842
  });
5817
5843
  return;
@@ -5819,7 +5845,7 @@ const databaseConnectCommand = {
5819
5845
  const connectionString = argv.mask ? maskConnectionString(result.value.connectionString) : result.value.connectionString;
5820
5846
  if (outputSuccess({
5821
5847
  argv,
5822
- command: COMMAND$25,
5848
+ command: COMMAND$26,
5823
5849
  data: {
5824
5850
  ...result.value,
5825
5851
  connectionString
@@ -5876,7 +5902,7 @@ async function resolveOrgId({ flagOrg, config, nonInteractive }) {
5876
5902
 
5877
5903
  //#endregion
5878
5904
  //#region src/commands/database-create.ts
5879
- const COMMAND$24 = "databases create";
5905
+ const COMMAND$25 = "databases create";
5880
5906
  const databaseCreateCommand = {
5881
5907
  command: "create",
5882
5908
  describe: "Create a new database for a project",
@@ -5895,7 +5921,7 @@ const databaseCreateCommand = {
5895
5921
  if (!name) {
5896
5922
  outputError({
5897
5923
  argv,
5898
- command: COMMAND$24,
5924
+ command: COMMAND$25,
5899
5925
  error: {
5900
5926
  message: "Database name is required. Pass --name <name>.",
5901
5927
  status: null
@@ -5911,7 +5937,7 @@ const databaseCreateCommand = {
5911
5937
  if (config.isErr()) {
5912
5938
  outputError({
5913
5939
  argv,
5914
- command: COMMAND$24,
5940
+ command: COMMAND$25,
5915
5941
  error: {
5916
5942
  message: config.error.message,
5917
5943
  status: null
@@ -5928,7 +5954,7 @@ const databaseCreateCommand = {
5928
5954
  if (!orgResult.ok) {
5929
5955
  outputError({
5930
5956
  argv,
5931
- command: COMMAND$24,
5957
+ command: COMMAND$25,
5932
5958
  error: {
5933
5959
  message: orgResult.error,
5934
5960
  status: null
@@ -5940,7 +5966,7 @@ const databaseCreateCommand = {
5940
5966
  if (argv["dry-run"]) {
5941
5967
  outputDryRun({
5942
5968
  argv,
5943
- command: COMMAND$24,
5969
+ command: COMMAND$25,
5944
5970
  plannedActions: [{
5945
5971
  action: "create_database",
5946
5972
  org: orgResult.orgId,
@@ -5958,14 +5984,14 @@ const databaseCreateCommand = {
5958
5984
  if (result.isErr()) {
5959
5985
  outputError({
5960
5986
  argv,
5961
- command: COMMAND$24,
5987
+ command: COMMAND$25,
5962
5988
  error: result.error
5963
5989
  });
5964
5990
  return;
5965
5991
  }
5966
5992
  if (outputSuccess({
5967
5993
  argv,
5968
- command: COMMAND$24,
5994
+ command: COMMAND$25,
5969
5995
  data: result.value.database,
5970
5996
  primaryId: result.value.database.id
5971
5997
  })) return;
@@ -5978,7 +6004,7 @@ const databaseCreateCommand = {
5978
6004
 
5979
6005
  //#endregion
5980
6006
  //#region src/commands/database-get.ts
5981
- const COMMAND$23 = "databases get";
6007
+ const COMMAND$24 = "databases get";
5982
6008
  const databaseGetCommand = {
5983
6009
  command: "get <databaseId>",
5984
6010
  describe: "Inspect a database",
@@ -5995,7 +6021,7 @@ const databaseGetCommand = {
5995
6021
  if (config.isErr()) {
5996
6022
  outputError({
5997
6023
  argv,
5998
- command: COMMAND$23,
6024
+ command: COMMAND$24,
5999
6025
  error: {
6000
6026
  message: config.error.message,
6001
6027
  status: null
@@ -6008,14 +6034,14 @@ const databaseGetCommand = {
6008
6034
  if (result.isErr()) {
6009
6035
  outputError({
6010
6036
  argv,
6011
- command: COMMAND$23,
6037
+ command: COMMAND$24,
6012
6038
  error: result.error
6013
6039
  });
6014
6040
  return;
6015
6041
  }
6016
6042
  if (outputSuccess({
6017
6043
  argv,
6018
- command: COMMAND$23,
6044
+ command: COMMAND$24,
6019
6045
  data: result.value.database,
6020
6046
  primaryId: result.value.database.id
6021
6047
  })) return;
@@ -6030,7 +6056,7 @@ const databaseGetCommand = {
6030
6056
 
6031
6057
  //#endregion
6032
6058
  //#region src/commands/database-query.ts
6033
- const COMMAND$22 = "databases query";
6059
+ const COMMAND$23 = "databases query";
6034
6060
  const databaseQueryCommand = {
6035
6061
  command: "query <databaseId> <sql>",
6036
6062
  describe: "Run a read-only SQL query against a database",
@@ -6051,7 +6077,7 @@ const databaseQueryCommand = {
6051
6077
  if (config.isErr()) {
6052
6078
  outputError({
6053
6079
  argv,
6054
- command: COMMAND$22,
6080
+ command: COMMAND$23,
6055
6081
  error: {
6056
6082
  message: config.error.message,
6057
6083
  status: null
@@ -6067,7 +6093,7 @@ const databaseQueryCommand = {
6067
6093
  if (result.isErr()) {
6068
6094
  outputError({
6069
6095
  argv,
6070
- command: COMMAND$22,
6096
+ command: COMMAND$23,
6071
6097
  error: result.error,
6072
6098
  hint: "Check the database ID and SQL syntax"
6073
6099
  });
@@ -6075,7 +6101,7 @@ const databaseQueryCommand = {
6075
6101
  }
6076
6102
  if (outputSuccess({
6077
6103
  argv,
6078
- command: COMMAND$22,
6104
+ command: COMMAND$23,
6079
6105
  data: result.value
6080
6106
  })) return;
6081
6107
  if (result.value.rows.length === 0) {
@@ -6093,7 +6119,7 @@ const databaseQueryCommand = {
6093
6119
 
6094
6120
  //#endregion
6095
6121
  //#region src/commands/database-reset.ts
6096
- const COMMAND$21 = "databases reset";
6122
+ const COMMAND$22 = "databases reset";
6097
6123
  const databaseResetCommand = {
6098
6124
  command: "reset <databaseId>",
6099
6125
  describe: "Reset a database (destructive)",
@@ -6114,7 +6140,7 @@ const databaseResetCommand = {
6114
6140
  if (config.isErr()) {
6115
6141
  outputError({
6116
6142
  argv,
6117
- command: COMMAND$21,
6143
+ command: COMMAND$22,
6118
6144
  error: {
6119
6145
  message: config.error.message,
6120
6146
  status: null
@@ -6126,7 +6152,7 @@ const databaseResetCommand = {
6126
6152
  if (argv["dry-run"]) {
6127
6153
  outputDryRun({
6128
6154
  argv,
6129
- command: COMMAND$21,
6155
+ command: COMMAND$22,
6130
6156
  plannedActions: [{
6131
6157
  action: "reset_database",
6132
6158
  databaseId: argv.databaseId
@@ -6137,12 +6163,13 @@ const databaseResetCommand = {
6137
6163
  if (!argv.yes) {
6138
6164
  outputError({
6139
6165
  argv,
6140
- command: COMMAND$21,
6166
+ command: COMMAND$22,
6141
6167
  error: {
6142
6168
  message: "Database reset is destructive. Pass --yes to confirm.",
6143
6169
  status: null
6144
6170
  },
6145
- exitCode: 2
6171
+ exitCode: 2,
6172
+ code: "CONFIRMATION_REQUIRED"
6146
6173
  });
6147
6174
  return;
6148
6175
  }
@@ -6150,14 +6177,14 @@ const databaseResetCommand = {
6150
6177
  if (result.isErr()) {
6151
6178
  outputError({
6152
6179
  argv,
6153
- command: COMMAND$21,
6180
+ command: COMMAND$22,
6154
6181
  error: result.error
6155
6182
  });
6156
6183
  return;
6157
6184
  }
6158
6185
  if (outputSuccess({
6159
6186
  argv,
6160
- command: COMMAND$21,
6187
+ command: COMMAND$22,
6161
6188
  data: {
6162
6189
  reset: true,
6163
6190
  databaseId: argv.databaseId
@@ -6167,6 +6194,84 @@ const databaseResetCommand = {
6167
6194
  }
6168
6195
  };
6169
6196
 
6197
+ //#endregion
6198
+ //#region src/commands/database-delete.ts
6199
+ const COMMAND$21 = "databases delete";
6200
+ const databaseDeleteCommand = {
6201
+ command: "delete <databaseId>",
6202
+ aliases: ["remove"],
6203
+ describe: "Delete a database (destructive)",
6204
+ builder: (yargs) => yargs.positional("databaseId", {
6205
+ type: "string",
6206
+ demandOption: true,
6207
+ describe: "The database ID"
6208
+ }).option("yes", {
6209
+ type: "boolean",
6210
+ default: false,
6211
+ describe: "Skip confirmation"
6212
+ }).example("anything databases delete db_123 --yes", "Delete a database without confirmation"),
6213
+ handler: async (argv) => {
6214
+ const config = resolveConfig({
6215
+ dev: argv.dev,
6216
+ apiUrl: argv.apiUrl
6217
+ });
6218
+ if (config.isErr()) {
6219
+ outputError({
6220
+ argv,
6221
+ command: COMMAND$21,
6222
+ error: {
6223
+ message: config.error.message,
6224
+ status: null
6225
+ },
6226
+ exitCode: 4
6227
+ });
6228
+ return;
6229
+ }
6230
+ if (argv["dry-run"]) {
6231
+ outputDryRun({
6232
+ argv,
6233
+ command: COMMAND$21,
6234
+ plannedActions: [{
6235
+ action: "delete_database",
6236
+ databaseId: argv.databaseId
6237
+ }]
6238
+ });
6239
+ return;
6240
+ }
6241
+ if (!argv.yes) {
6242
+ outputError({
6243
+ argv,
6244
+ command: COMMAND$21,
6245
+ error: {
6246
+ message: "Database deletion is destructive. Pass --yes to confirm.",
6247
+ status: null
6248
+ },
6249
+ exitCode: 2,
6250
+ code: "CONFIRMATION_REQUIRED"
6251
+ });
6252
+ return;
6253
+ }
6254
+ const result = await new AnythingApiClient(config.value).deleteDatabase({ databaseId: argv.databaseId });
6255
+ if (result.isErr()) {
6256
+ outputError({
6257
+ argv,
6258
+ command: COMMAND$21,
6259
+ error: result.error
6260
+ });
6261
+ return;
6262
+ }
6263
+ if (outputSuccess({
6264
+ argv,
6265
+ command: COMMAND$21,
6266
+ data: {
6267
+ deleted: true,
6268
+ databaseId: argv.databaseId
6269
+ }
6270
+ })) return;
6271
+ printSuccess(`Database ${argv.databaseId} deleted. It can be restored within 30 days.`);
6272
+ }
6273
+ };
6274
+
6170
6275
  //#endregion
6171
6276
  //#region src/commands/list-databases.ts
6172
6277
  const COMMAND$20 = "databases list";
@@ -6211,15 +6316,15 @@ const listDatabasesCommand = {
6211
6316
  });
6212
6317
  return;
6213
6318
  }
6214
- if (argv.quiet) {
6215
- for (const db of result.value.databases) console.log(db.id);
6216
- return;
6217
- }
6218
- if (outputSuccess({
6319
+ if (argv.json && outputSuccess({
6219
6320
  argv,
6220
6321
  command: COMMAND$20,
6221
6322
  data: result.value
6222
6323
  })) return;
6324
+ if (argv.quiet) {
6325
+ for (const db of result.value.databases) console.log(db.id);
6326
+ return;
6327
+ }
6223
6328
  if (result.value.databases.length === 0) {
6224
6329
  console.log("No databases found.");
6225
6330
  return;
@@ -6254,7 +6359,7 @@ const databasesListCommand = {
6254
6359
  const databasesCommand = {
6255
6360
  command: "databases",
6256
6361
  describe: "Manage databases",
6257
- builder: (yargs) => yargs.command(databasesListCommand).command(databaseGetCommand).command(databaseCreateCommand).command(databaseQueryCommand).command(databaseConnectCommand).command(databaseResetCommand).demandCommand(1, "Specify a databases subcommand. Run `anything databases --help` for usage."),
6362
+ builder: (yargs) => yargs.command(databasesListCommand).command(databaseGetCommand).command(databaseCreateCommand).command(databaseQueryCommand).command(databaseConnectCommand).command(databaseResetCommand).command(databaseDeleteCommand).demandCommand(1, "Specify a databases subcommand. Run `anything databases --help` for usage."),
6258
6363
  handler: () => {}
6259
6364
  };
6260
6365
 
@@ -6302,15 +6407,15 @@ const deploymentsListCommand = {
6302
6407
  });
6303
6408
  return;
6304
6409
  }
6305
- if (argv.quiet) {
6306
- for (const deployment of result.value.deployments) console.log(deployment.id);
6307
- return;
6308
- }
6309
- if (outputSuccess({
6410
+ if (argv.json && outputSuccess({
6310
6411
  argv,
6311
6412
  command,
6312
6413
  data: result.value
6313
6414
  })) return;
6415
+ if (argv.quiet) {
6416
+ for (const deployment of result.value.deployments) console.log(deployment.id);
6417
+ return;
6418
+ }
6314
6419
  if (result.value.deployments.length === 0) {
6315
6420
  console.log("No deployments found.");
6316
6421
  return;
@@ -6442,20 +6547,17 @@ const deploymentsLogsCommand = {
6442
6547
  }
6443
6548
  };
6444
6549
  const deploymentsRollbackCommand = {
6445
- command: "rollback <projectId> [deploymentId]",
6446
- describe: "Rollback to a previous deployment",
6550
+ command: "rollback <projectId>",
6551
+ describe: "Roll a project back to its previous deployment",
6447
6552
  builder: (yargs) => yargs.positional("projectId", {
6448
6553
  type: "string",
6449
6554
  demandOption: true,
6450
- describe: "The project ID"
6451
- }).positional("deploymentId", {
6452
- type: "string",
6453
- describe: "Specific deployment ID to rollback to (defaults to previous)"
6555
+ describe: "The project ID to roll back"
6454
6556
  }).option("yes", {
6455
6557
  type: "boolean",
6456
6558
  default: false,
6457
6559
  describe: "Skip confirmation"
6458
- }).example("anything deployments rollback pg_123 --yes", "Rollback to previous deployment").example("anything deployments rollback pg_123 dep_456 --yes", "Rollback to specific deployment"),
6560
+ }).example("anything deployments rollback pg_123 --yes", "Roll the project back to its previous deployment"),
6459
6561
  handler: async (argv) => {
6460
6562
  const command = "deployments rollback";
6461
6563
  const config = resolveConfig({
@@ -6480,8 +6582,7 @@ const deploymentsRollbackCommand = {
6480
6582
  command,
6481
6583
  plannedActions: [{
6482
6584
  action: "rollback_deployment",
6483
- projectId: argv.projectId,
6484
- ...argv.deploymentId ? { deploymentId: argv.deploymentId } : {}
6585
+ projectId: argv.projectId
6485
6586
  }]
6486
6587
  });
6487
6588
  return;
@@ -6494,14 +6595,12 @@ const deploymentsRollbackCommand = {
6494
6595
  message: "Rollback is destructive. Pass --yes to confirm.",
6495
6596
  status: null
6496
6597
  },
6497
- exitCode: 2
6598
+ exitCode: 2,
6599
+ code: "CONFIRMATION_REQUIRED"
6498
6600
  });
6499
6601
  return;
6500
6602
  }
6501
- const result = await new AnythingApiClient(config.value).rollbackDeployment({
6502
- projectGroupId: argv.projectId,
6503
- deploymentId: argv.deploymentId ?? null
6504
- });
6603
+ const result = await new AnythingApiClient(config.value).rollbackDeployment({ projectGroupId: argv.projectId });
6505
6604
  if (result.isErr()) {
6506
6605
  outputError({
6507
6606
  argv,
@@ -6530,9 +6629,29 @@ const deploymentsCommand = {
6530
6629
  handler: () => {}
6531
6630
  };
6532
6631
 
6632
+ //#endregion
6633
+ //#region src/domains-format.ts
6634
+ function toPublicDomain(domain) {
6635
+ return {
6636
+ id: domain.id,
6637
+ domain: domain.domain,
6638
+ verified: domain.vercelVerified,
6639
+ verificationChallenges: domain.vercelVerification ?? null,
6640
+ projectGroup: domain.projectGroup
6641
+ };
6642
+ }
6643
+
6533
6644
  //#endregion
6534
6645
  //#region src/commands/domain-add.ts
6535
6646
  const COMMAND$19 = "domains add";
6647
+ const HOSTNAME_PATTERN = /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
6648
+ function domainValidationError(domain) {
6649
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(domain)) return `Enter a bare hostname without a scheme (got "${domain}"). Example: app.example.com`;
6650
+ if (domain.includes("/") || /\s/.test(domain)) return `Invalid domain "${domain}". Enter a bare hostname like app.example.com`;
6651
+ if (!domain.includes(".")) return `Invalid domain "${domain}". A domain must include a dot, e.g. app.example.com`;
6652
+ if (!HOSTNAME_PATTERN.test(domain)) return `Invalid domain "${domain}". Enter a valid hostname like app.example.com`;
6653
+ return null;
6654
+ }
6536
6655
  const domainAddCommand = {
6537
6656
  command: "add <domain>",
6538
6657
  describe: "Add a custom domain to a project",
@@ -6548,6 +6667,19 @@ const domainAddCommand = {
6548
6667
  describe: "Project ID to link the domain to"
6549
6668
  }).example("anything domains add app.example.com --project pg_123", "Add a custom domain to a project"),
6550
6669
  handler: async (argv) => {
6670
+ const validationMessage = domainValidationError(argv.domain);
6671
+ if (validationMessage) {
6672
+ outputError({
6673
+ argv,
6674
+ command: COMMAND$19,
6675
+ error: {
6676
+ message: validationMessage,
6677
+ status: null
6678
+ },
6679
+ exitCode: 2
6680
+ });
6681
+ return;
6682
+ }
6551
6683
  const config = resolveConfig({
6552
6684
  dev: argv.dev,
6553
6685
  apiUrl: argv.apiUrl
@@ -6610,7 +6742,7 @@ const domainAddCommand = {
6610
6742
  if (outputSuccess({
6611
6743
  argv,
6612
6744
  command: COMMAND$19,
6613
- data: result.value.domain,
6745
+ data: toPublicDomain(result.value.domain),
6614
6746
  primaryId: result.value.domain.domain
6615
6747
  })) return;
6616
6748
  printSuccess(`Domain added: ${result.value.domain.domain}`);
@@ -6670,7 +6802,8 @@ const domainRemoveCommand = {
6670
6802
  message: "Domain removal is destructive. Pass --yes to confirm.",
6671
6803
  status: null
6672
6804
  },
6673
- exitCode: 2
6805
+ exitCode: 2,
6806
+ code: "CONFIRMATION_REQUIRED"
6674
6807
  });
6675
6808
  return;
6676
6809
  }
@@ -6790,15 +6923,16 @@ const domainsListCommand = {
6790
6923
  });
6791
6924
  return;
6792
6925
  }
6926
+ const jsonData = { domains: result.value.domains.map(toPublicDomain) };
6927
+ if (argv.json && outputSuccess({
6928
+ argv,
6929
+ command,
6930
+ data: jsonData
6931
+ })) return;
6793
6932
  if (argv.quiet) {
6794
6933
  for (const domain of result.value.domains) console.log(domain.domain);
6795
6934
  return;
6796
6935
  }
6797
- if (outputSuccess({
6798
- argv,
6799
- command,
6800
- data: result.value
6801
- })) return;
6802
6936
  if (result.value.domains.length === 0) {
6803
6937
  console.log("No domains found.");
6804
6938
  return;
@@ -8128,6 +8262,7 @@ const linkCommand = {
8128
8262
  orgId,
8129
8263
  projectId: projectGroupId
8130
8264
  }, null, 2) + "\n");
8265
+ setStoredProjectGroupId(projResult.value.id);
8131
8266
  if (outputSuccess({
8132
8267
  argv,
8133
8268
  command,
@@ -8163,7 +8298,9 @@ const unlinkCommand = {
8163
8298
  });
8164
8299
  return;
8165
8300
  }
8301
+ const linked = readLinkedProject();
8166
8302
  rmSync(projectFile);
8303
+ if (linked && getStoredProjectGroupId() === linked.projectId) clearStoredProjectGroupId();
8167
8304
  try {
8168
8305
  if (existsSync(dir) && readdirSync(dir).length === 0) rmSync(dir, { recursive: true });
8169
8306
  } catch {}
@@ -8366,6 +8503,22 @@ const llmContextCommand = {
8366
8503
  }
8367
8504
  };
8368
8505
 
8506
+ //#endregion
8507
+ //#region src/member-roles.ts
8508
+ function formatRole(role) {
8509
+ if (role === null) return null;
8510
+ switch (role.toUpperCase()) {
8511
+ case "OWNER": return "Owner";
8512
+ case "ADMIN": return "Admin";
8513
+ case "EDITOR": return "Editor";
8514
+ case "VIEWER": return "Viewer";
8515
+ default: return role;
8516
+ }
8517
+ }
8518
+ function normalizeRole(role) {
8519
+ return role === null ? null : role.toLowerCase();
8520
+ }
8521
+
8369
8522
  //#endregion
8370
8523
  //#region src/commands/members.ts
8371
8524
  const MEMBER_ROLE_CHOICES = [
@@ -8429,7 +8582,17 @@ const membersListCommand = {
8429
8582
  if (outputSuccess({
8430
8583
  argv,
8431
8584
  command,
8432
- data: result.value
8585
+ data: {
8586
+ organization: {
8587
+ ...result.value.organization,
8588
+ role: normalizeRole(result.value.organization.role)
8589
+ },
8590
+ members: result.value.collaborators.map((collaborator) => ({
8591
+ ...collaborator,
8592
+ role: normalizeRole(collaborator.role)
8593
+ })),
8594
+ pendingInvites: result.value.pendingInvites
8595
+ }
8433
8596
  })) return;
8434
8597
  if (result.value.collaborators.length > 0) printTable({
8435
8598
  headers: [
@@ -8440,7 +8603,7 @@ const membersListCommand = {
8440
8603
  rows: result.value.collaborators.map((c) => [
8441
8604
  c.displayName,
8442
8605
  c.email ?? "-",
8443
- c.role
8606
+ formatRole(c.role) ?? c.role
8444
8607
  ])
8445
8608
  });
8446
8609
  if (result.value.pendingInvites.length > 0) {
@@ -8629,7 +8792,8 @@ const membersRemoveCommand = {
8629
8792
  message: "Member removal is destructive. Pass --yes to confirm.",
8630
8793
  status: null
8631
8794
  },
8632
- exitCode: 2
8795
+ exitCode: 2,
8796
+ code: "CONFIRMATION_REQUIRED"
8633
8797
  });
8634
8798
  return;
8635
8799
  }
@@ -8762,16 +8926,6 @@ const humanizeCredits = (credits) => {
8762
8926
 
8763
8927
  //#endregion
8764
8928
  //#region src/commands/org-members.ts
8765
- function formatRole(role) {
8766
- if (role === null) return null;
8767
- switch (role.toUpperCase()) {
8768
- case "OWNER": return "Owner";
8769
- case "ADMIN": return "Admin";
8770
- case "EDITOR": return "Editor";
8771
- case "VIEWER": return "Viewer";
8772
- default: return role;
8773
- }
8774
- }
8775
8929
  const orgMembersCommand = {
8776
8930
  command: "members <organizationId>",
8777
8931
  describe: "Inspect collaborators and pending invites for an organization",
@@ -8810,7 +8964,17 @@ const orgMembersCommand = {
8810
8964
  if (outputSuccess({
8811
8965
  argv,
8812
8966
  command,
8813
- data: result.value
8967
+ data: {
8968
+ organization: {
8969
+ ...result.value.organization,
8970
+ role: normalizeRole(result.value.organization.role)
8971
+ },
8972
+ members: result.value.collaborators.map((collaborator) => ({
8973
+ ...collaborator,
8974
+ role: normalizeRole(collaborator.role)
8975
+ })),
8976
+ pendingInvites: result.value.pendingInvites
8977
+ }
8814
8978
  })) return;
8815
8979
  console.log();
8816
8980
  printLabel("Organization", result.value.organization.name);
@@ -8856,7 +9020,7 @@ const orgMembersCommand = {
8856
9020
 
8857
9021
  //#endregion
8858
9022
  //#region src/commands/orgs.ts
8859
- async function loadOrganizations(argv) {
9023
+ async function loadOrganizations(argv, command) {
8860
9024
  const config = resolveConfig({
8861
9025
  dev: argv.dev,
8862
9026
  apiUrl: argv.apiUrl
@@ -8864,7 +9028,7 @@ async function loadOrganizations(argv) {
8864
9028
  if (config.isErr()) {
8865
9029
  outputError({
8866
9030
  argv,
8867
- command: "orgs",
9031
+ command,
8868
9032
  error: {
8869
9033
  message: config.error.message,
8870
9034
  status: null
@@ -8877,7 +9041,7 @@ async function loadOrganizations(argv) {
8877
9041
  if (result.isErr()) {
8878
9042
  outputError({
8879
9043
  argv,
8880
- command: "orgs",
9044
+ command,
8881
9045
  error: result.error
8882
9046
  });
8883
9047
  return null;
@@ -8897,7 +9061,7 @@ const getCommand = {
8897
9061
  }).example("anything orgs get org_123", "Inspect one organization in more detail").example("anything orgs get org_123 --json", "Return one organization as JSON"),
8898
9062
  handler: async (argv) => {
8899
9063
  const command = "orgs get";
8900
- const organizations = await loadOrganizations(argv);
9064
+ const organizations = await loadOrganizations(argv, command);
8901
9065
  if (!organizations) return;
8902
9066
  const organization = organizations.find((org) => org.id === argv.organizationId);
8903
9067
  if (!organization) {
@@ -8932,14 +9096,10 @@ const listOrgs = {
8932
9096
  builder: (yargs) => yargs.example("anything orgs list", "List orgs available to the current user"),
8933
9097
  handler: async (argv) => {
8934
9098
  const command = "orgs list";
8935
- const organizations = await loadOrganizations(argv);
9099
+ const organizations = await loadOrganizations(argv, command);
8936
9100
  if (!organizations) return;
8937
9101
  const activeOrgId = getStoredOrgId();
8938
- if (argv.quiet) {
8939
- for (const org of organizations) console.log(org.id);
8940
- return;
8941
- }
8942
- if (outputSuccess({
9102
+ if (argv.json && outputSuccess({
8943
9103
  argv,
8944
9104
  command,
8945
9105
  data: {
@@ -8947,6 +9107,10 @@ const listOrgs = {
8947
9107
  activeOrgId: activeOrgId ?? null
8948
9108
  }
8949
9109
  })) return;
9110
+ if (argv.quiet) {
9111
+ for (const org of organizations) console.log(org.id);
9112
+ return;
9113
+ }
8950
9114
  if (organizations.length === 0) {
8951
9115
  console.log("No organizations found.");
8952
9116
  return;
@@ -8975,7 +9139,7 @@ const setOrg = {
8975
9139
  }).example("anything orgs set org_abc123", "Set the active organization"),
8976
9140
  handler: async (argv) => {
8977
9141
  const command = "orgs set";
8978
- const organizations = await loadOrganizations(argv);
9142
+ const organizations = await loadOrganizations(argv, command);
8979
9143
  if (!organizations) return;
8980
9144
  const org = organizations.find((o) => o.id === argv["org-id"]);
8981
9145
  if (!org) {
@@ -9350,10 +9514,6 @@ const createCommand = {
9350
9514
  message: "Project created"
9351
9515
  });
9352
9516
  if (!argv.wait) {
9353
- if (argv.quiet) {
9354
- console.log(result.value.projectGroupId);
9355
- return;
9356
- }
9357
9517
  if (argv.json) {
9358
9518
  printNdjson({
9359
9519
  type: "result",
@@ -9362,6 +9522,10 @@ const createCommand = {
9362
9522
  });
9363
9523
  return;
9364
9524
  }
9525
+ if (argv.quiet) {
9526
+ console.log(result.value.projectGroupId);
9527
+ return;
9528
+ }
9365
9529
  printStreamMarker("done", `project ${result.value.projectGroupId} created`);
9366
9530
  printSuccess("App created! Generation enqueued.");
9367
9531
  printLabel("Project Group ID", result.value.projectGroupId);
@@ -9380,27 +9544,11 @@ const createCommand = {
9380
9544
  projectGroupId: result.value.projectGroupId,
9381
9545
  emit
9382
9546
  });
9383
- if (argv.quiet) {
9384
- console.log(result.value.projectGroupId);
9385
- if (succeeded === false) process.exitCode = 1;
9386
- return;
9387
- }
9388
- if (succeeded === false) {
9389
- if (!argv.json) {
9390
- outputError({
9391
- argv,
9392
- command: COMMAND$16,
9393
- error: {
9394
- message: "Generation failed.",
9395
- status: null
9396
- }
9397
- });
9398
- printLabel("Project Group ID", result.value.projectGroupId);
9399
- }
9400
- process.exitCode = 1;
9401
- return;
9402
- }
9403
9547
  if (argv.json) {
9548
+ if (succeeded === false) {
9549
+ process.exitCode = 1;
9550
+ return;
9551
+ }
9404
9552
  const { projectGroupId: projectId, ...rest } = result.value;
9405
9553
  printNdjson({
9406
9554
  type: "result",
@@ -9410,12 +9558,30 @@ const createCommand = {
9410
9558
  ...rest
9411
9559
  }
9412
9560
  });
9413
- } else {
9414
- printStreamMarker("done", `project ${result.value.projectGroupId} ready`);
9415
- printSuccess("App created! Generation complete.");
9416
- printLabel("Project ID", result.value.projectGroupId);
9417
- printLabel("Revision ID", result.value.revisionId);
9561
+ return;
9418
9562
  }
9563
+ if (argv.quiet) {
9564
+ console.log(result.value.projectGroupId);
9565
+ if (succeeded === false) process.exitCode = 1;
9566
+ return;
9567
+ }
9568
+ if (succeeded === false) {
9569
+ outputError({
9570
+ argv,
9571
+ command: COMMAND$16,
9572
+ error: {
9573
+ message: "Generation failed.",
9574
+ status: null
9575
+ }
9576
+ });
9577
+ printLabel("Project Group ID", result.value.projectGroupId);
9578
+ process.exitCode = 1;
9579
+ return;
9580
+ }
9581
+ printStreamMarker("done", `project ${result.value.projectGroupId} ready`);
9582
+ printSuccess("App created! Generation complete.");
9583
+ printLabel("Project ID", result.value.projectGroupId);
9584
+ printLabel("Revision ID", result.value.revisionId);
9419
9585
  }
9420
9586
  };
9421
9587
 
@@ -9459,14 +9625,16 @@ async function waitForDeployment({ client, deploymentId, emit }) {
9459
9625
  function getDeploymentError({ result, statusCommand }) {
9460
9626
  if (result.outcome === "timeout") return {
9461
9627
  message: `Deployment timed out. Check status with: ${statusCommand}`,
9462
- exitCode: 6
9628
+ exitCode: 6,
9629
+ buildLogs: null
9463
9630
  };
9464
9631
  if (result.deployment.status === "FAILED") {
9465
9632
  const reason = result.deployment.failureReason ?? null;
9466
9633
  const logs = result.deployment.buildLogs ?? null;
9467
9634
  return {
9468
- message: reason ? logs ? `${reason}\n\n${logs}` : reason : logs ?? "Deployment failed (no logs available).",
9469
- exitCode: 1
9635
+ message: reason ?? (logs ? "Deployment failed. See build logs for details." : "Deployment failed (no logs available)."),
9636
+ exitCode: 1,
9637
+ buildLogs: logs
9470
9638
  };
9471
9639
  }
9472
9640
  return null;
@@ -9531,7 +9699,8 @@ const publishStatusCommand = {
9531
9699
  status: null
9532
9700
  },
9533
9701
  hint: `Inspect the full build logs with: anything deployments logs ${argv.deploymentId}`,
9534
- exitCode: failure?.exitCode ?? 1
9702
+ exitCode: failure?.exitCode ?? 1,
9703
+ buildLogs: failure?.buildLogs ?? void 0
9535
9704
  });
9536
9705
  return;
9537
9706
  }
@@ -9679,7 +9848,8 @@ const publishCommand = {
9679
9848
  message: deployError.message,
9680
9849
  status: null
9681
9850
  },
9682
- exitCode: deployError.exitCode
9851
+ exitCode: deployError.exitCode,
9852
+ buildLogs: deployError.buildLogs ?? void 0
9683
9853
  });
9684
9854
  return;
9685
9855
  }
@@ -9810,15 +9980,15 @@ const list$1 = {
9810
9980
  });
9811
9981
  return;
9812
9982
  }
9813
- if (argv.quiet) {
9814
- for (const file of result.value.files) console.log(file.path);
9815
- return;
9816
- }
9817
- if (outputSuccess({
9983
+ if (argv.json && outputSuccess({
9818
9984
  argv,
9819
9985
  command,
9820
9986
  data: result.value
9821
9987
  })) return;
9988
+ if (argv.quiet) {
9989
+ for (const file of result.value.files) console.log(file.path);
9990
+ return;
9991
+ }
9822
9992
  if (result.value.files.length === 0) {
9823
9993
  console.log("No files found.");
9824
9994
  return;
@@ -9983,10 +10153,6 @@ const generateCommand = {
9983
10153
  return;
9984
10154
  }
9985
10155
  if (!argv.wait) {
9986
- if (argv.quiet) {
9987
- console.log(result.value.revisionId);
9988
- return;
9989
- }
9990
10156
  if (argv.json) {
9991
10157
  printNdjson({
9992
10158
  type: "result",
@@ -9995,6 +10161,10 @@ const generateCommand = {
9995
10161
  });
9996
10162
  return;
9997
10163
  }
10164
+ if (argv.quiet) {
10165
+ console.log(result.value.revisionId);
10166
+ return;
10167
+ }
9998
10168
  printStreamMarker("done", `revision ${result.value.revisionId} enqueued`);
9999
10169
  printSuccess("Generation enqueued.");
10000
10170
  printLabel("Revision ID", result.value.revisionId);
@@ -10007,32 +10177,31 @@ const generateCommand = {
10007
10177
  status: "running",
10008
10178
  message: "Generation in progress..."
10009
10179
  });
10010
- const succeeded = await watchGeneration({
10180
+ if (await watchGeneration({
10011
10181
  config: config.value,
10012
10182
  client,
10013
10183
  projectGroupId: argv.projectId,
10014
10184
  emit
10015
- });
10016
- if (argv.quiet) {
10017
- console.log(result.value.revisionId);
10018
- if (succeeded === false) process.exitCode = 1;
10185
+ }) === false) {
10186
+ process.exitCode = 1;
10019
10187
  return;
10020
10188
  }
10021
- if (succeeded === false) {
10022
- process.exitCode = 1;
10189
+ if (argv.json) {
10190
+ printNdjson({
10191
+ type: "result",
10192
+ ok: true,
10193
+ data: result.value
10194
+ });
10023
10195
  return;
10024
10196
  }
10025
- if (argv.json) printNdjson({
10026
- type: "result",
10027
- ok: true,
10028
- data: result.value
10029
- });
10030
- else {
10031
- printStreamMarker("done", `revision ${result.value.revisionId} ready`);
10032
- printSuccess("Generation complete.");
10033
- printLabel("Revision ID", result.value.revisionId);
10034
- printLabel("Thread ID", result.value.threadId);
10197
+ if (argv.quiet) {
10198
+ console.log(result.value.revisionId);
10199
+ return;
10035
10200
  }
10201
+ printStreamMarker("done", `revision ${result.value.revisionId} ready`);
10202
+ printSuccess("Generation complete.");
10203
+ printLabel("Revision ID", result.value.revisionId);
10204
+ printLabel("Thread ID", result.value.threadId);
10036
10205
  }
10037
10206
  };
10038
10207
 
@@ -10253,15 +10422,15 @@ const listProjectsCommand = {
10253
10422
  });
10254
10423
  return;
10255
10424
  }
10256
- if (argv.quiet) {
10257
- for (const project of result.value.projects) console.log(project.id);
10258
- return;
10259
- }
10260
- if (outputSuccess({
10425
+ if (argv.json && outputSuccess({
10261
10426
  argv,
10262
10427
  command: COMMAND$11,
10263
10428
  data: result.value
10264
10429
  })) return;
10430
+ if (argv.quiet) {
10431
+ for (const project of result.value.projects) console.log(project.id);
10432
+ return;
10433
+ }
10265
10434
  if (result.value.projects.length === 0) {
10266
10435
  console.log("No projects found.");
10267
10436
  return;
@@ -10349,9 +10518,9 @@ const logsCommand = {
10349
10518
  describe: "Show logs since a duration ago (e.g. 1h, 30m, 2d). Only applies to initial fetch."
10350
10519
  }).option("follow", {
10351
10520
  type: "boolean",
10352
- alias: "f",
10521
+ alias: ["f", "tail"],
10353
10522
  default: false,
10354
- describe: "Tail logs in real-time (stream)"
10523
+ describe: "Tail logs in real-time (stream). Alias: --tail"
10355
10524
  }).option("interval", {
10356
10525
  type: "number",
10357
10526
  default: DEFAULT_POLL_INTERVAL_MS$1,
@@ -10399,7 +10568,7 @@ const logsCommand = {
10399
10568
  data: { logs }
10400
10569
  })) return;
10401
10570
  if (logs.length === 0) {
10402
- console.log("No logs found.");
10571
+ console.log("No development logs found. This command reads dev-server logs, not production deployment logs (use `anything deployments logs <deploymentId>` for those).");
10403
10572
  return;
10404
10573
  }
10405
10574
  for (const log of logs) formatLog(log);
@@ -10776,6 +10945,7 @@ const secretEnvironmentChoices = [
10776
10945
  "preview",
10777
10946
  "production"
10778
10947
  ];
10948
+ const DEFAULT_SECRET_ENVIRONMENT = "DEVELOPMENT";
10779
10949
  const add = {
10780
10950
  command: "add <projectId>",
10781
10951
  describe: "Add a secret to an app",
@@ -10792,8 +10962,13 @@ const add = {
10792
10962
  describe: "Secret value. If omitted, reads stdin when piped."
10793
10963
  }).option("env", {
10794
10964
  type: "string",
10965
+ coerce: (value) => value.toLowerCase(),
10795
10966
  choices: secretEnvironmentChoices,
10796
10967
  describe: "Target environment for the secret"
10968
+ }).option("force", {
10969
+ type: "boolean",
10970
+ default: false,
10971
+ describe: "Allow adding a secret whose name already exists in the target environment (creates a suffixed sibling)"
10797
10972
  }).example("anything projects secrets add <id> --name KEY --value \"secret\"", "Add a secret from an inline value").example("cat secret.txt | anything projects secrets add <id> --name KEY", "Read a secret value from stdin"),
10798
10973
  handler: async (argv) => {
10799
10974
  const command = "projects secrets add";
@@ -10843,11 +11018,30 @@ const add = {
10843
11018
  });
10844
11019
  return;
10845
11020
  }
10846
- const result = await new AnythingApiClient(config.value).addSecret({
11021
+ const client = new AnythingApiClient(config.value);
11022
+ const targetEnvironment = argv.env ? argv.env.toUpperCase() : DEFAULT_SECRET_ENVIRONMENT;
11023
+ if (!argv.force) {
11024
+ const existing = await client.listSecrets({ projectGroupId: argv.projectId });
11025
+ if (existing.isOk()) {
11026
+ if (existing.value.secrets.find((secret) => secret.displayName === argv.name && secret.environment === targetEnvironment)) {
11027
+ outputError({
11028
+ argv,
11029
+ command,
11030
+ error: {
11031
+ message: `A secret named "${argv.name}" already exists in ${targetEnvironment}.`,
11032
+ status: 409
11033
+ },
11034
+ hint: "Remove the existing secret first, or pass --force to create a suffixed sibling."
11035
+ });
11036
+ return;
11037
+ }
11038
+ }
11039
+ }
11040
+ const result = await client.addSecret({
10847
11041
  projectGroupId: argv.projectId,
10848
11042
  displayName: argv.name,
10849
11043
  value: valueResult.value,
10850
- environment: argv.env ? argv.env.toUpperCase() : null
11044
+ environment: targetEnvironment
10851
11045
  });
10852
11046
  if (result.isErr()) {
10853
11047
  outputError({
@@ -10908,7 +11102,8 @@ const remove = {
10908
11102
  message: "Removing a secret is destructive. Pass --yes to confirm.",
10909
11103
  status: null
10910
11104
  },
10911
- exitCode: 2
11105
+ exitCode: 2,
11106
+ code: "CONFIRMATION_REQUIRED"
10912
11107
  });
10913
11108
  return;
10914
11109
  }
@@ -10984,15 +11179,15 @@ const list = {
10984
11179
  });
10985
11180
  return;
10986
11181
  }
10987
- if (argv.quiet) {
10988
- for (const secret of result.value.secrets) console.log(secret.id);
10989
- return;
10990
- }
10991
- if (outputSuccess({
11182
+ if (argv.json && outputSuccess({
10992
11183
  argv,
10993
11184
  command,
10994
11185
  data: result.value
10995
11186
  })) return;
11187
+ if (argv.quiet) {
11188
+ for (const secret of result.value.secrets) console.log(secret.id);
11189
+ return;
11190
+ }
10996
11191
  if (result.value.secrets.length === 0) {
10997
11192
  console.log("No secrets found.");
10998
11193
  return;
@@ -11172,6 +11367,7 @@ const set = {
11172
11367
  array: true,
11173
11368
  describe: "Provider secret in ENV_KEY=VALUE format. Repeat for multiple secrets."
11174
11369
  }).option("env", {
11370
+ coerce: (value) => value.toLowerCase(),
11175
11371
  choices: authEnvironmentChoices,
11176
11372
  default: "production",
11177
11373
  describe: "Environment for secrets passed via --secret"
@@ -11376,7 +11572,7 @@ const unpublishCommand = {
11376
11572
  const COMMAND$5 = "projects delete";
11377
11573
  const deleteProjectCommand = {
11378
11574
  command: "delete <projectId>",
11379
- describe: "Delete a project permanently (gated behind the project-delete-enabled flag; returns 404 when disabled)",
11575
+ describe: "Delete a project permanently (gated behind the project-delete-enabled flag; returns 403 when disabled)",
11380
11576
  builder: (yargs) => yargs.positional("projectId", {
11381
11577
  type: "string",
11382
11578
  demandOption: true,
@@ -11406,7 +11602,8 @@ const deleteProjectCommand = {
11406
11602
  message: "Project deletion is destructive and cannot be undone. Pass --yes to confirm.",
11407
11603
  status: null
11408
11604
  },
11409
- exitCode: 2
11605
+ exitCode: 2,
11606
+ code: "CONFIRMATION_REQUIRED"
11410
11607
  });
11411
11608
  return;
11412
11609
  }
@@ -11429,12 +11626,10 @@ const deleteProjectCommand = {
11429
11626
  const startTime = performance.now();
11430
11627
  const result = await new AnythingApiClient(config.value).deleteProject({ projectGroupId: argv.projectId });
11431
11628
  if (result.isErr()) {
11432
- const hint = result.error.status === 404 ? "If the project ID is correct, project deletion may not be enabled for your account." : void 0;
11433
11629
  outputError({
11434
11630
  argv,
11435
11631
  command: COMMAND$5,
11436
- error: result.error,
11437
- hint
11632
+ error: result.error
11438
11633
  });
11439
11634
  return;
11440
11635
  }
@@ -11924,7 +12119,8 @@ const shipCommand = {
11924
12119
  message: deployError.message,
11925
12120
  status: null
11926
12121
  },
11927
- exitCode: deployError.exitCode
12122
+ exitCode: deployError.exitCode,
12123
+ buildLogs: deployError.buildLogs ?? void 0
11928
12124
  });
11929
12125
  return;
11930
12126
  }
@@ -11936,27 +12132,28 @@ const shipCommand = {
11936
12132
  message: "Published"
11937
12133
  });
11938
12134
  const url = publishResult.value.slug ? `https://${publishResult.value.slug}.created.app` : null;
12135
+ if (argv.json) {
12136
+ printNdjson({
12137
+ type: "result",
12138
+ ok: true,
12139
+ data: {
12140
+ projectId: projectGroupId,
12141
+ published: true,
12142
+ deploymentId,
12143
+ slug: publishResult.value.slug,
12144
+ url
12145
+ }
12146
+ });
12147
+ return;
12148
+ }
11939
12149
  if (argv.quiet) {
11940
12150
  console.log(url ?? projectGroupId);
11941
12151
  return;
11942
12152
  }
11943
- if (argv.json) printNdjson({
11944
- type: "result",
11945
- ok: true,
11946
- data: {
11947
- projectId: projectGroupId,
11948
- published: true,
11949
- deploymentId,
11950
- slug: publishResult.value.slug,
11951
- url
11952
- }
11953
- });
11954
- else {
11955
- printStreamMarker("done", url ?? projectGroupId);
11956
- printSuccess("Shipped!");
11957
- printLabel("Project ID", projectGroupId);
11958
- if (url) printLabel("URL", url);
11959
- }
12153
+ printStreamMarker("done", url ?? projectGroupId);
12154
+ printSuccess("Shipped!");
12155
+ printLabel("Project ID", projectGroupId);
12156
+ if (url) printLabel("URL", url);
11960
12157
  }
11961
12158
  };
11962
12159
 
@@ -12219,7 +12416,8 @@ const switchCommand = {
12219
12416
  //#endregion
12220
12417
  //#region src/update-check.ts
12221
12418
  const PACKAGE_NAME = "@anythingai/cli";
12222
- const REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
12419
+ const REGISTRY_BASE_URL = `https://registry.npmjs.org/${PACKAGE_NAME}`;
12420
+ const REGISTRY_URL = `${REGISTRY_BASE_URL}/latest`;
12223
12421
  const CHECK_INTERVAL_MS = 1440 * 60 * 1e3;
12224
12422
  const NOTICE_FETCH_TIMEOUT_MS = 1500;
12225
12423
  const latestManifestSchema = z.object({ version: z.string() });
@@ -12248,11 +12446,24 @@ async function fetchLatestVersion({ timeoutMs }) {
12248
12446
  return null;
12249
12447
  }
12250
12448
  }
12449
+ async function lookupVersion({ version, timeoutMs }) {
12450
+ try {
12451
+ const response = await fetch(`${REGISTRY_BASE_URL}/${encodeURIComponent(version)}`, {
12452
+ signal: AbortSignal.timeout(timeoutMs),
12453
+ headers: { accept: "application/json" }
12454
+ });
12455
+ if (response.status === 404) return { status: "not-found" };
12456
+ if (!response.ok) return { status: "unreachable" };
12457
+ return latestManifestSchema.safeParse(await response.json()).success ? { status: "exists" } : { status: "not-found" };
12458
+ } catch {
12459
+ return { status: "unreachable" };
12460
+ }
12461
+ }
12251
12462
  function printUpdateNotice({ current, latest }) {
12252
12463
  console.error([
12253
12464
  "",
12254
12465
  styleText("yellow", `Update available for ${PACKAGE_NAME}: ${current} → ${latest}`),
12255
- styleText("dim", `Run \`npm install -g ${PACKAGE_NAME}@latest\` to update.`),
12466
+ styleText("dim", "Run `anything update` to update."),
12256
12467
  ""
12257
12468
  ].join("\n"));
12258
12469
  }
@@ -12367,13 +12578,16 @@ function runInstall({ command, args, capture }) {
12367
12578
  });
12368
12579
  }
12369
12580
  const updateCommand = {
12370
- command: "update",
12371
- describe: "Update the CLI to the latest published version",
12372
- builder: (yargs) => yargs.option("check", {
12581
+ command: "update [version]",
12582
+ describe: "Update the CLI to the latest (or a specific) published version",
12583
+ builder: (yargs) => yargs.positional("version", {
12584
+ type: "string",
12585
+ describe: "A specific published version to install (defaults to the latest)"
12586
+ }).option("check", {
12373
12587
  type: "boolean",
12374
12588
  default: false,
12375
12589
  describe: "Report whether an update is available without installing it"
12376
- }).example("anything update", "Update to the latest version if one exists").example("anything update --check", "Check for a newer version without installing").example("anything update --dry-run", "Print the install command without running it"),
12590
+ }).example("anything update", "Update to the latest version if one exists").example("anything update 0.0.3", "Install a specific published version (may be a downgrade)").example("anything update --check", "Check for a newer version without installing").example("anything update --dry-run", "Print the install command without running it"),
12377
12591
  handler: async (argv) => {
12378
12592
  const latest = await fetchLatestVersion({ timeoutMs: FETCH_TIMEOUT_MS });
12379
12593
  if (latest === null) {
@@ -12389,25 +12603,65 @@ const updateCommand = {
12389
12603
  });
12390
12604
  return;
12391
12605
  }
12606
+ const requestedVersion = argv.version ?? null;
12607
+ if (requestedVersion !== null) {
12608
+ const lookup = await lookupVersion({
12609
+ version: requestedVersion,
12610
+ timeoutMs: FETCH_TIMEOUT_MS
12611
+ });
12612
+ switch (lookup.status) {
12613
+ case "exists": break;
12614
+ case "not-found":
12615
+ outputError({
12616
+ argv,
12617
+ command: COMMAND$1,
12618
+ error: {
12619
+ message: `Version ${requestedVersion} of ${PACKAGE_NAME} does not exist. The latest version is ${latest}.`,
12620
+ status: null
12621
+ },
12622
+ hint: `Run \`anything update\` to install the latest version (${latest}).`
12623
+ });
12624
+ return;
12625
+ case "unreachable":
12626
+ outputError({
12627
+ argv,
12628
+ command: COMMAND$1,
12629
+ error: {
12630
+ message: `Could not reach the npm registry to verify version ${requestedVersion}.`,
12631
+ status: null
12632
+ },
12633
+ hint: `Check available versions with \`npm view ${PACKAGE_NAME} versions\`.`,
12634
+ exitCode: EXIT_TIMEOUT
12635
+ });
12636
+ return;
12637
+ default: {
12638
+ const exhaustive = lookup.status;
12639
+ throw new Error(`Unhandled lookup status: ${String(exhaustive)}`);
12640
+ }
12641
+ }
12642
+ }
12643
+ const targetVersion = requestedVersion ?? latest;
12392
12644
  const packageManager = detectPackageManager(resolveSelfPath());
12393
12645
  const { command, args } = buildInstallCommand({
12394
12646
  packageManager,
12395
- target: `${PACKAGE_NAME}@${latest}`
12647
+ target: `${PACKAGE_NAME}@${targetVersion}`
12396
12648
  });
12397
12649
  const installCommand = [command, ...args].join(" ");
12398
- if (!isNewerVersion(latest, CLI_VERSION)) {
12650
+ const updateAvailable = isNewerVersion(latest, CLI_VERSION);
12651
+ if (requestedVersion === null ? !updateAvailable : targetVersion === CLI_VERSION) {
12399
12652
  if (outputSuccess({
12400
12653
  argv,
12401
12654
  command: COMMAND$1,
12402
12655
  data: {
12403
12656
  currentVersion: CLI_VERSION,
12404
12657
  latestVersion: latest,
12405
- updateAvailable: false,
12658
+ targetVersion,
12659
+ updateAvailable,
12406
12660
  updated: false
12407
12661
  },
12408
12662
  primaryId: CLI_VERSION
12409
12663
  })) return;
12410
- printSuccess(`Already on the latest version (${CLI_VERSION}).`);
12664
+ printSuccess(requestedVersion === null ? `Already on the latest version (${CLI_VERSION}).` : `Already on version ${CLI_VERSION}.`);
12411
12665
  return;
12412
12666
  }
12413
12667
  if (argv.check) {
@@ -12417,18 +12671,20 @@ const updateCommand = {
12417
12671
  data: {
12418
12672
  currentVersion: CLI_VERSION,
12419
12673
  latestVersion: latest,
12420
- updateAvailable: true,
12674
+ targetVersion,
12675
+ updateAvailable,
12421
12676
  updated: false,
12422
12677
  packageManager,
12423
12678
  installCommand
12424
12679
  },
12425
- primaryId: latest
12680
+ primaryId: targetVersion
12426
12681
  })) return;
12427
12682
  console.log();
12428
12683
  printLabel("Current", CLI_VERSION);
12429
12684
  printLabel("Latest", latest);
12685
+ if (requestedVersion !== null) printLabel("Target", targetVersion);
12430
12686
  console.log();
12431
- console.log(`Run \`anything update\` or \`${installCommand}\` to update.`);
12687
+ console.log(requestedVersion === null ? `Run \`anything update\` or \`${installCommand}\` to update.` : `Run \`anything update ${targetVersion}\` or \`${installCommand}\` to install it.`);
12432
12688
  return;
12433
12689
  }
12434
12690
  if (argv["dry-run"]) {
@@ -12438,14 +12694,14 @@ const updateCommand = {
12438
12694
  plannedActions: [{
12439
12695
  action: "update",
12440
12696
  from: CLI_VERSION,
12441
- to: latest,
12697
+ to: targetVersion,
12442
12698
  packageManager,
12443
12699
  command: installCommand
12444
12700
  }]
12445
12701
  });
12446
12702
  return;
12447
12703
  }
12448
- if (!argv.json && !argv.quiet) console.log(`Updating ${PACKAGE_NAME} ${CLI_VERSION} → ${latest} via ${packageManager}...`);
12704
+ if (!argv.json && !argv.quiet) console.log(`Updating ${PACKAGE_NAME} ${CLI_VERSION} → ${targetVersion} via ${packageManager}...`);
12449
12705
  let result;
12450
12706
  try {
12451
12707
  result = await runInstall({
@@ -12484,13 +12740,14 @@ const updateCommand = {
12484
12740
  data: {
12485
12741
  previousVersion: CLI_VERSION,
12486
12742
  latestVersion: latest,
12743
+ targetVersion,
12487
12744
  updated: true,
12488
12745
  packageManager,
12489
12746
  installCommand
12490
12747
  },
12491
- primaryId: latest
12748
+ primaryId: targetVersion
12492
12749
  })) return;
12493
- printSuccess(`Updated to ${latest}. Run \`anything --version\` to confirm.`);
12750
+ printSuccess(`Updated to ${targetVersion}. Run \`anything --version\` to confirm.`);
12494
12751
  }
12495
12752
  };
12496
12753
 
@@ -12779,6 +13036,15 @@ const watchCommand = {
12779
13036
 
12780
13037
  //#endregion
12781
13038
  //#region src/cli.ts
13039
+ var HandledCliError = class extends Error {};
13040
+ function commandPathFromArgv(argv) {
13041
+ const words = [];
13042
+ for (const token of argv) {
13043
+ if (token.startsWith("-")) break;
13044
+ words.push(token);
13045
+ }
13046
+ return words.length > 0 ? words.join(" ") : null;
13047
+ }
12782
13048
  function createCli(argv) {
12783
13049
  const cli = yargs(argv).scriptName("anything").usage("$0 <command> [options]").example("anything auth login", "Log in via browser").example("anything ship --prompt \"Build a todo app\"", "Create + publish in one shot").example("anything domains list org_123", "List domains for one organization").example("anything orgs", "List your organizations").example("anything orgs get <org-id>", "Inspect one organization").example("anything orgs set <org-id>", "Set the active organization").example("anything orgs members <org-id>", "Inspect collaborators and pending invites").example("anything projects create --prompt todo-app", "Create a new app").example("anything projects generate <project-id> --prompt add-auth", "Iterate on an existing app").example("anything projects publish <project-id> --slug my-app", "Publish an app").example("anything projects get <project-id> --json", "Inspect an app in JSON").example("anything projects rename <project-id> --name \"My App\"", "Rename a project").example("anything databases list --org <org-id>", "List databases for an organization").example("anything deployments list <project-id>", "List deployments for a project").example("anything members invite user@example.com --org org_123", "Invite a member").example("anything update", "Update the CLI to the latest version").example("anything status", "Show current context").example("anything switch", "Interactive org/project picker").example("anything introspect", "Output command tree as JSON").option("json", {
12784
13050
  type: "boolean",
@@ -12828,13 +13094,14 @@ function createCli(argv) {
12828
13094
  }
12829
13095
  if (isJson) console.error(JSON.stringify({
12830
13096
  ok: false,
12831
- command: null,
13097
+ command: commandPathFromArgv(argv),
12832
13098
  error: {
12833
13099
  code: "INVALID_ARGUMENTS",
12834
13100
  message
12835
13101
  }
12836
13102
  }, null, 2));
12837
13103
  process.exitCode = EXIT_INVALID_ARGS;
13104
+ throw new HandledCliError(message);
12838
13105
  }).exitProcess(false);
12839
13106
  if (isDevEnvironment()) cli.command(devCommand);
12840
13107
  return cli;
@@ -12842,7 +13109,18 @@ function createCli(argv) {
12842
13109
 
12843
13110
  //#endregion
12844
13111
  //#region src/bin.ts
12845
- createCli(hideBin(process.argv)).parse();
13112
+ function isHandled(err) {
13113
+ return err instanceof HandledCliError;
13114
+ }
13115
+ try {
13116
+ const result = createCli(hideBin(process.argv)).parse();
13117
+ if (result instanceof Promise) result.catch((err) => {
13118
+ if (isHandled(err)) return;
13119
+ throw err;
13120
+ });
13121
+ } catch (err) {
13122
+ if (!isHandled(err)) throw err;
13123
+ }
12846
13124
 
12847
13125
  //#endregion
12848
13126
  export { };