创建一个新的 Workframe 项目,或把已有项目接入 Workframe。按用户意图与目标目录状态分流(新建 / 接入),对话采集业务上下文后落骨架、订阅 core 插件、完成落盘验收。仅用于 Workframe 框架的项目初始化,不承担 npm init / create-react-app / git init 等通用脚手架。
Scanned 9/6/2026
Install to Claude Code
npx -y skills add ryanzhao1011/workframe --skill setup --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Setup?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ryanzhao1011-setup)More formats (shields.io, HTML) on the badges page.
---
name: setup
description: 创建一个新的 Workframe 项目,或把已有项目接入 Workframe。按用户意图与目标目录状态分流(新建 / 接入),对话采集业务上下文后落骨架、订阅 core 插件、完成落盘验收。仅用于 Workframe 框架的项目初始化,不承担 npm init / create-react-app / git init 等通用脚手架。
when_to_use: 用户想用 Workframe 开一个新项目,或想把手上已有的项目接入 Workframe 时。触发词:创建 workframe 项目、接入 workframe、初始化 workframe、workframe setup。**不适用**:已接入项目内的日常工作(由 core 插件的角色与技能承担);与 Workframe 无关的通用脚手架初始化。
allowed-tools: [Read, Write, Edit, Glob, Grep, Bash, AskUserQuestion]
user-invocable: true
---
# Workframe 项目初始化
## 定位
Workframe 的**唯一入口**:在任意目录发起,创建新项目或接入存量项目,完成后由 core 插件接管项目内的日常工作。
本 skill 属用户级 `workframe-launcher` 插件,与项目级 `core` 插件分层:launcher 管「怎么开局」,core 管「项目里怎么干活」。
## 依赖方向(硬约束)
launcher 只能**单向**依赖 core,且**只能**通过 marketplace 注册信息定位 core:
```
读 ~/.claude/plugins/known_marketplaces.json → 取本市场 installLocation
→ 拼 <installLocation>/plugins/core/...
```
**禁止**用 `../` 一类相对路径向上找 core:插件安装时按插件逐个复制到缓存
(`cache/<市场>/<插件>/<版本>/`),launcher 的安装目录旁边不存在 core。
目录源(开发期)碰巧有兄弟目录,GitHub 源(用户侧)没有——该写法开发期能跑、发布后必坏。
**定位脚本**(每次执行前跑一次,一次拿到 `CORE` 根路径**和市场源**):
```bash
python - <<'PY'
import json, pathlib
km = json.loads((pathlib.Path.home()/".claude/plugins/known_marketplaces.json").read_text(encoding="utf-8"))
for name, meta in km.items():
loc = pathlib.Path(meta.get("installLocation", ""))
mf = loc/".claude-plugin"/"marketplace.json"
if not mf.exists():
continue
names = {p.get("name") for p in json.loads(mf.read_text(encoding="utf-8")).get("plugins", [])}
if not ({"core", "workframe-launcher"} <= names):
continue
src = meta.get("source") or {}
kind = src.get("source") or ("directory" if src.get("path") else "?")
origin = src.get("repo") or src.get("url") or src.get("path") or "?"
print(f"MARKET={name}\tCORE={loc/'plugins'/'core'}\tSOURCE={origin}\tKIND={kind}")
PY
```
命中 0 个 → 停下告知用户「未找到 workframe 市场,请先 `claude plugin marketplace add <源>`」。
命中 ≥2 个(用户同时有开发目录源与 GitHub 源)→ 用 AskUserQuestion 让用户选一个,不要自己挑。
**`SOURCE` 就是 §5 步骤 2 里 `claude plugin marketplace add <市场源>` 要填的值——不要用
`CORE` 或 `installLocation` 顶替**。三种形态:`KIND=github` 时 `SOURCE` 是 `owner/repo`;
`KIND=git` 时是仓库 URL;`KIND=directory` 时是本地绝对路径。
`installLocation` 对 github / git 源是**本地缓存目录**(`~/.claude/plugins/marketplaces/<市场名>`),
拿它当市场源写进项目 settings,等于把每台机器各不相同的缓存路径当成插件来源——
协作者 clone 后解析不到,core 装不上(doctor 的 `subscription` 项会报本地目录源告警,
但那时项目已经建好了)。`KIND=directory` 时同样要提醒用户该项目对协作者不可自动安装(见 §5.5)。
## 交互纪律(本 skill 内生效,不依赖项目 rules)
launcher 常在**尚未接入 Workframe 的目录**运行,此时项目 rules 尚不存在,以下纪律必须由本 skill 自带:
1. **选择题一律用 `AskUserQuestion` 工具**,不要在正文里列 A/B/C 让用户敲字。
**是不是选择题看「答案空间」,不看问题措辞**——「有没有 X」「要不要 Y」是二元选择题,
该出卡,哪怕它被顺嘴问出来(2026-08-11 走查教训:Q4 被当开放题混进了文字段)。
一次调用可承载多个相关问题(组件分隔渲染),别为省往返把选择题揉进正文。
2. **复杂内容先在正文完整展示**(模块树、路径映射表、文件清单),AskUserQuestion 的选项只做轻量判断(「符合,按此执行」/「需调整」)——选项 preview 不承载关键信息。
3. **确认前零写盘**。方案确认页是唯一闸门,用户明确确认前不创建任何目录或文件。
4. 用户已表达倾向时正面回应:同意给理由,不同意给具体替代方案,不含糊带过。
5. **说人话**。来初始化项目的多半是 PM,不是工程师。技术名词(monorepo / git init / scaffold / 暂存区…)该用就用,但第一次出现时用一句日常话带出**它对用户意味着什么**——「已 init 但 0 次提交的 monorepo」不如「多包代码仓刚建好、还没有任何提交记录」。目标是把「发生了什么、对你意味着什么、可以怎么选」讲到初次使用的人能直接决策;具体怎么说不设模板,由你按对象发挥(2026-08-11 用户反馈:扫描汇报判定全对,但口径偏工程师)。
解释**首现一次到位**:同一概念第一次出现时讲透,之后直接用,不逐轮重复——多轮交互里
反复解释是内容墙的另一来源。
6. **输出密度:分档呈现,表格优先**(2026-08-11 用户反馈:每步确认内容偏多,核对费劲费时)。
确认类输出把内容分两档:**等用户拍板的**(会写进或改动用户文件的内容、可当场驳的推断结论)
完整展示;**供用户了解的**(框架介绍、日后随时可查的速查内容)压到最短、给一句指路。
呈现表格优先——每行一个可核对的事实,散文只用来说「为什么」。压缩幅度与排版按现场判断,
不设模板;底线一条:**决策对象不因简洁缺席**。
## §1 入口分流
### 1.1 判定目录状态
按顺序判,前面命中就不往下走:
| 步 | 判据 | 结论 |
|---|---|---|
| 1 | 有 `.workframe-config.json` | **已接入** |
| 2 | **根级**有 `.git`,或根级有项目清单(`package.json` / `pyproject.toml` / `Cargo.toml` / `go.mod` / `pom.xml` / `*.sln` …) | **项目目录** —— 这条**一票否决容器**,monorepo 里塞多少个子包都走这条 |
| 3 | 是众所周知的系统容器位置:`~/Desktop` `~/Downloads` `~/Documents` `~` 本身、盘符根、`/Users/<name>` `/home/<name>`,含各语言本地化名(桌面 / 下载 / 文档 / デスクトップ …) | **容器目录** |
| 4 | 近空(只有 `.git` / `README` 之类) | **空目录** |
| 5 | 综合判断:内容彼此无关(几个不同主题的目录 + 散落的截图安装包)且无「这是一个整体」的标志 → 容器;内容有主题一致性、README 在描述"这个东西是什么" → 项目 | 按判断走 |
| 6 | **拿不准** | **按项目目录处理** —— 判错只影响推荐顺序,不删任何选项 |
> **为什么第 2 步要一票否决**:早期草案用「子项里有 ≥2 个独立项目标志」判容器,这会把
> **monorepo 直接判成容器**,而 monorepo 恰恰最需要「接入」——那不是不便,是功能没了。
>
> **目录扫描的结果只用于判断目录状态**,不得直接拿去推断用户的业务或项目名(见 §2 约束)。
### 1.2 分流
**原则:明确意图不拦路(至多一句轻确认),模糊意图才出选择卡。**
先分清两个容易混的说法:
- **就地建** = 当前目录**本身**成为项目根
- **在此处建** = 在当前目录**下面**建一个子目录当项目根 ← 容器目录下的正常做法
| 用户表达 ↓ \ 目录状态 → | 空目录 | **容器目录** | 项目目录(未接入) | 已接入 |
|---|---|---|---|---|
| **明确「新建」** | 轻确认:就用这个空目录,还是另选位置? | 在此处建子目录(Q3 首选 `<容器>/<项目名>`) | 见 §1.3 | 轻确认:「这里已接入,是要在其他位置新建吧?」 |
| **明确「接入」** | 说明无可接入 → 顺势转就地新建 | **说明容器目录不适合整个接入**,问是要接入它下面的某个项目,还是在此处新建 | 走 §3 B 路径 | 提示已接入;可顺带跑 doctor 体检 |
| **模糊**(「初始化」「用上 workframe」) | 默认就地新建,确认一句 | 选择卡:**在此处建一个项目目录(推荐)/ 换个位置建**——**不出现「接入当前」** | 选择卡:接入当前(推荐)/ 在此处建子目录 / 另外建 | 提示已接入 + 问是否另建 |
**容器目录下「接入当前」不出现的唯一理由**:把桌面 / 下载夹本身变成 workframe 项目,在任何
情况下都不是用户想要的——那会在容器里散出 `projects/` `logs/` `.claude/` `CLAUDE.md` 一堆东西。
**兜底:用户意图永远高于自动判定。** 用户明确说「就接入当前这个目录」时照做,哪怕判定为容器。
### 1.3 项目目录里说「新建」时先问一句
这时「新建」有两种意思,差别很大,**不要替用户选**:
> 检测到当前目录是一个已有项目。你说的「新建」是指——
> 1. 在它下面建一个子目录当 workframe 工作区(如 `<repo>/pm/`)
> 2. 把**这个项目本身**接入 workframe
选 2 时必须提示:**这等同于「接入」**,会顺带做存量资料分析与 CLAUDE.md 整合。跳过整合的话,
角色路由 / 状态流转 / 文档约定这些框架约定**不会进你的 CLAUDE.md**——落盘验收会以 error 抓出
(doctor 的 claude_md 项查四个契约段的内容,不只看文件在不在)。用户坚持只要纯骨架也可以,
但要让他知道跳过了什么。
## §2 A 路径:全新创建
四个问题,全部遵循「候选 + 自填」,逐个问、不要一次性倒给用户。
| 步 | 问题 | 形式 | 要点 |
|---|---|---|---|
| Q1 | 你在负责什么类型的产品? | 选择卡,**选项即格式示范** | 示例选项:`toC 社交(海外陌生人交友)` / `toC 内容社区(短视频、图文)` / `toB SaaS(客服系统、CRM)`,选项写法本身示范回答颗粒度(产品形态 + 业务域)。这是**业务上下文采集**,喂给 CLAUDE.md 业务背景段、role_profile 推断与名称候选 |
| Q2 | 项目叫什么? | 基于 Q1 生成 2-3 个候选 + 自填 | 这是展示名(启动横幅、报告用),可以与目录名不同 |
| Q3 | 放在哪个目录? | 候选 + 自填 | 首选候选按目录状态给:空目录→当前目录本身;**容器目录→`<容器>/<项目名>`**;项目目录→`<当前项目>/<项目名>`。**就地新建(空目录)时本问自动跳过**。**给候选前必须先查该路径存不存在**——见下 |
| Q4 | 有没有已有资料或在维护的目录要纳入分析? | **选择卡**(本质是「有 / 没有」二元题——选择题看**答案空间**不看措辞)| 选项措辞自定,但须含「没有」的快捷出口与「有 → 给路径」的自填通道。有 → 走 §3 的分析能力;没有 → 标准骨架起步,日后在项目内随时用 `migrate-to-modules`(规范 md)/ `requirement-archiving`(异构原料)补充 |
### 必填字段从哪来
scaffold 有三个必填参数,上表只直接产出其中一个——**别把另外两个凭空编出来**:
| 字段 | 来源 |
|---|---|
| `project_name` | Q2 直接产出 |
| `one_line_goal` | **必须问用户**(见下 Q5),Q1 派生不出来——Q1 答的是**品类**(「toC 内容工具」),这里要的是**这个项目做成什么**(「做一个多平台自媒体内容生产与分发工具」) |
| `business_context` | 由 Q1 + Q5 合成即可(两个来源都是用户亲口说的,不算编) |
**Q5 一句话目标**:也用**选择卡**——基于 Q1 的回答派生 2-3 个候选目标供快速选择
(候选即格式示范,方向、颗粒度贴着用户的业务写),用户不满意随时自填。问的时候顺带
说清用途——「会写进 CLAUDE.md 业务背景段,影响模块切分与角色推断;写具体一点更好」。
写进 CLAUDE.md 的是用户**选中或自填的原文**,候选只是快选通道。
**Q4 与 Q5 可并入同一次 AskUserQuestion 调用**(组件天然分隔多个问题,不会变成文字墙;
2026-08-11 用户反馈:旧的「合并成一段文字问」正是墙的来源,已废止)。**Q1 必须单独问**,
它的答案决定后面所有候选。
三个字段**都必须在确认页的「项目基本信息」里展示**:它们会原样进 CLAUDE.md,用户在确认页
不过目,之后就没人看了。
### Q3 候选必须先查路径是否被占(硬约束)
项目名默认会变成目录名,而**用户起的名字很可能跟已有目录撞上**——尤其是他选了那个从当前
目录推断出来的候选时(选「SmartArticle」→ 默认目录 `<桌面>/SmartArticle` → 正是那个代码仓)。
给出候选前,对每个候选路径判一次:
| 路径状态 | 怎么办 |
|---|---|
| 不存在 | 正常作候选 |
| 存在但近空(只有 `.git` / `README` 等) | 可作候选,提一句「该目录已存在但基本是空的」 |
| **存在且有实质内容** | **不能作候选**。摆出来问用户:是想**接入**这个已有项目(走 §3,会做存量分析与 CLAUDE.md 整合)/在它**下面**建子目录/还是换个名字? |
最后一种情况**别自作主张**——「新建」和「接入」是两条不同的路,选错了后果是静默的:
按新建硬来虽然不会破坏文件,但会跳过整合,框架约定进不了他的 CLAUDE.md。
脚本侧有 `--require-empty` 兜底(退出码 3),但那是最后一道,不该指望它替你问用户。
### 候选从哪来(硬约束)
**Q2 / Q5 的候选主体必须从 Q1 的回答派生,不是从当前目录的内容派生。** A 路径是「另外建一个
新项目」,当前目录只是你敲命令的地方,跟新项目没有关系——拿它推断业务是类别错误。
允许**至多 1 个**候选来自当前目录内容,但三条同时满足才行:
1. **标注推断依据**——「看到你桌面上有 `SmartArticle`,如果是给它建的话…」,让用户知道你为什么
这么猜。不标注的话,错误推断会被误读成"系统知道什么内情"
2. **不作为推荐项**(不是默认高亮那个)
3. 其余候选照常从 Q1 派生
> 实测教训(2026-08-10 E2E):在桌面发起时,Q2 的三个候选**全是**从桌面上一个代码目录推断出的
> 变体,用户只能选「自填」才逃得出去——推断变成了**默认值**。而「桌面上有 X」推不出
> 「我要为 X 建项目」,这个推断即使碰巧猜对也不成立。
>
> Q4 用户明确给出的资料路径不受此限——那是他主动交给你分析的。
**role_profile 自动推断,不设问**(结果在确认页展示、可调):
- Q1 文本明显以 AI / LLM / Prompt / Agent 能力为核心 → `ai-product`(「智能 X」「自动化」等含混词**不**算)
- 文本命中「个人 PM / 一人 / 没研发 / 自己做」等 → `solo-pm`
- 否则 → `software-team`(默认)
**判据是「谁在这个项目里真的干活」,不是「公司里有没有这个工种」。**
B 路径能直接观测到有没有代码(见 §3 观测维度),**观测到的事实优先于文本推断**:项目里没有
代码时不要落进 `software-team` 默认档——那会把 @dev / @qa 设为主力,而这个项目里没有东西
可写、也没有东西可测。纯文档 / 需求项目按 `solo-pm`(pm 主力)判。
> 实测教训(2026-08-10):一个零代码的产品文档项目被判成 `software-team`,依据是原文里的
> 「研发给的需求文档」「和研发对齐用飞书」。推断执行得没错,是判据本身把「有研发协作」
> 当成了「研发在本项目内」——而那些研发在 TAPD 和飞书那头,从不进这个仓库。
> 确认页已要求写明推断依据,**依据里必须出现「本项目内有/无代码」这一条**,让用户一眼能驳。
## §3 B 路径:存量项目接入
**就地分析,扫描证据后带证据确认,不设问**——用户从「填表」变成「确认」。
| 观测维度 | 观测方式 | 影响 |
|---|---|---|
| 有没有代码 | Glob 源码 / 识别脚手架 | 模块树切分证据 + `submodule.yaml.code_paths` 建议 + 接入后 code-to-doc 计划 |
| 有没有存量文档 | Glob md / docx / xls 等 | 搬家分流计划(进确认页) |
| 带不带团队 | `git shortlog -sn` 贡献者数 | 仅 role_profile 推断,**不影响目录结构**;确认页可调 |
补充几条:
- **扫描汇报讲结论不铺过程**:三个观测维度一张表结清(看到什么 / 对你意味着什么),
判定结论先行;分析细节留给用户追问再展开。
- **项目已有 `CLAUDE.md` 时必须做整合**——这是 B 路径最容易漏、后果最隐蔽的一步。scaffold
对已存在的 CLAUDE.md 一律跳过不覆盖,不整合的话:hooks 装上了、rules 镜像了、4 个 agent
能路由,但项目 CLAUDE.md 里**没有角色体系表、没有路由规则、没有状态流转与签发权限、
没有文档与结构约定**——框架一半的行为约定不生效。落盘验收会以 error 抓出(claude_md 项查四个契约段的内容,不是只看文件存在)。
规范见 `<CORE>/reference/claude-md-merge-guide.md`,**本阶段只做到"分类原文 + 出合并稿"**,
写盘在 §5。
**合并稿必须在确认页正文露出——但只露含用户原文的段落**(业务背景 / 项目特殊约束 /
业务目录速查等)。框架样板段(订阅声明 / 角色体系 / 路由规则 / 状态流转)每个项目一模一样,
贴出来是噪音。合并质量只体现在用户原文那几段,不给就等于让用户盲签一份即将覆盖自己文件的东西。
「全文太长会盖掉方案页」是真的,但解法是**挑段落**,不是改用结构摘要代替。
- 已有 `.claude/agents/<custom-role>.md` 时自动检测三项并提议 patch:是否误用 `memory:` frontmatter、body 是否引用 agent-protocols、`.claude/agent-memory/<role>/` 是否存在。
- 存量文档的处理**层层递进,不一次性塞给用户**(2026-08-11 走查后定稿):本阶段只做
**粗扫**(形态计数 + 标题级抽样:md 读 H1/H2、docx 读标题与首段、xlsx 读表头,
**不逐字深读**——供模块树提议用,见 `material-intake` §两级盘点)。每份文件的安置与
原件处置在建树后的**逐模块小闸**(§5 步骤 4)深读后逐模块确认、当场执行;
**整理归档**(原始资料 → 正式需求文档,即 requirement-archiving)的节奏在节奏闸
(§5 步骤 4.5)拍。结构闸只拍项目级的事——用户核对量小,改动也不连锁。
- 项目已有 `project_name` / `role_profile` 等配置时,确认页必须展示既有值:scaffold 对已有用户字段不覆盖,但展示名会按确认结果刷新。
- **会被修改的已存在文件必须逐个点名**,不能只说「你现有 N 个文件一个不动」。
接入至少会碰两类:已存在的 `CLAUDE.md`(整合覆盖,落备份)、已存在的 `.gitignore`
(末尾追加 managed block,不动用户原有规则)。
实测教训:确认页报「现有 6 个文件一个不动」时,那个 6 悄悄没算 `.gitignore`——数字没说谎,
但用户读到的是「什么都不碰」,而它确实被改了。**统计口径排除掉的东西,必须在同一处说明白**。
## §4 结构闸(写盘与订阅前的唯一闸门)
在正文完整渲染,三条硬性标准见 [`./reference/proposal-page.md`](./reference/proposal-page.md):用 PM 自己的业务语言展示模块树、给「你以后每类东西放哪」映射表、框架术语必须带业务例子。
**只拍项目级三件事**:模块树(粗扫标题级证据支撑)、CLAUDE.md 合并稿(只露用户原文段落)、
会被修改的已有文件点名。**每份文件的去向与处置不在这里拍**——那是逐模块小闸(§5 步骤 4)
的事:一次性塞给用户既难核对,改树时又全部连锁重算。树也不是一锤定音:逐模块深读发现
更合理切分时回来提议微调(连锁已被逐模块机制隔离,微调便宜)。
本页本质是把确认从「审文件清单」升级为「审认知」——PM 确认的是「你们对我业务的分层理解对不对」。
确认用 AskUserQuestion,选项:`按此执行` / `我要调整`(用户用自然语句说改什么,迭代到满意)/ `取消`。
## §5 执行(确认后一气呵成)
先按 §依赖方向 拿到 `CORE` 路径,再依次执行。
**1. 写参数文件并落骨架**
把对话采集的值写成 JSON(必填 `project_name` / `one_line_goal` / `business_context`;可选 `project_type` / `dormant_profile` / `role_profile` / `project_level_roles` / `project_specific_constraints` / `business_directories`),交给脚本确定性渲染——占位符替换由脚本保证并断言零残留,不要手工替换模板:
```bash
# A 路径(新建)——必须带 --require-empty
python "<CORE>/scripts/project_scaffold.py" --project "<目标>" --params "<params.json>" \
--create-missing --require-empty
# B 路径(接入已有项目)——不带 --require-empty
python "<CORE>/scripts/project_scaffold.py" --project "<目标>" --params "<params.json>"
```
**A 路径必须带 `--require-empty`**:它保证目标是不存在或近空的。少了这个参数,用户把项目名
起成跟已有目录同名时,会**静默把一个已有代码仓当成新项目 scaffold**——文件不会被破坏,但
接入流程(存量分析 + CLAUDE.md 整合)被整个跳过,框架约定进不去,而落盘验收只查「文件存在」
**已经跳过的整合补不回来**(目标已有 CLAUDE.md 时验收会报契约段缺失,但那时返工成本更高;
目标没有 CLAUDE.md 时四段齐全、验收看不出走错路径)。退出码 3 = 目标非空,此时**改走接入
流程或换个不存在的路径**,不要去掉参数硬来。
**参数文件必须写在目标目录之外**(系统临时目录即可,`tree.json` 同理)。写进目标目录时它自己
就是"实质内容",A 路径会被 `--require-empty` 判为目标非空退出 3——而那条报错说的是「目标已有
内容」,照上一段的处置就会**错走接入流程**,把新建项目专属的存量分析与 CLAUDE.md 整合整个跳过。
非零退出即停下报错,不要跳过继续。退出码语义:**3** = 目标非空(见下段处置);**1** = 模板文件缺失(插件安装不完整,stdout 会列出缺哪些)——这时重装 core 插件再重跑,别在半成品骨架上继续初始化。
**1.2 建模块树(结构闸确认过模块树时)**
把确认页拍定的树写成 JSON(schema 见脚本 docstring:basics[] → subs[],各带
name / owner / positioning / code_paths),交给脚本确定性落盘:
```bash
python "<CORE>/scripts/module_init.py" --project "<目标>" --params "<tree.json>"
```
脚本承包骨架复制、占位符零残留断言、positioning 写入、code_paths 与反向索引、
两层索引段重建,且幂等(重跑安全)。退出码 2 = 命名 / 参数校验失败——转述 stderr、
修正后重跑,不要手工补文件。**只建 basic / sub 两层**:需求资产包是整理归档阶段的产物。
**1.5 写入合并后的 CLAUDE.md(仅 B 路径:目标已有 CLAUDE.md 时)**
scaffold 见到已存在的 CLAUDE.md 会跳过——**它跳过的这一份,由你按 §3 产出的合并稿写回**。
写盘前按 `<CORE>/reference/claude-md-merge-guide.md` §第 4 步做备份判断(两条确定性命令,
不是凭感觉):
```bash
cd "<目标>"
git ls-files --error-unmatch CLAUDE.md # 被跟踪吗
git status --porcelain CLAUDE.md # 输出空才算干净
```
两条都过 → 免备份(git 里有原文);任一不过 → 先写 `logs/CLAUDE.md.bak-<YYYYMMDD-HHmmss>`。
写完在响应里说清备份去哪了,或为什么没备份、怎么用 git 回退。
A 路径(新建项目)没有这一步——scaffold 已按模板渲染好。
**2. 订阅 core —— 两条命令缺一不可**
```bash
cd "<目标>"
claude plugin marketplace add "<市场源>" --scope project # ← §依赖方向 定位脚本输出的 SOURCE
claude plugin install core@workframe --scope project
```
`<市场源>` **取定位脚本输出的 `SOURCE` 字段,不是 `CORE` 也不是 installLocation**(理由见
§依赖方向 末段:后两者是本地缓存路径,写进项目 settings 会让协作者装不上)。
**只跑第二条会产出协作者用不了的项目**:项目 settings 里只有 `enabledPlugins`、没有 `extraKnownMarketplaces`,别人 clone 后无法解析插件来源。CLI 不可用时降级为在响应中输出这两条命令请用户手动执行,并继续后续步骤。
**3. 同步 rules 镜像**
```bash
python "<CORE>/scripts/sync-rules.py" --project "<目标>"
```
**3.5 git init + 首提交(A 路径默认做,确认页可取消)**
**必须排在 scaffold / 订阅 / sync-rules 之后**——这样 `.gitignore` 已就位,首提交才不会把
`workframe-state/` 与 `logs/` 一起提交进去。
```bash
cd "<目标>"
git rev-parse --git-dir >/dev/null 2>&1 || git init
git add -A
git commit -m "chore: 初始化 Workframe 项目骨架"
```
- 目标已经是 git 仓(B 路径接入常见)→ **跳过 init,也不要替用户提交**,他自己的工作区可能有
未提交改动
- `git commit` 失败(多半是没配 `user.name` / `user.email`)→ **保留 init 不回滚**,在响应里
告诉用户怎么补完,继续后面的步骤
- 用户在确认页取消了这一项 → 整步跳过
为什么默认做:没有 git,`.gitignore` 是废的、doctor 的可移植性检查直接跳过、
「同事 clone 接入好的项目」这条路径根本不成立。
**4. 逐模块深读与安置(小闸 × N——只对有资料的模块开)**
骨干已完整(树在、订阅在、git 在),现在按模块逐个处理资料——**深读发生在这里,不在粗扫**:
- 每轮取一个有资料的模块:深读该模块名下的文件 → 给出安置 + 原件处置方案
(处置五条边界与 A 路径外部资料档位变体见 `material-intake` §原件处置)→
AskUserQuestion 确认 → **当场执行该模块安置**,再进下一个模块
- **粒度弹性**:1-2 份文件的小模块合并进相邻一轮;单轮确认不超过约 10 份文件的决策量
——既不一次塞,又不过度分散。无资料的模块直接跳过
- **呈现纪律**:每轮方案一张表结清(文件 / 一句话结论 / 建议去向 / 原件处置),需要展开的
行在表下另起短段说「为什么」;引用收口、外部源只拷不搬这类通用纪律**首轮讲清,
后续轮只报例外**,不逐轮重复
- 深读中发现更合理的切分 → 按结构闸口径向用户**提议树微调**(改动只影响相关模块)
- 安置纪律:成品 md 搬入 / 拷入后补最小 frontmatter,**移动后收口三类引用**
(frontmatter `related` / wikilink / 相对路径资源);**成品需求类 md 的落点优先
`requirements/_draft/`(未立项的需求 / 方案)或 `<basic>/shared/`(跨 sub 事实源),
`others/` 是杂项区、不作成品文档的默认落点**(2026-08-11 走查:两轮归属选择不一致,
据此收紧);异构原料进 `<sub>/others/原始资料/<批次>/`(跨 sub 共用进
`<basic>/shared/assets/原始资料/`,分组进目录不平铺);**外部源一律拷不搬**
(material-intake §2.1 红线:源目录只读)
- **大批量(约 >15 份 md)走逃生口**:只安置样板批证明结构可用,其余留给重启后
`/core:migrate-to-modules` 批量迁移(记入步骤 5 的批次)
- 在线文档链接(飞书 / Notion 等)本地无副本,装机做不了——列入「待你导出」清单,进步骤 5 批次
**4.5 节奏闸(有待整理归档的批次时才出现)**
安置完成后,把剩余重型活摆到桌面上让用户拍节奏。**整理归档** = 把 docx / xls / 截图等
原始资料读懂后整理成正式需求文档(即 requirement-archiving 九段流水线)。
预估**只给客观量**:每批几份文件、含几个需要用户拍板的决策点(如原文里的未决口径)——
**不给时间预估**:模型执行速度与人力经验完全两码事,时间数字只会误导(2026-08-11 用户反馈)。
用 AskUserQuestion:
1. **现在连续做完**(推荐——装完即完整状态)
2. **现在做一部分**(选批次;其余接力)
3. **全部留到重启后**(首个会话主动接起)
4. **暂不做**(只在体检 / 看板可见,随时说「继续初始化」恢复)
同一张卡(或紧接的第二问)把 **git 提交策略**一并拍掉,之后全程沿用不再问:
每批完成自动提交(推荐;A 路径新建项目默认此档)/ 全部完成一次提交 / 用户自己管。
**用户中途挂起剩余批次时,视作当前阶段完成**——主动提议把已产出内容提交(经确认执行,
不强制);否则「全部完成一次提交」会因挂起让产物无限期滞留未提交(2026-08-11 实测现场)。
盘量超预期时主动建议档位 2(结构 + 样板批当场做)——不硬撑长会话,也不擅自缩水。
**PRD 风格定制提议(条件触发)**:粗扫与逐模块深读中识别到 **≥3 份章节骨架趋同**的存量
需求文档时,节奏闸顺带多问一项——本项目的 PRD 框架(装机已放入 `.claude/skills/prd-style/`,
当前为出厂默认版)要不要**按你现有 PRD 风格定制**?选定制 → 作为一个批次执行(当场做或
接力均可):读 `<CORE>/skills/prd-writer/SKILL.md` §风格定制与萃取照做(样例抽取 → 差异与
冲突表逐条拍 → 过目确认 → 改写项目 prd-style)。不满 3 份或用户选默认 → 不动,一句带过
「以后随时说『按我的风格写 PRD』再定制」。
**4.7 整理归档段(用户选了当场做的批次)**
逐批执行,**SOP 从磁盘读、逐阶段照做**——skill 未加载不等于拿不到,这与 §3 读
material-intake SOP 是同一模式:
| 批次去向 | 照做的 SOP | 解析脚本 |
|---|---|---|
| 异构原料归档 | `<CORE>/skills/requirement-archiving/SKILL.md`(九段 Phase 0-8,含各阶段门禁) | 该 skill `scripts/` 下直接 `python` 跑 |
| 大批量 md 迁移 | `<CORE>/skills/migrate-to-modules/SKILL.md` | — |
| 代码反解 current-state | `<CORE>/skills/code-to-doc/SKILL.md` | — |
纪律:
- 九段的**每个阶段门禁照过**(收料冻结 / 拍板集中问 / 反向对账缺一不可),装机场景不减配
- **每批完成主动汇报 + 按拍板的提交策略提交**,并给用户离场点(「继续下一批还是今天到这?」)
- 中断不怕:阶段产物步步落盘 + 台账逐行记账,任何后续会话说「继续初始化」精确续上
- 收尾跑一次 `python "<CORE>/scripts/check-stale-modules.py" rebuild-index` 补齐 hook 缺席期间的索引
**5. 断点标记——不是最后才写,是每步紧跟着记**
`setup-state.json` 是**为中断准备的**,所以它必须在中断发生**之前**就记下进度。
scaffold 成功时会自己落 `scaffold: ok`(代码保证,不靠你记得);**从第 2 步起,每完成一步
立刻记一笔**,用 core 的 `mark_setup_step()`:
```bash
python -c "import sys; sys.path.insert(0, r'<CORE>/scripts'); \
from project_scaffold import mark_setup_step; from pathlib import Path; \
mark_setup_step(Path(r'<目标>'), 'subscribe')"
```
失败时把原因一起记下(第三、四个参数):
```bash
python -c "import sys; sys.path.insert(0, r'<CORE>/scripts'); \
from project_scaffold import mark_setup_step; from pathlib import Path; \
mark_setup_step(Path(r'<目标>'), 'subscribe', 'failed', 'claude CLI 不在 PATH')"
```
**四步各自的落笔人**——第三列是套进上面那个 `python -c` 外壳的调用,紧跟在该步做完之后执行:
| step | 什么时候记 | 怎么记 |
|---|---|---|
| `scaffold` | 步骤 1 | **脚本自动落,不用你记** |
| `subscribe` | 步骤 2 两条订阅命令都跑完 | `mark_setup_step(Path(r'<目标>'), 'subscribe')` |
| `sync_rules` | 步骤 3 `sync-rules.py` 退出 0 之后 | `mark_setup_step(Path(r'<目标>'), 'sync_rules')` |
| `acceptance` | 步骤 5.5 验收跑完 | **doctor 自己落笔(含失败原因),不用你记** |
`acceptance` 之所以不由你记:它的语义是「落盘验收做完了」,只能在验收之后写,而验收查的就是
这份文件——让你来记就成了自指,第一次跑必然缺它、必然报一条机制自造的 error。
条件步做了就记:B 路径 `claude_md_merge`;做了 git 的 `git_init`;建了树的 `module_tree`;
安置了资料的 `placement`(全部模块安置完才记 ok);整理归档段做完的 `transform`。
**有剩余批次时必须记 `pending_work`**——用户在节奏闸拍了接力 / 暂不的批次、未定处置的
资料、待导出的在线文档,不记下来就再没人提起(收尾报告在 gitignore 的 `logs/` 下,
重启后是空白屏)。这是「第二幕」接力链的起点:
```bash
python -c "import sys, json; sys.path.insert(0, r'<CORE>/scripts'); \
from project_scaffold import mark_pending_work; from pathlib import Path; \
mark_pending_work(Path(r'<目标>'), json.loads(r'''<batches JSON>'''), '<一句话安排>')"
```
batches 每项含 `name` / `files`(项目根相对)/ `target_skill` / `pace`——pace 用用户拍的节奏:
`relay`(重启后做→首会话强接力)/ `paused`(暂不做→零打扰,仅体检可见)/
`undecided`(没做处置决策→软提醒 3 会话 + 文件搬走自清除)。
只填资料批次,不填 `CLAUDE.md` / `.gitignore` 这类项目约定文件。
当场全部做完则**不写此键**——doctor 的 init_completeness 直接报「完整落地」。
**5.5 落盘验收(批次落定之后跑——时序是关键)**
```bash
python "<CORE>/scripts/workframe_doctor.py" --project "<目标>" --group install
```
验收放在 pending_work 落定之后,「初始化完整度」读到的才是真实终态——放在安置前会
误报「完整落地」(2026-08-11 实测教训)。
11 项覆盖:骨架完整性(硬/软两档 + 占位符残留)、**CLAUDE.md 四契约段**、项目 PRD 框架
(prd-style 在位性,缺失仅 info)、config 三字段、订阅接线两项、rules 镜像 4 份、
`.gitignore` 必需条目、初始化断点、**初始化完整度**(pending_work 批次状态,纯 info)、
可移植性、环境与 hook 活性。
> 向用户报项数时**以实际输出为准,不要照抄本行**。本行到 2026-08-10 一直写「8 项」且漏了
> `claude_md`——新增该检查时没同步这里,而它恰是 B 路径最该被验的一项。清单与代码有两处
> 事实源就会漂,`check_doctor_install_group_contract` 已对账两边。
**此刻还没重启**,所以依赖 hook 的项会显示 `i`「待首个会话后复查」——这是正常的,不要当失败。
重启后由 core 侧自动跑同一组做运行时验收,那时它们才有真结果。
**来源形态是本地目录路径时必须提示用户**:该项目对协作者不可自动安装(对方机器上没有这个路径),开源/团队协作场景应改用 git 源。
退出码 1(有 error)时**当场对话修复**(重试 / 给手工命令),修完才放行——不要把待办写进文件让用户日后自己发现。仅有 `!` warn 时可继续,但要把每条 warn 念给用户听。
**失败要当场记,而不是等流程末尾统一写**——真断在中途时,末尾那次写入根本不会发生。
早期设计正是把它放在全流程最后一次性写:**为中断设计的机制反过来要求流程别中断**,
自我否定(2026-08-10 走查发现)。
> 顺带一个时序问题也随之解决:doctor 的 `setup_state` 项读的就是这份文件。按增量写法,
> 第 5.5 步落盘验收时此前各步已在文件里,它才验得到「装到哪一步」;旧写法下验收跑在写入之前,
> 那一项**永远**只能报「无 setup-state.json」。
## §6 收尾
1. 写 `<目标>/logs/creation-report.md`:基本信息、对话摘要、最终结构、订阅与验收状态、后续建议。**报告落 `logs/` 不落项目根**,避免污染业务目录。
2. **在响应正文里直接输出**关键结论,不依赖用户去打开报告文件:
按有无剩余批次分两种话术——**不给用户「装完了」的错觉是硬要求**:
全部落地(无 pending_work):
```
✅ 项目「<name>」已初始化并**完整落地**:模块树 <N> 个模块、<M> 份资料已归位<、K 份原料已归档>。
⚠️ 请现在用 Claude Code 打开 <target>(新开一个会话):
1. core 的 hook 链路与 rules 需要新会话才激活
2. **屏幕会是空白的,这是正常的**——hook 的输出进的是 Claude 的上下文,不显示在终端。
随便说句话(比如「装好了吗」),它会把首个会话的安装验收结果告诉你
3. 想自己确认:说「看板」让它读 `projects/board.yaml` 汇报,或跑
`python "<CORE>/scripts/workframe_doctor.py" --group install`
```
有剩余批次(记了 pending_work):
```
✅ 第一幕完成:模块树已建好、<已安置摘要>。
⏭️ 初始化还有**第二幕**(你拍的节奏):<批次 × 节奏清单,含「待你导出」项>
⚠️ 请重启 Claude Code 打开 <target> 继续:屏幕是空白的(正常),**随便说句话**——
我会按你拍的节奏接着带你走完第二幕。进度随时可查:说「看板」,或体检里的「初始化完整度」。
```
两种话术后都补一句(告知档,一行带过):「本项目的 PRD 规范在 `.claude/skills/prd-style/`,
写 PRD 按它执行——想按自己习惯改,直接改这份文件」;本次做过风格定制的项目改说
「PRD 规范已按你的风格定制,在 `.claude/skills/prd-style/`」。
**不要写「看启动横幅是否出现 `[<name>]`」**——那句话在终端里看不见(2026-08-10 走查实证:
用户重启后面对空白屏,以为 hook 没跑,实际全部正常)。hook stdout 只进模型上下文。
首次会话由 core 侧自动做运行时验收:`session-start-prep` hook 在 `session_counter == 1` 时
内联跑同一组检查,结果直接打进启动上下文——纯代码确定性,不依赖模型自觉,本 skill 不再介入。
## 质量自检
- [ ] 目录状态按 §1.1 六步判过(根级 .git / 项目清单一票否决容器;拿不准按项目处理)
- [ ] 容器目录下没给出「就地建」「接入当前」,Q3 首选是 `<容器>/<项目名>`
- [ ] Q1/Q2 候选主体来自 Q1 的回答;来自当前目录的至多 1 个且标了推断依据、不是推荐项
- [ ] Q3 候选路径逐个查过存不存在;已存在有内容的没直接拿来当候选
- [ ] A 路径的 scaffold 命令带了 `--require-empty`(B 路径不带)
- [ ] 选择题都走了 AskUserQuestion,没在正文列 A/B/C 让用户敲字
- [ ] 确认页在正文完整展示过,且用户明确确认后才开始写盘
- [ ] core 路径经 known_marketplaces 定位,全程无 `../` 向上引用
- [ ] 订阅跑了**两条**命令,落盘验收确认两项声明齐全
- [ ] scaffold / sync-rules / doctor 任一非零退出都已停下处理,没有跳过继续
- [ ] 报告落 `logs/`,且关键结论已在响应正文输出
- [ ] 没在任何生成文件里硬编码本机用户名或桌面路径
- [ ] 结构闸只拍项目级三件事(树 / 合并稿 / 文件点名),粗扫未逐字深读全文
- [ ] 确认类输出分了档:拍板项完整展示、告知项精简指路;同一概念未逐轮重复解释
- [ ] 逐模块小闸:有资料的模块才开、单轮 ≤ 约 10 份决策量、确认后当场执行该模块安置
- [ ] 模块树经 `module_init.py` 落盘(不手搓树);安置执行了引用收口;外部源只拷未动;大批量走了逃生口
- [ ] 节奏闸预估只给份数与待拍板决策点数、**没给时间**;git 提交策略一次拍板全程沿用
- [ ] 整理归档段逐阶段照 SOP(门禁不减配),每批完成有汇报与离场点
- [ ] 剩余批次已记 `pending_work`(pace 按用户拍板);全部落地则未写此键
- [ ] 落盘验收跑在批次落定之后(「初始化完整度」读到真实终态)
- [ ] 收尾话术按有无第二幕分形态,没给「装完了」的错觉
## 与其他 skill 的衔接
| 场景 | 交给谁 |
|---|---|
| 存量资料盘点 / 分流 / 结构推荐 | core `material-intake`(launcher 读其 SOP 照做) |
| basic / sub 建树 | core `module_init.py`(§5 步骤 1.2 直接调) |
| 规范 md 批量搬家 | core `migrate-to-modules`(装机整理归档段读 SOP 照做,或按节奏接力到重启后) |
| 异构原料整理归档 | core `requirement-archiving`(同上,九段门禁装机不减配) |
| 代码反解为现状文档 | core `code-to-doc`(同上) |
| 需求资产包(整理归档产物) | core `module-init`(requirement 模式,项目内执行) |
## 注意事项
- 生成内容不追求一次完美,鼓励用户后续迭代完善。
- 整理归档节奏由用户在节奏闸拍板,不替用户决定;推迟的批次必须记 `pending_work`,
否则「第二幕」再没人提起——装完 ≠ 完整落地,完整落地 = pending_work 清零。
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!