@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.
Files changed (181) hide show
  1. package/CHANGELOG.md +717 -0
  2. package/LICENSE +21 -0
  3. package/README.md +65 -165
  4. package/bin/dream-test-quality-scan +110 -0
  5. package/bin/roll +14897 -815
  6. package/conventions/config.yaml +17 -1
  7. package/conventions/global/AGENTS.md +146 -100
  8. package/conventions/global/CLAUDE.md +1 -21
  9. package/conventions/global/GEMINI.md +8 -22
  10. package/conventions/global/project_rules.md +9 -0
  11. package/conventions/templates/backend-service/AGENTS.md +30 -81
  12. package/conventions/templates/backend-service/GEMINI.md +3 -3
  13. package/conventions/templates/backend-service/project_rules.md +16 -0
  14. package/conventions/templates/cli/AGENTS.md +31 -58
  15. package/conventions/templates/cli/CLAUDE.md +3 -5
  16. package/conventions/templates/cli/GEMINI.md +3 -3
  17. package/conventions/templates/cli/project_rules.md +16 -0
  18. package/conventions/templates/frontend-only/AGENTS.md +29 -64
  19. package/conventions/templates/frontend-only/GEMINI.md +3 -3
  20. package/conventions/templates/frontend-only/project_rules.md +14 -0
  21. package/conventions/templates/fullstack/AGENTS.md +31 -79
  22. package/conventions/templates/fullstack/CLAUDE.md +1 -1
  23. package/conventions/templates/fullstack/GEMINI.md +3 -3
  24. package/conventions/templates/fullstack/project_rules.md +15 -0
  25. package/lib/README.md +42 -0
  26. package/lib/__pycache__/github_sync.cpython-314.pyc +0 -0
  27. package/lib/__pycache__/loop-fmt.cpython-314.pyc +0 -0
  28. package/lib/__pycache__/loop_result_eval.cpython-314.pyc +0 -0
  29. package/lib/__pycache__/loop_unstick.cpython-314.pyc +0 -0
  30. package/lib/__pycache__/model_prices.cpython-314.pyc +0 -0
  31. package/lib/__pycache__/prices_fetcher.cpython-314.pyc +0 -0
  32. package/lib/__pycache__/roll-home.cpython-314.pyc +0 -0
  33. package/lib/__pycache__/roll-loop-status.cpython-314.pyc +0 -0
  34. package/lib/__pycache__/roll_git.cpython-314.pyc +0 -0
  35. package/lib/__pycache__/roll_render.cpython-314.pyc +0 -0
  36. package/lib/__pycache__/slides-render.cpython-314.pyc +0 -0
  37. package/lib/agent_usage/README.md +49 -0
  38. package/lib/agent_usage/__init__.py +108 -0
  39. package/lib/agent_usage/__pycache__/__init__.cpython-314.pyc +0 -0
  40. package/lib/agent_usage/__pycache__/gemini.cpython-314.pyc +0 -0
  41. package/lib/agent_usage/__pycache__/kimi.cpython-314.pyc +0 -0
  42. package/lib/agent_usage/__pycache__/openai.cpython-314.pyc +0 -0
  43. package/lib/agent_usage/__pycache__/pi.cpython-314.pyc +0 -0
  44. package/lib/agent_usage/__pycache__/pi_emit.cpython-314.pyc +0 -0
  45. package/lib/agent_usage/__pycache__/qwen.cpython-314.pyc +0 -0
  46. package/lib/agent_usage/gemini.py +127 -0
  47. package/lib/agent_usage/kimi.py +278 -0
  48. package/lib/agent_usage/kimi_emit.py +123 -0
  49. package/lib/agent_usage/openai.py +126 -0
  50. package/lib/agent_usage/pi.py +200 -0
  51. package/lib/agent_usage/pi_emit.py +135 -0
  52. package/lib/agent_usage/qwen.py +128 -0
  53. package/lib/backfill-pi-usage.py +243 -0
  54. package/lib/changelog_audit.py +155 -0
  55. package/lib/changelog_generate.py +263 -0
  56. package/lib/context_feed_budget.sh +194 -0
  57. package/lib/github_sync.py +876 -0
  58. package/lib/i18n/README.md +54 -0
  59. package/lib/i18n/agent.sh +75 -0
  60. package/lib/i18n/alert.sh +20 -0
  61. package/lib/i18n/backlog.sh +96 -0
  62. package/lib/i18n/brief.sh +5 -0
  63. package/lib/i18n/changelog.sh +5 -0
  64. package/lib/i18n/ci.sh +15 -0
  65. package/lib/i18n/debug.sh +0 -0
  66. package/lib/i18n/doctor.sh +44 -0
  67. package/lib/i18n/dream.sh +0 -0
  68. package/lib/i18n/init.sh +91 -0
  69. package/lib/i18n/lang.sh +10 -0
  70. package/lib/i18n/loop.sh +140 -0
  71. package/lib/i18n/migrate.sh +74 -0
  72. package/lib/i18n/offboard.sh +31 -0
  73. package/lib/i18n/onboard.sh +0 -0
  74. package/lib/i18n/peer.sh +41 -0
  75. package/lib/i18n/peer_help.sh +25 -0
  76. package/lib/i18n/peer_reset.sh +7 -0
  77. package/lib/i18n/peer_status.sh +5 -0
  78. package/lib/i18n/prices.sh +3 -0
  79. package/lib/i18n/prices_refresh.sh +17 -0
  80. package/lib/i18n/prices_show.sh +7 -0
  81. package/lib/i18n/propose.sh +0 -0
  82. package/lib/i18n/release.sh +0 -0
  83. package/lib/i18n/research.sh +0 -0
  84. package/lib/i18n/review_pr.sh +0 -0
  85. package/lib/i18n/sentinel.sh +0 -0
  86. package/lib/i18n/setup.sh +3 -0
  87. package/lib/i18n/shared.sh +157 -0
  88. package/lib/i18n/skills/roll-brief.sh +47 -0
  89. package/lib/i18n/skills/roll-build.sh +97 -0
  90. package/lib/i18n/skills/roll-design.sh +18 -0
  91. package/lib/i18n/skills/roll-fix.sh +53 -0
  92. package/lib/i18n/skills/roll-loop.sh +28 -0
  93. package/lib/i18n/skills/roll-onboard.sh +33 -0
  94. package/lib/i18n/skills_catalog.sh +30 -0
  95. package/lib/i18n/slides.sh +3 -0
  96. package/lib/i18n/slides_build.sh +38 -0
  97. package/lib/i18n/slides_delete.sh +19 -0
  98. package/lib/i18n/slides_list.sh +14 -0
  99. package/lib/i18n/slides_logs.sh +12 -0
  100. package/lib/i18n/slides_new.sh +15 -0
  101. package/lib/i18n/slides_preview.sh +14 -0
  102. package/lib/i18n/slides_templates.sh +7 -0
  103. package/lib/i18n/status.sh +21 -0
  104. package/lib/i18n/update.sh +24 -0
  105. package/lib/i18n.sh +211 -0
  106. package/lib/loop-exit-summary.py +393 -0
  107. package/lib/loop-fmt.py +589 -0
  108. package/lib/loop_pick_agent.py +316 -0
  109. package/lib/loop_result_eval.py +469 -0
  110. package/lib/loop_unstick.py +180 -0
  111. package/lib/model_prices.py +186 -0
  112. package/lib/prices/README.md +35 -0
  113. package/lib/prices/snapshot-2026-05-22.json +22 -0
  114. package/lib/prices/snapshot-2026-05-23-deepseek.json +15 -0
  115. package/lib/prices/snapshot-2026-05-23-kimi.json +14 -0
  116. package/lib/prices_fetcher.py +285 -0
  117. package/lib/roll-backlog.py +225 -0
  118. package/lib/roll-brief.py +286 -0
  119. package/lib/roll-help.py +158 -0
  120. package/lib/roll-home.py +556 -0
  121. package/lib/roll-init.py +156 -0
  122. package/lib/roll-loop-status.py +1683 -0
  123. package/lib/roll-loop-story.py +191 -0
  124. package/lib/roll-onboard-render.py +378 -0
  125. package/lib/roll-peer.py +252 -0
  126. package/lib/roll-plan-validate.py +386 -0
  127. package/lib/roll-setup.py +102 -0
  128. package/lib/roll-status.py +367 -0
  129. package/lib/roll_git.py +41 -0
  130. package/lib/roll_render.py +414 -0
  131. package/lib/slides/components/README.md +123 -0
  132. package/lib/slides/components/cards-2.html +9 -0
  133. package/lib/slides/components/cards-3.html +9 -0
  134. package/lib/slides/components/cards-4.html +9 -0
  135. package/lib/slides/components/compare.html +22 -0
  136. package/lib/slides/components/highlight.html +9 -0
  137. package/lib/slides/components/pipeline.html +12 -0
  138. package/lib/slides/components/plain.html +7 -0
  139. package/lib/slides/components/quote.html +4 -0
  140. package/lib/slides/components/timeline.html +9 -0
  141. package/lib/slides/templates/introduction-v3.html +571 -0
  142. package/lib/slides/templates/pitch.html +0 -0
  143. package/lib/slides-render.py +778 -0
  144. package/lib/slides-validate.py +357 -0
  145. package/lib/test_quality_gate.py +143 -0
  146. package/package.json +8 -7
  147. package/skills/roll-.changelog/SKILL.md +406 -33
  148. package/skills/roll-.clarify/SKILL.md +5 -2
  149. package/skills/roll-.dream/SKILL.md +374 -0
  150. package/skills/roll-.echo/SKILL.md +5 -2
  151. package/skills/roll-.qa/SKILL.md +57 -3
  152. package/skills/roll-.review/SKILL.md +42 -3
  153. package/skills/roll-brief/SKILL.md +209 -0
  154. package/skills/roll-build/SKILL.md +308 -63
  155. package/skills/roll-debug/SKILL.md +341 -162
  156. package/skills/roll-debug/injectable-bb.js +263 -0
  157. package/skills/roll-deck/SKILL.md +296 -0
  158. package/skills/roll-design/ENGINEERING_CHECKLIST.md +1 -1
  159. package/skills/roll-design/SKILL.md +727 -94
  160. package/skills/roll-doc/SKILL.md +595 -0
  161. package/skills/roll-doctor/SKILL.md +192 -0
  162. package/skills/roll-fix/SKILL.md +149 -32
  163. package/skills/{roll-jot → roll-idea}/SKILL.md +18 -10
  164. package/skills/roll-loop/SKILL.md +578 -0
  165. package/skills/roll-notes/SKILL.md +103 -0
  166. package/skills/roll-onboard/SKILL.md +234 -0
  167. package/skills/roll-peer/SKILL.md +336 -0
  168. package/skills/roll-propose/SKILL.md +157 -0
  169. package/skills/roll-review-pr/SKILL.md +58 -0
  170. package/skills/roll-sentinel/SKILL.md +11 -2
  171. package/skills/roll-spar/SKILL.md +8 -6
  172. package/template/.github/workflows/ci.yml +5 -2
  173. package/template/AGENTS.md +20 -74
  174. package/skills/roll-research/SKILL.md +0 -307
  175. package/skills/roll-research/references/schema.json +0 -162
  176. package/skills/roll-research/scripts/md_to_pdf.py +0 -289
  177. package/tools/roll-fetch/SKILL.md +0 -182
  178. package/tools/roll-fetch/package.json +0 -15
  179. package/tools/roll-fetch/smart-web-fetch.js +0 -558
  180. package/tools/roll-probe/SKILL.md +0 -84
  181. /package/template/{BACKLOG.md → .roll/backlog.md} +0 -0
