@bendyline/gilde 0.1.7 → 0.1.9

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 (116) hide show
  1. package/README.md +19 -0
  2. package/data/chat-models/de/deepseek-v4-flash-284b-mxfp4/manifest.json +119 -0
  3. package/data/chat-models/de/deepseek-v4-flash-284b-mxfp4/versions/1.0.0/manifest.json +25 -0
  4. package/data/chat-models/de/deepseek-v4-flash-284b-q2/manifest.json +58 -12
  5. package/data/chat-models/de/deepseek-v4-flash-284b-q2/versions/1.1.0/manifest.json +25 -0
  6. package/data/chat-models/de/deepseek-v4-flash-284b-q2q4/manifest.json +120 -0
  7. package/data/chat-models/de/deepseek-v4-flash-284b-q2q4/versions/1.0.0/manifest.json +25 -0
  8. package/data/chat-models/de/deepseek-v4-flash-284b-q4/manifest.json +53 -7
  9. package/data/chat-models/de/deepseek-v4-flash-284b-q4/versions/1.1.0/manifest.json +223 -0
  10. package/data/chat-models/ge/gemma4-e4b-q4/manifest.json +7 -1
  11. package/data/chat-models/index.json +1 -1
  12. package/data/project-types/ca/caregiving-binder/versions/1.0.1/about.md +8 -0
  13. package/data/project-types/ca/caregiving-binder/versions/1.0.1/care.json +4 -0
  14. package/data/project-types/ca/caregiving-binder/versions/1.0.1/manifest.json +177 -0
  15. package/data/project-types/ca/caregiving-binder/versions/1.0.1/meds.json +8 -0
  16. package/data/project-types/ca/caregiving-binder/versions/1.0.1/mission.md +8 -0
  17. package/data/project-types/ca/caregiving-binder/versions/1.0.1/pages/dashboard/index.html +167 -0
  18. package/data/project-types/ch/checkers/versions/1.1.2/about.md +9 -0
  19. package/data/project-types/ch/checkers/versions/1.1.2/game.json +77 -0
  20. package/data/project-types/ch/checkers/versions/1.1.2/manifest.json +166 -0
  21. package/data/project-types/ch/checkers/versions/1.1.2/mission.md +9 -0
  22. package/data/project-types/ch/checkers/versions/1.1.2/pages/board/index.html +1091 -0
  23. package/data/project-types/ch/chess/versions/1.0.2/about.md +9 -0
  24. package/data/project-types/ch/chess/versions/1.0.2/game.json +127 -0
  25. package/data/project-types/ch/chess/versions/1.0.2/manifest.json +180 -0
  26. package/data/project-types/ch/chess/versions/1.0.2/mission.md +8 -0
  27. package/data/project-types/ch/chess/versions/1.0.2/pages/board/index.html +627 -0
  28. package/data/project-types/ch/chess/versions/1.0.3/about.md +9 -0
  29. package/data/project-types/ch/chess/versions/1.0.3/game.json +127 -0
  30. package/data/project-types/ch/chess/versions/1.0.3/manifest.json +180 -0
  31. package/data/project-types/ch/chess/versions/1.0.3/mission.md +8 -0
  32. package/data/project-types/ch/chess/versions/1.0.3/pages/board/index.html +769 -0
  33. package/data/project-types/de/design-scheme/versions/1.0.1/about.md +6 -0
  34. package/data/project-types/de/design-scheme/versions/1.0.1/manifest.json +69 -0
  35. package/data/project-types/de/design-scheme/versions/1.0.1/mission.md +3 -0
  36. package/data/project-types/de/design-scheme/versions/1.0.1/pages/gallery/index.html +105 -0
  37. package/data/project-types/de/design-scheme/versions/1.0.1/schemes/index.json +9 -0
  38. package/data/project-types/de/design-scheme/versions/1.0.1/schemes/warm-dusk.json +4 -0
  39. package/data/project-types/ev/event-planner/versions/1.0.1/about.md +7 -0
  40. package/data/project-types/ev/event-planner/versions/1.0.1/budget.json +5 -0
  41. package/data/project-types/ev/event-planner/versions/1.0.1/guests.json +10 -0
  42. package/data/project-types/ev/event-planner/versions/1.0.1/manifest.json +170 -0
  43. package/data/project-types/ev/event-planner/versions/1.0.1/mission.md +6 -0
  44. package/data/project-types/ev/event-planner/versions/1.0.1/pages/dashboard/index.html +186 -0
  45. package/data/project-types/fi/fitness-coach/versions/1.0.1/about.md +7 -0
  46. package/data/project-types/fi/fitness-coach/versions/1.0.1/manifest.json +125 -0
  47. package/data/project-types/fi/fitness-coach/versions/1.0.1/mission.md +7 -0
  48. package/data/project-types/fi/fitness-coach/versions/1.0.1/pages/dashboard/index.html +172 -0
  49. package/data/project-types/fi/fitness-coach/versions/1.0.1/training.json +6 -0
  50. package/data/project-types/fl/flashcards/versions/1.0.1/about.md +8 -0
  51. package/data/project-types/fl/flashcards/versions/1.0.1/deck.json +7 -0
  52. package/data/project-types/fl/flashcards/versions/1.0.1/manifest.json +167 -0
  53. package/data/project-types/fl/flashcards/versions/1.0.1/mission.md +6 -0
  54. package/data/project-types/fl/flashcards/versions/1.0.1/pages/review/index.html +396 -0
  55. package/data/project-types/fr/freelance-office/versions/1.0.1/about.md +6 -0
  56. package/data/project-types/fr/freelance-office/versions/1.0.1/invoices.json +9 -0
  57. package/data/project-types/fr/freelance-office/versions/1.0.1/manifest.json +142 -0
  58. package/data/project-types/fr/freelance-office/versions/1.0.1/mission.md +6 -0
  59. package/data/project-types/fr/freelance-office/versions/1.0.1/pages/dashboard/index.html +157 -0
  60. package/data/project-types/fu/fundraiser-hq/versions/1.0.1/about.md +7 -0
  61. package/data/project-types/fu/fundraiser-hq/versions/1.0.1/donations.json +7 -0
  62. package/data/project-types/fu/fundraiser-hq/versions/1.0.1/manifest.json +126 -0
  63. package/data/project-types/fu/fundraiser-hq/versions/1.0.1/mission.md +6 -0
  64. package/data/project-types/fu/fundraiser-hq/versions/1.0.1/pages/dashboard/index.html +160 -0
  65. package/data/project-types/go/go/versions/1.0.1/about.md +9 -0
  66. package/data/project-types/go/go/versions/1.0.1/game.json +103 -0
  67. package/data/project-types/go/go/versions/1.0.1/manifest.json +166 -0
  68. package/data/project-types/go/go/versions/1.0.1/mission.md +8 -0
  69. package/data/project-types/go/go/versions/1.0.1/pages/board/index.html +778 -0
  70. package/data/project-types/ho/household-budget/versions/1.0.1/about.md +6 -0
  71. package/data/project-types/ho/household-budget/versions/1.0.1/ledger.json +5 -0
  72. package/data/project-types/ho/household-budget/versions/1.0.1/manifest.json +163 -0
  73. package/data/project-types/ho/household-budget/versions/1.0.1/mission.md +6 -0
  74. package/data/project-types/ho/household-budget/versions/1.0.1/pages/dashboard/index.html +233 -0
  75. package/data/project-types/ho/household-manual/versions/1.0.1/about.md +7 -0
  76. package/data/project-types/ho/household-manual/versions/1.0.1/manifest.json +152 -0
  77. package/data/project-types/ho/household-manual/versions/1.0.1/mission.md +8 -0
  78. package/data/project-types/ho/household-manual/versions/1.0.1/pages/dashboard/index.html +157 -0
  79. package/data/project-types/ho/household-manual/versions/1.0.1/systems.json +8 -0
  80. package/data/project-types/index.json +1 -1
  81. package/data/project-types/jo/job-hunt/versions/1.0.1/about.md +10 -0
  82. package/data/project-types/jo/job-hunt/versions/1.0.1/activity.json +4 -0
  83. package/data/project-types/jo/job-hunt/versions/1.0.1/manifest.json +212 -0
  84. package/data/project-types/jo/job-hunt/versions/1.0.1/mission.md +9 -0
  85. package/data/project-types/jo/job-hunt/versions/1.0.1/pages/dashboard/index.html +327 -0
  86. package/data/project-types/jo/job-hunt/versions/1.0.1/pipeline.json +6 -0
  87. package/data/project-types/la/language-trainer/versions/1.0.1/about.md +6 -0
  88. package/data/project-types/la/language-trainer/versions/1.0.1/manifest.json +79 -0
  89. package/data/project-types/la/language-trainer/versions/1.0.1/mission.md +4 -0
  90. package/data/project-types/la/language-trainer/versions/1.0.1/pages/dashboard/index.html +153 -0
  91. package/data/project-types/la/language-trainer/versions/1.0.1/progress.json +7 -0
  92. package/data/project-types/li/life-binder/versions/1.0.1/about.md +7 -0
  93. package/data/project-types/li/life-binder/versions/1.0.1/documents.json +145 -0
  94. package/data/project-types/li/life-binder/versions/1.0.1/manifest.json +137 -0
  95. package/data/project-types/li/life-binder/versions/1.0.1/mission.md +7 -0
  96. package/data/project-types/li/life-binder/versions/1.0.1/pages/dashboard/index.html +147 -0
  97. package/data/project-types/me/meal-planner/versions/1.0.1/about.md +6 -0
  98. package/data/project-types/me/meal-planner/versions/1.0.1/manifest.json +159 -0
  99. package/data/project-types/me/meal-planner/versions/1.0.1/menu.json +5 -0
  100. package/data/project-types/me/meal-planner/versions/1.0.1/mission.md +5 -0
  101. package/data/project-types/me/meal-planner/versions/1.0.1/pages/dashboard/index.html +152 -0
  102. package/data/project-types/me/meal-planner/versions/1.0.1/pantry.json +9 -0
  103. package/data/project-types/no/novel-writing-room/versions/1.0.1/about.md +7 -0
  104. package/data/project-types/no/novel-writing-room/versions/1.0.1/chapters.json +10 -0
  105. package/data/project-types/no/novel-writing-room/versions/1.0.1/manifest.json +157 -0
  106. package/data/project-types/no/novel-writing-room/versions/1.0.1/mission.md +7 -0
  107. package/data/project-types/no/novel-writing-room/versions/1.0.1/pages/dashboard/index.html +165 -0
  108. package/data/project-types/no/novel-writing-room/versions/1.0.1/sessions.json +6 -0
  109. package/data/project-types/tr/trip-planner/versions/1.0.1/about.md +7 -0
  110. package/data/project-types/tr/trip-planner/versions/1.0.1/journal.json +4 -0
  111. package/data/project-types/tr/trip-planner/versions/1.0.1/manifest.json +193 -0
  112. package/data/project-types/tr/trip-planner/versions/1.0.1/mission.md +4 -0
  113. package/data/project-types/tr/trip-planner/versions/1.0.1/packing.json +8 -0
  114. package/data/project-types/tr/trip-planner/versions/1.0.1/pages/dashboard/index.html +215 -0
  115. package/data/project-types/tr/trip-planner/versions/1.0.1/trip.json +7 -0
  116. package/package.json +5 -2
