@bendyline/gilde 0.1.4 → 0.1.5

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 (141) hide show
  1. package/README.md +1 -0
  2. package/data/chat-models/de/deepseek-v4-flash-284b-q2/manifest.json +4 -3
  3. package/data/chat-models/de/deepseek-v4-flash-284b-q4/manifest.json +4 -3
  4. package/data/chat-models/ge/gemma4-12b-q4/manifest.json +20 -11
  5. package/data/chat-models/ge/gemma4-12b-q4/versions/1.1.0/manifest.json +2 -8
  6. package/data/chat-models/ge/gemma4-12b-q4/versions/1.1.2/manifest.json +78 -0
  7. package/data/chat-models/ge/gemma4-12b-q8/manifest.json +23 -14
  8. package/data/chat-models/ge/gemma4-12b-q8/versions/1.0.0/manifest.json +2 -8
  9. package/data/chat-models/ge/gemma4-12b-q8/versions/1.0.2/manifest.json +78 -0
  10. package/data/chat-models/ge/gemma4-26b-q4/manifest.json +55 -46
  11. package/data/chat-models/ge/gemma4-26b-q4/versions/1.2.0/manifest.json +2 -8
  12. package/data/chat-models/ge/gemma4-26b-q4/versions/1.2.1/manifest.json +81 -0
  13. package/data/chat-models/ge/gemma4-31b-q4/manifest.json +36 -28
  14. package/data/chat-models/ge/gemma4-31b-q4/versions/1.2.0/manifest.json +2 -8
  15. package/data/chat-models/ge/gemma4-31b-q4/versions/1.2.1/manifest.json +87 -0
  16. package/data/chat-models/ge/gemma4-e2b-q8/manifest.json +76 -69
  17. package/data/chat-models/ge/gemma4-e2b-q8/versions/1.1.0/manifest.json +2 -8
  18. package/data/chat-models/ge/gemma4-e2b-q8/versions/1.1.2/manifest.json +71 -0
  19. package/data/chat-models/ge/gemma4-e4b-q8/manifest.json +71 -78
  20. package/data/chat-models/ge/gemma4-e4b-q8/versions/1.1.0/manifest.json +3 -9
  21. package/data/chat-models/ge/gemma4-e4b-q8/versions/1.1.2/manifest.json +71 -0
  22. package/data/chat-models/index.json +1 -1
  23. package/data/chat-models/la/laguna-s-2.1-118b-q4/manifest.json +17 -17
  24. package/data/chat-models/la/laguna-s-2.1-118b-q4/versions/1.0.1/manifest.json +124 -0
  25. package/data/chat-models/la/laguna-s-2.1-118b-q8/manifest.json +7 -7
  26. package/data/chat-models/la/laguna-s-2.1-118b-q8/versions/1.0.1/manifest.json +174 -0
  27. package/data/chat-models/mi/mistral-medium-3.5-128b-q4/manifest.json +4 -17
  28. package/data/chat-models/mi/mistral-medium-3.5-128b-q4/versions/1.0.0/manifest.json +2 -12
  29. package/data/chat-models/ne/nemotron3-nano-30b-q4/manifest.json +5 -0
  30. package/data/chat-models/qw/qwen3.5-122b-a10b-q4/manifest.json +27 -19
  31. package/data/chat-models/qw/qwen3.5-122b-a10b-q4/versions/1.0.1/manifest.json +164 -0
  32. package/data/chat-models/qw/qwen3.5-2b-q4/manifest.json +79 -77
  33. package/data/chat-models/qw/qwen3.5-2b-q4/versions/1.1.0/manifest.json +2 -8
  34. package/data/chat-models/qw/qwen3.5-2b-q4/versions/1.1.2/manifest.json +76 -0
  35. package/data/chat-models/qw/qwen3.5-4b-q4/manifest.json +79 -77
  36. package/data/chat-models/qw/qwen3.5-4b-q4/versions/1.1.0/manifest.json +2 -8
  37. package/data/chat-models/qw/qwen3.5-4b-q4/versions/1.1.2/manifest.json +76 -0
  38. package/data/chat-models/qw/qwen3.5-9b-q4/manifest.json +87 -85
  39. package/data/chat-models/qw/qwen3.5-9b-q4/versions/1.1.0/manifest.json +2 -8
  40. package/data/chat-models/qw/qwen3.5-9b-q4/versions/1.1.2/manifest.json +81 -0
  41. package/data/chat-models/qw/qwen3.6-27b-q4/manifest.json +99 -97
  42. package/data/chat-models/qw/qwen3.6-27b-q4/versions/1.1.0/manifest.json +2 -8
  43. package/data/chat-models/qw/qwen3.6-27b-q4/versions/1.1.4/manifest.json +91 -0
  44. package/data/chat-models/qw/qwen3.6-27b-q8/manifest.json +16 -12
  45. package/data/chat-models/qw/qwen3.6-27b-q8/versions/1.0.0/manifest.json +2 -8
  46. package/data/chat-models/qw/qwen3.6-27b-q8/versions/1.0.2/manifest.json +103 -0
  47. package/data/chat-models/qw/qwen3.6-35b-a3b-q4/manifest.json +18 -14
  48. package/data/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.0/manifest.json +2 -8
  49. package/data/chat-models/qw/qwen3.6-35b-a3b-q4/versions/1.0.1/manifest.json +93 -0
  50. package/data/chat-models/qw/qwen3.6-35b-a3b-q8/manifest.json +16 -12
  51. package/data/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.0/manifest.json +2 -8
  52. package/data/chat-models/qw/qwen3.6-35b-a3b-q8/versions/1.0.1/manifest.json +113 -0
  53. package/data/craftbook-templates/bu/bug-fix-tdd/versions/1.0.1/test.json +0 -5
  54. package/data/craftbook-templates/bu/build-loop/versions/1.1.0/craftbook.json +65 -0
  55. package/data/craftbook-templates/bu/build-loop/versions/1.1.0/test.json +121 -0
  56. package/data/craftbook-templates/ch/character-sheet/versions/1.0.0/test.json +1 -2
  57. package/data/craftbook-templates/ch/character-turnaround/versions/1.0.0/test.json +1 -2
  58. package/data/craftbook-templates/cl/cli-tool/versions/1.1.0/craftbook.json +139 -0
  59. package/data/craftbook-templates/cl/cli-tool/versions/1.1.0/test.json +128 -0
  60. package/data/craftbook-templates/cr/crossword-forge/manifest.json +1 -2
  61. package/data/craftbook-templates/de/deep-security-review/versions/1.1.0/craftbook.json +201 -0
  62. package/data/craftbook-templates/de/deep-security-review/versions/1.1.0/test.json +157 -0
  63. package/data/craftbook-templates/do/dockerize-app/versions/1.0.0/test.json +0 -5
  64. package/data/craftbook-templates/fr/freeze-scope/manifest.json +1 -2
  65. package/data/craftbook-templates/fr/freeze-scope/versions/{1.0.1 → 1.1.0}/craftbook.json +5 -17
  66. package/data/craftbook-templates/gr/graphql-api/versions/1.0.1/test.json +0 -5
  67. package/data/craftbook-templates/gr/grpc-service/versions/1.0.0/test.json +0 -5
  68. package/data/craftbook-templates/ho/hotfix-flow/versions/1.0.0/test.json +0 -5
  69. package/data/craftbook-templates/in/investigate/versions/1.1.0/craftbook.json +81 -0
  70. package/data/craftbook-templates/in/investigate/versions/1.1.0/test.json +122 -0
  71. package/data/craftbook-templates/in/invoice-run/manifest.json +1 -2
  72. package/data/craftbook-templates/in/invoice-run/versions/{1.0.1 → 1.1.0}/craftbook.json +4 -4
  73. package/data/craftbook-templates/index.json +1 -1
  74. package/data/craftbook-templates/li/library-package/versions/1.0.0/test.json +0 -5
  75. package/data/craftbook-templates/me/memory-prompt-session/manifest.json +1 -2
  76. package/data/craftbook-templates/me/message-queue-consumer/versions/1.0.0/test.json +0 -5
  77. package/data/craftbook-templates/of/office-hours/versions/1.1.0/craftbook.json +48 -0
  78. package/data/craftbook-templates/of/office-hours/versions/1.1.0/test.json +118 -0
  79. package/data/craftbook-templates/pa/page-spread/manifest.json +1 -2
  80. package/data/craftbook-templates/pa/parser-grammar/versions/1.0.0/test.json +0 -5
  81. package/data/craftbook-templates/pe/perf-optimization/versions/1.0.0/test.json +0 -5
  82. package/data/craftbook-templates/pl/plan/manifest.json +1 -2
  83. package/data/craftbook-templates/po/powerpoint-deck/versions/1.1.0/craftbook.json +128 -0
  84. package/data/craftbook-templates/{ro/root-cause-investigation/versions/1.0.1 → po/powerpoint-deck/versions/1.1.0}/test.json +6 -6
  85. package/data/craftbook-templates/pu/pull-request-review/versions/1.1.0/craftbook.json +118 -0
  86. package/data/craftbook-templates/pu/pull-request-review/versions/1.1.0/test.json +160 -0
  87. package/data/craftbook-templates/re/refactor-module/versions/1.0.1/test.json +0 -5
  88. package/data/craftbook-templates/re/regex-builder/versions/1.0.0/test.json +0 -5
  89. package/data/craftbook-templates/re/research-to-document/versions/1.1.0/craftbook.json +158 -0
  90. package/data/craftbook-templates/re/research-to-document/versions/1.1.0/test.json +97 -0
  91. package/data/craftbook-templates/ro/root-cause-investigation/manifest.json +1 -2
  92. package/data/craftbook-templates/sd/sdk-wrapper/versions/1.0.1/test.json +0 -5
  93. package/data/craftbook-templates/se/security-architecture-review/versions/1.1.0/craftbook.json +28 -0
  94. package/data/craftbook-templates/{te/technical-documentation/versions/1.0.1 → se/security-architecture-review/versions/1.1.0}/test.json +7 -7
  95. package/data/craftbook-templates/sh/ship/versions/1.1.0/craftbook.json +137 -0
  96. package/data/craftbook-templates/sh/ship/versions/1.1.0/test.json +225 -0
  97. package/data/craftbook-templates/st/state-machine/versions/1.0.0/test.json +0 -5
  98. package/data/craftbook-templates/te/technical-documentation/manifest.json +1 -2
  99. package/data/craftbook-templates/te/test-suite-backfill/versions/1.0.0/test.json +0 -5
  100. package/data/craftbook-templates/ti/tileset-batch/versions/1.0.0/test.json +1 -2
  101. package/data/craftbook-templates/ty/type-safety-pass/versions/1.0.0/test.json +0 -5
  102. package/data/craftbook-templates/ve/version-bump/versions/1.0.0/test.json +0 -5
  103. package/data/gezel-templates/ch/chess-player/manifest.json +20 -0
  104. package/data/gezel-templates/ch/chess-player/versions/1.0.0/about.md +21 -0
  105. package/data/gezel-templates/ch/chess-player/versions/1.0.0/manifest.json +10 -0
  106. package/data/gezel-templates/go/go-player/manifest.json +22 -0
  107. package/data/gezel-templates/go/go-player/versions/1.0.0/about.md +22 -0
  108. package/data/gezel-templates/go/go-player/versions/1.0.0/manifest.json +10 -0
  109. package/data/gezel-templates/index.json +1 -1
  110. package/data/project-types/ch/chess/manifest.json +20 -0
  111. package/data/project-types/ch/chess/versions/1.0.0/about.md +9 -0
  112. package/data/project-types/ch/chess/versions/1.0.0/game.json +127 -0
  113. package/data/project-types/ch/chess/versions/1.0.0/manifest.json +180 -0
  114. package/data/project-types/ch/chess/versions/1.0.0/mission.md +8 -0
  115. package/data/project-types/ch/chess/versions/1.0.0/pages/board/index.html +574 -0
  116. package/data/project-types/go/go/manifest.json +22 -0
  117. package/data/project-types/go/go/versions/1.0.0/about.md +9 -0
  118. package/data/project-types/go/go/versions/1.0.0/game.json +103 -0
  119. package/data/project-types/go/go/versions/1.0.0/manifest.json +166 -0
  120. package/data/project-types/go/go/versions/1.0.0/mission.md +8 -0
  121. package/data/project-types/go/go/versions/1.0.0/pages/board/index.html +637 -0
  122. package/data/project-types/index.json +1 -1
  123. package/package.json +2 -1
  124. package/schemas/chat-model-version.schema.json +22 -0
  125. package/schemas/craftbook-doc.schema.json +12 -0
  126. package/schemas/craftbook-template-version.schema.json +12 -0
  127. package/schemas/craftbook-test.schema.json +12 -0
  128. package/data/chat-models/gl/glm-5.2-754b-q2/manifest.json +0 -66
  129. package/data/chat-models/gl/glm-5.2-754b-q2/versions/1.0.0/manifest.json +0 -18
  130. package/data/craftbook-templates/cr/crossword-forge/versions/1.0.1/craftbook.json +0 -147
  131. package/data/craftbook-templates/cr/crossword-forge/versions/1.0.1/test.json +0 -135
  132. package/data/craftbook-templates/me/memory-prompt-session/versions/1.0.1/craftbook.json +0 -116
  133. package/data/craftbook-templates/me/memory-prompt-session/versions/1.0.1/test.json +0 -112
  134. package/data/craftbook-templates/pa/page-spread/versions/1.0.1/craftbook.json +0 -94
  135. package/data/craftbook-templates/pa/page-spread/versions/1.0.1/test.json +0 -133
  136. package/data/craftbook-templates/pl/plan/versions/1.0.1/craftbook.json +0 -104
  137. package/data/craftbook-templates/pl/plan/versions/1.0.1/test.json +0 -91
  138. package/data/craftbook-templates/ro/root-cause-investigation/versions/1.0.1/craftbook.json +0 -126
  139. package/data/craftbook-templates/te/technical-documentation/versions/1.0.1/craftbook.json +0 -152
  140. /package/data/craftbook-templates/fr/freeze-scope/versions/{1.0.1 → 1.1.0}/test.json +0 -0
  141. /package/data/craftbook-templates/in/invoice-run/versions/{1.0.1 → 1.1.0}/test.json +0 -0
