@shipfox/client-workflows 0.2.0

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 (327) hide show
  1. package/.storybook/main.ts +1 -0
  2. package/.storybook/preview.css +10 -0
  3. package/.storybook/preview.tsx +97 -0
  4. package/.swcrc +42 -0
  5. package/.turbo/turbo-build.log +2 -0
  6. package/.turbo/turbo-type$colon$emit.log +1 -0
  7. package/.turbo/turbo-type.log +1 -0
  8. package/CHANGELOG.md +162 -0
  9. package/LICENSE +21 -0
  10. package/dist/components/identifier/identifier.d.ts +6 -0
  11. package/dist/components/identifier/identifier.d.ts.map +1 -0
  12. package/dist/components/identifier/identifier.js +144 -0
  13. package/dist/components/identifier/identifier.js.map +1 -0
  14. package/dist/components/identifier/index.d.ts +2 -0
  15. package/dist/components/identifier/index.d.ts.map +1 -0
  16. package/dist/components/identifier/index.js +3 -0
  17. package/dist/components/identifier/index.js.map +1 -0
  18. package/dist/components/job-graph/graph-model.d.ts +27 -0
  19. package/dist/components/job-graph/graph-model.d.ts.map +1 -0
  20. package/dist/components/job-graph/graph-model.js +107 -0
  21. package/dist/components/job-graph/graph-model.js.map +1 -0
  22. package/dist/components/job-graph/index.d.ts +3 -0
  23. package/dist/components/job-graph/index.d.ts.map +1 -0
  24. package/dist/components/job-graph/index.js +3 -0
  25. package/dist/components/job-graph/index.js.map +1 -0
  26. package/dist/components/job-graph/job-duration-format.d.ts +4 -0
  27. package/dist/components/job-graph/job-duration-format.d.ts.map +1 -0
  28. package/dist/components/job-graph/job-duration-format.js +41 -0
  29. package/dist/components/job-graph/job-duration-format.js.map +1 -0
  30. package/dist/components/job-graph/job-duration-label.d.ts +5 -0
  31. package/dist/components/job-graph/job-duration-label.d.ts.map +1 -0
  32. package/dist/components/job-graph/job-duration-label.js +33 -0
  33. package/dist/components/job-graph/job-duration-label.js.map +1 -0
  34. package/dist/components/job-graph/job-graph-content.d.ts +9 -0
  35. package/dist/components/job-graph/job-graph-content.d.ts.map +1 -0
  36. package/dist/components/job-graph/job-graph-content.js +181 -0
  37. package/dist/components/job-graph/job-graph-content.js.map +1 -0
  38. package/dist/components/job-graph/job-graph-view.d.ts +11 -0
  39. package/dist/components/job-graph/job-graph-view.d.ts.map +1 -0
  40. package/dist/components/job-graph/job-graph-view.js +24 -0
  41. package/dist/components/job-graph/job-graph-view.js.map +1 -0
  42. package/dist/components/job-graph/job-graph.d.ts +3 -0
  43. package/dist/components/job-graph/job-graph.d.ts.map +1 -0
  44. package/dist/components/job-graph/job-graph.js +21 -0
  45. package/dist/components/job-graph/job-graph.js.map +1 -0
  46. package/dist/components/job-graph/job-node.d.ts +16 -0
  47. package/dist/components/job-graph/job-node.d.ts.map +1 -0
  48. package/dist/components/job-graph/job-node.js +196 -0
  49. package/dist/components/job-graph/job-node.js.map +1 -0
  50. package/dist/components/job-graph/types.d.ts +9 -0
  51. package/dist/components/job-graph/types.d.ts.map +1 -0
  52. package/dist/components/job-graph/types.js +3 -0
  53. package/dist/components/job-graph/types.js.map +1 -0
  54. package/dist/components/step-list/index.d.ts +3 -0
  55. package/dist/components/step-list/index.d.ts.map +1 -0
  56. package/dist/components/step-list/index.js +3 -0
  57. package/dist/components/step-list/index.js.map +1 -0
  58. package/dist/components/step-list/step-list-model.d.ts +36 -0
  59. package/dist/components/step-list/step-list-model.d.ts.map +1 -0
  60. package/dist/components/step-list/step-list-model.js +135 -0
  61. package/dist/components/step-list/step-list-model.js.map +1 -0
  62. package/dist/components/step-list/step-list.d.ts +32 -0
  63. package/dist/components/step-list/step-list.d.ts.map +1 -0
  64. package/dist/components/step-list/step-list.js +409 -0
  65. package/dist/components/step-list/step-list.js.map +1 -0
  66. package/dist/components/workflow-run-duration-label.d.ts +8 -0
  67. package/dist/components/workflow-run-duration-label.d.ts.map +1 -0
  68. package/dist/components/workflow-run-duration-label.js +84 -0
  69. package/dist/components/workflow-run-duration-label.js.map +1 -0
  70. package/dist/components/workflow-run-list/index.d.ts +2 -0
  71. package/dist/components/workflow-run-list/index.d.ts.map +1 -0
  72. package/dist/components/workflow-run-list/index.js +3 -0
  73. package/dist/components/workflow-run-list/index.js.map +1 -0
  74. package/dist/components/workflow-run-list/run-display.d.ts +5 -0
  75. package/dist/components/workflow-run-list/run-display.d.ts.map +1 -0
  76. package/dist/components/workflow-run-list/run-display.js +19 -0
  77. package/dist/components/workflow-run-list/run-display.js.map +1 -0
  78. package/dist/components/workflow-run-list/types.d.ts +21 -0
  79. package/dist/components/workflow-run-list/types.d.ts.map +1 -0
  80. package/dist/components/workflow-run-list/types.js +3 -0
  81. package/dist/components/workflow-run-list/types.js.map +1 -0
  82. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts +14 -0
  83. package/dist/components/workflow-run-list/workflow-run-list-content.d.ts.map +1 -0
  84. package/dist/components/workflow-run-list/workflow-run-list-content.js +37 -0
  85. package/dist/components/workflow-run-list/workflow-run-list-content.js.map +1 -0
  86. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts +10 -0
  87. package/dist/components/workflow-run-list/workflow-run-list-header.d.ts.map +1 -0
  88. package/dist/components/workflow-run-list/workflow-run-list-header.js +55 -0
  89. package/dist/components/workflow-run-list/workflow-run-list-header.js.map +1 -0
  90. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts +15 -0
  91. package/dist/components/workflow-run-list/workflow-run-list-states.d.ts.map +1 -0
  92. package/dist/components/workflow-run-list/workflow-run-list-states.js +103 -0
  93. package/dist/components/workflow-run-list/workflow-run-list-states.js.map +1 -0
  94. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts +3 -0
  95. package/dist/components/workflow-run-list/workflow-run-list-view.d.ts.map +1 -0
  96. package/dist/components/workflow-run-list/workflow-run-list-view.js +46 -0
  97. package/dist/components/workflow-run-list/workflow-run-list-view.js.map +1 -0
  98. package/dist/components/workflow-run-list/workflow-run-list.d.ts +3 -0
  99. package/dist/components/workflow-run-list/workflow-run-list.d.ts.map +1 -0
  100. package/dist/components/workflow-run-list/workflow-run-list.js +20 -0
  101. package/dist/components/workflow-run-list/workflow-run-list.js.map +1 -0
  102. package/dist/components/workflow-run-list/workflow-run-row.d.ts +14 -0
  103. package/dist/components/workflow-run-list/workflow-run-row.d.ts.map +1 -0
  104. package/dist/components/workflow-run-list/workflow-run-row.js +172 -0
  105. package/dist/components/workflow-run-list/workflow-run-row.js.map +1 -0
  106. package/dist/components/workflow-run-summary/index.d.ts +2 -0
  107. package/dist/components/workflow-run-summary/index.d.ts.map +1 -0
  108. package/dist/components/workflow-run-summary/index.js +3 -0
  109. package/dist/components/workflow-run-summary/index.js.map +1 -0
  110. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts +9 -0
  111. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.d.ts.map +1 -0
  112. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js +138 -0
  113. package/dist/components/workflow-run-summary/workflow-run-attempt-switcher.js.map +1 -0
  114. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts +20 -0
  115. package/dist/components/workflow-run-summary/workflow-run-summary.d.ts.map +1 -0
  116. package/dist/components/workflow-run-summary/workflow-run-summary.js +252 -0
  117. package/dist/components/workflow-run-summary/workflow-run-summary.js.map +1 -0
  118. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts +7 -0
  119. package/dist/components/workflow-run-view/agent-config-failure-callout.d.ts.map +1 -0
  120. package/dist/components/workflow-run-view/agent-config-failure-callout.js +84 -0
  121. package/dist/components/workflow-run-view/agent-config-failure-callout.js.map +1 -0
  122. package/dist/components/workflow-run-view/index.d.ts +3 -0
  123. package/dist/components/workflow-run-view/index.d.ts.map +1 -0
  124. package/dist/components/workflow-run-view/index.js +4 -0
  125. package/dist/components/workflow-run-view/index.js.map +1 -0
  126. package/dist/components/workflow-run-view/job-card.d.ts +17 -0
  127. package/dist/components/workflow-run-view/job-card.d.ts.map +1 -0
  128. package/dist/components/workflow-run-view/job-card.js +476 -0
  129. package/dist/components/workflow-run-view/job-card.js.map +1 -0
  130. package/dist/components/workflow-run-view/job-execution-switcher.d.ts +10 -0
  131. package/dist/components/workflow-run-view/job-execution-switcher.d.ts.map +1 -0
  132. package/dist/components/workflow-run-view/job-execution-switcher.js +171 -0
  133. package/dist/components/workflow-run-view/job-execution-switcher.js.map +1 -0
  134. package/dist/components/workflow-run-view/job-execution-time-text.d.ts +6 -0
  135. package/dist/components/workflow-run-view/job-execution-time-text.d.ts.map +1 -0
  136. package/dist/components/workflow-run-view/job-execution-time-text.js +24 -0
  137. package/dist/components/workflow-run-view/job-execution-time-text.js.map +1 -0
  138. package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts +9 -0
  139. package/dist/components/workflow-run-view/step-attempt-log-panel.d.ts.map +1 -0
  140. package/dist/components/workflow-run-view/step-attempt-log-panel.js +152 -0
  141. package/dist/components/workflow-run-view/step-attempt-log-panel.js.map +1 -0
  142. package/dist/components/workflow-run-view/workflow-run-selection.d.ts +14 -0
  143. package/dist/components/workflow-run-view/workflow-run-selection.d.ts.map +1 -0
  144. package/dist/components/workflow-run-view/workflow-run-selection.js +56 -0
  145. package/dist/components/workflow-run-view/workflow-run-selection.js.map +1 -0
  146. package/dist/components/workflow-run-view/workflow-run-states.d.ts +12 -0
  147. package/dist/components/workflow-run-view/workflow-run-states.d.ts.map +1 -0
  148. package/dist/components/workflow-run-view/workflow-run-states.js +91 -0
  149. package/dist/components/workflow-run-view/workflow-run-states.js.map +1 -0
  150. package/dist/components/workflow-run-view/workflow-run-view.d.ts +15 -0
  151. package/dist/components/workflow-run-view/workflow-run-view.d.ts.map +1 -0
  152. package/dist/components/workflow-run-view/workflow-run-view.js +285 -0
  153. package/dist/components/workflow-run-view/workflow-run-view.js.map +1 -0
  154. package/dist/components/workflow-source-panel/index.d.ts +2 -0
  155. package/dist/components/workflow-source-panel/index.d.ts.map +1 -0
  156. package/dist/components/workflow-source-panel/index.js +3 -0
  157. package/dist/components/workflow-source-panel/index.js.map +1 -0
  158. package/dist/components/workflow-source-panel/workflow-source-panel.d.ts +13 -0
  159. package/dist/components/workflow-source-panel/workflow-source-panel.d.ts.map +1 -0
  160. package/dist/components/workflow-source-panel/workflow-source-panel.js +91 -0
  161. package/dist/components/workflow-source-panel/workflow-source-panel.js.map +1 -0
  162. package/dist/components/workflow-status/status-visuals.d.ts +12 -0
  163. package/dist/components/workflow-status/status-visuals.d.ts.map +1 -0
  164. package/dist/components/workflow-status/status-visuals.js +54 -0
  165. package/dist/components/workflow-status/status-visuals.js.map +1 -0
  166. package/dist/components/workflow-status/workflow-status-icon.d.ts +22 -0
  167. package/dist/components/workflow-status/workflow-status-icon.d.ts.map +1 -0
  168. package/dist/components/workflow-status/workflow-status-icon.js +100 -0
  169. package/dist/components/workflow-status/workflow-status-icon.js.map +1 -0
  170. package/dist/core/entities/job-execution.d.ts +69 -0
  171. package/dist/core/entities/job-execution.d.ts.map +1 -0
  172. package/dist/core/entities/job-execution.js +83 -0
  173. package/dist/core/entities/job-execution.js.map +1 -0
  174. package/dist/core/entities/job.d.ts +56 -0
  175. package/dist/core/entities/job.d.ts.map +1 -0
  176. package/dist/core/entities/job.js +71 -0
  177. package/dist/core/entities/job.js.map +1 -0
  178. package/dist/core/entities/step-attempt.d.ts +49 -0
  179. package/dist/core/entities/step-attempt.d.ts.map +1 -0
  180. package/dist/core/entities/step-attempt.js +48 -0
  181. package/dist/core/entities/step-attempt.js.map +1 -0
  182. package/dist/core/entities/step.d.ts +41 -0
  183. package/dist/core/entities/step.d.ts.map +1 -0
  184. package/dist/core/entities/step.js +51 -0
  185. package/dist/core/entities/step.js.map +1 -0
  186. package/dist/core/entities/workflow-run-attempt.d.ts +44 -0
  187. package/dist/core/entities/workflow-run-attempt.d.ts.map +1 -0
  188. package/dist/core/entities/workflow-run-attempt.js +51 -0
  189. package/dist/core/entities/workflow-run-attempt.js.map +1 -0
  190. package/dist/core/entities/workflow-run.d.ts +61 -0
  191. package/dist/core/entities/workflow-run.d.ts.map +1 -0
  192. package/dist/core/entities/workflow-run.js +104 -0
  193. package/dist/core/entities/workflow-run.js.map +1 -0
  194. package/dist/core/workflow-run-url-state.d.ts +13 -0
  195. package/dist/core/workflow-run-url-state.d.ts.map +1 -0
  196. package/dist/core/workflow-run-url-state.js +43 -0
  197. package/dist/core/workflow-run-url-state.js.map +1 -0
  198. package/dist/core/workflow-run.d.ts +13 -0
  199. package/dist/core/workflow-run.d.ts.map +1 -0
  200. package/dist/core/workflow-run.js +8 -0
  201. package/dist/core/workflow-run.js.map +1 -0
  202. package/dist/env.d.js +2 -0
  203. package/dist/env.d.js.map +1 -0
  204. package/dist/feature.d.ts +20 -0
  205. package/dist/feature.d.ts.map +1 -0
  206. package/dist/feature.js +27 -0
  207. package/dist/feature.js.map +1 -0
  208. package/dist/hooks/api/workflow-runs.d.ts +109 -0
  209. package/dist/hooks/api/workflow-runs.d.ts.map +1 -0
  210. package/dist/hooks/api/workflow-runs.js +394 -0
  211. package/dist/hooks/api/workflow-runs.js.map +1 -0
  212. package/dist/index.d.ts +5 -0
  213. package/dist/index.d.ts.map +1 -0
  214. package/dist/index.js +5 -0
  215. package/dist/index.js.map +1 -0
  216. package/dist/pages/workflow-run-first-time-use.d.ts +6 -0
  217. package/dist/pages/workflow-run-first-time-use.d.ts.map +1 -0
  218. package/dist/pages/workflow-run-first-time-use.js +17 -0
  219. package/dist/pages/workflow-run-first-time-use.js.map +1 -0
  220. package/dist/pages/workflow-run-page.d.ts +8 -0
  221. package/dist/pages/workflow-run-page.d.ts.map +1 -0
  222. package/dist/pages/workflow-run-page.js +83 -0
  223. package/dist/pages/workflow-run-page.js.map +1 -0
  224. package/dist/routes/run-detail.d.ts +8 -0
  225. package/dist/routes/run-detail.d.ts.map +1 -0
  226. package/dist/routes/run-detail.js +21 -0
  227. package/dist/routes/run-detail.js.map +1 -0
  228. package/dist/routes/runs.d.ts +8 -0
  229. package/dist/routes/runs.d.ts.map +1 -0
  230. package/dist/routes/runs.js +20 -0
  231. package/dist/routes/runs.js.map +1 -0
  232. package/dist/tsconfig.test.tsbuildinfo +1 -0
  233. package/package.json +114 -0
  234. package/src/components/identifier/identifier.tsx +178 -0
  235. package/src/components/identifier/index.ts +1 -0
  236. package/src/components/job-graph/graph-model.test.ts +189 -0
  237. package/src/components/job-graph/graph-model.ts +178 -0
  238. package/src/components/job-graph/index.ts +2 -0
  239. package/src/components/job-graph/job-duration-format.ts +54 -0
  240. package/src/components/job-graph/job-duration-label.tsx +29 -0
  241. package/src/components/job-graph/job-graph-content.tsx +225 -0
  242. package/src/components/job-graph/job-graph-view.test.tsx +298 -0
  243. package/src/components/job-graph/job-graph-view.tsx +45 -0
  244. package/src/components/job-graph/job-graph.stories.tsx +182 -0
  245. package/src/components/job-graph/job-graph.tsx +24 -0
  246. package/src/components/job-graph/job-node.stories.tsx +364 -0
  247. package/src/components/job-graph/job-node.test.tsx +347 -0
  248. package/src/components/job-graph/job-node.tsx +202 -0
  249. package/src/components/job-graph/types.ts +9 -0
  250. package/src/components/step-list/index.ts +6 -0
  251. package/src/components/step-list/step-list-model.test.ts +369 -0
  252. package/src/components/step-list/step-list-model.ts +205 -0
  253. package/src/components/step-list/step-list.stories.tsx +419 -0
  254. package/src/components/step-list/step-list.test.tsx +566 -0
  255. package/src/components/step-list/step-list.tsx +494 -0
  256. package/src/components/workflow-run-duration-label.tsx +118 -0
  257. package/src/components/workflow-run-list/index.ts +1 -0
  258. package/src/components/workflow-run-list/run-display.test.ts +53 -0
  259. package/src/components/workflow-run-list/run-display.ts +22 -0
  260. package/src/components/workflow-run-list/types.ts +22 -0
  261. package/src/components/workflow-run-list/workflow-run-list-content.tsx +58 -0
  262. package/src/components/workflow-run-list/workflow-run-list-header.tsx +53 -0
  263. package/src/components/workflow-run-list/workflow-run-list-states.tsx +86 -0
  264. package/src/components/workflow-run-list/workflow-run-list-view.test.tsx +178 -0
  265. package/src/components/workflow-run-list/workflow-run-list-view.tsx +57 -0
  266. package/src/components/workflow-run-list/workflow-run-list.stories.tsx +111 -0
  267. package/src/components/workflow-run-list/workflow-run-list.tsx +29 -0
  268. package/src/components/workflow-run-list/workflow-run-row.tsx +176 -0
  269. package/src/components/workflow-run-summary/index.ts +1 -0
  270. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.test.tsx +230 -0
  271. package/src/components/workflow-run-summary/workflow-run-attempt-switcher.tsx +146 -0
  272. package/src/components/workflow-run-summary/workflow-run-summary.stories.tsx +414 -0
  273. package/src/components/workflow-run-summary/workflow-run-summary.test.tsx +354 -0
  274. package/src/components/workflow-run-summary/workflow-run-summary.tsx +295 -0
  275. package/src/components/workflow-run-view/agent-config-failure-callout.stories.tsx +140 -0
  276. package/src/components/workflow-run-view/agent-config-failure-callout.tsx +93 -0
  277. package/src/components/workflow-run-view/index.ts +2 -0
  278. package/src/components/workflow-run-view/job-card.stories.tsx +788 -0
  279. package/src/components/workflow-run-view/job-card.tsx +566 -0
  280. package/src/components/workflow-run-view/job-execution-switcher.tsx +170 -0
  281. package/src/components/workflow-run-view/job-execution-time-text.tsx +34 -0
  282. package/src/components/workflow-run-view/step-attempt-log-panel.test.tsx +290 -0
  283. package/src/components/workflow-run-view/step-attempt-log-panel.tsx +152 -0
  284. package/src/components/workflow-run-view/workflow-run-selection.test.ts +280 -0
  285. package/src/components/workflow-run-view/workflow-run-selection.ts +89 -0
  286. package/src/components/workflow-run-view/workflow-run-states.tsx +70 -0
  287. package/src/components/workflow-run-view/workflow-run-view.test.tsx +1214 -0
  288. package/src/components/workflow-run-view/workflow-run-view.tsx +341 -0
  289. package/src/components/workflow-source-panel/index.ts +1 -0
  290. package/src/components/workflow-source-panel/workflow-source-panel.stories.tsx +110 -0
  291. package/src/components/workflow-source-panel/workflow-source-panel.test.tsx +96 -0
  292. package/src/components/workflow-source-panel/workflow-source-panel.tsx +136 -0
  293. package/src/components/workflow-status/status-visuals.test.ts +38 -0
  294. package/src/components/workflow-status/status-visuals.ts +36 -0
  295. package/src/components/workflow-status/workflow-status-icon.stories.tsx +90 -0
  296. package/src/components/workflow-status/workflow-status-icon.tsx +135 -0
  297. package/src/core/entities/job-execution.ts +139 -0
  298. package/src/core/entities/job.ts +149 -0
  299. package/src/core/entities/step-attempt.ts +89 -0
  300. package/src/core/entities/step.ts +105 -0
  301. package/src/core/entities/workflow-run-attempt.ts +87 -0
  302. package/src/core/entities/workflow-run.ts +183 -0
  303. package/src/core/workflow-run-url-state.ts +61 -0
  304. package/src/core/workflow-run.test.ts +640 -0
  305. package/src/core/workflow-run.ts +66 -0
  306. package/src/env.d.ts +8 -0
  307. package/src/feature.ts +26 -0
  308. package/src/hooks/api/workflow-runs.test.tsx +410 -0
  309. package/src/hooks/api/workflow-runs.ts +485 -0
  310. package/src/index.ts +45 -0
  311. package/src/page-harness-budget.test.ts +33 -0
  312. package/src/pages/workflow-run-first-time-use.tsx +17 -0
  313. package/src/pages/workflow-run-page.test.tsx +517 -0
  314. package/src/pages/workflow-run-page.tsx +89 -0
  315. package/src/routes/run-detail.tsx +15 -0
  316. package/src/routes/runs.tsx +11 -0
  317. package/test/fixtures/logs.ts +13 -0
  318. package/test/fixtures/workflow-run.ts +311 -0
  319. package/test/pages.tsx +79 -0
  320. package/test/render.tsx +40 -0
  321. package/test/setup.ts +3 -0
  322. package/tsconfig.build.json +9 -0
  323. package/tsconfig.build.tsbuildinfo +1 -0
  324. package/tsconfig.json +3 -0
  325. package/tsconfig.test.json +8 -0
  326. package/vercel.json +8 -0
  327. package/vitest.config.ts +70 -0
