@booklib/skills 1.0.0 → 1.3.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 (100) hide show
  1. package/CONTRIBUTING.md +122 -0
  2. package/README.md +20 -1
  3. package/ROADMAP.md +36 -0
  4. package/animation-at-work/evals/evals.json +44 -0
  5. package/animation-at-work/examples/after.md +64 -0
  6. package/animation-at-work/examples/before.md +35 -0
  7. package/animation-at-work/scripts/audit_animations.py +295 -0
  8. package/bin/skills.js +552 -42
  9. package/clean-code-reviewer/SKILL.md +109 -1
  10. package/clean-code-reviewer/evals/evals.json +121 -3
  11. package/clean-code-reviewer/examples/after.md +48 -0
  12. package/clean-code-reviewer/examples/before.md +33 -0
  13. package/clean-code-reviewer/references/api_reference.md +158 -0
  14. package/clean-code-reviewer/references/practices-catalog.md +282 -0
  15. package/clean-code-reviewer/references/review-checklist.md +254 -0
  16. package/clean-code-reviewer/scripts/pre-review.py +206 -0
  17. package/data-intensive-patterns/evals/evals.json +43 -0
  18. package/data-intensive-patterns/examples/after.md +61 -0
  19. package/data-intensive-patterns/examples/before.md +38 -0
  20. package/data-intensive-patterns/scripts/adr.py +213 -0
  21. package/data-pipelines/evals/evals.json +45 -0
  22. package/data-pipelines/examples/after.md +97 -0
  23. package/data-pipelines/examples/before.md +37 -0
  24. package/data-pipelines/scripts/new_pipeline.py +444 -0
  25. package/design-patterns/evals/evals.json +46 -0
  26. package/design-patterns/examples/after.md +52 -0
  27. package/design-patterns/examples/before.md +29 -0
  28. package/design-patterns/scripts/scaffold.py +807 -0
  29. package/domain-driven-design/SKILL.md +120 -0
  30. package/domain-driven-design/evals/evals.json +48 -0
  31. package/domain-driven-design/examples/after.md +80 -0
  32. package/domain-driven-design/examples/before.md +43 -0
  33. package/domain-driven-design/scripts/scaffold.py +421 -0
  34. package/effective-java/evals/evals.json +46 -0
  35. package/effective-java/examples/after.md +83 -0
  36. package/effective-java/examples/before.md +37 -0
  37. package/effective-java/scripts/checkstyle_setup.py +211 -0
  38. package/effective-kotlin/evals/evals.json +45 -0
  39. package/effective-kotlin/examples/after.md +36 -0
  40. package/effective-kotlin/examples/before.md +38 -0
  41. package/effective-python/SKILL.md +199 -0
  42. package/effective-python/evals/evals.json +44 -0
  43. package/effective-python/examples/after.md +56 -0
  44. package/effective-python/examples/before.md +40 -0
  45. package/effective-python/ref-01-pythonic-thinking.md +202 -0
  46. package/effective-python/ref-02-lists-and-dicts.md +146 -0
  47. package/effective-python/ref-03-functions.md +186 -0
  48. package/effective-python/ref-04-comprehensions-generators.md +211 -0
  49. package/effective-python/ref-05-classes-interfaces.md +188 -0
  50. package/effective-python/ref-06-metaclasses-attributes.md +209 -0
  51. package/effective-python/ref-07-concurrency.md +213 -0
  52. package/effective-python/ref-08-robustness-performance.md +248 -0
  53. package/effective-python/ref-09-testing-debugging.md +253 -0
  54. package/effective-python/ref-10-collaboration.md +175 -0
  55. package/effective-python/references/api_reference.md +218 -0
  56. package/effective-python/references/practices-catalog.md +483 -0
  57. package/effective-python/references/review-checklist.md +190 -0
  58. package/effective-python/scripts/lint.py +173 -0
  59. package/kotlin-in-action/evals/evals.json +43 -0
  60. package/kotlin-in-action/examples/after.md +53 -0
  61. package/kotlin-in-action/examples/before.md +39 -0
  62. package/kotlin-in-action/scripts/setup_detekt.py +224 -0
  63. package/lean-startup/evals/evals.json +43 -0
  64. package/lean-startup/examples/after.md +80 -0
  65. package/lean-startup/examples/before.md +34 -0
  66. package/lean-startup/scripts/new_experiment.py +286 -0
  67. package/microservices-patterns/SKILL.md +140 -0
  68. package/microservices-patterns/evals/evals.json +45 -0
  69. package/microservices-patterns/examples/after.md +69 -0
  70. package/microservices-patterns/examples/before.md +40 -0
  71. package/microservices-patterns/scripts/new_service.py +583 -0
  72. package/package.json +1 -1
  73. package/refactoring-ui/evals/evals.json +45 -0
  74. package/refactoring-ui/examples/after.md +85 -0
  75. package/refactoring-ui/examples/before.md +58 -0
  76. package/refactoring-ui/scripts/audit_css.py +250 -0
  77. package/skill-router/SKILL.md +142 -0
  78. package/skill-router/evals/evals.json +38 -0
  79. package/skill-router/examples/after.md +63 -0
  80. package/skill-router/examples/before.md +39 -0
  81. package/skill-router/references/api_reference.md +24 -0
  82. package/skill-router/references/routing-heuristics.md +89 -0
  83. package/skill-router/references/skill-catalog.md +156 -0
  84. package/skill-router/scripts/route.py +266 -0
  85. package/storytelling-with-data/evals/evals.json +47 -0
  86. package/storytelling-with-data/examples/after.md +50 -0
  87. package/storytelling-with-data/examples/before.md +33 -0
  88. package/storytelling-with-data/scripts/chart_review.py +301 -0
  89. package/system-design-interview/evals/evals.json +45 -0
  90. package/system-design-interview/examples/after.md +94 -0
  91. package/system-design-interview/examples/before.md +27 -0
  92. package/system-design-interview/scripts/new_design.py +421 -0
  93. package/using-asyncio-python/evals/evals.json +43 -0
  94. package/using-asyncio-python/examples/after.md +68 -0
  95. package/using-asyncio-python/examples/before.md +39 -0
  96. package/using-asyncio-python/scripts/check_blocking.py +270 -0
  97. package/web-scraping-python/evals/evals.json +46 -0
  98. package/web-scraping-python/examples/after.md +109 -0
  99. package/web-scraping-python/examples/before.md +40 -0
  100. package/web-scraping-python/scripts/new_scraper.py +231 -0
