tubeless 0.2.13 → 0.2.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/cli-pipeline-command.d.ts +7 -2
- package/dist/cli/cli-pipeline-command.js +24 -3
- package/dist/cli/cli-pipeline-command.js.map +1 -1
- package/dist/core/child-execution.js +5 -3
- package/dist/core/child-execution.js.map +1 -1
- package/dist/core/child-progress.js +2 -0
- package/dist/core/child-progress.js.map +1 -1
- package/dist/core/pipeline-cache.d.ts +68 -0
- package/dist/core/pipeline-cache.js +157 -0
- package/dist/core/pipeline-cache.js.map +1 -0
- package/dist/core/pipeline-compiler.js +4 -2
- package/dist/core/pipeline-compiler.js.map +1 -1
- package/dist/core/pipeline-definition-identity.d.ts +3 -1
- package/dist/core/pipeline-definition-identity.js +38 -5
- package/dist/core/pipeline-definition-identity.js.map +1 -1
- package/dist/core/pipeline-definition-validation.d.ts +7 -2
- package/dist/core/pipeline-definition-validation.js +22 -2
- package/dist/core/pipeline-definition-validation.js.map +1 -1
- package/dist/core/pipeline-definition.d.ts +6 -0
- package/dist/core/pipeline-definition.js.map +1 -1
- package/dist/core/pipeline-execute.js +5 -0
- package/dist/core/pipeline-execute.js.map +1 -1
- package/dist/core/pipeline-graph.d.ts +2 -1
- package/dist/core/pipeline-graph.js +10 -4
- package/dist/core/pipeline-graph.js.map +1 -1
- package/dist/core/pipeline-mermaid.js +7 -1
- package/dist/core/pipeline-mermaid.js.map +1 -1
- package/dist/core/pipeline-plan.js +4 -0
- package/dist/core/pipeline-plan.js.map +1 -1
- package/dist/core/pipeline-query.d.ts +11 -0
- package/dist/core/pipeline-query.js +10 -0
- package/dist/core/pipeline-query.js.map +1 -0
- package/dist/core/pipeline-run-state.d.ts +2 -2
- package/dist/core/pipeline-run-state.js.map +1 -1
- package/dist/core/pipeline-step-executor.d.ts +2 -0
- package/dist/core/pipeline-step-executor.js +24 -9
- package/dist/core/pipeline-step-executor.js.map +1 -1
- package/dist/core/pipeline-step-metadata.d.ts +1 -0
- package/dist/core/pipeline-step-metadata.js +1 -0
- package/dist/core/pipeline-step-metadata.js.map +1 -1
- package/dist/core/pipeline-steps.d.ts +17 -3
- package/dist/core/pipeline-steps.js +11 -3
- package/dist/core/pipeline-steps.js.map +1 -1
- package/dist/core/pipeline-types.d.ts +20 -7
- package/dist/core/pipeline-types.js.map +1 -1
- package/dist/core/pipeline.d.ts +4 -0
- package/dist/core/pipeline.js +7 -1
- package/dist/core/pipeline.js.map +1 -1
- package/dist/node/node.d.ts +1 -0
- package/dist/node/node.js +1 -0
- package/dist/node/node.js.map +1 -1
- package/dist/reporter/interactive-reporter.js +3 -4
- package/dist/reporter/interactive-reporter.js.map +1 -1
- package/dist/reporter/reporter.d.ts +1 -0
- package/dist/reporter/reporter.js +4 -2
- package/dist/reporter/reporter.js.map +1 -1
- package/dist/run-store/cache-artifact.d.ts +7 -0
- package/dist/run-store/cache-artifact.js +22 -0
- package/dist/run-store/cache-artifact.js.map +1 -0
- package/dist/run-store/definition-diff.js +20 -8
- package/dist/run-store/definition-diff.js.map +1 -1
- package/dist/run-store/run-projection.js +2 -2
- package/dist/run-store/run-projection.js.map +1 -1
- package/dist/run-store/run-store.d.ts +2 -2
- package/dist/run-store/run-store.js.map +1 -1
- package/dist/studio/run-store-ui-artifacts.d.ts +5 -0
- package/dist/studio/run-store-ui-artifacts.js +18 -0
- package/dist/studio/run-store-ui-artifacts.js.map +1 -0
- package/dist/studio/run-store-ui-client-browser.js +2 -2
- package/dist/studio/run-store-ui-client-transport.js +9 -3
- package/dist/studio/run-store-ui-client-transport.js.map +1 -1
- package/dist/studio/run-store-ui-client.d.ts +2 -2
- package/dist/studio/run-store-ui-client.js +13 -7
- package/dist/studio/run-store-ui-client.js.map +1 -1
- package/dist/studio/run-store-ui-definitions.js +2 -1
- package/dist/studio/run-store-ui-definitions.js.map +1 -1
- package/dist/studio/run-store-ui-metadata.d.ts +13 -0
- package/dist/studio/run-store-ui-metadata.js +32 -0
- package/dist/studio/run-store-ui-metadata.js.map +1 -0
- package/dist/studio/run-store-ui-page.js +8 -0
- package/dist/studio/run-store-ui-page.js.map +1 -1
- package/dist/tracing/artifact-metadata.d.ts +1 -0
- package/dist/tracing/artifact-metadata.js +2 -2
- package/dist/tracing/artifact-metadata.js.map +1 -1
- package/dist/tracing/graph-metadata.d.ts +12 -0
- package/dist/tracing/graph-metadata.js +55 -0
- package/dist/tracing/graph-metadata.js.map +1 -0
- package/dist/tracing/tracing-internal.js +2 -2
- package/dist/tracing/tracing-internal.js.map +1 -1
- package/dist/tracing/tracing-schema.d.ts +58 -31
- package/dist/tracing/tracing-schema.js +26 -8
- package/dist/tracing/tracing-schema.js.map +1 -1
- package/dist/utilities/cache-duration.d.ts +2 -0
- package/dist/utilities/cache-duration.js +39 -0
- package/dist/utilities/cache-duration.js.map +1 -0
- package/dist/utilities/cache-key.d.ts +2 -0
- package/dist/utilities/cache-key.js +63 -0
- package/dist/utilities/cache-key.js.map +1 -0
- package/dist/utilities/cache-storage.d.ts +6 -0
- package/dist/utilities/cache-storage.js +83 -0
- package/dist/utilities/cache-storage.js.map +1 -0
- package/dist/utilities/canonical-json.d.ts +2 -0
- package/dist/utilities/canonical-json.js +12 -0
- package/dist/utilities/canonical-json.js.map +1 -0
- package/dist/workbench/workbench-commands.js +43 -3
- package/dist/workbench/workbench-commands.js.map +1 -1
- package/dist/workbench/workbench-history.js +2 -1
- package/dist/workbench/workbench-history.js.map +1 -1
- package/docs/agent-guide.md +23 -0
- package/docs/api-reference.md +98 -85
- package/docs/api-report.json +19 -6
- package/docs/artifacts.md +6 -2
- package/docs/cli.md +14 -0
- package/docs/concepts.md +10 -0
- package/docs/declarative-pipelines.md +4 -0
- package/docs/graph-metadata.md +108 -0
- package/docs/llms.txt +2 -0
- package/docs/recipes.md +5 -0
- package/docs/step-output-cache.md +242 -0
- package/docs/studio.md +11 -2
- package/examples/graph-metadata.ts +32 -0
- package/examples/project/tubeless.project.ts +5 -0
- package/examples/step-output-cache.ts +30 -0
- package/package.json +1 -1
- package/skills/tubeless/SKILL.md +16 -0
|
@@ -2,7 +2,7 @@ import { format } from "node:util";
|
|
|
2
2
|
import { hasVisibleStepProgress } from "../core/progress.js";
|
|
3
3
|
import { elapsedToken, shimmerToken, SPINNER_TOKEN } from "./live-ticker-frame.js";
|
|
4
4
|
import { createLiveTicker } from "./live-ticker.js";
|
|
5
|
-
import { createReporterTheme, createRunReporter, formatDurationMs, } from "./reporter.js";
|
|
5
|
+
import { createReporterTheme, createRunReporter, formatDurationMs, outputSourceSuffix, } from "./reporter.js";
|
|
6
6
|
import { safeTerminalLog, safeTerminalText } from "./terminal-text.js";
|
|
7
7
|
function autoInteractiveAllowed(output, config) {
|
|
8
8
|
const isTTY = config.terminal?.isTTY ?? output.isTTY === true;
|
|
@@ -50,8 +50,7 @@ function renderProgressDetail(detail, theme, spinner, progressBarWidth, parentSt
|
|
|
50
50
|
? theme.styled.description(theme.symbols.pending)
|
|
51
51
|
: theme.styled.start(spinner);
|
|
52
52
|
const id = safeTerminalText(detail.name ?? detail.id);
|
|
53
|
-
const label = (detail.label ? safeTerminalText(detail.label) : "") +
|
|
54
|
-
(detail.outputSource === "override" ? " (overridden)" : "");
|
|
53
|
+
const label = (detail.label ? safeTerminalText(detail.label) : "") + outputSourceSuffix(detail.outputSource);
|
|
55
54
|
const labelText = status === "cancelled" ? `cancelled${label ? `: ${label}` : ""}` : label;
|
|
56
55
|
const running = status === "running";
|
|
57
56
|
const body = labelText ? `${id} ${labelText}` : id;
|
|
@@ -67,7 +66,7 @@ function renderProgressDetail(detail, theme, spinner, progressBarWidth, parentSt
|
|
|
67
66
|
function renderStep(state, theme, spinner, progressBarWidth) {
|
|
68
67
|
const { step } = state;
|
|
69
68
|
const displayName = safeTerminalText(step.name ?? step.id) +
|
|
70
|
-
(state.status
|
|
69
|
+
(state.status === "planned" ? "" : outputSourceSuffix(state.outputSource));
|
|
71
70
|
switch (state.status) {
|
|
72
71
|
case "running": {
|
|
73
72
|
const progress = state.progress && hasVisibleStepProgress(state.progress)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive-reporter.js","sourceRoot":"","sources":["../../src/reporter/interactive-reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import { format } from \"node:util\";\nimport type {\n PipelineError,\n PipelineHooks,\n PipelineLogger,\n PipelinePlan,\n PipelineRun,\n PipelineStepProgress,\n PipelineStepStatus,\n} from \"../core/pipeline.js\";\nimport { hasVisibleStepProgress } from \"../core/progress.js\";\nimport { elapsedToken, shimmerToken, SPINNER_TOKEN } from \"./live-ticker-frame.js\";\nimport { createLiveTicker, type LiveTicker } from \"./live-ticker.js\";\nimport {\n createReporterTheme,\n createRunReporter,\n formatDurationMs,\n type ReporterTheme,\n type RunReporterConfig,\n} from \"./reporter.js\";\nimport { safeTerminalLog, safeTerminalText } from \"./terminal-text.js\";\n\n/** Rendering mode selected for pipeline lifecycle reporting. */\nexport type PipelineReporterMode = \"auto\" | \"interactive\" | \"plain\";\nexport type ResolvedPipelineReporterMode = Exclude<PipelineReporterMode, \"auto\">;\n\n/** Writable terminal-like destination used by the interactive reporter. */\nexport interface ReporterOutput {\n readonly columns?: number;\n readonly rows?: number;\n /**\n * File descriptor for live frames. When set, spinner, elapsed time, and shimmer\n * paint on a worker thread so they keep moving during CPU-bound steps. Defaults\n * to stdout's fd when `output` is `process.stdout`.\n */\n readonly fd?: number;\n readonly isTTY?: boolean;\n write(chunk: string): unknown;\n}\n\n/** Rendering and output settings for automatic, plain, or interactive reporting. */\nexport interface PipelineReporterConfig extends RunReporterConfig {\n /** Auto selects the interactive renderer only for a capable, non-CI TTY. */\n mode?: PipelineReporterMode;\n /** Terminal stream used by the interactive renderer. Defaults to stdout. */\n output?: ReporterOutput;\n /** Spinner redraw cadence. Defaults to 80ms. */\n refreshIntervalMs?: number;\n /** Filled/empty character width for determinate progress. Defaults to 20. */\n progressBarWidth?: number;\n /** Show recent logs beside progress in TTYs at least 120 columns by 8 rows. Defaults to auto. */\n logPane?: \"auto\" | \"off\";\n}\n\nexport interface PipelineReporterOptions extends PipelineReporterConfig {\n log: PipelineLogger;\n}\n\nexport interface PipelineReporterController<TResult = unknown> {\n readonly hooks: PipelineHooks<TResult>;\n readonly log: PipelineLogger;\n readonly mode: ResolvedPipelineReporterMode;\n /** Stop redraws and restore terminal state. Safe to call more than once. */\n dispose(): void;\n}\n\ntype StepState = PipelineStepStatus & {\n /** Wall-clock ms from Date.now() when the step entered the running state. */\n startedAtMs?: number;\n details?: PipelineStepProgress[\"details\"];\n};\n\ntype FinalizeState =\n | { status: \"idle\" }\n | { status: \"running\" }\n | { durationMs: number; status: \"completed\" }\n | { durationMs: number; error: PipelineError; status: \"failed\" };\n\nfunction autoInteractiveAllowed(output: ReporterOutput, config: PipelineReporterConfig): boolean {\n const isTTY = config.terminal?.isTTY ?? output.isTTY === true;\n const ci = process.env.CI;\n const isCI = ci !== undefined && ci !== \"\" && ci !== \"0\" && ci !== \"false\";\n return isTTY && process.env.TERM !== \"dumb\" && !isCI;\n}\n\nfunction resolveMode(\n output: ReporterOutput,\n config: PipelineReporterConfig\n): ResolvedPipelineReporterMode {\n if (config.mode === \"interactive\") return \"interactive\";\n if (config.mode === \"plain\") return \"plain\";\n return autoInteractiveAllowed(output, config) ? \"interactive\" : \"plain\";\n}\n\nfunction safeNumber(value: number): number {\n return Number.isFinite(value) ? value : 0;\n}\n\nfunction formatCount(value: number): string {\n return Number.isInteger(value) ? String(value) : value.toFixed(1);\n}\n\nfunction renderProgress(progress: PipelineStepProgress, width: number, unicode: boolean): string {\n // Parent line keeps the summary message only; per-item work uses `details`.\n const message = progress.message ? ` ${safeTerminalText(progress.message)}` : \"\";\n if (progress.total === undefined || safeNumber(progress.total) <= 0) {\n return `${formatCount(safeNumber(progress.completed))}${message}`;\n }\n const completed = safeNumber(progress.completed);\n const total = safeNumber(progress.total);\n const ratio = Math.max(0, Math.min(1, completed / total));\n const filled = Math.round(ratio * width);\n const bar = `${unicode ? \"█\".repeat(filled) : \"=\".repeat(filled)}${\n unicode ? \"░\".repeat(width - filled) : \"-\".repeat(width - filled)\n }`;\n return `[${bar}] ${Math.round(ratio * 100)}% ${formatCount(completed)}/${formatCount(total)}${message}`;\n}\n\nfunction renderProgressDetail(\n detail: NonNullable<PipelineStepProgress[\"details\"]>[number],\n theme: ReporterTheme,\n spinner: string,\n progressBarWidth: number,\n parentStatus: PipelineStepStatus[\"status\"]\n): string {\n const status =\n (detail.status ?? \"running\") === \"running\" && parentStatus !== \"running\"\n ? parentStatus\n : (detail.status ?? \"running\");\n const symbol =\n status === \"completed\"\n ? theme.styled.complete(theme.symbols.complete)\n : status === \"failed\"\n ? theme.styled.fail(theme.symbols.fail)\n : status === \"skipped\" || status === \"cancelled\"\n ? theme.styled.skip(theme.symbols.skip)\n : status === \"pending\"\n ? theme.styled.description(theme.symbols.pending)\n : theme.styled.start(spinner);\n const id = safeTerminalText(detail.name ?? detail.id);\n const label =\n (detail.label ? safeTerminalText(detail.label) : \"\") +\n (detail.outputSource === \"override\" ? \" (overridden)\" : \"\");\n const labelText = status === \"cancelled\" ? `cancelled${label ? `: ${label}` : \"\"}` : label;\n const running = status === \"running\";\n const body = labelText ? `${id} ${labelText}` : id;\n const paintedBody =\n running && theme.colorEnabled\n ? shimmerToken(body)\n : `${id}${labelText ? ` ${theme.styled.description(labelText)}` : \"\"}`;\n const depth = Math.max(0, Math.min(32, Math.floor(safeNumber(detail.depth ?? 0))));\n const progress =\n detail.completed === undefined\n ? \"\"\n : ` ${renderProgress(\n { completed: detail.completed, total: detail.total },\n progressBarWidth,\n theme.unicodeEnabled\n )}`;\n return `${\" \".repeat(depth + 2)}${symbol} ${paintedBody}${progress}`;\n}\n\nfunction renderStep(\n state: StepState,\n theme: ReporterTheme,\n spinner: string,\n progressBarWidth: number\n): string[] {\n const { step } = state;\n const displayName =\n safeTerminalText(step.name ?? step.id) +\n (state.status !== \"planned\" && state.outputSource === \"override\" ? \" (overridden)\" : \"\");\n switch (state.status) {\n case \"running\": {\n const progress =\n state.progress && hasVisibleStepProgress(state.progress)\n ? ` ${renderProgress(state.progress, progressBarWidth, theme.unicodeEnabled)}`\n : \"\";\n const elapsed =\n state.startedAtMs !== undefined\n ? ` ${theme.styled.duration(elapsedToken(state.startedAtMs))}`\n : \"\";\n const lines = [\n ` ${theme.styled.start(spinner)} ${shimmerToken(displayName)}${progress}${elapsed}`,\n ];\n return lines;\n }\n case \"completed\":\n return [\n ` ${theme.styled.complete(theme.symbols.complete)} ${displayName} ${theme.styled.duration(\n `(${formatDurationMs(state.finishedAtMs - state.startedAtMs)})`\n )}`,\n ];\n case \"failed\":\n return [\n ` ${theme.styled.fail(theme.symbols.fail)} ${displayName}: ${safeTerminalText(\n state.error.message\n )}`,\n ];\n case \"cancelled\":\n return [\n ` ${theme.styled.skip(theme.symbols.skip)} ${displayName}: cancelled: ${safeTerminalText(\n state.error.message\n )}`,\n ];\n case \"skipped\":\n return [\n ` ${theme.styled.skip(theme.symbols.skip)} ${displayName} ${theme.styled.duration(\n `(${safeTerminalText(state.message ?? state.reason)})`\n )}`,\n ];\n case \"planned\":\n return [\n ` ${theme.styled.description(theme.symbols.pending)} ${displayName} ${theme.styled.description(\"waiting\")}`,\n ];\n }\n}\n\nfunction reporterOutputFd(output: ReporterOutput): number | undefined {\n const fd = output.fd ?? (output === process.stdout ? process.stdout.fd : undefined);\n return fd !== undefined && Number.isInteger(fd) && fd >= 0 ? fd : undefined;\n}\n\nfunction createInteractiveReporter<TResult>(\n options: PipelineReporterOptions,\n output: ReporterOutput\n): PipelineReporterController<TResult> {\n const terminalIsTTY = options.terminal?.isTTY ?? output.isTTY === true;\n const theme = createReporterTheme({\n ...options,\n terminal: { isTTY: terminalIsTTY, ...options.terminal },\n });\n const progressBarWidth = Math.max(4, Math.floor(options.progressBarWidth ?? 20));\n // ~12.5 fps keeps braille spinners smooth without flooding the terminal.\n const refreshIntervalMs = Math.max(16, Math.floor(options.refreshIntervalMs ?? 80));\n const steps = new Map<string, StepState>();\n const recentLogs: string[] = [];\n let plan: PipelinePlan | undefined;\n let result: PipelineRun<TResult> | undefined;\n let finalize: FinalizeState = { status: \"idle\" };\n let lastProgressRedrawAt = Number.NEGATIVE_INFINITY;\n let progressDirty = false;\n let disposed = false;\n let ticker: LiveTicker | undefined;\n let trailingFlush: ReturnType<typeof setTimeout> | undefined;\n let exitListener: (() => void) | undefined;\n let resizeOutput: NodeJS.WriteStream | undefined;\n\n const frameLines = (): string[] => {\n if (!plan) return [];\n const lines: string[] = [];\n if (options.logPlan !== false) {\n const header = result\n ? options.logSummary === false\n ? `Pipeline ${safeTerminalText(result.pipelineId)}`\n : `Pipeline ${safeTerminalText(result.pipelineId)}: done in ${formatDurationMs(result.finishedAtMs - result.startedAtMs)} (status=${result.status}, steps=${result.steps.length}, errors=${result.errors.length})`\n : `Pipeline ${safeTerminalText(plan.pipelineId)} (${plan.steps.length} steps, dryRun=${plan.dryRun})`;\n lines.push(\n result?.status === \"completed\"\n ? theme.styled.complete(header)\n : result\n ? theme.styled.fail(header)\n : theme.styled.pipeline(header)\n );\n }\n for (const state of steps.values()) {\n lines.push(...renderStep(state, theme, SPINNER_TOKEN, progressBarWidth));\n for (const detail of state.details ?? []) {\n lines.push(\n renderProgressDetail(detail, theme, SPINNER_TOKEN, progressBarWidth, state.status)\n );\n }\n }\n if (finalize.status === \"running\") {\n lines.push(` ${theme.styled.start(SPINNER_TOKEN)} ${shimmerToken(\"finalize\")}`);\n } else if (finalize.status === \"completed\") {\n lines.push(\n ` ${theme.styled.complete(theme.symbols.complete)} finalize ${theme.styled.duration(\n `(${formatDurationMs(finalize.durationMs)})`\n )}`\n );\n } else if (finalize.status === \"failed\") {\n lines.push(\n ` ${theme.styled.fail(theme.symbols.fail)} finalize: ${safeTerminalText(\n finalize.error.message\n )}`\n );\n }\n return lines;\n };\n\n const ensureTicker = (): LiveTicker => {\n if (!ticker) {\n ticker = createLiveTicker({\n color: theme.colorEnabled,\n columns: output.columns,\n getColumns: () => output.columns,\n fd: reporterOutputFd(output),\n refreshIntervalMs,\n unicode: theme.unicodeEnabled,\n write: (chunk) => {\n output.write(chunk);\n },\n });\n }\n return ticker;\n };\n\n const logPaneVisible = (): boolean =>\n plan !== undefined &&\n !result &&\n options.logPane !== \"off\" &&\n (output.columns ?? 0) >= 120 &&\n (output.rows ?? 0) >= 8;\n\n const redraw = (): void => {\n if (disposed) return;\n const lines = frameLines();\n if (lines.length === 0 && !logPaneVisible()) {\n ticker?.setLines([]);\n return;\n }\n const rows = output.rows;\n const logPane = logPaneVisible()\n ? recentLogs.length > 0\n ? recentLogs.slice(-Math.min(8, (rows ?? 0) - 3))\n : [theme.unicodeEnabled ? \"Waiting for logs…\" : \"Waiting for logs...\"]\n : undefined;\n if (rows === undefined || rows < 2 || lines.length < rows) {\n ensureTicker().setLines(lines, logPane);\n return;\n }\n if (result) {\n // A finished tree can scroll normally; never try to erase beyond the viewport.\n ensureTicker().setLines([]);\n ensureTicker().writeLog(`${lines.join(\"\\n\")}\\n`);\n return;\n }\n const ellipsis = theme.unicodeEnabled ? \"…\" : \"...\";\n if (rows < 5) {\n ensureTicker().setLines(\n [lines[0]!, ` ${ellipsis} ${lines.length - 1} rows omitted`].slice(0, rows - 1)\n );\n return;\n }\n const available = rows - 4;\n let focus = 0;\n for (const [index, line] of lines.entries()) {\n if (line.includes(SPINNER_TOKEN)) focus = index;\n }\n const start = Math.max(\n 1,\n Math.min(lines.length - available, focus - Math.floor(available / 2))\n );\n const end = start + available;\n const visible = [lines[0]!];\n if (start > 1) visible.push(` ${ellipsis} ${start - 1} rows above`);\n visible.push(...lines.slice(start, end));\n if (end < lines.length) visible.push(` ${ellipsis} ${lines.length - end} rows below`);\n ensureTicker().setLines(visible, logPane);\n };\n\n const flushProgress = (): void => {\n if (trailingFlush !== undefined) {\n clearTimeout(trailingFlush);\n trailingFlush = undefined;\n }\n if (!progressDirty) return;\n progressDirty = false;\n lastProgressRedrawAt = Date.now();\n redraw();\n };\n\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n if (trailingFlush !== undefined) {\n clearTimeout(trailingFlush);\n trailingFlush = undefined;\n }\n ticker?.dispose();\n ticker = undefined;\n if (exitListener) process.off(\"exit\", exitListener);\n exitListener = undefined;\n resizeOutput?.off(\"resize\", redraw);\n resizeOutput = undefined;\n };\n\n const writeLog = (level: \"error\" | \"log\" | \"warn\", message?: unknown, ...args: unknown[]) => {\n const rendered = message === undefined && args.length === 0 ? \"\" : format(message, ...args);\n const safeRendered = safeTerminalLog(rendered);\n const prefix =\n level === \"error\"\n ? `${theme.styled.fail(theme.symbols.fail)} `\n : level === \"warn\"\n ? `${theme.styled.skip(\"!\")} `\n : \"\";\n const text = `${prefix}${safeRendered}\\n`;\n if (disposed) {\n output.write(text);\n return;\n }\n // Retain a bounded tail for the pane, including when the terminal is resized.\n recentLogs.push(\n ...`${prefix}${safeRendered}`\n .split(\"\\n\")\n .slice(-8)\n .map((line) => line.slice(0, 2048))\n );\n recentLogs.splice(0, Math.max(0, recentLogs.length - 8));\n if (!logPaneVisible()) ensureTicker().writeLog(text);\n progressDirty = false;\n lastProgressRedrawAt = Date.now();\n redraw();\n };\n\n const log: PipelineLogger = {\n error: (message, ...args) => writeLog(\"error\", message, ...args),\n log: (message, ...args) => writeLog(\"log\", message, ...args),\n warn: (message, ...args) => writeLog(\"warn\", message, ...args),\n };\n\n const hooks: PipelineHooks<TResult> = {\n onPipelineStart: (nextPlan) => {\n plan = nextPlan;\n for (const step of nextPlan.steps) {\n steps.set(step.id, { pipelineId: nextPlan.pipelineId, status: \"planned\", step });\n }\n if (output === process.stdout || output === process.stderr) {\n exitListener = dispose;\n process.once(\"exit\", exitListener);\n resizeOutput = output === process.stdout ? process.stdout : process.stderr;\n resizeOutput.on(\"resize\", redraw);\n }\n redraw();\n },\n onStepStatus: (event) => {\n const previous = steps.get(event.step.id);\n if (event.status === \"running\") {\n // Empty/non-visible progress only refreshes the frame; retain the last\n // visible progress snapshot while still publishing one running state.\n const progress =\n event.progress && hasVisibleStepProgress(event.progress)\n ? event.progress\n : previous?.status === \"running\"\n ? previous.progress\n : undefined;\n steps.set(event.step.id, {\n ...event,\n progress,\n details: progress?.details,\n startedAtMs: previous?.startedAtMs ?? Date.now(),\n });\n const now = Date.now();\n if (now - lastProgressRedrawAt >= refreshIntervalMs) {\n progressDirty = false;\n lastProgressRedrawAt = now;\n redraw();\n } else {\n progressDirty = true;\n trailingFlush ??= setTimeout(\n () => {\n trailingFlush = undefined;\n if (!disposed) flushProgress();\n },\n Math.max(0, refreshIntervalMs - (now - lastProgressRedrawAt))\n );\n trailingFlush.unref?.();\n }\n return;\n }\n if (event.status !== \"planned\") flushProgress();\n steps.set(event.step.id, { ...event, details: previous?.details });\n redraw();\n },\n onFinalizeStart: () => {\n finalize = { status: \"running\" };\n redraw();\n },\n onFinalizeComplete: ({ durationMs }) => {\n finalize = { durationMs, status: \"completed\" };\n redraw();\n },\n onFinalizeError: ({ durationMs, error }) => {\n finalize = { durationMs, error, status: \"failed\" };\n redraw();\n },\n onPipelineComplete: (nextResult) => {\n result = nextResult;\n redraw();\n dispose();\n },\n };\n\n return { dispose, hooks, log, mode: \"interactive\" };\n}\n\n/** Create the plain or interactive reporter selected by the configured terminal mode. */\nexport function createPipelineReporter<TResult = unknown>(\n options: PipelineReporterOptions\n): PipelineReporterController<TResult> {\n const output = options.output ?? process.stdout;\n const mode = resolveMode(output, options);\n if (mode === \"interactive\") {\n return createInteractiveReporter(options, output);\n }\n return {\n dispose: () => undefined,\n hooks: createRunReporter<TResult>(options),\n log: options.log,\n mode: \"plain\",\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"interactive-reporter.js","sourceRoot":"","sources":["../../src/reporter/interactive-reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import { format } from \"node:util\";\nimport type {\n PipelineError,\n PipelineHooks,\n PipelineLogger,\n PipelinePlan,\n PipelineRun,\n PipelineStepProgress,\n PipelineStepStatus,\n} from \"../core/pipeline.js\";\nimport { hasVisibleStepProgress } from \"../core/progress.js\";\nimport { elapsedToken, shimmerToken, SPINNER_TOKEN } from \"./live-ticker-frame.js\";\nimport { createLiveTicker, type LiveTicker } from \"./live-ticker.js\";\nimport {\n createReporterTheme,\n createRunReporter,\n formatDurationMs,\n outputSourceSuffix,\n type ReporterTheme,\n type RunReporterConfig,\n} from \"./reporter.js\";\nimport { safeTerminalLog, safeTerminalText } from \"./terminal-text.js\";\n\n/** Rendering mode selected for pipeline lifecycle reporting. */\nexport type PipelineReporterMode = \"auto\" | \"interactive\" | \"plain\";\nexport type ResolvedPipelineReporterMode = Exclude<PipelineReporterMode, \"auto\">;\n\n/** Writable terminal-like destination used by the interactive reporter. */\nexport interface ReporterOutput {\n readonly columns?: number;\n readonly rows?: number;\n /**\n * File descriptor for live frames. When set, spinner, elapsed time, and shimmer\n * paint on a worker thread so they keep moving during CPU-bound steps. Defaults\n * to stdout's fd when `output` is `process.stdout`.\n */\n readonly fd?: number;\n readonly isTTY?: boolean;\n write(chunk: string): unknown;\n}\n\n/** Rendering and output settings for automatic, plain, or interactive reporting. */\nexport interface PipelineReporterConfig extends RunReporterConfig {\n /** Auto selects the interactive renderer only for a capable, non-CI TTY. */\n mode?: PipelineReporterMode;\n /** Terminal stream used by the interactive renderer. Defaults to stdout. */\n output?: ReporterOutput;\n /** Spinner redraw cadence. Defaults to 80ms. */\n refreshIntervalMs?: number;\n /** Filled/empty character width for determinate progress. Defaults to 20. */\n progressBarWidth?: number;\n /** Show recent logs beside progress in TTYs at least 120 columns by 8 rows. Defaults to auto. */\n logPane?: \"auto\" | \"off\";\n}\n\nexport interface PipelineReporterOptions extends PipelineReporterConfig {\n log: PipelineLogger;\n}\n\nexport interface PipelineReporterController<TResult = unknown> {\n readonly hooks: PipelineHooks<TResult>;\n readonly log: PipelineLogger;\n readonly mode: ResolvedPipelineReporterMode;\n /** Stop redraws and restore terminal state. Safe to call more than once. */\n dispose(): void;\n}\n\ntype StepState = PipelineStepStatus & {\n /** Wall-clock ms from Date.now() when the step entered the running state. */\n startedAtMs?: number;\n details?: PipelineStepProgress[\"details\"];\n};\n\ntype FinalizeState =\n | { status: \"idle\" }\n | { status: \"running\" }\n | { durationMs: number; status: \"completed\" }\n | { durationMs: number; error: PipelineError; status: \"failed\" };\n\nfunction autoInteractiveAllowed(output: ReporterOutput, config: PipelineReporterConfig): boolean {\n const isTTY = config.terminal?.isTTY ?? output.isTTY === true;\n const ci = process.env.CI;\n const isCI = ci !== undefined && ci !== \"\" && ci !== \"0\" && ci !== \"false\";\n return isTTY && process.env.TERM !== \"dumb\" && !isCI;\n}\n\nfunction resolveMode(\n output: ReporterOutput,\n config: PipelineReporterConfig\n): ResolvedPipelineReporterMode {\n if (config.mode === \"interactive\") return \"interactive\";\n if (config.mode === \"plain\") return \"plain\";\n return autoInteractiveAllowed(output, config) ? \"interactive\" : \"plain\";\n}\n\nfunction safeNumber(value: number): number {\n return Number.isFinite(value) ? value : 0;\n}\n\nfunction formatCount(value: number): string {\n return Number.isInteger(value) ? String(value) : value.toFixed(1);\n}\n\nfunction renderProgress(progress: PipelineStepProgress, width: number, unicode: boolean): string {\n // Parent line keeps the summary message only; per-item work uses `details`.\n const message = progress.message ? ` ${safeTerminalText(progress.message)}` : \"\";\n if (progress.total === undefined || safeNumber(progress.total) <= 0) {\n return `${formatCount(safeNumber(progress.completed))}${message}`;\n }\n const completed = safeNumber(progress.completed);\n const total = safeNumber(progress.total);\n const ratio = Math.max(0, Math.min(1, completed / total));\n const filled = Math.round(ratio * width);\n const bar = `${unicode ? \"█\".repeat(filled) : \"=\".repeat(filled)}${\n unicode ? \"░\".repeat(width - filled) : \"-\".repeat(width - filled)\n }`;\n return `[${bar}] ${Math.round(ratio * 100)}% ${formatCount(completed)}/${formatCount(total)}${message}`;\n}\n\nfunction renderProgressDetail(\n detail: NonNullable<PipelineStepProgress[\"details\"]>[number],\n theme: ReporterTheme,\n spinner: string,\n progressBarWidth: number,\n parentStatus: PipelineStepStatus[\"status\"]\n): string {\n const status =\n (detail.status ?? \"running\") === \"running\" && parentStatus !== \"running\"\n ? parentStatus\n : (detail.status ?? \"running\");\n const symbol =\n status === \"completed\"\n ? theme.styled.complete(theme.symbols.complete)\n : status === \"failed\"\n ? theme.styled.fail(theme.symbols.fail)\n : status === \"skipped\" || status === \"cancelled\"\n ? theme.styled.skip(theme.symbols.skip)\n : status === \"pending\"\n ? theme.styled.description(theme.symbols.pending)\n : theme.styled.start(spinner);\n const id = safeTerminalText(detail.name ?? detail.id);\n const label =\n (detail.label ? safeTerminalText(detail.label) : \"\") + outputSourceSuffix(detail.outputSource);\n const labelText = status === \"cancelled\" ? `cancelled${label ? `: ${label}` : \"\"}` : label;\n const running = status === \"running\";\n const body = labelText ? `${id} ${labelText}` : id;\n const paintedBody =\n running && theme.colorEnabled\n ? shimmerToken(body)\n : `${id}${labelText ? ` ${theme.styled.description(labelText)}` : \"\"}`;\n const depth = Math.max(0, Math.min(32, Math.floor(safeNumber(detail.depth ?? 0))));\n const progress =\n detail.completed === undefined\n ? \"\"\n : ` ${renderProgress(\n { completed: detail.completed, total: detail.total },\n progressBarWidth,\n theme.unicodeEnabled\n )}`;\n return `${\" \".repeat(depth + 2)}${symbol} ${paintedBody}${progress}`;\n}\n\nfunction renderStep(\n state: StepState,\n theme: ReporterTheme,\n spinner: string,\n progressBarWidth: number\n): string[] {\n const { step } = state;\n const displayName =\n safeTerminalText(step.name ?? step.id) +\n (state.status === \"planned\" ? \"\" : outputSourceSuffix(state.outputSource));\n switch (state.status) {\n case \"running\": {\n const progress =\n state.progress && hasVisibleStepProgress(state.progress)\n ? ` ${renderProgress(state.progress, progressBarWidth, theme.unicodeEnabled)}`\n : \"\";\n const elapsed =\n state.startedAtMs !== undefined\n ? ` ${theme.styled.duration(elapsedToken(state.startedAtMs))}`\n : \"\";\n const lines = [\n ` ${theme.styled.start(spinner)} ${shimmerToken(displayName)}${progress}${elapsed}`,\n ];\n return lines;\n }\n case \"completed\":\n return [\n ` ${theme.styled.complete(theme.symbols.complete)} ${displayName} ${theme.styled.duration(\n `(${formatDurationMs(state.finishedAtMs - state.startedAtMs)})`\n )}`,\n ];\n case \"failed\":\n return [\n ` ${theme.styled.fail(theme.symbols.fail)} ${displayName}: ${safeTerminalText(\n state.error.message\n )}`,\n ];\n case \"cancelled\":\n return [\n ` ${theme.styled.skip(theme.symbols.skip)} ${displayName}: cancelled: ${safeTerminalText(\n state.error.message\n )}`,\n ];\n case \"skipped\":\n return [\n ` ${theme.styled.skip(theme.symbols.skip)} ${displayName} ${theme.styled.duration(\n `(${safeTerminalText(state.message ?? state.reason)})`\n )}`,\n ];\n case \"planned\":\n return [\n ` ${theme.styled.description(theme.symbols.pending)} ${displayName} ${theme.styled.description(\"waiting\")}`,\n ];\n }\n}\n\nfunction reporterOutputFd(output: ReporterOutput): number | undefined {\n const fd = output.fd ?? (output === process.stdout ? process.stdout.fd : undefined);\n return fd !== undefined && Number.isInteger(fd) && fd >= 0 ? fd : undefined;\n}\n\nfunction createInteractiveReporter<TResult>(\n options: PipelineReporterOptions,\n output: ReporterOutput\n): PipelineReporterController<TResult> {\n const terminalIsTTY = options.terminal?.isTTY ?? output.isTTY === true;\n const theme = createReporterTheme({\n ...options,\n terminal: { isTTY: terminalIsTTY, ...options.terminal },\n });\n const progressBarWidth = Math.max(4, Math.floor(options.progressBarWidth ?? 20));\n // ~12.5 fps keeps braille spinners smooth without flooding the terminal.\n const refreshIntervalMs = Math.max(16, Math.floor(options.refreshIntervalMs ?? 80));\n const steps = new Map<string, StepState>();\n const recentLogs: string[] = [];\n let plan: PipelinePlan | undefined;\n let result: PipelineRun<TResult> | undefined;\n let finalize: FinalizeState = { status: \"idle\" };\n let lastProgressRedrawAt = Number.NEGATIVE_INFINITY;\n let progressDirty = false;\n let disposed = false;\n let ticker: LiveTicker | undefined;\n let trailingFlush: ReturnType<typeof setTimeout> | undefined;\n let exitListener: (() => void) | undefined;\n let resizeOutput: NodeJS.WriteStream | undefined;\n\n const frameLines = (): string[] => {\n if (!plan) return [];\n const lines: string[] = [];\n if (options.logPlan !== false) {\n const header = result\n ? options.logSummary === false\n ? `Pipeline ${safeTerminalText(result.pipelineId)}`\n : `Pipeline ${safeTerminalText(result.pipelineId)}: done in ${formatDurationMs(result.finishedAtMs - result.startedAtMs)} (status=${result.status}, steps=${result.steps.length}, errors=${result.errors.length})`\n : `Pipeline ${safeTerminalText(plan.pipelineId)} (${plan.steps.length} steps, dryRun=${plan.dryRun})`;\n lines.push(\n result?.status === \"completed\"\n ? theme.styled.complete(header)\n : result\n ? theme.styled.fail(header)\n : theme.styled.pipeline(header)\n );\n }\n for (const state of steps.values()) {\n lines.push(...renderStep(state, theme, SPINNER_TOKEN, progressBarWidth));\n for (const detail of state.details ?? []) {\n lines.push(\n renderProgressDetail(detail, theme, SPINNER_TOKEN, progressBarWidth, state.status)\n );\n }\n }\n if (finalize.status === \"running\") {\n lines.push(` ${theme.styled.start(SPINNER_TOKEN)} ${shimmerToken(\"finalize\")}`);\n } else if (finalize.status === \"completed\") {\n lines.push(\n ` ${theme.styled.complete(theme.symbols.complete)} finalize ${theme.styled.duration(\n `(${formatDurationMs(finalize.durationMs)})`\n )}`\n );\n } else if (finalize.status === \"failed\") {\n lines.push(\n ` ${theme.styled.fail(theme.symbols.fail)} finalize: ${safeTerminalText(\n finalize.error.message\n )}`\n );\n }\n return lines;\n };\n\n const ensureTicker = (): LiveTicker => {\n if (!ticker) {\n ticker = createLiveTicker({\n color: theme.colorEnabled,\n columns: output.columns,\n getColumns: () => output.columns,\n fd: reporterOutputFd(output),\n refreshIntervalMs,\n unicode: theme.unicodeEnabled,\n write: (chunk) => {\n output.write(chunk);\n },\n });\n }\n return ticker;\n };\n\n const logPaneVisible = (): boolean =>\n plan !== undefined &&\n !result &&\n options.logPane !== \"off\" &&\n (output.columns ?? 0) >= 120 &&\n (output.rows ?? 0) >= 8;\n\n const redraw = (): void => {\n if (disposed) return;\n const lines = frameLines();\n if (lines.length === 0 && !logPaneVisible()) {\n ticker?.setLines([]);\n return;\n }\n const rows = output.rows;\n const logPane = logPaneVisible()\n ? recentLogs.length > 0\n ? recentLogs.slice(-Math.min(8, (rows ?? 0) - 3))\n : [theme.unicodeEnabled ? \"Waiting for logs…\" : \"Waiting for logs...\"]\n : undefined;\n if (rows === undefined || rows < 2 || lines.length < rows) {\n ensureTicker().setLines(lines, logPane);\n return;\n }\n if (result) {\n // A finished tree can scroll normally; never try to erase beyond the viewport.\n ensureTicker().setLines([]);\n ensureTicker().writeLog(`${lines.join(\"\\n\")}\\n`);\n return;\n }\n const ellipsis = theme.unicodeEnabled ? \"…\" : \"...\";\n if (rows < 5) {\n ensureTicker().setLines(\n [lines[0]!, ` ${ellipsis} ${lines.length - 1} rows omitted`].slice(0, rows - 1)\n );\n return;\n }\n const available = rows - 4;\n let focus = 0;\n for (const [index, line] of lines.entries()) {\n if (line.includes(SPINNER_TOKEN)) focus = index;\n }\n const start = Math.max(\n 1,\n Math.min(lines.length - available, focus - Math.floor(available / 2))\n );\n const end = start + available;\n const visible = [lines[0]!];\n if (start > 1) visible.push(` ${ellipsis} ${start - 1} rows above`);\n visible.push(...lines.slice(start, end));\n if (end < lines.length) visible.push(` ${ellipsis} ${lines.length - end} rows below`);\n ensureTicker().setLines(visible, logPane);\n };\n\n const flushProgress = (): void => {\n if (trailingFlush !== undefined) {\n clearTimeout(trailingFlush);\n trailingFlush = undefined;\n }\n if (!progressDirty) return;\n progressDirty = false;\n lastProgressRedrawAt = Date.now();\n redraw();\n };\n\n const dispose = (): void => {\n if (disposed) return;\n disposed = true;\n if (trailingFlush !== undefined) {\n clearTimeout(trailingFlush);\n trailingFlush = undefined;\n }\n ticker?.dispose();\n ticker = undefined;\n if (exitListener) process.off(\"exit\", exitListener);\n exitListener = undefined;\n resizeOutput?.off(\"resize\", redraw);\n resizeOutput = undefined;\n };\n\n const writeLog = (level: \"error\" | \"log\" | \"warn\", message?: unknown, ...args: unknown[]) => {\n const rendered = message === undefined && args.length === 0 ? \"\" : format(message, ...args);\n const safeRendered = safeTerminalLog(rendered);\n const prefix =\n level === \"error\"\n ? `${theme.styled.fail(theme.symbols.fail)} `\n : level === \"warn\"\n ? `${theme.styled.skip(\"!\")} `\n : \"\";\n const text = `${prefix}${safeRendered}\\n`;\n if (disposed) {\n output.write(text);\n return;\n }\n // Retain a bounded tail for the pane, including when the terminal is resized.\n recentLogs.push(\n ...`${prefix}${safeRendered}`\n .split(\"\\n\")\n .slice(-8)\n .map((line) => line.slice(0, 2048))\n );\n recentLogs.splice(0, Math.max(0, recentLogs.length - 8));\n if (!logPaneVisible()) ensureTicker().writeLog(text);\n progressDirty = false;\n lastProgressRedrawAt = Date.now();\n redraw();\n };\n\n const log: PipelineLogger = {\n error: (message, ...args) => writeLog(\"error\", message, ...args),\n log: (message, ...args) => writeLog(\"log\", message, ...args),\n warn: (message, ...args) => writeLog(\"warn\", message, ...args),\n };\n\n const hooks: PipelineHooks<TResult> = {\n onPipelineStart: (nextPlan) => {\n plan = nextPlan;\n for (const step of nextPlan.steps) {\n steps.set(step.id, { pipelineId: nextPlan.pipelineId, status: \"planned\", step });\n }\n if (output === process.stdout || output === process.stderr) {\n exitListener = dispose;\n process.once(\"exit\", exitListener);\n resizeOutput = output === process.stdout ? process.stdout : process.stderr;\n resizeOutput.on(\"resize\", redraw);\n }\n redraw();\n },\n onStepStatus: (event) => {\n const previous = steps.get(event.step.id);\n if (event.status === \"running\") {\n // Empty/non-visible progress only refreshes the frame; retain the last\n // visible progress snapshot while still publishing one running state.\n const progress =\n event.progress && hasVisibleStepProgress(event.progress)\n ? event.progress\n : previous?.status === \"running\"\n ? previous.progress\n : undefined;\n steps.set(event.step.id, {\n ...event,\n progress,\n details: progress?.details,\n startedAtMs: previous?.startedAtMs ?? Date.now(),\n });\n const now = Date.now();\n if (now - lastProgressRedrawAt >= refreshIntervalMs) {\n progressDirty = false;\n lastProgressRedrawAt = now;\n redraw();\n } else {\n progressDirty = true;\n trailingFlush ??= setTimeout(\n () => {\n trailingFlush = undefined;\n if (!disposed) flushProgress();\n },\n Math.max(0, refreshIntervalMs - (now - lastProgressRedrawAt))\n );\n trailingFlush.unref?.();\n }\n return;\n }\n if (event.status !== \"planned\") flushProgress();\n steps.set(event.step.id, { ...event, details: previous?.details });\n redraw();\n },\n onFinalizeStart: () => {\n finalize = { status: \"running\" };\n redraw();\n },\n onFinalizeComplete: ({ durationMs }) => {\n finalize = { durationMs, status: \"completed\" };\n redraw();\n },\n onFinalizeError: ({ durationMs, error }) => {\n finalize = { durationMs, error, status: \"failed\" };\n redraw();\n },\n onPipelineComplete: (nextResult) => {\n result = nextResult;\n redraw();\n dispose();\n },\n };\n\n return { dispose, hooks, log, mode: \"interactive\" };\n}\n\n/** Create the plain or interactive reporter selected by the configured terminal mode. */\nexport function createPipelineReporter<TResult = unknown>(\n options: PipelineReporterOptions\n): PipelineReporterController<TResult> {\n const output = options.output ?? process.stdout;\n const mode = resolveMode(output, options);\n if (mode === \"interactive\") {\n return createInteractiveReporter(options, output);\n }\n return {\n dispose: () => undefined,\n hooks: createRunReporter<TResult>(options),\n log: options.log,\n mode: \"plain\",\n };\n}\n"]}
|
|
@@ -49,5 +49,6 @@ export interface ReporterTheme {
|
|
|
49
49
|
unicodeEnabled: boolean;
|
|
50
50
|
}
|
|
51
51
|
export declare function createReporterTheme(config?: RunReporterConfig): ReporterTheme;
|
|
52
|
+
export declare function outputSourceSuffix(source?: "override" | "cache"): string;
|
|
52
53
|
/** Create concise, append-only lifecycle logging for a pipeline run. */
|
|
53
54
|
export declare function createRunReporter<TResult = unknown>(options: RunReporterOptions): PipelineHooks<TResult>;
|
|
@@ -78,6 +78,9 @@ export function createReporterTheme(config = {}) {
|
|
|
78
78
|
},
|
|
79
79
|
};
|
|
80
80
|
}
|
|
81
|
+
export function outputSourceSuffix(source) {
|
|
82
|
+
return source === "override" ? " (overridden)" : source === "cache" ? " (cached)" : "";
|
|
83
|
+
}
|
|
81
84
|
/** Create concise, append-only lifecycle logging for a pipeline run. */
|
|
82
85
|
export function createRunReporter(options) {
|
|
83
86
|
const { log } = options;
|
|
@@ -89,8 +92,7 @@ export function createRunReporter(options) {
|
|
|
89
92
|
const lastProgressMessage = new Map();
|
|
90
93
|
const progressLogIntervalMs = 750;
|
|
91
94
|
const ellipsis = unicodeEnabled ? "…" : "...";
|
|
92
|
-
const displayName = (step) => safeTerminalText(step.name ?? step.id) +
|
|
93
|
-
(step.outputSource === "override" ? " (overridden)" : "");
|
|
95
|
+
const displayName = (step) => safeTerminalText(step.name ?? step.id) + outputSourceSuffix(step.outputSource);
|
|
94
96
|
const clearProgress = (stepId) => {
|
|
95
97
|
lastProgressLogAt.delete(stepId);
|
|
96
98
|
lastProgressMessage.delete(stepId);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/reporter/reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PipelineHooks, PipelineLogger } from \"../core/pipeline.js\";\nimport { hasVisibleStepProgress } from \"../core/progress.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\n/** Policy for ANSI color in terminal reporter output. */\nexport type ReporterColorMode = \"always\" | \"auto\" | \"never\";\n/** Symbol set used for step lifecycle markers in reporter output. */\nexport type ReporterSymbolMode = \"ascii\" | \"auto\" | \"emoji\" | \"unicode\";\n\n/** Detected or caller-overridden terminal rendering capabilities. */\nexport interface ReporterTerminalCapabilities {\n color: boolean;\n isTTY: boolean;\n unicode: boolean;\n}\n\n/** Presentation settings shared by plain and interactive pipeline reporters. */\nexport interface RunReporterConfig {\n /** Defaults to auto: color only when the output supports it. */\n color?: ReporterColorMode;\n /** Defaults to auto: Unicode in capable terminals, ASCII elsewhere. */\n symbols?: ReporterSymbolMode;\n /** Override detected capabilities, primarily for custom streams and tests. */\n terminal?: Partial<ReporterTerminalCapabilities>;\n /** Log the pipeline start summary. Defaults to true. */\n logPlan?: boolean;\n /** Log the final pipeline summary. Defaults to true. */\n logSummary?: boolean;\n}\n\nexport interface RunReporterOptions extends RunReporterConfig {\n log: PipelineLogger;\n}\n\nexport interface ReporterSymbols {\n complete: string;\n fail: string;\n pending: string;\n skip: string;\n start: string;\n}\n\nconst SYMBOLS = {\n ascii: { complete: \"ok\", fail: \"fail\", pending: \".\", skip: \"-\", start: \"->\" },\n // Distinct from pending (○): skipped work uses a yellow dash, not a green check.\n unicode: { complete: \"✓\", fail: \"✗\", pending: \"○\", skip: \"–\", start: \"→\" },\n emoji: { complete: \"✅\", fail: \"❌\", pending: \"▫️\", skip: \"⏭️\", start: \"⏳\" },\n} satisfies Record<Exclude<ReporterSymbolMode, \"auto\">, ReporterSymbols>;\n\nconst ANSI = {\n boldCyan: \"\\u001B[1;36m\",\n cyan: \"\\u001B[36m\",\n dim: \"\\u001B[2m\",\n green: \"\\u001B[32m\",\n red: \"\\u001B[31m\",\n reset: \"\\u001B[0m\",\n yellow: \"\\u001B[33m\",\n} as const;\n\nfunction detectTerminalCapabilities(\n overrides: Partial<ReporterTerminalCapabilities> = {}\n): ReporterTerminalCapabilities {\n const isTTY = overrides.isTTY ?? process.stdout.isTTY === true;\n const termIsDumb = process.env.TERM === \"dumb\";\n const forceColor = process.env.FORCE_COLOR;\n const autoColor =\n forceColor !== undefined\n ? forceColor !== \"0\"\n : process.env.NO_COLOR === undefined && isTTY && !termIsDumb;\n return {\n isTTY,\n color: overrides.color ?? autoColor,\n unicode: overrides.unicode ?? (isTTY && !termIsDumb),\n };\n}\n\nfunction resolveColorEnabled(\n mode: ReporterColorMode,\n capabilities: ReporterTerminalCapabilities\n): boolean {\n if (mode === \"always\") return true;\n if (mode === \"never\") return false;\n return capabilities.color;\n}\n\nfunction resolveSymbols(\n mode: ReporterSymbolMode,\n capabilities: ReporterTerminalCapabilities\n): ReporterSymbols {\n return SYMBOLS[mode === \"auto\" ? (capabilities.unicode ? \"unicode\" : \"ascii\") : mode];\n}\n\nfunction paint(enabled: boolean, code: string, value: string): string {\n return enabled ? `${code}${value}${ANSI.reset}` : value;\n}\n\nexport function formatDurationMs(durationMs: number): string {\n const ms = Math.max(0, Math.round(durationMs));\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) {\n const seconds = Math.round(ms / 100) / 10;\n if (seconds < 60) {\n return Number.isInteger(seconds) ? `${seconds}s` : `${seconds.toFixed(1)}s`;\n }\n }\n const totalSeconds = Math.round(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return seconds === 0 ? `${minutes}m` : `${minutes}m${seconds}s`;\n}\n\nexport interface ReporterTheme {\n capabilities: ReporterTerminalCapabilities;\n colorEnabled: boolean;\n styled: {\n complete(value: string): string;\n description(value: string): string;\n duration(value: string): string;\n fail(value: string): string;\n pipeline(value: string): string;\n skip(value: string): string;\n start(value: string): string;\n };\n symbols: ReporterSymbols;\n unicodeEnabled: boolean;\n}\n\nexport function createReporterTheme(config: RunReporterConfig = {}): ReporterTheme {\n const capabilities = detectTerminalCapabilities(config.terminal);\n const colorEnabled = resolveColorEnabled(config.color ?? \"auto\", capabilities);\n const symbolMode = config.symbols ?? \"auto\";\n const symbols = resolveSymbols(symbolMode, capabilities);\n const unicodeEnabled = symbolMode === \"auto\" ? capabilities.unicode : symbolMode !== \"ascii\";\n return {\n capabilities,\n colorEnabled,\n symbols,\n unicodeEnabled,\n styled: {\n complete: (value) => paint(colorEnabled, ANSI.green, value),\n description: (value) => paint(colorEnabled, ANSI.dim, value),\n duration: (value) => paint(colorEnabled, ANSI.dim, value),\n fail: (value) => paint(colorEnabled, ANSI.red, value),\n pipeline: (value) => paint(colorEnabled, ANSI.boldCyan, value),\n skip: (value) => paint(colorEnabled, ANSI.yellow, value),\n start: (value) => paint(colorEnabled, ANSI.cyan, value),\n },\n };\n}\n\n/** Create concise, append-only lifecycle logging for a pipeline run. */\nexport function createRunReporter<TResult = unknown>(\n options: RunReporterOptions\n): PipelineHooks<TResult> {\n const { log } = options;\n const logPlan = options.logPlan !== false;\n const logSummary = options.logSummary !== false;\n const { styled, symbols, unicodeEnabled } = createReporterTheme(options);\n // Throttle progress lines so concurrent mapped children stay readable.\n const lastProgressLogAt = new Map<string, number>();\n const lastProgressMessage = new Map<string, string>();\n const progressLogIntervalMs = 750;\n const ellipsis = unicodeEnabled ? \"…\" : \"...\";\n const displayName = (step: { id: string; name?: string; outputSource?: \"override\" }): string =>\n safeTerminalText(step.name ?? step.id) +\n (step.outputSource === \"override\" ? \" (overridden)\" : \"\");\n const clearProgress = (stepId: string): void => {\n lastProgressLogAt.delete(stepId);\n lastProgressMessage.delete(stepId);\n };\n\n return {\n onPipelineStart: (plan) => {\n if (!logPlan) return;\n log.log(\n styled.pipeline(\n `Pipeline ${safeTerminalText(plan.pipelineId)}: starting (${plan.steps.length} steps, dryRun=${plan.dryRun})`\n )\n );\n },\n onStepStart: ({ step, outputSource }) => {\n const description = step.description\n ? ` - ${styled.description(safeTerminalText(step.description))}`\n : \"\";\n log.log(\n ` ${styled.start(symbols.start)} ${displayName({ ...step, outputSource })}${description}`\n );\n },\n onStepProgress: ({ progress, step }) => {\n // Ignore empty/non-visible progress snapshots (no message, total, or work count).\n if (!hasVisibleStepProgress(progress)) return;\n\n const total =\n progress.total !== undefined && Number.isFinite(progress.total)\n ? String(progress.total)\n : \"?\";\n const message = progress.message ? ` ${safeTerminalText(progress.message)}` : \"\";\n const line = `${progress.completed}/${total}${message}`;\n const now = Date.now();\n const previousAt = lastProgressLogAt.get(step.id) ?? Number.NEGATIVE_INFINITY;\n const previousLine = lastProgressMessage.get(step.id);\n const isCompletion =\n progress.total !== undefined &&\n Number.isFinite(progress.total) &&\n progress.completed >= progress.total;\n if (!isCompletion && line === previousLine && now - previousAt < progressLogIntervalMs) {\n return;\n }\n if (!isCompletion && now - previousAt < progressLogIntervalMs && previousLine !== undefined) {\n return;\n }\n lastProgressLogAt.set(step.id, now);\n lastProgressMessage.set(step.id, line);\n log.log(` ${styled.description(ellipsis)} ${displayName(step)} ${styled.description(line)}`);\n },\n onStepComplete: (event) => {\n clearProgress(event.id);\n const durationMs = event.finishedAtMs - event.startedAtMs;\n log.log(\n ` ${styled.complete(symbols.complete)} ${displayName(event)} ${styled.duration(`(${formatDurationMs(durationMs)})`)}`\n );\n },\n onStepSkip: (event) => {\n clearProgress(event.id);\n const detail = safeTerminalText(\n event.dependencyId\n ? `${event.reason}: ${event.dependencyId}`\n : (event.message ?? event.reason)\n );\n log.log(\n ` ${styled.skip(symbols.skip)} ${displayName(event)} ${styled.duration(`(${detail})`)}`\n );\n },\n onStepCancel: (event) => {\n clearProgress(event.id);\n log.warn(\n ` ${styled.skip(symbols.skip)} ${displayName(event)}: cancelled: ${safeTerminalText(event.error.message)}`\n );\n },\n onStepFail: (event) => {\n clearProgress(event.id);\n log.error(\n ` ${styled.fail(symbols.fail)} ${displayName(event)}: ${safeTerminalText(event.error.message)}`\n );\n },\n onFinalizeStart: () => {\n log.log(` ${styled.start(symbols.start)} finalize`);\n },\n onFinalizeComplete: ({ durationMs }) => {\n log.log(\n ` ${styled.complete(symbols.complete)} finalize ${styled.duration(`(${formatDurationMs(durationMs)})`)}`\n );\n },\n onFinalizeError: ({ error }) => {\n log.error(` ${styled.fail(symbols.fail)} finalize: ${safeTerminalText(error.message)}`);\n },\n onPipelineComplete: (result) => {\n if (!logSummary) return;\n const durationMs = result.finishedAtMs - result.startedAtMs;\n const message = `Pipeline ${safeTerminalText(result.pipelineId)}: done in ${formatDurationMs(durationMs)} (status=${result.status}, steps=${result.steps.length}, errors=${result.errors.length})`;\n if (result.status === \"completed\") {\n log.log(styled.complete(message));\n } else {\n log.error(styled.fail(message));\n }\n },\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/reporter/reporter.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PipelineHooks, PipelineLogger } from \"../core/pipeline.js\";\nimport { hasVisibleStepProgress } from \"../core/progress.js\";\nimport { safeTerminalText } from \"./terminal-text.js\";\n\n/** Policy for ANSI color in terminal reporter output. */\nexport type ReporterColorMode = \"always\" | \"auto\" | \"never\";\n/** Symbol set used for step lifecycle markers in reporter output. */\nexport type ReporterSymbolMode = \"ascii\" | \"auto\" | \"emoji\" | \"unicode\";\n\n/** Detected or caller-overridden terminal rendering capabilities. */\nexport interface ReporterTerminalCapabilities {\n color: boolean;\n isTTY: boolean;\n unicode: boolean;\n}\n\n/** Presentation settings shared by plain and interactive pipeline reporters. */\nexport interface RunReporterConfig {\n /** Defaults to auto: color only when the output supports it. */\n color?: ReporterColorMode;\n /** Defaults to auto: Unicode in capable terminals, ASCII elsewhere. */\n symbols?: ReporterSymbolMode;\n /** Override detected capabilities, primarily for custom streams and tests. */\n terminal?: Partial<ReporterTerminalCapabilities>;\n /** Log the pipeline start summary. Defaults to true. */\n logPlan?: boolean;\n /** Log the final pipeline summary. Defaults to true. */\n logSummary?: boolean;\n}\n\nexport interface RunReporterOptions extends RunReporterConfig {\n log: PipelineLogger;\n}\n\nexport interface ReporterSymbols {\n complete: string;\n fail: string;\n pending: string;\n skip: string;\n start: string;\n}\n\nconst SYMBOLS = {\n ascii: { complete: \"ok\", fail: \"fail\", pending: \".\", skip: \"-\", start: \"->\" },\n // Distinct from pending (○): skipped work uses a yellow dash, not a green check.\n unicode: { complete: \"✓\", fail: \"✗\", pending: \"○\", skip: \"–\", start: \"→\" },\n emoji: { complete: \"✅\", fail: \"❌\", pending: \"▫️\", skip: \"⏭️\", start: \"⏳\" },\n} satisfies Record<Exclude<ReporterSymbolMode, \"auto\">, ReporterSymbols>;\n\nconst ANSI = {\n boldCyan: \"\\u001B[1;36m\",\n cyan: \"\\u001B[36m\",\n dim: \"\\u001B[2m\",\n green: \"\\u001B[32m\",\n red: \"\\u001B[31m\",\n reset: \"\\u001B[0m\",\n yellow: \"\\u001B[33m\",\n} as const;\n\nfunction detectTerminalCapabilities(\n overrides: Partial<ReporterTerminalCapabilities> = {}\n): ReporterTerminalCapabilities {\n const isTTY = overrides.isTTY ?? process.stdout.isTTY === true;\n const termIsDumb = process.env.TERM === \"dumb\";\n const forceColor = process.env.FORCE_COLOR;\n const autoColor =\n forceColor !== undefined\n ? forceColor !== \"0\"\n : process.env.NO_COLOR === undefined && isTTY && !termIsDumb;\n return {\n isTTY,\n color: overrides.color ?? autoColor,\n unicode: overrides.unicode ?? (isTTY && !termIsDumb),\n };\n}\n\nfunction resolveColorEnabled(\n mode: ReporterColorMode,\n capabilities: ReporterTerminalCapabilities\n): boolean {\n if (mode === \"always\") return true;\n if (mode === \"never\") return false;\n return capabilities.color;\n}\n\nfunction resolveSymbols(\n mode: ReporterSymbolMode,\n capabilities: ReporterTerminalCapabilities\n): ReporterSymbols {\n return SYMBOLS[mode === \"auto\" ? (capabilities.unicode ? \"unicode\" : \"ascii\") : mode];\n}\n\nfunction paint(enabled: boolean, code: string, value: string): string {\n return enabled ? `${code}${value}${ANSI.reset}` : value;\n}\n\nexport function formatDurationMs(durationMs: number): string {\n const ms = Math.max(0, Math.round(durationMs));\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) {\n const seconds = Math.round(ms / 100) / 10;\n if (seconds < 60) {\n return Number.isInteger(seconds) ? `${seconds}s` : `${seconds.toFixed(1)}s`;\n }\n }\n const totalSeconds = Math.round(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return seconds === 0 ? `${minutes}m` : `${minutes}m${seconds}s`;\n}\n\nexport interface ReporterTheme {\n capabilities: ReporterTerminalCapabilities;\n colorEnabled: boolean;\n styled: {\n complete(value: string): string;\n description(value: string): string;\n duration(value: string): string;\n fail(value: string): string;\n pipeline(value: string): string;\n skip(value: string): string;\n start(value: string): string;\n };\n symbols: ReporterSymbols;\n unicodeEnabled: boolean;\n}\n\nexport function createReporterTheme(config: RunReporterConfig = {}): ReporterTheme {\n const capabilities = detectTerminalCapabilities(config.terminal);\n const colorEnabled = resolveColorEnabled(config.color ?? \"auto\", capabilities);\n const symbolMode = config.symbols ?? \"auto\";\n const symbols = resolveSymbols(symbolMode, capabilities);\n const unicodeEnabled = symbolMode === \"auto\" ? capabilities.unicode : symbolMode !== \"ascii\";\n return {\n capabilities,\n colorEnabled,\n symbols,\n unicodeEnabled,\n styled: {\n complete: (value) => paint(colorEnabled, ANSI.green, value),\n description: (value) => paint(colorEnabled, ANSI.dim, value),\n duration: (value) => paint(colorEnabled, ANSI.dim, value),\n fail: (value) => paint(colorEnabled, ANSI.red, value),\n pipeline: (value) => paint(colorEnabled, ANSI.boldCyan, value),\n skip: (value) => paint(colorEnabled, ANSI.yellow, value),\n start: (value) => paint(colorEnabled, ANSI.cyan, value),\n },\n };\n}\n\nexport function outputSourceSuffix(source?: \"override\" | \"cache\"): string {\n return source === \"override\" ? \" (overridden)\" : source === \"cache\" ? \" (cached)\" : \"\";\n}\n\n/** Create concise, append-only lifecycle logging for a pipeline run. */\nexport function createRunReporter<TResult = unknown>(\n options: RunReporterOptions\n): PipelineHooks<TResult> {\n const { log } = options;\n const logPlan = options.logPlan !== false;\n const logSummary = options.logSummary !== false;\n const { styled, symbols, unicodeEnabled } = createReporterTheme(options);\n // Throttle progress lines so concurrent mapped children stay readable.\n const lastProgressLogAt = new Map<string, number>();\n const lastProgressMessage = new Map<string, string>();\n const progressLogIntervalMs = 750;\n const ellipsis = unicodeEnabled ? \"…\" : \"...\";\n const displayName = (step: {\n id: string;\n name?: string;\n outputSource?: \"override\" | \"cache\";\n }): string => safeTerminalText(step.name ?? step.id) + outputSourceSuffix(step.outputSource);\n const clearProgress = (stepId: string): void => {\n lastProgressLogAt.delete(stepId);\n lastProgressMessage.delete(stepId);\n };\n\n return {\n onPipelineStart: (plan) => {\n if (!logPlan) return;\n log.log(\n styled.pipeline(\n `Pipeline ${safeTerminalText(plan.pipelineId)}: starting (${plan.steps.length} steps, dryRun=${plan.dryRun})`\n )\n );\n },\n onStepStart: ({ step, outputSource }) => {\n const description = step.description\n ? ` - ${styled.description(safeTerminalText(step.description))}`\n : \"\";\n log.log(\n ` ${styled.start(symbols.start)} ${displayName({ ...step, outputSource })}${description}`\n );\n },\n onStepProgress: ({ progress, step }) => {\n // Ignore empty/non-visible progress snapshots (no message, total, or work count).\n if (!hasVisibleStepProgress(progress)) return;\n\n const total =\n progress.total !== undefined && Number.isFinite(progress.total)\n ? String(progress.total)\n : \"?\";\n const message = progress.message ? ` ${safeTerminalText(progress.message)}` : \"\";\n const line = `${progress.completed}/${total}${message}`;\n const now = Date.now();\n const previousAt = lastProgressLogAt.get(step.id) ?? Number.NEGATIVE_INFINITY;\n const previousLine = lastProgressMessage.get(step.id);\n const isCompletion =\n progress.total !== undefined &&\n Number.isFinite(progress.total) &&\n progress.completed >= progress.total;\n if (!isCompletion && line === previousLine && now - previousAt < progressLogIntervalMs) {\n return;\n }\n if (!isCompletion && now - previousAt < progressLogIntervalMs && previousLine !== undefined) {\n return;\n }\n lastProgressLogAt.set(step.id, now);\n lastProgressMessage.set(step.id, line);\n log.log(` ${styled.description(ellipsis)} ${displayName(step)} ${styled.description(line)}`);\n },\n onStepComplete: (event) => {\n clearProgress(event.id);\n const durationMs = event.finishedAtMs - event.startedAtMs;\n log.log(\n ` ${styled.complete(symbols.complete)} ${displayName(event)} ${styled.duration(`(${formatDurationMs(durationMs)})`)}`\n );\n },\n onStepSkip: (event) => {\n clearProgress(event.id);\n const detail = safeTerminalText(\n event.dependencyId\n ? `${event.reason}: ${event.dependencyId}`\n : (event.message ?? event.reason)\n );\n log.log(\n ` ${styled.skip(symbols.skip)} ${displayName(event)} ${styled.duration(`(${detail})`)}`\n );\n },\n onStepCancel: (event) => {\n clearProgress(event.id);\n log.warn(\n ` ${styled.skip(symbols.skip)} ${displayName(event)}: cancelled: ${safeTerminalText(event.error.message)}`\n );\n },\n onStepFail: (event) => {\n clearProgress(event.id);\n log.error(\n ` ${styled.fail(symbols.fail)} ${displayName(event)}: ${safeTerminalText(event.error.message)}`\n );\n },\n onFinalizeStart: () => {\n log.log(` ${styled.start(symbols.start)} finalize`);\n },\n onFinalizeComplete: ({ durationMs }) => {\n log.log(\n ` ${styled.complete(symbols.complete)} finalize ${styled.duration(`(${formatDurationMs(durationMs)})`)}`\n );\n },\n onFinalizeError: ({ error }) => {\n log.error(` ${styled.fail(symbols.fail)} finalize: ${safeTerminalText(error.message)}`);\n },\n onPipelineComplete: (result) => {\n if (!logSummary) return;\n const durationMs = result.finishedAtMs - result.startedAtMs;\n const message = `Pipeline ${safeTerminalText(result.pipelineId)}: done in ${formatDurationMs(durationMs)} (status=${result.status}, steps=${result.steps.length}, errors=${result.errors.length})`;\n if (result.status === \"completed\") {\n log.log(styled.complete(message));\n } else {\n log.error(styled.fail(message));\n }\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ArtifactMetadata } from "../tracing/artifact-metadata.js";
|
|
2
|
+
/** Read the reserved cache receipt namespace without treating arbitrary metadata as cache data. */
|
|
3
|
+
export declare function cacheArtifactMetadata(artifact: ArtifactMetadata): {
|
|
4
|
+
implementationVersion: string;
|
|
5
|
+
createdAtMs: number;
|
|
6
|
+
ageMs: number;
|
|
7
|
+
} | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/** Read the reserved cache receipt namespace without treating arbitrary metadata as cache data. */
|
|
2
|
+
export function cacheArtifactMetadata(artifact) {
|
|
3
|
+
const cache = artifact.metadata?.tubelessCache;
|
|
4
|
+
if (!cache ||
|
|
5
|
+
typeof cache !== "object" ||
|
|
6
|
+
Array.isArray(cache) ||
|
|
7
|
+
!("implementationVersion" in cache) ||
|
|
8
|
+
typeof cache.implementationVersion !== "string" ||
|
|
9
|
+
!("createdAtMs" in cache) ||
|
|
10
|
+
typeof cache.createdAtMs !== "number" ||
|
|
11
|
+
!Number.isFinite(cache.createdAtMs) ||
|
|
12
|
+
!("ageMs" in cache) ||
|
|
13
|
+
typeof cache.ageMs !== "number" ||
|
|
14
|
+
!Number.isFinite(cache.ageMs))
|
|
15
|
+
return undefined;
|
|
16
|
+
return {
|
|
17
|
+
implementationVersion: cache.implementationVersion,
|
|
18
|
+
createdAtMs: cache.createdAtMs,
|
|
19
|
+
ageMs: cache.ageMs,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=cache-artifact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache-artifact.js","sourceRoot":"","sources":["../../src/run-store/cache-artifact.ts"],"names":[],"mappings":"AAEA,mGAAmG;AACnG,MAAM,UAAU,qBAAqB,CAAC,QAA0B;IAC9D,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IAC/C,IACE,CAAC,KAAK;QACN,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACpB,CAAC,CAAC,uBAAuB,IAAI,KAAK,CAAC;QACnC,OAAO,KAAK,CAAC,qBAAqB,KAAK,QAAQ;QAC/C,CAAC,CAAC,aAAa,IAAI,KAAK,CAAC;QACzB,OAAO,KAAK,CAAC,WAAW,KAAK,QAAQ;QACrC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC;QACnC,CAAC,CAAC,OAAO,IAAI,KAAK,CAAC;QACnB,OAAO,KAAK,CAAC,KAAK,KAAK,QAAQ;QAC/B,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC;QAE7B,OAAO,SAAS,CAAC;IACnB,OAAO;QACL,qBAAqB,EAAE,KAAK,CAAC,qBAAqB;QAClD,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,KAAK,EAAE,KAAK,CAAC,KAAK;KACnB,CAAC;AACJ,CAAC","sourcesContent":["import type { ArtifactMetadata } from \"../tracing/artifact-metadata.js\";\n\n/** Read the reserved cache receipt namespace without treating arbitrary metadata as cache data. */\nexport function cacheArtifactMetadata(artifact: ArtifactMetadata) {\n const cache = artifact.metadata?.tubelessCache;\n if (\n !cache ||\n typeof cache !== \"object\" ||\n Array.isArray(cache) ||\n !(\"implementationVersion\" in cache) ||\n typeof cache.implementationVersion !== \"string\" ||\n !(\"createdAtMs\" in cache) ||\n typeof cache.createdAtMs !== \"number\" ||\n !Number.isFinite(cache.createdAtMs) ||\n !(\"ageMs\" in cache) ||\n typeof cache.ageMs !== \"number\" ||\n !Number.isFinite(cache.ageMs)\n )\n return undefined;\n return {\n implementationVersion: cache.implementationVersion,\n createdAtMs: cache.createdAtMs,\n ageMs: cache.ageMs,\n };\n}\n"]}
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
import { canonicalJsonValue } from "../utilities/canonical-json.js";
|
|
2
|
+
// Every step semantic needs a comparison label; new snapshot fields must be handled here.
|
|
3
|
+
const STEP_FIELDS = {
|
|
4
|
+
dependencies: "Required edges",
|
|
5
|
+
optionalDependencies: "Optional edges",
|
|
6
|
+
skipAfterFailureOf: "Failure gates",
|
|
7
|
+
dryRun: "Dry-run policy",
|
|
8
|
+
runtimeSkipPossible: "Skip policy",
|
|
9
|
+
outputValidated: "Output validation",
|
|
10
|
+
cache: "Cache settings",
|
|
11
|
+
nestedPipeline: "Child pipeline",
|
|
12
|
+
remote: "Remote adapter",
|
|
13
|
+
};
|
|
1
14
|
/** Compare complete recorded semantics, without loading the application's modules. */
|
|
2
15
|
export function compareDefinitions(before, after) {
|
|
3
16
|
const changes = [];
|
|
@@ -9,6 +22,7 @@ export function compareDefinitions(before, after) {
|
|
|
9
22
|
};
|
|
10
23
|
compare("Implementation version", before.identity.implementationVersion, after.identity.implementationVersion);
|
|
11
24
|
compare("Execution order", before.steps.map(({ id }) => id), after.steps.map(({ id }) => id));
|
|
25
|
+
compare("Metadata", canonicalJsonValue(before.metadata), canonicalJsonValue(after.metadata));
|
|
12
26
|
compare("Targets", before.targetIds, after.targetIds);
|
|
13
27
|
compare("Required finalizer steps", before.requiredFinalizerStepIds, after.requiredFinalizerStepIds);
|
|
14
28
|
compare("Options validation", before.optionsValidated, after.optionsValidated);
|
|
@@ -25,14 +39,12 @@ export function compareDefinitions(before, after) {
|
|
|
25
39
|
changes.push({ stepId: step.id, field: "Added step" });
|
|
26
40
|
continue;
|
|
27
41
|
}
|
|
28
|
-
compare("
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
compare("Child pipeline", old.nestedPipeline, step.nestedPipeline, step.id);
|
|
35
|
-
compare("Remote adapter", old.remote, step.remote, step.id);
|
|
42
|
+
compare("Metadata", canonicalJsonValue(old.metadata), canonicalJsonValue(step.metadata), step.id);
|
|
43
|
+
for (const field of Object.keys(STEP_FIELDS)) {
|
|
44
|
+
// SAFETY: keys come from the exhaustive, locally authored field map above.
|
|
45
|
+
const key = field;
|
|
46
|
+
compare(STEP_FIELDS[key], old[key], step[key], step.id);
|
|
47
|
+
}
|
|
36
48
|
}
|
|
37
49
|
return changes;
|
|
38
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definition-diff.js","sourceRoot":"","sources":["../../src/run-store/definition-diff.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"definition-diff.js","sourceRoot":"","sources":["../../src/run-store/definition-diff.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AAUpE,0FAA0F;AAC1F,MAAM,WAAW,GAAG;IAClB,YAAY,EAAE,gBAAgB;IAC9B,oBAAoB,EAAE,gBAAgB;IACtC,kBAAkB,EAAE,eAAe;IACnC,MAAM,EAAE,gBAAgB;IACxB,mBAAmB,EAAE,aAAa;IAClC,eAAe,EAAE,mBAAmB;IACpC,KAAK,EAAE,gBAAgB;IACvB,cAAc,EAAE,gBAAgB;IAChC,MAAM,EAAE,gBAAgB;CAIzB,CAAC;AAEF,sFAAsF;AACtF,MAAM,UAAU,kBAAkB,CAChC,MAAkC,EAClC,KAAiC;IAEjC,MAAM,OAAO,GAAuB,EAAE,CAAC;IACvC,MAAM,OAAO,GAAG,CAAC,KAAa,EAAE,IAAa,EAAE,KAAc,EAAE,MAAe,EAAE,EAAE;QAChF,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAC/B,MAAM,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QAChC,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC,CAAC;IACF,OAAO,CACL,wBAAwB,EACxB,MAAM,CAAC,QAAQ,CAAC,qBAAqB,EACrC,KAAK,CAAC,QAAQ,CAAC,qBAAqB,CACrC,CAAC;IACF,OAAO,CACL,iBAAiB,EACjB,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAChC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAChC,CAAC;IACF,OAAO,CAAC,UAAU,EAAE,kBAAkB,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC7F,OAAO,CAAC,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IACtD,OAAO,CACL,0BAA0B,EAC1B,MAAM,CAAC,wBAAwB,EAC/B,KAAK,CAAC,wBAAwB,CAC/B,CAAC;IACF,OAAO,CAAC,oBAAoB,EAAE,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAC/E,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,eAAe,EAAE,KAAK,CAAC,eAAe,CAAC,CAAC;IAC5E,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACtE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;IACjE,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;IACnF,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QACD,OAAO,CACL,UAAU,EACV,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAChC,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,EACjC,IAAI,CAAC,EAAE,CACR,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7C,2EAA2E;YAC3E,MAAM,GAAG,GAAG,KAAiC,CAAC;YAC9C,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC","sourcesContent":["import { canonicalJsonValue } from \"../utilities/canonical-json.js\";\nimport type { PipelineDefinitionSnapshot } from \"../core/pipeline.js\";\n\nexport interface DefinitionChange {\n stepId?: string;\n field: string;\n before?: string;\n after?: string;\n}\n\n// Every step semantic needs a comparison label; new snapshot fields must be handled here.\nconst STEP_FIELDS = {\n dependencies: \"Required edges\",\n optionalDependencies: \"Optional edges\",\n skipAfterFailureOf: \"Failure gates\",\n dryRun: \"Dry-run policy\",\n runtimeSkipPossible: \"Skip policy\",\n outputValidated: \"Output validation\",\n cache: \"Cache settings\",\n nestedPipeline: \"Child pipeline\",\n remote: \"Remote adapter\",\n} satisfies Record<\n Exclude<keyof PipelineDefinitionSnapshot[\"steps\"][number], \"id\" | \"metadata\">,\n string\n>;\n\n/** Compare complete recorded semantics, without loading the application's modules. */\nexport function compareDefinitions(\n before: PipelineDefinitionSnapshot,\n after: PipelineDefinitionSnapshot\n): DefinitionChange[] {\n const changes: DefinitionChange[] = [];\n const compare = (field: string, left: unknown, right: unknown, stepId?: string) => {\n const a = JSON.stringify(left);\n const b = JSON.stringify(right);\n if (a !== b) changes.push({ field, before: a, after: b, ...(stepId ? { stepId } : {}) });\n };\n compare(\n \"Implementation version\",\n before.identity.implementationVersion,\n after.identity.implementationVersion\n );\n compare(\n \"Execution order\",\n before.steps.map(({ id }) => id),\n after.steps.map(({ id }) => id)\n );\n compare(\"Metadata\", canonicalJsonValue(before.metadata), canonicalJsonValue(after.metadata));\n compare(\"Targets\", before.targetIds, after.targetIds);\n compare(\n \"Required finalizer steps\",\n before.requiredFinalizerStepIds,\n after.requiredFinalizerStepIds\n );\n compare(\"Options validation\", before.optionsValidated, after.optionsValidated);\n compare(\"Result validation\", before.resultValidated, after.resultValidated);\n const previous = new Map(before.steps.map((step) => [step.id, step]));\n const next = new Map(after.steps.map((step) => [step.id, step]));\n for (const step of before.steps) {\n if (!next.has(step.id)) changes.push({ stepId: step.id, field: \"Removed step\" });\n }\n for (const step of after.steps) {\n const old = previous.get(step.id);\n if (!old) {\n changes.push({ stepId: step.id, field: \"Added step\" });\n continue;\n }\n compare(\n \"Metadata\",\n canonicalJsonValue(old.metadata),\n canonicalJsonValue(step.metadata),\n step.id\n );\n for (const field of Object.keys(STEP_FIELDS)) {\n // SAFETY: keys come from the exhaustive, locally authored field map above.\n const key = field as keyof typeof STEP_FIELDS;\n compare(STEP_FIELDS[key], old[key], step[key], step.id);\n }\n }\n return changes;\n}\n"]}
|
|
@@ -111,8 +111,8 @@ export class RunProjection {
|
|
|
111
111
|
});
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
|
-
if ("outputSource" in event.payload && event.payload.outputSource
|
|
115
|
-
step.outputSource =
|
|
114
|
+
if ("outputSource" in event.payload && event.payload.outputSource) {
|
|
115
|
+
step.outputSource = event.payload.outputSource;
|
|
116
116
|
}
|
|
117
117
|
if (event.attemptId) {
|
|
118
118
|
let attempt = step.attempt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-projection.js","sourceRoot":"","sources":["../../src/run-store/run-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PipelineDefinitionIdentity } from \"../core/pipeline-types.js\";\nimport type { PipelineTraceError } from \"../tracing/tracing-contracts.js\";\nimport { RUN_MODEL_VERSION } from \"../core/pipeline-ids.js\";\nimport { hasVisibleStepProgress } from \"../core/progress.js\";\nimport type {\n StoredPipelineEvent,\n StoredPipelineRun,\n StoredPipelineRunStatus,\n StoredPipelineStep,\n StoredPipelineAttempt,\n StoredPipelineLog,\n} from \"./run-store.js\";\n\nfunction terminalStepStatus(event: StoredPipelineEvent): StoredPipelineStep[\"status\"] | undefined {\n switch (event.name) {\n case \"step.cancelled\":\n return \"cancelled\";\n case \"step.complete\":\n // Shipped trace name; projected snapshot uses the live success token.\n return \"completed\";\n case \"step.failed\":\n return \"failed\";\n case \"step.skipped\":\n return \"skipped\";\n default:\n return undefined;\n }\n}\n\nfunction attemptStatus(status: StoredPipelineStep[\"status\"]): StoredPipelineAttempt[\"status\"] {\n return status === \"planned\" ? \"running\" : status;\n}\n\n/** Own the mutable state of one recorded run. */\nexport class RunProjection {\n #completed:\n | {\n status: StoredPipelineRunStatus;\n timestampMs: number;\n durationMs?: number;\n error?: PipelineTraceError;\n }\n | undefined;\n #eventCount = 0;\n readonly #identity: Pick<\n StoredPipelineEvent,\n \"pipelineId\" | \"runId\" | \"correlationId\" | \"parentRunId\" | \"iteration\"\n >;\n #logCount = 0;\n readonly #logs: StoredPipelineLog[] = [];\n #startedAtMs: number;\n #startObserved = false;\n #dryRun = false;\n #definitionIdentity: PipelineDefinitionIdentity | undefined;\n readonly #steps = new Map<string, StoredPipelineStep>();\n\n constructor(\n event: StoredPipelineEvent,\n private readonly options: {\n readonly retainLogs?: boolean;\n readonly retainArtifacts?: boolean;\n } = {}\n ) {\n this.#identity = {\n pipelineId: event.pipelineId,\n runId: event.runId,\n correlationId: event.correlationId,\n parentRunId: event.parentRunId,\n iteration: event.iteration ? { ...event.iteration } : undefined,\n };\n this.#startedAtMs = event.timestampMs;\n this.append(event);\n }\n\n get definitionId(): string | undefined {\n return this.#definitionIdentity?.definitionId;\n }\n\n append(event: StoredPipelineEvent): void {\n this.#eventCount += 1;\n if (event.name === \"pipeline.started\" && !this.#startObserved) {\n this.#startObserved = true;\n this.#startedAtMs = event.timestampMs;\n this.#dryRun = event.payload.dryRun;\n this.#definitionIdentity = event.payload.definitionIdentity\n ? { ...event.payload.definitionIdentity }\n : undefined;\n }\n if (event.name === \"pipeline.completed\") {\n this.#completed = {\n status: event.payload.status,\n timestampMs: event.timestampMs,\n durationMs: event.durationMs,\n error: event.error ? structuredClone(event.error) : undefined,\n };\n }\n if (event.name === \"pipeline.log\") {\n this.#logCount += 1;\n if (this.options.retainLogs === false) return;\n const log: StoredPipelineLog = {\n id: event.id,\n level: event.payload.level,\n message: event.payload.message,\n timestampMs: event.timestampMs,\n };\n if (event.attemptId) log.attemptId = event.attemptId;\n if (event.stepId) log.stepId = event.stepId;\n this.#logs.push(log);\n return;\n }\n if (!event.stepId || !event.name.startsWith(\"step.\")) return;\n\n let step = this.#steps.get(event.stepId);\n if (!step) {\n step = { id: event.stepId, status: \"planned\" };\n this.#steps.set(event.stepId, step);\n }\n if (event.name === \"step.planned\") {\n step.name = event.payload.name;\n step.description = event.payload.description;\n if (event.payload.nestedPipeline) {\n step.nestedPipeline = {\n ...event.payload.nestedPipeline,\n stepIds: [...event.payload.nestedPipeline.stepIds],\n };\n }\n if (event.payload.remote) step.remote = { ...event.payload.remote };\n return;\n }\n if (event.name === \"step.artifact\") {\n if (this.options.retainArtifacts === false) return;\n (step.artifacts ??= []).push({\n ...structuredClone(event.payload),\n attemptId: event.attemptId,\n timestampMs: event.timestampMs,\n });\n return;\n }\n if (\"outputSource\" in event.payload && event.payload.outputSource === \"override\") {\n step.outputSource = \"override\";\n }\n if (event.attemptId) {\n let attempt = step.attempt;\n if (!attempt) {\n attempt = {\n attemptId: event.attemptId,\n retries: [],\n startedAtMs: event.timestampMs,\n status: \"running\",\n };\n step.attempt = attempt;\n }\n if (step.outputSource) attempt.outputSource = step.outputSource;\n if (event.name === \"step.attempted\") {\n attempt.retries.push(event.payload.attempt);\n }\n const terminal = terminalStepStatus(event);\n if (terminal) {\n attempt.status = attemptStatus(terminal);\n attempt.finishedAtMs = event.timestampMs;\n attempt.durationMs = event.durationMs;\n }\n }\n if (event.name === \"step.running\") {\n step.status = \"running\";\n step.startedAtMs ??= event.timestampMs;\n if (event.payload.progress) {\n const progress: StoredPipelineStep[\"progress\"] = {\n ...event.payload.progress,\n details: event.payload.progress.details?.map((detail) => ({ ...detail })),\n };\n if (!step.progress || hasVisibleStepProgress(progress)) step.progress = progress;\n }\n return;\n }\n const terminal = terminalStepStatus(event);\n if (terminal) {\n step.status = terminal;\n step.finishedAtMs = event.timestampMs;\n step.durationMs = event.durationMs;\n if (event.durationMs !== undefined) step.startedAtMs = event.timestampMs - event.durationMs;\n }\n }\n\n snapshot(): StoredPipelineRun {\n const completed = this.#completed;\n const run: StoredPipelineRun = {\n dryRun: this.#dryRun,\n eventCount: this.#eventCount,\n logCount: this.#logCount,\n logs: this.options.retainLogs === false ? [] : this.#logs.map((log) => ({ ...log })),\n pipelineId: this.#identity.pipelineId,\n runId: this.#identity.runId,\n startedAtMs: this.#startedAtMs,\n status: completed?.status ?? \"running\",\n steps: [...this.#steps.values()].map((step) => structuredClone(step)),\n version: RUN_MODEL_VERSION,\n };\n if (this.#definitionIdentity) run.definitionIdentity = { ...this.#definitionIdentity };\n if (this.#identity.correlationId !== undefined)\n run.correlationId = this.#identity.correlationId;\n if (completed?.durationMs !== undefined) run.durationMs = completed.durationMs;\n if (completed?.error) run.error = structuredClone(completed.error);\n if (completed) run.finishedAtMs = completed.timestampMs;\n if (this.#identity.parentRunId) run.parentRunId = this.#identity.parentRunId;\n if (this.#identity.iteration) run.iteration = { ...this.#identity.iteration };\n return run;\n }\n}\n\n/** Fold one run's append-only events into a UI-friendly current snapshot. */\nexport function projectPipelineRun(events: readonly StoredPipelineEvent[]): StoredPipelineRun {\n if (events.length === 0) throw new Error(\"Cannot project an empty pipeline run event list.\");\n const ordered = [...events].sort((left, right) => left.id - right.id);\n const projection = new RunProjection(ordered[0]!);\n for (const event of ordered.slice(1)) projection.append(event);\n return projection.snapshot();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"run-projection.js","sourceRoot":"","sources":["../../src/run-store/run-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PipelineDefinitionIdentity } from \"../core/pipeline-types.js\";\nimport type { PipelineTraceError } from \"../tracing/tracing-contracts.js\";\nimport { RUN_MODEL_VERSION } from \"../core/pipeline-ids.js\";\nimport { hasVisibleStepProgress } from \"../core/progress.js\";\nimport type {\n StoredPipelineEvent,\n StoredPipelineRun,\n StoredPipelineRunStatus,\n StoredPipelineStep,\n StoredPipelineAttempt,\n StoredPipelineLog,\n} from \"./run-store.js\";\n\nfunction terminalStepStatus(event: StoredPipelineEvent): StoredPipelineStep[\"status\"] | undefined {\n switch (event.name) {\n case \"step.cancelled\":\n return \"cancelled\";\n case \"step.complete\":\n // Shipped trace name; projected snapshot uses the live success token.\n return \"completed\";\n case \"step.failed\":\n return \"failed\";\n case \"step.skipped\":\n return \"skipped\";\n default:\n return undefined;\n }\n}\n\nfunction attemptStatus(status: StoredPipelineStep[\"status\"]): StoredPipelineAttempt[\"status\"] {\n return status === \"planned\" ? \"running\" : status;\n}\n\n/** Own the mutable state of one recorded run. */\nexport class RunProjection {\n #completed:\n | {\n status: StoredPipelineRunStatus;\n timestampMs: number;\n durationMs?: number;\n error?: PipelineTraceError;\n }\n | undefined;\n #eventCount = 0;\n readonly #identity: Pick<\n StoredPipelineEvent,\n \"pipelineId\" | \"runId\" | \"correlationId\" | \"parentRunId\" | \"iteration\"\n >;\n #logCount = 0;\n readonly #logs: StoredPipelineLog[] = [];\n #startedAtMs: number;\n #startObserved = false;\n #dryRun = false;\n #definitionIdentity: PipelineDefinitionIdentity | undefined;\n readonly #steps = new Map<string, StoredPipelineStep>();\n\n constructor(\n event: StoredPipelineEvent,\n private readonly options: {\n readonly retainLogs?: boolean;\n readonly retainArtifacts?: boolean;\n } = {}\n ) {\n this.#identity = {\n pipelineId: event.pipelineId,\n runId: event.runId,\n correlationId: event.correlationId,\n parentRunId: event.parentRunId,\n iteration: event.iteration ? { ...event.iteration } : undefined,\n };\n this.#startedAtMs = event.timestampMs;\n this.append(event);\n }\n\n get definitionId(): string | undefined {\n return this.#definitionIdentity?.definitionId;\n }\n\n append(event: StoredPipelineEvent): void {\n this.#eventCount += 1;\n if (event.name === \"pipeline.started\" && !this.#startObserved) {\n this.#startObserved = true;\n this.#startedAtMs = event.timestampMs;\n this.#dryRun = event.payload.dryRun;\n this.#definitionIdentity = event.payload.definitionIdentity\n ? { ...event.payload.definitionIdentity }\n : undefined;\n }\n if (event.name === \"pipeline.completed\") {\n this.#completed = {\n status: event.payload.status,\n timestampMs: event.timestampMs,\n durationMs: event.durationMs,\n error: event.error ? structuredClone(event.error) : undefined,\n };\n }\n if (event.name === \"pipeline.log\") {\n this.#logCount += 1;\n if (this.options.retainLogs === false) return;\n const log: StoredPipelineLog = {\n id: event.id,\n level: event.payload.level,\n message: event.payload.message,\n timestampMs: event.timestampMs,\n };\n if (event.attemptId) log.attemptId = event.attemptId;\n if (event.stepId) log.stepId = event.stepId;\n this.#logs.push(log);\n return;\n }\n if (!event.stepId || !event.name.startsWith(\"step.\")) return;\n\n let step = this.#steps.get(event.stepId);\n if (!step) {\n step = { id: event.stepId, status: \"planned\" };\n this.#steps.set(event.stepId, step);\n }\n if (event.name === \"step.planned\") {\n step.name = event.payload.name;\n step.description = event.payload.description;\n if (event.payload.nestedPipeline) {\n step.nestedPipeline = {\n ...event.payload.nestedPipeline,\n stepIds: [...event.payload.nestedPipeline.stepIds],\n };\n }\n if (event.payload.remote) step.remote = { ...event.payload.remote };\n return;\n }\n if (event.name === \"step.artifact\") {\n if (this.options.retainArtifacts === false) return;\n (step.artifacts ??= []).push({\n ...structuredClone(event.payload),\n attemptId: event.attemptId,\n timestampMs: event.timestampMs,\n });\n return;\n }\n if (\"outputSource\" in event.payload && event.payload.outputSource) {\n step.outputSource = event.payload.outputSource;\n }\n if (event.attemptId) {\n let attempt = step.attempt;\n if (!attempt) {\n attempt = {\n attemptId: event.attemptId,\n retries: [],\n startedAtMs: event.timestampMs,\n status: \"running\",\n };\n step.attempt = attempt;\n }\n if (step.outputSource) attempt.outputSource = step.outputSource;\n if (event.name === \"step.attempted\") {\n attempt.retries.push(event.payload.attempt);\n }\n const terminal = terminalStepStatus(event);\n if (terminal) {\n attempt.status = attemptStatus(terminal);\n attempt.finishedAtMs = event.timestampMs;\n attempt.durationMs = event.durationMs;\n }\n }\n if (event.name === \"step.running\") {\n step.status = \"running\";\n step.startedAtMs ??= event.timestampMs;\n if (event.payload.progress) {\n const progress: StoredPipelineStep[\"progress\"] = {\n ...event.payload.progress,\n details: event.payload.progress.details?.map((detail) => ({ ...detail })),\n };\n if (!step.progress || hasVisibleStepProgress(progress)) step.progress = progress;\n }\n return;\n }\n const terminal = terminalStepStatus(event);\n if (terminal) {\n step.status = terminal;\n step.finishedAtMs = event.timestampMs;\n step.durationMs = event.durationMs;\n if (event.durationMs !== undefined) step.startedAtMs = event.timestampMs - event.durationMs;\n }\n }\n\n snapshot(): StoredPipelineRun {\n const completed = this.#completed;\n const run: StoredPipelineRun = {\n dryRun: this.#dryRun,\n eventCount: this.#eventCount,\n logCount: this.#logCount,\n logs: this.options.retainLogs === false ? [] : this.#logs.map((log) => ({ ...log })),\n pipelineId: this.#identity.pipelineId,\n runId: this.#identity.runId,\n startedAtMs: this.#startedAtMs,\n status: completed?.status ?? \"running\",\n steps: [...this.#steps.values()].map((step) => structuredClone(step)),\n version: RUN_MODEL_VERSION,\n };\n if (this.#definitionIdentity) run.definitionIdentity = { ...this.#definitionIdentity };\n if (this.#identity.correlationId !== undefined)\n run.correlationId = this.#identity.correlationId;\n if (completed?.durationMs !== undefined) run.durationMs = completed.durationMs;\n if (completed?.error) run.error = structuredClone(completed.error);\n if (completed) run.finishedAtMs = completed.timestampMs;\n if (this.#identity.parentRunId) run.parentRunId = this.#identity.parentRunId;\n if (this.#identity.iteration) run.iteration = { ...this.#identity.iteration };\n return run;\n }\n}\n\n/** Fold one run's append-only events into a UI-friendly current snapshot. */\nexport function projectPipelineRun(events: readonly StoredPipelineEvent[]): StoredPipelineRun {\n if (events.length === 0) throw new Error(\"Cannot project an empty pipeline run event list.\");\n const ordered = [...events].sort((left, right) => left.id - right.id);\n const projection = new RunProjection(ordered[0]!);\n for (const event of ordered.slice(1)) projection.append(event);\n return projection.snapshot();\n}\n"]}
|
|
@@ -49,7 +49,7 @@ export interface StoredPipelineLog {
|
|
|
49
49
|
timestampMs: number;
|
|
50
50
|
}
|
|
51
51
|
export interface StoredPipelineAttempt {
|
|
52
|
-
outputSource?: "override";
|
|
52
|
+
outputSource?: "override" | "cache";
|
|
53
53
|
attemptId: string;
|
|
54
54
|
durationMs?: number;
|
|
55
55
|
finishedAtMs?: number;
|
|
@@ -65,7 +65,7 @@ export type StoredPipelineArtifact = Extract<PipelineTraceEvent, {
|
|
|
65
65
|
};
|
|
66
66
|
export interface StoredPipelineStep {
|
|
67
67
|
artifacts?: StoredPipelineArtifact[];
|
|
68
|
-
outputSource?: "override";
|
|
68
|
+
outputSource?: "override" | "cache";
|
|
69
69
|
/** One execution attempt; `retries` carries `reportAttempt` telemetry. */
|
|
70
70
|
attempt?: StoredPipelineAttempt;
|
|
71
71
|
description?: string;
|