使用 CLI Context 管理多个账户
如果你同时运行多个 UnDercontrol 实例——比如一个个人服务器和一个工作服务器——你大概已经体会过在不同 API 端点和凭据之间反复切换的麻烦。ud CLI 内置了一套仿照 kubectl 设计的 context 系统,切换账户只需一条命令。
如果你同时运行多个 UnDercontrol 实例——比如一个个人服务器和一个工作服务器——你大概已经体会过在不同 API 端点和凭据之间反复切换的麻烦。ud CLI 内置了一套仿照 kubectl 设计的 context 系统,切换账户只需一条命令。
当 UnDercontrol 里的任务积累到一定数量,"滚动浏览"这种方式就会开始失效。你清楚地知道自己在找什么——已逾期的项目、所有标记了 work 且仍在进行中的任务、还没有截止日期的待办——但仅靠状态筛选,很难快速定位到它们。
本文介绍 UnDercontrol 内置的查询系统:一套类 SQL 语法,可在 Web 界面、CLI、自定义视图、看板以及已保存查询中统一使用。一旦上手,你会发现自己几乎每天都在用它。
这套语法在设计上与 SQL WHERE 子句非常接近。如果你写过数据库查询,会立刻感到熟悉;如果没有,基础部分大约五分钟就能掌握。
一个简单的查询如下:
status = 'todo' AND deadline <= 'today'
这会找出所有状态为待办、且截止日期在今天或更早的任务——也就是已逾期的待办项。
你可以在此基础上加入标签、文本搜索、日期范围和自定义字段:
(deadline <= 'today' OR tags = 'urgent') AND status != 'done' AND status != 'archived'
这是一个可靠的"当前需要处理"查询。将它保存为已保存查询(下文详述),就有了一个一键直达的紧急任务列表。

语法中较为实用的一部分是相对日期支持。你不需要写死具体日期,而是使用 '-7d'、'+1w' 或直接写 'today' 这样的表达式。
-- 过去一周内创建的任务
created_at >= '-7d'
-- 未来一个月内到期
deadline BETWEEN 'today' AND '+1m'
-- 今天有更新
updated_at >= 'today'
支持的时间单位包括天(d)、周(w)、月(m)和年(y),+ 表示未来,- 表示过去。当你需要固定日期时,2025-06-01 这样的标准 ISO 8601 格式同样适用。
文本搜索使用 LIKE(区分大小写)和 ILIKE(不区分大小写),以 % 作为通配符:
title ILIKE '%api%'
自定义字段需加上 cf. 前缀:
cf.priority > 3 AND cf.department = 'engineering'
自定义字段根据其类型支持完整的比较运算符——数字、文本、下拉选项、复选框和用户引用均可使用。
熟悉语法后,手写查询其实很快。但如果你更倾向于直接描述需求,AI 集成功能可以自动完成转换。
在 Web 界面中,打开任务页面的 AI Chat 面板,输入类似"显示带有 work 标签的逾期任务",AI 会自动生成结构化查询并执行。
在 CLI 中,使用 ud task nlquery:
ud task nlquery "tasks I need to finish this week"
ud task nlquery "high priority engineering items with no deadline"
如果想少打几个字,nl 别名同样有效。此功能需要配置 AI 提供商,但一旦设置完成,它能处理相当自然的描述方式。
这是查询系统真正在日常使用中发挥价值的地方。已保存查询允许你为任意查询命名并存储,之后只需在侧边栏点击一下即可执行。

以下几个查询值得立即配置:
| 名称 | 查询 |
|---|---|
| 已逾期 | deadline < 'today' AND status != 'done' AND status != 'archived' |
| 本周到期 | deadline BETWEEN 'today' AND '+7d' AND status != 'done' |
| 未规划 | deadline IS NULL AND status = 'todo' |
| 近期活跃 | updated_at >= '-7d' AND status IN ('todo', 'in-progress') |
你可以将常用查询置顶,通过拖拽调整顺序,并随时编辑。点击已保存查询后,结果会在当前页面内展开,无需跳转。
CLI 通过 ud task query 支持相同的查询语法:
ud task query "status = 'todo'" --sort deadline --order asc
ud task query "(status = 'todo' OR status = 'in-progress') AND tags = 'work'"
分页(--page、--limit)和排序(--sort、--order)参数均可使用。这使得将查询结果导入其他工具或在 shell 脚本中调用查询变得非常方便。
完整的查询语法参考文档请见查询语法文档,包含所有运算符、日期时间表达式格式,以及一套可直接复用和改写的实用示例。
如果你还没有部署 UnDercontrol,自托管指南介绍了如何通过 Docker 完成部署。你的数据始终保存在自己的基础设施上——这正是它的核心价值所在。
大多数效率工具把文件存储当作附加功能——某个角落里的文件夹,与它所支撑的工作毫无关联。UnDercontrol 的做法不同:文件直接存放在它所属的任务、支出和预算旁边,收据跟着它对应的支出走,设计图跟着它所服务的任务走。
下面介绍资源管理系统在实际使用中的工作方式。

