shapeshift README

The project's README from github.com/anishfn/shapeshift. As one markdown file: README.md.

Shapeshift

An input that becomes what you mean. One text box that morphs into the right UI as you type — an event card, a checklist, a timer, a color picker, a bill splitter, a poll, a converter and more.

Typing 'dinner with priya friday 8pm on zoom' morphs the text box into an event card, then a shopping checklist
Try it live · Watch the full 60-second demo (1080p60)

dinner with priya friday 8pm on zoom   →  Event card · Friday · 8 PM · Priya · Video call
buy milk, eggs, bread and coffee       →  Shopping checklist
split 2400 between 3                   →  ₹800 each
minecraft diamond                      →  #4AEDD9

Intent is classified by TypeSafe AI's Jev model: one call answers 14 typed questions in parallel (which card, plus signals like "is it a video call?", "is it urgent?"). Everything else — dates, amounts, units, math — is deterministic code. Jev decides, code computes.

One Jev call answers 14 questions in parallel; a deterministic parser reads the same text for values

It works fully offline by default with a built-in keyword classifier, so you can run it without an account.

Quick start

Requires Bun 1.2+.

bun install
bun dev

Open http://localhost:3000 and start typing. Press / to see every card type.

Use the online Jev model (optional)

cp .env.example .env.local
# then set TYPESAFE_API_KEY=... (get one at https://console.typesafe.ai/keys)

Restart bun dev. The latency readout in the bottom-right corner switches from jev-offline to jev-1.13.0. The key is only ever read on the server (/api/intent); it never reaches the browser. If the API is unreachable or rate-limited, Shapeshift quietly falls back to offline mode.

Variable Default What it does
TYPESAFE_API_KEY (empty) Enables the online model. Empty or placeholder values keep you offline.
JEV_MODEL jev-1.13.0 Pinned model version.
NEXT_PUBLIC_USE_MOCK false true forces offline even with a key.
NEXT_PUBLIC_SITE_URL http://localhost:3000 Used for Open Graph metadata.

Card types

Card Try
Event lunch with rahul and anna tomorrow
Reminder remind me to pay rent tomorrow urgent
Checklist buy milk, eggs, bread and coffee
Timer 25 min focus
Habit gym 3x a week
Color #ff6b35, tiffany blue, minecraft diamond
Split split 2400 between 3
Expense spent 450 on uber
Convert 5 miles in km, 72f to c
Calculate 18% of 3450
Trip flight to goa next weekend
Poll pizza or burgers for friday?
Contact rahul 98200 12345 [email protected]
Bookmark https://vercel.com/blog check later
Countdown days until christmas
Time zone 3pm pst in ist, what time is it in tokyo
Random roll 2d6, flip a coin, pick one: tacos, sushi or pizza
Goal read 12 books this year, 4 done
Note anything else

Saved cards live in your browser (localStorage) until you delete them. Click one to edit it.

Keyboard

Key Action
Enter Save the card
Esc Clear (or cancel an edit)
Tab Keep a faint preview
← → Choose between "Did you mean" chips
/ Open every card type

URL flags: ?debug=1 shows every probability; ?demo=1&loop=1 plays a scripted demo.

How it works

Keystroke, debounced hook, server route, Jev or offline classifier, decide, gate signals, parse, card

Raw model output flickers as you type, so a small state machine turns confidence into calm UI states. A card only changes when a challenger wins twice in a row (or is very sure), and signal badges use an on/off hysteresis band.

States: input, ghost preview, choose between two chips, committed card, with the thresholds between them

The diagrams are Excalidraw files — open any docs/diagrams/*.excalidraw at excalidraw.com to edit them.

Path What lives there
src/components/intents/registry.ts The extension point. One entry per card type.
src/lib/jev/questions.ts The Jev question schema
src/lib/jev/mock.ts Offline keyword classifier (same output shape)
src/lib/parse/ One deterministic parser per card type
src/lib/decide.ts, src/lib/signals.ts The calm-UI state machine
src/components/shapeshift/ Shell, chips, palette, saved list, HUD

Adding a card type

  1. Add the key to INTENT_KEYS in src/lib/jev/types.ts.
  2. Add a non-overlapping criterion to intent in src/lib/jev/questions.ts.
  3. Write a parser in src/lib/parse/ and register it in src/lib/parse/index.ts.
  4. Write a card component in src/components/intents/ and add a registry entry.
  5. Teach the offline classifier in src/lib/jev/mock.ts, and add tests.

TypeScript will point at anything you missed.

Development

bun run check    # typecheck + lint + tests
bun test         # parser, decision, signal and classifier tests
bun run build

Stack: Next.js (App Router) · React 19 · TypeScript (strict) · Tailwind CSS v4 · shadcn/ui · Motion · chrono-node · zod.

License

MIT

shapeshift (anishfn/shapeshift)

Searching Database…

这是什么?Shapeshift 是一个单一的文本输入框,会根据它对你意图的理解,随着你的输入变成合适的 UI 控件——日程卡片、清单、计时器、取色器、账单分摊、投票、换算器等等。
这是在浏览器里打开的 Web 应用,还是需要安装的程序?它是一个 Next.js Web 应用(App Router、React 19),在本地运行,然后在浏览器中打开。
怎么让它跑起来?安装 Bun 1.2+,然后运行开发服务器并在浏览器中打开,即可开始输入——不需要账号。
使用它需要在线 API 密钥吗?不需要——它开箱即用、完全离线,依靠内置的关键词分类器工作。添加 TYPESAFE_API_KEY 是可选的,只是用来启用在线 Jev 模型。
输入时的卡片识别有多可靠?输入过程中模型的原始输出可能闪烁不定,因此由一个状态机控制,只有当挑战者连续两次胜出(或非常有把握)时才切换卡片;如果在线 API 无法访问,它会静默回退到离线模式。
它能生成哪些类型的 UI 卡片?十九种卡片类型,包括日程、提醒、清单、计时器、习惯、颜色、分摊、开支、换算、计算、行程、投票、联系人、书签、倒计时、时区、随机、目标和笔记。
Jev 模型如何与确定性代码配合工作?一次 Jev 调用会并行回答 14 个带类型的问题来分类意图(用哪种卡片,以及紧迫程度等信号);其余一切——日期、金额、单位、数学计算——都由确定性的解析代码处理,而不是模型。
可以添加自己的卡片类型吗?可以——在 INTENT_KEYS 里加一个键,编写分类判据、解析器、卡片组件,并教会离线模拟分类器;TypeScript 会标出你遗漏的任何部分。
输入时快捷键行能做什么?Enter 保存卡片,Esc 清空或取消编辑,Tab 保留一个淡淡的预览,方向键循环切换「你是不是想要」提示条,/ 则展开所有卡片类型。
Creator
anishfn
Size
11.8 MB
Stars
972
Updated
CommitSep 23
Age
26d
Commits · 90 Days