noctrace 0.7.4 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "noctrace",
3
- "version": "0.4.0",
3
+ "version": "0.7.5",
4
4
  "description": "Chrome DevTools Network-tab-style waterfall visualizer for Claude Code agent workflows",
5
- "author": {
6
- "name": "Nyktora Group LLC",
7
- "url": "https://nyktora.com"
8
- },
5
+ "author": "Nyktora Group LLC",
6
+ "license": "MIT",
9
7
  "homepage": "https://nyktora.github.io/noctrace/",
10
8
  "repository": "https://github.com/nyktora/noctrace",
11
- "license": "MIT",
12
- "keywords": ["devtools", "waterfall", "observability", "timeline", "context-health"]
9
+ "keywords": ["devtools", "waterfall", "observability", "timeline", "context-health", "claude-code", "agent-monitoring", "ai-observability"],
10
+ "category": "observability",
11
+ "minClaudeCodeVersion": "1.0.0",
12
+ "capabilities": ["hooks", "mcp"]
13
13
  }
package/README.md CHANGED
@@ -3,9 +3,12 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- Chrome DevTools Network-tab-style waterfall visualizer for <a href="https://docs.anthropic.com/en/docs/claude-code">Claude Code</a> agent workflows.
7
- <br />
8
- Zero config. Zero cloud. Just run <code>npx noctrace</code> and see what your agents are doing.
6
+ Open-source observability for <a href="https://docs.anthropic.com/en/docs/claude-code">Claude Code</a> agent workflows.
7
+ Chrome DevTools Network-tab-style waterfall visualizer that monitors tool calls, tracks token usage, and detects context rot — all locally, with zero config.
8
+ <br /><br />
9
+ Noctrace reads Claude Code JSONL session logs from <code>~/.claude/projects/</code> and renders them as an interactive waterfall timeline.
10
+ See every tool call, sub-agent spawn, token cost, and context window fill level at a glance.
11
+ Built for developers using Anthropic's Claude Code who want to understand what their AI agents are actually doing.
9
12
  </p>
10
13
 
11
14
  <p align="center">
@@ -20,18 +23,28 @@
20
23
  <img src="docs/screenshots/noctrace-demo.gif" alt="Noctrace demo — waterfall timeline, agent groups, detail panel" width="100%" />
21
24
  </p>
22
25
 
23
- ## Why
26
+ ## Why Noctrace?
24
27
 
25
28
  Claude Code's terminal output is opaque. Tool calls show summaries like "Read 3 files" and "Edited 2 files" — no paths, no timing, no concurrency visibility. When sub-agents spawn sub-agents, you're flying blind.
26
29
 
27
30
  Noctrace reads Claude Code's session logs from `~/.claude/projects/` and renders them as an interactive waterfall timeline — the same visual paradigm that makes Chrome DevTools' Network tab instantly readable.
28
31
 
32
+ - **Waterfall timeline** — See tool calls laid out on a time axis, just like Chrome DevTools Network tab
33
+ - **Sub-agent visibility** — Expandable agent rows show nested tool calls from Explore, Plan, and custom agents
34
+ - **Context health scoring** — A-F grade based on context fill, compaction frequency, re-reads, and error acceleration
35
+ - **Token cost tracking** — Per-row USD estimates using Claude's per-model pricing (Opus, Sonnet, Haiku)
36
+ - **Efficiency and security tips** — Automatic detection of wasteful patterns and security anti-patterns
37
+ - **Zero config** — Just run `npx noctrace` and it reads your local Claude Code session logs
38
+
29
39
  ## Install
30
40
 
31
41
  ```bash
32
- # Run directly (no install needed)
33
42
  npx noctrace
43
+ ```
44
+
45
+ That's it. No config required. Noctrace starts a local server, opens your browser, and begins reading Claude Code session logs from `~/.claude/projects/` immediately.
34
46
 
47
+ ```bash
35
48
  # Or install globally
36
49
  npm install -g noctrace
37
50
  noctrace
@@ -43,47 +56,45 @@ noctrace
43
56
  claude plugin install nyktora/noctrace
44
57
  ```
45
58
 
46
- Requires Node.js 20+. That's it. No config required. Optional hooks for real-time events.
59
+ Requires Node.js 20+. Optional `--install-hooks` flag enables real-time hook events from Claude Code.
47
60
 
