@tw93/waza 3.25.0

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 (68) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +206 -0
  3. package/package.json +35 -0
  4. package/rules/anti-patterns.md +38 -0
  5. package/rules/chinese.md +18 -0
  6. package/rules/durable-context.md +27 -0
  7. package/rules/english.md +14 -0
  8. package/scripts/build_metadata.py +360 -0
  9. package/scripts/check_routing_drift.py +82 -0
  10. package/scripts/dispatcher-template.md +43 -0
  11. package/scripts/dispatcher.md +53 -0
  12. package/scripts/package-skill.sh +71 -0
  13. package/scripts/packaging_filter.py +55 -0
  14. package/scripts/setup-rule.sh +109 -0
  15. package/scripts/setup-statusline.sh +127 -0
  16. package/scripts/skill_checks.py +483 -0
  17. package/scripts/skill_frontmatter.py +110 -0
  18. package/scripts/statusline.sh +321 -0
  19. package/scripts/validate_package.py +66 -0
  20. package/scripts/verify_skills.py +100 -0
  21. package/skills/RESOLVER.md +91 -0
  22. package/skills/check/SKILL.md +338 -0
  23. package/skills/check/agents/reviewer-architecture.md +39 -0
  24. package/skills/check/agents/reviewer-security.md +39 -0
  25. package/skills/check/references/persona-catalog.md +56 -0
  26. package/skills/check/references/project-context.md +107 -0
  27. package/skills/check/references/public-reply.md +14 -0
  28. package/skills/check/scripts/audit_signals.py +485 -0
  29. package/skills/check/scripts/run-tests.sh +19 -0
  30. package/skills/design/SKILL.md +134 -0
  31. package/skills/design/references/design-aesthetic-quality.md +67 -0
  32. package/skills/design/references/design-data-viz.md +34 -0
  33. package/skills/design/references/design-reference.md +278 -0
  34. package/skills/design/references/design-tokens.md +53 -0
  35. package/skills/design/references/design-traps.md +43 -0
  36. package/skills/health/SKILL.md +231 -0
  37. package/skills/health/agents/inspector-context.md +119 -0
  38. package/skills/health/agents/inspector-control.md +84 -0
  39. package/skills/health/agents/inspector-maintainability.md +55 -0
  40. package/skills/health/scripts/check-agent-context.sh +5 -0
  41. package/skills/health/scripts/check-doc-refs.sh +8 -0
  42. package/skills/health/scripts/check-maintainability.sh +8 -0
  43. package/skills/health/scripts/check-verifier-output.sh +5 -0
  44. package/skills/health/scripts/check_agent_context.py +407 -0
  45. package/skills/health/scripts/check_doc_refs.py +110 -0
  46. package/skills/health/scripts/check_maintainability.py +629 -0
  47. package/skills/health/scripts/check_verifier_output.py +116 -0
  48. package/skills/health/scripts/collect-data.sh +760 -0
  49. package/skills/hunt/SKILL.md +197 -0
  50. package/skills/hunt/references/failure-patterns.md +75 -0
  51. package/skills/hunt/references/ime-unicode.md +58 -0
  52. package/skills/hunt/references/logging-techniques.md +72 -0
  53. package/skills/hunt/references/rendering-debug.md +34 -0
  54. package/skills/learn/SKILL.md +128 -0
  55. package/skills/read/SKILL.md +108 -0
  56. package/skills/read/references/read-methods.md +110 -0
  57. package/skills/read/references/save-paths.md +33 -0
  58. package/skills/read/scripts/fetch.sh +105 -0
  59. package/skills/read/scripts/fetch_feishu.py +246 -0
  60. package/skills/read/scripts/fetch_local.py +218 -0
  61. package/skills/read/scripts/fetch_weixin.py +107 -0
  62. package/skills/think/SKILL.md +155 -0
  63. package/skills/write/SKILL.md +129 -0
  64. package/skills/write/references/write-en.md +197 -0
  65. package/skills/write/references/write-zh-bilingual.md +60 -0
  66. package/skills/write/references/write-zh-prose.md +48 -0
  67. package/skills/write/references/write-zh-release-notes.md +38 -0
  68. package/skills/write/references/write-zh.md +645 -0
