@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,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ws-migrate
|
|
3
|
-
description: 迁移(补齐/升级 AIWS 工作区文件)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
用中文输出;命令与路径保持原样不翻译。
|
|
7
|
-
|
|
8
|
-
目标:把当前仓库补齐为 aiws workspace 模板,并启用可验证门禁。
|
|
9
|
-
|
|
10
|
-
执行(在项目根目录):
|
|
11
|
-
```bash
|
|
12
|
-
if [[ -f ".aiws/manifest.json" ]]; then
|
|
13
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
14
|
-
./node_modules/.bin/aiws update .
|
|
15
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
16
|
-
aiws update .
|
|
17
|
-
else
|
|
18
|
-
npx @aipper/aiws update .
|
|
19
|
-
fi
|
|
20
|
-
else
|
|
21
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
22
|
-
./node_modules/.bin/aiws init .
|
|
23
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
24
|
-
aiws init .
|
|
25
|
-
else
|
|
26
|
-
npx @aipper/aiws init .
|
|
27
|
-
fi
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
31
|
-
./node_modules/.bin/aiws validate .
|
|
32
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
33
|
-
aiws validate .
|
|
34
|
-
else
|
|
35
|
-
npx @aipper/aiws validate .
|
|
36
|
-
fi
|
|
37
|
-
|
|
38
|
-
git config core.hooksPath .githooks
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
回滚(恢复最近一次快照):
|
|
42
|
-
```bash
|
|
43
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
44
|
-
./node_modules/.bin/aiws rollback . latest
|
|
45
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
46
|
-
aiws rollback . latest
|
|
47
|
-
else
|
|
48
|
-
npx @aipper/aiws rollback . latest
|
|
49
|
-
fi
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
约束:
|
|
53
|
-
- 不写入任何 secrets。
|
|
54
|
-
- 不执行破坏性命令。
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ws-pull
|
|
3
|
-
description: 拉取并对齐 submodules(避免 detached;减少人为差异)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
7
|
-
|
|
8
|
-
背景:
|
|
9
|
-
- Git submodule 在别的电脑 `git submodule update` 后常见现象是子模块处于 detached HEAD(因为主仓库记录的是固定 gitlink commit)。
|
|
10
|
-
- detached 本身不一定是错,但会增加“需要手动切分支/容易忘”的操作差异。
|
|
11
|
-
|
|
12
|
-
目标:
|
|
13
|
-
- 安全拉取 superproject(默认只允许 fast-forward)
|
|
14
|
-
- 初始化/同步 submodules(`--init --recursive`)
|
|
15
|
-
- 在**不改动 superproject gitlink commit** 的前提下,尽量把每个 submodule 从 detached HEAD “挂回”到一个**确定的目标分支**(仅当该分支包含 gitlink commit 时)
|
|
16
|
-
- 若未配置 `.gitmodules` 的 `submodule.<name>.branch`:保持 detached,并提示先运行 `$ws-submodule-setup`
|
|
17
|
-
|
|
18
|
-
安全约束(强制):
|
|
19
|
-
- 不执行破坏性命令(不 `reset --hard` 主仓库;不改动远端)
|
|
20
|
-
- 不自动提交/不自动 push
|
|
21
|
-
- 若工作区不干净:停止并要求用户先 commit 或 stash(不要自动处理)
|
|
22
|
-
|
|
23
|
-
执行步骤(建议):
|
|
24
|
-
0) 输出上下文:
|
|
25
|
-
```bash
|
|
26
|
-
git rev-parse --show-toplevel
|
|
27
|
-
git branch --show-current
|
|
28
|
-
git status --porcelain
|
|
29
|
-
```
|
|
30
|
-
若 `git status --porcelain` 非空:停止,要求用户先清理工作区(commit 或 stash)。
|
|
31
|
-
|
|
32
|
-
1) 拉取 superproject(默认只允许 fast-forward,避免隐式 merge/rebase):
|
|
33
|
-
```bash
|
|
34
|
-
git pull --ff-only
|
|
35
|
-
```
|
|
36
|
-
若失败(需要 merge/rebase):停止并向用户解释原因,让用户明确选择 `git pull --rebase` 或手动处理。
|
|
37
|
-
|
|
38
|
-
2) 同步并更新 submodules 到 superproject 记录的 gitlink commit:
|
|
39
|
-
```bash
|
|
40
|
-
if [[ -f .gitmodules ]]; then
|
|
41
|
-
git submodule sync --recursive
|
|
42
|
-
git submodule update --init --recursive
|
|
43
|
-
else
|
|
44
|
-
echo "[info] no .gitmodules"
|
|
45
|
-
fi
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
3) (可选但推荐)把 submodule 从 detached HEAD 尽量“挂回分支”,减少手工操作差异:
|
|
49
|
-
|
|
50
|
-
说明:
|
|
51
|
-
- 该步骤不会改变 superproject 的 gitlink commit(也不会让主仓库出现“submodule modified”)。
|
|
52
|
-
- 只在目标分支包含该 gitlink commit 时才执行“挂回”;否则保持 detached 并提示原因。
|
|
53
|
-
- 为了避免 origin 分支较多时“猜错分支”,本步骤**只在** `.gitmodules` 明确配置了 `submodule.<name>.branch` 时才执行“挂回分支”;否则保持 detached 并提示先运行 `$ws-submodule-setup` 对齐配置。
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
if [[ -f .gitmodules ]]; then
|
|
57
|
-
base_branch="$(git branch --show-current)"
|
|
58
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null \
|
|
59
|
-
| while read -r key sub_path; do
|
|
60
|
-
[[ -z "${sub_path:-}" ]] && continue
|
|
61
|
-
name="${key#submodule.}"
|
|
62
|
-
name="${name%.path}"
|
|
63
|
-
echo "== submodule: ${sub_path} (${name}) =="
|
|
64
|
-
|
|
65
|
-
sub_sha="$(git rev-parse "HEAD:${sub_path}" 2>/dev/null || true)"
|
|
66
|
-
if [[ -z "${sub_sha:-}" ]]; then
|
|
67
|
-
echo "[warn] failed to read gitlink sha for ${sub_path}"
|
|
68
|
-
continue
|
|
69
|
-
fi
|
|
70
|
-
|
|
71
|
-
cfg_branch="$(git config --file .gitmodules --get "submodule.${name}.branch" 2>/dev/null || true)"
|
|
72
|
-
if [[ "${cfg_branch:-}" == "." ]]; then cfg_branch="$base_branch"; fi
|
|
73
|
-
if [[ -z "${cfg_branch:-}" ]]; then
|
|
74
|
-
echo "[warn] ${sub_path}: missing .gitmodules submodule.${name}.branch; keep detached (run ws-submodule-setup to set it)"
|
|
75
|
-
continue
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
target_branch="${cfg_branch}"
|
|
79
|
-
pin_branch="aiws/pin/${target_branch}"
|
|
80
|
-
|
|
81
|
-
git -C "${sub_path}" fetch origin --prune || true
|
|
82
|
-
|
|
83
|
-
if git -C "${sub_path}" show-ref --verify --quiet "refs/remotes/origin/${target_branch}"; then
|
|
84
|
-
if git -C "${sub_path}" merge-base --is-ancestor "${sub_sha}" "origin/${target_branch}"; then
|
|
85
|
-
# 不改动现有分支(避免把已有 main/master 等分支强行指回旧 commit)
|
|
86
|
-
# 仅创建/更新一个 AIWS 专用 pin 分支指向 gitlink commit,从 detached “挂回分支”。
|
|
87
|
-
git -C "${sub_path}" checkout -B "${pin_branch}" "${sub_sha}"
|
|
88
|
-
git -C "${sub_path}" branch --set-upstream-to "origin/${target_branch}" "${pin_branch}" >/dev/null 2>&1 || true
|
|
89
|
-
echo "[ok] attached ${sub_path} to ${pin_branch} (upstream=origin/${target_branch}) at ${sub_sha}"
|
|
90
|
-
else
|
|
91
|
-
echo "[warn] ${sub_path}: ${sub_sha} is not in origin/${target_branch}; keep detached"
|
|
92
|
-
fi
|
|
93
|
-
else
|
|
94
|
-
echo "[warn] ${sub_path}: origin/${target_branch} not found; keep detached"
|
|
95
|
-
fi
|
|
96
|
-
|
|
97
|
-
git -C "${sub_path}" rev-parse --abbrev-ref HEAD 2>/dev/null || true
|
|
98
|
-
git -C "${sub_path}" status -sb || true
|
|
99
|
-
done
|
|
100
|
-
fi
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
4) 一次性配置(方案 2):为每个 submodule 写入跟踪分支,便于团队统一(需要用户确认,会改动 `.gitmodules`):
|
|
104
|
-
```bash
|
|
105
|
-
# 示例:把某个 submodule 固定跟踪 main(会写入 .gitmodules 的 submodule.<name>.branch)
|
|
106
|
-
git submodule set-branch --branch main <sub_path>
|
|
107
|
-
|
|
108
|
-
# 提示:该变更需要提交到 superproject
|
|
109
|
-
git add .gitmodules
|
|
110
|
-
git commit -m "chore(submodule): set tracking branch"
|
|
111
|
-
```
|
|
112
|
-
建议:
|
|
113
|
-
- 只有当团队明确希望“子模块按分支滚动”(而不是锁定固定 commit)时,才采用方案 2。
|
|
114
|
-
- 若只是想避免 detached 但仍锁定 gitlink commit:优先使用步骤 3(不改 `.gitmodules`)。
|
|
115
|
-
- 推荐用 `$ws-submodule-setup` 交互式对齐所有 submodules 的 branch,并提交 `.gitmodules`。
|
|
116
|
-
|
|
117
|
-
输出要求:
|
|
118
|
-
- `Context:` 当前分支 + 是否存在 `.gitmodules` + submodule 列表
|
|
119
|
-
- `Result:` pull 是否 fast-forward;每个 submodule 是否成功“挂回分支”,失败原因是什么
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ws-push
|
|
3
|
-
description: 推送(submodule 感知:先 submodules 后 superproject;fast-forward 安全)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
7
|
-
|
|
8
|
-
目标:
|
|
9
|
-
- 在不自动提交的前提下,安全 push 当前仓库
|
|
10
|
-
- 若仓库包含 submodules:按 `submodules -> superproject` 顺序 push,减少“别人拉取后子模块 detached/分叉”的协作摩擦
|
|
11
|
-
- 若不包含 submodules:按普通 git 仓库的规则 push
|
|
12
|
-
|
|
13
|
-
安全约束(强制):
|
|
14
|
-
- 不自动提交、不自动 `git add -A`
|
|
15
|
-
- 不使用 `--force` / `--force-with-lease`
|
|
16
|
-
- 默认只允许 fast-forward push(发现分叉则停止并提示人工处理)
|
|
17
|
-
- 若工作区不干净:停止并要求先 commit 或 stash
|
|
18
|
-
|
|
19
|
-
执行步骤(建议):
|
|
20
|
-
0) 输出上下文:
|
|
21
|
-
```bash
|
|
22
|
-
git branch --show-current
|
|
23
|
-
git status --porcelain
|
|
24
|
-
git status -sb
|
|
25
|
-
```
|
|
26
|
-
若 `git status --porcelain` 非空:停止。
|
|
27
|
-
|
|
28
|
-
1) 判断是否存在 submodules:
|
|
29
|
-
```bash
|
|
30
|
-
if [[ -f .gitmodules ]]; then
|
|
31
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' || true
|
|
32
|
-
else
|
|
33
|
-
echo "[info] no .gitmodules"
|
|
34
|
-
fi
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
2) 若不存在 `.gitmodules` 或没有 submodule 条目:按普通仓库 push(仍需用户确认):
|
|
38
|
-
```bash
|
|
39
|
-
git remote -v
|
|
40
|
-
git push
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
3) 若存在 submodules:先检查 `.gitmodules` 的 branch 真值是否齐全(缺失则停止并提示 setup):
|
|
44
|
-
```bash
|
|
45
|
-
missing=0
|
|
46
|
-
while read -r key sub_path; do
|
|
47
|
-
name="${key#submodule.}"; name="${name%.path}"
|
|
48
|
-
b="$(git config --file .gitmodules --get "submodule.${name}.branch" 2>/dev/null || true)"
|
|
49
|
-
if [[ -z "${b:-}" ]]; then
|
|
50
|
-
echo "error: missing .gitmodules submodule.${name}.branch (path=${sub_path})"
|
|
51
|
-
missing=1
|
|
52
|
-
fi
|
|
53
|
-
done < <(git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null || true)
|
|
54
|
-
if [[ "$missing" -ne 0 ]]; then
|
|
55
|
-
echo "hint: run $ws-submodule-setup (and commit .gitmodules), then retry"
|
|
56
|
-
exit 2
|
|
57
|
-
fi
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
4) 逐个 push submodules(fast-forward only),再 push superproject:
|
|
61
|
-
```bash
|
|
62
|
-
base_branch="$(git branch --show-current)"
|
|
63
|
-
change_id="$(echo "${base_branch}" | sed -n 's|^change/||p')"
|
|
64
|
-
targets="changes/${change_id}/submodules.targets"
|
|
65
|
-
# Note: if not on a change/ branch, change_id is empty and targets file won't exist;
|
|
66
|
-
# resolution falls back to .gitmodules submodule.<name>.branch via ws_resolve_sub_target.
|
|
67
|
-
|
|
68
|
-
source tools/ws_resolve_sub_target.sh
|
|
69
|
-
|
|
70
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null \
|
|
71
|
-
| while read -r key sub_path; do
|
|
72
|
-
name="${key#submodule.}"; name="${name%.path}"
|
|
73
|
-
echo "== submodule: ${sub_path} (${name}) =="
|
|
74
|
-
|
|
75
|
-
# submodule 工作区必须干净
|
|
76
|
-
if [[ -n "$(git -C "${sub_path}" status --porcelain 2>/dev/null || true)" ]]; then
|
|
77
|
-
echo "error: submodule dirty: ${sub_path}"
|
|
78
|
-
exit 2
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
ws_resolve_sub_target "${sub_path}" "${name}" "${targets}" "${base_branch}" || exit 2
|
|
82
|
-
target_branch="${_resolved_branch}"
|
|
83
|
-
remote="${_resolved_remote}"
|
|
84
|
-
|
|
85
|
-
git -C "${sub_path}" fetch "${remote}" --prune
|
|
86
|
-
if ! git -C "${sub_path}" show-ref --verify --quiet "refs/remotes/${remote}/${target_branch}"; then
|
|
87
|
-
echo "error: missing ${remote}/${target_branch} for ${sub_path}"
|
|
88
|
-
exit 2
|
|
89
|
-
fi
|
|
90
|
-
|
|
91
|
-
# fast-forward only: <remote>/<branch> 必须是 HEAD 的祖先
|
|
92
|
-
if ! git -C "${sub_path}" merge-base --is-ancestor "${remote}/${target_branch}" HEAD; then
|
|
93
|
-
echo "error: non-fast-forward (submodule=${sub_path}, remote=${remote}, branch=${target_branch})"
|
|
94
|
-
echo "hint: rebase/merge in submodule, then retry"
|
|
95
|
-
exit 2
|
|
96
|
-
fi
|
|
97
|
-
|
|
98
|
-
# push HEAD -> <remote>/<branch>(不 force)
|
|
99
|
-
git -C "${sub_path}" push "${remote}" "HEAD:refs/heads/${target_branch}"
|
|
100
|
-
done
|
|
101
|
-
|
|
102
|
-
# 最后 push superproject(仍需用户确认远端/分支)
|
|
103
|
-
git remote -v
|
|
104
|
-
git push
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
输出要求:
|
|
108
|
-
- `Context:` 当前分支 + 是否有 submodules
|
|
109
|
-
- `Submodules:` 每个 submodule push 的目标分支与结果(成功/阻断原因)
|
|
110
|
-
- `Superproject:` push 结果
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ws-submodule-setup
|
|
3
|
-
description: 子模块分支对齐(写入 .gitmodules 的 submodule.<name>.branch;减少 detached 与人为差异)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
7
|
-
|
|
8
|
-
目标:
|
|
9
|
-
- 为每个 submodule 写入 `.gitmodules` 的 `submodule.<name>.branch`,让 `ws-pull` / `ws-finish` 能确定性地“挂回分支/fast-forward push”,避免 origin 多分支时靠猜导致偏差。
|
|
10
|
-
- 该变更是 **superproject 的团队真值**:需要提交 `.gitmodules`。
|
|
11
|
-
|
|
12
|
-
安全约束(强制):
|
|
13
|
-
- 不自动提交、不自动 push(必须先输出 diff 并让用户确认)
|
|
14
|
-
- 不在 submodule 中做破坏性操作(不 `reset --hard` / 不改动远端)
|
|
15
|
-
|
|
16
|
-
步骤(建议):
|
|
17
|
-
1) 确认工作区干净(否则停止):
|
|
18
|
-
```bash
|
|
19
|
-
git status --porcelain
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
2) 列出 submodules(没有则停止并说明无需配置):
|
|
23
|
-
```bash
|
|
24
|
-
test -f .gitmodules || { echo "no .gitmodules"; exit 0; }
|
|
25
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$'
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
3) 对每个 submodule,输出当前配置与建议分支(让用户确认每个 submodule 的 branch):
|
|
29
|
-
```bash
|
|
30
|
-
while read -r key sub_path; do
|
|
31
|
-
name="${key#submodule.}"; name="${name%.path}"
|
|
32
|
-
echo "== submodule: ${name} path=${sub_path} =="
|
|
33
|
-
echo "[current] branch=$(git config --file .gitmodules --get submodule.${name}.branch || true)"
|
|
34
|
-
echo "[origin] HEAD=$(git -C \"${sub_path}\" symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null || true)"
|
|
35
|
-
git -C "${sub_path}" branch -r --list "origin/*" | sed -n '1,30p' || true
|
|
36
|
-
echo "[choose] set one of:"
|
|
37
|
-
echo " - a concrete branch, e.g. main / master / release/x.y"
|
|
38
|
-
echo " - '.' to follow superproject current branch name (only if your team uses matching branch names)"
|
|
39
|
-
done < <(git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$')
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
4) 逐个写入分支配置(每次写完都回显,避免误配):
|
|
43
|
-
```bash
|
|
44
|
-
# Example:
|
|
45
|
-
# git submodule set-branch --branch main path/to/submodule
|
|
46
|
-
# git submodule set-branch --branch . path/to/submodule
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
5) 输出变更并让用户确认是否提交:
|
|
50
|
-
```bash
|
|
51
|
-
git diff -- .gitmodules
|
|
52
|
-
git status --porcelain
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
6) 若用户确认要提交:
|
|
56
|
-
```bash
|
|
57
|
-
git add .gitmodules
|
|
58
|
-
git commit -m "chore(submodule): set tracking branches"
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
输出要求:
|
|
62
|
-
- `Submodules:` name/path + 选择的 branch(每个都列出)
|
|
63
|
-
- `Diff:` `.gitmodules` 的 diff(或至少 `git diff -- .gitmodules` 的摘要)
|
|
64
|
-
- `Next:` 提示后续用 `$ws-pull` 拉取可自动减少 detached;`aiws validate` 会检查该配置是否齐全
|
|
65
|
-
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ws-migrate
|
|
3
|
-
description: 迁移(补齐/升级 AIWS 工作区文件)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
用中文输出;命令与路径保持原样不翻译。
|
|
7
|
-
|
|
8
|
-
目标:把当前仓库补齐为 aiws workspace 模板,并启用可验证门禁。
|
|
9
|
-
|
|
10
|
-
执行(在项目根目录):
|
|
11
|
-
```bash
|
|
12
|
-
if [[ -f ".aiws/manifest.json" ]]; then
|
|
13
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
14
|
-
./node_modules/.bin/aiws update .
|
|
15
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
16
|
-
aiws update .
|
|
17
|
-
else
|
|
18
|
-
npx @aipper/aiws update .
|
|
19
|
-
fi
|
|
20
|
-
else
|
|
21
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
22
|
-
./node_modules/.bin/aiws init .
|
|
23
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
24
|
-
aiws init .
|
|
25
|
-
else
|
|
26
|
-
npx @aipper/aiws init .
|
|
27
|
-
fi
|
|
28
|
-
fi
|
|
29
|
-
|
|
30
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
31
|
-
./node_modules/.bin/aiws validate .
|
|
32
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
33
|
-
aiws validate .
|
|
34
|
-
else
|
|
35
|
-
npx @aipper/aiws validate .
|
|
36
|
-
fi
|
|
37
|
-
|
|
38
|
-
git config core.hooksPath .githooks
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
回滚(恢复最近一次快照):
|
|
42
|
-
```bash
|
|
43
|
-
if [[ -x "./node_modules/.bin/aiws" ]]; then
|
|
44
|
-
./node_modules/.bin/aiws rollback . latest
|
|
45
|
-
elif command -v aiws >/dev/null 2>&1; then
|
|
46
|
-
aiws rollback . latest
|
|
47
|
-
else
|
|
48
|
-
npx @aipper/aiws rollback . latest
|
|
49
|
-
fi
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
约束:
|
|
53
|
-
- 不写入任何 secrets。
|
|
54
|
-
- 不执行破坏性命令。
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ws-pull
|
|
3
|
-
description: 拉取并对齐 submodules(避免 detached;减少人为差异)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
7
|
-
|
|
8
|
-
背景:
|
|
9
|
-
- Git submodule 在别的电脑 `git submodule update` 后常见现象是子模块处于 detached HEAD(因为主仓库记录的是固定 gitlink commit)。
|
|
10
|
-
- detached 本身不一定是错,但会增加“需要手动切分支/容易忘”的操作差异。
|
|
11
|
-
|
|
12
|
-
目标:
|
|
13
|
-
- 安全拉取 superproject(默认只允许 fast-forward)
|
|
14
|
-
- 初始化/同步 submodules(`--init --recursive`)
|
|
15
|
-
- 在**不改动 superproject gitlink commit** 的前提下,尽量把每个 submodule 从 detached HEAD “挂回”到一个**确定的目标分支**(仅当该分支包含 gitlink commit 时)
|
|
16
|
-
- 若未配置 `.gitmodules` 的 `submodule.<name>.branch`:保持 detached,并提示先运行 `$ws-submodule-setup`
|
|
17
|
-
|
|
18
|
-
安全约束(强制):
|
|
19
|
-
- 不执行破坏性命令(不 `reset --hard` 主仓库;不改动远端)
|
|
20
|
-
- 不自动提交/不自动 push
|
|
21
|
-
- 若工作区不干净:停止并要求用户先 commit 或 stash(不要自动处理)
|
|
22
|
-
|
|
23
|
-
执行步骤(建议):
|
|
24
|
-
0) 输出上下文:
|
|
25
|
-
```bash
|
|
26
|
-
git rev-parse --show-toplevel
|
|
27
|
-
git branch --show-current
|
|
28
|
-
git status --porcelain
|
|
29
|
-
```
|
|
30
|
-
若 `git status --porcelain` 非空:停止,要求用户先清理工作区(commit 或 stash)。
|
|
31
|
-
|
|
32
|
-
1) 拉取 superproject(默认只允许 fast-forward,避免隐式 merge/rebase):
|
|
33
|
-
```bash
|
|
34
|
-
git pull --ff-only
|
|
35
|
-
```
|
|
36
|
-
若失败(需要 merge/rebase):停止并向用户解释原因,让用户明确选择 `git pull --rebase` 或手动处理。
|
|
37
|
-
|
|
38
|
-
2) 同步并更新 submodules 到 superproject 记录的 gitlink commit:
|
|
39
|
-
```bash
|
|
40
|
-
if [[ -f .gitmodules ]]; then
|
|
41
|
-
git submodule sync --recursive
|
|
42
|
-
git submodule update --init --recursive
|
|
43
|
-
else
|
|
44
|
-
echo "[info] no .gitmodules"
|
|
45
|
-
fi
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
3) (可选但推荐)把 submodule 从 detached HEAD 尽量“挂回分支”,减少手工操作差异:
|
|
49
|
-
|
|
50
|
-
说明:
|
|
51
|
-
- 该步骤不会改变 superproject 的 gitlink commit(也不会让主仓库出现“submodule modified”)。
|
|
52
|
-
- 只在目标分支包含该 gitlink commit 时才执行“挂回”;否则保持 detached 并提示原因。
|
|
53
|
-
- 为了避免 origin 分支较多时“猜错分支”,本步骤**只在** `.gitmodules` 明确配置了 `submodule.<name>.branch` 时才执行“挂回分支”;否则保持 detached 并提示先运行 `$ws-submodule-setup` 对齐配置。
|
|
54
|
-
|
|
55
|
-
```bash
|
|
56
|
-
if [[ -f .gitmodules ]]; then
|
|
57
|
-
base_branch="$(git branch --show-current)"
|
|
58
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null \
|
|
59
|
-
| while read -r key sub_path; do
|
|
60
|
-
[[ -z "${sub_path:-}" ]] && continue
|
|
61
|
-
name="${key#submodule.}"
|
|
62
|
-
name="${name%.path}"
|
|
63
|
-
echo "== submodule: ${sub_path} (${name}) =="
|
|
64
|
-
|
|
65
|
-
sub_sha="$(git rev-parse "HEAD:${sub_path}" 2>/dev/null || true)"
|
|
66
|
-
if [[ -z "${sub_sha:-}" ]]; then
|
|
67
|
-
echo "[warn] failed to read gitlink sha for ${sub_path}"
|
|
68
|
-
continue
|
|
69
|
-
fi
|
|
70
|
-
|
|
71
|
-
cfg_branch="$(git config --file .gitmodules --get "submodule.${name}.branch" 2>/dev/null || true)"
|
|
72
|
-
if [[ "${cfg_branch:-}" == "." ]]; then cfg_branch="$base_branch"; fi
|
|
73
|
-
if [[ -z "${cfg_branch:-}" ]]; then
|
|
74
|
-
echo "[warn] ${sub_path}: missing .gitmodules submodule.${name}.branch; keep detached (run ws-submodule-setup to set it)"
|
|
75
|
-
continue
|
|
76
|
-
fi
|
|
77
|
-
|
|
78
|
-
target_branch="${cfg_branch}"
|
|
79
|
-
pin_branch="aiws/pin/${target_branch}"
|
|
80
|
-
|
|
81
|
-
git -C "${sub_path}" fetch origin --prune || true
|
|
82
|
-
|
|
83
|
-
if git -C "${sub_path}" show-ref --verify --quiet "refs/remotes/origin/${target_branch}"; then
|
|
84
|
-
if git -C "${sub_path}" merge-base --is-ancestor "${sub_sha}" "origin/${target_branch}"; then
|
|
85
|
-
# 不改动现有分支(避免把已有 main/master 等分支强行指回旧 commit)
|
|
86
|
-
# 仅创建/更新一个 AIWS 专用 pin 分支指向 gitlink commit,从 detached “挂回分支”。
|
|
87
|
-
git -C "${sub_path}" checkout -B "${pin_branch}" "${sub_sha}"
|
|
88
|
-
git -C "${sub_path}" branch --set-upstream-to "origin/${target_branch}" "${pin_branch}" >/dev/null 2>&1 || true
|
|
89
|
-
echo "[ok] attached ${sub_path} to ${pin_branch} (upstream=origin/${target_branch}) at ${sub_sha}"
|
|
90
|
-
else
|
|
91
|
-
echo "[warn] ${sub_path}: ${sub_sha} is not in origin/${target_branch}; keep detached"
|
|
92
|
-
fi
|
|
93
|
-
else
|
|
94
|
-
echo "[warn] ${sub_path}: origin/${target_branch} not found; keep detached"
|
|
95
|
-
fi
|
|
96
|
-
|
|
97
|
-
git -C "${sub_path}" rev-parse --abbrev-ref HEAD 2>/dev/null || true
|
|
98
|
-
git -C "${sub_path}" status -sb || true
|
|
99
|
-
done
|
|
100
|
-
fi
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
4) 一次性配置(方案 2):为每个 submodule 写入跟踪分支,便于团队统一(需要用户确认,会改动 `.gitmodules`):
|
|
104
|
-
```bash
|
|
105
|
-
# 示例:把某个 submodule 固定跟踪 main(会写入 .gitmodules 的 submodule.<name>.branch)
|
|
106
|
-
git submodule set-branch --branch main <sub_path>
|
|
107
|
-
|
|
108
|
-
# 提示:该变更需要提交到 superproject
|
|
109
|
-
git add .gitmodules
|
|
110
|
-
git commit -m "chore(submodule): set tracking branch"
|
|
111
|
-
```
|
|
112
|
-
建议:
|
|
113
|
-
- 只有当团队明确希望“子模块按分支滚动”(而不是锁定固定 commit)时,才采用方案 2。
|
|
114
|
-
- 若只是想避免 detached 但仍锁定 gitlink commit:优先使用步骤 3(不改 `.gitmodules`)。
|
|
115
|
-
- 推荐用 `$ws-submodule-setup` 交互式对齐所有 submodules 的 branch,并提交 `.gitmodules`。
|
|
116
|
-
|
|
117
|
-
输出要求:
|
|
118
|
-
- `Context:` 当前分支 + 是否存在 `.gitmodules` + submodule 列表
|
|
119
|
-
- `Result:` pull 是否 fast-forward;每个 submodule 是否成功“挂回分支”,失败原因是什么
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: ws-push
|
|
3
|
-
description: 推送(submodule 感知:先 submodules 后 superproject;fast-forward 安全)
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
用中文输出(命令/路径/代码标识符保持原样不翻译)。
|
|
7
|
-
|
|
8
|
-
目标:
|
|
9
|
-
- 在不自动提交的前提下,安全 push 当前仓库
|
|
10
|
-
- 若仓库包含 submodules:按 `submodules -> superproject` 顺序 push,减少“别人拉取后子模块 detached/分叉”的协作摩擦
|
|
11
|
-
- 若不包含 submodules:按普通 git 仓库的规则 push
|
|
12
|
-
|
|
13
|
-
安全约束(强制):
|
|
14
|
-
- 不自动提交、不自动 `git add -A`
|
|
15
|
-
- 不使用 `--force` / `--force-with-lease`
|
|
16
|
-
- 默认只允许 fast-forward push(发现分叉则停止并提示人工处理)
|
|
17
|
-
- 若工作区不干净:停止并要求先 commit 或 stash
|
|
18
|
-
|
|
19
|
-
执行步骤(建议):
|
|
20
|
-
0) 输出上下文:
|
|
21
|
-
```bash
|
|
22
|
-
git branch --show-current
|
|
23
|
-
git status --porcelain
|
|
24
|
-
git status -sb
|
|
25
|
-
```
|
|
26
|
-
若 `git status --porcelain` 非空:停止。
|
|
27
|
-
|
|
28
|
-
1) 判断是否存在 submodules:
|
|
29
|
-
```bash
|
|
30
|
-
if [[ -f .gitmodules ]]; then
|
|
31
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' || true
|
|
32
|
-
else
|
|
33
|
-
echo "[info] no .gitmodules"
|
|
34
|
-
fi
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
2) 若不存在 `.gitmodules` 或没有 submodule 条目:按普通仓库 push(仍需用户确认):
|
|
38
|
-
```bash
|
|
39
|
-
git remote -v
|
|
40
|
-
git push
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
3) 若存在 submodules:先检查 `.gitmodules` 的 branch 真值是否齐全(缺失则停止并提示 setup):
|
|
44
|
-
```bash
|
|
45
|
-
missing=0
|
|
46
|
-
while read -r key sub_path; do
|
|
47
|
-
name="${key#submodule.}"; name="${name%.path}"
|
|
48
|
-
b="$(git config --file .gitmodules --get "submodule.${name}.branch" 2>/dev/null || true)"
|
|
49
|
-
if [[ -z "${b:-}" ]]; then
|
|
50
|
-
echo "error: missing .gitmodules submodule.${name}.branch (path=${sub_path})"
|
|
51
|
-
missing=1
|
|
52
|
-
fi
|
|
53
|
-
done < <(git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null || true)
|
|
54
|
-
if [[ "$missing" -ne 0 ]]; then
|
|
55
|
-
echo "hint: run $ws-submodule-setup (and commit .gitmodules), then retry"
|
|
56
|
-
exit 2
|
|
57
|
-
fi
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
4) 逐个 push submodules(fast-forward only),再 push superproject:
|
|
61
|
-
```bash
|
|
62
|
-
base_branch="$(git branch --show-current)"
|
|
63
|
-
change_id="$(echo "${base_branch}" | sed -n 's|^change/||p')"
|
|
64
|
-
targets="changes/${change_id}/submodules.targets"
|
|
65
|
-
# Note: if not on a change/ branch, change_id is empty and targets file won't exist;
|
|
66
|
-
# resolution falls back to .gitmodules submodule.<name>.branch via ws_resolve_sub_target.
|
|
67
|
-
|
|
68
|
-
source tools/ws_resolve_sub_target.sh
|
|
69
|
-
|
|
70
|
-
git config --file .gitmodules --get-regexp '^submodule\\..*\\.path$' 2>/dev/null \
|
|
71
|
-
| while read -r key sub_path; do
|
|
72
|
-
name="${key#submodule.}"; name="${name%.path}"
|
|
73
|
-
echo "== submodule: ${sub_path} (${name}) =="
|
|
74
|
-
|
|
75
|
-
# submodule 工作区必须干净
|
|
76
|
-
if [[ -n "$(git -C "${sub_path}" status --porcelain 2>/dev/null || true)" ]]; then
|
|
77
|
-
echo "error: submodule dirty: ${sub_path}"
|
|
78
|
-
exit 2
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
ws_resolve_sub_target "${sub_path}" "${name}" "${targets}" "${base_branch}" || exit 2
|
|
82
|
-
target_branch="${_resolved_branch}"
|
|
83
|
-
remote="${_resolved_remote}"
|
|
84
|
-
|
|
85
|
-
git -C "${sub_path}" fetch "${remote}" --prune
|
|
86
|
-
if ! git -C "${sub_path}" show-ref --verify --quiet "refs/remotes/${remote}/${target_branch}"; then
|
|
87
|
-
echo "error: missing ${remote}/${target_branch} for ${sub_path}"
|
|
88
|
-
exit 2
|
|
89
|
-
fi
|
|
90
|
-
|
|
91
|
-
# fast-forward only: <remote>/<branch> 必须是 HEAD 的祖先
|
|
92
|
-
if ! git -C "${sub_path}" merge-base --is-ancestor "${remote}/${target_branch}" HEAD; then
|
|
93
|
-
echo "error: non-fast-forward (submodule=${sub_path}, remote=${remote}, branch=${target_branch})"
|
|
94
|
-
echo "hint: rebase/merge in submodule, then retry"
|
|
95
|
-
exit 2
|
|
96
|
-
fi
|
|
97
|
-
|
|
98
|
-
# push HEAD -> <remote>/<branch>(不 force)
|
|
99
|
-
git -C "${sub_path}" push "${remote}" "HEAD:refs/heads/${target_branch}"
|
|
100
|
-
done
|
|
101
|
-
|
|
102
|
-
# 最后 push superproject(仍需用户确认远端/分支)
|
|
103
|
-
git remote -v
|
|
104
|
-
git push
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
输出要求:
|
|
108
|
-
- `Context:` 当前分支 + 是否有 submodules
|
|
109
|
-
- `Submodules:` 每个 submodule push 的目标分支与结果(成功/阻断原因)
|
|
110
|
-
- `Superproject:` push 结果
|