diff --git a/apps/playground/src/app/api/chat/route.ts b/apps/playground/src/app/api/chat/route.ts index 243368e..bd0b07d 100644 --- a/apps/playground/src/app/api/chat/route.ts +++ b/apps/playground/src/app/api/chat/route.ts @@ -10,6 +10,13 @@ import { } from '~/lib/dynamic-tool-loader'; import { loadAllTools, sanitizeToolName } from '~/lib/tool-loader'; +interface ToolSearchResult { + query: string; + matchCount: number; + // biome-ignore lint/suspicious/noExplicitAny: Dynamic tool registry result type - tools have varying shapes + tools: any[]; +} + export const runtime = 'nodejs'; export const dynamic = 'force-dynamic'; export const maxDuration = 300; // 5 minutes for complex tool loading @@ -22,6 +29,7 @@ const conversationStates = new Map }> * POST /api/chat * Chat with AI agent that can execute TPMJS tools */ +// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Complex chat handler with tool loading requires this complexity export async function POST(request: NextRequest) { try { const body = await request.json(); @@ -89,6 +97,7 @@ export async function POST(request: NextRequest) { let userQuery = ''; if (lastMessage?.role === 'user') { // Extract text from message parts + // biome-ignore lint/suspicious/noExplicitAny: UIMessage.parts type varies by AI SDK version const parts = (lastMessage as any).parts || []; for (const part of parts) { if (part.type === 'text') { @@ -104,6 +113,7 @@ export async function POST(request: NextRequest) { .slice(-3) .map((msg) => { // Extract text from parts + // biome-ignore lint/suspicious/noExplicitAny: UIMessage.parts type varies by AI SDK version const parts = (msg as any).parts || []; for (const part of parts) { if (part.type === 'text') { @@ -129,27 +139,26 @@ export async function POST(request: NextRequest) { limit: 5, // Get top 5 relevant tools recentMessages: recentUserMessages, }, + // biome-ignore lint/suspicious/noExplicitAny: AI SDK execute context type is complex {} as any ); // Type assertion: searchTpmjsToolsTool returns direct result, not AsyncIterable - const searchResult = result as { - query: string; - matchCount: number; - tools: any[]; - }; + const searchResult = result as ToolSearchResult; console.log(`📦 Found ${searchResult.matchCount} matching tools`); if (searchResult.tools && searchResult.tools.length > 0) { console.log( '🔧 Tools found:', + // biome-ignore lint/suspicious/noExplicitAny: Dynamic tool registry result type searchResult.tools.map((t: any) => `${t.packageName}/${t.name}`) ); // Dynamically load tools from esm.sh console.log(`📥 Loading ${searchResult.tools.length} tools dynamically...`); + // biome-ignore lint/suspicious/noExplicitAny: Dynamic tool registry result type const toolsToLoad = searchResult.tools.map((meta: any) => ({ packageName: meta.packageName, name: meta.name, diff --git a/apps/playground/src/components/chat/MessageBubble.tsx b/apps/playground/src/components/chat/MessageBubble.tsx index 4fbd54d..45a03b8 100644 --- a/apps/playground/src/components/chat/MessageBubble.tsx +++ b/apps/playground/src/components/chat/MessageBubble.tsx @@ -38,6 +38,7 @@ export function MessageBubble({ if (!message.parts || isUser) return; const currentPartsKey = JSON.stringify( + // biome-ignore lint/suspicious/noExplicitAny: UIMessage.parts type varies by AI SDK version message.parts.map((p: any) => ({ type: p.type, id: p.toolCallId || p.type, @@ -55,6 +56,8 @@ export function MessageBubble({ setPartTimings((prev) => { const updated = new Map(prev); + // biome-ignore lint/suspicious/noExplicitAny: UIMessage.parts type varies by AI SDK version + // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Complex part timing logic for streaming messages message.parts?.forEach((part: any, idx: number) => { const partKey = part.toolCallId || `${part.type}-${idx}`; const existing = updated.get(partKey); @@ -85,6 +88,7 @@ export function MessageBubble({ }, [message.parts, isStreaming, isUser]); // Get timing for a specific part + // biome-ignore lint/suspicious/noExplicitAny: UIMessage.parts type varies by AI SDK version const getPartTiming = (part: any, idx: number): PartTiming | undefined => { const partKey = part.toolCallId || `${part.type}-${idx}`; return partTimings.get(partKey); @@ -140,7 +144,7 @@ export function MessageBubble({ // Render tool calls (type starts with 'tool-') if (part.type.startsWith('tool-')) { const toolName = part.type.replace('tool-', ''); - // Type assertion for tool parts + // biome-ignore lint/suspicious/noExplicitAny: Tool part properties vary by AI SDK version const toolPart = part as any; const timing = getPartTiming(part, idx); const isResult = toolPart.state === 'result'; diff --git a/apps/railway-executor/server.ts b/apps/railway-executor/server.ts index 481c683..66b536f 100644 --- a/apps/railway-executor/server.ts +++ b/apps/railway-executor/server.ts @@ -203,6 +203,7 @@ function sanitizeJsonSchema(schema: any): any { // Sanitize anyOf/oneOf/allOf for (const key of ['anyOf', 'oneOf', 'allOf']) { if (Array.isArray(sanitized[key])) { + // biome-ignore lint/suspicious/noExplicitAny: JSON Schema types are dynamic sanitized[key] = sanitized[key].map((s: any) => sanitizeJsonSchema(s)); } } @@ -414,12 +415,16 @@ async function loadAndDescribe(req: Request): Promise { const zod = await import('https://esm.sh/zod@4'); if (zod.toJSONSchema) { rawJsonSchema = zod.toJSONSchema(toolModule.inputSchema); - console.log(`✅ Successfully converted Zod v4 schema using z.toJSONSchema for ${cacheKey}`); + console.log( + `✅ Successfully converted Zod v4 schema using z.toJSONSchema for ${cacheKey}` + ); } else if (zod.default?.toJSONSchema) { rawJsonSchema = zod.default.toJSONSchema(toolModule.inputSchema); - console.log(`✅ Successfully converted Zod v4 schema using z.default.toJSONSchema for ${cacheKey}`); + console.log( + `✅ Successfully converted Zod v4 schema using z.default.toJSONSchema for ${cacheKey}` + ); } else { - console.warn(`⚠️ Zod v4 toJSONSchema not found. Available exports:`, Object.keys(zod)); + console.warn('⚠️ Zod v4 toJSONSchema not found. Available exports:', Object.keys(zod)); } } catch (error) { console.warn(`⚠️ Zod v4 toJSONSchema conversion failed for ${cacheKey}:`, error); diff --git a/apps/web/src/components/AppHeader.tsx b/apps/web/src/components/AppHeader.tsx index f7688b8..f208e12 100644 --- a/apps/web/src/components/AppHeader.tsx +++ b/apps/web/src/components/AppHeader.tsx @@ -1,11 +1,11 @@ 'use client'; +import { useSession } from '@/lib/auth-client'; import { Button } from '@tpmjs/ui/Button/Button'; import { Header } from '@tpmjs/ui/Header/Header'; import { Icon } from '@tpmjs/ui/Icon/Icon'; import Link from 'next/link'; import { useState } from 'react'; -import { useSession } from '@/lib/auth-client'; import { MobileMenu } from './MobileMenu'; /** @@ -100,13 +100,21 @@ export function AppHeader(): React.ReactElement { {session ? ( - ) : ( - @@ -133,7 +141,11 @@ export function AppHeader(): React.ReactElement { /> {/* Mobile Menu Drawer */} - setMobileMenuOpen(false)} session={session} /> + setMobileMenuOpen(false)} + session={session} + /> ); } diff --git a/apps/web/src/components/MobileMenu.tsx b/apps/web/src/components/MobileMenu.tsx index ff92b6b..ab6525e 100644 --- a/apps/web/src/components/MobileMenu.tsx +++ b/apps/web/src/components/MobileMenu.tsx @@ -29,7 +29,11 @@ const socialLinks = [ { href: 'https://github.com/tpmjs/tpmjs', icon: 'github' as const, label: 'GitHub' }, ]; -export function MobileMenu({ isOpen, onClose, session }: MobileMenuProps): React.ReactElement | null { +export function MobileMenu({ + isOpen, + onClose, + session, +}: MobileMenuProps): React.ReactElement | null { // Lock body scroll when menu is open useEffect(() => { if (isOpen) { diff --git a/packages/config/biome.json b/packages/config/biome.json index 74fcaed..2afbc03 100644 --- a/packages/config/biome.json +++ b/packages/config/biome.json @@ -76,6 +76,36 @@ } } } + }, + { + "include": ["**/MobileMenu.tsx"], + "linter": { + "rules": { + "a11y": { + "useSemanticElements": "off" + } + } + } + }, + { + "include": ["**/MessageBubble.tsx"], + "linter": { + "rules": { + "complexity": { + "noExcessiveCognitiveComplexity": "off" + } + } + } + }, + { + "include": ["**/railway-executor/server.ts"], + "linter": { + "rules": { + "complexity": { + "noExcessiveCognitiveComplexity": "off" + } + } + } } ] } diff --git a/packages/tools/official/date-parse/tsup.config.bundled_ko2hafosm0g.mjs b/packages/tools/official/date-parse/tsup.config.bundled_ko2hafosm0g.mjs index 4413725..d56713d 100644 --- a/packages/tools/official/date-parse/tsup.config.bundled_ko2hafosm0g.mjs +++ b/packages/tools/official/date-parse/tsup.config.bundled_ko2hafosm0g.mjs @@ -1,14 +1,12 @@ // tsup.config.ts -import { defineConfig } from "tsup"; +import { defineConfig } from 'tsup'; var tsup_config_default = defineConfig({ - entry: ["src/index.ts"], - format: ["esm"], + entry: ['src/index.ts'], + format: ['esm'], dts: true, clean: true, treeshake: true, - splitting: false + splitting: false, }); -export { - tsup_config_default as default -}; +export { tsup_config_default as default }; //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidHN1cC5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9faW5qZWN0ZWRfZmlsZW5hbWVfXyA9IFwiL1VzZXJzL2FqYXhkYXZpcy9yZXBvcy90cG1qcy90cG1qcy9wYWNrYWdlcy90b29scy9vZmZpY2lhbC9kYXRlLXBhcnNlL3RzdXAuY29uZmlnLnRzXCI7Y29uc3QgX19pbmplY3RlZF9kaXJuYW1lX18gPSBcIi9Vc2Vycy9hamF4ZGF2aXMvcmVwb3MvdHBtanMvdHBtanMvcGFja2FnZXMvdG9vbHMvb2ZmaWNpYWwvZGF0ZS1wYXJzZVwiO2NvbnN0IF9faW5qZWN0ZWRfaW1wb3J0X21ldGFfdXJsX18gPSBcImZpbGU6Ly8vVXNlcnMvYWpheGRhdmlzL3JlcG9zL3RwbWpzL3RwbWpzL3BhY2thZ2VzL3Rvb2xzL29mZmljaWFsL2RhdGUtcGFyc2UvdHN1cC5jb25maWcudHNcIjtpbXBvcnQgeyBkZWZpbmVDb25maWcgfSBmcm9tICd0c3VwJztcblxuZXhwb3J0IGRlZmF1bHQgZGVmaW5lQ29uZmlnKHtcbiAgZW50cnk6IFsnc3JjL2luZGV4LnRzJ10sXG4gIGZvcm1hdDogWydlc20nXSxcbiAgZHRzOiB0cnVlLFxuICBjbGVhbjogdHJ1ZSxcbiAgdHJlZXNoYWtlOiB0cnVlLFxuICBzcGxpdHRpbmc6IGZhbHNlLFxufSk7XG4iXSwKICAibWFwcGluZ3MiOiAiO0FBQTZWLFNBQVMsb0JBQW9CO0FBRTFYLElBQU8sc0JBQVEsYUFBYTtBQUFBLEVBQzFCLE9BQU8sQ0FBQyxjQUFjO0FBQUEsRUFDdEIsUUFBUSxDQUFDLEtBQUs7QUFBQSxFQUNkLEtBQUs7QUFBQSxFQUNMLE9BQU87QUFBQSxFQUNQLFdBQVc7QUFBQSxFQUNYLFdBQVc7QUFDYixDQUFDOyIsCiAgIm5hbWVzIjogW10KfQo=