Claude Skill

eo-project-init

eo-skills 在当前仓库的总入口:生成 .eo-project.json、初始化项目管理侧(roadmap)和代码侧最小骨架(eo-doc/),以及 agent 配置注入。触发:启动项目 / 初始化项目 / 新建项目 / /eo-project-init。

LLM Mart · 0 points · 5 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download simpleeve-eo-skills-eo-project-init-e6f1112.zip · 25 KB
Part of simpleeve/eo-skills — 16 skills

Install

skills CLI npx skills add https://github.com/SimpleEve/eo-skills/tree/main/eo-project-init
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install simpleeve-eo-skills@llmmart
Git git clone https://github.com/SimpleEve/eo-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole simpleeve/eo-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

eo-project-init

定位

所有 eo- skill 的总入口*。其它 skill(eo-change / eo-implement / eo-doc-manager / …)都依赖 .eo-project.json;未运行过本 skill 的项目无法使用其它 eo-* skill。

一次 init 完成三件事:

  1. 生成 .eo-project.json(项目级配置,所有 skill 读它)
  2. 初始化项目管理侧(<repo>/.eo-project/)——最小骨架
  3. 初始化代码侧 eo-doc/ 最小骨架(内部调用 eo-doc-manager init 的子流程)

配置与目录约定详见 references/config.md。

输入

用户提供以下之一:

  • PRD/MVP 文档路径
  • 口头描述:项目名称 + 要做什么 + 大致阶段
  • 仅项目名:快速创建空骨架(后续再补充)

可选:

  • 代码仓库路径(当前 cwd 不是代码仓库时)

执行步骤

1. 检查是否已初始化

  • cwd 向上已有 .eo-project.json → 走下方「1.5 更新/修复分支」,不进入首次创建流程
  • 未有 → 继续首次创建流程

1.5 更新/修复分支(已初始化项目重跑本 skill)

对已有 .eo-project.json 的项目,重跑是幂等的补齐动作,逐项执行、已达标项静默跳过:

  1. v1 痕迹检测:发现 eo-doc/dev/ 存在、kanban_path 非 null 等信号 → 先按 references/migrate-v1.md 执行迁移子流程(冻结 spec、建项目级 changes、kanban 退役、roadmap 补 frontmatter、backlog 打散成卡等,幂等),完成后继续下列步骤 0.5. 协作者接入(local 覆盖):按 config.md 规则合并同目录 .eo-project.local.json(如有)后,检查合并结果的 project_root 在本机是否存在可写。不可用(典型:clone 了别人提交的配置,project_root 指向他人机器上的路径)或必填字段缺失 → 按「3. 计算 project_root」算出本机 project_root,把机器相关字段(mode / project_root)写入 .eo-project.local.json——不改动提交的 .eo-project.json。后续步骤一律以合并结果为准
  2. 配置校验:读现有 .eo-project.json(合并 local 覆盖),对照 references/config.md 的 schema——基础字段(project_name/mode/project_root/doc_root)缺失按默认补写;存量配置的 kanban_path 字段忽略不改,已有字段一律不改;project_root 非绝对路径(存量形态)是可修项——按 repo root 解析并解软链后回写绝对路径并提示用户(写回落点沿用既有规则:该顶层字段已存在于 .eo-project.local.json → 写 local,否则写 .eo-project.json);解析不出已存在目录时不猜,转「3. 计算 project_root」重新算出;sync 段(或其适配器键)与 state 键缺失时不在本步补写(补了显式关闭条目会吞掉第 5 步的询问),只记录缺失,留给第 5 步问答/迁移后落盘
  3. 骨架补齐:项目管理侧必建 roadmap.md 与代码侧 eo-doc/ 骨架缺什么补什么;不触碰任何已有文件的内容
  4. 注入段刷新:按标记整段刷新 agent 配置文件中的 eo-project / eo-doc / eo-reply-contract 注入段(存在则整段替换,缺失则补注);仓库根存在 DESIGN.md 时核对 eo-design 注入段
  5. .gitignore 核对:tmp/eo/、.eo-project.local.json 缺项补写;.eo-project/ 的 ignore 状态保持现状不核对——已 ignore 的不删行、未 ignore 的不补写
  6. sync / state 联动问答与存量迁移(仅合并配置 sync 段缺对应适配器键时问,规则见「7. 生成 .eo-project.json」的 sync 段小节)。存量迁移:检测到旧 board / github 段且合并配置无 sync 键 → 提示用户并代写等价 sync 段(启用集与兼容映射派生结果逐项一致;旧段问答已答过的适配器写显式条目——含关闭态,不重问;旧段保留不删,旧版工具仍可读);已有 sync 键 → 零动作零提示 state 问答(仅合并配置无 state 键时问,规则见「7. 生成 .eo-project.json」的 state 段小节):检测到存量 eo-doc/state/ → 问「恢复维护(推荐)/ 保持冻结」,结论写 state.enabled true/false;无存量 state/ → 按 §7 同一问(推荐关闭);已有 state 键 → 零动作零提示 5.5. 顺手注册:执行 eo-board --register(幂等,已注册则原地更新)。失败不阻塞本流程——注册失败时输出告警并给手工补注册指引:「⚠ 项目注册失败(<原因>),init 已正常完成;稍后可在项目目录手工执行 eo-board --register 补注册(注册后任意目录 eo-board --all 可见本项目)」
  7. 输出摘要:列出本次补齐/刷新/跳过了什么(含注册结果),然后结束——不执行首次创建流程的其余步骤

2. 解析项目信息

从输入中提取:

  • 项目名称(project_name)
  • 项目目标:一句话描述
  • 初始状态:active / researching

3. 计算 project_root

project_root = <repo>/.eo-project/。

检查 project_root 是否已存在:

  • 存在且含 roadmap.md → 按封闭选择协议三选一:1) 只建代码侧关联(推荐)2) 更新 roadmap 3) 重建(需确认)
  • 存在但无 roadmap.md → 异常,提示补全后进入拆解
  • 不存在 → 正常创建

4. 创建项目管理侧骨架(最小)

<project_root>/
└── roadmap.md     # 必建

按需目录一律不预建(backlog / phases / decisions / lessons / brainstorm / docs),等对应 skill 首次写入时由那个 skill 创建(backlog 为卡片目录,由 /eo-backlog 管理)。

写入 roadmap.md(读 templates/roadmap.md),填充项目名、目标、阶段概览占位。

5. Roadmap 拆解(可选)

如果用户提供了 PRD/MVP 或愿意拆解:

  1. 读取 references/roadmap-breakdown.md 方法论
  2. 与用户对话(不超过 5 轮):终态 → 里程碑 → Phase → 任务
  3. 用户确认后,lazy 创建 phases/ 目录,每个阶段一个文件(读 templates/phase.md)
  4. 更新 roadmap.md 的阶段概览表

仅"快速创建空骨架"时可跳过此步。

6. 初始化代码侧 eo-doc/(内部调用 eo-doc-manager init 子流程)

在代码仓库根目录创建最小骨架:

eo-doc/
├── changes/INDEX.md          # 骨架
├── agent-handbook/INDEX.md   # 骨架(篇目内容见 §6.5)
└── templates/                # 空目录

额外:

  • 询问是否启用 codegraph:启用则在仓库根执行 codegraph init 建索引,并把使用规范(索引按项目目录隔离,每个 worktree 需各自 codegraph init)写入 agent-handbook;不启用则跳过
  • 将 tmp/eo/ 追加到 .gitignore(tmp/eo/ 是各 skill 的临时工件命名空间,见 ../eo-shared/conventions.md)
  • 将 .eo-project.local.json 追加到 .gitignore(个人/机器覆盖文件不提交,见 references/config.md)
  • CLAUDE.md 注入(详见 ../eo-doc-manager/references/claude-injection.md)

注意:如果用户本次只想要项目管理侧(例如纯规划项目,没代码),可用 --skip-code-side 跳过本节。此时 doc_root 字段仍写入配置,留待将来补建。

6.5 Handbook 初始化(可选,逐步授权)

eo-doc/agent-handbook/ 是 Agent 操作手册:相对固定的操作规范,非 SSOT(代码为准),不挂自动同步;骨架由 §6 建好,是否填内容询问用户,同意才继续。模板机制(库位置 / manifest 格式 / 匹配合并细则)见 references/handbook-templates.md。