@@ -0,0 +1,24 @@
1
+ # API Reference: Skill Quick-Lookup
2
+
3
+ Quick-lookup table for all 17 skills.
4
+
5
+ | Skill | Domain | Works Well With | Conflicts With |
6
+ |-------|--------|-----------------|----------------|
7
+ | `animation-at-work` | Web animation, motion | `refactoring-ui` | None |
8
+ | `clean-code-reviewer` | Code quality (any language) | `effective-java`, `effective-python`, `effective-kotlin` | `domain-driven-design` (model design context) |
9
+ | `data-intensive-patterns` | Storage internals, distributed data | `system-design-interview` | `system-design-interview` (different altitude) |
10
+ | `data-pipelines` | ETL, data ingestion, orchestration | `data-intensive-patterns`, `effective-python` | `microservices-patterns` |
11
+ | `design-patterns` | GoF OO patterns | `clean-code-reviewer`, `effective-java` | `domain-driven-design` |
12
+ | `domain-driven-design` | Domain modeling, DDD patterns | `microservices-patterns`, `clean-code-reviewer` | `clean-code-reviewer` (code review context) |
13
+ | `effective-java` | Java idioms and best practices | `clean-code-reviewer`, `design-patterns` | `clean-code-reviewer` (Java-specific vs general) |
14
+ | `effective-kotlin` | Kotlin best practices | `kotlin-in-action`, `clean-code-reviewer` | `kotlin-in-action` |
15
+ | `effective-python` | Python idioms and best practices | `clean-code-reviewer`, `using-asyncio-python` | `using-asyncio-python` (async topics) |
16
+ | `kotlin-in-action` | Kotlin language features | `effective-kotlin` | `effective-kotlin` |
17
+ | `lean-startup` | Startup strategy, MVP, pivots | None (strategy only) | All technical skills |
18
+ | `microservices-patterns` | Service decomposition, sagas, CQRS | `domain-driven-design`, `system-design-interview` | `domain-driven-design` (service vs model) |
19
+ | `refactoring-ui` | UI design, visual hierarchy | `animation-at-work` | None |
20
+ | `skill-router` | Skill selection and routing | All skills | None |
21
+ | `storytelling-with-data` | Data visualization, charts | `data-pipelines` | None |
22
+ | `system-design-interview` | System scalability, high-level design | `microservices-patterns`, `data-intensive-patterns` | `data-intensive-patterns` (altitude) |
23
+ | `using-asyncio-python` | Python asyncio, concurrency | `effective-python` | `effective-python` (async topics) |
24
+ | `web-scraping-python` | Web scraping, crawling | `effective-python`, `data-pipelines` | None |
@@ -0,0 +1,89 @@
1
+ # Routing Heuristics
2
+
3
+ Decision rules for the skill-router. Apply these in order.
4
+
5
+ ## Primary Rules (apply first)
6
+
7
+ ### By Language
8
+
9
+ | Language | Primary Skill | Override Condition |
10
+ |----------|-------------|-------------------|
11
+ | Python (general) | `effective-python` | If async → `using-asyncio-python`; if scraping → `web-scraping-python` |
12
+ | Python (async/concurrent) | `using-asyncio-python` | Always wins over effective-python for async topics |
13
+ | Python (web scraping) | `web-scraping-python` | Always wins for scraping topics |
14
+ | Java | `effective-java` | If code quality focus → `clean-code-reviewer` |
15
+ | Kotlin | `effective-kotlin` | If learning Kotlin → `kotlin-in-action` |
16
+ | Any language (code quality) | `clean-code-reviewer` | Language-agnostic; always applicable for readability |
17
+ | CSS/HTML/Frontend | `refactoring-ui` | If animation → `animation-at-work` |
18
+ | Any (visualization) | `storytelling-with-data` | Must have a visual component |
19
+
20
+ ### By Domain
21
+
22
+ | Domain | Primary Skill |
23
+ |--------|-------------|
24
+ | Domain modeling, DDD | `domain-driven-design` |
25
+ | Service decomposition, distributed systems | `microservices-patterns` |
26
+ | GoF design patterns | `design-patterns` |
27
+ | System scalability, estimation | `system-design-interview` |
28
+ | Storage internals, distributed data | `data-intensive-patterns` |
29
+ | Data pipelines, ETL | `data-pipelines` |
30
+ | Startup strategy, product | `lean-startup` |
31
+
32
+ ## Conflict Resolution Rules
33
+
34
+ ### clean-code-reviewer vs effective-java
35
+ - **Code-level review with naming/readability focus** → `clean-code-reviewer`
36
+ - **Java-specific items (generics, enums, serialization, lambdas)** → `effective-java`
37
+ - **Both applicable** → primary: `clean-code-reviewer`, secondary: `effective-java`
38
+
39
+ ### effective-kotlin vs kotlin-in-action
40
+ - **User knows Kotlin, wants best practice advice** → `effective-kotlin`
41
+ - **User is learning Kotlin or asking about language features** → `kotlin-in-action`
42
+ - **Ambiguous** → ask whether they want best practices or feature explanation
43
+
44
+ ### domain-driven-design vs microservices-patterns
45
+ - **Designing or reviewing a domain model** → `domain-driven-design`
46
+ - **Designing service decomposition, sagas, inter-service communication** → `microservices-patterns`
47
+ - **Designing a new microservice with rich domain** → apply both: DDD first (model), microservices-patterns second (service design)
48
+
49
+ ### domain-driven-design vs clean-code-reviewer
50
+ - **Model design** → `domain-driven-design` (ignore clean code's "small functions" rule when modeling)
51
+ - **Code review** → `clean-code-reviewer` (DDD model concerns are separate from code readability)
52
+
53
+ ### data-intensive-patterns vs system-design-interview
54
+ - **Internals: storage engines, replication, consistency models** → `data-intensive-patterns`
55
+ - **High-level: system components, scale, estimation** → `system-design-interview`
56
+ - **Full system design** → primary: `system-design-interview`, secondary: `data-intensive-patterns`
57
+
58
+ ### effective-python vs using-asyncio-python
59
+ - **Any async/concurrent Python** → `using-asyncio-python` (always wins)
60
+ - **Non-async Python** → `effective-python`
61
+
62
+ ## Work Type Rules
63
+
64
+ | Work Type | Routing Preference |
65
+ |-----------|-------------------|
66
+ | Code review | Language-specific skill OR `clean-code-reviewer` |
67
+ | Code generation | Domain-specific skill (DDD, microservices, design-patterns) |
68
+ | Migration planning | Skill with Mode 3 (clean-code-reviewer, domain-driven-design, microservices-patterns) |
69
+ | System design | `system-design-interview` + optional `microservices-patterns` |
70
+ | Learning | Language-specific learning skill (kotlin-in-action) or domain skill |
71
+
72
+ ## Anti-Trigger Rules
73
+
74
+ Never route to these skills if:
75
+
76
+ | Skill | Don't route if... |
77
+ |-------|------------------|
78
+ | `domain-driven-design` | Simple CRUD, no complex domain, < 3 entity types |
79
+ | `microservices-patterns` | Single service, no decomposition intent |
80
+ | `lean-startup` | Pure technical code — this is a strategy skill only |
81
+ | `effective-java` | Code is not Java |
82
+ | `effective-kotlin` | Code is not Kotlin |
83
+ | `effective-python` | Code is not Python |
84
+ | `using-asyncio-python` | Code is not async Python |
85
+ | `web-scraping-python` | Not web scraping |
86
+ | `refactoring-ui` | No UI component |
87
+ | `storytelling-with-data` | No visualization |
88
+ | `animation-at-work` | No animation/motion concern |
89
+ | `system-design-interview` | Code-level concern, not system-level |
@@ -0,0 +1,156 @@
1
+ # Skill Catalog
2
+
3
+ All 17 skills in the `@booklib/skills` library with routing metadata.
4
+
5
+ ## animation-at-work
6
+ - **Source:** *Animation at Work* by Rachel Nabors
7
+ - **Domain:** Web animation, UI motion design
8
+ - **Language:** CSS, JavaScript, any frontend
9
+ - **Trigger keywords:** "animation", "motion", "transition", "keyframe", "easing", "12 principles of animation", "web animation", "CSS animation", "performance of animation"
10
+ - **Anti-triggers:** Backend code, data processing, non-visual concerns
11
+ - **Works well with:** refactoring-ui (visual design context)
12
+ - **Conflicts with:** None (niche domain)
13
+
14
+ ## clean-code-reviewer
15
+ - **Source:** *Clean Code* by Robert C. Martin
16
+ - **Domain:** Code quality, readability, maintainability
17
+ - **Language:** Language-agnostic (Java, Python, Kotlin, JavaScript examples used)
18
+ - **Trigger keywords:** "review my code", "code quality", "readable", "clean up", "refactor", "naming", "functions", "comments", "smells"
19
+ - **Anti-triggers:** Architecture design (too high-level), language-specific idioms (use language-specific skill instead)
20
+ - **Works well with:** effective-java, effective-python, effective-kotlin (clean code first, then language idioms)
21
+ - **Conflicts with:** domain-driven-design (Clean Code's "small functions" vs DDD's "rich models" — clean code wins for code review, DDD wins for model design)
22
+
23
+ ## data-intensive-patterns
24
+ - **Source:** *Designing Data-Intensive Applications* by Martin Kleppmann
25
+ - **Domain:** Storage engines, replication, partitioning, distributed systems, transactions, consistency
26
+ - **Language:** Language-agnostic (systems-level)
27
+ - **Trigger keywords:** "replication", "partitioning", "consistency", "CAP theorem", "event sourcing internals", "storage engine", "LSM tree", "B-tree", "distributed transactions", "ACID", "BASE", "linearizability"
28
+ - **Anti-triggers:** Application-level code quality, UI, domain modeling
29
+ - **Works well with:** system-design-interview (data layer + high-level architecture)
30
+ - **Conflicts with:** system-design-interview (data-intensive-patterns is deeper/lower-level; use it for internals, system-design-interview for high-level)
31
+
32
+ ## data-pipelines
33
+ - **Source:** *Data Pipelines Pocket Reference* by James Densmore
34
+ - **Domain:** Data ingestion, ETL, streaming, pipeline orchestration
35
+ - **Language:** Python, SQL, any data engineering stack
36
+ - **Trigger keywords:** "data pipeline", "ETL", "ELT", "ingestion", "Airflow", "dbt", "Spark", "streaming pipeline", "batch processing", "data warehouse", "orchestration"
37
+ - **Anti-triggers:** Application code unrelated to data movement, real-time microservices
38
+ - **Works well with:** data-intensive-patterns (pipeline + storage), effective-python (Python data code)
39
+ - **Conflicts with:** microservices-patterns (pipeline orchestration ≠ service decomposition)
40
+
41
+ ## design-patterns
42
+ - **Source:** *Head First Design Patterns* by Freeman & Robson (GoF patterns)
43
+ - **Domain:** Object-oriented design patterns (creational, structural, behavioral)
44
+ - **Language:** Java primarily, but pattern-agnostic
45
+ - **Trigger keywords:** "design pattern", "factory", "singleton", "observer", "strategy", "decorator", "facade", "command", "template method", "composite", "adapter", "proxy", "iterator", "state"
46
+ - **Anti-triggers:** Functional programming (patterns don't apply the same way), microservices decomposition
47
+ - **Works well with:** clean-code-reviewer (patterns + readability), effective-java (Java idioms + patterns)
48
+ - **Conflicts with:** domain-driven-design (GoF patterns are structural; DDD patterns are domain-driven — use DDD for domain modeling, GoF for implementation structure)
49
+
50
+ ## domain-driven-design
51
+ - **Source:** *Domain-Driven Design* by Eric Evans
52
+ - **Domain:** Domain modeling, tactical patterns (Entities, Value Objects, Aggregates, Repositories), strategic patterns (Bounded Contexts, Context Maps, ACL)
53
+ - **Language:** Language-agnostic (OO languages)
54
+ - **Trigger keywords:** "DDD", "domain model", "aggregate", "value object", "bounded context", "ubiquitous language", "repository pattern", "domain service", "anticorruption layer", "entity", "anemic domain model", "primitive obsession"
55
+ - **Anti-triggers:** Simple CRUD without domain complexity, microservices infrastructure concerns, code quality review
56
+ - **Works well with:** microservices-patterns (domain model + service boundaries), clean-code-reviewer (model + code quality)
57
+ - **Conflicts with:** clean-code-reviewer (rich models vs small functions — DDD wins for model design; clean code wins for code review)
58
+
59
+ ## effective-java
60
+ - **Source:** *Effective Java* (3rd Edition) by Joshua Bloch
61
+ - **Domain:** Java best practices and idioms
62
+ - **Language:** Java only
63
+ - **Trigger keywords:** "effective java", "java best practices", "generics", "enums", "lambdas", "streams", "builders", "serialization", "java concurrency", "checked exceptions", "java item"
64
+ - **Anti-triggers:** Non-Java code, architecture concerns, domain modeling
65
+ - **Works well with:** clean-code-reviewer (Java idioms + code quality), design-patterns (Java implementation of patterns)
66
+ - **Conflicts with:** clean-code-reviewer (both review Java but from different angles — use effective-java for Java-specific items, clean-code-reviewer for general readability)
67
+
68
+ ## effective-kotlin
69
+ - **Source:** *Effective Kotlin* (2nd Edition) by Marcin Moskała
70
+ - **Domain:** Kotlin best practices, safety, readability
71
+ - **Language:** Kotlin only
72
+ - **Trigger keywords:** "effective kotlin", "kotlin best practices", "kotlin safety", "null safety", "extension functions best practices", "kotlin idioms", "kotlin item"
73
+ - **Anti-triggers:** Non-Kotlin code, architecture concerns
74
+ - **Works well with:** kotlin-in-action (best practices + language features), clean-code-reviewer (Kotlin idioms + readability)
75
+ - **Conflicts with:** kotlin-in-action (effective-kotlin for best practices; kotlin-in-action for language learning — if user knows Kotlin and wants advice, use effective-kotlin)
76
+
77
+ ## effective-python
78
+ - **Source:** *Effective Python* (2nd Edition) by Brett Slatkin
79
+ - **Domain:** Python best practices, Pythonic idioms
80
+ - **Language:** Python only
81
+ - **Trigger keywords:** "effective python", "pythonic", "python best practices", "python idioms", "comprehensions", "generators", "decorators", "metaclasses", "python item"
82
+ - **Anti-triggers:** Non-Python code, async Python (use using-asyncio-python instead)
83
+ - **Works well with:** clean-code-reviewer (Pythonic + readable), using-asyncio-python (general Python + async)
84
+ - **Conflicts with:** using-asyncio-python (using-asyncio-python wins for async topics)
85
+
86
+ ## kotlin-in-action
87
+ - **Source:** *Kotlin in Action* (2nd Edition)
88
+ - **Domain:** Kotlin language features, learning Kotlin
89
+ - **Language:** Kotlin only
90
+ - **Trigger keywords:** "kotlin in action", "learn kotlin", "kotlin coroutines", "kotlin lambdas", "kotlin classes", "kotlin functions", "kotlin nullability", "how does kotlin"
91
+ - **Anti-triggers:** Best practices advice (use effective-kotlin), non-Kotlin code
92
+ - **Works well with:** effective-kotlin (learning + best practices)
93
+ - **Conflicts with:** effective-kotlin (kotlin-in-action for learning features; effective-kotlin for best practice advice)
94
+
95
+ ## lean-startup
96
+ - **Source:** *The Lean Startup* by Eric Ries
97
+ - **Domain:** Startup strategy, MVP, validated learning, Build-Measure-Learn
98
+ - **Language:** Not applicable (strategy skill)
99
+ - **Trigger keywords:** "lean startup", "MVP", "validated learning", "pivot", "build-measure-learn", "product market fit", "hypothesis", "experiment", "runway"
100
+ - **Anti-triggers:** Technical code review, architecture, any pure engineering concern
101
+ - **Works well with:** None (strategy domain, not engineering)
102
+ - **Conflicts with:** All technical skills (don't apply to code)
103
+
104
+ ## microservices-patterns
105
+ - **Source:** *Microservices Patterns* by Chris Richardson
106
+ - **Domain:** Microservices architecture, sagas, CQRS, API gateways, event sourcing
107
+ - **Language:** Language-agnostic (Java Spring Boot examples)
108
+ - **Trigger keywords:** "microservice", "saga", "CQRS", "event sourcing", "API gateway", "service mesh", "decompose monolith", "circuit breaker", "distributed transaction", "choreography", "orchestration"
109
+ - **Anti-triggers:** Monolith-only code with no decomposition intent, pure domain modeling without service concerns
110
+ - **Works well with:** domain-driven-design (service boundaries + domain model), system-design-interview (microservices + scale)
111
+ - **Conflicts with:** domain-driven-design (microservices-patterns for service decomposition; DDD for domain model — apply both for new services)
112
+
113
+ ## refactoring-ui
114
+ - **Source:** *Refactoring UI* by Adam Wathan & Steve Schoger
115
+ - **Domain:** UI design, visual hierarchy, typography, color, layout, spacing
116
+ - **Language:** CSS, HTML, any frontend
117
+ - **Trigger keywords:** "UI design", "visual hierarchy", "typography", "color palette", "spacing", "layout", "design system", "refactor UI", "looks bad", "UI review"
118
+ - **Anti-triggers:** Backend code, APIs, data processing, animation (use animation-at-work)
119
+ - **Works well with:** animation-at-work (UI design + motion)
120
+ - **Conflicts with:** animation-at-work (refactoring-ui for static design; animation-at-work for motion — they complement each other)
121
+
122
+ ## storytelling-with-data
123
+ - **Source:** *Storytelling with Data* by Cole Nussbaumer Knaflic
124
+ - **Domain:** Data visualization, charts, narrative structure
125
+ - **Language:** Not applicable (visualization skill)
126
+ - **Trigger keywords:** "data visualization", "chart", "graph", "dashboard", "storytelling", "declutter", "visual", "bar chart", "line chart", "scatter plot", "pie chart"
127
+ - **Anti-triggers:** Code quality, backend processing, no visual component
128
+ - **Works well with:** data-pipelines (pipeline data + visualization)
129
+ - **Conflicts with:** None (niche visual domain)
130
+
131
+ ## system-design-interview
132
+ - **Source:** *System Design Interview* by Alex Xu
133
+ - **Domain:** High-level system architecture, scalability, estimation, real-world system designs
134
+ - **Language:** Language-agnostic
135
+ - **Trigger keywords:** "system design", "scale", "scalability", "back of envelope", "rate limiting", "CDN", "load balancer", "cache", "sharding", "high availability", "design YouTube", "design Twitter", "design a URL shortener"
136
+ - **Anti-triggers:** Code-level review, domain modeling, specific language idioms
137
+ - **Works well with:** data-intensive-patterns (high-level + storage internals), microservices-patterns (system design + service architecture)
138
+ - **Conflicts with:** data-intensive-patterns (system-design-interview for high-level; data-intensive-patterns for storage internals)
139
+
140
+ ## using-asyncio-python
141
+ - **Source:** *Using Asyncio in Python* by Caleb Hattingh
142
+ - **Domain:** Python asyncio, coroutines, event loop, async patterns
143
+ - **Language:** Python only
144
+ - **Trigger keywords:** "asyncio", "async def", "await", "coroutine", "event loop", "aiohttp", "async Python", "concurrent Python", "Python concurrency"
145
+ - **Anti-triggers:** Non-async Python, non-Python code
146
+ - **Works well with:** effective-python (async + general Python best practices)
147
+ - **Conflicts with:** effective-python (using-asyncio-python wins for any async topic)
148
+
149
+ ## web-scraping-python
150
+ - **Source:** *Web Scraping with Python* by Ryan Mitchell
151
+ - **Domain:** Web scraping, BeautifulSoup, Scrapy, data extraction
152
+ - **Language:** Python only
153
+ - **Trigger keywords:** "web scraping", "BeautifulSoup", "Scrapy", "requests", "crawl", "parse HTML", "selenium scraping", "extract data from website"
154
+ - **Anti-triggers:** Non-scraping Python, general Python best practices
155
+ - **Works well with:** effective-python (scraping + Python best practices), data-pipelines (scraping + ingestion)
156
+ - **Conflicts with:** None (niche domain)
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ route.py — CLI for skill-router
4
+
5
+ Usage:
6
+ python route.py --task "review my Python class for code quality"
7
+ python route.py --file path/to/file.py --task "review for correctness"
8
+ python route.py --task "design a saga for order processing"
9
+ python route.py --task "decompose my monolith into microservices"
10
+
11
+ Prints the recommended skill(s) with rationale.
12
+ """
13
+
14
+ import argparse
15
+ import os
16
+
17
+ # Skill routing rules
18
+ SKILL_CATALOG = {
19
+ "animation-at-work": {
20
+ "domain": "Web animation, UI motion",
21
+ "languages": [], # language-agnostic but frontend
22
+ "keywords": ["animation", "motion", "transition", "keyframe", "easing", "css animation", "web animation"],
23
+ "anti_keywords": ["backend", "data processing", "api"],
24
+ },
25
+ "clean-code-reviewer": {
26
+ "domain": "Code quality, readability (any language)",
27
+ "languages": ["py", "java", "kt", "js", "ts", "go", "rs", "cpp", "cs"],
28
+ "keywords": ["review", "code quality", "readable", "clean", "refactor", "naming", "smell", "heuristic"],
29
+ "anti_keywords": ["architecture", "system design"],
30
+ },
31
+ "data-intensive-patterns": {
32
+ "domain": "Storage internals, distributed data",
33
+ "languages": [],
34
+ "keywords": ["replication", "partitioning", "consistency", "cap theorem", "storage engine", "lsm", "b-tree", "acid", "base", "linearizability"],
35
+ "anti_keywords": ["ui", "frontend", "domain model"],
36
+ },
37
+ "data-pipelines": {
38
+ "domain": "ETL, data ingestion, orchestration",
39
+ "languages": ["py", "sql"],
40
+ "keywords": ["data pipeline", "etl", "elt", "ingestion", "airflow", "dbt", "spark", "streaming", "batch", "warehouse"],
41
+ "anti_keywords": ["microservice", "ui"],
42
+ },
43
+ "design-patterns": {
44
+ "domain": "GoF OO design patterns",
45
+ "languages": ["java", "py", "kt", "cs"],
46
+ "keywords": ["design pattern", "factory", "singleton", "observer", "strategy", "decorator", "facade", "command", "template method", "composite"],
47
+ "anti_keywords": ["functional", "microservice decomposition"],
48
+ },
49
+ "domain-driven-design": {
50
+ "domain": "Domain modeling, DDD tactical and strategic patterns",
51
+ "languages": [],
52
+ "keywords": ["ddd", "domain model", "aggregate", "value object", "bounded context", "ubiquitous language", "repository", "domain service", "anticorruption", "entity", "anemic"],
53
+ "anti_keywords": ["simple crud", "ui", "code quality"],
54
+ },
55
+ "effective-java": {
56
+ "domain": "Java best practices",
57
+ "languages": ["java"],
58
+ "keywords": ["java", "generics", "enum", "lambda", "stream", "builder pattern", "serialization", "checked exception"],
59
+ "anti_keywords": [],
60
+ },
61
+ "effective-kotlin": {
62
+ "domain": "Kotlin best practices",
63
+ "languages": ["kt"],
64
+ "keywords": ["kotlin", "kotlin best practices", "kotlin safety", "null safety", "kotlin idioms", "effective kotlin", "best practices"],
65
+ "anti_keywords": ["learning kotlin"],
66
+ },
67
+ "effective-python": {
68
+ "domain": "Python idioms and best practices",
69
+ "languages": ["py"],
70
+ "keywords": ["pythonic", "python best practices", "comprehension", "generator", "decorator", "metaclass"],
71
+ "anti_keywords": ["async", "asyncio", "web scraping"],
72
+ },
73
+ "kotlin-in-action": {
74
+ "domain": "Kotlin language features",
75
+ "languages": ["kt"],
76
+ "keywords": ["learn kotlin", "kotlin coroutines", "kotlin lambdas", "kotlin classes", "how does kotlin"],
77
+ "anti_keywords": ["best practices"],
78
+ },
79
+ "lean-startup": {
80
+ "domain": "Startup strategy, MVP, validated learning",
81
+ "languages": [],
82
+ "keywords": ["mvp", "validated learning", "pivot", "build-measure-learn", "lean startup", "hypothesis", "product market fit"],
83
+ "anti_keywords": ["code", "review", "architecture", "api"],
84
+ },
85
+ "microservices-patterns": {
86
+ "domain": "Service decomposition, sagas, CQRS, event sourcing",
87
+ "languages": [],
88
+ "keywords": ["microservice", "services", "saga", "cqrs", "event sourcing", "api gateway", "decompose monolith", "circuit breaker", "distributed transaction", "choreography", "service coordination", "inter-service", "strangle", "strangler"],
89
+ "anti_keywords": ["monolith only", "simple crud"],
90
+ },
91
+ "refactoring-ui": {
92
+ "domain": "UI design, visual hierarchy, typography",
93
+ "languages": ["css", "html", "jsx", "tsx", "svelte"],
94
+ "keywords": ["ui design", "visual hierarchy", "typography", "color", "spacing", "layout", "design system"],
95
+ "anti_keywords": ["backend", "api", "animation"],
96
+ },
97
+ "storytelling-with-data": {
98
+ "domain": "Data visualization, charts, narrative",
99
+ "languages": [],
100
+ "keywords": ["data visualization", "chart", "graph", "dashboard", "storytelling", "declutter", "bar chart", "scatter plot"],
101
+ "anti_keywords": ["backend", "api", "code quality"],
102
+ },
103
+ "system-design-interview": {
104
+ "domain": "System scalability, high-level architecture",
105
+ "languages": [],
106
+ "keywords": ["system design", "scale", "scalability", "rate limiting", "cdn", "load balancer", "cache", "sharding", "high availability"],
107
+ "anti_keywords": ["code review", "domain model"],
108
+ },
109
+ "using-asyncio-python": {
110
+ "domain": "Python asyncio, concurrency",
111
+ "languages": ["py"],
112
+ "keywords": ["asyncio", "async def", "await", "coroutine", "event loop", "aiohttp", "async python", "concurrent python"],
113
+ "anti_keywords": [],
114
+ },
115
+ "web-scraping-python": {
116
+ "domain": "Web scraping, crawling",
117
+ "languages": ["py"],
118
+ "keywords": ["web scraping", "beautifulsoup", "scrapy", "crawl", "parse html", "selenium scraping"],
119
+ "anti_keywords": [],
120
+ },
121
+ }
122
+
123
+ CONFLICT_RULES = [
124
+ ("effective-python", "using-asyncio-python", "using-asyncio-python wins for async topics"),
125
+ ("kotlin-in-action", "effective-kotlin", "effective-kotlin wins for best practice advice"),
126
+ ("clean-code-reviewer", "effective-java", "effective-java wins for Java-specific items; use both for comprehensive review"),
127
+ ]
128
+
129
+
130
+ def detect_language(file_path: str | None) -> str | None:
131
+ """Detect language from file extension."""
132
+ if not file_path:
133
+ return None
134
+ ext = os.path.splitext(file_path)[1].lstrip(".")
135
+ return ext.lower() if ext else None
136
+
137
+
138
+ def score_skill(skill_name: str, skill_info: dict, task: str, language: str | None) -> float:
139
+ """Score a skill's relevance for a task. Higher = more relevant."""
140
+ task_lower = task.lower()
141
+ score = 0.0
142
+
143
+ # Keyword matching
144
+ for keyword in skill_info["keywords"]:
145
+ if keyword in task_lower:
146
+ score += 2.0
147
+
148
+ # Anti-keyword penalty
149
+ for anti_keyword in skill_info["anti_keywords"]:
150
+ if anti_keyword in task_lower:
151
+ score -= 3.0
152
+
153
+ # Language match bonus
154
+ if language and language in skill_info["languages"]:
155
+ score += 3.0
156
+ elif skill_info["languages"] and language and language not in skill_info["languages"]:
157
+ score -= 5.0 # Strong penalty for language mismatch
158
+
159
+ return score
160
+
161
+
162
+ def route(task: str, file_path: str | None = None) -> dict:
163
+ """Route a task to the best skill(s)."""
164
+ language = detect_language(file_path)
165
+ task_lower = task.lower()
166
+
167
+ scores = {}
168
+ keyword_hits = {}
169
+ for skill_name, skill_info in SKILL_CATALOG.items():
170
+ scores[skill_name] = score_skill(skill_name, skill_info, task, language)
171
+ keyword_hits[skill_name] = any(kw in task_lower for kw in skill_info["keywords"])
172
+
173
+ # Sort by score, descending
174
+ ranked = sorted(scores.items(), key=lambda x: x[1], reverse=True)
175
+
176
+ # Require positive score AND at least one keyword hit to prevent
177
+ # language-match-only false positives (e.g. data-pipelines for any .py file)
178
+ candidates = [(name, score) for name, score in ranked if score > 0 and keyword_hits[name]]
179
+
180
+ if not candidates:
181
+ return {
182
+ "primary": None,
183
+ "secondary": None,
184
+ "dont_apply": None,
185
+ "conflict_note": None,
186
+ "language_detected": language,
187
+ "rationale": "No skill matched. Try describing the task with more domain keywords, or browse the skill catalog.",
188
+ }
189
+
190
+ primary_name, _ = candidates[0]
191
+ secondary = candidates[1] if len(candidates) > 1 else None
192
+ dont_apply = candidates[2] if len(candidates) > 2 else None
193
+
194
+ # Apply conflict resolution
195
+ conflict_note = None
196
+ if secondary:
197
+ for skill_a, skill_b, note in CONFLICT_RULES:
198
+ if (primary_name == skill_a and secondary[0] == skill_b) or \
199
+ (primary_name == skill_b and secondary[0] == skill_a):
200
+ conflict_note = note
201
+ break
202
+
203
+ return {
204
+ "primary": primary_name,
205
+ "primary_domain": SKILL_CATALOG[primary_name]["domain"],
206
+ "secondary": secondary[0] if secondary else None,
207
+ "secondary_domain": SKILL_CATALOG[secondary[0]]["domain"] if secondary else None,
208
+ "dont_apply": dont_apply[0] if dont_apply else None,
209
+ "dont_apply_domain": SKILL_CATALOG[dont_apply[0]]["domain"] if dont_apply else None,
210
+ "conflict_note": conflict_note,
211
+ "language_detected": language,
212
+ }
213
+
214
+
215
+ def format_output(result: dict) -> str:
216
+ """Format routing result for CLI output."""
217
+ lines = []
218
+
219
+ if result.get("language_detected"):
220
+ lines.append(f"Detected language: .{result['language_detected']}")
221
+ lines.append("")
222
+
223
+ if not result["primary"]:
224
+ lines.append("No matching skill found.")
225
+ lines.append(result.get("rationale", ""))
226
+ return "\n".join(lines)
227
+
228
+ lines.append(f"**Primary skill:** `{result['primary']}`")
229
+ lines.append(f"**Why:** {result['primary_domain']}")
230
+
231
+ if result["secondary"]:
232
+ lines.append(f"**Secondary (optional):** `{result['secondary']}` — {result['secondary_domain']}")
233
+ else:
234
+ lines.append("**Secondary (optional):** none")
235
+
236
+ if result.get("dont_apply"):
237
+ lines.append(f"**Don't apply:** `{result['dont_apply']}` — {result['dont_apply_domain']} (lower relevance for this task)")
238
+
239
+ if result.get("conflict_note"):
240
+ lines.append(f"**Conflict resolution:** {result['conflict_note']}")
241
+
242
+ return "\n".join(lines)
243
+
244
+
245
+ def main():
246
+ parser = argparse.ArgumentParser(
247
+ description="Route a task to the best @booklib/skills skill",
248
+ formatter_class=argparse.RawDescriptionHelpFormatter,
249
+ epilog="""examples:
250
+ python route.py --task "review my Python class for code quality"
251
+ python route.py --file app/orders.py --task "review for correctness"
252
+ python route.py --task "design a saga for order processing"
253
+ python route.py --task "decompose my monolith into microservices"
254
+ python route.py --task "my bar chart is too cluttered"
255
+ """,
256
+ )
257
+ parser.add_argument("--file", help="Path to the file being reviewed (used for language detection)")
258
+ parser.add_argument("--task", required=True, help="Description of the task or question")
259
+ args = parser.parse_args()
260
+
261
+ result = route(task=args.task, file_path=args.file)
262
+ print(format_output(result))
263
+
264
+
265
+ if __name__ == "__main__":
266
+ main()
@@ -0,0 +1,47 @@
1
+ {
2
+ "evals": [
3
+ {
4
+ "id": "eval-01-pie-chart-comparison",
5
+ "prompt": "Review this data visualization specification:\n\nChart type: Pie chart (donut variant)\nTitle: \"Website Traffic by Source\"\nData (8 slices):\n- Organic Search: 28%\n- Direct: 22%\n- Social Media: 18%\n- Email: 12%\n- Paid Search: 9%\n- Referral: 5%\n- Display Ads: 4%\n- Other: 2%\n\nDesign choices:\n- Each slice has a distinct color (8 different hues)\n- Legend positioned to the right listing all 8 sources with their percentages\n- No data labels on the slices themselves\n- Title is \"Website Traffic by Source\" (descriptive, not action-oriented)\n- The chart will be used in a monthly marketing review presentation to decide where to increase ad spend",
6
+ "expectations": [
7
+ "Identifies pie/donut charts as inappropriate for comparing 8 categories — human perception cannot accurately compare angles or arc lengths, especially for similar-sized slices like 9%, 5%, 4%, 2%",
8
+ "Recommends replacing the pie chart with a horizontal bar chart ordered by value — this makes comparison trivially easy and is the explicit recommendation from Storytelling with Data Ch 2",
9
+ "Flags that 8 different colors violates the principle of purposeful color use — color should highlight the data point that matters, not differentiate all 8 categories",
10
+ "Flags the generic, descriptive title 'Website Traffic by Source' — per Ch 7, the title should state the actionable takeaway (e.g., 'Organic and Direct together drive half of all traffic — paid channels underperform')",
11
+ "Notes that forcing the audience to cross-reference a legend for 8 items adds unnecessary cognitive load — direct labels on bars would be clearer",
12
+ "Points out the context: this is for a decision about ad spend — the chart should make it obvious which channels to invest in or cut, not just show proportions",
13
+ "May suggest greying out all bars except the ones relevant to the decision (e.g., Paid Search and Display Ads highlighted to show underperformance) to focus attention per Ch 4"
14
+ ]
15
+ },
16
+ {
17
+ "id": "eval-02-chart-junk",
18
+ "prompt": "Review this data visualization specification for a quarterly sales dashboard:\n\nChart type: 3D clustered column chart\nTitle: \"Q1-Q4 Sales Performance by Region\" (displayed in WordArt-style gradient text)\nData: 4 regions × 4 quarters = 16 bars\nDesign choices:\n- 3D perspective effect with visible depth on bars\n- Heavy gridlines every $50K (dark grey, 1.5px)\n- Chart border: black box outline around entire chart area\n- Background: light blue gradient fill in the plot area\n- Data markers: small diamond shapes at the top of each bar\n- Both X-axis and Y-axis tick marks visible\n- Legend box with border in lower-right corner overlapping some bars\n- Y-axis title 'Sales ($)' rotated 90 degrees\n- All 16 bars use different colors\n- Dollar signs and commas on every data label (\"$125,432.00\")\n- Drop shadow effect on the chart frame",
19
+ "expectations": [
20
+ "Identifies the 3D effect as a critical flaw: 3D distorts the visual representation of bar heights — the same bar appears different heights depending on viewing angle, making accurate comparison impossible (Ch 2 and Ch 3)",
21
+ "Flags the 16-color palette as violating purposeful color use — with 4 regions × 4 quarters, either region or time should use color; the other should use position/grouping alone",
22
+ "Flags the heavy gridlines as chart junk (Ch 3): dark 1.5px gridlines compete with the data; if gridlines are needed, they should be very light grey (~#e5e7eb) and thin (0.5px)",
23
+ "Flags the blue gradient background as chart junk — plot area backgrounds add noise without adding information; white or no background is correct",
24
+ "Flags the chart border/drop shadow as chart junk — borders around charts imply the chart needs to be 'contained' and add visual noise",
25
+ "Flags the rotated Y-axis title — violates the alignment principle (Ch. 5: Think Like a Designer — left-align text for readability; rotated/vertical text is harder to read and should be made horizontal or removed)",
26
+ "Notes the data labels show '$125,432.00' — excessive decimal precision is visual clutter with no informational value at this scale; '$125K' is clearer (Ch. 3: Eliminate Clutter; data-ink ratio — maximize the proportion of ink devoted to actual data)",
27
+ "Notes the overlapping legend is a usability problem — direct labeling of regions on the chart would eliminate the need for a legend entirely",
28
+ "Recommends: remove 3D, use flat 2D bars; remove gridlines or make them very light; white background; consistent color scheme (one color per region); direct labels; action-oriented title"
29
+ ]
30
+ },
31
+ {
32
+ "id": "eval-03-clean-effective-visualization",
33
+ "prompt": "Review this data visualization specification:\n\nContext: Presenting to the VP of Sales — goal is to get approval to hire 2 more sales reps in the APAC region\n\nChart type: Horizontal bar chart\nTitle: \"APAC revenue per rep is half the company average — we need more headcount\"\n\nData: Revenue per sales rep by region (last 12 months)\n- North America: $2.4M per rep (4 reps)\n- Europe: $2.1M per rep (3 reps)\n- APAC: $1.2M per rep (2 reps) ← highlighted in brand blue\n- Latin America: $1.9M per rep (2 reps)\n\nDesign choices:\n- All bars grey (#9ca3af) except APAC which is brand blue (#2563eb)\n- Direct value labels at the end of each bar (\"$2.4M\", \"$2.1M\", etc.)\n- A vertical dashed reference line at $2.0M labeled 'Company average'\n- No legend (regions labeled directly on Y-axis)\n- Light horizontal gridlines removed; bars speak for themselves\n- Clean white background\n- Annotation next to APAC bar: \"Only 2 reps covering 4.5B population\"\n- Footnote: Source: Salesforce CRM, FY2025",
34
+ "expectations": [
35
+ "Recognizes this as a well-crafted, purposeful data visualization and says so explicitly",
36
+ "Praises the action-oriented title: 'APAC revenue per rep is half the company average — we need more headcount' states the insight AND the implication — exactly the Big Idea principle from Ch 1 and horizontal logic from Ch 7",
37
+ "Praises the strategic color use: all bars grey except APAC in brand blue — the audience's eye is immediately drawn to the data point that matters, implementing the Ch 4 principle of using color to direct attention",
38
+ "Praises the reference line: the company average line gives context to judge APAC's performance without requiring mental arithmetic",
39
+ "Praises direct labeling: no legend needed because regions are labeled on the Y-axis and values are labeled directly on bars — eliminating the cognitive cost of legend cross-referencing (Ch 3)",
40
+ "Praises the annotation: 'Only 2 reps covering 4.5B population' is a storytelling technique that adds human context to the data (Ch 7 — tell the story, don't just show the numbers)",
41
+ "Praises the source footnote: establishing credibility and data provenance is a design best practice",
42
+ "Does NOT manufacture fake issues just to have something to say",
43
+ "May offer optional suggestions (a second chart showing projected revenue with 4 APAC reps to make the business case) but clearly frames them as additions to strengthen the narrative, not corrections"
44
+ ]
45
+ }
46
+ ]
47
+ }
@@ -0,0 +1,50 @@
1
+ # After
2
+
3
+ A line chart with direct labels, a single accent color highlighting the insight, and an action title that states the finding — replacing three unreadable 3D pie charts.
4
+
5
+ ```
6
+ CHART SPECIFICATION: Support Ticket Trend (Revised)
7
+
8
+ Chart type: Line chart (2D, no markers except at Q3 for annotation)
9
+ Title (action headline): "Product Bug tickets doubled in Q3 — prioritise QA investment"
10
+
11
+ Data: Ticket counts by category, Q1–Q3 2024
12
+ Shown as: Single line chart, all three quarters on the x-axis
13
+
14
+ Visual choices:
15
+ - All category lines: hsl(0, 0%, 75%) [light grey, 1.5px stroke]
16
+ - "Product Bugs" line: hsl(4, 90%, 58%) [red accent, 2.5px stroke]
17
+ — only this line is coloured; all others recede into context
18
+ - Direct labels at Q3 data points (right side of chart)
19
+ — no legend required
20
+ - Single annotation on Product Bugs at Q3:
21
+ "↑ 2× vs Q1" in matching red, placed above the data point
22
+
23
+ Axes:
24
+ - X: Q1 2024, Q2 2024, Q3 2024 (three points, labelled clearly)
25
+ - Y: Ticket volume (0–1,200), light grey gridlines, no border
26
+ - Y-axis title removed — units are obvious from context
27
+
28
+ Clutter removed:
29
+ - No 3D effects
30
+ - No pie wedges (angles cannot be compared accurately)
31
+ - No rainbow palette (colour carries no meaning when everything is coloured)
32
+ - No legend (direct labels replace it)
33
+ - No percentage labels on invisible slices
34
+ - Chart border removed
35
+
36
+ Narrative context (slide title above chart):
37
+ "Our Q3 support data shows one outlier that demands attention."
38
+
39
+ Call to action (below chart, in body text):
40
+ "Recommendation: allocate 2 additional QA engineers to the mobile team
41
+ before the Q4 release to prevent further escalation."
42
+ ```
43
+
44
+ Key improvements:
45
+ - Line chart replaces pie charts — change over three time periods is exactly what a line chart communicates; pie charts cannot show trends (Ch 2: Choose an effective visual)
46
+ - Grey-out-then-highlight strategy: all lines are grey, only "Product Bugs" is red — the viewer's eye goes directly to the story without instruction (Ch 4: Focus attention with preattentive attributes — color)
47
+ - Direct labels at Q3 replace the legend — eliminates the back-and-forth between legend and chart (Ch 3: Eliminate clutter)
48
+ - Action headline "Product Bug tickets doubled in Q3 — prioritise QA investment" states the takeaway instead of describing the chart (Ch 7: Tell a story — horizontal logic, action titles)
49
+ - Annotation "↑ 2×" with the matching accent color amplifies the key data point without adding clutter (Ch 7: Annotation is storytelling)
50
+ - Explicit call-to-action in body text completes the three-act structure: context → insight → recommendation (Ch 7: Three-act structure)