tubeless 0.2.11 → 0.2.13

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.
Files changed (196) hide show
  1. package/dist/core/child-execution.d.ts +1 -24
  2. package/dist/core/child-execution.js +11 -13
  3. package/dist/core/child-execution.js.map +1 -1
  4. package/dist/core/child-progress.js +7 -2
  5. package/dist/core/child-progress.js.map +1 -1
  6. package/dist/core/iteration.d.ts +27 -0
  7. package/dist/core/iteration.js +111 -0
  8. package/dist/core/iteration.js.map +1 -0
  9. package/dist/core/lifecycle.d.ts +7 -5
  10. package/dist/core/lifecycle.js +36 -4
  11. package/dist/core/lifecycle.js.map +1 -1
  12. package/dist/core/pipeline-artifacts.d.ts +11 -0
  13. package/dist/core/pipeline-artifacts.js +2 -0
  14. package/dist/core/pipeline-artifacts.js.map +1 -0
  15. package/dist/core/pipeline-compiler.d.ts +1 -0
  16. package/dist/core/pipeline-compiler.js +1 -0
  17. package/dist/core/pipeline-compiler.js.map +1 -1
  18. package/dist/core/pipeline-definition-identity.d.ts +2 -2
  19. package/dist/core/pipeline-definition-identity.js +28 -5
  20. package/dist/core/pipeline-definition-identity.js.map +1 -1
  21. package/dist/core/pipeline-execute.d.ts +1 -6
  22. package/dist/core/pipeline-execute.js +28 -215
  23. package/dist/core/pipeline-execute.js.map +1 -1
  24. package/dist/core/pipeline-execution-error.d.ts +35 -0
  25. package/dist/core/pipeline-execution-error.js +195 -0
  26. package/dist/core/pipeline-execution-error.js.map +1 -0
  27. package/dist/core/pipeline-identity.d.ts +1 -0
  28. package/dist/core/pipeline-identity.js +1 -0
  29. package/dist/core/pipeline-identity.js.map +1 -1
  30. package/dist/core/pipeline-mermaid.js +4 -1
  31. package/dist/core/pipeline-mermaid.js.map +1 -1
  32. package/dist/core/pipeline-run-state.d.ts +4 -4
  33. package/dist/core/pipeline-run-state.js +10 -16
  34. package/dist/core/pipeline-run-state.js.map +1 -1
  35. package/dist/core/pipeline-step-executor.d.ts +2 -0
  36. package/dist/core/pipeline-step-executor.js +11 -3
  37. package/dist/core/pipeline-step-executor.js.map +1 -1
  38. package/dist/core/pipeline-steps.d.ts +24 -1
  39. package/dist/core/pipeline-steps.js +62 -0
  40. package/dist/core/pipeline-steps.js.map +1 -1
  41. package/dist/core/pipeline-types.d.ts +28 -3
  42. package/dist/core/pipeline-types.js.map +1 -1
  43. package/dist/core/pipeline.d.ts +4 -1
  44. package/dist/core/pipeline.js +22 -4
  45. package/dist/core/pipeline.js.map +1 -1
  46. package/dist/project/project-compiler.d.ts +3 -31
  47. package/dist/project/project-compiler.js +11 -180
  48. package/dist/project/project-compiler.js.map +1 -1
  49. package/dist/project/project-registry.d.ts +44 -0
  50. package/dist/project/project-registry.js +107 -0
  51. package/dist/project/project-registry.js.map +1 -0
  52. package/dist/project/project-step-graph.d.ts +9 -0
  53. package/dist/project/project-step-graph.js +99 -0
  54. package/dist/project/project-step-graph.js.map +1 -0
  55. package/dist/render/render.js +1 -1
  56. package/dist/render/render.js.map +1 -1
  57. package/dist/reporter/interactive-reporter.js +6 -3
  58. package/dist/reporter/interactive-reporter.js.map +1 -1
  59. package/dist/reporter/live-ticker-frame.d.ts +21 -0
  60. package/dist/reporter/live-ticker-frame.js +196 -0
  61. package/dist/reporter/live-ticker-frame.js.map +1 -0
  62. package/dist/reporter/live-ticker-protocol.d.ts +41 -0
  63. package/dist/reporter/live-ticker-protocol.js +59 -0
  64. package/dist/reporter/live-ticker-protocol.js.map +1 -0
  65. package/dist/reporter/live-ticker-worker.js +11 -25
  66. package/dist/reporter/live-ticker-worker.js.map +1 -1
  67. package/dist/reporter/live-ticker.d.ts +0 -15
  68. package/dist/reporter/live-ticker.js +11 -216
  69. package/dist/reporter/live-ticker.js.map +1 -1
  70. package/dist/reporter/reporter.js +7 -6
  71. package/dist/reporter/reporter.js.map +1 -1
  72. package/dist/run-store/definition-projection.d.ts +8 -0
  73. package/dist/run-store/definition-projection.js +89 -0
  74. package/dist/run-store/definition-projection.js.map +1 -0
  75. package/dist/run-store/run-projection.d.ts +15 -0
  76. package/dist/run-store/run-projection.js +203 -0
  77. package/dist/run-store/run-projection.js.map +1 -0
  78. package/dist/run-store/run-store-codec.d.ts +2 -0
  79. package/dist/run-store/run-store-codec.js +11 -0
  80. package/dist/run-store/run-store-codec.js.map +1 -1
  81. package/dist/run-store/run-store-event-decoder.js +3 -0
  82. package/dist/run-store/run-store-event-decoder.js.map +1 -1
  83. package/dist/run-store/run-store-reader.d.ts +7 -0
  84. package/dist/run-store/run-store-reader.js +31 -0
  85. package/dist/run-store/run-store-reader.js.map +1 -0
  86. package/dist/run-store/run-store-sqlite.js +23 -7
  87. package/dist/run-store/run-store-sqlite.js.map +1 -1
  88. package/dist/run-store/run-store.d.ts +16 -4
  89. package/dist/run-store/run-store.js +14 -263
  90. package/dist/run-store/run-store.js.map +1 -1
  91. package/dist/studio/run-store-ui-api.d.ts +13 -0
  92. package/dist/studio/run-store-ui-api.js +163 -0
  93. package/dist/studio/run-store-ui-api.js.map +1 -0
  94. package/dist/studio/run-store-ui-client-browser.js +2 -2
  95. package/dist/studio/run-store-ui-client-transport.js +28 -3
  96. package/dist/studio/run-store-ui-client-transport.js.map +1 -1
  97. package/dist/studio/run-store-ui-client.d.ts +2 -1
  98. package/dist/studio/run-store-ui-client.js +15 -9
  99. package/dist/studio/run-store-ui-client.js.map +1 -1
  100. package/dist/studio/run-store-ui-http.d.ts +11 -0
  101. package/dist/studio/run-store-ui-http.js +52 -0
  102. package/dist/studio/run-store-ui-http.js.map +1 -1
  103. package/dist/studio/run-store-ui-state.d.ts +1 -1
  104. package/dist/studio/run-store-ui-state.js +10 -28
  105. package/dist/studio/run-store-ui-state.js.map +1 -1
  106. package/dist/studio/run-store-ui.d.ts +5 -11
  107. package/dist/studio/run-store-ui.js +5 -203
  108. package/dist/studio/run-store-ui.js.map +1 -1
  109. package/dist/testing/testing.d.ts +18 -2
  110. package/dist/testing/testing.js +35 -2
  111. package/dist/testing/testing.js.map +1 -1
  112. package/dist/tracing/artifact-metadata.d.ts +28 -0
  113. package/dist/tracing/artifact-metadata.js +105 -0
  114. package/dist/tracing/artifact-metadata.js.map +1 -0
  115. package/dist/tracing/tracing-codec.d.ts +1 -1
  116. package/dist/tracing/tracing-codec.js +1 -1
  117. package/dist/tracing/tracing-codec.js.map +1 -1
  118. package/dist/tracing/tracing-constants.d.ts +1 -1
  119. package/dist/tracing/tracing-constants.js +1 -1
  120. package/dist/tracing/tracing-constants.js.map +1 -1
  121. package/dist/tracing/tracing-contracts.d.ts +3 -1
  122. package/dist/tracing/tracing-contracts.js.map +1 -1
  123. package/dist/tracing/tracing-internal.d.ts +2 -0
  124. package/dist/tracing/tracing-internal.js +36 -13
  125. package/dist/tracing/tracing-internal.js.map +1 -1
  126. package/dist/tracing/tracing-schema.d.ts +330 -49
  127. package/dist/tracing/tracing-schema.js +102 -10
  128. package/dist/tracing/tracing-schema.js.map +1 -1
  129. package/dist/workbench/workbench-command-execution.d.ts +6 -0
  130. package/dist/workbench/workbench-command-execution.js +48 -0
  131. package/dist/workbench/workbench-command-execution.js.map +1 -0
  132. package/dist/workbench/workbench-history.js +11 -18
  133. package/dist/workbench/workbench-history.js.map +1 -1
  134. package/dist/workbench/workbench-launch-session.d.ts +2 -2
  135. package/dist/workbench/workbench-launch-session.js.map +1 -1
  136. package/dist/workbench/workbench-run.d.ts +0 -4
  137. package/dist/workbench/workbench-run.js +3 -47
  138. package/dist/workbench/workbench-run.js.map +1 -1
  139. package/dist/workbench/workbench-studio-launcher.d.ts +27 -0
  140. package/dist/workbench/workbench-studio-launcher.js +95 -0
  141. package/dist/workbench/workbench-studio-launcher.js.map +1 -0
  142. package/dist/workbench/workbench-ui.js +10 -83
  143. package/dist/workbench/workbench-ui.js.map +1 -1
  144. package/docs/README.md +13 -7
  145. package/docs/agent-guide.md +75 -6
  146. package/docs/airflow.md +187 -0
  147. package/docs/api-reference.md +87 -76
  148. package/docs/api-report.json +17 -6
  149. package/docs/artifacts.md +173 -0
  150. package/docs/child-pipeline-composition.md +87 -8
  151. package/docs/comparison.md +20 -0
  152. package/docs/concepts.md +79 -2
  153. package/docs/dagster.md +161 -0
  154. package/docs/inngest.md +163 -0
  155. package/docs/llms.txt +30 -1
  156. package/docs/recipes.md +82 -32
  157. package/docs/remote-step-composition.md +6 -0
  158. package/docs/step-functions.md +190 -0
  159. package/docs/studio.md +31 -12
  160. package/docs/temporal.md +183 -0
  161. package/examples/airflow/contract.ts +46 -0
  162. package/examples/airflow/hosted.ts +70 -0
  163. package/examples/airflow/remote.ts +175 -0
  164. package/examples/airflow/tubeless_example.py +49 -0
  165. package/examples/airflow/worker.ts +24 -0
  166. package/examples/artifact-lineage.ts +70 -0
  167. package/examples/dagster/definitions.py +59 -0
  168. package/examples/dagster/hosted.ts +78 -0
  169. package/examples/dagster/pipeline.ts +62 -0
  170. package/examples/dagster/test_definitions.py +47 -0
  171. package/examples/dagster/tsconfig.build.json +10 -0
  172. package/examples/dagster/worker.ts +22 -0
  173. package/examples/inherited-inputs.ts +28 -0
  174. package/examples/inngest/client.ts +4 -0
  175. package/examples/inngest/functions.ts +65 -0
  176. package/examples/inngest/pipeline.ts +41 -0
  177. package/examples/inngest/send.ts +11 -0
  178. package/examples/inngest/server.ts +17 -0
  179. package/examples/inngest/tsconfig.build.json +10 -0
  180. package/examples/iteration.ts +52 -0
  181. package/examples/parameterized-steps.ts +96 -0
  182. package/examples/project/tubeless.project.ts +50 -0
  183. package/examples/step-functions/handler.ts +110 -0
  184. package/examples/step-functions/input.json +1 -0
  185. package/examples/step-functions/pipeline.ts +41 -0
  186. package/examples/step-functions/state-machine.asl.json +41 -0
  187. package/examples/step-functions/template.json +42 -0
  188. package/examples/step-output-overrides.ts +41 -0
  189. package/examples/temporal/activities.ts +94 -0
  190. package/examples/temporal/client.ts +19 -0
  191. package/examples/temporal/pipeline.ts +41 -0
  192. package/examples/temporal/tsconfig.build.json +10 -0
  193. package/examples/temporal/worker.ts +21 -0
  194. package/examples/temporal/workflows.ts +16 -0
  195. package/package.json +13 -4
  196. package/skills/tubeless/SKILL.md +37 -4
