无限画布
标签栏很适合拿住一个对话,很不适合拿住十二个。无限画布给出的是另一个答案:没有边界的画板,你的工作在上面按空间铺开 —— 一个文件夹一个区域、一个智能体一个区域、卡片可以钉在任何地方 —— 而且一张卡片能展开成一个真正可以打字进去的对话。多个智能体在同一块画板上并排跑,而不是一次只看一个标签页;你正在读的文件、正在跑的终端也摆在它们旁边。
它随 0.30.0 以无限对话之名到来,那时只有一块画板。从 0.32.4 起它叫无限画布,而且想建多少个画布都行 —— 一个项目一个、一个功能一个、一次评审一个 —— 每个都是一块独立的画板。这个路由和「待办」「仓库面板」一样是整页的;也和它们一样,如果这不是你的工作方式,可以关掉。
它大体上是你工作的一个视图,而不是一份副本
一张会话卡片就是你的某个对话,一个文件夹区域就是你的某个文件夹,一张文件卡片就是那个文件 —— 删掉对话,它的卡片跟着消失;重命名对话,卡片也跟着改。对这些东西而言,画布额外给出的是位置,以及让同一个对话同时出现在三个地方、或出现在好几个画布上的自由。
有三样东西确实属于画布自己:一个收藏区的成员名单、一张便签的文字,以及一张终端卡片里正在运行的 shell。它们不存在于别处,这也正是下文里删除它们要另作处理的原因。
画布上只承载根对话。子智能体会话 —— 任何由委派或循环派生出来的东西 —— 是拥有它的那个对话的下层结构,而不是一个可供铺排的同级对象,因此它永远不会成为一张独立的卡片。不过卡片上会有一个徽标,数出它下面挂着多少个子智能体。→ 多智能体协作
打开它
无限画布是左侧边栏导航块里的最后一行,位于仓库面板下方,同时也在状态栏快捷操作的导航分组里。它会打开你的画布列表 —— 如果自 Codeg 启动以来你进过某个画布,则直接回到那个画布。身在某个画布里时再点一次这一行,就会回到列表。
如果你不想要这一行,在侧边栏的导航项里关掉它 —— 快捷操作仍然能进去。
你的画布
这个路由先打开画布:每个画布一张卡片,最近编辑的排在最前。每张卡片上有
- 画板的缩略图 —— 区域画成轮廓,卡片和便签画成色块,带着各自的颜色,所以不用打开就能认出是哪个画布;
- 顶部一条画布颜色的色带;
- 它的名称 —— 还没起名时显示未命名画布 —— 以及最多两行描述;
- 它装了多少个元素、最后一次编辑是什么时候,悬停可看确切时间。
点击卡片即可打开。它的 ⋯ 按钮 —— 或者右键 —— 提供打开、编辑画布…和删除画布…。至少有一个画布时,会出现一个搜索框,输入时按名称和描述筛选,旁边是新建画布。
新建画布会请你填名称、描述和颜色,三项都可以不填 —— 名称留空就显示为未命名画布 —— 创建的那一刻就会打开新画布。编辑画布…是同一个对话框,用来改已有的画布。进入画布后,标题栏显示无限画布 › 名称:前半段带你返回全部画布,名称则打开一个菜单,里面有编辑画布…和删除画布…。
删除画布会删掉上面的东西
删除画布…总会先询问,并说明它要删掉什么:这个画布以及上面的一切 —— 区域、卡片、便签 —— 带上元素的数量,以及有几张终端卡片会被关闭、其中的进程一并结束。画布上展示的会话、文件夹和文件不受影响;它们只是在那里被展示而已。另一个打开着这个画布的窗口会退回列表,并告诉你该画布已被删除。
如果你在 0.32.4 之前用过那一块画板,它还在:上面的一切都挪到了一个名为未命名画布的画布上。如果那块画板是空的,列表就从空的开始。
把它填起来
一个新画布是空的,并且直接给出一键的出路:从当前工作区生成会用你已经打开的东西把整个画布搭出来 —— 一个文件夹一个区域,里面装着它的对话,位置都替你排好。这是最快看清画布用来做什么的方式,之后你可以随意重排。
更从容的方式是添加到画布,一次放一样东西。它的第一项是新建会话 —— 在工作区当前文件夹里放一张空白卡片,你发出第一条消息时它就成为一个真正的对话。它下面是你可以铺开的八样东西:
| 你添加的 | 它做什么 |
|---|---|
| 文件夹区域 | 映射一个已打开的文件夹,显示其中的每个对话,worktree 子项一并并入 |
| 文件夹分组区域 | 映射一个侧边栏文件夹分组 —— 分组里的每个文件夹,收在一条带子里 |
| 智能体区域 | 跑在同一个智能体上的所有对话,跨文件夹 |
| 会话卡片 | 一个对话,钉在你放下它的地方。选择器可搜索 |
| 文件卡片 | 一个文件,就地阅读 —— 见下文 |
| 终端卡片 | 一个在你某个文件夹里运行的 shell —— 见下文 |
| 自定义区域 | 一个收藏区:没有任何自动规则,只装你拖进去的东西 |
| 便签卡片 | 文字。写那些不属于任何人对话记录的推敲 |
前三种是绑定的 —— 它们跟着自己的文件夹、分组或智能体走,新对话会自己出现在里面。收藏区则是你的:它只装你放进去的,不会有东西不请自来。
画板上的文件和终端
从 0.30.5 起,画布上装的不只是对话。
文件卡片是你希望在智能体干活时一直看得见的文件 —— 一份规格、一份计划、一段日志、一张设计稿。添加到画布 → 文件卡片会列出工作区里已经打开的文件;输入文字则改为搜索当前文件夹;在本地的桌面窗口里,还可以用浏览…选这台机器上任意位置的文件。卡片按文件栏的方式渲染文件 —— Markdown 和 HTML 带预览 / 源码切换,还有图片、Office 文档、自 0.35.2 起带着自己工具栏的 PDF、源代码 —— 因为它是同一个文件标签页的视图,而不是一份副本;PDF 甚至会在卡片和标签页之间保持同一个页码和缩放。它刻意是只读的:编辑留在文件栏里,保存也在那里。重新加载会从磁盘重新读取,在工作区打开跳到那个标签页;渲染后的 Markdown 里的链接会在工作区中打开,而不是把卡片显示的内容换掉。文件后来没了,卡片会作为一个可以移除的空框留在画板上。
终端卡片是你某个文件夹里的一个 shell —— 在添加到画布 → 终端卡片里选文件夹。它运行你的默认 shell,你离开这个路由时它不会停,回来时仍在运行,近期的输出也还在:关掉视图不会杀掉任何东西。进程退出后,最后的输出仍留在屏幕上,上面盖着一个重启终端按钮;即使你关掉了创建它时所用的文件夹,这张卡片也照常工作。于是一个画布可以为某个功能涉及的每个仓库各放一个 pnpm dev,紧挨着正在处理它们的对话。
移除一张终端卡片 —— 或者删除包含终端卡片的选区或画布 —— 都会先询问,因为里面的 shell 不存在于别处。退出 Codeg 时,终端卡片会和其他所有终端一起被停掉。
用拖拽来编排
画板的整套编辑方式就是拖放,而两个方向的含义并不相同:
- 把卡片从区域里拖到空白画板上,它就成为一张钉住的卡片。从收藏区里拖出是移动;从绑定区域里拖出是复制 —— 因为文件夹区域对「有哪些对话」并没有发言权,移走卡片并不会把对话从文件夹里移走。
- 把卡片拖进收藏区,就把它收了进去。
同一个对话可以同时待在任意多个区域里,这正是「复制」规则的意义所在,也可以出现在任意多个画布上。选中一张卡片,它在同一个画布上别处的分身也会一起亮起,于是你能看见它还住在哪里。
除此之外:给区域重命名、折叠、调整大小,给任何东西上色(区域、卡片和便签都可以;区域里的卡片穿区域的颜色),把区域的成员网格设成固定的列数或行数,或者留给自动。成员多到放不下的区域会显示还有 N 个,配上显示全部会话 / 收起多余会话。自动整理在画板铺散之后把它重新收拢,导出 PNG 则给它拍一张照,文件以画布的名字命名 —— 上限是 4096×4096,所以摊得足够开的画板会被裁掉边缘,而不是无止境地缩下去。
框选多个东西,工具条会给出收进新区域 —— 这是做收藏区最快的方式,因为你先聚起来,再给它起名字。
删除选中项时,会先问那些别处没有的东西
会话卡片是一个视图:删掉它,对话本身分毫未动。便签不是 —— 它的文字不存在于别处 —— 终端卡片里的 shell 也不是。所以包含写了内容的便签、或包含任何终端卡片的删除会先确认,并告诉你各有几个;而纯卡片的选择、或者你从没往里打过字的便签,都会直接删掉。
一张卡片就是一个真正的对话
这正是画布与「地图」的区别。展开一张钉住的卡片,你得到的是一个能干活的对话:对话记录、带着智能体设置按钮的 composer,以及权限、提问和方案对话框 —— 在画板上真正跑一轮所需要的一切。新建会话的卡片还会额外提供智能体选择器,因为那是这个选择尚未落定的唯一时刻 —— 而从 0.35.2 起,在你选中的智能体还在连接时,这个选择也仍未落定,所以选错了只需再点一下:你最后选的那个智能体,才是真正去连接的那个。已经存在的对话保持它开场时的那个智能体,和在标签页里完全一样。
有几样东西留在标签页视图里,刻意没有一起过来:消息队列、中途发送和导出。画布是为了让多个对话并排跑,而不是取代那个属于单个对话的界面。
卡片里的文件链接会在它旁边打开。 画布占满整页时,工作区的文件栏并不在屏幕上,所以在卡片的对话记录里点文件徽章、Markdown 链接或查看差异,会在对话旁边的侧面板里打开一个只读预览,在工作区打开也只有一步之遥。对于普通文件,底下仍是同一个工作区文件标签页 —— 面板只是它的一个视图 —— 所以在那儿读它不会损失什么。在 0.30.3 之前,这些点击会在你看不见的那一栏里打开标签页,看上去就像什么都没发生。待办看板出于同样的理由也是这么做的;从 0.32.2 起,用这种方式打开的网页也会显示在那里,而不再让面板一片空白。
区域里的卡片必须先移出到画板才能展开 —— 一个完整的对话界面远大于区域成员网格里的一格,所以它得先被钉住,才能长大。
打开画布并不会把上面每个智能体都叫起来
这条规则针对的是不去拉起智能体,而不是拒绝一个本来就在那里的。对话处于休眠的卡片会立刻画出对话记录,但直到你第一次点它才会去连接 —— 否则走进一个有十几张卡片的画布,就会一次拉起十几个智能体 CLI。而智能体已经在跑的卡片会以活着的状态回来,因为让它继续睡着,只会让你看着一张显示为已断连的卡片,而它的回复正往里面流。
而一旦某张卡片已经活着,它就攥住自己的连接:把它平移出屏幕不会悄悄把它卸载成一次断连。至于你已经在标签页里打开的对话,它在画布上的卡片会以观察者身份接入 —— 连接归标签页,卡片只是看着。
在画布上找路
画板按设计就比窗口大,所以底部角落里放着导航:放大 / 缩小、重置缩放为 100%、适应视图,以及它们上方那张整块画板的导航地图。导航地图可以收起,收没收起按设备记住,对所有画布一起生效。
每个画布都保留自己的缩放和位置,在每台设备上的多次访问之间记住,并且与应用的界面缩放相互独立。这个分离是刻意的:把画板放大是角落那个控件的职责,于是你缩放界面时,卡片的尺寸不会在脚下变形。而工具坞、导航地图和各种菜单属于窗口装饰,仍然跟随应用的缩放。
正在运行的对话会呼吸般闪动,区域则会数出它的成员里有多少个在跑 —— 于是瞟一眼折叠着的区域,就知道它里面有没有东西在干活。带着子智能体的卡片会用徽标标出有几个。
值得了解
- 画布存在你的数据里,不在浏览器里。 桌面端和共享同一数据目录的服务器看到的是同样的画布,一边的改动另一边也会出现。你在每个画布上看到哪里,则按设备分别记住。
- 关掉文件夹并不会弄坏它的区域。 画布是对着 Codeg 知道的每一个文件夹来解析的,而不只是此刻在侧边栏里打开的那些,所以你关掉文件夹之后区域照常工作。文件夹不可用留给真正没了的文件夹 —— 被删除或找不到 —— 被删除的文件夹分组会留下同类的墓碑。
- 已经不存在的对话读作会话已删除。 看到时把卡片移掉即可,别的不需要收拾。删除一个对话,会把它从它所在的每一个画布上一并拿掉。
- 这一行可以隐藏。 如果画布不适合你,在侧边栏导航项里把无限画布关掉。
