TreeMap
A free, open-source disk-space visualizer. Squarified treemap, duplicate hunting, disk-full forecasting, and cleanup that only ever moves files to the Trash.
翻譯準備中
尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
Meeting notes you can trust the day after. A rebuild of Fathom for the 8x engineering assessment, built around the case the brief says matters most: an eight-person call that runs an hour.
• Live app: https://fathom-rebuild-iota.vercel.app. Press Try the demo account on the sign-in page: one click, no sign-up.
• Repository: https://github.com/Abdul-Rafay-web/fathom-rebuild
• Capture log: CAPTURE-TEST.md · prompts and responses in .agent-logs/
• Product plan & recon: PLAN.md · screenshots of Fathom in recon/
• Measured accuracy: EVAL.md檢視完整 README ↗Meeting notes you can trust the day after. A rebuild of Fathom built around the case the brief says matters most: an eight-person call that runs an hour.
CAPTURE-TEST.md · prompts and responses in .agent-logs/PLAN.md · screenshots of Fathom in recon/EVAL.mdFathom is excellent at capture. After using it end to end (recon/), what I kept running into was the day after: nobody re-watches an hour, and the notes can't be checked against what was said. On a big call, people come back with three questions:
| Question | What Afterword does | What Fathom does |
|---|---|---|
| "What do I have to do?" | Action items with owner, due date and the exact moment, plus a cross-meeting inbox grouped by owner | Action items per call, no cross-meeting view (and "None detected" on my test call) |
| "Can I trust the summary?" | Every summary line, decision and action item cites the transcript moment. Hover to see the verbatim quote, click to hear it. Claims the model can't back with a quote are dropped. | Summary with no links back to the source |
| "Where did we talk about X?" | Hybrid keyword + semantic search returning moments (speaker + timestamp), and Ask with cited answers across all meetings | Search returns calls |
Built
Changed
recon/notes.txt): press record and words appear.Cut, deliberately:
| Cut | Why |
|---|---|
| The bot that joins Zoom/Meet/Teams | The brief allows stubbing it. It's days of infrastructure work for no product insight, so the capture layer is browser recording + upload, feeding the same pipeline. |
| Calendar sync | It only exists to schedule the bot. |
| CRM, Deals, Alerts, Playlists, Refer, credits | Sales add-ons, not the core loop. |
| Sign-up | Reviewers get in with one click into a seeded demo workspace. |
/login, which remembers where they were going./c/…), by design.proxy.ts refreshes them and redirects visitors without one.lib/auth.ts. meetingAccess() returns none | read | write, and someone else's meeting is a 404.workspace_id (006_workspaces.sql). Search filters candidates by workspace in both retrieval arms before ranking./auth/v1/settings.There are six meetings for one fictional company, Tidewater, including Q4 planning: 8 people, 70 minutes. Story threads run across meetings (an offline-sync bug, a big deal, a hiring plan), so search and Ask have something real to connect. How they were made:
scripts/seed/specs.mjs).render-audio.mjs).ingest.mts).The transcripts, speaker names, notes and stats you see are genuine pipeline output, not hand-written fixtures. Because the truth is known, the pipeline is scored (EVAL.md).
| All six meetings | The 8-person hour | |
|---|---|---|
| Action-item recall | 92% (F1 82%) | 100% |
| Decision recall | 89% | 100% |
| Speaker count detected | correct in every meeting | 8 of 8 |
Browser ──upload (signed URL, direct to storage)──► Supabase Storage
│ │
│ POST /api/uploads/:id/complete │ Deepgram fetches media by signed URL
▼ ▼
jobs (Postgres) ─claim: FOR UPDATE SKIP LOCKED─► worker: transcribe → name_speakers → { stats, analyse, index }
▲ │ Gemini (schema-constrained JSON) + quote grounding
│ pg_cron (every min, only if work exists) / after() ▼
└──────────────────────────────────────────── utterances · speakers · insights · action_items · chunks(pgvector, tsvector)
syd1, next to the database.gemini-embedding-001 (768-d) for search.postgres. No UI kit: Tailwind v4 + hand-built components. Fonts are self-hosted: Newsreader (reading), Schibsted Grotesk (UI), Fragment Mono (timestamps).Databases
Job queue in Postgres. Workers claim with FOR UPDATE SKIP LOCKED, so serverless invocations never double-process. Completing a step and enqueuing its successors in the DAG happens in one transaction. A visibility timeout reclaims jobs whose worker died. Rate limits (429) get linear backoff and more attempts; real errors get exponential backoff. → pipeline/queue.ts
Indexes chosen for the access pattern:
(meeting_id, start_ms), so a clip's transcript is a range scantsvector + GIN for keyword searchIdempotency everywhere:
unique (meeting_id, step) jobsOptimistic concurrency on action items (version column; a stale write gets 409 plus the current row). → api/action-items/[id]
A rate limiter in Postgres: a fixed window via an atomic upsert. In-memory limiters reset on every serverless cold start. → ratelimit.ts
Advisory-locked migrations (scripts/migrate.mjs), plus RLS on every table. The browser can't read the database directly.
A bug worth knowing about: Supabase's transaction pooler can route pipelined statements to different backends, so one query got . The fix is , with concurrency coming from the pool instead. →
AI / ML
Grounder checks the quote against a ±3-line window around the cited line (models are often off by one or two), then the whole transcript, using word-bigram containment. Claims whose quote can't be found are dropped, never shown with a made-up timestamp. The notes footer says how many were discarded.gemini.tssearch.ts, chunk.tsask.tsscripts/eval.mts, Algorithms
intervals.tsbsearch.tsfuzzy.tsnpm test. Lint is clean under the React Compiler rules.OS / systems / frontend runtime
player.ts). A requestAnimationFrame loop feeds useSyncExternalStore selectors, so the transcript re-renders when the active line changes, not 60 times a second. The transcript is virtualized (~30 DOM rows for a 300+ line meeting).Recorder.tsx): one Opus encoder, two sinks.
bufferedAmount, then dropping the oldest slices, never the WebM header.recorder-store.ts handles recovery.performance.now()), not wall time.getaddrinfo calls occupy libuv's 4-thread pool and starve everything else that uses it, including file I/O. Fixes: a development-only public-DNS resolver with stale-while-revalidate caching (instrumentation-node.ts), and self-hosted fonts, so builds never depend on Google Fonts.running. The visibility timeout reclaims it, and the kick endpoint now counts stale locks as runnable work. That endpoint had a bug, and this incident found it.npm install
cp .env.example .env.local # Deepgram, Gemini, Supabase keys
npm run migrate # applies db/migrations/*.sql
npm run dev
Seed data (optional; needs API quota):
node scripts/seed/gen-scripts.mjs # dialogue from specs (Gemini)
node scripts/seed/render-audio.mjs # multi-voice audio (Deepgram Aura + ffmpeg)
npx tsx --conditions=react-server scripts/seed/ingest.mts # through the real pipeline
npx tsx --conditions=react-server scripts/eval.mts # score it → EVAL.md
After deploying: node scripts/schedule-worker.mjs https://<your-app> points the database's every-minute cron at the worker.
No meeting bot. I'd add a Recall.ai-style bot behind the same uploads/complete entry point; nothing downstream changes.
No auth. It's a single demo workspace by design. Next would be Supabase Auth plus RLS policies keyed on workspace membership. The schema already isolates everything per meeting.
Diarization can merge similar voices. An early render of the Harbor call merged two male voices, and action-item recall there was 33%. It reached 100% after two changes:
Per-workspace voice-print enrolment would be the proper long-term fix.
Polling, not Realtime, for pipeline progress. It's 2.5 s polls that also nudge the worker; simpler and robust. Supabase Realtime is already enabled on meetings/jobs (migration 002) for a later switch.
Live captions need a Deepgram key with token-grant permission. Without one, recording still works and the transcript arrives after stop. The UI says so instead of failing.
PLAN.mdmax_pipeline: 1sha256(prompt_version, template, transcript), so a prompt change can never serve stale output.