PersonaPost reworks your whole LinkedIn from one place: headline, About, posts, comments and connection notes, plus what worked. It writes in your voice, leaves a [bracketed gap] instead of inventing facts, and never publishes a post you haven't approved.
- Studio: posts drafted from rough notes in your persona's voice; plan a whole week at once
- Growth Toolkit: headline, About, post ideas, hooks, comments and connection notes
- Review queue + calendar: approval-first, drag to reorder, auto-publish at your times
- Profile analysis: likes, comments, reposts, best day and hour from LinkedIn
- Bring your own AI: run drafts on your Claude Code or Codex subscription (see below)
- LinkedIn via official OAuth only (no passwords, no scraping, no auto-engagement)
- Cloudinary images, Razorpay credit packs
Pick one per account under Settings → AI Engine, with a Test connection button.
| Engine | Needs | Credits |
|---|---|---|
| Claude Code | claude CLI installed and logged in on the server machine |
free |
| Codex | codex CLI installed and codex login on the server machine |
free |
| Groq API | GROK_API_KEY |
charged |
Local engines are spawned with every tool disabled (claude -p --tools "", codex exec -s read-only), and ANTHROPIC_API_KEY / OPENAI_API_KEY are stripped from their environment so they bill your subscription, not an API key. They only work when PersonaPost runs on your own machine, and each person should use their own login: don't expose your personal subscription to other users of a hosted instance.
"Sign in with LinkedIn" uses LinkedIn's OAuth: you log in on LinkedIn's page and PersonaPost gets a revocable token (w_member_social, profile, email). PersonaPost never asks for or stores a LinkedIn password; password-based automation violates LinkedIn's User Agreement and gets accounts restricted. LinkedIn's API doesn't allow apps to edit your headline or About, so the Toolkit gives you options to paste.
- Next.js 16 (App Router)
- React 19 + TypeScript
- Convex (database + backend functions)
- SWR
- Cloudinary
- LinkedIn OAuth
- Razorpay
app/- Next.js App Router pages and API routescomponents/- UI componentsconvex/- Convex schema and functionslib/- integrations, auth, AI, utilitiespublic/- static assets (logos, icons, screenshots)
- Install dependencies:
npm install- Start Convex + Next.js:
npm run dev- Open:
Copy .env.example to .env.local and fill values.
NEXT_PUBLIC_CONVEX_URLSESSION_SECRET(required in production)- An AI engine: the
claudeorcodexCLI on the server machine, orGROK_API_KEY NEXT_PUBLIC_APP_URLin production, so LinkedIn/Slack link previews get absolute image URLs
CONVEX_DEPLOYMENTNEXT_PUBLIC_CONVEX_SITE_URLNEXT_PUBLIC_APP_URLGROK_MODELRAZORPAY_KEY_IDRAZORPAY_KEY_SECRETNEXT_PUBLIC_CLOUDINARY_CLOUD_NAMECLOUDINARY_API_KEYCLOUDINARY_API_SECRETLINKEDIN_CLIENT_IDLINKEDIN_CLIENT_SECRETLINKEDIN_REDIRECT_URILINKEDIN_REQUEST_OFFLINE_ACCESS
- Posts are never published without user approval
- Scheduled queue order determines publishing priority
- Retry/backoff and dead-letter protections are built into publishing flow
- Disconnected channel constraints are surfaced in scheduling/publishing flows
npm run dev- run Next.js + Convex concurrentlynpm run lint- lint codebasenpm run build- production buildnpm run convex:dev- run Convex dev servernpm run convex:deploy- deploy Convex functions
Convex only answers this project's Next.js server. The server sends the OIDC token Vercel issues to every function, Convex verifies it (convex/auth.config.ts), and each function checks the token's subject against the deployment's VERCEL_OIDC_SUBJECT env var (production accepts only …:environment:production). There is no shared secret. Locally, vercel env pull .env.local writes a development token that lasts about 12 hours; run it again when calls start failing with "Unauthorized".
Run before deploy:
npm run lint
npm run buildMinimum production env:
SESSION_SECRETNEXT_PUBLIC_CONVEX_URLGROK_API_KEY(hosted deploys have no local CLI)- LinkedIn keys for LinkedIn features
- Cloudinary and Razorpay keys for those feature paths