c64bridge 0.9.3 → 1.0.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/AGENTS.md +19 -3
- package/README.md +190 -148
- package/dist/.tsbuildinfo +1 -1
- package/dist/c64Client.js +277 -41
- package/dist/config.js +30 -18
- package/dist/device.js +191 -125
- package/dist/knowledge.js +1 -1
- package/dist/loggingHttpClient.js +15 -3
- package/dist/mcp-server.js +65 -16
- package/dist/platform.js +13 -2
- package/dist/rag/indexer.js +11 -8
- package/dist/rag/init.js +11 -8
- package/dist/sidwaveCompiler.js +2 -2
- package/dist/tools/audio.js +27 -6
- package/dist/tools/developer.js +6 -6
- package/dist/tools/graphics.js +4 -4
- package/dist/tools/input.js +136 -24
- package/dist/tools/machineControl.js +85 -6
- package/dist/tools/memory.js +21 -6
- package/dist/tools/meta/artifacts.js +20 -8
- package/dist/tools/meta/background.js +11 -1
- package/dist/tools/meta/index.js +1 -1
- package/dist/tools/pollValidator.js +19 -51
- package/dist/tools/printer.js +1 -0
- package/dist/tools/programRunners.js +5 -5
- package/dist/tools/rag.js +1 -1
- package/dist/tools/registry/batch.js +1 -1
- package/dist/tools/registry/config.js +5 -5
- package/dist/tools/registry/disk.js +2 -2
- package/dist/tools/registry/drive.js +2 -2
- package/dist/tools/registry/graphics.js +2 -2
- package/dist/tools/registry/memory.js +2 -2
- package/dist/tools/registry/platform.js +9 -5
- package/dist/tools/registry/printer.js +1 -0
- package/dist/tools/registry/program.js +5 -5
- package/dist/tools/registry/rag.js +1 -1
- package/dist/tools/registry/sound.js +4 -4
- package/dist/tools/registry/system.js +13 -3
- package/dist/tools/storage.js +1 -1
- package/dist/vice/mockServer.js +33 -0
- package/dist/vice/process.js +11 -1
- package/dist/vice/viceClient.js +35 -6
- package/doc/c64u/c64-openapi.yaml +1130 -774
- package/doc/reviews/hardening/01-fable/prompt-handover.md +125 -0
- package/doc/reviews/hardening/01-fable/prompt.md +98 -0
- package/doc/reviews/hardening/01-fable/review-prompt.md +468 -0
- package/doc/reviews/hardening/01-fable/review.md +1234 -0
- package/doc/u2/u2-openapi.yaml +1192 -0
- package/generated/c64/index.js +142 -9
- package/generated/openapi/c64u/index.js +1117 -0
- package/generated/openapi/u2/index.js +929 -0
- package/mcp/schemas/c64_graphics.schema.json +3 -3
- package/mcp/schemas/c64_input.schema.json +249 -8
- package/mcp/schemas/c64_memory.schema.json +3 -3
- package/mcp/schemas/c64_program.schema.json +3 -3
- package/mcp/schemas/c64_select_backend.schema.json +2 -0
- package/mcp/schemas/c64_system.schema.json +41 -1
- package/mcp/server.json +1 -1
- package/mcp/tools.json +386 -44
- package/mcp.json +14 -2
- package/package.json +4 -2
- package/scripts/mockC64Server.mjs +171 -2
- package/scripts/prepare-release.mjs +13 -2
- package/scripts/update-readme.ts +18 -30
- package/server.json +3 -3
package/dist/vice/viceClient.js
CHANGED
|
@@ -53,6 +53,8 @@ export class ViceClient {
|
|
|
53
53
|
}
|
|
54
54
|
rejectAllPending(reason) {
|
|
55
55
|
for (const [, pending] of this.pending) {
|
|
56
|
+
if (pending.timer)
|
|
57
|
+
clearTimeout(pending.timer);
|
|
56
58
|
try {
|
|
57
59
|
pending.reject(reason);
|
|
58
60
|
}
|
|
@@ -66,7 +68,7 @@ export class ViceClient {
|
|
|
66
68
|
// Frame: [0]=0x02, [1]=0x02, [2..5]=len, [6]=respType, [7]=err, [8..11]=reqId, [12..]=body
|
|
67
69
|
while (this.buffer.length >= 12) {
|
|
68
70
|
if (this.buffer[0] !== 0x02 || this.buffer[1] !== 0x02) {
|
|
69
|
-
const idx = this.buffer.indexOf(0x02, 1);
|
|
71
|
+
const idx = this.buffer.indexOf(Buffer.from([0x02, 0x02]), 1);
|
|
70
72
|
this.buffer = idx === -1 ? Buffer.alloc(0) : this.buffer.subarray(idx);
|
|
71
73
|
continue;
|
|
72
74
|
}
|
|
@@ -88,6 +90,8 @@ export class ViceClient {
|
|
|
88
90
|
continue;
|
|
89
91
|
}
|
|
90
92
|
if (err !== 0x00) {
|
|
93
|
+
if (pending.timer)
|
|
94
|
+
clearTimeout(pending.timer);
|
|
91
95
|
pending.reject(new Error(`BM error 0x${err.toString(16)}`));
|
|
92
96
|
this.pending.delete(reqId);
|
|
93
97
|
continue;
|
|
@@ -98,6 +102,8 @@ export class ViceClient {
|
|
|
98
102
|
pending.onFrame(responseType, frame);
|
|
99
103
|
}
|
|
100
104
|
catch (error) {
|
|
105
|
+
if (pending.timer)
|
|
106
|
+
clearTimeout(pending.timer);
|
|
101
107
|
pending.reject(error);
|
|
102
108
|
this.pending.delete(reqId);
|
|
103
109
|
}
|
|
@@ -108,6 +114,8 @@ export class ViceClient {
|
|
|
108
114
|
continue;
|
|
109
115
|
}
|
|
110
116
|
pending.resolve(frame);
|
|
117
|
+
if (pending.timer)
|
|
118
|
+
clearTimeout(pending.timer);
|
|
111
119
|
this.pending.delete(reqId);
|
|
112
120
|
}
|
|
113
121
|
}
|
|
@@ -115,7 +123,10 @@ export class ViceClient {
|
|
|
115
123
|
if (!this.socket || this.socket.destroyed) {
|
|
116
124
|
return Promise.reject(new Error("VICE monitor socket is not connected"));
|
|
117
125
|
}
|
|
118
|
-
|
|
126
|
+
if (this.nextReqId === 0xffffffff) { // Reserved for unsolicited events (see onData above); skip it on wraparound.
|
|
127
|
+
this.nextReqId = 0;
|
|
128
|
+
}
|
|
129
|
+
const reqId = this.nextReqId++ >>> 0;
|
|
119
130
|
const payload = body ?? Buffer.alloc(0);
|
|
120
131
|
const header = Buffer.alloc(11);
|
|
121
132
|
header[0] = 0x02; // STX
|
|
@@ -126,12 +137,20 @@ export class ViceClient {
|
|
|
126
137
|
const packet = Buffer.concat([header, payload]);
|
|
127
138
|
const expectedCmd = options?.responseType ?? cmd;
|
|
128
139
|
const promise = new Promise((resolve, reject) => {
|
|
129
|
-
|
|
140
|
+
const pending = {
|
|
130
141
|
cmd: expectedCmd,
|
|
131
142
|
resolve,
|
|
132
143
|
reject,
|
|
133
144
|
onFrame: options?.onFrame,
|
|
134
|
-
}
|
|
145
|
+
};
|
|
146
|
+
const timeoutMs = options?.timeoutMs ?? (cmd === 0x84 ? 30000 : 10000);
|
|
147
|
+
pending.timer = setTimeout(() => {
|
|
148
|
+
if (!this.pending.delete(reqId))
|
|
149
|
+
return;
|
|
150
|
+
reject(new Error(`VICE monitor request 0x${cmd.toString(16)} timed out after ${timeoutMs}ms`));
|
|
151
|
+
this.socket?.destroy();
|
|
152
|
+
}, timeoutMs);
|
|
153
|
+
this.pending.set(reqId, pending);
|
|
135
154
|
});
|
|
136
155
|
this.socket.write(packet);
|
|
137
156
|
return promise;
|
|
@@ -178,6 +197,13 @@ export class ViceClient {
|
|
|
178
197
|
const body = Buffer.concat([Buffer.from([bytes.length & 0xff]), bytes]);
|
|
179
198
|
await this.send(0x72, body);
|
|
180
199
|
}
|
|
200
|
+
/** Set the VICE joyport's active-low control byte (BM command 0xA2). */
|
|
201
|
+
async joyportSet(port, activeLowMask) {
|
|
202
|
+
const body = Buffer.alloc(4);
|
|
203
|
+
body.writeUInt16LE(port, 0);
|
|
204
|
+
body.writeUInt16LE(activeLowMask & 0xff, 2);
|
|
205
|
+
await this.send(0xA2, body);
|
|
206
|
+
}
|
|
181
207
|
async checkpointGet(id) {
|
|
182
208
|
const body = Buffer.alloc(4);
|
|
183
209
|
body.writeUInt32LE(id >>> 0, 0);
|
|
@@ -189,8 +215,11 @@ export class ViceClient {
|
|
|
189
215
|
const end = (options.end ?? options.start) & 0xffff;
|
|
190
216
|
const stop = options.stopOnHit !== false;
|
|
191
217
|
const enabled = options.enabled !== false;
|
|
192
|
-
const ops = options.operations
|
|
193
|
-
const
|
|
218
|
+
const ops = options.operations;
|
|
219
|
+
const hasExplicitOperation = ops && (ops.load !== undefined || ops.store !== undefined || ops.execute !== undefined);
|
|
220
|
+
const mask = hasExplicitOperation
|
|
221
|
+
? ((ops?.load ? 0x01 : 0) | (ops?.store ? 0x02 : 0) | (ops?.execute ? 0x04 : 0))
|
|
222
|
+
: 0x04;
|
|
194
223
|
const temporary = options.temporary === true;
|
|
195
224
|
const memspace = options.memspace ?? 0;
|
|
196
225
|
const hasMemspace = options.memspace !== undefined;
|