chesspal 0.3.4 → 0.3.6

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.
Files changed (104) hide show
  1. package/README.md +1 -0
  2. package/dist/cli/cli.js +10 -2
  3. package/dist/cli/command-line.js +17 -9
  4. package/dist/cli/icon.d.ts +2 -0
  5. package/dist/cli/icon.js +11 -1
  6. package/dist/commands/analysis/analyse.d.ts +2 -2
  7. package/dist/commands/analysis/analyse.js +3 -3
  8. package/dist/commands/answers/agents.d.ts +10 -2
  9. package/dist/commands/answers/agents.js +30 -7
  10. package/dist/commands/answers/index.d.ts +1 -1
  11. package/dist/commands/answers/index.js +1 -1
  12. package/dist/commands/answers/lines.js +3 -2
  13. package/dist/commands/answers/summary.d.ts +2 -1
  14. package/dist/commands/answers/view.d.ts +1 -1
  15. package/dist/commands/answers/view.js +2 -2
  16. package/dist/commands/game/look.d.ts +7 -3
  17. package/dist/commands/game/look.js +9 -4
  18. package/dist/commands/game/new.js +1 -1
  19. package/dist/commands/game/ponder.js +3 -3
  20. package/dist/commands/game/position.d.ts +2 -1
  21. package/dist/commands/game/position.js +9 -4
  22. package/dist/commands/game/status.d.ts +3 -1
  23. package/dist/commands/game/status.js +19 -9
  24. package/dist/commands/profiles/past-games.d.ts +7 -2
  25. package/dist/commands/profiles/past-games.js +26 -10
  26. package/dist/commands/talk/ai-say.js +1 -1
  27. package/dist/games/analysis.d.ts +7 -4
  28. package/dist/games/analysis.js +5 -3
  29. package/dist/games/index.d.ts +1 -1
  30. package/dist/games/index.js +1 -1
  31. package/dist/games/thoughts.d.ts +12 -4
  32. package/dist/games/thoughts.js +27 -10
  33. package/dist/home/index.d.ts +1 -0
  34. package/dist/home/index.js +1 -0
  35. package/dist/home/same-path.d.ts +2 -0
  36. package/dist/home/same-path.js +5 -0
  37. package/dist/host-files/host-files.js +8 -3
  38. package/dist/page/app/anchor.js +15 -11
  39. package/dist/page/app/app.js +30 -17
  40. package/dist/page/app/served.js +23 -36
  41. package/dist/page/app/watch.js +97 -0
  42. package/dist/page/avatars/torretta.css +108 -0
  43. package/dist/page/board/board.css +7 -6
  44. package/dist/page/board/marks.js +2 -2
  45. package/dist/page/board/pointer.js +2 -2
  46. package/dist/page/dialogs/analyses.js +9 -7
  47. package/dist/page/dialogs/rows.js +72 -0
  48. package/dist/page/dialogs/site-games.js +3 -1
  49. package/dist/page/dialogs/studied.js +11 -6
  50. package/dist/page/dialogs/study.js +2 -2
  51. package/dist/page/game/game.css +51 -10
  52. package/dist/page/game/move-list.js +7 -5
  53. package/dist/page/guide/en.md +1 -1
  54. package/dist/page/guide/it.md +1 -1
  55. package/dist/page/helps/helps.css +5 -5
  56. package/dist/page/helps/helps.js +3 -181
  57. package/dist/page/helps/rows.js +16 -0
  58. package/dist/page/helps/strategy.js +105 -0
  59. package/dist/page/helps/tactics.js +69 -0
  60. package/dist/page/layout/header.js +49 -6
  61. package/dist/page/layout/layout.css +17 -2
  62. package/dist/page/layout/window.js +4 -4
  63. package/dist/page/lead/lead.js +41 -4
  64. package/dist/page/sounds/sounds.js +1 -1
  65. package/dist/page/style.css +1 -0
  66. package/dist/page/talk/talk.css +0 -109
  67. package/dist/page/text.js +10 -0
  68. package/dist/page/theme.css +13 -0
  69. package/dist/profiles/profiles.js +5 -1
  70. package/dist/server/bell/bell.d.ts +0 -2
  71. package/dist/server/bell/bell.js +17 -7
  72. package/dist/server/bell/index.d.ts +1 -1
  73. package/dist/server/bell/index.js +1 -1
  74. package/dist/server/page/chat.d.ts +5 -1
  75. package/dist/server/page/chat.js +5 -1
  76. package/dist/server/page/game.js +18 -3
  77. package/dist/server/page/table.d.ts +2 -1
  78. package/dist/server/page/table.js +4 -2
  79. package/dist/server/page/update.d.ts +1 -1
  80. package/dist/server/page/update.js +4 -4
  81. package/dist/server/table/hosts/chats.d.ts +5 -0
  82. package/dist/server/table/hosts/chats.js +11 -4
  83. package/dist/server/table/hosts/play.d.ts +3 -1
  84. package/dist/server/table/hosts/play.js +17 -5
  85. package/dist/server/table/icon/index.d.ts +2 -0
  86. package/dist/server/table/icon/index.js +16 -2
  87. package/dist/server/table/index.d.ts +1 -1
  88. package/dist/server/table/index.js +1 -1
  89. package/dist/server/table/link.js +3 -1
  90. package/dist/server/table/table.js +2 -2
  91. package/dist/sites/index.d.ts +1 -1
  92. package/dist/sites/index.js +1 -1
  93. package/dist/sites/{chesscom.d.ts → ratings/chesscom.d.ts} +2 -2
  94. package/dist/sites/{chesscom.js → ratings/chesscom.js} +1 -1
  95. package/dist/sites/{choice.d.ts → ratings/choice.d.ts} +1 -1
  96. package/dist/sites/{choice.js → ratings/choice.js} +1 -1
  97. package/dist/sites/ratings/index.d.ts +1 -0
  98. package/dist/sites/ratings/index.js +2 -0
  99. package/dist/sites/{lichess.d.ts → ratings/lichess.d.ts} +2 -2
  100. package/dist/sites/{lichess.js → ratings/lichess.js} +1 -1
  101. package/dist/sites/{sites.d.ts → ratings/ratings.d.ts} +2 -2
  102. package/dist/sites/{sites.js → ratings/ratings.js} +1 -1
  103. package/instructions/start.md +1 -1
  104. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  // Chesspal's icon on the desktop and in the system's menu (D-104): it opens the table as `chesspal` alone does, with no console, on Windows, macOS and Linux.
