Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 41 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@
[![PHP](https://img.shields.io/badge/PHP-8.2%2B-blue)](https://php.net)
[![Laravel](https://img.shields.io/badge/Laravel-10%20|%2011%20|%2012%20|%2013-red)](https://laravel.com)
[![License: MIT](https://img.shields.io/badge/License-MIT-green)](LICENSE)
[![Tests](https://img.shields.io/badge/tests-101%20passing-brightgreen)](#testing)
[![Tests](https://img.shields.io/badge/tests-104%20passing-brightgreen)](#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.

![TraceReplay Dashboard](art/preview.png)
![TraceReplay](art/preview.png)

---

Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down Expand Up @@ -260,14 +263,19 @@ Drop the `<x-trace-replay-trace-bar />` Blade component into your layout for ins

Access the built-in dashboard at `https://your-app.com/trace-replay`.

![Dashboard](art/dashboard.png)

**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

![Trace Details](art/details.png)

### Securing the Dashboard

Add authentication or authorization middleware in `config/trace-replay.php`:
Expand Down Expand Up @@ -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.

---

Expand Down Expand Up @@ -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`)
Expand Down
Binary file added art/dashboard.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/details.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand All @@ -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) {
Expand All @@ -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();

Expand All @@ -66,7 +80,7 @@ public function up()
});
}

public function down()
public function down(): void
{
Schema::dropIfExists('tr_trace_steps');
Schema::dropIfExists('tr_traces');
Expand Down

This file was deleted.

34 changes: 27 additions & 7 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,13 @@ <h1 id="introduction" class="text-4xl">TraceReplay Documentation</h1>

<h2 id="installation">Installation</h2>
<pre><code class="language-bash">composer require iazaran/trace-replay</code></pre>
<p>Publish config and migrations:</p>
<pre><code class="language-bash">php artisan vendor:publish --tag=trace-replay-config
php artisan vendor:publish --tag=trace-replay-migrations</code></pre>
<p>Publish the config:</p>
<pre><code class="language-bash">php artisan vendor:publish --tag=trace-replay-config</code></pre>
<p>Run migrations:</p>
<pre><code class="language-bash">php artisan migrate</code></pre>
<p>Migrations use <code>json</code> columns for full MySQL, MariaDB, PostgreSQL, and SQLite compatibility.</p>
<p>Migrations run automatically without publishing. They use <code>json</code> columns for full MySQL, MariaDB, PostgreSQL, and SQLite compatibility.</p>

<h3>Publishing Views (Recommended)</h3>
<h3>Publishing Views</h3>
<p>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:</p>
<pre><code class="language-bash">php artisan vendor:publish --tag=trace-replay-views</code></pre>
<p>This copies the Blade templates to <code>resources/views/vendor/trace-replay/</code> where you can edit them freely. The package will automatically use your published versions instead of its built-in views.</p>
Expand Down Expand Up @@ -352,7 +352,27 @@ <h2 id="ai-debugging">AI Debugging</h2>
<li>Request/response payloads (sensitive fields masked)</li>
<li>Step-by-step state snapshots</li>
</ul>
<p>Three AI drivers are supported out of the box: <strong>OpenAI</strong> (default), <strong>Anthropic Claude</strong>, and <strong>Ollama</strong> (local models). Configure via <code>TRACE_REPLAY_AI_DRIVER</code> and <code>TRACE_REPLAY_AI_KEY</code>, then click <strong>"Ask AI"</strong> to get an answer directly in the dashboard.</p>

<h3>No API Key Required</h3>
<p>The AI prompt feature works <strong>without any API key</strong>. Simply copy the generated prompt and paste it into ChatGPT, Claude, or any other AI assistant of your choice.</p>

<h3>Optional: Direct AI Integration</h3>
<p>For a seamless experience, configure an AI driver to get answers directly in the dashboard. Three drivers are supported:</p>
<pre><code class="language-bash"># 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</code></pre>
<p>With a key configured, clicking <strong>"Ask AI"</strong> sends the prompt to your chosen provider and displays the response directly in the dashboard.</p>

<h2 id="mcp-api">MCP / AI-Agent JSON-RPC API</h2>
<p>Autonomous agents can query TraceReplay over JSON-RPC 2.0 at <code>POST /api/trace-replay/mcp</code>.</p>
Expand Down Expand Up @@ -386,7 +406,7 @@ <h2 id="retention">Data Retention</h2>

<h2 id="testing">Testing</h2>
<pre><code class="language-bash">./vendor/bin/pest</code></pre>
<p>The test suite (101 tests, 200 assertions) covers the full engine lifecycle, model scopes &amp; accessors, payload masking (PII, case-insensitive), AI prompt &amp; notification services, dashboard UI, MCP JSON-RPC API, middleware (trace &amp; auth), replay engine, log call tracking, <code>TraceReplayFake</code> assertions, Artisan commands (prune &amp; export with validation), and Blade components — all using an in-memory SQLite database.</p>
<p>The test suite (104 tests, 208 assertions) covers the full engine lifecycle, model scopes &amp; accessors, payload masking (PII, case-insensitive), AI prompt &amp; notification services, dashboard UI with date range filters, MCP JSON-RPC API, middleware (trace &amp; auth), replay engine, log call tracking, <code>TraceReplayFake</code> assertions, Artisan commands (prune &amp; export with validation), and Blade components — all using an in-memory SQLite database.</p>

<hr class="my-12 border-zinc-800">
<p class="text-sm text-center text-zinc-500">TraceReplay &copy; 2026 &mdash; MIT License</p>
Expand Down
Loading
Loading