@henols/vice-mcp 0.2.0 → 0.2.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/THIRD-PARTY-NOTICES.md +23 -0
- package/package.json +15 -1
- package/r2000-acme-ident.ts +97 -0
- package/r2000-cli.ts +1103 -0
- package/r2000-confidence.ts +233 -0
- package/r2000-d64.ts +310 -0
- package/r2000-enum-gen.ts +574 -0
- package/r2000-launch.ts +357 -0
- package/r2000-mcp-client.ts +596 -0
- package/r2000-memmap-render.ts +531 -0
- package/r2000-project.ts +190 -0
- package/r2000-regbits-gen.ts +416 -0
- package/r2000-regbits.json +1370 -0
- package/r2000-symbols.ts +388 -0
- package/r2000-tools.ts +914 -0
- package/r2000-verify.ts +184 -0
- package/stock-symbols.ts +33 -9
- package/vice-proxy.ts +146 -0
package/THIRD-PARTY-NOTICES.md
CHANGED
|
@@ -75,6 +75,29 @@ package**, so ACME's licence does not attach to anything shipped. ACME never
|
|
|
75
75
|
appears in `.claude/mcp/vice/package.json`'s `files[]`, `dependencies`, or
|
|
76
76
|
`devDependencies` — it is an apt/CI-installed tool, never an npm package.
|
|
77
77
|
|
|
78
|
+
## Build/CI tools — not incorporated: regenerator2000
|
|
79
|
+
|
|
80
|
+
regenerator2000 is invoked as an **external CLI subprocess** (Phase 10's
|
|
81
|
+
`R2000-09` bootstrap and `R2000-06` reassembly proof) against a real,
|
|
82
|
+
locally-installed `regenerator2000` binary. **No regenerator2000 source,
|
|
83
|
+
data table, or output is included in this repository or in either
|
|
84
|
+
published package**, so its licence does not attach to anything shipped.
|
|
85
|
+
|
|
86
|
+
Its licence is **`MIT OR Apache-2.0`** — dual, at the user's option —
|
|
87
|
+
confirmed from the crate's own crates.io licence field, with both
|
|
88
|
+
`LICENSE-MIT` and `LICENSE-APACHE` shipping in the crate. (Do not read this
|
|
89
|
+
as Apache-2.0 alone: that stale, single-licence claim is what `R2000-03`'s
|
|
90
|
+
own requirement text and `.planning/notes/regenerator2000-integration.md`
|
|
91
|
+
still carried before Phase 10 corrected it here.)
|
|
92
|
+
|
|
93
|
+
Verified version `0.9.20`, published 2026-07-11 by `ricardoquesada`
|
|
94
|
+
(matching the linked GitHub repository owner), checked 2026-08-20 — so this
|
|
95
|
+
provenance claim is re-checkable against a specific release.
|
|
96
|
+
|
|
97
|
+
regenerator2000 never appears in `.claude/mcp/vice/package.json`'s
|
|
98
|
+
`files[]`, `dependencies`, or `devDependencies` — it is a `cargo
|
|
99
|
+
install`-provided tool, never an npm package.
|
|
100
|
+
|
|
78
101
|
## Explicitly NOT a source: VICE
|
|
79
102
|
|
|
80
103
|
VICE is GPL-2 and this repository is MIT. **No opcode fact, protocol
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@henols/vice-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "VICE emulator MCP server for C64 reverse-engineering: a stdio MCP server that proxies vice tools to a host VICE MCP server.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -53,6 +53,20 @@
|
|
|
53
53
|
"stock-run-until.ts",
|
|
54
54
|
"stock-diagnose.ts",
|
|
55
55
|
"stock-recycle.ts",
|
|
56
|
+
"r2000-launch.ts",
|
|
57
|
+
"r2000-project.ts",
|
|
58
|
+
"r2000-d64.ts",
|
|
59
|
+
"r2000-cli.ts",
|
|
60
|
+
"r2000-verify.ts",
|
|
61
|
+
"r2000-mcp-client.ts",
|
|
62
|
+
"r2000-tools.ts",
|
|
63
|
+
"r2000-symbols.ts",
|
|
64
|
+
"r2000-regbits-gen.ts",
|
|
65
|
+
"r2000-regbits.json",
|
|
66
|
+
"r2000-enum-gen.ts",
|
|
67
|
+
"r2000-acme-ident.ts",
|
|
68
|
+
"r2000-confidence.ts",
|
|
69
|
+
"r2000-memmap-render.ts",
|
|
56
70
|
"resources",
|
|
57
71
|
"tools-manifest.json",
|
|
58
72
|
"tools-manifest.stock.json",
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// r2000-acme-ident.ts -- the ONE authoritative place in this repo for the
|
|
3
|
+
// ACME identifier policy (T-11-ENUM-NAME / T-11-NAME-INJECT): what makes a
|
|
4
|
+
// string a legal ACME symbol/label name, and the single check function that
|
|
5
|
+
// decides it.
|
|
6
|
+
//
|
|
7
|
+
// WHY THIS MODULE EXISTS: this policy started life inside r2000-enum-gen.ts,
|
|
8
|
+
// consumed only by its own `createOrUpdateEnum()`/`sanitizeVariantMap()`.
|
|
9
|
+
// T-11-NAME-INJECT widened the finding to a SECOND entry route --
|
|
10
|
+
// `r2000_set_label_name` (both outer and batch-inner) in r2000-tools.ts, and
|
|
11
|
+
// `importLabels()` in r2000-symbols.ts -- and `r2000-enum-gen.ts` statically
|
|
12
|
+
// imports `runR2000Tool` FROM `r2000-tools.ts`, so `r2000-tools.ts` cannot
|
|
13
|
+
// import the policy back from `r2000-enum-gen.ts` without forming a module
|
|
14
|
+
// cycle. This module has no import from anywhere else in this repo, so
|
|
15
|
+
// every one of those consumers (and any future one) can import it directly.
|
|
16
|
+
//
|
|
17
|
+
// WHAT THIS IS THE ONE AUTHORITATIVE PLACE FOR: `MAX_ACME_IDENTIFIER_LENGTH`,
|
|
18
|
+
// `ACME_IDENT_RE`, `ACME_RESERVED_MNEMONICS` and `assertLegalAcmeIdentifier()`
|
|
19
|
+
// -- the complete, only definition of "legal ACME identifier" in this repo.
|
|
20
|
+
// `r2000-enum-gen.ts` re-exports `assertLegalAcmeIdentifier` /
|
|
21
|
+
// `MAX_ACME_IDENTIFIER_LENGTH` from here so its own existing consumers and
|
|
22
|
+
// tests keep their current import path; it does not hold a second copy.
|
|
23
|
+
//
|
|
24
|
+
// WHAT NOT TO DO, named concretely:
|
|
25
|
+
// - Never add a second identifier regex anywhere in this repo. The
|
|
26
|
+
// `r2000-regbits-gen.ts` / `r2000-regbits.test.ts` copies of
|
|
27
|
+
// `ACME_IDENT_RE` predate this module and are out of this plan's scope
|
|
28
|
+
// (260821-a86) to consolidate -- but no NEW copy should be added; import
|
|
29
|
+
// this module's `assertLegalAcmeIdentifier()` instead.
|
|
30
|
+
// - Never sanitize, quote, or auto-correct an illegal identifier here or
|
|
31
|
+
// in any caller. This function's contract is REJECT, per
|
|
32
|
+
// T-11-REGBITS-PROSE and T-11-ENUM-NAME precedent: a malformed name is a
|
|
33
|
+
// bug to surface, never silently rewritten into something else -- the
|
|
34
|
+
// caller-visible name must never diverge from what actually gets
|
|
35
|
+
// exported into ACME source.
|
|
36
|
+
// - Never import anything from this repo into this module. It must stay
|
|
37
|
+
// importable by both `r2000-tools.ts` and `r2000-enum-gen.ts` (which
|
|
38
|
+
// imports `runR2000Tool` FROM `r2000-tools.ts`) without a cycle.
|
|
39
|
+
export const MAX_ACME_IDENTIFIER_LENGTH = 200;
|
|
40
|
+
|
|
41
|
+
const ACME_IDENT_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* The 6502/6510 instruction mnemonics -- the ONLY category of reserved word
|
|
45
|
+
* actually measured to collide with a bare identifier in real ACME 0.97.
|
|
46
|
+
* Verified live on this host: `LDA = $05` is REJECTED ("No value given." /
|
|
47
|
+
* "Garbage data at end of statement" -- ACME parses `LDA` positionally as
|
|
48
|
+
* the opcode, not as an assignable symbol), while `A = $05` is ACCEPTED
|
|
49
|
+
* (register-letter shorthand is not reserved as a bare symbol name). This
|
|
50
|
+
* list is therefore a measured, not a guessed, reservation.
|
|
51
|
+
*/
|
|
52
|
+
const ACME_RESERVED_MNEMONICS: ReadonlySet<string> = new Set([
|
|
53
|
+
"ADC", "AND", "ASL", "BCC", "BCS", "BEQ", "BIT", "BMI", "BNE", "BPL", "BRK", "BVC",
|
|
54
|
+
"BVS", "CLC", "CLD", "CLI", "CLV", "CMP", "CPX", "CPY", "DEC", "DEX", "DEY", "EOR",
|
|
55
|
+
"INC", "INX", "INY", "JMP", "JSR", "LDA", "LDX", "LDY", "LSR", "NOP", "ORA", "PHA",
|
|
56
|
+
"PHP", "PLA", "PLP", "ROL", "ROR", "RTI", "RTS", "SBC", "SEC", "SED", "SEI", "STA",
|
|
57
|
+
"STX", "STY", "TAX", "TAY", "TSX", "TXA", "TXS", "TYA",
|
|
58
|
+
]);
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Refuses `id` (naming it as `what` in the thrown message) unless it is a
|
|
62
|
+
* legal ACME identifier: matches `^[A-Za-z_][A-Za-z0-9_]*$`, is no longer
|
|
63
|
+
* than `MAX_ACME_IDENTIFIER_LENGTH`, and does not collide (case-
|
|
64
|
+
* insensitively) with a reserved 6502/6510 mnemonic (see
|
|
65
|
+
* `ACME_RESERVED_MNEMONICS`'s own header comment for how that specific list
|
|
66
|
+
* was measured, not assumed).
|
|
67
|
+
*
|
|
68
|
+
* T-11-ENUM-NAME (the highest-value threat in this phase): regenerator2000
|
|
69
|
+
* validates only the ENUM name server-side
|
|
70
|
+
* (`app_state.rs:443`, `validate_new_enum_name`) and performs ZERO
|
|
71
|
+
* validation on variant names -- they flow straight into
|
|
72
|
+
* `format!("{}_{}", enum_name, variant)` at export time
|
|
73
|
+
* (`formatter_acme.rs:367-369`). This function is called on BOTH the enum
|
|
74
|
+
* name and every variant name, and is called BEFORE any
|
|
75
|
+
* `r2000_create_project_enum`/`r2000_update_project_enum` call reaches
|
|
76
|
+
* `runR2000Tool()` -- proven zero-spawn in `r2000-enum-gen.test.ts`.
|
|
77
|
+
*/
|
|
78
|
+
export function assertLegalAcmeIdentifier(id: string, what: string): void {
|
|
79
|
+
if (id.length === 0) {
|
|
80
|
+
throw new Error(`${what}: identifier must not be empty`);
|
|
81
|
+
}
|
|
82
|
+
if (id.length > MAX_ACME_IDENTIFIER_LENGTH) {
|
|
83
|
+
throw new Error(
|
|
84
|
+
`${what}: identifier "${id.slice(0, 40)}..." is ${id.length} characters, exceeding the ` +
|
|
85
|
+
`${MAX_ACME_IDENTIFIER_LENGTH}-character ceiling`,
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
if (!ACME_IDENT_RE.test(id)) {
|
|
89
|
+
throw new Error(`${what}: "${JSON.stringify(id)}" is not a legal ACME identifier -- must match ${ACME_IDENT_RE}`);
|
|
90
|
+
}
|
|
91
|
+
if (ACME_RESERVED_MNEMONICS.has(id.toUpperCase())) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`${what}: "${id}" collides with the reserved 6502/6510 mnemonic ${id.toUpperCase()} (verified rejected ` +
|
|
94
|
+
`by real ACME 0.97 -- see this module's ACME_RESERVED_MNEMONICS header comment)`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|