@henols/c64-re-tools 2.1.0-rc.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (103) hide show
  1. package/package.json +1 -1
  2. package/skills/c64-assembler/SKILL.md +24 -9
  3. package/skills/c64-assembler/scripts/assembler.ts +95 -0
  4. package/skills/c64-basic/SKILL.md +17 -9
  5. package/skills/c64-basic/scripts/basic.ts +26 -36
  6. package/skills/c64-disk/SKILL.md +17 -7
  7. package/skills/c64-disk/scripts/disk.ts +130 -104
  8. package/skills/c64-disk/scripts/lib/containers.ts +10 -12
  9. package/skills/c64-docs/SKILL.md +47 -28
  10. package/skills/c64-docs/references/style.md +6 -6
  11. package/skills/c64-docs/scripts/docs.ts +323 -0
  12. package/skills/c64-docs/scripts/lib/source-map.ts +1 -1
  13. package/skills/c64-emulator/SKILL.md +11 -7
  14. package/skills/c64-knowledge/SKILL.md +34 -21
  15. package/skills/c64-knowledge/scripts/knowledge.ts +597 -718
  16. package/skills/c64-knowledge/scripts/lib/listing.ts +5 -7
  17. package/skills/c64-memory-map/SKILL.md +18 -10
  18. package/skills/c64-memory-map/scripts/memory-map.ts +81 -0
  19. package/skills/c64-provenance/SKILL.md +33 -24
  20. package/skills/c64-provenance/scripts/lib/compare.ts +8 -12
  21. package/skills/c64-provenance/scripts/lib/leftovers.ts +19 -20
  22. package/skills/c64-provenance/scripts/lib/library.ts +15 -25
  23. package/skills/c64-provenance/scripts/lib/runtime.ts +12 -37
  24. package/skills/c64-provenance/scripts/lib/separate.ts +9 -10
  25. package/skills/c64-provenance/scripts/provenance.ts +177 -279
  26. package/skills/c64-reverse-engineering/SKILL.md +13 -12
  27. package/skills/c64-source/SKILL.md +28 -16
  28. package/skills/c64-source/scripts/lib/loader.ts +52 -77
  29. package/skills/c64-source/scripts/lib/source.ts +33 -42
  30. package/skills/c64-source/scripts/{generate.ts → source.ts} +68 -109
  31. package/skills/c64-static-analysis/SKILL.md +24 -13
  32. package/skills/c64-static-analysis/scripts/lib/coverage.ts +3 -4
  33. package/skills/c64-static-analysis/scripts/lib/findings.ts +2 -2
  34. package/skills/c64-static-analysis/scripts/lib/instructions.ts +1 -1
  35. package/skills/c64-static-analysis/scripts/lib/macros.ts +6 -8
  36. package/skills/c64-static-analysis/scripts/{analyze.ts → static-analysis.ts} +58 -118
  37. package/skills/c64-testing/SKILL.md +48 -32
  38. package/skills/c64-testing/references/recording-format.md +48 -19
  39. package/skills/c64-testing/references/scenario-format.md +24 -19
  40. package/skills/c64-testing/scripts/{diff.ts → lib/diff-files.ts} +18 -69
  41. package/skills/c64-testing/scripts/lib/diff.ts +5 -3
  42. package/skills/c64-testing/scripts/lib/play.ts +244 -54
  43. package/skills/c64-testing/scripts/lib/recording.ts +153 -120
  44. package/skills/c64-testing/scripts/{replay.ts → lib/replay.ts} +28 -86
  45. package/skills/c64-testing/scripts/{run.ts → lib/runs.ts} +36 -59
  46. package/skills/c64-testing/scripts/lib/scenario.ts +73 -81
  47. package/skills/c64-testing/scripts/testing.ts +189 -0
  48. package/skills/c64-unpacker/SKILL.md +42 -25
  49. package/skills/c64-unpacker/scripts/lib/evidence.ts +3 -4
  50. package/skills/c64-unpacker/scripts/lib/loads.ts +12 -10
  51. package/skills/c64-unpacker/scripts/lib/machine.ts +0 -2
  52. package/skills/c64-unpacker/scripts/lib/stages.ts +14 -19
  53. package/skills/c64-unpacker/scripts/{unpack.ts → unpacker.ts} +109 -211
  54. package/src/c64.ts +35 -20
  55. package/src/cli/main.ts +2 -2
  56. package/src/errors.ts +38 -0
  57. package/src/graphics.ts +3 -1
  58. package/src/host/server.ts +3 -2
  59. package/src/host/vice/session.ts +4 -4
  60. package/src/host-client/entry-state.ts +106 -0
  61. package/src/host-client/image.ts +21 -10
  62. package/src/host-client/steps.ts +285 -108
  63. package/src/host-client/transfer.ts +21 -15
  64. package/src/host-client/vice-session.ts +1 -1
  65. package/src/knowledge/database.ts +3 -23
  66. package/src/knowledge/expression.ts +8 -11
  67. package/src/knowledge/history.ts +2 -2
  68. package/src/knowledge/import.ts +13 -14
  69. package/src/knowledge/names.ts +50 -0
  70. package/src/knowledge/program.ts +11 -10
  71. package/src/knowledge/read.ts +16 -21
  72. package/src/knowledge/schema.ts +9 -3
  73. package/src/knowledge/text.ts +5 -5
  74. package/src/knowledge/write.ts +93 -137
  75. package/src/mcp/inputs.ts +105 -0
  76. package/src/mcp/output.ts +2 -13
  77. package/src/mcp/server.ts +12 -60
  78. package/src/mcp/tools/debug.ts +17 -12
  79. package/src/mcp/tools/execution.ts +5 -32
  80. package/src/mcp/tools/input.ts +7 -32
  81. package/src/mcp/tools/media.ts +6 -5
  82. package/src/mcp/tools/memory.ts +11 -38
  83. package/src/mcp/tools/video.ts +6 -5
  84. package/src/native/c64run.ts +1 -1
  85. package/src/native/dxa.ts +7 -6
  86. package/src/native/ghidra/analyze.ts +2 -1
  87. package/src/native/ghidra/index.ts +2 -1
  88. package/src/native/processes.ts +4 -3
  89. package/src/native/status.ts +2 -2
  90. package/src/native/types.ts +3 -7
  91. package/src/opcodes.ts +13 -13
  92. package/src/platform.ts +9 -9
  93. package/src/project.ts +16 -26
  94. package/src/protocol/messages.ts +3 -21
  95. package/src/protocol/vice.ts +7 -7
  96. package/src/script.ts +491 -49
  97. package/skills/c64-assembler/scripts/assemble.ts +0 -138
  98. package/skills/c64-docs/scripts/generate.ts +0 -109
  99. package/skills/c64-docs/scripts/link.ts +0 -239
  100. package/skills/c64-memory-map/scripts/memmap.ts +0 -92
  101. package/skills/c64-testing/scripts/checklist.ts +0 -51
  102. package/skills/c64-testing/scripts/record.ts +0 -96
  103. package/skills/c64-testing/scripts/test.ts +0 -65
