启动或恢复一个模块的开发工作流——在项目根目录的 `OpenLog/` 下浏览模块清单、快速接手某个已有模块的最新进度,或为一个新模块搭建文档骨架(架构 / 开发日志 / 当前阶段)。任务收尾时自动维护这三个文档,以便下一次会话 / 下一个 agent 能用最少 token 接手。 触发条件:用户输入 `/openlog`,或在大型项目里说"开始开发 X 模块"、"接手 X 模块"、"现在做哪个模块"、"模块开发起步"、"写一下这个模块的开发日志"等模块级开发起步 / 收尾动作。
Resources
4Install
npx skillscat add aodusk-future/openlog-skill Install via the SkillsCat registry.
OpenLog —— 模块化开发工作流
OpenLog 是一个轻量的"模块开发档案"机制。它把每个模块的架构说明、开发轨迹、当前断点沉淀到 OpenLog/<Module>/ 下的三个固定文件里,让接手者(人或 agent)能在 1k token 以内重建上下文。
核心目标:稳定、可复读、低 token。
数据布局(项目根目录)
OpenLog/
├── INDEX.md # 模块清单 + 跨模块协作约定(极简表格)
├── CONVENTIONS.md # 可选:工程横切规范(asmdef / 测试样板 / 命名约定等项目专属做法)
├── <ModuleA>/
│ ├── ARCHITECTURE.md # 模块架构(结构化、保持最新;契约所有者声明)
│ ├── DEV_LOG.md # 开发日志(倒序,最新在最上)—— 已完成动作的历史
│ ├── DEV_LOG.archive/ # 自动归档(仅在 DEV_LOG > 500 行时出现)
│ │ └── YYYY-MM.md
│ ├── CURRENT.md # 当前阶段断点(< 30 行;含「外部需求 (inbox)」)—— 长期阶段总览
│ └── HANDOFF.md # 可选,一次性:会话末「现场快照」(未完成 / 验证状态 / 待审核)
└── <ModuleB>/...语义分工(不要混淆):
- 三类时间视角:DEV_LOG = 历史(持久累计) / CURRENT = 长期阶段(持续) / HANDOFF = 会话末现场(一次性,接手后删)
- 两套约定:INDEX 顶部「跨模块协作约定」管模块间契约 / CONVENTIONS 管模块内技术做法(可选)
OpenLog/ 跟随项目 git 仓库提交,团队 / 多 worktree / 不同 agent 共享同一份档案。
启动阶段(最省 token 的入口)
按顺序执行:
步骤 1:确保 OpenLog/INDEX.md 存在
若项目根目录没有
OpenLog/,创建之若没有
INDEX.md,写入下面这个空模板:# OpenLog 模块索引 > 工程约定(横切规范)见 [CONVENTIONS.md](CONVENTIONS.md)(可选,不存在则忽略此行)。 ## 跨模块协作约定 1. 边界 = 一个具体命名的契约(接口 / 数据形态);依赖契约,不依赖内部实现。 2. 更基础(被依赖)的模块为契约所有者,负责统一、尽量只增不改;下游写适配层、只提需求。 3. 契约写在所有者的 ARCHITECTURE→关键接口,消费方在「依赖」里引用;发现对不齐先在本模块记 TODO,到所有者对话再改契约。 4. 跨模块提需求:可向所有者 CURRENT 的「外部需求 (inbox)」追加(带日期 + 源模块),但**不得修改对方的契约/决策**——契约只由所有者 triage 后落入其 ARCHITECTURE。 | 模块 | 一句话定位 | 状态 | |------|----------|------|这套"跨模块协作约定"是 skill 默认元规则,所有项目通用。不要删它,除非用户明确要求用别的协作模型。
步骤 2:Read OpenLog/INDEX.md(一次性、完整)
把模块清单的全部条目 + 顶部的「跨模块协作约定」记入上下文。这是这一阶段唯一允许的"全量读"。
条件读 CONVENTIONS.md:仅在 INDEX 顶部有该指针、且任务涉及"新建底层子模块 / 跨模块契约调整 / 用户明确按工程约定"时才完整读;否则跳过。
步骤 3:尝试模块名模糊匹配(优先级高于询问)
如果用户本次唤起 skill 时已经提到了模块名或描述(如"开发战斗模块"、"接手 X 的配置"),先做匹配:
- 对 INDEX 中的「模块名」+「一句话定位」两列做关键词模糊匹配(包含子串、忽略大小写、支持中英对照)
- 命中恰好 1 个 → 直接进入分支 A,跳过询问,但在接手摘要前加一句确认:"(已自动匹配模块
<Module>)" - 命中 2+ 个 → 用 AskUserQuestion 让用户在候选中选(候选 ≤ 4 时用 AskUserQuestion;> 4 时走步骤 4 的文本列表方式)
- 命中 0 个 → 进入步骤 4
如果用户唤起时没有提任何模块线索(如纯 /openlog),直接跳到步骤 4。
步骤 4:让用户挑选模块
根据模块数量选择交互方式:
模块数 ≤ 3(即 + "+ 新建模块" 后总选项 ≤ 4) → 用
AskUserQuestion模块数 ≥ 4 → 不能用 AskUserQuestion(它最多 4 项)。改为直接输出 INDEX 表格给用户,并在最后写一行提示:
请回复模块名(任意一列子串都行),或回复
新建来创建新模块。等待用户文本回复,再做一次模糊匹配。匹配规则同步骤 3。
步骤 5:根据用户选择分支处理
分支 A:接手某个已有模块
按下面这个严格顺序读取文件,不要并行、不要全文:
- 先检查
OpenLog/<Module>/HANDOFF.md是否存在(用 Bashtest -f)- 存在 → 完整读它(通常 < 30 行)。这是上一次会话刚停下来的现场,比 CURRENT 还新,优先级最高
- 不存在 → 跳过,走标准接手
Read OpenLog/<Module>/ARCHITECTURE.md(完整读,通常 1-2KB)Read OpenLog/<Module>/DEV_LOG.md,只读前 40 行(用 Read 的limit: 40参数)——这覆盖最近 ~5 条日志Read OpenLog/<Module>/CURRENT.md(完整读,固定 < 30 行)
架构漂移检查(轻量、可选):
用 Bash
stat -f "%m" OpenLog/<Module>/ARCHITECTURE.md(macOS)或stat -c %Y ...(Linux)拿到 ARCHITECTURE 的 mtime如果距今 > 30 天,且步骤 2-3 中读到的 DEV_LOG 头部能数出至少 5 条新于 ARCHITECTURE 的日志条目(按日志条目时间戳与 mtime 对比),在接手摘要末尾追加一句:
⚠️ ARCHITECTURE 已 N 天未更新,期间有 M 条日志,建议复核架构文档。
不强制更新,只提示。
随后向用户输出接手摘要,结构如下(HANDOFF 存在时多一段):
模块定位:<一句话>
最近进展:<最近 1-2 条日志的合并陈述>
当前断点 / 下一步:<CURRENT.md 中"进行中"+"下一步"的合并陈述>
[⚠️ 漂移提示,可选]🔴 上轮交接单(YYYY-MM-DD,留于 HANDOFF.md)—— 仅在文件存在时输出此段:
- 本轮目标:<HANDOFF 的「本轮目标」原文>
- 未完成:N 项(<逐项列举,简短>)
- 待审核:M 项(<逐项列举,简短>)
- 验证状态:<一句话总结>
关闭 handoff:任何收尾指令("做完了" / "完成了" /
/openlog 收尾等)都会触发收尾步骤 0 主动问您"是否一并关闭 handoff",您不必记特定口令。
然后按用户指令干活。重要:用户跳过 handoff 做别的事时,不要主动删 HANDOFF.md——下一次收尾的步骤 0 会处理。
分支 B:新建模块
- 用
AskUserQuestion一次性收集:- 模块名(kebab-case 或 PascalCase 均可,与项目代码风格对齐)
- 一句话功能定位
- 创建
OpenLog/<Module>/目录 - 在该目录下创建三个文件,使用下方"文件模板"小节的内容填入
- 在
OpenLog/INDEX.md表格末尾追加一行:| <Module> | <一句话定位> | 🟢 active | - 输出一句确认:"模块
<Module>已建档,现在可以开始开发。",然后等待用户下一条指令
分支 C:变更模块状态(暂停 / 完成 / 重启)
如果用户的唤起短语属于状态变更类("X 模块暂停"、"X 模块完成了"、"归档 X"、"重启 X"),不读模块文档,直接:
- 在 INDEX.md 中找到该模块对应行,更新「状态」列:
- 暂停 → 🟡 paused
- 完成 → ✅ done
- 重启 / 恢复 → 🟢 active
- 若变更为 ✅ done,可选地把 CURRENT.md 改写成"最终交付摘要"(5-10 行)
- 在 DEV_LOG.md 顶部追加一条状态变更记录
- 输出确认即可,不进入开发流程
分支 D:留交接单(创建 / 覆盖 HANDOFF.md)
触发口令(必须用户显式提出,不要主动催生):
- "留个交接" / "留交接" / "留 handoff"
- "写个交接单" / "写个 handoff"
- "下次接手要注意..." / "给下一个 agent 留个..."
- 用户输入
/openlog handoff
执行步骤:
- 用
AskUserQuestion或单次对话采集 6 个字段(如果信息已经在本轮对话上下文里,直接整理,不必再问):- 本轮目标(一句话)
- 已改文件(列表,每条 = path + 一句话改动)
- 关键实现(决策点,2-5 条)
- 验证状态(已跑 / 未跑 / 已知失败)
- 未完成(带
[ ]的复选框列表) - 需要重点审核(让下一个接手者注意的疑问点)
- 用下方"HANDOFF.md 模板"写入
OpenLog/<Module>/HANDOFF.md(覆盖已有的——一个模块同时只能有一份 handoff;旧的没关闭就被覆盖意味着旧 handoff 被作废,你需要提醒用户"上轮 HANDOFF 未关闭就被覆盖,旧内容会丢失,确认吗?") - 同时走标准收尾流程(DEV_LOG 追加 + CURRENT 更新)——handoff 不替代收尾,而是补充
- 输出确认:"交接单已写入 HANDOFF.md。下次任何 agent 接手
<Module>时会优先读它。"
分支 E:关闭交接单(删除 HANDOFF.md + 吸收信息)
触发口令:
- "handoff 处理完了" / "交接单处理完了" / "现场清完了"
- "handoff 关掉" / "把交接单删了"
- "那些 handoff 项都解决了"
- 用户输入
/openlog handoff close
执行步骤:
- 读
OpenLog/<Module>/HANDOFF.md(如果不存在,告知用户"当前模块没有未关闭的 handoff",结束) - 吸收关键信息——逐项判断 handoff 里的内容应该沉淀到哪:
- 未完成项中已完成的 → 追加到 DEV_LOG 的当条记录关联字段(或新追加一条 DEV_LOG)
- 未完成项中仍未完成的 → 移入 CURRENT 的「进行中」或「下一步」
- 待审核项中已审核通过 + 落地为接口/契约变更的 → 写入 ARCHITECTURE「关键接口」
- 待审核项中决定不变更的 → 在 DEV_LOG 当条记录里写一句"审核结论:不变更,原因 <...>"
- 验证状态里 ❌ 已知失败仍未修 → 写入 CURRENT「已知问题 / TODO」
- 删除 HANDOFF.md 文件
- 输出确认:"handoff 已关闭,N 项已沉淀进 DEV_LOG / CURRENT / ARCHITECTURE。"
重要:删除前你必须完成第 2 步的吸收——直接删等于丢信息。如果某些信息不知道往哪放,先问用户,不要擅自决定。
收尾阶段(任务完成后维护文档)
触发判定(重要:避免过度触发)
只有用户的指令属于下列情形之一,才执行收尾:
- 用户显式说:"做完了" / "完成了" / "搞定了" / "ok 了" / "差不多了"
- 用户显式说:"收一下" / "收尾" / "归档一下" / "记一下"
- 用户显式说:"下一个任务" / "切下一个" / "换模块"
- 用户显式说:"提交一下" / "commit 一下" / "更新一下日志"
- 用户输入
/openlog 收尾或/openlog commit
禁止仅凭"产生了文件改动"或"看起来一段工作完成了"就触发收尾。收尾必须由用户的语言信号确认,否则你会污染日志。
收尾步骤
按顺序执行:
0. 前置检查:HANDOFF.md(必做,先于其它步骤)
test -f OpenLog/<Module>/HANDOFF.md:
- 不存在 → 跳过,进入步骤 1
- 存在 → 询问用户:"检测到未关闭的 HANDOFF.md,本次收尾是否一并关闭它?"
- 是 → 先完整执行分支 E(读 → 吸收信息 → 删除),再继续步骤 1-5;若步骤 1-3 的本次变更与 handoff 吸收内容重叠,合并写入避免重复
- 否 → 继续步骤 1-5,但在末尾追加
⚠️ HANDOFF.md 仍未关闭,记得回头处理
为何必有此步:"做完了"/"完成了"是最自然的收尾表达,但用户可能也指 handoff 完了——必须主动问,不能让 handoff 被悄悄遗忘。
1. 追加 DEV_LOG.md 一条(必做)
在文件最上方(标题 # <Module> 开发日志 之后)插入一条,格式:
## YYYY-MM-DD HH:MM — <一句话改动摘要>
- <关键改动 1>
- 修改:`<path/to/file>:<line>`(多文件分多行)
- 关联:CURRENT 中 "<某项>" 已解决 / 新增阻塞 "<X>"时间用本地时间(可用 date "+%Y-%m-%d %H:%M")。摘要保持 ≤ 60 字。
追加前检查并发风险:如果项目使用 git 且有远端协作,提醒用户:"多 worktree / 多 agent 协作时,写入前请先 git pull --rebase 同步 OpenLog/,避免冲突。" 不要自动 pull,让用户决定。
2. 更新 CURRENT.md(必做)
- 把"进行中"里完成的项移到"已完成"或直接删除(保持已完成 ≤ 5 条)
- 如果出现新阻塞,写入"已知问题 / TODO"
- 更新顶部"最后更新"时间戳
- 保持总长 < 30 行,超出就把陈旧"已完成"条目下沉到 DEV_LOG 的"关联"字段或直接删掉
3. 更新 ARCHITECTURE.md(仅在结构变化时)
只有当本次任务发生下列任意一种结构变化时才修改:
- 新增 / 删除 / 重命名 公开接口(方法、组件、事件)—— 这些进「关键接口」一节
- 新增 / 删除 / 重命名 模块依赖(上游或下游)
- 新增 / 删除 / 重命名 关键文件
- 落地了一条值得记录的设计决策("为什么这么做",1-3 行即可)
纯实现细节的改动不要污染 ARCHITECTURE。 这是省 token 的关键规则。
契约 inbox triage:如果本次任务期间,本模块 CURRENT 的「外部需求 (inbox)」里有新增请求被你接受了,把它转写为关键接口(写进 ARCHITECTURE)并从 inbox 删除;拒绝的写明理由后删除;延后的移入「已知问题 / TODO」。不要让 inbox 长期积压。
3.5. 追加新横切规范到 CONVENTIONS.md(仅在你确实总结出了一条可复用的工程约定时)
触发条件(必须同时满足):
- 本次任务里你和用户反复对照过的一个项目专属做法(如 asmdef 配置 / 测试框架样板 / 命名规范 / 目录结构)
- 这条做法未来会在其它模块继续套用(不只本模块一次性)
- 用户显式确认要沉淀("把这个规则记下来" / "以后都这么做")
满足时:
- 如果
OpenLog/CONVENTIONS.md不存在,用文件模板小节里的格式创建,并在OpenLog/INDEX.md顶部加一行指针:> 工程约定(横切规范)见 [CONVENTIONS.md](CONVENTIONS.md)。 - 在 CONVENTIONS.md 末尾追加一条新约定(C1 / C2 / ... 递增编号),包含:何时套用 / 不套用 / 模板 / 已套用清单。
- 在 DEV_LOG 当条记录里关联一句:"(沉淀为 CONVENTIONS C)"。
不要主动催生这一步——大多数收尾不涉及横切规范,跳过即可。
4. 检查 DEV_LOG 归档(仅在文件过长时)
收尾写完后,检查 DEV_LOG.md 总行数:
wc -l OpenLog/<Module>/DEV_LOG.md如果 > 500 行,执行归档:
- 创建目录
OpenLog/<Module>/DEV_LOG.archive/(如未存在) - 找到所有 > 90 天(按条目时间戳)的条目
- 把这些条目按月份切分,追加到
DEV_LOG.archive/YYYY-MM.md(若文件已存在则合并、按时间倒序保持) - 从 DEV_LOG.md 主文件中删除这些已归档的条目
- 在 DEV_LOG.md 末尾保留一行:
> 更早的日志见 [DEV_LOG.archive/](DEV_LOG.archive/)
归档不需要每次收尾都做,可以每 N 次(比如 10 次)收尾再检查一次行数。
5. 不更新 INDEX.md,除非模块状态变化
- 模块进入暂停 → 🟡 paused(由用户在分支 C 触发)
- 模块完成 → ✅ done(由用户在分支 C 触发)
- 否则不动
文件模板(新建模块时复制使用)
ARCHITECTURE.md
# <Module> 架构
## 功能定位
(2-3 行:这个模块解决什么问题,在系统中处于什么位置)
## 关键接口(本模块作为契约所有者对外发布)
- `<Interface>.<Method>(...)` — `<path/to/file>:<line>` — 一句话职责
- ...
## 依赖
- 上游:<上游模块列表>(消费它们 ARCHITECTURE→关键接口 的契约)
- 下游:<下游模块列表>(消费本模块的关键接口)
## 文件清单
- `<path/to/file>` — 一句话职责
- ...
## 设计决策
(按需追加,每条 1-3 行,记 "why" 不记 "what")「关键接口」即契约所有者声明:放在这里的接口对所有下游模块开放,所有者负责"尽量只增不改";下游想要新接口 → 在所有者的 CURRENT「外部需求 (inbox)」追加请求,等所有者 triage,不得直接改这一节。
DEV_LOG.md
# <Module> 开发日志
(最新条目在最上方。每条 3-5 行。)CURRENT.md
# <Module> 当前阶段
**最后更新**:YYYY-MM-DD HH:MM
**阶段目标**:<本阶段要达成的目标,一句话>
## 已完成
- <已交付的关键点>
## 进行中
- <正在做的事,必要时用括号标注卡点>
## 下一步
1. <下一动作>
2. <下一动作>
## 外部需求 (inbox)
- YYYY-MM-DD [<来源模块>] <需求描述>
(消费方追加,本模块作为契约所有者 triage 后:接受 → 落入 ARCHITECTURE 的「关键接口」并删除此条;拒绝 → 写明拒绝理由后删除;延后 → 移入「已知问题 / TODO」)
## 已知问题 / TODO
- [ ] <待办>HANDOFF.md(可选,一次性,由分支 D 创建,分支 E 删除)
# <Module> 本轮交接 (handoff)
**留于** YYYY-MM-DD HH:MM
**留交接者**: <可选,标注 agent 名 / 用户名,便于追溯>
## 本轮目标
<一句话,这次会话想达成的事>
## 已改文件
- `<path/to/file>` — <一句话改动>
- ...
## 关键实现
- <决策点 1,1-2 行>
- <决策点 2,1-2 行>
## 验证状态
- ✅ 已跑:<测试名 / 描述>(通过)
- ⏳ 未跑:<未跑的测试 / Play Mode 目视等>
- ❌ 已知失败:<如有,描述失败现象;无则写「无」>
## 未完成
- [ ] <未完成项 1>
- [ ] <未完成项 2>
## 需要重点审核
- <让接手者注意的疑问点 1,1-2 行>
- <让接手者注意的疑问点 2,1-2 行>HANDOFF 纪律:一次性(一模块最多一份,新写覆盖旧、先警告);整篇 < 30 行,需大段说明则放 ARCHITECTURE「设计决策」并在 handoff 里引用。
CONVENTIONS.md(可选,仅在项目需要沉淀横切技术约定时创建)
# OpenLog 工程约定(横切规范)
> 跨模块通用的工程做法(区别于 INDEX 里管模块间契约的协作约定)。按需查阅,新约定追加于此,INDEX 顶部留一行指针即可。
---
## C1. <约定名,如:模块 asmdef + 单元测试样板>
**立于** YYYY-MM-DD,源自 `<首例落地的子模块路径>`。
### 何时套用
<触发场景,1-3 行>
### 不套用 / 暂缓
<反例 / 成本过高的场景,1-3 行>
### 模板 / 步骤 / 关键纪律
(具体内容,可以含代码 / 配置片段 / 命令)
### 已套用清单
- `<模块路径>` — YYYY-MM-DD
- ...每条约定一个 H2 编号(C1 / C2 / ...)。约定的具体内容是项目专属的(语言 / 引擎 / 工具链都由项目自定),模板只规范外壳结构。
严禁的行为(写下来是为了不要忘)
读取边界:
- ❌ 不要复读整篇 DEV_LOG(前 40 行是设计边界);不要 grep 代码重提结构(ARCHITECTURE 是真相源,过时先更新它)
- ❌ 不要把临时讨论 / 技术栈废话(Unity / React / asmdef 模板等项目专属约定)塞进 ARCHITECTURE 或 skill 本体——前者污染架构,后者污染分发;项目专属约定放
CONVENTIONS.md
写入边界:
- ❌ 不要主动触发收尾或主动创建 HANDOFF——都必须用户显式口令;同理不得修改他人模块的契约(只能在对方 inbox 追加请求)
- ❌ CURRENT 不超过 30 行;inbox 不超 5 条未 triage;任何文档不写代码 diff 全文(用
path:line引用)
HANDOFF 纪律:
- ❌ HANDOFF 是一次性现场,过去的必须被关闭(删除);不吸收信息就删 = 丢失(分支 E 步骤 2 必须先于步骤 3)
一次完整调用的预期 token 消耗
| 操作 | 基线 | 增量(条件触发时叠加) |
|---|---|---|
| 接手已有模块 | 700-1000 | +150-400(有 HANDOFF)/ +200-600(条件读 CONVENTIONS) |
| 新建模块 | 300 | — |
| 状态变更 | 100 | — |
| 标准收尾 | 150-400 | +50-150(处理 inbox)/ +300-500(追加 CONVENTIONS,罕见) |
| 留 / 关闭 handoff | 200-500 | — |
| 归档(罕见) | 500 | — |
如果某次实际消耗远超上述预算,停下来检查是不是违反了"严禁的行为"。