@seanyao/roll 0.5.0 → 2.602.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 +736 -0
- package/LICENSE +21 -0
- package/README.md +65 -165
- package/bin/dream-test-quality-scan +110 -0
- package/bin/roll +15030 -814
- package/conventions/config.yaml +17 -1
- package/conventions/global/AGENTS.md +146 -100
- package/conventions/global/CLAUDE.md +1 -21
- package/conventions/global/GEMINI.md +8 -22
- package/conventions/global/project_rules.md +9 -0
- package/conventions/templates/backend-service/AGENTS.md +30 -81
- package/conventions/templates/backend-service/GEMINI.md +3 -3
- package/conventions/templates/backend-service/project_rules.md +16 -0
- package/conventions/templates/cli/AGENTS.md +31 -58
- package/conventions/templates/cli/CLAUDE.md +3 -5
- package/conventions/templates/cli/GEMINI.md +3 -3
- package/conventions/templates/cli/project_rules.md +16 -0
- package/conventions/templates/frontend-only/AGENTS.md +29 -64
- package/conventions/templates/frontend-only/GEMINI.md +3 -3
- package/conventions/templates/frontend-only/project_rules.md +14 -0
- package/conventions/templates/fullstack/AGENTS.md +31 -79
- package/conventions/templates/fullstack/CLAUDE.md +1 -1
- package/conventions/templates/fullstack/GEMINI.md +3 -3
- package/conventions/templates/fullstack/project_rules.md +15 -0
- package/lib/README.md +42 -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/README.md +49 -0
- package/lib/agent_usage/__init__.py +108 -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/agent_usage/gemini.py +127 -0
- package/lib/agent_usage/kimi.py +278 -0
- package/lib/agent_usage/kimi_emit.py +123 -0
- package/lib/agent_usage/openai.py +126 -0
- package/lib/agent_usage/pi.py +200 -0
- package/lib/agent_usage/pi_emit.py +135 -0
- package/lib/agent_usage/qwen.py +128 -0
- package/lib/backfill-pi-usage.py +243 -0
- package/lib/changelog_audit.py +155 -0
- package/lib/changelog_generate.py +263 -0
- package/lib/context_feed_budget.sh +194 -0
- package/lib/github_sync.py +876 -0
- package/lib/i18n/README.md +54 -0
- package/lib/i18n/agent.sh +75 -0
- package/lib/i18n/alert.sh +20 -0
- package/lib/i18n/backlog.sh +96 -0
- package/lib/i18n/brief.sh +5 -0
- package/lib/i18n/changelog.sh +5 -0
- package/lib/i18n/ci.sh +15 -0
- package/lib/i18n/debug.sh +0 -0
- package/lib/i18n/doctor.sh +44 -0
- package/lib/i18n/dream.sh +0 -0
- package/lib/i18n/init.sh +91 -0
- package/lib/i18n/lang.sh +10 -0
- package/lib/i18n/loop.sh +140 -0
- package/lib/i18n/migrate.sh +74 -0
- package/lib/i18n/offboard.sh +31 -0
- package/lib/i18n/onboard.sh +0 -0
- package/lib/i18n/peer.sh +41 -0
- package/lib/i18n/peer_help.sh +25 -0
- package/lib/i18n/peer_reset.sh +7 -0
- package/lib/i18n/peer_status.sh +5 -0
- package/lib/i18n/prices.sh +3 -0
- package/lib/i18n/prices_refresh.sh +17 -0
- package/lib/i18n/prices_show.sh +7 -0
- package/lib/i18n/propose.sh +0 -0
- package/lib/i18n/release.sh +0 -0
- package/lib/i18n/research.sh +0 -0
- package/lib/i18n/review_pr.sh +0 -0
- package/lib/i18n/sentinel.sh +0 -0
- package/lib/i18n/setup.sh +3 -0
- package/lib/i18n/shared.sh +157 -0
- package/lib/i18n/skills/roll-brief.sh +47 -0
- package/lib/i18n/skills/roll-build.sh +97 -0
- package/lib/i18n/skills/roll-design.sh +18 -0
- package/lib/i18n/skills/roll-fix.sh +53 -0
- package/lib/i18n/skills/roll-loop.sh +28 -0
- package/lib/i18n/skills/roll-onboard.sh +33 -0
- package/lib/i18n/skills_catalog.sh +30 -0
- package/lib/i18n/slides.sh +3 -0
- package/lib/i18n/slides_build.sh +38 -0
- package/lib/i18n/slides_delete.sh +19 -0
- package/lib/i18n/slides_list.sh +14 -0
- package/lib/i18n/slides_logs.sh +12 -0
- package/lib/i18n/slides_new.sh +15 -0
- package/lib/i18n/slides_preview.sh +14 -0
- package/lib/i18n/slides_templates.sh +7 -0
- package/lib/i18n/status.sh +21 -0
- package/lib/i18n/update.sh +24 -0
- package/lib/i18n.sh +211 -0
- package/lib/loop-exit-summary.py +393 -0
- package/lib/loop-fmt.py +589 -0
- package/lib/loop_pick_agent.py +316 -0
- package/lib/loop_result_eval.py +469 -0
- package/lib/loop_unstick.py +180 -0
- package/lib/model_prices.py +194 -0
- package/lib/prices/README.md +35 -0
- package/lib/prices/snapshot-2026-05-22.json +22 -0
- package/lib/prices/snapshot-2026-05-23-deepseek.json +15 -0
- package/lib/prices/snapshot-2026-05-23-kimi.json +15 -0
- package/lib/prices_fetcher.py +285 -0
- package/lib/roll-backlog.py +225 -0
- package/lib/roll-brief.py +286 -0
- package/lib/roll-help.py +158 -0
- package/lib/roll-home.py +556 -0
- package/lib/roll-init.py +156 -0
- package/lib/roll-loop-status.py +1683 -0
- package/lib/roll-loop-story.py +191 -0
- package/lib/roll-onboard-render.py +378 -0
- package/lib/roll-peer.py +252 -0
- package/lib/roll-plan-validate.py +386 -0
- package/lib/roll-setup.py +102 -0
- package/lib/roll-status.py +367 -0
- package/lib/roll_git.py +41 -0
- package/lib/roll_render.py +414 -0
- package/lib/slides/components/README.md +123 -0
- package/lib/slides/components/cards-2.html +9 -0
- package/lib/slides/components/cards-3.html +9 -0
- package/lib/slides/components/cards-4.html +9 -0
- package/lib/slides/components/compare.html +22 -0
- package/lib/slides/components/highlight.html +9 -0
- package/lib/slides/components/pipeline.html +12 -0
- package/lib/slides/components/plain.html +7 -0
- package/lib/slides/components/quote.html +4 -0
- package/lib/slides/components/timeline.html +9 -0
- package/lib/slides/templates/introduction-v3.html +571 -0
- package/lib/slides/templates/pitch.html +0 -0
- package/lib/slides-render.py +778 -0
- package/lib/slides-validate.py +357 -0
- package/lib/test_quality_gate.py +143 -0
- package/package.json +8 -7
- package/skills/roll-.changelog/SKILL.md +406 -33
- package/skills/roll-.clarify/SKILL.md +5 -2
- package/skills/roll-.dream/SKILL.md +374 -0
- package/skills/roll-.echo/SKILL.md +5 -2
- package/skills/roll-.qa/SKILL.md +57 -3
- package/skills/roll-.review/SKILL.md +42 -3
- package/skills/roll-brief/SKILL.md +209 -0
- package/skills/roll-build/SKILL.md +308 -63
- package/skills/roll-debug/SKILL.md +341 -162
- package/skills/roll-debug/injectable-bb.js +263 -0
- package/skills/roll-deck/SKILL.md +296 -0
- package/skills/roll-design/ENGINEERING_CHECKLIST.md +1 -1
- package/skills/roll-design/SKILL.md +733 -94
- package/skills/roll-doc/SKILL.md +595 -0
- package/skills/roll-doctor/SKILL.md +192 -0
- package/skills/roll-fix/SKILL.md +149 -32
- package/skills/{roll-jot → roll-idea}/SKILL.md +18 -10
- package/skills/roll-loop/SKILL.md +579 -0
- package/skills/roll-notes/SKILL.md +103 -0
- package/skills/roll-onboard/SKILL.md +234 -0
- package/skills/roll-peer/SKILL.md +336 -0
- package/skills/roll-propose/SKILL.md +157 -0
- package/skills/roll-review-pr/SKILL.md +58 -0
- package/skills/roll-sentinel/SKILL.md +11 -2
- package/skills/roll-spar/SKILL.md +8 -6
- package/template/.github/workflows/ci.yml +5 -2
- package/template/AGENTS.md +20 -74
- package/skills/roll-research/SKILL.md +0 -307
- package/skills/roll-research/references/schema.json +0 -162
- package/skills/roll-research/scripts/md_to_pdf.py +0 -289
- package/tools/roll-fetch/SKILL.md +0 -182
- package/tools/roll-fetch/package.json +0 -15
- package/tools/roll-fetch/smart-web-fetch.js +0 -558
- package/tools/roll-probe/SKILL.md +0 -84
- /package/template/{BACKLOG.md → .roll/backlog.md} +0 -0
package/lib/roll-init.py
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""roll-init — v2 terminal view for `roll init`.
|
|
3
|
+
|
|
4
|
+
Reads a single JSON document from stdin describing real step outcomes
|
|
5
|
+
captured by the bash flow in `bin/roll cmd_init`. Renders the v2 UI
|
|
6
|
+
(banner + horizontal rule + numbered steps + NEXT block) preserving the
|
|
7
|
+
visual style of US-VIEW-008 but reflecting what actually happened.
|
|
8
|
+
|
|
9
|
+
Input schema (single JSON object on stdin):
|
|
10
|
+
{
|
|
11
|
+
"kind": "init", # informational; UI label uses header_label
|
|
12
|
+
"header_label": "INIT", # banner label (e.g. "INIT" / "REINIT")
|
|
13
|
+
"subtitle": "项目初始化", # banner subtitle
|
|
14
|
+
"project_path": "/path/to/project", # right-aligned banner text
|
|
15
|
+
"steps": [
|
|
16
|
+
{"num": 1, "label": "Detect project type", "status": "ok"},
|
|
17
|
+
{"num": 2, "label": "Create AGENTS.md", "status": "ok",
|
|
18
|
+
"files": [["+", "AGENTS.md"]]},
|
|
19
|
+
{"num": 3, "label": "...", "status": "skip", "note": "already exists"},
|
|
20
|
+
{"num": 4, "label": "...", "status": "fail", "error": "permission denied"}
|
|
21
|
+
],
|
|
22
|
+
"footer": {"status": "ok", "label": "Project ready"},
|
|
23
|
+
"next": [["Edit .roll/backlog.md", "open the backlog and add your first US"]]
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
`status` values: ok | skip | fail.
|
|
27
|
+
`files` ops: "+" created "~" merged "·" unchanged "✗" failed.
|
|
28
|
+
|
|
29
|
+
If stdin is empty or invalid JSON, exit 1 with a short message — the
|
|
30
|
+
renderer is no longer runnable standalone, it always renders real data.
|
|
31
|
+
"""
|
|
32
|
+
from __future__ import annotations
|
|
33
|
+
|
|
34
|
+
import argparse
|
|
35
|
+
import json
|
|
36
|
+
import os
|
|
37
|
+
import sys
|
|
38
|
+
|
|
39
|
+
_LIB_DIR = os.path.dirname(os.path.realpath(__file__))
|
|
40
|
+
if _LIB_DIR not in sys.path:
|
|
41
|
+
sys.path.insert(0, _LIB_DIR)
|
|
42
|
+
import roll_render
|
|
43
|
+
from roll_render import c, row, COLS
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def _divider(char: str = "─") -> None:
|
|
47
|
+
print(c("dim", char * min(COLS, 80)))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _op_marker(op: str) -> str:
|
|
51
|
+
if op == "+":
|
|
52
|
+
return c("green", "+", bold=True)
|
|
53
|
+
if op == "~":
|
|
54
|
+
return c("amber", "~", bold=True)
|
|
55
|
+
if op == "·":
|
|
56
|
+
return c("dim", "·")
|
|
57
|
+
if op == "✗":
|
|
58
|
+
return c("red", "✗", bold=True)
|
|
59
|
+
return c("dim", op)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _step_icon(status: str) -> str:
|
|
63
|
+
if status == "ok":
|
|
64
|
+
return c("green", "✓")
|
|
65
|
+
if status == "skip":
|
|
66
|
+
return c("amber", "↷")
|
|
67
|
+
if status == "fail":
|
|
68
|
+
return c("red", "✗", bold=True)
|
|
69
|
+
return c("dim", "·")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def _file_color(op: str) -> str:
|
|
73
|
+
if op == "+":
|
|
74
|
+
return "green"
|
|
75
|
+
if op == "~":
|
|
76
|
+
return "amber"
|
|
77
|
+
if op == "✗":
|
|
78
|
+
return "red"
|
|
79
|
+
return "dim"
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def render(payload: dict) -> None:
|
|
83
|
+
header_label = payload.get("header_label", "INIT")
|
|
84
|
+
subtitle = payload.get("subtitle", "项目初始化")
|
|
85
|
+
project_path = payload.get("project_path", "")
|
|
86
|
+
|
|
87
|
+
left = " " + c("blue", header_label, bold=True) + c("dim", " · ") + c("dim", subtitle)
|
|
88
|
+
right = c("dim", project_path) + " "
|
|
89
|
+
print(row(left, right))
|
|
90
|
+
_divider()
|
|
91
|
+
print()
|
|
92
|
+
|
|
93
|
+
for step in payload.get("steps", []):
|
|
94
|
+
num = c("dim", f" {step.get('num', 0)}.")
|
|
95
|
+
icon = _step_icon(step.get("status", "ok"))
|
|
96
|
+
label = step.get("label", "")
|
|
97
|
+
print(f"{num} {icon} {label}")
|
|
98
|
+
for entry in step.get("files", []) or []:
|
|
99
|
+
op, fname = entry[0], entry[1]
|
|
100
|
+
mark = _op_marker(op)
|
|
101
|
+
color = _file_color(op)
|
|
102
|
+
print(" " + mark + " " + c(color, fname))
|
|
103
|
+
note = step.get("note") or step.get("error")
|
|
104
|
+
if note:
|
|
105
|
+
tone = "red" if step.get("status") == "fail" else "dim"
|
|
106
|
+
print(" " + c(tone, str(note)))
|
|
107
|
+
|
|
108
|
+
print()
|
|
109
|
+
_divider()
|
|
110
|
+
|
|
111
|
+
footer = payload.get("footer") or {}
|
|
112
|
+
f_status = footer.get("status", "ok")
|
|
113
|
+
f_label = footer.get("label", "Done")
|
|
114
|
+
icon_color = "green" if f_status == "ok" else "red"
|
|
115
|
+
icon = "✓" if f_status == "ok" else "✗"
|
|
116
|
+
print(" " + c(icon_color, icon) + " " + c(icon_color, f_label, bold=True))
|
|
117
|
+
|
|
118
|
+
next_items = payload.get("next") or []
|
|
119
|
+
if next_items:
|
|
120
|
+
print()
|
|
121
|
+
print(" " + c("pink", "NEXT", bold=True) + c("dim", " · 下一步"))
|
|
122
|
+
for i, entry in enumerate(next_items, start=1):
|
|
123
|
+
label = entry[0]
|
|
124
|
+
hint = entry[1] if len(entry) > 1 else ""
|
|
125
|
+
num = c("dim", f" {i}.")
|
|
126
|
+
print(f"{num} {c('fg', label, bold=True)}")
|
|
127
|
+
if hint:
|
|
128
|
+
print(" " + c("dim", hint))
|
|
129
|
+
_divider("═")
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
def _read_payload() -> dict:
|
|
133
|
+
raw = sys.stdin.read()
|
|
134
|
+
if not raw.strip():
|
|
135
|
+
sys.stderr.write("roll-init.py: expected JSON on stdin\n")
|
|
136
|
+
sys.exit(1)
|
|
137
|
+
try:
|
|
138
|
+
return json.loads(raw)
|
|
139
|
+
except json.JSONDecodeError as exc:
|
|
140
|
+
sys.stderr.write(f"roll-init.py: invalid JSON on stdin: {exc}\n")
|
|
141
|
+
sys.exit(1)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def main() -> None:
|
|
145
|
+
ap = argparse.ArgumentParser(add_help=False)
|
|
146
|
+
ap.add_argument("--no-color", dest="no_color", action="store_true")
|
|
147
|
+
args, _ = ap.parse_known_args()
|
|
148
|
+
|
|
149
|
+
if args.no_color or os.environ.get("NO_COLOR") or not sys.stdout.isatty():
|
|
150
|
+
roll_render.USE_COLOR = False
|
|
151
|
+
|
|
152
|
+
render(_read_payload())
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
if __name__ == "__main__":
|
|
156
|
+
main()
|