geo-new 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -7311,7 +7311,7 @@ var ApiError = class extends Error {
7311
7311
  };
7312
7312
 
7313
7313
  // packages/geo-new/src/client.ts
7314
- var VERSION = true ? "0.1.1" : "0.0.0-dev";
7314
+ var VERSION = true ? "0.1.2" : "0.0.0-dev";
7315
7315
  var DEFAULT_ORIGIN = "https://geo.new";
7316
7316
  var isLoopback = (url2) => url2.hostname === "localhost" || url2.hostname === "127.0.0.1" || url2.hostname === "[::1]" || url2.hostname === "::1";
7317
7317
  var sleep = (ms, signal) => new Promise((resolve, reject) => {
@@ -7565,6 +7565,105 @@ var clock = (ms) => {
7565
7565
  function detectUtf8(env = process.env) {
7566
7566
  return /utf-?8/i.test(env.LC_ALL ?? env.LC_CTYPE ?? env.LANG ?? "") || process.platform === "win32";
7567
7567
  }
7568
+ var ACCENT = "38;5;173";
7569
+ var COMET = [ACCENT, "38;5;137", "38;5;95"];
7570
+ var BASE = "38;5;240";
7571
+ var FACE = {
7572
+ G: [".####", "#....", "#..##", "#...#", ".####"],
7573
+ E: ["#####", "#....", "####.", "#....", "#####"],
7574
+ O: [".###.", "#...#", "#...#", "#...#", ".###."],
7575
+ ".": [".", ".", ".", ".", "#"],
7576
+ n: [".....", "####.", "#...#", "#...#", "#...#"],
7577
+ e: [".....", ".###.", "#####", "#....", ".####"],
7578
+ w: [".....", "#...#", "#.#.#", "#.#.#", ".#.#."]
7579
+ };
7580
+ var WORD = "GEO.new";
7581
+ var GAP = 2;
7582
+ var ROWS = 5;
7583
+ var CARET = 4;
7584
+ var STARTS = [...WORD].reduce(
7585
+ (xs, ch) => [...xs, xs[xs.length - 1] + FACE[ch][0].length + GAP],
7586
+ [0]
7587
+ );
7588
+ var BOOT_WIDTH = STARTS[WORD.length] - GAP + 1 + CARET;
7589
+ var RING = [
7590
+ [0, 0],
7591
+ [0, 1],
7592
+ [0, 2],
7593
+ [1, 2],
7594
+ [2, 2],
7595
+ [2, 1],
7596
+ [2, 0],
7597
+ [1, 0]
7598
+ ];
7599
+ var BOOT = [
7600
+ [70, 0],
7601
+ [70, 0],
7602
+ [70, 0],
7603
+ [70, 0],
7604
+ [70, 0],
7605
+ [70, 0],
7606
+ [70, 0],
7607
+ [70, 0],
7608
+ [110, 0],
7609
+ [120, 0],
7610
+ [70, 1],
7611
+ [70, 2],
7612
+ [70, 3],
7613
+ [120, 3],
7614
+ // a beat between the name and the suffix, as in the design
7615
+ [65, 4],
7616
+ [65, 5],
7617
+ [65, 6],
7618
+ [420, 7]
7619
+ // the caret stands here, then the boot is over
7620
+ ];
7621
+ var LAST = BOOT.length - 1;
7622
+ var UP = `\r\x1B[${Math.ceil(ROWS / 2) - 1}A`;
7623
+ var sgr = (p, glyph) => p ? `\x1B[${p}m${glyph}\x1B[0m` : glyph;
7624
+ var bg = (p) => p.replace(/^38;/, "48;");
7625
+ function cell(u, l) {
7626
+ if (u === null) return l === null ? " " : sgr(l, "\u2584");
7627
+ if (l === null) return sgr(u, "\u2580");
7628
+ if (u === l) return sgr(u, "\u2588");
7629
+ if (!u) return sgr(bg(l), "\u2580");
7630
+ if (!l) return sgr(bg(u), "\u2584");
7631
+ return sgr(`${u};${bg(l)}`, "\u2580");
7632
+ }
7633
+ function bootFrame(step, done, color) {
7634
+ const grid = Array.from({ length: ROWS }, () => []);
7635
+ const ink = (shade) => color ? shade : "";
7636
+ const put = (row, col, shade) => grid[row][col] = shade;
7637
+ const typed = done ? WORD.length : BOOT[step][1];
7638
+ [...WORD].slice(0, typed).forEach(
7639
+ (ch, i) => FACE[ch].forEach(
7640
+ (row, r) => [...row].forEach((p, c) => p === "#" && put(r, STARTS[i] + c, i < 3 ? ink(ACCENT) : ""))
7641
+ )
7642
+ );
7643
+ if (!done && step <= 7)
7644
+ RING.forEach(([r, c], i) => {
7645
+ const k = (step - i + RING.length) % RING.length;
7646
+ put(r + 1, c + 1, color ? COMET[k] ?? BASE : k < COMET.length ? "" : null);
7647
+ });
7648
+ else if (!done && step === 8)
7649
+ for (let r = 1; r <= 3; r++) for (let c = 1; c <= 3; c++) put(r, c, ink(ACCENT));
7650
+ else if (!done && step === 9) {
7651
+ for (let r = 0; r < ROWS; r++)
7652
+ for (let c = 0; c < ROWS; c++) if (r === 0 || r === 4 || c === 0 || c === 4) put(r, c, ink(COMET[2]));
7653
+ }
7654
+ if (!done && step >= 10) {
7655
+ const x = STARTS[typed] - GAP + 1;
7656
+ for (let r = 0; r < ROWS; r++) for (let c = 0; c < CARET; c++) put(r, x + c, "");
7657
+ }
7658
+ const width = Math.max(0, ...grid.map((row) => row.length));
7659
+ const lines = [];
7660
+ for (let r = 0; r < ROWS; r += 2) {
7661
+ let line = "";
7662
+ for (let c = 0; c < width; c++) line += cell(grid[r][c] ?? null, grid[r + 1]?.[c] ?? null);
7663
+ lines.push(line.replace(/ +$/, ""));
7664
+ }
7665
+ return lines;
7666
+ }
7568
7667
  var Output = class {
7569
7668
  stream;
7570
7669
  tty;
@@ -7574,6 +7673,11 @@ var Output = class {
7574
7673
  verbose;
7575
7674
  lastLine = "";
7576
7675
  lineOpen = false;
7676
+ booting;
7677
+ /** A process that exits mid-boot must leave the cursor visible and the prompt on its own line. */
7678
+ abandon = () => {
7679
+ if (this.booting) this.stream.write("\x1B[?25h\n");
7680
+ };
7577
7681
  constructor(options = {}) {
7578
7682
  this.stream = options.stream ?? process.stderr;
7579
7683
  this.tty = options.tty ?? Boolean(process.stderr.isTTY);
@@ -7587,9 +7691,51 @@ var Output = class {
7587
7691
  const symbol2 = this.utf8 ? utf8 : ascii;
7588
7692
  return this.color ? `\x1B[${color}m${symbol2}\x1B[0m` : symbol2;
7589
7693
  }
7694
+ /**
7695
+ * Runs the wordmark's boot while an audit is admitted. Progress waits behind it: the first snapshot
7696
+ * lets the ring finish its turn and hand over to the name, and `settle` cuts it to the finished name.
7697
+ */
7698
+ boot() {
7699
+ if (this.quiet || !this.tty || !this.utf8 || this.booting) return;
7700
+ if ((this.stream.columns || 80) < BOOT_WIDTH) return;
7701
+ this.booting = { step: 0, seen: false };
7702
+ process.once("exit", this.abandon);
7703
+ this.stream.write(`\x1B[?25l
7704
+ ${this.frame(0)}`);
7705
+ this.tick();
7706
+ }
7707
+ frame(step, done = false) {
7708
+ return bootFrame(step, done, this.color).map((line) => `\x1B[2K${line}`).join("\n");
7709
+ }
7710
+ tick() {
7711
+ const b = this.booting;
7712
+ if (!b) return;
7713
+ b.timer = setTimeout(() => {
7714
+ if (b.step === LAST) return this.endBoot();
7715
+ b.step = b.step === 7 && !b.seen ? 0 : b.step + 1;
7716
+ this.stream.write(`${UP}${this.frame(b.step)}`);
7717
+ this.tick();
7718
+ }, BOOT[b.step][0]);
7719
+ }
7720
+ endBoot() {
7721
+ const b = this.booting;
7722
+ if (!b) return;
7723
+ clearTimeout(b.timer);
7724
+ this.booting = void 0;
7725
+ process.off("exit", this.abandon);
7726
+ this.stream.write(`${UP}${this.frame(LAST, true)}\x1B[?25h
7727
+
7728
+ `);
7729
+ if (b.pending) this.progress(...b.pending);
7730
+ }
7590
7731
  /** One live line on a TTY, one line per change otherwise. */
7591
7732
  progress(snapshot, elapsedMs) {
7592
7733
  if (this.quiet) return;
7734
+ if (this.booting) {
7735
+ this.booting.seen = true;
7736
+ this.booting.pending = [snapshot, elapsedMs];
7737
+ return;
7738
+ }
7593
7739
  const parts = Object.entries(snapshot.sections).filter(([key]) => key in SECTION_LABEL).map(([key, section]) => `${SECTION_LABEL[key]} ${this.glyph(section.state)}`);
7594
7740
  const line = `${parts.join(" ")} ${clock(elapsedMs)}`;
7595
7741
  if (this.tty) {
@@ -7604,6 +7750,7 @@ var Output = class {
7604
7750
  }
7605
7751
  /** Ends a live progress line before anything else is printed. */
7606
7752
  settle() {
7753
+ this.endBoot();
7607
7754
  if (this.lineOpen) {
7608
7755
  this.stream.write("\n");
7609
7756
  this.lineOpen = false;
@@ -7648,7 +7795,9 @@ function comparisonLines(comparison) {
7648
7795
  const c = comparison ?? {};
7649
7796
  const delta = (v) => v === null || v === void 0 ? "unmeasured" : v > 0 ? `+${v}` : `${v}`;
7650
7797
  const count = (change) => (c.checks ?? []).filter((k) => k.change === change).length;
7651
- const lines = [`geo ${delta(c.score_delta?.geo)} \xB7 seo ${delta(c.score_delta?.seo)} \xB7 ${c.state ?? "unknown"}`];
7798
+ const lines = [
7799
+ `geo ${delta(c.score_delta?.geo)} \xB7 seo ${delta(c.score_delta?.seo)} \xB7 ${c.state ?? "unknown"}`
7800
+ ];
7652
7801
  const moved = [
7653
7802
  ["fixed", count("fixed")],
7654
7803
  ["new", count("new")],
@@ -37759,6 +37908,7 @@ async function main(argv, deps = {}) {
37759
37908
  const url2 = positional[0];
37760
37909
  if (!url2) throw new Exit(EXIT.usage, "usage: geo-new audit <url>");
37761
37910
  const waitSeconds = integer2(flags.wait, "wait", 90);
37911
+ if (waitSeconds > 0) output2.boot();
37762
37912
  const envelope = await client.audit(url2, {
37763
37913
  fresh: Boolean(flags.fresh),
37764
37914
  signal: deps.signal
package/dist/index.js CHANGED
@@ -107,7 +107,7 @@ var ApiError = class extends Error {
107
107
  };
108
108
 
109
109
  // packages/geo-new/src/client.ts
110
- var VERSION = true ? "0.1.1" : "0.0.0-dev";
110
+ var VERSION = true ? "0.1.2" : "0.0.0-dev";
111
111
  var DEFAULT_ORIGIN = "https://geo.new";
112
112
  var isLoopback = (url) => url.hostname === "localhost" || url.hostname === "127.0.0.1" || url.hostname === "[::1]" || url.hostname === "::1";
113
113
  var sleep = (ms, signal) => new Promise((resolve, reject) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "geo-new",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Audit one page for GEO, SEO and agent readiness from a terminal, a coding agent (MCP) or a script. Keyless by default; a key is optional.",
5
5
  "license": "MIT",
6
6
  "type": "module",