@@ -1,15 +1,20 @@
1
1
  ---
2
2
  name: roll-debug
3
- description: Universal web debugger. Collects diagnostics (console/network/DOM) via Playwright, analyzes root causes, and suggests fixes. Works with or without Black Box (BB) integration.
3
+ license: MIT
4
+ allowed-tools: "Read, Edit, Write, Bash, Agent"
5
+ description: Universal web debugger. Mounts a Black Box (BB) diagnostic probe on any page, collects rich diagnostics, analyzes root causes, and auto-fixes when the root cause is in project source. Cleans up after itself.
4
6
  ---
5
7
 
6
8
  # Roll Debug
7
9
 
8
- Universal web debugging tool that combines diagnostic collection and analysis into a single workflow: **Diagnose → Analyze → Suggest Fix**.
10
+ Web debugging tool that treats the **Black Box (BB) as a diagnostic probe** — mounted when needed, unmounted when done. Combines diagnostic collection, analysis, and auto-repair into a single workflow: **MountCollect → Analyze → Unmount → Auto-Fix (when fixable) → Re-verify**.
9
11
 
10
- Two collection modes:
11
- - **Native BB Mode**: Page has Black Box integrated; click button to collect rich diagnostic data
12
- - **Universal Diagnostic Mode**: Page has no BB; use Playwright to directly collect console/network/DOM/screenshot data
12
+ ## Philosophy
13
+
14
+ - BB is a **diagnostic probe**, not a product feature. Pages do not need to integrate BB natively.
15
+ - For any web diagnosis, **mount BB first** (unless already present).
16
+ - The entire lifecycle is **explicit and visible**: you see when BB mounts, when it collects, and when it unmounts.
17
+ - A visible **BB button** appears on the page during diagnosis so you always know the probe is active.
13
18
 
