zchess 0.1.6-alpha.0 → 0.1.8-alpha.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
@@ -20,3 +20,42 @@ brew install --formula https://github.com/kennylwx/zchess/releases/latest/downlo
20
20
 
21
21
  Stockfish runs locally. Plain-English move descriptions need the Chess server;
22
22
  SAN and UCI moves work offline.
23
+
24
+ Terminal graphics default to `--graphics auto`: the CLI probes the active terminal
25
+ for Kitty graphics support only when identified as Kitty or Ghostty. Unknown
26
+ emulators stay on text without receiving APC queries, because QTerminal 2.1.0
27
+ was observed to leak query payloads into shell scrollback. A known identifier
28
+ only permits probing; a successful runtime reply is still required. Names alone do not
29
+ enable images. Unsupported terminals, redirected streams, tmux, screen and Konsole use the
30
+ text board. `--graphics text` skips probing; `--graphics kitty` explicitly forces
31
+ the protocol on an interactive terminal (use only if you know it supports it).
32
+
33
+ Konsole defaults to text because testing in 25.04.2 found that it acknowledged
34
+ Kitty queries but ignored the requested image sizing, clipping the board over
35
+ the input field. Forced Kitty mode can still exhibit this issue in Konsole.
36
+
37
+ The CLI queries cell pixel dimensions at startup and on image-board resize, then
38
+ specifies only one image dimension so the PNG stays square. If cell size is not
39
+ reported, sizing uses an approximate 2:1 cell ratio; image aspect is still preserved,
40
+ but available-space estimates can be less accurate with unusual fonts. The text
41
+ board also uses approximate proportions and depends on the terminal font.
42
+
43
+ Help, returning to menus and exit delete the board image. If the native PNG
44
+ renderer cannot load, play continues with the text board. A protocol response
45
+ establishes capability, not visual correctness in every terminal/version.
46
+
47
+ When you start an interactive session, Chess checks npm for a newer version and
48
+ shows the command to install it in the main menu. Alpha installations also check
49
+ the alpha channel; stable installations only check stable releases. Homebrew
50
+ installations show a command to reinstall the latest release formula instead.
51
+ The check times out after 800 ms and failures are silent, so you can still play
52
+ offline. Set `ZCHESS_NO_UPDATE_CHECK=1` to disable it. Help and noninteractive
53
+ sessions do not check for updates. Updates are never installed automatically.
54
+
55
+
56
+ Unicode text boards require a terminal font containing chess symbols. The XTerm
57
+ 398 Unicode check used DejaVu Sans Mono 11; its default bitmap font showed missing
58
+ glyph boxes. For fonts without chess symbols, use `chess --graphics ascii`.
59
+ This disables image probing and uses uppercase `KQRBNP` for white, lowercase
60
+ `kqrbnp` for black, and ASCII board labels/markers. It changes the board only;
61
+ other CLI messages can still contain Unicode. Font support is not auto-detected.
package/bin/chess.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { fileURLToPath } from 'node:url';
4
+ import { readFile } from 'node:fs/promises';
4
5
 
5
6
  // Node 22 labels its built-in SQLite module experimental. Keep that runtime
6
7
  // notice out of the player-facing menu while leaving other warnings intact.
@@ -18,7 +19,9 @@ try {
18
19
  if (error.code !== 'ENOENT') throw error;
19
20
  }
20
21
 
21
- run(process.argv.slice(2)).catch(error => {
22
+ const { version } = JSON.parse(await readFile(new URL('../package.json', import.meta.url), 'utf8'));
23
+ const homebrew = /[\\/](?:Cellar|Homebrew)[\\/]/i.test(fileURLToPath(import.meta.url));
24
+ run(process.argv.slice(2), { version, homebrew }).catch(error => {
22
25
  console.error(`\nError: ${error.message}`);
23
26
  process.exitCode = 1;
24
27
  });
@@ -1,6 +1,66 @@
1
+ // src/update.ts
2
+ function parseVersion(value) {
3
+ if (typeof value !== "string") return;
4
+ const match = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*))?(?:\+[\da-zA-Z-]+(?:\.[\da-zA-Z-]+)*)?$/.exec(value);
5
+ if (!match) return;
6
+ const prerelease = match[4]?.split(".") || [];
7
+ if (prerelease.some((part) => /^0\d+$/.test(part))) return;
8
+ return { core: match.slice(1, 4).map(BigInt), prerelease };
9
+ }
10
+ function isNewerVersion(candidate, installed) {
11
+ const a = parseVersion(candidate), b = parseVersion(installed);
12
+ if (!a || !b) return false;
13
+ for (let i = 0; i < 3; i++) if (a.core[i] !== b.core[i]) return a.core[i] > b.core[i];
14
+ if (!a.prerelease.length || !b.prerelease.length) return a.prerelease.length === 0 && b.prerelease.length > 0;
15
+ for (let i = 0; i < Math.max(a.prerelease.length, b.prerelease.length); i++) {
16
+ const x = a.prerelease[i], y = b.prerelease[i];
17
+ if (x === void 0 || y === void 0) return x !== void 0;
18
+ if (x === y) continue;
19
+ const xn = /^\d+$/.test(x), yn = /^\d+$/.test(y);
20
+ if (xn && yn) return BigInt(x) > BigInt(y);
21
+ if (xn !== yn) return !xn;
22
+ return x > y;
23
+ }
24
+ return false;
25
+ }
26
+ async function checkForUpdate(installed, options = {}) {
27
+ const current = parseVersion(installed);
28
+ if (!current) return;
29
+ const controller = new AbortController();
30
+ let timer;
31
+ try {
32
+ const lookup = async () => {
33
+ const response = await (options.fetch || fetch)("https://registry.npmjs.org/-/package/zchess/dist-tags", { signal: controller.signal });
34
+ if (!response.ok) return;
35
+ const tags = await response.json();
36
+ if (!tags || typeof tags !== "object") return;
37
+ const candidates = [tags.latest];
38
+ if (current.prerelease.length && !options.homebrew) candidates.push(tags[current.prerelease[0]]);
39
+ let version = installed;
40
+ for (const candidate of candidates) {
41
+ if (typeof candidate === "string" && isNewerVersion(candidate, version)) version = candidate;
42
+ }
43
+ if (version === installed) return;
44
+ return { version, command: options.homebrew ? `brew reinstall --formula \\
45
+ https://github.com/kennylwx/zchess/releases/latest/download/zchess.rb` : `npm install --global zchess@${version}` };
46
+ };
47
+ const timeout = new Promise((resolve) => {
48
+ timer = setTimeout(() => {
49
+ controller.abort();
50
+ resolve(void 0);
51
+ }, options.timeoutMs ?? 800);
52
+ });
53
+ return await Promise.race([lookup(), timeout]);
54
+ } catch {
55
+ return;
56
+ } finally {
57
+ if (timer) clearTimeout(timer);
58
+ }
59
+ }
60
+
1
61
  // src/cli.ts
2
62
  import { createInterface as createInterface2 } from "node:readline/promises";
3
- import { stdin, stdout as stdout2 } from "node:process";
63
+ import { stdin as stdin2, stdout as stdout3 } from "node:process";
4
64
 
5
65
  // ../../packages/chess/dist/index.js
6
66
  var START_FEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
@@ -533,40 +593,40 @@ var PIECES = {
533
593
  };
534
594
  var OUTLINES = { K: "\u2654", Q: "\u2655", R: "\u2656", B: "\u2657", N: "\u2658", P: "\u2659" };
535
595
  var RESET = "\x1B[0m";
536
- function render(chess, { perspective = "w", last = null, color: color2 = Boolean(process.stdout.isTTY), compact = false } = {}) {
596
+ function render(chess, { perspective = "w", last = null, color: color2 = Boolean(process.stdout.isTTY), compact = false, ascii = false } = {}) {
537
597
  const rows = perspective === "w" ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];
538
598
  const files = perspective === "w" ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];
539
- const cellWidth = Math.max(6, Math.min(8, Math.floor(((process.stdout.columns || 80) - 8) / 8)));
599
+ const cellWidth = Math.max(1, Math.min(compact ? 2 : 6, Math.floor(((process.stdout.columns || 80) - 8) / 8)));
540
600
  const cell = (content = "") => {
541
601
  const left = Math.floor((cellWidth - 1) / 2);
542
602
  return `${" ".repeat(left)}${content}${" ".repeat(cellWidth - left - (content ? 1 : 0))}`;
543
603
  };
544
- const green = (text) => color2 ? `\x1B[38;5;114m${text}${RESET}` : text;
545
- const border = green(` +${"-".repeat(cellWidth * 8)}+`);
604
+ const defaultText = (text) => color2 ? `\x1B[39m${text}${RESET}` : text;
605
+ const border = defaultText(` +${"-".repeat(cellWidth * 8)}+`);
546
606
  const output = [border];
547
607
  for (const rank of rows) {
548
608
  for (const line of compact ? [1] : [0, 1, 2]) {
549
- let row = green(`${line === 1 ? ` ${8 - rank} ` : " "}|`);
609
+ let row = defaultText(`${line === 1 ? ` ${8 - rank} ` : " "}|`);
550
610
  for (const file of files) {
551
611
  const index = rank * 8 + file;
552
612
  const piece = chess.board[index];
553
613
  const white = piece !== null && piece === piece.toUpperCase();
554
- const glyph = piece ? !color2 && white ? OUTLINES[piece] : PIECES[piece] : " ";
614
+ const glyph = piece ? ascii ? piece : !color2 && white ? OUTLINES[piece] : PIECES[piece] : " ";
555
615
  let square = cell(line === 1 ? glyph : "");
556
616
  if (color2) {
557
617
  const background = last?.includes(index) ? 107 : (rank + file) % 2 ? 65 : 108;
558
618
  square = `\x1B[1;48;5;${background};38;5;${white ? 231 : 16}m${square}${RESET}`;
559
619
  } else if (!piece && line === 1) {
560
- square = cell((rank + file) % 2 ? "\xB7" : "");
620
+ square = cell((rank + file) % 2 ? ascii ? "." : "\xB7" : "");
561
621
  }
562
622
  row += square;
563
623
  }
564
- output.push(row + green("|"));
624
+ output.push(row + defaultText("|"));
565
625
  }
566
626
  }
567
627
  output.push(border);
568
- output.push(green(" " + files.map((file) => cell("abcdefgh"[file])).join("")));
569
- output.push(color2 ? ` \x1B[1;38;5;231m\u265A White${RESET} ${green("\u265A Black \xB7 dark pieces")}` : " \u2654 White \u265A Black");
628
+ output.push(defaultText(" " + files.map((file) => cell("abcdefgh"[file])).join("")));
629
+ output.push(ascii ? defaultText(" White: KQRBNP Black: kqrbnp") : color2 ? defaultText(" \u2654 White \u265A Black \xB7 dark pieces") : " \u2654 White \u265A Black");
570
630
  return output.join("\n") + "\n";
571
631
  }
572
632
 
@@ -589,15 +649,103 @@ var pieces_default = {
589
649
  R: '<g id="white-rook" class="white rook" fill="#fff" fill-rule="evenodd" stroke="#000" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M9 39h27v-3H9v3zM12 36v-4h21v4H12zM11 14V9h4v2h5V9h5v2h5V9h4v5" stroke-linecap="butt"/><path d="M34 14l-3 3H14l-3-3"/><path d="M31 17v12.5H14V17" stroke-linecap="butt" stroke-linejoin="miter"/><path d="M31 29.5l1.5 2.5h-20l1.5-2.5"/><path d="M11 14h23" fill="none" stroke-linejoin="miter"/></g>'
590
650
  };
591
651
 
