Files
portal/docs/automation-graph.html
T

1077 lines
69 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Система автоматизации Лидерры</title>
<script src="https://unpkg.com/vis-network@9.1.9/standalone/umd/vis-network.min.js"></script>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { background: #0d0d1a; color: #fdf6e3; font-family: 'Segoe UI', system-ui, sans-serif; height: 100vh; display: flex; flex-direction: column; overflow: hidden; }
/* ── Toolbar ── */
#toolbar { background: #073642; border-bottom: 1px solid #586e75; padding: 8px 12px; display: flex; align-items: center; gap: 10px; flex-shrink: 0; }
#toolbar h1 { font-size: 14px; color: #93a1a1; white-space: nowrap; margin-right: 6px; }
#search { background: #002b36; border: 1px solid #586e75; color: #fdf6e3; border-radius: 5px; padding: 5px 10px; font-size: 13px; width: 220px; outline: none; }
#search:focus { border-color: #268bd2; }
#search::placeholder { color: #586e75; }
.btn { background: #073642; border: 1px solid #586e75; color: #93a1a1; border-radius: 5px; padding: 5px 12px; font-size: 12px; cursor: pointer; transition: all 0.15s; }
.btn:hover { background: #0d4a5a; color: #fdf6e3; border-color: #839496; }
#btn-clear { margin-left: auto; }
/* ── Main area ── */
#main { flex: 1; display: flex; overflow: hidden; }
/* ── Graph canvas ── */
#network { flex: 1; background: #1e1e2e; }
#network canvas { background: #1e1e2e; }
/* ── Legend panel ── */
#legend-panel { width: 300px; min-width: 300px; background: #002b36; border-left: 1px solid #586e75; overflow-y: auto; padding: 16px; display: none; flex-direction: column; gap: 14px; }
#legend-panel.visible { display: flex; }
#legend-close { align-self: flex-end; background: none; border: none; color: #586e75; font-size: 18px; cursor: pointer; line-height: 1; padding: 0; }
#legend-close:hover { color: #fdf6e3; }
#legend-title { font-size: 15px; font-weight: 600; color: #fdf6e3; overflow-wrap: break-word; }
#legend-category { font-size: 11px; text-transform: uppercase; letter-spacing: 0.08em; }
.legend-section { background: #073642; border-radius: 6px; padding: 10px 12px; }
.legend-section h4 { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: #839496; margin-bottom: 6px; }
.legend-section p { font-size: 13px; color: #eee8d5; line-height: 1.5; }
.legend-section ul { list-style: none; display: flex; flex-direction: column; gap: 4px; }
.legend-section li { font-size: 12px; color: #eee8d5; line-height: 1.4; }
.legend-section li span.cond { color: #839496; font-style: italic; }
.conflict-item { background: #2d0000; border-radius: 4px; padding: 6px 8px; }
.conflict-item .cname { color: #ff5f57; font-weight: 600; font-size: 12px; }
.conflict-item .cdesc { color: #cb9b96; font-size: 11px; margin-top: 2px; line-height: 1.4; }
#legend-no-conflicts { font-size: 12px; color: #586e75; }
/* ── Category legend footer ── */
#cat-legend { background: #073642; border-top: 1px solid #586e75; padding: 7px 14px; display: flex; flex-wrap: wrap; gap: 12px; flex-shrink: 0; }
.cat-item { display: flex; align-items: center; gap: 5px; font-size: 11px; color: #839496; }
.cat-dot { width: 10px; height: 10px; border-radius: 50%; flex-shrink: 0; }
</style>
</head>
<body>
<div id="toolbar">
<h1>🗺 Лидерра — карта автоматизации</h1>
<input id="search" type="text" placeholder="Поиск узла…" autocomplete="off">
<button class="btn" id="btn-freeze">❄ Зафиксировать</button>
<button class="btn" id="btn-unfreeze">▶ Расшевелить</button>
<button class="btn" id="btn-reset">⊙ Сбросить вид</button>
<button class="btn" id="btn-clear">✕ Снять выделение</button>
</div>
<div id="main">
<div id="network"></div>
<div id="legend-panel">
<button id="legend-close">×</button>
<div id="legend-title"></div>
<div id="legend-category"></div>
<div class="legend-section"><h4>Что делает</h4><p id="ld-desc"></p></div>
<div class="legend-section"><h4>Когда используется</h4><p id="ld-when"></p></div>
<div class="legend-section"><h4>Ограничения</h4><p id="ld-limits"></p></div>
<div class="legend-section"><h4>Кому подчиняется</h4><ul id="ld-reports"></ul></div>
<div class="legend-section"><h4>Кто подчиняется ему</h4><ul id="ld-manages"></ul></div>
<div class="legend-section"><h4>С кем работает одновременно</h4><ul id="ld-together"></ul></div>
<div class="legend-section" id="conflicts-section">
<h4>⚡ Конфликты</h4>
<div id="ld-conflicts"></div>
</div>
</div>
</div>
<div id="cat-legend">
<div class="cat-item"><div class="cat-dot" style="background:#268bd2"></div>Правила</div>
<div class="cat-item"><div class="cat-dot" style="background:#859900"></div>Плагины</div>
<div class="cat-item"><div class="cat-dot" style="background:#6c71c4"></div>Скилы Superpowers</div>
<div class="cat-item"><div class="cat-dot" style="background:#d33682"></div>Скилы проекта</div>
<div class="cat-item"><div class="cat-dot" style="background:#2aa198"></div>Хуки</div>
<div class="cat-item"><div class="cat-dot" style="background:#b58900"></div>Агенты</div>
<div class="cat-item"><div class="cat-dot" style="background:#cb4b16"></div>MCP-серверы</div>
<div class="cat-item"><div class="cat-dot" style="background:#dc322f"></div>Lefthook jobs</div>
<div class="cat-item"><div class="cat-dot" style="background:#586e75"></div>Memory files</div>
<div class="cat-item"><div class="cat-dot" style="background:#ff5f57; border: 1px dashed #ff5f57;"></div>— конфликт</div>
</div>
<script>
// ════════════════════════════════════════════════════
// SECTION 1: NODES
// ════════════════════════════════════════════════════
const NODES = [
// ── ПРАВИЛА (4) ──────────────────────────────────
{ id: 'pravila', label: 'Pravila v1.13', group: 'rules', size: 38 },
{ id: 'claude_md', label: 'CLAUDE.md v1.92', group: 'rules', size: 34 },
{ id: 'psr_v1', label: 'PSR_v1 v2.1', group: 'rules', size: 32 },
{ id: 'tooling', label: 'Tooling v1.17', group: 'rules', size: 30 },
// ── ПЛАГИНЫ (5) ──────────────────────────────────
{ id: 'superpowers', label: 'Superpowers v5.1', group: 'plugins', size: 30 },
{ id: 'fd_plugin', label: 'Frontend Design', group: 'plugins', size: 26 },
{ id: 'upm', label: 'UI UX Pro Max', group: 'plugins', size: 22 },
{ id: 'claude_md_mgmt', label: 'claude-md-mgmt', group: 'plugins', size: 22 },
{ id: 'hookify_plugin', label: 'hookify (плагин)', group: 'plugins', size: 22 },
// ── СКИЛЫ SUPERPOWERS (14) ────────────────────────
{ id: 'sk_brainstorm', label: 'brainstorming', group: 'skills_sp', size: 18 },
{ id: 'sk_tdd', label: 'TDD', group: 'skills_sp', size: 18 },
{ id: 'sk_debug', label: 'systematic-debugging', group: 'skills_sp', size: 18 },
{ id: 'sk_wplans', label: 'writing-plans', group: 'skills_sp', size: 20 },
{ id: 'sk_eplans', label: 'executing-plans', group: 'skills_sp', size: 18 },
{ id: 'sk_verify', label: 'verification-before-completion', group: 'skills_sp', size: 18 },
{ id: 'sk_parallel', label: 'parallel-work', group: 'skills_sp', size: 18 },
{ id: 'sk_worktree', label: 'worktree', group: 'skills_sp', size: 18 },
{ id: 'sk_pr', label: 'finishing-pr', group: 'skills_sp', size: 18 },
{ id: 'sk_subagent', label: 'subagent-driven', group: 'skills_sp', size: 20 },
{ id: 'sk_wskills', label: 'writing-skills', group: 'skills_sp', size: 16 },
{ id: 'sk_spreview', label: 'spec-review', group: 'skills_sp', size: 16 },
{ id: 'sk_coderev', label: 'code-review', group: 'skills_sp', size: 16 },
{ id: 'sk_elements', label: 'elements-of-style', group: 'skills_sp', size: 16 },
// ── СКИЛЫ ПРОЕКТА (2) ────────────────────────────
{ id: 'sk_rls', label: 'rls-check', group: 'skills_proj', size: 20 },
{ id: 'sk_qitem', label: 'q-item-add', group: 'skills_proj', size: 20 },
// ── ХУКИ .claude (5) ────────────────────────────
{ id: 'hk_pre_claude', label: 'PreToolUse:\nCLAUDE.md-warn', group: 'hooks', size: 22 },
{ id: 'hk_post_md', label: 'PostToolUse:\nmarkdownlint', group: 'hooks', size: 20 },
{ id: 'hk_post_schema', label: 'PostToolUse:\nschema-changelog',group: 'hooks', size: 20 },
{ id: 'hk_session', label: 'SessionStart:\ncontext-inject', group: 'hooks', size: 24 },
{ id: 'hk_economy', label: 'UserPromptSubmit:\neconomy-mode', group: 'hooks', size: 22 },
// ── АГЕНТЫ (11) ──────────────────────────────────
{ id: 'ag_pest', label: 'pest-parallel-debugger', group: 'agents', size: 24 },
{ id: 'ag_rls', label: 'rls-reviewer', group: 'agents', size: 22 },
{ id: 'ag_statusline', label: 'statusline-setup', group: 'agents', size: 18 },
{ id: 'ag_guide', label: 'claude-code-guide', group: 'agents', size: 18 },
{ id: 'ag_explore', label: 'Explore', group: 'agents', size: 20 },
{ id: 'ag_general', label: 'general-purpose', group: 'agents', size: 20 },
{ id: 'ag_plan', label: 'Plan', group: 'agents', size: 20 },
{ id: 'ag_hookify', label: 'hookify:\nconversation-analyzer', group: 'agents', size: 18 },
{ id: 'ag_pcreator', label: 'plugin-dev:\nagent-creator', group: 'agents', size: 16 },
{ id: 'ag_pvalid', label: 'plugin-dev:\nplugin-validator',group: 'agents', size: 16 },
{ id: 'ag_skreview', label: 'plugin-dev:\nskill-reviewer', group: 'agents', size: 16 },
// ── MCP-СЕРВЕРЫ (7) ──────────────────────────────
{ id: 'mcp_pw', label: 'MCP: playwright', group: 'mcp', size: 22 },
{ id: 'mcp_gh', label: 'MCP: github', group: 'mcp', size: 22 },
{ id: 'mcp_boost', label: 'MCP: laravel-boost', group: 'mcp', size: 24 },
{ id: 'mcp_semgrep', label: 'MCP: semgrep', group: 'mcp', size: 20 },
{ id: 'mcp_sentry', label: 'MCP: sentry', group: 'mcp', size: 22 },
{ id: 'mcp_redis', label: 'MCP: redis', group: 'mcp', size: 22 },
{ id: 'mcp_21st', label: 'MCP: 21st.dev Magic', group: 'mcp', size: 20 },
// ── LEFTHOOK JOBS (10) ───────────────────────────
{ id: 'lh_gitleaks', label: 'lefthook:\ngitleaks', group: 'lefthook', size: 18 },
{ id: 'lh_mdlint', label: 'lefthook:\nmarkdownlint', group: 'lefthook', size: 18 },
{ id: 'lh_cspell', label: 'lefthook:\ncspell', group: 'lefthook', size: 18 },
{ id: 'lh_stylelint', label: 'lefthook:\nstylelint', group: 'lefthook', size: 16 },
{ id: 'lh_pint', label: 'lefthook:\npint', group: 'lefthook', size: 18 },
{ id: 'lh_larastan', label: 'lefthook:\nlarastan', group: 'lefthook', size: 18 },
{ id: 'lh_squawk', label: 'lefthook:\nsquawk', group: 'lefthook', size: 18 },
{ id: 'lh_eslint', label: 'lefthook:\neslint-vue', group: 'lefthook', size: 18 },
{ id: 'lh_gitleaks2', label: 'lefthook:\ngitleaks pre-push', group: 'lefthook', size: 18 },
{ id: 'lh_lychee', label: 'lefthook:\nlychee-links', group: 'lefthook', size: 18 },
// ── MEMORY FILES (15) ────────────────────────────
{ id: 'mem_user', label: 'memory:\nuser_profile', group: 'memory', size: 16 },
{ id: 'mem_comm', label: 'memory:\nfeedback_comm', group: 'memory', size: 14 },
{ id: 'mem_env', label: 'memory:\nfeedback_env', group: 'memory', size: 16 },
{ id: 'mem_sp', label: 'memory:\nfeedback_superpowers',group: 'memory', size: 16 },
{ id: 'mem_plugins', label: 'memory:\nfeedback_plugins', group: 'memory', size: 16 },
{ id: 'mem_state', label: 'memory:\nproject_state', group: 'memory', size: 16 },
{ id: 'mem_phase1', label: 'memory:\nphase1_strategy', group: 'memory', size: 14 },
{ id: 'mem_archive', label: 'memory:\nreference_archive', group: 'memory', size: 14 },
{ id: 'mem_github', label: 'memory:\nreference_github', group: 'memory', size: 14 },
{ id: 'mem_handoff', label: 'memory:\nreference_handoff', group: 'memory', size: 14 },
{ id: 'mem_audit', label: 'memory:\naudit_2026-05-13', group: 'memory', size: 14 },
{ id: 'mem_supplier', label: 'memory:\nsupplier_integration',group: 'memory', size: 14 },
{ id: 'mem_brain', label: 'memory:\nclaude_brain', group: 'memory', size: 14 },
{ id: 'mem_redesign', label: 'memory:\nportal_redesign', group: 'memory', size: 14 },
{ id: 'mem_devindices', label: 'memory:\ndev_indices', group: 'memory', size: 12 },
];
// ════════════════════════════════════════════════════
// SECTION 2: EDGES
// ════════════════════════════════════════════════════
const E = (from, to, label) => ({
from, to,
title: label,
color: { color: '#586e75', highlight: '#93a1a1', hover: '#93a1a1' },
arrows: { to: { enabled: true, scaleFactor: 0.6 } },
smooth: { type: 'continuous', roundness: 0.5 }
});
const CONFLICT = (from, to, label) => ({
from, to,
title: label,
label: '⚡',
dashes: true,
width: 2,
color: { color: '#ff5f57', highlight: '#ff8880', hover: '#ff8880' },
arrows: { to: { enabled: true, scaleFactor: 0.7 }, from: { enabled: true, scaleFactor: 0.7 } },
font: { color: '#ff5f57', size: 14, align: 'middle', strokeWidth: 3, strokeColor: '#1e1e2e' },
smooth: { type: 'curvedCW', roundness: 0.35 }
});
const EDGES = [
// ── ПРАВИЛА — иерархия ──────────────────────────
E('pravila', 'claude_md', 'подчиняет\n(уровень 1→2a)'),
E('pravila', 'psr_v1', 'подчиняет\n(уровень 1→3)'),
E('claude_md', 'tooling', 'ссылается\nна реестр'),
E('pravila', 'superpowers', '§12: обязывает\nинвокировать 1-м'),
// ── PSR_v1 координирует плагины ─────────────────
E('psr_v1', 'superpowers', 'R5: координирует\nпарный стек'),
E('psr_v1', 'fd_plugin', 'R5: координирует\nпарный стек'),
E('psr_v1', 'upm', 'R14.3: активирует\nтолько через pipeline'),
E('psr_v1', 'mcp_21st', 'R14.4: активирует\nтолько через pipeline'),
E('psr_v1', 'claude_md_mgmt','R10.1 блок 1:\nинфраструктурный'),
// ── CLAUDE.md ────────────────────────────────────
E('claude_md', 'mcp_boost', 'описывает §3.2'),
E('claude_md', 'mcp_sentry', 'описывает §4.8'),
E('claude_md', 'mcp_redis', 'описывает §4.9'),
E('claude_md', 'claude_md_mgmt', '§5п.10:\nединственный канал'),
E('claude_md', 'ag_pest', 'описывает\nкогда вызывать'),
E('claude_md', 'ag_rls', 'описывает\nкогда вызывать'),
// ── ХУКИ ────────────────────────────────────────
E('hk_pre_claude', 'claude_md', 'проверяет\nпри Edit/Write'),
E('hk_post_md', 'lh_mdlint', 'дублирует задачу\n(локально)'),
E('hk_post_schema', 'claude_md', 'напоминает про\nCHANGELOG_schema'),
E('hk_session', 'mem_user', 'читает\nпри старте'),
E('hk_session', 'mem_env', 'читает\nпри старте'),
E('hk_session', 'mem_sp', 'читает\nпри старте'),
E('hk_session', 'mem_plugins', 'читает\nпри старте'),
E('hk_session', 'mem_state', 'читает\nпри старте'),
E('hk_economy', 'superpowers', 'парсит уровень\nэкономии'),
// ── SUPERPOWERS содержит скилы ──────────────────
E('superpowers', 'sk_brainstorm', 'содержит'),
E('superpowers', 'sk_tdd', 'содержит'),
E('superpowers', 'sk_debug', 'содержит'),
E('superpowers', 'sk_wplans', 'содержит'),
E('superpowers', 'sk_eplans', 'содержит'),
E('superpowers', 'sk_verify', 'содержит'),
E('superpowers', 'sk_parallel', 'содержит'),
E('superpowers', 'sk_worktree', 'содержит'),
E('superpowers', 'sk_pr', 'содержит'),
E('superpowers', 'sk_subagent', 'содержит'),
E('superpowers', 'sk_wskills', 'содержит'),
E('superpowers', 'sk_spreview', 'содержит'),
E('superpowers', 'sk_coderev', 'содержит'),
E('superpowers', 'sk_elements', 'содержит'),
// ── СКИЛЫ вызывают друг друга ───────────────────
E('sk_brainstorm', 'sk_wplans', 'вызывает\nпосле дизайна'),
E('sk_wplans', 'sk_eplans', 'вызывает\nдля выполнения'),
E('sk_wplans', 'sk_subagent','альтернатива\nexecuting-plans'),
E('sk_subagent', 'ag_explore', 'запускает\nдля поиска'),
E('sk_subagent', 'ag_general', 'запускает\nдля задач'),
E('sk_subagent', 'ag_plan', 'запускает\nдля архитектуры'),
E('sk_parallel', 'sk_worktree','использует\nдля изоляции'),
// ── СКИЛЫ ПРОЕКТА ───────────────────────────────
E('sk_rls', 'tooling', 'использует\nsquawk + grep §3.2'),
E('sk_rls', 'mcp_boost', 'SQL запросы\nк схеме'),
E('sk_qitem', 'claude_md_mgmt','делегирует\nправку CLAUDE.md'),
// ── CLAUDE-MD-MGMT ──────────────────────────────
E('claude_md_mgmt', 'claude_md', 'единственный\nканал правок'),
// ── HOOKIFY ─────────────────────────────────────
E('ag_hookify', 'hookify_plugin', 'передаёт\nанализ'),
E('hookify_plugin', 'hk_pre_claude', 'может создавать\nновые хуки'),
E('hookify_plugin', 'hk_economy', 'может создавать\nновые хуки'),
// ── АГЕНТЫ используют MCP ───────────────────────
E('ag_pest', 'mcp_redis', 'читает\nочереди/кэш'),
E('ag_rls', 'mcp_boost', 'SQL запросы\nк БД'),
E('ag_guide', 'mcp_gh', 'ищет\nв репозитории'),
// ── LEFTHOOK вызывается git ──────────────────────
E('lh_gitleaks', 'mem_plugins', 'блокирует коммит\nпри ПДн в staged'),
E('lh_larastan', 'mcp_boost', 'Boost даёт\nконтекст типов'),
E('lh_squawk', 'tooling', 'соответствует\n§3.2 #15'),
E('lh_gitleaks2', 'lh_gitleaks', 'строже:\nвся история'),
E('lh_lychee', 'claude_md', 'проверяет\nссылки в .md'),
// ── MEMORY читается Claude ──────────────────────
E('mem_env', 'ag_pest', 'квирки 72/77\nиспользует агент'),
E('mem_plugins', 'psr_v1', 'отражает\nтекущие версии'),
E('mem_archive', 'claude_md', 'синхронизирует\nверсии доков'),
// ── MCP ─────────────────────────────────────────
E('mcp_pw', 'hk_session', 'используется\nдля a11y smoke'),
E('mcp_gh', 'sk_pr', 'PR, issues\nпри finishing-pr'),
E('mcp_boost', 'ag_rls', 'схема БД\nдля RLS-review'),
// ══════════════════════════════════════════════════
// КОНФЛИКТЫ (красные пунктирные рёбра)
// ══════════════════════════════════════════════════
CONFLICT('psr_v1', 'claude_md', '⚡ T2.2'),
CONFLICT('upm', 'fd_plugin', '⚡ R14.5'),
CONFLICT('mcp_21st', 'fd_plugin', '⚡ R14.5'),
CONFLICT('sk_rls', 'ag_rls', '⚡ перекрытие RLS'),
CONFLICT('hookify_plugin','hk_pre_claude', '⚡ может затенить'),
CONFLICT('hk_economy', 'superpowers', '⚡ §12 vs Economy'),
];
// ════════════════════════════════════════════════════
// SECTION 3: NODE DETAILS
// ════════════════════════════════════════════════════
const CATEGORY_LABELS = {
rules: 'Правило', plugins: 'Плагин', skills_sp: 'Скил Superpowers',
skills_proj: 'Скил проекта', hooks: 'Хук .claude', agents: 'Агент',
mcp: 'MCP-сервер', lefthook: 'Lefthook job', memory: 'Memory-файл'
};
function nd(desc, when, limits, reportsTo, manages, together, conflicts) {
// Backward-compat: old 5-arg signature was nd(desc, reportsTo, manages, together, conflicts).
// If 2nd arg is an array, treat as old-style call and shift args.
if (Array.isArray(when)) {
return {
desc,
when: '',
limits: '',
reportsTo: when,
manages: limits,
together: reportsTo,
conflicts: (manages || []),
};
}
return { desc, when: when || '', limits: limits || '', reportsTo, manages, together, conflicts: conflicts || [] };
}
const NODE_DETAILS = {
// ── ПРАВИЛА ──────────────────────────────────────
pravila: nd(
'Главный свод правил работы Клода — приоритеты, запреты и обязательные скилы.',
'Действует постоянно — fundamental слой автоматизации; читается при старте каждой сессии через SessionStart хук.',
'§12 hard rule неотменяем; §9 «Отступления» не применяется к §12. Расходимость с CLAUDE.md/PSR_v1/Tooling — нарушение §7.',
[],
[
{ name: 'CLAUDE.md', cond: 'подчинён уровень 2a' },
{ name: 'PSR_v1', cond: 'подчинён уровень 3' },
{ name: 'Superpowers', cond: '§12 — обязывает инвокировать первым' },
{ name: 'Все компоненты', cond: 'через цепочку приоритетов §1' }
],
[{ name: 'CLAUDE.md', cond: 'оба читаются при старте сессии' }]
),
claude_md: nd(
'Оперативная карта проекта — список технологий, команд, фаз, ссылок на документы.',
'Читается при старте каждой сессии (SessionStart хук); upd при добавлении новых tooling/фазы.',
'Правки **только** через `/claude-md-management:claude-md-improver` или `:revise-claude-md` (§5 п.10). Прямые Edit/Write запрещены — блокируются PreToolUse:CLAUDE.md-warn хуком.',
[{ name: 'Pravila', cond: 'всегда (уровень 2a)' }],
[
{ name: 'Tooling v1.17', cond: 'ссылается как на реестр инструментов' },
{ name: 'claude-md-mgmt', cond: '§5п.10 — единственный канал правок' }
],
[
{ name: 'Pravila', cond: 'оба читаются SessionStart хуком' },
{ name: 'Tooling', cond: 'оба operational maps уровня 2' }
],
[{ name: 'PSR_v1', desc: 'T2.2: §5п.10 запрещает прямые правки, но PSR_v1 не дублирует это явно — риск Edit без skill\'а' }]
),
psr_v1: nd(
'Правила совместного использования плагинов — кто с кем работает, какой pipeline обязателен.',
'При выборе UI-инструмента (FD vs UPM vs 21st), при координации парного стека, при активации off-phase MCP.',
'R14.5: UPM, 21st, FD — не одновременно. R6.0 фильтр стека и R6.1 hard-override Forest обязательны для UI-вывода плагинов.',
[{ name: 'Pravila', cond: 'уровень 3 в цепочке' }],
[
{ name: 'Superpowers + Frontend Design', cond: 'координирует как парный стек' },
{ name: 'UI UX Pro Max', cond: 'R14.3: активирует только через pipeline' },
{ name: '21st Magic MCP', cond: 'R14.4: активирует только через pipeline' }
],
[{ name: 'CLAUDE.md', cond: 'оба operational maps — согласуются при правках' }],
[{ name: 'CLAUDE.md', desc: 'T2.2: CLAUDE.md §5п.10 требует claude-md-mgmt, PSR_v1 не дублирует это ограничение — риск прямых Edit' }]
),
tooling: nd(
'Реестр 35 инструментов — когда что использовать, команды установки, конфликты.',
'При выборе инструмента для фазы (0/1/2/3), при добавлении нового tooling, при актуализации после обновления версий.',
'При прямом конфликте с CLAUDE.md приоритетнее CLAUDE.md (operational map уровня 2a). Изменения требуют sync с CLAUDE.md §3.',
[
{ name: 'Pravila', cond: 'уровень 2b (operational map рядом с CLAUDE.md)' },
{ name: 'CLAUDE.md', cond: 'при прямом конфликте CLAUDE.md приоритетнее' }
],
[],
[{ name: 'CLAUDE.md', cond: 'оба operational maps — правятся синхронно' }]
),
// ── ПЛАГИНЫ ──────────────────────────────────────
superpowers: nd(
'Плагин поведения Клода — 14 скилов для TDD, дебага, планирования, параллельной работы.',
'При creative / multi-step / debug / verify / TDD / brainstorm / parallel / worktree / finishing-PR / subagent / writing-skills задачах (карта §12.2 Pravila).',
'§12 hard rule — единственный override: явная просьба заказчика «не используй superpowers сейчас» на текущее действие. Pravila §9 «Отступления» к §12 не применяется.',
[
{ name: 'Pravila §12', cond: 'hard rule: инвокируется первым' },
{ name: 'PSR_v1', cond: 'координирует как парный стек с Frontend Design' }
],
[{ name: 'Все 14 Superpowers-скилов', cond: 'содержит' }],
[{ name: 'Frontend Design', cond: 'парный стек — работают вместе при UI-задачах' }],
[{ name: 'economy-mode хук', desc: 'Economy=100% теоретически может «сэкономить» инвокацию skill\'а, нарушая §12 hard rule (§12 неотменяем)' }]
),
fd_plugin: nd(
'Плагин знаний о UI — Vue, Vuetify, a11y, паттерны компонентов для Лидерры.',
'При UI/UX задачах — компоненты, экраны, паттерны взаимодействия; в паре с Superpowers (процесс).',
'R6.0 фильтр стека: срезать React/Tailwind/shadcn/JSX → Vue 3 + Vuetify 3. R6.1 hard-override Forest для палитры/шрифтов/иконок.',
[{ name: 'PSR_v1', cond: 'R5: подчинён как часть парного стека' }],
[],
[{ name: 'Superpowers', cond: 'парный стек — FD даёт UI-знания, Superpowers даёт процесс' }],
[
{ name: 'UI UX Pro Max', desc: 'PSR_v1 R14.5: нельзя параллельно — оба активны в settings.json, но должны чередоваться' },
{ name: '21st Magic MCP', desc: 'PSR_v1 R14.5: нельзя параллельно с FD — оба потенциально доступны одновременно' }
]
),
upm: nd(
'Резервная библиотека UI — 50+ стилей, 161 палитра, 99 UX-гайдлайнов. Только по pipeline.',
'PSR_v1 R14.3 pipeline: фаза 2 R2 fallback к FD ИЛИ фаза 1 R2 «третий вариант» в R12 архитектурном.',
'R14.5: не параллельно с FD/21st. R6.0 фильтр стека + R6.1 hard-override Forest обязательны. Pa11y a11y на deployable.',
[{ name: 'PSR_v1', cond: 'R14.3: активируется только через pipeline, не самостоятельно' }],
[],
[],
[{ name: 'Frontend Design', desc: 'PSR_v1 R14.5: нельзя параллельно — UPM как материал, FD как решатель; риск смешивания ролей' }]
),
claude_md_mgmt: nd(
'Единственный разрешённый способ редактировать CLAUDE.md — через skill claude-md-improver или revise-claude-md.',
'При любой правке CLAUDE.md (новая фаза, новый tooling, изменение версии, новые quirks — все через skill).',
'PSR_v1 R10.1 блок 1 (infrastructure). Внутри flow продолжают действовать §4 правил Claude (синхронизация Pravila + Tooling).',
[{ name: 'PSR_v1', cond: 'R10.1 Блок 1: инфраструктурная категория' }],
[{ name: 'CLAUDE.md', cond: '§5п.10: монопольный канал правок' }],
[{ name: 'q-item-add скил', cond: 'скил делегирует CLAUDE.md правки через этот плагин' }]
),
hookify_plugin: nd(
'Плагин создания хуков — анализирует разговоры и предлагает новые автоматизации через хуки.',
'При запросе «давай повесим хук на это поведение» или после серии повторяющихся ошибок — анализ через conversation-analyzer агента.',
'PSR_v1 R10.1. Новые хуки могут конфликтовать с существующими (см. конфликты ниже) — обязательная проверка settings.json до создания.',
[{ name: 'PSR_v1', cond: 'R10.1: формализован' }],
[{ name: 'hookify:conversation-analyzer агент', cond: 'запускает анализ разговоров' }],
[{ name: 'hookify:conversation-analyzer', cond: 'плагин и агент работают в паре' }],
[
{ name: 'PreToolUse:CLAUDE.md-warn', desc: 'hookify создаёт новые PreToolUse хуки динамически — может перезаписать или конкурировать с этим хуком' },
{ name: 'economy-mode хук', desc: 'новые хуки от hookify могут вступить в конфликт с логикой economy-mode парсера' }
]
),
// ── СКИЛЫ SUPERPOWERS ────────────────────────────
sk_brainstorm: nd(
'Продумывает задачу вместе с заказчиком, формулирует варианты A/B/C и согласует дизайн до написания кода.',
'При creative задаче — новая фича, нетривиальный refactor, дизайн-решение; ПЕРЕД любым кодом или планом.',
'Обязательно «Approved» от заказчика до перехода к writing-plans. HARD-GATE: нельзя инвокировать implementation skill до утверждения дизайна.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен для creative задач' }],
[],
[{ name: 'writing-plans', cond: 'вызывается сразу после brainstorming для создания плана' }]
),
sk_tdd: nd(
'Ведёт разработку через написание провального теста до кода — failing test first, потом GREEN.',
'При любом новом production коде — backend (Pest) и frontend (Vitest).',
'Failing test ДО написания implementation; код «должен работать» без verified теста — нарушение §12.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен для любого нового кода' }],
[],
[{ name: 'executing-plans', cond: 'TDD встроен в каждый шаг плана выполнения' }]
),
sk_debug: nd(
'Системный дебаг: минимум 3 гипотезы, фальсификация каждой перед исправлением — никаких «должно работать».',
'При unexpected behavior, фейле теста, runtime ошибке, неожиданном выводе.',
'Минимум 3 гипотезы. Фальсификация через реальные команды/тесты, не «логика подсказывает». Никаких «попробую исправить» без проверки причины.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен при unexpected behavior' }],
[],
[{ name: 'MCP: redis', cond: 'используется для дебага Redis-очередей' }]
),
sk_wplans: nd(
'Создаёт детальный план реализации с полным кодом, командами и шагами по 2-5 минут.',
'После brainstorming (creative задача) или сразу для multi-step (≥3 шага) технической задачи.',
'Никаких placeholder\'ов (TBD, TODO, «add validation»). Каждый шаг — реальный код или команда. Spec coverage обязателен.',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен для multi-step задач (≥3 шага)' }],
[],
[{ name: 'executing-plans или subagent-driven', cond: 'план передаётся в один из них для выполнения' }]
),
sk_eplans: nd(
'Выполняет готовый план шаг за шагом, отмечает чекбоксы, делает коммиты после каждого шага.',
'После writing-plans (если выбран inline execution); альтернатива — subagent-driven для same-session.',
'Каждый шаг отмечается checkbox\'ом, не batch\'ит коммиты — атомарно (Pravila §4.2).',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'writing-plans', cond: 'получает план от writing-plans' }, { name: 'subagent-driven', cond: 'альтернатива — зависит от выбора пользователя' }]
),
sk_verify: nd(
'Обязательная проверка перед «готово» — запускает тесты, видит реальный вывод, никаких предположений.',
'Перед любым claim «готово»/«passed»/«closed»/«merged» — обязательно (§12 + economy 0% hard requirement).',
'Реальный запуск, не «должно пройти». Output виден полностью. Cherry-picking запрещён («tests pass» = ровно столько, сколько прошло).',
[{ name: 'Superpowers', cond: 'содержит' }, { name: 'Pravila §12', cond: 'обязателен перед любым claim «готово»' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'запросы к БД для проверки данных' }]
),
sk_parallel: nd(
'Разбивает независимые задачи на параллельные потоки с изоляцией через git worktrees.',
'При наличии нескольких независимых рабочих фронтов (CTO-task + Plan task + audit-fix) одновременно.',
'Изоляция через worktree обязательна — никакого «работаю в одной директории на 3 ветках сразу». Risk of contention.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'worktree скил', cond: 'parallel-work использует worktree для изоляции' }]
),
sk_worktree: nd(
'Создаёт изолированную копию репозитория для рискованной или параллельной работы.',
'При parallel-work или при рискованной работе (refactor с возможностью abort, ветка экспериментов).',
'Cleanup через ExitWorktree обязателен. Не оставлять untracked worktree\'ы — захламляют файловую систему.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'parallel-work', cond: 'worktree — инструмент для parallel-work' }]
),
sk_pr: nd(
'Чеклист финальной готовности PR — тесты, документация, чистота кода, pre-push хуки.',
'Перед `gh pr create` или `git push` на upstream — обязательная проверка готовности.',
'Pre-push хуки (gitleaks full-history + lychee) — не bypass\'ить через `--no-verify`. Pravila §4.2.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'MCP: github', cond: 'создаёт PR через GitHub MCP' }, { name: 'lefthook pre-push', cond: 'запускает gitleaks + lychee' }]
),
sk_subagent: nd(
'Запускает суб-агентов для крупных задач — каждый в отдельном контексте без накопленного шума.',
'При plan-driven execution в same-session ИЛИ при делегировании поиска/анализа большого scope.',
'Subagent в режиме экономии 0%: запрашивать raw output, не summary — решения принимать самому.',
[{ name: 'Superpowers', cond: 'содержит' }],
[
{ name: 'Explore агент', cond: 'запускает для поиска по кодовой базе' },
{ name: 'general-purpose агент', cond: 'запускает для сложных задач' },
{ name: 'Plan агент', cond: 'запускает для архитектурного планирования' }
],
[{ name: 'writing-plans', cond: 'subagent-driven — основной способ выполнения планов' }]
),
sk_wskills: nd(
'Создаёт новые скилы по стандартному шаблону с SKILL.md, frontmatter, workflow.',
'При формализации повторяющегося workflow в reusable skill (после 2-3 примеров одинаковой работы).',
'Шаблон SKILL.md, frontmatter (name, description, when_to_use, allowed-tools), workflow с DOT-диаграммой.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'plugin-dev:skill-reviewer', cond: 'агент проверяет созданный скил' }]
),
sk_spreview: nd(
'Проверяет spec-документ на полноту, противоречия, placeholder\'ы и scope.',
'После writing-plans на отдельном этапе ДО implementation — для крупных multi-task планов.',
'Inline self-review в режиме brainstorming достаточно для small spec; для крупных — выделенная инвокация.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'brainstorming', cond: 'spec-review вызывается в конце brainstorming после записи спека' }]
),
sk_coderev: nd(
'Систематический code review — безопасность, тесты, архитектура, соответствие правилам.',
'Перед merge PR; после крупной серии коммитов; при подготовке к релизу; при подозрении на регрессию.',
'Не cherry-pick: review всех diff\'ов, не только tarred. SAST (Semgrep) включается обязательно.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[{ name: 'MCP: semgrep', cond: 'SAST-проверка при code review' }]
),
sk_elements: nd(
'Улучшает написание текстов и документации — ясность, лаконичность, без воды.',
'При написании spec/plan/CHANGELOG/PR description — для коммуникации с командой.',
'Без воды. Без «легко», «просто», «всего лишь». Каждое утверждение — измеримое.',
[{ name: 'Superpowers', cond: 'содержит' }],
[],
[]
),
// ── СКИЛЫ ПРОЕКТА ────────────────────────────────
sk_rls: nd(
'7-шаговый чеклист RLS для новой таблицы: tenant_id, ENABLE RLS, политики, 5-role GRANTs, CHANGELOG, squawk, smoke test.',
'При создании новой таблицы в db/schema.sql ИЛИ при правках существующих RLS политик.',
'5-role GRANTs обязательны (crm_app_user / crm_app_admin / crm_supplier_worker BYPASSRLS / crm_readonly / crm_migrator). CHANGELOG_schema.md обязателен.',
[{ name: 'Tooling §3.2', cond: 'использует squawk (#15) и команды grep' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'SQL запросы к schema.sql для проверки' }],
[{ name: 'rls-reviewer агент', desc: 'оба проверяют RLS compliance — скил для ручной проверки таблицы, агент для PR/diff review; нет чёткой границы когда какой' }]
),
sk_qitem: nd(
'Добавляет новый открытый вопрос в реестр Открытые_вопросы_v8_3.md с обновлением счётчиков §0 и версии.',
'При появлении нового открытого вопроса (Биз-/CTO-/Ю-/Диз-/DO-/OPEN-) — формальный input в реестр.',
'Категоризация (Биз-/CTO-/...) обязательна. Связанные документы (CLAUDE.md/Pravila/PSR_v1/Tooling) — синхронизируются.',
[],
[],
[{ name: 'claude-md-mgmt', cond: 'скил делегирует правку CLAUDE.md через плагин (§5п.10)' }]
),
// ── ХУКИ ─────────────────────────────────────────
hk_pre_claude: nd(
'Блокирует прямое редактирование CLAUDE.md — срабатывает на Edit/Write по этому файлу.',
[{ name: '.claude/settings.json', cond: 'описан как PreToolUse hook' }],
[],
[],
[{ name: 'hookify (плагин)', desc: 'hookify динамически создаёт новые PreToolUse хуки — может перезаписать или конкурировать с этим хуком' }]
),
hk_post_md: nd(
'После каждого Edit .md файла запускает markdownlint --fix автоматически.',
[{ name: '.claude/settings.json', cond: 'описан как PostToolUse hook' }],
[],
[{ name: 'lefthook:markdownlint', cond: 'дублируют задачу: хук — в сессии, lefthook — при коммите' }]
),
hk_post_schema: nd(
'После правки db/schema.sql напоминает обновить db/CHANGELOG_schema.md.',
[{ name: '.claude/settings.json', cond: 'описан как PostToolUse hook' }],
[],
[{ name: 'lefthook:squawk', cond: 'оба реагируют на изменения SQL' }]
),
hk_session: nd(
'При старте каждой сессии инжектирует CLAUDE.md, Pravila и ключевые memory-файлы в контекст.',
[{ name: '.claude/settings.json', cond: 'описан как SessionStart hook' }],
[
{ name: 'memory:user_profile', cond: 'читает' },
{ name: 'memory:feedback_env', cond: 'читает' },
{ name: 'memory:project_state', cond: 'читает' },
{ name: 'memory:feedback_superpowers', cond: 'читает' },
{ name: 'memory:feedback_plugins', cond: 'читает' }
],
[]
),
hk_economy: nd(
'Перед каждым промптом парсит «экономия X%» и выставляет режим строгости (0%=полная качество, 100%=по умолчанию).',
[{ name: '.claude/settings.json', cond: 'описан как UserPromptSubmit hook' }],
[],
[],
[{ name: 'Superpowers (§12)', desc: 'Economy=100% теоретически может «сэкономить» инвокацию skill\'а, нарушая §12 hard rule — §12 неотменяем, экономия его не override\'ит' }]
),
// ── АГЕНТЫ ───────────────────────────────────────
ag_pest: nd(
'Диагностирует падения Pest --parallel: классифицирует как реальный баг или один из 5 квирков (72-73-77...).',
[{ name: 'CLAUDE.md §6', cond: 'описывает когда вызывать' }],
[],
[{ name: 'MCP: redis', cond: 'читает Redis для дебага quirk 72 (supplier:session race)' }]
),
ag_rls: nd(
'Проверяет RLS compliance в миграциях — 7-item чеклист с реальными запусками команд, READ-ONLY.',
[{ name: 'CLAUDE.md', cond: 'описывает в §6 и агенты/ директории' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'SQL запросы к db/schema.sql' }],
[{ name: 'rls-check скил', desc: 'оба покрывают RLS compliance, нет чёткой границы: агент — для PR/diff, скил — для ручной таблицы' }]
),
ag_statusline: nd(
'Настраивает строку состояния Claude Code через редактирование файла конфига.',
[],
[],
[]
),
ag_guide: nd(
'Отвечает на вопросы об API Claude Code, SDK, MCP серверах, хуках, slash commands.',
[],
[],
[{ name: 'MCP: github', cond: 'ищет примеры в репозитории при необходимости' }]
),
ag_explore: nd(
'Быстрый поиск файлов по паттерну или символу — только чтение, без анализа.',
[{ name: 'subagent-driven скил', cond: 'запускается для задач поиска' }],
[],
[]
),
ag_general: nd(
'Универсальный агент для сложных multi-step исследований с полным доступом к инструментам.',
[{ name: 'subagent-driven скил', cond: 'запускается для основных задач' }],
[],
[]
),
ag_plan: nd(
'Архитектор: разрабатывает планы реализации, выявляет критичные файлы, рассматривает trade-offs.',
[{ name: 'subagent-driven скил', cond: 'запускается для архитектурных задач' }],
[],
[{ name: 'writing-plans скил', cond: 'Plan агент и writing-plans решают похожую задачу для разных контекстов' }]
),
ag_hookify: nd(
'Анализирует транскрипты разговоров для поиска поведений, которые стоит предотвратить хуком.',
[],
[],
[{ name: 'hookify (плагин)', cond: 'агент передаёт рекомендации в плагин' }]
),
ag_pcreator: nd(
'Создаёт конфигурацию новых агентов по описанию пользователя.',
[],
[],
[{ name: 'plugin-dev:plugin-validator', cond: 'validator проверяет созданного агента' }]
),
ag_pvalid: nd(
'Проверяет структуру плагина на корректность — plugin.json, tools, manifest.',
[],
[],
[{ name: 'plugin-dev:agent-creator', cond: 'validator и creator работают в паре' }]
),
ag_skreview: nd(
'Оценивает качество написанного скила — описание, workflow, примеры, best practices.',
[],
[],
[{ name: 'writing-skills скил', cond: 'skill-reviewer проверяет то, что writing-skills создал' }]
),
// ── MCP-СЕРВЕРЫ ──────────────────────────────────
mcp_pw: nd(
'Управляет браузером — снимает скриншоты, кликает, заполняет формы для smoke и a11y тестов.',
[{ name: 'CLAUDE.md §3.1 #2', cond: 'активен с фазы 0' }],
[],
[{ name: 'SessionStart хук', cond: 'используется для визуальной проверки прототипов' }]
),
mcp_gh: nd(
'GitHub API — читает/создаёт PR, issues, коммиты, branches в репозитории CoralMinister/lidpotok.',
[{ name: 'CLAUDE.md §3.1 #3', cond: 'активен с фазы 0' }],
[],
[{ name: 'finishing-pr скил', cond: 'создаёт PR через этот MCP' }]
),
mcp_boost: nd(
'Laravel Boost — SQL запросы к dev-БД, схема таблиц, логи ошибок, поиск в docs Laravel.',
[{ name: 'CLAUDE.md §3.2 #10', cond: 'активен с фазы 1, READ-ONLY к prod запрещено' }],
[],
[{ name: 'ag_rls агент', cond: 'rls-reviewer использует Boost для SQL' }, { name: 'sk_rls скил', cond: 'rls-check использует Boost' }]
),
mcp_semgrep: nd(
'SAST анализ кода — ищет уязвимости, XSS, SQLi, нарушения правил по паттернам.',
[{ name: 'CLAUDE.md §3.4 #25', cond: 'фаза 3 pre-production' }],
[],
[{ name: 'code-review скил', cond: 'Semgrep MCP используется при code review' }]
),
mcp_sentry: nd(
'Читает ошибки из self-hosted Sentry в Yandex Cloud — события, стектрейсы, метрики. READ-ONLY.',
[{ name: 'CLAUDE.md §3.3 #34', cond: 'off-phase debug-runtime; pending Sentry deployment Б-1' }],
[],
[]
),
mcp_redis: nd(
'Читает Redis/Memurai — ключи, очереди, кэш для дебага race conditions. СТРОГО READ-ONLY.',
[{ name: 'CLAUDE.md §3.3 #35', cond: 'off-phase debug-runtime; PSR_v1 R10.1 блок 3' }],
[],
[{ name: 'pest-parallel-debugger агент', cond: 'агент использует для quirk 72 (Redis race)' }]
),
mcp_21st: nd(
'Генератор стартовых шаблонов UI-компонентов через LLM. Активация только через R14.4 pipeline.',
[{ name: 'PSR_v1 R14.4', cond: 'строгий pre-check: 9 условий перед активацией' }],
[],
[],
[{ name: 'Frontend Design', desc: 'PSR_v1 R14.5: нельзя параллельно — 21st как генератор материала, FD как решатель; риск смешивания ролей и нарушения R6 фильтра стека' }]
),
// ── LEFTHOOK JOBS ─────────────────────────────────
lh_gitleaks: nd(
'pre-commit: ищет ПДн, токены и API-ключи в staged-файлах. Блокирует коммит при находке.',
[{ name: 'lefthook.yml', cond: 'job #1 в pre-commit, parallel:false' }],
[],
[{ name: 'lefthook:gitleaks pre-push', cond: 'pre-push версия сканирует всю историю' }]
),
lh_mdlint: nd(
'pre-commit: проверяет и авто-исправляет стиль Markdown файлов перед коммитом.',
[{ name: 'lefthook.yml', cond: 'job #2 в pre-commit' }],
[],
[{ name: 'PostToolUse:markdownlint-fix хук', cond: 'оба делают одно — хук немедленно, lefthook при коммите' }]
),
lh_cspell: nd(
'pre-commit: проверяет орфографию в .md файлах по словарю cspell-words.txt.',
[{ name: 'lefthook.yml', cond: 'job #3 в pre-commit' }],
[],
[]
),
lh_stylelint: nd(
'pre-commit: линтует CSS в HTML-прототипах (web/v8/*.html).',
[{ name: 'lefthook.yml', cond: 'job #4 в pre-commit' }],
[],
[]
),
lh_pint: nd(
'pre-commit: авто-форматирует PHP код по PSR-стандарту, stage_fixed:true.',
[{ name: 'lefthook.yml', cond: 'job #5 в pre-commit, root:app/' }],
[],
[]
),
lh_larastan: nd(
'pre-commit: статический анализ PHP — находит ошибки типов выше baseline (Larastan L9).',
[{ name: 'lefthook.yml', cond: 'job #6 в pre-commit, root:app/' }],
[],
[{ name: 'MCP: laravel-boost', cond: 'Boost даёт контекст типов через IDE stubs' }]
),
lh_squawk: nd(
'pre-commit: линтует SQL миграции на безопасные паттерны (lock-safe, concurrent, etc.).',
[{ name: 'lefthook.yml', cond: 'job #7 в pre-commit, glob:*.sql' }],
[],
[{ name: 'Tooling #15 squawk', cond: 'соответствует §3.2 entry' }]
),
lh_eslint: nd(
'pre-commit: линтует Vue/TypeScript файлы в app/resources/js/.',
[{ name: 'lefthook.yml', cond: 'job #8 в pre-commit, root:app/' }],
[],
[]
),
lh_gitleaks2: nd(
'pre-push: полный скан всей истории коммитов на секреты (строже pre-commit job).',
[{ name: 'lefthook.yml', cond: 'job в pre-push' }],
[],
[{ name: 'lefthook:gitleaks', cond: 'pre-push версия строже pre-commit: проверяет всю историю' }]
),
lh_lychee: nd(
'pre-push: проверяет все ссылки в .md файлах на битые (docs/**/*.md, db/**/*.md, *.md).',
[{ name: 'lefthook.yml', cond: 'job в pre-push' }],
[],
[{ name: 'CLAUDE.md', cond: 'проверяет ссылки в CLAUDE.md в том числе' }]
),
// ── MEMORY FILES ─────────────────────────────────
mem_user: nd(
'Профиль заказчика: Дмитрий, Windows Server 2022, VSCode, русский язык, путь к проекту.',
[],
[],
[{ name: 'SessionStart хук', cond: 'читается при старте каждой сессии' }]
),
mem_comm: nd(
'Стиль общения: короткие команды («а», «б», «делай»), варианты A/B/C, фиксация переоткрытий.',
[],
[],
[{ name: 'memory:user_profile', cond: 'дополняет профиль пользователя' }]
),
mem_env: nd(
'80+ квирков окружения: специфика Windows Server, баги инструментов, митигации.',
[],
[],
[
{ name: 'pest-parallel-debugger агент', cond: 'квирки 72/77 используются агентом' },
{ name: 'SessionStart хук', cond: 'читается при старте' }
]
),
mem_sp: nd(
'Hard rule §12 + economy hook architecture из 6 компонентов — дисциплина инвокации скилов.',
[],
[],
[{ name: 'economy-mode хук', cond: 'связаны: memory описывает архитектуру хука' }]
),
mem_plugins: nd(
'Правила парного стека плагинов, debug-runtime MCP, tier-структура PSR_v1.',
[],
[],
[{ name: 'PSR_v1', cond: 'memory отражает актуальные версии PSR_v1' }]
),
mem_state: nd(
'Текущее состояние: ветка, тесты (Pest/Vitest), последние коммиты, активные задачи.',
[],
[],
[{ name: 'SessionStart хук', cond: 'читается при старте для быстрого контекста' }]
),
mem_phase1: nd(
'Стратегия фазы 1: native Windows стек без Docker, pg_partman заменён Artisan cron.',
[],
[],
[]
),
mem_archive: nd(
'Карта источников истины: версии всех 13+ ключевых документов проекта.',
[],
[],
[{ name: 'CLAUDE.md', cond: 'memory синхронизирует версии с CLAUDE.md §0' }]
),
mem_github: nd(
'GitHub репозиторий CoralMinister/lidpotok: HEAD, hooks, правила push.',
[],
[],
[{ name: 'MCP: github', cond: 'MCP и memory дополняют друг друга для работы с GitHub' }]
),
mem_handoff: nd(
'Дизайн-handoff Платона: что из liderra_v8_handoff/ используем, что нет.',
[],
[],
[]
),
mem_audit: nd(
'Полный аудит портала 13.05.2026: 38 находок, вердикт 🟡, 10 Q-items закрыты.',
[],
[],
[]
),
mem_supplier: nd(
'Прогресс интеграции поставщика Plans 1-5: Tasks, коммиты, блокеры.',
[],
[],
[]
),
mem_brain: nd(
'Claude Brain v1.0 — extracted brain repo, тег brain-v1.0, install.sh.',
[],
[],
[]
),
mem_redesign: nd(
'Редизайн Quiet Luxury: 20 коммитов, foundation CSS + composables + AppSidebar rewrite.',
[],
[],
[]
),
mem_devindices: nd(
'Dev Element Indices — временная feedback-фича для разработки; к удалению в продакшене.',
[],
[],
[]
),
};
// ════════════════════════════════════════════════════
// SECTION 4: VIS INIT
// ════════════════════════════════════════════════════
const GROUPS = {
rules: { color: { background: '#073642', border: '#268bd2', highlight: { border: '#93a1a1', background: '#0d4a5a' } }, font: { color: '#fdf6e3', size: 13, bold: true } },
plugins: { color: { background: '#001a00', border: '#859900', highlight: { border: '#b8cc00', background: '#002600' } }, font: { color: '#fdf6e3', size: 12 } },
skills_sp: { color: { background: '#1a0033', border: '#6c71c4', highlight: { border: '#9b9fea', background: '#250047' } }, font: { color: '#fdf6e3', size: 11 } },
skills_proj: { color: { background: '#2d0020', border: '#d33682', highlight: { border: '#e869a8', background: '#3d0028' } }, font: { color: '#fdf6e3', size: 12 } },
hooks: { color: { background: '#002233', border: '#2aa198', highlight: { border: '#4dd7ce', background: '#003344' } }, font: { color: '#fdf6e3', size: 11 } },
agents: { color: { background: '#1a1200', border: '#b58900', highlight: { border: '#e0ad00', background: '#261a00' } }, font: { color: '#fdf6e3', size: 11 } },
mcp: { color: { background: '#2d1200', border: '#cb4b16', highlight: { border: '#ff6b30', background: '#3d1900' } }, font: { color: '#fdf6e3', size: 11 } },
lefthook: { color: { background: '#2d0000', border: '#dc322f', highlight: { border: '#ff5f5c', background: '#3d0000' } }, font: { color: '#fdf6e3', size: 10 } },
memory: { color: { background: '#112233', border: '#586e75', highlight: { border: '#839496', background: '#1a2f40' } }, font: { color: '#eee8d5', size: 10 } },
};
const nodesDS = new vis.DataSet(NODES);
const edgesDS = new vis.DataSet(EDGES);
const network = new vis.Network(
document.getElementById('network'),
{ nodes: nodesDS, edges: edgesDS },
{
groups: GROUPS,
nodes: {
shape: 'dot',
borderWidth: 2,
borderWidthSelected: 3,
font: { multi: 'html' },
},
edges: {
smooth: { type: 'dynamic', roundness: 0.5 },
selectionWidth: 2,
},
physics: {
enabled: true,
solver: 'barnesHut',
barnesHut: {
gravitationalConstant: -7000,
centralGravity: 0.25,
springLength: 130,
springConstant: 0.04,
damping: 0.09,
avoidOverlap: 0.15,
},
stabilization: { enabled: true, iterations: 300, fit: true },
},
interaction: {
hover: true,
tooltipDelay: 400,
multiselect: false,
},
}
);
network.once('stabilizationIterationsDone', () => {
network.fit({ animation: { duration: 800, easingFunction: 'easeInOutQuad' } });
});
// ════════════════════════════════════════════════════
// SECTION 5: LEGEND PANEL
// ════════════════════════════════════════════════════
function renderLegendItem(item) {
return `<li>${item.name}${item.cond ? ` <span class="cond">— ${item.cond}</span>` : ''}</li>`;
}
function showLegend(nodeId) {
const node = NODES.find(n => n.id === nodeId);
const details = NODE_DETAILS[nodeId];
const panel = document.getElementById('legend-panel');
if (!node || !details) { panel.classList.remove('visible'); return; }
document.getElementById('legend-title').textContent = node.label.replace(/\n/g, ' ');
const catLabel = CATEGORY_LABELS[node.group] || node.group;
const catColor = GROUPS[node.group] && GROUPS[node.group].color ? GROUPS[node.group].color.border : '#839496';
document.getElementById('legend-category').innerHTML =
`<span style="color:${catColor}; font-weight:600;">● ${catLabel}</span>`;
document.getElementById('ld-desc').textContent = details.desc;
document.getElementById('ld-when').textContent = details.when || '—';
document.getElementById('ld-limits').textContent = details.limits || 'без особых ограничений';
const ldReports = document.getElementById('ld-reports');
ldReports.innerHTML = details.reportsTo.length
? details.reportsTo.map(renderLegendItem).join('')
: '<li style="color:#586e75; font-style:italic;">Не подчиняется никому</li>';
const ldManages = document.getElementById('ld-manages');
ldManages.innerHTML = details.manages.length
? details.manages.map(renderLegendItem).join('')
: '<li style="color:#586e75; font-style:italic;">Никто не подчиняется</li>';
const ldTogether = document.getElementById('ld-together');
ldTogether.innerHTML = details.together.length
? details.together.map(renderLegendItem).join('')
: '<li style="color:#586e75; font-style:italic;">Нет особых одновременных связей</li>';
const ldConflicts = document.getElementById('ld-conflicts');
if (details.conflicts && details.conflicts.length) {
ldConflicts.innerHTML = details.conflicts.map(c =>
`<div class="conflict-item"><div class="cname">⚡ ${c.name}</div><div class="cdesc">${c.desc}</div></div>`
).join('');
} else {
ldConflicts.innerHTML = '<div id="legend-no-conflicts" style="font-size:12px;color:#586e75;">Конфликтов не выявлено</div>';
}
document.getElementById('conflicts-section').style.display = '';
panel.classList.add('visible');
}
network.on('click', params => {
if (params.nodes.length === 1) {
showLegend(params.nodes[0]);
} else if (params.nodes.length === 0 && params.edges.length === 0) {
document.getElementById('legend-panel').classList.remove('visible');
}
});
document.getElementById('legend-close').addEventListener('click', () => {
document.getElementById('legend-panel').classList.remove('visible');
});
// ════════════════════════════════════════════════════
// SECTION 6: TOOLBAR
// ════════════════════════════════════════════════════
let highlightedNode = null;
document.getElementById('search').addEventListener('input', function () {
const q = this.value.trim().toLowerCase();
if (!q) {
nodesDS.update(NODES.map(n => ({ id: n.id, borderWidth: 2, opacity: 1.0 })));
highlightedNode = null;
return;
}
const matches = NODES.filter(n => n.label.toLowerCase().includes(q));
const updates = NODES.map(n => {
const match = matches.some(m => m.id === n.id);
return {
id: n.id,
borderWidth: match ? 5 : 1,
opacity: match ? 1.0 : 0.25,
};
});
nodesDS.update(updates);
if (matches.length === 1) {
network.focus(matches[0].id, { scale: 1.4, animation: { duration: 500, easingFunction: 'easeInOutQuad' } });
showLegend(matches[0].id);
highlightedNode = matches[0].id;
}
});
document.getElementById('btn-freeze').addEventListener('click', () => {
network.setOptions({ physics: { enabled: false } });
});
document.getElementById('btn-unfreeze').addEventListener('click', () => {
network.setOptions({ physics: { enabled: true } });
});
document.getElementById('btn-reset').addEventListener('click', () => {
network.fit({ animation: { duration: 600, easingFunction: 'easeInOutQuad' } });
});
document.getElementById('btn-clear').addEventListener('click', () => {
document.getElementById('search').value = '';
nodesDS.update(NODES.map(n => ({ id: n.id, borderWidth: 2, opacity: 1.0 })));
document.getElementById('legend-panel').classList.remove('visible');
highlightedNode = null;
});
</script>
</body>
</html>