c64bridge 0.7.4 → 0.8.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/.github/prompts/README.md +14 -4
- package/.github/prompts/assembly-routine-session.prompt.md +9 -9
- package/.github/prompts/basic-program-session.prompt.md +11 -9
- package/.github/prompts/drive-management-session.prompt.md +9 -9
- package/.github/prompts/hello-world-session.prompt.md +17 -0
- package/.github/prompts/petscii-art-session.prompt.md +9 -9
- package/.github/prompts/play-classic-game.prompt.md +9 -9
- package/.github/prompts/pr-converge.prompt.md +13 -0
- package/.github/prompts/sid-music-session.prompt.md +9 -9
- package/AGENTS.md +59 -60
- package/README.md +550 -191
- package/data/assembly/assembly-spec.md +290 -1
- package/data/context/bootstrap.md +26 -2
- package/data/context/fast-paths.md +44 -0
- package/data/graphics/petscii-style-guide.md +6 -2
- package/data/graphics/sprite-charset-best-practices.md +5 -5
- package/dist/.tsbuildinfo +1 -1
- package/dist/c64Client.js +990 -26
- package/dist/config.js +5 -1
- package/dist/device.js +680 -57
- package/dist/diagnostics.js +371 -0
- package/dist/mcp/metadata.js +39 -0
- package/dist/mcp-server.js +170 -20
- package/dist/platform.js +10 -2
- package/dist/prompts/registry.js +166 -309
- package/dist/rag/init.js +37 -1
- package/dist/rag/knowledgeIndex.js +18 -6
- package/dist/rag/rateLimiter.js +2 -2
- package/dist/streamCapture.js +135 -0
- package/dist/tools/audio.js +3 -1
- package/dist/tools/debug.js +470 -0
- package/dist/tools/developer.js +10 -4
- package/dist/tools/graphics.js +183 -17
- package/dist/tools/machineControl.js +11 -5
- package/dist/tools/memory.js +19 -10
- package/dist/tools/meta/audio.js +240 -1
- package/dist/tools/meta/config.js +20 -28
- package/dist/tools/meta/configInventory.js +104 -0
- package/dist/tools/meta/diagnostics.js +45 -2
- package/dist/tools/meta/graphics.js +14 -6
- package/dist/tools/meta/index.js +1 -0
- package/dist/tools/meta/memory.js +20 -6
- package/dist/tools/meta/program.js +473 -0
- package/dist/tools/pollValidator.js +4 -2
- package/dist/tools/programRunners.js +8 -4
- package/dist/tools/registry/config.js +17 -0
- package/dist/tools/registry/disk.js +7 -0
- package/dist/tools/registry/drive.js +3 -0
- package/dist/tools/registry/graphics.js +111 -27
- package/dist/tools/registry/index.js +6 -0
- package/dist/tools/registry/memory.js +1 -0
- package/dist/tools/registry/platform.js +121 -0
- package/dist/tools/registry/program.js +26 -8
- package/dist/tools/registry/sound.js +96 -0
- package/dist/tools/registry/system.js +15 -2
- package/dist/tools/storage.js +1 -0
- package/dist/tools/streaming.js +1 -0
- package/dist/tools/types.js +38 -4
- package/dist/tools/vice.js +160 -0
- package/dist/vicBitmap.js +317 -0
- package/dist/vice/mockServer.js +439 -0
- package/dist/vice/process.js +310 -0
- package/dist/vice/readiness.js +18 -2
- package/dist/vice/viceClient.js +382 -22
- package/doc/developer.md +71 -25
- package/doc/img/backend-switch/hello-c64u.png +0 -0
- package/doc/img/backend-switch/hello-vice-and-c64u.png +0 -0
- package/doc/img/backend-switch/hello-vice.png +0 -0
- package/doc/img/backend-switch/metadata.json +50 -0
- package/doc/plans/vice-backend-switch/plan.md +486 -0
- package/doc/plans/vice-backend-switch-2/plan.md +48 -0
- package/doc/plans/vice-support/notes.md +1 -0
- package/doc/plans/vice-support/plan.md +5 -0
- package/doc/plans/vice-support/rollout.md +23 -17
- package/doc/reviews/vice-support-review.md +185 -0
- package/doc/troubleshooting-mcp.md +35 -6
- package/doc/vice/support-matrix.md +54 -0
- package/mcp/prompts.json +292 -0
- package/mcp/protocol-examples.json +46 -0
- package/mcp/resources.json +940 -0
- package/mcp/schemas/c64_config.schema.json +350 -0
- package/mcp/schemas/c64_debug.schema.json +380 -0
- package/mcp/schemas/c64_disk.schema.json +278 -0
- package/mcp/schemas/c64_drive.schema.json +120 -0
- package/mcp/schemas/c64_extract.schema.json +302 -0
- package/mcp/schemas/c64_graphics.schema.json +333 -0
- package/mcp/schemas/c64_memory.schema.json +155 -0
- package/mcp/schemas/c64_printer.schema.json +218 -0
- package/mcp/schemas/c64_program.schema.json +391 -0
- package/mcp/schemas/c64_rag.schema.json +67 -0
- package/mcp/schemas/c64_select_backend.schema.json +32 -0
- package/mcp/schemas/c64_sound.schema.json +644 -0
- package/mcp/schemas/c64_stream.schema.json +61 -0
- package/mcp/schemas/c64_system.schema.json +227 -0
- package/mcp/schemas/c64_vice.schema.json +63 -0
- package/mcp/server.json +15 -0
- package/mcp/tools.json +4517 -0
- package/mcp.json +90 -15
- package/package.json +11 -4
- package/scripts/capture-backend-switch-screenshots.mjs +276 -0
- package/scripts/generate-mcp-interface.ts +289 -0
- package/scripts/invoke-bun.mjs +67 -21
- package/scripts/mockC64Server.mjs +162 -6
- package/scripts/prepare-release.mjs +59 -2
- package/scripts/run-coverage.mjs +284 -0
- package/scripts/run-tests.mjs +95 -39
- package/scripts/run-tests.ts +378 -73
- package/scripts/update-readme.ts +147 -13
- package/server.json +94 -0
package/dist/prompts/registry.js
CHANGED
|
@@ -1,213 +1,52 @@
|
|
|
1
1
|
import { listKnowledgeResources } from "../rag/knowledgeIndex.js";
|
|
2
2
|
import { toolRegistry } from "../tools/registry/index.js";
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
content: [
|
|
17
|
-
"Safety guardrails:",
|
|
18
|
-
"- Ask the user before resets, power cycles, disk swaps, or destructive writes.",
|
|
19
|
-
"- Offer an undo or recovery path (reload prior program, remount image, or restore settings).",
|
|
20
|
-
"- Highlight side effects that could halt running software or corrupt data.",
|
|
21
|
-
].join("\n"),
|
|
22
|
-
},
|
|
23
|
-
"workflow/basic-verify": {
|
|
24
|
-
id: "workflow/basic-verify",
|
|
25
|
-
role: "assistant",
|
|
26
|
-
content: [
|
|
27
|
-
"Verification for BASIC programs:",
|
|
28
|
-
"- After uploading, call `c64_memory` (op `read_screen`) to capture PETSCII output and confirm `READY.` appears when expected.",
|
|
29
|
-
"- Use `c64_memory` (op `read`) around the BASIC program area when verifying that lines tokenised correctly.",
|
|
30
|
-
"- Call out newline and quotation handling quirks so the user can interpret the output accurately.",
|
|
31
|
-
].join("\n"),
|
|
32
|
-
},
|
|
33
|
-
"workflow/asm-irq": {
|
|
34
|
-
id: "workflow/asm-irq",
|
|
35
|
-
role: "assistant",
|
|
36
|
-
content: [
|
|
37
|
-
"IRQ discipline:",
|
|
38
|
-
"- Wrap installation in `SEI`/`CLI`, set vectors, and configure `$D01A` masks explicitly.",
|
|
39
|
-
"- Acknowledge interrupts via `$D019` before returning, and document any timing assumptions.",
|
|
40
|
-
"- Describe zero-page and workspace usage so other routines can coexist safely.",
|
|
41
|
-
].join("\n"),
|
|
42
|
-
},
|
|
43
|
-
"workflow/sid-iterate": {
|
|
44
|
-
id: "workflow/sid-iterate",
|
|
45
|
-
role: "assistant",
|
|
46
|
-
content: [
|
|
47
|
-
"SID feedback loop:",
|
|
48
|
-
"- Compose the sequence, waveform, ADSR, and modulation plan referencing SID register names.",
|
|
49
|
-
"- Explain how to play it (e.g., `c64_sound` ops `generate` or `note_on`, or uploading executable code).",
|
|
50
|
-
"- After playback, run `analyze_audio` and describe how to adjust envelope, tuning, or rhythm.",
|
|
51
|
-
].join("\n"),
|
|
52
|
-
},
|
|
53
|
-
"workflow/graphics-verify": {
|
|
54
|
-
id: "workflow/graphics-verify",
|
|
55
|
-
role: "assistant",
|
|
56
|
-
content: [
|
|
57
|
-
"Graphics verification:",
|
|
58
|
-
"- List register writes for mode setup, colour RAM, and sprite pointers.",
|
|
59
|
-
"- Suggest capturing output with `c64_memory` (op `read_screen`) or noting expected border/background colours.",
|
|
60
|
-
"- Include timing checks (raster lines, badline windows) when applicable.",
|
|
61
|
-
].join("\n"),
|
|
62
|
-
},
|
|
63
|
-
"workflow/printer": {
|
|
64
|
-
id: "workflow/printer",
|
|
65
|
-
role: "assistant",
|
|
66
|
-
content: [
|
|
67
|
-
"Printer workflow:",
|
|
68
|
-
"- Confirm printer type and device number before printing.",
|
|
69
|
-
"- Include channel open/write/close steps and eject the page with `CHR$(12)` when appropriate.",
|
|
70
|
-
"- Recommend checking printer status or repeating `print_text` if paper alignment is uncertain.",
|
|
71
|
-
].join("\n"),
|
|
72
|
-
},
|
|
73
|
-
"workflow/memory-snapshot": {
|
|
74
|
-
id: "workflow/memory-snapshot",
|
|
75
|
-
role: "assistant",
|
|
76
|
-
content: [
|
|
77
|
-
"Memory safety:",
|
|
78
|
-
"- Pause running code before writes, capture the target range with `c64_memory` (op `read`), then resume when safe.",
|
|
79
|
-
"- Explain how to revert the change (rewriting original bytes or power-cycling if needed).",
|
|
80
|
-
"- Document address ranges, register dependencies, and any expected side effects.",
|
|
81
|
-
].join("\n"),
|
|
82
|
-
},
|
|
83
|
-
"workflow/drive": {
|
|
84
|
-
id: "workflow/drive",
|
|
85
|
-
role: "assistant",
|
|
86
|
-
content: [
|
|
87
|
-
"Drive management protocol:",
|
|
88
|
-
"- List currently mounted images before altering drives to avoid disrupting active workflows.",
|
|
89
|
-
"- Warn if IEC bus operations could interfere with running programs or disk writes.",
|
|
90
|
-
"- Verify results with `drives_list` or relevant status tools after each action.",
|
|
91
|
-
].join("\n"),
|
|
92
|
-
},
|
|
3
|
+
const ASSEMBLY_HARDWARE_NOTES = {
|
|
4
|
+
sid: [
|
|
5
|
+
"When routing this request, keep SID register usage, voice allocation, and timing side effects in scope.",
|
|
6
|
+
],
|
|
7
|
+
vic: [
|
|
8
|
+
"When routing this request, keep VIC-II register usage, raster timing, and display-mode side effects in scope.",
|
|
9
|
+
],
|
|
10
|
+
cia: [
|
|
11
|
+
"When routing this request, keep CIA timer, interrupt, and I/O side effects in scope.",
|
|
12
|
+
],
|
|
13
|
+
multi: [
|
|
14
|
+
"When routing this request, keep cross-chip coordination across SID, VIC-II, and CIA state in scope.",
|
|
15
|
+
],
|
|
93
16
|
};
|
|
94
|
-
const
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
"
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"
|
|
103
|
-
]
|
|
17
|
+
const GRAPHICS_MODE_NOTES = {
|
|
18
|
+
text: [
|
|
19
|
+
"When routing this request, keep screen-code layout, PETSCII constraints, and colour RAM updates in scope.",
|
|
20
|
+
],
|
|
21
|
+
multicolour: [
|
|
22
|
+
"When routing this request, keep multicolour cell constraints, palette choices, and VIC-II mode flags in scope.",
|
|
23
|
+
],
|
|
24
|
+
bitmap: [
|
|
25
|
+
"When routing this request, keep bitmap memory layout, colour sources, and frame-capture validation in scope.",
|
|
26
|
+
],
|
|
27
|
+
sprite: [
|
|
28
|
+
"When routing this request, keep sprite data layout, sprite pointers, enable masks, and expansion flags in scope.",
|
|
29
|
+
],
|
|
104
30
|
};
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
switch (hardware) {
|
|
108
|
-
case "sid":
|
|
109
|
-
return "- Emphasise SID register usage, voice mixing, and timing derived from `c64://specs/sid`.";
|
|
110
|
-
case "vic":
|
|
111
|
-
return "- Highlight VIC-II raster, sprite, or bitmap setup drawing from `c64://specs/vic`.";
|
|
112
|
-
case "cia":
|
|
113
|
-
return "- Cover CIA timer/port configuration and interrupt hand-offs carefully.";
|
|
114
|
-
case "multi":
|
|
115
|
-
return "- Coordinate SID, VIC-II, and CIA interactions; call out contention risks.";
|
|
116
|
-
default:
|
|
117
|
-
return "- Declare which hardware blocks (SID, VIC-II, CIA) you will touch and why.";
|
|
118
|
-
}
|
|
119
|
-
})();
|
|
120
|
-
return {
|
|
121
|
-
id: "family/assembly-core",
|
|
122
|
-
role: "assistant",
|
|
123
|
-
content: [
|
|
124
|
-
"Assembly workflow:",
|
|
125
|
-
focus,
|
|
126
|
-
"- Provide memory layout, zero-page usage, and register effects for the routine.",
|
|
127
|
-
"- Explain how to build and deploy via `c64_program` (op `upload_run_asm`) or targeted `c64_memory` (op `write`) calls.",
|
|
128
|
-
"- Include verification steps using `c64_memory` operations or hardware-specific checks.",
|
|
129
|
-
].join("\n"),
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
const SID_CORE_SEGMENT = {
|
|
133
|
-
id: "family/sid-core",
|
|
31
|
+
const ROUTING_CORE_SEGMENT = {
|
|
32
|
+
id: "routing/core",
|
|
134
33
|
role: "assistant",
|
|
135
34
|
content: [
|
|
136
|
-
"
|
|
137
|
-
"
|
|
138
|
-
"
|
|
139
|
-
"- Provide a playback plan (tool calls, SID register writes, or PRG execution) and note required buffers.",
|
|
35
|
+
"Prompts in this repository define intent and routing only.",
|
|
36
|
+
"Execution logic, validation steps, and safety rules live exclusively in `.github/skills/*/SKILL.md`.",
|
|
37
|
+
"Use the referenced skill, extract missing inputs from the user request, execute the skill, and summarize the outcome.",
|
|
140
38
|
].join("\n"),
|
|
141
39
|
};
|
|
142
|
-
function
|
|
143
|
-
const intro = (() => {
|
|
144
|
-
switch (mode) {
|
|
145
|
-
case "text":
|
|
146
|
-
return "- Focus on PETSCII screen composition and character set considerations.";
|
|
147
|
-
case "multicolour":
|
|
148
|
-
return "- Detail multicolour bitmap setup, shared colour registers, and memory banking.";
|
|
149
|
-
case "bitmap":
|
|
150
|
-
return "- Lay out bitmap memory, screen RAM, and colour RAM usage explicitly.";
|
|
151
|
-
case "sprite":
|
|
152
|
-
return "- Describe sprite data, pointer tables, and multiplexing or animation timing.";
|
|
153
|
-
default:
|
|
154
|
-
return "- State which VIC-II mode or technique you will use and justify the choice.";
|
|
155
|
-
}
|
|
156
|
-
})();
|
|
157
|
-
return {
|
|
158
|
-
id: "family/graphics-core",
|
|
159
|
-
role: "assistant",
|
|
160
|
-
content: [
|
|
161
|
-
"Graphics workflow:",
|
|
162
|
-
intro,
|
|
163
|
-
"- Summarise VIC-II register writes, memory banking, and colour usage with references to `c64://specs/vic`.",
|
|
164
|
-
"- Explain how to deploy the routine (BASIC loader vs assembly) and required assets.",
|
|
165
|
-
"- Include clean-up or teardown steps so the user can restore the display state.",
|
|
166
|
-
].join("\n"),
|
|
167
|
-
};
|
|
168
|
-
}
|
|
169
|
-
function printerCoreSegment(printerType) {
|
|
170
|
-
const detail = (() => {
|
|
171
|
-
switch (printerType) {
|
|
172
|
-
case "commodore":
|
|
173
|
-
return "- Reference Commodore device 4 character codes and PETSCII control sequences.";
|
|
174
|
-
case "epson":
|
|
175
|
-
return "- Reference Epson ESC/P control codes, especially for fonts and bit-image modes.";
|
|
176
|
-
default:
|
|
177
|
-
return "- Clarify whether the target is Commodore MPS or Epson FX to select correct control codes.";
|
|
178
|
-
}
|
|
179
|
-
})();
|
|
40
|
+
function buildSkillRoutingSegment(skillPath, routingNotes) {
|
|
180
41
|
return {
|
|
181
|
-
id:
|
|
42
|
+
id: `routing/${skillPath}`,
|
|
182
43
|
role: "assistant",
|
|
183
44
|
content: [
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
"- Outline data preparation, channel open/write/close, and any required delays.",
|
|
187
|
-
"- Mention how to recover if paper jams or alignment differs from expectations.",
|
|
45
|
+
`Use the skill defined in \`${skillPath}\` as the single source of truth for execution.`,
|
|
46
|
+
...routingNotes,
|
|
188
47
|
].join("\n"),
|
|
189
48
|
};
|
|
190
49
|
}
|
|
191
|
-
const MEMORY_CORE_SEGMENT = {
|
|
192
|
-
id: "family/memory-core",
|
|
193
|
-
role: "assistant",
|
|
194
|
-
content: [
|
|
195
|
-
"Memory debugging workflow:",
|
|
196
|
-
"- Restate the target address ranges and relate them to symbols from `c64://specs/assembly` or the memory map.",
|
|
197
|
-
"- Plan safe inspection or patching steps using `c64_memory` operations alongside `pause` and `resume`.",
|
|
198
|
-
"- Encourage logging or diffing memory before and after changes for auditability.",
|
|
199
|
-
].join("\n"),
|
|
200
|
-
};
|
|
201
|
-
const DRIVE_CORE_SEGMENT = {
|
|
202
|
-
id: "family/drive-core",
|
|
203
|
-
role: "assistant",
|
|
204
|
-
content: [
|
|
205
|
-
"Drive management workflow:",
|
|
206
|
-
"- Summarise desired drive state and confirm affected slots before issuing commands.",
|
|
207
|
-
"- Use `drives_list` to baseline the system and to verify outcomes after each operation.",
|
|
208
|
-
"- Provide contingency steps if mounting or power commands fail.",
|
|
209
|
-
].join("\n"),
|
|
210
|
-
};
|
|
211
50
|
function mergeUniqueStrings(base, extras) {
|
|
212
51
|
if (!extras || extras.length === 0) {
|
|
213
52
|
return [...base];
|
|
@@ -230,12 +69,12 @@ function prepareAssemblyArgs(args) {
|
|
|
230
69
|
if (typeof hardware !== "string") {
|
|
231
70
|
throw new Error("assembly-program prompt argument \"hardware\" must be a string");
|
|
232
71
|
}
|
|
233
|
-
const
|
|
72
|
+
const normalized = hardware.trim().toLowerCase();
|
|
234
73
|
const allowed = ["sid", "vic", "cia", "multi"];
|
|
235
|
-
if (!allowed.includes(
|
|
236
|
-
throw new Error(`assembly-program prompt does not support hardware "${hardware}". Expected one of: ${allowed.join(", ")}`);
|
|
74
|
+
if (!allowed.includes(normalized)) {
|
|
75
|
+
throw new Error(`assembly-program prompt does not support hardware \"${hardware}\". Expected one of: ${allowed.join(", ")}`);
|
|
237
76
|
}
|
|
238
|
-
return { hardware:
|
|
77
|
+
return { hardware: normalized };
|
|
239
78
|
}
|
|
240
79
|
function prepareGraphicsArgs(args) {
|
|
241
80
|
const mode = args.mode;
|
|
@@ -245,12 +84,12 @@ function prepareGraphicsArgs(args) {
|
|
|
245
84
|
if (typeof mode !== "string") {
|
|
246
85
|
throw new Error("graphics-demo prompt argument \"mode\" must be a string");
|
|
247
86
|
}
|
|
248
|
-
const
|
|
87
|
+
const normalized = mode.trim().toLowerCase();
|
|
249
88
|
const allowed = ["text", "multicolour", "bitmap", "sprite"];
|
|
250
|
-
if (!allowed.includes(
|
|
251
|
-
throw new Error(`graphics-demo prompt does not support mode "${mode}". Expected one of: ${allowed.join(", ")}`);
|
|
89
|
+
if (!allowed.includes(normalized)) {
|
|
90
|
+
throw new Error(`graphics-demo prompt does not support mode \"${mode}\". Expected one of: ${allowed.join(", ")}`);
|
|
252
91
|
}
|
|
253
|
-
return { mode:
|
|
92
|
+
return { mode: normalized };
|
|
254
93
|
}
|
|
255
94
|
function preparePrinterArgs(args) {
|
|
256
95
|
const printerType = args.printerType;
|
|
@@ -260,53 +99,97 @@ function preparePrinterArgs(args) {
|
|
|
260
99
|
if (typeof printerType !== "string") {
|
|
261
100
|
throw new Error("printer-job prompt argument \"printerType\" must be a string");
|
|
262
101
|
}
|
|
263
|
-
const
|
|
102
|
+
const normalized = printerType.trim().toLowerCase();
|
|
264
103
|
const allowed = ["commodore", "epson"];
|
|
265
|
-
if (!allowed.includes(
|
|
266
|
-
throw new Error(`printer-job prompt does not support printerType "${printerType}". Expected one of: ${allowed.join(", ")}`);
|
|
104
|
+
if (!allowed.includes(normalized)) {
|
|
105
|
+
throw new Error(`printer-job prompt does not support printerType \"${printerType}\". Expected one of: ${allowed.join(", ")}`);
|
|
267
106
|
}
|
|
268
|
-
return { printerType:
|
|
107
|
+
return { printerType: normalized };
|
|
269
108
|
}
|
|
270
109
|
export function createPromptRegistry() {
|
|
271
110
|
const knowledgeByUri = new Map(listKnowledgeResources().map((resource) => [resource.uri, resource]));
|
|
272
111
|
const toolByName = new Map(toolRegistry.list().map((tool) => [tool.name, tool]));
|
|
273
112
|
const definitions = [
|
|
113
|
+
{
|
|
114
|
+
descriptor: {
|
|
115
|
+
name: "hello-world",
|
|
116
|
+
title: "Hello World Workflow",
|
|
117
|
+
description: "Route ultra-fast hello-world and smoke-test requests to the canonical greeting skill.",
|
|
118
|
+
requiredResources: ["c64://context/bootstrap", "c64://context/fast-paths", "c64://docs/index"],
|
|
119
|
+
optionalResources: [],
|
|
120
|
+
tools: ["c64_program"],
|
|
121
|
+
tags: ["hello", "demo", "greeting", "smoke-test"],
|
|
122
|
+
},
|
|
123
|
+
skillPath: ".github/skills/hello-world/SKILL.md",
|
|
124
|
+
routingNotes: [
|
|
125
|
+
"Use this prompt for the narrowest hello-world, greeting, or smoke-test path.",
|
|
126
|
+
"Backend-pinned requests such as `vice: write a small BASIC program that clears the screen and prints HELLO VICE` should prefer this prompt over the bespoke BASIC prompt.",
|
|
127
|
+
"`c64_program` is a grouped tool, so every direct invocation must include `op`; for this prompt the canonical call is `{ op: \"cross_platform_greeting\", ... }`.",
|
|
128
|
+
"If the current agent cannot directly call `c64_program`, immediately delegate the same request to the `C64` agent instead of exploring repository files or manifests.",
|
|
129
|
+
"For visible single-backend VICE greetings, prefer the no-probe fast path unless the user explicitly asks for screenshots or verification.",
|
|
130
|
+
],
|
|
131
|
+
},
|
|
274
132
|
{
|
|
275
133
|
descriptor: {
|
|
276
134
|
name: "basic-program",
|
|
277
135
|
title: "BASIC Program Workflow",
|
|
278
|
-
description: "
|
|
279
|
-
requiredResources: [
|
|
280
|
-
|
|
281
|
-
"c64://context/bootstrap",
|
|
282
|
-
"c64://docs/index",
|
|
283
|
-
],
|
|
284
|
-
optionalResources: [],
|
|
136
|
+
description: "Route bespoke Commodore BASIC v2 requests to the canonical BASIC skill.",
|
|
137
|
+
requiredResources: ["c64://specs/basic", "c64://context/bootstrap", "c64://docs/index"],
|
|
138
|
+
optionalResources: ["c64://context/fast-paths"],
|
|
285
139
|
tools: ["c64_program", "c64_memory"],
|
|
286
140
|
tags: ["basic", "program"],
|
|
287
141
|
},
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
142
|
+
skillPath: ".github/skills/basic-program/SKILL.md",
|
|
143
|
+
routingNotes: [
|
|
144
|
+
"This prompt is for bespoke BASIC programs rather than generic quick demos.",
|
|
145
|
+
"If the request collapses to a hello-world or smoke test, the selected skill should redirect to the hello-world flow.",
|
|
146
|
+
],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
descriptor: {
|
|
150
|
+
name: "cross-platform-demo",
|
|
151
|
+
title: "Cross-Platform Demo Workflow",
|
|
152
|
+
description: "Route quick visible demo requests to the cross-platform demo skill.",
|
|
153
|
+
requiredResources: ["c64://context/bootstrap", "c64://context/fast-paths", "c64://docs/index"],
|
|
154
|
+
optionalResources: [],
|
|
155
|
+
tools: ["c64_program"],
|
|
156
|
+
tags: ["demo", "platform", "greeting"],
|
|
157
|
+
},
|
|
158
|
+
skillPath: ".github/skills/cross-platform-demo/SKILL.md",
|
|
159
|
+
routingNotes: [
|
|
160
|
+
"This prompt is for the shortest visible confirmation path across one or more configured backends.",
|
|
161
|
+
"`c64_program` is a grouped tool, so always call it with `op: \"cross_platform_greeting\"` for this workflow.",
|
|
162
|
+
],
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
descriptor: {
|
|
166
|
+
name: "preset-music-demo",
|
|
167
|
+
title: "Preset Music Demo Workflow",
|
|
168
|
+
description: "Route quick recognizable tune requests to the SID music skill.",
|
|
169
|
+
requiredResources: ["c64://specs/sid", "c64://specs/sidwave", "c64://context/fast-paths"],
|
|
170
|
+
optionalResources: ["c64://docs/sid/best-practices"],
|
|
171
|
+
tools: ["c64_sound"],
|
|
172
|
+
tags: ["sid", "music", "demo"],
|
|
173
|
+
},
|
|
174
|
+
skillPath: ".github/skills/sid-music/SKILL.md",
|
|
175
|
+
routingNotes: [
|
|
176
|
+
"This prompt is for the built-in preset playback path, using `fuer_elise` as the canonical preset.",
|
|
293
177
|
],
|
|
294
178
|
},
|
|
295
179
|
{
|
|
296
180
|
descriptor: {
|
|
297
181
|
name: "assembly-program",
|
|
298
182
|
title: "Assembly Program Workflow",
|
|
299
|
-
description: "
|
|
300
|
-
requiredResources: [
|
|
301
|
-
"c64://specs/assembly",
|
|
302
|
-
"c64://specs/vic",
|
|
303
|
-
"c64://specs/sid",
|
|
304
|
-
"c64://context/bootstrap",
|
|
305
|
-
],
|
|
183
|
+
description: "Route 6502/6510 routine requests to the canonical assembly skill.",
|
|
184
|
+
requiredResources: ["c64://specs/assembly", "c64://specs/vic", "c64://specs/sid", "c64://context/bootstrap"],
|
|
306
185
|
optionalResources: ["c64://docs/sid/best-practices"],
|
|
307
186
|
tools: ["c64_program", "c64_memory"],
|
|
308
187
|
tags: ["assembly", "program"],
|
|
309
188
|
},
|
|
189
|
+
skillPath: ".github/skills/assembly-program/SKILL.md",
|
|
190
|
+
routingNotes: [
|
|
191
|
+
"Use this prompt when the user needs assembly-level control, IRQ handling, or direct register work.",
|
|
192
|
+
],
|
|
310
193
|
arguments: [
|
|
311
194
|
{
|
|
312
195
|
name: "hardware",
|
|
@@ -317,57 +200,54 @@ export function createPromptRegistry() {
|
|
|
317
200
|
prepareArgs: prepareAssemblyArgs,
|
|
318
201
|
selectOptionalResources: (args) => {
|
|
319
202
|
const hardware = args.hardware;
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
return [];
|
|
203
|
+
return hardware === "sid" || hardware === "multi"
|
|
204
|
+
? ["c64://docs/sid/best-practices"]
|
|
205
|
+
: [];
|
|
324
206
|
},
|
|
325
|
-
|
|
207
|
+
renderRoutingNotes: (args) => {
|
|
326
208
|
const hardware = args.hardware;
|
|
327
|
-
return
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
];
|
|
209
|
+
return hardware
|
|
210
|
+
? [
|
|
211
|
+
`Prompt argument hardware is set to \`${hardware}\`; keep that focus while executing the skill.`,
|
|
212
|
+
...ASSEMBLY_HARDWARE_NOTES[hardware],
|
|
213
|
+
]
|
|
214
|
+
: [];
|
|
334
215
|
},
|
|
335
216
|
},
|
|
336
217
|
{
|
|
337
218
|
descriptor: {
|
|
338
219
|
name: "sid-music",
|
|
339
220
|
title: "SID Composition Workflow",
|
|
340
|
-
description: "
|
|
221
|
+
description: "Route SID playback and composition work to the canonical SID skill.",
|
|
341
222
|
requiredResources: [
|
|
342
223
|
"c64://specs/sid",
|
|
343
224
|
"c64://specs/sidwave",
|
|
344
225
|
"c64://docs/sid/file-structure",
|
|
345
226
|
"c64://docs/sid/best-practices",
|
|
346
227
|
],
|
|
347
|
-
optionalResources: [],
|
|
228
|
+
optionalResources: ["c64://context/fast-paths"],
|
|
348
229
|
tools: ["c64_sound"],
|
|
349
230
|
tags: ["sid", "music"],
|
|
350
231
|
},
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
BASE_SEGMENTS["workflow/sid-iterate"],
|
|
355
|
-
BASE_SEGMENTS["safety/reset"],
|
|
232
|
+
skillPath: ".github/skills/sid-music/SKILL.md",
|
|
233
|
+
routingNotes: [
|
|
234
|
+
"Use this prompt for custom SID work or when the user wants to move beyond the preset demo path.",
|
|
356
235
|
],
|
|
357
236
|
},
|
|
358
237
|
{
|
|
359
238
|
descriptor: {
|
|
360
239
|
name: "graphics-demo",
|
|
361
240
|
title: "Graphics Demo Workflow",
|
|
362
|
-
description: "
|
|
363
|
-
requiredResources: [
|
|
364
|
-
"c64://specs/vic",
|
|
365
|
-
"c64://context/bootstrap",
|
|
366
|
-
],
|
|
241
|
+
description: "Route graphics requests to the canonical graphics skill.",
|
|
242
|
+
requiredResources: ["c64://specs/vic", "c64://context/bootstrap"],
|
|
367
243
|
optionalResources: ["c64://specs/assembly", "c64://specs/charset", "c64://docs/petscii-style"],
|
|
368
244
|
tools: ["c64_program", "c64_memory", "c64_graphics"],
|
|
369
245
|
tags: ["graphics", "vic"],
|
|
370
246
|
},
|
|
247
|
+
skillPath: ".github/skills/graphics-demo/SKILL.md",
|
|
248
|
+
routingNotes: [
|
|
249
|
+
"Use this prompt for PETSCII, sprite, bitmap, or frame-capture work.",
|
|
250
|
+
],
|
|
371
251
|
arguments: [
|
|
372
252
|
{
|
|
373
253
|
name: "mode",
|
|
@@ -376,39 +256,22 @@ export function createPromptRegistry() {
|
|
|
376
256
|
},
|
|
377
257
|
],
|
|
378
258
|
prepareArgs: prepareGraphicsArgs,
|
|
379
|
-
|
|
380
|
-
const mode = args.mode;
|
|
381
|
-
if (mode === "sprite") {
|
|
382
|
-
return ["c64_graphics", "c64_memory"];
|
|
383
|
-
}
|
|
384
|
-
if (mode === "bitmap" || mode === "multicolour") {
|
|
385
|
-
return ["c64_graphics", "c64_memory"];
|
|
386
|
-
}
|
|
387
|
-
if (mode === "text") {
|
|
388
|
-
return ["c64_graphics", "c64_memory"];
|
|
389
|
-
}
|
|
390
|
-
return ["c64_graphics", "c64_memory"];
|
|
391
|
-
},
|
|
392
|
-
buildMessages: (args) => {
|
|
259
|
+
renderRoutingNotes: (args) => {
|
|
393
260
|
const mode = args.mode;
|
|
394
|
-
return
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
261
|
+
return mode
|
|
262
|
+
? [
|
|
263
|
+
`Prompt argument mode is set to \`${mode}\`; keep that mode constraint while executing the skill.`,
|
|
264
|
+
...GRAPHICS_MODE_NOTES[mode],
|
|
265
|
+
]
|
|
266
|
+
: [];
|
|
400
267
|
},
|
|
401
268
|
},
|
|
402
269
|
{
|
|
403
270
|
descriptor: {
|
|
404
271
|
name: "printer-job",
|
|
405
272
|
title: "Printer Job Workflow",
|
|
406
|
-
description: "
|
|
407
|
-
requiredResources: [
|
|
408
|
-
"c64://specs/printer",
|
|
409
|
-
"c64://docs/printer/guide",
|
|
410
|
-
"c64://docs/printer/prompts",
|
|
411
|
-
],
|
|
273
|
+
description: "Route printer work to the canonical printer skill.",
|
|
274
|
+
requiredResources: ["c64://specs/printer", "c64://docs/printer/guide", "c64://docs/printer/prompts"],
|
|
412
275
|
optionalResources: [
|
|
413
276
|
"c64://docs/printer/commodore-text",
|
|
414
277
|
"c64://docs/printer/commodore-bitmap",
|
|
@@ -418,6 +281,10 @@ export function createPromptRegistry() {
|
|
|
418
281
|
tools: ["c64_printer"],
|
|
419
282
|
tags: ["printer"],
|
|
420
283
|
},
|
|
284
|
+
skillPath: ".github/skills/printer-job/SKILL.md",
|
|
285
|
+
routingNotes: [
|
|
286
|
+
"Use this prompt when the user needs Commodore or Epson printer workflows.",
|
|
287
|
+
],
|
|
421
288
|
arguments: [
|
|
422
289
|
{
|
|
423
290
|
name: "printerType",
|
|
@@ -436,56 +303,41 @@ export function createPromptRegistry() {
|
|
|
436
303
|
}
|
|
437
304
|
return [];
|
|
438
305
|
},
|
|
439
|
-
|
|
440
|
-
buildMessages: (args) => {
|
|
306
|
+
renderRoutingNotes: (args) => {
|
|
441
307
|
const printerType = args.printerType;
|
|
442
|
-
return
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
BASE_SEGMENTS["workflow/printer"],
|
|
446
|
-
BASE_SEGMENTS["safety/reset"],
|
|
447
|
-
];
|
|
308
|
+
return printerType
|
|
309
|
+
? [`Prompt argument printerType is set to \`${printerType}\`; preserve that choice while executing the skill.`]
|
|
310
|
+
: [];
|
|
448
311
|
},
|
|
449
312
|
},
|
|
450
313
|
{
|
|
451
314
|
descriptor: {
|
|
452
315
|
name: "memory-debug",
|
|
453
316
|
title: "Memory Debug Workflow",
|
|
454
|
-
description: "
|
|
455
|
-
requiredResources: [
|
|
456
|
-
"c64://context/bootstrap",
|
|
457
|
-
"c64://specs/assembly",
|
|
458
|
-
"c64://docs/index",
|
|
459
|
-
],
|
|
317
|
+
description: "Route reversible memory inspection or patching work to the canonical memory skill.",
|
|
318
|
+
requiredResources: ["c64://context/bootstrap", "c64://specs/assembly", "c64://docs/index"],
|
|
460
319
|
optionalResources: [],
|
|
461
320
|
tools: ["c64_memory", "c64_system"],
|
|
462
321
|
tags: ["memory", "debug"],
|
|
463
322
|
},
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
MEMORY_CORE_SEGMENT,
|
|
468
|
-
BASE_SEGMENTS["workflow/memory-snapshot"],
|
|
323
|
+
skillPath: ".github/skills/memory-debug/SKILL.md",
|
|
324
|
+
routingNotes: [
|
|
325
|
+
"Use this prompt for screen reads, memory reads, polling, and carefully scoped writes.",
|
|
469
326
|
],
|
|
470
327
|
},
|
|
471
328
|
{
|
|
472
329
|
descriptor: {
|
|
473
330
|
name: "drive-manager",
|
|
474
331
|
title: "Drive Manager Workflow",
|
|
475
|
-
description: "
|
|
332
|
+
description: "Route disk-image and drive-state requests to the canonical drive skill.",
|
|
476
333
|
requiredResources: ["c64://context/bootstrap"],
|
|
477
334
|
optionalResources: [],
|
|
478
|
-
tools: [
|
|
479
|
-
"c64_disk",
|
|
480
|
-
"c64_drive",
|
|
481
|
-
],
|
|
335
|
+
tools: ["c64_disk", "c64_drive"],
|
|
482
336
|
tags: ["drive", "storage"],
|
|
483
337
|
},
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
DRIVE_CORE_SEGMENT,
|
|
488
|
-
BASE_SEGMENTS["workflow/drive"],
|
|
338
|
+
skillPath: ".github/skills/drive-manager/SKILL.md",
|
|
339
|
+
routingNotes: [
|
|
340
|
+
"Use this prompt for image mounts, blank media creation, drive resets, and mode changes.",
|
|
489
341
|
],
|
|
490
342
|
},
|
|
491
343
|
];
|
|
@@ -528,15 +380,20 @@ export function createPromptRegistry() {
|
|
|
528
380
|
throw new Error(`Prompt ${name} missing required knowledge resources after resolution`);
|
|
529
381
|
}
|
|
530
382
|
const toolNames = mergeUniqueStrings(definition.descriptor.tools, definition.selectTools ? definition.selectTools(prepared) : undefined);
|
|
531
|
-
const tools = toolNames
|
|
532
|
-
.map((toolName) => {
|
|
383
|
+
const tools = toolNames.map((toolName) => {
|
|
533
384
|
const tool = toolByName.get(toolName);
|
|
534
385
|
if (!tool) {
|
|
535
386
|
throw new Error(`Prompt ${name} references unknown tool: ${toolName}`);
|
|
536
387
|
}
|
|
537
388
|
return tool;
|
|
538
389
|
});
|
|
539
|
-
const
|
|
390
|
+
const routingNotes = definition.renderRoutingNotes
|
|
391
|
+
? [...definition.routingNotes, ...definition.renderRoutingNotes(prepared)]
|
|
392
|
+
: [...definition.routingNotes];
|
|
393
|
+
const messages = [
|
|
394
|
+
ROUTING_CORE_SEGMENT,
|
|
395
|
+
buildSkillRoutingSegment(definition.skillPath, routingNotes),
|
|
396
|
+
];
|
|
540
397
|
return {
|
|
541
398
|
name: definition.descriptor.name,
|
|
542
399
|
description: definition.descriptor.description,
|