@seanyao/roll 0.5.0 → 2.602.1
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 +717 -0
- package/LICENSE +21 -0
- package/README.md +65 -165
- package/bin/dream-test-quality-scan +110 -0
- package/bin/roll +14897 -815
- 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 +186 -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 +14 -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 +727 -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 +578 -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
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Roll i18n catalog — roll-loop skill user-facing strings (US-I18N-003).
|
|
3
|
+
_i18n_set en loop.cycle_start "Cycle %s started"
|
|
4
|
+
_i18n_set zh loop.cycle_start "Cycle %s 开始"
|
|
5
|
+
_i18n_set en loop.orphan_recovery "Orphan recovery: %s items reverted"
|
|
6
|
+
_i18n_set zh loop.orphan_recovery "孤儿恢复: %s 项已回退"
|
|
7
|
+
_i18n_set en loop.ci_precheck "Pre-run CI check"
|
|
8
|
+
_i18n_set zh loop.ci_precheck "启动前 CI 检查"
|
|
9
|
+
_i18n_set en loop.pr_inbox "PR inbox: %s open"
|
|
10
|
+
_i18n_set zh loop.pr_inbox "PR 收件箱: %s 个开放"
|
|
11
|
+
_i18n_set en loop.scanning_backlog "Scanning backlog..."
|
|
12
|
+
_i18n_set zh loop.scanning_backlog "扫描 backlog..."
|
|
13
|
+
_i18n_set en loop.picked_story "Picked: %s"
|
|
14
|
+
_i18n_set zh loop.picked_story "已选取: %s"
|
|
15
|
+
_i18n_set en loop.executing "Executing: %s"
|
|
16
|
+
_i18n_set zh loop.executing "执行中: %s"
|
|
17
|
+
_i18n_set en loop.story_done "Story complete: %s"
|
|
18
|
+
_i18n_set zh loop.story_done "故事完成: %s"
|
|
19
|
+
_i18n_set en loop.ci_waiting "Waiting for CI..."
|
|
20
|
+
_i18n_set zh loop.ci_waiting "等待 CI..."
|
|
21
|
+
_i18n_set en loop.ci_green "CI: green"
|
|
22
|
+
_i18n_set zh loop.ci_green "CI: 通过"
|
|
23
|
+
_i18n_set en loop.ci_red "CI: red"
|
|
24
|
+
_i18n_set zh loop.ci_red "CI: 失败"
|
|
25
|
+
_i18n_set en loop.cycle_complete "Cycle complete: %s built, %s skipped"
|
|
26
|
+
_i18n_set zh loop.cycle_complete "Cycle 完成: %s 个已构建, %s 个已跳过"
|
|
27
|
+
_i18n_set en loop.idle_exit "No Todo items — idle exit"
|
|
28
|
+
_i18n_set zh loop.idle_exit "无待办项 — 空闲退出"
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Roll i18n catalog — roll-onboard skill user-facing strings (US-I18N-003).
|
|
3
|
+
# These are the templates/questions shown to users by agents executing roll-onboard.
|
|
4
|
+
|
|
5
|
+
# ── Step 0-2: Setup ──
|
|
6
|
+
_i18n_set en onboard.welcome "Welcome to Roll Onboard"
|
|
7
|
+
_i18n_set zh onboard.welcome "欢迎使用 Roll Onboard"
|
|
8
|
+
_i18n_set en onboard.scanning "Scanning project..."
|
|
9
|
+
_i18n_set zh onboard.scanning "正在扫描项目..."
|
|
10
|
+
_i18n_set en onboard.stop_migrate_first "This project has legacy Roll structure (BACKLOG.md or docs/features/). Run 'roll migrate' first before onboarding."
|
|
11
|
+
_i18n_set zh onboard.stop_migrate_first "此项目还保留着旧版 Roll 结构(BACKLOG.md 或 docs/features/)。请先运行 'roll migrate' 再 onboard。"
|
|
12
|
+
|
|
13
|
+
# ── Step 3: Nine Questions ──
|
|
14
|
+
_i18n_set en onboard.questions_group1 "Group 1/3: Understanding your project"
|
|
15
|
+
_i18n_set zh onboard.questions_group1 "第 1/3 组: 理解你的项目"
|
|
16
|
+
_i18n_set en onboard.questions_group2 "Group 2/3: Defining scope"
|
|
17
|
+
_i18n_set zh onboard.questions_group2 "第 2/3 组: 定义范围"
|
|
18
|
+
_i18n_set en onboard.questions_group3 "Group 3/3: Privacy & preferences"
|
|
19
|
+
_i18n_set zh onboard.questions_group3 "第 3/3 组: 隐私与偏好"
|
|
20
|
+
_i18n_set en onboard.q1 "I see this is a %s project doing %s — correct?"
|
|
21
|
+
_i18n_set zh onboard.q1 "我看到这是一个 %s 项目,做的是 %s — 对吗?"
|
|
22
|
+
_i18n_set en onboard.q2 "The main business domains look like %s — anything to add or correct?"
|
|
23
|
+
_i18n_set zh onboard.q2 "主要业务领域看起来有 %s — 有需要补充或纠正的吗?"
|
|
24
|
+
_i18n_set en onboard.q3 "The key modules are %s — any missed or mis-identified?"
|
|
25
|
+
_i18n_set zh onboard.q3 "关键模块是 %s — 有遗漏或识别错误的吗?"
|
|
26
|
+
_i18n_set en onboard.q4 "Which artifacts should I generate?"
|
|
27
|
+
_i18n_set zh onboard.q4 "需要生成哪些产出物?"
|
|
28
|
+
|
|
29
|
+
# ── Step 4: Plan complete ──
|
|
30
|
+
_i18n_set en onboard.plan_written "Onboard plan written to .roll/onboard-plan.yaml"
|
|
31
|
+
_i18n_set zh onboard.plan_written "Onboard 计划已写入 .roll/onboard-plan.yaml"
|
|
32
|
+
_i18n_set en onboard.next_step "Next: run 'roll init --apply' to execute this plan"
|
|
33
|
+
_i18n_set zh onboard.next_step "下一步: 运行 'roll init --apply' 执行此计划"
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Roll i18n catalog — `roll skills` command (US-SKILL-016).
|
|
3
|
+
# Generated skills catalog: scan skills/*/SKILL.md frontmatter → guide/skills.md.
|
|
4
|
+
|
|
5
|
+
_i18n_set en skills.generated "Generated skill catalog: %s"
|
|
6
|
+
_i18n_set zh skills.generated "已生成技能清单:%s"
|
|
7
|
+
|
|
8
|
+
_i18n_set en skills.check_ok "Skill catalog is up to date."
|
|
9
|
+
_i18n_set zh skills.check_ok "技能清单已是最新。"
|
|
10
|
+
|
|
11
|
+
_i18n_set en skills.check_drift "Skill catalog drift: %s differs from a fresh scan. Run 'roll skills generate'."
|
|
12
|
+
_i18n_set zh skills.check_drift "技能清单漂移:%s 与最新扫描不一致。请运行 'roll skills generate'。"
|
|
13
|
+
|
|
14
|
+
_i18n_set en skills.check_missing "Skill catalog not found at %s. Run 'roll skills generate'."
|
|
15
|
+
_i18n_set zh skills.check_missing "未找到技能清单 %s。请运行 'roll skills generate'。"
|
|
16
|
+
|
|
17
|
+
_i18n_set en skills.unknown_sub "Unknown 'roll skills' subcommand: %s"
|
|
18
|
+
_i18n_set zh skills.unknown_sub "未知的 'roll skills' 子命令:%s"
|
|
19
|
+
|
|
20
|
+
_i18n_set en skills.usage "Usage: roll skills <generate|check>"
|
|
21
|
+
_i18n_set zh skills.usage "用法:roll skills <generate|check>"
|
|
22
|
+
|
|
23
|
+
_i18n_set en skills.doctor_heading "Skill catalog"
|
|
24
|
+
_i18n_set zh skills.doctor_heading "技能清单"
|
|
25
|
+
|
|
26
|
+
_i18n_set en skills.doctor_ok "✅ guide/skills.md matches skills/*/SKILL.md"
|
|
27
|
+
_i18n_set zh skills.doctor_ok "✅ guide/skills.md 与 skills/*/SKILL.md 一致"
|
|
28
|
+
|
|
29
|
+
_i18n_set en skills.doctor_drift "⚠️ guide/skills.md is stale — run 'roll skills generate'"
|
|
30
|
+
_i18n_set zh skills.doctor_drift "⚠️ guide/skills.md 已过期 — 请运行 'roll skills generate'"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en slides_build.unknown_option_1 "Unknown option: %s"
|
|
3
|
+
_i18n_set zh slides_build.unknown_option_1 "未知选项: %s"
|
|
4
|
+
_i18n_set en slides_build.unexpected_argument_1 "Unexpected argument: %s"
|
|
5
|
+
_i18n_set zh slides_build.unexpected_argument_1 "多余参数: %s"
|
|
6
|
+
_i18n_set en slides_build.slides_toolchain_missing_re_run_roll "Slides toolchain missing — re-run 'roll setup'"
|
|
7
|
+
_i18n_set zh slides_build.slides_toolchain_missing_re_run_roll "渲染工具缺失,请运行 roll setup"
|
|
8
|
+
_i18n_set en slides_build.deck_md " deck.md"
|
|
9
|
+
_i18n_set zh slides_build.deck_md "校验失败,请先修复上方提示再重试。"
|
|
10
|
+
_i18n_set en slides_build.template_not_found "Template not found: %s"
|
|
11
|
+
_i18n_set zh slides_build.template_not_found "未找到模板:%s"
|
|
12
|
+
_i18n_set en slides_build.render_failed_for "Render failed for %s"
|
|
13
|
+
_i18n_set zh slides_build.render_failed_for "渲染失败:%s"
|
|
14
|
+
_i18n_set en slides_build.rendered "Rendered → %s"
|
|
15
|
+
_i18n_set zh slides_build.rendered "渲染完成 → %s"
|
|
16
|
+
|
|
17
|
+
# US-DECK-012: build failure recovery paths
|
|
18
|
+
_i18n_set en slides_build.validation_failed_for "Validation failed for %s"
|
|
19
|
+
_i18n_set zh slides_build.validation_failed_for "校验失败:%s"
|
|
20
|
+
_i18n_set en slides_build.hint_fix_and_rerun "Hint: fix the issues above in %s and re-run 'roll slides build %s'"
|
|
21
|
+
_i18n_set zh slides_build.hint_fix_and_rerun "提示:请按上方提示修复 %s,然后重新运行 'roll slides build %s'"
|
|
22
|
+
_i18n_set en slides_build.available_templates "Available templates:"
|
|
23
|
+
_i18n_set zh slides_build.available_templates "可用模板:"
|
|
24
|
+
_i18n_set en slides_build.templates_list_hint "Hint: 'roll slides templates' lists all installed templates"
|
|
25
|
+
_i18n_set zh slides_build.templates_list_hint "提示:'roll slides templates' 列出所有已安装模板"
|
|
26
|
+
_i18n_set en slides_build.renderer_crashed_for "Renderer crashed for %s"
|
|
27
|
+
_i18n_set zh slides_build.renderer_crashed_for "渲染器崩溃:%s"
|
|
28
|
+
_i18n_set en slides_build.see_full_error_logs "See full error: roll slides logs %s"
|
|
29
|
+
_i18n_set zh slides_build.see_full_error_logs "查看完整错误:roll slides logs %s"
|
|
30
|
+
_i18n_set en slides_build.last_5_lines_of_renderer_output "Last 5 lines of renderer output:"
|
|
31
|
+
_i18n_set zh slides_build.last_5_lines_of_renderer_output "渲染器最后 5 行:"
|
|
32
|
+
|
|
33
|
+
_i18n_set en slides_build.usage_roll_slides_build_slug_no "Usage: roll slides build <slug> [--no-open]"
|
|
34
|
+
_i18n_set zh slides_build.usage_roll_slides_build_slug_no "用法: roll slides build <slug> [--no-open]"
|
|
35
|
+
_i18n_set en slides_build.en_deck "[EN: 未找到 deck 文件:%s...]"
|
|
36
|
+
_i18n_set zh slides_build.en_deck " 未找到 deck 文件:%s"
|
|
37
|
+
_i18n_set en slides_build.en_roll_slides_new "[EN: 提示:先运行 'roll slides new \"<主题>\"' 生成新的幻灯片。...]"
|
|
38
|
+
_i18n_set zh slides_build.en_roll_slides_new " 提示:先运行 'roll slides new \"<主题>\"' 生成新的幻灯片。"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en slides_delete.unknown_option_1 "Unknown option: %s"
|
|
3
|
+
_i18n_set zh slides_delete.unknown_option_1 "未知选项: %s"
|
|
4
|
+
_i18n_set en slides_delete.unexpected_argument_1 "Unexpected argument: %s"
|
|
5
|
+
_i18n_set zh slides_delete.unexpected_argument_1 "多余参数: %s"
|
|
6
|
+
_i18n_set en slides_delete.deck_not_found "Deck not found: %s"
|
|
7
|
+
_i18n_set zh slides_delete.deck_not_found "未找到幻灯片:%s"
|
|
8
|
+
_i18n_set en slides_delete.non_interactive_terminal_must_use_force "Non-interactive terminal: must use --force to delete"
|
|
9
|
+
_i18n_set zh slides_delete.non_interactive_terminal_must_use_force "非交互终端:需使用 --force 参数"
|
|
10
|
+
_i18n_set en slides_delete.cancelled "Cancelled"
|
|
11
|
+
_i18n_set zh slides_delete.cancelled "已取消"
|
|
12
|
+
_i18n_set en slides_delete.deleted "Deleted %s"
|
|
13
|
+
_i18n_set zh slides_delete.deleted "已删除 %s"
|
|
14
|
+
|
|
15
|
+
_i18n_set en slides_delete.usage_roll_slides_delete_slug_force "Usage: roll slides delete <slug> [--force]"
|
|
16
|
+
_i18n_set zh slides_delete.usage_roll_slides_delete_slug_force "用法: roll slides delete <slug> [--force]"
|
|
17
|
+
|
|
18
|
+
_i18n_set en slides_delete.prompt 'Delete deck "%s"? (y/N)'
|
|
19
|
+
_i18n_set zh slides_delete.prompt '删除幻灯片 "%s"?(y/N)'
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en slides_list.unknown_option_1 "Unknown option: %s"
|
|
3
|
+
_i18n_set zh slides_list.unknown_option_1 "未知选项: %s"
|
|
4
|
+
_i18n_set en slides_list.unexpected_argument_1 "Unexpected argument: %s"
|
|
5
|
+
_i18n_set zh slides_list.unexpected_argument_1 "多余参数: %s"
|
|
6
|
+
_i18n_set en slides_list.no_decks_found_under_roll_slides "No decks found under .roll/slides/"
|
|
7
|
+
_i18n_set zh slides_list.no_decks_found_under_roll_slides "无幻灯片"
|
|
8
|
+
_i18n_set en slides_list.no_decks_found_under_roll_slides_2 "No decks found under .roll/slides/"
|
|
9
|
+
_i18n_set zh slides_list.no_decks_found_under_roll_slides_2 "无幻灯片"
|
|
10
|
+
|
|
11
|
+
_i18n_set en slides_list.en_roll_slides_new "[EN: 提示:运行 'roll slides new \"<主题>\"' 创建第一个幻灯片。...]"
|
|
12
|
+
_i18n_set zh slides_list.en_roll_slides_new " 提示:运行 'roll slides new \"<主题>\"' 创建第一个幻灯片。"
|
|
13
|
+
_i18n_set en slides_list.en_roll_slides_new_2 "[EN: 提示:运行 'roll slides new \"<主题>\"' 创建第一个幻灯片。...]"
|
|
14
|
+
_i18n_set zh slides_list.en_roll_slides_new_2 " 提示:运行 'roll slides new \"<主题>\"' 创建第一个幻灯片。"
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en slides_logs.unknown_option_1 "Unknown option: %s"
|
|
3
|
+
_i18n_set zh slides_logs.unknown_option_1 "未知选项: %s"
|
|
4
|
+
_i18n_set en slides_logs.unexpected_argument_1 "Unexpected argument: %s"
|
|
5
|
+
_i18n_set zh slides_logs.unexpected_argument_1 "多余参数: %s"
|
|
6
|
+
_i18n_set en slides_logs.deck_not_found "Deck not found: %s"
|
|
7
|
+
_i18n_set zh slides_logs.deck_not_found "未找到幻灯片:%s"
|
|
8
|
+
_i18n_set en slides_logs.no_failure_records_for "No failure records for %s"
|
|
9
|
+
_i18n_set zh slides_logs.no_failure_records_for "该幻灯片没有失败记录"
|
|
10
|
+
|
|
11
|
+
_i18n_set en slides_logs.usage_roll_slides_logs_slug "Usage: roll slides logs <slug>"
|
|
12
|
+
_i18n_set zh slides_logs.usage_roll_slides_logs_slug "用法: roll slides logs <slug>"
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en slides_new.unknown_option_1 "Unknown option: %s"
|
|
3
|
+
_i18n_set zh slides_new.unknown_option_1 "未知选项: %s"
|
|
4
|
+
_i18n_set en slides_new.unexpected_argument_1 "Unexpected argument: %s"
|
|
5
|
+
_i18n_set zh slides_new.unexpected_argument_1 "多余参数: %s"
|
|
6
|
+
|
|
7
|
+
_i18n_set en slides_new.en_roll_slides_new_template "[EN: 用法:roll slides new \"<主题>\" [--template <模板名>] [...]"
|
|
8
|
+
_i18n_set zh slides_new.en_roll_slides_new_template " 用法:roll slides new \"<主题>\" [--template <模板名>] [--quiet] [--no-build]"
|
|
9
|
+
_i18n_set en slides_new.en_slug "[EN: 无法从主题派生 slug:%s...]"
|
|
10
|
+
_i18n_set zh slides_new.en_slug " 无法从主题派生 slug:%s"
|
|
11
|
+
_i18n_set en slides_new.en_roll_slides_build "[EN:下一步:roll slides build %s...]"
|
|
12
|
+
_i18n_set zh slides_new.en_roll_slides_build "下一步:roll slides build %s"
|
|
13
|
+
|
|
14
|
+
_i18n_set en slides_new.template_requires_value "--template requires a value"
|
|
15
|
+
_i18n_set zh slides_new.template_requires_value "--template 需要一个值"
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en slides_preview.unknown_option_1 "Unknown option: %s"
|
|
3
|
+
_i18n_set zh slides_preview.unknown_option_1 "未知选项: %s"
|
|
4
|
+
_i18n_set en slides_preview.unexpected_argument_1 "Unexpected argument: %s"
|
|
5
|
+
_i18n_set zh slides_preview.unexpected_argument_1 "多余参数: %s"
|
|
6
|
+
_i18n_set en slides_preview.preview "Preview → %s"
|
|
7
|
+
_i18n_set zh slides_preview.preview "打开预览 → %s"
|
|
8
|
+
|
|
9
|
+
_i18n_set en slides_preview.usage_roll_slides_preview_slug_no "Usage: roll slides preview <slug> [--no-open]"
|
|
10
|
+
_i18n_set zh slides_preview.usage_roll_slides_preview_slug_no "用法: roll slides preview <slug> [--no-open]"
|
|
11
|
+
_i18n_set en slides_preview.en_html "[EN: 未找到已渲染的 HTML:%s...]"
|
|
12
|
+
_i18n_set zh slides_preview.en_html " 未找到已渲染的 HTML:%s"
|
|
13
|
+
_i18n_set en slides_preview.en_roll_slides_build "[EN: 提示:先运行 'roll slides build %s' 渲染幻灯片。...]"
|
|
14
|
+
_i18n_set zh slides_preview.en_roll_slides_build " 提示:先运行 'roll slides build %s' 渲染幻灯片。"
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en slides_templates.unknown_option_1 "Unknown option: %s"
|
|
3
|
+
_i18n_set zh slides_templates.unknown_option_1 "未知选项: %s"
|
|
4
|
+
_i18n_set en slides_templates.unexpected_argument_1 "Unexpected argument: %s"
|
|
5
|
+
_i18n_set zh slides_templates.unexpected_argument_1 "多余参数: %s"
|
|
6
|
+
_i18n_set en slides_templates.no_templates_found "No templates found"
|
|
7
|
+
_i18n_set zh slides_templates.no_templates_found "无可用模板"
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
|
|
2
|
+
_i18n_set en status.loop_overview "%sLoop Overview:"
|
|
3
|
+
_i18n_set zh status.loop_overview "所有项目 loop 状态%s"
|
|
4
|
+
_i18n_set en status.not_synced " %s-%s %s: %s (not synced /"
|
|
5
|
+
_i18n_set zh status.not_synced "未同步)"
|
|
6
|
+
_i18n_set en status.out_of_sync_roll_md_missing " %s~%s %s: %s (out of sync — roll.md missing / roll.md"
|
|
7
|
+
_i18n_set zh status.out_of_sync_roll_md_missing "缺失)"
|
|
8
|
+
_i18n_set en status.out_of_sync_roll_md_outdated " %s~%s %s: %s (out of sync — roll.md outdated / roll.md"
|
|
9
|
+
_i18n_set zh status.out_of_sync_roll_md_outdated "已过期)"
|
|
10
|
+
_i18n_set en status.out_of_sync_roll_md_not " %s~%s %s: %s (out of sync — @roll.md not in config /"
|
|
11
|
+
_i18n_set zh status.out_of_sync_roll_md_not "未包含 @roll.md)"
|
|
12
|
+
_i18n_set en status.in_sync " %s=%s %s: %s (in sync /"
|
|
13
|
+
_i18n_set zh status.in_sync "已同步)"
|
|
14
|
+
_i18n_set en status.peer_call_timeout_s_peer "Peer call timeout: %ss Peer"
|
|
15
|
+
_i18n_set zh status.peer_call_timeout_s_peer "调用超时: %ss"
|
|
16
|
+
_i18n_set en status.peer_call_timeout_killed "Peer %s killed after %ss wall-clock budget (FIX-150c)"
|
|
17
|
+
_i18n_set zh status.peer_call_timeout_killed "Peer %s 超过 %ss 上限,已强制终止 (FIX-150c)"
|
|
18
|
+
_i18n_set en status.unsupported_peer "Unsupported peer: %s"
|
|
19
|
+
_i18n_set zh status.unsupported_peer "不支持的 peer: %s"
|
|
20
|
+
_i18n_set en status.unsupported_peer_2 "Unsupported peer: %s"
|
|
21
|
+
_i18n_set zh status.unsupported_peer_2 "不支持的 peer: %s"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Roll i18n catalog — update command (US-I18N-002).
|
|
3
|
+
|
|
4
|
+
_i18n_set en update.version_mismatch "Version mismatch: installed %s, expected %s — CDN propagation lag, clearing cache and retrying..."
|
|
5
|
+
_i18n_set zh update.version_mismatch "版本不一致(已安装 %s,期望 %s),疑似 CDN 未同步,清理缓存后重试..."
|
|
6
|
+
_i18n_set en update.still_mismatch "Still on %s after retry — registry may not have propagated yet, try again in a minute."
|
|
7
|
+
_i18n_set zh update.still_mismatch "重试后仍为 %s,注册表可能尚未同步,请稍后再试。"
|
|
8
|
+
_i18n_set en update.current_version "Current version: roll v%s"
|
|
9
|
+
_i18n_set zh update.current_version "当前版本: roll v%s"
|
|
10
|
+
|
|
11
|
+
_i18n_set en update.upgrading_via_npm "Upgrading via npm..."
|
|
12
|
+
_i18n_set zh update.upgrading_via_npm "正在通过 npm 升级..."
|
|
13
|
+
_i18n_set en update.upgrading_via_curl "Upgrading via curl..."
|
|
14
|
+
_i18n_set zh update.upgrading_via_curl "正在通过 curl 升级..."
|
|
15
|
+
_i18n_set en update.npm_install_failed_check_network_proxy "npm install failed. Check network/proxy and try again."
|
|
16
|
+
_i18n_set zh update.npm_install_failed_check_network_proxy "安装失败,请检查网络/代理后重试。"
|
|
17
|
+
_i18n_set en update.curl_download_failed "Download failed. Check network/proxy and try again."
|
|
18
|
+
_i18n_set zh update.curl_download_failed "下载失败,请检查网络/代理后重试。"
|
|
19
|
+
_i18n_set en update.curl_extract_failed "Extraction failed. The downloaded archive may be corrupted."
|
|
20
|
+
_i18n_set zh update.curl_extract_failed "解压失败,下载的归档可能已损坏。"
|
|
21
|
+
_i18n_set en update.new_version "Upgraded to roll v%s"
|
|
22
|
+
_i18n_set zh update.new_version "已升级到 roll v%s"
|
|
23
|
+
_i18n_set en update.re_syncing_to_ai_tools "Re-syncing to AI tools..."
|
|
24
|
+
_i18n_set zh update.re_syncing_to_ai_tools "正在重新同步到 AI 工具..."
|
package/lib/i18n.sh
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Roll i18n engine — US-I18N-001.
|
|
3
|
+
#
|
|
4
|
+
# Provides:
|
|
5
|
+
# _i18n_resolve_lang — resolve user's language per precedence
|
|
6
|
+
# msg <key> [args...] — look up message catalog with EN fallback
|
|
7
|
+
# _i18n_set <lang> <key> <value> — fill the catalog (used by modules)
|
|
8
|
+
#
|
|
9
|
+
# Storage is bash 3.2-compatible (macOS default ships 3.2): each catalog entry
|
|
10
|
+
# is held in a plain variable named `MSG_<LANG>_<key>`, looked up via indirect
|
|
11
|
+
# reference. Bash 4 assoc arrays would be cleaner but break macOS default bash
|
|
12
|
+
# (see AGENTS.md §4: single bash script, no runtime).
|
|
13
|
+
#
|
|
14
|
+
# Precedence: ROLL_LANG env > ~/.roll/config.yaml `lang` > LC_ALL > LANG
|
|
15
|
+
# > (macOS) AppleLanguages > 'en'.
|
|
16
|
+
# Decision: value starting with `zh` → "zh", everything else → "en".
|
|
17
|
+
|
|
18
|
+
# Fill the catalog. Modules call this at source-time:
|
|
19
|
+
# _i18n_set en hello "Hello, %s!"
|
|
20
|
+
# _i18n_set zh hello "你好,%s!"
|
|
21
|
+
# No subshell forks: lang uppercasing uses a case statement (bash 3.2-safe;
|
|
22
|
+
# ${var^^} requires bash 4+), key sanitization uses inline param-expansion.
|
|
23
|
+
_i18n_set() {
|
|
24
|
+
local lang="$1" key="$2" val="$3"
|
|
25
|
+
local upper safe varname
|
|
26
|
+
case "$lang" in
|
|
27
|
+
en|EN) upper=EN ;;
|
|
28
|
+
zh|ZH) upper=ZH ;;
|
|
29
|
+
*) upper="$(printf '%s' "$lang" | tr '[:lower:]' '[:upper:]')" ;;
|
|
30
|
+
esac
|
|
31
|
+
safe="${key//[^A-Za-z0-9_]/_}" # inline param-expansion — no subshell fork
|
|
32
|
+
varname="MSG_${upper}_${safe}"
|
|
33
|
+
printf -v "$varname" '%s' "$val"
|
|
34
|
+
export "$varname"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Decide "zh" or "en" from a free-form locale string.
|
|
38
|
+
_i18n_classify() {
|
|
39
|
+
case "${1:-}" in
|
|
40
|
+
zh*) echo zh ;;
|
|
41
|
+
*) echo en ;;
|
|
42
|
+
esac
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
# Resolve the active language. Caches in ROLL_LANG_RESOLVED so later calls are
|
|
46
|
+
# free.
|
|
47
|
+
_i18n_resolve_lang() {
|
|
48
|
+
if [[ -n "${ROLL_LANG_RESOLVED:-}" ]]; then
|
|
49
|
+
echo "$ROLL_LANG_RESOLVED"
|
|
50
|
+
return
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
local lang=""
|
|
54
|
+
|
|
55
|
+
if [[ -n "${ROLL_LANG:-}" ]]; then
|
|
56
|
+
lang=$(_i18n_classify "$ROLL_LANG")
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
if [[ -z "$lang" && -n "${ROLL_CONFIG:-}" && -f "${ROLL_CONFIG}" ]]; then
|
|
60
|
+
local cfg
|
|
61
|
+
cfg=$(grep -E '^lang:' "$ROLL_CONFIG" 2>/dev/null | head -1 \
|
|
62
|
+
| sed 's/^lang:[[:space:]]*//' \
|
|
63
|
+
| sed 's/[[:space:]]*#.*$//' \
|
|
64
|
+
| sed 's/[[:space:]]*$//')
|
|
65
|
+
[[ -n "$cfg" ]] && lang=$(_i18n_classify "$cfg")
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
if [[ -z "$lang" && -n "${LC_ALL:-}" ]]; then
|
|
69
|
+
lang=$(_i18n_classify "$LC_ALL")
|
|
70
|
+
fi
|
|
71
|
+
|
|
72
|
+
if [[ -z "$lang" && -n "${LANG:-}" ]]; then
|
|
73
|
+
lang=$(_i18n_classify "$LANG")
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
if [[ -z "$lang" ]] && command -v defaults >/dev/null 2>&1; then
|
|
77
|
+
local apple
|
|
78
|
+
apple=$(defaults read -g AppleLanguages 2>/dev/null | head -2 | tail -1 \
|
|
79
|
+
| tr -d ' ",()' | head -1 || true)
|
|
80
|
+
[[ -n "$apple" ]] && lang=$(_i18n_classify "$apple")
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
[[ -z "$lang" ]] && lang="en"
|
|
84
|
+
|
|
85
|
+
ROLL_LANG_RESOLVED="$lang"
|
|
86
|
+
echo "$lang"
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Look up message catalog entry. Falls back to EN, then to the key itself so
|
|
90
|
+
# missing translations stay visible without crashing the caller.
|
|
91
|
+
msg() {
|
|
92
|
+
local key="$1"; shift || true
|
|
93
|
+
local lang safe
|
|
94
|
+
# FIX: avoid subshell forks — check cached value first, inline key sanitize
|
|
95
|
+
if [[ -n "${ROLL_LANG_RESOLVED:-}" ]]; then
|
|
96
|
+
lang="$ROLL_LANG_RESOLVED"
|
|
97
|
+
else
|
|
98
|
+
lang=$(_i18n_resolve_lang)
|
|
99
|
+
fi
|
|
100
|
+
safe="${key//[^A-Za-z0-9_]/_}" # FIX: inline — no subshell fork
|
|
101
|
+
|
|
102
|
+
local zh_var="MSG_ZH_${safe}"
|
|
103
|
+
local en_var="MSG_EN_${safe}"
|
|
104
|
+
local tmpl=""
|
|
105
|
+
|
|
106
|
+
if [[ "$lang" == "zh" && -n "${!zh_var:-}" ]]; then
|
|
107
|
+
tmpl="${!zh_var}"
|
|
108
|
+
elif [[ -n "${!en_var:-}" ]]; then
|
|
109
|
+
tmpl="${!en_var}"
|
|
110
|
+
else
|
|
111
|
+
tmpl="$key"
|
|
112
|
+
fi
|
|
113
|
+
|
|
114
|
+
# shellcheck disable=SC2059 — template comes from our own catalog
|
|
115
|
+
printf "$tmpl" "$@"
|
|
116
|
+
echo
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
# Look up message catalog entry with an explicit language, bypassing ROLL_LANG env.
|
|
120
|
+
# Usage: msg_lang <lang> <key> [printf-args...]
|
|
121
|
+
# Useful when the caller tracks language independently of the process env (e.g.
|
|
122
|
+
# _loop_schedule_desc passes an explicit lang= parameter).
|
|
123
|
+
msg_lang() {
|
|
124
|
+
local lang="$1" key="$2"; shift 2 || true
|
|
125
|
+
local upper safe varname tmpl
|
|
126
|
+
case "$lang" in
|
|
127
|
+
en|EN) upper=EN ;;
|
|
128
|
+
zh|ZH) upper=ZH ;;
|
|
129
|
+
*) upper="$(printf '%s' "$lang" | tr '[:lower:]' '[:upper:]')" ;;
|
|
130
|
+
esac
|
|
131
|
+
safe="${key//[^A-Za-z0-9_]/_}"
|
|
132
|
+
varname="MSG_${upper}_${safe}"
|
|
133
|
+
tmpl="${!varname:-}"
|
|
134
|
+
if [[ -z "$tmpl" ]]; then
|
|
135
|
+
varname="MSG_EN_${safe}"
|
|
136
|
+
tmpl="${!varname:-$key}"
|
|
137
|
+
fi
|
|
138
|
+
# shellcheck disable=SC2059 — template comes from our own catalog
|
|
139
|
+
printf "$tmpl" "$@"
|
|
140
|
+
echo
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
# ── CJK display-width helpers (US-I18N-006) ──────────────────────────────
|
|
144
|
+
# Compute visual display width of a string (CJK fullwidth = 2 cells,
|
|
145
|
+
# ASCII = 1 cell). Delegates to python3 which is already a dependency.
|
|
146
|
+
_strw() {
|
|
147
|
+
python3 -c "
|
|
148
|
+
import sys
|
|
149
|
+
from unicodedata import east_asian_width
|
|
150
|
+
s = sys.argv[1]
|
|
151
|
+
w = sum(2 if east_asian_width(c) in ('F','W') else 1 for c in s)
|
|
152
|
+
print(w)
|
|
153
|
+
" "$1"
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# Left-pad a string to a target visual display width (CJK-aware).
|
|
157
|
+
_pad_l() {
|
|
158
|
+
local s="$1" target="$2"
|
|
159
|
+
local sw
|
|
160
|
+
sw=$(_strw "$s")
|
|
161
|
+
local pad=$((target - sw))
|
|
162
|
+
if ((pad <= 0)); then
|
|
163
|
+
printf '%s' "$s"
|
|
164
|
+
else
|
|
165
|
+
printf '%s%*s' "$s" "$pad" ''
|
|
166
|
+
fi
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
# Right-pad a string to a target visual display width (CJK-aware).
|
|
170
|
+
_pad_r() {
|
|
171
|
+
local s="$1" target="$2"
|
|
172
|
+
local sw
|
|
173
|
+
sw=$(_strw "$s")
|
|
174
|
+
local pad=$((target - sw))
|
|
175
|
+
if ((pad <= 0)); then
|
|
176
|
+
printf '%s' "$s"
|
|
177
|
+
else
|
|
178
|
+
printf '%*s%s' "$pad" '' "$s"
|
|
179
|
+
fi
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
# ── Load per-command message catalogs (US-I18N-002) ──
|
|
183
|
+
# Source all lib/i18n/*.sh files (skip self). Called once at bin/roll startup.
|
|
184
|
+
_i18n_load_catalogs() {
|
|
185
|
+
# FIX: guard — skip re-load when catalogs already loaded in this shell.
|
|
186
|
+
# Each bats test sources bin/roll in its own subshell so the guard resets
|
|
187
|
+
# automatically; but within a single shell (e.g. integration tests) this
|
|
188
|
+
# prevents 2.6s of catalog I/O on every subsequent source.
|
|
189
|
+
[[ -n "${_I18N_CATALOGS_LOADED:-}" ]] && return 0
|
|
190
|
+
local i18n_dir
|
|
191
|
+
i18n_dir="$(dirname "${BASH_SOURCE[0]:-$0}")/i18n"
|
|
192
|
+
if [[ -d "$i18n_dir" ]]; then
|
|
193
|
+
local f
|
|
194
|
+
# Load per-command catalogs
|
|
195
|
+
for f in "$i18n_dir"/*.sh; do
|
|
196
|
+
[[ -f "$f" ]] || continue
|
|
197
|
+
# shellcheck source=/dev/null
|
|
198
|
+
source "$f"
|
|
199
|
+
done
|
|
200
|
+
# Load skill catalogs (US-I18N-003)
|
|
201
|
+
if [[ -d "$i18n_dir/skills" ]]; then
|
|
202
|
+
for f in "$i18n_dir/skills"/*.sh; do
|
|
203
|
+
[[ -f "$f" ]] || continue
|
|
204
|
+
# shellcheck source=/dev/null
|
|
205
|
+
source "$f"
|
|
206
|
+
done
|
|
207
|
+
fi
|
|
208
|
+
fi
|
|
209
|
+
_I18N_CATALOGS_LOADED=1
|
|
210
|
+
}
|
|
211
|
+
_i18n_load_catalogs
|