AI Decision System
Replayable, offline-verifiable records for AI-assisted go/no-go decisions: experiment promotions, typed model answers and human-approved actions.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Paste a public GitHub repo, ask it a question, and an agent composes an interface around that repo's data, live, from a hand-built component catalog.
Demo: coming · docs/demo.gif (placeholder; the owner replaces this line when the video is recorded)檢視完整 README ↗Paste a public GitHub repo, ask it a question, and an agent composes an interface around that repo's data, live, from a hand-built component catalog.
Demo: coming · docs/demo.gif (placeholder; the owner replaces this line when the video is recorded)
Full-page generation is slow and expensive: minutes per page and hundreds of thousands of tokens (docs/00-brief.md). Here the model never writes HTML, CSS or a color. It picks components from a catalog and passes structured arguments, and code draws every piece. A golden question on one of the five sample repos is served from a precomputed composition with no model call (2 ms in a production build). A live question is one Haiku classification and one Haiku fill: in the 2026-10-12 eval run the median live template answer used 2,596 uncached tokens, 875 of them output, the whole set cost $0.0021 per answer, and answers finished at 6.2 s p50. That latency is still above the composer's targets because the fill runs before anything streams. Because the model only chooses, the catalog is the product: 21 designed components plus code-first primitives, each with five states, three densities, a Zod schema and its own motion. When a new answer replaces the old one, the screen rewrites in place: exits reverse entrances and pieces that survive morph instead of remounting.
repo + question
│
▼
GitHub API public REST and GraphQL reads · cached · "warming" while /stats computes
│ normalized repo data
▼
Composer model decides
│ router (Haiku): one of 15 templates, or off-template
├── template path: Haiku fills the prose slots of a fixed layout
└── off-template: Sonnet composes freely from the registry
│
▼
JSON composition meaning only: component, props, tone, emphasis, density
│ A2UI adapter both ways
▼
Renderer code renders
│ validates each piece against its Zod schema · diffs by stable id · streams JSONL
▼
Component catalog + design tokens
│
├── Web app apps/web
└── MCP App apps/mcp-app
The four layers, from the brief:
| Layer | What it is | Package |
|---|---|---|
| Component catalog | 21 designed components plus the code-first primitives. Each ships a Zod schema, five states, three densities, motion, and a sample JSON | packages/ui |
| Renderer | Takes a UI description, validates against the registry, diffs against the current tree so pieces morph instead of remount, streams pieces in as they arrive. A2UI adapter both ways | packages/renderer |
| Composer | Takes intent plus normalized repo data, returns a streaming UI description. Haiku picks a template; Sonnet composes off-template. Never writes HTML | packages/composer |
| Eval harness | Scores the composer on component choice, data binding, schema validity, latency and cost, across models. Results page in the app | packages/evals |
Numbers the model writes into prose are checked against the data they cite. A number that does not match is replaced by a system sentence. A malformed piece renders its error state with a logged reason; the renderer never throws on model output.
Each is a layout template and a row in the eval set. The landing page chips use these words.
| # | Question | Template |
|---|---|---|
| 1 | How's this repo doing? | overview |
| 2 | What's blocking the next release? | release-blockers |
| 3 | Who's carrying this repo? | contributors |
| 4 | Is CI getting slower? | ci-trend |
| 5 | What's been merged this week? | merged-recent |
| 6 | Which issues have gone stale? | stale-issues |
| 7 | Show me the biggest open PR | biggest-pr |
| 8 | Where would a new contributor start? | new-contributor |
| 9 | How responsive are the maintainers? | responsiveness |
| 10 | Compare this month to last | month-compare |
| 11 | When does this project get worked on? | punch-card |
| 12 | What changed between the last two releases? | release-diff |
Clicking a piece asks a follow-up. Three more templates answer those (check-failures, pr-detail, person), 15 in all. Anything else goes off-template to Sonnet. The full table, with the components each template uses, is in docs/golden-questions.md.
Node 22.12 or later · pnpm 10 (corepack enable picks up the pinned version).
Create .env.local at the repo root. It is gitignored; never commit it.
# Fine-grained personal access token · public repositories · read-only
GITHUB_TOKEN=
# Server side only
ANTHROPIC_API_KEY=
# Optional · daily spend cap in USD; when reached the site serves cached answers only
DAILY_CAP_USD=5
# Optional in dev (counters and cache stay in memory) · required in production
KV_REST_API_URL=
KV_REST_API_TOKEN=
pnpm install
pnpm dev
Next.js prints the local URL. Then:
/ · paste a repo or pick a sample, ask a question/catalog · every component in every state and density, drawn from its sample.json/evals · the latest eval resultsOther scripts:
pnpm test # render and schema tests
pnpm lint # ESLint, the copy rules and the CSS token check
pnpm e2e # Playwright
pnpm evals:run --model production --runs 3 # calls the Anthropic API and spends money
pnpm evals:check # reruns the 60 golden cases and fails on a regression
The renderer and the catalog are MIT packages under the @genui-github scope.
npm install @genui-github/renderer @genui-github/ui react react-dom
React 19. Load Plus Jakarta Sans (400 to 700) and JetBrains Mono (400, 500), for example from Google Fonts.
import { useState } from 'react'
import { createRoot } from 'react-dom/client'
import { Renderer, type Composition } from '@genui-github/renderer'
import releaseBlockers from '@genui-github/renderer/fixtures/1-release-blockers.json'
import checkFailures from '@genui-github/renderer/fixtures/2-check-failures.json'
import '@genui-github/ui/styles.css'
import '@genui-github/renderer/styles.css'
function App() {
const [composition, setComposition] = useState(releaseBlockers as Composition)
// A click on a piece arrives as a question. Swapping in the answer rewrites the
// screen in place: pieces that keep their id morph instead of remounting.
const onAsk = () => setComposition(checkFailures as Composition)
return <Renderer composition={composition} question="What's blocking the next release?" onAsk={onAsk} />
}
createRoot(document.getElementById('root')!).render(<App />)
To render a stream, feed each JSONL line to createStreamParser() and pass its tree: <Renderer tree={parser.push(chunk)} />. The package also exports the format as Zod schemas, diff(prev, next), and toA2UI / fromA2UI. See packages/renderer/README.md and packages/ui/README.md.
apps/mcp-app exposes one tool, compose(repo, question), and draws the answer in a 420px frame inside a chat host that supports MCP Apps. It runs over stdio, or Streamable HTTP on port 3240 at /mcp. It reads the same .env.local, so the host config carries no secrets.
pnpm --filter @genui-github/mcp-app build
Claude Desktop setup is in docs/questions.md, entry 8.4.
Baseline from 2026-10-12: 99 cases × 3 runs per model. Every model composed 291 and refused the 6 it should (private and missing repos), with no failures. production is the shipped routing (Haiku classifies and fills, Sonnet off-template); sonnet composes everything with Sonnet; haiku composes everything with Haiku. sonnet skips routing by design, so template and bindings are not scored for it.
| Scorer | production | sonnet | haiku |
|---|---|---|---|
| template | 1.00 | not scored · no routing | 1.00 |
| components (mean F1) | 1.00 (0.993) | 0.25 (0.753) | 1.00 (0.993) |
| hot | 1.00 | 0.30 | 1.00 |
| schema | 1.00 | 0.89 | 0.99 (0.98 to 1.00) |
| bindings | 1.00 | not scored · no routing | 1.00 |
| numbers | 1.00 | 1.00 | 1.00 |
| rules | 1.00 | 0.91 (0.91 to 0.92) | 0.997 (0.99 to 1.00) |
| done p50 / p90 | 6.2 s / 8.3 s | 4.8 s / 7.3 s | 6.2 s / 8.6 s |
| first piece p50 | 6.0 s | 2.6 s | 6.2 s |
| cost per answer | $0.0021 | $0.0138 | $0.0007 |
| cost for 297 | $0.62 | $4.01 | $0.20 |
Haiku-only matches production on template, bindings and numbers at about a third of the cost; its misses are off-template copy-length and layout rules; Sonnet earns its cost only on off-template rule compliance. Against Sonnet composing everything, routing to templates costs about a sixth as much and uses the expected components every time (Sonnet: 0.25).
The full results are at /evals in the app and in packages/evals/results/. Reproduce with pnpm evals:run.
localStorage and a day-scoped rate-limit counter keyed on a hash, gone at midnight UTC.MIT. See LICENSE.