14
19
  ## When to Use
15
20
 
@@ -21,20 +26,26 @@ Two collection modes:
21
26
  - "Analyze BB data", "look at the diagnostic file"
22
27
  - Any scenario requiring web page diagnosis
23
28
 
29
+ ## When Not to Use
30
+
31
+ - Non-web environments (CLI tools, backend-only services) — outside this skill's scope
32
+ - Scheduled production sampling / acceptance checks (use `$roll-sentinel`)
33
+ - Pure source-reading without runtime reproduction
34
+
24
35
  ## Quick Start
25
36
 
26
37
  ```bash
27
- # Full workflow: collect + analyze + suggest fix (recommended)
38
+ # Full workflow: mount + collect + analyze + unmount (recommended)
28
39
  $roll-debug https://example.com/page
29
40
 
30
41
  # Collect data only, skip analysis
31
42
  $roll-debug https://example.com/page --no-analyze
32
43
 
33
- # Force universal diagnostic mode (no BB)
44
+ # Skip BB mount, use built-in universal collector
34
45
  $roll-debug https://example.com/page --universal
35
46
 
36
- # Collect + analyze + auto-fix
37
- $roll-debug https://example.com/page --fix
47
+ # Use a custom BB SDK instead of the built-in stub
48
+ $roll-debug https://example.com/page --bb-sdk-url https://cdn.example.com/bb.js
38
49
 
39
50
  # Analyze an existing report file (skip collection)
40
51
  $roll-debug --report /tmp/bb-report.json
@@ -44,44 +55,21 @@ $roll-debug https://site.com/page1,https://site.com/page2
44
55
  $roll-debug --file urls.txt
45
56
  ```
46
57
 
