Codync
免费开源的 1:1 Grok Bot 与 Muse 替代方案。可在 iPhone、Mac 或 Linux 桌面上将 Claude 代码、Codex、Cursor 以及 40 多个编码代理作为持久机器人使用。支持群组聊天、线程、应用。
AI 翻译
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证Full-stack AI chatbot: approve, edit or reject the agent's tool calls, branch the conversation from any checkpoint, and watch a supervisor plan and delegate to subagents in real time. Next.js 16 · React 19 · TypeScript · Tailwind v4 · LangGraph · deepagents · Claude · Vercel + LangSmith
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Human-in-the-loop agents that ask before they act. Two chatbots on real LangGraph agents: one pauses for your approval before every sensitive action, the other plans a job, delegates it to a team of subagents, and writes code on its own isolated Linux machine, with you approving each file write and shell command.
Live demo: fullstack-agent-ui.vercel.app (password-protected, because every message spends model credit; the password is available on request, or run it yourself with your own key in two minutes).
send_email, the card shows exactly what would run, and you approve, edit
the arguments, or reject with a reason. Close the tab and the card is still waiting./orchestrate coder reads, edits and runs
commands on its own Linux machine, created per thread and deleted an hour after idle.
Nothing is shared between conversations, and every shell command is shown to you first.‹ 1/2 › switcher. Stop cancels the run on the server, and a reloaded page rejoins the
run still in progress.| Layer | What | Notes |
|---|---|---|
| UI | Next.js 16 (App Router), React 19, TypeScript, Tailwind v4 | Vercel |
| Agent client | @langchain/react useStream, @langchain/langgraph-sdk | Streaming, interrupts, branching |
| Edge | Route-handler proxy plus password gate (proxy.ts) | Adds the LangSmith key server-side; streams unbuffered |
| Agents | Python 3.12, LangGraph, LangChain create_agent, deepagents | HumanInTheLoopMiddleware, a deep-agent supervisor |
| Models | Claude Sonnet 5 (supervisor), Claude Haiku 4.5 (workers) | Adaptive extended thinking |
| Sandbox | LangSmith Sandboxes | One Linux machine per thread, git-backed diffs |
| Persistence | LangSmith Deployment (managed Postgres and Redis) | Threads, checkpoints and pending approvals live here |
| Feedback | LangSmith feedback API | Behind custom Starlette routes |
| Quality | pytest, Vitest, Playwright, GitHub Actions | CI gates both deploys |
| Use the live demo | Ask me for the password. It exists so the demo cannot be used to run up someone else's bill. |
| Run it with your own key | Quickstart. Your keys stay in packages/agent/.env on your machine and never pass through anyone else's server. |
| Just read it | Start at Architecture. |
Two processes, deployed separately, that only talk over HTTP.
Browser never holds a key, never leaves the origin
│ /api/langgraph/...
▼
packages/web Next.js 16 on Vercel
routes the two chats, and proxies every agent call,
injecting the LangSmith key server-side
│ https://<id>.us.langgraph.app (http://127.0.0.1:2024 locally)
▼
packages/agent Python on LangSmith Deployment
LangGraph server: two graphs, threads, checkpoints,
managed Postgres + Redis
▼
Anthropic API
Next.js does two jobs: it serves the pages, and it proxies every agent call so the API key stays server-side and the browser only ever talks to its own origin.
How the browser reaches the agent. The agent server is deployed on LangSmith at a
public HTTPS URL, but it rejects any request without a LangSmith API key in the
X-Api-Key header. To keep that key out of the browser, the browser only talks to my
Next.js app on Vercel. A catch-all route handler there, which runs as a serverless
function, takes any path the browser calls under /api/langgraph/, swaps that prefix for the agent's base URL, adds the key from a server-side env var, and forwards the request to the agent URL. It streams the response back unbuffered. The proxy doesn't know what any path means. The LangGraph server decides what each endpoint does. The browser never sees the agent URL or the key.
Custom endpoints. packages/agent/http_app.py adds our own endpoints (for the
sandbox and user feedback) alongside the LangGraph agent server's built-in ones. The
browser reaches them the same way as the built-in ones: through the Next.js route handler
running as a Vercel serverless function. langgraph.json accepts only one extra app, so
http_app.py is a single Starlette app that mounts the two route modules.
browser
│ https://your-app.vercel.app/api/langgraph/<anything>
▼ (same origin, no key)
Vercel serverless function: app/api/langgraph/[...path]/route.ts
│ strips /api/langgraph, adds X-Api-Key
▼
LangSmith Deployment: ONE public URL, https://<id>.us.langgraph.app
┌──────────────────────────────────────────────────────────────────────┐
│ LangGraph Server (one process, decides by path) │
│ │
│ built-in routes custom routes │
│ /threads, /runs/stream, ... /sandbox/{thread}/tree │
│ │ /sandbox/{thread}/file │
│ │ /sandbox/{thread}/changes │
│ │ POST /sandbox/{thread}/baseline │
│ │ POST /feedback/{thread} │
│ │ /feedback/{thread}/votes │
│ │ │ │
│ │ langgraph.json: "http": {"app": │
│ │ "./http_app.py:app"} │
│ │ │ │
│ │ http_app.py │
│ │ one Starlette app, mounts: │
│ │ ├─ routes/sandbox_files.py │
│ │ └─ routes/feedback.py │
│ ▼ │ │
│ graphs from langgraph.json │ │
│ human_in_the_loop, orchestrator │ │
└───────┬─────────────────────────────────────┼────────────────────────┘
▼ ▼
Anthropic API LangSmith sandbox (tree/file/changes)
(+ sandbox for the coder) LangSmith API (feedback)
One agent deployment serves both chats. LangSmith owns the checkpointer, so threads,
branches and pending approvals live in its managed Postgres — which is why a run
survives a closed tab.
/approve — one agent, one gated toolThe agent proposes sending an email and stops. You approve, edit or reject it.
| Capability | What it does |
|---|---|
| Interrupt / resume | The agent pauses before a sensitive tool; the card survives a reload |
| Branching | Edit or Retry any message, with a ‹ 1/2 › switcher between branches |
| Rejoin | Reload or navigate away and come back to the same conversation, still running |
| Stop | Cancels the run server-side, not just the spinner |
| Tool-call cards | Arguments and results, attached to the turn that made the call |
/orchestrate — a deep agent that plans, delegates and writes codeA Sonnet supervisor writes a plan, hands topics to Haiku workers, and delegates coding to a subagent with a real Linux machine. Every file write and every shell command stops for approval, wherever it happens — including inside a worker.
| Capability | What it does |
|---|---|
| Plan panel | The agent's live todo list, from TodoListMiddleware |
| Subagent cards | One per delegation, attached to the turn that delegated it; expand to watch that worker's own messages, tools and reasoning stream |
| Reasoning traces | Extended thinking rendered for the supervisor and every worker |
| Sandbox | A per-conversation machine. The coder reads, edits and runs commands on it; nothing is shared between conversations |
Approval on execute | A shell command is shown to you before it runs. Nothing else in the app has a shell to gate |
| File tree and diffs | The workspace as the agent changes it, with a source-control view of what this run touched |
| Approval, nested | A worker's write_file raises a card on the page and resumes correctly |
The page is a two-column chat until a conversation needs code, then becomes a three-column IDE — a code pane that sits empty takes the width the conversation needs.
Each conversation gets its own Linux machine, named after its thread id, created when the run starts and deleted an hour after it goes idle. Nothing is shared between conversations.
The coder is a separate compiled agent, not just a named helper, because a helper can
be given its own model but not its own filesystem — and a different filesystem is the
whole point. It carries its own approval rules, which is why execute is gated there and
nowhere else: nothing else in the app has a shell.
The browser never talks to the machine, because reaching it needs a credential. The agent server reads the files and the page asks the agent server:
browser ──► Next.js proxy ──► agent server ──► the machine
/sandbox/{thread}/tree the file list
/sandbox/{thread}/file one file, now or before
/sandbox/{thread}/changes what this run touched
The diff is a git commit, not a copy held in the browser. The workspace is committed
when the machine is seeded, so "what did this look like before" is git show HEAD:<file>
and "what changed" is git diff. The obvious alternative — remember the files in the
page — loses everything on reload, and then silently reports that nothing changed.
Needs Node 22+ (.nvmrc says 24), pnpm, uv, GNU Make,
and an Anthropic API key. uv fetches the right Python
itself, so you do not need one installed.
cp .env.example packages/agent/.env # then add ANTHROPIC_API_KEY
make install # uv sync + pnpm install
make dev-next # agent :2024 + Next.js :4200
Open http://localhost:4200.
Locally the app is open: no WEB_PASSWORD, no login. On a deploy, set WEB_PASSWORD in
Vercel; a production build with none refuses everyone rather than serving the app open.
packages/web/.env.local is optional locally — AGENT_SERVER_URL defaults are in
.env.local.example, and langgraph dev needs no API key.
| Command | Runs |
|---|---|
make dev-next | agent + Next.js app — this is the project |
make dev-agent | LangGraph server only, port 2024 |
make dev-web | Next.js only, port 4200 |
make typecheck | tsc --noEmit — the only automated gate |
make dev | agent + the old Vite app, port 4100 (reference only) |
| Path | What |
|---|---|
packages/web | The app. Next.js 16 App Router, Tailwind v4 |
packages/agent | The Python graphs — a uv project. langgraph.json registers human_in_the_loop and orchestrator |
packages/frontend | The original Vite app, kept as a reference. Not part of the system |
langgraph dev
quietly starts on a random port while the app keeps talking to 2024. Check with
lsof -nP -iTCP:2024 -sTCP:LISTEN.pnpm fails with URL.canParse is not a function. Node older than 22. Run
nvm use in the repo root, in each new terminal.packages/agent/uv.lock. Run
uv sync from packages/agent to match it exactly, or uv lock --upgrade to move
them deliberately.{"type": "adaptive", "display": "summarized"}; without display the default is
"omitted" and no reasoning blocks are returned at all — silently. Pre-4.7 models
take {"type": "enabled", "budget_tokens": N} and reject the adaptive form with a 400.curl localhost:2024/threads/<id>/state is the
truth; threads/search returns a stale snapshot.