@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.
- package/CONTRIBUTING.md +23 -1
- package/README.md +55 -0
- package/benchmark/devto-post.md +178 -0
- package/benchmark/order-processing.original.js +158 -0
- package/benchmark/order-processing.pr-toolkit.js +181 -0
- package/benchmark/order-processing.skill-router.js +271 -0
- package/benchmark/review-report.md +129 -0
- package/bin/skills.js +327 -69
- package/commands/animation-at-work.md +10 -0
- package/commands/clean-code-reviewer.md +10 -0
- package/commands/data-intensive-patterns.md +10 -0
- package/commands/data-pipelines.md +10 -0
- package/commands/design-patterns.md +10 -0
- package/commands/domain-driven-design.md +10 -0
- package/commands/effective-java.md +10 -0
- package/commands/effective-kotlin.md +10 -0
- package/commands/effective-python.md +10 -0
- package/commands/effective-typescript.md +10 -0
- package/commands/kotlin-in-action.md +10 -0
- package/commands/lean-startup.md +10 -0
- package/commands/microservices-patterns.md +10 -0
- package/commands/programming-with-rust.md +10 -0
- package/commands/refactoring-ui.md +10 -0
- package/commands/rust-in-action.md +10 -0
- package/commands/skill-router.md +10 -0
- package/commands/spring-boot-in-action.md +10 -0
- package/commands/storytelling-with-data.md +10 -0
- package/commands/system-design-interview.md +10 -0
- package/commands/using-asyncio-python.md +10 -0
- package/commands/web-scraping-python.md +10 -0
- package/docs/index.html +268 -44
- package/package.json +4 -1
- package/scripts/gen-og.mjs +142 -0
- 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
|
```
|