New skills covering 10 categories: **Security & Audit**: 007 (STRIDE/PASTA/OWASP), cred-omega (secrets management) **AI Personas**: Karpathy, Hinton, Sutskever, LeCun (4 sub-skills), Altman, Musk, Gates, Jobs, Buffett **Multi-agent Orchestration**: agent-orchestrator, task-intelligence, multi-advisor **Code Analysis**: matematico-tao (Terence Tao-inspired mathematical code analysis) **Social & Messaging**: Instagram Graph API, Telegram Bot, WhatsApp Cloud API, social-orchestrator **Image Generation**: AI Studio (Gemini), Stability AI, ComfyUI Gateway, image-studio router **Brazilian Domain**: 6 auction specialist modules, 2 legal advisors, auctioneers data scraper **Product & Growth**: design, invention, monetization, analytics, growth engine **DevOps & LLM Ops**: Docker/CI-CD/AWS, RAG/embeddings/fine-tuning **Skill Governance**: installer, sentinel auditor, context management Each skill includes: - Standardized YAML frontmatter (name, description, risk, source, tags, tools) - Structured sections (Overview, When to Use, How it Works, Best Practices) - Python scripts and reference documentation where applicable - Cross-platform compatibility (Claude Code, Antigravity, Cursor, Gemini CLI, Codex CLI) Co-authored-by: ProgramadorBrasil <214873561+ProgramadorBrasil@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
135 lines
5.4 KiB
Python
135 lines
5.4 KiB
Python
"""
|
|
Analyzer cross-skill.
|
|
|
|
Identifica padroes compartilhados entre skills que poderiam ser
|
|
extraidos em modulos comuns, reducindo duplicacao.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import re
|
|
from pathlib import Path
|
|
from typing import Any, Dict, List, Tuple
|
|
|
|
|
|
def analyze_cross_skill(all_skills: List[Dict[str, Any]]) -> Tuple[float, List[Dict[str, Any]]]:
|
|
"""
|
|
Analisa padroes cross-skill. Diferente dos outros analyzers,
|
|
recebe TODAS as skills e retorna findings globais.
|
|
Retorna (score_medio, findings).
|
|
"""
|
|
findings: List[Dict[str, Any]] = []
|
|
|
|
if len(all_skills) < 2:
|
|
return 100.0, findings
|
|
|
|
# -- 1. Detectar modulos duplicados (mesmo nome de arquivo em multiplas skills) ---
|
|
module_presence: Dict[str, List[str]] = {}
|
|
for skill in all_skills:
|
|
for rel_path in skill.get("python_files", []):
|
|
filename = Path(rel_path).name
|
|
module_presence.setdefault(filename, []).append(skill["name"])
|
|
|
|
shared_modules = {k: v for k, v in module_presence.items() if len(v) > 1}
|
|
|
|
if shared_modules:
|
|
for module, skills in shared_modules.items():
|
|
if module in ("__init__.py", "requirements.txt"):
|
|
continue
|
|
findings.append({
|
|
"skill_name": "cross-skill",
|
|
"dimension": "cross_skill",
|
|
"severity": "medium",
|
|
"category": "duplicated_module",
|
|
"title": f"Modulo '{module}' presente em {len(skills)} skills",
|
|
"description": f"Skills: {', '.join(skills)}. "
|
|
"Potencial para extrair em modulo compartilhado.",
|
|
"recommendation": f"Avaliar se {module} pode ser extraido para uma lib compartilhada "
|
|
f"(ex: shared-core/scripts/{module})",
|
|
"effort": "medium",
|
|
"impact": "high",
|
|
})
|
|
|
|
# -- 2. Padroes de Database (mesmo pattern _connect) --------------------------
|
|
db_skills = [s for s in all_skills if s.get("has_db")]
|
|
if len(db_skills) > 1:
|
|
findings.append({
|
|
"skill_name": "cross-skill",
|
|
"dimension": "cross_skill",
|
|
"severity": "low",
|
|
"category": "shared_db_pattern",
|
|
"title": f"{len(db_skills)} skills com modulo db.py independente",
|
|
"description": f"Skills: {', '.join(s['name'] for s in db_skills)}. "
|
|
"Padrao Database._connect() com WAL mode eh repetido.",
|
|
"recommendation": "Criar classe BaseDatabase em shared-core com _connect(), "
|
|
"e cada skill herdar e definir apenas suas tabelas.",
|
|
"effort": "medium",
|
|
"impact": "medium",
|
|
})
|
|
|
|
# -- 3. Padroes de Config (mesmo pattern ROOT_DIR) ----------------------------
|
|
config_skills = [s for s in all_skills if s.get("has_config")]
|
|
if len(config_skills) > 1:
|
|
findings.append({
|
|
"skill_name": "cross-skill",
|
|
"dimension": "cross_skill",
|
|
"severity": "info",
|
|
"category": "shared_config_pattern",
|
|
"title": f"{len(config_skills)} skills com config.py similar",
|
|
"description": "Padrao de paths (ROOT_DIR, DATA_DIR, etc) repetido.",
|
|
"recommendation": "Considerar base_config.py compartilhado com paths padrao",
|
|
"effort": "low",
|
|
"impact": "low",
|
|
})
|
|
|
|
# -- 4. Skills sem governanca vs com governanca --------------------------------
|
|
gov_skills = [s for s in all_skills if s.get("has_governance")]
|
|
no_gov_skills = [s for s in all_skills if not s.get("has_governance")]
|
|
|
|
if gov_skills and no_gov_skills:
|
|
findings.append({
|
|
"skill_name": "cross-skill",
|
|
"dimension": "cross_skill",
|
|
"severity": "medium",
|
|
"category": "inconsistent_governance",
|
|
"title": "Governanca inconsistente entre skills",
|
|
"description": f"Com governanca: {', '.join(s['name'] for s in gov_skills)}. "
|
|
f"Sem governanca: {', '.join(s['name'] for s in no_gov_skills)}.",
|
|
"recommendation": "Padronizar governanca em todas as skills. "
|
|
"Extrair GovernanceManager para modulo compartilhado.",
|
|
"effort": "medium",
|
|
"impact": "high",
|
|
})
|
|
|
|
# -- 5. Padroes de export (json/csv/parquet) -----------------------------------
|
|
export_skills = []
|
|
for skill in all_skills:
|
|
for rel_path in skill.get("python_files", []):
|
|
if "export" in rel_path.lower():
|
|
export_skills.append(skill["name"])
|
|
break
|
|
|
|
if len(export_skills) > 1:
|
|
findings.append({
|
|
"skill_name": "cross-skill",
|
|
"dimension": "cross_skill",
|
|
"severity": "low",
|
|
"category": "shared_export_pattern",
|
|
"title": f"{len(export_skills)} skills com modulo de export",
|
|
"description": f"Skills: {', '.join(export_skills)}",
|
|
"recommendation": "Considerar export utils compartilhados (json/csv/parquet)",
|
|
"effort": "low",
|
|
"impact": "low",
|
|
})
|
|
|
|
# Score baseado na quantidade de duplicacao encontrada
|
|
score = 100.0
|
|
for f in findings:
|
|
if f["severity"] == "medium":
|
|
score -= 8
|
|
elif f["severity"] == "low":
|
|
score -= 3
|
|
elif f["severity"] == "info":
|
|
score -= 1
|
|
|
|
return max(0.0, min(100.0, score)), findings
|