From 9f1f93b53247043458e1e680232b6b19eef93832 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Sun, 14 Dec 2025 13:00:21 +1000 Subject: [PATCH] feat(docs): add comprehensive documentation page with sidebar navigation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Create /docs page with complete TPMJS documentation - Add sidebar navigation with section tracking - Document SDK reference (registrySearchTool, registryExecuteTool) - Document REST API endpoints - Document publishing guide and TPMJS specification - Add advanced sections (override execute, custom wrappers, self-hosting) - Include FAQ and troubleshooting sections - Add Docs link to main navigation header πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- apps/web/src/app/docs/layout.tsx | 16 + apps/web/src/app/docs/page.tsx | 1064 +++++++++++++++++++++++++ apps/web/src/components/AppHeader.tsx | 5 + 3 files changed, 1085 insertions(+) create mode 100644 apps/web/src/app/docs/layout.tsx create mode 100644 apps/web/src/app/docs/page.tsx diff --git a/apps/web/src/app/docs/layout.tsx b/apps/web/src/app/docs/layout.tsx new file mode 100644 index 0000000..d988b9f --- /dev/null +++ b/apps/web/src/app/docs/layout.tsx @@ -0,0 +1,16 @@ +import type { Metadata } from 'next'; + +export const metadata: Metadata = { + title: 'Documentation | TPMJS', + description: + 'Complete documentation for TPMJS - the registry for AI tools. Learn how to use the SDK, API, and publish your own tools.', + openGraph: { + title: 'TPMJS Documentation', + description: + 'Complete documentation for TPMJS - the registry for AI tools. Learn how to use the SDK, API, and publish your own tools.', + }, +}; + +export default function DocsLayout({ children }: { children: React.ReactNode }) { + return children; +} diff --git a/apps/web/src/app/docs/page.tsx b/apps/web/src/app/docs/page.tsx new file mode 100644 index 0000000..84363a0 --- /dev/null +++ b/apps/web/src/app/docs/page.tsx @@ -0,0 +1,1064 @@ +'use client'; + +import { TPMJS_CATEGORIES } from '@tpmjs/types/tpmjs'; +import { Badge } from '@tpmjs/ui/Badge/Badge'; +import { Button } from '@tpmjs/ui/Button/Button'; +import { CodeBlock } from '@tpmjs/ui/CodeBlock/CodeBlock'; +import Link from 'next/link'; +import { useEffect, useState } from 'react'; +import { AppHeader } from '~/components/AppHeader'; + +const NAV_SECTIONS = [ + { + title: 'Getting Started', + items: [ + { id: 'introduction', label: 'Introduction' }, + { id: 'quickstart', label: 'Quick Start' }, + { id: 'core-concepts', label: 'Core Concepts' }, + ], + }, + { + title: 'SDK Reference', + items: [ + { id: 'installation', label: 'Installation' }, + { id: 'registry-search', label: 'registrySearchTool' }, + { id: 'registry-execute', label: 'registryExecuteTool' }, + { id: 'passing-api-keys', label: 'Passing API Keys' }, + ], + }, + { + title: 'API Reference', + items: [ + { id: 'api-overview', label: 'Overview' }, + { id: 'api-tools', label: 'GET /api/tools' }, + { id: 'api-tools-search', label: 'GET /api/tools/search' }, + { id: 'api-tool-detail', label: 'GET /api/tools/[id]' }, + ], + }, + { + title: 'Publishing Tools', + items: [ + { id: 'publish-overview', label: 'Overview' }, + { id: 'tpmjs-spec', label: 'TPMJS Specification' }, + { id: 'metadata-tiers', label: 'Metadata Tiers' }, + { id: 'quality-score', label: 'Quality Score' }, + ], + }, + { + title: 'Advanced', + items: [ + { id: 'override-execute', label: 'Override Execute' }, + { id: 'custom-wrappers', label: 'Custom Wrappers' }, + { id: 'self-hosting', label: 'Self-Hosting' }, + { id: 'security', label: 'Security' }, + ], + }, + { + title: 'Resources', + items: [ + { id: 'faq', label: 'FAQ' }, + { id: 'troubleshooting', label: 'Troubleshooting' }, + { id: 'changelog', label: 'Changelog' }, + ], + }, +]; + +function SidebarNav({ + activeSection, + onSectionClick, +}: { + activeSection: string; + onSectionClick: (id: string) => void; +}) { + return ( + + ); +} + +function DocSection({ + id, + title, + children, +}: { + id: string; + title: string; + children: React.ReactNode; +}) { + return ( +
+

+ {title} +

+ {children} +
+ ); +} + +function DocSubSection({ title, children }: { title: string; children: React.ReactNode }) { + return ( +
+

{title}

+ {children} +
+ ); +} + +function ParamTable({ + params, +}: { + params: { name: string; type: string; required: boolean; description: string }[]; +}) { + return ( +
+ + + + + + + + + + + {params.map((param, i) => ( + + + + + + + ))} + +
ParameterTypeRequiredDescription
{param.name}{param.type} + {param.required ? ( + + Yes + + ) : ( + No + )} + {param.description}
+
+ ); +} + +function InfoCard({ + icon, + title, + children, +}: { + icon: string; + title: string; + children: React.ReactNode; +}) { + return ( +
+
+ {icon} +
+

{title}

+

{children}

+
+
+
+ ); +} + +export default function DocsPage(): React.ReactElement { + const [activeSection, setActiveSection] = useState('introduction'); + + useEffect(() => { + const observer = new IntersectionObserver( + (entries) => { + entries.forEach((entry) => { + if (entry.isIntersecting) { + setActiveSection(entry.target.id); + } + }); + }, + { rootMargin: '-100px 0px -66%' } + ); + + NAV_SECTIONS.forEach((section) => { + section.items.forEach((item) => { + const element = document.getElementById(item.id); + if (element) observer.observe(element); + }); + }); + + return () => observer.disconnect(); + }, []); + + const scrollToSection = (id: string) => { + const element = document.getElementById(id); + if (element) { + element.scrollIntoView({ behavior: 'smooth' }); + } + }; + + return ( +
+ + +
+ {/* Sidebar */} + + + {/* Main Content */} +
+
+ {/* Hero */} +
+

TPMJS Documentation

+

+ The complete guide to using TPMJS - the registry for AI tools. +

+ +
+ + {/* ==================== GETTING STARTED ==================== */} + +

+ TPMJS (Tool Package Manager for JavaScript) is a registry and execution platform for + AI tools. It enables AI agents to dynamically discover, load, and execute tools from + npm packages at runtime. +

+
+ + Search thousands of AI tools from the npm ecosystem + + + Run any tool in a secure sandbox - no installation needed + + + Share your tools with the AI community via npm + +
+

+ TPMJS works with{' '} + + Vercel AI SDK + + , LangChain, LlamaIndex, and any framework that supports the AI SDK tool format. +

+
+ + +

+ Get up and running with TPMJS in under 2 minutes. +

+ + + + + + + +

+ Your agent can now discover and execute any tool from the TPMJS registry. The + agent will automatically search for relevant tools and execute them as needed. +

+
+
+ + +
+ +

+ TPMJS automatically discovers tools from npm packages that have the{' '} + + tpmjs-tool + {' '} + keyword. Tools are indexed every 2-15 minutes. +

+
+ +

+ All tools run in an isolated Deno runtime on Railway. They cannot access your + local filesystem or environment. API keys are passed per-request and never + stored. +

+
+ +

+ Every tool receives a quality score (0.00-1.00) based on metadata completeness, + npm downloads, and GitHub stars. Higher scores mean better visibility in search + results. +

+
+ +

+ Tools are continuously health-checked to ensure they can be imported and + executed. Broken tools are flagged and can be filtered from search results. +

+
+
+
+ + {/* ==================== SDK REFERENCE ==================== */} + +

+ Install the TPMJS SDK packages to give your AI agent access to the tool registry. +

+
+ + + +
+
+

+ Peer Dependencies: Both packages + require ai and{' '} + zod as peer dependencies. Make sure you have + them installed. +

+
+
+ + +

+ Search the TPMJS registry to find tools for any task. Returns metadata including the{' '} + toolId needed for execution. +

+ + + + + + + + + + +
+ {TPMJS_CATEGORIES.map((cat) => ( + + {cat} + + ))} +
+
+
+ + +

+ Execute any tool from the registry by its{' '} + toolId. Tools run in a secure sandboxβ€”no local + installation required. +

+ + + + + + + + + +
+ + +

+ Many tools require API keys (e.g., Firecrawl, Exa). The recommended approach is to + wrap registryExecuteTool with your + pre-configured keys. +

+ + = { + FIRECRAWL_API_KEY: process.env.FIRECRAWL_API_KEY!, + EXA_API_KEY: process.env.EXA_API_KEY!, +}; + +// Create a wrapped version that auto-injects keys +export const registryExecute = tool({ + description: registryExecuteTool.description, + parameters: registryExecuteTool.parameters, + execute: async ({ toolId, params }) => { + return registryExecuteTool.execute({ toolId, params, env: API_KEYS }); + }, +});`} + /> + + + + +
+ + {/* ==================== API REFERENCE ==================== */} + +

+ The TPMJS API is a REST API that provides access to the tool registry. All endpoints + return JSON and are publicly accessible without authentication. +

+
+

+ Base URL:{' '} + https://tpmjs.com/api +

+
+
+ + +

+ List all tools with optional filtering and pagination. +

+ + + + + + +
+ + +

+ BM25-ranked search optimized for AI agent tool discovery. +

+ + + +
+ + +

+ Get detailed information about a specific tool. +

+ + + + + + +
+ + {/* ==================== PUBLISHING TOOLS ==================== */} + +

+ Publishing a tool to TPMJS is as simple as publishing to npm with standardized + metadata. +

+
+ {[ + { step: '1', label: 'Add tpmjs-tool keyword' }, + { step: '2', label: 'Add tpmjs field' }, + { step: '3', label: 'Publish to npm' }, + { step: '4', label: 'Live in 15 minutes!' }, + ].map((item) => ( +
+
{item.step}
+

{item.label}

+
+ ))} +
+
+ + + + + + +
+
+ + +

+ The tpmjs field in package.json describes your + tool's capabilities. +

+ +
+ + + +
+
+ + +

+ There are three tiers of metadata. Higher tiers get better visibility and quality + scores. +

+
+
+
+ Tier 1: Minimal + 1x multiplier +
+

+ Required fields only: category,{' '} + description,{' '} + exportName +

+
+
+
+ Tier 2: Basic + 2x multiplier +
+

+ + parameters and{' '} + returns documentation +

+
+
+
+ Tier 3: Rich + 4x multiplier +
+

+ + env,{' '} + frameworks,{' '} + aiAgent (useCase, limitations, examples) +

+
+
+
+ + +

+ Every tool receives a quality score (0.00-1.00) that affects search ranking. +

+ +
+ + {/* ==================== ADVANCED ==================== */} + +

+ When you import a tool from npm, you can override its{' '} + execute function before passing it to your AI + agent. +

+ + { + console.log('Custom execution with args:', args); + // Your completely custom implementation + return { result: 'my custom result' }; + }, +};`} + /> + + + { + console.log(\`[\${new Date().toISOString()}] Calling tool with:\`, args); + const start = Date.now(); + const result = await someTool.execute(args, options); + console.log(\`[\${Date.now() - start}ms] Tool returned:\`, result); + return result; + }, +};`} + /> + +
+ + +

+ Create reusable wrapper functions for common patterns like caching, retries, and + rate limiting. +

+ + ( + tool: { description: string; parameters: any; execute: (args: T, opts: any) => Promise }, + options: { + before?: (args: T) => T | Promise; + after?: (result: R) => R | Promise; + timeout?: number; + retries?: number; + } = {} +) { + return { + ...tool, + execute: async (args: T, execOptions: any): Promise => { + let processedArgs = options.before ? await options.before(args) : args; + + let lastError: Error | undefined; + const maxAttempts = (options.retries ?? 0) + 1; + + for (let attempt = 1; attempt <= maxAttempts; attempt++) { + try { + let result = await tool.execute(processedArgs, execOptions); + if (options.after) result = await options.after(result); + return result; + } catch (error) { + lastError = error as Error; + if (attempt < maxAttempts) { + await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 100)); + } + } + } + throw lastError; + }, + }; +}`} + /> + +
+ + +

+ Both SDK packages support self-hosted registries via environment variables. +

+ +
+ +
+
+ + +

+ TPMJS is designed with security in mind. +

+
+ + All tools run in an isolated Deno runtime. They cannot access your local + filesystem or environment. + + + API keys are passed per-request and never stored. Each execution is stateless and + isolated. + + + Only tools registered in TPMJS can be executed. No arbitrary code execution is + possible. + + + Every tool is continuously health-checked. Broken tools are flagged and filtered + from search results. + +
+
+ + {/* ==================== RESOURCES ==================== */} + +
+ {[ + { + q: 'How long does it take for my tool to appear?', + a: 'Tools are discovered within 2-15 minutes of publishing to npm. Make sure you have the "tpmjs-tool" keyword in your package.json.', + }, + { + q: 'Is TPMJS free to use?', + a: 'Yes! TPMJS is free for public tools. We may introduce paid tiers for private registries and enterprise features in the future.', + }, + { + q: 'Can I use TPMJS with any AI framework?', + a: 'TPMJS works with any framework that supports the AI SDK tool format, including Vercel AI SDK, LangChain, and LlamaIndex.', + }, + { + q: 'How are tools executed?', + a: 'Tools are dynamically loaded from esm.sh and executed in a sandboxed Deno runtime on Railway. No local installation is required.', + }, + { + q: 'Can I run my own TPMJS registry?', + a: 'Yes! Set the TPMJS_API_URL and TPMJS_EXECUTOR_URL environment variables to point to your own infrastructure.', + }, + ].map((item) => ( +
+

{item.q}

+

{item.a}

+
+ ))} +
+
+ + +
+ +
    +
  • + Ensure you have{' '} + tpmjs-tool in + your keywords +
  • +
  • + Verify your tpmjs field is valid JSON +
  • +
  • Wait 15 minutes after publishing
  • +
  • Check the validation errors in the npm package page
  • +
+
+ +
    +
  • Check that required environment variables are passed
  • +
  • Verify the toolId format is correct (package::exportName)
  • +
  • Check the tool's health status on tpmjs.com
  • +
+
+
+
+ + +
+
+
+ v1.0.0 + December 2024 +
+

+ Initial release with registrySearchTool and registryExecuteTool +

+
+
+
+ + {/* CTA */} +
+

Ready to Get Started?

+

+ Give your AI agent access to thousands of tools in minutes. +

+
+ + + + + + + + + +
+
+
+
+
+
+ ); +} diff --git a/apps/web/src/components/AppHeader.tsx b/apps/web/src/components/AppHeader.tsx index 733e464..e0d878a 100644 --- a/apps/web/src/components/AppHeader.tsx +++ b/apps/web/src/components/AppHeader.tsx @@ -28,6 +28,11 @@ export function AppHeader(): React.ReactElement { Tools + + +