This repo ships every ThreatCrush surface from one tree. pnpm workspaces. Node ≥ 22.
.
├── apps/
│ ├── web/ Next.js 16 — threatcrush.com (PWA, API, org pages)
│ ├── cli/ @profullstack/threatcrush — CLI + threatcrushd daemon + TUI
│ ├── desktop/ @profullstack/threatcrush-desktop — Electron + react-blessed
│ ├── mobile/ Expo (deferred for v0.1.0)
│ ├── extension/ Vite + React MV3 extension (dev preview)
│ └── sdk/ @threatcrush/sdk — types for module authors
├── supabase/ Migrations + seed SQL
├── scripts/ release, version-bump, submit-packages, smoke-test
├── docs/ SURFACES.md, PRE_LAUNCH.md, FUTURE_PLANS.md, etc.
├── boilerplates/ Starter module template
├── Dockerfile Builds apps/web as standalone for Railway
└── railway.json Deploy config
From the repo root:
pnpm install # hydrate all workspaces
pnpm dev # run apps/web in dev mode
pnpm build # build apps/web
pnpm build:cli # build apps/cli (CLI + daemon bundles)
pnpm build:desktop # build apps/desktop
pnpm build:all # build every app (recursive)
pnpm test # run every app's test script
pnpm version:patch|:minor # bump all package.json versions in lockstep
pnpm --filter <pkg> <cmd> # target one workspacePer-app dev loops live in each apps/<name>/README.md.
- Web API —
apps/web/src/app/api/** - Daemon —
apps/cli/src/daemon/(boot, IPC, alerts, module host, runs worker) - CLI commands —
apps/cli/src/commands/*.ts - TUI —
apps/cli/src/tui/app.tsx(react-blessed) - Desktop ↔ daemon IPC —
apps/desktop/src/main/daemon-client.ts - Shared CLI config —
apps/cli/src/core/cli-config.ts(bearer token lives at~/.threatcrush/config.json) - Runtime paths —
apps/cli/src/daemon/paths.tspicks/etc/threatcrushwhen root,~/.threatcrushotherwise
.envat the repo root is symlinked intoapps/web/.envso Next.js picks it up duringpnpm dev.- The daemon reads
/etc/threatcrush/threatcrushd.conf(or~/.threatcrush/threatcrushd.conf) for alert channels + modules. SENTRY_DSNandNEXT_PUBLIC_SENTRY_DSNare optional. Unset → no-op.
pnpm version:minor— bumps everypackage.jsonand tagsv<version>git push --follow-tags- GitHub workflows kick in:
npm-publish.ymlpublishesapps/clito npmdesktop-release.ymlbuilds + uploads Electron artifactsdocker-publish.ymlpushes the web image to GHCR + Docker Hub
railway up(or push to the tracked branch) deploysapps/web
See docs/SURFACES.md for the status of every interface + distribution channel.
mkdir -p apps/<name>with its ownpackage.json— must be scoped@profullstack/…or@threatcrush/…- Add to
SURFACES.mdwithnot-startedbefore writing code — the row is your reminder - Add a
README.mdwith the dev loop so contributors don't have to guess
apps/cli/installs via the root workspace install — native deps (better-sqlite3) rebuild automatically- Next.js standalone output in
apps/web/.next/standalone/apps/web/— theDockerfilecopiespublic/and.next/staticinto it because Next.js standalone doesn't include static assets - Electron packaging requires
npmRebuild: falsebecause pnpm's symlink layout confuses@electron/rebuild(there are no native deps in the desktop app anyway)