2
2
  // The command line asks once a machine whether to put it there.
3
- import { existsSync, mkdirSync, readFileSync } from "node:fs";
3
+ import { existsSync, lstatSync, mkdirSync, readFileSync, rmSync } from "node:fs";
4
4
  import { hostname } from "node:os";
5
- import { join } from "node:path";
5
+ import { basename, join } from "node:path";
6
6
  import { fileURLToPath } from "node:url";
7
7
  import { writeAtomically } from "../../../games/index.js";
8
8
  import { tableFolder } from "../../../home/index.js";
@@ -46,6 +46,18 @@ export function noteIconMade(home, command, files, machine = hostname()) {
46
46
  const asked = notes.asked.includes(machine) ? notes.asked : [...notes.asked, machine];
47
47
  writeIconNotes(home, { asked, made: { ...notes.made, [machine]: { command: commandLine(command), files: [...files] } } });
48
48
  }
49
+ /** Takes Chesspal's icon off the desktop and the menu of this machine, the files noted when it was made: those it removed. */
50
+ export function removeIcons(home, machine = hostname()) {
51
+ const notes = iconNotes(home);
52
+ // Only Chesspal's own files, by their names, and links too, whose target the player may have thrown away already.
53
+ const removed = (notes.made[machine]?.files ?? []).filter((file) => iconName.test(basename(file)) && lstatSync(file, { throwIfNoEntry: false }) !== undefined);
54
+ // On macOS the icon is an application, a folder.
55
+ for (const file of removed) {
56
+ rmSync(file, { recursive: true, force: true });
57
+ }
58
+ writeIconNotes(home, { ...notes, made: Object.fromEntries(Object.entries(notes.made).filter(([name]) => name !== machine)) });
59
+ return removed;
60
+ }
49
61
  /**
50
62
  * Whether the icon made on this machine runs another Node or script than `command`, which a Node manager or an update may have taken away, and is still
51
63
  * there: then it is made again. One the player removed stays removed.
@@ -68,6 +80,8 @@ function writeIconNotes(home, notes) {
68
80
  mkdirSync(tableFolder(home), { recursive: true });
69
81
  writeAtomically(notesFile(home), `${JSON.stringify(notes, null, 2)}\n`);
70
82
  }
83
+ // The names of the files an icon is made of, on Windows, Linux and macOS: removing touches no other, whatever the notes say.
84
+ const iconName = /^chesspal\.(lnk|desktop|app)$/i;
71
85
  // The notes kept; none when the file is missing or cannot be read, which only asks again.
72
86
  function iconNotes(home) {
73
87
  const file = notesFile(home);
@@ -1,6 +1,6 @@
1
1
  export { appBrowser, openedAddress } from "./browser.ts";
2
2
  export { hostLaunch, isHostName, playHost, terminalChats } from "./hosts/index.ts";
3
- export { iconAsked, type IconCommand, iconCommand, type IconPlaces, iconToRemake, makeIcons, noteIconAsked, noteIconMade } from "./icon/index.ts";
3
+ export { iconAsked, type IconCommand, iconCommand, type IconPlaces, iconToRemake, makeIcons, noteIconAsked, noteIconMade, removeIcons } from "./icon/index.ts";
4
4
  export { noteFailure, openTable, processLauncher, type TableLauncher } from "./launch.ts";
5
5
  export { attachTable, tableToJoin } from "./link.ts";
6
6
  export { startTable, type Table, type TableTimes, tableTimes } from "./table.ts";
@@ -1,7 +1,7 @@
1
1
  // The table (D-104): the board page in a process of its own, started by `chesspal` alone, with no chat. Above server/page, which serves the page in either process.
2
2
  export { appBrowser, openedAddress } from "./browser.js";
3
3
  export { hostLaunch, isHostName, playHost, terminalChats } from "./hosts/index.js";
4
- export { iconAsked, iconCommand, iconToRemake, makeIcons, noteIconAsked, noteIconMade } from "./icon/index.js";
4
+ export { iconAsked, iconCommand, iconToRemake, makeIcons, noteIconAsked, noteIconMade, removeIcons } from "./icon/index.js";
5
5
  export { noteFailure, openTable, processLauncher } from "./launch.js";
6
6
  export { attachTable, tableToJoin } from "./link.js";
7
7
  export { startTable, tableTimes } from "./table.js";
@@ -198,14 +198,16 @@ function answerOf(status, text) {
198
198
  }
199
199
  return status === 200 ? jsonOf(text) : undefined;
200
200
  }
201
- /** What the chat says of itself as it attaches:its version, session and folder, its host, and whether its folder needs init again. */
201
+ /** What the chat says of itself as it attaches: its version, session and folder, its host, whether its folder needs init again, and the seat of its play. */
202
202
  function attachment(context) {
203
+ const seat = Number(process.env.CHESSPAL_SEAT);
203
204
  return {
204
205
  version,
205
206
  session: process.env.CLAUDE_CODE_SESSION_ID ?? null,
206
207
  folder: context.folder,
207
208
  host: context.host?.(),
208
209
  outdated: outdatedHostFiles(context.folder, context.platform).length > 0,
210
+ ...(Number.isInteger(seat) && seat > 0 ? { seat } : {}),
209
211
  };
210
212
  }
