Project Timeline Report
thedotmack/claude-mem
Writes a narrative Journey Into report on a project's whole development history, built from the timeline that claude-mem has recorded.
Durability and state persistence for TanStack AI chats with @tanstack/ai-persistence.
$ npx skills add TanStack/ai --skill ai-persistence -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install TanStack/ai ai-persistence --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/TanStack/ai.git skills-src && mkdir -p .claude/skills && cp -r skills-src/packages/ai-persistence/skills/ai-persistence .claude/skills/ai-persistence && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "ai-persistence" agent skill from https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistence into .claude/skills/ai-persistence/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ai-persistence", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistenceType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add TanStack/ai --skill ai-persistence -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install TanStack/ai ai-persistence --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/TanStack/ai.git skills-src && mkdir -p .agents/skills && cp -r skills-src/packages/ai-persistence/skills/ai-persistence .agents/skills/ai-persistence && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "ai-persistence" agent skill from https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistence into .agents/skills/ai-persistence/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ai-persistence", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add TanStack/ai --skill ai-persistence -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install TanStack/ai ai-persistence --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/TanStack/ai.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/packages/ai-persistence/skills/ai-persistence .cursor/skills/ai-persistence && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "ai-persistence" agent skill from https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistence into .cursor/skills/ai-persistence/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ai-persistence", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/TanStack/ai.git --path packages/ai-persistence/skills/ai-persistence--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add TanStack/ai --skill ai-persistence -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install TanStack/ai ai-persistence --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/TanStack/ai.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/packages/ai-persistence/skills/ai-persistence .gemini/skills/ai-persistence && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "ai-persistence" agent skill from https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistence into .gemini/skills/ai-persistence/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ai-persistence", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install TanStack/ai ai-persistenceInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add TanStack/ai --skill ai-persistence -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/TanStack/ai.git skills-src && mkdir -p .github/skills && cp -r skills-src/packages/ai-persistence/skills/ai-persistence .github/skills/ai-persistence && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "ai-persistence" agent skill from https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistence into .github/skills/ai-persistence/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ai-persistence", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add TanStack/ai --skill ai-persistence -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install TanStack/ai ai-persistence --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/TanStack/ai.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/packages/ai-persistence/skills/ai-persistence .opencode/skills/ai-persistence && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "ai-persistence" agent skill from https://github.com/TanStack/ai/tree/main/packages/ai-persistence/skills/ai-persistence into .opencode/skills/ai-persistence/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "ai-persistence", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
ai-persistenceDurability and state persistence for TanStack AI chats with @tanstack/ai-persistence.
AI Persistence is an agent skill from TanStack/ai. Durability and state persistence for TanStack AI chats with @tanstack/ai-persistence. Routes to server chat persistence (withPersistence), client persistence (localStorage/IndexedDB), the store contracts, and adapter recipes. Distinguishes delivery durability (resumable streams) from conversation state. Use when conversations must survive reloads, multi-device, approvals, or server restarts — NOT for stream reconnect alone.
Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Agent Workflows, covering Agent memory. It works with TanStack. The repository describes itself as: 🤖 Type-safe, provider-agnostic TypeScript AI SDK for streaming chat, tool calling, agents, and multimodal apps across OpenAI, Anthropic, Gemini, React, Vue, Svelte, and Solid. The licence is MIT.
4 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 5a41239. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
AI Persistence loads about 3.3k tokens when it runs. Until then it costs about 111 tokens; SKILL.md has 1,096 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from TanStack/ai at commit 5a41239, republished under its MIT licence (© TanStack). 1,096 words, ~3,250 tokens.
.claude/skills/ai-persistence/SKILL.md (or your agent's skills folder).Builds on the
ai-coreskill in@tanstack/ai, and usuallyai-core/chat-experience.
TanStack AI splits delivery durability from state persistence. They share no code and solve different problems.
| Layer | Answers | Package / API |
|---|---|---|
| Delivery durability | Reconnect to a stream still running | memoryStream / @tanstack/ai-durable-stream on the response; see resumable streams docs |
| State persistence | What is the conversation, later? | Client persistence on useChat + server withPersistence from @tanstack/ai-persistence |
A replayable stream is not a saved conversation. A saved conversation is not a live stream. Production apps often use both.
@tanstack/ai-persistence ships the store interfaces, the middleware that
drives them, an in-memory reference backend, and a conformance testkit. It does
not ship a backend for your database, and you do not need one: implement the
stores against whatever you already run — Postgres, SQLite, D1, Mongo — and hand
the result to withPersistence. The core never inspects your tables.
| Ships in the package | What it is |
|---|---|
MessageStore / RunStore / InterruptStore / MetadataStore | The four chat state contracts |
GenerationRunStore / ArtifactStore / BlobStore | The generation contracts (job lifecycle + bytes) |
withPersistence / withGenerationPersistence | Chat + generation middleware |
memoryPersistence() | In-process reference backend, all seven stores (dev, tests) |
reconstructChat / reconstructGeneration | Server hydrate route helpers (chat / generation) |
retrieveArtifact / retrieveBlob / resolveArtifactBlobKey | Serve persisted generation-media bytes back |
LockStore / withLocks / InMemoryLockStore (from @tanstack/ai/locks) | Coordination, not this package — see ai-core/locks |
@tanstack/ai-persistence/testkit | runPersistenceConformance gate (chat state stores) |
Chat vs generation stores. Chat persistence keys on threadId and uses
messages + optional runs / interrupts / metadata. Generation persistence
keys on its own runId and uses generationRuns (required by withGenerationPersistence) plus an
optional artifacts + blobs pair — provide both or neither — to store the
generated media bytes at blob key artifacts/<runId>/<artifactId>. A generation
run's identity is its own runId, but threadId is required on the record:
it is the stable slot successive runs fill, and findLatestForThread — the only
query that hydrates a run — keys on it. To
build the R2/D1-backed byte stores for a Worker, see
ai-persistence/build-cloudflare-artifact-store.
Where bytes land. Default blob key is artifacts/<runId>/<artifactId>. Pass
storageKey to withGenerationPersistence for your own folder structure — it
receives { artifactId, runId, threadId, role, activity, path, mimeType, name }
and returns the key. Server-side only (a browser-supplied key is path traversal +
cross-tenant writes). The resolved key is recorded on ArtifactRecord.blobKey
because it is no longer derivable; read through resolveArtifactBlobKey(record),
never by recomputing. Records predating blobKey fall back to the default
convention — which is why that convention can never be changed retroactively. A
non-unique key overwrites, so include artifactId unless that is intended.
Byte storage stores generated output, not prompt URLs. Provider result URLs
expire, so they are downloaded and kept. Prompt media sent as base64
(source: { type: 'data' }) is stored too. Prompt media sent as a URL is
NOT fetched — that URL is caller-supplied, so downloading it server-side is an
SSRF vector, and the bytes are redundant. Apps that genuinely need a durable
copy opt in with allowInputUrl, a predicate so the check can't be skipped:
allowInputUrl: ({ url }) => url.hostname.endsWith('.cdn.example.com'). Never
suggest () => true. All artifact fetches are http/https-only, timed out
(artifactFetchTimeoutMs) and size-capped (maxArtifactBytes); input fetches
also block loopback/private/link-local hosts and refuse redirects. artifactFetch
injects the fetch, for routing through an egress-restricted proxy.
Two related route-level rules: a GET that serves artifact bytes by id MUST
authorize the caller against ArtifactRecord.threadId before serving (404, not
403, so valid ids aren't confirmed), and reconstructGeneration MUST be given
authorize on any multi-user route. Both take ids straight from the caller.
Portable sandbox snapshots use the same messages, artifacts, and blobs
stores. Their artifact reader checks the checkpoint thread, but it does not
authenticate a caller. Authorize the thread before any route reads a snapshot
artifact. The snapshot checkpoint store also needs atomic append and fork
operations. A SQLite adapter must write a checkpoint, its head, and blob
reference counts in one transaction.
| Need to... | Read |
|---|---|
| Wire server-side chat history, runs, interrupts | ai-persistence/server/SKILL.md |
| Survive reloads in the browser | ai-core/client-persistence/SKILL.md in @tanstack/ai |
| Implement the store interfaces for your DB | ai-persistence/stores/SKILL.md |
| Multi-instance locks (separate from state) | ai-core/locks/SKILL.md in @tanstack/ai |
Adding persistence to an app? Pick the recipe that matches what it already
runs — each one writes a single chat-persistence.ts against the app's
existing database client and schema:
| The app runs... | Read |
|---|---|
| Drizzle ORM (SQLite / Postgres / MySQL) | ai-persistence/build-drizzle-adapter/SKILL.md |
| Prisma | ai-persistence/build-prisma-adapter/SKILL.md |
| Cloudflare Workers + D1 (± Durable Object locks) | ai-persistence/build-cloudflare-adapter/SKILL.md |
| Cloudflare Workers + R2/D1 for generated media bytes | ai-persistence/build-cloudflare-artifact-store/SKILL.md |
Anything else — raw pg, Kysely, SQLite, Mongo | ai-persistence/build-custom-adapter/SKILL.md |
| Half | Stores | Survives | Typical use |
|---|---|---|---|
| Client | transcript ± resume pointer in browser storage | reload / tab close (per browser) | SPA restore, offline-first |
| Server | messages, runs, interrupts, metadata in your DB | restart + multi-device | authoritative history, durable approvals |
They are independent. Use either alone or both.
threadId and ScopeServer stores key on threadId (same as chat({ threadId }) /
ChatMiddlewareContext.threadId / Scope.threadId from @tanstack/ai).
threadId strings for adapter simplicity.userId / tenantId from
session server-side; authorize before load/save / reconstructChat.When both halves run, ownership per turn is decided by request messages:
| Client sends | Meaning | On finish |
|---|---|---|
Non-empty messages | Full transcript (source of truth) | Server overwrites stored thread |
Empty messages | Continue from server copy | Server loads stored thread |
Never post a delta as messages — that wipes history down to the delta.
Client-authoritative: always send full transcript; browser is truth, server mirrors.
Server-authoritative: send empty messages (or hydrate via server load); server is truth, multi-device works.
persistence: true — server-authoritative, no client cache.withPersistence(backend) — messages + runs + interrupts.withLocks(distributedLockStore) from @tanstack/ai/locks when other middleware needs multi-instance coordination (not part of the state bag).Server
import {
chat,
chatParamsFromRequest,
toServerSentEventsResponse,
} from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'
import { withPersistence } from '@tanstack/ai-persistence'
// Your adapter — see ai-persistence/stores.
import { persistence } from './persistence'
export async function POST(request: Request) {
const params = await chatParamsFromRequest(request)
const stream = chat({
adapter: openaiText('gpt-5.5'),
messages: params.messages,
threadId: params.threadId,
runId: params.runId,
...(params.resume ? { resume: params.resume } : {}),
middleware: [withPersistence(persistence)],
})
return toServerSentEventsResponse(stream)
}Client (server-authoritative)
import { useChat, fetchServerSentEvents } from '@tanstack/ai-react'
function Chat({ threadId }: { threadId: string }) {
const { messages, sendMessage } = useChat({
threadId,
connection: fetchServerSentEvents('/api/chat'),
persistence: true,
})
// ...
}With persistence: true, the client caches nothing and hydrates the transcript
from the server on mount (thread id is the key). Pair with a server load path
such as reconstructChat for the GET.
@tanstack/ai-persistence + middleware, not Vercel useChat storage hacks.saveThread is full overwrite, never append.createOrResume is insert-if-absent for the same runId.create is insert-if-absent — never clobber resolved → pending.withLocks from @tanstack/ai/locks. Sandbox resume is a sandbox-package concern — not a stores key. stores accepts only messages, runs, interrupts, metadata.@tanstack/ai) — useChat, SSE, client persistence option overview@tanstack/ai) — middleware hooks; withPersistence is a ChatMiddleware© TanStack, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in packages/ai-persistence/skills/ai-persistence of TanStack/ai.
Open the folder on GitHubat commit 5a41239
AI Persistence next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| AI Persistence this skillTanStack/ai | 3.2k | — | ~3.3k | Automated safety check: Pass | MIT | |
| Project Timeline Reportthedotmack/claude-mem | 97k | 1 repos | ~3.1k | Automated safety check: Pass | Apache-2.0 | |
| Neat-Freak Knowledge CloseoutKKKKhazix/khazix-skills | 21k | — | ~1.9k | Automated safety check: Pass | MIT | |
| Beads Task Memorygastownhall/beads | 28k | — | ~1.2k | Automated safety check: Pass | MIT | |
| MemPalace Memory SearchMemPalace/mempalace | 59k | — | ~1.4k | Automated safety check: Pass | MIT | |
| Reflect on Session Learningscursor/plugins | 10k | 5 repos | ~1.2k | Automated safety check: Pass | None |
thedotmack/claude-mem
Writes a narrative Journey Into report on a project's whole development history, built from the timeline that claude-mem has recorded.
KKKKhazix/khazix-skills
Brings project docs, agent rule files, authorized memory and leftover workspace files back in line with what the code and runtime actually do at the end of a work session.
gastownhall/beads
Tracks multi-session work with dependencies in the bd issue tracker so the agent can find ready tasks and recover its context after conversation compaction.
MemPalace/mempalace
Mines project files and conversation exports into a local, searchable memory palace and recalls past work by semantic search through the mempalace CLI.
cursor/plugins
Starts three parallel reviewer subagents over the current conversation transcript, then turns their findings into concrete edits to existing skills.
EveryInc/compound-engineering-plugin
Records one solved and verified problem as a durable learning in the repository, but only when the reasoning is not already clear from the final code, tests or docs.
TanStack/ai
A skill your agent uses when the user invokes /i-have-adhd, says they have ADHD, or asks for ADHD-friendly output.
TanStack/ai
Sweep open (or listed) PRs with up to 100 parallel agents: security-scan outside contributors, rebase onto main when behind (push --force-with-lease), approve pending first-time-contributor CI when…
TanStack/ai
A skill your agent uses when wiring honcho() from @tanstack/ai-memory/honcho — a hosted memory adapter where recall is a dialectic answer over the user's representation (no discrete fragments).
TanStack/ai
A skill your agent uses when wiring inMemory() from @tanstack/ai-memory/in-memory — explains setup, options (embedder, extract, topK/minScore), when to pick it (dev/tests/single-process demos), and…
TanStack/ai
A skill your agent uses when wiring redis() from @tanstack/ai-memory/redis in production — covers client setup (ioredis or node-redis via fromNodeRedis), the storage model, client-side ranking…
TanStack/ai
A skill your agent uses when adding a public teaching example or a docs tutorial.
Works with
Categories
Durability and state persistence for TanStack AI chats with @tanstack/ai-persistence. AI Persistence is an agent skill from TanStack/ai. Durability and state persistence for TanStack AI chats with @tanstack/ai-persistence.
AI Persistence fits situations like: conversations must survive reloads; server restarts — NOT for stream reconnect alone.
Run `npx skills add TanStack/ai --skill ai-persistence -a claude-code`. Or copy the skill folder (packages/ai-persistence/skills/ai-persistence in TanStack/ai) into .claude/skills/ai-persistence in your project. Claude Code loads it when a task matches its description.
Run `npx skills add TanStack/ai --skill ai-persistence -a codex`. Or copy the skill folder (packages/ai-persistence/skills/ai-persistence in TanStack/ai) into .agents/skills/ai-persistence in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add TanStack/ai --skill ai-persistence -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/ai-persistence, .gemini/skills/ai-persistence, .github/skills/ai-persistence and .opencode/skills/ai-persistence in your project.
SKILL.md names no scripts, command-line tools or credentials: AI Persistence is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
AI Persistence is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with AI Persistence: Project Timeline Report (thedotmack/claude-mem, 97k stars), Neat-Freak Knowledge Closeout (KKKKhazix/khazix-skills, 21k stars), Beads Task Memory (gastownhall/beads, 28k stars) and MemPalace Memory Search (MemPalace/mempalace, 59k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
TanStack (a GitHub organization) maintains it in TanStack/ai, which has 3,169 GitHub stars. The repository holds 24 skills in this directory. The repository was last updated on October 7, 2026.
Source: TanStack/ai on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.