feat(v1.5.2): Execute database migrations and complete setup
- Execute all 6 migrations on Desk CRM production database - Create missing tables: cr_lsps, cr_agent_lsps, cr_lsp_usage - Create archive tables: cr_*_usage_archive (4 tables) - Create system tables: cr_migrations, cr_maintenance_log - Make all scripts executable (chmod +x) - Total cr_* tables: 38 Migration files: - 001_initial_schema.sql - 002_add_lsps.sql - 003_add_relationships.sql - 004_add_telemetry.sql - 005_add_archive_tables.sql - 006_add_maintenance_log.sql Scripts: - session-init.sh, session-end.sh - inject-context.sh, inject-agent-context.sh - record-usage.sh, db-backup.sh, sync-to-mysql.sh Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
89
scripts/db-backup.sh
Executable file
89
scripts/db-backup.sh
Executable file
@@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
# db-backup.sh - Backup selectivo das tabelas cr_*
|
||||
# Author: Descomplicar®
|
||||
#
|
||||
# Uso: ./db-backup.sh [--compress] [--tables=X,Y]
|
||||
|
||||
set -e
|
||||
|
||||
# Directório de backups (regra CLAUDE.md)
|
||||
BACKUP_BASE="/media/ealmeida/Dados/Backups"
|
||||
BACKUP_DIR="$BACKUP_BASE/claude-infrastructure/cr_backup_$(date +%Y%m%d_%H%M%S)"
|
||||
COMPRESS=0
|
||||
TABLES=""
|
||||
|
||||
# Parse argumentos
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
--compress)
|
||||
COMPRESS=1
|
||||
shift
|
||||
;;
|
||||
--tables=*)
|
||||
TABLES="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Criar directório de backup
|
||||
mkdir -p "$BACKUP_DIR/schema"
|
||||
mkdir -p "$BACKUP_DIR/data"
|
||||
|
||||
# Lista de tabelas cr_* (se não especificadas)
|
||||
if [[ -z "$TABLES" ]]; then
|
||||
TABLES="cr_agents,cr_skills,cr_mcps,cr_lsps,cr_sdks,cr_mcp_tools,cr_plugins,cr_hooks"
|
||||
TABLES="$TABLES,cr_agent_mcps,cr_agent_lsps,cr_agent_skills,cr_skill_mcps"
|
||||
TABLES="$TABLES,cr_sdk_agents,cr_sdk_skills,cr_sdk_mcps,cr_agent_collaborations"
|
||||
TABLES="$TABLES,cr_agent_usage,cr_skill_usage,cr_mcp_tool_usage,cr_lsp_usage"
|
||||
TABLES="$TABLES,cr_decision_trees,cr_recommendations,cr_component_issues,cr_reflections"
|
||||
TABLES="$TABLES,cr_migrations,cr_maintenance_log"
|
||||
fi
|
||||
|
||||
# Criar manifest.json
|
||||
cat > "$BACKUP_DIR/manifest.json" << EOF
|
||||
{
|
||||
"backup_id": "$(basename $BACKUP_DIR)",
|
||||
"created_at": "$(date -Iseconds)",
|
||||
"created_by": "descomplicar-meta-plugin",
|
||||
"version": "1.5.1",
|
||||
"tables": "$(echo $TABLES | tr ',' '\n' | wc -l)",
|
||||
"compressed": $COMPRESS
|
||||
}
|
||||
EOF
|
||||
|
||||
echo "╔══════════════════════════════════════════════════════════════════════╗"
|
||||
echo "║ DB BACKUP ║"
|
||||
echo "╠══════════════════════════════════════════════════════════════════════╣"
|
||||
echo "║ Backup ID: $(basename $BACKUP_DIR)"
|
||||
echo "║ Output: $BACKUP_DIR/"
|
||||
echo "╠══════════════════════════════════════════════════════════════════════╣"
|
||||
echo "║ NOTA: Este script gera estrutura de backup. ║"
|
||||
echo "║ Para dump real, usar desk-crm-v3 MCP ou mysqldump. ║"
|
||||
echo "╠══════════════════════════════════════════════════════════════════════╣"
|
||||
|
||||
# Gerar SQL para cada tabela (esqueleto - dump real via MCP)
|
||||
IFS=',' read -ra TABLE_ARRAY <<< "$TABLES"
|
||||
for table in "${TABLE_ARRAY[@]}"; do
|
||||
echo "-- Backup: $table" > "$BACKUP_DIR/schema/$table.sql"
|
||||
echo "-- Dump via: mysqldump perfex_crm $table > $BACKUP_DIR/data/$table.sql" >> "$BACKUP_DIR/schema/$table.sql"
|
||||
echo "║ $table ✓"
|
||||
done
|
||||
|
||||
if [[ $COMPRESS -eq 1 ]]; then
|
||||
echo "╠══════════════════════════════════════════════════════════════════════╣"
|
||||
echo "║ Compressing..."
|
||||
cd "$BACKUP_BASE/claude-infrastructure"
|
||||
tar -czf "$(basename $BACKUP_DIR).tar.gz" "$(basename $BACKUP_DIR)"
|
||||
rm -rf "$BACKUP_DIR"
|
||||
echo "║ Compressed: $(basename $BACKUP_DIR).tar.gz"
|
||||
fi
|
||||
|
||||
echo "╠══════════════════════════════════════════════════════════════════════╣"
|
||||
echo "║ Status: ✓ SUCCESS ║"
|
||||
echo "╚══════════════════════════════════════════════════════════════════════╝"
|
||||
|
||||
exit 0
|
||||
48
scripts/inject-agent-context.sh
Executable file
48
scripts/inject-agent-context.sh
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/bin/bash
|
||||
# inject-agent-context.sh - Injecção de contexto para subagentes
|
||||
# Hook: SubagentStart
|
||||
# Autor: Descomplicar
|
||||
# Data: 2026-02-04
|
||||
|
||||
# Este script é chamado quando um subagente inicia
|
||||
# Recebe o tipo de agente via variável de ambiente CLAUDE_SUBAGENT_TYPE
|
||||
|
||||
PLUGIN_ROOT="$(dirname "$(dirname "$(readlink -f "$0")")")"
|
||||
AGENT_TYPE="${CLAUDE_SUBAGENT_TYPE:-unknown}"
|
||||
CONFIG_FILE="$HOME/.claude/agents/agent-knowledge-config.json"
|
||||
CACHE_DIR="${PLUGIN_ROOT}/.cache"
|
||||
|
||||
mkdir -p "$CACHE_DIR"
|
||||
|
||||
# Verificar se temos configuração para este agente
|
||||
if [[ ! -f "$CONFIG_FILE" ]]; then
|
||||
echo "META-PLUGIN: No agent-knowledge-config.json found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Tentar extrair configuração do agente (usando jq se disponível)
|
||||
if command -v jq &> /dev/null; then
|
||||
AGENT_CONFIG=$(jq -r ".\"$AGENT_TYPE\" // empty" "$CONFIG_FILE" 2>/dev/null)
|
||||
|
||||
if [[ -n "$AGENT_CONFIG" && "$AGENT_CONFIG" != "null" ]]; then
|
||||
# Extrair datasets
|
||||
DATASETS=$(echo "$AGENT_CONFIG" | jq -r '.datasets // [] | join(", ")' 2>/dev/null)
|
||||
AUTO_CONSULT=$(echo "$AGENT_CONFIG" | jq -r '.auto_consult // false' 2>/dev/null)
|
||||
QUERY_TEMPLATE=$(echo "$AGENT_CONFIG" | jq -r '.query_template // ""' 2>/dev/null)
|
||||
|
||||
if [[ -n "$DATASETS" && "$DATASETS" != "null" ]]; then
|
||||
echo "META-PLUGIN: Agent context for $AGENT_TYPE"
|
||||
echo " Datasets: $DATASETS"
|
||||
echo " Auto-consult: $AUTO_CONSULT"
|
||||
if [[ -n "$QUERY_TEMPLATE" && "$QUERY_TEMPLATE" != "null" ]]; then
|
||||
echo " Query template: $QUERY_TEMPLATE"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo "META-PLUGIN: No specific config for agent '$AGENT_TYPE'"
|
||||
fi
|
||||
else
|
||||
echo "META-PLUGIN: jq not installed, skipping advanced context injection"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
34
scripts/inject-context.sh
Executable file
34
scripts/inject-context.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
# inject-context.sh - Injeta contexto específico para subagentes
|
||||
# Chamado pelo hook SubagentStart
|
||||
# Author: Descomplicar®
|
||||
|
||||
set -e
|
||||
|
||||
AGENT_TYPE="${1:-unknown}"
|
||||
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-/home/ealmeida/mcp-servers/descomplicar-meta-plugin}"
|
||||
|
||||
# Output contexto relevante para o agente
|
||||
cat << EOF
|
||||
## Descomplicar Infrastructure Context
|
||||
|
||||
### Available Commands
|
||||
- /descomplicar:status - Dashboard de infraestrutura
|
||||
- /descomplicar:sync - Sincronização ficheiros ↔ MySQL
|
||||
- /descomplicar:relationships - Gestão de relacionamentos
|
||||
- /descomplicar:telemetry - Métricas de uso
|
||||
|
||||
### Database Tables (cr_*)
|
||||
- Core: cr_agents, cr_skills, cr_mcps, cr_lsps, cr_sdks
|
||||
- Relationships: cr_agent_mcps, cr_agent_skills, cr_skill_mcps
|
||||
- Telemetry: cr_agent_usage, cr_skill_usage, cr_mcp_tool_usage
|
||||
|
||||
### MCP Available
|
||||
- desk-crm-v3: Operações MySQL
|
||||
- filesystem: Operações de ficheiros
|
||||
- mcp-time: Data/hora actual
|
||||
- gitea: Repositórios
|
||||
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
75
scripts/record-usage.sh
Executable file
75
scripts/record-usage.sh
Executable file
@@ -0,0 +1,75 @@
|
||||
#!/bin/bash
|
||||
# record-usage.sh - Regista uso de componentes na telemetria
|
||||
# Pode ser chamado manualmente ou via hooks
|
||||
# Author: Descomplicar®
|
||||
#
|
||||
# Uso: ./record-usage.sh <type> <component_slug> [success] [duration_ms]
|
||||
# Exemplo: ./record-usage.sh agent wordpress-plugin-developer 1 5200
|
||||
|
||||
set -e
|
||||
|
||||
TYPE="${1:-agent}"
|
||||
COMPONENT="${2:-unknown}"
|
||||
SUCCESS="${3:-1}"
|
||||
DURATION="${4:-0}"
|
||||
SESSION_ID="${CLAUDE_SESSION_ID:-manual}"
|
||||
|
||||
# Validar argumentos
|
||||
if [[ -z "$COMPONENT" || "$COMPONENT" == "unknown" ]]; then
|
||||
echo "Usage: $0 <type> <component_slug> [success] [duration_ms]"
|
||||
echo "Types: agent, skill, mcp_tool, lsp"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Determinar tabela baseado no tipo
|
||||
case "$TYPE" in
|
||||
agent)
|
||||
TABLE="cr_agent_usage"
|
||||
ID_COLUMN="agent_id"
|
||||
LOOKUP_TABLE="cr_agents"
|
||||
;;
|
||||
skill)
|
||||
TABLE="cr_skill_usage"
|
||||
ID_COLUMN="skill_id"
|
||||
LOOKUP_TABLE="cr_skills"
|
||||
;;
|
||||
mcp_tool)
|
||||
TABLE="cr_mcp_tool_usage"
|
||||
ID_COLUMN="mcp_tool_id"
|
||||
LOOKUP_TABLE="cr_mcp_tools"
|
||||
;;
|
||||
lsp)
|
||||
TABLE="cr_lsp_usage"
|
||||
ID_COLUMN="lsp_id"
|
||||
LOOKUP_TABLE="cr_lsps"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown type: $TYPE"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# Gerar SQL para inserção
|
||||
# Nota: Este SQL seria executado via desk-crm-v3 MCP
|
||||
SQL="INSERT INTO $TABLE ($ID_COLUMN, session_id, success, duration_sec, created_at)
|
||||
SELECT id, '$SESSION_ID', $SUCCESS, $((DURATION / 1000)), NOW()
|
||||
FROM $LOOKUP_TABLE
|
||||
WHERE slug = '$COMPONENT'
|
||||
LIMIT 1;"
|
||||
|
||||
# Output SQL para debug ou execução manual
|
||||
echo "-- Record Usage: $TYPE/$COMPONENT"
|
||||
echo "$SQL"
|
||||
|
||||
# Se EXECUTE_SQL=1, tentar executar via mysql client (se disponível)
|
||||
if [[ "${EXECUTE_SQL:-0}" == "1" ]]; then
|
||||
if command -v mysql &> /dev/null && [[ -n "$MYSQL_HOST" ]]; then
|
||||
mysql -h "$MYSQL_HOST" -u "$MYSQL_USER" -p"$MYSQL_PASS" "$MYSQL_DB" -e "$SQL"
|
||||
echo "-- Executed successfully"
|
||||
else
|
||||
echo "-- MySQL client not available or credentials not set"
|
||||
echo "-- Set MYSQL_HOST, MYSQL_USER, MYSQL_PASS, MYSQL_DB to execute"
|
||||
fi
|
||||
fi
|
||||
|
||||
exit 0
|
||||
46
scripts/session-end.sh
Executable file
46
scripts/session-end.sh
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
# session-end.sh - Finaliza sessão e regista métricas
|
||||
# Chamado pelo hook Stop
|
||||
# Author: Descomplicar®
|
||||
|
||||
set -e
|
||||
|
||||
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-/home/ealmeida/mcp-servers/descomplicar-meta-plugin}"
|
||||
SESSION_FILE="$PLUGIN_ROOT/.current_session"
|
||||
|
||||
# Verificar se existe sessão activa
|
||||
if [[ ! -f "$SESSION_FILE" ]]; then
|
||||
echo "No active session found"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Ler dados da sessão
|
||||
SESSION_DATA=$(cat "$SESSION_FILE")
|
||||
SESSION_ID=$(echo "$SESSION_DATA" | jq -r '.session_id // "unknown"')
|
||||
STARTED_AT=$(echo "$SESSION_DATA" | jq -r '.started_at // ""')
|
||||
TOOL_CALLS=$(echo "$SESSION_DATA" | jq -r '.tool_calls // 0')
|
||||
|
||||
# Calcular duração
|
||||
if [[ -n "$STARTED_AT" ]]; then
|
||||
START_EPOCH=$(date -d "$STARTED_AT" +%s 2>/dev/null || echo 0)
|
||||
NOW_EPOCH=$(date +%s)
|
||||
DURATION=$((NOW_EPOCH - START_EPOCH))
|
||||
else
|
||||
DURATION=0
|
||||
fi
|
||||
|
||||
# Output resumo
|
||||
cat << EOF
|
||||
╔══════════════════════════════════════════════════════════════════════╗
|
||||
║ SESSION ENDED ║
|
||||
╠══════════════════════════════════════════════════════════════════════╣
|
||||
║ Session ID: $SESSION_ID
|
||||
║ Duration: ${DURATION}s
|
||||
║ Tool Calls: $TOOL_CALLS
|
||||
╚══════════════════════════════════════════════════════════════════════╝
|
||||
EOF
|
||||
|
||||
# Limpar ficheiro de sessão
|
||||
rm -f "$SESSION_FILE"
|
||||
|
||||
exit 0
|
||||
29
scripts/session-init.sh
Executable file
29
scripts/session-init.sh
Executable file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
# session-init.sh - Inicializa sessão e mostra status da infraestrutura
|
||||
# Chamado pelo hook SessionStart
|
||||
# Author: Descomplicar®
|
||||
|
||||
set -e
|
||||
|
||||
# Gerar session ID único
|
||||
SESSION_ID="${CLAUDE_SESSION_ID:-$(date +%s)-$$}"
|
||||
export SESSION_ID
|
||||
|
||||
# Ficheiro de sessão para tracking
|
||||
SESSION_FILE="${CLAUDE_PLUGIN_ROOT:-/home/ealmeida/mcp-servers/descomplicar-meta-plugin}/.current_session"
|
||||
|
||||
# Registar início de sessão
|
||||
echo "{\"session_id\": \"$SESSION_ID\", \"started_at\": \"$(date -Iseconds)\", \"tool_calls\": 0}" > "$SESSION_FILE"
|
||||
|
||||
# Output status (será capturado pelo Claude)
|
||||
cat << 'EOF'
|
||||
╔══════════════════════════════════════════════════════════════════════╗
|
||||
║ DESCOMPLICAR INFRASTRUCTURE - Session Started ║
|
||||
╠══════════════════════════════════════════════════════════════════════╣
|
||||
║ Meta-Plugin v1.5.1 loaded ║
|
||||
║ Commands: /descomplicar:status, :sync, :create, :validate, :release ║
|
||||
║ DB Maintenance: :db-cleanup, :db-migrate, :db-backup, :db-archive ║
|
||||
╚══════════════════════════════════════════════════════════════════════╝
|
||||
EOF
|
||||
|
||||
exit 0
|
||||
76
scripts/sync-to-mysql.sh
Executable file
76
scripts/sync-to-mysql.sh
Executable file
@@ -0,0 +1,76 @@
|
||||
#!/bin/bash
|
||||
# sync-to-mysql.sh - Sincronização ficheiros → MySQL
|
||||
# Autor: Descomplicar
|
||||
# Data: 2026-02-04
|
||||
|
||||
# Este script é chamado manualmente ou via /descomplicar:sync
|
||||
# Requer: mysql client, jq
|
||||
|
||||
PLUGIN_ROOT="$(dirname "$(dirname "$(readlink -f "$0")")")"
|
||||
LOG_FILE="${PLUGIN_ROOT}/logs/sync.log"
|
||||
|
||||
# Configuração BD (usar variáveis de ambiente ou .env)
|
||||
DB_HOST="${DESK_DB_HOST:-localhost}"
|
||||
DB_USER="${DESK_DB_USER:-ealmeida_desk}"
|
||||
DB_PASS="${DESK_DB_PASS:-}"
|
||||
DB_NAME="${DESK_DB_NAME:-ealmeida_desk24}"
|
||||
|
||||
# Ficheiros fonte
|
||||
AGENTS_FILE="$HOME/.claude/sdks/_resources/agents.json"
|
||||
SKILLS_FILE="$HOME/.claude/sdks/_resources/skills.json"
|
||||
MCPS_FILE="$HOME/.claude/sdks/_resources/mcps.json"
|
||||
REGISTRY_FILE="$HOME/.claude/sdks/_registry.json"
|
||||
|
||||
# Timestamp
|
||||
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
|
||||
|
||||
log() {
|
||||
echo "[$TIMESTAMP] $1" >> "$LOG_FILE"
|
||||
echo "$1"
|
||||
}
|
||||
|
||||
# Verificar dependências
|
||||
check_deps() {
|
||||
if ! command -v jq &> /dev/null; then
|
||||
log "ERROR: jq is required but not installed"
|
||||
exit 1
|
||||
fi
|
||||
if ! command -v mysql &> /dev/null; then
|
||||
log "ERROR: mysql client is required but not installed"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Contar items em JSON
|
||||
count_json() {
|
||||
local file="$1"
|
||||
local key="$2"
|
||||
if [[ -f "$file" ]]; then
|
||||
jq -r ".$key | length" "$file" 2>/dev/null || echo "0"
|
||||
else
|
||||
echo "0"
|
||||
fi
|
||||
}
|
||||
|
||||
# Main
|
||||
main() {
|
||||
log "Starting sync..."
|
||||
|
||||
check_deps
|
||||
|
||||
# Contar items locais
|
||||
AGENTS_LOCAL=$(count_json "$AGENTS_FILE" "agents")
|
||||
SKILLS_LOCAL=$(count_json "$SKILLS_FILE" "skills")
|
||||
MCPS_LOCAL=$(count_json "$MCPS_FILE" "mcps")
|
||||
SDKS_LOCAL=$(jq -r '.sdks | length' "$REGISTRY_FILE" 2>/dev/null || echo "0")
|
||||
|
||||
log "Local counts: Agents=$AGENTS_LOCAL, Skills=$SKILLS_LOCAL, MCPs=$MCPS_LOCAL, SDKs=$SDKS_LOCAL"
|
||||
|
||||
# Nota: A sincronização real com MySQL seria feita via MCP desk-crm-v3
|
||||
# Este script serve como documentação e pode ser expandido
|
||||
|
||||
log "Sync completed (dry-run mode)"
|
||||
log "Use /descomplicar:sync for full sync via MCP"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user