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.
Files changed (125) hide show
  1. package/dist/cli/cli-pipeline-command.d.ts +7 -2
  2. package/dist/cli/cli-pipeline-command.js +24 -3
  3. package/dist/cli/cli-pipeline-command.js.map +1 -1
  4. package/dist/core/child-execution.js +5 -3
  5. package/dist/core/child-execution.js.map +1 -1
  6. package/dist/core/child-progress.js +2 -0
  7. package/dist/core/child-progress.js.map +1 -1
  8. package/dist/core/pipeline-cache.d.ts +68 -0
  9. package/dist/core/pipeline-cache.js +157 -0
  10. package/dist/core/pipeline-cache.js.map +1 -0
  11. package/dist/core/pipeline-compiler.js +4 -2
  12. package/dist/core/pipeline-compiler.js.map +1 -1
  13. package/dist/core/pipeline-definition-identity.d.ts +3 -1
  14. package/dist/core/pipeline-definition-identity.js +38 -5
  15. package/dist/core/pipeline-definition-identity.js.map +1 -1
  16. package/dist/core/pipeline-definition-validation.d.ts +7 -2
  17. package/dist/core/pipeline-definition-validation.js +22 -2
  18. package/dist/core/pipeline-definition-validation.js.map +1 -1
  19. package/dist/core/pipeline-definition.d.ts +6 -0
  20. package/dist/core/pipeline-definition.js.map +1 -1
  21. package/dist/core/pipeline-execute.js +5 -0
  22. package/dist/core/pipeline-execute.js.map +1 -1
  23. package/dist/core/pipeline-graph.d.ts +2 -1
  24. package/dist/core/pipeline-graph.js +10 -4
  25. package/dist/core/pipeline-graph.js.map +1 -1
  26. package/dist/core/pipeline-mermaid.js +7 -1
  27. package/dist/core/pipeline-mermaid.js.map +1 -1
  28. package/dist/core/pipeline-plan.js +4 -0
  29. package/dist/core/pipeline-plan.js.map +1 -1
  30. package/dist/core/pipeline-query.d.ts +11 -0
  31. package/dist/core/pipeline-query.js +10 -0
  32. package/dist/core/pipeline-query.js.map +1 -0
  33. package/dist/core/pipeline-run-state.d.ts +2 -2
  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 +24 -9
  37. package/dist/core/pipeline-step-executor.js.map +1 -1
  38. package/dist/core/pipeline-step-metadata.d.ts +1 -0
  39. package/dist/core/pipeline-step-metadata.js +1 -0
  40. package/dist/core/pipeline-step-metadata.js.map +1 -1
  41. package/dist/core/pipeline-steps.d.ts +17 -3
  42. package/dist/core/pipeline-steps.js +11 -3
  43. package/dist/core/pipeline-steps.js.map +1 -1
  44. package/dist/core/pipeline-types.d.ts +20 -7
  45. package/dist/core/pipeline-types.js.map +1 -1
  46. package/dist/core/pipeline.d.ts +4 -0
  47. package/dist/core/pipeline.js +7 -1
  48. package/dist/core/pipeline.js.map +1 -1
  49. package/dist/node/node.d.ts +1 -0
  50. package/dist/node/node.js +1 -0
  51. package/dist/node/node.js.map +1 -1
  52. package/dist/reporter/interactive-reporter.js +3 -4
  53. package/dist/reporter/interactive-reporter.js.map +1 -1
  54. package/dist/reporter/reporter.d.ts +1 -0
  55. package/dist/reporter/reporter.js +4 -2
  56. package/dist/reporter/reporter.js.map +1 -1
  57. package/dist/run-store/cache-artifact.d.ts +7 -0
  58. package/dist/run-store/cache-artifact.js +22 -0
  59. package/dist/run-store/cache-artifact.js.map +1 -0
  60. package/dist/run-store/definition-diff.js +20 -8
  61. package/dist/run-store/definition-diff.js.map +1 -1
  62. package/dist/run-store/run-projection.js +2 -2
  63. package/dist/run-store/run-projection.js.map +1 -1
  64. package/dist/run-store/run-store.d.ts +2 -2
  65. package/dist/run-store/run-store.js.map +1 -1
  66. package/dist/studio/run-store-ui-artifacts.d.ts +5 -0
  67. package/dist/studio/run-store-ui-artifacts.js +18 -0
  68. package/dist/studio/run-store-ui-artifacts.js.map +1 -0
  69. package/dist/studio/run-store-ui-client-browser.js +2 -2
  70. package/dist/studio/run-store-ui-client-transport.js +9 -3
  71. package/dist/studio/run-store-ui-client-transport.js.map +1 -1
  72. package/dist/studio/run-store-ui-client.d.ts +2 -2
  73. package/dist/studio/run-store-ui-client.js +13 -7
  74. package/dist/studio/run-store-ui-client.js.map +1 -1
  75. package/dist/studio/run-store-ui-definitions.js +2 -1
  76. package/dist/studio/run-store-ui-definitions.js.map +1 -1
  77. package/dist/studio/run-store-ui-metadata.d.ts +13 -0
  78. package/dist/studio/run-store-ui-metadata.js +32 -0
  79. package/dist/studio/run-store-ui-metadata.js.map +1 -0
  80. package/dist/studio/run-store-ui-page.js +8 -0
  81. package/dist/studio/run-store-ui-page.js.map +1 -1
  82. package/dist/tracing/artifact-metadata.d.ts +1 -0
  83. package/dist/tracing/artifact-metadata.js +2 -2
  84. package/dist/tracing/artifact-metadata.js.map +1 -1
  85. package/dist/tracing/graph-metadata.d.ts +12 -0
  86. package/dist/tracing/graph-metadata.js +55 -0
  87. package/dist/tracing/graph-metadata.js.map +1 -0
  88. package/dist/tracing/tracing-internal.js +2 -2
  89. package/dist/tracing/tracing-internal.js.map +1 -1
  90. package/dist/tracing/tracing-schema.d.ts +58 -31
  91. package/dist/tracing/tracing-schema.js +26 -8
  92. package/dist/tracing/tracing-schema.js.map +1 -1
  93. package/dist/utilities/cache-duration.d.ts +2 -0
  94. package/dist/utilities/cache-duration.js +39 -0
  95. package/dist/utilities/cache-duration.js.map +1 -0
  96. package/dist/utilities/cache-key.d.ts +2 -0
  97. package/dist/utilities/cache-key.js +63 -0
  98. package/dist/utilities/cache-key.js.map +1 -0
  99. package/dist/utilities/cache-storage.d.ts +6 -0
  100. package/dist/utilities/cache-storage.js +83 -0
  101. package/dist/utilities/cache-storage.js.map +1 -0
  102. package/dist/utilities/canonical-json.d.ts +2 -0
  103. package/dist/utilities/canonical-json.js +12 -0
  104. package/dist/utilities/canonical-json.js.map +1 -0
  105. package/dist/workbench/workbench-commands.js +43 -3
  106. package/dist/workbench/workbench-commands.js.map +1 -1
  107. package/dist/workbench/workbench-history.js +2 -1
  108. package/dist/workbench/workbench-history.js.map +1 -1
  109. package/docs/agent-guide.md +23 -0
  110. package/docs/api-reference.md +98 -85
  111. package/docs/api-report.json +19 -6
  112. package/docs/artifacts.md +6 -2
  113. package/docs/cli.md +14 -0
  114. package/docs/concepts.md +10 -0
  115. package/docs/declarative-pipelines.md +4 -0
  116. package/docs/graph-metadata.md +108 -0
  117. package/docs/llms.txt +2 -0
  118. package/docs/recipes.md +5 -0
  119. package/docs/step-output-cache.md +242 -0
  120. package/docs/studio.md +11 -2
  121. package/examples/graph-metadata.ts +32 -0
  122. package/examples/project/tubeless.project.ts +5 -0
  123. package/examples/step-output-cache.ts +30 -0
  124. package/package.json +1 -1
  125. 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 !== "planned" && state.outputSource === "override" ? " (overridden)" : "");
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":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAUnC,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAmB,MAAM,kBAAkB,CAAC;AACrE,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,GAGjB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA0DvE,SAAS,sBAAsB,CAAC,MAAsB,EAAE,MAA8B;IACpF,MAAM,KAAK,GAAG,MAAM,CAAC,QAAQ,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;IAC9D,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IAC1B,MAAM,IAAI,GAAG,EAAE,KAAK,SAAS,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,OAAO,CAAC;IAC3E,OAAO,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC;AACvD,CAAC;AAED,SAAS,WAAW,CAClB,MAAsB,EACtB,MAA8B;IAE9B,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa;QAAE,OAAO,aAAa,CAAC;IACxD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5C,OAAO,sBAAsB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC;AAC1E,CAAC;AAED,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,SAAS,cAAc,CAAC,QAA8B,EAAE,KAAa,EAAE,OAAgB;IACrF,4EAA4E;IAC5E,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACjF,IAAI,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACpE,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC;IACpE,CAAC;IACD,MAAM,SAAS,GAAG,UAAU,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACjD,MAAM,KAAK,GAAG,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;IACzC,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,GAC9D,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,MAAM,CAClE,EAAE,CAAC;IACH,OAAO,IAAI,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,WAAW,CAAC,SAAS,CAAC,IAAI,WAAW,CAAC,KAAK,CAAC,GAAG,OAAO,EAAE,CAAC;AAC1G,CAAC;AAED,SAAS,oBAAoB,CAC3B,MAA4D,EAC5D,KAAoB,EACpB,OAAe,EACf,gBAAwB,EACxB,YAA0C;IAE1C,MAAM,MAAM,GACV,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,KAAK,SAAS,IAAI,YAAY,KAAK,SAAS;QACtE,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,CAAC,CAAC;IACnC,MAAM,MAAM,GACV,MAAM,KAAK,WAAW;QACpB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAC/C,CAAC,CAAC,MAAM,KAAK,QAAQ;YACnB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YACvC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,WAAW;gBAC9C,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;gBACvC,CAAC,CAAC,MAAM,KAAK,SAAS;oBACpB,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;oBACjD,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,gBAAgB,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC;IACtD,MAAM,KAAK,GACT,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACpD,CAAC,MAAM,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC9D,MAAM,SAAS,GAAG,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;IAC3F,MAAM,OAAO,GAAG,MAAM,KAAK,SAAS,CAAC;IACrC,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,MAAM,WAAW,GACf,OAAO,IAAI,KAAK,CAAC,YAAY;QAC3B,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC;QACpB,CAAC,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC3E,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,QAAQ,GACZ,MAAM,CAAC,SAAS,KAAK,SAAS;QAC5B,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,IAAI,cAAc,CAChB,EAAE,SAAS,EAAE,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EACpD,gBAAgB,EAChB,KAAK,CAAC,cAAc,CACrB,EAAE,CAAC;IACV,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,MAAM,IAAI,WAAW,GAAG,QAAQ,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,UAAU,CACjB,KAAgB,EAChB,KAAoB,EACpB,OAAe,EACf,gBAAwB;IAExB,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC;IACvB,MAAM,WAAW,GACf,gBAAgB,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,EAAE,CAAC;QACtC,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3F,QAAQ,KAAK,CAAC,MAAM,EAAE,CAAC;QACrB,KAAK,SAAS,EAAE,CAAC;YACf,MAAM,QAAQ,GACZ,KAAK,CAAC,QAAQ,IAAI,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC;gBACtD,CAAC,CAAC,IAAI,cAAc,CAAC,KAAK,CAAC,QAAQ,EAAE,gBAAgB,EAAE,KAAK,CAAC,cAAc,CAAC,EAAE;gBAC9E,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,OAAO,GACX,KAAK,CAAC,WAAW,KAAK,SAAS;gBAC7B,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,EAAE;gBAC9D,CAAC,CAAC,EAAE,CAAC;YACT,MAAM,KAAK,GAAG;gBACZ,KAAK,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,YAAY,CAAC,WAAW,CAAC,GAAG,QAAQ,GAAG,OAAO,EAAE;aACrF,CAAC;YACF,OAAO,KAAK,CAAC;QACf,CAAC;QACD,KAAK,WAAW;YACd,OAAO;gBACL,KAAK,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CACxF,IAAI,gBAAgB,CAAC,KAAK,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,CAChE,EAAE;aACJ,CAAC;QACJ,KAAK,QAAQ;YACX,OAAO;gBACL,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,WAAW,KAAK,gBAAgB,CAC5E,KAAK,CAAC,KAAK,CAAC,OAAO,CACpB,EAAE;aACJ,CAAC;QACJ,KAAK,WAAW;YACd,OAAO;gBACL,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,WAAW,gBAAgB,gBAAgB,CACvF,KAAK,CAAC,KAAK,CAAC,OAAO,CACpB,EAAE;aACJ,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO;gBACL,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,QAAQ,CAChF,IAAI,gBAAgB,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CACvD,EAAE;aACJ,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO;gBACL,KAAK,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,CAAC,EAAE;aAC7G,CAAC;IACN,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CAAC,MAAsB;IAC9C,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IACpF,OAAO,EAAE,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9E,CAAC;AAED,SAAS,yBAAyB,CAChC,OAAgC,EAChC,MAAsB;IAEtB,MAAM,aAAa,GAAG,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;IACvE,MAAM,KAAK,GAAG,mBAAmB,CAAC;QAChC,GAAG,OAAO;QACV,QAAQ,EAAE,EAAE,KAAK,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,QAAQ,EAAE;KACxD,CAAC,CAAC;IACH,MAAM,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,CAAC;IACjF,yEAAyE;IACzE,MAAM,iBAAiB,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,CAAC;IACpF,MAAM,KAAK,GAAG,IAAI,GAAG,EAAqB,CAAC;IAC3C,MAAM,UAAU,GAAa,EAAE,CAAC;IAChC,IAAI,IAA8B,CAAC;IACnC,IAAI,MAAwC,CAAC;IAC7C,IAAI,QAAQ,GAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjD,IAAI,oBAAoB,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACpD,IAAI,aAAa,GAAG,KAAK,CAAC;IAC1B,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,MAA8B,CAAC;IACnC,IAAI,aAAwD,CAAC;IAC7D,IAAI,YAAsC,CAAC;IAC3C,IAAI,YAA4C,CAAC;IAEjD,MAAM,UAAU,GAAG,GAAa,EAAE;QAChC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QACrB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,OAAO,CAAC,OAAO,KAAK,KAAK,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM;gBACnB,CAAC,CAAC,OAAO,CAAC,UAAU,KAAK,KAAK;oBAC5B,CAAC,CAAC,YAAY,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE;oBACnD,CAAC,CAAC,YAAY,gBAAgB,CAAC,MAAM,CAAC,UAAU,CAAC,aAAa,gBAAgB,CAAC,MAAM,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC,YAAY,MAAM,CAAC,MAAM,WAAW,MAAM,CAAC,KAAK,CAAC,MAAM,YAAY,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG;gBACpN,CAAC,CAAC,YAAY,gBAAgB,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,kBAAkB,IAAI,CAAC,MAAM,GAAG,CAAC;YACxG,KAAK,CAAC,IAAI,CACR,MAAM,EAAE,MAAM,KAAK,WAAW;gBAC5B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC/B,CAAC,CAAC,MAAM;oBACN,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC;oBAC3B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CACpC,CAAC;QACJ,CAAC;QACD,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACnC,KAAK,CAAC,IAAI,CAAC,GAAG,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC;YACzE,KAAK,MAAM,MAAM,IAAI,KAAK,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;gBACzC,KAAK,CAAC,IAAI,CACR,oBAAoB,CAAC,MAAM,EAAE,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,KAAK,CAAC,MAAM,CAAC,CACnF,CAAC;YACJ,CAAC;QACH,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,aAAa,CAAC,IAAI,YAAY,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;YAC3C,KAAK,CAAC,IAAI,CACR,KAAK,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,aAAa,KAAK,CAAC,MAAM,CAAC,QAAQ,CAClF,IAAI,gBAAgB,CAAC,QAAQ,CAAC,UAAU,CAAC,GAAG,CAC7C,EAAE,CACJ,CAAC;QACJ,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxC,KAAK,CAAC,IAAI,CACR,KAAK,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,cAAc,gBAAgB,CACtE,QAAQ,CAAC,KAAK,CAAC,OAAO,CACvB,EAAE,CACJ,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;IAEF,MAAM,YAAY,GAAG,GAAe,EAAE;QACpC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,GAAG,gBAAgB,CAAC;gBACxB,KAAK,EAAE,KAAK,CAAC,YAAY;gBACzB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,UAAU,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO;gBAChC,EAAE,EAAE,gBAAgB,CAAC,MAAM,CAAC;gBAC5B,iBAAiB;gBACjB,OAAO,EAAE,KAAK,CAAC,cAAc;gBAC7B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE;oBACf,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;aACF,CAAC,CAAC;QACL,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;IAEF,MAAM,cAAc,GAAG,GAAY,EAAE,CACnC,IAAI,KAAK,SAAS;QAClB,CAAC,MAAM;QACP,OAAO,CAAC,OAAO,KAAK,KAAK;QACzB,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,CAAC,IAAI,GAAG;QAC5B,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;IAE1B,MAAM,MAAM,GAAG,GAAS,EAAE;QACxB,IAAI,QAAQ;YAAE,OAAO;QACrB,MAAM,KAAK,GAAG,UAAU,EAAE,CAAC;QAC3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;YAC5C,MAAM,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QACzB,MAAM,OAAO,GAAG,cAAc,EAAE;YAC9B,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC;gBACrB,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACjD,CAAC,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,qBAAqB,CAAC;YACxE,CAAC,CAAC,SAAS,CAAC;QACd,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,GAAG,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;YAC1D,YAAY,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACxC,OAAO;QACT,CAAC;QACD,IAAI,MAAM,EAAE,CAAC;YACX,+EAA+E;YAC/E,YAAY,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC5B,YAAY,EAAE,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjD,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QACpD,IAAI,IAAI,GAAG,CAAC,EAAE,CAAC;YACb,YAAY,EAAE,CAAC,QAAQ,CACrB,CAAC,KAAK,CAAC,CAAC,CAAE,EAAE,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,eAAe,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CACjF,CAAC;YACF,OAAO;QACT,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC;QAC3B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,KAAK,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC;YAC5C,IAAI,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC;gBAAE,KAAK,GAAG,KAAK,CAAC;QAClD,CAAC;QACD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CACpB,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,SAAS,EAAE,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC,CAAC,CACtE,CAAC;QACF,MAAM,GAAG,GAAG,KAAK,GAAG,SAAS,CAAC;QAC9B,MAAM,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,CAAE,CAAC,CAAC;QAC5B,IAAI,KAAK,GAAG,CAAC;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,KAAK,GAAG,CAAC,aAAa,CAAC,CAAC;QACrE,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,CAAC;QACzC,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM;YAAE,OAAO,CAAC,IAAI,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,GAAG,aAAa,CAAC,CAAC;QACvF,YAAY,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC,CAAC;IAEF,MAAM,aAAa,GAAG,GAAS,EAAE;QAC/B,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,YAAY,CAAC,aAAa,CAAC,CAAC;YAC5B,aAAa,GAAG,SAAS,CAAC;QAC5B,CAAC;QACD,IAAI,CAAC,aAAa;YAAE,OAAO;QAC3B,aAAa,GAAG,KAAK,CAAC;QACtB,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,EAAE,CAAC;IACX,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAS,EAAE;QACzB,IAAI,QAAQ;YAAE,OAAO;QACrB,QAAQ,GAAG,IAAI,CAAC;QAChB,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;YAChC,YAAY,CAAC,aAAa,CAAC,CAAC;YAC5B,aAAa,GAAG,SAAS,CAAC;QAC5B,CAAC;QACD,MAAM,EAAE,OAAO,EAAE,CAAC;QAClB,MAAM,GAAG,SAAS,CAAC;QACnB,IAAI,YAAY;YAAE,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACpD,YAAY,GAAG,SAAS,CAAC;QACzB,YAAY,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;QACpC,YAAY,GAAG,SAAS,CAAC;IAC3B,CAAC,CAAC;IAEF,MAAM,QAAQ,GAAG,CAAC,KAA+B,EAAE,OAAiB,EAAE,GAAG,IAAe,EAAE,EAAE;QAC1F,MAAM,QAAQ,GAAG,OAAO,KAAK,SAAS,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QAC5F,MAAM,YAAY,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC/C,MAAM,MAAM,GACV,KAAK,KAAK,OAAO;YACf,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG;YAC7C,CAAC,CAAC,KAAK,KAAK,MAAM;gBAChB,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG;gBAC9B,CAAC,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,GAAG,GAAG,MAAM,GAAG,YAAY,IAAI,CAAC;QAC1C,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACnB,OAAO;QACT,CAAC;QACD,8EAA8E;QAC9E,UAAU,CAAC,IAAI,CACb,GAAG,GAAG,MAAM,GAAG,YAAY,EAAE;aAC1B,KAAK,CAAC,IAAI,CAAC;aACX,KAAK,CAAC,CAAC,CAAC,CAAC;aACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,CACtC,CAAC;QACF,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,cAAc,EAAE;YAAE,YAAY,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrD,aAAa,GAAG,KAAK,CAAC;QACtB,oBAAoB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,EAAE,CAAC;IACX,CAAC,CAAC;IAEF,MAAM,GAAG,GAAmB;QAC1B,KAAK,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAChE,GAAG,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;QAC5D,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;KAC/D,CAAC;IAEF,MAAM,KAAK,GAA2B;QACpC,eAAe,EAAE,CAAC,QAAQ,EAAE,EAAE;YAC5B,IAAI,GAAG,QAAQ,CAAC;YAChB,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;gBAClC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACnF,CAAC;YACD,IAAI,MAAM,KAAK,OAAO,CAAC,MAAM,IAAI,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;gBAC3D,YAAY,GAAG,OAAO,CAAC;gBACvB,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;gBACnC,YAAY,GAAG,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;gBAC3E,YAAY,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;YACpC,CAAC;YACD,MAAM,EAAE,CAAC;QACX,CAAC;QACD,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE;YACtB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC1C,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC/B,uEAAuE;gBACvE,sEAAsE;gBACtE,MAAM,QAAQ,GACZ,KAAK,CAAC,QAAQ,IAAI,sBAAsB,CAAC,KAAK,CAAC,QAAQ,CAAC;oBACtD,CAAC,CAAC,KAAK,CAAC,QAAQ;oBAChB,CAAC,CAAC,QAAQ,EAAE,MAAM,KAAK,SAAS;wBAC9B,CAAC,CAAC,QAAQ,CAAC,QAAQ;wBACnB,CAAC,CAAC,SAAS,CAAC;gBAClB,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE;oBACvB,GAAG,KAAK;oBACR,QAAQ;oBACR,OAAO,EAAE,QAAQ,EAAE,OAAO;oBAC1B,WAAW,EAAE,QAAQ,EAAE,WAAW,IAAI,IAAI,CAAC,GAAG,EAAE;iBACjD,CAAC,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;gBACvB,IAAI,GAAG,GAAG,oBAAoB,IAAI,iBAAiB,EAAE,CAAC;oBACpD,aAAa,GAAG,KAAK,CAAC;oBACtB,oBAAoB,GAAG,GAAG,CAAC;oBAC3B,MAAM,EAAE,CAAC;gBACX,CAAC;qBAAM,CAAC;oBACN,aAAa,GAAG,IAAI,CAAC;oBACrB,aAAa,KAAK,UAAU,CAC1B,GAAG,EAAE;wBACH,aAAa,GAAG,SAAS,CAAC;wBAC1B,IAAI,CAAC,QAAQ;4BAAE,aAAa,EAAE,CAAC;oBACjC,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,iBAAiB,GAAG,CAAC,GAAG,GAAG,oBAAoB,CAAC,CAAC,CAC9D,CAAC;oBACF,aAAa,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC1B,CAAC;gBACD,OAAO;YACT,CAAC;YACD,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS;gBAAE,aAAa,EAAE,CAAC;YAChD,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;YACnE,MAAM,EAAE,CAAC;QACX,CAAC;QACD,eAAe,EAAE,GAAG,EAAE;YACpB,QAAQ,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YACjC,MAAM,EAAE,CAAC;QACX,CAAC;QACD,kBAAkB,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE;YACrC,QAAQ,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;YAC/C,MAAM,EAAE,CAAC;QACX,CAAC;QACD,eAAe,EAAE,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE;YACzC,QAAQ,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;YACnD,MAAM,EAAE,CAAC;QACX,CAAC;QACD,kBAAkB,EAAE,CAAC,UAAU,EAAE,EAAE;YACjC,MAAM,GAAG,UAAU,CAAC;YACpB,MAAM,EAAE,CAAC;YACT,OAAO,EAAE,CAAC;QACZ,CAAC;KACF,CAAC;IAEF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC;AACtD,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,sBAAsB,CACpC,OAAgC;IAEhC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;IAChD,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,IAAI,IAAI,KAAK,aAAa,EAAE,CAAC;QAC3B,OAAO,yBAAyB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;IACD,OAAO;QACL,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS;QACxB,KAAK,EAAE,iBAAiB,CAAU,OAAO,CAAC;QAC1C,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,IAAI,EAAE,OAAO;KACd,CAAC;AACJ,CAAC","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("Required edges", old.dependencies, step.dependencies, step.id);
29
- compare("Optional edges", old.optionalDependencies, step.optionalDependencies, step.id);
30
- compare("Failure gates", old.skipAfterFailureOf, step.skipAfterFailureOf, step.id);
31
- compare("Dry-run policy", old.dryRun, step.dryRun, step.id);
32
- compare("Skip policy", old.runtimeSkipPossible, step.runtimeSkipPossible, step.id);
33
- compare("Output validation", old.outputValidated, step.outputValidated, step.id);
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":"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","sourcesContent":["import 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/** 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(\"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(\"Required edges\", old.dependencies, step.dependencies, step.id);\n compare(\"Optional edges\", old.optionalDependencies, step.optionalDependencies, step.id);\n compare(\"Failure gates\", old.skipAfterFailureOf, step.skipAfterFailureOf, step.id);\n compare(\"Dry-run policy\", old.dryRun, step.dryRun, step.id);\n compare(\"Skip policy\", old.runtimeSkipPossible, step.runtimeSkipPossible, step.id);\n compare(\"Output validation\", old.outputValidated, step.outputValidated, step.id);\n compare(\"Child pipeline\", old.nestedPipeline, step.nestedPipeline, step.id);\n compare(\"Remote adapter\", old.remote, step.remote, step.id);\n }\n return changes;\n}\n"]}
1
+ {"version":3,"file":"definition-diff.js","sourceRoot":"","sources":["../../src/run-store/definition-diff.ts"],"names":[],"mappings":"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","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 === "override") {
115
- step.outputSource = "override";
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":"AAEA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAU7D,SAAS,kBAAkB,CAAC,KAA0B;IACpD,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;QACnB,KAAK,gBAAgB;YACnB,OAAO,WAAW,CAAC;QACrB,KAAK,eAAe;YAClB,sEAAsE;YACtE,OAAO,WAAW,CAAC;QACrB,KAAK,aAAa;YAChB,OAAO,QAAQ,CAAC;QAClB,KAAK,cAAc;YACjB,OAAO,SAAS,CAAC;QACnB;YACE,OAAO,SAAS,CAAC;IACrB,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,MAAoC;IACzD,OAAO,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;AACnD,CAAC;AAED,iDAAiD;AACjD,MAAM,OAAO,aAAa;IAwBL,OAAO;IAvB1B,UAAU,CAOI;IACd,WAAW,GAAG,CAAC,CAAC;IACP,SAAS,CAGhB;IACF,SAAS,GAAG,CAAC,CAAC;IACL,KAAK,GAAwB,EAAE,CAAC;IACzC,YAAY,CAAS;IACrB,cAAc,GAAG,KAAK,CAAC;IACvB,OAAO,GAAG,KAAK,CAAC;IAChB,mBAAmB,CAAyC;IACnD,MAAM,GAAG,IAAI,GAAG,EAA8B,CAAC;IAExD,YACE,KAA0B,EACT,OAAO,GAGpB,EAAE;uBAHW,OAAO;QAKxB,IAAI,CAAC,SAAS,GAAG;YACf,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,KAAK,EAAE,KAAK,CAAC,KAAK;YAClB,aAAa,EAAE,KAAK,CAAC,aAAa;YAClC,WAAW,EAAE,KAAK,CAAC,WAAW;YAC9B,SAAS,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS;SAChE,CAAC;QACF,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC;QACtC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACrB,CAAC;IAED,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,mBAAmB,EAAE,YAAY,CAAC;IAChD,CAAC;IAED,MAAM,CAAC,KAA0B;QAC/B,IAAI,CAAC,WAAW,IAAI,CAAC,CAAC;QACtB,IAAI,KAAK,CAAC,IAAI,KAAK,kBAAkB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC9D,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC;YACtC,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;YACpC,IAAI,CAAC,mBAAmB,GAAG,KAAK,CAAC,OAAO,CAAC,kBAAkB;gBACzD,CAAC,CAAC,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE;gBACzC,CAAC,CAAC,SAAS,CAAC;QAChB,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,oBAAoB,EAAE,CAAC;YACxC,IAAI,CAAC,UAAU,GAAG;gBAChB,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM;gBAC5B,WAAW,EAAE,KAAK,CAAC,WAAW;gBAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS;aAC9D,CAAC;QACJ,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;YACpB,IAAI,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,KAAK;gBAAE,OAAO;YAC9C,MAAM,GAAG,GAAsB;gBAC7B,EAAE,EAAE,KAAK,CAAC,EAAE;gBACZ,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK;gBAC1B,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,OAAO;gBAC9B,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC;YACF,IAAI,KAAK,CAAC,SAAS;gBAAE,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;YACrD,IAAI,KAAK,CAAC,MAAM;gBAAE,GAAG,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACrB,OAAO;QACT,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO;QAE7D,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,IAAI,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;YAC/C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,IAAI,CAAC,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC;YAC/B,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC;YAC7C,IAAI,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC;gBACjC,IAAI,CAAC,cAAc,GAAG;oBACpB,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc;oBAC/B,OAAO,EAAE,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC;iBACnD,CAAC;YACJ,CAAC;YACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM;gBAAE,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;YACpE,OAAO;QACT,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACnC,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,KAAK,KAAK;gBAAE,OAAO;YACnD,CAAC,IAAI,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC,IAAI,CAAC;gBAC3B,GAAG,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC;gBACjC,SAAS,EAAE,KAAK,CAAC,SAAS;gBAC1B,WAAW,EAAE,KAAK,CAAC,WAAW;aAC/B,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QACD,IAAI,cAAc,IAAI,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAClE,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC;QACjD,CAAC;QACD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YAC3B,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,GAAG;oBACR,SAAS,EAAE,KAAK,CAAC,SAAS;oBAC1B,OAAO,EAAE,EAAE;oBACX,WAAW,EAAE,KAAK,CAAC,WAAW;oBAC9B,MAAM,EAAE,SAAS;iBAClB,CAAC;gBACF,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;YACzB,CAAC;YACD,IAAI,IAAI,CAAC,YAAY;gBAAE,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;YAChE,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;gBACpC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAC9C,CAAC;YACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,QAAQ,EAAE,CAAC;gBACb,OAAO,CAAC,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACzC,OAAO,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC;gBACzC,OAAO,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YACxC,CAAC;QACH,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;YACxB,IAAI,CAAC,WAAW,KAAK,KAAK,CAAC,WAAW,CAAC;YACvC,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAC3B,MAAM,QAAQ,GAAmC;oBAC/C,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ;oBACzB,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;iBAC1E,CAAC;gBACF,IAAI,CAAC,IAAI,CAAC,QAAQ,IAAI,sBAAsB,CAAC,QAAQ,CAAC;oBAAE,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;YACnF,CAAC;YACD,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,KAAK,CAAC,CAAC;QAC3C,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC,MAAM,GAAG,QAAQ,CAAC;YACvB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC;YACtC,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC,UAAU,CAAC;YACnC,IAAI,KAAK,CAAC,UAAU,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC,UAAU,CAAC;QAC9F,CAAC;IACH,CAAC;IAED,QAAQ;QACN,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,MAAM,GAAG,GAAsB;YAC7B,MAAM,EAAE,IAAI,CAAC,OAAO;YACpB,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,GAAG,EAAE,CAAC,CAAC;YACpF,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU;YACrC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK;YAC3B,WAAW,EAAE,IAAI,CAAC,YAAY;YAC9B,MAAM,EAAE,SAAS,EAAE,MAAM,IAAI,SAAS;YACtC,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;YACrE,OAAO,EAAE,iBAAiB;SAC3B,CAAC;QACF,IAAI,IAAI,CAAC,mBAAmB;YAAE,GAAG,CAAC,kBAAkB,GAAG,EAAE,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAC;QACvF,IAAI,IAAI,CAAC,SAAS,CAAC,aAAa,KAAK,SAAS;YAC5C,GAAG,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC;QACnD,IAAI,SAAS,EAAE,UAAU,KAAK,SAAS;YAAE,GAAG,CAAC,UAAU,GAAG,SAAS,CAAC,UAAU,CAAC;QAC/E,IAAI,SAAS,EAAE,KAAK;YAAE,GAAG,CAAC,KAAK,GAAG,eAAe,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACnE,IAAI,SAAS;YAAE,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,WAAW,CAAC;QACxD,IAAI,IAAI,CAAC,SAAS,CAAC,WAAW;YAAE,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC;QAC7E,IAAI,IAAI,CAAC,SAAS,CAAC,SAAS;YAAE,GAAG,CAAC,SAAS,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC;QAC9E,OAAO,GAAG,CAAC;IACb,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,UAAU,kBAAkB,CAAC,MAAsC;IACvE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC,CAAC;IAC7F,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,CAAC;IAClD,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;QAAE,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC/D,OAAO,UAAU,CAAC,QAAQ,EAAE,CAAC;AAC/B,CAAC","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;