@anythingai/cli 0.1.0 → 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
@@ -3026,9 +3026,11 @@ const EXIT_CONFLICT = 5;
3026
3026
  const EXIT_TIMEOUT = 6;
3027
3027
  const EXIT_SERVER_ERROR = 7;
3028
3028
  const EXIT_RATE_LIMITED = 8;
3029
+ const EXIT_CREDIT_LIMIT = 9;
3029
3030
  function exitCodeFromHttpStatus(status) {
3030
3031
  if (status === null) return EXIT_ERROR;
3031
3032
  if (status === 401 || status === 403) return EXIT_AUTH_FAILURE;
3033
+ if (status === 402) return EXIT_CREDIT_LIMIT;
3032
3034
  if (status === 404) return EXIT_NOT_FOUND;
3033
3035
  if (status === 409) return EXIT_CONFLICT;
3034
3036
  if (status === 408 || status === 504) return EXIT_TIMEOUT;
@@ -3042,6 +3044,7 @@ function errorCodeFromExitCode(exitCode) {
3042
3044
  case EXIT_INVALID_ARGS: return "INVALID_ARGUMENTS";
3043
3045
  case EXIT_NOT_FOUND: return "NOT_FOUND";
3044
3046
  case EXIT_AUTH_FAILURE: return "AUTH_FAILURE";
3047
+ case EXIT_CREDIT_LIMIT: return "CREDIT_LIMIT_REACHED";
3045
3048
  case EXIT_CONFLICT: return "CONFLICT";
3046
3049
  case EXIT_TIMEOUT: return "TIMEOUT";
3047
3050
  case EXIT_SERVER_ERROR: return "SERVER_ERROR";
@@ -3052,6 +3055,7 @@ function errorCodeFromExitCode(exitCode) {
3052
3055
  function errorCodeFromHttpStatus(status) {
3053
3056
  if (status === null) return "NETWORK_ERROR";
3054
3057
  if (status === 401) return "AUTH_FAILURE";
3058
+ if (status === 402) return "CREDIT_LIMIT_REACHED";
3055
3059
  if (status === 403) return "FORBIDDEN";
3056
3060
  if (status === 404) return "NOT_FOUND";
3057
3061
  if (status === 409) return "CONFLICT";
@@ -3065,7 +3069,7 @@ function errorCodeFromHttpStatus(status) {
3065
3069
 
3066
3070
  //#endregion
3067
3071
  //#region package.json
3068
- var version = "0.1.0";
3072
+ var version = "0.1.2";
3069
3073
 
3070
3074
  //#endregion
3071
3075
  //#region generated/core/bodySerializer.gen.ts
@@ -4136,6 +4140,19 @@ const deleteV0ApiProjectsByProjectGroupIdAssetsByAssetId = (options) => (options
4136
4140
  ...options
4137
4141
  });
4138
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
+ /**
4139
4156
  * Get a single database
4140
4157
  *
4141
4158
  * Returns details for a specific user database.
@@ -4423,10 +4440,12 @@ var AnythingApiClient = class {
4423
4440
  }
4424
4441
  if (!response.ok) {
4425
4442
  const retryAfter = parseRetryAfter(response);
4443
+ const hint = error && typeof error === "object" && "hint" in error && typeof error.hint === "string" ? error.hint : void 0;
4426
4444
  return err({
4427
4445
  message: extractErrorMessage(response.status, error),
4428
4446
  status: response.status,
4429
4447
  details: error,
4448
+ ...hint ? { hint } : {},
4430
4449
  ...retryAfter !== null ? { retryAfter } : {}
4431
4450
  });
4432
4451
  }
@@ -4730,6 +4749,12 @@ var AnythingApiClient = class {
4730
4749
  path: { databaseId }
4731
4750
  }));
4732
4751
  }
4752
+ async deleteDatabase({ databaseId }) {
4753
+ return this.toResult(await deleteV0ApiDatabasesByDatabaseId({
4754
+ client: this.client,
4755
+ path: { databaseId }
4756
+ }));
4757
+ }
4733
4758
  async addDomain({ organizationId, domain, projectGroupId }) {
4734
4759
  return this.toResult(await postV0ApiDomains({
4735
4760
  client: this.client,
@@ -4784,12 +4809,17 @@ var AnythingApiClient = class {
4784
4809
  });
4785
4810
  }
4786
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
+ });
4787
4817
  return this.toResult(await postV0ApiOrganizationsByOrganizationIdInvites({
4788
4818
  client: this.client,
4789
4819
  path: { organizationId },
4790
4820
  body: {
4791
4821
  email,
4792
- ...role !== null ? { role } : {}
4822
+ ...normalizedRole !== null ? { role: normalizedRole } : {}
4793
4823
  }
4794
4824
  }));
4795
4825
  }
@@ -4870,12 +4900,13 @@ function extractErrorCode(details) {
4870
4900
  const parsed = DetailsWithCodeSchema.safeParse(details);
4871
4901
  return parsed.success ? parsed.data.code : null;
4872
4902
  }
4873
- function outputError({ argv, command, error, hint, exitCode }) {
4903
+ function outputError({ argv, command, error, hint, exitCode, buildLogs, code: codeOverride }) {
4874
4904
  const status = "status" in error ? error.status ?? null : null;
4875
4905
  const details = "details" in error ? error.details : void 0;
4876
4906
  const retryAfter = "retryAfter" in error && typeof error.retryAfter === "number" ? error.retryAfter : null;
4907
+ const resolvedHint = hint ?? ("hint" in error && typeof error.hint === "string" ? error.hint : void 0);
4877
4908
  process.exitCode = exitCode ?? exitCodeFromHttpStatus(status);
4878
- 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));
4879
4910
  if (argv.json || argv.quiet) {
4880
4911
  console.error(JSON.stringify({
4881
4912
  ok: false,
@@ -4883,8 +4914,9 @@ function outputError({ argv, command, error, hint, exitCode }) {
4883
4914
  error: {
4884
4915
  code,
4885
4916
  message: error.message,
4886
- ...hint ? { hint } : {},
4887
- ...retryAfter !== null ? { retry_after_seconds: retryAfter } : {}
4917
+ ...resolvedHint ? { hint: resolvedHint } : {},
4918
+ ...retryAfter !== null ? { retry_after_seconds: retryAfter } : {},
4919
+ ...buildLogs ? { buildLogs } : {}
4888
4920
  }
4889
4921
  }, null, 2));
4890
4922
  return;
@@ -4895,7 +4927,8 @@ function outputError({ argv, command, error, hint, exitCode }) {
4895
4927
  details
4896
4928
  });
4897
4929
  if (retryAfter !== null) console.error(` ${styleText("dim", `Retry after ${retryAfter}s`)}`);
4898
- if (hint) console.error(` ${styleText("dim", hint)}`);
4930
+ if (resolvedHint) console.error(` ${styleText("dim", resolvedHint)}`);
4931
+ if (buildLogs) console.error(`\n${styleText("dim", "Build logs:")}\n${buildLogs}`);
4899
4932
  }
4900
4933
  function outputValidationError({ argv, command, message, hint }) {
4901
4934
  outputError({
@@ -5103,15 +5136,15 @@ const list$2 = {
5103
5136
  });
5104
5137
  return;
5105
5138
  }
5106
- if (argv.quiet) {
5107
- for (const asset of result.value.assets) console.log(asset.id);
5108
- return;
5109
- }
5110
- if (outputSuccess({
5139
+ if (argv.json && outputSuccess({
5111
5140
  argv,
5112
5141
  command,
5113
5142
  data: result.value
5114
5143
  })) return;
5144
+ if (argv.quiet) {
5145
+ for (const asset of result.value.assets) console.log(asset.id);
5146
+ return;
5147
+ }
5115
5148
  const { assets } = result.value;
5116
5149
  if (assets.length === 0) {
5117
5150
  console.log("No assets found.");
@@ -5207,7 +5240,7 @@ const assetsCommand = {
5207
5240
 
5208
5241
  //#endregion
5209
5242
  //#region src/commands/dev.ts
5210
- const COMMAND$26 = "dev";
5243
+ const COMMAND$27 = "dev";
5211
5244
  const devCommand = {
5212
5245
  command: "dev [state]",
5213
5246
  describe: "Toggle local dev mode so commands target your local dev stack",
@@ -5227,7 +5260,7 @@ const devCommand = {
5227
5260
  const apiUrl = resolveApiUrl({ apiUrl: argv.apiUrl });
5228
5261
  if (outputSuccess({
5229
5262
  argv,
5230
- command: COMMAND$26,
5263
+ command: COMMAND$27,
5231
5264
  data: {
5232
5265
  devMode: enabled,
5233
5266
  apiUrl
@@ -5767,7 +5800,7 @@ const authCommand = {
5767
5800
 
5768
5801
  //#endregion
5769
5802
  //#region src/commands/database-connect.ts
5770
- const COMMAND$25 = "databases connect";
5803
+ const COMMAND$26 = "databases connect";
5771
5804
  function maskConnectionString(connectionString) {
5772
5805
  return connectionString.replace(/(\/\/[^:/?#@]+:)[^@/?#]*(@)/, "$1****$2");
5773
5806
  }
@@ -5791,7 +5824,7 @@ const databaseConnectCommand = {
5791
5824
  if (config.isErr()) {
5792
5825
  outputError({
5793
5826
  argv,
5794
- command: COMMAND$25,
5827
+ command: COMMAND$26,
5795
5828
  error: {
5796
5829
  message: config.error.message,
5797
5830
  status: null
@@ -5804,7 +5837,7 @@ const databaseConnectCommand = {
5804
5837
  if (result.isErr()) {
5805
5838
  outputError({
5806
5839
  argv,
5807
- command: COMMAND$25,
5840
+ command: COMMAND$26,
5808
5841
  error: result.error
5809
5842
  });
5810
5843
  return;
@@ -5812,7 +5845,7 @@ const databaseConnectCommand = {
5812
5845
  const connectionString = argv.mask ? maskConnectionString(result.value.connectionString) : result.value.connectionString;
5813
5846
  if (outputSuccess({
5814
5847
  argv,
5815
- command: COMMAND$25,
5848
+ command: COMMAND$26,
5816
5849
  data: {
5817
5850
  ...result.value,
5818
5851
  connectionString
@@ -5869,7 +5902,7 @@ async function resolveOrgId({ flagOrg, config, nonInteractive }) {
5869
5902
 
5870
5903
  //#endregion
5871
5904
  //#region src/commands/database-create.ts
5872
- const COMMAND$24 = "databases create";
5905
+ const COMMAND$25 = "databases create";
5873
5906
  const databaseCreateCommand = {
5874
5907
  command: "create",
5875
5908
  describe: "Create a new database for a project",
@@ -5888,7 +5921,7 @@ const databaseCreateCommand = {
5888
5921
  if (!name) {
5889
5922
  outputError({
5890
5923
  argv,
5891
- command: COMMAND$24,
5924
+ command: COMMAND$25,
5892
5925
  error: {
5893
5926
  message: "Database name is required. Pass --name <name>.",
5894
5927
  status: null
@@ -5904,7 +5937,7 @@ const databaseCreateCommand = {
5904
5937
  if (config.isErr()) {
5905
5938
  outputError({
5906
5939
  argv,
5907
- command: COMMAND$24,
5940
+ command: COMMAND$25,
5908
5941
  error: {
5909
5942
  message: config.error.message,
5910
5943
  status: null
@@ -5921,7 +5954,7 @@ const databaseCreateCommand = {
5921
5954
  if (!orgResult.ok) {
5922
5955
  outputError({
5923
5956
  argv,
5924
- command: COMMAND$24,
5957
+ command: COMMAND$25,
5925
5958
  error: {
5926
5959
  message: orgResult.error,
5927
5960
  status: null
@@ -5933,7 +5966,7 @@ const databaseCreateCommand = {
5933
5966
  if (argv["dry-run"]) {
5934
5967
  outputDryRun({
5935
5968
  argv,
5936
- command: COMMAND$24,
5969
+ command: COMMAND$25,
5937
5970
  plannedActions: [{
5938
5971
  action: "create_database",
5939
5972
  org: orgResult.orgId,
@@ -5951,14 +5984,14 @@ const databaseCreateCommand = {
5951
5984
  if (result.isErr()) {
5952
5985
  outputError({
5953
5986
  argv,
5954
- command: COMMAND$24,
5987
+ command: COMMAND$25,
5955
5988
  error: result.error
5956
5989
  });
5957
5990
  return;
5958
5991
  }
5959
5992
  if (outputSuccess({
5960
5993
  argv,
5961
- command: COMMAND$24,
5994
+ command: COMMAND$25,
5962
5995
  data: result.value.database,
5963
5996
  primaryId: result.value.database.id
5964
5997
  })) return;
@@ -5971,7 +6004,7 @@ const databaseCreateCommand = {
5971
6004
 
5972
6005
  //#endregion
5973
6006
  //#region src/commands/database-get.ts
5974
- const COMMAND$23 = "databases get";
6007
+ const COMMAND$24 = "databases get";
5975
6008
  const databaseGetCommand = {
5976
6009
  command: "get <databaseId>",
5977
6010
  describe: "Inspect a database",
@@ -5988,7 +6021,7 @@ const databaseGetCommand = {
5988
6021
  if (config.isErr()) {
5989
6022
  outputError({
5990
6023
  argv,
5991
- command: COMMAND$23,
6024
+ command: COMMAND$24,
5992
6025
  error: {
5993
6026
  message: config.error.message,
5994
6027
  status: null
@@ -6001,14 +6034,14 @@ const databaseGetCommand = {
6001
6034
  if (result.isErr()) {
6002
6035
  outputError({
6003
6036
  argv,
6004
- command: COMMAND$23,
6037
+ command: COMMAND$24,
6005
6038
  error: result.error
6006
6039
  });
6007
6040
  return;
6008
6041
  }
6009
6042
  if (outputSuccess({
6010
6043
  argv,
6011
- command: COMMAND$23,
6044
+ command: COMMAND$24,
6012
6045
  data: result.value.database,
6013
6046
  primaryId: result.value.database.id
6014
6047
  })) return;
@@ -6023,7 +6056,7 @@ const databaseGetCommand = {
6023
6056
 
6024
6057
  //#endregion
6025
6058
  //#region src/commands/database-query.ts
6026
- const COMMAND$22 = "databases query";
6059
+ const COMMAND$23 = "databases query";
6027
6060
  const databaseQueryCommand = {
6028
6061
  command: "query <databaseId> <sql>",
6029
6062
  describe: "Run a read-only SQL query against a database",
@@ -6044,7 +6077,7 @@ const databaseQueryCommand = {
6044
6077
  if (config.isErr()) {
6045
6078
  outputError({
6046
6079
  argv,
6047
- command: COMMAND$22,
6080
+ command: COMMAND$23,
6048
6081
  error: {
6049
6082
  message: config.error.message,
6050
6083
  status: null
@@ -6060,7 +6093,7 @@ const databaseQueryCommand = {
6060
6093
  if (result.isErr()) {
6061
6094
  outputError({
6062
6095
  argv,
6063
- command: COMMAND$22,
6096
+ command: COMMAND$23,
6064
6097
  error: result.error,
6065
6098
  hint: "Check the database ID and SQL syntax"
6066
6099
  });
@@ -6068,7 +6101,7 @@ const databaseQueryCommand = {
6068
6101
  }
6069
6102
  if (outputSuccess({
6070
6103
  argv,
6071
- command: COMMAND$22,
6104
+ command: COMMAND$23,
6072
6105
  data: result.value
6073
6106
  })) return;
6074
6107
  if (result.value.rows.length === 0) {
@@ -6086,7 +6119,7 @@ const databaseQueryCommand = {
6086
6119
 
6087
6120
  //#endregion
6088
6121
  //#region src/commands/database-reset.ts
6089
- const COMMAND$21 = "databases reset";
6122
+ const COMMAND$22 = "databases reset";
6090
6123
  const databaseResetCommand = {
6091
6124
  command: "reset <databaseId>",
6092
6125
  describe: "Reset a database (destructive)",
@@ -6107,7 +6140,7 @@ const databaseResetCommand = {
6107
6140
  if (config.isErr()) {
6108
6141
  outputError({
6109
6142
  argv,
6110
- command: COMMAND$21,
6143
+ command: COMMAND$22,
6111
6144
  error: {
6112
6145
  message: config.error.message,
6113
6146
  status: null
@@ -6119,7 +6152,7 @@ const databaseResetCommand = {
6119
6152
  if (argv["dry-run"]) {
6120
6153
  outputDryRun({
6121
6154
  argv,
6122
- command: COMMAND$21,
6155
+ command: COMMAND$22,
6123
6156
  plannedActions: [{
6124
6157
  action: "reset_database",
6125
6158
  databaseId: argv.databaseId
@@ -6130,12 +6163,13 @@ const databaseResetCommand = {
6130
6163
  if (!argv.yes) {
6131
6164
  outputError({
6132
6165
  argv,
6133
- command: COMMAND$21,
6166
+ command: COMMAND$22,
6134
6167
  error: {
6135
6168
  message: "Database reset is destructive. Pass --yes to confirm.",
6136
6169
  status: null
6137
6170
  },
6138
- exitCode: 2
6171
+ exitCode: 2,
6172
+ code: "CONFIRMATION_REQUIRED"
6139
6173
  });
6140
6174
  return;
6141
6175
  }
@@ -6143,14 +6177,14 @@ const databaseResetCommand = {
6143
6177
  if (result.isErr()) {
6144
6178
  outputError({
6145
6179
  argv,
6146
- command: COMMAND$21,
6180
+ command: COMMAND$22,
6147
6181
  error: result.error
6148
6182
  });
6149
6183
  return;
6150
6184
  }
6151
6185
  if (outputSuccess({
6152
6186
  argv,
6153
- command: COMMAND$21,
6187
+ command: COMMAND$22,
6154
6188
  data: {
6155
6189
  reset: true,
6156
6190
  databaseId: argv.databaseId
@@ -6160,6 +6194,84 @@ const databaseResetCommand = {
6160
6194
  }
6161
6195
  };
6162
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
+
6163
6275
  //#endregion
6164
6276
  //#region src/commands/list-databases.ts
6165
6277
  const COMMAND$20 = "databases list";
@@ -6204,15 +6316,15 @@ const listDatabasesCommand = {
6204
6316
  });
6205
6317
  return;
6206
6318
  }
6207
- if (argv.quiet) {
6208
- for (const db of result.value.databases) console.log(db.id);
6209
- return;
6210
- }
6211
- if (outputSuccess({
6319
+ if (argv.json && outputSuccess({
6212
6320
  argv,
6213
6321
  command: COMMAND$20,
6214
6322
  data: result.value
6215
6323
  })) return;
6324
+ if (argv.quiet) {
6325
+ for (const db of result.value.databases) console.log(db.id);
6326
+ return;
6327
+ }
6216
6328
  if (result.value.databases.length === 0) {
6217
6329
  console.log("No databases found.");
6218
6330
  return;
@@ -6247,7 +6359,7 @@ const databasesListCommand = {
6247
6359
  const databasesCommand = {
6248
6360
  command: "databases",
6249
6361
  describe: "Manage databases",
6250
- 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."),
6251
6363
  handler: () => {}
6252
6364
  };
6253
6365
 
@@ -6295,15 +6407,15 @@ const deploymentsListCommand = {
6295
6407
  });
6296
6408
  return;
6297
6409
  }
6298
- if (argv.quiet) {
6299
- for (const deployment of result.value.deployments) console.log(deployment.id);
6300
- return;
6301
- }
6302
- if (outputSuccess({
6410
+ if (argv.json && outputSuccess({
6303
6411
  argv,
6304
6412
  command,
6305
6413
  data: result.value
6306
6414
  })) return;
6415
+ if (argv.quiet) {
6416
+ for (const deployment of result.value.deployments) console.log(deployment.id);
6417
+ return;
6418
+ }
6307
6419
  if (result.value.deployments.length === 0) {
6308
6420
  console.log("No deployments found.");
6309
6421
  return;
@@ -6435,20 +6547,17 @@ const deploymentsLogsCommand = {
6435
6547
  }
6436
6548
  };
6437
6549
  const deploymentsRollbackCommand = {
6438
- command: "rollback <projectId> [deploymentId]",
6439
- describe: "Rollback to a previous deployment",
6550
+ command: "rollback <projectId>",
6551
+ describe: "Roll a project back to its previous deployment",
6440
6552
  builder: (yargs) => yargs.positional("projectId", {
6441
6553
  type: "string",
6442
6554
  demandOption: true,
6443
- describe: "The project ID"
6444
- }).positional("deploymentId", {
6445
- type: "string",
6446
- describe: "Specific deployment ID to rollback to (defaults to previous)"
6555
+ describe: "The project ID to roll back"
6447
6556
  }).option("yes", {
6448
6557
  type: "boolean",
6449
6558
  default: false,
6450
6559
  describe: "Skip confirmation"
6451
- }).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"),
6452
6561
  handler: async (argv) => {
6453
6562
  const command = "deployments rollback";
6454
6563
  const config = resolveConfig({
@@ -6473,8 +6582,7 @@ const deploymentsRollbackCommand = {
6473
6582
  command,
6474
6583
  plannedActions: [{
6475
6584
  action: "rollback_deployment",
6476
- projectId: argv.projectId,
6477
- ...argv.deploymentId ? { deploymentId: argv.deploymentId } : {}
6585
+ projectId: argv.projectId
6478
6586
  }]
6479
6587
  });
6480
6588
  return;
@@ -6487,14 +6595,12 @@ const deploymentsRollbackCommand = {
6487
6595
  message: "Rollback is destructive. Pass --yes to confirm.",
6488
6596
  status: null
6489
6597
  },
6490
- exitCode: 2
6598
+ exitCode: 2,
6599
+ code: "CONFIRMATION_REQUIRED"
6491
6600
  });
6492
6601
  return;
6493
6602
  }
6494
- const result = await new AnythingApiClient(config.value).rollbackDeployment({
6495
- projectGroupId: argv.projectId,
6496
- deploymentId: argv.deploymentId ?? null
6497
- });
6603
+ const result = await new AnythingApiClient(config.value).rollbackDeployment({ projectGroupId: argv.projectId });
6498
6604
  if (result.isErr()) {
6499
6605
  outputError({
6500
6606
  argv,
@@ -6523,9 +6629,29 @@ const deploymentsCommand = {
6523
6629
  handler: () => {}
6524
6630
  };
6525
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
+
6526
6644
  //#endregion
6527
6645
  //#region src/commands/domain-add.ts
6528
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
+ }
6529
6655
  const domainAddCommand = {
6530
6656
  command: "add <domain>",
6531
6657
  describe: "Add a custom domain to a project",
@@ -6541,6 +6667,19 @@ const domainAddCommand = {
6541
6667
  describe: "Project ID to link the domain to"
6542
6668
  }).example("anything domains add app.example.com --project pg_123", "Add a custom domain to a project"),
6543
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
+ }
6544
6683
  const config = resolveConfig({
6545
6684
  dev: argv.dev,
6546
6685
  apiUrl: argv.apiUrl
@@ -6603,7 +6742,7 @@ const domainAddCommand = {
6603
6742
  if (outputSuccess({
6604
6743
  argv,
6605
6744
  command: COMMAND$19,
6606
- data: result.value.domain,
6745
+ data: toPublicDomain(result.value.domain),
6607
6746
  primaryId: result.value.domain.domain
6608
6747
  })) return;
6609
6748
  printSuccess(`Domain added: ${result.value.domain.domain}`);
@@ -6663,7 +6802,8 @@ const domainRemoveCommand = {
6663
6802
  message: "Domain removal is destructive. Pass --yes to confirm.",
6664
6803
  status: null
6665
6804
  },
6666
- exitCode: 2
6805
+ exitCode: 2,
6806
+ code: "CONFIRMATION_REQUIRED"
6667
6807
  });
6668
6808
  return;
6669
6809
  }
@@ -6783,15 +6923,16 @@ const domainsListCommand = {
6783
6923
  });
6784
6924
  return;
6785
6925
  }
6926
+ const jsonData = { domains: result.value.domains.map(toPublicDomain) };
6927
+ if (argv.json && outputSuccess({
6928
+ argv,
6929
+ command,
6930
+ data: jsonData
6931
+ })) return;
6786
6932
  if (argv.quiet) {
6787
6933
  for (const domain of result.value.domains) console.log(domain.domain);
6788
6934
  return;
6789
6935
  }
6790
- if (outputSuccess({
6791
- argv,
6792
- command,
6793
- data: result.value
6794
- })) return;
6795
6936
  if (result.value.domains.length === 0) {
6796
6937
  console.log("No domains found.");
6797
6938
  return;
@@ -8121,6 +8262,7 @@ const linkCommand = {
8121
8262
  orgId,
8122
8263
  projectId: projectGroupId
8123
8264
  }, null, 2) + "\n");
8265
+ setStoredProjectGroupId(projResult.value.id);
8124
8266
  if (outputSuccess({
8125
8267
  argv,
8126
8268
  command,
@@ -8156,7 +8298,9 @@ const unlinkCommand = {
8156
8298
  });
8157
8299
  return;
8158
8300
  }
8301
+ const linked = readLinkedProject();
8159
8302
  rmSync(projectFile);
8303
+ if (linked && getStoredProjectGroupId() === linked.projectId) clearStoredProjectGroupId();
8160
8304
  try {
8161
8305
  if (existsSync(dir) && readdirSync(dir).length === 0) rmSync(dir, { recursive: true });
8162
8306
  } catch {}
@@ -8359,6 +8503,22 @@ const llmContextCommand = {
8359
8503
  }
8360
8504
  };
8361
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
+
8362
8522
  //#endregion
8363
8523
  //#region src/commands/members.ts
8364
8524
  const MEMBER_ROLE_CHOICES = [
@@ -8422,7 +8582,17 @@ const membersListCommand = {
8422
8582
  if (outputSuccess({
8423
8583
  argv,
8424
8584
  command,
8425
- 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
+ }
8426
8596
  })) return;
8427
8597
  if (result.value.collaborators.length > 0) printTable({
8428
8598
  headers: [
@@ -8433,7 +8603,7 @@ const membersListCommand = {
8433
8603
  rows: result.value.collaborators.map((c) => [
8434
8604
  c.displayName,
8435
8605
  c.email ?? "-",
8436
- c.role
8606
+ formatRole(c.role) ?? c.role
8437
8607
  ])
8438
8608
  });
8439
8609
  if (result.value.pendingInvites.length > 0) {
@@ -8622,7 +8792,8 @@ const membersRemoveCommand = {
8622
8792
  message: "Member removal is destructive. Pass --yes to confirm.",
8623
8793
  status: null
8624
8794
  },
8625
- exitCode: 2
8795
+ exitCode: 2,
8796
+ code: "CONFIRMATION_REQUIRED"
8626
8797
  });
8627
8798
  return;
8628
8799
  }
@@ -8755,16 +8926,6 @@ const humanizeCredits = (credits) => {
8755
8926
 
8756
8927
  //#endregion
8757
8928
  //#region src/commands/org-members.ts
8758
- function formatRole(role) {
8759
- if (role === null) return null;
8760
- switch (role.toUpperCase()) {
8761
- case "OWNER": return "Owner";
8762
- case "ADMIN": return "Admin";
8763
- case "EDITOR": return "Editor";
8764
- case "VIEWER": return "Viewer";
8765
- default: return role;
8766
- }
8767
- }
8768
8929
  const orgMembersCommand = {
8769
8930
  command: "members <organizationId>",
8770
8931
  describe: "Inspect collaborators and pending invites for an organization",
@@ -8803,7 +8964,17 @@ const orgMembersCommand = {
8803
8964
  if (outputSuccess({
8804
8965
  argv,
8805
8966
  command,
8806
- 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
+ }
8807
8978
  })) return;
8808
8979
  console.log();
8809
8980
  printLabel("Organization", result.value.organization.name);
@@ -8849,7 +9020,7 @@ const orgMembersCommand = {
8849
9020
 
8850
9021
  //#endregion
8851
9022
  //#region src/commands/orgs.ts
8852
- async function loadOrganizations(argv) {
9023
+ async function loadOrganizations(argv, command) {
8853
9024
  const config = resolveConfig({
8854
9025
  dev: argv.dev,
8855
9026
  apiUrl: argv.apiUrl
@@ -8857,7 +9028,7 @@ async function loadOrganizations(argv) {
8857
9028
  if (config.isErr()) {
8858
9029
  outputError({
8859
9030
  argv,
8860
- command: "orgs",
9031
+ command,
8861
9032
  error: {
8862
9033
  message: config.error.message,
8863
9034
  status: null
@@ -8870,7 +9041,7 @@ async function loadOrganizations(argv) {
8870
9041
  if (result.isErr()) {
8871
9042
  outputError({
8872
9043
  argv,
8873
- command: "orgs",
9044
+ command,
8874
9045
  error: result.error
8875
9046
  });
8876
9047
  return null;
@@ -8890,7 +9061,7 @@ const getCommand = {
8890
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"),
8891
9062
  handler: async (argv) => {
8892
9063
  const command = "orgs get";
8893
- const organizations = await loadOrganizations(argv);
9064
+ const organizations = await loadOrganizations(argv, command);
8894
9065
  if (!organizations) return;
8895
9066
  const organization = organizations.find((org) => org.id === argv.organizationId);
8896
9067
  if (!organization) {
@@ -8925,14 +9096,10 @@ const listOrgs = {
8925
9096
  builder: (yargs) => yargs.example("anything orgs list", "List orgs available to the current user"),
8926
9097
  handler: async (argv) => {
8927
9098
  const command = "orgs list";
8928
- const organizations = await loadOrganizations(argv);
9099
+ const organizations = await loadOrganizations(argv, command);
8929
9100
  if (!organizations) return;
8930
9101
  const activeOrgId = getStoredOrgId();
8931
- if (argv.quiet) {
8932
- for (const org of organizations) console.log(org.id);
8933
- return;
8934
- }
8935
- if (outputSuccess({
9102
+ if (argv.json && outputSuccess({
8936
9103
  argv,
8937
9104
  command,
8938
9105
  data: {
@@ -8940,6 +9107,10 @@ const listOrgs = {
8940
9107
  activeOrgId: activeOrgId ?? null
8941
9108
  }
8942
9109
  })) return;
9110
+ if (argv.quiet) {
9111
+ for (const org of organizations) console.log(org.id);
9112
+ return;
9113
+ }
8943
9114
  if (organizations.length === 0) {
8944
9115
  console.log("No organizations found.");
8945
9116
  return;
@@ -8968,7 +9139,7 @@ const setOrg = {
8968
9139
  }).example("anything orgs set org_abc123", "Set the active organization"),
8969
9140
  handler: async (argv) => {
8970
9141
  const command = "orgs set";
8971
- const organizations = await loadOrganizations(argv);
9142
+ const organizations = await loadOrganizations(argv, command);
8972
9143
  if (!organizations) return;
8973
9144
  const org = organizations.find((o) => o.id === argv["org-id"]);
8974
9145
  if (!org) {
@@ -9343,10 +9514,6 @@ const createCommand = {
9343
9514
  message: "Project created"
9344
9515
  });
9345
9516
  if (!argv.wait) {
9346
- if (argv.quiet) {
9347
- console.log(result.value.projectGroupId);
9348
- return;
9349
- }
9350
9517
  if (argv.json) {
9351
9518
  printNdjson({
9352
9519
  type: "result",
@@ -9355,6 +9522,10 @@ const createCommand = {
9355
9522
  });
9356
9523
  return;
9357
9524
  }
9525
+ if (argv.quiet) {
9526
+ console.log(result.value.projectGroupId);
9527
+ return;
9528
+ }
9358
9529
  printStreamMarker("done", `project ${result.value.projectGroupId} created`);
9359
9530
  printSuccess("App created! Generation enqueued.");
9360
9531
  printLabel("Project Group ID", result.value.projectGroupId);
@@ -9373,27 +9544,11 @@ const createCommand = {
9373
9544
  projectGroupId: result.value.projectGroupId,
9374
9545
  emit
9375
9546
  });
9376
- if (argv.quiet) {
9377
- console.log(result.value.projectGroupId);
9378
- if (succeeded === false) process.exitCode = 1;
9379
- return;
9380
- }
9381
- if (succeeded === false) {
9382
- if (!argv.json) {
9383
- outputError({
9384
- argv,
9385
- command: COMMAND$16,
9386
- error: {
9387
- message: "Generation failed.",
9388
- status: null
9389
- }
9390
- });
9391
- printLabel("Project Group ID", result.value.projectGroupId);
9392
- }
9393
- process.exitCode = 1;
9394
- return;
9395
- }
9396
9547
  if (argv.json) {
9548
+ if (succeeded === false) {
9549
+ process.exitCode = 1;
9550
+ return;
9551
+ }
9397
9552
  const { projectGroupId: projectId, ...rest } = result.value;
9398
9553
  printNdjson({
9399
9554
  type: "result",
@@ -9403,12 +9558,30 @@ const createCommand = {
9403
9558
  ...rest
9404
9559
  }
9405
9560
  });
9406
- } else {
9407
- printStreamMarker("done", `project ${result.value.projectGroupId} ready`);
9408
- printSuccess("App created! Generation complete.");
9409
- printLabel("Project ID", result.value.projectGroupId);
9410
- printLabel("Revision ID", result.value.revisionId);
9561
+ return;
9411
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);
9412
9585
  }
9413
9586
  };
9414
9587
 
@@ -9452,14 +9625,16 @@ async function waitForDeployment({ client, deploymentId, emit }) {
9452
9625
  function getDeploymentError({ result, statusCommand }) {
9453
9626
  if (result.outcome === "timeout") return {
9454
9627
  message: `Deployment timed out. Check status with: ${statusCommand}`,
9455
- exitCode: 6
9628
+ exitCode: 6,
9629
+ buildLogs: null
9456
9630
  };
9457
9631
  if (result.deployment.status === "FAILED") {
9458
9632
  const reason = result.deployment.failureReason ?? null;
9459
9633
  const logs = result.deployment.buildLogs ?? null;
9460
9634
  return {
9461
- message: reason ? logs ? `${reason}\n\n${logs}` : reason : logs ?? "Deployment failed (no logs available).",
9462
- exitCode: 1
9635
+ message: reason ?? (logs ? "Deployment failed. See build logs for details." : "Deployment failed (no logs available)."),
9636
+ exitCode: 1,
9637
+ buildLogs: logs
9463
9638
  };
9464
9639
  }
9465
9640
  return null;
@@ -9524,7 +9699,8 @@ const publishStatusCommand = {
9524
9699
  status: null
9525
9700
  },
9526
9701
  hint: `Inspect the full build logs with: anything deployments logs ${argv.deploymentId}`,
9527
- exitCode: failure?.exitCode ?? 1
9702
+ exitCode: failure?.exitCode ?? 1,
9703
+ buildLogs: failure?.buildLogs ?? void 0
9528
9704
  });
9529
9705
  return;
9530
9706
  }
@@ -9672,7 +9848,8 @@ const publishCommand = {
9672
9848
  message: deployError.message,
9673
9849
  status: null
9674
9850
  },
9675
- exitCode: deployError.exitCode
9851
+ exitCode: deployError.exitCode,
9852
+ buildLogs: deployError.buildLogs ?? void 0
9676
9853
  });
9677
9854
  return;
9678
9855
  }
@@ -9803,15 +9980,15 @@ const list$1 = {
9803
9980
  });
9804
9981
  return;
9805
9982
  }
9806
- if (argv.quiet) {
9807
- for (const file of result.value.files) console.log(file.path);
9808
- return;
9809
- }
9810
- if (outputSuccess({
9983
+ if (argv.json && outputSuccess({
9811
9984
  argv,
9812
9985
  command,
9813
9986
  data: result.value
9814
9987
  })) return;
9988
+ if (argv.quiet) {
9989
+ for (const file of result.value.files) console.log(file.path);
9990
+ return;
9991
+ }
9815
9992
  if (result.value.files.length === 0) {
9816
9993
  console.log("No files found.");
9817
9994
  return;
@@ -9976,10 +10153,6 @@ const generateCommand = {
9976
10153
  return;
9977
10154
  }
9978
10155
  if (!argv.wait) {
9979
- if (argv.quiet) {
9980
- console.log(result.value.revisionId);
9981
- return;
9982
- }
9983
10156
  if (argv.json) {
9984
10157
  printNdjson({
9985
10158
  type: "result",
@@ -9988,6 +10161,10 @@ const generateCommand = {
9988
10161
  });
9989
10162
  return;
9990
10163
  }
10164
+ if (argv.quiet) {
10165
+ console.log(result.value.revisionId);
10166
+ return;
10167
+ }
9991
10168
  printStreamMarker("done", `revision ${result.value.revisionId} enqueued`);
9992
10169
  printSuccess("Generation enqueued.");
9993
10170
  printLabel("Revision ID", result.value.revisionId);
@@ -10000,32 +10177,31 @@ const generateCommand = {
10000
10177
  status: "running",
10001
10178
  message: "Generation in progress..."
10002
10179
  });
10003
- const succeeded = await watchGeneration({
10180
+ if (await watchGeneration({
10004
10181
  config: config.value,
10005
10182
  client,
10006
10183
  projectGroupId: argv.projectId,
10007
10184
  emit
10008
- });
10009
- if (argv.quiet) {
10010
- console.log(result.value.revisionId);
10011
- if (succeeded === false) process.exitCode = 1;
10185
+ }) === false) {
10186
+ process.exitCode = 1;
10012
10187
  return;
10013
10188
  }
10014
- if (succeeded === false) {
10015
- process.exitCode = 1;
10189
+ if (argv.json) {
10190
+ printNdjson({
10191
+ type: "result",
10192
+ ok: true,
10193
+ data: result.value
10194
+ });
10016
10195
  return;
10017
10196
  }
10018
- if (argv.json) printNdjson({
10019
- type: "result",
10020
- ok: true,
10021
- data: result.value
10022
- });
10023
- else {
10024
- printStreamMarker("done", `revision ${result.value.revisionId} ready`);
10025
- printSuccess("Generation complete.");
10026
- printLabel("Revision ID", result.value.revisionId);
10027
- printLabel("Thread ID", result.value.threadId);
10197
+ if (argv.quiet) {
10198
+ console.log(result.value.revisionId);
10199
+ return;
10028
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);
10029
10205
  }
10030
10206
  };
10031
10207
 
@@ -10246,15 +10422,15 @@ const listProjectsCommand = {
10246
10422
  });
10247
10423
  return;
10248
10424
  }
10249
- if (argv.quiet) {
10250
- for (const project of result.value.projects) console.log(project.id);
10251
- return;
10252
- }
10253
- if (outputSuccess({
10425
+ if (argv.json && outputSuccess({
10254
10426
  argv,
10255
10427
  command: COMMAND$11,
10256
10428
  data: result.value
10257
10429
  })) return;
10430
+ if (argv.quiet) {
10431
+ for (const project of result.value.projects) console.log(project.id);
10432
+ return;
10433
+ }
10258
10434
  if (result.value.projects.length === 0) {
10259
10435
  console.log("No projects found.");
10260
10436
  return;
@@ -10342,9 +10518,9 @@ const logsCommand = {
10342
10518
  describe: "Show logs since a duration ago (e.g. 1h, 30m, 2d). Only applies to initial fetch."
10343
10519
  }).option("follow", {
10344
10520
  type: "boolean",
10345
- alias: "f",
10521
+ alias: ["f", "tail"],
10346
10522
  default: false,
10347
- describe: "Tail logs in real-time (stream)"
10523
+ describe: "Tail logs in real-time (stream). Alias: --tail"
10348
10524
  }).option("interval", {
10349
10525
  type: "number",
10350
10526
  default: DEFAULT_POLL_INTERVAL_MS$1,
@@ -10392,7 +10568,7 @@ const logsCommand = {
10392
10568
  data: { logs }
10393
10569
  })) return;
10394
10570
  if (logs.length === 0) {
10395
- 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).");
10396
10572
  return;
10397
10573
  }
10398
10574
  for (const log of logs) formatLog(log);
@@ -10769,6 +10945,7 @@ const secretEnvironmentChoices = [
10769
10945
  "preview",
10770
10946
  "production"
10771
10947
  ];
10948
+ const DEFAULT_SECRET_ENVIRONMENT = "DEVELOPMENT";
10772
10949
  const add = {
10773
10950
  command: "add <projectId>",
10774
10951
  describe: "Add a secret to an app",
@@ -10785,8 +10962,13 @@ const add = {
10785
10962
  describe: "Secret value. If omitted, reads stdin when piped."
10786
10963
  }).option("env", {
10787
10964
  type: "string",
10965
+ coerce: (value) => value.toLowerCase(),
10788
10966
  choices: secretEnvironmentChoices,
10789
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)"
10790
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"),
10791
10973
  handler: async (argv) => {
10792
10974
  const command = "projects secrets add";
@@ -10836,11 +11018,30 @@ const add = {
10836
11018
  });
10837
11019
  return;
10838
11020
  }
10839
- 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({
10840
11041
  projectGroupId: argv.projectId,
10841
11042
  displayName: argv.name,
10842
11043
  value: valueResult.value,
10843
- environment: argv.env ? argv.env.toUpperCase() : null
11044
+ environment: targetEnvironment
10844
11045
  });
10845
11046
  if (result.isErr()) {
10846
11047
  outputError({
@@ -10901,7 +11102,8 @@ const remove = {
10901
11102
  message: "Removing a secret is destructive. Pass --yes to confirm.",
10902
11103
  status: null
10903
11104
  },
10904
- exitCode: 2
11105
+ exitCode: 2,
11106
+ code: "CONFIRMATION_REQUIRED"
10905
11107
  });
10906
11108
  return;
10907
11109
  }
@@ -10977,15 +11179,15 @@ const list = {
10977
11179
  });
10978
11180
  return;
10979
11181
  }
10980
- if (argv.quiet) {
10981
- for (const secret of result.value.secrets) console.log(secret.id);
10982
- return;
10983
- }
10984
- if (outputSuccess({
11182
+ if (argv.json && outputSuccess({
10985
11183
  argv,
10986
11184
  command,
10987
11185
  data: result.value
10988
11186
  })) return;
11187
+ if (argv.quiet) {
11188
+ for (const secret of result.value.secrets) console.log(secret.id);
11189
+ return;
11190
+ }
10989
11191
  if (result.value.secrets.length === 0) {
10990
11192
  console.log("No secrets found.");
10991
11193
  return;
@@ -11165,6 +11367,7 @@ const set = {
11165
11367
  array: true,
11166
11368
  describe: "Provider secret in ENV_KEY=VALUE format. Repeat for multiple secrets."
11167
11369
  }).option("env", {
11370
+ coerce: (value) => value.toLowerCase(),
11168
11371
  choices: authEnvironmentChoices,
11169
11372
  default: "production",
11170
11373
  describe: "Environment for secrets passed via --secret"
@@ -11369,7 +11572,7 @@ const unpublishCommand = {
11369
11572
  const COMMAND$5 = "projects delete";
11370
11573
  const deleteProjectCommand = {
11371
11574
  command: "delete <projectId>",
11372
- 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)",
11373
11576
  builder: (yargs) => yargs.positional("projectId", {
11374
11577
  type: "string",
11375
11578
  demandOption: true,
@@ -11399,7 +11602,8 @@ const deleteProjectCommand = {
11399
11602
  message: "Project deletion is destructive and cannot be undone. Pass --yes to confirm.",
11400
11603
  status: null
11401
11604
  },
11402
- exitCode: 2
11605
+ exitCode: 2,
11606
+ code: "CONFIRMATION_REQUIRED"
11403
11607
  });
11404
11608
  return;
11405
11609
  }
@@ -11422,12 +11626,10 @@ const deleteProjectCommand = {
11422
11626
  const startTime = performance.now();
11423
11627
  const result = await new AnythingApiClient(config.value).deleteProject({ projectGroupId: argv.projectId });
11424
11628
  if (result.isErr()) {
11425
- const hint = result.error.status === 404 ? "If the project ID is correct, project deletion may not be enabled for your account." : void 0;
11426
11629
  outputError({
11427
11630
  argv,
11428
11631
  command: COMMAND$5,
11429
- error: result.error,
11430
- hint
11632
+ error: result.error
11431
11633
  });
11432
11634
  return;
11433
11635
  }
@@ -11917,7 +12119,8 @@ const shipCommand = {
11917
12119
  message: deployError.message,
11918
12120
  status: null
11919
12121
  },
11920
- exitCode: deployError.exitCode
12122
+ exitCode: deployError.exitCode,
12123
+ buildLogs: deployError.buildLogs ?? void 0
11921
12124
  });
11922
12125
  return;
11923
12126
  }
@@ -11929,27 +12132,28 @@ const shipCommand = {
11929
12132
  message: "Published"
11930
12133
  });
11931
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
+ }
11932
12149
  if (argv.quiet) {
11933
12150
  console.log(url ?? projectGroupId);
11934
12151
  return;
11935
12152
  }
11936
- if (argv.json) printNdjson({
11937
- type: "result",
11938
- ok: true,
11939
- data: {
11940
- projectId: projectGroupId,
11941
- published: true,
11942
- deploymentId,
11943
- slug: publishResult.value.slug,
11944
- url
11945
- }
11946
- });
11947
- else {
11948
- printStreamMarker("done", url ?? projectGroupId);
11949
- printSuccess("Shipped!");
11950
- printLabel("Project ID", projectGroupId);
11951
- if (url) printLabel("URL", url);
11952
- }
12153
+ printStreamMarker("done", url ?? projectGroupId);
12154
+ printSuccess("Shipped!");
12155
+ printLabel("Project ID", projectGroupId);
12156
+ if (url) printLabel("URL", url);
11953
12157
  }
11954
12158
  };
11955
12159
 
@@ -12212,7 +12416,8 @@ const switchCommand = {
12212
12416
  //#endregion
12213
12417
  //#region src/update-check.ts
12214
12418
  const PACKAGE_NAME = "@anythingai/cli";
12215
- 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`;
12216
12421
  const CHECK_INTERVAL_MS = 1440 * 60 * 1e3;
12217
12422
  const NOTICE_FETCH_TIMEOUT_MS = 1500;
12218
12423
  const latestManifestSchema = z.object({ version: z.string() });
@@ -12241,11 +12446,24 @@ async function fetchLatestVersion({ timeoutMs }) {
12241
12446
  return null;
12242
12447
  }
12243
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
+ }
12244
12462
  function printUpdateNotice({ current, latest }) {
12245
12463
  console.error([
12246
12464
  "",
12247
12465
  styleText("yellow", `Update available for ${PACKAGE_NAME}: ${current} → ${latest}`),
12248
- styleText("dim", `Run \`npm install -g ${PACKAGE_NAME}@latest\` to update.`),
12466
+ styleText("dim", "Run `anything update` to update."),
12249
12467
  ""
12250
12468
  ].join("\n"));
12251
12469
  }
@@ -12360,13 +12578,16 @@ function runInstall({ command, args, capture }) {
12360
12578
  });
12361
12579
  }
12362
12580
  const updateCommand = {
12363
- command: "update",
12364
- describe: "Update the CLI to the latest published version",
12365
- 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", {
12366
12587
  type: "boolean",
12367
12588
  default: false,
12368
12589
  describe: "Report whether an update is available without installing it"
12369
- }).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"),
12370
12591
  handler: async (argv) => {
12371
12592
  const latest = await fetchLatestVersion({ timeoutMs: FETCH_TIMEOUT_MS });
12372
12593
  if (latest === null) {
@@ -12382,25 +12603,65 @@ const updateCommand = {
12382
12603
  });
12383
12604
  return;
12384
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;
12385
12644
  const packageManager = detectPackageManager(resolveSelfPath());
12386
12645
  const { command, args } = buildInstallCommand({
12387
12646
  packageManager,
12388
- target: `${PACKAGE_NAME}@${latest}`
12647
+ target: `${PACKAGE_NAME}@${targetVersion}`
12389
12648
  });
12390
12649
  const installCommand = [command, ...args].join(" ");
12391
- if (!isNewerVersion(latest, CLI_VERSION)) {
12650
+ const updateAvailable = isNewerVersion(latest, CLI_VERSION);
12651
+ if (requestedVersion === null ? !updateAvailable : targetVersion === CLI_VERSION) {
12392
12652
  if (outputSuccess({
12393
12653
  argv,
12394
12654
  command: COMMAND$1,
12395
12655
  data: {
12396
12656
  currentVersion: CLI_VERSION,
12397
12657
  latestVersion: latest,
12398
- updateAvailable: false,
12658
+ targetVersion,
12659
+ updateAvailable,
12399
12660
  updated: false
12400
12661
  },
12401
12662
  primaryId: CLI_VERSION
12402
12663
  })) return;
12403
- printSuccess(`Already on the latest version (${CLI_VERSION}).`);
12664
+ printSuccess(requestedVersion === null ? `Already on the latest version (${CLI_VERSION}).` : `Already on version ${CLI_VERSION}.`);
12404
12665
  return;
12405
12666
  }
12406
12667
  if (argv.check) {
@@ -12410,18 +12671,20 @@ const updateCommand = {
12410
12671
  data: {
12411
12672
  currentVersion: CLI_VERSION,
12412
12673
  latestVersion: latest,
12413
- updateAvailable: true,
12674
+ targetVersion,
12675
+ updateAvailable,
12414
12676
  updated: false,
12415
12677
  packageManager,
12416
12678
  installCommand
12417
12679
  },
12418
- primaryId: latest
12680
+ primaryId: targetVersion
12419
12681
  })) return;
12420
12682
  console.log();
12421
12683
  printLabel("Current", CLI_VERSION);
12422
12684
  printLabel("Latest", latest);
12685
+ if (requestedVersion !== null) printLabel("Target", targetVersion);
12423
12686
  console.log();
12424
- 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.`);
12425
12688
  return;
12426
12689
  }
12427
12690
  if (argv["dry-run"]) {
@@ -12431,14 +12694,14 @@ const updateCommand = {
12431
12694
  plannedActions: [{
12432
12695
  action: "update",
12433
12696
  from: CLI_VERSION,
12434
- to: latest,
12697
+ to: targetVersion,
12435
12698
  packageManager,
12436
12699
  command: installCommand
12437
12700
  }]
12438
12701
  });
12439
12702
  return;
12440
12703
  }
12441
- 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}...`);
12442
12705
  let result;
12443
12706
  try {
12444
12707
  result = await runInstall({
@@ -12477,13 +12740,14 @@ const updateCommand = {
12477
12740
  data: {
12478
12741
  previousVersion: CLI_VERSION,
12479
12742
  latestVersion: latest,
12743
+ targetVersion,
12480
12744
  updated: true,
12481
12745
  packageManager,
12482
12746
  installCommand
12483
12747
  },
12484
- primaryId: latest
12748
+ primaryId: targetVersion
12485
12749
  })) return;
12486
- printSuccess(`Updated to ${latest}. Run \`anything --version\` to confirm.`);
12750
+ printSuccess(`Updated to ${targetVersion}. Run \`anything --version\` to confirm.`);
12487
12751
  }
12488
12752
  };
12489
12753
 
@@ -12772,6 +13036,15 @@ const watchCommand = {
12772
13036
 
12773
13037
  //#endregion
12774
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
+ }
12775
13048
  function createCli(argv) {
12776
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", {
12777
13050
  type: "boolean",
@@ -12821,13 +13094,14 @@ function createCli(argv) {
12821
13094
  }
12822
13095
  if (isJson) console.error(JSON.stringify({
12823
13096
  ok: false,
12824
- command: null,
13097
+ command: commandPathFromArgv(argv),
12825
13098
  error: {
12826
13099
  code: "INVALID_ARGUMENTS",
12827
13100
  message
12828
13101
  }
12829
13102
  }, null, 2));
12830
13103
  process.exitCode = EXIT_INVALID_ARGS;
13104
+ throw new HandledCliError(message);
12831
13105
  }).exitProcess(false);
12832
13106
  if (isDevEnvironment()) cli.command(devCommand);
12833
13107
  return cli;
@@ -12835,7 +13109,18 @@ function createCli(argv) {
12835
13109
 
12836
13110
  //#endregion
12837
13111
  //#region src/bin.ts
12838
- 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
+ }
12839
13124
 
12840
13125
  //#endregion
12841
13126
  export { };