@booklib/skills 1.5.1 → 1.6.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 (34) hide show
  1. package/CONTRIBUTING.md +23 -1
  2. package/README.md +55 -0
  3. package/benchmark/devto-post.md +178 -0
  4. package/benchmark/order-processing.original.js +158 -0
  5. package/benchmark/order-processing.pr-toolkit.js +181 -0
  6. package/benchmark/order-processing.skill-router.js +271 -0
  7. package/benchmark/review-report.md +129 -0
  8. package/bin/skills.js +327 -69
  9. package/commands/animation-at-work.md +10 -0
  10. package/commands/clean-code-reviewer.md +10 -0
  11. package/commands/data-intensive-patterns.md +10 -0
  12. package/commands/data-pipelines.md +10 -0
  13. package/commands/design-patterns.md +10 -0
  14. package/commands/domain-driven-design.md +10 -0
  15. package/commands/effective-java.md +10 -0
  16. package/commands/effective-kotlin.md +10 -0
  17. package/commands/effective-python.md +10 -0
  18. package/commands/effective-typescript.md +10 -0
  19. package/commands/kotlin-in-action.md +10 -0
  20. package/commands/lean-startup.md +10 -0
  21. package/commands/microservices-patterns.md +10 -0
  22. package/commands/programming-with-rust.md +10 -0
  23. package/commands/refactoring-ui.md +10 -0
  24. package/commands/rust-in-action.md +10 -0
  25. package/commands/skill-router.md +10 -0
  26. package/commands/spring-boot-in-action.md +10 -0
  27. package/commands/storytelling-with-data.md +10 -0
  28. package/commands/system-design-interview.md +10 -0
  29. package/commands/using-asyncio-python.md +10 -0
  30. package/commands/web-scraping-python.md +10 -0
  31. package/docs/index.html +268 -44
  32. package/package.json +4 -1
  33. package/scripts/gen-og.mjs +142 -0
  34. package/skills/skill-router/SKILL.md +23 -0
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * gen-og.mjs — generates docs/og.png (1200×630) for GitHub Pages OG preview.
4
+ * Usage: node scripts/gen-og.mjs
5
+ * Requires: npm install -g puppeteer OR npx puppeteer is available
6
+ */
7
+ import { writeFileSync, mkdirSync } from "fs";
8
+ import { join, dirname } from "path";
9
+ import { fileURLToPath } from "url";
10
+
11
+ const __dirname = dirname(fileURLToPath(import.meta.url));
12
+ const OUT = join(__dirname, "../docs/og.png");
13
+
14
+ const HTML = `<!DOCTYPE html>
15
+ <html>
16
+ <head>
17
+ <meta charset="UTF-8"/>
18
+ <style>
19
+ * { margin: 0; padding: 0; box-sizing: border-box; }
20
+ body {
21
+ width: 1200px; height: 630px; overflow: hidden;
22
+ background: #0d0d1a;
23
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
24
+ display: flex;
25
+ align-items: center;
26
+ justify-content: space-between;
27
+ padding: 0 80px;
28
+ position: relative;
29
+ }
30
+
31
+ /* Left: text content */
32
+ .left { flex: 0 0 auto; max-width: 540px; z-index: 2; }
33
+
34
+ .org {
35
+ font-size: 22px; font-weight: 500; color: #6366f1;
36
+ letter-spacing: 0.04em; margin-bottom: 16px;
37
+ font-family: "SF Mono", "Fira Code", monospace;
38
+ }
39
+ h1 {
40
+ font-size: 72px; font-weight: 800; color: #f1f5f9;
41
+ line-height: 1; letter-spacing: -0.04em; margin-bottom: 20px;
42
+ }
43
+ .tagline {
44
+ font-size: 24px; color: #64748b; line-height: 1.4; margin-bottom: 40px;
45
+ max-width: 460px;
46
+ }
47
+ .pills { display: flex; gap: 12px; flex-wrap: wrap; }
48
+ .pill {
49
+ background: #161625; border: 1px solid #2d2d4a;
50
+ border-radius: 999px; padding: 8px 20px;
51
+ font-size: 15px; color: #a5b4fc; font-weight: 600;
52
+ }
53
+
54
+ /* Right: book grid */
55
+ .books {
56
+ display: grid;
57
+ grid-template-columns: repeat(5, 1fr);
58
+ gap: 8px;
59
+ width: 420px;
60
+ flex-shrink: 0;
61
+ opacity: 0.92;
62
+ }
63
+ .book {
64
+ aspect-ratio: 2/3;
65
+ border-radius: 5px;
66
+ background: var(--c);
67
+ position: relative;
68
+ overflow: hidden;
69
+ }
70
+ .book::after {
71
+ content: "";
72
+ position: absolute; inset: 0;
73
+ background: linear-gradient(135deg, rgba(255,255,255,0.08) 0%, transparent 60%);
74
+ }
75
+ /* Spine line */
76
+ .book::before {
77
+ content: "";
78
+ position: absolute; top: 0; bottom: 0; left: 8px;
79
+ width: 2px; background: rgba(0,0,0,0.2);
80
+ }
81
+
82
+ /* Fade edge on left side of book grid */
83
+ .books-wrap {
84
+ position: relative;
85
+ flex-shrink: 0;
86
+ }
87
+ .books-wrap::before {
88
+ content: "";
89
+ position: absolute; top: 0; bottom: 0; left: -60px;
90
+ width: 80px;
91
+ background: linear-gradient(to right, #0d0d1a, transparent);
92
+ z-index: 1;
93
+ pointer-events: none;
94
+ }
95
+ </style>
96
+ </head>
97
+ <body>
98
+ <div class="left">
99
+ <div class="org">booklib-ai / skills</div>
100
+ <h1>Skills</h1>
101
+ <p class="tagline">Expert knowledge from 22 canonical programming books — packaged as AI agent skills.</p>
102
+ <div class="pills">
103
+ <span class="pill">22 skills</span>
104
+ <span class="pill">Claude Code</span>
105
+ <span class="pill">Cursor</span>
106
+ <span class="pill">Copilot</span>
107
+ </div>
108
+ </div>
109
+
110
+ <div class="books-wrap">
111
+ <div class="books">
112
+ ${[
113
+ "#1e3a5f","#5f1e1e","#1e5f2a","#5f4a1e","#2a1e5f",
114
+ "#1e4d5f","#5f1e4a","#3d5f1e","#5f3d1e","#1e5f5f",
115
+ "#4a1e5f","#1e5f3d","#5f5f1e","#1e2a5f","#5f1e2a",
116
+ "#2a5f1e","#5f2a1e","#1e5f4a","#4a5f1e","#1e4a5f",
117
+ "#5f1e5f","#3d1e5f","#1e5f1e","#5f3d3d","#1e3d5f",
118
+ "#5f4d1e","#1e4d3d","#4d1e1e","#1e1e4d","#3d5f3d",
119
+ ].map(c => `<div class="book" style="--c:${c}"></div>`).join("")}
120
+ </div>
121
+ </div>
122
+ </body>
123
+ </html>`;
124
+
125
+ let puppeteer;
126
+ try {
127
+ puppeteer = await import("puppeteer");
128
+ } catch {
129
+ // Try puppeteer-core as fallback
130
+ puppeteer = await import("puppeteer-core");
131
+ }
132
+
133
+ const browser = await puppeteer.default.launch({ headless: true });
134
+ const page = await browser.newPage();
135
+ await page.setViewport({ width: 1200, height: 630, deviceScaleFactor: 2 });
136
+ await page.setContent(HTML, { waitUntil: "networkidle0" });
137
+ const buf = await page.screenshot({ type: "png" });
138
+ await browser.close();
139
+
140
+ mkdirSync(dirname(OUT), { recursive: true });
141
+ writeFileSync(OUT, buf);
142
+ console.log(`Written: ${OUT} (${(buf.length / 1024).toFixed(0)} KB)`);
@@ -24,6 +24,14 @@ You are a skill selector for the `@booklib/skills` library — a collection of 1
24
24
 
