@seanyao/roll 2026.518.1 → 2026.518.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 CHANGED
@@ -1,5 +1,18 @@
1
1
  # Changelog
2
2
 
3
+ ## v2026.518.3
4
+
5
+ ### Fixed
6
+
7
+ - **autonomous loop 跑测试时狂开 Ghostty 窗口** — `_write_loop_runner_script` 生成的 outer runner 在 popup 分支只检查 `ROLL_LOOP_NO_POPUP` / mute 文件 / Darwin;当 loop 的执行 agent 跑 bats 跑到 `_loop_test` 这类需要执行生成脚本的测试时,每个 test case 都会真的弹一个 Ghostty 窗口,一轮 cycle 累出 80+ 个孤儿窗口。popup 守卫追加 `BATS_TEST_NUMBER` 判定,任何 bats 上下文里自动跳过 popup `[loop]`
8
+
9
+ ## v2026.518.2
10
+
11
+ ### Fixed
12
+
13
+ - **`roll loop status` dashboard 崩溃 / 列对齐** — `_dash_release_ready` 用 `grep -c` 在零匹配时返回 "0" + 非零退出码再被 `|| echo 0` 追加一个 "0",拼成 "0\n0" 让 `[[ -gt ]]` 报语法错;改用 `grep | wc -l | tr -d ' '` 单值返回。Today 表头去掉 "(in progress)" 后缀(曾溢出到 Yesterday 列),数值列宽 6→8 让指标行对齐表头 `[loop]`
14
+ - **v2026.518.1 在刚发版的仓库里 dashboard 不可用** — 上面那个崩溃在 HEAD == latest tag、或 tag 之后只有 docs/chore commit 的仓库中必触发;本版作为追加修复,升到 v2026.518.2 即恢复 `[release]`
15
+
3
16
  ## v2026.518.1
4
17
 
5
18
  ### Improved
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.518.1"
7
+ VERSION="2026.518.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"
@@ -2590,7 +2590,7 @@ if command -v tmux >/dev/null 2>&1; then
2590
2590
  # Auto-attach popup: when not muted, spawn a Terminal window attached to the
2591
2591
  # tmux session so the user can watch the loop work in real time. Best-effort
2592
2592
  # focus retention: capture the current frontmost app and re-activate after.
2593
- if [ -z "\${ROLL_LOOP_NO_POPUP:-}" ] && [ ! -f "\$HOME/.shared/roll/loop/mute-${slug}" ] && [ "\$(uname)" = "Darwin" ]; then
2593
+ if [ -z "\${ROLL_LOOP_NO_POPUP:-}" ] && [ -z "\${BATS_TEST_NUMBER:-}" ] && [ ! -f "\$HOME/.shared/roll/loop/mute-${slug}" ] && [ "\$(uname)" = "Darwin" ]; then
2594
2594
  # Runtime terminal detection: try preferred first, fallback through installed apps.
2595
2595
  # open -na returns non-zero when app not found, so || chain works as fallback.
2596
2596
  _launched=0
@@ -5127,8 +5127,8 @@ _dash_release_ready() {
5127
5127
  latest_tag=$(git describe --tags --abbrev=0 2>/dev/null) || return 1
5128
5128
  local commits_with_code
5129
5129
  commits_with_code=$(git log "${latest_tag}..HEAD" --pretty=format:%s 2>/dev/null \
5130
- | grep -cvE '^(docs|chore)(\([^)]*\))?:[[:space:]]' 2>/dev/null \
5131
- || echo 0)
5130
+ | grep -vE '^(docs|chore)(\([^)]*\))?:[[:space:]]' \
5131
+ | wc -l | tr -d ' ')
5132
5132
  [[ "${commits_with_code:-0}" -gt 0 ]] || return 1
5133
5133
  local latest
