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.
Files changed (295) hide show
  1. package/.clangd +5 -0
  2. package/.mcp.json +12 -0
  3. package/CLAUDE.md +362 -0
  4. package/CMakeLists.txt +774 -0
  5. package/LICENSE +21 -0
  6. package/README.md +392 -0
  7. package/build-wasm/generated/roms.cpp +2447 -0
  8. package/docker-compose.staging.yml +9 -0
  9. package/docs/basic-rom-disassembly.md +6663 -0
  10. package/docs/softswitch-comparison.md +273 -0
  11. package/docs/thunderclock-debug.md +89 -0
  12. package/examples/cube.bas +72 -0
  13. package/examples/hello.s +55 -0
  14. package/examples/scroll.s +140 -0
  15. package/package.json +18 -0
  16. package/public/assets/apple-logo-old.png +0 -0
  17. package/public/assets/apple-logo.png +0 -0
  18. package/public/assets/drive-closed-light-on.png +0 -0
  19. package/public/assets/drive-closed.png +0 -0
  20. package/public/assets/drive-open-light-on.png +0 -0
  21. package/public/assets/drive-open.png +0 -0
  22. package/public/audio-worklet.js +82 -0
  23. package/public/disks/Apple DOS 3.3 January 1983.dsk +0 -0
  24. package/public/disks/ProDOS 2.4.3.po +0 -0
  25. package/public/disks/h32mb.2mg +0 -0
  26. package/public/disks/library.json +26 -0
  27. package/public/docs/llms/llm-assembler.txt +90 -0
  28. package/public/docs/llms/llm-basic-program.txt +256 -0
  29. package/public/docs/llms/llm-disk-drives.txt +72 -0
  30. package/public/docs/llms/llm-file-explorer.txt +50 -0
  31. package/public/docs/llms/llm-hard-drives.txt +80 -0
  32. package/public/docs/llms/llm-main.txt +51 -0
  33. package/public/docs/llms/llm-slot-configuration.txt +66 -0
  34. package/public/icons/icon-192.svg +4 -0
  35. package/public/icons/icon-512.svg +4 -0
  36. package/public/index.html +661 -0
  37. package/public/llms.txt +49 -0
  38. package/public/manifest.json +29 -0
  39. package/public/shaders/burnin.glsl +22 -0
  40. package/public/shaders/crt.glsl +706 -0
  41. package/public/shaders/edge.glsl +109 -0
  42. package/public/shaders/vertex.glsl +8 -0
  43. package/public/sw.js +186 -0
  44. package/roms/341-0027.bin +0 -0
  45. package/roms/341-0160-A-US-UK.bin +0 -0
  46. package/roms/341-0160-A.bin +0 -0
  47. package/roms/342-0273-A-US-UK.bin +0 -0
  48. package/roms/342-0349-B-C0-FF.bin +0 -0
  49. package/roms/Apple Mouse Interface Card ROM - 342-0270-C.bin +0 -0
  50. package/roms/Thunderclock Plus ROM.bin +0 -0
  51. package/scripts/generate_roms.sh +69 -0
  52. package/src/bindings/wasm_interface.cpp +1940 -0
  53. package/src/core/assembler/assembler.cpp +1239 -0
  54. package/src/core/assembler/assembler.hpp +115 -0
  55. package/src/core/audio/audio.cpp +160 -0
  56. package/src/core/audio/audio.hpp +81 -0
  57. package/src/core/basic/basic_detokenizer.cpp +436 -0
  58. package/src/core/basic/basic_detokenizer.hpp +41 -0
  59. package/src/core/basic/basic_tokenizer.cpp +286 -0
  60. package/src/core/basic/basic_tokenizer.hpp +26 -0
  61. package/src/core/basic/basic_tokens.hpp +295 -0
  62. package/src/core/cards/disk2_card.cpp +568 -0
  63. package/src/core/cards/disk2_card.hpp +316 -0
  64. package/src/core/cards/expansion_card.hpp +185 -0
  65. package/src/core/cards/mockingboard/ay8910.cpp +616 -0
  66. package/src/core/cards/mockingboard/ay8910.hpp +159 -0
  67. package/src/core/cards/mockingboard/via6522.cpp +530 -0
  68. package/src/core/cards/mockingboard/via6522.hpp +163 -0
  69. package/src/core/cards/mockingboard_card.cpp +312 -0
  70. package/src/core/cards/mockingboard_card.hpp +159 -0
  71. package/src/core/cards/mouse_card.cpp +654 -0
  72. package/src/core/cards/mouse_card.hpp +190 -0
  73. package/src/core/cards/smartport/block_device.cpp +202 -0
  74. package/src/core/cards/smartport/block_device.hpp +60 -0
  75. package/src/core/cards/smartport/smartport_card.cpp +603 -0
  76. package/src/core/cards/smartport/smartport_card.hpp +120 -0
  77. package/src/core/cards/thunderclock_card.cpp +237 -0
  78. package/src/core/cards/thunderclock_card.hpp +122 -0
  79. package/src/core/cpu/cpu6502.cpp +1609 -0
  80. package/src/core/cpu/cpu6502.hpp +203 -0
  81. package/src/core/debug/condition_evaluator.cpp +470 -0
  82. package/src/core/debug/condition_evaluator.hpp +87 -0
  83. package/src/core/disassembler/disassembler.cpp +552 -0
  84. package/src/core/disassembler/disassembler.hpp +171 -0
  85. package/src/core/disk-image/disk_image.hpp +267 -0
  86. package/src/core/disk-image/dsk_disk_image.cpp +827 -0
  87. package/src/core/disk-image/dsk_disk_image.hpp +204 -0
  88. package/src/core/disk-image/gcr_encoding.cpp +147 -0
  89. package/src/core/disk-image/gcr_encoding.hpp +78 -0
  90. package/src/core/disk-image/woz_disk_image.cpp +1049 -0
  91. package/src/core/disk-image/woz_disk_image.hpp +343 -0
  92. package/src/core/emulator.cpp +2126 -0
  93. package/src/core/emulator.hpp +434 -0
  94. package/src/core/filesystem/dos33.cpp +178 -0
  95. package/src/core/filesystem/dos33.hpp +66 -0
  96. package/src/core/filesystem/pascal.cpp +262 -0
  97. package/src/core/filesystem/pascal.hpp +87 -0
  98. package/src/core/filesystem/prodos.cpp +369 -0
  99. package/src/core/filesystem/prodos.hpp +119 -0
  100. package/src/core/input/keyboard.cpp +227 -0
  101. package/src/core/input/keyboard.hpp +111 -0
  102. package/src/core/mmu/mmu.cpp +1387 -0
  103. package/src/core/mmu/mmu.hpp +236 -0
  104. package/src/core/types.hpp +196 -0
  105. package/src/core/video/video.cpp +680 -0
  106. package/src/core/video/video.hpp +156 -0
  107. package/src/css/assembler-editor.css +1617 -0
  108. package/src/css/base.css +470 -0
  109. package/src/css/basic-debugger.css +791 -0
  110. package/src/css/basic-editor.css +792 -0
  111. package/src/css/controls.css +783 -0
  112. package/src/css/cpu-debugger.css +1413 -0
  113. package/src/css/debug-base.css +160 -0
  114. package/src/css/debug-windows.css +6455 -0
  115. package/src/css/disk-drives.css +406 -0
  116. package/src/css/documentation.css +392 -0
  117. package/src/css/file-explorer.css +867 -0
  118. package/src/css/hard-drive.css +180 -0
  119. package/src/css/layout.css +217 -0
  120. package/src/css/memory-windows.css +798 -0
  121. package/src/css/modals.css +510 -0
  122. package/src/css/monitor.css +425 -0
  123. package/src/css/release-notes.css +101 -0
  124. package/src/css/responsive.css +400 -0
  125. package/src/css/rule-builder.css +340 -0
  126. package/src/css/save-states.css +201 -0
  127. package/src/css/settings-windows.css +1231 -0
  128. package/src/css/window-switcher.css +150 -0
  129. package/src/js/agent/agent-manager.js +643 -0
  130. package/src/js/agent/agent-tools.js +293 -0
  131. package/src/js/agent/agent-version-tools.js +131 -0
  132. package/src/js/agent/assembler-tools.js +357 -0
  133. package/src/js/agent/basic-program-tools.js +894 -0
  134. package/src/js/agent/disk-tools.js +417 -0
  135. package/src/js/agent/file-explorer-tools.js +269 -0
  136. package/src/js/agent/index.js +13 -0
  137. package/src/js/agent/main-tools.js +222 -0
  138. package/src/js/agent/slot-tools.js +303 -0
  139. package/src/js/agent/smartport-tools.js +257 -0
  140. package/src/js/agent/window-tools.js +80 -0
  141. package/src/js/audio/audio-driver.js +417 -0
  142. package/src/js/audio/audio-worklet.js +85 -0
  143. package/src/js/audio/index.js +8 -0
  144. package/src/js/config/default-layout.js +34 -0
  145. package/src/js/config/version.js +8 -0
  146. package/src/js/data/apple2-rom-routines.js +577 -0
  147. package/src/js/debug/assembler-editor-window.js +2993 -0
  148. package/src/js/debug/basic-breakpoint-manager.js +529 -0
  149. package/src/js/debug/basic-program-parser.js +436 -0
  150. package/src/js/debug/basic-program-window.js +2594 -0
  151. package/src/js/debug/basic-variable-inspector.js +447 -0
  152. package/src/js/debug/breakpoint-manager.js +472 -0
  153. package/src/js/debug/cpu-debugger-window.js +2396 -0
  154. package/src/js/debug/index.js +22 -0
  155. package/src/js/debug/label-manager.js +238 -0
  156. package/src/js/debug/memory-browser-window.js +416 -0
  157. package/src/js/debug/memory-heat-map-window.js +481 -0
  158. package/src/js/debug/memory-map-window.js +206 -0
  159. package/src/js/debug/mockingboard-window.js +882 -0
  160. package/src/js/debug/mouse-card-window.js +355 -0
  161. package/src/js/debug/rule-builder-window.js +648 -0
  162. package/src/js/debug/soft-switch-window.js +458 -0
  163. package/src/js/debug/stack-viewer-window.js +221 -0
  164. package/src/js/debug/symbols.js +416 -0
  165. package/src/js/debug/trace-panel.js +291 -0
  166. package/src/js/debug/zero-page-watch-window.js +297 -0
  167. package/src/js/disk-manager/disk-drives-window.js +212 -0
  168. package/src/js/disk-manager/disk-operations.js +284 -0
  169. package/src/js/disk-manager/disk-persistence.js +301 -0
  170. package/src/js/disk-manager/disk-surface-renderer.js +388 -0
  171. package/src/js/disk-manager/drive-sounds.js +139 -0
  172. package/src/js/disk-manager/hard-drive-manager.js +481 -0
  173. package/src/js/disk-manager/hard-drive-persistence.js +187 -0
  174. package/src/js/disk-manager/hard-drive-window.js +57 -0
  175. package/src/js/disk-manager/index.js +890 -0
  176. package/src/js/display/display-settings-window.js +383 -0
  177. package/src/js/display/index.js +10 -0
  178. package/src/js/display/screen-window.js +342 -0
  179. package/src/js/display/webgl-renderer.js +705 -0
  180. package/src/js/file-explorer/disassembler.js +574 -0
  181. package/src/js/file-explorer/dos33.js +266 -0
  182. package/src/js/file-explorer/file-viewer.js +359 -0
  183. package/src/js/file-explorer/index.js +1261 -0
  184. package/src/js/file-explorer/prodos.js +549 -0
  185. package/src/js/file-explorer/utils.js +67 -0
  186. package/src/js/help/documentation-window.js +1096 -0
  187. package/src/js/help/index.js +10 -0
  188. package/src/js/help/release-notes-window.js +85 -0
  189. package/src/js/help/release-notes.js +612 -0
  190. package/src/js/input/gamepad-handler.js +176 -0
  191. package/src/js/input/index.js +12 -0
  192. package/src/js/input/input-handler.js +396 -0
  193. package/src/js/input/joystick-window.js +404 -0
  194. package/src/js/input/mouse-handler.js +99 -0
  195. package/src/js/input/text-selection.js +462 -0
  196. package/src/js/main.js +653 -0
  197. package/src/js/state/index.js +15 -0
  198. package/src/js/state/save-states-window.js +393 -0
  199. package/src/js/state/state-manager.js +409 -0
  200. package/src/js/state/state-persistence.js +218 -0
  201. package/src/js/ui/confirm.js +43 -0
  202. package/src/js/ui/disk-drive-positioner.js +347 -0
  203. package/src/js/ui/reminder-controller.js +129 -0
  204. package/src/js/ui/slot-configuration-window.js +560 -0
  205. package/src/js/ui/theme-manager.js +61 -0
  206. package/src/js/ui/toast.js +44 -0
  207. package/src/js/ui/ui-controller.js +897 -0
  208. package/src/js/ui/window-switcher.js +275 -0
  209. package/src/js/utils/basic-autocomplete.js +832 -0
  210. package/src/js/utils/basic-highlighting.js +473 -0
  211. package/src/js/utils/basic-tokenizer.js +153 -0
  212. package/src/js/utils/basic-tokens.js +117 -0
  213. package/src/js/utils/constants.js +28 -0
  214. package/src/js/utils/indexeddb-helper.js +225 -0
  215. package/src/js/utils/merlin-editor-support.js +905 -0
  216. package/src/js/utils/merlin-highlighting.js +551 -0
  217. package/src/js/utils/storage.js +125 -0
  218. package/src/js/utils/string-utils.js +19 -0
  219. package/src/js/utils/wasm-memory.js +54 -0
  220. package/src/js/windows/base-window.js +690 -0
  221. package/src/js/windows/index.js +9 -0
  222. package/src/js/windows/window-manager.js +375 -0
  223. package/tests/catch2/catch.hpp +17976 -0
  224. package/tests/common/basic_program_builder.cpp +119 -0
  225. package/tests/common/basic_program_builder.hpp +209 -0
  226. package/tests/common/disk_image_builder.cpp +444 -0
  227. package/tests/common/disk_image_builder.hpp +141 -0
  228. package/tests/common/test_helpers.hpp +118 -0
  229. package/tests/gcr/gcr-test.cpp +142 -0
  230. package/tests/integration/check-rom.js +70 -0
  231. package/tests/integration/compare-boot.js +239 -0
  232. package/tests/integration/crash-trace.js +102 -0
  233. package/tests/integration/disk-boot-test.js +264 -0
  234. package/tests/integration/memory-crash.js +108 -0
  235. package/tests/integration/nibble-read-test.js +249 -0
  236. package/tests/integration/phase-test.js +159 -0
  237. package/tests/integration/test_emulator.cpp +291 -0
  238. package/tests/integration/test_emulator_basic.cpp +91 -0
  239. package/tests/integration/test_emulator_debug.cpp +344 -0
  240. package/tests/integration/test_emulator_disk.cpp +153 -0
  241. package/tests/integration/test_emulator_state.cpp +163 -0
  242. package/tests/klaus/6502_functional_test.bin +0 -0
  243. package/tests/klaus/65C02_extended_opcodes_test.bin +0 -0
  244. package/tests/klaus/klaus_6502_test.cpp +184 -0
  245. package/tests/klaus/klaus_65c02_test.cpp +197 -0
  246. package/tests/thunderclock/thunderclock_mmu_test.cpp +304 -0
  247. package/tests/thunderclock/thunderclock_test.cpp +550 -0
  248. package/tests/unit/test_assembler.cpp +521 -0
  249. package/tests/unit/test_audio.cpp +196 -0
  250. package/tests/unit/test_ay8910.cpp +311 -0
  251. package/tests/unit/test_basic_detokenizer.cpp +265 -0
  252. package/tests/unit/test_basic_tokenizer.cpp +382 -0
  253. package/tests/unit/test_block_device.cpp +259 -0
  254. package/tests/unit/test_condition_evaluator.cpp +219 -0
  255. package/tests/unit/test_cpu6502.cpp +1301 -0
  256. package/tests/unit/test_cpu_addressing.cpp +361 -0
  257. package/tests/unit/test_cpu_cycle_counts.cpp +409 -0
  258. package/tests/unit/test_cpu_decimal.cpp +166 -0
  259. package/tests/unit/test_cpu_interrupts.cpp +285 -0
  260. package/tests/unit/test_disassembler.cpp +323 -0
  261. package/tests/unit/test_disk2_card.cpp +330 -0
  262. package/tests/unit/test_dos33.cpp +273 -0
  263. package/tests/unit/test_dsk_disk_image.cpp +315 -0
  264. package/tests/unit/test_expansion_card.cpp +178 -0
  265. package/tests/unit/test_gcr_encoding.cpp +232 -0
  266. package/tests/unit/test_keyboard.cpp +262 -0
  267. package/tests/unit/test_mmu.cpp +555 -0
  268. package/tests/unit/test_mmu_slots.cpp +323 -0
  269. package/tests/unit/test_mockingboard.cpp +352 -0
  270. package/tests/unit/test_mouse_card.cpp +386 -0
  271. package/tests/unit/test_pascal.cpp +248 -0
  272. package/tests/unit/test_prodos.cpp +259 -0
  273. package/tests/unit/test_smartport_card.cpp +321 -0
  274. package/tests/unit/test_thunderclock.cpp +354 -0
  275. package/tests/unit/test_via6522.cpp +323 -0
  276. package/tests/unit/test_video.cpp +319 -0
  277. package/tests/unit/test_woz_disk_image.cpp +257 -0
  278. package/vite.config.js +96 -0
  279. package/wiki/AI-Agent.md +372 -0
  280. package/wiki/Architecture-Overview.md +303 -0
  281. package/wiki/Audio-System.md +449 -0
  282. package/wiki/CPU-Emulation.md +477 -0
  283. package/wiki/Debugger.md +516 -0
  284. package/wiki/Disk-Drives.md +161 -0
  285. package/wiki/Disk-System-Internals.md +547 -0
  286. package/wiki/Display-Settings.md +88 -0
  287. package/wiki/Expansion-Slots.md +187 -0
  288. package/wiki/File-Explorer.md +259 -0
  289. package/wiki/Getting-Started.md +156 -0
  290. package/wiki/Home.md +69 -0
  291. package/wiki/Input-Devices.md +183 -0
  292. package/wiki/Keyboard-Shortcuts.md +158 -0
  293. package/wiki/Memory-System.md +364 -0
  294. package/wiki/Save-States.md +172 -0
  295. 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
+ };