@tangle-network/charts 0.21.6 → 0.21.8

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.
@@ -47,7 +47,8 @@
47
47
  font-family: var(--font-sans, Inter, ui-sans-serif, system-ui, sans-serif);
48
48
  font-size: 14px;
49
49
  line-height: 20px;
50
- font-feature-settings: "tnum" 1, "cv11" 1;
50
+ /* Tabular figures only on numeric cells: on names they widen hyphens ("v6 - battery", "glm - 5.3"). */
51
+ font-feature-settings: "cv11" 1;
51
52
  -webkit-font-smoothing: antialiased;
52
53
  }
53
54
  .fw-root-agents { --fw-bar-h: 24px; --fw-label-col: min(var(--fw-name-w), 28%); border-radius: 16px; }
@@ -81,7 +82,7 @@
81
82
  .fw-root .fw-state::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
82
83
  .fw-root .fw-state-live { color: var(--fw-accent); background: color-mix(in oklab, var(--fw-accent) 12%, transparent); }
83
84
  .fw-root .fw-state-live::before { animation: fw-pulse 1.6s var(--fw-ease) infinite; }
84
- .fw-root .fw-headline { color: var(--fw-muted); font-variant-numeric: tabular-nums; display: flex; align-items: center; gap: 8px; }
85
+ .fw-root .fw-headline { color: var(--fw-muted); display: flex; align-items: center; gap: 8px; }
85
86
  .fw-root .fw-done-mark { display: inline-grid; place-items: center; width: 16px; height: 16px; border-radius: 50%; border: 1.5px solid var(--fw-ok); color: var(--fw-ok); font-size: 12px; line-height: 1; }
86
87
  .fw-root .fw-tools { display: flex; align-items: center; gap: 8px; }
87
88
  .fw-root .fw-views { display: inline-flex; padding: 4px; border-radius: 8px; background: var(--fw-well); border: 1px solid var(--fw-border); }
@@ -135,10 +136,9 @@
135
136
  background: repeating-linear-gradient(-45deg, color-mix(in oklab, var(--fw-text) 9%, transparent) 0 1px, transparent 1px 6px), color-mix(in oklab, var(--fw-text) 4%, transparent);
136
137
  border-inline: 1px dashed color-mix(in oklab, var(--fw-text) 24%, transparent); }
137
138
  .fw-root .fw-pause-label b { font-weight: 600; color: var(--fw-text); }
138
- .fw-root .fw-pause { overflow: visible; }
139
- .fw-root .fw-pause-label { position: sticky; top: 4px; display: block; width: max-content; margin: 4px 0 0 50%; translate: -50% 0; padding: 0 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
139
+ .fw-root .fw-pause-label { position: absolute; z-index: 2; top: 50%; left: calc(var(--fw-pad) + ((var(--s) + var(--e)) / 2 - var(--fw-v0)) * var(--fw-k) * 1px); translate: -50% -50%; width: max-content; padding: 0 8px; white-space: nowrap;
140
140
  border-radius: 4px; font-size: 12px; line-height: 20px; color: var(--fw-muted); background: var(--fw-surface); box-shadow: inset 0 0 0 1px var(--fw-border); }
141
- /* The label alone takes the pointer, for its reason; the band stays click-through to the rows. */
141
+ /* The label takes the pointer, for its reason; the band stays click-through to the rows. */
142
142
  .fw-root .fw-pause-label[title] { pointer-events: auto; cursor: help; }
143
143
  .fw-root .fw-marker-label { position: absolute; top: 2px; left: 3px; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 4px; border-radius: 4px; font-size: 12px; line-height: 16px; color: var(--fw-marker); background: var(--fw-surface); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-marker) 40%, transparent); }
144
144
  .fw-root .fw-marker-label-left { left: auto; right: 3px; }
@@ -235,7 +235,11 @@
235
235
  /* An agent bar with no child marks says who it is by its lane color, never a neutral grey. */
236
236
  /* In the agent view the bar's own extent between steps is waiting: hatched in the outcome tone, under the step segments. */
237
237
  .fw-root .fw-view-agents .fw-bar.fw-k-pipeline.fw-has-marks { background: repeating-linear-gradient(-45deg, color-mix(in oklab, var(--tone) 28%, transparent) 0 1px, transparent 1px 5px), color-mix(in oklab, var(--tone) 9%, transparent); }
238
- .fw-root .fw-view-agents .fw-bar.fw-k-pipeline:not(.fw-has-marks, .fw-has-agents) { background: var(--fill); box-shadow: inset 0 0 0 1px var(--line); }
238
+ /* An agent lane is a tint of its color; full saturation is kept for its model and tool segments and its status dot, so a run never
239
+ reads as a wall of colored slabs. */
240
+ .fw-root .fw-view-agents .fw-bar.fw-k-pipeline:not(.fw-has-marks, .fw-has-agents) { background: color-mix(in oklab, var(--tone) 30%, var(--fw-surface)); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--tone) 55%, transparent); }
241
+ /* A family row without one shared outcome is neutral when bars mean outcomes, not a hue of its own. */
242
+ .fw-root.fw-fill-outcome .fw-view-agents .fw-row[data-span-id^="family:"]:not([data-outcome]), .fw-root.fw-fill-outcome .fw-view-agents .fw-row[data-span-id^="family:"]:not([data-outcome]) [data-tone] { --tone: var(--fw-h0); }
239
243
  /* A host outcome re-tones the whole lane: dot, bar and marks. */
