Skill: liuboyang025-sketch/openclaw-project-context-manager (version 1.0.0)

--- name: project-context-manager description: 用统一规则管理长期项目的发现、进入、退出、恢复与阶段性固化。 metadata: { "openclaw": { "emoji": "🗂️", "requires": { "bins": ["python3"] } } } --- # Project Context Manager 当用户在一个共享主会话中同时推进**多个长期项目**，并希望可靠地做到以下事情时，使用这个 skill： - 防止项目上下文与普通对话混在一起 - 在会话丢失、归档或中断后恢复项目状态 - 为项目建立统一的文件结构 - 通过文件化记录而不是聊天记忆来保存项目进度 这个 skill 是**项目无关的通用机制**，不得假设或写死任何具体项目。 ## 重要边界 这个 skill 管理的是**项目上下文**，不是 OpenClaw 原生 UI 层面的多会话切换。 它不应假装把共享主会话变成一个真正隔离的原生项目会话。它提供的是一套基于文件的项目发现、进入、恢复、退出边界与阶段性固化工作流。 ## 核心理念 不要依赖聊天记忆来管理长期项目。 应依赖： 1. **workspace 级项目系统规则文件** 2. **统一项目根目录**（每个项目一个文件夹） 3. **项目级恢复入口与结构化进度文件** 4. 明确的 **进入 / 退出 / 恢复 / 固化** 协议 ## 这个 skill 管什么 这个 skill 定义一套标准工作流，用于： - 在统一项目根目录下发现项目 - 当用户说“进入项目 / 恢复项目”时，让用户先确认目标项目 - 只有在用户确认后才进入对应项目 - 通过恢复入口、索引、决策、checkpoint 与记忆恢复项目上下文 - 退出项目后，防止普通聊天被写入项目记录 - 在关键节点把当前项目状态固化为可恢复记录 ## 标准架构 ### workspace 级规则层 一个 workspace 级规则文件（推荐文件名：`PROJECT_SYSTEM.md`）定义： - 项目放在哪 - 如何发现项目 - 如何进入、退出和恢复项目 - 如何进行阶段性固化 - 项目工作与普通事务的边界规则 ### 项目级结构层 每个项目应位于独立文件夹中，并至少包含： - `00_恢复入口.md` - `00_文档总索引与当前进度.md` - `01_项目会话与恢复机制说明.md` - `99_关键决策记录.md` - `checkpoints/` - `session-backups/` ## 当用户说“进入项目 / 恢复项目”时的要求 除非用户已经非常明确指出目标项目，否则不要猜测他要进入哪个项目。 正确流程应为： 1. 优先读取 workspace 级项目系统规则文件 2. 优先读取项目注册表（若存在） 3. 优先扫描已登记项目路径；若采用统一项目根目录模式，再扫描该根目录 4. 列出可识别项目 5. 若存在歧义，让用户选择 6. 用户确认后，再读取该项目的恢复入口并恢复上下文 补充原则： - 不应只依赖默认目录猜测项目 - 不应假设所有项目都位于同一个固定目录 - 单个项目里的 `00_恢复入口.md` 只能解决“已知项目后的恢复”，不能替代“发现有哪些项目”的能力 ## 当用户说“退出项目”时的要求 当用户明确退出项目后： - 后续消息不再默认属于该项目 - 不应把普通事务自动写入项目恢复文件 - 若后续消息看起来像项目相关，应提醒用户并确认是否重新进入项目 ## 项目恢复工作流 选定具体项目后，应使用该项目自己的文件恢复： 1. `00_恢复入口.md` 2. `00_文档总索引与当前进度.md` 3. `99_关键决策记录.md` 4. 由索引或恢复入口指向的当前断点文件 5. 最新相关 checkpoint 文件 6. 必要时读取最近相关 workspace memory 恢复后应至少还原： - 当前项目主线 - 已完成内容 - 当前断点 - 最近新增的重要文件 - 关键决策 - 推荐下一步 ## 项目固化工作流 用户可通过以下表达显式触发固化： - 固化当前项目 - 更新恢复文件并保存当前断点 - 保存当前阶段进展 当用户明确下达固化指令时，应立即执行。 在重要节点，应主动提醒用户是否需要固化，例如： - 完成关键文档后 - 当前断点明显变化后 - 新决策形成后 - 新增强相关文件后 - 进入新阶段时 - 会话可能暂停或中断前 固化保存的是**可恢复的有效上下文**，而不是默认保存全部原始聊天原文。 通常需要更新： - 项目索引 / 当前进度文件 - 关键决策文件（若决策发生变化） - 当日 workspace memory（如有需要） - checkpoint 快照文件（推荐在关键阶段生成） ## 项目创建与接管机制 ### 1. 已有项目目录时的接管 当用户明确说明以下任一情况时，应视为“已有项目目录待接管”： - 已经建好了项目文件夹 - 这个目录就是新项目 - 以这个目录作为项目继续推进 - 帮我给这个目录补齐项目恢复结构 此时应： 1. 确认用户提供的项目路径 2. 检查该目录是否已有项目结构文件 3. 若缺失结构，则提示是否初始化标准项目结构 4. 若已有部分结构，则提示是否补齐并接管 5. 接管完成后，再将该目录纳入项目恢复与固化机制 6. 将该项目路径登记到独立的项目注册表中，而不是写死在 skill 本体里 ### 2. 未建项目目录时的新项目初始化 当用户明确表示要开展一个长期项目，但尚未建立项目目录时，应： 1. 识别这是“长期项目启动”，而不是普通一次性任务 2. 提示用户是否需要建立标准项目目录与恢复结构 3. 若用户同意： - 让用户提供路径 - 或使用统一项目根目录创建新项目文件夹 4. 初始化标准项目结构 5. 再进入该项目的恢复与管理流程 ### 3. 仅想逻辑分开、不想立刻建目录时 当用户只想把对话逻辑上与其他事务分开，但尚未准备建立正式项目目录时： 1. 可以先按“项目方式”继续讨论 2. 但应提醒用户：当前只是逻辑分开；若希望后续稳定恢复，仍建议尽早建立项目目录与恢复结构 3. 在未正式建立项目目录前，不应假装该项目已经具备完整恢复能力 ### 4. 项目目录确认与恢复前发现机制 为了避免会话中断后只能恢复“已知路径的单个项目”，当前版本增加如下要求： 1. **首次纳入项目管理时，应确认项目路径** - 若用户已给出路径，直接登记 - 若用户未给出路径，可在合适时机提示补充 2. **项目路径不应写死在 `SKILL.md` 本体中** - skill 负责规则 - 具体项目路径应登记在独立的项目注册表中 - 当前版本可采用轻量注册表：`~/.openclaw/workspace/projects-registry.json` 3. **当用户说“恢复项目 / 进入项目 / 回到项目”时** - 若当前没有明确激活的项目上下文，应先读取项目注册表 - 当前版本可优先读取：`~/.openclaw/workspace/projects-registry.json` - 再扫描所有已登记项目路径 - 检查路径是否存在、恢复文件是否完整 - 列出当前可识别项目 - 让用户选择进入哪个项目 - 用户确认后，再读取对应项目的 `00_恢复入口.md` 4. **目录确认应采用条件触发，不高频打扰** - 首次纳入项目时可确认目录 - 恢复失败、路径失效、无法形成候选项目列表时可提示补目录 - 路径已确认有效时，不应反复提醒 5. **注册表只记录已确认项目** - 项目注册表用于记录“已被用户确认纳入 skill 管理的项目” - 不应把 assistant 仅凭猜测发现的目录写入注册表 - 不应把普通聊天中偶然提到的话题自动写入注册表 6. **单次提醒原则** - 对同一项目的目录确认问题，默认只提醒一次 - 只有在用户再次要求恢复、路径再次失效、或目录状态发生变化时，才适合再次提醒 ## 提示触发规则 ### 强触发：应主动进入项目创建 / 接管流程 当用户明确表达以下意图时，应主动触发项目创建或接管提示： - 开始一个新项目 - 这是一个长期项目 - 以后要持续推进这个事情 - 给这个任务建立项目管理 - 这个项目需要后续继续跟进 - 我已经建好了项目目录 / 文件夹 ### 中触发：可提示一次 当用户没有明确说“新项目”，但已经表现出明显的长期项目特征时，可以提示一次是否需要进入项目机制。 长期项目特征可包括： - 需要分阶段推进 - 需要持续写文档 - 需要记录断点 - 需要 checkpoint / 恢复 - 需要后续多轮协作 - 需要在普通事务之外单独管理 ### 弱触发：不提示 以下情况不应主动提示建立项目： - 一次性问答 - 临时报错排查 - 短任务脚本 - 单次资料查询 - 普通闲聊 - 用户没有表现出长期推进或恢复需求 即：新话题 ≠ 新项目。 ## 反打扰规则 - 不应因每个新话题都建议建项目 - 同一主题内，默认只提醒一次 - 如果用户已经拒绝，则不应在短时间内重复催促 - 只有再次出现明确的长期项目信号时，才适合重新提醒 - assistant 不应擅自创建项目目录，除非用户明确同意 ## 初始化一个新项目结构 本 skill 提供一个初始化脚本，用于生成标准项目结构。 使用方式： ```bash python3 {baseDir}/scripts/init_project.py '<JSON>' ``` 示例： ```bash python3 {baseDir}/scripts/init_project.py '{ "projects_root": "/Users/example/Desktop/项目库", "project_name": "示例项目", "create_workspace_rule": true }' ``` ## 脚本输入参数 ```json { "projects_root": "string, required", "project_name": "string, required", "create_workspace_rule": true, "workspace_root": "string, optional, defaults to ~/.openclaw/workspace", "project_rule_filename": "string, optional, defaults to PROJECT_SYSTEM.md" } ``` ## 初始化会创建什么 - workspace 级 `PROJECT_SYSTEM.md`（如果请求创建且当前不存在） - 项目根目录下的项目文件夹 - 该项目的标准恢复与管理文件 - `checkpoints/` 与 `session-backups/` 目录 ## 边界规则 - 这个 skill 管理的是**项目上下文**，不是原生 UI 会话切换 - 不应假装 WebChat 或 main 会话已经变成真正的多会话隔离环境 - 不应假设某个具体项目 - 用户退出项目后，不应把普通聊天写入项目记录 - 恢复时不能只依赖固定历史文件名，必须先扫描项目目录 ## 第一版范围 第一版重点支持： - 标准化的项目发现 - 项目进入 / 退出 / 恢复 / 固化规则 - 新项目标准模板生成 第一版不提供： - OpenClaw 原生多会话 UI 支持 - 隐式后台项目自动切换 - 通道级 thread binding

