c64-kb 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (970) hide show
  1. package/CHANGELOG.md +2082 -0
  2. package/LICENSE +29 -0
  3. package/README.md +559 -0
  4. package/VERSION +25 -0
  5. package/dist/cli/setup.js +66 -0
  6. package/dist/cli/setup.js.map +1 -0
  7. package/dist/cli-memorize-audit.js +97 -0
  8. package/dist/cli-memorize-audit.js.map +1 -0
  9. package/dist/cli.js +335 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/config.js +83 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/context.js +53 -0
  14. package/dist/context.js.map +1 -0
  15. package/dist/domain/budget-notes.js +104 -0
  16. package/dist/domain/budget-notes.js.map +1 -0
  17. package/dist/domain/budget.js +417 -0
  18. package/dist/domain/budget.js.map +1 -0
  19. package/dist/domain/game-design.js +77 -0
  20. package/dist/domain/game-design.js.map +1 -0
  21. package/dist/domain/timing.js +39 -0
  22. package/dist/domain/timing.js.map +1 -0
  23. package/dist/graph/apply.js +132 -0
  24. package/dist/graph/apply.js.map +1 -0
  25. package/dist/graph/claims.js +231 -0
  26. package/dist/graph/claims.js.map +1 -0
  27. package/dist/graph/extract/archetype.js +118 -0
  28. package/dist/graph/extract/archetype.js.map +1 -0
  29. package/dist/graph/extract/common.js +69 -0
  30. package/dist/graph/extract/common.js.map +1 -0
  31. package/dist/graph/extract/failure.js +37 -0
  32. package/dist/graph/extract/failure.js.map +1 -0
  33. package/dist/graph/extract/game-design.js +189 -0
  34. package/dist/graph/extract/game-design.js.map +1 -0
  35. package/dist/graph/extract/hardware.js +124 -0
  36. package/dist/graph/extract/hardware.js.map +1 -0
  37. package/dist/graph/extract/pitfall.js +62 -0
  38. package/dist/graph/extract/pitfall.js.map +1 -0
  39. package/dist/graph/extract/raster-band.js +56 -0
  40. package/dist/graph/extract/raster-band.js.map +1 -0
  41. package/dist/graph/extract/recipe.js +71 -0
  42. package/dist/graph/extract/recipe.js.map +1 -0
  43. package/dist/graph/extract/technique-entities.js +180 -0
  44. package/dist/graph/extract/technique-entities.js.map +1 -0
  45. package/dist/graph/extract/technique.js +179 -0
  46. package/dist/graph/extract/technique.js.map +1 -0
  47. package/dist/graph/extract/toolchain.js +67 -0
  48. package/dist/graph/extract/toolchain.js.map +1 -0
  49. package/dist/graph/extract/types.js +3 -0
  50. package/dist/graph/extract/types.js.map +1 -0
  51. package/dist/graph/extract/vocabulary.js +65 -0
  52. package/dist/graph/extract/vocabulary.js.map +1 -0
  53. package/dist/graph/extract.js +43 -0
  54. package/dist/graph/extract.js.map +1 -0
  55. package/dist/graph/kernal-clobbers.js +64 -0
  56. package/dist/graph/kernal-clobbers.js.map +1 -0
  57. package/dist/graph/machine-variants.js +208 -0
  58. package/dist/graph/machine-variants.js.map +1 -0
  59. package/dist/ingest/files.js +99 -0
  60. package/dist/ingest/files.js.map +1 -0
  61. package/dist/ingest/passes.js +104 -0
  62. package/dist/ingest/passes.js.map +1 -0
  63. package/dist/ingest/points.js +50 -0
  64. package/dist/ingest/points.js.map +1 -0
  65. package/dist/ingest/report.js +140 -0
  66. package/dist/ingest/report.js.map +1 -0
  67. package/dist/ingest/tally.js +81 -0
  68. package/dist/ingest/tally.js.map +1 -0
  69. package/dist/ingest/verified-on.js +43 -0
  70. package/dist/ingest/verified-on.js.map +1 -0
  71. package/dist/ingest.js +135 -0
  72. package/dist/ingest.js.map +1 -0
  73. package/dist/schemas/cost-basis.js +5 -0
  74. package/dist/schemas/cost-basis.js.map +1 -0
  75. package/dist/schemas/machine-variant.js +25 -0
  76. package/dist/schemas/machine-variant.js.map +1 -0
  77. package/dist/schemas/plan-budget.js +121 -0
  78. package/dist/schemas/plan-budget.js.map +1 -0
  79. package/dist/schemas/tool-outputs.js +526 -0
  80. package/dist/schemas/tool-outputs.js.map +1 -0
  81. package/dist/server/define-tool.js +52 -0
  82. package/dist/server/define-tool.js.map +1 -0
  83. package/dist/server/defined-only.js +9 -0
  84. package/dist/server/defined-only.js.map +1 -0
  85. package/dist/server/tools-briefings.js +70 -0
  86. package/dist/server/tools-briefings.js.map +1 -0
  87. package/dist/server/tools-lookup.js +180 -0
  88. package/dist/server/tools-lookup.js.map +1 -0
  89. package/dist/server/tools-maintenance.js +116 -0
  90. package/dist/server/tools-maintenance.js.map +1 -0
  91. package/dist/server/tools-pitfalls.js +89 -0
  92. package/dist/server/tools-pitfalls.js.map +1 -0
  93. package/dist/server/tools-recipes.js +296 -0
  94. package/dist/server/tools-recipes.js.map +1 -0
  95. package/dist/server/tools-runtime.js +48 -0
  96. package/dist/server/tools-runtime.js.map +1 -0
  97. package/dist/server/tools.js +43 -0
  98. package/dist/server/tools.js.map +1 -0
  99. package/dist/server.js +95 -0
  100. package/dist/server.js.map +1 -0
  101. package/dist/services/analytics/schema.js +78 -0
  102. package/dist/services/analytics/schema.js.map +1 -0
  103. package/dist/services/analytics/statements.js +99 -0
  104. package/dist/services/analytics/statements.js.map +1 -0
  105. package/dist/services/analytics.js +195 -0
  106. package/dist/services/analytics.js.map +1 -0
  107. package/dist/services/bm25.js +158 -0
  108. package/dist/services/bm25.js.map +1 -0
  109. package/dist/services/chunker.js +81 -0
  110. package/dist/services/chunker.js.map +1 -0
  111. package/dist/services/embeddings.js +58 -0
  112. package/dist/services/embeddings.js.map +1 -0
  113. package/dist/services/falkor/base.js +85 -0
  114. package/dist/services/falkor/base.js.map +1 -0
  115. package/dist/services/falkor/links.js +361 -0
  116. package/dist/services/falkor/links.js.map +1 -0
  117. package/dist/services/falkor/nodes.js +183 -0
  118. package/dist/services/falkor/nodes.js.map +1 -0
  119. package/dist/services/falkor/params.js +45 -0
  120. package/dist/services/falkor/params.js.map +1 -0
  121. package/dist/services/falkor/schema.js +77 -0
  122. package/dist/services/falkor/schema.js.map +1 -0
  123. package/dist/services/falkor.js +100 -0
  124. package/dist/services/falkor.js.map +1 -0
  125. package/dist/services/qdrant.js +238 -0
  126. package/dist/services/qdrant.js.map +1 -0
  127. package/dist/services/versions.js +73 -0
  128. package/dist/services/versions.js.map +1 -0
  129. package/dist/services/vice-bin.js +51 -0
  130. package/dist/services/vice-bin.js.map +1 -0
  131. package/dist/tools/briefings/archetype.js +174 -0
  132. package/dist/tools/briefings/archetype.js.map +1 -0
  133. package/dist/tools/briefings/budget.js +177 -0
  134. package/dist/tools/briefings/budget.js.map +1 -0
  135. package/dist/tools/briefings/build-order.js +135 -0
  136. package/dist/tools/briefings/build-order.js.map +1 -0
  137. package/dist/tools/briefings/build.js +185 -0
  138. package/dist/tools/briefings/build.js.map +1 -0
  139. package/dist/tools/briefings/discovery.js +290 -0
  140. package/dist/tools/briefings/discovery.js.map +1 -0
  141. package/dist/tools/briefings/plan-pitfalls.js +69 -0
  142. package/dist/tools/briefings/plan-pitfalls.js.map +1 -0
  143. package/dist/tools/briefings/render.js +151 -0
  144. package/dist/tools/briefings/render.js.map +1 -0
  145. package/dist/tools/briefings/rows.js +41 -0
  146. package/dist/tools/briefings/rows.js.map +1 -0
  147. package/dist/tools/briefings/toolchain.js +63 -0
  148. package/dist/tools/briefings/toolchain.js.map +1 -0
  149. package/dist/tools/briefings/why-proposed.js +69 -0
  150. package/dist/tools/briefings/why-proposed.js.map +1 -0
  151. package/dist/tools/briefings.js +44 -0
  152. package/dist/tools/briefings.js.map +1 -0
  153. package/dist/tools/feedback.js +97 -0
  154. package/dist/tools/feedback.js.map +1 -0
  155. package/dist/tools/hydrate.js +75 -0
  156. package/dist/tools/hydrate.js.map +1 -0
  157. package/dist/tools/intelligence.js +67 -0
  158. package/dist/tools/intelligence.js.map +1 -0
  159. package/dist/tools/lint/asm-decimal.js +86 -0
  160. package/dist/tools/lint/asm-decimal.js.map +1 -0
  161. package/dist/tools/lint/asm-rules.js +221 -0
  162. package/dist/tools/lint/asm-rules.js.map +1 -0
  163. package/dist/tools/lint/asm-shared.js +3 -0
  164. package/dist/tools/lint/asm-shared.js.map +1 -0
  165. package/dist/tools/lint/c-rules.js +215 -0
  166. package/dist/tools/lint/c-rules.js.map +1 -0
  167. package/dist/tools/lint/text.js +122 -0
  168. package/dist/tools/lint/text.js.map +1 -0
  169. package/dist/tools/lint/types.js +40 -0
  170. package/dist/tools/lint/types.js.map +1 -0
  171. package/dist/tools/lint.js +76 -0
  172. package/dist/tools/lint.js.map +1 -0
  173. package/dist/tools/memorization-mcp.js +111 -0
  174. package/dist/tools/memorization-mcp.js.map +1 -0
  175. package/dist/tools/pitfalls/bm25.js +53 -0
  176. package/dist/tools/pitfalls/bm25.js.map +1 -0
  177. package/dist/tools/pitfalls/format.js +58 -0
  178. package/dist/tools/pitfalls/format.js.map +1 -0
  179. package/dist/tools/pitfalls/graph.js +124 -0
  180. package/dist/tools/pitfalls/graph.js.map +1 -0
  181. package/dist/tools/pitfalls.js +134 -0
  182. package/dist/tools/pitfalls.js.map +1 -0
  183. package/dist/tools/prompts.js +81 -0
  184. package/dist/tools/prompts.js.map +1 -0
  185. package/dist/tools/query/compatibility/closure.js +62 -0
  186. package/dist/tools/query/compatibility/closure.js.map +1 -0
  187. package/dist/tools/query/compatibility/facts.js +28 -0
  188. package/dist/tools/query/compatibility/facts.js.map +1 -0
  189. package/dist/tools/query/compatibility/fetch.js +164 -0
  190. package/dist/tools/query/compatibility/fetch.js.map +1 -0
  191. package/dist/tools/query/compatibility/hard-rules.js +159 -0
  192. package/dist/tools/query/compatibility/hard-rules.js.map +1 -0
  193. package/dist/tools/query/compatibility/index.js +27 -0
  194. package/dist/tools/query/compatibility/index.js.map +1 -0
  195. package/dist/tools/query/compatibility/kernal-zp-rule.js +90 -0
  196. package/dist/tools/query/compatibility/kernal-zp-rule.js.map +1 -0
  197. package/dist/tools/query/compatibility/render.js +106 -0
  198. package/dist/tools/query/compatibility/render.js.map +1 -0
  199. package/dist/tools/query/compatibility/rules.js +337 -0
  200. package/dist/tools/query/compatibility/rules.js.map +1 -0
  201. package/dist/tools/query/compatibility/unit-rules.js +253 -0
  202. package/dist/tools/query/compatibility/unit-rules.js.map +1 -0
  203. package/dist/tools/query/game-design.js +83 -0
  204. package/dist/tools/query/game-design.js.map +1 -0
  205. package/dist/tools/query/lookups.js +220 -0
  206. package/dist/tools/query/lookups.js.map +1 -0
  207. package/dist/tools/query/plan-budget.js +266 -0
  208. package/dist/tools/query/plan-budget.js.map +1 -0
  209. package/dist/tools/query/recipes.js +214 -0
  210. package/dist/tools/query/recipes.js.map +1 -0
  211. package/dist/tools/query/retrieval.js +128 -0
  212. package/dist/tools/query/retrieval.js.map +1 -0
  213. package/dist/tools/query/shared.js +121 -0
  214. package/dist/tools/query/shared.js.map +1 -0
  215. package/dist/tools/query/techniques.js +331 -0
  216. package/dist/tools/query/techniques.js.map +1 -0
  217. package/dist/tools/query/timing.js +106 -0
  218. package/dist/tools/query/timing.js.map +1 -0
  219. package/dist/tools/query/types.js +11 -0
  220. package/dist/tools/query/types.js.map +1 -0
  221. package/dist/tools/query.js +21 -0
  222. package/dist/tools/query.js.map +1 -0
  223. package/dist/tools/resources.js +186 -0
  224. package/dist/tools/resources.js.map +1 -0
  225. package/dist/tools/run-game.js +249 -0
  226. package/dist/tools/run-game.js.map +1 -0
  227. package/dist/tools/selfimprovement.js +367 -0
  228. package/dist/tools/selfimprovement.js.map +1 -0
  229. package/docker-compose.yml +35 -0
  230. package/docs/ARCHITECTURE.md +164 -0
  231. package/docs/CONVENTIONS-archetypes.md +158 -0
  232. package/docs/CONVENTIONS-failures.md +46 -0
  233. package/docs/CONVENTIONS-game-designs.md +75 -0
  234. package/docs/CONVENTIONS-hardware-reference.md +184 -0
  235. package/docs/CONVENTIONS-pitfalls.md +91 -0
  236. package/docs/CONVENTIONS-recipes.md +106 -0
  237. package/docs/CONVENTIONS-techniques.md +309 -0
  238. package/docs/CONVENTIONS-toolchain-reference.md +89 -0
  239. package/docs/ONTOLOGY.md +655 -0
  240. package/docs/art/art-production-reference.md +157 -0
  241. package/docs/art/asset-pipelines.md +586 -0
  242. package/docs/c64-failure-patterns.md +693 -0
  243. package/docs/demo-design/demo-composition.md +349 -0
  244. package/docs/demo-design/demo-design-philosophy.md +320 -0
  245. package/docs/demo-design/intro-cracktro-patterns.md +435 -0
  246. package/docs/figures/ctm-spd-embed-probe.png +0 -0
  247. package/docs/figures/dot-flag-mid-5000000.png +0 -0
  248. package/docs/figures/dot-flag-no-erase-12000000.png +0 -0
  249. package/docs/figures/edges.json +1 -0
  250. package/docs/figures/fig6-architecture.png +0 -0
  251. package/docs/figures/fig7-ontology.png +0 -0
  252. package/docs/figures/screen-dissolve-mid-frame25.png +0 -0
  253. package/docs/figures/screen-dissolve-wipe-frame25.png +0 -0
  254. package/docs/figures/spindle-two-parts-part1.png +0 -0
  255. package/docs/figures/spindle-two-parts-part2.png +0 -0
  256. package/docs/figures/starters/action-puzzle.png +0 -0
  257. package/docs/figures/starters/adventure.png +0 -0
  258. package/docs/figures/starters/beat-em-up.png +0 -0
  259. package/docs/figures/starters/demo.png +0 -0
  260. package/docs/figures/starters/platformer.png +0 -0
  261. package/docs/figures/starters/shmup-vertical.png +0 -0
  262. package/docs/figures/tape-kernal-master-ntsc.png +0 -0
  263. package/docs/figures/tape-kernal-master-pal.png +0 -0
  264. package/docs/figures/tape-turbo-loader-ntsc.png +0 -0
  265. package/docs/figures/tape-turbo-loader-pal.png +0 -0
  266. package/docs/figures/tape-turbo-master-ntsc.png +0 -0
  267. package/docs/figures/tape-turbo-master-pal.png +0 -0
  268. package/docs/figures/tech-tech-pad2-12000000.png +0 -0
  269. package/docs/figures/tech-tech-pad4-12000000.png +0 -0
  270. package/docs/figures/tech-tech-seven-12000000.png +0 -0
  271. package/docs/figures/twister-mid-5000000.png +0 -0
  272. package/docs/figures/twister-straight-12000000.png +0 -0
  273. package/docs/figures/vector-balls-nosort-ntsc.png +0 -0
  274. package/docs/figures/vector-balls-nosort.png +0 -0
  275. package/docs/formats/c64-file-formats.md +1212 -0
  276. package/docs/formats/iec-disk-reference.md +754 -0
  277. package/docs/game-design/c64-game-archetypes.md +273 -0
  278. package/docs/game-design/designs/falling-blocks.md +54 -0
  279. package/docs/game-design/designs/platformer-scaffold.md +48 -0
  280. package/docs/game-design/designs/simple-shmup.md +27 -0
  281. package/docs/game-design/enemy-behaviour-and-difficulty.md +349 -0
  282. package/docs/game-design/game-design-patterns.md +1189 -0
  283. package/docs/game-design/game-structure.md +354 -0
  284. package/docs/game-design/production-planning.md +349 -0
  285. package/docs/game-design/reference-game-sources.md +90 -0
  286. package/docs/hardware/6502-illegal-opcodes.md +1353 -0
  287. package/docs/hardware/6510-cpu-reference.md +2112 -0
  288. package/docs/hardware/c64-memory-map.md +3184 -0
  289. package/docs/hardware/c64-registers-reference.md +996 -0
  290. package/docs/hardware/cia-reference.md +1281 -0
  291. package/docs/hardware/kernal-routines-reference.md +1836 -0
  292. package/docs/hardware/pal-ntsc-reference.md +813 -0
  293. package/docs/hardware/sid-reference.md +1137 -0
  294. package/docs/hardware/vic-ii-reference.md +1714 -0
  295. package/docs/music/music-production-reference.md +403 -0
  296. package/docs/pitfalls/banking.md +1067 -0
  297. package/docs/pitfalls/cia.md +1147 -0
  298. package/docs/pitfalls/cpu.md +874 -0
  299. package/docs/pitfalls/input.md +282 -0
  300. package/docs/pitfalls/kernal-and-io.md +1615 -0
  301. package/docs/pitfalls/loader.md +1191 -0
  302. package/docs/pitfalls/logic.md +94 -0
  303. package/docs/pitfalls/maths.md +187 -0
  304. package/docs/pitfalls/raster-and-badline.md +721 -0
  305. package/docs/pitfalls/region-timing.md +660 -0
  306. package/docs/pitfalls/scroll.md +207 -0
  307. package/docs/pitfalls/sid.md +738 -0
  308. package/docs/pitfalls/sprite.md +979 -0
  309. package/docs/pitfalls/text-mode-render.md +1172 -0
  310. package/docs/recipes/cc65/cartridge-8k.md +398 -0
  311. package/docs/recipes/cc65/hello-world-conio.md +76 -0
  312. package/docs/recipes/cc65/memory-layout.md +312 -0
  313. package/docs/recipes/cc65/screenshots/README.md +14 -0
  314. package/docs/recipes/cc65/screenshots/cartridge-8k-ntsc.png +0 -0
  315. package/docs/recipes/cc65/screenshots/cartridge-8k.png +0 -0
  316. package/docs/recipes/cc65/screenshots/hello-world-conio.png +0 -0
  317. package/docs/recipes/cc65/screenshots/memory-layout-ntsc.png +0 -0
  318. package/docs/recipes/cc65/screenshots/memory-layout.png +0 -0
  319. package/docs/recipes/kickassembler/basic-float-calls.md +578 -0
  320. package/docs/recipes/kickassembler/basic-wedge.md +398 -0
  321. package/docs/recipes/kickassembler/big-font-scroller.md +620 -0
  322. package/docs/recipes/kickassembler/charset-copy-rom-to-ram.md +623 -0
  323. package/docs/recipes/kickassembler/cia-revision-detect.md +366 -0
  324. package/docs/recipes/kickassembler/colour-cycling.md +343 -0
  325. package/docs/recipes/kickassembler/colour-fade.md +303 -0
  326. package/docs/recipes/kickassembler/compare-16bit-signed.md +1007 -0
  327. package/docs/recipes/kickassembler/cracktro-template.md +526 -0
  328. package/docs/recipes/kickassembler/crt-banked.md +276 -0
  329. package/docs/recipes/kickassembler/dos-error-codes.md +466 -0
  330. package/docs/recipes/kickassembler/dot-flag.md +576 -0
  331. package/docs/recipes/kickassembler/drive-job-queue.md +667 -0
  332. package/docs/recipes/kickassembler/drive-via-probe.md +690 -0
  333. package/docs/recipes/kickassembler/dycp-scroller.md +568 -0
  334. package/docs/recipes/kickassembler/dypp-sprite-scroller.md +681 -0
  335. package/docs/recipes/kickassembler/dysp.md +670 -0
  336. package/docs/recipes/kickassembler/easyflash-save.md +800 -0
  337. package/docs/recipes/kickassembler/eight-way-scroll.md +1484 -0
  338. package/docs/recipes/kickassembler/file-io-roundtrip.md +546 -0
  339. package/docs/recipes/kickassembler/fire-effect.md +420 -0
  340. package/docs/recipes/kickassembler/fld.md +414 -0
  341. package/docs/recipes/kickassembler/fli-image.md +336 -0
  342. package/docs/recipes/kickassembler/four-player-read.md +672 -0
  343. package/docs/recipes/kickassembler/headless-verify.md +228 -0
  344. package/docs/recipes/kickassembler/hello-world.md +98 -0
  345. package/docs/recipes/kickassembler/high-score-insert.md +660 -0
  346. package/docs/recipes/kickassembler/hires-plot-line.md +723 -0
  347. package/docs/recipes/kickassembler/irq-chain.md +316 -0
  348. package/docs/recipes/kickassembler/irq-owns-port.md +668 -0
  349. package/docs/recipes/kickassembler/isometric-room.md +1145 -0
  350. package/docs/recipes/kickassembler/light-pen-read.md +926 -0
  351. package/docs/recipes/kickassembler/logic-rate-decoupling.md +670 -0
  352. package/docs/recipes/kickassembler/mci-interlace.md +543 -0
  353. package/docs/recipes/kickassembler/memory-layout.md +277 -0
  354. package/docs/recipes/kickassembler/mouse-1351-read.md +801 -0
  355. package/docs/recipes/kickassembler/nmi-timer-tick.md +562 -0
  356. package/docs/recipes/kickassembler/own-keyscan.md +881 -0
  357. package/docs/recipes/kickassembler/paddle-read.md +751 -0
  358. package/docs/recipes/kickassembler/palette-cells.md +219 -0
  359. package/docs/recipes/kickassembler/pseudo-3d-road.md +930 -0
  360. package/docs/recipes/kickassembler/pwm-digi.md +463 -0
  361. package/docs/recipes/kickassembler/raster-bars.md +264 -0
  362. package/docs/recipes/kickassembler/reu-dma.md +1019 -0
  363. package/docs/recipes/kickassembler/runtime-relocation.md +743 -0
  364. package/docs/recipes/kickassembler/screen-dissolve.md +545 -0
  365. package/docs/recipes/kickassembler/screen-wipe.md +408 -0
  366. package/docs/recipes/kickassembler/screenshots/README.md +72 -0
  367. package/docs/recipes/kickassembler/screenshots/basic-float-calls-ntsc.png +0 -0
  368. package/docs/recipes/kickassembler/screenshots/basic-float-calls.png +0 -0
  369. package/docs/recipes/kickassembler/screenshots/basic-wedge-ntsc.png +0 -0
  370. package/docs/recipes/kickassembler/screenshots/basic-wedge.png +0 -0
  371. package/docs/recipes/kickassembler/screenshots/big-font-scroller-ntsc.png +0 -0
  372. package/docs/recipes/kickassembler/screenshots/big-font-scroller.png +0 -0
  373. package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram-ntsc.png +0 -0
  374. package/docs/recipes/kickassembler/screenshots/charset-copy-rom-to-ram.png +0 -0
  375. package/docs/recipes/kickassembler/screenshots/cia-revision-detect-ntsc.png +0 -0
  376. package/docs/recipes/kickassembler/screenshots/cia-revision-detect.png +0 -0
  377. package/docs/recipes/kickassembler/screenshots/colour-cycling-ntsc.png +0 -0
  378. package/docs/recipes/kickassembler/screenshots/colour-cycling.png +0 -0
  379. package/docs/recipes/kickassembler/screenshots/colour-fade-ntsc.png +0 -0
  380. package/docs/recipes/kickassembler/screenshots/colour-fade.png +0 -0
  381. package/docs/recipes/kickassembler/screenshots/compare-16bit-signed-ntsc.png +0 -0
  382. package/docs/recipes/kickassembler/screenshots/compare-16bit-signed.png +0 -0
  383. package/docs/recipes/kickassembler/screenshots/cracktro-template.png +0 -0
  384. package/docs/recipes/kickassembler/screenshots/crt-banked-ntsc.png +0 -0
  385. package/docs/recipes/kickassembler/screenshots/crt-banked.png +0 -0
  386. package/docs/recipes/kickassembler/screenshots/dos-error-codes-ntsc.png +0 -0
  387. package/docs/recipes/kickassembler/screenshots/dos-error-codes.png +0 -0
  388. package/docs/recipes/kickassembler/screenshots/dot-flag-ntsc.png +0 -0
  389. package/docs/recipes/kickassembler/screenshots/dot-flag.png +0 -0
  390. package/docs/recipes/kickassembler/screenshots/drive-job-queue-ntsc.png +0 -0
  391. package/docs/recipes/kickassembler/screenshots/drive-job-queue.png +0 -0
  392. package/docs/recipes/kickassembler/screenshots/drive-via-probe-ntsc.png +0 -0
  393. package/docs/recipes/kickassembler/screenshots/drive-via-probe.png +0 -0
  394. package/docs/recipes/kickassembler/screenshots/dycp-scroller-ntsc.png +0 -0
  395. package/docs/recipes/kickassembler/screenshots/dycp-scroller.png +0 -0
  396. package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller-ntsc.png +0 -0
  397. package/docs/recipes/kickassembler/screenshots/dypp-sprite-scroller.png +0 -0
  398. package/docs/recipes/kickassembler/screenshots/dysp-ntsc.png +0 -0
  399. package/docs/recipes/kickassembler/screenshots/dysp.png +0 -0
  400. package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc-run2.png +0 -0
  401. package/docs/recipes/kickassembler/screenshots/easyflash-save-ntsc.png +0 -0
  402. package/docs/recipes/kickassembler/screenshots/easyflash-save-run2.png +0 -0
  403. package/docs/recipes/kickassembler/screenshots/easyflash-save.png +0 -0
  404. package/docs/recipes/kickassembler/screenshots/eight-way-scroll-ntsc.png +0 -0
  405. package/docs/recipes/kickassembler/screenshots/eight-way-scroll.png +0 -0
  406. package/docs/recipes/kickassembler/screenshots/file-io-roundtrip-ntsc.png +0 -0
  407. package/docs/recipes/kickassembler/screenshots/file-io-roundtrip.png +0 -0
  408. package/docs/recipes/kickassembler/screenshots/fire-effect-ntsc.png +0 -0
  409. package/docs/recipes/kickassembler/screenshots/fire-effect.png +0 -0
  410. package/docs/recipes/kickassembler/screenshots/fld-ntsc.png +0 -0
  411. package/docs/recipes/kickassembler/screenshots/fld.png +0 -0
  412. package/docs/recipes/kickassembler/screenshots/fli-image.png +0 -0
  413. package/docs/recipes/kickassembler/screenshots/four-player-read-ntsc.png +0 -0
  414. package/docs/recipes/kickassembler/screenshots/four-player-read.png +0 -0
  415. package/docs/recipes/kickassembler/screenshots/headless-verify-ntsc.png +0 -0
  416. package/docs/recipes/kickassembler/screenshots/headless-verify.png +0 -0
  417. package/docs/recipes/kickassembler/screenshots/hello-world.png +0 -0
  418. package/docs/recipes/kickassembler/screenshots/high-score-insert-ntsc.png +0 -0
  419. package/docs/recipes/kickassembler/screenshots/high-score-insert.png +0 -0
  420. package/docs/recipes/kickassembler/screenshots/hires-plot-line-ntsc.png +0 -0
  421. package/docs/recipes/kickassembler/screenshots/hires-plot-line.png +0 -0
  422. package/docs/recipes/kickassembler/screenshots/irq-chain-ntsc.png +0 -0
  423. package/docs/recipes/kickassembler/screenshots/irq-chain.png +0 -0
  424. package/docs/recipes/kickassembler/screenshots/irq-owns-port-ntsc.png +0 -0
  425. package/docs/recipes/kickassembler/screenshots/irq-owns-port.png +0 -0
  426. package/docs/recipes/kickassembler/screenshots/isometric-room-ntsc.png +0 -0
  427. package/docs/recipes/kickassembler/screenshots/isometric-room.png +0 -0
  428. package/docs/recipes/kickassembler/screenshots/light-pen-read-ntsc.png +0 -0
  429. package/docs/recipes/kickassembler/screenshots/light-pen-read.png +0 -0
  430. package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling-ntsc.png +0 -0
  431. package/docs/recipes/kickassembler/screenshots/logic-rate-decoupling.png +0 -0
  432. package/docs/recipes/kickassembler/screenshots/mci-interlace-average.png +0 -0
  433. package/docs/recipes/kickassembler/screenshots/mci-interlace-frame-b.png +0 -0
  434. package/docs/recipes/kickassembler/screenshots/mci-interlace-ntsc.png +0 -0
  435. package/docs/recipes/kickassembler/screenshots/mci-interlace.png +0 -0
  436. package/docs/recipes/kickassembler/screenshots/memory-layout-ntsc.png +0 -0
  437. package/docs/recipes/kickassembler/screenshots/memory-layout.png +0 -0
  438. package/docs/recipes/kickassembler/screenshots/mouse-1351-read-ntsc.png +0 -0
  439. package/docs/recipes/kickassembler/screenshots/mouse-1351-read.png +0 -0
  440. package/docs/recipes/kickassembler/screenshots/nmi-timer-tick-ntsc.png +0 -0
  441. package/docs/recipes/kickassembler/screenshots/nmi-timer-tick.png +0 -0
  442. package/docs/recipes/kickassembler/screenshots/own-keyscan-ntsc.png +0 -0
  443. package/docs/recipes/kickassembler/screenshots/own-keyscan.png +0 -0
  444. package/docs/recipes/kickassembler/screenshots/paddle-read-ntsc.png +0 -0
  445. package/docs/recipes/kickassembler/screenshots/paddle-read.png +0 -0
  446. package/docs/recipes/kickassembler/screenshots/palette-cells-ntsc.png +0 -0
  447. package/docs/recipes/kickassembler/screenshots/palette-cells.png +0 -0
  448. package/docs/recipes/kickassembler/screenshots/pseudo-3d-road-ntsc.png +0 -0
  449. package/docs/recipes/kickassembler/screenshots/pseudo-3d-road.png +0 -0
  450. package/docs/recipes/kickassembler/screenshots/pwm-digi-ntsc.png +0 -0
  451. package/docs/recipes/kickassembler/screenshots/pwm-digi.png +0 -0
  452. package/docs/recipes/kickassembler/screenshots/raster-bars.png +0 -0
  453. package/docs/recipes/kickassembler/screenshots/reu-dma-ntsc.png +0 -0
  454. package/docs/recipes/kickassembler/screenshots/reu-dma.png +0 -0
  455. package/docs/recipes/kickassembler/screenshots/runtime-relocation-ntsc.png +0 -0
  456. package/docs/recipes/kickassembler/screenshots/runtime-relocation.png +0 -0
  457. package/docs/recipes/kickassembler/screenshots/screen-dissolve-ntsc.png +0 -0
  458. package/docs/recipes/kickassembler/screenshots/screen-dissolve.png +0 -0
  459. package/docs/recipes/kickassembler/screenshots/screen-wipe-ntsc.png +0 -0
  460. package/docs/recipes/kickassembler/screenshots/screen-wipe.png +0 -0
  461. package/docs/recipes/kickassembler/screenshots/scroll-panel-split-ntsc.png +0 -0
  462. package/docs/recipes/kickassembler/screenshots/scroll-panel-split.png +0 -0
  463. package/docs/recipes/kickassembler/screenshots/sfx-in-player-ntsc.png +0 -0
  464. package/docs/recipes/kickassembler/screenshots/sfx-in-player.png +0 -0
  465. package/docs/recipes/kickassembler/screenshots/shadebobs-ntsc.png +0 -0
  466. package/docs/recipes/kickassembler/screenshots/shadebobs.png +0 -0
  467. package/docs/recipes/kickassembler/screenshots/sideborder-open.png +0 -0
  468. package/docs/recipes/kickassembler/screenshots/sine-scroller.png +0 -0
  469. package/docs/recipes/kickassembler/screenshots/sine-table-runtime-ntsc.png +0 -0
  470. package/docs/recipes/kickassembler/screenshots/sine-table-runtime.png +0 -0
  471. package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted-ntsc.png +0 -0
  472. package/docs/recipes/kickassembler/screenshots/software-sprite-preshifted.png +0 -0
  473. package/docs/recipes/kickassembler/screenshots/speedcode-generator-ntsc.png +0 -0
  474. package/docs/recipes/kickassembler/screenshots/speedcode-generator.png +0 -0
  475. package/docs/recipes/kickassembler/screenshots/sprite-border-scroller-ntsc.png +0 -0
  476. package/docs/recipes/kickassembler/screenshots/sprite-border-scroller.png +0 -0
  477. package/docs/recipes/kickassembler/screenshots/sprite-cache-flip-ntsc.png +0 -0
  478. package/docs/recipes/kickassembler/screenshots/sprite-cache-flip.png +0 -0
  479. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-24.png +0 -0
  480. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game-ntsc.png +0 -0
  481. package/docs/recipes/kickassembler/screenshots/sprite-multiplex-game.png +0 -0
  482. package/docs/recipes/kickassembler/screenshots/sprite-priority-classes-ntsc.png +0 -0
  483. package/docs/recipes/kickassembler/screenshots/sprite-priority-classes.png +0 -0
  484. package/docs/recipes/kickassembler/screenshots/sprite-sine-chain-ntsc.png +0 -0
  485. package/docs/recipes/kickassembler/screenshots/sprite-sine-chain.png +0 -0
  486. package/docs/recipes/kickassembler/screenshots/sprite-stretcher-ntsc.png +0 -0
  487. package/docs/recipes/kickassembler/screenshots/sprite-stretcher.png +0 -0
  488. package/docs/recipes/kickassembler/screenshots/sprites-only-screen-ntsc.png +0 -0
  489. package/docs/recipes/kickassembler/screenshots/sprites-only-screen.png +0 -0
  490. package/docs/recipes/kickassembler/screenshots/sqrt-atan2-ntsc.png +0 -0
  491. package/docs/recipes/kickassembler/screenshots/sqrt-atan2.png +0 -0
  492. package/docs/recipes/kickassembler/screenshots/stable-raster-irq-control.png +0 -0
  493. package/docs/recipes/kickassembler/screenshots/stable-raster-irq.png +0 -0
  494. package/docs/recipes/kickassembler/screenshots/tech-tech-ntsc.png +0 -0
  495. package/docs/recipes/kickassembler/screenshots/tech-tech.png +0 -0
  496. package/docs/recipes/kickassembler/screenshots/tod-alarm-ntsc.png +0 -0
  497. package/docs/recipes/kickassembler/screenshots/tod-alarm.png +0 -0
  498. package/docs/recipes/kickassembler/screenshots/topbottom-border-open.png +0 -0
  499. package/docs/recipes/kickassembler/screenshots/twister-ntsc.png +0 -0
  500. package/docs/recipes/kickassembler/screenshots/twister.png +0 -0
  501. package/docs/recipes/kickassembler/screenshots/unit-test-driver-ntsc.png +0 -0
  502. package/docs/recipes/kickassembler/screenshots/unit-test-driver.png +0 -0
  503. package/docs/recipes/kickassembler/screenshots/vector-balls-ntsc.png +0 -0
  504. package/docs/recipes/kickassembler/screenshots/vector-balls.png +0 -0
  505. package/docs/recipes/kickassembler/screenshots/wireframe-ships-ntsc.png +0 -0
  506. package/docs/recipes/kickassembler/screenshots/wireframe-ships.png +0 -0
  507. package/docs/recipes/kickassembler/scroll-panel-split.md +381 -0
  508. package/docs/recipes/kickassembler/sfx-in-player.md +907 -0
  509. package/docs/recipes/kickassembler/shadebobs.md +522 -0
  510. package/docs/recipes/kickassembler/sideborder-open.md +338 -0
  511. package/docs/recipes/kickassembler/sine-scroller.md +321 -0
  512. package/docs/recipes/kickassembler/sine-table-runtime.md +815 -0
  513. package/docs/recipes/kickassembler/software-sprite-preshifted.md +725 -0
  514. package/docs/recipes/kickassembler/speedcode-generator.md +606 -0
  515. package/docs/recipes/kickassembler/sprite-border-scroller.md +696 -0
  516. package/docs/recipes/kickassembler/sprite-cache-flip.md +1071 -0
  517. package/docs/recipes/kickassembler/sprite-multiplex-24.md +326 -0
  518. package/docs/recipes/kickassembler/sprite-multiplex-game.md +986 -0
  519. package/docs/recipes/kickassembler/sprite-priority-classes.md +463 -0
  520. package/docs/recipes/kickassembler/sprite-sine-chain.md +338 -0
  521. package/docs/recipes/kickassembler/sprite-stretcher.md +501 -0
  522. package/docs/recipes/kickassembler/sprites-only-screen.md +550 -0
  523. package/docs/recipes/kickassembler/sqrt-atan2.md +1014 -0
  524. package/docs/recipes/kickassembler/stable-raster-irq.md +360 -0
  525. package/docs/recipes/kickassembler/tape-turbo-loader.md +875 -0
  526. package/docs/recipes/kickassembler/tech-tech.md +679 -0
  527. package/docs/recipes/kickassembler/tod-alarm.md +754 -0
  528. package/docs/recipes/kickassembler/topbottom-border-open.md +407 -0
  529. package/docs/recipes/kickassembler/twister.md +518 -0
  530. package/docs/recipes/kickassembler/unit-test-driver.md +314 -0
  531. package/docs/recipes/kickassembler/vector-balls.md +545 -0
  532. package/docs/recipes/kickassembler/wireframe-ships.md +2324 -0
  533. package/docs/recipes/oscar64/actor-activation-window.md +807 -0
  534. package/docs/recipes/oscar64/adventure-engine.md +1094 -0
  535. package/docs/recipes/oscar64/attract-replay.md +465 -0
  536. package/docs/recipes/oscar64/beat-em-up-lanes.md +563 -0
  537. package/docs/recipes/oscar64/bfs-distance-map.md +723 -0
  538. package/docs/recipes/oscar64/bitmap-koala-viewer.md +355 -0
  539. package/docs/recipes/oscar64/car-contact.md +950 -0
  540. package/docs/recipes/oscar64/cave-scan.md +609 -0
  541. package/docs/recipes/oscar64/char-bullets.md +477 -0
  542. package/docs/recipes/oscar64/charset-animation.md +383 -0
  543. package/docs/recipes/oscar64/charset-parallax.md +401 -0
  544. package/docs/recipes/oscar64/destructible-terrain.md +1099 -0
  545. package/docs/recipes/oscar64/difficulty-tables.md +654 -0
  546. package/docs/recipes/oscar64/dig-and-guards.md +975 -0
  547. package/docs/recipes/oscar64/directory-reader.md +535 -0
  548. package/docs/recipes/oscar64/divide-check.md +581 -0
  549. package/docs/recipes/oscar64/double-buffer-nomirror.md +205 -0
  550. package/docs/recipes/oscar64/double-buffer.md +255 -0
  551. package/docs/recipes/oscar64/falling-blocks.md +874 -0
  552. package/docs/recipes/oscar64/fixed-point-jump-velocity.md +289 -0
  553. package/docs/recipes/oscar64/fixed-point-jump.md +210 -0
  554. package/docs/recipes/oscar64/flip-screen-rooms.md +793 -0
  555. package/docs/recipes/oscar64/frame-sync-loop-overrun.md +214 -0
  556. package/docs/recipes/oscar64/frame-sync-loop.md +254 -0
  557. package/docs/recipes/oscar64/game-tree-search.md +743 -0
  558. package/docs/recipes/oscar64/ghost-targeting.md +867 -0
  559. package/docs/recipes/oscar64/headless-verify.md +345 -0
  560. package/docs/recipes/oscar64/hello-world.md +83 -0
  561. package/docs/recipes/oscar64/high-score-persist.md +772 -0
  562. package/docs/recipes/oscar64/iffl-kernal-skip.md +421 -0
  563. package/docs/recipes/oscar64/joystick-input.md +358 -0
  564. package/docs/recipes/oscar64/lane-pursuit.md +1028 -0
  565. package/docs/recipes/oscar64/level-rle-decoder.md +620 -0
  566. package/docs/recipes/oscar64/lfsr-random-seed2.md +338 -0
  567. package/docs/recipes/oscar64/lfsr-random.md +403 -0
  568. package/docs/recipes/oscar64/load-asset-runtime.md +492 -0
  569. package/docs/recipes/oscar64/memory-layout.md +232 -0
  570. package/docs/recipes/oscar64/mixed-fighters.md +781 -0
  571. package/docs/recipes/oscar64/multi-sprite-object.md +533 -0
  572. package/docs/recipes/oscar64/nav-area-pathfinding.md +881 -0
  573. package/docs/recipes/oscar64/object-pool.md +572 -0
  574. package/docs/recipes/oscar64/pal-ntsc-detect.md +257 -0
  575. package/docs/recipes/oscar64/password-state.md +532 -0
  576. package/docs/recipes/oscar64/per-frame-hitbox.md +651 -0
  577. package/docs/recipes/oscar64/petscii-screen-codes.md +428 -0
  578. package/docs/recipes/oscar64/platformer-scaffold.md +1467 -0
  579. package/docs/recipes/oscar64/print-number.md +367 -0
  580. package/docs/recipes/oscar64/raster-bars.md +239 -0
  581. package/docs/recipes/oscar64/raster-profile-bars.md +404 -0
  582. package/docs/recipes/oscar64/rel-side-sectors.md +391 -0
  583. package/docs/recipes/oscar64/relative-file-records.md +378 -0
  584. package/docs/recipes/oscar64/save-load-seq-file.md +365 -0
  585. package/docs/recipes/oscar64/screenshots/README.md +99 -0
  586. package/docs/recipes/oscar64/screenshots/actor-activation-window-ntsc.png +0 -0
  587. package/docs/recipes/oscar64/screenshots/actor-activation-window.png +0 -0
  588. package/docs/recipes/oscar64/screenshots/adventure-engine-ntsc.png +0 -0
  589. package/docs/recipes/oscar64/screenshots/adventure-engine.png +0 -0
  590. package/docs/recipes/oscar64/screenshots/attract-replay-ntsc.png +0 -0
  591. package/docs/recipes/oscar64/screenshots/attract-replay.png +0 -0
  592. package/docs/recipes/oscar64/screenshots/beat-em-up-lanes-ntsc.png +0 -0
  593. package/docs/recipes/oscar64/screenshots/beat-em-up-lanes.png +0 -0
  594. package/docs/recipes/oscar64/screenshots/bfs-distance-map-ntsc.png +0 -0
  595. package/docs/recipes/oscar64/screenshots/bfs-distance-map.png +0 -0
  596. package/docs/recipes/oscar64/screenshots/bitmap-koala-viewer.png +0 -0
  597. package/docs/recipes/oscar64/screenshots/car-contact-ntsc.png +0 -0
  598. package/docs/recipes/oscar64/screenshots/car-contact.png +0 -0
  599. package/docs/recipes/oscar64/screenshots/cave-scan-ntsc.png +0 -0
  600. package/docs/recipes/oscar64/screenshots/cave-scan.png +0 -0
  601. package/docs/recipes/oscar64/screenshots/char-bullets-ntsc.png +0 -0
  602. package/docs/recipes/oscar64/screenshots/char-bullets.png +0 -0
  603. package/docs/recipes/oscar64/screenshots/charset-animation-ntsc.png +0 -0
  604. package/docs/recipes/oscar64/screenshots/charset-animation.png +0 -0
  605. package/docs/recipes/oscar64/screenshots/charset-parallax-ntsc.png +0 -0
  606. package/docs/recipes/oscar64/screenshots/charset-parallax.png +0 -0
  607. package/docs/recipes/oscar64/screenshots/destructible-terrain-ntsc.png +0 -0
  608. package/docs/recipes/oscar64/screenshots/destructible-terrain.png +0 -0
  609. package/docs/recipes/oscar64/screenshots/difficulty-tables-ntsc.png +0 -0
  610. package/docs/recipes/oscar64/screenshots/difficulty-tables.png +0 -0
  611. package/docs/recipes/oscar64/screenshots/dig-and-guards-ntsc.png +0 -0
  612. package/docs/recipes/oscar64/screenshots/dig-and-guards.png +0 -0
  613. package/docs/recipes/oscar64/screenshots/directory-reader-ntsc.png +0 -0
  614. package/docs/recipes/oscar64/screenshots/directory-reader.png +0 -0
  615. package/docs/recipes/oscar64/screenshots/divide-check-ntsc.png +0 -0
  616. package/docs/recipes/oscar64/screenshots/divide-check.png +0 -0
  617. package/docs/recipes/oscar64/screenshots/double-buffer-nomirror.png +0 -0
  618. package/docs/recipes/oscar64/screenshots/double-buffer-ntsc.png +0 -0
  619. package/docs/recipes/oscar64/screenshots/double-buffer.png +0 -0
  620. package/docs/recipes/oscar64/screenshots/falling-blocks-ntsc.png +0 -0
  621. package/docs/recipes/oscar64/screenshots/falling-blocks.png +0 -0
  622. package/docs/recipes/oscar64/screenshots/fixed-point-jump-ntsc.png +0 -0
  623. package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity-ntsc.png +0 -0
  624. package/docs/recipes/oscar64/screenshots/fixed-point-jump-velocity.png +0 -0
  625. package/docs/recipes/oscar64/screenshots/fixed-point-jump.png +0 -0
  626. package/docs/recipes/oscar64/screenshots/flip-screen-rooms-ntsc.png +0 -0
  627. package/docs/recipes/oscar64/screenshots/flip-screen-rooms.png +0 -0
  628. package/docs/recipes/oscar64/screenshots/frame-sync-loop-ntsc.png +0 -0
  629. package/docs/recipes/oscar64/screenshots/frame-sync-loop-overrun.png +0 -0
  630. package/docs/recipes/oscar64/screenshots/frame-sync-loop.png +0 -0
  631. package/docs/recipes/oscar64/screenshots/game-tree-search-ntsc.png +0 -0
  632. package/docs/recipes/oscar64/screenshots/game-tree-search.png +0 -0
  633. package/docs/recipes/oscar64/screenshots/ghost-targeting-ntsc.png +0 -0
  634. package/docs/recipes/oscar64/screenshots/ghost-targeting.png +0 -0
  635. package/docs/recipes/oscar64/screenshots/headless-verify-ntsc.png +0 -0
  636. package/docs/recipes/oscar64/screenshots/headless-verify.png +0 -0
  637. package/docs/recipes/oscar64/screenshots/hello-world.png +0 -0
  638. package/docs/recipes/oscar64/screenshots/high-score-persist-ntsc.png +0 -0
  639. package/docs/recipes/oscar64/screenshots/high-score-persist.png +0 -0
  640. package/docs/recipes/oscar64/screenshots/iffl-kernal-skip-ntsc.png +0 -0
  641. package/docs/recipes/oscar64/screenshots/iffl-kernal-skip.png +0 -0
  642. package/docs/recipes/oscar64/screenshots/joystick-input-ntsc.png +0 -0
  643. package/docs/recipes/oscar64/screenshots/joystick-input.png +0 -0
  644. package/docs/recipes/oscar64/screenshots/lane-pursuit-ntsc.png +0 -0
  645. package/docs/recipes/oscar64/screenshots/lane-pursuit.png +0 -0
  646. package/docs/recipes/oscar64/screenshots/level-rle-decoder-ntsc.png +0 -0
  647. package/docs/recipes/oscar64/screenshots/level-rle-decoder.png +0 -0
  648. package/docs/recipes/oscar64/screenshots/lfsr-random-ntsc.png +0 -0
  649. package/docs/recipes/oscar64/screenshots/lfsr-random-seed2.png +0 -0
  650. package/docs/recipes/oscar64/screenshots/lfsr-random.png +0 -0
  651. package/docs/recipes/oscar64/screenshots/load-asset-runtime-ntsc.png +0 -0
  652. package/docs/recipes/oscar64/screenshots/load-asset-runtime.png +0 -0
  653. package/docs/recipes/oscar64/screenshots/memory-layout-ntsc.png +0 -0
  654. package/docs/recipes/oscar64/screenshots/memory-layout.png +0 -0
  655. package/docs/recipes/oscar64/screenshots/mixed-fighters-ntsc.png +0 -0
  656. package/docs/recipes/oscar64/screenshots/mixed-fighters.png +0 -0
  657. package/docs/recipes/oscar64/screenshots/multi-sprite-object-ntsc.png +0 -0
  658. package/docs/recipes/oscar64/screenshots/multi-sprite-object.png +0 -0
  659. package/docs/recipes/oscar64/screenshots/nav-area-pathfinding-ntsc.png +0 -0
  660. package/docs/recipes/oscar64/screenshots/nav-area-pathfinding.png +0 -0
  661. package/docs/recipes/oscar64/screenshots/object-pool-ntsc.png +0 -0
  662. package/docs/recipes/oscar64/screenshots/object-pool.png +0 -0
  663. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-ntsc.png +0 -0
  664. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-oldntsc.png +0 -0
  665. package/docs/recipes/oscar64/screenshots/pal-ntsc-detect-pal.png +0 -0
  666. package/docs/recipes/oscar64/screenshots/password-state-ntsc.png +0 -0
  667. package/docs/recipes/oscar64/screenshots/password-state.png +0 -0
  668. package/docs/recipes/oscar64/screenshots/per-frame-hitbox-ntsc.png +0 -0
  669. package/docs/recipes/oscar64/screenshots/per-frame-hitbox.png +0 -0
  670. package/docs/recipes/oscar64/screenshots/petscii-screen-codes-ntsc.png +0 -0
  671. package/docs/recipes/oscar64/screenshots/petscii-screen-codes.png +0 -0
  672. package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64-ntsc.png +0 -0
  673. package/docs/recipes/oscar64/screenshots/platformer-scaffold-d64.png +0 -0
  674. package/docs/recipes/oscar64/screenshots/platformer-scaffold-ntsc.png +0 -0
  675. package/docs/recipes/oscar64/screenshots/platformer-scaffold.png +0 -0
  676. package/docs/recipes/oscar64/screenshots/print-number-ntsc.png +0 -0
  677. package/docs/recipes/oscar64/screenshots/print-number.png +0 -0
  678. package/docs/recipes/oscar64/screenshots/raster-bars.png +0 -0
  679. package/docs/recipes/oscar64/screenshots/raster-profile-bars-ntsc.png +0 -0
  680. package/docs/recipes/oscar64/screenshots/raster-profile-bars.png +0 -0
  681. package/docs/recipes/oscar64/screenshots/rel-side-sectors-ntsc.png +0 -0
  682. package/docs/recipes/oscar64/screenshots/rel-side-sectors.png +0 -0
  683. package/docs/recipes/oscar64/screenshots/relative-file-records-ntsc.png +0 -0
  684. package/docs/recipes/oscar64/screenshots/relative-file-records.png +0 -0
  685. package/docs/recipes/oscar64/screenshots/save-load-seq-file-ntsc.png +0 -0
  686. package/docs/recipes/oscar64/screenshots/save-load-seq-file.png +0 -0
  687. package/docs/recipes/oscar64/screenshots/seeded-level-fill-ntsc.png +0 -0
  688. package/docs/recipes/oscar64/screenshots/seeded-level-fill.png +0 -0
  689. package/docs/recipes/oscar64/screenshots/sfx-engine-ntsc.png +0 -0
  690. package/docs/recipes/oscar64/screenshots/sfx-engine.png +0 -0
  691. package/docs/recipes/oscar64/screenshots/sid-music-player.png +0 -0
  692. package/docs/recipes/oscar64/screenshots/simple-shmup.png +0 -0
  693. package/docs/recipes/oscar64/screenshots/slope-collision-ntsc.png +0 -0
  694. package/docs/recipes/oscar64/screenshots/slope-collision.png +0 -0
  695. package/docs/recipes/oscar64/screenshots/soft-scroll-h.png +0 -0
  696. package/docs/recipes/oscar64/screenshots/sprite-animation-table-ntsc.png +0 -0
  697. package/docs/recipes/oscar64/screenshots/sprite-animation-table.png +0 -0
  698. package/docs/recipes/oscar64/screenshots/sprite-multiplex-8.png +0 -0
  699. package/docs/recipes/oscar64/screenshots/stable-raster-irq.png +0 -0
  700. package/docs/recipes/oscar64/screenshots/text-input-ntsc.png +0 -0
  701. package/docs/recipes/oscar64/screenshots/text-input.png +0 -0
  702. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-gameover.png +0 -0
  703. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-notrail-control.png +0 -0
  704. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ntsc.png +0 -0
  705. package/docs/recipes/oscar64/screenshots/text-overlay-playfield-ungated-control.png +0 -0
  706. package/docs/recipes/oscar64/screenshots/text-overlay-playfield.png +0 -0
  707. package/docs/recipes/oscar64/screenshots/text-window-menu-ntsc.png +0 -0
  708. package/docs/recipes/oscar64/screenshots/text-window-menu.png +0 -0
  709. package/docs/recipes/oscar64/screenshots/tile-grid-collision-ntsc.png +0 -0
  710. package/docs/recipes/oscar64/screenshots/tile-grid-collision.png +0 -0
  711. package/docs/recipes/oscar64/screenshots/tile-map-render-ntsc.png +0 -0
  712. package/docs/recipes/oscar64/screenshots/tile-map-render.png +0 -0
  713. package/docs/recipes/oscar64/screenshots/two-player-ntsc.png +0 -0
  714. package/docs/recipes/oscar64/screenshots/two-player.png +0 -0
  715. package/docs/recipes/oscar64/screenshots/two-word-parser-ntsc.png +0 -0
  716. package/docs/recipes/oscar64/screenshots/two-word-parser.png +0 -0
  717. package/docs/recipes/oscar64/screenshots/vehicle-control-ntsc.png +0 -0
  718. package/docs/recipes/oscar64/screenshots/vehicle-control.png +0 -0
  719. package/docs/recipes/oscar64/screenshots/wave-director-ntsc.png +0 -0
  720. package/docs/recipes/oscar64/screenshots/wave-director.png +0 -0
  721. package/docs/recipes/oscar64/seeded-level-fill.md +364 -0
  722. package/docs/recipes/oscar64/sfx-engine.md +514 -0
  723. package/docs/recipes/oscar64/sid-music-player.md +441 -0
  724. package/docs/recipes/oscar64/simple-shmup.md +1000 -0
  725. package/docs/recipes/oscar64/slope-collision.md +610 -0
  726. package/docs/recipes/oscar64/soft-scroll-h.md +261 -0
  727. package/docs/recipes/oscar64/sprite-animation-table.md +671 -0
  728. package/docs/recipes/oscar64/sprite-multiplex-8.md +314 -0
  729. package/docs/recipes/oscar64/stable-raster-irq.md +236 -0
  730. package/docs/recipes/oscar64/text-input.md +274 -0
  731. package/docs/recipes/oscar64/text-overlay-playfield.md +617 -0
  732. package/docs/recipes/oscar64/text-window-menu.md +551 -0
  733. package/docs/recipes/oscar64/tile-grid-collision.md +563 -0
  734. package/docs/recipes/oscar64/tile-map-render.md +395 -0
  735. package/docs/recipes/oscar64/two-player.md +528 -0
  736. package/docs/recipes/oscar64/two-word-parser.md +510 -0
  737. package/docs/recipes/oscar64/vehicle-control.md +771 -0
  738. package/docs/recipes/oscar64/wave-director.md +787 -0
  739. package/docs/recipes/runs.json +1606 -0
  740. package/docs/runtime/sim6502-reference.md +466 -0
  741. package/docs/runtime/vice-mcp-reference.md +351 -0
  742. package/docs/runtime/vice-reference.md +1393 -0
  743. package/docs/techniques/bitmap-modes.md +685 -0
  744. package/docs/techniques/cpu-cycle-tricks.md +1570 -0
  745. package/docs/techniques/effects-vector-3d.md +1431 -0
  746. package/docs/techniques/file-io.md +1427 -0
  747. package/docs/techniques/input.md +1072 -0
  748. package/docs/techniques/loaders-packers.md +768 -0
  749. package/docs/techniques/logic.md +3091 -0
  750. package/docs/techniques/maths.md +1524 -0
  751. package/docs/techniques/memory-banking.md +1686 -0
  752. package/docs/techniques/music-sid.md +1144 -0
  753. package/docs/techniques/raster.md +1543 -0
  754. package/docs/techniques/scroll.md +1292 -0
  755. package/docs/techniques/sprite.md +2566 -0
  756. package/docs/techniques/text-mode-render.md +717 -0
  757. package/docs/techniques/text.md +1095 -0
  758. package/docs/techniques/transitions.md +405 -0
  759. package/docs/toolchains/cartconv-reference.md +262 -0
  760. package/docs/toolchains/cc1541-reference.md +316 -0
  761. package/docs/toolchains/cc65-reference.md +667 -0
  762. package/docs/toolchains/error-sources/cc65/README.md +1 -0
  763. package/docs/toolchains/error-sources/cc65/missing-setcpu.s +4 -0
  764. package/docs/toolchains/error-sources/cc65/range-error.s +4 -0
  765. package/docs/toolchains/error-sources/cc65/segment-overflow.c +6 -0
  766. package/docs/toolchains/error-sources/cc65/unresolved-external.c +6 -0
  767. package/docs/toolchains/error-sources/kickassembler/README.md +1 -0
  768. package/docs/toolchains/error-sources/kickassembler/branch-out-of-range.asm +4 -0
  769. package/docs/toolchains/error-sources/kickassembler/failed-assert.asm +3 -0
  770. package/docs/toolchains/error-sources/kickassembler/flat-lib.asm +4 -0
  771. package/docs/toolchains/error-sources/kickassembler/import-source-no-namespace.asm +5 -0
  772. package/docs/toolchains/error-sources/kickassembler/macro-without-parentheses.asm +6 -0
  773. package/docs/toolchains/error-sources/kickassembler/memory-block-overlap.asm +4 -0
  774. package/docs/toolchains/error-sources/kickassembler/symbol-clash-lib.asm +5 -0
  775. package/docs/toolchains/error-sources/kickassembler/symbol-clash-main.asm +6 -0
  776. package/docs/toolchains/error-sources/kickassembler/unknown-symbol.asm +4 -0
  777. package/docs/toolchains/error-sources/oscar64/README.md +1 -0
  778. package/docs/toolchains/error-sources/oscar64/asm-addressing-mode.c +7 -0
  779. package/docs/toolchains/error-sources/oscar64/region-overflow.c +6 -0
  780. package/docs/toolchains/error-sources/oscar64/undefined-extern-var.c +5 -0
  781. package/docs/toolchains/error-sources/oscar64/undefined-extern.c +6 -0
  782. package/docs/toolchains/error-sources/oscar64/unknown-vic-field.c +6 -0
  783. package/docs/toolchains/error-sources/oscar64/void-main.c +3 -0
  784. package/docs/toolchains/kickassembler-reference.md +1020 -0
  785. package/docs/toolchains/memory-layout-planning.md +362 -0
  786. package/docs/toolchains/oscar64-headers-reference.md +583 -0
  787. package/docs/toolchains/oscar64-reference.md +892 -0
  788. package/docs/toolchains/petcat-reference.md +290 -0
  789. package/docs/toolchains/png2prg.md +188 -0
  790. package/docs/toolchains/release-disk.md +314 -0
  791. package/docs/toolchains/sidreloc.md +236 -0
  792. package/docs/toolchains/spindle-reference.md +487 -0
  793. package/docs/toolchains/tape-mastering.md +592 -0
  794. package/docs/toolchains/unit-testing-6502.md +281 -0
  795. package/docs/workflow/agent-harness.md +478 -0
  796. package/package.json +105 -0
  797. package/templates/_harness/CLAUDE.md.template +91 -0
  798. package/templates/_harness/PLAN.md.template +72 -0
  799. package/templates/_harness/check.py +442 -0
  800. package/templates/_harness/claude/settings.json +17 -0
  801. package/templates/_harness/gen-asm-header.py +96 -0
  802. package/templates/_harness/harness.mk +273 -0
  803. package/templates/_harness/hooks/plan-gate.py +185 -0
  804. package/templates/_harness/meter/frame_meter.asm +311 -0
  805. package/templates/_harness/meter/frame_meter.c +155 -0
  806. package/templates/_harness/meter/frame_meter.h +80 -0
  807. package/templates/_harness/zp-used.py +104 -0
  808. package/templates/action-puzzle/.claude/settings.json +17 -0
  809. package/templates/action-puzzle/.mcp.json +10 -0
  810. package/templates/action-puzzle/CLAUDE.md +120 -0
  811. package/templates/action-puzzle/Makefile +125 -0
  812. package/templates/action-puzzle/PLAN.md +388 -0
  813. package/templates/action-puzzle/README.md +240 -0
  814. package/templates/action-puzzle/expect.json +25 -0
  815. package/templates/action-puzzle/src/cave.c +280 -0
  816. package/templates/action-puzzle/src/cave.h +80 -0
  817. package/templates/action-puzzle/src/gen_autopilot.h +20 -0
  818. package/templates/action-puzzle/src/gen_caves.h +59 -0
  819. package/templates/action-puzzle/src/gen_notes.h +16 -0
  820. package/templates/action-puzzle/src/hiscore.c +152 -0
  821. package/templates/action-puzzle/src/hiscore.h +41 -0
  822. package/templates/action-puzzle/src/level.c +64 -0
  823. package/templates/action-puzzle/src/level.h +24 -0
  824. package/templates/action-puzzle/src/main.c +599 -0
  825. package/templates/action-puzzle/src/render.c +239 -0
  826. package/templates/action-puzzle/src/render.h +31 -0
  827. package/templates/action-puzzle/src/sound.c +158 -0
  828. package/templates/action-puzzle/src/sound.h +22 -0
  829. package/templates/action-puzzle/tools/disk_check.py +77 -0
  830. package/templates/action-puzzle/tools/drive.py +106 -0
  831. package/templates/action-puzzle/tools/gen.py +454 -0
  832. package/templates/action-puzzle/tools/model_check.py +49 -0
  833. package/templates/action-puzzle/tools/verdict_codes.py +24 -0
  834. package/templates/adventure/.claude/settings.json +17 -0
  835. package/templates/adventure/.mcp.json +10 -0
  836. package/templates/adventure/CLAUDE.md +118 -0
  837. package/templates/adventure/Makefile +113 -0
  838. package/templates/adventure/PLAN.md +396 -0
  839. package/templates/adventure/README.md +277 -0
  840. package/templates/adventure/expect.json +25 -0
  841. package/templates/adventure/src/engine.c +543 -0
  842. package/templates/adventure/src/engine.h +48 -0
  843. package/templates/adventure/src/gen_script.h +141 -0
  844. package/templates/adventure/src/gen_world.h +511 -0
  845. package/templates/adventure/src/main.c +439 -0
  846. package/templates/adventure/src/picture.c +83 -0
  847. package/templates/adventure/src/picture.h +16 -0
  848. package/templates/adventure/src/save.c +159 -0
  849. package/templates/adventure/src/save.h +25 -0
  850. package/templates/adventure/src/sound.c +71 -0
  851. package/templates/adventure/src/sound.h +16 -0
  852. package/templates/adventure/src/text.c +349 -0
  853. package/templates/adventure/src/text.h +40 -0
  854. package/templates/adventure/tools/disk_check.py +128 -0
  855. package/templates/adventure/tools/drive.py +119 -0
  856. package/templates/adventure/tools/gen.py +1033 -0
  857. package/templates/adventure/tools/world.py +356 -0
  858. package/templates/beat-em-up/.claude/settings.json +17 -0
  859. package/templates/beat-em-up/.mcp.json +10 -0
  860. package/templates/beat-em-up/CLAUDE.md +136 -0
  861. package/templates/beat-em-up/Makefile +96 -0
  862. package/templates/beat-em-up/PLAN.md +502 -0
  863. package/templates/beat-em-up/README.md +315 -0
  864. package/templates/beat-em-up/expect-gameover.json +8 -0
  865. package/templates/beat-em-up/expect.json +29 -0
  866. package/templates/beat-em-up/src/anim.c +70 -0
  867. package/templates/beat-em-up/src/art.c +344 -0
  868. package/templates/beat-em-up/src/autopilot.h +154 -0
  869. package/templates/beat-em-up/src/brute.c +273 -0
  870. package/templates/beat-em-up/src/enemy.c +281 -0
  871. package/templates/beat-em-up/src/engine.asm +512 -0
  872. package/templates/beat-em-up/src/fighter.c +384 -0
  873. package/templates/beat-em-up/src/game.h +269 -0
  874. package/templates/beat-em-up/src/hud.c +135 -0
  875. package/templates/beat-em-up/src/main.c +341 -0
  876. package/templates/beat-em-up/src/sound.c +44 -0
  877. package/templates/beat-em-up/src/street.c +93 -0
  878. package/templates/beat-em-up/src/verdict.h +523 -0
  879. package/templates/beat-em-up/src/view.c +362 -0
  880. package/templates/beat-em-up/tools/drive.py +105 -0
  881. package/templates/beat-em-up/tools/flickercheck.py +273 -0
  882. package/templates/demo/.claude/settings.json +17 -0
  883. package/templates/demo/.mcp.json +10 -0
  884. package/templates/demo/CLAUDE.md +129 -0
  885. package/templates/demo/Makefile +66 -0
  886. package/templates/demo/PLAN.md +401 -0
  887. package/templates/demo/README.md +322 -0
  888. package/templates/demo/expect.json +945 -0
  889. package/templates/demo/src/config.asm +80 -0
  890. package/templates/demo/src/framework.asm +390 -0
  891. package/templates/demo/src/main.asm +139 -0
  892. package/templates/demo/src/music.asm +197 -0
  893. package/templates/demo/src/part_main.asm +279 -0
  894. package/templates/demo/src/part_title.asm +79 -0
  895. package/templates/demo/src/parts.asm +43 -0
  896. package/templates/demo/src/tables.asm +73 -0
  897. package/templates/demo/src/verdict.asm +179 -0
  898. package/templates/demo/tools/audio.py +80 -0
  899. package/templates/demo/tools/gen_expect.py +167 -0
  900. package/templates/demo/tools/probe.py +95 -0
  901. package/templates/hello/.claude/settings.json +17 -0
  902. package/templates/hello/.mcp.json +10 -0
  903. package/templates/hello/CLAUDE.md +100 -0
  904. package/templates/hello/Makefile +38 -0
  905. package/templates/hello/PLAN.md +200 -0
  906. package/templates/hello/expect.json +20 -0
  907. package/templates/hello/src/main.c +161 -0
  908. package/templates/hello/src/sprite.asm +27 -0
  909. package/templates/hello-kick/.claude/settings.json +17 -0
  910. package/templates/hello-kick/.mcp.json +10 -0
  911. package/templates/hello-kick/CLAUDE.md +100 -0
  912. package/templates/hello-kick/Makefile +17 -0
  913. package/templates/hello-kick/PLAN.md +199 -0
  914. package/templates/hello-kick/expect.json +20 -0
  915. package/templates/hello-kick/src/main.asm +233 -0
  916. package/templates/platformer/.claude/settings.json +17 -0
  917. package/templates/platformer/.mcp.json +10 -0
  918. package/templates/platformer/CLAUDE.md +125 -0
  919. package/templates/platformer/Makefile +86 -0
  920. package/templates/platformer/PLAN.md +360 -0
  921. package/templates/platformer/README.md +277 -0
  922. package/templates/platformer/expect.json +32 -0
  923. package/templates/platformer/src/actors.c +289 -0
  924. package/templates/platformer/src/anim.c +51 -0
  925. package/templates/platformer/src/art.c +212 -0
  926. package/templates/platformer/src/autopilot.h +30 -0
  927. package/templates/platformer/src/engine.asm +253 -0
  928. package/templates/platformer/src/game.h +248 -0
  929. package/templates/platformer/src/hud.c +90 -0
  930. package/templates/platformer/src/level.c +184 -0
  931. package/templates/platformer/src/main.c +306 -0
  932. package/templates/platformer/src/player.c +268 -0
  933. package/templates/platformer/src/sound.c +42 -0
  934. package/templates/platformer/src/verdict.h +206 -0
  935. package/templates/platformer/src/view.c +331 -0
  936. package/templates/platformer/stage-expect.json +6 -0
  937. package/templates/platformer/tools/drive.py +112 -0
  938. package/templates/platformer/tools/tearcheck.py +229 -0
  939. package/templates/shmup-vertical/.claude/settings.json +17 -0
  940. package/templates/shmup-vertical/.mcp.json +10 -0
  941. package/templates/shmup-vertical/CLAUDE.md +137 -0
  942. package/templates/shmup-vertical/Makefile +131 -0
  943. package/templates/shmup-vertical/PLAN.md +569 -0
  944. package/templates/shmup-vertical/README.md +189 -0
  945. package/templates/shmup-vertical/expect.json +38 -0
  946. package/templates/shmup-vertical/src/bullets.c +158 -0
  947. package/templates/shmup-vertical/src/bullets.h +35 -0
  948. package/templates/shmup-vertical/src/display.c +239 -0
  949. package/templates/shmup-vertical/src/display.h +40 -0
  950. package/templates/shmup-vertical/src/game.h +85 -0
  951. package/templates/shmup-vertical/src/glyph.asm +358 -0
  952. package/templates/shmup-vertical/src/hiscore.c +141 -0
  953. package/templates/shmup-vertical/src/hiscore.h +16 -0
  954. package/templates/shmup-vertical/src/hit.asm +180 -0
  955. package/templates/shmup-vertical/src/hitbox.c +59 -0
  956. package/templates/shmup-vertical/src/hitbox.h +25 -0
  957. package/templates/shmup-vertical/src/kernel.asm +330 -0
  958. package/templates/shmup-vertical/src/level.c +174 -0
  959. package/templates/shmup-vertical/src/level.h +27 -0
  960. package/templates/shmup-vertical/src/main.c +824 -0
  961. package/templates/shmup-vertical/src/mux.asm +321 -0
  962. package/templates/shmup-vertical/src/sound.asm +255 -0
  963. package/templates/shmup-vertical/src/step.asm +169 -0
  964. package/templates/shmup-vertical/src/waves.c +195 -0
  965. package/templates/shmup-vertical/src/waves.h +33 -0
  966. package/templates/shmup-vertical/stage-expect.json +6 -0
  967. package/templates/shmup-vertical/tools/drive.py +152 -0
  968. package/templates/shmup-vertical/tools/joytest.py +159 -0
  969. package/templates/shmup-vertical/tools/meter.py +15 -0
  970. package/templates/shmup-vertical/tools/phases.py +73 -0
