- Add standardized ApiResponse interface with consistent structure
- Implement proper request validation with detailed error messages
- Add response metadata (version, timestamp, requestId, processingTime)
- Include proper HTTP status codes and error handling
- Add validation for pagination parameters (limit: 1-1000, offset: >=0)
- Add health status enum validation
- Include response headers (X-Request-ID, X-Processing-Time, Cache-Control)
- Improve error logging with structured context
- Add count field to pagination response
- Follow REST API industry standards and best practices
- Increase max limit from 50 to 1000 for bulk tool fetching
- Exclude large fields (npmReadme, npmAuthor, npmMaintainers) from API response
- Reduces payload size while maintaining all necessary tool metadata
- Executor now updates TPM.js database directly when loading tools
- Update /api/tools/update-schema to use packageName+exportName lookup
- Remove schema update logic from HLLM proxy (no longer needed)
- Add /api/tools/update-schema endpoint to TPM.js to update tool parameters
- When a tool is executed, fetch its schema from the executor
- Update TPM.js database with the discovered schema (async, non-blocking)
- This ensures /api/tools returns correct inputSchema for all tools
- Move env var injection to happen BEFORE cache check and factory function calls
- This ensures process.env is set when factory functions like Valyu's webSearch() read from it
- Skip caching factory-created tools since they may read env vars at creation time
- Fixes issue where Valyu tools fail with 'VALYU_API_KEY is required' even when key is provided
- Document POST /api/tools/execute/[...slug] endpoint
- Show URL formats (by tool ID and by package/export name)
- Document request body parameters (prompt, parameters)
- List SSE events (chunk, tokens, complete, error)
- Add curl and JavaScript code examples
- Document rate limiting (10 requests/minute per IP)
- Add to sidebar navigation
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Parse CHANGELOG.md files from SDK and tool packages at build time
- Display version history with major/minor/patch badges
- Group by SDK packages (ui, types, utils, env) and Tool packages
- Add changelog link to navigation header
- Fix unescaped apostrophes in docs page
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add modern SVG favicon with TPMJS "T" logo
- Add apple-touch-icon for iOS devices
- Update metadata to reference new icons
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Launch checklist implementation:
- Add Privacy Policy page (/privacy) with GDPR compliance
- Add Terms of Service page (/terms)
- Add custom 404 and error pages with helpful navigation
- Add FAQ page (/faq) covering common questions
- Add SEO meta tags with OpenGraph/Twitter cards
- Add JSON-LD structured data (Organization, WebSite, SoftwareApplication)
- Add sitemap.ts and robots.ts for search engines
- Add security headers (HSTS, CSP, X-Frame-Options) in vercel.json
- Add security.txt at /.well-known/security.txt
- Add API rate limiting (100 req/min default, 20 req/min strict)
- Add empty states in tool search for better UX
- Update AppHeader with FAQ link
- Update AppFooter with Privacy/Terms links
- Update biome.json to allow dangerouslySetInnerHTML for JSON-LD in page files
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- ChatInput: Redesign with rounded container, better button alignment, helper text
- ChatHeader: Consistent bg-surface, refined typography and spacing
- ChatMessages: Improved empty state with icon badge and suggestion box
- MessageBubble: Cleaner message cards, collapsible tool input/output, status badges
- ToolsSidebar: Header/content separation, keyboard accessibility, wider width
- SettingsSidebar: Matching header style, dashed empty state, footer info section
All components now use consistent theme tokens (bg-surface, bg-background, etc.)
and follow the same visual patterns for headers, cards, and spacing.
- Paginate through all tools from registry API (was limited to 20)
- Add 'Hide broken tools' checkbox (enabled by default)
- Filter out tools with BROKEN import or execution health
- Make tooltips more verbose with detailed explanations for each node
- Add tooltip for 'Your Tools' node
- Change GitHub button labels from 'GitHub' to 'Source'
- Fix missing </p> closing tags
- Create SDKFlowDiagram component with animated D3 graphics
- Add flowing particle animations along connection paths
- Add hover interactions with tooltips for each node
- Add entrance animations with staggered timing
- Add subtle glow effects and shadows
- Responsive design that adapts to screen width
- Sleek minimal black and white aesthetic with depth effects
- Replace deprecated Agent class with streamText function
- Add @ai-sdk/anthropic import for model provider
- Change instructions to system parameter
- Add example prompt showing tool usage
- Create @tpmjs/registrySearch package for searching tool registry
- Create @tpmjs/registryExecute package for executing tools via sandbox
- Support self-hosted registries via TPMJS_API_URL and TPMJS_EXECUTOR_URL env vars
- Add /sdk documentation page with usage examples and architecture
- Add SDK link to navigation menu
- Include design doc for registry SDK architecture
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Same issue as startTime - these variables were destructured inside the
try block but referenced in the catch block for health reporting. If
JSON parsing or any early error occurred, the catch block would crash
with 'packageName is not defined'.
Now declares them with 'unknown' defaults before try, then assigns
the actual values inside.
The startTime variable was declared inside the try block but referenced
in the catch block, causing 'startTime is not defined' errors when
exceptions occurred before line 404 (e.g., during req.json() parsing).
Moving the declaration before the try ensures it's in scope for the
catch block's executionTimeMs calculation.
Health status is now reported from the executor - the single point where
all tools run. This ensures consistent health tracking regardless of
client (playground, direct API, etc).
- Add reportToolHealth() to Railway executor
- Report success/failure after every tool execution
- Remove health reporting from playground (executor handles it)
- Executor calls /api/tools/report-health which has all the logic
- Remove direct DB updates from playground
- Add /api/tools/report-health endpoint with all health logic
- Playground now reports results to web app API
- All env var / validation error detection is in one place
- Health status updates based on execution success and error type
- Fix type errors with proper null checks
The executor returns HTTP 500 for all tool errors, including missing env vars.
Before: 500 response = BROKEN
After: Check error message for env/validation patterns before marking BROKEN
This ensures tools that require API keys (like @parallel-web/ai-sdk-tools)
show importHealth: HEALTHY since the tool loads correctly - it just needs config.
Some AI SDK tools (like @parallel-web/ai-sdk-tools) expect execute(params, context)
where context contains { abortSignal, messages, toolCallId }. Previously we only
passed params which caused 'Cannot destructure abortSignal' errors.
Also:
- Improved playground system prompt for better tool execution
- Playground /api/tools now proxies to web app with response transformation
- Added broken-tools.md documenting tool failure categories
Co-Authored-By: Claude <noreply@anthropic.com>
Removes importHealth, executionHealth, healthCheckError, and lastHealthCheck
fields from tool search results. Models were refusing to call tools marked
as BROKEN, even when the issue was just a missing env var.
Co-Authored-By: Claude <noreply@anthropic.com>
Simplify execution health check logic:
- If executor responds (2xx or 4xx), tool is HEALTHY
- Only mark BROKEN for 5xx errors or network/timeout failures
- Validation errors (URL format, missing fields) mean tool IS working
- Remove brittle pattern matching for specific error messages
The previous approach tried to match specific error patterns to determine
if an error was "acceptable". This was fragile. The new approach:
- Import check: can we load and describe the tool?
- Execution check: did the tool execute at all?
If a tool throws a validation error, it executed successfully - it's
correctly rejecting invalid test input. Only infrastructure failures
(executor down, network timeout) indicate a truly broken tool.
Tools that reject invalid test inputs (like invalid URLs) are actually
working correctly - they're validating input as expected. Previously
the health check marked these as BROKEN because the test used dummy
values like 'test' which failed Zod validation.
Now input validation errors (invalid URL, invalid format, type mismatch,
etc.) are treated as HEALTHY, similar to how we already treat missing
environment variables.
When a tool is marked as BROKEN but executes successfully in the
playground, update its health status to HEALTHY. This ensures
stale health check data doesn't persist when tools are working.
Also fixes noImplicitAnyLet lint error by refactoring to const.
- Add formatTimeAgo utility function for relative time display
- Show "Published X ago" at bottom of each tool card using npmPublishedAt
- Center CodeBlock copy button vertically for better alignment
- Update Tool interface to include npmPublishedAt from API
- Add eslint-disable and biome-ignore for a11y rules in tool-search page
- Escape quotes in how-it-works page for react/no-unescaped-entities
- Exclude Deno-based railway-executor from dependency cruiser
- Extract sortTools helper to reduce cognitive complexity
- Add sortBy state with 'downloads' as default (most downloaded)
- Add 'recent' sort option to sort by createdAt
- Sorting keeps broken tools at bottom regardless of sort order
- Add createdAt field to Tool interface
- Update interface to match actual API response (Tool has package relation)
- Fix package name display in installation section (was showing undefined)
- Add step-by-step usage instructions:
1. Install package
2. Import the tool
3. Use with AI SDK (generateText example)
- Update all sidebar sections to use pkg.* for package-level data
- Remove deprecated tpmjsMetadata references
- Clean up unused Tags section
- Replace orbital spinner with 3x3 grid of blocks
- Diagonal wave animation matches dithering aesthetic
- Sharp squares, no rounded corners (brutalist)
- Inline horizontal layout with monospace text
- Consistent styling across all loading states
The new loader evokes "tools being constructed" - fitting
for a tool registry. Uses staggered opacity/scale animation
creating a wave pattern across the grid.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Create new Spinner component with three orbiting dots
- Use inline CSS keyframes for reliable animation
- Support multiple size variants (xs, sm, md, lg, xl)
- Increase spinner sizes in loading states across the app
- Add biome-ignore directives for pre-existing lint issues
- Fix accessibility: change span onClick to button element
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Remove Tabs component and activeTab state
- Show all tools in a single grid view
- Simplify API calls by removing unnecessary count fetches
- Add missing Script import in layout.tsx
Shows duration for text generation and tool execution in chat messages.
Tracks when each part starts and completes, displays timing in the UI.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Ensures fresh data is always fetched from database on homepage load.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Simplified Docker configuration to use manually mounted volume at /data
instead of complex pre-caching strategy. This approach:
- Uses ENV DENO_DIR=/data to point to manually created Railway volume
- Keeps Dockerfile simple and maintainable
- Adds --allow-read/--allow-write permissions for cache access
- Removes railway.toml volume configuration (manual setup instead)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>