将文件导入 UnDercontrol 不应该每次都要打开文件选择器绕一圈。目前支持三种主要上传方式:
拖放上传 — 打开资源页面,或在任务、支出的附件面板中,直接将文件拖入即可。支持单文件和批量上传。
剪贴板粘贴 — 按下 Ctrl+V,剪贴板中的文件会立即上传。这对截图尤其方便。对着收据或界面 bug 截个图,切换到 UnDercontrol,粘贴。无需先保存到磁盘。
CLI 上传 — 如果你习惯在终端工作,ud CLI 可以直接处理上传:
ud upload resource ./receipt.png --entity-type expense --entity-id exp-456
这在自动化工作流中很有用,比如将导出的报告自动附加到每月预算审查任务中。
同一个资源可以关联到多个条目。如果有一份合同 PDF 同时与某个预算和某个任务相关,你可以将它分别附加到两者——无需重复文件,也无需翻找文件夹。当任务标记为完成后,可以取消该文件与任务的关联,同时保留它与预算的附加关系。
检查器面板会清晰显示某个文件附加到了哪些条目,让你随时掌握文件的引用情况。
资源页面提供所有已上传文件的完整概览,并内置筛选功能。你可以按文件类型、附加的实体类型(任务、支出、预算、账户)或日期范围进行筛选。对于图片,图库视图会显示缩略图,让你无需逐一打开便能快速浏览一批收据或截图。
检查器还会显示照片的 EXIF 元数据——如果你需要确认照片的拍摄时间或地点,这非常实用。

由于 UnDercontrol 是自托管的,你可以完全掌控文件的存储位置。默认使用本地磁盘存储,对于运行在家庭服务器或 VPS 上的个人使用场景完全够用。对于更大规模的部署或远程访问需求,可以配置兼容 S3 的对象存储——AWS S3、Backblaze B2、MinIO,用你已有的方案即可。
关键一点:你的文件不会经过任何第三方服务,直接从浏览器传输到你自己的服务器。
存储限制可自行配置。普通用户默认获得 1 GB 空间,单文件上限 10 MB。管理员则不受限制。
如果你的工作流程涉及系统图、流程图或架构草图,UnDercontrol 内置了 drawio 支持。你可以直接在应用内创建和编辑图表,无需导出为 PNG,也无需切换到其他工具再重新上传。图表文件作为资源附加在对应的任务或笔记上。
对于收据和文档扫描件,AI 集成功能值得了解。你可以打开一张图片资源,让 AI 从中提取信息——比如收据上的明细条目、扫描表格中的文字。这与支出追踪工作流天然契合:拍一张收据照片,附加到支出条目,让 AI 自动提取金额和商家名称。
举一个实际的例子:你在追踪一个自由职业项目。有一个"审查客户合同"的任务,你将合同 PDF 附加到该任务。随后,你为项目采购的软件记录了一笔支出,并将发票附加到该支出条目。这两个文件都会出现在资源页面中——你可以按实体类型筛选,只查看支出附件,也可以一起查看,对整个项目进行完整的文件审计。
所有内容集中在一处,无需外部文件托管,也无需翻找邮件记录。

如果你已经在运行 UnDercontrol,资源页面可以在主导航中找到。如果你正在评估是否自托管,部署指南 涵盖了实例搭建的全部流程,包括存储配置。
资源管理文档 提供了 CLI 命令、存储配置和实体附加选项的完整参考。
这种挫败感往往是慢慢积累的。你注册了一款效率工具,把任务和财务数据迁移进去,围绕它建立起工作习惯——然后某一天,定价突然变了,公司转型了,甚至服务直接关停了。你的数据就此消失,或者被锁在一个导出按钮后面,导出来的东西几乎无法使用。
UnDercontrol 从一开始就是为了彻底避免这种情况而设计的。它支持自托管,意味着你在自己掌控的基础设施上运行它,数据存放在你指定的地方。