5134
5134
  latest=$(ls docs/briefs/*.md 2>/dev/null | sort | tail -1 || true)
@@ -634,12 +634,15 @@ def render(events, cron, state, backlog, *, days=3, lang="both", now=None,
634
634
  # 'in progress' indicator stays on the day band + muted deltas, not the
635
635
  # column header (cramming '(in progress)' into 18 chars collides with
636
636
  # the Yesterday column).
637
+ # Today column spans 22 cols = value(8) + gap(2) + delta(12), matching
638
+ # the metric row geometry exactly so Yesterday and −2d line up under
639
+ # their data — fixes the "yesterday/−2d squished" misalignment.
637
640
  hdr_en = (" " + c("muted", pad("", 14)) +
638
- c("fg", pad("Today", 18), bold=True) +
641
+ c("fg", pad("Today", 22), bold=True) +
639
642
  c("dim", pad("Yesterday", 10)) +
640
643
  c("muted", pad("−2d", 8)))
641
644
  hdr_zh = (" " + c("muted", pad("", 14)) +
642
- c("dim", pad("今日", 18)) +
645
+ c("dim", pad("今日", 22)) +
643
646
  c("muted", pad("昨日", 10)) +
644
647
  c("muted", pad("前天", 8)))
645
648
  bilingual(hdr_en, hdr_zh)
@@ -158,14 +158,18 @@ def metric(name: str, t: int, y: int, d2: int, kind: str, *,
158
158
  partial: bool = False) -> None:
159
159
  """Print one metric row. When `partial=True` the delta is rendered in
160
160
  muted gray instead of green/red — today's incomplete, so a 'down −23'
161
- against yesterday's full day would otherwise read as an alarm."""
161
+ against yesterday's full day would otherwise read as an alarm.
162
+
163
+ Column geometry (kept in lockstep with the header in roll-loop-status):
164
+ indent 2 · name 14 · today_value 8 · gap 2 · delta 12 · yest 10 · d2 8
165
+ """
162
166
  delta_text, delta_c = fmt_delta(float(t), float(y), kind=kind)
163
167
  if partial and delta_c not in ("muted",):
164
168
  delta_c = "muted"
165
169
  yest_str = f"{y}" + (f" {yest_suffix}" if yest_suffix else "")
166
170
  print(" " +
167
171
  c("dim", pad(name, 14)) +
168
- c("fg", pad(str(t), 6, "r"), bold=True) + " " +
172
+ c("fg", pad(str(t), 8, "r"), bold=True) + " " +
169
173
  c(delta_c, pad(delta_text, 12), bold=(delta_c != "muted")) +
170
174
  c(yest_color, pad(yest_str, 10), bold=bool(yest_suffix)) +
171
175
  c("muted", pad(str(d2), 8)))
@@ -179,7 +183,7 @@ def metric_dur(name: str, t: int, y: int, d2: int, *, partial: bool = False) ->
179
183
  delta_c = "muted"
180
184
  print(" " +
181
185
  c("dim", pad(name, 14)) +
182
- c("fg", pad(fmt_dur(t), 6, "r"), bold=True) + " " +
186
+ c("fg", pad(fmt_dur(t), 8, "r"), bold=True) + " " +
183
187
  c(delta_c, pad(delta_text, 12), bold=(delta_c != "muted")) +
184
188
  c("dim", pad(fmt_dur(y), 10)) +
185
189
  c("muted", pad(fmt_dur(d2), 8)))
@@ -214,7 +218,7 @@ def metric_tokens(name: str, t: int, y: int, d2: int, *, partial: bool = False)
214
218
  delta_c = "muted"
215
219
  print(" " +
216
220
  c("dim", pad(name, 14)) +
217
- c("fg", pad(fmt_tokens(t), 6, "r"), bold=True) + " " +
221
+ c("fg", pad(fmt_tokens(t), 8, "r"), bold=True) + " " +
218
222
  c(delta_c, pad(delta_text, 12), bold=(delta_c != "muted")) +
219
223
  c("dim", pad(fmt_tokens(y), 10)) +
220
224
  c("muted", pad(fmt_tokens(d2), 8)))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seanyao/roll",
3
- "version": "2026.518.1",
3
+ "version": "2026.518.3",
4
4
  "description": "Roll — Roll out features with AI agents",
5
5
  "scripts": {
6
6
  "test": "bash tests/run.sh"