编码工作台
Coding / 编码工作台:入口内独立前哨窗(UI +
remote_tools.attach),在开发机执行 FS / 终端 / patch;栖息地做脑与项目 World。与 桌面伴侣 同类前哨,不是第二个 App,也不是 项目管理(任务/文件夹 PM)。
- 个人玩具 → 逐步成为 Agent 编码的日常主力(不是先做 Tab 补全)。
- 聊天室已能 vibe;瓶颈是工作台 UX(explore / patch / 多仓会话)。
- 第一阶段重心:读仓(explore);写与 diff 其次。LSP / Debugger 为后续。SSH Remote(编排远端
anima-probe)已落地首版。
- 栖息地在稳定弱机(脑 + 记忆 + 编排)。
- 手在开发机前哨:FS / 搜索 / 终端 / patch(GUI 窗或
anima-probe)。 - 跨机前哨是硬性要求,不是可选项。
三角色:栖息地(脑)←RPC→ 客户端/操作台;栖息地 ←remote_tools.attach→ 执行端 Outpost。CLI 分发:anima / anima-client / anima-probe(见 portal.md、glossary)。
Coding outpost window ── RPC + attach ──► weak-machine Habitatanima-probe ── attach 直连 ──► same Habitatanima-client ── RPC + subscribe ─► same Habitat(TUI;不中转 tool.call)Main Chat / tasks ── RPC only ─────► same Habitatinstance_id:Habitat 在 probe/窗 attach 时分配;会话outpost_instance_id绑 执行端,不是 client。- 对话列表:
conversation.list({ platform: "coding" })在 Habitat;client 与 GUI 同 token 可读全部 coding 会话。 - 实时进度:client 订 Habitat 会话流;
tool.call直达 probe,结果经 Habitat 扇出到 TUI。 - SSH Remote(现行):桌面 New Agent →「SSH 远程」或
anima-client coding --ssh user@host --workspace /abs/path。本机经 OpenSSH(密钥 / ssh-agent /~/.ssh/config,BatchMode)在远端 ensure/startanima-probe;probe↔Habitat 直连 attach。若 Habitat URL 为 loopback,自动ssh -R反向隧道。UI 文件树/预览经coding.outpostExec(白名单只读工具)同步调用远端,不做 client 工具中继。首版远端 OS:Linux x64。
SSH Remote 用法
Section titled “SSH Remote 用法”# 本机先有可 scp 的 probe(装到 ~/.anima/bin)just pack client-probe
# CLIanima-client config --habitat-url http://127.0.0.1:2658 --token <token>anima-client coding --ssh user@host --workspace /home/user/repo [--port 22] [--identity ~/.ssh/id_ed25519]桌面:Coding 窗 → 新建 Agent → SSH 远程 → 填 user/host/远端绝对路径 → 连接。
手测清单:公网可达 Habitat + 远端 Linux;本机 loopback Habitat(触发反向隧道);桌面树/预览/对话工具;CLI 同路径;退出/切会话后隧道回收。自动化门闩:just pack client-probe && bun scripts/smoke-ssh-remote.ts。
just pack cli 仍只打栖息地运维二进制 anima;SSH 用的 client/probe 走 just pack client-probe。
CLI:anima-client / anima-probe(风巢 #18887)
Section titled “CLI:anima-client / anima-probe(风巢 #18887)”产品执行层路线:自研 Coding(A)并对标 OpenCode,不把 OpenCode 当执行脑。
| 命令 | 首版范围 |
|---|---|
anima-client | ① 配置 Habitat URL + Service API Token ② coding TUI(含 --ssh Remote) |
anima-probe | app_id=coding attach;执行全部 coding Outpost toolset(与下表及 GUI 窗对齐);持久化 instance_id |
共享执行面:packages/shared/coding/outpost/。GUI Coding 前哨窗仍可同进程焊操作台+手;CLI 打包图必须可拆。
依赖禁令:anima-probe 不得 import habitat/core|platform;anima-client 不得 import probe 执行实现 / habitat/core。
- 编码工作台 = 独立前哨窗(UI +
remote_tools.attach),与桌面伴侣同类;同一 Tauri 入口,不是第二个应用。 - 功能代码:
packages/habitat/features/coding/+packages/frontend/features/coding/—— 不要把 Coding 塞进features/companion/。 - 「产品 UI 不 attach」适用于主壳产品模块(聊天室、任务、…)。前哨窗可以既是 UI 又是手。
- 保活与伴侣进程/壳存活对齐,但 attach 生命周期不同:
- 伴侣:隐藏显示会关闭 WebView → attach 拆除(离线)。
- 编码:优先隐藏不关,使前哨保持 attach,供 Agent 工具调用。不要把 attach 绑到主窗生命周期。
连接与多仓会话
Section titled “连接与多仓会话”- 默认:一次 attach,一个
instance_id(一个 Coding 窗 = 一只本机手)。 - 多仓 ≠ 多实例。Cursor 式「一个 UI、多个仓」= 多个 Agent 会话,各锁自己的
workspaceRoot(一会话一根;创建后不可变)。 - 多次 attach 仅用于:多机前哨、伴侣+编码,或罕见双 Coding 窗。
instance_id= 哪条本机连接;不是哪个仓库。
| 层 | 含义 | 示例 |
|---|---|---|
stable_key | 跨机逻辑项目 id(在 World 上) | git:github.com/org/foo、novel:crane-summer |
| 项目 World | 该项目的知识/任务边界(建议 public,一项目一 World) | entity + world_config |
workspace_root | 某机上的 checkout 路径 | 会话 platform_info;所有 FS/终端相对它 |
- 分组 / 记忆 / 任务 → World /
stable_key - 读文件 / 跑命令 → 当前会话
workspace_root - 分开以免「同源、错目录」类 bug。
会话元数据还存 project_world_id。编码会话 platform = coding(flat),实例经 platform_extra.outpost_instance_id(及 outpost_app_id: "coding")绑定;不是 remote:coding:…,也不是普通 chat。
World 策略
Section titled “World 策略”- 不要把多仓知识倒进 Agent private(泥球),也不要全放 Commons。
- Private World:主体个性化(风格、偏好、弱项目相关)。
- 项目 Public World:项目绑定数据(explore 笔记、该项目任务、…);后续经 grants 多 agent。
- Commons:栖息地级共享资产(内置技能、伴侣资源),不绑单一项目。
- 壳的 User/Agent 切换仍框定日常;编码会话携带
project_world_id上下文。
World 上的 stable_key
Section titled “World 上的 stable_key”world_configbody 上的通用字段:stable_key(永不叫repo_key)。- 编码可从规范化 git origin 推导;其他领域复用前缀:
git:/novel:/manual:。 title= 可编辑显示名;stable_key= 机器身份,设置时唯一(PG 部分唯一索引 + 应用检查)。
.anima/project.json(可提交)
Section titled “.anima/project.json(可提交)”团队可提交的最小集合:
{ "version": 1, "stable_key": "git:github.com/org/freeanima"}可选:display_name(团队规范名)。
不要提交: world_id(栖息地本地)。本地缓存(project.local.json 或前哨 prefs)。
有 git remote 时可省略该文件并由系统计算 key;无 remote / 非 git 项目用文件钉死 key。
.anima/ 边界:仅项目身份(project.json 等)。不要放置 skills/、rules/、agents/、mcp.json — 这些由社区 .agents/ 与厂商兼容路径承担。
项目 Agent 上下文(仅 Coding 模块)
Section titled “项目 Agent 上下文(仅 Coding 模块)”栖息地普通聊天室不从会话 cwd 读 AGENTS.md。项目上下文只在 module=coding 且有 workspace_root 时装配:
- Coding 前哨在工作区扫盘发现资产
- 经
coding.projectContextSync写入栖息地会话缓存(GUI 与anima-client建会话后均会 sync;SSH 会话经coding.outpostExec/project_context发现) - system prompt 注入 always rules(
project_context)与 scoped rules 目录(project_rules_scoped);skill_load/subagent_run/ 前哨工具按需叠加项目层
UI 只读远端盘: coding.outpostExec(file_list / file_read / file_search / project_context)供 SSH 会话文件树与预览;改写仍只走 Agent 回合。
system prompt 不进 catalog 段: 项目 skills / agents / mcp 列表不注入编码 system prompt(避免与按需加载重复)。
栖息地 subagent / skill 目录: 用 entity 顶层 tag_ids 指向同 World 标签 coding 控制是否出现在 coding system prompt;例如内置 coding-explorer 仅 coding 会话可见,chat 向 general / explorer 不受影响。
.agents/ # 社区默认(Codex / OpenCode / Copilot 等) skills/<name>/SKILL.md # agentskills.io rules/**/*.md agents/**/*.{md,agent.md} mcp.jsonAGENTS.md # 社区通用项目叙事;可读写(agents_md_read / agents_md_write)CLAUDE.md # Claude Code 兼容.claude/skills | .claude/rules | .claude/CLAUDE.md.cursor/rules/*.mdc.opencode/skills | .opencode/agents.mcp.json | .vscode/mcp.json | .cursor/mcp.json
.anima/ project.json # 仅 identity / stable_key同名资产优先级:.agents → 厂商路径(先声明的来源赢)。
项目 MCP(前哨桥)
Section titled “项目 MCP(前哨桥)”- 发现与启停在 Coding 前哨(开发机),不写入栖息地全局
mcp_servers - HTTP/SSE MCP:前哨连接后把 tools
tool.register为mcp_<server>_<tool>,栖息地经现有 remote-tools 桥调用 - stdio MCP:在 Node/Bun 前哨环境可连;纯 Tauri WebView 暂记 status(改用 HTTP 或后续壳桥)
- 工具
project_mcp_status查看连接状态
工作台 UI(P0)
Section titled “工作台 UI(P0)”交互对标 Cursor Agents Window:三栏 Agents | 对话 | Context,深色 Agent 优先。
会话 × 工作区(硬约束,对接未来 worktree)
Section titled “会话 × 工作区(硬约束,对接未来 worktree)”- 一对话一根工作区:本地
CodingAgentSession.workspaceRoot: string | null(创建时可明确选「无工作区」)。 - 创建后不可变:New Agent 选定路径(或无)即锁定;UI 无添加/移除/更换文件夹。换目录 = 新建 Agent。
- 新建可选已有工作区:本地额外持久化
knownWorkspaces(去重工作区路径,会话删除后仍保留);New Agent 对话框用下拉列出这些工作区,选中即复用该根新建会话(仍是独立workspaceRoot字符串),也可「选择新文件夹」或「无工作区」。 - 栖息地
conversation.create的workspace_root与本地字段一致且同样视为不可变;本地conversationId持久化后复用。 - 左栏按
workspaceRoot的 basename 分组(null→「无工作区」);同仓多会话 = 同组多条(为后续同仓不同 worktree 路径留口:每条仍是独立workspaceRoot字符串)。 - 组 = 仓名,行 = 话题标题:本地默认 title 仅占位;
conversation.create不预填 title,首回合由栖息地 LLM 生成后经conversation.subscribe写回侧栏。 - 本地存储 key
freeanima:coding:agent-sessions:v3(含workspaceKind/ SSH 字段;从 v2/v1 迁移);从 v1 多根迁移时只保留activeRoot ?? workspaceRoots[0] ?? null。
- 左栏 Agents:Repositories 分组 + 会话列表(单行 title;悬停归档 / 删除);Search(Ctrl/Cmd+K);New Agent。归档为软隐藏(
archivedAt),本轮无「已归档」入口。 - 中栏对话:空态居中输入;有消息后线程 + 底部 follow-up;流式走
getBundledRpcStreamClient(不整包 import Chat SPA);platform =coding,outpost_instance_id= 当前 attachinstanceId。- 复用聊天室原子(禁止挂载 ChatApp):
ConversationTranscript(消息列表 + stick-to-bottom + 向上懒加载 SSOT;新增气泡样式 / display 分支只改该组件,禁止 Coding 平行display.map)、slash-command-menu/conversation-command-api(slash)、stream-events+ Markdown(流式 token)、upsert-tool-block+ToolBlockBubble(经 Transcript)、LlmDebugPanel+useChatLlmDebugEnabled(LLM 调试;设置页开关与聊天室共用)。compose / 空态 hero / 三栏布局皮肤留在 Coding SPA。 - 历史分页与聊天室同契约:
conversation.messages的before_pos/has_more_before/from_pos。
- 复用聊天室原子(禁止挂载 ChatApp):
- 右栏 Context(默认展开):Files(可展开树)/ Preview(Shiki)/ Terminals(
terminal_run输出日志;非交互 PTY)。 - Search Actions:无「更换工作区」,有「新建 Agent」。
- 理解笔记:挂在 Files 区(需
project_world_id)。
工具(P0)
Section titled “工具(P0)”前哨 local_name(在 Coding WebView / 薄 Rust IPC 内于开发机执行):
| 工具 | 角色 |
|---|---|
file_list | 只读树 |
file_read | 读文件 |
file_search | 搜文件/内容 |
file_patch | 最小编辑(old_string / new_string);立即写入工作区 |
terminal_run | 一次性命令(可选 terminal_process) |
project_context | 发现项目 agent 资产(rules / skills / agents / mcp) |
agents_md_read | 读根 AGENTS.md |
agents_md_write | 写根 AGENTS.md |
project_mcp_status | 前哨管理的项目 MCP 连接状态 |
mcp_*_* | 桥接的项目 MCP 工具 |
路径沙箱在会话 workspace_root 下。编码会话须默认用这些前哨工具 —— 不要静默回退到栖息地本机 file_*(服务器上没有你的仓)。编码会话 toolset_load 拒绝栖息地 file / shell;catalog 也不再列出它们。
内置 subagent explorer 用栖息地 file_*,不是工作区探索器。前哨只读工具请用 coding-explorer。
P0(本模块)
- Coding 前哨窗 + attach
workspace_root+project_world_id/stable_key- 只读 explore + 终端;coding-explorer subagent
- 最小
file_patch立即写盘 - 理解笔记写入项目 World(
coding_note),经栖息地 RPCcoding.noteCreate/coding.noteList(Coding 窗「理解笔记」)
后续
- LSP / refactor / Debugger
- 更重索引 / symbols
- 交互式 PTY
- Cloud / Worktree 检出与真 Git Commit&Push
- SSH:密码 / 2FA UI;远端 macOS / Windows 自动安装
弱机栖息地 = 脑 + 项目 World;本机一个 Coding 前哨窗 = 手;多仓靠会话路径 + World
stable_key;团队仓内只钉stable_key;先赢 explore + 工作台,再加深 IDE。