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.
- package/.github/prompts/steer.prompt.md +55 -0
- package/AGENTS.md +9 -7
- package/README.md +192 -154
- package/data/embeddings_asm.json +1 -1
- package/data/embeddings_basic.json +1 -1
- package/data/embeddings_hardware.json +1 -1
- package/data/embeddings_mixed.json +1 -1
- package/data/embeddings_other.json +1 -1
- package/data/graphics/petscii-style-guide.md +4 -4
- package/data/graphics/sprite-charset-best-practices.md +9 -9
- package/data/vice/vice-binary-monitor-spec.md +938 -0
- package/dist/.tsbuildinfo +1 -1
- package/dist/c64Client.js +76 -2
- package/dist/device.js +129 -13
- package/dist/mcp-server.js +1 -1
- package/dist/prompts/registry.js +27 -25
- package/dist/rag/indexer.js +18 -8
- package/dist/rag/knowledgeIndex.js +112 -79
- package/dist/rag/resourceUris.js +93 -0
- package/dist/sidwaveCompiler.js +1 -1
- package/dist/{assemblyConverter.js → tools/assember.js} +10 -1
- package/dist/tools/audio.js +11 -11
- package/dist/{basicConverter.js → tools/basicTokenizer.js} +1 -1
- package/dist/tools/debug.js +159 -6
- package/dist/tools/developer.js +13 -13
- package/dist/tools/disassembler.js +478 -0
- package/dist/tools/graphics.js +10 -10
- package/dist/tools/input.js +338 -0
- package/dist/tools/machineControl.js +5 -5
- package/dist/tools/memory.js +336 -12
- package/dist/tools/meta/index.js +1 -1
- package/dist/tools/printer.js +11 -12
- package/dist/tools/programRunners.js +61 -22
- package/dist/tools/rag.js +9 -9
- package/dist/tools/registry/batch.js +167 -0
- package/dist/tools/registry/config.js +1 -1
- package/dist/tools/registry/disk.js +1 -1
- package/dist/tools/registry/drive.js +1 -1
- package/dist/tools/registry/extract.js +1 -1
- package/dist/tools/registry/graphics.js +102 -2
- package/dist/tools/registry/index.js +4 -0
- package/dist/tools/registry/input.js +2 -0
- package/dist/tools/registry/memory.js +62 -2
- package/dist/tools/registry/platform.js +1 -1
- package/dist/tools/registry/printer.js +1 -1
- package/dist/tools/registry/program.js +1 -1
- package/dist/tools/registry/rag.js +1 -1
- package/dist/tools/registry/sound.js +1 -1
- package/dist/tools/registry/stream.js +1 -1
- package/dist/tools/registry/system.js +1 -1
- package/dist/tools/schema.js +4 -5
- package/dist/tools/storage.js +15 -15
- package/dist/tools/streaming.js +3 -3
- package/dist/tools/symbolRegistry.js +49 -0
- package/dist/tools/types.js +56 -4
- package/dist/tools/vice.js +2 -5
- package/dist/vice/process.js +120 -2
- package/dist/vice/readiness.js +35 -0
- package/dist/vice/smokeOptions.js +44 -0
- package/dist/vice/viceClient.js +5 -1
- package/dist/viceRunner.js +2 -0
- package/doc/plans/prompts/README.md +7 -7
- package/mcp/prompts.json +42 -59
- package/mcp/protocol-examples.json +2 -2
- package/mcp/resources.json +179 -166
- package/mcp/schemas/c64_batch.schema.json +53 -0
- package/mcp/schemas/c64_config.schema.json +525 -283
- package/mcp/schemas/c64_debug.schema.json +763 -304
- package/mcp/schemas/c64_disk.schema.json +499 -243
- package/mcp/schemas/c64_drive.schema.json +165 -90
- package/mcp/schemas/c64_extract.schema.json +533 -274
- package/mcp/schemas/c64_graphics.schema.json +607 -295
- package/mcp/schemas/c64_input.schema.json +136 -0
- package/mcp/schemas/c64_memory.schema.json +637 -128
- package/mcp/schemas/c64_printer.schema.json +393 -196
- package/mcp/schemas/c64_program.schema.json +699 -340
- package/mcp/schemas/c64_rag.schema.json +100 -54
- package/mcp/schemas/c64_select_backend.schema.json +49 -23
- package/mcp/schemas/c64_sound.schema.json +1092 -577
- package/mcp/schemas/c64_stream.schema.json +89 -47
- package/mcp/schemas/c64_system.schema.json +351 -185
- package/mcp/schemas/c64_vice.schema.json +85 -47
- package/mcp/server.json +1 -1
- package/mcp/tools.json +7299 -3346
- package/mcp.json +3 -3
- package/package.json +17 -14
- package/scripts/fetch-external-sources.mjs +1 -2
- package/scripts/run-coverage.mjs +33 -1
- package/scripts/run-tests.mjs +2 -2
- package/scripts/run-tests.ts +275 -52
- package/scripts/update-readme.ts +132 -3
- package/server.json +2 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createOperationDispatcher, defineToolModule, discriminatedUnionSchema, } from "../types.js";
|
|
2
|
-
import { memoryModule, memoryOperationHandlers as groupedMemoryHandlers } from "../memory.js";
|
|
2
|
+
import { memoryModule, memoryOperationHandlers as groupedMemoryHandlers, disassembleArgsSchema, copyMemoryArgsSchema, fillMemoryArgsSchema, searchMemoryArgsSchema, compareMemoryArgsSchema, saveMemoryArgsSchema, } from "../memory.js";
|
|
3
3
|
import { metaModule } from "../meta/index.js";
|
|
4
4
|
import { buildDescriptorIndex, ensureDescriptor, extendSchemaWithOp, createOperationHandlers, invokeModuleTool, } from "./utils.js";
|
|
5
5
|
const memoryDescriptorIndex = buildDescriptorIndex(memoryModule);
|
|
@@ -25,13 +25,43 @@ const memoryOperations = [
|
|
|
25
25
|
schema: extendSchemaWithOp("wait_for_text", ensureDescriptor(metaDescriptorIndex, "wait_for_screen_text").inputSchema, { description: "Poll the screen until a substring or regex appears, or timeout elapses." }),
|
|
26
26
|
handler: async (rawArgs, ctx) => invokeModuleTool(metaModule, "wait_for_screen_text", rawArgs, ctx),
|
|
27
27
|
},
|
|
28
|
+
{
|
|
29
|
+
op: "disassemble",
|
|
30
|
+
schema: extendSchemaWithOp("disassemble", disassembleArgsSchema.jsonSchema, { 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." }),
|
|
31
|
+
handler: groupedMemoryHandlers.disassemble,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
op: "copy_memory",
|
|
35
|
+
schema: extendSchemaWithOp("copy_memory", copyMemoryArgsSchema.jsonSchema, { description: "Copy a RAM region to another address." }),
|
|
36
|
+
handler: groupedMemoryHandlers.copy_memory,
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
op: "fill_memory",
|
|
40
|
+
schema: extendSchemaWithOp("fill_memory", fillMemoryArgsSchema.jsonSchema, { description: "Fill a memory range with a repeating byte pattern." }),
|
|
41
|
+
handler: groupedMemoryHandlers.fill_memory,
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
op: "search_memory",
|
|
45
|
+
schema: extendSchemaWithOp("search_memory", searchMemoryArgsSchema.jsonSchema, { description: "Search for a byte pattern within a memory range and return matching addresses." }),
|
|
46
|
+
handler: groupedMemoryHandlers.search_memory,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
op: "compare_memory",
|
|
50
|
+
schema: extendSchemaWithOp("compare_memory", compareMemoryArgsSchema.jsonSchema, { description: "Compare two memory regions byte-by-byte and report differences." }),
|
|
51
|
+
handler: groupedMemoryHandlers.compare_memory,
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
op: "save_memory",
|
|
55
|
+
schema: extendSchemaWithOp("save_memory", saveMemoryArgsSchema.jsonSchema, { description: "Dump a memory range to a local file, with an optional PRG load-address header." }),
|
|
56
|
+
handler: groupedMemoryHandlers.save_memory,
|
|
57
|
+
},
|
|
28
58
|
];
|
|
29
59
|
const memoryOperationHandlers = createOperationHandlers(memoryOperations);
|
|
30
60
|
export const memoryModuleGroup = defineToolModule({
|
|
31
61
|
domain: "memory",
|
|
32
62
|
summary: "Grouped memory, screen, and polling operations.",
|
|
33
63
|
supportedPlatforms: ["c64u", "vice"],
|
|
34
|
-
resources: ["c64://
|
|
64
|
+
resources: ["c64://guide/bootstrap", "c64://basic/spec", "c64://assembly/6510-spec"],
|
|
35
65
|
prompts: ["memory-debug", "basic-program", "assembly-program"],
|
|
36
66
|
defaultTags: ["memory", "debug"],
|
|
37
67
|
workflowHints: [
|
|
@@ -59,6 +89,36 @@ export const memoryModuleGroup = defineToolModule({
|
|
|
59
89
|
description: "Poll until the READY. prompt appears",
|
|
60
90
|
arguments: { op: "wait_for_text", pattern: "READY." },
|
|
61
91
|
},
|
|
92
|
+
{
|
|
93
|
+
name: "Disassemble entry point",
|
|
94
|
+
description: "Disassemble 20 instructions starting at $0810",
|
|
95
|
+
arguments: { op: "disassemble", address: "$0810", instructionCount: 20 },
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: "Copy screen RAM",
|
|
99
|
+
description: "Copy 1000 bytes of screen RAM to a scratch area",
|
|
100
|
+
arguments: { op: "copy_memory", source: "$0400", dest: "$C000", length: 1000 },
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
name: "Clear screen RAM",
|
|
104
|
+
description: "Fill screen RAM with space character ($20)",
|
|
105
|
+
arguments: { op: "fill_memory", address: "$0400", length: 1000, pattern: "20" },
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: "Search for RTS",
|
|
109
|
+
description: "Find RTS ($60) instructions in BASIC ROM",
|
|
110
|
+
arguments: { op: "search_memory", startAddress: "$A000", endAddress: "$BFFF", pattern: "60" },
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: "Compare two buffers",
|
|
114
|
+
description: "Check whether two 256-byte regions differ",
|
|
115
|
+
arguments: { op: "compare_memory", address1: "$C000", address2: "$C100", length: 256 },
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: "Save PRG dump",
|
|
119
|
+
description: "Save $0801-$CFFF as a PRG file",
|
|
120
|
+
arguments: { op: "save_memory", startAddress: "$0801", endAddress: "$CFFF", filePath: "/tmp/dump.prg" },
|
|
121
|
+
},
|
|
62
122
|
],
|
|
63
123
|
execute: createOperationDispatcher("c64_memory", memoryOperationHandlers),
|
|
64
124
|
},
|
|
@@ -92,7 +92,7 @@ export const platformModuleGroup = defineToolModule({
|
|
|
92
92
|
domain: "platform",
|
|
93
93
|
summary: "Runtime backend selection and platform-status coordination.",
|
|
94
94
|
supportedPlatforms: ["c64u", "vice"],
|
|
95
|
-
resources: ["c64://platform/status", "c64://
|
|
95
|
+
resources: ["c64://platform/status", "c64://guide/bootstrap"],
|
|
96
96
|
prompts: [],
|
|
97
97
|
defaultTags: ["platform", "backend", "grouped"],
|
|
98
98
|
workflowHints: [
|
|
@@ -117,7 +117,7 @@ function invokePrintTool(toolName, rawArgs, ctx) {
|
|
|
117
117
|
export const printerModuleGroup = defineToolModule({
|
|
118
118
|
domain: "printer",
|
|
119
119
|
summary: "Grouped printer text, bitmap, and character definition helpers.",
|
|
120
|
-
resources: ["c64://
|
|
120
|
+
resources: ["c64://guide/bootstrap"],
|
|
121
121
|
defaultTags: ["printer", "device"],
|
|
122
122
|
workflowHints: [
|
|
123
123
|
"Mention device/secondary addresses so the user knows which printer workflow ran.",
|
|
@@ -50,7 +50,7 @@ const programOperationHandlers = createOperationHandlers(programOperations);
|
|
|
50
50
|
export const programModule = defineToolModule({
|
|
51
51
|
domain: "programs",
|
|
52
52
|
summary: "Grouped program upload, run, and orchestration workflows.",
|
|
53
|
-
resources: ["c64://
|
|
53
|
+
resources: ["c64://guide/bootstrap", "c64://basic/spec", "c64://assembly/6510-spec"],
|
|
54
54
|
prompts: ["basic-program", "assembly-program"],
|
|
55
55
|
defaultTags: ["programs", "execution"],
|
|
56
56
|
workflowHints: [
|
|
@@ -18,7 +18,7 @@ const ragOperationHandlers = createOperationHandlers(ragOperations);
|
|
|
18
18
|
export const ragModuleGroup = defineToolModule({
|
|
19
19
|
domain: "rag",
|
|
20
20
|
summary: "Grouped retrieval helpers for BASIC and assembly references.",
|
|
21
|
-
resources: ["c64://
|
|
21
|
+
resources: ["c64://basic/spec", "c64://assembly/6510-spec", "c64://guide/bootstrap"],
|
|
22
22
|
prompts: ["basic-program", "assembly-program"],
|
|
23
23
|
defaultTags: ["rag", "search"],
|
|
24
24
|
workflowHints: [
|
|
@@ -140,7 +140,7 @@ export const soundModuleGroup = defineToolModule({
|
|
|
140
140
|
domain: "audio",
|
|
141
141
|
summary: "Grouped SID control, playback, composition, and analysis operations.",
|
|
142
142
|
supportedPlatforms: ["c64u", "vice"],
|
|
143
|
-
resources: ["c64://
|
|
143
|
+
resources: ["c64://sound/sid/spec", "c64://sound/sidwave/spec", "c64://sound/sid/file-format"],
|
|
144
144
|
prompts: ["sid-music"],
|
|
145
145
|
defaultTags: ["sid", "audio"],
|
|
146
146
|
workflowHints: [
|
|
@@ -18,7 +18,7 @@ const streamOperationHandlers = createOperationHandlers(streamOperations);
|
|
|
18
18
|
export const streamModule = defineToolModule({
|
|
19
19
|
domain: "stream",
|
|
20
20
|
summary: "Grouped streaming helpers for starting and stopping Ultimate capture sessions.",
|
|
21
|
-
resources: ["c64://
|
|
21
|
+
resources: ["c64://guide/index", "c64://sound/sid/spec"],
|
|
22
22
|
prompts: ["sid-music"],
|
|
23
23
|
defaultTags: ["stream", "monitor"],
|
|
24
24
|
workflowHints: [
|
|
@@ -66,7 +66,7 @@ export const systemModuleGroup = defineToolModule({
|
|
|
66
66
|
domain: "system",
|
|
67
67
|
summary: "Grouped machine control and background task orchestration.",
|
|
68
68
|
supportedPlatforms: ["c64u", "vice"],
|
|
69
|
-
resources: ["c64://
|
|
69
|
+
resources: ["c64://guide/bootstrap"],
|
|
70
70
|
prompts: ["memory-debug"],
|
|
71
71
|
defaultTags: ["system", "control"],
|
|
72
72
|
workflowHints: [
|
package/dist/tools/schema.js
CHANGED
|
@@ -195,15 +195,14 @@ function isPlainObject(value) {
|
|
|
195
195
|
}
|
|
196
196
|
export function objectSchema(options) {
|
|
197
197
|
const required = options.required ?? [];
|
|
198
|
+
const additionalProperties = options.additionalProperties ?? false;
|
|
198
199
|
const propertyEntries = Object.entries(options.properties).map(([key, schema]) => [key, schema.jsonSchema]);
|
|
199
200
|
const jsonSchema = {
|
|
200
201
|
type: "object",
|
|
201
202
|
...(options.description ? { description: options.description } : {}),
|
|
202
203
|
properties: Object.fromEntries(propertyEntries),
|
|
203
204
|
...(required.length > 0 ? { required: required.map((key) => key) } : {}),
|
|
204
|
-
|
|
205
|
-
? { additionalProperties: options.additionalProperties }
|
|
206
|
-
: { additionalProperties: false }),
|
|
205
|
+
additionalProperties,
|
|
207
206
|
};
|
|
208
207
|
return createSchema(jsonSchema, (value, path) => {
|
|
209
208
|
ensureType(isPlainObject(value), "Expected an object", path, {
|
|
@@ -234,7 +233,7 @@ export function objectSchema(options) {
|
|
|
234
233
|
}
|
|
235
234
|
}
|
|
236
235
|
}
|
|
237
|
-
if (
|
|
236
|
+
if (!additionalProperties) {
|
|
238
237
|
for (const key of Object.keys(input)) {
|
|
239
238
|
if (!hasOwn.call(options.properties, key)) {
|
|
240
239
|
throw new ToolValidationError("Unexpected property", {
|
|
@@ -243,7 +242,7 @@ export function objectSchema(options) {
|
|
|
243
242
|
}
|
|
244
243
|
}
|
|
245
244
|
}
|
|
246
|
-
else
|
|
245
|
+
else {
|
|
247
246
|
for (const key of Object.keys(input)) {
|
|
248
247
|
if (!hasOwn.call(options.properties, key)) {
|
|
249
248
|
result[key] = input[key];
|
package/dist/tools/storage.js
CHANGED
|
@@ -144,7 +144,7 @@ export const storageModule = defineToolModule({
|
|
|
144
144
|
domain: "storage",
|
|
145
145
|
summary: "Drive management, disk image creation, and file inspection utilities.",
|
|
146
146
|
supportedPlatforms: ["c64u", "vice"],
|
|
147
|
-
resources: ["c64://
|
|
147
|
+
resources: ["c64://guide/bootstrap"],
|
|
148
148
|
prompts: ["memory-debug"],
|
|
149
149
|
defaultTags: ["drive", "storage"],
|
|
150
150
|
workflowHints: [
|
|
@@ -154,10 +154,10 @@ export const storageModule = defineToolModule({
|
|
|
154
154
|
tools: [
|
|
155
155
|
{
|
|
156
156
|
name: "drives_list",
|
|
157
|
-
description: "List Ultimate drive slots and their currently mounted images. Read c64://
|
|
157
|
+
description: "List Ultimate drive slots and their currently mounted images. Read c64://guide/bootstrap for drive safety.",
|
|
158
158
|
summary: "Fetches firmware drive status including mounted images, power state, and modes.",
|
|
159
159
|
inputSchema: drivesListArgsSchema.jsonSchema,
|
|
160
|
-
relatedResources: ["c64://
|
|
160
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
161
161
|
tags: ["drive", "status"],
|
|
162
162
|
prerequisites: [],
|
|
163
163
|
examples: [
|
|
@@ -193,7 +193,7 @@ export const storageModule = defineToolModule({
|
|
|
193
193
|
description: "Mount a disk image onto a specific Ultimate drive slot.",
|
|
194
194
|
summary: "Validates parameters and instructs the firmware to mount an image with optional type/mode overrides.",
|
|
195
195
|
inputSchema: driveMountArgsSchema.jsonSchema,
|
|
196
|
-
relatedResources: ["c64://
|
|
196
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
197
197
|
tags: ["drive", "mount"],
|
|
198
198
|
prerequisites: ["drives_list"],
|
|
199
199
|
examples: [
|
|
@@ -250,7 +250,7 @@ export const storageModule = defineToolModule({
|
|
|
250
250
|
description: "Remove the currently mounted disk image from an Ultimate drive slot.",
|
|
251
251
|
summary: "Ejects the image and leaves the drive empty without powering it off.",
|
|
252
252
|
inputSchema: driveOnlyArgsSchema.jsonSchema,
|
|
253
|
-
relatedResources: ["c64://
|
|
253
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
254
254
|
tags: ["drive", "unmount"],
|
|
255
255
|
prerequisites: ["drives_list"],
|
|
256
256
|
examples: [
|
|
@@ -292,7 +292,7 @@ export const storageModule = defineToolModule({
|
|
|
292
292
|
description: "Reset the selected Ultimate drive slot.",
|
|
293
293
|
summary: "Issues a IEC reset for the chosen drive without cycling the entire machine.",
|
|
294
294
|
inputSchema: driveOnlyArgsSchema.jsonSchema,
|
|
295
|
-
relatedResources: ["c64://
|
|
295
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
296
296
|
tags: ["drive", "reset"],
|
|
297
297
|
prerequisites: ["drives_list"],
|
|
298
298
|
examples: [
|
|
@@ -334,7 +334,7 @@ export const storageModule = defineToolModule({
|
|
|
334
334
|
description: "Power on a specific Ultimate drive slot.",
|
|
335
335
|
summary: "Ensures the selected drive is reported as powered and ready on the IEC bus.",
|
|
336
336
|
inputSchema: driveOnlyArgsSchema.jsonSchema,
|
|
337
|
-
relatedResources: ["c64://
|
|
337
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
338
338
|
tags: ["drive", "power"],
|
|
339
339
|
prerequisites: ["drives_list"],
|
|
340
340
|
examples: [
|
|
@@ -377,7 +377,7 @@ export const storageModule = defineToolModule({
|
|
|
377
377
|
description: "Power off a specific Ultimate drive slot.",
|
|
378
378
|
summary: "Disables the drive without altering mounted media so it can be re-enabled later.",
|
|
379
379
|
inputSchema: driveOnlyArgsSchema.jsonSchema,
|
|
380
|
-
relatedResources: ["c64://
|
|
380
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
381
381
|
tags: ["drive", "power"],
|
|
382
382
|
prerequisites: ["drives_list"],
|
|
383
383
|
examples: [
|
|
@@ -420,7 +420,7 @@ export const storageModule = defineToolModule({
|
|
|
420
420
|
description: "Temporarily load a custom ROM into an Ultimate drive slot.",
|
|
421
421
|
summary: "Points the drive at an alternative ROM file without flashing permanent storage.",
|
|
422
422
|
inputSchema: driveLoadRomArgsSchema.jsonSchema,
|
|
423
|
-
relatedResources: ["c64://
|
|
423
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
424
424
|
tags: ["drive", "rom"],
|
|
425
425
|
prerequisites: ["drives_list"],
|
|
426
426
|
examples: [
|
|
@@ -463,7 +463,7 @@ export const storageModule = defineToolModule({
|
|
|
463
463
|
description: "Set the emulation mode for an Ultimate drive slot (1541/1571/1581).",
|
|
464
464
|
summary: "Switches the drive hardware profile to match the mounted media and desired behaviour.",
|
|
465
465
|
inputSchema: driveModeArgsSchema.jsonSchema,
|
|
466
|
-
relatedResources: ["c64://
|
|
466
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
467
467
|
tags: ["drive", "mode"],
|
|
468
468
|
prerequisites: ["drives_list"],
|
|
469
469
|
examples: [
|
|
@@ -506,7 +506,7 @@ export const storageModule = defineToolModule({
|
|
|
506
506
|
description: "Inspect metadata for a file on the Ultimate filesystem.",
|
|
507
507
|
summary: "Queries the REST API for file size, type, and other details useful when managing disk images.",
|
|
508
508
|
inputSchema: fileInfoArgsSchema.jsonSchema,
|
|
509
|
-
relatedResources: ["c64://
|
|
509
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
510
510
|
tags: ["storage", "info"],
|
|
511
511
|
prerequisites: [],
|
|
512
512
|
examples: [
|
|
@@ -543,7 +543,7 @@ export const storageModule = defineToolModule({
|
|
|
543
543
|
description: "Create a blank D64 disk image on the Ultimate filesystem.",
|
|
544
544
|
summary: "Allocates a 35 or 40 track D64 image with an optional disk name.",
|
|
545
545
|
inputSchema: createD64ArgsSchema.jsonSchema,
|
|
546
|
-
relatedResources: ["c64://
|
|
546
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
547
547
|
tags: ["disk", "create"],
|
|
548
548
|
prerequisites: ["drives_list"],
|
|
549
549
|
examples: [
|
|
@@ -594,7 +594,7 @@ export const storageModule = defineToolModule({
|
|
|
594
594
|
description: "Create a blank D71 disk image on the Ultimate filesystem.",
|
|
595
595
|
summary: "Allocates a 1571-compatible disk image with optional labelling.",
|
|
596
596
|
inputSchema: createD71ArgsSchema.jsonSchema,
|
|
597
|
-
relatedResources: ["c64://
|
|
597
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
598
598
|
tags: ["disk", "create"],
|
|
599
599
|
prerequisites: ["drives_list"],
|
|
600
600
|
examples: [
|
|
@@ -642,7 +642,7 @@ export const storageModule = defineToolModule({
|
|
|
642
642
|
description: "Create a blank D81 disk image on the Ultimate filesystem.",
|
|
643
643
|
summary: "Allocates a 1581-compatible disk image with optional labelling.",
|
|
644
644
|
inputSchema: createD81ArgsSchema.jsonSchema,
|
|
645
|
-
relatedResources: ["c64://
|
|
645
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
646
646
|
tags: ["disk", "create"],
|
|
647
647
|
prerequisites: ["drives_list"],
|
|
648
648
|
examples: [
|
|
@@ -690,7 +690,7 @@ export const storageModule = defineToolModule({
|
|
|
690
690
|
description: "Create a blank DNP disk image on the Ultimate filesystem.",
|
|
691
691
|
summary: "Allocates a CMD-native DNP image with custom track count and optional label.",
|
|
692
692
|
inputSchema: createDnpArgsSchema.jsonSchema,
|
|
693
|
-
relatedResources: ["c64://
|
|
693
|
+
relatedResources: ["c64://guide/bootstrap"],
|
|
694
694
|
tags: ["disk", "create"],
|
|
695
695
|
prerequisites: [
|
|
696
696
|
"drives_list"
|
package/dist/tools/streaming.js
CHANGED
|
@@ -36,8 +36,8 @@ export const streamingModule = defineToolModule({
|
|
|
36
36
|
domain: "streaming",
|
|
37
37
|
summary: "Long-running or streaming workflows such as audio capture or SID playback monitoring.",
|
|
38
38
|
resources: [
|
|
39
|
-
"c64://
|
|
40
|
-
"c64://
|
|
39
|
+
"c64://sound/sid/spec",
|
|
40
|
+
"c64://guide/index",
|
|
41
41
|
],
|
|
42
42
|
prompts: ["sid-music"],
|
|
43
43
|
defaultLifecycle: "stream",
|
|
@@ -50,7 +50,7 @@ export const streamingModule = defineToolModule({
|
|
|
50
50
|
tools: [
|
|
51
51
|
{
|
|
52
52
|
name: "stream_start",
|
|
53
|
-
description: "Start an Ultimate streaming session (video/audio/debug) targeting a host:port destination. See c64://
|
|
53
|
+
description: "Start an Ultimate streaming session (video/audio/debug) targeting a host:port destination. See c64://guide/index for usage notes.",
|
|
54
54
|
summary: "Validates stream arguments and forwards the request to firmware, returning status metadata.",
|
|
55
55
|
inputSchema: streamStartArgsSchema.jsonSchema,
|
|
56
56
|
tags: ["stream", "start"],
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-process symbol registry for VICE debug sessions.
|
|
3
|
+
* Maps addresses to label names so the disassembler can annotate output.
|
|
4
|
+
* Cleared and repopulated each time a new program is loaded.
|
|
5
|
+
*/
|
|
6
|
+
const viceAddressToLabel = new Map();
|
|
7
|
+
export function setViceSymbols(nameToAddress) {
|
|
8
|
+
viceAddressToLabel.clear();
|
|
9
|
+
for (const [name, address] of nameToAddress) {
|
|
10
|
+
if (address >= 0 && address <= 0xffff) {
|
|
11
|
+
viceAddressToLabel.set(address, name);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
export function getViceSymbol(address) {
|
|
16
|
+
return viceAddressToLabel.get(address);
|
|
17
|
+
}
|
|
18
|
+
export function clearViceSymbols() {
|
|
19
|
+
viceAddressToLabel.clear();
|
|
20
|
+
}
|
|
21
|
+
export function getViceSymbols() {
|
|
22
|
+
return viceAddressToLabel;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Parse a VICE symbol file (.vs) into a name->address map.
|
|
26
|
+
*
|
|
27
|
+
* Supported line formats:
|
|
28
|
+
* add_label 0x0810 .main
|
|
29
|
+
* add_label C:0810 .main
|
|
30
|
+
* al C:0810 .main
|
|
31
|
+
* al 0810 .main
|
|
32
|
+
*/
|
|
33
|
+
export function parseViceSymbolFile(content) {
|
|
34
|
+
const symbols = new Map();
|
|
35
|
+
for (const rawLine of content.split("\n")) {
|
|
36
|
+
const line = rawLine.trim();
|
|
37
|
+
if (!line || line.startsWith(";") || line.startsWith("#"))
|
|
38
|
+
continue;
|
|
39
|
+
const match = /^(?:add_label|al)\s+(?:[A-Za-z]+:)?(?:0x|\$)?([0-9A-Fa-f]+)\s+\.?(\S+)/i.exec(line);
|
|
40
|
+
if (match) {
|
|
41
|
+
const addr = parseInt(match[1], 16);
|
|
42
|
+
const name = match[2];
|
|
43
|
+
if (!isNaN(addr) && addr >= 0 && addr <= 0xffff && name) {
|
|
44
|
+
symbols.set(name, addr);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return symbols;
|
|
49
|
+
}
|
package/dist/tools/types.js
CHANGED
|
@@ -30,13 +30,65 @@ export function discriminatedUnionSchema(options) {
|
|
|
30
30
|
if (!variants || variants.length === 0) {
|
|
31
31
|
throw new Error("Discriminated union schemas require at least one variant.");
|
|
32
32
|
}
|
|
33
|
+
// Flatten the discriminated union into a single object schema.
|
|
34
|
+
// Claude's API does not support oneOf/allOf/anyOf at the top level,
|
|
35
|
+
// so we merge all variant properties and use an enum for the discriminator.
|
|
36
|
+
const opValues = [];
|
|
37
|
+
const mergedProperties = {};
|
|
38
|
+
const opDescriptions = [];
|
|
39
|
+
const operationMetadata = [];
|
|
40
|
+
for (const variant of variants) {
|
|
41
|
+
const variantProps = variant.properties ?? {};
|
|
42
|
+
const discProp = variantProps[discriminator];
|
|
43
|
+
const opValue = discProp?.const;
|
|
44
|
+
const variantDesc = variant.description ?? discProp?.description ?? "";
|
|
45
|
+
const requiredInputs = (variant.required ?? []).filter((name) => name !== discriminator);
|
|
46
|
+
const optionalInputs = Object.keys(variantProps).filter((name) => name !== discriminator && !requiredInputs.includes(name));
|
|
47
|
+
if (opValue) {
|
|
48
|
+
opValues.push(opValue);
|
|
49
|
+
const requiredSummary = requiredInputs.length > 0
|
|
50
|
+
? ` Required inputs: ${requiredInputs.join(", ")}.`
|
|
51
|
+
: " Required inputs: none.";
|
|
52
|
+
const optionalSummary = optionalInputs.length > 0
|
|
53
|
+
? ` Optional inputs: ${optionalInputs.join(", ")}.`
|
|
54
|
+
: "";
|
|
55
|
+
opDescriptions.push(`${opValue}: ${variantDesc || `Operation ${opValue}`}${requiredSummary}${optionalSummary}`);
|
|
56
|
+
operationMetadata.push({
|
|
57
|
+
op: opValue,
|
|
58
|
+
...(variantDesc ? { description: variantDesc } : {}),
|
|
59
|
+
required: requiredInputs,
|
|
60
|
+
optional: optionalInputs,
|
|
61
|
+
inputSchema: variant,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
for (const [key, propSchema] of Object.entries(variantProps)) {
|
|
65
|
+
if (key === discriminator)
|
|
66
|
+
continue;
|
|
67
|
+
if (!mergedProperties[key]) {
|
|
68
|
+
mergedProperties[key] = propSchema;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const opPropertySchema = opValues.length > 0
|
|
73
|
+
? { type: "string", enum: opValues, description: `Selects the operation.` }
|
|
74
|
+
: { type: "string", description: `Selects the operation.` };
|
|
75
|
+
const fullDescription = description
|
|
76
|
+
? (opDescriptions.length > 0
|
|
77
|
+
? `${description}\n\nOperations:\n${opDescriptions.map((d) => `- ${d}`).join("\n")}`
|
|
78
|
+
: description)
|
|
79
|
+
: (opDescriptions.length > 0
|
|
80
|
+
? `Operations:\n${opDescriptions.map((d) => `- ${d}`).join("\n")}`
|
|
81
|
+
: undefined);
|
|
33
82
|
const schema = {
|
|
34
83
|
type: "object",
|
|
35
|
-
...(
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
84
|
+
...(fullDescription ? { description: fullDescription } : {}),
|
|
85
|
+
properties: {
|
|
86
|
+
[discriminator]: opPropertySchema,
|
|
87
|
+
...mergedProperties,
|
|
39
88
|
},
|
|
89
|
+
required: [discriminator],
|
|
90
|
+
additionalProperties: false,
|
|
91
|
+
...(operationMetadata.length > 0 ? { "x-c64bridge-operations": operationMetadata } : {}),
|
|
40
92
|
};
|
|
41
93
|
return schema;
|
|
42
94
|
}
|
package/dist/tools/vice.js
CHANGED
|
@@ -15,11 +15,8 @@ const SAFE_RESOURCE_PREFIXES = [
|
|
|
15
15
|
];
|
|
16
16
|
const resourceValueSchema = {
|
|
17
17
|
jsonSchema: {
|
|
18
|
+
type: ["string", "integer"],
|
|
18
19
|
description: "VICE resource value (string or integer).",
|
|
19
|
-
oneOf: [
|
|
20
|
-
{ type: "string" },
|
|
21
|
-
{ type: "integer" },
|
|
22
|
-
],
|
|
23
20
|
},
|
|
24
21
|
parse(value, path) {
|
|
25
22
|
const resolvedPath = path ?? "$.value";
|
|
@@ -110,7 +107,7 @@ const viceOperationDispatcher = createOperationDispatcher("c64_vice", viceOperat
|
|
|
110
107
|
export const viceModuleGroup = defineToolModule({
|
|
111
108
|
domain: "vice",
|
|
112
109
|
summary: "VICE emulator helpers for safe runtime resource access.",
|
|
113
|
-
resources: ["c64://
|
|
110
|
+
resources: ["c64://memory/map"],
|
|
114
111
|
prompts: ["assembly-program", "memory-debug"],
|
|
115
112
|
defaultTags: ["vice", "emulator"],
|
|
116
113
|
workflowHints: [
|