@@ -0,0 +1 @@
1
+ export {default} from '../../.storybook/main.ts';
@@ -0,0 +1,10 @@
1
+ @import "@shipfox/react-ui/index.css";
2
+
3
+ /* The `@import` already pulls in the full design-system theme (tokens, preflight,
4
+ base layer) from react-ui, so nothing is duplicated here. Tailwind v4 only emits
5
+ utilities for classes it finds in scanned source, though, and these stories render
6
+ react-ui components (Button, Input, Dot, Alert, ...) whose classes live in react-ui's
7
+ own source. Scanning both trees keeps those components styled, the same way
8
+ apps/client/src/styles.css scans every package it renders. */
9
+ @source "../src";
10
+ @source "../../../shared/react/ui/src";
@@ -0,0 +1,97 @@
1
+ import './preview.css';
2
+ import {RelativeTimeProvider} from '@shipfox/react-ui/relative-time';
3
+ import {ThemeProvider} from '@shipfox/react-ui/theme';
4
+ import type {Decorator, Preview} from '@storybook/react';
5
+ import {
6
+ createMemoryHistory,
7
+ createRootRoute,
8
+ createRoute,
9
+ createRouter,
10
+ RouterProvider,
11
+ } from '@tanstack/react-router';
12
+
13
+ if (typeof document !== 'undefined' && document.fonts) {
14
+ void Promise.all([
15
+ document.fonts.load("16px 'Inter'"),
16
+ document.fonts.load("italic 16px 'Inter'"),
17
+ document.fonts.load("16px 'Commit Mono'"),
18
+ document.fonts.load("bold 16px 'Commit Mono'"),
19
+ ]);
20
+ }
21
+
22
+ const STORYBOOK_NOW_MS = Date.parse('2026-06-26T12:00:00.000Z');
23
+
24
+ Object.defineProperty(Date, 'now', {
25
+ configurable: true,
26
+ writable: true,
27
+ value: () => STORYBOOK_NOW_MS,
28
+ });
29
+
30
+ const withTheme: Decorator = (Story, context) => {
31
+ const theme = context.globals.theme;
32
+ return (
33
+ <ThemeProvider key={theme} defaultTheme={theme} storageKey={`shipfox-theme-${theme}`}>
34
+ <Story />
35
+ </ThemeProvider>
36
+ );
37
+ };
38
+
39
+ const withRelativeTime: Decorator = (Story) => (
40
+ <RelativeTimeProvider>
41
+ <Story />
42
+ </RelativeTimeProvider>
43
+ );
44
+
45
+ // Run rows render `<Link to="/workspaces/$wid/projects/$pid/runs/$runId">` and read
46
+ // `useParams`, both of which need a router in context. A memory router seeded at a
47
+ // matching path lets the rows render and resolve their hrefs without a real app shell.
48
+ const withRouter: Decorator = (Story) => {
49
+ const rootRoute = createRootRoute();
50
+ const runRoute = createRoute({
51
+ getParentRoute: () => rootRoute,
52
+ path: '/workspaces/$wid/projects/$pid/runs/$runId',
53
+ component: () => <Story />,
54
+ });
55
+ const router = createRouter({
56
+ routeTree: rootRoute.addChildren([runRoute]),
57
+ history: createMemoryHistory({
58
+ initialEntries: ['/workspaces/ws-demo/projects/proj-demo/runs/run-1'],
59
+ }),
60
+ });
61
+ return <RouterProvider router={router} />;
62
+ };
63
+
64
+ const preview: Preview = {
65
+ decorators: [withTheme, withRelativeTime, withRouter],
66
+ parameters: {
67
+ argos: {
68
+ // Dual-theme coverage lives in @shipfox/react-ui (the theming source of truth);
69
+ // feature packages capture only the primary dark theme to limit Argos spend.
70
+ modes: {
71
+ dark: {theme: 'dark'},
72
+ },
73
+ fitToContent: false,
74
+ },
75
+ options: {
76
+ storySort: {method: 'alphabetical'},
77
+ },
78
+ },
79
+ globalTypes: {
80
+ theme: {
81
+ name: 'Theme',
82
+ description: 'Global theme for components',
83
+ defaultValue: 'dark',
84
+ toolbar: {
85
+ icon: 'sun',
86
+ items: [
87
+ {value: 'light', icon: 'sun', title: 'Light'},
88
+ {value: 'dark', icon: 'moon', title: 'Dark'},
89
+ {value: 'system', icon: 'info', title: 'System'},
90
+ ],
91
+ showName: true,
92
+ },
93
+ },
94
+ },
95
+ };
96
+
97
+ export default preview;
package/.swcrc ADDED
@@ -0,0 +1,42 @@
1
+ {
2
+ "jsc": {
3
+ "target": "es2023",
4
+ "parser": {
5
+ "syntax": "typescript",
6
+ "decorators": true,
7
+ "dynamicImport": true,
8
+ "tsx": true
9
+ },
10
+ "transform": {
11
+ "decoratorMetadata": true,
12
+ "legacyDecorator": true,
13
+ "react": {
14
+ "runtime": "automatic"
15
+ }
16
+ },
17
+ "keepClassNames": true,
18
+ "externalHelpers": true,
19
+ "loose": true,
20
+ "experimental": {
21
+ "keepImportAttributes": true
22
+ }
23
+ },
24
+ "module": {
25
+ "type": "es6",
26
+ "strict": true,
27
+ "strictMode": true,
28
+ "noInterop": true,
29
+ "resolveFully": true
30
+ },
31
+ "sourceMaps": true,
32
+ "minify": false,
33
+ "exclude": [
34
+ "node_modules",
35
+ "jest.config.ts",
36
+ "^.*\\.spec\\.tsx?$",
37
+ "^.*\\.test\\.tsx?$",
38
+ "^.*\\.stories\\.tsx?$",
39
+ ".*/jest-setup\\.ts$",
40
+ "^.*\\.js$"
41
+ ]
42
+ }
@@ -0,0 +1,2 @@
1
+ $ shipfox-swc
2
+ Successfully compiled: 56 files with swc (44.53ms)
@@ -0,0 +1 @@
1
+ $ shipfox-tsc-emit
@@ -0,0 +1 @@
1
+ $ shipfox-tsc-check
package/CHANGELOG.md ADDED
@@ -0,0 +1,162 @@
1
+ # @shipfox/client-workflows
2
+
3
+ ## 0.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 3d064b8: Publishes the client runtime closure with shell, feature, route, Vite, and testing contracts.
8
+ - 6bc2e45: Adds the composable upstream client shell, feature catalog, and route manifests for every client feature.
9
+
10
+ ### Patch Changes
11
+
12
+ - Updated dependencies [3d064b8]
13
+ - Updated dependencies [6bc2e45]
14
+ - @shipfox/client-api@0.2.0
15
+ - @shipfox/client-logs@0.2.0
16
+ - @shipfox/client-shell@0.2.0
17
+ - @shipfox/client-triggers@0.2.0
18
+ - @shipfox/client-ui@0.2.0
19
+
20
+ ## 0.1.2
21
+
22
+ ### Patch Changes
23
+
24
+ - Updated dependencies [c18d624]
25
+ - @shipfox/react-ui@0.3.1
26
+ - @shipfox/client-logs@0.1.2
27
+ - @shipfox/client-triggers@0.1.2
28
+ - @shipfox/client-ui@0.1.2
29
+
30
+ ## 0.1.1
31
+
32
+ ### Patch Changes
33
+
34
+ - Updated dependencies [1b0d344]
35
+ - @shipfox/api-workflows-dto@2.0.0
36
+ - @shipfox/client-ui@0.1.1
37
+ - @shipfox/client-logs@0.1.1
38
+ - @shipfox/client-triggers@0.1.1
39
+ - @shipfox/client-api@0.0.1
40
+ - @shipfox/react-ui@0.3.0
41
+
42
+ ## 0.1.0
43
+
44
+ ### Minor Changes
45
+
46
+ - 2bc5595: Adds workflow-run cancellation across the API, orchestration queue cleanup, event contract, and run-page cancel action.
47
+ - d69b164: Adds workflow run attempt lineage APIs and a run summary switcher for navigating rerun attempts.
48
+ - 2fb3e87: Derives workflow run attempt durations on the client and displays them in the run list and run header.
49
+ - e699508: Adds first-class skipped workflow jobs with persisted status reasons across API DTOs, orchestration, events, and client run views.
50
+
51
+ ### Patch Changes
52
+
53
+ - dc3e434: Show logs inline under the active or selected workflow step attempt, including missing-stream retry for running attempts and stale-log retry states.
54
+ - 974b501: Moves manual workflow-run firing and optimistic run-list cache updates into `@shipfox/client-workflows` so project workflow pages consume the run cache owner directly.
55
+ - 228385c: Centralizes workflow run DTO mapping behind core client models for workflow UI components.
56
+ - a20b345: Compacts workflow job graph nodes and shows only current unresolved dependency counts.
57
+ - 8037501: Capture the `@shipfox/client-workflows` Storybook stories as Argos visual
58
+ snapshots. Vitest now runs a browser `storybook` project that screenshots every
59
+ story in light and dark and uploads them to the `client-workflows` Argos build
60
+ in CI.
61
+ - 6e435dd: Add a resizable workflow source panel to the run page. The run summary exposes a Source control that opens the run's workflow YAML (from `source_snapshot`) in a page-level right panel, leaving the jobs graph and step attempts visible. The panel defaults to 720px and can be dragged between 420px and `min(1280px, 85vw)`.
62
+ - 5264a22: Adds a shared time ticker provider and hook for live elapsed-time displays that pause while hidden and slow down under reduced motion.
63
+ - 0b75eba: Replace the color-only job/run status dot with `WorkflowStatusIcon`, an icon-in-circle status glyph. Each state now carries a distinct shape plus the saturated `--tag-*-icon` tone, so the state is readable without relying on color alone: a dotted ring (pending), check / X / slash discs (succeeded / failed / cancelled), and a filled disc with an external ripple halo for the live running state (no spinner; honors reduced motion). Applied to the jobs graph nodes and the run-history rows. The run-header keeps its existing status `Badge` (its flat leading icon now matches the new glyph set).
64
+ - 417e220: Removes duplicate status icon from the workflow run summary, keeping only the status badge.
65
+ - 7a0ac44: Highlights workflow job graph edges on node hover with a neutral emphasis instead of the selected-job accent.
66
+ - 8fad235: Adds trigger source icons to workflow run rows so trigger metadata aligns with the status column.
67
+ - f880179: Replaces the trigger node rectangle in the workflow jobs graph with a circle containing only the trigger source icon, and shows the source label on hover via tooltip.
68
+ - 7341569: Add a per-step source action to the workflow run page with highlighted-line scrolling in the source panel.
69
+ - 8037501: Replace the local `StatusDot` in the workflow runs list with the shared `Dot`
70
+ component from `@shipfox/react-ui`, mapping run status to the dot's native color
71
+ variant. Active (running) runs show a blue rippling dot.
72
+
73
+ Refine the selected run row: drop the washed-out orange-tinted fill and border in
74
+ favor of a subtle neutral surface plus the existing orange "you are here" rail, so
75
+ selection reads as intentional restraint rather than a faint brand wash.
76
+
77
+ Re-align the status filter buttons to native `Button` variants instead of
78
+ hardcoded highlight tokens: the active filter uses `primary`, the rest
79
+ `transparent`.
80
+
81
+ Tidy the runs list header: drop the redundant "Runs" title (already shown in the
82
+ section selector above) and align the header inset with the run rows so the search
83
+ box, filters, and run cards share one left edge.
84
+
85
+ Match the runs list panel surface to the nav bar chrome: use
86
+ `bg-background-subtle-base` (instead of a solid `bg-background-neutral-base` panel
87
+ fill) so it reads as app chrome rather than a dedicated card, keeping only the
88
+ right-edge separator.
89
+
90
+ - Updated dependencies [dc3e434]
91
+ - Updated dependencies [eb40964]
92
+ - Updated dependencies [b83d31a]
93
+ - Updated dependencies [5c18360]
94
+ - Updated dependencies [43d7996]
95
+ - Updated dependencies [14e0bea]
96
+ - Updated dependencies [7a9943d]
97
+ - Updated dependencies [c17dd6e]
98
+ - Updated dependencies [9018f0b]
99
+ - Updated dependencies [7fdfd72]
100
+ - Updated dependencies [736249b]
101
+ - Updated dependencies [2bc5595]
102
+ - Updated dependencies [2a3193f]
103
+ - Updated dependencies [f104ff2]
104
+ - Updated dependencies [7341569]
105
+ - Updated dependencies [940696a]
106
+ - Updated dependencies [f98c2be]
107
+ - Updated dependencies [e9396c9]
108
+ - Updated dependencies [b525dcd]
109
+ - Updated dependencies [e4c6abf]
110
+ - Updated dependencies [e4c6abf]
111
+ - Updated dependencies [2c352bb]
112
+ - Updated dependencies [e5d2f13]
113
+ - Updated dependencies [5d0676a]
114
+ - Updated dependencies [a460020]
115
+ - Updated dependencies [3afb7e3]
116
+ - Updated dependencies [a35c2dc]
117
+ - Updated dependencies [58f7aef]
118
+ - Updated dependencies [5264a22]
119
+ - Updated dependencies [9674879]
120
+ - Updated dependencies [c652a68]
121
+ - Updated dependencies [225c9a5]
122
+ - Updated dependencies [24f131b]
123
+ - Updated dependencies [bb2a7bc]
124
+ - Updated dependencies [795f440]
125
+ - Updated dependencies [3dcd751]
126
+ - Updated dependencies [5eb06d0]
127
+ - Updated dependencies [4e13e5f]
128
+ - Updated dependencies [e92150d]
129
+ - Updated dependencies [8037501]
130
+ - Updated dependencies [0fb6018]
131
+ - Updated dependencies [c27a1ed]
132
+ - Updated dependencies [c0a883c]
133
+ - Updated dependencies [362b3eb]
134
+ - Updated dependencies [b8e49ff]
135
+ - Updated dependencies [8037501]
136
+ - Updated dependencies [6c0da64]
137
+ - Updated dependencies [d69b164]
138
+ - Updated dependencies [07f8ff8]
139
+ - Updated dependencies [e457582]
140
+ - Updated dependencies [8b5c905]
141
+ - Updated dependencies [2fb3e87]
142
+ - Updated dependencies [ef1e917]
143
+ - Updated dependencies [f849131]
144
+ - Updated dependencies [0c6373a]
145
+ - Updated dependencies [94bdcc5]
146
+ - Updated dependencies [a34c8ea]
147
+ - Updated dependencies [27770eb]
148
+ - Updated dependencies [2933c33]
149
+ - Updated dependencies [8ac4bf4]
150
+ - Updated dependencies [3a0be6b]
151
+ - Updated dependencies [e699508]
152
+ - Updated dependencies [d42baf4]
153
+ - Updated dependencies [8037501]
154
+ - Updated dependencies [54bb8a3]
155
+ - Updated dependencies [f711e18]
156
+ - Updated dependencies [8ecc121]
157
+ - @shipfox/client-logs@0.1.0
158
+ - @shipfox/api-workflows-dto@0.1.0
159
+ - @shipfox/react-ui@0.3.0
160
+ - @shipfox/client-triggers@0.1.0
161
+ - @shipfox/client-api@0.0.1
162
+ - @shipfox/client-ui@0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Shipfox
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,6 @@
1
+ export declare function Identifier({ display, value, label, }: {
2
+ display: string;
3
+ value: string;
4
+ label?: string | undefined;
5
+ }): import("react").JSX.Element;
6
+ //# sourceMappingURL=identifier.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identifier.d.ts","sourceRoot":"","sources":["../../../src/components/identifier/identifier.tsx"],"names":[],"mappings":"AAkBA,wBAAgB,UAAU,CAAC,EACzB,OAAO,EACP,KAAK,EACL,KAAoB,GACrB,EAAE;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B,+BA6GA"}
@@ -0,0 +1,144 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { useCopyToClipboard } from '@shipfox/react-ui/hooks';
3
+ import { Icon } from '@shipfox/react-ui/icon';
4
+ import { Tooltip, TooltipContent, TooltipTrigger } from '@shipfox/react-ui/tooltip';
5
+ import { Code } from '@shipfox/react-ui/typography';
6
+ import { cn } from '@shipfox/react-ui/utils';
7
+ import { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
8
+ import { createPortal } from 'react-dom';
9
+ const COPY_FEEDBACK_OFFSET_PX = 8;
10
+ export function Identifier({ display, value, label = 'identifier' }) {
11
+ const [copyState, setCopyState] = useState('idle');
12
+ const [tooltipOpen, setTooltipOpen] = useState(false);
13
+ const [feedbackAnchor, setFeedbackAnchor] = useState(null);
14
+ const buttonRef = useRef(null);
15
+ const timeoutRef = useRef(undefined);
16
+ const { copy } = useCopyToClipboard({
17
+ text: value,
18
+ onCopy: ()=>{
19
+ setTemporaryCopyState('copied', 2500);
20
+ }
21
+ });
22
+ useEffect(()=>{
23
+ return ()=>{
24
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
25
+ };
26
+ }, []);
27
+ const resetCopyFeedback = useCallback(()=>{
28
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
29
+ setCopyState('idle');
30
+ setTooltipOpen(false);
31
+ setFeedbackAnchor(null);
32
+ }, []);
33
+ useEffect(()=>{
34
+ if (copyState === 'idle') return;
35
+ window.addEventListener('scroll', resetCopyFeedback, true);
36
+ window.addEventListener('resize', resetCopyFeedback);
37
+ return ()=>{
38
+ window.removeEventListener('scroll', resetCopyFeedback, true);
39
+ window.removeEventListener('resize', resetCopyFeedback);
40
+ };
41
+ }, [
42
+ copyState,
43
+ resetCopyFeedback
44
+ ]);
45
+ function setTemporaryCopyState(state, timeout) {
46
+ const rect = buttonRef.current?.getBoundingClientRect();
47
+ setCopyState(state);
48
+ setTooltipOpen(false);
49
+ setFeedbackAnchor(rect ? {
50
+ left: rect.left + rect.width / 2,
51
+ top: rect.top,
52
+ bottom: rect.bottom
53
+ } : null);
54
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
55
+ timeoutRef.current = setTimeout(resetCopyFeedback, timeout);
56
+ }
57
+ async function handleCopy() {
58
+ try {
59
+ await copy();
60
+ } catch {
61
+ setTemporaryCopyState('failed', 2500);
62
+ }
63
+ }
64
+ const ariaLabel = copyState === 'copied' ? `Copied ${label} ${value}` : copyState === 'failed' ? `Could not copy ${label} ${value}` : `Copy ${label} ${value}`;
65
+ const feedback = copyState === 'copied' ? {
66
+ kind: copyState,
67
+ label: 'Copied'
68
+ } : copyState === 'failed' ? {
69
+ kind: copyState,
70
+ label: 'Could not copy'
71
+ } : null;
72
+ return /*#__PURE__*/ _jsxs(_Fragment, {
73
+ children: [
74
+ /*#__PURE__*/ _jsxs(Tooltip, {
75
+ open: copyState === 'idle' ? tooltipOpen : false,
76
+ onOpenChange: setTooltipOpen,
77
+ children: [
78
+ /*#__PURE__*/ _jsx(TooltipTrigger, {
79
+ asChild: true,
80
+ children: /*#__PURE__*/ _jsxs("button", {
81
+ ref: buttonRef,
82
+ type: "button",
83
+ "aria-label": ariaLabel,
84
+ onClick: ()=>{
85
+ void handleCopy();
86
+ },
87
+ className: "inline-flex h-20 min-w-0 shrink-0 items-center gap-4 rounded-4 px-2 text-foreground-neutral-muted outline-none transition-colors hover:bg-background-components-hover hover:text-foreground-neutral-base focus-visible:shadow-border-interactive-with-active",
88
+ children: [
89
+ /*#__PURE__*/ _jsx(Icon, {
90
+ name: "copy",
91
+ "aria-hidden": "true",
92
+ className: "size-12 shrink-0"
93
+ }),
94
+ /*#__PURE__*/ _jsx(Code, {
95
+ as: "span",
96
+ variant: "label",
97
+ className: "truncate",
98
+ children: display
99
+ })
100
+ ]
101
+ })
102
+ }),
103
+ /*#__PURE__*/ _jsx(TooltipContent, {
104
+ children: /*#__PURE__*/ _jsx(Code, {
105
+ as: "span",
106
+ variant: "label",
107
+ className: "block max-w-[360px] truncate",
108
+ children: value
109
+ })
110
+ })
111
+ ]
112
+ }),
113
+ feedback && feedbackAnchor ? /*#__PURE__*/ _jsx(CopyFeedbackPortal, {
114
+ anchor: feedbackAnchor,
115
+ kind: feedback.kind,
116
+ children: feedback.label
117
+ }) : null
118
+ ]
119
+ });
120
+ }
121
+ function CopyFeedbackPortal({ anchor, children, kind }) {
122
+ const feedbackRef = useRef(null);
123
+ const [placement, setPlacement] = useState('bottom');
124
+ useLayoutEffect(()=>{
125
+ const height = feedbackRef.current?.offsetHeight ?? 0;
126
+ setPlacement(anchor.top >= height + COPY_FEEDBACK_OFFSET_PX ? 'top' : 'bottom');
127
+ }, [
128
+ anchor.top
129
+ ]);
130
+ if (typeof document === 'undefined') return null;
131
+ return /*#__PURE__*/ createPortal(/*#__PURE__*/ _jsx("span", {
132
+ ref: feedbackRef,
133
+ role: "status",
134
+ style: {
135
+ left: anchor.left,
136
+ top: placement === 'top' ? anchor.top : anchor.bottom,
137
+ transform: placement === 'top' ? `translate(-50%, calc(-100% - ${COPY_FEEDBACK_OFFSET_PX}px))` : `translate(-50%, ${COPY_FEEDBACK_OFFSET_PX}px)`
138
+ },
139
+ className: cn('pointer-events-none fixed z-50 whitespace-nowrap rounded-8 bg-background-components-base px-8 py-4 text-xs font-display font-medium leading-20 shadow-tooltip', kind === 'failed' ? 'text-foreground-highlight-error' : 'text-foreground-neutral-base'),
140
+ children: children
141
+ }), document.body);
142
+ }
143
+
144
+ //# sourceMappingURL=identifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/identifier/identifier.tsx"],"sourcesContent":["import {useCopyToClipboard} from '@shipfox/react-ui/hooks';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Code} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useCallback, useEffect, useLayoutEffect, useRef, useState} from 'react';\nimport {createPortal} from 'react-dom';\n\nconst COPY_FEEDBACK_OFFSET_PX = 8;\n\ntype CopyState = 'idle' | 'copied' | 'failed';\n\ninterface FeedbackAnchor {\n bottom: number;\n left: number;\n top: number;\n}\n\nexport function Identifier({\n display,\n value,\n label = 'identifier',\n}: {\n display: string;\n value: string;\n label?: string | undefined;\n}) {\n const [copyState, setCopyState] = useState<CopyState>('idle');\n const [tooltipOpen, setTooltipOpen] = useState(false);\n const [feedbackAnchor, setFeedbackAnchor] = useState<FeedbackAnchor | null>(null);\n const buttonRef = useRef<HTMLButtonElement | null>(null);\n const timeoutRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const {copy} = useCopyToClipboard({\n text: value,\n onCopy: () => {\n setTemporaryCopyState('copied', 2500);\n },\n });\n\n useEffect(() => {\n return () => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n };\n }, []);\n\n const resetCopyFeedback = useCallback(() => {\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n setCopyState('idle');\n setTooltipOpen(false);\n setFeedbackAnchor(null);\n }, []);\n\n useEffect(() => {\n if (copyState === 'idle') return;\n\n window.addEventListener('scroll', resetCopyFeedback, true);\n window.addEventListener('resize', resetCopyFeedback);\n\n return () => {\n window.removeEventListener('scroll', resetCopyFeedback, true);\n window.removeEventListener('resize', resetCopyFeedback);\n };\n }, [copyState, resetCopyFeedback]);\n\n function setTemporaryCopyState(state: Exclude<CopyState, 'idle'>, timeout: number) {\n const rect = buttonRef.current?.getBoundingClientRect();\n setCopyState(state);\n setTooltipOpen(false);\n setFeedbackAnchor(\n rect\n ? {\n left: rect.left + rect.width / 2,\n top: rect.top,\n bottom: rect.bottom,\n }\n : null,\n );\n if (timeoutRef.current) clearTimeout(timeoutRef.current);\n timeoutRef.current = setTimeout(resetCopyFeedback, timeout);\n }\n\n async function handleCopy() {\n try {\n await copy();\n } catch {\n setTemporaryCopyState('failed', 2500);\n }\n }\n\n const ariaLabel =\n copyState === 'copied'\n ? `Copied ${label} ${value}`\n : copyState === 'failed'\n ? `Could not copy ${label} ${value}`\n : `Copy ${label} ${value}`;\n\n const feedback =\n copyState === 'copied'\n ? {kind: copyState, label: 'Copied'}\n : copyState === 'failed'\n ? {kind: copyState, label: 'Could not copy'}\n : null;\n\n return (\n <>\n <Tooltip open={copyState === 'idle' ? tooltipOpen : false} onOpenChange={setTooltipOpen}>\n <TooltipTrigger asChild>\n <button\n ref={buttonRef}\n type=\"button\"\n aria-label={ariaLabel}\n onClick={() => {\n void handleCopy();\n }}\n className=\"inline-flex h-20 min-w-0 shrink-0 items-center gap-4 rounded-4 px-2 text-foreground-neutral-muted outline-none transition-colors hover:bg-background-components-hover hover:text-foreground-neutral-base focus-visible:shadow-border-interactive-with-active\"\n >\n <Icon name=\"copy\" aria-hidden=\"true\" className=\"size-12 shrink-0\" />\n <Code as=\"span\" variant=\"label\" className=\"truncate\">\n {display}\n </Code>\n </button>\n </TooltipTrigger>\n <TooltipContent>\n <Code as=\"span\" variant=\"label\" className=\"block max-w-[360px] truncate\">\n {value}\n </Code>\n </TooltipContent>\n </Tooltip>\n {feedback && feedbackAnchor ? (\n <CopyFeedbackPortal anchor={feedbackAnchor} kind={feedback.kind}>\n {feedback.label}\n </CopyFeedbackPortal>\n ) : null}\n </>\n );\n}\n\nfunction CopyFeedbackPortal({\n anchor,\n children,\n kind,\n}: {\n anchor: FeedbackAnchor;\n children: string;\n kind: Exclude<CopyState, 'idle'>;\n}) {\n const feedbackRef = useRef<HTMLSpanElement | null>(null);\n const [placement, setPlacement] = useState<'top' | 'bottom'>('bottom');\n\n useLayoutEffect(() => {\n const height = feedbackRef.current?.offsetHeight ?? 0;\n setPlacement(anchor.top >= height + COPY_FEEDBACK_OFFSET_PX ? 'top' : 'bottom');\n }, [anchor.top]);\n\n if (typeof document === 'undefined') return null;\n\n return createPortal(\n <span\n ref={feedbackRef}\n role=\"status\"\n style={{\n left: anchor.left,\n top: placement === 'top' ? anchor.top : anchor.bottom,\n transform:\n placement === 'top'\n ? `translate(-50%, calc(-100% - ${COPY_FEEDBACK_OFFSET_PX}px))`\n : `translate(-50%, ${COPY_FEEDBACK_OFFSET_PX}px)`,\n }}\n className={cn(\n 'pointer-events-none fixed z-50 whitespace-nowrap rounded-8 bg-background-components-base px-8 py-4 text-xs font-display font-medium leading-20 shadow-tooltip',\n kind === 'failed' ? 'text-foreground-highlight-error' : 'text-foreground-neutral-base',\n )}\n >\n {children}\n </span>,\n document.body,\n );\n}\n"],"names":["useCopyToClipboard","Icon","Tooltip","TooltipContent","TooltipTrigger","Code","cn","useCallback","useEffect","useLayoutEffect","useRef","useState","createPortal","COPY_FEEDBACK_OFFSET_PX","Identifier","display","value","label","copyState","setCopyState","tooltipOpen","setTooltipOpen","feedbackAnchor","setFeedbackAnchor","buttonRef","timeoutRef","undefined","copy","text","onCopy","setTemporaryCopyState","current","clearTimeout","resetCopyFeedback","window","addEventListener","removeEventListener","state","timeout","rect","getBoundingClientRect","left","width","top","bottom","setTimeout","handleCopy","ariaLabel","feedback","kind","open","onOpenChange","asChild","button","ref","type","aria-label","onClick","className","name","aria-hidden","as","variant","CopyFeedbackPortal","anchor","children","feedbackRef","placement","setPlacement","height","offsetHeight","document","span","role","style","transform","body"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export { Identifier } from './identifier.js';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/identifier/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,UAAU,EAAC,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { Identifier } from './identifier.js';
2
+
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/components/identifier/index.ts"],"sourcesContent":["export {Identifier} from './identifier.js';\n"],"names":["Identifier"],"mappings":"AAAA,SAAQA,UAAU,QAAO,kBAAkB"}
@@ -0,0 +1,27 @@
1
+ import type { Job, WorkflowRunDetail } from '#core/workflow-run.js';
2
+ export type JobGraphNode = Job & {
3
+ column: number;
4
+ row: number;
5
+ currentDependencyCount: number;
6
+ };
7
+ export type JobGraphNavigationKey = 'ArrowRight' | 'ArrowLeft' | 'ArrowDown' | 'ArrowUp' | 'j' | 'k';
8
+ export interface JobGraphEdge {
9
+ id: string;
10
+ from: string;
11
+ to: string;
12
+ kind: 'trigger' | 'dependency';
13
+ }
14
+ export interface JobGraphModel {
15
+ nodes: JobGraphNode[];
16
+ edges: JobGraphEdge[];
17
+ columns: JobGraphNode[][];
18
+ }
19
+ export declare function buildJobGraphModel({ run }: {
20
+ run: WorkflowRunDetail;
21
+ }): JobGraphModel;
22
+ export declare function nextJobGraphNodeId({ model, currentNodeId, key, }: {
23
+ model: JobGraphModel;
24
+ currentNodeId: string;
25
+ key: JobGraphNavigationKey;
26
+ }): string | undefined;
27
+ //# sourceMappingURL=graph-model.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"graph-model.d.ts","sourceRoot":"","sources":["../../../src/components/job-graph/graph-model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,GAAG,EAAE,iBAAiB,EAAC,MAAM,uBAAuB,CAAC;AAElE,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,sBAAsB,EAAE,MAAM,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAC7B,YAAY,GACZ,WAAW,GACX,WAAW,GACX,SAAS,GACT,GAAG,GACH,GAAG,CAAC;AAER,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,SAAS,GAAG,YAAY,CAAC;CAChC;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,KAAK,EAAE,YAAY,EAAE,CAAC;IACtB,OAAO,EAAE,YAAY,EAAE,EAAE,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,EAAC,GAAG,EAAC,EAAE;IAAC,GAAG,EAAE,iBAAiB,CAAA;CAAC,GAAG,aAAa,CAwCjF;AA0ED,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,aAAa,EACb,GAAG,GACJ,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,GAAG,EAAE,qBAAqB,CAAC;CAC5B,GAAG,MAAM,GAAG,SAAS,CAgBrB"}