@henols/vice-mcp 0.2.0 → 0.2.2

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 +2 -1
  2. package/THIRD-PARTY-NOTICES.md +1 -1
  3. package/anno-acme-ident.ts +97 -0
  4. package/anno-cli.ts +1465 -0
  5. package/anno-confidence.ts +233 -0
  6. package/anno-coverage.ts +2465 -0
  7. package/anno-d64.ts +310 -0
  8. package/anno-derive.ts +590 -0
  9. package/anno-details.ts +169 -0
  10. package/anno-enum-gen.ts +533 -0
  11. package/anno-export-asm.ts +1310 -0
  12. package/anno-index.ts +150 -0
  13. package/anno-memmap-render.ts +672 -0
  14. package/anno-regbits-gen.ts +421 -0
  15. package/anno-regbits.json +1370 -0
  16. package/anno-register.ts +240 -0
  17. package/anno-store.ts +3486 -0
  18. package/anno-symbols.ts +266 -0
  19. package/anno-tools.ts +2111 -0
  20. package/anno-types.ts +1636 -0
  21. package/block-class.ts +201 -0
  22. package/build.ts +1 -1
  23. package/capability-registry.ts +3 -1
  24. package/disasm-decoder.ts +14 -14
  25. package/disasm-opcodes.ts +4 -4
  26. package/disasm-renderer.ts +2 -2
  27. package/hostpath.ts +1 -1
  28. package/install-resources.ts +1 -1
  29. package/package.json +23 -3
  30. package/prg-image.ts +119 -0
  31. package/repo-root.ts +20 -5
  32. package/resources/broker-launch.mjs +8 -4
  33. package/resources/vice-launcher.sh +3 -3
  34. package/stock-address.ts +5 -5
  35. package/stock-cia.ts +2 -2
  36. package/stock-condition.ts +7 -7
  37. package/stock-connect.ts +1 -1
  38. package/stock-dispatch.ts +35 -5
  39. package/stock-execution.ts +5 -3
  40. package/stock-input.ts +9 -9
  41. package/stock-machine.ts +17 -6
  42. package/stock-protocol.ts +16 -11
  43. package/stock-registers.ts +54 -29
  44. package/stock-sprites.ts +3 -3
  45. package/stock-symbols.ts +33 -9
  46. package/stock-timing.ts +1 -1
  47. package/stock-vicii.ts +1 -1
  48. package/version.ts +1 -1
  49. package/vice-proxy.ts +168 -0