25
25
  ## Routing Process
26
26
 
27
+ ### Step 0 — Establish Input Scope
28
+
29
+ Before routing, pin what you're actually reviewing:
30
+
31
+ 1. **Prefer `git diff` as default scope.** If the user asks to review code without specifying files, default to the current diff — not the entire codebase. Routing a skill against 10,000 lines of unchanged code wastes context and dilutes findings.
32
+ 2. **Check for a CLAUDE.md.** If one exists, read it before routing. Project conventions (language standards, test requirements, banned patterns) affect which skill is most relevant and what the selected skill should prioritize.
33
+ 3. **Identify the specific files or scope** from the user's message. If genuinely ambiguous, ask before routing.
34
+
27
35
  ### Step 1 — Classify the Work Type
28
36
 
29
37
  Identify what the user is trying to do:
@@ -92,12 +100,18 @@ Some skill pairs can conflict. Resolve using these rules:
92
100
  Format your output as:
93
101
 
94
102
  ```
103
+ **Scope:** [files or git diff being reviewed]
95
104
  **Primary skill:** `skill-name`
96
105
  **Why:** [1-2 sentence rationale tying the task to the skill's domain]
97
106
  **Secondary (optional):** `skill-name` — [brief rationale] OR none
98
107
  **Don't apply:** `skill-name` — [why it would produce irrelevant feedback]
99
108
  ```
