@seanyao/roll 2026.510.5 → 2026.510.6
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/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.510.
|
|
7
|
+
VERSION="2026.510.6"
|
|
8
8
|
ROLL_HOME="${ROLL_HOME:-${HOME}/.roll}"
|
|
9
9
|
ROLL_CONFIG="${ROLL_HOME}/config.yaml"
|
|
10
10
|
ROLL_GLOBAL="${ROLL_HOME}/conventions/global"
|
|
@@ -1332,7 +1332,16 @@ _peer_call() {
|
|
|
1332
1332
|
output="$(kimi --quiet -p "$prompt" 2>"$stderr_log" || true)"
|
|
1333
1333
|
;;
|
|
1334
1334
|
pi)
|
|
1335
|
-
output="$(pi -p
|
|
1335
|
+
output="$(pi -p "$prompt" 2>"$stderr_log" || true)"
|
|
1336
|
+
;;
|
|
1337
|
+
deepseek)
|
|
1338
|
+
output="$(deepseek "$prompt" 2>"$stderr_log" || true)"
|
|
1339
|
+
;;
|
|
1340
|
+
codex)
|
|
1341
|
+
output="$(codex exec --json --output-last-message "$prompt" 2>"$stderr_log" || true)"
|
|
1342
|
+
;;
|
|
1343
|
+
opencode)
|
|
1344
|
+
output="$(opencode run "$prompt" 2>"$stderr_log" || true)"
|
|
1336
1345
|
;;
|
|
1337
1346
|
*)
|
|
1338
1347
|
err "Unsupported peer: $to 不支持的 peer: $to"
|
|
@@ -1660,9 +1669,12 @@ _agent_run_skill() {
|
|
|
1660
1669
|
[[ -f "$skill_file" ]] || { err "Skill not found: ${skill}"; return 1; }
|
|
1661
1670
|
case "$agent" in
|
|
1662
1671
|
claude) claude -p "$(cat "$skill_file")" ;;
|
|
1663
|
-
kimi) kimi --quiet "$(cat "$skill_file")" ;;
|
|
1672
|
+
kimi) kimi --quiet -p "$(cat "$skill_file")" ;;
|
|
1664
1673
|
deepseek) deepseek "$(cat "$skill_file")" ;;
|
|
1665
|
-
|
|
1674
|
+
pi) pi -p "$(cat "$skill_file")" ;;
|
|
1675
|
+
codex) codex exec --json --output-last-message "$(cat "$skill_file")" ;;
|
|
1676
|
+
opencode) opencode run "$(cat "$skill_file")" ;;
|
|
1677
|
+
*) err "Unknown agent '${agent}'. Run: roll agent use <claude|kimi|deepseek|pi|codex|opencode>"; return 1 ;;
|
|
1666
1678
|
esac
|
|
1667
1679
|
}
|
|
1668
1680
|
|
|
@@ -1671,10 +1683,10 @@ cmd_agent() {
|
|
|
1671
1683
|
case "$subcmd" in
|
|
1672
1684
|
use)
|
|
1673
1685
|
local name="${1:-}"
|
|
1674
|
-
[[ -z "$name" ]] && { err "Usage: roll agent use <claude|kimi|deepseek>"; exit 1; }
|
|
1686
|
+
[[ -z "$name" ]] && { err "Usage: roll agent use <claude|kimi|deepseek|pi|codex|opencode>"; exit 1; }
|
|
1675
1687
|
command -v "$name" &>/dev/null || warn "${name} not found in PATH — setting anyway 未找到,仍写入配置"
|
|
1676
1688
|
if [[ -f ".roll.yaml" ]] && grep -q "^agent:" .roll.yaml; then
|
|
1677
|
-
sed
|
|
1689
|
+
local tmp; tmp=$(mktemp) && sed "s/^agent:.*/agent: ${name}/" .roll.yaml > "$tmp" && mv "$tmp" .roll.yaml
|
|
1678
1690
|
else
|
|
1679
1691
|
echo "agent: ${name}" >> .roll.yaml
|
|
1680
1692
|
fi
|
|
@@ -1714,6 +1726,20 @@ _LOOP_TAG="# roll-loop"
|
|
|
1714
1726
|
_LOOP_STATE="${HOME}/.shared/roll/loop/state.yaml"
|
|
1715
1727
|
_LOOP_ALERT="${HOME}/.shared/roll/loop/ALERT.md"
|
|
1716
1728
|
|
|
1729
|
+
_agent_skill_cmd() {
|
|
1730
|
+
local skill_path="$1"
|
|
1731
|
+
local agent; agent=$(_project_agent)
|
|
1732
|
+
case "$agent" in
|
|
1733
|
+
claude) echo "claude -p \"\$(cat '${skill_path}')\"" ;;
|
|
1734
|
+
kimi) echo "kimi --quiet -p \"\$(cat '${skill_path}')\"" ;;
|
|
1735
|
+
deepseek) echo "deepseek \"\$(cat '${skill_path}')\"" ;;
|
|
1736
|
+
pi) echo "pi -p \"\$(cat '${skill_path}')\"" ;;
|
|
1737
|
+
codex) echo "codex exec --json --output-last-message \"\$(cat '${skill_path}')\"" ;;
|
|
1738
|
+
opencode) echo "opencode run \"\$(cat '${skill_path}')\"" ;;
|
|
1739
|
+
*) err "Unknown agent '${agent}'. Run: roll agent use <claude|kimi|deepseek|pi|codex|opencode>"; return 1 ;;
|
|
1740
|
+
esac
|
|
1741
|
+
}
|
|
1742
|
+
|
|
1717
1743
|
cmd_loop() {
|
|
1718
1744
|
local subcmd="${1:-status}"; shift || true
|
|
1719
1745
|
case "$subcmd" in
|
|
@@ -1721,7 +1747,9 @@ cmd_loop() {
|
|
|
1721
1747
|
off) _loop_off ;;
|
|
1722
1748
|
now) _loop_now ;;
|
|
1723
1749
|
status) _loop_status ;;
|
|
1724
|
-
|
|
1750
|
+
resume) _loop_resume ;;
|
|
1751
|
+
reset) _loop_reset ;;
|
|
1752
|
+
*) err "Usage: roll loop <on|off|now|status|resume|reset>"; exit 1 ;;
|
|
1725
1753
|
esac
|
|
1726
1754
|
}
|
|
1727
1755
|
|
|
@@ -1737,9 +1765,9 @@ _loop_on() {
|
|
|
1737
1765
|
mkdir -p ~/.shared/roll/{loop,dream,brief}
|
|
1738
1766
|
|
|
1739
1767
|
local loop_cmd dream_cmd brief_cmd
|
|
1740
|
-
loop_cmd="cd \"${project_path}\" && $
|
|
1741
|
-
dream_cmd="cd \"${project_path}\" && $
|
|
1742
|
-
brief_cmd="cd \"${project_path}\" && $
|
|
1768
|
+
loop_cmd="cd \"${project_path}\" && $(_agent_skill_cmd "${sd}/roll-loop/SKILL.md") >> ~/.shared/roll/loop/cron.log 2>&1"
|
|
1769
|
+
dream_cmd="cd \"${project_path}\" && $(_agent_skill_cmd "${sd}/roll-.dream/SKILL.md") >> ~/.shared/roll/dream/cron.log 2>&1"
|
|
1770
|
+
brief_cmd="cd \"${project_path}\" && $(_agent_skill_cmd "${sd}/roll-brief/SKILL.md") >> ~/.shared/roll/brief/cron.log 2>&1"
|
|
1743
1771
|
|
|
1744
1772
|
(
|
|
1745
1773
|
crontab -l 2>/dev/null
|
|
@@ -1786,6 +1814,26 @@ _loop_status() {
|
|
|
1786
1814
|
echo ""
|
|
1787
1815
|
}
|
|
1788
1816
|
|
|
1817
|
+
_loop_resume() {
|
|
1818
|
+
if [[ ! -f "$_LOOP_STATE" ]]; then
|
|
1819
|
+
warn "No loop state found — nothing to resume 未找到 loop 状态,无需恢复"; return 0
|
|
1820
|
+
fi
|
|
1821
|
+
if grep -q "status: running" "$_LOOP_STATE" 2>/dev/null; then
|
|
1822
|
+
warn "Loop already running loop 正在运行中"; return 0
|
|
1823
|
+
fi
|
|
1824
|
+
info "Resuming loop from last state... 正在从上次状态恢复..."
|
|
1825
|
+
_agent_run_skill "roll-loop"
|
|
1826
|
+
}
|
|
1827
|
+
|
|
1828
|
+
_loop_reset() {
|
|
1829
|
+
if [[ -f "$_LOOP_STATE" ]]; then
|
|
1830
|
+
rm -f "$_LOOP_STATE"
|
|
1831
|
+
ok "Loop state cleared — will start fresh on next run loop 状态已清除,下次运行将重新开始"
|
|
1832
|
+
else
|
|
1833
|
+
info "No loop state to clear 无 loop 状态可清除"
|
|
1834
|
+
fi
|
|
1835
|
+
}
|
|
1836
|
+
|
|
1789
1837
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
1790
1838
|
# BRIEF — owner-facing project digest
|
|
1791
1839
|
# ═══════════════════════════════════════════════════════════════════════════════
|
|
@@ -1812,6 +1860,23 @@ cmd_brief() {
|
|
|
1812
1860
|
[[ -f "$latest" ]] && cat "$latest"
|
|
1813
1861
|
}
|
|
1814
1862
|
|
|
1863
|
+
cmd_release() {
|
|
1864
|
+
local script="scripts/release.sh"
|
|
1865
|
+
if [[ ! -f "$script" ]]; then
|
|
1866
|
+
err "scripts/release.sh not found — run this command from the roll project root."
|
|
1867
|
+
exit 1
|
|
1868
|
+
fi
|
|
1869
|
+
# Sync CHANGELOG.md before releasing, using the configured agent
|
|
1870
|
+
local last_tag; last_tag=$(git tag --sort=-version:refname | grep "^v" | head -1)
|
|
1871
|
+
if [[ -n "$last_tag" ]] && ! git diff "${last_tag}..HEAD" --name-only | grep -q "CHANGELOG.md"; then
|
|
1872
|
+
info "CHANGELOG.md not updated since ${last_tag}, syncing via $(_project_agent)..."
|
|
1873
|
+
_agent_run_skill "roll-.changelog"
|
|
1874
|
+
fi
|
|
1875
|
+
bash "$script" "$@"
|
|
1876
|
+
}
|
|
1877
|
+
|
|
1878
|
+
# ─────────────────────────────────────────────────────────────────────────────
|
|
1879
|
+
|
|
1815
1880
|
_dashboard() {
|
|
1816
1881
|
local project_path; project_path=$(pwd -P)
|
|
1817
1882
|
local project_name; project_name=$(basename "$project_path")
|
|
@@ -1841,7 +1906,7 @@ _dashboard() {
|
|
|
1841
1906
|
fi
|
|
1842
1907
|
|
|
1843
1908
|
echo ""
|
|
1844
|
-
echo " roll loop on|off|now|status · roll brief · roll agent use <name>"
|
|
1909
|
+
echo " roll loop on|off|now|status|resume|reset · roll brief · roll agent use <name>"
|
|
1845
1910
|
echo ""
|
|
1846
1911
|
}
|
|
1847
1912
|
|
|
@@ -1867,7 +1932,7 @@ usage() {
|
|
|
1867
1932
|
echo " init [Project] Create AGENTS.md + BACKLOG.md + docs/ 初始化项目工作流文件"
|
|
1868
1933
|
echo " status [Diagnostic] Show current state 显示当前状态"
|
|
1869
1934
|
echo " peer [Peer Review] Cross-agent negotiation 跨 Agent 协商对审"
|
|
1870
|
-
echo " loop <on|off|now|status> [Autonomous] Manage scheduled BACKLOG executor 管理自主执行循环"
|
|
1935
|
+
echo " loop <on|off|now|status|resume|reset> [Autonomous] Manage scheduled BACKLOG executor 管理自主执行循环"
|
|
1871
1936
|
echo " brief [Digest] Show latest owner brief (regenerate if stale) 展示最新简报"
|
|
1872
1937
|
echo " agent [use <name>|list] [Config] Per-project agent selection 切换项目 agent"
|
|
1873
1938
|
echo ""
|
|
@@ -1894,6 +1959,7 @@ main() {
|
|
|
1894
1959
|
loop) cmd_loop "$@" ;;
|
|
1895
1960
|
brief) cmd_brief "$@" ;;
|
|
1896
1961
|
agent) cmd_agent "$@" ;;
|
|
1962
|
+
release) cmd_release "$@" ;;
|
|
1897
1963
|
version|--version|-v) echo "roll v${VERSION}" ;;
|
|
1898
1964
|
help|--help|-h) usage ;;
|
|
1899
1965
|
"") [[ -f "BACKLOG.md" ]] && _dashboard || { usage; _show_changelog; } ;;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seanyao/roll",
|
|
3
|
-
"version": "2026.510.
|
|
3
|
+
"version": "2026.510.6",
|
|
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"
|
|
@@ -144,18 +144,8 @@ roll-.dream runs **locally** — it reads the local codebase directly.
|
|
|
144
144
|
|
|
145
145
|
### Local cron (default)
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
0 1 * * * cd /path/to/project && claude -p "$(cat ~/.roll/skills/roll-.dream/SKILL.md)" >> ~/.shared/roll/dream/cron.log 2>&1
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
Installed automatically via `roll loop install` alongside roll-loop.
|
|
153
|
-
The agent command is read from `~/.roll/config.yaml → loop.primary_agent`.
|
|
154
|
-
|
|
155
|
-
### Agent with native scheduling support
|
|
156
|
-
|
|
157
|
-
If your agent (Claude Code, opencode, etc.) supports scheduled prompts
|
|
158
|
-
natively, prefer that over cron for cleaner lifecycle management.
|
|
147
|
+
Installed automatically via `roll loop on` alongside roll-loop and roll-brief.
|
|
148
|
+
The cron entry is generated using the configured agent — no manual cron editing needed.
|
|
159
149
|
|
|
160
150
|
## Failure Handling
|
|
161
151
|
|
|
@@ -150,13 +150,8 @@ BACKLOG state and git history directly.
|
|
|
150
150
|
|
|
151
151
|
### Local cron (daily morning)
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
0 8 * * * cd /path/to/project && claude -p "$(cat ~/.roll/skills/roll-brief/SKILL.md)"
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
Installed automatically via `roll loop install` alongside roll-loop and
|
|
159
|
-
roll-.dream. The agent command respects `~/.roll/config.yaml → loop.primary_agent`.
|
|
153
|
+
Installed automatically via `roll loop on` alongside roll-loop and roll-.dream.
|
|
154
|
+
The cron entry is generated using the configured agent — no manual cron editing needed.
|
|
160
155
|
|
|
161
156
|
### Triggered by roll-loop
|
|
162
157
|
|
|
@@ -517,6 +517,9 @@ git push
|
|
|
517
517
|
|
|
518
518
|
### Phase 12: Report & Celebrate
|
|
519
519
|
|
|
520
|
+
**Before reporting, run `$roll-.changelog`** to sync completed Story to CHANGELOG.md.
|
|
521
|
+
This is mandatory — release notes depend on it.
|
|
522
|
+
|
|
520
523
|
```
|
|
521
524
|
✅ Pushed to GitHub: origin/main
|
|
522
525
|
🚀 Deployed: <url>
|
|
@@ -601,7 +604,7 @@ Before creating any file or directory:
|
|
|
601
604
|
- [ ] **Verification Gate passed** (fresh evidence for tests, build, deploy, no regression)
|
|
602
605
|
- [ ] **BACKLOG.md index status updated** (📋 → ✅, REQUIRED)
|
|
603
606
|
- [ ] **`docs/features/<feature>.md` US section updated** (Completed date + [x] ACs, REQUIRED)
|
|
604
|
-
- [ ] **CHANGELOG.md updated** via `$roll-.changelog`
|
|
607
|
+
- [ ] **CHANGELOG.md updated** via `$roll-.changelog` (REQUIRED)
|
|
605
608
|
- [ ] Summary reported to user
|
|
606
609
|
|
|
607
610
|
---
|
package/skills/roll-fix/SKILL.md
CHANGED
|
@@ -174,47 +174,20 @@ cannot fulfill these requirements.
|
|
|
174
174
|
|
|
175
175
|
### Local cron (default)
|
|
176
176
|
|
|
177
|
-
Install once with `roll loop
|
|
177
|
+
Install once with `roll loop on` — it reads the configured agent from
|
|
178
|
+
`.roll.yaml` or `~/.roll/config.yaml` and writes the correct cron entry
|
|
179
|
+
automatically. No agent-specific command needed.
|
|
178
180
|
|
|
179
181
|
```bash
|
|
180
|
-
#
|
|
181
|
-
|
|
182
|
+
roll loop on # install cron for loop + dream + brief
|
|
183
|
+
roll loop off # remove cron entries
|
|
184
|
+
roll loop status # show current state
|
|
182
185
|
```
|
|
183
186
|
|
|
184
|
-
The agent invoked (`claude`, `kimi`, `deepseek`, etc.) is read from
|
|
185
|
-
`~/.roll/config.yaml → loop.primary_agent`. The command is agent-agnostic:
|
|
186
|
-
|
|
187
|
-
```bash
|
|
188
|
-
# claude
|
|
189
|
-
claude -p "$(cat ~/.roll/skills/roll-loop/SKILL.md)"
|
|
190
|
-
|
|
191
|
-
# kimi
|
|
192
|
-
kimi --quiet "$(cat ~/.roll/skills/roll-loop/SKILL.md)"
|
|
193
|
-
|
|
194
|
-
# deepseek
|
|
195
|
-
deepseek "$(cat ~/.roll/skills/roll-loop/SKILL.md)"
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
### Agent with native scheduling support
|
|
199
|
-
|
|
200
|
-
Some agents support scheduled prompts natively (e.g., Claude Code hooks,
|
|
201
|
-
opencode scheduled tasks). If your agent supports it, prefer that over cron
|
|
202
|
-
— the agent handles its own lifecycle and the setup is cleaner.
|
|
203
|
-
|
|
204
|
-
Consult your agent's documentation for scheduling configuration.
|
|
205
|
-
|
|
206
187
|
### Manual run (for testing)
|
|
207
188
|
|
|
208
189
|
```bash
|
|
209
|
-
roll loop
|
|
210
|
-
roll loop status # show current state without running
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
### Local cron
|
|
214
|
-
|
|
215
|
-
```bash
|
|
216
|
-
# Every hour
|
|
217
|
-
0 * * * * cd /path/to/project && claude -p "$(cat ~/.roll/skills/roll-loop/SKILL.md)" >> ~/.shared/roll/loop/cron.log 2>&1
|
|
190
|
+
roll loop now # execute one cycle immediately
|
|
218
191
|
```
|
|
219
192
|
|
|
220
193
|
## Integration Map
|
|
@@ -170,12 +170,13 @@ If serve mode is available, prefer HTTP transport over direct CLI invocation.
|
|
|
170
170
|
|
|
171
171
|
| Peer | Non-interactive command | Reliability | Notes |
|
|
172
172
|
|------|------------------------|-------------|-------|
|
|
173
|
-
| `claude` | `claude -p "<prompt>"` | ✅
|
|
174
|
-
| `deepseek` | `deepseek "<prompt>"` | ✅
|
|
173
|
+
| `claude` | `claude -p "<prompt>"` | ✅ Verified | Native, stable |
|
|
174
|
+
| `deepseek` | `deepseek "<prompt>"` | ✅ Verified | No TTY dependency |
|
|
175
175
|
| `deepseek` (serve) | `curl localhost:<port>/v1/...` | ✅ High | Start with `deepseek serve --http`; preferred over direct CLI |
|
|
176
|
-
| `kimi` | `kimi --quiet "<prompt>"` |
|
|
177
|
-
| `
|
|
178
|
-
| `
|
|
176
|
+
| `kimi` | `kimi --quiet -p "<prompt>"` | ✅ Verified | `--quiet` is alias for `--print --output-format text --final-message-only`; prompt via `-p` |
|
|
177
|
+
| `pi` | `pi -p "<prompt>"` | ✅ Verified | Clean non-interactive output |
|
|
178
|
+
| `opencode` | `opencode run "<prompt>"` | ✅ Verified | Works non-interactively |
|
|
179
|
+
| `codex` | `codex exec "<prompt>"` | ⚠️ Auth required | Token must be valid; re-login with `codex login` if expired |
|
|
179
180
|
|
|
180
181
|
**CLI vs. API Key**: `claude`, `deepseek`, `kimi`, `codex` CLIs authenticate via existing subscription accounts — no separate API key required. This is the primary advantage of CLI transport over the MCP/HTTP approach.
|
|
181
182
|
|