The Clinician profile frame inset its content 40px and drew a second
border around it — a box inside a box. Both came from CardFramePanel,
added in 44d653f. It doesn't exist in the COSS registry: upstream
@coss/card ships Card, CardFrame, CardFrameHeader/Title/Description/
Action/Footer and nothing else. There is no body part because the frame
isn't meant to pad its body.
CardFrame styles its cards through *direct-child* selectors — -m-px,
the clip-path, rounded-t/b-xl, shadow-none, before:hidden — pulling each
card out by a pixel so it sits flush inside the frame's own border. The
panel wrapper made every card a grandchild, so none of those selectors
matched: the 20px came from the panel's p-5, the second border came from
the card keeping the treatment the frame was supposed to suppress. The
commit that added it claimed the cards would "pick up the frame's card
treatment"; they never did.
Drop the panel and render children directly inside the frame, which is
the COSS default. Body padding goes on the Card, where COSS puts it, so
content is inset once rather than twice. Card-bearing bodies now get the
frame treatment they were meant to have, and the divide-y lists in
Records, Care team and Signing stack flush, which is what -m-px and
rounded-t-xl were for. The notification ToggleRows lose their space-y
wrapper and read as one list.
Frames holding raw form content (the AI panel, Care team's error and
toolbar) get an explicit padded Card instead of leaning on the frame.
card.tsx is now upstream @coss/card verbatim, minus font-heading on
CardTitle.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
temetro
An open-source AI middleman between clinicians and patient data.
Clinicians ask in plain language; temetro retrieves and organizes patient information as rich record cards — backed by a patient-owned data model.
What is temetro?
temetro is a clinical tool that puts a natural-language AI chat between clinicians and patient records. Instead of clicking through tabs, a clinician asks for what they need and temetro returns organized record cards — vitals, labs, medications, problems, encounters — with trend sparklines and detail views.
Its distinguishing idea is a patient-owned data model. Instead of (or alongside) living only in a doctor's database, a patient's record can live on the patient's own device. When a clinician adds or changes data they sign it (blockchain-style); the change is written to the patient's record and cannot be modified until the patient approves it through a companion wallet app. temetro can also read existing patient databases and present them in the same card UI.
"Decentralization" here means keys and data live on the patient's device and the relay only ever forwards ciphertext — it is not a literal blockchain. Records are off-chain, which is what lets a temporary share be deleted.
Features
- 🗂️ AI chat over patient records —
/patient <file#>(or natural language) renders the record as cards with sparklines and detail dialogs. - 🔐 Auth & multi-tenant clinics — email/password + staff usernames, organizations, and role-based access (owner / admin / doctor / reception / pharmacy / lab) via Better Auth.
- 🩺 Full clinical surface — patients, appointments, prescriptions, tasks, doctor's notes, pharmacy inventory, analytics, an activity audit log, real-time staff messaging, and notifications.
- 📲 Patient wallet & encrypted share — a companion app holds the record encrypted on-device; clinics import records over an end-to-end encrypted, patient-approved relay (with optional auto-deleting temporary shares).
- 🌐 Works across the clinic LAN — open it on the server or from any
department's computer at
http://<server-IP>:3000; no per-machine config. - 🔄 Self-update awareness — the app tells admins when a newer release is out and how to update.
Quick start (Docker)
The fastest path uses the prebuilt images published to Docker Hub. From the
backend/ directory (it holds the Compose file):
cd backend
docker compose pull # fetch the latest published images
docker compose up -d # start Postgres + backend + frontend
No .env or secret setup is required — the backend generates and persists any
missing secrets on first start. Then open:
- Frontend → http://localhost:3000
- Backend → http://localhost:4000 (health:
GET /health)
Prefer to build from source (for development)? Use docker compose up --build instead. Migrations apply automatically on backend start.
Port conflict? If host ports
5432,4000or3000are already in use, setPOSTGRES_PORT,BACKEND_PORTand/orFRONTEND_PORT(e.g.5433/4001/3001) inbackend/.env. The services still talk to each other on their internal ports (db:5432,backend:4000); only the published host ports change.
Access from other computers (hospital LAN)
temetro figures out the backend address from the host you open it on, so other
departments can simply visit http://<server-LAN-IP>:3000 — no rebuild
needed. Settings → About & updates shows the exact shareable address. The
server's firewall must allow ports 3000/4000.
Updating
docker compose pull && docker compose up -d
The app surfaces a notification when a newer release exists. See
CHANGELOG.md for what changed and RELEASING.md
for how releases are built and published.
Run without Docker
Each app runs independently (you'll need a local Postgres in DATABASE_URL):
# backend
cd backend && npm install && cp .env.example .env
npm run db:migrate && npm run dev # http://localhost:4000
# frontend (second terminal)
cd frontend && npm install && npm run dev # http://localhost:3000
With
SMTP_HOSTunset, verification / reset / invitation emails are printed to the backend console — no email setup needed for local development.
Monorepo layout
Two independent apps live side by side, each with its own package.json and
CLAUDE.md:
frontend/— Next.js 16 product app (the AI chat UI).backend/— Express 5 + Postgres API (Drizzle ORM + Better Auth). Seebackend/README.mdfor the API reference.
The patient wallet app and the marketing landing page live in their own separate repositories.
Tech stack
- Frontend: Next.js 16 (App Router) · React 19 · TypeScript · Tailwind CSS v4 · i18next · Socket.io client.
- Backend: Node ≥ 20 · TypeScript (ESM) · Express 5 · Postgres · Drizzle ORM · Better Auth (email/password + organizations/RBAC) · Socket.io · AI SDK.
Contributing
Issues and pull requests are welcome. Please keep each PR focused on one logical
change and run the type checks (npm run typecheck in backend/, npx tsc --noEmit in frontend/) before opening it. Bug reports and feature requests
have issue templates.
License
MIT.
