Skip to content

Latest commit

 

History

History
280 lines (194 loc) · 17 KB

FAQ.md

File metadata and controls

280 lines (194 loc) · 17 KB

常见问题

19 个真问题,答案都能在代码里核对。文中路径相对仓库根;$DSH_HOME 默认是 ~/.dsh。

这个插件的中心规则:完成要人点头。 Agent 在工具里报完成,和交给的会话干净收尾后宿主自动 收尾,都只把记录送进「待确认」;你点「确认完成」才算完成,点「退回清单」就回到清单里。为什么 两条路都要人回答,见第 3 问。

1. 我的数据到底存在哪?卸载会删掉吗?

默认 $DSH_HOME/global-todo/todos.json,可以用插件配置的 storePath 指到任意绝对路径 (lib/store.js 的 resolveStorePath)。同一个目录里还有 settings.json(宿主侧开关)和 client-errors.log(面板错误日志,有上限)。

安装和卸载都不碰这些文件。卸载后手动 rm -r 那个目录才会彻底清掉。

2. 两台机器之间会同步吗?

0.21.0 起会了,但要你自己指定一个碰头目录(插件仍然没有账号、没有服务器):

在每台机器的面板里打开 设置 → 多端同步,把「共享目录」填成同一个绝对路径(Windows 用盘符或 UNC, 例如 Z:\Agent产出\global-todo;「自动同步间隔」填 0 就只在手动同步)。无面板的 headless 部署可以在 cordis.patch.yml 的 config.sync.dir 里给默认值。

每台机器各存一份本地文件,在那个目录里交换一份 todos.hub.json。同步 = 两边都折一次: 按记录合并(同一条看 updatedAt,删除靠墓碑传播,seq 重号会按创建顺序重排),所以顺序、重试、 两台同时同步都不会丢记录。规则与限制见 README 的「两台机器,一份清单」。

  • 读列表永远读本地文件:共享盘挂了、NAS 掉线,清单照常能用,只是 /health.sync 报失败原因。
  • 手动同步:面板/脚本 POST /api/global-todo/sync,或让 Agent 调 global_todo_sync。
  • 不要再把 storePath 指到共享盘上:那是另一种做法(共享同一个文件),每次读都走网络、 断网就打不开,而且它和 sync 混用会互相覆盖。

老办法仍然可用(把 storePath 放在 Syncthing/Dropbox 里),但它没有合并逻辑:两边同时改, 最后落盘的那份赢,另一边丢失;删除也会在对方的下一次写里复活。真正跨机请用 sync。

2b. 配了 sync.dir,另一台机器还是看不到我的改动?

按顺序查(GET /api/global-todo/sync 或 /health.sync 会给答案):

现象(last.error / 状态) 原因
sync-not-configured 那台机器的面板里没填共享目录,或 headless 部署的 config.sync.dir 没写
sync-unavailable 上层目录不存在(共享盘没挂上)。插件故意不替你建这个目录,否则会安静地写进本地空目录
sync-busy 上一次还没跑完(网络盘卡住时常见);等下一轮
sync-timeout 单次文件操作超过 20 秒:挂载点僵死,检查 mount / 重挂
sync-corrupt todos.hub.json 不是合法 JSON,或被别的程序改坏。它不会被覆盖:手工检查/移走后下一轮重建
一切正常但另一台没变 两台看的是不是同一个目录(Windows 盘符映射 vs Linux 挂载点)?那台机器的插件是不是 ≥ 0.21.0?

3. Agent 把一条标成完成之后会发生什么?

记录变成 done,同时带上 review: { pending: true }(lib/model.js 的 completeTodo)。 清单里两处可见:行上的「待确认」徽标,顶部的「待确认」筛选与计数。

你的回答 结果
确认完成 保持已完成,标记清除,动态里记下是谁确认的
退回清单 回到 open;doneAt 和完成记录清空;动态里加一条 reopened

派发出去的会话干净结束时,自动收尾也走同一条规则——自动完成同样是「agent 的声明」,一样要人回答。

4. 已经有 steps 了,为什么不做子任务?

因为子任务就是另一条待办:要有自己的 id、状态、加入时间、附件、派发目标和完成记录。真做出来, 「一份清单」就变成了「一堆互相嵌套的清单」。

