<!-- GENERATED by scripts/build-llms.mjs from llms/agent-tools.md — do not edit this file. -->

# `lr-stack-trace`

- **Import** `import '@aceshooting/lyra-ui/components/lr-stack-trace.js';` (stable tag alias; registers the tag)
- **Class** `LyraStackTrace`, also available unregistered from `@aceshooting/lyra-ui/components/agent-tools/stack-trace/stack-trace.class.js`
- **Family** `components/agent-tools/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
- **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
- **Deprecations** none
- **Optional peers** none
- **Themeable via** 10 parts, 9 custom properties — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-stack-trace`

Parses common V8/JS-TS, Firefox/Safari, and Python stack traces into a leading message plus
activatable frames, splitting chained/caused-by errors (`Caused by:`, `[cause]:`, Python's "direct
cause"/"During handling" separators) into separate groups. Frames matching `internalPatterns` fold
behind a count-labeled toggle. A malformed or non-safe-integer location remains visible as raw,
non-activatable text. Falls back to verbatim raw text when nothing parses. First-party invention
(no Web Awesome equivalent).

Removing the `trace` attribute clears parsed content and copies empty text; the property retains
`null` until assigned again.

**Properties:**

- `trace: string = ''` — the raw stack trace text to parse and render.
- `collapseInternal: boolean = true` (attribute: `collapse-internal`) — folds runs of internal
  frames behind a toggle.
- `internalPatterns: readonly (string | RegExp)[] = DEFAULT_INTERNAL_PATTERNS` (attribute: false) —
  clone-owned, bounded, frozen file-path substrings/`RegExp`s that mark a frame as internal.
  Reassign a new array after changing the matcher sequence.
- `copyable: boolean = true` — shows a copy-to-clipboard button for the raw trace text.
- `maxHeight: string = ''` (attribute: `max-height`) — caps the rendered block size and enables an
  internal scrollbar once content exceeds it (any valid CSS length). Empty string (the default)
  grows with content.
- `frame: LyraFrame = 'card'` (reflected) — container treatment, in the library-wide `frame`
  vocabulary (`'card' | 'plain'`). `'card'` keeps the bordered, filled, padded box. `'plain'` removes
  the border, background, padding and corner radius, so a trace nested inside an
  `lr-result-card`/`lr-agent-run` — which already draws a border — doesn't double the frame. The
  `max-height` scroll cap and the copy/frame affordances are unaffected either way, and `'plain'`
  wins over `compact` when both are set. The exported alias `StackTraceAppearance` is retained as a
  name for the same union.
- `compact: boolean = false` (reflected) — tighter root padding and between-group spacing for dense
  contexts (a trace as a row in an error list, a side panel), the same density convention
  `lr-agent-run`, `lr-commit-card`, `lr-result-card`, `lr-task-list`, `lr-terminal` and
  `lr-thinking-panel` already pair with `frame`. Purely density: the border, corner radius and
  background stay, so reach for `frame="plain"` to drop the chrome. Added in 9.0.0.

**Events:**

- `lr-frame-select` (`detail: { file: string; line: number; column?: number; raw: string }`) — a
  frame with a safe parsed location was activated. `column` is always undefined for Python frames,
  which carry no column information. Malformed or unsafe locations render as raw text and never
  emit this event.
- `lr-copy` (`detail: { ok: true; text: string }`) — the raw, unparsed trace text, fired only after the
  clipboard write resolves successfully.
- `lr-error` (no detail) and `lr-copy-error` (`detail: { ok: false; text: string; reason:
'unsupported'|'denied'|'failed'; error: unknown }`) — compatibility and detailed failure signals. A rejected or
  unavailable clipboard never enters the success state or emits `lr-copy`.

**Slots:** none.

**CSS parts:** `base` (the root wrapper; respects `max-height`, tightens its padding under
`compact`, and drops its card chrome under `frame="plain"`), `message` (the leading error
message text for a group), `group` (one chained-error group of frames), `frame` (a selectable
frame button, carrying `data-internal` for internal frames, or a non-activatable raw row for an
unsafe location), `frame-function` (the frame's function name), `frame-location` (the frame's
`file:line:col` text), `internal-toggle` (the collapse/expand toggle for a run of internal frames),
`limit` (the resource-ceiling status when additional frames are omitted), `raw` (the verbatim fallback when zero structured frames parsed), `copy-button` (only rendered
while `copyable`).

**Themeable custom properties:** `--lr-stack-trace-max-height` (default `none`),
`--lr-stack-trace-font` (default `var(--lr-font-mono)`),
`--lr-stack-trace-internal-frame-color` (default `var(--lr-color-text-quiet)`) — internal-frame
foreground, `--lr-stack-trace-interactive-color` (default `var(--lr-color-brand)`) — frame
hover/focus, internal-toggle, and copy-button-hover accent, plus the two density hooks
`--lr-stack-trace-compact-padding` (default `var(--lr-space-2xs)`, `[part="base"]` padding while
`compact`, overridden entirely by `frame="plain"`) and `--lr-stack-trace-compact-gap` (default
`var(--lr-space-2xs)`, the space below `[part="message"]` and between `[part="group"]`s while
`compact`). The scoped color hooks avoid changing
the shared quiet/brand tokens used by surrounding UI. `--lr-stack-trace-background` (default
`var(--lr-color-surface)`), `--lr-stack-trace-border-color` (default `var(--lr-color-border)`) and
`--lr-stack-trace-radius` (default `var(--lr-radius)`) retune `[part="base"]`'s card chrome without a
`::part(base)` override; `frame="plain"` still removes all three outright. Plus shared tokens
`--lr-color-border`/`-surface`/`-text`/`-text-quiet`/`-brand`, `--lr-radius`,
`--lr-border-width-thin`, `--lr-space-xs`/`-s`/`-2xs`, `--lr-font-size-sm`/`-xs`,
`--lr-font-weight-bold`/`-semibold`, `--lr-focus-ring-*`.

**Optional peer deps:** none.

```html
<lr-stack-trace></lr-stack-trace>
<script type="module">
  const stackTrace = document.querySelector("lr-stack-trace");
  stackTrace.trace = "TypeError: boom\n    at doThing (/app/src/util.js:10:5)";
  stackTrace.addEventListener("lr-frame-select", (e) =>
    console.log(e.detail.file, e.detail.line)
  );
</script>
```

The package root also exports the pure
`parseStackTrace(trace: string, options?: StackTraceParseOptions): StackTraceParseResult` helper
(plus `DEFAULT_INTERNAL_PATTERNS`, `STACK_TRACE_LIMITS`, and the `StackFrame`, `StackGroup`,
`StackTraceParseOptions`, and `StackTraceParseResult` types) — the same parser this component uses,
exposed standalone so a consumer can parse or unit-test traces without instantiating the element.
Pass custom classifiers as `{ internalPatterns: ['node_modules/', /vendor\//] }`. The result is
`{ groups, truncated, source }`, where `source` is the bounded raw-text fallback.

**Known gotchas:**

- an internal-frame run only collapses behind the `internal-toggle` when it is two or more
  consecutive internal frames; a single isolated internal frame renders as a normal `frame` button
  (there is nothing useful to fold).
- when `trace` doesn't match any supported format, `parseStackTrace().groups` is empty and the
  component renders the result's bounded `source` verbatim in a `raw` part instead of silently
  dropping content.
- every coordinate of an activatable frame must be a JavaScript safe integer. A malformed or
  overlarge location remains visible as a non-activatable raw row; if no safe frame is left, the
  component uses the verbatim `raw` fallback.

---