@@ -0,0 +1,627 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>Chess</title>
7
+ <style>
8
+ :root {
9
+ color-scheme: light dark;
10
+ --bg: #faf7f2;
11
+ --card: #fff;
12
+ --ink: #2b2620;
13
+ --muted: #7a7166;
14
+ --accent: #9a5928;
15
+ --track: #e8dfd2;
16
+ --sq-light: #efe4d1;
17
+ --sq-dark: #9a7455;
18
+ --sq-hint: #557a5b;
19
+ --frame-a: #8d694d;
20
+ --frame-b: #4d3424;
21
+ --frame-edge: #342116;
22
+ --white-piece-face: #fff8e8;
23
+ --white-piece-side: #a8987e;
24
+ --white-piece-edge: #594b3c;
25
+ --white-piece-highlight: rgba(255, 255, 255, 0.9);
26
+ --black-piece-face: #302a24;
27
+ --black-piece-side: #100d0a;
28
+ --black-piece-edge: #090705;
29
+ --black-piece-highlight: rgba(255, 255, 255, 0.2);
30
+ --last-move: rgba(241, 184, 84, 0.42);
31
+ }
32
+ @media (prefers-color-scheme: dark) {
33
+ :root {
34
+ --bg: #1c1a17;
35
+ --card: #262320;
36
+ --ink: #efe9e0;
37
+ --muted: #a59a8c;
38
+ --accent: #e0894a;
39
+ --track: #3a352f;
40
+ --sq-light: #b8a58b;
41
+ --sq-dark: #674a35;
42
+ --sq-hint: #6f9b70;
43
+ --frame-a: #74543d;
44
+ --frame-b: #34241a;
45
+ --frame-edge: #1b120d;
46
+ --white-piece-face: #fff5dc;
47
+ --white-piece-side: #9d8b70;
48
+ --white-piece-edge: #4b3d30;
49
+ --white-piece-highlight: rgba(255, 255, 255, 0.88);
50
+ --black-piece-face: #29221c;
51
+ --black-piece-side: #0b0907;
52
+ --black-piece-edge: #050403;
53
+ --black-piece-highlight: rgba(255, 255, 255, 0.18);
54
+ --last-move: rgba(236, 159, 85, 0.38);
55
+ }
56
+ }
57
+ * { box-sizing: border-box; }
58
+ body {
59
+ margin: 0;
60
+ padding: 1.25rem;
61
+ background: var(--bg);
62
+ color: var(--ink);
63
+ font: 15px/1.5 system-ui, -apple-system, 'Segoe UI', sans-serif;
64
+ }
65
+ main { max-width: 760px; margin: 0 auto; }
66
+ header {
67
+ display: flex;
68
+ align-items: baseline;
69
+ justify-content: space-between;
70
+ gap: 0.75rem;
71
+ flex-wrap: wrap;
72
+ }
73
+ h1 {
74
+ margin: 0;
75
+ font-family: Georgia, 'PT Serif', 'Times New Roman', serif;
76
+ font-size: 1.35rem;
77
+ }
78
+ button { font: inherit; }
79
+ .newgame,
80
+ .passive-button {
81
+ border: 1px solid var(--track);
82
+ border-radius: 6px;
83
+ padding: 0.32rem 0.7rem;
84
+ background: var(--card);
85
+ color: var(--ink);
86
+ cursor: pointer;
87
+ }
88
+ .newgame:hover,
89
+ .passive-button:hover { border-color: var(--accent); }
90
+ .status { min-height: 1.5em; margin: 0.15rem 0 0.9rem; color: var(--muted); }
91
+ .status.thinking { color: var(--accent); }
92
+ .banner {
93
+ display: none;
94
+ margin-bottom: 0.75rem;
95
+ padding: 0.45rem 0.7rem;
96
+ border: 1px solid var(--accent);
97
+ border-radius: 6px;
98
+ font-size: 0.85rem;
99
+ }
100
+ .banner.show { display: block; }
101
+ .table { display: grid; grid-template-columns: minmax(0, 1fr) 220px; gap: 0.9rem; }
102
+ .boardwrap {
103
+ padding: 0.85rem;
104
+ border: 1px solid var(--frame-edge);
105
+ border-radius: 14px;
106
+ background: linear-gradient(145deg, var(--frame-a), var(--frame-b));
107
+ box-shadow:
108
+ inset 0 1px 0 rgba(255, 255, 255, 0.2),
109
+ inset 0 -4px 8px rgba(0, 0, 0, 0.25),
110
+ 0 10px 24px rgba(31, 21, 15, 0.22);
111
+ }
112
+ .board {
113
+ display: grid;
114
+ grid-template-columns: repeat(8, minmax(0, 1fr));
115
+ width: 100%;
116
+ aspect-ratio: 1;
117
+ overflow: hidden;
118
+ border: 1px solid var(--frame-edge);
119
+ border-radius: 8px;
120
+ box-shadow: 0 5px 12px rgba(0, 0, 0, 0.3);
121
+ user-select: none;
122
+ }
123
+ .cell {
124
+ position: relative;
125
+ display: grid;
126
+ min-width: 0;
127
+ min-height: 0;
128
+ aspect-ratio: 1;
129
+ place-items: center;
130
+ padding: 0;
131
+ border: 0;
132
+ color: inherit;
133
+ }
134
+ .cell.light { background: var(--sq-light); }
135
+ .cell.dark { background: var(--sq-dark); }
136
+ .cell.selectable { cursor: pointer; }
137
+ .cell.selected {
138
+ outline: 3px solid var(--accent);
139
+ outline-offset: -3px;
140
+ z-index: 2;
141
+ }
142
+ .cell.hint { cursor: pointer; }
143
+ .cell.hint::after {
144
+ position: absolute;
145
+ z-index: 2;
146
+ width: 24%;
147
+ height: 24%;
148
+ border-radius: 50%;
149
+ background: var(--sq-hint);
150
+ box-shadow: 0 0 0 4px rgba(255, 255, 255, 0.18);
151
+ content: '';
152
+ }
153
+ .cell.hint.capture::after {
154
+ width: 72%;
155
+ height: 72%;
156
+ border: 5px solid var(--sq-hint);
157
+ background: transparent;
158
+ box-shadow: none;
159
+ }
160
+ .cell.last-from { box-shadow: inset 0 0 0 3px var(--last-move); }
161
+ .cell.last-to { box-shadow: inset 0 0 0 999px var(--last-move); }
162
+ .piece {
163
+ position: relative;
164
+ z-index: 1;
165
+ display: grid;
166
+ width: 100%;
167
+ height: 100%;
168
+ place-items: center;
169
+ font-family: Georgia, 'Times New Roman', serif;
170
+ font-size: clamp(1.5rem, 7vw, 3.25rem);
171
+ line-height: 1;
172
+ isolation: isolate;
173
+ transform: translate(-2px, -3px);
174
+ transition: transform 140ms ease-out;
175
+ }
176
+ .piece.white {
177
+ --piece-face: var(--white-piece-face);
178
+ --piece-side: var(--white-piece-side);
179
+ --piece-edge: var(--white-piece-edge);
180
+ --piece-highlight: var(--white-piece-highlight);
181
+ }
182
+ .piece.black {
183
+ --piece-face: var(--black-piece-face);
184
+ --piece-side: var(--black-piece-side);
185
+ --piece-edge: var(--black-piece-edge);
186
+ --piece-highlight: var(--black-piece-highlight);
187
+ }
188
+ .piece::before,
189
+ .piece::after {
190
+ position: absolute;
191
+ inset: 0;
192
+ display: grid;
193
+ place-items: center;
194
+ content: attr(data-glyph);
195
+ }
196
+ .piece::before {
197
+ z-index: -1;
198
+ color: var(--piece-side);
199
+ -webkit-text-stroke: 1px var(--piece-edge);
200
+ text-shadow:
201
+ 1px 1px 0 var(--piece-edge),
202
+ 2px 2px 0 var(--piece-edge),
203
+ 3px 3px 0 var(--piece-edge),
204
+ 4px 5px 4px rgba(0, 0, 0, 0.34);
205
+ transform: translate(3px, 4px);
206
+ }
207
+ .piece::after {
208
+ color: var(--piece-face);
209
+ -webkit-text-stroke: 1px var(--piece-edge);
210
+ text-shadow:
211
+ -1px -1px 0 var(--piece-highlight),
212
+ 1px 1px 0 color-mix(in srgb, var(--piece-side) 68%, transparent);
213
+ }
214
+ .cell.selectable:hover .piece,
215
+ .cell.selected .piece { transform: translate(-3px, -5px) scale(1.04); }
216
+ .coord {
217
+ position: absolute;
218
+ z-index: 3;
219
+ color: rgba(43, 38, 32, 0.55);
220
+ font-size: clamp(0.45rem, 1.3vw, 0.65rem);
221
+ font-weight: 700;
222
+ line-height: 1;
223
+ pointer-events: none;
224
+ }
225
+ .coord.rank { top: 5%; left: 6%; }
226
+ .coord.file { right: 6%; bottom: 5%; }
227
+ .dark .coord { color: rgba(255, 250, 242, 0.58); }
228
+ .aside { display: flex; flex-direction: column; gap: 0.6rem; min-width: 0; }
229
+ .panel {
230
+ padding: 0.7rem 0.85rem;
231
+ border: 1px solid var(--track);
232
+ border-radius: 10px;
233
+ background: var(--card);
234
+ font-size: 0.85rem;
235
+ }
236
+ .panel h2 {
237
+ margin: 0 0 0.35rem;
238
+ color: var(--muted);
239
+ font-size: 0.72rem;
240
+ letter-spacing: 0.05em;
241
+ text-transform: uppercase;
242
+ }
243
+ .move-thought { font-style: italic; }
244
+ .move-thought .who {
245
+ display: block;
246
+ margin-bottom: 0.15rem;
247
+ color: var(--muted);
248
+ font-size: 0.78rem;
249
+ font-style: normal;
250
+ }
251
+ .log { max-height: 230px; margin: 0; padding-left: 1.2rem; overflow-y: auto; }
252
+ .log li { margin: 0.12rem 0; color: var(--muted); }
253
+ .log li.latest { color: var(--ink); }
254
+ dialog {
255
+ width: min(410px, calc(100vw - 2rem));
256
+ padding: 0;
257
+ border: 1px solid var(--track);
258
+ border-radius: 10px;
259
+ background: var(--card);
260
+ color: var(--ink);
261
+ box-shadow: 0 18px 55px rgba(0, 0, 0, 0.35);
262
+ }
263
+ dialog::backdrop { background: rgba(20, 17, 14, 0.62); }
264
+ .dialog-content { padding: 1rem; }
265
+ .dialog-content h2 {
266
+ margin: 0 0 0.2rem;
267
+ font-family: Georgia, 'PT Serif', serif;
268
+ font-size: 1.1rem;
269
+ }
270
+ .dialog-content p { margin: 0 0 0.85rem; color: var(--muted); font-size: 0.85rem; }
271
+ .piece-tray {
272
+ display: grid;
273
+ grid-template-columns: repeat(4, 1fr);
274
+ gap: 0.35rem;
275
+ padding: 0.35rem;
276
+ border: 1px solid var(--track);
277
+ border-radius: 10px;
278
+ background: var(--track);
279
+ }
280
+ .promotion-key {
281
+ min-height: 3.2rem;
282
+ border: 1px solid transparent;
283
+ border-radius: 6px;
284
+ background: var(--card);
285
+ color: var(--ink);
286
+ cursor: pointer;
287
+ font-family: Georgia, 'Times New Roman', serif;
288
+ font-size: 1.8rem;
289
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.14);
290
+ }
291
+ .promotion-key:hover { border-color: var(--accent); }
292
+ .dialog-actions { display: flex; justify-content: flex-end; margin-top: 0.8rem; }
293
+ @media (max-width: 640px) {
294
+ .table { grid-template-columns: 1fr; }
295
+ .aside { display: grid; grid-template-columns: 1fr 1fr; }
296
+ }
297
+ @media (prefers-reduced-motion: reduce) {
298
+ .piece { transition: none; }
299
+ }
300
+ </style>
301
+ </head>
302
+ <body>
303
+ <main>
304
+ <div class="banner" id="banner"></div>
305
+ <header>
306
+ <h1>Chess</h1>
307
+ <button type="button" class="newgame" id="newgame">New game</button>
308
+ </header>
309
+ <p class="status" id="status">Setting up the board…</p>
310
+ <div class="table">
311
+ <div class="boardwrap"><div class="board" id="board" aria-label="Chess board"></div></div>
312
+ <div class="aside">
313
+ <div class="panel move-thought" id="move-thought-panel" hidden>
314
+ <span class="who">Schaakspeler says</span>
315
+ <span id="move-thought"></span>
316
+ </div>
317
+ <div class="panel">
318
+ <h2>Moves</h2>
319
+ <ol class="log" id="log"><li>No moves yet — white opens.</li></ol>
320
+ </div>
321
+ </div>
322
+ </div>
323
+ <dialog id="promotion-dialog" aria-labelledby="promotion-title">
324
+ <div class="dialog-content">
325
+ <h2 id="promotion-title">Promote your pawn</h2>
326
+ <p>Choose the piece that arrives on the back rank.</p>
327
+ <div class="piece-tray" id="promotion-choices"></div>
328
+ <div class="dialog-actions">
329
+ <button type="button" class="passive-button" id="cancel-promotion">Cancel</button>
330
+ </div>
331
+ </div>
332
+ </dialog>
333
+ </main>
334
+ <script>
335
+ (function () {
336
+ 'use strict';
337
+
338
+ var gezelPage = (function () {
339
+ var seq = 0;
340
+ var pending = {};
341
+ window.addEventListener('message', function (event) {
342
+ var data = event.data;
343
+ if (!data || data.__gezelPageResult !== true || typeof data.id !== 'string') return;
344
+ var entry = pending[data.id];
345
+ if (!entry) return;
346
+ delete pending[data.id];
347
+ clearTimeout(entry.timer);
348
+ if (data.ok) entry.resolve(data);
349
+ else entry.reject(new Error(data.error || 'invoke failed'));
350
+ });
351
+ return {
352
+ embedded: function () { return window.parent !== window; },
353
+ invoke: function (tool, input) {
354
+ return new Promise(function (resolve, reject) {
355
+ if (window.parent === window) return reject(new Error('not embedded in Gezel'));
356
+ seq += 1;
357
+ var id = 'pi-' + Date.now() + '-' + seq;
358
+ pending[id] = {
359
+ resolve: resolve,
360
+ reject: reject,
361
+ timer: setTimeout(function () {
362
+ delete pending[id];
363
+ reject(new Error('invoke timed out'));
364
+ }, 45000),
365
+ };
366
+ window.parent.postMessage(
367
+ { __gezelPageInvoke: true, id: id, tool: tool, input: input || {} },
368
+ '*',
369
+ );
370
+ });
371
+ },
372
+ refresh: function () {
373
+ if (window.parent !== window) window.parent.postMessage({ __gezelPageRefresh: true }, '*');
374
+ },
375
+ };
376
+ })();
377
+
378
+ var parts = location.pathname.split('/').filter(Boolean);
379
+ var typeIndex = parts.indexOf('type');
380
+ var capability = typeIndex > 0 ? parts[typeIndex - 1] : null;
381
+ var projectId = typeIndex >= 0 ? parts[typeIndex + 1] : null;
382
+ var FILES = 'abcdefgh';
383
+ var PIECES = {
384
+ K: '♚', Q: '♛', R: '♜', B: '♝', N: '♞', P: '♟',
385
+ k: '♚', q: '♛', r: '♜', b: '♝', n: '♞', p: '♟',
386
+ };
387
+ var PROMOTION_PIECES = { q: '♛', r: '♜', b: '♝', n: '♞' };
388
+ var state = null;
389
+ var selected = null;
390
+ var busy = false;
391
+ var pollTimer = null;
392
+ var failedPolls = 0;
393
+ var promotionMoves = [];
394
+
395
+ function squareName(x, y) { return FILES[x] + String(8 - y); }
396
+ function sideOf(piece) {
397
+ if (!piece || piece === '.') return null;
398
+ return piece === piece.toUpperCase() ? 'user' : 'ai';
399
+ }
400
+ function setBanner(text) {
401
+ var banner = document.getElementById('banner');
402
+ banner.textContent = text || '';
403
+ banner.className = text ? 'banner show' : 'banner';
404
+ }
405
+ function statusLine() {
406
+ if (!state) return 'Setting up the board…';
407
+ if (state.status === 'user_won') return 'Checkmate — you won. The Schaakspeler is ready for a rematch.';
408
+ if (state.status === 'ai_won') return 'Checkmate — the Schaakspeler takes this one.';
409
+ if (state.status === 'draw') return 'Draw — a balanced board, and a rematch whenever you like.';
410
+ if (busy) return 'Sending your move…';
411
+ if (state.turn === 'ai') return 'Schaakspeler is thinking…';
412
+ return selected ? 'Choose a highlighted destination.' : 'Your move — you have white.';
413
+ }
414
+ function movesFrom(name) {
415
+ if (!state) return [];
416
+ return state.legalMoves.filter(function (move) { return move.from === name; });
417
+ }
418
+ function movesTo(name) {
419
+ return selected
420
+ ? movesFrom(selected).filter(function (move) { return move.to === name; })
421
+ : [];
422
+ }
423
+ function render() {
424
+ var status = document.getElementById('status');
425
+ status.textContent = statusLine();
426
+ status.className =
427
+ state && state.turn === 'ai' && state.status === 'playing'
428
+ ? 'status thinking'
429
+ : 'status';
430
+
431
+ var thoughtPanel = document.getElementById('move-thought-panel');
432
+ if (state && state.lastMoveThought) {
433
+ thoughtPanel.hidden = false;
434
+ document.getElementById('move-thought').textContent = state.lastMoveThought;
435
+ } else {
436
+ thoughtPanel.hidden = true;
437
+ }
438
+
439
+ var log = document.getElementById('log');
440
+ if (state && state.moveLog.length) {
441
+ log.innerHTML = '';
442
+ state.moveLog.forEach(function (entry, index) {
443
+ var item = document.createElement('li');
444
+ item.textContent = (entry.by === 'user' ? 'White ' : 'Black ') + entry.notation;
445
+ if (index === state.moveLog.length - 1) item.className = 'latest';
446
+ log.appendChild(item);
447
+ });
448
+ log.scrollTop = log.scrollHeight;
449
+ } else {
450
+ log.innerHTML = '<li>No moves yet — white opens.</li>';
451
+ }
452
+
453
+ var board = document.getElementById('board');
454
+ board.innerHTML = '';
455
+ var myTurn = state && state.turn === 'user' && state.status === 'playing' && !busy;
456
+ for (var y = 0; y < 8; y += 1) {
457
+ for (var x = 0; x < 8; x += 1) {
458
+ var name = squareName(x, y);
459
+ var piece = state ? state.squares[y * 8 + x] : '.';
460
+ var choices = movesTo(name);
461
+ var cell = document.createElement('button');
462
+ cell.type = 'button';
463
+ cell.className = 'cell ' + ((x + y) % 2 ? 'dark' : 'light');
464
+ cell.setAttribute('aria-label', name + (piece === '.' ? ', empty' : ', ' + piece));
465
+ cell.dataset.square = name;
466
+ if (state && state.lastMove) {
467
+ if (state.lastMove.from === name) cell.className += ' last-from';
468
+ if (state.lastMove.to === name) cell.className += ' last-to';
469
+ }
470
+ if (selected === name) cell.className += ' selected';
471
+ if (choices.length) {
472
+ cell.className += ' hint';
473
+ if (piece !== '.') cell.className += ' capture';
474
+ }
475
+ if (myTurn && (movesFrom(name).length || choices.length)) cell.className += ' selectable';
476
+
477
+ if (x === 0) {
478
+ var rank = document.createElement('span');
479
+ rank.className = 'coord rank';
480
+ rank.textContent = String(8 - y);
481
+ cell.appendChild(rank);
482
+ }
483
+ if (y === 7) {
484
+ var file = document.createElement('span');
485
+ file.className = 'coord file';
486
+ file.textContent = FILES[x];
487
+ cell.appendChild(file);
488
+ }
489
+ if (piece !== '.') {
490
+ var figure = document.createElement('span');
491
+ figure.className = 'piece ' + (sideOf(piece) === 'user' ? 'white' : 'black');
492
+ figure.dataset.glyph = PIECES[piece];
493
+ figure.setAttribute('aria-hidden', 'true');
494
+ cell.appendChild(figure);
495
+ }
496
+ cell.addEventListener('click', onSquareClick);
497
+ board.appendChild(cell);
498
+ }
499
+ }
500
+ }
501
+
502
+ function onSquareClick(event) {
503
+ if (!state || state.turn !== 'user' || state.status !== 'playing' || busy) return;
504
+ var name = event.currentTarget.dataset.square;
505
+ var destinations = movesTo(name);
506
+ if (selected && destinations.length) {
507
+ if (destinations.some(function (move) { return move.promotion; })) {
508
+ openPromotion(destinations);
509
+ } else {
510
+ submitMove(destinations[0]);
511
+ }
512
+ return;
513
+ }
514
+ if (movesFrom(name).length) selected = name;
515
+ else selected = null;
516
+ render();
517
+ }
518
+
519
+ function openPromotion(moves) {
520
+ promotionMoves = moves;
521
+ var tray = document.getElementById('promotion-choices');
522
+ tray.innerHTML = '';
523
+ moves.forEach(function (move) {
524
+ var button = document.createElement('button');
525
+ button.type = 'button';
526
+ button.className = 'promotion-key';
527
+ button.textContent = PROMOTION_PIECES[move.promotion];
528
+ button.setAttribute('aria-label', 'Promote to ' + move.promotion);
529
+ button.addEventListener('click', function () {
530
+ document.getElementById('promotion-dialog').close();
531
+ submitMove(move);
532
+ });
533
+ tray.appendChild(button);
534
+ });
535
+ document.getElementById('promotion-dialog').showModal();
536
+ }
537
+
538
+ function submitMove(move) {
539
+ selected = null;
540
+ busy = true;
541
+ render();
542
+ gezelPage
543
+ .invoke('user_move', {
544
+ from: move.from,
545
+ to: move.to,
546
+ ...(move.promotion ? { promotion: move.promotion } : {}),
547
+ })
548
+ .then(function (result) {
549
+ busy = false;
550
+ if (
551
+ result.reaction &&
552
+ result.reaction.delivered === false &&
553
+ result.reaction.reason === 'engagement-off'
554
+ ) {
555
+ setBanner('Move played — but AI engagement is off, so the Schaakspeler cannot reply.');
556
+ }
557
+ return poll();
558
+ })
559
+ .catch(function (error) {
560
+ busy = false;
561
+ setBanner(String(error && error.message ? error.message : error));
562
+ render();
563
+ });
564
+ }
565
+
566
+ function newGame() {
567
+ if (!gezelPage.embedded() || busy) return;
568
+ selected = null;
569
+ busy = true;
570
+ render();
571
+ gezelPage
572
+ .invoke('new_game', {})
573
+ .then(function () {
574
+ busy = false;
575
+ setBanner('');
576
+ return poll();
577
+ })
578
+ .catch(function (error) {
579
+ busy = false;
580
+ setBanner(String(error && error.message ? error.message : error));
581
+ render();
582
+ });
583
+ }
584
+
585
+ function transitionState(next) {
586
+ state = next;
587
+ if (selected && !movesFrom(selected).length) selected = null;
588
+ render();
589
+ }
590
+ function poll() {
591
+ if (!capability || !projectId) return Promise.resolve();
592
+ return fetch(
593
+ '/preview/' + encodeURIComponent(capability) + '/workspace/' + encodeURIComponent(projectId) + '/game.json',
594
+ { cache: 'no-store' },
595
+ )
596
+ .then(function (response) {
597
+ if (!response.ok) throw new Error('poll ' + response.status);
598
+ return response.json();
599
+ })
600
+ .then(function (next) {
601
+ failedPolls = 0;
602
+ transitionState(next);
603
+ })
604
+ .catch(function () {
605
+ failedPolls += 1;
606
+ if (failedPolls === 3) gezelPage.refresh();
607
+ });
608
+ }
609
+ function schedule() {
610
+ if (pollTimer) clearTimeout(pollTimer);
611
+ var wait = state && state.turn === 'ai' && state.status === 'playing' ? 1500 : 5000;
612
+ pollTimer = setTimeout(function () { poll().then(schedule, schedule); }, wait);
613
+ }
614
+
615
+ document.getElementById('newgame').addEventListener('click', newGame);
616
+ document.getElementById('cancel-promotion').addEventListener('click', function () {
617
+ promotionMoves = [];
618
+ document.getElementById('promotion-dialog').close();
619
+ });
620
+ if (!gezelPage.embedded()) {
621
+ setBanner('Read-only view — moves need the Gezel app (open this project and use the Output tab).');
622
+ }
623
+ poll().then(schedule, schedule);
624
+ })();
625
+ </script>
626
+ </body>
627
+ </html>
@@ -0,0 +1,9 @@
1
+ A standing chess table. You play white on the board in the **Output** tab;
2
+ your Schaakspeler plays black — reading the exact position, replying on the
3
+ board, and keeping up a light line of {{personality}} table talk.
4
+
5
+ The Schaakspeler plays as an **{{playStyle}}**: opponents keep plans and tactics
6
+ to themselves, while instructors offer one small teaching observation at a
7
+ time. Click a white piece, then a highlighted square. The board enforces the
8
+ whole game — check, castling, en passant, promotion, mate, stalemate, repetition,
9
+ and the fifty-move rule — so neither player has to referee the other.