@nice-code/action 0.2.16 → 0.2.17

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 (28) hide show
  1. package/build/devtools/browser/index.js +2113 -1362
  2. package/build/devtools/server/index.js +35 -7
  3. package/build/index.js +112 -22
  4. package/build/types/ActionDefinition/Action/Payload/ActionPayload.types.d.ts +3 -1
  5. package/build/types/ActionDefinition/Action/Payload/ActionPayload_Request.d.ts +1 -0
  6. package/build/types/ActionDefinition/Action/Payload/ActionPayload_Result.d.ts +1 -0
  7. package/build/types/ActionDefinition/Action/RunningAction.d.ts +1 -0
  8. package/build/types/ActionDefinition/Domain/ActionDomain.d.ts +2 -1
  9. package/build/types/ActionDefinition/Domain/ActionRootDomain.d.ts +1 -1
  10. package/build/types/ActionDefinition/Schema/ActionSchema.d.ts +0 -18
  11. package/build/types/devtools/browser/components/ActionErrorDisplay.d.ts +4 -0
  12. package/build/types/devtools/browser/components/ChildDispatchChips.d.ts +5 -3
  13. package/build/types/devtools/browser/components/Chip.d.ts +17 -5
  14. package/build/types/devtools/browser/components/DomainChip.d.ts +3 -11
  15. package/build/types/devtools/browser/components/HandlerChips.d.ts +2 -1
  16. package/build/types/devtools/browser/components/Icon.d.ts +15 -0
  17. package/build/types/devtools/browser/components/NiceErrorDisplay.d.ts +19 -0
  18. package/build/types/devtools/browser/components/StackTraceSection.d.ts +3 -1
  19. package/build/types/devtools/browser/components/Tooltip.d.ts +14 -0
  20. package/build/types/devtools/browser/components/{ActionDetailPanel.d.ts → action_detail/ActionDetailPanel.d.ts} +1 -1
  21. package/build/types/devtools/browser/components/action_list/ActionEntryRow.d.ts +13 -0
  22. package/build/types/devtools/browser/components/utils.d.ts +4 -0
  23. package/build/types/devtools/browser/ui_util/size.d.ts +6 -0
  24. package/build/types/devtools/core/ActionDevtools.types.d.ts +4 -1
  25. package/build/types/devtools/core/devtools_colors.d.ts +57 -0
  26. package/build/types/utils/hashPayloadData.d.ts +5 -0
  27. package/package.json +4 -3
  28. package/build/types/devtools/browser/components/ActionEntryRow.d.ts +0 -11
@@ -1827,6 +1827,12 @@ var require_source_node = __commonJS((exports) => {
1827
1827
  });
1828
1828
 
1829
1829
  // src/devtools/core/ActionDevtoolsCore.ts
1830
+ function serializeErrorForDisplay(error) {
1831
+ if (error != null && typeof error === "object" && error.name === "NiceError" && typeof error.toJsonObject === "function") {
1832
+ return error.toJsonObject();
1833
+ }
1834
+ return error;
1835
+ }
1830
1836
  function extractRouting(context) {
1831
1837
  return (context?.routing ?? []).map((item) => {
1832
1838
  const handler = item.handler;
@@ -1876,6 +1882,7 @@ class ActionDevtoolsCore {
1876
1882
  status: "running",
1877
1883
  startTime: time,
1878
1884
  input: runningAction.state?.request?.input,
1885
+ inputHash: runningAction.state?.request?.inputHash,
1879
1886
  progressUpdates: [],
1880
1887
  meta: extractMeta(runningAction.context),
1881
1888
  parentCuid: runningAction.parentCuid,
@@ -1898,16 +1905,29 @@ class ActionDevtoolsCore {
1898
1905
  };
1899
1906
  const finishType = update.finishType;
1900
1907
  if (finishType === "success" /* success */) {
1901
- return { ...base, status: "success", output: update.response?.result?.output };
1908
+ const result = update.response?.result;
1909
+ const outputHash = update.response?.outputHash;
1910
+ if (result != null && !result.ok) {
1911
+ const rawError = result.error;
1912
+ const errorStack2 = rawError instanceof Error ? rawError.stack : undefined;
1913
+ return {
1914
+ ...base,
1915
+ status: "action-error",
1916
+ outputHash,
1917
+ error: serializeErrorForDisplay(rawError),
1918
+ errorStack: errorStack2
1919
+ };
1920
+ }
1921
+ return { ...base, status: "success", output: result?.output, outputHash };
1902
1922
  }
1903
1923
  if (finishType === "failed" /* failed */) {
1904
1924
  const rawError = update.error;
1905
1925
  const errorStack2 = rawError instanceof Error ? rawError.stack : undefined;
1906
- return { ...base, status: "failed", error: rawError, errorStack: errorStack2 };
1926
+ return { ...base, status: "failed", error: serializeErrorForDisplay(rawError), errorStack: errorStack2 };
1907
1927
  }
1908
1928
  const abortReason = update.reason;
1909
1929
  const errorStack = abortReason instanceof Error ? abortReason.stack : undefined;
1910
- return { ...base, status: "aborted", abortReason, errorStack };
1930
+ return { ...base, status: "aborted", abortReason: serializeErrorForDisplay(abortReason), errorStack };
1911
1931
  });
1912
1932
  }
1913
1933
  });
@@ -1937,204 +1957,176 @@ class ActionDevtoolsCore {
1937
1957
  }
1938
1958
  }
1939
1959
  // src/devtools/browser/NiceActionDevtools.tsx
1940
- import { useCallback, useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState6 } from "react";
1941
-
1942
- // src/devtools/browser/components/ActionDetailPanel.tsx
1943
- import { useMemo, useState as useState5 } from "react";
1960
+ import { useEffect as useEffect3, useMemo as useMemo2, useRef, useState as useState9 } from "react";
1944
1961
 
1945
1962
  // src/devtools/core/devtools_colors.ts
1963
+ var DEVTOOL_COLOR_SEMANTIC_ERROR = "#FF5C5C";
1964
+ var DEVTOOL_COLOR_SEMANTIC_SUCCESS = "#A3E635";
1965
+ var DEVTOOL_COLOR_SEMANTIC_SYSTEM = "#38BDF8";
1966
+ var DEVTOOL_COLOR_SEMANTIC_WARNING = "#FB923C";
1967
+ var DEVTOOL_COLOR_SEMANTIC_METADATA = "#A1A1AA";
1946
1968
  var DEVTOOL_COLOR_HANDLER_LOCAL_TEXT = "#34bb89";
1947
1969
  var DEVTOOL_COLOR_HANDLER_LOCAL_BORDER = "#144427";
1948
1970
  var DEVTOOL_COLOR_HANDLER_EXTERNAL_TEXT = "#cfa12a";
1949
1971
  var DEVTOOL_COLOR_HANDLER_EXTERNAL_BORDER = "#723917";
1972
+ var DEVTOOL_COLOR_TEXT_EMPHASIS = "#f1f5f9";
1973
+ var DEVTOOL_COLOR_TEXT_SECONDARY = "#cbd5e1";
1974
+ var DEVTOOL_COLOR_TEXT_MUTED = "#64748b";
1975
+ var DEVTOOL_COLOR_TEXT_FAINT = "#334155";
1976
+ var DEVTOOL_LIST_BASE_BACKGROUND = "#0f172a";
1977
+ var DEVTOOL_LIST_GROUP_DIVIDER = "#101109";
1978
+ var DEVTOOL_DETAIL_BASE_BACKGROUND = "#0d1729";
1979
+ var DEVTOOL_DETAIL_HEADER_BACKGROUND = "#131f35";
1980
+ var DEVTOOL_SECTION_BACKGROUND = "#1e293b";
1981
+ var DEVTOOL_SECTION_STRING_BACKGROUND = "#0d131f";
1982
+ var DEVTOOL_STACK_TRACE_BACKGROUND = "#040a13";
1983
+ var DEVTOOL_PANEL_BORDER = "#1e293b";
1984
+ var DEVTOOL_PANEL_DIVIDER_BORDER = "#1d3352";
1985
+ var DEVTOOL_ERROR_BACKGROUND = "#1e0a0a";
1986
+ var DEVTOOL_ERROR_BADGE_BACKGROUND = "#2d0f0f";
1987
+ var DEVTOOL_TOOLTIP_BACKGROUND = "#0c1526";
1988
+ var DEVTOOL_TOOLTIP_TITLE_BACKGROUND = "#101b2e";
1989
+ var DEVTOOL_TOOLTIP_TITLE_BOTTOM_BORDER = "#211f5f";
1990
+ var DEVTOOL_TOOLTIP_BORDER = "#312e81";
1991
+ var DEVTOOL_COLOR_CALL_STACK_DIVIDER = "#0a1120";
1992
+ var DEVTOOL_JSON_KEY = "#a5b4fc";
1993
+ var DEVTOOL_JSON_STRING = "#fbbf24";
1994
+ var DEVTOOL_JSON_NUMBER = "#34d399";
1995
+ var DEVTOOL_JSON_KEYWORD = "#a78bfa";
1996
+ var DEVTOOL_JSON_PUNCTUATION = "#475569";
1997
+ var DEVTOOL_STACK_FRAME_USER_NUMBER = "#64748b";
1998
+ var DEVTOOL_STACK_FRAME_USER_FUNCTION = "#e2e8f0";
1999
+ var DEVTOOL_STACK_FRAME_USER_FOLDER = "#596b83";
2000
+ var DEVTOOL_STACK_FRAME_USER_FILE = "#8a9ebb";
2001
+ var DEVTOOL_STACK_FRAME_USER_LINE = "#4a7fa8";
2002
+ var DEVTOOL_STACK_FRAME_INTERNAL_NUMBER = "#2d3f53";
2003
+ var DEVTOOL_STACK_FRAME_INTERNAL_FUNCTION = "#50698b";
2004
+ var DEVTOOL_STACK_FRAME_INTERNAL_FOLDER = "#2d3f53";
2005
+ var DEVTOOL_STACK_FRAME_INTERNAL_FILE = "#425979";
2006
+ var DEVTOOL_STACK_FRAME_INTERNAL_LINE = "#2d4a63";
2007
+ var SEMANTIC_COLORS = {
2008
+ running_action: {
2009
+ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
2010
+ borderColor: `${DEVTOOL_COLOR_SEMANTIC_SYSTEM}55`
2011
+ },
2012
+ success: {
2013
+ color: DEVTOOL_COLOR_SEMANTIC_SUCCESS,
2014
+ borderColor: `${DEVTOOL_COLOR_SEMANTIC_SUCCESS}55`
2015
+ },
2016
+ action_error: {
2017
+ color: DEVTOOL_COLOR_SEMANTIC_WARNING,
2018
+ borderColor: `${DEVTOOL_COLOR_SEMANTIC_WARNING}55`
2019
+ },
2020
+ failed: {
2021
+ color: DEVTOOL_COLOR_SEMANTIC_ERROR,
2022
+ borderColor: `${DEVTOOL_COLOR_SEMANTIC_ERROR}55`
2023
+ },
2024
+ aborted: {
2025
+ color: DEVTOOL_COLOR_SEMANTIC_METADATA,
2026
+ borderColor: DEVTOOL_COLOR_TEXT_FAINT
2027
+ },
2028
+ error: {
2029
+ color: DEVTOOL_COLOR_SEMANTIC_ERROR,
2030
+ borderColor: DEVTOOL_COLOR_SEMANTIC_ERROR
2031
+ },
2032
+ domain: {
2033
+ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
2034
+ borderColor: `${DEVTOOL_COLOR_SEMANTIC_SYSTEM}55`,
2035
+ subtle: { color: "#4b5563", borderColor: "transparent" }
2036
+ },
2037
+ handler_local: {
2038
+ color: DEVTOOL_COLOR_HANDLER_LOCAL_TEXT,
2039
+ borderColor: DEVTOOL_COLOR_HANDLER_LOCAL_BORDER
2040
+ },
2041
+ handler_external: {
2042
+ color: DEVTOOL_COLOR_HANDLER_EXTERNAL_TEXT,
2043
+ borderColor: DEVTOOL_COLOR_HANDLER_EXTERNAL_BORDER
2044
+ },
2045
+ age: {
2046
+ color: DEVTOOL_COLOR_SEMANTIC_METADATA,
2047
+ borderColor: DEVTOOL_SECTION_BACKGROUND
2048
+ },
2049
+ io_input: {
2050
+ color: "#fbbf24",
2051
+ borderColor: "#78350f"
2052
+ },
2053
+ io_output: {
2054
+ color: "#a78bfa",
2055
+ borderColor: "#4c1d95"
2056
+ },
2057
+ default: {
2058
+ color: DEVTOOL_COLOR_TEXT_MUTED,
2059
+ borderColor: DEVTOOL_COLOR_TEXT_FAINT
2060
+ }
2061
+ };
1950
2062
 