已有项目(生成 = 匹配合并,不是裸 copy):

  1. 派子 agent 扫描五个面:lint/commit 配置、git log 归纳的 commit 规律、目录结构、架构分工、UI token 用法
  2. 按 manifest signals 匹配候选 preset(私有库优先),按封闭选择协议确认(含「不用模板」)
  3. 合并生成:实证 > 模板 > 待补——模板篇目为底,扫描实证覆盖冲突项,扫描不到依据的标「待补」;已配置文件化的只落一行指针(指向配置文件)
  4. worktree 协作与 codegraph 使用两篇逐个询问授权后才写入(comments 注释纪律随 preset 默认生成,无需单独授权)

空项目:询问项目类型,选定 preset 纯 copy。

7. 生成 .eo-project.json

在代码仓库根目录写入:

{
  "project_name": "{{project_name}}",
  "mode": "local",
  "project_root": "{{absolute_path_to_project_root}}",
  "doc_root": "eo-doc",
  "kanban_path": null
}

kanban_path:固定写 null;存量配置该字段被所有 skill 忽略。项目级总览由 Bases 聚合各项目 roadmap.md 的 frontmatter 承担。

协作/多机场景:机器相关字段(project_root / mode / sync——顶层段整段覆盖)可拆到不提交的 .eo-project.local.json(顶层字段覆盖合并,规则见 references/config.md)。首次 init 默认全部写入 .eo-project.json 即可;协作者 clone 后重跑本 skill 走「1.5 更新/修复分支」的协作者接入步骤生成 local 覆盖。

sync 段(投影开关,eo-sync 直接消费——机制见 ../eo-shared/board-github.md,schema 见 references/config.md;新配置只写 sync 段本身,存量 board / github 段由兼容映射护住):按封闭选择协议问一次(触发判据 = 合并配置 sync 段缺对应适配器键)——

  • github 适配器(检测到 git remote 指向 GitHub 时才问;pr 推荐 auto):写 sync.github = {"enabled": true, "issue": <bool>, "pr": "auto"|"always"|"never"}

用户跳过 → 对应适配器写显式关闭条目({"enabled": false}),后续 skill 不再询问。后开场景:对已初始化项目重跑本 skill 走「1.5 更新/修复分支」,其第 5 步提供这一问。 state 段(现状文档层开关,/eo-doc-manager sync 与 archive 联动直接消费,schema 见 references/config.md):按封闭选择协议问一次(触发判据 = 合并配置无 state 键)——「启用 state 现状文档层?」(推荐关闭:保持精简,需要「系统现在是什么样」活文档的项目再开)。启用 → 写 state.enabled: true 并建 eo-doc/state/(空目录,首篇由 /eo-doc-manager sync 生成);跳过/拒绝 → 写显式 {"enabled": false},后续不再询问。

8. 处理 .eo-project/

.eo-project/ 即 project_root。缺省随仓库提交,不写入 .gitignore——roadmap / backlog / decisions / lessons 是协作者最需要的项目记忆,跟代码走。

仅当用户明确表示不想提交管理侧时,当场追加:

# eo-project local management side
.eo-project/

9. Agent 配置注入

检测代码仓库使用的 agent 配置文件(顺序):

  1. CLAUDE.md
  2. AGENTS.md
  3. COPILOT.md
  4. CURSOR.md
  5. 都不存在 → 按封闭选择协议问创建哪个(推荐 CLAUDE.md)

注入两个标记段(均幂等、整段替换):

1. 项目上下文段(<!-- eo-project:start/end -->):

<!-- eo-project:start -->
## EO-Project

本项目已接入 eo-skills。项目管理侧(roadmap / backlog 卡片 / decisions / lessons 等)位置从 `.eo-project.json` 的 `project_root` 字段解析(同目录存在 `.eo-project.local.json` 时顶层字段覆盖,local 优先),下文记作 `<project_root>`。

- 代码侧文档:`{{doc_root}}/`

### 项目记录入口

仅当**用户明确表达**要记录时响应(不做关键词嗅探,避免误触发):

- 用户明确说「加个待办 / 记到 backlog / 以后做」→ 调用 `/eo-backlog` 写卡到 `<project_root>/backlog/`
- 用户明确说「把这个决策记下来」→ 调用 `/eo-project-record` 写入 `<project_root>/decisions/`
- 用户明确说「记一条经验 / 踩坑记录一下」→ 调用 `/eo-project-record` 写入 `<project_root>/lessons/`

对话中出现疑似待办/决策/教训但用户未明说时,**至多在当前话题收尾处轻提一句**「要不要记入 backlog/decisions/lessons?」,不打断进行中的工作。
<!-- eo-project:end -->

2. 回复契约段(<!-- eo-reply-contract:start/end -->):

<!-- eo-reply-contract:start -->
## 回复契约(长任务收尾)

长开发任务收尾时,用一段人话向用户汇报,四条各一句:

1. **做了什么**——行为变化,不是 diff 清单
2. **为什么这么做**——关键决策与理由,被否掉的方案一并点名
3. **主要产出**——文件 / 功能 / 命令,用户去哪看、怎么验
4. **遇到的问题与解法**——没有就明说「无」

受众分两层:对开发者讲接口与路径,对需求方讲行为与结果。一句一事,不铺陈过程。
<!-- eo-reply-contract:end -->

段内正文以 ../eo-shared/reply-contract.md「契约正文」为单一来源,整段搬运不改写——注入是被动兜底通道(覆盖非 eo 流程的直改收尾);eo 流程收尾的硬步骤(eo-archive 交付汇报 / eo-loop 线段收尾报告)以该文「生效通道」为准。

模板纪律:项目上下文段不内联 project_root 绝对路径——它因人/机器而异且 agent 配置文件提交进仓库,内联会把个人路径泄进 git 并在协作者机器上失真。运行时一律从配置合并结果解析。

DESIGN.md 检查:若仓库根存在 DESIGN.md 但 agent 配置文件中无 <!-- eo-design:start --> 标记段,执行 /eo-design 的约束注入子步骤补上(注入模板见 ../eo-design/references/design-md-template.md)。

10. 注册到生态注册表(顺手注册)

执行 eo-board --register(在仓库根目录),把项目登记进用户级注册表 ${EO_HOME:-$HOME/.eo}/projects.json,供 eo-board --all / eo-sync watch --all 跨项目枚举。

失败不阻塞 init——注册失败(如注册表目录不可写)时本 skill 仍算成功完成,但必须输出告警与手工补注册指引:「⚠ 项目注册失败(<原因>),init 已正常完成;稍后可在项目目录手工执行 eo-board --register 补注册(注册后任意目录 eo-board --all 可见本项目)」

11. 输出摘要

展示:

  • .eo-project.json 路径和内容
  • 项目管理侧骨架结构
  • 代码侧骨架结构
  • gitignore / agent 配置 / 生态注册 状态

输出

  • 代码仓库:.eo-project.json + eo-doc/ 最小骨架 + agent 配置注入
  • 项目管理侧:<project_root>/ 含 roadmap.md(+ 按需 backlog/ 卡片、phases/ 等)

约束

  • .eo-project.json 是所有 eo- skill 的启动前置*。本 skill 的核心产出
  • 按需目录(phases / decisions / lessons / brainstorm / docs)init 时不预建,由对应 skill 首次写入时 lazy 创建
  • 项目名用用户给的原始名称,不转换
  • 原始 PRD/MVP 若提供,存到 <project_root>/docs/(lazy 建)
  • .eo-project/ 缺省随仓库提交、不进 .gitignore;用户明确不想提交时当场覆盖。存量项目重跑本 skill 不改其既有 ignore 状态
  • .eo-project.local.json 始终进 .gitignore(个人/机器覆盖,不提交);协作者接入只写 local,不改共享的 .eo-project.json
  • agent 配置注入使用 <!-- ...:start/end --> 标记段(eo-project / eo-reply-contract),幂等可重复执行
