-
Notifications
You must be signed in to change notification settings - Fork 0
Architecture
tavlean edited this page Jul 2, 2026
·
1 revision
File map, the two data paths, and the conventions that keep the Store reviewer happy. For how data reaches the extension at all, read Data Contract first.
package.json Raycast manifest: 2 commands, 4 tools, dataUrl preference
ai.yaml AI instructions + evals (current docs: root ai.yaml, NOT package.json.ai)
assets/icon.png 512×512 site logo (own background — works light & dark)
src/
search-models.tsx Search Models command
search-benchmarks.tsx Search Benchmarks command
tools/ 4 AI tools: search-models, get-model, rank-models-by-benchmark, compare-models
lib/
types.ts Dataset / ModelRow / BenchmarkDef (+ index signatures — tolerate unknown fields)
constants.ts DEFAULT_DATA_URL, COMPOSITE_KEYS (fixed display order), SITE_ROOT
data.ts useDataset() — React hook for view commands (useFetch, SWR, failure toast)
dataset.ts loadDataset() — non-hook path for AI tools (fetch + Cache, 1 h TTL, stale fallback)
collections.ts deriveDatasetCollections(): benchmarksByKey / realBenchmarks / composites — ONE derivation, both paths use it
resolve.ts deterministic fuzzy resolution (models + benchmarks): exact key → exact name → substring → word prefix; ambiguity returns candidates
ranking.ts sortModelsByKey (honors ascending, missing always last), rankModelsForBenchmark
format.ts formatScore (percent=fraction×100 / integer / currency, missing="—"), formatCost
React hooks don't work in AI tools (plain async functions), so:
-
View commands →
useDataset()(data.ts):useFetchgives stale-while-revalidate — instant reopen, background refresh,keepPreviousData, failure toast, manual "Refresh Data" action callingrevalidate(). -
AI tools →
loadDataset()(dataset.ts): plain fetch +Cache(namespace"dataset"), skip refetch under 1 h, fall back to any-age cache when the network fails. Both shareDEFAULT_DATA_URL, thedataUrlpreference, andderiveDatasetCollections()— change data logic in ONE place.
-
Never render empty: lists pass
isLoading(no empty-flicker); the Reasoning Levels table renders only columns with ≥1 value and levels with ≥1 value, and is omitted entirely otherwise (defense in depth — the endpoint also filters empty levels, but stale caches exist). - Benchmark labels:
namealone (see Data Contract "Rules that bite"). - Detail panels: markdown tables for scores,
Metadatafor structured facts,Metadata.Linkforlinks[](objects{title, url}— NOT strings; this was a real bug once). - AI tools: outputs capped (limits clamped to 25), fuzzy matches echoed back precisely (
benchmark: {name, key}) so misresolution is visible, ambiguity returns top-3 candidates instead of guessing.
- The extension repo ships to the Store verbatim — no docs, no
.claude/tracked, nothing extra. Docs live in this wiki. -
.claude/PROJECT_BRIEF.mdexists locally in the extension repo (untracked, gitignored) so Claude sessions get oriented; it points here. - Screenshots for the Store go in
metadata/at the extension root (3–6 PNGs, 2000×1250) — added at R4. - Validation:
npm run build+npm run lint(ray CLI). Manual test:npm run devopens it in Raycast. No test suite — same as DevServers. - Submission:
npm run publishvia the existing forktavlean/raycast-extensions; author handletavlean.