steps 明确是一条工作里的计划:扁平、最多 20 步、每步只有 text 和 done,派发时作为编号 计划原样交出去。需要各自派发的,就拆成多条待办——那才是清单该有的粒度。

5. evidence(原话)是什么?为什么有的条目没有?

抓取时逐字引用的那一句用户原话,最多 300 字(lib/model.js 的 LIMITS.evidence)。 global_todo_capture 会要求模型带上,global_todo_add 也收。

面板详情里显示在「原话」下;Markdown 导出里是 原话: 一行。你在面板里手敲的条目没有这一项—— 它只服务于「抓来的东西有没有听错」这件事。

6. 怎么从别的工具导进来?

三个门,按需要选:

入口 形状 行为
JSON 文档 { "version": 2, "todos": [...], "trash": [...] } 面板「更多操作 → 导入」,或 POST /api/global-todo/import;面板用 merge(按记录合并:updatedAt 晚的赢,删除随 trash 传播,旧副本里的已删记录不会复活),dryRun: true 只返回 wouldCreate / wouldUpdate
Markdown - [ ] 标题 任务列表,缩进标注 优先级 / 截止 / 标签 / 原话 / 描述 / 附件 / # 同上,选 .md 文件;按 create 新建,没有 id 所以不会覆盖任何记录
外部写入 POST /api/global-todo/ingest,带 Authorization: Bearer <settings.ingestToken> 来源只接受 mail / notification / announcement;一次最多 100 条;置信度低于 ingestConfirmBelow(默认 0.8)的进收件箱

CSV 没有直接入口:先转成 JSON 或 Markdown。Markdown 解析是容错的——不认识的行忽略,日期解析失败 就丢掉那一项,整份文件里一行任务都没有才会报错。

7. 不用 Agent 也能用吗?

能。面板只依赖宿主的 web server 和那个 JSON 文件:增删改查、标签、优先级、截止、步骤、附件、 筛选、搜索、导出导入、提醒都不需要 Agent。global_todo_* 工具只是可选挂载面。

没有 Agent 参与时用不上的只有四件事:抓取、派发、Agent 的完成声明、会话回读。

8. 哪些功能目前还没有?

目前没有 现状
看板 / 日历视图 现在只有列表,加三种分组(对话 / 时间 / 级别);没有拖拽看板,没有日历
重复任务 dueAt 是单个时间点,还没有 recurrence 字段;同一截止只提醒一次,改了时间才会重新提醒
子任务树 现在只有扁平的 steps,最多 20 条
上传附件 现在只存引用(绝对路径或 URL),不复制字节
多清单 / 项目 现在只有一份全局清单
自动开工 现在没有;它是一份个人清单,不是任务队列
桌面端面板 现在只有 Web 客户端
账号 / 多用户 现在没有;只有一个本机(或受信网络)可访问的 HTTP 面

9. 两个进程同时写这个文件会怎样?

有锁,会排队。 每次写之前,先在文件旁边独占建出 todos.json.lock(open(…, 'wx')),写完删掉:

  • 同一个进程里,人和 Agent 的写本来就走同一条串行链。
  • 另一个宿主进程(Web 面板 + 桌面端 / 命令行会话,或两台机器共用一份同步盘)只能排队。轮到了就继续; 等不到 5 秒就报 store-busy(HTTP 503,工具返回 { ok: false, reason: "store-busy" }), 不会默默把你的改动覆盖掉。
  • 持锁进程崩了也不会把清单锁死:锁文件里记着 pid、host 和一个随机 token。同一台机器上, 只有持有者进程确实不在了才算过期;跨机器没有 pid 可问,按 30 秒超龄接管。接管会写一条 warn 日志; 被接管过的锁,前一个持有者回来也不会误删新的那把。
  • 读者永远不会看到半截文件(rename 是原子的)。清单在别处变过,面板仍然会提示。

有三件事它管不到,说清楚:旧版本插件(不拿锁)、你手改文件、同步盘客户端在任意时刻写入—— 这几种仍然是「后写覆盖先写」。所以把清单放进同步盘时,别让多个客户端同时同步它。

