fix(frontend,harness): phase-stepper wiring, central tail, activity-panel markdown
- WorkflowBar: center the phase pills (add justify-center).
- tht-gate.js: the gate was sending the descriptive phase name (e.g.
"chiarimento") instead of the workflow.yaml id ("F1") in the widget's
`phase` field, so the frontend's F1..F8 match never hit and pills never
lit up. Rename phaseName -> phaseId, return p.id.
- CentralStatus: expand the live "working" tail from a single truncated
line to up to 5 lines (line-clamp-5 safety net for unbroken paragraphs).
- ModelActivityPanel: render the streamed tail through react-markdown +
remark-gfm instead of raw per-line <p> tags, so emphasis/headings render
and blank-line paragraph breaks (previously stripped) are preserved;
tail-cut now operates on paragraphs instead of physical lines.
Updated tests accordingly (WorkflowBar/CentralStatus/ModelActivityPanel/
AppShell.session-mgmt); full frontend suite (98/98) + harness gate node
tests (34/34) + tsc -b pass.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -172,10 +172,13 @@ function phaseMeta(ctx) {
|
||||
_phaseMetaCache = meta;
|
||||
return meta;
|
||||
}
|
||||
function phaseName(ctx, num) {
|
||||
// Returns the workflow.yaml phase id (e.g. "F1"), not the descriptive name — this is
|
||||
// what feeds the widget's `phase` field, which the frontend WorkflowBar matches against
|
||||
// its own "F1".."F8" ids to light up the stepper pills.
|
||||
function phaseId(ctx, num) {
|
||||
const meta = phaseMeta(ctx);
|
||||
const p = meta.phases.find((x) => x.num === num);
|
||||
return p ? p.name : "?";
|
||||
return p ? p.id : "?";
|
||||
}
|
||||
function currentPhase(ctx, session) {
|
||||
const out = tht(ctx, ["phase", "show", "--session", session]);
|
||||
@@ -433,7 +436,7 @@ export default function (pi) {
|
||||
async execute(_id, params, _signal, _onUpdate, ctx) {
|
||||
lockActive = true;
|
||||
const { session, title, options: opts, intro, advance } = params;
|
||||
const phase = phaseName(ctx, currentPhase(ctx, session));
|
||||
const phase = phaseId(ctx, currentPhase(ctx, session));
|
||||
const recommended = opts.find((o) => o.recommended)?.id ?? null;
|
||||
|
||||
const widget = buildSelectRequest({
|
||||
@@ -505,7 +508,7 @@ export default function (pi) {
|
||||
async execute(_id, params, _signal, _onUpdate, ctx) {
|
||||
lockActive = true;
|
||||
const { session, title, options: opts, advance } = params;
|
||||
const phase = phaseName(ctx, currentPhase(ctx, session));
|
||||
const phase = phaseId(ctx, currentPhase(ctx, session));
|
||||
const toAdd = [];
|
||||
const widget = buildMultiselectRequest({
|
||||
id: `u${Date.now()}`,
|
||||
@@ -571,7 +574,7 @@ export default function (pi) {
|
||||
async execute(_id, params, _signal, _onUpdate, ctx) {
|
||||
lockActive = true;
|
||||
const { session, kind, title, artifact } = params;
|
||||
const phase = phaseName(ctx, currentPhase(ctx, session));
|
||||
const phase = phaseId(ctx, currentPhase(ctx, session));
|
||||
const widget = buildArtifactGate({
|
||||
id: `u${Date.now()}`,
|
||||
phase,
|
||||
|
||||
Reference in New Issue
Block a user