jev-chess 1.0.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.
Files changed (67) hide show
  1. package/ARCHITECTURE.md +148 -0
  2. package/README.md +109 -0
  3. package/dist/chessEngine.d.ts +36 -0
  4. package/dist/chessEngine.d.ts.map +1 -0
  5. package/dist/chessEngine.js +173 -0
  6. package/dist/chessEngine.js.map +1 -0
  7. package/dist/classicMatches.d.ts +50 -0
  8. package/dist/classicMatches.d.ts.map +1 -0
  9. package/dist/classicMatches.js +223 -0
  10. package/dist/classicMatches.js.map +1 -0
  11. package/dist/demo.d.ts +2 -0
  12. package/dist/demo.d.ts.map +1 -0
  13. package/dist/demo.js +142 -0
  14. package/dist/demo.js.map +1 -0
  15. package/dist/gameReviewer.d.ts +11 -0
  16. package/dist/gameReviewer.d.ts.map +1 -0
  17. package/dist/gameReviewer.js +89 -0
  18. package/dist/gameReviewer.js.map +1 -0
  19. package/dist/index.d.ts +9 -0
  20. package/dist/index.d.ts.map +1 -0
  21. package/dist/index.js +9 -0
  22. package/dist/index.js.map +1 -0
  23. package/dist/moveEvaluator.d.ts +11 -0
  24. package/dist/moveEvaluator.d.ts.map +1 -0
  25. package/dist/moveEvaluator.js +103 -0
  26. package/dist/moveEvaluator.js.map +1 -0
  27. package/dist/moveResolver.d.ts +15 -0
  28. package/dist/moveResolver.d.ts.map +1 -0
  29. package/dist/moveResolver.js +97 -0
  30. package/dist/moveResolver.js.map +1 -0
  31. package/dist/personaEngine.d.ts +15 -0
  32. package/dist/personaEngine.d.ts.map +1 -0
  33. package/dist/personaEngine.js +151 -0
  34. package/dist/personaEngine.js.map +1 -0
  35. package/dist/server.d.ts +2 -0
  36. package/dist/server.d.ts.map +1 -0
  37. package/dist/server.js +1490 -0
  38. package/dist/server.js.map +1 -0
  39. package/dist/typeSafeClient.d.ts +13 -0
  40. package/dist/typeSafeClient.d.ts.map +1 -0
  41. package/dist/typeSafeClient.js +336 -0
  42. package/dist/typeSafeClient.js.map +1 -0
  43. package/dist/types.d.ts +100 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +5 -0
  46. package/dist/types.js.map +1 -0
  47. package/dist/web/main.d.ts +2 -0
  48. package/dist/web/main.d.ts.map +1 -0
  49. package/dist/web/main.js +620 -0
  50. package/dist/web/main.js.map +1 -0
  51. package/package.json +35 -0
  52. package/public/app.js +45 -0
  53. package/public/index.html +790 -0
  54. package/src/chessEngine.ts +191 -0
  55. package/src/classicMatches.ts +291 -0
  56. package/src/demo.ts +160 -0
  57. package/src/gameReviewer.ts +113 -0
  58. package/src/index.ts +8 -0
  59. package/src/moveEvaluator.ts +122 -0
  60. package/src/moveResolver.ts +120 -0
  61. package/src/personaEngine.ts +193 -0
  62. package/src/server.ts +1509 -0
  63. package/src/typeSafeClient.ts +321 -0
  64. package/src/types.ts +118 -0
  65. package/src/web/main.ts +615 -0
  66. package/tests/chess.test.ts +206 -0
  67. package/tsconfig.json +21 -0
