mirror of
https://github.com/KeygraphHQ/shannon.git
synced 2026-09-18 16:02:27 +02:00
fix: terminate failed scans in Temporal and surface the reason when following (#429)
* fix(cli): skip splash screen off a TTY (e.g. CI) * fix: terminate failed scans in Temporal and surface the reason when following * fix(cli): indent embedded newlines within failure-error segments * fix(worker): omit the Agent Breakdown section when no agents completed * fix(cli): don't reprint the failure reason when the log already showed it * fix(worker): indent embedded newlines within the workflow.log error block
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Rendering for the worker's '|'-delimited failure string.
|
||||
*
|
||||
* `formatWorkflowError` in the worker joins error segments — phase context, error type,
|
||||
* message, and remediation hint — with '|' as a delimiter. These helpers turn that raw
|
||||
* string into readable output for the CLI's own surfaces.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Split the failure string into trimmed, non-empty lines. Segments are delimited by '|', and a
|
||||
* segment's own embedded newlines (e.g. a multi-line validation message) become their own lines so
|
||||
* each aligns with the rest of the block.
|
||||
*/
|
||||
export function parseFailureSegments(message: string): string[] {
|
||||
return message
|
||||
.split(/[|\n]/)
|
||||
.map((segment) => segment.trim())
|
||||
.filter((segment) => segment.length > 0);
|
||||
}
|
||||
|
||||
/** Multi-line block: one segment per indented line (the caller prints the header). */
|
||||
export function indentFailureSegments(message: string, indent = ' '): string {
|
||||
return parseFailureSegments(message)
|
||||
.map((segment) => `${indent}${segment}`)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
/** Single-line summary for compact contexts like the status footer. */
|
||||
export function inlineFailureReason(message: string): string {
|
||||
return parseFailureSegments(message).join(' — ');
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import { BOLD, DIM, GOLD, paint, RED, YELLOW } from '../colors.js';
|
||||
import { commandPrefix } from '../mode.js';
|
||||
import type { RunningAgent } from '../temporal-client.js';
|
||||
import { agentError, deriveAgentStates, isTerminal, phaseGlyphState, type RunState, scanElapsedMs } from './derive.js';
|
||||
import { inlineFailureReason } from './failure.js';
|
||||
import { PIPELINE, type PipelineState } from './pipeline.js';
|
||||
|
||||
export interface RenderInput {
|
||||
@@ -229,7 +230,8 @@ function footerLines(input: RenderInput, opts: RenderOptions): string[] {
|
||||
const temporalValue = temporalDashboardUrl(input.workflowId);
|
||||
|
||||
if (isTerminal(input.temporalStatus)) {
|
||||
const reason = input.failureMessage ?? input.state?.error ?? 'no result recorded';
|
||||
const rawReason = input.failureMessage ?? input.state?.error;
|
||||
const reason = rawReason ? inlineFailureReason(rawReason) : 'no result recorded';
|
||||
return [
|
||||
footerDivider(opts),
|
||||
paint(
|
||||
|
||||
Reference in New Issue
Block a user