48
61
  ## Features
49
62
 
50
- - **Waterfall timeline** — horizontal bars on a shared time axis showing tool call concurrency and duration
51
- - **Collapsible agent groups** — sub-agents as expandable row groups with real execution time bars showing parallel work
52
- - **Sub-agent visibility** — parses sub-agent JSONL files to show what happened inside each agent
53
- - **Real-time updates** — file watcher pushes new events via WebSocket as your session runs
54
- - **Token drift detection** — tracks how per-turn token cost drifts from baseline, warns when sessions burn excessive quota
55
- - **Context Health grade** — A-F letter grade from 5 signals with actionable recommendations
56
- - **Compact stats pill** — toolbar shows agent count, health grade, drift factor, total tokens, and session duration at a glance
57
- - **Advanced filtering** — structured filter syntax: `type:bash`, `>5s`, `<100ms`, `tokens:>1k`, `error`, `running`, `success` combinable with plain text search
58
- - **Per-tool latency stats** — Session Stats flyout shows P50/P95/Max latency per tool type; calls exceeding a configurable threshold (default 5s) are flagged with a clock icon
59
- - **Loop detection** — flags 3+ consecutive identical tool calls (same tool + same input) as a warning tip on the row
60
- - **Session comparison** — split-screen view comparing two sessions side-by-side: health grades, summary metrics, tool mix bars, and context fill trajectory sparklines
61
- - **Virtual scrolling** — handles sessions with thousands of tool calls
62
- - **Zoom & pan** — mouse wheel zoom (1-50x), click-drag pan
63
- - **Detail panel** — click any row for full tool input/output, resizable
64
- - **Re-read detection** — flags duplicate file reads that waste context
65
- - **Efficiency tips** — 8 waste patterns detected (re-reads, fan-out, correction loops, repeated commands, token spikes, high fill, no delegation, post-compaction re-reads) with amber lightbulb indicators
66
- - **Security tips** — 13 patterns detect secrets, dangerous commands, exfiltration attempts, prompt injection, and more, with a red shield indicator
67
- - **Markdown rendering** — detail panel renders markdown in tool output with zero dependencies, XSS-safe
68
- - **Dark theme** — Catppuccin Mocha palette
69
- - **Session export** — share sessions as standalone offline HTML files
70
- - **Hooks integration** — optional real-time event streaming from Claude Code
71
- - **Context Drift Rate** — detect accelerating token growth before context rot hits
72
- - **MCP session registry** — when integrated with Claude Code, sessions self-register on start and unregister on exit; dashboard shows only active sessions with a live count indicator
73
- - **Per-tool token cost** — estimated USD cost on every waterfall row and session total in the toolbar; uses Claude's public pricing with per-model detection (Sonnet, Opus, Haiku)
74
- - **Agent type labels** — subagent rows show the named agent type (e.g., "Explore", "core:deep-researcher") as a blue badge chip
75
- - **Tool failure rows** — tool crashes, timeouts, and kills render as distinct red-tinted rows with a lightning bolt icon, separate from normal error results
76
- - **API error markers** — rate limit, billing, and auth failures appear as full-width red alert banners on the timeline
77
- - **Agent Teams panel** — detects running Agent Teams at `~/.claude/teams/`, shows members and task counts in a flyout (`GET /api/teams`)
78
- - **Context Startup flyout** — shows which instruction files (CLAUDE.md and others) loaded at session start with estimated token counts, parsed from JSONL system records
63
+ - **Waterfall Timeline Visualization** — horizontal bars on a shared time axis showing tool call concurrency and duration, just like Chrome DevTools Network tab
64
+ - **Sub-Agent Waterfall Visualization** — collapsible agent row groups with real execution time bars; parses sub-agent JSONL files to show what happened inside each agent
65
+ - **Real-Time Session Monitoring** — file watcher pushes new events via WebSocket as your Claude Code session runs
66
+ - **Token Drift Detection** — tracks how per-turn token cost drifts from baseline, warns when sessions burn excessive quota
67
+ - **Context Health Scoring** — A-F letter grade from 5 signals with actionable recommendations for when to run `/compact`
68
+ - **Compact Stats Toolbar** — shows agent count, health grade, drift factor, total tokens, and session duration at a glance
69
+ - **Advanced Filtering** — structured filter syntax: `type:bash`, `>5s`, `<100ms`, `tokens:>1k`, `error`, `running`, `success` combinable with plain text search
70
+ - **Per-Tool Latency Stats** — Session Stats flyout shows P50/P95/Max latency per tool type; calls exceeding a configurable threshold (default 5s) are flagged with a clock icon
71
+ - **Loop Detection** — flags 3+ consecutive identical tool calls (same tool + same input) as a warning tip on the row
72
+ - **Session Comparison** — split-screen view comparing two Claude Code sessions side-by-side: health grades, summary metrics, tool mix bars, and context fill trajectory sparklines
73
+ - **Virtual Scrolling** — handles sessions with thousands of tool calls without performance degradation
74
+ - **Zoom and Pan** — mouse wheel zoom (1-50x), click-drag pan on the timeline
75
+ - **Detail Panel** — click any row for full tool input/output, resizable two-column layout
76
+ - **Re-Read Detection** — flags duplicate file reads that waste context window space
77
+ - **Efficiency Tips** — 8 waste patterns detected (re-reads, fan-out, correction loops, repeated commands, token spikes, high fill, no delegation, post-compaction re-reads) with amber lightbulb indicators
78
+ - **Security Tips** — 13 patterns detect secrets, dangerous commands, exfiltration attempts, prompt injection, and more, with a red shield indicator
79
+ - **Markdown Rendering** — detail panel renders markdown in tool output with zero dependencies, XSS-safe
80
+ - **Session Export** — share sessions as standalone offline HTML files, no server required
81
+ - **Claude Code Hook Integration** — optional real-time event streaming from Claude Code via `--install-hooks`
82
+ - **Context Drift Rate** — detects accelerating token growth before context rot degrades output quality
83
+ - **MCP Session Registry** — sessions self-register and unregister automatically; dashboard shows only active sessions with a live count indicator
84
+ - **Per-Tool Token Cost Estimation** — estimated USD cost on every waterfall row and session total in the toolbar; uses Claude's public pricing with per-model detection (Sonnet, Opus, Haiku)
85
+ - **Agent Type Labels** — sub-agent rows show the named agent type (e.g., "Explore", "core:deep-researcher") as a blue badge chip
86
+ - **Tool Failure Rows** — tool crashes, timeouts, and kills render as distinct red-tinted rows with a lightning bolt icon, separate from normal error results
87
+ - **API Error Markers** — rate limit, billing, and auth failures appear as full-width red alert banners on the timeline
88
+ - **Agent Teams Panel** — detects running Agent Teams at `~/.claude/teams/`, shows members and task counts in a flyout
89
+ - **Context Startup Flyout** — shows which instruction files (CLAUDE.md and others) loaded at session start with estimated token counts, parsed from JSONL system records
79
90
 
