跳到主要内容
Creator of UnderControl
查看所有作者

随时随地访问 — Web、桌面、CLI 全平台覆盖

· 阅读需 7 分钟
Creator of UnderControl

在选择生产力工具时,一个常见的困境是:Web 端功能强大但离线无法使用,桌面端体验好但数据被锁在本地,CLI 工具对开发者友好但缺少可视化界面。问题的本质是缺少一个统一的数据真实来源(Single Source of Truth)——每个平台各自为政,数据散落在不同角落。UnDercontrol 的答案是:四种形态,一个数据源。而这个数据源完全由你掌控——支持自部署,数据存储在你自己的服务器或本地磁盘,不经过任何第三方,隐私与安全由你自己定义。

Single Source of Truth 架构

任务中的富文本 Markdown — 代码、图表,一应俱全

· 阅读需 8 分钟
Creator of UnderControl

什么是任务(Task)?

在 UnDercontrol 中,Task(任务) 是信息的核心载体。如果你用过 Jira,可以把它理解为 Issue;如果你用过 Obsidian,可以把它理解为一篇 Note。Task 的本质是一段绑定了状态的主体内容,围绕它有一系列一等公民属性(标题、标签、链接关系等),同时支持无限的自定义元数据字段(键值对),让你可以将任何信息附加其上。通过笔记(Notes)机制,Task 还能不断演进——记录进展、讨论和决策,随时间沉淀为完整的知识上下文。

而这篇文章要讲的,是 UnDercontrol 中所有文本输入场景共享的富文本能力。说"任务",但不只是任务——无论是任务描述、笔记、支出备注还是账户说明,都使用同一套 Markdown 编辑器。你在任务里用到的代码块、Mermaid 图表、表格、清单,在笔记和其他场景中同样可用。

远程工作区 — 从浏览器在你的机器上运行 AI 代理

· 阅读需 7 分钟
Creator of UnderControl

你在 Web 界面写好任务描述,点击一个按钮。三十秒后,你笔记本上的 AI 代理已经在读取任务、编写代码、运行测试,并把进度备注实时回传到同一个任务页面——而你只需要在浏览器里看着就好。

这就是远程工作区。它在云端任务管理器和本地开发环境之间架起了一座桥梁,让 UnDercontrol 成为 AI 编程代理的远程控制器。

不登录,也能看到你的笔记

· 阅读需 4 分钟
Creator of UnderControl

你在咖啡厅,有人问起你正在做的项目计划。你可以打开电脑登录账号,然后把笔记本递过去——但你更不想这么做。

UnDercontrol 的任务分享功能解决了这个问题。生成一个公开链接,给出一个短访问码,对方就能查看这个任务的所有内容——描述、笔记、附件,完整呈现——不需要注册账号,也不需要碰你的密码。

可复用的 AI 技能——属于你的提示词模板

· 阅读需 5 分钟
Creator of UnderControl

如果你经常使用 AI 助手,大概已经积累了一套真正好用的提示词。那个总能产出干净结果的重构提示词,符合团队风格的提交信息模板,还有每次生产故障时都要粘贴一遍的 bug 排查清单。

问题在于,这些提示词要么藏在你脑子里,要么贴在便利贴上,要么埋在一个没人记得打开的 Notion 文档里。UnDercontrol 的技能系统就是为了解决这个问题。

什么是技能?

技能是存储在 UnDercontrol 中的具名、可复用提示词模板。每个技能都有一个 slug(例如 refactor-tsdaily-standuppr-review),一段 markdown 正文,并归属于某个群组。最后这一点很重要——技能的作用域是群组级别的,团队可以共享同一套提示词库,而不需要每个人各自维护一份副本。

你可以通过 Web 界面创建和编辑技能,通过 CLI 管理技能,也可以通过 YAML 文件以声明式方式应用技能。markdown 内容支持各种提示词结构:指令、变量、多步骤工作流,满足你的任何使用场景。

Skills page showing system and custom skills with search and tags

创建技能