211
213
  /** What the chat saw, for the table's copy: the game and the position, the words it was given, its host, and who played as the AI (D-82, D-97). */
@@ -1,9 +1,9 @@
1
1
  // The table (D-104): the board page served in a process of its own, on a folder of the data folder that is one for every profile, which a chat attaches
2
2
  // to; it closes by itself once no browser has had the page open, and no chat been attached, for a while.
3
3
  import { request } from "node:http";
4
- import { tableFolder } from "../../home/index.js";
4
+ import { samePath, tableFolder } from "../../home/index.js";
5
5
  import { setUpHosts } from "../../host-files/index.js";
6
- import { pageAt, pagePorts, samePath } from "../bell/index.js";
6
+ import { pageAt, pagePorts } from "../bell/index.js";
7
7
  import { startPage } from "../page/index.js";
8
8
  /** Five minutes with no browser and no chat, looked at every fifteen seconds (D-104). */
9
9
  export const tableTimes = { idle: 5 * 60_000, every: 15_000 };
@@ -1,3 +1,3 @@
1
1
  export { isSiteGameName, pointsAtSite, readSiteGames, type SiteGame, siteGameName, type SiteGames, siteOfGameName } from "./games/index.ts";
2
+ export { readingsStale, readSites } from "./ratings/index.ts";
2
3
  export { answerTime, askSite, type Fetch } from "./request/index.ts";
3
- export { readingsStale, readSites } from "./sites.ts";
@@ -2,5 +2,5 @@
2
2
  // asked by a tool of the AI's (D-106); and their latest games there, which a tool lists too, to study one (D-110). Below the commands, beside the profiles,
3
3
  // whose types it fills. Its request asks npm too, for a newer Chesspal (D-108).
4
4
  export { isSiteGameName, pointsAtSite, readSiteGames, siteGameName, siteOfGameName } from "./games/index.js";
5
+ export { readingsStale, readSites } from "./ratings/index.js";
5
6
  export { answerTime, askSite } from "./request/index.js";
6
- export { readingsStale, readSites } from "./sites.js";
@@ -1,4 +1,4 @@
1
- import type { SiteReading } from "../profiles/index.ts";
2
- import { type Fetch } from "./request/index.ts";
1
+ import type { SiteReading } from "../../profiles/index.ts";
2
+ import { type Fetch } from "../request/index.ts";
3
3
  /** What Chess.com says of a name: undefined when it could not be reached. */