path: PUBLISH_CHECKLIST.md
content: # 发布文件清单（建议）

## 建议保留

### 核心文件
- `SKILL.md`
- `README.md`
- `scripts/init_project.py`
- `templates/` 目录全部内容

### 补充文档
- `docs/初始化与测试说明.md`
- `docs/项目注册表维护说明.md`
- `docs/发布说明与用户使用指南.md`

## 不建议作为主发布内容

这些更偏内部研发资料：

- `00_恢复入口.md`
- `00_文档总索引与当前进度.md`
- `01_skill定位与使用机制说明.md`
- `02_项目创建与接管机制说明.md`
- `99_关键决策记录.md`
- `checkpoints/`
- `session-backups/`

## 推荐最终发布目录结构

```text
project-context-manager/
├─ SKILL.md
├─ README.md
├─ scripts/
│  └─ init_project.py
├─ templates/
│  ├─ PROJECT_SYSTEM.md
│  ├─ 00_恢复入口.md
│  ├─ 00_文档总索引与当前进度.md
│  ├─ 01_项目会话与恢复机制说明.md
│  ├─ 99_关键决策记录.md
│  ├─ checkpoints/README.md
│  └─ session-backups/README.md
└─ docs/
   ├─ 初始化与测试说明.md
   ├─ 项目注册表维护说明.md
   └─ 发布说明与用户使用指南.md
```