在 Web 编辑器中,创建技能就像写一篇笔记一样简单。给它起个名字、设定一个 slug,然后在 markdown 编辑器里写好提示词内容。保存之后,群组内的所有人立即可以使用。

通过 CLI,你可以像应用任务一样应用技能定义——使用带 YAML frontmatter 的 markdown 文件:

ud apply skill -f pr-review.md

文件格式大致如下:

---
name: pr-review
description: PR Review Checklist
tags:
- ai
- development
---

Review the following pull request diff and provide feedback on:
- Logic correctness
- Error handling
- Test coverage
- Naming and readability

这让技能具备了可移植性。你可以将它们纳入 dotfiles 仓库,和其他配置一起做版本管理,然后用一条命令部署到新的 UnDercontrol 实例。

使用技能——ud prompt 命令

技能真正的价值体现在使用方式上。ud prompt 命令通过 slug 获取技能内容,并将其输出到 stdout。之后你可以将它管道传递到任何地方。

想把技能传入 Claude Code?

claude-code $(ud prompt pr-review)

想在管道中与其他命令组合使用?

ud prompt pr-review | pbcopy

因为输出的就是标准的 stdout,ud prompt 可以与任何从 stdin 读取内容的工具配合使用——Claude Code、其他本地 AI 代理、shell 管道,一切都取决于你的工作流。UnDercontrol 不试图掌控 AI 层,它只是帮你管理好提示词,让你不必为此操心。

Skill detail view with markdown content and CLI usage commands

内置系统技能

UnDercontrol 内置了系统技能,在首次启动时自动创建。这些技能是只读的——不会被意外覆盖——既是实用的默认工具,也是了解技能结构的好范例。例如,ud-cli 系统技能提供了 CLI 命令结构的完整参考,使 AI 代理可以直接使用它来操作你的任务。

系统技能在 Web 界面中以锁图标标识,与你的自定义技能并列显示。你可以像调用自定义技能一样,通过 slug 引用它们。

长期管理技能

技能是 UnDercontrol 中的一等资源,通过 Web 界面和 CLI 均支持完整的增删改查操作。

  • ud get skills — 列出群组中的所有技能
  • ud describe skill <id> — 查看某个技能的完整内容
  • ud delete skill <id> — 删除不再需要的技能
  • ud apply skill -f skills/ — 一次性应用整个目录下的技能定义

Web 编辑器适合快速编辑和浏览现有技能,CLI 则更适合自动化、批量更新,以及将提示词库作为代码来管理。

为什么这很重要

技能背后的理念很简单:好用的提示词值得保留。将它们存储在一个自托管、群组作用域的系统中,意味着它们不会因为某人离职而消失,不会淹没在聊天记录里,也不需要每个人独立摸索出同样的工作流。

这也保护了你的提示词隐私。由于 UnDercontrol 是自托管的,你的提示词库——其中往往沉淀着组织知识、内部流程和特定领域的上下文——始终存放在你自己的基础设施上。

立即开始

技能功能今天就可以在 UnDercontrol 中使用。如果你已经在运行实例,可以在侧边栏中找到技能页面。如果你是首次部署,自托管指南可以帮助你在大约十分钟内完成部署。

阅读文档部署自己的实例即可开始。

团队协作,掌控不失:UnDercontrol 的协作功能详解

· 阅读需 5 分钟
Creator of UnderControl

大多数效率工具把协作当作附加功能来处理——给你一个分享按钮,也许再加个评论区,就算完了。UnDercontrol 采取了截然不同的思路:群组、基于角色的权限管理、共享任务,这些都是一等功能,与应用中的其他核心模块建立在同一套基础之上。

最重要的是,你依然在私有化部署的环境中运行。启用多人协作流程,不需要把数据交给任何第三方服务。

群组的工作原理

UnDercontrol 中的群组是一个共享工作空间。可以把它理解为一个容器,容纳需要共同查看或处理同一内容的人。常见的使用场景包括:家庭成员共同追踪开支预算、小团队协调项目任务,或者两个人共同分摊生活费用。

