Accumulated uncommitted work: GHOST Web backend, WebGL/GPU web layer, web workflow engine and protocol, tooling, docs and task records. Large generated evidence, user-testing archives, build snapshots and imported test assets remain untracked. Co-Authored-By: Claude Code <noreply@anthropic.com>
79 lines
6.7 KiB
Python
79 lines
6.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Prepare bounded font and animation contracts from the supplied native entries."""
|
|
import copy
|
|
import json
|
|
|
|
from wbv2_autopilot import Autopilot, ROOT, contained, queue_context, write_json
|
|
|
|
|
|
WORKFLOWS = {
|
|
"WEBUI-FONT-ASSETS": {
|
|
"slug": "font-assets", "test": "font-assets-ui-production.spec.ts", "reader": "font-main-snapshots.py", "fixture": "nonmesh_scene.blend",
|
|
"units": ["web-command:setFontAdvanced", "web-command:importVFont", "web-command:setFontLinks"],
|
|
"negative": ["web-command:setFontLinks"], "history": ["web-command:setFontLinks"],
|
|
"source": ["blender-5.2.0/source/blender/makesrna/intern/rna_curve.cc"],
|
|
"assets": ["blender-5.2.0/release/datafiles/bfont.pfb", "web/app/src/fonts/external-vfont-import.ts"],
|
|
"workflow": "Edit font layout, import a packed browser font and link it to text; reject missing links and preserve native Main through history and reopening",
|
|
},
|
|
"ACTION-MARKER-AUTHORING": {
|
|
"slug": "action-marker", "test": "action-marker-ui-production.spec.ts", "reader": "action-main-snapshots.py", "fixture": "animation_scene.blend",
|
|
"units": ["web-command:createAction", "web-command:removeAction", "web-command:setKeyframe", "web-command:setFCurveKeyframes", "web-command:setTimelineMarkers"],
|
|
"negative": ["web-command:setTimelineMarkers"], "history": ["web-command:setTimelineMarkers"],
|
|
"source": ["blender-5.2.0/source/blender/makesrna/intern/rna_action.cc", "blender-5.2.0/source/blender/makesrna/intern/rna_timeline.cc"],
|
|
"assets": [],
|
|
"workflow": "Create and remove Actions, edit keyframes and their handles, and add, rename, move and delete timeline markers through native Main",
|
|
},
|
|
}
|
|
|
|
|
|
def main():
|
|
runner = Autopilot()
|
|
context = queue_context(ROOT)
|
|
jobs = {job["id"]: job for job in runner.jobs(context)}
|
|
results = []
|
|
for identifier, spec in WORKFLOWS.items():
|
|
if identifier not in jobs:
|
|
raise ValueError("workflow is not in the authorized backlog")
|
|
test = "web/tests/e2e/" + spec["test"]
|
|
reader = "web/tests/fixtures/" + spec["reader"]
|
|
references = spec["source"] + ["blender-5.2.0/source/blender/web_engine/web_engine_api.cpp", "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp", "blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp"]
|
|
dependencies = sorted(set(jobs[identifier]["ownedPaths"] + references + spec["assets"] + [
|
|
test, reader, "web/tests/fixtures/native-ui-workflow.ts", "tests/files/web/" + spec["fixture"],
|
|
"web/app/src/engine-client/WebEngineClient.ts", "web/app/src/workers/web-engine.worker.ts",
|
|
"web/protocol/scene-ir.ts", "web/protocol/web-engine.ts", "web/protocol/animation-render-commands.ts", "web/protocol/nonmesh-geometry-commands.ts",
|
|
"web/app/vite.config.ts", "web/app/src/capabilities/blender-feature-route-catalog.json", "web/playwright.config.ts", "web/package.json", "web/tsconfig.json",
|
|
"my-tools/build_local_webengine.py", "tools/web/sync-web-engine-runtime.mjs", "tools/web/incremental-web-build.mjs", "tools/web/run-incremental-typecheck.mjs", "tools/web/web-build-fingerprint.mjs",
|
|
".emscripten-web", "build_web_blender6/CMakeCache.txt", "my-tools/prepare_wbv2_authoring_batch.py",
|
|
]))
|
|
behavior = ["positive", "negative", "undo_redo", "save_reopen", "determinism"]
|
|
result = {
|
|
"status": "ready", "summary": "Prepared local native authoring workflow; independent behavioral validation is mandatory", "workflow": spec["workflow"],
|
|
"sourceUnits": spec["units"], "routeIds": spec["units"], "sourceReferences": references,
|
|
"changedFiles": [test, reader, "web/tests/fixtures/native-ui-workflow.ts", "web/app/src/app/App.tsx"] + (["blender-5.2.0/source/blender/web_engine/web_engine_blend_reader.cpp", "blender-5.2.0/source/blender/web_engine/web_engine_main_state.cpp"] if identifier == "ACTION-MARKER-AUTHORING" else []),
|
|
"dependencies": dependencies,
|
|
"artifacts": ["build_blender_native/bin/blender", "build_web_blender6/bin/web_engine.wasm", "build_web_blender6/bin/web_engine.js", "web/app/public/vendor/blender/web_engine.wasm", "web/app/public/vendor/blender/web_engine.js", "web/app/public/wasm-module-manifest.json"],
|
|
"checks": [
|
|
{"id": "wasm-source-build", "argv": ["python3", "my-tools/build_local_webengine.py"], "cwd": ".", "kinds": ["source_build"], "timeoutSeconds": 1200, "continueOnFailure": True},
|
|
{"id": "web-build", "argv": ["node", "tools/web/incremental-web-build.mjs"], "cwd": ".", "kinds": ["typecheck"], "dependsOn": ["wasm-source-build"], "timeoutSeconds": 300, "continueOnFailure": True},
|
|
{"id": "authoring-lint", "argv": ["node", "node_modules/eslint/bin/eslint.js", "app/src/app/App.tsx"], "cwd": "web", "kinds": ["lint"], "timeoutSeconds": 60, "continueOnFailure": True},
|
|
{"id": "chromium-authoring", "argv": ["env", "BLENDER_BIN=" + str(ROOT / "build_blender_native/bin/blender"), "WEB_TEST_PORT=5357", "node", "node_modules/@playwright/test/cli.js", "test", "--config", "playwright.config.ts", "tests/e2e/" + spec["test"], "--workers=1", "--max-failures=1"], "cwd": "web", "kinds": ["chromium", *behavior], "dependsOn": ["wasm-source-build", "web-build"], "timeoutSeconds": 180, "continueOnFailure": True},
|
|
],
|
|
"cases": [{"id": spec["slug"] + "-" + kind, "kind": kind, "checkId": "chromium-authoring", "receipt": "unallocated/" + kind + ".json", "unitIds": spec["negative"] if kind == "negative" else spec["history"] if kind == "undo_redo" else spec["units"]} for kind in behavior],
|
|
}
|
|
for relative in dependencies + result["artifacts"]:
|
|
if not contained(ROOT, relative).is_file():
|
|
raise ValueError("missing local workflow prerequisite: " + relative)
|
|
probe = runner.directory / "contract-admission" / identifier
|
|
validated = copy.deepcopy(result)
|
|
for case in validated["cases"]:
|
|
case["receipt"] = str((probe / "cases" / (case["id"] + ".json")).relative_to(ROOT))
|
|
runner.validate_result(validated, probe)
|
|
destination = ROOT / "my-tools/local-workflows" / (identifier + ".json")
|
|
write_json(destination, {"schemaVersion": 1, "task": context["task"], "job": identifier, "parentSha256": context["parentSha256"], "acceptance": "pending independent local validation", "result": result})
|
|
results.append({"job": identifier, "contract": str(destination.relative_to(ROOT)), "checks": len(result["checks"]), "cases": len(result["cases"])})
|
|
print(json.dumps({"prepared": results, "modelRequests": 0}))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|