Meltype
This is Japanese input that melts the wall between half-width and full-width, like thawing snow.
AI translation
Every post you saved, on every platform, in one inbox.
Translation pending
ProductivityTypeScript · CSSGitHub @shubhamsinalkarOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
One inbox for everything you save. Collects bookmarks from your browser, X, Reddit, Instagram, LinkedIn and YouTube Watch Later through a Chrome extension, with AI summaries and search by meaning
Loading the full README.
Read the full README ↗Every post you saved, on every platform, in one inbox — summarised, linked across platforms, and resurfaced so you actually use it.
https://github.com/user-attachments/assets/8dd438a1-adcc-41dd-8c75-b49fd279c393
bookmark-captain-extension.zip
from the latest release
and unzip it into a folder you'll keep. Chrome runs the extension from that folder.chrome://extensions, turn on Developer mode (top right), click Load unpacked
and choose the unzipped folder (the one containing manifest.json).Updates don't install themselves yet: download the new zip, replace the folder's contents, and
click the reload icon (↻) on Bookmark Captain in chrome://extensions.
Using the app? Read the User Guide: setup, connecting platforms, the inbox, and troubleshooting.
utm_*, fbclid, si, …) are stripped, and the same
page saved twice (or from another platform) is detected instead of duplicated.bookmarks.html — exports from Chrome, Firefox, Safari or Edge, with folder paths.apps/
api/ Express 5 API — auth, API tokens, bookmarks, live events (SSE)
web/ Next.js 16 web app (App Router, Tailwind CSS 4, TanStack Query)
extension/ Chrome extension (Manifest V3), bundled with esbuild
packages/
db/ Drizzle ORM schema, Postgres client (Neon-ready), SQL migrations
shared/ Types, zod schemas, URL normaliser; `@bc/shared/constants` is dependency-free
e2e/ Playwright end-to-end tests (API + web + real Chromium with the extension)
Tooling: pnpm workspaces, Turborepo, TypeScript (strict), ESLint (type-aware), Prettier, Vitest + Supertest, Playwright, GitHub Actions CI.
.nvmrc) and pnpm 10 (corepack enable)production, dev (local development) and
test (wiped by the test suites). Docker is optional (pnpm db:up) for working offline.pnpm install
cp .env.example .env # fill in the Neon connection strings (see "Using Neon")
pnpm db:migrate # apply migrations to DATABASE_URL
pnpm dev # API on :4000, web on :3000, extension rebuilt on change
Open http://localhost:3000 and use Development sign-in (any email) — no Google setup needed locally.
pnpm --filter @bc/extension build (or keep pnpm dev running).chrome://extensions, turn on Developer mode, click Load unpacked and choose
apps/extension/dist.The extension is built for the URLs in .env (NEXT_PUBLIC_API_URL, WEB_URL); override with
EXTENSION_API_URL / EXTENSION_WEB_URL for other environments.
| Command | What it does |
|---|---|
pnpm dev | Run every app in watch mode |
pnpm test | Unit + integration tests (uses TEST_DATABASE_URL) |
pnpm test:e2e | End-to-end tests on ports 3100/4100 against TEST_DATABASE_URL |
pnpm lint | ESLint with type-aware rules |
pnpm typecheck | tsc in every package |
pnpm format | Prettier |
pnpm build | Production builds (API bundle, web app, extension) |
pnpm db:generate | Create a SQL migration after editing packages/db/src/schema.ts |
pnpm db:migrate | Apply pending migrations |
pnpm db:studio | Browse the database with Drizzle Studio |
The first pnpm test:e2e needs a browser: pnpm --filter @bc/e2e exec playwright install chromium.
The e2e suite builds its own copies of the web app (apps/web/.next-e2e) and extension
(e2e/.extension), so it never disturbs pnpm dev or your dev data.
| Method & path | Auth | Purpose |
|---|---|---|
GET /bookmarks | session or token | List with view, platform, q, cursor paging |
POST /bookmarks | session or token | Save one link (returns the existing one if saved) |
POST /bookmarks/ingest | session or token | Idempotent bulk upsert (≤ 500 items per request) |
POST /bookmarks/remove | session or token | Mirror deletions made at the source |
PATCH /bookmarks/:id | session or token | Change status / snooze |
DELETE /bookmarks/:id | session or token | Delete |
GET /events | session or token | Server-sent events: bookmarks.changed |
GET/POST /api-tokens | session only | List / create API tokens (e.g. for the extension) |
DELETE /api-tokens/:id | session only | Revoke a token |
DELETE /api-tokens/current | token only | A client revokes its own token (disconnect) |
/auth/*, GET /me | — | Sign-in, sign-out, current user |
Errors always have the shape { "error": { "code", "message", "details?" } }.
dev and test branches
from production (or neonctl branches create --name dev).dev branch, copy the pooled connection string into DATABASE_URL and the
direct one into DATABASE_URL_UNPOOLED. Migrations use the direct connection.test branch's direct connection string into TEST_DATABASE_URL.sslmode=verify-full in every URL.pnpm db:migrateThe production branch is only touched by deployments (pnpm db:migrate with production env vars).
Point your host's health check at /healthz (process liveness, no database access), not
/readyz — frequent readiness probes would keep the Neon compute from scaling to zero.
{API_URL}/auth/google/callback (locally http://localhost:4000/auth/google/callback).GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.HttpOnly, SameSite=Lax
cookie; the database stores only its SHA-256 hash. Sliding 30-day expiry.bct_…) for the extension are also stored hashed, expire after a year, can only be
created from a browser session, and can be revoked from Settings → Connected devices.window.postMessage on the web app's own connect page;
the background worker only accepts it from that exact origin and path.state check.SameSite=Lax plus an Origin allow-list on every cookie-authenticated state change.app.example.com and api.example.com, set COOKIE_DOMAIN=example.com
so the Next.js server can read the session cookie.TRUST_PROXY to the number of proxies in front of the API so client IPs and rate limits are correct.LISTEN/NOTIFY.pnpm --filter @bc/api build && pnpm --filter @bc/api start (bundled to apps/api/dist).