@seanyao/roll 2026.518.1 → 2026.518.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.
- package/CHANGELOG.md +7 -0
- package/bin/roll +3 -3
- package/lib/roll-loop-status.py +5 -2
- package/lib/roll_render.py +8 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v2026.518.2
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **`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]`
|
|
8
|
+
- **v2026.518.1 在刚发版的仓库里 dashboard 不可用** — 上面那个崩溃在 HEAD == latest tag、或 tag 之后只有 docs/chore commit 的仓库中必触发;本版作为追加修复,升到 v2026.518.2 即恢复 `[release]`
|
|
9
|
+
|
|
3
10
|
## v2026.518.1
|
|
4
11
|
|
|
5
12
|
### 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.
|
|
7
|
+
VERSION="2026.518.2"
|
|
8
8
|
ROLL_HOME="${ROLL_HOME:-${HOME}/.roll}"
|
|
9
9
|
ROLL_CONFIG="${ROLL_HOME}/config.yaml"
|
|
10
10
|
ROLL_GLOBAL="${ROLL_HOME}/conventions/global"
|
|
@@ -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 -
|
|
5131
|
-
|
|
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)
|
package/lib/roll-loop-status.py
CHANGED
|
@@ -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",
|
|
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("今日",
|
|
645
|
+
c("dim", pad("今日", 22)) +
|
|
643
646
|
c("muted", pad("昨日", 10)) +
|
|
644
647
|
c("muted", pad("前天", 8)))
|
|
645
648
|
bilingual(hdr_en, hdr_zh)
|
package/lib/roll_render.py
CHANGED
|
@@ -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),
|
|
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),
|
|
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),
|
|
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)))
|