c64bridge 0.8.1 → 0.9.1

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 (92) hide show
  1. package/.github/prompts/steer.prompt.md +55 -0
  2. package/AGENTS.md +9 -7
  3. package/README.md +192 -154
  4. package/data/embeddings_asm.json +1 -1
  5. package/data/embeddings_basic.json +1 -1
  6. package/data/embeddings_hardware.json +1 -1
  7. package/data/embeddings_mixed.json +1 -1
  8. package/data/embeddings_other.json +1 -1
  9. package/data/graphics/petscii-style-guide.md +4 -4
  10. package/data/graphics/sprite-charset-best-practices.md +9 -9
  11. package/data/vice/vice-binary-monitor-spec.md +938 -0
  12. package/dist/.tsbuildinfo +1 -1
  13. package/dist/c64Client.js +76 -2
  14. package/dist/device.js +129 -13
  15. package/dist/mcp-server.js +1 -1
  16. package/dist/prompts/registry.js +27 -25
  17. package/dist/rag/indexer.js +18 -8
  18. package/dist/rag/knowledgeIndex.js +112 -79
  19. package/dist/rag/resourceUris.js +93 -0
  20. package/dist/sidwaveCompiler.js +1 -1
  21. package/dist/{assemblyConverter.js → tools/assember.js} +10 -1
  22. package/dist/tools/audio.js +11 -11
  23. package/dist/{basicConverter.js → tools/basicTokenizer.js} +1 -1
  24. package/dist/tools/debug.js +159 -6
  25. package/dist/tools/developer.js +13 -13
  26. package/dist/tools/disassembler.js +478 -0
  27. package/dist/tools/graphics.js +10 -10
  28. package/dist/tools/input.js +338 -0
  29. package/dist/tools/machineControl.js +5 -5
  30. package/dist/tools/memory.js +336 -12
  31. package/dist/tools/meta/index.js +1 -1
  32. package/dist/tools/printer.js +11 -12
  33. package/dist/tools/programRunners.js +61 -22
  34. package/dist/tools/rag.js +9 -9
  35. package/dist/tools/registry/batch.js +167 -0
  36. package/dist/tools/registry/config.js +1 -1
  37. package/dist/tools/registry/disk.js +1 -1
  38. package/dist/tools/registry/drive.js +1 -1
  39. package/dist/tools/registry/extract.js +1 -1
  40. package/dist/tools/registry/graphics.js +102 -2
  41. package/dist/tools/registry/index.js +4 -0
  42. package/dist/tools/registry/input.js +2 -0
  43. package/dist/tools/registry/memory.js +62 -2
  44. package/dist/tools/registry/platform.js +1 -1
  45. package/dist/tools/registry/printer.js +1 -1
  46. package/dist/tools/registry/program.js +1 -1
  47. package/dist/tools/registry/rag.js +1 -1
  48. package/dist/tools/registry/sound.js +1 -1
  49. package/dist/tools/registry/stream.js +1 -1
  50. package/dist/tools/registry/system.js +1 -1
  51. package/dist/tools/schema.js +4 -5
  52. package/dist/tools/storage.js +15 -15
  53. package/dist/tools/streaming.js +3 -3
  54. package/dist/tools/symbolRegistry.js +49 -0
  55. package/dist/tools/types.js +56 -4
  56. package/dist/tools/vice.js +2 -5
  57. package/dist/vice/process.js +120 -2
  58. package/dist/vice/readiness.js +35 -0
  59. package/dist/vice/smokeOptions.js +44 -0
  60. package/dist/vice/viceClient.js +5 -1
  61. package/dist/viceRunner.js +2 -0
  62. package/doc/plans/prompts/README.md +7 -7
  63. package/mcp/prompts.json +42 -59
  64. package/mcp/protocol-examples.json +2 -2
  65. package/mcp/resources.json +179 -166
  66. package/mcp/schemas/c64_batch.schema.json +53 -0
  67. package/mcp/schemas/c64_config.schema.json +525 -283
  68. package/mcp/schemas/c64_debug.schema.json +763 -304
  69. package/mcp/schemas/c64_disk.schema.json +499 -243
  70. package/mcp/schemas/c64_drive.schema.json +165 -90
  71. package/mcp/schemas/c64_extract.schema.json +533 -274
  72. package/mcp/schemas/c64_graphics.schema.json +607 -295
  73. package/mcp/schemas/c64_input.schema.json +136 -0
  74. package/mcp/schemas/c64_memory.schema.json +637 -128
  75. package/mcp/schemas/c64_printer.schema.json +393 -196
  76. package/mcp/schemas/c64_program.schema.json +699 -340
  77. package/mcp/schemas/c64_rag.schema.json +100 -54
  78. package/mcp/schemas/c64_select_backend.schema.json +49 -23
  79. package/mcp/schemas/c64_sound.schema.json +1092 -577
  80. package/mcp/schemas/c64_stream.schema.json +89 -47
  81. package/mcp/schemas/c64_system.schema.json +351 -185
  82. package/mcp/schemas/c64_vice.schema.json +85 -47
  83. package/mcp/server.json +1 -1
  84. package/mcp/tools.json +7299 -3346
  85. package/mcp.json +3 -3
  86. package/package.json +17 -14
  87. package/scripts/fetch-external-sources.mjs +1 -2
  88. package/scripts/run-coverage.mjs +33 -1
  89. package/scripts/run-tests.mjs +2 -2
  90. package/scripts/run-tests.ts +275 -52
  91. package/scripts/update-readme.ts +132 -3
  92. package/server.json +2 -2
