# text16.txt - LinuxCNC WASM/browser port continuation Created: 2026-06-16 CST This file continues from `text15.txt`. Use it for the next execution batches. ## Current Repository State - Branch: `master` - Remote sync state at creation: `master...origin/master` - Latest commit at creation: ```text 69ccf93 支持真实G代码程序执行 ``` - Working tree at creation: clean - Active project tracker still exists at `PROJECT_COMPLETION_TRACKER.md` - Previous continuation file: `text15.txt` ## Current Priority The first priority remains the real browser CNC simulation page: ```text wasm-port/runtime/ui/simulation/index.html ``` Primary supporting docs: ```text wasm-port/docs/real-browser-simulation-priority.md wasm-port/docs/axis-style-simulation-implementation.md PROJECT_COMPLETION_TRACKER.md ``` Do not switch back to dashboard-only metadata work unless it directly creates a gate or unblocks the browser simulation page. ## Completed Since text15 Start The browser simulation page now has: - AXIS-style browser shell: - titlebar; - File / Machine / View / Help menubar; - toolbar; - Manual Control / MDI tabs; - Preview / DRO tabs; - G-code pane; - machine-state pane; - bottom status bar. - LinuxCNC-backed WASM execution through `createLinuxCncInterpSdk()`. - Built-in test program selector. - Built-in program directory: ```text wasm-port/runtime/ui/simulation/programs/ ``` - Current built-in program modules: - `square-linear.js`; - `pocket-z.js`; - `incremental-loop.js`; - `arc-g2-g3.js`; - `drill-g81.js`. - Program inventory export: ```text wasm-port/runtime/ui/simulation/programs/index.js ``` - Reset / Step Back / Play / Step Forward / Finish playback over LinuxCNC canonical motion events. - Active G-code line highlighting. - Active and executed motion row highlighting. - Live XYZ/ABC readout. - Full toolpath and executed-path SVG rendering. - Moving toolhead marker. - Real operator-provided G-code execution: - `linuxCncRealSimulationApi.runProgramText(programText, metadata)`; - `linuxCncRealSimulationApi.loadProgramFile(file)`; - toolbar `Open` file input for `.ngc/.nc/.tap/.gcode/.txt`. - Editable AXIS-style G-code pane: - loaded file/custom/built-in program text is visible in a textarea; - editor text can be changed before execution; - toolbar `Run Editor Text` executes the current editor contents; - `getProgramText()`, `setProgramText()`, and `runEditorProgramText()` are exposed on the browser API. - Program source metadata: - `program.source`; - `program.sourceLabel`; - `program.filename`; - `document.body.dataset.simulationProgramSource`. ## Current Browser API Available on the simulation page: ```js window.linuxCncRealSimulationApi ``` Current methods: - `getState()` - `getPrograms()` - `runProgramById(programId)` - `runProgramText(programText, metadata)` - `loadProgramFile(file)` - `getProgramText()` - `setProgramText(text, metadata)` - `runEditorProgramText()` - `getPlaybackFrame()` - `resetPlayback()` - `stepPlayback(delta)` - `play()` - `pause()` - `finishPlayback()` All G-code execution must continue to go through LinuxCNC-backed WASM. Browser JS must not interpret G-code or implement planner/machine semantics. ## Validation Baseline The latest full validation completed successfully: ```text real_simulation_programs_node_smoke=ok ui_node_smokes=ok browser_real_simulation_page_smoke=ok axis_style_simulation_docs_node_smoke=ok real_browser_simulation_priority_docs_node_smoke=ok project_release_gate=ok ``` Useful focused commands: ```bash wasm-port/tests/ui/node/verify_real_simulation_programs.sh wasm-port/tests/ui/node/verify_ui_node_smokes.sh SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh wasm-port/tests/docs/node/verify_axis_style_simulation_docs.sh wasm-port/tests/docs/node/verify_real_browser_simulation_priority_docs.sh ``` Full gate: ```bash wasm-port/tests/host/verify_project_release_gate.sh ``` ## Semantic Boundary LinuxCNC remains the only CNC semantic source. Browser code may: - render UI layout and interaction state; - read user-selected G-code files/text; - call the SDK/WASM boundary; - render LinuxCNC-produced canonical output; - animate playback over LinuxCNC-produced canonical motion events; - stage future OPFS/session files when that integration is added. Browser code must not implement: - G-code interpretation; - modal semantics; - tool/cutter compensation semantics; - parameter semantics; - kinematics; - remap behavior; - planner behavior; - machine-control behavior not backed by LinuxCNC/WASM or validated session APIs. ## Next Recommended Batches ### 1. Real G-code Editor Pane Status: complete. Implemented: - show loaded file/custom text in an editor area; - allow editing before run; - add `Run Editor Text`; - preserve line numbers and active-line highlighting; - expose `linuxCncRealSimulationApi.getProgramText()`; - expose `linuxCncRealSimulationApi.setProgramText(text, metadata)`. - expose `linuxCncRealSimulationApi.runEditorProgramText()`. Validation: - browser smoke sets editor text, runs it, and verifies changed LinuxCNC canonical output. ### 2. OPFS Program Persistence Connect real G-code programs to OPFS: - save current program text to OPFS; - load program text from OPFS; - show OPFS path in status/readiness; - keep browser file loading as an import path, not the only path. Validation: - browser smoke load file -> save OPFS -> reload OPFS -> run -> playback. ### 3. AXIS DRO/Modal State Expansion Improve the DRO panel without inventing unsupported data: - derive any available fields from LinuxCNC output or validated summaries; - show unavailable fields as `n/a`; - add tests that prevent silently fabricated G54/G92/TLO/DTG values. Validation: - browser smoke verifies no `undefined` and no fabricated unavailable values. ### 4. Preview Controls Add AXIS-like preview controls: - zoom fit; - reset view; - optional pan/viewport scale state; - keep SVG nonblank and stable. Validation: - browser smoke verifies viewBox changes/reset and toolhead/path remain visible. ### 5. Machine/Session Integration Use the existing OPFS/session workflow: - load machine session; - show machine file readiness; - stage INI/parameter/tool-table/program into WASM; - block run with explicit reasons when readiness is missing. Validation: - OPFS/session browser smoke covers load -> run -> playback. ## Adding More Built-In Test Programs To add a built-in test: 1. Add a module under: ```text wasm-port/runtime/ui/simulation/programs/ ``` 2. Export an object with: ```js { id, label, category, text, expectedMotionTypes, } ``` 3. Import it in: ```text wasm-port/runtime/ui/simulation/programs/index.js ``` 4. Add it to `SIMULATION_TEST_PROGRAMS`. 5. Run: ```bash wasm-port/tests/ui/node/verify_real_simulation_programs.sh SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_real_simulation_browser.sh ``` ## Commit / Upload Rule After each completed implementation batch: 1. Run focused smoke(s). 2. Run `wasm-port/tests/host/verify_project_release_gate.sh` when feasible. 3. Commit with a Chinese title and conclusion body. 4. Push to: ```text http://154.8.160.151:3000/wangdequan/cnc_wams.git ``` ## Immediate Suggested Start Start with "OPFS Program Persistence" because the page can now load, edit, and run real G-code text/files, but programs are not yet saved to or restored from OPFS from within the AXIS shell. Updated after batch 9: compact run summary is implemented. The next recommended batch is adding machine/session run summaries to saved OPFS/session artifacts or making the preview controls more AXIS-like with fit-state persistence. ## Execution Record ### 一、2026-06-16 Real G-code Editor Pane 按 `text16.txt` 的 Immediate Suggested Start 推进,完成 AXIS shell 内真实 G-code 编辑区。 本批新增实质能力: - `runtime/ui/simulation/index.html` 新增 editable G-code pane: - `data-axis-shell="program-editor"`; - `textarea[data-program-editor]`; - `data-program-editor-status`; - 工具栏新增: - `Run Editor Text`; - 页面状态新增 `programEditorState`; - 内置程序加载、真实文本执行、真实文件加载都会同步到 editor textarea; - editor textarea 修改后可直接运行; - `window.linuxCncRealSimulationApi` 新增: - `getProgramText()`; - `setProgramText(text, metadata)`; - `runEditorProgramText()`; - browser smoke 新增验证: - 初始内置程序会同步到 editor; - `runProgramText()` 后 editor 同步自定义文本; - `loadProgramFile()` 后 editor 同步文件文本和 filename metadata; - `setProgramText()` 修改 editor 内容; - `runEditorProgramText()` 通过 LinuxCNC WASM 执行修改后的 G-code,并验证 canonical output 出现修改后的坐标。 关键验证: ```text browser_real_simulation_page_smoke=ok real_simulation_programs_node_smoke=ok ``` 语义边界: - editor 只保存和显示 G-code 文本; - G-code 执行仍通过 LinuxCNC-backed WASM; - JS 不解释 G-code、不规划刀路、不推导 modal/machine semantics。 ### 二、2026-06-16 AXIS DRO/Modal State and Preview Controls 继续按 AXIS 实现文档推进,完成 Phase 3/4 的可落地部分。 本批新增实质能力: - `runtime/ui/simulation/simulation-app.js` 新增: - `createModalState(resultText)`; - `createDroState(frame)`; - `zoomToolpathViewBox(viewBox, zoom)`; - modal display 不再使用硬编码 active G-code 文本,改为显示 LinuxCNC `canon_event=UPDATE_TAG` 字段; - DRO 显示: - actual X/Y/Z/A/B/C 来自 LinuxCNC canonical motion playback frame; - DTG/G54/G92/TLO/velocity 在当前 canonical 输出不可用时明确显示 `n/a`; - `window.linuxCncRealSimulationApi` 新增: - `getDroState()`; - `getModalState()`; - `fitPreview()`; - `zoomPreview(factor)`; - `resetPreview()`; - preview toolbar 新增 Fit / Zoom In / Zoom Out / Reset; - SVG preview 保留 full path、executed path、toolhead,并支持 viewBox 缩放/恢复。 测试覆盖: - Node smoke 验证: - modal state 来自 `UPDATE_TAG`; - unavailable DRO 字段保持显式 `n/a`; - viewBox zoom 会收窄; - browser smoke 验证: - API 暴露; - modal DOM 显示 LinuxCNC 字段; - DRO 不伪造 DTG/G54/G92/TLO/velocity; - preview zoom 改变 viewBox,reset 恢复 fit viewBox; - 现有 built-in/custom/file/editor G-code 执行继续走 LinuxCNC WASM。 关键验证: ```text real_simulation_programs_node_smoke=ok axis_style_simulation_docs_node_smoke=ok browser_real_simulation_page_smoke=ok ``` 语义边界: - JS 只解析 LinuxCNC canonical text 中已经输出的 `UPDATE_TAG` 字段用于显示; - JS 不解释 G-code,不推导 modal 语义,不计算 DTG/G54/G92/TLO/velocity; - preview zoom/reset 只改变 SVG viewBox,不改变 LinuxCNC 生成的 motion events。 ### 三、2026-06-16 AXIS OPFS Program Persistence 继续按 AXIS 实现文档推进,完成 Phase 2 的 OPFS program persistence 闭环。 本批新增实质能力: - AXIS editable G-code pane 新增: - OPFS G-code filename 输入; - `Save OPFS`; - `Load OPFS`; - 页面复用既有 OPFS helpers: - `saveGcodeProgram()`; - `loadGcodeProgram()`; - `gcodeProgramPath()`; - `window.linuxCncRealSimulationApi` 新增: - `getOpfsProgramState()`; - `saveProgramToOpfs(filename)`; - `loadProgramFromOpfs(filename)`; - OPFS load 会调用现有 `runProgramText()`,因此 reloaded program 仍通过 LinuxCNC-backed WASM 执行; - OPFS metadata 写入 program state: - `program.source = "opfs"`; - `program.opfsPath = "linuxcnc/gcode/"`; - statusbar 显示 `Loaded OPFS: ...`。 browser smoke 新增验证: - 设置 editor G-code; - 保存到 `linuxcnc/gcode/axis-opfs-roundtrip.ngc`; - 修改 editor 为不同内容; - 从 OPFS 重新加载保存的程序; - 验证 reloaded canonical output 出现保存内容的坐标; - 验证 editor、body dataset、statusbar 和 OPFS state metadata 同步。 关键验证: ```text browser_real_simulation_page_smoke=ok real_simulation_programs_node_smoke=ok ``` 语义边界: - OPFS 只持久化 G-code 文本; - OPFS load 后仍走 LinuxCNC-backed WASM interpreter; - JS 不解释 G-code,不推导机床状态,不绕过 canonical output。 ### 四、2026-06-16 AXIS Machine/Session Readiness 继续按 AXIS 实现文档推进,完成 Phase 5 的 readiness 前半段。 本批新增实质能力: - Manual Control panel 新增 `data-axis-shell="machine-session"` 区域: - machine id; - session id; - G-code filename; - `Check Session`; - readiness phase/missing/path readout; - 页面复用既有 OPFS/session helper: - `readMachineSessionReadiness()`; - `window.linuxCncRealSimulationApi` 新增: - `getMachineReadiness()`; - `checkMachineSessionReadiness(options)`; - readiness DOM 同步: - `document.body.dataset.machineSessionReady`; - `data-machine-readiness-phase`; - `data-machine-readiness-missing`; - `data-machine-readiness-path="ini"`; - `data-machine-readiness-path="gcode"`。 browser smoke 新增验证: - 检查不存在的 machine/session,确认 readiness 为 blocked,并报告 missing `ini` 和 `gcode`; - 通过既有 OPFS helpers 写入: - machine INI; - parameter file; - tool table; - G-code; - machine session snapshot; - 再次调用 AXIS API 检查 readiness,确认 phase 为 `ready`,missing 为空; - 验证 readiness paths 与 OPFS path model 一致,并同步到 API/body/DOM。 关键验证: ```text browser_real_simulation_page_smoke=ok ``` 语义边界: - readiness 只检查 OPFS 文件存在和 snapshot envelope; - JS 不合成 INI/tool/parameter/G-code 语义; - 本批不加载或执行完整 machine session,只把可运行前置条件暴露给 AXIS shell。 ### 五、2026-06-16 AXIS Machine/Session WASM Staging 继续按 AXIS 实现文档推进,完成 Phase 5 的 ready session load/stage 能力。 本批新增实质能力: - Manual Control panel 的 machine-session 区域新增: - `Load Session`; - loaded INI WASM path; - loaded parameter WASM path; - loaded tool-table WASM path; - 页面复用既有 LinuxCNC-backed helpers: - `createLinuxCncInterpSdk()`; - `createLinuxCncIniSdk()`; - `loadMachineSessionFromOpfs()`; - `window.linuxCncRealSimulationApi` 新增: - `getMachineSessionLoadState()`; - `loadReadyMachineSession(options)`; - `loadReadyMachineSession()` 先调用 readiness check;blocked 时返回 blocked load state,不 stage; - ready 时创建 LinuxCNC interp/INI SDK,调用 `loadMachineSessionFromOpfs()`, 把 OPFS INI/parameter/tool-table staged 到 WASM filesystem; - DOM 同步: - `document.body.dataset.machineSessionLoaded`; - `data-machine-session-loaded-path="ini"`; - `data-machine-session-loaded-path="parameters"`; - `data-machine-session-loaded-path="toolTable"`。 browser smoke 新增验证: - 在 ready machine/session 基础上调用 `loadReadyMachineSession()`; - 使用显式 WASM paths: - `/work/axis-smoke/machine.ini`; - `/work/axis-smoke/linuxcnc.var`; - `/work/axis-smoke/tool.tbl`; - 验证 API 返回 loaded state; - 验证 API/body/DOM 中 loaded paths 同步。 关键验证: ```text browser_real_simulation_page_smoke=ok ``` 语义边界: - session load/stage 完全通过既有 LinuxCNC-backed SDK 和 OPFS bridge; - JS 不解释 INI/tool-table/parameter/G-code; - 本批只 stage machine session,不改变 program execution semantics。 ### 六、2026-06-16 AXIS Loaded-Session Program Execution 继续按 AXIS 实现文档推进,让 loaded machine session 真正参与程序执行。 本批新增实质能力: - `simulation-app.js` 新增: - `runLinuxCncProgram(interp, programText, options)`; - `runRealBrowserSimulation({ interp, iniPath })`; - state.execution: - `mode: "linuxcnc-wasm"`; - `mode: "linuxcnc-wasm-with-ini"`; - `iniPath`; - AXIS page 在 `loadReadyMachineSession()` 成功后保留 staged interpreter; - 后续 built-in/custom/editor/OPFS text execution 自动使用: - staged interpreter; - loaded session INI WASM path; - LinuxCNC-backed `runProgramWithIni()`; - program source label 会显示 `Session INI: `。 browser smoke 新增验证: - 在 ready session staged 后设置 editor G-code; - 调用 `runEditorProgramText()`; - 验证 returned state: - `execution.mode === "linuxcnc-wasm-with-ini"`; - `execution.iniPath === "/work/axis-smoke/machine.ini"`; - canonical output 包含修改后的 G-code 坐标; - source label 包含 loaded session INI path。 Node smoke 新增验证: - `runLinuxCncProgram()` 无 INI 时调用 `runProgram()`; - 有 INI 时调用 `runProgramWithIni()`; - `runRealBrowserSimulation({ interp, iniPath })` 返回 `linuxcnc-wasm-with-ini` execution metadata。 关键验证: ```text real_simulation_programs_node_smoke=ok browser_real_simulation_page_smoke=ok ``` 语义边界: - JS 只选择 LinuxCNC-backed interpreter SDK 方法; - G-code 解释仍由 LinuxCNC WASM 执行; - INI/tool/parameter state 仍由 existing OPFS bridge 和 LinuxCNC SDK staged/loaded。 ### 七、2026-06-16 AXIS Run Mode Status and OPFS Session-Backed Execution 继续按 AXIS 实现文档推进,补齐 visible run-mode 状态,并扩展 OPFS program 在 loaded session 下的执行覆盖。 本批新增实质能力: - toolbar status strip 新增: - `Run mode Standalone`; - loaded session 执行后显示 `Session-backed: `; - statusbar 同步显示 run mode; - body dataset 新增: - `data-run-mode="standalone"`; - `data-run-mode="session-backed"`; - `window.linuxCncRealSimulationApi` 新增: - `getRunMode()`; - 每次 program render 后同步 run-mode UI/API 状态。 browser smoke 新增验证: - 初始页面 run mode 为 standalone; - loaded session editor run 后 run mode 切换为 session-backed; - OPFS-loaded G-code 在 session-backed 模式下执行: - 保存 `axis-session-opfs.ngc` 到 OPFS; - 修改 editor 为不同内容; - 从 OPFS load/run; - 验证 `execution.mode === "linuxcnc-wasm-with-ini"`; - 验证 canonical output 来自 OPFS 保存内容; - 验证 source label 同时包含 OPFS path 和 Session INI path。 关键验证: ```text real_simulation_programs_node_smoke=ok browser_real_simulation_page_smoke=ok ``` 语义边界: - run mode 只反映当前 LinuxCNC-backed execution path; - OPFS program load/run 仍通过 LinuxCNC-backed `runProgramWithIni()`; - JS 不解释 G-code,也不实现 session semantics。 ### 八、2026-06-16 AXIS Run Mode Session Toggle 继续按 AXIS 实现文档推进,补齐 standalone/session-backed 显式切换。 本批新增实质能力: - Manual Control machine-session actions 新增: - `Use Session` checkbox; - run mode 逻辑新增: - loaded session 存在且 Use Session 开启时,程序执行走 loaded session INI; - Use Session 关闭时,即使 session staged,也回到 standalone execution; - `window.linuxCncRealSimulationApi` 新增: - `setUseLoadedSession(value)`; - `getRunMode()` 返回: - `mode`; - `label`; - `iniPath`; - `useLoadedSession`; - `sessionLoaded`。 browser smoke 新增验证: - loaded session editor run 后为 session-backed; - 调用 `setUseLoadedSession(false)` 后 checkbox 同步关闭; - 再次运行 editor G-code,确认: - `execution.mode === "linuxcnc-wasm"`; - `execution.iniPath === null`; - body run mode 维持 standalone; - 调用 `setUseLoadedSession(true)` 后 checkbox 同步开启; - 后续 OPFS program load/run 再次使用 loaded session INI。 关键验证: ```text real_simulation_programs_node_smoke=ok browser_real_simulation_page_smoke=ok ``` 语义边界: - Use Session 只选择 LinuxCNC-backed execution method; - 不修改 staged machine session 内容; - JS 不解释 G-code/INI/tool/parameter semantics。 ### 九、2026-06-16 AXIS Run Summary 继续按 AXIS 实现文档推进,增加 compact run summary,方便操作时判断当前运行上下文。 本批新增实质能力: - Machine State readout 新增: - Execution Mode; - Session INI; - OPFS Program; - Session State; - `window.linuxCncRealSimulationApi` 新增: - `getRunSummary()`; - run summary 字段: - `apiName: "real-browser-simulation-run-summary"`; - `executionMode`; - `runMode`; - `sessionIniPath`; - `opfsProgramPath`; - `readinessPhase`; - `sessionLoadPhase`; - `programSource`; - readiness/load/run/toggle 后都会同步 run summary DOM。 browser smoke 新增验证: - 初始 summary 为 standalone `linuxcnc-wasm`; - session ready/load 后 summary 显示 `ready / loaded`; - session-backed editor run 后 summary 显示: - `linuxcnc-wasm-with-ini`; - `/work/axis-smoke/machine.ini`; - Use Session 关闭后 standalone run summary 回到: - `linuxcnc-wasm`; - Session INI `n/a`; - session-backed OPFS run 后 summary 显示: - OPFS program path `linuxcnc/gcode/axis-session-opfs.ngc`。 关键验证: ```text real_simulation_programs_node_smoke=ok browser_real_simulation_page_smoke=ok ``` 语义边界: - run summary 只汇总已有 LinuxCNC-backed execution/session/readiness state; - 不推导 CNC semantics; - 不改变 execution path。 ### 十、2026-06-17 AXIS MDI Text and Preview Pan 继续按 AXIS 实现文档推进,补齐 MDI scratch 文本路径和 preview pan 控制。 本批新增实质能力: - AXIS MDI panel 新增: - `data-mdi-program-text` scratch G-code textarea; - `Load MDI Text`; - `Run MDI Text`; - `data-mdi-status`; - `window.linuxCncRealSimulationApi` 新增: - `loadProgramText(text, metadata)`; - `runMdiProgramText(text)`; - `loadProgramText()` 只把 operator text staging 到 AXIS G-code pane, 不执行、不解释 G-code; - `runMdiProgramText()` 复用既有 `runProgramText()`,继续走 LinuxCNC-backed WASM execution; - preview controls 新增 pan left/right/up/down; - `simulation-app.js` 新增纯显示 helper: - `panToolpathViewBox(viewBox, offset)`; - browser API 新增: - `panPreview(dx, dy)`; - `fitPreview()` / `resetPreview()` 清除 pan offset,zoom/pan 不改变 canonical motion state。 browser smoke 新增验证: - MDI 控件存在; - `loadProgramText()` 可以 staging 文本到 editor/statusbar; - MDI scratch 文本执行后 canonical output 包含 LinuxCNC-produced `STRAIGHT_FEED`; - `panPreview()` 会移动已填充 toolpath viewBox; - `fitPreview()` 会清除 pan offset 并恢复 fit viewBox。 Node smoke 新增验证: - `panToolpathViewBox()` 只平移 viewBox,不改变 width/height; - existing zoom helper 仍围绕 fit viewBox 缩放。 文档同步: - `wasm-port/docs/axis-style-simulation-implementation.md` 将 `loadProgramText()` 从 future API 移入 required API; - Phase 2 增补 MDI text execution; - Phase 4 增补 preview pan; - Immediate Next Batch 更新为当前后续方向:run-control blocked/ready messaging 和 preview state readback。 关键验证: ```text real_simulation_programs_node_smoke=ok axis_style_simulation_docs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - MDI text 只是 operator-provided program text,仍由 LinuxCNC WASM 解释; - preview pan/zoom 只改变 SVG viewBox; - JS 不实现 G-code、modal、planner、kinematics 或 machine runtime semantics。 ### 十一、2026-06-17 AXIS Run-Control State and Preview State Readback 继续按“页面样式和功能对标 LinuxCNC AXIS”的方向推进,补齐 operator-facing 状态反馈,避免 session-backed/standalone 执行路径不透明。 本批新增实质能力: - toolbar status strip 新增 run-control 状态行: - `data-run-control-state`; - `document.body.dataset.runControlPhase`; - 初始显示 `fallback`,说明 Use Session 开启但尚无 loaded machine session; - Machine State readout 新增: - Run Control; - Preview; - browser API 新增: - `getRunControlState()`; - `getPreviewState()`; - run-control state 字段: - `apiName: "real-browser-simulation-run-control-state"`; - `phase`; - `requestedMode`; - `executionMode`; - `reason`; - `canUseSession`; - `loadedIniPath`; - preview state 字段: - `apiName: "real-browser-simulation-preview-state"`; - `zoom`; - `pan`; - `fitViewBox`; - `viewBox`; - preview controls 的 pan/zoom 状态同步到: - `data-preview-zoom`; - `data-preview-pan`; - Machine State Preview; - Manual Control 新增 explicit blocked LED: - `data-axis-machine-control-state`; - 明确 jog/spindle/coolant 未绑定真实 machine runtime。 AXIS visual polish: - preview pan controls 从长文字改为更接近工具按钮的 `< > ^ v`; - 保留 `aria-label` 和原有 `data-preview-pan-*` selectors; - 控件仍保持密集、灰色、边框式 AXIS 风格。 browser smoke 新增验证: - 初始 run-control 为 fallback; - run-control DOM 解释 standalone fallback 原因; - preview pan 后 API/DOM 同步; - fit 后 pan offset 清零; - session load 后 run-control 显示 loaded INI 可用; - session-backed run 后 run-control 为 ready; - Use Session 关闭后 run-control 说明 loaded session 被 bypass; - real-machine controls 必须显示 `not bound` blocked 状态。 文档同步: - `wasm-port/docs/axis-style-simulation-implementation.md` 增补: - `getRunControlState()`; - `getPreviewState()`; - real jog/spindle/coolant unbound blocked state; - run-control ready/fallback 状态。 关键验证: ```text real_simulation_programs_node_smoke=ok axis_style_simulation_docs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - run-control 只反映当前 LinuxCNC-backed execution path; - preview state 只反映 SVG viewBox; - unbound machine-control 状态不伪造真实 jog/spindle/coolant 行为。 ### 十二、2026-06-17 AXIS Canonical Machine Status Panel 继续推进 AXIS 对标,把左侧和 Machine State 中的 spindle/coolant/tool/override 状态从静态 UI 升级为 LinuxCNC canonical output 派生状态。 本批新增实质能力: - `simulation-app.js` 新增: - `createMachineStatusState(resultText)`; - simulation state 新增: - `machineStatus`; - browser API 新增: - `getMachineStatusState()`; - machine status 字段: - `apiName: "real-browser-simulation-machine-status-state"`; - `source: "linuxcnc-canonical-events"`; - `spindle.state` / `spindle.direction` / `spindle.speed`; - `coolant.mist` / `coolant.flood`; - `tool.selected` / `tool.current` / `tool.pocket` / `tool.lengthOffset`; - `overrides.feed` / `overrides.speed` / `overrides.adaptiveFeed` / `overrides.feedHold`; - AXIS UI 新增/同步: - Manual Control Spindle status LED; - Manual Control Coolant status LED; - Machine State Spindle row; - Machine State Coolant row; - Machine State Tool row; - Machine State Overrides row; - 没有 LinuxCNC canonical event 的字段保持 `n/a`。 canonical event mapping: - `SET_SPINDLE_SPEED` -> spindle speed; - `START_SPINDLE_CLOCKWISE` / `START_SPINDLE_COUNTERCLOCKWISE` -> spindle direction/state; - `STOP_SPINDLE_TURNING` -> spindle off; - `MIST_ON/OFF`、`FLOOD_ON/OFF` -> coolant state; - `SELECT_TOOL`、`CHANGE_TOOL_NUMBER`、`USE_TOOL_LENGTH_OFFSET` -> tool/TLO; - `ENABLE/DISABLE_*_OVERRIDE`、`ENABLE/DISABLE_FEED_HOLD` -> override rows。 browser smoke 新增验证: - 初始 built-in program 未产生 machine-status events 时,spindle/coolant 明确显示 `n/a`; - 执行包含 `S1200 M3/M5/M7/M8/M9/M48/M50/T2/M6/G43/G49/M61` 的 program; - 验证 API 和 DOM 中 spindle/coolant/tool/override 状态均来自 LinuxCNC canonical output。 Node smoke 新增验证: - `createMachineStatusState()` 对 unavailable canonical output 返回 `n/a`; - spindle/coolant/override canonical events 可正确折叠为最终状态; - tool/TLO canonical events 可正确折叠为当前 tool/pocket/TLO。 文档同步: - `wasm-port/docs/axis-style-simulation-implementation.md` 增补: - machine status canonical event display; - `getMachineStatusState()` required API。 关键验证: ```text real_simulation_programs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - machine status 只显示 LinuxCNC canonical output 已产生的事件; - 前端不推断真实 spindle/coolant/tool runtime; - 缺失字段继续显示 `n/a`。 ### 十三、2026-06-17 AXIS Preview Extents, Origin, and Legend 继续推进 AXIS preview 对标,补齐更接近 LinuxCNC AXIS 的预览覆盖层。 本批新增实质能力: - SVG preview 新增: - `data-preview-extents` extents rectangle; - `data-preview-origin-x` / `data-preview-origin-y` origin axes; - `data-preview-origin` origin marker; - `data-axis-shell="preview-legend"` legend; - `data-preview-extents-label` extents text; - `renderToolpath()` 现在基于 LinuxCNC canonical motion 生成的 `createToolpathViewBox(motion)` 同步: - extents rectangle; - origin axes; - origin marker size; - extents label; - preview legend 显示: - Extents; - Full path; - Executed path; - Origin。 browser smoke 新增验证: - AXIS shell 必须存在 preview legend; - SVG extents rectangle width/height > 0; - origin marker 位于 `0,0`; - extents label 同时包含 X/Y 范围; - zoom/pan/fit 仍保持原有行为。 文档同步: - `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 记录: - motion-derived extents rectangle; - origin axes/marker; - preview legend。 关键验证: ```text real_simulation_programs_node_smoke=ok axis_style_simulation_docs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - extents 只来自 LinuxCNC canonical motion path; - origin marker/axes 只是 preview display overlay; - 不新增浏览器端 CNC 几何、planner 或 kinematics 语义。 ### 十四、2026-06-17 AXIS Three.js Toolpath Preview 按用户要求,刀具轨迹预览区改用 Three.js,版本要求为: ```json "three": "^0.183.2" ``` 本批新增实质能力: - 新增 `wasm-port/runtime/ui/simulation/package.json`: - `dependencies.three = "^0.183.2"`; - 新增 `package-lock.json` 记录 resolved dependency; - 新增 vendored runtime build: - `runtime/ui/simulation/vendor/three/three.module.js`; - `runtime/ui/simulation/vendor/three/three.core.js`; - `runtime/ui/simulation/vendor/three/LICENSE`; - `simulation-app.js` 直接 import: - `./vendor/three/three.module.js`; - preview 主视图新增: - ``; - 原 SVG preview 改为 hidden fallback/state surface: - 保留 `data-toolpath-svg`; - 保留 polyline/head/extents selectors,兼容既有 tests/API。 Three.js 渲染内容: - orthographic camera; - dark AXIS-like background; - motion-derived extents outline; - origin X/Y axes; - full canonical path; - executed canonical path; - origin marker; - active tool marker; - camera fit/zoom/pan 与现有 `fitPreview()` / `zoomPreview()` / `panPreview()` 同步。 browser smoke 新增验证: - `data-toolpath-three.dataset.threeReady === "true"`; - Three.js revision 为 `183`; - Three path point count 等于 LinuxCNC canonical motion count; - playback step 后 Three executed point count 前进; - SVG fallback viewBox/polyline 继续保持兼容。 docs smoke 新增验证: - AXIS implementation docs 记录 Three.js `^0.183.2`; - simulation package 声明 `three: ^0.183.2`; - vendored `three.core.js` revision 为 `183`; - real-browser priority docs smoke 确认页面包含 `data-toolpath-three`。 关键验证: ```text real_simulation_programs_node_smoke=ok axis_style_simulation_docs_node_smoke=ok real_browser_simulation_priority_docs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - Three.js 只负责显示 LinuxCNC canonical motion; - 不在 Three.js/浏览器端实现 G-code、planner、kinematics 或 compensation; - SVG fallback 仅作为 state/compatibility surface 保留。 ### 十五、2026-06-17 AXIS Three.js Preview View Modes 继续按用户“预览区使用 threejs、对标 LinuxCNC AXIS”的要求推进,补齐 AXIS 常见预览视图模式。 本批新增实质能力: - Preview toolbar 新增: - `Top`; - `Front`; - `Side`; - `Iso`; - `window.linuxCncRealSimulationApi` 新增: - `setPreviewViewMode(mode)`; - `getPreviewState()` 新增: - `viewMode`; - Three.js preview canvas 新增/同步: - `data-three-view-mode`; - UI 新增: - `data-preview-view-label`; - active view-mode button state。 Three.js camera behavior: - `top`:正交 top view; - `front`:正交 front-style view; - `side`:正交 side-style view; - `iso`:isometric-like angled view; - zoom/pan/fit 继续复用现有 viewBox 状态; - Three.js 仅显示 LinuxCNC canonical motion,不改变 motion semantics。 browser smoke 新增验证: - API 必须存在 `setPreviewViewMode()`; - 切换 `iso` 后: - `getPreviewState().viewMode === "iso"`; - Three canvas `data-three-view-mode === "iso"`; - UI label 显示 `Iso`; - 切换 `side` 后: - active button state 为 true; - 切回 `top` 后继续执行 fit/zoom/pan smoke。 文档同步: - `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 增补 Top/Front/Side/Iso view modes; - Required APIs 增补 `setPreviewViewMode(mode)`。 关键验证: ```text real_simulation_programs_node_smoke=ok axis_style_simulation_docs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - view modes 只改变 Three.js camera; - 不改变 LinuxCNC canonical motion path; - 不实现浏览器端 kinematics 或 G-code 几何语义。 ### 十六、2026-06-17 AXIS Three.js Grid, Axis Labels, and Pixel Smoke 继续按“预览区使用 threejs、对标 LinuxCNC AXIS”推进,补齐 Three.js 预览的 网格、轴标签和 canvas 非空验证。 本批新增实质能力: - Three.js preview 新增动态 grid: - `chooseGridStep(span)` 按 viewBox 尺寸选择 1/2/5/10 系列步距; - `addThreeGrid(scene, viewBox)` 生成 viewBox 覆盖范围内的 grid lines; - canvas dataset: - `data-three-grid-step`; - `data-three-grid-lines`; - Three.js preview 新增 X/Y/Z axis labels: - `createTextSprite(text, color)`; - `addThreeAxisLabels(scene, viewBox)`; - canvas dataset: - `data-three-axis-labels="3"`; - Three.js preview smoke 新增 WebGL pixel readback: - 获取 `webgl2` / `webgl` context; - `readPixels()` 检查 canvas 中心像素非透明空白; - 继续验证 Three.js revision/path points/executed points。 文档同步: - `wasm-port/docs/axis-style-simulation-implementation.md` Phase 4 增补: - dynamic grid lines; - X/Y/Z axis labels; - browser smoke canvas pixel check。 关键验证: ```text real_simulation_programs_node_smoke=ok axis_style_simulation_docs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - grid 和 labels 只使用当前 preview viewBox; - Three.js 仍只显示 LinuxCNC canonical motion; - pixel smoke 只验证渲染非空,不推导 CNC 语义。 ### 十七、2026-06-17 Browser Virtual HAL for AXIS Manual Controls 接续“虚拟 HAL 业务”,本批把 AXIS 手动控制从静态未绑定状态推进为浏览器 虚拟 HAL 状态模型,并接入 UI、SDK 和 WASM bridge。 本批新增实质能力: - 新增 `wasm-port/runtime/sdk/src/linuxcnc-hal.js`: - `VIRTUAL_HAL_AXISUI_PINS` 对齐 `linuxcnc/bin/axis` 中的 axisui pins: `jog.x/y/z/a/b/c/u/v/w`、`jog.increment`、notification pins、 `error`、`abort`; - `createVirtualHalState()` / `applyVirtualHalAction()` 管理 ESTOP、Power、 Home、Jog、Touch Off、Spindle、Coolant、Limit Override、Brake 等状态; - `createVirtualHalDroState()` 输出 AXIS DRO 默认/实际位置; - `createVirtualHalLimitsHomeState()` 输出 home/limit/fault rows; - `createVirtualHalMachineStatusState()` 输出 spindle/coolant/tool/override state; - `createVirtualHalWasmBridgeSnapshot()` 生成可写入 standalone HAL adapter 的 pin/value snapshot。 - SDK 入口新增 re-export: - virtual HAL 状态、action、DRO、limits/home、machine status、runtime、 bridge snapshot、jog increment parser。 - Interpreter SDK 新增 HAL bridge API: - `hasWasmFunction(name)`; - `resetHal()`; - `setHalValue({ kind, name, type, value, connected })`; - `applyVirtualHalSnapshot(snapshot, options)`; - `applyVirtualHalState(halState, options)`; - `probeHalNamed(name)`。 - WASM wrapper 新增导出: - `lcinterp_hal_reset()`; - `lcinterp_hal_set_value()`; - `lcinterp_probe_hal_named()`; - `build_wasm_core.sh` 已把这些函数加入 `EXPORTED_FUNCTIONS`。 - Browser simulation UI 接入: - F1/F2 快捷键驱动 ESTOP/Power; - Ctrl-Home 驱动 Home All; - Manual jog 更新 `jog.*` pins 和 DRO; - spindle/coolant/brake/limit override 写入 virtual HAL state; - diagnostics artifact 新增 `virtualHal`; - machine control state 从“not bound”变为 `browser virtual HAL active for jog/spindle/coolant/home simulation`。 - Bridge snapshot 同时输出: - AXIS Python component 内部 pin 名,例如 `jog.x`; - HAL 全名,例如 `axisui.jog.x`; - machine/task pins,例如 `halui.machine.is-on`; - spindle/coolant pins,例如 `spindle.0.speed-out`、 `iocontrol.0.coolant-flood`。 新增/扩展验证: - `verify_real_simulation_programs.mjs` 覆盖 virtual HAL SDK、runtime snapshot、 `axisui.*` HAL 全名、DRO、home、spindle、coolant; - `real_simulation_page_smoke.html` 覆盖 F1/F2/Ctrl-Home/jog/spindle/coolant 的 浏览器交互; - `verify_interp_wasm.mjs` 在新 WASM 导出存在时验证: `applyVirtualHalState()` 写入 HAL adapter 后,`probeHalNamed()` 能读到 `_hal[jog.x]`、`_hal[axisui.jog.x]`、`_hal[halui.machine.is-on]`、 `_hal[spindle.0.speed-out]`、`_hal[iocontrol.0.coolant-flood]`。 关键验证: ```text real_simulation_programs_node_smoke=ok interp_wasm_node_smoke=ok (SKIP_INTERP_BUILD=1) browser_real_simulation_page_smoke=ok (SKIP_INTERP_BUILD=1) sdk_surface_node_smoke=ok ui_node_smokes=ok git diff --check ok ``` 当前构建备注: - 当前 Codex shell 的 `PATH` 未解析到 `emcc`,完整 `build_wasm_core.sh` 会停在 `emcc: command not found`; - 这不是代码侧缺少 Emscripten 的结论,只是本 shell 未加载用户已有的 Emscripten 环境; - 快速 smoke 已用现有 WASM 产物验证旧路径不回归,新导出的 HAL bridge smoke 会在 重建后的 WASM 存在对应函数时自动执行。 语义边界: - virtual HAL 只模拟 AXIS/manual UI 与 standalone HAL adapter 的状态桥; - 不在浏览器端实现 LinuxCNC realtime HAL、motion controller、planner、 kinematics 或 G-code 语义; - G-code execution 和 canonical motion 仍来自 LinuxCNC interpreter WASM。 ### 十八、2026-06-17 Project-level Virtual HAL SDK Boundary 按用户要求“虚拟 HAL 适合整个项目”,本批把上一节的 simulation/UI 虚拟 HAL 提升为项目级 SDK host-boundary 能力,供 simulation、INI panel、Node/browser smoke、外部 dashboard 和 interpreter bridge 共用。 新增项目级 API: - `VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS`: - `lcinterp_hal_reset`; - `lcinterp_hal_set_value`; - `lcinterp_probe_hal_named`; - `VIRTUAL_HAL_PROJECT_PIN_GROUPS`: - `axisui`; - `axis`; - `task`; - `spindle-coolant`; - `createVirtualHalPinInventory(halState)`: - 输出全部 bridge pin rows; - 按项目级 pin group 归类; - `createVirtualHalBridgeReadiness(options)`: - 检查 snapshot 是否包含 required pins; - 检查 caller-provided WASM function evidence 是否覆盖 `VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS`; - 无 evidence 时显式 blocked:`wasm-function-evidence`; - `createVirtualHalBridgeActionPlan(readiness)`: - blocked 时给出下一步: `wasm-port/tools/build_wasm_core.sh`; `SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh`; - ready 时返回空 command; - `createVirtualHalProjectReport(options)`: - 汇总 state、DRO、limits/home、machine status、pin inventory、 WASM bridge snapshot、bridge readiness、bridge action plan; - `applyVirtualHalToInterpSdk(interpSdk, halState, options)`: - 对有 `applyVirtualHalState()` 或 `applyVirtualHalSnapshot()` 的 interpreter SDK 做统一适配; - `createLinuxCncVirtualHalRuntime()` 新增: - `getPinInventory()`; - `getProjectReport(options)`; - `applyToInterpSdk(interpSdk, options)`。 文档同步: - `runtime/sdk/README.md` 新增 `Project-level virtual HAL boundary` 小节; - `docs/project-release-handoff.md` 把 project-level virtual HAL 纳入当前支持 workflow; - `PROJECT_COMPLETION_TRACKER.md` 的 SDK/API surface 行记录 pin inventory、 bridge readiness/action-plan、project report、interpreter apply adapter; - `verify_project_release_handoff_docs.mjs` 增加文档 gate,防止后续退回页面私有 virtual HAL。 新增/扩展验证: - `verify_sdk_surface.mjs` 覆盖: - SDK re-export; - constants discovery; - virtual HAL snapshot; - pin inventory; - blocked/ready bridge readiness; - bridge action plan; - project report; - runtime project report; - fake interpreter SDK apply wrapper; - `verify_project_release_handoff_docs.mjs` 覆盖 handoff/README 中的项目级 virtual HAL API 和 realtime HAL runtime 边界声明。 关键验证: ```text sdk_surface_node_smoke=ok project_release_handoff_docs_node_smoke=ok real_simulation_programs_node_smoke=ok git diff --check ok ``` 语义边界: - project-level virtual HAL 仍是 host-boundary adapter; - 它可服务 UI/session/diagnostics/dashboard 和 `_hal[...]` interpreter probe; - 它不是 LinuxCNC realtime HAL runtime; - 不提升 task、motion、HAL module loading、HALUI process、Tcl/Python process、 external device semantics。 ### 十九、2026-06-17 Simulation-grade LinuxCNC Realtime HAL / halcmd / Motion Replacement 按用户要求“在满足仿真方面,实现 LinuxCNC realtime HAL / halcmd / motion controller 的完整替代,以虚拟 HAL 方式实现”,本批把上一节项目级 virtual HAL 从 bridge/readiness 推进为仿真级 runtime replacement。 新增实质能力: - `VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS`: - `linuxcnc-realtime-hal`; - `halcmd`; - `motion-controller`; - `VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES` 新增: - `realtime-hal-simulation-replacement`; - `halcmd-simulation-replacement`; - `motion-controller-simulation-replacement`; - 新增 `executeVirtualHalcmd()`: - 作为 `executeVirtualHalCommand()` 的 halcmd 语义别名; - 支持当前仿真所需 `setp`、`sets`、`newsig`、`net`、`show`、`getp`、`gets`、 `loadrt`、`loadusr`、`addf`、`start`、`stop`、`unlinkp`、`motion-step`; - 新增 `stepVirtualHalMotionController()`: - 多周期 servo step; - 输出每周期 position/motion frame; - 更新 target、velocity、distance-to-go、in-position; - 新增 `createVirtualHalSimulationReplacementReport()`: - 明确报告 realtime HAL、halcmd、motion controller 三类仿真替代 ready 状态; - 保留 `hardRealtime: false`、`realtimeKernelAbi: false`,避免伪装为 Linux kernel realtime ABI; - `createLinuxCncVirtualHalRuntime()` 新增: - `executeHalcmd()`; - `stepMotionController()`; - `getSimulationReplacementReport()`。 Browser simulation API 新增: - `executeVirtualHalcmd()`; - `executeVirtualHalCommand()`; - `stepVirtualHalMotionController()`; - `getVirtualHalSimulationRuntimeReport()`; - `getVirtualHalSimulationReplacementReport()`; - `getVirtualRealtimeHalRuntimeReport()`; - diagnostics artifact 新增 `virtualHalSimulationReplacement`。 新增/扩展验证: - `verify_sdk_surface.mjs` 覆盖: - replacement target constants; - runtime capability constants; - `executeVirtualHalcmd()`; - `stepVirtualHalMotionController()`; - `createVirtualHalSimulationReplacementReport()`; - runtime wrapper 的 `executeHalcmd()` / `stepMotionController()` / `getSimulationReplacementReport()`; - `real_simulation_page_smoke.html` 覆盖: - 页面 API 暴露 halcmd/motion/replacement report; - browser 中执行 `loadrt`、`addf`、`setp`、`show pin`; - browser 中执行 motion controller 多周期 step; - diagnostics artifact 携带 replacement report。 关键验证: ```text sdk_surface_node_smoke=ok project_release_gate_manifest_node_smoke=ok project_release_artifact_url_workflow_node_smoke=ok project_batch_acceptance_workflow_node_smoke=ok project_batch_acceptance_artifact_node_smoke=ok real_simulation_programs_node_smoke=ok browser_real_simulation_page_smoke=ok git diff --check ok ``` 语义边界: - 本批实现的是 simulation-grade replacement; - Browser/SDK 仿真不再依赖 host `halcmd`、host realtime HAL process 或 host motion process 来完成页面/Node 仿真闭环; - 仍不声称提供 Linux kernel hard-realtime ABI、外部硬件驱动 ABI、native HAL module ABI; - G-code 执行、canonical event、planner/interpreter 语义仍来自 LinuxCNC-backed WASM。