@anythingai/cli 0.1.1 → 0.1.3

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.3";
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
  }
@@ -4828,6 +4852,11 @@ var AnythingApiClient = class {
4828
4852
  function printJson(data) {
4829
4853
  console.log(JSON.stringify(data, null, 2));
4830
4854
  }
4855
+ function buildLogsToLines(buildLogs) {
4856
+ const lines = buildLogs.split("\n");
4857
+ if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
4858
+ return lines;
4859
+ }
4831
4860
  function printSuccess(message) {
4832
4861
  console.log(styleText("green", message));
4833
4862
  }
@@ -4876,22 +4905,23 @@ function extractErrorCode(details) {
4876
4905
  const parsed = DetailsWithCodeSchema.safeParse(details);
4877
4906
  return parsed.success ? parsed.data.code : null;
4878
4907
  }
4879
- function outputError({ argv, command, error, hint, exitCode }) {
4908
+ function outputError({ argv, command, error, hint, exitCode, buildLogs, code: codeOverride }) {
4880
4909
  const status = "status" in error ? error.status ?? null : null;
4881
4910
  const details = "details" in error ? error.details : void 0;
4882
4911
  const retryAfter = "retryAfter" in error && typeof error.retryAfter === "number" ? error.retryAfter : null;
4883
4912
  const resolvedHint = hint ?? ("hint" in error && typeof error.hint === "string" ? error.hint : void 0);
4884
4913
  process.exitCode = exitCode ?? exitCodeFromHttpStatus(status);
4885
- const code = extractErrorCode(details) ?? (status === null && exitCode !== void 0 ? errorCodeFromExitCode(exitCode) : errorCodeFromHttpStatus(status));
4914
+ const code = codeOverride ?? extractErrorCode(details) ?? (status === null && exitCode !== void 0 ? errorCodeFromExitCode(exitCode) : errorCodeFromHttpStatus(status));
4886
4915
  if (argv.json || argv.quiet) {
4887
- console.error(JSON.stringify({
4916
+ console.log(JSON.stringify({
4888
4917
  ok: false,
4889
4918
  command,
4890
4919
  error: {
4891
4920
  code,
4892
4921
  message: error.message,
4893
4922
  ...resolvedHint ? { hint: resolvedHint } : {},
4894
- ...retryAfter !== null ? { retry_after_seconds: retryAfter } : {}
4923
+ ...retryAfter !== null ? { retry_after_seconds: retryAfter } : {},
4924
+ ...buildLogs ? { buildLogs: buildLogsToLines(buildLogs) } : {}
4895
4925
  }
4896
4926
  }, null, 2));
4897
4927
  return;
@@ -4903,6 +4933,7 @@ function outputError({ argv, command, error, hint, exitCode }) {
4903
4933
  });
4904
4934
  if (retryAfter !== null) console.error(` ${styleText("dim", `Retry after ${retryAfter}s`)}`);
4905
4935
  if (resolvedHint) console.error(` ${styleText("dim", resolvedHint)}`);
4936
+ if (buildLogs) console.error(`\n${styleText("dim", "Build logs:")}\n${buildLogs}`);
4906
4937
  }
4907
4938
  function outputValidationError({ argv, command, message, hint }) {
4908
4939
  outputError({
@@ -5110,15 +5141,15 @@ const list$2 = {
5110
5141
  });
5111
5142
  return;
5112
5143
  }
5113
- if (argv.quiet) {
5114
- for (const asset of result.value.assets) console.log(asset.id);
5115
- return;
5116
- }
5117
- if (outputSuccess({
5144
+ if (argv.json && outputSuccess({
5118
5145
  argv,
5119
5146
  command,
5120
5147
  data: result.value
5121
5148
  })) return;
5149
+ if (argv.quiet) {
5150
+ for (const asset of result.value.assets) console.log(asset.id);
5151
+ return;
5152
+ }
5122
5153
  const { assets } = result.value;
5123
5154
  if (assets.length === 0) {
5124
5155
  console.log("No assets found.");
@@ -5214,7 +5245,7 @@ const assetsCommand = {
5214
5245
 
5215
5246
  //#endregion
5216
5247
  //#region src/commands/dev.ts
5217
- const COMMAND$26 = "dev";
5248
+ const COMMAND$27 = "dev";
5218
5249
  const devCommand = {
5219
5250
  command: "dev [state]",
5220
5251
  describe: "Toggle local dev mode so commands target your local dev stack",
@@ -5234,7 +5265,7 @@ const devCommand = {
5234
5265
  const apiUrl = resolveApiUrl({ apiUrl: argv.apiUrl });
5235
5266
  if (outputSuccess({
5236
5267
  argv,
5237
- command: COMMAND$26,
5268
+ command: COMMAND$27,
5238
5269
  data: {
5239
5270
  devMode: enabled,
5240
5271
  apiUrl
@@ -5774,7 +5805,7 @@ const authCommand = {
5774
5805
 
5775
5806
  //#endregion
5776
5807
  //#region src/commands/database-connect.ts
5777
- const COMMAND$25 = "databases connect";
5808
+ const COMMAND$26 = "databases connect";
5778
5809
  function maskConnectionString(connectionString) {
5779
5810
  return connectionString.replace(/(\/\/[^:/?#@]+:)[^@/?#]*(@)/, "$1****$2");
5780
5811
  }
@@ -5798,7 +5829,7 @@ const databaseConnectCommand = {
5798
5829
  if (config.isErr()) {
5799
5830
  outputError({
5800
5831
  argv,
5801
- command: COMMAND$25,
5832
+ command: COMMAND$26,
5802
5833
  error: {
5803
5834
  message: config.error.message,
5804
5835
  status: null
@@ -5811,7 +5842,7 @@ const databaseConnectCommand = {
5811
5842
  if (result.isErr()) {
5812
5843
  outputError({
5813
5844
  argv,
5814
- command: COMMAND$25,
5845
+ command: COMMAND$26,
5815
5846
  error: result.error
5816
5847
  });
5817
5848
  return;
@@ -5819,7 +5850,7 @@ const databaseConnectCommand = {
5819
5850
  const connectionString = argv.mask ? maskConnectionString(result.value.connectionString) : result.value.connectionString;
5820
5851
  if (outputSuccess({
5821
5852
  argv,
5822
- command: COMMAND$25,
5853
+ command: COMMAND$26,
5823
5854
  data: {
5824
5855
  ...result.value,
5825
5856
  connectionString
@@ -5876,7 +5907,7 @@ async function resolveOrgId({ flagOrg, config, nonInteractive }) {
5876
5907
 
5877
5908
  //#endregion
5878
5909
  //#region src/commands/database-create.ts
5879
- const COMMAND$24 = "databases create";
5910
+ const COMMAND$25 = "databases create";
5880
5911
  const databaseCreateCommand = {
5881
5912
  command: "create",
5882
5913
  describe: "Create a new database for a project",
@@ -5895,7 +5926,7 @@ const databaseCreateCommand = {
5895
5926
  if (!name) {
5896
5927
  outputError({
5897
5928
  argv,
5898
- command: COMMAND$24,
5929
+ command: COMMAND$25,
5899
5930
  error: {
5900
5931
  message: "Database name is required. Pass --name <name>.",
5901
5932
  status: null
@@ -5911,7 +5942,7 @@ const databaseCreateCommand = {
5911
5942
  if (config.isErr()) {
5912
5943
  outputError({
5913
5944
  argv,
5914
- command: COMMAND$24,
5945
+ command: COMMAND$25,
5915
5946
  error: {
5916
5947
  message: config.error.message,
5917
5948
  status: null
@@ -5928,7 +5959,7 @@ const databaseCreateCommand = {
5928
5959
  if (!orgResult.ok) {
5929
5960
  outputError({
5930
5961
  argv,
5931
- command: COMMAND$24,
5962
+ command: COMMAND$25,
5932
5963
  error: {
5933
5964
  message: orgResult.error,
5934
5965
  status: null
@@ -5940,7 +5971,7 @@ const databaseCreateCommand = {
5940
5971
  if (argv["dry-run"]) {
5941
5972
  outputDryRun({
5942
5973
  argv,
5943
- command: COMMAND$24,
5974
+ command: COMMAND$25,
5944
5975
  plannedActions: [{
5945
5976
  action: "create_database",
5946
5977
  org: orgResult.orgId,
@@ -5958,14 +5989,14 @@ const databaseCreateCommand = {
5958
5989
  if (result.isErr()) {
5959
5990
  outputError({
5960
5991
  argv,
5961
- command: COMMAND$24,
5992
+ command: COMMAND$25,
5962
5993
  error: result.error
5963
5994
  });
5964
5995
  return;
5965
5996
  }
5966
5997
  if (outputSuccess({
5967
5998
  argv,
5968
- command: COMMAND$24,
5999
+ command: COMMAND$25,
5969
6000
  data: result.value.database,
5970
6001
  primaryId: result.value.database.id
5971
6002
  })) return;
@@ -5978,7 +6009,7 @@ const databaseCreateCommand = {
5978
6009
 
5979
6010
  //#endregion
5980
6011
  //#region src/commands/database-get.ts
5981
- const COMMAND$23 = "databases get";
6012
+ const COMMAND$24 = "databases get";
5982
6013
  const databaseGetCommand = {
5983
6014
  command: "get <databaseId>",
5984
6015
  describe: "Inspect a database",
@@ -5995,7 +6026,7 @@ const databaseGetCommand = {
5995
6026
  if (config.isErr()) {
5996
6027
  outputError({
5997
6028
  argv,
5998
- command: COMMAND$23,
6029
+ command: COMMAND$24,
5999
6030
  error: {
6000
6031
  message: config.error.message,
6001
6032
  status: null
@@ -6008,14 +6039,14 @@ const databaseGetCommand = {
6008
6039
  if (result.isErr()) {
6009
6040
  outputError({
6010
6041
  argv,
6011
- command: COMMAND$23,
6042
+ command: COMMAND$24,
6012
6043
  error: result.error
6013
6044
  });
6014
6045
  return;
6015
6046
  }
6016
6047
  if (outputSuccess({
6017
6048
  argv,
6018
- command: COMMAND$23,
6049
+ command: COMMAND$24,
6019
6050
  data: result.value.database,
6020
6051
  primaryId: result.value.database.id
6021
6052
  })) return;
@@ -6030,7 +6061,7 @@ const databaseGetCommand = {
6030
6061
 
6031
6062
  //#endregion
6032
6063
  //#region src/commands/database-query.ts
6033
- const COMMAND$22 = "databases query";
6064
+ const COMMAND$23 = "databases query";
6034
6065
  const databaseQueryCommand = {
6035
6066
  command: "query <databaseId> <sql>",
6036
6067
  describe: "Run a read-only SQL query against a database",
@@ -6051,7 +6082,7 @@ const databaseQueryCommand = {
6051
6082
  if (config.isErr()) {
6052
6083
  outputError({
6053
6084
  argv,
6054
- command: COMMAND$22,
6085
+ command: COMMAND$23,
6055
6086
  error: {
6056
6087
  message: config.error.message,
6057
6088
  status: null
@@ -6067,7 +6098,7 @@ const databaseQueryCommand = {
6067
6098
  if (result.isErr()) {
6068
6099
  outputError({
6069
6100
  argv,
6070
- command: COMMAND$22,
6101
+ command: COMMAND$23,
6071
6102
  error: result.error,
6072
6103
  hint: "Check the database ID and SQL syntax"
6073
6104
  });
@@ -6075,7 +6106,7 @@ const databaseQueryCommand = {
6075
6106
  }
6076
6107
  if (outputSuccess({
6077
6108
  argv,
6078
- command: COMMAND$22,
6109
+ command: COMMAND$23,
6079
6110
  data: result.value
6080
6111
  })) return;
6081
6112
  if (result.value.rows.length === 0) {
@@ -6093,7 +6124,7 @@ const databaseQueryCommand = {
6093
6124
 
6094
6125
  //#endregion
6095
6126
  //#region src/commands/database-reset.ts
6096
- const COMMAND$21 = "databases reset";
6127
+ const COMMAND$22 = "databases reset";
6097
6128
  const databaseResetCommand = {
6098
6129
  command: "reset <databaseId>",
6099
6130
  describe: "Reset a database (destructive)",
@@ -6114,7 +6145,7 @@ const databaseResetCommand = {
6114
6145
  if (config.isErr()) {
6115
6146
  outputError({
6116
6147
  argv,
6117
- command: COMMAND$21,
6148
+ command: COMMAND$22,
6118
6149
  error: {
6119
6150
  message: config.error.message,
6120
6151
  status: null
@@ -6126,7 +6157,7 @@ const databaseResetCommand = {
6126
6157
  if (argv["dry-run"]) {
6127
6158
  outputDryRun({
6128
6159
  argv,
6129
- command: COMMAND$21,
6160
+ command: COMMAND$22,
6130
6161
  plannedActions: [{
6131
6162
  action: "reset_database",
6132
6163
  databaseId: argv.databaseId
@@ -6137,12 +6168,13 @@ const databaseResetCommand = {
6137
6168
  if (!argv.yes) {
6138
6169
  outputError({
6139
6170
  argv,
6140
- command: COMMAND$21,
6171
+ command: COMMAND$22,
6141
6172
  error: {
6142
6173
  message: "Database reset is destructive. Pass --yes to confirm.",
6143
6174
  status: null
6144
6175
  },
6145
- exitCode: 2
6176
+ exitCode: 2,
6177
+ code: "CONFIRMATION_REQUIRED"
6146
6178
  });
6147
6179
  return;
6148
6180
  }
@@ -6150,14 +6182,14 @@ const databaseResetCommand = {
6150
6182
  if (result.isErr()) {
6151
6183
  outputError({
6152
6184
  argv,
6153
- command: COMMAND$21,
6185
+ command: COMMAND$22,
6154
6186
  error: result.error
6155
6187
  });
6156
6188
  return;
6157
6189
  }
6158
6190
  if (outputSuccess({
6159
6191
  argv,
6160
- command: COMMAND$21,
6192
+ command: COMMAND$22,
6161
6193
  data: {
6162
6194
  reset: true,
6163
6195
  databaseId: argv.databaseId
@@ -6167,6 +6199,84 @@ const databaseResetCommand = {
6167
6199
  }
6168
6200
  };
6169
6201
 
6202
+ //#endregion
6203
+ //#region src/commands/database-delete.ts
6204
+ const COMMAND$21 = "databases delete";
6205
+ const databaseDeleteCommand = {
6206
+ command: "delete <databaseId>",
6207
+ aliases: ["remove"],
6208
+ describe: "Delete a database (destructive)",
6209
+ builder: (yargs) => yargs.positional("databaseId", {
6210
+ type: "string",
6211
+ demandOption: true,
6212
+ describe: "The database ID"
6213
+ }).option("yes", {
6214
+ type: "boolean",
6215
+ default: false,
6216
+ describe: "Skip confirmation"
6217
+ }).example("anything databases delete db_123 --yes", "Delete a database without confirmation"),
6218
+ handler: async (argv) => {
6219
+ const config = resolveConfig({
6220
+ dev: argv.dev,
6221
+ apiUrl: argv.apiUrl
6222
+ });
6223
+ if (config.isErr()) {
6224
+ outputError({
6225
+ argv,
6226
+ command: COMMAND$21,
6227
+ error: {
6228
+ message: config.error.message,
6229
+ status: null
6230
+ },
6231
+ exitCode: 4
6232
+ });
6233
+ return;
6234
+ }
6235
+ if (argv["dry-run"]) {
6236
+ outputDryRun({
6237
+ argv,
6238
+ command: COMMAND$21,
6239
+ plannedActions: [{
6240
+ action: "delete_database",
6241
+ databaseId: argv.databaseId
6242
+ }]
6243
+ });
6244
+ return;
6245
+ }
6246
+ if (!argv.yes) {
6247
+ outputError({
6248
+ argv,
6249
+ command: COMMAND$21,
6250
+ error: {
6251
+ message: "Database deletion is destructive. Pass --yes to confirm.",
6252
+ status: null
6253
+ },
6254
+ exitCode: 2,
6255
+ code: "CONFIRMATION_REQUIRED"
6256
+ });
6257
+ return;
6258
+ }
6259
+ const result = await new AnythingApiClient(config.value).deleteDatabase({ databaseId: argv.databaseId });
6260
+ if (result.isErr()) {
6261
+ outputError({
6262
+ argv,
6263
+ command: COMMAND$21,
6264
+ error: result.error
6265
+ });
6266
+ return;
6267
+ }
6268
+ if (outputSuccess({
6269
+ argv,
6270
+ command: COMMAND$21,
6271
+ data: {
6272
+ deleted: true,
6273
+ databaseId: argv.databaseId
6274
+ }
6275
+ })) return;
6276
+ printSuccess(`Database ${argv.databaseId} deleted. It can be restored within 30 days.`);
6277
+ }
6278
+ };
6279
+
6170
6280
  //#endregion
6171
6281
  //#region src/commands/list-databases.ts
6172
6282
  const COMMAND$20 = "databases list";
@@ -6211,15 +6321,15 @@ const listDatabasesCommand = {
6211
6321
  });
6212
6322
  return;
6213
6323
  }
6214
- if (argv.quiet) {
6215
- for (const db of result.value.databases) console.log(db.id);
6216
- return;
6217
- }
6218
- if (outputSuccess({
6324
+ if (argv.json && outputSuccess({
6219
6325
  argv,
6220
6326
  command: COMMAND$20,
6221
6327
  data: result.value
6222
6328
  })) return;
6329
+ if (argv.quiet) {
6330
+ for (const db of result.value.databases) console.log(db.id);
6331
+ return;
6332
+ }
6223
6333
  if (result.value.databases.length === 0) {
6224
6334
  console.log("No databases found.");
6225
6335
  return;
@@ -6254,7 +6364,7 @@ const databasesListCommand = {
6254
6364
  const databasesCommand = {
6255
6365
  command: "databases",
6256
6366
  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."),
6367
+ 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
6368
  handler: () => {}
6259
6369
  };
6260
6370
 
@@ -6302,15 +6412,15 @@ const deploymentsListCommand = {
6302
6412
  });
6303
6413
  return;
6304
6414
  }
6305
- if (argv.quiet) {
6306
- for (const deployment of result.value.deployments) console.log(deployment.id);
6307
- return;
6308
- }
6309
- if (outputSuccess({
6415
+ if (argv.json && outputSuccess({
6310
6416
  argv,
6311
6417
  command,
6312
6418
  data: result.value
6313
6419
  })) return;
6420
+ if (argv.quiet) {
6421
+ for (const deployment of result.value.deployments) console.log(deployment.id);
6422
+ return;
6423
+ }
6314
6424
  if (result.value.deployments.length === 0) {
6315
6425
  console.log("No deployments found.");
6316
6426
  return;
@@ -6442,20 +6552,17 @@ const deploymentsLogsCommand = {
6442
6552
  }
6443
6553
  };
6444
6554
  const deploymentsRollbackCommand = {
6445
- command: "rollback <projectId> [deploymentId]",
6446
- describe: "Rollback to a previous deployment",
6555
+ command: "rollback <projectId>",
6556
+ describe: "Roll a project back to its previous deployment",
6447
6557
  builder: (yargs) => yargs.positional("projectId", {
6448
6558
  type: "string",
6449
6559
  demandOption: true,
6450
- describe: "The project ID"
6451
- }).positional("deploymentId", {
6452
- type: "string",
6453
- describe: "Specific deployment ID to rollback to (defaults to previous)"
6560
+ describe: "The project ID to roll back"
6454
6561
  }).option("yes", {
6455
6562
  type: "boolean",
6456
6563
  default: false,
6457
6564
  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"),
6565
+ }).example("anything deployments rollback pg_123 --yes", "Roll the project back to its previous deployment"),
6459
6566
  handler: async (argv) => {
6460
6567
  const command = "deployments rollback";
6461
6568
  const config = resolveConfig({
@@ -6480,8 +6587,7 @@ const deploymentsRollbackCommand = {
6480
6587
  command,
6481
6588
  plannedActions: [{
6482
6589
  action: "rollback_deployment",
6483
- projectId: argv.projectId,
6484
- ...argv.deploymentId ? { deploymentId: argv.deploymentId } : {}
6590
+ projectId: argv.projectId
6485
6591
  }]
6486
6592
  });
6487
6593
  return;
@@ -6494,14 +6600,12 @@ const deploymentsRollbackCommand = {
6494
6600
  message: "Rollback is destructive. Pass --yes to confirm.",
6495
6601
  status: null
6496
6602
  },
6497
- exitCode: 2
6603
+ exitCode: 2,
6604
+ code: "CONFIRMATION_REQUIRED"
6498
6605
  });
6499
6606
  return;
6500
6607
  }
6501
- const result = await new AnythingApiClient(config.value).rollbackDeployment({
6502
- projectGroupId: argv.projectId,
6503
- deploymentId: argv.deploymentId ?? null
6504
- });
6608
+ const result = await new AnythingApiClient(config.value).rollbackDeployment({ projectGroupId: argv.projectId });
6505
6609
  if (result.isErr()) {
6506
6610
  outputError({
6507
6611
  argv,
@@ -6530,9 +6634,37 @@ const deploymentsCommand = {
6530
6634
  handler: () => {}
6531
6635
  };
6532
6636
 
6637
+ //#endregion
6638
+ //#region src/domains-format.ts
6639
+ function toPublicDomain(domain) {
6640
+ return {
6641
+ id: domain.id,
6642
+ domain: domain.domain,
6643
+ verified: domain.vercelVerified,
6644
+ verificationChallenges: domain.vercelVerification ?? null,
6645
+ projectGroup: domain.projectGroup
6646
+ };
6647
+ }
6648
+
6533
6649
  //#endregion
6534
6650
  //#region src/commands/domain-add.ts
6535
6651
  const COMMAND$19 = "domains add";
6652
+ const HOSTNAME_PATTERN = /^(?=.{1,253}$)([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
6653
+ const RESERVED_TLDS = new Set([
6654
+ "invalid",
6655
+ "example",
6656
+ "test",
6657
+ "localhost"
6658
+ ]);
6659
+ function domainValidationError(domain) {
6660
+ if (/^[a-zA-Z][a-zA-Z0-9+.-]*:\/\//.test(domain)) return `Enter a bare hostname without a scheme (got "${domain}"). Example: app.example.com`;
6661
+ if (domain.includes("/") || /\s/.test(domain)) return `Invalid domain "${domain}". Enter a bare hostname like app.example.com`;
6662
+ if (!domain.includes(".")) return `Invalid domain "${domain}". A domain must include a dot, e.g. app.example.com`;
6663
+ if (!HOSTNAME_PATTERN.test(domain)) return `Invalid domain "${domain}". Enter a valid hostname like app.example.com`;
6664
+ const tld = domain.split(".").pop()?.toLowerCase() ?? "";
6665
+ if (RESERVED_TLDS.has(tld)) return `Invalid domain "${domain}". ".${tld}" is a reserved TLD that cannot be used for a real domain. Use a registered domain like app.example.com`;
6666
+ return null;
6667
+ }
6536
6668
  const domainAddCommand = {
6537
6669
  command: "add <domain>",
6538
6670
  describe: "Add a custom domain to a project",
@@ -6548,6 +6680,19 @@ const domainAddCommand = {
6548
6680
  describe: "Project ID to link the domain to"
6549
6681
  }).example("anything domains add app.example.com --project pg_123", "Add a custom domain to a project"),
6550
6682
  handler: async (argv) => {
6683
+ const validationMessage = domainValidationError(argv.domain);
6684
+ if (validationMessage) {
6685
+ outputError({
6686
+ argv,
6687
+ command: COMMAND$19,
6688
+ error: {
6689
+ message: validationMessage,
6690
+ status: null
6691
+ },
6692
+ exitCode: 2
6693
+ });
6694
+ return;
6695
+ }
6551
6696
  const config = resolveConfig({
6552
6697
  dev: argv.dev,
6553
6698
  apiUrl: argv.apiUrl
@@ -6610,7 +6755,7 @@ const domainAddCommand = {
6610
6755
  if (outputSuccess({
6611
6756
  argv,
6612
6757
  command: COMMAND$19,
6613
- data: result.value.domain,
6758
+ data: toPublicDomain(result.value.domain),
6614
6759
  primaryId: result.value.domain.domain
6615
6760
  })) return;
6616
6761
  printSuccess(`Domain added: ${result.value.domain.domain}`);
@@ -6670,7 +6815,8 @@ const domainRemoveCommand = {
6670
6815
  message: "Domain removal is destructive. Pass --yes to confirm.",
6671
6816
  status: null
6672
6817
  },
6673
- exitCode: 2
6818
+ exitCode: 2,
6819
+ code: "CONFIRMATION_REQUIRED"
6674
6820
  });
6675
6821
  return;
6676
6822
  }
@@ -6790,15 +6936,16 @@ const domainsListCommand = {
6790
6936
  });
6791
6937
  return;
6792
6938
  }
6939
+ const jsonData = { domains: result.value.domains.map(toPublicDomain) };
6940
+ if (argv.json && outputSuccess({
6941
+ argv,
6942
+ command,
6943
+ data: jsonData
6944
+ })) return;
6793
6945
  if (argv.quiet) {
6794
6946
  for (const domain of result.value.domains) console.log(domain.domain);
6795
6947
  return;
6796
6948
  }
6797
- if (outputSuccess({
6798
- argv,
6799
- command,
6800
- data: result.value
6801
- })) return;
6802
6949
  if (result.value.domains.length === 0) {
6803
6950
  console.log("No domains found.");
6804
6951
  return;
@@ -8128,6 +8275,7 @@ const linkCommand = {
8128
8275
  orgId,
8129
8276
  projectId: projectGroupId
8130
8277
  }, null, 2) + "\n");
8278
+ setStoredProjectGroupId(projResult.value.id);
8131
8279
  if (outputSuccess({
8132
8280
  argv,
8133
8281
  command,
@@ -8163,7 +8311,9 @@ const unlinkCommand = {
8163
8311
  });
8164
8312
  return;
8165
8313
  }
8314
+ const linked = readLinkedProject();
8166
8315
  rmSync(projectFile);
8316
+ if (linked && getStoredProjectGroupId() === linked.projectId) clearStoredProjectGroupId();
8167
8317
  try {
8168
8318
  if (existsSync(dir) && readdirSync(dir).length === 0) rmSync(dir, { recursive: true });
8169
8319
  } catch {}
@@ -8366,6 +8516,22 @@ const llmContextCommand = {
8366
8516
  }
8367
8517
  };
8368
8518
 
8519
+ //#endregion
8520
+ //#region src/member-roles.ts
8521
+ function formatRole(role) {
8522
+ if (role === null) return null;
8523
+ switch (role.toUpperCase()) {
8524
+ case "OWNER": return "Owner";
8525
+ case "ADMIN": return "Admin";
8526
+ case "EDITOR": return "Editor";
8527
+ case "VIEWER": return "Viewer";
8528
+ default: return role;
8529
+ }
8530
+ }
8531
+ function normalizeRole(role) {
8532
+ return role === null ? null : role.toLowerCase();
8533
+ }
8534
+
8369
8535
  //#endregion
8370
8536
  //#region src/commands/members.ts
8371
8537
  const MEMBER_ROLE_CHOICES = [
@@ -8429,7 +8595,17 @@ const membersListCommand = {
8429
8595
  if (outputSuccess({
8430
8596
  argv,
8431
8597
  command,
8432
- data: result.value
8598
+ data: {
8599
+ organization: {
8600
+ ...result.value.organization,
8601
+ role: normalizeRole(result.value.organization.role)
8602
+ },
8603
+ members: result.value.collaborators.map((collaborator) => ({
8604
+ ...collaborator,
8605
+ role: normalizeRole(collaborator.role)
8606
+ })),
8607
+ pendingInvites: result.value.pendingInvites
8608
+ }
8433
8609
  })) return;
8434
8610
  if (result.value.collaborators.length > 0) printTable({
8435
8611
  headers: [
@@ -8440,7 +8616,7 @@ const membersListCommand = {
8440
8616
  rows: result.value.collaborators.map((c) => [
8441
8617
  c.displayName,
8442
8618
  c.email ?? "-",
8443
- c.role
8619
+ formatRole(c.role) ?? c.role
8444
8620
  ])
8445
8621
  });
8446
8622
  if (result.value.pendingInvites.length > 0) {
@@ -8629,7 +8805,8 @@ const membersRemoveCommand = {
8629
8805
  message: "Member removal is destructive. Pass --yes to confirm.",
8630
8806
  status: null
8631
8807
  },
8632
- exitCode: 2
8808
+ exitCode: 2,
8809
+ code: "CONFIRMATION_REQUIRED"
8633
8810
  });
8634
8811
  return;
8635
8812
  }
@@ -8762,16 +8939,6 @@ const humanizeCredits = (credits) => {
8762
8939
 
8763
8940
  //#endregion
8764
8941
  //#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
8942
  const orgMembersCommand = {
8776
8943
  command: "members <organizationId>",
8777
8944
  describe: "Inspect collaborators and pending invites for an organization",
@@ -8810,7 +8977,17 @@ const orgMembersCommand = {
8810
8977
  if (outputSuccess({
8811
8978
  argv,
8812
8979
  command,
8813
- data: result.value
8980
+ data: {
8981
+ organization: {
8982
+ ...result.value.organization,
8983
+ role: normalizeRole(result.value.organization.role)
8984
+ },
8985
+ members: result.value.collaborators.map((collaborator) => ({
8986
+ ...collaborator,
8987
+ role: normalizeRole(collaborator.role)
8988
+ })),
8989
+ pendingInvites: result.value.pendingInvites
8990
+ }
8814
8991
  })) return;
8815
8992
  console.log();
8816
8993
  printLabel("Organization", result.value.organization.name);
@@ -8856,7 +9033,7 @@ const orgMembersCommand = {
8856
9033
 
8857
9034
  //#endregion
8858
9035
  //#region src/commands/orgs.ts
8859
- async function loadOrganizations(argv) {
9036
+ async function loadOrganizations(argv, command) {
8860
9037
  const config = resolveConfig({
8861
9038
  dev: argv.dev,
8862
9039
  apiUrl: argv.apiUrl
@@ -8864,7 +9041,7 @@ async function loadOrganizations(argv) {
8864
9041
  if (config.isErr()) {
8865
9042
  outputError({
8866
9043
  argv,
8867
- command: "orgs",
9044
+ command,
8868
9045
  error: {
8869
9046
  message: config.error.message,
8870
9047
  status: null
@@ -8877,7 +9054,7 @@ async function loadOrganizations(argv) {
8877
9054
  if (result.isErr()) {
8878
9055
  outputError({
8879
9056
  argv,
8880
- command: "orgs",
9057
+ command,
8881
9058
  error: result.error
8882
9059
  });
8883
9060
  return null;
@@ -8897,7 +9074,7 @@ const getCommand = {
8897
9074
  }).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
9075
  handler: async (argv) => {
8899
9076
  const command = "orgs get";
8900
- const organizations = await loadOrganizations(argv);
9077
+ const organizations = await loadOrganizations(argv, command);
8901
9078
  if (!organizations) return;
8902
9079
  const organization = organizations.find((org) => org.id === argv.organizationId);
8903
9080
  if (!organization) {
@@ -8932,14 +9109,10 @@ const listOrgs = {
8932
9109
  builder: (yargs) => yargs.example("anything orgs list", "List orgs available to the current user"),
8933
9110
  handler: async (argv) => {
8934
9111
  const command = "orgs list";
8935
- const organizations = await loadOrganizations(argv);
9112
+ const organizations = await loadOrganizations(argv, command);
8936
9113
  if (!organizations) return;
8937
9114
  const activeOrgId = getStoredOrgId();
8938
- if (argv.quiet) {
8939
- for (const org of organizations) console.log(org.id);
8940
- return;
8941
- }
8942
- if (outputSuccess({
9115
+ if (argv.json && outputSuccess({
8943
9116
  argv,
8944
9117
  command,
8945
9118
  data: {
@@ -8947,6 +9120,10 @@ const listOrgs = {
8947
9120
  activeOrgId: activeOrgId ?? null
8948
9121
  }
8949
9122
  })) return;
9123
+ if (argv.quiet) {
9124
+ for (const org of organizations) console.log(org.id);
9125
+ return;
9126
+ }
8950
9127
  if (organizations.length === 0) {
8951
9128
  console.log("No organizations found.");
8952
9129
  return;
@@ -8975,7 +9152,7 @@ const setOrg = {
8975
9152
  }).example("anything orgs set org_abc123", "Set the active organization"),
8976
9153
  handler: async (argv) => {
8977
9154
  const command = "orgs set";
8978
- const organizations = await loadOrganizations(argv);
9155
+ const organizations = await loadOrganizations(argv, command);
8979
9156
  if (!organizations) return;
8980
9157
  const org = organizations.find((o) => o.id === argv["org-id"]);
8981
9158
  if (!org) {
@@ -9350,10 +9527,6 @@ const createCommand = {
9350
9527
  message: "Project created"
9351
9528
  });
9352
9529
  if (!argv.wait) {
9353
- if (argv.quiet) {
9354
- console.log(result.value.projectGroupId);
9355
- return;
9356
- }
9357
9530
  if (argv.json) {
9358
9531
  printNdjson({
9359
9532
  type: "result",
@@ -9362,6 +9535,10 @@ const createCommand = {
9362
9535
  });
9363
9536
  return;
9364
9537
  }
9538
+ if (argv.quiet) {
9539
+ console.log(result.value.projectGroupId);
9540
+ return;
9541
+ }
9365
9542
  printStreamMarker("done", `project ${result.value.projectGroupId} created`);
9366
9543
  printSuccess("App created! Generation enqueued.");
9367
9544
  printLabel("Project Group ID", result.value.projectGroupId);
@@ -9380,27 +9557,11 @@ const createCommand = {
9380
9557
  projectGroupId: result.value.projectGroupId,
9381
9558
  emit
9382
9559
  });
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
9560
  if (argv.json) {
9561
+ if (succeeded === false) {
9562
+ process.exitCode = 1;
9563
+ return;
9564
+ }
9404
9565
  const { projectGroupId: projectId, ...rest } = result.value;
9405
9566
  printNdjson({
9406
9567
  type: "result",
@@ -9410,12 +9571,30 @@ const createCommand = {
9410
9571
  ...rest
9411
9572
  }
9412
9573
  });
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);
9574
+ return;
9418
9575
  }
9576
+ if (argv.quiet) {
9577
+ console.log(result.value.projectGroupId);
9578
+ if (succeeded === false) process.exitCode = 1;
9579
+ return;
9580
+ }
9581
+ if (succeeded === false) {
9582
+ outputError({
9583
+ argv,
9584
+ command: COMMAND$16,
9585
+ error: {
9586
+ message: "Generation failed.",
9587
+ status: null
9588
+ }
9589
+ });
9590
+ printLabel("Project Group ID", result.value.projectGroupId);
9591
+ process.exitCode = 1;
9592
+ return;
9593
+ }
9594
+ printStreamMarker("done", `project ${result.value.projectGroupId} ready`);
9595
+ printSuccess("App created! Generation complete.");
9596
+ printLabel("Project ID", result.value.projectGroupId);
9597
+ printLabel("Revision ID", result.value.revisionId);
9419
9598
  }
9420
9599
  };
9421
9600
 
@@ -9459,14 +9638,16 @@ async function waitForDeployment({ client, deploymentId, emit }) {
9459
9638
  function getDeploymentError({ result, statusCommand }) {
9460
9639
  if (result.outcome === "timeout") return {
9461
9640
  message: `Deployment timed out. Check status with: ${statusCommand}`,
9462
- exitCode: 6
9641
+ exitCode: 6,
9642
+ buildLogs: null
9463
9643
  };
9464
9644
  if (result.deployment.status === "FAILED") {
9465
9645
  const reason = result.deployment.failureReason ?? null;
9466
9646
  const logs = result.deployment.buildLogs ?? null;
9467
9647
  return {
9468
- message: reason ? logs ? `${reason}\n\n${logs}` : reason : logs ?? "Deployment failed (no logs available).",
9469
- exitCode: 1
9648
+ message: reason ?? (logs ? "Deployment failed. See build logs for details." : "Deployment failed (no logs available)."),
9649
+ exitCode: 1,
9650
+ buildLogs: logs
9470
9651
  };
9471
9652
  }
9472
9653
  return null;
@@ -9531,7 +9712,8 @@ const publishStatusCommand = {
9531
9712
  status: null
9532
9713
  },
9533
9714
  hint: `Inspect the full build logs with: anything deployments logs ${argv.deploymentId}`,
9534
- exitCode: failure?.exitCode ?? 1
9715
+ exitCode: failure?.exitCode ?? 1,
9716
+ buildLogs: failure?.buildLogs ?? void 0
9535
9717
  });
9536
9718
  return;
9537
9719
  }
@@ -9679,7 +9861,8 @@ const publishCommand = {
9679
9861
  message: deployError.message,
9680
9862
  status: null
9681
9863
  },
9682
- exitCode: deployError.exitCode
9864
+ exitCode: deployError.exitCode,
9865
+ buildLogs: deployError.buildLogs ?? void 0
9683
9866
  });
9684
9867
  return;
9685
9868
  }
@@ -9810,15 +9993,15 @@ const list$1 = {
9810
9993
  });
9811
9994
  return;
9812
9995
  }
9813
- if (argv.quiet) {
9814
- for (const file of result.value.files) console.log(file.path);
9815
- return;
9816
- }
9817
- if (outputSuccess({
9996
+ if (argv.json && outputSuccess({
9818
9997
  argv,
9819
9998
  command,
9820
9999
  data: result.value
9821
10000
  })) return;
10001
+ if (argv.quiet) {
10002
+ for (const file of result.value.files) console.log(file.path);
10003
+ return;
10004
+ }
9822
10005
  if (result.value.files.length === 0) {
9823
10006
  console.log("No files found.");
9824
10007
  return;
@@ -9983,10 +10166,6 @@ const generateCommand = {
9983
10166
  return;
9984
10167
  }
9985
10168
  if (!argv.wait) {
9986
- if (argv.quiet) {
9987
- console.log(result.value.revisionId);
9988
- return;
9989
- }
9990
10169
  if (argv.json) {
9991
10170
  printNdjson({
9992
10171
  type: "result",
@@ -9995,6 +10174,10 @@ const generateCommand = {
9995
10174
  });
9996
10175
  return;
9997
10176
  }
10177
+ if (argv.quiet) {
10178
+ console.log(result.value.revisionId);
10179
+ return;
10180
+ }
9998
10181
  printStreamMarker("done", `revision ${result.value.revisionId} enqueued`);
9999
10182
  printSuccess("Generation enqueued.");
10000
10183
  printLabel("Revision ID", result.value.revisionId);
@@ -10007,32 +10190,31 @@ const generateCommand = {
10007
10190
  status: "running",
10008
10191
  message: "Generation in progress..."
10009
10192
  });
10010
- const succeeded = await watchGeneration({
10193
+ if (await watchGeneration({
10011
10194
  config: config.value,
10012
10195
  client,
10013
10196
  projectGroupId: argv.projectId,
10014
10197
  emit
10015
- });
10016
- if (argv.quiet) {
10017
- console.log(result.value.revisionId);
10018
- if (succeeded === false) process.exitCode = 1;
10198
+ }) === false) {
10199
+ process.exitCode = 1;
10019
10200
  return;
10020
10201
  }
10021
- if (succeeded === false) {
10022
- process.exitCode = 1;
10202
+ if (argv.json) {
10203
+ printNdjson({
10204
+ type: "result",
10205
+ ok: true,
10206
+ data: result.value
10207
+ });
10023
10208
  return;
10024
10209
  }
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);
10210
+ if (argv.quiet) {
10211
+ console.log(result.value.revisionId);
10212
+ return;
10035
10213
  }
10214
+ printStreamMarker("done", `revision ${result.value.revisionId} ready`);
10215
+ printSuccess("Generation complete.");
10216
+ printLabel("Revision ID", result.value.revisionId);
10217
+ printLabel("Thread ID", result.value.threadId);
10036
10218
  }
10037
10219
  };
10038
10220
 
@@ -10253,15 +10435,15 @@ const listProjectsCommand = {
10253
10435
  });
10254
10436
  return;
10255
10437
  }
10256
- if (argv.quiet) {
10257
- for (const project of result.value.projects) console.log(project.id);
10258
- return;
10259
- }
10260
- if (outputSuccess({
10438
+ if (argv.json && outputSuccess({
10261
10439
  argv,
10262
10440
  command: COMMAND$11,
10263
10441
  data: result.value
10264
10442
  })) return;
10443
+ if (argv.quiet) {
10444
+ for (const project of result.value.projects) console.log(project.id);
10445
+ return;
10446
+ }
10265
10447
  if (result.value.projects.length === 0) {
10266
10448
  console.log("No projects found.");
10267
10449
  return;
@@ -10349,9 +10531,9 @@ const logsCommand = {
10349
10531
  describe: "Show logs since a duration ago (e.g. 1h, 30m, 2d). Only applies to initial fetch."
10350
10532
  }).option("follow", {
10351
10533
  type: "boolean",
10352
- alias: "f",
10534
+ alias: ["f", "tail"],
10353
10535
  default: false,
10354
- describe: "Tail logs in real-time (stream)"
10536
+ describe: "Tail logs in real-time (stream). Alias: --tail"
10355
10537
  }).option("interval", {
10356
10538
  type: "number",
10357
10539
  default: DEFAULT_POLL_INTERVAL_MS$1,
@@ -10399,7 +10581,7 @@ const logsCommand = {
10399
10581
  data: { logs }
10400
10582
  })) return;
10401
10583
  if (logs.length === 0) {
10402
- console.log("No logs found.");
10584
+ console.log("No development logs found. This command reads dev-server logs, not production deployment logs (use `anything deployments logs <deploymentId>` for those).");
10403
10585
  return;
10404
10586
  }
10405
10587
  for (const log of logs) formatLog(log);
@@ -10776,6 +10958,7 @@ const secretEnvironmentChoices = [
10776
10958
  "preview",
10777
10959
  "production"
10778
10960
  ];
10961
+ const DEFAULT_SECRET_ENVIRONMENT = "DEVELOPMENT";
10779
10962
  const add = {
10780
10963
  command: "add <projectId>",
10781
10964
  describe: "Add a secret to an app",
@@ -10792,8 +10975,13 @@ const add = {
10792
10975
  describe: "Secret value. If omitted, reads stdin when piped."
10793
10976
  }).option("env", {
10794
10977
  type: "string",
10978
+ coerce: (value) => value.toLowerCase(),
10795
10979
  choices: secretEnvironmentChoices,
10796
10980
  describe: "Target environment for the secret"
10981
+ }).option("force", {
10982
+ type: "boolean",
10983
+ default: false,
10984
+ describe: "Allow adding a secret whose name already exists in the target environment (creates a suffixed sibling)"
10797
10985
  }).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
10986
  handler: async (argv) => {
10799
10987
  const command = "projects secrets add";
@@ -10843,11 +11031,30 @@ const add = {
10843
11031
  });
10844
11032
  return;
10845
11033
  }
10846
- const result = await new AnythingApiClient(config.value).addSecret({
11034
+ const client = new AnythingApiClient(config.value);
11035
+ const targetEnvironment = argv.env ? argv.env.toUpperCase() : DEFAULT_SECRET_ENVIRONMENT;
11036
+ if (!argv.force) {
11037
+ const existing = await client.listSecrets({ projectGroupId: argv.projectId });
11038
+ if (existing.isOk()) {
11039
+ if (existing.value.secrets.find((secret) => secret.displayName === argv.name && secret.environment === targetEnvironment)) {
11040
+ outputError({
11041
+ argv,
11042
+ command,
11043
+ error: {
11044
+ message: `A secret named "${argv.name}" already exists in ${targetEnvironment}.`,
11045
+ status: 409
11046
+ },
11047
+ hint: "Remove the existing secret first, or pass --force to create a suffixed sibling."
11048
+ });
11049
+ return;
11050
+ }
11051
+ }
11052
+ }
11053
+ const result = await client.addSecret({
10847
11054
  projectGroupId: argv.projectId,
10848
11055
  displayName: argv.name,
10849
11056
  value: valueResult.value,
10850
- environment: argv.env ? argv.env.toUpperCase() : null
11057
+ environment: targetEnvironment
10851
11058
  });
10852
11059
  if (result.isErr()) {
10853
11060
  outputError({
@@ -10908,7 +11115,8 @@ const remove = {
10908
11115
  message: "Removing a secret is destructive. Pass --yes to confirm.",
10909
11116
  status: null
10910
11117
  },
10911
- exitCode: 2
11118
+ exitCode: 2,
11119
+ code: "CONFIRMATION_REQUIRED"
10912
11120
  });
10913
11121
  return;
10914
11122
  }
@@ -10984,15 +11192,15 @@ const list = {
10984
11192
  });
10985
11193
  return;
10986
11194
  }
10987
- if (argv.quiet) {
10988
- for (const secret of result.value.secrets) console.log(secret.id);
10989
- return;
10990
- }
10991
- if (outputSuccess({
11195
+ if (argv.json && outputSuccess({
10992
11196
  argv,
10993
11197
  command,
10994
11198
  data: result.value
10995
11199
  })) return;
11200
+ if (argv.quiet) {
11201
+ for (const secret of result.value.secrets) console.log(secret.id);
11202
+ return;
11203
+ }
10996
11204
  if (result.value.secrets.length === 0) {
10997
11205
  console.log("No secrets found.");
10998
11206
  return;
@@ -11172,6 +11380,7 @@ const set = {
11172
11380
  array: true,
11173
11381
  describe: "Provider secret in ENV_KEY=VALUE format. Repeat for multiple secrets."
11174
11382
  }).option("env", {
11383
+ coerce: (value) => value.toLowerCase(),
11175
11384
  choices: authEnvironmentChoices,
11176
11385
  default: "production",
11177
11386
  describe: "Environment for secrets passed via --secret"
@@ -11376,7 +11585,7 @@ const unpublishCommand = {
11376
11585
  const COMMAND$5 = "projects delete";
11377
11586
  const deleteProjectCommand = {
11378
11587
  command: "delete <projectId>",
11379
- describe: "Delete a project permanently (gated behind the project-delete-enabled flag; returns 404 when disabled)",
11588
+ describe: "Delete a project permanently (gated behind the project-delete-enabled flag; returns 403 when disabled)",
11380
11589
  builder: (yargs) => yargs.positional("projectId", {
11381
11590
  type: "string",
11382
11591
  demandOption: true,
@@ -11406,7 +11615,8 @@ const deleteProjectCommand = {
11406
11615
  message: "Project deletion is destructive and cannot be undone. Pass --yes to confirm.",
11407
11616
  status: null
11408
11617
  },
11409
- exitCode: 2
11618
+ exitCode: 2,
11619
+ code: "CONFIRMATION_REQUIRED"
11410
11620
  });
11411
11621
  return;
11412
11622
  }
@@ -11429,12 +11639,10 @@ const deleteProjectCommand = {
11429
11639
  const startTime = performance.now();
11430
11640
  const result = await new AnythingApiClient(config.value).deleteProject({ projectGroupId: argv.projectId });
11431
11641
  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
11642
  outputError({
11434
11643
  argv,
11435
11644
  command: COMMAND$5,
11436
- error: result.error,
11437
- hint
11645
+ error: result.error
11438
11646
  });
11439
11647
  return;
11440
11648
  }
@@ -11924,7 +12132,8 @@ const shipCommand = {
11924
12132
  message: deployError.message,
11925
12133
  status: null
11926
12134
  },
11927
- exitCode: deployError.exitCode
12135
+ exitCode: deployError.exitCode,
12136
+ buildLogs: deployError.buildLogs ?? void 0
11928
12137
  });
11929
12138
  return;
11930
12139
  }
@@ -11936,27 +12145,28 @@ const shipCommand = {
11936
12145
  message: "Published"
11937
12146
  });
11938
12147
  const url = publishResult.value.slug ? `https://${publishResult.value.slug}.created.app` : null;
12148
+ if (argv.json) {
12149
+ printNdjson({
12150
+ type: "result",
12151
+ ok: true,
12152
+ data: {
12153
+ projectId: projectGroupId,
12154
+ published: true,
12155
+ deploymentId,
12156
+ slug: publishResult.value.slug,
12157
+ url
12158
+ }
12159
+ });
12160
+ return;
12161
+ }
11939
12162
  if (argv.quiet) {
11940
12163
  console.log(url ?? projectGroupId);
11941
12164
  return;
11942
12165
  }
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
- }
12166
+ printStreamMarker("done", url ?? projectGroupId);
12167
+ printSuccess("Shipped!");
12168
+ printLabel("Project ID", projectGroupId);
12169
+ if (url) printLabel("URL", url);
11960
12170
  }
11961
12171
  };
11962
12172
 
@@ -12219,9 +12429,11 @@ const switchCommand = {
12219
12429
  //#endregion
12220
12430
  //#region src/update-check.ts
12221
12431
  const PACKAGE_NAME = "@anythingai/cli";
12222
- const REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
12223
- const CHECK_INTERVAL_MS = 1440 * 60 * 1e3;
12224
- const NOTICE_FETCH_TIMEOUT_MS = 1500;
12432
+ const REGISTRY_BASE_URL = `https://registry.npmjs.org/${PACKAGE_NAME}`;
12433
+ const REGISTRY_URL = `${REGISTRY_BASE_URL}/latest`;
12434
+ const INTERNAL_UPDATE_CHECK_ARG = "__update-check";
12435
+ const CHECK_INTERVAL_MS = 10800 * 1e3;
12436
+ const REFRESH_FETCH_TIMEOUT_MS = 1e4;
12225
12437
  const latestManifestSchema = z.object({ version: z.string() });
12226
12438
  function isNewerVersion(candidate, current) {
12227
12439
  const core = (v) => (v.split("-")[0] ?? "").split(".").map((part) => Number.parseInt(part, 10));
@@ -12248,38 +12460,83 @@ async function fetchLatestVersion({ timeoutMs }) {
12248
12460
  return null;
12249
12461
  }
12250
12462
  }
12463
+ async function lookupVersion({ version, timeoutMs }) {
12464
+ try {
12465
+ const response = await fetch(`${REGISTRY_BASE_URL}/${encodeURIComponent(version)}`, {
12466
+ signal: AbortSignal.timeout(timeoutMs),
12467
+ headers: { accept: "application/json" }
12468
+ });
12469
+ if (response.status === 404) return { status: "not-found" };
12470
+ if (!response.ok) return { status: "unreachable" };
12471
+ return latestManifestSchema.safeParse(await response.json()).success ? { status: "exists" } : { status: "not-found" };
12472
+ } catch {
12473
+ return { status: "unreachable" };
12474
+ }
12475
+ }
12251
12476
  function printUpdateNotice({ current, latest }) {
12252
12477
  console.error([
12253
12478
  "",
12254
12479
  styleText("yellow", `Update available for ${PACKAGE_NAME}: ${current} → ${latest}`),
12255
- styleText("dim", `Run \`npm install -g ${PACKAGE_NAME}@latest\` to update.`),
12480
+ styleText("dim", "Run `anything update` to update."),
12256
12481
  ""
12257
12482
  ].join("\n"));
12258
12483
  }
12259
- async function notifyIfUpdateAvailable(now) {
12484
+ function spawnBackgroundRefresh() {
12485
+ const entry = process.argv[1];
12486
+ if (!entry) return;
12487
+ try {
12488
+ spawn(process.execPath, [entry, INTERNAL_UPDATE_CHECK_ARG], {
12489
+ detached: true,
12490
+ stdio: "ignore",
12491
+ windowsHide: true,
12492
+ env: backgroundRefreshEnv()
12493
+ }).unref();
12494
+ } catch {}
12495
+ }
12496
+ function backgroundRefreshEnv() {
12497
+ const allowed = [
12498
+ "PATH",
12499
+ "HOME",
12500
+ "XDG_CONFIG_HOME",
12501
+ "APPDATA",
12502
+ "LOCALAPPDATA",
12503
+ "SystemRoot"
12504
+ ];
12505
+ const env = {};
12506
+ for (const key of allowed) {
12507
+ const value = process.env[key];
12508
+ if (value !== void 0) env[key] = value;
12509
+ }
12510
+ return env;
12511
+ }
12512
+ async function refreshUpdateCheckCache(now) {
12513
+ recordUpdateCheck({
12514
+ checkedAt: now,
12515
+ latestVersion: await fetchLatestVersion({ timeoutMs: REFRESH_FETCH_TIMEOUT_MS })
12516
+ });
12517
+ }
12518
+ function notifyIfUpdateAvailable(now) {
12260
12519
  const state = getUpdateCheckState();
12261
- let latest = state.latestKnownVersion;
12262
- if (state.checkedAt === null || now - state.checkedAt >= CHECK_INTERVAL_MS) {
12263
- const fetched = await fetchLatestVersion({ timeoutMs: NOTICE_FETCH_TIMEOUT_MS });
12264
- recordUpdateCheck({
12265
- checkedAt: now,
12266
- latestVersion: fetched
12267
- });
12268
- if (fetched) latest = fetched;
12269
- }
12270
- if (!latest || !isNewerVersion(latest, CLI_VERSION)) return;
12271
- if (state.notifiedVersion === latest) return;
12272
- printUpdateNotice({
12273
- current: CLI_VERSION,
12274
- latest
12520
+ const latest = state.latestKnownVersion;
12521
+ if (latest && isNewerVersion(latest, CLI_VERSION) && state.notifiedVersion !== latest) {
12522
+ printUpdateNotice({
12523
+ current: CLI_VERSION,
12524
+ latest
12525
+ });
12526
+ recordUpdateNotified(latest);
12527
+ }
12528
+ if (!(state.checkedAt === null || now - state.checkedAt >= CHECK_INTERVAL_MS)) return;
12529
+ recordUpdateCheck({
12530
+ checkedAt: now,
12531
+ latestVersion: null
12275
12532
  });
12276
- recordUpdateNotified(latest);
12533
+ spawnBackgroundRefresh();
12277
12534
  }
12278
- async function maybeNotifyUpdate(argv, now) {
12535
+ function maybeNotifyUpdate(argv, now) {
12279
12536
  if (argv.json || argv.quiet) return;
12280
12537
  if (isNonInteractive(argv)) return;
12281
12538
  if (!process.stderr.isTTY) return;
12282
- await notifyIfUpdateAvailable(now);
12539
+ notifyIfUpdateAvailable(now);
12283
12540
  }
12284
12541
 
12285
12542
  //#endregion
@@ -12367,13 +12624,16 @@ function runInstall({ command, args, capture }) {
12367
12624
  });
12368
12625
  }
12369
12626
  const updateCommand = {
12370
- command: "update",
12371
- describe: "Update the CLI to the latest published version",
12372
- builder: (yargs) => yargs.option("check", {
12627
+ command: "update [version]",
12628
+ describe: "Update the CLI to the latest (or a specific) published version",
12629
+ builder: (yargs) => yargs.version(false).positional("version", {
12630
+ type: "string",
12631
+ describe: "A specific published version to install (defaults to the latest)"
12632
+ }).option("check", {
12373
12633
  type: "boolean",
12374
12634
  default: false,
12375
12635
  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"),
12636
+ }).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
12637
  handler: async (argv) => {
12378
12638
  const latest = await fetchLatestVersion({ timeoutMs: FETCH_TIMEOUT_MS });
12379
12639
  if (latest === null) {
@@ -12389,25 +12649,65 @@ const updateCommand = {
12389
12649
  });
12390
12650
  return;
12391
12651
  }
12652
+ const requestedVersion = argv.version ?? null;
12653
+ if (requestedVersion !== null) {
12654
+ const lookup = await lookupVersion({
12655
+ version: requestedVersion,
12656
+ timeoutMs: FETCH_TIMEOUT_MS
12657
+ });
12658
+ switch (lookup.status) {
12659
+ case "exists": break;
12660
+ case "not-found":
12661
+ outputError({
12662
+ argv,
12663
+ command: COMMAND$1,
12664
+ error: {
12665
+ message: `Version ${requestedVersion} of ${PACKAGE_NAME} does not exist. The latest version is ${latest}.`,
12666
+ status: null
12667
+ },
12668
+ hint: `Run \`anything update\` to install the latest version (${latest}).`
12669
+ });
12670
+ return;
12671
+ case "unreachable":
12672
+ outputError({
12673
+ argv,
12674
+ command: COMMAND$1,
12675
+ error: {
12676
+ message: `Could not reach the npm registry to verify version ${requestedVersion}.`,
12677
+ status: null
12678
+ },
12679
+ hint: `Check available versions with \`npm view ${PACKAGE_NAME} versions\`.`,
12680
+ exitCode: EXIT_TIMEOUT
12681
+ });
12682
+ return;
12683
+ default: {
12684
+ const exhaustive = lookup.status;
12685
+ throw new Error(`Unhandled lookup status: ${String(exhaustive)}`);
12686
+ }
12687
+ }
12688
+ }
12689
+ const targetVersion = requestedVersion ?? latest;
12392
12690
  const packageManager = detectPackageManager(resolveSelfPath());
12393
12691
  const { command, args } = buildInstallCommand({
12394
12692
  packageManager,
12395
- target: `${PACKAGE_NAME}@${latest}`
12693
+ target: `${PACKAGE_NAME}@${targetVersion}`
12396
12694
  });
12397
12695
  const installCommand = [command, ...args].join(" ");
12398
- if (!isNewerVersion(latest, CLI_VERSION)) {
12696
+ const updateAvailable = isNewerVersion(latest, CLI_VERSION);
12697
+ if (requestedVersion === null ? !updateAvailable : targetVersion === CLI_VERSION) {
12399
12698
  if (outputSuccess({
12400
12699
  argv,
12401
12700
  command: COMMAND$1,
12402
12701
  data: {
12403
12702
  currentVersion: CLI_VERSION,
12404
12703
  latestVersion: latest,
12405
- updateAvailable: false,
12704
+ targetVersion,
12705
+ updateAvailable,
12406
12706
  updated: false
12407
12707
  },
12408
12708
  primaryId: CLI_VERSION
12409
12709
  })) return;
12410
- printSuccess(`Already on the latest version (${CLI_VERSION}).`);
12710
+ printSuccess(requestedVersion === null ? `Already on the latest version (${CLI_VERSION}).` : `Already on version ${CLI_VERSION}.`);
12411
12711
  return;
12412
12712
  }
12413
12713
  if (argv.check) {
@@ -12417,18 +12717,20 @@ const updateCommand = {
12417
12717
  data: {
12418
12718
  currentVersion: CLI_VERSION,
12419
12719
  latestVersion: latest,
12420
- updateAvailable: true,
12720
+ targetVersion,
12721
+ updateAvailable,
12421
12722
  updated: false,
12422
12723
  packageManager,
12423
12724
  installCommand
12424
12725
  },
12425
- primaryId: latest
12726
+ primaryId: targetVersion
12426
12727
  })) return;
12427
12728
  console.log();
12428
12729
  printLabel("Current", CLI_VERSION);
12429
12730
  printLabel("Latest", latest);
12731
+ if (requestedVersion !== null) printLabel("Target", targetVersion);
12430
12732
  console.log();
12431
- console.log(`Run \`anything update\` or \`${installCommand}\` to update.`);
12733
+ console.log(requestedVersion === null ? `Run \`anything update\` or \`${installCommand}\` to update.` : `Run \`anything update ${targetVersion}\` or \`${installCommand}\` to install it.`);
12432
12734
  return;
12433
12735
  }
12434
12736
  if (argv["dry-run"]) {
@@ -12438,14 +12740,14 @@ const updateCommand = {
12438
12740
  plannedActions: [{
12439
12741
  action: "update",
12440
12742
  from: CLI_VERSION,
12441
- to: latest,
12743
+ to: targetVersion,
12442
12744
  packageManager,
12443
12745
  command: installCommand
12444
12746
  }]
12445
12747
  });
12446
12748
  return;
12447
12749
  }
12448
- if (!argv.json && !argv.quiet) console.log(`Updating ${PACKAGE_NAME} ${CLI_VERSION} → ${latest} via ${packageManager}...`);
12750
+ if (!argv.json && !argv.quiet) console.log(`Updating ${PACKAGE_NAME} ${CLI_VERSION} → ${targetVersion} via ${packageManager}...`);
12449
12751
  let result;
12450
12752
  try {
12451
12753
  result = await runInstall({
@@ -12484,13 +12786,14 @@ const updateCommand = {
12484
12786
  data: {
12485
12787
  previousVersion: CLI_VERSION,
12486
12788
  latestVersion: latest,
12789
+ targetVersion,
12487
12790
  updated: true,
12488
12791
  packageManager,
12489
12792
  installCommand
12490
12793
  },
12491
- primaryId: latest
12794
+ primaryId: targetVersion
12492
12795
  })) return;
12493
- printSuccess(`Updated to ${latest}. Run \`anything --version\` to confirm.`);
12796
+ printSuccess(`Updated to ${targetVersion}. Run \`anything --version\` to confirm.`);
12494
12797
  }
12495
12798
  };
12496
12799
 
@@ -12779,6 +13082,33 @@ const watchCommand = {
12779
13082
 
12780
13083
  //#endregion
12781
13084
  //#region src/cli.ts
13085
+ const REGISTERED_COMMAND_PATHS = (() => {
13086
+ const paths = /* @__PURE__ */ new Set();
13087
+ for (const { name } of commandTree) {
13088
+ const words = name.split(" ");
13089
+ for (let i = 1; i <= words.length; i++) paths.add(words.slice(0, i).join(" "));
13090
+ }
13091
+ paths.add("dev");
13092
+ paths.add("update");
13093
+ return paths;
13094
+ })();
13095
+ var HandledCliError = class extends Error {};
13096
+ function commandPathFromArgv(argv) {
13097
+ const words = [];
13098
+ for (const token of argv) {
13099
+ if (token.startsWith("-")) break;
13100
+ words.push(token);
13101
+ }
13102
+ const [firstWord] = words;
13103
+ if (firstWord === void 0) return null;
13104
+ let matched = "";
13105
+ for (let i = 0; i < words.length; i++) {
13106
+ const candidate = words.slice(0, i + 1).join(" ");
13107
+ if (!REGISTERED_COMMAND_PATHS.has(candidate)) break;
13108
+ matched = candidate;
13109
+ }
13110
+ return matched === "" ? firstWord : matched;
13111
+ }
12782
13112
  function createCli(argv) {
12783
13113
  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
13114
  type: "boolean",
@@ -12809,9 +13139,9 @@ function createCli(argv) {
12809
13139
  type: "string",
12810
13140
  description: "Override the API base URL",
12811
13141
  global: true
12812
- }).middleware(async (args) => {
13142
+ }).middleware((args) => {
12813
13143
  setDevFlagOverride(args.dev === true);
12814
- await maybeNotifyUpdate({
13144
+ maybeNotifyUpdate({
12815
13145
  json: args.json === true,
12816
13146
  quiet: args.quiet === true,
12817
13147
  "non-interactive": args["non-interactive"] === true,
@@ -12828,13 +13158,14 @@ function createCli(argv) {
12828
13158
  }
12829
13159
  if (isJson) console.error(JSON.stringify({
12830
13160
  ok: false,
12831
- command: null,
13161
+ command: commandPathFromArgv(argv),
12832
13162
  error: {
12833
13163
  code: "INVALID_ARGUMENTS",
12834
13164
  message
12835
13165
  }
12836
13166
  }, null, 2));
12837
13167
  process.exitCode = EXIT_INVALID_ARGS;
13168
+ throw new HandledCliError(message);
12838
13169
  }).exitProcess(false);
12839
13170
  if (isDevEnvironment()) cli.command(devCommand);
12840
13171
  return cli;
@@ -12842,7 +13173,19 @@ function createCli(argv) {
12842
13173
 
12843
13174
  //#endregion
12844
13175
  //#region src/bin.ts
12845
- createCli(hideBin(process.argv)).parse();
13176
+ function isHandled(err) {
13177
+ return err instanceof HandledCliError;
13178
+ }
13179
+ if (process.argv[2] === INTERNAL_UPDATE_CHECK_ARG) refreshUpdateCheckCache(Date.now()).catch(() => {}).finally(() => process.exit(0));
13180
+ else try {
13181
+ const result = createCli(hideBin(process.argv)).parse();
13182
+ if (result instanceof Promise) result.catch((err) => {
13183
+ if (isHandled(err)) return;
13184
+ throw err;
13185
+ });
13186
+ } catch (err) {
13187
+ if (!isHandled(err)) throw err;
13188
+ }
12846
13189
 
12847
13190
  //#endregion
12848
13191
  export { };