feat(ui): three-screen mission wizard that asks only what the type needs
Five fixed steps for every mission type, and getting a research document out of it meant naming a team, choosing a runtime, and writing per-phase completion conditions under a paragraph explaining what a model checker can and cannot prove. Two of those steps asked for things the mission does not use, and one of them blocked outright. 1 What do you want to do? 2 Title, a description with a Polish button, repo ONLY if the type needs one 3 Review -> Launch, plus one collapsed Advanced section Two hard defects fixed on the way: - The microVM runtime could not be selected AT ALL. Step 4 gated Next on `targetNodeId`, which microVM deliberately never sets because placement picks the node per phase. Everything shipped today, the local-GPU backend included, was unreachable from the UI. - Step 3 required a team while every workflow TOML already names one in `default_team_template` — which this file ignored. The answer was always available and the question was always asked. It is now resolved by key, with a category fallback, and shown under Advanced so an operator can see WHICH default rather than having to supply one. A failed `/api/team-templates` request and a genuinely empty list rendered the identical red banner, which sends the reader looking for missing template files when the request had 401'd. They now say different things. `phases[]` is no longer sent unless someone set a completion condition. `recipeToPreset` strips each phase's `config`, so posting the stripped list overrode the recipe's real settings — tools, commit policy, loop mode — with nothing. Omitting it lets `phases_for_create` use the recipe, which is both simpler and more correct. Launch keeps its own gate, since Advanced can still produce an unlaunchable combination — but it names what is missing instead of greying out in silence. Artifacts get a Download link. Deliberately a plain link to the streaming route rather than a Blob built from what "Read" already fetched: that content is capped at 2 MiB and UTF-8-decoded, so reusing it would silently produce a truncated or undownloadable file for exactly the artifacts worth downloading. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5
parent
25f075a8be
commit
e4bddeb1ba
@@ -11,7 +11,7 @@
|
||||
// research phase can leave dozens of documents.
|
||||
|
||||
import { useCallback, useState } from "react";
|
||||
import { FileText, GitMerge } from "lucide-react";
|
||||
import { Download, FileText, GitMerge } from "lucide-react";
|
||||
|
||||
import {
|
||||
getArtifactContent,
|
||||
@@ -172,6 +172,28 @@ export function MissionArtifacts({
|
||||
>
|
||||
{isOpen ? "Hide" : "Read"}
|
||||
</button>
|
||||
{/* A plain link, not a fetch-and-Blob.
|
||||
The read endpoint caps at 2 MiB and decodes as UTF-8, so
|
||||
building the download from what "Read" already fetched would
|
||||
inherit both limits and silently produce a truncated or
|
||||
undownloadable file for exactly the artifacts worth
|
||||
downloading. This hits the streaming route instead. */}
|
||||
<a
|
||||
href={`/api/missions/${missionId}/artifacts/${a.id}/download`}
|
||||
download
|
||||
style={{
|
||||
...secondaryBtn,
|
||||
padding: "5px 10px",
|
||||
fontSize: 11,
|
||||
textDecoration: "none",
|
||||
display: "inline-flex",
|
||||
alignItems: "center",
|
||||
gap: 5,
|
||||
}}
|
||||
>
|
||||
<Download aria-hidden size={12} />
|
||||
Download
|
||||
</a>
|
||||
</div>
|
||||
{isOpen && (
|
||||
<div
|
||||
@@ -194,7 +216,8 @@ export function MissionArtifacts({
|
||||
</div>
|
||||
) : text?.truncated ? (
|
||||
<div style={{ fontFamily: mono, fontSize: 11.5, color: "#8a8a92" }}>
|
||||
too large to display inline ({text.bytes.toLocaleString()} bytes)
|
||||
too large to display inline ({text.bytes.toLocaleString()}{" "}
|
||||
bytes) — use Download
|
||||
</div>
|
||||
) : text ? (
|
||||
<MarkdownBlock source={text.content} />
|
||||
|
||||
Reference in New Issue
Block a user