A privacy-first Google Drive / Dropbox clone built on Solid Pods.
File data lives in the user's pod as LDP binary resources. Sharing flows through WAC/ACP and pod-to-pod notifications. No central server ever sees plaintext bytes — the only backend is the user's own Solid storage.
Status: All five v0 milestones (M1–M5) implemented and validated end-to-end in Playwright.
This app installs @mind-studio/core and @mind-studio/ui from GitHub Packages.
A committed .npmrc scopes @mind-studio to that registry; before installing, export
a GitHub token with read:packages (export NODE_AUTH_TOKEN=<PAT>).
(cd ../.. && docker compose up -d) # shared Mind CSS on :3011 (see ../../SOLID-SERVER.md)cd apps/drive
npm install
npm run seed:demo # populate alice + bob pods (under /alice/mind-drive/)
npm run dev # Next.js on :3060# open http://localhost:3060/connect → log in as alice@mind.local- M1: WebID OIDC login, /drive routing, breadcrumb navigation, folder traversal.
- M2: drag-drop upload, download, create folder, rename file (copy+delete), recursive delete, inline image/PDF/text/video/audio preview.
- M3: list/grid view toggle (persisted), image thumbnails in grid, filename search.
- M4: share with WebID (universalAccess WAC grant), public link toggle, revoke; auth state probed via
WAC-Allowheader. - M5: client-side AES-GCM-256 encryption on opt-in upload, passphrase-derived KEK (PBKDF2-SHA256, 250k iter, per-file salt), per-file random key wrapped in a
<name>.enc.jsonsidecar. Pod stores only ciphertext.
- Hard refresh / direct deep-link loses the in-memory Solid session — user has to click "Connect" again. We deliberately don't use
restorePreviousSession: truebecause CSS's silent OIDC is a full redirect, which infinite-loops. A persistent-session fix is v0.2 work. - No expiring share links — WAC has no time-bounded ACLs and CSS v7 doesn't ship ACP by default. v0.2 idea: a sidecar JSON with
expiresAt+ a scheduled revoke job. - No "Shared with me" view — would need LDN inbox notifications.
- No version history, no trash bin, no PDF first-page thumbnails, no recursive search, no full-text content search.
- Browser-only; refreshing keeps you signed out unless you go through
/connectagain.
Sibling prototype to codespaces. Same stack, different problem space. The bet: a meaningful slice of users will trade away gdrive/dropbox's OCR-quality search and decade-old sync clients in exchange for nobody but me can read my files, and I can walk away tomorrow.
| Service | Port |
|---|---|
| Next.js dev | 3060 |
| Pod host | shared Mind CSS :3011 (see ../../SOLID-SERVER.md) |
docs/PLAN.md— synthesis: scope, architecture, milestonesdocs/RESEARCH.md— what Solid gives us, what existing tools do, what we should reusedocs/FEATURES.md— MVP tier / differentiators / non-features / comparison table
AGENTS.mdin this directory for prototype-specific constraints (once code lands).
Versioning, CHANGELOG.md, and tags are automated with
release-please — don't tag or
edit CHANGELOG.md by hand.
- Commit to
mainusing Conventional Commits:fix:→ patch,feat:→ minor,feat!:/BREAKING CHANGE:→ major.chore:/docs:/refactor:/test:don't trigger a release. - release-please keeps an open "chore(main): release X.Y.Z" PR that rolls the
pending commits into
CHANGELOG.mdand bumps the version. - Merge that PR to release: it creates the
vX.Y.Ztag + GitHub Release, which firesrelease.ymlto build and push the Docker image to GHCR. - Deploying the image to production is a separate, manual GitOps step in
mindpods-infra(mind-deploy.sh).