@anythingai/cli 0.1.2 → 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/CHANGELOG.md ADDED
@@ -0,0 +1,29 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@anythingai/cli` are documented here.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Changed
11
+
12
+ - **Breaking:** `--env` now accepts only lowercase values (`development`,
13
+ `preview`, `production`). The uppercase forms (`DEVELOPMENT`, `PREVIEW`,
14
+ `PRODUCTION`) that 0.0.x silently accepted no longer validate — pass the
15
+ lowercase form instead.
16
+
17
+ ### Fixed
18
+
19
+ - `--json` failures now write the error envelope to stdout (was stderr), so
20
+ `anything … --json | jq` receives the payload on failure as well as success.
21
+ - Strict-mode (argument-validation) error envelopes no longer leak positional
22
+ values into `command`; the field is now the canonical command path (e.g.
23
+ `orgs get`, `members invite`), keeping IDs and emails out of the envelope.
24
+ - Silenced the yargs `"version" is a reserved word` warning emitted by
25
+ `anything update` / `anything update --check`.
26
+ - `domains add` now rejects RFC 2606 reserved TLDs (`.invalid`, `.example`,
27
+ `.test`, `.localhost`) before the network round-trip.
28
+ - Deployment-failure `buildLogs` are now emitted as an array of lines
29
+ (`string[]`) in the JSON envelope instead of one newline-joined string.
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.2";
3072
+ var version = "0.1.3";
3073
3073
 
3074
3074
  //#endregion
3075
3075
  //#region generated/core/bodySerializer.gen.ts
@@ -4852,6 +4852,11 @@ var AnythingApiClient = class {
4852
4852
  function printJson(data) {
4853
4853
  console.log(JSON.stringify(data, null, 2));
4854
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
+ }
4855
4860
  function printSuccess(message) {
4856
4861
  console.log(styleText("green", message));
4857
4862
  }
@@ -4908,7 +4913,7 @@ function outputError({ argv, command, error, hint, exitCode, buildLogs, code: co
4908
4913
  process.exitCode = exitCode ?? exitCodeFromHttpStatus(status);
4909
4914
  const code = codeOverride ?? extractErrorCode(details) ?? (status === null && exitCode !== void 0 ? errorCodeFromExitCode(exitCode) : errorCodeFromHttpStatus(status));
4910
4915
  if (argv.json || argv.quiet) {
4911
- console.error(JSON.stringify({
4916
+ console.log(JSON.stringify({
4912
4917
  ok: false,
4913
4918
  command,
4914
4919
  error: {
@@ -4916,7 +4921,7 @@ function outputError({ argv, command, error, hint, exitCode, buildLogs, code: co
4916
4921
  message: error.message,
4917
4922
  ...resolvedHint ? { hint: resolvedHint } : {},
4918
4923
  ...retryAfter !== null ? { retry_after_seconds: retryAfter } : {},
4919
- ...buildLogs ? { buildLogs } : {}
4924
+ ...buildLogs ? { buildLogs: buildLogsToLines(buildLogs) } : {}
4920
4925
  }
4921
4926
  }, null, 2));
4922
4927
  return;
@@ -6645,11 +6650,19 @@ function toPublicDomain(domain) {
6645
6650
  //#region src/commands/domain-add.ts
6646
6651
  const COMMAND$19 = "domains add";
6647
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
+ ]);
6648
6659
  function domainValidationError(domain) {
6649
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`;
6650
6661
  if (domain.includes("/") || /\s/.test(domain)) return `Invalid domain "${domain}". Enter a bare hostname like app.example.com`;
6651
6662
  if (!domain.includes(".")) return `Invalid domain "${domain}". A domain must include a dot, e.g. app.example.com`;
6652
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`;
6653
6666
  return null;
6654
6667
  }
6655
6668
  const domainAddCommand = {
@@ -12418,8 +12431,9 @@ const switchCommand = {
12418
12431
  const PACKAGE_NAME = "@anythingai/cli";
12419
12432
  const REGISTRY_BASE_URL = `https://registry.npmjs.org/${PACKAGE_NAME}`;
12420
12433
  const REGISTRY_URL = `${REGISTRY_BASE_URL}/latest`;
12421
- const CHECK_INTERVAL_MS = 1440 * 60 * 1e3;
12422
- const NOTICE_FETCH_TIMEOUT_MS = 1500;
12434
+ const INTERNAL_UPDATE_CHECK_ARG = "__update-check";
12435
+ const CHECK_INTERVAL_MS = 10800 * 1e3;
12436
+ const REFRESH_FETCH_TIMEOUT_MS = 1e4;
12423
12437
  const latestManifestSchema = z.object({ version: z.string() });
