content: update tutorial slides with pitch deck messaging

- WelcomeSlide: 'Tool Discovery for AI Agents'
- ProblemSlide: 'Tool Sprawl' with integration tax framing
- SolutionSlide: Registry that normalizes + enriches tool metadata
- HowItWorksSlide: What TPMJS stores (description, schema, env, signals)
- DiscoverySlide: Two users - engineers browsing & agents selecting
- IntegrationSlide: Immediate benefits (less spelunking, schemas, vocab)
- QualitySlide: The Multipliers (signals, health, playground, remote exec)
- ToolDetailSlide: Tool-shaped results, remove guesswork
- GetStartedSlide: Engineering-friendly CTAs
This commit is contained in:
Ajax Davis 2025-12-29 01:49:47 +10:00
parent a57af97585
commit b279be2a25
9 changed files with 84 additions and 115 deletions

View file

@ -1,32 +1,6 @@
'use client';
import { animate, motion, useMotionValue, useTransform } from 'framer-motion';
import { useEffect, useState } from 'react';
function AnimatedCounter({ value, delay = 0 }: { value: number; delay?: number }) {
const count = useMotionValue(0);
const rounded = useTransform(count, (latest) => Math.round(latest));
const [displayValue, setDisplayValue] = useState(0);
useEffect(() => {
const timeout = setTimeout(() => {
const controls = animate(count, value, {
duration: 2,
ease: 'easeOut',
});
return () => controls.stop();
}, delay * 1000);
return () => clearTimeout(timeout);
}, [count, value, delay]);
useEffect(() => {
const unsubscribe = rounded.on('change', (v) => setDisplayValue(v));
return unsubscribe;
}, [rounded]);
return <span>{displayValue}</span>;
}
import { motion } from 'framer-motion';
export function DiscoverySlide(): React.ReactElement {
return (
@ -53,60 +27,52 @@ export function DiscoverySlide(): React.ReactElement {
🔍
</motion.div>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">Automatic Discovery</h2>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">Two Users, One Surface</h2>
<p className="text-xl text-white/40 mb-12">
npm changes feed synced every{' '}
<span className="text-cyan-400 font-semibold">2 minutes</span>
Same registry. <span className="text-cyan-400 font-semibold">Different clients.</span>
</p>
{/* Stats grid */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 mt-8">
{/* Two user types */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mt-8 max-w-4xl mx-auto">
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
initial={{ opacity: 0, x: -30 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.5 }}
className="p-6 rounded-2xl bg-white/5 border border-white/10"
className="p-6 rounded-2xl bg-white/5 border border-white/10 text-left"
>
<div className="text-5xl md:text-6xl font-bold text-cyan-400 font-mono">
<AnimatedCounter value={78} delay={0.8} />+
</div>
<div className="text-white/40 mt-2">Tools Registered</div>
<div className="text-4xl mb-4">👨💻</div>
<div className="text-2xl font-bold text-cyan-400 mb-3">Engineers browsing</div>
<ul className="space-y-2 text-white/60">
<li>&quot;Show me the best extraction tools&quot;</li>
<li>&quot;I need one that supports screenshots&quot;</li>
<li>&quot;I need maintained + documented&quot;</li>
</ul>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
initial={{ opacity: 0, x: 30 }}
animate={{ opacity: 1, x: 0 }}
transition={{ delay: 0.7 }}
className="p-6 rounded-2xl bg-white/5 border border-white/10"
className="p-6 rounded-2xl bg-white/5 border border-white/10 text-left"
>
<div className="text-5xl md:text-6xl font-bold text-purple-400 font-mono">2m</div>
<div className="text-white/40 mt-2">Sync Interval</div>
</motion.div>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: 0.9 }}
className="p-6 rounded-2xl bg-white/5 border border-white/10"
>
<div className="text-5xl md:text-6xl font-bold text-emerald-400 font-mono">24/7</div>
<div className="text-white/40 mt-2">Always Running</div>
<div className="text-4xl mb-4">🤖</div>
<div className="text-2xl font-bold text-purple-400 mb-3">Agents selecting</div>
<ul className="space-y-2 text-white/60">
<li>&quot;I need to scrape a URL into markdown&quot;</li>
<li>&quot;I need to summarize a PDF with citations&quot;</li>
<li>&quot;I need a company research tool&quot;</li>
</ul>
</motion.div>
</div>
{/* Animated sync indicator */}
{/* Key insight */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 1.2 }}
className="mt-12 flex items-center justify-center gap-3"
className="mt-12 text-white/40 text-lg"
>
<motion.div
animate={{ scale: [1, 1.2, 1] }}
transition={{ duration: 1.5, repeat: Number.POSITIVE_INFINITY }}
className="w-3 h-3 rounded-full bg-emerald-400"
/>
<span className="text-emerald-400/60 font-mono text-sm">Live sync active</span>
Results are <span className="text-emerald-400 font-semibold">tool-shaped</span>, not just package-shaped.
</motion.div>
</motion.div>
</div>

View file

@ -6,22 +6,22 @@ const links = [
{
label: 'Browse Tools',
href: 'https://tpmjs.com/tool-search',
description: 'Explore the registry',
description: 'Use as a discovery portal',
icon: '🔍',
gradient: 'from-cyan-500 to-blue-500',
},
{
label: 'Publish Your Tool',
href: 'https://tpmjs.com/publish',
description: 'Share with the community',
label: 'Publish a Tool',
href: 'https://tpmjs.com/docs/publishing',
description: 'Clean metadata + examples',
icon: '📦',
gradient: 'from-purple-500 to-pink-500',
},
{
label: 'Read the Docs',
href: 'https://tpmjs.com/docs',
description: 'Learn everything',
icon: '📚',
label: 'The Playground',
href: 'https://tpmjs.com/playground',
description: 'Try tools before adopting',
icon: '🎮',
gradient: 'from-emerald-500 to-teal-500',
},
];
@ -61,8 +61,8 @@ export function GetStartedSlide(): React.ReactElement {
🚀
</motion.div>
<h2 className="text-5xl md:text-7xl font-bold text-white mb-4">Get Started</h2>
<p className="text-xl md:text-2xl text-white/40 mb-16">Join the future of AI tooling</p>
<h2 className="text-5xl md:text-7xl font-bold text-white mb-4">Try It</h2>
<p className="text-xl md:text-2xl text-white/40 mb-16">Discovery chaos is optional</p>
{/* CTA buttons */}
<div className="flex flex-col md:flex-row items-center justify-center gap-6">
@ -120,7 +120,7 @@ export function GetStartedSlide(): React.ReactElement {
transition={{ delay: 1.2 }}
className="mt-16 text-white/30 text-sm"
>
Made with for the AI community
Tools are inevitable. Discovery chaos isn&apos;t.
</motion.div>
</motion.div>
</div>

View file

@ -3,10 +3,10 @@
import { motion } from 'framer-motion';
const steps = [
{ icon: '📦', label: 'npm publish', description: 'Publish your tool to npm' },
{ icon: '🔍', label: 'Discovery', description: 'Automatic detection' },
{ icon: '📋', label: 'Registry', description: 'Added to TPMJS' },
{ icon: '🤖', label: 'AI Agent', description: 'Ready to use' },
{ icon: '📝', label: 'What it does', description: 'Description, category, tags' },
{ icon: '⚙️', label: 'How to call it', description: 'Inputs, schema, examples' },
{ icon: '🔑', label: 'What it needs', description: 'Env vars, auth hints' },
{ icon: '📊', label: 'Signals', description: 'Downloads, health, freshness' },
];
export function HowItWorksSlide(): React.ReactElement {
@ -21,8 +21,8 @@ export function HowItWorksSlide(): React.ReactElement {
transition={{ duration: 0.8 }}
className="relative z-10 max-w-5xl w-full"
>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">How It Works</h2>
<p className="text-xl text-white/40 mb-16">From npm to AI in 4 simple steps</p>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">What TPMJS Stores</h2>
<p className="text-xl text-white/40 mb-16">For each tool, we expose the useful stuff</p>
{/* Flow diagram */}
<div className="flex flex-col md:flex-row items-center justify-center gap-4 md:gap-0">

View file

@ -4,15 +4,14 @@ import { motion } from 'framer-motion';
import { useEffect, useState } from 'react';
const codeLines = [
{ text: "import { tool } from '@tpmjs/sdk';", delay: 0.5 },
{ text: '', delay: 0.8 },
{ text: '// Get any tool from the registry', delay: 1.0 },
{ text: "const webSearch = await tool('web-search');", delay: 1.3 },
{ text: '', delay: 1.6 },
{ text: '// Use it with your AI agent', delay: 1.8 },
{ text: 'const result = await webSearch.execute({', delay: 2.1 },
{ text: " query: 'latest AI news'", delay: 2.4 },
{ text: '});', delay: 2.7 },
{ text: '// Faster tool evaluation', delay: 0.5 },
{ text: 'const tool = await tpmjs.find({', delay: 0.8 },
{ text: " capability: 'web-scraping',", delay: 1.1 },
{ text: " minQuality: 0.8", delay: 1.4 },
{ text: '});', delay: 1.7 },
{ text: '', delay: 2.0 },
{ text: '// Schema + examples included', delay: 2.2 },
{ text: 'console.log(tool.schema, tool.examples);', delay: 2.5 },
];
function TypewriterLine({ text, delay }: { text: string; delay: number }) {
@ -77,8 +76,8 @@ export function IntegrationSlide(): React.ReactElement {
🔌
</motion.div>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">Simple Integration</h2>
<p className="text-xl text-white/40 mb-12">Three lines of code. That&apos;s it.</p>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">Immediate Benefits</h2>
<p className="text-xl text-white/40 mb-12">Even if you do nothing else</p>
{/* Code block */}
<motion.div
@ -108,19 +107,19 @@ export function IntegrationSlide(): React.ReactElement {
</div>
</motion.div>
{/* Framework badges */}
{/* Benefits badges */}
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ delay: 3 }}
className="mt-8 flex flex-wrap justify-center gap-3"
>
{['Vercel AI SDK', 'LangChain', 'Claude', 'OpenAI'].map((framework) => (
{['Less spelunking', 'Schemas + examples', 'Shared vocabulary', 'Tool visibility'].map((benefit) => (
<span
key={framework}
className="px-3 py-1 rounded-full bg-white/5 border border-white/10 text-white/50 text-sm"
key={benefit}
className="px-3 py-1 rounded-full bg-emerald-500/10 border border-emerald-500/20 text-emerald-400/70 text-sm"
>
Works with {framework}
{benefit}
</span>
))}
</motion.div>

View file

@ -73,12 +73,13 @@ export function ProblemSlide(): React.ReactElement {
😵
</motion.div>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-6">The Problem</h2>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-6">Tool Sprawl</h2>
<p className="text-xl md:text-2xl text-white/60 leading-relaxed">
AI tools are <span className="text-red-400 font-semibold">everywhere</span>.
<p className="text-xl md:text-2xl text-white/60 leading-relaxed max-w-2xl">
In modern agent stacks, tools are the{' '}
<span className="text-red-400 font-semibold">real product surface area</span>.
<br />
Finding and trusting them is <span className="text-orange-400 font-semibold">hard</span>.
But discovery is the <span className="text-orange-400 font-semibold">bottleneck</span>.
</p>
<motion.div
@ -87,7 +88,7 @@ export function ProblemSlide(): React.ReactElement {
transition={{ delay: 1 }}
className="mt-12 flex flex-wrap justify-center gap-4"
>
{['Scattered', 'Inconsistent', 'Unverified', 'Fragmented'].map((word, i) => (
{['Dozens of packages', 'Missing schemas', 'Vague READMEs', 'Unknown status'].map((word, i) => (
<motion.span
key={word}
initial={{ opacity: 0, y: 20 }}

View file

@ -58,10 +58,10 @@ function AnimatedGauge({ value, delay = 0 }: { value: number; delay?: number })
}
const qualityFactors = [
{ name: 'Schema Completeness', icon: '📋', score: 95, color: 'cyan' },
{ name: 'npm Downloads', icon: '📈', score: 78, color: 'purple' },
{ name: 'Documentation', icon: '📚', score: 88, color: 'emerald' },
{ name: 'Type Safety', icon: '🛡️', score: 100, color: 'yellow' },
{ name: 'Quality Signals', icon: '📊', score: 95, color: 'cyan', desc: 'Docs, schema, adoption' },
{ name: 'Health Checks', icon: '💚', score: 88, color: 'emerald', desc: 'Imports, exports, runs' },
{ name: 'The Playground', icon: '🎮', score: 92, color: 'purple', desc: 'Try before you adopt' },
{ name: 'Remote Execution', icon: '☁️', score: 85, color: 'yellow', desc: 'Optional sandbox' },
];
export function QualitySlide(): React.ReactElement {
@ -85,8 +85,8 @@ export function QualitySlide(): React.ReactElement {
</motion.div>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">Quality Scoring</h2>
<p className="text-xl text-white/40 mb-12">Every tool is scored for reliability</p>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">The Multipliers</h2>
<p className="text-xl text-white/40 mb-12">Extra leverage when you&apos;re ready</p>
{/* Main gauge */}
<motion.div
@ -109,7 +109,8 @@ export function QualitySlide(): React.ReactElement {
className="p-4 rounded-xl bg-white/5 border border-white/10"
>
<div className="text-3xl mb-2">{factor.icon}</div>
<div className="text-sm text-white/60 mb-2">{factor.name}</div>
<div className="text-base font-semibold text-white mb-1">{factor.name}</div>
<div className="text-xs text-white/40 mb-3">{factor.desc}</div>
<div className="w-full h-2 bg-white/10 rounded-full overflow-hidden">
<motion.div
initial={{ width: 0 }}

View file

@ -29,12 +29,14 @@ export function SolutionSlide(): React.ReactElement {
</motion.div>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-6">The Solution</h2>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-6">TPMJS</h2>
<p className="text-xl md:text-2xl text-white/60 leading-relaxed mb-12">
<span className="text-cyan-400 font-semibold">One registry</span>.
<p className="text-xl md:text-2xl text-white/60 leading-relaxed mb-12 max-w-2xl">
A registry that indexes AI-tool packages and exposes{' '}
<span className="text-cyan-400 font-semibold">normalized, enriched information</span>
<br />
Curated tools. <span className="text-emerald-400 font-semibold">Quality guaranteed</span>.
so agents and engineers can{' '}
<span className="text-emerald-400 font-semibold">discover the right tool faster</span>.
</p>
{/* Organized grid of icons */}
@ -68,7 +70,7 @@ export function SolutionSlide(): React.ReactElement {
transition={{ delay: 1.5 }}
className="mt-12 flex flex-wrap justify-center gap-4"
>
{['Organized', 'Consistent', 'Verified', 'Unified'].map((word, i) => (
{['Catalog', 'Metadata layer', 'Search surface', 'Consistent contract'].map((word, i) => (
<motion.span
key={word}
initial={{ opacity: 0, y: 20 }}

View file

@ -14,8 +14,8 @@ export function ToolDetailSlide(): React.ReactElement {
transition={{ duration: 0.8 }}
className="relative z-10 max-w-4xl w-full"
>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">Rich Tool Data</h2>
<p className="text-xl text-white/40 mb-12">Everything you need to know about each tool</p>
<h2 className="text-5xl md:text-6xl font-bold text-white mb-4">Tool-Shaped Results</h2>
<p className="text-xl text-white/40 mb-12">Remove guesswork before you integrate</p>
{/* Mock tool card */}
<motion.div

View file

@ -56,7 +56,7 @@ export function WelcomeSlide(): React.ReactElement {
transition={{ duration: 0.8, delay: 0.5 }}
className="mt-6 text-2xl md:text-3xl text-white/60 font-light max-w-2xl"
>
Tool Package Manager for AI Agents
Tool Discovery for AI Agents
</motion.p>
{/* Decorative line */}