## 发布前检查

- [ ] 没有个人真实路径
- [ ] 没有个人真实项目名
- [ ] 没有个人账号/用户名
- [ ] README 可独立读懂
- [ ] SKILL.md 与 README 描述一致
- [ ] 模板完整
- [ ] 脚本可运行
- [ ] docs 中的示例为通用示例


path: README.md
content: # project-context-manager

一个用于 **长期项目上下文管理** 的 OpenClaw skill。

它解决的不是单轮问答，而是下面这类长期协作问题：

- 同一个主会话里同时推进多个项目
- 会话中断后，需要恢复某个项目的当前断点
- 需要把“项目工作”和“普通聊天”分开
- 需要把关键进展、决策、断点固化到文件里，而不是只留在聊天记录里

## 核心能力

- 项目进入 / 退出 / 恢复规则
- 已有项目目录接管
- 新项目初始化
- 项目目录确认机制
- 已登记项目扫描机制
- 项目注册表维护规则
- 项目阶段性固化机制

## 适用场景

适合：

- 长期项目
- 多轮协作
- 需要恢复断点的工作
- 需要记录关键决策、索引、checkpoint 的任务

不适合：

- 一次性问答
- 临时查资料
- 短平快的小任务
- 不需要恢复的轻量事务

## 它不是什么

这个 skill 不是：

- OpenClaw 原生多会话 UI 的替代品
- 自动猜中用户当前项目的黑盒系统
- 完全无配置的项目管理器

它提供的是：

- 一套基于文件的项目管理约定
- 一套项目发现、进入、恢复、退出、固化工作流

## 最小使用方式

### 1. 接管已有项目目录
你可以对 assistant 说：

- 这是我的项目目录，帮我接管
- 把这个目录纳入项目管理
- 给这个目录补齐项目恢复结构

### 2. 初始化一个新项目
你可以说：

- 帮我建一个长期项目
- 给这个任务建立项目结构
- 以后要持续推进，帮我按项目机制管理

### 3. 恢复项目
你可以说：

- 恢复项目
- 进入项目
- 按恢复入口恢复项目
- 回到项目

### 4. 退出项目
你可以说：

- 退出项目
- 回到普通模式

### 5. 固化项目状态
你可以说：

- 固化当前项目
- 更新恢复文件并保存当前断点
- 保存当前阶段进展

## 推荐项目结构

每个项目建议至少包含：

- `00_恢复入口.md`
- `00_文档总索引与当前进度.md`
- `01_项目会话与恢复机制说明.md`
- `99_关键决策记录.md`
- `checkpoints/`
- `session-backups/`

## 项目发现怎么工作

当用户说“恢复项目 / 进入项目”时，推荐流程是：

1. 读取项目注册表
2. 扫描所有已登记项目路径
3. 检查路径和恢复文件是否有效
4. 列出当前可识别项目
5. 让用户选择进入哪个项目
6. 再读取该项目的恢复入口继续恢复

当前推荐的轻量注册表示例：

- `<workspace>/projects-registry.json`

## 目录说明

- `SKILL.md`：skill 主说明
- `scripts/init_project.py`：初始化项目结构的脚本
- `templates/`：项目模板文件
- `docs/`：补充说明文档（初始化、注册表维护等）

## 发布说明

如果你打算继续分发或二次修改，建议：

- 不要保留个人真实路径
- 不要保留个人真实项目名
- 把本地样例替换成通用示例
- 根据自己的目录习惯调整注册表与模板

## 相关补充文档

- `docs/初始化与测试说明.md`
- `docs/项目注册表维护说明.md`
- `docs/发布说明与用户使用指南.md`


path: templates/00_恢复入口.md
content: # 会话恢复入口（项目模板）

## 一、用途

当当前项目会话中断、上下文丢失、或需要快速恢复项目工作时，优先从本文件开始。

本文件定义的是**动态恢复协议**，不是静态文件清单。

---

## 二、恢复原则

1. 先读恢复入口，再执行恢复流程
2. 先扫描项目目录，再决定读哪些文件
3. 不依赖固定旧文件名而忽略新增文件
4. 优先恢复当前主线、当前阶段、当前断点、关键决策、下一步

---

## 三、恢复流程