@@ -1,96 +0,0 @@
1
- // The c64-testing record script: plays the steps of a record file on the
2
- // original program in the replay core (c64run), and writes the session as a
3
- // recording folder: recording.json, reads.txt, checkpoints.txt, coverage.bin.
4
- // Exit status: 0 recorded, 1 the session did not complete, 2 a bad call.
5
-
6
- import { parseArgs } from "node:util";
7
-
8
- import { COVERAGE } from "#src/c64.ts";
9
- import { writeProjectFile } from "#src/host-client/transfer.ts";
10
- import { C64RunSession, PAL_FRAME_CYCLES } from "#src/native/c64run.ts";
11
- import { localToolContext } from "#src/native/local.ts";
12
- import { Workspace } from "#src/native/staging.ts";
13
- import { resolveProjectPath } from "#src/project.ts";
14
- import { runScript, UsageError } from "#src/script.ts";
15
- import { play } from "./lib/play.ts";
16
- import { record, readRecordFile, RECORDING_FILES } from "./lib/recording.ts";
17
- import { ScenarioError } from "./lib/scenario.ts";
18
-
19
- const USAGE = `record.ts <record.json> --out <folder> [--play [--joystick 1|2] [--http-port <n>]]
20
-
21
- <record.json> is a record file relative to the project folder. See
22
- references/recording-format.md. --out is the recording folder, for example
23
- tests/recordings/<name>. With --play, a person plays after the steps: the
24
- script prints the address of a page on stderr and runs until Stop on the page.
25
- --joystick is the port of the arrow keys, space and the gamepad (default 2).
26
- --http-port is the port of the page (default 6465). The result is one JSON object.`;
27
-
28
- /** The default port of the --play page: next to the Host Runtime's 6464. */
29
- const DEFAULT_HTTP_PORT = 6465;
30
-
31
- async function run(argv: string[]): Promise<Record<string, unknown>> {
32
- const { values, positionals } = parseArgs({
33
- args: argv,
34
- strict: true,
35
- allowPositionals: true,
36
- options: { out: { type: "string" }, play: { type: "boolean" }, joystick: { type: "string" }, "http-port": { type: "string" }, help: { type: "boolean" } },
37
- });
38
- if (values.help) throw new UsageError("");
39
- if (positionals.length !== 1) throw new UsageError("give one record file");
40
- if (values.out === undefined) throw new UsageError("give --out, the recording folder");
41
- try {
42
- resolveProjectPath(values.out);
43
- } catch {
44
- throw new UsageError(`--out must be a path relative to the project folder that stays inside it, not ${values.out}`);
45
- }
46
- if (!values.play && (values.joystick !== undefined || values["http-port"] !== undefined)) throw new UsageError("--joystick and --http-port are for --play");
47
- const joystick = values.joystick === undefined ? 2 : Number(values.joystick);
48
- if (joystick !== 1 && joystick !== 2) throw new UsageError("--joystick must be 1 or 2");
49
- const httpPort = values["http-port"] === undefined ? DEFAULT_HTTP_PORT : Number(values["http-port"]);
50
- if (!Number.isInteger(httpPort) || httpPort < 0 || httpPort > 65535) throw new UsageError("--http-port must be a TCP port from 0 to 65535");
51
- let file;
52
- try {
53
- file = readRecordFile(positionals[0]!);
54
- } catch (error) {
55
- if (error instanceof ScenarioError) throw new UsageError(error.message);
56
- throw error;
57
- }
58
- const context = localToolContext();
59
- const core = await C64RunSession.open(context);
60
- const workspace = Workspace.create(context.supervisor, "c64-re-tools-record-");
61
- try {
62
- let outcome;
63
- try {
64
- const person = values.play
65
- ? (session: C64RunSession) =>
66
- play(session, { httpPort, joystick, ready: (url) => process.stderr.write(`Play at ${url} and press Stop on the page to save the recording.\n`) })
67
- : undefined;
68
- outcome = await record(core, file, workspace, person);
69
- } catch (error) {
70
- if (error instanceof ScenarioError) throw new UsageError(error.message);
71
- throw error;
72
- }
73
- const summary = {
74
- name: file.name,
75
- frames: Math.round(outcome.recording.ticks / PAL_FRAME_CYCLES),
76
- inputSites: outcome.recording.sites.length,
77
- events: outcome.recording.events.length,
78
- // The instructions in the coverage map: 0 when the program never read its input from RAM.
79
- executed: outcome.coverage.reduce((count, byte) => count + ((byte & COVERAGE.ramExecute) === 0 ? 0 : 1), 0),
80
- };
81
- if (outcome.reason !== undefined) {
82
- process.exitCode = 1;
83
- return { recorded: false, reason: outcome.reason, ...summary };
84
- }
85
- const write = (name: string, bytes: Uint8Array) => writeProjectFile(`${values.out}/${name}`, bytes, { what: "--out" });
86
- write(RECORDING_FILES.recording, Buffer.from(`${JSON.stringify(outcome.recording, null, 2)}\n`));
87
- write(RECORDING_FILES.reads, outcome.reads);
88
- write(RECORDING_FILES.coverage, outcome.coverage);
89
- return { recorded: true, out: values.out, ...summary, files: Object.values(RECORDING_FILES) };
90
- } finally {
91
- await core.close();
92
- workspace.remove();
93
- }
94
- }
95
-
96
- await runScript(run, { usage: USAGE });
@@ -1,65 +0,0 @@
1
- // The c64-testing script: runs a scenario on the original and then on the
2
- // rebuild in one emulator, and prints PASS, FAIL or INCONCLUSIVE with the
3
- // differences. Exit status: 0 PASS, 1 FAIL, 3 INCONCLUSIVE, 2 a bad call.
4
-
5
- import { parseArgs } from "node:util";
6
-
7
- import { ViceSessionClient } from "#src/host-client/vice-session.ts";
8
- import { WireFailure } from "#src/host-client/tools.ts";
9
- import { resolveProjectPath } from "#src/project.ts";
10
- import { runScript, UsageError } from "#src/script.ts";
11
- import { readScenario, runScenario, ScenarioError, type ScenarioResult } from "./lib/scenario.ts";
12
-
13
- const USAGE = `test.ts <scenario.json> [--out <dir>]
14
-
15
- <scenario.json> is a scenario file relative to the project folder. See
16
- references/scenario-format.md. With --out, a FAIL writes both screens, the
17
- difference image and memory.json with each differing byte into <dir>. The
18
- result is one JSON object.`;
19
-
20
- const EXIT = { PASS: 0, FAIL: 1, INCONCLUSIVE: 3 } as const;
21
-
22
- async function run(argv: string[]): Promise<ScenarioResult> {
23
- const { values, positionals } = parseArgs({ args: argv, strict: true, allowPositionals: true, options: { out: { type: "string" }, help: { type: "boolean" } } });
24
- if (values.help) throw new UsageError("");
25
- if (positionals.length !== 1) throw new UsageError("give one scenario file");
26
- if (values.out !== undefined) {
27
- try {
28
- resolveProjectPath(values.out);
29
- } catch {
30
- throw new UsageError(`--out must be a path relative to the project folder that stays inside it, not ${values.out}`);
31
- }
32
- }
33
- try {
34
- return await runScenarioFile(positionals[0]!, values.out);
35
- } catch (error) {
36
- // A scenario or symbol file that is not usable is a bad call.
37
- if (error instanceof ScenarioError) throw new UsageError(error.message);
38
- throw error;
39
- }
40
- }
41
-
42
- async function runScenarioFile(path: string, out: string | undefined): Promise<ScenarioResult> {
43
- const scenario = readScenario(path);
44
- let client: ViceSessionClient;
45
- try {
46
- client = await ViceSessionClient.open({ videoStandard: scenario.videoStandard ?? "pal" });
47
- } catch (error) {
48
- if (!(error instanceof WireFailure)) throw error;
49
- return { result: "INCONCLUSIVE", scenario: scenario.name, reason: `no emulator: ${error.message}`, checkpoints: [], differences: [] };
50
- }
51
- try {
52
- return await runScenario(client, scenario, out === undefined ? {} : { out });
53
- } finally {
54
- await client.close();
55
- }
56
- }
57
-
58
- await runScript(
59
- async (argv) => {
60
- const result = await run(argv);
61
- process.exitCode = EXIT[result.result];
62
- return result;
63
- },
64
- { usage: USAGE },
65
- );