@@ -0,0 +1,148 @@
1
+ # Architectural Design: Chess Moves & Games with TypeSafe AI
2
+
3
+ ## 1. Executive Summary & Core Philosophy
4
+
5
+ Building chess software with AI has historically faced two opposite extremes:
6
+ 1. **Classical Chess Engines (Stockfish, Komodo):** Masterful at minimax tree search and bitboard physics, but opaque and purely numeric. A scalar evaluation like `+1.4` cannot explain *why* a move is stylistically brilliant, prophylactic, psychological, or intuitive.
7
+ 2. **Generative LLMs (System Two / Chatbots):** Prone to hallucinating illegal coordinates, moving through pieces, losing track of castling rights, and taking 2–5 seconds with high token costs.
8
+
9
+ **TypeSafe AI (System One / Jev)** introduces a third, superior paradigm: **AI-Powered Software**.
10
+
11
+ ```
12
+ ┌────────────────────────────────────────────────────────┐
13
+ │ DETERMINISTIC CODE │
14
+ │ • Board Physics & Move Legality (chess.js / bitboard)│
15
+ │ • FEN / SAN / PGN Parsing & Clock Management │
16
+ │ • Check, Checkmate & Draw Detection │
17
+ └───────────────────────────┬────────────────────────────┘
18
+ │ Structured State Context
19
+
20
+ ┌────────────────────────────────────────────────────────┐
21
+ │ TYPESAFE SYSTEM ONE (jev-latest) │
22
+ │ • Fast (~100ms) Semantic & Qualitative Judgments │
23
+ │ • Typed Primitives: Choice, Score, Noul │
24
+ │ • Calibrated Probabilities & Peaked Confidence │
25
+ │ • 100% Guaranteed Schema Conformance │
26
+ └───────────────────────────┬────────────────────────────┘
27
+ │ Typed Judgments
28
+
29
+ ┌────────────────────────────────────────────────────────┐
30
+ │ APPLICATION ORCHESTRATION │
31
+ │ • Natural Language Move Selection (Confidence-Gated) │
32
+ │ • Persona-Driven AI Opponents (Composite Scoring) │
33
+ │ • Dynamic Commentary Badges & Game Tension Tracking │
34
+ │ • Post-Game Blunder Diagnostics & Mistake Taxonomy │
35
+ └────────────────────────────────────────────────────────┘
36
+ ```
37
+
38
+ > **The Golden Rule:** Keep deterministic rules, execution, calculations, and side-effects in code. Insert System One where semantic understanding, natural language, and human common-sense judgment are needed.
39
+
40
+ ---
41
+
42
+ ## 2. Designing Chess Moves (The Atomic Level)
43
+
44
+ ### 2.1 State Representation
45
+ State is the context presented to Jev. In chess, raw board graphics or cryptic FEN strings alone lack the semantic relationships the model needs. We structure the state cleanly into typed JSON:
46
+
47
+ ```json
48
+ {
49
+ "user_intent": "Develop my knight to attack their e5 pawn",
50
+ "board": {
51
+ "turn": "white",
52
+ "move_number": 2,
53
+ "in_check": false,
54
+ "material_balance": "Equal",
55
+ "game_phase": "opening",
56
+ "fen": "rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq - 0 2"
57
+ },
58
+ "legal_moves": [
59
+ { "san": "Nf3", "description": "Knight on g1 moves to f3" },
60
+ { "san": "Nc3", "description": "Knight on b1 moves to c3" },
61
+ { "san": "d4", "description": "Pawn on d2 moves to d4" }
62
+ ]
63
+ }
64
+ ```
65
+
66
+ ### 2.2 Pattern 1: Move Intent Resolution ("Select Instead of Generate")
67
+ Traditional chatbot interfaces try to make LLMs generate algebraic notation directly from text (e.g. "play e4"), which fails when positions get complicated.
68
+ With TypeSafe, we use the **Select Instead of Generate** pattern:
69
+ 1. Code deterministically generates all legal moves in the current position.
70
+ 2. Jev selects from the candidate pool using `Choice`.
71
+ 3. If the user command is vague or illegal, Jev returns `none` or a low confidence score, triggering an interactive clarification prompt in code.
72
+
73
+ ```typescript
74
+ const response = await client.systemOne({
75
+ state,
76
+ questions: {
77
+ matched_move: choice(
78
+ "Which legal chess move in `legal_moves` best fulfills the player's command in `user_intent`?",
79
+ criteria
80
+ ),
81
+ },
82
+ });
83
+
84
+ // Confidence-Gated Ambiguity Resolution
85
+ if (response.answers.matched_move.choice === "none" || response.answers.matched_move.confidence < 0.6) {
86
+ promptUserForDisambiguation(response.answers.matched_move.probabilities);
87
+ } else {
88
+ engine.makeMove(response.answers.matched_move.choice);
89
+ }
90
+ ```
91
+
92
+ ### 2.3 Pattern 2: Multi-Dimensional Qualitative Assessment
93
+ To explain moves to humans or show real-time broadcast commentary, we ask **parallel atomic questions** over the same state:
94
+
95
+ | Dimension | Primitive | Levels / Criteria |
96
+ | :--- | :--- | :--- |
97
+ | **Tactical Sharpness** | `Score` (0-3) | 0: Quiet/prophylactic, 1: Solid consolidation, 2: Sharp tension, 3: Explosive sacrifice |
98
+ | **Strategic Theme** | `Choice` | `pawn_break`, `piece_activation`, `prophylaxis`, `tactical_strike`, `king_hunt`, `simplification` |
99
+ | **King Threat** | `Noul` (0.0-1.0) | Probability the move initiates a direct assault on the opposing monarch |
100
+ | **Psychological Pressure** | `Noul` (0.0-1.0) | Probability the move provokes tactical panic or forces narrow only-moves |
101
+
102
+ All 4 questions are evaluated in parallel in **one single network call (~100ms)**.
103
+
104
+ ---
105
+
106
+ ## 3. Designing Chess Games (The System Level)
107
+
108
+ ### 3.1 Pattern 3: Persona Opponents via Composite Scoring
109
+ How do you build AI opponents that play with the distinct personalities of Mikhail Tal, Tigran Petrosian, or Jose Raul Capablanca without training expensive models?
110
+
111
+ Use the **Composite Scoring Pattern**:
112
+ 1. For each candidate move, compute atomic scores:
113
+ - `aggression` (`Score` 0–3)
114
+ - `prophylaxis` (`Score` 0–3)
115
+ - `complexity` (`Score` 0–3)
116
+ - `material_greed` (`Noul` 0–1)
117
+ 2. Define client-side weight vectors for each persona:
118
+ - **Mikhail Tal (The Magician from Riga):**
119
+ $$\text{Score} = 0.45 \cdot \text{agg} - 0.15 \cdot \text{pro} + 0.50 \cdot \text{comp} - 0.20 \cdot \text{greed}$$
120
+ - **Tigran Petrosian (Iron Tigran):**
121
+ $$\text{Score} = 0.05 \cdot \text{agg} + 0.65 \cdot \text{pro} - 0.30 \cdot \text{comp} + 0.20 \cdot \text{greed}$$
122
+ - **José Raúl Capablanca (The Chess Machine):**
123
+ $$\text{Score} = 0.20 \cdot \text{agg} + 0.35 \cdot \text{pro} - 0.40 \cdot \text{comp} + 0.45 \cdot \text{greed}$$
124
+ 3. Code selects the move with the highest composite score.
125
+
126
+ > [!TIP]
127
+ > **Zero Inference Rerun:** If you want to make Mikhail Tal 15% more wild or Petrosian 10% more cautious, you simply adjust the weights in client code. The underlying model judgments remain reusable and unchanged.
128
+
129
+ ### 3.2 Pattern 4: Post-Game Blunder & Tactical Review (The Cascade Pattern)
130
+ When an evaluation drops or a blunder occurs, traditional engines output a cold numeric penalty (`-4.2`). TypeSafe runs a diagnostic cascade:
131
+ - `Choice(mistake_archetype)`:
132
+ - `tactical_blindness` (missed a fork, pin, skewer)
133
+ - `poisoned_pawn_greed` (grabbed pawns while king was exposed)
134
+ - `over_extension` (pushed pawns without support)
135
+ - `passive_concession` (yielded tempo and space)
136
+ - `king_safety_negligence` (compromised shelter)
137
+ - `Score(defensive_difficulty)`:
138
+ - 0: Simple defense $\rightarrow$ 3: Hopeless human defense
139
+ - Code maps the typed diagnosis directly into actionable coaching advice.
140
+
141
+ ---
142
+
143
+ ## 4. Verification & Testing Standards
144
+
145
+ All move selection and game orchestration pipelines must obey three non-negotiable guarantees:
146
+ 1. **Zero Illegal Moves:** Every move presented to or selected by TypeSafe originates from the deterministic legal move generator.
147
+ 2. **Deterministic Schema Safety:** No regex parsing of LLM markdown or JSON extraction blocks. System One returns typed fields directly.
148
+ 3. **Graceful Degraded Mode:** If network connection or API keys are absent, the system falls back to calibrated simulation while preserving identical schemas.
package/README.md ADDED
@@ -0,0 +1,109 @@
1
+ # jev-chess
2
+
3
+ Chess moves, evaluations, persona opponents, and game classification using TypeSafe AI System One models.
4
+
5
+ ```bash
6
+ npm install jev-chess
7
+ ```
8
+
9
+ ## Quick start
10
+
11
+ ```ts
12
+ import { ChessEngine, MoveResolver, MoveEvaluator, PersonaEngine } from "jev-chess";
13
+
14
+ const engine = new ChessEngine();
15
+ const resolver = new MoveResolver();
16
+ const evaluator = new MoveEvaluator();
17
+ const personas = new PersonaEngine();
18
+
19
+ // Natural language intent -> verified legal move
20
+ const { matchedMove } = await resolver.resolveIntent(engine, "Develop knight to attack center");
21
+ const move = engine.makeMove(matchedMove.san);
22
+
23
+ // Parallel System One evaluation
24
+ const evalResult = await evaluator.evaluateMove(engine, move);
25
+ console.log(`${move.san}: ${evalResult.commentaryBadge} (Sharpness: ${evalResult.tacticalSharpness.score}/3.0)`);
26
+
27
+ // Opponent response via composite scoring
28
+ const { selectedMove, rationale } = await personas.selectMove(engine, "tal");
29
+ engine.makeMove(selectedMove.san);
30
+ console.log(`Tal plays ${selectedMove.san}: ${rationale}`);
31
+ ```
32
+
33
+ `resolveIntent()` maps natural language to verified legal moves via `Choice`. `evaluateMove()` assesses sharpness, strategic themes, and king risk in parallel. `selectMove()` weighs candidates against persona archetypes. That's the whole loop.
34
+
35
+ ## Natural language move intent
36
+
37
+ ```ts
38
+ const { matchedMove, confidence, alternativeCandidates } = await resolver.resolveIntent(
39
+ engine,
40
+ "Castle kingside to safety"
41
+ );
42
+
43
+ if (matchedMove && confidence > 0.6) {
44
+ engine.makeMove(matchedMove.san);
45
+ }
46
+ ```
47
+
48
+ Resolves ambiguous instructions against verified legal moves instead of generating coordinates from scratch. If confidence falls below threshold, it returns candidate alternatives rather than hallucinating illegal squares.
49
+
50
+ ## Parallel move evaluation
51
+
52
+ ```ts
53
+ const evaluation = await evaluator.evaluateMove(engine, move);
54
+
55
+ // evaluation.tacticalSharpness -> Score (0.0 to 3.0)
56
+ // evaluation.strategicTheme -> Choice (pawn_break, tactical_strike, prophylaxis, etc.)
57
+ // evaluation.kingAttackRisk -> Noul (0.0 to 1.0 probability)
58
+ // evaluation.commentaryBadge -> "Sharp Tactical Clash"
59
+ ```
60
+
61
+ A single `systemOne()` call evaluates candidate moves across four orthogonal dimensions simultaneously. Deterministic code synthesizes the results into human-readable commentary without asking an LLM to generate prose.
62
+
63
+ ## Persona AI opponents
64
+
65
+ ```ts
66
+ const decision = await personas.selectMove(engine, "tal");
67
+ // or "petrosian", "capablanca", "coffeehouse"
68
+ ```
69
+
70
+ Personas are client-side weight vectors over atomic System One dimensions:
71
+
72
+ - **Tal**: Heavy weight on tactical sharpness, king attack, and psychological pressure
73
+ - **Petrosian**: Dominant prophylaxis and king safety weights
74
+ - **Capablanca**: Prioritizes simplification and clear piece coordination
75
+ - **Coffeehouse**: Romantic gambiteer favoring king assault and complications
76
+
77
+ ## Historic game classification
78
+
79
+ ```ts
80
+ import { ClassicMatchStudio, CLASSIC_MATCHES } from "jev-chess";
81
+
82
+ const studio = new ClassicMatchStudio();
83
+ const report = await studio.classifyMatch(CLASSIC_MATCHES[0]);
84
+
85
+ console.log(report.archetype); // "ROMANTIC SWASHBUCKLER"
86
+ console.log(report.aestheticBrilliance); // { score: 2.9, level: "Immortal artistic masterpiece..." }
87
+ console.log(report.turningPoint); // { moveNumber: 20, san: "Ke2", ... }
88
+ ```
89
+
90
+ Classifies full games into historical archetypes, detects turning points, verifies sacrifices, and generates structural tension breakdowns.
91
+
92
+ ## Studio & demo
93
+
94
+ ```bash
95
+ npm run demo # Interactive terminal showcase
96
+ npm run serve # Browser studio on http://localhost:3333
97
+ ```
98
+
99
+ Interactive studio with board replay, real-time move intelligence, dynamic API key configuration, and classic match recreations.
100
+
101
+ ## Related
102
+
103
+ - [TypeSafe AI](https://typesafe.ai) — Small units of AI intelligence as programming primitives
104
+ - [TypeSafe SDK](https://github.com/typesafe-ai/typesafe-sdk) — Official TypeScript SDK
105
+ - [Architecture Manifesto](./ARCHITECTURE.md) — Architectural pattern for TypeSafe chess software
106
+
107
+ ## License
108
+
109
+ MIT © [Hemanth.HM](https://h3manth.com)
@@ -0,0 +1,36 @@
1
+ import { Chess } from "chess.js";
2
+ import type { AnnotatedMove, BoardContext, GamePhase, MaterialBalance } from "./types.js";
3
+ export declare class ChessEngine {
4
+ chess: Chess;
5
+ constructor(fen?: string);
6
+ reset(): void;
7
+ load(fen: string): boolean;
8
+ fen(): string;
9
+ turn(): "white" | "black";
10
+ isCheck(): boolean;
11
+ isGameOver(): boolean;
12
+ history(): string[];
13
+ /**
14
+ * Generates all legal moves in the current position, richly annotated with semantic facts.
15
+ * This is 100% deterministic code.
16
+ */
17
+ getAnnotatedMoves(): AnnotatedMove[];
18
+ /**
19
+ * Calculates material balance between white and black.
20
+ */
21
+ getMaterialBalance(): MaterialBalance;
22
+ /**
23
+ * Deterministically infers game phase based on remaining major/minor pieces and move number.
24
+ */
25
+ getGamePhase(): GamePhase;
26
+ /**
27
+ * Creates the complete structured context representing the board.
28
+ * This matches TypeSafe's principle: provide clear, structured JSON state.
29
+ */
30
+ getBoardContext(): BoardContext;
31
+ /**
32
+ * Deterministically applies a move in SAN (Standard Algebraic Notation).
33
+ */
34
+ makeMove(sanOrUci: string): AnnotatedMove | null;
35
+ }
36
+ //# sourceMappingURL=chessEngine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chessEngine.d.ts","sourceRoot":"","sources":["../src/chessEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAiC,MAAM,UAAU,CAAC;AAChE,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAoB1F,qBAAa,WAAW;IACf,KAAK,EAAE,KAAK,CAAC;IAEpB,YAAY,GAAG,CAAC,EAAE,MAAM,EAEvB;IAEM,KAAK,IAAI,IAAI,CAEnB;IAEM,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOhC;IAEM,GAAG,IAAI,MAAM,CAEnB;IAEM,IAAI,IAAI,OAAO,GAAG,OAAO,CAE/B;IAEM,OAAO,IAAI,OAAO,CAExB;IAEM,UAAU,IAAI,OAAO,CAE3B;IAEM,OAAO,IAAI,MAAM,EAAE,CAEzB;IAED;;;OAGG;IACI,iBAAiB,IAAI,aAAa,EAAE,CAiC1C;IAED;;OAEG;IACI,kBAAkB,IAAI,eAAe,CAuB3C;IAED;;OAEG;IACI,YAAY,IAAI,SAAS,CAuB/B;IAED;;;OAGG;IACI,eAAe,IAAI,YAAY,CAcrC;IAED;;OAEG;IACI,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAUtD;CACF"}
@@ -0,0 +1,173 @@
1
+ import { Chess } from "chess.js";
2
+ const PIECE_NAMES = {
3
+ p: "pawn",
4
+ n: "knight",
5
+ b: "bishop",
6
+ r: "rook",
7
+ q: "queen",
8
+ k: "king",
9
+ };
10
+ const PIECE_VALUES = {
11
+ p: 1,
12
+ n: 3,
13
+ b: 3,
14
+ r: 5,
15
+ q: 9,
16
+ k: 0,
17
+ };
18
+ export class ChessEngine {
19
+ chess;
20
+ constructor(fen) {
21
+ this.chess = new Chess(fen);
22
+ }
23
+ reset() {
24
+ this.chess.reset();
25
+ }
26
+ load(fen) {
27
+ try {
28
+ this.chess.load(fen);
29
+ return true;
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ fen() {
36
+ return this.chess.fen();
37
+ }
38
+ turn() {
39
+ return this.chess.turn() === "w" ? "white" : "black";
40
+ }
41
+ isCheck() {
42
+ return this.chess.inCheck();
43
+ }
44
+ isGameOver() {
45
+ return this.chess.isGameOver();
46
+ }
47
+ history() {
48
+ return this.chess.history();
49
+ }
50
+ /**
51
+ * Generates all legal moves in the current position, richly annotated with semantic facts.
52
+ * This is 100% deterministic code.
53
+ */
54
+ getAnnotatedMoves() {
55
+ const rawMoves = this.chess.moves({ verbose: true });
56
+ return rawMoves.map((m) => {
57
+ const pieceName = PIECE_NAMES[m.piece] ?? m.piece;
58
+ const isCastling = m.san === "O-O" || m.san === "O-O-O";
59
+ const isCapture = Boolean(m.captured);
60
+ const capturedName = m.captured ? PIECE_NAMES[m.captured] : undefined;
61
+ let description = `${pieceName} moves from ${m.from} to ${m.to}`;
62
+ if (isCastling) {
63
+ description = m.san === "O-O" ? "Kingside castle" : "Queenside castle";
64
+ }
65
+ else if (isCapture) {
66
+ description = `${pieceName} on ${m.from} captures ${capturedName} on ${m.to}`;
67
+ }
68
+ if (m.san.includes("+")) {
69
+ description += " with check";
70
+ }
71
+ else if (m.san.includes("#")) {
72
+ description += " with checkmate!";
73
+ }
74
+ return {
75
+ san: m.san,
76
+ from: m.from,
77
+ to: m.to,
78
+ piece: pieceName,
79
+ color: m.color === "w" ? "white" : "black",
80
+ isCapture,
81
+ capturedPiece: capturedName,
82
+ isCheck: m.san.includes("+") || m.san.includes("#"),
83
+ isCastling,
84
+ description,
85
+ };
86
+ });
87
+ }
88
+ /**
89
+ * Calculates material balance between white and black.
90
+ */
91
+ getMaterialBalance() {
92
+ const board = this.chess.board();
93
+ let whiteScore = 0;
94
+ let blackScore = 0;
95
+ for (const row of board) {
96
+ for (const square of row) {
97
+ if (!square)
98
+ continue;
99
+ const val = PIECE_VALUES[square.type];
100
+ if (square.color === "w")
101
+ whiteScore += val;
102
+ else
103
+ blackScore += val;
104
+ }
105
+ }
106
+ const diff = whiteScore - blackScore;
107
+ let description = "Material is exactly equal";
108
+ if (diff > 0) {
109
+ description = `White is up +${diff} point${diff > 1 ? "s" : ""}`;
110
+ }
111
+ else if (diff < 0) {
112
+ description = `Black is up +${Math.abs(diff)} point${Math.abs(diff) > 1 ? "s" : ""}`;
113
+ }
114
+ return { whiteScore, blackScore, diff, description };
115
+ }
116
+ /**
117
+ * Deterministically infers game phase based on remaining major/minor pieces and move number.
118
+ */
119
+ getGamePhase() {
120
+ const board = this.chess.board();
121
+ let totalPieces = 0;
122
+ let queenCount = 0;
123
+ for (const row of board) {
124
+ for (const square of row) {
125
+ if (!square)
126
+ continue;
127
+ if (square.type !== "p" && square.type !== "k") {
128
+ totalPieces++;
129
+ if (square.type === "q")
130
+ queenCount++;
131
+ }
132
+ }
133
+ }
134
+ const moveCount = this.chess.history().length;
135
+ if (moveCount < 16 && totalPieces >= 12) {
136
+ return "opening";
137
+ }
138
+ if (totalPieces <= 6 || queenCount === 0) {
139
+ return "endgame";
140
+ }
141
+ return "middlegame";
142
+ }
143
+ /**
144
+ * Creates the complete structured context representing the board.
145
+ * This matches TypeSafe's principle: provide clear, structured JSON state.
146
+ */
147
+ getBoardContext() {
148
+ const history = this.chess.history();
149
+ const recentHistory = history.slice(-6);
150
+ return {
151
+ fen: this.chess.fen(),
152
+ turn: this.turn(),
153
+ moveNumber: Math.floor(history.length / 2) + 1,
154
+ inCheck: this.isCheck(),
155
+ materialBalance: this.getMaterialBalance(),
156
+ gamePhase: this.getGamePhase(),
157
+ recentHistory,
158
+ candidateMoves: this.getAnnotatedMoves(),
159
+ };
160
+ }
161
+ /**
162
+ * Deterministically applies a move in SAN (Standard Algebraic Notation).
163
+ */
164
+ makeMove(sanOrUci) {
165
+ const candidate = this.getAnnotatedMoves().find((m) => m.san === sanOrUci || `${m.from}${m.to}` === sanOrUci);
166
+ if (!candidate) {
167
+ return null;
168
+ }
169
+ this.chess.move(candidate.san);
170
+ return candidate;
171
+ }
172
+ }
173
+ //# sourceMappingURL=chessEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chessEngine.js","sourceRoot":"","sources":["../src/chessEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,50 @@
1
+ export interface ClassicMatch {
2
+ id: string;
3
+ title: string;
4
+ white: string;
5
+ black: string;
6
+ year: number;
7
+ event: string;
8
+ result: "1-0" | "0-1" | "1/2-1/2";
9
+ eco: string;
10
+ opening: string;
11
+ description: string;
12
+ moves: string[];
13
+ keyMoveIndex: number;
14
+ }
15
+ export interface MatchClassification {
16
+ matchId: string;
17
+ title: string;
18
+ archetype: string;
19
+ aestheticBrilliance: {
20
+ score: number;
21
+ level: string;
22
+ confidence: number;
23
+ };
24
+ overallSharpness: {
25
+ score: number;
26
+ level: string;
27
+ };
28
+ hasDecisiveSacrifice: boolean;
29
+ turningPoint: {
30
+ moveNumber: number;
31
+ san: string;
32
+ annotation: string;
33
+ };
34
+ strategicBreakdown: {
35
+ tacticalStrikesPct: number;
36
+ pawnBreaksPct: number;
37
+ prophylaxisPct: number;
38
+ pieceActivationPct: number;
39
+ };
40
+ verdict: string;
41
+ }
42
+ export declare const CLASSIC_MATCHES: ClassicMatch[];
43
+ export declare class ClassicMatchStudio {
44
+ private get client();
45
+ /**
46
+ * Classifies a classic chess match using TypeSafe System One.
47
+ */
48
+ classifyMatch(match: ClassicMatch): Promise<MatchClassification>;
49
+ }
50
+ //# sourceMappingURL=classicMatches.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classicMatches.d.ts","sourceRoot":"","sources":["../src/classicMatches.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,SAAS,CAAC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,gBAAgB,EAAE;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;IACF,oBAAoB,EAAE,OAAO,CAAC;IAC9B,YAAY,EAAE;QACZ,UAAU,EAAE,MAAM,CAAC;QACnB,GAAG,EAAE,MAAM,CAAC;QACZ,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,kBAAkB,EAAE;QAClB,kBAAkB,EAAE,MAAM,CAAC;QAC3B,aAAa,EAAE,MAAM,CAAC;QACtB,cAAc,EAAE,MAAM,CAAC;QACvB,kBAAkB,EAAE,MAAM,CAAC;KAC5B,CAAC;IACF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,eAAe,EAAE,YAAY,EAmHzC,CAAC;AAuBF,qBAAa,kBAAkB;IAC7B,OAAO,KAAK,MAAM,GAEjB;IAED;;OAEG;IACU,aAAa,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAiG5E;CACF"}