### 第 1 步：扫描当前项目目录
至少识别：
- `*.md`
- `checkpoints/`
- `session-backups/`
- 其他新增的说明、决策、验证、实施、排障类文件

### 第 2 步：读取索引与决策文件
优先读取：
1. `00_文档总索引与当前进度.md`
2. `99_关键决策记录.md`

### 第 3 步：动态定位当前断点
根据索引和目录现状识别：
- 当前进行到哪
- 当前断点在哪个文件
- 最近新增的重要文件有哪些

### 第 4 步：补读最近 checkpoint / memory
如有需要，再补读：
- 最新 checkpoint
- 最近相关 memory 记录
- 其他与当前断点高度相关的新增文件

---

## 四、恢复兜底策略

如果恢复过程中发现以下情况：

- 索引缺失或明显过期
- 恢复入口内容不完整
- 目录结构与索引不一致
- 当前断点无法直接定位

则应执行兜底流程：

1. 先扫描当前目录中的全部相关文件
2. 优先读取最近 checkpoint
3. 再读取最近相关 memory / 摘要记录
4. 给出“低置信恢复”提示
5. 再向用户确认是否按当前判断继续

---

## 五、恢复后必须输出

恢复完成后，至少输出：

- 当前项目主线
- 已完成内容
- 当前断点
- 最近新增文件
- 当前关键决策
- 下一步建议

---

## 六、固化提醒

若恢复后发现：
- 索引已落后
- 当前断点变化但未固化
- 新决策未写入决策文件
- 当前阶段即将结束

应提醒用户考虑执行一次固化。


path: templates/01_项目会话与恢复机制说明.md
content: # 项目会话与恢复机制说明

## 一、目的

本说明用于规范长期项目在主会话中的工作方式，避免项目内容与普通事务混淆，并保证会话中断后仍可恢复。

---

## 二、当前工作方式

- 聊天表面上仍可能发生在主会话中
- 但项目上下文不依赖聊天连续性
- 项目恢复依赖项目目录中的恢复入口、索引、决策、checkpoint 与相关记录

---

## 三、进入项目的方式

用户表达以下意图时，视为进入项目：

- 进入项目
- 恢复项目
- 回到项目
- 继续当前项目

在多项目场景下，应先列出项目并让用户确认目标项目。

---

## 四、退出项目的方式

用户表达以下意图时，视为退出项目：

- 退出项目
- 先切到普通事务
- 当前问题和项目无关

退出项目后：
- 后续普通事务不写入项目记录
- 如后续内容疑似项目相关，应先提醒用户确认是否重新进入项目

---

## 五、会话中断后的恢复方式

恢复顺序：

1. 读取 `00_恢复入口.md`
2. 扫描当前项目目录
3. 读取索引与决策文件
4. 读取当前断点文件
5. 必要时补读最近 checkpoint / memory / 摘要

---

## 六、固化机制

### 用户明确触发时
用户明确下达以下指令时，应直接执行固化：

- 固化当前项目
- 更新恢复文件并保存当前断点
- 保存当前阶段进展

### 关键节点提醒
在以下节点，应主动提醒用户是否固化：

- 完成关键文档后
- 当前断点变化后
- 新决策形成后
- 新增强相关文件后
- 进入新阶段时
- 会话可能暂停或中断前

---

## 七、边界规则

- 项目记录保存的是有效可恢复上下文，不是全部聊天原文
- 项目外普通事务不应纳入项目记录
- 恢复时不能只依赖固定文件，必须先扫描目录并识别新增文件

---

## 八、重要边界说明

本机制管理的是“项目上下文”，不是 OpenClaw 原生 UI 级别的多会话切换。

也就是说，它不等同于在 WebChat 中真正创建了一个独立、持久、可切换的原生项目会话，而是通过文件化项目结构、恢复入口和上下文切换协议来实现长期项目管理。


path: templates/00_文档总索引与当前进度.md
content: # <项目名称>｜文档总索引与当前进度

## 一、项目定位

- 项目名称：<项目名称>
- 当前主线：<当前主线>
- 当前阶段：<当前阶段>

---

## 二、文档总览

### 已完成
- <已完成文档 1>
- <已完成文档 2>

### 当前进行中
- <当前进行中的文档或任务>

### 预留后续文档
- <后续文档 1>
- <后续文档 2>

---

## 三、当前断点

- 当前断点：<当前断点>
- 当前说明：<当前说明>

---

## 四、最近新增

- <最近新增文件 1>
- <最近新增文件 2>

---

## 五、当前关键结论

- <关键结论 1>
- <关键结论 2>

---

## 六、下一步

### 立即下一步
- <下一步 1>

### 后续建议
- <后续建议 1>
- <后续建议 2>

---

## 七、维护规则

每完成一份关键文档、一个阶段、或一个关键决策后，应更新本文件，至少同步：

- 已完成内容
- 当前断点
- 最近新增文件
- 下一步


path: templates/PROJECT_SYSTEM.md
content: # 项目系统总入口

## 一、用途

本文件定义 workspace 级别的项目上下文管理规则。

当用户说“进入项目”“恢复项目”“回到项目”时，助手应优先读取本文件，而不是依赖聊天记忆猜测当前项目。

---

## 二、项目根目录

- 项目统一根目录：`<在初始化时填写>`
- 每个项目一个单独文件夹
- 项目名称应尽量稳定、可读、可区分

---

## 三、有效项目识别规则

扫描项目根目录时，不应把所有文件夹都视为有效项目。

