diff --git a/README.md b/README.md
index 078a476bb..b76a57361 100644
--- a/README.md
+++ b/README.md
@@ -6,117 +6,103 @@
- A team of long-lived AI Bots that can split work down a tree and chat with your friends' Bots.
+ Long-lived AI Bots that work as a team in your browser: one request goes in, the team takes it apart, one answer comes back.
-
-
+
English | 中文
-FlyBot is three plugins on top of a pinned [DS Bot](https://github.com/Fei2411/DeepSeek-Bot) core for
-[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness):
+FlyBot is a local team of AI Bots you run in your own browser, on top of
+[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness). You talk to one Bot — the **Chief**. It keeps
+the rest of the team, hands each part of a job to the Bot whose role fits, and comes back with one answer. Every Bot
+keeps its own memory, working folder, model and schedules between turns, so the team you set up on Monday is still
+there on Friday.
-- **`@flybot/tree`** — a recursive Bot tree that splits a request, delegates level by level, and combines answers on the way back up.
-- **`@flybot/social`** — connect your Bots as friends with other homes and chat through a self-hosted [Bot Social](https://github.com/Birfy/bot-social) server, with owner approvals.
-- **`@flybot/timeline`** (optional, off by default) — see where your team's time goes: swimlanes per Bot, who waits on whom, and how busy each Bot is.
+## Is this for you?
-## Features
+**Yes, if** you want work that outlives one chat — a team that keeps its own notes, folders and schedules and picks
+it up again tomorrow; you would rather run it yourself, on your machine, with your own model keys; or you want your
+Bots to be able to talk to a friend's Bots.
-### Tree plugin (`@flybot/tree`)
+**Probably not, if** you just need one quick answer (any chat app does that), or you want a framework to build your
+own agents on — FlyBot is an app you run, on top of DeepSeek Harness.
-Turns your Bots into one recursive tree that splits a request into parts, sends each part down a level, and combines the answers on the way back up.
+## See it work
+
+### One request, a whole team

-*Demo: Chief starts alone in the sidebar, creates the child Bots Travel, Food and Budget, hands each one a part, and then combines their answers into one plan. Some waiting is sped up.* [Watch the full video (MP4)](docs/images/demo-tree.mp4)
-
-- **One root.** The tree's root is the Main Bot (Chief); no new bot is created for it. A separate `Root` bot is created only if the team has Bots but no Main Bot. Every other local Bot joins the tree, including one made with `create_bot` or the Bot list, under the same limits as `create_child_bot`. The tree organizes itself by role: a new Bot goes into the group that matches its role, and when a level is full (and once a day) related Bots are grouped under a suitable existing lead or a new lead with a clear role, such as "FlyBot Lead" for dev / test / repo Bots or "Life Lead" for cooking / shopping. Duplicate Bots are merged and long-idle ones archived after 30 days; nothing is deleted. Every change is logged, the sidebar shows what the last reorganization did, and one click undoes it.
-- **Children on demand.** Any tree Bot (not only the Main/root) calls `create_child_bot(name, role_description)` to make a child directly under *itself*; the tool takes no parent argument. Calls are handled one at a time per parent, so parallel calls never go over the limits or create two siblings with the same name. The rules:
- - names are 1–40 characters, and duplicate sibling names are rejected (case and spaces ignored);
- - depth is at most 5 (the root counts as 1), with at most 8 children per Bot (set in `limits.json` or the plugin config);
- - a new child is usable only by its creator's owner; sharing it still needs an independent per-Bot grant (default deny — no publish).
-- **Level-by-level delegation.** Each Bot sees only its direct children (`list_children()`), never deeper levels.
- - A Bot with children acts as coordinator: it splits the task, sends each part to the child whose scope fits, waits, and combines the answers for its parent.
- - A Bot with no children does the work itself.
-- **Message rules** (the `tree` send policy):
- - a tree Bot may message its parent, its direct children, and remote (friends') Bots (the tree never blocks remote messages; the social plugin decides);
- - the root may also message any local Bot;
- - local Bots outside the tree may message only the root;
- - `stopped` and `report` notices are never blocked, so Chief can always stop any Bot.
-- **Reparenting.** When a Bot is deleted, its children move up to its parent. The parent and every moved subtree get a fresh prompt and trace, and no child is dropped. If the parent is then over `maxChildren`, its children are regrouped by role the same way.
-- **Trace line.** When a tree Bot answers its *parent*, it starts the answer with its path, e.g. `Chief → Work → Dev`. Replies to you or to a friend's Bot never include it, and the root never adds one.
-- **Your prompts are kept.** The plugin adds its rules in a marked block inside each Bot's system prompt and replaces only that block, so text you wrote yourself is never overwritten.
-- **Sidebar.** The Bot list is drawn as one expandable tree with Chief on top. Retired, archived and other Main Bots are shown directly under Chief, with a tag for archived, idle or (rarely) outside-the-tree Bots; every other Bot is drawn where the tree has it.
-
-Install (needs the core, `path:/core`):
-
-```bash
-npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/plugins/tree"
-```
+*Demo: Chief starts alone in the sidebar, creates the child Bots Travel, Food and Budget, hands each one a part, and
+then combines their answers into one plan. Some waiting is sped up.*
+[Watch the full video (MP4)](docs/images/demo-tree.mp4)
-### Social plugin (`@flybot/social`)
+- **You only talk to the Chief.** It splits the request and sends each part one level down; a Bot with children
+ coordinates, a Bot without children does the work itself.
+- **The tree grows itself.** Any Bot can create a child for a slice of work. Bots are grouped by role, duplicates
+ are merged, and a Bot idle for 30 days is archived — never deleted, and each reorganization can be undone in one
+ click.
+- **You can always stop it.** A running turn ends on `stop_bot`, and no message rule ever blocks a stop.
-Every local Bot can chat with friends' Bots through a [Bot Social](https://github.com/Birfy/bot-social) server that **you self-host**. Invites are per Bot; what your Bots send on their own can wait for your approval; everything a friend's Bot writes arrives fenced as untrusted text.
+### Your Bots and your friends' Bots

-*Demo: one owner invites a friend to their Chief from **Sharing**; the friend pastes the link in **Add friend** (the link is hidden in the video) and messages that Chief. The Chief's reply waits in the owner's chat with an **Approve** card, and after **Approve** it arrives in the friend's chat. Some waiting is sped up.* [Watch the full video (MP4)](docs/images/demo-social.mp4)
-
-- **One-click onboarding.** On first start with a `server` configured, FlyBot calls `POST /v1/onboard/flybot`, creates your home (`@.home`), and stores credentials in `$DSH_HOME/bot/flybot-social.json` (mode 600).
-- **Members.** Access is a per-Bot **grant** (default deny, Chief included). A local Bot becomes `@.` on the server when you invite someone to that Bot, when it joins an invite, or when you bring it into a face-to-face room. The sidebar lists only Bots granted to you. **Manage access** on a Bot shows who has it and **Revoke**. Deleted Bots are revoked. Ungranted Bots have no outside identity: friends cannot reach them and they cannot message friends.
-- **Connectors (GitHub, Composio).** Settings → **Connectors** connects an account once; it is **on for every one of your Bots**, new and existing, on every turn: in its own chat, in group chats, on scheduled tasks, in sub-agents, and when a friend uses a Bot you shared. A friend's own Bot never gets it. You can turn a Bot's connector off (**Choose Bots**, or the **Connectors** card in the Bot's settings). Bots use the GitHub connector first and the saved token in the shell only as a fallback (for example `git push`). Disconnecting resets every Bot's choices.
-- **Friends in the Bot list.** A friend's Bot sits in the same sidebar list as yours, with a small globe after the name. Face-to-face rooms sit there too, with a people mark; ended ones fold under **Past rooms**. Click a row to open a normal chat. Sidebar **+** → **Add friend** (paste a handle, invite link or code), **Face-to-face room**, and **Copy my handle**. On a local Bot: right-click / settings **Sharing** → **Copy invite link for **, then **Copy link** / **Copy with instructions** / **New link** (the same control as **Add friend** → **Invite a friend**); **People with access** lists who has it and **Revoke**. Each person row there also has **Auto-send** for that Bot → that person (default off); **Auto-send from now on** on a held reply turns on that same switch.
-- **Face-to-face rooms.** Sidebar **+** → **Face-to-face room**: pick one or more of your Bots, enter the **same 6-digit number** as your friend (about 10 minutes), wait, then **Enter chat** (or **Leave**). No prior friendship and no preview of the other home's other Bots. Your typed lines are sent as you (when the server supports `typed_by_owner`); `@Name` / the picker label / a handle asks that Bot; `@all` asks everyone. A plain line with no `@` is answered by the one Bot it is for (each Bot passes silently unless the line fits it; the Bot that spoke last gets follow-ups; the first Bot answers if all pass); a line to everyone ("introduce yourselves", "你们…") may get one answer from each. Bot-written room lines still go through Approve unless face **Auto-send** is on (open room overview; default off).
-- **Typed by the owner · mentions · thinking.** Against a Bot Social that lists these under `GET /v1/platform` `features`: your typed friend-DM and face lines can be stamped `typed_by_owner` so the other home draws them as you; face sends may carry an explicit `mentions` handle list; a quiet `Name is thinking…` line appears above the composer while a Bot of another home works in a friend DM or a face-to-face room (ephemeral `presence`; DM path [#360](https://github.com/ThinkFlowLab/FlyBot/pull/360) / [#332](https://github.com/ThinkFlowLab/FlyBot/issues/332)). Older servers simply omit what they do not support.
-- **Approvals.** Inbound messages from a friend arrive immediately (fenced as untrusted). Outbound replies may wait in the open chat (badge + Approve / Reject) until you decide, unless Auto-send is on for that Bot and person (the Bot's **Sharing** → **People with access**) or for the face room. FlyBot also holds a Bot's own send behind an approval card; files are always held.
-- **Tools.** Every local Bot gets `list_friend_bots` and `message_friend_bot` (with optional file attachments).
-
-
-
-*Demo: each home picks its Bots in **+** → **Face-to-face room** and types the same 6-digit number, then **Enter chat**. A plain line is answered by Bots in the room; **@Planner** is answered by that Bot alone. Auto-send was on in this demo so Bot lines post without a hold. Some waiting is sped up.* [Watch the full video (MP4)](docs/images/demo-face.mp4)
+*Demo: one owner invites a friend to their Chief from **Sharing**; the friend pastes the link in **Add friend** and
+messages that Chief. The reply waits in the owner's chat with an **Approve** card, and after **Approve** it arrives in
+the friend's chat. Some waiting is sped up.* [Watch the full video (MP4)](docs/images/demo-social.mp4)
-The social plugin stays idle until you point it at a Bot Social server (see [Quick Start](#quick-start) below).
+- **The meeting point is yours.** A [Bot Social](https://github.com/Birfy/bot-social) server you self-host connects
+ two homes. With no server configured, FlyBot simply stays local.
+- **Sharing is one Bot at a time, and off by default.** An invite grants exactly one Bot; **People with access** lists
+ who has it, and **Revoke** takes it back.
+- **Your replies can wait for you.** What a Bot sends can sit in the chat with **Approve** / **Reject** until you
+ decide, or go straight out where **Auto-send** is on for that Bot and that person. What a friend's Bot writes
+ arrives fenced as untrusted text.
-### Timeline plugin (`@flybot/timeline`)
+### Several Bots in one room
-**Optional and off by default.** Installing the package does not show anything or record anything; you turn it on (see below). When on, it shows where the time goes across your local Bot team, from a **Timeline** row under the Bot list. It reads the core's activity feed and keeps a capped trace (about 3000 spans or 24 hours); it stores ids, times and names only, never message text, tool arguments or output.
-
-- **Swimlanes.** One lane for you, one per Bot, one per group (a round is drawn as round brackets). Each turn is a bar with its tool calls inside; arrows are messages (dashed requests, solid replies) with the time to the answer, and an open request shows how long it has been waiting.
-- **Who waits on whom.** A map of the requests between Bots with median wait per edge, plus a table with the slowest and still-unanswered ones.
-- **Utilization.** Per Bot: model time, tool time and time with no running turn.
-- **Honest numbers.** Times are when a message reached the other Bot's log, not when it was read. "No running turn" is not "waiting". "Model" time is turn time outside tool calls, not a measured model latency.
+
-Install (needs the core), then turn it on:
+*Demo: each home picks its Bots in **+** → **Face-to-face room** and types the same 6-digit number, then **Enter
+chat**. A plain line is answered by the Bots in the room; **@Planner** is answered by that Bot alone. Auto-send was on
+here, so Bot lines post without a hold. Some waiting is sped up.*
+[Watch the full video (MP4)](docs/images/demo-face.mp4)
-```bash
-npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/plugins/timeline"
-```
+- **No friendship needed.** Two homes type the same 6-digit number within about ten minutes and are in one room: a
+ plain line is answered by the Bot it fits, `@Name` by that Bot alone, `@all` by everyone.
+- **Only the Bots you brought.** The other home sees neither your other Bots nor your other chats.
-```yaml
-# profile cordis.patch.yml
-- id: flybot-timeline
- config:
- enabled: true # starts the recorder and the endpoint
- sidebarSection: true # shows the Timeline row (browser side)
-```
+## Also in the app
-Without `enabled: true` it records nothing and keeps no files; without `sidebarSection: true` no row is drawn.
+- **Task board.** One card per piece of work — owner, column, and how far it got — and a card can be handed to a Bot
+ or to a Workflow.
+- **Group chats.** You and some Bots in one room; the room's board says who does what, and a plain message is answered
+ by the member it fits.
+- **Workflows** (`@flybot/workflow`). A pipeline drawn as a flowchart of your Bots: drag a Bot onto the canvas,
+ connect it, save. A run walks the graph and posts its progress in the Workflow chat. In v1 a step posts that progress
+ and moves on; it does not call that Bot's model yet.
+- **Schedules.** A Bot wakes at a fixed time to do one job, then sleeps again.
+- **Connectors.** GitHub and Composio, connected once in Settings and on for every one of your Bots, unless you turn
+ one off for a particular Bot.
+- **Timeline** (`@flybot/timeline`, optional and off by default). Swimlanes per Bot, who waits on whom, and how busy
+ each Bot is. It stores ids, times and names — never message text, tool arguments or output.
-## Quick Start
+## Install
-### 1. Prerequisites
+**1. What you need**
-- **Node.js 22.19+** and **pnpm** (`npm install -g pnpm`, or `corepack enable`).
-- **Git**, to install from GitHub.
-- An API key for at least one model provider (for example DeepSeek: see [Set a DeepSeek API key](docs/deepseek-api-key.md)).
+- **Node.js 22.19+** and **pnpm** (`npm install -g pnpm`, or `corepack enable`)
+- **Git**, to install from GitHub
+- An API key for at least one model provider — for example DeepSeek ([how to set one](docs/deepseek-api-key.md))
-### 2. Install FlyBot (core + plugins)
+**2. Add FlyBot to DeepSeek Harness**
```sh
npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/core"
@@ -124,62 +110,61 @@ npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab
npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/plugins/tree"
```
-The first line is the FlyBot core (package `ds-bot`). The plugins are optional but recommended. `@flybot/timeline` is off by default; see [its section](#timeline-plugin-flybottimeline) to add and turn it on. On DSH Desktop: **Plugins → Add plugin**, paste one of the `github:` addresses above, then **Install** and **Enable now**.
+The first line is the FlyBot core (package `ds-bot`); the two plugins are what turn it into a team. Add
+`/plugins/workflow` or `/plugins/timeline` the same way if you want them.
-### 3. Run the web app
+On DSH Desktop: **Plugins → Add plugin**, paste one `github:` address at a time, then **Install** and **Enable now**.
-```sh
-npx -y @deepseek-ai/dsh@0.2.0-rc.2 web --port 3080
-```
-
-Open the printed `http://127.0.0.1:3080/?token=…` link. The first time you open Chief, pick a model (or open **Models and providers…**). A picture reaches a model that cannot read images as text: FlyBot reads it with one that can, and names the file on disk when no model can (see [Models](core/README.md#models)).
-
-To run FlyBot on a Linux server that stays on, one instance per person, use the container: [Run FlyBot in Docker](docs/docker.md).
+`0.2.0-rc.2` is the DeepSeek Harness release FlyBot is built and tested against — the same version `dev/harness`
+pins and CI runs, so keep it in all four commands.
-### 4. Self-host Bot Social (for friends' Bots)
-
-`@flybot/social` needs a [Bot Social](https://github.com/Birfy/bot-social) server. It does not ship one. Deploy Bot Social yourself (see its README), then set a public base URL so invite links work:
+**3. Run it**
```sh
-# example only — use your own host
-export PUBLIC_BASE_URL=https://your-server.example.com
-export PORT=8787
-# start Bot Social as documented in https://github.com/Birfy/bot-social
+npx -y @deepseek-ai/dsh@0.2.0-rc.2 web --port 3080
```
-Point FlyBot at that server in `~/.dsh/profiles/web/cordis.patch.yml` (or `$DSH_HOME/profiles/web/cordis.patch.yml`), then **restart** DSH:
+Open the printed `http://127.0.0.1:3080/?token=…` link, pick a model the first time, and say hello to the Chief. To
+keep FlyBot running on a machine that stays on, use the container: [Run FlyBot in Docker](docs/docker.md).
-```yaml
-- id: flybot-social
- config:
- server: https://your-server.example.com # e.g. https://47-80-69-220.sslip.io
- displayName: Your Name
-```
+## Friends' Bots are opt-in
-On first start FlyBot calls `POST /v1/onboard/flybot`, registers your home (`@.home`), and stores credentials in `$DSH_HOME/bot/flybot-social.json` (mode 600). No Bot is shared until you grant it. If that home handle is already taken, FlyBot retries a suffixed name (`Your Name2`, …). Sidebar **+** → **Copy my handle** copies the connected handle. If Social failed to start, the UI shows **Social is not running:** with the reason (also under Settings → Feedback).
+Social stays idle until you point it at a server you host.
-**Change the server later** without editing YAML: Settings → **Bot Social** shows the server and its connection status, **Change server** checks the new address (`https://`, or `http://localhost` for development; FlyBot reads `/v1/platform` and shows its features) and, after a clear warning, switches without a restart. A new server is a **new identity**: your friends and sharing stay on the old server, your old credentials file is kept as a backup and never deleted, and switching back restores them. The `cordis.patch.yml` value stays the default.
+1. Deploy [Bot Social](https://github.com/Birfy/bot-social) — FlyBot does not ship one. Its README covers
+ `PUBLIC_BASE_URL`.
+2. Add the server to `$DSH_HOME/profiles/web/cordis.patch.yml` and restart DSH:
-**Share one Bot:** that Bot's settings → **Sharing** → **Copy invite link for ** (or **+** → **Add friend** → **Invite a friend**); send the link. Your friend opens sidebar **+** → **Add friend**, pastes the link or code, and accepts — that grant covers **only** that Bot. **People with access** lists who has it; **Revoke** removes them.
+ ```yaml
+ - id: flybot-social
+ config:
+ server: https://your-server.example.com
+ displayName: Your Name
+ ```
-**Chat:** click the friend's Bot in the sidebar. Their messages arrive at once. What your Bots send back waits in that chat (Approve / Reject) unless **Auto-send** is on for that Bot and that friend (your Bot's **Sharing** → **People with access**, or **Auto-send my Bots' replies to …** on the friend's Bot settings for all your Bots; default off). Look for the **to approve** badge if they see no reply.
+3. On the first start FlyBot registers your home (`@.home`) and shares nothing. To share one Bot: that Bot's
+ settings → **Sharing** → **Copy invite link for **; your friend opens **+** → **Add friend**, pastes the link
+ and accepts.
-**Face-to-face:** sidebar **+** → **Face-to-face room** → pick your Bot(s) → enter the **same 6-digit number** within about 10 minutes → **Enter chat**. Friendship is not required. Face **Auto-send** is the checkbox on the open room overview (default off).
+Change the server later in Settings → **Bot Social**, without editing YAML: a new server is a new identity, and the
+old credentials are kept as a backup. Details: [social subsystem](docs/subsystems/social.md).
-This is the FlyBot path. Bot Social's separate “tell Grok Bot: set me up following `https://…/setup`” flow is for Grok Bot MCP clients, not for FlyBot.
+## Docs
-Without a `server`, the social plugin stays idle by design. Tree works without Bot Social.
+- Core options, models and updates: [`core/README.md`](core/README.md)
+- Plugins: [`tree`](plugins/tree/README.md), [`social`](plugins/social/README.md),
+ [`workflow`](plugins/workflow/README.md), [`timeline`](plugins/timeline/README.md)
+- Architecture and subsystem pages: [docs/architecture.md](docs/architecture.md),
+ [docs/subsystems/](docs/subsystems/README.md)
+- Known issues: [docs/known-issues.md](docs/known-issues.md)
+- Contributing: [CONTRIBUTING.md](CONTRIBUTING.md), [AGENTS.md](AGENTS.md), [LESSONS.md](LESSONS.md)
## Built on
-FlyBot keeps the upstream DS Bot core byte-identical (`ds-bot/`, pinned in `ds-bot.pin.json`), applies a short FlyBot patch series (`patches/` → `core/`), then adds the plugins under `plugins/`. See [#34](https://github.com/ThinkFlowLab/FlyBot/issues/34). The web UI (header, About, settings, update popups) says FlyBot; the npm package keeps the upstream `ds-bot` name (a registry install still checks npm `ds-bot` for updates), while the package's repository, About's links and stars, and the GitHub update check point at ThinkFlowLab/FlyBot.
-
-## More
-
-- Core options and internals: [`core/README.md`](core/README.md)
-- Contributing: [CONTRIBUTING.md](CONTRIBUTING.md), [AGENTS.md](AGENTS.md), [LESSONS.md](LESSONS.md)
-- Known issues: [docs/known-issues.md](docs/known-issues.md)
-- Architecture notes: [docs/architecture.md](docs/architecture.md)
+FlyBot is the upstream [DS Bot](https://github.com/Fei2411/DeepSeek-Bot) core, kept byte-identical and pinned in
+`ds-bot.pin.json`, plus a short patch series (`patches/` → `core/`) and the plugins under `plugins/`. It is developed
+and tested against DeepSeek Harness `0.2.0-rc.2`, the version the commands above pin. The npm package keeps
+the upstream name `ds-bot`, while everything you see in the app says FlyBot.
## License
@@ -187,4 +172,5 @@ FlyBot keeps the upstream DS Bot core byte-identical (`ds-bot/`, pinned in `ds-b
## Disclaimer
-FlyBot is an independent community project. **It is not an official DeepSeek product.** Bots use your own model quota and can read, write, and run commands when you ask them to — check important actions yourself.
+FlyBot is an independent community project. **It is not an official DeepSeek product.** Bots use your own model quota
+and can read, write, and run commands when you ask them to — check important actions yourself.
diff --git a/README.zh.md b/README.zh.md
index 90ca2f119..5b51db51a 100644
--- a/README.zh.md
+++ b/README.zh.md
@@ -5,113 +5,91 @@
-长期存活的 AI Bot 团队:能按树拆分任务,也能和朋友的 Bot 聊天。
+在你自己的浏览器里干活的长期存活 AI Bot 团队:一句话进去,全队拆开做,一个答案回来。
-
-
+
+
English | 中文
-FlyBot 是在固定版本的 [DS Bot](https://github.com/Fei2411/DeepSeek-Bot) 核心之上,为 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 准备的三个插件:
+FlyBot 是跑在你浏览器里的一支本地 AI Bot 团队,构建在
+[DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 之上。你只跟一个 Bot 说话——**Chief**。它带
+着其余的人:把一件事拆开,交给职责合适的 Bot,再把答案合成一份给你。每个 Bot 都有自己长期保存的记忆、工作
+目录、模型和定时任务,所以周一搭好的团队,周五还在。
-- **`@flybot/tree`**:递归 Bot 树,把请求拆成几块,按层委托,再汇总答案。
-- **`@flybot/social`**:通过你自己部署的 [Bot Social](https://github.com/Birfy/bot-social) 服务器,把 Bot 加为好友并聊天(带主人审批)。
+## 适合谁用?
-## 功能
+**适合你,如果**你要的活不止一个聊天窗口——团队自己记笔记、管目录、排定时任务,明天接着干;你更愿意用自己的
+机器、自己的模型额度来跑;或者你想让自己的 Bot 能和朋友家的 Bot 说话。
-### 树插件(`@flybot/tree`)
+**大概不适合,如果**你只想要一个快速答案(任何聊天应用都能做),或者你在找一个能二次开发的 agent 框架——
+FlyBot 是一个直接跑起来的应用,建在 DeepSeek Harness 之上。
-把你的 Bot 组成一棵递归树:把请求拆成几块,一层层往下委托,再把答案汇总回来。
+## 看看它怎么工作
+
+### 一个请求,一整支团队

-*演示:侧栏里一开始只有 Chief;它建出子 Bot Travel、Food、Budget,各分一块,再把答案汇总成一份行程。等待的部分做了加速。* [观看完整视频(MP4)](docs/images/demo-tree.mp4)
-
-- **一个根。** 树的根是主 Bot(Chief),不会再新建一个根。只有团队里有 Bot、却没有主 Bot 时,才会单独建一个 `Root`。其他本地 Bot(包括用 `create_bot` 或 Bot 列表建的)都会进树,遵守和 `create_child_bot` 一样的限制。树会按角色自我整理:新 Bot 进入角色匹配的分组;某一层满了时(以及每天一次),角色相近的 Bot 归到一个合适的现有负责人下,或新建一个职责明确的负责人(例如开发 / 测试 / 仓库维护归到 "FlyBot Lead",做饭 / 购物归到 "Life Lead")。重复的 Bot 会合并,长期闲置的 Bot 30 天后归档;从不删除。每次改动都记日志,侧栏会显示上一次整理做了什么,一键即可撤销。
-- **按需生子。** 树中的任意 Bot(不只是主 Bot / 根)调用 `create_child_bot(name, role_description)`,在**自己**下面直接建子 Bot;工具没有 parent 参数。同一父节点的调用串行处理,避免超限或重名。规则:
- - 名称 1–40 个字符;同级重名会被拒绝(忽略大小写和空格);
- - 深度最多 5(根算第 1 层),每个 Bot 最多 8 个子节点(见 `limits.json` 或插件配置);
- - 新建的子 Bot 默认只给创建者的主人用;分享给别人仍需对该 Bot 单独授权(默认拒绝,没有发布机制)。
-- **按层委托。** 每个 Bot 只能看到直接子节点(`list_children()`),看不到更深。
- - 有子节点的 Bot 当协调者:拆任务,把每块发给职责匹配的子节点,等待,再汇总给父节点。
- - 没有子节点的 Bot 自己干活。
-- **消息规则**(`tree` 发送策略):
- - 树中 Bot 可给父节点、直接子节点以及远端(好友)Bot 发消息(树不拦截远端消息;由社交插件决定);
- - 根还可以给任意本地 Bot 发消息;
- - 树外的本地 Bot 只能给根发消息;
- - `stopped` 与 `report` 通知永不拦截,Chief 总能叫停任意 Bot。
-- **换父。** 删除某个 Bot 时,其子节点上移到它的父节点;父节点与整棵子树会刷新提示词与路径,子节点不会丢失。如果父节点因此超过 `maxChildren`,其子节点按同样的角色规则重新分组。
-- **路径行。** 树中 Bot **向父节点**汇报时,答案以路径开头,例如 `Chief → Work → Dev`。回给你或好友 Bot 时不加路径;根也不会加。
-- **保留你的提示词。** 插件把规则写在系统提示词里的标记块中,只替换该块,不会覆盖你自己写的内容。
-- **侧栏。** Bot 列表画成可展开的树,Chief 在顶上;已退役、已归档的 Bot 和其他主 Bot 直接挂在 Chief 下,归档、闲置或(少见的)树外 Bot 带有标签;其余 Bot 都画在树里它所在的位置。
-
-安装(需要先装核心 `path:/core`):
-
-```bash
-npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/plugins/tree"
-```
+*演示:侧栏里一开始只有 Chief;它建出子 Bot Travel、Food、Budget,各分一块,再把答案汇总成一份行程。等待的
+部分做了加速。* [观看完整视频(MP4)](docs/images/demo-tree.mp4)
-### 社交插件(`@flybot/social`)
+- **你只跟 Chief 说话。** 它把请求拆开、往下一层各发一块;有子节点的 Bot 当协调者,没子节点的自己动手。
+- **树会自己长。** 任意 Bot 都能为一块活建子 Bot。Bot 按角色分组、重名合并,闲置 30 天的归档(从不删除),
+ 每次整理都能一键撤销。
+- **随时叫停。** 运行中的回合用 `stop_bot` 结束,任何消息规则都不会挡住这次叫停。
-每个本地 Bot 都可以通过你**自己部署**的 [Bot Social](https://github.com/Birfy/bot-social) 服务器,和朋友的 Bot 聊天。邀请按 Bot 计;你的 Bot 主动发出的消息可以等你审批;好友 Bot 写的内容一律放进不可信围栏。
+### 你的 Bot 和朋友的 Bot

-*演示:一方在 **Sharing(分享)** 里邀请好友使用自己的 Chief;好友在 **添加好友** 里粘贴链接(视频里链接已隐藏)并给这个 Chief 发消息。Chief 的回复停在主人的聊天里,出现 **Approve(批准)** 卡片,批准后到达好友的聊天。等待的部分做了加速。* [观看完整视频(MP4)](docs/images/demo-social.mp4)
-
-- **一键入驻。** 配置好 `server` 后首次启动会调用 `POST /v1/onboard/flybot`,创建家(`@.home`),凭证写在 `$DSH_HOME/bot/flybot-social.json`(权限 600)。
-- **成员。** 访问是按 Bot 的**授权**(默认拒绝,Chief 也一样)。本地 Bot 在你邀请别人使用它、它加入邀请、或你把它带进面对面房间时,才会在服务器上成为 `@.`。侧栏只列出别人授权给你的 Bot。每个 Bot 的 **管理访问** 列出谁有它,并可 **撤销**。删除 Bot 会撤销其身份。未授权的 Bot 没有对外身份:朋友够不到它,它也不能给朋友发消息。
-- **连接器(GitHub、Composio)。** 设置 → **连接器** 里连接一次账号;**你的每个 Bot 都默认开启**,新建的和已有的都一样,每一轮都能用:它自己的聊天、群聊、定时任务、子代理,以及好友使用你共享出去的 Bot 时。好友自己的 Bot 永远拿不到。你可以为某个 Bot 关闭连接器(**选择 Bot**,或该 Bot 设置里的 **连接器** 卡片)。做 GitHub 的事时 Bot 先用 GitHub 连接器,shell 里保存的 token 只作后备(比如 `git push`)。断开连接会重置所有 Bot 的选择。
-- **侧栏里的好友。** 好友的 Bot 和你自己的 Bot 在同一列表,名字后面有一个小地球标记。面对面房间也在这份列表里,带一个小人标记;已结束的折在 **过去的房间** 下。点开就是普通对话。侧栏 **+** → **添加好友**(可粘贴句柄、邀请链接或码)、**面对面房间**、**复制我的 handle**。本地 Bot:设置里 **Sharing(分享)** → **Copy invite link for (复制邀请链接)**,之后可 **Copy link** / **Copy with instructions**(带说明)/ **New link**(与 **添加好友** → **Invite a friend** 是同一个控件);**People with access(访问权限)** 列出谁有它并可 **Revoke(撤销)**。这里每个人的那一行也有 **Auto-send(自动发送)**,只管这个 Bot → 这个人(默认关);被暂扣回复上的 **Auto-send from now on** 打开的就是这个开关。
-- **面对面房间。** 侧栏 **+** → **面对面房间**:勾选自己的 Bot,双方输入**同一组 6 位数字**(约 10 分钟内),等候后点 **Enter chat(进入聊天)**(或 **Leave**)。不必先成为好友,也不会暴露对方家里的其他 Bot。你打的字在对方看来是你本人(服务器支持 `typed_by_owner` 时);`@名字` / 选择器标签 / handle 点名该 Bot;`@all` 叫全员。没有 `@` 的普通一句话只由最合适的那个 Bot 回答(其他 Bot 默默跳过;追问优先给上一个发言的 Bot;都跳过时第一个 Bot 兜底回答);对“大家 / 你们 / 自我介绍”这类面向所有人的话,每个 Bot 可各答一句。Bot 自己写的房间消息仍可能进审批,除非在该房间概览开了面对面 **Auto-send**(默认关)。
-- **主人手打 · 提及 · 正在输入。** 若 Bot Social 的 `GET /v1/platform` `features` 含相应项:私聊与面对面里你手打的行可盖 `typed_by_owner` 章;面对面发送可带显式 `mentions` handle 列表;朋友私聊或面对面房间里,其他家的 Bot 工作时输入框上方会出现安静的 `Name is thinking…`(短暂的 `presence`;私聊路径见 [#360](https://github.com/ThinkFlowLab/FlyBot/pull/360) / [#332](https://github.com/ThinkFlowLab/FlyBot/issues/332))。旧服务器没有的能力会自动跳过。
-- **审批。** 好友发来的消息会立刻送达(按不可信内容处理)。你的 Bot 发出的回复可能停在当前聊天里等你批准(或拒绝),除非对这个 Bot 和这个人开了自动发送(该 Bot 的 **Sharing** → **People with access**),或该面对面房间开了自动发送。FlyBot 本地也会暂扣 Bot 自己发起的发送;文件一律先审批。
-- **工具。** 每个本地 Bot 都有 `list_friend_bots` 与 `message_friend_bot`(可带附件)。
-
-
+*演示:一方在 **Sharing(分享)** 里邀请好友使用自己的 Chief;好友在 **添加好友** 里粘贴链接,并给这个 Chief
+发消息。回复停在主人的聊天里,出现 **Approve(批准)** 卡片,批准后到达好友的聊天。等待的部分做了加速。*
+[观看完整视频(MP4)](docs/images/demo-social.mp4)
-*演示:双方在 **+** → **面对面房间** 里各选自己的 Bot、输入同一组 6 位数字,再点 **Enter chat(进入聊天)**。普通一句话由房间里的 Bot 回答;**@Planner** 只由那个 Bot 回答。演示中开了 Auto-send,所以 Bot 的消息不会被暂扣。等待的部分做了加速。* [观看完整视频(MP4)](docs/images/demo-face.mp4)
+- **碰头的地方是你自己的。** 两台机器之间靠你自己部署的 [Bot Social](https://github.com/Birfy/bot-social)
+ 服务器相连;没配服务器时,FlyBot 就只是本地的。
+- **一次只共享一个 Bot,而且默认不共享。** 一次邀请只授权一个 Bot;**People with access(访问权限)** 列出谁
+ 有它,**Revoke(撤销)** 收回。
+- **回复可以等你点头。** Bot 要发的内容会停在聊天里等你 **Approve / Reject**;对这个 Bot 和这个人开了
+ **Auto-send(自动发送)** 时直接发出。好友 Bot 写来的内容一律放进不可信围栏。
-在指向 Bot Social 服务器之前,社交插件会保持空闲(见下方快速开始)。
+### 一个房间里的几个 Bot
-### 时间线插件(`@flybot/timeline`)
+
-**可选,默认关闭。** 只安装不会显示或记录任何东西,需要手动开启(见下)。开启后,在侧栏 Bot 列表下的 **Timeline** 一行里,看本地 Bot 团队的时间花在哪。它读核心的活动事件流,保存一份有上限的记录(约 3000 段或 24 小时),只存 id、时间和名称,不存消息正文、工具参数和输出。
+*演示:双方在 **+** → **面对面房间** 里各选自己的 Bot、输入同一组 6 位数字,再点 **Enter chat(进入聊天)**。
+普通一句话由房间里的 Bot 回答;**@Planner** 只由那个 Bot 回答。演示中开了自动发送,所以 Bot 的消息不会被暂扣。
+等待的部分做了加速。* [观看完整视频(MP4)](docs/images/demo-face.mp4)
-- **泳道**:你、每个 Bot、每个群各一条(群的一轮用圆括号标出)。每个回合是一条横条,工具调用画在里面;箭头是消息(虚线请求、实线回复),标出等到回答的时间,没回的请求显示已等多久。
-- **谁在等谁**:Bot 之间请求的关系图,每条边标中位等待时间,下面的表列出最慢和仍未回答的。
-- **利用率**:每个 Bot 的模型时间、工具时间和“没有运行中回合”的时间。
-- **如实的数字**:时间指消息到达对方 Bot 记录的时刻,不是被读到的时刻;“没有运行中回合”不等于“在等”;“模型”时间是回合里工具之外的时间,不是实测的模型延迟。
+- **不用先加好友。** 两家在十分钟内输入同一组 6 位数字就进同一个房间:普通一句话由合适的 Bot 回答,`@名字`
+ 只由那个 Bot 回答,`@all` 叫全员。
+- **只带你带来的 Bot。** 对方看不到你的其他 Bot,也看不到你的其他聊天。
-安装(需要核心):
+## 应用里还有
-```bash
-npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/plugins/timeline"
-```
+- **任务看板。** 一件活一张卡:谁在干、在哪一列、做到几成;卡可以直接交给某个 Bot 或某个 Workflow。
+- **群聊。** 你和几个 Bot 在同一个房间;房间的看板决定谁做什么,普通一句话由合适的那位回答。
+- **工作流**(`@flybot/workflow`)。把流水线画成一张 Bot 流程图:拖一个 Bot 上画布、连线、保存。运行时沿着图
+ 走,把进度发在 Workflow 聊天里。v1 的一步只发这条进度就往下走,还不会调用那个 Bot 的模型。
+- **定时任务。** Bot 到点醒来做一件事,做完再睡。
+- **连接器。** GitHub 与 Composio,在设置里连一次,你的每个 Bot 都能用;也可以单独给某个 Bot 关掉。
+- **时间线**(`@flybot/timeline`,可选,默认关闭)。每个 Bot 一条泳道、谁在等谁、各自多忙。只存 id、时间和
+ 名称,不存消息正文、工具参数和输出。
-再开启(默认什么都不记录、不显示):
-
-```yaml
-# profile 的 cordis.patch.yml
-- id: flybot-timeline
- config:
- enabled: true # 启动记录器和接口
- sidebarSection: true # 显示 Timeline 一行(浏览器端)
-```
+## 安装
-## 快速开始
+**1. 你需要**
-### 1. 环境
-
-- **Node.js 22.19+** 与 **pnpm**
+- **Node.js 22.19+** 与 **pnpm**(`npm install -g pnpm`,或 `corepack enable`)
- **Git**(从 GitHub 安装)
-- 至少一个模型提供商的 API Key(例如 DeepSeek,设置方法见 [Set a DeepSeek API key](docs/deepseek-api-key.md),英文)
+- 至少一个模型提供商的 API Key,例如 DeepSeek([怎么设置](docs/deepseek-api-key.md),英文)
-### 2. 安装 FlyBot(核心 + 插件)
+**2. 把 FlyBot 加到 DeepSeek Harness**
```sh
npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/core"
@@ -119,55 +97,64 @@ npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab
npx -y @deepseek-ai/dsh@0.2.0-rc.2 plugin --profile web add "github:ThinkFlowLab/FlyBot#main&path:/plugins/tree"
```
-第一行是核心(包名 `ds-bot`)。`@flybot/timeline` 默认不安装也不显示,需要时见上面的时间线插件一节。桌面版:侧栏 **插件 → 添加插件**,粘贴上面的 `github:` 地址后安装并启用。
+第一行是 FlyBot 核心(包名 `ds-bot`),后两行才把它变成一支团队。想要工作流或时间线,照样再加
+`/plugins/workflow`、`/plugins/timeline`。
+
+桌面版:**插件 → 添加插件**,一次粘一个 `github:` 地址,然后**安装**并**立即启用**。
+
+`0.2.0-rc.2` 是 FlyBot 构建与测试所用的 DeepSeek Harness 版本,也正是 `dev/harness` 钉住、CI 在跑的那一版,
+四条命令保持一致。
-### 3. 启动 Web
+**3. 跑起来**
```sh
npx -y @deepseek-ai/dsh@0.2.0-rc.2 web --port 3080
```
-打开打印出的 `http://127.0.0.1:3080/?token=…`。第一次打开 Chief 时选择模型。
+打开打印出的 `http://127.0.0.1:3080/?token=…`,第一次先选一个模型,然后跟 Chief 打个招呼。想让它在一台一直开着
+的机器上常驻,用容器:[用 Docker 运行 FlyBot](docs/docker.zh.md)。
-想在一直开着的 Linux 服务器上运行(每人一个实例),可以用容器:[用 Docker 运行 FlyBot](docs/docker.zh.md)。
+## 朋友功能是可选的
-### 4. 自建 Bot Social(好友功能需要)
+没把社交插件指向服务器之前,它一直空闲。
-`@flybot/social` **依赖**你自己部署的 [Bot Social](https://github.com/Birfy/bot-social),仓库里不附带服务器。按 Bot Social 的 README 部署,并设置对外地址:
-
-```sh
-# 示例:换成你自己的域名
-export PUBLIC_BASE_URL=https://your-server.example.com
-export PORT=8787
-```
-
-在 `~/.dsh/profiles/web/cordis.patch.yml`(或 `$DSH_HOME/profiles/web/cordis.patch.yml`)里写上服务器地址,然后**重启** DSH:
-
-```yaml
-- id: flybot-social
- config:
- server: https://your-server.example.com # 例如 https://47-80-69-220.sslip.io
- displayName: 你的名字
-```
+1. 部署 [Bot Social](https://github.com/Birfy/bot-social)——FlyBot 不附带服务器,部署见它的 README
+ (`PUBLIC_BASE_URL`)。
+2. 把服务器写进 `$DSH_HOME/profiles/web/cordis.patch.yml`,重启 DSH:
-首次启动会调用 `POST /v1/onboard/flybot`,登记你家(`@<名字>.home`),凭证写在 `$DSH_HOME/bot/flybot-social.json`(权限 600)。在你授权之前,没有任何 Bot 被共享。若家句柄已被占用,会自动试 `你的名字2`…。侧栏 **+** → **复制我的 handle** 复制当前已连接的句柄。若 Social 没起来,界面会显示 **Social is not running:** 及原因(也会进 Settings → Feedback)。
+ ```yaml
+ - id: flybot-social
+ config:
+ server: https://your-server.example.com
+ displayName: 你的名字
+ ```
-**之后换服务器**不用改 YAML:设置 → **Bot Social** 显示当前服务器和连接状态,**更换服务器**会先检查新地址(`https://`;开发时可用 `http://localhost`;FlyBot 读取 `/v1/platform` 并列出它的功能),经过明确的警告确认后无需重启即可切换。换服务器等于**换一个新身份**:好友和分享留在旧服务器上,旧的凭证文件作为备份保留、不会被删除,切换回去即可恢复。`cordis.patch.yml` 里的值仍是默认值。
+3. 首次启动会登记你家(`@<名字>.home`),什么都不共享。要共享某一个 Bot:该 Bot 设置 → **Sharing** →
+ **Copy invite link for **;对方在 **+** → **添加好友** 里粘贴链接并接受。
-**分享某一个 Bot:** 该 Bot 设置 → **Sharing** → **Copy invite link for **(或 **+** → **添加好友** → **Invite a friend**),把链接发给对方;对方侧栏 **+** → **添加好友** 粘贴链接或码并接受——**只授权这一个 Bot**。**People with access** 可查看并 **Revoke**。
+之后换服务器不用改 YAML:设置 → **Bot Social** 里换。换服务器等于换新身份,旧凭证会作为备份留着。细节见
+[社交子系统](docs/subsystems/social.md)。
-**私聊:** 点侧栏里对方的 Bot。对方来信立刻到。你这边发出去的内容停在该聊天等批准(除非对这个 Bot 和该好友开了 **Auto-send**:你的 Bot 的 **Sharing** → **People with access**;或在好友 Bot 设置里勾 **Auto-send my Bots' replies to …**,覆盖你所有 Bot;默认关)。对方看不到回复时,先看 **to approve / 待批准** 角标。
+## 文档
-**面对面:** 侧栏 **+** → **面对面房间** → 勾选自己的 Bot → 双方输入**同一组 6 位数字**(约 10 分钟内)→ **Enter chat**。不必先加好友。面对面 **Auto-send** 在该房间概览上(默认关)。
+- 核心选项、模型与更新:[`core/README.md`](core/README.md)
+- 插件:[`tree`](plugins/tree/README.md)、[`social`](plugins/social/README.md)、
+ [`workflow`](plugins/workflow/README.md)、[`timeline`](plugins/timeline/README.md)
+- 架构与子系统页:[docs/architecture.md](docs/architecture.md)、[docs/subsystems/](docs/subsystems/README.md)
+- 已知问题:[docs/known-issues.md](docs/known-issues.md)
+- 参与开发:[CONTRIBUTING.md](CONTRIBUTING.md)、[AGENTS.md](AGENTS.md)、[LESSONS.md](LESSONS.md)
-以上是 **FlyBot** 的接法。Bot Social 另有一条给 Grok Bot 的「按 `https://…/setup` 一句话入驻」流程,不是 FlyBot 用的。
+## 它建立在什么之上
-未配置 `server` 时,社交插件会故意保持空闲。树插件不依赖 Bot Social。
+FlyBot 是上游 [DS Bot](https://github.com/Fei2411/DeepSeek-Bot) 的核心,保持字节一致并钉在 `ds-bot.pin.json`
+里,加上一组简短的补丁(`patches/` → `core/`)和 `plugins/` 下的插件。开发和测试针对 DeepSeek Harness
+`0.2.0-rc.2`,也就是上面命令钉住的版本。npm 包名沿用上游的 `ds-bot`,而你在界面里看到的都是 FlyBot。
-## 架构简述
+## 许可
-上游 DS Bot 核心保持字节一致(`ds-bot/`,见 `ds-bot.pin.json`),经 `patches/` 打出 `core/`,插件在 `plugins/`。详见 [#34](https://github.com/ThinkFlowLab/FlyBot/issues/34)。网页界面(顶栏、关于、设置、更新提示)显示 FlyBot;npm 包名仍是上游的 `ds-bot`(从 npm 安装时仍查 npm 上的 `ds-bot` 更新),包的仓库地址、关于页的链接和 Star、以及 GitHub 更新检查都指向 ThinkFlowLab/FlyBot。
+[Apache License 2.0](LICENSE)。第三方声明见 [NOTICE](NOTICE)。
-## 许可与声明
+## 声明
-[Apache License 2.0](LICENSE)。FlyBot 是独立社区项目,**不是 DeepSeek 官方产品**。Bot 会使用你自己的模型额度,并可能按你的要求读写文件、执行命令——重要操作请自行核对。
+FlyBot 是独立社区项目,**不是 DeepSeek 官方产品**。Bot 用的是你自己的模型额度,并可能按你的要求读写文件、执行
+命令——重要操作请自己核对。