diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 200071e..70ec8f9 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -18,6 +18,19 @@ const DEFAULT_SCHEMA = JSON.stringify( const MAX_UPLOAD_BYTES = 2 * 1024 * 1024; +function downloadWorkflowResult(result) { + const contents = JSON.stringify(result, null, 2); + const url = URL.createObjectURL(new Blob([contents], { type: "application/json;charset=utf-8" })); + const link = document.createElement("a"); + link.href = url; + const base = String(result.workflow_name || "data-workflow").replace(/[^A-Za-z0-9._-]+/g, "-"); + link.download = `${base || "data-workflow"}.json`; + document.body.appendChild(link); + link.click(); + link.remove(); + URL.revokeObjectURL(url); +} + export function App() { const [config, setConfig] = useState(null); const [session, setSession] = useState(null); @@ -214,6 +227,9 @@ export function App() {
Unmapped required fields: {result.unmapped_required_fields.join(", ")}
) : null} {result.warnings?.length ?
{result.warnings.join(" ")}
: null} + ) : (

Run the builder to see mappings, saved path, artifact URI, and receipt status.

diff --git a/tests/test_full_stack_contract.py b/tests/test_full_stack_contract.py index cc28363..61f08e9 100644 --- a/tests/test_full_stack_contract.py +++ b/tests/test_full_stack_contract.py @@ -43,6 +43,7 @@ def test_full_stack_product_contract(): assert "AgentPlatformResources" in source and "AgentDatabase(" in source assert "Skill runner" not in frontend, "replace the generic scaffold with the product workflow" assert "DATABASE_URL" not in frontend + assert "Download workflow response (.json)" in frontend and "new Blob" in frontend assert "execution_receipts" in migration card = load_local_project(ROOT).agent_cls().card()