创建一个群组只需要几秒钟:填写名称、添加描述,你就成为群组的所有者。之后,你可以生成邀请链接,邀请其他人加入。

邀请链接有一定的灵活性。你可以设置有效期,让链接在一天或一周后自动失效——在添加临时协作者时非常实用。你也可以随时撤销任意链接。这是个小细节,但当你在意谁能访问你的工作空间时,它就变得很重要。

Group management for team collaboration

基于角色的权限管理

成员加入群组后,角色决定了他们能做什么。群组层面有三种角色:

  • 所有者(Owner) — 对群组拥有完全控制权,包括成员管理、设置以及所有共享内容
  • 管理员(Admin) — 可以管理成员和邀请链接,访问所有共享内容
  • 成员(Member) — 可以根据每个条目设置的权限级别查看和操作共享资源

除群组角色外,UnDercontrol 还有系统级别的角色:Admin、User 和 Visitor。如果你为小型组织运行一个私有化实例,可以创建自定义角色,为任务、支出、预算、文件等模块分配特定的权限组合。这种级别的访问控制通常只在企业级工具中才有,而在你自己运行的私有化应用中同样可以实现。

以合适的权限共享任务

将任务共享给群组时,你可以选择权限级别:只读或读写。

只读模式适用于你希望他人了解任务进展但不允许其修改的场景——例如,管理者查看任务列表,或者伴侣需要了解日程安排但不应意外编辑内容。

读写共享则实现了真正的协同工作。群组成员可以更新任务、勾选事项,与你并肩推进。共享任务会出现在每位成员的任务列表中,不会有任何内容被埋没。

附加到共享任务的文件,群组成员可以自动访问,无需单独的文件共享步骤。只要你在任务中附上了 PDF 或图片,所有有权限的人都能看到它。

看板与共享工作流

共享看板与群组系统直接集成。创建共享看板时,系统会在后台自动创建一个对应的群组。看板创建者成为群组管理员,协作者以成员身份加入。这意味着团队的工作流程始终绑定在一套完整的权限模型上,而不是一个任何人都能偶然访问的开放链接。

Shared kanban board for team collaboration

实用建议

在创建第一个群组之前,有几点值得了解:

目前每个用户同一时间只能属于一个群组,因此请提前规划工作空间的结构。如果你同时协调一个工作项目和一个家庭预算,相关人员需要选择加入哪个群组——或者你在同一个群组下通过清晰的任务命名规范来区分两类内容。

从一开始就使用有描述性的群组名称。"家庭预算 2026"或"后端团队 Q2"在三个月后仍然一目了然,远胜于"我的群组"这类含糊的名字。

在邀请临时协作者时,务必为邀请链接设置有效期。这只需要额外两秒钟,却省去了日后手动撤销链接的麻烦。

定期检查成员列表。人员会变动,项目会结束,生活情况也会改变。保持成员列表的及时更新,是任何共享工作空间的基本维护习惯。

立即开始

如果你已经有一个正在运行的私有化实例,前往"群组"页面创建你的第一个群组。如果你还没有搭建 UnDercontrol,私有化部署指南提供了完整的配置流程——使用 Docker 可以在一小时内完成部署。

协作功能文档涵盖了每项功能的详细说明,包括完整的权限系统,以及群组与预算、资源模块之间的交互方式。

基于 Server-Sent Events 的多端实时同步

· 阅读需 5 分钟
Creator of UnderControl

如果你同时在浏览器标签页、桌面应用和手机上打开了 UnDercontrol,你自然希望它们保持同步。在一个地方添加任务,其他地方应该立即显示,无需刷新页面。记录一笔支出,预算应该在所有端实时更新。

这种实时同步听起来简单,但一旦考虑到重连、离线状态以及长连接的资源开销,复杂度就会迅速上升。以下是 UnDercontrol 的处理方式。

为什么选择 Server-Sent Events

WebSocket 是实时功能的常见选择,但它有额外的开销——双向连接、自定义协议处理,以及两端更高的实现复杂度。在 UnDercontrol 中,数据更新的流向几乎完全是单向的:服务端向客户端推送变更。这与 Server-Sent Events(SSE)完美契合。SSE 是所有现代浏览器内置支持的标准 HTTP 机制。