47
- ## Two Collection Modes
48
-
49
- ### Mode 1: Native BB (Page has Black Box integrated)
50
-
51
- ```
52
- Page with BB → Playwright clicks BB button → Download diagnostic JSON
53
- ```
54
-
55
- Requirements:
56
- - Page has `[data-testid="bb-toggle"]` button
57
- - Or exposes `window.__BB_DATA__`
58
- - Or stores data in `localStorage.bb_diagnostic`
59
-
60
- ### Mode 2: Universal Diagnostic (No BB required)
61
-
62
- ```
63
- Any page → Playwright injects collector → Gather console/network/DOM/screenshot
64
- ```
65
-
66
- Collects:
67
- - Console logs (error/warn/info)
68
- - Network requests (failed XHR/fetch, slow requests)
69
- - DOM state (key elements visibility, HTML length)
70
- - Screenshot (full page + viewport)
71
- - Performance metrics (load time, FCP, LCP, render blocking)
72
- - JavaScript errors with stack traces
73
-
74
- ## Full Workflow
58
+ ## BB Probe Lifecycle
75
59
 
76
60
  ```
77
61
  User: "Debug the page"
78
62
 
79
63
 
80
64
  ┌─────────────────────────────────────┐
81
- │ 1. Auto-detect collection mode
82
- │ ├── Try BB button found?
83
- │ ├── Try window.__BB_DATA__?
84
- │ └── Fallback to Universal
65
+ │ 1. Mount BB Probe
66
+ │ ├── Check: page already has BB?
67
+ ├── Yes → reuse existing
68
+ └── No → inject BB
69
+ │ │ ├── Built-in stub (default)
70
+ │ │ └── Custom SDK (--bb-sdk-url)
71
+ │ ├── Wait for initialization │
72
+ │ └── BB button appears on page │
85
73
  └──────────────────┬──────────────────┘
86
74
 
87
75
 
@@ -90,6 +78,7 @@ User: "Debug the page"
90
78
  │ ├── Console logs │
91
79
  │ ├── Network requests │
92
80
  │ ├── DOM state │
81
+ │ ├── Performance metrics │
93
82
  │ └── Screenshot │
94
83
  └──────────────────┬──────────────────┘
95
84
 
@@ -104,40 +93,112 @@ User: "Debug the page"
104
93
 
105
94
 
106
95
  ┌─────────────────────────────────────┐
107
- │ 4. Suggest (or apply) fix
108
- │ ├── Actionable fix suggestions
109
- │ ├── Auto-fix via TCR (--fix)
110
- └── Deploy & verify
111
- └─────────────────────────────────────┘
96
+ │ 4. Unmount BB Probe
97
+ │ ├── Restore console/fetch/XHR
98
+ │ ├── Remove BB button from DOM
99
+ ├── Delete window.__BB_DATA__
100
+ │ └── Page state fully restored │
101
+ └──────────────────┬──────────────────┘
102
+
103
+
104
+ ┌─────────────────────────────────────┐
105
+ │ 5. Auto-Fix Decision Gate │
106
+ │ ├── Assess root cause location │
107
+ │ │ and fixability │
108
+ │ ├── Fixable? │
109
+ │ │ ├── Yes (single-file, │
110
+ │ │ │ bounded scope) │
111
+ │ │ │ → enter $roll-fix TCR │
112
+ │ │ │ workflow automatically │
113
+ │ │ ├── Complex (cross-module, │
114
+ │ │ │ architectural) │
115
+ │ │ │ → create US-XXX │
116
+ │ │ │ → suggest $roll-build │
117
+ │ │ └── External (third-party │
118
+ │ │ API, infra) │
119
+ │ │ → report findings only │
120
+ │ └── Tell user what was found │
121
+ │ and what was done │
122
+ └──────────────────┬──────────────────┘
123
+ │ (if auto-fixed)
124
+
125
+ ┌─────────────────────────────────────┐
126
+ │ 6. Re-verify (after fix) │
127
+ │ ├── Re-mount BB probe │
128
+ │ ├── Collect + analyze again │
129
+ │ ├── Confirm issue is resolved │
130
+ │ └── Unmount BB probe │
131
+ └──────────────────┬──────────────────┘
132
+
133
+
134
+ Report to user (findings + actions taken)
112
135
  ```
113
136
 
137
+ ## Collection Modes
138
+
139
+ ### Mode 1: Mounted BB (Default)
140
+
141
+ BB probe is mounted on the page — either reused from an existing BB or freshly injected.
142
+
143
+ **Visual indicator**: a red circular **BB** button appears at the bottom-right of the page.
144
+
145
+ **Data collected via BB interface**:
146
+ - Console logs (error/warn/info)
147
+ - Network requests (failed XHR/fetch, slow requests)
148
+ - DOM state (key elements visibility, HTML length)
149
+ - Performance metrics (load time, FCP, LCP)
150
+ - JavaScript errors with stack traces
151
+
152
+ **BB Sources**:
153
+
154
+ | Source | When Used | Capability |
155
+ |--------|-----------|------------|
156
+ | Existing native BB | Page already has `[data-testid="bb-toggle"]` or `window.__BB_DATA__` | Full app-specific metrics (contentState, audioState, etc.) |
157
+ | Built-in stub | Default when no BB present | Generic metrics (console, network, DOM, performance, errors) |
158
+ | Custom SDK | `--bb-sdk-url` provided | Determined by the SDK implementation |
159
+
160
+ ### Mode 2: Universal Diagnostic (No BB)
161
+
162
+ When `--universal` is passed, skip BB mount entirely. Use Playwright's built-in event listeners directly.
163
+
164
+ ```bash
165
+ $roll-debug https://example.com/page --universal
166
+ ```
167
+
168
+ Useful when:
169
+ - You explicitly do not want to modify the page state
170
+ - The page has strict CSP that blocks script injection
171
+ - You need a quick check without probe overhead
172
+
114
173
  ## Usage Examples
