AutoCua
macOS·Windows·Linux·브라우저·iOS·Android용 컴퓨터 사용 에이전트(CUA)로 자동화
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Backpocket is a WhatsApp contact you share links, screenshots and reels to. It turns every save into a structured card (title, summary, key points, topics), stores it, and sends the right one back when you ask for it in the same chat.
I save things by sending them to my own WhatsApp chat: LinkedIn posts before coffee chats, recipes, how-to reels, internship postings. I almost never open them again, and when I need one I can't find it. The problem isn't reading. It's timing: a saved post is useful on the morning of the chat it relates to, not the day I saved it.
So Backpocket lives where the saving habit already is. You share to it like any contact, ask it questions in plain language, and tell it what you acted on ("applied to 1 and 3").
Not built yet: Notability notes, and reading application emails in a UNC Outlook inbox.
| Decision | Alternative I rejected | Why |
|---|---|---|
| WhatsApp as the only interface | Telegram bot, web app | It's where I already save things. Telegram was an hour less setup but a habit I don't have. |
| Ask for a screenshot when LinkedIn or Instagram hides a post | Scraping behind logins, downloading reels | Scraping breaks the platforms' terms and fails silently. A screenshot works every time and the user knows why it's asked. |
| Claude decides what a link-free message means, with a keyword check as backup | Keyword rules only | "Done with Nordstrom" or just "2" only makes sense next to the last list sent, which keyword rules can't see. The backup keeps the bot answering when the model call fails. |
| Answers capped near 200 characters | Full summaries | Early answers restated everything in the saved item. A reply should read like a friend who read it for you. |
| Strip tracking parameters before saving links | Store links as shared | The same LinkedIn post shared twice had different URLs, so duplicates slipped through. |
| Calendar and inbox read by an Apps Script in my own Google account | "Sign in with Google" | Google requires a paid security assessment for inbox access, and without it the login expires every 7 days. The script keeps the inbox inside Google and sends only confirmation-email metadata. It doesn't scale past a handful of users, which is fine for now. |
| No brief on quiet days | A daily message no matter what | A brief that's empty half the time teaches you to ignore it. |
| Remind about a saved job at most every 3 days, sooner near its deadline | Every unapplied post, every morning | Nagging is how reminders get muted. |
I wrote the spec and the rules in CLAUDE.md and built with Claude Code. Every change after the first version came from using it on my own saves: two screenshots racing for one link, LinkedIn previews cutting posts short, answers running too long. The commit history shows that trail.
POST /api/whatsapp for every incoming message.X-Hub-Signature-256 signature, returns 200 right away, and does the work in after() so Meta never retries a slow webhook.lib/extract.ts) reads Open Graph tags, page titles and JSON-LD recipes from links, and downloads screenshots. Pages that hide content behind a login are marked needs_fallback and the user is asked for a screenshot. No login scraping, no video downloads.claude-sonnet-5-5) turns the extracted content into a card using a strict tool schema, and picks the best matches when you search.text-embedding-3-small embeds each card for semantic search.items, resurfacings, match_items()), and screenshots in a private Storage bucket.lib/brief.ts): a Google Apps Script (bridge/) posts today's events and confirmation emails to POST /api/brief, signed with BRIDGE_SECRET. The server adds the published Outlook calendar if there is one, matches emails to saved job posts with Claude, embeds each meeting to find related saves, asks Claude which ones genuinely help, and sends one message. If WhatsApp's 24-hour window has closed, the brief waits in chat_state until the user writes.npm install.supabase/migrations/ in order.screenshots..env.example to .env.local and fill in every value. The app names any missing variable when it starts.npm run dev and open http://localhost:3000/api/health. You should see {"ok":true}.| Command | What it does |
|---|---|
npm run dev | Local dev server on port 3000 |
npm run build | Production build |
npm run lint | ESLint |
npm test | Vitest unit tests |
npm run simulate | Sends a signed fake WhatsApp webhook |
npm run simulate-brief | Builds the morning brief for a sample day (add --send to send it) |
npm run backfill-jobs | Finds job posts among items saved before job detection |
scripts/simulate.ts builds a realistic WhatsApp webhook payload, signs it with WHATSAPP_APP_SECRET from .env.local, and POSTs it to the webhook. It lets you test the full pipeline without a phone.
npm run simulate -- --text "https://www.example.com/some-article"
npm run simulate -- --text "what can I make with paneer?"
npm run simulate -- --text "hello" https://your-app.vercel.app/api/whatsapp
The URL defaults to http://localhost:3000/api/whatsapp. The sender is the first number in ALLOWED_PHONES.
Against a server with a real WHATSAPP_TOKEN (including the deployed app), every simulated message gets a real WhatsApp reply on that phone, and test items mix with real ones. To test without sending anything, run the local server with a fake token: WHATSAPP_TOKEN=fake npm run dev.