@aipper/aiws-spec 0.0.27 → 0.0.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/docs/cli-interface.md +10 -12
- package/docs/opencode-autonomous-swarm.md +178 -0
- package/docs/opencode-omo-adapter.md +123 -4
- package/docs/opencode-omo-validation-checklist.md +47 -0
- package/docs/opencode-subagent-first.md +187 -0
- package/docs/workflow-delegation-context-injection.md +217 -0
- package/docs/workflow-delegation-contracts.json +68 -1
- package/docs/workflow-delegation-contracts.md +3 -0
- package/docs/workflow-delegation-contracts.schema.json +95 -0
- package/docs/workflow-governance-rules.json +47 -6
- package/docs/workflow-governance-rules.md +7 -6
- package/docs/workflow-governance-rules.schema.json +39 -1
- package/docs/workflow-router-rules.json +63 -8
- package/docs/workflow-router-rules.md +15 -6
- package/docs/workflow-stage-contracts.json +16 -8
- package/docs/workflow-stage-contracts.md +7 -7
- package/package.json +1 -1
- package/templates/workspace/.agents/skills/using-aiws/SKILL.md +22 -8
- package/templates/workspace/.agents/skills/ws-commit/SKILL.md +6 -118
- package/templates/workspace/.agents/skills/ws-deliver/SKILL.md +6 -218
- package/templates/workspace/.agents/skills/ws-dev/SKILL.md +52 -141
- package/templates/workspace/.agents/skills/ws-finish/SKILL.md +6 -205
- package/templates/workspace/.agents/skills/ws-handoff/SKILL.md +10 -44
- package/templates/workspace/.agents/skills/ws-intake/SKILL.md +87 -0
- package/templates/workspace/.agents/skills/ws-plan/SKILL.md +15 -9
- package/templates/workspace/.agents/skills/ws-plan-verify/SKILL.md +6 -49
- package/templates/workspace/.agents/skills/ws-review/SKILL.md +6 -1
- package/templates/workspace/.agents/skills/ws-verify-before-complete/SKILL.md +12 -53
- package/templates/workspace/.claude/commands/ws-intake.md +19 -0
- package/templates/workspace/.claude/commands/ws-review.md +5 -1
- package/templates/workspace/.claude/settings.json.example +26 -0
- package/templates/workspace/.claude/skills/ws-commit/SKILL.md +6 -118
- package/templates/workspace/.claude/skills/ws-deliver/SKILL.md +6 -218
- package/templates/workspace/.claude/skills/ws-dev/SKILL.md +52 -141
- package/templates/workspace/.claude/skills/ws-finish/SKILL.md +6 -205
- package/templates/workspace/.claude/skills/ws-handoff/SKILL.md +10 -44
- package/templates/workspace/.claude/skills/ws-intake/SKILL.md +31 -0
- package/templates/workspace/.claude/skills/ws-plan-verify/SKILL.md +6 -49
- package/templates/workspace/.claude/skills/ws-review/SKILL.md +6 -1
- package/templates/workspace/.claude/skills/ws-verify-before-complete/SKILL.md +12 -53
- package/templates/workspace/.opencode/command/ws-auto.md +33 -0
- package/templates/workspace/.opencode/command/ws-autonomy.md +25 -0
- package/templates/workspace/.opencode/command/ws-intake.md +22 -0
- package/templates/workspace/.opencode/command/ws-review.md +5 -1
- package/templates/workspace/.opencode/commands/ws-auto.md +33 -0
- package/templates/workspace/.opencode/commands/ws-autonomy.md +25 -0
- package/templates/workspace/.opencode/commands/ws-commit.md +4 -56
- package/templates/workspace/.opencode/commands/ws-deliver.md +10 -50
- package/templates/workspace/.opencode/commands/ws-finish.md +8 -65
- package/templates/workspace/.opencode/commands/ws-handoff.md +9 -17
- package/templates/workspace/.opencode/commands/ws-intake.md +22 -0
- package/templates/workspace/.opencode/commands/ws-migrate.md +10 -17
- package/templates/workspace/.opencode/commands/ws-plan-verify.md +5 -15
- package/templates/workspace/.opencode/commands/ws-pull.md +6 -75
- package/templates/workspace/.opencode/commands/ws-push.md +7 -82
- package/templates/workspace/.opencode/commands/ws-review.md +5 -1
- package/templates/workspace/.opencode/commands/ws-submodule-setup.md +8 -47
- package/templates/workspace/.opencode/commands/ws-verify-before-complete.md +10 -19
- package/templates/workspace/.opencode/helpers/approval-whitelist-check.sh +148 -0
- package/templates/workspace/.opencode/helpers/approval-whitelist-run.sh +82 -0
- package/templates/workspace/.opencode/helpers/approval-whitelist-watchdog.sh +144 -0
- package/templates/workspace/.opencode/helpers/tmux-swarm-rescue.sh +56 -0
- package/templates/workspace/.opencode/helpers/tmux-swarm-scan.sh +46 -0
- package/templates/workspace/.opencode/oh-my-opencode.json.example +64 -4
- package/templates/workspace/.opencode/skills/using-aiws/SKILL.md +93 -77
- package/templates/workspace/.opencode/skills/ws-analyze/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-auto/SKILL.md +46 -0
- package/templates/workspace/.opencode/skills/ws-autonomy/SKILL.md +62 -0
- package/templates/workspace/.opencode/skills/ws-bugfix/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-commit/SKILL.md +6 -118
- package/templates/workspace/.opencode/skills/ws-delegate/SKILL.md +93 -40
- package/templates/workspace/.opencode/skills/ws-deliver/SKILL.md +6 -218
- package/templates/workspace/.opencode/skills/ws-dev/SKILL.md +53 -142
- package/templates/workspace/.opencode/skills/ws-dev-lite/SKILL.md +19 -6
- package/templates/workspace/.opencode/skills/ws-finish/SKILL.md +6 -205
- package/templates/workspace/.opencode/skills/ws-frontend-design/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-handoff/SKILL.md +10 -44
- package/templates/workspace/.opencode/skills/ws-intake/SKILL.md +40 -0
- package/templates/workspace/.opencode/skills/ws-migrate/SKILL.md +6 -42
- package/templates/workspace/.opencode/skills/ws-plan/SKILL.md +4 -2
- package/templates/workspace/.opencode/skills/ws-plan-verify/SKILL.md +6 -49
- package/templates/workspace/.opencode/skills/ws-preflight/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-pull/SKILL.md +8 -109
- package/templates/workspace/.opencode/skills/ws-push/SKILL.md +8 -100
- package/templates/workspace/.opencode/skills/ws-quality-review/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-req-change/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-req-contract-sync/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-req-contract-validate/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-req-flow-sync/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-req-review/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-review/SKILL.md +14 -3
- package/templates/workspace/.opencode/skills/ws-rule/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-spec-review/SKILL.md +1 -1
- package/templates/workspace/.opencode/skills/ws-submodule-setup/SKILL.md +10 -57
- package/templates/workspace/.opencode/skills/ws-verify-before-complete/SKILL.md +12 -53
- package/templates/workspace/AGENTS.md +12 -5
- package/templates/workspace/AI_PROJECT.md +1 -1
- package/templates/workspace/changes/README.md +9 -12
- package/templates/workspace/manifest.json +277 -203
- package/templates/workspace/.agents/skills/ws-migrate/SKILL.md +0 -54
- package/templates/workspace/.agents/skills/ws-pull/SKILL.md +0 -119
- package/templates/workspace/.agents/skills/ws-push/SKILL.md +0 -110
- package/templates/workspace/.agents/skills/ws-submodule-setup/SKILL.md +0 -65
- package/templates/workspace/.claude/skills/ws-migrate/SKILL.md +0 -54
- package/templates/workspace/.claude/skills/ws-pull/SKILL.md +0 -119
- package/templates/workspace/.claude/skills/ws-push/SKILL.md +0 -110
- package/templates/workspace/.claude/skills/ws-submodule-setup/SKILL.md +0 -65
|
@@ -1,230 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ws-deliver
|
|
3
|
-
description:
|
|
3
|
+
description: `aiws ws-deliver` 的薄包装入口
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
# ws-deliver
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
- 适配 superproject + submodule(数量不固定)的交付收尾:
|
|
10
|
-
1) 先逐个提交 submodule(每个 repo 单独确认 commit message)
|
|
11
|
-
2) 再提交 superproject(包含 submodule gitlink 指针更新 + 变更工件/代码)
|
|
12
|
-
3) 最后 fast-forward 合并回目标分支(复用 `aiws change finish`,减少手动 merge 出错)
|
|
8
|
+
`aiws ws-deliver` 的薄包装入口。
|
|
13
9
|
|
|
14
|
-
非目标(强制):
|
|
15
|
-
- 不自动 `git add -A`(避免误提交)
|
|
16
|
-
- 不自动 push
|
|
17
|
-
- 不自动删除分支
|
|
18
|
-
|
|
19
|
-
前置(强制):
|
|
20
|
-
1) 先运行 `$ws-preflight`。
|
|
21
|
-
2) 确认当前处于 change 分支(推荐):`change/<change-id>`(也支持 `changes/`、`ws/`、`ws-change/`)。
|
|
22
|
-
- 若不在 change 分支:要求用户先切换到 `change/<change-id>`(或在命令里显式提供 `<change-id>`)。
|
|
23
|
-
3) 任何自动提交都必须在提交前输出:
|
|
24
|
-
- 该 repo 的 `git status --porcelain`
|
|
25
|
-
- 该 repo 的 `git diff --staged`
|
|
26
|
-
并让用户确认 commit message(每个 repo 单独确认)。
|
|
27
|
-
|
|
28
|
-
阶段定位:
|
|
29
|
-
- delivery 阶段;负责在多 repo / submodule 场景下完成顺序提交、证据收敛和最终合并前准备。
|
|
30
|
-
|
|
31
|
-
必需输入:
|
|
32
|
-
- 当前 `change/<change-id>` 上下文
|
|
33
|
-
- 若存在 submodule:`.gitmodules` + `changes/<change-id>/submodules.targets`
|
|
34
|
-
- 各 repo 当前状态与 staged diff
|
|
35
|
-
|
|
36
|
-
必需输出:
|
|
37
|
-
- `Submodules:` 每个 submodule 的提交摘要
|
|
38
|
-
- `Superproject:` 主仓库提交摘要
|
|
39
|
-
- `Evidence:` validate stamp 与持久证据路径
|
|
40
|
-
- `Next:` 进入 `$ws-finish` 或 `aiws change finish`
|
|
41
|
-
|
|
42
|
-
阻断条件:
|
|
43
|
-
- 不在正确的 change 上下文
|
|
44
|
-
- submodule branch / targets 真值不完整
|
|
45
|
-
- 任一 repo 未确认 commit message 或存在未处理冲突
|
|
46
|
-
|
|
47
|
-
完成判定:
|
|
48
|
-
- submodule 与 superproject 提交都已完成,证据已收敛,且可以安全进入 finish 阶段。
|
|
49
|
-
|
|
50
|
-
建议流程(按顺序):
|
|
51
|
-
|
|
52
|
-
## 0) submodule branch 真值检查(减少 detached 与人为差异)
|
|
53
|
-
如果存在 `.gitmodules` 但缺少 `submodule.<name>.branch`,先运行 `$ws-submodule-setup` 并提交 `.gitmodules`,否则后续 `aiws validate .` 会失败,且 `ws-pull/ws-finish` 无法确定性工作。
|
|
54
|
-
> 说明:若同一 superproject 分支内存在多渠道 submodule 目标分支的交付需求,可在 `changes/<change-id>/submodules.targets` 额外声明本次 change 的目标分支;交付时会优先使用该文件(不改变 `.gitmodules` 的团队默认真值)。
|
|
55
|
-
> 生成该文件时,可以按当前状态做默认预填,但必须显式说明来源并让用户确认:detached HEAD 默认建议取 `.gitmodules` 声明分支;已附着在某个本地分支时默认建议取当前分支;finish/push 最终只认 `submodules.targets`。
|
|
56
10
|
```bash
|
|
57
|
-
if [[ -f .gitmodules ]]; then
|
|
58
|
-
missing=0
|
|
59
|
-
while read -r key sub_path; do
|
|
60
|
-
name="${key#submodule.}"; name="${name%.path}"
|
|
61
|
-
b="$(git config --file .gitmodules --get "submodule.${name}.branch" 2>/dev/null || true)"
|
|
62
|
-
if [[ -z "${b:-}" ]]; then
|
|
63
|
-
echo "error: missing .gitmodules submodule.${name}.branch (path=${sub_path})"
|
|
64
|
-
missing=1
|
|
65
|
-
fi
|
|
66
|
-
done < <(git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null || true)
|
|
67
|
-
if [[ "$missing" -ne 0 ]]; then
|
|
68
|
-
echo "hint: run $ws-submodule-setup (and commit .gitmodules), then retry"
|
|
69
|
-
exit 2
|
|
70
|
-
fi
|
|
71
|
-
|
|
72
|
-
# 强约束:当 .gitmodules 声明 submodules 时,要求本次 change 存在 submodules.targets 且覆盖所有 submodule path
|
|
73
|
-
if git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' >/dev/null 2>&1; then
|
|
74
|
-
change_id="$(git branch --show-current | sed -n 's|^change/||p')"
|
|
75
|
-
targets="changes/${change_id}/submodules.targets"
|
|
76
|
-
if [[ ! -f "${targets}" ]]; then
|
|
77
|
-
echo "error: missing ${targets} (required when .gitmodules declares submodules)"
|
|
78
|
-
exit 2
|
|
79
|
-
fi
|
|
80
|
-
t_missing=0
|
|
81
|
-
while read -r _ sub_path; do
|
|
82
|
-
[[ -z "${sub_path:-}" ]] && continue
|
|
83
|
-
if ! awk -v p="${sub_path}" '$1==p && $0 !~ /^[[:space:]]*#/ && $2!="" { found=1 } END { exit(found?0:1) }' "${targets}" 2>/dev/null; then
|
|
84
|
-
echo "error: ${targets} missing entry for submodule path=${sub_path}"
|
|
85
|
-
t_missing=1
|
|
86
|
-
fi
|
|
87
|
-
done < <(git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null || true)
|
|
88
|
-
if [[ "${t_missing}" -ne 0 ]]; then
|
|
89
|
-
echo "hint: fill ${targets} as: <path> <target_branch> [remote]"
|
|
90
|
-
exit 2
|
|
91
|
-
fi
|
|
92
|
-
fi
|
|
93
|
-
fi
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
## A) 发现 submodules 清单(数量不固定)
|
|
97
|
-
在 superproject 根目录执行:
|
|
98
|
-
```bash
|
|
99
|
-
git submodule status --recursive
|
|
100
|
-
```
|
|
101
|
-
如果没有 submodule:跳到 C)。
|
|
102
|
-
|
|
103
|
-
## B) 逐个提交 submodules(先 submodule,后 superproject)
|
|
104
|
-
对每个 submodule path(可递归)重复以下步骤(建议按 `git submodule status --recursive` 顺序):
|
|
105
|
-
1) 定位并检查状态:
|
|
106
|
-
```bash
|
|
107
|
-
sub_path="<path>"
|
|
108
|
-
git -C "$sub_path" branch --show-current
|
|
109
|
-
git -C "$sub_path" status --porcelain
|
|
110
|
-
```
|
|
111
|
-
2) 先确定该 submodule 的目标分支来源,并显式说明给用户:
|
|
112
|
-
- `branch --show-current` 非空:默认建议用当前分支
|
|
113
|
-
- `branch --show-current` 为空(detached HEAD):默认建议用 `.gitmodules` 的 `submodule.<name>.branch`
|
|
114
|
-
- 若建议值与 `changes/<change-id>/submodules.targets` 已落盘值不一致:以 `submodules.targets` 为准,并先提示差异
|
|
115
|
-
3) 若 submodule 处于 detached HEAD(`branch --show-current` 为空):
|
|
116
|
-
- 说明:这通常是因为 superproject 的 gitlink checkout(例如 `git submodule update`)导致 detached。
|
|
117
|
-
- 不要直接切 `change/<change-id>` / `main` / `master` 来解 detached。
|
|
118
|
-
- 若你要在该 submodule 里提交:先按目标分支挂到 pin 分支 `aiws/pin/<target-branch>`,再在其上提交:
|
|
119
|
-
- 目标分支真值优先级:`changes/<change-id>/submodules.targets`(若存在)> `.gitmodules submodule.<name>.branch`
|
|
120
|
-
```bash
|
|
121
|
-
change_id="<change-id>"
|
|
122
|
-
targets="changes/${change_id}/submodules.targets"
|
|
123
|
-
sub_name="$(git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null | awk -v p="${sub_path}" '$2==p { name=$1; sub(/^submodule\\./,"",name); sub(/\\.path$/,"",name); print name; exit }')"
|
|
124
|
-
base_branch="$(python3 - <<'PY'
|
|
125
|
-
import json, pathlib
|
|
126
|
-
change_id = "<change-id>"
|
|
127
|
-
meta = pathlib.Path("changes") / change_id / ".ws-change.json"
|
|
128
|
-
data = json.loads(meta.read_text(encoding="utf-8"))
|
|
129
|
-
print((data.get("base_branch") or "").strip())
|
|
130
|
-
PY
|
|
131
|
-
)"
|
|
132
|
-
test -n "${sub_name}"
|
|
133
|
-
test -n "${base_branch}"
|
|
134
|
-
|
|
135
|
-
source tools/ws_resolve_sub_target.sh
|
|
136
|
-
ws_resolve_sub_target "${sub_path}" "${sub_name}" "${targets}" "${base_branch}" || exit 2
|
|
137
|
-
target_branch="${_resolved_branch}"
|
|
138
|
-
remote="${_resolved_remote}"
|
|
139
|
-
|
|
140
|
-
git -C "$sub_path" fetch "${remote}" --prune
|
|
141
|
-
if ! git -C "$sub_path" show-ref --verify --quiet "refs/remotes/${remote}/${target_branch}"; then
|
|
142
|
-
echo "error: missing ${remote}/${target_branch} for submodule path=${sub_path}"
|
|
143
|
-
exit 2
|
|
144
|
-
fi
|
|
145
|
-
git -C "$sub_path" checkout -B "aiws/pin/${target_branch}" HEAD
|
|
146
|
-
git -C "$sub_path" branch --set-upstream-to "${remote}/${target_branch}" "aiws/pin/${target_branch}" >/dev/null 2>&1 || true
|
|
147
|
-
```
|
|
148
|
-
- 若 `origin/<target-branch>` 不存在,或用户明确不想使用 pin 分支:停止,解释风险(提交可能不可追溯/难以推送)。
|
|
149
|
-
4) 选择性 staging(默认用 `-p` 更安全):
|
|
150
|
-
```bash
|
|
151
|
-
git -C "$sub_path" add -p
|
|
152
|
-
git -C "$sub_path" diff --staged --stat
|
|
153
|
-
git -C "$sub_path" diff --staged
|
|
154
|
-
```
|
|
155
|
-
5) AI 生成该 submodule 的 commit message(标题+可选 body),并让用户确认(每个 repo 单独确认)。
|
|
156
|
-
6) 执行提交(不带 `--no-verify`):
|
|
157
|
-
```bash
|
|
158
|
-
git -C "$sub_path" commit -m "<message>"
|
|
159
|
-
```
|
|
160
|
-
7) 若该 submodule 没有 staged changes:跳过(不要硬提交空 commit)。
|
|
161
|
-
|
|
162
|
-
## C) 提交 superproject(更新 gitlinks + 自身改动 + changes 工件)
|
|
163
|
-
1) 先检查 submodule 指针差异(gitlinks):
|
|
164
|
-
```bash
|
|
165
|
-
git diff --submodule
|
|
166
|
-
```
|
|
167
|
-
2) 选择性 staging:
|
|
168
|
-
- 先 stage 发生指针变化的 submodule 路径(明确列出):
|
|
169
|
-
```bash
|
|
170
|
-
git add <submodule-path-1> <submodule-path-2>
|
|
171
|
-
```
|
|
172
|
-
- 再 stage superproject 自身改动(默认 `-p`):
|
|
173
|
-
```bash
|
|
174
|
-
git add -p
|
|
175
|
-
git diff --staged --stat
|
|
176
|
-
git diff --staged
|
|
177
|
-
```
|
|
178
|
-
3) AI 生成 superproject 的 commit message(应包含 `bump submodule <name> -> <sha>` 等关键信息),并让用户确认。
|
|
179
|
-
4) 提交:
|
|
180
|
-
```bash
|
|
181
|
-
git commit -m "<message>"
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
## D) 门禁与证据(推荐)
|
|
185
|
-
```bash
|
|
186
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
187
|
-
./node_modules/.bin/aiws validate . --stamp
|
|
188
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
189
|
-
aiws validate . --stamp
|
|
190
|
-
else
|
|
191
|
-
npx @aipper/aiws validate . --stamp
|
|
192
|
-
fi
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
## D2) 生成持久证据并回填 Evidence_Path(强烈建议)
|
|
196
|
-
> 说明:`.agentdocs/tmp/...` 默认 gitignored;交付前建议把关键结果落到 `changes/<change-id>/evidence/...` 并回填 `proposal.md`/`plan` 的 `Evidence_Path`,避免后续评审/二次会话读不到证据。
|
|
197
|
-
```bash
|
|
198
|
-
change_id="<change-id>"
|
|
199
11
|
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
200
|
-
./node_modules/.bin/aiws
|
|
12
|
+
./node_modules/.bin/aiws ws-deliver
|
|
201
13
|
elif command -v aiws >/dev/null 2>&1; then
|
|
202
|
-
aiws
|
|
14
|
+
aiws ws-deliver
|
|
203
15
|
else
|
|
204
|
-
npx @aipper/aiws
|
|
16
|
+
npx @aipper/aiws ws-deliver
|
|
205
17
|
fi
|
|
206
18
|
```
|
|
207
|
-
|
|
208
|
-
## D3) 生成状态快照(可选,建议)
|
|
209
|
-
```bash
|
|
210
|
-
aiws change state "${change_id}" --write
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
## E) 安全合并回目标分支(fast-forward)
|
|
214
|
-
优先使用 `$ws-finish`(底层调用 `aiws change finish`,并在 push 成功后清理对应 change worktree)。
|
|
215
|
-
|
|
216
|
-
若需要显式指定目标分支:
|
|
217
|
-
```bash
|
|
218
|
-
aiws change finish <change-id> --into <base-branch>
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
## F) 归档说明
|
|
222
|
-
- 标准链路下不需要再单独执行 `aiws change archive <change-id>`。
|
|
223
|
-
- 进入 `$ws-finish` 并使用 `aiws change finish --push` 时,会自动完成 archive + handoff。
|
|
224
|
-
|
|
225
|
-
输出要求:
|
|
226
|
-
- `Submodules:` 每个 submodule 的分支/提交摘要(repo → commit sha → message)
|
|
227
|
-
- `Superproject:` 提交摘要
|
|
228
|
-
- `Merge:` `aiws change finish` 的输出(into/from)
|
|
229
|
-
- `Worktree cleanup:` 若存在独立 change worktree,输出清理结果(removed/skipped + reason)
|
|
230
|
-
- `Evidence:` `.agentdocs/tmp/aiws-validate/*.json`(若使用 --stamp)
|
|
@@ -7,162 +7,73 @@ description: 开发(按需求实现并验证;适用于任何需要修改代
|
|
|
7
7
|
|
|
8
8
|
目标:在 AIWS 约束下完成一个可回放、可验证的小步交付。
|
|
9
9
|
|
|
10
|
-
阶段定位:
|
|
11
|
-
|
|
10
|
+
阶段定位:implementation 阶段。
|
|
11
|
+
|
|
12
|
+
## 必需输入
|
|
12
13
|
|
|
13
|
-
必需输入:
|
|
14
14
|
- 真值文件:`AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`
|
|
15
15
|
- 当前任务的归因目标(`Req_ID` 或 `Problem_ID`)
|
|
16
16
|
- 若为 medium/complex:已通过 `$ws-plan` / `$ws-plan-verify` 的计划
|
|
17
17
|
- 当前 `change/<change-id>` 上下文或等价变更归因
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
## 必需输出
|
|
20
|
+
|
|
20
21
|
- `变更文件(Changed):` 实际改动清单
|
|
21
22
|
- `验证(Verify):` 实际运行的命令与结果说明
|
|
22
23
|
- `证据(Evidence):` `plan/...`、`changes/<change-id>/...`、`.agentdocs/tmp/...` 等证据路径
|
|
23
24
|
- `Next:` 若准备提交,建议 `$ws-review` 或 `$ws-commit`
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
## 阻断条件
|
|
27
|
+
|
|
26
28
|
- 无法把改动归因到 `REQUIREMENTS.md` 或问题单
|
|
27
29
|
- 没有可复现验证入口
|
|
28
30
|
- 需要创建 change 上下文但当前工作区状态不允许安全切换
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
- 已附着在某个本地分支:默认建议取该 submodule 的当前分支名
|
|
70
|
-
- 上述两条都只是建议值,不是运行时真值;真正的 finish/push 只认 `changes/<change-id>/submodules.targets`
|
|
71
|
-
```bash
|
|
72
|
-
change_id="<change-id>"
|
|
73
|
-
targets="changes/${change_id}/submodules.targets"
|
|
74
|
-
has_submodules=0
|
|
75
|
-
if [[ -f .gitmodules ]]; then
|
|
76
|
-
if git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' >/dev/null 2>&1; then
|
|
77
|
-
has_submodules=1
|
|
78
|
-
fi
|
|
79
|
-
fi
|
|
80
|
-
if [[ "${has_submodules}" -eq 1 && ! -f "${targets}" ]]; then
|
|
81
|
-
echo "error: missing ${targets} (required when .gitmodules declares submodules)"
|
|
82
|
-
echo "hint: create it first; defaults may be inferred, but the final truth must be written explicitly"
|
|
83
|
-
exit 2
|
|
84
|
-
fi
|
|
85
|
-
|
|
86
|
-
if [[ -f "${targets}" ]]; then
|
|
87
|
-
echo "info: applying submodule targets: ${targets}"
|
|
88
|
-
while read -r sub_path target_branch remote; do
|
|
89
|
-
[[ -z "${sub_path:-}" ]] && continue
|
|
90
|
-
[[ "${sub_path}" == \#* ]] && continue
|
|
91
|
-
[[ -z "${target_branch:-}" ]] && { echo "error: missing target_branch for path=${sub_path}"; exit 2; }
|
|
92
|
-
remote="${remote:-origin}"
|
|
93
|
-
|
|
94
|
-
echo "== submodule: ${sub_path} target=${remote}/${target_branch} =="
|
|
95
|
-
if [[ -n "$(git -C "${sub_path}" status --porcelain 2>/dev/null)" ]]; then
|
|
96
|
-
echo "error: submodule dirty: ${sub_path} (commit/stash first)"
|
|
97
|
-
exit 2
|
|
98
|
-
fi
|
|
99
|
-
git -C "${sub_path}" fetch "${remote}" --prune
|
|
100
|
-
# 选渠道:默认切到远端目标分支,并用 pin 分支承载本地提交(避免 detached)
|
|
101
|
-
git -C "${sub_path}" checkout -B "aiws/pin/${target_branch}" "${remote}/${target_branch}"
|
|
102
|
-
git -C "${sub_path}" branch --set-upstream-to "${remote}/${target_branch}" "aiws/pin/${target_branch}" >/dev/null 2>&1 || true
|
|
103
|
-
git -C "${sub_path}" status -sb
|
|
104
|
-
done < "${targets}"
|
|
105
|
-
|
|
106
|
-
# 检查 superproject 的 gitlink 是否发生变化(预期:若切了不同渠道,会看到差异)
|
|
107
|
-
git diff --submodule
|
|
108
|
-
fi
|
|
109
|
-
```
|
|
110
|
-
- 若你还没写 `submodules.targets`,可按下面方式先生成建议值,再人工确认后落盘:
|
|
111
|
-
```bash
|
|
112
|
-
change_id="<change-id>"
|
|
113
|
-
targets="changes/${change_id}/submodules.targets"
|
|
114
|
-
: > "${targets}"
|
|
115
|
-
|
|
116
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null | while read -r key sub_path; do
|
|
117
|
-
name="${key#submodule.}"; name="${name%.path}"
|
|
118
|
-
current_branch="$(git -C "${sub_path}" branch --show-current 2>/dev/null || true)"
|
|
119
|
-
declared_branch="$(git config --file .gitmodules --get "submodule.${name}.branch" 2>/dev/null || true)"
|
|
120
|
-
|
|
121
|
-
if [[ -n "${current_branch}" ]]; then
|
|
122
|
-
inferred_branch="${current_branch}"
|
|
123
|
-
inferred_from="current branch"
|
|
124
|
-
else
|
|
125
|
-
inferred_branch="${declared_branch}"
|
|
126
|
-
inferred_from=".gitmodules"
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
if [[ -z "${inferred_branch}" ]]; then
|
|
130
|
-
echo "error: cannot infer target branch for ${sub_path}; set it manually"
|
|
131
|
-
exit 2
|
|
132
|
-
fi
|
|
133
|
-
|
|
134
|
-
printf "%s %s\n" "${sub_path}" "${inferred_branch}" >> "${targets}"
|
|
135
|
-
echo "info: ${sub_path} -> ${inferred_branch} (inferred from ${inferred_from}; remote defaults to origin unless you edit ${targets})"
|
|
136
|
-
done
|
|
137
|
-
|
|
138
|
-
echo "review required: ${targets}"
|
|
139
|
-
cat "${targets}"
|
|
140
|
-
```
|
|
141
|
-
- 若你明确要在 superproject 直接切分支:`aiws change start <change-id> --hooks --switch`(仅在存在 `.gitmodules` 时有意义;会尝试让 submodules 工作区跟随 superproject 指针)
|
|
142
|
-
- 或手工:`git switch -c change/<change-id>`,并创建 `changes/<change-id>/proposal.md` 与 `changes/<change-id>/tasks.md`(参考 `changes/README.md`)
|
|
143
|
-
3) 若需要外部 / 子 agent 协作:
|
|
144
|
-
- 分析结论落盘到 `changes/<change-id>/analysis/`
|
|
145
|
-
- patch 草案落盘到 `changes/<change-id>/patches/`
|
|
146
|
-
- 不要把 `patches/` 当成“已应用代码”;主 agent 必须先审查再决定是否采用
|
|
147
|
-
- 若采用了委托结果,后续在 `ws-review` 或 `changes/<change-id>/review/` 中收敛最终结论
|
|
148
|
-
4) 如涉及需求调整:先做需求评审(可用 `$ws-req-review`)→ 用户确认后再做需求落盘(可用 `$ws-req-change`)(避免需求漂移)。
|
|
149
|
-
5) 实施最小改动:任何改动都要能归因到 `REQUIREMENTS.md`(验收)或 `issues/problem-issues.csv`(问题)。
|
|
150
|
-
6) 运行 `AI_WORKSPACE.md` 里声明的验证命令;未运行不声称已运行。
|
|
151
|
-
7) 多步任务(≥2 步):使用 `update_plan` 工具跟踪 `pending → in_progress → completed`,每完成一步立即更新(不要事后批量更新)。
|
|
152
|
-
8) 提交前强制门禁(commit/push hooks 也会阻断):
|
|
153
|
-
```bash
|
|
154
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
155
|
-
./node_modules/.bin/aiws validate .
|
|
156
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
32
|
+
## 完成判定
|
|
33
|
+
|
|
34
|
+
改动已落盘、验证已执行或明确未执行原因、证据路径可回放,并可进入 review/commit 阶段。
|
|
35
|
+
|
|
36
|
+
## 建议流程
|
|
37
|
+
|
|
38
|
+
### 1. Preflight
|
|
39
|
+
|
|
40
|
+
定位项目根目录,读取 `AI_PROJECT.md` / `REQUIREMENTS.md` / `AI_WORKSPACE.md`,输出约束摘要。
|
|
41
|
+
|
|
42
|
+
- 中大型任务:建议先用 `$ws-plan` 生成 `plan/` 工件。
|
|
43
|
+
- 已有计划:先 `$ws-plan-verify`,通过后进入实现。
|
|
44
|
+
- `$ws-plan` 已创建 worktree:直接在该 worktree 中继续。
|
|
45
|
+
|
|
46
|
+
### 2. 建立变更归因
|
|
47
|
+
|
|
48
|
+
- 若 `git status --porcelain` 仅有计划/工件文件,属于预期行为,继续即可。
|
|
49
|
+
- 若需创建新 change:`aiws change start <change-id> --hooks --no-switch`
|
|
50
|
+
- 若需切换分支:先确认无额外未提交改动,再 `git switch change/<change-id>`
|
|
51
|
+
- 若存在 submodule(`.gitmodules`):进入编码前必须准备好 `changes/<change-id>/submodules.targets`。`aiws change start` 的 `--submodules` 标志会自动处理。参考 `changes/README.md` 和 `changes/<change-id>/submodules.targets` 格式。
|
|
52
|
+
|
|
53
|
+
### 3. 实现策略:默认 dispatch aiws-worker(Subagent-First)
|
|
54
|
+
|
|
55
|
+
详细执行循环见 `packages/spec/docs/opencode-subagent-first.md`。
|
|
56
|
+
|
|
57
|
+
- 主 session **默认不直接写实现代码**;通过 `$ws-delegate` 派发 `aiws-worker`
|
|
58
|
+
- `task()` 调用中指定 `role: worker`,让 `aiws-inject-context` 插件自动注入 JSONL 上下文
|
|
59
|
+
- worker 返回后,派发 `aiws-reviewer` 做独立审查
|
|
60
|
+
- 根据 review 结果决定 fix 或收敛 evidence
|
|
61
|
+
- **Inline escape hatch**:如果用户明确说"你直接改"或"do it inline",主 session 可直接写代码,但必须落盘 evidence 记录理由
|
|
62
|
+
|
|
63
|
+
### 4. 其他规则
|
|
64
|
+
|
|
65
|
+
- 需求调整:先 `$ws-req-review` → 确认后 `$ws-req-change`
|
|
66
|
+
- 最小改动:每处改动必须归因到 `REQUIREMENTS.md` 或 `issues/problem-issues.csv`
|
|
67
|
+
- 验证:运行 `AI_WORKSPACE.md` 声明的命令;未运行不声称已运行
|
|
68
|
+
- 多步任务:使用 `update_plan` 工具跟踪状态
|
|
69
|
+
- 提交前门禁:
|
|
70
|
+
```bash
|
|
157
71
|
aiws validate .
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
10) 交付收尾(推荐,减少手动 merge 出错):运行 `$ws-finish`(底层调用 `aiws change finish`,默认 fast-forward 安全合并回目标分支)。
|
|
164
|
-
|
|
165
|
-
输出要求:
|
|
72
|
+
```
|
|
73
|
+
- 交付收尾:`$ws-finish`
|
|
74
|
+
|
|
75
|
+
## 输出要求
|
|
76
|
+
|
|
166
77
|
- `变更文件(Changed):` 文件清单
|
|
167
78
|
- `验证(Verify):` 实际运行的命令 + 期望结果
|
|
168
|
-
- `证据(Evidence):`
|
|
79
|
+
- `证据(Evidence):` 证据路径
|