115
174
 
116
- ### Example 1: Full auto-detect + analyze (default)
175
+ ### Example 1: Full auto-mount + analyze (default)
117
176
 
118
177
  ```bash
119
178
  $roll-debug https://yyy.up.railway.app/story/cars/chapter/1
120
179
 
121
- Detecting diagnostic capability...
122
- ├── BB found: [data-testid="bb-toggle"]
123
- └── Using: Native BB mode
124
-
125
- Collecting data...
126
- ├── Console: 3 errors, 5 warnings
127
- ├── Network: 2 failed requests
128
- ├── DOM: #app rendered, .content empty
129
- └── Screenshot: saved to /tmp/bb-screenshot.png
180
+ 🔍 Diagnosing https://yyy.up.railway.app/story/cars/chapter/1
181
+ 📡 Mounting BB probe...
182
+ ├── Source: built-in stub
183
+ └── Status: ready (320ms)
184
+ └── BB button visible on page ✓
185
+ 📊 Collecting data via BB...
186
+ ├── Console: 3 errors, 5 warnings
187
+ ├── Network: 2 failed requests
188
+ ├── DOM: #app rendered, .content empty
189
+ └── Screenshot: saved to /tmp/bb-screenshot.png
190
+ 🔬 Analyzing...
191
+ 🧹 Unmounting BB probe... done
192
+ └── Page state restored ✓
130
193
 
131
194
  Report: /tmp/bb-report.json
132
195
 
133
- Analyzing...
134
-
135
196
  ## Diagnostic Analysis Report
136
197
 
137
198
  ### Basic Info
138
199
  | Field | Value |
139
200
  |-------|-------|
140
- | Diagnostic Mode | native-bb |
201
+ | Diagnostic Mode | mounted-bb (stub) |
141
202
  | Page URL | https://yyy.up.railway.app/story/cars/chapter/1 |
142
203
 
143
204
  ### Key Findings
@@ -153,63 +214,81 @@ Analyzing...
153
214
  useEffect dependency error causing content not to load.
154
215
  Dependency `[chapter?.id]` should be `[chapter?.number]`
155
216
 
156
- ### Suggested Fix
157
- Modify Player.tsx line 45, change useEffect dependency
158
- from `[chapter?.id]` to `[chapter?.number]`
217
+ ### Auto-Fix
218
+ Root cause is in project source (Player.tsx:45), single-file, bounded scope.
219
+ Entering $roll-fix TCR workflow...
220
+
221
+ 🧪 Test: added regression test for chapter content loading
222
+ 🔧 Fix: Player.tsx:45 — useEffect dep [chapter?.id] → [chapter?.number]
223
+ ✅ TCR: test green, committed
224
+ 🔍 Review: $roll-.review passed
225
+ 📤 Push: origin/main
226
+ ⏳ CI: green
227
+ 🚀 Deploy: https://yyy.up.railway.app
228
+
229
+ 🔄 Re-verifying...
230
+ 📡 Re-mounting BB probe...
231
+ 📊 Collecting data...
232
+ ├── Console: 0 errors
233
+ ├── contentLength: 2340
234
+ └── hasText: true
235
+ 🧹 Unmounting BB probe... done
236
+
237
+ ✅ Issue resolved. Content now loads correctly.
238
+ ```
239
+
240
+ ### Example 2: Reuse existing native BB
241
+
242
+ ```bash
243
+ $roll-debug https://example.com/page
244
+
245
+ 🔍 Diagnosing https://example.com/page
246
+ 📡 Mounting BB probe...
247
+ ├── Native BB detected
248
+ └── Reusing existing probe
249
+ 📊 Collecting data via BB...
250
+ ├── Console: 0 errors
251
+ ├── Network: 0 failed
252
+ └── DOM: fully rendered
253
+ 🔬 Analyzing...
254
+ 🧹 Unmounting BB probe... skipped
255
+ └── Native BB left intact
256
+
257
+ No issues found. Page is healthy.
159
258
  ```
160
259
 
161
- ### Example 2: Universal mode (no BB)
260
+ ### Example 3: Universal mode (no BB mount)
162
261
 