652
+ // src/terminal.ts
653
+ import { stdin, stdout } from "node:process";
654
+ var QUERY_ID = 73192;
655
+ function blocksAutoGraphics(env) {
656
+ const candidate = env.TERM === "xterm-kitty" || env.TERM === "xterm-ghostty" || ["kitty", "ghostty"].includes(env.TERM_PROGRAM?.toLowerCase() ?? "");
657
+ return Boolean(!candidate || env.TMUX || env.STY || env.TERM === "dumb" || env.KONSOLE_VERSION || env.TERM_PROGRAM?.toLowerCase() === "konsole");
658
+ }
659
+ function supportsGraphics(mode, tty = Boolean(stdout.isTTY && stdin.isTTY), env = process.env, confirmed = false) {
660
+ if (!tty || (mode === "text" || mode === "ascii")) return false;
661
+ if (mode === "kitty") return true;
662
+ if (blocksAutoGraphics(env)) return false;
663
+ return confirmed;
664
+ }
665
+ async function detectGraphics(mode, input = stdin, output = stdout, env = process.env, timeout = 300, onCellAspect) {
666
+ const tty = Boolean(input.isTTY && output.isTTY);
667
+ if (mode === "text" || mode === "ascii" || !tty || env.TMUX || env.STY || env.TERM === "dumb" || mode === "auto" && blocksAutoGraphics(env)) {
668
+ return supportsGraphics(mode, tty, env);
669
+ }
670
+ const previous = input.listeners("data");
671
+ previous.forEach((listener) => input.off("data", listener));
672
+ const wasRaw = input.isRaw;
673
+ const wasFlowing = input.readableFlowing === true;
674
+ let pending = "";
675
+ let keyboard = "";
676
+ let confirmed = mode === "kitty";
677
+ return await new Promise((resolve, reject) => {
678
+ let finished = false;
679
+ const finish = (error) => {
680
+ if (finished) return;
681
+ finished = true;
682
+ clearTimeout(timer);
683
+ input.pause();
684
+ input.off("data", onData);
685
+ input.off("end", onEnd);
686
+ input.off("error", onError);
687
+ input.setRawMode(Boolean(wasRaw));
688
+ previous.forEach((listener) => input.on("data", listener));
689
+ if (keyboard) input.unshift(Buffer.from(keyboard, "latin1"));
690
+ if (wasFlowing) input.resume();
691
+ if (error) reject(error);
692
+ else resolve(confirmed);
693
+ };
694
+ const onEnd = () => finish();
695
+ const onError = (error) => finish(error);
696
+ const onData = (chunk) => {
697
+ pending += (typeof chunk === "string" ? Buffer.from(chunk) : chunk).toString("latin1");
698
+ while (pending) {
699
+ if (pending[0] !== "\x1B") {
700
+ keyboard += pending[0];
701
+ pending = pending.slice(1);
702
+ continue;
703
+ }
704
+ const reply = pending.match(/^\x1b_G([^;]*);([^\x1b]*)\x1b\\/);
705
+ if (reply) {
706
+ if (mode === "auto" && reply[1].split(",").includes(`i=${QUERY_ID}`)) confirmed = reply[2] === "OK";
707
+ pending = pending.slice(reply[0].length);
708
+ continue;
709
+ }
710
+ const cellSize = pending.match(/^\x1b\[6;(\d+);(\d+)t/);
711
+ if (cellSize) {
712
+ const height = Number(cellSize[1]), width = Number(cellSize[2]);
713
+ if (height > 0 && width > 0 && height <= 1e3 && width <= 1e3) onCellAspect?.(height / width);
714
+ pending = pending.slice(cellSize[0].length);
715
+ continue;
716
+ }
717
+ const attributes = pending.match(/^\x1b\[\?[\d;]*c/);
718
+ if (attributes) {
719
+ keyboard += pending.slice(attributes[0].length);
720
+ pending = "";
721
+ finish();
722
+ return;
723
+ }
724
+ if ("\x1B_G".startsWith(pending) || pending.startsWith("\x1B_G") || "\x1B[?".startsWith(pending) || /^\x1b\[(?:\?[\d;]*|6[;\d]*)$/.test(pending)) break;
725
+ keyboard += pending[0];
726
+ pending = pending.slice(1);
727
+ }
728
+ };
729
+ const timer = setTimeout(() => finish(), timeout);
730
+ input.on("data", onData);
731
+ input.once("end", onEnd);
732
+ input.once("error", onError);
733
+ try {
734
+ input.setRawMode(true);
735
+ input.resume();
736
+ output.write(`\x1B_Gi=${QUERY_ID},s=1,v=1,a=q,t=d,f=24;AAAA\x1B\\\x1B[16t\x1B[c`);
737
+ } catch (error) {
738
+ finish(error);
739
+ }
740
+ });
741
+ }
742
+
592
743
  // src/graphics.ts
593
744
  var require2 = createRequire(import.meta.url);
594
745
  var pieces = pieces_default;
595
746
  var IMAGE_ID = 73191;
596
- function supportsGraphics(mode, tty = Boolean(process.stdout.isTTY), env = process.env) {
597
- if (!tty || mode === "text") return false;
598
- if (mode === "kitty") return true;
599
- if (env.TMUX || env.STY) return false;
600
- return env.TERM_PROGRAM === "ghostty" || env.TERM === "xterm-ghostty" || env.TERM === "xterm-kitty";
747
+ function clearGraphics() {
748
+ return `\x1B_Ga=d,d=I,i=${IMAGE_ID},q=2;\x1B\\`;
601
749
  }
602
750
  function boardSvg(chess, perspective, last) {
603
751
  const order = perspective === "w" ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];
@@ -626,19 +774,20 @@ function boardPng(chess, perspective, last) {
626
774
  const { Resvg } = require2("@resvg/resvg-js");
627
775
  return new Resvg(boardSvg(chess, perspective, last)).render().asPng();
628
776
  }
629
- function renderGraphics(chess, perspective, last, fixed = false) {
630
- const columnsPerRow = 2.2;
631
- const availableRows = Math.max(1, (process.stdout.rows || 40) - (fixed ? 8 : 7));
632
- const availableColumns = Math.max(2, (process.stdout.columns || 80) - 2);
633
- const rows = Math.max(1, Math.min(32, availableRows, Math.floor(availableColumns / columnsPerRow)));
634
- const columns = Math.min(availableColumns, Math.round(rows * columnsPerRow));
777
+ function renderGraphics(chess, perspective, last, fixed = false, columnsPerRow = 2) {
778
+ const availableRows = Math.max(1, Math.min(32, (process.stdout.rows || 40) - (fixed ? 8 : 7)));
779
+ const availableColumns = Math.max(1, (process.stdout.columns || 80) - 2);
780
+ const ratio = Number.isFinite(columnsPerRow) && columnsPerRow > 0 ? columnsPerRow : 2;
781
+ const widthLimited = availableColumns / ratio < availableRows;
782
+ const rows = widthLimited ? Math.ceil(availableColumns / ratio) : availableRows;
783
+ const placement = widthLimited ? `c=${availableColumns}` : `r=${rows}`;
635
784
  const data = boardPng(chess, perspective, last).toString("base64");
636
- let output = `\x1B_Ga=d,d=I,i=${IMAGE_ID},q=2;\x1B\\`;
785
+ let output = clearGraphics();
637
786
  if (!fixed) output += "\n".repeat(rows) + `\x1B[${rows}A\r`;
638
787
  for (let offset = 0; offset < data.length; offset += 4096) {
639
788
  const chunk = data.slice(offset, offset + 4096);
640
789
  const more = offset + 4096 < data.length ? 1 : 0;
641
- const control = offset === 0 ? `a=T,f=100,t=d,i=${IMAGE_ID},c=${columns},r=${rows},C=1,q=2,` : "";
790
+ const control = offset === 0 ? `a=T,f=100,t=d,i=${IMAGE_ID},${placement},C=1,q=2,` : "";
642
791
  output += `\x1B_G${control}m=${more};${chunk}\x1B\\`;
643
792
  }
644
793
  return output + `\x1B[${rows}B\r`;
@@ -701,9 +850,9 @@ go depth ${depth}
701
850
  }
702
851
 
703
852
  // src/screen.ts
704
- import { stdout } from "node:process";
853
+ import { stdout as stdout2 } from "node:process";
705
854
  var GameScreen = class {
706
- constructor(active, output = stdout, manageScreen = true) {
855
+ constructor(active, output = stdout2, manageScreen = true) {
707
856
  this.active = active;
708
857
  this.output = output;
709
858
  this.manageScreen = manageScreen;
@@ -731,14 +880,14 @@ ${status}
731
880
  }
732
881
  const width = Math.max(1, (this.output.columns || 80) - 1);
733
882
  const fit = (text) => [...text.replace(/[\x00-\x1f\x7f]/g, " ")].slice(0, width).join("");
734
- const title = `\x1B[38;2;224;242;215m${fit(header).padEnd(width)}\x1B[0m`;
735
- const history = `\x1B[38;2;190;221;173m${fit(moves).padEnd(width)}\x1B[0m`;
883
+ const title = `\x1B[39m${fit(header).padEnd(width)}\x1B[0m`;
884
+ const history = `\x1B[39m${fit(moves).padEnd(width)}\x1B[0m`;
736
885
  const horizontalPadding = Math.min(1, Math.floor((width - 1) / 2));
737
886
  const innerWidth = Math.max(1, width - horizontalPadding * 2);
738
887
  const controls = "/help";
739
888
  const visibleControls = controls.slice(-Math.min(innerWidth, controls.length));
740
889
  const statusWidth = Math.max(0, innerWidth - visibleControls.length);
741
- const footer = `\x1B[38;2;224;242;215m${" ".repeat(horizontalPadding)}${fit(status).slice(0, statusWidth).padEnd(statusWidth)}${visibleControls}${" ".repeat(horizontalPadding + 1)}\x1B[0m`;
890
+ const footer = `\x1B[39m${" ".repeat(horizontalPadding)}${fit(status).slice(0, statusWidth).padEnd(statusWidth)}${visibleControls}${" ".repeat(horizontalPadding + 1)}\x1B[0m`;
742
891
  const bottom = Math.max(6, this.output.rows || 40);
743
892
  this.output.write(`\x1B[?2026h\x1B[H\x1B[2J${title}\r
744
893
  ${history}\r
@@ -777,7 +926,7 @@ ${board}\x1B[${bottom - 4};1H${footer}` + this.inputFrame("", "Type any moves e.
777
926
  }
778
927
  };
779
928
  var MenuScreen = class {
780
- constructor(active, output = stdout) {
929
+ constructor(active, output = stdout2) {
781
930
  this.active = active;
782
931
  this.output = output;
783
932
  }
@@ -800,9 +949,9 @@ ${footer}
800
949
  `);
801
950
  return;
802
951
  }
803
- const title = `\x1B[38;2;224;242;215m${fit(header).padEnd(width)}\x1B[0m`;
952
+ const title = `\x1B[39m${fit(header).padEnd(width)}\x1B[0m`;
804
953
  const horizontalPadding = Math.min(2, Math.floor((width - 1) / 2));
805
- const status = `\x1B[38;2;210;225;202m${" ".repeat(horizontalPadding)}${fit(footer).slice(0, width - horizontalPadding * 2).padEnd(width - horizontalPadding * 2)}${" ".repeat(horizontalPadding)}\x1B[0m`;
954
+ const status = `\x1B[39m${" ".repeat(horizontalPadding)}${fit(footer).slice(0, width - horizontalPadding * 2).padEnd(width - horizontalPadding * 2)}${" ".repeat(horizontalPadding)}\x1B[0m`;
806
955
  const body = content.split("\n").map((line) => fit(line)).join("\r\n");
807
956
  this.output.write(`\x1B[?25l\x1B[?2026h\x1B[H\x1B[2J${title}\r
808
957
  \r
@@ -884,7 +1033,7 @@ var GameStore = class {
884
1033
  var HELP = `chess \u2014 terminal chess
885
1034
 
886
1035
  Usage: chess [--elo 1500] [--color white|black] [--fen FEN]
887
- [--server URL] [--depth 12] [--graphics auto|kitty|text]
1036
+ [--server URL] [--depth 12] [--graphics auto|kitty|text|ascii]
888
1037
 
889
1038
  Run "chess" with no options to open the Play / Load game menu.
890
1039
  Moves accept UCI (e2e4), SAN (Nf3), or free text ("move the queen up by 1").
@@ -912,7 +1061,7 @@ function editGameInput(value, text, key) {
912
1061
  if (!key?.ctrl && !key?.meta && text && !/[\x00-\x1f\x7f]/.test(text)) return value + text;
913
1062
  return value;
914
1063
  }
915
- var promptColor = "\x1B[38;2;190;221;173m";
1064
+ var promptColor = "\x1B[39m";
916
1065
  var reset = "\x1B[0m";
917
1066
  var ELO_PRESETS = [
918
1067
  { label: "Beginner", elo: 1320 },
@@ -921,7 +1070,7 @@ var ELO_PRESETS = [
921
1070
  { label: "Expert", elo: 2200 },
922
1071
  { label: "Master", elo: 3190 }
923
1072
  ];
924
- async function run(args) {
1073
+ async function run(args, installation) {
925
1074
  if (args.includes("--help") || args.includes("-h")) {
926
1075
  console.log(HELP);
927
1076
  return;
@@ -931,32 +1080,39 @@ async function run(args) {
931
1080
  return index < 0 ? fallback : args[index + 1] ?? fallback;
932
1081
  };
933
1082
  const graphics = get("--graphics", "auto");
934
- if (!["auto", "kitty", "text"].includes(graphics)) throw new Error("Graphics must be auto, kitty, or text.");
1083
+ if (!["auto", "kitty", "text", "ascii"].includes(graphics)) throw new Error("Graphics must be auto, kitty, text, or ascii.");
935
1084
  const depth = Number(get("--depth", "12"));
936
1085
  if (!Number.isInteger(depth) || depth < 1 || depth > 30) throw new Error("Depth must be an integer from 1 to 30.");
1086
+ let cellAspect = 2;
1087
+ const useGraphics = await detectGraphics(graphics, stdin2, stdout3, process.env, 300, (ratio) => {
1088
+ cellAspect = ratio;
1089
+ });
1090
+ const update = installation && stdin2.isTTY && stdout3.isTTY && process.env.ZCHESS_NO_UPDATE_CHECK !== "1" ? await checkForUpdate(installation.version, { homebrew: installation.homebrew }) : void 0;
937
1091
  const store = new GameStore(get("--db", void 0));
938
1092
  const direct = args.some((arg) => arg.startsWith("--"));
939
- const interactiveMenu = !direct && stdin.isTTY && stdout2.isTTY;
1093
+ const interactiveMenu = !direct && stdin2.isTTY && stdout3.isTTY;
940
1094
  const menuScreen = interactiveMenu ? new MenuScreen(true) : void 0;
941
1095
  menuScreen?.open();
1096
+ if (update && !interactiveMenu) console.log(`Update available: ${installation.version} \u2192 ${update.version}
1097
+ Run: ${update.command}`);
942
1098
  try {
943
1099
  let keepGoing = true;
944
1100
  let returnToSavedGames = false;
945
1101
  while (keepGoing) {
946
1102
  let config;
947
- if (direct || !stdin.isTTY || !stdout2.isTTY) {
1103
+ if (direct || !stdin2.isTTY || !stdout3.isTTY) {
948
1104
  const elo = Number(get("--elo", "1500"));
949
1105
  if (!Number.isInteger(elo) || elo < 1320 || elo > 3190) throw new Error("ELO must be an integer from 1320 to 3190 (Stockfish UCI range).");
950
1106
  config = { elo, human: get("--color", "white").toLowerCase().startsWith("b") ? "b" : "w", fen: get("--fen", void 0) };
951
1107
  keepGoing = false;
952
1108
  } else {
953
- const choice = await mainMenu(store, menuScreen, returnToSavedGames);
1109
+ const choice = await mainMenu(store, menuScreen, returnToSavedGames, update, installation?.version);
954
1110
  returnToSavedGames = false;
955
1111
  if (choice === "quit") break;
956
1112
  config = choice;
957
1113
  }
958
1114
  if (config) {
959
- const again = await playGame(config, { graphics, depth, serverUrl: get("--server", process.env.ZCHESS_SERVER_URL || "http://localhost:8000"), store, sharedScreen: interactiveMenu });
1115
+ const again = await playGame(config, { useGraphics, ascii: graphics === "ascii", cellAspect, depth, serverUrl: get("--server", process.env.ZCHESS_SERVER_URL || "http://localhost:8000"), store, sharedScreen: interactiveMenu });
960
1116
  if (again && config.saved) returnToSavedGames = true;
961
1117
  if (direct || !again) keepGoing = false;
962
1118
  }
@@ -966,8 +1122,8 @@ async function run(args) {
966
1122
  store.close();
967
1123
  }
968
1124
  }
969
- async function mainMenu(store, screen, openSavedGames = false) {
970
- const rl = createInterface2({ input: stdin, output: stdout2 });
1125
+ async function mainMenu(store, screen, openSavedGames = false, update, installed) {
1126
+ const rl = createInterface2({ input: stdin2, output: stdout3 });
971
1127
  try {
972
1128
  while (true) {
973
1129
  if (openSavedGames) {
@@ -977,7 +1133,11 @@ async function mainMenu(store, screen, openSavedGames = false) {
977
1133
  if (game) return game;
978
1134
  continue;
979
1135
  }
980
- screen.draw("ZCHESS / LOCAL STOCKFISH", " 1 Play\n 2 Load a saved game\n 3 Quit", "");
1136
+ const notice = update ? `
1137
+
1138
+ Update available: ${installed} \u2192 ${update.version}
1139
+ Run: ${update.command}` : "";
1140
+ screen.draw("ZCHESS / LOCAL STOCKFISH", " 1 Play\n 2 Load a saved game\n 3 Quit" + notice, "");
981
1141
  const choice = await menuKey("Select \u203A ", ["1", "2", "3"]);
982
1142
  if (choice === "q") return "quit";
983
1143
  if (choice === "b") continue;
@@ -1079,7 +1239,7 @@ function menuText(prompt) {
1079
1239
  }
1080
1240
  if (key?.name === "backspace") {
1081
1241
  value = value.slice(0, -1);
1082
- stdout2.write("\b \b");
1242
+ stdout3.write("\b \b");
1083
1243
  return;
1084
1244
  }
1085
1245
  if (key?.name === "return" || key?.name === "enter") {
@@ -1089,29 +1249,29 @@ function menuText(prompt) {
1089
1249
  const character = text ?? "";
1090
1250
  if (key?.ctrl || !character) return;
1091
1251
  value += character;
1092
- stdout2.write(character);
1252
+ stdout3.write(character);
1093
1253
  });
1094
1254
  }
1095
1255
  function rawPrompt(prompt, onKey) {
1096
- const stream = stdin;
1256
+ const stream = stdin2;
1097
1257
  if (!stream.isTTY || !stream.setRawMode) return Promise.reject(new Error("Menu selection requires an interactive terminal."));
1098
- const previous = stdin.listeners("keypress");
1099
- previous.forEach((listener) => stdin.removeListener("keypress", listener));
1100
- stdout2.write(`${promptColor}${prompt}${reset}`);
1258
+ const previous = stdin2.listeners("keypress");
1259
+ previous.forEach((listener) => stdin2.removeListener("keypress", listener));
1260
+ stdout3.write(`${promptColor}${prompt}${reset}`);
1101
1261
  stream.setRawMode(true);
1102
1262
  return new Promise((resolve) => {
1103
1263
  let finished = false;
1104
1264
  const finish = (value) => {
1105
1265
  if (finished) return;
1106
1266
  finished = true;
1107
- stdin.removeListener("keypress", listener);
1267
+ stdin2.removeListener("keypress", listener);
1108
1268
  stream.setRawMode(false);
1109
- [...previous].reverse().forEach((listener2) => stdin.prependListener("keypress", listener2));
1110
- stdout2.write("\r\n");
1269
+ [...previous].reverse().forEach((listener2) => stdin2.prependListener("keypress", listener2));
1270
+ stdout3.write("\r\n");
1111
1271
  resolve(value);
1112
1272
  };
1113
1273
  const listener = (text, key) => onKey(text, key, finish);
1114
- stdin.on("keypress", listener);
1274
+ stdin2.on("keypress", listener);
1115
1275
  });
1116
1276
  }
1117
1277
  async function playGame(config, options) {
@@ -1121,9 +1281,9 @@ async function playGame(config, options) {
1121
1281
  if (saved) for (const move of saved.moves) chess.play(move);
1122
1282
  const abort = new AbortController();
1123
1283
  const server = new ChessServerClient(options.serverUrl, abort.signal);
1124
- const rl = createInterface2({ input: stdin, output: stdout2 });
1125
- const screen = new GameScreen(Boolean(stdout2.isTTY && stdin.isTTY), stdout2, !options.sharedScreen);
1126
- const useGraphics = supportsGraphics(options.graphics);
1284
+ const rl = createInterface2({ input: stdin2, output: stdout3 });
1285
+ const screen = new GameScreen(Boolean(stdout3.isTTY && stdin2.isTTY), stdout3, !options.sharedScreen);
1286
+ let useGraphics = options.useGraphics;
1127
1287
  let stopped = false;
1128
1288
  let redrawInput;
1129
1289
  let last = null;
@@ -1137,12 +1297,21 @@ async function playGame(config, options) {
1137
1297
  const persist = () => {
1138
1298
  gameId = options.store.save({ elo, color: human, startFen, fen: chess.fen(), moves: chess.history.map((entry) => entry.san), status: chess.status() ?? "In progress" }, gameId);
1139
1299
  };
1140
- const draw = () => screen.draw(
1141
- header,
1142
- showingHelp ? commandHelp() : useGraphics ? renderGraphics(chess, human, last, screen.active) : render(chess, { perspective: human, last, compact: screen.active && (stdout2.rows || 40) < 36 }),
1143
- notice,
1144
- showingHelp ? "" : moveHistory(chess, Math.max(1, (stdout2.columns || 80) - 1))
1145
- );
1300
+ const draw = () => {
1301
+ let board;
1302
+ if (showingHelp) board = (useGraphics ? clearGraphics() : "") + commandHelp();
1303
+ else {
1304
+ try {
1305
+ board = useGraphics ? renderGraphics(chess, human, last, screen.active, options.cellAspect) : "";
1306
+ } catch {
1307
+ stdout3.write(clearGraphics());
1308
+ useGraphics = false;
1309
+ board = "";
1310
+ }
1311
+ if (!useGraphics) board = render(chess, { ascii: options.ascii, perspective: human, last, compact: screen.active && (stdout3.rows || 40) < 36 });
1312
+ }
1313
+ screen.draw(header, board, notice, showingHelp ? "" : moveHistory(chess, Math.max(1, (stdout3.columns || 80) - 1)));
1314
+ };
1146
1315
  const takeBack = () => {
1147
1316
  notice = undoTurn(chess, human) ? "Took back your last move and any Stockfish reply." : "No move to undo yet.";
1148
1317
  const move = chess.history.at(-1)?.move;
@@ -1161,18 +1330,30 @@ async function playGame(config, options) {
1161
1330
  abort.abort();
1162
1331
  search?.abort();
1163
1332
  };
1333
+ let resizeTask;
1164
1334
  const resize = () => {
1165
- if (!stopped) {
1166
- draw();
1167
- redrawInput?.();
1168
- }
1335
+ if (stopped || resizeTask) return;
1336
+ resizeTask = (async () => {
1337
+ try {
1338
+ if (useGraphics) await detectGraphics("kitty", stdin2, stdout3, process.env, 300, (ratio) => {
1339
+ options.cellAspect = ratio;
1340
+ });
1341
+ if (!stopped) {
1342
+ draw();
1343
+ redrawInput?.();
1344
+ }
1345
+ } catch {
1346
+ }
1347
+ })().finally(() => {
1348
+ resizeTask = void 0;
1349
+ });
1169
1350
  };
1170
1351
  const question = async (placeholder) => {
1171
1352
  if (!screen.active) return await rl.question(`${promptColor}${placeholder} \u203A ${reset}`, { signal: abort.signal });
1172
- const stream = stdin;
1353
+ const stream = stdin2;
1173
1354
  const previousRaw = stream.isRaw;
1174
- const previous = stdin.listeners("keypress");
1175
- previous.forEach((listener) => stdin.removeListener("keypress", listener));
1355
+ const previous = stdin2.listeners("keypress");
1356
+ previous.forEach((listener) => stdin2.removeListener("keypress", listener));
1176
1357
  stream.setRawMode?.(true);
1177
1358
  return new Promise((resolve) => {
1178
1359
  let value = "";
@@ -1181,9 +1362,9 @@ async function playGame(config, options) {
1181
1362
  const finish = (answer) => {
1182
1363
  if (done) return;
1183
1364
  done = true;
1184
- stdin.removeListener("keypress", onKey);
1365
+ stdin2.removeListener("keypress", onKey);
1185
1366
  abort.signal.removeEventListener("abort", onAbort);
1186
- previous.forEach((listener) => stdin.on("keypress", listener));
1367
+ previous.forEach((listener) => stdin2.on("keypress", listener));
1187
1368
  stream.setRawMode?.(previousRaw);
1188
1369
  redrawInput = void 0;
1189
1370
  screen.input("", placeholder);
@@ -1204,17 +1385,17 @@ async function playGame(config, options) {
1204
1385
  redraw();
1205
1386
  };
1206
1387
  redrawInput = redraw;
1207
- stdin.on("keypress", onKey);
1388
+ stdin2.on("keypress", onKey);
1208
1389
  abort.signal.addEventListener("abort", onAbort, { once: true });
1209
1390
  redraw();
1210
1391
  });
1211
1392
  };
1212
- stdin.on("keypress", shortcut);
1393
+ stdin2.on("keypress", shortcut);
1213
1394
  rl.on("SIGINT", stop);
1214
1395
  rl.on("close", stop);
1215
1396
  process.on("SIGINT", stop);
1216
1397
  process.on("SIGTERM", stop);
1217
- stdout2.on("resize", resize);
1398
+ stdout3.on("resize", resize);
1218
1399
  screen.open();
1219
1400
  persist();
1220
1401
  try {
@@ -1329,12 +1510,14 @@ async function playGame(config, options) {
1329
1510
  } catch (error) {
1330
1511
  if (!stopped) throw error;
1331
1512
  } finally {
1513
+ await resizeTask;
1332
1514
  returnToMenu = screen.active && !stopped;
1333
- stdin.off("keypress", shortcut);
1334
- stdout2.off("resize", resize);
1515
+ stdin2.off("keypress", shortcut);
1516
+ stdout3.off("resize", resize);
1335
1517
  process.off("SIGINT", stop);
1336
1518
  process.off("SIGTERM", stop);
1337
1519
  rl.close();
1520
+ if (useGraphics) stdout3.write(clearGraphics());
1338
1521
  screen.close();
1339
1522
  }
1340
1523
  return returnToMenu || screen.active && returnToMenuRequested;
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/cli.ts", "../../../packages/chess/src/index.ts", "../../../packages/chess/src/resolution.ts", "../../../packages/chess/src/legality.ts", "../../../packages/chess/src/suggestions.ts", "../../../packages/chess/src/input.ts", "../../../packages/chess/src/history.ts", "../src/api.ts", "../src/ui.ts", "../src/graphics.ts", "../../../packages/chess/assets/pieces.json", "../src/engine.ts", "../src/screen.ts", "../src/store.ts"],
4
- "sourcesContent": ["import { createInterface } from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { Chess, START_FEN } from '@zchess/chess';\nimport { modelInput } from './input.js';\nimport { ChessServerClient } from './api.js';\nimport { render } from './ui.js';\nimport { renderGraphics, supportsGraphics, type GraphicsMode } from './graphics.js';\nimport { engineMove } from './engine.js';\nimport { GameScreen, MenuScreen } from './screen.js';\nimport { moveHistory, undoTurn } from './history.js';\nimport { GameStore, type SavedGame } from './store.js';\nimport type { Key } from 'node:readline';\n\nconst HELP = `chess \u2014 terminal chess\n\nUsage: chess [--elo 1500] [--color white|black] [--fen FEN]\n [--server URL] [--depth 12] [--graphics auto|kitty|text]\n\nRun \"chess\" with no options to open the Play / Load game menu.\nMoves accept UCI (e2e4), SAN (Nf3), or free text (\"move the queen up by 1\").\nStockfish is included and runs locally. Only free text requires the Chess server.\nGames are saved automatically in ~/.local/share/zchess/games.sqlite.\nCommands: /fen, /fen <position>, /undo, /help, /back, /quit`;\n\nexport function commandHelp(): string {\n return [\n 'COMMANDS',\n '/help Show this list',\n '/undo Take back a turn',\n '/fen Show the current position',\n '/fen <FEN> Load a position',\n '/back Return to the previous screen',\n '/quit Quit Chess',\n '',\n 'SHORTCUTS',\n 'Ctrl+C Quit',\n 'Ctrl+U Clear input',\n ].join('\\n');\n}\n\nexport function editGameInput(value: string, text: string, key: Key): string {\n if ((key?.ctrl && key.name === 'u') || (key?.meta && key.name === 'backspace')) return '';\n if (key?.name === 'backspace') return [...value].slice(0, -1).join('');\n if (!key?.ctrl && !key?.meta && text && !/[\\x00-\\x1f\\x7f]/.test(text)) return value + text;\n return value;\n}\n\nconst promptColor = '\\x1b[38;2;190;221;173m';\nconst reset = '\\x1b[0m';\nconst ELO_PRESETS = [\n { label: 'Beginner', elo: 1320 },\n { label: 'Intermediate', elo: 1500 },\n { label: 'Advanced', elo: 1800 },\n { label: 'Expert', elo: 2200 },\n { label: 'Master', elo: 3190 },\n];\ninterface GameConfig { elo: number; human: 'w' | 'b'; saved?: SavedGame; fen?: string }\n\nexport async function run(args: string[]): Promise<void> {\n if (args.includes('--help') || args.includes('-h')) { console.log(HELP); return; }\n const get = (name: string, fallback: string | undefined): string | undefined => {\n const index = args.indexOf(name);\n return index < 0 ? fallback : (args[index + 1] ?? fallback);\n };\n const graphics = get('--graphics', 'auto') as GraphicsMode;\n if (!['auto', 'kitty', 'text'].includes(graphics)) throw new Error('Graphics must be auto, kitty, or text.');\n const depth = Number(get('--depth', '12'));\n if (!Number.isInteger(depth) || depth < 1 || depth > 30) throw new Error('Depth must be an integer from 1 to 30.');\n const store = new GameStore(get('--db', undefined));\n const direct = args.some(arg => arg.startsWith('--'));\n const interactiveMenu = !direct && stdin.isTTY && stdout.isTTY;\n const menuScreen = interactiveMenu ? new MenuScreen(true) : undefined;\n menuScreen?.open();\n\n try {\n let keepGoing = true;\n let returnToSavedGames = false;\n while (keepGoing) {\n let config: GameConfig | undefined;\n if (direct || !stdin.isTTY || !stdout.isTTY) {\n const elo = Number(get('--elo', '1500'));\n if (!Number.isInteger(elo) || elo < 1320 || elo > 3190) throw new Error('ELO must be an integer from 1320 to 3190 (Stockfish UCI range).');\n config = { elo, human: get('--color', 'white')!.toLowerCase().startsWith('b') ? 'b' : 'w', fen: get('--fen', undefined) };\n keepGoing = false;\n } else {\n const choice = await mainMenu(store, menuScreen!, returnToSavedGames);\n returnToSavedGames = false;\n if (choice === 'quit') break;\n config = choice;\n }\n if (config) {\n const again = await playGame(config, { graphics, depth, serverUrl: get('--server', process.env.ZCHESS_SERVER_URL || 'http://localhost:8000')!, store, sharedScreen: interactiveMenu });\n if (again && config.saved) returnToSavedGames = true;\n if (direct || !again) keepGoing = false;\n }\n }\n } finally { menuScreen?.close(); store.close(); }\n}\n\nasync function mainMenu(store: GameStore, screen: MenuScreen, openSavedGames = false): Promise<GameConfig | 'quit'> {\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n while (true) {\n if (openSavedGames) {\n openSavedGames = false;\n const game = await savedGamesMenu(store, screen);\n if (game === 'quit') return 'quit';\n if (game) return game;\n continue;\n }\n screen.draw('ZCHESS / LOCAL STOCKFISH', ' 1 Play\\n 2 Load a saved game\\n 3 Quit', '');\n const choice = await menuKey('Select \u203A ', ['1', '2', '3']);\n if (choice === 'q') return 'quit';\n if (choice === 'b') continue;\n if (choice === '3') return 'quit';\n if (choice === '1') {\n const game = await newGameMenu(screen);\n if (game === 'quit') return 'quit';\n if (game) return game;\n }\n if (choice === '2' || choice === 'load') {\n const game = await savedGamesMenu(store, screen);\n if (game === 'quit') return 'quit';\n if (game) return game;\n }\n }\n } finally { rl.close(); }\n}\n\nasync function savedGamesMenu(store: GameStore, screen: MenuScreen): Promise<GameConfig | 'quit' | null> {\n const games = store.list();\n if (!games.length) {\n screen.draw('LOAD A SAVED GAME', 'No saved games yet.\\n\\n 1 Back\\n 2 Quit', '');\n const action = await menuKey('Select \u203A ', ['1', '2']);\n return action === '2' || action === 'q' ? 'quit' : null;\n }\n const recent = games.slice(0, 7);\n const lines = recent.map((game, index) => ` ${index + 1} ${game.updatedAt.slice(0, 16).replace('T', ' ')} \u00B7 ${game.elo} ELO \u00B7 ${game.moves.length ? game.moves.join(' ') : 'New game'} \u00B7 ${game.status}`);\n if (games.length > recent.length) lines.push(' Showing the 7 most recent games.');\n const backChoice = recent.length + 1;\n const quitChoice = recent.length + 2;\n lines.push(` ${backChoice} Back`, ` ${quitChoice} Quit`);\n screen.draw('LOAD A SAVED GAME', lines.join('\\n'), '');\n const selection = await menuKey('Choose a game \u203A ', Array.from({ length: quitChoice }, (_, index) => String(index + 1)));\n if (selection === 'q') return 'quit';\n if (Number(selection) === backChoice) return null;\n if (Number(selection) === quitChoice) return 'quit';\n const game = recent[Number(selection) - 1];\n return game ? { elo: game.elo, human: game.color, saved: game } : null;\n}\n\nasync function newGameMenu(screen: MenuScreen): Promise<GameConfig | null | 'quit'> {\n const choices = ELO_PRESETS.map(({ label, elo }, index) => ` ${index + 1} ${label} \u00B7 ${elo} ELO`);\n choices.push(' 6 Custom ELO');\n choices.push(' 7 Back', ' 8 Quit');\n screen.draw('NEW GAME / STOCKFISH STRENGTH', `${choices.join('\\n')}\\n\\nAvailable range: 1320\u20133190 ELO`, '');\n const selection = await menuKey('ELO \u203A ', ['1', '2', '3', '4', '5', '6', '7', '8']);\n if (selection === 'q') return 'quit';\n if (selection === '7') return null;\n if (selection === '8') return 'quit';\n let elo = ELO_PRESETS[Number(selection) - 1]?.elo;\n if (selection === '6') {\n let custom: number;\n while (true) {\n screen.draw('NEW GAME / CUSTOM ELO', 'Enter any ELO from 1320 to 3190.\\n\\n 0 Back\\n 00 Quit', '');\n const value = await menuText('ELO \u203A ');\n if (value === 'q') return 'quit';\n if (value === 'b' || value === null) return await newGameMenu(screen);\n custom = Number(value);\n if (Number.isInteger(custom) && custom >= 1320 && custom <= 3190) break;\n screen.draw('NEW GAME / CUSTOM ELO', 'Enter an ELO from 1320 to 3190.\\nThat value is outside the range.\\n\\n 0 Back\\n 00 Quit', '');\n }\n elo = custom;\n }\n if (elo === undefined) return null;\n while (true) {\n screen.draw('NEW GAME / CHOOSE SIDE', `Stockfish ${elo} ELO\\n\\n 1 White\\n 2 Black\\n 3 Random\\n 4 Back\\n 5 Quit`, '');\n const side = await menuKey('Side \u203A ', ['1', '2', '3', '4', '5']);\n if (side === 'q') return 'quit';\n if (side === '4') return await newGameMenu(screen);\n if (side === '5') return 'quit';\n const human: 'w' | 'b' = side === '1' ? 'w' : side === '2' ? 'b' : Math.random() < 0.5 ? 'w' : 'b';\n return { elo, human };\n }\n}\n\nfunction menuKey(prompt: string, choices: string[]): Promise<string> {\n return rawPrompt(prompt, (text, key, finish) => {\n if (key?.ctrl && key.name === 'c') { finish('q'); return; }\n const character = (text ?? '').toLowerCase();\n if (!key?.ctrl && choices.includes(character)) finish(character);\n });\n}\n\nfunction menuText(prompt: string): Promise<string | 'b' | 'q' | null> {\n let value = '';\n return rawPrompt(prompt, (text, key, finish) => {\n if (key?.ctrl && key.name === 'c') { finish('q'); return; }\n if (key?.name === 'backspace') {\n value = value.slice(0, -1);\n stdout.write('\\b \\b');\n return;\n }\n if (key?.name === 'return' || key?.name === 'enter') {\n finish(value === '0' ? 'b' : value === '00' ? 'q' : value);\n return;\n }\n const character = text ?? '';\n if (key?.ctrl || !character) return;\n value += character;\n stdout.write(character);\n });\n}\n\nfunction rawPrompt<T>(prompt: string, onKey: (text: string, key: Key, finish: (value: T) => void) => void): Promise<T> {\n const stream = stdin as typeof stdin & { setRawMode?: (mode: boolean) => void };\n if (!stream.isTTY || !stream.setRawMode) return Promise.reject(new Error('Menu selection requires an interactive terminal.'));\n const previous = stdin.listeners('keypress') as Array<(...args: any[]) => void>;\n previous.forEach(listener => stdin.removeListener('keypress', listener));\n stdout.write(`${promptColor}${prompt}${reset}`);\n stream.setRawMode(true);\n return new Promise(resolve => {\n let finished = false;\n const finish = (value: T): void => {\n if (finished) return;\n finished = true;\n stdin.removeListener('keypress', listener);\n stream.setRawMode(false);\n [...previous].reverse().forEach(listener => stdin.prependListener('keypress', listener));\n stdout.write('\\r\\n');\n resolve(value);\n };\n const listener = (text: string, key: Key): void => onKey(text, key, finish);\n stdin.on('keypress', listener);\n });\n}\n\nasync function playGame(config: GameConfig, options: { graphics: GraphicsMode; depth: number; serverUrl: string; store: GameStore; sharedScreen: boolean }): Promise<boolean> {\n const { elo, human, saved } = config;\n let startFen = saved?.startFen ?? config.fen ?? START_FEN;\n const chess = new Chess(startFen);\n if (saved) for (const move of saved.moves) chess.play(move);\n const abort = new AbortController();\n const server = new ChessServerClient(options.serverUrl, abort.signal);\n const rl = createInterface({ input: stdin, output: stdout });\n const screen = new GameScreen(Boolean(stdout.isTTY && stdin.isTTY), stdout, !options.sharedScreen);\n const useGraphics = supportsGraphics(options.graphics);\n let stopped = false;\n let redrawInput: (() => void) | undefined;\n let last: number[] | null = null;\n let showingHelp = false;\n let returnToMenu = false;\n let returnToMenuRequested = false;\n let search: AbortController | undefined;\n let notice = 'Your move';\n let gameId = saved?.id;\n const header = `CHESS / ${human === 'w' ? 'White' : 'Black'} / Stockfish ${elo} ELO`;\n const persist = (): void => {\n gameId = options.store.save({ elo, color: human, startFen, fen: chess.fen(), moves: chess.history.map(entry => entry.san), status: chess.status() ?? 'In progress' }, gameId);\n };\n const draw = (): void => screen.draw(header,\n showingHelp ? commandHelp()\n : useGraphics ? renderGraphics(chess, human, last, screen.active)\n : render(chess, { perspective: human, last, compact: screen.active && (stdout.rows || 40) < 36 }),\n notice, showingHelp ? '' : moveHistory(chess, Math.max(1, (stdout.columns || 80) - 1)));\n const takeBack = (): void => {\n notice = undoTurn(chess, human) ? 'Took back your last move and any Stockfish reply.' : 'No move to undo yet.';\n const move = chess.history.at(-1)?.move;\n last = move ? [move.from, move.to] : null;\n persist();\n };\n const shortcut = (text: string, key: Key): void => {\n if (stopped || returnToMenuRequested) return;\n if (key?.ctrl && key.name === 'c') { stop(); return; }\n };\n const stop = (): void => { stopped = true; abort.abort(); search?.abort(); };\n const resize = (): void => { if (!stopped) { draw(); redrawInput?.(); } };\n const question = async (placeholder: string): Promise<string> => {\n if (!screen.active) return await rl.question(`${promptColor}${placeholder} \u203A ${reset}`, { signal: abort.signal });\n const stream = stdin as typeof stdin & { setRawMode?: (mode: boolean) => void };\n const previousRaw = stream.isRaw;\n const previous = stdin.listeners('keypress') as Array<(text: string, key: Key) => void>;\n previous.forEach(listener => stdin.removeListener('keypress', listener));\n stream.setRawMode?.(true);\n return new Promise(resolve => {\n let value = '';\n let done = false;\n const redraw = (): void => screen.input(value, placeholder);\n const finish = (answer: string): void => {\n if (done) return;\n done = true;\n stdin.removeListener('keypress', onKey);\n abort.signal.removeEventListener('abort', onAbort);\n previous.forEach(listener => stdin.on('keypress', listener));\n stream.setRawMode?.(previousRaw);\n redrawInput = undefined;\n screen.input('', placeholder);\n resolve(answer);\n };\n const onAbort = (): void => finish('');\n const onKey = (text: string, key: Key): void => {\n if (key?.ctrl && key.name === 'c') { stop(); finish(''); return; }\n if (key?.name === 'return' || key?.name === 'enter') { finish(value); return; }\n value = editGameInput(value, text, key);\n redraw();\n };\n redrawInput = redraw;\n stdin.on('keypress', onKey);\n abort.signal.addEventListener('abort', onAbort, { once: true });\n redraw();\n });\n };\n stdin.on('keypress', shortcut);\n rl.on('SIGINT', stop);\n rl.on('close', stop);\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n stdout.on('resize', resize);\n screen.open();\n persist();\n\n try {\n while (!stopped && !returnToMenuRequested) {\n const status = chess.status();\n if (status) {\n notice = status;\n persist();\n draw();\n if (screen.active) {\n const command = await question('Type /undo, /back, or /quit \u00B7 Ctrl+C quit');\n if (command.trim().toLowerCase() === '/undo') { takeBack(); continue; }\n if (/^\\/(quit|exit)$/.test(command.trim().toLowerCase())) { stop(); break; }\n break;\n }\n console.log(status);\n break;\n }\n if (chess.turn !== human) {\n notice = 'Stockfish is thinking\u2026';\n draw();\n search = new AbortController();\n let move: string;\n try { move = await engineMove(chess.fen(), elo, options.depth, search.signal); }\n catch (error) {\n if (returnToMenuRequested) break;\n throw error;\n } finally { search = undefined; }\n const side = chess.turn;\n const san = chess.play(move);\n const played = chess.history.at(-1)!.move;\n last = [played.from, played.to];\n notice = `${side === 'w' ? 'White' : 'Black'} plays ${san}`;\n persist();\n continue;\n }\n\n draw();\n let raw: string;\n try { raw = await question(showingHelp ? 'Type /back to return to the game' : 'Type any moves e.g. e4 or e pawn up 2'); }\n catch (error) { if (returnToMenuRequested) break; throw error; }\n const wasShowingHelp = showingHelp;\n showingHelp = false;\n if (wasShowingHelp && /^\\/back$/i.test(raw.trim())) { notice = 'Your move'; continue; }\n let intent;\n try { intent = await modelInput(raw, chess, server); }\n catch (error) { notice = message(error); continue; }\n if (stopped) break;\n if (intent.type === 'quit') { stop(); break; }\n if (intent.type === 'help') { notice = 'Available commands'; showingHelp = true; continue; }\n if (intent.type === 'back') { returnToMenuRequested = true; break; }\n if (intent.type === 'show-fen') { notice = chess.fen(); continue; }\n if (intent.type === 'load-fen') {\n try { chess.load(intent.value); startFen = intent.value; last = null; notice = 'Position loaded.'; persist(); }\n catch (error) { notice = message(error); }\n continue;\n }\n if (intent.type === 'undo') { takeBack(); continue; }\n if (intent.type === 'empty') continue;\n try {\n const san = chess.play(intent.value);\n const move = chess.history.at(-1)!.move;\n last = [move.from, move.to];\n notice = intent.source === 'jev' ? `JEV chose ${san}` : `You played ${san}`;\n persist();\n } catch (error) { notice = `${message(error)}. Try e2e4, Nf3, or describe the move.`; }\n }\n } catch (error) { if (!stopped) throw error; }\n finally {\n returnToMenu = screen.active && !stopped;\n stdin.off('keypress', shortcut);\n stdout.off('resize', resize);\n process.off('SIGINT', stop);\n process.off('SIGTERM', stop);\n rl.close();\n screen.close();\n }\n return returnToMenu || screen.active && returnToMenuRequested;\n}\n\nexport { HELP };\nconst message = (error: unknown): string => error instanceof Error ? error.message : String(error);\n", "export const START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';\nconst FILES = 'abcdefgh';\nconst KNIGHT: Direction[] = [[1,2],[2,1],[2,-1],[1,-2],[-1,-2],[-2,-1],[-2,1],[-1,2]];\nconst KING: Direction[] = [[1,0],[-1,0],[0,1],[0,-1],[1,1],[1,-1],[-1,1],[-1,-1]];\ntype Side = 'w' | 'b';\ntype Piece = 'P'|'N'|'B'|'R'|'Q'|'K'|'p'|'n'|'b'|'r'|'q'|'k';\ntype Direction = [number, number];\nexport interface Move { from:number; to:number; promotion:string|null; flags:string }\nexport interface PositionSnapshot { board:(Piece|null)[]; turn:Side; castling:string; ep:number; halfmove:number; fullmove:number }\nexport interface HistoryEntry { move:Move; san:string; before:PositionSnapshot }\n\nexport const squareName = (i:number):string => FILES[i % 8] + (8 - Math.floor(i / 8));\nexport const squareIndex = (s:string):number => /^[a-h][1-8]$/i.test(s) ? (8 - Number(s[1])) * 8 + FILES.indexOf(s[0].toLowerCase()) : -1;\nconst color = (p:Piece|null):Side|null => p ? (p === p.toUpperCase() ? 'w' : 'b') : null;\n\nexport class Chess {\n board:(Piece|null)[]=[]; turn:Side='w'; castling=''; ep=-1; halfmove=0; fullmove=1; history:HistoryEntry[]=[];\n constructor(fen:string = START_FEN) { this.load(fen); }\n load(fen:string):this {\n const [placement, turn, castling = '-', ep = '-', half = '0', full = '1'] = fen.trim().split(/\\s+/);\n const ranks = placement?.split('/');\n if (!ranks || ranks.length !== 8 || !/^[wb]$/.test(turn)) throw new Error('Invalid FEN');\n this.board = [];\n for (const rank of ranks) {\n for (const c of rank) {\n if (/\\d/.test(c)) this.board.push(...Array(Number(c)).fill(null));\n else if (/[prnbqkPRNBQK]/.test(c)) this.board.push(c as Piece);\n else throw new Error('Invalid FEN');\n }\n }\n if (this.board.length !== 64) throw new Error('Invalid FEN');\n this.turn = turn as Side; this.castling = castling === '-' ? '' : castling; this.ep = ep === '-' ? -1 : squareIndex(ep);\n this.halfmove = Number(half); this.fullmove = Number(full); this.history = [];\n if (this.ep < -1 || !Number.isFinite(this.halfmove) || !Number.isFinite(this.fullmove)) throw new Error('Invalid FEN');\n return this;\n }\n fen():string {\n let out = '';\n for (let r=0;r<8;r++) { let empty=0; for(let f=0;f<8;f++){ const p=this.board[r*8+f]; if(!p) empty++; else {if(empty){out+=empty;empty=0;} out+=p;} } if(empty)out+=empty; if(r<7)out+='/'; }\n return `${out} ${this.turn} ${this.castling || '-'} ${this.ep < 0 ? '-' : squareName(this.ep)} ${this.halfmove} ${this.fullmove}`;\n }\n attacked(sq:number, by:Side):boolean {\n const r=Math.floor(sq/8), f=sq%8;\n const pawn = by==='w'?'P':'p', pawnRow = r + (by==='w'?1:-1);\n for(const df of [-1,1]) if(pawnRow>=0&&pawnRow<8&&f+df>=0&&f+df<8&&this.board[pawnRow*8+f+df]===pawn)return true;\n for(const [df,dr] of KNIGHT){const rr=r+dr,ff=f+df;if(rr>=0&&rr<8&&ff>=0&&ff<8&&this.board[rr*8+ff]===(by==='w'?'N':'n'))return true;}\n for(const [df,dr] of KING){const rr=r+dr,ff=f+df;if(rr>=0&&rr<8&&ff>=0&&ff<8&&this.board[rr*8+ff]===(by==='w'?'K':'k'))return true;}\n for(const [df,dr,types] of [[1,0,'RQ'],[-1,0,'RQ'],[0,1,'RQ'],[0,-1,'RQ'],[1,1,'BQ'],[-1,1,'BQ'],[1,-1,'BQ'],[-1,-1,'BQ']] as [number,number,string][]) {\n let rr=r+dr,ff=f+df; while(rr>=0&&rr<8&&ff>=0&&ff<8){const p=this.board[rr*8+ff];if(p){if(color(p)===by&&types.includes(p.toUpperCase()))return true;break;}rr+=dr;ff+=df;\n }} return false;\n }\n inCheck(side:Side=this.turn):boolean { const king=this.board.indexOf(side==='w'?'K':'k'); return king<0 || this.attacked(king,side==='w'?'b':'w'); }\n pseudo():Move[] {\n const moves:Move[]=[];\n const add=(from:number,to:number,promotion:string|null=null,flags='')=>moves.push({from,to,promotion,flags});\n for(let from=0;from<64;from++){const p=this.board[from];if(!p||color(p)!==this.turn)continue;const type=p.toUpperCase(),r=Math.floor(from/8),f=from%8;\n if(type==='P'){const dir=this.turn==='w'?-1:1, home=this.turn==='w'?6:1, last=this.turn==='w'?0:7;const one=(r+dir)*8+f;\n if(r+dir>=0&&r+dir<8&&!this.board[one]){if(r+dir===last)for(const q of 'qrbn')add(from,one,q,'p');else add(from,one);const two=(r+2*dir)*8+f;if(r===home&&!this.board[two])add(from,two,null,'d');}\n for(const df of [-1,1]){const rr=r+dir,ff=f+df;if(rr<0||rr>7||ff<0||ff>7)continue;const to=rr*8+ff;if((this.board[to]&&color(this.board[to])!==this.turn)||to===this.ep){if(rr===last)for(const q of 'qrbn')add(from,to,q,to===this.ep?'ep':'cp');else add(from,to,null,to===this.ep?'e':'c');}}\n } else if(type==='N'||type==='K'){for(const [df,dr] of type==='N'?KNIGHT:KING){const rr=r+dr,ff=f+df;if(rr>=0&&rr<8&&ff>=0&&ff<8&&color(this.board[rr*8+ff])!==this.turn)add(from,rr*8+ff,null,this.board[rr*8+ff]?'c':'');}\n if(type==='K')this.castleMoves(from,add);\n } else {const dirs=type==='B'?KING.slice(4):type==='R'?KING.slice(0,4):KING;for(const[df,dr]of dirs){let rr=r+dr,ff=f+df;while(rr>=0&&rr<8&&ff>=0&&ff<8){const to=rr*8+ff;if(color(this.board[to])===this.turn)break;add(from,to,null,this.board[to]?'c':'');if(this.board[to])break;rr+=dr;ff+=df;}}}\n } return moves;\n }\n castleMoves(from:number, add:(from:number,to:number,promotion?:string|null,flags?:string)=>void):void {\n const white=this.turn==='w', base=white?60:4, enemy=white?'b':'w'; if(from!==base||this.inCheck())return;\n const king=white?'K':'k', rook=white?'R':'r'; if(this.board[from]!==king)return;\n if(this.castling.includes(white?'K':'k')&&this.board[base+3]===rook&&!this.board[base+1]&&!this.board[base+2]&&!this.attacked(base+1,enemy)&&!this.attacked(base+2,enemy))add(from,base+2,null,'k');\n if(this.castling.includes(white?'Q':'q')&&this.board[base-4]===rook&&!this.board[base-1]&&!this.board[base-2]&&!this.board[base-3]&&!this.attacked(base-1,enemy)&&!this.attacked(base-2,enemy))add(from,base-2,null,'q');\n }\n moves():Move[] { return this.pseudo().filter(m=>{const snapshot=this.snapshot();this.apply(m);const bad=this.inCheck(this.turn==='w'?'b':'w');this.restore(snapshot);return !bad;}); }\n snapshot():PositionSnapshot{return {board:[...this.board],turn:this.turn,castling:this.castling,ep:this.ep,halfmove:this.halfmove,fullmove:this.fullmove};}\n restore(s:PositionSnapshot):void{Object.assign(this,s);}\n apply(m:Move):void{const p=this.board[m.from]! as Piece, side=this.turn, captured=this.board[m.to];this.board[m.to]=(m.promotion?(side==='w'?m.promotion.toUpperCase():m.promotion):p) as Piece;this.board[m.from]=null;\n if(m.flags.includes('e'))this.board[m.to+(side==='w'?8:-8)]=null;\n if(m.flags==='k'){this.board[m.to-1]=this.board[m.to+1];this.board[m.to+1]=null;} if(m.flags==='q'){this.board[m.to+1]=this.board[m.to-2];this.board[m.to-2]=null;}\n const rights:Record<number,string>={0:'q',4:'kq',7:'k',56:'Q',60:'KQ',63:'K'};for(const sq of [m.from,m.to])if(rights[sq])for(const x of rights[sq])this.castling=this.castling.replace(x,'');\n this.ep=m.flags==='d'?(m.from+m.to)/2:-1;this.halfmove=(p.toUpperCase()==='P'||captured||m.flags.includes('e'))?0:this.halfmove+1;if(side==='b')this.fullmove++;this.turn=side==='w'?'b':'w';\n }\n san(m:Move, legal:Move[]=this.moves()):string {const p=this.board[m.from]!, type=p.toUpperCase();if(m.flags==='k')return'O-O';if(m.flags==='q')return'O-O-O';let s=type==='P'?'':type;\n if(type!=='P'){const same=legal.filter(x=>x!==m&&x.to===m.to&&this.board[x.from]?.toUpperCase()===type);if(same.length){if(same.every(x=>x.from%8!==m.from%8))s+=FILES[m.from%8];else if(same.every(x=>Math.floor(x.from/8)!==Math.floor(m.from/8)))s+=8-Math.floor(m.from/8);else s+=squareName(m.from);}}\n if(m.flags.includes('c')||m.flags.includes('e'))s+=(type==='P'?FILES[m.from%8]:'')+'x';s+=squareName(m.to);if(m.promotion)s+='='+m.promotion.toUpperCase();const snap=this.snapshot();this.apply(m);if(this.inCheck()){s+=this.moves().length?'#'.replace('#','+'):'#';}this.restore(snap);return s;\n }\n play(input:string):string {const legal=this.moves(), normalized=input.trim().replace(/[!?+#]/g,'').replace(/0/g,'O');let move=legal.find(m=>`${squareName(m.from)}${squareName(m.to)}${m.promotion||''}`===normalized.toLowerCase());if(!move)move=legal.find(m=>this.san(m,legal).replace(/[+#]/g,'')===normalized);if(!move)throw new Error(`Illegal or unrecognized move: ${input}`);const san=this.san(move,legal), before=this.snapshot();this.apply(move);this.history.push({move,san,before});return san;}\n undo():HistoryEntry|undefined{const h=this.history.pop();if(h)this.restore(h.before);return h;}\n status():string|null{const moves=this.moves();if(!moves.length)return this.inCheck()?(this.turn==='w'?'Black':'White')+' wins by checkmate':'Draw by stalemate';if(this.halfmove>=100)return'Draw by fifty-move rule';return null;}\n}\n", "import type { Chess } from './index.js';\nexport interface MoveResult { move: string; fen: string; explanation: string }\nexport interface MoveResolver { resolve(text: string, chess: Chess): Promise<MoveResult> }\nexport class ResolutionError extends Error {\n constructor(message: string, readonly status: number) { super(message); }\n}\n", "import { Chess, squareName } from './index.js';\n\nconst names: Record<string, string> = { P: 'Pawn', N: 'Knight', B: 'Bishop', R: 'Rook', Q: 'Queen', K: 'King' };\n\n/** Explain a recognizable move rejected for king safety, without changing the game. */\nexport function illegalMoveReason(input: string, chess: Chess): string | undefined {\n const text = input.trim();\n const uci = /^([a-h][1-8])([a-h][1-8])([qrbn])?$/.exec(text);\n const san = /^([KQRBN])?([a-h])?([1-8])?(x)?([a-h][1-8])(?:=([QRBN]))?[+#]?$/.exec(text);\n const words = text.toLowerCase();\n const squares = words.match(/[a-h][1-8]/g) || [];\n const named = words.match(/\\bwith (?:my |the |a )?(pawn|knight|bishop|rook|queen|king)\\b/)?.[1]\n || words.match(/\\b(pawn|knight|bishop|rook|queen|king)\\b/)?.[1];\n const kind = uci ? undefined : san ? san[1] || 'P'\n : Object.keys(names).find(key => names[key].toLowerCase() === named);\n const from = uci?.[1] || (squares.length > 1 ? squares[0] : undefined);\n const to = uci?.[2] || san?.[5] || squares.at(-1);\n if (!to || (!uci && !san && !kind && !from)) return;\n const capture = san ? Boolean(san[4]) : /\\b(take|takes|taking|capture|captures|capturing)\\b/.test(words);\n const candidates = chess.pseudo().filter(move => {\n if (squareName(move.to) !== to) return false;\n if (from && squareName(move.from) !== from) return false;\n if (kind && chess.board[move.from]!.toUpperCase() !== kind) return false;\n if (san?.[2] && squareName(move.from)[0] !== san[2]) return false;\n if (san?.[3] && squareName(move.from)[1] !== san[3]) return false;\n if (capture && !/[ce]/.test(move.flags)) return false;\n return true;\n });\n const legal = chess.moves();\n // A legal interpretation or multiple possible pieces needs clarification, not a pin claim.\n if (candidates.length !== 1 || legal.some(move => move.from === candidates[0].from && move.to === candidates[0].to)) return;\n const move = candidates[0];\n const copy = new Chess(chess.fen());\n copy.apply(move);\n if (!copy.inCheck(chess.turn)) return;\n const piece = chess.board[move.from]!.toUpperCase();\n if (piece === 'K') return `King cannot move to ${to}: that square is attacked.`;\n if (chess.inCheck()) return 'You are in check; this move would leave your king in check.';\n\n const king = chess.board.indexOf(chess.turn === 'w' ? 'K' : 'k');\n const dr = Math.floor(move.from / 8) - Math.floor(king / 8);\n const df = move.from % 8 - king % 8;\n if (dr === 0 || df === 0 || Math.abs(dr) === Math.abs(df)) {\n const stepR = Math.sign(dr), stepF = Math.sign(df);\n let rank = Math.floor(king / 8) + stepR, file = king % 8 + stepF;\n let passedPiece = false;\n while (rank >= 0 && rank < 8 && file >= 0 && file < 8) {\n const index = rank * 8 + file;\n const blocker = chess.board[index];\n if (index === move.from) passedPiece = true;\n else if (blocker) {\n const enemy = (blocker === blocker.toUpperCase() ? 'w' : 'b') !== chess.turn;\n const slider = (dr === 0 || df === 0 ? 'RQ' : 'BQ').includes(blocker.toUpperCase());\n if (passedPiece && enemy && slider) {\n return `${names[piece]} ${squareName(move.from)} is pinned by ${names[blocker.toUpperCase()].toLowerCase()} ${squareName(index)}; moving it exposes your king.`;\n }\n break;\n }\n rank += stepR;\n file += stepF;\n }\n }\n return `${names[piece]} ${squareName(move.from)} cannot move to ${to}: it would expose your king to check.`;\n}\n", "import { squareName, type Chess } from './index.js';\n\nconst names: Record<string, string> = { king: 'K', queen: 'Q', rook: 'R', bishop: 'B', knight: 'N', pawn: 'P' };\nexport function normalizeNotation(text: string): string {\n const symbols: Record<string, string> = { '\u2654':'K', '\u265A':'K', '\u2655':'Q', '\u265B':'Q', '\u2656':'R', '\u265C':'R', '\u2657':'B', '\u265D':'B', '\u2658':'N', '\u265E':'N', '\u2659':'', '\u265F':'' };\n return text.trim().replace(/[\u2654\u265A\u2655\u265B\u2656\u265C\u2657\u265D\u2658\u265E\u2659\u265F]/g, symbol => symbols[symbol])\n .replace(/\u00D7/g, 'x').replace(/([a-h][1-8])\\s*(?:\u2192|->|-)\\s*(?=[a-h][1-8])/g, '$1').replace(/0/g, 'O');\n}\n\nexport const looksLikeNotation = (text: string): boolean => !/\\s/.test(text) && (/\\d/.test(text) || /^[O0]-[O0]/.test(text));\n\nfunction distance(a: string, b: string): number {\n let row = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 0; i < a.length; i++) {\n const next = [i + 1];\n for (let j = 0; j < b.length; j++) next.push(Math.min(next[j] + 1, row[j + 1] + 1, row[j] + Number(a[i] !== b[j])));\n row = next;\n }\n return row[b.length];\n}\n\n/** Prefer matching legal moves, then offer explicitly labeled legal alternatives. */\nexport function suggestMoves(input: string, chess: Chess): string[] {\n const text = normalizeNotation(input);\n const lower = text.toLowerCase();\n const notation = looksLikeNotation(text);\n const squares = lower.match(/[a-h][1-8]/g) || [];\n const destination = squares.at(-1);\n const source = squares.length > 1 ? squares[0] : undefined;\n const named = lower.match(/\\bwith (?:my |the |a )?(king|queen|rook|bishop|knight|pawn)\\b/)?.[1]\n || lower.match(/\\b(king|queen|rook|bishop|knight|pawn)\\b/)?.[1];\n const piece = named ? names[named] : notation && !/^[a-h][1-8][a-h][1-8]/.test(text)\n ? (/^[KQRBN]/.exec(text)?.[0] || (/^[a-h]/.test(text) ? 'P' : undefined)) : undefined;\n const capture = notation ? text.includes('x') : /\\b(take|takes|taking|capture|captures|capturing)\\b/.test(lower);\n const castle = /\\bcastl/.test(lower) || /^[O0]-[O0]/.test(text);\n const legal = chess.moves();\n const matches = legal.map(move => {\n const san = chess.san(move, legal);\n const from = squareName(move.from), to = squareName(move.to);\n const kind = chess.board[move.from]!.toUpperCase();\n if (piece && kind !== piece) return null;\n if (source && from !== source) return null;\n if (capture && !san.includes('x')) return null;\n if (castle && !san.startsWith('O-O')) return null;\n if (!notation && destination && to !== destination) return null;\n const uci = from + to + (move.promotion || '');\n const difference = Math.min(distance(text, san), distance(lower, uci));\n if (notation && difference > 2 && to !== destination) return null;\n return { san, score: (to === destination ? 20 : 0) + (from === source ? 10 : 0) - difference };\n }).filter((entry): entry is { san: string; score: number } => entry !== null)\n .sort((a, b) => b.score - a.score || a.san.localeCompare(b.san)).slice(0, 5).map(entry => entry.san);\n return matches.length ? matches : legal.map(move => chess.san(move, legal)).sort().slice(0, 5);\n}\n\nexport function suggestionMessage(input: string, chess: Chess): string {\n const moves = suggestMoves(input, chess);\n return moves.length ? `No exact match. Try: ${moves.join(' \u00B7 ')} (legal alternatives; confirm your intended move).` : 'No legal moves are available.';\n}\n", "import { squareName } from './index.js';\nimport type { Chess } from './index.js';\nimport { ResolutionError, type MoveResolver } from './resolution.js';\nimport { illegalMoveReason } from './legality.js';\nimport { looksLikeNotation, normalizeNotation, suggestionMessage } from './suggestions.js';\n\nexport type InputIntent =\n | { type:'empty' }\n | { type:'quit' }\n | { type:'help' }\n | { type:'undo' }\n | { type:'back' }\n | { type:'show-fen' }\n | { type:'load-fen'; value:string }\n | { type:'move'; value:string; source:'notation'|'jev'; fen?:string; explanation?:string };\n\n/** Parse local commands/notation; delegate all genuinely free-form text to JEV. */\nexport async function modelInput(raw:string, chess:Chess, server?:MoveResolver):Promise<InputIntent> {\n const text = String(raw).trim();\n const lower = text.toLowerCase();\n if (!text) return { type: 'empty' };\n if (/^\\/(quit|exit)$/.test(lower)) return { type: 'quit' };\n if (lower === '/help') return { type: 'help' };\n if (lower === '/undo') return { type: 'undo' };\n if (/^\\/(back|menu)$/.test(lower)) return { type: 'back' };\n if (/^\\/(fen|position)$/.test(lower)) return { type: 'show-fen' };\n if (/^\\/(fen|position)\\s+/.test(lower)) return { type: 'load-fen', value: text.replace(/^\\/(?:fen|position)\\s+/i, '').trim() };\n if (lower.startsWith('/')) throw new Error(`Unknown command: ${text}. Type /help to see commands.`);\n\n const legal = chess.moves();\n const normalized = normalizeNotation(text);\n const exact = legal.find(move => {\n const uci = squareName(move.from) + squareName(move.to) + (move.promotion || '');\n return uci === normalized || chess.san(move, legal) === normalized;\n });\n if (exact) return { type: 'move', value: squareName(exact.from) + squareName(exact.to) + (exact.promotion || ''), source: 'notation' };\n\n const reason = illegalMoveReason(text, chess);\n if (reason) throw new Error(`${reason} ${suggestionMessage(text, chess)}`);\n if (looksLikeNotation(text)) throw new Error(suggestionMessage(text, chess));\n\n if (!server) throw new Error(`Chess server is required for natural-language input. ${suggestionMessage(text, chess)}`);\n let result;\n try { result = await server.resolve(text, chess); }\n catch (error) {\n if (error instanceof ResolutionError && error.status === 422) throw new Error(suggestionMessage(text, chess));\n if (error instanceof Error && error.name === 'AbortError') throw error;\n const detail = error instanceof Error ? error.message : String(error);\n throw new Error(`${detail}. ${suggestionMessage(text, chess)}`);\n }\n return { type: 'move', value: result.move, fen: result.fen, explanation: result.explanation, source: 'jev' };\n}\n", "import type { Chess } from './index.js';\n\n/** Undo through the player's most recent move, including any engine reply. */\nexport function undoTurn(chess: Chess, human: 'w' | 'b'): boolean {\n let index = chess.history.length - 1;\n while (index >= 0 && chess.history[index].before.turn !== human) index--;\n if (index < 0) return false;\n while (chess.history.length > index) chess.undo();\n return true;\n}\n\nexport function moveHistory(chess: Chess, width = 80): string {\n const groups: string[] = [];\n for (const entry of chess.history) {\n const { fullmove, turn } = entry.before;\n if (turn === 'w') groups.push(`${fullmove}. ${entry.san}`);\n else if (groups.length) groups[groups.length - 1] += ` ${entry.san}`;\n else groups.push(`${fullmove}\u2026 ${entry.san}`);\n }\n if (!groups.length) return 'Moves: \u2014';\n let clipped = false;\n while (groups.length > 1 && `Moves: ${clipped ? '\u2026 ' : ''}${groups.join(' ')}`.length > width) {\n groups.shift();\n clipped = true;\n }\n return `Moves: ${clipped ? '\u2026 ' : ''}${groups.join(' ')}`;\n}\n", "import type { Chess } from '@zchess/chess';\nimport { ResolutionError, type MoveResult } from '@zchess/chess/interaction';\nexport { ResolutionError, type MoveResult } from '@zchess/chess/interaction';\nexport class ChessServerClient {\n constructor(private readonly baseUrl=process.env.ZCHESS_SERVER_URL||'http://localhost:8000', private readonly signal?:AbortSignal){}\n async resolve(text:string,chess:Chess):Promise<MoveResult>{return this.post('/api/resolve',{instruction:text,fen:chess.fen()});}\n private async post(path:string,body:unknown):Promise<MoveResult>{const response=await fetch(this.baseUrl.replace(/\\/$/,'')+path,{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify(body),signal:this.signal});if(!response.ok){\n const body = await response.json().catch(() => ({})) as {detail?:unknown};\n throw new ResolutionError(typeof body.detail === 'string' ? body.detail : `Chess server failed (${response.status})`, response.status);\n }return response.json() as Promise<MoveResult>;}\n}\n", "import type { Chess } from '@zchess/chess';\n\nconst PIECES: Record<string, string> = {\n K: '\u265A', Q: '\u265B', R: '\u265C', B: '\u265D', N: '\u265E', P: '\u265F',\n k: '\u265A', q: '\u265B', r: '\u265C', b: '\u265D', n: '\u265E', p: '\u265F',\n};\nconst OUTLINES: Record<string, string> = { K: '\u2654', Q: '\u2655', R: '\u2656', B: '\u2657', N: '\u2658', P: '\u2659' };\nconst RESET = '\\x1b[0m';\ninterface RenderOptions { perspective?: 'w' | 'b'; last?: number[] | null; color?: boolean; compact?: boolean }\n\nexport function render(chess: Chess, { perspective = 'w', last = null, color = Boolean(process.stdout.isTTY), compact = false }: RenderOptions = {}): string {\n const rows = perspective === 'w' ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];\n const files = perspective === 'w' ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];\n const cellWidth = Math.max(6, Math.min(8, Math.floor(((process.stdout.columns || 80) - 8) / 8)));\n const cell = (content = ''): string => {\n const left = Math.floor((cellWidth - 1) / 2);\n return `${' '.repeat(left)}${content}${' '.repeat(cellWidth - left - (content ? 1 : 0))}`;\n };\n const green = (text: string): string => color ? `\\x1b[38;5;114m${text}${RESET}` : text;\n const border = green(` +${'-'.repeat(cellWidth * 8)}+`);\n const output = [border];\n\n for (const rank of rows) {\n for (const line of compact ? [1] : [0, 1, 2]) {\n let row = green(`${line === 1 ? ` ${8 - rank} ` : ' '}|`);\n for (const file of files) {\n const index = rank * 8 + file;\n const piece = chess.board[index];\n const white = piece !== null && piece === piece.toUpperCase();\n const glyph = piece ? (!color && white ? OUTLINES[piece] : PIECES[piece]) : ' ';\n let square = cell(line === 1 ? glyph : '');\n if (color) {\n const background = last?.includes(index) ? 107 : (rank + file) % 2 ? 65 : 108;\n square = `\\x1b[1;48;5;${background};38;5;${white ? 231 : 16}m${square}${RESET}`;\n } else if (!piece && line === 1) {\n square = cell((rank + file) % 2 ? '\u00B7' : '');\n }\n row += square;\n }\n output.push(row + green('|'));\n }\n }\n output.push(border);\n output.push(green(' ' + files.map(file => cell('abcdefgh'[file])).join('')));\n output.push(color\n ? ` \\x1b[1;38;5;231m\u265A White${RESET} ${green('\u265A Black \u00B7 dark pieces')}`\n : ' \u2654 White \u265A Black');\n return output.join('\\n') + '\\n';\n}\n", "import { createRequire } from 'node:module';\nimport type { Chess } from '@zchess/chess';\nimport piecesData from '@zchess/chess/pieces' with { type: 'json' };\n\nconst require = createRequire(import.meta.url);\nconst pieces = piecesData as Record<string, string>;\nconst IMAGE_ID = 73191;\nexport type GraphicsMode = 'auto' | 'kitty' | 'text';\n\nexport function supportsGraphics(mode: GraphicsMode, tty = Boolean(process.stdout.isTTY), env = process.env): boolean {\n if (!tty || mode === 'text') return false;\n if (mode === 'kitty') return true;\n if (env.TMUX || env.STY) return false;\n return env.TERM_PROGRAM === 'ghostty' || env.TERM === 'xterm-ghostty' || env.TERM === 'xterm-kitty';\n}\n\nexport function boardSvg(chess: Chess, perspective: 'w' | 'b', last: number[] | null): string {\n const order = perspective === 'w' ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];\n const svg = ['<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"768\" height=\"768\" viewBox=\"0 0 768 768\">',\n '<rect width=\"768\" height=\"768\" rx=\"12\" fill=\"#14291f\"/>'];\n for (const [y, rank] of order.entries()) {\n for (const [x, file] of order.entries()) {\n const index = rank * 8 + file;\n const left = 24 + x * 90, top = 24 + y * 90;\n const fill = last?.includes(index) ? '#b4cf68' : (rank + file) % 2 ? '#64916d' : '#d5e5cb';\n svg.push(`<rect x=\"${left}\" y=\"${top}\" width=\"90\" height=\"90\" fill=\"${fill}\"/>`);\n const piece = chess.board[index];\n if (piece) svg.push(`<g transform=\"translate(${left} ${top}) scale(2)\">${pieces[piece]}</g>`);\n }\n svg.push(`<text x=\"12\" y=\"${24 + y * 90 + 50}\" text-anchor=\"middle\" font-size=\"16\" font-family=\"sans-serif\" fill=\"#d5e5cb\">${8 - rank}</text>`);\n }\n for (const [x, file] of order.entries()) {\n svg.push(`<text x=\"${24 + x * 90 + 45}\" y=\"762\" text-anchor=\"middle\" font-size=\"16\" font-family=\"sans-serif\" fill=\"#d5e5cb\">${'abcdefgh'[file]}</text>`);\n }\n svg.push('</svg>');\n return svg.join('');\n}\n\nexport function boardPng(chess: Chess, perspective: 'w' | 'b', last: number[] | null): Buffer {\n const { Resvg } = require('@resvg/resvg-js') as typeof import('@resvg/resvg-js');\n return new Resvg(boardSvg(chess, perspective, last)).render().asPng();\n}\n\nexport function renderGraphics(chess: Chess, perspective: 'w' | 'b', last: number[] | null, fixed = false): string {\n // The supplied Ghostty screenshot shows that this terminal's cells are a\n // little narrower than the usual 2:1 estimate. Use a 2.2:1 placement so the\n // rendered board squares do not appear tall.\n const columnsPerRow = 2.2;\n const availableRows = Math.max(1, (process.stdout.rows || 40) - (fixed ? 8 : 7));\n const availableColumns = Math.max(2, (process.stdout.columns || 80) - 2);\n const rows = Math.max(1, Math.min(32, availableRows, Math.floor(availableColumns / columnsPerRow)));\n const columns = Math.min(availableColumns, Math.round(rows * columnsPerRow));\n const data = boardPng(chess, perspective, last).toString('base64');\n // Reserve room first: images anchored near the bottom must not cover the prompt.\n let output = `\\x1b_Ga=d,d=I,i=${IMAGE_ID},q=2;\\x1b\\\\`;\n if (!fixed) output += '\\n'.repeat(rows) + `\\x1b[${rows}A\\r`;\n for (let offset = 0; offset < data.length; offset += 4096) {\n const chunk = data.slice(offset, offset + 4096);\n const more = offset + 4096 < data.length ? 1 : 0;\n const control = offset === 0 ? `a=T,f=100,t=d,i=${IMAGE_ID},c=${columns},r=${rows},C=1,q=2,` : '';\n output += `\\x1b_G${control}m=${more};${chunk}\\x1b\\\\`;\n }\n return output + `\\x1b[${rows}B\\r`;\n}\n", "{\n \"b\": \"<g id=\\\"black-bishop\\\" class=\\\"black bishop\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M9 36c3.39-.97 10.11.43 13.5-2 3.39 2.43 10.11 1.03 13.5 2 0 0 1.65.54 3 2-.68.97-1.65.99-3 .5-3.39-.97-10.11.46-13.5-1-3.39 1.46-10.11.03-13.5 1-1.354.49-2.323.47-3-.5 1.354-1.94 3-2 3-2zm6-4c2.5 2.5 12.5 2.5 15 0 .5-1.5 0-2 0-2 0-2.5-2.5-4-2.5-4 5.5-1.5 6-11.5-5-15.5-11 4-10.5 14-5 15.5 0 0-2.5 1.5-2.5 4 0 0-.5.5 0 2zM25 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 1 1 5 0z\\\" fill=\\\"#000\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M17.5 26h10M15 30h15m-7.5-14.5v5M20 18h5\\\" stroke=\\\"#fff\\\" stroke-linejoin=\\\"miter\\\"/></g>\",\n \"k\": \"<g id=\\\"black-king\\\" class=\\\"black king\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M22.5 11.63V6\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5\\\" fill=\\\"#000\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M11.5 37c5.5 3.5 15.5 3.5 21 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-3.5-7.5-13-10.5-16-4-3 6 5 10 5 10V37z\\\" fill=\\\"#000\\\"/><path d=\\\"M20 8h5\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M32 29.5s8.5-4 6.03-9.65C34.15 14 25 18 22.5 24.5l.01 2.1-.01-2.1C20 18 9.906 14 6.997 19.85c-2.497 5.65 4.853 9 4.853 9M11.5 30c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0\\\" stroke=\\\"#fff\\\"/></g>\",\n \"n\": \"<g id=\\\"black-knight\\\" class=\\\"black knight\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/><path d=\\\"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/><path d=\\\"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z\\\" style=\\\"fill:#ececec; stroke:#ececec;\\\"/><path d=\\\"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z\\\" transform=\\\"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)\\\" style=\\\"fill:#ececec; stroke:#ececec;\\\"/><path d=\\\"M 24.55,10.4 L 24.1,11.85 L 24.6,12 C 27.75,13 30.25,14.49 32.5,18.75 C 34.75,23.01 35.75,29.06 35.25,39 L 35.2,39.5 L 37.45,39.5 L 37.5,39 C 38,28.94 36.62,22.15 34.25,17.66 C 31.88,13.17 28.46,11.02 25.06,10.5 L 24.55,10.4 z \\\" style=\\\"fill:#ececec; stroke:none;\\\"/></g>\",\n \"p\": \"<g id=\\\"black-pawn\\\" class=\\\"black pawn\\\"><path d=\\\"M22.5 9c-2.21 0-4 1.79-4 4 0 .89.29 1.71.78 2.38C17.33 16.5 16 18.59 16 21c0 2.03.94 3.84 2.41 5.03-3 1.06-7.41 5.55-7.41 13.47h23c0-7.92-4.41-12.41-7.41-13.47 1.47-1.19 2.41-3 2.41-5.03 0-2.41-1.33-4.5-3.28-5.62.49-.67.78-1.49.78-2.38 0-2.21-1.79-4-4-4z\\\" fill=\\\"#000\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"/></g>\",\n \"q\": \"<g id=\\\"black-queen\\\" class=\\\"black queen\\\" fill=\\\"#000\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><g fill=\\\"#000\\\" stroke=\\\"none\\\"><circle cx=\\\"6\\\" cy=\\\"12\\\" r=\\\"2.75\\\"/><circle cx=\\\"14\\\" cy=\\\"9\\\" r=\\\"2.75\\\"/><circle cx=\\\"22.5\\\" cy=\\\"8\\\" r=\\\"2.75\\\"/><circle cx=\\\"31\\\" cy=\\\"9\\\" r=\\\"2.75\\\"/><circle cx=\\\"39\\\" cy=\\\"12\\\" r=\\\"2.75\\\"/></g><path d=\\\"M9 26c8.5-1.5 21-1.5 27 0l2.5-12.5L31 25l-.3-14.1-5.2 13.6-3-14.5-3 14.5-5.2-13.6L14 25 6.5 13.5 9 26zM9 26c0 2 1.5 2 2.5 4 1 1.5 1 1 .5 3.5-1.5 1-1.5 2.5-1.5 2.5-1.5 1.5.5 2.5.5 2.5 6.5 1 16.5 1 23 0 0 0 1.5-1 0-2.5 0 0 .5-1.5-1-2.5-.5-2.5-.5-2 .5-3.5 1-2 2.5-2 2.5-4-8.5-1.5-18.5-1.5-27 0z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M11 38.5a35 35 1 0 0 23 0\\\" fill=\\\"none\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M11 29a35 35 1 0 1 23 0M12.5 31.5h20M11.5 34.5a35 35 1 0 0 22 0M10.5 37.5a35 35 1 0 0 24 0\\\" fill=\\\"none\\\" stroke=\\\"#fff\\\"/></g>\",\n \"r\": \"<g id=\\\"black-rook\\\" class=\\\"black rook\\\" fill=\\\"#000\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M9 39h27v-3H9v3zM12.5 32l1.5-2.5h17l1.5 2.5h-20zM12 36v-4h21v4H12z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M14 29.5v-13h17v13H14z\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M14 16.5L11 14h23l-3 2.5H14zM11 14V9h4v2h5V9h5v2h5V9h4v5H11z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M12 35.5h21M13 31.5h19M14 29.5h17M14 16.5h17M11 14h23\\\" fill=\\\"none\\\" stroke=\\\"#fff\\\" stroke-width=\\\"1\\\" stroke-linejoin=\\\"miter\\\"/></g>\",\n \"B\": \"<g id=\\\"white-bishop\\\" class=\\\"white bishop\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><g fill=\\\"#fff\\\" stroke-linecap=\\\"butt\\\"><path d=\\\"M9 36c3.39-.97 10.11.43 13.5-2 3.39 2.43 10.11 1.03 13.5 2 0 0 1.65.54 3 2-.68.97-1.65.99-3 .5-3.39-.97-10.11.46-13.5-1-3.39 1.46-10.11.03-13.5 1-1.354.49-2.323.47-3-.5 1.354-1.94 3-2 3-2zM15 32c2.5 2.5 12.5 2.5 15 0 .5-1.5 0-2 0-2 0-2.5-2.5-4-2.5-4 5.5-1.5 6-11.5-5-15.5-11 4-10.5 14-5 15.5 0 0-2.5 1.5-2.5 4 0 0-.5.5 0 2zM25 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 1 1 5 0z\\\"/></g><path d=\\\"M17.5 26h10M15 30h15m-7.5-14.5v5M20 18h5\\\" stroke-linejoin=\\\"miter\\\"/></g>\",\n \"K\": \"<g id=\\\"white-king\\\" class=\\\"white king\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M22.5 11.63V6M20 8h5\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5\\\" fill=\\\"#fff\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M11.5 37c5.5 3.5 15.5 3.5 21 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-3.5-7.5-13-10.5-16-4-3 6 5 10 5 10V37z\\\" fill=\\\"#fff\\\"/><path d=\\\"M11.5 30c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0\\\"/></g>\",\n \"N\": \"<g id=\\\"white-knight\\\" class=\\\"white knight\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18\\\" style=\\\"fill:#ffffff; stroke:#000000;\\\"/><path d=\\\"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10\\\" style=\\\"fill:#ffffff; stroke:#000000;\\\"/><path d=\\\"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/><path d=\\\"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z\\\" transform=\\\"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/></g>\",\n \"P\": \"<g id=\\\"white-pawn\\\" class=\\\"white pawn\\\"><path d=\\\"M22.5 9c-2.21 0-4 1.79-4 4 0 .89.29 1.71.78 2.38C17.33 16.5 16 18.59 16 21c0 2.03.94 3.84 2.41 5.03-3 1.06-7.41 5.55-7.41 13.47h23c0-7.92-4.41-12.41-7.41-13.47 1.47-1.19 2.41-3 2.41-5.03 0-2.41-1.33-4.5-3.28-5.62.49-.67.78-1.49.78-2.38 0-2.21-1.79-4-4-4z\\\" fill=\\\"#fff\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"/></g>\",\n \"Q\": \"<g id=\\\"white-queen\\\" class=\\\"white queen\\\" fill=\\\"#fff\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M8 12a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM24.5 7.5a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM41 12a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM16 8.5a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM33 9a2 2 0 1 1-4 0 2 2 0 1 1 4 0z\\\"/><path d=\\\"M9 26c8.5-1.5 21-1.5 27 0l2-12-7 11V11l-5.5 13.5-3-15-3 15-5.5-14V25L7 14l2 12zM9 26c0 2 1.5 2 2.5 4 1 1.5 1 1 .5 3.5-1.5 1-1.5 2.5-1.5 2.5-1.5 1.5.5 2.5.5 2.5 6.5 1 16.5 1 23 0 0 0 1.5-1 0-2.5 0 0 .5-1.5-1-2.5-.5-2.5-.5-2 .5-3.5 1-2 2.5-2 2.5-4-8.5-1.5-18.5-1.5-27 0z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M11.5 30c3.5-1 18.5-1 22 0M12 33.5c6-1 15-1 21 0\\\" fill=\\\"none\\\"/></g>\",\n \"R\": \"<g id=\\\"white-rook\\\" class=\\\"white rook\\\" fill=\\\"#fff\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M9 39h27v-3H9v3zM12 36v-4h21v4H12zM11 14V9h4v2h5V9h5v2h5V9h4v5\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M34 14l-3 3H14l-3-3\\\"/><path d=\\\"M31 17v12.5H14V17\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M31 29.5l1.5 2.5h-20l1.5-2.5\\\"/><path d=\\\"M11 14h23\\\" fill=\\\"none\\\" stroke-linejoin=\\\"miter\\\"/></g>\"\n}\n", "import { spawn } from 'node:child_process';\nimport { createRequire } from 'node:module';\nimport { createInterface } from 'node:readline';\nimport { Chess } from '@zchess/chess';\n\nconst require = createRequire(import.meta.url);\nconst stockfish = require('stockfish') as { findEngine(flavor: string): string };\n\n/** Run the bundled engine in a separate process so search never blocks the CLI. */\nexport async function engineMove(fen: string, elo: number, depth: number, signal?: AbortSignal): Promise<string> {\n if (!Number.isInteger(elo) || elo < 1320 || elo > 3190) throw new Error('ELO must be an integer from 1320 to 3190.');\n if (!Number.isInteger(depth) || depth < 1 || depth > 30) throw new Error('Depth must be an integer from 1 to 30.');\n signal?.throwIfAborted();\n const position = new Chess(fen);\n if (position.status()) throw new Error('The game is over.');\n\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, [stockfish.findEngine('single')], { stdio: ['pipe', 'pipe', 'ignore'] });\n const lines = createInterface({ input: child.stdout });\n let settled = false;\n const finish = (error?: Error, move?: string): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n signal?.removeEventListener('abort', cancel);\n lines.close();\n child.kill();\n if (error) reject(error);\n else resolve(move!);\n };\n const timer = setTimeout(() => finish(new Error('Stockfish timed out. Try a lower --depth.')), 60_000);\n const cancel = (): void => finish(new Error('Stockfish search cancelled.'));\n signal?.addEventListener('abort', cancel, { once: true });\n child.on('error', error => finish(new Error(`Could not start bundled Stockfish: ${error.message}`)));\n child.stdin.on('error', error => finish(error));\n child.on('exit', () => finish(new Error('Stockfish exited before returning a move.')));\n lines.on('line', line => {\n if (line === 'uciok') {\n child.stdin.write(`setoption name UCI_LimitStrength value true\\nsetoption name UCI_Elo value ${elo}\\nisready\\n`);\n } else if (line === 'readyok') {\n child.stdin.write(`position fen ${fen}\\ngo depth ${depth}\\n`);\n } else if (line.startsWith('bestmove ')) {\n const move = line.split(/\\s+/)[1];\n try {\n position.play(move);\n finish(undefined, move);\n } catch {\n finish(new Error('Stockfish returned an invalid move.'));\n }\n }\n });\n child.stdin.write('uci\\n');\n });\n}\n", "import { stdout } from 'node:process';\n\ninterface Output {\n columns?: number;\n rows?: number;\n write(text: string): unknown;\n}\n\n/** Keep game frames out of shell scrollback and restore the shell on exit. */\nexport class GameScreen {\n private opened = false;\n private cursorStyled = false;\n constructor(readonly active: boolean, private readonly output: Output = stdout, private readonly manageScreen = true) {}\n\n open(): void {\n if (this.active && this.manageScreen && !this.opened) {\n this.output.write('\\x1b[?1049h');\n this.opened = true;\n }\n }\n\n draw(header: string, board: string, status: string, moves = ''): void {\n if (!this.active) {\n this.output.write(`${header}\\n${moves}\\n\\n${board}\\n${status}\\n`);\n return;\n }\n const width = Math.max(1, (this.output.columns || 80) - 1);\n const fit = (text: string): string => [...text.replace(/[\\x00-\\x1f\\x7f]/g, ' ')].slice(0, width).join('');\n // Synchronized output prevents a visible blank frame between positions.\n const title = `\\x1b[38;2;224;242;215m${fit(header).padEnd(width)}\\x1b[0m`;\n const history = `\\x1b[38;2;190;221;173m${fit(moves).padEnd(width)}\\x1b[0m`;\n const horizontalPadding = Math.min(1, Math.floor((width - 1) / 2));\n const innerWidth = Math.max(1, width - horizontalPadding * 2);\n const controls = '/help';\n const visibleControls = controls.slice(-Math.min(innerWidth, controls.length));\n const statusWidth = Math.max(0, innerWidth - visibleControls.length);\n const footer = `\\x1b[38;2;224;242;215m${' '.repeat(horizontalPadding)}${fit(status).slice(0, statusWidth).padEnd(statusWidth)}${visibleControls}${' '.repeat(horizontalPadding + 1)}\\x1b[0m`;\n const bottom = Math.max(6, this.output.rows || 40);\n this.output.write('\\x1b[?2026h\\x1b[H\\x1b[2J' +\n `${title}\\r\\n${history}\\r\\n\\r\\n${board}\\x1b[${bottom - 4};1H${footer}` +\n this.inputFrame('', 'Type any moves e.g. e4 or e pawn up 2') + '\\x1b[?2026l');\n }\n\n input(value: string, placeholder = 'Type any moves e.g. e4 or e pawn up 2'): void {\n if (this.active) this.output.write(this.inputFrame(value, placeholder));\n }\n\n private inputFrame(value: string, placeholder: string): string {\n const width = Math.max(1, (this.output.columns || 80) - 1);\n const bottom = Math.max(6, this.output.rows || 40);\n const visible = [...value].slice(-Math.max(0, width - 4)).join('');\n const foreground = value ? '\\x1b[38;2;235;248;226m' : '\\x1b[38;2;139;168;144m';\n const horizontalPadding = 1;\n const fieldTextWidth = Math.max(0, width - horizontalPadding - 2);\n const shown = value\n ? [...visible].slice(-fieldTextWidth).join('')\n : [...placeholder].slice(0, Math.max(0, fieldTextWidth - 1)).join('');\n const prefix = ' ';\n const displayed = value ? shown : ` ${shown}`;\n const background = '\\x1b[48;2;12;42;34m';\n const paddingRow = `${background}${' '.repeat(width + 1)}\\x1b[0m`;\n const row = `${background}\\x1b[38;2;190;221;173m${prefix}${foreground}${displayed}${' '.repeat(Math.max(0, width + 1 - prefix.length - [...displayed].length))}\\x1b[0m`;\n const cursor = value ? Math.min(width, prefix.length + [...shown].length + 1) : 2;\n this.cursorStyled = true;\n return `\\x1b[${bottom - 2};1H${paddingRow}` +\n `\\x1b[${bottom - 1};1H${row}` +\n `\\x1b[${bottom};1H${paddingRow}\\x1b[${bottom - 1};${cursor}H\\x1b[5 q\\x1b[?25h`;\n }\n\n close(): void {\n if (this.cursorStyled) {\n this.output.write('\\x1b[0 q');\n this.cursorStyled = false;\n }\n if (this.opened) {\n this.output.write('\\x1b[?2026l\\x1b[?25h\\x1b[?1049l');\n this.opened = false;\n }\n }\n}\n\n/** Full-screen start and load menus that replace one another without scrollback. */\nexport class MenuScreen {\n private opened = false;\n constructor(readonly active: boolean, private readonly output: Output = stdout) {}\n\n open(): void {\n if (this.active && !this.opened) {\n this.output.write('\\x1b[?1049h\\x1b[?25l');\n this.opened = true;\n }\n }\n\n draw(header: string, content: string, footer: string): void {\n const width = Math.max(1, (this.output.columns || 80) - 1);\n const fit = (text: string): string => [...text.replace(/[\\x00-\\x1f\\x7f]/g, ' ')].slice(0, width).join('');\n if (!this.active) {\n this.output.write(`${header}\\n${content}\\n${footer}\\n`);\n return;\n }\n const title = `\\x1b[38;2;224;242;215m${fit(header).padEnd(width)}\\x1b[0m`;\n const horizontalPadding = Math.min(2, Math.floor((width - 1) / 2));\n const status = `\\x1b[38;2;210;225;202m${' '.repeat(horizontalPadding)}${fit(footer).slice(0, width - horizontalPadding * 2).padEnd(width - horizontalPadding * 2)}${' '.repeat(horizontalPadding)}\\x1b[0m`;\n const body = content.split('\\n').map(line => fit(line)).join('\\r\\n');\n this.output.write(`\\x1b[?25l\\x1b[?2026h\\x1b[H\\x1b[2J${title}\\r\\n\\r\\n${body}\\r\\n\\r\\n${status}\\r\\n\\x1b[?2026l`);\n }\n\n close(): void {\n if (this.opened) {\n this.output.write('\\x1b[?25h\\x1b[?1049l');\n this.opened = false;\n }\n }\n}\n", "import { DatabaseSync } from 'node:sqlite';\nimport { mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport interface SavedGame {\n id: number;\n createdAt: string;\n updatedAt: string;\n elo: number;\n color: 'w' | 'b';\n startFen: string;\n fen: string;\n moves: string[];\n status: string;\n}\n\nexport class GameStore {\n private readonly db: DatabaseSync;\n\n constructor(path = process.env.ZCHESS_DB_PATH || join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), 'zchess', 'games.sqlite')) {\n mkdirSync(dirname(path), { recursive: true });\n this.db = new DatabaseSync(path);\n this.db.exec(`\n PRAGMA journal_mode = WAL;\n CREATE TABLE IF NOT EXISTS games (\n id INTEGER PRIMARY KEY,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n elo INTEGER NOT NULL,\n color TEXT NOT NULL CHECK (color IN ('w', 'b')),\n start_fen TEXT NOT NULL,\n fen TEXT NOT NULL,\n moves TEXT NOT NULL,\n status TEXT NOT NULL\n );\n `);\n }\n\n save(game: Omit<SavedGame, 'id' | 'createdAt' | 'updatedAt'>, id?: number): number {\n const now = new Date().toISOString();\n if (id === undefined) {\n const result = this.db.prepare(`INSERT INTO games (created_at, updated_at, elo, color, start_fen, fen, moves, status)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(now, now, game.elo, game.color, game.startFen, game.fen, JSON.stringify(game.moves), game.status);\n return Number(result.lastInsertRowid);\n }\n this.db.prepare(`UPDATE games SET updated_at = ?, elo = ?, color = ?, start_fen = ?, fen = ?, moves = ?, status = ? WHERE id = ?`)\n .run(now, game.elo, game.color, game.startFen, game.fen, JSON.stringify(game.moves), game.status, id);\n return id;\n }\n\n list(): SavedGame[] {\n const rows = this.db.prepare('SELECT * FROM games ORDER BY updated_at DESC').all() as Array<Record<string, unknown>>;\n return rows.map(row => this.decode(row));\n }\n\n get(id: number): SavedGame | undefined {\n const row = this.db.prepare('SELECT * FROM games WHERE id = ?').get(id) as Record<string, unknown> | undefined;\n return row ? this.decode(row) : undefined;\n }\n\n close(): void { this.db.close(); }\n\n private decode(row: Record<string, unknown>): SavedGame {\n return {\n id: Number(row.id), createdAt: String(row.created_at), updatedAt: String(row.updated_at),\n elo: Number(row.elo), color: row.color === 'b' ? 'b' : 'w', startFen: String(row.start_fen), fen: String(row.fen),\n moves: JSON.parse(String(row.moves)) as string[], status: String(row.status),\n };\n }\n}\n"],
5
- "mappings": "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",
6
- "names": ["createInterface", "stdout", "message", "move", "names", "body", "color", "require", "createRequire", "require", "createRequire", "stdout", "createInterface", "game", "elo", "listener"]
3
+ "sources": ["../src/update.ts", "../src/cli.ts", "../../../packages/chess/src/index.ts", "../../../packages/chess/src/resolution.ts", "../../../packages/chess/src/legality.ts", "../../../packages/chess/src/suggestions.ts", "../../../packages/chess/src/input.ts", "../../../packages/chess/src/history.ts", "../src/api.ts", "../src/ui.ts", "../src/graphics.ts", "../../../packages/chess/assets/pieces.json", "../src/terminal.ts", "../src/engine.ts", "../src/screen.ts", "../src/store.ts"],
4
+ "sourcesContent": ["export interface UpdateNotice { version: string; command: string }\n\ninterface Version { core: bigint[]; prerelease: string[] }\nfunction parseVersion(value: unknown): Version | undefined {\n if (typeof value !== 'string') return;\n const match = /^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(?:-([\\da-zA-Z-]+(?:\\.[\\da-zA-Z-]+)*))?(?:\\+[\\da-zA-Z-]+(?:\\.[\\da-zA-Z-]+)*)?$/.exec(value);\n if (!match) return;\n const prerelease = match[4]?.split('.') || [];\n if (prerelease.some(part => /^0\\d+$/.test(part))) return;\n return { core: match.slice(1, 4).map(BigInt), prerelease };\n}\n\nexport function isNewerVersion(candidate: string, installed: string): boolean {\n const a = parseVersion(candidate), b = parseVersion(installed);\n if (!a || !b) return false;\n for (let i = 0; i < 3; i++) if (a.core[i] !== b.core[i]) return a.core[i] > b.core[i];\n if (!a.prerelease.length || !b.prerelease.length) return a.prerelease.length === 0 && b.prerelease.length > 0;\n for (let i = 0; i < Math.max(a.prerelease.length, b.prerelease.length); i++) {\n const x = a.prerelease[i], y = b.prerelease[i];\n if (x === undefined || y === undefined) return x !== undefined;\n if (x === y) continue;\n const xn = /^\\d+$/.test(x), yn = /^\\d+$/.test(y);\n if (xn && yn) return BigInt(x) > BigInt(y);\n if (xn !== yn) return !xn;\n return x > y;\n }\n return false;\n}\n\n/** An optional startup hint: network or registry problems must never prevent play. */\nexport async function checkForUpdate(installed: string, options: {\n fetch?: typeof fetch;\n timeoutMs?: number;\n homebrew?: boolean;\n} = {}): Promise<UpdateNotice | undefined> {\n const current = parseVersion(installed);\n if (!current) return;\n const controller = new AbortController();\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n const lookup = async (): Promise<UpdateNotice | undefined> => {\n const response = await (options.fetch || fetch)('https://registry.npmjs.org/-/package/zchess/dist-tags', { signal: controller.signal });\n if (!response.ok) return;\n const tags = await response.json() as Record<string, unknown> | null;\n if (!tags || typeof tags !== 'object') return;\n const candidates = [tags.latest];\n if (current.prerelease.length && !options.homebrew) candidates.push(tags[current.prerelease[0]]);\n let version = installed;\n for (const candidate of candidates) {\n if (typeof candidate === 'string' && isNewerVersion(candidate, version)) version = candidate;\n }\n if (version === installed) return;\n return { version, command: options.homebrew\n ? `brew reinstall --formula \\\\\n https://github.com/kennylwx/zchess/releases/latest/download/zchess.rb`\n : `npm install --global zchess@${version}` };\n };\n const timeout = new Promise<undefined>(resolve => {\n timer = setTimeout(() => { controller.abort(); resolve(undefined); }, options.timeoutMs ?? 800);\n });\n return await Promise.race([lookup(), timeout]);\n } catch { return; }\n finally { if (timer) clearTimeout(timer); }\n}\n", "import { checkForUpdate, type UpdateNotice } from './update.js';\nimport { createInterface } from 'node:readline/promises';\nimport { stdin, stdout } from 'node:process';\nimport { Chess, START_FEN } from '@zchess/chess';\nimport { modelInput } from './input.js';\nimport { ChessServerClient } from './api.js';\nimport { render } from './ui.js';\nimport { clearGraphics, renderGraphics, type GraphicsMode } from './graphics.js';\nimport { detectGraphics } from './terminal.js';\nimport { engineMove } from './engine.js';\nimport { GameScreen, MenuScreen } from './screen.js';\nimport { moveHistory, undoTurn } from './history.js';\nimport { GameStore, type SavedGame } from './store.js';\nimport type { Key } from 'node:readline';\n\nconst HELP = `chess \u2014 terminal chess\n\nUsage: chess [--elo 1500] [--color white|black] [--fen FEN]\n [--server URL] [--depth 12] [--graphics auto|kitty|text|ascii]\n\nRun \"chess\" with no options to open the Play / Load game menu.\nMoves accept UCI (e2e4), SAN (Nf3), or free text (\"move the queen up by 1\").\nStockfish is included and runs locally. Only free text requires the Chess server.\nGames are saved automatically in ~/.local/share/zchess/games.sqlite.\nCommands: /fen, /fen <position>, /undo, /help, /back, /quit`;\n\nexport function commandHelp(): string {\n return [\n 'COMMANDS',\n '/help Show this list',\n '/undo Take back a turn',\n '/fen Show the current position',\n '/fen <FEN> Load a position',\n '/back Return to the previous screen',\n '/quit Quit Chess',\n '',\n 'SHORTCUTS',\n 'Ctrl+C Quit',\n 'Ctrl+U Clear input',\n ].join('\\n');\n}\n\nexport function editGameInput(value: string, text: string, key: Key): string {\n if ((key?.ctrl && key.name === 'u') || (key?.meta && key.name === 'backspace')) return '';\n if (key?.name === 'backspace') return [...value].slice(0, -1).join('');\n if (!key?.ctrl && !key?.meta && text && !/[\\x00-\\x1f\\x7f]/.test(text)) return value + text;\n return value;\n}\n\nconst promptColor = '\\x1b[39m';\nconst reset = '\\x1b[0m';\nconst ELO_PRESETS = [\n { label: 'Beginner', elo: 1320 },\n { label: 'Intermediate', elo: 1500 },\n { label: 'Advanced', elo: 1800 },\n { label: 'Expert', elo: 2200 },\n { label: 'Master', elo: 3190 },\n];\ninterface GameConfig { elo: number; human: 'w' | 'b'; saved?: SavedGame; fen?: string }\n\nexport async function run(args: string[], installation?: { version: string; homebrew?: boolean }): Promise<void> {\n if (args.includes('--help') || args.includes('-h')) { console.log(HELP); return; }\n const get = (name: string, fallback: string | undefined): string | undefined => {\n const index = args.indexOf(name);\n return index < 0 ? fallback : (args[index + 1] ?? fallback);\n };\n const graphics = get('--graphics', 'auto') as GraphicsMode;\n if (!['auto', 'kitty', 'text', 'ascii'].includes(graphics)) throw new Error('Graphics must be auto, kitty, text, or ascii.');\n const depth = Number(get('--depth', '12'));\n if (!Number.isInteger(depth) || depth < 1 || depth > 30) throw new Error('Depth must be an integer from 1 to 30.');\n let cellAspect = 2;\n const useGraphics = await detectGraphics(graphics, stdin, stdout, process.env, 300, ratio => { cellAspect = ratio; });\n\n const update = installation && stdin.isTTY && stdout.isTTY && process.env.ZCHESS_NO_UPDATE_CHECK !== '1'\n ? await checkForUpdate(installation.version, { homebrew: installation.homebrew }) : undefined;\n const store = new GameStore(get('--db', undefined));\n const direct = args.some(arg => arg.startsWith('--'));\n const interactiveMenu = !direct && stdin.isTTY && stdout.isTTY;\n const menuScreen = interactiveMenu ? new MenuScreen(true) : undefined;\n menuScreen?.open();\n if (update && !interactiveMenu) console.log(`Update available: ${installation!.version} \u2192 ${update.version}\\nRun: ${update.command}`);\n\n try {\n let keepGoing = true;\n let returnToSavedGames = false;\n while (keepGoing) {\n let config: GameConfig | undefined;\n if (direct || !stdin.isTTY || !stdout.isTTY) {\n const elo = Number(get('--elo', '1500'));\n if (!Number.isInteger(elo) || elo < 1320 || elo > 3190) throw new Error('ELO must be an integer from 1320 to 3190 (Stockfish UCI range).');\n config = { elo, human: get('--color', 'white')!.toLowerCase().startsWith('b') ? 'b' : 'w', fen: get('--fen', undefined) };\n keepGoing = false;\n } else {\n const choice = await mainMenu(store, menuScreen!, returnToSavedGames, update, installation?.version);\n returnToSavedGames = false;\n if (choice === 'quit') break;\n config = choice;\n }\n if (config) {\n const again = await playGame(config, { useGraphics, ascii: graphics === 'ascii', cellAspect, depth, serverUrl: get('--server', process.env.ZCHESS_SERVER_URL || 'http://localhost:8000')!, store, sharedScreen: interactiveMenu });\n if (again && config.saved) returnToSavedGames = true;\n if (direct || !again) keepGoing = false;\n }\n }\n } finally { menuScreen?.close(); store.close(); }\n}\n\nasync function mainMenu(store: GameStore, screen: MenuScreen, openSavedGames = false, update?: UpdateNotice, installed?: string): Promise<GameConfig | 'quit'> {\n const rl = createInterface({ input: stdin, output: stdout });\n try {\n while (true) {\n if (openSavedGames) {\n openSavedGames = false;\n const game = await savedGamesMenu(store, screen);\n if (game === 'quit') return 'quit';\n if (game) return game;\n continue;\n }\n const notice = update ? `\\n\\nUpdate available: ${installed} \u2192 ${update.version}\\nRun: ${update.command}` : '';\n screen.draw('ZCHESS / LOCAL STOCKFISH', ' 1 Play\\n 2 Load a saved game\\n 3 Quit' + notice, '');\n const choice = await menuKey('Select \u203A ', ['1', '2', '3']);\n if (choice === 'q') return 'quit';\n if (choice === 'b') continue;\n if (choice === '3') return 'quit';\n if (choice === '1') {\n const game = await newGameMenu(screen);\n if (game === 'quit') return 'quit';\n if (game) return game;\n }\n if (choice === '2' || choice === 'load') {\n const game = await savedGamesMenu(store, screen);\n if (game === 'quit') return 'quit';\n if (game) return game;\n }\n }\n } finally { rl.close(); }\n}\n\nasync function savedGamesMenu(store: GameStore, screen: MenuScreen): Promise<GameConfig | 'quit' | null> {\n const games = store.list();\n if (!games.length) {\n screen.draw('LOAD A SAVED GAME', 'No saved games yet.\\n\\n 1 Back\\n 2 Quit', '');\n const action = await menuKey('Select \u203A ', ['1', '2']);\n return action === '2' || action === 'q' ? 'quit' : null;\n }\n const recent = games.slice(0, 7);\n const lines = recent.map((game, index) => ` ${index + 1} ${game.updatedAt.slice(0, 16).replace('T', ' ')} \u00B7 ${game.elo} ELO \u00B7 ${game.moves.length ? game.moves.join(' ') : 'New game'} \u00B7 ${game.status}`);\n if (games.length > recent.length) lines.push(' Showing the 7 most recent games.');\n const backChoice = recent.length + 1;\n const quitChoice = recent.length + 2;\n lines.push(` ${backChoice} Back`, ` ${quitChoice} Quit`);\n screen.draw('LOAD A SAVED GAME', lines.join('\\n'), '');\n const selection = await menuKey('Choose a game \u203A ', Array.from({ length: quitChoice }, (_, index) => String(index + 1)));\n if (selection === 'q') return 'quit';\n if (Number(selection) === backChoice) return null;\n if (Number(selection) === quitChoice) return 'quit';\n const game = recent[Number(selection) - 1];\n return game ? { elo: game.elo, human: game.color, saved: game } : null;\n}\n\nasync function newGameMenu(screen: MenuScreen): Promise<GameConfig | null | 'quit'> {\n const choices = ELO_PRESETS.map(({ label, elo }, index) => ` ${index + 1} ${label} \u00B7 ${elo} ELO`);\n choices.push(' 6 Custom ELO');\n choices.push(' 7 Back', ' 8 Quit');\n screen.draw('NEW GAME / STOCKFISH STRENGTH', `${choices.join('\\n')}\\n\\nAvailable range: 1320\u20133190 ELO`, '');\n const selection = await menuKey('ELO \u203A ', ['1', '2', '3', '4', '5', '6', '7', '8']);\n if (selection === 'q') return 'quit';\n if (selection === '7') return null;\n if (selection === '8') return 'quit';\n let elo = ELO_PRESETS[Number(selection) - 1]?.elo;\n if (selection === '6') {\n let custom: number;\n while (true) {\n screen.draw('NEW GAME / CUSTOM ELO', 'Enter any ELO from 1320 to 3190.\\n\\n 0 Back\\n 00 Quit', '');\n const value = await menuText('ELO \u203A ');\n if (value === 'q') return 'quit';\n if (value === 'b' || value === null) return await newGameMenu(screen);\n custom = Number(value);\n if (Number.isInteger(custom) && custom >= 1320 && custom <= 3190) break;\n screen.draw('NEW GAME / CUSTOM ELO', 'Enter an ELO from 1320 to 3190.\\nThat value is outside the range.\\n\\n 0 Back\\n 00 Quit', '');\n }\n elo = custom;\n }\n if (elo === undefined) return null;\n while (true) {\n screen.draw('NEW GAME / CHOOSE SIDE', `Stockfish ${elo} ELO\\n\\n 1 White\\n 2 Black\\n 3 Random\\n 4 Back\\n 5 Quit`, '');\n const side = await menuKey('Side \u203A ', ['1', '2', '3', '4', '5']);\n if (side === 'q') return 'quit';\n if (side === '4') return await newGameMenu(screen);\n if (side === '5') return 'quit';\n const human: 'w' | 'b' = side === '1' ? 'w' : side === '2' ? 'b' : Math.random() < 0.5 ? 'w' : 'b';\n return { elo, human };\n }\n}\n\nfunction menuKey(prompt: string, choices: string[]): Promise<string> {\n return rawPrompt(prompt, (text, key, finish) => {\n if (key?.ctrl && key.name === 'c') { finish('q'); return; }\n const character = (text ?? '').toLowerCase();\n if (!key?.ctrl && choices.includes(character)) finish(character);\n });\n}\n\nfunction menuText(prompt: string): Promise<string | 'b' | 'q' | null> {\n let value = '';\n return rawPrompt(prompt, (text, key, finish) => {\n if (key?.ctrl && key.name === 'c') { finish('q'); return; }\n if (key?.name === 'backspace') {\n value = value.slice(0, -1);\n stdout.write('\\b \\b');\n return;\n }\n if (key?.name === 'return' || key?.name === 'enter') {\n finish(value === '0' ? 'b' : value === '00' ? 'q' : value);\n return;\n }\n const character = text ?? '';\n if (key?.ctrl || !character) return;\n value += character;\n stdout.write(character);\n });\n}\n\nfunction rawPrompt<T>(prompt: string, onKey: (text: string, key: Key, finish: (value: T) => void) => void): Promise<T> {\n const stream = stdin as typeof stdin & { setRawMode?: (mode: boolean) => void };\n if (!stream.isTTY || !stream.setRawMode) return Promise.reject(new Error('Menu selection requires an interactive terminal.'));\n const previous = stdin.listeners('keypress') as Array<(...args: any[]) => void>;\n previous.forEach(listener => stdin.removeListener('keypress', listener));\n stdout.write(`${promptColor}${prompt}${reset}`);\n stream.setRawMode(true);\n return new Promise(resolve => {\n let finished = false;\n const finish = (value: T): void => {\n if (finished) return;\n finished = true;\n stdin.removeListener('keypress', listener);\n stream.setRawMode(false);\n [...previous].reverse().forEach(listener => stdin.prependListener('keypress', listener));\n stdout.write('\\r\\n');\n resolve(value);\n };\n const listener = (text: string, key: Key): void => onKey(text, key, finish);\n stdin.on('keypress', listener);\n });\n}\n\nasync function playGame(config: GameConfig, options: { useGraphics: boolean; ascii: boolean; cellAspect: number; depth: number; serverUrl: string; store: GameStore; sharedScreen: boolean }): Promise<boolean> {\n const { elo, human, saved } = config;\n let startFen = saved?.startFen ?? config.fen ?? START_FEN;\n const chess = new Chess(startFen);\n if (saved) for (const move of saved.moves) chess.play(move);\n const abort = new AbortController();\n const server = new ChessServerClient(options.serverUrl, abort.signal);\n const rl = createInterface({ input: stdin, output: stdout });\n const screen = new GameScreen(Boolean(stdout.isTTY && stdin.isTTY), stdout, !options.sharedScreen);\n let useGraphics = options.useGraphics;\n let stopped = false;\n let redrawInput: (() => void) | undefined;\n let last: number[] | null = null;\n let showingHelp = false;\n let returnToMenu = false;\n let returnToMenuRequested = false;\n let search: AbortController | undefined;\n let notice = 'Your move';\n let gameId = saved?.id;\n const header = `CHESS / ${human === 'w' ? 'White' : 'Black'} / Stockfish ${elo} ELO`;\n const persist = (): void => {\n gameId = options.store.save({ elo, color: human, startFen, fen: chess.fen(), moves: chess.history.map(entry => entry.san), status: chess.status() ?? 'In progress' }, gameId);\n };\n const draw = (): void => {\n let board: string;\n if (showingHelp) board = (useGraphics ? clearGraphics() : '') + commandHelp();\n else {\n try { board = useGraphics ? renderGraphics(chess, human, last, screen.active, options.cellAspect) : ''; }\n catch {\n // A missing native rasterizer must not prevent playing a text game.\n stdout.write(clearGraphics());\n useGraphics = false;\n board = '';\n }\n if (!useGraphics) board = render(chess, { ascii: options.ascii, perspective: human, last, compact: screen.active && (stdout.rows || 40) < 36 });\n }\n screen.draw(header, board, notice, showingHelp ? '' : moveHistory(chess, Math.max(1, (stdout.columns || 80) - 1)));\n };\n const takeBack = (): void => {\n notice = undoTurn(chess, human) ? 'Took back your last move and any Stockfish reply.' : 'No move to undo yet.';\n const move = chess.history.at(-1)?.move;\n last = move ? [move.from, move.to] : null;\n persist();\n };\n const shortcut = (text: string, key: Key): void => {\n if (stopped || returnToMenuRequested) return;\n if (key?.ctrl && key.name === 'c') { stop(); return; }\n };\n const stop = (): void => { stopped = true; abort.abort(); search?.abort(); };\n let resizeTask: Promise<void> | undefined;\n const resize = (): void => {\n if (stopped || resizeTask) return;\n resizeTask = (async () => {\n try {\n if (useGraphics) await detectGraphics('kitty', stdin, stdout, process.env, 300, ratio => { options.cellAspect = ratio; });\n if (!stopped) { draw(); redrawInput?.(); }\n } catch { /* Keep the previous geometry if the terminal stops responding. */ }\n })().finally(() => { resizeTask = undefined; });\n };\n const question = async (placeholder: string): Promise<string> => {\n if (!screen.active) return await rl.question(`${promptColor}${placeholder} \u203A ${reset}`, { signal: abort.signal });\n const stream = stdin as typeof stdin & { setRawMode?: (mode: boolean) => void };\n const previousRaw = stream.isRaw;\n const previous = stdin.listeners('keypress') as Array<(text: string, key: Key) => void>;\n previous.forEach(listener => stdin.removeListener('keypress', listener));\n stream.setRawMode?.(true);\n return new Promise(resolve => {\n let value = '';\n let done = false;\n const redraw = (): void => screen.input(value, placeholder);\n const finish = (answer: string): void => {\n if (done) return;\n done = true;\n stdin.removeListener('keypress', onKey);\n abort.signal.removeEventListener('abort', onAbort);\n previous.forEach(listener => stdin.on('keypress', listener));\n stream.setRawMode?.(previousRaw);\n redrawInput = undefined;\n screen.input('', placeholder);\n resolve(answer);\n };\n const onAbort = (): void => finish('');\n const onKey = (text: string, key: Key): void => {\n if (key?.ctrl && key.name === 'c') { stop(); finish(''); return; }\n if (key?.name === 'return' || key?.name === 'enter') { finish(value); return; }\n value = editGameInput(value, text, key);\n redraw();\n };\n redrawInput = redraw;\n stdin.on('keypress', onKey);\n abort.signal.addEventListener('abort', onAbort, { once: true });\n redraw();\n });\n };\n stdin.on('keypress', shortcut);\n rl.on('SIGINT', stop);\n rl.on('close', stop);\n process.on('SIGINT', stop);\n process.on('SIGTERM', stop);\n stdout.on('resize', resize);\n screen.open();\n persist();\n\n try {\n while (!stopped && !returnToMenuRequested) {\n const status = chess.status();\n if (status) {\n notice = status;\n persist();\n draw();\n if (screen.active) {\n const command = await question('Type /undo, /back, or /quit \u00B7 Ctrl+C quit');\n if (command.trim().toLowerCase() === '/undo') { takeBack(); continue; }\n if (/^\\/(quit|exit)$/.test(command.trim().toLowerCase())) { stop(); break; }\n break;\n }\n console.log(status);\n break;\n }\n if (chess.turn !== human) {\n notice = 'Stockfish is thinking\u2026';\n draw();\n search = new AbortController();\n let move: string;\n try { move = await engineMove(chess.fen(), elo, options.depth, search.signal); }\n catch (error) {\n if (returnToMenuRequested) break;\n throw error;\n } finally { search = undefined; }\n const side = chess.turn;\n const san = chess.play(move);\n const played = chess.history.at(-1)!.move;\n last = [played.from, played.to];\n notice = `${side === 'w' ? 'White' : 'Black'} plays ${san}`;\n persist();\n continue;\n }\n\n draw();\n let raw: string;\n try { raw = await question(showingHelp ? 'Type /back to return to the game' : 'Type any moves e.g. e4 or e pawn up 2'); }\n catch (error) { if (returnToMenuRequested) break; throw error; }\n const wasShowingHelp = showingHelp;\n showingHelp = false;\n if (wasShowingHelp && /^\\/back$/i.test(raw.trim())) { notice = 'Your move'; continue; }\n let intent;\n try { intent = await modelInput(raw, chess, server); }\n catch (error) { notice = message(error); continue; }\n if (stopped) break;\n if (intent.type === 'quit') { stop(); break; }\n if (intent.type === 'help') { notice = 'Available commands'; showingHelp = true; continue; }\n if (intent.type === 'back') { returnToMenuRequested = true; break; }\n if (intent.type === 'show-fen') { notice = chess.fen(); continue; }\n if (intent.type === 'load-fen') {\n try { chess.load(intent.value); startFen = intent.value; last = null; notice = 'Position loaded.'; persist(); }\n catch (error) { notice = message(error); }\n continue;\n }\n if (intent.type === 'undo') { takeBack(); continue; }\n if (intent.type === 'empty') continue;\n try {\n const san = chess.play(intent.value);\n const move = chess.history.at(-1)!.move;\n last = [move.from, move.to];\n notice = intent.source === 'jev' ? `JEV chose ${san}` : `You played ${san}`;\n persist();\n } catch (error) { notice = `${message(error)}. Try e2e4, Nf3, or describe the move.`; }\n }\n } catch (error) { if (!stopped) throw error; }\n finally {\n await resizeTask;\n returnToMenu = screen.active && !stopped;\n stdin.off('keypress', shortcut);\n stdout.off('resize', resize);\n process.off('SIGINT', stop);\n process.off('SIGTERM', stop);\n rl.close();\n if (useGraphics) stdout.write(clearGraphics());\n screen.close();\n }\n return returnToMenu || screen.active && returnToMenuRequested;\n}\n\nexport { HELP };\nconst message = (error: unknown): string => error instanceof Error ? error.message : String(error);\n", "export const START_FEN = 'rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1';\nconst FILES = 'abcdefgh';\nconst KNIGHT: Direction[] = [[1,2],[2,1],[2,-1],[1,-2],[-1,-2],[-2,-1],[-2,1],[-1,2]];\nconst KING: Direction[] = [[1,0],[-1,0],[0,1],[0,-1],[1,1],[1,-1],[-1,1],[-1,-1]];\ntype Side = 'w' | 'b';\ntype Piece = 'P'|'N'|'B'|'R'|'Q'|'K'|'p'|'n'|'b'|'r'|'q'|'k';\ntype Direction = [number, number];\nexport interface Move { from:number; to:number; promotion:string|null; flags:string }\nexport interface PositionSnapshot { board:(Piece|null)[]; turn:Side; castling:string; ep:number; halfmove:number; fullmove:number }\nexport interface HistoryEntry { move:Move; san:string; before:PositionSnapshot }\n\nexport const squareName = (i:number):string => FILES[i % 8] + (8 - Math.floor(i / 8));\nexport const squareIndex = (s:string):number => /^[a-h][1-8]$/i.test(s) ? (8 - Number(s[1])) * 8 + FILES.indexOf(s[0].toLowerCase()) : -1;\nconst color = (p:Piece|null):Side|null => p ? (p === p.toUpperCase() ? 'w' : 'b') : null;\n\nexport class Chess {\n board:(Piece|null)[]=[]; turn:Side='w'; castling=''; ep=-1; halfmove=0; fullmove=1; history:HistoryEntry[]=[];\n constructor(fen:string = START_FEN) { this.load(fen); }\n load(fen:string):this {\n const [placement, turn, castling = '-', ep = '-', half = '0', full = '1'] = fen.trim().split(/\\s+/);\n const ranks = placement?.split('/');\n if (!ranks || ranks.length !== 8 || !/^[wb]$/.test(turn)) throw new Error('Invalid FEN');\n this.board = [];\n for (const rank of ranks) {\n for (const c of rank) {\n if (/\\d/.test(c)) this.board.push(...Array(Number(c)).fill(null));\n else if (/[prnbqkPRNBQK]/.test(c)) this.board.push(c as Piece);\n else throw new Error('Invalid FEN');\n }\n }\n if (this.board.length !== 64) throw new Error('Invalid FEN');\n this.turn = turn as Side; this.castling = castling === '-' ? '' : castling; this.ep = ep === '-' ? -1 : squareIndex(ep);\n this.halfmove = Number(half); this.fullmove = Number(full); this.history = [];\n if (this.ep < -1 || !Number.isFinite(this.halfmove) || !Number.isFinite(this.fullmove)) throw new Error('Invalid FEN');\n return this;\n }\n fen():string {\n let out = '';\n for (let r=0;r<8;r++) { let empty=0; for(let f=0;f<8;f++){ const p=this.board[r*8+f]; if(!p) empty++; else {if(empty){out+=empty;empty=0;} out+=p;} } if(empty)out+=empty; if(r<7)out+='/'; }\n return `${out} ${this.turn} ${this.castling || '-'} ${this.ep < 0 ? '-' : squareName(this.ep)} ${this.halfmove} ${this.fullmove}`;\n }\n attacked(sq:number, by:Side):boolean {\n const r=Math.floor(sq/8), f=sq%8;\n const pawn = by==='w'?'P':'p', pawnRow = r + (by==='w'?1:-1);\n for(const df of [-1,1]) if(pawnRow>=0&&pawnRow<8&&f+df>=0&&f+df<8&&this.board[pawnRow*8+f+df]===pawn)return true;\n for(const [df,dr] of KNIGHT){const rr=r+dr,ff=f+df;if(rr>=0&&rr<8&&ff>=0&&ff<8&&this.board[rr*8+ff]===(by==='w'?'N':'n'))return true;}\n for(const [df,dr] of KING){const rr=r+dr,ff=f+df;if(rr>=0&&rr<8&&ff>=0&&ff<8&&this.board[rr*8+ff]===(by==='w'?'K':'k'))return true;}\n for(const [df,dr,types] of [[1,0,'RQ'],[-1,0,'RQ'],[0,1,'RQ'],[0,-1,'RQ'],[1,1,'BQ'],[-1,1,'BQ'],[1,-1,'BQ'],[-1,-1,'BQ']] as [number,number,string][]) {\n let rr=r+dr,ff=f+df; while(rr>=0&&rr<8&&ff>=0&&ff<8){const p=this.board[rr*8+ff];if(p){if(color(p)===by&&types.includes(p.toUpperCase()))return true;break;}rr+=dr;ff+=df;\n }} return false;\n }\n inCheck(side:Side=this.turn):boolean { const king=this.board.indexOf(side==='w'?'K':'k'); return king<0 || this.attacked(king,side==='w'?'b':'w'); }\n pseudo():Move[] {\n const moves:Move[]=[];\n const add=(from:number,to:number,promotion:string|null=null,flags='')=>moves.push({from,to,promotion,flags});\n for(let from=0;from<64;from++){const p=this.board[from];if(!p||color(p)!==this.turn)continue;const type=p.toUpperCase(),r=Math.floor(from/8),f=from%8;\n if(type==='P'){const dir=this.turn==='w'?-1:1, home=this.turn==='w'?6:1, last=this.turn==='w'?0:7;const one=(r+dir)*8+f;\n if(r+dir>=0&&r+dir<8&&!this.board[one]){if(r+dir===last)for(const q of 'qrbn')add(from,one,q,'p');else add(from,one);const two=(r+2*dir)*8+f;if(r===home&&!this.board[two])add(from,two,null,'d');}\n for(const df of [-1,1]){const rr=r+dir,ff=f+df;if(rr<0||rr>7||ff<0||ff>7)continue;const to=rr*8+ff;if((this.board[to]&&color(this.board[to])!==this.turn)||to===this.ep){if(rr===last)for(const q of 'qrbn')add(from,to,q,to===this.ep?'ep':'cp');else add(from,to,null,to===this.ep?'e':'c');}}\n } else if(type==='N'||type==='K'){for(const [df,dr] of type==='N'?KNIGHT:KING){const rr=r+dr,ff=f+df;if(rr>=0&&rr<8&&ff>=0&&ff<8&&color(this.board[rr*8+ff])!==this.turn)add(from,rr*8+ff,null,this.board[rr*8+ff]?'c':'');}\n if(type==='K')this.castleMoves(from,add);\n } else {const dirs=type==='B'?KING.slice(4):type==='R'?KING.slice(0,4):KING;for(const[df,dr]of dirs){let rr=r+dr,ff=f+df;while(rr>=0&&rr<8&&ff>=0&&ff<8){const to=rr*8+ff;if(color(this.board[to])===this.turn)break;add(from,to,null,this.board[to]?'c':'');if(this.board[to])break;rr+=dr;ff+=df;}}}\n } return moves;\n }\n castleMoves(from:number, add:(from:number,to:number,promotion?:string|null,flags?:string)=>void):void {\n const white=this.turn==='w', base=white?60:4, enemy=white?'b':'w'; if(from!==base||this.inCheck())return;\n const king=white?'K':'k', rook=white?'R':'r'; if(this.board[from]!==king)return;\n if(this.castling.includes(white?'K':'k')&&this.board[base+3]===rook&&!this.board[base+1]&&!this.board[base+2]&&!this.attacked(base+1,enemy)&&!this.attacked(base+2,enemy))add(from,base+2,null,'k');\n if(this.castling.includes(white?'Q':'q')&&this.board[base-4]===rook&&!this.board[base-1]&&!this.board[base-2]&&!this.board[base-3]&&!this.attacked(base-1,enemy)&&!this.attacked(base-2,enemy))add(from,base-2,null,'q');\n }\n moves():Move[] { return this.pseudo().filter(m=>{const snapshot=this.snapshot();this.apply(m);const bad=this.inCheck(this.turn==='w'?'b':'w');this.restore(snapshot);return !bad;}); }\n snapshot():PositionSnapshot{return {board:[...this.board],turn:this.turn,castling:this.castling,ep:this.ep,halfmove:this.halfmove,fullmove:this.fullmove};}\n restore(s:PositionSnapshot):void{Object.assign(this,s);}\n apply(m:Move):void{const p=this.board[m.from]! as Piece, side=this.turn, captured=this.board[m.to];this.board[m.to]=(m.promotion?(side==='w'?m.promotion.toUpperCase():m.promotion):p) as Piece;this.board[m.from]=null;\n if(m.flags.includes('e'))this.board[m.to+(side==='w'?8:-8)]=null;\n if(m.flags==='k'){this.board[m.to-1]=this.board[m.to+1];this.board[m.to+1]=null;} if(m.flags==='q'){this.board[m.to+1]=this.board[m.to-2];this.board[m.to-2]=null;}\n const rights:Record<number,string>={0:'q',4:'kq',7:'k',56:'Q',60:'KQ',63:'K'};for(const sq of [m.from,m.to])if(rights[sq])for(const x of rights[sq])this.castling=this.castling.replace(x,'');\n this.ep=m.flags==='d'?(m.from+m.to)/2:-1;this.halfmove=(p.toUpperCase()==='P'||captured||m.flags.includes('e'))?0:this.halfmove+1;if(side==='b')this.fullmove++;this.turn=side==='w'?'b':'w';\n }\n san(m:Move, legal:Move[]=this.moves()):string {const p=this.board[m.from]!, type=p.toUpperCase();if(m.flags==='k')return'O-O';if(m.flags==='q')return'O-O-O';let s=type==='P'?'':type;\n if(type!=='P'){const same=legal.filter(x=>x!==m&&x.to===m.to&&this.board[x.from]?.toUpperCase()===type);if(same.length){if(same.every(x=>x.from%8!==m.from%8))s+=FILES[m.from%8];else if(same.every(x=>Math.floor(x.from/8)!==Math.floor(m.from/8)))s+=8-Math.floor(m.from/8);else s+=squareName(m.from);}}\n if(m.flags.includes('c')||m.flags.includes('e'))s+=(type==='P'?FILES[m.from%8]:'')+'x';s+=squareName(m.to);if(m.promotion)s+='='+m.promotion.toUpperCase();const snap=this.snapshot();this.apply(m);if(this.inCheck()){s+=this.moves().length?'#'.replace('#','+'):'#';}this.restore(snap);return s;\n }\n play(input:string):string {const legal=this.moves(), normalized=input.trim().replace(/[!?+#]/g,'').replace(/0/g,'O');let move=legal.find(m=>`${squareName(m.from)}${squareName(m.to)}${m.promotion||''}`===normalized.toLowerCase());if(!move)move=legal.find(m=>this.san(m,legal).replace(/[+#]/g,'')===normalized);if(!move)throw new Error(`Illegal or unrecognized move: ${input}`);const san=this.san(move,legal), before=this.snapshot();this.apply(move);this.history.push({move,san,before});return san;}\n undo():HistoryEntry|undefined{const h=this.history.pop();if(h)this.restore(h.before);return h;}\n status():string|null{const moves=this.moves();if(!moves.length)return this.inCheck()?(this.turn==='w'?'Black':'White')+' wins by checkmate':'Draw by stalemate';if(this.halfmove>=100)return'Draw by fifty-move rule';return null;}\n}\n", "import type { Chess } from './index.js';\nexport interface MoveResult { move: string; fen: string; explanation: string }\nexport interface MoveResolver { resolve(text: string, chess: Chess): Promise<MoveResult> }\nexport class ResolutionError extends Error {\n constructor(message: string, readonly status: number) { super(message); }\n}\n", "import { Chess, squareName } from './index.js';\n\nconst names: Record<string, string> = { P: 'Pawn', N: 'Knight', B: 'Bishop', R: 'Rook', Q: 'Queen', K: 'King' };\n\n/** Explain a recognizable move rejected for king safety, without changing the game. */\nexport function illegalMoveReason(input: string, chess: Chess): string | undefined {\n const text = input.trim();\n const uci = /^([a-h][1-8])([a-h][1-8])([qrbn])?$/.exec(text);\n const san = /^([KQRBN])?([a-h])?([1-8])?(x)?([a-h][1-8])(?:=([QRBN]))?[+#]?$/.exec(text);\n const words = text.toLowerCase();\n const squares = words.match(/[a-h][1-8]/g) || [];\n const named = words.match(/\\bwith (?:my |the |a )?(pawn|knight|bishop|rook|queen|king)\\b/)?.[1]\n || words.match(/\\b(pawn|knight|bishop|rook|queen|king)\\b/)?.[1];\n const kind = uci ? undefined : san ? san[1] || 'P'\n : Object.keys(names).find(key => names[key].toLowerCase() === named);\n const from = uci?.[1] || (squares.length > 1 ? squares[0] : undefined);\n const to = uci?.[2] || san?.[5] || squares.at(-1);\n if (!to || (!uci && !san && !kind && !from)) return;\n const capture = san ? Boolean(san[4]) : /\\b(take|takes|taking|capture|captures|capturing)\\b/.test(words);\n const candidates = chess.pseudo().filter(move => {\n if (squareName(move.to) !== to) return false;\n if (from && squareName(move.from) !== from) return false;\n if (kind && chess.board[move.from]!.toUpperCase() !== kind) return false;\n if (san?.[2] && squareName(move.from)[0] !== san[2]) return false;\n if (san?.[3] && squareName(move.from)[1] !== san[3]) return false;\n if (capture && !/[ce]/.test(move.flags)) return false;\n return true;\n });\n const legal = chess.moves();\n // A legal interpretation or multiple possible pieces needs clarification, not a pin claim.\n if (candidates.length !== 1 || legal.some(move => move.from === candidates[0].from && move.to === candidates[0].to)) return;\n const move = candidates[0];\n const copy = new Chess(chess.fen());\n copy.apply(move);\n if (!copy.inCheck(chess.turn)) return;\n const piece = chess.board[move.from]!.toUpperCase();\n if (piece === 'K') return `King cannot move to ${to}: that square is attacked.`;\n if (chess.inCheck()) return 'You are in check; this move would leave your king in check.';\n\n const king = chess.board.indexOf(chess.turn === 'w' ? 'K' : 'k');\n const dr = Math.floor(move.from / 8) - Math.floor(king / 8);\n const df = move.from % 8 - king % 8;\n if (dr === 0 || df === 0 || Math.abs(dr) === Math.abs(df)) {\n const stepR = Math.sign(dr), stepF = Math.sign(df);\n let rank = Math.floor(king / 8) + stepR, file = king % 8 + stepF;\n let passedPiece = false;\n while (rank >= 0 && rank < 8 && file >= 0 && file < 8) {\n const index = rank * 8 + file;\n const blocker = chess.board[index];\n if (index === move.from) passedPiece = true;\n else if (blocker) {\n const enemy = (blocker === blocker.toUpperCase() ? 'w' : 'b') !== chess.turn;\n const slider = (dr === 0 || df === 0 ? 'RQ' : 'BQ').includes(blocker.toUpperCase());\n if (passedPiece && enemy && slider) {\n return `${names[piece]} ${squareName(move.from)} is pinned by ${names[blocker.toUpperCase()].toLowerCase()} ${squareName(index)}; moving it exposes your king.`;\n }\n break;\n }\n rank += stepR;\n file += stepF;\n }\n }\n return `${names[piece]} ${squareName(move.from)} cannot move to ${to}: it would expose your king to check.`;\n}\n", "import { squareName, type Chess } from './index.js';\n\nconst names: Record<string, string> = { king: 'K', queen: 'Q', rook: 'R', bishop: 'B', knight: 'N', pawn: 'P' };\nexport function normalizeNotation(text: string): string {\n const symbols: Record<string, string> = { '\u2654':'K', '\u265A':'K', '\u2655':'Q', '\u265B':'Q', '\u2656':'R', '\u265C':'R', '\u2657':'B', '\u265D':'B', '\u2658':'N', '\u265E':'N', '\u2659':'', '\u265F':'' };\n return text.trim().replace(/[\u2654\u265A\u2655\u265B\u2656\u265C\u2657\u265D\u2658\u265E\u2659\u265F]/g, symbol => symbols[symbol])\n .replace(/\u00D7/g, 'x').replace(/([a-h][1-8])\\s*(?:\u2192|->|-)\\s*(?=[a-h][1-8])/g, '$1').replace(/0/g, 'O');\n}\n\nexport const looksLikeNotation = (text: string): boolean => !/\\s/.test(text) && (/\\d/.test(text) || /^[O0]-[O0]/.test(text));\n\nfunction distance(a: string, b: string): number {\n let row = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 0; i < a.length; i++) {\n const next = [i + 1];\n for (let j = 0; j < b.length; j++) next.push(Math.min(next[j] + 1, row[j + 1] + 1, row[j] + Number(a[i] !== b[j])));\n row = next;\n }\n return row[b.length];\n}\n\n/** Prefer matching legal moves, then offer explicitly labeled legal alternatives. */\nexport function suggestMoves(input: string, chess: Chess): string[] {\n const text = normalizeNotation(input);\n const lower = text.toLowerCase();\n const notation = looksLikeNotation(text);\n const squares = lower.match(/[a-h][1-8]/g) || [];\n const destination = squares.at(-1);\n const source = squares.length > 1 ? squares[0] : undefined;\n const named = lower.match(/\\bwith (?:my |the |a )?(king|queen|rook|bishop|knight|pawn)\\b/)?.[1]\n || lower.match(/\\b(king|queen|rook|bishop|knight|pawn)\\b/)?.[1];\n const piece = named ? names[named] : notation && !/^[a-h][1-8][a-h][1-8]/.test(text)\n ? (/^[KQRBN]/.exec(text)?.[0] || (/^[a-h]/.test(text) ? 'P' : undefined)) : undefined;\n const capture = notation ? text.includes('x') : /\\b(take|takes|taking|capture|captures|capturing)\\b/.test(lower);\n const castle = /\\bcastl/.test(lower) || /^[O0]-[O0]/.test(text);\n const legal = chess.moves();\n const matches = legal.map(move => {\n const san = chess.san(move, legal);\n const from = squareName(move.from), to = squareName(move.to);\n const kind = chess.board[move.from]!.toUpperCase();\n if (piece && kind !== piece) return null;\n if (source && from !== source) return null;\n if (capture && !san.includes('x')) return null;\n if (castle && !san.startsWith('O-O')) return null;\n if (!notation && destination && to !== destination) return null;\n const uci = from + to + (move.promotion || '');\n const difference = Math.min(distance(text, san), distance(lower, uci));\n if (notation && difference > 2 && to !== destination) return null;\n return { san, score: (to === destination ? 20 : 0) + (from === source ? 10 : 0) - difference };\n }).filter((entry): entry is { san: string; score: number } => entry !== null)\n .sort((a, b) => b.score - a.score || a.san.localeCompare(b.san)).slice(0, 5).map(entry => entry.san);\n return matches.length ? matches : legal.map(move => chess.san(move, legal)).sort().slice(0, 5);\n}\n\nexport function suggestionMessage(input: string, chess: Chess): string {\n const moves = suggestMoves(input, chess);\n return moves.length ? `No exact match. Try: ${moves.join(' \u00B7 ')} (legal alternatives; confirm your intended move).` : 'No legal moves are available.';\n}\n", "import { squareName } from './index.js';\nimport type { Chess } from './index.js';\nimport { ResolutionError, type MoveResolver } from './resolution.js';\nimport { illegalMoveReason } from './legality.js';\nimport { looksLikeNotation, normalizeNotation, suggestionMessage } from './suggestions.js';\n\nexport type InputIntent =\n | { type:'empty' }\n | { type:'quit' }\n | { type:'help' }\n | { type:'undo' }\n | { type:'back' }\n | { type:'show-fen' }\n | { type:'load-fen'; value:string }\n | { type:'move'; value:string; source:'notation'|'jev'; fen?:string; explanation?:string };\n\n/** Parse local commands/notation; delegate all genuinely free-form text to JEV. */\nexport async function modelInput(raw:string, chess:Chess, server?:MoveResolver):Promise<InputIntent> {\n const text = String(raw).trim();\n const lower = text.toLowerCase();\n if (!text) return { type: 'empty' };\n if (/^\\/(quit|exit)$/.test(lower)) return { type: 'quit' };\n if (lower === '/help') return { type: 'help' };\n if (lower === '/undo') return { type: 'undo' };\n if (/^\\/(back|menu)$/.test(lower)) return { type: 'back' };\n if (/^\\/(fen|position)$/.test(lower)) return { type: 'show-fen' };\n if (/^\\/(fen|position)\\s+/.test(lower)) return { type: 'load-fen', value: text.replace(/^\\/(?:fen|position)\\s+/i, '').trim() };\n if (lower.startsWith('/')) throw new Error(`Unknown command: ${text}. Type /help to see commands.`);\n\n const legal = chess.moves();\n const normalized = normalizeNotation(text);\n const exact = legal.find(move => {\n const uci = squareName(move.from) + squareName(move.to) + (move.promotion || '');\n return uci === normalized || chess.san(move, legal) === normalized;\n });\n if (exact) return { type: 'move', value: squareName(exact.from) + squareName(exact.to) + (exact.promotion || ''), source: 'notation' };\n\n const reason = illegalMoveReason(text, chess);\n if (reason) throw new Error(`${reason} ${suggestionMessage(text, chess)}`);\n if (looksLikeNotation(text)) throw new Error(suggestionMessage(text, chess));\n\n if (!server) throw new Error(`Chess server is required for natural-language input. ${suggestionMessage(text, chess)}`);\n let result;\n try { result = await server.resolve(text, chess); }\n catch (error) {\n if (error instanceof ResolutionError && error.status === 422) throw new Error(suggestionMessage(text, chess));\n if (error instanceof Error && error.name === 'AbortError') throw error;\n const detail = error instanceof Error ? error.message : String(error);\n throw new Error(`${detail}. ${suggestionMessage(text, chess)}`);\n }\n return { type: 'move', value: result.move, fen: result.fen, explanation: result.explanation, source: 'jev' };\n}\n", "import type { Chess } from './index.js';\n\n/** Undo through the player's most recent move, including any engine reply. */\nexport function undoTurn(chess: Chess, human: 'w' | 'b'): boolean {\n let index = chess.history.length - 1;\n while (index >= 0 && chess.history[index].before.turn !== human) index--;\n if (index < 0) return false;\n while (chess.history.length > index) chess.undo();\n return true;\n}\n\nexport function moveHistory(chess: Chess, width = 80): string {\n const groups: string[] = [];\n for (const entry of chess.history) {\n const { fullmove, turn } = entry.before;\n if (turn === 'w') groups.push(`${fullmove}. ${entry.san}`);\n else if (groups.length) groups[groups.length - 1] += ` ${entry.san}`;\n else groups.push(`${fullmove}\u2026 ${entry.san}`);\n }\n if (!groups.length) return 'Moves: \u2014';\n let clipped = false;\n while (groups.length > 1 && `Moves: ${clipped ? '\u2026 ' : ''}${groups.join(' ')}`.length > width) {\n groups.shift();\n clipped = true;\n }\n return `Moves: ${clipped ? '\u2026 ' : ''}${groups.join(' ')}`;\n}\n", "import type { Chess } from '@zchess/chess';\nimport { ResolutionError, type MoveResult } from '@zchess/chess/interaction';\nexport { ResolutionError, type MoveResult } from '@zchess/chess/interaction';\nexport class ChessServerClient {\n constructor(private readonly baseUrl=process.env.ZCHESS_SERVER_URL||'http://localhost:8000', private readonly signal?:AbortSignal){}\n async resolve(text:string,chess:Chess):Promise<MoveResult>{return this.post('/api/resolve',{instruction:text,fen:chess.fen()});}\n private async post(path:string,body:unknown):Promise<MoveResult>{const response=await fetch(this.baseUrl.replace(/\\/$/,'')+path,{method:'POST',headers:{'content-type':'application/json'},body:JSON.stringify(body),signal:this.signal});if(!response.ok){\n const body = await response.json().catch(() => ({})) as {detail?:unknown};\n throw new ResolutionError(typeof body.detail === 'string' ? body.detail : `Chess server failed (${response.status})`, response.status);\n }return response.json() as Promise<MoveResult>;}\n}\n", "import type { Chess } from '@zchess/chess';\n\nconst PIECES: Record<string, string> = {\n K: '\u265A', Q: '\u265B', R: '\u265C', B: '\u265D', N: '\u265E', P: '\u265F',\n k: '\u265A', q: '\u265B', r: '\u265C', b: '\u265D', n: '\u265E', p: '\u265F',\n};\nconst OUTLINES: Record<string, string> = { K: '\u2654', Q: '\u2655', R: '\u2656', B: '\u2657', N: '\u2658', P: '\u2659' };\nconst RESET = '\\x1b[0m';\ninterface RenderOptions { perspective?: 'w' | 'b'; last?: number[] | null; color?: boolean; compact?: boolean; ascii?: boolean }\n\nexport function render(chess: Chess, { perspective = 'w', last = null, color = Boolean(process.stdout.isTTY), compact = false, ascii = false }: RenderOptions = {}): string {\n const rows = perspective === 'w' ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];\n const files = perspective === 'w' ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];\n // Typical terminal cells are about twice as tall as they are wide. Keep\n // compact ranks proportional too, and allow narrow windows to shrink.\n const cellWidth = Math.max(1, Math.min(compact ? 2 : 6, Math.floor(((process.stdout.columns || 80) - 8) / 8)));\n const cell = (content = ''): string => {\n const left = Math.floor((cellWidth - 1) / 2);\n return `${' '.repeat(left)}${content}${' '.repeat(cellWidth - left - (content ? 1 : 0))}`;\n };\n const defaultText = (text: string): string => color ? `\\x1b[39m${text}${RESET}` : text;\n const border = defaultText(` +${'-'.repeat(cellWidth * 8)}+`);\n const output = [border];\n\n for (const rank of rows) {\n for (const line of compact ? [1] : [0, 1, 2]) {\n let row = defaultText(`${line === 1 ? ` ${8 - rank} ` : ' '}|`);\n for (const file of files) {\n const index = rank * 8 + file;\n const piece = chess.board[index];\n const white = piece !== null && piece === piece.toUpperCase();\n const glyph = piece ? (ascii ? piece : !color && white ? OUTLINES[piece] : PIECES[piece]) : ' ';\n let square = cell(line === 1 ? glyph : '');\n if (color) {\n const background = last?.includes(index) ? 107 : (rank + file) % 2 ? 65 : 108;\n square = `\\x1b[1;48;5;${background};38;5;${white ? 231 : 16}m${square}${RESET}`;\n } else if (!piece && line === 1) {\n square = cell((rank + file) % 2 ? (ascii ? '.' : '\u00B7') : '');\n }\n row += square;\n }\n output.push(row + defaultText('|'));\n }\n }\n output.push(border);\n output.push(defaultText(' ' + files.map(file => cell('abcdefgh'[file])).join('')));\n output.push(ascii ? defaultText(' White: KQRBNP Black: kqrbnp') : color\n ? defaultText(' \u2654 White \u265A Black \u00B7 dark pieces')\n : ' \u2654 White \u265A Black');\n return output.join('\\n') + '\\n';\n}\n", "import { createRequire } from 'node:module';\nimport type { Chess } from '@zchess/chess';\nimport piecesData from '@zchess/chess/pieces' with { type: 'json' };\n\nconst require = createRequire(import.meta.url);\nconst pieces = piecesData as Record<string, string>;\nconst IMAGE_ID = 73191;\nexport { supportsGraphics, type GraphicsMode } from './terminal.js';\n\nexport function clearGraphics(): string {\n return `\\x1b_Ga=d,d=I,i=${IMAGE_ID},q=2;\\x1b\\\\`;\n}\n\nexport function boardSvg(chess: Chess, perspective: 'w' | 'b', last: number[] | null): string {\n const order = perspective === 'w' ? [0, 1, 2, 3, 4, 5, 6, 7] : [7, 6, 5, 4, 3, 2, 1, 0];\n const svg = ['<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"768\" height=\"768\" viewBox=\"0 0 768 768\">',\n '<rect width=\"768\" height=\"768\" rx=\"12\" fill=\"#14291f\"/>'];\n for (const [y, rank] of order.entries()) {\n for (const [x, file] of order.entries()) {\n const index = rank * 8 + file;\n const left = 24 + x * 90, top = 24 + y * 90;\n const fill = last?.includes(index) ? '#b4cf68' : (rank + file) % 2 ? '#64916d' : '#d5e5cb';\n svg.push(`<rect x=\"${left}\" y=\"${top}\" width=\"90\" height=\"90\" fill=\"${fill}\"/>`);\n const piece = chess.board[index];\n if (piece) svg.push(`<g transform=\"translate(${left} ${top}) scale(2)\">${pieces[piece]}</g>`);\n }\n svg.push(`<text x=\"12\" y=\"${24 + y * 90 + 50}\" text-anchor=\"middle\" font-size=\"16\" font-family=\"sans-serif\" fill=\"#d5e5cb\">${8 - rank}</text>`);\n }\n for (const [x, file] of order.entries()) {\n svg.push(`<text x=\"${24 + x * 90 + 45}\" y=\"762\" text-anchor=\"middle\" font-size=\"16\" font-family=\"sans-serif\" fill=\"#d5e5cb\">${'abcdefgh'[file]}</text>`);\n }\n svg.push('</svg>');\n return svg.join('');\n}\n\nexport function boardPng(chess: Chess, perspective: 'w' | 'b', last: number[] | null): Buffer {\n const { Resvg } = require('@resvg/resvg-js') as typeof import('@resvg/resvg-js');\n return new Resvg(boardSvg(chess, perspective, last)).render().asPng();\n}\n\nexport function renderGraphics(chess: Chess, perspective: 'w' | 'b', last: number[] | null, fixed = false, columnsPerRow = 2): string {\n // A single placement dimension preserves PNG aspect even in terminals that\n // stretch images when both c and r are supplied. Use measured cell pixels to\n // select the limiting dimension and reserve the corresponding rows.\n const availableRows = Math.max(1, Math.min(32, (process.stdout.rows || 40) - (fixed ? 8 : 7)));\n const availableColumns = Math.max(1, (process.stdout.columns || 80) - 2);\n const ratio = Number.isFinite(columnsPerRow) && columnsPerRow > 0 ? columnsPerRow : 2;\n const widthLimited = availableColumns / ratio < availableRows;\n const rows = widthLimited ? Math.ceil(availableColumns / ratio) : availableRows;\n const placement = widthLimited ? `c=${availableColumns}` : `r=${rows}`;\n const data = boardPng(chess, perspective, last).toString('base64');\n // Reserve room first: images anchored near the bottom must not cover the prompt.\n let output = clearGraphics();\n if (!fixed) output += '\\n'.repeat(rows) + `\\x1b[${rows}A\\r`;\n for (let offset = 0; offset < data.length; offset += 4096) {\n const chunk = data.slice(offset, offset + 4096);\n const more = offset + 4096 < data.length ? 1 : 0;\n const control = offset === 0 ? `a=T,f=100,t=d,i=${IMAGE_ID},${placement},C=1,q=2,` : '';\n output += `\\x1b_G${control}m=${more};${chunk}\\x1b\\\\`;\n }\n return output + `\\x1b[${rows}B\\r`;\n}\n", "{\n \"b\": \"<g id=\\\"black-bishop\\\" class=\\\"black bishop\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M9 36c3.39-.97 10.11.43 13.5-2 3.39 2.43 10.11 1.03 13.5 2 0 0 1.65.54 3 2-.68.97-1.65.99-3 .5-3.39-.97-10.11.46-13.5-1-3.39 1.46-10.11.03-13.5 1-1.354.49-2.323.47-3-.5 1.354-1.94 3-2 3-2zm6-4c2.5 2.5 12.5 2.5 15 0 .5-1.5 0-2 0-2 0-2.5-2.5-4-2.5-4 5.5-1.5 6-11.5-5-15.5-11 4-10.5 14-5 15.5 0 0-2.5 1.5-2.5 4 0 0-.5.5 0 2zM25 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 1 1 5 0z\\\" fill=\\\"#000\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M17.5 26h10M15 30h15m-7.5-14.5v5M20 18h5\\\" stroke=\\\"#fff\\\" stroke-linejoin=\\\"miter\\\"/></g>\",\n \"k\": \"<g id=\\\"black-king\\\" class=\\\"black king\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M22.5 11.63V6\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5\\\" fill=\\\"#000\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M11.5 37c5.5 3.5 15.5 3.5 21 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-3.5-7.5-13-10.5-16-4-3 6 5 10 5 10V37z\\\" fill=\\\"#000\\\"/><path d=\\\"M20 8h5\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M32 29.5s8.5-4 6.03-9.65C34.15 14 25 18 22.5 24.5l.01 2.1-.01-2.1C20 18 9.906 14 6.997 19.85c-2.497 5.65 4.853 9 4.853 9M11.5 30c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0\\\" stroke=\\\"#fff\\\"/></g>\",\n \"n\": \"<g id=\\\"black-knight\\\" class=\\\"black knight\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/><path d=\\\"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/><path d=\\\"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z\\\" style=\\\"fill:#ececec; stroke:#ececec;\\\"/><path d=\\\"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z\\\" transform=\\\"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)\\\" style=\\\"fill:#ececec; stroke:#ececec;\\\"/><path d=\\\"M 24.55,10.4 L 24.1,11.85 L 24.6,12 C 27.75,13 30.25,14.49 32.5,18.75 C 34.75,23.01 35.75,29.06 35.25,39 L 35.2,39.5 L 37.45,39.5 L 37.5,39 C 38,28.94 36.62,22.15 34.25,17.66 C 31.88,13.17 28.46,11.02 25.06,10.5 L 24.55,10.4 z \\\" style=\\\"fill:#ececec; stroke:none;\\\"/></g>\",\n \"p\": \"<g id=\\\"black-pawn\\\" class=\\\"black pawn\\\"><path d=\\\"M22.5 9c-2.21 0-4 1.79-4 4 0 .89.29 1.71.78 2.38C17.33 16.5 16 18.59 16 21c0 2.03.94 3.84 2.41 5.03-3 1.06-7.41 5.55-7.41 13.47h23c0-7.92-4.41-12.41-7.41-13.47 1.47-1.19 2.41-3 2.41-5.03 0-2.41-1.33-4.5-3.28-5.62.49-.67.78-1.49.78-2.38 0-2.21-1.79-4-4-4z\\\" fill=\\\"#000\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"/></g>\",\n \"q\": \"<g id=\\\"black-queen\\\" class=\\\"black queen\\\" fill=\\\"#000\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><g fill=\\\"#000\\\" stroke=\\\"none\\\"><circle cx=\\\"6\\\" cy=\\\"12\\\" r=\\\"2.75\\\"/><circle cx=\\\"14\\\" cy=\\\"9\\\" r=\\\"2.75\\\"/><circle cx=\\\"22.5\\\" cy=\\\"8\\\" r=\\\"2.75\\\"/><circle cx=\\\"31\\\" cy=\\\"9\\\" r=\\\"2.75\\\"/><circle cx=\\\"39\\\" cy=\\\"12\\\" r=\\\"2.75\\\"/></g><path d=\\\"M9 26c8.5-1.5 21-1.5 27 0l2.5-12.5L31 25l-.3-14.1-5.2 13.6-3-14.5-3 14.5-5.2-13.6L14 25 6.5 13.5 9 26zM9 26c0 2 1.5 2 2.5 4 1 1.5 1 1 .5 3.5-1.5 1-1.5 2.5-1.5 2.5-1.5 1.5.5 2.5.5 2.5 6.5 1 16.5 1 23 0 0 0 1.5-1 0-2.5 0 0 .5-1.5-1-2.5-.5-2.5-.5-2 .5-3.5 1-2 2.5-2 2.5-4-8.5-1.5-18.5-1.5-27 0z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M11 38.5a35 35 1 0 0 23 0\\\" fill=\\\"none\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M11 29a35 35 1 0 1 23 0M12.5 31.5h20M11.5 34.5a35 35 1 0 0 22 0M10.5 37.5a35 35 1 0 0 24 0\\\" fill=\\\"none\\\" stroke=\\\"#fff\\\"/></g>\",\n \"r\": \"<g id=\\\"black-rook\\\" class=\\\"black rook\\\" fill=\\\"#000\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M9 39h27v-3H9v3zM12.5 32l1.5-2.5h17l1.5 2.5h-20zM12 36v-4h21v4H12z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M14 29.5v-13h17v13H14z\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M14 16.5L11 14h23l-3 2.5H14zM11 14V9h4v2h5V9h5v2h5V9h4v5H11z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M12 35.5h21M13 31.5h19M14 29.5h17M14 16.5h17M11 14h23\\\" fill=\\\"none\\\" stroke=\\\"#fff\\\" stroke-width=\\\"1\\\" stroke-linejoin=\\\"miter\\\"/></g>\",\n \"B\": \"<g id=\\\"white-bishop\\\" class=\\\"white bishop\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><g fill=\\\"#fff\\\" stroke-linecap=\\\"butt\\\"><path d=\\\"M9 36c3.39-.97 10.11.43 13.5-2 3.39 2.43 10.11 1.03 13.5 2 0 0 1.65.54 3 2-.68.97-1.65.99-3 .5-3.39-.97-10.11.46-13.5-1-3.39 1.46-10.11.03-13.5 1-1.354.49-2.323.47-3-.5 1.354-1.94 3-2 3-2zM15 32c2.5 2.5 12.5 2.5 15 0 .5-1.5 0-2 0-2 0-2.5-2.5-4-2.5-4 5.5-1.5 6-11.5-5-15.5-11 4-10.5 14-5 15.5 0 0-2.5 1.5-2.5 4 0 0-.5.5 0 2zM25 8a2.5 2.5 0 1 1-5 0 2.5 2.5 0 1 1 5 0z\\\"/></g><path d=\\\"M17.5 26h10M15 30h15m-7.5-14.5v5M20 18h5\\\" stroke-linejoin=\\\"miter\\\"/></g>\",\n \"K\": \"<g id=\\\"white-king\\\" class=\\\"white king\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M22.5 11.63V6M20 8h5\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M22.5 25s4.5-7.5 3-10.5c0 0-1-2.5-3-2.5s-3 2.5-3 2.5c-1.5 3 3 10.5 3 10.5\\\" fill=\\\"#fff\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M11.5 37c5.5 3.5 15.5 3.5 21 0v-7s9-4.5 6-10.5c-4-6.5-13.5-3.5-16 4V27v-3.5c-3.5-7.5-13-10.5-16-4-3 6 5 10 5 10V37z\\\" fill=\\\"#fff\\\"/><path d=\\\"M11.5 30c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0m-21 3.5c5.5-3 15.5-3 21 0\\\"/></g>\",\n \"N\": \"<g id=\\\"white-knight\\\" class=\\\"white knight\\\" fill=\\\"none\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18\\\" style=\\\"fill:#ffffff; stroke:#000000;\\\"/><path d=\\\"M 24,18 C 24.38,20.91 18.45,25.37 16,27 C 13,29 13.18,31.34 11,31 C 9.958,30.06 12.41,27.96 11,28 C 10,28 11.19,29.23 10,30 C 9,30 5.997,31 6,26 C 6,24 12,14 12,14 C 12,14 13.89,12.1 14,10.5 C 13.27,9.506 13.5,8.5 13.5,7.5 C 14.5,6.5 16.5,10 16.5,10 L 18.5,10 C 18.5,10 19.28,8.008 21,7 C 22,7 22,10 22,10\\\" style=\\\"fill:#ffffff; stroke:#000000;\\\"/><path d=\\\"M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/><path d=\\\"M 15 15.5 A 0.5 1.5 0 1 1 14,15.5 A 0.5 1.5 0 1 1 15 15.5 z\\\" transform=\\\"matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)\\\" style=\\\"fill:#000000; stroke:#000000;\\\"/></g>\",\n \"P\": \"<g id=\\\"white-pawn\\\" class=\\\"white pawn\\\"><path d=\\\"M22.5 9c-2.21 0-4 1.79-4 4 0 .89.29 1.71.78 2.38C17.33 16.5 16 18.59 16 21c0 2.03.94 3.84 2.41 5.03-3 1.06-7.41 5.55-7.41 13.47h23c0-7.92-4.41-12.41-7.41-13.47 1.47-1.19 2.41-3 2.41-5.03 0-2.41-1.33-4.5-3.28-5.62.49-.67.78-1.49.78-2.38 0-2.21-1.79-4-4-4z\\\" fill=\\\"#fff\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\"/></g>\",\n \"Q\": \"<g id=\\\"white-queen\\\" class=\\\"white queen\\\" fill=\\\"#fff\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M8 12a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM24.5 7.5a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM41 12a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM16 8.5a2 2 0 1 1-4 0 2 2 0 1 1 4 0zM33 9a2 2 0 1 1-4 0 2 2 0 1 1 4 0z\\\"/><path d=\\\"M9 26c8.5-1.5 21-1.5 27 0l2-12-7 11V11l-5.5 13.5-3-15-3 15-5.5-14V25L7 14l2 12zM9 26c0 2 1.5 2 2.5 4 1 1.5 1 1 .5 3.5-1.5 1-1.5 2.5-1.5 2.5-1.5 1.5.5 2.5.5 2.5 6.5 1 16.5 1 23 0 0 0 1.5-1 0-2.5 0 0 .5-1.5-1-2.5-.5-2.5-.5-2 .5-3.5 1-2 2.5-2 2.5-4-8.5-1.5-18.5-1.5-27 0z\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M11.5 30c3.5-1 18.5-1 22 0M12 33.5c6-1 15-1 21 0\\\" fill=\\\"none\\\"/></g>\",\n \"R\": \"<g id=\\\"white-rook\\\" class=\\\"white rook\\\" fill=\\\"#fff\\\" fill-rule=\\\"evenodd\\\" stroke=\\\"#000\\\" stroke-width=\\\"1.5\\\" stroke-linecap=\\\"round\\\" stroke-linejoin=\\\"round\\\"><path d=\\\"M9 39h27v-3H9v3zM12 36v-4h21v4H12zM11 14V9h4v2h5V9h5v2h5V9h4v5\\\" stroke-linecap=\\\"butt\\\"/><path d=\\\"M34 14l-3 3H14l-3-3\\\"/><path d=\\\"M31 17v12.5H14V17\\\" stroke-linecap=\\\"butt\\\" stroke-linejoin=\\\"miter\\\"/><path d=\\\"M31 29.5l1.5 2.5h-20l1.5-2.5\\\"/><path d=\\\"M11 14h23\\\" fill=\\\"none\\\" stroke-linejoin=\\\"miter\\\"/></g>\"\n}\n", "import { stdin, stdout } from 'node:process';\n\nexport type GraphicsMode = 'auto' | 'kitty' | 'text' | 'ascii';\nconst QUERY_ID = 73192;\n\nfunction blocksAutoGraphics(env: NodeJS.ProcessEnv): boolean {\n // Konsole 25.04.2 acknowledges Kitty queries but was observed to ignore our\n // single-dimension placement, clipping the board over the input field.\n // Keep auto conservative until its placement is empirically validated.\n const candidate = env.TERM === 'xterm-kitty' || env.TERM === 'xterm-ghostty' ||\n ['kitty', 'ghostty'].includes(env.TERM_PROGRAM?.toLowerCase() ?? '');\n // Unknown emulators can print APC payloads into shell scrollback (observed\n // in QTerminal 2.1.0). A hint permits probing; only an OK reply enables images.\n return Boolean(!candidate || env.TMUX || env.STY || env.TERM === 'dumb' ||\n env.KONSOLE_VERSION || env.TERM_PROGRAM?.toLowerCase() === 'konsole');\n}\n\n/** Environment variables can disable probing, but cannot prove graphics support. */\nexport function supportsGraphics(mode: GraphicsMode, tty = Boolean(stdout.isTTY && stdin.isTTY), env = process.env, confirmed = false): boolean {\n if (!tty || (mode === 'text' || mode === 'ascii')) return false;\n if (mode === 'kitty') return true;\n if (blocksAutoGraphics(env)) return false;\n return confirmed;\n}\n\n/** Isolate protocol replies from readline. Queries do not store or display images. */\nexport async function detectGraphics(mode: GraphicsMode, input = stdin, output = stdout, env = process.env, timeout = 300, onCellAspect?: (ratio: number) => void): Promise<boolean> {\n const tty = Boolean(input.isTTY && output.isTTY);\n if ((mode === 'text' || mode === 'ascii') || !tty || env.TMUX || env.STY || env.TERM === 'dumb' ||\n (mode === 'auto' && blocksAutoGraphics(env))) {\n return supportsGraphics(mode, tty, env);\n }\n const previous = input.listeners('data') as Array<(chunk: Buffer | string) => void>;\n previous.forEach(listener => input.off('data', listener));\n const wasRaw = input.isRaw;\n const wasFlowing = input.readableFlowing === true;\n let pending = '';\n let keyboard = '';\n let confirmed = mode === 'kitty';\n return await new Promise<boolean>((resolve, reject) => {\n let finished = false;\n const finish = (error?: Error): void => {\n if (finished) return;\n finished = true;\n clearTimeout(timer);\n input.pause();\n input.off('data', onData);\n input.off('end', onEnd);\n input.off('error', onError);\n input.setRawMode(Boolean(wasRaw));\n previous.forEach(listener => input.on('data', listener));\n // Replay original bytes, including any partial UTF-8 character. The\n // downstream decoder owns completion across this handoff and EOF.\n if (keyboard) input.unshift(Buffer.from(keyboard, 'latin1'));\n if (wasFlowing) input.resume();\n if (error) reject(error); else resolve(confirmed);\n };\n const onEnd = (): void => finish();\n const onError = (error: Error): void => finish(error);\n const onData = (chunk: Buffer | string): void => {\n // Latin-1 is a reversible byte mapping here, not a text encoding choice.\n // Protocol delimiters are ASCII; decoding keyboard UTF-8 here would\n // corrupt characters whose continuation arrives after the probe ends.\n pending += (typeof chunk === 'string' ? Buffer.from(chunk) : chunk).toString('latin1');\n while (pending) {\n if (pending[0] !== '\\x1b') {\n keyboard += pending[0];\n pending = pending.slice(1);\n continue;\n }\n const reply = pending.match(/^\\x1b_G([^;]*);([^\\x1b]*)\\x1b\\\\/);\n if (reply) {\n if (mode === 'auto' && reply[1].split(',').includes(`i=${QUERY_ID}`)) confirmed = reply[2] === 'OK';\n pending = pending.slice(reply[0].length);\n continue;\n }\n const cellSize = pending.match(/^\\x1b\\[6;(\\d+);(\\d+)t/);\n if (cellSize) {\n const height = Number(cellSize[1]), width = Number(cellSize[2]);\n if (height > 0 && width > 0 && height <= 1000 && width <= 1000) onCellAspect?.(height / width);\n pending = pending.slice(cellSize[0].length);\n continue;\n }\n const attributes = pending.match(/^\\x1b\\[\\?[\\d;]*c/);\n if (attributes) {\n keyboard += pending.slice(attributes[0].length);\n pending = '';\n finish();\n return;\n }\n // Buffer fragmented responses, preserving unrelated escape keys.\n if ('\\x1b_G'.startsWith(pending) || pending.startsWith('\\x1b_G') ||\n '\\x1b[?'.startsWith(pending) || /^\\x1b\\[(?:\\?[\\d;]*|6[;\\d]*)$/.test(pending)) break;\n keyboard += pending[0];\n pending = pending.slice(1);\n }\n };\n const timer = setTimeout(() => finish(), timeout);\n input.on('data', onData);\n input.once('end', onEnd);\n input.once('error', onError);\n try {\n input.setRawMode(true);\n input.resume();\n output.write(`\\x1b_Gi=${QUERY_ID},s=1,v=1,a=q,t=d,f=24;AAAA\\x1b\\\\\\x1b[16t\\x1b[c`);\n } catch (error) { finish(error as Error); }\n });\n}\n", "import { spawn } from 'node:child_process';\nimport { createRequire } from 'node:module';\nimport { createInterface } from 'node:readline';\nimport { Chess } from '@zchess/chess';\n\nconst require = createRequire(import.meta.url);\nconst stockfish = require('stockfish') as { findEngine(flavor: string): string };\n\n/** Run the bundled engine in a separate process so search never blocks the CLI. */\nexport async function engineMove(fen: string, elo: number, depth: number, signal?: AbortSignal): Promise<string> {\n if (!Number.isInteger(elo) || elo < 1320 || elo > 3190) throw new Error('ELO must be an integer from 1320 to 3190.');\n if (!Number.isInteger(depth) || depth < 1 || depth > 30) throw new Error('Depth must be an integer from 1 to 30.');\n signal?.throwIfAborted();\n const position = new Chess(fen);\n if (position.status()) throw new Error('The game is over.');\n\n return new Promise((resolve, reject) => {\n const child = spawn(process.execPath, [stockfish.findEngine('single')], { stdio: ['pipe', 'pipe', 'ignore'] });\n const lines = createInterface({ input: child.stdout });\n let settled = false;\n const finish = (error?: Error, move?: string): void => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n signal?.removeEventListener('abort', cancel);\n lines.close();\n child.kill();\n if (error) reject(error);\n else resolve(move!);\n };\n const timer = setTimeout(() => finish(new Error('Stockfish timed out. Try a lower --depth.')), 60_000);\n const cancel = (): void => finish(new Error('Stockfish search cancelled.'));\n signal?.addEventListener('abort', cancel, { once: true });\n child.on('error', error => finish(new Error(`Could not start bundled Stockfish: ${error.message}`)));\n child.stdin.on('error', error => finish(error));\n child.on('exit', () => finish(new Error('Stockfish exited before returning a move.')));\n lines.on('line', line => {\n if (line === 'uciok') {\n child.stdin.write(`setoption name UCI_LimitStrength value true\\nsetoption name UCI_Elo value ${elo}\\nisready\\n`);\n } else if (line === 'readyok') {\n child.stdin.write(`position fen ${fen}\\ngo depth ${depth}\\n`);\n } else if (line.startsWith('bestmove ')) {\n const move = line.split(/\\s+/)[1];\n try {\n position.play(move);\n finish(undefined, move);\n } catch {\n finish(new Error('Stockfish returned an invalid move.'));\n }\n }\n });\n child.stdin.write('uci\\n');\n });\n}\n", "import { stdout } from 'node:process';\n\ninterface Output {\n columns?: number;\n rows?: number;\n write(text: string): unknown;\n}\n\n/** Keep game frames out of shell scrollback and restore the shell on exit. */\nexport class GameScreen {\n private opened = false;\n private cursorStyled = false;\n constructor(readonly active: boolean, private readonly output: Output = stdout, private readonly manageScreen = true) {}\n\n open(): void {\n if (this.active && this.manageScreen && !this.opened) {\n this.output.write('\\x1b[?1049h');\n this.opened = true;\n }\n }\n\n draw(header: string, board: string, status: string, moves = ''): void {\n if (!this.active) {\n this.output.write(`${header}\\n${moves}\\n\\n${board}\\n${status}\\n`);\n return;\n }\n const width = Math.max(1, (this.output.columns || 80) - 1);\n const fit = (text: string): string => [...text.replace(/[\\x00-\\x1f\\x7f]/g, ' ')].slice(0, width).join('');\n // Synchronized output prevents a visible blank frame between positions.\n const title = `\\x1b[39m${fit(header).padEnd(width)}\\x1b[0m`;\n const history = `\\x1b[39m${fit(moves).padEnd(width)}\\x1b[0m`;\n const horizontalPadding = Math.min(1, Math.floor((width - 1) / 2));\n const innerWidth = Math.max(1, width - horizontalPadding * 2);\n const controls = '/help';\n const visibleControls = controls.slice(-Math.min(innerWidth, controls.length));\n const statusWidth = Math.max(0, innerWidth - visibleControls.length);\n const footer = `\\x1b[39m${' '.repeat(horizontalPadding)}${fit(status).slice(0, statusWidth).padEnd(statusWidth)}${visibleControls}${' '.repeat(horizontalPadding + 1)}\\x1b[0m`;\n const bottom = Math.max(6, this.output.rows || 40);\n this.output.write('\\x1b[?2026h\\x1b[H\\x1b[2J' +\n `${title}\\r\\n${history}\\r\\n\\r\\n${board}\\x1b[${bottom - 4};1H${footer}` +\n this.inputFrame('', 'Type any moves e.g. e4 or e pawn up 2') + '\\x1b[?2026l');\n }\n\n input(value: string, placeholder = 'Type any moves e.g. e4 or e pawn up 2'): void {\n if (this.active) this.output.write(this.inputFrame(value, placeholder));\n }\n\n private inputFrame(value: string, placeholder: string): string {\n const width = Math.max(1, (this.output.columns || 80) - 1);\n const bottom = Math.max(6, this.output.rows || 40);\n const visible = [...value].slice(-Math.max(0, width - 4)).join('');\n const foreground = value ? '\\x1b[38;2;235;248;226m' : '\\x1b[38;2;139;168;144m';\n const horizontalPadding = 1;\n const fieldTextWidth = Math.max(0, width - horizontalPadding - 2);\n const shown = value\n ? [...visible].slice(-fieldTextWidth).join('')\n : [...placeholder].slice(0, Math.max(0, fieldTextWidth - 1)).join('');\n const prefix = ' ';\n const displayed = value ? shown : ` ${shown}`;\n const background = '\\x1b[48;2;12;42;34m';\n const paddingRow = `${background}${' '.repeat(width + 1)}\\x1b[0m`;\n const row = `${background}\\x1b[38;2;190;221;173m${prefix}${foreground}${displayed}${' '.repeat(Math.max(0, width + 1 - prefix.length - [...displayed].length))}\\x1b[0m`;\n const cursor = value ? Math.min(width, prefix.length + [...shown].length + 1) : 2;\n this.cursorStyled = true;\n return `\\x1b[${bottom - 2};1H${paddingRow}` +\n `\\x1b[${bottom - 1};1H${row}` +\n `\\x1b[${bottom};1H${paddingRow}\\x1b[${bottom - 1};${cursor}H\\x1b[5 q\\x1b[?25h`;\n }\n\n close(): void {\n if (this.cursorStyled) {\n this.output.write('\\x1b[0 q');\n this.cursorStyled = false;\n }\n if (this.opened) {\n this.output.write('\\x1b[?2026l\\x1b[?25h\\x1b[?1049l');\n this.opened = false;\n }\n }\n}\n\n/** Full-screen start and load menus that replace one another without scrollback. */\nexport class MenuScreen {\n private opened = false;\n constructor(readonly active: boolean, private readonly output: Output = stdout) {}\n\n open(): void {\n if (this.active && !this.opened) {\n this.output.write('\\x1b[?1049h\\x1b[?25l');\n this.opened = true;\n }\n }\n\n draw(header: string, content: string, footer: string): void {\n const width = Math.max(1, (this.output.columns || 80) - 1);\n const fit = (text: string): string => [...text.replace(/[\\x00-\\x1f\\x7f]/g, ' ')].slice(0, width).join('');\n if (!this.active) {\n this.output.write(`${header}\\n${content}\\n${footer}\\n`);\n return;\n }\n const title = `\\x1b[39m${fit(header).padEnd(width)}\\x1b[0m`;\n const horizontalPadding = Math.min(2, Math.floor((width - 1) / 2));\n const status = `\\x1b[39m${' '.repeat(horizontalPadding)}${fit(footer).slice(0, width - horizontalPadding * 2).padEnd(width - horizontalPadding * 2)}${' '.repeat(horizontalPadding)}\\x1b[0m`;\n const body = content.split('\\n').map(line => fit(line)).join('\\r\\n');\n this.output.write(`\\x1b[?25l\\x1b[?2026h\\x1b[H\\x1b[2J${title}\\r\\n\\r\\n${body}\\r\\n\\r\\n${status}\\r\\n\\x1b[?2026l`);\n }\n\n close(): void {\n if (this.opened) {\n this.output.write('\\x1b[?25h\\x1b[?1049l');\n this.opened = false;\n }\n }\n}\n", "import { DatabaseSync } from 'node:sqlite';\nimport { mkdirSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { homedir } from 'node:os';\n\nexport interface SavedGame {\n id: number;\n createdAt: string;\n updatedAt: string;\n elo: number;\n color: 'w' | 'b';\n startFen: string;\n fen: string;\n moves: string[];\n status: string;\n}\n\nexport class GameStore {\n private readonly db: DatabaseSync;\n\n constructor(path = process.env.ZCHESS_DB_PATH || join(process.env.XDG_DATA_HOME || join(homedir(), '.local', 'share'), 'zchess', 'games.sqlite')) {\n mkdirSync(dirname(path), { recursive: true });\n this.db = new DatabaseSync(path);\n this.db.exec(`\n PRAGMA journal_mode = WAL;\n CREATE TABLE IF NOT EXISTS games (\n id INTEGER PRIMARY KEY,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n elo INTEGER NOT NULL,\n color TEXT NOT NULL CHECK (color IN ('w', 'b')),\n start_fen TEXT NOT NULL,\n fen TEXT NOT NULL,\n moves TEXT NOT NULL,\n status TEXT NOT NULL\n );\n `);\n }\n\n save(game: Omit<SavedGame, 'id' | 'createdAt' | 'updatedAt'>, id?: number): number {\n const now = new Date().toISOString();\n if (id === undefined) {\n const result = this.db.prepare(`INSERT INTO games (created_at, updated_at, elo, color, start_fen, fen, moves, status)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?)`).run(now, now, game.elo, game.color, game.startFen, game.fen, JSON.stringify(game.moves), game.status);\n return Number(result.lastInsertRowid);\n }\n this.db.prepare(`UPDATE games SET updated_at = ?, elo = ?, color = ?, start_fen = ?, fen = ?, moves = ?, status = ? WHERE id = ?`)\n .run(now, game.elo, game.color, game.startFen, game.fen, JSON.stringify(game.moves), game.status, id);\n return id;\n }\n\n list(): SavedGame[] {\n const rows = this.db.prepare('SELECT * FROM games ORDER BY updated_at DESC').all() as Array<Record<string, unknown>>;\n return rows.map(row => this.decode(row));\n }\n\n get(id: number): SavedGame | undefined {\n const row = this.db.prepare('SELECT * FROM games WHERE id = ?').get(id) as Record<string, unknown> | undefined;\n return row ? this.decode(row) : undefined;\n }\n\n close(): void { this.db.close(); }\n\n private decode(row: Record<string, unknown>): SavedGame {\n return {\n id: Number(row.id), createdAt: String(row.created_at), updatedAt: String(row.updated_at),\n elo: Number(row.elo), color: row.color === 'b' ? 'b' : 'w', startFen: String(row.start_fen), fen: String(row.fen),\n moves: JSON.parse(String(row.moves)) as string[], status: String(row.status),\n };\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["createInterface", "stdin", "stdout", "message", "move", "names", "body", "color", "require", "createRequire", "require", "createRequire", "stdout", "stdin", "stdout", "createInterface", "game", "elo", "listener"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zchess",
3
- "version": "0.1.6-alpha.0",
3
+ "version": "0.1.8-alpha.0",
4
4
  "type": "module",
5
5
  "engines": {
6
6
  "node": ">=22.13.0"