diff --git a/skills/product-prototype/README.md b/skills/product-prototype/README.md index b06806e..f67081c 100644 --- a/skills/product-prototype/README.md +++ b/skills/product-prototype/README.md @@ -13,7 +13,7 @@ pouch add product-prototype -g # 全局 Skill 安装后,从 Skill 目录运行初始化脚本。使用仓库 checkout 时命令如下: ```bash -python3 skills/product-prototype/scripts/init.py ./prototype-studio +python3 skills/product-prototype/scripts/init.py ./prototype ``` 全局安装后可使用 `~/.pouch/skills/product-prototype/scripts/init.py`。初始化脚本是安全的 @@ -32,7 +32,7 @@ mock。四类源数据仍是唯一事实来源;浏览器产物和构建目录 ## 初始化后的目录 ```text -prototype-studio/ +prototype/ ├── prototype/ # 源数据:requirements/flow/layout/review ├── src/ │ ├── App.tsx # React Flow Studio 与 runtime preview @@ -65,7 +65,7 @@ prototype-studio/ 初始化后: ```bash -cd prototype-studio +cd prototype npm install # 安装 package-lock 锁定的依赖 npm run init # 幂等补齐当前项目;已有文件只报告 skip npm run dev # 启动 Vite(加载/依赖错误原样可见) @@ -107,13 +107,23 @@ npm test # 离线合约 + mock + Playwright 关键交互与 模板提供可离线复核的 fixture 检查: ```bash -cd prototype-studio +cd prototype npm run test:incremental ``` 它同时比较 flow、layout、review 的 add/change/delete 结果,并断言 `page.keep`、无关坐标和 `comment.keep` 等未受影响记录保持不变;该检查是边界回归,不替代真实浏览器回归。 +## 版本策略 + +原型默认是持续演进的:新增功能直接在当前 `prototype/` 上增量修改,保持稳定 ID,并同步 +更新 flow、layout、review、实现和相关截图。每轮变更用 Git 提交保留历史;达到评审通过或 +需要冻结时,再打 `prototype-v1` 这类 tag 作为基线。 + +只有需要并行比较多个方案、重做导航/信息架构,或必须保留不可变评审基线时才新开版本分支 +或目录。新版本应记录基于哪个版本、变更范围和受影响的稳定 ID,避免复制出两套长期漂移的 +原型数据。 + ## 如何判断完成 至少应完成:`init` 幂等、`validate` 通过合法 fixture 且拒绝非法 fixture、增量检查通过、 diff --git a/skills/product-prototype/SKILL.md b/skills/product-prototype/SKILL.md index 85be925..c1d8ede 100644 --- a/skills/product-prototype/SKILL.md +++ b/skills/product-prototype/SKILL.md @@ -55,6 +55,17 @@ description: >- 的截图/测试产物。 - 生成物:截图、报告和测试输出只能写入项目约定的 artifacts 目录;它们不是源数据。 +## 命名与版本策略 + +- 初始化生成的工作区目录和 npm package 名称统一为 `prototype`;界面标题仍可使用 + `Prototype Studio`。 +- 后续添加功能默认在当前 `prototype` 上增量修改:保留已有稳定 ID,只新增或局部修改 + flow/layout/review 和对应实现,并用 Git 提交记录每轮变更。 +- 当一轮原型被评审通过或需要冻结时,用 Git tag/分支保存基线,例如 + `prototype-v1`;新需求默认从当前基线继续,不复制一套容易漂移的四类源数据。 +- 只有需要并行比较方案、导航/信息架构大幅重做,或必须长期保留不可变评审基线时,才新开 + 版本分支/目录。新版本必须记录 `based on`、变更范围和受影响的稳定 ID。 + ## 路由 - **初始化**:读取 `references/commands.md`,运行 `python3 scripts/init.py `;先检查目标, diff --git a/skills/product-prototype/assets/studio-template/package-lock.json b/skills/product-prototype/assets/studio-template/package-lock.json index 106a30e..bed35f0 100644 --- a/skills/product-prototype/assets/studio-template/package-lock.json +++ b/skills/product-prototype/assets/studio-template/package-lock.json @@ -1,11 +1,11 @@ { - "name": "prototype-studio-template", + "name": "prototype", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "prototype-studio-template", + "name": "prototype", "version": "0.1.0", "dependencies": { "@xyflow/react": "12.3.1", diff --git a/skills/product-prototype/assets/studio-template/package.json b/skills/product-prototype/assets/studio-template/package.json index 1ab7b6b..0fabf9a 100644 --- a/skills/product-prototype/assets/studio-template/package.json +++ b/skills/product-prototype/assets/studio-template/package.json @@ -1,5 +1,5 @@ { - "name": "prototype-studio-template", + "name": "prototype", "version": "0.1.0", "private": true, "packageManager": "npm@10", diff --git a/skills/product-prototype/assets/studio-template/scripts/init.mjs b/skills/product-prototype/assets/studio-template/scripts/init.mjs index cb04c94..a0063e9 100644 --- a/skills/product-prototype/assets/studio-template/scripts/init.mjs +++ b/skills/product-prototype/assets/studio-template/scripts/init.mjs @@ -16,7 +16,7 @@ try { fs.mkdirSync(target, { recursive: true }); } catch (error) { fail("INIT_WR const created = []; const skipped = []; copyTree(root, target, root); -console.log(`Prototype Studio init: ${target}`); +console.log(`Prototype init: ${target}`); console.log(`created: ${created.length}`); for (const item of created) console.log(` create ${item}`); console.log(`skipped: ${skipped.length}`); diff --git a/skills/product-prototype/references/commands.md b/skills/product-prototype/references/commands.md index db52097..4ba2809 100644 --- a/skills/product-prototype/references/commands.md +++ b/skills/product-prototype/references/commands.md @@ -21,8 +21,8 @@ python3 skills/product-prototype/scripts/check_structure.py python3 skills/product-prototype/scripts/check_docs.py tmp_dir="$(mktemp -d)" -python3 skills/product-prototype/scripts/init.py "$tmp_dir/studio" -python3 skills/product-prototype/scripts/init.py "$tmp_dir/studio" +python3 skills/product-prototype/scripts/init.py "$tmp_dir/prototype" +python3 skills/product-prototype/scripts/init.py "$tmp_dir/prototype" ``` 第二次输出应只有 `skip`,并且第一次创建的源数据不会被覆盖。`validate` 使用无第三方依赖的 diff --git a/skills/product-prototype/scripts/check_structure.py b/skills/product-prototype/scripts/check_structure.py index 265abeb..7da209c 100644 --- a/skills/product-prototype/scripts/check_structure.py +++ b/skills/product-prototype/scripts/check_structure.py @@ -94,7 +94,7 @@ def main() -> int: root = lock.get("packages", {}).get("") if lock.get("lockfileVersion") != 3 or not isinstance(root, dict): errors.append("package-lock.json: expected lockfileVersion 3 with root package") - elif root.get("name") != "prototype-studio-template": + elif root.get("name") != "prototype": errors.append("package-lock.json: root package name mismatch") except json.JSONDecodeError as exc: errors.append(f"package-lock.json: invalid JSON ({exc})") diff --git a/skills/product-prototype/scripts/init.py b/skills/product-prototype/scripts/init.py index b26e827..5e82a03 100644 --- a/skills/product-prototype/scripts/init.py +++ b/skills/product-prototype/scripts/init.py @@ -49,7 +49,7 @@ def main() -> int: parser.error("target must not be the template directory or one of its children") target.mkdir(parents=True, exist_ok=True) created, skipped = copy_missing(source, target) - print(f"Prototype Studio init: {target}") + print(f"Prototype init: {target}") print(f"created: {len(created)}") for path in created: print(f" create {path}")