@@ -1 +1 @@
1
- {"schemaVersion":1,"kind":"gezel-template","count":29,"entries":[{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"aanjager","name":"Aanjager","description":"An infectious, organized rallier for community drives. Keeps the thermometer honest, the sponsor outreach warm, and makes sure every donor gets thanked.","tags":["fundraiser","community","donations","outreach"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Aanjager","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"archivaris","name":"Archivaris","description":"A gentle, rigorous archivist for the file nobody wants to need — wills, policies, accounts, instructions. Careful about hard topics, relentless about completeness, and everything stays on this machine.","tags":["documents","estate","emergency","family","archive"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Archivaris","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"boekwachter","name":"Boekwachter","description":"The index-keeper. Works quietly in the background while the machine is idle, distilling code and documents into summaries and embeddings so the rest of the crew can search the workspace by meaning.","tags":["boekwachter","index","librarian","background","search"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-06-06T00:00:00Z","role":"Boekwachter","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"builder","name":"Builder","description":"Product-oriented developer. Owns a job end-to-end — research, code, shape, ship. Best fit for solo projects.","tags":["builder","developer","product","solo","ambachtsman"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.3.0","releasedAt":"2026-07-05T00:00:00Z","role":"Builder","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-coding"},"availableVersions":["1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"ceremoniemeester","name":"Ceremoniemeester","description":"A composed master of ceremonies for weddings, parties, and reunions. Guest list current, budget honest, day-of runbook ready — and the thank-yous actually go out.","tags":["events","party","wedding","planning","guests"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Ceremoniemeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"coach","name":"Coach","description":"A steady, encouraging training coach. Celebrates every session logged, keeps the weekly rhythm honest, and adjusts the plan to the life you actually have.","tags":["fitness","training","habits","health"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Coach","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"copywriter","name":"Copywriter","description":"Writes for humans. Starts with what the reader cares about, then figures out the words.","tags":["copywriter","writing"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.1.0","releasedAt":"2026-05-28T00:00:00Z","role":"Copywriter","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"creative"},"availableVersions":["1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"checkers-player","name":"Damspeler","description":"A warm, playful checkers opponent. Plays a real game, talks a fun game — peppy table talk that never bites — and is gracious whichever way it ends.","tags":["checkers","game","opponent","play"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Damspeler","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"designer","name":"Designer","description":"Thinks in layout, hierarchy, and visual tone. Works in mocks and style directions, hands off to copy + dev.","tags":["designer","visual"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.1.0","releasedAt":"2026-05-28T00:00:00Z","role":"Designer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"creative"},"availableVersions":["1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"developer","name":"Developer","description":"Writes, tests, and ships code. Works inside a project's scope and leans on the voorman for direction.","tags":["developer","engineer","code","programmer"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.4.0","releasedAt":"2026-07-04T00:00:00Z","role":"Developer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-coding"},"availableVersions":["1.4.0","1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"huismeester","name":"Huismeester","description":"An unflappable house steward. Knows every system in the home, what care it needs and when, and turns the junk drawer of manuals into a calm maintenance rhythm.","tags":["home","maintenance","household","manual"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Huismeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"image-generator","name":"Image generator","description":"An image generator. Always passes through requests to the image generation system. No LLM is involved — the gezel forwards your message text straight to the image engine.","tags":["image","fixed-function","passthrough","generative"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-05-03T00:00:00Z","role":"Image generator","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"fixedFunction":{"tool":"generate_image","promptKey":"prompt"}},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"kantoormeester","name":"Kantoormeester","description":"The operations half of a freelancer's brain. Keeps every invoice tracked to paid, every proposal followed up, and the income picture one question away.","tags":["freelance","invoices","business","operations"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Kantoormeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"keurmeester","name":"Keurmeester","description":"The guild's quality inspector — consulted when a smaller model's work stalls, loops, or drifts, to diagnose the cause and hand back the smallest fix that gets the journeyman moving again.","tags":["keurmeester","supervision","quality","core"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-06T00:00:00Z","role":"Keurmeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"language-trainer","name":"Language Trainer","description":"A warm, patient language tutor. Chats with you in the language you're learning, gently corrects mistakes, and tracks your progress over time.","tags":["language","tutor","learning","conversation"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-06T00:00:00Z","role":"Language Trainer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"career-coach","name":"Loopbaancoach","description":"A steady career coach who runs your job search like a campaign — keeps the pipeline current, gets your materials tailored, and never lets a follow-up slip.","tags":["career","coach","job","interview","planning"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Loopbaancoach","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"maaltijdplanner","name":"Maaltijdplanner","description":"A practical meal planner who answers \"what's for dinner?\" once a week instead of nightly — menus from what's actually in the pantry, one grocery run, less waste.","tags":["meals","cooking","pantry","groceries","home"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Maaltijdplanner","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"meester","name":"Meester","description":"The concierge of a gezel crew — greets new users, understands what they're trying to build, and spins up the right team.","tags":["meester","concierge","core","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.4.0","releasedAt":"2026-07-05T00:00:00Z","role":"Meester","about":"about.md","suggestedTools":[],"meesterCandidate":true,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.4.0","1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"mock-interviewer","name":"Oefen-interviewer","description":"A mock interviewer who asks the hard questions for real — then debriefs kindly, with specifics you can actually fix before it counts.","tags":["interview","practice","career","questions","coaching"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Oefen-interviewer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"penningmeester","name":"Penningmeester","description":"A calm, unjudging treasurer for the household. Keeps the ledger honest, closes each month in minutes, and answers \"where does it actually go?\" with numbers, not lectures.","tags":["budget","money","household","ledger"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Penningmeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"planner","name":"Planner","description":"Turns fuzzy asks into concrete steps — good at the 'what' and the 'in what order', less opinionated on the 'how'.","tags":["planner","strategy"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.1.0","releasedAt":"2026-05-28T00:00:00Z","role":"Planner","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"reisleider","name":"Reisleider","description":"A well-traveled guide who plans trips people actually take: a day-by-day itinerary with slack in it, a packing list that fits the weather, and a journal worth keeping afterward.","tags":["travel","trip","itinerary","packing"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Reisleider","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"researcher","name":"Researcher","description":"Reads source, prior art, or external docs and files a substantive written analysis. Long-form deliverables go to disk; chat carries the path + a short precis.","tags":["researcher","analysis","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.2.0","releasedAt":"2026-07-05T00:00:00Z","role":"Researcher","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"reviewer","name":"Reviewer","description":"Second set of eyes on code, docs, or plans. Sharp on quality, clear on feedback.","tags":["reviewer","quality","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.3.0","releasedAt":"2026-07-05T00:00:00Z","role":"Reviewer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"schrijfmaat","name":"Schrijfmaat","description":"A warm writing companion for the long haul of a novel. Guards the daily words, keeps the chapter board honest, and reads drafts like a friend who wants the book to exist.","tags":["writing","novel","fiction","drafting"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Schrijfmaat","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"study-buddy","name":"Studiemaat","description":"A patient study companion who writes sharp flashcards, keeps the review rhythm going, and cheers the streak without ever shaming a miss.","tags":["study","flashcards","learning","practice"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Studiemaat","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"video-generator","name":"Video generator","description":"Turns your prompts into short video clips. Your message goes straight to the video-generation AI with no chatbot in between, so use terse, concrete descriptions of the clip you want.","tags":["video","passthrough","generative"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-06-18T00:00:00Z","role":"Video generator","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"fixedFunction":{"tool":"generate_video","promptKey":"prompt"}},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"voorman","name":"Voorman","description":"Foreman of a project — plans tasks, delegates to the right gezels, and keeps work moving.","tags":["voorman","planning","delegation","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.6.0","releasedAt":"2026-07-05T00:00:00Z","role":"Voorman","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.6.0","1.5.0","1.4.0","1.3.0","1.2.1","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"zorgcoordinator","name":"Zorgcoördinator","description":"A warm, discreet care coordinator. Keeps the medication list current, every appointment prepped, and the family on the same page — and everything stays on this machine.","tags":["caregiving","health","family","appointments"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Zorgcoördinator","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}}]}
1
+ {"schemaVersion":1,"kind":"gezel-template","count":31,"entries":[{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"aanjager","name":"Aanjager","description":"An infectious, organized rallier for community drives. Keeps the thermometer honest, the sponsor outreach warm, and makes sure every donor gets thanked.","tags":["fundraiser","community","donations","outreach"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Aanjager","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"archivaris","name":"Archivaris","description":"A gentle, rigorous archivist for the file nobody wants to need — wills, policies, accounts, instructions. Careful about hard topics, relentless about completeness, and everything stays on this machine.","tags":["documents","estate","emergency","family","archive"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Archivaris","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"boekwachter","name":"Boekwachter","description":"The index-keeper. Works quietly in the background while the machine is idle, distilling code and documents into summaries and embeddings so the rest of the crew can search the workspace by meaning.","tags":["boekwachter","index","librarian","background","search"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-06-06T00:00:00Z","role":"Boekwachter","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"builder","name":"Builder","description":"Product-oriented developer. Owns a job end-to-end — research, code, shape, ship. Best fit for solo projects.","tags":["builder","developer","product","solo","ambachtsman"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.3.0","releasedAt":"2026-07-05T00:00:00Z","role":"Builder","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-coding"},"availableVersions":["1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"ceremoniemeester","name":"Ceremoniemeester","description":"A composed master of ceremonies for weddings, parties, and reunions. Guest list current, budget honest, day-of runbook ready — and the thank-yous actually go out.","tags":["events","party","wedding","planning","guests"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Ceremoniemeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"coach","name":"Coach","description":"A steady, encouraging training coach. Celebrates every session logged, keeps the weekly rhythm honest, and adjusts the plan to the life you actually have.","tags":["fitness","training","habits","health"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Coach","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"copywriter","name":"Copywriter","description":"Writes for humans. Starts with what the reader cares about, then figures out the words.","tags":["copywriter","writing"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.1.0","releasedAt":"2026-05-28T00:00:00Z","role":"Copywriter","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"creative"},"availableVersions":["1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"checkers-player","name":"Damspeler","description":"A warm, playful checkers opponent. Plays a real game, talks a fun game — peppy table talk that never bites — and is gracious whichever way it ends.","tags":["checkers","game","opponent","play"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Damspeler","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"designer","name":"Designer","description":"Thinks in layout, hierarchy, and visual tone. Works in mocks and style directions, hands off to copy + dev.","tags":["designer","visual"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.1.0","releasedAt":"2026-05-28T00:00:00Z","role":"Designer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"creative"},"availableVersions":["1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"developer","name":"Developer","description":"Writes, tests, and ships code. Works inside a project's scope and leans on the voorman for direction.","tags":["developer","engineer","code","programmer"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.4.0","releasedAt":"2026-07-04T00:00:00Z","role":"Developer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-coding"},"availableVersions":["1.4.0","1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"go-player","name":"Go-speler","description":"A calm, attentive Go opponent who plays legal stones, respects the quiet shape of the board, and handles captures, passes, and final scores with good grace.","tags":["go","baduk","weiqi","game","opponent","strategy","play"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-28T00:00:00Z","role":"Go-speler","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"huismeester","name":"Huismeester","description":"An unflappable house steward. Knows every system in the home, what care it needs and when, and turns the junk drawer of manuals into a calm maintenance rhythm.","tags":["home","maintenance","household","manual"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Huismeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"image-generator","name":"Image generator","description":"An image generator. Always passes through requests to the image generation system. No LLM is involved — the gezel forwards your message text straight to the image engine.","tags":["image","fixed-function","passthrough","generative"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-05-03T00:00:00Z","role":"Image generator","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"fixedFunction":{"tool":"generate_image","promptKey":"prompt"}},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"kantoormeester","name":"Kantoormeester","description":"The operations half of a freelancer's brain. Keeps every invoice tracked to paid, every proposal followed up, and the income picture one question away.","tags":["freelance","invoices","business","operations"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Kantoormeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"keurmeester","name":"Keurmeester","description":"The guild's quality inspector — consulted when a smaller model's work stalls, loops, or drifts, to diagnose the cause and hand back the smallest fix that gets the journeyman moving again.","tags":["keurmeester","supervision","quality","core"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-06T00:00:00Z","role":"Keurmeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"language-trainer","name":"Language Trainer","description":"A warm, patient language tutor. Chats with you in the language you're learning, gently corrects mistakes, and tracks your progress over time.","tags":["language","tutor","learning","conversation"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-06T00:00:00Z","role":"Language Trainer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"career-coach","name":"Loopbaancoach","description":"A steady career coach who runs your job search like a campaign — keeps the pipeline current, gets your materials tailored, and never lets a follow-up slip.","tags":["career","coach","job","interview","planning"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Loopbaancoach","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"maaltijdplanner","name":"Maaltijdplanner","description":"A practical meal planner who answers \"what's for dinner?\" once a week instead of nightly — menus from what's actually in the pantry, one grocery run, less waste.","tags":["meals","cooking","pantry","groceries","home"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Maaltijdplanner","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"meester","name":"Meester","description":"The concierge of a gezel crew — greets new users, understands what they're trying to build, and spins up the right team.","tags":["meester","concierge","core","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.4.0","releasedAt":"2026-07-05T00:00:00Z","role":"Meester","about":"about.md","suggestedTools":[],"meesterCandidate":true,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.4.0","1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"mock-interviewer","name":"Oefen-interviewer","description":"A mock interviewer who asks the hard questions for real — then debriefs kindly, with specifics you can actually fix before it counts.","tags":["interview","practice","career","questions","coaching"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Oefen-interviewer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"penningmeester","name":"Penningmeester","description":"A calm, unjudging treasurer for the household. Keeps the ledger honest, closes each month in minutes, and answers \"where does it actually go?\" with numbers, not lectures.","tags":["budget","money","household","ledger"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Penningmeester","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"planner","name":"Planner","description":"Turns fuzzy asks into concrete steps — good at the 'what' and the 'in what order', less opinionated on the 'how'.","tags":["planner","strategy"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.1.0","releasedAt":"2026-05-28T00:00:00Z","role":"Planner","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"reisleider","name":"Reisleider","description":"A well-traveled guide who plans trips people actually take: a day-by-day itinerary with slack in it, a packing list that fits the weather, and a journal worth keeping afterward.","tags":["travel","trip","itinerary","packing"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Reisleider","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"researcher","name":"Researcher","description":"Reads source, prior art, or external docs and files a substantive written analysis. Long-form deliverables go to disk; chat carries the path + a short precis.","tags":["researcher","analysis","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.2.0","releasedAt":"2026-07-05T00:00:00Z","role":"Researcher","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"reviewer","name":"Reviewer","description":"Second set of eyes on code, docs, or plans. Sharp on quality, clear on feedback.","tags":["reviewer","quality","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.3.0","releasedAt":"2026-07-05T00:00:00Z","role":"Reviewer","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.3.0","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"chess-player","name":"Schaakspeler","description":"A thoughtful, warm chess opponent who plays a complete legal game, keeps plans private, and makes the table welcoming whether the result is a win, loss, or draw.","tags":["chess","game","opponent","strategy","play"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-28T00:00:00Z","role":"Schaakspeler","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"schrijfmaat","name":"Schrijfmaat","description":"A warm writing companion for the long haul of a novel. Guards the daily words, keeps the chapter board honest, and reads drafts like a friend who wants the book to exist.","tags":["writing","novel","fiction","drafting"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Schrijfmaat","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"study-buddy","name":"Studiemaat","description":"A patient study companion who writes sharp flashcards, keeps the review rhythm going, and cheers the streak without ever shaming a miss.","tags":["study","flashcards","learning","practice"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Studiemaat","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-general"},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"video-generator","name":"Video generator","description":"Turns your prompts into short video clips. Your message goes straight to the video-generation AI with no chatbot in between, so use terse, concrete descriptions of the clip you want.","tags":["video","passthrough","generative"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-06-18T00:00:00Z","role":"Video generator","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"fixedFunction":{"tool":"generate_video","promptKey":"prompt"}},"availableVersions":["1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"voorman","name":"Voorman","description":"Foreman of a project — plans tasks, delegates to the right gezels, and keeps work moving.","tags":["voorman","planning","delegation","recommended"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.6.0","releasedAt":"2026-07-05T00:00:00Z","role":"Voorman","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.6.0","1.5.0","1.4.0","1.3.0","1.2.1","1.2.0","1.1.0","1.0.0"]}},{"manifest":{"schemaVersion":1,"kind":"gezel-template","id":"zorgcoordinator","name":"Zorgcoördinator","description":"A warm, discreet care coordinator. Keeps the medication list current, every appointment prepped, and the family on the same page — and everything stays on this machine.","tags":["caregiving","health","family","appointments"],"maintainer":{"name":"Gezel"},"license":"MIT","version":"1.0.0","releasedAt":"2026-07-18T00:00:00Z","role":"Zorgcoördinator","about":"about.md","suggestedTools":[],"meesterCandidate":false,"frontmatter":{"suggestedTuningProfile":"thinking-precise"},"availableVersions":["1.0.0"]}}]}
@@ -0,0 +1,20 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "kind": "project-type",
4
+ "id": "chess",
5
+ "name": "Chess",
6
+ "description": "Play a complete game of chess against a gezel opponent on a live board. You move white; the Schaakspeler sees the exact position, replies with a legal move, and shares the table without spoiling your plans.",
7
+ "tags": [
8
+ "chess",
9
+ "game",
10
+ "board-game",
11
+ "strategy",
12
+ "play"
13
+ ],
14
+ "category": "game",
15
+ "maintainer": {
16
+ "name": "Gezel"
17
+ },
18
+ "license": "MIT",
19
+ "yankedVersions": []
20
+ }
@@ -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.
@@ -0,0 +1,127 @@
1
+ {
2
+ "version": 1,
3
+ "squares": "rnbqkbnrpppppppp................................PPPPPPPPRNBQKBNR",
4
+ "turn": "user",
5
+ "status": "playing",
6
+ "castling": "KQkq",
7
+ "enPassant": null,
8
+ "halfmoveClock": 0,
9
+ "fullmoveNumber": 1,
10
+ "positionHistory": [
11
+ "rnbqkbnrpppppppp................................PPPPPPPPRNBQKBNR|user|KQkq|-"
12
+ ],
13
+ "legalMoves": [
14
+ {
15
+ "from": "a2",
16
+ "to": "a3",
17
+ "capture": false
18
+ },
19
+ {
20
+ "from": "a2",
21
+ "to": "a4",
22
+ "capture": false,
23
+ "doublePawn": true
24
+ },
25
+ {
26
+ "from": "b2",
27
+ "to": "b3",
28
+ "capture": false
29
+ },
30
+ {
31
+ "from": "b2",
32
+ "to": "b4",
33
+ "capture": false,
34
+ "doublePawn": true
35
+ },
36
+ {
37
+ "from": "c2",
38
+ "to": "c3",
39
+ "capture": false
40
+ },
41
+ {
42
+ "from": "c2",
43
+ "to": "c4",
44
+ "capture": false,
45
+ "doublePawn": true
46
+ },
47
+ {
48
+ "from": "d2",
49
+ "to": "d3",
50
+ "capture": false
51
+ },
52
+ {
53
+ "from": "d2",
54
+ "to": "d4",
55
+ "capture": false,
56
+ "doublePawn": true
57
+ },
58
+ {
59
+ "from": "e2",
60
+ "to": "e3",
61
+ "capture": false
62
+ },
63
+ {
64
+ "from": "e2",
65
+ "to": "e4",
66
+ "capture": false,
67
+ "doublePawn": true
68
+ },
69
+ {
70
+ "from": "f2",
71
+ "to": "f3",
72
+ "capture": false
73
+ },
74
+ {
75
+ "from": "f2",
76
+ "to": "f4",
77
+ "capture": false,
78
+ "doublePawn": true
79
+ },
80
+ {
81
+ "from": "g2",
82
+ "to": "g3",
83
+ "capture": false
84
+ },
85
+ {
86
+ "from": "g2",
87
+ "to": "g4",
88
+ "capture": false,
89
+ "doublePawn": true
90
+ },
91
+ {
92
+ "from": "h2",
93
+ "to": "h3",
94
+ "capture": false
95
+ },
96
+ {
97
+ "from": "h2",
98
+ "to": "h4",
99
+ "capture": false,
100
+ "doublePawn": true
101
+ },
102
+ {
103
+ "from": "b1",
104
+ "to": "a3",
105
+ "capture": false
106
+ },
107
+ {
108
+ "from": "b1",
109
+ "to": "c3",
110
+ "capture": false
111
+ },
112
+ {
113
+ "from": "g1",
114
+ "to": "f3",
115
+ "capture": false
116
+ },
117
+ {
118
+ "from": "g1",
119
+ "to": "h3",
120
+ "capture": false
121
+ }
122
+ ],
123
+ "moveLog": [],
124
+ "lastMove": null,
125
+ "lastMoveThought": "",
126
+ "updatedAt": "2026-07-28T00:00:00.000Z"
127
+ }
@@ -0,0 +1,180 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "version": "1.0.0",
4
+ "releasedAt": "2026-07-28T00:00:00Z",
5
+ "meesterManaged": false,
6
+ "mode": "solo",
7
+ "leadLabel": "Opponent",
8
+ "leanProfile": true,
9
+ "tabVisibility": {
10
+ "overview": false,
11
+ "tasks": false,
12
+ "approvals": false,
13
+ "workspace": false,
14
+ "artifacts": false,
15
+ "map": false
16
+ },
17
+ "params": {
18
+ "type": "object",
19
+ "properties": {
20
+ "personality": {
21
+ "type": "string",
22
+ "title": "Table-talk style",
23
+ "description": "How your opponent talks between moves.",
24
+ "enum": [
25
+ "peppy",
26
+ "cheeky",
27
+ "zen",
28
+ "gracious"
29
+ ],
30
+ "default": "peppy"
31
+ },
32
+ "playStyle": {
33
+ "type": "string",
34
+ "title": "How should the Schaakspeler play?",
35
+ "description": "An opponent keeps their strategy to themselves; an instructor offers light teaching notes.",
36
+ "enum": [
37
+ "Opponent",
38
+ "Instructor"
39
+ ],
40
+ "default": "Opponent"
41
+ }
42
+ },
43
+ "required": [
44
+ "personality",
45
+ "playStyle"
46
+ ]
47
+ },
48
+ "nameTemplate": "Chess vs the Schaakspeler",
49
+ "aboutTemplate": "about.md",
50
+ "missionTemplate": "mission.md",
51
+ "gezels": [
52
+ {
53
+ "templateId": "chess-player",
54
+ "voorman": true
55
+ }
56
+ ],
57
+ "scripts": {
58
+ "game-store": "import { type InferredInput, defineScript, gezel } from '@bendyline/gezel-sdk';\n\nexport const meta = defineScript({\n name: 'game-store',\n description:\n \"Read and update the chess game (game.json). Call action:'board' to see the position and every legal move; action:'ai_move' to play your move (from/to, optional promotion and moveThought); action:'state' for a light summary; action:'new_game' to reset. Illegal moves fail with the engine's legal-move list.\",\n inputs: {\n action: {\n type: 'string',\n description: \"One of 'state', 'board', 'user_move', 'ai_move', or 'new_game'.\",\n required: true,\n },\n from: { type: 'string', description: \"Origin square, e.g. 'e7'.\" },\n to: { type: 'string', description: \"Destination square, e.g. 'e5'.\" },\n promotion: {\n type: 'string',\n description: \"Promotion piece: 'q', 'r', 'b', or 'n'. Defaults to queen.\",\n },\n moveThought: {\n type: 'string',\n description: 'A short line of table talk to show on the board (max 140 chars).',\n },\n },\n outputs: {\n board: { type: 'string', description: 'ASCII board with coordinates.' },\n turn: { type: 'string', description: \"Whose move: 'user' (white) or 'ai' (black).\" },\n status: {\n type: 'string',\n description: 'playing, user_won, ai_won, or draw.',\n },\n lastMove: { type: 'string', description: \"The move just played, e.g. 'e2-e4'.\" },\n legalMoves: { type: 'string', description: 'Rendered legal moves for the side to move.' },\n summary: { type: 'string', description: 'Human-readable game summary.' },\n },\n requires: ['workspace.read', 'workspace.write'],\n} as const);\n\nconst input = gezel.input as InferredInput<typeof meta>;\n\n// ── chess-rules-start ──\n// Pure, annotation-free chess engine. Squares are a 64-character row-major\n// string: y0 is rank 8, x0 is file a. Uppercase pieces are white (the user);\n// lowercase pieces are black (the AI).\n\nvar FILES = 'abcdefgh';\nvar PROMOTIONS = ['q', 'r', 'b', 'n'];\n\nfunction sqName(x, y) {\n return FILES[x] + String(8 - y);\n}\n\nfunction parseSq(name) {\n if (typeof name !== 'string' || name.length !== 2) return null;\n var x = FILES.indexOf(name[0].toLowerCase());\n var rank = Number(name[1]);\n if (x < 0 || !(rank >= 1 && rank <= 8)) return null;\n return { x: x, y: 8 - rank };\n}\n\nfunction inBounds(x, y) {\n return x >= 0 && x < 8 && y >= 0 && y < 8;\n}\n\nfunction pieceAt(squares, x, y) {\n return squares[y * 8 + x];\n}\n\nfunction withPiece(squares, x, y, ch) {\n var i = y * 8 + x;\n return squares.slice(0, i) + ch + squares.slice(i + 1);\n}\n\nfunction sideOf(ch) {\n if (!ch || ch === '.') return null;\n return ch === ch.toUpperCase() ? 'user' : 'ai';\n}\n\nfunction otherSide(side) {\n return side === 'user' ? 'ai' : 'user';\n}\n\nfunction kindOf(ch) {\n return ch && ch !== '.' ? ch.toLowerCase() : '';\n}\n\nfunction buildInitial() {\n return 'rnbqkbnr' + 'pppppppp' + '.'.repeat(32) + 'PPPPPPPP' + 'RNBQKBNR';\n}\n\nfunction findKing(squares, side) {\n var needle = side === 'user' ? 'K' : 'k';\n var i = squares.indexOf(needle);\n return i < 0 ? null : { x: i % 8, y: Math.floor(i / 8) };\n}\n\nfunction isAttacked(squares, x, y, bySide) {\n var pawn = bySide === 'user' ? 'P' : 'p';\n var pawnY = y - (bySide === 'user' ? -1 : 1);\n for (var pdx of [-1, 1]) {\n var px = x - pdx;\n if (inBounds(px, pawnY) && pieceAt(squares, px, pawnY) === pawn) return true;\n }\n\n var knight = bySide === 'user' ? 'N' : 'n';\n var knightSteps = [\n [-2, -1],\n [-2, 1],\n [-1, -2],\n [-1, 2],\n [1, -2],\n [1, 2],\n [2, -1],\n [2, 1],\n ];\n for (var n of knightSteps) {\n if (inBounds(x + n[0], y + n[1]) && pieceAt(squares, x + n[0], y + n[1]) === knight) {\n return true;\n }\n }\n\n var rays = [\n [-1, 0, 'rq'],\n [1, 0, 'rq'],\n [0, -1, 'rq'],\n [0, 1, 'rq'],\n [-1, -1, 'bq'],\n [-1, 1, 'bq'],\n [1, -1, 'bq'],\n [1, 1, 'bq'],\n ];\n for (var ray of rays) {\n var rx = x + ray[0];\n var ry = y + ray[1];\n while (inBounds(rx, ry)) {\n var seen = pieceAt(squares, rx, ry);\n if (seen !== '.') {\n if (sideOf(seen) === bySide && ray[2].indexOf(kindOf(seen)) >= 0) return true;\n break;\n }\n rx += ray[0];\n ry += ray[1];\n }\n }\n\n var king = bySide === 'user' ? 'K' : 'k';\n for (var ky = -1; ky <= 1; ky += 1) {\n for (var kx = -1; kx <= 1; kx += 1) {\n if (\n (kx !== 0 || ky !== 0) &&\n inBounds(x + kx, y + ky) &&\n pieceAt(squares, x + kx, y + ky) === king\n ) {\n return true;\n }\n }\n }\n return false;\n}\n\nfunction inCheck(squares, side) {\n var king = findKing(squares, side);\n return !king || isAttacked(squares, king.x, king.y, otherSide(side));\n}\n\nfunction pushMove(out, fromX, fromY, toX, toY, extra) {\n out.push(\n Object.assign(\n {\n from: sqName(fromX, fromY),\n to: sqName(toX, toY),\n capture: false,\n },\n extra || {},\n ),\n );\n}\n\nfunction pseudoMovesFor(squares, side, castling, enPassant) {\n var out = [];\n for (var y = 0; y < 8; y += 1) {\n for (var x = 0; x < 8; x += 1) {\n var ch = pieceAt(squares, x, y);\n if (sideOf(ch) !== side) continue;\n var kind = kindOf(ch);\n\n if (kind === 'p') {\n var dir = side === 'user' ? -1 : 1;\n var startY = side === 'user' ? 6 : 1;\n var promotionY = side === 'user' ? 0 : 7;\n var oneY = y + dir;\n if (inBounds(x, oneY) && pieceAt(squares, x, oneY) === '.') {\n if (oneY === promotionY) {\n for (var promotion of PROMOTIONS) {\n pushMove(out, x, y, x, oneY, { promotion: promotion });\n }\n } else {\n pushMove(out, x, y, x, oneY);\n var twoY = y + dir * 2;\n if (y === startY && pieceAt(squares, x, twoY) === '.') {\n pushMove(out, x, y, x, twoY, { doublePawn: true });\n }\n }\n }\n for (var dx of [-1, 1]) {\n var cx = x + dx;\n var cy = y + dir;\n if (!inBounds(cx, cy)) continue;\n var target = pieceAt(squares, cx, cy);\n var targetName = sqName(cx, cy);\n var isEp = targetName === enPassant && target === '.';\n if ((target !== '.' && sideOf(target) === otherSide(side)) || isEp) {\n if (cy === promotionY) {\n for (var capturePromotion of PROMOTIONS) {\n pushMove(out, x, y, cx, cy, {\n capture: true,\n promotion: capturePromotion,\n enPassant: isEp,\n });\n }\n } else {\n pushMove(out, x, y, cx, cy, { capture: true, enPassant: isEp });\n }\n }\n }\n continue;\n }\n\n if (kind === 'n') {\n var jumps = [\n [-2, -1],\n [-2, 1],\n [-1, -2],\n [-1, 2],\n [1, -2],\n [1, 2],\n [2, -1],\n [2, 1],\n ];\n for (var jump of jumps) {\n var nx = x + jump[0];\n var ny = y + jump[1];\n if (!inBounds(nx, ny) || sideOf(pieceAt(squares, nx, ny)) === side) continue;\n pushMove(out, x, y, nx, ny, { capture: pieceAt(squares, nx, ny) !== '.' });\n }\n continue;\n }\n\n if (kind === 'b' || kind === 'r' || kind === 'q') {\n var dirs = [];\n if (kind === 'b' || kind === 'q') dirs.push([-1, -1], [-1, 1], [1, -1], [1, 1]);\n if (kind === 'r' || kind === 'q') dirs.push([-1, 0], [1, 0], [0, -1], [0, 1]);\n for (var d of dirs) {\n var sx = x + d[0];\n var sy = y + d[1];\n while (inBounds(sx, sy)) {\n var occupant = pieceAt(squares, sx, sy);\n if (sideOf(occupant) === side) break;\n pushMove(out, x, y, sx, sy, { capture: occupant !== '.' });\n if (occupant !== '.') break;\n sx += d[0];\n sy += d[1];\n }\n }\n continue;\n }\n\n if (kind === 'k') {\n for (var kdy = -1; kdy <= 1; kdy += 1) {\n for (var kdx = -1; kdx <= 1; kdx += 1) {\n if (kdx === 0 && kdy === 0) continue;\n var ktx = x + kdx;\n var kty = y + kdy;\n if (!inBounds(ktx, kty) || sideOf(pieceAt(squares, ktx, kty)) === side) continue;\n pushMove(out, x, y, ktx, kty, { capture: pieceAt(squares, ktx, kty) !== '.' });\n }\n }\n\n var homeY = side === 'user' ? 7 : 0;\n var kingChar = side === 'user' ? 'K' : 'k';\n var rookChar = side === 'user' ? 'R' : 'r';\n var enemy = otherSide(side);\n if (x === 4 && y === homeY && ch === kingChar && !isAttacked(squares, 4, homeY, enemy)) {\n var kingRight = side === 'user' ? castling.indexOf('K') >= 0 : castling.indexOf('k') >= 0;\n if (\n kingRight &&\n pieceAt(squares, 7, homeY) === rookChar &&\n pieceAt(squares, 5, homeY) === '.' &&\n pieceAt(squares, 6, homeY) === '.' &&\n !isAttacked(squares, 5, homeY, enemy) &&\n !isAttacked(squares, 6, homeY, enemy)\n ) {\n pushMove(out, x, y, 6, homeY, { castle: 'king' });\n }\n var queenRight = side === 'user' ? castling.indexOf('Q') >= 0 : castling.indexOf('q') >= 0;\n if (\n queenRight &&\n pieceAt(squares, 0, homeY) === rookChar &&\n pieceAt(squares, 1, homeY) === '.' &&\n pieceAt(squares, 2, homeY) === '.' &&\n pieceAt(squares, 3, homeY) === '.' &&\n !isAttacked(squares, 3, homeY, enemy) &&\n !isAttacked(squares, 2, homeY, enemy)\n ) {\n pushMove(out, x, y, 2, homeY, { castle: 'queen' });\n }\n }\n }\n }\n }\n return out;\n}\n\nfunction applyUnchecked(squares, move, side) {\n var from = parseSq(move.from);\n var to = parseSq(move.to);\n var ch = pieceAt(squares, from.x, from.y);\n var next = withPiece(squares, from.x, from.y, '.');\n if (move.enPassant) {\n next = withPiece(next, to.x, from.y, '.');\n }\n if (move.castle === 'king') {\n next = withPiece(next, 7, from.y, '.');\n next = withPiece(next, 5, from.y, side === 'user' ? 'R' : 'r');\n } else if (move.castle === 'queen') {\n next = withPiece(next, 0, from.y, '.');\n next = withPiece(next, 3, from.y, side === 'user' ? 'R' : 'r');\n }\n if (move.promotion) ch = side === 'user' ? move.promotion.toUpperCase() : move.promotion;\n return withPiece(next, to.x, to.y, ch);\n}\n\nfunction legalMovesFor(squares, side, castling, enPassant) {\n return pseudoMovesFor(squares, side, castling || '', enPassant || null).filter(function (move) {\n return !inCheck(applyUnchecked(squares, move, side), side);\n });\n}\n\nfunction nextCastling(castling, squares, move) {\n var rights = castling || '';\n var ch = pieceAt(squares, parseSq(move.from).x, parseSq(move.from).y);\n if (ch === 'K') rights = rights.replace(/K|Q/g, '');\n if (ch === 'k') rights = rights.replace(/k|q/g, '');\n if (move.from === 'a1' || move.to === 'a1') rights = rights.replace('Q', '');\n if (move.from === 'h1' || move.to === 'h1') rights = rights.replace('K', '');\n if (move.from === 'a8' || move.to === 'a8') rights = rights.replace('q', '');\n if (move.from === 'h8' || move.to === 'h8') rights = rights.replace('k', '');\n return rights;\n}\n\nfunction nextEnPassant(move, side) {\n if (!move.doublePawn) return null;\n var from = parseSq(move.from);\n var to = parseSq(move.to);\n return sqName(from.x, (from.y + to.y) / 2);\n}\n\nfunction isInsufficientMaterial(squares) {\n var pieces = [];\n for (var i = 0; i < squares.length; i += 1) {\n var ch = squares[i];\n if (ch !== '.' && kindOf(ch) !== 'k') pieces.push({ ch: ch, x: i % 8, y: Math.floor(i / 8) });\n }\n if (pieces.length === 0) return true;\n if (pieces.length === 1 && (kindOf(pieces[0].ch) === 'b' || kindOf(pieces[0].ch) === 'n')) {\n return true;\n }\n if (\n pieces.length > 0 &&\n pieces.every(function (p) {\n return kindOf(p.ch) === 'b';\n })\n ) {\n var color = (pieces[0].x + pieces[0].y) % 2;\n return pieces.every(function (p) {\n return (p.x + p.y) % 2 === color;\n });\n }\n return false;\n}\n\nfunction positionKey(squares, side, castling, enPassant) {\n var effectiveEnPassant =\n enPassant &&\n legalMovesFor(squares, side, castling, enPassant).some(function (move) {\n return move.enPassant;\n })\n ? enPassant\n : '-';\n return [squares, side, castling || '-', effectiveEnPassant].join('|');\n}\n\nfunction statusAfter(squares, sideToMove, castling, enPassant) {\n if (isInsufficientMaterial(squares)) return 'draw';\n var moves = legalMovesFor(squares, sideToMove, castling, enPassant);\n if (moves.length > 0) return 'playing';\n if (!inCheck(squares, sideToMove)) return 'draw';\n return sideToMove === 'user' ? 'ai_won' : 'user_won';\n}\n\nfunction describeMove(move) {\n if (move.castle === 'king') return move.from + '-' + move.to + ' (O-O)';\n if (move.castle === 'queen') return move.from + '-' + move.to + ' (O-O-O)';\n var text = move.from + (move.capture ? 'x' : '-') + move.to;\n if (move.promotion) text += '=' + move.promotion.toUpperCase();\n if (move.enPassant) text += ' e.p.';\n return text;\n}\n\nfunction renderAscii(squares) {\n var lines = [' a b c d e f g h'];\n for (var y = 0; y < 8; y += 1) {\n var row = String(8 - y);\n for (var x = 0; x < 8; x += 1) row += ' ' + pieceAt(squares, x, y);\n lines.push(row + ' ' + String(8 - y));\n }\n lines.push(' a b c d e f g h');\n lines.push('Uppercase = white (user). Lowercase = black (you).');\n return lines.join('\\n');\n}\n// ── chess-rules-end ──\n\nconst STATE_FILE = 'game.json';\nconst SIDE_NAMES = { user: 'white', ai: 'black' };\n\ninterface ChessMove {\n from: string;\n to: string;\n capture: boolean;\n promotion?: string;\n doublePawn?: boolean;\n enPassant?: boolean;\n castle?: string;\n}\n\ninterface GameState {\n version: number;\n squares: string;\n turn: 'user' | 'ai';\n status: 'playing' | 'user_won' | 'ai_won' | 'draw';\n castling: string;\n enPassant: string | null;\n halfmoveClock: number;\n fullmoveNumber: number;\n positionHistory: string[];\n legalMoves: ChessMove[];\n moveLog: Array<{\n by: 'user' | 'ai';\n from: string;\n to: string;\n promotion?: string;\n notation: string;\n at: string;\n moveThought?: string;\n }>;\n lastMove: {\n by: 'user' | 'ai';\n from: string;\n to: string;\n promotion?: string;\n notation: string;\n } | null;\n lastMoveThought: string;\n updatedAt: string;\n}\n\nfunction freshState(): GameState {\n const squares = buildInitial();\n const castling = 'KQkq';\n return {\n version: 1,\n squares,\n turn: 'user',\n status: 'playing',\n castling,\n enPassant: null,\n halfmoveClock: 0,\n fullmoveNumber: 1,\n positionHistory: [positionKey(squares, 'user', castling, null)],\n legalMoves: legalMovesFor(squares, 'user', castling, null),\n moveLog: [],\n lastMove: null,\n lastMoveThought: '',\n updatedAt: new Date().toISOString(),\n };\n}\n\nasync function load(): Promise<GameState> {\n let raw: string;\n try {\n raw = await gezel.fs.read(STATE_FILE);\n } catch {\n return freshState();\n }\n const parsed = JSON.parse(raw) as Partial<GameState>;\n if (typeof parsed.squares !== 'string' || parsed.squares.length !== 64) {\n throw new Error(`${STATE_FILE} is corrupt; call action:'new_game' to reset.`);\n }\n return {\n ...freshState(),\n ...parsed,\n castling: typeof parsed.castling === 'string' ? parsed.castling : '',\n enPassant: parsed.enPassant ?? null,\n } as GameState;\n}\n\nasync function persist(state: GameState): Promise<GameState> {\n state.legalMoves =\n state.status === 'playing'\n ? legalMovesFor(state.squares, state.turn, state.castling, state.enPassant)\n : [];\n state.updatedAt = new Date().toISOString();\n await gezel.fs.write(STATE_FILE, `${JSON.stringify(state, null, 2)}\\n`);\n return state;\n}\n\nfunction renderLegal(state: GameState): string {\n if (state.status !== 'playing') return '(game over)';\n return state.legalMoves.map(describeMove).join(', ') || '(none)';\n}\n\nfunction summarize(state: GameState): string {\n if (state.status === 'user_won') return 'Checkmate — the user (white) won.';\n if (state.status === 'ai_won') return 'Checkmate — you (black) won.';\n if (state.status === 'draw') return 'Game over — draw.';\n const check = inCheck(state.squares, state.turn) ? ' The king is in check.' : '';\n return `Move ${state.fullmoveNumber}: ${SIDE_NAMES[state.turn]} (${state.turn}) to move.${check}`;\n}\n\nfunction applyTurn(\n state: GameState,\n by: 'user' | 'ai',\n moveThought?: string,\n): { state: GameState; move: ChessMove } {\n if (state.status !== 'playing') {\n throw new Error(`The game is over (${state.status}). Call action:'new_game' to start another.`);\n }\n if (state.turn !== by) {\n throw new Error(by === 'ai' ? \"It's not your turn yet.\" : 'The opponent is still to move.');\n }\n if (!input.from || !input.to) throw new Error(\"Pass 'from' and 'to' squares.\");\n const wantedPromotion = (input.promotion || 'q').toLowerCase();\n const candidates = state.legalMoves.filter(\n (move) =>\n move.from === input.from!.toLowerCase() &&\n move.to === input.to!.toLowerCase(),\n );\n const move =\n candidates.find((candidate) => (candidate.promotion || 'q') === wantedPromotion) ??\n candidates.find((candidate) => !candidate.promotion);\n if (!move) {\n throw new Error(\n `Illegal move ${input.from}-${input.to}. Legal moves for ${SIDE_NAMES[by]}: ${renderLegal(state)}`,\n );\n }\n\n const movingPiece = pieceAt(\n state.squares,\n parseSq(move.from)!.x,\n parseSq(move.from)!.y,\n );\n const oldSquares = state.squares;\n state.castling = nextCastling(state.castling, oldSquares, move);\n state.squares = applyUnchecked(oldSquares, move, by);\n state.enPassant = nextEnPassant(move, by);\n state.halfmoveClock =\n kindOf(movingPiece) === 'p' || move.capture ? 0 : state.halfmoveClock + 1;\n if (by === 'ai') state.fullmoveNumber += 1;\n state.turn = otherSide(by) as 'user' | 'ai';\n const key = positionKey(state.squares, state.turn, state.castling, state.enPassant);\n state.positionHistory.push(key);\n state.status = statusAfter(\n state.squares,\n state.turn,\n state.castling,\n state.enPassant,\n ) as GameState['status'];\n if (\n state.status === 'playing' &&\n (state.halfmoveClock >= 100 ||\n state.positionHistory.filter((candidate) => candidate === key).length >= 3)\n ) {\n state.status = 'draw';\n }\n\n const notation = describeMove(move);\n const entry = {\n by,\n from: move.from,\n to: move.to,\n ...(move.promotion ? { promotion: move.promotion } : {}),\n notation,\n at: new Date().toISOString(),\n ...(moveThought ? { moveThought } : {}),\n };\n state.moveLog.push(entry);\n state.lastMove = {\n by,\n from: move.from,\n to: move.to,\n ...(move.promotion ? { promotion: move.promotion } : {}),\n notation,\n };\n if (by === 'ai' && moveThought) state.lastMoveThought = moveThought;\n return { state, move };\n}\n\nlet state = await load();\nlet lastMoveText = state.lastMove?.notation ?? '(none)';\n\nif (input.action === 'new_game') {\n state = await persist(freshState());\n lastMoveText = '(none)';\n} else if (input.action === 'user_move' || input.action === 'ai_move') {\n const by = input.action === 'user_move' ? 'user' : 'ai';\n const moveThought = input.moveThought?.trim().slice(0, 140);\n const applied = applyTurn(state, by, moveThought);\n state = await persist(applied.state);\n lastMoveText = describeMove(applied.move);\n} else if (input.action !== 'state' && input.action !== 'board') {\n throw new Error(`Unknown action '${input.action}'. Use state, board, user_move, ai_move, or new_game.`);\n}\n\ngezel.output({\n board:\n `${renderAscii(state.squares)}\\nTurn: ${SIDE_NAMES[state.turn]} (${state.turn}).` +\n `${inCheck(state.squares, state.turn) && state.status === 'playing' ? ' CHECK.' : ''}\\n` +\n `Legal moves: ${renderLegal(state)}`,\n turn: state.turn,\n status: state.status,\n lastMove: lastMoveText,\n legalMoves: renderLegal(state),\n summary: summarize(state),\n});\n"
59
+ },
60
+ "tools": [
61
+ {
62
+ "name": "get_board",
63
+ "description": "See the authoritative chess position, whose turn it is, and every legal move.",
64
+ "script": "game-store",
65
+ "inputs": {
66
+ "type": "object",
67
+ "properties": {}
68
+ },
69
+ "bind": {
70
+ "action": "board"
71
+ }
72
+ },
73
+ {
74
+ "name": "make_move",
75
+ "description": "Play your black move. Pass from/to; for promotion optionally choose 'q', 'r', 'b', or 'n'. Include a short moveThought for the board.",
76
+ "script": "game-store",
77
+ "inputs": {
78
+ "type": "object",
79
+ "properties": {
80
+ "from": {
81
+ "type": "string",
82
+ "description": "Origin square, e.g. 'e7'."
83
+ },
84
+ "to": {
85
+ "type": "string",
86
+ "description": "Destination square, e.g. 'e5'."
87
+ },
88
+ "promotion": {
89
+ "type": "string",
90
+ "enum": [
91
+ "q",
92
+ "r",
93
+ "b",
94
+ "n"
95
+ ],
96
+ "description": "Promotion piece. Defaults to queen."
97
+ },
98
+ "moveThought": {
99
+ "type": "string",
100
+ "description": "A short line of table talk (max 140 chars)."
101
+ }
102
+ },
103
+ "required": [
104
+ "from",
105
+ "to"
106
+ ]
107
+ },
108
+ "bind": {
109
+ "action": "ai_move"
110
+ }
111
+ },
112
+ {
113
+ "name": "user_move",
114
+ "description": "The user's white move, played from the chess board.",
115
+ "script": "game-store",
116
+ "inputs": {
117
+ "type": "object",
118
+ "properties": {
119
+ "from": {
120
+ "type": "string"
121
+ },
122
+ "to": {
123
+ "type": "string"
124
+ },
125
+ "promotion": {
126
+ "type": "string",
127
+ "enum": [
128
+ "q",
129
+ "r",
130
+ "b",
131
+ "n"
132
+ ]
133
+ }
134
+ },
135
+ "required": [
136
+ "from",
137
+ "to"
138
+ ]
139
+ },
140
+ "bind": {
141
+ "action": "user_move"
142
+ },
143
+ "reaction": {
144
+ "gezel": "chess-player",
145
+ "hideSeed": true,
146
+ "prompt": "Your opponent played {{output.lastMove}}. Status: {{output.status}}. Board now:\n{{output.board}}\nThe board and Legal moves line come directly from the chess engine and are always correct. Do not re-derive the position, dispute a listed move, or invent a move outside that list. Spend your thought on choosing among the listed legal moves.\nStyle: {{playStyle}}. In Opponent style, do not volunteer advice or reveal the user’s available moves, threats, tactics, or your plan; comment only about your own move or the atmosphere. In Instructor style, offer at most one brief teaching observation without choosing the user’s move. Answer strategy questions when asked.\nAct on this latest position. If the game is over, do not move — give one gracious line and offer a new game. Otherwise choose a strong legal move and play it with make_move, including a short {{personality}} moveThought that follows the selected style. If make_move rejects it, choose one move verbatim from the legal list in the error and retry. After moving, reply with ONE short line of table talk."
147
+ }
148
+ },
149
+ {
150
+ "name": "new_game",
151
+ "description": "Reset the chess board to the standard opening position.",
152
+ "script": "game-store",
153
+ "inputs": {
154
+ "type": "object",
155
+ "properties": {}
156
+ },
157
+ "bind": {
158
+ "action": "new_game"
159
+ }
160
+ }
161
+ ],
162
+ "craftbooks": [],
163
+ "schedules": [],
164
+ "pages": {
165
+ "entry": "board/index.html",
166
+ "reads": [
167
+ {
168
+ "source": "workspace",
169
+ "path": "game.json"
170
+ }
171
+ ],
172
+ "tools": [
173
+ "user_move",
174
+ "new_game"
175
+ ]
176
+ },
177
+ "workspaceSeed": [
178
+ "game.json"
179
+ ]
180
+ }
@@ -0,0 +1,8 @@
1
+ - Keep a standard chess position ready, with white moving first and a rematch one
2
+ press away.
3
+ - The Schaakspeler answers every user move with a legal black move of their own.
4
+ - Let the engine settle check, mate, stalemate, promotion, castling, en passant,
5
+ repetition, and fifty-move draws.
6
+ - Keep table talk {{personality}} and kind, matching the chosen {{playStyle}}:
7
+ Opponents do not leak plans or hints; Instructors teach lightly.
8
+ - End wins, losses, and draws graciously, with an easy offer of another game.