4
4
  export declare function chesscomReading(account: string, fetch: Fetch, signal: AbortSignal): Promise<SiteReading | undefined>;
@@ -1,5 +1,5 @@
1
+ import { askSite } from "../request/index.js";
1
2
  import { counted } from "./choice.js";
2
- import { askSite } from "./request/index.js";
3
3
  /** What Chess.com says of a name: undefined when it could not be reached. */
4
4
  export async function chesscomReading(account, fetch, signal) {
5
5
  const statistics = await askSite(`https://api.chess.com/pub/player/${encodeURIComponent(account.toLowerCase())}/stats`, fetch, signal);
@@ -1,4 +1,4 @@
1
- import { type Speed } from "../profiles/index.ts";
1
+ import { type Speed } from "../../profiles/index.ts";
2
2
  /** A site's rating at one speed, as it gives it: established once it is no longer provisional. */
3
3
  export interface Candidate {
4
4
  readonly value: number;
@@ -1,5 +1,5 @@
1
1
  // Which of a site's ratings counts (D-106): the rapid, and when it is missing or provisional the classical, then the blitz.
2
- import { speeds } from "../profiles/index.js";
2
+ import { speeds } from "../../profiles/index.js";
3
3
  /** The first established rating in the order the speeds count: none when every one is missing or provisional. */
4
4
  export function counted(at) {
5
5
  for (const speed of speeds) {
@@ -0,0 +1 @@
1
+ export { readingsStale, readSites } from "./ratings.ts";
@@ -0,0 +1,2 @@
1
+ // The player's public ratings on Lichess and Chess.com (D-105), read from the names in their profile, without a key; and which speed counts.
2
+ export { readingsStale, readSites } from "./ratings.js";
@@ -1,4 +1,4 @@
1
- import type { SiteReading } from "../profiles/index.ts";
2
- import { type Fetch } from "./request/index.ts";
1
+ import type { SiteReading } from "../../profiles/index.ts";
2
+ import { type Fetch } from "../request/index.ts";
3
3
  /** What Lichess says of a name: undefined when it could not be reached. */
4
4
  export declare function lichessReading(account: string, fetch: Fetch, signal: AbortSignal): Promise<SiteReading | undefined>;
@@ -1,5 +1,5 @@
1
+ import { askSite } from "../request/index.js";
1
2
  import { counted } from "./choice.js";
2
- import { askSite } from "./request/index.js";
3
3
  /** What Lichess says of a name: undefined when it could not be reached. */
4
4
  export async function lichessReading(account, fetch, signal) {
5
5
  const user = await askSite(`${address}/${encodeURIComponent(account)}`, fetch, signal);
@@ -1,5 +1,5 @@
1
- import type { Accounts, SiteReadings } from "../profiles/index.ts";
2
- import { type Fetch } from "./request/index.ts";
1
+ import type { Accounts, SiteReadings } from "../../profiles/index.ts";
2
+ import { type Fetch } from "../request/index.ts";
3
3
  /** What Lichess and Chess.com say now of the player's names there, at `now`; a site that cannot be reached keeps what it said before of the same name. */
4
4
  export declare function readSites(accounts: Accounts, fetch: Fetch, before: SiteReadings | undefined, now: Date): Promise<SiteReadings>;
5
5
  /** Whether the readings are of other names than the profile's now, or a site did not answer a while ago: they are read again then, whatever their age. */
@@ -1,6 +1,6 @@
1
+ import { answerTime } from "../request/index.js";
1
2
  import { chesscomReading } from "./chesscom.js";
2
3
  import { lichessReading } from "./lichess.js";
3
- import { answerTime } from "./request/index.js";
4
4
  /** What Lichess and Chess.com say now of the player's names there, at `now`; a site that cannot be reached keeps what it said before of the same name. */
5
5
  export async function readSites(accounts, fetch, before, now) {
6
6
  const signal = AbortSignal.timeout(answerTime);
@@ -1 +1 @@
1
- This folder is the player's chess table, and you are their opponent; Chesspal keeps the rules, the board, the clock and the games. In every chat, before you write anything, even to a greeting, call `instructions` and `status`; again after the conversation is summarized. Every move goes through Chesspal's tools: never keep the board in your head or invent a position.
1
+ This folder is the player's chess table, and you are their opponent; Chesspal keeps the rules, the board, the clock and the games. In every chat, before you write anything, even to a greeting, call `instructions` and `status`; again after the conversation is summarized. Every move goes through Chesspal's tools: never keep the board in your head or invent a position. Without them, tell the player plainly to reopen this chat in this folder and trust it; name no tool or setting.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chesspal",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "Play chess against an AI with a character, and learn with an AI coach: Chesspal keeps the rules, the board, the games and the memory; the AI plays, reasons and talks.",
5
5
  "type": "module",
6
6
  "bin": {