c64bridge 0.9.0 → 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 (49) hide show
  1. package/README.md +158 -164
  2. package/data/vice/vice-binary-monitor-spec.md +21 -4
  3. package/dist/.tsbuildinfo +1 -1
  4. package/dist/c64Client.js +76 -2
  5. package/dist/device.js +43 -3
  6. package/dist/rag/indexer.js +18 -8
  7. package/dist/sidwaveCompiler.js +1 -1
  8. package/dist/{assemblyConverter.js → tools/assember.js} +10 -1
  9. package/dist/{basicConverter.js → tools/basicTokenizer.js} +1 -1
  10. package/dist/tools/debug.js +158 -5
  11. package/dist/tools/disassembler.js +478 -0
  12. package/dist/tools/input.js +338 -0
  13. package/dist/tools/memory.js +317 -1
  14. package/dist/tools/programRunners.js +45 -6
  15. package/dist/tools/registry/batch.js +167 -0
  16. package/dist/tools/registry/graphics.js +101 -1
  17. package/dist/tools/registry/index.js +4 -0
  18. package/dist/tools/registry/input.js +2 -0
  19. package/dist/tools/registry/memory.js +61 -1
  20. package/dist/tools/schema.js +4 -5
  21. package/dist/tools/symbolRegistry.js +49 -0
  22. package/dist/tools/types.js +19 -4
  23. package/dist/vice/process.js +43 -2
  24. package/dist/vice/viceClient.js +5 -1
  25. package/mcp/schemas/c64_batch.schema.json +53 -0
  26. package/mcp/schemas/c64_config.schema.json +461 -2
  27. package/mcp/schemas/c64_debug.schema.json +641 -3
  28. package/mcp/schemas/c64_disk.schema.json +340 -2
  29. package/mcp/schemas/c64_drive.schema.json +157 -2
  30. package/mcp/schemas/c64_extract.schema.json +359 -2
  31. package/mcp/schemas/c64_graphics.schema.json +415 -3
  32. package/mcp/schemas/c64_input.schema.json +136 -0
  33. package/mcp/schemas/c64_memory.schema.json +562 -3
  34. package/mcp/schemas/c64_printer.schema.json +253 -2
  35. package/mcp/schemas/c64_program.schema.json +499 -2
  36. package/mcp/schemas/c64_rag.schema.json +82 -2
  37. package/mcp/schemas/c64_select_backend.schema.json +35 -2
  38. package/mcp/schemas/c64_sound.schema.json +793 -2
  39. package/mcp/schemas/c64_stream.schema.json +73 -2
  40. package/mcp/schemas/c64_system.schema.json +301 -2
  41. package/mcp/schemas/c64_vice.schema.json +71 -2
  42. package/mcp/server.json +1 -1
  43. package/mcp/tools.json +6718 -1257
  44. package/mcp.json +1 -1
  45. package/package.json +1 -1
  46. package/scripts/run-coverage.mjs +7 -0
  47. package/scripts/run-tests.ts +2 -0
  48. package/scripts/update-readme.ts +79 -2
  49. package/server.json +2 -2
package/mcp.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c64bridge",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Stdio-based Model Context Protocol (MCP) server that bridges Commodore 64 Ultimate hardware with AI agents.",
5
5
  "entry": "dist/index.js",
6
6
  "type": "stdio",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "c64bridge",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "mcpName": "io.github.chrisgleissner/c64bridge",
5
5
  "description": "C64 Bridge MCP server for Commodore 64 Ultimate hardware and VICE emulator control",
6
6
  "type": "module",
