feat: add playground sidebars with dynamic tools and env var management

Left Sidebar:
- Create /api/tools endpoint to fetch tools from registry
- Update ToolsSidebar to fetch and display tools dynamically
- Add filter input for searching tools by name/description/category
- Fix interface to use packageName/exportName from search registry

Right Sidebar:
- Create SettingsSidebar with environment variable management
- Add localStorage persistence for env vars
- Implement password masking for values
- Export useEnvVars() hook for accessing env vars

Environment Variable Forwarding:
- Update useChat hook to read and forward env vars to API
- Update chat route to extract env vars from request body
- Update dynamic-tool-loader to accept and forward env vars
- Update Railway executor to inject env vars into Deno environment
- Complete chain: localStorage → client → chat → Railway → Deno.env

Bug Fixes:
- Fix undefined property errors in tool detail page
- Add optional chaining for npmDownloadsLastMonth and qualityScore

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

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ajax Davis 2025-12-04 11:00:20 +10:00
parent c18d1b7ea6
commit f127b47f08
9 changed files with 311 additions and 55 deletions

View file

@ -339,7 +339,7 @@ export default function ToolDetailPage({
<div>
<p className="text-sm text-foreground-secondary mb-1">Downloads/month</p>
<p className="text-2xl font-bold text-foreground">
{tool.npmDownloadsLastMonth.toLocaleString()}
{tool.npmDownloadsLastMonth?.toLocaleString() || '0'}
</p>
</div>
{tool.githubStars !== null && (
@ -353,11 +353,11 @@ export default function ToolDetailPage({
<div>
<p className="text-sm text-foreground-secondary mb-2">Quality Score</p>
<ProgressBar
value={Number.parseFloat(tool.qualityScore) * 100}
value={(tool.qualityScore ? Number.parseFloat(tool.qualityScore) : 0) * 100}
variant={
Number.parseFloat(tool.qualityScore) >= 0.7
tool.qualityScore && Number.parseFloat(tool.qualityScore) >= 0.7
? 'success'
: Number.parseFloat(tool.qualityScore) >= 0.5
: tool.qualityScore && Number.parseFloat(tool.qualityScore) >= 0.5
? 'primary'
: 'warning'
}