@seanyao/roll 2026.511.1 → 2026.511.3
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/CHANGELOG.md +11 -0
- package/README.md +105 -27
- package/bin/roll +53 -25
- package/package.json +1 -1
- package/skills/roll-brief/SKILL.md +32 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v2026.511.3
|
|
4
|
+
- **Fixed**: loop/dream/brief 多项目运行隔离 — 共享 run.sh 导致所有项目的 loop 在同一目录执行,改为每个项目独立 runner 脚本(run-{slug}.sh),彻底隔离多项目并发执行环境
|
|
5
|
+
- **Fixed**: roll release 自发版拦截 — 在 roll 自身项目执行 `roll release` 时自动拦截并提示改用 scripts/release.sh,防止误操作绕过 2FA
|
|
6
|
+
|
|
7
|
+
## v2026.511.2
|
|
8
|
+
- **Added**: roll loop monitor 三服务状态 — 监控台新增 loop/dream/brief 三个 launchd 服务的运行状态、调度时间和实时 log tail,一屏掌握全局执行情况
|
|
9
|
+
- **Fixed**: dashboard 多处展示问题 — 修复 pending_count 算术错误、brief 内联显示 release readiness、移除底部冗余命令列表
|
|
10
|
+
- **Fixed**: loop 异常退出后 state 未重置 — 防止 queue 卡住导致后续任务无法执行
|
|
11
|
+
- **Fixed**: CI 稳定性 — 修复 _notify_update 裸返回和时间断言,消除环境差异引起的随机失败
|
|
12
|
+
- **Improved**: roll-brief 输出格式 — 序号命名、省略空 section、元信息格式精简,减少无效噪音
|
|
13
|
+
|
|
3
14
|
## v2026.511.1
|
|
4
15
|
- **Changed**: roll loop 调度器切换到 launchd(macOS)— `roll setup` 自动安装 loop/dream/brief 三个 launchd 服务(默认关闭),`roll loop on/off/status` 统一走 launchctl 管理,幂等安装,Linux 保留 crontab 回退路径
|
|
5
16
|
- **Added**: roll-loop TCR 硬校验 — 故事完成后自动统计 `tcr:` 微提交数量,为 0 时将故事状态回退为 📋 Todo 并写 ALERT,防止 agent 跳过 TCR 节奏
|
package/README.md
CHANGED
|
@@ -9,6 +9,8 @@
|
|
|
9
9
|
|
|
10
10
|
> Roll out features with AI agents — _Move fast, no sprints._
|
|
11
11
|
|
|
12
|
+
**[中文版 README](README_CN.md)**
|
|
13
|
+
|
|
12
14
|
[](LICENSE)
|
|
13
15
|
[](https://www.npmjs.com/package/@seanyao/roll)
|
|
14
16
|
[](https://github.com/seanyao/roll/actions/workflows/ci.yml)
|
|
@@ -17,20 +19,21 @@
|
|
|
17
19
|
|
|
18
20
|
## What is Roll?
|
|
19
21
|
|
|
20
|
-
Roll solves a specific problem: when developers on the same team use different AI clients (Claude Code, Cursor, Gemini CLI, Codex), each agent operates under different engineering constraints. One developer's Claude runs tests another's Cursor never even considers.
|
|
22
|
+
Roll solves a specific problem: when developers on the same team use different AI clients (Claude Code, Cursor, Gemini CLI, Kimi, Codex, DeepSeek, Pi, OpenCode, Trae), each agent operates under different engineering constraints. One developer's Claude runs tests another's Cursor never even considers.
|
|
21
23
|
|
|
22
|
-
Roll fixes this through
|
|
24
|
+
Roll fixes this through three mechanisms:
|
|
23
25
|
|
|
24
|
-
1. **Convention CLI** — a single source of engineering conventions distributed to every AI client on the machine (`~/.claude/`, `~/.cursor/`, `~/.gemini/`, etc.)
|
|
25
|
-
2. **Skill System** — proven engineering practices (TDD, TCR, SRE, INVEST) encoded as instructions that any AI agent can follow
|
|
26
|
+
1. **Convention CLI** — a single source of engineering conventions distributed to every AI client on the machine (`~/.claude/`, `~/.cursor/`, `~/.gemini/`, `~/.kimi/`, `~/.codex/`, `~/.deepseek/`, etc.)
|
|
27
|
+
2. **Skill System** — 20 proven engineering practices (TDD, TCR, SRE, INVEST, DDD) encoded as instructions that any AI agent can follow
|
|
28
|
+
3. **Autonomous Evolution** — an optional layer that lets the agent work unattended: `roll-loop` executes BACKLOG items hourly, `roll-.dream` scans code health nightly, and `roll-brief` briefs the human each morning. The human retains sole authority over releases.
|
|
26
29
|
|
|
27
|
-
The result: any agent, any client, same constraints.
|
|
30
|
+
The result: any agent, any client, same constraints — and optionally, continuous autonomous delivery.
|
|
28
31
|
|
|
29
32
|
---
|
|
30
33
|
|
|
31
34
|
## Start Here
|
|
32
35
|
|
|
33
|
-
Before commands and skills, read the Engineering Methodology — it explains the three-loop architecture (Research → Build → Observe), why each skill exists, and how they connect into a complete delivery system.
|
|
36
|
+
Before commands and skills, read the Engineering Methodology — it explains the three-loop architecture (Research → Build → Observe), the autonomous evolution layer, why each skill exists, and how they connect into a complete delivery system.
|
|
34
37
|
|
|
35
38
|
**[English](docs/methodology-en.md)** · **[中文](docs/methodology.md)**
|
|
36
39
|
|
|
@@ -57,17 +60,25 @@ roll update
|
|
|
57
60
|
|
|
58
61
|
## Convention Management
|
|
59
62
|
|
|
60
|
-
Unified behavioral conventions for Claude Code / Gemini CLI / Cursor / Codex — all from one source.
|
|
63
|
+
Unified behavioral conventions for Claude Code / Gemini CLI / Cursor / Kimi / Codex / DeepSeek / Pi / OpenCode / Trae — all from one source.
|
|
61
64
|
|
|
62
65
|
### Commands
|
|
63
66
|
|
|
67
|
+
Commands fall into two categories: **bash commands** run pure shell logic; **agent commands** (marked with 🤖) launch a full AI agent session to execute a SKILL.md.
|
|
68
|
+
|
|
64
69
|
| Command | Description |
|
|
65
70
|
|---------|-------------|
|
|
66
|
-
| `roll setup` | First-time install on this machine, or re-sync
|
|
67
|
-
| `roll update` | One-step upgrade: `npm install -g @seanyao/roll@latest` + re-sync via
|
|
71
|
+
| `roll setup [-f]` | First-time install on this machine, or re-sync (use `--force` to overwrite local cache) |
|
|
72
|
+
| `roll update` | One-step upgrade: `npm install -g @seanyao/roll@latest` + re-sync via setup |
|
|
68
73
|
| `roll init` | New project: create `AGENTS.md` + `BACKLOG.md` + `docs/features/` |
|
|
69
|
-
|
|
70
74
|
| `roll status` | Show sync state, skill links, and detected AI tools |
|
|
75
|
+
| `roll backlog` | Show all pending tasks from BACKLOG.md |
|
|
76
|
+
| `roll agent [use <name>\|list]` | Per-project agent selection — affects all 🤖 commands |
|
|
77
|
+
| `roll loop <on\|off\|now\|status\|monitor\|resume\|reset>` | 🤖 Manage the autonomous BACKLOG executor (three-service: loop/dream/brief) |
|
|
78
|
+
| `roll brief` | 🤖 Show latest owner brief (regenerate if stale >24h) |
|
|
79
|
+
| `roll peer` | 🤖 Cross-agent code review and negotiation |
|
|
80
|
+
| `roll release` | 🤖 Sync changelog + version bump + tag + npm publish + GitHub Release |
|
|
81
|
+
| `roll` _(no args, in project dir)_ | Dashboard: loop status, pending count, latest brief summary |
|
|
71
82
|
|
|
72
83
|
### Typical Flow
|
|
73
84
|
|
|
@@ -83,7 +94,13 @@ roll init
|
|
|
83
94
|
# 3. Upgrade to a new release
|
|
84
95
|
roll update
|
|
85
96
|
|
|
97
|
+
# 4. Enable autonomous evolution (optional)
|
|
98
|
+
roll loop on # three services: loop (hourly) + dream (nightly) + brief (daily)
|
|
99
|
+
roll loop monitor # real-time top-like dashboard
|
|
100
|
+
roll brief # read the latest digest
|
|
86
101
|
|
|
102
|
+
# 5. Switch agent per project
|
|
103
|
+
roll agent use kimi # all 🤖 commands now use kimi for this project
|
|
87
104
|
```
|
|
88
105
|
|
|
89
106
|
### How Convention Layering Works
|
|
@@ -137,29 +154,90 @@ Research → Design → Build → Check → Fix → (loop)
|
|
|
137
154
|
| Fast backlog capture (bug / idea) | `$roll-idea "description"` |
|
|
138
155
|
| High-risk logic (payments, auth, state machines) | `$roll-spar "feature"` |
|
|
139
156
|
| Deep research (product / company / tech) | `$roll-research "subject"` |
|
|
157
|
+
| Cross-agent code review | `$roll-peer` |
|
|
140
158
|
| Patrol production for regressions | `$roll-sentinel patrol` |
|
|
141
159
|
| Debug a broken page | `$roll-debug <URL>` |
|
|
142
160
|
| Record a dev moment / diary entry | `$roll-notes "just fixed that nasty bug"` |
|
|
161
|
+
| Let the agent work overnight | `roll loop on` |
|
|
143
162
|
|
|
144
163
|
### Full Skill List
|
|
145
164
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
|
149
|
-
|
|
150
|
-
| `$roll-
|
|
151
|
-
| `$roll-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
|
156
|
-
|
|
157
|
-
| `$roll
|
|
158
|
-
| `$roll
|
|
159
|
-
| `$roll
|
|
160
|
-
| `$roll
|
|
161
|
-
| `$roll
|
|
162
|
-
|
|
165
|
+
**Loop A — Research & Design**
|
|
166
|
+
|
|
167
|
+
| Skill | Description |
|
|
168
|
+
|-------|-------------|
|
|
169
|
+
| `$roll-research` | HV Analysis (Horizontal-Vertical) deep research framework, outputs PDF report |
|
|
170
|
+
| `$roll-design` | Multi-turn discuss → [peer review] → DDD model → solution design → [peer review] → write Stories to BACKLOG |
|
|
171
|
+
|
|
172
|
+
**Loop B — Implementation & Iteration**
|
|
173
|
+
|
|
174
|
+
| Skill | Description |
|
|
175
|
+
|-------|-------------|
|
|
176
|
+
| `$roll-build` | Universal entry: Story ID, fix ID, or free-text fly mode. TCR-driven micro-commits |
|
|
177
|
+
| `$roll-spar` | Adversarial TDD — Attacker writes tests, Defender writes code |
|
|
178
|
+
| `$roll-fix` | Bug fix / hotfix from BACKLOG |
|
|
179
|
+
| `$roll-release` | One-command publish: auto version (YYYY.MMDD.N) → tag → npm publish → GitHub Release |
|
|
180
|
+
| `$roll-peer` | Cross-agent code review — Claude / Kimi / DeepSeek / Codex bilateral negotiation |
|
|
181
|
+
|
|
182
|
+
**Loop C — Observability & Maintenance**
|
|
183
|
+
|
|
184
|
+
| Skill | Description |
|
|
185
|
+
|-------|-------------|
|
|
186
|
+
| `$roll-sentinel` | Randomized production patrol with adaptive hot-spot weighting |
|
|
187
|
+
| `$roll-debug` | Deep page diagnostics + root cause analysis (Black Box probe) |
|
|
188
|
+
|
|
189
|
+
**Autonomous Evolution (optional, via `roll loop on`)**
|
|
190
|
+
|
|
191
|
+
| Skill | Description |
|
|
192
|
+
|-------|-------------|
|
|
193
|
+
| `$roll-loop` | Hourly BACKLOG executor — routes US/FIX/REFACTOR to the right skill, enforces TCR |
|
|
194
|
+
| `$roll-.dream` | Nightly code health scan — dead code, architectural drift → REFACTOR entries |
|
|
195
|
+
| `$roll-brief` | Owner-facing digest — what's done, what's pending, release readiness verdict |
|
|
196
|
+
|
|
197
|
+
**Passive Support**
|
|
198
|
+
|
|
199
|
+
| Skill | Description |
|
|
200
|
+
|-------|-------------|
|
|
201
|
+
| `$roll-.review` | Pre-commit multi-dimensional self code review |
|
|
202
|
+
| `$roll-.qa` | Test pyramid and coverage standards reference |
|
|
203
|
+
| `$roll-.changelog` | Auto-generate CHANGELOG from BACKLOG |
|
|
204
|
+
| `$roll-.echo` | Passive intent clarification |
|
|
205
|
+
| `$roll-.clarify` | Passive scope clarification for vague build requests |
|
|
206
|
+
| `$roll-idea` | Fast capture a bug or idea into BACKLOG.md |
|
|
207
|
+
| `$roll-notes` | Project diary — append dev moments to `notes/YYYY-MM-DD.md` |
|
|
208
|
+
| `$roll-doctor` | One-command dev toolchain health check |
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Autonomous Evolution
|
|
213
|
+
|
|
214
|
+
Off by default. Enable with `roll loop on` to let the agent work unattended on your project.
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
┌─────────────────────────────────────────────────────────┐
|
|
218
|
+
│ Base layer (always active) │
|
|
219
|
+
│ $roll-design → $roll-build → $roll-fix → $roll-spar │
|
|
220
|
+
│ Human drives every action │
|
|
221
|
+
├─────────────────────────────────────────────────────────┤
|
|
222
|
+
│ Autonomous layer (opt-in: roll loop on) │
|
|
223
|
+
│ roll-loop — hourly BACKLOG executor │
|
|
224
|
+
│ roll-.dream — nightly code health scan │
|
|
225
|
+
│ roll-brief — daily morning digest + release readiness │
|
|
226
|
+
│ Human reviews briefs; retains sole release authority │
|
|
227
|
+
└─────────────────────────────────────────────────────────┘
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
Three services are scheduled via macOS launchd (Linux: crontab) and managed as a unit:
|
|
231
|
+
|
|
232
|
+
- **roll-loop** runs hourly, picks up `📋 Todo` items from BACKLOG, routes them (`US-XXX → $roll-build`, `FIX-XXX → $roll-fix`, `REFACTOR-XXX → $roll-build`), and enforces TCR discipline — if a story completes with zero `tcr:` micro-commits, it reverts to Todo with an ALERT.
|
|
233
|
+
- **roll-.dream** runs nightly, scanning for dead code, architectural drift, and refactoring opportunities. Outputs `REFACTOR-XXX` entries to BACKLOG.
|
|
234
|
+
- **roll-brief** runs each morning (or on-demand via `roll brief`), producing an owner-facing digest with a release-readiness verdict.
|
|
235
|
+
|
|
236
|
+
The autonomous layer **never** invokes `roll-release`. Production deployment is always a human decision.
|
|
237
|
+
|
|
238
|
+
Use `roll loop monitor` for a real-time `top`-like view of all three services: launchd status, current execution state, pending queue, alerts, and live log tail.
|
|
239
|
+
|
|
240
|
+
Per-project agent configuration: `roll agent use <name>` writes `.roll.yaml` so each project can use a different AI client (claude / kimi / deepseek / pi / codex / opencode). Lookup order: `.roll.yaml` → `~/.roll/config.yaml` → `claude` (default).
|
|
163
241
|
|
|
164
242
|
---
|
|
165
243
|
|
package/bin/roll
CHANGED
|
@@ -4,7 +4,7 @@ set -euo pipefail
|
|
|
4
4
|
# Roll — AI Agent Convention Manager
|
|
5
5
|
# Single source of truth for how all AI coding agents behave.
|
|
6
6
|
|
|
7
|
-
VERSION="2026.511.
|
|
7
|
+
VERSION="2026.511.3"
|
|
8
8
|
ROLL_HOME="${ROLL_HOME:-${HOME}/.roll}"
|
|
9
9
|
ROLL_CONFIG="${ROLL_HOME}/config.yaml"
|
|
10
10
|
ROLL_GLOBAL="${ROLL_HOME}/conventions/global"
|
|
@@ -1827,7 +1827,7 @@ _install_launchd_plists() {
|
|
|
1827
1827
|
local services=("loop" "dream" "brief")
|
|
1828
1828
|
local skill_names=("roll-loop" "roll-.dream" "roll-brief")
|
|
1829
1829
|
local minutes=("0" "0" "0")
|
|
1830
|
-
local hours=("" "
|
|
1830
|
+
local hours=("" "3" "9")
|
|
1831
1831
|
|
|
1832
1832
|
local updated=0
|
|
1833
1833
|
for i in "${!services[@]}"; do
|
|
@@ -1837,7 +1837,8 @@ _install_launchd_plists() {
|
|
|
1837
1837
|
local hour="${hours[$i]}"
|
|
1838
1838
|
local label; label=$(_launchd_label "$svc" "$project_path")
|
|
1839
1839
|
local plist; plist=$(_launchd_plist_path "$svc" "$project_path")
|
|
1840
|
-
local
|
|
1840
|
+
local slug; slug=$(_project_slug "$project_path")
|
|
1841
|
+
local runner="${shared}/${svc}/run-${slug}.sh"
|
|
1841
1842
|
local log="${shared}/${svc}/cron.log"
|
|
1842
1843
|
local cmd; cmd=$(_agent_skill_cmd "${sd}/${skill}/SKILL.md" 2>/dev/null || echo "roll loop now")
|
|
1843
1844
|
|
|
@@ -1910,8 +1911,8 @@ _loop_on() {
|
|
|
1910
1911
|
|
|
1911
1912
|
ok "Loop enabled 已启用"
|
|
1912
1913
|
echo " • roll-loop every hour :00 每小时整点"
|
|
1913
|
-
echo " • roll-.dream nightly at
|
|
1914
|
-
echo " • roll-brief daily at
|
|
1914
|
+
echo " • roll-.dream nightly at 03:00 每晚 03:00"
|
|
1915
|
+
echo " • roll-brief daily at 09:00 每天 09:00"
|
|
1915
1916
|
echo " • Agent: ${agent} (change: roll agent use <name>)"
|
|
1916
1917
|
return 0
|
|
1917
1918
|
fi
|
|
@@ -1938,8 +1939,8 @@ _loop_on() {
|
|
|
1938
1939
|
|
|
1939
1940
|
ok "Loop enabled 已启用"
|
|
1940
1941
|
echo " • roll-loop every hour :00 每小时整点"
|
|
1941
|
-
echo " • roll-.dream nightly at
|
|
1942
|
-
echo " • roll-brief daily at
|
|
1942
|
+
echo " • roll-.dream nightly at 03:00 每晚 03:00"
|
|
1943
|
+
echo " • roll-brief daily at 09:00 每天 09:00"
|
|
1943
1944
|
echo " • Agent: ${agent} (change: roll agent use <name>)"
|
|
1944
1945
|
}
|
|
1945
1946
|
|
|
@@ -1958,6 +1959,10 @@ _loop_off() {
|
|
|
1958
1959
|
if ! $any_loaded; then
|
|
1959
1960
|
warn "Loop not enabled for this project 当前项目 loop 未启用"; return 0
|
|
1960
1961
|
fi
|
|
1962
|
+
local slug; slug=$(_project_slug "$project_path")
|
|
1963
|
+
for svc in loop dream brief; do
|
|
1964
|
+
rm -f "${_SHARED_ROOT}/${svc}/run-${slug}.sh"
|
|
1965
|
+
done
|
|
1961
1966
|
ok "Loop disabled 已停用"
|
|
1962
1967
|
return 0
|
|
1963
1968
|
fi
|
|
@@ -1977,7 +1982,11 @@ _loop_now() {
|
|
|
1977
1982
|
info "Triggering loop cycle... 正在触发一个周期..."
|
|
1978
1983
|
local log_file="${_SHARED_ROOT}/loop/launchd.log"
|
|
1979
1984
|
mkdir -p "$(dirname "$log_file")"
|
|
1980
|
-
_agent_run_skill "roll-loop" | tee -a "$log_file"
|
|
1985
|
+
_agent_run_skill "roll-loop" 2>&1 | tee -a "$log_file" || true
|
|
1986
|
+
# Reset stale running state if skill exited without cleanup (e.g. API error, SIGKILL)
|
|
1987
|
+
if [[ -f "$_LOOP_STATE" ]] && grep -q "^status: running" "$_LOOP_STATE" 2>/dev/null; then
|
|
1988
|
+
printf "status: idle\n" > "$_LOOP_STATE"
|
|
1989
|
+
fi
|
|
1981
1990
|
}
|
|
1982
1991
|
|
|
1983
1992
|
_loop_status() {
|
|
@@ -2085,7 +2094,7 @@ _loop_monitor() {
|
|
|
2085
2094
|
echo -e " ${BOLD}Services 服务状态${NC} Agent: ${CYAN}${agent}${NC}"
|
|
2086
2095
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
2087
2096
|
local svc_info svc schedule
|
|
2088
|
-
for svc_info in "loop:hourly" "dream:
|
|
2097
|
+
for svc_info in "loop:hourly" "dream:03:00" "brief:09:00"; do
|
|
2089
2098
|
svc="${svc_info%%:*}"
|
|
2090
2099
|
schedule="${svc_info#*:}"
|
|
2091
2100
|
if _launchd_is_loaded "$(_launchd_label "$svc" "$project_path")"; then
|
|
@@ -2135,9 +2144,9 @@ _loop_monitor() {
|
|
|
2135
2144
|
if [[ -f "$backlog" ]]; then
|
|
2136
2145
|
local queue_count=0
|
|
2137
2146
|
local fix_pending us_pending refactor_pending
|
|
2138
|
-
fix_pending=$(grep -E '^\| FIX-' "$backlog" | grep '📋 Todo' || true)
|
|
2139
|
-
us_pending=$(grep -E '^\| \[US-' "$backlog" | grep '📋 Todo' || true)
|
|
2140
|
-
refactor_pending=$(grep -E '^\| REFACTOR-' "$backlog" | grep '📋 Todo' || true)
|
|
2147
|
+
fix_pending=$(grep -E '^\| FIX-' "$backlog" | grep -F '| 📋 Todo |' || true)
|
|
2148
|
+
us_pending=$(grep -E '^\| \[US-' "$backlog" | grep -F '| 📋 Todo |' || true)
|
|
2149
|
+
refactor_pending=$(grep -E '^\| REFACTOR-' "$backlog" | grep -F '| 📋 Todo |' || true)
|
|
2141
2150
|
|
|
2142
2151
|
# FIX first (priority)
|
|
2143
2152
|
while IFS= read -r line; do
|
|
@@ -2217,6 +2226,12 @@ cmd_brief() {
|
|
|
2217
2226
|
}
|
|
2218
2227
|
|
|
2219
2228
|
cmd_release() {
|
|
2229
|
+
local pkg; pkg=$(node -p "require('./package.json').name" 2>/dev/null || true)
|
|
2230
|
+
if [[ "$pkg" == "@seanyao/roll" ]]; then
|
|
2231
|
+
err "roll 自身发版请用 scripts/release.sh(npm publish 需要人工 2FA)"
|
|
2232
|
+
echo " Run: scripts/release.sh"
|
|
2233
|
+
exit 1
|
|
2234
|
+
fi
|
|
2220
2235
|
_agent_run_skill "roll-release"
|
|
2221
2236
|
}
|
|
2222
2237
|
|
|
@@ -2233,9 +2248,9 @@ cmd_backlog() {
|
|
|
2233
2248
|
|
|
2234
2249
|
local us_items fix_items refactor_items total=0
|
|
2235
2250
|
|
|
2236
|
-
us_items=$(grep -E '^\| \[US-' "$backlog" | grep '📋 Todo' || true)
|
|
2237
|
-
fix_items=$(grep -E '^\| FIX-' "$backlog" | grep '📋 Todo' || true)
|
|
2238
|
-
refactor_items=$(grep -E '^\| REFACTOR-' "$backlog" | grep '📋 Todo' || true)
|
|
2251
|
+
us_items=$(grep -E '^\| \[US-' "$backlog" | grep -F '| 📋 Todo |' || true)
|
|
2252
|
+
fix_items=$(grep -E '^\| FIX-' "$backlog" | grep -F '| 📋 Todo |' || true)
|
|
2253
|
+
refactor_items=$(grep -E '^\| REFACTOR-' "$backlog" | grep -F '| 📋 Todo |' || true)
|
|
2239
2254
|
|
|
2240
2255
|
local us_count fix_count refactor_count
|
|
2241
2256
|
us_count=$(echo "$us_items" | grep -c . || true)
|
|
@@ -2298,8 +2313,24 @@ _dashboard() {
|
|
|
2298
2313
|
|
|
2299
2314
|
echo -e "\n ${BOLD}${CYAN}${project_name}${NC} ${YELLOW}v${VERSION}${NC}\n"
|
|
2300
2315
|
|
|
2301
|
-
|
|
2316
|
+
local _dash_loop_enabled=false
|
|
2317
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
2318
|
+
_launchd_is_loaded "$(_launchd_label "loop" "$project_path")" && _dash_loop_enabled=true
|
|
2319
|
+
else
|
|
2320
|
+
crontab -l 2>/dev/null | grep -q "${_LOOP_TAG}:${project_path}" && _dash_loop_enabled=true
|
|
2321
|
+
fi
|
|
2322
|
+
if $_dash_loop_enabled; then
|
|
2302
2323
|
echo -e " Loop ${GREEN}● on${NC} Agent: ${CYAN}${agent}${NC}"
|
|
2324
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
2325
|
+
for svc_info in "loop:hourly" "dream:03:00" "brief:09:00"; do
|
|
2326
|
+
local svc="${svc_info%%:*}" schedule="${svc_info#*:}"
|
|
2327
|
+
if _launchd_is_loaded "$(_launchd_label "$svc" "$project_path")"; then
|
|
2328
|
+
printf " ${GREEN}%-8s ● enabled${NC} (%s)\n" "$svc" "$schedule"
|
|
2329
|
+
else
|
|
2330
|
+
printf " ${YELLOW}%-8s ○ disabled${NC} (%s)\n" "$svc" "$schedule"
|
|
2331
|
+
fi
|
|
2332
|
+
done
|
|
2333
|
+
fi
|
|
2303
2334
|
else
|
|
2304
2335
|
echo -e " Loop ${YELLOW}○ off${NC} run: roll loop on"
|
|
2305
2336
|
fi
|
|
@@ -2308,7 +2339,7 @@ _dashboard() {
|
|
|
2308
2339
|
# Backlog summary
|
|
2309
2340
|
if [[ -f "BACKLOG.md" ]]; then
|
|
2310
2341
|
local pending_count
|
|
2311
|
-
pending_count=$(grep -
|
|
2342
|
+
pending_count=$(grep -cF '| 📋 Todo |' "BACKLOG.md" 2>/dev/null) || pending_count=0
|
|
2312
2343
|
if (( pending_count > 0 )); then
|
|
2313
2344
|
echo -e " Backlog ${YELLOW}${pending_count} pending${NC} run: roll backlog"
|
|
2314
2345
|
else
|
|
@@ -2322,18 +2353,15 @@ _dashboard() {
|
|
|
2322
2353
|
local mod_time now age
|
|
2323
2354
|
mod_time=$(stat -c %Y "$latest" 2>/dev/null || stat -f %m "$latest" 2>/dev/null || echo 0)
|
|
2324
2355
|
now=$(date +%s); age=$(( (now - mod_time) / 3600 ))
|
|
2325
|
-
|
|
2326
|
-
grep -
|
|
2327
|
-
echo ""
|
|
2328
|
-
echo "
|
|
2356
|
+
local readiness; readiness=$(awk '/^## Release Readiness/{found=1;next} found && /[^[:space:]]/{gsub(/\*\*/,""); print; exit}' "$latest" 2>/dev/null || true)
|
|
2357
|
+
local done_count; done_count=$(grep -c '| Story\|| Fix\|| Refactor' "$latest" 2>/dev/null) || done_count=0
|
|
2358
|
+
echo -e "\n Brief (${age}h ago) ${readiness:+${CYAN}${readiness}${NC}}"
|
|
2359
|
+
[[ "$done_count" -gt 0 ]] && echo -e " This cycle: ${done_count} items completed"
|
|
2329
2360
|
else
|
|
2330
2361
|
echo -e "\n No brief yet — run: roll brief"
|
|
2331
2362
|
fi
|
|
2332
2363
|
|
|
2333
2364
|
echo ""
|
|
2334
|
-
echo " loop <on|off|now|status|monitor|resume|reset> · brief · backlog · agent use <name> · release"
|
|
2335
|
-
echo " setup · update · init · status · peer · help"
|
|
2336
|
-
echo ""
|
|
2337
2365
|
}
|
|
2338
2366
|
|
|
2339
2367
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
@@ -2443,7 +2471,7 @@ _check_update_async() {
|
|
|
2443
2471
|
|
|
2444
2472
|
_notify_update() {
|
|
2445
2473
|
local cache="${ROLL_HOME}/.update-check"
|
|
2446
|
-
[[ -f "$cache" ]] || return
|
|
2474
|
+
[[ -f "$cache" ]] || return 0
|
|
2447
2475
|
local latest; latest=$(awk '{print $2}' "$cache" 2>/dev/null || true)
|
|
2448
2476
|
[[ -z "$latest" || "$latest" == "$VERSION" ]] && return
|
|
2449
2477
|
local newer; newer=$(printf '%s\n%s\n' "$VERSION" "$latest" | sort -V | tail -1)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seanyao/roll",
|
|
3
|
-
"version": "2026.511.
|
|
3
|
+
"version": "2026.511.3",
|
|
4
4
|
"description": "Roll — Roll out features with AI agents",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"test": "find tests/unit tests/integration -name '*.bats' | sort | xargs ./tests/helpers/bats-core/bin/bats"
|
|
@@ -95,39 +95,60 @@ A simple heuristic — not a gate, just a signal for the human:
|
|
|
95
95
|
|
|
96
96
|
### Step 4 — Write Brief
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
文件命名:`docs/briefs/YYYY-MM-DD-{NN}.md`,NN 为当日序号(01 起,零填充两位)。
|
|
99
|
+
计算方式:`ls docs/briefs/YYYY-MM-DD-*.md 2>/dev/null | wc -l`,+1 即为本次序号。
|
|
100
|
+
|
|
101
|
+
全部用中文输出。**省略空 section**(无内容时连标题一起不输出):
|
|
99
102
|
|
|
100
103
|
```markdown
|
|
101
104
|
# 简报 {YYYY-MM-DD HH:mm}
|
|
102
105
|
|
|
103
|
-
|
|
106
|
+
> 触发:{触发原因} | 覆盖:{起止时间范围}
|
|
107
|
+
|
|
108
|
+
## 已完成({N} 项)
|
|
104
109
|
| 编号 | 描述 | 类型 |
|
|
105
110
|
|----|-------------|------|
|
|
106
111
|
| US-XXX | {标题} | 用户故事 |
|
|
107
112
|
| FIX-XXX | {标题} | 缺陷修复 |
|
|
108
113
|
| REFACTOR-XXX | {标题} | 重构 |
|
|
109
114
|
|
|
115
|
+
<!-- 仅当有 🔨 条目时输出 -->
|
|
110
116
|
## 进行中
|
|
111
117
|
| 编号 | 描述 |
|
|
112
118
|
|----|-------------|
|
|
113
119
|
| US-XXX | {标题} — 开始于 {date} |
|
|
114
120
|
|
|
121
|
+
<!-- 仅当有 📋 条目时输出 -->
|
|
115
122
|
## 待处理队列({N} 项)
|
|
116
123
|
| 编号 | 描述 | 优先级 |
|
|
117
124
|
|----|-------------|----------|
|
|
118
125
|
| US-XXX | {标题} | 高 |
|
|
119
126
|
|
|
120
|
-
|
|
121
|
-
|
|
127
|
+
<!-- 仅当 roll-.dream 有新发现时输出 -->
|
|
128
|
+
## 悟见
|
|
129
|
+
{来自 docs/dream/ 的摘要}
|
|
130
|
+
|
|
131
|
+
<!-- 仅当有 ESCALATE 告警时输出 -->
|
|
132
|
+
## 需人工介入
|
|
133
|
+
{告警内容}
|
|
134
|
+
|
|
135
|
+
## 发版就绪
|
|
136
|
+
{✅ 可发版 / ⚠️ 暂缓 — 原因}
|
|
122
137
|
|
|
123
|
-
|
|
124
|
-
{任何告警,无则写"无 — agent 运行正常。"}
|
|
138
|
+
**下一版本:** `v{YYYY}.{MMDD}.{序号}`
|
|
125
139
|
|
|
126
|
-
|
|
127
|
-
{
|
|
140
|
+
- {本轮新增 1}
|
|
141
|
+
- {本轮新增 2}
|
|
128
142
|
|
|
129
143
|
---
|
|
130
|
-
|
|
144
|
+
*状态:进行中 {N} · 待处理 {N} · 告警 {N} | 下次简报:{datetime}*
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**首份简报或传入 `--full-history`**:在"已完成"表格后追加历史汇总区块:
|
|
148
|
+
|
|
149
|
+
```markdown
|
|
150
|
+
### 历史汇总
|
|
151
|
+
**Epic: {Name}** — {done}/{total} ✅
|
|
131
152
|
```
|
|
132
153
|
|
|
133
154
|
### Step 5 — Notify
|
|
@@ -135,8 +156,8 @@ Output to `docs/briefs/YYYY-MM-DD-HH.md`,全部用中文输出:
|
|
|
135
156
|
写完文件后在终端或 CI 日志中打印简报路径:
|
|
136
157
|
|
|
137
158
|
```
|
|
138
|
-
📋 简报已生成:docs/briefs/2026-05-10-
|
|
139
|
-
发布就绪:✅
|
|
159
|
+
📋 简报已生成:docs/briefs/2026-05-10-01.md
|
|
160
|
+
发布就绪:✅ 可发版
|
|
140
161
|
```
|
|
141
162
|
|
|
142
163
|
有升级事项时须显著打印,不得遗漏。
|