feat: rename prototype workspace and document versioning

This commit is contained in:
2026-10-19 10:54:02 +08:00
parent 49cd594233
commit 181cce6bfe
8 changed files with 33 additions and 12 deletions
+14 -4
View File
@@ -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、增量检查通过、
+11
View File
@@ -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 <target>`;先检查目标,
@@ -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",
@@ -1,5 +1,5 @@
{
"name": "prototype-studio-template",
"name": "prototype",
"version": "0.1.0",
"private": true,
"packageManager": "npm@10",
@@ -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}`);
@@ -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` 使用无第三方依赖的
@@ -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})")
+1 -1
View File
@@ -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}")