@seanyao/roll 2.604.1 → 3.0.0
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 +24 -0
- package/README.md +6 -0
- package/bin/roll +37 -44
- package/dist/roll.mjs +12875 -0
- package/lib/__pycache__/changelog_audit.cpython-314.pyc +0 -0
- package/lib/__pycache__/github_sync.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop-fmt.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_result_eval.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_unstick.cpython-314.pyc +0 -0
- package/lib/__pycache__/model_prices.cpython-314.pyc +0 -0
- package/lib/__pycache__/prices_fetcher.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-home.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-loop-status.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_git.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_render.cpython-314.pyc +0 -0
- package/lib/__pycache__/slides-render.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/__init__.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/gemini.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/kimi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/openai.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi_emit.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/qwen.cpython-314.pyc +0 -0
- package/lib/i18n/loop.sh +0 -4
- package/lib/roll-loop-status.py +14 -6
- package/package.json +20 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v3.0.0
|
|
4
|
+
|
|
5
|
+
### TypeScript 重写
|
|
6
|
+
|
|
7
|
+
- **引擎从 bash 换成 TypeScript** — roll 的核心重写为 pnpm monorepo(`packages/`:spec/core/infra/cli/web 分层)。这是一次引擎替换,不是功能改版
|
|
8
|
+
- **命令一个不变** — `roll init` / `loop` / `status` / `backlog` / `prices` / `slides` 等全部子命令的入参、输出、副作用、退出码保持原样;升级后照旧用
|
|
9
|
+
- **逐层对拍迁移** — 地基、CLI、领域服务、infra、loop 各层逐条移植,每条命令写 diff-test 断言「TS 输出 == 原 bash 输出」,逐字节对齐冻结的 v2 oracle
|
|
10
|
+
- **1031 项 TS 测试全绿** — 单测覆盖每个公共入口 + 跨层 diff-test;`npm i -g @seanyao/roll` 装的就是这套 TS-first CLI
|
|
11
|
+
|
|
12
|
+
### 兼容与回滚
|
|
13
|
+
|
|
14
|
+
- **bash 实现留作回落 + oracle** — `bin/roll` 随包一起发布:TS 层尚未接管的命令自动透传 bash,行为零差异;同一份 bash 也是测试套件的标准答案
|
|
15
|
+
- **v2 归档在 `v2` 分支** — 锚点 tag `v2-freeze-2026-06-04`,需要时一键回滚
|
|
16
|
+
|
|
17
|
+
## v2.604.2
|
|
18
|
+
|
|
19
|
+
### 精简
|
|
20
|
+
|
|
21
|
+
- **自动简报功能下线(FIX-195)** — 不再后台定时生成每日简报;需要时手动运行 `roll brief` 即可,过往简报都保留
|
|
22
|
+
|
|
23
|
+
### 稳定性
|
|
24
|
+
|
|
25
|
+
- **一条坏记录不再拖垮整个自动循环(FIX-193)** — 以前运行历史里出现一条损坏记录,会让 `roll loop` 整个起不来;现在自动跳过坏记录、照常运行
|
|
26
|
+
|
|
3
27
|
## v2.604.1
|
|
4
28
|
|
|
5
29
|
### PR Loop 重构
|
package/README.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
> **Roll v3 — the engine is now TypeScript (`packages/`, a pnpm monorepo). The commands are unchanged.**
|
|
2
|
+
> **Roll v3——引擎已是 TypeScript(`packages/`,pnpm monorepo);命令保持不变。**
|
|
3
|
+
> The bash implementation stays in-tree as `bin/roll`: the automatic fallback for any command the TS layer doesn't yet own, and the oracle the TS suite diff-tests against. `skills/` is a git submodule → [seanyao/roll-skills](https://github.com/seanyao/roll-skills). v2 is archived on the `v2` branch (anchor tag `v2-freeze-2026-06-04`).
|
|
4
|
+
> bash 实现作为 `bin/roll` 留在仓内:TS 层未接管命令的自动回落,也是 TS 套件对拍的 oracle。`skills/` 是 git submodule。v2 归档在 `v2` 分支(锚点 tag `v2-freeze-2026-06-04`)。
|
|
5
|
+
> Build & test: `pnpm install && pnpm -r test`.
|
|
6
|
+
|
|
1
7
|
```
|
|
2
8
|
██████╗ ██████╗ ██╗ ██╗
|
|
3
9
|
██╔══██╗██╔═══██╗██║ ██║
|
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="
|
|
7
|
+
VERSION="3.0.0"
|
|
8
8
|
ROLL_HOME="${ROLL_HOME:-${HOME}/.roll}"
|
|
9
9
|
ROLL_CONFIG="${ROLL_HOME}/config.yaml"
|
|
10
10
|
ROLL_GLOBAL="${ROLL_HOME}/conventions/global"
|
|
@@ -1092,8 +1092,6 @@ editor: ${EDITOR:-vim}
|
|
|
1092
1092
|
# loop_minute: 5 # omit to auto-derive from project hash
|
|
1093
1093
|
loop_dream_hour: 3
|
|
1094
1094
|
# loop_dream_minute: 10 # omit to auto-derive
|
|
1095
|
-
loop_brief_hour: 9
|
|
1096
|
-
# loop_brief_minute: 15 # omit to auto-derive
|
|
1097
1095
|
primary_agent: claude
|
|
1098
1096
|
YAML
|
|
1099
1097
|
ok "$(msg shared.created_roll_config_yaml)"
|
|
@@ -1418,6 +1416,13 @@ cmd_setup() {
|
|
|
1418
1416
|
esac
|
|
1419
1417
|
done
|
|
1420
1418
|
|
|
1419
|
+
# P1-3.4 (v3 branch): skills/ is a git submodule — populate it for git clones
|
|
1420
|
+
# whose skills/ is still empty. No-op for npm/curl installs (no .gitmodules).
|
|
1421
|
+
if [[ -d "$ROLL_PKG_DIR/.git" ]] && [[ -f "$ROLL_PKG_DIR/.gitmodules" ]] \
|
|
1422
|
+
&& [[ -z "$(ls -A "$ROLL_PKG_DIR/skills" 2>/dev/null)" ]]; then
|
|
1423
|
+
( cd "$ROLL_PKG_DIR" && git submodule update --init --recursive --quiet ) || true
|
|
1424
|
+
fi
|
|
1425
|
+
|
|
1421
1426
|
# Capture per-step outcomes for the v2 UI render at the end.
|
|
1422
1427
|
local steps_buf=()
|
|
1423
1428
|
_record() { steps_buf+=("$1|$2"); }
|
|
@@ -5752,8 +5757,6 @@ loop_schedule.period_minutes|project|nested:loop_schedule|1|1440|60
|
|
|
5752
5757
|
loop_schedule.offset_minute|project|nested:loop_schedule|0|59|0
|
|
5753
5758
|
loop_dream_hour|global|flat|0|23|3
|
|
5754
5759
|
loop_dream_minute|global|flat|0|59|-
|
|
5755
|
-
loop_brief_hour|global|flat|0|23|9
|
|
5756
|
-
loop_brief_minute|global|flat|0|59|-
|
|
5757
5760
|
EOF
|
|
5758
5761
|
}
|
|
5759
5762
|
|
|
@@ -5892,10 +5895,10 @@ Usage: roll config <key> print current value + source
|
|
|
5892
5895
|
roll config --list list all loop schedule keys
|
|
5893
5896
|
roll config <key> <value> [--global|--project] set a value
|
|
5894
5897
|
统一调度配置
|
|
5895
|
-
Read / list / set the loop
|
|
5898
|
+
Read / list / set the loop and dream schedule keys without hand-editing
|
|
5896
5899
|
yaml. Default write scope is --project (.roll/local.yaml); --global writes
|
|
5897
5900
|
~/.roll/config.yaml.
|
|
5898
|
-
读 / 列 / 写 loop、dream
|
|
5901
|
+
读 / 列 / 写 loop、dream 调度 key,免去手工编辑 yaml。默认写 --project
|
|
5899
5902
|
(.roll/local.yaml);--global 写 ~/.roll/config.yaml。
|
|
5900
5903
|
|
|
5901
5904
|
Supported keys (range):
|
|
@@ -5905,14 +5908,11 @@ Supported keys (range):
|
|
|
5905
5908
|
loop_schedule.offset_minute 0-59 minute offset within the period
|
|
5906
5909
|
loop_dream_hour 0-23 dream daily fire hour
|
|
5907
5910
|
loop_dream_minute 0-59 dream daily fire minute
|
|
5908
|
-
loop_brief_hour 0-23 brief daily fire hour
|
|
5909
|
-
loop_brief_minute 0-59 brief daily fire minute
|
|
5910
5911
|
|
|
5911
5912
|
Compact facades (write multiple keys at once):
|
|
5912
5913
|
roll config loop-window 9-18 loop_active_start + loop_active_end
|
|
5913
5914
|
roll config loop-schedule 30/7 period_minutes + offset_minute
|
|
5914
5915
|
roll config dream-time 03:20 loop_dream_hour + loop_dream_minute
|
|
5915
|
-
roll config brief-time 09:15 loop_brief_hour + loop_brief_minute
|
|
5916
5916
|
|
|
5917
5917
|
Examples:
|
|
5918
5918
|
roll config loop_dream_hour
|
|
@@ -6012,11 +6012,12 @@ _config_loop_schedule() {
|
|
|
6012
6012
|
return 0
|
|
6013
6013
|
}
|
|
6014
6014
|
|
|
6015
|
-
# US-LOOP-035: `roll config dream-time <HH:MM>`
|
|
6016
|
-
#
|
|
6017
|
-
#
|
|
6015
|
+
# US-LOOP-035: `roll config dream-time <HH:MM>` — compact facade writing
|
|
6016
|
+
# loop_<svc>_hour + loop_<svc>_minute in one shot. With no value, prints the
|
|
6017
|
+
# current effective time + source. HH ∈ [0,23], MM ∈ [0,59].
|
|
6018
6018
|
# These keys are global-scoped, so writes land in ~/.roll/config.yaml.
|
|
6019
|
-
#
|
|
6019
|
+
# FIX-195: brief retired — svc is {dream} (the helper stays generic).
|
|
6020
|
+
# _config_daily_time <svc> <value>
|
|
6020
6021
|
_config_daily_time() {
|
|
6021
6022
|
local svc="$1" value="$2"
|
|
6022
6023
|
local hour_key="loop_${svc}_hour" min_key="loop_${svc}_minute"
|
|
@@ -6115,8 +6116,9 @@ cmd_config() {
|
|
|
6115
6116
|
[[ $_rc -eq 0 && -n "$value" ]] && _config_reload_schedule
|
|
6116
6117
|
return $_rc
|
|
6117
6118
|
;;
|
|
6118
|
-
dream-time
|
|
6119
|
-
#
|
|
6119
|
+
dream-time)
|
|
6120
|
+
# FIX-195: brief-time retired with the brief loop; dream-time is the only
|
|
6121
|
+
# daily schedule facade. The key is global-scoped (~/.roll/config.yaml).
|
|
6120
6122
|
local fscope="$scope"; [[ -z "$fscope" ]] && fscope="global"
|
|
6121
6123
|
ROLL_CFG_SCOPE="$fscope"
|
|
6122
6124
|
local _rc
|
|
@@ -6171,7 +6173,7 @@ cmd_config() {
|
|
|
6171
6173
|
fi
|
|
6172
6174
|
_config_set "$key" "$value" "$file"
|
|
6173
6175
|
ok "✓ set $key = $value in $file"
|
|
6174
|
-
# US-LOOP-036: every recognized config key is a loop/dream
|
|
6176
|
+
# US-LOOP-036: every recognized config key is a loop/dream schedule key
|
|
6175
6177
|
# (display-only keys are out of scope for this command), so a successful write
|
|
6176
6178
|
# always reloads the launchd plists.
|
|
6177
6179
|
_config_reload_schedule
|
|
@@ -9658,9 +9660,10 @@ _install_launchd_plists() {
|
|
|
9658
9660
|
local shared="${_SHARED_ROOT}"
|
|
9659
9661
|
|
|
9660
9662
|
mkdir -p "$_LAUNCHD_DIR"
|
|
9661
|
-
|
|
9663
|
+
# FIX-194/FIX-195: brief/ci/alert loops retired — only loop/dream/pr remain.
|
|
9664
|
+
mkdir -p "${shared}/loop" "${shared}/dream" "${shared}/pr"
|
|
9662
9665
|
|
|
9663
|
-
local active_start active_end dream_hour dream_minute
|
|
9666
|
+
local active_start active_end dream_hour dream_minute loop_period loop_offset
|
|
9664
9667
|
local _aw; _aw=$(_loop_read_active_window "$project_path")
|
|
9665
9668
|
active_start="${_aw%% *}"; active_end="${_aw##* }"
|
|
9666
9669
|
# US-LOOP-012: use _loop_schedule_spec instead of raw loop_minute
|
|
@@ -9669,8 +9672,6 @@ _install_launchd_plists() {
|
|
|
9669
9672
|
loop_offset="${loop_spec##* }"
|
|
9670
9673
|
dream_hour=$(_config_read_int "loop_dream_hour" "3")
|
|
9671
9674
|
dream_minute=$(_config_read_int "loop_dream_minute" "$(_loop_derive_minute "$project_path" 2)")
|
|
9672
|
-
brief_hour=$(_config_read_int "loop_brief_hour" "9")
|
|
9673
|
-
brief_minute=$(_config_read_int "loop_brief_minute" "$(_loop_derive_minute "$project_path" 4)")
|
|
9674
9675
|
|
|
9675
9676
|
# FIX-054: terminal preference removed — runner always uses Terminal.app.
|
|
9676
9677
|
|
|
@@ -9840,7 +9841,7 @@ cmd_loop() {
|
|
|
9840
9841
|
*) cat <<'HELP'
|
|
9841
9842
|
Usage: roll loop <on|off|now|test|status|monitor|runs|log|story|events|attach|mute|unmute|pause|resume|reset|gc|branches>
|
|
9842
9843
|
|
|
9843
|
-
on Install launchd scheduler (loop + dream +
|
|
9844
|
+
on Install launchd scheduler (loop + dream + pr)
|
|
9844
9845
|
off Remove launchd scheduler
|
|
9845
9846
|
now Run one cycle immediately
|
|
9846
9847
|
test Quick smoke test (tmux/popup/stream chain)
|
|
@@ -9885,7 +9886,7 @@ _loop_on() {
|
|
|
9885
9886
|
local project_path; project_path=$(pwd -P)
|
|
9886
9887
|
local agent; agent=$(_project_agent)
|
|
9887
9888
|
|
|
9888
|
-
local active_start active_end loop_minute dream_hour dream_minute
|
|
9889
|
+
local active_start active_end loop_minute dream_hour dream_minute
|
|
9889
9890
|
local _aw; _aw=$(_loop_read_active_window "$project_path")
|
|
9890
9891
|
active_start="${_aw%% *}"; active_end="${_aw##* }"
|
|
9891
9892
|
# US-LOOP-011: read schedule spec from project or global config
|
|
@@ -9900,8 +9901,6 @@ _loop_on() {
|
|
|
9900
9901
|
loop_sched_zh=$(_loop_schedule_desc "$loop_period" "$loop_offset" zh)
|
|
9901
9902
|
dream_hour=$(_config_read_int "loop_dream_hour" "3")
|
|
9902
9903
|
dream_minute=$(_config_read_int "loop_dream_minute" "$(_loop_derive_minute "$project_path" 2)")
|
|
9903
|
-
brief_hour=$(_config_read_int "loop_brief_hour" "9")
|
|
9904
|
-
brief_minute=$(_config_read_int "loop_brief_minute" "$(_loop_derive_minute "$project_path" 4)")
|
|
9905
9904
|
|
|
9906
9905
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
9907
9906
|
_install_launchd_plists "$project_path" >/dev/null
|
|
@@ -9936,7 +9935,6 @@ _loop_on() {
|
|
|
9936
9935
|
msg loop.roll_loop_s_active_02d_00 \
|
|
9937
9936
|
"$loop_sched_en" "$active_start" "$active_end" "$loop_sched_zh" "$active_start" "$active_end"
|
|
9938
9937
|
msg loop.roll_dream_daily_at_02d_02d "$dream_hour" "$dream_minute" "$dream_hour" "$dream_minute"
|
|
9939
|
-
msg loop.roll_brief_daily_at_02d_02d "$brief_hour" "$brief_minute" "$brief_hour" "$brief_minute"
|
|
9940
9938
|
echo " • Agent: ${agent} (change: roll agent use <name>)"
|
|
9941
9939
|
return 0
|
|
9942
9940
|
fi
|
|
@@ -9947,29 +9945,26 @@ _loop_on() {
|
|
|
9947
9945
|
warn "$(msg loop.loop_already_enabled_for_this_project_2)"; return 0
|
|
9948
9946
|
fi
|
|
9949
9947
|
|
|
9950
|
-
mkdir -p "${_SHARED_ROOT}/loop" "${_SHARED_ROOT}/dream"
|
|
9948
|
+
mkdir -p "${_SHARED_ROOT}/loop" "${_SHARED_ROOT}/dream"
|
|
9951
9949
|
|
|
9952
9950
|
# FIX-052: per-project cron logs so concurrent projects don't interleave.
|
|
9953
9951
|
local slug; slug=$(_project_slug "$project_path")
|
|
9954
|
-
local loop_cmd dream_cmd
|
|
9952
|
+
local loop_cmd dream_cmd
|
|
9955
9953
|
loop_cmd="cd \"${project_path}\" && $(_agent_skill_cmd "${sd}/roll-loop/SKILL.md") >> ${_SHARED_ROOT}/loop/cron-${slug}.log 2>&1"
|
|
9956
|
-
# IDEA-051: dream
|
|
9957
|
-
mkdir -p "${project_path}/.roll/dream"
|
|
9954
|
+
# IDEA-051: dream cron log is project-local, mirroring loop (FIX-139).
|
|
9955
|
+
mkdir -p "${project_path}/.roll/dream"
|
|
9958
9956
|
dream_cmd="cd \"${project_path}\" && $(_agent_skill_cmd "${sd}/roll-.dream/SKILL.md") >> ${project_path}/.roll/dream/cron.log 2>&1"
|
|
9959
|
-
brief_cmd="cd \"${project_path}\" && $(_agent_skill_cmd "${sd}/roll-brief/SKILL.md") >> ${project_path}/.roll/brief/cron.log 2>&1"
|
|
9960
9957
|
|
|
9961
9958
|
(
|
|
9962
9959
|
crontab -l 2>/dev/null
|
|
9963
9960
|
printf "%d * * * * %s %s:%s\n" "$loop_minute" "$loop_cmd" "$_LOOP_TAG" "$project_path"
|
|
9964
9961
|
printf "%d %d * * * %s %s:%s\n" "$dream_minute" "$dream_hour" "$dream_cmd" "$_LOOP_TAG" "$project_path"
|
|
9965
|
-
printf "%d %d * * * %s %s:%s\n" "$brief_minute" "$brief_hour" "$brief_cmd" "$_LOOP_TAG" "$project_path"
|
|
9966
9962
|
) | crontab -
|
|
9967
9963
|
|
|
9968
9964
|
ok "$(msg loop.loop_enabled_2)"
|
|
9969
9965
|
msg loop.roll_loop_s_active_02d_00_2 \
|
|
9970
9966
|
"$loop_sched_en" "$active_start" "$active_end" "$loop_sched_zh" "$active_start" "$active_end"
|
|
9971
9967
|
msg loop.roll_dream_daily_at_02d_02d_2 "$dream_hour" "$dream_minute" "$dream_hour" "$dream_minute"
|
|
9972
|
-
msg loop.roll_brief_daily_at_02d_02d_2 "$brief_hour" "$brief_minute" "$brief_hour" "$brief_minute"
|
|
9973
9968
|
echo " • Agent: ${agent} (change: roll agent use <name>)"
|
|
9974
9969
|
}
|
|
9975
9970
|
|
|
@@ -13789,7 +13784,7 @@ _loop_monitor() {
|
|
|
13789
13784
|
# Services status (three services on macOS, single on Linux)
|
|
13790
13785
|
echo -e "$(msg loop.services ${BOLD} ${NC} ${CYAN} ${agent})"
|
|
13791
13786
|
if [[ "$(uname)" == "Darwin" ]]; then
|
|
13792
|
-
local active_start active_end dream_hour dream_minute
|
|
13787
|
+
local active_start active_end dream_hour dream_minute
|
|
13793
13788
|
local _aw; _aw=$(_loop_read_active_window "$project_path")
|
|
13794
13789
|
active_start="${_aw%% *}"; active_end="${_aw##* }"
|
|
13795
13790
|
# US-LOOP-013: use schedule spec for display
|
|
@@ -13799,17 +13794,16 @@ _loop_monitor() {
|
|
|
13799
13794
|
loop_offset="${loop_spec##* }"
|
|
13800
13795
|
dream_hour=$(_config_read_int "loop_dream_hour" "3")
|
|
13801
13796
|
dream_minute=$(_config_read_int "loop_dream_minute" "$(_loop_derive_minute "$project_path" 2)")
|
|
13802
|
-
brief_hour=$(_config_read_int "loop_brief_hour" "9")
|
|
13803
|
-
brief_minute=$(_config_read_int "loop_brief_minute" "$(_loop_derive_minute "$project_path" 4)")
|
|
13804
13797
|
|
|
13805
|
-
local loop_sched dream_sched
|
|
13798
|
+
local loop_sched dream_sched pr_sched
|
|
13806
13799
|
loop_sched=$(_loop_schedule_desc "$loop_period" "$loop_offset" en)
|
|
13807
13800
|
loop_sched="${loop_sched} active ${active_start}:00–${active_end}:00"
|
|
13808
13801
|
dream_sched=$(printf "%02d:%02d" "$dream_hour" "$dream_minute")
|
|
13809
|
-
|
|
13802
|
+
# FIX-195: pr is a 5-min PR Loop (StartInterval=300); brief was retired.
|
|
13803
|
+
pr_sched="every 5m"
|
|
13810
13804
|
|
|
13811
13805
|
local svcs=("loop" "dream" "pr")
|
|
13812
|
-
local scheds=("$loop_sched" "$dream_sched" "$
|
|
13806
|
+
local scheds=("$loop_sched" "$dream_sched" "$pr_sched")
|
|
13813
13807
|
for i in "${!svcs[@]}"; do
|
|
13814
13808
|
local svc="${svcs[$i]}" schedule="${scheds[$i]}"
|
|
13815
13809
|
local state; state=$(_launchd_svc_state "$svc" "$project_path")
|
|
@@ -14899,7 +14893,7 @@ _legacy_home() {
|
|
|
14899
14893
|
else
|
|
14900
14894
|
crontab -l 2>/dev/null | grep -q "${_LOOP_TAG}:${project_path}" && loop_state="enabled"
|
|
14901
14895
|
fi
|
|
14902
|
-
local active_start active_end dream_hour dream_minute
|
|
14896
|
+
local active_start active_end dream_hour dream_minute
|
|
14903
14897
|
local _aw; _aw=$(_loop_read_active_window "$project_path")
|
|
14904
14898
|
active_start="${_aw%% *}"; active_end="${_aw##* }"
|
|
14905
14899
|
# US-LOOP-013: use schedule spec for display
|
|
@@ -14909,8 +14903,6 @@ _legacy_home() {
|
|
|
14909
14903
|
loop_offset="${loop_spec##* }"
|
|
14910
14904
|
dream_hour=$(_config_read_int "loop_dream_hour" "3")
|
|
14911
14905
|
dream_minute=$(_config_read_int "loop_dream_minute" "$(_loop_derive_minute "$project_path" 2)")
|
|
14912
|
-
brief_hour=$(_config_read_int "loop_brief_hour" "9")
|
|
14913
|
-
brief_minute=$(_config_read_int "loop_brief_minute" "$(_loop_derive_minute "$project_path" 4)")
|
|
14914
14906
|
|
|
14915
14907
|
local loop_badge loop_sched
|
|
14916
14908
|
loop_sched=$(_loop_schedule_desc "$loop_period" "$loop_offset" en)
|
|
@@ -15040,8 +15032,9 @@ _legacy_home() {
|
|
|
15040
15032
|
# ── ⑥ Schedules & Last Brief ──────────────────────────────────────────────
|
|
15041
15033
|
printf " ${BOLD}⏰ Schedules & Last Brief${NC}\n"
|
|
15042
15034
|
local loop_sched_short; loop_sched_short=$(_loop_schedule_desc "$loop_period" "$loop_offset" en)
|
|
15043
|
-
|
|
15044
|
-
|
|
15035
|
+
# FIX-195: brief loop retired — schedule line shows loop + dream only.
|
|
15036
|
+
printf " %s · dream %02d:%02d\n" \
|
|
15037
|
+
"$loop_sched_short" "$dream_hour" "$dream_minute"
|
|
15045
15038
|
local latest_brief; latest_brief=$(ls .roll/briefs/*.md 2>/dev/null | sort | tail -1 || true)
|
|
15046
15039
|
if [[ -n "$latest_brief" ]]; then
|
|
15047
15040
|
local mod_time now age summary
|