| 7967 | } |
| 7968 | |
| 7969 | function renderTestText(t: CliTest): string { |
| 7970 | // M2.1 piece 4: when the facade ships `projectName`, lead with a |
| 7971 | // human-friendly `project: <name> (<id>)` line so an operator |
| 7972 | // skimming `test get` sees the project label without a second |
| 7973 | // command. Pre-M2.1 facades that don't emit the field still render |
| 7974 | // — we fall back to `projectId:` only. |
| 7975 | const projectLine = |
| 7976 | t.projectName != null && t.projectName.length > 0 |
| 7977 | ? `project: ${t.projectName} (${t.projectId})` |
| 7978 | : `projectId: ${t.projectId}`; |
| 7979 | const lines = [ |
| 7980 | `id: ${t.id}`, |
| 7981 | projectLine, |
| 7982 | `name: ${t.name}`, |
| 7983 | `type: ${t.type}`, |
| 7984 | `createdFrom: ${t.createdFrom}`, |
| 7985 | `status: ${t.status}`, |
| 7986 | ]; |
| 7987 | // G1a: surface priority when the backend ships it and it is non-null. |
| 7988 | if (t.priority) { |
| 7989 | lines.push(`priority: ${t.priority}`); |
| 7990 | } |
| 7991 | // M3.4: surface plan-step count when the facade ships it (FE tests). |
| 7992 | // Lets an operator read the current count — e.g. to recover after a |
| 7993 | // `test plan put --expected-step-count` 412 — without a JSON round-trip. |
| 7994 | if (typeof t.planStepCount === 'number') { |
| 7995 | lines.push(`planSteps: ${t.planStepCount}`); |
| 7996 | } |
| 7997 | lines.push(`createdAt: ${t.createdAt}`, `updatedAt: ${t.updatedAt}`); |
| 7998 | return lines.join('\n'); |
| 7999 | } |
| 8000 | |
| 8001 | function renderStepsText(page: Page<CliTestStep>): string { |
| 8002 | if (page.items.length === 0) { |