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,155 +1,664 @@
1
1
  {
2
2
  "type": "object",
3
- "description": "Memory operations available via the c64_memory tool.",
4
- "oneOf": [
3
+ "properties": {
4
+ "op": {
5
+ "type": "string",
6
+ "enum": [
7
+ "read",
8
+ "write",
9
+ "read_screen",
10
+ "wait_for_text",
11
+ "disassemble",
12
+ "copy_memory",
13
+ "fill_memory",
14
+ "search_memory",
15
+ "compare_memory",
16
+ "save_memory"
17
+ ],
18
+ "description": "Selects the operation."
19
+ },
20
+ "address": {
21
+ "type": "string",
22
+ "description": "Start address expressed as $HHHH, decimal, or a documented symbol name.",
23
+ "minLength": 1
24
+ },
25
+ "length": {
26
+ "type": "integer",
27
+ "description": "Number of bytes to read starting from the resolved address.",
28
+ "minimum": 1,
29
+ "maximum": 4096,
30
+ "default": 256
31
+ },
32
+ "bytes": {
33
+ "type": "string",
34
+ "description": "Hex byte sequence like $AABBCC or AA BB CC to write starting at the resolved address.",
35
+ "minLength": 2,
36
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
37
+ },
38
+ "verify": {
39
+ "type": "boolean",
40
+ "description": "When true, verify the write by reading before and after the change; Ultimate hardware also pauses during verification.",
41
+ "default": false
42
+ },
43
+ "expected": {
44
+ "type": [
45
+ "string",
46
+ "null"
47
+ ],
48
+ "description": "Optional hex data expected before the write (verifies before writing).",
49
+ "minLength": 2,
50
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
51
+ },
52
+ "mask": {
53
+ "type": [
54
+ "string",
55
+ "null"
56
+ ],
57
+ "description": "Optional verification mask (hex); only bits set in the mask are compared.",
58
+ "minLength": 2,
59
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
60
+ },
61
+ "abortOnMismatch": {
62
+ "type": "boolean",
63
+ "description": "Abort the write when the pre-write verification fails.",
64
+ "default": true
65
+ },
66
+ "pattern": {
67
+ "type": "string",
68
+ "description": "Substring or regex to find",
69
+ "minLength": 1
70
+ },
71
+ "isRegex": {
72
+ "type": [
73
+ "boolean",
74
+ "null"
75
+ ],
76
+ "description": "Interpret pattern as regular expression",
77
+ "default": false
78
+ },
79
+ "caseInsensitive": {
80
+ "type": [
81
+ "boolean",
82
+ "null"
83
+ ],
84
+ "description": "Case-insensitive search",
85
+ "default": true
86
+ },
87
+ "timeoutMs": {
88
+ "type": [
89
+ "integer",
90
+ "null"
91
+ ],
92
+ "description": "Overall timeout in milliseconds",
93
+ "minimum": 1,
94
+ "default": 3000
95
+ },
96
+ "intervalMs": {
97
+ "type": [
98
+ "integer",
99
+ "null"
100
+ ],
101
+ "description": "Poll interval in milliseconds",
102
+ "minimum": 1,
103
+ "default": 100
104
+ },
105
+ "instructionCount": {
106
+ "type": [
107
+ "integer",
108
+ "null"
109
+ ],
110
+ "description": "Stop after this many instructions (overrides length as a termination condition).",
111
+ "minimum": 1,
112
+ "maximum": 512
113
+ },
114
+ "source": {
115
+ "type": "string",
116
+ "description": "Source start address ($HHHH, decimal, or symbol).",
117
+ "minLength": 1
118
+ },
119
+ "dest": {
120
+ "type": "string",
121
+ "description": "Destination start address.",
122
+ "minLength": 1
123
+ },
124
+ "startAddress": {
125
+ "type": "string",
126
+ "description": "Start of search range ($HHHH, decimal, or symbol).",
127
+ "minLength": 1
128
+ },
129
+ "endAddress": {
130
+ "type": "string",
131
+ "description": "End of search range (inclusive).",
132
+ "minLength": 1
133
+ },
134
+ "maxResults": {
135
+ "type": [
136
+ "integer",
137
+ "null"
138
+ ],
139
+ "description": "Maximum matches to return (default 10).",
140
+ "minimum": 1,
141
+ "maximum": 100,
142
+ "default": 10
143
+ },
144
+ "address1": {
145
+ "type": "string",
146
+ "description": "First region start address.",
147
+ "minLength": 1
148
+ },
149
+ "address2": {
150
+ "type": "string",
151
+ "description": "Second region start address.",
152
+ "minLength": 1
153
+ },
154
+ "maxDiffs": {
155
+ "type": [
156
+ "integer",
157
+ "null"
158
+ ],
159
+ "description": "Max differences to report (default 10).",
160
+ "minimum": 1,
161
+ "maximum": 200,
162
+ "default": 10
163
+ },
164
+ "filePath": {
165
+ "type": "string",
166
+ "description": "Absolute or relative path for the output file.",
167
+ "minLength": 1
168
+ },
169
+ "asPrg": {
170
+ "type": [
171
+ "boolean",
172
+ "null"
173
+ ],
174
+ "description": "Prepend a 2-byte little-endian load-address header (PRG format). Default: true.",
175
+ "default": true
176
+ }
177
+ },
178
+ "required": [
179
+ "op"
180
+ ],
181
+ "description": "Memory operations available via the c64_memory tool.\n\nOperations:\n- read: Read a range of bytes and return a hex dump with address metadata. Required inputs: address. Optional inputs: length.\n- write: Write a hexadecimal byte sequence into RAM. Required inputs: address, bytes. Optional inputs: verify, expected, mask, abortOnMismatch.\n- read_screen: Return the current 40x25 text screen converted to ASCII. Required inputs: none.\n- wait_for_text: Poll the screen until a substring or regex appears, or timeout elapses. Required inputs: pattern. Optional inputs: isRegex, caseInsensitive, timeoutMs, intervalMs.\n- disassemble: Disassemble a memory region into annotated 6502/6510 instructions, including undocumented opcodes with canonical names. Symbol annotations from `.vs` files are applied when available. Works on both C64U and VICE. Required inputs: address. Optional inputs: length, instructionCount.\n- copy_memory: Copy a RAM region to another address. Required inputs: source, dest, length.\n- fill_memory: Fill a memory range with a repeating byte pattern. Required inputs: address, length, pattern.\n- search_memory: Search for a byte pattern within a memory range and return matching addresses. Required inputs: startAddress, endAddress, pattern. Optional inputs: maxResults.\n- compare_memory: Compare two memory regions byte-by-byte and report differences. Required inputs: address1, address2, length. Optional inputs: maxDiffs.\n- save_memory: Dump a memory range to a local file, with an optional PRG load-address header. Required inputs: startAddress, endAddress, filePath. Optional inputs: asPrg.",
182
+ "additionalProperties": false,
183
+ "x-c64bridge-operations": [
5
184
  {
6
- "type": "object",
185
+ "op": "read",
7
186
  "description": "Read a range of bytes and return a hex dump with address metadata.",
8
- "properties": {
9
- "address": {
10
- "type": "string",
11
- "description": "Start address expressed as $HHHH, decimal, or a documented symbol name.",
12
- "minLength": 1
13
- },
14
- "length": {
15
- "type": "integer",
16
- "description": "Number of bytes to read starting from the resolved address.",
17
- "minimum": 1,
18
- "maximum": 4096,
19
- "default": 256
20
- },
21
- "op": {
22
- "const": "read"
23
- }
24
- },
25
187
  "required": [
26
- "address",
27
- "op"
188
+ "address"
189
+ ],
190
+ "optional": [
191
+ "length"
28
192
  ],
29
- "additionalProperties": false
193
+ "inputSchema": {
194
+ "type": "object",
195
+ "description": "Read a range of bytes and return a hex dump with address metadata.",
196
+ "properties": {
197
+ "address": {
198
+ "type": "string",
199
+ "description": "Start address expressed as $HHHH, decimal, or a documented symbol name.",
200
+ "minLength": 1
201
+ },
202
+ "length": {
203
+ "type": "integer",
204
+ "description": "Number of bytes to read starting from the resolved address.",
205
+ "minimum": 1,
206
+ "maximum": 4096,
207
+ "default": 256
208
+ },
209
+ "op": {
210
+ "const": "read"
211
+ }
212
+ },
213
+ "required": [
214
+ "address",
215
+ "op"
216
+ ],
217
+ "additionalProperties": false
218
+ }
30
219
  },
31
220
  {
32
- "type": "object",
221
+ "op": "write",
33
222
  "description": "Write a hexadecimal byte sequence into RAM.",
34
- "properties": {
35
- "address": {
36
- "type": "string",
37
- "description": "Destination address expressed as $HHHH, decimal, or a documented symbol name.",
38
- "minLength": 1
39
- },
40
- "bytes": {
41
- "type": "string",
42
- "description": "Hex byte sequence like $AABBCC or AA BB CC to write starting at the resolved address.",
43
- "minLength": 2,
44
- "pattern": "^[\\s_0-9A-Fa-f$]+$"
45
- },
46
- "verify": {
47
- "type": "boolean",
48
- "description": "When true, verify the write by reading before and after the change; Ultimate hardware also pauses during verification.",
49
- "default": false
50
- },
51
- "expected": {
52
- "type": [
53
- "string",
54
- "null"
55
- ],
56
- "description": "Optional hex data expected before the write (verifies before writing).",
57
- "minLength": 2,
58
- "pattern": "^[\\s_0-9A-Fa-f$]+$"
59
- },
60
- "mask": {
61
- "type": [
62
- "string",
63
- "null"
64
- ],
65
- "description": "Optional verification mask (hex); only bits set in the mask are compared.",
66
- "minLength": 2,
67
- "pattern": "^[\\s_0-9A-Fa-f$]+$"
68
- },
69
- "abortOnMismatch": {
70
- "type": "boolean",
71
- "description": "Abort the write when the pre-write verification fails.",
72
- "default": true
73
- },
74
- "op": {
75
- "const": "write"
76
- }
77
- },
78
223
  "required": [
79
224
  "address",
80
- "bytes",
81
- "op"
225
+ "bytes"
226
+ ],
227
+ "optional": [
228
+ "verify",
229
+ "expected",
230
+ "mask",
231
+ "abortOnMismatch"
82
232
  ],
83
- "additionalProperties": false
233
+ "inputSchema": {
234
+ "type": "object",
235
+ "description": "Write a hexadecimal byte sequence into RAM.",
236
+ "properties": {
237
+ "address": {
238
+ "type": "string",
239
+ "description": "Destination address expressed as $HHHH, decimal, or a documented symbol name.",
240
+ "minLength": 1
241
+ },
242
+ "bytes": {
243
+ "type": "string",
244
+ "description": "Hex byte sequence like $AABBCC or AA BB CC to write starting at the resolved address.",
245
+ "minLength": 2,
246
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
247
+ },
248
+ "verify": {
249
+ "type": "boolean",
250
+ "description": "When true, verify the write by reading before and after the change; Ultimate hardware also pauses during verification.",
251
+ "default": false
252
+ },
253
+ "expected": {
254
+ "type": [
255
+ "string",
256
+ "null"
257
+ ],
258
+ "description": "Optional hex data expected before the write (verifies before writing).",
259
+ "minLength": 2,
260
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
261
+ },
262
+ "mask": {
263
+ "type": [
264
+ "string",
265
+ "null"
266
+ ],
267
+ "description": "Optional verification mask (hex); only bits set in the mask are compared.",
268
+ "minLength": 2,
269
+ "pattern": "^[\\s_0-9A-Fa-f$]+$"
270
+ },
271
+ "abortOnMismatch": {
272
+ "type": "boolean",
273
+ "description": "Abort the write when the pre-write verification fails.",
274
+ "default": true
275
+ },
276
+ "op": {
277
+ "const": "write"
278
+ }
279
+ },
280
+ "required": [
281
+ "address",
282
+ "bytes",
283
+ "op"
284
+ ],
285
+ "additionalProperties": false
286
+ }
84
287
  },
85
288
  {
86
- "type": "object",
289
+ "op": "read_screen",
87
290
  "description": "Return the current 40x25 text screen converted to ASCII.",
88
- "properties": {
89
- "op": {
90
- "const": "read_screen"
91
- }
92
- },
93
- "additionalProperties": false,
94
- "required": [
95
- "op"
96
- ]
291
+ "required": [],
292
+ "optional": [],
293
+ "inputSchema": {
294
+ "type": "object",
295
+ "description": "Return the current 40x25 text screen converted to ASCII.",
296
+ "properties": {
297
+ "op": {
298
+ "const": "read_screen"
299
+ }
300
+ },
301
+ "additionalProperties": false,
302
+ "required": [
303
+ "op"
304
+ ]
305
+ }
97
306
  },
98
307
  {
99
- "type": "object",
308
+ "op": "wait_for_text",
100
309
  "description": "Poll the screen until a substring or regex appears, or timeout elapses.",
101
- "properties": {
102
- "pattern": {
103
- "type": "string",
104
- "description": "Substring or regex to find",
105
- "minLength": 1
310
+ "required": [
311
+ "pattern"
312
+ ],
313
+ "optional": [
314
+ "isRegex",
315
+ "caseInsensitive",
316
+ "timeoutMs",
317
+ "intervalMs"
318
+ ],
319
+ "inputSchema": {
320
+ "type": "object",
321
+ "description": "Poll the screen until a substring or regex appears, or timeout elapses.",
322
+ "properties": {
323
+ "pattern": {
324
+ "type": "string",
325
+ "description": "Substring or regex to find",
326
+ "minLength": 1
327
+ },
328
+ "isRegex": {
329
+ "type": [
330
+ "boolean",
331
+ "null"
332
+ ],
333
+ "description": "Interpret pattern as regular expression",
334
+ "default": false
335
+ },
336
+ "caseInsensitive": {
337
+ "type": [
338
+ "boolean",
339
+ "null"
340
+ ],
341
+ "description": "Case-insensitive search",
342
+ "default": true
343
+ },
344
+ "timeoutMs": {
345
+ "type": [
346
+ "integer",
347
+ "null"
348
+ ],
349
+ "description": "Overall timeout in milliseconds",
350
+ "minimum": 1,
351
+ "default": 3000
352
+ },
353
+ "intervalMs": {
354
+ "type": [
355
+ "integer",
356
+ "null"
357
+ ],
358
+ "description": "Poll interval in milliseconds",
359
+ "minimum": 1,
360
+ "default": 100
361
+ },
362
+ "op": {
363
+ "const": "wait_for_text"
364
+ }
365
+ },
366
+ "required": [
367
+ "pattern",
368
+ "op"
369
+ ],
370
+ "additionalProperties": false
371
+ }
372
+ },
373
+ {
374
+ "op": "disassemble",
375
+ "description": "Disassemble a memory region into annotated 6502/6510 instructions, including undocumented opcodes with canonical names. Symbol annotations from `.vs` files are applied when available. Works on both C64U and VICE.",
376
+ "required": [
377
+ "address"
378
+ ],
379
+ "optional": [
380
+ "length",
381
+ "instructionCount"
382
+ ],
383
+ "inputSchema": {
384
+ "type": "object",
385
+ "description": "Disassemble a memory region into annotated 6502/6510 instructions, including undocumented opcodes with canonical names. Symbol annotations from `.vs` files are applied when available. Works on both C64U and VICE.",
386
+ "properties": {
387
+ "address": {
388
+ "type": "string",
389
+ "description": "Start address as $HHHH, decimal, or symbol name.",
390
+ "minLength": 1
391
+ },
392
+ "length": {
393
+ "type": "integer",
394
+ "description": "Number of bytes to read and disassemble.",
395
+ "minimum": 1,
396
+ "maximum": 4096,
397
+ "default": 64
398
+ },
399
+ "instructionCount": {
400
+ "type": [
401
+ "integer",
402
+ "null"
403
+ ],
404
+ "description": "Stop after this many instructions (overrides length as a termination condition).",
405
+ "minimum": 1,
406
+ "maximum": 512
407
+ },
408
+ "op": {
409
+ "const": "disassemble"
410
+ }
106
411
  },
107
- "isRegex": {
108
- "type": [
109
- "boolean",
110
- "null"
111
- ],
112
- "description": "Interpret pattern as regular expression",
113
- "default": false
412
+ "required": [
413
+ "address",
414
+ "op"
415
+ ],
416
+ "additionalProperties": false
417
+ }
418
+ },
419
+ {
420
+ "op": "copy_memory",
421
+ "description": "Copy a RAM region to another address.",
422
+ "required": [
423
+ "source",
424
+ "dest",
425
+ "length"
426
+ ],
427
+ "optional": [],
428
+ "inputSchema": {
429
+ "type": "object",
430
+ "description": "Copy a RAM region to another address.",
431
+ "properties": {
432
+ "source": {
433
+ "type": "string",
434
+ "description": "Source start address ($HHHH, decimal, or symbol).",
435
+ "minLength": 1
436
+ },
437
+ "dest": {
438
+ "type": "string",
439
+ "description": "Destination start address.",
440
+ "minLength": 1
441
+ },
442
+ "length": {
443
+ "type": "integer",
444
+ "description": "Number of bytes to copy (1–16384).",
445
+ "minimum": 1,
446
+ "maximum": 16384
447
+ },
448
+ "op": {
449
+ "const": "copy_memory"
450
+ }
114
451
  },
115
- "caseInsensitive": {
116
- "type": [
117
- "boolean",
118
- "null"
119
- ],
120
- "description": "Case-insensitive search",
121
- "default": true
452
+ "required": [
453
+ "source",
454
+ "dest",
455
+ "length",
456
+ "op"
457
+ ],
458
+ "additionalProperties": false
459
+ }
460
+ },
461
+ {
462
+ "op": "fill_memory",
463
+ "description": "Fill a memory range with a repeating byte pattern.",
464
+ "required": [
465
+ "address",
466
+ "length",
467
+ "pattern"
468
+ ],
469
+ "optional": [],
470
+ "inputSchema": {
471
+ "type": "object",
472
+ "description": "Fill a memory range with a repeating byte pattern.",
473
+ "properties": {
474
+ "address": {
475
+ "type": "string",
476
+ "description": "Start address ($HHHH, decimal, or symbol).",
477
+ "minLength": 1
478
+ },
479
+ "length": {
480
+ "type": "integer",
481
+ "description": "Number of bytes to fill (1–16384).",
482
+ "minimum": 1,
483
+ "maximum": 16384
484
+ },
485
+ "pattern": {
486
+ "type": "string",
487
+ "description": "Hex bytes to repeat, e.g. 'FF' or 'AA 55'. Space-separated or run together.",
488
+ "minLength": 2,
489
+ "pattern": "^[\\s0-9A-Fa-f$]+$"
490
+ },
491
+ "op": {
492
+ "const": "fill_memory"
493
+ }
122
494
  },
123
- "timeoutMs": {
124
- "type": [
125
- "integer",
126
- "null"
127
- ],
128
- "description": "Overall timeout in milliseconds",
129
- "minimum": 1,
130
- "default": 3000
495
+ "required": [
496
+ "address",
497
+ "length",
498
+ "pattern",
499
+ "op"
500
+ ],
501
+ "additionalProperties": false
502
+ }
503
+ },
504
+ {
505
+ "op": "search_memory",
506
+ "description": "Search for a byte pattern within a memory range and return matching addresses.",
507
+ "required": [
508
+ "startAddress",
509
+ "endAddress",
510
+ "pattern"
511
+ ],
512
+ "optional": [
513
+ "maxResults"
514
+ ],
515
+ "inputSchema": {
516
+ "type": "object",
517
+ "description": "Search for a byte pattern within a memory range and return matching addresses.",
518
+ "properties": {
519
+ "startAddress": {
520
+ "type": "string",
521
+ "description": "Start of search range ($HHHH, decimal, or symbol).",
522
+ "minLength": 1
523
+ },
524
+ "endAddress": {
525
+ "type": "string",
526
+ "description": "End of search range (inclusive).",
527
+ "minLength": 1
528
+ },
529
+ "pattern": {
530
+ "type": "string",
531
+ "description": "Hex bytes to find, e.g. 'A9 00' for LDA #$00.",
532
+ "minLength": 2,
533
+ "pattern": "^[\\s0-9A-Fa-f$]+$"
534
+ },
535
+ "maxResults": {
536
+ "type": [
537
+ "integer",
538
+ "null"
539
+ ],
540
+ "description": "Maximum matches to return (default 10).",
541
+ "minimum": 1,
542
+ "maximum": 100,
543
+ "default": 10
544
+ },
545
+ "op": {
546
+ "const": "search_memory"
547
+ }
131
548
  },
132
- "intervalMs": {
133
- "type": [
134
- "integer",
135
- "null"
136
- ],
137
- "description": "Poll interval in milliseconds",
138
- "minimum": 1,
139
- "default": 100
549
+ "required": [
550
+ "startAddress",
551
+ "endAddress",
552
+ "pattern",
553
+ "op"
554
+ ],
555
+ "additionalProperties": false
556
+ }
557
+ },
558
+ {
559
+ "op": "compare_memory",
560
+ "description": "Compare two memory regions byte-by-byte and report differences.",
561
+ "required": [
562
+ "address1",
563
+ "address2",
564
+ "length"
565
+ ],
566
+ "optional": [
567
+ "maxDiffs"
568
+ ],
569
+ "inputSchema": {
570
+ "type": "object",
571
+ "description": "Compare two memory regions byte-by-byte and report differences.",
572
+ "properties": {
573
+ "address1": {
574
+ "type": "string",
575
+ "description": "First region start address.",
576
+ "minLength": 1
577
+ },
578
+ "address2": {
579
+ "type": "string",
580
+ "description": "Second region start address.",
581
+ "minLength": 1
582
+ },
583
+ "length": {
584
+ "type": "integer",
585
+ "description": "Number of bytes to compare (1–16384).",
586
+ "minimum": 1,
587
+ "maximum": 16384
588
+ },
589
+ "maxDiffs": {
590
+ "type": [
591
+ "integer",
592
+ "null"
593
+ ],
594
+ "description": "Max differences to report (default 10).",
595
+ "minimum": 1,
596
+ "maximum": 200,
597
+ "default": 10
598
+ },
599
+ "op": {
600
+ "const": "compare_memory"
601
+ }
140
602
  },
141
- "op": {
142
- "const": "wait_for_text"
143
- }
144
- },
603
+ "required": [
604
+ "address1",
605
+ "address2",
606
+ "length",
607
+ "op"
608
+ ],
609
+ "additionalProperties": false
610
+ }
611
+ },
612
+ {
613
+ "op": "save_memory",
614
+ "description": "Dump a memory range to a local file, with an optional PRG load-address header.",
145
615
  "required": [
146
- "pattern",
147
- "op"
616
+ "startAddress",
617
+ "endAddress",
618
+ "filePath"
619
+ ],
620
+ "optional": [
621
+ "asPrg"
148
622
  ],
149
- "additionalProperties": false
623
+ "inputSchema": {
624
+ "type": "object",
625
+ "description": "Dump a memory range to a local file, with an optional PRG load-address header.",
626
+ "properties": {
627
+ "startAddress": {
628
+ "type": "string",
629
+ "description": "Start address of region to save.",
630
+ "minLength": 1
631
+ },
632
+ "endAddress": {
633
+ "type": "string",
634
+ "description": "End address (inclusive).",
635
+ "minLength": 1
636
+ },
637
+ "filePath": {
638
+ "type": "string",
639
+ "description": "Absolute or relative path for the output file.",
640
+ "minLength": 1
641
+ },
642
+ "asPrg": {
643
+ "type": [
644
+ "boolean",
645
+ "null"
646
+ ],
647
+ "description": "Prepend a 2-byte little-endian load-address header (PRG format). Default: true.",
648
+ "default": true
649
+ },
650
+ "op": {
651
+ "const": "save_memory"
652
+ }
653
+ },
654
+ "required": [
655
+ "startAddress",
656
+ "endAddress",
657
+ "filePath",
658
+ "op"
659
+ ],
660
+ "additionalProperties": false
661
+ }
150
662
  }
151
- ],
152
- "discriminator": {
153
- "propertyName": "op"
154
- }
663
+ ]
155
664
  }