@@ -18,6 +18,8 @@ const DEFAULT_VICE_MOCK_TEST_FILES = [
18
18
  "test/viceIntegration.test.mjs",
19
19
  "test/viceModule.test.mjs",
20
20
  "test/groupedToolsShims.test.mjs",
21
+ "test/inputModule.test.mjs",
22
+ "test/batchAndDisplayState.test.mjs",
21
23
  "test/toolsTypes.test.mjs",
22
24
  "test/platformRegistry.test.mjs",
23
25
  "test/meta/program.test.mjs",
@@ -40,6 +42,11 @@ const supplementalTests = [
40
42
  "test/toolsCoverage.test.mjs",
41
43
  "test/audioModule.test.mjs",
42
44
  "test/updateReadme.test.mjs",
45
+ "test/toolsSchema.test.mjs",
46
+ "test/symbolRegistry.test.mjs",
47
+ "test/programRunnersModule.test.mjs",
48
+ "test/batchAndDisplayState.test.mjs",
49
+ "test/inputModule.test.mjs",
43
50
  "test/viceIntegration.test.mjs",
44
51
  ];
45
52
 
@@ -16,6 +16,8 @@ const DEFAULT_VICE_MOCK_TEST_FILES = [
16
16
  "test/viceIntegration.test.mjs",
17
17
  "test/viceModule.test.mjs",
18
18
  "test/groupedToolsShims.test.mjs",
19
+ "test/inputModule.test.mjs",
20
+ "test/batchAndDisplayState.test.mjs",
19
21
  "test/toolsTypes.test.mjs",
20
22
  "test/platformRegistry.test.mjs",
21
23
  "test/meta/program.test.mjs",
@@ -142,6 +142,8 @@ type GroupedOperation = {
142
142
  readonly op: string;
143
143
  readonly description: string;
144
144
  readonly required: readonly string[];
145
+ readonly optional: readonly string[];
146
+ readonly properties: Readonly<Record<string, JsonSchema | undefined>>;
145
147
  readonly notes: readonly string[];
146
148
  };
147
149
 
@@ -165,11 +167,27 @@ function toTableValue(values: readonly string[]): string {
165
167
  return values.join(", ");
166
168
  }
167
169
 
170
+ function formatInputName(name: string, schema?: JsonSchema): string {
171
+ const defaultSuffix = schema && Object.prototype.hasOwnProperty.call(schema, "default")
172
+ ? `=${JSON.stringify(schema.default)}`
173
+ : "";
174
+ return `\`${name}${defaultSuffix}\``;
175
+ }
176
+
177
+ function formatInputs(names: readonly string[], properties: Readonly<Record<string, JsonSchema | undefined>>): string {
178
+ return toTableValue(names.map((name) => formatInputName(name, properties[name])));
179
+ }
180
+
168
181
  function collectGroupedOperations(schema?: JsonSchema): readonly GroupedOperation[] {
169
182
  if (!schema || !isObject(schema)) {
170
183
  return [];
171
184
  }
172
185
 
186
+ const metadataOperations = collectFromOperationMetadata(schema);
187
+ if (metadataOperations.length > 0) {
188
+ return metadataOperations;
189
+ }
190
+
173
191
  const discriminator = (schema as JsonSchema & { discriminator?: { propertyName?: string } }).discriminator;
174
192
  const variants = (schema as JsonSchema & { oneOf?: readonly JsonSchema[] }).oneOf;
175
193
 
@@ -180,6 +198,57 @@ function collectGroupedOperations(schema?: JsonSchema): readonly GroupedOperatio
180
198
  return collectFromFlattenedSchema(schema);
181
199
  }
182
200
 
201
+ function collectFromOperationMetadata(schema: JsonSchema): readonly GroupedOperation[] {
202
+ const metadata = (schema as JsonSchema & {
203
+ readonly "x-c64bridge-operations"?: readonly unknown[];
204
+ })["x-c64bridge-operations"];
205
+
206
+ if (!Array.isArray(metadata)) {
207
+ return [];
208
+ }
209
+
210
+ const operations: GroupedOperation[] = [];
211
+
212
+ for (const entry of metadata) {
213
+ if (!isObject(entry)) {
214
+ continue;
215
+ }
216
+
217
+ const opName = getString(entry.op);
218
+ if (!opName) {
219
+ continue;
220
+ }
221
+
222
+ const inputSchema = isObject(entry.inputSchema) ? (entry.inputSchema as JsonSchema) : undefined;
223
+ const properties = (inputSchema?.properties ?? {}) as Record<string, JsonSchema | undefined>;
224
+ const requiredProps = Array.isArray(entry.required)
225
+ ? entry.required.filter((name): name is string => typeof name === "string" && name !== "op")
226
+ : [];
227
+ const optionalProps = Array.isArray(entry.optional)
228
+ ? entry.optional.filter((name): name is string => typeof name === "string" && name !== "op")
229
+ : Object.keys(properties).filter((name) => name !== "op" && !requiredProps.includes(name));
230
+
231
+ const notes: string[] = [];
232
+ const hasVerificationProperty = Object.keys(properties).some((name) =>
233
+ name.toLowerCase().startsWith("verify"),
234
+ );
235
+ if (hasVerificationProperty) {
236
+ notes.push("supports verify");
237
+ }
238
+
239
+ operations.push({
240
+ op: opName,
241
+ description: getString(entry.description, `Operation ${opName}`),
242
+ required: requiredProps,
243
+ optional: optionalProps,
244
+ properties,
245
+ notes,
246
+ });
247
+ }
248
+
249
+ return operations;
250
+ }
251
+
183
252
  function collectFromVariantList(variants: readonly JsonSchema[]): readonly GroupedOperation[] {
184
253
  const operations: GroupedOperation[] = [];
185
254
 
@@ -224,6 +293,8 @@ function collectFromVariantList(variants: readonly JsonSchema[]): readonly Group
224
293
  op: opName,
225
294
  description,
226
295
  required: requiredProps,
296
+ optional: Object.keys(properties).filter((name) => name !== "op" && !requiredProps.includes(name)),
297
+ properties,
227
298
  notes,
228
299
  });
229
300
  }