Files (eo-skills)
  • references
    • config.md 10.7 KB
      # eo-skills 配置约定
      
      所有 eo-* skill 共享的路径与配置约定。本文档是**唯一权威来源**——其它 skill 引用本文,不重复定义。
      
      ## 用户级数据根 `~/.eo/`
      
      `~/.eo/` 是整个 eo 生态(eo-skills + eo-platform 等)在单用户下共享的**用户级数据根**,避免配置与缓存散落各处。当前约定内容如下:
      
      | 路径 | 性质 | 谁维护 |
      |------|------|--------|
      | `~/.eo/projects.json` | eo 生态项目注册表(`eo-board --all` / `eo-sync watch --all` 跨项目枚举) | `eo-board --register` / `--unregister` |
      | `~/.eo/platform.db` | eo-platform 本地索引缓存(SQLite) | eo-platform |
      | `~/.eo/logs/` | eo-platform 日志(按需) | eo-platform |
      | `~/.eo/handbook-templates/<preset>/` | handbook 模板私有库(同名 preset 整套覆盖内置库) | 用户手工维护 |
      
      根路径可通过环境变量 `EO_HOME` 覆盖(例如跑测试或多账号隔离时指向临时目录)。未设置时一律使用 `~/.eo/`。涉及该路径的内联命令一律写 `"${EO_HOME:-$HOME/.eo}"`。
      
      ## 两个配置文件
      
      | 文件 | 作用域 | 谁维护 | 何时读 |
      |------|--------|--------|--------|
      | `<repo>/.eo-project.json` | 项目级·团队共享 | `eo-project-init` 生成,后续 skill 只读 | **所有 eo-* skill 启动时必读** |
      | `<repo>/.eo-project.local.json` | 项目级·个人/机器覆盖(可选,**不提交**) | 协作者手工 / `eo-project-init` 协作者接入分支生成 | 与 `.eo-project.json` 同时读,顶层字段覆盖合并(local 优先) |
      
      **合并结果**(`.eo-project.json` + 可选 local 覆盖)是**自包含**的——含所有需要的绝对路径,其它 skill 不需要再去读用户级文件。
      
      ## `<repo>/.eo-project.json` schema(项目级,必需)
      
      ```json
      {
        "project_name": "my-project",
        "mode": "local",
        "project_root": "/Users/xxx/my-project/.eo-project",
        "doc_root": "eo-doc",
        "kanban_path": null,
        "sync": {
          "obsidian": { "enabled": true, "stub_dir": "board" },
          "github":   { "enabled": false }
        }
      }
      ```
      
      | 字段 | 类型 | 必填 | 说明 |
      |------|------|------|------|
      | `project_name` | string | ✅ | 项目显示名 |
      | `mode` | `"local"` | ✅ | 运行模式 |
      | `project_root` | string(绝对路径) | ✅ | **项目管理侧根**,= `<repo>/.eo-project` 的绝对路径。写成相对路径时(存量形态)读取层按 repo root 解析并解软链后放行 + 告警,见下「读取层归一化」 |
      | `doc_root` | string(相对 repo root) | ✅ | **代码侧根**,默认 `"eo-doc"` |
      | `kanban_path` | null | ❌ | 一律 `null`;存量值被所有 skill 忽略。项目级总览 = Bases 聚合各项目 roadmap.md frontmatter |
      | `board.enabled` | bool | ❌(默认 `false`) | **存量字段**(新配置不再生成,仅兼容映射消费;首选写 `sync.obsidian.enabled`)。change 看板投影开关。开启后 `eo-sync`(obsidian 适配器)把 stub 卡片投影到 `<project_root>/board/`,见 `eo-shared/board-github.md` 与下文 `sync` 段 |
      | `board.stub_dir` | string | ❌(默认 `"board"`) | **存量字段**(首选 `sync.obsidian.stub_dir`)。stub 目录名(相对 `project_root`) |
      | `github.issue` | bool | ❌(默认 `false`) | **存量字段**(首选 `sync.github.issue`)。change ↔ GitHub issue 联动开关 |
      | `github.pr` | `"auto"` \| `"always"` \| `"never"` | ❌(默认 `"never"`) | **存量字段**(首选 `sync.github.pr`)。archive 时的 PR 策略:`auto` = 在非默认分支且有 remote 时自动建 PR |
      | `sync` | object \| null | ❌ | **首选**(init 新配置写本段,存量 `board`/`github` 仅存量兼容)。`eo-sync` 适配器启用制。**键存在性决定是否回落**:缺省(键不在)→ 由 `board`/`github` 兼容映射派生;键存在(含空 `{}` 或显式 `null`)→ 完全以其为准、绝不回落,其中 `{}`/`null` = 显式零目标;object 以外的类型(数字/字符串等)→ 配置错误。schema 见下 |
      | `state` | object | ❌ | state 现状文档层启用制。键缺失 = 未表态(init 走问答);`{"enabled": true}` 启用,`{"enabled": false}` 显式关闭不再询问。schema 见下 |
      
      缺省 `board` / `github` 字段 = 全部关闭(存量项目兼容映射照常生效;新配置不含这两段)。
      
      ### `sync` 段(eo-sync 适配器启用制)
      
      `eo-sync` 的投影目标由 `sync` 段显式启用——**发现 ≠ 执行**:PATH 上的 `eo-sync-*` 可执行文件负责「有哪些」,`sync` 段负责「启用哪些 + 参数」(这也是第三方可执行文件的信任边界)。
      
      ```json
      {
        "sync": {
          "obsidian": { "enabled": true, "stub_dir": "board" },
          "github":   { "enabled": true, "issue": true, "pr": "auto" },
          "notion":   { "enabled": false, "database_id": "..." }
        }
      }
      ```
      
      | 键 | 说明 |
      |----|------|
      | `sync.<name>.enabled` | bool,仅 `true` 的适配器会被 `eo-sync run` 执行 |
      | `sync.<name>.<其它>` | 该适配器的自定义参数,`enabled` 之外的键原样透传给适配器 |
      
      **兼容映射**:以**键是否存在**判定(非「值是否非空」)——合并配置**无** `sync` 键时由存量 `board` / `github` 段等价派生启用集(`board.enabled`→`obsidian`、`github.issue`/`pr`→`github`);`sync` 键**存在**(含空 `{}` 或显式 `null`)则完全以其为准、不与 `board`/`github` 深合并,其中 `{}`/`null` 是用户显式选择的零目标(绝不回落存量段);`sync` 值为 object 以外的类型 → 配置校验失败(不静默降级)。存量项目无需改配置即按等价映射生效。Init 新配置只写 `sync` 段,重跑 init(1.5 分支)对仅有旧段的项目提示并代写等价 `sync` 段(旧段保留不删)。协议契约见 [../../docs/sync-adapter-protocol.md](../../docs/sync-adapter-protocol.md)。
      ### `state` 段(state 现状文档层)
      
      `eo-doc/state/` 现状篇(业务现状活文档,代码为唯一信源)是否启用,由 `state` 段显式表达:
      
      ```json
      { "state": { "enabled": true } }
      ```
      
      - 键缺失 = 未表态——init(首建与 1.5 分支)按封闭选择协议问一次,结论落本段
      - `enabled: true`:`/eo-doc-manager sync` 按 cursor 增量再生 `state/` 现状篇(`eo-doc/.sync-cursor` 记录游标);archive 收口自动联动
      - `enabled: false`:显式关闭,不再询问;存量 `state/` 目录冻结留存(不删除)
      - `enabled` 非 bool 或 `state` 值为 object 以外类型 → 配置校验失败
      - 团队共享字段(文档层偏好是团队口径),不进 `.eo-project.local.json` 的机器相关覆盖清单
      
      **设计约束**:
      - `project_root` **生成时**永远写绝对路径,skill 一律走 `project_root`。
      - **读取层归一化**(存量兼容):合并结果的 `project_root` 是相对路径时(存量常写成软链相对路径),读取层按 repo root 解析并解软链,得到已存在的目录即放行并在 stderr 告警一行;解析不到已存在目录则仍按配置校验失败处理(不猜、不静默放行)。下游拿到的 `project_root` 恒为绝对路径,消费方无需感知。重跑 `/eo-project-init` 会把它回写成绝对路径(落点按 local 优先规则)。
      - `.eo-project.json` 本身**提交到仓库**(团队共享配置);`.eo-project.local.json` **不提交**(`eo-project-init` 默认写入 `.gitignore`)。
      - 必填校验以**合并结果**为准——单个文件不要求自包含。
      
      ## `<repo>/.eo-project.local.json`(项目级个人覆盖,可选)
      
      **动机**:`.eo-project.json` 提交进仓库,但 `project_root`(绝对路径)、`mode`、`sync` 因人/机器而异——协作者 clone 后拿到的是别人机器上的路径。local 文件承载这些机器相关字段,共享文件只留团队口径。
      
      **规则**:
      
      - 与 `.eo-project.json` **同目录**;schema 相同,**所有字段可选**。
      - **顶层浅合并**,local 优先:local 出现的顶层字段整段覆盖共享文件的同名字段(`sync` 及 存量 `board` / `github` 是对象也**整段覆盖**,不做深合并)。
      - 团队仓库的 `.eo-project.json` 可只保留共享字段(`project_name` / `doc_root`),机器相关字段(`project_root` / `mode` / `sync`)由每人的 local 文件提供。
      - **字段写回**(如 sync 段后开补齐,见 `eo-shared/board-github.md`):该顶层字段已存在于 local 文件 → 写 local(写共享文件会被覆盖屏蔽);否则写 `.eo-project.json`。
      
      ## Skill 启动时的配置解析流程
      
      **除 `eo-project-init` 外的所有 eo-* skill 启动时:**
      
      1. 从 cwd 向上查找 `.eo-project.json`(到文件系统根为止)
      2. 找不到 → 报错并退出:
         ```
         ❌ 未找到 .eo-project.json
         请先运行 /eo-project-init 初始化项目。
         ```
      3. 找到 → 解析其内容;**同目录存在 `.eo-project.local.json` 时先做顶层字段覆盖合并(local 优先)**,后续一律用合并结果中的路径(**不读用户级文件**)
      4. 合并结果缺必填字段(`project_root` / `mode` 等)→ 报错并提示运行 `/eo-project-init`(协作者 clone 场景见其「协作者接入」分支)
      
      **`eo-project-init` 的启动行为更特殊**:
      1. 先看 cwd 向上是否已有 `.eo-project.json`(已初始化过 → 走「1.5 更新/修复分支」)。
      2. 未初始化 → 进入首次创建流程(见 `eo-project-init/SKILL.md`)。
      
      ## 目录结构参考
      
      ### 代码侧(仓库内 `<doc_root>/`,默认 `eo-doc/`)
      
      `eo-doc-manager init` 建最小骨架:
      
      ```
      eo-doc/
      ├── changes/          # 必建,change 工件流
      ├── agent-handbook/   # 可选,Agent 操作手册(篇目含 INDEX.md)
      └── templates/        # 必建(空),eo-* 扩展点
      ```
      
      ### 项目管理侧(`project_root/`)
      
      `eo-project-init` 建最小骨架:
      
      ```
      <project_root>/
      ├── roadmap.md     # 必建(frontmatter 含 status/phase/summary,Bases 项目总览按此聚合)
      ├── backlog/       # 按需,待办/灵感卡片(每条一文件,status: backlog 上看板;archive/ 存归档卡)
      ├── phases/        # 按需,roadmap 拆解后生成
      ├── decisions/     # 按需,首次记录决策时建
      ├── lessons/       # 按需,首次记录经验时建(**项目级**,替代全局 _lessons/)
      ├── brainstorm/    # 按需,eo-brainstorming 首次产出时建
      ├── board/         # 按需,change 看板 stub(sync.obsidian(或存量 board.enabled)启用时由 eo-sync 投影维护)
      ├── research/      # 按需,调研沉淀(带 INDEX + frontmatter;eo-recall / eo-change 事实自查消费)
      └── docs/          # 按需,原始 PRD / 设计 / 规划
      ```
      
      `.eo-project/`(即 `project_root`)**缺省随仓库提交**——管理侧是协作者最需要的项目记忆;用户明确不想提交时才追加进 `.gitignore`。
      
    • handbook-templates.md 2.2 KB
      # Handbook 模板机制
      
      `eo-doc/agent-handbook/` 的篇目内容从模板生成:一套模板 = 一个 preset 目录,init 按项目信号匹配候选,用户确认后合并生成。handbook 定位:规范性、方向性、非 SSOT(代码为准)、不挂自动同步。
      
      ## 两个库
      
      | 库 | 位置 | 来源 |
      |----|------|------|
      | 内置库 | `eo-project-init/templates/handbook/<preset>/` | 随整套 skill 软链分发 |
      | 私有库 | `"${EO_HOME:-$HOME/.eo}/handbook-templates/<preset>/"` | 用户手工维护 |
      
      同名 preset **私有库整套覆盖内置库**(按 preset 粒度替换,不做文件级合并)。
      
      ## 一套 preset 的结构
      
      ```
      <preset>/
      ├── manifest.md   # frontmatter 声明适用信号与简介
      ├── INDEX.md      # handbook 索引(篇目表 + 待补区)
      └── <篇目>.md     # 篇目文件组
      ```
      
      `manifest.md` frontmatter:
      
      ```yaml
      ---
      name: general             # preset 名,与目录名一致
      summary: 一句话简介        # 封闭选择时展示给用户
      signals: []               # 适用信号:相对仓库根的文件路径或 glob 列表
      ---
      ```
      
      - signals 逐条在仓库根探测:文件路径存在、或 glob 有匹配,任一命中即该 preset 成为候选
      - **空 signals 不参与命中**,仅在无其他候选时作为缺省候选
      
      ## 匹配与生成
      
      **已有项目**(生成 = 匹配合并,不是裸 copy):
      
      1. 五面扫描(lint/commit 配置、`git log` 归纳的 commit 规律、目录结构、架构分工、UI token 用法)产出实证
      2. 取两个库的 preset 集合(同名取私有库版本),按 signals 命中候选
      3. 按封闭选择协议确认用哪套(含「不用模板」——纯按实证落盘)
      4. 合并生成:实证 > 模板 > 待补——模板篇目为底,扫描实证覆盖冲突项,扫描不到依据的标「待补」;已配置文件化的只落一行指针(指向配置文件)
      5. worktree 协作与 codegraph 使用两篇逐个询问授权后才写入(comments 注释纪律随 preset 默认生成;AGENTS.md 注入段有其硬入口指针)
      
      **空项目**:无实证可扫;询问项目类型,选定 preset 纯 copy(「待补」占位随项目成形后补齐)。
      
    • migrate-v1.md 2.8 KB
      # v1 项目迁移子流程(由 1.5 更新/修复分支触发)
      
      > 检测到 v1 痕迹时执行。全程**幂等**、逐项汇报;除明确列出的写入外不动任何存量内容。人类背景版见仓库 docs/migration-v1-to-v2.md(本文件是可执行版,两者以本文件为准)。
      
      ## 触发信号(任一命中即进入本流程)
      
      - `eo-doc/dev/` 目录存在(v1 模块维度)
      - `.eo-project.json` 的 `kanban_path` 为非 null 字符串
      - `<project_root>/log.md` 存在且 `eo-doc/changes/` 不存在
      - `<project_root>/backlog.md`(或 backlog/todo.md 等扁平文件)存在且未标注「已迁移」
      
      ## 迁移步骤
      
      1. **冻结存量 spec**:对每个 `eo-doc/dev/<module>/spec.md` 与 `spec-history.md`,frontmatter 补 `status: frozen`(已有则跳过)。它们保留作历史参考,v2 任何 skill 不再读写。
      2. **建项目级 changes/**:`eo-doc/changes/INDEX.md` 不存在则创建;`seq` 起始号 = 扫描全部 `dev/*/changes/` 取最大 `NNN` + 1(新 change 按 v2 规则:slug 即 id,seq 只是显示别名,见 eo-shared/conventions.md §2);INDEX 顶部加一行注记「此号之前的历史 change 见 `dev/<module>/changes/`(v1 存量,原地保留)」。
      3. **在途 change 盘点**:列出旧目录里 status 非 archived 的 change,逐个告知:「走完余下生命周期即可(implement/test/review 照旧),**归档按现行 `/eo-archive` 执行**——不合并 Delta,直接结算 commit + 冻结」。不迁移文件位置。
      4. **kanban 退役**:`kanban_path` 非 null → 改写为 `null`,提示「旧手工看板已退役,看板文件(如 00-Wiki/项目看板.md 中本项目条目)可自行归档删除;项目级总览改由 Bases 聚合 roadmap frontmatter」。
      5. **roadmap frontmatter 补齐**:`roadmap.md` 缺 `status` / `phase` / `summary` 字段的,从正文推断补写(推断不出的问一次);`status` 枚举 `active | researching | paused | done`。
      6. **log.md 处置**:存在则提示「v2 不再写入 log.md,时间线由 changes/INDEX + git log 承担;文件可留存或归档」,不删除。
      7. **lessons 存量**:`lessons/` 有文件但无 INDEX.md → 提示「跑 `/eo-project-record` 的 reindex 补建检索锚点与索引」;decisions/ 同理。
      8. **backlog 打散**:存在旧扁平 `backlog.md`(或 backlog/todo.md 等)→ 按 /eo-backlog 的 migrate 动作把未完成条目打散成卡片(created 取原日期、行内 #tag 转 tags),已完成/放弃条目留存原文件,原文件顶部标注「已迁移」。
      
      ## 收尾
      
      汇报迁移清单(冻结 N 个 spec / changes 起始编号 / 在途 change 数 / kanban 状态 / roadmap 补了什么),然后**继续 1.5 分支的常规步骤**(配置校验、骨架补齐、注入刷新、gitignore 核对、sync 联动问答)。
      
    • roadmap-breakdown.md 7.4 KB
      # Roadmap 拆解方法论
      
      当 `eo-project-init` 需要从 PRD/MVP 文档或口头描述拆解出 roadmap 和 phase 时,读取本文件指导拆解过程。
      
      ---
      
      ## 核心取向:阶段性可验收
      
      拆 phase 时手里只有一把尺子:**每个阶段结束时,用户能验收什么。**
      
      验收的意思是:有人能打开真实界面、做一次真实操作、看到一个完整场景从头到尾跑通——哪怕这个场景很窄。做商城,先把"商品目录"从前端到后端打通(API 可以是 mock 的),能浏览、能点进去看详情,这就是一个可验收的阶段;接着再做"下单"。反过来,"用户体系和权限做完了,用 curl 都能调通"**不是**可验收的阶段——它只证明某一层在动。
      
      判断有没有切对,问一个问题:这个阶段结束时,**验收动作越接近最终用户的真实操作,切得越对;越依赖命令行、测试脚本、API 调试器,越可能是横切了**。横切(把一整层做完再做下一层)是 roadmap 里最贵的错误:进度一直在走,但没有任何时刻能端到端看一眼,所有返工都堆在最后爆发。
      
      这不排斥先后偏重。后端可以比前端先走半个身位,框架和骨架可以先搭——但骨架的验收物是"能打开的页面",不是"配好的脚手架";层与层的差距以"一个阶段内能合拢"为限。超出这个差距的领先不是进度,是库存。
      
      ---
      
      ## 拆解思维框架
      
      ### 第零步:前提质询
      
      动手拆之前,先回头质疑需求本身:
      
      1. **还原根本问题**:把「要做 X」还原成「要解决 Y」——X 是某人已经给好的解法,Y 才是拆解的输入。问:这个需求背后,用户真正痛的是什么?
      2. **审计隐含前提**:需求陈述里藏着哪些假设(用户真的需要、现有能力撑不住、必须现在做、必须自己造)?逐条问「这个前提有证据吗」
      3. **消解优先**:能不能不做、用现有能力拼、或改流程而不是造系统?最好的拆解是让需求变小的拆解
      
      质询不落文档,落的是拆解起点的修正——前提站不住时,把疑问按提问纪律抛回用户,钉完再拆。
      
      ### 第一步:明确终态
      
      在动手拆之前,先回答一个问题:
      
      > **这个项目做完,用户能做到什么之前做不到的事?**
      
      不是"实现了什么功能",而是"改变了什么行为/能力"。这决定了 roadmap 的终点。
      
      示例:
      - ❌ "完成小程序开发" → 太模糊
      - ✅ "用户能通过微信搜索找到我的小程序并付费使用" → 明确的终态
      
      ### 第二步:逆向拆解里程碑
      
      从终态往回推,找出 **必须经过的中间状态**(里程碑),每个里程碑是一个可验证的"能做到":
      
      ```
      终态:用户付费使用
        ← 里程碑 3:有用户来(流量获取)
          ← 里程碑 2:能被找到(上线发布)
            ← 里程碑 1:能跑起来(MVP 可用)
              ← 起点:有想法
      ```
      
      **里程碑的标准**:
      - 可以 demo / 可以截图 / 可以测量——demo 的主角是用户不是工程师,能截图的是界面不是终端
      - 不依赖后续里程碑就有独立价值——价值对用户可见,不是只对架构可见
      - 如果项目在这里停下,之前的工作不浪费
      
      ### 第三步:里程碑 → Phase
      
      每个里程碑对应一个 Phase。Phase 数量控制在 **2-5 个**:
      
      | 数量 | 判断 |
      |------|------|
      | 只有 1 个 | 项目太小,不需要 roadmap,直接做 |
      | 2-3 个 | 正常项目 |
      | 4-5 个 | 大项目,检查是否能合并 |
      | >5 个 | 太细了,合并或拆成多个项目 |
      
      ### 第四步:Phase 内任务拆解
      
      每个 Phase 内部拆任务,遵循 **MECE 原则**(互不重叠、完全穷尽):
      
      1. **先列交付物**:这个 Phase 结束时,产出什么?
      2. **再列依赖链**:要产出这些,必须先做什么?
      3. **最后排序**:有依赖关系的按序,无依赖的并行标注
      
      任务粒度标准:
      - **太粗**:"开发后端" → 拆
      - **刚好**:"实现用户登录接口" → ✅
      - **太细**:"写第 3 行代码" → 合并
      
      经验法则:每个任务 **0.5-2 天**可完成。
      
      ---
      
      ## 拆解质量检查
      
      拆完后,过一遍检查清单:
      
      ### Roadmap 层面
      - [ ] 终态清晰,一句话能说明白
      - [ ] Phase 之间有明确的先后依赖(不是随意排序)
      - [ ] 每个 Phase 独立可交付(如果后面不做了,前面的成果仍有价值)
      - [ ] 总 Phase 数 2-5 个
      
      ### Phase 层面
      - [ ] 每个 Phase 有明确的"完成标志"(怎么判断这个阶段做完了)
      - [ ] 任务清单覆盖了所有交付物所需的工作
      - [ ] 没有"万能任务"(如"其他工作"、"收尾")
      - [ ] 每个任务 0.5-2 天粒度
      
      ### 常见陷阱
      - **横切(最贵)**:按层拆——"先做完用户体系/安全/权限,再做业务功能"。进度一直在走,但没有任何时刻能端到端验收,前端长期空壳、返工堆在最后爆发 → 按完整场景切,每层只做到支撑当前场景所需的厚度
      - **前期堆积**:把所有"基础设施"放 Phase 1 → 用户迟迟看不到价值(横切的变种)
      - **平行铺开**:所有功能同时推进 → 没有一个先完整可用
      - **完美主义**:Phase 1 就想做到 100% → MVP 思维缺失
      
      ---
      
      ## 拆解对话流程
      
      **有 UI 的项目,开拆之前先建议把"长什么样"钉下来**:花一轮建立 design token 和高保真对比稿(走 `/eo-design` variants 出 HTML 对比页),把 UI/UX 操作方式用图钉死再拆——一张对比图暴露的分歧比十轮文字描述多;而且前端定下来之后,后端要支撑哪些操作、什么数据形态往往会自己浮出来,拆解的输入从猜测变成事实。这是建议不是前置:纯后端/工具类项目没有这一步,UI 方向已经很稳的也可以直接拆。
      
      与用户对话时的节奏:
      
      ### 1. 确认终态(1 轮)
      > "这个项目做完,你希望达到什么效果?"
      
      ### 2. 逆推里程碑(1-2 轮)
      > "要达到这个效果,之前必须先做到什么?再往前呢?"
      
      展示逆推出的里程碑链,让用户确认。
      
      ### 3. 展示 Phase 划分(1 轮)
      > 根据里程碑生成 Phase 表格:
      
      ```markdown
      | Phase | 目标 | 交付物 | 预估时间 |
      |-------|------|--------|----------|
      | 1 - MVP | 核心功能可用 | 可运行的最小版本 | 1-2 周 |
      | 2 - 上线 | 用户可访问 | 备案 + 审核通过 | 1-3 周 |
      | 3 - 增长 | 有人用 | 引流内容 + 数据验证 | 2-4 周 |
      ```
      
      ### 4. 确认后拆任务(1 轮)
      > 逐个 Phase 展开任务清单,格式用 `- [ ]`。
      
      ### 5. 用户确认 → 写入文件
      
      **整个过程不超过 5 轮对话**。避免过度讨论——先落地,再迭代。
      
      ---
      
      ## 不同项目类型的拆解模板
      
      ### 软件产品
      ```
      Phase 1: MVP(核心功能跑通)
      Phase 2: 合规上线(备案/审核/发布)
      Phase 3: 增长验证(获客 + 数据反馈)
      Phase 4: 迭代优化(基于数据改进)
      ```
      
      ### 内容/课程项目
      ```
      Phase 1: 框架设计(大纲 + 前 N 节内容)
      Phase 2: 内容生产(完成全部内容)
      Phase 3: 分发上线(平台发布 + 推广)
      ```
      
      ### 调研/学习项目
      ```
      Phase 1: 信息收集(素材 + 对标分析)
      Phase 2: 知识整理(结构化 + 提炼)
      Phase 3: 输出成果(报告/文章/分享)
      ```
      
      ### 自动化/工具项目
      ```
      Phase 1: 手动验证(人工跑通流程)
      Phase 2: 半自动化(脚本辅助核心步骤)
      Phase 3: 全自动化(端到端无人值守)
      ```
      
  • templates
    • handbook
      • general
        • architecture.md 222 B
          # 架构分工
          
          ## 分层
          
          - 待补:本仓分层与各层职责(层名(路径):职责)
          
          ## 修改纪律
          
          - 待补:跨层改动约束、口径单一来源等
          
          **何时读**:新增或修改核心模块前。
          
        • comments.md 1.9 KB
          # 注释纪律
          
          代码是真相源,注释是它的补丁——只在代码表达不了时才写。本篇约束**一切**代码改动,无论改动是否经过 eo 流程。
          
          ## 写什么
          
          注释只写**代码本身表达不了的约束**:
          
          - 不变量(「此列表按 created 升序,下游依赖该顺序」)
          - 反直觉的坑(「这里必须先 flush 再 close,顺序反了会丢尾包」)
          - 外部契约(「依赖方 X 要求该字段非空」)
          
          一两行为限;不复述代码在做什么;不向审查者解释这次改动为何正确——正确性辩护属于 commit message 与对话汇报。密度对齐所在文件的既有风格。
          
          ## 不写什么
          
          - **复述代码**:`i++ // 递增 i` 类纯噪声
          - **流程溯源标注**:change 编号/slug、TODO/AC 编号、review finding(P0-x/P1-x)、FAIL-x、批次/阶段号、revision 号——文件↔change 的对应由 commit 前缀 `[<change-id>]` 承载(git blame 即得),归档后这些标记对读代码的人毫无意义,只会腐烂。判据看语义不看字面:领域术语恰与 change slug 同名的正常约束注释不违规(如 slug 为 `cache-invalidation` 时描述缓存失效契约的注释照写)
          - **叙事辩护**:「为何这样改是对的」属于 commit message,不属于注释
          
          ## 存量清理(顺手原则)
          
          编辑代码时,对路过区域的存量注释:
          
          1. 注释与代码矛盾 → **以代码为准**,就地修正或删除该注释
          2. 过时/误导性注释 → 顺手删除,不专列清理任务
          3. 拿不准注释是否仍成立 → 视为误导,删——正确信息在代码与 git 历史里
          
          动机:过时注释比没有注释更贵——它消耗每个读者的 token 与信任。
          
          ## 项目例外
          
          - 待补(按项目补充:合规/审计要求保留的注释、自动生成代码的标记注释等)
          
          **何时读**:编辑任何代码前。
          
        • commit.md 729 B
          # Commit 规范
          
          单一来源:eo-shared/conventions.md §2.5。
          
          ## 成文前缀(conventions.md §2.5)
          
          | 场景 | 前缀 | 例 |
          |------|------|-----|
          | change 相关提交(测试锁定 / implement 批次 / archive 结算) | `[<slug>]` | `[<slug>] <一句话说清改了什么>` |
          | 直改:bug 小修 | `fix:` | `fix: <一句话>` |
          | 直改:UI / 样式 / 文案 | `ui:` | `ui: <一句话>` |
          
          - 正文中文短句,一句话说清改了什么
          - seq 绝不进 commit message;slug 随首个 commit 落地后不改名
          - 前缀不因活跃 change 改向:trivial 直改仍走 `fix:` / `ui:`
          
          ## 观察到但未入表的前缀
          
          - 待补(从本仓 `git log` 归纳)
          
          **何时读**:每次提交前选前缀。
          
        • directory.md 329 B
          # 目录职责边界
          
          | 路径 | 职责 | 入库 |
          |------|------|------|
          | 待补 | 待补 | 待补 |
          
          - 管理侧(roadmap / backlog / decisions / lessons 等)不在仓内:在 `.eo-project.json` 的 `project_root`
          - 测试跑法:待补
          
          **何时读**:新文件不知道放哪、或判断某内容该不该入库时。
          
        • INDEX.md 987 B
          # Agent Handbook — 项目操作手册
          
          规范性、方向性:细节判断交运行时;非 SSOT(代码为准);不挂自动同步。
          先扫本表定位篇目,按需读,不通读。
          
          | 篇目 | 一句话 | 何时读 |
          |------|--------|--------|
          | [worktree.md](worktree.md) | 多 worktree 并行:看板/索引隔离 + commit 归集口径 | 开 worktree 并行开发前;看板出现分叉徽标时 |
          | [commit.md](commit.md) | commit 前缀规范 | 每次提交前选前缀 |
          | [comments.md](comments.md) | 注释纪律:代码为真相源、顺手清理过时注释 | 编辑任何代码前 |
          | [directory.md](directory.md) | 仓内目录职责边界与入库口径 | 新文件不知道放哪、判断该不该入库时 |
          | [architecture.md](architecture.md) | 架构分层分工与修改纪律 | 新增或修改核心模块前 |
          | [ui.md](ui.md) | UI Design Token 与组件规范 | 动样式、新增组件或颜色前 |
          
          ## 待补
          
          - 待补:扫描未覆盖的篇目
          
        • manifest.md 156 B
          ---
          name: general
          summary: 通用五篇骨架(worktree / commit / directory / architecture / ui),项目特异处留「待补」占位
          signals: []
          ---
          
        • ui.md 732 B
          # UI 规范(Design Token 与组件)
          
          待补:UI 实现位置与渲染方式一句话。
          
          ## 色彩 Token
          
          - 待补:主题方案(如 light/dark 双套 CSS 变量)、用色纪律(一律 var() 引用、状态色成对)
          
          ## 字体 / 字号 / 圆角 / 间距 / 动效
          
          - 待补
          
          ## 组件清单
          
          | 组件 | class / 渲染入口 | 用法约束 |
          |------|------------------|----------|
          | 待补 | 待补 | 待补 |
          
          ## 规范
          
          1. 新 UI 先查既有 token 与组件:能复用就不写新样式
          2. 新增颜色先进变量,禁写死色值
          3. 状态相关着色走状态色变量对,成对新增
          4. 待补:项目特有约束(依赖红线、动效兜底等)
          
          **何时读**:动样式、新增组件或颜色前。
          
        • worktree.md 1015 B
          # 多 worktree 协作规范
          
          并行 change 各自开 worktree。看板与代码索引对多 worktree 的口径如下。
          
          ## 看板(eo-board)
          
          - 同一 change id 多 worktree 并行:只出「最近活动」最新的一张卡
          - 内容实质分叉的其余变体:收进卡面「分叉×N」徽标与详情副本列表,可切换查看
          - 内容一致的副本:合并出卡,无标记
          - 状态严格低于 main worktree 的过期版本:过滤,不出卡也不计入 N
          - 卡面 branch 与 worktree 分行显示(`⎇ branch` / `worktree_name`)
          
          ## codegraph
          
          - 索引按目录隔离:存 `<dir>/.codegraph/`,不跨 worktree 共享
          - 每个 worktree 各自 `codegraph init`
          - `.codegraph/` 不入库(gitignore)
          
          ## commit 归集
          
          - change 提交前缀 `[<slug>]` 是跨 worktree 归集与 archive 结算的唯一索引
          - slug 出生查重(含 remote 兜底),口径见 eo-shared/conventions.md §2
          
          **何时读**:开 worktree 并行开发前;看板出现分叉徽标想确认口径时。
          
    • phase.md 385 B
      ---
      type: phase
      project: "{{project_name}}"
      phase: {{phase_number}}
      status: "{{phase_status}}"
      created: "{{date}}"
      updated: "{{date}}"
      ---
      
      # Phase {{phase_number}}:{{phase_name}}
      
      ## 目标
      
      {{phase_goal}}
      
      ## 验收画面
      
      {{这个阶段结束时,用户能打开什么、操作什么、看到什么——一句话}}
      
      ## 任务
      
      {{task_checklist}}
      
      ## 交付物
      
      {{deliverables}}
      
    • roadmap.md 445 B
      ---
      type: roadmap
      project: "{{project_name}}"
      status: "{{status}}"        # active | researching | paused | done —— Bases 项目总览按此聚合
      phase: "{{当前阶段一句话}}"
      summary: "{{项目目标一句话}}"
      created: "{{date}}"
      updated: "{{date}}"
      ---
      
      # {{project_name}}
      
      ## 目标
      
      {{project_goal}}
      
      ## 阶段概览
      
      | 阶段 | 目标 | 交付物 | 状态 |
      |------|------|--------|------|
      {{phase_table}}
      
      ## 备注
      
      {{notes}}
      
  • SKILL.md 16 KB
    ---
    name: eo-project-init
    description: "eo-skills 在当前仓库的总入口:生成 .eo-project.json、初始化项目管理侧(roadmap)和代码侧最小骨架(eo-doc/),以及 agent 配置注入。触发:启动项目 / 初始化项目 / 新建项目 / /eo-project-init。"
    ---
    
    # eo-project-init
    
    ## 定位
    
    **所有 eo-* skill 的总入口**。其它 skill(eo-change / eo-implement / eo-doc-manager / …)都依赖 `.eo-project.json`;未运行过本 skill 的项目无法使用其它 eo-* skill。
    
    一次 init 完成三件事:
    1. 生成 `.eo-project.json`(项目级配置,所有 skill 读它)
    2. 初始化**项目管理侧**(`<repo>/.eo-project/`)——最小骨架
    3. 初始化**代码侧** `eo-doc/` 最小骨架(内部调用 `eo-doc-manager init` 的子流程)
    
    配置与目录约定详见 [references/config.md](references/config.md)。
    
    ## 输入
    
    用户提供以下之一:
    - **PRD/MVP 文档路径**
    - **口头描述**:项目名称 + 要做什么 + 大致阶段
    - **仅项目名**:快速创建空骨架(后续再补充)
    
    可选:
    - 代码仓库路径(当前 cwd 不是代码仓库时)
    
    ## 执行步骤
    
    ### 1. 检查是否已初始化
    
    - cwd 向上已有 `.eo-project.json` → 走下方「1.5 更新/修复分支」,**不进入首次创建流程**
    - 未有 → 继续首次创建流程
    
    ### 1.5 更新/修复分支(已初始化项目重跑本 skill)
    
    对已有 `.eo-project.json` 的项目,重跑是**幂等的补齐动作**,逐项执行、已达标项静默跳过:
    
    0. **v1 痕迹检测**:发现 `eo-doc/dev/` 存在、`kanban_path` 非 null 等信号 → 先按 [references/migrate-v1.md](references/migrate-v1.md) 执行迁移子流程(冻结 spec、建项目级 changes、kanban 退役、roadmap 补 frontmatter、backlog 打散成卡等,幂等),完成后继续下列步骤
    0.5. **协作者接入(local 覆盖)**:按 config.md 规则合并同目录 `.eo-project.local.json`(如有)后,检查合并结果的 `project_root` 在本机是否存在可写。不可用(典型:clone 了别人提交的配置,`project_root` 指向他人机器上的路径)或必填字段缺失 → 按「3. 计算 `project_root`」算出本机 `project_root`,把机器相关字段(`mode` / `project_root`)写入 `.eo-project.local.json`——**不改动提交的 `.eo-project.json`**。后续步骤一律以合并结果为准
    1. **配置校验**:读现有 `.eo-project.json`(合并 local 覆盖),对照 [references/config.md](references/config.md) 的 schema——基础字段(project_name/mode/project_root/doc_root)缺失按默认补写;存量配置的 `kanban_path` 字段忽略不改,已有字段一律不改;**`project_root` 非绝对路径(存量形态)是可修项**——按 repo root 解析并解软链后**回写绝对路径**并提示用户(写回落点沿用既有规则:该顶层字段已存在于 `.eo-project.local.json` → 写 local,否则写 `.eo-project.json`);解析不出已存在目录时不猜,转「3. 计算 `project_root`」重新算出;**`sync` 段(或其适配器键)与 `state` 键缺失时不在本步补写**(补了显式关闭条目会吞掉第 5 步的询问),只记录缺失,留给第 5 步问答/迁移后落盘
    2. **骨架补齐**:项目管理侧必建 roadmap.md 与代码侧 `eo-doc/` 骨架缺什么补什么;**不触碰任何已有文件的内容**
    3. **注入段刷新**:按标记整段刷新 agent 配置文件中的 `eo-project` / `eo-doc` / `eo-reply-contract` 注入段(存在则整段替换,缺失则补注);仓库根存在 `DESIGN.md` 时核对 `eo-design` 注入段
    4. **.gitignore 核对**:`tmp/eo/`、`.eo-project.local.json` 缺项补写;`.eo-project/` 的 ignore 状态**保持现状不核对**——已 ignore 的不删行、未 ignore 的不补写
    5. **sync / state 联动问答与存量迁移**(仅合并配置 `sync` 段缺对应适配器键时问,规则见「7. 生成 .eo-project.json」的 sync 段小节)。**存量迁移**:检测到旧 `board` / `github` 段且合并配置无 `sync` 键 → 提示用户并**代写等价 `sync` 段**(启用集与兼容映射派生结果逐项一致;旧段问答已答过的适配器写显式条目——含关闭态,**不重问**;**旧段保留不删**,旧版工具仍可读);已有 `sync` 键 → **零动作**零提示
       **state 问答**(仅合并配置无 `state` 键时问,规则见「7. 生成 .eo-project.json」的 state 段小节):检测到存量 `eo-doc/state/` → 问「恢复维护(推荐)/ 保持冻结」,结论写 `state.enabled` true/false;无存量 `state/` → 按 §7 同一问(推荐关闭);已有 `state` 键 → **零动作**零提示
    5.5. **顺手注册**:执行 `eo-board --register`(幂等,已注册则原地更新)。**失败不阻塞本流程**——注册失败时输出告警并给手工补注册指引:「⚠ 项目注册失败(<原因>),init 已正常完成;稍后可在项目目录手工执行 `eo-board --register` 补注册(注册后任意目录 `eo-board --all` 可见本项目)」
    6. **输出摘要**:列出本次补齐/刷新/跳过了什么(含注册结果),然后结束——不执行首次创建流程的其余步骤
    
    ### 2. 解析项目信息
    
    从输入中提取:
    - **项目名称**(`project_name`)
    - **项目目标**:一句话描述
    - **初始状态**:`active` / `researching`
    
    ### 3. 计算 `project_root`
    
    `project_root` = `<repo>/.eo-project/`。
    
    检查 `project_root` 是否已存在:
    - 存在且含 `roadmap.md` → 按封闭选择协议三选一:1) 只建代码侧关联(推荐)2) 更新 roadmap 3) 重建(需确认)
    - 存在但无 `roadmap.md` → 异常,提示补全后进入拆解
    - 不存在 → 正常创建
    
    ### 4. 创建项目管理侧骨架(最小)
    
    ```
    <project_root>/
    └── roadmap.md     # 必建
    ```
    
    **按需目录一律不预建**(backlog / phases / decisions / lessons / brainstorm / docs),等对应 skill 首次写入时由那个 skill 创建(backlog 为卡片目录,由 /eo-backlog 管理)。
    
    写入 `roadmap.md`(读 [templates/roadmap.md](templates/roadmap.md)),填充项目名、目标、阶段概览占位。
    
    ### 5. Roadmap 拆解(可选)
    
    如果用户提供了 PRD/MVP 或愿意拆解:
    1. 读取 [references/roadmap-breakdown.md](references/roadmap-breakdown.md) 方法论
    2. 与用户对话(不超过 5 轮):终态 → 里程碑 → Phase → 任务
    3. 用户确认后,**lazy 创建** `phases/` 目录,每个阶段一个文件(读 [templates/phase.md](templates/phase.md))
    4. 更新 `roadmap.md` 的阶段概览表
    
    仅"快速创建空骨架"时可跳过此步。
    
    ### 6. 初始化代码侧 `eo-doc/`(内部调用 eo-doc-manager init 子流程)
    
    在代码仓库根目录创建**最小骨架**:
    
    ```
    eo-doc/
    ├── changes/INDEX.md          # 骨架
    ├── agent-handbook/INDEX.md   # 骨架(篇目内容见 §6.5)
    └── templates/                # 空目录
    ```
    
    额外:
    - 询问是否启用 codegraph:启用则在仓库根执行 `codegraph init` 建索引,并把使用规范(索引按项目目录隔离,每个 worktree 需各自 `codegraph init`)写入 agent-handbook;不启用则跳过
    - 将 `tmp/eo/` 追加到 `.gitignore`(tmp/eo/ 是各 skill 的临时工件命名空间,见 [../eo-shared/conventions.md](../eo-shared/conventions.md))
    - 将 `.eo-project.local.json` 追加到 `.gitignore`(个人/机器覆盖文件不提交,见 [references/config.md](references/config.md))
    - CLAUDE.md 注入(详见 [../eo-doc-manager/references/claude-injection.md](../eo-doc-manager/references/claude-injection.md))
    
    **注意**:如果用户本次只想要项目管理侧(例如纯规划项目,没代码),可用 `--skip-code-side` 跳过本节。此时 `doc_root` 字段仍写入配置,留待将来补建。
    
    ### 6.5 Handbook 初始化(可选,逐步授权)
    
    `eo-doc/agent-handbook/` 是 Agent 操作手册:相对固定的操作规范,非 SSOT(代码为准),不挂自动同步;骨架由 §6 建好,是否填内容询问用户,同意才继续。模板机制(库位置 / manifest 格式 / 匹配合并细则)见 [references/handbook-templates.md](references/handbook-templates.md)。
    
    **已有项目**(生成 = 匹配合并,不是裸 copy):
    1. 派子 agent 扫描五个面:lint/commit 配置、`git log` 归纳的 commit 规律、目录结构、架构分工、UI token 用法
    2. 按 manifest signals 匹配候选 preset(私有库优先),按封闭选择协议确认(含「不用模板」)
    3. 合并生成:实证 > 模板 > 待补——模板篇目为底,扫描实证覆盖冲突项,扫描不到依据的标「待补」;已配置文件化的只落一行指针(指向配置文件)
    4. worktree 协作与 codegraph 使用两篇逐个询问授权后才写入(comments 注释纪律随 preset 默认生成,无需单独授权)
    
    **空项目**:询问项目类型,选定 preset 纯 copy。
    
    ### 7. 生成 `.eo-project.json`
    
    在**代码仓库根目录**写入:
    
    ```json
    {
      "project_name": "{{project_name}}",
      "mode": "local",
      "project_root": "{{absolute_path_to_project_root}}",
      "doc_root": "eo-doc",
      "kanban_path": null
    }
    ```
    
    `kanban_path`:固定写 `null`;存量配置该字段被所有 skill 忽略。项目级总览由 Bases 聚合各项目 roadmap.md 的 frontmatter 承担。
    
    **协作/多机场景**:机器相关字段(`project_root` / `mode` / `sync`——顶层段整段覆盖)可拆到不提交的 `.eo-project.local.json`(顶层字段覆盖合并,规则见 [references/config.md](references/config.md))。首次 init 默认全部写入 `.eo-project.json` 即可;协作者 clone 后重跑本 skill 走「1.5 更新/修复分支」的协作者接入步骤生成 local 覆盖。
    
    **sync 段**(投影开关,`eo-sync` 直接消费——机制见 [../eo-shared/board-github.md](../eo-shared/board-github.md),schema 见 [references/config.md](references/config.md);新配置只写 `sync` 段本身,存量 `board` / `github` 段由兼容映射护住):按封闭选择协议问一次(触发判据 = 合并配置 `sync` 段缺对应适配器键)——
    - github 适配器(检测到 git remote 指向 GitHub 时才问;pr 推荐 `auto`):写 `sync.github = {"enabled": true, "issue": <bool>, "pr": "auto"|"always"|"never"}`
    
    用户跳过 → 对应适配器写显式关闭条目(`{"enabled": false}`),后续 skill 不再询问。**后开场景**:对已初始化项目重跑本 skill 走「1.5 更新/修复分支」,其第 5 步提供这一问。
    **state 段**(现状文档层开关,`/eo-doc-manager sync` 与 archive 联动直接消费,schema 见 [references/config.md](references/config.md)):按封闭选择协议问一次(触发判据 = 合并配置无 `state` 键)——「启用 state 现状文档层?」(推荐**关闭**:保持精简,需要「系统现在是什么样」活文档的项目再开)。启用 → 写 `state.enabled: true` 并建 `eo-doc/state/`(空目录,首篇由 `/eo-doc-manager sync` 生成);跳过/拒绝 → 写显式 `{"enabled": false}`,后续不再询问。
    
    ### 8. 处理 `.eo-project/`
    
    `.eo-project/` 即 `project_root`。**缺省随仓库提交,不写入 `.gitignore`**——roadmap / backlog / decisions / lessons 是协作者最需要的项目记忆,跟代码走。
    
    仅当用户明确表示不想提交管理侧时,当场追加:
    
    ```
    # eo-project local management side
    .eo-project/
    ```
    
    ### 9. Agent 配置注入
    
    检测代码仓库使用的 agent 配置文件(顺序):
    1. `CLAUDE.md`
    2. `AGENTS.md`
    3. `COPILOT.md`
    4. `CURSOR.md`
    5. 都不存在 → 按封闭选择协议问创建哪个(推荐 CLAUDE.md)
    
    注入两个标记段(均幂等、整段替换):
    
    **1. 项目上下文段**(`<!-- eo-project:start/end -->`):
    
    ```markdown
    <!-- eo-project:start -->
    ## EO-Project
    
    本项目已接入 eo-skills。项目管理侧(roadmap / backlog 卡片 / decisions / lessons 等)位置从 `.eo-project.json` 的 `project_root` 字段解析(同目录存在 `.eo-project.local.json` 时顶层字段覆盖,local 优先),下文记作 `<project_root>`。
    
    - 代码侧文档:`{{doc_root}}/`
    
    ### 项目记录入口
    
    仅当**用户明确表达**要记录时响应(不做关键词嗅探,避免误触发):
    
    - 用户明确说「加个待办 / 记到 backlog / 以后做」→ 调用 `/eo-backlog` 写卡到 `<project_root>/backlog/`
    - 用户明确说「把这个决策记下来」→ 调用 `/eo-project-record` 写入 `<project_root>/decisions/`
    - 用户明确说「记一条经验 / 踩坑记录一下」→ 调用 `/eo-project-record` 写入 `<project_root>/lessons/`
    
    对话中出现疑似待办/决策/教训但用户未明说时,**至多在当前话题收尾处轻提一句**「要不要记入 backlog/decisions/lessons?」,不打断进行中的工作。
    <!-- eo-project:end -->
    ```
    
    **2. 回复契约段**(`<!-- eo-reply-contract:start/end -->`):
    
    ```markdown
    <!-- eo-reply-contract:start -->
    ## 回复契约(长任务收尾)
    
    长开发任务收尾时,用一段人话向用户汇报,四条各一句:
    
    1. **做了什么**——行为变化,不是 diff 清单
    2. **为什么这么做**——关键决策与理由,被否掉的方案一并点名
    3. **主要产出**——文件 / 功能 / 命令,用户去哪看、怎么验
    4. **遇到的问题与解法**——没有就明说「无」
    
    受众分两层:对开发者讲接口与路径,对需求方讲行为与结果。一句一事,不铺陈过程。
    <!-- eo-reply-contract:end -->
    ```
    
    段内正文以 [../eo-shared/reply-contract.md](../eo-shared/reply-contract.md)「契约正文」为单一来源,整段搬运不改写——注入是被动兜底通道(覆盖非 eo 流程的直改收尾);eo 流程收尾的硬步骤(eo-archive 交付汇报 / eo-loop 线段收尾报告)以该文「生效通道」为准。
    
    **模板纪律**:项目上下文段**不内联** `project_root` 绝对路径——它因人/机器而异且 agent 配置文件提交进仓库,内联会把个人路径泄进 git 并在协作者机器上失真。运行时一律从配置合并结果解析。
    
    **DESIGN.md 检查**:若仓库根存在 `DESIGN.md` 但 agent 配置文件中无 `<!-- eo-design:start -->` 标记段,执行 `/eo-design` 的约束注入子步骤补上(注入模板见 [../eo-design/references/design-md-template.md](../eo-design/references/design-md-template.md))。
    
    ### 10. 注册到生态注册表(顺手注册)
    
    执行 `eo-board --register`(在仓库根目录),把项目登记进用户级注册表 `${EO_HOME:-$HOME/.eo}/projects.json`,供 `eo-board --all` / `eo-sync watch --all` 跨项目枚举。
    
    **失败不阻塞 init**——注册失败(如注册表目录不可写)时本 skill 仍算成功完成,但必须输出告警与手工补注册指引:「⚠ 项目注册失败(<原因>),init 已正常完成;稍后可在项目目录手工执行 `eo-board --register` 补注册(注册后任意目录 `eo-board --all` 可见本项目)」
    
    ### 11. 输出摘要
    
    展示:
    - `.eo-project.json` 路径和内容
    - 项目管理侧骨架结构
    - 代码侧骨架结构
    - gitignore / agent 配置 / 生态注册 状态
    
    ## 输出
    
    - **代码仓库**:`.eo-project.json` + `eo-doc/` 最小骨架 + agent 配置注入
    - **项目管理侧**:`<project_root>/` 含 `roadmap.md`(+ 按需 `backlog/` 卡片、`phases/` 等)
    
    ## 约束
    
    - **`.eo-project.json` 是所有 eo-* skill 的启动前置**。本 skill 的核心产出
    - 按需目录(phases / decisions / lessons / brainstorm / docs)**init 时不预建**,由对应 skill 首次写入时 lazy 创建
    - 项目名用用户给的原始名称,不转换
    - 原始 PRD/MVP 若提供,存到 `<project_root>/docs/`(lazy 建)
    - `.eo-project/` 缺省随仓库提交、不进 `.gitignore`;用户明确不想提交时当场覆盖。存量项目重跑本 skill 不改其既有 ignore 状态
    - `.eo-project.local.json` **始终**进 `.gitignore`(个人/机器覆盖,不提交);协作者接入只写 local,不改共享的 `.eo-project.json`
    - agent 配置注入使用 `<!-- ...:start/end -->` 标记段(`eo-project` / `eo-reply-contract`),幂等可重复执行
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related