对大多数人来说,Docker Compose 是最快的启动方式。一个 docker-compose.yml 文件就能拉取后端和前端镜像,将它们连接起来,几分钟内就能在你的服务器或本地机器上运行 UnDercontrol。
一个最简配置大致如下:一个将数据目录挂载为卷的后端服务、一个指向它的前端服务,以及可选的 Caddy 或 Nginx 反向代理。对于单用户或小家庭部署来说,这就是全部了。不需要托管云账户,不需要第三方服务的 API 密钥,数据不会离开你的网络。
Docker 镜像设计得轻量且行为可预期。它不会回连服务器,初次拉取后无需网络连接,所有内容都存储在你配置的路径下。
如果你在使用 Kubernetes 搭建家庭实验室,或者希望获得正式编排带来的可靠性,UnDercontrol 同样提供了 Kubernetes 清单文件。你可以使用标准的 Deployment 和 Service、用于数据持久化的 PersistentVolumeClaim,以及用于环境配置的 ConfigMap。
这对于为小型团队——家庭、朋友群组、小公司——部署 UnDercontrol 尤为实用。你可以设置合理的资源限制、滚动更新,并在需要时独立扩展后端。Kubernetes 还让添加 Ingress 规则、TLS 终止和命名空间级别的隔离变得非常简单。
UnDercontrol 在数据库选择上给了你充分的灵活性。对于单用户或少量用户的场景,SQLite 是默认选项,而且表现非常出色。无需管理数据库服务器,无需配置连接池,备份就是复制一个文件那么简单。在这种场景下,SQLite 的能力出乎意料地强,运维负担几乎为零。
当你需要更多能力时——并发用户、大规模数据集、与现有数据库基础设施集成——切换到 PostgreSQL 只需修改环境变量并运行迁移。两种后端的 Schema 完全一致,不需要重新设计任何东西,只需将应用指向你的 Postgres 实例即可。
这种灵活性很重要,因为你的需求会随时间变化。从 SQLite 起步、之后再迁移是一条官方支持的路径,而不是事后才想到的补丁。
自托管意味着你的任务、财务记录、上传的文件以及 AI 对话历史,全部存储在你掌控的存储介质上。想迁移到其他服务器,只需复制数据目录并更新部署配置。想备份所有内容,备份那个目录就行。即使你决定彻底停用 UnDercontrol,数据依然在那里,格式可读。
不需要注销账户,不需要提交工单,不需要等待期。数据属于你,因为它从一开始就在你的机器上。
这也意味着你控制着访问权限。在私有网络或 VPN 后面运行 UnDercontrol,你的财务数据就不会触及公共互联网,除非你主动将其路由出去。对于追踪详细预算或敏感个人信息的用户来说,这绝非小事。
后端 API 有完整文档,且对外开放。CLI 使用 kubectl 风格的命令,与 Web 应用调用的是同一套 API。你可以编写脚本调用它、与其他工具集成,或者构建自己的客户端。任务和笔记的格式设计上注重可移植性。
我们的目标始终是:让你持续使用它,是因为它真的有用——而不是因为迁移走的代价太高、懒得折腾。
部署指南详细介绍了 Docker Compose 配置、Kubernetes 清单、数据库配置以及备份策略。如果你有一台服务器或闲置的机器,今天就能跑起来一个可用实例。
查阅自托管文档开始部署,或者在 GitHub 上提 Issue,如果配置过程中有任何地方不符合预期。
个人财务和任务管理中最让人头疼的环节,往往不是做决策,而是录入数据。吃完午饭,手里拿着一张收据,却要打开 app、一路点开表单、输入金额、选择分类、再点保存。这样的操作每天要重复无数次——每杯咖啡、每次打车、每趟买菜——日积月累,就成了真实存在的摩擦。
UnDercontrol 的 AI 助手正是为了消除这种摩擦而设计的。下面介绍它在实际使用中的具体表现。


最直接实用的 AI 功能是收据扫描。新建支出时,你可以上传一张照片——拖拽、从剪贴板粘贴或选择文件均可。AI 会读取图片,自动提取金额、货币、商家名称、日期,并给出一个建议分类。
它能处理揉皱的收据、倾斜的角度和不同格式的小票,表现相当稳定。有一个实用技巧值得记住:光线比摆放角度更重要。在充足光线下拍摄的清晰照片,几乎都能正确解析;而在昏暗餐厅里拍的模糊照片,则很可能识别失败。
你也可以一次批量上传多张收据,非常适合出差回来或积压了一周账单的情况。
并不是每笔支出都有收据。对于这类情况,直接用自然语言描述就好:
AI 会将描述解析成填好各字段的结构化支出记录,比逐个点选表单快得多,在手机上尤其明显。
同样的方式也适用于任务。不需要填写任务表单,直接描述要做的事:
UnDercontrol 会根据描述生成结构化任务,包括标题、可推断的相关标签以及描述内容。你检查一遍,改掉不准确的地方,保存即可。

