Skip to content

Commit ae636d3

Browse files
KyleAMathewsclaude
andcommitted
feat: add TanStack Intent library and blog post header image
- Add Intent as a new library in the sidebar with landing page - Add header image to the "From Docs to Agents" blog post - Fix relative SVG image paths in blog post to use absolute paths Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 3c3094a commit ae636d3

File tree

8 files changed

+136
-4
lines changed

8 files changed

+136
-4
lines changed
5.98 MB
Loading

src/blog/from-docs-to-agents.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ authors:
66
- Kyle Matthews
77
---
88

9+
![From Docs to Agents](/blog-assets/from-docs-to-agents/header.png)
10+
911
Your docs are good. Your types are solid. Your agent still gets it wrong.
1012

1113
Not because it's dumb — because there's no pipeline between what you know about your tool and what agents know about your tool. Docs are written for humans who browse. Types check individual API calls but can't encode intent. Training data is a snapshot of the ecosystem as it *was*, mixing versions without flagging which one applies. The knowledge gap between your tool and agents using your tool isn't a content problem. It's a lifecycle problem.
@@ -74,7 +76,7 @@ npx intent setup
7476

7577
This matters because the alternative is hoping model providers eventually re-train on your latest docs. That's not a strategy. Training data has a permanent version-mixing problem: once a breaking change ships, models contain *both* versions forever with no mechanism to disambiguate. Skills bypass this entirely. They're versioned with your package, and `npm update` brings the latest knowledge with the latest code.
7678

77-
![Model training data mixes versions permanently vs. skills pinned to your installed version](./diagram-split-brain.svg)
79+
![Model training data mixes versions permanently vs. skills pinned to your installed version](/blog-assets/from-docs-to-agents/diagram-split-brain.svg)
7880

7981
## The dependency graph does the discovery
8082

