@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
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: roll-debug
|
|
3
|
-
|
|
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
|
-
|
|
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: **Mount → Collect → Analyze → Unmount → Auto-Fix (when fixable) → Re-verify**.
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- **
|
|
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 +
|
|
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
|
-
#
|
|
44
|
+
# Skip BB mount, use built-in universal collector
|
|
34
45
|
$roll-debug https://example.com/page --universal
|
|
35
46
|
|
|
36
|
-
#
|
|
37
|
-
$roll-debug https://example.com/page --
|
|
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
|
-
##
|
|
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.
|
|
82
|
-
│ ├──
|
|
83
|
-
│ ├──
|
|
84
|
-
│ └──
|
|
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.
|
|
108
|
-
│ ├──
|
|
109
|
-
│ ├──
|
|
110
|
-
│
|
|
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-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
├──
|
|
128
|
-
├──
|
|
129
|
-
|
|
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 |
|
|
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
|
-
###
|
|
157
|
-
|
|
158
|
-
|
|
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
|
|
260
|
+
### Example 3: Universal mode (no BB mount)
|
|
162
261
|
|
|
163
262
|
```bash
|
|
164
263
|
$roll-debug https://example.com --universal
|
|
165
264
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
|
|
176
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
|
223
|
-
|
|
|
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
|
-
###
|
|
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 | {
|
|
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
|
-
###
|
|
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
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
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
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
497
|
+
### Mounted BB Mode
|
|
350
498
|
|
|
351
499
|
```json
|
|
352
500
|
{
|
|
353
|
-
"mode": "
|
|
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
|
-
"
|
|
358
|
-
|
|
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, "
|
|
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 |
|
|
406
|
-
|
|
407
|
-
|
|
|
408
|
-
|
|
|
409
|
-
|
|
|
410
|
-
|
|
|
411
|
-
|
|
|
412
|
-
|
|
|
413
|
-
|
|
|
414
|
-
|
|
|
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
|
-
##
|
|
565
|
+
## Safety & Cleanup Guarantees
|
|
417
566
|
|
|
418
|
-
|
|
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
|
-
|
|
421
|
-
|
|
422
|
-
|
|
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)
|