先提交到云仓库

结论:已提交当前 Python-remap proof 链路、runtime/browser/UI/docs 相关变更;保持 L4-PYTHON-REMAP inventory baseline 不直接批量 PASS。
This commit is contained in:
2026-06-20 00:06:10 +08:00
parent fbf9dade9c
commit ac52b48d62
36 changed files with 4388 additions and 240 deletions

View File

@@ -1726,6 +1726,12 @@ M2
<dd>T<span data-machine-status="tool-current">0</span> selected <span data-machine-status="tool-selected">0</span> pocket <span data-machine-status="tool-pocket">0</span> TLO <span data-machine-status="tool-length-offset">z=0.000</span></dd>
<dt>Tool Table</dt>
<dd><span data-tool-table-summary="state">not-loaded</span> | <span data-tool-table-summary="paths">-</span> | <span data-tool-table-summary="tool">No tool table loaded</span></dd>
<dt>Python Remap</dt>
<dd><span data-python-remap-runtime="boundary">L4-PYTHON-REMAP</span> | <span data-python-remap-runtime="fixture">axis/remap/stop-lookahead/nc_files</span> | <span data-python-remap-runtime="lifecycle">locked</span></dd>
<dt>Python Runtime</dt>
<dd><span data-python-remap-runtime="mode">contract-only</span> | callable <span data-python-remap-runtime="callable">locked</span> | generator <span data-python-remap-runtime="generator">locked</span> | state <span data-python-remap-runtime="interpreter">locked</span></dd>
<dt>Python Promotion</dt>
<dd>execution <span data-python-remap-runtime="execution">disabled</span> | promotion <span data-python-remap-runtime="promotion">locked</span></dd>
<dt>Limits/Home</dt>
<dd data-limits-home-summary>source unavailable | X home no limit off/off fault none</dd>
<dt>Overrides</dt>
@@ -2794,6 +2800,7 @@ M2
virtualHalSimConfigMacroLoadFixtures: createVirtualHalSimConfigMacroLoadFixtureReport(),
virtualHalCommandScriptFixtures: createVirtualHalCommandScriptFixtureReport(),
virtualHalMotionControllerMatrix: createVirtualHalMotionControllerMatrixReport(),
pythonRemapRuntime: state?.pythonRemapRuntime ?? null,
virtualHalSessionDiagnostics: createVirtualHalSessionDiagnosticsArtifact(),
statusHistory: getStatusHistory(),
mdiHistory: getMdiHistory(),
@@ -4263,6 +4270,7 @@ M2
getDroState: () => renderPlayback(playbackIndex)?.dro ?? null,
getModalState: () => currentState()?.modal ?? null,
getMachineStatusState: () => currentState()?.machineStatus ?? null,
getPythonRemapRuntimeStatus: () => currentState()?.pythonRemapRuntime ?? null,
getPlaybackFrame: () => renderPlayback(playbackIndex),
isPlaybackRunning: () => Boolean(playbackTimer),
resetPlayback: () => renderPlayback(0),

View File