@@ -84,7 +86,7 @@ When a developer runs `intent init`, the CLI discovers every intent-enabled pack
8486
npx intent init
8587
```
8688

87-
![intent init discovers intent-enabled packages in node_modules and wires skills into agent config](./diagram-discovery.svg)
89+
![intent init discovers intent-enabled packages in node_modules and wires skills into agent config](/blog-assets/from-docs-to-agents/diagram-discovery.svg)
8890

8991
No manual setup per-library. No hunting for rules files. Install the package, run `intent init`, and the agent understands the tool. Update the package, and the skills update with it. Knowledge travels through the same channel as code.
9092

@@ -122,7 +124,7 @@ npx intent stale --json # Machine-readable for CI
122124

123125
Run it in CI and you get a failing check when source material has changed. The skill becomes part of your release checklist — not something you remember to update, something your pipeline catches.
124126

125-
![The intent lifecycle: docs to skills to npm to agent config, with staleness checks and feedback loops](./diagram-lifecycle.svg)
127+
![The intent lifecycle: docs to skills to npm to agent config, with staleness checks and feedback loops](/blog-assets/from-docs-to-agents/diagram-lifecycle.svg)
126128

127129
The feedback loop runs both directions. `intent feedback` lets users submit structured reports when a skill produces incorrect output — which skill was active, which version, what went wrong. That context flows back to you as a maintainer, and the fix ships to everyone on the next `npm update`.
128130

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import { Footer } from '~/components/Footer'
2+
import { LazySponsorSection } from '~/components/LazySponsorSection'
3+
import { LibraryHero } from '~/components/LibraryHero'
4+
import { BottomCTA } from '~/components/BottomCTA'
5+
import { intentProject } from '~/libraries/intent'
6+
import { getLibrary } from '~/libraries'
7+
import { LibraryFeatureHighlights } from '~/components/LibraryFeatureHighlights'
8+
import LandingPageGad from '~/components/LandingPageGad'
9+
import { PartnersSection } from '~/components/PartnersSection'
10+
import { MaintainersSection } from '~/components/MaintainersSection'
11+
import { LibraryPageContainer } from '~/components/LibraryPageContainer'
12+
import { LibraryStatsSection } from '~/components/LibraryStatsSection'
13+
14+
const library = getLibrary('intent')
15+
16+
export default function IntentLanding() {
17+
return (
18+
<LibraryPageContainer>
19+
<LibraryHero project={intentProject} />
20+
21+
<LibraryStatsSection library={library} />
22+
23+
<LibraryFeatureHighlights
24+
featureHighlights={intentProject.featureHighlights}
25+
/>
26+
27+
<MaintainersSection libraryId="intent" />
28+
<PartnersSection libraryId="intent" />
29+
<LazySponsorSection />
30+
<LandingPageGad />
31+
32+
<BottomCTA
33+
linkProps={{
34+
to: '/$libraryId/$version/docs',
35+
params: { libraryId: library.id },
36+
}}
37+
label="Get Started!"
38+
className="bg-sky-500 border-sky-500 hover:bg-sky-600 text-white"
39+
/>
40+
<Footer />
41+
</LibraryPageContainer>
42+
)
43+
}

src/libraries/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export {
2121
hotkeys,
2222
db,
2323
ai,
24+
intent,
2425
config,
2526
devtools,
2627
cli,

src/libraries/intent.tsx

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { Library } from '.'
2+
import { BookOpen, Package, RefreshCw } from 'lucide-react'
3+
import { twMerge } from 'tailwind-merge'
4+
import { intent } from './libraries'
5+
6+
const textStyles = `text-sky-600 dark:text-sky-500`
7+
8+
export const intentProject = {
9+
...intent,
10+
featureHighlights: [
11+
{
12+
title: 'Skills as npm Packages',
13+
icon: <Package className={twMerge(textStyles)} />,
14+
description: (
15+
<div>
16+
Skills are knowledge encoded for AI coding agents, shipped as npm
17+
packages. They travel with your tool via{' '}
18+
<span className={twMerge('font-semibold', textStyles)}>
19+
npm update
20+
</span>{' '}
21+
— not the model's training cutoff, not community-maintained rules
22+
files, not prompt snippets in READMEs.
23+
</div>
24+
),
25+
},
26+
{
27+
title: 'Automatic Discovery',
28+
icon: <BookOpen className={twMerge(textStyles)} />,
29+
description: (
30+
<div>
31+
Run{' '}
32+
<span className={twMerge('font-semibold', textStyles)}>
33+
intent install
34+
</span>{' '}
35+
and the CLI discovers every intent-enabled package in your
36+
dependencies, wiring skills into your agent configuration — CLAUDE.md,
37+
.cursorrules, whatever your tooling expects.
38+
</div>
39+
),
40+
},
41+
{
42+
title: 'Staleness Detection',
43+
icon: <RefreshCw className={twMerge(textStyles)} />,
44+
description: (
45+
<div>
46+
Each skill declares its source docs. When those docs change,{' '}
47+
<span className={twMerge('font-semibold', textStyles)}>
48+
intent stale
49+
</span>{' '}
50+
flags the skill for review. Run it in CI and you get a failing check
51+
when sources drift — skills become part of your release checklist.
52+
</div>
53+
),
54+
},
55+
],
56+
} satisfies Library

src/libraries/libraries.ts

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,32 @@ export const ai: LibrarySlim = {
584584
defaultDocs: 'getting-started/overview',
585585
}
586586

587+
export const intent: LibrarySlim = {
588+
id: 'intent',
589+
name: 'TanStack Intent',
590+
cardStyles: 'text-sky-500 dark:text-sky-400 hover:border-current',
591+
to: '/intent',
592+
tagline:
593+
'Ship compositional knowledge for AI coding agents alongside your npm packages',
594+
description:
595+
'A toolkit for generating, discovering, and maintaining skills — knowledge encoded for AI coding agents — shipped as npm packages that travel with your code.',
596+
badge: 'alpha',
597+
bgStyle: 'bg-sky-500',
598+
borderStyle: 'border-sky-500/50',
599+
textStyle: 'text-sky-500 dark:text-sky-400',
600+
textColor: 'text-sky-600 dark:text-sky-400',
601+
colorFrom: 'from-sky-500',
602+
colorTo: 'to-sky-700',
603+
bgRadial: 'from-sky-500 via-sky-700/50 to-transparent',
604+
repo: 'tanstack/intent',
605+
frameworks: [],
606+
latestVersion: 'v0',
607+
latestBranch: 'main',
608+
availableVersions: ['v0'],
609+
ogImage: 'https://github.com/tanstack/intent/raw/main/media/repo-header.png',
610+
defaultDocs: 'overview',
611+
}
612+
587613
export const config: LibrarySlim = {
588614
id: 'config',
589615
name: 'TanStack Config',
@@ -712,6 +738,7 @@ export const libraries: LibrarySlim[] = [
712738
form,
713739
db,
714740
ai,
741+
intent,
715742
virtual,
716743
pacer,
717744
hotkeys,
@@ -761,7 +788,7 @@ export const librariesByGroup = {
761788
state: [start, router, query, db, store, ai],
762789
headlessUI: [table, form, hotkeys],
763790
performance: [virtual, pacer],
764-
tooling: [devtools, config, cli],
791+
tooling: [devtools, config, cli, intent],
765792
}
766793

767794
export const librariesGroupNamesMap = {
@@ -801,4 +828,5 @@ export const SIDEBAR_LIBRARY_IDS = [
801828
'store',
802829
'devtools',
803830
'cli',
831+
'intent',
804832
] as const satisfies readonly LibraryId[]

src/libraries/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export type LibraryId =
2424
| 'hotkeys'
2525
| 'db'
2626
| 'ai'
27+
| 'intent'
2728
| 'config'
2829
| 'devtools'
2930
| 'mcp'

src/routes/$libraryId/$version.index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const landingComponents: Partial<
3232
ai: React.lazy(() => import('~/components/landing/AiLanding')),
3333
devtools: React.lazy(() => import('~/components/landing/DevtoolsLanding')),
3434
cli: React.lazy(() => import('~/components/landing/CliLanding')),
35+
intent: React.lazy(() => import('~/components/landing/IntentLanding')),
3536
}
3637

3738
export const Route = createFileRoute('/$libraryId/$version/')({

0 commit comments

Comments
 (0)