@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,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The BookLib Curated Registry.
|
|
3
|
+
*
|
|
4
|
+
* Each entry describes a skill — where it lives, what triggers it,
|
|
5
|
+
* and which languages it applies to. The `source` field tells the
|
|
6
|
+
* skill fetcher how to retrieve the skill content.
|
|
7
|
+
*
|
|
8
|
+
* source.type values:
|
|
9
|
+
* "npm" — bundled in this package, available at source.path
|
|
10
|
+
* "github" — raw content fetched from source.url
|
|
11
|
+
*/
|
|
12
|
+
export const SKILL_REGISTRY = [
|
|
13
|
+
{
|
|
14
|
+
name: 'clean-code-reviewer',
|
|
15
|
+
description: 'Principles for readable, maintainable, and expressive code.',
|
|
16
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/clean-code-reviewer' },
|
|
17
|
+
triggers: { extensions: ['.js', '.ts', '.py', '.java', '.kt', '.rb'], keywords: ['naming', 'functions', 'refactor', 'smells', 'clean code'] },
|
|
18
|
+
languages: ['all'],
|
|
19
|
+
version: '1.10.0',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
name: 'effective-kotlin',
|
|
23
|
+
description: 'Best practices for safety, readability, and efficiency in Kotlin.',
|
|
24
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/effective-kotlin' },
|
|
25
|
+
triggers: { extensions: ['.kt', '.kts'], keywords: ['kotlin', 'null safety', 'mutability', 'coroutines'] },
|
|
26
|
+
languages: ['kotlin'],
|
|
27
|
+
version: '1.10.0',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'effective-typescript',
|
|
31
|
+
description: 'Type-safe patterns from the 62 items of Effective TypeScript.',
|
|
32
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/effective-typescript' },
|
|
33
|
+
triggers: { extensions: ['.ts', '.tsx'], keywords: ['typescript', 'type safety', 'any', 'generics', 'inference'] },
|
|
34
|
+
languages: ['typescript'],
|
|
35
|
+
version: '1.10.0',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
name: 'effective-python',
|
|
39
|
+
description: 'Pythonic patterns from Effective Python 3rd edition.',
|
|
40
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/effective-python' },
|
|
41
|
+
triggers: { extensions: ['.py'], keywords: ['python', 'pythonic', 'comprehensions', 'generators', 'async'] },
|
|
42
|
+
languages: ['python'],
|
|
43
|
+
version: '1.10.0',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'effective-java',
|
|
47
|
+
description: 'Best practices from Effective Java 3rd edition.',
|
|
48
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/effective-java' },
|
|
49
|
+
triggers: { extensions: ['.java'], keywords: ['java', 'generics', 'concurrency', 'immutability', 'builder'] },
|
|
50
|
+
languages: ['java'],
|
|
51
|
+
version: '1.10.0',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: 'domain-driven-design',
|
|
55
|
+
description: 'DDD patterns: aggregates, value objects, bounded contexts.',
|
|
56
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/domain-driven-design' },
|
|
57
|
+
triggers: { extensions: ['.ts', '.java', '.kt', '.py'], keywords: ['domain', 'aggregate', 'entity', 'value object', 'bounded context', 'ddd'] },
|
|
58
|
+
languages: ['all'],
|
|
59
|
+
version: '1.10.0',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'microservices-patterns',
|
|
63
|
+
description: 'Patterns for building reliable microservices.',
|
|
64
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/microservices-patterns' },
|
|
65
|
+
triggers: { extensions: ['.ts', '.java', '.py', '.go'], keywords: ['microservices', 'saga', 'event', 'api gateway', 'service mesh'] },
|
|
66
|
+
languages: ['all'],
|
|
67
|
+
version: '1.10.0',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'system-design-interview',
|
|
71
|
+
description: 'High-level patterns for scalability, estimation, and distributed systems.',
|
|
72
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/system-design-interview' },
|
|
73
|
+
triggers: { extensions: ['.md', '.ts', '.java'], keywords: ['scalability', 'load balancer', 'caching', 'replication', 'sharding'] },
|
|
74
|
+
languages: ['all'],
|
|
75
|
+
version: '1.10.0',
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'data-intensive-patterns',
|
|
79
|
+
description: 'Patterns for data systems: storage, replication, consistency.',
|
|
80
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/data-intensive-patterns' },
|
|
81
|
+
triggers: { extensions: ['.py', '.java', '.scala', '.ts'], keywords: ['data', 'replication', 'consistency', 'stream', 'batch', 'kafka'] },
|
|
82
|
+
languages: ['all'],
|
|
83
|
+
version: '1.10.0',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'refactoring-ui',
|
|
87
|
+
description: 'Visual design principles for developers building UI.',
|
|
88
|
+
source: { type: 'npm', package: '@booklib/skills', path: 'skills/refactoring-ui' },
|
|
89
|
+
triggers: { extensions: ['.tsx', '.jsx', '.css', '.html', '.svelte', '.vue'], keywords: ['ui', 'design', 'spacing', 'typography', 'color', 'tailwind'] },
|
|
90
|
+
languages: ['typescript', 'javascript', 'css'],
|
|
91
|
+
version: '1.10.0',
|
|
92
|
+
},
|
|
93
|
+
// External / community skills (fetched from GitHub on demand)
|
|
94
|
+
{
|
|
95
|
+
name: 'superpowers-debug',
|
|
96
|
+
description: 'Systematic debugging workflow.',
|
|
97
|
+
source: { type: 'github', url: 'https://raw.githubusercontent.com/obra/superpowers/main/skills/debugging.md' },
|
|
98
|
+
triggers: { extensions: [], keywords: ['debugging', 'troubleshooting', 'systematic', 'bug'] },
|
|
99
|
+
languages: ['all'],
|
|
100
|
+
version: null,
|
|
101
|
+
},
|
|
102
|
+
];
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { SKILL_REGISTRY } from './registry/skills.js';
|
|
2
|
+
import { BookLibSearcher } from './engine/searcher.js';
|
|
3
|
+
import { resolveBookLibPaths } from './paths.js';
|
|
4
|
+
import { loadConfig } from './config-loader.js';
|
|
5
|
+
import { DiscoveryEngine } from './discovery-engine.js';
|
|
6
|
+
import { ConflictResolver } from './conflict-resolver.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Orchestrates the 'Suggested Retrieval' flow.
|
|
10
|
+
* Combines local semantic search with registry-level keyword suggestions.
|
|
11
|
+
*/
|
|
12
|
+
export class BookLibRegistrySearcher {
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
this.projectCwd = options.projectCwd;
|
|
15
|
+
const paths = resolveBookLibPaths(options.projectCwd);
|
|
16
|
+
this.searcher = new BookLibSearcher(paths.indexPath);
|
|
17
|
+
this.config = loadConfig(options.projectCwd);
|
|
18
|
+
this.threshold = this.config.search.registryFallbackThreshold;
|
|
19
|
+
this.minScore = this.config.search.minScore;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async searchHybrid(query, options = {}) {
|
|
23
|
+
const { useGraph = false } = options;
|
|
24
|
+
// 1. Perform local semantic search
|
|
25
|
+
let localResults = [];
|
|
26
|
+
try {
|
|
27
|
+
localResults = await this.searcher.search(query, 5, this.minScore, { useGraph });
|
|
28
|
+
} catch {
|
|
29
|
+
// Local index might not exist yet
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// 2. Fall back to keyword matching across bundled registry + community manifest
|
|
33
|
+
const bestLocalScore = localResults[0]?.score ?? 0;
|
|
34
|
+
const useFallback = bestLocalScore < this.threshold;
|
|
35
|
+
|
|
36
|
+
let suggestions = [];
|
|
37
|
+
if (useFallback) {
|
|
38
|
+
const queryLower = query.toLowerCase();
|
|
39
|
+
const queryWords = queryLower.split(/\s+/).filter(w => w.length > 2);
|
|
40
|
+
|
|
41
|
+
const matchesQuery = (skill) => {
|
|
42
|
+
if (!skill.triggers?.keywords) return false;
|
|
43
|
+
const keywordMatch = skill.triggers.keywords.some(k => {
|
|
44
|
+
const kLower = k.toLowerCase();
|
|
45
|
+
return queryLower.includes(kLower) ||
|
|
46
|
+
kLower.split(/\s+/).some(kw => queryWords.includes(kw));
|
|
47
|
+
});
|
|
48
|
+
return keywordMatch ||
|
|
49
|
+
skill.name.toLowerCase().includes(queryLower) ||
|
|
50
|
+
queryWords.some(w => (skill.description ?? '').toLowerCase().includes(w));
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const alreadyLocal = (skill) =>
|
|
54
|
+
localResults.some(r => r.metadata?.name === (skill.name ?? skill.id));
|
|
55
|
+
|
|
56
|
+
// Bundled registry suggestions
|
|
57
|
+
const bundledSuggestions = SKILL_REGISTRY.filter(s => matchesQuery(s) && !alreadyLocal(s));
|
|
58
|
+
|
|
59
|
+
// Community manifest suggestions (cached — no network call)
|
|
60
|
+
let communitySuggestions = [];
|
|
61
|
+
try {
|
|
62
|
+
const engine = new DiscoveryEngine({ projectCwd: this.projectCwd });
|
|
63
|
+
const discovered = await engine.discover();
|
|
64
|
+
communitySuggestions = discovered.filter(s => matchesQuery(s) && !alreadyLocal(s));
|
|
65
|
+
} catch { /* non-fatal */ }
|
|
66
|
+
|
|
67
|
+
suggestions = [...bundledSuggestions, ...communitySuggestions];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Run conflict resolution on suggestions using community registry metadata
|
|
71
|
+
let resolved = { winners: suggestions, suppressed: [], conflicts: [] };
|
|
72
|
+
if (suggestions.length > 1) {
|
|
73
|
+
try {
|
|
74
|
+
const engine = new DiscoveryEngine({ projectCwd: this.projectCwd });
|
|
75
|
+
const allSkills = await engine.discover();
|
|
76
|
+
const resolver = new ConflictResolver(allSkills);
|
|
77
|
+
resolved = resolver.resolveSkills(suggestions);
|
|
78
|
+
} catch { /* non-fatal — fall back to unresolved list */ }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Run conflict resolution on local chunks — only for named skill chunks.
|
|
82
|
+
// Project docs (Context7, GitHub, local) have no skill name and should pass through.
|
|
83
|
+
const namedChunks = localResults.filter(r => r.metadata?.name);
|
|
84
|
+
const unnamedChunks = localResults.filter(r => !r.metadata?.name);
|
|
85
|
+
let resolvedLocal = { winners: [...unnamedChunks], suppressed: [], conflicts: [] };
|
|
86
|
+
if (namedChunks.length > 1) {
|
|
87
|
+
try {
|
|
88
|
+
const engine = new DiscoveryEngine({ projectCwd: this.projectCwd });
|
|
89
|
+
const allSkills = await engine.discover();
|
|
90
|
+
const resolver = new ConflictResolver(allSkills);
|
|
91
|
+
const resolved2 = resolver.resolveChunks(namedChunks);
|
|
92
|
+
resolvedLocal.winners = [...resolved2.winners, ...unnamedChunks];
|
|
93
|
+
resolvedLocal.suppressed = resolved2.suppressed;
|
|
94
|
+
resolvedLocal.conflicts = resolved2.conflicts;
|
|
95
|
+
} catch { /* non-fatal */ }
|
|
96
|
+
} else if (namedChunks.length === 1) {
|
|
97
|
+
resolvedLocal.winners = [namedChunks[0], ...unnamedChunks];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
local: resolvedLocal.winners,
|
|
102
|
+
suggested: resolved.winners,
|
|
103
|
+
suppressed: [...(resolvedLocal.suppressed ?? []), ...(resolved.suppressed ?? [])],
|
|
104
|
+
conflicts: [...(resolvedLocal.conflicts ?? []), ...(resolved.conflicts ?? [])],
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// lib/rules/rules-manager.js
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import os from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
|
|
7
|
+
const PACKAGE_ROOT = path.resolve(fileURLToPath(import.meta.url), '..', '..', '..');
|
|
8
|
+
const RULES_DIR = path.join(PACKAGE_ROOT, 'rules');
|
|
9
|
+
|
|
10
|
+
function markerStart(lang) { return `<!-- booklib-rules-${lang}-start -->`; }
|
|
11
|
+
function markerEnd(lang) { return `<!-- booklib-rules-${lang}-end -->`; }
|
|
12
|
+
function escapeRegex(s) { return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); }
|
|
13
|
+
|
|
14
|
+
function _ensureAlwaysApply(content) {
|
|
15
|
+
if (!content.trimStart().startsWith('---')) {
|
|
16
|
+
// No frontmatter — add complete block
|
|
17
|
+
return `---\nalwaysApply: false\n---\n\n${content}`;
|
|
18
|
+
}
|
|
19
|
+
// Has frontmatter — check if alwaysApply is already set
|
|
20
|
+
if (content.includes('alwaysApply:')) return content;
|
|
21
|
+
// Inject alwaysApply before the closing ---
|
|
22
|
+
// Frontmatter ends at the first \n---\n (or \n--- at EOF) after the opening ---
|
|
23
|
+
const fmEnd = content.indexOf('\n---', 3); // skip the opening ---
|
|
24
|
+
if (fmEnd === -1) return content; // malformed, leave as-is
|
|
25
|
+
return content.slice(0, fmEnd) + '\nalwaysApply: false' + content.slice(fmEnd);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Lists all bundled language rule sets with project/global install status.
|
|
30
|
+
*/
|
|
31
|
+
export function listAvailable(cwd = process.cwd(), home = os.homedir()) {
|
|
32
|
+
if (!fs.existsSync(RULES_DIR)) return [];
|
|
33
|
+
|
|
34
|
+
const claudeMdPath = path.join(home, '.claude', 'CLAUDE.md');
|
|
35
|
+
const claudeMdContent = fs.existsSync(claudeMdPath)
|
|
36
|
+
? fs.readFileSync(claudeMdPath, 'utf8')
|
|
37
|
+
: '';
|
|
38
|
+
|
|
39
|
+
const langDirs = fs.readdirSync(RULES_DIR, { withFileTypes: true })
|
|
40
|
+
.filter(e => e.isDirectory())
|
|
41
|
+
.map(e => e.name);
|
|
42
|
+
|
|
43
|
+
return langDirs.map(lang => {
|
|
44
|
+
const files = fs.readdirSync(path.join(RULES_DIR, lang))
|
|
45
|
+
.filter(f => f.endsWith('.md'));
|
|
46
|
+
|
|
47
|
+
const cursorRulesDir = path.join(cwd, '.cursor', 'rules');
|
|
48
|
+
const installedProject = fs.existsSync(cursorRulesDir) &&
|
|
49
|
+
fs.readdirSync(cursorRulesDir).some(f => f.startsWith(`${lang}-`) && f.endsWith('.mdc'));
|
|
50
|
+
|
|
51
|
+
const installedGlobal = claudeMdContent.includes(markerStart(lang));
|
|
52
|
+
|
|
53
|
+
return { lang, files, installedProject, installedGlobal };
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Installs a language rule set to the project (.cursor/rules/) or globally (~/.claude/CLAUDE.md).
|
|
59
|
+
*
|
|
60
|
+
* @param {string} lang
|
|
61
|
+
* @param {{ cwd?, home?, global?, dryRun? }} opts
|
|
62
|
+
* @returns {string[]} written file paths
|
|
63
|
+
*/
|
|
64
|
+
export function installRule(lang, {
|
|
65
|
+
cwd = process.cwd(),
|
|
66
|
+
home = os.homedir(),
|
|
67
|
+
global: isGlobal = false,
|
|
68
|
+
dryRun = false,
|
|
69
|
+
} = {}) {
|
|
70
|
+
const langDir = path.join(RULES_DIR, lang);
|
|
71
|
+
if (!fs.existsSync(langDir)) {
|
|
72
|
+
const available = fs.readdirSync(RULES_DIR, { withFileTypes: true })
|
|
73
|
+
.filter(e => e.isDirectory()).map(e => e.name);
|
|
74
|
+
throw new Error(`Unknown language: '${lang}'. Available: ${available.join(', ')}`);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const mdFiles = fs.readdirSync(langDir).filter(f => f.endsWith('.md'));
|
|
78
|
+
if (mdFiles.length === 0) return [];
|
|
79
|
+
|
|
80
|
+
return isGlobal
|
|
81
|
+
? _installGlobal(lang, langDir, mdFiles, home, dryRun)
|
|
82
|
+
: _installProject(lang, langDir, mdFiles, cwd, dryRun);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function _installProject(lang, langDir, mdFiles, cwd, dryRun) {
|
|
86
|
+
const destDir = path.join(cwd, '.cursor', 'rules');
|
|
87
|
+
const written = [];
|
|
88
|
+
|
|
89
|
+
if (!dryRun) {
|
|
90
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
for (const file of mdFiles) {
|
|
94
|
+
const content = _ensureAlwaysApply(fs.readFileSync(path.join(langDir, file), 'utf8'));
|
|
95
|
+
const destPath = path.join(destDir, `${lang}-${file.replace(/\.md$/, '.mdc')}`);
|
|
96
|
+
if (!dryRun) {
|
|
97
|
+
fs.writeFileSync(destPath, content);
|
|
98
|
+
}
|
|
99
|
+
written.push(destPath);
|
|
100
|
+
}
|
|
101
|
+
return written;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function _installGlobal(lang, langDir, mdFiles, home, dryRun) {
|
|
105
|
+
const claudeDir = path.join(home, '.claude');
|
|
106
|
+
const claudeMdPath = path.join(claudeDir, 'CLAUDE.md');
|
|
107
|
+
|
|
108
|
+
const body = mdFiles
|
|
109
|
+
.map(f => fs.readFileSync(path.join(langDir, f), 'utf8'))
|
|
110
|
+
.join('\n\n');
|
|
111
|
+
|
|
112
|
+
const section = [
|
|
113
|
+
markerStart(lang),
|
|
114
|
+
`## ${lang.charAt(0).toUpperCase() + lang.slice(1)} Standards (BookLib)`,
|
|
115
|
+
'',
|
|
116
|
+
body,
|
|
117
|
+
markerEnd(lang),
|
|
118
|
+
].join('\n');
|
|
119
|
+
|
|
120
|
+
if (!dryRun) {
|
|
121
|
+
fs.mkdirSync(claudeDir, { recursive: true });
|
|
122
|
+
let existing = '';
|
|
123
|
+
try { existing = fs.readFileSync(claudeMdPath, 'utf8'); } catch (err) {
|
|
124
|
+
if (err.code !== 'ENOENT') throw err;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const re = new RegExp(
|
|
128
|
+
`${escapeRegex(markerStart(lang))}[\\s\\S]*?${escapeRegex(markerEnd(lang))}`,
|
|
129
|
+
);
|
|
130
|
+
const updated = existing.includes(markerStart(lang))
|
|
131
|
+
? existing.replace(re, section)
|
|
132
|
+
: (existing ? `${existing}\n\n${section}\n` : `${section}\n`);
|
|
133
|
+
|
|
134
|
+
fs.writeFileSync(claudeMdPath, updated);
|
|
135
|
+
}
|
|
136
|
+
return [claudeMdPath];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Returns sizes of all installed rules in the current project and globally.
|
|
141
|
+
*/
|
|
142
|
+
export function status(cwd = process.cwd(), home = os.homedir()) {
|
|
143
|
+
const cursorRulesDir = path.join(cwd, '.cursor', 'rules');
|
|
144
|
+
const claudeMdPath = path.join(home, '.claude', 'CLAUDE.md');
|
|
145
|
+
|
|
146
|
+
const cursor = [];
|
|
147
|
+
if (fs.existsSync(cursorRulesDir)) {
|
|
148
|
+
for (const file of fs.readdirSync(cursorRulesDir)) {
|
|
149
|
+
if (!file.endsWith('.mdc')) continue;
|
|
150
|
+
const p = path.join(cursorRulesDir, file);
|
|
151
|
+
cursor.push({ path: p, sizeBytes: fs.statSync(p).size });
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const globalEntries = [];
|
|
156
|
+
if (fs.existsSync(claudeMdPath)) {
|
|
157
|
+
const content = fs.readFileSync(claudeMdPath, 'utf8');
|
|
158
|
+
const re = /<!-- booklib-rules-(\w+)-start -->([\s\S]*?)<!-- booklib-rules-\1-end -->/g;
|
|
159
|
+
let match;
|
|
160
|
+
while ((match = re.exec(content)) !== null) {
|
|
161
|
+
globalEntries.push({ lang: match[1], sizeBytes: Buffer.byteLength(match[0], 'utf8') });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
const totalBytes = cursor.reduce((s, c) => s + c.sizeBytes, 0) +
|
|
166
|
+
globalEntries.reduce((s, g) => s + g.sizeBytes, 0);
|
|
167
|
+
|
|
168
|
+
return { cursor, global: globalEntries, totalBytes };
|
|
169
|
+
}
|