80
91
  ![Noctrace waterfall timeline](docs/screenshots/noctrace-waterfall.gif)
81
92
 
82
- ### Token Drift
93
+ ### Token Drift Detection
83
94
 
84
95
  The stats pill shows a **drift factor** (e.g. `2.8x`) measuring how much each turn costs compared to the session's baseline. A 10x drift means every turn burns 10x more quota than it did at the start. Session picker shows drift per-session so you can spot wasteful sessions at a glance.
85
96
 
86
- ### Context Health
97
+ ### Context Health Scoring
87
98
 
88
99
  ![Context health visualization](docs/screenshots/noctrace-context-rot.png)
89
100
 
@@ -97,7 +108,7 @@ Noctrace computes a real-time health score from your session data and warns you
97
108
  | Error Rate | 10% | Accelerating errors in second half of session |
98
109
  | Tool Efficiency | 10% | Declining productive output |
99
110
 
100
- ### Detail Panel
111
+ ### Tool Call Detail Panel
101
112
 
102
113
  ![Detail panel with tips](docs/screenshots/noctrace-detail-panel.gif)
103
114
 
@@ -157,10 +168,28 @@ npm run dev # starts server + Vite dev server
157
168
  - **Tests**: Vitest 4
158
169
  - **Language**: TypeScript 5.9 (strict mode)
159
170
 
