Compare commits
57 Commits
59d352d385
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| bc1cd45c38 | |||
| 2342b63fc2 | |||
| ac7a3abda9 | |||
| 3b851a195e | |||
| 39a34577da | |||
| fd40217ab8 | |||
| 85c2062318 | |||
| 5df451011c | |||
| 00ca7044c7 | |||
| a4fd3d3092 | |||
| 8ee21e5e80 | |||
| c4ea51b7e6 | |||
| caadd87d8f | |||
| 82fb409a9e | |||
| 0b060b0a74 | |||
| 91b390d577 | |||
| 6f8b599629 | |||
| 3d0b835593 | |||
| f86ffb511e | |||
| 7d0bfc123b | |||
| e63ae56021 | |||
| 4c6c8db1a8 | |||
| 86967bb256 | |||
| e982464cb3 | |||
| ac8c67ffc6 | |||
| 2f7d0fa2f8 | |||
| ca78e9c4cf | |||
| 042bebe9d7 | |||
| 17fbf9fe3f | |||
| 810c3a030c | |||
| cbdf941da5 | |||
| f74883701d | |||
| fe770daf77 | |||
| 3c69445d90 | |||
| f1932667aa | |||
| f2f4d0f382 | |||
| 2cf295f95d | |||
| 9b23cb1d24 | |||
| c509223e08 | |||
| b8f27221b2 | |||
| 7a2436a612 | |||
| a951009dae | |||
| a20eec8d57 | |||
| bb34641bfe | |||
| ca023844c9 | |||
| 3da8ce5e13 | |||
| 7bbcd9696e | |||
| 5367d82407 | |||
| 7d5a0657bb | |||
| d102c1b13a | |||
| 1d1f9fb638 | |||
| 0d3a957bdd | |||
| 9f6572600b | |||
| 0646d8c349 | |||
| 22711cf946 | |||
| fa533f75f5 | |||
| ebbb6217c7 |
@@ -1,4 +1,5 @@
|
|||||||
# 策划 Agent Memory Index
|
# 策划 Agent Memory Index
|
||||||
|
|
||||||
- [千禧年怀旧文化灵感](nostalgia-culture-inspirations.md) — 电视剧/广播体操/广场舞/电话热线游戏的灵感记录与共识
|
- [千禧年怀旧文化灵感](nostalgia-culture-inspirations.md) — 电视剧/广播体操/广场舞/电话热线/零食/小孩游戏/乡下活动灵感汇总
|
||||||
|
- [建筑与区域规划](building-area-plan.md) — 城市主场景完整建筑清单、可进入室内、新增设施共识
|
||||||
- [v0.1执行案状态](v01-execution-status.md) — 三份执行案已通过二次质量门审查,流水线可推进至④程序设计
|
- [v0.1执行案状态](v01-execution-status.md) — 三份执行案已通过二次质量门审查,流水线可推进至④程序设计
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
name: building-area-plan
|
||||||
|
description: 城市主场景建筑与区域规划共识,包含完整建筑清单、可进入室内、新增设施
|
||||||
|
metadata:
|
||||||
|
type: project
|
||||||
|
---
|
||||||
|
|
||||||
|
## 城市主场景建筑清单(2026-06-10 确认)
|
||||||
|
|
||||||
|
来源:头脑风暴-2026-06-10-建筑与区域规划.md
|
||||||
|
|
||||||
|
### 关键变更(vs 原场景设计)
|
||||||
|
|
||||||
|
- 小伙伴家:原"全部不可进入" → 4家可进入(简化室内)
|
||||||
|
- 包机房:合并进街机店后屋
|
||||||
|
- 废品回收:固定摊位 + 流动收废品车
|
||||||
|
- 秘密基地:多处散布(工地围挡后、平房区死角等)
|
||||||
|
- 新增店铺:粮油店、服装店/裁缝铺、鞋店(主街东侧)、储蓄所(西侧)
|
||||||
|
- 新增设施:棋牌室(纯氛围)、公交站牌(纯装饰)、公共厕所、自行车棚、信报箱
|
||||||
|
|
||||||
|
### 主街布局(东西排列)
|
||||||
|
|
||||||
|
东→:学校操场 | 小卖部 | 粮油店 | 书店 | 服装店 | 鞋店 · 公交站 · 棋牌室 | 储蓄所 | 录像出租 | 网吧 | 街机店 ←西
|
||||||
|
|
||||||
|
### 可进入室内(~12个)
|
||||||
|
|
||||||
|
完整:主角家、合并小卖部、书店、街机店、网吧、录像出租点
|
||||||
|
简化:死党A家(小区内)、死党B家(平房区)、老板儿子家(小卖部后屋)、女班长家(主角家同楼)
|
||||||
|
|
||||||
|
### 不做的元素
|
||||||
|
|
||||||
|
菜地(留乡下)、装修、游泳(河边不下水)
|
||||||
|
|
||||||
|
### How to apply:
|
||||||
|
- 场景与世界观.md 已更新为最新清单
|
||||||
|
- 新增店铺和设施在后续版本逐步添加(见版本映射)
|
||||||
|
- 概念草案不变(冻结),变更记录在系统设计案中
|
||||||
@@ -54,3 +54,34 @@ metadata:
|
|||||||
- 广播体操和广场舞适合作为场景氛围事件
|
- 广播体操和广场舞适合作为场景氛围事件
|
||||||
- 迈皋桥考据直接用于场景设计的"半城半乡"氛围塑造
|
- 迈皋桥考据直接用于场景设计的"半城半乡"氛围塑造
|
||||||
- 华电子弟学校、工厂宿舍区、菜地、老街都是高还原度的场景元素
|
- 华电子弟学校、工厂宿舍区、菜地、老街都是高还原度的场景元素
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2026-06-10 灵感补充
|
||||||
|
|
||||||
|
来源:头脑风暴-2026-06-10-建筑与区域规划.md
|
||||||
|
|
||||||
|
### 重点新发现(⭐⭐⭐)
|
||||||
|
|
||||||
|
1. **钻狗洞的秘密基地** — 多处散布(工地围挡后、平房区死角),高探索叙事价值
|
||||||
|
2. **叠纸飞机** — 纸张收集+折叠选择+飞行结果三层玩法
|
||||||
|
3. **不知道名字的小哥哥** — 一次性邂逅NPC,极高情感潜力微型叙事线
|
||||||
|
4. **体力系统+家庭动态事件** — 吃饭补充体力→不吃炒饭→换速冻水饺→给饭钱
|
||||||
|
5. **爷爷奶奶家亲戚小孩** — 乡下NPC角色体系(之前乡下NPC完全空白)
|
||||||
|
|
||||||
|
### 新零食/小吃(具体品牌品种)
|
||||||
|
|
||||||
|
大大泡泡糖、秀逗(超酸糖)、无花果丝、老鼠屎(盐津葡萄)、跳跳糖、烤鱿鱼、烤里脊
|
||||||
|
|
||||||
|
### 新小孩游戏
|
||||||
|
|
||||||
|
双人拍手/互推游戏、猜在哪个手里、跑步比赛、叠纸飞机
|
||||||
|
|
||||||
|
### 新人物/社交
|
||||||
|
|
||||||
|
- 北方来南方的同学(与"转学生"角色互补)
|
||||||
|
- 等着去别人家(串门文化)
|
||||||
|
|
||||||
|
### 新乡下活动
|
||||||
|
|
||||||
|
钓鱼(鱼竿)、游泳、挤牛奶、喂鸡掏鸡蛋、菜地浇水、打水漂
|
||||||
|
|||||||
@@ -2,3 +2,4 @@
|
|||||||
- [UE5.7 Python API](ue57-python-api.md) — 实测 API 差异(set_actor_rotation、new_level、CWD、import 路径、Rotator 关键字参数)
|
- [UE5.7 Python API](ue57-python-api.md) — 实测 API 差异(set_actor_rotation、new_level、CWD、import 路径、Rotator 关键字参数)
|
||||||
- [V01 Bugfix](level-builder-bugfix-v01.md) — 8个白模关卡问题诊断修复(搭建指南6+解析器双重解析+构建器静默fallback)
|
- [V01 Bugfix](level-builder-bugfix-v01.md) — 8个白模关卡问题诊断修复(搭建指南6+解析器双重解析+构建器静默fallback)
|
||||||
- [BSP Pivot Types](bsp-pivot-types.md) — 38种 BSP 资产实测锚点+自动补偿机制(角落/底边中心/底面中心)
|
- [BSP Pivot Types](bsp-pivot-types.md) — 38种 BSP 资产实测锚点+自动补偿机制(角落/底边中心/底面中心)
|
||||||
|
- [交互系统架构](interaction-effect-architecture.md) — v1.0 Effect/Action 数据驱动架构(Manager在GI、AInfo Tick、门派生、Prompt独立)
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
---
|
||||||
|
name: interaction-effect-architecture
|
||||||
|
description: 交互系统 v1.0 Effect/Action 数据驱动架构决策记录
|
||||||
|
metadata:
|
||||||
|
type: project
|
||||||
|
---
|
||||||
|
|
||||||
|
## 交互系统架构决策(v1.0 重构,2026-06-11)
|
||||||
|
|
||||||
|
### 核心架构:Effect/Action 数据驱动
|
||||||
|
|
||||||
|
交互物不关心"交互后发生什么",只配置 Effect(由 Action 组成)交给 EffectManager 执行。
|
||||||
|
|
||||||
|
**Why:** v0.1 用 switch(Type) 硬编码,新增交互类型需改代码。v1.0 配数据即可。
|
||||||
|
|
||||||
|
### Manager 归属
|
||||||
|
- FInteractionManager / FEffectManager 是普通 C++ 类,不是 UObject
|
||||||
|
- 由 ASystemDriver (AInfo) 持有,随 World 生灭
|
||||||
|
- 不依赖 UE Subsystem 生命周期,显式控制创建顺序和 Tick 顺序
|
||||||
|
- 所有 UObject 引用用 TWeakObjectPtr,回调用 TFunction
|
||||||
|
- GameInstance 不持有任何交互系统对象,只有 UPersistenceSubsystem 跨 World
|
||||||
|
|
||||||
|
### 分层规则
|
||||||
|
- 表现层只读 Manager 缓存(getter),不碰 Component
|
||||||
|
- Manager 在选择变化时从 Component 读一次并缓存
|
||||||
|
- 逻辑事件仅用于 "A 影响 B"(如 Consume → Persistence)
|
||||||
|
|
||||||
|
### 协调方式
|
||||||
|
- Character 输入回调通过 ASystemDriver::Get(World) 访问两个 Manager
|
||||||
|
- Driver::BeginPlay 中 TFunction 连线 EffectManager.OnEffectComplete → Manager.OnInteractionFinished
|
||||||
|
- PromptComponent 通过 Driver 获取 Manager,只读缓存
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
name: subagent-permissions
|
||||||
|
description: 后台子 Agent 需要预授权 Edit/Write 权限才能修改文件
|
||||||
|
metadata:
|
||||||
|
type: feedback
|
||||||
|
---
|
||||||
|
|
||||||
|
后台子 Agent(game-dev 等)无法弹出交互式权限确认,缺少 Edit/Write 授权时会直接被拒绝文件修改。
|
||||||
|
|
||||||
|
**Why:** 首次启动 game-dev 后台 Agent 实现 P-011 时,因 settings.json 缺少 Edit/Write 权限,Agent 只读了技术文档但无法修改源码。
|
||||||
|
|
||||||
|
**How to apply:** 在 `.claude/settings.json` 的 `permissions.allow` 中添加 `"Edit"` 和 `"Write"`(2026-06-10 已添加)。如果后续新增需要后台运行的工具,同样需要预授权对应权限。
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
# game-reviewer 记忆索引
|
||||||
|
|
||||||
|
- [Gitea Token Permission](gitea-token-permission.md) — reviewer token 仅可评论,标签操作需用 PM token
|
||||||
|
- [P-006 Review](p006-review-note.md) — Issue #17 白模搭建审查通过记录
|
||||||
|
- [P-009 Review](p009-review-note.md) — Issue #20 收集系统程序设计审查通过记录
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
---
|
||||||
|
name: gitea-token-permission
|
||||||
|
description: reviewer token 权限限制——仅可评论,标签操作需 PM token
|
||||||
|
metadata:
|
||||||
|
type: feedback
|
||||||
|
---
|
||||||
|
|
||||||
|
reviewer token (ff336234...) 权限不足,无法修改 Issue 标签(HTTP 403: write permission is required)。评论操作正常。
|
||||||
|
|
||||||
|
**Why:** reviewer token 可能被配置为只读 + 评论权限。
|
||||||
|
|
||||||
|
**How to apply:** 标签更新操作使用 PM 角色执行:`node .claude/skills/gitea-pm/gitea.js --role pm issue labels <number> --set <ids>`
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
---
|
||||||
|
name: p006-review-note
|
||||||
|
description: Issue #17 P-006 白模搭建审查通过记录
|
||||||
|
metadata:
|
||||||
|
type: project
|
||||||
|
---
|
||||||
|
|
||||||
|
P-006(Issue #17)v0.1 白模关卡搭建审查于 2026-06-08 通过。
|
||||||
|
|
||||||
|
**结论:** 7 区域完整覆盖执行案,238 Actor,偏差记录详尽。
|
||||||
|
|
||||||
|
**已知偏差:** Z5 巷子宽度 260cm vs 设计 300cm(重大但不阻塞,260cm 仍可通行)。
|
||||||
|
|
||||||
|
**How to apply:** 后续 6b-6f 子任务可继续推进。空间精度偏差由用户决定是否修正。
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
name: p009-review-note
|
||||||
|
description: Issue #20 P-009 收集系统程序设计审查通过记录
|
||||||
|
metadata:
|
||||||
|
type: project
|
||||||
|
---
|
||||||
|
|
||||||
|
## P-009 收集系统程序设计审查 (2026-06-10)
|
||||||
|
|
||||||
|
- Issue: #20
|
||||||
|
- 审查类型: 程序设计(质量门 2)
|
||||||
|
- 产出文件: `docs/technical/收集系统-技术方案.md`
|
||||||
|
- 结果: **通过**
|
||||||
|
|
||||||
|
### 审查要点
|
||||||
|
- 技术方案文档路径实际为中文文件名 `收集系统-技术方案.md`(非 Issue 中标注的 `collection-system-tech.md`)
|
||||||
|
- 执行案文件名也是中文:`收集系统-执行案.md`(非 `collection-system-execution.md`)
|
||||||
|
- 6 个检查维度全部通过:执行案覆盖度、美术资源需求、架构清晰度、数据流、技术风险、工作量与拆分建议
|
||||||
|
- 标签操作:移除了 gate:art-fail(30) 和 status:in-review(14),添加了 review:pass(33)
|
||||||
@@ -4,6 +4,11 @@ description: "策划 Agent:头脑风暴、产出设计文档(概念草案/
|
|||||||
model: opus
|
model: opus
|
||||||
color: red
|
color: red
|
||||||
memory: project
|
memory: project
|
||||||
|
skills:
|
||||||
|
- gitea-collab
|
||||||
|
- design-execution
|
||||||
|
- level-builder
|
||||||
|
- world-sketcher
|
||||||
---
|
---
|
||||||
|
|
||||||
你是一名精英游戏设计师,拥有深厚的游戏设计理论、玩家心理学和叙事工艺专业能力。你的领域是当前游戏项目,项目具体信息(美术风格、核心玩法、灵感来源等)以 `CLAUDE.md` 中"项目概况"为准,首次工作时读取该文件了解项目上下文。你是用户的创意搭档。
|
你是一名精英游戏设计师,拥有深厚的游戏设计理论、玩家心理学和叙事工艺专业能力。你的领域是当前游戏项目,项目具体信息(美术风格、核心玩法、灵感来源等)以 `CLAUDE.md` 中"项目概况"为准,首次工作时读取该文件了解项目上下文。你是用户的创意搭档。
|
||||||
@@ -217,6 +222,17 @@ GameConfig/ # 数值配置表
|
|||||||
- 对应的场景设计案 `场景-v<XX>-<名称>.md`(氛围愿景)
|
- 对应的场景设计案 `场景-v<XX>-<名称>.md`(氛围愿景)
|
||||||
- 使用 `level-builder` 技能时自动加载模板和资产参考
|
- 使用 `level-builder` 技能时自动加载模板和资产参考
|
||||||
|
|
||||||
|
### 布局草图(前置步骤)
|
||||||
|
|
||||||
|
在产出关卡执行案之前,使用 World Layout Sketcher 画出世界布局:
|
||||||
|
|
||||||
|
1. 引导用户打开 `tools/world-sketcher/sketch.html`
|
||||||
|
2. 用户用颜色画笔绘制各区域(L1 总览 + L2 区域详图)
|
||||||
|
3. 保存草图后,使用 `world-sketcher` 技能分析草图,产出布局解读文档
|
||||||
|
4. 用户确认布局解读后,基于其坐标数据产出关卡执行案
|
||||||
|
|
||||||
|
**为什么需要这一步**:仅靠文字描述空间布局容易产生偏差。绘图让用户和 AI 在坐标、区域关系上达成一致,减少执行案的返工。
|
||||||
|
|
||||||
### 关键规则
|
### 关键规则
|
||||||
|
|
||||||
1. **混合坐标体系**:区域用场景绝对坐标(原点在西南角),区域内物件用相对偏移坐标
|
1. **混合坐标体系**:区域用场景绝对坐标(原点在西南角),区域内物件用相对偏移坐标
|
||||||
@@ -227,6 +243,34 @@ GameConfig/ # 数值配置表
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Git 工作流(develop 分支模型)
|
||||||
|
|
||||||
|
项目使用 `develop` 长期开发分支。所有 agent 在 develop 上工作,迭代结束时由 PM 发起 PR 合并回 main。
|
||||||
|
|
||||||
|
### 开始工作
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh ready
|
||||||
|
```
|
||||||
|
|
||||||
|
### 提交文档
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh commit docs <scope> "中文描述"
|
||||||
|
```
|
||||||
|
示例:`bash .claude/scripts/git-workflow.sh commit docs design "交互系统执行案"`
|
||||||
|
|
||||||
|
### 推送
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh push
|
||||||
|
```
|
||||||
|
|
||||||
|
### 完成工作后
|
||||||
|
1. 推送文档到 develop
|
||||||
|
2. 通过 gitea-collab 在对应 Issue 下评论汇报进度
|
||||||
|
3. 更新 Issue 标签为 `status:in-review`
|
||||||
|
4. 启动 `game-reviewer` 子代理
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 审查交接
|
## 审查交接
|
||||||
|
|
||||||
完成工作并发布 Issue 评论后,启动审查流程:
|
完成工作并发布 Issue 评论后,启动审查流程:
|
||||||
|
|||||||
@@ -4,6 +4,12 @@ description: "程序 Agent:根据执行案设计技术方案、编写 C++/蓝
|
|||||||
model: opus
|
model: opus
|
||||||
color: blue
|
color: blue
|
||||||
memory: project
|
memory: project
|
||||||
|
skills:
|
||||||
|
- requirements-analysis
|
||||||
|
- level-builder
|
||||||
|
- code-implementation
|
||||||
|
- deviation-report
|
||||||
|
- gitea-collab
|
||||||
---
|
---
|
||||||
|
|
||||||
你是游戏项目的**程序 Agent**。项目具体信息(引擎版本、美术风格等)以 `CLAUDE.md` 中"项目概况"为准,首次工作时读取该文件了解项目上下文。
|
你是游戏项目的**程序 Agent**。项目具体信息(引擎版本、美术风格等)以 `CLAUDE.md` 中"项目概况"为准,首次工作时读取该文件了解项目上下文。
|
||||||
@@ -215,6 +221,42 @@ memory: project
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Git 工作流(develop 分支模型)
|
||||||
|
|
||||||
|
项目使用 `develop` 长期开发分支。所有 agent 在 develop 上工作,迭代结束时由 PM 发起 PR 合并回 main。
|
||||||
|
|
||||||
|
### 开始开发
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh ready
|
||||||
|
```
|
||||||
|
确认在 develop 分支上且代码最新。
|
||||||
|
|
||||||
|
### 提交代码
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh commit <type> <scope> "中文描述"
|
||||||
|
```
|
||||||
|
- ⚠️ 只提交自己修改的文件,避免提交其他 agent 的 WIP
|
||||||
|
- 蓝图(.uasset)和 C++ 分开提交
|
||||||
|
- commit message subject ≤ 50 字符
|
||||||
|
|
||||||
|
### 推送
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh push
|
||||||
|
```
|
||||||
|
|
||||||
|
### 完成开发后
|
||||||
|
1. 推送代码到 develop
|
||||||
|
2. 通过 gitea-collab 在对应 Issue 下评论汇报进度
|
||||||
|
3. 更新 Issue 标签为 `status:in-review`
|
||||||
|
4. 启动 `game-reviewer` 子代理
|
||||||
|
|
||||||
|
### 开发中发现 main 有更新
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh catchup
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 代码规范
|
## 代码规范
|
||||||
|
|
||||||
- C++ 和蓝图遵循 UE5 编码规范
|
- C++ 和蓝图遵循 UE5 编码规范
|
||||||
|
|||||||
@@ -3,6 +3,9 @@ name: "game-pm"
|
|||||||
description: "项目管理 Agent:进度管理(3阶段状态机)、任务分配与追踪、开发决策咨询。触发关键词:开始工作、进度、分配任务、优先级。"
|
description: "项目管理 Agent:进度管理(3阶段状态机)、任务分配与追踪、开发决策咨询。触发关键词:开始工作、进度、分配任务、优先级。"
|
||||||
model: opus
|
model: opus
|
||||||
memory: project
|
memory: project
|
||||||
|
skills:
|
||||||
|
- gitea-pm
|
||||||
|
- gitea-collab
|
||||||
---
|
---
|
||||||
|
|
||||||
你是游戏项目的项目管理(PM)Agent。项目具体信息(引擎、美术风格、核心玩法等)以 `CLAUDE.md` 中"项目概况"为准,首次工作时读取该文件了解项目上下文。
|
你是游戏项目的项目管理(PM)Agent。项目具体信息(引擎、美术风格、核心玩法等)以 `CLAUDE.md` 中"项目概况"为准,首次工作时读取该文件了解项目上下文。
|
||||||
@@ -100,6 +103,36 @@ memory: project
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Git 工作流(develop 分支模型)
|
||||||
|
|
||||||
|
项目使用 `develop` 长期开发分支,所有 agent 在 develop 上工作。
|
||||||
|
|
||||||
|
### PM 日常
|
||||||
|
```bash
|
||||||
|
# 会话开始时同步
|
||||||
|
bash .claude/scripts/git-workflow.sh ready
|
||||||
|
```
|
||||||
|
|
||||||
|
### 迭代完成 → 发布
|
||||||
|
当所有 Issue 都 review:pass 且用户确认发布时:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建 develop → main 的 PR
|
||||||
|
bash .claude/scripts/git-workflow.sh release "迭代名称"
|
||||||
|
# 或手动:
|
||||||
|
# node .claude/skills/gitea-pm/gitea.js --role pm pr create --base main --head develop --title "标题" --body "描述"
|
||||||
|
```
|
||||||
|
|
||||||
|
通知用户在 Gitea 审查并合并 PR。
|
||||||
|
|
||||||
|
### 用户合并后同步
|
||||||
|
```bash
|
||||||
|
bash .claude/scripts/git-workflow.sh post-release
|
||||||
|
```
|
||||||
|
自动同步 main 并将 merge commit 同步回 develop。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## 决策框架
|
## 决策框架
|
||||||
|
|
||||||
### 你可以自主决定:
|
### 你可以自主决定:
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ description: "审查子代理 — 角色完成工作后启动,审查交付物
|
|||||||
model: opus
|
model: opus
|
||||||
color: purple
|
color: purple
|
||||||
memory: project
|
memory: project
|
||||||
|
tools: Read, Grep, Glob, Bash, Skill
|
||||||
|
skills:
|
||||||
|
- gitea-collab
|
||||||
|
- quality-gate-review
|
||||||
---
|
---
|
||||||
|
|
||||||
你是游戏项目的**审查子代理**。你由策划、程序等角色在完成工作后启动,负责审查他们的交付物质量。
|
你是游戏项目的**审查子代理**。你由策划、程序等角色在完成工作后启动,负责审查他们的交付物质量。
|
||||||
|
|||||||
@@ -6,23 +6,30 @@
|
|||||||
|
|
||||||
## 分支策略
|
## 分支策略
|
||||||
|
|
||||||
**轻量 Feature Branch** — 单人开发,`main` 永远可玩可编译。
|
**develop 长期开发分支模型** — 单人开发 + 多 Agent 协作。
|
||||||
|
|
||||||
|
```
|
||||||
|
main ─────────── 永远可玩可编译,受保护,禁止直接推送
|
||||||
|
│
|
||||||
|
│ PR (Gitea) ← 里程碑/迭代结束时,PM 发起
|
||||||
|
│
|
||||||
|
└── develop ──── 长期分支,所有 agent 在此工作
|
||||||
|
```
|
||||||
|
|
||||||
|
| 分支 | 生命期 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| `main` | 永久 | 稳定版本,受保护 |
|
||||||
|
| `develop` | 永久 | 日常开发分支,所有 agent 共用 |
|
||||||
|
|
||||||
|
**辅助分支(可选,用于实验):**
|
||||||
|
|
||||||
| 分支 | 前缀 | 生命期 | 说明 |
|
| 分支 | 前缀 | 生命期 | 说明 |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
| 主线 | `main` | 永久 | 稳定版本,不直接在上面开发 |
|
|
||||||
| 功能 | `feature/` | 合并后删 | 新系统、新功能 |
|
|
||||||
| 修复 | `fix/` | 合并后删 | Bug 修复 |
|
|
||||||
| 原型 | `prototype/` | 实验完即删 | 技术验证,随便写 |
|
| 原型 | `prototype/` | 实验完即删 | 技术验证,随便写 |
|
||||||
| 发布 | `release/` | 永久 | 从 main 切出,版本标记 |
|
| 发布 | `release/` | 永久 | 从 main 切出,版本标记 |
|
||||||
|
|
||||||
**命名规则:** `<类型>/<小写连字符描述>`
|
|
||||||
```
|
|
||||||
feature/player-movement fix/camera-clipping release/v0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
**流程:**
|
**流程:**
|
||||||
1. 从 `main` 拉分支 → 2. 开发并提交 → 3. 测试通过后合并回 `main` → 4. 删除分支
|
1. 所有开发在 `develop` 上进行 → 2. 迭代完成时创建 PR → 3. 审查通过后合并回 `main`
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -100,3 +107,33 @@ Host gitea micecola.top
|
|||||||
**内网地址**(家里用):`ssh://sc-gitea@192.168.1.22:2223/starmen1265/ChildHood.git`
|
**内网地址**(家里用):`ssh://sc-gitea@192.168.1.22:2223/starmen1265/ChildHood.git`
|
||||||
|
|
||||||
完整规范见 → [GIT-GUIDE.md](GIT-GUIDE.md)
|
完整规范见 → [GIT-GUIDE.md](GIT-GUIDE.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 自动化工作流
|
||||||
|
|
||||||
|
`git-workflow.sh` 脚本封装了常用 git 操作:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 开始工作:确保在 develop 上且最新
|
||||||
|
bash .claude/scripts/git-workflow.sh ready
|
||||||
|
|
||||||
|
# 提交修改
|
||||||
|
bash .claude/scripts/git-workflow.sh commit <type> <scope> "中文描述"
|
||||||
|
|
||||||
|
# 推送到远程
|
||||||
|
bash .claude/scripts/git-workflow.sh push
|
||||||
|
|
||||||
|
# 查看状态
|
||||||
|
bash .claude/scripts/git-workflow.sh status
|
||||||
|
```
|
||||||
|
|
||||||
|
### PM 发布流程
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 创建 develop → main PR
|
||||||
|
bash .claude/scripts/git-workflow.sh release "迭代名称"
|
||||||
|
|
||||||
|
# 用户在 Gitea 合并后同步
|
||||||
|
bash .claude/scripts/git-workflow.sh post-release
|
||||||
|
```
|
||||||
|
|||||||
+36
-60
@@ -7,81 +7,57 @@
|
|||||||
|
|
||||||
## 一、分支策略
|
## 一、分支策略
|
||||||
|
|
||||||
采用**轻量级 Feature Branch 模型**,避免企业级复杂流程,保持 `main` 分支随时可玩。
|
采用 **develop 长期开发分支模型**,适合单人开发 + 多 AI Agent 协作场景。所有 agent 在 `develop` 上工作,迭代结束时通过 PR 合并回 `main`。
|
||||||
|
|
||||||
### 1.1 分支总览
|
### 1.1 分支总览
|
||||||
|
|
||||||
```
|
```
|
||||||
main ──────────────────────────────────────── 稳定主线
|
main ──────────── 永远可玩可编译,受保护,禁止直接推送
|
||||||
│
|
│
|
||||||
├── feature/player-movement ───→ 合并后删除
|
│ PR (Gitea) ← 里程碑/迭代结束时,PM 发起
|
||||||
├── feature/inventory-system ──→ 合并后删除
|
│
|
||||||
├── fix/camera-clipping ───────→ 合并后删除
|
└── develop ──── 长期分支,所有 agent 的日常工作分支
|
||||||
├── prototype/procedural-gen ──→ 实验完即删
|
│
|
||||||
└── release/v0.1 ──────────────→ 永久保留
|
├── 程序1 提交代码
|
||||||
|
├── 策划 提交文档
|
||||||
|
├── 程序2 提交代码
|
||||||
|
└── 迭代就绪 → PR develop→main
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.2 分支类型
|
### 1.2 分支类型
|
||||||
|
|
||||||
| 分支 | 前缀 | 用途 | 合并目标 | 生命周期 |
|
| 分支 | 用途 | 生命周期 |
|
||||||
|---|---|---|---|---|
|
|---|---|---|
|
||||||
| 主线 | `main` | 稳定可玩版本,每次提交都能编译运行 | — | 永久 |
|
| `main` | 稳定可玩版本,受保护 | 永久 |
|
||||||
| 功能 | `feature/` | 新系统、新功能开发 | `main` | 完成后删除 |
|
| `develop` | 日常开发,所有 agent 共用 | 永久 |
|
||||||
| 修复 | `fix/` | Bug 修复 | `main` | 完成后删除 |
|
| `prototype/` | 技术验证、玩法实验 | 实验完即删 |
|
||||||
| 原型 | `prototype/` | 技术验证、玩法实验 | 合并或丢弃 | 实验完即删 |
|
| `release/` | 版本发布标记,只从 main 切出 | 永久保留 |
|
||||||
| 发布 | `release/` | 版本发布标记,只从 `main` 切出 | — | 永久保留 |
|
|
||||||
|
|
||||||
### 1.3 命名规范
|
### 1.3 工作流程
|
||||||
|
|
||||||
格式:`<类型>/<简短描述>`,全小写,用连字符分隔单词。
|
|
||||||
|
|
||||||
```
|
```
|
||||||
# ✅ 好的命名
|
1. 开始工作(agent 自动执行)
|
||||||
feature/player-movement
|
bash .claude/scripts/git-workflow.sh ready
|
||||||
feature/inventory-system
|
|
||||||
feature/dialogue-tree
|
|
||||||
fix/camera-clipping-through-walls
|
|
||||||
fix/enemy-ai-stuck-on-navmesh
|
|
||||||
prototype/procedural-dungeon
|
|
||||||
release/v0.1
|
|
||||||
|
|
||||||
# ❌ 不好的命名
|
2. 开发并提交
|
||||||
my-new-feature
|
bash .claude/scripts/git-workflow.sh commit <type> <scope> "描述"
|
||||||
fix-bug
|
|
||||||
test
|
3. 推送到远程
|
||||||
feature/AddPlayerMovement
|
bash .claude/scripts/git-workflow.sh push
|
||||||
|
|
||||||
|
4. 迭代完成,PM 创建 PR
|
||||||
|
bash .claude/scripts/git-workflow.sh release "迭代名称"
|
||||||
|
|
||||||
|
5. 用户在 Gitea 合并后同步
|
||||||
|
bash .claude/scripts/git-workflow.sh post-release
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.4 工作流程
|
### 1.4 核心原则
|
||||||
|
|
||||||
```
|
- **`main` 永远可玩**:通过 develop → main PR 合并,不直接推送
|
||||||
1. 开始新功能
|
- **develop 是工作台**:所有 agent 在 develop 上并行工作
|
||||||
git checkout main
|
- **不同文件不冲突**:各 agent 修改不同文件,可真正并行
|
||||||
git pull
|
- **同一文件需协调**:两个 agent 修改同一文件时需顺序执行
|
||||||
git checkout -b feature/xxx
|
|
||||||
|
|
||||||
2. 开发过程中(随时提交)
|
|
||||||
git add .
|
|
||||||
git commit -m "wip(xxx): 进度描述"
|
|
||||||
|
|
||||||
3. 功能完成,测试通过
|
|
||||||
git checkout main
|
|
||||||
git merge feature/xxx
|
|
||||||
git branch -d feature/xxx # 删除已合并分支
|
|
||||||
|
|
||||||
4. 到达里程碑
|
|
||||||
git checkout main
|
|
||||||
git tag -a v0.1.0 -m "第一个可玩原型"
|
|
||||||
git checkout -b release/v0.1
|
|
||||||
git push origin release/v0.1
|
|
||||||
```
|
|
||||||
|
|
||||||
### 1.5 核心原则
|
|
||||||
|
|
||||||
- **`main` 永远可玩**:坏了就留在 feature 分支继续改,不要合并进 main
|
|
||||||
- **功能分支粒度**:一个分支做一件事,不要在一个分支里同时做多个系统
|
|
||||||
- **原型不怕乱**:`prototype/` 分支随便写,验证完再决定合并还是丢弃
|
|
||||||
- **定期清理**:已合并的 feature/fix 分支及时删除,避免分支堆积
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
> 本模板供策划产出关卡执行案时使用。关卡执行案是场景设计案的"空间精度版本"——将氛围描述转化为带有坐标、尺寸和资产建议的结构化搭建指南,供程序在 UE5 编辑器中搭建白模。
|
> 本模板供策划产出关卡执行案时使用。关卡执行案是场景设计案的"空间精度版本"——将氛围描述转化为带有坐标、尺寸和资产建议的结构化搭建指南,供程序在 UE5 编辑器中搭建白模。
|
||||||
>
|
>
|
||||||
|
> **注意**:交互物和收集品的放置**不在本模板范围内**,由交互系统/收集系统后续在白盒关卡上叠加。
|
||||||
|
>
|
||||||
> 文件命名:`关卡-v<XX>-<名称>-执行案.md`(如 `关卡-v01-城郊街区-执行案.md`)
|
> 文件命名:`关卡-v<XX>-<名称>-执行案.md`(如 `关卡-v01-城郊街区-执行案.md`)
|
||||||
> 存放位置:`docs/design/<阶段>/`(与其他执行案同目录)
|
> 存放位置:`docs/design/<阶段>/`(与其他执行案同目录)
|
||||||
|
|
||||||
@@ -131,30 +133,18 @@
|
|||||||
| Zx-P02 | | | | | |
|
| Zx-P02 | | | | | |
|
||||||
| ... | | | | | |
|
| ... | | | | | |
|
||||||
|
|
||||||
#### 3.x.4 可交互物体标记
|
#### 3.x.4 组合资产标记
|
||||||
|
|
||||||
<!-- 引用交互系统执行案中的交互物,此处只标注空间位置 -->
|
<!-- 需要多个 Primitives 拼搭的物件(无直接 BSP 匹配)。如无此类物件可删除本节。 -->
|
||||||
|
|
||||||
| 交互编号 | 物件名称 | 交互类型 | 相对原点偏移 (ΔX,ΔY,ΔZ) | 触发半径 (cm) | 引用 |
|
| 编号 | 物件名称 | 期望尺寸 (约, cm) | 推荐拼搭方案 | 说明 |
|
||||||
|---------|---------|---------|----------------------|-------------|------|
|
|------|---------|-----------------|-------------|------|
|
||||||
| Zx-I01 | <!-- 如 旧冰箱 --> | <!-- 如 观察 --> | (200,400,10) | <!-- 如 150 --> | 交互系统-执行案 #n |
|
| Zx-C01 | <!-- 如 旧收音机 --> | <!-- 如 20x15x12 --> | <!-- 如 Cube(0.2,0.15,0.12) + Cylinder天线 --> | <!-- 如 放在柜台上 --> |
|
||||||
| Zx-I02 | | | | | |
|
|
||||||
| ... | | | | | |
|
|
||||||
|
|
||||||
> 交互类型参照交互系统执行案中的分类(观察/拾取/操作/对话等)。
|
|
||||||
> "引用"列填写交互系统执行案中对应交互物的编号,确保跨文档一致。
|
|
||||||
|
|
||||||
#### 3.x.5 收集品标记
|
|
||||||
|
|
||||||
<!-- 引用收集系统执行案中的收集品,此处只标注空间位置 -->
|
|
||||||
|
|
||||||
| 收集编号 | 物品名称 | 稀有度 | 相对原点偏移 (ΔX,ΔY,ΔZ) | 引用 |
|
|
||||||
|---------|---------|--------|----------------------|------|
|
|
||||||
| Zx-C01 | <!-- 如 彩色弹珠 --> | <!-- 如 普通/稀有 --> | (500,200,0) | 收集系统-执行案 #n |
|
|
||||||
| Zx-C02 | | | | |
|
| Zx-C02 | | | | |
|
||||||
| ... | | | | | |
|
| ... | | | | | |
|
||||||
|
|
||||||
> 稀有度影响拾取物的视觉效果标识(普通=白色光,稀有=金色光),具体表现由收集系统技术方案定义。
|
> 组合资产将在搭建指南生成阶段展开为多个 Primitive Actor,并在组合资产清单中记录拼搭方案。
|
||||||
|
> 用户确认后的组合资产方案将回馈到 asset-catalog 模板库,供后续关卡直接引用。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -183,14 +173,6 @@
|
|||||||
| G-E02 | | | | | |
|
| G-E02 | | | | | |
|
||||||
| ... | | | | | |
|
| ... | | | | | |
|
||||||
|
|
||||||
### 4.3 收集品位置汇总
|
|
||||||
|
|
||||||
| # | 物品名称 | 所在区域 | 绝对坐标 (X,Y,Z) | 稀有度 | 引用 |
|
|
||||||
|---|---------|---------|-----------------|--------|------|
|
|
||||||
| 1 | | | | | 收集系统-执行案 #n |
|
|
||||||
| 2 | | | | | |
|
|
||||||
| ... | | | | | |
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 五、场景边界与遮挡
|
## 五、场景边界与遮挡
|
||||||
@@ -225,10 +207,10 @@
|
|||||||
### 策划填写要点
|
### 策划填写要点
|
||||||
|
|
||||||
1. **先确定区域坐标布局**(第二章),确保所有区域在总尺寸内不重叠、流线合理
|
1. **先确定区域坐标布局**(第二章),确保所有区域在总尺寸内不重叠、流线合理
|
||||||
2. **逐区域填写**(第三章),按"结构体 → 布景 → 交互物 → 收集品"的顺序
|
2. **逐区域填写**(第三章),按"结构体 → 布景 → 组合资产"的顺序
|
||||||
3. **BSP 资产建议是方向性指引**:写资产类别名和组合方式即可(如 "Wall_400x300 × 2"),不需要写文件路径
|
3. **BSP 资产建议是方向性指引**:写资产类别名和组合方式即可(如 "Wall_400x300 × 2"),不需要写文件路径
|
||||||
4. **尺寸以 cm 为单位**,对应 UE5 的 1 uu = 1 cm
|
4. **尺寸以 cm 为单位**,对应 UE5 的 1 uu = 1 cm
|
||||||
5. **交叉引用**:交互物和收集品必须引用对应系统执行案中的编号,保持跨文档一致
|
5. **组合资产**:无法用单个 BSP 资产匹配的物件,在 3.x.4 中记录拼搭方案
|
||||||
|
|
||||||
### 不要填写的内容
|
### 不要填写的内容
|
||||||
|
|
||||||
@@ -237,6 +219,7 @@
|
|||||||
- ❌ Blueprint 类名
|
- ❌ Blueprint 类名
|
||||||
- ❌ 精确的硬编码参数值(标注"建议值,可调"并附范围)
|
- ❌ 精确的硬编码参数值(标注"建议值,可调"并附范围)
|
||||||
- ❌ 代码或脚本
|
- ❌ 代码或脚本
|
||||||
|
- ❌ 交互物和收集品位置(由系统后续叠加)
|
||||||
|
|
||||||
### 与场景设计案的关系
|
### 与场景设计案的关系
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,326 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# git-workflow.sh — ChildHood 项目 Git 工作流自动化
|
||||||
|
#
|
||||||
|
# 基于 develop 长期开发分支模型。
|
||||||
|
# 所有 agent 在 develop 上工作,迭代结束时通过 PR 合并回 main。
|
||||||
|
#
|
||||||
|
# 用法: bash .claude/scripts/git-workflow.sh <command> [args...]
|
||||||
|
#
|
||||||
|
# 命令:
|
||||||
|
# ready 确保在 develop 上且最新
|
||||||
|
# commit <type> <scope> "<msg>" 格式化提交
|
||||||
|
# push 推送 develop 到远程
|
||||||
|
# submit <issue-number> 一键 commit + push(从 Issue 拉取信息)
|
||||||
|
# release [milestone-name] 创建 develop→main 的 PR
|
||||||
|
# post-release 合并后同步 main 和 develop
|
||||||
|
# catchup 将 develop 合并最新 main 的内容
|
||||||
|
# status 显示当前分支和状态
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ─── 配置 ───
|
||||||
|
DEVELOP_BRANCH="develop"
|
||||||
|
MAIN_BRANCH="main"
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
||||||
|
GITEA_PM_CLI="node $PROJECT_ROOT/.claude/skills/gitea-pm/gitea.js"
|
||||||
|
GITEA_COLLAB_CLI="node $PROJECT_ROOT/.claude/skills/gitea-collab/gitea.js"
|
||||||
|
|
||||||
|
# ─── 颜色 ───
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
info() { echo -e "${BLUE}ℹ️ $*${NC}"; }
|
||||||
|
ok() { echo -e "${GREEN}✅ $*${NC}"; }
|
||||||
|
warn() { echo -e "${YELLOW}⚠️ $*${NC}"; }
|
||||||
|
fail() { echo -e "${RED}❌ $*${NC}"; exit 1; }
|
||||||
|
|
||||||
|
# ─── 当前分支 ───
|
||||||
|
current_branch() { git rev-parse --abbrev-ref HEAD; }
|
||||||
|
|
||||||
|
# ─── 检查是否有未提交的修改 ───
|
||||||
|
has_changes() { [ -n "$(git status --porcelain)" ]; }
|
||||||
|
|
||||||
|
# ─── 检测 UE5 二进制文件 ───
|
||||||
|
has_ue5_binaries() {
|
||||||
|
git diff --cached --name-only 2>/dev/null | grep -qE '\.(uasset|umap)$'
|
||||||
|
}
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# 命令实现
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
cmd_ready() {
|
||||||
|
info "准备工作环境..."
|
||||||
|
|
||||||
|
local branch
|
||||||
|
branch=$(current_branch)
|
||||||
|
|
||||||
|
# 如果不在 develop 上,切换过去
|
||||||
|
if [ "$branch" != "$DEVELOP_BRANCH" ]; then
|
||||||
|
if has_changes; then
|
||||||
|
warn "有未提交的修改,暂存中..."
|
||||||
|
git stash push --include-untracked -m "auto-stash-$(date +%s)"
|
||||||
|
fi
|
||||||
|
git checkout "$DEVELOP_BRANCH" 2>/dev/null || {
|
||||||
|
# 本地没有 develop 分支,从 main 创建
|
||||||
|
info "本地没有 $DEVELOP_BRANCH 分支,从 $MAIN_BRANCH 创建..."
|
||||||
|
git checkout "$MAIN_BRANCH"
|
||||||
|
git pull origin "$MAIN_BRANCH"
|
||||||
|
git checkout -b "$DEVELOP_BRANCH"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 拉取最新 develop
|
||||||
|
if git remote get-url origin &>/dev/null; then
|
||||||
|
info "拉取远程 $DEVELOP_BRANCH..."
|
||||||
|
git pull origin "$DEVELOP_BRANCH" 2>/dev/null || {
|
||||||
|
# 远程没有 develop,首次推送
|
||||||
|
warn "远程没有 $DEVELOP_BRANCH 分支,将首次推送"
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
local commit_hash
|
||||||
|
commit_hash=$(git rev-parse --short HEAD)
|
||||||
|
ok "已在 $DEVELOP_BRANCH 分支上 (${commit_hash})"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_commit() {
|
||||||
|
local type="${1:-}"
|
||||||
|
local scope="${2:-}"
|
||||||
|
local message="${3:-}"
|
||||||
|
|
||||||
|
if [ -z "$type" ] || [ -z "$scope" ] || [ -z "$message" ]; then
|
||||||
|
fail "用法: git-workflow.sh commit <type> <scope> \"<message>\"\n 示例: git-workflow.sh commit feat player \"实现角色跳跃\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 校验分支
|
||||||
|
if [ "$(current_branch)" != "$DEVELOP_BRANCH" ]; then
|
||||||
|
warn "当前不在 $DEVELOP_BRANCH 分支上 (当前: $(current_branch))"
|
||||||
|
read -rp "继续提交? [y/N] " confirm
|
||||||
|
[[ "$confirm" != [yY] ]] && { info "已取消"; return; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 暂存所有修改
|
||||||
|
if ! has_changes; then
|
||||||
|
warn "没有检测到修改"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
git add -A
|
||||||
|
|
||||||
|
# UE5 二进制文件检测
|
||||||
|
if has_ue5_binaries; then
|
||||||
|
warn "检测到 .uasset/.umap 文件,请确保 commit message 清楚描述了变更内容"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 格式化 commit message
|
||||||
|
local commit_msg="${type}(${scope}): ${message}"
|
||||||
|
|
||||||
|
# subject ≤ 50 字符检查(仅消息部分)
|
||||||
|
local msg_len=${#commit_msg}
|
||||||
|
if [ "$msg_len" -gt 72 ]; then
|
||||||
|
warn "提交消息较长 ($msg_len 字符),建议精简"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git commit -m "$commit_msg"
|
||||||
|
ok "已提交: $commit_msg"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_push() {
|
||||||
|
local branch
|
||||||
|
branch=$(current_branch)
|
||||||
|
|
||||||
|
info "推送 $branch 到远程..."
|
||||||
|
|
||||||
|
# 设置上游分支(首次)
|
||||||
|
if ! git rev-parse --abbrev-ref "@{upstream}" &>/dev/null; then
|
||||||
|
git push -u origin "$branch"
|
||||||
|
else
|
||||||
|
git push origin "$branch"
|
||||||
|
fi
|
||||||
|
|
||||||
|
ok "已推送 $branch 到远程"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_submit() {
|
||||||
|
local issue_number="${1:-}"
|
||||||
|
if [ -z "$issue_number" ]; then
|
||||||
|
fail "用法: git-workflow.sh submit <issue-number>"
|
||||||
|
fi
|
||||||
|
|
||||||
|
info "提交工作 (Issue #$issue_number)..."
|
||||||
|
|
||||||
|
# 从 Issue 拉取标题作为 commit 参考
|
||||||
|
local issue_title=""
|
||||||
|
issue_title=$($GITEA_COLLAB_CLI --role dev issue get "$issue_number" --json 2>/dev/null | grep -o '"title":"[^"]*"' | head -1 | sed 's/"title":"//;s/"//') || true
|
||||||
|
|
||||||
|
# 提交
|
||||||
|
if has_changes; then
|
||||||
|
if [ -n "$issue_title" ]; then
|
||||||
|
info "Issue 标题: $issue_title"
|
||||||
|
fi
|
||||||
|
warn "有未提交的修改,请先运行: git-workflow.sh commit <type> <scope> \"<message>\""
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 推送
|
||||||
|
cmd_push
|
||||||
|
|
||||||
|
ok "工作已提交到 $DEVELOP_BRANCH (关联 Issue #$issue_number)"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_release() {
|
||||||
|
local milestone_name="${1:-}"
|
||||||
|
|
||||||
|
info "准备发布 PR ($DEVELOP_BRANCH → $MAIN_BRANCH)..."
|
||||||
|
|
||||||
|
# 确保在 develop 上
|
||||||
|
if [ "$(current_branch)" != "$DEVELOP_BRANCH" ]; then
|
||||||
|
fail "请先切换到 $DEVELOP_BRANCH 分支"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 确保本地最新
|
||||||
|
git pull origin "$DEVELOP_BRANCH"
|
||||||
|
|
||||||
|
# 获取里程碑名称
|
||||||
|
if [ -z "$milestone_name" ]; then
|
||||||
|
# 尝试从当前里程碑获取
|
||||||
|
milestone_name=$($GITEA_PM_CLI --role pm milestone list --state open --json 2>/dev/null | grep -o '"title":"[^"]*"' | head -1 | sed 's/"title":"//;s/"//') || "迭代发布"
|
||||||
|
if [ -z "$milestone_name" ]; then
|
||||||
|
milestone_name="迭代发布"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
local pr_title="Merge develop → main: ${milestone_name}"
|
||||||
|
|
||||||
|
# 构造 PR body(汇总已关闭的 Issue)
|
||||||
|
local pr_body="## 发布合并\n\n将 \`${DEVELOP_BRANCH}\` 分支的成果合并到 \`${MAIN_BRANCH}\`。\n\n### 里程碑\n${milestone_name}"
|
||||||
|
|
||||||
|
# 创建 PR
|
||||||
|
info "创建 PR: $pr_title"
|
||||||
|
local pr_result
|
||||||
|
pr_result=$($GITEA_PM_CLI --role pm pr create \
|
||||||
|
--base "$MAIN_BRANCH" \
|
||||||
|
--head "$DEVELOP_BRANCH" \
|
||||||
|
--title "$pr_title" \
|
||||||
|
--body "$(echo -e "$pr_body")" \
|
||||||
|
--json 2>&1) || {
|
||||||
|
fail "创建 PR 失败: $pr_result"
|
||||||
|
}
|
||||||
|
|
||||||
|
local pr_number
|
||||||
|
pr_number=$(echo "$pr_result" | grep -o '"number":[0-9]*' | head -1 | sed 's/"number"://') || true
|
||||||
|
|
||||||
|
if [ -n "$pr_number" ]; then
|
||||||
|
ok "PR #$pr_number 已创建: $pr_title"
|
||||||
|
info "请在 Gitea 审查并合并: http://micecola.top:8418/starmen1265/ChildHood/pulls/$pr_number"
|
||||||
|
else
|
||||||
|
ok "PR 已创建,请查看 Gitea"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_post_release() {
|
||||||
|
info "合并后同步..."
|
||||||
|
|
||||||
|
# 同步 main
|
||||||
|
info "同步 $MAIN_BRANCH..."
|
||||||
|
git checkout "$MAIN_BRANCH"
|
||||||
|
git pull origin "$MAIN_BRANCH"
|
||||||
|
ok "$MAIN_BRANCH 已更新"
|
||||||
|
|
||||||
|
# 切回 develop 并合并 main(保持 develop 包含 merge commit)
|
||||||
|
info "同步 $DEVELOP_BRANCH..."
|
||||||
|
git checkout "$DEVELOP_BRANCH"
|
||||||
|
git merge "$MAIN_BRANCH" --no-edit
|
||||||
|
git push origin "$DEVELOP_BRANCH"
|
||||||
|
ok "$DEVELOP_BRANCH 已同步(包含 $MAIN_BRANCH 的 merge commit)"
|
||||||
|
|
||||||
|
local commit_hash
|
||||||
|
commit_hash=$(git rev-parse --short HEAD)
|
||||||
|
ok "完成,当前在 $DEVELOP_BRANCH (${commit_hash})"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_catchup() {
|
||||||
|
info "将 develop 跟上最新的 $MAIN_BRANCH..."
|
||||||
|
|
||||||
|
if [ "$(current_branch)" != "$DEVELOP_BRANCH" ]; then
|
||||||
|
fail "请先切换到 $DEVELOP_BRANCH 分支"
|
||||||
|
fi
|
||||||
|
|
||||||
|
git fetch origin
|
||||||
|
git merge "origin/$MAIN_BRANCH" --no-edit
|
||||||
|
ok "$DEVELOP_BRANCH 已合并最新 $MAIN_BRANCH"
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd_status() {
|
||||||
|
local branch
|
||||||
|
branch=$(current_branch)
|
||||||
|
local commit_hash
|
||||||
|
commit_hash=$(git rev-parse --short HEAD)
|
||||||
|
local changed
|
||||||
|
changed=$(git status --porcelain | wc -l | tr -d ' ')
|
||||||
|
|
||||||
|
echo -e "${BLUE}═══ Git 工作流状态 ═══${NC}"
|
||||||
|
echo " 当前分支: ${branch} (${commit_hash})"
|
||||||
|
|
||||||
|
if [ "$branch" = "$DEVELOP_BRANCH" ]; then
|
||||||
|
echo -e " ${GREEN}✓ 在 develop 开发分支上${NC}"
|
||||||
|
elif [ "$branch" = "$MAIN_BRANCH" ]; then
|
||||||
|
echo -e " ${YELLOW}⚠ 在 main 分支上,请切换到 develop 开始工作${NC}"
|
||||||
|
else
|
||||||
|
echo -e " ${YELLOW}⚠ 在非标准分支上: $branch${NC}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo " 未提交修改: ${changed} 个文件"
|
||||||
|
|
||||||
|
if [ "$changed" -gt 0 ]; then
|
||||||
|
echo ""
|
||||||
|
git status --short
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 远程同步状态
|
||||||
|
if git rev-parse "@{upstream}" &>/dev/null; then
|
||||||
|
local ahead behind
|
||||||
|
ahead=$(git rev-list --count "@{upstream}..HEAD" 2>/dev/null || echo "0")
|
||||||
|
behind=$(git rev-list --count "HEAD..@{upstream}" 2>/dev/null || echo "0")
|
||||||
|
echo " 远程状态: ahead ${ahead}, behind ${behind}"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
# 入口
|
||||||
|
# ═══════════════════════════════════════════════════════════════
|
||||||
|
|
||||||
|
case "${1:-}" in
|
||||||
|
ready) cmd_ready ;;
|
||||||
|
commit) shift; cmd_commit "$@" ;;
|
||||||
|
push) cmd_push ;;
|
||||||
|
submit) shift; cmd_submit "$@" ;;
|
||||||
|
release) shift; cmd_release "$@" ;;
|
||||||
|
post-release) cmd_post_release ;;
|
||||||
|
catchup) cmd_catchup ;;
|
||||||
|
status) cmd_status ;;
|
||||||
|
*)
|
||||||
|
echo "git-workflow.sh — ChildHood 项目 Git 工作流自动化"
|
||||||
|
echo ""
|
||||||
|
echo "用法: bash .claude/scripts/git-workflow.sh <command> [args...]"
|
||||||
|
echo ""
|
||||||
|
echo "命令:"
|
||||||
|
echo " ready 确保在 develop 上且最新"
|
||||||
|
echo " commit <type> <scope> \"<msg>\" 格式化提交"
|
||||||
|
echo " push 推送 develop 到远程"
|
||||||
|
echo " submit <issue-number> 推送并关联 Issue"
|
||||||
|
echo " release [milestone-name] 创建 develop→main PR"
|
||||||
|
echo " post-release 合并后同步 main 和 develop"
|
||||||
|
echo " catchup 将 develop 合并最新 main"
|
||||||
|
echo " status 显示当前分支和状态"
|
||||||
|
echo ""
|
||||||
|
echo "工作流模型: develop 长期开发分支 → 迭代完成时 PR 合并回 main"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
{
|
{
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"allow": [
|
"allow": [
|
||||||
"Bash(dir:*)",
|
|
||||||
"Bash(git:*)",
|
|
||||||
"mcp__web-reader__webReader",
|
"mcp__web-reader__webReader",
|
||||||
"mcp__zread__get_repo_structure",
|
"mcp__zread__get_repo_structure",
|
||||||
"mcp__web-search-prime__webSearchPrime",
|
"mcp__web-search-prime__webSearchPrime",
|
||||||
"WebSearch",
|
"WebSearch",
|
||||||
"Read:*",
|
"Read",
|
||||||
"Bash(\"C:/Program Files/Epic Games/UE_5.7/Engine/Build/BatchFiles/Build.bat\":*)"
|
"Edit",
|
||||||
|
"Write",
|
||||||
|
"Bash"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hooks": {
|
"hooks": {
|
||||||
|
|||||||
@@ -148,7 +148,43 @@ node .claude/skills/gitea-collab/gitea.js --role reviewer issue labels <number>
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 7. 汇报模板
|
## 7. PR 查询
|
||||||
|
|
||||||
|
非 PM 角色可以查看 PR 状态(创建和合并由 PM 负责):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 列出 PR
|
||||||
|
node .claude/skills/gitea-collab/gitea.js --role <角色名> pr list
|
||||||
|
|
||||||
|
# 查看 PR 详情
|
||||||
|
node .claude/skills/gitea-collab/gitea.js --role <角色名> pr get <number>
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Git 工作流
|
||||||
|
|
||||||
|
所有 agent 在 `develop` 长期开发分支上工作:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 开始工作时:确保在 develop 上
|
||||||
|
bash .claude/scripts/git-workflow.sh ready
|
||||||
|
|
||||||
|
# 提交代码/文档
|
||||||
|
bash .claude/scripts/git-workflow.sh commit <type> <scope> "中文描述"
|
||||||
|
|
||||||
|
# 推送到远程
|
||||||
|
bash .claude/scripts/git-workflow.sh push
|
||||||
|
|
||||||
|
# 查看当前状态
|
||||||
|
bash .claude/scripts/git-workflow.sh status
|
||||||
|
```
|
||||||
|
|
||||||
|
详见 `.claude/refs/GIT-GUIDE-LITE.md` 的"自动化工作流"章节。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 汇报模板
|
||||||
|
|
||||||
### 策划汇报
|
### 策划汇报
|
||||||
|
|
||||||
|
|||||||
@@ -222,6 +222,27 @@ class GiteaAPI {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== Pull Requests ======
|
||||||
|
|
||||||
|
listPullRequests(params = {}) {
|
||||||
|
return this.request('GET', '/pulls', null, { state: 'open', limit: 50, ...params });
|
||||||
|
}
|
||||||
|
|
||||||
|
getPullRequest(number) {
|
||||||
|
return this.request('GET', `/pulls/${number}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
createPullRequest(data) {
|
||||||
|
return this.request('POST', '/pulls', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
mergePullRequest(number, data = {}) {
|
||||||
|
return this.request('POST', `/pulls/${number}/merge`, {
|
||||||
|
Do: data.style || 'merge',
|
||||||
|
...data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ====== 辅助方法 ======
|
// ====== 辅助方法 ======
|
||||||
|
|
||||||
/** 通过名称查找标签,返回 ID(不存在则返回 null) */
|
/** 通过名称查找标签,返回 ID(不存在则返回 null) */
|
||||||
|
|||||||
@@ -520,6 +520,84 @@ cmd.pipeline = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ──────── pr ────────
|
||||||
|
|
||||||
|
cmd.pr = {
|
||||||
|
async list(api, opts) {
|
||||||
|
const params = {};
|
||||||
|
if (opts.options.state) params.state = opts.options.state;
|
||||||
|
if (opts.options.base) params.base = opts.options.base;
|
||||||
|
if (opts.options.head) params.head = opts.options.head;
|
||||||
|
|
||||||
|
const prs = await api.listPullRequests(params);
|
||||||
|
out(prs);
|
||||||
|
if (!opts.options.json) {
|
||||||
|
outText(`\n🔀 Pull Requests (${prs.length || 0})\n`);
|
||||||
|
if (!prs || !prs.length) { outText(' (无)'); return; }
|
||||||
|
table(
|
||||||
|
['#', '标题', '状态', 'Base', 'Head', '合并'],
|
||||||
|
prs.map(p => [
|
||||||
|
p.number,
|
||||||
|
truncate(p.title, 35),
|
||||||
|
p.state,
|
||||||
|
p.base?.ref || '—',
|
||||||
|
p.head?.ref || '—',
|
||||||
|
p.merged ? '✅' : '—',
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async get(api, opts) {
|
||||||
|
const num = opts.rest[0];
|
||||||
|
if (!num) { fail('用法: pr get <number>'); return; }
|
||||||
|
const pr = await api.getPullRequest(num);
|
||||||
|
out(pr);
|
||||||
|
if (!opts.options.json) {
|
||||||
|
outText(`\n🔀 PR #${pr.number}: ${pr.title}`);
|
||||||
|
outText(` 状态: ${pr.state}`);
|
||||||
|
outText(` ${pr.base?.ref} ← ${pr.head?.ref}`);
|
||||||
|
outText(` 合并: ${pr.merged ? '✅ 已合并' : '❌ 未合并'}`);
|
||||||
|
if (pr.body) {
|
||||||
|
outText(`\n--- Body ---\n${pr.body.slice(0, 500)}${pr.body.length > 500 ? '…' : ''}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async create(api, opts) {
|
||||||
|
const base = opts.options.base || 'main';
|
||||||
|
const head = opts.options.head;
|
||||||
|
const title = opts.options.title;
|
||||||
|
const body = opts.options.body || '';
|
||||||
|
|
||||||
|
if (!head || !title) {
|
||||||
|
fail('用法: pr create --head <分支> --title "标题" [--base main] [--body "描述"]');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pr = await api.createPullRequest({ base, head, title, body });
|
||||||
|
out(pr);
|
||||||
|
if (!opts.options.json) {
|
||||||
|
ok(`PR #${pr.number} 已创建: ${pr.title}`);
|
||||||
|
outText(` ${pr.html_url}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async merge(api, opts) {
|
||||||
|
const num = opts.rest[0];
|
||||||
|
if (!num) { fail('用法: pr merge <number> [--style merge|squash|rebase]'); return; }
|
||||||
|
const style = opts.options.style || 'merge';
|
||||||
|
|
||||||
|
const pr = await api.getPullRequest(num);
|
||||||
|
if (pr.merged) { fail(`PR #${num} 已合并,无需重复操作`); return; }
|
||||||
|
if (pr.mergeable === false) { fail(`PR #${num} 存在冲突,无法自动合并。请先解决冲突。`); return; }
|
||||||
|
|
||||||
|
const result = await api.mergePullRequest(num, { style });
|
||||||
|
out(result);
|
||||||
|
if (!opts.options.json) ok(`PR #${num} 已合并 (${style})`);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// ──────── test ────────
|
// ──────── test ────────
|
||||||
|
|
||||||
cmd.test = {
|
cmd.test = {
|
||||||
@@ -682,6 +760,11 @@ Gitea CLI — 项目管理工具
|
|||||||
pipeline status 查看当前流水线进度
|
pipeline status 查看当前流水线进度
|
||||||
pipeline update <#> 更新 Pipeline 字段 --field <阶段|当前迭代> --value <值>
|
pipeline update <#> 更新 Pipeline 字段 --field <阶段|当前迭代> --value <值>
|
||||||
|
|
||||||
|
pr list 列出 Pull Requests [--state open|closed|all] [--base <分支>] [--head <分支>]
|
||||||
|
pr get <#> 查看 PR 详情
|
||||||
|
pr create 创建 PR --head <分支> --title "标题" [--base main] [--body "描述"]
|
||||||
|
pr merge <#> 合并 PR [--style merge|squash|rebase]
|
||||||
|
|
||||||
test 验证所有 API 接口
|
test 验证所有 API 接口
|
||||||
|
|
||||||
角色自动映射:
|
角色自动映射:
|
||||||
|
|||||||
@@ -218,7 +218,36 @@ Pipeline Tracker 是一个 Meta Issue,仅记录**无法从 Issue/Milestone 推
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 8. 标签体系
|
## 8. PR 操作(发布合并)
|
||||||
|
|
||||||
|
迭代完成时,PM 负责创建 develop → main 的 PR:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 列出当前 PR
|
||||||
|
node .claude/skills/gitea-pm/gitea.js --role pm pr list
|
||||||
|
|
||||||
|
# 创建发布 PR
|
||||||
|
bash .claude/scripts/git-workflow.sh release "迭代名称"
|
||||||
|
|
||||||
|
# 或手动创建
|
||||||
|
node .claude/skills/gitea-pm/gitea.js --role pm pr create \
|
||||||
|
--base main --head develop \
|
||||||
|
--title "Merge develop → main: 迭代名称" \
|
||||||
|
--body "发布描述"
|
||||||
|
|
||||||
|
# 查看 PR 详情
|
||||||
|
node .claude/skills/gitea-pm/gitea.js --role pm pr get <number>
|
||||||
|
|
||||||
|
# 合并 PR(用户审查确认后)
|
||||||
|
node .claude/skills/gitea-pm/gitea.js --role pm pr merge <number> --style merge
|
||||||
|
|
||||||
|
# 合并后同步
|
||||||
|
bash .claude/scripts/git-workflow.sh post-release
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. 标签体系
|
||||||
|
|
||||||
从 `gitea-config.json` 的 `labels` 字段定义。`label init` 命令从此配置创建标签。
|
从 `gitea-config.json` 的 `labels` 字段定义。`label init` 命令从此配置创建标签。
|
||||||
|
|
||||||
|
|||||||
@@ -222,6 +222,27 @@ class GiteaAPI {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ====== Pull Requests ======
|
||||||
|
|
||||||
|
listPullRequests(params = {}) {
|
||||||
|
return this.request('GET', '/pulls', null, { state: 'open', limit: 50, ...params });
|
||||||
|
}
|
||||||
|
|
||||||
|
getPullRequest(number) {
|
||||||
|
return this.request('GET', `/pulls/${number}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
createPullRequest(data) {
|
||||||
|
return this.request('POST', '/pulls', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
mergePullRequest(number, data = {}) {
|
||||||
|
return this.request('POST', `/pulls/${number}/merge`, {
|
||||||
|
Do: data.style || 'merge', // merge | squash | rebase
|
||||||
|
...data,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// ====== 辅助方法 ======
|
// ====== 辅助方法 ======
|
||||||
|
|
||||||
/** 通过名称查找标签,返回 ID(不存在则返回 null) */
|
/** 通过名称查找标签,返回 ID(不存在则返回 null) */
|
||||||
|
|||||||
@@ -520,6 +520,87 @@ cmd.pipeline = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ──────── pr ────────
|
||||||
|
|
||||||
|
cmd.pr = {
|
||||||
|
async list(api, opts) {
|
||||||
|
const params = {};
|
||||||
|
if (opts.options.state) params.state = opts.options.state;
|
||||||
|
if (opts.options.base) params.base = opts.options.base;
|
||||||
|
if (opts.options.head) params.head = opts.options.head;
|
||||||
|
|
||||||
|
const prs = await api.listPullRequests(params);
|
||||||
|
out(prs);
|
||||||
|
if (!opts.options.json) {
|
||||||
|
outText(`\n🔀 Pull Requests (${prs.length || 0})\n`);
|
||||||
|
if (!prs || !prs.length) { outText(' (无)'); return; }
|
||||||
|
table(
|
||||||
|
['#', '标题', '状态', 'Base', 'Head', '合并'],
|
||||||
|
prs.map(p => [
|
||||||
|
p.number,
|
||||||
|
truncate(p.title, 35),
|
||||||
|
p.state,
|
||||||
|
p.base?.ref || '—',
|
||||||
|
p.head?.ref || '—',
|
||||||
|
p.merged ? '✅' : '—',
|
||||||
|
])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async get(api, opts) {
|
||||||
|
const num = opts.rest[0];
|
||||||
|
if (!num) { fail('用法: pr get <number>'); return; }
|
||||||
|
const pr = await api.getPullRequest(num);
|
||||||
|
out(pr);
|
||||||
|
if (!opts.options.json) {
|
||||||
|
outText(`\n🔀 PR #${pr.number}: ${pr.title}`);
|
||||||
|
outText(` 状态: ${pr.state}`);
|
||||||
|
outText(` ${pr.base?.ref} ← ${pr.head?.ref}`);
|
||||||
|
outText(` 合并: ${pr.merged ? '✅ 已合并' : '❌ 未合并'}`);
|
||||||
|
outText(` 创建: ${pr.created_at?.slice(0, 10)}`);
|
||||||
|
outText(` 更新: ${pr.updated_at?.slice(0, 10)}`);
|
||||||
|
if (pr.body) {
|
||||||
|
outText(`\n--- Body ---\n${pr.body.slice(0, 500)}${pr.body.length > 500 ? '…' : ''}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async create(api, opts) {
|
||||||
|
const base = opts.options.base || 'main';
|
||||||
|
const head = opts.options.head;
|
||||||
|
const title = opts.options.title;
|
||||||
|
const body = opts.options.body || '';
|
||||||
|
|
||||||
|
if (!head || !title) {
|
||||||
|
fail('用法: pr create --head <分支> --title "标题" [--base main] [--body "描述"]');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pr = await api.createPullRequest({ base, head, title, body });
|
||||||
|
out(pr);
|
||||||
|
if (!opts.options.json) {
|
||||||
|
ok(`PR #${pr.number} 已创建: ${pr.title}`);
|
||||||
|
outText(` ${pr.html_url}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async merge(api, opts) {
|
||||||
|
const num = opts.rest[0];
|
||||||
|
if (!num) { fail('用法: pr merge <number> [--style merge|squash|rebase]'); return; }
|
||||||
|
const style = opts.options.style || 'merge';
|
||||||
|
|
||||||
|
// 先检查 PR 状态
|
||||||
|
const pr = await api.getPullRequest(num);
|
||||||
|
if (pr.merged) { fail(`PR #${num} 已合并,无需重复操作`); return; }
|
||||||
|
if (pr.mergeable === false) { fail(`PR #${num} 存在冲突,无法自动合并。请先解决冲突。`); return; }
|
||||||
|
|
||||||
|
const result = await api.mergePullRequest(num, { style });
|
||||||
|
out(result);
|
||||||
|
if (!opts.options.json) ok(`PR #${num} 已合并 (${style})`);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
// ──────── test ────────
|
// ──────── test ────────
|
||||||
|
|
||||||
cmd.test = {
|
cmd.test = {
|
||||||
@@ -682,6 +763,11 @@ Gitea CLI — 项目管理工具
|
|||||||
pipeline status 查看当前流水线进度
|
pipeline status 查看当前流水线进度
|
||||||
pipeline update <#> 更新 Pipeline 字段 --field <阶段|当前迭代> --value <值>
|
pipeline update <#> 更新 Pipeline 字段 --field <阶段|当前迭代> --value <值>
|
||||||
|
|
||||||
|
pr list 列出 Pull Requests [--state open|closed|all] [--base <分支>] [--head <分支>]
|
||||||
|
pr get <#> 查看 PR 详情
|
||||||
|
pr create 创建 PR --head <分支> --title "标题" [--base main] [--body "描述"]
|
||||||
|
pr merge <#> 合并 PR [--style merge|squash|rebase]
|
||||||
|
|
||||||
test 验证所有 API 接口
|
test 验证所有 API 接口
|
||||||
|
|
||||||
角色自动映射:
|
角色自动映射:
|
||||||
|
|||||||
@@ -0,0 +1,156 @@
|
|||||||
|
---
|
||||||
|
name: "world-sketcher"
|
||||||
|
description: >
|
||||||
|
世界布局草图工具。当需要"画布局"、"世界草图"、"分析布局草图"、"layout sketch"、
|
||||||
|
"interpret sketch"、"world layout"、"世界布局"、"布局草图"时使用。
|
||||||
|
引导用户使用绘图工具画出世界布局,分析草图 PNG 产出结构化布局数据 Markdown,
|
||||||
|
作为关卡执行案的前置输入。
|
||||||
|
---
|
||||||
|
|
||||||
|
# 世界布局草图工具 (World Layout Sketcher)
|
||||||
|
|
||||||
|
> 三级层次化布局绘图 → AI 解读 → 结构化布局文档 → 关卡执行案前置输入
|
||||||
|
|
||||||
|
## 触发条件
|
||||||
|
|
||||||
|
- **用户主动触发**:用户说"画布局"、"世界草图"、"layout sketch"、"world layout"等
|
||||||
|
- **策划关卡执行案前置**:策划需要产出关卡执行案,但不存在对应的布局解读文档
|
||||||
|
- **用户提供草图分析**:用户提供了草图 PNG 要求分析
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 工具位置
|
||||||
|
|
||||||
|
```
|
||||||
|
tools/world-sketcher/
|
||||||
|
sketch.html # 绘图工具(浏览器打开)
|
||||||
|
README.md # 使用说明、画笔图例
|
||||||
|
output/ # 草图输出目录
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三级层次
|
||||||
|
|
||||||
|
| 层级 | 范围 | 绘制内容 |
|
||||||
|
|------|------|---------|
|
||||||
|
| L1 场景总览 | ≤1km | 大区域、主干道、河流 |
|
||||||
|
| L2 区域详图 | ≤300m | 建筑、内部道路、绿化、水体 |
|
||||||
|
| L3 建筑内部 | 预留 | 拖放细节资产(未实现) |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 画笔颜色 → 材质映射
|
||||||
|
|
||||||
|
| 画笔 | 颜色 | 地形 | UE 材质 | 默认高度 |
|
||||||
|
|------|------|------|---------|---------|
|
||||||
|
| 道路 Road | `#909090` 灰 | 道路 | MI_DevGray | — |
|
||||||
|
| 建筑 Building | `#E07020` 橙 | 建筑物 | MI_DevOrange | 3m |
|
||||||
|
| 水域 Water | `#40A0D0` 天蓝 | 河流/水塘 | MI_DevSkyBlue | — |
|
||||||
|
| 植被 Greenery | `#40B040` 绿 | 树木/草地 | MI_DevGreen | 2m |
|
||||||
|
| 不可通行 Blocked | `#A07040` 棕 | 山体/围墙 | MI_DevBrown | 3m |
|
||||||
|
| 区域 Zone | `#D04040` 红 | 区域划分 | MI_DevRed | 3m |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 工作流
|
||||||
|
|
||||||
|
### 步骤 1:检查现有草图
|
||||||
|
|
||||||
|
检查 `tools/world-sketcher/output/` 目录下是否有当前场景的草图文件。
|
||||||
|
|
||||||
|
- 如果存在:跳到步骤 3
|
||||||
|
- 如果不存在:进入步骤 2
|
||||||
|
|
||||||
|
### 步骤 2:引导用户绘图
|
||||||
|
|
||||||
|
1. 告诉用户打开 `tools/world-sketcher/sketch.html`
|
||||||
|
2. 说明画笔含义:不同颜色代表不同地形类型
|
||||||
|
3. 建议先画 L1 场景总览(大区域、主干道、河流),用区域画笔画出各区域轮廓
|
||||||
|
4. 双击已画区域命名(如"城郊小街"),勾选"可进入"创建 L2 详图
|
||||||
|
5. 进入 L2 后用建筑、道路等画笔细化区域内部
|
||||||
|
6. 完成后点"保存全部",将文件保存到 `output/` 目录
|
||||||
|
|
||||||
|
### 步骤 3:AI 读取布局数据
|
||||||
|
|
||||||
|
**数据源以 JSON 为准,不依赖 PNG 像素分析。**
|
||||||
|
|
||||||
|
1. 读取 JSON 布局数据(`*-scene.json`):elements(含 `height_m`、`connections`)、regions(含 `bounds_world_m`)、层级关系
|
||||||
|
2. 交叉参考场景设计案 `场景-v<XX>-<名称>.md` 的氛围描述,将 JSON 区域与场景设计案的区域描述建立映射
|
||||||
|
3. 如需视觉确认,可参考预览 PNG(非必须,仅用于核对区域形状)
|
||||||
|
|
||||||
|
> **说明**:PNG 文件仍保存在 ZIP 中用于保存/加载画布,但 AI 分析流程以结构化 JSON 为准。
|
||||||
|
|
||||||
|
### 步骤 4:产出布局解读文档
|
||||||
|
|
||||||
|
产出文件:`docs/design/<场景名>-layout-v<XX>.md`
|
||||||
|
|
||||||
|
文档结构:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# <场景名> 世界布局解读 v<XX>
|
||||||
|
|
||||||
|
> 基于 `tools/world-sketcher/output/` 中的草图分析产出。
|
||||||
|
|
||||||
|
## 草图参数
|
||||||
|
| 参数 | 值 |
|
||||||
|
|------|-----|
|
||||||
|
| 世界尺寸 | ... |
|
||||||
|
| 坐标系 | 原点西南角,X+东,Y+北 |
|
||||||
|
| 比例 | 1px = ... |
|
||||||
|
|
||||||
|
## L1 场景总览
|
||||||
|
|
||||||
|
### 识别区域
|
||||||
|
| 区域编号 | 名称 | 推测坐标范围 (cm) | 推测尺寸 | 地形类型 | 高度 (m) | 连通到 | 标识色建议 |
|
||||||
|
|---------|------|-------------------|---------|---------|---------|--------|-----------|
|
||||||
|
|
||||||
|
### 识别道路/河流
|
||||||
|
| 编号 | 名称 | 类型 | 走向 | 长度 |
|
||||||
|
|
||||||
|
### 区域连通关系
|
||||||
|
| 连接 | 方式 | 说明 |
|
||||||
|
|
||||||
|
## L2 区域详图(如有)
|
||||||
|
|
||||||
|
### <区域名>
|
||||||
|
| 编号 | 名称 | 类型 | 推测坐标 | 尺寸 | 高度 (m) | 连通到 |
|
||||||
|
|
||||||
|
## 待确认问题
|
||||||
|
1. ...
|
||||||
|
|
||||||
|
## 待细化项
|
||||||
|
- ...
|
||||||
|
```
|
||||||
|
|
||||||
|
**数据来源说明**:
|
||||||
|
- 区域坐标、尺寸:来自 JSON 中 `regions[].bounds_world_m`,乘以 100 转为 cm
|
||||||
|
- 高度:来自 JSON 中 `elements[].height_m`,直接采用(无需 AI 推断)
|
||||||
|
- 连通关系:来自 JSON 中 `elements[].connections`,直接采用(无需 AI 推断)
|
||||||
|
- 地形类型和标识色:来自 JSON 中 `elements[].type` → brush_legend 映射
|
||||||
|
|
||||||
|
### 步骤 5:用户确认
|
||||||
|
|
||||||
|
将解读文档呈现给用户,等待用户确认或修正。确认后,该文档作为关卡执行案的前置输入。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 与关卡执行案的衔接
|
||||||
|
|
||||||
|
布局解读文档产出并经用户确认后,策划产出关卡执行案时:
|
||||||
|
|
||||||
|
1. **区域坐标**:直接采用解读文档中的推测坐标范围作为起点
|
||||||
|
2. **区域连通**:采用解读文档中的连通关系
|
||||||
|
3. **标识色**:采用解读文档中的标识色建议(与画笔颜色一致)
|
||||||
|
4. **需细化**:解读文档中"待细化项"的内容在执行案中必须给出精确数据
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 注意事项
|
||||||
|
|
||||||
|
- 画笔颜色是**强制预定义**的,不允许自由拾色,保证颜色→材质的映射一致
|
||||||
|
- 坐标系与 `zone_config.py` 一致:原点西南角,X+ 东,Y+ 北,单位 cm
|
||||||
|
- AI 解读时如有不确定之处,**必须**列入"待确认问题",不要自行假设
|
||||||
|
- L3 建筑内部本期不实现,仅预留 `has_interior` 标记
|
||||||
|
- **高度 (`height_m`)**:由用户在双击命名时输入,AI 直接采用,不做推断
|
||||||
|
- **连通关系 (`connections`)**:由用户在双击命名时勾选,双向同步,AI 直接采用
|
||||||
@@ -111,6 +111,11 @@ scripts/.gitea-tokens.json
|
|||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
|
# ==============================
|
||||||
|
# AI 生图工具 — API 密钥
|
||||||
|
# ==============================
|
||||||
|
ai-art-research/.env
|
||||||
|
|
||||||
# ==============================
|
# ==============================
|
||||||
# 其他
|
# 其他
|
||||||
# ==============================
|
# ==============================
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
/.claude
|
/.claude
|
||||||
/.git
|
/.git
|
||||||
/.vscode
|
/.vscode
|
||||||
|
/ai-art-research
|
||||||
/Content
|
/Content
|
||||||
/DerivedDataCache
|
/DerivedDataCache
|
||||||
/docs
|
/docs
|
||||||
/GameConfig
|
/GameConfig
|
||||||
/Intermediate
|
/Intermediate
|
||||||
/Saved
|
/Saved
|
||||||
|
/scripts
|
||||||
/tools
|
/tools
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
[/Script/EngineSettings.GameMapsSettings]
|
[/Script/EngineSettings.GameMapsSettings]
|
||||||
GameDefaultMap=/Game/ThirdPerson/Lvl_ThirdPerson.Lvl_ThirdPerson
|
GameDefaultMap=/Game/Maps/LVL_SuburbanV01.LVL_SuburbanV01
|
||||||
EditorStartupMap=/Game/ThirdPerson/Lvl_ThirdPerson.Lvl_ThirdPerson
|
EditorStartupMap=/Game/Maps/LVL_SuburbanV01.LVL_SuburbanV01
|
||||||
GlobalDefaultGameMode=/Game/ThirdPerson/Blueprints/BP_ThirdPersonGameMode.BP_ThirdPersonGameMode_C
|
GlobalDefaultGameMode=/Game/BP/Basic/BP_ChildHoodGameMode.BP_ChildHoodGameMode_C
|
||||||
|
|
||||||
[/Script/Engine.RendererSettings]
|
[/Script/Engine.RendererSettings]
|
||||||
r.ReflectionMethod=1
|
r.ReflectionMethod=1
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user