当系统中积累了一定数量的任务和支出后,你可以用日常语言直接提问。比如"显示逾期任务"或"本周有什么待办",这些问题会被转化为查询条件并返回匹配结果。这不是什么魔法——对于简单直接的问题效果最好——但它确实省去了记忆 UnDercontrol 查询语法的麻烦。
在 iOS 和 macOS 上,UnDercontrol 提供了 Apple Shortcuts,可以将 AI 功能接入系统的分享菜单和快捷指令自动化。实际好处就是:在设备上任意位置,一键即可完成录入。
最实用的一个快捷指令:用相机拍一张照片,运行该指令,收据就会作为支出记录保存下来,全程无需打开 app。你也可以分享文字内容——复制的邮件片段、一条消息、一条备忘录——直接从中创建任务。
快捷指令可在你的 UnDercontrol 实例的订阅/下载页面获取。
UnDercontrol 不绑定任何单一 AI 后端。你可以接入自己的 API key,来源可以是 OpenAI、Anthropic,或任何兼容 OpenAI 接口的服务。如果你希望所有计算都在本地完成、不依赖任何外部 API,也可以通过 Ollama 或 LM Studio 接入本地模型。
配置过程很简单:进入个人资料设置,找到 AI Providers 部分,添加服务商和 API key,选择模型,测试连接。你可以添加多个服务商并设置优先级,列表中第一个可用的服务商会被实际调用。
如果你运行的是多人共享的 UnDercontrol 实例,管理员还可以配置系统级服务商,供所有用户使用——对于家庭服务器或小型团队来说非常方便。
AI 提取的准确率很高,但并非完美。保存之前,务必快速检查一下解析结果,尤其是金额和日期字段。如果收据上的合计金额在视觉上与小计行很接近,解析器可能会混淆。花两秒钟确认一下,远比事后追查一笔记错的账要省力得多。
对于文字输入,描述越具体,结果越准确。"咖啡"比"登机前在机场喝的咖啡,6.50 美元"更难分类。
如果你已经在运行 UnDercontrol,前往个人资料设置,添加一个 AI 服务商。下次记录支出时,试着上传一张收据——工作流上的差异会立刻显现出来。
如果你还没有部署 UnDercontrol,自托管指南涵盖了从 Docker 部署到配置的全部内容:UnDercontrol 文档。
大多数个人理财工具都让你在隐私与功能之间二选一:要么把财务数据交给云服务,要么凑合用一张电子表格——而后者一旦情况稍微复杂就会变得难以维护。UnDercontrol 提供了另一种选择:一个功能完整的预算追踪系统,运行在你自己的服务器上,数据始终在你的掌控之中。
下面来看看 UnDercontrol 的预算追踪功能在实际使用中是如何运作的。
在 UnDercontrol 中创建预算,从基本信息开始:名称、初始金额、开始日期和周期频率。支持按周、按月、按季度或按年——选择最符合你日常思维习惯的方式即可。
但真正的强大之处在于预算计划。UnDercontrol 不会把你锁定在一个固定金额里,而是允许你随时添加新的计划。比如你年初设定了每月 500 美元的餐饮预算,到了三月物价上涨,需要调整为 650 美元,直接添加一个更新金额的新计划即可。系统会自动处理计算逻辑——根据每个计划的生效时间段来汇总金额——历史数据保持准确,当前视图也始终是最新状态。
一次性调整可以覆盖周期计划无法处理的情况:收到意外退款、项目奖金分配、修正数据录入错误……每笔调整都会记录金额、日期和可选的备注说明。几个月后对账时,你会庆幸当初留下了那些备注。
在 UnDercontrol 中,消费记录是一等公民。添加一笔支出时,你可以将其关联到某个具体的预算。这个关联关系正是"预算 vs 实际"视图的数据基础——支出金额会汇总到该预算的已花费总额中,并显示在对应预算的账目明细里。
![]()
这种设计也允许存在不关联任何预算的支出记录,这是有意为之的。并非每笔交易都需要立刻分类。你可以先记下来,之后再回来关联,等到合适的时机处理即可。
预算详情页将所有信息整合在一起:顶部概览区一目了然地展示总分配额、已花费金额和剩余余额;支出趋势图则以 7 天、30 天或 90 天为维度,将实际支出与预算线并排呈现。如果你在追踪月度餐饮预算,图表显示在第 22 天就已突破分配上限,这个信号足够清晰,无需任何心算。
![]()
UnDercontrol 的账户系统支持同时追踪多个资金来源——活期账户、储蓄账户、独立的业务账户,无论你的财务结构如何都能适配。预算账户会汇入整体可用余额,因此在规划新预算时,你看到的是真实数字,而不是凭空估算。
当你管理小团队或家庭财务时,这一功能尤为实用。协作系统允许你与其他用户共享预算,多人可以同时向同一个预算记录支出,并看到相同的实时汇总数据。不再需要来回发送电子表格,也不用手动合并两套独立的记录系统。
预算列表页的设计让你可以一眼掌握全局:进度条、已花费和剩余金额,以及汇总所有预算总额的侧边栏。搜索功能帮助你快速定位特定预算。"显示隐藏项"开关则适用于那些想归档但不想删除的预算。
![]()
隐私模式值得一提:开启后,界面上所有金额数字都会被隐藏。在会议中共享屏幕时非常实用——你不需要向同事解释自己的餐饮预算。
在数据导出与可移植性方面,UnDercontrol 支持将消费历史以结构化格式导出。由于是自托管部署,你还可以直接访问底层数据库,随时执行自定义查询或将数据接入其他工具。
上述所有功能都运行在你自己的服务器上。你的财务数据不会经过任何第三方的基础设施。备份策略、访问权限、数据保留周期——一切都由你决定。对于那些在第三方应用里输入银行流水时感到不安的人来说,这一点至关重要。
如果你想开始上手,自部署指南 提供了使用 Docker 搭建 UnDercontrol 的完整流程。预算功能文档 则详细介绍了每项功能,包括预算总额的计算方式以及如何有效使用调整记录。
创建你的第一个预算,关联几笔支出,一周后再来看看。支出趋势图告诉你的,会比任何电子表格都多。
如果你一直用平铺列表管理任务,却越来越觉得力不从心,那看板很可能就是你需要的答案。UnderControl 的看板视图在你现有任务系统之上提供了一套基于列的布局——无需维护独立系统,无需重复数据,只是一种更直观地掌握全局的方式。
在了解其他内容之前,这一点值得先搞清楚。在 UnderControl 中,看板是任务系统之上的一层可视化界面。当你把一张卡片从"待办"拖到"进行中"时,你不只是在移动看板上的一张卡——你是在更新该任务的状态。这个变更会立即反映在任务列表、CLI 查询结果以及所有其他地方。不存在同步问题,因为始终只有一个数据来源。
这意味着你可以在看板视图和列表视图之间自由切换,完全不用担心数据不一致。
每个账户都内置了一个"全部任务"看板。打开它,你会看到所有任务按六个列排列:待办、进行中、待定、已搁置、已完成和已归档。这个看板无法删除,且始终显示在最前面。
这是一个很好的起点。把一个任务从"待办"拖到"进行中",状态会立即更新。这就是基本的操作逻辑——卡片的位置决定任务状态,而非反过来。
真正有意思的地方在于你创建自己的看板时。每一列都由一个过滤条件定义——本质上是一个查询,决定哪些任务属于这一列。"被阻塞"列可以过滤出打了 blocked 标签的任务,"本周到期"列可以按截止日期过滤。列不只是一个标签,而是一个实时查询。
当你为列配置操作后,移动卡片就变成了一个触发器。把任务拖入"已完成"列,它会自动标记为完成;把任务移入"待审核"列,可以一次性完成打标签和指派操作。你来定义拖入某一列意味着什么,看板负责处理后续的数据更新。
这对多步骤工作流非常实用。如果你的流程是草稿 -> 审核 -> 待发布 -> 完成,你可以完整地建模这个流程——每次列间转换都会对底层任务数据做出正确的变更。
私有看板只对你可见。你可以按需创建任意数量——为某个副业项目创建一个,为每周计划创建一个,为家装项目创建一个。它们都从你的完整任务池中拉取数据,并通过你配置的列条件进行过滤。
共享看板的工作方式有所不同。当你把看板共享给一个群组时,该看板只显示属于该群组的任务。群组中的每个人都可以看到这个看板,并根据各自的权限移动卡片。这是一个清晰的模型:看板的数据范围由群组决定,访问权限通过群组成员身份控制。
这让共享看板对小团队来说非常实用。为一个两三人的团队搭建一个迭代看板,让所有人都能看到哪些任务在进行、哪些被阻塞,配置简单,也不需要任何额外工具。
如果你还不确定如何规划看板结构,以下几种方式效果都不错:
基于状态的看板与默认设置类似——待办、进行中、已完成。结构简单、维护成本低,适合个人使用。
基于时间的看板使用积压、本周、今日、已完成这样的列结构。过滤条件基于截止日期或自定义字段,而非任务状态。把任务拖入"今日"列可以自动更新优先级字段。
带共享访问的项目看板利用群组功能将任务范围限定在特定项目内。列的划分对应团队实际的工作流阶段,所有人在同一个看板上协作。
由于看板构建在与 UnderControl 其他功能相同的任务和标签系统之上,它能与其他功能自然地组合使用。你在任务过滤器中使用的标签同样可以作为列的条件。你为项目创建的自定义字段可以驱动列的归属,并通过列操作自动更新。看板不是一个独立模块,而是任务系统的可视化呈现。
如果你想了解它如何融入整体配置,看板文档详细介绍了列配置、自动操作和共享功能。如果你还没有运行 UnderControl,自托管部署指南可以帮你在一小时内完成搭建——你的数据始终保存在自己的基础设施上。
Most task managers give you a list. Maybe a kanban board if you're lucky. UnderControl takes a different approach: your tasks are a data structure you can view, query, and manipulate from multiple angles — whether you're in the browser, the desktop app, or a terminal.
Here's a practical walkthrough of how the task system works.
Tasks in UnderControl move through six statuses: Todo, In Progress, Pending, Done, Stale, and Archived.
The distinction between Pending and Stale is one I find genuinely useful. Pending means you're deliberately waiting — on a reply, a dependency, a decision. Stale means the task just hasn't been touched in a while. That difference matters when you're doing a weekly review and trying to figure out what to act on versus what to clean up.
Different work calls for different views. UnderControl gives you seven:
Switching between views doesn't change your data — it's the same tasks, just rendered differently. The Graph view in particular is worth trying if you use linked tasks heavily.
You can link any two tasks together, and the connection is bidirectional — follow it from either side. Over time, this turns your task list into something closer to a knowledge graph. The Graph view is where this becomes visible: nodes are tasks, edges are links, and you can see clusters form around related work.
Derived tasks (parent-child relationships) work differently. When you create a task from an existing one, the child inherits context from the parent and links back to it automatically. This is the right pattern for breaking down a large project into concrete steps.
Every task has a notes section. Notes support full markdown — headers, code blocks, lists, links. More importantly, every note keeps a full edit history. If you wrote something, changed your mind, and want to go back, you can revert to any previous version.
I use notes for things like decision logs, blockers, and meeting summaries attached to a task. It keeps everything in one place instead of scattered across documents and chat threads.
The quick filters cover the common cases: filter by status, tags, or deadline range (overdue, today, this week, and so on). For more specific needs, there's a structured query language:
status = 'pending' AND tag:work = 'true'
If you don't want to write the query yourself, the AI assistant accepts plain English — something like "show me overdue tasks tagged with client work" — and translates it into a filter.
Attach any file to a task — images, PDFs, diagrams, exported reports. The attachments live on your server, under your control.
For sharing, you can generate a public link to a specific task with an optional expiration date. Or share with a group and set whether they get read or read-write access.
If you work in a terminal, ud gives you the full task API from the command line:
ud task list
ud task create "Review Q2 metrics"
ud task done <id>
ud task query "status = 'todo' AND deadline < '2026-05-01'"
ud task apply -f task.md
The apply command is particularly useful — you can write a task in a markdown file and push it to UnderControl, which fits nicely into scripting and automation workflows. The CLI follows kubectl-style conventions, so if you spend time in Kubernetes or similar tools, the patterns feel familiar.
For repeating work, recurring tasks generate new task instances on a schedule — daily standups, weekly reviews, monthly reports. You can use presets or write a custom CRON expression.
Check-ins are a lighter-weight alternative for habit tracking: each check-in increments a counter and records a timestamp, giving you a simple log of consistency without the overhead of a full task lifecycle.
All of this runs on your own infrastructure. No data leaves your server, no subscriptions, no vendor lock-in.
The full task management documentation is at undercontrol.dev/docs/tasks, and the self-hosting guide covers deployment with Docker or the prebuilt binaries. If you run into anything, the GitHub repo is the right place to file issues or ask questions.