@@ -0,0 +1,296 @@
1
+ /** Toolchain, recipe and technique tools. */
2
+ import { z } from "zod";
3
+ import { toolchainHint, recipeLookup, recipesFor, techniqueLookup, techniquesFor, checkCompatibility, timingBudget, planBudgetTool as planBudgetRun, budgetRegion, BUDGET_REGION, } from "../tools/query.js";
4
+ import { ToolchainHintSchema, RecipeLookupSchema, RecipesForSchema, TechniqueLookupSchema, TechniquesForSchema, CompatibilityCheckSchema, TimingBudgetSchema, PlanBudgetSchema, } from "../schemas/tool-outputs.js";
5
+ import { defineTool, READ_ONLY } from "./define-tool.js";
6
+ import { definedOnly } from "./defined-only.js";
7
+ export const toolchainHintTool = defineTool({
8
+ name: "c64_toolchain_hint",
9
+ title: "Toolchain-idiomatic snippet",
10
+ description: `Surface an idiomatic code snippet for a (toolchain, intent) pair. Defaults to Oscar64 when no toolchain is specified — c64-kb's primary-toolchain bias enforcer.
11
+
12
+ Purpose: Returns a ranked set of documentation chunks most relevant to the intent, scoped to the requested toolchain. The structured output carries the snippet text plus the bias-rationale string so the consuming agent can surface it to the user.
13
+
14
+ Inputs: 'toolchain' is optional (oscar64 | kickassembler | cc65). Omitting it triggers the Oscar64 default and annotates the rationale. 'intent' is a free-form description of what you want to do (e.g. "raster irq", "sprite multiplex", "disk load").
15
+
16
+ Output: {toolchain, intent, snippet, rationale, sources[]}. 'snippet' is the text of the top-matching chunk. 'rationale' explains the toolchain choice. 'sources' carries up to 3 ranked chunks.
17
+
18
+ When to use: When you need toolchain-idiomatic code patterns rather than hardware-register semantics. For register/opcode/kernal questions use the dedicated lookup tools.
19
+
20
+ Examples: {"intent": "raster irq"} → Oscar64 rasterirq.h snippet. {"toolchain": "kickassembler", "intent": "raster irq"} → KickAssembler raster setup.
21
+
22
+ See also: c64_recipe_lookup for complete buildable examples. c64_search for broad topic queries.
23
+
24
+ Limitations: Snippet quality depends on corpus coverage. If a pattern doc is missing, the rationale will note a coverage gap. Does not execute or validate code.`,
25
+ inputSchema: {
26
+ toolchain: z
27
+ .enum(["oscar64", "kickassembler", "cc65"])
28
+ .optional()
29
+ .describe("Target toolchain (default: oscar64)"),
30
+ intent: z.string().describe("What you want to do (e.g. 'raster irq', 'sprite multiplex', 'disk load')"),
31
+ },
32
+ outputSchema: ToolchainHintSchema.shape,
33
+ annotations: READ_ONLY,
34
+ run: ({ toolchain, intent }) => toolchainHint(toolchain, intent),
35
+ });
36
+ export const recipeLookupTool = defineTool({
37
+ name: "c64_recipe_lookup",
38
+ title: "Look up a buildable recipe",
39
+ description: `Look up a complete, buildable C64 recipe by canonical name (e.g. 'oscar64-hello-world'). Returns structured metadata plus the recipe doc body (synopsis, source, build command, expected output, rationale).
40
+
41
+ Purpose: Gives the agent a ready-to-use, verified example with build instructions rather than requiring it to synthesize code from raw documentation chunks.
42
+
43
+ Inputs: 'name' is the canonical recipe identifier — toolchain prefix + hyphen + recipe slug (e.g. 'oscar64-hello-world', 'kickassembler-hello-world', 'cc65-hello-world-conio'). Case-sensitive.
44
+
45
+ Output: {name, toolchain, output_format, region, source_doc, toolchain_version_verified?, documentation[], source_code?, verified_on[{variant, vic, sid, cia, region, model, cycles, shot, flags, pinned, overrides[]}]}. toolchain_version_verified is the toolchain version this repo's gates built the recipe with (e.g. '5.25' for KickAssembler); a different version may or may not build it. verified_on lists the VICE machine variants verify:recipes runs the recipe on and compares with a committed screenshot pixel for pixel (from docs/recipes/runs.json): a runs.json "pal" run is VICE's default machine, which is the c64c variant (VIC-II 8565, SID 8580, CIA 8521), not a 6569; "ntsc" is the 6567R8 with a 6581 and 6526. vic, sid and cia are the chips the run had: a chip flag in 'flags' (-ciamodel, -cia1model, -cia2model, -sidmodel, -VICIImodel) replaces the variant's chip, and 'overrides' names each one replaced (cia-revision-detect runs the c64c with -ciamodel 0, so its CIA is the 6526). pinned false means the run uses verify:recipes' defaults. An empty list means no run is compared. On not-found, 'name' is empty and 'text' lists near-match suggestions.
46
+
47
+ When to use: When you know the specific recipe name or have already identified the toolchain + intent from c64_toolchain_hint and want a complete worked example.
48
+
49
+ Examples: {"name": "oscar64-hello-world"} returns the Oscar64 hello-world recipe metadata + doc. {"name": "oscar64-hello"} returns not-found with 'oscar64-hello-world' as a suggestion.
50
+
51
+ See also: c64_recipes_for to enumerate available recipes. c64_toolchain_hint for pattern snippets.
52
+
53
+ Limitations: Only recipes explicitly ingested into the KB are available. Partial name matches trigger suggestions but do not auto-resolve.`,
54
+ inputSchema: {
55
+ name: z
56
+ .string()
57
+ .describe("Canonical recipe name (e.g. 'oscar64-hello-world', 'kickassembler-hello-world')"),
58
+ },
59
+ outputSchema: RecipeLookupSchema.shape,
60
+ annotations: READ_ONLY,
61
+ run: ({ name }) => recipeLookup(name),
62
+ });
63
+ export const recipesForTool = defineTool({
64
+ name: "c64_recipes_for",
65
+ title: "List recipes by filter",
66
+ description: `List all recipes matching an optional set of filters: toolchain, region, technique, or file format. Returns a structured table of matching Recipe nodes from FalkorDB.
67
+
68
+ Purpose: Lets the agent discover what buildable examples are available before committing to a specific recipe. All filters are optional — omitting all returns the full recipe catalog.
69
+
70
+ Inputs: All optional. 'toolchain' is one of oscar64 | kickassembler | cc65. 'region' is pal | ntsc | both (note: recipes with region='both' appear for any region filter). 'verified_on' is a MachineVariant name (c64c, ntsc, oldntsc, ...) or a region word (PAL, NTSC): only recipes verify:recipes runs on that variant, or on any variant of that region. 'technique' is an exact Technique.title match (Phase 2: no techniques yet — omit for now). 'file_format' is an exact FileFormat.name match (e.g. 'PRG').
71
+
72
+ Output: {filter, recipes[{name, toolchain, output_format, region, source_doc}]}. Empty recipes array means no matches — try a broader filter.
73
+
74
+ When to use: Before calling c64_recipe_lookup, use this to discover what names exist. Also useful to audit coverage gaps.
75
+
76
+ Examples: {"toolchain": "oscar64"} → table of all Oscar64 recipes. {} → full catalog. {"region": "pal"} → PAL-compatible recipes. {"verified_on": "oldntsc"} → the recipes run on the 6567R56A.
77
+
78
+ See also: c64_recipe_lookup to fetch a specific recipe's full content. c64_toolchain_hint for pattern snippets without a complete recipe.
79
+
80
+ Limitations: Returns graph metadata only — use c64_recipe_lookup to get the actual source code. technique filter is a no-op in Phase 2 (no Technique nodes yet).`,
81
+ inputSchema: {
82
+ toolchain: z.enum(["oscar64", "kickassembler", "cc65"]).optional().describe("Filter by toolchain"),
83
+ region: z
84
+ .enum(["pal", "ntsc", "both"])
85
+ .optional()
86
+ .describe("Filter by region (recipes with region='both' match any value)"),
87
+ technique: z.string().optional().describe("Filter by Technique title (exact match)"),
88
+ file_format: z.string().optional().describe("Filter by FileFormat name (e.g. 'PRG')"),
89
+ verified_on: z
90
+ .string()
91
+ .optional()
92
+ .describe("MachineVariant name (c64c, ntsc, oldntsc) or region word (PAL, NTSC): recipes run in VICE on it"),
93
+ },
94
+ outputSchema: RecipesForSchema.shape,
95
+ annotations: READ_ONLY,
96
+ run: (args) => recipesFor(definedOnly(args)),
97
+ });
98
+ export const techniqueLookupTool = defineTool({
99
+ name: "c64_technique_lookup",
100
+ title: "Look up a technique",
101
+ description: `Look up a Commodore 64 programming technique by canonical snake_case name (e.g. 'stable_raster_irq'). Returns technique metadata, chip, region requirements, all USES edges to Registers and KERNAL routines, the techniques it REQUIRES (must be set up before, or run underneath, it) and those that require it, the pitfalls it is the Fix for (MITIGATED_BY), the list of recipes that implement it, and the top documentation chunks.
102
+
103
+ Guidelines: Use when you know a specific technique name and want its full profile — registers it touches, KERNAL calls it makes, what it presupposes (text_zoom requires stable_raster_irq on every scanline of its zone), and buildable recipe examples. For discovery ("what raster techniques exist?", "what builds on stable_raster_irq?"), use c64_techniques_for instead.
104
+
105
+ Limitations: Returns structured data from FalkorDB; documentation chunks from Qdrant. Technique must be indexed (ingested from docs/techniques/). Partial or hyphenated names trigger a suggestion list.
106
+
107
+ Param notes: 'name' is the exact snake_case Technique.name (e.g. 'stable_raster_irq', 'sprite_multiplex_8'). Case-sensitive.
108
+
109
+ Expected length: 1 technique header + register/kernal/recipe lists + up to 3 doc chunks (~200-600 words total).
110
+
111
+ Example: {"name": "stable_raster_irq"} returns the stable raster IRQ technique with its register list (D011, D012, D019), recipes, and documentation.
112
+
113
+ Returns structured: {name, title, category, complexity, chip?, requires_region?, uses_registers[], uses_kernal[], recipes[], requires[{name,title}], required_by[{name,title}], mitigates[{name,title,severity}], documentation[], cost?}. requires/required_by are direct REQUIRES edges authored from **Requires:** lines (CONVENTIONS-techniques.md); a variant of a technique (double_irq of stable_raster_irq) is not a prerequisite and does not appear here. 'cost' is present only when the page carries a **Cost:** line: {cycles_per_line?, cycles_per_frame?, lines_active?, bytes_code?, bytes_data?, zp_bytes?, irq_slots?, basis}, integers, with only the keys the page stated; 'basis' is one of measured-vice, derived-listing, arithmetic, estimated and says how the figures were obtained (measured-vice means run in VICE; estimated means a judgement). Cycles are per PAL frame of 19,656 unless the page says otherwise; bytes are the built recipe's segments. 'claims' [{unit, mode, ranges?, relocatable?}] lists the HardwareUnits the technique holds (**Claims:** line; units such as sid_voice_2, sprite_0..7, vic_raster_irq, irq_vector_0314, zero_page with ranges like "E0-EF"); mode is owns, shares (writes under the owner's protocol), reads or init (once, before the frame loop). 'claims_stated' is stated, none (claims no unit) or unknown (the page states nothing: never read unknown as none); 'claims_basis' is measured-vice, derived-listing or estimated.`,
114
+ inputSchema: {
115
+ name: z
116
+ .string()
117
+ .describe("Canonical snake_case technique name (e.g. 'stable_raster_irq', 'sprite_multiplex_8')"),
118
+ },
119
+ outputSchema: TechniqueLookupSchema.shape,
120
+ annotations: READ_ONLY,
121
+ run: ({ name }) => techniqueLookup(name),
122
+ });
123
+ export const techniquesForTool = defineTool({
124
+ name: "c64_techniques_for",
125
+ title: "List techniques by filter",
126
+ description: `List C64 techniques matching an optional set of filters: category, chip, region, register, recipe, requires, or claims. All filters are optional — omitting all returns the full technique catalog.
127
+
128
+ Purpose: Lets the agent discover what techniques are documented before committing to a specific one. Use before c64_technique_lookup to find the right technique name.
129
+
130
+ Inputs: All optional. 'category' is one of raster | sprite | scroll | bitmap | effect | music | cpu | banking | loader. 'chip' is a chip name (e.g. 'VIC-II', 'SID'). 'region' is PAL or NTSC (techniques locked to that region by a REQUIRES_REGION edge). 'register' is a register name (e.g. 'D011') to find techniques that USE it. 'recipe' is a recipe canonical name to find what techniques it implements. 'requires' is a technique name to find what builds on it — techniques whose REQUIRES chain reaches it directly or through other techniques. 'claims' is a HardwareUnit name (e.g. 'sid_voice_3', 'vic_raster_irq', 'zero_page') to find the techniques that claim it in any mode; a technique whose page states no claims is not listed, which does not mean it leaves the unit alone.
131
+
132
+ Output: {filter, techniques[{name, title, category, complexity}]}. Empty array means no matches.
133
+
134
+ Examples: {"category": "raster"} → all raster techniques. {"chip": "VIC-II"} → ~30+ rows. {"register": "D011"} → techniques that use SCROLY. {"requires": "stable_raster_irq"} → every technique that presupposes a stable raster IRQ.
135
+
136
+ See also: c64_technique_lookup for full profile of a specific technique.
137
+
138
+ Limitations: region filter matches only techniques with an explicit REQUIRES_REGION edge (PAL/NTSC-locked). Most techniques work on both regions and won't appear in a region filter. The requires filter follows REQUIRES edges only and does not unify variants: double_irq is a variant of stable_raster_irq with no edge between them, so {"requires": "stable_raster_irq"} does not list sideborder_open (which requires double_irq) — ask for double_irq as well. Chains longer than twelve edges are not followed.`,
139
+ inputSchema: {
140
+ category: z
141
+ .string()
142
+ .optional()
143
+ .describe("Technique category (raster | sprite | scroll | bitmap | effect | music | cpu | banking | loader)"),
144
+ chip: z.string().optional().describe("Chip name (e.g. 'VIC-II', 'SID', '6510')"),
145
+ region: z
146
+ .string()
147
+ .optional()
148
+ .describe("Region requirement filter: PAL or NTSC (matches REQUIRES_REGION edge)"),
149
+ register: z
150
+ .string()
151
+ .optional()
152
+ .describe("Register name (e.g. 'D011') — returns techniques that USE this register"),
153
+ recipe: z
154
+ .string()
155
+ .optional()
156
+ .describe("Recipe canonical name — returns techniques that this recipe implements"),
157
+ requires: z
158
+ .string()
159
+ .optional()
160
+ .describe("Technique name — returns techniques whose REQUIRES chain reaches it (what builds on it)"),
161
+ claims: z
162
+ .string()
163
+ .optional()
164
+ .describe("HardwareUnit name (e.g. 'sid_voice_3', 'vic_raster_irq') — returns techniques with a CLAIMS edge to it"),
165
+ },
166
+ outputSchema: TechniquesForSchema.shape,
167
+ annotations: READ_ONLY,
168
+ run: (args) => techniquesFor(definedOnly(args)),
169
+ });
170
+ export const checkCompatibilityTool = defineTool({
171
+ name: "c64_check_compatibility",
172
+ title: "Check technique compatibility",
173
+ description: `Check whether two or more C64 techniques can be combined. Hard conflicts come from authored resource demands on the techniques (DEMANDS edges): two techniques that each need every CPU cycle on their lines, a cycle-exact technique against one that takes interrupts mid-frame, a constant-sprite-set technique against a multiplexer, a KERNAL-out technique against KERNAL calls, and PAL-vs-NTSC requirements. Soft conflicts come from shared registers and shared KERNAL routines. The check also takes each technique's REQUIRES closure — the techniques it must have set up underneath it — and runs the demand and unit rules between one technique's prerequisites and the other technique, reporting a hit as prerequisite_conflict with the rule that fired in underlying_kind and its own severity (hard, soft or info); a technique is never reported against a prerequisite it declared itself (kernal_clobbers_zp excepted, below), and no technique's own demand set is changed by this.
174
+
175
+ Inputs: 'techniques' is an array of 2+ canonical technique names (snake_case). Order doesn't matter — all pairwise combinations are checked.
176
+
177
+ Output: {techniques[], conflicts[], band_separated[], shared_infrastructure[], data_coverage[], verdict}. verdict is 'incompatible' if any hard conflict exists (each carries a 'resolution' saying how to separate the two, usually by raster region), 'warnings' if only soft conflicts exist, 'compatible' otherwise. A prerequisite_conflict names the input techniques in a/b, the implied ones in 'via', and the rule in 'underlying_kind'. shared_infrastructure gains a 'missing_prerequisite' entry (with required_by[]) for every technique the set leans on through REQUIRES without naming it. data_coverage says, per technique, how many registers, KERNAL routines and demands the graph holds for it — implied techniques appear with implied_by[]; a technique with known=false cannot conflict with anything by construction, and the verdict is silent about it rather than a clearance.
178
+
179
+ Conflict kinds: cpu_exclusive, cpu_vs_irq, sprite_set, kernal_banked_out, serial_bus_busy (a resident fast loader against KERNAL disk I/O), region_mismatch (hard); shared_register, shared_kernal (soft); prerequisite_conflict (the severity of its underlying_kind).
180
+
181
+ Unit claims (**Claims:** lines, CLAIMS edges to HardwareUnit nodes): unit_contention (hard: both own the same unit, e.g. two raster-IRQ owners, since there is one raster compare, or two owners of sprite_0..7); zero_page_overlap (hard, soft when either side is relocatable; 'shared' lists the bytes); unit_shared (soft: one owns and the other shares, e.g. SFX on voice 2 beside a music player, or stable_raster_irq, a way into a handler, beside a raster effect that owns the compare; a resident loader beside a VIC bank owner says not to write $DD00 raw); unit_read_while_driven (soft: one reads a port the other drives); init_order (info: one uses the unit once at start-up; info does not change the verdict). Between a technique and its own prerequisite, unit_contention and zero_page_overlap do not run, and unit_shared runs only when the sharer is the one that requires the owner. A prerequisite's claims on units its input holds are the input's and are not reported again. kernal_clobbers_zp (soft): one technique calls a KERNAL routine (**Uses kernal:**) whose zero-page may set (CLOBBERS_ZP, a static walk of the ROM through the power-on vectors, an upper bound) overlaps bytes the other claims; 'shared' lists the bytes and the routines. It also runs inside one input's own chain, the technique against itself and against its own prerequisites, since a KERNAL call clobbers the bytes whoever declared them; such a finding has a = b = that input (a prerequisite_conflict with the prerequisites in 'via' when they are involved). A routine hit already reported for the same inputs, routine and bytes is not repeated through a prerequisite. Only technique claims are checked: the zero-page bytes and vectors a recipe chooses are not yet (issue #22, step 8). data_coverage carries claims: stated | none | unknown per technique, and the text says for how many inputs claims are stated; an unknown claim set is never treated as "claims nothing", so a unit conflict with it cannot be ruled out.
182
+
183
+ Examples: {"techniques": ["fli_image", "sprite_multiplex_24"]} → incompatible (cpu_vs_irq, sprite_set and unit_contention on vic_raster_irq; resolution: multiplex outside the FLI region, in one interrupt chain). {"techniques": ["stable_raster_irq", "raster_bars"]} → warnings (unit_shared on vic_raster_irq: the stable entry runs inside raster_bars' handler; shared registers). {"techniques": ["fli_image", "digi_4bit"]} → incompatible (cpu_vs_irq: continuous interrupts inside the FLI region).
184
+
185
+ Raster bands: a technique page may state the raster lines it holds the CPU on (**Raster band:**, e.g. fli_image 45-250). When both techniques state line bands and they share no line, the line-sharing rules (cpu_exclusive, cpu_vs_irq through mid-frame IRQs or sprite-set changes, sprite_set) do not fire; the pair is listed in band_separated[] {a, b, a_band, b_band, rules[]} instead. A missing band, or one the program chooses ('movable'), keeps the conflict, and its rationale names the unknown side. data_coverage carries each technique's raster_band.
186
+
187
+ Limitations: demands and prerequisites are authored per technique in docs/techniques (see CONVENTIONS-techniques.md); a technique without them only participates in the soft checks. Named techniques are checked as named even when one requires the other. Where bands are not stated, 'incompatible' means 'not on the same raster lines', and the resolution says so.`,
188
+ inputSchema: {
189
+ techniques: z
190
+ .array(z.string())
191
+ .min(2)
192
+ .describe("Array of 2+ canonical technique names to check (e.g. ['stable_raster_irq', 'raster_bars'])"),
193
+ },
194
+ outputSchema: CompatibilityCheckSchema.shape,
195
+ annotations: READ_ONLY,
196
+ run: ({ techniques }) => checkCompatibility(techniques),
197
+ });
198
+ export const timingBudgetTool = defineTool({
199
+ name: "c64_timing_budget",
200
+ title: "Per-scanline cycle budget",
201
+ description: `Compute the per-scanline cycle budget for a C64 technique on a given region (PAL or NTSC). Returns the canonical cycle constants plus IRQ overhead and net user-available cycles.
202
+
203
+ Purpose: Gives the agent the authoritative cycle math for raster-critical technique implementations. Use before writing or evaluating cycle-tight C64 raster code.
204
+
205
+ Inputs: 'technique' is the canonical technique name (e.g. 'stable_raster_irq'). 'region' is 'pal' or 'ntsc' (case-insensitive). 'sprites_per_line' (optional, 0-8) is the number of sprites displayed on the line; without it the technique's own Cost sprites_per_line is used, and without that sprite DMA is not counted and a note says so.
206
+
207
+ Output: {technique, region, cycles_per_line, cycles_per_frame, badline_cycles_lost, irq_overhead_cycles, sprites_per_line, sprites_source ('input' | 'technique' | 'none'), sprite_dma_cycles, user_cycles_per_line_normal, user_cycles_per_line_badline, notes[]}.
208
+
209
+ Constants: PAL: 63 cycles/line × 312 lines = 19656 cycles/frame. NTSC: 65 cycles/line × 263 lines = 17095 cycles/frame. Badline: 43 cycles to plan on (the VIC holds the bus for cycles 15-54 and BA drops on cycle 12; only writes fit in 12-14). Default IRQ overhead: 36 cycles (7 interrupt sequence + 29 KERNAL dispatcher at $FF48 via $0314). Sprite DMA: 3 + 2 per sprite for sprites numbered without gaps (5 for one, 19 for eight, measured in VICE x64sc); each gap adds up to 3.
210
+
211
+ Examples: {"technique": "stable_raster_irq", "region": "pal"} → cycles_per_line=63, user_cycles_per_line_normal=27, user_cycles_per_line_badline=0 (a handler entered on a badline through the KERNAL vector has nothing left on that line). {"technique": "stable_raster_irq", "region": "pal", "sprites_per_line": 8} → sprite_dma_cycles=19, user_cycles_per_line_normal=8.
212
+
213
+ Limitations: irq_overhead is the default 36 cycles for every technique (an earlier version of this line said it was read from a Technique irq_overhead property; nothing writes one, and the read was removed in tools 1.25.0); a handler on $FFFE with the KERNAL banked out pays 7 plus its own register saves. An earlier version of this description said 23 badline cycles and 14 overhead, which was not what the tool computed. An earlier version did not subtract sprite DMA at all.`,
214
+ inputSchema: {
215
+ technique: z.string().describe("Canonical technique name (e.g. 'stable_raster_irq')"),
216
+ region: z
217
+ .string()
218
+ .optional()
219
+ .default("pal")
220
+ .describe("Region: 'pal' or 'ntsc' (case-insensitive, default: 'pal')"),
221
+ sprites_per_line: z
222
+ .number()
223
+ .int()
224
+ .min(0)
225
+ .max(8)
226
+ .optional()
227
+ .describe("Sprites displayed on the line (0-8). Overrides the technique's Cost sprites_per_line."),
228
+ },
229
+ outputSchema: TimingBudgetSchema.shape,
230
+ annotations: READ_ONLY,
231
+ run: ({ technique, region, sprites_per_line }) => timingBudget({ technique, region, ...definedOnly({ sprites_per_line }) }),
232
+ });
233
+ export const planBudgetTool = defineTool({
234
+ name: "c64_plan_budget",
235
+ title: "Frame budget for a set of techniques",
236
+ description: `Add a set of techniques up against a frame, honestly: per phase and region, a cycle range, what was left out and why, what is unknown, and a verdict.
237
+
238
+ Purpose: Answers "does this combination fit a frame?" before code is written. It does not sum blindly: a missing figure is never counted as zero, a figure above one frame is never summed, work one figure already includes is not counted twice, and every figure names the recipe it was measured on.
239
+
240
+ Inputs: 'techniques' is a list of canonical technique names, each optionally with a phase: "name" (play), "name:play", "name:transition" (level decode, wipe) or "name:init" (one-off setup). Each phase is budgeted alone. 'design' is a GameDesign name (a whole game from docs/game-design/designs, e.g. "platformer_scaffold_oscar64"): its COMPOSES edges, each in its phase, are budgeted first, then any 'techniques' given; its region is the default. Give 'techniques', 'design' or both. 'region' is 'pal', 'ntsc' or 'both' (default: PAL unless every region-locked member is NTSC-locked). 'screen' is 'on' (default) or 'off'. 'sprites_per_line' (0-8) and 'sprite_lines' (default 200) charge sprite DMA, 3 + 2n cycles a line.
241
+
242
+ Output: {design{name, title, region, instance_of[], realised_by[], composes[{technique, phase}], source_doc, measured[{phase, region, worst, typical, basis, source, predicted{low, high, fixed, verdict, missing[]}, position: below_low | within | within_incomplete | above_high | not_predicted, finding}]} | null, design_not_found?{requested, known[]}, techniques, refused[], region, screen, sprites, phases[{phase, region, frame, contributors[{name, low, high, every_frame, basis, charge, measured_on, conditions}], excluded[{name, reason: multi_frame | included_by | inside_band_of, by?, cycles?}], unknown[], not_found[], to_measure[{technique, recipe, why}], fixed_losses{badlines, sprite_dma, charged_for[], badlines_in_bands, floor}, worst_only[], low, high, floor, verdict, weakest_basis, irq_slots, notes[]}], bytes{sum, contributors, excluded (whole_program), inside[{name, by}], without_bytes}, verdict, assumptions[]}. A design's position places its measured worst against [low, high + fixed]: within_incomplete is inside that range while predicted.missing is non-empty, so the uncounted members could move the range past it and it is not agreement; above_high with members missing may be explained by them; below_low stands, since a missing member can only raise the range.
243
+
244
+ Rules: low sums each member's cycles_per_frame_typical where the page states a measured one, else its cycles_per_frame; high sums cycles_per_frame (worst frames). A member with no cycles figure goes to unknown and to_measure, with the recipe to measure it on. A figure above the frame (19,656 PAL, 17,095 NTSC) is excluded as multi_frame. A member named in another's **Cost includes:**, followed through the graph (a includes b, b includes c), is excluded as included_by, unless the including member is itself multi-frame; of two members that include each other the first listed is kept. A name listed twice in one phase is counted once and the repeat is listed in refused. A technique that holds every cycle of a stated raster band (cycles_per_line 63 and a line band) is charged band lines × line length, and its REQUIRES closure in the set is excluded as inside_band_of. With the screen on, the badlines (lines 51-243, every eighth, 25 × 43 = 1,075 cycles) outside any band charge, and the stated sprite DMA, are charged as fixed losses unless every summed figure is a band charge or is measured with measured-on conditions that say the screen was on; a figure measured blanked, one that does not say, and an arithmetic, derived-listing or estimated one are all charged. A stall takes its cycles wherever the code runs, so the charge is exact when no summed figure already holds stalls and too high by what a screen-on figure holds; fixed_losses.floor is the part no figure can hold. The low end is not a floor: a typical figure is a common frame or a real run's worst, and worst_only lists members with no typical at all. floor is the band and per-line charges, which run every frame, plus fixed_losses.floor. Verdict per phase: fits when nothing is unknown, missing or multi-frame and high + fixed losses fit the frame; over when floor passes the frame; otherwise undetermined. The overall verdict is the worst phase's. Bytes flagged "(whole PRG)" on their measured-on line are not summed; a member whose work is inside another's figure that states bytes is listed in inside, not summed. 'region' other than pal, ntsc or both is refused.
245
+
246
+ Examples: {"techniques": ["wave_director", "object_pool"]} → object_pool excluded (included_by wave_director); 1,170-3,188 plus 1,075 fixed, floor 1,075; fits. {"techniques": ["fli_image", "stable_raster_irq", "double_irq"]} → fli_image charged 207 lines × 63 = 13,041; the two prerequisites inside its band; all 25 badlines are inside the band, so no fixed loss. {"techniques": ["soft_scroll_h", "sid_play_routine_pattern"]} → soft_scroll_h multi_frame; undetermined. {"design": "falling_blocks_oscar64", "region": "pal"} → init and play phases; play undetermined (text_mode_overlay_render and others unknown); the design's measured PAL worst frame, 6,276 cycles, is set beside the predicted range with where it falls.
247
+
248
+ See also: c64_timing_budget for the cycles left on one raster line; c64_check_compatibility for hardware claims, zero page and raster-line conflicts; c64_game_briefing, whose budget block uses the same rules on a proposed set in one play phase.
249
+
250
+ Limitations: the figures are the pages' own, each measured on one recipe; a different implementation costs differently. Figures are mostly PAL measurements, judged against the NTSC frame unchanged. Claims, zero page and memory are not judged here. Most compositions give undetermined rather than over: only work that runs every frame is a floor.`,
251
+ inputSchema: {
252
+ techniques: z
253
+ .array(z.string())
254
+ .min(1)
255
+ .optional()
256
+ .describe('Technique names, each "name" or "name:phase" (phase: play, transition, init)'),
257
+ design: z
258
+ .string()
259
+ .min(1)
260
+ .optional()
261
+ .describe("GameDesign name (e.g. 'platformer_scaffold_oscar64'): budgets its composed techniques by phase"),
262
+ region: z
263
+ .string()
264
+ .regex(BUDGET_REGION, "region is pal, ntsc or both")
265
+ .optional()
266
+ .describe("Region: 'pal', 'ntsc' or 'both' (case-insensitive; default PAL unless every region-locked member is NTSC)"),
267
+ screen: z.enum(["on", "off"]).optional().describe("Display on (default) or blanked"),
268
+ sprites_per_line: z
269
+ .number()
270
+ .int()
271
+ .min(0)
272
+ .max(8)
273
+ .optional()
274
+ .describe("Sprites displayed on each sprite line (0-8)"),
275
+ sprite_lines: z
276
+ .number()
277
+ .int()
278
+ .min(0)
279
+ .max(312)
280
+ .optional()
281
+ .describe("Raster lines with sprites on them (default 200)"),
282
+ },
283
+ outputSchema: PlanBudgetSchema.shape,
284
+ annotations: READ_ONLY,
285
+ run: ({ techniques, design, region, screen, sprites_per_line, sprite_lines }) => planBudgetRun({
286
+ ...definedOnly({
287
+ techniques,
288
+ design,
289
+ region: budgetRegion(region),
290
+ screen,
291
+ sprites_per_line,
292
+ sprite_lines,
293
+ }),
294
+ }),
295
+ });
296
+ //# sourceMappingURL=tools-recipes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools-recipes.js","sourceRoot":"","sources":["../../src/server/tools-recipes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /** Runtime tools (the eval substrate): run a built PRG in VICE. */
2
+ import { runGame, RunGameInputSchema, RunGameOutputSchema } from "../tools/run-game.js";
3
+ import { defineTool } from "./define-tool.js";
4
+ /** c64_run_game kills the x64sc on monitor port 6502 and starts a new one. */
5
+ const RUN_GAME = {
6
+ readOnlyHint: false,
7
+ destructiveHint: true,
8
+ idempotentHint: false,
9
+ openWorldHint: false,
10
+ };
11
+ async function runGameReply(args) {
12
+ const r = await runGame(args);
13
+ const summary = `c64_run_game: ${r.exit_reason} after ${r.duration_ms}ms\n` +
14
+ ` state @ $${r.state_address.toString(16).padStart(4, "0")} (size ${r.state_size})\n` +
15
+ ` ${r.frames_observed} polls, ${r.inputs_fired}/${args.inputs.length} inputs fired\n` +
16
+ (r.error ? ` error: ${r.error}\n` : "") +
17
+ (r.final_screen ? `\n--- final screen ---\n${r.final_screen}\n` : "");
18
+ // A caught VICE failure comes back as exit_reason "error"; without
19
+ // isError an MCP client read it as success.
20
+ return { text: summary, structured: r, isError: r.exit_reason === "error" };
21
+ }
22
+ export const runGameTool = defineTool({
23
+ name: "c64_run_game",
24
+ title: "Run a PRG in VICE and trace its state",
25
+ description: `Spawn x64sc with -autostart for the given .prg, drive it via the parallel-input-cell harness pattern (writeMemory into the game's state struct), and return a state trace + final screen render. The eval substrate primitive — used to verify a built game reaches expected states.
26
+
27
+ Inputs:
28
+ - prg_path (required): absolute path to the .prg to run
29
+ - dbj_path (required): absolute path to the matching .dbj (typed debug info; oscar64 -g produces this)
30
+ - state_symbol (optional, default "state"): top-level state struct symbol name
31
+ - state_read_len (optional, default 16): bytes to read per poll
32
+ - inputs (optional): scheduled writes into the state struct — each {after_ms, offset_in_state, bytes}. Use this to drive harness inputs (e.g. write 1 to state.start_request to simulate a "press fire").
33
+ - poll_every_ms (optional, default 250): state-polling cadence
34
+ - max_duration_ms (optional, default 20000): session hard cap
35
+ - autostart_wait_ms (optional, default 5000): time after x64sc launch before harness loop starts (lets autostart settle)
36
+ - capture_screen (optional, default true): render the final screen
37
+
38
+ Output: structured RunGameOutput with state_address, state_size, frames_observed, inputs_fired, trace[{at_ms, bytes}], final_screen, exit_reason.
39
+
40
+ Limitations: kills any existing x64sc on the machine to ensure clean state. Assumes x64sc binary is on PATH. Designed for the parallel-input-cell pattern (see loop/demo/unlock-trap.c); BP-driven games don't fit.
41
+
42
+ Example: {"prg_path": "/.../unlock-trap.prg", "dbj_path": "/.../unlock-trap.dbj", "inputs": [{"after_ms": 1000, "offset_in_state": 9, "bytes": [1]}, {"after_ms": 2000, "offset_in_state": 8, "bytes": [1]}], "max_duration_ms": 8000}`,
43
+ inputSchema: RunGameInputSchema,
44
+ outputSchema: RunGameOutputSchema,
45
+ annotations: RUN_GAME,
46
+ run: runGameReply,
47
+ });
48
+ //# sourceMappingURL=tools-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools-runtime.js","sourceRoot":"","sources":["../../src/server/tools-runtime.ts"],"names":[],"mappings":"AAAA,mEAAmE;AAGnE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AACxF,OAAO,EAAE,UAAU,EAAkB,MAAM,kBAAkB,CAAC;AAE9D,8EAA8E;AAC9E,MAAM,QAAQ,GAAoB;IAChC,YAAY,EAAE,KAAK;IACnB,eAAe,EAAE,IAAI;IACrB,cAAc,EAAE,KAAK;IACrB,aAAa,EAAE,KAAK;CACrB,CAAC;AAIF,KAAK,UAAU,YAAY,CAAC,IAAiB;IAC3C,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,OAAO,GACX,iBAAiB,CAAC,CAAC,WAAW,UAAU,CAAC,CAAC,WAAW,MAAM;QAC3D,cAAc,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC,UAAU,KAAK;QACtF,KAAK,CAAC,CAAC,eAAe,WAAW,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,iBAAiB;QACtF,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QACxC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACxE,mEAAmE;IACnE,4CAA4C;IAC5C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,WAAW,KAAK,OAAO,EAAE,CAAC;AAC9E,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG,UAAU,CAAC;IACpC,IAAI,EAAE,cAAc;IACpB,KAAK,EAAE,uCAAuC;IAC9C,WAAW,EAAE;;;;;;;;;;;;;;;;;uOAiBwN;IACrO,WAAW,EAAE,kBAAkB;IAC/B,YAAY,EAAE,mBAAmB;IACjC,WAAW,EAAE,QAAQ;IACrB,GAAG,EAAE,YAAY;CAClB,CAAC,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Every MCP tool, in the order tools/list has always returned them. The
3
+ * definitions live in one file per tool family; this list is the only place
4
+ * the order is decided.
5
+ */
6
+ import { healthTool, searchTool, lookupRegisterTool, lookupKernalTool, memoryMapTool, lookupOpcodeTool, palNtscDiffTool, } from "./tools-lookup.js";
7
+ import { toolchainHintTool, recipeLookupTool, recipesForTool, techniqueLookupTool, techniquesForTool, checkCompatibilityTool, timingBudgetTool, planBudgetTool, } from "./tools-recipes.js";
8
+ import { pitfallsForTool, lintSourceTool, failureDiagnoseTool } from "./tools-pitfalls.js";
9
+ import { demoBriefingTool, gameBriefingTool } from "./tools-briefings.js";
10
+ import { ingestDocTool, coverageTool, suggestLinksTool, reportGapTool } from "./tools-maintenance.js";
11
+ import { runGameTool } from "./tools-runtime.js";
12
+ import { memorizationTool } from "../tools/memorization-mcp.js";
13
+ export const TOOLS = [
14
+ healthTool,
15
+ searchTool,
16
+ ingestDocTool,
17
+ lookupRegisterTool,
18
+ lookupKernalTool,
19
+ memoryMapTool,
20
+ lookupOpcodeTool,
21
+ palNtscDiffTool,
22
+ toolchainHintTool,
23
+ recipeLookupTool,
24
+ recipesForTool,
25
+ techniqueLookupTool,
26
+ techniquesForTool,
27
+ checkCompatibilityTool,
28
+ timingBudgetTool,
29
+ planBudgetTool,
30
+ pitfallsForTool,
31
+ lintSourceTool,
32
+ failureDiagnoseTool,
33
+ demoBriefingTool,
34
+ gameBriefingTool,
35
+ coverageTool,
36
+ suggestLinksTool,
37
+ reportGapTool,
38
+ // Runtime tools (Layer 1: eval substrate)
39
+ runGameTool,
40
+ // SID Phase A: memorization detection. Absent where the Python analyzer is not installed.
41
+ ...(memorizationTool ? [memorizationTool] : []),
42
+ ];
43
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/server/tools.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EACL,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,gBAAgB,EAChB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACtG,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAEhE,MAAM,CAAC,MAAM,KAAK,GAA+B;IAC/C,UAAU;IACV,UAAU;IACV,aAAa;IACb,kBAAkB;IAClB,gBAAgB;IAChB,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,cAAc;IACd,mBAAmB;IACnB,iBAAiB;IACjB,sBAAsB;IACtB,gBAAgB;IAChB,cAAc;IACd,eAAe;IACf,cAAc;IACd,mBAAmB;IACnB,gBAAgB;IAChB,gBAAgB;IAChB,YAAY;IACZ,gBAAgB;IAChB,aAAa;IACb,0CAA0C;IAC1C,WAAW;IACX,0FAA0F;IAC1F,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;CAChD,CAAC"}
package/dist/server.js ADDED
@@ -0,0 +1,95 @@
1
+ /**
2
+ * c64-kb MCP server: a thin wrapper over the tool functions in src/tools/.
3
+ *
4
+ * Structured tools return `structuredContent` matching a Zod
5
+ * `outputSchema`, alongside a `content[0].text` markdown blob. Closed-set
6
+ * string args use `z.enum()`. Tool descriptions follow the 6-component
7
+ * template: purpose, guidelines, limitations, param notes, expected length,
8
+ * example. `c64_health` lists the live surface; the list is not repeated
9
+ * here because it went stale.
10
+ *
11
+ * The tools themselves are defined in src/server/ (one file per family) and
12
+ * registered by one loop; src/server/tools.ts fixes their order.
13
+ */
14
+ import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
15
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
16
+ import { getVersions } from "./services/versions.js";
17
+ import { closeAll } from "./context.js";
18
+ import { registerTools } from "./server/define-tool.js";
19
+ import { TOOLS } from "./server/tools.js";
20
+ import { STATIC_RESOURCES, readStaticResource, readRegisterResource } from "./tools/resources.js";
21
+ import { demoBriefPrompt, gameBriefPrompt, demoBriefArgs, gameBriefArgs } from "./tools/prompts.js";
22
+ export async function startMcpServer() {
23
+ // The version said "0.1.0" through package 0.8.0.
24
+ const server = new McpServer({ name: "c64-kb", version: getVersions().package }, {
25
+ instructions: "Commodore 64 knowledge base. Call c64_health first to see what the stores hold; c64_demo_briefing and c64_game_briefing plan a whole program in one call.",
26
+ });
27
+ registerTools(server, TOOLS);
28
+ registerResources(server);
29
+ registerPrompts(server);
30
+ const transport = new StdioServerTransport();
31
+ await server.connect(transport);
32
+ exitWhenStdinCloses(server);
33
+ }
34
+ function registerResources(server) {
35
+ for (const r of STATIC_RESOURCES) {
36
+ server.registerResource(r.name, r.uri, { description: r.description, mimeType: "text/markdown" }, () => {
37
+ const res = readStaticResource(r.uri);
38
+ return { contents: res ? [res] : [] };
39
+ });
40
+ }
41
+ // Template resource for per-register structured lookup.
42
+ server.registerResource("register", new ResourceTemplate("c64://register/{name}", { list: undefined }), {
43
+ description: "Per-register structured data (name, address, chip, R/W, aliases). Useful for direct attach when the consuming agent already knows which register it cares about.",
44
+ }, async (uri, vars) => {
45
+ const raw = vars.name;
46
+ const name = typeof raw === "string" ? raw : Array.isArray(raw) ? (raw.at(0) ?? "") : "";
47
+ const res = await readRegisterResource(uri.toString(), name);
48
+ return { contents: res ? [res] : [] };
49
+ });
50
+ }
51
+ function registerPrompts(server) {
52
+ server.registerPrompt("c64_demo_brief", {
53
+ description: "Design a C64 demo from a natural-language brief. Templated body guides the agent through technique identification, register/KERNAL lookup, pitfall surfacing, build order, and toolchain split (Oscar64 vs KickAssembler). Prefer the c64_demo_briefing tool, which runs the lookups itself.",
54
+ argsSchema: demoBriefArgs,
55
+ }, demoBriefPrompt);
56
+ server.registerPrompt("c64_game_brief", {
57
+ description: "Design a C64 game from a natural-language brief. Templated body guides the agent through archetype matching, architecture sketch, technique selection, SID approach, KERNAL usage, and toolchain split. Prefer the c64_game_briefing tool, which runs the lookups itself.",
58
+ argsSchema: gameBriefArgs,
59
+ }, gameBriefPrompt);
60
+ }
61
+ /**
62
+ * A stdio client shuts the server down by closing stdin (MCP spec,
63
+ * transports/stdio); the SDK's transport does not listen for that, and the
64
+ * open FalkorDB socket kept the process alive. Close everything and exit.
65
+ */
66
+ function exitWhenStdinCloses(server) {
67
+ let closing = false;
68
+ const shutdown = (code) => {
69
+ if (closing)
70
+ return;
71
+ closing = true;
72
+ const force = setTimeout(() => process.exit(code), 3000);
73
+ force.unref();
74
+ void server
75
+ .close()
76
+ .catch((e) => {
77
+ console.error("c64-kb: closing the MCP server failed:", e);
78
+ })
79
+ .then(() => closeAll())
80
+ .finally(() => process.exit(code));
81
+ };
82
+ process.stdin.on("end", () => {
83
+ shutdown(0);
84
+ });
85
+ process.stdin.on("close", () => {
86
+ shutdown(0);
87
+ });
88
+ process.on("SIGINT", () => {
89
+ shutdown(0);
90
+ });
91
+ process.on("SIGTERM", () => {
92
+ shutdown(0);
93
+ });
94
+ }
95
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The analytics database's tables. CREATE ... IF NOT EXISTS, then ALTERs
3
+ * for columns added after the first release, so an old file upgrades in place.
4
+ */
5
+ function addColumnIfMissing(db, table, column, type) {
6
+ const cols = db.prepare(`PRAGMA table_info(${table})`).all();
7
+ if (!cols.some((c) => c.name === column)) {
8
+ db.exec(`ALTER TABLE ${table} ADD COLUMN ${column} ${type}`);
9
+ }
10
+ }
11
+ export function initSchema(db) {
12
+ db.exec(`
13
+ CREATE TABLE IF NOT EXISTS query_log (
14
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
15
+ tool TEXT NOT NULL,
16
+ query TEXT NOT NULL,
17
+ result_count INTEGER NOT NULL,
18
+ timestamp TEXT DEFAULT (datetime('now'))
19
+ );
20
+
21
+ CREATE TABLE IF NOT EXISTS gaps (
22
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
23
+ query TEXT NOT NULL,
24
+ tool TEXT NOT NULL,
25
+ hit_count INTEGER DEFAULT 1,
26
+ first_seen TEXT DEFAULT (datetime('now')),
27
+ last_seen TEXT DEFAULT (datetime('now')),
28
+ resolved INTEGER DEFAULT 0,
29
+ resolved_at TEXT
30
+ );
31
+
32
+ CREATE INDEX IF NOT EXISTS idx_gaps_query ON gaps(query);
33
+ CREATE INDEX IF NOT EXISTS idx_gaps_resolved ON gaps(resolved);
34
+ CREATE INDEX IF NOT EXISTS idx_query_log_tool ON query_log(tool);
35
+
36
+ CREATE TABLE IF NOT EXISTS hydration_log (
37
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
38
+ tool TEXT NOT NULL,
39
+ doc_path TEXT,
40
+ title TEXT,
41
+ timestamp TEXT DEFAULT (datetime('now'))
42
+ );
43
+
44
+ CREATE TABLE IF NOT EXISTS episodes (
45
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
46
+ started_at TEXT,
47
+ ended_at TEXT,
48
+ query_log_ids TEXT,
49
+ resolution TEXT DEFAULT 'open',
50
+ resolution_summary TEXT
51
+ );
52
+
53
+ CREATE TABLE IF NOT EXISTS learning_candidates (
54
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
55
+ type TEXT NOT NULL,
56
+ title TEXT NOT NULL,
57
+ body TEXT NOT NULL,
58
+ evidence TEXT,
59
+ confidence TEXT,
60
+ status TEXT DEFAULT 'proposed',
61
+ source_episodes TEXT,
62
+ created_at TEXT DEFAULT (datetime('now')),
63
+ promoted_at TEXT,
64
+ related_apis TEXT,
65
+ promote_manifest TEXT
66
+ );
67
+ `);
68
+ // Upgrade existing query_log with new columns (safe if already present)
69
+ addColumnIfMissing(db, "query_log", "result_scores", "TEXT");
70
+ addColumnIfMissing(db, "query_log", "search_mode", "TEXT");
71
+ addColumnIfMissing(db, "query_log", "result_sources", "TEXT");
72
+ // Upgrade existing gaps with pending_verify column
73
+ addColumnIfMissing(db, "gaps", "pending_verify", "INTEGER DEFAULT 0");
74
+ // Upgrade existing gaps with user_reported + notes columns (P7a-1)
75
+ addColumnIfMissing(db, "gaps", "user_reported", "INTEGER DEFAULT 0");
76
+ addColumnIfMissing(db, "gaps", "notes", "TEXT");
77
+ }
78
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/services/analytics/schema.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,SAAS,kBAAkB,CAAC,EAAqB,EAAE,KAAa,EAAE,MAAc,EAAE,IAAY;IAC5F,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,CAAuB,qBAAqB,KAAK,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;IACnF,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,CAAC;QACzC,EAAE,CAAC,IAAI,CAAC,eAAe,KAAK,eAAe,MAAM,IAAI,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,EAAqB;IAC9C,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDP,CAAC,CAAC;IAEH,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;IAC7D,kBAAkB,CAAC,EAAE,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC;IAC3D,kBAAkB,CAAC,EAAE,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAE9D,mDAAmD;IACnD,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,gBAAgB,EAAE,mBAAmB,CAAC,CAAC;IAEtE,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,eAAe,EAAE,mBAAmB,CAAC,CAAC;IACrE,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAClD,CAAC"}