@mseep/core 3.0.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/CHANGELOG.md +285 -0
- package/LICENSE +21 -0
- package/README.ja.md +14 -0
- package/README.ko.md +14 -0
- package/README.md +227 -0
- package/README.pt-BR.md +14 -0
- package/README.skills.md +50 -0
- package/README.uk.md +14 -0
- package/README.zh-CN.md +14 -0
- package/bin/booklib-mcp.js +458 -0
- package/bin/booklib.js +2394 -0
- package/bin/skills.cjs +1292 -0
- package/community/registry.json +1616 -0
- package/hooks/hooks.json +52 -0
- package/hooks/posttooluse-capture.mjs +67 -0
- package/hooks/posttooluse-contradict.mjs +76 -0
- package/hooks/posttooluse-imports.mjs +67 -0
- package/hooks/pretooluse-inject.mjs +82 -0
- package/hooks/suggest.js +153 -0
- package/lib/agent-detector.js +96 -0
- package/lib/config-loader.js +39 -0
- package/lib/conflict-resolver.js +148 -0
- package/lib/connectors/context7.js +167 -0
- package/lib/connectors/github.js +223 -0
- package/lib/connectors/local.js +120 -0
- package/lib/connectors/notion.js +436 -0
- package/lib/connectors/web.js +134 -0
- package/lib/context-builder.js +574 -0
- package/lib/discovery-engine.js +298 -0
- package/lib/doctor/hook-installer.js +83 -0
- package/lib/doctor/usage-tracker.js +87 -0
- package/lib/engine/auditor.js +103 -0
- package/lib/engine/auto-linker.js +177 -0
- package/lib/engine/bm25-index.js +178 -0
- package/lib/engine/capture.js +120 -0
- package/lib/engine/context-map.js +641 -0
- package/lib/engine/corrections.js +194 -0
- package/lib/engine/decision-checker.js +203 -0
- package/lib/engine/doctor.js +207 -0
- package/lib/engine/embedding-provider.js +72 -0
- package/lib/engine/gap-detector.js +138 -0
- package/lib/engine/gap-resolver.js +135 -0
- package/lib/engine/graph-injector.js +137 -0
- package/lib/engine/graph-search.js +183 -0
- package/lib/engine/graph.js +170 -0
- package/lib/engine/handoff.js +411 -0
- package/lib/engine/import-checker.js +249 -0
- package/lib/engine/import-parser.js +145 -0
- package/lib/engine/indexer.js +334 -0
- package/lib/engine/lookup-priority.js +15 -0
- package/lib/engine/parser.js +257 -0
- package/lib/engine/principle-extractor.js +116 -0
- package/lib/engine/project-analyzer.js +353 -0
- package/lib/engine/query-expander.js +42 -0
- package/lib/engine/reasoning-modes.js +353 -0
- package/lib/engine/registries.js +524 -0
- package/lib/engine/reranker.js +45 -0
- package/lib/engine/rrf.js +59 -0
- package/lib/engine/scanner.js +151 -0
- package/lib/engine/searcher.js +223 -0
- package/lib/engine/session-coordinator.js +291 -0
- package/lib/engine/session-manager.js +375 -0
- package/lib/engine/source-detector.js +240 -0
- package/lib/engine/source-manager.js +142 -0
- package/lib/engine/structured-response.js +47 -0
- package/lib/engine/synthesis-templates.js +364 -0
- package/lib/installer.js +70 -0
- package/lib/instinct-block.js +21 -0
- package/lib/mcp-config-writer.js +107 -0
- package/lib/paths.js +62 -0
- package/lib/project-initializer.js +856 -0
- package/lib/registry/skills.js +102 -0
- package/lib/registry-searcher.js +107 -0
- package/lib/rules/rules-manager.js +169 -0
- package/lib/skill-fetcher.js +333 -0
- package/lib/well-known-builder.js +74 -0
- package/lib/wizard/index.js +1389 -0
- package/lib/wizard/integration-detector.js +41 -0
- package/lib/wizard/project-detector.js +146 -0
- package/lib/wizard/prompt.js +221 -0
- package/lib/wizard/registry-embeddings.js +107 -0
- package/lib/wizard/skill-recommender.js +69 -0
- package/package.json +70 -0
- package/skills/animation-at-work/SKILL.md +270 -0
- package/skills/animation-at-work/assets/example_asset.txt +1 -0
- package/skills/animation-at-work/evals/evals.json +44 -0
- package/skills/animation-at-work/evals/results.json +13 -0
- package/skills/animation-at-work/examples/after.md +64 -0
- package/skills/animation-at-work/examples/before.md +35 -0
- package/skills/animation-at-work/references/api_reference.md +369 -0
- package/skills/animation-at-work/references/review-checklist.md +79 -0
- package/skills/animation-at-work/scripts/audit_animations.py +295 -0
- package/skills/animation-at-work/scripts/example.py +1 -0
- package/skills/booklib-mcp-guide/SKILL.md +129 -0
- package/skills/booklib-mcp-guide/evals/evals.json +37 -0
- package/skills/booklib-mcp-guide/examples/after.md +34 -0
- package/skills/booklib-mcp-guide/examples/before.md +27 -0
- package/skills/booklib-mcp-guide/references/tool-catalog.md +9 -0
- package/skills/clean-code-reviewer/SKILL.md +444 -0
- package/skills/clean-code-reviewer/audit.json +35 -0
- package/skills/clean-code-reviewer/evals/evals.json +185 -0
- package/skills/clean-code-reviewer/evals/results.json +13 -0
- package/skills/clean-code-reviewer/examples/after.md +48 -0
- package/skills/clean-code-reviewer/examples/before.md +33 -0
- package/skills/clean-code-reviewer/references/api_reference.md +158 -0
- package/skills/clean-code-reviewer/references/practices-catalog.md +282 -0
- package/skills/clean-code-reviewer/references/review-checklist.md +254 -0
- package/skills/clean-code-reviewer/scripts/pre-review.py +206 -0
- package/skills/data-intensive-patterns/SKILL.md +267 -0
- package/skills/data-intensive-patterns/assets/example_asset.txt +1 -0
- package/skills/data-intensive-patterns/evals/evals.json +54 -0
- package/skills/data-intensive-patterns/evals/results.json +13 -0
- package/skills/data-intensive-patterns/examples/after.md +61 -0
- package/skills/data-intensive-patterns/examples/before.md +38 -0
- package/skills/data-intensive-patterns/references/api_reference.md +34 -0
- package/skills/data-intensive-patterns/references/patterns-catalog.md +551 -0
- package/skills/data-intensive-patterns/references/review-checklist.md +193 -0
- package/skills/data-intensive-patterns/scripts/adr.py +213 -0
- package/skills/data-intensive-patterns/scripts/example.py +1 -0
- package/skills/data-pipelines/SKILL.md +259 -0
- package/skills/data-pipelines/assets/example_asset.txt +1 -0
- package/skills/data-pipelines/evals/evals.json +45 -0
- package/skills/data-pipelines/evals/results.json +13 -0
- package/skills/data-pipelines/examples/after.md +97 -0
- package/skills/data-pipelines/examples/before.md +37 -0
- package/skills/data-pipelines/references/api_reference.md +301 -0
- package/skills/data-pipelines/references/review-checklist.md +181 -0
- package/skills/data-pipelines/scripts/example.py +1 -0
- package/skills/data-pipelines/scripts/new_pipeline.py +444 -0
- package/skills/design-patterns/SKILL.md +271 -0
- package/skills/design-patterns/assets/example_asset.txt +1 -0
- package/skills/design-patterns/evals/evals.json +46 -0
- package/skills/design-patterns/evals/results.json +13 -0
- package/skills/design-patterns/examples/after.md +52 -0
- package/skills/design-patterns/examples/before.md +29 -0
- package/skills/design-patterns/references/api_reference.md +1 -0
- package/skills/design-patterns/references/patterns-catalog.md +726 -0
- package/skills/design-patterns/references/review-checklist.md +173 -0
- package/skills/design-patterns/scripts/example.py +1 -0
- package/skills/design-patterns/scripts/scaffold.py +807 -0
- package/skills/domain-driven-design/SKILL.md +142 -0
- package/skills/domain-driven-design/assets/example_asset.txt +1 -0
- package/skills/domain-driven-design/evals/evals.json +48 -0
- package/skills/domain-driven-design/evals/results.json +13 -0
- package/skills/domain-driven-design/examples/after.md +80 -0
- package/skills/domain-driven-design/examples/before.md +43 -0
- package/skills/domain-driven-design/references/api_reference.md +1 -0
- package/skills/domain-driven-design/references/patterns-catalog.md +545 -0
- package/skills/domain-driven-design/references/review-checklist.md +158 -0
- package/skills/domain-driven-design/scripts/example.py +1 -0
- package/skills/domain-driven-design/scripts/scaffold.py +421 -0
- package/skills/effective-java/SKILL.md +227 -0
- package/skills/effective-java/assets/example_asset.txt +1 -0
- package/skills/effective-java/evals/evals.json +46 -0
- package/skills/effective-java/evals/results.json +13 -0
- package/skills/effective-java/examples/after.md +83 -0
- package/skills/effective-java/examples/before.md +37 -0
- package/skills/effective-java/references/api_reference.md +1 -0
- package/skills/effective-java/references/items-catalog.md +955 -0
- package/skills/effective-java/references/review-checklist.md +216 -0
- package/skills/effective-java/scripts/checkstyle_setup.py +211 -0
- package/skills/effective-java/scripts/example.py +1 -0
- package/skills/effective-kotlin/SKILL.md +271 -0
- package/skills/effective-kotlin/assets/example_asset.txt +1 -0
- package/skills/effective-kotlin/audit.json +29 -0
- package/skills/effective-kotlin/evals/evals.json +45 -0
- package/skills/effective-kotlin/evals/results.json +13 -0
- package/skills/effective-kotlin/examples/after.md +36 -0
- package/skills/effective-kotlin/examples/before.md +38 -0
- package/skills/effective-kotlin/references/api_reference.md +1 -0
- package/skills/effective-kotlin/references/practices-catalog.md +1228 -0
- package/skills/effective-kotlin/references/review-checklist.md +126 -0
- package/skills/effective-kotlin/scripts/example.py +1 -0
- package/skills/effective-python/SKILL.md +441 -0
- package/skills/effective-python/evals/evals.json +44 -0
- package/skills/effective-python/evals/results.json +13 -0
- package/skills/effective-python/examples/after.md +56 -0
- package/skills/effective-python/examples/before.md +40 -0
- package/skills/effective-python/ref-01-pythonic-thinking.md +202 -0
- package/skills/effective-python/ref-02-lists-and-dicts.md +146 -0
- package/skills/effective-python/ref-03-functions.md +186 -0
- package/skills/effective-python/ref-04-comprehensions-generators.md +211 -0
- package/skills/effective-python/ref-05-classes-interfaces.md +188 -0
- package/skills/effective-python/ref-06-metaclasses-attributes.md +209 -0
- package/skills/effective-python/ref-07-concurrency.md +213 -0
- package/skills/effective-python/ref-08-robustness-performance.md +248 -0
- package/skills/effective-python/ref-09-testing-debugging.md +253 -0
- package/skills/effective-python/ref-10-collaboration.md +175 -0
- package/skills/effective-python/references/api_reference.md +218 -0
- package/skills/effective-python/references/practices-catalog.md +483 -0
- package/skills/effective-python/references/review-checklist.md +190 -0
- package/skills/effective-python/scripts/lint.py +173 -0
- package/skills/effective-typescript/SKILL.md +262 -0
- package/skills/effective-typescript/audit.json +29 -0
- package/skills/effective-typescript/evals/evals.json +37 -0
- package/skills/effective-typescript/evals/results.json +13 -0
- package/skills/effective-typescript/examples/after.md +70 -0
- package/skills/effective-typescript/examples/before.md +47 -0
- package/skills/effective-typescript/references/api_reference.md +118 -0
- package/skills/effective-typescript/references/practices-catalog.md +371 -0
- package/skills/effective-typescript/scripts/review.py +169 -0
- package/skills/kotlin-in-action/SKILL.md +261 -0
- package/skills/kotlin-in-action/assets/example_asset.txt +1 -0
- package/skills/kotlin-in-action/evals/evals.json +43 -0
- package/skills/kotlin-in-action/evals/results.json +13 -0
- package/skills/kotlin-in-action/examples/after.md +53 -0
- package/skills/kotlin-in-action/examples/before.md +39 -0
- package/skills/kotlin-in-action/references/api_reference.md +1 -0
- package/skills/kotlin-in-action/references/practices-catalog.md +436 -0
- package/skills/kotlin-in-action/references/review-checklist.md +204 -0
- package/skills/kotlin-in-action/scripts/example.py +1 -0
- package/skills/kotlin-in-action/scripts/setup_detekt.py +224 -0
- package/skills/lean-startup/SKILL.md +160 -0
- package/skills/lean-startup/assets/example_asset.txt +1 -0
- package/skills/lean-startup/evals/evals.json +43 -0
- package/skills/lean-startup/evals/results.json +13 -0
- package/skills/lean-startup/examples/after.md +80 -0
- package/skills/lean-startup/examples/before.md +34 -0
- package/skills/lean-startup/references/api_reference.md +319 -0
- package/skills/lean-startup/references/review-checklist.md +137 -0
- package/skills/lean-startup/scripts/example.py +1 -0
- package/skills/lean-startup/scripts/new_experiment.py +286 -0
- package/skills/microservices-patterns/SKILL.md +384 -0
- package/skills/microservices-patterns/evals/evals.json +45 -0
- package/skills/microservices-patterns/evals/results.json +13 -0
- package/skills/microservices-patterns/examples/after.md +69 -0
- package/skills/microservices-patterns/examples/before.md +40 -0
- package/skills/microservices-patterns/references/patterns-catalog.md +391 -0
- package/skills/microservices-patterns/references/review-checklist.md +169 -0
- package/skills/microservices-patterns/scripts/new_service.py +583 -0
- package/skills/programming-with-rust/SKILL.md +209 -0
- package/skills/programming-with-rust/evals/evals.json +37 -0
- package/skills/programming-with-rust/evals/results.json +13 -0
- package/skills/programming-with-rust/examples/after.md +107 -0
- package/skills/programming-with-rust/examples/before.md +59 -0
- package/skills/programming-with-rust/references/api_reference.md +152 -0
- package/skills/programming-with-rust/references/practices-catalog.md +335 -0
- package/skills/programming-with-rust/scripts/review.py +142 -0
- package/skills/refactoring-ui/SKILL.md +362 -0
- package/skills/refactoring-ui/assets/example_asset.txt +1 -0
- package/skills/refactoring-ui/evals/evals.json +45 -0
- package/skills/refactoring-ui/evals/results.json +13 -0
- package/skills/refactoring-ui/examples/after.md +85 -0
- package/skills/refactoring-ui/examples/before.md +58 -0
- package/skills/refactoring-ui/references/api_reference.md +355 -0
- package/skills/refactoring-ui/references/review-checklist.md +114 -0
- package/skills/refactoring-ui/scripts/audit_css.py +250 -0
- package/skills/refactoring-ui/scripts/example.py +1 -0
- package/skills/rust-in-action/SKILL.md +350 -0
- package/skills/rust-in-action/evals/evals.json +38 -0
- package/skills/rust-in-action/evals/results.json +13 -0
- package/skills/rust-in-action/examples/after.md +156 -0
- package/skills/rust-in-action/examples/before.md +56 -0
- package/skills/rust-in-action/references/practices-catalog.md +346 -0
- package/skills/rust-in-action/scripts/review.py +147 -0
- package/skills/skill-router/SKILL.md +186 -0
- package/skills/skill-router/evals/evals.json +38 -0
- package/skills/skill-router/evals/results.json +13 -0
- package/skills/skill-router/examples/after.md +63 -0
- package/skills/skill-router/examples/before.md +39 -0
- package/skills/skill-router/references/api_reference.md +24 -0
- package/skills/skill-router/references/routing-heuristics.md +89 -0
- package/skills/skill-router/references/skill-catalog.md +174 -0
- package/skills/skill-router/scripts/route.py +266 -0
- package/skills/spring-boot-in-action/SKILL.md +340 -0
- package/skills/spring-boot-in-action/evals/evals.json +39 -0
- package/skills/spring-boot-in-action/evals/results.json +13 -0
- package/skills/spring-boot-in-action/examples/after.md +185 -0
- package/skills/spring-boot-in-action/examples/before.md +84 -0
- package/skills/spring-boot-in-action/references/practices-catalog.md +403 -0
- package/skills/spring-boot-in-action/scripts/review.py +184 -0
- package/skills/storytelling-with-data/SKILL.md +241 -0
- package/skills/storytelling-with-data/assets/example_asset.txt +1 -0
- package/skills/storytelling-with-data/evals/evals.json +47 -0
- package/skills/storytelling-with-data/evals/results.json +13 -0
- package/skills/storytelling-with-data/examples/after.md +50 -0
- package/skills/storytelling-with-data/examples/before.md +33 -0
- package/skills/storytelling-with-data/references/api_reference.md +379 -0
- package/skills/storytelling-with-data/references/review-checklist.md +111 -0
- package/skills/storytelling-with-data/scripts/chart_review.py +301 -0
- package/skills/storytelling-with-data/scripts/example.py +1 -0
- package/skills/system-design-interview/SKILL.md +233 -0
- package/skills/system-design-interview/assets/example_asset.txt +1 -0
- package/skills/system-design-interview/evals/evals.json +46 -0
- package/skills/system-design-interview/evals/results.json +13 -0
- package/skills/system-design-interview/examples/after.md +94 -0
- package/skills/system-design-interview/examples/before.md +27 -0
- package/skills/system-design-interview/references/api_reference.md +582 -0
- package/skills/system-design-interview/references/review-checklist.md +201 -0
- package/skills/system-design-interview/scripts/example.py +1 -0
- package/skills/system-design-interview/scripts/new_design.py +421 -0
- package/skills/using-asyncio-python/SKILL.md +290 -0
- package/skills/using-asyncio-python/assets/example_asset.txt +1 -0
- package/skills/using-asyncio-python/evals/evals.json +43 -0
- package/skills/using-asyncio-python/evals/results.json +13 -0
- package/skills/using-asyncio-python/examples/after.md +68 -0
- package/skills/using-asyncio-python/examples/before.md +39 -0
- package/skills/using-asyncio-python/references/api_reference.md +267 -0
- package/skills/using-asyncio-python/references/review-checklist.md +149 -0
- package/skills/using-asyncio-python/scripts/check_blocking.py +270 -0
- package/skills/using-asyncio-python/scripts/example.py +1 -0
- package/skills/web-scraping-python/SKILL.md +280 -0
- package/skills/web-scraping-python/assets/example_asset.txt +1 -0
- package/skills/web-scraping-python/evals/evals.json +46 -0
- package/skills/web-scraping-python/evals/results.json +13 -0
- package/skills/web-scraping-python/examples/after.md +109 -0
- package/skills/web-scraping-python/examples/before.md +40 -0
- package/skills/web-scraping-python/references/api_reference.md +393 -0
- package/skills/web-scraping-python/references/review-checklist.md +163 -0
- package/skills/web-scraping-python/scripts/example.py +1 -0
- package/skills/web-scraping-python/scripts/new_scraper.py +231 -0
- package/skills/writing-plans/audit.json +34 -0
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
audit_animations.py - Audit CSS/SCSS for animation anti-patterns.
|
|
4
|
+
|
|
5
|
+
Usage:
|
|
6
|
+
python audit_animations.py <file_or_directory>
|
|
7
|
+
|
|
8
|
+
Scans .css and .scss files for animation anti-patterns documented in
|
|
9
|
+
"Animation at Work" by Rachel Nabors.
|
|
10
|
+
|
|
11
|
+
Checks performed:
|
|
12
|
+
1. Animating layout-triggering properties (use transform instead)
|
|
13
|
+
2. transition: all (too broad)
|
|
14
|
+
3. Transitions > 500ms or animations > 1000ms (too slow)
|
|
15
|
+
4. Durations < 100ms (too fast to perceive)
|
|
16
|
+
5. linear easing on UI transitions (use ease-out or cubic-bezier)
|
|
17
|
+
6. Missing prefers-reduced-motion in files that animate
|
|
18
|
+
7. infinite animations without a pause mechanism
|
|
19
|
+
|
|
20
|
+
Outputs: file, line, offending CSS, and recommended fix.
|
|
21
|
+
Summary at end: total issues by category.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
import argparse
|
|
25
|
+
import pathlib
|
|
26
|
+
import re
|
|
27
|
+
import sys
|
|
28
|
+
from collections import defaultdict
|
|
29
|
+
from typing import NamedTuple
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Issue(NamedTuple):
|
|
33
|
+
file: str
|
|
34
|
+
line: int
|
|
35
|
+
category: str
|
|
36
|
+
snippet: str
|
|
37
|
+
advice: str
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# Properties that trigger layout recalculation — animating them is expensive.
|
|
41
|
+
LAYOUT_TRIGGERING = [
|
|
42
|
+
"width", "height", "top", "left", "right", "bottom",
|
|
43
|
+
"margin", "margin-top", "margin-right", "margin-bottom", "margin-left",
|
|
44
|
+
"padding", "padding-top", "padding-right", "padding-bottom", "padding-left",
|
|
45
|
+
]
|
|
46
|
+
|
|
47
|
+
CATEGORIES = {
|
|
48
|
+
"layout_property": "Layout-triggering property animated",
|
|
49
|
+
"transition_all": "transition: all used",
|
|
50
|
+
"too_slow": "Duration too long (sluggish UI)",
|
|
51
|
+
"too_fast": "Duration too short (imperceptible)",
|
|
52
|
+
"linear_easing": "Linear easing on UI transition",
|
|
53
|
+
"no_reduced_motion": "Missing prefers-reduced-motion",
|
|
54
|
+
"infinite_no_pause": "Infinite animation without pause mechanism",
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def parse_duration_ms(value: str) -> float | None:
|
|
59
|
+
"""Convert a CSS duration string (e.g. '0.3s', '300ms') to milliseconds."""
|
|
60
|
+
value = value.strip()
|
|
61
|
+
if value.endswith("ms"):
|
|
62
|
+
try:
|
|
63
|
+
return float(value[:-2])
|
|
64
|
+
except ValueError:
|
|
65
|
+
return None
|
|
66
|
+
if value.endswith("s"):
|
|
67
|
+
try:
|
|
68
|
+
return float(value[:-1]) * 1000
|
|
69
|
+
except ValueError:
|
|
70
|
+
return None
|
|
71
|
+
return None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def find_css_files(path: pathlib.Path) -> list[pathlib.Path]:
|
|
75
|
+
if path.is_file():
|
|
76
|
+
if path.suffix in {".css", ".scss"}:
|
|
77
|
+
return [path]
|
|
78
|
+
print(f"WARNING: {path} is not a .css or .scss file — skipping.")
|
|
79
|
+
return []
|
|
80
|
+
return sorted(path.rglob("*.css")) + sorted(path.rglob("*.scss"))
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def audit_file(filepath: pathlib.Path) -> list[Issue]:
|
|
84
|
+
issues: list[Issue] = []
|
|
85
|
+
try:
|
|
86
|
+
lines = filepath.read_text(encoding="utf-8", errors="replace").splitlines()
|
|
87
|
+
except OSError as exc:
|
|
88
|
+
print(f"ERROR reading {filepath}: {exc}")
|
|
89
|
+
return []
|
|
90
|
+
|
|
91
|
+
file_str = filepath.as_posix()
|
|
92
|
+
full_text = "\n".join(lines)
|
|
93
|
+
|
|
94
|
+
has_animation = bool(
|
|
95
|
+
re.search(r"\b(transition|animation)\s*:", full_text)
|
|
96
|
+
)
|
|
97
|
+
has_reduced_motion = "prefers-reduced-motion" in full_text
|
|
98
|
+
|
|
99
|
+
for lineno, raw_line in enumerate(lines, start=1):
|
|
100
|
+
line = raw_line.strip()
|
|
101
|
+
if not line or line.startswith("//") or line.startswith("/*"):
|
|
102
|
+
continue
|
|
103
|
+
|
|
104
|
+
# 1. Animating layout-triggering properties
|
|
105
|
+
transition_match = re.match(r"transition\s*:\s*(.+)", line, re.IGNORECASE)
|
|
106
|
+
if transition_match:
|
|
107
|
+
props_part = transition_match.group(1)
|
|
108
|
+
for prop in LAYOUT_TRIGGERING:
|
|
109
|
+
if re.search(r"\b" + re.escape(prop) + r"\b", props_part, re.IGNORECASE):
|
|
110
|
+
issues.append(Issue(
|
|
111
|
+
file=file_str,
|
|
112
|
+
line=lineno,
|
|
113
|
+
category="layout_property",
|
|
114
|
+
snippet=line[:120],
|
|
115
|
+
advice=(
|
|
116
|
+
f"Animating '{prop}' triggers layout recalculation on every frame. "
|
|
117
|
+
"Use 'transform: translate/scale' or 'opacity' instead — "
|
|
118
|
+
"these are compositor-only and do not cause reflow."
|
|
119
|
+
),
|
|
120
|
+
))
|
|
121
|
+
|
|
122
|
+
# 2. transition: all
|
|
123
|
+
if re.search(r"transition\s*:\s*all\b", line, re.IGNORECASE):
|
|
124
|
+
issues.append(Issue(
|
|
125
|
+
file=file_str,
|
|
126
|
+
line=lineno,
|
|
127
|
+
category="transition_all",
|
|
128
|
+
snippet=line[:120],
|
|
129
|
+
advice=(
|
|
130
|
+
"'transition: all' animates every animatable property, including "
|
|
131
|
+
"layout-triggering ones you may not intend. List specific properties: "
|
|
132
|
+
"e.g., 'transition: opacity 0.2s ease-out, transform 0.2s ease-out'."
|
|
133
|
+
),
|
|
134
|
+
))
|
|
135
|
+
|
|
136
|
+
# 3 & 4. Duration checks — transition and animation shorthand
|
|
137
|
+
duration_patterns = [
|
|
138
|
+
re.compile(r"transition\s*:[^;]+", re.IGNORECASE),
|
|
139
|
+
re.compile(r"animation\s*:[^;]+", re.IGNORECASE),
|
|
140
|
+
re.compile(r"transition-duration\s*:\s*([^;]+)", re.IGNORECASE),
|
|
141
|
+
re.compile(r"animation-duration\s*:\s*([^;]+)", re.IGNORECASE),
|
|
142
|
+
]
|
|
143
|
+
for pat in duration_patterns:
|
|
144
|
+
m = pat.search(line)
|
|
145
|
+
if not m:
|
|
146
|
+
continue
|
|
147
|
+
value_str = m.group(0)
|
|
148
|
+
is_animation = "animation" in value_str.lower() and "transition" not in value_str.lower()
|
|
149
|
+
for dur_match in re.finditer(r"\d+(?:\.\d+)?(?:ms|s)\b", value_str):
|
|
150
|
+
dur_ms = parse_duration_ms(dur_match.group(0))
|
|
151
|
+
if dur_ms is None:
|
|
152
|
+
continue
|
|
153
|
+
slow_limit = 1000 if is_animation else 500
|
|
154
|
+
if dur_ms > slow_limit:
|
|
155
|
+
issues.append(Issue(
|
|
156
|
+
file=file_str,
|
|
157
|
+
line=lineno,
|
|
158
|
+
category="too_slow",
|
|
159
|
+
snippet=line[:120],
|
|
160
|
+
advice=(
|
|
161
|
+
f"Duration {dur_ms:.0f}ms feels sluggish for UI feedback. "
|
|
162
|
+
f"Keep UI transitions under {slow_limit}ms. "
|
|
163
|
+
"Aim for 200-300ms for most interactions."
|
|
164
|
+
),
|
|
165
|
+
))
|
|
166
|
+
elif dur_ms < 100 and dur_ms > 0:
|
|
167
|
+
issues.append(Issue(
|
|
168
|
+
file=file_str,
|
|
169
|
+
line=lineno,
|
|
170
|
+
category="too_fast",
|
|
171
|
+
snippet=line[:120],
|
|
172
|
+
advice=(
|
|
173
|
+
f"Duration {dur_ms:.0f}ms is below the human perception threshold (~100ms). "
|
|
174
|
+
"The animation will not be noticed. Use 100-200ms for snappy transitions."
|
|
175
|
+
),
|
|
176
|
+
))
|
|
177
|
+
|
|
178
|
+
# 5. Linear easing on transitions
|
|
179
|
+
if re.search(r"transition\s*:", line, re.IGNORECASE):
|
|
180
|
+
if re.search(r"\blinear\b", line, re.IGNORECASE):
|
|
181
|
+
issues.append(Issue(
|
|
182
|
+
file=file_str,
|
|
183
|
+
line=lineno,
|
|
184
|
+
category="linear_easing",
|
|
185
|
+
snippet=line[:120],
|
|
186
|
+
advice=(
|
|
187
|
+
"Linear easing feels mechanical and unnatural for UI elements. "
|
|
188
|
+
"Use 'ease-out' for elements entering the screen, 'ease-in' for "
|
|
189
|
+
"elements leaving, or a custom cubic-bezier for branded motion."
|
|
190
|
+
),
|
|
191
|
+
))
|
|
192
|
+
|
|
193
|
+
# 7. Infinite animation without pause mechanism
|
|
194
|
+
if re.search(r"animation-iteration-count\s*:\s*infinite\b", line, re.IGNORECASE):
|
|
195
|
+
# Check nearby lines (±10) for a paused state or play-state control
|
|
196
|
+
start = max(0, lineno - 10)
|
|
197
|
+
end = min(len(lines), lineno + 10)
|
|
198
|
+
context_block = "\n".join(lines[start:end])
|
|
199
|
+
if "animation-play-state" not in context_block and "paused" not in context_block:
|
|
200
|
+
issues.append(Issue(
|
|
201
|
+
file=file_str,
|
|
202
|
+
line=lineno,
|
|
203
|
+
category="infinite_no_pause",
|
|
204
|
+
snippet=line[:120],
|
|
205
|
+
advice=(
|
|
206
|
+
"Infinite animations can be distracting and drain battery on mobile. "
|
|
207
|
+
"Add 'animation-play-state: paused' controlled via :hover, :focus, "
|
|
208
|
+
"or a JS toggle so users can pause it."
|
|
209
|
+
),
|
|
210
|
+
))
|
|
211
|
+
|
|
212
|
+
# 6. Missing prefers-reduced-motion
|
|
213
|
+
if has_animation and not has_reduced_motion:
|
|
214
|
+
issues.append(Issue(
|
|
215
|
+
file=file_str,
|
|
216
|
+
line=0,
|
|
217
|
+
category="no_reduced_motion",
|
|
218
|
+
snippet="(entire file)",
|
|
219
|
+
advice=(
|
|
220
|
+
"This file contains animations but no '@media (prefers-reduced-motion: reduce)' "
|
|
221
|
+
"block. Add one to disable or reduce motion for users who request it — "
|
|
222
|
+
"required for WCAG 2.1 AA compliance."
|
|
223
|
+
),
|
|
224
|
+
))
|
|
225
|
+
|
|
226
|
+
return issues
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def print_issues(issues: list[Issue]) -> None:
|
|
230
|
+
for issue in issues:
|
|
231
|
+
loc = f"{issue.file}:{issue.line}" if issue.line else issue.file
|
|
232
|
+
category_label = CATEGORIES.get(issue.category, issue.category)
|
|
233
|
+
print(f"\n[{category_label}]")
|
|
234
|
+
print(f" Location : {loc}")
|
|
235
|
+
print(f" CSS : {issue.snippet}")
|
|
236
|
+
print(f" Fix : {issue.advice}")
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
def print_summary(issues: list[Issue]) -> None:
|
|
240
|
+
counts: dict[str, int] = defaultdict(int)
|
|
241
|
+
for issue in issues:
|
|
242
|
+
counts[issue.category] += 1
|
|
243
|
+
print("\n" + "=" * 60)
|
|
244
|
+
print("SUMMARY")
|
|
245
|
+
print("=" * 60)
|
|
246
|
+
if not counts:
|
|
247
|
+
print("No issues found.")
|
|
248
|
+
return
|
|
249
|
+
for cat, label in CATEGORIES.items():
|
|
250
|
+
count = counts.get(cat, 0)
|
|
251
|
+
if count:
|
|
252
|
+
print(f" {count:3d} {label}")
|
|
253
|
+
print(f" ---")
|
|
254
|
+
print(f" {sum(counts.values()):3d} Total issues")
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
def main() -> None:
|
|
258
|
+
parser = argparse.ArgumentParser(
|
|
259
|
+
description="Audit CSS/SCSS files for animation anti-patterns."
|
|
260
|
+
)
|
|
261
|
+
parser.add_argument(
|
|
262
|
+
"path",
|
|
263
|
+
help="A .css/.scss file or directory to scan recursively.",
|
|
264
|
+
)
|
|
265
|
+
args = parser.parse_args()
|
|
266
|
+
|
|
267
|
+
target = pathlib.Path(args.path)
|
|
268
|
+
if not target.exists():
|
|
269
|
+
print(f"ERROR: Path not found: {target}")
|
|
270
|
+
sys.exit(1)
|
|
271
|
+
|
|
272
|
+
files = find_css_files(target)
|
|
273
|
+
if not files:
|
|
274
|
+
print("No .css or .scss files found.")
|
|
275
|
+
sys.exit(0)
|
|
276
|
+
|
|
277
|
+
print(f"Scanning {len(files)} file(s) ...\n")
|
|
278
|
+
|
|
279
|
+
all_issues: list[Issue] = []
|
|
280
|
+
for f in files:
|
|
281
|
+
file_issues = audit_file(f)
|
|
282
|
+
all_issues.extend(file_issues)
|
|
283
|
+
|
|
284
|
+
if all_issues:
|
|
285
|
+
print_issues(all_issues)
|
|
286
|
+
else:
|
|
287
|
+
print("No animation anti-patterns detected.")
|
|
288
|
+
|
|
289
|
+
print_summary(all_issues)
|
|
290
|
+
|
|
291
|
+
sys.exit(1 if all_issues else 0)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
if __name__ == "__main__":
|
|
295
|
+
main()
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: booklib-mcp-guide
|
|
3
|
+
version: "1.0"
|
|
4
|
+
license: MIT
|
|
5
|
+
tags: [meta, mcp, tools, agent-guide]
|
|
6
|
+
description: "Use when working with BookLib MCP tools. Reference for lookup, review, remember, verify, guard — parameters, workflows, and anti-patterns."
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# BookLib MCP Tool Guide
|
|
10
|
+
|
|
11
|
+
BookLib exposes 5 MCP tools to AI coding agents. Each tool has a single purpose. This guide covers when to call each one, what parameters to pass, and common workflows.
|
|
12
|
+
|
|
13
|
+
## Tool Reference
|
|
14
|
+
|
|
15
|
+
| Tool | When to call | Key params |
|
|
16
|
+
|------|-------------|------------|
|
|
17
|
+
| `lookup` | Before working with unfamiliar APIs or post-training deps | `query` (required), `file`, `limit`, `source` |
|
|
18
|
+
| `review` | User asks for deep code review of a specific file | `skill_name`, `file_path` (both required) |
|
|
19
|
+
| `remember` | User says "remember this", "capture", or makes a team decision | `title` (required), `content`, `type`, `tags` |
|
|
20
|
+
| `verify` | After writing code that uses unfamiliar or new APIs | `file_path` (required) |
|
|
21
|
+
| `guard` | After writing code that touches architecture or API choices | `file_path` (required) |
|
|
22
|
+
|
|
23
|
+
## Decision Tree
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Need current docs for a post-training library -> lookup
|
|
27
|
+
Need a full expert review of a file -> review
|
|
28
|
+
User wants to save a decision or insight -> remember
|
|
29
|
+
Code uses unknown imports -> verify
|
|
30
|
+
Code might violate team rules -> guard
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Tool Details
|
|
34
|
+
|
|
35
|
+
### lookup
|
|
36
|
+
|
|
37
|
+
Searches across post-training corrections, team knowledge, and expert skills. Returns structured principles with source citations.
|
|
38
|
+
|
|
39
|
+
Parameters:
|
|
40
|
+
- `query` (string, required): What you need to know. Include the library name and task.
|
|
41
|
+
- `file` (string): Path to the file being worked on. Adds language and component context.
|
|
42
|
+
- `limit` (number): Maximum results. Default: 3.
|
|
43
|
+
- `source` (enum: all/skills/knowledge): Filter by source type.
|
|
44
|
+
|
|
45
|
+
Prioritization order: (1) post-training gap corrections, (2) team knowledge nodes, (3) expert skill principles.
|
|
46
|
+
|
|
47
|
+
### review
|
|
48
|
+
|
|
49
|
+
Audits a file against a named skill's principles. Returns structured findings with line references and citations.
|
|
50
|
+
|
|
51
|
+
Parameters:
|
|
52
|
+
- `skill_name` (string, required): The skill to review against (e.g., "effective-kotlin", "clean-code-reviewer").
|
|
53
|
+
- `file_path` (string, required): Path to the file to review.
|
|
54
|
+
|
|
55
|
+
### remember
|
|
56
|
+
|
|
57
|
+
Creates a searchable knowledge node. Automatically indexed and auto-linked to related nodes.
|
|
58
|
+
|
|
59
|
+
Parameters:
|
|
60
|
+
- `title` (string, required): Short descriptive title.
|
|
61
|
+
- `content` (string): Detailed description in markdown.
|
|
62
|
+
- `type` (enum: insight/decision/pattern/note/research): Node type. Default: "insight".
|
|
63
|
+
- `tags` (string): Comma-separated tags.
|
|
64
|
+
- `links` (string): Link targets as "target:edge-type" pairs.
|
|
65
|
+
|
|
66
|
+
### verify
|
|
67
|
+
|
|
68
|
+
Checks if a file's imports are covered by BookLib's index. Flags unknown post-training APIs that may need current docs.
|
|
69
|
+
|
|
70
|
+
Parameters:
|
|
71
|
+
- `file_path` (string, required): Path to the source file.
|
|
72
|
+
|
|
73
|
+
Returns: list of unknown imports with suggested documentation URLs.
|
|
74
|
+
|
|
75
|
+
### guard
|
|
76
|
+
|
|
77
|
+
Checks if code contradicts captured team decisions. Compares code patterns against decision nodes.
|
|
78
|
+
|
|
79
|
+
Parameters:
|
|
80
|
+
- `file_path` (string, required): Path to the source file.
|
|
81
|
+
|
|
82
|
+
Returns: list of contradictions with the violated decision and source.
|
|
83
|
+
|
|
84
|
+
## Common Workflows
|
|
85
|
+
|
|
86
|
+
### 1. Gap detection and resolution
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
verify file.ts -> finds unknown import "@stripe/stripe-js"
|
|
90
|
+
lookup "stripe js v5 api" -> returns current v5 docs
|
|
91
|
+
-> write correct code using current API
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 2. Team knowledge enforcement
|
|
95
|
+
|
|
96
|
+
```
|
|
97
|
+
write code -> make architectural choice
|
|
98
|
+
guard file.ts -> flags: contradicts "use PaymentIntents not Charges"
|
|
99
|
+
-> fix the violation, commit
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 3. Knowledge capture during work
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
discover a useful pattern -> remember "retry with exponential backoff" --type pattern
|
|
106
|
+
make a team decision -> remember "use PaymentIntents not Charges" --type decision
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Anti-Patterns
|
|
110
|
+
|
|
111
|
+
- **Don't call `lookup` for standard patterns.** React hooks, Python builtins, Go stdlib -- you already know these. Only call for project-specific or post-training knowledge.
|
|
112
|
+
- **Don't call `verify` on stdlib imports.** Standard library imports are always known. Only check third-party imports.
|
|
113
|
+
- **Don't call `remember` for ephemeral notes.** Only capture durable decisions, patterns, and insights that future sessions should know about.
|
|
114
|
+
- **Don't call `review` without a specific skill.** The skill_name parameter is required -- pick the most relevant one or use "clean-code-reviewer" as default.
|
|
115
|
+
- **Don't over-call tools.** One `lookup` per topic is enough. Don't repeat the same query hoping for different results.
|
|
116
|
+
|
|
117
|
+
## CLI-Only Commands (Not MCP Tools)
|
|
118
|
+
|
|
119
|
+
These features are available via the `booklib` CLI but not exposed as MCP tools:
|
|
120
|
+
|
|
121
|
+
- `booklib connect <path>` -- connect a documentation source
|
|
122
|
+
- `booklib connect github releases <repo>` -- index GitHub changelogs
|
|
123
|
+
- `booklib connect notion database <id>` -- index Notion pages
|
|
124
|
+
- `booklib link <from> <to> --type <edge>` -- connect two knowledge nodes
|
|
125
|
+
- `booklib save-state --goal "..." --next "..."` -- save session for handoff
|
|
126
|
+
- `booklib nodes list` / `booklib nodes show <id>` -- list and inspect knowledge
|
|
127
|
+
- `booklib gaps` / `booklib resolve-gaps` -- detect and fix knowledge gaps
|
|
128
|
+
- `booklib analyze` -- show affected files and post-training APIs
|
|
129
|
+
- `booklib doctor` -- health check
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"evals": [
|
|
3
|
+
{
|
|
4
|
+
"id": "eval-01-lookup-trigger",
|
|
5
|
+
"prompt": "You are editing frontend/src/lib/supabase.ts which imports @supabase/supabase-js.\nThe file currently has:\n\nimport { createClient } from '@supabase/supabase-js'\n\nconst supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!\nconst supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!\n\nexport const supabase = createClient(supabaseUrl, supabaseKey)\n\nYou need to add user authentication with email/password sign-in.\nBefore writing auth code, what BookLib tool should you call and why?",
|
|
6
|
+
"expectations": [
|
|
7
|
+
"Should call lookup with a query about supabase auth",
|
|
8
|
+
"Should NOT call lookup for standard TypeScript features",
|
|
9
|
+
"Should mention that supabase may be post-training",
|
|
10
|
+
"Should wait for lookup results before writing auth code",
|
|
11
|
+
"Should use the results to write correct v2 auth patterns"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
"id": "eval-02-guard-trigger",
|
|
16
|
+
"prompt": "You just wrote a payment processing module at src/payments/charge.ts:\n\nimport Stripe from 'stripe'\n\nconst stripe = new Stripe(process.env.STRIPE_SECRET_KEY!)\n\nexport async function processPayment(amount: number) {\n const charge = await stripe.charges.create({\n amount,\n currency: 'usd',\n source: 'tok_visa',\n })\n return charge\n}\n\nThe team previously decided to use PaymentIntents instead of Charges.\nWhat BookLib tool catches this violation and how does it work?",
|
|
17
|
+
"expectations": [
|
|
18
|
+
"Should mention the guard tool",
|
|
19
|
+
"Should explain guard checks code against team decisions",
|
|
20
|
+
"Should note the team decision about PaymentIntents",
|
|
21
|
+
"Should suggest fixing the code to use PaymentIntents",
|
|
22
|
+
"Should mention that guard runs automatically via PostToolUse hooks"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "eval-03-verify-trigger",
|
|
27
|
+
"prompt": "You added zod@3.25 to the project and wrote this validation module at src/lib/validate.ts:\n\nimport { z } from 'zod'\n\nexport const UserSchema = z.object({\n name: z.string().min(1),\n email: z.string().email(),\n age: z.number().int().positive(),\n role: z.enum(['admin', 'user', 'guest']),\n})\n\nexport type User = z.infer<typeof UserSchema>\n\nHow do you check if BookLib has documentation for this version of zod?\nWhat happens if zod@3.25 is a post-training library?",
|
|
28
|
+
"expectations": [
|
|
29
|
+
"Should mention the verify tool",
|
|
30
|
+
"Should explain verify checks if imports are in the BookLib index",
|
|
31
|
+
"Should note that zod@3.25 may be post-training",
|
|
32
|
+
"Should suggest running booklib verify on the file",
|
|
33
|
+
"Should mention that verify also runs automatically via hooks"
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# After: Agent calls BookLib lookup before writing code
|
|
2
|
+
|
|
3
|
+
The agent calls lookup("supabase auth session") and gets the current v2.95 API.
|
|
4
|
+
It then writes code using the correct patterns.
|
|
5
|
+
|
|
6
|
+
```typescript
|
|
7
|
+
import { createClient } from '@supabase/supabase-js'
|
|
8
|
+
|
|
9
|
+
const supabase = createClient(url, key, {
|
|
10
|
+
auth: {
|
|
11
|
+
autoRefreshToken: true,
|
|
12
|
+
persistSession: true,
|
|
13
|
+
},
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
// Correct: v2.95 session pattern
|
|
17
|
+
const { data: { session } } = await supabase.auth.getSession()
|
|
18
|
+
|
|
19
|
+
// Correct: v2 sign-in with password
|
|
20
|
+
const { data, error } = await supabase.auth.signInWithPassword({
|
|
21
|
+
email: 'user@example.com',
|
|
22
|
+
password: 'password123',
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// Correct: v2 realtime channel pattern
|
|
26
|
+
const channel = supabase
|
|
27
|
+
.channel('messages')
|
|
28
|
+
.on('postgres_changes', { event: 'INSERT', schema: 'public' }, payload => {
|
|
29
|
+
console.log(payload)
|
|
30
|
+
})
|
|
31
|
+
.subscribe()
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The agent used current APIs because BookLib injected the correct knowledge.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Before: Agent writes code without checking BookLib for post-training knowledge
|
|
2
|
+
|
|
3
|
+
The agent is asked to create a Supabase auth flow. Without calling the BookLib
|
|
4
|
+
lookup tool, it uses patterns from its training data which are outdated.
|
|
5
|
+
|
|
6
|
+
```typescript
|
|
7
|
+
import { createClient } from '@supabase/supabase-js'
|
|
8
|
+
|
|
9
|
+
const supabase = createClient(url, key)
|
|
10
|
+
|
|
11
|
+
// Wrong: uses deprecated v1 auth pattern
|
|
12
|
+
const { data, error } = await supabase.auth.session()
|
|
13
|
+
|
|
14
|
+
// Wrong: old sign-in method
|
|
15
|
+
const { user, error: signInError } = await supabase.auth.signIn({
|
|
16
|
+
email: 'user@example.com',
|
|
17
|
+
password: 'password123',
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// Wrong: old subscription pattern
|
|
21
|
+
const subscription = supabase
|
|
22
|
+
.from('messages')
|
|
23
|
+
.on('INSERT', payload => console.log(payload))
|
|
24
|
+
.subscribe()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The code compiles but uses deprecated APIs that will fail at runtime.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# BookLib MCP Tool Catalog
|
|
2
|
+
|
|
3
|
+
| Tool | Purpose | Key Parameters |
|
|
4
|
+
|------|---------|---------------|
|
|
5
|
+
| lookup | Search for post-training docs, team decisions, expert knowledge | query, file, limit, source |
|
|
6
|
+
| review | Deep code review against a named skill | skill_name, file_path |
|
|
7
|
+
| remember | Capture a team decision or insight | title, type, tags |
|
|
8
|
+
| verify | Check if imports are covered by the index | file_path |
|
|
9
|
+
| guard | Check if code contradicts team decisions | file_path |
|