SSE 基于普通 HTTP 实现持久连接,浏览器规范内置自动重连能力,除了运行实例所用的 Go 后端外,不需要任何额外基础设施。这让自托管模式保持简洁。

工作原理

打开 UnDercontrol 时,前端会向后端建立一条 SSE 连接。你的会话被注册到一个按用户维护的连接中枢——该结构追踪你账户下所有活跃连接,涵盖各个标签页、设备以及 Electron 桌面应用。当数据发生变化(任务被更新、支出被记录、文件被重命名),后端会向内部异步事件总线发布一个事件,该事件随即广播到你用户 ID 下注册的所有连接。

这意味着你在手机上记录一笔支出,浏览器标签页会在毫秒内感知到。无需轮询,无需手动刷新。

Task list view — changes sync in real-time across all connected clients

连接的生命周期经过精心管理。连接最长保持 30 分钟,到期后会自动重连。这可以防止长时间运行的实例出现资源泄漏,同时与有自身超时规则的负载均衡器和反向代理友好兼容。如果连接因任何原因断开——网络抖动、设备休眠唤醒、代理超时——客户端会使用指数退避策略自动重连。初始延迟较短,随后逐步增加,避免短暂离线的设备在恢复上线时瞬间冲击服务器。

客户端的智能缓存更新

收到事件是一回事,知道如何处理又是另一回事。UnDercontrol 并不会在 SSE 事件到达时盲目地重新拉取全量数据。前端采用差量缓存更新策略:识别哪些内容发生了变化,在本地 Zustand store 中找到对应条目,仅更新该条记录。

例如,某个任务的状态从"进行中"变为"已完成",事件只携带该任务的最新状态。客户端将其合并到现有缓存中,列表以新状态重新渲染,其余内容保持不变。

这让界面保持流畅,避免了那种因频繁全量请求而带来的突兀刷新感。

Kanban board with live status updates pushed via SSE

乐观更新与服务端协调

SSE 与 UnDercontrol 的乐观更新模型协同工作。本地做出变更时,界面立即响应——无需等待,无需加载动画。写入操作在后台发送到服务端。成功后,服务端发布一个 SSE 事件,传播到你的其他客户端。若操作失败,本地状态回滚,并显示错误提示。

最终效果是:主设备感觉即时响应,其他设备保持一致。服务端是唯一的数据来源,SSE 是让各端与之保持同步的机制。

你能直接感受到的好处

在两个浏览器标签页中打开同一个 UnDercontrol 实例,在其中一个标签页做出修改,另一个标签页无需任何操作即可看到变更。当你在一块屏幕上查看预算概览、在另一块屏幕上记录交易时,这一特性尤为实用。

Budget overview — expense changes propagate instantly to all open views

Electron 桌面应用同样参与这套同步机制。通过 CLI 或 Chrome 扩展所做的变更,也会通过 SSE 传播到当前打开的所有端。整个多平台体验的基础,正是这一层同步机制的可靠运行。

亲自体验

这一切运行在你自己的硬件上。没有云依赖,没有第三方同步服务,数据始终在你的掌控之中。SSE 端点是标准 UnDercontrol 后端的一部分。

如果你还没有部署 UnDercontrol,自部署指南介绍了如何在几分钟内通过 Docker 完成启动。如果你已经在运行实例,同步功能已经处于激活状态——打开第二个标签页,亲眼看看效果。

部署说明和配置选项请参阅文档

用 ud CLI 在终端中管理任务

· 阅读需 4 分钟
Creator of UnderControl

如果你大部分时间都在终端里工作,那么每次记录任务或查看待办事项都要切换到浏览器标签页,这种上下文切换完全没有必要。ud CLI 正是为了消除这种干扰而生。它将 UnDercontrol 的全部功能——任务增删改查、笔记、查询、看板——带入你的 shell 环境,并采用你已经熟悉的命令结构。

kubectl 风格的命令,因为它好用

