Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
c40661b
CI: coverage via pcov
dg Oct 12, 2026
e906a54
phpstan: removed stale ignores, requires PHPStan 2.3
dg Oct 12, 2026
9677c95
cs: only compiler-optimized functions in use-function imports
dg Oct 13, 2026
484447f
cs: suppression comments
dg Oct 13, 2026
4f5f951
cs: grouped use statements
dg Oct 13, 2026
273ce67
cs
dg Oct 13, 2026
b9185ef
uses dresscode
dg Oct 14, 2026
ba05c0a
BlueScreen: markdown output hides /*sensitive{*/ regions in source (t…
dg Oct 13, 2026
4517330
added support for PHP 8.6
dg Oct 13, 2026
a82e1bc
Released version 2.12.2
dg Oct 13, 2026
1a0a501
added upgrading.md
dg Sep 16, 2026
17adcd2
opened 2.13-dev
dg Mar 26, 2026
fece2b4
assets: real event target is obtained via Tracy.retarget()
dg Jul 18, 2026
09ef38a
assets: added Tracy.css registry and adoptedStyleSheets helpers
dg Jul 18, 2026
2797c8b
added Shadow DOM for CSS isolation of Bar, BlueScreen and Dumper
dg Jul 18, 2026
a08c438
removed CSS scoping superseded by Shadow DOM
dg Jul 18, 2026
0b131f3
CSS: added @layer for cascade priority control
dg Jul 18, 2026
1f914a6
Bar: draggable() rewritten to Pointer Events
dg Jul 11, 2026
db7796d
BlueScreen: render pipeline split into shared context and page-only a…
dg Jul 11, 2026
2f1763b
Dumper: light & dark CSS themes merged into single dumper.css using c…
dg Jul 11, 2026
27bf409
agent output: custom panels can contribute to markdown reports
dg Jul 11, 2026
eb22225
Logger: machine-readable exceptions.jsonl index and $retention for ex…
dg Jul 11, 2026
a15b90c
BlueScreen: 'copy as markdown' action
dg Jul 11, 2026
304e190
Debugger: reset() clears per-request state for long-running workers
dg Jul 11, 2026
dc3daa5
UI & Logger improvements
dg Jul 11, 2026
a647d0b
opened 3.0-dev
dg Dec 10, 2021
83b460d
open in editor: added support for columns
dg Nov 24, 2025
bad7424
uses PascalCase constants
dg Dec 5, 2022
2072df2
Logger: added typehints WIP
dg Feb 3, 2022
dfc3e81
error.log changed to warning.log
dg Apr 3, 2024
be1e994
used attribute Deprecated
dg Nov 23, 2024
558641a
added lazy panel loading support
jakduch Oct 20, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@
.github/ export-ignore
.gitignore export-ignore
AGENTS.md export-ignore
ncs.* export-ignore
dresscode.neon export-ignore
phpstan*.neon export-ignore
src/**/*.latte export-ignore
docs/ export-ignore
tests/ export-ignore
tools/latte-convert/ export-ignore

* text=auto
*.php* diff=php
*.sh text eol=lf
tools/latte-convert/tests/fixtures/*.latte text eol=lf
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/coding-style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ jobs:
- run: php temp/code-checker/code-checker --strict-types --no-progress -i tests/Tracy/fixtures -i examples/assets -i *.latte


nette_cs:
name: Nette Coding Standard
dresscode:
name: DressCode
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: shivammathur/setup-php@v2
with:
php-version: 8.3
php-version: 8.4
coverage: none

- run: composer create-project nette/coding-standard temp/coding-standard ^3 --no-progress
- run: php temp/coding-standard/ecs check src tests tools
- run: composer create-project dresscode/dresscode temp/dresscode ^1.0 --no-progress
- run: php temp/dresscode/bin/dresscode check


js:
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
php: ['8.2', '8.3', '8.4', '8.5']
php: ['8.2', '8.3', '8.4', '8.5', '8.6']
sapi: ['php', 'php-cgi']

fail-fast: false
Expand Down Expand Up @@ -43,10 +43,10 @@ jobs:
with:
php-version: 8.2
extensions: ds
coverage: none
coverage: pcov

- run: composer install --no-progress --prefer-dist
- run: composer tester -- -p phpdbg ${{ env.php-options }} --coverage ./coverage.xml --coverage-src ./src
- run: composer tester -- ${{ env.php-options }} --coverage ./coverage.xml --coverage-src ./src
continue-on-error: true
- uses: coverallsapp/github-action@v2
with:
Expand Down
12 changes: 9 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ deferred content, the dumper, BlueScreen, the Bar, the logger). Read the relevan
`docs/internals/` seam before editing one - especially `deferred-content.md`, the
most counterintuitive part.

`docs/upgrading.md` records, per released version, every change visible to
users of the package (renames, removals, deprecations, signatures, behavior,
configuration), each with its commit hash; internal changes are not in it. It
is the place to look up the history of a public symbol. Do not write to it; it
is extended at release time from the git history.

## Project Overview

Tracy is a debugging and error-visualization library for PHP: BlueScreen error
Expand All @@ -21,7 +27,7 @@ Dumper, and a production error Logger. It auto-detects development vs production
emits **markdown for agents** (automated browsers via `navigator.webdriver`, or any
client sending an `X-Tracy-Agent` header) instead of HTML.

- **PHP Version**: 8.2 - 8.5
- **PHP Version**: 8.2 - 8.6
- **Package**: `tracy/tracy` (currently v2.12)

## Essential Commands
Expand All @@ -45,8 +51,8 @@ composer compile-templates
## Conventions

- Every PHP file starts with `declare(strict_types=1);`; **tabs**; return type and
opening brace on separate lines; Nette Coding Standard (`ncs.php`). JS is linted
with `@nette/eslint-plugin`.
opening brace on separate lines; the Nette coding standard, which
`dresscode.neon` applies. JS is linted with `@nette/eslint-plugin`.
- Tests are Nette Tester `.phpt` using `test()` and `getTempDir()`. **CI runs both
`php` and `php-cgi`**; UI-rendering tests need `php-cgi`.
- Templates are `.latte` (HTML-escaping) / `*.agent.latte` (text/markdown, no
Expand Down
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
}
],
"require": {
"php": "8.2 - 8.5",
"php": "8.2 - 8.6",
"ext-session": "*",
"ext-json": "*"
},
Expand All @@ -27,7 +27,7 @@
"nette/tester": "^2.6",
"latte/latte": "^2.5 || ^3.0",
"psr/log": "^1.0 || ^2.0 || ^3.0",
"phpstan/phpstan": "^2.1@stable",
"phpstan/phpstan": "^2.3@stable",
"phpstan/extension-installer": "^1.4@stable",
"nette/phpstan-rules": "^1.0"
},
Expand All @@ -49,7 +49,7 @@
},
"extra": {
"branch-alias": {
"dev-master": "2.12-dev"
"dev-master": "3.0-dev"
}
},
"config": {
Expand Down
5 changes: 4 additions & 1 deletion docs/internals/bluescreen.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,10 @@ template by comparing against that index. `CodeHighlighter` tokenizes PHP, shows
`DisplayLines` (15) lines around the error — the public `$lines` parameters of the
`highlight*` methods are ignored — highlights the line and column, and replaces
`/*sensitive{*/…/*}*/` regions with `*****` (`Describer::HiddenValue`) before
highlighting (PHP path only, not the plain-text one).
highlighting (not for the `php: false` path). The markdown variant does
not highlight, but its source snippets go through the same
`CodeHighlighter::hideSensitive()`; any new place printing PHP source must too.
The masking keeps the newlines of a multi-line region, so line numbers stay true.

Two dumpers exist: `getDumper()` renders **HTML** (`BlueScreen::$maxDepth` etc.,
`LOCATION_CLASS`, the shared `SNAPSHOT`, scrubber, `keysToHide`) and feeds the page
Expand Down
128 changes: 128 additions & 0 deletions docs/upgrading.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Upgrading tracy/tracy

## 2.12.1

- **Changed** `Tracy\Debugger::dump()` called with `return: true` now applies `Tracy\Debugger::$keysToHide` and, in CLI, also `$maxDepth`, `$maxLength` and `$maxItems`; previously it ignored them (69f595b0)
- **Changed** `Tracy\Debugger::enable()` called again after output has already started is now a silent no-op; previously it threw `LogicException` (1ddaa887)
- **Changed** `Tracy\Dumper` now checks properties coming from `__debugInfo()` or from a custom object exporter against `Tracy\Debugger::$keysToHide` and the scrubber; previously such properties were always shown unmasked (e726c8f0)
- **Changed** `Tracy\Logger::$emailSnooze` now throws `InvalidArgumentException` when its value cannot be parsed by `strtotime()`; previously throttling was silently disabled and an email was sent for every error (ed5e3a48)
- **Changed** `Tracy\Bridges\Psr\TracyToPsrLoggerAdapter::log()` now logs an exception passed in the PSR-3 context only once when the message is empty or equal to the exception message; previously the message was logged a second time (6ccd6e55)

## 2.12.0

- **Deprecated** `Tracy\BlueScreen::$collapsePaths`: use `Tracy\Debugger::$transparentPaths`, a static property filled when the class is loaded; the old name is silently deprecated and its value is still merged in (0deea90e)
- **Changed** `Tracy\BlueScreen::renderToFile()` now writes a Markdown companion file with the same basename next to the HTML file (1dbb02d7)
- **Changed** `Tracy\Logger::getExceptionFile()` now reuses an existing log file only when its name ends with the exception hash and `.html`; previously the hash could appear anywhere in the name (1dbb02d7)

## 2.11.1

- **Signature** `Tracy\Bridges\Psr\PsrToTracyLoggerAdapter::log()` now declares the return type `void`; affects subclasses overriding it (2f4c7df4)
- **Config** `tracy.keysToHide` now fills `Tracy\Debugger::$keysToHide` as well, not only `Tracy\BlueScreen::$keysToHide`, so the listed keys are masked in all dumps (ebd29547)

## 2.11.0

- **Renamed** the Tracy Bar panel id `Tracy:errors` → `Tracy:warnings`; the old id was removed (0dda9390)

## 2.10.5

- **Renamed** `Tracy\Debugger::VERSION` → `Tracy\Debugger::Version`; the old name is silently deprecated (3a6fb902)
- **Deprecated** `Tracy\Debugger::PRODUCTION`: use `Tracy\Debugger::Production`; the old name is silently deprecated (alias since 2.9.6) (3a6fb902)
- **Deprecated** `Tracy\Debugger::DEVELOPMENT`: use `Tracy\Debugger::Development`; the old name is silently deprecated (alias since 2.9.6) (3a6fb902)
- **Deprecated** `Tracy\Debugger::DETECT`: use `Tracy\Debugger::Detect`; the old name is silently deprecated (alias since 2.9.6) (3a6fb902)
- **Deprecated** `Tracy\Debugger::COOKIE_SECRET`: use `Tracy\Debugger::CookieSecret`; the old name is silently deprecated (alias since 2.9.6) (3a6fb902)

## 2.10.0

- **Removed** `Tracy\FireLogger`; FireLogger support was dropped without replacement (8eaf4f25)
- **Removed** `Tracy\Debugger::fireLog()`; FireLogger support was dropped without replacement (8eaf4f25)
- **Removed** `Tracy\Debugger::getFireLogger()`; FireLogger support was dropped without replacement (8eaf4f25)
- **Removed** `Tracy\Debugger::$showFireLogger`; FireLogger support was dropped without replacement (8eaf4f25)
- **Signature** `Tracy\ILogger::log()` is now `log(mixed $value, string $level = self::INFO)`; a custom implementation must declare the same types or PHP reports an incompatible signature (9cf27348)
- **Signature** native types were added to parameters, return values and properties; notably `Tracy\Debugger::enable(bool|string|array|null $mode = null, ?string $logDirectory = null, string|array|null $email = null)`, `Tracy\Debugger::$email`, `Tracy\Debugger::$logDirectory`, `Tracy\Debugger::$browser`, `Tracy\Debugger::$errorTemplate`, `Tracy\Debugger::$productionMode`, `Tracy\Debugger::$showLocation`, `Tracy\Debugger::$scream`, `Tracy\Debugger::$logSeverity`, `Tracy\Logger::__construct()` and `Tracy\BlueScreen::addFiber()`. Assigning a value of another type to a now typed static property throws `TypeError` (9cf27348)

## 2.9.8

- **Changed** `Tracy\BlueScreen::highlightLine()` no longer appends the closing `</code>` tag, which `Tracy\BlueScreen::highlightPhp()` adds instead; also in 2.10.5 (ba708e94)

## 2.9.6

- **Renamed** `Tracy\Debugger::PRODUCTION` → `Tracy\Debugger::Production`; the old name still works as an alias (b6cd4a42)
- **Renamed** `Tracy\Debugger::DEVELOPMENT` → `Tracy\Debugger::Development`; the old name still works as an alias (b6cd4a42)
- **Renamed** `Tracy\Debugger::DETECT` → `Tracy\Debugger::Detect`; the old name still works as an alias (b6cd4a42)
- **Renamed** `Tracy\Debugger::COOKIE_SECRET` → `Tracy\Debugger::CookieSecret`; the old name still works as an alias (b6cd4a42)

## 2.9.2

- **Changed** `Tracy\Dumper::dump()` with the option `Tracy\Dumper::HASH => false` now renders a repeated array or object in full; previously it was collapsed to "see above" / "see below" (d9c2e36b)

## 2.9.1

- **Changed** `Tracy\Debugger::$maxDepth` now defaults to 15; previously 7. Set it to 7 explicitly to keep the previous depth (d6d21012)

## 2.9.0

- **Changed** `Tracy\Debugger::$scream` no longer changes `error_reporting()` globally; it now only controls whether `Tracy\Debugger::errorHandler()` processes a silenced error (52a9cc0c)
- **Config** `tracy.logSeverity` accepts as list items only strings naming `E_*` constants; a raw integer or an arbitrary string is rejected, pass a single int bitmask instead of a list (74a9fbee)

## 2.8.4

- **Changed** `Tracy\Dumper::ITEMS` with the value `0` now means no limit; previously it truncated the output to zero items (0bc1b627)
- **Changed** the scrubber callback (`Tracy\Dumper::SCRUBBER`, `Tracy\BlueScreen::$scrubber`) is now called for non-string keys as well, cast to string; previously it was not called for them (c2f56c43)

## 2.8.2

- **Changed** `Tracy\Debugger::$maxDepth` now defaults to 7; previously 3 (845130ec)
- **Changed** `Tracy\BlueScreen::$collapsePaths` now defaults to the `tracy/`, `nette/` and `latte/` directories; previously to the whole `vendor` directory, so stack frames of other packages are no longer collapsed (8c7bdf03)
- **Changed** `Tracy\Debugger::dump()` with `$return = true` now returns plain text in CLI; previously the captured HTML output (34ed4467)

## 2.8.1

- **Changed** `Tracy\BlueScreen::$maxDepth` now defaults to 5; previously 3 (e23800ff)
- **Changed** `Tracy\BlueScreen::$keysToHide` is no longer matched against virtual (computed) properties, so such a property is dumped in full (47cab47b)
- **Changed** `Tracy\BlueScreen::$scrubber` is no longer called for virtual (computed) properties (47cab47b)

## 2.8.0

- **Renamed** `Tracy\Dumper::LOCATION_LINK` → `Tracy\Dumper::LOCATION_SOURCE`; the old name still works as an alias (67e9e791)
- **Signature** `Tracy\BlueScreen::highlightFile()` and `Tracy\BlueScreen::highlightPhp()` lost the `$vars` and `$keysToHide` parameters together with the feature of inlining dumped variables into the source; drop them from calls (7d2862e9)
- **Changed** `Tracy\Dumper::LOCATION_SOURCE` now implies `Tracy\Dumper::LOCATION_CLASS`, whose bit value changed from `0b0100` to `0b0001` (67e9e791)
- **Changed** `Tracy\Debugger::$showLocation` now defaults to `null` and HTML dumps show the source location by default; previously the default was `false` and the location was hidden (2deb1d2d)
- **Changed** `Tracy\Dumper::DEPTH` now defaults to 7; previously 4 (5f275f6c)
- **Changed** `Tracy\Dumper::dump()`, `Tracy\Dumper::toHtml()` and `Tracy\Dumper::toText()` now truncate arrays and objects to 100 items; pass `Tracy\Dumper::ITEMS` to change or lift the limit (1c4dc56c)
- **Changed** `Tracy\Dumper::dump()` now emits inline `<style>` tags (and `<script>` tags unless Tracy is enabled) with Tracy's assets on the first HTML dump of a request (c481ec05)
- **Changed** `Tracy\Dumper::dump()` in CLI now writes the terminal output directly to `STDOUT` and bypasses output buffering; previously it echoed it (c5855a03)
- **Changed** `Tracy\Dumper::toHtml()`, `Tracy\Dumper::toText()` and `Tracy\Dumper::toTerminal()` no longer use late static binding, so a subclass is not instantiated through them (2eb960e9)

## 2.7.9

- **Signature** `Tracy\Bridges\Psr\TracyToPsrLoggerAdapter::log()` now declares the return type `void`; affects subclasses overriding it; also in 2.8.8 (d46d6558)

## 2.7.0

- **Config** `tracy.maxLen` → `tracy.maxLength`; the old key is now rejected as unknown (it never had any effect) (1c3317b6)
- **Config** the values of the `tracy` section are now validated by `Nette\Schema`; a value of the wrong type that previously passed silently now fails the container compilation (1c3317b6)

## 2.6.4

- **Renamed** parameter `$priority` of `log()` → `$level` in `Tracy\ILogger`, `Tracy\Logger`, `Tracy\Debugger`, `Tracy\FireLogger` and `Tracy\Bridges\Psr\PsrToTracyLoggerAdapter`; the old name was removed, which affects named arguments (1cd808a9)

## 2.6.3

- **Changed** `Tracy\Bridges\Psr\PsrToTracyLoggerAdapter::log()` now forwards a `Throwable` to the wrapped PSR logger as `Class: message #code in file:line`; previously only the exception message (45349ccc)

## 2.6.1

- **Replaced** `Tracy\Dumper::LIVE` with `Tracy\Dumper::LAZY`: lazy loading through JavaScript is controlled by `Tracy\Dumper::LAZY`, while `Tracy\Dumper::LIVE` now means collecting into the shared snapshot `Tracy\Dumper::$liveSnapshot` (ebd3f509)
- **Deprecated** `Tracy\Debugger::$maxLen`: use `Tracy\Debugger::$maxLength`; the property is declared again after having been removed in 2.6.0, but it is ignored and the old name is silently deprecated (46046a46)

## 2.6.0

- **Renamed** `Tracy\Debugger::$maxLen` → `Tracy\Debugger::$maxLength`; the old name was removed (c0d9d117)
- **Signature** `Tracy\BlueScreen::renderToFile()` now returns `bool`; previously `void`; affects subclasses overriding it (3030c0a8)
- **Signature** the default of the array parameter changed from `null` to `[]` in `Tracy\Dumper::dump()`, `Tracy\Dumper::toHtml()`, `Tracy\Dumper::toText()`, `Tracy\Dumper::toTerminal()`, `Tracy\Debugger::barDump()`, `Tracy\BlueScreen::highlightFile()` and `Tracy\BlueScreen::highlightPhp()`; passing `null` explicitly now throws `TypeError` (16703617)
- **Signature** `Tracy\Helpers::editorUri()`: the parameters `$search` and `$replace` are now `string` with the default `''`; previously `null` (daa115b6)
- **Signature** `Tracy\Dumper::__construct()` is private, so the class can no longer be instantiated; use its static methods (8358cd1f)
- **Signature** native types were added to parameters and return values; notably `Tracy\Bar::addPanel()`, `Tracy\BlueScreen::addPanel()`, `Tracy\BlueScreen::render()`, `Tracy\BlueScreen::renderToFile()`, `Tracy\Debugger::enable()`, `Tracy\Debugger::log()`, `Tracy\Logger::__construct()` and `Tracy\Logger::log()`; subclasses must declare matching types (daa115b6)
- **Changed** `Tracy\Debugger::barDump()` is rendered as a lazy dump loaded by JavaScript; previously as static HTML (de7fd36a)
- **Changed** `Tracy\Dumper::toHtml()` renders collapsed parts of arrays and objects as a lazy placeholder loaded by JavaScript; pass `Tracy\Dumper::LIVE => false` for the previous static HTML (a5333872)
- **Changed** `Tracy\Dumper::toHtml()` renders keys containing punctuation without quotes; previously they were quoted (b21853c1)
80 changes: 80 additions & 0 deletions dresscode.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use:
- nette
- modernizations

typeAnalysis: phpstan

correctness:
# Tracy is where dump() comes from
debugOutput: keep

paths:
- src
- tests
- tools

excludePaths:
- tests/**/fixtures*

fileExtensions:
- php
- phpt

imports: {grouping: {class: grouped}}

overrides:
-
paths: [src]
nameResolution: certain
use:
- compilerOptimizations
- deprecations

- # constants published in upper case, where the case is part of the API
paths:
- src/Tracy/Debugger/Debugger.php
- src/Tracy/Dumper/Dumper.php
- src/Tracy/Logger/ILogger.php
- src/Tracy/OutputDebugger/OutputDebugger.php
naming: {constant: keep}

- # $this_ holds the $this of a closure, a name PHP reserves
paths: [src/Tracy/Dumper/Exposer.php]
naming: {variable: keep}

- # the last fallback when neither mbstring nor iconv is loaded
paths: [src/Tracy/Helpers.php]
upgrading: {php: {deprecatedCall: keep}}

- # the bridge supports nette/di and nette/mail since 3.0, older than the installed ones
paths: [src/Bridges/Nette/TracyExtension.php]
upgrading: {libraries: {packages: ignored}, declarations: {deprecatedClass: keep, deprecatedMember: keep}}

- # promotion would move the properties to the end, which changes how a Value is dumped
paths: [src/Tracy/Dumper/Value.php]
upgrading: {syntax: {promotedProperties: keep}}

- # the source of these functions is what the expected output shows
paths:
- 'tests/Tracy/BlueScreen.renderAgent().output.phpt'
- tests/Tracy/Debugger.exception.fiber.html.phpt
- tests/Tracy/Debugger.exception.generator.html.phpt
- tests/Tracy/Debugger.exception.html.phpt
- tests/Tracy/Debugger.exception.nonhtml.phpt
correctness: {neverReturnType: keep}

- # the members are grouped by topic under divider comments
paths: [src/Tracy/Debugger/Debugger.php]
classes: {members: {order: keep}}

- # the deprecated property is still honored for BC
paths: [src/Tracy/BlueScreen/BlueScreen.php]
upgrading: {declarations: {deprecatedMember: keep}}

- # renaming the parameter would break calls naming the argument
paths: [src/Tracy/Logger/Logger.php]
classes: {overriding: {parameterName: keep}}

- # the test reads the page of a User Error
paths: [tests/Tracy/Debugger.error-in-toString.phpt]
upgrading: {php: {deprecatedCall: keep}}
Loading