litclaude-ai 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/CHANGELOG.md +155 -0
  2. package/LICENSE +21 -0
  3. package/README.md +369 -0
  4. package/README_ko-KR.md +374 -0
  5. package/RELEASE_CHECKLIST.md +165 -0
  6. package/bin/litclaude-ai.js +643 -0
  7. package/cover.png +0 -0
  8. package/docs/agents.md +67 -0
  9. package/docs/hooks.md +134 -0
  10. package/docs/lsp.md +40 -0
  11. package/docs/migration.md +209 -0
  12. package/docs/workflow-compatibility-audit.md +119 -0
  13. package/generate_cover.py +123 -0
  14. package/package.json +48 -0
  15. package/plugins/litclaude/.claude-plugin/plugin.json +25 -0
  16. package/plugins/litclaude/.lsp.json +13 -0
  17. package/plugins/litclaude/.mcp.json +9 -0
  18. package/plugins/litclaude/agents/boulder-executor.md +12 -0
  19. package/plugins/litclaude/agents/librarian-researcher.md +15 -0
  20. package/plugins/litclaude/agents/oracle-verifier.md +16 -0
  21. package/plugins/litclaude/agents/prometheus-planner.md +13 -0
  22. package/plugins/litclaude/agents/qa-runner.md +16 -0
  23. package/plugins/litclaude/agents/quality-reviewer.md +17 -0
  24. package/plugins/litclaude/bin/litclaude-hook.js +110 -0
  25. package/plugins/litclaude/bin/litclaude-hud.js +271 -0
  26. package/plugins/litclaude/bin/litclaude-lsp-doctor.js +15 -0
  27. package/plugins/litclaude/bin/litclaude-mcp.js +70 -0
  28. package/plugins/litclaude/commands/deep-interview.md +21 -0
  29. package/plugins/litclaude/commands/dynamic-workflow.md +36 -0
  30. package/plugins/litclaude/commands/lit-loop.md +40 -0
  31. package/plugins/litclaude/commands/lit-plan.md +35 -0
  32. package/plugins/litclaude/commands/litgoal.md +30 -0
  33. package/plugins/litclaude/commands/review-work.md +35 -0
  34. package/plugins/litclaude/commands/start-work.md +36 -0
  35. package/plugins/litclaude/hooks/hooks.json +54 -0
  36. package/plugins/litclaude/lib/context-pressure.mjs +25 -0
  37. package/plugins/litclaude/lib/hud-accent-palette.mjs +58 -0
  38. package/plugins/litclaude/lib/litgoal/cli.mjs +266 -0
  39. package/plugins/litclaude/lib/litgoal/ledger.mjs +16 -0
  40. package/plugins/litclaude/lib/litgoal/paths.mjs +7 -0
  41. package/plugins/litclaude/lib/litgoal/state.mjs +67 -0
  42. package/plugins/litclaude/lib/mutated-file-paths.mjs +63 -0
  43. package/plugins/litclaude/lib/start-work-continuation.mjs +99 -0
  44. package/plugins/litclaude/lib/workflow-check.mjs +83 -0
  45. package/plugins/litclaude/skills/ai-slop-remover/SKILL.md +142 -0
  46. package/plugins/litclaude/skills/comment-checker/SKILL.md +55 -0
  47. package/plugins/litclaude/skills/debugging/SKILL.md +70 -0
  48. package/plugins/litclaude/skills/debugging/references/methodology/00-setup.md +108 -0
  49. package/plugins/litclaude/skills/debugging/references/methodology/02-investigate.md +126 -0
  50. package/plugins/litclaude/skills/debugging/references/methodology/04-oracle-triple.md +106 -0
  51. package/plugins/litclaude/skills/debugging/references/methodology/05-escalate.md +69 -0
  52. package/plugins/litclaude/skills/debugging/references/methodology/06-fix.md +116 -0
  53. package/plugins/litclaude/skills/debugging/references/methodology/08-qa.md +94 -0
  54. package/plugins/litclaude/skills/debugging/references/methodology/09-cleanup.md +164 -0
  55. package/plugins/litclaude/skills/debugging/references/methodology/partial-runtime-evidence.md +228 -0
  56. package/plugins/litclaude/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
  57. package/plugins/litclaude/skills/debugging/references/runtimes/go.md +252 -0
  58. package/plugins/litclaude/skills/debugging/references/runtimes/native-binary.md +484 -0
  59. package/plugins/litclaude/skills/debugging/references/runtimes/node.md +260 -0
  60. package/plugins/litclaude/skills/debugging/references/runtimes/python.md +248 -0
  61. package/plugins/litclaude/skills/debugging/references/runtimes/rust.md +234 -0
  62. package/plugins/litclaude/skills/debugging/references/tools/ghidra.md +212 -0
  63. package/plugins/litclaude/skills/debugging/references/tools/playwright-cli.md +194 -0
  64. package/plugins/litclaude/skills/debugging/references/tools/pwndbg.md +263 -0
  65. package/plugins/litclaude/skills/debugging/references/tools/pwntools.md +265 -0
  66. package/plugins/litclaude/skills/deep-interview/SKILL.md +323 -0
  67. package/plugins/litclaude/skills/deep-interview/scripts/render_progress.py +193 -0
  68. package/plugins/litclaude/skills/frontend-ui-ux/SKILL.md +62 -0
  69. package/plugins/litclaude/skills/lit-loop/SKILL.md +144 -0
  70. package/plugins/litclaude/skills/lit-plan/SKILL.md +125 -0
  71. package/plugins/litclaude/skills/litgoal/SKILL.md +219 -0
  72. package/plugins/litclaude/skills/lsp/SKILL.md +63 -0
  73. package/plugins/litclaude/skills/programming/SKILL.md +106 -0
  74. package/plugins/litclaude/skills/programming/references/go/README.md +90 -0
  75. package/plugins/litclaude/skills/programming/references/go/backend-stack.md +641 -0
  76. package/plugins/litclaude/skills/programming/references/go/bootstrap.md +328 -0
  77. package/plugins/litclaude/skills/programming/references/go/bubbletea-v2.md +360 -0
  78. package/plugins/litclaude/skills/programming/references/go/cobra-stack.md +468 -0
  79. package/plugins/litclaude/skills/programming/references/go/concurrency.md +362 -0
  80. package/plugins/litclaude/skills/programming/references/go/data-modeling.md +329 -0
  81. package/plugins/litclaude/skills/programming/references/go/error-handling.md +359 -0
  82. package/plugins/litclaude/skills/programming/references/go/golangci-strict.md +236 -0
  83. package/plugins/litclaude/skills/programming/references/go/grpc-connect.md +375 -0
  84. package/plugins/litclaude/skills/programming/references/go/libraries.md +337 -0
  85. package/plugins/litclaude/skills/programming/references/go/one-liners.md +202 -0
  86. package/plugins/litclaude/skills/programming/references/go/sqlc-pgx.md +471 -0
  87. package/plugins/litclaude/skills/programming/references/go/testing.md +467 -0
  88. package/plugins/litclaude/skills/programming/references/go/type-patterns.md +298 -0
  89. package/plugins/litclaude/skills/programming/references/python/README.md +314 -0
  90. package/plugins/litclaude/skills/programming/references/python/async-anyio.md +442 -0
  91. package/plugins/litclaude/skills/programming/references/python/data-modeling.md +233 -0
  92. package/plugins/litclaude/skills/programming/references/python/data-processing.md +133 -0
  93. package/plugins/litclaude/skills/programming/references/python/error-handling.md +218 -0
  94. package/plugins/litclaude/skills/programming/references/python/fastapi-stack.md +316 -0
  95. package/plugins/litclaude/skills/programming/references/python/httpx2-optimization.md +360 -0
  96. package/plugins/litclaude/skills/programming/references/python/libraries.md +307 -0
  97. package/plugins/litclaude/skills/programming/references/python/one-liners.md +268 -0
  98. package/plugins/litclaude/skills/programming/references/python/orjson-stack.md +378 -0
  99. package/plugins/litclaude/skills/programming/references/python/pydantic-ai.md +285 -0
  100. package/plugins/litclaude/skills/programming/references/python/pyproject-strict.md +232 -0
  101. package/plugins/litclaude/skills/programming/references/python/textual-tui.md +201 -0
  102. package/plugins/litclaude/skills/programming/references/python/type-patterns.md +176 -0
  103. package/plugins/litclaude/skills/programming/references/rust/README.md +317 -0
  104. package/plugins/litclaude/skills/programming/references/rust/async-tokio.md +299 -0
  105. package/plugins/litclaude/skills/programming/references/rust/axum-stack.md +467 -0
  106. package/plugins/litclaude/skills/programming/references/rust/cargo-strict.md +317 -0
  107. package/plugins/litclaude/skills/programming/references/rust/clap-stack.md +409 -0
  108. package/plugins/litclaude/skills/programming/references/rust/concurrency.md +375 -0
  109. package/plugins/litclaude/skills/programming/references/rust/libraries.md +439 -0
  110. package/plugins/litclaude/skills/programming/references/rust/one-liners.md +291 -0
  111. package/plugins/litclaude/skills/programming/references/rust/proptest-insta.md +429 -0
  112. package/plugins/litclaude/skills/programming/references/rust/type-state.md +354 -0
  113. package/plugins/litclaude/skills/programming/references/rust/unsafe-discipline.md +250 -0
  114. package/plugins/litclaude/skills/programming/references/rust/zero-cost-safety.md +527 -0
  115. package/plugins/litclaude/skills/programming/references/rust-ub/README.md +289 -0
  116. package/plugins/litclaude/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
  117. package/plugins/litclaude/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
  118. package/plugins/litclaude/skills/programming/references/typescript/README.md +195 -0
  119. package/plugins/litclaude/skills/programming/references/typescript/backend-hono.md +672 -0
  120. package/plugins/litclaude/skills/programming/references/typescript/bootstrap.md +199 -0
  121. package/plugins/litclaude/skills/programming/references/typescript/data-modeling.md +202 -0
  122. package/plugins/litclaude/skills/programming/references/typescript/error-handling.md +169 -0
  123. package/plugins/litclaude/skills/programming/references/typescript/tsconfig-strict.md +152 -0
  124. package/plugins/litclaude/skills/programming/references/typescript/type-patterns.md +196 -0
  125. package/plugins/litclaude/skills/programming/scripts/go/check-no-excuse-rules.sh +173 -0
  126. package/plugins/litclaude/skills/programming/scripts/go/new-project.py +138 -0
  127. package/plugins/litclaude/skills/programming/scripts/go/templates/.editorconfig +13 -0
  128. package/plugins/litclaude/skills/programming/scripts/go/templates/.golangci.yml +95 -0
  129. package/plugins/litclaude/skills/programming/scripts/go/templates/AGENTS.md.tmpl +24 -0
  130. package/plugins/litclaude/skills/programming/scripts/go/templates/README.md.tmpl +12 -0
  131. package/plugins/litclaude/skills/programming/scripts/go/templates/Taskfile.yml +40 -0
  132. package/plugins/litclaude/skills/programming/scripts/go/templates/ci.yml +37 -0
  133. package/plugins/litclaude/skills/programming/scripts/go/templates/config.go +24 -0
  134. package/plugins/litclaude/skills/programming/scripts/go/templates/gitignore +15 -0
  135. package/plugins/litclaude/skills/programming/scripts/go/templates/main.go.tmpl +22 -0
  136. package/plugins/litclaude/skills/programming/scripts/go/templates/run.go +15 -0
  137. package/plugins/litclaude/skills/programming/scripts/python/check-no-excuse-rules.py +687 -0
  138. package/plugins/litclaude/skills/programming/scripts/python/new-project.py +172 -0
  139. package/plugins/litclaude/skills/programming/scripts/python/new-script.py +116 -0
  140. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.py +296 -0
  141. package/plugins/litclaude/skills/programming/scripts/rust/check-no-excuse-rules.sh +158 -0
  142. package/plugins/litclaude/skills/programming/scripts/rust/new-project.py +175 -0
  143. package/plugins/litclaude/skills/programming/scripts/typescript/check-no-excuse-rules.ts +282 -0
  144. package/plugins/litclaude/skills/programming/scripts/typescript/new-project.ts +177 -0
  145. package/plugins/litclaude/skills/refactor/SKILL.md +73 -0
  146. package/plugins/litclaude/skills/remove-ai-slops/SKILL.md +52 -0
  147. package/plugins/litclaude/skills/review-work/SKILL.md +331 -0
  148. package/plugins/litclaude/skills/rules/SKILL.md +66 -0
  149. package/plugins/litclaude/skills/start-work/SKILL.md +132 -0
  150. package/scripts/audit-plan-checkboxes.mjs +37 -0
  151. package/scripts/doctor.mjs +41 -0
  152. package/scripts/inspect-agent-tools.mjs +27 -0
  153. package/scripts/postinstall.mjs +50 -0
  154. package/scripts/qa-claude-plugin-smoke.sh +60 -0
  155. package/scripts/qa-portable-install.sh +136 -0
  156. package/scripts/validate-plugin.mjs +72 -0