@@ -0,0 +1,233 @@
1
+ #!/usr/bin/env node
2
+ // anno-confidence.ts -- the ONE authoritative place in this repo for D-25's
3
+ // confidence-grade convention: a machine-readable bracket-token prefix inside
4
+ // an anno line comment (e.g. `[confirmed-code] observed executing at $0810`).
5
+ //
6
+ // WHY THIS MODULE EXISTS: anno's own `BlockType` (twelve variants -- Code,
7
+ // Byte, Word, Address, PETSCII, Screencode, four split-table variants,
8
+ // ExternalFile, Undefined; `types.rs:314-331`) carries CLASSIFICATION but no
9
+ // CONFIDENCE axis. `Code` cannot distinguish "PC observed executing" from
10
+ // "reachable via a JSR, never run" -- that distinction is
11
+ // `memory-map.template.md`'s most deliberate feature, and its own text
12
+ // forbids promoting a row by editing its grade (re-verify and restate the
13
+ // evidence instead). Measured (D-25): anno line comments persist through
14
+ // save/reload (`user_line_comments`), and both `anno_get_comments` and
15
+ // `anno_search_disassembly` (which searches comments by default) can filter
16
+ // on a leading token -- so "show me everything still [unknown]" is a real
17
+ // query today, with NO new storage.
18
+ //
19
+ // WHAT THIS IS THE ONE AUTHORITATIVE PLACE FOR:
20
+ // - the five-grade vocabulary (`CONFIDENCE_GRADES`), copied verbatim from
21
+ // `src/skills/c64-program-recon/templates/memory-map.template.md`'s
22
+ // own confidence table -- nowhere else in this repo may hand-write one
23
+ // of these five phrases or bracket tokens as a second copy;
24
+ // - the parser (`parseConfidencePrefix`) that decides whether a comment
25
+ // carries a grade, an ungraded plain comment, or a TYPO'D near-miss that
26
+ // must fail loudly;
27
+ // - the composer (`formatConfidenceComment`) that writes a graded comment,
28
+ // so no caller invents its own spelling of a bracket token;
29
+ // - the query builder (`searchQueryForGrade`) that gives the "still
30
+ // [grade]" search exactly one spelling.
31
+ //
32
+ // THE POINT OF THIS MODULE, STATED PLAINLY: a comment beginning with a
33
+ // bracket token that is NOT exactly one of the five valid tokens must THROW,
34
+ // naming the offending token and listing the five valid ones. A comment with
35
+ // no leading bracket at all is a legal, ungraded comment (`grade: null`) --
36
+ // that is not an error. What must NEVER happen is a TYPO silently degrading
37
+ // into an ungraded comment, because that is exactly how an `[unknown]` row
38
+ // could disappear from the "still unknown" query without anyone noticing.
39
+ //
40
+ // WHAT NOT TO DO, named concretely:
41
+ // - Never accept a near-miss token (wrong case, an underscore instead of a
42
+ // hyphen, a plural, extra whitespace inside the brackets, a genuine
43
+ // typo). Every one of those must throw `AnnoConfidenceGradeError`, not
44
+ // silently degrade to `grade: null`.
45
+ // - Never add a second, address-keyed sidecar store for grades (T-11-
46
+ // SECOND-STORE). Grades live ONLY as this bracket-token prefix inside
47
+ // anno's own line comments -- a second store keyed by address is
48
+ // exactly the drift class criterion 1 exists to close, and it would not
49
+ // be queryable through the same `anno_get_comments` /
50
+ // `anno_search_disassembly` tools this module's whole design depends
51
+ // on.
52
+ // - Never promote a row by editing its grade in place. The template's own
53
+ // text says so, and this module has no "upgrade" or "promote" function
54
+ // by design -- a caller who wants to change a grade calls
55
+ // `anno_set_comment` again with a freshly composed
56
+ // `formatConfidenceComment()` string, leaving a new comment (or
57
+ // replacing the old one explicitly), never a silent in-place mutation
58
+ // this module would hide.
59
+ // - Never widen `CONFIDENCE_GRADES` without updating
60
+ // `memory-map.template.md`'s own table first -- the template is the
61
+ // source of the vocabulary, this module is its one authoritative
62
+ // runtime copy, and the non-vacuity test below fails if the two drift.
63
+
64
+ export interface ConfidenceGrade {
65
+ /** The bracket token's inner text, e.g. `"confirmed-code"` -- no brackets. */
66
+ readonly token: string;
67
+ /** The full bracket token as it appears in a comment, e.g. `"[confirmed-code]"`. */
68
+ readonly bracket: string;
69
+ /** The human phrase from `memory-map.template.md`'s own confidence table,
70
+ * e.g. `"confirmed code"` (no hyphen -- this is prose, not an identifier). */
71
+ readonly phrase: string;
72
+ /** What the grade means, copied verbatim from the template's "Means" column. */
73
+ readonly meaning: string;
74
+ }
75
+
76
+ /**
77
+ * The five grades from `memory-map.template.md`'s confidence table, in the
78
+ * template's own order. This is the ONE place the vocabulary is written
79
+ * down -- see the module header's "what NOT to do" list.
80
+ */
81
+ export const CONFIDENCE_GRADES: readonly ConfidenceGrade[] = [
82
+ {
83
+ token: "confirmed-code",
84
+ bracket: "[confirmed-code]",
85
+ phrase: "confirmed code",
86
+ meaning: "Executed during tracing, PC observed inside it",
87
+ },
88
+ {
89
+ token: "probable-code",
90
+ bracket: "[probable-code]",
91
+ phrase: "probable code",
92
+ meaning: "Reachable through a JSR/JMP/vector, not yet observed executing",
93
+ },
94
+ {
95
+ token: "confirmed-data",
96
+ bracket: "[confirmed-data]",
97
+ phrase: "confirmed data",
98
+ meaning: "Never hit as an instruction stream across full gameplay coverage",
99
+ },
100
+ {
101
+ token: "probable-data",
102
+ bracket: "[probable-data]",
103
+ phrase: "probable data",
104
+ meaning:
105
+ "Indexed-load target, or matches a data shape (sprite blocks, PETSCII, address tables)",
106
+ },
107
+ {
108
+ token: "unknown",
109
+ bracket: "[unknown]",
110
+ phrase: "unknown",
111
+ meaning: "No reliable interpretation yet",
112
+ },
113
+ ] as const;
114
+
115
+ /** Every valid bracket token, e.g. `["[confirmed-code]", ..., "[unknown]"]`. */
116
+ const VALID_BRACKETS: readonly string[] = CONFIDENCE_GRADES.map((g) => g.bracket);
117
+
118
+ /** Every valid inner token, e.g. `["confirmed-code", ..., "unknown"]`. */
119
+ const VALID_TOKENS: readonly string[] = CONFIDENCE_GRADES.map((g) => g.token);
120
+
121
+ const GRADE_BY_TOKEN: ReadonlyMap<string, ConfidenceGrade> = new Map(
122
+ CONFIDENCE_GRADES.map((g) => [g.token, g]),
123
+ );
124
+
125
+ export interface AnnoConfidenceGradeErrorOptions {
126
+ /** The raw text found between the leading `[` and `]`, verbatim -- may
127
+ * carry the wrong case, stray whitespace, an underscore, or a plural, so a
128
+ * caller can see exactly what was rejected. */
129
+ offendingToken: string;
130
+ }
131
+
132
+ /**
133
+ * Thrown by `parseConfidencePrefix()` when a comment begins with a bracket
134
+ * token that is not exactly one of `CONFIDENCE_GRADES`'s five. Named,
135
+ * carries the offending token as a field, and its message lists all five
136
+ * valid tokens -- mirroring `anno-launch.ts`'s `AnnoViceFlagError` shape
137
+ * (a named error over a malformed token, rather than a silent strip).
138
+ */
139
+ export class AnnoConfidenceGradeError extends Error {
140
+ offendingToken: string;
141
+
142
+ constructor(message: string, { offendingToken }: AnnoConfidenceGradeErrorOptions) {
143
+ super(message);
144
+ this.name = "AnnoConfidenceGradeError";
145
+ this.offendingToken = offendingToken;
146
+ }
147
+ }
148
+
149
+ export interface ParsedConfidencePrefix {
150
+ /** The matched grade, or `null` for a legal, ungraded plain comment. */
151
+ grade: ConfidenceGrade | null;
152
+ /** The comment text with the leading bracket token (and one following
153
+ * run of whitespace, if any) stripped. Equal to the input when `grade` is
154
+ * `null`. */
155
+ rest: string;
156
+ }
157
+
158
+ /**
159
+ * Extracts a leading `[...]` bracket token from `comment` and resolves it
160
+ * against `CONFIDENCE_GRADES`.
161
+ *
162
+ * - No leading bracket at all (the comment does not start with `[`, or has
163
+ * no closing `]`): returns `{ grade: null, rest: comment }`. A comment
164
+ * with no attempted grade token is legal and ungraded -- this is not an
165
+ * error.
166
+ * - A leading bracket token that matches exactly one of the five valid
167
+ * tokens: returns `{ grade, rest }` with `rest` being the remainder after
168
+ * the bracket and one run of following whitespace.
169
+ * - A leading bracket token that does NOT match exactly one of the five
170
+ * (wrong case, an underscore, a plural, stray whitespace inside the
171
+ * brackets, or a plain typo): THROWS `AnnoConfidenceGradeError`, naming
172
+ * the offending token and listing the five valid ones. This is the whole
173
+ * point of the module -- see the header comment.
174
+ */
175
+ export function parseConfidencePrefix(comment: string): ParsedConfidencePrefix {
176
+ const match = /^\[([^[\]]*)\](\s*)/.exec(comment);
177
+ if (!match) {
178
+ return { grade: null, rest: comment };
179
+ }
180
+
181
+ const innerToken = match[1]!;
182
+ const grade = GRADE_BY_TOKEN.get(innerToken);
183
+ if (!grade) {
184
+ throw new AnnoConfidenceGradeError(
185
+ `"[${innerToken}]" is not a valid confidence grade -- the five valid tokens are ` +
186
+ `${VALID_BRACKETS.join(", ")}. A near-miss (wrong case, an underscore instead of a hyphen, a ` +
187
+ "plural, stray whitespace inside the brackets, or a plain typo) is refused rather than " +
188
+ "silently treated as an ungraded comment, because that is exactly how an [unknown] row " +
189
+ "could disappear from the \"still unknown\" query without anyone noticing.",
190
+ { offendingToken: innerToken },
191
+ );
192
+ }
193
+
194
+ const consumed = match[0]!.length;
195
+ return { grade, rest: comment.slice(consumed) };
196
+ }
197
+
198
+ /**
199
+ * Composes a graded comment: the grade's bracket token, one space, then
200
+ * `evidence`. The ONE place a graded comment is assembled, so no caller
201
+ * invents its own spelling of a bracket token.
202
+ */
203
+ export function formatConfidenceComment(grade: string, evidence: string): string {
204
+ const found = GRADE_BY_TOKEN.get(grade);
205
+ if (!found) {
206
+ throw new AnnoConfidenceGradeError(
207
+ `"${grade}" is not a valid confidence grade token -- the five valid tokens are ` +
208
+ `${VALID_TOKENS.join(", ")}.`,
209
+ { offendingToken: grade },
210
+ );
211
+ }
212
+ return `${found.bracket} ${evidence}`;
213
+ }
214
+
215
+ /**
216
+ * Returns the literal search string that appears verbatim in every comment
217
+ * carrying `grade` -- the bracket token itself, e.g. `"[unknown]"`. Passing
218
+ * this to `anno_search_disassembly`'s `query` (with `use_regex` left
219
+ * false/omitted) lists every address still carrying that grade. One
220
+ * spelling, so "show me everything still [unknown]" never has two competing
221
+ * queries drifting apart.
222
+ */
223
+ export function searchQueryForGrade(grade: string): string {
224
+ const found = GRADE_BY_TOKEN.get(grade);
225
+ if (!found) {
226
+ throw new AnnoConfidenceGradeError(
227
+ `"${grade}" is not a valid confidence grade token -- the five valid tokens are ` +
228
+ `${VALID_TOKENS.join(", ")}.`,
229
+ { offendingToken: grade },
230
+ );
231
+ }
232
+ return found.bracket;
233
+ }