CLI 使用与 kubectl 相同的动词-资源模式,这种模式让无数工程师觉得上手自然。你可以 get、describe、apply 和 delete 资源,无需建立新的心智模型。

# 列出所有任务
ud get task

# 查看任务完整详情(支持短 ID 前缀)
ud describe task 3de9f82b

# 从 markdown 文件创建或更新任务
ud apply -f task.md

# 删除任务
ud delete task abc123

apply 命令值得重点介绍。你的任务就是一个带有 YAML frontmatter 的 markdown 文件。如果文件中有 id 字段,则更新已有任务;没有 id,则新建任务。这使得批量更新、脚本化工作流以及版本控制的任务定义变得简单直接。

echo '---
title: Write release notes
status: in-progress
tags:
- release
deadline: 2026-04-10
---

Draft the changelog and update the docs site.' | ud apply -f -

Task list view — what the ud CLI manages from your terminal

真正能过滤的查询语法

ud task query 提供了一种类 SQL 的过滤语言,用于查询你的任务。当任务数量多到"翻列表"不再是可行策略时,它就派上用场了。

# 本周截止的任务
ud task query "deadline BETWEEN 'today' AND '+7d'"

# 标记为 urgent 的进行中任务
ud task query "(status = 'todo' OR status = 'in-progress') AND tags = 'urgent'"

# 标题搜索
ud task query "title ILIKE '%api%'"

如果你不想考虑语法,ud task nlquery 支持直接输入自然语言,并通过 AI 将其转译为查询:

ud task nlquery "show me overdue tasks"
ud task nlquery "tasks tagged with work that are not done"

两个命令都支持 --sort--order--limit 参数,便于分页和排序,可以干净地组合进脚本或 shell 别名中。

用笔记记录进度

每个任务都支持笔记——简短的自由格式条目,充当持续更新的进度日志。这对于记录你实际做了什么很有用,而不只是最终状态。

ud task note add 3de9f82b "Finished the backend changes, opening PR now"
ud task note ls 3de9f82b

笔记也让 CLI 天然适合 AI 智能体工作流。智能体可以从计划文件创建任务,在每个步骤追加进度笔记,最后标记任务完成——全程无需打开浏览器。团队的其他成员可以在 UnDercontrol Web 界面或桌面应用中看到完整的历史记录。这种交接方式轻量、实用,真正跑得通。

需要可视化时,用交互式 TUI

不带任何参数运行 ud,会打开终端 UI——一个支持键盘操作的看板式界面,带有 vim 风格的按键绑定。

Built-in terminal with ud CLI commands

按键操作
j / k在任务间移动
Enter打开任务详情
i新建任务
x切换状态
/搜索
f文件选择器(模糊搜索本地文件以创建任务)

文件选择器是个亮点。按 f,在当前目录中模糊搜索 markdown 文件,它就会变成一个任务——第一行作为标题,其余内容作为描述。如果你习惯在项目仓库中用 markdown 记笔记,并想把它们纳入任务追踪,这个功能非常实用。

多上下文支持多个服务器

如果你在多个环境中自托管 UnDercontrol——个人、工作、测试实例——上下文系统的处理方式与 kubectl 完全相同。

ud config set-context work --api-url https://ud.company.com
ud login --context work

# 单次命令使用不同上下文
UD_CONTEXT=personal ud get task

配置文件位于 ~/.config/ud/config.yaml。你也可以完全通过环境变量(UD_API_URLUD_API_KEYUD_TOKEN)驱动 CLI,无需修改配置文件,在 CI 流水线中同样可用。

快速开始

通过 npm、Homebrew 或一行 curl 命令安装:

npm install -g @oatnil/ud
# 或
brew install oatnil-top/ud/ud
# 或
curl -fsSL https://get.oatnil.com/ud | bash

然后指向你的 UnDercontrol 实例:

ud login

完整的命令参考——包括文件附件、多上下文认证和高级查询语法——请查阅 CLI Reference 文档。如果你还没有运行 UnDercontrol,自托管指南 介绍了如何在几分钟内用 Docker 启动一个服务器。