DeepSeek Harness Remote
DeepSeek Harness Remote: DeepSeek Harness 실행 PC와 모바일·PC를 안전하게 연결해 어디서나 작업 이어받기
채용 공고와 담당자를 찾아 Gmail로 메일 보내고 Naukri·Instahyre·Hirist에 지원해 답변을 면접까지 추적
Find hiring posts and the people behind them, email them from your own Gmail, apply on Naukri, Instahyre and Hirist, and track every reply through to the interview.
생산성GitHub @Jainprashuk온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
저장소 정보는 아직 수집하지 않았습니다.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
A personal cold-email outreach tool. Import contacts from CSV, personalise and approve emails per contact, send via Gmail, and automatically track bounces and replies.
저장소 README에서 가져옴
README 전체를 불러오는 중입니다.
README 전문 보기 ↗A cold-email and job-search tool. It finds people to contact (CSV, LinkedIn hiring posts, Hacker News, web search, company lookups), sends personalised emails through each user's own Gmail, reads the replies back from the mailbox, and tracks everything through to interviews.
It started as a single-owner tool. It is now multi-user: each account has its own contacts, templates, Gmail credentials and settings, and an admin decides who can sign in.
Stack: Node.js + Express · MongoDB Atlas (Mongoose 9) · Inngest (background jobs and crons) · React 18 + Vite + TypeScript (client/) · Vercel (region bom1) · Resend (sign-in codes and lifecycle emails)
cp .env.example .env # every variable is documented in that file
npm install
NODE_ENV=dev npm start # http://localhost:3000 → redirects to /app/
In a second terminal, run the Inngest dev server. Without it nothing sends and no cron runs:
npx inngest-cli@latest dev
To work on the frontend with hot reload:
npm run dev:client # Vite dev server for client/
Check which database you are on.
db.jsusesMONGODB_URI_PRODwhenNODE_ENV=prodandMONGODB_URI_DEVotherwise. If your.envsetsNODE_ENV=prod, a barenpm startwrites to the live database. The boot log says which one it picked.
There are no passwords. Sign-in is a six-digit code sent by email to a whitelisted address.
node scripts/invite-user.js [email protected] --admin --env=dev --execute
RESEND_API_KEY unset, the code is printed to the server log instead of emailed.AUTH_OPEN=1 (plus AUTH_OPEN_EMAIL once more than one account exists) to skip sign-in entirely. Local development only.The UI is a React single-page app served at /app/. Its source is in client/src/pages.
| Page | What it does |
|---|---|
| Dashboard | Replies waiting on you, sent/bounced counts, follow-ups due, and every contact |
| Analytics | Reply funnel, template and company performance, response speed, PDF reports |
| Contacts / Add Contacts | The contact list; add people by CSV/Excel upload or by hand |
Send (/send/step1–3) | One-off sends: pick contacts, approve each personalised email, send |
| Campaigns | Hands-off drip sending: a list is released a set number per day at a chosen IST hour |
| Mailbox | Replies, with "Needs you" tabs for the ones waiting on an answer; reply in place |
| Interviews | People who replied, and interview stages, dates and reminders |
| Leads | Hiring posts from LinkedIn, Hacker News, web search or pasted text, with recruiter emails |
| Discover | Type a company, find people who work there, and guess their work email from its pattern |
| Companies | One page per company combining contacts, posts, jobs, interviews and the email format |
| Library | Data shared across users (contacts, leads, companies only). Admin-gated, and each user can opt out |
| Jobs | Every role from Naukri, Instahyre and Hirist in one pipeline, with your outreach state per company |
| Naukri | Keeps a Naukri profile fresh and applies to jobs you approve, using a local worker |
| Templates | Email templates with {{variables}} |
| Blocklist | Addresses and whole companies that must never be emailed |
| Export Contacts | Spreadsheet download, or a read-only share link for outsiders |
| Logs | Everything the app did: sends, imports, scrapes, errors |
| Settings / Onboarding | Sender identity, Gmail App Password, resume, custom variables, API keys |
| Admin | Users and access requests, per-user numbers, Issues, Sending, AI call logs, lifecycle emails. Admins only |
The old static pages in the repo root (index.html, step1.html …) are the pre-React UI. / now redirects to /app/.
{{name}}, {{company}}, {{role}}, {{industry}}, {{jobTitle}}, {{sender}}, {{senderCompany}}, {{sentSubject}}, plus any custom variable defined in Settings. Rendering is in lib/renderTemplate.js.
Each user sends from their own Gmail account using an App Password (2-Step Verification on, then myaccount.google.com/apppasswords). It is entered in Settings and stored per user, encrypted with AES-256-GCM under CREDENTIAL_KEY (lib/credentials.js). If you rotate CREDENTIAL_KEY, every stored password becomes unreadable and has to be entered again.
When Gmail's daily limit is hit (SMTP 5.4.5), the batch pauses. An hourly quota-watcher resumes paused batches one account at a time.
Sending and scheduled work run as Inngest functions served at /api/inngest. The crons run in IST.
| Function | Trigger | Where |
|---|---|---|
send-email-batch, send-email-bulk, send-email-drip, send-single-email | events | inngest-fns.js |
quota-watcher / resume-after-quota | hourly at :05 / event | inngest-fns.js |
campaigns-run-due | hourly at :01 | lib/campaigns/inngest.js |
mailbox-sweep (fans out one check per account) | every 2 h | lib/mailbox/inngest.js |
companies-enrich-daily | 06:00 daily | lib/discovery/enrich |
sources-hn-daily / sources-web-daily | 07:00 on days 1–10 / 08:00 daily | lib/sources/inngest.js |
lifecycle-* (daily emails, Monday report, 21:00 admin digest) | daily / weekly | lib/lifecycle/inngest.js |
report-failed-functions | any failed function, logged to Admin → Issues | inngest-fns.js |
These workflows call the app with the X-Cron-Secret header. Set CRON_SECRET in Vercel and as a GitHub secret, and set VERCEL_APP_URL as a GitHub secret too.
check-mailbox.yml and run-campaigns.yml: now duplicated by the Inngest crons above and being retired. Running both at once is safe because campaign claims are atomic.GitHub turns off scheduled workflows after 60 days with no repo activity.
The mailbox check connects to Gmail over IMAP (lib/mailbox) and does three things:
In-Reply-To/References;CLASSIFIER_PROVIDER_ORDER (Groq, Gemini, Cerebras).A scan holds a 3-minute lease per account, so two scans never overlap.
LinkedIn harvesting and Naukri automation attach to a real, logged-in Chrome over CDP on your own Mac or Linux desktop. They cannot run on Vercel, in Docker or in CI, and they are opt-in for each account.
npm run scrape-worker # LinkedIn hiring-post harvest
npm run naukri-worker # Naukri refresh / harvest / apply
npm run workers # both
Each worker machine needs its own token from POST /api/scrapes/worker-token, set as WORKER_SECRET in that machine's .env. See worker/README.md for setup.
cd client && npm run build # Vercel does NOT build the client
git add client/dist # the committed dist is what ships
vercel --prod
vercel.json builds only server.js and ships the committed client/dist/**. If you change client/src without rebuilding and committing dist, the change will not show up in production.
The server must run in bom1, next to the Atlas cluster in Mumbai. In any other region every query pays a cross-world round trip.
A deployed instance refuses to boot without RESEND_API_KEY and OTP_FROM_EMAIL. Every variable is listed in .env.example. The ones a deployment needs:
| Variable | Purpose |
|---|---|
MONGODB_URI_PROD (+ NODE_ENV=prod) | Database |
CREDENTIAL_KEY | Encrypts stored Gmail App Passwords |
RESEND_API_KEY, OTP_FROM_EMAIL | Sign-in codes |
INNGEST_EVENT_KEY, INNGEST_SIGNING_KEY | Background jobs |
CRON_SECRET | GitHub Actions callers |
AUTH_SECRET | Signs the share-link cookie |
OUTREACH_URL | Links in lifecycle emails |
GROQ_API_KEY / GEMINI_API_KEY / CEREBRAS_API_KEY | Reply classification (optional) |
LIFECYCLE_FROM_EMAIL | Welcome, reminder and report emails (optional) |
scripts/ holds one-off tools and test suites. Scripts that change data are dry-run unless you pass --execute. Use --env=dev or --env=prod to pick the database.
| Script | Use |
|---|---|
invite-user.js | Whitelist, promote, disable or enable a user |
mint-session.js | Emergency sign-in if Resend is down |
import-gmail-credential.js | Move the legacy GMAIL_* env credential into the database |
clone-db.js | Back up a database before a migration |
lifecycle-preview.js | See who would get which lifecycle email |
view-replies.js | Inspect stored replies |
Test suites are named scripts/test-*.js and run with NODE_ENV=dev node scripts/test-<name>.js. Run these three after touching routes or auth:
test-tenant-isolation.jstest-token-isolation.jstest-admin-isolation.jsSome suites need the server running and take --email. Check the header of each file.
The API is defined in routes/ and mounted in server.js. Every /api route except the auth, share and cron endpoints needs a signed-in session and is scoped to that user.