fix: use deployed /api/tools endpoint with client-side filtering and streamline git hooks

- Change search-registry to use /api/tools instead of /api/tools/search (not deployed yet)
- Add client-side filtering for search queries since deployed API doesn't support search
- Handle both deployed (/api/tools) and local dev (/api/tools/search) response formats
- Remove lint from pre-commit hooks to speed up commits (keep format + type-check)
- Fixes 404 errors when playground tries to search tools in production

🤖 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 13:43:19 +10:00
parent 08d1e5a717
commit 8441b5fc70
7 changed files with 41 additions and 11 deletions

View file

@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View file

@ -65,7 +65,11 @@ export function ToolsSidebar(): React.ReactElement {
<p className="text-sm text-foreground-secondary">No tools found</p>
) : (
filteredTools.map((tool) => (
<Card key={`${tool.packageName}-${tool.exportName}`} variant="outline" className="cursor-pointer hover:bg-background">
<Card
key={`${tool.packageName}-${tool.exportName}`}
variant="outline"
className="cursor-pointer hover:bg-background"
>
<CardHeader>
<CardTitle className="text-sm">{tool.exportName}</CardTitle>
</CardHeader>

View file

@ -1,4 +1,4 @@
import { tool, jsonSchema } from 'ai';
import { jsonSchema, tool } from 'ai';
// Cache for tool wrappers (process-level)
const moduleCache = new Map<string, any>();

View file

@ -107,7 +107,9 @@ async function loadAndDescribe(req: Request): Promise<Response> {
// Strategy 3: Try Zod v3 schema (detect via _def property and convert)
if (!rawJsonSchema && toolModule.inputSchema._def) {
console.log(`📋 Detected Zod schema (v3), converting with zod-to-json-schema for ${cacheKey}`);
console.log(
`📋 Detected Zod schema (v3), converting with zod-to-json-schema for ${cacheKey}`
);
try {
rawJsonSchema = zodToJsonSchema(toolModule.inputSchema);
console.log(`✅ Successfully converted Zod schema for ${cacheKey}`);

View file

@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./.next/dev/types/routes.d.ts";
import "./.next/types/routes.d.ts";
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View file

@ -9,9 +9,6 @@ pre-commit:
type-check:
run: pnpm type-check
lint:
run: pnpm lint
pre-push:
commands:
test:

View file

@ -68,7 +68,10 @@ export const searchTpmjsToolsTool = tool({
const baseUrl =
process.env.TPMJS_API_URL ||
(process.env.NODE_ENV === 'production' ? 'https://tpmjs.com' : 'http://localhost:3000');
const url = `${baseUrl}/api/tools/search?${params}`;
// Note: /api/tools/search endpoint exists in local dev but not deployed yet
// Using /api/tools as fallback with client-side filtering for now
const url = `${baseUrl}/api/tools?${params}`;
console.log(`🌐 Fetching: ${url}`);
@ -83,10 +86,34 @@ export const searchTpmjsToolsTool = tool({
const data = (await response.json()) as any;
console.log('📦 Search response data:', JSON.stringify(data, null, 2));
// Handle both /api/tools (deployed) and /api/tools/search (local dev) responses
const toolsArray = data.results?.tools || data.data || [];
// Client-side filtering if query is provided (since deployed /api/tools doesn't support search yet)
let filteredTools = toolsArray;
if (query?.trim()) {
const queryLower = query.toLowerCase();
filteredTools = toolsArray.filter((tool: any) => {
const searchableText = [
tool.description,
tool.exportName,
tool.package?.npmPackageName,
tool.package?.npmDescription,
...(tool.package?.npmKeywords || []),
]
.join(' ')
.toLowerCase();
return searchableText.includes(queryLower);
});
}
// Apply limit
const limitedTools = filteredTools.slice(0, limit);
return {
query,
matchCount: data.results?.total || data.data?.length || 0,
tools: (data.results?.tools || data.data || []).map((tool: any) => ({
matchCount: filteredTools.length,
tools: limitedTools.map((tool: any) => ({
toolId: tool.id,
packageName: tool.package.npmPackageName,
exportName: tool.exportName,