layro-cli 0.2.0 → 0.3.0

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/README.md CHANGED
@@ -24,12 +24,12 @@ Requires Node 20 or newer. No dependencies.
24
24
 
25
25
  ### Publish options
26
26
 
27
- `--name`, `--description` (20 to 200 characters), `--category` (a slug from layro.dev/components), `--license` (MIT, Apache-2.0, ISC or BSD-3-Clause; default MIT), `--version` (new versions: defaults to a patch bump), `--notes` (what changed), `--dark-only`, `--preview <plan.json>` (how to film the preview), `-y, --yes` (don't ask; for CI).
27
+ `--name`, `--description` (20 to 200 characters), `--category` (a slug from layro.dev/components), `--license` (MIT, Apache-2.0, ISC or BSD-3-Clause; default MIT), `--version` (new versions: defaults to a patch bump), `--notes` (what changed), `--dark-only`, `--preview <plan.json>` (how to film the preview), `--if-changed` (new versions: unchanged code or a version still in review exits 0 with "Nothing sent"; for CI), `-y, --yes` (don't ask; for CI).
28
28
 
29
29
  Everything goes through review on Layro before it's live. The CLI and coding agents (MCP) share one daily allowance of submissions per account.
30
30
 
31
31
  ## Where tokens live
32
32
 
33
- `~/.config/layro/credentials.json` (or `$XDG_CONFIG_HOME/layro`), readable only by you. Access tokens last an hour and renew themselves. `LAYRO_TOKEN` uses an access token instead; `LAYRO_URL` points at another Layro server.
33
+ `~/.config/layro/credentials.json` (or `$XDG_CONFIG_HOME/layro`), readable only by you. Access tokens last an hour and renew themselves. `LAYRO_TOKEN` uses a token instead: for CI, make a long-lived one at https://layro.dev/settings/tokens (publish only; a GitHub Actions example is at https://layro.dev/docs/cli); `LAYRO_URL` points at another Layro server.
34
34
 
35
35
  Docs: https://layro.dev/docs/cli
package/dist/layro.mjs CHANGED
@@ -340,7 +340,7 @@ async function logout(server2) {
340
340
  }
341
341
 
342
342
  // src/api.ts
343
- var VERSION = true ? "0.2.0" : "dev";
343
+ var VERSION = true ? "0.3.0" : "dev";
344
344
  var ApiFailure = class extends CliError {
345
345
  constructor(detail) {
346
346
  super(detail.error);
@@ -376,13 +376,16 @@ async function api(server2, path, init = {}) {
376
376
  if (response.ok && body) return body;
377
377
  if (response.status === 401) {
378
378
  if (process.env.LAYRO_TOKEN)
379
- throw new CliError("LAYRO_TOKEN was refused: it's invalid or expired.");
379
+ throw new CliError(
380
+ `LAYRO_TOKEN was refused: it's invalid, revoked or expired. Make a new one at ${server2}/settings/tokens.`
381
+ );
380
382
  throw notSignedIn();
381
383
  }
382
384
  throw new ApiFailure({
383
385
  status: response.status,
384
386
  error: body?.error ?? `${server2} answered ${response.status} for ${path}.`,
385
- errors: body?.errors
387
+ errors: body?.errors,
388
+ code: body?.code
386
389
  });
387
390
  }
388
391
 
@@ -461,14 +464,25 @@ async function publish(server2, paths, flags) {
461
464
  const notes = flags.notes ?? (interactive ? await ask("What changed", "") : "");
462
465
  if (interactive && !await confirm(`Send ${existing.id} ${version} for review?`))
463
466
  return say("Nothing sent.");
464
- result = await api(
467
+ const sent = await api(
465
468
  server2,
466
469
  `/components/${existing.id}/versions`,
467
470
  {
468
471
  method: "POST",
469
472
  body: { version, notes, files, preview }
470
473
  }
471
- ).catch(explain);
474
+ ).catch((error) => {
475
+ if (flags.ifChanged && error instanceof ApiFailure && (error.detail.code === "unchanged" || error.detail.code === "pending"))
476
+ return error;
477
+ return explain(error);
478
+ });
479
+ if (sent instanceof ApiFailure) {
480
+ say(
481
+ `Nothing sent: ${Object.values(sent.detail.errors ?? {})[0] ?? sent.message}`
482
+ );
483
+ return;
484
+ }
485
+ result = sent;
472
486
  } else {
473
487
  if (flags.version && flags.version !== "1.0.0")
474
488
  warn(
@@ -624,6 +638,7 @@ Publish options
624
638
  --notes <text> New versions: what changed
625
639
  --dark-only It only works on a dark page
626
640
  --preview <plan.json> How to film its preview (see the docs)
641
+ --if-changed Unchanged code, or a version still in review: say so, exit 0 (CI)
627
642
  -y, --yes Don't ask; send what's given (for CI)
628
643
 
629
644
  Search options
@@ -636,7 +651,8 @@ Login options
636
651
  --no-browser Print the sign-in link instead of opening it
637
652
 
638
653
  Environment
639
- LAYRO_TOKEN An access token to use instead of signing in
654
+ LAYRO_TOKEN A token to use instead of signing in: an access
655
+ token from https://layro.dev/settings/tokens (CI)
640
656
  LAYRO_URL Another Layro server (default https://layro.dev)
641
657
 
642
658
  Docs: https://layro.dev/docs/cli`;
@@ -698,13 +714,19 @@ async function main(argv) {
698
714
  notes: { type: "string" },
699
715
  preview: { type: "string" },
700
716
  "dark-only": { type: "boolean" },
717
+ "if-changed": { type: "boolean" },
701
718
  yes: { type: "boolean", short: "y" }
702
719
  }
703
720
  });
704
- const { "dark-only": darkOnly, ...flags } = values;
721
+ const {
722
+ "dark-only": darkOnly,
723
+ "if-changed": ifChanged,
724
+ ...flags
725
+ } = values;
705
726
  await publish(server, positionals, {
706
727
  ...flags,
707
- darkOnly
728
+ darkOnly,
729
+ ifChanged
708
730
  });
709
731
  return;
710
732
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "layro-cli",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Find and publish React components on Layro (layro.dev) from your terminal.",
5
5
  "license": "MIT",
6
6
  "type": "module",