diff --git a/README.md b/README.md
index d89bacc..924044e 100644
--- a/README.md
+++ b/README.md
@@ -6,11 +6,11 @@
[](https://php.net)
[](https://laravel.com)
[](LICENSE)
-[](#testing)
+[](#testing)
TraceReplay is not a standard error logger. It is a full-fledged **execution tracer** that captures every step of your complex workflows, reconstructs them with a waterfall timeline, and offers one-click AI debugging when things go wrong.
-
+
---
@@ -47,11 +47,10 @@ TraceReplay is not a standard error logger. It is a full-fledged **execution tra
composer require iazaran/trace-replay
```
-Publish the config and migrations:
+Publish the config:
```bash
php artisan vendor:publish --tag=trace-replay-config
-php artisan vendor:publish --tag=trace-replay-migrations
```
Run migrations:
@@ -60,14 +59,18 @@ Run migrations:
php artisan migrate
```
-> **Note:** Migrations use `json` columns and support `decimal` precision for timings, compatible with MySQL 5.7+, MariaDB, PostgreSQL, and SQLite.
+> **Note:** Migrations run automatically without publishing. They use `json` columns and `decimal` precision for timings, compatible with MySQL 5.7+, MariaDB, PostgreSQL, and SQLite.
-#### Publishing Views (Optional)
+#### Publishing Views
+
+To customize the dashboard UI:
```bash
php artisan vendor:publish --tag=trace-replay-views
```
+This copies the Blade templates to `resources/views/vendor/trace-replay/` where you can customize the layout, colors, or add your own branding.
+
---
## ⚙️ Configuration
@@ -260,14 +263,19 @@ Drop the `` Blade component into your layout for ins
Access the built-in dashboard at `https://your-app.com/trace-replay`.
+
+
**Features:**
- **Waterfall timeline** — visual bars show each step's exact duration relative to the total trace
- **Live stats** — auto-refreshing counters (total traces, failed, avg duration)
- **Search & filter** — filter by name, IP, user ID; toggle failed-only view
+- **Date range filter** — quickly filter traces by today, yesterday, last 7 days, or last 30 days
- **Step inspector** — syntax-highlighted JSON for request payload, response payload, and state snapshot
- **Replay engine** — re-execute any HTTP step and view a structural JSON diff
- **AI Fix Prompt** — one-click prompt ready for Cursor, ChatGPT, or Claude
+
+
### Securing the Dashboard
Add authentication or authorization middleware in `config/trace-replay.php`:
@@ -302,7 +310,32 @@ For any failed trace the dashboard shows an **AI Fix Prompt** button that genera
- Request/response payloads (sensitive fields masked)
- Step-by-step state snapshots
-Paste this into any LLM. Optionally configure your OpenAI key and click **"Ask AI"** to get an answer directly in the dashboard.
+### No API Key Required
+
+The AI prompt feature works **without any API key**. Copy the generated prompt and paste it into ChatGPT, Claude, or any other AI assistant.
+
+### Optional: Direct AI Integration
+
+For a seamless experience, configure an AI driver to get answers directly in the dashboard:
+
+```env
+# OpenAI (default)
+TRACE_REPLAY_AI_DRIVER=openai
+TRACE_REPLAY_AI_KEY=sk-your-openai-key
+TRACE_REPLAY_AI_MODEL=gpt-4o
+
+# Or Anthropic Claude
+TRACE_REPLAY_AI_DRIVER=anthropic
+TRACE_REPLAY_AI_KEY=sk-ant-your-key
+TRACE_REPLAY_AI_MODEL=claude-3-5-sonnet-latest
+
+# Or Ollama (local, no API key needed)
+TRACE_REPLAY_AI_DRIVER=ollama
+TRACE_REPLAY_AI_MODEL=llama3
+TRACE_REPLAY_AI_BASE_URL=http://localhost:11434/api/generate
+```
+
+With a key configured, clicking **"Ask AI"** sends the prompt to your chosen AI provider and displays the response in the dashboard.
---
@@ -371,7 +404,7 @@ composer install
./vendor/bin/pest
```
-101 tests, 200 assertions. The test suite covers:
+104 tests, 208 assertions. The test suite covers:
- Trace lifecycle (start, step, checkpoint, context, end, duration precision)
- Error capturing, step ordering, DB query tracking
- Model scopes (`failed`, `successful`, `search`)
diff --git a/art/dashboard.png b/art/dashboard.png
new file mode 100644
index 0000000..b84e4d4
Binary files /dev/null and b/art/dashboard.png differ
diff --git a/art/details.png b/art/details.png
new file mode 100644
index 0000000..deeb7ab
Binary files /dev/null and b/art/details.png differ
diff --git a/database/migrations/2024_01_01_000000_create_trace_replay_tables.php b/database/migrations/2024_01_01_000000_create_trace_replay_tables.php
index 5a58dc8..f91b226 100644
--- a/database/migrations/2024_01_01_000000_create_trace_replay_tables.php
+++ b/database/migrations/2024_01_01_000000_create_trace_replay_tables.php
@@ -6,7 +6,7 @@
return new class extends Migration
{
- public function up()
+ public function up(): void
{
Schema::create('tr_workspaces', function (Blueprint $table) {
$table->uuid('id')->primary();
@@ -27,10 +27,14 @@ public function up()
$table->uuid('id')->primary();
$table->uuid('project_id')->nullable()->index();
$table->string('name')->nullable();
+ $table->string('type', 20)->default('http'); // http, job, command, livewire
$table->json('tags')->nullable();
- $table->float('duration_ms')->nullable();
+ $table->string('trace_parent')->nullable()->index(); // W3C trace context
+ $table->decimal('duration_ms', 12, 2)->nullable();
+ $table->unsignedBigInteger('peak_memory_usage')->nullable();
$table->string('status')->default('processing'); // processing, success, error
$table->unsignedSmallInteger('http_status')->nullable();
+ $table->text('error_reason')->nullable();
$table->string('user_id')->nullable()->index();
$table->string('user_type')->nullable();
$table->string('ip_address', 45)->nullable();
@@ -40,6 +44,9 @@ public function up()
$table->timestamps();
$table->foreign('project_id')->references('id')->on('tr_projects')->onDelete('set null');
+ $table->index('status');
+ $table->index('started_at');
+ $table->index(['type', 'started_at']);
});
Schema::create('tr_trace_steps', function (Blueprint $table) {
@@ -53,10 +60,17 @@ public function up()
$table->json('response_payload')->nullable();
$table->json('state_snapshot')->nullable();
- $table->float('duration_ms')->nullable();
+ $table->decimal('duration_ms', 12, 2)->nullable();
$table->unsignedBigInteger('memory_usage')->nullable(); // bytes
$table->unsignedInteger('db_query_count')->nullable();
- $table->float('db_query_time_ms')->nullable();
+ $table->decimal('db_query_time_ms', 12, 2)->nullable();
+ $table->json('db_queries')->nullable(); // Detailed SQL tracking
+ $table->json('cache_calls')->nullable();
+ $table->unsignedInteger('cache_hit_count')->default(0);
+ $table->unsignedInteger('cache_miss_count')->default(0);
+ $table->json('http_calls')->nullable();
+ $table->json('mail_calls')->nullable();
+ $table->json('log_calls')->nullable();
$table->string('status')->default('success'); // success, error, checkpoint
$table->text('error_reason')->nullable();
@@ -66,7 +80,7 @@ public function up()
});
}
- public function down()
+ public function down(): void
{
Schema::dropIfExists('tr_trace_steps');
Schema::dropIfExists('tr_traces');
diff --git a/database/migrations/2026_04_06_000001_enhance_trace_replay_tables.php b/database/migrations/2026_04_06_000001_enhance_trace_replay_tables.php
deleted file mode 100644
index 0557220..0000000
--- a/database/migrations/2026_04_06_000001_enhance_trace_replay_tables.php
+++ /dev/null
@@ -1,93 +0,0 @@
-isDoctrineAvailable();
-
- // tr_traces enhancements
- Schema::table('tr_traces', function (Blueprint $table) use ($canChangeColumns) {
- // Recommendation 17: Trace parent for W3C context
- if (! Schema::hasColumn('tr_traces', 'trace_parent')) {
- $table->string('trace_parent')->after('tags')->nullable()->index();
- }
-
- // Phase 2: Memory tracking
- if (! Schema::hasColumn('tr_traces', 'peak_memory_usage')) {
- $table->unsignedBigInteger('peak_memory_usage')->after('duration_ms')->nullable();
- }
-
- // Recommendation 30: Indexes for performance
- // We use try-catch or individual checks because some DBs might already have these
- try {
- $table->index('status');
- $table->index('started_at');
- } catch (Throwable $e) {
- // Ignore if index already exists
- }
-
- // Recommendation 29: Change precision of float to decimal
- if ($canChangeColumns) {
- $table->decimal('duration_ms', 12, 2)->nullable()->change();
- }
- });
-
- // tr_trace_steps enhancements
- Schema::table('tr_trace_steps', function (Blueprint $table) use ($canChangeColumns) {
- // Recommendation 13: Detailed SQL tracking
- if (! Schema::hasColumn('tr_trace_steps', 'db_queries')) {
- $table->json('db_queries')->after('db_query_time_ms')->nullable();
- }
-
- // Recommendation 6: Cache tracking
- if (! Schema::hasColumn('tr_trace_steps', 'cache_calls')) {
- $table->json('cache_calls')->after('db_queries')->nullable();
- $table->unsignedInteger('cache_hit_count')->after('cache_calls')->default(0);
- $table->unsignedInteger('cache_miss_count')->after('cache_hit_count')->default(0);
- }
-
- // Recommendation 7: HTTP tracking
- if (! Schema::hasColumn('tr_trace_steps', 'http_calls')) {
- $table->json('http_calls')->after('cache_miss_count')->nullable();
- }
-
- // Recommendation 14: Mail/Notification tracking
- if (! Schema::hasColumn('tr_trace_steps', 'mail_calls')) {
- $table->json('mail_calls')->after('http_calls')->nullable();
- }
-
- // Phase 3: Application logs
- if (! Schema::hasColumn('tr_trace_steps', 'log_calls')) {
- $table->json('log_calls')->after('mail_calls')->nullable();
- }
-
- // Recommendation 29: Change precision of float to decimal
- if ($canChangeColumns) {
- $table->decimal('duration_ms', 12, 2)->nullable()->change();
- $table->decimal('db_query_time_ms', 12, 2)->nullable()->change();
- }
- });
- }
-
- public function down(): void
- {
- if (DB::getDriverName() !== 'sqlite') {
- Schema::table('tr_traces', function (Blueprint $table) {
- $table->dropColumn(['trace_parent', 'peak_memory_usage']);
- $table->dropIndex(['status']);
- $table->dropIndex(['started_at']);
- });
-
- Schema::table('tr_trace_steps', function (Blueprint $table) {
- $table->dropColumn(['db_queries', 'cache_calls', 'cache_hit_count', 'cache_miss_count', 'http_calls', 'mail_calls', 'log_calls']);
- });
- }
- }
-};
diff --git a/docs/index.html b/docs/index.html
index 8c23e05..bb086ff 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -159,13 +159,13 @@
Migrations use json columns for full MySQL, MariaDB, PostgreSQL, and SQLite compatibility.
+
Migrations run automatically without publishing. They use json columns for full MySQL, MariaDB, PostgreSQL, and SQLite compatibility.
-
Publishing Views (Recommended)
+
Publishing Views
TraceReplay ships with a polished, dark-themed dashboard featuring a waterfall timeline, syntax-highlighted JSON inspector, and live stats — all styled and ready to use out of the box. Publishing the views lets you customise the layout, colours, or add your own branding:
This copies the Blade templates to resources/views/vendor/trace-replay/ where you can edit them freely. The package will automatically use your published versions instead of its built-in views.
Three AI drivers are supported out of the box: OpenAI (default), Anthropic Claude, and Ollama (local models). Configure via TRACE_REPLAY_AI_DRIVER and TRACE_REPLAY_AI_KEY, then click "Ask AI" to get an answer directly in the dashboard.
+
+
No API Key Required
+
The AI prompt feature works without any API key. Simply copy the generated prompt and paste it into ChatGPT, Claude, or any other AI assistant of your choice.
+
+
Optional: Direct AI Integration
+
For a seamless experience, configure an AI driver to get answers directly in the dashboard. Three drivers are supported:
+
# OpenAI (default)
+TRACE_REPLAY_AI_DRIVER=openai
+TRACE_REPLAY_AI_KEY=sk-your-openai-key
+TRACE_REPLAY_AI_MODEL=gpt-4o
+
+# Or Anthropic Claude
+TRACE_REPLAY_AI_DRIVER=anthropic
+TRACE_REPLAY_AI_KEY=sk-ant-your-key
+TRACE_REPLAY_AI_MODEL=claude-3-5-sonnet-latest
+
+# Or Ollama (local, no API key needed)
+TRACE_REPLAY_AI_DRIVER=ollama
+TRACE_REPLAY_AI_MODEL=llama3
+TRACE_REPLAY_AI_BASE_URL=http://localhost:11434/api/generate
+
With a key configured, clicking "Ask AI" sends the prompt to your chosen provider and displays the response directly in the dashboard.
MCP / AI-Agent JSON-RPC API
Autonomous agents can query TraceReplay over JSON-RPC 2.0 at POST /api/trace-replay/mcp.
@@ -386,7 +406,7 @@
Data Retention
Testing
./vendor/bin/pest
-
The test suite (101 tests, 200 assertions) covers the full engine lifecycle, model scopes & accessors, payload masking (PII, case-insensitive), AI prompt & notification services, dashboard UI, MCP JSON-RPC API, middleware (trace & auth), replay engine, log call tracking, TraceReplayFake assertions, Artisan commands (prune & export with validation), and Blade components — all using an in-memory SQLite database.
+
The test suite (104 tests, 208 assertions) covers the full engine lifecycle, model scopes & accessors, payload masking (PII, case-insensitive), AI prompt & notification services, dashboard UI with date range filters, MCP JSON-RPC API, middleware (trace & auth), replay engine, log call tracking, TraceReplayFake assertions, Artisan commands (prune & export with validation), and Blade components — all using an in-memory SQLite database.