100
109
 
110
+ When instructing the selected skill(s), tell them to:
111
+ - Classify each finding as **HIGH** (correctness/security/data loss), **MEDIUM** (design/maintainability), or **LOW** (style/naming)
112
+ - Reference findings as `file.ext:line` — not just "line 42" or "the function"
113
+ - Skip findings below the threshold for the work type: **review** → HIGH + MEDIUM; **migrate/design** → all tiers
114
+
101
115
  If you're genuinely uncertain between two equally applicable skills, say so and recommend applying both in sequence, primary first.
102
116
 
103
117
  ---
@@ -118,28 +132,37 @@ Do NOT route to a skill if:
118
132
  ```
119
133
  User: "Review my Python class for code quality"
120
134
 
135
+ Scope: orders/service.py (specified file)
121
136
  Primary skill: clean-code-reviewer
122
137
  Why: Language-agnostic code quality review is exactly Clean Code's domain — naming, functions, comments, classes.
123
138
  Secondary: none
124
139
  Don't apply: effective-python — Python-specific idioms are not the concern here; effective-python would focus on list comprehensions and context managers, not the general code quality issues Clean Code addresses.
140
+
141
+ → Instruct clean-code-reviewer to classify findings as HIGH/MEDIUM/LOW and reference each as orders/service.py:line.
125
142
  ```
126
143
 
127
144
  **Example 2 — Conflict case:**
128
145
  ```
129
146
  User: "I'm building a new microservice for our e-commerce platform. Review the domain model."
130
147
 
148
+ Scope: git diff (new files in src/domain/)
131
149
  Primary skill: domain-driven-design
132
150
  Why: The request is about domain model design — Aggregates, Value Objects, Bounded Contexts. DDD is the authoritative source.
133
151
  Secondary: microservices-patterns — apply after DDD review to check service boundaries, database ownership, and communication patterns.
134
152
  Don't apply: clean-code-reviewer — code quality review is premature at the design stage; apply later when implementation code exists.
153
+
154
+ → Instruct both skills to classify findings as HIGH/MEDIUM/LOW and reference each as file:line.
135
155
  ```
136
156
 
137
157
  **Example 3 — Already routed (positive case):**
138
158
  ```
139
159
  User: "Use the effective-java skill to review my builder pattern"
140
160
 
161
+ Scope: user specified — confirm with them if files aren't clear
141
162
  Primary skill: effective-java (already specified by user — confirm and proceed)
142
163
  Why: User correctly identified the skill. effective-java Item 2 covers the Builder pattern directly.
143
164
  Secondary: none
144
165
  Don't apply: design-patterns — GoF Builder pattern is covered, but Effective Java's opinionated take on Java-specific Builder is more directly applicable.
166
+
167
+ → Instruct effective-java to classify findings as HIGH/MEDIUM/LOW and reference each as file:line.
145
168
  ```