fix(ci): resolve lint and architecture errors blocking Vercel deploy

- 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
This commit is contained in:
Ajax Davis 2025-12-11 09:46:27 +10:00
parent 833a023688
commit 022d363ccb
3 changed files with 29 additions and 21 deletions

View file

@ -143,6 +143,10 @@ export default {
doNotFollow: { doNotFollow: {
path: ['node_modules', '\\.next', 'dist', '\\.turbo', 'storybook-static'], path: ['node_modules', '\\.next', 'dist', '\\.turbo', 'storybook-static'],
}, },
exclude: {
// Exclude railway-executor - it's a Deno app with HTTP imports that can't be resolved
path: '^apps/railway-executor',
},
tsPreCompilationDeps: true, tsPreCompilationDeps: true,
tsConfig: { tsConfig: {
fileName: './tsconfig.json', fileName: './tsconfig.json',

View file

@ -642,7 +642,7 @@ const result = await streamText({
<p className="text-sm text-foreground-secondary"> <p className="text-sm text-foreground-secondary">
<strong className="text-foreground">Why collections?</strong> They let you <strong className="text-foreground">Why collections?</strong> They let you
compose specialized sub-agents without manually curating tool lists. Think of compose specialized sub-agents without manually curating tool lists. Think of
them as "skill packs" for your AI. them as &ldquo;skill packs&rdquo; for your AI.
</p> </p>
</div> </div>
</div> </div>
@ -654,8 +654,8 @@ const result = await streamText({
Try It in the Playground Try It in the Playground
</h3> </h3>
<p className="text-foreground-secondary mb-4"> <p className="text-foreground-secondary mb-4">
Ask the playground agent to "search for tools about X" and watch it discover, Ask the playground agent to &ldquo;search for tools about X&rdquo; and watch it
load, and execute tools dynamically! discover, load, and execute tools dynamically!
</p> </p>
<Link href="/playground"> <Link href="/playground">
<Button size="lg" variant="default"> <Button size="lg" variant="default">

View file

@ -34,6 +34,25 @@ interface Tool {
type SortOption = 'downloads' | 'recent'; type SortOption = 'downloads' | 'recent';
/** Sort tools by criterion, pushing broken tools to the bottom */
function sortTools(tools: Tool[], sortBy: SortOption): Tool[] {
return [...tools].sort((a, b) => {
const aIsBroken = a.importHealth === 'BROKEN' || a.executionHealth === 'BROKEN';
const bIsBroken = b.importHealth === 'BROKEN' || b.executionHealth === 'BROKEN';
// Always push broken tools to bottom
if (aIsBroken && !bIsBroken) return 1;
if (!aIsBroken && bIsBroken) return -1;
// Within same broken status, sort by selected criterion
if (sortBy === 'downloads') {
const aDownloads = a.package.npmDownloadsLastMonth ?? 0;
const bDownloads = b.package.npmDownloadsLastMonth ?? 0;
return bDownloads - aDownloads;
}
// Sort by recent (createdAt descending)
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
});
}
/** /**
* Tool Registry Search Page * Tool Registry Search Page
* *
@ -79,23 +98,7 @@ export default function ToolSearchPage(): React.ReactElement {
if (toolsData.success) { if (toolsData.success) {
const fetchedTools = toolsData.data; const fetchedTools = toolsData.data;
// Sort by selected criterion, then push broken tools to bottom setTools(sortTools(fetchedTools, sortBy));
const sortedTools = [...fetchedTools].sort((a: Tool, b: Tool) => {
const aIsBroken = a.importHealth === 'BROKEN' || a.executionHealth === 'BROKEN';
const bIsBroken = b.importHealth === 'BROKEN' || b.executionHealth === 'BROKEN';
// Always push broken tools to bottom
if (aIsBroken && !bIsBroken) return 1;
if (!aIsBroken && bIsBroken) return -1;
// Within same broken status, sort by selected criterion
if (sortBy === 'downloads') {
const aDownloads = a.package.npmDownloadsLastMonth ?? 0;
const bDownloads = b.package.npmDownloadsLastMonth ?? 0;
return bDownloads - aDownloads;
}
// Sort by recent (createdAt descending)
return new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime();
});
setTools(sortedTools);
setError(null); setError(null);
// Extract unique categories from all tools // Extract unique categories from all tools
@ -321,7 +324,8 @@ export default function ToolSearchPage(): React.ReactElement {
</div> </div>
{/* Install command */} {/* Install command */}
{/* biome-ignore lint/a11y/useKeyWithClickEvents: onClick only prevents propagation, not an interactive element */} {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-static-element-interactions */}
{/* biome-ignore lint/a11y/useKeyWithClickEvents: onClick only prevents propagation */}
<div className="mt-auto" onClick={(e) => e.stopPropagation()}> <div className="mt-auto" onClick={(e) => e.stopPropagation()}>
<CodeBlock <CodeBlock
code={`npm install ${tool.package.npmPackageName}`} code={`npm install ${tool.package.npmPackageName}`}