@@ -258,6 +329,8 @@ function collectFromFlattenedSchema(schema: JsonSchema): readonly GroupedOperati
258
329
  op: opName,
259
330
  description: descriptionMap.get(opName) ?? `Operation ${opName}`,
260
331
  required: [] as readonly string[],
332
+ optional: Object.keys(properties).filter((name) => name !== "op"),
333
+ properties,
261
334
  notes,
262
335
  }));
263
336
  }
@@ -302,6 +375,9 @@ export function renderToolsSection(modules: readonly ToolModuleDescriptor[] = de
302
375
  if (operations.length === 0) {
303
376
  lines.push("_No operations defined._");
304
377
  } else {
378
+ if (!lines.includes("_Address range convention: `address` + `length` means start address plus byte count; `startAddress` + `endAddress` means inclusive bounds._")) {
379
+ lines.splice(2, 0, "_Address range convention: `address` + `length` means start address plus byte count; `startAddress` + `endAddress` means inclusive bounds._", "");
380
+ }
305
381
  const toolPlatforms: readonly string[] = tool.metadata.platforms ?? ["c64u"];
306
382
  const opPlatformOverrides: Record<string, readonly string[]> = tool.metadata.operationPlatforms ?? {};
307
383
  const operationRows = operations
@@ -312,14 +388,15 @@ export function renderToolsSection(modules: readonly ToolModuleDescriptor[] = de
312
388
  return [
313
389
  `\`${operation.op}\``,
314
390
  escapeCell(operation.description),
315
- escapeCell(toTableValue(operation.required.map((name) => `\`${name}\``))),
391
+ escapeCell(formatInputs(operation.required, operation.properties)),
392
+ escapeCell(formatInputs(operation.optional, operation.properties)),
316
393
  operation.notes.length ? escapeCell(operation.notes.join(", ")) : "—",
317
394
  effectivePlatforms.includes("c64u") ? "✅" : "",
318
395
  effectivePlatforms.includes("vice") ? "✅" : "",
319
396
  ];
320
397
  });
321
398
 
322
- lines.push(renderTable(["Operation", "Description", "Required Inputs", "Notes", "C64U", "VICE"], operationRows));
399
+ lines.push(renderTable(["Operation", "Description", "Required Inputs", "Optional Inputs", "Notes", "C64U", "VICE"], operationRows));
323
400
  }
324
401
 
325
402
  lines.push("");
package/server.json CHANGED
@@ -8,12 +8,12 @@
8
8
  "source": "github"
9
9
  },
10
10
  "websiteUrl": "https://github.com/chrisgleissner/c64bridge",
11
- "version": "0.9.0",
11
+ "version": "0.9.1",
12
12
  "packages": [
13
13
  {
14
14
  "registryType": "npm",
15
15
  "identifier": "c64bridge",
16
- "version": "0.9.0",
16
+ "version": "0.9.1",
17
17
  "transport": {
18
18
  "type": "stdio"
19
19
  },