Codync
免费开源的 1:1 Grok Bot 与 Muse 替代方案。可在 iPhone、Mac 或 Linux 桌面上将 Claude 代码、Codex、Cursor 以及 40 多个编码代理作为持久机器人使用。支持群组聊天、线程、应用。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Handoff: hand a headless VM checkout to a real person. Device actions trigger the SDK's merchant callbacks in the VM over Firebase RTDB; results stream back.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Live at https://handoff.solutionbyhour.com
The fallback for agentic checkout. An AI agent checks out in a headless VM; when it can't finish (it needs the user's address, a choice, or their approval), it sends the user a fallback URL. The user completes the paysheet on their own device while the checkout SDK keeps running in the VM. The SDK (and its callbacks) stay in the VM; the device sends semantic actions, the VM fires the real callbacks, and results + state stream back.
Device UI (/pay/[code]) ⇄ Firebase RTDB sessions/{sid} ⇄ VM paysheet + SDK (/vm)
How it works: see architecture/, starting with
the end-to-end flow (sequence diagrams from the
agent's fallback to the agent resuming), then components, protocol, data
model and security, session lifecycle, deployment, and testing.
npm install
npm run dev # Firebase emulators (auth, RTDB, UI :4000) + Next on :3000
npm run e2e # in another terminal: full relay test against the emulators
Open http://localhost:3000 (the session console). Launch VM paysheet boots a new session with its own cart and device link, in a new tab. The console updates live; reopen any session's VM to resume it, or hand its device link to someone else to run transactions in parallel. To use a real phone, open the console via your LAN IP so the links point there.
The device link opens the paysheet the user interacts with, laid out like a
familiar wallet checkout. The VM page shows no paysheet at all, like a real
headless VM: it shows the relay steps for each request (action in from the
device → callback_pending out → merchant callback fired in the VM → resolved
or rejected → callback_result out), each with its timing. The Merchant
simulator panel stands in for the merchant's backend: Hold responses
makes callbacks wait for you, so you can watch the device wait. Hold one past
10 s and the SDK times it out. Try SF (3 options + CA tax), Honolulu (express only), and Toronto
or ZIP 00000 (merchant rejects).
Resume and ownership: the VM rebuilds the SDK from the last persisted snapshot.
Opening a session in a second VM tab takes it over (newest wins). The old tab
stands down, and any callback it had in flight fails on the device with
INTERRUPTED instead of hanging.
| File | Role |
|---|---|
src/lib/protocol.ts | Wire types. Transport-agnostic. |
src/lib/channel.ts | Only file that knows about RTDB: queues, presence, state. Swap for WebSockets/Cloud Run later. |
src/lib/mock-paysheet-sdk.ts | Stand-in for the third-party SDK (PayPal-shaped onShippingAddressChange / onShippingOptionsChange / onApprove, actions.reject, callback timeout). |
src/lib/merchant.ts | Merchant's callback implementations. |
src/lib/vm-bridge.ts | VM side: device action → SDK call → callback fires → callback_result back. Publishes full state snapshots on every change. |
src/lib/device-client.ts | Device side: request/response with correlation ids and a relay timeout. |
src/app/api/sessions | Creates a session (cart, initial state, share link). |
src/app/api/sessions/[sid]/vm-token | VM-role token for a new or resumed session. |
src/app/api/operator-token | Read-only console token (demo: unauthenticated). |
src/app/api/sessions/redeem | Exchanges the share code for a device-role token. |
src/lib/vm-session.ts | Boots or resumes the SDK for one session: rehydrate, take the VM lease, bridge. |
src/lib/response-gate.ts | Lets you hold merchant responses by hand (replaces simulated latency). |
src/components/VmActivity.tsx | VM relay-steps view, built from the bridge's VmEvents. |
src/components/PaySheetView.tsx | The device paysheet (wallet-checkout layout). |
src/lib/console-feed.ts | Live session list for the console (operator token, read-only). |
deploy/ | Dockerfile, compose files, and deploy.sh for the VPS. |
database.rules.json | Per-session, per-role access. Device can't write state; nobody reads share codes; the operator token is read-only. |
RTDB layout:
sessions/{sid}/meta { status, createdAt, expiresAt } (admin creates, VM updates status)
sessions/{sid}/state { seq, paysheet } (VM writes, device renders)
sessions/{sid}/toVm/* action messages (device appends, VM consumes + deletes)
sessions/{sid}/toDevice/* callback_pending / callback_result (VM appends, device consumes + deletes)
sessions/{sid}/presence { vm, device } (onDisconnect clears)
sessions/{sid}/vmLease tab id of the VM that owns the SDK
shareCodes/{code} { sid, expiresAt } (admin only)
sessionIndex/{sid} { code, label, createdAt, ... } (admin writes, operator reads)
Design rules: the VM is the source of truth; the device renders snapshots and never applies optimistic state. Every action has an id; the VM dedupes by id; the device times out (15 s) after the SDK would (10 s), so the SDK's verdict wins. Those two deadlines are the only timers in the code: no sleeps, no polling.
Copy .env.live.example to .env.live and fill in your project's values (emulator
config is .env.emulators; there is no .env.local). .env.live is gitignored.
npm run rules:deploy # push database.rules.json to the project in .env.live
npm run dev:live # Next against the real project (no emulators)
npm run e2e:live # same suite, against real RTDB
Free tier (Spark): this uses only Realtime Database (1 instance, 100 simultaneous
connections, 1 GB stored, 10 GB/month download) and Firebase Auth custom tokens,
both free. No Cloud Functions, no Identity Platform upgrade. A full e2e:live
run opens about 25 connections and writes a few KB.
The server needs a service-account key to mint custom tokens; .env.live points
GOOGLE_APPLICATION_CREDENTIALS at it (outside the repo).
POST /api/sessions must be service-authenticated (it mints VM tokens).npm run cleanup:live deletes expired sessions by hand. A scheduled Cloud Function would automate it but needs the paid Blaze plan, so the demo doesn't use one. Delete on completion too, since addresses are PII.