# 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, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactRenderState, createIniPanelShellWorkflowOverviewReleaseReadinessArtifactValidationSummaryViewModel, createLinuxCncIniSdk, createLinuxCncInterpSdk, createMachineSessionPersistenceDisplayViewModel, createMachineSessionPersistenceRenderState, createMachineSessionPersistenceSummary, createMachineSessionSnapshotPayload, createProjectReleaseGateActionPlan, createProjectReleaseGateManifest, createProjectReleaseGateResultMatrix, createProjectReleaseReadinessArtifactValidation, createProjectReleaseReadinessArtifactValidationSummaryViewModel, createProjectReleaseReadinessReport, createProjectReleaseReadinessSummaryViewModel, createSessionSnapshot, defaultMachinePaths, gcodeFilenameFromProgramPath, gcodeProgramPath, getIniPanelEntryByHref, getIniPanelEntryManifest, getOpfsRoot, getVisibleIniPanelEntries, isSupportedIniPanelControlPageApiManifest, isSupportedIniPanelLaunchApiManifest, isSupportedIniPanelShellIntegrationManifest, loadIniPanelShellWorkflowOverviewReleaseReadinessArtifactUrl, loadMachineSessionFromOpfs, loadMachineSessionSnapshot, loadMachineTextFiles, loadMachineToolTableFromOpfs, loadTextFile, machineFilePaths, machineIniPath, mountIniPanelShellWorkflowOverviewEmbeddingMountState, mountIniPanelShellWorkflowOverviewReleaseReadinessArtifactState, normalizeOpfsPath, parameterFilePath, parseProjectReleaseReadinessArtifactJson, planIniFileContextStaging, planSimConfigStaging, readMachineSessionReadiness, renderIniPanelShellWorkflowOverviewEmbeddingMountState, 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 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. `createProjectReleaseReadinessReport()` returns a machine-readable release readiness report that embeds the same manifest, result matrix, and action plan beside the 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. 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`, `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. ## 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. - `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 `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` for dashboards. `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.