@seanyao/roll 2026.523.2 → 2026.524.2

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.
Files changed (54) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/bin/roll +546 -97
  3. package/lib/__pycache__/loop-fmt.cpython-314.pyc +0 -0
  4. package/lib/__pycache__/loop_unstick.cpython-314.pyc +0 -0
  5. package/lib/__pycache__/model_prices.cpython-314.pyc +0 -0
  6. package/lib/__pycache__/roll-home.cpython-314.pyc +0 -0
  7. package/lib/__pycache__/roll-loop-status.cpython-314.pyc +0 -0
  8. package/lib/__pycache__/roll_render.cpython-314.pyc +0 -0
  9. package/lib/changelog_audit.py +155 -0
  10. package/lib/i18n/agent.sh +0 -0
  11. package/lib/i18n/alert.sh +0 -0
  12. package/lib/i18n/backlog.sh +0 -0
  13. package/lib/i18n/brief.sh +0 -0
  14. package/lib/i18n/changelog.sh +0 -0
  15. package/lib/i18n/ci.sh +0 -0
  16. package/lib/i18n/debug.sh +0 -0
  17. package/lib/i18n/doctor.sh +31 -0
  18. package/lib/i18n/dream.sh +0 -0
  19. package/lib/i18n/init.sh +17 -0
  20. package/lib/i18n/lang.sh +0 -0
  21. package/lib/i18n/loop.sh +0 -0
  22. package/lib/i18n/migrate.sh +0 -0
  23. package/lib/i18n/offboard.sh +15 -0
  24. package/lib/i18n/onboard.sh +0 -0
  25. package/lib/i18n/peer.sh +0 -0
  26. package/lib/i18n/propose.sh +0 -0
  27. package/lib/i18n/release.sh +0 -0
  28. package/lib/i18n/research.sh +0 -0
  29. package/lib/i18n/review_pr.sh +0 -0
  30. package/lib/i18n/sentinel.sh +0 -0
  31. package/lib/i18n/setup.sh +0 -0
  32. package/lib/i18n/shared.sh +83 -0
  33. package/lib/i18n/skills/roll-brief.sh +20 -0
  34. package/lib/i18n/skills/roll-build.sh +97 -0
  35. package/lib/i18n/skills/roll-design.sh +18 -0
  36. package/lib/i18n/skills/roll-fix.sh +14 -0
  37. package/lib/i18n/skills/roll-loop.sh +28 -0
  38. package/lib/i18n/skills/roll-onboard.sh +16 -0
  39. package/lib/i18n/slides.sh +0 -0
  40. package/lib/i18n/status.sh +0 -0
  41. package/lib/i18n/update.sh +9 -0
  42. package/lib/i18n.sh +25 -0
  43. package/lib/loop-fmt.py +77 -11
  44. package/lib/loop_unstick.py +180 -0
  45. package/lib/model_prices.py +93 -12
  46. package/lib/prices/snapshot-2026-05-22.json +2 -0
  47. package/lib/prices/snapshot-2026-05-23-deepseek.json +15 -0
  48. package/lib/prices/snapshot-2026-05-23-kimi.json +14 -0
  49. package/lib/roll-home.py +17 -1
  50. package/lib/roll-loop-status.py +9 -0
  51. package/lib/roll_render.py +10 -2
  52. package/package.json +1 -1
  53. package/skills/roll-.dream/SKILL.md +4 -4
  54. package/skills/roll-loop/SKILL.md +15 -1
