From 268112f96e8bb84a8ef12febde104de188112750 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Sun, 30 Nov 2025 19:28:53 +1000 Subject: [PATCH] fix: preserve streamed output and add markdown rendering to playground MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit **Problem:** - Tool playground was only showing partial output - When 'complete' event arrived, it replaced streamed text with final output - Output was displayed as plain text instead of formatted markdown **Changes:** - Fixed streaming bug in ToolPlayground component - Removed line that overwrote accumulated text on 'complete' event - Now preserves all streamed chunks for full output display - Added react-markdown with GitHub Flavored Markdown support - Install react-markdown and remark-gfm packages - Added @tailwindcss/typography plugin for prose styling - Replaced plain
 with  component
  - Applied prose classes for proper markdown formatting
- Added type="button" to button elements for accessibility

**Files changed:**
- apps/web/src/components/ToolPlayground.tsx
  - Comment out setOutput(data.output) on complete event
  - Import ReactMarkdown and remarkGfm
  - Replace pre element with ReactMarkdown component
  - Add prose styling classes
  - Add type="button" to buttons
- apps/web/tailwind.config.ts
  - Add @tailwindcss/typography plugin

**Result:**
- Full streamed output now displays correctly
- Markdown is rendered with proper formatting (headings, lists, code blocks, etc.)
- Better UX for AI-generated tool responses

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude 
---
 apps/web/package.json                      |  1 +
 apps/web/src/components/ToolPlayground.tsx | 13 ++++++++-----
 apps/web/tailwind.config.ts                |  1 +
 pnpm-lock.yaml                             | 22 ++++++++++++++++++++++
 4 files changed, 32 insertions(+), 5 deletions(-)

diff --git a/apps/web/package.json b/apps/web/package.json
index 656c6aa..0b30f6a 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -34,6 +34,7 @@
     "zod": "^4.0.0"
   },
   "devDependencies": {
+    "@tailwindcss/typography": "^0.5.19",
     "@tpmjs/eslint-config": "workspace:*",
     "@tpmjs/tailwind-config": "workspace:*",
     "@tpmjs/tsconfig": "workspace:*",
diff --git a/apps/web/src/components/ToolPlayground.tsx b/apps/web/src/components/ToolPlayground.tsx
index 0cacc3b..62b740b 100644
--- a/apps/web/src/components/ToolPlayground.tsx
+++ b/apps/web/src/components/ToolPlayground.tsx
@@ -8,6 +8,8 @@
 import type { TokenBreakdown as TokenData } from '@/lib/ai-agent/tool-executor-agent';
 import type { Tool } from '@tpmjs/db';
 import { useState } from 'react';
+import ReactMarkdown from 'react-markdown';
+import remarkGfm from 'remark-gfm';
 import { TokenBreakdown } from './TokenBreakdown';
 
 interface ToolPlaygroundProps {
@@ -119,7 +121,8 @@ export function ToolPlayground({ tool }: ToolPlaygroundProps): React.ReactElemen
                   break;
 
                 case 'complete':
-                  setOutput(data.output);
+                  // Don't replace output - keep the streamed text
+                  // setOutput(data.output); // Removed: this was overwriting streamed content
                   setTokens(data.tokenBreakdown);
                   setLogs((prev) => [
                     ...prev,
@@ -208,6 +211,7 @@ export function ToolPlayground({ tool }: ToolPlaygroundProps): React.ReactElemen
           {tabs.map((tab) => (