# LinuxCNC WASM SDK This SDK exposes browser/Node JavaScript wrappers for standalone WASM modules built from vendored LinuxCNC source. ## Boundary The SDK is a host-boundary layer only. It may: - load generated Emscripten modules; - allocate and free C strings; - write text files into the Emscripten filesystem; - call exported C ABI functions; - return LinuxCNC-produced text output to JavaScript callers. The SDK must not implement G-code interpretation, canonical motion behavior, tool semantics, parameter semantics, kinematics, or planner behavior. Those behaviors must continue to come from vendored LinuxCNC source through the C ABI. ## Entrypoints Use `src/index.js` for stable imports: ```js import { INI_PANEL_ENTRIES, analyzeIniRuntimeBoundaries, createControlPageBrowserApiManifest, createControlPageBrowserApiMethods, createControlPageBrowserApiSchema, createIniPanelLaunchApiManifest, createIniPanelLauncherLinkViewModel, createIniPanelShellApiSurfaceInventory, createIniPanelShellControlPageContract, createIniPanelShellIntegrationManifest, createIniPanelShellIntegrationReadiness, createIniPanelShellIntegrationSchema, createIniPanelShellIntegrationWorkflowPlan, createIniPanelShellSessionReadinessWorkflowReport, createIniPanelShellViewModel, createIniPanelShellWorkflowOverviewContract, createIniPanelShellWorkflowOverviewEmbeddingMountDomContract, createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel, VIRTUAL_HAL_COMMAND_SCRIPT_FIXTURES, VIRTUAL_HAL_COVERAGE_STATES, VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES, VIRTUAL_HAL_PROJECT_PIN_GROUPS, VIRTUAL_HAL_SIM_CONFIG_SOURCE_TARGETS, VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES, VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS, VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES, VIRTUAL_HAL_SOURCE_FILES, VIRTUAL_HAL_SYSTEM_PIN_FAMILIES, VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS, applyVirtualHalAction, applyVirtualHalPinUpdates, applyVirtualHalToInterpSdk, createLinuxCncIniSdk, createLinuxCncInterpSdk, createLinuxCncVirtualHalRuntime, createVirtualHalCommandScriptFixtureReport, createVirtualHalMotionControllerMatrixReport, createMachineSessionPersistenceDisplayViewModel, createMachineSessionPersistenceRenderState, createMachineSessionPersistenceSummary, createVirtualHalBridgeActionPlan, createVirtualHalBridgeReadiness, createVirtualHalIntegrityReport, createVirtualHalPinInventory, createVirtualHalPinRegistry, createVirtualHalProjectReport, createVirtualHalSimConfigSourceCoverageReport, createVirtualHalSimulationReplacementReport, createVirtualHalSimulationRuntimeReport, createVirtualHalSourceComplianceReport, createVirtualHalState, createVirtualHalSystemCoverageReport, createVirtualHalWasmBridgeSnapshot, executeVirtualHalCommand, executeVirtualHalcmd, readVirtualHalPin, stepVirtualHalMotion, stepVirtualHalMotionController, writeVirtualHalPin, createMachineSessionSnapshotPayload, createVirtualHalSessionPayload, createProjectReleaseGateActionPlan, createProjectReleaseGateExecutionManifest, createProjectReleaseGateExecutionSummaryViewModel, createProjectReleaseGateManifest, createProjectReleaseGateResultMatrix, createProjectReleaseReadinessArtifactJsonWorkflow, createProjectReleaseReadinessArtifactUrlWorkflowActionPlan, createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel, createProjectReleaseReadinessArtifactValidation, createProjectReleaseReadinessArtifactValidationActionPlan, createProjectReleaseReadinessArtifactValidationSummaryViewModel, createProjectReleaseReadinessReport, createProjectReleaseReadinessSummaryViewModel, createSessionSnapshot, defaultMachinePaths, gcodeFilenameFromProgramPath, gcodeProgramPath, getIniPanelEntryByHref, getIniPanelEntryManifest, getOpfsRoot, getVisibleIniPanelEntries, isSupportedIniPanelControlPageApiManifest, isSupportedIniPanelLaunchApiManifest, isSupportedIniPanelShellIntegrationManifest, loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, loadProjectReleaseReadinessArtifactUrlWorkflow, loadMachineSessionFromOpfs, loadMachineSessionSnapshot, loadMachineTextFiles, loadMachineToolTableFromOpfs, loadTextFile, machineFilePaths, machineIniPath, mountIniPanelShellWorkflowOverviewEmbeddingMountState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState, normalizeOpfsPath, parameterFilePath, parseProjectReleaseReadinessArtifactJson, planIniFileContextStaging, planSimConfigStaging, createProjectBatchAcceptanceActionPlan, createProjectBatchAcceptanceCapabilityMatrix, createProjectBatchAcceptanceChecklist, createProjectBatchAcceptanceReport, createProjectBatchAcceptanceReportJsonWorkflow, createProjectBatchAcceptanceReportUrlWorkflowActionPlan, createProjectBatchAcceptanceReportUrlWorkflowSummaryViewModel, createProjectBatchAcceptanceReportValidationActionPlan, createProjectBatchAcceptanceReportValidationSummaryViewModel, createProjectBatchAcceptanceReportValidation, createProjectBatchAcceptanceSummaryViewModel, createProjectBatchAcceptanceWorkflow, loadProjectBatchAcceptanceReportUrlWorkflow, createProjectReleaseBrowserDiagnosticsArtifactValidation, readMachineSessionReadiness, restoreVirtualHalStateFromSessionSnapshot, renderIniPanelShellWorkflowOverviewEmbeddingMountState, renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState, renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState, renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState, renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState, renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState, restoreMachineParametersFromOpfs, saveMachineSessionSnapshot, saveMachineTextFiles, saveSessionSnapshot, saveTextFile, sessionSnapshotPath, toolTablePath, validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson, validateSessionSnapshot, } from "./src/index.js"; ``` `createLinuxCncIniSdk()` wraps the INI parser module built from vendored LinuxCNC `inifile.cc` and exposes `getString()` plus `getBool()`. Boolean conversion is performed by vendored LinuxCNC `iniFindBool()`. `createLinuxCncInterpSdk()` wraps the interpreter-core module built from vendored LinuxCNC RS274NGC sources and exposes: - `runProgram(programText)` - `runProgramWithIni(programText, iniPath)` - `runFile(path)` - `runFileWithIni(path, iniPath)` - `runFileWithIniContinueOnError(path, iniPath)` - `runSimConfigProgram({ iniPath, programPath, files, executionMode })` - `runFiveAxisRemapFile(path, iniPath)` - `runRemapFile(path, iniPath)` - `runRemapIoMdiSequence(iniPath)` - `restoreParameters(path)` - `saveParameters(path, values)` - `loadToolTable(path, options)` - `saveToolTable(path)` - `writeTextFile(path, text)` - `readTextFile(path)` `loadToolTable()` accepts `{ randomToolChanger: true }` to select the LinuxCNC random-toolchanger branch before calling vendored `tooldata_load()`. The SDK only forwards that runtime boundary flag. `runFiveAxisRemapFile()` is a narrow host boundary for vendored LinuxCNC sample-machine remap validation. Callers provide INI/remap/demo files in the WASM filesystem; the C ABI runs vendored LinuxCNC `REMAP`, O-word, file execution, and HAL adapter paths. `runRemapFile()` is the generic remap-test equivalent for vendored LinuxCNC tests such as `tests/remap/duplicate-o-word`. It reads LinuxCNC INI `SUBROUTINE_PATH` and `REMAP` entries, then calls vendored LinuxCNC `Interp::parse_remap()`, `open()`, `read()`, and `execute()`. `runRemapIoMdiSequence()` is a narrow regression boundary for the NGC-only branch of vendored LinuxCNC `tests/remap/remap-io/test-ngc.ini`. The C ABI reads LinuxCNC `REMAP` entries, then feeds the upstream test driver's MDI command sequence into vendored `Interp::execute()`. JavaScript only copies the vendored INI/subroutine files into the WASM filesystem and forwards the INI path; it does not implement M62-M68, M66 input, or remap semantics. `runFileWithIni()` is the plain interpreter-file equivalent for upstream tests that need LinuxCNC INI search paths, such as `tests/interp/sub-call-from-sub`. The C ABI reads LinuxCNC `SUBROUTINE_PATH` and then calls vendored `Interp::open()`, `read()`, and `execute()`; the SDK only copies files and forwards paths. `runSimConfigProgram()` is a convenience host boundary for representative LinuxCNC `configs/sim` programs. Callers provide `{ path, text, executable }` file entries, an INI path, and a program path. The SDK writes those text files into the Emscripten filesystem, applies executable bits for user M-code files, then forwards to `runFileWithIni()` by default or to `runFiveAxisRemapFile()` when `executionMode: "fiveAxisRemap"` is explicitly requested. `planIniFileContextStaging()` is the generic file-staging planner for LinuxCNC INI-driven interpreter runs. Callers provide vendored source-manifest text, a source root, an INI file name, INI text, and a target WASM directory. The planner reads only INI file references and the manifest, then returns the INI, `[DISPLAY]OPEN_FILE`, `[EMCIO]TOOL_TABLE`, `[RS274NGC]PARAMETER_FILE`, `[RS274NGC]SUBROUTINE_PATH`, `[RS274NGC]USER_M_PATH`, and remap-NGC files that should be copied into the Emscripten filesystem. Each planned file includes `sourceRel`, `wasmPath`, the legacy alias `path`, and `executable`. It does not implement G-code, tool, parameter, remap, or user-M semantics. `planSimConfigStaging()` is the companion convenience wrapper for representative LinuxCNC `configs/sim` programs. Callers provide the vendored source manifest text, machine relative path, INI file name, and INI text. It uses `planIniFileContextStaging()` with a `configs/sim/` source root and `configs/sim` upward-search boundary. `analyzeIniRuntimeBoundaries()` is a host-boundary classifier for LinuxCNC INI-driven runs. It reads INI text plus optional execution text and manifest text, then reports declared HAL, UI, HALUI MDI, Python, tool-database, and external user-M process dependencies. User-M accounting is per execution code: `executionCodes` lists `M100..M199` codes seen in the supplied execution text, while `unstagedExecutionCodes` lists the subset not backed by vendored `USER_M_PATH` files. Python accounting keeps UI/DB references separate from Python remap runtime references, so a UI handler or DB program does not imply Python-remap coverage. It also returns the currently recommended Layer 4 blocked kind for hard process boundaries such as `L4-TOOL-DB` and `L4-USER-M-PROCESS`. The classifier is policy/accounting only: it does not execute HAL, task, UI, Python, user-M, or tool-database behavior and does not change interpreter semantics. `runFileWithIniContinueOnError()` uses the same LinuxCNC-backed file execution path but keeps the runner loop going after LinuxCNC reports an error, matching upstream `rs274 -n 0` regression tests such as `tests/interp/oword-unwind`. It does not implement or reinterpret LinuxCNC error semantics. ## Project-level virtual HAL boundary The SDK exposes a project-level browser/Node virtual HAL boundary for UI, session, diagnostics, and standalone interpreter bridge workflows. It is shared through `runtime/sdk/src/index.js`, so simulation pages, INI-panel shells, Node smokes, and external dashboards can use the same objects instead of private page state. - `createVirtualHalState()` creates the normalized browser virtual HAL state. - `applyVirtualHalAction()` applies stable manual-control actions such as ESTOP, power, home, jog, spindle, coolant, brake, touch-off, and limit override. - `createLinuxCncVirtualHalRuntime()` wraps that state in a small runtime with `dispatch()`, `getDroState()`, `getLimitsHomeState()`, `getMachineStatusState()`, `getWasmBridgeSnapshot()`, `getPinRegistry()`, `readPin()`, `writePin()`, `applyPinUpdates()`, `executeHalCommand()`, `executeHalcmd()`, `stepMotion()`, `stepMotionController()`, `getSimulationRuntimeReport()`, `getSimulationReplacementReport()`, `getSourceComplianceReport()`, `getIntegrityReport()`, `getPinInventory()`, `getProjectReport()`, and `applyToInterpSdk()`. - `VIRTUAL_HAL_SIMULATION_RUNTIME_CAPABILITIES`, `VIRTUAL_HAL_SIMULATION_REPLACEMENT_TARGETS`, `VIRTUAL_HAL_SOURCE_DERIVED_CAPABILITIES`, `executeVirtualHalCommand()`, `executeVirtualHalcmd()`, `stepVirtualHalMotion()`, `stepVirtualHalMotionController()`, `VIRTUAL_HAL_MOTION_CONTROLLER_MATRIX_FIXTURES`, `createVirtualHalMotionControllerMatrixReport()`, `createVirtualHalSimulationRuntimeReport()`, and `createVirtualHalSimulationReplacementReport()` expose a simulation-grade replacement for the host LinuxCNC realtime HAL, `halcmd`, and motion controller runtime. It supports HAL pin/signal/param storage, `setp`, `sets`, `newsig`, `net`, `show`, `getp`, `gets`, `loadrt`/`loadusr` stubs, `addf`, thread start/stop, and servo-period motion stepping for browser simulation and Node dashboards. - `createVirtualHalSourceComplianceReport()` is the machine-readable gate for the virtual HAL source rule. It maps replacement targets, runtime capabilities, and HAL pin families back to LinuxCNC source files such as `linuxcnc/bin/axis`, `linuxcnc/src/hal/utils/halcmd_commands.cc`, `linuxcnc/src/emc/usr_intf/halui.cc`, `linuxcnc/src/emc/task/taskclass.cc`, and `linuxcnc/src/emc/motion/motion.c`, then reports whether the Web simulation HAL is source-complete. - `createVirtualHalWasmBridgeSnapshot()` returns the pin/value rows that can be applied through the interpreter SDK HAL bridge. It includes AXIS internal pin names such as `jog.x`, full HAL names such as `axisui.jog.x`, task/power names such as `halui.machine.is-on`, and spindle/coolant names such as `spindle.0.speed-out` and `iocontrol.0.coolant-flood`. - `createVirtualHalPinRegistry()`, `readVirtualHalPin()`, `writeVirtualHalPin()`, and `applyVirtualHalPinUpdates()` expose the project virtual HAL as a source-derived pin service. Callers can read/write HAL names such as `halui.machine.on`, `spindle.0.speed-out`, `motion.tooloffset.z`, or `joint.0.homed` without duplicating pin mapping. - `createVirtualHalIntegrityReport()` verifies registry completeness, duplicate pin absence, required project pins, and source coverage in one machine readable report. - `createVirtualHalPinInventory()` returns a stable project inventory grouped by `VIRTUAL_HAL_PROJECT_PIN_GROUPS`. - `VIRTUAL_HAL_SYSTEM_PIN_FAMILIES`, `VIRTUAL_HAL_SOURCE_FILES`, and `VIRTUAL_HAL_COVERAGE_STATES` expose the source-derived coverage model for AXIS, HALUI, iocontrol, motion, axis, joint, spindle, coolant, and tool pins. - `createVirtualHalSystemCoverageReport()` expands that source-derived model into a machine-readable completeness report. It records the LinuxCNC source files used as evidence, concrete declared pin rows, represented bridge pins, and explicit `bridge-only` / `runtime-boundary` rows. - `createVirtualHalBridgeReadiness()` checks that a snapshot has required bridge pins and that caller-provided WASM function evidence covers `VIRTUAL_HAL_WASM_BRIDGE_FUNCTIONS`. - `createVirtualHalBridgeActionPlan()` turns blocked bridge readiness into the next build/verify commands. - `createVirtualHalProjectReport()` packages state, DRO, limits/home, machine status, pin inventory, pin registry, integrity, system coverage, simulation runtime evidence, bridge snapshot, bridge readiness, and action plan into one stable report for dashboards or release artifacts. - `applyVirtualHalToInterpSdk()` applies a virtual HAL state to any interpreter SDK instance exposing `applyVirtualHalState()` or `applyVirtualHalSnapshot()`. For simulation, this replaces the host `halcmd`, HAL object store, and basic motion feedback loop. It is a virtual realtime HAL runtime replacement for browser workflows, but still not a Linux kernel hard-realtime ABI: kernel realtime scheduling, external device drivers, native HAL module ABI behavior, HALUI process behavior, and Tcl/Python process integration remain explicit boundaries. ## Project release readiness export `createProjectReleaseGateManifest()` returns the required release gate IDs, commands, expected smoke outputs, and gate count for CI dashboards and external SDK callers. `createProjectReleaseGateResultMatrix()` maps observed gate output and explicit gate results onto that manifest as stable `passed`/`unknown` rows. `createProjectReleaseGateActionPlan()` turns that matrix into pending gate commands, the next gate command, stable display rows, and a shell script that external CI can execute or show without duplicating the manifest order. `createProjectReleaseGateExecutionManifest()` packages the same gate manifest with caller-provided explicit results and observed output evidence. Each row includes the command, expected output, matched observed output when present, evidence kind, and `passed`/`unknown` status so CI or browser dashboards can render release-gate execution state without scraping shell scripts. `createProjectReleaseGateExecutionSummaryViewModel()` turns that execution manifest into stable dashboard status text, evidence counts, next missing gate, summary rows, and normalized per-gate rows. `createProjectReleaseReadinessReport()` returns a machine-readable release readiness report that embeds the same manifest, result matrix, action plan, gate execution manifest, gate execution summary view-model, sim-config inventory baseline, and blocked runtime families. It is evidence driven: the default report is `ready: false` until the caller supplies observed gate output such as `project_release_gate=ok` or explicit gate results. `createProjectReleaseReadinessSummaryViewModel()` turns the report into stable status text, a status line, and display rows for dashboards without executing any gate. `createProjectBatchAcceptanceCapabilityMatrix()` normalizes per-batch evidence and classifies accepted `api`, `workflow`, `gate`, and `browser` capabilities separately from rejected docs-only or unknown entries. `createProjectBatchAcceptanceWorkflow()` packages that capability matrix with release-gate evidence for the project rule that each batch must produce at least one callable API, verifiable workflow, executable gate, or browser capability. The companion `createProjectBatchAcceptanceSummaryViewModel()` and `createProjectBatchAcceptanceActionPlan()` helpers make that evidence dashboard-friendly and provide the next gate command when the batch acceptance smoke has not been observed. `createProjectBatchAcceptanceChecklist()` combines the capability matrix, gate evidence, and action plan into pass/blocked rows for release dashboards. `createProjectBatchAcceptanceReport()` packages the matrix, workflow, summary, action plan, and checklist into one stable object for external CI or release dashboards. `createProjectBatchAcceptanceReportValidation()` validates that report shape without copying test assertions. `createProjectBatchAcceptanceReportValidationSummaryViewModel()` and `createProjectBatchAcceptanceReportValidationActionPlan()` expose dashboard rows and the next artifact gate command for blocked report validation. `createProjectBatchAcceptanceReportJsonWorkflow()` is the non-throwing JSON workflow for external CI systems that exchange batch acceptance reports as strings. `loadProjectBatchAcceptanceReportUrlWorkflow()` is the fetch-driven URL workflow for hosted batch acceptance reports. It returns fetch status, the JSON workflow, report validation, and missing evidence without throwing. `createProjectBatchAcceptanceReportUrlWorkflowSummaryViewModel()` and `createProjectBatchAcceptanceReportUrlWorkflowActionPlan()` turn the same URL workflow into dashboard rows and ordered input/fetch/gate actions. This helper does not execute shell commands and does not inspect or implement CNC behavior. It only packages project-level release evidence and blocked runtime policy that are already documented in `docs/project-release-handoff.md` and `../PROJECT_COMPLETION_TRACKER.md`. The executable release gate uses the same helper to write `build/project-release-readiness.json` after all project checks pass, then validates that artifact with `tests/host/verify_project_release_readiness_artifact.sh`. External tools can load that JSON with `parseProjectReleaseReadinessArtifactJson()` and validate it with `createProjectReleaseReadinessArtifactValidation()` without copying the host test assertions. The validation result includes `expectedGateCount` and `expectedGateIds` so external callers can compare an artifact against the current manifest, plus `gateManifestReady`, `gateExecutionManifestReady`, `gateExecutionSummaryReady`, `gateResultMatrixReady`, and `gateActionPlanReady` so stale artifacts that omit the embedded gate evidence chain fail the same executable gate. `createProjectReleaseReadinessArtifactValidationSummaryViewModel()` turns that validation result into stable status text and display rows for dashboards or browser shells without reinterpreting the artifact fields. `createProjectReleaseReadinessArtifactValidationActionPlan()` turns a blocked artifact validation result into the exact project release gate and artifact validation commands to run next, plus the missing evidence list and shell script. Ready validations return no commands. `createProjectReleaseReadinessArtifactJsonWorkflow()` is the non-throwing one-call wrapper for dashboards that receive artifact JSON text. It parses, validates, builds the validation summary, and builds the action plan. Invalid JSON returns a blocked workflow with `parsed: false` and the same next-command action plan instead of throwing. `loadProjectReleaseReadinessArtifactUrlWorkflow()` is the SDK-side URL workflow for callers that supply a `fetch` implementation. It fetches the artifact URL, runs the JSON workflow, and returns fetch status, validation, summary, and action-plan output without executing release gates. `createProjectReleaseReadinessArtifactUrlWorkflowSummaryViewModel()` turns the URL workflow result into stable dashboard status text and rows for ready, missing-input, fetch-failure, and artifact-validation-blocked states. `createProjectReleaseReadinessArtifactUrlWorkflowActionPlan()` turns the same URL workflow into ordered workflow-level actions, distinguishing caller input, fetch checks, and executable gate commands while preserving a shell script for command actions. `tests/sdk/node/verify_project_release_artifact_url_workflow.sh` is the dedicated executable SDK gate for that URL workflow. It verifies caller-provided fetch handling, ready summaries, action plans, missing input, HTTP failure, thrown fetch errors, and ends with `project_release_artifact_url_workflow_node_smoke=ok`. `tests/sdk/node/verify_project_batch_acceptance_workflow.sh` is the executable SDK gate for the per-batch acceptance workflow. It runs the workflow smoke, writes `build/project-batch-acceptance.json` through `write_project_batch_acceptance_artifact.mjs`, validates that artifact through `verify_project_batch_acceptance_artifact.sh`, and emits `project_batch_acceptance_workflow_node_smoke=ok` before ending with `project_batch_acceptance_artifact_node_smoke=ok`. ## OPFS/session persistence exports The SDK entrypoint re-exports the OPFS/session persistence helpers used by the browser panel so external callers can stage the same files without importing private module paths: - `getOpfsRoot()`, `saveTextFile()`, and `loadTextFile()` for browser OPFS text persistence. - `machineIniPath()`, `toolTablePath()`, `parameterFilePath()`, `gcodeProgramPath()`, `sessionSnapshotPath()`, `defaultMachinePaths()`, and `normalizeOpfsPath()` for stable OPFS path construction. - `createMachineSessionSnapshotPayload()`, `createSessionSnapshot()`, `saveSessionSnapshot()`, `saveMachineSessionSnapshot()`, `loadMachineSessionSnapshot()`, and `validateSessionSnapshot()` for session snapshot persistence. - `createVirtualHalSessionPayload()` and `restoreVirtualHalStateFromSessionSnapshot()` for saving and restoring Web virtual HAL state with source compliance, sim-config coverage, halcmd fixtures, and motion controller matrix evidence. - `machineFilePaths()`, `saveMachineTextFiles()`, `loadMachineTextFiles()`, and `gcodeFilenameFromProgramPath()` for machine-file and G-code file helpers. - `readMachineSessionReadiness()` for checking persisted INI, parameter, tool-table, optional G-code, and optional session snapshot files before loading a session. - `restoreMachineParametersFromOpfs()`, `loadMachineToolTableFromOpfs()`, and `loadMachineSessionFromOpfs()` for loading OPFS machine state into the LinuxCNC-backed interpreter SDK. These helpers only move and validate host files. Parameter and tool-table effects still come from the LinuxCNC-backed interpreter SDK methods they call. ## INI panel shell handoff exports The SDK entrypoint also re-exports the stable INI panel shell handoff surface for external browser shells: - `INI_PANEL_ENTRIES`, `getIniPanelEntryManifest()`, `getIniPanelEntryByHref()`, `getVisibleIniPanelEntries()`, and `createIniPanelLauncherLinkViewModel()` for discovering launch pages and rendering shell-owned launcher links from the stable entry manifest. - `createIniPanelLaunchApiManifest()` and `isSupportedIniPanelLaunchApiManifest()` for launch API negotiation. - `createControlPageBrowserApiSchema()`, `createControlPageBrowserApiManifest()`, `createControlPageBrowserApiMethods()`, `createIniPanelShellControlPageContract()`, and `isSupportedIniPanelControlPageApiManifest()` for read-only control-page API negotiation. - `createIniPanelShellIntegrationSchema()`, `createIniPanelShellIntegrationManifest()`, `createIniPanelShellIntegrationReadiness()`, `createIniPanelShellIntegrationWorkflowPlan()`, and `isSupportedIniPanelShellIntegrationManifest()` for checking launch and control-page compatibility before embedding. - `createIniPanelShellViewModel()` for a complete read-only shell integration bundle. - `createMachineSessionPersistenceSummary()` for a machine-readable OPFS/session persistence summary covering machine files, session snapshot, session readiness, session load, readonly status, and shell handoff readiness rows. `createMachineSessionPersistenceDisplayViewModel()` and `createMachineSessionPersistenceRenderState()` turn the summary into stable display and render data. `createIniPanelShellSessionHandoffWorkflowSummary()` can include this as the read-only `persistence-summary` row. - `createIniPanelShellWorkflowOverviewContract()` for discovering the workflow overview iframe API contract. - `validateIniPanelShellWorkflowOverviewReleaseReadinessArtifactJson()` for the read-only workflow overview artifact validation wrapper exposed by `workflow-overview.html`. Use `runIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflow()` when a shell already has artifact JSON and needs parse, validation, summary, action-plan, and gate execution summary output in one non-throwing workflow. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowSummaryViewModel()` turns that JSON workflow into stable dashboard status text and rows. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowActionPlan()` exposes the JSON workflow next-command plan without requiring callers to read internal workflow fields. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomContract()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowDomReadiness()`, `renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState()`, and `mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactJsonWorkflowState()` let a shell render or mount that JSON workflow render-state into caller-owned DOM without executing release gate commands. Use `loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl()` when a browser or shell should fetch the artifact JSON URL, validate it, and optionally mount the resulting render-state into caller-owned DOM. The URL workflow result includes `validationSummaryViewModel` and `gateExecutionSummaryViewModel` for dashboards. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowSummaryViewModel()` turns the full URL workflow result into stable status text and rows. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowActionPlan()` exposes the same URL workflow next-action/next-command plan through the browser workflow overview surface. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowRenderState()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomContract()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowDomReadiness()`, `renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()`, and `mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlWorkflowState()` let callers render the URL workflow status into their own DOM. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlan()` exposes the direct artifact-validation next-command plan when callers already have parsed or validated artifact JSON. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanRenderState()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomContract()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanDomReadiness()`, `renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState()`, and `mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationActionPlanState()` let callers render that validation action plan into caller-owned DOM. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryViewModel()` and `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrlGateExecutionSummaryViewModel()` expose the embedded release gate execution summary for external shells without requiring callers to parse artifact internals. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryRenderState()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomContract()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryDomReadiness()`, `renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState()`, and `mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactGateExecutionSummaryState()` let callers render the per-gate execution summary rows into caller-owned DOM. `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDisplayViewModel()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomContract()`, `createIniPanelShellWorkflowOverviewReleaseReadinessArtifactDomReadiness()`, `renderIniPanelShellWorkflowOverviewReleaseReadinessArtifactState()`, and `mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState()` when an outer shell needs to render that validation into caller-owned DOM. - `createIniPanelShellApiSurfaceInventory()` for a machine-readable inventory of launch, control-page, workflow overview, persistence, and session readiness report API counts, including persistence summary row counts. `createIniPanelShellViewModel()` also includes this inventory as a read-only workflow summary row so browser overview pages and external shells can display API coverage without private imports. - `createIniPanelShellSessionReadinessWorkflowReport()` for a machine-readable session readiness workflow report with phase, missing reasons, status line, and stable rows. - `createIniPanelShellWorkflowOverviewEmbeddingMountDomContract()` and `createIniPanelShellWorkflowOverviewEmbeddingMountDomReadiness()` for workflow overview embedding mount DOM checks. - `renderIniPanelShellWorkflowOverviewEmbeddingMountState()` for rendering a mount render-state into caller-owned DOM. - `mountIniPanelShellWorkflowOverviewEmbeddingMountState()` for a non-throwing workflow overview embedding mount wrapper that returns structured blocked results when DOM nodes are missing. The workflow overview embedding helpers are UI/runtime boundary helpers only. They render status and rows already produced by the shell view-model; they do not parse G-code, execute action plans, or implement CNC semantics.