@@ -0,0 +1,197 @@
1
+ ---
2
+ name: hunt
3
+ description: "Finds root cause before applying fixes for errors, crashes, regressions, failing tests, broken behavior, and screenshot-reported defects. Use when users ask 排查/报错/崩溃/不工作/回归/判断为什么报错, or say something used to work and now fails. Not for code review or new features."
4
+ when_to_use: "排查, 查查, 报错, 崩溃, 不工作, 不对, 跑不通, 以前是好的, 回归, 截图回归, 判断错误原因, 判断为什么报错, 反复修不好, debug, regression, used to work, broke after update, why broken, not working, what's wrong, fix error, stack trace"
5
+ dispatch_intent: "Error, crash, regression, screenshot-reported defect, test failure, stale cache, runtime boundary, why broken"
6
+ ---
7
+
8
+ # Hunt: Diagnose Before You Fix
9
+
10
+ Prefix your first line with 🥷 inline, not as its own paragraph.
11
+
12
+ A patch applied to a symptom creates a new bug somewhere else.
13
+
14
+ **Do not touch code until you can state the root cause in one sentence:**
15
+ > "I believe the root cause is [X] because [evidence]."
16
+
17
+ Name a specific file, function, line, or condition. "A state management issue" is not testable. "Stale cache in `useUser` at `src/hooks/user.ts:42` because the dependency array is missing `userId`" is testable. If you cannot be that specific, you do not have a hypothesis yet.
18
+
19
+ ## Diagnosis Signals
20
+
21
+ Good progress: a log line matches the hypothesis, you can predict the next error before running it, you understand the propagation path from root cause to symptom, you can write a test that fails on the old code. At each of these signals, find one more independent piece of evidence before committing.
22
+
23
+ Hypothesis quality gate: before acting on a hypothesis, list all observable symptoms (not just the one the user reported first). The hypothesis must explain every symptom; if it only covers some, it is a symptom-level guess, not a root cause. For timing-dependent issues (flicker, intermittent failure, race condition), reproduce reliably before diagnosing.
24
+
25
+ Rationalization warning: "I'll just try this" means no hypothesis, write it first. "I'm confident" means run an instrument that proves it. "Probably the same issue" means re-read the execution path from scratch. "It works on my machine" means enumerate every env difference before dismissing. "One more restart" means read the last error verbatim; never restart more than twice without new evidence.
26
+
27
+ ## Durable Context Preflight
28
+
29
+ See [rules/durable-context.md](../../rules/durable-context.md) for when to read durable context, the read-order budget, and the memory-type mapping.
30
+
31
+ For `/hunt`, diagnostic constraints are `decision`, `preference`, and `principle` entries; `pattern` and `learning` can seed hypotheses. Current code, logs, repro steps, tests, environment versions, and remote state override memory. Durable context is hypothesis fuel only. It never replaces a fresh root-cause sentence, a reproducible symptom list, or evidence from the current state.
32
+
33
+ ## Hard Rules
34
+
35
+ - **Same symptom after a fix is a hard stop; so is "let me just try this."** Both mean the hypothesis is unfinished. Re-read the execution path from scratch before touching code again.
36
+ - **After three failed hypotheses, stop.** Use the Handoff format below to surface what was checked, what was ruled out, and what is unknown. Ask how to proceed.
37
+ - **Verify before claiming.** Never state versions, function names, or file locations from memory. Run `sw_vers` / `node --version` / grep first. No results = re-examine the path.
38
+ - **External tool failure: diagnose before switching.** When an MCP tool or API fails, determine why first (server running? API key valid? Config correct?) before trying an alternative.
39
+ - **Pay attention to deflection.** When someone says "that part doesn't matter," treat it as a signal. The area someone avoids examining is often where the problem lives.
40
+ - **Visual/rendering bugs: static analysis first.** Trace paint layers, stacking contexts, and layer order in DevTools before adding console.log or visual debug overlays. Logs cannot capture what the compositor does. Only add instrumentation after static analysis fails.
41
+ - **Fix the cause, not the symptom.** If the fix touches more than 5 files, pause and confirm scope with the user.
42
+
43
+ ## Fix Scope Discipline
44
+
45
+ If the bug genuinely needs a refactor first (e.g. the cause cannot be addressed without changing a shared interface), pause, name the refactor explicitly, and ask. Do not silently bundle it. A bug fix that grew into a refactor is a separate PR.
46
+
47
+ ## Bisect Mode
48
+
49
+ Activate when: "以前是好的", "之前是好的", "used to work", "上一次提交还是对的", "broke after update", or the user remembers a specific good commit or version.
50
+
51
+ 1. Find candidate good tag: `git tag --sort=-version:refname | head -10` or ask the user for the last known-good commit.
52
+ 2. Define a non-interactive pass/fail test command before starting bisect. Bisect is worthless without a reproducible check.
53
+ 3. Run: `git bisect start && git bisect bad HEAD && git bisect good <tag-or-hash>`
54
+ 4. At each step bisect checks out a commit. Run the test command. Mark: `git bisect good` or `git bisect bad`.
55
+ 5. Let bisect drive. Do not jump ahead or skip commits unless explicitly asked.
56
+ 6. When bisect names the culprit commit, read only that diff. Identify the specific line that introduced the regression.
57
+ 7. Run `git bisect reset` when done.
58
+
59
+ Read large files once and reference from notes rather than re-reading at each bisect step.
60
+
61
+ ## Repeated Regression / Screenshot Reference Mode
62
+
63
+ Activate when the user says the same issue is still wrong after a fix, provides a "good" screenshot/version/file, or describes a visual result as previously correct.
64
+
65
+ Treat the reference as evidence, not decoration:
66
+
67
+ 1. List every reported and visible symptom, preserving the user's concrete words where useful ("still slow", "not clear", "尖刺", "先显示上一个内容").
68
+ 2. Identify the reference oracle: last-good commit/tag, old build, fixture, screenshot, downloaded artifact, or expected state from the user's description.
69
+ 3. Define the pass/fail check before editing. For visual bugs, this may be a narrow screenshot checklist plus the command that renders the view; for behavioral bugs, prefer an automated regression test or deterministic repro.
70
+ 4. Compare current vs. reference and name the exact delta. Do not generalize a visual defect into "style polish" when the evidence points to a broken render, race, font pipeline, or state path.
71
+ 5. If the same symptom remains after one attempted fix, stop and rebuild the hypothesis from the evidence. Do not stack more patches onto a disproven explanation.
72
+
73
+ If the issue is purely subjective UI taste, route to `/design`. If it is rendering, state, timing, build output, font generation, or a regression from a known-good version, stay in `/hunt`.
74
+
75
+ ## Scope Blast Mode
76
+
77
+ Activate after fixing a root-cause pattern, before declaring the bug done; also when the user says "举一反三", "举一反三深入看看", or "其他地方有没有同样问题". The same shape often hides in N other places; one local fix that ignores the blast leaves N - 1 bugs in the tree.
78
+
79
+ 1. Extract the pattern signature: the specific function name, regex, API call, CSS selector, lock acquisition, validation skip, or input boundary that produced the bug.
80
+ 2. `grep -rn <pattern>` across the repo (exclude generated dirs, build output, vendored deps). For class-of-bug patterns (e.g. "any handler missing the lock"), grep for the surrounding shape, not just the literal text.
81
+ 3. List every match. For each one, answer in writing: same bug here? Pick fix / leave (explain why it is safe) / unsure (ask the user). Do not silently skip a match.
82
+ 4. Do not claim "fixed" until the blast report is in the Outcome block.
83
+
84
+ Common triggers:
85
+ - Visual bug fixed on one page: check every other page using the same component, layout, or media-query breakpoint.
86
+ - One race fixed in one handler: check every handler acquiring the same lock or touching the same shared state.
87
+ - One validation skip patched at one entry point: check every entry point that reaches the same downstream sink.
88
+ - One regex / parser fix for one input shape: check every caller of the same regex / parser.
89
+
90
+ If the blast surfaces unrelated bugs, list them but do not fix in this PR unless the user agrees; scope creep is its own anti-pattern.
91
+
92
+ ## Confirm or Discard
93
+
94
+ Add one targeted instrument: a log line, a failing assertion, or the smallest test that would fail if the hypothesis is correct. Run it. If the evidence contradicts the hypothesis, discard it completely and re-orient with what was just learned. Do not preserve a hypothesis the evidence disproves.
95
+
96
+ ## Runtime Evidence Ladder
97
+
98
+ Use this ladder before claiming a bug is fixed:
99
+
100
+ 1. Source trace: name the exact function, state transition, file, line, or condition that can produce the symptom.
101
+ 2. Deterministic repro: run or write the smallest command, fixture, UI path, or scenario that produces it.
102
+ 3. Logs/state/cache: inspect the runtime state that proves the path was reached, including queues, DB rows, caches, temp files, generated outputs, or external tool logs.
103
+ 4. Build/test: run the narrow test or build that exercises the fix.
104
+ 5. Real runtime check: for UI, native app, browser, rendering, or visual bugs, open the app/page/artifact and verify the visible result with a screenshot or concrete checklist.
105
+
106
+ Compile-only is not enough for UI, native-app, visual, rendering, or generated-artifact bugs. If the runtime check is impossible in the environment, say why and hand off the exact screen, command, or artifact to verify.
107
+
108
+ For recurring classes of failures, load `references/failure-patterns.md` before adding a second fix.
109
+
110
+ ## Targeted Logging
111
+
112
+ Use logs as a scalpel, not as noise. Before adding a log, write the question it answers:
113
+
114
+ > "If this log prints X before Y, hypothesis A is still possible; if it does not, hypothesis A is wrong."
115
+
116
+ Load `references/logging-techniques.md` for the full logging playbook: binary-search instrumentation, discriminating log content, boundary-first placement, timing bug logging, and removal discipline.
117
+
118
+ Quick rules:
119
+ 1. Place the first log at the midpoint of the execution path, not at the symptom. Binary search from there.
120
+ 2. Log discriminating facts only: sequence number, input key, branch taken, old/new state, error code.
121
+ 3. Remove temporary logs before finishing. Gate persistent diagnostics behind the project's debug flag.
122
+
123
+ If adding logs changes the behavior, treat that as evidence of a timing, lifecycle, or concurrency problem.
124
+
125
+ ## Gotchas
126
+
127
+ | What happened | Rule |
128
+ |---------------|------|
129
+ | Patched client pane instead of local pane | Trace the execution path backward before touching any file |
130
+ | MCP not loading, switched tools instead of diagnosing | Check server status, API key, config before switching methods |
131
+ | Orchestrator said RUNNING but TTS vendor was misconfigured | In multi-stage pipelines, test each stage in isolation |
132
+ | Race condition diagnosed as a stale-state bug | For timing-sensitive issues, inspect event timestamps and ordering before state |
133
+ | Added logs everywhere and still could not explain the bug | Rewrite each log as a yes/no question. Delete logs that do not rule a hypothesis in or out |
134
+ | Reproduced locally but failed in CI | Align the environment first (runtime version, env vars, timezone), then chase the code |
135
+ | Stack trace points deep into a library | Walk back 3 frames into your own code; the bug is almost always there, not in the dependency |
136
+ | Worked when launched from app, broke when opened via file association / drag-drop / deep link / external proxy | Reproduce using the exact entry point the user described. App-internal init differs from cold-launch-with-file init; state may not be ready when the document arrives. |
137
+ | Build passed but UI still looked wrong | Move up the Runtime Evidence Ladder and verify the real rendered surface or artifact. |
138
+
139
+ ## Outcome
140
+
141
+ ### Success Format
142
+
143
+ ```
144
+ Root cause: [what was wrong, file:line]
145
+ Fix: [what changed, file:line]
146
+ Confirmed: [evidence or test that proves the fix]
147
+ Tests: [pass/fail count, regression test location]
148
+ Regression guard: [test file:line] or [none, reason]
149
+ ```
150
+
151
+ Status: **resolved**, **resolved with caveats** (state them), or **blocked** (state what is unknown).
152
+
153
+ **Regression guard rule**: for any bug that recurred or was previously "fixed", the fix is not done until:
154
+ 1. A regression test exists that fails on the unfixed code and passes on the fixed code.
155
+ 2. The test lives in the project's test suite, not a temporary file.
156
+ 3. The commit message states why the bug recurred and why this fix prevents it.
157
+
158
+ ### Handoff Format (after 3 failed hypotheses)
159
+
160
+ ```
161
+ Symptom:
162
+ [Original error description, one sentence]
163
+
164
+ Hypotheses Tested:
165
+ 1. [Hypothesis 1] → [Test method] → [Result: ruled out because...]
166
+ 2. [Hypothesis 2] → [Test method] → [Result: ruled out because...]
167
+ 3. [Hypothesis 3] → [Test method] → [Result: ruled out because...]
168
+
169
+ Evidence Collected:
170
+ - [Log snippets / stack traces / file content]
171
+ - [Reproduction steps]
172
+ - [Environment info: versions, config, runtime]
173
+
174
+ Ruled Out:
175
+ - [Root causes that have been eliminated]
176
+
177
+ Unknowns:
178
+ - [What is still unclear]
179
+ - [What information is missing]
180
+
181
+ Suggested Next Steps:
182
+ 1. [Next investigation direction]
183
+ 2. [External tools or permissions that may be needed]
184
+ 3. [Additional context the user should provide]
185
+ ```
186
+
187
+ Status: **blocked**
188
+
189
+ ## Rendering Bug Mode
190
+
191
+ Activate when: "PDF looks wrong", "page break issue", "font not rendering", broken PDF output, or print layout wrong.
192
+
193
+ Load `references/rendering-debug.md` for the full diagnosis checklist (WeasyPrint quirks, font loading, page overflow, browser print CSS). Static analysis first, then reproduce if needed.
194
+
195
+ ## IME / Unicode Issues
196
+
197
+ For input method, character rendering, or text encoding bugs (IME state, cursor drift, emoji splitting, composition events), check `references/ime-unicode.md` first before forming a hypothesis.
@@ -0,0 +1,75 @@
1
+ # Failure Pattern Reference
2
+
3
+ Use this when a bug has repeated, a first fix did not hold, or the symptom smells like runtime state rather than local code syntax.
4
+
5
+ ## Stale Verifier Or Tool Cache
6
+
7
+ Signals: verifier output points at deleted temp worktrees, old generated files, or paths outside the current repo; rerunning after a clean checkout changes the file path but not the current code.
8
+
9
+ Checks:
10
+ - Confirm the reported path exists.
11
+ - Clear the tool cache only after proving the path is stale.
12
+ - Re-run the same verifier from the current repo root.
13
+
14
+ ## Worker Queue Or DB Boundary
15
+
16
+ Signals: UI says work is running but no worker processes it; logs show scheduler activity but no queued row; retry fixes one item but not the pipeline.
17
+
18
+ Checks:
19
+ - Trace request -> enqueue -> worker pickup -> persistence -> UI refresh.
20
+ - Inspect queue rows or job state directly.
21
+ - Add a regression test around the enqueue boundary, not only the worker body.
22
+
23
+ ## Generated Rebuild Boundary
24
+
25
+ Signals: source changed but generated output, app bundle, CLI artifact, archive, checksum, or release package still contains old behavior.
26
+
27
+ Checks:
28
+ - Identify the source-to-artifact rule.
29
+ - Verify the build system watches the source path.
30
+ - Inspect the generated artifact contents, not just the source diff.
31
+
32
+ ## Guard Lifetime Race
33
+
34
+ Signals: permission, auth, or state guard looks correct locally but a delayed callback, app relaunch, or alternate entry point bypasses it.
35
+
36
+ Checks:
37
+ - Trace guard creation, retention, invalidation, and every alternate entry point.
38
+ - Verify cold launch, warm launch, deep link/file open, and retry paths when applicable.
39
+ - Prefer explicit durable state over transient flags when the guard must survive relaunch.
40
+
41
+ ## Atomic Temp Filename
42
+
43
+ Signals: concurrent runs collide, cleanup removes the wrong file, or a partially written output is observed.
44
+
45
+ Checks:
46
+ - Use unique temp directories or atomic rename.
47
+ - Keep cleanup scoped to files created by the current run.
48
+ - Test two concurrent or back-to-back runs when the tool supports it.
49
+
50
+ ## Path, Cwd, Or Symlink Escape
51
+
52
+ Signals: an operation intended for one root touches a sibling directory, follows a symlink unexpectedly, or behaves differently from another working directory.
53
+
54
+ Checks:
55
+ - Resolve and compare canonical roots before writing or deleting.
56
+ - Reject paths outside the allowed root after symlink resolution.
57
+ - Reproduce from a non-default cwd and through any UI entry point that supplies paths.
58
+
59
+ ## Snapshot Rebuild Drops Carried Field
60
+
61
+ Signals: live data shows up at the data source and on the wire but a downstream view sees it empty; the field has a default value (`var x: [T] = []`, `var y: Int? = nil`) that lets memberwise init compile without it; the symptom appears only on the path where the snapshot is rebuilt (icon resolution, decoration, redaction), not on a fresh fetch.
62
+
63
+ Checks:
64
+ - Trace whether every code path that constructs the snapshot type passes the field. The Swift compiler does not warn on default-value omission in memberwise init.
65
+ - Add a unit test that fetches the snapshot, runs the rebuild path, and asserts the carried field equals the input.
66
+ - Prefer `with(...)` mutating helpers or `inout` mutation over fresh memberwise init when only one field is changing.
67
+
68
+ ## Multi-Sample Command Cold Start
69
+
70
+ Signals: a CLI tool that takes `-l N` / `--samples N` / `--repeat N` returns one block of zeros and one block of real data; aggregating all blocks yields zeros; only the second sample carries real measurements.
71
+
72
+ Checks:
73
+ - Read the tool's man page for cold-start semantics. `top -l 2`, `iostat -d 2`, `vm_stat 1 2`, etc. all share this shape.
74
+ - Slice the output to the latest sample (`.suffix(perSampleSize)` on parsed lines, or look for the second instance of the header row).
75
+ - When in doubt, raise `-l` to 3 and confirm sample 2 and 3 agree; sample 1 stays zero.
@@ -0,0 +1,58 @@
1
+ # IME / Unicode Debugging Reference
2
+
3
+ Recurring patterns in Tauri and native macOS apps. Check these before forming a hypothesis.
4
+
5
+ ## IME State Desync
6
+
7
+ **Symptom**: Latin characters appear correctly but CJK input is dropped, doubled, or committed at the wrong time.
8
+
9
+ **Cause candidates**:
10
+ - Input method switch mid-composition: the IME commits the preedit with a stale target, then the new mode processes the same keystrokes again.
11
+ - `keydown` handler consuming events during active composition: check `event.isComposing` before acting on `keydown`/`keyup`. If `isComposing` is true, defer the action until `compositionend`.
12
+ - Webview + native frame split focus: in Tauri, the webview and the native window title bar can hold focus simultaneously. A click on a native control during IME composition triggers a focus-out, committing incomplete preedit text.
13
+
14
+ **Instruments**:
15
+ - Log `compositionstart`, `compositionupdate`, `compositionend` sequence; confirm they fire in order without gaps.
16
+ - Log the `data` field of each `compositionupdate`; a sudden empty string signals a forced commit.
17
+
18
+ ## Cursor Position Drift After IME Commit
19
+
20
+ **Symptom**: After confirming a CJK word, the cursor jumps to the wrong position or the selection collapses.
21
+
22
+ **Cause candidates**:
23
+ - DOM mutation during composition: React/Svelte/Vue re-rendering while `isComposing` is true will reset the selection. Batch state updates and flush only on `compositionend`.
24
+ - Counting bytes instead of code points in position math: CJK characters are multi-byte in UTF-8. Use `Array.from(str).length` or `[...str].length`, not `str.length`, for character-level offsets in positions.
25
+
26
+ ## Emoji ZWJ Sequence Splitting
27
+
28
+ **Symptom**: Multi-person or profession emoji (e.g. `👩‍🚒`) renders as two or three separate emoji, or the ZWJ (`U+200D`) appears as a visible character.
29
+
30
+ **Cause candidates**:
31
+ - String sliced at byte offset: `str.slice(0, n)` splits a ZWJ sequence if `n` falls inside the sequence. Use `Intl.Segmenter` with `granularity: 'grapheme'` to split at grapheme cluster boundaries.
32
+ - Font does not support the sequence: the font renders each code point individually. Verify with `canvas.measureText` or by checking which font is actually used via `document.fonts`.
33
+ - Serialization strips ZWJ: some JSON encoders normalize or escape `U+200D`. Verify the raw bytes of the stored string.
34
+
35
+ **Test**: `[...'👩‍🚒'].length` should be 1 (one grapheme cluster). If it returns 3, the runtime is iterating code points, not grapheme clusters.
36
+
37
+ ## `compositionend` / `keydown` Event Ordering
38
+
39
+ **Symptom**: The action bound to Enter or Tab fires during IME confirmation, submitting incomplete input.
40
+
41
+ **Cause**: On macOS + some IMEs, the sequence is `compositionend` → `keydown(Enter)`. On Windows + other IMEs it can be `keydown(Enter)` → `compositionend`. Code that blocks Enter only when `isComposing` is true will break on the macOS ordering because `isComposing` is already false when `keydown` fires.
42
+
43
+ **Fix**: Track composition state with a boolean flag set on `compositionstart`, cleared on `compositionend`. Guard the Enter handler with that flag rather than `event.isComposing`.
44
+
45
+ ## macOS Text System vs Webview Conflict
46
+
47
+ **Symptom**: Undo (`Cmd+Z`) reverts individual IME preedit characters instead of committed words, or system text shortcuts (Cmd+Shift+Left for word selection) behave differently inside vs outside the webview.
48
+
49
+ **Cause**: WKWebView has its own text system that partially overlaps with NSTextView conventions. Tauri's `preventDefaultFor` config can suppress system shortcuts; check `tauri.conf.json` (v1) or `app.json` (v2) for any `preventDefault` rules that may be too broad.
50
+
51
+ ## Quick Checklist
52
+
53
+ - [ ] `isComposing` checked before acting on keyboard events?
54
+ - [ ] No DOM mutation while `isComposing` is true?
55
+ - [ ] String position math uses grapheme clusters, not bytes or code points?
56
+ - [ ] ZWJ sequences verified with `Intl.Segmenter`?
57
+ - [ ] Enter/Tab guard uses a flag set by `compositionstart`, not `event.isComposing`?
58
+ - [ ] `tauri.conf.json` `preventDefaultFor` not too broad?
@@ -0,0 +1,72 @@
1
+ # Logging Techniques for Debugging
2
+
3
+ Use logs as a scalpel, not as noise. The goal is to answer a yes/no question about a hypothesis, not to dump state.
4
+
5
+ ## Binary Search Instrumentation
6
+
7
+ Place the first log at the midpoint of the execution path, not at the symptom. If it fires correctly, move downstream. If it does not fire, move upstream. This is binary search over the call graph.
8
+
9
+ ```
10
+ Entry → [midpoint log] → ... → symptom
11
+ ^
12
+ First log here, not at the symptom
13
+ ```
14
+
15
+ Repeat: each log cuts the remaining unknown path in half.
16
+
17
+ ## Log What Discriminates, Not What Is Convenient
18
+
19
+ Before adding a log, write the question it must answer:
20
+
21
+ > "If this prints X before Y, hypothesis A holds. If it prints Y first, A is wrong."
22
+
23
+ Discriminating log content:
24
+ - Sequence number or timestamp (ordering)
25
+ - Input identity key (which request/item)
26
+ - Branch taken (which `if` arm)
27
+ - Old vs. new state transition (not just new value)
28
+ - Error code plus context string (not just the exception message)
29
+
30
+ Never log: full request/response bodies, credentials, PII, or huge JSON blobs.
31
+
32
+ ## Log the Boundary, Not the Interior
33
+
34
+ Log at system boundaries where behavior should be predictable:
35
+
36
+ - Request handler entry/exit
37
+ - Cache read (hit or miss) with key
38
+ - State setter (old value, new value, caller)
39
+ - Async callback entry
40
+ - External API call result
41
+ - Build step start/end
42
+
43
+ Interior logs (inside tight loops or low-level helpers) are noise unless the hypothesis is specifically about that interior.
44
+
45
+ ## Prefix Discipline
46
+
47
+ Use a consistent log prefix to filter by context:
48
+
49
+ ```
50
+ [hunt:auth] token validate: user=42 result=expired
51
+ [hunt:cache] miss: key=user:42 latency=12ms
52
+ [hunt:render] phase=layout height=842px overflow=yes
53
+ ```
54
+
55
+ Gate verbose logging behind a debug flag when the project already has one. Remove temporary logs before finishing.
56
+
57
+ ## Timing Bug Logging
58
+
59
+ For race conditions, flicker, or intermittent failures, log:
60
+ - Event identity (which event source)
61
+ - Timestamp (or monotonic counter)
62
+ - Start and end (not just "it ran")
63
+ - Thread/task/queue identity when concurrency is involved
64
+
65
+ If adding a log changes the behavior, treat that as evidence of a timing, lifecycle, or concurrency problem. Do not dismiss it as "just logging side effects."
66
+
67
+ ## Removing Logs
68
+
69
+ After the root cause is confirmed:
70
+ 1. Remove all temporary logs.
71
+ 2. If a log is genuinely useful in production, move it behind the project's debug flag or logger level.
72
+ 3. Do not leave `console.log`, `print`, or `fmt.Println` in shipped code paths unless the project keeps debug instrumentation there.
@@ -0,0 +1,34 @@
1
+ # Rendering Bug Debug Reference
2
+
3
+ ## Rendering Bug Mode
4
+
5
+ Activate when: "PDF looks wrong", "page break issue", "font not rendering", broken PDF output, print layout wrong.
6
+
7
+ Static analysis first (CSS review), then reproduce if needed.
8
+
9
+ ### WeasyPrint
10
+
11
+ - `rgba()` causes double-rectangle bug: use solid hex colors instead
12
+ - `page-break-inside: avoid` is often ignored: use explicit breaks
13
+ - Float-based layouts often break at page boundaries: prefer flexbox or block
14
+ - External font URLs blocked at render time: embed fonts as base64 or host locally
15
+
16
+ ### Font Loading
17
+
18
+ - Check `@font-face` src paths (relative vs. absolute)
19
+ - CORS headers must allow the render origin for external fonts
20
+ - Format support: WeasyPrint prefers WOFF/TTF; WOFF2 support depends on version
21
+ - Missing font fallback = invisible text or system fallback glyph
22
+
23
+ ### Page Overflow
24
+
25
+ - Calculate content height vs. page height before debugging line-by-line
26
+ - Reduce `line-height`, `padding`, or `margin` to reclaim space
27
+ - Orphan/widow control: `orphans: 3; widows: 3` in `@page` body rule
28
+
29
+ ### Browser Print CSS
30
+
31
+ - Confirm `@media print` rules are present and not overridden
32
+ - `@page` margin must account for printer unprintable area (~6mm minimum)
33
+ - `break-before: page` / `break-after: page` on section dividers
34
+ - Test with `window.print()` in browser DevTools, not just visual preview
@@ -0,0 +1,128 @@
1
+ ---
2
+ name: learn
3
+ description: "Runs a six-phase research workflow that turns unfamiliar domains, source bundles, or collected material into publish-ready output. Use when users ask 学习一下/深入研究/研究一下/整理成文章/deep dive/compile sources or need one coherent reference from many inputs. Not for quick lookups or single-file reads."
4
+ when_to_use: "学习一下, 深入研究, 研究一下, 整理成文章, 把这批材料整理, 一站式参考, 一篇就够, 整理成长文, research, deep dive, help me understand, compile sources, unfamiliar domain"
5
+ dispatch_intent: "Deep research, unfamiliar domain, compile sources into output"
6
+ ---
7
+
8
+ # Learn: From Raw Materials to Published Output
9
+
10
+ Prefix your first line with 🥷 inline, not as its own paragraph.
11
+
12
+ Collect, organize, translate, explain, structure. Support the user's thinking; do not replace it.
13
+
14
+ **Boundary**: single URL that only needs fetching belongs in `/read`. A single URL that needs summary or analysis can use `/read` as the fetch step, but the final answer should satisfy the user's requested summary or analysis. `/learn` is for multi-source research that produces a new structured output.
15
+
16
+ ## Pre-check
17
+
18
+ Check whether `/read` and `/write` skills are installed (look for their SKILL.md in the skills directories). Warn if missing, do not block:
19
+ - `/read` missing -- Phase 1 fetch falls back to native `WebFetch` / `curl`; coverage on paywalled, JS-heavy, and Chinese-platform pages degrades.
20
+ - `/write` missing -- Phase 5 AI-pattern stripping falls back to manual scan. Phases 1-4 are unaffected.
21
+
22
+ ## Choose Mode
23
+
24
+ Ask the user to confirm the mode, using the environment's native question or approval mechanism if it has one:
25
+
26
+ | Mode | Goal | Entry | Exit |
27
+ |------|------|-------|------|
28
+ | **Deep Research** | Understand a domain well enough to write about it | Phase 1 | Phase 6: publish-ready draft |
29
+ | **Quick Reference** | Build a working mental model fast, no article planned | Phase 2 | Phase 2: notes only |
30
+ | **Write to Learn** | Already have materials, force understanding through writing | Phase 3 | Phase 6: publish-ready draft |
31
+ | **Canonical Article** | One article that covers a topic so thoroughly readers need nothing else | Phase 1 | Phase 6: single authoritative reference |
32
+
33
+ If unsure, suggest Quick Reference.
34
+
35
+ ## Canonical Article Mode
36
+
37
+ Activate when: "一篇就够", "一站式参考", "整理成长文", "目的是大家只需要看这篇就好了", or the user wants a single authoritative reference on a topic.
38
+
39
+ Goal: after reading the article, no one should need to search for anything else on this topic.
40
+
41
+ Additional requirements on top of standard Deep Research:
42
+ - Every major sub-topic must have its own section; nothing left as a footnote
43
+ - Include worked examples, not just principles
44
+ - Cover common mistakes and how to avoid them
45
+ - Add a "Further Reading" section with the 3-5 sources that go deepest; flag which ones are the best starting points
46
+ - Phase 6 self-review must confirm: "Could a reader implement/understand this from this article alone?"
47
+
48
+ ## Phase 1: Collect
49
+
50
+ Gather primary sources only: papers that introduced key ideas, official lab/product blogs, posts from builders, canonical "build it from scratch" repositories. Not summaries. Not explainers.
51
+
52
+ Three ordered steps per source -- no shortcuts, no merging:
53
+
54
+ 1. **Discover** -- use an installed search plugin (e.g., PipeLLM) to map the landscape, then deep-search the 2-3 most promising sub-topics. No plugin: use the environment's native web search. Output is a URL list; do not fetch content here.
55
+ 2. **Fetch** -- every URL goes through `/read`. `/read` already owns the proxy cascade, paywall detection, and platform routing (WeChat, Feishu, PDF, GitHub). `WebFetch` and raw `curl` silently fail on JS-heavy or paywalled sites and skip all of that. If `/read` is missing (Pre-check warned), fall back to native fetch and accept reduced coverage.
56
+ 3. **File** -- `/read` saves to `~/Downloads/{title}.md` when called from `/learn`. Move each file into a sub-topic directory under the research project after the fetch returns. Move, don't refetch.
57
+
58
+ Target: 5-10 sources for a blog post, 15-20 for a deep technical survey.
59
+
60
+ ## Phase 2: Digest
61
+
62
+ Work through the materials. For each piece: read it fully, keep what is good, cut what is not. At the end of this phase, cut roughly half of what was collected.
63
+
64
+ For key claims, ask before including in the outline:
65
+ - Does this idea appear in at least two different contexts from the same source?
66
+ - Can this framework predict what the source would say about a new problem?
67
+ - Is this specific to this source, or would any expert in the field say the same thing?
68
+
69
+ Generic wisdom is not worth distilling. Passes two or three: belongs in the outline. Passes one: background material. Passes zero: cut it.
70
+
71
+ When two sources contradict on a factual claim, note both positions and the evidence each gives. Do not silently pick one.
72
+
73
+ ### Conversation Or Review Distillation
74
+
75
+ When the input is a recent conversation, project review, scorecard, or diagnostic report, treat it as raw material:
76
+
77
+ - Extract repeated workflow failures, invariants, and verifier surfaces.
78
+ - Drop dated line numbers, current-score framing, private paths, one-machine setup, and repo-specific commands unless the output is explicitly for that same repo.
79
+ - Map each durable lesson to its target layer: project docs, shared rules, skill references, or deterministic scripts.
80
+ - Keep evidence snippets only as notes for yourself; do not paste raw conversation history into the final artifact.
81
+
82
+ ## Phase 3: Outline
83
+
84
+ Write the outline for the article. For each section: note the source materials it draws from. If a section has no sources, either it does not belong or a source needs to be found first.
85
+
86
+ Do not start Phase 4 until the outline is solid.
87
+
88
+ ## Phase 4: Fill In
89
+
90
+ Work through the outline section by section. If a section is hard to write, the mental model is still weak there: return to Phase 2 for that sub-topic. The outline may change, and that is fine.
91
+
92
+ Stall signals (any one means the mental model is incomplete for this section):
93
+ - You have rewritten the opening sentence three or more times without settling
94
+ - The section relies on a single source and you cannot cross-check the claim
95
+ - You need a new source that was not collected in Phase 1
96
+ - The paragraph makes a claim you could not explain to someone out loud
97
+
98
+ When stalled: return to Phase 2 for that sub-topic, not for the whole article.
99
+
100
+ ## Phase 5: Refine
101
+
102
+ Pass the draft with a specific brief:
103
+ - Remove redundant and verbose passages without changing meaning or voice
104
+ - Flag places where the argument does not flow
105
+ - Identify gaps: concepts used before they are explained, claims needing sources
106
+
107
+ Do not summarize sections the user has not written. Do not draft new sections from scratch. Edits only.
108
+
109
+ Then strip AI patterns from the draft. If `/write` is installed, invoke it. If not, do it manually: scan for filler phrases, binary contrasts, dramatic fragmentation, and overused adverbs. Cut them without changing meaning.
110
+
111
+ ## Phase 6: Self-review and Publish Readiness
112
+
113
+ The user reads the entire article linearly before publishing. Not with AI. Mark everything that feels off, fix it, read again. Two passes minimum.
114
+
115
+ When it reads clean from start to finish, the draft is ready for the user to publish.
116
+
117
+ **After the user confirms the article is ready to publish, stop.** Do not upload, post, distribute, or perform any publish action unless explicitly asked.
118
+
119
+ ## Gotchas
120
+
121
+ | What happened | Rule |
122
+ |---------------|------|
123
+ | Collected 30 secondary explainers instead of primary sources | Phase 1 targets papers, official blogs, and repos by builders. Summaries are not sources. |
124
+ | Used `WebFetch` or `curl` on URLs while `/read` was installed | Phase 1 fetch is not optional. `/read` owns the proxy cascade, paywall detection, and platform routing. Bypassing it silently loses coverage on paywalled, JS-heavy, or Chinese-platform pages. |
125
+ | Treated a convincing explainer as ground truth | Ask: does this appear in at least two different contexts from the same source? |
126
+ | Phase 2 wrote summaries instead of teaching the concept | Digest means building the mental model. Summarizing is not digesting. |
127
+ | AI offered to upload the article to a blog or social platform after the user said it was ready | Stop at confirmation. Publishing is the user's action, not yours. |
128
+ | Turned a project review into a generic Waza rule without filtering | Promote only repeated workflow behavior. Leave project-specific commands, paths, and safety constraints in that project |