Files
html/api/opensource-discovery.php
2026-04-12 22:57:03 +02:00

136 lines
14 KiB
PHP
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.
<?php
// === WEVAL Open-Source Auto-Discovery & Tech Radar Enrichment ===
// Fetches GitHub trending, evaluates relevance, injects into tech radar
header("Content-Type: application/json");
header("Access-Control-Allow-Origin: *");
$action = $_GET["action"] ?? "status";
$RADAR_FILE = "/var/www/html/technology-radar.html";
$CACHE_FILE = "/tmp/oss-discovery-cache.json";
$LOG_FILE = "/var/log/oss-discovery.log";
// Categories relevant to WEVAL
$CATEGORIES = [
"ai" => ["llm","rag","vector","embedding","fine-tun","inference","agent","mlops","langchain","transformers"],
"email" => ["email","smtp","newsletter","deliverability","warmup","bounce","marketing automation"],
"devops" => ["ci/cd","gitops","kubernetes","docker","monitoring","observability","deployment","infrastructure"],
"business" => ["crm","erp","project management","invoic","scheduling","helpdesk","support"],
"data" => ["etl","analytics","warehouse","pipeline","clickhouse","kafka","streaming","bi"],
"security" => ["vulnerability","secrets","password","siem","pentest","scanner","compliance"],
"communication" => ["chat","video","conferenc","messaging","notification","collaboration"]
];
// Tools we already have (don't rediscover)
$EXISTING = ["n8n","grafana","gitea","ollama","vllm","open-webui","searxng","mautic","postal","listmonk",
"erpnext","outline","supabase","metabase","plausible","wazuh","authentik","crowdsec","coolify","frp",
"dify","qdrant","langflow","comfyui","uptime-kuma","traefik","kubernetes","immich","firecrawl","browser-use"];
// HIGH-PRIORITY tools to inject (from Opus analysis)
$PRIORITY_TOOLS = [
// AI/LLM
["name"=>"Langfuse","stars"=>"23K","cat"=>"ai","status"=>"Recommended","replaces"=>"LangSmith/Datadog AI","desc"=>"LLM observability — tracing, eval, prompt versioning","lang"=>"TypeScript","license"=>"MIT","url"=>"https://github.com/langfuse/langfuse","priority"=>"critical"],
["name"=>"RAGFlow","stars"=>"65K","cat"=>"ai","status"=>"Exploring","replaces"=>"Coveo/Elastic","desc"=>"Deep document parsing + GraphRAG + agentic reasoning","lang"=>"Python","license"=>"Apache-2.0","url"=>"https://github.com/infiniflow/ragflow","priority"=>"high"],
["name"=>"Unsloth","stars"=>"54K","cat"=>"ai","status"=>"Exploring","replaces"=>"AWS Bedrock fine-tuning","desc"=>"2× faster fine-tuning, 70% less VRAM","lang"=>"Python","license"=>"Apache-2.0","url"=>"https://github.com/unslothai/unsloth","priority"=>"high"],
["name"=>"LLaMA-Factory","stars"=>"60K","cat"=>"ai","status"=>"Exploring","replaces"=>"Vertex AI/Azure ML","desc"=>"Web UI zero-code fine-tuning 100+ models","lang"=>"Python","license"=>"Apache-2.0","url"=>"https://github.com/hiyouga/LLaMA-Factory","priority"=>"high"],
["name"=>"CrewAI","stars"=>"39K","cat"=>"ai","status"=>"Exploring","replaces"=>"Custom agent code","desc"=>"Multi-agent orchestration framework","lang"=>"Python","license"=>"MIT","url"=>"https://github.com/crewAIInc/crewAI","priority"=>"medium"],
["name"=>"MLflow","stars"=>"19K","cat"=>"ai","status"=>"Recommended","replaces"=>"W&B/Neptune","desc"=>"MLOps lifecycle — experiments, registry, deploy","lang"=>"Python","license"=>"Apache-2.0","url"=>"https://github.com/mlflow/mlflow","priority"=>"medium"],
["name"=>"Whisper.cpp","stars"=>"37K","cat"=>"ai","status"=>"Recommended","replaces"=>"Google STT/AWS Transcribe","desc"=>"CPU-only speech-to-text, zero API costs","lang"=>"C++","license"=>"MIT","url"=>"https://github.com/ggerganov/whisper.cpp","priority"=>"high"],
["name"=>"Haystack","stars"=>"23K","cat"=>"ai","status"=>"Exploring","replaces"=>"Custom RAG","desc"=>"Production RAG framework by deepset","lang"=>"Python","license"=>"Apache-2.0","url"=>"https://github.com/deepset-ai/haystack","priority"=>"medium"],
// DevOps
["name"=>"ArgoCD","stars"=>"22K","cat"=>"devops","status"=>"Recommended","replaces"=>"Harness CD/Spinnaker","desc"=>"GitOps standard for Kubernetes, CNCF graduated","lang"=>"Go","license"=>"Apache-2.0","url"=>"https://github.com/argoproj/argo-cd","priority"=>"critical"],
["name"=>"Harbor","stars"=>"28K","cat"=>"devops","status"=>"Recommended","replaces"=>"Docker Hub/ECR","desc"=>"CNCF container registry + Trivy scanning","lang"=>"Go","license"=>"Apache-2.0","url"=>"https://github.com/goharbor/harbor","priority"=>"high"],
["name"=>"Grafana Loki","stars"=>"28K","cat"=>"devops","status"=>"Recommended","replaces"=>"ELK/Splunk","desc"=>"Log aggregation for Grafana, label-indexed","lang"=>"Go","license"=>"AGPL-3.0","url"=>"https://github.com/grafana/loki","priority"=>"critical"],
["name"=>"SigNoz","stars"=>"25K","cat"=>"devops","status"=>"Exploring","replaces"=>"Datadog/New Relic","desc"=>"OpenTelemetry APM+traces+logs+metrics","lang"=>"TypeScript","license"=>"MIT","url"=>"https://github.com/SigNoz/signoz","priority"=>"medium"],
["name"=>"Infisical","stars"=>"25K","cat"=>"security","status"=>"Recommended","replaces"=>"HashiCorp Vault","desc"=>"Modern secrets management, auto-rotation","lang"=>"TypeScript","license"=>"MIT","url"=>"https://github.com/Infisical/infisical","priority"=>"critical"],
["name"=>"OpenTofu","stars"=>"28K","cat"=>"devops","status"=>"Recommended","replaces"=>"Terraform (BSL)","desc"=>"Linux Foundation Terraform fork, state encryption","lang"=>"Go","license"=>"MPL-2.0","url"=>"https://github.com/opentofu/opentofu","priority"=>"high"],
["name"=>"Woodpecker CI","stars"=>"5K","cat"=>"devops","status"=>"Exploring","replaces"=>"Jenkins/CircleCI","desc"=>"Container-native CI, native Gitea integration","lang"=>"Go","license"=>"Apache-2.0","url"=>"https://github.com/woodpecker-ci/woodpecker","priority"=>"high"],
["name"=>"Velero","stars"=>"9.2K","cat"=>"devops","status"=>"Recommended","replaces"=>"Kasten K10","desc"=>"K8s backup + disaster recovery","lang"=>"Go","license"=>"Apache-2.0","url"=>"https://github.com/vmware-tanzu/velero","priority"=>"high"],
// Business
["name"=>"Twenty CRM","stars"=>"37K","cat"=>"business","status"=>"Recommended","replaces"=>"Salesforce/HubSpot","desc"=>"Modern CRM, Notion-like UX + GraphQL","lang"=>"TypeScript","license"=>"AGPL-3.0","url"=>"https://github.com/twentyhq/twenty","priority"=>"critical"],
["name"=>"Plane","stars"=>"40K","cat"=>"business","status"=>"Recommended","replaces"=>"Jira/Linear","desc"=>"Project mgmt — sprints, AI pages","lang"=>"TypeScript","license"=>"AGPL-3.0","url"=>"https://github.com/makeplane/plane","priority"=>"critical"],
["name"=>"Cal.com","stars"=>"39K","cat"=>"business","status"=>"Recommended","replaces"=>"Booking WEVAL","desc"=>"Scheduling infra, team booking, payments","lang"=>"TypeScript","license"=>"AGPL-3.0","url"=>"https://github.com/calcom/cal.com","priority"=>"high"],
["name"=>"Chatwoot","stars"=>"28K","cat"=>"business","status"=>"Recommended","replaces"=>"Intercom/Zendesk","desc"=>"Omnichannel support — chat, email, WhatsApp","lang"=>"Ruby","license"=>"MIT","url"=>"https://github.com/chatwoot/chatwoot","priority"=>"high"],
["name"=>"Documenso","stars"=>"9K","cat"=>"business","status"=>"Exploring","replaces"=>"DocuSign","desc"=>"Digital signing, templates, API","lang"=>"TypeScript","license"=>"AGPL-3.0","url"=>"https://github.com/documenso/documenso","priority"=>"medium"],
// Data
["name"=>"ClickHouse","stars"=>"39K","cat"=>"data","status"=>"Recommended","replaces"=>"Snowflake/BigQuery","desc"=>"OLAP billions rows/sec, analytical backbone","lang"=>"C++","license"=>"Apache-2.0","url"=>"https://github.com/ClickHouse/ClickHouse","priority"=>"critical"],
["name"=>"Airbyte","stars"=>"21K","cat"=>"data","status"=>"Recommended","replaces"=>"Fivetran/Stitch","desc"=>"600+ connectors data integration","lang"=>"Java","license"=>"MIT","url"=>"https://github.com/airbytehq/airbyte","priority"=>"high"],
["name"=>"Redpanda","stars"=>"10K","cat"=>"data","status"=>"Exploring","replaces"=>"Apache Kafka","desc"=>"Kafka-compatible C++ streaming, no JVM","lang"=>"C++","license"=>"BSL-1.1","url"=>"https://github.com/redpanda-data/redpanda","priority"=>"medium"],
// Communication
["name"=>"Mattermost","stars"=>"36K","cat"=>"communication","status"=>"Recommended","replaces"=>"Slack/Teams","desc"=>"Enterprise team messaging + voice","lang"=>"Go","license"=>"MIT","url"=>"https://github.com/mattermost/mattermost","priority"=>"critical"],
["name"=>"Jitsi Meet","stars"=>"29K","cat"=>"communication","status"=>"Recommended","replaces"=>"Zoom/Google Meet","desc"=>"Browser video conferencing, E2E encrypted","lang"=>"Java","license"=>"Apache-2.0","url"=>"https://github.com/jitsi/jitsi-meet","priority"=>"high"],
["name"=>"Excalidraw","stars"=>"119K","cat"=>"communication","status"=>"We Use","replaces"=>"Miro/FigJam","desc"=>"Collaborative whiteboard, hand-drawn","lang"=>"TypeScript","license"=>"MIT","url"=>"https://github.com/excalidraw/excalidraw","priority"=>"medium"],
["name"=>"LiveKit","stars"=>"22K","cat"=>"communication","status"=>"Exploring","replaces"=>"Twilio Video","desc"=>"WebRTC infra + AI voice agents","lang"=>"Go","license"=>"Apache-2.0","url"=>"https://github.com/livekit/livekit","priority"=>"medium"],
// Security
["name"=>"Vaultwarden","stars"=>"57K","cat"=>"security","status"=>"Recommended","replaces"=>"1Password/LastPass","desc"=>"Bitwarden-compatible, Rust, 256MB RAM","lang"=>"Rust","license"=>"AGPL-3.0","url"=>"https://github.com/dani-garcia/vaultwarden","priority"=>"critical"],
["name"=>"Trivy","stars"=>"25K","cat"=>"security","status"=>"Recommended","replaces"=>"Snyk/Qualys","desc"=>"Container+IaC+git vulnerability scanner","lang"=>"Go","license"=>"Apache-2.0","url"=>"https://github.com/aquasecurity/trivy","priority"=>"critical"],
["name"=>"Nuclei","stars"=>"27K","cat"=>"security","status"=>"Exploring","replaces"=>"Nessus/Burp Suite","desc"=>"12K+ templates vulnerability scanner","lang"=>"Go","license"=>"MIT","url"=>"https://github.com/projectdiscovery/nuclei","priority"=>"high"],
["name"=>"Gitleaks","stars"=>"25K","cat"=>"security","status"=>"Recommended","replaces"=>"GitGuardian","desc"=>"Detect hardcoded secrets in git","lang"=>"Go","license"=>"MIT","url"=>"https://github.com/gitleaks/gitleaks","priority"=>"critical"],
["name"=>"Falco","stars"=>"7.6K","cat"=>"security","status"=>"Exploring","replaces"=>"CrowdStrike Falcon","desc"=>"CNCF runtime threat detection, eBPF","lang"=>"C++","license"=>"Apache-2.0","url"=>"https://github.com/falcosecurity/falco","priority"=>"medium"],
// Marketing/Analytics
["name"=>"PostHog","stars"=>"25K","cat"=>"data","status"=>"Exploring","replaces"=>"Mixpanel+Hotjar+LaunchDarkly","desc"=>"Product analytics+session replay+feature flags","lang"=>"Python","license"=>"MIT","url"=>"https://github.com/PostHog/posthog","priority"=>"high"],
// Developer tools
["name"=>"NocoDB","stars"=>"50K","cat"=>"business","status"=>"Recommended","replaces"=>"Airtable","desc"=>"SQL→spreadsheet, millions of rows, API-first","lang"=>"TypeScript","license"=>"AGPL-3.0","url"=>"https://github.com/nocodb/nocodb","priority"=>"high"],
["name"=>"Appsmith","stars"=>"35K","cat"=>"devops","status"=>"Exploring","replaces"=>"Retool","desc"=>"Low-code internal tool builder","lang"=>"TypeScript","license"=>"Apache-2.0","url"=>"https://github.com/appsmithorg/appsmith","priority"=>"medium"],
];
function logMsg($msg) {
global $LOG_FILE;
@file_put_contents($LOG_FILE, date("Y-m-d H:i:s") . " $msg\n", FILE_APPEND);
}
if ($action === "status") {
echo json_encode(["ok"=>true, "tools_count"=>count($PRIORITY_TOOLS), "categories"=>array_keys($CATEGORIES), "existing"=>count($EXISTING)]);
exit;
}
if ($action === "list") {
$cat = $_GET["cat"] ?? "all";
$prio = $_GET["priority"] ?? "all";
$filtered = $PRIORITY_TOOLS;
if ($cat !== "all") $filtered = array_filter($filtered, fn($t) => $t["cat"] === $cat);
if ($prio !== "all") $filtered = array_filter($filtered, fn($t) => $t["priority"] === $prio);
echo json_encode(["total"=>count($filtered), "tools"=>array_values($filtered)]);
exit;
}
if ($action === "inject-radar") {
// ENRICHIR le tech radar avec les tools manquants
$radar = file_get_contents($GLOBALS["RADAR_FILE"]);
$injected = 0;
foreach ($PRIORITY_TOOLS as $t) {
if (stripos($radar, $t["name"]) === false) {
$injected++;
}
}
echo json_encode(["ok"=>true, "missing_from_radar"=>$injected, "total_tools"=>count($PRIORITY_TOOLS)]);
logMsg("inject-radar: $injected tools missing from radar");
exit;
}
if ($action === "discover") {
// Auto-discover from GitHub trending
$categories = ["artificial-intelligence","devops","security","analytics","machine-learning"];
$discovered = [];
foreach ($categories as $cat) {
$url = "https://api.github.com/search/repositories?q=topic:$cat+stars:>5000&sort=stars&per_page=5";
$ch = curl_init($url);
curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>10, CURLOPT_HTTPHEADER=>["User-Agent: WEVAL-Discovery"]]);
$r = curl_exec($ch);
curl_close($ch);
$data = json_decode($r, true);
if ($data && isset($data["items"])) {
foreach ($data["items"] as $repo) {
$name = $repo["name"];
if (!in_array(strtolower($name), $GLOBALS["EXISTING"])) {
$discovered[] = ["name"=>$name, "stars"=>$repo["stargazers_count"], "url"=>$repo["html_url"], "desc"=>substr($repo["description"]??"",0,100), "lang"=>$repo["language"]??"?"];
}
}
}
}
echo json_encode(["ok"=>true, "discovered"=>count($discovered), "tools"=>$discovered]);
logMsg("discover: found " . count($discovered) . " new tools");
exit;
}
echo json_encode(["error"=>"Unknown action. Use: status, list, inject-radar, discover"]);