1951
- // src/devtools/browser/components/DomainChip.tsx
1952
- import { createContext, useContext, useRef } from "react";
1953
- import { jsxDEV } from "react/jsx-dev-runtime";
1954
- var DomainTooltipCtx = createContext(null);
1955
- function DomainHierarchyTooltip({
1956
- allDomains,
1957
- anchor
1958
- }) {
1959
- return /* @__PURE__ */ jsxDEV("div", {
1960
- style: {
1961
- position: "fixed",
1962
- left: anchor.left,
1963
- top: anchor.top - 6,
1964
- transform: "translateY(-100%)",
1965
- zIndex: 2147483647,
1966
- background: "#0c1526",
1967
- border: "1px solid #312e81",
1968
- borderRadius: "5px",
1969
- padding: "6px 8px",
1970
- fontFamily: "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace",
1971
- boxShadow: "0 4px 20px rgba(0,0,0,0.6)",
1972
- pointerEvents: "none",
1973
- minWidth: "80px"
1974
- },
1975
- children: allDomains.map((d, i) => {
1976
- const isCurrent = i === allDomains.length - 1;
1977
- return /* @__PURE__ */ jsxDEV("div", {
1978
- style: {
1979
- display: "flex",
1980
- alignItems: "center",
1981
- gap: "0.3rem",
1982
- paddingLeft: `${i * 10}px`,
1983
- paddingTop: i > 0 ? "0.1rem" : undefined
1984
- },
1985
- children: [
1986
- /* @__PURE__ */ jsxDEV("span", {
1987
- style: {
1988
- fontSize: "0.8rem",
1989
- height: "0.6em",
1990
- width: "0.6em",
1991
- overflow: "hidden",
1992
- color: isCurrent ? "#818cf8" : "#3730a3",
1993
- display: "flex",
1994
- alignItems: "center",
1995
- justifyContent: "center"
1996
- },
1997
- children: "⬢"
1998
- }, undefined, false, undefined, this),
1999
- /* @__PURE__ */ jsxDEV("span", {
2000
- style: {
2001
- color: isCurrent ? "#a5b4fc" : "#4b5563",
2002
- fontSize: "0.7rem",
2003
- fontWeight: isCurrent ? 500 : undefined
2004
- },
2005
- children: d
2006
- }, undefined, false, undefined, this)
2007
- ]
2008
- }, d, true, undefined, this);
2009
- })
2010
- }, undefined, false, undefined, this);
2011
- }
2012
- function DomainChip({
2013
- subtle = false,
2014
- domain,
2015
- allDomains,
2016
- size
2017
- }) {
2018
- const ctx = useContext(DomainTooltipCtx);
2019
- const chipRef = useRef(null);
2020
- const hasHierarchy = allDomains != null && allDomains.length > 1;
2021
- const fontSize = size === "md" ? "0.7rem" : "0.6rem";
2022
- const padding = size === "md" ? "1px 5px" : "1px 4px";
2023
- return /* @__PURE__ */ jsxDEV("span", {
2024
- ref: chipRef,
2025
- onMouseEnter: hasHierarchy && ctx != null ? () => {
2026
- if (chipRef.current != null)
2027
- ctx.show(chipRef.current.getBoundingClientRect(), allDomains);
2028
- } : undefined,
2029
- onMouseLeave: hasHierarchy && ctx != null ? () => ctx.hide() : undefined,
2030
- style: {
2031
- display: "flex",
2032
- alignItems: "center",
2033
- gap: "0.4em",
2034
- color: subtle ? "#4b5563" : "#818cf8",
2035
- fontSize,
2036
- background: "#0f172a",
2037
- border: !subtle ? "1px solid #312e81" : "1px solid transparent",
2038
- padding,
2039
- borderRadius: "0.6rem",
2040
- flexShrink: 0,
2041
- whiteSpace: "nowrap"
2042
- },
2043
- children: [
2044
- /* @__PURE__ */ jsxDEV("span", {
2045
- style: {
2046
- fontSize: size === "md" ? "0.9rem" : "0.8rem",
2047
- height: "0.6em",
2048
- width: "0.6em",
2049
- display: "flex",
2050
- alignItems: "center",
2051
- justifyContent: "center"
2052
- },
2053
- children: "⬢"
2054
- }, undefined, false, undefined, this),
2055
- /* @__PURE__ */ jsxDEV("span", {
2056
- children: domain
2057
- }, undefined, false, undefined, this)
2058
- ]
2059
- }, undefined, true, undefined, this);
2063
+ // src/devtools/browser/components/action_detail/ActionDetailPanel.tsx
2064
+ import { useMemo, useState as useState6 } from "react";
2065
+
2066
+ // src/devtools/browser/ui_util/size.ts
2067
+ function getSizeValue(size) {
2068
+ switch (size) {
2069
+ case "sm" /* sm */:
2070
+ return 0.8;
2071
+ case "md" /* md */:
2072
+ return 1;
2073
+ case "lg" /* lg */:
2074
+ return 1.2;
2075
+ default:
2076
+ return 1;
2077
+ }
2060
2078
  }
2061
2079
 
2062
- // src/devtools/browser/components/Chip.tsx
2063
- import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
2064
- function Chip({
2065
- color,
2066
- borderColor,
2067
- fontSize = "8px",
2068
- padding = "1px 4px",
2069
- children,
2070
- style
2071
- }) {
2072
- return /* @__PURE__ */ jsxDEV2("span", {
2080
+ // src/devtools/browser/components/DetailSection.tsx
2081
+ import { useState } from "react";
2082
+
2083
+ // src/devtools/browser/components/SectionLabel.tsx
2084
+ import { jsxDEV } from "react/jsx-dev-runtime";
2085
+ function SectionLabel({ label, color = DEVTOOL_COLOR_SEMANTIC_SYSTEM }) {
2086
+ return /* @__PURE__ */ jsxDEV("div", {
2073
2087
  style: {
2074
2088
  color,
2075
- fontSize,
2076
- background: "#0f172a",
2077
- border: `1px solid ${borderColor}`,
2078
- padding,
2079
- borderRadius: "3px",
2080
- flexShrink: 0,
2081
- whiteSpace: "nowrap",
2082
- ...style
2089
+ fontSize: "0.85em",
2090
+ marginBottom: "3px",
2091
+ textTransform: "uppercase",
2092
+ letterSpacing: "0.05em",
2093
+ fontWeight: 500,
2094
+ textAlign: "left"
2083
2095
  },
2084
- children
2096
+ children: label
2085
2097
  }, undefined, false, undefined, this);
2086
2098
  }
2087
2099
 
2088
- // src/devtools/browser/components/HandlerChips.tsx
2089
- import { jsxDEV as jsxDEV3, Fragment } from "react/jsx-dev-runtime";
2090
- function getExternalLabel(hop) {
2091
- if (hop.handlerType !== "external")
2092
- return null;
2093
- return hop.handlerClient != null ? `${hop.transport ?? "ext"} → ${hop.handlerClient.envId}` : `→ ${hop.transport ?? "ext"}`;
2094
- }
2095
- function HandlerChips({ entry, size }) {
2096
- const firstHop = entry.meta.routing[0];
2097
- const localEnvId = firstHop != null ? firstHop.runtime.envId : null;
2098
- const externalLabel = firstHop != null ? getExternalLabel(firstHop) : null;
2099
- const fontSize = size === "md" ? "1em" : "0.8em";
2100
- const padding = size === "md" ? "1px 5px" : "1px 4px";
2101
- const firstHopIsLocal = firstHop != null && firstHop.handlerType === "local";
2102
- return /* @__PURE__ */ jsxDEV3(Fragment, {
2103
- children: [
2104
- localEnvId != null && (firstHopIsLocal || externalLabel == null) && /* @__PURE__ */ jsxDEV3(Chip, {
2105
- color: DEVTOOL_COLOR_HANDLER_LOCAL_TEXT,
2106
- borderColor: DEVTOOL_COLOR_HANDLER_LOCAL_BORDER,
2107
- fontSize,
2108
- padding,
2109
- children: "local"
2110
- }, undefined, false, undefined, this),
2111
- externalLabel != null && /* @__PURE__ */ jsxDEV3(Chip, {
2112
- color: DEVTOOL_COLOR_HANDLER_EXTERNAL_TEXT,
2113
- borderColor: DEVTOOL_COLOR_HANDLER_EXTERNAL_BORDER,
2114
- fontSize,
2115
- padding,
2116
- children: externalLabel
2117
- }, undefined, false, undefined, this)
2118
- ]
2119
- }, undefined, true, undefined, this);
2120
- }
2121
-
2122
- // src/devtools/browser/components/RunningTimer.tsx
2123
- import { useEffect, useState } from "react";
2124
-
2125
2100
  // src/devtools/browser/components/utils.ts
2101
+ import { Circle, CircleAlert, CircleCheck, CircleX, Loader2 } from "lucide-react";
2126
2102
  var STATUS_COLOR = {
2127
- running: "#60a5fa",
2128
- success: "#4ade80",
2129
- failed: "#f87171",
2130
- aborted: "#9ca3af"
2103
+ running: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
2104
+ success: DEVTOOL_COLOR_SEMANTIC_SUCCESS,
2105
+ "action-error": DEVTOOL_COLOR_SEMANTIC_WARNING,
2106
+ failed: DEVTOOL_COLOR_SEMANTIC_ERROR,
2107
+ aborted: DEVTOOL_COLOR_SEMANTIC_METADATA
2108
+ };
2109
+ var STATUS_THING = {
2110
+ running: "running_action" /* running_action */,
2111
+ success: "success" /* success */,
2112
+ "action-error": "action_error" /* action_error */,
2113
+ failed: "failed" /* failed */,
2114
+ aborted: "aborted" /* aborted */
2131
2115
  };
2132
2116
  var STATUS_SYMBOL = {
2133
2117
  running: "●",
2134
2118
  success: "✓",
2119
+ "action-error": "!",
2135
2120
  failed: "✗",
2136
2121
  aborted: "○"
2137
2122
  };
2123
+ var STATUS_ICON = {
2124
+ running: Loader2,
2125
+ success: CircleCheck,
2126
+ "action-error": CircleAlert,
2127
+ failed: CircleX,
2128
+ aborted: Circle
2129
+ };
2138
2130
  function safeStringify(value, indent = 2) {
2139
2131
  if (value === undefined)
2140
2132
  return "undefined";
@@ -2165,214 +2157,405 @@ function formatTimestamp(startTime) {
2165
2157
  });
2166
2158
  }
2167
2159
 
2168
- // src/devtools/browser/components/RunningTimer.tsx
2169
- import { jsxDEV as jsxDEV4, Fragment as Fragment2 } from "react/jsx-dev-runtime";
2170
- function RunningTimer({ startTime }) {
2171
- const [elapsed, setElapsed] = useState(() => Date.now() - startTime);
2172
- useEffect(() => {
2173
- const interval = setInterval(() => setElapsed(Date.now() - startTime), 100);
2174
- return () => clearInterval(interval);
2175
- }, [startTime]);
2176
- return /* @__PURE__ */ jsxDEV4(Fragment2, {
2160
+ // src/devtools/browser/components/DetailSection.tsx
2161
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
2162
+ var COMPACT_CHAR_LIMIT = 120;
2163
+ var MONO = "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace";
2164
+ var JSON_TOKEN_RE = /("(?:\\.|[^"\\])*")(\s*:)?|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b|\bnull\b|\bundefined\b)|([{}[\],])/g;
2165
+ function renderColoredJson(text) {
2166
+ const nodes = [];
2167
+ let last = 0;
2168
+ let i = 0;
2169
+ JSON_TOKEN_RE.lastIndex = 0;
2170
+ for (let m = JSON_TOKEN_RE.exec(text);m !== null; m = JSON_TOKEN_RE.exec(text)) {
2171
+ if (m.index > last)
2172
+ nodes.push(text.slice(last, m.index));
2173
+ const [, str, colon, num, kw, punct] = m;
2174
+ if (str != null) {
2175
+ if (colon != null) {
2176
+ nodes.push(/* @__PURE__ */ jsxDEV2("span", {
2177
+ style: { color: DEVTOOL_JSON_KEY },
2178
+ children: str
2179
+ }, i++, false, undefined, this));
2180
+ nodes.push(/* @__PURE__ */ jsxDEV2("span", {
2181
+ style: { color: DEVTOOL_JSON_PUNCTUATION },
2182
+ children: colon
2183
+ }, i++, false, undefined, this));
2184
+ } else {
2185
+ nodes.push(/* @__PURE__ */ jsxDEV2("span", {
2186
+ style: { color: DEVTOOL_JSON_STRING },
2187
+ children: str
2188
+ }, i++, false, undefined, this));
2189
+ }
2190
+ } else if (num != null) {
2191
+ nodes.push(/* @__PURE__ */ jsxDEV2("span", {
2192
+ style: { color: DEVTOOL_JSON_NUMBER },
2193
+ children: num
2194
+ }, i++, false, undefined, this));
2195
+ } else if (kw != null) {
2196
+ nodes.push(/* @__PURE__ */ jsxDEV2("span", {
2197
+ style: { color: DEVTOOL_JSON_KEYWORD },
2198
+ children: kw
2199
+ }, i++, false, undefined, this));
2200
+ } else if (punct != null) {
2201
+ nodes.push(/* @__PURE__ */ jsxDEV2("span", {
2202
+ style: { color: DEVTOOL_JSON_PUNCTUATION },
2203
+ children: punct
2204
+ }, i++, false, undefined, this));
2205
+ }
2206
+ last = JSON_TOKEN_RE.lastIndex;
2207
+ }
2208
+ if (last < text.length)
2209
+ nodes.push(text.slice(last));
2210
+ return nodes;
2211
+ }
2212
+ function tryParseJson(s) {
2213
+ try {
2214
+ return JSON.parse(s);
2215
+ } catch {
2216
+ return null;
2217
+ }
2218
+ }
2219
+ function DetailSection({
2220
+ label,
2221
+ value,
2222
+ color = DEVTOOL_COLOR_SEMANTIC_SYSTEM
2223
+ }) {
2224
+ const parsedFromString = typeof value === "string" ? tryParseJson(value) : null;
2225
+ const isPlainString = typeof value === "string" && parsedFromString === null;
2226
+ const effectiveValue = parsedFromString !== null ? parsedFromString : value;
2227
+ const [expanded, setExpanded] = useState(false);
2228
+ const fullJson = isPlainString ? value : safeStringify(effectiveValue, 2);
2229
+ const compactJson = isPlainString ? value : safeStringify(effectiveValue, 0);
2230
+ const canExpand = fullJson !== compactJson || compactJson.length > COMPACT_CHAR_LIMIT;
2231
+ const compactDisplay = compactJson.length > COMPACT_CHAR_LIMIT ? `${compactJson.slice(0, COMPACT_CHAR_LIMIT)}…` : compactJson;
2232
+ const baseStyle = isPlainString ? { background: DEVTOOL_SECTION_STRING_BACKGROUND, color: DEVTOOL_COLOR_TEXT_MUTED } : { background: DEVTOOL_SECTION_BACKGROUND, color: DEVTOOL_COLOR_TEXT_SECONDARY };
2233
+ return /* @__PURE__ */ jsxDEV2("div", {
2177
2234
  children: [
2178
- elapsed,
2179
- "ms"
2235
+ /* @__PURE__ */ jsxDEV2("div", {
2236
+ style: {
2237
+ display: "flex",
2238
+ alignItems: "center",
2239
+ justifyContent: "space-between",
2240
+ marginBottom: "3px"
2241
+ },
2242
+ children: [
2243
+ /* @__PURE__ */ jsxDEV2(SectionLabel, {
2244
+ label,
2245
+ color
2246
+ }, undefined, false, undefined, this),
2247
+ canExpand && /* @__PURE__ */ jsxDEV2("span", {
2248
+ style: { color: DEVTOOL_COLOR_TEXT_FAINT, fontSize: "11px" },
2249
+ children: expanded ? "▾" : "▸"
2250
+ }, undefined, false, undefined, this)
2251
+ ]
2252
+ }, undefined, true, undefined, this),
2253
+ expanded ? /* @__PURE__ */ jsxDEV2("div", {
2254
+ onClick: canExpand ? () => setExpanded(false) : undefined,
2255
+ style: {
2256
+ margin: 0,
2257
+ padding: "6px 8px",
2258
+ borderRadius: "4px",
2259
+ fontSize: "11px",
2260
+ fontFamily: MONO,
2261
+ overflowX: "auto",
2262
+ textAlign: "left",
2263
+ whiteSpace: "pre-wrap",
2264
+ wordBreak: "break-all",
2265
+ cursor: canExpand ? "pointer" : "default",
2266
+ fontStyle: isPlainString ? "italic" : "normal",
2267
+ ...baseStyle
2268
+ },
2269
+ children: isPlainString ? fullJson : renderColoredJson(fullJson)
2270
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV2("div", {
2271
+ onClick: canExpand ? () => setExpanded(true) : undefined,
2272
+ style: {
2273
+ padding: "5px 8px",
2274
+ borderRadius: "4px",
2275
+ fontSize: "11px",
2276
+ fontFamily: MONO,
2277
+ whiteSpace: "nowrap",
2278
+ overflow: "hidden",
2279
+ textOverflow: "ellipsis",
2280
+ cursor: canExpand ? "pointer" : "default",
2281
+ fontStyle: isPlainString ? "italic" : "normal",
2282
+ ...baseStyle
2283
+ },
2284
+ children: compactDisplay
2285
+ }, undefined, false, undefined, this)
2180
2286
  ]
2181
2287
  }, undefined, true, undefined, this);
2182
2288
  }
2183
- function DurationDisplay({ entry }) {
2184
- const d = formatDuration(entry);
2185
- return /* @__PURE__ */ jsxDEV4(Fragment2, {
2186
- children: d ?? /* @__PURE__ */ jsxDEV4(RunningTimer, {
2187
- startTime: entry.startTime
2188
- }, undefined, false, undefined, this)
2189
- }, undefined, false, undefined, this);
2190
- }
2191
-
2192
- // src/devtools/browser/components/SectionLabel.tsx
2193
- import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
2194
- function SectionLabel({ label, color = "#60a5fa" }) {
2195
- return /* @__PURE__ */ jsxDEV5("div", {
2196
- style: {
2197
- color,
2198
- fontSize: "10px",
2199
- marginBottom: "3px",
2200
- textTransform: "uppercase",
2201
- letterSpacing: "0.05em"
2202
- },
2203
- children: label
2204
- }, undefined, false, undefined, this);
2205
- }
2206
2289
 
2207
- // src/devtools/browser/components/CallStackSection.tsx
2208
- import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
2209
- function getCalledLabel(entry) {
2210
- const firstHop = entry.meta.routing[0];
2211
- if (firstHop == null)
2212
- return " call";
2213
- if (firstHop.handlerType === "local")
2214
- return "↳ local";
2215
- const label = getExternalLabel(firstHop);
2216
- return label != null ? `↳ ${label}` : "↳ call";
2217
- }
2218
- function getCalledColor(entry) {
2219
- const firstHop = entry.meta.routing[0];
2220
- if (firstHop == null)
2221
- return "#a78bfa";
2222
- if (firstHop.handlerType === "local")
2223
- return DEVTOOL_COLOR_HANDLER_LOCAL_TEXT;
2224
- return DEVTOOL_COLOR_HANDLER_EXTERNAL_TEXT;
2290
+ // src/devtools/browser/components/NiceErrorDisplay.tsx
2291
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
2292
+ var MONO2 = "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace";
2293
+ var SANS = "ui-sans-serif, system-ui, -apple-system, sans-serif";
2294
+ function isNiceErrorJson(value) {
2295
+ if (typeof value !== "object" || value == null)
2296
+ return false;
2297
+ const v = value;
2298
+ return v["name"] === "NiceError" && Array.isArray(v["ids"]) && typeof v["message"] === "string";
2225
2299
  }
2226
- function CallStackLink({
2227
- entry,
2228
- entryRole,
2229
- isFocused,
2230
- onClick
2231
- }) {
2232
- const color = STATUS_COLOR[entry.status];
2233
- const symbol = STATUS_SYMBOL[entry.status];
2234
- const labelColor = entryRole === "caller" ? "#94a3b8" : getCalledColor(entry);
2235
- const label = entryRole === "caller" ? "↑ from" : getCalledLabel(entry);
2236
- return /* @__PURE__ */ jsxDEV6("div", {
2237
- onClick,
2300
+ function NiceErrorBody({ error }) {
2301
+ return /* @__PURE__ */ jsxDEV3("div", {
2238
2302
  style: {
2239
- background: isFocused ? "#1e2e45" : "#1e293b",
2303
+ background: DEVTOOL_ERROR_BACKGROUND,
2304
+ border: `1px solid ${DEVTOOL_COLOR_SEMANTIC_ERROR}`,
2240
2305
  borderRadius: "4px",
2241
- borderLeft: isFocused ? "2px solid #a78bfa" : "2px solid transparent",
2242
- padding: isFocused ? "5px 8px 5px 6px" : "5px 8px",
2243
- display: "grid",
2244
- gridTemplateColumns: "30% 1fr 30%",
2245
- alignItems: "center",
2246
- columnGap: "8px",
2247
- cursor: "pointer"
2306
+ overflow: "hidden"
2248
2307
  },
2249
2308
  children: [
2250
- /* @__PURE__ */ jsxDEV6("span", {
2309
+ /* @__PURE__ */ jsxDEV3("div", {
2251
2310
  style: {
2252
- color: labelColor,
2253
- fontSize: "9px",
2254
- whiteSpace: "nowrap",
2255
- overflow: "hidden",
2256
- textOverflow: "ellipsis"
2311
+ padding: "12px 14px",
2312
+ color: DEVTOOL_COLOR_SEMANTIC_ERROR,
2313
+ fontSize: "14px",
2314
+ fontWeight: "700",
2315
+ lineHeight: "1.45",
2316
+ wordBreak: "break-word",
2317
+ fontFamily: SANS,
2318
+ borderBottom: `1px solid ${DEVTOOL_ERROR_BADGE_BACKGROUND}`
2257
2319
  },
2258
- children: label
2320
+ children: error.message
2259
2321
  }, undefined, false, undefined, this),
2260
- /* @__PURE__ */ jsxDEV6("span", {
2322
+ /* @__PURE__ */ jsxDEV3("div", {
2261
2323
  style: {
2324
+ padding: "6px 14px 8px",
2262
2325
  display: "flex",
2326
+ flexWrap: "wrap",
2327
+ gap: "10px",
2263
2328
  alignItems: "center",
2264
- justifyContent: "center",
2265
- gap: "5px",
2266
- overflow: "hidden"
2329
+ background: DEVTOOL_ERROR_BADGE_BACKGROUND
2267
2330
  },
2268
2331
  children: [
2269
- /* @__PURE__ */ jsxDEV6("span", {
2270
- style: { color, fontSize: "10px", flexShrink: 0 },
2271
- children: symbol
2272
- }, undefined, false, undefined, this),
2273
- /* @__PURE__ */ jsxDEV6("span", {
2332
+ error.ids.map((id) => /* @__PURE__ */ jsxDEV3("span", {
2274
2333
  style: {
2275
- color: "#cbd5e1",
2334
+ color: DEVTOOL_COLOR_SEMANTIC_ERROR,
2335
+ fontFamily: MONO2,
2276
2336
  fontSize: "11px",
2277
- overflow: "hidden",
2278
- textOverflow: "ellipsis",
2279
- whiteSpace: "nowrap"
2337
+ fontWeight: "600"
2280
2338
  },
2281
- children: entry.actionId
2282
- }, undefined, false, undefined, this),
2283
- /* @__PURE__ */ jsxDEV6(DomainChip, {
2284
- domain: entry.domain,
2285
- allDomains: entry.allDomains,
2286
- size: "sm"
2287
- }, undefined, false, undefined, this)
2339
+ children: id
2340
+ }, id, false, undefined, this)),
2341
+ /* @__PURE__ */ jsxDEV3("span", {
2342
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "10px", fontFamily: SANS },
2343
+ children: [
2344
+ "domain:",
2345
+ " ",
2346
+ /* @__PURE__ */ jsxDEV3("span", {
2347
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontFamily: MONO2 },
2348
+ children: error.def.domain
2349
+ }, undefined, false, undefined, this)
2350
+ ]
2351
+ }, undefined, true, undefined, this),
2352
+ /* @__PURE__ */ jsxDEV3("span", {
2353
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "10px", fontFamily: SANS },
2354
+ children: [
2355
+ "http:",
2356
+ " ",
2357
+ /* @__PURE__ */ jsxDEV3("span", {
2358
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontFamily: MONO2 },
2359
+ children: error.httpStatusCode
2360
+ }, undefined, false, undefined, this)
2361
+ ]
2362
+ }, undefined, true, undefined, this)
2288
2363
  ]
2289
- }, undefined, true, undefined, this),
2290
- /* @__PURE__ */ jsxDEV6("span", {
2291
- style: { color: "#475569", fontSize: "10px", textAlign: "right" },
2292
- children: /* @__PURE__ */ jsxDEV6(DurationDisplay, {
2293
- entry
2294
- }, undefined, false, undefined, this)
2295
- }, undefined, false, undefined, this)
2364
+ }, undefined, true, undefined, this)
2296
2365
  ]
2297
2366
  }, undefined, true, undefined, this);
2298
2367
  }
2299
- function CallStackSection({
2300
- parent,
2301
- childEntries,
2302
- focusedChildCuid,
2303
- onFocusChild,
2304
- onSelectParent
2368
+ function NiceErrorDisplay({
2369
+ error,
2370
+ label,
2371
+ color
2305
2372
  }) {
2306
- if (parent == null && childEntries.length === 0)
2307
- return null;
2308
- return /* @__PURE__ */ jsxDEV6("div", {
2373
+ return /* @__PURE__ */ jsxDEV3("div", {
2309
2374
  children: [
2310
- /* @__PURE__ */ jsxDEV6(SectionLabel, {
2311
- label: "Call Stack",
2312
- color: "#a78bfa"
2375
+ /* @__PURE__ */ jsxDEV3(SectionLabel, {
2376
+ label,
2377
+ color
2313
2378
  }, undefined, false, undefined, this),
2314
- /* @__PURE__ */ jsxDEV6("div", {
2315
- style: { display: "flex", flexDirection: "column", gap: "2px" },
2316
- children: [
2317
- parent != null && /* @__PURE__ */ jsxDEV6(CallStackLink, {
2318
- entry: parent,
2319
- entryRole: "caller",
2320
- isFocused: false,
2321
- onClick: () => onSelectParent(parent.cuid)
2322
- }, undefined, false, undefined, this),
2323
- childEntries.map((child) => /* @__PURE__ */ jsxDEV6(CallStackLink, {
2324
- entry: child,
2325
- entryRole: "called",
2326
- isFocused: focusedChildCuid === child.cuid,
2327
- onClick: () => onFocusChild(child.cuid)
2328
- }, child.cuid, false, undefined, this))
2329
- ]
2330
- }, undefined, true, undefined, this)
2379
+ /* @__PURE__ */ jsxDEV3(NiceErrorBody, {
2380
+ error
2381
+ }, undefined, false, undefined, this)
2331
2382
  ]
2332
2383
  }, undefined, true, undefined, this);
2333
2384
  }
2334
2385
 
2335
- // src/devtools/browser/components/ChildDispatchChips.tsx
2336
- import { jsxDEV as jsxDEV7, Fragment as Fragment3 } from "react/jsx-dev-runtime";
2337
- function ChildDispatchChips({
2338
- labels,
2339
- size = "sm"
2340
- }) {
2341
- if (labels == null || labels.length === 0)
2386
+ // src/devtools/browser/components/StackTraceSection.tsx
2387
+ import { useEffect, useState as useState2 } from "react";
2388
+
2389
+ // ../../node_modules/.bun/source-map-js@1.2.1/node_modules/source-map-js/source-map.js
2390
+ var $SourceMapGenerator = require_source_map_generator().SourceMapGenerator;
2391
+ var $SourceMapConsumer = require_source_map_consumer().SourceMapConsumer;
2392
+ var $SourceNode = require_source_node().SourceNode;
2393
+
2394
+ // src/devtools/browser/components/sourceMapResolver.ts
2395
+ var consumerCache = new Map;
2396
+ async function loadConsumer(fileUrl) {
2397
+ try {
2398
+ if (!fileUrl.startsWith("http://") && !fileUrl.startsWith("https://"))
2399
+ return null;
2400
+ const resp = await fetch(fileUrl);
2401
+ if (!resp.ok)
2402
+ return null;
2403
+ const text = await resp.text();
2404
+ const match = text.match(/\/\/[#@] sourceMappingURL=(\S+)/);
2405
+ if (match == null)
2406
+ return null;
2407
+ const mapRef = match[1];
2408
+ let mapJson;
2409
+ if (mapRef.startsWith("data:")) {
2410
+ const commaIdx = mapRef.indexOf(",");
2411
+ if (commaIdx === -1)
2412
+ return null;
2413
+ const header = mapRef.slice(5, commaIdx);
2414
+ const payload = mapRef.slice(commaIdx + 1);
2415
+ mapJson = header.includes("base64") ? atob(payload) : decodeURIComponent(payload);
2416
+ } else {
2417
+ const mapUrl = new URL(mapRef, fileUrl).href;
2418
+ const mapResp = await fetch(mapUrl);
2419
+ if (!mapResp.ok)
2420
+ return null;
2421
+ mapJson = await mapResp.text();
2422
+ }
2423
+ return new $SourceMapConsumer(JSON.parse(mapJson));
2424
+ } catch {
2342
2425
  return null;
2343
- const fontSize = size === "md" ? "1em" : "0.8em";
2344
- const padding = size === "md" ? "1px 4px" : "1px 3px";
2345
- return /* @__PURE__ */ jsxDEV7(Fragment3, {
2346
- children: labels.map((label) => /* @__PURE__ */ jsxDEV7(Chip, {
2347
- color: DEVTOOL_COLOR_HANDLER_EXTERNAL_TEXT,
2348
- borderColor: DEVTOOL_COLOR_HANDLER_EXTERNAL_BORDER,
2349
- fontSize,
2350
- padding,
2351
- children: [
2352
- "↳ ",
2353
- label
2354
- ]
2355
- }, label, true, undefined, this))
2356
- }, undefined, false, undefined, this);
2426
+ }
2427
+ }
2428
+ function getConsumer(fileUrl) {
2429
+ const key = fileUrl.split("?")[0] ?? fileUrl;
2430
+ if (!consumerCache.has(key)) {
2431
+ consumerCache.set(key, loadConsumer(fileUrl));
2432
+ }
2433
+ return consumerCache.get(key);
2434
+ }
2435
+ async function resolveCompiledPosition(fileUrl, line, col) {
2436
+ try {
2437
+ const consumer = await getConsumer(fileUrl);
2438
+ if (consumer == null)
2439
+ return null;
2440
+ const pos = consumer.originalPositionFor({ line, column: col });
2441
+ if (pos.source == null || pos.line == null)
2442
+ return null;
2443
+ return { file: pos.source, line: pos.line, col: pos.column ?? 0 };
2444
+ } catch {
2445
+ return null;
2446
+ }
2357
2447
  }
2358
2448
 
2359
- // src/devtools/browser/components/DetailSection.tsx
2360
- import { useState as useState2 } from "react";
2361
- import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
2362
- var COMPACT_CHAR_LIMIT = 120;
2363
- function DetailSection({
2449
+ // src/devtools/browser/components/StackTraceSection.tsx
2450
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
2451
+ var INTERNAL_PATTERNS = [
2452
+ "/nice-action/",
2453
+ "@nice-code/action",
2454
+ "/nice-error/",
2455
+ "@nice-code/error",
2456
+ "node_modules/",
2457
+ "native code",
2458
+ "<anonymous>"
2459
+ ];
2460
+ function isInternalFrame(file) {
2461
+ return INTERNAL_PATTERNS.some((p) => file.includes(p));
2462
+ }
2463
+ function parseStackFrames(stack) {
2464
+ return stack.split(`
2465
+ `).slice(1).map((line) => {
2466
+ const raw = line.trim();
2467
+ if (raw === "")
2468
+ return null;
2469
+ const matchFn = raw.match(/^at (.+?) \((.+):(\d+):(\d+)\)$/);
2470
+ if (matchFn != null) {
2471
+ const file = matchFn[2];
2472
+ return {
2473
+ fn: matchFn[1],
2474
+ file,
2475
+ line: parseInt(matchFn[3], 10),
2476
+ col: parseInt(matchFn[4], 10),
2477
+ raw,
2478
+ isInternal: isInternalFrame(file)
2479
+ };
2480
+ }
2481
+ const matchUrl = raw.match(/^at (.+):(\d+):(\d+)$/);
2482
+ if (matchUrl != null) {
2483
+ const file = matchUrl[1];
2484
+ return {
2485
+ file,
2486
+ line: parseInt(matchUrl[2], 10),
2487
+ col: parseInt(matchUrl[3], 10),
2488
+ raw,
2489
+ isInternal: isInternalFrame(file)
2490
+ };
2491
+ }
2492
+ return { raw, isInternal: true };
2493
+ }).filter((f) => f != null);
2494
+ }
2495
+ async function resolveSourceMapPositions(frames) {
2496
+ return Promise.all(frames.map(async (frame) => {
2497
+ if (frame.isInternal || frame.file == null || frame.line == null)
2498
+ return frame;
2499
+ const resolved = await resolveCompiledPosition(frame.file, frame.line, frame.col ?? 0);
2500
+ if (resolved == null)
2501
+ return frame;
2502
+ return { ...frame, file: resolved.file, line: resolved.line, col: resolved.col };
2503
+ }));
2504
+ }
2505
+ function formatFrameFile(file) {
2506
+ if (file == null)
2507
+ return "?";
2508
+ let path = file;
2509
+ try {
2510
+ const url = new URL(file);
2511
+ path = url.pathname.split("?")[0] ?? url.pathname;
2512
+ if (path.startsWith("/@fs/"))
2513
+ path = path.slice(4);
2514
+ } catch {}
2515
+ const parts = path.replace(/\\/g, "/").split("/").filter(Boolean);
2516
+ const filtered = parts[0]?.match(/^[a-zA-Z]:$/) != null ? parts.slice(1) : parts;
2517
+ const tail = filtered.slice(-4);
2518
+ return tail.join("/") || file;
2519
+ }
2520
+ function countUserFrames(stack) {
2521
+ if (stack == null)
2522
+ return 0;
2523
+ return parseStackFrames(stack).filter((f) => !f.isInternal).length;
2524
+ }
2525
+ function StackTraceSection({
2364
2526
  label,
2365
- value,
2366
- color = "#60a5fa"
2527
+ stack,
2528
+ color = DEVTOOL_COLOR_SEMANTIC_SYSTEM,
2529
+ minFrameCount
2367
2530
  }) {
2368
- const [expanded, setExpanded] = useState2(false);
2369
- const fullJson = safeStringify(value, 2);
2370
- const compactJson = safeStringify(value, 0);
2371
- const canExpand = fullJson !== compactJson || compactJson.length > COMPACT_CHAR_LIMIT;
2372
- const compactDisplay = compactJson.length > COMPACT_CHAR_LIMIT ? `${compactJson.slice(0, COMPACT_CHAR_LIMIT)}…` : compactJson;
2373
- return /* @__PURE__ */ jsxDEV8("div", {
2531
+ const [showAll, setShowAll] = useState2(false);
2532
+ const [resolvedFrames, setResolvedFrames] = useState2(null);
2533
+ useEffect(() => {
2534
+ if (stack == null)
2535
+ return;
2536
+ setResolvedFrames(null);
2537
+ const parsed = parseStackFrames(stack);
2538
+ let cancelled = false;
2539
+ resolveSourceMapPositions(parsed).then((frames) => {
2540
+ if (!cancelled)
2541
+ setResolvedFrames(frames);
2542
+ });
2543
+ return () => {
2544
+ cancelled = true;
2545
+ };
2546
+ }, [stack]);
2547
+ if (stack == null)
2548
+ return null;
2549
+ const allFrames = resolvedFrames ?? parseStackFrames(stack);
2550
+ const userFrames = allFrames.filter((f) => !f.isInternal);
2551
+ const hasInternalFrames = allFrames.length > userFrames.length;
2552
+ const displayFrames = showAll ? allFrames : userFrames;
2553
+ const phantomFrameCount = !showAll ? Math.max(0, (minFrameCount ?? 0) - displayFrames.length) : 0;
2554
+ if (allFrames.length === 0)
2555
+ return null;
2556
+ return /* @__PURE__ */ jsxDEV4("div", {
2374
2557
  children: [
2375
- /* @__PURE__ */ jsxDEV8("div", {
2558
+ /* @__PURE__ */ jsxDEV4("div", {
2376
2559
  style: {
2377
2560
  display: "flex",
2378
2561
  alignItems: "center",
@@ -2380,705 +2563,1053 @@ function DetailSection({
2380
2563
  marginBottom: "3px"
2381
2564
  },
2382
2565
  children: [
2383
- /* @__PURE__ */ jsxDEV8("div", {
2384
- style: {
2385
- color,
2386
- fontSize: "10px",
2387
- textTransform: "uppercase",
2388
- letterSpacing: "0.05em"
2389
- },
2390
- children: label
2566
+ /* @__PURE__ */ jsxDEV4(SectionLabel, {
2567
+ label,
2568
+ color
2391
2569
  }, undefined, false, undefined, this),
2392
- canExpand && /* @__PURE__ */ jsxDEV8("span", {
2393
- style: { color: "#334155", fontSize: "11px" },
2394
- children: expanded ? "" : "▸"
2570
+ hasInternalFrames && /* @__PURE__ */ jsxDEV4("span", {
2571
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "9px" },
2572
+ children: !showAll ? "user only" : `all (${allFrames.length})`
2395
2573
  }, undefined, false, undefined, this)
2396
2574
  ]
2397
2575
  }, undefined, true, undefined, this),
2398
- expanded ? /* @__PURE__ */ jsxDEV8("div", {
2399
- onClick: canExpand ? () => setExpanded(false) : undefined,
2400
- style: {
2401
- margin: 0,
2402
- padding: "6px 8px",
2403
- background: "#1e293b",
2404
- borderRadius: "4px",
2405
- fontSize: "11px",
2406
- color: "#cbd5e1",
2407
- overflowX: "auto",
2408
- textAlign: "left",
2409
- whiteSpace: "pre-wrap",
2410
- wordBreak: "break-all",
2411
- cursor: canExpand ? "pointer" : "default"
2412
- },
2413
- children: fullJson
2414
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV8("div", {
2415
- onClick: canExpand ? () => setExpanded(true) : undefined,
2576
+ /* @__PURE__ */ jsxDEV4("div", {
2577
+ onClick: () => setShowAll((s) => !s),
2416
2578
  style: {
2417
- padding: "5px 8px",
2418
- background: "#1e293b",
2579
+ background: DEVTOOL_STACK_TRACE_BACKGROUND,
2419
2580
  borderRadius: "4px",
2420
- fontSize: "11px",
2421
- color: "#94a3b8",
2422
- fontFamily: "inherit",
2423
- whiteSpace: "nowrap",
2581
+ padding: "2px",
2424
2582
  overflow: "hidden",
2425
- textOverflow: "ellipsis",
2426
- cursor: canExpand ? "pointer" : "default"
2427
- },
2428
- children: compactDisplay
2429
- }, undefined, false, undefined, this)
2430
- ]
2431
- }, undefined, true, undefined, this);
2432
- }
2433
-
2434
- // src/devtools/browser/components/MetaSection.tsx
2435
- import { useState as useState3 } from "react";
2436
- import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
2437
- function MetaChip({ label, value }) {
2438
- return /* @__PURE__ */ jsxDEV9("span", {
2439
- style: { whiteSpace: "nowrap" },
2440
- children: [
2441
- /* @__PURE__ */ jsxDEV9("span", {
2442
- style: { color: "#475569" },
2443
- children: [
2444
- label,
2445
- " "
2446
- ]
2447
- }, undefined, true, undefined, this),
2448
- /* @__PURE__ */ jsxDEV9("span", {
2449
- style: { color: "#cbd5e1" },
2450
- children: value
2451
- }, undefined, false, undefined, this)
2452
- ]
2453
- }, undefined, true, undefined, this);
2454
- }
2455
- function MetaSection({ entry }) {
2456
- const [expanded, setExpanded] = useState3(false);
2457
- const { meta, cuid } = entry;
2458
- const expandedRows = [
2459
- { label: "cuid", value: cuid },
2460
- { label: "origin", value: meta.originClient.envId },
2461
- ...meta.originClient.perId != null ? [{ label: "perId", value: meta.originClient.perId }] : [],
2462
- ...meta.originClient.insId != null ? [{ label: "insId", value: meta.originClient.insId }] : []
2463
- ];
2464
- return /* @__PURE__ */ jsxDEV9("div", {
2465
- children: [
2466
- /* @__PURE__ */ jsxDEV9("div", {
2467
- style: {
2468
- display: "flex",
2469
- alignItems: "center",
2470
- justifyContent: "space-between",
2471
- marginBottom: "3px"
2583
+ cursor: "pointer"
2472
2584
  },
2473
2585
  children: [
2474
- /* @__PURE__ */ jsxDEV9("div", {
2475
- style: {
2476
- color: "#60a5fa",
2477
- fontSize: "10px",
2478
- textTransform: "uppercase",
2479
- letterSpacing: "0.05em"
2480
- },
2481
- children: "Meta"
2482
- }, undefined, false, undefined, this),
2483
- /* @__PURE__ */ jsxDEV9("span", {
2484
- style: { color: "#334155", fontSize: "11px" },
2485
- children: expanded ? "▾" : "▸"
2486
- }, undefined, false, undefined, this)
2487
- ]
2488
- }, undefined, true, undefined, this),
2489
- expanded ? /* @__PURE__ */ jsxDEV9("div", {
2490
- onClick: () => setExpanded(false),
2491
- style: { background: "#1e293b", borderRadius: "4px", overflow: "hidden", cursor: "pointer" },
2492
- children: expandedRows.map(({ label, value }, i) => /* @__PURE__ */ jsxDEV9("div", {
2493
- style: {
2494
- display: "grid",
2495
- gridTemplateColumns: "52px 1fr",
2496
- columnGap: "8px",
2497
- padding: "4px 8px",
2498
- borderBottom: i < expandedRows.length - 1 ? "1px solid #0f172a" : "none",
2499
- alignItems: "start"
2500
- },
2501
- children: [
2502
- /* @__PURE__ */ jsxDEV9("span", {
2503
- style: { textAlign: "left", color: "#475569", fontSize: "10px", paddingTop: "1px" },
2504
- children: label
2505
- }, undefined, false, undefined, this),
2506
- /* @__PURE__ */ jsxDEV9("span", {
2507
- style: { textAlign: "left", color: "#cbd5e1", fontSize: "11px", wordBreak: "break-all" },
2508
- children: value
2509
- }, undefined, false, undefined, this)
2510
- ]
2511
- }, label, true, undefined, this))
2512
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV9("div", {
2513
- onClick: () => setExpanded(true),
2514
- style: {
2515
- background: "#1e293b",
2516
- borderRadius: "4px",
2517
- padding: "5px 8px",
2518
- fontSize: "11px",
2519
- display: "flex",
2520
- gap: "10px",
2521
- rowGap: "2px",
2522
- flexWrap: "wrap",
2523
- cursor: "pointer"
2524
- },
2525
- children: [
2526
- /* @__PURE__ */ jsxDEV9(MetaChip, {
2527
- label: "cuid",
2528
- value: `…${cuid.slice(-8)}`
2529
- }, undefined, false, undefined, this),
2530
- /* @__PURE__ */ jsxDEV9(MetaChip, {
2531
- label: "origin",
2532
- value: meta.originClient.envId
2533
- }, undefined, false, undefined, this),
2534
- meta.originClient.perId != null && /* @__PURE__ */ jsxDEV9(MetaChip, {
2535
- label: "perId",
2536
- value: meta.originClient.perId.length > 10 ? `${meta.originClient.perId.slice(0, 10)}…` : meta.originClient.perId
2537
- }, undefined, false, undefined, this),
2538
- meta.originClient.insId != null && /* @__PURE__ */ jsxDEV9(MetaChip, {
2539
- label: "insId",
2540
- value: meta.originClient.insId.length > 10 ? `${meta.originClient.insId.slice(0, 10)}…` : meta.originClient.insId
2541
- }, undefined, false, undefined, this)
2542
- ]
2543
- }, undefined, true, undefined, this)
2544
- ]
2545
- }, undefined, true, undefined, this);
2546
- }
2547
-
2548
- // src/devtools/browser/components/RoutingSection.tsx
2549
- import { jsxDEV as jsxDEV10 } from "react/jsx-dev-runtime";
2550
- function RoutingSection({
2551
- entry,
2552
- minHopCount = 0
2553
- }) {
2554
- const { meta, startTime } = entry;
2555
- const hopCount = meta.routing.length;
2556
- const phantomCount = Math.max(0, minHopCount - hopCount);
2557
- if (hopCount === 0 && phantomCount === 0)
2558
- return null;
2559
- return /* @__PURE__ */ jsxDEV10("div", {
2560
- children: [
2561
- /* @__PURE__ */ jsxDEV10(SectionLabel, {
2562
- label: hopCount > 0 ? `Routing · ${hopCount} hop${hopCount !== 1 ? "s" : ""}` : "Routing"
2563
- }, undefined, false, undefined, this),
2564
- /* @__PURE__ */ jsxDEV10("div", {
2565
- style: { display: "flex", flexDirection: "column", gap: "2px" },
2566
- children: [
2567
- meta.routing.map((hop, i) => {
2568
- const isLocal = hop.handlerType === "local";
2569
- const isLast = i === hopCount - 1 && phantomCount === 0;
2570
- const badgeColor = isLocal ? "#34d399" : "#fbbf24";
2571
- const badgeText = isLocal ? "● exec" : `→ ${hop.transport ?? "ext"}`;
2572
- const runtimeTitle = [hop.runtime.perId, hop.runtime.insId].filter(Boolean).join(" · ") || undefined;
2573
- return /* @__PURE__ */ jsxDEV10("div", {
2586
+ displayFrames.length === 0 ? /* @__PURE__ */ jsxDEV4("div", {
2587
+ style: { padding: "6px 10px", color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "10px", fontStyle: "italic" },
2588
+ children: "no user frames captured"
2589
+ }, undefined, false, undefined, this) : displayFrames.map((frame, idx) => {
2590
+ const displayFile = formatFrameFile(frame.file);
2591
+ const slashIdx = displayFile.lastIndexOf("/");
2592
+ const folderPrefix = slashIdx >= 0 ? displayFile.slice(0, slashIdx + 1) : "";
2593
+ const bareFilename = slashIdx >= 0 ? displayFile.slice(slashIdx + 1) : displayFile;
2594
+ const titleStr = frame.file != null ? frame.file : frame.raw;
2595
+ const isUser = !frame.isInternal;
2596
+ return /* @__PURE__ */ jsxDEV4("div", {
2597
+ title: titleStr,
2574
2598
  style: {
2575
- background: "#1e293b",
2576
- borderRadius: "4px",
2577
- overflow: "hidden",
2578
- display: "grid",
2579
- gridTemplateColumns: "30% 1fr 30%",
2580
- alignItems: "center",
2581
- columnGap: "8px",
2582
- borderBottom: isLast ? undefined : "1px solid #0f172a",
2583
- padding: "4px 8px"
2599
+ display: "flex",
2600
+ flexDirection: "row",
2601
+ gap: "0.5em",
2602
+ padding: "4px",
2603
+ borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`
2584
2604
  },
2585
2605
  children: [
2586
- /* @__PURE__ */ jsxDEV10("span", {
2587
- style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "10px" },
2588
- children: [
2589
- /* @__PURE__ */ jsxDEV10("span", {
2590
- style: { color: "#334155", fontSize: "10px", width: "16px", textAlign: "right" },
2591
- children: i + 1
2592
- }, undefined, false, undefined, this),
2593
- /* @__PURE__ */ jsxDEV10("span", {
2594
- title: runtimeTitle,
2595
- style: {
2596
- color: "#94a3b8",
2597
- fontSize: "11px",
2598
- overflow: "hidden",
2599
- textOverflow: "ellipsis",
2600
- whiteSpace: "nowrap",
2601
- textAlign: "center"
2602
- },
2603
- children: hop.runtime.envId
2604
- }, undefined, false, undefined, this)
2605
- ]
2606
- }, undefined, true, undefined, this),
2607
- /* @__PURE__ */ jsxDEV10("span", {
2608
- style: { color: badgeColor, fontSize: "10px", whiteSpace: "nowrap" },
2609
- children: badgeText
2606
+ /* @__PURE__ */ jsxDEV4("span", {
2607
+ style: {
2608
+ color: isUser ? DEVTOOL_STACK_FRAME_USER_NUMBER : DEVTOOL_STACK_FRAME_INTERNAL_NUMBER,
2609
+ fontSize: "10px",
2610
+ minWidth: "10px",
2611
+ textAlign: "left",
2612
+ flexShrink: 0,
2613
+ fontVariantNumeric: "tabular-nums"
2614
+ },
2615
+ children: idx + 1
2610
2616
  }, undefined, false, undefined, this),
2611
- /* @__PURE__ */ jsxDEV10("span", {
2617
+ /* @__PURE__ */ jsxDEV4("div", {
2612
2618
  style: {
2613
2619
  display: "flex",
2614
- alignItems: "center",
2615
- justifyContent: "space-between",
2616
- paddingRight: "8px",
2617
- overflow: "hidden"
2620
+ flexDirection: "column",
2621
+ gap: "0.15em",
2622
+ lineHeight: 1.2
2618
2623
  },
2619
2624
  children: [
2620
- /* @__PURE__ */ jsxDEV10("span", {
2621
- style: {
2622
- color: "#475569",
2623
- fontSize: "10px",
2624
- whiteSpace: "nowrap",
2625
- overflow: "hidden",
2626
- textOverflow: "ellipsis"
2627
- },
2628
- children: hop.handlerClient != null ? `↳ ${hop.handlerClient.envId}` : ""
2625
+ /* @__PURE__ */ jsxDEV4("div", {
2626
+ style: { display: "flex", alignItems: "center" },
2627
+ children: /* @__PURE__ */ jsxDEV4("span", {
2628
+ style: {
2629
+ color: isUser ? DEVTOOL_STACK_FRAME_USER_FUNCTION : DEVTOOL_STACK_FRAME_INTERNAL_FUNCTION,
2630
+ fontSize: "12px",
2631
+ fontWeight: 500,
2632
+ overflow: "hidden",
2633
+ textOverflow: "ellipsis",
2634
+ whiteSpace: "nowrap"
2635
+ },
2636
+ children: frame.fn ?? "(anonymous)"
2637
+ }, undefined, false, undefined, this)
2629
2638
  }, undefined, false, undefined, this),
2630
- /* @__PURE__ */ jsxDEV10("span", {
2631
- style: { color: "#334155", fontSize: "10px", flexShrink: 0, marginLeft: "auto" },
2639
+ /* @__PURE__ */ jsxDEV4("div", {
2640
+ style: { display: "flex", alignItems: "baseline", overflow: "hidden" },
2632
2641
  children: [
2633
- "+",
2634
- hop.time - startTime,
2635
- "ms"
2642
+ folderPrefix !== "" && /* @__PURE__ */ jsxDEV4("span", {
2643
+ style: {
2644
+ color: isUser ? DEVTOOL_STACK_FRAME_USER_FOLDER : DEVTOOL_STACK_FRAME_INTERNAL_FOLDER,
2645
+ fontSize: "10px",
2646
+ overflow: "hidden",
2647
+ textOverflow: "ellipsis",
2648
+ whiteSpace: "nowrap",
2649
+ flexShrink: 1,
2650
+ minWidth: 0
2651
+ },
2652
+ children: folderPrefix
2653
+ }, undefined, false, undefined, this),
2654
+ /* @__PURE__ */ jsxDEV4("span", {
2655
+ style: {
2656
+ color: isUser ? DEVTOOL_STACK_FRAME_USER_FILE : DEVTOOL_STACK_FRAME_INTERNAL_FILE,
2657
+ fontSize: "10px",
2658
+ whiteSpace: "nowrap",
2659
+ flexShrink: 0
2660
+ },
2661
+ children: bareFilename
2662
+ }, undefined, false, undefined, this),
2663
+ frame.line != null && /* @__PURE__ */ jsxDEV4("span", {
2664
+ style: {
2665
+ color: isUser ? DEVTOOL_STACK_FRAME_USER_LINE : DEVTOOL_STACK_FRAME_INTERNAL_LINE,
2666
+ fontSize: "10px",
2667
+ whiteSpace: "nowrap",
2668
+ flexShrink: 0,
2669
+ fontVariantNumeric: "tabular-nums"
2670
+ },
2671
+ children: [
2672
+ ":",
2673
+ frame.line
2674
+ ]
2675
+ }, undefined, true, undefined, this)
2636
2676
  ]
2637
2677
  }, undefined, true, undefined, this)
2638
2678
  ]
2639
2679
  }, undefined, true, undefined, this)
2640
2680
  ]
2641
- }, `${hop.time}-${hop.runtime.envId}`, true, undefined, this);
2681
+ }, frame.raw, true, undefined, this);
2642
2682
  }),
2643
- Array.from({ length: phantomCount }, (_, i) => `routing-phantom-${hopCount + i}`).map((key) => /* @__PURE__ */ jsxDEV10("div", {
2683
+ Array.from({ length: phantomFrameCount }, (_, i) => i).map((i) => /* @__PURE__ */ jsxDEV4("div", {
2644
2684
  "aria-hidden": "true",
2645
2685
  style: {
2646
2686
  visibility: "hidden",
2647
- background: "#1e293b",
2648
- borderRadius: "4px",
2649
- display: "grid",
2650
- gridTemplateColumns: "30% 1fr 30%",
2651
- alignItems: "center",
2652
- columnGap: "8px",
2653
- padding: "4px 8px"
2687
+ display: "flex",
2688
+ flexDirection: "row",
2689
+ gap: "0.5em",
2690
+ padding: "4px",
2691
+ borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`
2654
2692
  },
2655
2693
  children: [
2656
- /* @__PURE__ */ jsxDEV10("span", {
2657
- style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "10px" },
2694
+ /* @__PURE__ */ jsxDEV4("span", {
2695
+ style: { fontSize: "10px", minWidth: "10px", flexShrink: 0 },
2696
+ children: "0"
2697
+ }, undefined, false, undefined, this),
2698
+ /* @__PURE__ */ jsxDEV4("div", {
2699
+ style: { display: "flex", flexDirection: "column", gap: "0.15em", lineHeight: 1.2 },
2658
2700
  children: [
2659
- /* @__PURE__ */ jsxDEV10("span", {
2660
- style: { fontSize: "10px", width: "16px" },
2661
- children: "0"
2662
- }, undefined, false, undefined, this),
2663
- /* @__PURE__ */ jsxDEV10("span", {
2664
- style: { fontSize: "11px" },
2701
+ /* @__PURE__ */ jsxDEV4("div", {
2702
+ style: { fontSize: "12px" },
2665
2703
  children: "placeholder"
2704
+ }, undefined, false, undefined, this),
2705
+ /* @__PURE__ */ jsxDEV4("div", {
2706
+ style: { fontSize: "10px" },
2707
+ children: "placeholder/file.ts:1"
2666
2708
  }, undefined, false, undefined, this)
2667
2709
  ]
2668
- }, undefined, true, undefined, this),
2669
- /* @__PURE__ */ jsxDEV10("span", {
2670
- style: { fontSize: "10px" },
2671
- children: "placeholder"
2672
- }, undefined, false, undefined, this),
2673
- /* @__PURE__ */ jsxDEV10("span", {}, undefined, false, undefined, this)
2710
+ }, undefined, true, undefined, this)
2674
2711
  ]
2675
- }, key, true, undefined, this))
2712
+ }, `phantom-${i}`, true, undefined, this))
2676
2713
  ]
2677
2714
  }, undefined, true, undefined, this)
2678
2715
  ]
2679
2716
  }, undefined, true, undefined, this);
2680
2717
  }
2681
2718
 
2682
- // src/devtools/browser/components/StackTraceSection.tsx
2683
- import { useEffect as useEffect2, useState as useState4 } from "react";
2719
+ // src/devtools/browser/components/ActionErrorDisplay.tsx
2720
+ import { jsxDEV as jsxDEV5, Fragment } from "react/jsx-dev-runtime";
2721
+ function FullErrorContent({
2722
+ label,
2723
+ error,
2724
+ errorStack,
2725
+ color
2726
+ }) {
2727
+ return /* @__PURE__ */ jsxDEV5(Fragment, {
2728
+ children: [
2729
+ isNiceErrorJson(error) ? /* @__PURE__ */ jsxDEV5(NiceErrorDisplay, {
2730
+ error,
2731
+ label,
2732
+ color
2733
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5(DetailSection, {
2734
+ label,
2735
+ value: error,
2736
+ color
2737
+ }, undefined, false, undefined, this),
2738
+ /* @__PURE__ */ jsxDEV5(StackTraceSection, {
2739
+ label: "Error Stack",
2740
+ stack: errorStack,
2741
+ color
2742
+ }, undefined, false, undefined, this)
2743
+ ]
2744
+ }, undefined, true, undefined, this);
2745
+ }
2746
+ function ActionErrorDisplay({ entry }) {
2747
+ const { status, error, abortReason, errorStack } = entry;
2748
+ if (status === "action-error") {
2749
+ const color = DEVTOOL_COLOR_SEMANTIC_WARNING;
2750
+ return /* @__PURE__ */ jsxDEV5(FullErrorContent, {
2751
+ label: "Action Error",
2752
+ error,
2753
+ errorStack,
2754
+ color
2755
+ }, undefined, false, undefined, this);
2756
+ }
2757
+ if (status === "failed") {
2758
+ const color = DEVTOOL_COLOR_SEMANTIC_ERROR;
2759
+ return /* @__PURE__ */ jsxDEV5(FullErrorContent, {
2760
+ label: "Error",
2761
+ error,
2762
+ errorStack,
2763
+ color
2764
+ }, undefined, false, undefined, this);
2765
+ }
2766
+ if (status === "aborted") {
2767
+ const color = DEVTOOL_COLOR_SEMANTIC_METADATA;
2768
+ return /* @__PURE__ */ jsxDEV5(Fragment, {
2769
+ children: [
2770
+ abortReason != null && (isNiceErrorJson(abortReason) ? /* @__PURE__ */ jsxDEV5(NiceErrorDisplay, {
2771
+ error: abortReason,
2772
+ label: "Abort Reason",
2773
+ color
2774
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV5(DetailSection, {
2775
+ label: "Abort Reason",
2776
+ value: abortReason,
2777
+ color
2778
+ }, undefined, false, undefined, this)),
2779
+ /* @__PURE__ */ jsxDEV5(StackTraceSection, {
2780
+ label: "Abort Stack",
2781
+ stack: errorStack,
2782
+ color
2783
+ }, undefined, false, undefined, this)
2784
+ ]
2785
+ }, undefined, true, undefined, this);
2786
+ }
2787
+ return null;
2788
+ }
2684
2789
 
2685
- // ../../node_modules/.bun/source-map-js@1.2.1/node_modules/source-map-js/source-map.js
2686
- var $SourceMapGenerator = require_source_map_generator().SourceMapGenerator;
2687
- var $SourceMapConsumer = require_source_map_consumer().SourceMapConsumer;
2688
- var $SourceNode = require_source_node().SourceNode;
2790
+ // src/devtools/browser/components/Chip.tsx
2791
+ import { useState as useState3 } from "react";
2689
2792
 
2690
- // src/devtools/browser/components/sourceMapResolver.ts
2691
- var consumerCache = new Map;
2692
- async function loadConsumer(fileUrl) {
2693
- try {
2694
- if (!fileUrl.startsWith("http://") && !fileUrl.startsWith("https://"))
2695
- return null;
2696
- const resp = await fetch(fileUrl);
2697
- if (!resp.ok)
2698
- return null;
2699
- const text = await resp.text();
2700
- const match = text.match(/\/\/[#@] sourceMappingURL=(\S+)/);
2701
- if (match == null)
2702
- return null;
2703
- const mapRef = match[1];
2704
- let mapJson;
2705
- if (mapRef.startsWith("data:")) {
2706
- const commaIdx = mapRef.indexOf(",");
2707
- if (commaIdx === -1)
2708
- return null;
2709
- const header = mapRef.slice(5, commaIdx);
2710
- const payload = mapRef.slice(commaIdx + 1);
2711
- mapJson = header.includes("base64") ? atob(payload) : decodeURIComponent(payload);
2793
+ // src/devtools/browser/components/Tooltip.tsx
2794
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
2795
+ function Tooltip({
2796
+ anchor,
2797
+ config,
2798
+ children
2799
+ }) {
2800
+ const resolvedTitle = config?.title;
2801
+ const resolvedAlign = config?.align;
2802
+ const resolvedMaxWidth = config?.maxWidth ?? 400;
2803
+ const resolvedContent = config != null ? config.content : children;
2804
+ const showAbove = anchor.top >= window.innerHeight - anchor.bottom;
2805
+ const gap = 6;
2806
+ const screenMargin = 16;
2807
+ const top = showAbove ? Math.round(anchor.top - gap) : Math.round(anchor.bottom + gap);
2808
+ const maxHeight = showAbove ? Math.round(anchor.top - gap - screenMargin) : Math.round(window.innerHeight - anchor.bottom - gap - screenMargin);
2809
+ let left;
2810
+ let right;
2811
+ let transform;
2812
+ if (resolvedAlign === "center") {
2813
+ const halfMax = resolvedMaxWidth != null ? resolvedMaxWidth / 2 : 120;
2814
+ const center = Math.round(anchor.left + anchor.width / 2);
2815
+ left = Math.max(halfMax + screenMargin, Math.min(center, window.innerWidth - halfMax - screenMargin));
2816
+ transform = showAbove ? "translateX(-50%) translateY(-100%)" : "translateX(-50%)";
2817
+ } else {
2818
+ const anchorMidX = anchor.left + anchor.width / 2;
2819
+ if (anchorMidX <= window.innerWidth / 2) {
2820
+ left = Math.max(screenMargin, anchor.left);
2712
2821
  } else {
2713
- const mapUrl = new URL(mapRef, fileUrl).href;
2714
- const mapResp = await fetch(mapUrl);
2715
- if (!mapResp.ok)
2716
- return null;
2717
- mapJson = await mapResp.text();
2822
+ right = Math.max(screenMargin, window.innerWidth - anchor.right);
2718
2823
  }
2719
- return new $SourceMapConsumer(JSON.parse(mapJson));
2720
- } catch {
2721
- return null;
2722
- }
2723
- }
2724
- function getConsumer(fileUrl) {
2725
- const key = fileUrl.split("?")[0] ?? fileUrl;
2726
- if (!consumerCache.has(key)) {
2727
- consumerCache.set(key, loadConsumer(fileUrl));
2824
+ if (showAbove)
2825
+ transform = "translateY(-100%)";
2728
2826
  }
2729
- return consumerCache.get(key);
2827
+ return /* @__PURE__ */ jsxDEV6("div", {
2828
+ style: {
2829
+ position: "fixed",
2830
+ left,
2831
+ right,
2832
+ top,
2833
+ transform,
2834
+ zIndex: 2147483647,
2835
+ background: DEVTOOL_TOOLTIP_BACKGROUND,
2836
+ border: `1px solid ${DEVTOOL_TOOLTIP_BORDER}`,
2837
+ borderRadius: "5px",
2838
+ boxShadow: "0 4px 20px rgba(0,0,0,0.6)",
2839
+ pointerEvents: "none",
2840
+ maxWidth: resolvedMaxWidth != null ? `${resolvedMaxWidth}px` : undefined,
2841
+ maxHeight: `${maxHeight}px`,
2842
+ overflowY: "auto"
2843
+ },
2844
+ children: [
2845
+ resolvedTitle != null && /* @__PURE__ */ jsxDEV6("div", {
2846
+ style: {
2847
+ background: DEVTOOL_TOOLTIP_TITLE_BACKGROUND,
2848
+ padding: "6px 8px",
2849
+ alignSelf: "start",
2850
+ textAlign: "left",
2851
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
2852
+ fontSize: "0.75rem",
2853
+ fontWeight: 600,
2854
+ paddingBottom: "4px",
2855
+ marginBottom: "4px",
2856
+ borderBottom: `1px solid ${DEVTOOL_TOOLTIP_TITLE_BOTTOM_BORDER}`
2857
+ },
2858
+ children: resolvedTitle
2859
+ }, undefined, false, undefined, this),
2860
+ /* @__PURE__ */ jsxDEV6("div", {
2861
+ style: {
2862
+ padding: "6px 8px"
2863
+ },
2864
+ children: resolvedContent
2865
+ }, undefined, false, undefined, this)
2866
+ ]
2867
+ }, undefined, true, undefined, this);
2730
2868
  }
2731
- async function resolveCompiledPosition(fileUrl, line, col) {
2732
- try {
2733
- const consumer = await getConsumer(fileUrl);
2734
- if (consumer == null)
2735
- return null;
2736
- const pos = consumer.originalPositionFor({ line, column: col });
2737
- if (pos.source == null || pos.line == null)
2738
- return null;
2739
- return { file: pos.source, line: pos.line, col: pos.column ?? 0 };
2740
- } catch {
2741
- return null;
2742
- }
2869
+
2870
+ // src/devtools/browser/components/Chip.tsx
2871
+ import { jsxDEV as jsxDEV7, Fragment as Fragment2 } from "react/jsx-dev-runtime";
2872
+ var CHIP_SIZE_STYLES = {
2873
+ ["sm" /* sm */]: { fontSize: "0.8em", padding: "1px 3px" },
2874
+ ["md" /* md */]: { fontSize: "0.9em", padding: "1px 4px" },
2875
+ ["lg" /* lg */]: { fontSize: "1em", padding: "2px 6px" }
2876
+ };
2877
+ function Chip({
2878
+ color,
2879
+ subtle = false,
2880
+ size = "md" /* md */,
2881
+ rounded = false,
2882
+ tooltip,
2883
+ children,
2884
+ style
2885
+ }) {
2886
+ const [anchor, setAnchor] = useState3(null);
2887
+ const hasTooltip = tooltip != null;
2888
+ const { fontSize, padding } = CHIP_SIZE_STYLES[size];
2889
+ const colorEntry = SEMANTIC_COLORS[color];
2890
+ const resolvedColor = subtle ? colorEntry.subtle?.color ?? colorEntry.color : colorEntry.color;
2891
+ const resolvedBorderColor = subtle ? colorEntry.subtle?.borderColor ?? "transparent" : colorEntry.borderColor;
2892
+ return /* @__PURE__ */ jsxDEV7(Fragment2, {
2893
+ children: [
2894
+ /* @__PURE__ */ jsxDEV7("span", {
2895
+ onMouseEnter: hasTooltip ? (e) => setAnchor(e.currentTarget.getBoundingClientRect()) : undefined,
2896
+ onMouseLeave: hasTooltip ? () => setAnchor(null) : undefined,
2897
+ style: {
2898
+ color: resolvedColor,
2899
+ fontSize,
2900
+ background: DEVTOOL_LIST_BASE_BACKGROUND,
2901
+ border: `1px solid ${resolvedBorderColor}`,
2902
+ padding,
2903
+ borderRadius: rounded ? "0.6rem" : "3px",
2904
+ flexShrink: 0,
2905
+ whiteSpace: "nowrap",
2906
+ cursor: hasTooltip ? "default" : undefined,
2907
+ ...style
2908
+ },
2909
+ children
2910
+ }, undefined, false, undefined, this),
2911
+ anchor != null && hasTooltip && /* @__PURE__ */ jsxDEV7(Tooltip, {
2912
+ anchor,
2913
+ config: tooltip
2914
+ }, undefined, false, undefined, this)
2915
+ ]
2916
+ }, undefined, true, undefined, this);
2743
2917
  }
2744
2918
 
2745
- // src/devtools/browser/components/StackTraceSection.tsx
2746
- import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
2747
- var INTERNAL_PATTERNS = [
2748
- "/nice-action/",
2749
- "@nice-code/action",
2750
- "node_modules/",
2751
- "native code",
2752
- "<anonymous>"
2753
- ];
2754
- function isInternalFrame(file) {
2755
- return INTERNAL_PATTERNS.some((p) => file.includes(p));
2919
+ // src/devtools/browser/components/DomainChip.tsx
2920
+ import { jsxDEV as jsxDEV8, Fragment as Fragment3 } from "react/jsx-dev-runtime";
2921
+ function DomainHierarchyContent({ allDomains }) {
2922
+ return /* @__PURE__ */ jsxDEV8(Fragment3, {
2923
+ children: allDomains.map((d, i) => {
2924
+ const isCurrent = i === allDomains.length - 1;
2925
+ return /* @__PURE__ */ jsxDEV8("div", {
2926
+ style: {
2927
+ display: "flex",
2928
+ alignItems: "center",
2929
+ gap: "0.3rem",
2930
+ paddingLeft: `${i * 10}px`,
2931
+ paddingTop: i > 0 ? "0.1rem" : undefined
2932
+ },
2933
+ children: [
2934
+ /* @__PURE__ */ jsxDEV8("span", {
2935
+ style: {
2936
+ fontSize: "0.8rem",
2937
+ height: "0.6em",
2938
+ width: "0.6em",
2939
+ overflow: "hidden",
2940
+ color: isCurrent ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : "#3730a3",
2941
+ display: "flex",
2942
+ alignItems: "center",
2943
+ justifyContent: "center"
2944
+ },
2945
+ children: "⬢"
2946
+ }, undefined, false, undefined, this),
2947
+ /* @__PURE__ */ jsxDEV8("span", {
2948
+ style: {
2949
+ color: isCurrent ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : "#4b5563",
2950
+ fontSize: "0.7rem",
2951
+ fontWeight: isCurrent ? 500 : undefined
2952
+ },
2953
+ children: d
2954
+ }, undefined, false, undefined, this)
2955
+ ]
2956
+ }, d, true, undefined, this);
2957
+ })
2958
+ }, undefined, false, undefined, this);
2756
2959
  }
2757
- function parseStackFrames(stack) {
2758
- return stack.split(`
2759
- `).slice(1).map((line) => {
2760
- const raw = line.trim();
2761
- if (raw === "")
2762
- return null;
2763
- const matchFn = raw.match(/^at (.+?) \((.+):(\d+):(\d+)\)$/);
2764
- if (matchFn != null) {
2765
- const file = matchFn[2];
2766
- return {
2767
- fn: matchFn[1],
2768
- file,
2769
- line: parseInt(matchFn[3], 10),
2770
- col: parseInt(matchFn[4], 10),
2771
- raw,
2772
- isInternal: isInternalFrame(file)
2773
- };
2774
- }
2775
- const matchUrl = raw.match(/^at (.+):(\d+):(\d+)$/);
2776
- if (matchUrl != null) {
2777
- const file = matchUrl[1];
2778
- return {
2779
- file,
2780
- line: parseInt(matchUrl[2], 10),
2781
- col: parseInt(matchUrl[3], 10),
2782
- raw,
2783
- isInternal: isInternalFrame(file)
2784
- };
2785
- }
2786
- return { raw, isInternal: true };
2787
- }).filter((f) => f != null);
2960
+ function DomainChip({
2961
+ subtle = false,
2962
+ domain,
2963
+ allDomains,
2964
+ size
2965
+ }) {
2966
+ return /* @__PURE__ */ jsxDEV8(Chip, {
2967
+ color: "domain" /* domain */,
2968
+ subtle,
2969
+ size,
2970
+ rounded: true,
2971
+ tooltip: {
2972
+ content: /* @__PURE__ */ jsxDEV8(DomainHierarchyContent, {
2973
+ allDomains
2974
+ }, undefined, false, undefined, this),
2975
+ title: "Action Domain",
2976
+ align: "edge"
2977
+ },
2978
+ style: { display: "flex", alignItems: "center", gap: "0.4em" },
2979
+ children: [
2980
+ /* @__PURE__ */ jsxDEV8("span", {
2981
+ style: {
2982
+ height: "0.6em",
2983
+ width: "0.6em",
2984
+ display: "flex",
2985
+ alignItems: "center",
2986
+ justifyContent: "center"
2987
+ },
2988
+ children: "⬢"
2989
+ }, undefined, false, undefined, this),
2990
+ /* @__PURE__ */ jsxDEV8("span", {
2991
+ children: domain
2992
+ }, undefined, false, undefined, this)
2993
+ ]
2994
+ }, undefined, true, undefined, this);
2788
2995
  }
2789
- async function resolveSourceMapPositions(frames) {
2790
- return Promise.all(frames.map(async (frame) => {
2791
- if (frame.isInternal || frame.file == null || frame.line == null)
2792
- return frame;
2793
- const resolved = await resolveCompiledPosition(frame.file, frame.line, frame.col ?? 0);
2794
- if (resolved == null)
2795
- return frame;
2796
- return { ...frame, file: resolved.file, line: resolved.line, col: resolved.col };
2797
- }));
2996
+
2997
+ // src/devtools/browser/components/HandlerChips.tsx
2998
+ import { jsxDEV as jsxDEV9, Fragment as Fragment4 } from "react/jsx-dev-runtime";
2999
+ function getExternalLabel(hop) {
3000
+ if (hop.handlerType !== "external")
3001
+ return null;
3002
+ return hop.handlerClient != null ? `${hop.transport ?? "ext"} → ${hop.handlerClient.envId}` : `→ ${hop.transport ?? "ext"}`;
2798
3003
  }
2799
- function formatFrameFile(file) {
2800
- if (file == null)
2801
- return "?";
2802
- let path = file;
2803
- try {
2804
- const url = new URL(file);
2805
- path = url.pathname.split("?")[0] ?? url.pathname;
2806
- if (path.startsWith("/@fs/"))
2807
- path = path.slice(4);
2808
- } catch {}
2809
- const parts = path.replace(/\\/g, "/").split("/").filter(Boolean);
2810
- const filtered = parts[0]?.match(/^[a-zA-Z]:$/) != null ? parts.slice(1) : parts;
2811
- const tail = filtered.slice(-4);
2812
- return tail.join("/") || file;
3004
+ function HandlerChips({ entry, size }) {
3005
+ const firstHop = entry.meta.routing[0];
3006
+ const localEnvId = firstHop != null ? firstHop.runtime.envId : null;
3007
+ const externalLabel = firstHop != null ? getExternalLabel(firstHop) : null;
3008
+ const firstHopIsLocal = firstHop != null && firstHop.handlerType === "local";
3009
+ return /* @__PURE__ */ jsxDEV9(Fragment4, {
3010
+ children: [
3011
+ localEnvId != null && (firstHopIsLocal || externalLabel == null) && /* @__PURE__ */ jsxDEV9(Chip, {
3012
+ color: "handler_local" /* handler_local */,
3013
+ size,
3014
+ children: localEnvId
3015
+ }, undefined, false, undefined, this),
3016
+ externalLabel != null && /* @__PURE__ */ jsxDEV9(Chip, {
3017
+ color: "handler_external" /* handler_external */,
3018
+ size,
3019
+ children: externalLabel
3020
+ }, undefined, false, undefined, this)
3021
+ ]
3022
+ }, undefined, true, undefined, this);
2813
3023
  }
2814
- function StackTraceSection({
2815
- label,
2816
- stack,
2817
- color = "#60a5fa"
2818
- }) {
2819
- const [showAll, setShowAll] = useState4(false);
2820
- const [resolvedFrames, setResolvedFrames] = useState4(null);
3024
+
3025
+ // src/devtools/browser/components/RunningTimer.tsx
3026
+ import { useEffect as useEffect2, useState as useState4 } from "react";
3027
+ import { jsxDEV as jsxDEV10, Fragment as Fragment5 } from "react/jsx-dev-runtime";
3028
+ function RunningTimer({ startTime }) {
3029
+ const [elapsed, setElapsed] = useState4(() => Date.now() - startTime);
2821
3030
  useEffect2(() => {
2822
- if (stack == null)
2823
- return;
2824
- setResolvedFrames(null);
2825
- const parsed = parseStackFrames(stack);
2826
- let cancelled = false;
2827
- resolveSourceMapPositions(parsed).then((frames) => {
2828
- if (!cancelled)
2829
- setResolvedFrames(frames);
2830
- });
2831
- return () => {
2832
- cancelled = true;
2833
- };
2834
- }, [stack]);
2835
- if (stack == null)
2836
- return null;
2837
- const allFrames = resolvedFrames ?? parseStackFrames(stack);
2838
- const userFrames = allFrames.filter((f) => !f.isInternal);
2839
- const hasInternalFrames = allFrames.length > userFrames.length;
2840
- const displayFrames = showAll ? allFrames : userFrames;
2841
- if (allFrames.length === 0)
3031
+ const interval = setInterval(() => setElapsed(Date.now() - startTime), 100);
3032
+ return () => clearInterval(interval);
3033
+ }, [startTime]);
3034
+ return /* @__PURE__ */ jsxDEV10(Fragment5, {
3035
+ children: [
3036
+ elapsed,
3037
+ "ms"
3038
+ ]
3039
+ }, undefined, true, undefined, this);
3040
+ }
3041
+ function DurationDisplay({ entry }) {
3042
+ const d = formatDuration(entry);
3043
+ return /* @__PURE__ */ jsxDEV10(Fragment5, {
3044
+ children: d ?? /* @__PURE__ */ jsxDEV10(RunningTimer, {
3045
+ startTime: entry.startTime
3046
+ }, undefined, false, undefined, this)
3047
+ }, undefined, false, undefined, this);
3048
+ }
3049
+
3050
+ // src/devtools/browser/components/CallStackSection.tsx
3051
+ import { jsxDEV as jsxDEV11 } from "react/jsx-dev-runtime";
3052
+ function getCalledLabel(entry) {
3053
+ const firstHop = entry.meta.routing[0];
3054
+ if (firstHop == null)
3055
+ return "↳ call";
3056
+ if (firstHop.handlerType === "local")
3057
+ return "↳ local";
3058
+ const label = getExternalLabel(firstHop);
3059
+ return label != null ? `↳ ${label}` : "↳ call";
3060
+ }
3061
+ function getCalledColor(entry) {
3062
+ const firstHop = entry.meta.routing[0];
3063
+ if (firstHop == null)
3064
+ return DEVTOOL_COLOR_SEMANTIC_SYSTEM;
3065
+ if (firstHop.handlerType === "local")
3066
+ return DEVTOOL_COLOR_HANDLER_LOCAL_TEXT;
3067
+ return DEVTOOL_COLOR_HANDLER_EXTERNAL_TEXT;
3068
+ }
3069
+ function CallStackLink({
3070
+ entry,
3071
+ entryRole,
3072
+ isFocused,
3073
+ onClick
3074
+ }) {
3075
+ const color = STATUS_COLOR[entry.status];
3076
+ const symbol = STATUS_SYMBOL[entry.status];
3077
+ const labelColor = entryRole === "caller" ? DEVTOOL_COLOR_TEXT_SECONDARY : getCalledColor(entry);
3078
+ const label = entryRole === "caller" ? "↑ from" : getCalledLabel(entry);
3079
+ return /* @__PURE__ */ jsxDEV11("div", {
3080
+ onClick,
3081
+ style: {
3082
+ background: isFocused ? DEVTOOL_SECTION_BACKGROUND : DEVTOOL_DETAIL_HEADER_BACKGROUND,
3083
+ borderBottom: `1px solid ${DEVTOOL_COLOR_CALL_STACK_DIVIDER}`,
3084
+ borderLeft: isFocused ? `2px solid ${DEVTOOL_COLOR_SEMANTIC_SYSTEM}` : "2px solid transparent",
3085
+ padding: "5px 12px 5px 10px",
3086
+ display: "grid",
3087
+ gridTemplateColumns: "1fr 1fr",
3088
+ alignItems: "center",
3089
+ columnGap: "6px",
3090
+ cursor: "pointer"
3091
+ },
3092
+ children: [
3093
+ /* @__PURE__ */ jsxDEV11("span", {
3094
+ style: { display: "flex", alignItems: "center", gap: "1em", flexShrink: 0 },
3095
+ children: [
3096
+ /* @__PURE__ */ jsxDEV11("span", {
3097
+ style: { color, fontSize: "10px", flexShrink: 0 },
3098
+ children: symbol
3099
+ }, undefined, false, undefined, this),
3100
+ /* @__PURE__ */ jsxDEV11("span", {
3101
+ style: { color: labelColor, fontSize: "9px", flexShrink: 0 },
3102
+ children: label
3103
+ }, undefined, false, undefined, this),
3104
+ /* @__PURE__ */ jsxDEV11("span", {
3105
+ style: { display: "flex", alignItems: "center", gap: "5px" },
3106
+ children: [
3107
+ /* @__PURE__ */ jsxDEV11("span", {
3108
+ style: {
3109
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
3110
+ fontSize: "11px",
3111
+ overflow: "hidden",
3112
+ textOverflow: "ellipsis",
3113
+ whiteSpace: "nowrap"
3114
+ },
3115
+ children: entry.actionId
3116
+ }, undefined, false, undefined, this),
3117
+ /* @__PURE__ */ jsxDEV11(DomainChip, {
3118
+ domain: entry.domain,
3119
+ allDomains: entry.allDomains,
3120
+ size: "sm" /* sm */
3121
+ }, undefined, false, undefined, this)
3122
+ ]
3123
+ }, undefined, true, undefined, this)
3124
+ ]
3125
+ }, undefined, true, undefined, this),
3126
+ /* @__PURE__ */ jsxDEV11("span", {
3127
+ style: {
3128
+ color: DEVTOOL_COLOR_TEXT_FAINT,
3129
+ fontSize: "10px",
3130
+ textAlign: "right",
3131
+ whiteSpace: "nowrap"
3132
+ },
3133
+ children: /* @__PURE__ */ jsxDEV11(DurationDisplay, {
3134
+ entry
3135
+ }, undefined, false, undefined, this)
3136
+ }, undefined, false, undefined, this)
3137
+ ]
3138
+ }, undefined, true, undefined, this);
3139
+ }
3140
+ function CallStackSection({
3141
+ parent,
3142
+ childEntries,
3143
+ focusedChildCuid,
3144
+ onFocusChild,
3145
+ onSelectParent
3146
+ }) {
3147
+ if (parent == null && childEntries.length === 0)
2842
3148
  return null;
2843
3149
  return /* @__PURE__ */ jsxDEV11("div", {
2844
3150
  children: [
2845
- /* @__PURE__ */ jsxDEV11("div", {
3151
+ parent != null && /* @__PURE__ */ jsxDEV11(CallStackLink, {
3152
+ entry: parent,
3153
+ entryRole: "caller",
3154
+ isFocused: false,
3155
+ onClick: () => onSelectParent(parent.cuid)
3156
+ }, undefined, false, undefined, this),
3157
+ childEntries.map((child) => /* @__PURE__ */ jsxDEV11(CallStackLink, {
3158
+ entry: child,
3159
+ entryRole: "called",
3160
+ isFocused: focusedChildCuid === child.cuid,
3161
+ onClick: () => onFocusChild(child.cuid)
3162
+ }, child.cuid, false, undefined, this))
3163
+ ]
3164
+ }, undefined, true, undefined, this);
3165
+ }
3166
+
3167
+ // src/devtools/browser/components/ChildDispatchChips.tsx
3168
+ import { jsxDEV as jsxDEV12 } from "react/jsx-dev-runtime";
3169
+ function ChildDispatchChips({
3170
+ childRouteItems,
3171
+ size = "sm" /* sm */
3172
+ }) {
3173
+ if (childRouteItems == null || childRouteItems.length === 0)
3174
+ return null;
3175
+ const groups = new Map;
3176
+ for (const item of childRouteItems) {
3177
+ const runtimeId = item.handlerClient?.envId ?? item.transport ?? "ext";
3178
+ const hasClient = item.handlerClient != null;
3179
+ if (!groups.has(runtimeId)) {
3180
+ groups.set(runtimeId, { runtimeId, transports: [], hasClient });
3181
+ }
3182
+ const transport = item.transport;
3183
+ const group = groups.get(runtimeId);
3184
+ if (transport != null && !group.transports.includes(transport)) {
3185
+ group.transports.push(transport);
3186
+ }
3187
+ }
3188
+ return /* @__PURE__ */ jsxDEV12("div", {
3189
+ style: { display: "flex", alignItems: "center", gap: "4px", flexWrap: "wrap" },
3190
+ children: Array.from(groups.values()).map((group) => {
3191
+ const transportStr = group.transports.length > 0 ? group.transports.join(", ") : "ext";
3192
+ const label = group.hasClient ? `${transportStr} → ${group.runtimeId}` : `→ ${transportStr}`;
3193
+ return /* @__PURE__ */ jsxDEV12(Chip, {
3194
+ color: "handler_external" /* handler_external */,
3195
+ size,
3196
+ children: label
3197
+ }, group.runtimeId, false, undefined, this);
3198
+ })
3199
+ }, undefined, false, undefined, this);
3200
+ }
3201
+
3202
+ // src/devtools/browser/components/MetaSection.tsx
3203
+ import { useState as useState5 } from "react";
3204
+ import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
3205
+ function MetaChip({ label, value }) {
3206
+ return /* @__PURE__ */ jsxDEV13("span", {
3207
+ style: { whiteSpace: "nowrap" },
3208
+ children: [
3209
+ /* @__PURE__ */ jsxDEV13("span", {
3210
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED },
3211
+ children: [
3212
+ label,
3213
+ " "
3214
+ ]
3215
+ }, undefined, true, undefined, this),
3216
+ /* @__PURE__ */ jsxDEV13("span", {
3217
+ style: { color: DEVTOOL_COLOR_TEXT_SECONDARY },
3218
+ children: value
3219
+ }, undefined, false, undefined, this)
3220
+ ]
3221
+ }, undefined, true, undefined, this);
3222
+ }
3223
+ function MetaSection({ entry }) {
3224
+ const [expanded, setExpanded] = useState5(false);
3225
+ const { meta, cuid } = entry;
3226
+ const expandedRows = [
3227
+ { label: "cuid", value: cuid },
3228
+ { label: "runtime", value: meta.originClient.envId },
3229
+ ...meta.originClient.perId != null ? [{ label: "perId", value: meta.originClient.perId }] : [],
3230
+ ...meta.originClient.insId != null ? [{ label: "insId", value: meta.originClient.insId }] : []
3231
+ ];
3232
+ return /* @__PURE__ */ jsxDEV13("div", {
3233
+ children: [
3234
+ /* @__PURE__ */ jsxDEV13("div", {
2846
3235
  style: {
2847
3236
  display: "flex",
2848
- alignItems: "center",
2849
- justifyContent: "space-between",
2850
- marginBottom: "3px"
3237
+ alignItems: "center",
3238
+ justifyContent: "space-between",
3239
+ marginBottom: "3px"
3240
+ },
3241
+ children: [
3242
+ /* @__PURE__ */ jsxDEV13("div", {
3243
+ style: {
3244
+ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
3245
+ fontSize: "10px",
3246
+ textTransform: "uppercase",
3247
+ letterSpacing: "0.05em"
3248
+ },
3249
+ children: "Meta"
3250
+ }, undefined, false, undefined, this),
3251
+ /* @__PURE__ */ jsxDEV13("span", {
3252
+ style: { color: DEVTOOL_COLOR_TEXT_FAINT, fontSize: "11px" },
3253
+ children: expanded ? "▾" : "▸"
3254
+ }, undefined, false, undefined, this)
3255
+ ]
3256
+ }, undefined, true, undefined, this),
3257
+ expanded ? /* @__PURE__ */ jsxDEV13("div", {
3258
+ onClick: () => setExpanded(false),
3259
+ style: {
3260
+ background: DEVTOOL_SECTION_BACKGROUND,
3261
+ borderRadius: "4px",
3262
+ overflow: "hidden",
3263
+ cursor: "pointer"
3264
+ },
3265
+ children: expandedRows.map(({ label, value }, i) => /* @__PURE__ */ jsxDEV13("div", {
3266
+ style: {
3267
+ display: "grid",
3268
+ gridTemplateColumns: "52px 1fr",
3269
+ columnGap: "8px",
3270
+ padding: "4px 8px",
3271
+ borderBottom: i < expandedRows.length - 1 ? `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}` : "none",
3272
+ alignItems: "start"
3273
+ },
3274
+ children: [
3275
+ /* @__PURE__ */ jsxDEV13("span", {
3276
+ style: { textAlign: "left", color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: "10px", paddingTop: "1px" },
3277
+ children: label
3278
+ }, undefined, false, undefined, this),
3279
+ /* @__PURE__ */ jsxDEV13("span", {
3280
+ style: {
3281
+ textAlign: "left",
3282
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
3283
+ fontSize: "11px",
3284
+ wordBreak: "break-all"
3285
+ },
3286
+ children: value
3287
+ }, undefined, false, undefined, this)
3288
+ ]
3289
+ }, label, true, undefined, this))
3290
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV13("div", {
3291
+ onClick: () => setExpanded(true),
3292
+ style: {
3293
+ background: DEVTOOL_SECTION_BACKGROUND,
3294
+ borderRadius: "4px",
3295
+ padding: "5px 8px",
3296
+ fontSize: "11px",
3297
+ display: "flex",
3298
+ gap: "10px",
3299
+ rowGap: "2px",
3300
+ flexWrap: "wrap",
3301
+ cursor: "pointer"
2851
3302
  },
2852
3303
  children: [
2853
- /* @__PURE__ */ jsxDEV11(SectionLabel, {
2854
- label,
2855
- color
3304
+ /* @__PURE__ */ jsxDEV13(MetaChip, {
3305
+ label: "cuid",
3306
+ value: `…${cuid.slice(-8)}`
2856
3307
  }, undefined, false, undefined, this),
2857
- hasInternalFrames && /* @__PURE__ */ jsxDEV11("span", {
2858
- style: { color: "#475569", fontSize: "9px" },
2859
- children: !showAll ? "user only" : `all (${allFrames.length})`
3308
+ /* @__PURE__ */ jsxDEV13(MetaChip, {
3309
+ label: "runtime",
3310
+ value: meta.originClient.envId
3311
+ }, undefined, false, undefined, this),
3312
+ meta.originClient.perId != null && /* @__PURE__ */ jsxDEV13(MetaChip, {
3313
+ label: "perId",
3314
+ value: meta.originClient.perId.length > 10 ? `${meta.originClient.perId.slice(0, 10)}…` : meta.originClient.perId
3315
+ }, undefined, false, undefined, this),
3316
+ meta.originClient.insId != null && /* @__PURE__ */ jsxDEV13(MetaChip, {
3317
+ label: "insId",
3318
+ value: meta.originClient.insId.length > 10 ? `${meta.originClient.insId.slice(0, 10)}…` : meta.originClient.insId
2860
3319
  }, undefined, false, undefined, this)
2861
3320
  ]
2862
- }, undefined, true, undefined, this),
2863
- /* @__PURE__ */ jsxDEV11("div", {
2864
- onClick: () => setShowAll((s) => !s),
2865
- style: {
2866
- background: "#040a13",
2867
- borderRadius: "4px",
2868
- padding: "2px",
2869
- overflow: "hidden",
2870
- cursor: "pointer"
2871
- },
2872
- children: displayFrames.length === 0 ? /* @__PURE__ */ jsxDEV11("div", {
2873
- style: { padding: "6px 10px", color: "#64748b", fontSize: "10px", fontStyle: "italic" },
2874
- children: "no user frames captured"
2875
- }, undefined, false, undefined, this) : displayFrames.map((frame, idx) => {
2876
- const displayFile = formatFrameFile(frame.file);
2877
- const slashIdx = displayFile.lastIndexOf("/");
2878
- const folderPrefix = slashIdx >= 0 ? displayFile.slice(0, slashIdx + 1) : "";
2879
- const bareFilename = slashIdx >= 0 ? displayFile.slice(slashIdx + 1) : displayFile;
2880
- const titleStr = frame.file != null ? frame.file : frame.raw;
2881
- const isUser = !frame.isInternal;
2882
- return /* @__PURE__ */ jsxDEV11("div", {
2883
- title: titleStr,
2884
- style: {
2885
- display: "flex",
2886
- flexDirection: "row",
2887
- gap: "0.5em",
2888
- padding: "4px",
2889
- borderBottom: idx < displayFrames.length - 1 ? "1px solid #0f172a" : undefined
2890
- },
2891
- children: [
2892
- /* @__PURE__ */ jsxDEV11("span", {
2893
- style: {
2894
- color: isUser ? "#64748b" : "#2d3f53",
2895
- fontSize: "10px",
2896
- minWidth: "10px",
2897
- textAlign: "left",
2898
- flexShrink: 0,
2899
- fontVariantNumeric: "tabular-nums"
2900
- },
2901
- children: idx + 1
2902
- }, undefined, false, undefined, this),
2903
- /* @__PURE__ */ jsxDEV11("div", {
2904
- style: { display: "flex", flexDirection: "column", gap: "0.15em", lineHeight: 1.2 },
2905
- children: [
2906
- /* @__PURE__ */ jsxDEV11("div", {
2907
- style: { display: "flex", alignItems: "center" },
2908
- children: /* @__PURE__ */ jsxDEV11("span", {
3321
+ }, undefined, true, undefined, this)
3322
+ ]
3323
+ }, undefined, true, undefined, this);
3324
+ }
3325
+
3326
+ // src/devtools/browser/components/RoutingSection.tsx
3327
+ import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
3328
+ function RoutingSection({
3329
+ entry,
3330
+ minHopCount = 0
3331
+ }) {
3332
+ const { meta, startTime } = entry;
3333
+ const hopCount = meta.routing.length;
3334
+ const phantomCount = Math.max(0, minHopCount - hopCount);
3335
+ if (hopCount === 0 && phantomCount === 0)
3336
+ return null;
3337
+ return /* @__PURE__ */ jsxDEV14("div", {
3338
+ children: [
3339
+ /* @__PURE__ */ jsxDEV14(SectionLabel, {
3340
+ label: hopCount > 0 ? `Routing · ${hopCount} hop${hopCount !== 1 ? "s" : ""}` : "Routing"
3341
+ }, undefined, false, undefined, this),
3342
+ /* @__PURE__ */ jsxDEV14("div", {
3343
+ style: { display: "flex", flexDirection: "column", gap: "2px" },
3344
+ children: [
3345
+ meta.routing.map((hop, i) => {
3346
+ const isLocal = hop.handlerType === "local";
3347
+ const isLast = i === hopCount - 1 && phantomCount === 0;
3348
+ const badgeColor = isLocal ? DEVTOOL_COLOR_SEMANTIC_SUCCESS : DEVTOOL_COLOR_SEMANTIC_WARNING;
3349
+ const badgeText = isLocal ? "● exec" : `→ ${hop.transport ?? "ext"}`;
3350
+ const runtimeTitle = [hop.runtime.perId, hop.runtime.insId].filter(Boolean).join(" · ") || undefined;
3351
+ return /* @__PURE__ */ jsxDEV14("div", {
3352
+ style: {
3353
+ background: DEVTOOL_SECTION_BACKGROUND,
3354
+ borderRadius: "4px",
3355
+ overflow: "hidden",
3356
+ display: "grid",
3357
+ gridTemplateColumns: "30% 1fr 30%",
3358
+ alignItems: "center",
3359
+ columnGap: "8px",
3360
+ borderBottom: isLast ? undefined : `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
3361
+ padding: "4px 8px"
3362
+ },
3363
+ children: [
3364
+ /* @__PURE__ */ jsxDEV14("span", {
3365
+ style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "10px" },
3366
+ children: [
3367
+ /* @__PURE__ */ jsxDEV14("span", {
3368
+ style: { color: DEVTOOL_COLOR_TEXT_FAINT, fontSize: "10px", width: "16px", textAlign: "right" },
3369
+ children: i + 1
3370
+ }, undefined, false, undefined, this),
3371
+ /* @__PURE__ */ jsxDEV14("span", {
3372
+ title: runtimeTitle,
2909
3373
  style: {
2910
- color: isUser ? "#e2e8f0" : "#50698b",
2911
- fontSize: "12px",
2912
- fontWeight: 500,
3374
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
3375
+ fontSize: "11px",
2913
3376
  overflow: "hidden",
2914
3377
  textOverflow: "ellipsis",
2915
- whiteSpace: "nowrap"
3378
+ whiteSpace: "nowrap",
3379
+ textAlign: "center"
2916
3380
  },
2917
- children: frame.fn ?? "(anonymous)"
3381
+ children: hop.runtime.envId
2918
3382
  }, undefined, false, undefined, this)
3383
+ ]
3384
+ }, undefined, true, undefined, this),
3385
+ /* @__PURE__ */ jsxDEV14("span", {
3386
+ style: { color: badgeColor, fontSize: "10px", whiteSpace: "nowrap" },
3387
+ children: badgeText
3388
+ }, undefined, false, undefined, this),
3389
+ /* @__PURE__ */ jsxDEV14("span", {
3390
+ style: {
3391
+ display: "flex",
3392
+ alignItems: "center",
3393
+ justifyContent: "space-between",
3394
+ paddingRight: "8px",
3395
+ overflow: "hidden"
3396
+ },
3397
+ children: [
3398
+ /* @__PURE__ */ jsxDEV14("span", {
3399
+ style: {
3400
+ color: DEVTOOL_COLOR_TEXT_MUTED,
3401
+ fontSize: "10px",
3402
+ whiteSpace: "nowrap",
3403
+ overflow: "hidden",
3404
+ textOverflow: "ellipsis"
3405
+ },
3406
+ children: hop.handlerClient != null ? `↳ ${hop.handlerClient.envId}` : ""
3407
+ }, undefined, false, undefined, this),
3408
+ /* @__PURE__ */ jsxDEV14("span", {
3409
+ style: { color: DEVTOOL_COLOR_TEXT_FAINT, fontSize: "10px", flexShrink: 0, marginLeft: "auto" },
3410
+ children: [
3411
+ "+",
3412
+ hop.time - startTime,
3413
+ "ms"
3414
+ ]
3415
+ }, undefined, true, undefined, this)
3416
+ ]
3417
+ }, undefined, true, undefined, this)
3418
+ ]
3419
+ }, `${hop.time}-${hop.runtime.envId}`, true, undefined, this);
3420
+ }),
3421
+ Array.from({ length: phantomCount }, (_, i) => `routing-phantom-${hopCount + i}`).map((key) => /* @__PURE__ */ jsxDEV14("div", {
3422
+ "aria-hidden": "true",
3423
+ style: {
3424
+ visibility: "hidden",
3425
+ background: DEVTOOL_SECTION_BACKGROUND,
3426
+ borderRadius: "4px",
3427
+ display: "grid",
3428
+ gridTemplateColumns: "30% 1fr 30%",
3429
+ alignItems: "center",
3430
+ columnGap: "8px",
3431
+ padding: "4px 8px"
3432
+ },
3433
+ children: [
3434
+ /* @__PURE__ */ jsxDEV14("span", {
3435
+ style: { display: "flex", flexDirection: "row", alignItems: "center", gap: "10px" },
3436
+ children: [
3437
+ /* @__PURE__ */ jsxDEV14("span", {
3438
+ style: { fontSize: "10px", width: "16px" },
3439
+ children: "0"
2919
3440
  }, undefined, false, undefined, this),
2920
- /* @__PURE__ */ jsxDEV11("div", {
2921
- style: { display: "flex", alignItems: "baseline", overflow: "hidden" },
2922
- children: [
2923
- folderPrefix !== "" && /* @__PURE__ */ jsxDEV11("span", {
2924
- style: {
2925
- color: isUser ? "#596b83" : "#2d3f53",
2926
- fontSize: "10px",
2927
- overflow: "hidden",
2928
- textOverflow: "ellipsis",
2929
- whiteSpace: "nowrap",
2930
- flexShrink: 1,
2931
- minWidth: 0
2932
- },
2933
- children: folderPrefix
2934
- }, undefined, false, undefined, this),
2935
- /* @__PURE__ */ jsxDEV11("span", {
2936
- style: {
2937
- color: isUser ? "#8a9ebb" : "#425979",
2938
- fontSize: "10px",
2939
- whiteSpace: "nowrap",
2940
- flexShrink: 0
2941
- },
2942
- children: bareFilename
2943
- }, undefined, false, undefined, this),
2944
- frame.line != null && /* @__PURE__ */ jsxDEV11("span", {
2945
- style: {
2946
- color: isUser ? "#4a7fa8" : "#2d4a63",
2947
- fontSize: "10px",
2948
- whiteSpace: "nowrap",
2949
- flexShrink: 0,
2950
- fontVariantNumeric: "tabular-nums"
2951
- },
2952
- children: [
2953
- ":",
2954
- frame.line
2955
- ]
2956
- }, undefined, true, undefined, this)
2957
- ]
2958
- }, undefined, true, undefined, this)
3441
+ /* @__PURE__ */ jsxDEV14("span", {
3442
+ style: { fontSize: "11px" },
3443
+ children: "placeholder"
3444
+ }, undefined, false, undefined, this)
2959
3445
  ]
2960
- }, undefined, true, undefined, this)
3446
+ }, undefined, true, undefined, this),
3447
+ /* @__PURE__ */ jsxDEV14("span", {
3448
+ style: { fontSize: "10px" },
3449
+ children: "placeholder"
3450
+ }, undefined, false, undefined, this),
3451
+ /* @__PURE__ */ jsxDEV14("span", {}, undefined, false, undefined, this)
2961
3452
  ]
2962
- }, frame.raw, true, undefined, this);
2963
- })
2964
- }, undefined, false, undefined, this)
3453
+ }, key, true, undefined, this))
3454
+ ]
3455
+ }, undefined, true, undefined, this)
2965
3456
  ]
2966
3457
  }, undefined, true, undefined, this);
2967
3458
  }
2968
3459
 
2969
- // src/devtools/browser/components/ActionDetailPanel.tsx
2970
- import { jsxDEV as jsxDEV12, Fragment as Fragment4 } from "react/jsx-dev-runtime";
3460
+ // src/devtools/browser/components/action_detail/ActionDetailPanel.tsx
3461
+ import { jsxDEV as jsxDEV15 } from "react/jsx-dev-runtime";
3462
+ var STATUS_BADGE_LABEL = {
3463
+ running: "RUNNING",
3464
+ success: "SUCCESS",
3465
+ "action-error": "ERROR",
3466
+ failed: "FAILED",
3467
+ aborted: "ABORTED"
3468
+ };
3469
+ var STATUS_BADGE_BG = {
3470
+ running: STATUS_COLOR.running,
3471
+ success: STATUS_COLOR.success,
3472
+ "action-error": DEVTOOL_COLOR_SEMANTIC_ERROR,
3473
+ failed: DEVTOOL_COLOR_SEMANTIC_ERROR,
3474
+ aborted: DEVTOOL_COLOR_SEMANTIC_METADATA
3475
+ };
3476
+ var STATUS_BADGE_TEXT_COLOR = {
3477
+ running: "#0f172a",
3478
+ success: "#0f172a",
3479
+ "action-error": "#ffffff",
3480
+ failed: "#ffffff",
3481
+ aborted: "#0f172a"
3482
+ };
2971
3483
  function DetailHeader({
2972
3484
  entry,
2973
3485
  isActive,
2974
3486
  onClick,
2975
- childExternalLabels
3487
+ childExternalRouteItems
2976
3488
  }) {
2977
3489
  const color = STATUS_COLOR[entry.status];
2978
- const symbol = STATUS_SYMBOL[entry.status];
3490
+ const StatusIconComponent = STATUS_ICON[entry.status];
2979
3491
  const timestamp = formatTimestamp(entry.startTime);
2980
- return /* @__PURE__ */ jsxDEV12("div", {
3492
+ return /* @__PURE__ */ jsxDEV15("div", {
2981
3493
  onClick: !isActive ? onClick : undefined,
2982
3494
  style: {
2983
- padding: "10px 12px",
2984
- background: isActive ? "#1e293b" : "#131f35",
2985
- borderBottom: "1px solid #0f172a",
2986
- borderLeft: isActive ? "2px solid #60a5fa" : "2px solid transparent",
3495
+ padding: "0.5em 1em",
3496
+ background: isActive ? DEVTOOL_SECTION_BACKGROUND : DEVTOOL_DETAIL_HEADER_BACKGROUND,
3497
+ borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
3498
+ borderLeft: isActive ? `2px solid ${color}` : "2px solid transparent",
2987
3499
  flexShrink: 0,
3500
+ flexDirection: "row",
2988
3501
  display: "flex",
2989
3502
  alignItems: "flex-start",
2990
- gap: "10px",
3503
+ gap: "1em",
2991
3504
  cursor: isActive ? "default" : "pointer"
2992
3505
  },
2993
- children: [
2994
- /* @__PURE__ */ jsxDEV12("span", {
2995
- style: {
2996
- color,
2997
- fontSize: "15px",
2998
- flexShrink: 0,
2999
- paddingTop: "1px",
3000
- animation: entry.status === "running" ? "__nice-action-pulse 1.2s ease-in-out infinite" : undefined
3001
- },
3002
- children: symbol
3003
- }, undefined, false, undefined, this),
3004
- /* @__PURE__ */ jsxDEV12("div", {
3005
- style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "0.5em" },
3006
- children: [
3007
- /* @__PURE__ */ jsxDEV12("div", {
3008
- style: { display: "flex", alignItems: "center", minWidth: 0, gap: "0.4em" },
3009
- children: [
3010
- /* @__PURE__ */ jsxDEV12("span", {
3011
- style: { fontSize: "1.2em" },
3012
- children: "⚡"
3013
- }, undefined, false, undefined, this),
3014
- /* @__PURE__ */ jsxDEV12("span", {
3015
- style: {
3016
- color: "#f1f5f9",
3017
- fontSize: "1.2em",
3018
- fontWeight: "600",
3019
- overflow: "hidden",
3020
- textOverflow: "ellipsis",
3021
- whiteSpace: "nowrap",
3022
- flexShrink: 1,
3023
- minWidth: "24px"
3024
- },
3025
- children: entry.actionId
3026
- }, undefined, false, undefined, this),
3027
- /* @__PURE__ */ jsxDEV12(DomainChip, {
3028
- domain: entry.domain,
3029
- allDomains: entry.allDomains,
3030
- size: "md"
3506
+ children: /* @__PURE__ */ jsxDEV15("div", {
3507
+ style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "0.5em" },
3508
+ children: [
3509
+ /* @__PURE__ */ jsxDEV15("div", {
3510
+ style: { display: "flex", alignItems: "center", minWidth: 0, gap: "0.5em" },
3511
+ children: [
3512
+ /* @__PURE__ */ jsxDEV15("span", {
3513
+ style: {
3514
+ color,
3515
+ flexShrink: 0,
3516
+ display: "flex",
3517
+ alignItems: "center",
3518
+ animation: entry.status === "running" ? "__nice-action-pulse 1.2s ease-in-out infinite" : undefined
3519
+ },
3520
+ children: /* @__PURE__ */ jsxDEV15(StatusIconComponent, {
3521
+ size: 20,
3522
+ strokeWidth: 1.75
3031
3523
  }, undefined, false, undefined, this)
3032
- ]
3033
- }, undefined, true, undefined, this),
3034
- /* @__PURE__ */ jsxDEV12("div", {
3035
- style: {
3036
- display: "flex",
3037
- alignItems: "center",
3038
- justifyContent: "space-between",
3039
- gap: "8px"
3040
- },
3041
- children: [
3042
- /* @__PURE__ */ jsxDEV12("div", {
3043
- style: {
3044
- display: "flex",
3045
- alignItems: "center",
3046
- gap: "6px",
3047
- minWidth: 0,
3048
- overflow: "hidden"
3049
- },
3050
- children: [
3051
- /* @__PURE__ */ jsxDEV12(HandlerChips, {
3052
- entry,
3053
- size: "md"
3054
- }, undefined, false, undefined, this),
3055
- /* @__PURE__ */ jsxDEV12(ChildDispatchChips, {
3056
- labels: childExternalLabels,
3057
- size: "md"
3058
- }, undefined, false, undefined, this)
3059
- ]
3060
- }, undefined, true, undefined, this),
3061
- /* @__PURE__ */ jsxDEV12("div", {
3062
- style: { display: "flex", alignItems: "center", gap: "8px", flexShrink: 0 },
3063
- children: [
3064
- /* @__PURE__ */ jsxDEV12("span", {
3065
- style: { color: "#334155", fontSize: "10px", letterSpacing: "0.02em" },
3066
- children: timestamp
3067
- }, undefined, false, undefined, this),
3068
- /* @__PURE__ */ jsxDEV12("span", {
3069
- style: { color, fontSize: "12px", fontWeight: "500" },
3070
- children: /* @__PURE__ */ jsxDEV12(DurationDisplay, {
3071
- entry
3072
- }, undefined, false, undefined, this)
3524
+ }, undefined, false, undefined, this),
3525
+ /* @__PURE__ */ jsxDEV15("span", {
3526
+ style: {
3527
+ color: DEVTOOL_COLOR_TEXT_EMPHASIS,
3528
+ fontSize: "1.2em",
3529
+ fontWeight: "600",
3530
+ fontFamily: "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace",
3531
+ overflow: "hidden",
3532
+ textOverflow: "ellipsis",
3533
+ whiteSpace: "nowrap",
3534
+ flexShrink: 1,
3535
+ minWidth: "2.5em"
3536
+ },
3537
+ children: entry.actionId
3538
+ }, undefined, false, undefined, this),
3539
+ /* @__PURE__ */ jsxDEV15("span", {
3540
+ style: {
3541
+ flexShrink: 0,
3542
+ padding: "2px 9px",
3543
+ borderRadius: "999px",
3544
+ background: STATUS_BADGE_BG[entry.status],
3545
+ color: STATUS_BADGE_TEXT_COLOR[entry.status],
3546
+ fontSize: "9px",
3547
+ fontWeight: "700",
3548
+ letterSpacing: "0.1em",
3549
+ textTransform: "uppercase",
3550
+ fontFamily: "ui-sans-serif, system-ui, sans-serif"
3551
+ },
3552
+ children: STATUS_BADGE_LABEL[entry.status]
3553
+ }, undefined, false, undefined, this),
3554
+ /* @__PURE__ */ jsxDEV15(DomainChip, {
3555
+ domain: entry.domain,
3556
+ allDomains: entry.allDomains,
3557
+ size: "md" /* md */
3558
+ }, undefined, false, undefined, this)
3559
+ ]
3560
+ }, undefined, true, undefined, this),
3561
+ /* @__PURE__ */ jsxDEV15("div", {
3562
+ style: {
3563
+ display: "flex",
3564
+ alignItems: "center",
3565
+ justifyContent: "space-between",
3566
+ gap: "8px"
3567
+ },
3568
+ children: [
3569
+ /* @__PURE__ */ jsxDEV15("div", {
3570
+ style: {
3571
+ display: "flex",
3572
+ alignItems: "center",
3573
+ gap: "6px",
3574
+ minWidth: 0,
3575
+ overflow: "hidden"
3576
+ },
3577
+ children: [
3578
+ /* @__PURE__ */ jsxDEV15(HandlerChips, {
3579
+ entry,
3580
+ size: "md" /* md */
3581
+ }, undefined, false, undefined, this),
3582
+ /* @__PURE__ */ jsxDEV15(ChildDispatchChips, {
3583
+ childRouteItems: childExternalRouteItems,
3584
+ size: "md" /* md */
3585
+ }, undefined, false, undefined, this)
3586
+ ]
3587
+ }, undefined, true, undefined, this),
3588
+ /* @__PURE__ */ jsxDEV15("div", {
3589
+ style: { display: "flex", alignItems: "center", gap: "8px", flexShrink: 0 },
3590
+ children: [
3591
+ /* @__PURE__ */ jsxDEV15("span", {
3592
+ style: {
3593
+ color: DEVTOOL_COLOR_SEMANTIC_METADATA,
3594
+ fontSize: "10px",
3595
+ letterSpacing: "0.02em",
3596
+ fontFamily: "ui-sans-serif, system-ui, sans-serif"
3597
+ },
3598
+ children: timestamp
3599
+ }, undefined, false, undefined, this),
3600
+ /* @__PURE__ */ jsxDEV15("span", {
3601
+ style: { color, fontSize: "12px", fontWeight: "500" },
3602
+ children: /* @__PURE__ */ jsxDEV15(DurationDisplay, {
3603
+ entry
3073
3604
  }, undefined, false, undefined, this)
3074
- ]
3075
- }, undefined, true, undefined, this)
3076
- ]
3077
- }, undefined, true, undefined, this)
3078
- ]
3079
- }, undefined, true, undefined, this)
3080
- ]
3081
- }, undefined, true, undefined, this);
3605
+ }, undefined, false, undefined, this)
3606
+ ]
3607
+ }, undefined, true, undefined, this)
3608
+ ]
3609
+ }, undefined, true, undefined, this)
3610
+ ]
3611
+ }, undefined, true, undefined, this)
3612
+ }, undefined, false, undefined, this);
3082
3613
  }
3083
3614
  function ActionDetailPanel({
3084
3615
  entry,
@@ -3086,44 +3617,52 @@ function ActionDetailPanel({
3086
3617
  childEntries,
3087
3618
  onSelectEntry
3088
3619
  }) {
3089
- const [focusedChildCuid, setFocusedChildCuid] = useState5(null);
3620
+ const [focusedChildCuid, setFocusedChildCuid] = useState6(null);
3090
3621
  const focusedEntry = focusedChildCuid != null ? childEntries.find((e) => e.cuid === focusedChildCuid) ?? entry : entry;
3091
3622
  const maxRoutingHops = Math.max(entry.meta.routing.length, ...childEntries.map((e) => e.meta.routing.length), 0);
3092
- const childExternalLabels = useMemo(() => {
3623
+ const maxCallSiteFrames = Math.max(countUserFrames(entry.callSite), ...childEntries.map((e) => countUserFrames(e.callSite)), 0);
3624
+ const childExternalRouteItems = useMemo(() => {
3093
3625
  const seen = new Set;
3094
3626
  const result = [];
3095
3627
  for (const child of childEntries) {
3096
3628
  const firstHop = child.meta.routing[0];
3097
- if (firstHop == null)
3629
+ if (firstHop == null || firstHop.handlerType !== "external")
3098
3630
  continue;
3099
- const label = getExternalLabel(firstHop);
3100
- if (label == null || seen.has(label))
3631
+ const key = `${firstHop.handlerClient?.envId ?? ""}:${firstHop.transport ?? ""}`;
3632
+ if (seen.has(key))
3101
3633
  continue;
3102
- seen.add(label);
3103
- result.push(label);
3634
+ seen.add(key);
3635
+ result.push(firstHop);
3104
3636
  }
3105
3637
  return result;
3106
3638
  }, [childEntries]);
3107
3639
  const handleFocusChild = (cuid) => {
3108
3640
  setFocusedChildCuid((prev) => prev === cuid ? null : cuid);
3109
3641
  };
3110
- return /* @__PURE__ */ jsxDEV12("div", {
3642
+ return /* @__PURE__ */ jsxDEV15("div", {
3111
3643
  style: {
3112
3644
  flex: 1,
3113
3645
  display: "flex",
3114
3646
  flexDirection: "column",
3115
3647
  overflow: "hidden",
3116
3648
  minHeight: 0,
3117
- background: "#0f172a"
3649
+ background: DEVTOOL_DETAIL_BASE_BACKGROUND
3118
3650
  },
3119
3651
  children: [
3120
- /* @__PURE__ */ jsxDEV12(DetailHeader, {
3652
+ /* @__PURE__ */ jsxDEV15(DetailHeader, {
3121
3653
  entry,
3122
3654
  isActive: focusedChildCuid === null,
3123
3655
  onClick: () => setFocusedChildCuid(null),
3124
- childExternalLabels
3656
+ childExternalRouteItems
3125
3657
  }, undefined, false, undefined, this),
3126
- /* @__PURE__ */ jsxDEV12("div", {
3658
+ /* @__PURE__ */ jsxDEV15(CallStackSection, {
3659
+ parent,
3660
+ childEntries,
3661
+ focusedChildCuid,
3662
+ onFocusChild: handleFocusChild,
3663
+ onSelectParent: onSelectEntry
3664
+ }, undefined, false, undefined, this),
3665
+ /* @__PURE__ */ jsxDEV15("div", {
3127
3666
  style: {
3128
3667
  flex: 1,
3129
3668
  overflowY: "auto",
@@ -3134,211 +3673,376 @@ function ActionDetailPanel({
3134
3673
  gap: "8px"
3135
3674
  },
3136
3675
  children: [
3137
- /* @__PURE__ */ jsxDEV12(CallStackSection, {
3138
- parent,
3139
- childEntries,
3140
- focusedChildCuid,
3141
- onFocusChild: handleFocusChild,
3142
- onSelectParent: onSelectEntry
3676
+ focusedEntry.input !== undefined ? /* @__PURE__ */ jsxDEV15(DetailSection, {
3677
+ label: "Input",
3678
+ value: focusedEntry.input
3679
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV15(DetailSection, {
3680
+ label: "Input",
3681
+ value: "No input required or given"
3682
+ }, undefined, false, undefined, this),
3683
+ focusedEntry.status === "success" && /* @__PURE__ */ jsxDEV15(DetailSection, {
3684
+ label: "Output",
3685
+ value: focusedEntry.output,
3686
+ color: DEVTOOL_COLOR_SEMANTIC_SUCCESS
3143
3687
  }, undefined, false, undefined, this),
3144
- /* @__PURE__ */ jsxDEV12(MetaSection, {
3688
+ (focusedEntry.status === "action-error" || focusedEntry.status === "failed" || focusedEntry.status === "aborted") && /* @__PURE__ */ jsxDEV15(ActionErrorDisplay, {
3145
3689
  entry: focusedEntry
3146
3690
  }, undefined, false, undefined, this),
3147
- /* @__PURE__ */ jsxDEV12(RoutingSection, {
3148
- entry: focusedEntry,
3149
- minHopCount: maxRoutingHops
3691
+ focusedEntry.progressUpdates.length > 0 && /* @__PURE__ */ jsxDEV15(DetailSection, {
3692
+ label: `Progress (${focusedEntry.progressUpdates.length})`,
3693
+ value: focusedEntry.progressUpdates
3150
3694
  }, undefined, false, undefined, this),
3151
- /* @__PURE__ */ jsxDEV12(StackTraceSection, {
3695
+ /* @__PURE__ */ jsxDEV15(StackTraceSection, {
3152
3696
  label: "Dispatch Site",
3153
3697
  stack: focusedEntry.callSite,
3154
- color: "#94a3b8"
3155
- }, undefined, false, undefined, this),
3156
- /* @__PURE__ */ jsxDEV12(DetailSection, {
3157
- label: "Input",
3158
- value: focusedEntry.input
3698
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
3699
+ minFrameCount: maxCallSiteFrames
3159
3700
  }, undefined, false, undefined, this),
3160
- focusedEntry.status === "success" && /* @__PURE__ */ jsxDEV12(DetailSection, {
3161
- label: "Output",
3162
- value: focusedEntry.output,
3163
- color: "#4ade80"
3701
+ /* @__PURE__ */ jsxDEV15(RoutingSection, {
3702
+ entry: focusedEntry,
3703
+ minHopCount: maxRoutingHops
3164
3704
  }, undefined, false, undefined, this),
3165
- focusedEntry.status === "failed" && /* @__PURE__ */ jsxDEV12(Fragment4, {
3166
- children: [
3167
- /* @__PURE__ */ jsxDEV12(DetailSection, {
3168
- label: "Error",
3169
- value: focusedEntry.error,
3170
- color: "#f87171"
3171
- }, undefined, false, undefined, this),
3172
- /* @__PURE__ */ jsxDEV12(StackTraceSection, {
3173
- label: "Error Stack",
3174
- stack: focusedEntry.errorStack,
3175
- color: "#f87171"
3176
- }, undefined, false, undefined, this)
3177
- ]
3178
- }, undefined, true, undefined, this),
3179
- focusedEntry.status === "aborted" && /* @__PURE__ */ jsxDEV12(Fragment4, {
3705
+ /* @__PURE__ */ jsxDEV15(MetaSection, {
3706
+ entry: focusedEntry
3707
+ }, undefined, false, undefined, this)
3708
+ ]
3709
+ }, undefined, true, undefined, this)
3710
+ ]
3711
+ }, undefined, true, undefined, this);
3712
+ }
3713
+
3714
+ // src/devtools/browser/components/action_list/ActionEntryRow.tsx
3715
+ import { Box, CircleX as CircleX2, Variable } from "lucide-react";
3716
+ import { useState as useState8 } from "react";
3717
+
3718
+ // src/devtools/browser/components/Icon.tsx
3719
+ import { useState as useState7 } from "react";
3720
+ import { jsxDEV as jsxDEV16, Fragment as Fragment6 } from "react/jsx-dev-runtime";
3721
+ var ICON_SIZE_PX = {
3722
+ ["sm" /* sm */]: 13,
3723
+ ["md" /* md */]: 16,
3724
+ ["lg" /* lg */]: 18
3725
+ };
3726
+ function Icon({
3727
+ icon: IconComponent,
3728
+ color,
3729
+ size = "md" /* md */,
3730
+ subtle = false,
3731
+ tooltip,
3732
+ style
3733
+ }) {
3734
+ const [anchor, setAnchor] = useState7(null);
3735
+ const hasTooltip = tooltip != null;
3736
+ const colorEntry = SEMANTIC_COLORS[color];
3737
+ const resolvedColor = subtle ? colorEntry.subtle?.color ?? colorEntry.color : colorEntry.color;
3738
+ return /* @__PURE__ */ jsxDEV16(Fragment6, {
3739
+ children: [
3740
+ /* @__PURE__ */ jsxDEV16("div", {
3741
+ onMouseEnter: hasTooltip ? (e) => setAnchor(e.currentTarget.getBoundingClientRect()) : undefined,
3742
+ onMouseLeave: hasTooltip ? () => setAnchor(null) : undefined,
3743
+ style: {
3744
+ borderRadius: "0.4em",
3745
+ height: `${1.65 * getSizeValue(size)}em`,
3746
+ width: `${1.65 * getSizeValue(size)}em`,
3747
+ display: "flex",
3748
+ alignItems: "center",
3749
+ justifyContent: "center",
3750
+ background: "rgba(0,0,0,0.4)",
3751
+ color: resolvedColor,
3752
+ flexShrink: 0,
3753
+ cursor: hasTooltip ? "default" : undefined,
3754
+ ...style
3755
+ },
3756
+ children: /* @__PURE__ */ jsxDEV16(IconComponent, {
3757
+ size: ICON_SIZE_PX[size],
3758
+ strokeWidth: 1.5
3759
+ }, undefined, false, undefined, this)
3760
+ }, undefined, false, undefined, this),
3761
+ anchor != null && hasTooltip && /* @__PURE__ */ jsxDEV16(Tooltip, {
3762
+ anchor,
3763
+ config: tooltip
3764
+ }, undefined, false, undefined, this)
3765
+ ]
3766
+ }, undefined, true, undefined, this);
3767
+ }
3768
+
3769
+ // src/devtools/browser/components/action_list/ActionEntryRow.tsx
3770
+ import { jsxDEV as jsxDEV17, Fragment as Fragment7 } from "react/jsx-dev-runtime";
3771
+ function getLatestChipColor(status) {
3772
+ if (status === "failed")
3773
+ return "failed" /* failed */;
3774
+ if (status === "action-error")
3775
+ return "action_error" /* action_error */;
3776
+ if (status === "aborted")
3777
+ return "aborted" /* aborted */;
3778
+ return "running_action" /* running_action */;
3779
+ }
3780
+ var JSON_TOKEN_RE2 = /("(?:\\.|[^"\\])*")(\s*:)?|(-?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)|(\btrue\b|\bfalse\b|\bnull\b|\bundefined\b)|([{}[\],])/g;
3781
+ function renderColoredJson2(text) {
3782
+ const nodes = [];
3783
+ let last = 0;
3784
+ let i = 0;
3785
+ JSON_TOKEN_RE2.lastIndex = 0;
3786
+ for (let m = JSON_TOKEN_RE2.exec(text);m !== null; m = JSON_TOKEN_RE2.exec(text)) {
3787
+ if (m.index > last)
3788
+ nodes.push(text.slice(last, m.index));
3789
+ const [, str, colon, num, kw, punct] = m;
3790
+ if (str != null) {
3791
+ if (colon != null) {
3792
+ nodes.push(/* @__PURE__ */ jsxDEV17("span", {
3793
+ style: { color: DEVTOOL_JSON_KEY },
3794
+ children: str
3795
+ }, i++, false, undefined, this));
3796
+ nodes.push(/* @__PURE__ */ jsxDEV17("span", {
3797
+ style: { color: DEVTOOL_JSON_PUNCTUATION },
3798
+ children: colon
3799
+ }, i++, false, undefined, this));
3800
+ } else {
3801
+ nodes.push(/* @__PURE__ */ jsxDEV17("span", {
3802
+ style: { color: DEVTOOL_JSON_STRING },
3803
+ children: str
3804
+ }, i++, false, undefined, this));
3805
+ }
3806
+ } else if (num != null) {
3807
+ nodes.push(/* @__PURE__ */ jsxDEV17("span", {
3808
+ style: { color: DEVTOOL_JSON_NUMBER },
3809
+ children: num
3810
+ }, i++, false, undefined, this));
3811
+ } else if (kw != null) {
3812
+ nodes.push(/* @__PURE__ */ jsxDEV17("span", {
3813
+ style: { color: DEVTOOL_JSON_KEYWORD },
3814
+ children: kw
3815
+ }, i++, false, undefined, this));
3816
+ } else if (punct != null) {
3817
+ nodes.push(/* @__PURE__ */ jsxDEV17("span", {
3818
+ style: { color: DEVTOOL_JSON_PUNCTUATION },
3819
+ children: punct
3820
+ }, i++, false, undefined, this));
3821
+ }
3822
+ last = JSON_TOKEN_RE2.lastIndex;
3823
+ }
3824
+ if (last < text.length)
3825
+ nodes.push(text.slice(last));
3826
+ return nodes;
3827
+ }
3828
+ function stripOuterBraces(json) {
3829
+ const lines = json.split(`
3830
+ `);
3831
+ if (lines.length > 2 && lines[0] === "{" && lines[lines.length - 1] === "}") {
3832
+ return lines.slice(1, -1).map((l) => l.slice(2)).join(`
3833
+ `);
3834
+ }
3835
+ return json;
3836
+ }
3837
+ function IoTooltipContent({ value }) {
3838
+ const text = stripOuterBraces(safeStringify(value, 2));
3839
+ return /* @__PURE__ */ jsxDEV17("div", {
3840
+ style: {
3841
+ fontFamily: "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace",
3842
+ fontSize: "10px",
3843
+ whiteSpace: "pre-wrap",
3844
+ wordBreak: "break-all",
3845
+ lineHeight: "1.5",
3846
+ textAlign: "left"
3847
+ },
3848
+ children: renderColoredJson2(text)
3849
+ }, undefined, false, undefined, this);
3850
+ }
3851
+ function GroupDotTooltip({
3852
+ entry,
3853
+ index,
3854
+ total,
3855
+ refTime,
3856
+ dotColor,
3857
+ anchor
3858
+ }) {
3859
+ const symbol = STATUS_SYMBOL[entry.status];
3860
+ const deltaMs = refTime - entry.startTime;
3861
+ const relStr = index === 0 ? "latest run" : `−${formatRelativeAge(deltaMs)} from latest`;
3862
+ const durationStr = entry.endTime != null ? `${entry.endTime - entry.startTime}ms` : "running…";
3863
+ return /* @__PURE__ */ jsxDEV17(Tooltip, {
3864
+ anchor,
3865
+ config: {
3866
+ align: "center",
3867
+ maxWidth: 240,
3868
+ content: /* @__PURE__ */ jsxDEV17(Fragment7, {
3869
+ children: [
3870
+ /* @__PURE__ */ jsxDEV17("div", {
3871
+ style: { color: dotColor, marginBottom: "1px" },
3180
3872
  children: [
3181
- focusedEntry.abortReason != null && /* @__PURE__ */ jsxDEV12(DetailSection, {
3182
- label: "Abort Reason",
3183
- value: focusedEntry.abortReason,
3184
- color: "#9ca3af"
3185
- }, undefined, false, undefined, this),
3186
- /* @__PURE__ */ jsxDEV12(StackTraceSection, {
3187
- label: "Abort Stack",
3188
- stack: focusedEntry.errorStack,
3189
- color: "#9ca3af"
3190
- }, undefined, false, undefined, this)
3873
+ symbol,
3874
+ " run ",
3875
+ index + 1,
3876
+ " of ",
3877
+ total
3191
3878
  ]
3192
3879
  }, undefined, true, undefined, this),
3193
- focusedEntry.progressUpdates.length > 0 && /* @__PURE__ */ jsxDEV12(DetailSection, {
3194
- label: `Progress (${focusedEntry.progressUpdates.length})`,
3195
- value: focusedEntry.progressUpdates
3880
+ /* @__PURE__ */ jsxDEV17("div", {
3881
+ style: { color: DEVTOOL_COLOR_TEXT_SECONDARY },
3882
+ children: formatTimestamp(entry.startTime)
3883
+ }, undefined, false, undefined, this),
3884
+ /* @__PURE__ */ jsxDEV17("div", {
3885
+ style: { color: DEVTOOL_COLOR_TEXT_MUTED },
3886
+ children: durationStr
3887
+ }, undefined, false, undefined, this),
3888
+ index > 0 && /* @__PURE__ */ jsxDEV17("div", {
3889
+ style: {
3890
+ color: DEVTOOL_COLOR_TEXT_MUTED,
3891
+ marginTop: "3px",
3892
+ paddingTop: "3px",
3893
+ borderTop: `1px solid ${DEVTOOL_SECTION_BACKGROUND}`
3894
+ },
3895
+ children: relStr
3196
3896
  }, undefined, false, undefined, this)
3197
3897
  ]
3198
3898
  }, undefined, true, undefined, this)
3899
+ }
3900
+ }, undefined, false, undefined, this);
3901
+ }
3902
+ function GroupDot({
3903
+ entry,
3904
+ index,
3905
+ total,
3906
+ refTime,
3907
+ isActive,
3908
+ onSelect
3909
+ }) {
3910
+ const [anchor, setAnchor] = useState8(null);
3911
+ const dotColor = STATUS_COLOR[entry.status];
3912
+ const hovered = anchor != null;
3913
+ return /* @__PURE__ */ jsxDEV17(Fragment7, {
3914
+ children: [
3915
+ /* @__PURE__ */ jsxDEV17("button", {
3916
+ "data-cuid": entry.cuid,
3917
+ onClick: (e) => {
3918
+ e.stopPropagation();
3919
+ onSelect();
3920
+ },
3921
+ onMouseEnter: (e) => setAnchor(e.currentTarget.getBoundingClientRect()),
3922
+ onMouseLeave: () => setAnchor(null),
3923
+ style: {
3924
+ width: "9px",
3925
+ height: "9px",
3926
+ borderRadius: "50%",
3927
+ border: isActive ? `2px solid ${dotColor}` : hovered ? `1px solid ${dotColor}99` : "1px solid transparent",
3928
+ background: isActive ? "transparent" : dotColor,
3929
+ cursor: "pointer",
3930
+ padding: 0,
3931
+ flexShrink: 0,
3932
+ opacity: isActive ? 1 : hovered ? 0.8 : 0.35,
3933
+ transform: hovered ? "scale(1.55)" : "scale(1)",
3934
+ transition: "transform 0.1s ease, opacity 0.1s ease, border-color 0.1s ease"
3935
+ }
3936
+ }, undefined, false, undefined, this),
3937
+ hovered && anchor != null && /* @__PURE__ */ jsxDEV17(GroupDotTooltip, {
3938
+ entry,
3939
+ index,
3940
+ total,
3941
+ refTime,
3942
+ dotColor,
3943
+ anchor
3944
+ }, undefined, false, undefined, this)
3199
3945
  ]
3200
3946
  }, undefined, true, undefined, this);
3201
3947
  }
3202
-
3203
- // src/devtools/browser/components/ActionEntryRow.tsx
3204
- import { jsxDEV as jsxDEV13 } from "react/jsx-dev-runtime";
3205
3948
  function ActionEntryRow({
3206
3949
  entry,
3207
3950
  isSelected,
3208
3951
  onClick,
3209
- groupCount,
3210
- isSubEntry = false,
3211
3952
  isLatest = false,
3212
3953
  latestTime,
3213
- childExternalLabels
3954
+ childExternalRouteEntries,
3955
+ breakReasons,
3956
+ groupEntries,
3957
+ selectedGroupCuid,
3958
+ onSelectGroupEntry
3214
3959
  }) {
3215
- const color = STATUS_COLOR[entry.status];
3216
- const symbol = STATUS_SYMBOL[entry.status];
3960
+ const statusSemantic = STATUS_THING[entry.status];
3961
+ const statusIcon = STATUS_ICON[entry.status];
3217
3962
  const timestamp = formatTimestamp(entry.startTime);
3218
- if (isSubEntry) {
3219
- return /* @__PURE__ */ jsxDEV13("div", {
3220
- "data-cuid": entry.cuid,
3221
- onClick,
3222
- style: {
3223
- display: "flex",
3224
- alignItems: "center",
3225
- gap: "1em",
3226
- padding: "4px 10px 4px 26px",
3227
- cursor: "pointer",
3228
- background: isSelected ? "#131f35" : "#070d18",
3229
- borderBottom: "1px solid #0f172a",
3230
- borderLeft: isSelected ? "2px solid #3b82f6" : "2px solid transparent"
3231
- },
3232
- children: [
3233
- /* @__PURE__ */ jsxDEV13("span", {
3234
- style: { color: "#334155", fontSize: "10px", flexShrink: 0 },
3235
- children: symbol
3236
- }, undefined, false, undefined, this),
3237
- /* @__PURE__ */ jsxDEV13(DomainChip, {
3238
- subtle: true,
3239
- domain: entry.domain,
3240
- allDomains: entry.allDomains,
3241
- size: "sm"
3242
- }, undefined, false, undefined, this),
3243
- /* @__PURE__ */ jsxDEV13("span", {
3244
- children: [
3245
- /* @__PURE__ */ jsxDEV13("span", {
3246
- style: { color: isSelected ? "#818cf8" : "#3730a3", opacity: 0.5, fontSize: "10px" },
3247
- children: "⚡"
3248
- }, undefined, false, undefined, this),
3249
- /* @__PURE__ */ jsxDEV13("span", {
3250
- style: {
3251
- flex: 1,
3252
- color: "#475569",
3253
- fontSize: "11px",
3254
- overflow: "hidden",
3255
- textOverflow: "ellipsis",
3256
- whiteSpace: "nowrap",
3257
- minWidth: 0
3258
- },
3259
- children: entry.actionId
3260
- }, undefined, false, undefined, this)
3261
- ]
3262
- }, undefined, true, undefined, this),
3263
- /* @__PURE__ */ jsxDEV13("span", {
3264
- style: { color: "#334155", fontSize: "11px", flexShrink: 0 },
3265
- children: /* @__PURE__ */ jsxDEV13(DurationDisplay, {
3266
- entry
3267
- }, undefined, false, undefined, this)
3268
- }, undefined, false, undefined, this)
3269
- ]
3270
- }, undefined, true, undefined, this);
3271
- }
3272
- return /* @__PURE__ */ jsxDEV13("div", {
3963
+ const hasGroup = groupEntries != null && groupEntries.length > 1;
3964
+ return /* @__PURE__ */ jsxDEV17("div", {
3273
3965
  "data-cuid": entry.cuid,
3274
3966
  onClick,
3275
3967
  style: {
3968
+ position: "relative",
3276
3969
  display: "flex",
3277
3970
  alignItems: "flex-start",
3278
3971
  gap: "8px",
3279
- padding: isSelected ? "6px 12px 6px 10px" : "6px 12px",
3972
+ padding: "10px 12px",
3280
3973
  cursor: "pointer",
3281
- background: isSelected ? "#131f35" : "transparent",
3282
- borderBottom: "1px solid #0f172a",
3283
- borderLeft: isSelected ? "2px solid #60a5fa" : "2px solid transparent"
3974
+ background: isSelected ? DEVTOOL_DETAIL_HEADER_BACKGROUND : "transparent",
3975
+ border: `1px solid ${DEVTOOL_PANEL_BORDER}`,
3976
+ borderLeft: isSelected ? `2px solid ${STATUS_COLOR[entry.status]}` : entry.status === "failed" || entry.status === "action-error" ? `2px solid ${STATUS_COLOR[entry.status]}55` : `2px solid transparent`,
3977
+ borderRadius: "3px",
3978
+ margin: "2px 4px"
3284
3979
  },
3285
3980
  children: [
3286
- /* @__PURE__ */ jsxDEV13("span", {
3981
+ /* @__PURE__ */ jsxDEV17("div", {
3982
+ style: {
3983
+ position: "absolute",
3984
+ left: "32px",
3985
+ top: 0,
3986
+ bottom: 0,
3987
+ width: "1px",
3988
+ background: `${DEVTOOL_COLOR_SEMANTIC_METADATA}28`,
3989
+ pointerEvents: "none",
3990
+ zIndex: 0
3991
+ }
3992
+ }, undefined, false, undefined, this),
3993
+ /* @__PURE__ */ jsxDEV17("div", {
3287
3994
  style: {
3995
+ position: "relative",
3996
+ zIndex: 1,
3288
3997
  flexShrink: 0,
3289
3998
  minWidth: "3.5em",
3290
3999
  display: "flex",
3291
4000
  alignItems: "center",
3292
- justifyContent: "start"
4001
+ justifyContent: "flex-start"
3293
4002
  },
3294
- children: isLatest ? /* @__PURE__ */ jsxDEV13(Chip, {
3295
- color: "#60a5fa",
3296
- borderColor: "#1e3a5f",
4003
+ children: isLatest ? /* @__PURE__ */ jsxDEV17(Chip, {
4004
+ color: getLatestChipColor(entry.status),
3297
4005
  children: "latest"
3298
- }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV13(Chip, {
3299
- color: "#475569",
3300
- borderColor: "#1e293b",
4006
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV17(Chip, {
4007
+ color: "age" /* age */,
3301
4008
  children: [
3302
4009
  "+",
3303
4010
  latestTime != null ? formatRelativeAge(latestTime - entry.startTime) : "?"
3304
4011
  ]
3305
4012
  }, undefined, true, undefined, this)
3306
4013
  }, undefined, false, undefined, this),
3307
- /* @__PURE__ */ jsxDEV13("span", {
4014
+ /* @__PURE__ */ jsxDEV17("span", {
3308
4015
  style: {
3309
- color,
3310
- fontSize: "10px",
4016
+ position: "relative",
4017
+ zIndex: 1,
4018
+ color: statusSemantic,
3311
4019
  flexShrink: 0,
3312
- paddingTop: "2px",
4020
+ display: "flex",
4021
+ alignItems: "center",
3313
4022
  animation: entry.status === "running" ? "__nice-action-pulse 1.2s ease-in-out infinite" : undefined
3314
4023
  },
3315
- children: symbol
4024
+ children: /* @__PURE__ */ jsxDEV17(Icon, {
4025
+ icon: statusIcon,
4026
+ color: statusSemantic
4027
+ }, undefined, false, undefined, this)
3316
4028
  }, undefined, false, undefined, this),
3317
- /* @__PURE__ */ jsxDEV13("div", {
3318
- style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "3px" },
4029
+ /* @__PURE__ */ jsxDEV17("div", {
4030
+ style: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", gap: "0.3em" },
3319
4031
  children: [
3320
- /* @__PURE__ */ jsxDEV13("div", {
4032
+ /* @__PURE__ */ jsxDEV17("div", {
3321
4033
  style: {
3322
4034
  display: "flex",
3323
4035
  alignItems: "center",
3324
4036
  minWidth: 0,
3325
4037
  overflow: "hidden",
3326
- gap: "0.3em"
4038
+ gap: "0.5em"
3327
4039
  },
3328
4040
  children: [
3329
- /* @__PURE__ */ jsxDEV13(DomainChip, {
3330
- domain: entry.domain,
3331
- allDomains: entry.allDomains,
3332
- size: "md"
3333
- }, undefined, false, undefined, this),
3334
- /* @__PURE__ */ jsxDEV13("span", {
3335
- style: { color: isSelected ? "#818cf8" : "#3730a3", fontSize: "1em" },
3336
- children: "⚡"
3337
- }, undefined, false, undefined, this),
3338
- /* @__PURE__ */ jsxDEV13("span", {
4041
+ /* @__PURE__ */ jsxDEV17("span", {
3339
4042
  style: {
3340
- color: "#cbd5e1",
4043
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
3341
4044
  fontSize: "11px",
4045
+ fontFamily: "ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace",
3342
4046
  overflow: "hidden",
3343
4047
  textOverflow: "ellipsis",
3344
4048
  whiteSpace: "nowrap",
@@ -3346,10 +4050,46 @@ function ActionEntryRow({
3346
4050
  minWidth: "24px"
3347
4051
  },
3348
4052
  children: entry.actionId
4053
+ }, undefined, false, undefined, this),
4054
+ /* @__PURE__ */ jsxDEV17(DomainChip, {
4055
+ domain: entry.domain,
4056
+ allDomains: entry.allDomains
4057
+ }, undefined, false, undefined, this),
4058
+ entry.input !== undefined && /* @__PURE__ */ jsxDEV17(Icon, {
4059
+ icon: Variable,
4060
+ color: "io_input" /* io_input */,
4061
+ tooltip: { content: /* @__PURE__ */ jsxDEV17(IoTooltipContent, {
4062
+ value: entry.input
4063
+ }, undefined, false, undefined, this), title: "Input" }
4064
+ }, undefined, false, undefined, this),
4065
+ entry.status === "success" && entry.output !== undefined && /* @__PURE__ */ jsxDEV17(Icon, {
4066
+ icon: Box,
4067
+ color: "io_output" /* io_output */,
4068
+ tooltip: { content: /* @__PURE__ */ jsxDEV17(IoTooltipContent, {
4069
+ value: entry.output
4070
+ }, undefined, false, undefined, this), title: "Output" }
4071
+ }, undefined, false, undefined, this),
4072
+ (entry.error != null || entry.abortReason != null) && /* @__PURE__ */ jsxDEV17(Icon, {
4073
+ icon: CircleX2,
4074
+ color: entry.status === "aborted" ? "aborted" /* aborted */ : "error" /* error */,
4075
+ tooltip: {
4076
+ content: /* @__PURE__ */ jsxDEV17("div", {
4077
+ style: {
4078
+ display: "flex",
4079
+ flexDirection: "column",
4080
+ gap: "1em"
4081
+ },
4082
+ children: /* @__PURE__ */ jsxDEV17(ActionErrorDisplay, {
4083
+ entry
4084
+ }, undefined, false, undefined, this)
4085
+ }, undefined, false, undefined, this),
4086
+ title: entry.status === "aborted" ? "Aborted" : "Error",
4087
+ maxWidth: 400
4088
+ }
3349
4089
  }, undefined, false, undefined, this)
3350
4090
  ]
3351
4091
  }, undefined, true, undefined, this),
3352
- /* @__PURE__ */ jsxDEV13("div", {
4092
+ /* @__PURE__ */ jsxDEV17("div", {
3353
4093
  style: {
3354
4094
  display: "flex",
3355
4095
  alignItems: "center",
@@ -3357,53 +4097,70 @@ function ActionEntryRow({
3357
4097
  gap: "6px"
3358
4098
  },
3359
4099
  children: [
3360
- /* @__PURE__ */ jsxDEV13("div", {
4100
+ /* @__PURE__ */ jsxDEV17("div", {
3361
4101
  style: {
3362
4102
  display: "flex",
3363
4103
  flexDirection: "row",
3364
- alignItems: "center",
4104
+ alignItems: "start",
3365
4105
  gap: "5px",
3366
4106
  minWidth: 0,
3367
4107
  overflow: "hidden"
3368
4108
  },
3369
4109
  children: [
3370
- /* @__PURE__ */ jsxDEV13(HandlerChips, {
4110
+ /* @__PURE__ */ jsxDEV17(HandlerChips, {
3371
4111
  entry,
3372
- size: "sm"
4112
+ size: "sm" /* sm */
3373
4113
  }, undefined, false, undefined, this),
3374
- /* @__PURE__ */ jsxDEV13(ChildDispatchChips, {
3375
- labels: childExternalLabels,
3376
- size: "sm"
3377
- }, undefined, false, undefined, this)
4114
+ /* @__PURE__ */ jsxDEV17(ChildDispatchChips, {
4115
+ childRouteItems: childExternalRouteEntries,
4116
+ size: "sm" /* sm */
4117
+ }, undefined, false, undefined, this),
4118
+ breakReasons?.filter((r) => r !== "new input" && r !== "new output").map((reason) => /* @__PURE__ */ jsxDEV17(Chip, {
4119
+ color: "default" /* default */,
4120
+ children: reason
4121
+ }, reason, false, undefined, this))
3378
4122
  ]
3379
4123
  }, undefined, true, undefined, this),
3380
- /* @__PURE__ */ jsxDEV13("div", {
4124
+ /* @__PURE__ */ jsxDEV17("div", {
3381
4125
  style: { display: "flex", alignItems: "center", gap: "6px", flexShrink: 0 },
3382
4126
  children: [
3383
- groupCount != null && /* @__PURE__ */ jsxDEV13(Chip, {
3384
- color: "#3b82f6",
3385
- borderColor: "#1e3a5f",
3386
- fontSize: "9px",
3387
- padding: "1px 5px",
3388
- children: [
3389
- "x",
3390
- groupCount
3391
- ]
3392
- }, undefined, true, undefined, this),
3393
- /* @__PURE__ */ jsxDEV13("span", {
3394
- style: { color: "#1e3a5f", fontSize: "10px", letterSpacing: "0.02em" },
4127
+ /* @__PURE__ */ jsxDEV17("span", {
4128
+ style: {
4129
+ color: DEVTOOL_COLOR_SEMANTIC_METADATA,
4130
+ fontSize: "10px",
4131
+ letterSpacing: "0.02em",
4132
+ fontFamily: "ui-sans-serif, system-ui, sans-serif"
4133
+ },
3395
4134
  children: timestamp
3396
4135
  }, undefined, false, undefined, this),
3397
- /* @__PURE__ */ jsxDEV13("span", {
3398
- style: { color: "#475569", fontSize: "11px" },
3399
- children: /* @__PURE__ */ jsxDEV13(DurationDisplay, {
4136
+ /* @__PURE__ */ jsxDEV17("span", {
4137
+ style: { color: DEVTOOL_COLOR_SEMANTIC_WARNING, fontSize: "11px" },
4138
+ children: /* @__PURE__ */ jsxDEV17(DurationDisplay, {
3400
4139
  entry
3401
4140
  }, undefined, false, undefined, this)
3402
4141
  }, undefined, false, undefined, this)
3403
4142
  ]
3404
4143
  }, undefined, true, undefined, this)
3405
4144
  ]
3406
- }, undefined, true, undefined, this)
4145
+ }, undefined, true, undefined, this),
4146
+ hasGroup && /* @__PURE__ */ jsxDEV17("div", {
4147
+ style: {
4148
+ display: "flex",
4149
+ flexWrap: "wrap",
4150
+ alignItems: "center",
4151
+ gap: "5px",
4152
+ paddingBottom: "3px",
4153
+ paddingTop: "1px"
4154
+ },
4155
+ children: groupEntries.map((e, i) => /* @__PURE__ */ jsxDEV17(GroupDot, {
4156
+ entry: e,
4157
+ index: i,
4158
+ total: groupEntries.length,
4159
+ refTime: groupEntries[0].startTime,
4160
+ isActive: selectedGroupCuid === e.cuid,
4161
+ onSelect: () => onSelectGroupEntry?.(e.cuid)
4162
+ }, e.cuid, false, undefined, this))
4163
+ }, undefined, false, undefined, this)
3407
4164
  ]
3408
4165
  }, undefined, true, undefined, this)
3409
4166
  ]
@@ -3411,7 +4168,7 @@ function ActionEntryRow({
3411
4168
  }
3412
4169
 
3413
4170
  // src/devtools/browser/components/PanelChrome.tsx
3414
- import { jsxDEV as jsxDEV14 } from "react/jsx-dev-runtime";
4171
+ import { jsxDEV as jsxDEV18 } from "react/jsx-dev-runtime";
3415
4172
  var DOCKED_SIZE_MIN = 140;
3416
4173
  var POSITION_GRID = [
3417
4174
  ["top-left", "dock-top", "top-right"],
@@ -3435,46 +4192,46 @@ function PanelHeader({
3435
4192
  onClose,
3436
4193
  onClear
3437
4194
  }) {
3438
- return /* @__PURE__ */ jsxDEV14("div", {
4195
+ return /* @__PURE__ */ jsxDEV18("div", {
3439
4196
  style: {
3440
4197
  display: "flex",
3441
4198
  alignItems: "center",
3442
4199
  justifyContent: "space-between",
3443
4200
  padding: "8px 12px",
3444
- background: "#1e293b",
3445
- borderBottom: "1px solid #0f172a",
4201
+ background: DEVTOOL_SECTION_BACKGROUND,
4202
+ borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,
3446
4203
  flexShrink: 0
3447
4204
  },
3448
4205
  children: [
3449
- /* @__PURE__ */ jsxDEV14("span", {
3450
- style: { color: "#60a5fa", fontWeight: "bold", fontSize: "11px" },
4206
+ /* @__PURE__ */ jsxDEV18("span", {
4207
+ style: { color: DEVTOOL_COLOR_SEMANTIC_SYSTEM, fontWeight: "bold", fontSize: "11px" },
3451
4208
  children: "⚡ nice-action devtools"
3452
4209
  }, undefined, false, undefined, this),
3453
- /* @__PURE__ */ jsxDEV14("div", {
4210
+ /* @__PURE__ */ jsxDEV18("div", {
3454
4211
  style: { display: "flex", gap: "10px", alignItems: "center" },
3455
4212
  children: [
3456
- /* @__PURE__ */ jsxDEV14(PositionPicker, {
4213
+ /* @__PURE__ */ jsxDEV18(PositionPicker, {
3457
4214
  position,
3458
4215
  onChange: onPositionChange
3459
4216
  }, undefined, false, undefined, this),
3460
- onClear != null && /* @__PURE__ */ jsxDEV14("button", {
4217
+ onClear != null && /* @__PURE__ */ jsxDEV18("button", {
3461
4218
  onClick: onClear,
3462
4219
  style: {
3463
4220
  background: "none",
3464
4221
  border: "none",
3465
- color: "#475569",
4222
+ color: DEVTOOL_COLOR_TEXT_MUTED,
3466
4223
  cursor: "pointer",
3467
4224
  fontSize: "11px",
3468
4225
  padding: "0"
3469
4226
  },
3470
4227
  children: "clear"
3471
4228
  }, undefined, false, undefined, this),
3472
- /* @__PURE__ */ jsxDEV14("button", {
4229
+ /* @__PURE__ */ jsxDEV18("button", {
3473
4230
  onClick: onClose,
3474
4231
  style: {
3475
4232
  background: "none",
3476
4233
  border: "none",
3477
- color: "#475569",
4234
+ color: DEVTOOL_COLOR_TEXT_MUTED,
3478
4235
  cursor: "pointer",
3479
4236
  fontSize: "16px",
3480
4237
  padding: "0",
@@ -3491,18 +4248,18 @@ function PositionPicker({
3491
4248
  position,
3492
4249
  onChange
3493
4250
  }) {
3494
- return /* @__PURE__ */ jsxDEV14("div", {
4251
+ return /* @__PURE__ */ jsxDEV18("div", {
3495
4252
  title: "Move / dock panel",
3496
4253
  style: { display: "grid", gridTemplateColumns: "repeat(3, 9px)", gap: "2px", padding: "2px" },
3497
4254
  children: POSITION_GRID.flat().map((pos) => {
3498
4255
  if (pos == null)
3499
- return /* @__PURE__ */ jsxDEV14("div", {
4256
+ return /* @__PURE__ */ jsxDEV18("div", {
3500
4257
  style: { width: "9px", height: "9px" }
3501
4258
  }, "center-empty", false, undefined, this);
3502
4259
  const isDock = pos.startsWith("dock-");
3503
4260
  const isTopBottom = pos === "dock-top" || pos === "dock-bottom";
3504
4261
  const isActive = pos === position;
3505
- return /* @__PURE__ */ jsxDEV14("div", {
4262
+ return /* @__PURE__ */ jsxDEV18("div", {
3506
4263
  title: pos,
3507
4264
  onClick: () => onChange(pos),
3508
4265
  style: {
@@ -3513,12 +4270,12 @@ function PositionPicker({
3513
4270
  justifyContent: "center",
3514
4271
  cursor: "pointer"
3515
4272
  },
3516
- children: /* @__PURE__ */ jsxDEV14("div", {
4273
+ children: /* @__PURE__ */ jsxDEV18("div", {
3517
4274
  style: {
3518
4275
  width: isDock ? isTopBottom ? "9px" : "3px" : "7px",
3519
4276
  height: isDock ? isTopBottom ? "3px" : "9px" : "7px",
3520
4277
  borderRadius: isDock ? "1px" : "50%",
3521
- background: isActive ? "#60a5fa" : "#334155"
4278
+ background: isActive ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT
3522
4279
  }
3523
4280
  }, undefined, false, undefined, this)
3524
4281
  }, pos, false, undefined, this);
@@ -3549,7 +4306,7 @@ function ResizeHandle({
3549
4306
  window.addEventListener("mouseup", onUp);
3550
4307
  };
3551
4308
  const edgeStyle = dockSide === "bottom" ? { top: 0, left: 0, right: 0, height: "5px", cursor: "ns-resize" } : dockSide === "top" ? { bottom: 0, left: 0, right: 0, height: "5px", cursor: "ns-resize" } : dockSide === "right" ? { top: 0, bottom: 0, left: 0, width: "5px", cursor: "ew-resize" } : { top: 0, bottom: 0, right: 0, width: "5px", cursor: "ew-resize" };
3552
- return /* @__PURE__ */ jsxDEV14("div", {
4309
+ return /* @__PURE__ */ jsxDEV18("div", {
3553
4310
  onMouseDown,
3554
4311
  style: {
3555
4312
  position: "absolute",
@@ -3561,7 +4318,7 @@ function ResizeHandle({
3561
4318
  }
3562
4319
 
3563
4320
  // src/devtools/browser/NiceActionDevtools.tsx
3564
- import { jsxDEV as jsxDEV15, Fragment as Fragment5 } from "react/jsx-dev-runtime";
4321
+ import { jsxDEV as jsxDEV19, Fragment as Fragment8 } from "react/jsx-dev-runtime";
3565
4322
  if (typeof document !== "undefined" && !document.getElementById("__nice-action-devtools-styles")) {
3566
4323
  const style = document.createElement("style");
3567
4324
  style.id = "__nice-action-devtools-styles";
@@ -3576,6 +4333,23 @@ if (typeof document !== "undefined" && !document.getElementById("__nice-action-d
3576
4333
  85% { opacity: 1; }
3577
4334
  100% { transform: translateX(200%); opacity: 0; }
3578
4335
  }
4336
+ #__nice-action-devtools-panel ::-webkit-scrollbar {
4337
+ width: 4px;
4338
+ height: 4px;
4339
+ }
4340
+ #__nice-action-devtools-panel ::-webkit-scrollbar-track {
4341
+ background: transparent;
4342
+ }
4343
+ #__nice-action-devtools-panel ::-webkit-scrollbar-thumb {
4344
+ background: #334155;
4345
+ border-radius: 2px;
4346
+ }
4347
+ #__nice-action-devtools-panel ::-webkit-scrollbar-thumb:hover {
4348
+ background: #475569;
4349
+ }
4350
+ #__nice-action-devtools-panel ::-webkit-scrollbar-corner {
4351
+ background: transparent;
4352
+ }
3579
4353
  `;
3580
4354
  document.head?.appendChild(style);
3581
4355
  }
@@ -3619,7 +4393,9 @@ function canGroupWith(a, b) {
3619
4393
  const handlerA = getHandlerKey(a);
3620
4394
  const handlerB = getHandlerKey(b);
3621
4395
  const handlerConflict = handlerA !== "none" && handlerB !== "none" && handlerA !== handlerB;
3622
- return a.actionId === b.actionId && a.domain === b.domain && a.status === b.status && !handlerConflict && safeStringify(a.input, 0) === safeStringify(b.input, 0);
4396
+ const inputMatch = a.inputHash != null && b.inputHash != null ? a.inputHash === b.inputHash : safeStringify(a.input, 0) === safeStringify(b.input, 0);
4397
+ const outputMatch = a.outputHash != null && b.outputHash != null ? a.outputHash === b.outputHash : true;
4398
+ return a.actionId === b.actionId && a.domain === b.domain && a.status === b.status && !handlerConflict && inputMatch && outputMatch;
3623
4399
  }
3624
4400
  function groupEntries(entries) {
3625
4401
  const groups = [];
@@ -3635,7 +4411,7 @@ function groupEntries(entries) {
3635
4411
  }
3636
4412
  function NiceActionDevtools(props) {
3637
4413
  if (false) {}
3638
- return /* @__PURE__ */ jsxDEV15(NiceActionDevtools_Panel, {
4414
+ return /* @__PURE__ */ jsxDEV19(NiceActionDevtools_Panel, {
3639
4415
  ...props
3640
4416
  }, undefined, false, undefined, this);
3641
4417
  }
@@ -3644,34 +4420,28 @@ function NiceActionDevtools_Panel({
3644
4420
  position: defaultPosition = "bottom-right",
3645
4421
  initialOpen = false
3646
4422
  }) {
3647
- const [prefs, setPrefsRaw] = useState6(() => readPrefs(defaultPosition, initialOpen));
3648
- const [entries, setEntries] = useState6([]);
3649
- const [selectedCuid, setSelectedCuid] = useState6(null);
3650
- const [expandedGroupCuids, setExpandedGroupCuids] = useState6(new Set);
3651
- const [domainTooltip, setDomainTooltip] = useState6(null);
3652
- const showDomainTooltip = useCallback((rect, allDomains) => setDomainTooltip({ rect, allDomains }), []);
3653
- const hideDomainTooltip = useCallback(() => setDomainTooltip(null), []);
3654
- const domainTooltipCtx = useMemo2(() => ({ show: showDomainTooltip, hide: hideDomainTooltip }), [showDomainTooltip, hideDomainTooltip]);
4423
+ const [prefs, setPrefsRaw] = useState9(() => readPrefs(defaultPosition, initialOpen));
4424
+ const [entries, setEntries] = useState9([]);
4425
+ const [selectedCuid, setSelectedCuid] = useState9(null);
3655
4426
  useEffect3(() => core.subscribe(setEntries), [core]);
3656
4427
  const groups = useMemo2(() => {
3657
4428
  const byCuid = new Map(entries.map((e) => [e.cuid, e]));
3658
4429
  const roots = entries.filter((e) => e.status !== "running" && (e.parentCuid == null || !byCuid.has(e.parentCuid)));
3659
4430
  return groupEntries(roots);
3660
4431
  }, [entries]);
3661
- const childExternalLabelsMap = useMemo2(() => {
4432
+ const childExternalRouteItemsMap = useMemo2(() => {
3662
4433
  const map = new Map;
3663
4434
  for (const entry of entries) {
3664
4435
  if (entry.parentCuid == null)
3665
4436
  continue;
3666
4437
  const firstHop = entry.meta.routing[0];
3667
- if (firstHop == null)
3668
- continue;
3669
- const label = getExternalLabel(firstHop);
3670
- if (label == null)
4438
+ if (firstHop == null || firstHop.handlerType !== "external")
3671
4439
  continue;
3672
4440
  const existing = map.get(entry.parentCuid) ?? [];
3673
- if (!existing.includes(label))
3674
- map.set(entry.parentCuid, [...existing, label]);
4441
+ const key = `${firstHop.handlerClient?.envId ?? ""}:${firstHop.transport ?? ""}`;
4442
+ if (!existing.some((r) => `${r.handlerClient?.envId ?? ""}:${r.transport ?? ""}` === key)) {
4443
+ map.set(entry.parentCuid, [...existing, firstHop]);
4444
+ }
3675
4445
  }
3676
4446
  return map;
3677
4447
  }, [entries]);
@@ -3679,18 +4449,12 @@ function NiceActionDevtools_Panel({
3679
4449
  const repCuid = group.representative.cuid;
3680
4450
  const allInGroup = [group.representative, ...group.rest];
3681
4451
  const selectedInGroup = allInGroup.find((e) => e.cuid === selectedCuid) ?? null;
3682
- setExpandedGroupCuids(new Set);
3683
4452
  if (selectedInGroup != null && selectedCuid !== repCuid) {
3684
4453
  setSelectedCuid(repCuid);
3685
4454
  } else {
3686
4455
  setSelectedCuid(selectedCuid === repCuid ? null : repCuid);
3687
4456
  }
3688
4457
  };
3689
- const handleExpandGroup = (group) => {
3690
- const oldestCuid = (group.rest[group.rest.length - 1] ?? group.representative).cuid;
3691
- setSelectedCuid(null);
3692
- setExpandedGroupCuids(new Set([oldestCuid]));
3693
- };
3694
4458
  const setPrefs = (update) => {
3695
4459
  setPrefsRaw((prev) => {
3696
4460
  const next = { ...prev, ...update };
@@ -3743,14 +4507,14 @@ function NiceActionDevtools_Panel({
3743
4507
  fontSize: "12px"
3744
4508
  };
3745
4509
  if (!isOpen) {
3746
- return /* @__PURE__ */ jsxDEV15("button", {
4510
+ return /* @__PURE__ */ jsxDEV19("button", {
3747
4511
  onClick: () => setPrefs({ isOpen: true }),
3748
4512
  style: {
3749
4513
  ...baseStyle,
3750
4514
  ...closedAnchor,
3751
- background: "#1e293b",
3752
- color: "#94a3b8",
3753
- border: "1px solid #334155",
4515
+ background: DEVTOOL_SECTION_BACKGROUND,
4516
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
4517
+ border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,
3754
4518
  borderRadius: "6px",
3755
4519
  padding: "5px 10px",
3756
4520
  cursor: "pointer",
@@ -3758,10 +4522,10 @@ function NiceActionDevtools_Panel({
3758
4522
  },
3759
4523
  children: [
3760
4524
  "⚡ actions",
3761
- runningCount > 0 && /* @__PURE__ */ jsxDEV15("span", {
4525
+ runningCount > 0 && /* @__PURE__ */ jsxDEV19("span", {
3762
4526
  style: {
3763
4527
  marginLeft: "6px",
3764
- color: "#60a5fa",
4528
+ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,
3765
4529
  animation: "__nice-action-pulse 1.2s ease-in-out infinite"
3766
4530
  },
3767
4531
  children: [
@@ -3774,9 +4538,9 @@ function NiceActionDevtools_Panel({
3774
4538
  }
3775
4539
  const panelStyle = dockSide != null ? {
3776
4540
  ...baseStyle,
3777
- background: "#0f172a",
3778
- border: "1px solid #1e293b",
3779
- color: "#e2e8f0",
4541
+ background: DEVTOOL_LIST_BASE_BACKGROUND,
4542
+ border: `1px solid ${DEVTOOL_PANEL_BORDER}`,
4543
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
3780
4544
  display: "flex",
3781
4545
  flexDirection: "column",
3782
4546
  boxShadow: "0 -4px 24px rgba(0,0,0,0.4)",
@@ -3811,10 +4575,10 @@ function NiceActionDevtools_Panel({
3811
4575
  ...closedAnchor,
3812
4576
  width: "460px",
3813
4577
  maxHeight: "560px",
3814
- background: "#0f172a",
3815
- border: "1px solid #1e293b",
4578
+ background: DEVTOOL_LIST_BASE_BACKGROUND,
4579
+ border: `1px solid ${DEVTOOL_PANEL_BORDER}`,
3816
4580
  borderRadius: "10px",
3817
- color: "#e2e8f0",
4581
+ color: DEVTOOL_COLOR_TEXT_SECONDARY,
3818
4582
  display: "flex",
3819
4583
  flexDirection: "column",
3820
4584
  boxShadow: "0 25px 50px rgba(0,0,0,0.5)",
@@ -3825,179 +4589,197 @@ function NiceActionDevtools_Panel({
3825
4589
  const virtualListProps = {
3826
4590
  groups,
3827
4591
  selectedCuid,
3828
- expandedGroupCuids,
3829
4592
  onGroupClick: handleGroupRowClick,
3830
4593
  onSubClick: (cuid, isSelected) => {
3831
4594
  setSelectedCuid(isSelected ? null : cuid);
3832
- setExpandedGroupCuids(new Set);
3833
4595
  },
3834
- onExpandGroup: handleExpandGroup,
3835
- childExternalLabelsMap
4596
+ childExternalRouteItemsMap
3836
4597
  };
3837
- return /* @__PURE__ */ jsxDEV15(DomainTooltipCtx.Provider, {
3838
- value: domainTooltipCtx,
3839
- children: /* @__PURE__ */ jsxDEV15("div", {
3840
- style: panelStyle,
3841
- children: [
3842
- domainTooltip != null && /* @__PURE__ */ jsxDEV15(DomainHierarchyTooltip, {
3843
- anchor: domainTooltip.rect,
3844
- allDomains: domainTooltip.allDomains
3845
- }, undefined, false, undefined, this),
3846
- dockSide != null && /* @__PURE__ */ jsxDEV15(ResizeHandle, {
3847
- dockSide,
3848
- dockedSize,
3849
- onChange: (size) => setPrefs(isHorizDock ? { dockedHeight: size } : { dockedWidth: size })
3850
- }, undefined, false, undefined, this),
3851
- /* @__PURE__ */ jsxDEV15(PanelHeader, {
3852
- position,
3853
- onPositionChange: (p) => setPrefs({ position: p }),
3854
- onClose: () => setPrefs({ isOpen: false }),
3855
- onClear: entries.length > 0 ? () => {
3856
- core.clear();
3857
- setSelectedCuid(null);
3858
- setExpandedGroupCuids(new Set);
3859
- } : undefined
3860
- }, undefined, false, undefined, this),
3861
- isHorizDock ? /* @__PURE__ */ jsxDEV15("div", {
3862
- style: { flex: 1, display: "flex", overflow: "hidden" },
3863
- children: [
3864
- /* @__PURE__ */ jsxDEV15(ActionList, {
3865
- ...virtualListProps,
3866
- style: {
3867
- width: "340px",
3868
- flexShrink: 0,
3869
- overflowY: "auto",
3870
- borderRight: "1px solid #1e293b"
3871
- }
3872
- }, undefined, false, undefined, this),
3873
- /* @__PURE__ */ jsxDEV15("div", {
3874
- style: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" },
3875
- children: selectedEntry != null ? /* @__PURE__ */ jsxDEV15(ActionDetailPanel, {
3876
- entry: selectedEntry,
3877
- parent: selectedEntryParent,
3878
- childEntries: selectedEntryChildren,
3879
- onSelectEntry: (cuid) => setSelectedCuid(cuid)
3880
- }, selectedEntry.cuid, false, undefined, this) : /* @__PURE__ */ jsxDEV15("div", {
4598
+ return /* @__PURE__ */ jsxDEV19("div", {
4599
+ id: "__nice-action-devtools-panel",
4600
+ style: panelStyle,
4601
+ children: [
4602
+ dockSide != null && /* @__PURE__ */ jsxDEV19(ResizeHandle, {
4603
+ dockSide,
4604
+ dockedSize,
4605
+ onChange: (size) => setPrefs(isHorizDock ? { dockedHeight: size } : { dockedWidth: size })
4606
+ }, undefined, false, undefined, this),
4607
+ /* @__PURE__ */ jsxDEV19(PanelHeader, {
4608
+ position,
4609
+ onPositionChange: (p) => setPrefs({ position: p }),
4610
+ onClose: () => setPrefs({ isOpen: false }),
4611
+ onClear: entries.length > 0 ? () => {
4612
+ core.clear();
4613
+ setSelectedCuid(null);
4614
+ } : undefined
4615
+ }, undefined, false, undefined, this),
4616
+ isHorizDock ? /* @__PURE__ */ jsxDEV19("div", {
4617
+ style: { flex: 1, display: "flex", overflow: "hidden" },
4618
+ children: [
4619
+ /* @__PURE__ */ jsxDEV19("div", {
4620
+ style: { position: "relative", width: "340px", flexShrink: 0 },
4621
+ children: [
4622
+ /* @__PURE__ */ jsxDEV19(ActionList, {
4623
+ ...virtualListProps,
4624
+ style: { width: "100%", height: "100%", overflowY: "auto" }
4625
+ }, undefined, false, undefined, this),
4626
+ /* @__PURE__ */ jsxDEV19("div", {
3881
4627
  style: {
3882
- padding: "24px",
3883
- textAlign: "center",
3884
- color: "#475569",
3885
- fontSize: "11px"
3886
- },
3887
- children: "Select an action to inspect"
4628
+ position: "absolute",
4629
+ top: 0,
4630
+ right: 0,
4631
+ bottom: 0,
4632
+ width: "36px",
4633
+ pointerEvents: "none",
4634
+ background: `linear-gradient(to right, transparent, ${DEVTOOL_LIST_BASE_BACKGROUND} 88%)`
4635
+ }
3888
4636
  }, undefined, false, undefined, this)
3889
- }, undefined, false, undefined, this)
3890
- ]
3891
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV15(Fragment5, {
3892
- children: [
3893
- /* @__PURE__ */ jsxDEV15(ActionList, {
3894
- ...virtualListProps,
3895
- style: {
3896
- overflowY: "auto",
3897
- flex: 1,
3898
- minHeight: "80px",
3899
- borderBottom: selectedEntry != null ? "1px solid #1e293b" : "none"
3900
- }
3901
- }, undefined, false, undefined, this),
3902
- selectedEntry != null && /* @__PURE__ */ jsxDEV15("div", {
4637
+ ]
4638
+ }, undefined, true, undefined, this),
4639
+ /* @__PURE__ */ jsxDEV19("div", {
4640
+ style: {
4641
+ flex: 1,
4642
+ display: "flex",
4643
+ flexDirection: "column",
4644
+ overflow: "hidden",
4645
+ borderLeft: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`,
4646
+ boxShadow: "inset 18px 0 36px -14px rgba(0,0,0,0.8)"
4647
+ },
4648
+ children: selectedEntry != null ? /* @__PURE__ */ jsxDEV19(ActionDetailPanel, {
4649
+ entry: selectedEntry,
4650
+ parent: selectedEntryParent,
4651
+ childEntries: selectedEntryChildren,
4652
+ onSelectEntry: (cuid) => setSelectedCuid(cuid)
4653
+ }, selectedEntry.cuid, false, undefined, this) : /* @__PURE__ */ jsxDEV19("div", {
3903
4654
  style: {
3904
- flexShrink: 0,
3905
- maxHeight: "45%",
3906
- display: "flex",
3907
- flexDirection: "column",
3908
- overflow: "hidden"
4655
+ padding: "24px",
4656
+ textAlign: "center",
4657
+ color: DEVTOOL_COLOR_TEXT_MUTED,
4658
+ fontSize: "11px"
3909
4659
  },
3910
- children: /* @__PURE__ */ jsxDEV15(ActionDetailPanel, {
3911
- entry: selectedEntry,
3912
- parent: selectedEntryParent,
3913
- childEntries: selectedEntryChildren,
3914
- onSelectEntry: (cuid) => setSelectedCuid(cuid)
3915
- }, selectedEntry.cuid, false, undefined, this)
4660
+ children: "Select an action to inspect"
3916
4661
  }, undefined, false, undefined, this)
3917
- ]
3918
- }, undefined, true, undefined, this)
3919
- ]
3920
- }, undefined, true, undefined, this)
3921
- }, undefined, false, undefined, this);
4662
+ }, undefined, false, undefined, this)
4663
+ ]
4664
+ }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV19(Fragment8, {
4665
+ children: [
4666
+ /* @__PURE__ */ jsxDEV19("div", {
4667
+ style: { position: "relative", flex: 1, minHeight: "80px" },
4668
+ children: [
4669
+ /* @__PURE__ */ jsxDEV19(ActionList, {
4670
+ ...virtualListProps,
4671
+ style: { overflowY: "auto", height: "100%" }
4672
+ }, undefined, false, undefined, this),
4673
+ selectedEntry != null && /* @__PURE__ */ jsxDEV19("div", {
4674
+ style: {
4675
+ position: "absolute",
4676
+ bottom: 0,
4677
+ left: 0,
4678
+ right: 0,
4679
+ height: "36px",
4680
+ pointerEvents: "none",
4681
+ background: `linear-gradient(to bottom, transparent, ${DEVTOOL_LIST_BASE_BACKGROUND} 88%)`
4682
+ }
4683
+ }, undefined, false, undefined, this)
4684
+ ]
4685
+ }, undefined, true, undefined, this),
4686
+ selectedEntry != null && /* @__PURE__ */ jsxDEV19("div", {
4687
+ style: {
4688
+ flexShrink: 0,
4689
+ maxHeight: "55%",
4690
+ display: "flex",
4691
+ flexDirection: "column",
4692
+ overflow: "hidden",
4693
+ borderTop: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`,
4694
+ boxShadow: "inset 0 18px 36px -14px rgba(0,0,0,0.8)"
4695
+ },
4696
+ children: /* @__PURE__ */ jsxDEV19(ActionDetailPanel, {
4697
+ entry: selectedEntry,
4698
+ parent: selectedEntryParent,
4699
+ childEntries: selectedEntryChildren,
4700
+ onSelectEntry: (cuid) => setSelectedCuid(cuid)
4701
+ }, selectedEntry.cuid, false, undefined, this)
4702
+ }, undefined, false, undefined, this)
4703
+ ]
4704
+ }, undefined, true, undefined, this)
4705
+ ]
4706
+ }, undefined, true, undefined, this);
4707
+ }
4708
+ function getBreakReasons(current, previous) {
4709
+ const reasons = [];
4710
+ const inputChanged = current.inputHash != null && previous.inputHash != null ? current.inputHash !== previous.inputHash : safeStringify(current.input, 0) !== safeStringify(previous.input, 0);
4711
+ if (inputChanged)
4712
+ reasons.push("new input");
4713
+ const outputChanged = current.outputHash != null && previous.outputHash != null && current.outputHash !== previous.outputHash;
4714
+ if (outputChanged)
4715
+ reasons.push("new output");
4716
+ return reasons;
3922
4717
  }
3923
4718
  function getFlatItemKey(item) {
3924
4719
  const oldestCuid = item.group.rest[item.group.rest.length - 1]?.cuid ?? item.group.representative.cuid;
3925
- if (item.type === "group")
3926
- return `g:${oldestCuid}`;
3927
- if (item.type === "sub")
3928
- return `s:${item.entry.cuid}`;
3929
- return `c:${item.position}:${oldestCuid}`;
4720
+ return `g:${oldestCuid}`;
3930
4721
  }
3931
4722
  function ActionList({
3932
4723
  groups,
3933
4724
  selectedCuid,
3934
- expandedGroupCuids,
3935
4725
  onGroupClick,
3936
4726
  onSubClick,
3937
- onExpandGroup,
3938
- childExternalLabelsMap,
4727
+ childExternalRouteItemsMap,
3939
4728
  style
3940
4729
  }) {
3941
- const containerRef = useRef2(null);
4730
+ const containerRef = useRef(null);
3942
4731
  const latestTime = groups[0]?.representative.startTime;
3943
4732
  const flatItems = useMemo2(() => {
3944
- const result = [];
3945
- for (let gi = 0;gi < groups.length; gi++) {
3946
- const group = groups[gi];
3947
- const repCuid = group.representative.cuid;
3948
- const allInGroup = [group.representative, ...group.rest];
3949
- const selectedIdx = allInGroup.findIndex((e) => e.cuid === selectedCuid);
3950
- result.push({ type: "group", group, groupIndex: gi });
3951
- const oldestCuid = (group.rest[group.rest.length - 1] ?? group.representative).cuid;
3952
- if (selectedIdx > 0) {
3953
- const aboveCount = selectedIdx;
3954
- const belowCount = allInGroup.length - selectedIdx - 1;
3955
- if (aboveCount > 0)
3956
- result.push({ type: "group-count", count: aboveCount, position: "above", group });
3957
- result.push({ type: "sub", entry: allInGroup[selectedIdx], group });
3958
- if (belowCount > 0)
3959
- result.push({ type: "group-count", count: belowCount, position: "below", group });
3960
- } else if (selectedIdx === 0 && group.rest.length > 0) {
3961
- result.push({ type: "group-count", count: group.rest.length, position: "below", group });
3962
- } else {
3963
- const isExpanded = expandedGroupCuids.has(repCuid) || expandedGroupCuids.has(oldestCuid);
3964
- if (isExpanded) {
3965
- for (const entry of group.rest) {
3966
- result.push({ type: "sub", entry, group });
3967
- }
3968
- }
4733
+ return groups.map((group, gi) => {
4734
+ const prevGroup = groups[gi + 1];
4735
+ let breakReasons;
4736
+ if (prevGroup != null && prevGroup.representative.actionId === group.representative.actionId && prevGroup.representative.domain === group.representative.domain) {
4737
+ const reasons = getBreakReasons(group.representative, prevGroup.representative);
4738
+ if (reasons.length > 0)
4739
+ breakReasons = reasons;
3969
4740
  }
3970
- }
3971
- return result;
3972
- }, [groups, expandedGroupCuids, selectedCuid]);
3973
- const prevSelectedRef = useRef2(selectedCuid);
4741
+ return { group, groupIndex: gi, breakReasons };
4742
+ });
4743
+ }, [groups]);
4744
+ const prevSelectedRef = useRef(selectedCuid);
3974
4745
  useEffect3(() => {
3975
4746
  if (selectedCuid === prevSelectedRef.current)
3976
4747
  return;
3977
4748
  prevSelectedRef.current = selectedCuid;
3978
4749
  if (selectedCuid == null)
3979
4750
  return;
3980
- containerRef.current?.querySelector(`[data-cuid="${selectedCuid}"]`)?.scrollIntoView({ block: "nearest" });
3981
- }, [selectedCuid]);
4751
+ let repCuid = selectedCuid;
4752
+ for (const item of flatItems) {
4753
+ if (item.group.rest.some((e) => e.cuid === selectedCuid)) {
4754
+ repCuid = item.group.representative.cuid;
4755
+ break;
4756
+ }
4757
+ }
4758
+ containerRef.current?.querySelector(`[data-cuid="${repCuid}"]`)?.scrollIntoView({ block: "nearest" });
4759
+ }, [selectedCuid, flatItems]);
3982
4760
  if (groups.length === 0) {
3983
- return /* @__PURE__ */ jsxDEV15("div", {
4761
+ return /* @__PURE__ */ jsxDEV19("div", {
3984
4762
  style,
3985
- children: /* @__PURE__ */ jsxDEV15("div", {
3986
- style: { padding: "24px", textAlign: "center", color: "#475569" },
4763
+ children: /* @__PURE__ */ jsxDEV19("div", {
4764
+ style: { padding: "24px", textAlign: "center", color: DEVTOOL_COLOR_TEXT_MUTED },
3987
4765
  children: "No actions recorded yet"
3988
4766
  }, undefined, false, undefined, this)
3989
4767
  }, undefined, false, undefined, this);
3990
4768
  }
3991
- return /* @__PURE__ */ jsxDEV15("div", {
4769
+ return /* @__PURE__ */ jsxDEV19("div", {
3992
4770
  ref: containerRef,
3993
4771
  style,
3994
4772
  children: flatItems.map((item) => {
3995
4773
  const key = getFlatItemKey(item);
3996
- return /* @__PURE__ */ jsxDEV15("div", {
3997
- "data-cuid": item.type === "group" ? item.group.representative.cuid : item.type === "sub" ? item.entry.cuid : undefined,
3998
- style: { borderBottom: "1px solid #101109", position: "relative", overflow: "hidden" },
4774
+ const { group } = item;
4775
+ return /* @__PURE__ */ jsxDEV19("div", {
4776
+ style: {
4777
+ borderBottom: `1px solid ${DEVTOOL_LIST_GROUP_DIVIDER}`,
4778
+ position: "relative",
4779
+ overflow: "hidden"
4780
+ },
3999
4781
  children: [
4000
- item.type === "group" && /* @__PURE__ */ jsxDEV15("div", {
4782
+ /* @__PURE__ */ jsxDEV19("div", {
4001
4783
  style: {
4002
4784
  position: "absolute",
4003
4785
  inset: 0,
@@ -4005,49 +4787,18 @@ function ActionList({
4005
4787
  background: "linear-gradient(90deg, transparent 0%, rgba(148, 210, 255, 0.13) 50%, transparent 100%)",
4006
4788
  animation: "__nice-action-shine 0.65s ease-out forwards"
4007
4789
  }
4008
- }, item.group.representative.cuid, false, undefined, this),
4009
- item.type === "group" ? /* @__PURE__ */ jsxDEV15(ActionEntryRow, {
4010
- entry: item.group.representative,
4011
- isSelected: selectedCuid === item.group.representative.cuid,
4012
- groupCount: item.group.rest.length > 0 ? item.group.rest.length + 1 : undefined,
4790
+ }, group.representative.cuid, false, undefined, this),
4791
+ /* @__PURE__ */ jsxDEV19(ActionEntryRow, {
4792
+ entry: group.representative,
4793
+ isSelected: selectedCuid === group.representative.cuid || group.rest.some((e) => e.cuid === selectedCuid),
4013
4794
  isLatest: item.groupIndex === 0,
4014
4795
  latestTime,
4015
- childExternalLabels: childExternalLabelsMap.get(item.group.representative.cuid),
4016
- onClick: () => onGroupClick(item.group)
4017
- }, undefined, false, undefined, this) : item.type === "group-count" ? /* @__PURE__ */ jsxDEV15("div", {
4018
- onClick: () => onExpandGroup(item.group),
4019
- style: {
4020
- padding: "2px 28px",
4021
- fontSize: "10px",
4022
- color: "#475569",
4023
- display: "flex",
4024
- alignItems: "center",
4025
- gap: "5px",
4026
- background: "#0a1120",
4027
- cursor: "pointer",
4028
- userSelect: "none"
4029
- },
4030
- children: [
4031
- /* @__PURE__ */ jsxDEV15("span", {
4032
- style: { opacity: 0.6 },
4033
- children: item.position === "above" ? "↑" : "↓"
4034
- }, undefined, false, undefined, this),
4035
- /* @__PURE__ */ jsxDEV15("span", {
4036
- children: [
4037
- item.count,
4038
- " ",
4039
- item.position === "above" ? "newer" : "older",
4040
- " — click to browse"
4041
- ]
4042
- }, undefined, true, undefined, this)
4043
- ]
4044
- }, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV15(ActionEntryRow, {
4045
- entry: item.entry,
4046
- isSelected: selectedCuid === item.entry.cuid,
4047
- isSubEntry: true,
4048
- isLatest: false,
4049
- latestTime,
4050
- onClick: () => onSubClick(item.entry.cuid, selectedCuid === item.entry.cuid)
4796
+ childExternalRouteEntries: childExternalRouteItemsMap.get(group.representative.cuid),
4797
+ breakReasons: item.breakReasons,
4798
+ groupEntries: group.rest.length > 0 ? [group.representative, ...group.rest] : undefined,
4799
+ selectedGroupCuid: selectedCuid,
4800
+ onSelectGroupEntry: (cuid) => onSubClick(cuid, selectedCuid === cuid),
4801
+ onClick: () => onGroupClick(group)
4051
4802
  }, undefined, false, undefined, this)
4052
4803
  ]
4053
4804
  }, key, true, undefined, this);