一个文件夹若至少满足以下任一条件，可视为“可识别项目”：

- 包含 `00_恢复入口.md`
- 包含 `00_文档总索引与当前进度.md`
- 包含 `99_关键决策记录.md`

如果某个文件夹只是普通资料夹、缓存目录或临时目录，不应作为项目候选项展示给用户。

---

## 四、进入项目规则

当用户表达“进入项目 / 恢复项目 / 回到项目”时：

1. 先扫描项目根目录
2. 列出所有可识别项目
3. 若用户未明确指定项目，则让用户确认选择
4. 只有用户确认后，才进入对应项目
5. 进入项目后，再读取该项目的 `00_恢复入口.md`

不得在多项目场景下直接猜测用户要进入哪个项目。

如果当前项目根目录下只有一个有效项目，也应优先向用户确认，而不是静默默认进入。

---

## 五、退出项目规则

当用户明确表示退出项目、切到普通事务、或说明当前问题与项目无关时：

- 后续内容不默认属于任何项目
- 不应自动写入任何项目恢复记录
- 若后续内容疑似项目相关，应先提醒并确认是否重新进入项目

---

## 六、恢复项目规则

进入具体项目后，应：

1. 读取该项目的 `00_恢复入口.md`
2. 扫描该项目目录中的相关文件
3. 读取索引、决策、当前断点与最近 checkpoint
4. 输出结构化恢复结果

恢复不能只依赖旧聊天，也不能只机械读取几个固定文件而忽略新增文件。

---

## 七、固化规则

用户明确要求固化时，应立即执行。

在以下节点，助手应主动提醒用户是否固化：

- 完成关键文档后
- 当前断点明显变化后
- 形成关键决策后
- 新增强相关文件后
- 进入新阶段时
- 会话可能中断或暂停前

固化保存的是“可被后续继承的有效项目上下文”，不是机械保存全部聊天原文。

---

## 八、推荐项目标准结构

每个项目建议至少包含：

- `00_恢复入口.md`
- `00_文档总索引与当前进度.md`
- `01_项目会话与恢复机制说明.md`
- `99_关键决策记录.md`
- `checkpoints/`
- `session-backups/`

---

## 九、当前执行原则

- 项目管理依赖文件化规则，而不是聊天记忆
- 进入项目前先发现项目，再确认选择
- 退出项目后关闭项目记录边界
- 恢复项目时优先扫描目录并识别新增文件


path: templates/99_关键决策记录.md
content: # <项目名称>｜关键决策记录

## 决策 001

### 结论
<决策结论>

### 原因
- <原因 1>
- <原因 2>

---

## 决策 002

### 结论
<决策结论>

### 原因
- <原因 1>
- <原因 2>

---

## 当前最新状态摘要

- 当前阶段：<当前阶段>
- 当前断点：<当前断点>
- 当前下一步：<下一步>


path: templates/checkpoints/README.md
content: # checkpoints

Use this directory for phase-level snapshots.

Recommended times to create a checkpoint:

- after a key document is completed
- when entering a new phase
- after creating a patch or configuration draft
- before and after applying configuration changes
- whenever you want to preserve the current recoverable state before continuing


path: templates/session-backups/README.md
content: # session-backups

Use this directory for project-related conversation summaries, transcript notes, or important backup artifacts.

By default, you do not need to save the entire raw chat transcript every time.

Prefer saving:
- phase summaries
- key discussion snapshots
- transcript backup notes at important milestones


path: scripts/init_project.py
content: #!/usr/bin/env python3
import json
import os
import sys
from pathlib import Path


def expand(p: str) -> Path:
    return Path(os.path.expanduser(p)).resolve()


def write_text(path: Path, content: str, overwrite: bool = False):
    path.parent.mkdir(parents=True, exist_ok=True)
    if path.exists() and not overwrite:
        return False
    path.write_text(content, encoding='utf-8')
    return True


def read_template(base: Path, rel: str) -> str:
    return (base / 'templates' / rel).read_text(encoding='utf-8')


def main():
    if len(sys.argv) != 2:
        print(json.dumps({
            'ok': False,
            'error': 'Usage: init_project.py <json-args>'
        }, ensure_ascii=False))
        sys.exit(1)

    try:
        args = json.loads(sys.argv[1])
    except Exception as e:
        print(json.dumps({'ok': False, 'error': f'Invalid JSON: {e}'}, ensure_ascii=False))
        sys.exit(1)

    projects_root = args.get('projects_root')
    project_name = args.get('project_name')
    create_workspace_rule = bool(args.get('create_workspace_rule', True))
    workspace_root = args.get('workspace_root', '~/.openclaw/workspace')
    project_rule_filename = args.get('project_rule_filename', 'PROJECT_SYSTEM.md')
    overwrite = bool(args.get('overwrite', False))

    if not projects_root or not project_name:
        print(json.dumps({
            'ok': False,
            'error': 'projects_root and project_name are required'
        }, ensure_ascii=False))
        sys.exit(1)

    base_dir = Path(__file__).resolve().parent.parent
    workspace_root = expand(workspace_root)
    projects_root = expand(projects_root)
    project_dir = projects_root / project_name

    created = []
    skipped = []

    projects_root.mkdir(parents=True, exist_ok=True)
    project_dir.mkdir(parents=True, exist_ok=True)
    (project_dir / 'checkpoints').mkdir(parents=True, exist_ok=True)
    (project_dir / 'session-backups').mkdir(parents=True, exist_ok=True)

    if create_workspace_rule:
        system_path = workspace_root / project_rule_filename
        content = read_template(base_dir, 'PROJECT_SYSTEM.md').replace('`<在初始化时填写>`', f'`{projects_root}`')
        if write_text(system_path, content, overwrite=overwrite):
            created.append(str(system_path))
        else:
            skipped.append(str(system_path))

    files = [
        '00_恢复入口.md',
        '00_文档总索引与当前进度.md',
        '01_项目会话与恢复机制说明.md',
        '99_关键决策记录.md',
        'checkpoints/README.md',
        'session-backups/README.md',
    ]

    for rel in files:
        target = project_dir / rel
        content = read_template(base_dir, rel)
        content = content.replace('<项目名称>', project_name)
        if write_text(target, content, overwrite=overwrite):
            created.append(str(target))
        else:
            skipped.append(str(target))

    print(json.dumps({
        'ok': True,
        'projects_root': str(projects_root),
        'project_dir': str(project_dir),
        'created': created,
        'skipped': skipped,
        'next': [
            f'Edit {project_dir / "00_文档总索引与当前进度.md"} to define mainline / phase / breakpoint.',
            f'Edit {project_dir / "99_关键决策记录.md"} to record initial decisions.',
            f'Read {workspace_root / project_rule_filename} before using enter/recover-project workflow.'
        ]
    }, ensure_ascii=False, indent=2))