163
262
  ```bash
164
263
  $roll-debug https://example.com --universal
165
264
 
166
- Universal diagnostic mode (no BB required)
167
-
168
- Collected:
169
- ├── Console Errors: 2
170
- │ ├── TypeError: Cannot read property 'id' of undefined
171
- │ │ at Player.tsx:45
172
- │ └── ReferenceError: AudioContext is not defined
173
- ├── Failed Network: 1
174
- │ └── GET https://api.example.com/data 404
175
- ├── DOM State:
176
- │ ├── body.innerHTML length: 2340
177
- │ ├── #root: rendered
178
- │ ├── .loading: still visible (timeout?)
179
- │ └── .error-message: visible
180
- ├── Performance:
181
- │ ├── DOMContentLoaded: 1.2s
182
- │ ├── First Contentful Paint: 2.3s
183
- │ └── Largest Contentful Paint: 4.5s
184
- └── Screenshot: /tmp/bb-screenshot.png
265
+ 🔍 Diagnosing https://example.com (universal mode)
266
+ 📡 BB mount skipped (--universal)
267
+ 📊 Collecting data via Playwright events...
268
+ ├── Console Errors: 2
269
+ │ ├── TypeError: Cannot read property 'id' of undefined
270
+ │ │ at Player.tsx:45
271
+ │ └── ReferenceError: AudioContext is not defined
272
+ ├── Failed Network: 1
273
+ │ └── GET https://api.example.com/data 404
274
+ └── Screenshot: /tmp/bb-screenshot.png
275
+ 🔬 Analyzing...
185
276
 
186
277
  Report: /tmp/bb-report.json
187
278
 
188
- Analyzing...
189
-
190
279
  ### Key Findings
191
280
  | Metric | Value | Status |
192
281
  |--------|-------|--------|
193
282
  | Console Errors | 2 | Critical |
194
283
  | Network Failed | 1 | Critical |
195
- | DOM Rendering | Partial | Warning |
196
- | Load Time (LCP) | 4.5s | Slow |
197
-
198
- ### Diagnosis Conclusion
199
- API endpoint returning 404 causes content not to load.
200
- AudioContext undefined suggests missing polyfill or browser incompatibility.
201
-
202
- ### Suggested Fix
203
- 1. Fix API route for /data endpoint (404)
204
- 2. Add AudioContext polyfill or guard with `typeof AudioContext !== 'undefined'`
205
284
  ```
206
285
 
207
- ### Example 3: Analyze existing report file
286
+ ### Example 4: Analyze existing report file
208
287
 
209
288
  ```bash
210
289
  $roll-debug --report /tmp/bb-report.json
211
290
 
212
- Reading report: /tmp/bb-report.json (mode: universal)
291
+ Reading report: /tmp/bb-report.json (mode: mounted-bb)
213
292
 
214
293
  ### Key Findings
215
294
  ...
@@ -219,11 +298,13 @@ Reading report: /tmp/bb-report.json (mode: universal)
219
298
 
220
299
  | Format | Source | Description |
221
300
  |--------|--------|-------------|
222
- | Native BB | Page with Black Box | `window.__BB_DATA__` or `localStorage.bb_diagnostic` |
223
- | Universal | Playwright collector | Injected collector data |
301
+ | Mounted BB (stub) | Injected built-in stub | `window.__BB_DATA__` via injectable-bb.js |
302
+ | Mounted BB (native) | Page with existing Black Box | `window.__BB_DATA__` or `localStorage.bb_diagnostic` |
303
+ | Mounted BB (custom) | Custom SDK via `--bb-sdk-url` | Determined by SDK |
304
+ | Universal | Playwright native events | Direct event listener data |
224
305
  | Legacy | Old diagnostic files | Backward compatible |
225
306
 
226
- ### Native BB Mode Fields
307
+ ### Mounted BB Mode Fields
227
308
 
228
309
  ```javascript
229
310
  const bbData = report.diagnostic.bbData;
@@ -233,6 +314,11 @@ bbData.audioState?.src
233
314
  bbData.audioState?.error
234
315
  bbData.hasAudio
235
316
  bbData.errors
317
+ bbData.console.errors
318
+ bbData.console.warnings
319
+ bbData.network.failed
320
+ bbData.dom.keyElements
321
+ bbData.performance.loadComplete
236
322
  ```
237
323
 
238
324
  ### Universal Mode Fields
@@ -248,7 +334,6 @@ d.dom['#root']
248
334
  d.dom.htmlLength
249
335
  d.performance.loadComplete
250
336
  d.performance.domContentLoaded
251
- d.errors
252
337
  ```
253
338
 
254
339
  ## Analysis Report Template
@@ -259,7 +344,8 @@ d.errors
259
344
  ### Basic Info
260
345
  | Field | Value |
261
346
  |-------|-------|
262
- | Diagnostic Mode | {native-bb / universal} |
347
+ | Diagnostic Mode | {mounted-bb / universal} |
348
+ | BB Source | {native / stub / custom-sdk} |
263
349
  | Page URL | {url} |
264
350
  | Collected At | {timestamp} |
265
351
 
@@ -302,62 +388,123 @@ d.errors
302
388
 
303
389
  ## Implementation Notes
304
390
 
305
- ### Universal Mode Injection
306
-
307
- When page has no BB, inject a lightweight collector via `page.evaluate()`:
391
+ ### BB Mount Flow (Playwright)
308
392
 