240
244
  /* Muted agents (the default): one quiet tone for every agent bar, its steps and handoffs; the slowest agent alone takes amber, and
241
245
  failure keeps its red glyph, so color only ever means state. */
@@ -2755,6 +2755,7 @@ function agentFamilies(agents, open) {
2755
2755
  const running = members.some((row) => spanRunning(row.span));
2756
2756
  const known = members.map((row) => row.span.costUsd ?? row.rollupCostUsd).filter((cost) => cost !== void 0);
2757
2757
  const failed = members.filter((row) => !row.ok).length;
2758
+ const outcome = members.every((row) => row.span.outcome && row.span.outcome.tone === members[0].span.outcome?.tone) ? members[0].span.outcome : void 0;
2758
2759
  out.push({
2759
2760
  costFloor: known.length < members.length || members.some((row) => row.costFloor),
2760
2761
  id,
@@ -2784,6 +2785,7 @@ function agentFamilies(agents, open) {
2784
2785
  startMs,
2785
2786
  endMs,
2786
2787
  status: running ? "running" : failed ? "failed" : "done",
2788
+ ...outcome ? { outcome } : {},
2787
2789
  detail: members[0].span.detail,
2788
2790
  meta: {
2789
2791
  failedAgents: failed,
@@ -3752,6 +3754,22 @@ function FlowBody(props) {
3752
3754
  trackPx,
3753
3755
  view
3754
3756
  ]);
3757
+ const pauseLabels = useMemo(() => {
3758
+ const shown = /* @__PURE__ */ new Set();
3759
+ let freeFrom = -Infinity;
3760
+ for (const pause of [...props.pauses ?? []].sort((a, b) => a.startMs - b.startMs)) {
3761
+ const width = duration(pause.endMs - pause.startMs).length * 7 + 24;
3762
+ const centre = ((pause.startMs + pause.endMs) / 2 - win.startMs) / msPerPx;
3763
+ if (centre - width / 2 < freeFrom) continue;
3764
+ shown.add(pause);
3765
+ freeFrom = centre + width / 2 + 8;
3766
+ }
3767
+ return shown;
3768
+ }, [
3769
+ props.pauses,
3770
+ win.startMs,
3771
+ msPerPx
3772
+ ]);
3755
3773
  useEffect(() => {
3756
3774
  const element = scroller.current;
3757
3775
  if (!element) return;
@@ -3922,6 +3940,18 @@ function FlowBody(props) {
3922
3940
  props.onScrub(marker.at);
3923
3941
  }
3924
3942
  }, `e-${marker.at}-${marker.label}`)),
3943
+ props.pauses?.filter((pause) => pauseLabels.has(pause)).map((pause) => /* @__PURE__ */ jsx("span", {
3944
+ className: "fw-pause-label",
3945
+ style: {
3946
+ "--s": pause.startMs,
3947
+ "--e": pause.endMs
3948
+ },
3949
+ title: pause.detail ? `${pause.label}: ${pause.detail}` : pause.label,
3950
+ tabIndex: 0,
3951
+ "aria-label": `${pause.label}, ${duration(pause.endMs - pause.startMs)}${pause.detail ? `: ${pause.detail}` : ""}`,
3952
+ onPointerDown: (event) => event.stopPropagation(),
3953
+ children: /* @__PURE__ */ jsx("b", { children: duration(pause.endMs - pause.startMs) })
3954
+ }, `pl-${pause.startMs}`)),
3925
3955
  jumped && /* @__PURE__ */ jsx("span", {
3926
3956
  className: "fw-event-label",
3927
3957
  "data-tone": jumped.tone ?? "neutral",
@@ -4028,14 +4058,7 @@ function FlowBody(props) {
4028
4058
  "--s": pause.startMs,
4029
4059
  "--e": pause.endMs
4030
4060
  },
4031
- title: pause.label,
4032
- children: /* @__PURE__ */ jsx("span", {
4033
- className: "fw-pause-label",
4034
- title: pause.detail ? `${pause.label}: ${pause.detail}` : pause.label,
4035
- tabIndex: 0,
4036
- "aria-label": `${pause.label}, ${duration(pause.endMs - pause.startMs)}${pause.detail ? `: ${pause.detail}` : ""}`,
4037
- children: /* @__PURE__ */ jsx("b", { children: duration(pause.endMs - pause.startMs) })
4038
- })
4061
+ title: `${pause.label}, ${duration(pause.endMs - pause.startMs)}`
4039
4062
  }, `p-${pause.startMs}`)), props.markers?.map((marker) => /* @__PURE__ */ jsx("span", {
4040
4063
  className: "fw-marker",
4041
4064
  "data-tone": marker.tone ?? "neutral",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/charts",
3
- "version": "0.21.6",
3
+ "version": "0.21.8",
4
4
  "description": "Static SVG and HTML figures for benchmarks and operational timing. Draws from producer data and refuses what it cannot draw honestly.",
5
5
  "type": "module",
6
6
  "license": "MIT",