if __name__ == '__main__':
    main()


path: docs/初始化与测试说明.md
content: # 初始化与测试说明

## 一、目的

本文件用于说明 `project-context-manager` 当前版本的初始化方式、已确认的最小运行机制，以及推荐测试流程。

当前版本重点验证三件事：

1. 能否把一个长期项目纳入 skill 管理
2. 能否在会话中断后按恢复入口恢复单个项目
3. 能否在多个已登记项目之间先发现候选项目，再让用户选择进入哪个

---

## 二、当前最小运行机制

当前版本建议由以下几部分组成：

1. `SKILL.md`
   - 定义项目进入 / 退出 / 恢复 / 固化的规则

2. `PROJECT_SYSTEM.md`（可选但推荐）
   - 定义 workspace 级项目系统规则
   - 适合采用统一项目根目录时使用

3. `projects-registry.json`
   - 用于登记已纳入 skill 管理的项目
   - 记录项目名、项目路径、状态、恢复入口文件等信息

4. 每个项目自己的恢复文件
   - `00_恢复入口.md`
   - `00_文档总索引与当前进度.md`
   - `99_关键决策记录.md`
   - `checkpoints/`
   - `session-backups/`

---

## 三、当前建议的恢复逻辑

当用户说：
- 恢复项目
- 进入项目
- 回到项目
- 按恢复入口恢复项目

建议执行顺序为：

1. 读取 `projects-registry.json`
2. 扫描所有已登记项目路径
3. 检查路径与关键恢复文件是否有效
4. 列出当前可识别项目
5. 让用户选择进入哪个项目
6. 选择后，再读取对应项目的 `00_恢复入口.md`
7. 按该项目的恢复协议继续恢复

如果当前只有一个有效项目，也建议先向用户确认，而不是静默默认进入。

---

## 四、首次纳入项目时的推荐流程

### 情况 A：用户已有项目目录

1. 用户提供项目路径
2. 检查该目录是否已有恢复结构
3. 如无结构，则提示是否初始化
4. 如已有结构，则直接接管
5. 将项目登记进 `projects-registry.json`

### 情况 B：用户还没有项目目录

1. 识别这是长期项目，而不是一次性任务
2. 询问是否建立标准项目目录
3. 用户确认后初始化结构
4. 将项目登记进 `projects-registry.json`

---

## 五、当前已验证样例

当前已登记样例项目：

1. `示例业务项目`
   - 路径：`/Users/example/Desktop/项目库/示例业务项目/00_团队建设`
   - 状态：active

2. `示例skill项目`
   - 路径：`/Users/example/Desktop/项目库/project-context-manager-skill`
   - 状态：active

这两个项目用于验证：
- 项目恢复入口是否可用
- 多项目场景下能否先发现候选项目
- 退出项目后是否能重新选择进入

---

## 六、建议测试用例

### 测试 1：单项目恢复

场景：
- 当前只有一个已登记且有效项目
- 用户说“恢复项目”

期望：
- assistant 先扫描已登记项目
- 告知当前仅识别到一个项目
- 仍建议用户确认是否进入

### 测试 2：多项目恢复

场景：
- 当前有多个已登记项目
- 用户说“进入项目”

期望：
- assistant 先列出所有可识别项目
- 让用户选择
- 选择后再进入对应恢复入口

### 测试 3：路径失效

场景：
- 某个项目已登记，但目录被移动或删除

期望：
- assistant 检测到路径失效
- 给出低打扰提示
- 请求用户更新路径，而不是假装恢复成功

### 测试 4：缺少目录记录

场景：
- 用户让 assistant 恢复项目
- 但当前没有该项目的目录登记

期望：
- assistant 提示补充目录
- 不应直接猜测项目

---

## 七、当前限制

1. 当前版本已补规则，但注册表还属于轻量实现
2. 目前主要解决“已登记项目发现与恢复”问题
3. 尚未建立更完整的自动注册、更新、清理机制
4. 后续可以继续补：
   - 注册表维护规则
   - 项目删除 / 归档规则
   - 路径迁移后的更新流程
   - 更明确的用户使用说明

---

## 八、下一步建议