309
393
  ```javascript
310
- window.__ROLL_DEBUG_COLLECTOR__ = {
311
- console: [],
312
- network: [],
313
- errors: [],
314
-
315
- init() {
316
- // Hook console methods
317
- ['error', 'warn', 'log', 'info'].forEach(method => {
318
- const original = console[method];
319
- console[method] = (...args) => {
320
- this.console.push({method, args, timestamp: Date.now()});
321
- original.apply(console, args);
322
- };
323
- });
324
-
325
- // Hook fetch/XHR for network interception
326
-
327
- // Listen for JS errors
328
- window.addEventListener('error', e => {
329
- this.errors.push({message: e.message, stack: e.error?.stack});
330
- });
331
- },
394
+ // Pseudocode for AI agent execution
395
+ async function diagnose(page, url, args) {
396
+ log(`🔍 Diagnosing ${url}`);
397
+
398
+ // Step 1: Mount
399
+ const bbState = await mountBB(page, args);
400
+ log(`📡 Mounting BB probe...`);
401
+ log(` ├── Source: ${bbState.source}`); // native / stub / custom
402
+ log(` └── Status: ${bbState.ready ? 'ready' : 'failed'}`);
403
+
404
+ if (bbState.ready && bbState.source !== 'native') {
405
+ log(` └── BB button visible on page ✓`);
406
+ }
407
+
408
+ // Step 2: Collect
409
+ log(`📊 Collecting data via BB...`);
410
+ const data = await collectViaBB(page);
411
+
412
+ // Step 3: Analyze
413
+ log(`🔬 Analyzing...`);
414
+ const analysis = await analyze(data);
415
+
416
+ // Step 4: Unmount (unless native BB)
417
+ if (bbState.source !== 'native') {
418
+ log(`🧹 Unmounting BB probe...`);
419
+ const ok = await page.evaluate(() => window.__BB_UNMOUNT__?.());
420
+ log(` └── ${ok ? 'done' : 'failed'}`);
421
+ log(` └── Page state restored ✓`);
422
+ } else {
423
+ log(`🧹 Unmounting BB probe... skipped`);
424
+ log(` └── Native BB left intact`);
425
+ }
332
426
 
333
- getData() {
334
- return {
335
- console: this.console,
336
- network: this.network,
337
- errors: this.errors,
338
- dom: this.captureDOM(),
339
- performance: this.capturePerformance()
340
- };
427
+ return analysis;
428
+ }
429
+
430
+ async function mountBB(page, args) {
431
+ // Check for existing BB
432
+ const hasNative = await page.evaluate(() =>
433
+ !!document.querySelector('[data-testid="bb-toggle"]') || !!window.__BB_DATA__
434
+ );
435
+ if (hasNative) {
436
+ return { source: 'native', ready: true };
437
+ }
438
+
439
+ if (args.universal) {
440
+ return { source: 'universal', ready: false };
341
441
  }
342
- };
442
+
443
+ // Inject BB
444
+ try {
445
+ if (args.bbSdkUrl) {
446
+ await page.addScriptTag({ url: args.bbSdkUrl });
447
+ } else {
448
+ const stubPath = path.join(__dirname, 'injectable-bb.js');
449
+ await page.addScriptTag({ path: stubPath });
450
+ }
451
+
452
+ // Poll for readiness
453
+ const ready = await poll(
454
+ () => page.evaluate(() => !!window.__BB_DATA__),
455
+ { timeout: 5000, interval: 200 }
456
+ );
457
+
458
+ return { source: args.bbSdkUrl ? 'custom' : 'stub', ready };
459
+ } catch (e) {
460
+ return { source: 'stub', ready: false, error: e.message };
461
+ }
462
+ }
343
463
  ```
344
464
 
345
- The injected collector only exists in the Playwright browser context — no cleanup needed.
465
+ ### Built-in Stub (`injectable-bb.js`)
466
+
467
+ The stub is injected via `page.addScriptTag({ path })` when no native BB exists.
468
+
469
+ **Capabilities**:
470
+ - Hooks `console.*` with internal error firewall (stub bugs never leak to page)
471
+ - Hooks `fetch` and `XMLHttpRequest` transparently — original behavior fully preserved
472
+ - Listens for `error` and `unhandledrejection`
473
+ - Captures Performance Navigation Timing + FCP + LCP
474
+ - Captures DOM state (title, HTML length, key element visibility)
475
+ - Renders a visible **BB** button on the page
476
+
477
+ **Cleanup**:
478
+ - `window.__BB_UNMOUNT__()` restores all modified globals to their original references
479
+ - Removes the BB button from DOM
480
+ - Deletes `window.__BB_DATA__` and `window.__BB_UNMOUNT__`
481
+
482
+ ### Universal Mode (No BB)
483
+
484
+ When `--universal` is used, collect via Playwright native events:
485
+
486
+ ```javascript
487
+ page.on('console', msg => ...);
488
+ page.on('requestfailed', req => ...);
489
+ page.on('response', res => ...);
490
+ page.on('pageerror', err => ...);
491
+ ```
492
+
493
+ No page state is modified.
346
494
 
347
495
  ## Data Output Formats
348
496
 
349
- ### Native BB Mode
497
+ ### Mounted BB Mode
350
498
 