171
+ ## Compatibility
172
+
173
+ Noctrace works with all Claude Code versions that write JSONL session logs to `~/.claude/projects/`. This includes:
174
+
175
+ - **Claude Code CLI** (`claude` command)
176
+ - **Claude Code in VS Code** (via the extension)
177
+ - **Claude Code in JetBrains** (via the extension)
178
+ - **Claude Code Desktop App** (Mac/Windows)
179
+
180
+ No API keys or cloud accounts required. Noctrace is 100% local — your session data never leaves your machine.
181
+
160
182
  ## License
161
183
 
162
184
  [MIT](LICENSE)
163
185
 
186
+ ## Links
187
+
188
+ - [Website](https://nyktora.github.io/noctrace/) — Landing page and documentation
189
+ - [npm](https://www.npmjs.com/package/noctrace) — Package registry
190
+ - [GitHub](https://github.com/nyktora/noctrace) — Source code and issues
191
+ - [Changelog](CHANGELOG.md) — Version history
192
+
164
193
  ---
165
194
 
166
195
  <p align="center">
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-ease:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-semibold:600;--font-weight-bold:700;--tracking-wider:.05em;--radius-sm:.25rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-8{top:calc(var(--spacing) * 8)}.right-0{right:calc(var(--spacing) * 0)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.right-2{right:calc(var(--spacing) * 2)}.left-0{left:calc(var(--spacing) * 0)}.left-2{left:calc(var(--spacing) * 2)}.z-10{z-index:10}.z-50{z-index:50}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mb-0\.5{margin-bottom:calc(var(--spacing) * .5)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-full{height:100%}.w-full{width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.resize{resize:both}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-sm{border-radius:var(--radius-sm)}.rounded-r{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.pr-3{padding-right:calc(var(--spacing) * 3)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pl-7{padding-left:calc(var(--spacing) * 7)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-all{word-break:break-all}.whitespace-pre-wrap{white-space:pre-wrap}.uppercase{text-transform:uppercase}.italic{font-style:italic}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.invert{--tw-invert:invert(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.select-none{-webkit-user-select:none;user-select:none}.\[file\:line\]{file:line}@media (width>=48rem){.md\:hidden{display:none}}}:root{--ctp-base:#1e1e2e;--ctp-mantle:#181825;--ctp-crust:#11111b;--ctp-surface0:#313244;--ctp-surface1:#45475a;--ctp-surface2:#585b70;--ctp-overlay0:#6c7086;--ctp-overlay1:#7f849c;--ctp-text:#cdd6f4;--ctp-subtext0:#a6adc8;--ctp-subtext1:#bac2de;--ctp-blue:#89b4fa;--ctp-green:#a6e3a1;--ctp-yellow:#f9e2af;--ctp-peach:#fab387;--ctp-mauve:#cba6f7;--ctp-teal:#94e2d5;--ctp-red:#f38ba8;--ctp-pink:#f5c2e7;--ctp-lavender:#b4befe;--ctp-sky:#89dceb;--color-read:var(--ctp-blue);--color-write:var(--ctp-green);--color-edit:var(--ctp-yellow);--color-bash:var(--ctp-peach);--color-agent:var(--ctp-mauve);--color-grep:var(--ctp-teal);--color-error:var(--ctp-red);--color-running:var(--ctp-pink);--color-monitor:var(--ctp-sky)}body{background-color:var(--ctp-base);color:var(--ctp-text);font-family:SF Mono,Cascadia Code,JetBrains Mono,Fira Code,ui-monospace,monospace}@keyframes pulse-edge{0%,to{opacity:.6}50%{opacity:.1}}.running-pulse{animation:1.2s ease-in-out infinite pulse-edge}@keyframes noc-pulse{0%,to{opacity:1;transform:scale(1)}50%{opacity:.4;transform:scale(.85)}}@keyframes noc-blink{0%,to{opacity:1}50%{opacity:0}}@media (width<=768px){.hidden-mobile{display:none!important}}.sidebar-panel{background-color:var(--ctp-mantle);flex-direction:column;flex-shrink:0;width:240px;display:flex;overflow:hidden}@media (width<=767px){.sidebar-panel{width:240px;transition:transform .2s;position:fixed;top:0;bottom:0;left:0;transform:translate(-100%)}.sidebar-panel[data-open=true]{transform:translate(0)}}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}