要并行又不想排队?那就各自一份文件,再用导出 / 导入合并。

10. 提醒是怎么工作的?

宿主每 30 秒扫一次(lib/index.js 的 reminder tick):状态是 open / doing、dueAt 已过、 且这个 id → dueAt 还没报过的条目,进 /health 的 reminders.due,面板顶部显示成一条提醒条。

设置 默认 作用
remindersEnabled 开 关掉就不再扫、不再显示
reminderLeadMinutes 0 提前几分钟报;0 = 到点才报

点「知道了」调 POST /api/global-todo/reminders/ack,只从当前进程的提醒列表里移除。 「报过了」的记忆也在内存里,所以重启宿主后,仍然到点且未完成的条目会再报一次。 浏览器通知是可选的:面板里点「开启系统通知」授权后,到点的条目会发一条系统通知。

11. 怎么关掉自动获取(auto-collect)?

先分清三件不同的事:

开关 默认 管什么 怎么关
autoCollect 关 插件自动去问一个安静了 30 分钟的对话「有没有要跟进的事」 面板设置里的「自动获取」开关,或 POST /api/global-todo/settings { autoCollect: false }
guidance 开 往 system prompt 里注入「主动记」的引导 插件配置 guidance: false
对话分组上的「豁免」 无 把某个工作目录整个排除在自动获取之外 再点一次取消

「抓一下待办」/「从本对话抓取」不在此列:那是你手动触发的,永远听你的。

12. 怎么干净卸载?

dsh plugin --profile <profile> remove dsh-global-todo

然后重启宿主、刷新页面,侧栏入口消失。清单和设置都还在原处——这是刻意的。

要彻底清掉(先确认里面的 todos.json 你不要了):

rm -r "$DSH_HOME/global-todo"

更稳的顺序:先导出 JSON 或 Markdown,再删目录。重新装回来后,把导出的 JSON 用「更多操作 → 导入」 就能接着用。

13. 收件箱和「待确认」有什么区别?

收件箱(Inbox) 待确认(Review)
谁产生的 外部写入(/ingest),置信度低于阈值 Agent 的完成声明(工具或自动收尾)
问题是什么 「这条要不要收下」 「这活是不是真做完了」
两个动作 确认(去掉 inbox 标签进清单)/ 丢弃(归档并去掉标签) 确认完成 / 退回清单
不处理会怎样 超过 7 天自动归档(宿主每 6 小时扫一次) 一直挂着,行上一直有「待确认」

14. 派发失败最常见的原因?

原因 表现与处理
没有工作目录 明确报错,因为没有目录的会话里 agent 做不了事;改用「开新对话」,或先选目录
目标对话已归档 选择器里标「(已归档)」;换一个,或新开
宿主没有 agents 服务 agents-unavailable:精简组合里没有能接活的 agent
bound 模式但没绑定 直接告诉你没有绑定会话,并建议改用 auto

失败一定带原因,也记在详情的「最近派发」里;不会静默什么都不做。

15. 桌面端报 Plugin metadata … ENOENT … \locale 是什么?