12424
12438
  function isNewerVersion(candidate, current) {
12425
12439
  const core = (v) => (v.split("-")[0] ?? "").split(".").map((part) => Number.parseInt(part, 10));
@@ -12467,30 +12481,62 @@ function printUpdateNotice({ current, latest }) {
12467
12481
  ""
12468
12482
  ].join("\n"));
12469
12483
  }
12470
- 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) {
12471
12519
  const state = getUpdateCheckState();
12472
- let latest = state.latestKnownVersion;
12473
- if (state.checkedAt === null || now - state.checkedAt >= CHECK_INTERVAL_MS) {
12474
- const fetched = await fetchLatestVersion({ timeoutMs: NOTICE_FETCH_TIMEOUT_MS });
12475
- recordUpdateCheck({
12476
- checkedAt: now,
12477
- latestVersion: fetched
12478
- });
12479
- if (fetched) latest = fetched;
12480
- }
12481
- if (!latest || !isNewerVersion(latest, CLI_VERSION)) return;
12482
- if (state.notifiedVersion === latest) return;
12483
- printUpdateNotice({
12484
- current: CLI_VERSION,
12485
- 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
12486
12532
  });
12487
- recordUpdateNotified(latest);
12533
+ spawnBackgroundRefresh();
12488
12534
  }
12489
- async function maybeNotifyUpdate(argv, now) {
12535
+ function maybeNotifyUpdate(argv, now) {
12490
12536
  if (argv.json || argv.quiet) return;
12491
12537
  if (isNonInteractive(argv)) return;
12492
12538
  if (!process.stderr.isTTY) return;
12493
- await notifyIfUpdateAvailable(now);
12539
+ notifyIfUpdateAvailable(now);
12494
12540
  }
12495
12541
 
12496
12542
  //#endregion
@@ -12580,7 +12626,7 @@ function runInstall({ command, args, capture }) {
12580
12626
  const updateCommand = {
12581
12627
  command: "update [version]",
12582
12628
  describe: "Update the CLI to the latest (or a specific) published version",
12583
- builder: (yargs) => yargs.positional("version", {
12629
+ builder: (yargs) => yargs.version(false).positional("version", {
12584
12630
  type: "string",
12585
12631
  describe: "A specific published version to install (defaults to the latest)"
12586
12632
  }).option("check", {
@@ -13036,6 +13082,16 @@ const watchCommand = {
13036
13082
 
13037
13083
  //#endregion
13038
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
+ })();
13039
13095
  var HandledCliError = class extends Error {};
13040
13096
  function commandPathFromArgv(argv) {
13041
13097
  const words = [];
@@ -13043,7 +13099,15 @@ function commandPathFromArgv(argv) {
13043
13099
  if (token.startsWith("-")) break;
13044
13100
  words.push(token);
13045
13101
  }
13046
- return words.length > 0 ? words.join(" ") : null;
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;
13047
13111
  }
13048
13112
  function createCli(argv) {
13049
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", {
@@ -13075,9 +13139,9 @@ function createCli(argv) {
13075
13139
  type: "string",
13076
13140
  description: "Override the API base URL",
13077
13141
  global: true
13078
- }).middleware(async (args) => {
13142
+ }).middleware((args) => {
13079
13143
  setDevFlagOverride(args.dev === true);
13080
- await maybeNotifyUpdate({
13144
+ maybeNotifyUpdate({
13081
13145
  json: args.json === true,
13082
13146
  quiet: args.quiet === true,
13083
13147
  "non-interactive": args["non-interactive"] === true,
@@ -13112,7 +13176,8 @@ function createCli(argv) {
13112
13176
  function isHandled(err) {
13113
13177
  return err instanceof HandledCliError;
13114
13178
  }
13115
- try {
13179
+ if (process.argv[2] === INTERNAL_UPDATE_CHECK_ARG) refreshUpdateCheckCache(Date.now()).catch(() => {}).finally(() => process.exit(0));
13180
+ else try {
13116
13181
  const result = createCli(hideBin(process.argv)).parse();
13117
13182
  if (result instanceof Promise) result.catch((err) => {
13118
13183
  if (isHandled(err)) return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@anythingai/cli",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "homepage": "https://anything.com/",
5
5
  "license": "MIT",
6
6
  "bin": {