@@ -1 +1 @@
1
- {"version":3,"file":"live-ticker.js","sourceRoot":"","sources":["../../src/reporter/live-ticker.ts"],"names":[],"mappings":"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","sourcesContent":["import { writeSync } from \"node:fs\";\nimport { isatty } from \"node:tty\";\nimport { MessageChannel, receiveMessageOnPort, Worker } from \"node:worker_threads\";\nimport { formatDurationMs } from \"./reporter.js\";\n\nexport const SPINNER_TOKEN = \"\\u0001\";\nconst ELAPSED_TOKEN_START = \"\\u0002\";\nconst ELAPSED_TOKEN_END = \"\\u0003\";\nexport const SHIMMER_TOKEN_START = \"\\u0004\";\nconst SHIMMER_TOKEN_END = \"\\u0005\";\n\nconst ANSI = {\n clearDown: \"\\u001B[J\",\n hideCursor: \"\\u001B[?25l\",\n reset: \"\\u001B[0m\",\n showCursor: \"\\u001B[?25h\",\n} as const;\n\nconst SHIMMER_BAND_COLUMNS = 3;\nconst SHIMMER_BRIGHT = \"\\u001B[0;1;36m\";\nconst SHIMMER_DIM = \"\\u001B[0;2;36m\";\nconst SHIMMER_FRAME_MS = 80;\nconst OUTPUT_LOCK_TIMEOUT_MS = 50;\n\nconst ANSI_STYLE = /\\u001B\\[[0-9;]*m/g;\nconst ANSI_STYLE_PREFIX = /^\\u001B\\[[0-9;]*m/;\nconst COMBINING_MARK = /\\p{Mark}/u;\nconst EMOJI = /\\p{Extended_Pictographic}/u;\n\nconst SPINNERS = {\n ascii: [\"-\", \"\\\\\", \"|\", \"/\"],\n unicode: [\"⠋\", \"⠙\", \"⠹\", \"⠸\", \"⠼\", \"⠴\", \"⠦\", \"⠧\", \"⠇\", \"⠏\"],\n} as const;\n\nfunction characterWidth(character: string): number {\n if (COMBINING_MARK.test(character) || character === \"\\u200D\") return 0;\n if (EMOJI.test(character)) return 2;\n const codePoint = character.codePointAt(0) ?? 0;\n return codePoint >= 0x1100 &&\n (codePoint <= 0x115f ||\n codePoint === 0x2329 ||\n codePoint === 0x232a ||\n (codePoint >= 0x2e80 && codePoint <= 0xa4cf) ||\n (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff) ||\n (codePoint >= 0xfe10 && codePoint <= 0xfe6f) ||\n (codePoint >= 0xff00 && codePoint <= 0xff60) ||\n (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||\n (codePoint >= 0x20000 && codePoint <= 0x3fffd))\n ? 2\n : 1;\n}\n\nfunction visibleWidth(value: string): number {\n return [...value].reduce((width, character) => width + characterWidth(character), 0);\n}\n\nfunction fitLine(value: string, columns: number | undefined, unicode: boolean): string {\n if (!columns || columns <= 1) return value;\n const maxWidth = columns - 1;\n const plain = value.replace(ANSI_STYLE, \"\");\n if (visibleWidth(plain) <= maxWidth) return value;\n const ellipsis = unicode ? \"…\" : \".\".repeat(Math.min(3, maxWidth));\n const targetWidth = Math.max(0, maxWidth - visibleWidth(ellipsis));\n let width = 0;\n let truncated = \"\";\n let index = 0;\n let hasStyle = false;\n while (index < value.length) {\n const style = value.slice(index).match(ANSI_STYLE_PREFIX)?.[0];\n if (style) {\n truncated += style;\n index += style.length;\n hasStyle = true;\n continue;\n }\n const character = String.fromCodePoint(value.codePointAt(index) ?? 0);\n const nextWidth = width + characterWidth(character);\n if (nextWidth > targetWidth) break;\n truncated += character;\n width = nextWidth;\n index += character.length;\n }\n return `${truncated}${hasStyle ? ANSI.reset : \"\"}${ellipsis}`;\n}\n\nexport function elapsedToken(startedAtMs: number): string {\n return `${ELAPSED_TOKEN_START}${startedAtMs}${ELAPSED_TOKEN_END}`;\n}\n\nexport function shimmerToken(value: string): string {\n return `${SHIMMER_TOKEN_START}${value}${SHIMMER_TOKEN_END}`;\n}\n\nfunction paintShimmerText(text: string, nowMs: number): string {\n const characters = [...text];\n if (characters.length === 0) return text;\n const widths = characters.map(characterWidth);\n const totalWidth = visibleWidth(text);\n const period = Math.max(1, totalWidth + SHIMMER_BAND_COLUMNS);\n const head = Math.floor(nowMs / SHIMMER_FRAME_MS) % period;\n const bandStart = head - SHIMMER_BAND_COLUMNS + 1;\n let column = 0;\n let output = ANSI.reset;\n let last: \"bright\" | \"dim\" | undefined;\n for (const [index, character] of characters.entries()) {\n const width = widths[index] ?? 0;\n const inBand =\n width === 0 ? last === \"bright\" : column <= head && column + width - 1 >= bandStart;\n const style = inBand ? \"bright\" : \"dim\";\n if (style !== last) {\n output += style === \"bright\" ? SHIMMER_BRIGHT : SHIMMER_DIM;\n last = style;\n }\n output += character;\n column += width;\n }\n return `${output}${ANSI.reset}`;\n}\n\nfunction replaceLiveTokens(line: string, spinner: string, nowMs: number, color: boolean): string {\n return line\n .replaceAll(SPINNER_TOKEN, spinner)\n .replace(\n new RegExp(`${ELAPSED_TOKEN_START}(\\\\d+)${ELAPSED_TOKEN_END}`, \"g\"),\n (_match, start: string) => formatDurationMs(Math.max(0, nowMs - Number(start)))\n )\n .replace(\n new RegExp(`${SHIMMER_TOKEN_START}(.*?)${SHIMMER_TOKEN_END}`, \"g\"),\n (_match, text: string) => (color ? paintShimmerText(text, nowMs) : text)\n );\n}\n\nexport function paintLiveLines(\n lines: readonly string[],\n spinner: string,\n nowMs: number,\n columns?: number,\n color = false,\n unicode = true,\n logPane?: readonly string[]\n): string[] {\n const painted = lines.map((line) => replaceLiveTokens(line, spinner, nowMs, color));\n if (!logPane || !columns || columns < 120) {\n return painted.map((line) => fitLine(line, columns, unicode));\n }\n const paneWidth = Math.min(60, Math.floor(columns * 0.4));\n const leftWidth = columns - paneWidth - 3;\n const horizontal = unicode ? \"─\" : \"-\";\n const vertical = unicode ? \"│\" : \"|\";\n const pad = (line: string, width: number): string => {\n const fitted = fitLine(line, width + 1, unicode);\n return fitted + \" \".repeat(Math.max(0, width - visibleWidth(fitted.replace(ANSI_STYLE, \"\"))));\n };\n const pane = [\n `${unicode ? \"╭\" : \"+\"}${horizontal} Logs ${horizontal.repeat(paneWidth - 9)}${unicode ? \"╮\" : \"+\"}`,\n ...logPane.map((line) => `${vertical} ${pad(line, paneWidth - 4)} ${vertical}`),\n `${unicode ? \"╰\" : \"+\"}${horizontal.repeat(paneWidth - 2)}${unicode ? \"╯\" : \"+\"}`,\n ];\n return Array.from({ length: Math.max(painted.length, pane.length) }, (_, index) =>\n pane[index] === undefined\n ? fitLine(painted[index] ?? \"\", leftWidth + 1, unicode)\n : `${pad(painted[index] ?? \"\", leftWidth)} ${pane[index]}`\n );\n}\n\nexport interface LiveTicker {\n setLines(lines: readonly string[], logPane?: readonly string[]): void;\n writeLog(text: string): void;\n dispose(): void;\n}\n\nexport interface LiveTickerOptions {\n columns?: number;\n getColumns?(): number | undefined;\n fd?: number;\n refreshIntervalMs: number;\n unicode: boolean;\n color?: boolean;\n write(chunk: string): void;\n workerUrl?: URL;\n}\n\ntype TickerWorkerMessage =\n | { columns?: number; lines: string[]; logPane?: readonly string[]; type: \"lines\" }\n | { columns?: number; text: string; type: \"log\" }\n | { columns?: number; lines: string[]; logPane?: readonly string[]; type: \"stop\" };\n\nexport class TickerFrame {\n private cursorHidden: boolean;\n\n constructor(\n private readonly write: (chunk: string) => void,\n private paintedLines: readonly string[] = []\n ) {\n this.cursorHidden = paintedLines.length > 0;\n }\n\n showCursor(): void {\n if (!this.cursorHidden) return;\n this.write(ANSI.showCursor);\n this.cursorHidden = false;\n }\n\n clear(columns?: number): void {\n if (this.paintedLines.length === 0) return;\n // Resizing can reflow each previously painted line across several rows.\n // Count those rows at the current width before moving back to the frame start.\n let rows = this.paintedLines.length;\n if (columns !== undefined && columns > 0) {\n rows = 0;\n for (const line of this.paintedLines) {\n rows += 1;\n let column = 0;\n for (const character of line.replace(ANSI_STYLE, \"\")) {\n const width = characterWidth(character);\n if (column + width > columns) {\n rows += 1;\n column = 0;\n }\n column += width;\n }\n }\n }\n this.write(`\\u001B[${rows}F${ANSI.clearDown}`);\n this.paintedLines = [];\n }\n\n redraw(lines: readonly string[], columns?: number): void {\n if (!this.cursorHidden) {\n this.write(ANSI.hideCursor);\n this.cursorHidden = true;\n }\n this.clear(columns);\n if (lines.length === 0) return;\n this.write(`${lines.join(\"\\n\")}\\n`);\n this.paintedLines = lines;\n }\n}\n\nfunction resolveColumns(options: LiveTickerOptions): number | undefined {\n return options.getColumns?.() ?? options.columns;\n}\n\nexport function currentSpinner(unicode: boolean, refreshIntervalMs: number): string {\n const frames = unicode ? SPINNERS.unicode : SPINNERS.ascii;\n return frames[Math.floor(Date.now() / refreshIntervalMs) % frames.length] ?? frames[0]!;\n}\n\nfunction createInlineTicker(\n options: LiveTickerOptions,\n adoptedPaintedLines: readonly string[] = []\n): LiveTicker {\n let disposed = false;\n let lines: readonly string[] = [];\n let logPane: readonly string[] | undefined;\n const frame = new TickerFrame((chunk) => options.write(chunk), adoptedPaintedLines);\n const redraw = (): void => {\n if (disposed) return;\n const columns = resolveColumns(options);\n frame.redraw(\n paintLiveLines(\n lines,\n currentSpinner(options.unicode, options.refreshIntervalMs),\n Date.now(),\n columns,\n options.color === true,\n options.unicode,\n logPane\n ),\n columns\n );\n };\n\n const timer = setInterval(() => {\n if (\n disposed ||\n !lines.some((line) => line.includes(SPINNER_TOKEN) || line.includes(SHIMMER_TOKEN_START))\n ) {\n return;\n }\n redraw();\n }, options.refreshIntervalMs);\n timer.unref();\n\n return {\n setLines(nextLines, nextLogPane) {\n lines = nextLines;\n logPane = nextLogPane;\n redraw();\n },\n writeLog(text) {\n if (disposed) {\n options.write(text);\n return;\n }\n frame.clear(resolveColumns(options));\n options.write(text);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n clearInterval(timer);\n frame.showCursor();\n },\n };\n}\n\nfunction resolveLiveTickerWorkerUrl(): URL {\n return import.meta.url.endsWith(\".ts\")\n ? new URL(\"../../dist/reporter/live-ticker-worker.js\", import.meta.url)\n : new URL(\"./live-ticker-worker.js\", import.meta.url);\n}\n\nfunction fileWorkerExecArgv(argv: readonly string[] = process.execArgv): string[] {\n const next: string[] = [];\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === \"--input-type\") {\n index += 1;\n } else if (!arg.startsWith(\"--input-type=\")) {\n next.push(arg);\n }\n }\n return next;\n}\n\nfunction createWorkerTicker(options: LiveTickerOptions & { fd: number }): LiveTicker {\n // [0] stopped, [1] accepted logs, [2] inline owns output, [3] output lock\n const stateBuffer = new SharedArrayBuffer(16);\n const state = new Int32Array(stateBuffer);\n const { port1: framePort, port2: workerFramePort } = new MessageChannel();\n let worker: Worker;\n try {\n worker = new Worker(options.workerUrl ?? resolveLiveTickerWorkerUrl(), {\n execArgv: fileWorkerExecArgv(),\n transferList: [workerFramePort],\n workerData: {\n color: options.color === true,\n columns: resolveColumns(options),\n fd: options.fd,\n framePort: workerFramePort,\n refreshIntervalMs: options.refreshIntervalMs,\n stateBuffer,\n unicode: options.unicode,\n },\n });\n } catch (error) {\n framePort.close();\n workerFramePort.close();\n throw error;\n }\n let paintedLines: readonly string[] = [];\n framePort.on(\"message\", (nextLines: string[]) => {\n paintedLines = nextLines;\n });\n framePort.unref();\n let disposed = false;\n let inlineFallback: LiveTicker | undefined;\n let lines: readonly string[] = [];\n let logPane: readonly string[] | undefined;\n const pendingLogs: string[] = [];\n let acknowledgedLogs = 0;\n\n const restoreCursor = (): void => {\n try {\n if (isatty(options.fd)) {\n writeSync(options.fd, ANSI.showCursor);\n } else {\n options.write(ANSI.showCursor);\n }\n } catch {\n // The output may remain unavailable; cursor restore is best-effort.\n }\n };\n\n const dropAcknowledgedLogs = (): void => {\n const accepted = Atomics.load(state, 1);\n pendingLogs.splice(0, accepted - acknowledgedLogs);\n acknowledgedLogs = accepted;\n };\n\n const replayThrough = (ticker: LiveTicker): void => {\n dropAcknowledgedLogs();\n for (const text of pendingLogs) ticker.writeLog(text);\n pendingLogs.length = 0;\n ticker.setLines([...lines], logPane);\n };\n\n const claimOutput = (): boolean => {\n Atomics.store(state, 2, 1);\n const deadline = Date.now() + OUTPUT_LOCK_TIMEOUT_MS;\n while (Atomics.compareExchange(state, 3, 0, 1) !== 0) {\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) return false;\n Atomics.wait(state, 3, 1, remainingMs);\n }\n return true;\n };\n\n const createFallback = (): LiveTicker | undefined => {\n if (!claimOutput()) return undefined;\n // dispose() blocks the event loop. Drain snapshots synchronously after taking\n // the output lock so adoption includes the worker's last completed paint.\n let snapshot;\n while ((snapshot = receiveMessageOnPort(framePort)) !== undefined) {\n paintedLines = snapshot.message as string[];\n }\n framePort.close();\n const ticker = createInlineTicker(options, paintedLines);\n replayThrough(ticker);\n return ticker;\n };\n\n const failToInline = (): void => {\n if (disposed || inlineFallback) return;\n // The exit event guarantees that no worker write still owns this lock.\n Atomics.store(state, 3, 0);\n inlineFallback = createFallback();\n };\n\n worker.on(\"error\", () => void worker.terminate());\n worker.on(\"exit\", () => failToInline());\n worker.unref();\n\n return {\n setLines(nextLines, nextLogPane) {\n if (disposed) return;\n lines = nextLines;\n logPane = nextLogPane;\n if (inlineFallback) {\n inlineFallback.setLines(nextLines, nextLogPane);\n return;\n }\n worker.postMessage({\n columns: resolveColumns(options),\n lines: [...nextLines],\n logPane,\n type: \"lines\",\n } satisfies TickerWorkerMessage);\n },\n writeLog(text) {\n if (inlineFallback) {\n inlineFallback.writeLog(text);\n return;\n }\n if (disposed) {\n options.write(text);\n return;\n }\n dropAcknowledgedLogs();\n pendingLogs.push(text);\n worker.postMessage({\n columns: resolveColumns(options),\n text,\n type: \"log\",\n } satisfies TickerWorkerMessage);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (inlineFallback) {\n inlineFallback.dispose();\n void worker.terminate();\n return;\n }\n let restoreCursorAfterTerminate = false;\n try {\n let workerStopped = false;\n try {\n worker.postMessage({\n columns: resolveColumns(options),\n lines: [...lines],\n logPane,\n type: \"stop\",\n } satisfies TickerWorkerMessage);\n workerStopped = Atomics.wait(state, 0, 0, 500) !== \"timed-out\";\n } catch {\n // The worker is unavailable; render its retained state below.\n }\n if (!workerStopped) {\n const ticker = createFallback();\n if (ticker) {\n ticker.dispose();\n } else {\n restoreCursorAfterTerminate = true;\n }\n }\n } finally {\n framePort.close();\n const terminated = worker.terminate();\n if (restoreCursorAfterTerminate) {\n restoreCursor();\n void terminated.then(restoreCursor);\n }\n }\n },\n };\n}\n\nfunction outputFd(fd: number | undefined): fd is number {\n return fd !== undefined && Number.isInteger(fd) && fd >= 0;\n}\n\nexport function createLiveTicker(options: LiveTickerOptions): LiveTicker {\n if (outputFd(options.fd)) {\n try {\n return createWorkerTicker({ ...options, fd: options.fd });\n } catch {\n // Some embeddings do not provide worker threads.\n }\n }\n return createInlineTicker(options);\n}\n"]}
1
+ {"version":3,"file":"live-ticker.js","sourceRoot":"","sources":["../../src/reporter/live-ticker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AACnF,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,WAAW,EACX,WAAW,GACZ,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,iBAAiB,GAGlB,MAAM,2BAA2B,CAAC;AAEnC,MAAM,sBAAsB,GAAG,EAAE,CAAC;AAmBlC,SAAS,cAAc,CAAC,OAA0B;IAChD,OAAO,OAAO,CAAC,UAAU,EAAE,EAAE,IAAI,OAAO,CAAC,OAAO,CAAC;AACnD,CAAC;AAED,SAAS,kBAAkB,CACzB,OAA0B,EAC1B,mBAAmB,GAAsB,EAAE;IAE3C,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,KAAK,GAAsB,EAAE,CAAC;IAClC,IAAI,OAAsC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,mBAAmB,CAAC,CAAC;IACpF,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,IAAI,QAAQ;YAAE,OAAO;QACrB,MAAM,OAAO,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;QACxC,KAAK,CAAC,MAAM,CACV,cAAc,CACZ,KAAK,EACL,cAAc,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,iBAAiB,CAAC,EAC1D,IAAI,CAAC,GAAG,EAAE,EACV,OAAO,EACP,OAAO,CAAC,KAAK,KAAK,IAAI,EACtB,OAAO,CAAC,OAAO,EACf,OAAO,CACR,EACD,OAAO,CACR,CAAC;IACJ,CAAC,CAAC;IAEF,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,IAAI,QAAQ,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;YACzC,OAAO;QACT,CAAC;QACD,MAAM,EAAE,CAAC;IACX,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC9B,KAAK,CAAC,KAAK,EAAE,CAAC;IAEd,OAAO;QACL,QAAQ,CAAC,SAAS,EAAE,WAAW;YAC7B,KAAK,GAAG,SAAS,CAAC;YAClB,OAAO,GAAG,WAAW,CAAC;YACtB,MAAM,EAAE,CAAC;QACX,CAAC;QACD,QAAQ,CAAC,IAAI;YACX,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACpB,OAAO;YACT,CAAC;YACD,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;YACrC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACtB,CAAC;QACD,OAAO;YACL,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,aAAa,CAAC,KAAK,CAAC,CAAC;YACrB,KAAK,CAAC,UAAU,EAAE,CAAC;QACrB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,0BAA0B;IACjC,OAAO,OAAO,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC;QACpC,CAAC,CAAC,IAAI,GAAG,CAAC,2CAA2C,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC;QACvE,CAAC,CAAC,IAAI,GAAG,CAAC,yBAAyB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1D,CAAC;AAED,SAAS,kBAAkB,CAAC,IAAI,GAAsB,OAAO,CAAC,QAAQ;IACpE,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;YAC3B,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAC5C,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CAAC,OAA2C;IACrE,MAAM,KAAK,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACtC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,eAAe,EAAE,GAAG,IAAI,cAAc,EAAE,CAAC;IAC1E,IAAI,MAAc,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,CAAC,SAAS,IAAI,0BAA0B,EAAE,EAAE;YACrE,QAAQ,EAAE,kBAAkB,EAAE;YAC9B,YAAY,EAAE,CAAC,eAAe,CAAC;YAC/B,UAAU,EAAE;gBACV,KAAK,EAAE,OAAO,CAAC,KAAK,KAAK,IAAI;gBAC7B,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC;gBAChC,EAAE,EAAE,OAAO,CAAC,EAAE;gBACd,SAAS,EAAE,eAAe;gBAC1B,iBAAiB,EAAE,OAAO,CAAC,iBAAiB;gBAC5C,WAAW,EAAE,KAAK,CAAC,MAAM;gBACzB,OAAO,EAAE,OAAO,CAAC,OAAO;aACM;SACjC,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,CAAC,KAAK,EAAE,CAAC;QAClB,eAAe,CAAC,KAAK,EAAE,CAAC;QACxB,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,YAAY,GAAsB,EAAE,CAAC;IACzC,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,SAAmB,EAAE,EAAE;QAC9C,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC,CAAC,CAAC;IACH,SAAS,CAAC,KAAK,EAAE,CAAC;IAClB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,cAAsC,CAAC;IAC3C,IAAI,KAAK,GAAsB,EAAE,CAAC;IAClC,IAAI,OAAsC,CAAC;IAC3C,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,gBAAgB,GAAG,CAAC,CAAC;IAEzB,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,IAAI,CAAC;YACH,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBACvB,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;YAChD,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;YACxC,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,oEAAoE;QACtE,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,oBAAoB,GAAG,GAAS,EAAE;QACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,CAAC;QACpC,WAAW,CAAC,MAAM,CAAC,CAAC,EAAE,QAAQ,GAAG,gBAAgB,CAAC,CAAC;QACnD,gBAAgB,GAAG,QAAQ,CAAC;IAC9B,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,CAAC,MAAkB,EAAQ,EAAE;QACjD,oBAAoB,EAAE,CAAC;QACvB,KAAK,MAAM,IAAI,IAAI,WAAW;YAAE,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACtD,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC;QACvB,MAAM,CAAC,QAAQ,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,GAA2B,EAAE;QAClD,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,sBAAsB,CAAC;YAAE,OAAO,SAAS,CAAC;QACjE,8EAA8E;QAC9E,0EAA0E;QAC1E,IAAI,QAAQ,CAAC;QACb,OAAO,CAAC,QAAQ,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAClE,YAAY,GAAG,QAAQ,CAAC,OAAmB,CAAC;QAC9C,CAAC;QACD,SAAS,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,kBAAkB,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;QACzD,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,GAAS,EAAE;QAC9B,IAAI,QAAQ,IAAI,cAAc;YAAE,OAAO;QACvC,KAAK,CAAC,4BAA4B,EAAE,CAAC;QACrC,cAAc,GAAG,cAAc,EAAE,CAAC;IACpC,CAAC,CAAC;IAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAClD,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,CAAC,CAAC;IACxC,MAAM,CAAC,KAAK,EAAE,CAAC;IAEf,OAAO;QACL,QAAQ,CAAC,SAAS,EAAE,WAAW;YAC7B,IAAI,QAAQ;gBAAE,OAAO;YACrB,KAAK,GAAG,SAAS,CAAC;YAClB,OAAO,GAAG,WAAW,CAAC;YACtB,IAAI,cAAc,EAAE,CAAC;gBACnB,cAAc,CAAC,QAAQ,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;gBAChD,OAAO;YACT,CAAC;YACD,MAAM,CAAC,WAAW,CAAC;gBACjB,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC;gBAChC,KAAK,EAAE,CAAC,GAAG,SAAS,CAAC;gBACrB,OAAO;gBACP,IAAI,EAAE,OAAO;aACgB,CAAC,CAAC;QACnC,CAAC;QACD,QAAQ,CAAC,IAAI;YACX,IAAI,cAAc,EAAE,CAAC;gBACnB,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC9B,OAAO;YACT,CAAC;YACD,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACpB,OAAO;YACT,CAAC;YACD,oBAAoB,EAAE,CAAC;YACvB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACvB,MAAM,CAAC,WAAW,CAAC;gBACjB,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC;gBAChC,IAAI;gBACJ,IAAI,EAAE,KAAK;aACkB,CAAC,CAAC;QACnC,CAAC;QACD,OAAO;YACL,IAAI,QAAQ;gBAAE,OAAO;YACrB,QAAQ,GAAG,IAAI,CAAC;YAChB,IAAI,cAAc,EAAE,CAAC;gBACnB,cAAc,CAAC,OAAO,EAAE,CAAC;gBACzB,KAAK,MAAM,CAAC,SAAS,EAAE,CAAC;gBACxB,OAAO;YACT,CAAC;YACD,IAAI,2BAA2B,GAAG,KAAK,CAAC;YACxC,IAAI,CAAC;gBACH,IAAI,aAAa,GAAG,KAAK,CAAC;gBAC1B,IAAI,CAAC;oBACH,MAAM,CAAC,WAAW,CAAC;wBACjB,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC;wBAChC,KAAK,EAAE,CAAC,GAAG,KAAK,CAAC;wBACjB,OAAO;wBACP,IAAI,EAAE,MAAM;qBACiB,CAAC,CAAC;oBACjC,aAAa,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;gBACzC,CAAC;gBAAC,MAAM,CAAC;oBACP,8DAA8D;gBAChE,CAAC;gBACD,IAAI,CAAC,aAAa,EAAE,CAAC;oBACnB,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;oBAChC,IAAI,MAAM,EAAE,CAAC;wBACX,MAAM,CAAC,OAAO,EAAE,CAAC;oBACnB,CAAC;yBAAM,CAAC;wBACN,2BAA2B,GAAG,IAAI,CAAC;oBACrC,CAAC;gBACH,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,SAAS,CAAC,KAAK,EAAE,CAAC;gBAClB,MAAM,UAAU,GAAG,MAAM,CAAC,SAAS,EAAE,CAAC;gBACtC,IAAI,2BAA2B,EAAE,CAAC;oBAChC,aAAa,EAAE,CAAC;oBAChB,KAAK,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACtC,CAAC;YACH,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,EAAsB;IACtC,OAAO,EAAE,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,OAA0B;IACzD,IAAI,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,OAAO,kBAAkB,CAAC,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,iDAAiD;QACnD,CAAC;IACH,CAAC;IACD,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC","sourcesContent":["import { writeSync } from \"node:fs\";\nimport { isatty } from \"node:tty\";\nimport { MessageChannel, receiveMessageOnPort, Worker } from \"node:worker_threads\";\nimport {\n currentSpinner,\n hasLiveAnimation,\n paintLiveLines,\n TICKER_ANSI,\n TickerFrame,\n} from \"./live-ticker-frame.js\";\nimport {\n TickerWorkerState,\n type LiveTickerWorkerData,\n type TickerWorkerMessage,\n} from \"./live-ticker-protocol.js\";\n\nconst OUTPUT_LOCK_TIMEOUT_MS = 50;\n\nexport interface LiveTicker {\n setLines(lines: readonly string[], logPane?: readonly string[]): void;\n writeLog(text: string): void;\n dispose(): void;\n}\n\nexport interface LiveTickerOptions {\n columns?: number;\n getColumns?(): number | undefined;\n fd?: number;\n refreshIntervalMs: number;\n unicode: boolean;\n color?: boolean;\n write(chunk: string): void;\n workerUrl?: URL;\n}\n\nfunction resolveColumns(options: LiveTickerOptions): number | undefined {\n return options.getColumns?.() ?? options.columns;\n}\n\nfunction createInlineTicker(\n options: LiveTickerOptions,\n adoptedPaintedLines: readonly string[] = []\n): LiveTicker {\n let disposed = false;\n let lines: readonly string[] = [];\n let logPane: readonly string[] | undefined;\n const frame = new TickerFrame((chunk) => options.write(chunk), adoptedPaintedLines);\n const redraw = (): void => {\n if (disposed) return;\n const columns = resolveColumns(options);\n frame.redraw(\n paintLiveLines(\n lines,\n currentSpinner(options.unicode, options.refreshIntervalMs),\n Date.now(),\n columns,\n options.color === true,\n options.unicode,\n logPane\n ),\n columns\n );\n };\n\n const timer = setInterval(() => {\n if (disposed || !hasLiveAnimation(lines)) {\n return;\n }\n redraw();\n }, options.refreshIntervalMs);\n timer.unref();\n\n return {\n setLines(nextLines, nextLogPane) {\n lines = nextLines;\n logPane = nextLogPane;\n redraw();\n },\n writeLog(text) {\n if (disposed) {\n options.write(text);\n return;\n }\n frame.clear(resolveColumns(options));\n options.write(text);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n clearInterval(timer);\n frame.showCursor();\n },\n };\n}\n\nfunction resolveLiveTickerWorkerUrl(): URL {\n return import.meta.url.endsWith(\".ts\")\n ? new URL(\"../../dist/reporter/live-ticker-worker.js\", import.meta.url)\n : new URL(\"./live-ticker-worker.js\", import.meta.url);\n}\n\nfunction fileWorkerExecArgv(argv: readonly string[] = process.execArgv): string[] {\n const next: string[] = [];\n for (let index = 0; index < argv.length; index += 1) {\n const arg = argv[index];\n if (arg === \"--input-type\") {\n index += 1;\n } else if (!arg.startsWith(\"--input-type=\")) {\n next.push(arg);\n }\n }\n return next;\n}\n\nfunction createWorkerTicker(options: LiveTickerOptions & { fd: number }): LiveTicker {\n const state = new TickerWorkerState();\n const { port1: framePort, port2: workerFramePort } = new MessageChannel();\n let worker: Worker;\n try {\n worker = new Worker(options.workerUrl ?? resolveLiveTickerWorkerUrl(), {\n execArgv: fileWorkerExecArgv(),\n transferList: [workerFramePort],\n workerData: {\n color: options.color === true,\n columns: resolveColumns(options),\n fd: options.fd,\n framePort: workerFramePort,\n refreshIntervalMs: options.refreshIntervalMs,\n stateBuffer: state.buffer,\n unicode: options.unicode,\n } satisfies LiveTickerWorkerData,\n });\n } catch (error) {\n framePort.close();\n workerFramePort.close();\n throw error;\n }\n let paintedLines: readonly string[] = [];\n framePort.on(\"message\", (nextLines: string[]) => {\n paintedLines = nextLines;\n });\n framePort.unref();\n let disposed = false;\n let inlineFallback: LiveTicker | undefined;\n let lines: readonly string[] = [];\n let logPane: readonly string[] | undefined;\n const pendingLogs: string[] = [];\n let acknowledgedLogs = 0;\n\n const restoreCursor = (): void => {\n try {\n if (isatty(options.fd)) {\n writeSync(options.fd, TICKER_ANSI.showCursor);\n } else {\n options.write(TICKER_ANSI.showCursor);\n }\n } catch {\n // The output may remain unavailable; cursor restore is best-effort.\n }\n };\n\n const dropAcknowledgedLogs = (): void => {\n const accepted = state.acceptedLogs;\n pendingLogs.splice(0, accepted - acknowledgedLogs);\n acknowledgedLogs = accepted;\n };\n\n const replayThrough = (ticker: LiveTicker): void => {\n dropAcknowledgedLogs();\n for (const text of pendingLogs) ticker.writeLog(text);\n pendingLogs.length = 0;\n ticker.setLines([...lines], logPane);\n };\n\n const createFallback = (): LiveTicker | undefined => {\n if (!state.claimOutput(OUTPUT_LOCK_TIMEOUT_MS)) return undefined;\n // dispose() blocks the event loop. Drain snapshots synchronously after taking\n // the output lock so adoption includes the worker's last completed paint.\n let snapshot;\n while ((snapshot = receiveMessageOnPort(framePort)) !== undefined) {\n paintedLines = snapshot.message as string[];\n }\n framePort.close();\n const ticker = createInlineTicker(options, paintedLines);\n replayThrough(ticker);\n return ticker;\n };\n\n const failToInline = (): void => {\n if (disposed || inlineFallback) return;\n state.releaseOutputAfterWorkerExit();\n inlineFallback = createFallback();\n };\n\n worker.on(\"error\", () => void worker.terminate());\n worker.on(\"exit\", () => failToInline());\n worker.unref();\n\n return {\n setLines(nextLines, nextLogPane) {\n if (disposed) return;\n lines = nextLines;\n logPane = nextLogPane;\n if (inlineFallback) {\n inlineFallback.setLines(nextLines, nextLogPane);\n return;\n }\n worker.postMessage({\n columns: resolveColumns(options),\n lines: [...nextLines],\n logPane,\n type: \"lines\",\n } satisfies TickerWorkerMessage);\n },\n writeLog(text) {\n if (inlineFallback) {\n inlineFallback.writeLog(text);\n return;\n }\n if (disposed) {\n options.write(text);\n return;\n }\n dropAcknowledgedLogs();\n pendingLogs.push(text);\n worker.postMessage({\n columns: resolveColumns(options),\n text,\n type: \"log\",\n } satisfies TickerWorkerMessage);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n if (inlineFallback) {\n inlineFallback.dispose();\n void worker.terminate();\n return;\n }\n let restoreCursorAfterTerminate = false;\n try {\n let workerStopped = false;\n try {\n worker.postMessage({\n columns: resolveColumns(options),\n lines: [...lines],\n logPane,\n type: \"stop\",\n } satisfies TickerWorkerMessage);\n workerStopped = state.waitForStop(500);\n } catch {\n // The worker is unavailable; render its retained state below.\n }\n if (!workerStopped) {\n const ticker = createFallback();\n if (ticker) {\n ticker.dispose();\n } else {\n restoreCursorAfterTerminate = true;\n }\n }\n } finally {\n framePort.close();\n const terminated = worker.terminate();\n if (restoreCursorAfterTerminate) {\n restoreCursor();\n void terminated.then(restoreCursor);\n }\n }\n },\n };\n}\n\nfunction outputFd(fd: number | undefined): fd is number {\n return fd !== undefined && Number.isInteger(fd) && fd >= 0;\n}\n\nexport function createLiveTicker(options: LiveTickerOptions): LiveTicker {\n if (outputFd(options.fd)) {\n try {\n return createWorkerTicker({ ...options, fd: options.fd });\n } catch {\n // Some embeddings do not provide worker threads.\n }\n }\n return createInlineTicker(options);\n}\n"]}
@@ -89,7 +89,8 @@ export function createRunReporter(options) {
89
89
  const lastProgressMessage = new Map();
90
90
  const progressLogIntervalMs = 750;
91
91
  const ellipsis = unicodeEnabled ? "…" : "...";
92
- const displayName = (step) => safeTerminalText(step.name ?? step.id);
92
+ const displayName = (step) => safeTerminalText(step.name ?? step.id) +
93
+ (step.outputSource === "override" ? " (overridden)" : "");
93
94
  const clearProgress = (stepId) => {
94
95
  lastProgressLogAt.delete(stepId);
95
96
  lastProgressMessage.delete(stepId);
@@ -100,11 +101,11 @@ export function createRunReporter(options) {
100
101
  return;
101
102
  log.log(styled.pipeline(`Pipeline ${safeTerminalText(plan.pipelineId)}: starting (${plan.steps.length} steps, dryRun=${plan.dryRun})`));
102
103
  },
103
- onStepStart: ({ step }) => {
104
+ onStepStart: ({ step, outputSource }) => {
104
105
  const description = step.description
105
106
  ? ` - ${styled.description(safeTerminalText(step.description))}`
106
107
  : "";
107
- log.log(` ${styled.start(symbols.start)} ${displayName(step)}${description}`);
108
+ log.log(` ${styled.start(symbols.start)} ${displayName({ ...step, outputSource })}${description}`);
108
109
  },
109
110
  onStepProgress: ({ progress, step }) => {
110
111
  // Ignore empty/non-visible progress snapshots (no message, total, or work count).
@@ -141,15 +142,15 @@ export function createRunReporter(options) {
141
142
  const detail = safeTerminalText(event.dependencyId
142
143
  ? `${event.reason}: ${event.dependencyId}`
143
144
  : (event.message ?? event.reason));
144
- log.log(` ${styled.skip(symbols.skip)} ${displayName(event.step)} ${styled.duration(`(${detail})`)}`);
145
+ log.log(` ${styled.skip(symbols.skip)} ${displayName(event)} ${styled.duration(`(${detail})`)}`);
145
146
  },
146
147
  onStepCancel: (event) => {
147
148
  clearProgress(event.id);
148
- log.warn(` ${styled.skip(symbols.skip)} ${displayName(event.step)}: cancelled: ${safeTerminalText(event.error.message)}`);
149
+ log.warn(` ${styled.skip(symbols.skip)} ${displayName(event)}: cancelled: ${safeTerminalText(event.error.message)}`);
149
150
  },
150
151
  onStepFail: (event) => {
151
152
  clearProgress(event.id);
152
- log.error(` ${styled.fail(symbols.fail)} ${displayName(event.step)}: ${safeTerminalText(event.error.message)}`);
153
+ log.error(` ${styled.fail(symbols.fail)} ${displayName(event)}: ${safeTerminalText(event.error.message)}`);
153
154
  },
154
155
  onFinalizeStart: () => {
155
156
  log.log(` ${styled.start(symbols.start)} finalize`);
@@ -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 }): string =>\n safeTerminalText(step.name ?? step.id);\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 }) => {\n const description = step.description\n ? ` - ${styled.description(safeTerminalText(step.description))}`\n : \"\";\n log.log(` ${styled.start(symbols.start)} ${displayName(step)}${description}`);\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.step)} ${styled.duration(`(${detail})`)}`\n );\n },\n onStepCancel: (event) => {\n clearProgress(event.id);\n log.warn(\n ` ${styled.skip(symbols.skip)} ${displayName(event.step)}: cancelled: ${safeTerminalText(event.error.message)}`\n );\n },\n onStepFail: (event) => {\n clearProgress(event.id);\n log.error(\n ` ${styled.fail(symbols.fail)} ${displayName(event.step)}: ${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\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"]}
@@ -0,0 +1,8 @@
1
+ import type { StoredPipelineDefinition, StoredPipelineEvent, StoredPipelineRun } from "./run-store.js";
2
+ /** Own observed definition replacement independently of run execution state. */
3
+ export declare class DefinitionProjection {
4
+ #private;
5
+ constructor(event: StoredPipelineEvent);
6
+ append(event: StoredPipelineEvent): void;
7
+ snapshot(pipelineRuns: readonly StoredPipelineRun[]): StoredPipelineDefinition;
8
+ }
@@ -0,0 +1,89 @@
1
+ function definitionStep(event) {
2
+ const step = {
3
+ dependencies: [...event.payload.dependencies],
4
+ dryRun: event.payload.dryRun,
5
+ id: event.stepId,
6
+ optionalDependencies: [...event.payload.optionalDependencies],
7
+ runtimeSkipPossible: event.payload.runtimeSkipPossible,
8
+ skipAfterFailureOf: [...event.payload.skipAfterFailureOf],
9
+ };
10
+ const description = event.payload.description;
11
+ if (description)
12
+ step.description = description;
13
+ const name = event.payload.name;
14
+ if (name)
15
+ step.name = name;
16
+ if (event.payload.nestedPipeline) {
17
+ step.nestedPipeline = {
18
+ ...event.payload.nestedPipeline,
19
+ stepIds: [...event.payload.nestedPipeline.stepIds],
20
+ };
21
+ }
22
+ if (event.payload.remote)
23
+ step.remote = { ...event.payload.remote };
24
+ return step;
25
+ }
26
+ /** Own observed definition replacement independently of run execution state. */
27
+ export class DefinitionProjection {
28
+ #snapshot;
29
+ #definitionRun;
30
+ #firstSeenAtMs;
31
+ #lastSeenAtMs;
32
+ #latestSteps = new Map();
33
+ #runStarts = new Map();
34
+ #targetIds = [];
35
+ constructor(event) {
36
+ this.#firstSeenAtMs = event.timestampMs;
37
+ this.#lastSeenAtMs = event.timestampMs;
38
+ this.append(event);
39
+ }
40
+ append(event) {
41
+ this.#firstSeenAtMs = Math.min(this.#firstSeenAtMs, event.timestampMs);
42
+ this.#lastSeenAtMs = Math.max(this.#lastSeenAtMs, event.timestampMs);
43
+ if (event.name === "pipeline.started") {
44
+ if (event.payload.definitionSnapshot)
45
+ this.#snapshot = structuredClone(event.payload.definitionSnapshot);
46
+ this.#runStarts.set(event.runId, {
47
+ atMs: event.timestampMs,
48
+ eventId: event.id,
49
+ targetIds: [...event.payload.targetIds],
50
+ });
51
+ }
52
+ if (event.name !== "step.planned" || !event.stepId)
53
+ return;
54
+ const start = this.#runStarts.get(event.runId);
55
+ if (!start)
56
+ return;
57
+ const current = this.#definitionRun;
58
+ if (!current ||
59
+ start.atMs > current.startedAtMs ||
60
+ (start.atMs === current.startedAtMs && start.eventId > current.startedEventId)) {
61
+ this.#definitionRun = {
62
+ id: event.runId,
63
+ startedAtMs: start.atMs,
64
+ startedEventId: start.eventId,
65
+ };
66
+ this.#latestSteps.clear();
67
+ this.#targetIds = start.targetIds;
68
+ }
69
+ if (event.runId === this.#definitionRun?.id) {
70
+ this.#latestSteps.set(event.stepId, definitionStep(event));
71
+ }
72
+ }
73
+ snapshot(pipelineRuns) {
74
+ const identity = pipelineRuns[0].definitionIdentity;
75
+ const snapshot = this.#snapshot;
76
+ return {
77
+ activeRuns: pipelineRuns.filter(({ status }) => status === "running").length,
78
+ firstSeenAtMs: this.#firstSeenAtMs,
79
+ lastSeenAtMs: this.#lastSeenAtMs,
80
+ pipelineId: pipelineRuns[0].pipelineId,
81
+ ...(identity ? { identity: { ...identity } } : {}),
82
+ ...(snapshot ? { snapshot: structuredClone(snapshot) } : {}),
83
+ runCount: pipelineRuns.length,
84
+ steps: [...this.#latestSteps.values()].map((step) => structuredClone(step)),
85
+ targetIds: [...(snapshot?.targetIds ?? this.#targetIds)],
86
+ };
87
+ }
88
+ }
89
+ //# sourceMappingURL=definition-projection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition-projection.js","sourceRoot":"","sources":["../../src/run-store/definition-projection.ts"],"names":[],"mappings":"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","sourcesContent":["import type { PipelineDefinitionSnapshot } from \"../core/pipeline.js\";\nimport type {\n StoredPipelineDefinition,\n StoredPipelineDefinitionStep,\n StoredPipelineEvent,\n StoredPipelineRun,\n} from \"./run-store.js\";\n\nfunction definitionStep(\n event: Extract<StoredPipelineEvent, { name: \"step.planned\" }>\n): StoredPipelineDefinitionStep {\n const step: StoredPipelineDefinitionStep = {\n dependencies: [...event.payload.dependencies],\n dryRun: event.payload.dryRun,\n id: event.stepId,\n optionalDependencies: [...event.payload.optionalDependencies],\n runtimeSkipPossible: event.payload.runtimeSkipPossible,\n skipAfterFailureOf: [...event.payload.skipAfterFailureOf],\n };\n const description = event.payload.description;\n if (description) step.description = description;\n const name = event.payload.name;\n if (name) step.name = name;\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 step;\n}\n\n/** Own observed definition replacement independently of run execution state. */\nexport class DefinitionProjection {\n #snapshot?: PipelineDefinitionSnapshot;\n #definitionRun: { id: string; startedAtMs: number; startedEventId: number } | undefined;\n #firstSeenAtMs: number;\n #lastSeenAtMs: number;\n readonly #latestSteps = new Map<string, StoredPipelineDefinitionStep>();\n readonly #runStarts = new Map<string, { atMs: number; eventId: number; targetIds: string[] }>();\n #targetIds: string[] = [];\n\n constructor(event: StoredPipelineEvent) {\n this.#firstSeenAtMs = event.timestampMs;\n this.#lastSeenAtMs = event.timestampMs;\n this.append(event);\n }\n\n append(event: StoredPipelineEvent): void {\n this.#firstSeenAtMs = Math.min(this.#firstSeenAtMs, event.timestampMs);\n this.#lastSeenAtMs = Math.max(this.#lastSeenAtMs, event.timestampMs);\n if (event.name === \"pipeline.started\") {\n if (event.payload.definitionSnapshot)\n this.#snapshot = structuredClone(event.payload.definitionSnapshot);\n this.#runStarts.set(event.runId, {\n atMs: event.timestampMs,\n eventId: event.id,\n targetIds: [...event.payload.targetIds],\n });\n }\n if (event.name !== \"step.planned\" || !event.stepId) return;\n const start = this.#runStarts.get(event.runId);\n if (!start) return;\n const current = this.#definitionRun;\n if (\n !current ||\n start.atMs > current.startedAtMs ||\n (start.atMs === current.startedAtMs && start.eventId > current.startedEventId)\n ) {\n this.#definitionRun = {\n id: event.runId,\n startedAtMs: start.atMs,\n startedEventId: start.eventId,\n };\n this.#latestSteps.clear();\n this.#targetIds = start.targetIds;\n }\n if (event.runId === this.#definitionRun?.id) {\n this.#latestSteps.set(event.stepId, definitionStep(event));\n }\n }\n\n snapshot(pipelineRuns: readonly StoredPipelineRun[]): StoredPipelineDefinition {\n const identity = pipelineRuns[0]!.definitionIdentity;\n const snapshot = this.#snapshot;\n return {\n activeRuns: pipelineRuns.filter(({ status }) => status === \"running\").length,\n firstSeenAtMs: this.#firstSeenAtMs,\n lastSeenAtMs: this.#lastSeenAtMs,\n pipelineId: pipelineRuns[0]!.pipelineId,\n ...(identity ? { identity: { ...identity } } : {}),\n ...(snapshot ? { snapshot: structuredClone(snapshot) } : {}),\n runCount: pipelineRuns.length,\n steps: [...this.#latestSteps.values()].map((step) => structuredClone(step)),\n targetIds: [...(snapshot?.targetIds ?? this.#targetIds)],\n };\n }\n}\n"]}
@@ -0,0 +1,15 @@
1
+ import type { StoredPipelineEvent, StoredPipelineRun } from "./run-store.js";
2
+ /** Own the mutable state of one recorded run. */
3
+ export declare class RunProjection {
4
+ #private;
5
+ private readonly options;
6
+ constructor(event: StoredPipelineEvent, options?: {
7
+ readonly retainLogs?: boolean;
8
+ readonly retainArtifacts?: boolean;
9
+ });
10
+ get definitionId(): string | undefined;
11
+ append(event: StoredPipelineEvent): void;
12
+ snapshot(): StoredPipelineRun;
13
+ }
14
+ /** Fold one run's append-only events into a UI-friendly current snapshot. */
15
+ export declare function projectPipelineRun(events: readonly StoredPipelineEvent[]): StoredPipelineRun;
@@ -0,0 +1,203 @@
1
+ import { RUN_MODEL_VERSION } from "../core/pipeline-ids.js";
2
+ import { hasVisibleStepProgress } from "../core/progress.js";
3
+ function terminalStepStatus(event) {
4
+ switch (event.name) {
5
+ case "step.cancelled":
6
+ return "cancelled";
7
+ case "step.complete":
8
+ // Shipped trace name; projected snapshot uses the live success token.
9
+ return "completed";
10
+ case "step.failed":
11
+ return "failed";
12
+ case "step.skipped":
13
+ return "skipped";
14
+ default:
15
+ return undefined;
16
+ }
17
+ }
18
+ function attemptStatus(status) {
19
+ return status === "planned" ? "running" : status;
20
+ }
21
+ /** Own the mutable state of one recorded run. */
22
+ export class RunProjection {
23
+ options;
24
+ #completed;
25
+ #eventCount = 0;
26
+ #identity;
27
+ #logCount = 0;
28
+ #logs = [];
29
+ #startedAtMs;
30
+ #startObserved = false;
31
+ #dryRun = false;
32
+ #definitionIdentity;
33
+ #steps = new Map();
34
+ constructor(event, options = {}) {
35
+ this.options = options;
36
+ this.#identity = {
37
+ pipelineId: event.pipelineId,
38
+ runId: event.runId,
39
+ correlationId: event.correlationId,
40
+ parentRunId: event.parentRunId,
41
+ iteration: event.iteration ? { ...event.iteration } : undefined,
42
+ };
43
+ this.#startedAtMs = event.timestampMs;
44
+ this.append(event);
45
+ }
46
+ get definitionId() {
47
+ return this.#definitionIdentity?.definitionId;
48
+ }
49
+ append(event) {
50
+ this.#eventCount += 1;
51
+ if (event.name === "pipeline.started" && !this.#startObserved) {
52
+ this.#startObserved = true;
53
+ this.#startedAtMs = event.timestampMs;
54
+ this.#dryRun = event.payload.dryRun;
55
+ this.#definitionIdentity = event.payload.definitionIdentity
56
+ ? { ...event.payload.definitionIdentity }
57
+ : undefined;
58
+ }
59
+ if (event.name === "pipeline.completed") {
60
+ this.#completed = {
61
+ status: event.payload.status,
62
+ timestampMs: event.timestampMs,
63
+ durationMs: event.durationMs,
64
+ error: event.error ? structuredClone(event.error) : undefined,
65
+ };
66
+ }
67
+ if (event.name === "pipeline.log") {
68
+ this.#logCount += 1;
69
+ if (this.options.retainLogs === false)
70
+ return;
71
+ const log = {
72
+ id: event.id,
73
+ level: event.payload.level,
74
+ message: event.payload.message,
75
+ timestampMs: event.timestampMs,
76
+ };
77
+ if (event.attemptId)
78
+ log.attemptId = event.attemptId;
79
+ if (event.stepId)
80
+ log.stepId = event.stepId;
81
+ this.#logs.push(log);
82
+ return;
83
+ }
84
+ if (!event.stepId || !event.name.startsWith("step."))
85
+ return;
86
+ let step = this.#steps.get(event.stepId);
87
+ if (!step) {
88
+ step = { id: event.stepId, status: "planned" };
89
+ this.#steps.set(event.stepId, step);
90
+ }
91
+ if (event.name === "step.planned") {
92
+ step.name = event.payload.name;
93
+ step.description = event.payload.description;
94
+ if (event.payload.nestedPipeline) {
95
+ step.nestedPipeline = {
96
+ ...event.payload.nestedPipeline,
97
+ stepIds: [...event.payload.nestedPipeline.stepIds],
98
+ };
99
+ }
100
+ if (event.payload.remote)
101
+ step.remote = { ...event.payload.remote };
102
+ return;
103
+ }
104
+ if (event.name === "step.artifact") {
105
+ if (this.options.retainArtifacts === false)
106
+ return;
107
+ (step.artifacts ??= []).push({
108
+ ...structuredClone(event.payload),
109
+ attemptId: event.attemptId,
110
+ timestampMs: event.timestampMs,
111
+ });
112
+ return;
113
+ }
114
+ if ("outputSource" in event.payload && event.payload.outputSource === "override") {
115
+ step.outputSource = "override";
116
+ }
117
+ if (event.attemptId) {
118
+ let attempt = step.attempt;
119
+ if (!attempt) {
120
+ attempt = {
121
+ attemptId: event.attemptId,
122
+ retries: [],
123
+ startedAtMs: event.timestampMs,
124
+ status: "running",
125
+ };
126
+ step.attempt = attempt;
127
+ }
128
+ if (step.outputSource)
129
+ attempt.outputSource = step.outputSource;
130
+ if (event.name === "step.attempted") {
131
+ attempt.retries.push(event.payload.attempt);
132
+ }
133
+ const terminal = terminalStepStatus(event);
134
+ if (terminal) {
135
+ attempt.status = attemptStatus(terminal);
136
+ attempt.finishedAtMs = event.timestampMs;
137
+ attempt.durationMs = event.durationMs;
138
+ }
139
+ }
140
+ if (event.name === "step.running") {
141
+ step.status = "running";
142
+ step.startedAtMs ??= event.timestampMs;
143
+ if (event.payload.progress) {
144
+ const progress = {
145
+ ...event.payload.progress,
146
+ details: event.payload.progress.details?.map((detail) => ({ ...detail })),
147
+ };
148
+ if (!step.progress || hasVisibleStepProgress(progress))
149
+ step.progress = progress;
150
+ }
151
+ return;
152
+ }
153
+ const terminal = terminalStepStatus(event);
154
+ if (terminal) {
155
+ step.status = terminal;
156
+ step.finishedAtMs = event.timestampMs;
157
+ step.durationMs = event.durationMs;
158
+ if (event.durationMs !== undefined)
159
+ step.startedAtMs = event.timestampMs - event.durationMs;
160
+ }
161
+ }
162
+ snapshot() {
163
+ const completed = this.#completed;
164
+ const run = {
165
+ dryRun: this.#dryRun,
166
+ eventCount: this.#eventCount,
167
+ logCount: this.#logCount,
168
+ logs: this.options.retainLogs === false ? [] : this.#logs.map((log) => ({ ...log })),
169
+ pipelineId: this.#identity.pipelineId,
170
+ runId: this.#identity.runId,
171
+ startedAtMs: this.#startedAtMs,
172
+ status: completed?.status ?? "running",
173
+ steps: [...this.#steps.values()].map((step) => structuredClone(step)),
174
+ version: RUN_MODEL_VERSION,
175
+ };
176
+ if (this.#definitionIdentity)
177
+ run.definitionIdentity = { ...this.#definitionIdentity };
178
+ if (this.#identity.correlationId !== undefined)
179
+ run.correlationId = this.#identity.correlationId;
180
+ if (completed?.durationMs !== undefined)
181
+ run.durationMs = completed.durationMs;
182
+ if (completed?.error)
183
+ run.error = structuredClone(completed.error);
184
+ if (completed)
185
+ run.finishedAtMs = completed.timestampMs;
186
+ if (this.#identity.parentRunId)
187
+ run.parentRunId = this.#identity.parentRunId;
188
+ if (this.#identity.iteration)
189
+ run.iteration = { ...this.#identity.iteration };
190
+ return run;
191
+ }
192
+ }
193
+ /** Fold one run's append-only events into a UI-friendly current snapshot. */
194
+ export function projectPipelineRun(events) {
195
+ if (events.length === 0)
196
+ throw new Error("Cannot project an empty pipeline run event list.");
197
+ const ordered = [...events].sort((left, right) => left.id - right.id);
198
+ const projection = new RunProjection(ordered[0]);
199
+ for (const event of ordered.slice(1))
200
+ projection.append(event);
201
+ return projection.snapshot();
202
+ }
203
+ //# sourceMappingURL=run-projection.js.map
@@ -0,0 +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"]}
@@ -2,3 +2,5 @@ export declare function isDefinitionIdentity(value: unknown): boolean;
2
2
  export declare function isDefinitionSnapshot(value: unknown): boolean;
3
3
  /** Validate a projected trace error at the Studio transport boundary. */
4
4
  export declare function isPipelineTraceError(value: unknown): boolean;
5
+ /** Validate artifact metadata received in a Studio step projection. */
6
+ export declare function isArtifactRecord(value: unknown): boolean;