@@ -0,0 +1,155 @@
1
+ #!/usr/bin/env python3
2
+ """FIX-113: changelog audit — list PRs merged to main since the latest
3
+ release tag that don't appear in CHANGELOG.md's ## Unreleased section.
4
+
5
+ Run before `release.sh` so missing entries surface BEFORE the AI rewrite
6
+ gets a chance to silently drop them.
7
+
8
+ Usage:
9
+ python3 lib/changelog_audit.py # report missing
10
+ python3 lib/changelog_audit.py --since v2026.520.1
11
+ python3 lib/changelog_audit.py --json # machine-readable
12
+
13
+ Exit 0 always (read-only audit). Output:
14
+ - "audit ok" + no missing list when CHANGELOG covers every merged PR
15
+ - "audit found N PR(s) without a CHANGELOG entry:" + list otherwise
16
+ """
17
+ from __future__ import annotations
18
+ import argparse, json, re, subprocess, sys
19
+ from pathlib import Path
20
+
21
+ PR_RE = re.compile(r"\(#(\d+)\)")
22
+ SQUASH_RE = re.compile(r"^([a-z0-9]{7,40})\s+(.*?)\s*\(#(\d+)\)\s*$")
23
+
24
+ # Heuristic: PR titles whose first token is one of these tags are usually
25
+ # user-visible (need CHANGELOG entry). Tags like "chore:", "docs:" still
26
+ # warrant a docs section entry; left to user judgement.
27
+ USER_VISIBLE_PATTERNS = (
28
+ re.compile(r"\b(US-[A-Z0-9-]+-\d+)\b"),
29
+ re.compile(r"\b(FIX-\d+)\b"),
30
+ re.compile(r"\b(REFACTOR-\d+)\b"),
31
+ )
32
+
33
+ def _latest_tag() -> str:
34
+ """Return the most recent v* tag, or empty string if none."""
35
+ try:
36
+ out = subprocess.check_output(
37
+ ["git", "tag", "--list", "v*", "--sort=-creatordate"],
38
+ text=True, stderr=subprocess.DEVNULL,
39
+ ).strip()
40
+ for line in out.splitlines():
41
+ if line:
42
+ return line
43
+ except Exception:
44
+ pass
45
+ return ""
46
+
47
+ def _merged_prs_since(since: str):
48
+ """Return list of (sha, subject, pr_number) for first-parent merges
49
+ on main between <since> and HEAD."""
50
+ cmd = ["git", "log", "--first-parent", "--oneline"]
51
+ if since:
52
+ cmd.append(f"{since}..HEAD")
53
+ try:
54
+ out = subprocess.check_output(cmd, text=True, stderr=subprocess.DEVNULL)
55
+ except Exception:
56
+ return []
57
+ rows = []
58
+ for line in out.splitlines():
59
+ m = SQUASH_RE.match(line)
60
+ if not m:
61
+ # Older "Merge pull request #N from <branch>" format
62
+ m2 = re.match(r"^([a-f0-9]{7,40})\s+Merge pull request #(\d+) from .*$", line)
63
+ if m2:
64
+ rows.append((m2.group(1), line.split(None, 1)[1], int(m2.group(2))))
65
+ continue
66
+ # Also look for parenthesized #N anywhere in subject
67
+ m3 = re.match(r"^([a-f0-9]{7,40})\s+(.*)$", line)
68
+ if m3:
69
+ pr_match = PR_RE.search(m3.group(2))
70
+ if pr_match:
71
+ rows.append((m3.group(1), m3.group(2), int(pr_match.group(1))))
72
+ continue
73
+ rows.append((m.group(1), m.group(2), int(m.group(3))))
74
+ return rows
75
+
76
+ def _read_unreleased_section(changelog: Path) -> str:
77
+ """Return the text of the ## Unreleased section (or empty string)."""
78
+ if not changelog.exists():
79
+ return ""
80
+ text = changelog.read_text(errors="ignore")
81
+ m = re.search(r"^## Unreleased\s*\n(.*?)(?=^## |\Z)", text, re.MULTILINE | re.DOTALL)
82
+ return m.group(1) if m else ""
83
+
84
+ def _is_in_changelog(subject: str, unreleased_text: str) -> bool:
85
+ """A PR is considered covered if any story id from its subject appears in
86
+ the Unreleased section text."""
87
+ for pat in USER_VISIBLE_PATTERNS:
88
+ for m in pat.finditer(subject):
89
+ sid = m.group(1)
90
+ if sid in unreleased_text:
91
+ return True
92
+ # Fallback: PR number explicit mention
93
+ pr_m = PR_RE.search(subject)
94
+ if pr_m and f"#{pr_m.group(1)}" in unreleased_text:
95
+ return True
96
+ return False
97
+
98
+ def main():
99
+ ap = argparse.ArgumentParser()
100
+ ap.add_argument("--since", default="", help="Compare against this tag (default: latest v* tag)")
101
+ ap.add_argument("--changelog", default="CHANGELOG.md")
102
+ ap.add_argument("--json", action="store_true", help="Machine-readable output")
103
+ args = ap.parse_args()
104
+
105
+ since = args.since or _latest_tag()
106
+ prs = _merged_prs_since(since)
107
+ cl = _read_unreleased_section(Path(args.changelog))
108
+
109
+ missing = []
110
+ skipped_internal = []
111
+ for sha, subject, pr_n in prs:
112
+ # Skip merges that are themselves releases
113
+ if subject.startswith("[release]") or subject.startswith("[ release]"):
114
+ continue
115
+ if _is_in_changelog(subject, cl):
116
+ continue
117
+ # Heuristic: subjects that don't contain a story id and start with
118
+ # internal-only tags (chore: backlog ..., chore: rebase, etc.) are
119
+ # marked as "internal", less likely to need user-facing entry.
120
+ is_user_visible = any(p.search(subject) for p in USER_VISIBLE_PATTERNS)
121
+ if is_user_visible:
122
+ missing.append({"pr": pr_n, "sha": sha, "subject": subject})
123
+ else:
124
+ skipped_internal.append({"pr": pr_n, "sha": sha, "subject": subject})
125
+
126
+ if args.json:
127
+ json.dump({
128
+ "since": since,
129
+ "total_prs": len(prs),
130
+ "missing_user_visible": missing,
131
+ "skipped_internal": skipped_internal,
132
+ }, sys.stdout, indent=2, ensure_ascii=False)
133
+ print()
134
+ return 0
135
+
136
+ print(f"changelog audit since={since or '(no tag)'} scanned {len(prs)} PR(s)")
137
+ print()
138
+ if not missing:
139
+ print(f" ✓ audit ok — every user-visible PR is mentioned in CHANGELOG.md Unreleased")
140
+ if skipped_internal:
141
+ print(f" · {len(skipped_internal)} internal/infra PR(s) skipped from audit")
142
+ return 0
143
+
144
+ print(f" ⚠ {len(missing)} user-visible PR(s) without a CHANGELOG entry:")
145
+ for m in missing:
146
+ print(f" #{m['pr']} {m['subject']}")
147
+ print()
148
+ print(" Add bullets under '## Unreleased' in CHANGELOG.md before release,")
149
+ print(" or confirm these PRs are intentionally undocumented (rare).")
150
+ if skipped_internal:
151
+ print(f" ({len(skipped_internal)} internal PR(s) skipped from audit)")
152
+ return 0
153
+
154
+ if __name__ == "__main__":
155
+ sys.exit(main())
File without changes
File without changes
File without changes
File without changes
File without changes
package/lib/i18n/ci.sh ADDED
File without changes
File without changes
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — doctor command (US-I18N-002).
3
+
4
+ _i18n_set en doctor.stale_plists "Stale launchd plists"
5
+ _i18n_set zh doctor.stale_plists "无效的 launchd 服务"
6
+ _i18n_set en doctor.stale_plists_cleanup "Path is stale, clean up with"
7
+ _i18n_set zh doctor.stale_plists_cleanup "路径已失效,可清理"
8
+
9
+ _i18n_set en doctor.pr_review_extras "PR review extras"
10
+ _i18n_set zh doctor.pr_review_extras "PR 评审两档开关"
11
+
12
+ _i18n_set en doctor.pr_double_gate_enabled "✅ AI review double gate enabled"
13
+ _i18n_set zh doctor.pr_double_gate_enabled "✅ AI 评审双门已启用"
14
+ _i18n_set en doctor.pr_double_gate_disabled "⚪ AI review double gate not enabled"
15
+ _i18n_set zh doctor.pr_double_gate_disabled "⚪ 双门未启用"
16
+ _i18n_set en doctor.pr_double_gate_unknown "⚪ AI review double gate state unknown — requires gh auth"
17
+ _i18n_set zh doctor.pr_double_gate_unknown "⚪ 状态未知(需要 gh auth)"
18
+
19
+ _i18n_set en doctor.pr_event_enabled "✅ Event-driven PR review installed"
20
+ _i18n_set zh doctor.pr_event_enabled "✅ 事件驱动 PR 评审已安装"
21
+ _i18n_set en doctor.pr_event_disabled "⚪ Event-driven PR review not installed"
22
+ _i18n_set zh doctor.pr_event_disabled "⚪ 事件驱动 PR 评审未安装"
23
+
24
+ _i18n_set en doctor.pr_event_optional "Optional — enable event-driven PR review (seconds-fast, GitHub only)."
25
+ _i18n_set zh doctor.pr_event_optional "可选 —— 启用事件驱动 PR 评审(秒级响应,仅限 GitHub)。"
26
+ _i18n_set en doctor.pr_event_without "Without this, Roll reviews PRs each loop cycle (~1h). With it,"
27
+ _i18n_set zh doctor.pr_event_without "不安装也行 — loop 每轮会兜底评审。安装后"
28
+ _i18n_set en doctor.pr_event_without_zh "contributors get AI feedback on PR open/update immediately."
29
+ _i18n_set zh doctor.pr_event_without_zh "PR 一开即触发 AI 评审。"
30
+ _i18n_set en doctor.pr_event_secret "Then set the API key secret for your configured agent in GitHub repo settings."
31
+ _i18n_set zh doctor.pr_event_secret "然后在 GitHub 仓库设置中添加你配置的 agent 对应的 API key secret。"
File without changes
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — init command (US-I18N-002).
3
+
4
+ _i18n_set en init.onboard_cancelled "Onboard cancelled (Ctrl-C)."
5
+ _i18n_set zh init.onboard_cancelled "Onboard 已取消(Ctrl-C)。"
6
+ _i18n_set en init.onboard_agent_exited "Agent '%s' exited with code %s."
7
+ _i18n_set zh init.onboard_agent_exited "agent '%s' 异常退出 (code %s)。"
8
+ _i18n_set en init.onboard_next_step "Next step 下一步:"
9
+ _i18n_set zh init.onboard_next_step "下一步 Next step:"
10
+ _i18n_set en init.onboard_retry "retry the same agent: roll init"
11
+ _i18n_set zh init.onboard_retry "再试一次同一个 agent: roll init"
12
+ _i18n_set en init.onboard_retry_en "retry the same agent: roll init"
13
+ _i18n_set zh init.onboard_retry_en "retry the same agent: roll init"
14
+ _i18n_set en init.onboard_switch "switch to another: ROLL_ONBOARD_AGENT=<name> roll init"
15
+ _i18n_set zh init.onboard_switch "换一个 agent: ROLL_ONBOARD_AGENT=<name> roll init"
16
+ _i18n_set en init.onboard_switch_en "switch to another: ROLL_ONBOARD_AGENT=<name> roll init"
17
+ _i18n_set zh init.onboard_switch_en "switch to another: ROLL_ONBOARD_AGENT=<name> roll init"
File without changes
File without changes
File without changes
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — offboard command (US-I18N-002).
3
+
4
+ _i18n_set en offboard.no_changeset_en "No onboard changeset found at .roll/onboard-changeset.yaml"
5
+ _i18n_set zh offboard.no_changeset_en "No onboard changeset found at .roll/onboard-changeset.yaml"
6
+ _i18n_set en offboard.no_changeset_zh "未找到 onboard 变更清单 .roll/onboard-changeset.yaml"
7
+ _i18n_set zh offboard.no_changeset_zh "未找到 onboard 变更清单 .roll/onboard-changeset.yaml"
8
+ _i18n_set en offboard.manual_offboard "Manual offboard — remove these by hand if they came from Roll:"
9
+ _i18n_set zh offboard.manual_offboard "手动清理——如果这些文件来自 Roll,请手动删除:"
10
+ _i18n_set en offboard.manual_rm_roll "rm -rf .roll/ # all process artefacts"
11
+ _i18n_set zh offboard.manual_rm_roll "rm -rf .roll/ # 所有过程文件"
12
+ _i18n_set en offboard.manual_rm_agents "rm -f AGENTS.md CLAUDE.md # only if they were generated by roll init"
13
+ _i18n_set zh offboard.manual_rm_agents "rm -f AGENTS.md CLAUDE.md # 仅当这些文件由 roll init 生成"
14
+ _i18n_set en offboard.manual_edit_gitignore "Edit .gitignore to remove any '.roll/' entry"
15
+ _i18n_set zh offboard.manual_edit_gitignore "编辑 .gitignore 移除 '.roll/' 条目"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — shared / common messages (US-I18N-002).
3
+ # Sourced by lib/i18n.sh. Fill with _i18n_set.
4
+
5
+ # ── update notification ──
6
+ _i18n_set en update.available "v%s available — run 'roll update' to upgrade"
7
+ _i18n_set zh update.available "有新版本 v%s — 运行 'roll update' 升级"
8
+
9
+ # ── changelog heading ──
10
+ _i18n_set en changelog.heading "Recent Changes"
11
+ _i18n_set zh changelog.heading "最近更新"
12
+
13
+ # ── init: onboard agent ──
14
+ _i18n_set en init.onboard_retry "retry the same agent: roll init"
15
+ _i18n_set zh init.onboard_retry "再试一次同一个 agent: roll init"
16
+ _i18n_set en init.onboard_switch "switch to another: ROLL_ONBOARD_AGENT=<name> roll init"
17
+ _i18n_set zh init.onboard_switch "换一个 agent: ROLL_ONBOARD_AGENT=<name> roll init"
18
+
19
+ # ── migrate ──
20
+ _i18n_set en migrate.tips.inspect "Inspect the migration commit"
21
+ _i18n_set zh migrate.tips.inspect "查看迁移提交"
22
+ _i18n_set en migrate.tips.verify "Verify new structure"
23
+ _i18n_set zh migrate.tips.verify "验证新结构"
24
+
25
+ # ── peer help ──
26
+ _i18n_set en peer.help.from "Originating agent"
27
+ _i18n_set zh peer.help.from "发起方"
28
+ _i18n_set en peer.help.to "Target peer (auto-detected if omitted)"
29
+ _i18n_set zh peer.help.to "对端 peer(省略则自动选择)"
30
+ _i18n_set en peer.help.round "Current round (default: 1)"
31
+ _i18n_set zh peer.help.round "当前轮数"
32
+ _i18n_set en peer.help.tag "Task type for routing (architecture, security, test...)"
33
+ _i18n_set zh peer.help.tag "任务类型"
34
+ _i18n_set en peer.help.context "Context file to send to peer"
35
+ _i18n_set zh peer.help.context "上下文文件"
36
+ _i18n_set en peer.help.yes "Skip opt-out prompt"
37
+ _i18n_set zh peer.help.yes "跳过确认提示"
38
+ _i18n_set en peer.help.status_cmd "Show peer review state"
39
+ _i18n_set zh peer.help.status_cmd "显示状态"
40
+
41
+ # ── agent ──
42
+ _i18n_set en agent.use_hint "roll agent use <name> — switch agent for this project"
43
+ _i18n_set zh agent.use_hint "roll agent use <name> — 切换此项目的 agent"
44
+ _i18n_set en agent.list_hint "roll agent list — show installed agents"
45
+ _i18n_set zh agent.list_hint "roll agent list — 查看已安装的 agent"
46
+
47
+ # ── offboard ──
48
+ _i18n_set en offboard.manual_rm_agents "rm -f AGENTS.md CLAUDE.md # only if they were generated by roll init"
49
+ _i18n_set zh offboard.manual_rm_agents "rm -f AGENTS.md CLAUDE.md # 仅当这些文件由 roll init 生成"
50
+ _i18n_set en offboard.manual_rm_roll "rm -rf .roll/ # all process artefacts"
51
+ _i18n_set zh offboard.manual_rm_roll "rm -rf .roll/ # 所有过程文件"
52
+ _i18n_set en offboard.manual_edit_gitignore "Edit .gitignore to remove any '.roll/' entry"
53
+ _i18n_set zh offboard.manual_edit_gitignore "编辑 .gitignore 移除 '.roll/' 条目"
54
+
55
+ # ── doctor ──
56
+ _i18n_set en doctor.stale_plists "Stale launchd plists"
57
+ _i18n_set zh doctor.stale_plists "无效的 launchd 服务"
58
+ _i18n_set en doctor.stale_plists_path "Path no longer valid, clean up with:"
59
+ _i18n_set zh doctor.stale_plists_path "路径已失效,可清理:"
60
+
61
+ # ── check_structure (US-ONBOARD-004) ──
62
+ _i18n_set en check_structure.detected "Legacy structure detected at: %s"
63
+ _i18n_set zh check_structure.detected "发现老结构目录: %s"
64
+ _i18n_set en check_structure.pre_2_0_layout "This project uses the pre-2.0 layout (BACKLOG.md / docs/*). Roll 2.0 requires"
65
+ _i18n_set zh check_structure.pre_2_0_layout "此项目使用 2.0 之前的老结构 (BACKLOG.md / docs/*)。Roll 2.0 要求"
66
+ _i18n_set en check_structure.run_migration "process artifacts to live in .roll/. Run the migration to upgrade:"
67
+ _i18n_set zh check_structure.run_migration "过程文件放在 .roll/ 下。运行迁移命令升级:"
68
+ _i18n_set en check_structure.preview_changes "# Preview changes"
69
+ _i18n_set zh check_structure.preview_changes "# 预览变更"
70
+ _i18n_set en check_structure.execute "# Execute (single atomic commit)"
71
+ _i18n_set zh check_structure.execute "# 执行(单次原子提交)"
72
+ _i18n_set en check_structure.migration_guide "Migration guide"
73
+ _i18n_set zh check_structure.migration_guide "迁移指南"
74
+ _i18n_set en check_structure.roll_back "To roll back to Roll 1.x temporarily"
75
+ _i18n_set zh check_structure.roll_back "如需临时回退到 Roll 1.x"
76
+
77
+ # ── main dispatch ──
78
+ _i18n_set en main.unknown_command "Unknown command: %s"
79
+ _i18n_set zh main.unknown_command "未知命令: %s"
80
+
81
+ # ── dashboard status ──
82
+ _i18n_set en dashboard.pending "pending"
83
+ _i18n_set zh dashboard.pending "待办"
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — roll-brief skill user-facing strings (US-I18N-003).
3
+ _i18n_set en brief.title "Roll Brief — %s"
4
+ _i18n_set zh brief.title "Roll 简报 — %s"
5
+ _i18n_set en brief.summary "Summary"
6
+ _i18n_set zh brief.summary "摘要"
7
+ _i18n_set en brief.completed "Completed: %s"
8
+ _i18n_set zh brief.completed "已完成: %s"
9
+ _i18n_set en brief.in_progress "In Progress: %s"
10
+ _i18n_set zh brief.in_progress "进行中: %s"
11
+ _i18n_set en brief.backlog_queue "Backlog Queue: %s pending"
12
+ _i18n_set zh brief.backlog_queue "Backlog 队列: %s 个待办"
13
+ _i18n_set en brief.requires_attention "Requires Attention"
14
+ _i18n_set zh brief.requires_attention "需要关注"
15
+ _i18n_set en brief.release_readiness "Release Readiness"
16
+ _i18n_set zh brief.release_readiness "发版就绪"
17
+ _i18n_set en brief.ready "Ready to release"
18
+ _i18n_set zh brief.ready "可以发版"
19
+ _i18n_set en brief.not_ready "Not ready — %s blockers"
20
+ _i18n_set zh brief.not_ready "暂不可发版 — %s 个阻塞项"
@@ -0,0 +1,97 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — roll-build skill user-facing strings (US-I18N-003).
3
+ # These are the templates/output blocks shown to users by agents executing roll-build.
4
+
5
+ # ── Phase 1-2: Clarify & Assess ──
6
+ _i18n_set en build.clarified_goal "Clarified Goal"
7
+ _i18n_set zh build.clarified_goal "目标澄清"
8
+ _i18n_set en build.complexity_assessment "Complexity Assessment"
9
+ _i18n_set zh build.complexity_assessment "复杂度评估"
10
+ _i18n_set en build.uncertainty_areas "Uncertainty Areas"
11
+ _i18n_set zh build.uncertainty_areas "不确定性"
12
+ _i18n_set en build.approach_confirmation "Approach Confirmation"
13
+ _i18n_set zh build.approach_confirmation "方案确认"
14
+ _i18n_set en build.what_changes "What changes"
15
+ _i18n_set zh build.what_changes "变更内容"
16
+ _i18n_set en build.the_approach "The approach"
17
+ _i18n_set zh build.the_approach "方案"
18
+ _i18n_set en build.files_touched "Files touched"
19
+ _i18n_set zh build.files_touched "涉及文件"
20
+
21
+ # ── Phase 2.5: Parallel Dispatch ──
22
+ _i18n_set en build.parallel_dispatch "Parallel Dispatch: %s Actions running in parallel"
23
+ _i18n_set zh build.parallel_dispatch "并行分发: %s 个 Action 并行执行"
24
+ _i18n_set en build.agent_running "Agent %s [Action: %s] ⏳ Running..."
25
+ _i18n_set zh build.agent_running "Agent %s [Action: %s] ⏳ 运行中..."
26
+ _i18n_set en build.agent_done "Agent %s [Action: %s] ✅ Done (%s TCR commits)"
27
+ _i18n_set zh build.agent_done "Agent %s [Action: %s] ✅ 完成 (%s 个 TCR 提交)"
28
+ _i18n_set en build.merge_summary "Merge: %s/%s succeeded, merging..."
29
+ _i18n_set zh build.merge_summary "合并: %s/%s 成功,正在合并..."
30
+ _i18n_set en build.integration_tests "Integration tests: running..."
31
+ _i18n_set zh build.integration_tests "集成测试: 运行中..."
32
+
33
+ # ── Phase 4: Test Design Review ──
34
+ _i18n_set en build.test_design "Test Design"
35
+ _i18n_set zh build.test_design "测试设计"
36
+ _i18n_set en build.scenarios "Scenarios"
37
+ _i18n_set zh build.scenarios "场景"
38
+ _i18n_set en build.test_types "Test Types"
39
+ _i18n_set zh build.test_types "测试类型"
40
+
41
+ # ── Phase 5: TCR ──
42
+ _i18n_set en build.tcr_cycle "TCR CYCLE (Test && Commit || Revert)"
43
+ _i18n_set zh build.tcr_cycle "TCR 循环 (Test && Commit || Revert)"
44
+ _i18n_set en build.micro_step "MICRO-STEP %s: %s"
45
+ _i18n_set zh build.micro_step "微步骤 %s: %s"
46
+
47
+ # ── Phase 6: Pre-Push CI Gate ──
48
+ _i18n_set en build.ci_check_failed "Local CI check failed"
49
+ _i18n_set zh build.ci_check_failed "本地 CI 检查失败"
50
+ _i18n_set en build.ci_check_passed "CI check passed"
51
+ _i18n_set zh build.ci_check_passed "CI 检查通过"
52
+
53
+ # ── Phase 10.5: Verification Gate ──
54
+ _i18n_set en build.verification_gate "Verification Gate"
55
+ _i18n_set zh build.verification_gate "验证门"
56
+ _i18n_set en build.evidence_checklist "Evidence checklist (each item must have actual output)"
57
+ _i18n_set zh build.evidence_checklist "证据清单(每项必须有实际输出)"
58
+ _i18n_set en build.tests_passed "Tests passed: paste actual test run output"
59
+ _i18n_set zh build.tests_passed "测试通过: 粘贴实际测试输出"
60
+ _i18n_set en build.build_succeeded "Build succeeded: paste build output"
61
+ _i18n_set zh build.build_succeeded "构建成功: 粘贴构建输出"
62
+ _i18n_set en build.online_verification "Online verification: screenshot / curl output / log snippet"
63
+ _i18n_set zh build.online_verification "在线验证: 截图 / curl 输出 / 日志片段"
64
+ _i18n_set en build.no_regression "No regression: verify at least one existing feature still works"
65
+ _i18n_set zh build.no_regression "无回归: 验证至少一个已有功能仍然正常"
66
+ _i18n_set en build.gate_decision "Gate Decision"
67
+ _i18n_set zh build.gate_decision "门控决议"
68
+ _i18n_set en build.gate_pass "All items have evidence → Can mark as DONE"
69
+ _i18n_set zh build.gate_pass "所有项有证据 → 可标记为完成"
70
+ _i18n_set en build.gate_fail "Any item missing evidence → Gather evidence before passing the gate"
71
+ _i18n_set zh build.gate_fail "任一项缺证据 → 收集证据后再过门"
72
+
73
+ # ── Phase 12: Report & Celebrate ──
74
+ _i18n_set en build.pushed_to "Pushed to GitHub: origin/main"
75
+ _i18n_set zh build.pushed_to "已推送至 GitHub: origin/main"
76
+ _i18n_set en build.deployed "Deployed"
77
+ _i18n_set zh build.deployed "已部署"
78
+ _i18n_set en build.verified "Verified"
79
+ _i18n_set zh build.verified "已验证"
80
+ _i18n_set en build.changes_summary "Changes"
81
+ _i18n_set zh build.changes_summary "变更"
82
+ _i18n_set en build.commits_count "Commits"
83
+ _i18n_set zh build.commits_count "提交"
84
+ _i18n_set en build.tests_added "Tests"
85
+ _i18n_set zh build.tests_added "测试"
86
+ _i18n_set en build.tcr_stats "TCR Stats"
87
+ _i18n_set zh build.tcr_stats "TCR 统计"
88
+ _i18n_set en build.review_gate "Review Gate"
89
+ _i18n_set zh build.review_gate "评审门"
90
+ _i18n_set en build.backlog_updated "BACKLOG: %s marked ✅ Done"
91
+ _i18n_set zh build.backlog_updated "BACKLOG: %s 已标记 ✅ Done"
92
+ _i18n_set en build.changelog_bundled "CHANGELOG: bundled into completion commit"
93
+ _i18n_set zh build.changelog_bundled "CHANGELOG: 已并入完成提交"
94
+ _i18n_set en build.shipped "Shipped"
95
+ _i18n_set zh build.shipped "已交付"
96
+ _i18n_set en build.next_options "Next Options"
97
+ _i18n_set zh build.next_options "下一步"
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — roll-design skill user-facing strings (US-I18N-003).
3
+ _i18n_set en design.epic "Epic: %s"
4
+ _i18n_set zh design.epic "Epic: %s"
5
+ _i18n_set en design.feature "Feature: %s"
6
+ _i18n_set zh design.feature "功能: %s"
7
+ _i18n_set en design.user_story "User Story: %s"
8
+ _i18n_set zh design.user_story "用户故事: %s"
9
+ _i18n_set en design.acceptance_criteria "Acceptance Criteria"
10
+ _i18n_set zh design.acceptance_criteria "验收标准"
11
+ _i18n_set en design.domain_model "Domain Model"
12
+ _i18n_set zh design.domain_model "领域模型"
13
+ _i18n_set en design.aggregates "Aggregates"
14
+ _i18n_set zh design.aggregates "聚合"
15
+ _i18n_set en design.context_map "Context Map"
16
+ _i18n_set zh design.context_map "上下文映射"
17
+ _i18n_set en design.stories_created "Created %s stories in backlog"
18
+ _i18n_set zh design.stories_created "已在 backlog 创建 %s 个故事"
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — roll-fix skill user-facing strings (US-I18N-003).
3
+ _i18n_set en fix.bug_identified "Bug identified: %s"
4
+ _i18n_set zh fix.bug_identified "Bug 已识别: %s"
5
+ _i18n_set en fix.root_cause "Root cause"
6
+ _i18n_set zh fix.root_cause "根因"
7
+ _i18n_set en fix.fix_applied "Fix applied via TCR"
8
+ _i18n_set zh fix.fix_applied "已通过 TCR 应用修复"
9
+ _i18n_set en fix.tests_updated "Tests updated: %s"
10
+ _i18n_set zh fix.tests_updated "测试已更新: %s"
11
+ _i18n_set en fix.regression_verified "Regression verified"
12
+ _i18n_set zh fix.regression_verified "回归验证通过"
13
+ _i18n_set en fix.fix_complete "Fix complete: %s"
14
+ _i18n_set zh fix.fix_complete "修复完成: %s"
@@ -0,0 +1,28 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — roll-loop skill user-facing strings (US-I18N-003).
3
+ _i18n_set en loop.cycle_start "Cycle %s started"
4
+ _i18n_set zh loop.cycle_start "Cycle %s 开始"
5
+ _i18n_set en loop.orphan_recovery "Orphan recovery: %s items reverted"
6
+ _i18n_set zh loop.orphan_recovery "孤儿恢复: %s 项已回退"
7
+ _i18n_set en loop.ci_precheck "Pre-run CI check"
8
+ _i18n_set zh loop.ci_precheck "启动前 CI 检查"
9
+ _i18n_set en loop.pr_inbox "PR inbox: %s open"
10
+ _i18n_set zh loop.pr_inbox "PR 收件箱: %s 个开放"
11
+ _i18n_set en loop.scanning_backlog "Scanning backlog..."
12
+ _i18n_set zh loop.scanning_backlog "扫描 backlog..."
13
+ _i18n_set en loop.picked_story "Picked: %s"
14
+ _i18n_set zh loop.picked_story "已选取: %s"
15
+ _i18n_set en loop.executing "Executing: %s"
16
+ _i18n_set zh loop.executing "执行中: %s"
17
+ _i18n_set en loop.story_done "Story complete: %s"
18
+ _i18n_set zh loop.story_done "故事完成: %s"
19
+ _i18n_set en loop.ci_waiting "Waiting for CI..."
20
+ _i18n_set zh loop.ci_waiting "等待 CI..."
21
+ _i18n_set en loop.ci_green "CI: green"
22
+ _i18n_set zh loop.ci_green "CI: 通过"
23
+ _i18n_set en loop.ci_red "CI: red"
24
+ _i18n_set zh loop.ci_red "CI: 失败"
25
+ _i18n_set en loop.cycle_complete "Cycle complete: %s built, %s skipped"
26
+ _i18n_set zh loop.cycle_complete "Cycle 完成: %s 个已构建, %s 个已跳过"
27
+ _i18n_set en loop.idle_exit "No Todo items — idle exit"
28
+ _i18n_set zh loop.idle_exit "无待办项 — 空闲退出"
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — roll-onboard skill user-facing strings (US-I18N-003).
3
+ _i18n_set en onboard.welcome "Welcome to Roll Onboard"
4
+ _i18n_set zh onboard.welcome "欢迎使用 Roll Onboard"
5
+ _i18n_set en onboard.scanning "Scanning project..."
6
+ _i18n_set zh onboard.scanning "正在扫描项目..."
7
+ _i18n_set en onboard.questions_group1 "Group 1/3: Understanding your project"
8
+ _i18n_set zh onboard.questions_group1 "第 1/3 组: 理解你的项目"
9
+ _i18n_set en onboard.questions_group2 "Group 2/3: Defining scope"
10
+ _i18n_set zh onboard.questions_group2 "第 2/3 组: 定义范围"
11
+ _i18n_set en onboard.questions_group3 "Group 3/3: Privacy & preferences"
12
+ _i18n_set zh onboard.questions_group3 "第 3/3 组: 隐私与偏好"
13
+ _i18n_set en onboard.plan_written "Onboard plan written to .roll/onboard-plan.yaml"
14
+ _i18n_set zh onboard.plan_written "Onboard 计划已写入 .roll/onboard-plan.yaml"
15
+ _i18n_set en onboard.next_step "Next: run 'roll init --apply' to execute this plan"
16
+ _i18n_set zh onboard.next_step "下一步: 运行 'roll init --apply' 执行此计划"
File without changes
File without changes
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env bash
2
+ # Roll i18n catalog — update command (US-I18N-002).
3
+
4
+ _i18n_set en update.version_mismatch "Version mismatch: installed %s, expected %s — CDN propagation lag, clearing cache and retrying..."
5
+ _i18n_set zh update.version_mismatch "版本不一致(已安装 %s,期望 %s),疑似 CDN 未同步,清理缓存后重试..."
6
+ _i18n_set en update.still_mismatch "Still on %s after retry — registry may not have propagated yet, try again in a minute."
7
+ _i18n_set zh update.still_mismatch "重试后仍为 %s,注册表可能尚未同步,请稍后再试。"
8
+ _i18n_set en update.current_version "Current version: roll v%s"
9
+ _i18n_set zh update.current_version "当前版本: roll v%s"
package/lib/i18n.sh CHANGED
@@ -111,3 +111,28 @@ msg() {
111
111
  printf "$tmpl" "$@"
112
112
  echo
113
113
  }
114
+
115
+ # ── Load per-command message catalogs (US-I18N-002) ──
116
+ # Source all lib/i18n/*.sh files (skip self). Called once at bin/roll startup.
117
+ _i18n_load_catalogs() {
118
+ local i18n_dir
119
+ i18n_dir="$(dirname "${BASH_SOURCE[0]:-$0}")/i18n"
120
+ if [[ -d "$i18n_dir" ]]; then
121
+ local f
122
+ # Load per-command catalogs
123
+ for f in "$i18n_dir"/*.sh; do
124
+ [[ -f "$f" ]] || continue
125
+ # shellcheck source=/dev/null
126
+ source "$f"
127
+ done
128
+ # Load skill catalogs (US-I18N-003)
129
+ if [[ -d "$i18n_dir/skills" ]]; then
130
+ for f in "$i18n_dir/skills"/*.sh; do
131
+ [[ -f "$f" ]] || continue
132
+ # shellcheck source=/dev/null
133
+ source "$f"
134
+ done
135
+ fi
136
+ fi
137
+ }
138
+ _i18n_load_catalogs