@@ -1,5 +1,6 @@
1
1
  import { readFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
+ import { CANONICAL_KNOWLEDGE_RESOURCE_URIS, PLATFORM_RESOURCE_URI, RESOURCE_URIS } from "./resourceUris.js";
3
4
  function generateCharsetQuickref() {
4
5
  const csvPath = join(process.cwd(), "data/graphics/character-set.csv");
5
6
  const csvContent = readFileSync(csvPath, "utf-8");
@@ -34,14 +35,14 @@ function generateCharsetQuickref() {
34
35
  }
35
36
  const KNOWLEDGE_BUNDLES = [
36
37
  {
37
- id: "orientation",
38
- title: "Workflow & Orientation",
38
+ id: "guide",
39
+ title: "Guides & Orientation",
39
40
  summary: "Mandatory workflow and safety guidance before issuing any C64 commands.",
40
41
  prompts: ["basic-program", "assembly-program", "memory-debug", "cross-platform-demo", "preset-music-demo"],
41
42
  tools: ["upload_run_basic", "upload_run_asm", "cross_platform_greeting", "music_play_preset", "read_screen", "read"],
42
43
  resources: [
43
44
  {
44
- uri: "c64://context/bootstrap",
45
+ uri: RESOURCE_URIS.guide.bootstrap,
45
46
  name: "Workflow Rules & Best Practices",
46
47
  description: "CRITICAL: Mandatory workflow rules for all C64 programming",
47
48
  relativePath: "data/context/bootstrap.md",
@@ -52,7 +53,7 @@ const KNOWLEDGE_BUNDLES = [
52
53
  tags: ["workflow", "safety"],
53
54
  },
54
55
  {
55
- uri: "c64://context/fast-paths",
56
+ uri: RESOURCE_URIS.guide.fastPaths,
56
57
  name: "Fast Path Workflows",
57
58
  description: "Shortest reliable workflows for common C64U and VICE tasks, including dual-backend demos.",
58
59
  relativePath: "data/context/fast-paths.md",
@@ -60,11 +61,56 @@ const KNOWLEDGE_BUNDLES = [
60
61
  summary: "Condensed routing guide for one-call demos, backend switching, and when to prefer orchestration over manual tool composition.",
61
62
  prompts: ["basic-program", "graphics-demo", "cross-platform-demo", "sid-music", "preset-music-demo"],
62
63
  tools: ["c64_program", "c64_sound", "c64_select_backend", "c64_memory", "c64_graphics"],
63
- relatedResources: ["c64://context/bootstrap", "c64://platform/status"],
64
+ relatedResources: [RESOURCE_URIS.guide.bootstrap, PLATFORM_RESOURCE_URI],
64
65
  tags: ["workflow", "fast-path", "routing"],
65
66
  },
66
67
  ],
67
68
  },
69
+ {
70
+ id: "vice",
71
+ title: "VICE Emulator",
72
+ summary: "Critical Binary Monitor protocol guidance for any workflow that targets the VICE backend.",
73
+ prompts: [
74
+ "hello-world",
75
+ "basic-program",
76
+ "cross-platform-demo",
77
+ "preset-music-demo",
78
+ "assembly-program",
79
+ "sid-music",
80
+ "graphics-demo",
81
+ "memory-debug",
82
+ "drive-manager",
83
+ ],
84
+ tools: ["c64_program", "c64_memory", "c64_debug", "c64_vice", "c64_system"],
85
+ resources: [
86
+ {
87
+ uri: RESOURCE_URIS.vice.binaryMonitorSpec,
88
+ name: "VICE Binary Monitor Specification",
89
+ description: "Critical VICE Binary Monitor reference for emulator-backed workflows and debugger operations.",
90
+ relativePath: "data/vice/vice-binary-monitor-spec.md",
91
+ priority: "critical",
92
+ summary: "Transport framing, single-client constraints, command semantics, and monitor side effects that shape all VICE-backed operations.",
93
+ prompts: [
94
+ "hello-world",
95
+ "basic-program",
96
+ "cross-platform-demo",
97
+ "preset-music-demo",
98
+ "assembly-program",
99
+ "sid-music",
100
+ "graphics-demo",
101
+ "memory-debug",
102
+ "drive-manager",
103
+ ],
104
+ tools: ["c64_program", "c64_memory", "c64_debug", "c64_vice", "c64_system"],
105
+ relatedResources: [
106
+ RESOURCE_URIS.guide.bootstrap,
107
+ RESOURCE_URIS.guide.fastPaths,
108
+ PLATFORM_RESOURCE_URI,
109
+ ],
110
+ tags: ["vice", "binary-monitor", "emulator", "debugger"],
111
+ },
112
+ ],
113
+ },
68
114
  {
69
115
  id: "languages",
70
116
  title: "Programming Languages",
@@ -73,7 +119,7 @@ const KNOWLEDGE_BUNDLES = [
73
119
  tools: ["upload_run_basic", "upload_run_asm", "read_screen", "read"],
74
120
  resources: [
75
121
  {
76
- uri: "c64://specs/basic",
122
+ uri: RESOURCE_URIS.basic.spec,
77
123
  name: "Commodore BASIC v2 Specification",
78
124
  description: "Complete BASIC v2 reference. READ THIS BEFORE generating any BASIC code!",
79
125
  relativePath: "data/basic/basic-spec.md",
@@ -81,11 +127,11 @@ const KNOWLEDGE_BUNDLES = [
81
127
  summary: "Token definitions, syntax rules, and device I/O guidance for BASIC v2.",
82
128
  prompts: ["basic-program"],
83
129
  tools: ["upload_run_basic", "read_screen"],
84
- relatedResources: ["c64://context/bootstrap", "c64://docs/basic/pitfalls"],
130
+ relatedResources: [RESOURCE_URIS.guide.bootstrap, RESOURCE_URIS.basic.pitfalls],
85
131
  tags: ["basic", "language"],
86
132
  },
87
133
  {
88
- uri: "c64://docs/basic/pitfalls",
134
+ uri: RESOURCE_URIS.basic.pitfalls,
89
135
  name: "BASIC Pitfalls & Gotchas",
90
136
  description: "Common mistakes and gotchas when writing Commodore BASIC v2 programs",
91
137
  relativePath: "data/basic/basic-pitfalls.md",
@@ -93,11 +139,11 @@ const KNOWLEDGE_BUNDLES = [
93
139
  summary: "Quickref covering quotation handling, line length, tokenization, variable names, and other BASIC traps.",
94
140
  prompts: ["basic-program"],
95
141
  tools: ["upload_run_basic"],
96
- relatedResources: ["c64://specs/basic"],
142
+ relatedResources: [RESOURCE_URIS.basic.spec],
97
143
  tags: ["basic", "pitfalls", "quickref"],
98
144
  },
99
145
  {
100
- uri: "c64://specs/assembly",
146
+ uri: RESOURCE_URIS.assembly.spec6510,
101
147
  name: "6502/6510 Assembly Reference",
102
148
  description: "Full instruction set and addressing modes. READ THIS BEFORE generating assembly!",
103
149
  relativePath: "data/assembly/assembly-spec.md",
@@ -105,7 +151,7 @@ const KNOWLEDGE_BUNDLES = [
105
151
  summary: "Official opcode matrix, addressing modes, and zero-page strategy for the 6510 CPU.",
106
152
  prompts: ["assembly-program"],
107
153
  tools: ["upload_run_asm", "read"],
108
- relatedResources: ["c64://context/bootstrap"],
154
+ relatedResources: [RESOURCE_URIS.guide.bootstrap],
109
155
  tags: ["assembly", "language"],
110
156
  },
111
157
  ],
@@ -118,7 +164,7 @@ const KNOWLEDGE_BUNDLES = [
118
164
  tools: ["c64_sound"],
119
165
  resources: [
120
166
  {
121
- uri: "c64://specs/sid",
167
+ uri: RESOURCE_URIS.sound.sid.spec,
122
168
  name: "SID Chip Programming Guide",
123
169
  description: "Sound Interface Device registers and music programming",
124
170
  relativePath: "data/sound/sid-spec.md",
@@ -126,11 +172,11 @@ const KNOWLEDGE_BUNDLES = [
126
172
  summary: "Register map, waveform behaviour, and ADSR envelopes for expressive SID playback.",
127
173
  prompts: ["sid-music"],
128
174
  tools: ["c64_sound"],
129
- relatedResources: ["c64://specs/sidwave", "c64://docs/sid/file-structure"],
175
+ relatedResources: [RESOURCE_URIS.sound.sidwave.spec, RESOURCE_URIS.sound.sid.fileFormat],
130
176
  tags: ["sid", "audio"],
131
177
  },
132
178
  {
133
- uri: "c64://specs/sidwave",
179
+ uri: RESOURCE_URIS.sound.sidwave.spec,
134
180
  name: "SIDWAVE Music Format Specification",
135
181
  description: "YAML/JSON music composition format for SID chip",
136
182
  relativePath: "data/sound/sidwave.md",
@@ -138,11 +184,11 @@ const KNOWLEDGE_BUNDLES = [
138
184
  summary: "Defines the SIDWAVE interchange format used by the SID composer workflow.",
139
185
  prompts: ["sid-music"],
140
186
  tools: ["c64_sound"],
141
- relatedResources: ["c64://specs/sid", "c64://docs/sid/file-structure"],
187
+ relatedResources: [RESOURCE_URIS.sound.sid.spec, RESOURCE_URIS.sound.sid.fileFormat],
142
188
  tags: ["sid", "format"],
143
189
  },
144
190
  {
145
- uri: "c64://docs/sid/file-structure",
191
+ uri: RESOURCE_URIS.sound.sid.fileFormat,
146
192
  name: "SID File Structure Reference",
147
193
  description: "Breakdown of the SID file format layout and metadata",
148
194
  relativePath: "data/sound/sid-file-structure.md",
@@ -150,11 +196,11 @@ const KNOWLEDGE_BUNDLES = [
150
196
  summary: "Explains PSID/RSID headers, metadata blocks, and compatibility notes for imported music.",
151
197
  prompts: ["sid-music"],
152
198
  tools: ["c64_sound"],
153
- relatedResources: ["c64://specs/sid", "c64://specs/sidwave"],
199
+ relatedResources: [RESOURCE_URIS.sound.sid.spec, RESOURCE_URIS.sound.sidwave.spec],
154
200
  tags: ["sid", "format"],
155
201
  },
156
202
  {
157
- uri: "c64://docs/sid/best-practices",
203
+ uri: RESOURCE_URIS.sound.sid.bestPractices,
158
204
  name: "SID Programming Best Practices",
159
205
  description: "Expressive SID composition defaults, ADSR guidance, and musical phrasing tips.",
160
206
  relativePath: "data/sound/sid-programming-best-practices.md",
@@ -162,7 +208,7 @@ const KNOWLEDGE_BUNDLES = [
162
208
  summary: "Captures proven waveforms, ADSR presets, phrasing, and verification workflow for pleasant SID music.",
163
209
  prompts: ["sid-music"],
164
210
  tools: ["c64_sound"],
165
- relatedResources: ["c64://specs/sid", "c64://specs/sidwave"],
211
+ relatedResources: [RESOURCE_URIS.sound.sid.spec, RESOURCE_URIS.sound.sidwave.spec],
166
212
  tags: ["sid", "best-practices", "audio"],
167
213
  },
168
214
  ],
@@ -175,7 +221,7 @@ const KNOWLEDGE_BUNDLES = [
175
221
  tools: ["c64_graphics", "c64_memory"],
176
222
  resources: [
177
223
  {
178
- uri: "c64://specs/vic",
224
+ uri: RESOURCE_URIS.graphics.vic.spec,
179
225
  name: "VIC-II Graphics Specification",
180
226
  description: "Video chip, sprites, raster programming, and timing",
181
227
  relativePath: "data/graphics/vic-spec.md",
@@ -183,11 +229,11 @@ const KNOWLEDGE_BUNDLES = [
183
229
  summary: "Covers raster timing, sprite control, colour RAM, and bitmap modes on the VIC-II.",
184
230
  prompts: ["graphics-demo"],
185
231
  tools: ["c64_graphics", "c64_memory"],
186
- relatedResources: ["c64://specs/assembly", "c64://specs/charset", "c64://docs/petscii-style"],
232
+ relatedResources: [RESOURCE_URIS.assembly.spec6510, RESOURCE_URIS.graphics.characterSet, RESOURCE_URIS.graphics.petscii.styleGuide],
187
233
  tags: ["vic", "graphics"],
188
234
  },
189
235
  {
190
- uri: "c64://specs/charset",
236
+ uri: RESOURCE_URIS.graphics.characterSet,
191
237
  name: "PETSCII Character Set Reference",
192
238
  description: "Complete PETSCII character codes, screen codes, and glyph mappings",
193
239
  relativePath: "data/graphics/character-set.csv",
@@ -195,11 +241,11 @@ const KNOWLEDGE_BUNDLES = [
195
241
  summary: "Character code table mapping PETSCII codes to screen codes, glyphs, and keyboard input.",
196
242
  prompts: ["graphics-demo"],
197
243
  tools: ["c64_graphics"],
198
- relatedResources: ["c64://specs/vic", "c64://docs/petscii-style"],
244
+ relatedResources: [RESOURCE_URIS.graphics.vic.spec, RESOURCE_URIS.graphics.petscii.styleGuide],
199
245
  tags: ["petscii", "charset", "graphics"],
200
246
  },
201
247
  {
202
- uri: "c64://docs/petscii-style",
248
+ uri: RESOURCE_URIS.graphics.petscii.styleGuide,
203
249
  name: "PETSCII Style Guide and Presets",
204
250
  description: "Colour combinations, contrast guidelines, and recommended presets for PETSCII art",
205
251
  relativePath: "data/graphics/petscii-style-guide.md",
@@ -207,11 +253,11 @@ const KNOWLEDGE_BUNDLES = [
207
253
  summary: "Documents colour palette, readability presets, dithering patterns, and best practices for creating artistic and readable PETSCII displays.",
208
254
  prompts: ["graphics-demo"],
209
255
  tools: ["c64_graphics"],
210
- relatedResources: ["c64://specs/vic", "c64://specs/charset", "c64://docs/sprite-charset-workflows"],
256
+ relatedResources: [RESOURCE_URIS.graphics.vic.spec, RESOURCE_URIS.graphics.characterSet, RESOURCE_URIS.graphics.spriteCharset.bestPractices],
211
257
  tags: ["petscii", "style", "colours", "graphics"],
212
258
  },
213
259
  {
214
- uri: "c64://docs/sprite-charset-workflows",
260
+ uri: RESOURCE_URIS.graphics.spriteCharset.bestPractices,
215
261
  name: "Sprite & Charset Workflows Best Practices",
216
262
  description: "Comprehensive guide to creating, managing, and deploying sprites and custom character sets",
217
263
  relativePath: "data/graphics/sprite-charset-best-practices.md",
@@ -219,7 +265,7 @@ const KNOWLEDGE_BUNDLES = [
219
265
  summary: "Documents sprite and charset workflows, memory layout, VIC-II configuration, common pitfalls, and proven techniques for hardware-accelerated graphics.",
220
266
  prompts: ["graphics-demo"],
221
267
  tools: ["c64_graphics", "c64_memory", "c64_program"],
222
- relatedResources: ["c64://specs/vic", "c64://specs/charset", "c64://docs/petscii-style", "c64://specs/memory-map"],
268
+ relatedResources: [RESOURCE_URIS.graphics.vic.spec, RESOURCE_URIS.graphics.characterSet, RESOURCE_URIS.graphics.petscii.styleGuide, RESOURCE_URIS.memory.map],
223
269
  tags: ["sprites", "charset", "graphics", "workflows"],
224
270
  },
225
271
  ],
@@ -232,7 +278,7 @@ const KNOWLEDGE_BUNDLES = [
232
278
  tools: ["read", "write", "verify_and_write_memory", "debugreg_read", "debugreg_write"],
233
279
  resources: [
234
280
  {
235
- uri: "c64://specs/memory-map",
281
+ uri: RESOURCE_URIS.memory.map,
236
282
  name: "C64 Memory Map",
237
283
  description: "Complete RAM, ROM, and I/O address map for the Commodore 64.",
238
284
  relativePath: "data/memory/memory-map.md",
@@ -240,11 +286,11 @@ const KNOWLEDGE_BUNDLES = [
240
286
  summary: "Page-by-page breakdown of the 64 KB address space with hardware, ROM, and RAM regions.",
241
287
  prompts: ["memory-debug", "assembly-program"],
242
288
  tools: ["read", "write", "verify_and_write_memory"],
243
- relatedResources: ["c64://specs/assembly"],
289
+ relatedResources: [RESOURCE_URIS.assembly.spec6510],
244
290
  tags: ["memory", "hardware"],
245
291
  },
246
292
  {
247
- uri: "c64://specs/memory-low",
293
+ uri: RESOURCE_URIS.memory.zeroPageAndWorkspace,
248
294
  name: "Low Memory Usage Guide",
249
295
  description: "Zero-page and system vector reference for low-memory addresses.",
250
296
  relativePath: "data/memory/low-memory-map.md",
@@ -252,11 +298,11 @@ const KNOWLEDGE_BUNDLES = [
252
298
  summary: "Documents zero-page variables, BASIC pointers, and KERNAL workspace addresses.",
253
299
  prompts: ["memory-debug", "assembly-program"],
254
300
  tools: ["read", "write", "verify_and_write_memory"],
255
- relatedResources: ["c64://specs/memory-map", "c64://specs/assembly"],
301
+ relatedResources: [RESOURCE_URIS.memory.map, RESOURCE_URIS.assembly.spec6510],
256
302
  tags: ["memory", "zero-page"],
257
303
  },
258
304
  {
259
- uri: "c64://specs/memory-kernal",
305
+ uri: RESOURCE_URIS.kernal.romRoutines,
260
306
  name: "KERNAL Memory Map",
261
307
  description: "Detailed breakdown of KERNAL ROM routines and entry points.",
262
308
  relativePath: "data/memory/kernal-memory-map.md",
@@ -264,11 +310,11 @@ const KNOWLEDGE_BUNDLES = [
264
310
  summary: "Lists KERNAL ROM vectors and service routines for OS-level functionality.",
265
311
  prompts: ["memory-debug", "assembly-program"],
266
312
  tools: ["read", "verify_and_write_memory"],
267
- relatedResources: ["c64://specs/memory-map", "c64://specs/assembly"],
313
+ relatedResources: [RESOURCE_URIS.memory.map, RESOURCE_URIS.assembly.spec6510],
268
314
  tags: ["memory", "kernal"],
269
315
  },
270
316
  {
271
- uri: "c64://specs/io",
317
+ uri: RESOURCE_URIS.io.spec,
272
318
  name: "C64 I/O Register Map",
273
319
  description: "Comprehensive table of memory-mapped hardware registers.",
274
320
  relativePath: "data/io/io-spec.md",
@@ -276,11 +322,11 @@ const KNOWLEDGE_BUNDLES = [
276
322
  summary: "Covers VIC-II, SID, CIA, and system control registers with address ranges and usage notes.",
277
323
  prompts: ["memory-debug", "assembly-program"],
278
324
  tools: ["read", "write", "verify_and_write_memory", "debugreg_read", "debugreg_write"],
279
- relatedResources: ["c64://specs/memory-map", "c64://specs/assembly"],
325
+ relatedResources: [RESOURCE_URIS.memory.map, RESOURCE_URIS.assembly.spec6510],
280
326
  tags: ["io", "hardware"],
281
327
  },
282
328
  {
283
- uri: "c64://specs/cia",
329
+ uri: RESOURCE_URIS.io.cia.spec,
284
330
  name: "CIA Register Reference",
285
331
  description: "Timer, keyboard, and peripheral register reference for CIA chips.",
286
332
  relativePath: "data/io/cia-spec.md",
@@ -288,7 +334,7 @@ const KNOWLEDGE_BUNDLES = [
288
334
  summary: "Details CIA 1/2 registers, timers, interrupts, and keyboard matrix layout.",
289
335
  prompts: ["memory-debug", "assembly-program"],
290
336
  tools: ["read", "write", "verify_and_write_memory", "debugreg_read"],
291
- relatedResources: ["c64://specs/io", "c64://specs/memory-map"],
337
+ relatedResources: [RESOURCE_URIS.io.spec, RESOURCE_URIS.memory.map],
292
338
  tags: ["io", "hardware"],
293
339
  },
294
340
  ],
@@ -308,7 +354,7 @@ const KNOWLEDGE_BUNDLES = [
308
354
  ],
309
355
  resources: [
310
356
  {
311
- uri: "c64://specs/printer",
357
+ uri: RESOURCE_URIS.printer.spec,
312
358
  name: "Printer Programming Guide",
313
359
  description: "Commodore MPS and Epson FX printer control",
314
360
  relativePath: "data/printer/printer-spec.md",
@@ -317,30 +363,13 @@ const KNOWLEDGE_BUNDLES = [
317
363
  prompts: ["printer-job"],
318
364
  tools: ["printer_guide", "printer_commodore_text", "printer_epson_text"],
319
365
  relatedResources: [
320
- "c64://docs/printer/guide",
321
- "c64://docs/printer/commodore-text",
322
- "c64://docs/printer/epson-text",
366
+ RESOURCE_URIS.printer.commodore.text,
367
+ RESOURCE_URIS.printer.epson.text,
323
368
  ],
324
369
  tags: ["printer", "spec"],
325
370
  },
326
371
  {
327
- uri: "c64://docs/printer/guide",
328
- name: "Printer Workflow Guide",
329
- description: "Unified quick reference for Commodore and Epson printers",
330
- relativePath: "data/printer/printer-spec.md",
331
- priority: "reference",
332
- summary: "Quick-look workflow covering setup, troubleshooting, and sample jobs for both printer families.",
333
- prompts: ["printer-job"],
334
- tools: ["printer_guide"],
335
- relatedResources: [
336
- "c64://specs/printer",
337
- "c64://docs/printer/commodore-text",
338
- "c64://docs/printer/epson-text",
339
- ],
340
- tags: ["printer", "workflow"],
341
- },
342
- {
343
- uri: "c64://docs/printer/commodore-text",
372
+ uri: RESOURCE_URIS.printer.commodore.text,
344
373
  name: "Commodore Printer Text Guide",
345
374
  description: "Device 4 character printing reference for Commodore MPS printers",
346
375
  relativePath: "data/printer/printer-commodore.md",
@@ -349,13 +378,13 @@ const KNOWLEDGE_BUNDLES = [
349
378
  prompts: ["printer-job"],
350
379
  tools: ["printer_commodore_text"],
351
380
  relatedResources: [
352
- "c64://specs/printer",
353
- "c64://docs/printer/commodore-bitmap",
381
+ RESOURCE_URIS.printer.spec,
382
+ RESOURCE_URIS.printer.commodore.bitmap,
354
383
  ],
355
384
  tags: ["printer", "commodore"],
356
385
  },
357
386
  {
358
- uri: "c64://docs/printer/commodore-bitmap",
387
+ uri: RESOURCE_URIS.printer.commodore.bitmap,
359
388
  name: "Commodore Printer Bitmap Guide",
360
389
  description: "Bitmap and custom character printing workflow for Commodore printers",
361
390
  relativePath: "data/printer/printer-commodore-bitmap.md",
@@ -364,13 +393,13 @@ const KNOWLEDGE_BUNDLES = [
364
393
  prompts: ["printer-job"],
365
394
  tools: ["printer_commodore_bitmap"],
366
395
  relatedResources: [
367
- "c64://docs/printer/commodore-text",
368
- "c64://specs/printer",
396
+ RESOURCE_URIS.printer.commodore.text,
397
+ RESOURCE_URIS.printer.spec,
369
398
  ],
370
399
  tags: ["printer", "commodore", "graphics"],
371
400
  },
372
401
  {
373
- uri: "c64://docs/printer/epson-text",
402
+ uri: RESOURCE_URIS.printer.epson.text,
374
403
  name: "Epson Printer Text Guide",
375
404
  description: "Text control sequences for Epson FX-compatible printers",
376
405
  relativePath: "data/printer/printer-epson.md",
@@ -379,13 +408,13 @@ const KNOWLEDGE_BUNDLES = [
379
408
  prompts: ["printer-job"],
380
409
  tools: ["printer_epson_text"],
381
410
  relatedResources: [
382
- "c64://docs/printer/epson-bitmap",
383
- "c64://specs/printer",
411
+ RESOURCE_URIS.printer.epson.bitmap,
412
+ RESOURCE_URIS.printer.spec,
384
413
  ],
385
414
  tags: ["printer", "epson"],
386
415
  },
387
416
  {
388
- uri: "c64://docs/printer/epson-bitmap",
417
+ uri: RESOURCE_URIS.printer.epson.bitmap,
389
418
  name: "Epson Printer Bitmap Guide",
390
419
  description: "Bitmap printing and graphics control for Epson FX printers",
391
420
  relativePath: "data/printer/printer-epson-bitmap.md",
@@ -394,13 +423,13 @@ const KNOWLEDGE_BUNDLES = [
394
423
  prompts: ["printer-job"],
395
424
  tools: ["printer_epson_bitmap"],
396
425
  relatedResources: [
397
- "c64://docs/printer/epson-text",
398
- "c64://specs/printer",
426
+ RESOURCE_URIS.printer.epson.text,
427
+ RESOURCE_URIS.printer.spec,
399
428
  ],
400
429
  tags: ["printer", "epson", "graphics"],
401
430
  },
402
431
  {
403
- uri: "c64://docs/printer/prompts",
432
+ uri: RESOURCE_URIS.printer.promptGuide,
404
433
  name: "Printer Prompt Templates",
405
434
  description: "Template prompts and workflow guidance for printer jobs",
406
435
  relativePath: "data/printer/printer-prompts.md",
@@ -409,16 +438,20 @@ const KNOWLEDGE_BUNDLES = [
409
438
  prompts: ["printer-job"],
410
439
  tools: ["printer_prompts"],
411
440
  relatedResources: [
412
- "c64://docs/printer/guide",
413
- "c64://docs/printer/commodore-text",
414
- "c64://docs/printer/epson-text",
441
+ RESOURCE_URIS.printer.spec,
442
+ RESOURCE_URIS.printer.commodore.text,
443
+ RESOURCE_URIS.printer.epson.text,
415
444
  ],
416
445
  tags: ["printer", "prompts"],
417
446
  },
418
447
  ],
419
448
  },
420
449
  ];
450
+ const CANONICAL_KNOWLEDGE_RESOURCE_URI_SET = new Set(CANONICAL_KNOWLEDGE_RESOURCE_URIS);
421
451
  const BASE_RESOURCES = KNOWLEDGE_BUNDLES.flatMap((bundle, bundleIndex) => bundle.resources.map((resource, resourceIndex) => {
452
+ if (!CANONICAL_KNOWLEDGE_RESOURCE_URI_SET.has(resource.uri)) {
453
+ throw new Error(`Knowledge resource URI ${resource.uri} is not part of the canonical resource set`);
454
+ }
422
455
  const baseResource = {
423
456
  uri: resource.uri,
424
457
  name: resource.name,
@@ -443,18 +476,18 @@ const BASE_RESOURCES = KNOWLEDGE_BUNDLES.flatMap((bundle, bundleIndex) => bundle
443
476
  },
444
477
  };
445
478
  // Add buildContent for resources that need dynamic generation
446
- if (resource.uri === "c64://specs/charset") {
479
+ if (resource.uri === RESOURCE_URIS.graphics.characterSet) {
447
480
  return { ...baseResource, buildContent: generateCharsetQuickref };
448
481
  }
449
482
  return baseResource;
450
483
  }));
451
484
  const INDEX_RESOURCE = {
452
- uri: "c64://docs/index",
485
+ uri: RESOURCE_URIS.guide.index,
453
486
  name: "C64 Knowledge Map",
454
487
  description: "Start here for a guided tour of all Commodore 64 knowledge resources",
455
488
  mimeType: "text/markdown",
456
489
  metadata: {
457
- domain: "overview",
490
+ domain: "guide",
458
491
  priority: "critical",
459
492
  summary: "Explains how to approach each knowledge bundle and when to consult it.",
460
493
  prompts: ["basic-program", "assembly-program", "sid-music", "graphics-demo", "printer-job", "memory-debug", "cross-platform-demo", "preset-music-demo"],
@@ -468,7 +501,7 @@ const INDEX_RESOURCE = {
468
501
  ],
469
502
  tags: ["overview"],
470
503
  bundle: {
471
- id: "overview",
504
+ id: "guide",
472
505
  title: "Knowledge Overview",
473
506
  summary: "Read this first to understand how the MCP server organizes Commodore 64 expertise.",
474
507
  order: -1,
@@ -523,7 +556,7 @@ export function readKnowledgeResource(uri, projectRoot) {
523
556
  if (resource.buildContent) {
524
557
  const baseResources = ALL_RESOURCES.filter((item) => item.uri !== resource.uri);
525
558
  return {
526
- uri: resource.uri,
559
+ uri,
527
560
  mimeType: resource.mimeType,
528
561
  text: resource.buildContent(baseResources),
529
562
  };
@@ -534,7 +567,7 @@ export function readKnowledgeResource(uri, projectRoot) {
534
567
  const fullPath = join(projectRoot, resource.relativePath);
535
568
  const text = readFileSync(fullPath, "utf-8");
536
569
  return {
537
- uri: resource.uri,
570
+ uri,
538
571
  mimeType: resource.mimeType,
539
572
  text,
540
573
  };
@@ -0,0 +1,93 @@
1
+ export const RESOURCE_URIS = {
2
+ guide: {
3
+ index: "c64://guide/index",
4
+ bootstrap: "c64://guide/bootstrap",
5
+ fastPaths: "c64://guide/fast-paths",
6
+ },
7
+ vice: {
8
+ binaryMonitorSpec: "c64://vice/binary-monitor-spec",
9
+ },
10
+ basic: {
11
+ spec: "c64://basic/spec",
12
+ pitfalls: "c64://basic/pitfalls",
13
+ },
14
+ assembly: {
15
+ spec6510: "c64://assembly/6510-spec",
16
+ },
17
+ sound: {
18
+ sid: {
19
+ spec: "c64://sound/sid/spec",
20
+ fileFormat: "c64://sound/sid/file-format",
21
+ bestPractices: "c64://sound/sid/best-practices",
22
+ },
23
+ sidwave: {
24
+ spec: "c64://sound/sidwave/spec",
25
+ },
26
+ },
27
+ graphics: {
28
+ vic: {
29
+ spec: "c64://graphics/vic/spec",
30
+ },
31
+ characterSet: "c64://graphics/character-set",
32
+ petscii: {
33
+ styleGuide: "c64://graphics/petscii/style-guide",
34
+ },
35
+ spriteCharset: {
36
+ bestPractices: "c64://graphics/sprite-charset/best-practices",
37
+ },
38
+ },
39
+ memory: {
40
+ map: "c64://memory/map",
41
+ zeroPageAndWorkspace: "c64://memory/zero-page-and-workspace",
42
+ },
43
+ kernal: {
44
+ romRoutines: "c64://kernal/rom-routines",
45
+ },
46
+ io: {
47
+ spec: "c64://io/spec",
48
+ cia: {
49
+ spec: "c64://io/cia/spec",
50
+ },
51
+ },
52
+ printer: {
53
+ spec: "c64://printer/spec",
54
+ commodore: {
55
+ text: "c64://printer/commodore/text",
56
+ bitmap: "c64://printer/commodore/bitmap",
57
+ },
58
+ epson: {
59
+ text: "c64://printer/epson/text",
60
+ bitmap: "c64://printer/epson/bitmap",
61
+ },
62
+ promptGuide: "c64://printer/prompt-guide",
63
+ },
64
+ };
65
+ export const PLATFORM_RESOURCE_URI = "c64://platform/status";
66
+ export const CANONICAL_KNOWLEDGE_RESOURCE_URIS = Object.freeze([
67
+ RESOURCE_URIS.guide.bootstrap,
68
+ RESOURCE_URIS.guide.fastPaths,
69
+ RESOURCE_URIS.vice.binaryMonitorSpec,
70
+ RESOURCE_URIS.basic.spec,
71
+ RESOURCE_URIS.basic.pitfalls,
72
+ RESOURCE_URIS.assembly.spec6510,
73
+ RESOURCE_URIS.sound.sid.spec,
74
+ RESOURCE_URIS.sound.sidwave.spec,
75
+ RESOURCE_URIS.sound.sid.fileFormat,
76
+ RESOURCE_URIS.sound.sid.bestPractices,
77
+ RESOURCE_URIS.graphics.vic.spec,
78
+ RESOURCE_URIS.graphics.characterSet,
79
+ RESOURCE_URIS.graphics.petscii.styleGuide,
80
+ RESOURCE_URIS.graphics.spriteCharset.bestPractices,
81
+ RESOURCE_URIS.memory.map,
82
+ RESOURCE_URIS.memory.zeroPageAndWorkspace,
83
+ RESOURCE_URIS.kernal.romRoutines,
84
+ RESOURCE_URIS.io.spec,
85
+ RESOURCE_URIS.io.cia.spec,
86
+ RESOURCE_URIS.printer.spec,
87
+ RESOURCE_URIS.printer.commodore.text,
88
+ RESOURCE_URIS.printer.commodore.bitmap,
89
+ RESOURCE_URIS.printer.epson.text,
90
+ RESOURCE_URIS.printer.epson.bitmap,
91
+ RESOURCE_URIS.printer.promptGuide,
92
+ RESOURCE_URIS.guide.index,
93
+ ]);
@@ -6,7 +6,7 @@ Licensed under the GNU General Public License v2.0 or later.
6
6
  See <https://www.gnu.org/licenses/> for details.
7
7
  */
8
8
  import { Buffer } from "node:buffer";
9
- import { assemblyToPrg } from "./assemblyConverter.js";
9
+ import { assemblyToPrg } from "./tools/assember.js";
10
10
  import { midiToHz, noteNameToMidi } from "./sidwave.js";
11
11
  /**
12
12
  * Small SIDWAVE to PRG compiler: generates a 50/60Hz player that writes SID registers from a precomputed frame table.
@@ -77,6 +77,9 @@ const DIRECTIVE_ALIASES = {
77
77
  };
78
78
  const RELATIVE_ONLY = new Set(["BCC", "BCS", "BEQ", "BMI", "BNE", "BPL", "BVC", "BVS"]);
79
79
  export function assemblyToPrg(source, options) {
80
+ return assemblyToPrgDetailed(source, options).prg;
81
+ }
82
+ export function assemblyToPrgDetailed(source, options) {
80
83
  const normalized = normalizeSource(source);
81
84
  const loadAddress = options?.loadAddress ?? DEFAULT_LOAD_ADDRESS;
82
85
  const rootFile = options?.fileName ?? "(input)";
@@ -86,7 +89,7 @@ export function assemblyToPrg(source, options) {
86
89
  const assembler = new Assembler(statements, loadAddress);
87
90
  assembler.runPass(0);
88
91
  assembler.runPass(1);
89
- return assembler.buildPrg();
92
+ return { prg: assembler.buildPrg(), symbols: assembler.getSymbols() };
90
93
  }
91
94
  function normalizeSource(input) {
92
95
  return input.replace(/\r\n?/g, "\n");
@@ -608,6 +611,9 @@ class SymbolTable {
608
611
  }
609
612
  return this.globals.get(label);
610
613
  }
614
+ allGlobals() {
615
+ return this.globals;
616
+ }
611
617
  ensureLocalScope(scope) {
612
618
  if (!this.locals.has(scope)) {
613
619
  this.locals.set(scope, new Map());
@@ -658,6 +664,9 @@ class Assembler {
658
664
  header.writeUInt16LE(start, 0);
659
665
  return Buffer.concat([header, Buffer.from(body)]);
660
666
  }
667
+ getSymbols() {
668
+ return this.symbolTable.allGlobals();
669
+ }
661
670
  processLine(line, pass) {
662
671
  for (const label of line.labels) {
663
672
  if (pass === 0) {