1. 在 skill 文档中正式引用 `projects-registry.json`
2. 增加注册表维护说明
3. 后续根据真实使用继续补发布说明与用户指南


path: docs/项目注册表维护说明.md
content: # 项目注册表维护说明

## 一、目的

本文件用于说明 `project-context-manager` 当前版本中 `projects-registry.json` 的职责、维护规则与推荐更新时机。

目标是让“项目发现层”可持续维护，而不是只靠临时补记路径。

---

## 二、注册表的定位

`projects-registry.json` 是当前版本的轻量项目发现入口。

它不替代：
- 每个项目自己的 `00_恢复入口.md`
- 每个项目自己的索引与决策文件
- workspace 级 `PROJECT_SYSTEM.md`

它负责的是：
- 记录有哪些项目已经被纳入 skill 管理
- 记录这些项目当前应去哪里扫描
- 在用户说“恢复项目 / 进入项目”时，为项目发现提供第一批候选对象

一句话：

> 注册表解决“先找到有哪些项目”，项目内文件解决“进入后怎么恢复”。

---

## 三、建议字段

当前版本建议每个项目至少记录以下字段：

- `name`
  - 项目名称
- `path`
  - 项目目录路径
- `status`
  - 当前状态，例如：`active` / `archived` / `invalid`
- `entryFile`
  - 恢复入口文件名，通常为 `00_恢复入口.md`
- `indexFile`
  - 索引文件名，通常为 `00_文档总索引与当前进度.md`
- `decisionFile`
  - 决策文件名，通常为 `99_关键决策记录.md`
- `registeredAt`
  - 首次登记时间
- `notes`
  - 简要说明该项目当前用途或主线

可选字段：
- `lastValidatedAt`
- `lastRecoveredAt`
- `lastCheckpoint`
- `tags`
- `rootMode`（例如 `project-root` / `subdir-entry`）

---

## 四、什么时候应新增项目登记

以下情况应新增项目到注册表：

1. 用户明确要求把某个长期项目纳入 skill 管理
2. 用户提供了项目路径，并确认这是正式项目目录
3. assistant 已完成项目初始化并确认目录存在
4. assistant 已接管一个已有项目目录并确认结构有效

在这些情况下，不应只完成项目结构初始化，还应同步写入注册表。

---

## 五、什么时候应更新已有项目登记

以下情况应更新已有项目的注册表信息：

### 5.1 项目路径变更

当用户说明：
- 项目搬家了
- 我把目录移动了
- 路径改了

应更新：
- `path`
- 必要时补记 `notes`
- 更新验证时间

### 5.2 项目恢复入口结构调整

当项目内部关键文件改名或结构调整时，应更新：
- `entryFile`
- `indexFile`
- `decisionFile`

### 5.3 项目状态变化

当项目已不再活跃、进入归档、或路径已失效时，应更新：
- `status`

推荐状态：
- `active`：当前正常使用
- `archived`：已归档但仍可参考
- `invalid`：路径失效或结构不可用

### 5.4 项目说明变化

当项目主线明显变化时，可更新：
- `notes`

---

## 六、什么时候不应随便修改注册表

以下情况不应轻易改注册表：

1. 只是普通聊天提到某个项目名
2. 用户没有确认项目路径
3. 当前只是逻辑上按项目讨论，但还未正式纳入管理
4. assistant 只是猜测某个目录可能是项目

原则：

> 注册表是“已确认项目”的名单，不是“疑似项目”的缓存池。

---

## 七、恢复项目时的使用规则

当用户说：
- 恢复项目
- 进入项目
- 回到项目

建议顺序：

1. 读取 `projects-registry.json`
2. 过滤 `status = active` 的项目
3. 逐个检查：
   - 路径是否存在
   - 入口文件是否存在
   - 索引/决策文件是否存在
4. 形成当前可识别项目列表
5. 让用户选择进入哪个项目
6. 选择后，再进入对应项目恢复流程

如果某项目登记存在但路径失效：
- 可暂不从候选列表主展示
- 或带着“路径失效”标签提示用户
- 并建议用户更新路径

---

## 八、反打扰规则

注册表维护不应造成高频打扰。

### 应提示用户的情况
- 首次登记项目时
- 项目路径失效时
- 恢复时找不到可用项目时
- 项目路径与恢复结构不一致时

### 不应反复提示的情况
- 项目已登记且可正常恢复
- 只是普通事务对话
- 刚刚确认过路径且状态未变化

### 单次提醒原则
对同一项目的同一目录问题，默认只提醒一次；
只有在用户再次要求恢复、路径再次校验失败、或项目状态变化时，才再次提醒。

---

## 九、当前版本的限制

1. 当前注册表仍是轻量版本
2. 主要依赖手动维护或在接管/初始化时同步更新
3. 尚未建立更完整的自动校验与清理机制
4. 尚未支持更复杂的多入口项目结构

---

## 十、下一步建议

1. 后续可补“注册表自动更新规则”
2. 可补“项目归档与失效处理规则”
3. 可补“多子目录项目的登记策略”
4. 可补面向用户的简化使用说明


path: docs/发布说明与用户使用指南.md
content: # 发布说明与用户使用指南

## 一、这是什么

`project-context-manager` 是一个用于长期项目上下文管理的通用 skill。

它主要解决的问题不是“单轮问答”，而是：

- 一个共享主会话里同时推进多个长期项目
- 会话中断、归档或上下文丢失后，需要恢复项目现场
- 需要把项目工作与普通事务分开
- 需要在关键阶段把当前状态固化下来，便于后续继续