@@ -1,4 +1,8 @@
import { createLinuxCncInterpSdk } from "../../sdk/src/index.js";
import {
PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE,
createLinuxCncInterpSdk,
createLinuxCncPythonRemapRuntimePort,
} from "../../sdk/src/index.js";
import * as THREE from "./vendor/three/three.module.js";
import {
DEFAULT_SIMULATION_PROGRAM,
@@ -190,6 +194,58 @@ export function createSimulationSummary({ programText, resultText, motion }) {
};
}
export async function createPythonRemapSimulationRuntimeStatus({
runtimeMode = "contract-only",
runtimeAdapter = null,
} = {}) {
const port = createLinuxCncPythonRemapRuntimePort({
fixtureFamily: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.fixtureFamily,
iniPath: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.iniPath,
pythonPathPrepend: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.pythonPathPrepend,
topLevelPath: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.topLevelPath,
sourceFiles: PYTHON_REMAP_STOP_LOOKAHEAD_FIXTURE.modules,
runtimeMode,
runtimeAdapter,
});
const start = await port.start();
const plan = await port.runLifecyclePlan();
const diagnostics = port.exportDiagnostics();
await port.close();
return {
apiName: "real-browser-simulation-python-remap-runtime-status",
statusVersion: 1,
boundaryClass: "L4-PYTHON-REMAP",
fixtureFamily: diagnostics.fixtureFamily,
iniPath: diagnostics.iniPath,
pythonPathPrepend: diagnostics.pythonPathPrepend,
topLevelPath: diagnostics.topLevelPath,
modules: diagnostics.modules,
runtimeMode: diagnostics.runtimeMode,
runtimeExecutionReady: diagnostics.runtimeExecutionReady,
lifecycleTranscriptReady: diagnostics.lifecycleTranscriptReady,
callableLookupReady: diagnostics.callableLookupReady,
generatorLifecycleReady: diagnostics.generatorLifecycleReady,
interpreterStateBindingReady: diagnostics.interpreterStateBindingReady,
executionEnabled: diagnostics.executionEnabled,
promotionAllowed: diagnostics.promotionAllowed,
bulkPromotionAllowed: diagnostics.bulkPromotionAllowed,
ngcOnlySubroutinePromoted: diagnostics.ngcOnlySubroutinePromoted,
jsCncSemantics: diagnostics.jsCncSemantics,
startStatus: start.status ?? "contract-only",
planStatus: plan.status,
phase: diagnostics.lifecycleTranscriptReady ? "ready" : "locked",
ready: diagnostics.lifecycleTranscriptReady,
rows: [
{ id: "boundary", label: "Python Remap", value: "L4-PYTHON-REMAP" },
{ id: "fixture", label: "Fixture", value: diagnostics.fixtureFamily },
{ id: "runtime-mode", label: "Runtime mode", value: diagnostics.runtimeMode },
{ id: "lifecycle", label: "Lifecycle", value: diagnostics.lifecycleTranscriptReady ? "ready" : "locked" },
{ id: "promotion", label: "Promotion", value: diagnostics.promotionAllowed ? "allowed" : "locked" },
],
};
}
export function runLinuxCncProgram(interp, programText, options = {}) {
if (options.iniPath) {
return interp.runProgramWithIni(programText, options.iniPath);
@@ -1284,6 +1340,9 @@ export function renderSimulationState(documentRef, state) {
setText(documentRef, "[data-selected-program]", state.program?.label ?? "Custom program");
setText(documentRef, "[data-program-source]", state.program?.sourceLabel ?? "Custom G-code text");
setText(documentRef, "[data-canonical-output]", state.resultText);
if (state.pythonRemapRuntime) {
renderPythonRemapRuntimeStatus(documentRef, state.pythonRemapRuntime);
}
renderProgramSelector(documentRef, state.program?.id ?? "custom");
renderRows(documentRef, state.summary.rows);
renderModalState(documentRef, state.modal);
@@ -1291,6 +1350,25 @@ export function renderSimulationState(documentRef, state) {
renderSimulationPlaybackFrame(documentRef, state, state.motion.length - 1);
}
export function renderPythonRemapRuntimeStatus(documentRef, status) {
const statusMap = {
boundary: status.boundaryClass,
fixture: status.fixtureFamily,
mode: status.runtimeMode,
lifecycle: status.lifecycleTranscriptReady ? "ready" : "locked",
callable: status.callableLookupReady ? "ready" : "locked",
generator: status.generatorLifecycleReady ? "ready" : "locked",
interpreter: status.interpreterStateBindingReady ? "ready" : "locked",
execution: status.executionEnabled ? "enabled" : "disabled",
promotion: status.promotionAllowed ? "allowed" : "locked",
};
documentRef.body.dataset.pythonRemapRuntimeReady = status.ready ? "true" : "false";
documentRef.body.dataset.pythonRemapRuntimePhase = status.phase;
for (const [name, value] of Object.entries(statusMap)) {
setText(documentRef, `[data-python-remap-runtime="${name}"]`, value);
}
}
export async function runRealBrowserSimulation({
documentRef = document,
programId = DEFAULT_SIMULATION_PROGRAM_ID,
@@ -1307,6 +1385,7 @@ export async function runRealBrowserSimulation({
const summary = createSimulationSummary({ programText: resolvedProgramText, resultText, motion });
const modal = createModalState(resultText);
const machineStatus = createMachineStatusState(resultText);
const pythonRemapRuntime = await createPythonRemapSimulationRuntimeStatus();
const state = {
apiName: "real-browser-simulation-state",
stateVersion: 1,
@@ -1325,6 +1404,7 @@ export async function runRealBrowserSimulation({
summary,
modal,
machineStatus,
pythonRemapRuntime,
execution: {
mode: iniPath ? "linuxcnc-wasm-with-ini" : "linuxcnc-wasm",
iniPath,