web-a2e 1.0.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.
- package/.clangd +5 -0
- package/.mcp.json +12 -0
- package/CLAUDE.md +362 -0
- package/CMakeLists.txt +774 -0
- package/LICENSE +21 -0
- package/README.md +392 -0
- package/build-wasm/generated/roms.cpp +2447 -0
- package/docker-compose.staging.yml +9 -0
- package/docs/basic-rom-disassembly.md +6663 -0
- package/docs/softswitch-comparison.md +273 -0
- package/docs/thunderclock-debug.md +89 -0
- package/examples/cube.bas +72 -0
- package/examples/hello.s +55 -0
- package/examples/scroll.s +140 -0
- package/package.json +18 -0
- package/public/assets/apple-logo-old.png +0 -0
- package/public/assets/apple-logo.png +0 -0
- package/public/assets/drive-closed-light-on.png +0 -0
- package/public/assets/drive-closed.png +0 -0
- package/public/assets/drive-open-light-on.png +0 -0
- package/public/assets/drive-open.png +0 -0
- package/public/audio-worklet.js +82 -0
- package/public/disks/Apple DOS 3.3 January 1983.dsk +0 -0
- package/public/disks/ProDOS 2.4.3.po +0 -0
- package/public/disks/h32mb.2mg +0 -0
- package/public/disks/library.json +26 -0
- package/public/docs/llms/llm-assembler.txt +90 -0
- package/public/docs/llms/llm-basic-program.txt +256 -0
- package/public/docs/llms/llm-disk-drives.txt +72 -0
- package/public/docs/llms/llm-file-explorer.txt +50 -0
- package/public/docs/llms/llm-hard-drives.txt +80 -0
- package/public/docs/llms/llm-main.txt +51 -0
- package/public/docs/llms/llm-slot-configuration.txt +66 -0
- package/public/icons/icon-192.svg +4 -0
- package/public/icons/icon-512.svg +4 -0
- package/public/index.html +661 -0
- package/public/llms.txt +49 -0
- package/public/manifest.json +29 -0
- package/public/shaders/burnin.glsl +22 -0
- package/public/shaders/crt.glsl +706 -0
- package/public/shaders/edge.glsl +109 -0
- package/public/shaders/vertex.glsl +8 -0
- package/public/sw.js +186 -0
- package/roms/341-0027.bin +0 -0
- package/roms/341-0160-A-US-UK.bin +0 -0
- package/roms/341-0160-A.bin +0 -0
- package/roms/342-0273-A-US-UK.bin +0 -0
- package/roms/342-0349-B-C0-FF.bin +0 -0
- package/roms/Apple Mouse Interface Card ROM - 342-0270-C.bin +0 -0
- package/roms/Thunderclock Plus ROM.bin +0 -0
- package/scripts/generate_roms.sh +69 -0
- package/src/bindings/wasm_interface.cpp +1940 -0
- package/src/core/assembler/assembler.cpp +1239 -0
- package/src/core/assembler/assembler.hpp +115 -0
- package/src/core/audio/audio.cpp +160 -0
- package/src/core/audio/audio.hpp +81 -0
- package/src/core/basic/basic_detokenizer.cpp +436 -0
- package/src/core/basic/basic_detokenizer.hpp +41 -0
- package/src/core/basic/basic_tokenizer.cpp +286 -0
- package/src/core/basic/basic_tokenizer.hpp +26 -0
- package/src/core/basic/basic_tokens.hpp +295 -0
- package/src/core/cards/disk2_card.cpp +568 -0
- package/src/core/cards/disk2_card.hpp +316 -0
- package/src/core/cards/expansion_card.hpp +185 -0
- package/src/core/cards/mockingboard/ay8910.cpp +616 -0
- package/src/core/cards/mockingboard/ay8910.hpp +159 -0
- package/src/core/cards/mockingboard/via6522.cpp +530 -0
- package/src/core/cards/mockingboard/via6522.hpp +163 -0
- package/src/core/cards/mockingboard_card.cpp +312 -0
- package/src/core/cards/mockingboard_card.hpp +159 -0
- package/src/core/cards/mouse_card.cpp +654 -0
- package/src/core/cards/mouse_card.hpp +190 -0
- package/src/core/cards/smartport/block_device.cpp +202 -0
- package/src/core/cards/smartport/block_device.hpp +60 -0
- package/src/core/cards/smartport/smartport_card.cpp +603 -0
- package/src/core/cards/smartport/smartport_card.hpp +120 -0
- package/src/core/cards/thunderclock_card.cpp +237 -0
- package/src/core/cards/thunderclock_card.hpp +122 -0
- package/src/core/cpu/cpu6502.cpp +1609 -0
- package/src/core/cpu/cpu6502.hpp +203 -0
- package/src/core/debug/condition_evaluator.cpp +470 -0
- package/src/core/debug/condition_evaluator.hpp +87 -0
- package/src/core/disassembler/disassembler.cpp +552 -0
- package/src/core/disassembler/disassembler.hpp +171 -0
- package/src/core/disk-image/disk_image.hpp +267 -0
- package/src/core/disk-image/dsk_disk_image.cpp +827 -0
- package/src/core/disk-image/dsk_disk_image.hpp +204 -0
- package/src/core/disk-image/gcr_encoding.cpp +147 -0
- package/src/core/disk-image/gcr_encoding.hpp +78 -0
- package/src/core/disk-image/woz_disk_image.cpp +1049 -0
- package/src/core/disk-image/woz_disk_image.hpp +343 -0
- package/src/core/emulator.cpp +2126 -0
- package/src/core/emulator.hpp +434 -0
- package/src/core/filesystem/dos33.cpp +178 -0
- package/src/core/filesystem/dos33.hpp +66 -0
- package/src/core/filesystem/pascal.cpp +262 -0
- package/src/core/filesystem/pascal.hpp +87 -0
- package/src/core/filesystem/prodos.cpp +369 -0
- package/src/core/filesystem/prodos.hpp +119 -0
- package/src/core/input/keyboard.cpp +227 -0
- package/src/core/input/keyboard.hpp +111 -0
- package/src/core/mmu/mmu.cpp +1387 -0
- package/src/core/mmu/mmu.hpp +236 -0
- package/src/core/types.hpp +196 -0
- package/src/core/video/video.cpp +680 -0
- package/src/core/video/video.hpp +156 -0
- package/src/css/assembler-editor.css +1617 -0
- package/src/css/base.css +470 -0
- package/src/css/basic-debugger.css +791 -0
- package/src/css/basic-editor.css +792 -0
- package/src/css/controls.css +783 -0
- package/src/css/cpu-debugger.css +1413 -0
- package/src/css/debug-base.css +160 -0
- package/src/css/debug-windows.css +6455 -0
- package/src/css/disk-drives.css +406 -0
- package/src/css/documentation.css +392 -0
- package/src/css/file-explorer.css +867 -0
- package/src/css/hard-drive.css +180 -0
- package/src/css/layout.css +217 -0
- package/src/css/memory-windows.css +798 -0
- package/src/css/modals.css +510 -0
- package/src/css/monitor.css +425 -0
- package/src/css/release-notes.css +101 -0
- package/src/css/responsive.css +400 -0
- package/src/css/rule-builder.css +340 -0
- package/src/css/save-states.css +201 -0
- package/src/css/settings-windows.css +1231 -0
- package/src/css/window-switcher.css +150 -0
- package/src/js/agent/agent-manager.js +643 -0
- package/src/js/agent/agent-tools.js +293 -0
- package/src/js/agent/agent-version-tools.js +131 -0
- package/src/js/agent/assembler-tools.js +357 -0
- package/src/js/agent/basic-program-tools.js +894 -0
- package/src/js/agent/disk-tools.js +417 -0
- package/src/js/agent/file-explorer-tools.js +269 -0
- package/src/js/agent/index.js +13 -0
- package/src/js/agent/main-tools.js +222 -0
- package/src/js/agent/slot-tools.js +303 -0
- package/src/js/agent/smartport-tools.js +257 -0
- package/src/js/agent/window-tools.js +80 -0
- package/src/js/audio/audio-driver.js +417 -0
- package/src/js/audio/audio-worklet.js +85 -0
- package/src/js/audio/index.js +8 -0
- package/src/js/config/default-layout.js +34 -0
- package/src/js/config/version.js +8 -0
- package/src/js/data/apple2-rom-routines.js +577 -0
- package/src/js/debug/assembler-editor-window.js +2993 -0
- package/src/js/debug/basic-breakpoint-manager.js +529 -0
- package/src/js/debug/basic-program-parser.js +436 -0
- package/src/js/debug/basic-program-window.js +2594 -0
- package/src/js/debug/basic-variable-inspector.js +447 -0
- package/src/js/debug/breakpoint-manager.js +472 -0
- package/src/js/debug/cpu-debugger-window.js +2396 -0
- package/src/js/debug/index.js +22 -0
- package/src/js/debug/label-manager.js +238 -0
- package/src/js/debug/memory-browser-window.js +416 -0
- package/src/js/debug/memory-heat-map-window.js +481 -0
- package/src/js/debug/memory-map-window.js +206 -0
- package/src/js/debug/mockingboard-window.js +882 -0
- package/src/js/debug/mouse-card-window.js +355 -0
- package/src/js/debug/rule-builder-window.js +648 -0
- package/src/js/debug/soft-switch-window.js +458 -0
- package/src/js/debug/stack-viewer-window.js +221 -0
- package/src/js/debug/symbols.js +416 -0
- package/src/js/debug/trace-panel.js +291 -0
- package/src/js/debug/zero-page-watch-window.js +297 -0
- package/src/js/disk-manager/disk-drives-window.js +212 -0
- package/src/js/disk-manager/disk-operations.js +284 -0
- package/src/js/disk-manager/disk-persistence.js +301 -0
- package/src/js/disk-manager/disk-surface-renderer.js +388 -0
- package/src/js/disk-manager/drive-sounds.js +139 -0
- package/src/js/disk-manager/hard-drive-manager.js +481 -0
- package/src/js/disk-manager/hard-drive-persistence.js +187 -0
- package/src/js/disk-manager/hard-drive-window.js +57 -0
- package/src/js/disk-manager/index.js +890 -0
- package/src/js/display/display-settings-window.js +383 -0
- package/src/js/display/index.js +10 -0
- package/src/js/display/screen-window.js +342 -0
- package/src/js/display/webgl-renderer.js +705 -0
- package/src/js/file-explorer/disassembler.js +574 -0
- package/src/js/file-explorer/dos33.js +266 -0
- package/src/js/file-explorer/file-viewer.js +359 -0
- package/src/js/file-explorer/index.js +1261 -0
- package/src/js/file-explorer/prodos.js +549 -0
- package/src/js/file-explorer/utils.js +67 -0
- package/src/js/help/documentation-window.js +1096 -0
- package/src/js/help/index.js +10 -0
- package/src/js/help/release-notes-window.js +85 -0
- package/src/js/help/release-notes.js +612 -0
- package/src/js/input/gamepad-handler.js +176 -0
- package/src/js/input/index.js +12 -0
- package/src/js/input/input-handler.js +396 -0
- package/src/js/input/joystick-window.js +404 -0
- package/src/js/input/mouse-handler.js +99 -0
- package/src/js/input/text-selection.js +462 -0
- package/src/js/main.js +653 -0
- package/src/js/state/index.js +15 -0
- package/src/js/state/save-states-window.js +393 -0
- package/src/js/state/state-manager.js +409 -0
- package/src/js/state/state-persistence.js +218 -0
- package/src/js/ui/confirm.js +43 -0
- package/src/js/ui/disk-drive-positioner.js +347 -0
- package/src/js/ui/reminder-controller.js +129 -0
- package/src/js/ui/slot-configuration-window.js +560 -0
- package/src/js/ui/theme-manager.js +61 -0
- package/src/js/ui/toast.js +44 -0
- package/src/js/ui/ui-controller.js +897 -0
- package/src/js/ui/window-switcher.js +275 -0
- package/src/js/utils/basic-autocomplete.js +832 -0
- package/src/js/utils/basic-highlighting.js +473 -0
- package/src/js/utils/basic-tokenizer.js +153 -0
- package/src/js/utils/basic-tokens.js +117 -0
- package/src/js/utils/constants.js +28 -0
- package/src/js/utils/indexeddb-helper.js +225 -0
- package/src/js/utils/merlin-editor-support.js +905 -0
- package/src/js/utils/merlin-highlighting.js +551 -0
- package/src/js/utils/storage.js +125 -0
- package/src/js/utils/string-utils.js +19 -0
- package/src/js/utils/wasm-memory.js +54 -0
- package/src/js/windows/base-window.js +690 -0
- package/src/js/windows/index.js +9 -0
- package/src/js/windows/window-manager.js +375 -0
- package/tests/catch2/catch.hpp +17976 -0
- package/tests/common/basic_program_builder.cpp +119 -0
- package/tests/common/basic_program_builder.hpp +209 -0
- package/tests/common/disk_image_builder.cpp +444 -0
- package/tests/common/disk_image_builder.hpp +141 -0
- package/tests/common/test_helpers.hpp +118 -0
- package/tests/gcr/gcr-test.cpp +142 -0
- package/tests/integration/check-rom.js +70 -0
- package/tests/integration/compare-boot.js +239 -0
- package/tests/integration/crash-trace.js +102 -0
- package/tests/integration/disk-boot-test.js +264 -0
- package/tests/integration/memory-crash.js +108 -0
- package/tests/integration/nibble-read-test.js +249 -0
- package/tests/integration/phase-test.js +159 -0
- package/tests/integration/test_emulator.cpp +291 -0
- package/tests/integration/test_emulator_basic.cpp +91 -0
- package/tests/integration/test_emulator_debug.cpp +344 -0
- package/tests/integration/test_emulator_disk.cpp +153 -0
- package/tests/integration/test_emulator_state.cpp +163 -0
- package/tests/klaus/6502_functional_test.bin +0 -0
- package/tests/klaus/65C02_extended_opcodes_test.bin +0 -0
- package/tests/klaus/klaus_6502_test.cpp +184 -0
- package/tests/klaus/klaus_65c02_test.cpp +197 -0
- package/tests/thunderclock/thunderclock_mmu_test.cpp +304 -0
- package/tests/thunderclock/thunderclock_test.cpp +550 -0
- package/tests/unit/test_assembler.cpp +521 -0
- package/tests/unit/test_audio.cpp +196 -0
- package/tests/unit/test_ay8910.cpp +311 -0
- package/tests/unit/test_basic_detokenizer.cpp +265 -0
- package/tests/unit/test_basic_tokenizer.cpp +382 -0
- package/tests/unit/test_block_device.cpp +259 -0
- package/tests/unit/test_condition_evaluator.cpp +219 -0
- package/tests/unit/test_cpu6502.cpp +1301 -0
- package/tests/unit/test_cpu_addressing.cpp +361 -0
- package/tests/unit/test_cpu_cycle_counts.cpp +409 -0
- package/tests/unit/test_cpu_decimal.cpp +166 -0
- package/tests/unit/test_cpu_interrupts.cpp +285 -0
- package/tests/unit/test_disassembler.cpp +323 -0
- package/tests/unit/test_disk2_card.cpp +330 -0
- package/tests/unit/test_dos33.cpp +273 -0
- package/tests/unit/test_dsk_disk_image.cpp +315 -0
- package/tests/unit/test_expansion_card.cpp +178 -0
- package/tests/unit/test_gcr_encoding.cpp +232 -0
- package/tests/unit/test_keyboard.cpp +262 -0
- package/tests/unit/test_mmu.cpp +555 -0
- package/tests/unit/test_mmu_slots.cpp +323 -0
- package/tests/unit/test_mockingboard.cpp +352 -0
- package/tests/unit/test_mouse_card.cpp +386 -0
- package/tests/unit/test_pascal.cpp +248 -0
- package/tests/unit/test_prodos.cpp +259 -0
- package/tests/unit/test_smartport_card.cpp +321 -0
- package/tests/unit/test_thunderclock.cpp +354 -0
- package/tests/unit/test_via6522.cpp +323 -0
- package/tests/unit/test_video.cpp +319 -0
- package/tests/unit/test_woz_disk_image.cpp +257 -0
- package/vite.config.js +96 -0
- package/wiki/AI-Agent.md +372 -0
- package/wiki/Architecture-Overview.md +303 -0
- package/wiki/Audio-System.md +449 -0
- package/wiki/CPU-Emulation.md +477 -0
- package/wiki/Debugger.md +516 -0
- package/wiki/Disk-Drives.md +161 -0
- package/wiki/Disk-System-Internals.md +547 -0
- package/wiki/Display-Settings.md +88 -0
- package/wiki/Expansion-Slots.md +187 -0
- package/wiki/File-Explorer.md +259 -0
- package/wiki/Getting-Started.md +156 -0
- package/wiki/Home.md +69 -0
- package/wiki/Input-Devices.md +183 -0
- package/wiki/Keyboard-Shortcuts.md +158 -0
- package/wiki/Memory-System.md +364 -0
- package/wiki/Save-States.md +172 -0
- package/wiki/Video-Rendering.md +658 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* agent-tools.js - Frontend tool implementations for AG-UI protocol
|
|
3
|
+
*
|
|
4
|
+
* Written by
|
|
5
|
+
* Shawn Bullock <shawn@agenticexpert.ai>
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { windowTools } from "./window-tools.js";
|
|
9
|
+
import { basicProgramTools } from "./basic-program-tools.js";
|
|
10
|
+
import { assemblerTools } from "./assembler-tools.js";
|
|
11
|
+
import { fileExplorerTools } from "./file-explorer-tools.js";
|
|
12
|
+
import { mainTools } from "./main-tools.js";
|
|
13
|
+
import { diskTools } from "./disk-tools.js";
|
|
14
|
+
import { smartportTools } from "./smartport-tools.js";
|
|
15
|
+
import { slotTools } from "./slot-tools.js";
|
|
16
|
+
import { agentVersionTools } from "./agent-version-tools.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Registry of available frontend tools
|
|
20
|
+
* Tools are functions that execute in the browser and return results
|
|
21
|
+
*/
|
|
22
|
+
const AGENT_TOOLS = {
|
|
23
|
+
// Import feature-specific tools
|
|
24
|
+
...windowTools,
|
|
25
|
+
...basicProgramTools,
|
|
26
|
+
...assemblerTools,
|
|
27
|
+
...fileExplorerTools,
|
|
28
|
+
...mainTools,
|
|
29
|
+
...diskTools,
|
|
30
|
+
...smartportTools,
|
|
31
|
+
...slotTools,
|
|
32
|
+
...agentVersionTools,
|
|
33
|
+
/**
|
|
34
|
+
* Generic command wrapper (from MCP server)
|
|
35
|
+
*/
|
|
36
|
+
emma_command: async (args) => {
|
|
37
|
+
const { command, params = {} } = args;
|
|
38
|
+
if (!command) {
|
|
39
|
+
throw new Error("command parameter is required");
|
|
40
|
+
}
|
|
41
|
+
// Recursively execute the actual tool
|
|
42
|
+
return await executeAgentTool(command, params);
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Execute a command in the emulator
|
|
47
|
+
*/
|
|
48
|
+
executeCommand: async (args) => {
|
|
49
|
+
const { command, params = {} } = args;
|
|
50
|
+
|
|
51
|
+
if (!command) {
|
|
52
|
+
throw new Error("command parameter is required");
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Route commands to appropriate subsystems
|
|
56
|
+
switch (command) {
|
|
57
|
+
case "power":
|
|
58
|
+
return await handlePowerCommand(params);
|
|
59
|
+
|
|
60
|
+
case "reset":
|
|
61
|
+
return await handleResetCommand(params);
|
|
62
|
+
|
|
63
|
+
case "insertDisk":
|
|
64
|
+
return await handleInsertDiskCommand(params);
|
|
65
|
+
|
|
66
|
+
case "ejectDisk":
|
|
67
|
+
return await handleEjectDiskCommand(params);
|
|
68
|
+
|
|
69
|
+
case "loadBASICProgram":
|
|
70
|
+
return await handleLoadBASICCommand(params);
|
|
71
|
+
|
|
72
|
+
case "typeText":
|
|
73
|
+
return await handleTypeTextCommand(params);
|
|
74
|
+
|
|
75
|
+
default:
|
|
76
|
+
throw new Error(`Unknown command: ${command}`);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Get emulator state
|
|
82
|
+
*/
|
|
83
|
+
getState: async (args) => {
|
|
84
|
+
const wasmModule = window.emulator?.wasmModule;
|
|
85
|
+
if (!wasmModule) {
|
|
86
|
+
throw new Error("Emulator not available");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
success: true,
|
|
91
|
+
state: {
|
|
92
|
+
running: window.emulator.running,
|
|
93
|
+
paused: wasmModule._isPaused(),
|
|
94
|
+
pc: wasmModule._getPC(),
|
|
95
|
+
a: wasmModule._getA(),
|
|
96
|
+
x: wasmModule._getX(),
|
|
97
|
+
y: wasmModule._getY(),
|
|
98
|
+
sp: wasmModule._getSP(),
|
|
99
|
+
cycles: wasmModule._getTotalCycles(),
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Set emulator state
|
|
106
|
+
*/
|
|
107
|
+
setState: async (args) => {
|
|
108
|
+
const wasmModule = window.emulator?.wasmModule;
|
|
109
|
+
if (!wasmModule) {
|
|
110
|
+
throw new Error("Emulator not available");
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const { pc, a, x, y, sp } = args;
|
|
114
|
+
|
|
115
|
+
if (pc !== undefined) wasmModule._setRegPC(pc);
|
|
116
|
+
if (a !== undefined) wasmModule._setRegA(a);
|
|
117
|
+
if (x !== undefined) wasmModule._setRegX(x);
|
|
118
|
+
if (y !== undefined) wasmModule._setRegY(y);
|
|
119
|
+
if (sp !== undefined) wasmModule._setRegSP(sp);
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
success: true,
|
|
123
|
+
message: "State updated",
|
|
124
|
+
};
|
|
125
|
+
},
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Execute a tool by name
|
|
130
|
+
*/
|
|
131
|
+
export async function executeAgentTool(toolName, args) {
|
|
132
|
+
const tool = AGENT_TOOLS[toolName];
|
|
133
|
+
|
|
134
|
+
if (!tool) {
|
|
135
|
+
throw new Error(`Unknown tool: ${toolName}`);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return await tool(args);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Get list of available tools (for MCP server registration)
|
|
143
|
+
*/
|
|
144
|
+
export function getAvailableTools() {
|
|
145
|
+
return Object.keys(AGENT_TOOLS);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ========================================
|
|
149
|
+
// Command Handlers
|
|
150
|
+
// ========================================
|
|
151
|
+
|
|
152
|
+
async function handlePowerCommand(params) {
|
|
153
|
+
const emulator = window.emulator;
|
|
154
|
+
if (!emulator) {
|
|
155
|
+
throw new Error("Emulator not available");
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const { action = "toggle" } = params;
|
|
159
|
+
|
|
160
|
+
if (action === "on" && !emulator.running) {
|
|
161
|
+
emulator.start();
|
|
162
|
+
} else if (action === "off" && emulator.running) {
|
|
163
|
+
emulator.stop();
|
|
164
|
+
} else if (action === "toggle") {
|
|
165
|
+
if (emulator.running) {
|
|
166
|
+
emulator.stop();
|
|
167
|
+
} else {
|
|
168
|
+
emulator.start();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
success: true,
|
|
174
|
+
running: emulator.running,
|
|
175
|
+
message: `Emulator is now ${emulator.running ? "running" : "stopped"}`,
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
async function handleResetCommand(params) {
|
|
180
|
+
const wasmModule = window.emulator?.wasmModule;
|
|
181
|
+
if (!wasmModule) {
|
|
182
|
+
throw new Error("Emulator not available");
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const { warm = false } = params;
|
|
186
|
+
|
|
187
|
+
if (warm) {
|
|
188
|
+
wasmModule._warmReset();
|
|
189
|
+
} else {
|
|
190
|
+
wasmModule._reset();
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return {
|
|
194
|
+
success: true,
|
|
195
|
+
resetType: warm ? "warm" : "cold",
|
|
196
|
+
message: `${warm ? "Warm" : "Cold"} reset executed`,
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async function handleInsertDiskCommand(params) {
|
|
201
|
+
const { drive, url, filename } = params;
|
|
202
|
+
|
|
203
|
+
if (drive === undefined) {
|
|
204
|
+
throw new Error("drive parameter is required (0 or 1)");
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (!url) {
|
|
208
|
+
throw new Error("url parameter is required");
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Fetch disk image
|
|
212
|
+
const response = await fetch(url);
|
|
213
|
+
if (!response.ok) {
|
|
214
|
+
throw new Error(`Failed to fetch disk: ${response.statusText}`);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
218
|
+
const uint8Array = new Uint8Array(arrayBuffer);
|
|
219
|
+
|
|
220
|
+
// Insert into emulator
|
|
221
|
+
const diskManager = window.emulator?.diskManager;
|
|
222
|
+
if (!diskManager) {
|
|
223
|
+
throw new Error("Disk manager not available");
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
await diskManager.insertDisk(drive, uint8Array, filename || url);
|
|
227
|
+
|
|
228
|
+
return {
|
|
229
|
+
success: true,
|
|
230
|
+
drive: drive,
|
|
231
|
+
filename: filename || url,
|
|
232
|
+
size: uint8Array.length,
|
|
233
|
+
message: `Disk inserted into drive ${drive}`,
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async function handleEjectDiskCommand(params) {
|
|
238
|
+
const { drive } = params;
|
|
239
|
+
|
|
240
|
+
if (drive === undefined) {
|
|
241
|
+
throw new Error("drive parameter is required (0 or 1)");
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const diskManager = window.emulator?.diskManager;
|
|
245
|
+
if (!diskManager) {
|
|
246
|
+
throw new Error("Disk manager not available");
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
diskManager.ejectDisk(drive);
|
|
250
|
+
|
|
251
|
+
return {
|
|
252
|
+
success: true,
|
|
253
|
+
drive: drive,
|
|
254
|
+
message: `Disk ejected from drive ${drive}`,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
async function handleLoadBASICCommand(params) {
|
|
259
|
+
const { program } = params;
|
|
260
|
+
|
|
261
|
+
if (!program) {
|
|
262
|
+
throw new Error("program parameter is required");
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
// Type program into emulator
|
|
266
|
+
// This would need to be implemented via the input handler
|
|
267
|
+
throw new Error("loadBASICProgram not yet implemented");
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async function handleTypeTextCommand(params) {
|
|
271
|
+
const { text } = params;
|
|
272
|
+
|
|
273
|
+
if (!text) {
|
|
274
|
+
throw new Error("text parameter is required");
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
const inputHandler = window.emulator?.inputHandler;
|
|
278
|
+
if (!inputHandler) {
|
|
279
|
+
throw new Error("Input handler not available");
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return new Promise((resolve) => {
|
|
283
|
+
inputHandler.queueTextInput(text, {
|
|
284
|
+
onComplete: () => {
|
|
285
|
+
resolve({
|
|
286
|
+
success: true,
|
|
287
|
+
length: text.length,
|
|
288
|
+
message: `Typed ${text.length} characters`,
|
|
289
|
+
});
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
});
|
|
293
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* agent-version-tools.js - Agent version and compatibility tools
|
|
3
|
+
*
|
|
4
|
+
* Written by
|
|
5
|
+
* Shawn Bullock <shawn@agenticexpert.ai>
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Parse semantic version string (e.g., "1.0.2") into comparable parts
|
|
10
|
+
* @param {string} version - Version string in semver format
|
|
11
|
+
* @returns {Object} Version parts {major, minor, patch}
|
|
12
|
+
*/
|
|
13
|
+
function parseVersion(version) {
|
|
14
|
+
const parts = version.split('.').map(p => parseInt(p, 10));
|
|
15
|
+
if (parts.length !== 3 || parts.some(isNaN)) {
|
|
16
|
+
throw new Error(`Invalid version format: ${version}`);
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
major: parts[0],
|
|
20
|
+
minor: parts[1],
|
|
21
|
+
patch: parts[2]
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Compare two semantic versions
|
|
27
|
+
* @param {string} version1 - First version
|
|
28
|
+
* @param {string} version2 - Second version
|
|
29
|
+
* @returns {number} -1 if v1 < v2, 0 if equal, 1 if v1 > v2
|
|
30
|
+
*/
|
|
31
|
+
function compareVersions(version1, version2) {
|
|
32
|
+
const v1 = parseVersion(version1);
|
|
33
|
+
const v2 = parseVersion(version2);
|
|
34
|
+
|
|
35
|
+
if (v1.major !== v2.major) return v1.major - v2.major;
|
|
36
|
+
if (v1.minor !== v2.minor) return v1.minor - v2.minor;
|
|
37
|
+
return v1.patch - v2.patch;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const agentVersionTools = {
|
|
41
|
+
/**
|
|
42
|
+
* Check if the currently running agent is compatible with the app
|
|
43
|
+
* Returns version info and compatibility status
|
|
44
|
+
*/
|
|
45
|
+
checkAgentCompatibility: async (args) => {
|
|
46
|
+
const { minVersion = "1.0.5" } = args;
|
|
47
|
+
|
|
48
|
+
// Get agentManager from global window object
|
|
49
|
+
const agentManager = window.emulator?.agentManager;
|
|
50
|
+
if (!agentManager) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: "AgentManager not available",
|
|
54
|
+
compatible: false
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
// Call the MCP server's get_version tool
|
|
60
|
+
const versionInfo = await agentManager.callMCPTool("get_version", {});
|
|
61
|
+
|
|
62
|
+
if (!versionInfo.success) {
|
|
63
|
+
return {
|
|
64
|
+
success: false,
|
|
65
|
+
error: "Failed to get agent version",
|
|
66
|
+
compatible: false
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Parse versions into numeric parts
|
|
71
|
+
const agentVersionParsed = parseVersion(versionInfo.version);
|
|
72
|
+
const minVersionParsed = parseVersion(minVersion);
|
|
73
|
+
|
|
74
|
+
// Compare versions
|
|
75
|
+
const comparison = compareVersions(versionInfo.version, minVersion);
|
|
76
|
+
const compatible = comparison >= 0;
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
agent: {
|
|
81
|
+
name: versionInfo.name,
|
|
82
|
+
version: versionInfo.version,
|
|
83
|
+
versionNumeric: agentVersionParsed,
|
|
84
|
+
description: versionInfo.description
|
|
85
|
+
},
|
|
86
|
+
required: {
|
|
87
|
+
minVersion: minVersion,
|
|
88
|
+
minVersionNumeric: minVersionParsed
|
|
89
|
+
},
|
|
90
|
+
compatible: compatible,
|
|
91
|
+
comparison: comparison, // -1 if agent < required, 0 if equal, 1 if agent > required
|
|
92
|
+
message: compatible
|
|
93
|
+
? `Agent version ${versionInfo.version} is compatible (>= ${minVersion})`
|
|
94
|
+
: `Agent version ${versionInfo.version} is NOT compatible (requires >= ${minVersion})`
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
} catch (error) {
|
|
98
|
+
return {
|
|
99
|
+
success: false,
|
|
100
|
+
error: error.message,
|
|
101
|
+
compatible: false
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Get agent version information
|
|
108
|
+
*/
|
|
109
|
+
getAgentVersion: async (args) => {
|
|
110
|
+
// Get agentManager from global window object
|
|
111
|
+
const agentManager = window.emulator?.agentManager;
|
|
112
|
+
if (!agentManager) {
|
|
113
|
+
return {
|
|
114
|
+
success: false,
|
|
115
|
+
error: "AgentManager not available"
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
// Call the MCP server's get_version tool
|
|
121
|
+
const versionInfo = await agentManager.callMCPTool("get_version", {});
|
|
122
|
+
return versionInfo;
|
|
123
|
+
|
|
124
|
+
} catch (error) {
|
|
125
|
+
return {
|
|
126
|
+
success: false,
|
|
127
|
+
error: error.message
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|