插件本身已经加载了,这是「显示文字」取不到,不影响面板和工具。宿主读插件页标题/描述的顺序是: 先解析 <包>/locale/en.json(走 exports 里的 ./locale/*.json),解析成功后扫这个目录, 把 zh.json/en.json 逐个读进来。目录不存在,扫描就抛 ENOENT,于是元信息报错。

也就是说:你那份本地插件目录缺 locale/ 文件夹。常见于把仓库文件夹手动复制到 %USERPROFILE%\.dsh\plugins-local\ 时只拷了 lib、package.json、cordis.patch.yml。

先确认到底缺什么,别靠猜:

npx dsh-global-todo-doctor "$HOME/.dsh/plugins-local/全局待办插件"
# Windows: npx dsh-global-todo-doctor "$env:USERPROFILE\.dsh\plugins-local\全局待办插件"

它逐项检查 package.json、patch 文件、两个入口、locale/、图标与 lib/,缺哪样直接点出来, 缺必需项时退出码为 1(可以放进安装脚本里当门禁)。

修法二选一:

  1. 推荐:别用本地目录,直接装 npm 包(包里有 locale/en.json、locale/zh.json):

    dsh plugin add dsh-global-todo
  2. 保留本地目录,把缺的补齐($src 换成仓库或 npm 包里那份):

    $dst = "$env:USERPROFILE\.dsh\plugins-local\全局待办插件"
    $src = "C:\path\to\dsh-global-todo"
    New-Item -ItemType Directory -Force "$dst\locale" | Out-Null
    Copy-Item "$src\locale\*.json" "$dst\locale\" -Force
    Copy-Item "$src\docs\icon.svg" "$dst\docs\" -Force   # 图标同理会报错

    然后重启宿主(插件元信息在启动时读一次)。

为什么会这么脆:exports 的 ./locale/*.json 是通配映射,Node 解析它时不检查文件是否存在, 所以宿主以为文件在、去扫目录,才发现没有。完整安装不会触发;只有手工拷半份才会。

16. 一直报 store-busy 怎么办?

说明有进程正持有 <store>.lock。锁文件里记着 pid、host、at,按顺序看:

  1. host 是本机、pid 还活着:真的在写,正常几毫秒就过去。一直卡住说明那个进程卡死了—— 重启它(或等它退出),下一次写入会按 pid 判死、立刻接管。
  2. host 是本机、pid 已经不在了:下一次写入立刻接管并写一条 warn 日志,不用手动删。
  3. host 是另一台机器:没有 pid 可问,按 30 秒超龄接管,最多等半分钟。两台机器时钟差得多时 先校准时钟,否则判断会偏。
  4. 确认没有第二个宿主在用同一个 storePath(Web 面板 + 桌面端 / 命令行会话,或同步盘两端)—— 这是唯一会把「排队」变成「一直排队」的情况。
  5. 兜底:确认没有任何进程在写之后,直接删掉那个 .lock 文件。它是缓存,不是数据,删了不会丢条目。

17. 装了记忆库插件(dsh-mnemon),两边会不会记重复?

会,而且这是最常见的浪费。插件在检测到 mnemonMemory 服务时(也就是记忆插件真的装着)会多注入一段分工:

  • 要跟进的动作用待办(global_todo_*);已经知道的事实用记忆(mnemon_remember)。同一件事只写一边。
  • 待办标完成时,工具结果里会多一句「结论值得以后想起来就 mnemon_remember 一条,正文带上待办 id」, 所以「完成了」和「记住了」不是两套记录,而是一条线索。
  • 从记忆里看到「还有件事要办」→ 用 global_todo_add 记成待办;记忆里的条目不会被画掉。

不装记忆插件时这段和那句都不出现:模型不会被引导去调一个不存在的工具。

想更深一层(让记忆检索直接召回待办)需要另写一个 dsh-mnemon-source-global-todo(用它的 Source SDK), 那是第二个包、带 peer 依赖,本仓库故意不做——这个插件必须能单独工作。

18. Agent 记的条目为什么跑进了「收件箱」,而且一天只有 8 条进清单?

0.22.0 起,Agent 写进清单要过一道门(阈值由数据定,见 README 的「自动记录的门槛」):

情形 结果
没有截止时间(dueAt 为空) 进「收件箱」,等你点「收下」或「丢弃」
有截止时间,但今天已经进了 8 条 Agent 记录 进收件箱,原因写 quota(不丢,只是不在清单里)
有截止时间、额度还有 直接进清单
面板里你自己敲的 永远直接进清单
升级到 0.22 那一刻 做一次清理:没有截止时间、且你从没动过的 Agent 记录移进收件箱(本机回放:68 条),之后再按新规则走

顺带两件事也变了:

  • 级别按截止时间算:没有日期 = P3、7 天内 = P2、48 小时内 = P1、已逾期 = P0。你在面板上改过一次级别,这条就锁成你的(prioritySource: human),规则不再覆盖;Agent 当时想给的级别留在 suggestedPriority 里。
  • 同一轮里 Agent 已经自己记过,就不再触发自动获取的提问——它已经把要说的写下来了,再问一次只会多出没人要的条目。

收件箱里的记录不算进「全部 / 未完成」的计数,所以那两个数字现在就是清单本身。想把它放回清单,就「收下」;想彻底不要,就「丢弃」(归档,不删)。