mirror of
https://github.com/hanzoai/bot-hub.git
synced 2026-10-30 18:46:42 +00:00
Migration from Convex/Vercel to self-hosted infrastructure: API Backend (api/): - Hono server with PostgreSQL (Drizzle ORM) + pgvector - Skills CRUD, search (hybrid vector + lexical), auth (hanzo.id OAuth) - Upload (MinIO S3), stars, comments, API tokens - Rate limiting middleware, session management Frontend Adapter (src/lib/): - api.ts: REST API client replacing Convex SDK - hooks.ts: React hooks replacing convex/react useQuery/useMutation - AuthContext.tsx: Auth provider replacing ConvexAuthProvider Deployment: - Dockerfile (multi-stage: API build + web build + production) - K8s manifests for hub.hanzo.bot on hanzo-k8s - GitHub Actions CI/CD (build → GHCR → deploy) Rebrand: - clawhub/clawdhub/ClawHub → bothub/Bot Hub - Domain: clawhub.ai → hub.hanzo.bot - CLI: clawhub → bothub - Package: @hanzo/bot-hub-api
2.8 KiB
2.8 KiB
summary, read_when
| summary | read_when | ||
|---|---|---|---|
| Skill version diffing mode (Monaco-backed) |
|
Diffing mode
Goals
- Compare any file between two versions.
- Default compare:
latestvsprevious(SemVer precedence). - UX feels native to Bot Hub (theme + typography + motion).
- Inline or side-by-side toggle.
- Public access.
UX
- Diff card on skill detail page.
- Two selectors: Left/Right.
- Items: version strings, plus tags (e.g.
latest), plusprevious. - Default: Left =
previous, Right =latest.
- Items: version strings, plus tags (e.g.
- File list with status: added / removed / changed / same.
- Default file:
SKILL.mdif present; else first changed file.
- Default file:
- Toggle: Inline vs Side-by-side.
- Show size guard message when file > 200KB.
SemVer ordering
- Use SemVer precedence to sort versions.
previous= immediate predecessor oflatestby SemVer.- If
latestmissing or only one version:- Disable
previousand show empty-state copy.
- Disable
Data sources
- Versions:
api.skills.listVersions(all, not just latest 10). - Tags:
skill.tagsmap. - File list:
version.fileswithpath,sha256,size.
API
Add action:
skills.getFileText({ versionId, path }) -> { text, size, sha256 }- Validate version exists + file path exists in version.
- Enforce size <= 200KB (both in action and client).
- Use
fetchTextfromconvex/lib/skillPublish.ts.
Optional helper action:
skills.getVersionFiles({ versionId }) -> files[]- If we want lightweight fetch without full version object.
Client flow
- Fetch versions + tags.
- Resolve default compare pair:
- Right = tag
latestif present else highest SemVer. - Left =
previous(SemVer predecessor).
- Right = tag
- Build file union by path.
- For selected file:
- Fetch left/right text (guard by size).
- Feed into Monaco diff editor.
Monaco theming
- Define
bothub-light/bothub-darkviamonaco.editor.defineTheme. - Derive colors from CSS variables on
document.documentElement:--surface,--surface-muted,--ink,--ink-soft,--line,--accent.
- Apply theme on load + when theme changes (
data-theme). - Match font:
var(--font-mono). - Set diff options:
renderSideBySidetogglediffAlgorithm: 'advanced'renderSideBySideInlineBreakpointfor mobilewordWrap: 'on'
Edge cases
- File removed/added: show empty buffer on missing side + label.
- Non-text file should not exist (upload rejects), but still guard.
- Large file: show size warning + disable fetch.
- Missing version: show error state.
Perf
- Cache file text per version+path in client state.
- Debounce selector changes (100-200ms).
- Limit concurrent fetches to 2.
Tests
- Unit: SemVer ordering +
previousselection. - Component: default selectors, tag inclusion, size guard.