diff --git a/docs/registry/nodes.yaml b/docs/registry/nodes.yaml index b993a6a7..5a41613c 100644 --- a/docs/registry/nodes.yaml +++ b/docs/registry/nodes.yaml @@ -1,6 +1,261 @@ version: "0.1.0" nodes: + - id: "#2" + name: "Playwright MCP" + slug: "playwright-mcp" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "html prototype", weight: 1.0} + - {keyword: "screenshot", weight: 1.0} + - {keyword: "interaction smoke", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #2" + + - id: "#3" + name: "GitHub MCP" + slug: "github-mcp" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "issues", weight: 1.0} + - {keyword: "pr", weight: 1.0} + - {keyword: "commits", weight: 1.0} + - {keyword: "открытые вопросы", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #3" + + - id: "#4" + name: "markdownlint-cli2" + slug: "markdownlint" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "lint .md", weight: 1.0} + - {keyword: "markdown style", weight: 1.0} + - {keyword: "заголовки/таблицы", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #4" + install: "npm run lint:md" + + - id: "#5" + name: "cspell" + slug: "cspell" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "орфография ru/en", weight: 1.0} + - {keyword: "кастомный словарь", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #5" + install: "npm run spell" + + - id: "#6" + name: "lychee" + slug: "lychee" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "проверка ссылок .md", weight: 1.0} + - {keyword: "кросс-ссылки архива", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #6" + install: "npm run links" + + - id: "#7" + name: "Stylelint" + slug: "stylelint" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "css lint", weight: 1.0} + - {keyword: "vue sfc style", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #7" + install: "npm run lint:css" + + - id: "#8" + name: "gitleaks" + slug: "gitleaks" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "секреты в diff", weight: 1.0} + - {keyword: "pre-commit hook", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #8" + + - id: "#9" + name: "Pa11y" + slug: "pa11y" + category: "phase-0" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "a11y wcag 2.1 aa", weight: 1.0} + - {keyword: "прототипы", weight: 1.0} + - {keyword: "технический sot", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§2.4 #9" + install: "npm run a11y" + + - id: "#10" + name: "Laravel Boost" + slug: "boost" + category: "phase-1" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "sql", weight: 1.0} + - {keyword: "eloquent", weight: 1.0} + - {keyword: "docs laravel", weight: 1.0} + - {keyword: "roster auto-detect", weight: 1.0} + boundaries: + - {pair: "#1", relation: "replaces"} + chain_membership: [] + attributes: + tooling_section: "§3.5 #10" + install: "composer require laravel/boost --dev" + + - id: "#11" + name: "Laravel Pint" + slug: "pint" + category: "phase-1" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "php code style", weight: 1.0} + - {keyword: "форматтер", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§3.5 #11" + install: "composer pint" + + - id: "#12" + name: "Larastan" + slug: "larastan" + category: "phase-1" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "статанализ php", weight: 1.0} + - {keyword: "типы", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§3.5 #12" + install: "composer stan" + + - id: "#13" + name: "Roave/SecurityAdvisories" + slug: "roave-security" + category: "phase-1" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "cve на install", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§3.5 #13" + install: "composer install (автоматически)" + + - id: "#14" + name: "Laravel IDE Helper" + slug: "ide-helper" + category: "phase-1" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "ide-stubs php", weight: 1.0} + - {keyword: "@mixin", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§3.5 #14" + install: "php artisan ide-helper:generate" + + - id: "#15" + name: "squawk" + slug: "squawk" + category: "phase-1" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "лит миграций postgresql", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§3.5 #15" + + - id: "#16" + name: "pgFormatter" + slug: "pg-formatter" + category: "phase-1" + subcategory: null + status: "active" + dormancy_reason: null + triggers: + - {keyword: "форматирование sql", weight: 1.0} + boundaries: [] + chain_membership: [] + attributes: + tooling_section: "§3.5 #16" + + - id: "#17" + name: "pg_partman" + slug: "pg-partman" + category: "phase-1" + subcategory: null + status: "dormant" + dormancy_reason: "native Windows PG не поддерживает расширение; заменён ручным cron'ом partitions:create-months" + triggers: + - {keyword: "партиционирование pg", weight: 1.0} + boundaries: + - {relation: "replaced by Artisan partitions:create-months (CLAUDE.md §6)"} + chain_membership: [] + attributes: + tooling_section: "§3.5 #17" + - id: "#19" name: "Superpowers v5.1.0" slug: "superpowers" diff --git a/tools/registry-load.test.mjs b/tools/registry-load.test.mjs index 381b2e19..b6437312 100644 --- a/tools/registry-load.test.mjs +++ b/tools/registry-load.test.mjs @@ -5,9 +5,9 @@ import { loadRegistry, clearCache, findByClassification, findByKeyword, findActi describe('registry-load', () => { beforeEach(() => clearCache()); - it('loads pilot registry with 3 nodes', () => { + it('loads registry (19 nodes after task 8a)', () => { const r = loadRegistry(); - expect(r.nodes).toHaveLength(3); + expect(r.nodes).toHaveLength(19); expect(r.version).toBe('0.1.0'); }); @@ -46,7 +46,12 @@ describe('registry-load', () => { it('findActiveNodes excludes non-active', () => { const r = loadRegistry(); const active = findActiveNodes(r); - expect(active.map(n => n.id).sort()).toEqual(['#18', '#19']); + // After task 8a: 19 nodes total; #1 historic, #17 dormant → 17 active + expect(active).toHaveLength(17); + expect(active.map(n => n.id)).toContain('#18'); + expect(active.map(n => n.id)).toContain('#19'); + expect(active.map(n => n.id)).not.toContain('#1'); + expect(active.map(n => n.id)).not.toContain('#17'); }); it('findChainsByNode returns chain membership', () => {