351
499
  ```json
352
500
  {
353
- "mode": "native-bb",
501
+ "mode": "mounted-bb",
502
+ "bbSource": "stub",
354
503
  "timestamp": "2024-01-15T10:30:00Z",
355
504
  "url": "https://example.com/page",
356
505
  "bbData": {},
357
- "collected": {
358
- "console": [],
359
- "network": []
360
- }
506
+ "mountedAt": 1705315800000,
507
+ "unmountedAt": 1705315805000
361
508
  }
362
509
  ```
363
510
 
@@ -382,7 +529,7 @@ The injected collector only exists in the Playwright browser context — no clea
382
529
  "title": "Page Title",
383
530
  "htmlLength": 2340,
384
531
  "keyElements": {
385
- "#root": {"exists": true, "visible": true, "children": 5},
532
+ "#root": {"exists": true, "visible": true, "text": "..."},
386
533
  ".error": {"exists": false}
387
534
  }
388
535
  },
@@ -402,27 +549,59 @@ The injected collector only exists in the Playwright browser context — no clea
402
549
 
403
550
  ## Capability Comparison
404
551
 
405
- | Feature | Native BB Mode | Universal Mode |
406
- |---------|---------------|----------------|
407
- | Requires BB integration | Yes | No |
408
- | Console logs | Yes | Yes |
409
- | Network data | Yes | Yes |
410
- | DOM state | Detailed | Key elements |
411
- | App-specific metrics | Yes | No |
412
- | Screenshot | Yes | Yes |
413
- | Performance metrics | Yes | Yes |
414
- | Works on any site | No | Yes |
552
+ | Feature | Mounted BB (stub) | Mounted BB (native) | Universal |
553
+ |---------|-------------------|---------------------|-----------|
554
+ | Page modification | Yes (mount/unmount) | No (already there) | No |
555
+ | Visible BB button | Yes | If native has one | No |
556
+ | Console logs | Yes | Yes | Yes |
557
+ | Network data | Yes | Yes | Yes |
558
+ | DOM state | Detailed | Detailed | Key elements |
559
+ | App-specific metrics | No | Yes | No |
560
+ | Screenshot | Yes | Yes | Yes |
561
+ | Performance metrics | Yes | Yes | Yes |
562
+ | Works offline | Yes | Yes | Yes |
563
+ | Cleanup on exit | Yes (full restore) | N/A | N/A |
415
564
 
416
- ## Integration with Build Skills
565
+ ## Safety & Cleanup Guarantees
417
566
 
418
- After `$roll-debug` finds issues:
567
+ 1. **Stub errors are firewalled** — every hook wraps its internal logic in try/catch. A bug in the stub cannot crash the page.
568
+ 2. **Original behavior preserved** — fetch/XHR wrappers return the exact same values/throw the exact same errors as the originals.
569
+ 3. **Full unmount** — `__BB_UNMOUNT__()` restores console, fetch, XHR, removes listeners, removes DOM element, and deletes globals.
570
+ 4. **Native BB untouched** — if a page already has BB, it is reused but never unmounted.
571
+ 5. **CSP fallback** — if script injection fails (CSP), automatically falls back to Universal mode.
419
572
 
420
- ```bash
421
- # For a single-file bug fix
422
- # Create FIX-XXX in backlog
423
- # → $roll-fix FIX-XXX
573
+ ## Auto-Fix Behavior
574
+
575
+ After diagnosis, roll-debug automatically assesses whether the root cause can be fixed — **no flag needed**. The decision is context-driven:
424
576
 
425
- # For a complex multi-step fix
426
- # → Create US-XXX in backlog
427
- # → $roll-story US-XXX
428
577
  ```
578
+ Root cause identified
579
+
580
+ ├── In project source + single-file + bounded scope
581
+ │ └── AUTO-FIX: enter $roll-fix TCR workflow
582
+ │ ├── Write regression test (RED)
583
+ │ ├── Apply fix (GREEN)
584
+ │ ├── TCR commit
585
+ │ ├── $roll-.review staged
586
+ │ ├── Push → CI → Deploy
587
+ │ └── Re-mount BB → re-verify on page
588
+
589
+ ├── In project source + cross-module / architectural
590
+ │ └── ESCALATE: create US-XXX in .roll/backlog.md
591
+ │ ├── Suggest: $roll-build US-XXX
592
+ │ └── Report diagnosis findings
593
+
594
+ └── External (third-party API, infra, CDN, DNS)
595
+ └── REPORT ONLY
596
+ ├── What was found
597
+ └── Suggested actions (manual or external)
598
+ ```
599
+
600
+ **Quality gates preserved**: When auto-fixing, all `$roll-fix` quality gates apply — TCR, `$roll-.review`, push, CI, deploy. No shortcuts.
601
+
602
+ **Re-verification**: After a successful auto-fix, roll-debug re-mounts the BB probe on the same page and re-runs diagnosis to confirm the issue is actually resolved. If the issue persists, it reports the remaining findings.
603
+
604
+ **User communication**: roll-debug always tells the user:
605
+ - What was found (root cause, severity)
606
+ - What was done (auto-fixed / escalated / reported)
607
+ - Why (fixability assessment reasoning)