一句话：

> 它用文件化规则来管理项目的进入、退出、恢复与固化。

---

## 二、它不是什么

这个 skill 不是：

- OpenClaw 原生多会话 UI 的替代品
- 自动猜中当前项目的黑盒系统
- 完全无配置的全自动项目管理器

它提供的是：

- 一套明确的项目边界规则
- 一套可恢复的文件结构
- 一套项目发现、进入和恢复的工作流

---

## 三、适用场景

适合：

- 需要长期推进的项目
- 需要多轮协作、记录断点、保留决策的任务
- 希望在普通事务之外单独管理项目上下文的情况
- 会话中断后还需要稳定恢复的工作

不太适合：

- 一次性问答
- 单次资料查询
- 临时报错排查
- 很短的脚本任务
- 不需要恢复和阶段固化的轻任务

---

## 四、最小使用方式

### 方式 A：接管已有项目目录

当你已经有一个项目文件夹时，可以对 assistant 说：

- 这是我的项目目录，帮我接管
- 把这个目录纳入项目管理
- 给这个目录补齐项目恢复结构

assistant 应该：

1. 确认项目路径
2. 检查该目录是否已有恢复结构
3. 缺失时询问是否初始化
4. 接管后，把该项目登记进项目注册表

### 方式 B：初始化一个新项目

当你还没有项目目录，但确定这是长期项目时，可以说：

- 帮我建立一个新项目
- 这是个长期项目，给我建项目结构
- 以后要持续推进，帮我按项目机制管理

assistant 应该：

1. 识别这是长期项目
2. 询问项目路径或项目根目录
3. 初始化标准项目结构
4. 把项目登记进项目注册表

---

## 五、推荐项目结构

每个项目建议至少包含：

- `00_恢复入口.md`
- `00_文档总索引与当前进度.md`
- `01_项目会话与恢复机制说明.md`
- `99_关键决策记录.md`
- `checkpoints/`
- `session-backups/`

这些文件分别负责：

- 定义恢复协议
- 记录当前断点与文档总览
- 说明项目会话机制
- 记录关键决策
- 保存阶段性快照与会话备份

---

## 六、项目发现如何工作

当用户说：

- 恢复项目
- 进入项目
- 回到项目
- 按恢复入口恢复项目

推荐流程是：

1. 读取项目注册表
2. 扫描所有已登记项目路径
3. 检查路径与关键恢复文件是否有效
4. 列出当前可识别项目
5. 让用户选择进入哪个项目
6. 用户确认后，再进入该项目的恢复入口

注意：

- 单个项目里的 `00_恢复入口.md` 解决的是“已知项目后的恢复”
- 项目注册表解决的是“先发现有哪些项目”

---

## 七、为什么有时会要求你确认项目目录

为了让项目能够在未来稳定恢复，assistant 在以下情况可能会提示你确认目录：

- 首次把项目纳入 skill 管理时
- 恢复项目但当前没有目录记录时
- 项目路径失效时
- 无法形成可靠候选项目列表时

但它不应该高频打扰：

- 若路径已经登记且有效，不应反复询问
- 对同一目录问题，默认只提醒一次
- 只有在用户再次要求恢复或路径状态变化时，才适合再次提醒

---

## 八、注册表是必需的吗

不是绝对必需，但在多项目场景下非常推荐。

当前推荐的最小实现是：

- 注册表文件：`<workspace>/projects-registry.json`

它记录：

- 项目名称
- 项目路径
- 当前状态
- 关键恢复文件信息

如果没有注册表，assistant 就更难在“恢复项目”时先列出候选项目。

---

## 九、常见口令示例

### 接管已有项目
- 这是我的项目目录，帮我接管
- 把这个目录纳入项目管理

### 新建项目
- 帮我建一个长期项目
- 给这个任务建立项目结构

### 恢复项目
- 恢复项目
- 按恢复入口恢复项目
- 回到项目

### 退出项目
- 退出项目
- 回到普通模式

### 固化当前状态
- 固化当前项目
- 更新恢复文件并保存当前断点
- 保存当前阶段进展

---

## 十、常见问题

### 1. 为什么 assistant 不直接猜我要进哪个项目？

因为在多项目场景下，猜测很容易出错。

这个 skill 的原则是：
- 先发现候选项目
- 再让用户确认
- 确认后再恢复

### 2. 为什么我明明有恢复入口，assistant 还是要问项目目录？

因为恢复入口只能在“已知项目路径”后发挥作用。
如果 assistant 还不知道项目在哪里，就没法先发现并进入该项目。

### 3. 为什么不把所有桌面文件夹都当项目？

因为这样误识别太多，也会污染项目列表。
当前推荐只把“已确认纳入管理的项目”写进注册表。

---

## 十一、发布建议

如果你准备把这个 skill 对外发布，建议：

1. 去掉个人真实路径与真实项目名
2. 把本地样例改成通用示例
3. 明确写清边界：它不是原生多会话替代品
4. 提供最小可运行示例
5. 提供常见错误与恢复说明

---

## 十二、当前版本定位

当前版本已经具备：

- 项目进入 / 退出 / 恢复 / 固化规则
- 已有项目接管机制
- 新项目初始化机制
- 项目目录确认机制
- 已登记项目扫描机制
- 项目注册表维护规则

后续仍可继续增强：

- 注册表自动维护
- 项目归档规则
- 更完整的发布说明
- 更丰富的模板与示例


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)