@@ -0,0 +1,234 @@
1
+ # Rust Debugging
2
+
3
+ Covers `cargo`, `tokio`, panics, and the fact that you usually don't actually need a debugger — Rust's type system, `dbg!`, and logging cover 80% of sessions faster than gdb would.
4
+
5
+ ---
6
+
7
+ ## Environment detection (Phase 0)
8
+
9
+ ```bash
10
+ cargo --version
11
+ rustc --version
12
+ cat rust-toolchain.toml rust-toolchain 2>/dev/null
13
+ cat Cargo.toml | head -30
14
+
15
+ # Debuggers available
16
+ which rust-gdb
17
+ which rust-lldb
18
+ which lldb
19
+
20
+ # Async infrastructure
21
+ grep -E '"(tokio|async-std|smol)"' Cargo.toml
22
+
23
+ # Profile flags
24
+ grep -E '^\[profile' Cargo.toml
25
+ ```
26
+
27
+ **The default `cargo run` builds with `dev` profile** which includes debug symbols. `cargo run --release` strips them. For debugging, stay in dev unless the bug only manifests under optimization.
28
+
29
+ ---
30
+
31
+ ## The Rust debugging hierarchy (use in this order)
32
+
33
+ Rust's ecosystem has a specific order that's faster than reaching for gdb first:
34
+
35
+ 1. **`dbg!(expr)` macro** — for a single value at a specific spot. Prints file:line + value, returns the value unchanged so you can inline it. Faster than a debugger for 60% of bugs.
36
+ 2. **`RUST_LOG=trace` with `tracing` / `env_logger`** — for flow and state across an operation. Zero code change in dev-time.
37
+ 3. **`RUST_BACKTRACE=1` / `=full`** — for crashes. Almost always sufficient; you rarely need a live debugger for a panic.
38
+ 4. **`rust-gdb` / `rust-lldb`** — when you need to pause execution and inspect memory, especially for unsafe code or FFI.
39
+ 5. **`tokio-console`** — for async deadlocks, stuck tasks, hot loops.
40
+ 6. **`cargo-expand`** — when a macro is doing something weird.
41
+
42
+ Reach for the lightest tool that answers the hypothesis.
43
+
44
+ ---
45
+
46
+ ## `dbg!` — the underused macro
47
+
48
+ ```rust
49
+ let x = 5;
50
+ let y = dbg!(x * 2); // prints: [src/main.rs:2] x * 2 = 10
51
+ ```
52
+
53
+ Inside a complex expression:
54
+ ```rust
55
+ let total = items.iter().filter(|i| i.active).map(|i| dbg!(i.cost)).sum::<u64>();
56
+ ```
57
+
58
+ Multiple values at once:
59
+ ```rust
60
+ dbg!(&user, &request, elapsed.as_millis());
61
+ ```
62
+
63
+ `dbg!` writes to stderr, so it won't corrupt stdout-based pipelines. **Journal each `dbg!` you add**; revert at Phase 9.
64
+
65
+ ---
66
+
67
+ ## `RUST_LOG` for flow-level debugging
68
+
69
+ If the codebase uses `tracing` or `env_logger`:
70
+
71
+ ```bash
72
+ RUST_LOG=debug cargo run
73
+ RUST_LOG=trace cargo run # very verbose
74
+ RUST_LOG=my_crate=trace,hyper=info cargo run # per-module level
75
+ RUST_LOG=debug,tokio=off cargo run # silence noisy crates
76
+ ```
77
+
78
+ For `tracing`-based apps, instrument with spans:
79
+ ```rust
80
+ #[tracing::instrument]
81
+ fn handle_request(req: &Request) -> Response { ... }
82
+ ```
83
+
84
+ This gives you structured per-call entry/exit logs with args and timing, zero additional code in the body.
85
+
86
+ ---
87
+
88
+ ## `RUST_BACKTRACE` for panics
89
+
90
+ ```bash
91
+ RUST_BACKTRACE=1 cargo run # backtrace on panic
92
+ RUST_BACKTRACE=full cargo run # include libstd/tokio frames
93
+ ```
94
+
95
+ The panic itself usually tells you the file:line. The backtrace tells you how it got there. Between the two, most crash bugs are solved without a debugger.
96
+
97
+ ---
98
+
99
+ ## rust-gdb / rust-lldb
100
+
101
+ ### Launch
102
+
103
+ ```bash
104
+ # Build with debug symbols (default dev profile)
105
+ cargo build
106
+
107
+ # Attach gdb wrapper (applies Rust type pretty-printers)
108
+ rust-gdb ./target/debug/my_binary
109
+ # Or lldb:
110
+ rust-lldb ./target/debug/my_binary
111
+
112
+ # With args
113
+ rust-gdb --args ./target/debug/my_binary arg1 arg2
114
+
115
+ # Attach to running process
116
+ rust-gdb -p $(pgrep my_binary)
117
+ ```
118
+
119
+ ### Breakpoints
120
+
121
+ Rust symbols are mangled. Use either:
122
+
123
+ ```
124
+ (gdb) b main # main function
125
+ (gdb) b my_crate::module::function # canonical path
126
+ (gdb) b src/handler.rs:42 # file:line
127
+ (gdb) info functions my_function # find mangled name
128
+ ```
129
+
130
+ ### State inspection
131
+
132
+ ```
133
+ (gdb) p x # print value (uses Rust pretty-printer for Vec, Option, HashMap, etc.)
134
+ (gdb) p *ptr # deref
135
+ (gdb) info locals # all locals in current frame
136
+ (gdb) info args # function args
137
+ (gdb) bt # backtrace
138
+ (gdb) frame <n> # switch to stack frame n
139
+ (gdb) watch my_var # stop when my_var changes
140
+ (gdb) rbreak regex # breakpoint all functions matching regex
141
+ ```
142
+
143
+ **Pair with pwndbg** for better layout on native bugs — see [tools/pwndbg.md](../tools/pwndbg.md). Pwndbg works with rust-gdb too.
144
+
145
+ ---
146
+
147
+ ## tokio-console — async task debugging
148
+
149
+ For tokio-based async apps, this is essential when tasks are stuck or leaking.
150
+
151
+ ```bash
152
+ # Add tokio-console instrumentation to the target binary
153
+ # In Cargo.toml:
154
+ # [dependencies]
155
+ # console-subscriber = "0.2"
156
+
157
+ # In main.rs:
158
+ # console_subscriber::init();
159
+
160
+ # Build with tokio_unstable:
161
+ RUSTFLAGS="--cfg tokio_unstable" cargo run
162
+
163
+ # In another terminal:
164
+ tokio-console # connects to default port 6669
165
+ ```
166
+
167
+ Shows live tasks, their state, wake counts, poll durations, parent tasks. The single fastest way to find "why is my async thing stuck".
168
+
169
+ ---
170
+
171
+ ## cargo-expand — when a macro is suspect
172
+
173
+ ```bash
174
+ cargo install cargo-expand
175
+ cargo expand # expand all macros in the crate
176
+ cargo expand my::module::path # scope to one item
177
+ ```
178
+
179
+ If you suspect a macro (especially `#[derive]`, `#[tokio::main]`, `#[async_trait]`) is generating code that doesn't match your mental model, this shows you exactly what the compiler sees.
180
+
181
+ ---
182
+
183
+ ## Release-build gotcha
184
+
185
+ ```bash
186
+ cargo build --release # no debug symbols by default
187
+ ```
188
+
189
+ If the bug only shows up in `--release`:
190
+
191
+ ```toml
192
+ # Cargo.toml
193
+ [profile.release]
194
+ debug = true # add symbols, keep optimizations
195
+ ```
196
+
197
+ Now `rust-gdb ./target/release/my_binary` works on release builds. This is required when optimization-enabled codegen bugs (inlining, LLVM folding) are suspected.
198
+
199
+ ---
200
+
201
+ ## Silent-failure patterns in Rust
202
+
203
+ | Pattern | Why it's silent |
204
+ |---|---|
205
+ | `.unwrap_or_default()` | Masks errors as the zero value |
206
+ | `.unwrap_or(fallback)` | Same, with a specific fallback |
207
+ | `let _ = fallible_operation()` | Explicitly discards the Result, no compiler warning |
208
+ | `if let Ok(x) = ... { use(x); } // no else` | Silent on Err |
209
+ | `.ok()` chaining | Converts Result to Option, throwing the error away |
210
+ | Panic inside a tokio task not `.await`ed | Task dies silently; runtime usually logs but it's quiet if logs are off |
211
+ | `eprintln!` that goes to a redirected-null stderr | Looks like nothing happened |
212
+ | `Drop` impl that panics under specific condition | Double-panic aborts process silently if no logging configured |
213
+
214
+ ---
215
+
216
+ ## Phase 9 cleanup specifics
217
+
218
+ ```bash
219
+ # Revert dbg! macro additions
220
+ git diff | grep -E 'dbg!\('
221
+ # For any file with dbg! additions:
222
+ git checkout <file>
223
+
224
+ # Unset env vars
225
+ unset RUST_LOG RUST_BACKTRACE
226
+
227
+ # Kill any rust-gdb/lldb sessions
228
+ pkill -f 'rust-gdb' || true
229
+ pkill -f 'rust-lldb' || true
230
+ pkill -f '^lldb ' || true
231
+
232
+ # tokio-console binds 6669 by default
233
+ lsof -iTCP:6669 -sTCP:LISTEN -nP 2>/dev/null
234
+ ```
@@ -0,0 +1,212 @@
1
+ # Ghidra — Decompile Binaries Into Readable C
2
+
3
+ **https://github.com/NationalSecurityAgency/ghidra**
4
+
5
+ Ghidra is the NSA's open-source reverse-engineering suite. Its defining feature is a **decompiler** that turns machine code back into readable C. For any binary you don't have source for, this is the correct starting point — not `strings`, not hex-staring, not `objdump -d`.
6
+
7
+ **Use Ghidra when**: third-party closed-source libs, malware analysis, vendored binaries whose behavior contradicts docs, CTF challenges, firmware, any time you need to read compiled code.
8
+
9
+ ---
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ # macOS
15
+ brew install --cask ghidra
16
+ # OR download the release ZIP from the repo and ./ghidraRun
17
+
18
+ # Linux
19
+ # Download from https://github.com/NationalSecurityAgency/ghidra/releases
20
+ # Requires JDK 21+
21
+ ./ghidraRun
22
+
23
+ # Dependency
24
+ java -version # must be 21+
25
+ ```
26
+
27
+ Ghidra is a Java Swing app. Looks dated, works well.
28
+
29
+ ---
30
+
31
+ ## First-time workflow (memorize this — it's not obvious)
32
+
33
+ 1. **Start Ghidra**: `ghidraRun`
34
+ 2. **Create a project**: File → New Project → Non-Shared → name it `debug-<binary-name>` (journal this path so you can rm it at Phase 9 if disposable).
35
+ 3. **Import the binary**: File → Import File → pick your target. Accept default format detection.
36
+ 4. **Double-click the imported binary** in the project listing. Ghidra asks to analyze it — say **yes**, accept defaults for the first pass. This takes anywhere from seconds (small binary) to tens of minutes (large binary).
37
+ 5. **Once analysis completes**, you're in the CodeBrowser view.
38
+
39
+ Two panels you'll use 95% of the time:
40
+
41
+ - **Listing** (middle) — the disassembly with Ghidra's inferred labels/types.
42
+ - **Decompiler** (right) — the reconstructed C. The real value.
43
+
44
+ ---
45
+
46
+ ## Finding the right function fast
47
+
48
+ Don't try to read the whole binary. Use these to narrow:
49
+
50
+ ### Symbol Tree (left panel)
51
+
52
+ - `Functions` — all detected functions. Stripped binaries show `FUN_00401234` (address-named); unstripped show actual names.
53
+ - `Imports` — dynamically-linked functions. Great for "does this binary call `system()`, `strcpy`, `curl_easy_perform`?"
54
+ - `Exports` — if it's a library.
55
+
56
+ Click to jump. The Decompiler updates instantly.
57
+
58
+ ### String search
59
+
60
+ ```
61
+ Search → For Strings
62
+ ```
63
+
64
+ Produces a list of all strings. Right-click a string → `References` → `Show References to Address`. Jumps to code that references it. **This is how you find which function handles the error message you saw at runtime.**
65
+
66
+ ### Memory search for bytes
67
+
68
+ ```
69
+ Search → Memory
70
+ ```
71
+
72
+ Search hex or text. Useful for known magic bytes, file-format signatures, constants.
73
+
74
+ ### Cross-references (XREF)
75
+
76
+ Right-click any function / address → `References → Find References to`. Shows every place that calls it. Walk the call graph backward from interesting functions.
77
+
78
+ ---
79
+
80
+ ## Making the decompiler's output readable
81
+
82
+ Ghidra's decompiler is good but needs hints. These three actions dramatically improve its output:
83
+
84
+ ### 1. Rename variables
85
+
86
+ Click a variable in the Decompiler view → press `L` → type a better name. Ghidra propagates the rename across all uses.
87
+
88
+ ### 2. Set types
89
+
90
+ A variable that looks like `undefined4` or `void *` is unhelpful. Click it → press `Ctrl+L` → set type (e.g. `int`, `char *`, `struct my_header *`).
91
+
92
+ For pointers to structs from headers you have, use:
93
+ ```
94
+ File → Parse C Source → paste header file → auto-creates struct types
95
+ ```
96
+
97
+ Then assign the struct type to the pointer. Ghidra resolves field accesses immediately.
98
+
99
+ ### 3. Retype function signatures
100
+
101
+ Click the function name in the Decompiler → press `F` (Edit Function Signature) → set return type + argument types. This propagates through callers.
102
+
103
+ Do these three actions on the 3-5 most relevant functions and the decompiler output becomes near-source-readable.
104
+
105
+ ---
106
+
107
+ ## Patterns for specific bug types
108
+
109
+ ### Looking for integer overflow / buffer overflow
110
+
111
+ ```
112
+ Listing: look for
113
+ - LEA → CMP patterns on sizes
114
+ - memcpy/strcpy/sprintf with non-constant sizes
115
+ Decompiler: look for
116
+ - arithmetic on size_t without bounds check
117
+ - `+ user_input` in a length calculation
118
+ ```
119
+
120
+ ### Looking for a missing auth check
121
+
122
+ Navigate from the handler entry (found via Strings or Imports) and check the control flow:
123
+
124
+ ```
125
+ Decompiler: does the function return early / jump to error handler when some flag is not set?
126
+ If the check is absent, that's the bug.
127
+ ```
128
+
129
+ ### Looking for hardcoded URLs / keys / paths
130
+
131
+ ```
132
+ Search → For Strings → filter `http:` / `https:` / `/etc/` / `bearer ` / `api_key`
133
+ ```
134
+
135
+ ### Looking for dispatch / plugin loading
136
+
137
+ ```
138
+ Imports → dlopen, LoadLibrary, dlsym, GetProcAddress
139
+ ```
140
+
141
+ The strings referenced near those calls are often plugin names.
142
+
143
+ ---
144
+
145
+ ## Scripting (headless Ghidra)
146
+
147
+ When you need to automate analysis across many binaries, or repeat a workflow:
148
+
149
+ ```bash
150
+ # Headless analyzer
151
+ $GHIDRA_INSTALL_DIR/support/analyzeHeadless \
152
+ <project-dir> <project-name> \
153
+ -import <binary> \
154
+ -postScript <script.py or script.java>
155
+ ```
156
+
157
+ Ghidra supports Python 3 scripts (via Jython-compatible API) and Java. Useful scripts:
158
+
159
+ - Dump all function signatures to JSON
160
+ - Find all calls to `system()` with constant arguments
161
+ - Auto-rename FUN_xxx based on heuristics (string refs, call patterns)
162
+
163
+ The community has a large collection: https://github.com/NationalSecurityAgency/ghidra/tree/master/Ghidra/Features/Base/ghidra_scripts
164
+
165
+ ---
166
+
167
+ ## Bookmarks + Notes
168
+
169
+ Ghidra has built-in bookmarks and comments. Use them as your journal inside the project:
170
+
171
+ - Right-click an address → `Set Bookmark` → tag as `Note`. Attach a description.
172
+ - Right-click → `Comments → Set EOL Comment` (shows up inline in decompiler).
173
+
174
+ Treat these as part of the journal. If you end up promoting this Ghidra project (keeping it after the debug session), the comments become durable documentation.
175
+
176
+ ---
177
+
178
+ ## Gotchas
179
+
180
+ - **Large binaries need more Java heap.** Edit `support/launch.properties` and bump `VMARGS=-Xmx8G` (default is often 2G, too small).
181
+ - **Save often.** Ghidra's autosave is not instant; a crash loses uncommitted analysis.
182
+ - **Decompiler has timeouts.** For complex functions it may give up and print `/* WARNING: ... */`. Increase timeout in `Edit → Tool Options → Decompiler`.
183
+ - **Archs beyond x86/ARM/MIPS** sometimes need Sleigh processor module tweaks. Rare but possible.
184
+ - **Signed vs unsigned decompilation** is frequently wrong. Manually retype when integer behavior matters.
185
+
186
+ ---
187
+
188
+ ## When Ghidra is NOT the right tool
189
+
190
+ - You have the source. Go read it.
191
+ - Bug is in your own recently-compiled binary. Rebuild with `-g` and use gdb/pwndbg (see [pwndbg.md](pwndbg.md)).
192
+ - You just need to know which libs a binary links. `ldd` / `otool -L` / `readelf -d` are faster.
193
+ - You just need strings. `strings -n 8` is faster.
194
+
195
+ Ghidra is the right tool when you need to **read the logic** of a binary you don't have source for.
196
+
197
+ ---
198
+
199
+ ## Phase 9 cleanup specifics
200
+
201
+ ```bash
202
+ # If you created a scratch project just for this debug session, journal path and remove:
203
+ # (the journal should have the exact path)
204
+ # Example:
205
+ ls ~/ghidra-projects/ 2>/dev/null
206
+ # rm -rf ~/ghidra-projects/debug-<binary-name>
207
+
208
+ # If you promoted the project (kept it), it's not cleanup — note it in the final summary to the user
209
+
210
+ # Kill any running Ghidra headless processes
211
+ pkill -f 'analyzeHeadless' || true
212
+ ```
@@ -0,0 +1,194 @@
1
+ # Playwright CLI — Browser QA That Actually Drives a Browser
2
+
3
+ **https://playwright.dev/ · https://github.com/microsoft/playwright**
4
+
5
+ For any browser-served web UI bug, this is the correct tool. Not curl. Not imagination. Not a headless HTTP library. A real browser with a real rendering engine, real JS execution, real cookies, real service workers, real viewport.
6
+
7
+ **In Phase 8 Manual QA for browser products, using Playwright is not optional.** Curl cannot catch: CSS that breaks at specific viewport widths, hydration mismatches, client-side router bugs, cookie/session interactions, service-worker caching, JS-triggered navigations. All of those are common bug classes. Drive a browser.
8
+
9
+ > Note: `microsoft/playwright-cli` is the legacy repo; the current tooling lives in `@playwright/test` (npm) and `playwright` (pip), which include the `playwright` CLI. Use those — the legacy `playwright-cli` package is deprecated.
10
+
11
+ ---
12
+
13
+ ## When to reach for Playwright
14
+
15
+ | Bug symptom | Use Playwright? |
16
+ |---|---|
17
+ | Form submit produces wrong result | ✅ — Playwright drives the form exactly as a user does |
18
+ | Page blank in prod, fine locally | ✅ — hydration/env differences need a real browser |
19
+ | CSS looks wrong at a specific width | ✅ — use `--viewport-size` |
20
+ | Click doesn't fire / wrong handler | ✅ — Playwright fires real DOM events |
21
+ | Flash of unstyled content / loading glitch | ✅ — use trace viewer to see frames |
22
+ | API returns wrong data | ❌ — use curl, this isn't a browser bug |
23
+ | Backend returns wrong status code | ❌ — use curl |
24
+ | Client hits a URL that returns 500 | ✅ but also ❌ — Playwright shows the call + response + failure effect on UI |
25
+
26
+ ---
27
+
28
+ ## Install (per-project)
29
+
30
+ Playwright installs browser binaries separately from the npm package.
31
+
32
+ ```bash
33
+ # In the project
34
+ npm init playwright@latest # interactive; picks TS/JS + browsers + config
35
+ # Or if Playwright is already a dep:
36
+ npx playwright install # downloads browsers
37
+ npx playwright install chromium # just chromium
38
+ npx playwright install --with-deps # also installs OS deps (Linux)
39
+ ```
40
+
41
+ Python:
42
+ ```bash
43
+ pip install playwright
44
+ playwright install
45
+ ```
46
+
47
+ ---
48
+
49
+ ## The four things you'll actually use
50
+
51
+ ### 1. `codegen` — record a session, generate the script
52
+
53
+ The fastest way to create a repro. Opens a real browser; your clicks / typing become a Playwright script you can paste into a test.
54
+
55
+ ```bash
56
+ npx playwright codegen https://your-app.local
57
+ npx playwright codegen --viewport-size=375,667 https://your-app.local # iPhone SE size
58
+ npx playwright codegen --device="iPhone 14" https://your-app.local
59
+ ```
60
+
61
+ Click / type / navigate in the browser; watch the script build in the side panel. Copy the generated script into your journal as the repro for Phase 8.
62
+
63
+ ### 2. A one-shot Playwright script — reproduce + capture
64
+
65
+ Usually the Phase 8 QA artifact. Save to `/tmp/debug-repro.spec.ts` (journal it):
66
+
67
+ ```ts
68
+ // /tmp/debug-repro.spec.ts
69
+ import { test, expect } from '@playwright/test';
70
+
71
+ test('refinement chat shows non-empty response when env var set', async ({ page }) => {
72
+ await page.goto('http://localhost:3000/chat');
73
+ await page.fill('textarea[name="message"]', 'Add a logging step');
74
+ await page.click('button[type=submit]');
75
+
76
+ // Wait for the response to appear (not just the spinner to disappear)
77
+ const response = page.locator('[data-testid="assistant-reply"]');
78
+ await expect(response).toBeVisible({ timeout: 30_000 });
79
+ await expect(response).not.toBeEmpty();
80
+
81
+ // Capture evidence
82
+ await page.screenshot({ path: '/tmp/debug-after-fix.png', fullPage: true });
83
+ console.log(await response.textContent());
84
+ });
85
+ ```
86
+
87
+ Run it with tracing enabled for rich post-mortem:
88
+
89
+ ```bash
90
+ npx playwright test /tmp/debug-repro.spec.ts --trace on --headed
91
+ ```
92
+
93
+ ### 3. `PWDEBUG=1` — step through the script with Playwright Inspector
94
+
95
+ ```bash
96
+ PWDEBUG=1 npx playwright test /tmp/debug-repro.spec.ts
97
+ ```
98
+
99
+ Opens the Playwright Inspector alongside the browser. You can step through Playwright actions, see the DOM state at each step, and edit selectors on the fly.
100
+
101
+ Use this when the script doesn't reproduce cleanly and you need to watch it run.
102
+
103
+ ### 4. `show-trace` — post-mortem on a failed run
104
+
105
+ ```bash
106
+ npx playwright show-trace trace.zip
107
+ # or from the test-results dir:
108
+ npx playwright show-trace test-results/<test-name>/trace.zip
109
+ ```
110
+
111
+ Scrubs through a recorded session: timeline, DOM snapshot at each action, network, console, source. When a test failed on CI but passed locally, this is the single best artifact.
112
+
113
+ ---
114
+
115
+ ## Headless vs headed during debugging
116
+
117
+ Always add `--headed` when debugging. Headless browsers sometimes behave subtly differently (font rendering, viewport, media permissions). For QA evidence, run headed and screenshot.
118
+
119
+ ```bash
120
+ npx playwright test --headed
121
+ npx playwright test --headed --project=chromium # pin the browser
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Catching the silent-failure patterns Playwright is good at
127
+
128
+ ```ts
129
+ // Toast that flashes and disappears
130
+ page.on('console', msg => console.log('[browser console]', msg.type(), msg.text()));
131
+
132
+ // Unhandled page errors (uncaught exceptions in the page JS)
133
+ page.on('pageerror', err => console.error('[page error]', err));
134
+
135
+ // Network failures — e.g., backend returned 500 but UI shows nothing
136
+ page.on('response', async resp => {
137
+ if (!resp.ok()) {
138
+ console.warn(`[network ${resp.status()}] ${resp.url()} — ${await resp.text()}`);
139
+ }
140
+ });
141
+
142
+ // Request that never came back
143
+ page.on('requestfailed', req => {
144
+ console.error('[request failed]', req.url(), req.failure()?.errorText);
145
+ });
146
+ ```
147
+
148
+ Add these listeners to the top of the debug script. They surface a lot of the "UI showed nothing" class of bug.
149
+
150
+ ---
151
+
152
+ ## Viewport and device emulation
153
+
154
+ CSS bugs that only appear at specific sizes, or layout bugs on mobile:
155
+
156
+ ```ts
157
+ // At test level
158
+ test.use({ viewport: { width: 375, height: 667 } });
159
+
160
+ // Per-page
161
+ await page.setViewportSize({ width: 375, height: 667 });
162
+
163
+ // Predefined devices
164
+ import { devices } from '@playwright/test';
165
+ test.use({ ...devices['iPhone 14'] });
166
+ ```
167
+
168
+ ---
169
+
170
+ ## Gotchas
171
+
172
+ - **Wait for state, not for time.** `await page.waitForTimeout(2000)` is flaky. Use `await expect(locator).toBeVisible()` or `page.waitForResponse(urlPattern)`.
173
+ - **Stale selectors re-resolve.** Playwright's locators re-find the element on each action, unlike Puppeteer's handles. Don't over-think it.
174
+ - **Service workers persist across test runs in headed mode.** If you see cached behavior from a previous run, add `await context.clearCookies()` + clear storage before the test.
175
+ - **Installing on CI requires `--with-deps`** on Linux images that lack the browser's shared-library deps.
176
+ - **Parallel tests share a browser process by default**; if one test polls a debugger port, others may interfere. Use `workers: 1` for debugging.
177
+
178
+ ---
179
+
180
+ ## Phase 9 cleanup specifics
181
+
182
+ ```bash
183
+ # Remove trace files from debug runs
184
+ rm -rf playwright-report/ test-results/ trace.zip
185
+
186
+ # Remove debug spec files from /tmp
187
+ rm -f /tmp/debug-*.spec.ts
188
+
189
+ # Remove screenshot captures
190
+ rm -f /tmp/debug-*.png
191
+
192
+ # If you installed browsers just for this session (rare):
193
+ # Don't remove them — they're useful for future sessions. They live in ~/Library/Caches/ms-playwright (macOS) or ~/.cache/ms-playwright (Linux).
194
+ ```