#!/usr/bin/env bash # ============================================================== # grafo-conocimiento.sh — Grafo de conocimientos desde front matter # # Extrae el front matter de todas las notas Markdown de un vault # y construye un grafo JSON: nodos = notas, aristas = tags # compartidos. Sin Python, sin IA. Solo fd, yq y jq. # # Uso: ./grafo-conocimiento.sh [ruta-al-vault] [salida.json] # ./grafo-conocimiento.sh ~/notas grafo.json # # Dependencias: fd, yq (Mike Farah), jq # ============================================================== VAULT="${1:-.}" OUT="${2:-grafo.json}" # 1. Un nodo (objeto JSON) por cada nota, con su ruta real como id. # Se filtran los .md que no empiezan por '---' (sin front matter). fd -e md . "$VAULT" -x sh -c ' head -1 "$1" | grep -q "^---" || exit 0 yq --front-matter=extract -o=json \ "{\"id\": \"$1\", \"title\": .title, \"created\": .created, \"updated\": .updated, \"tags\": (.tags // [])}" "$1" 2>/dev/null ' _ {} \; > /tmp/nodos.ndjson # 2. Construye nodos + aristas (dos notas comparten al menos un tag). jq -s ' . as $n | { nodes: [ $n[] | {id: .id, title: .title, tags: .tags} ], edges: [ $n[] as $a | $n[] as $b | select($a.id < $b.id) | ([ $a.tags[] | select(. as $t | $b.tags | index($t)) ]) as $c | select(($c | length) > 0) | {source: $a.id, target: $b.id, tags: ($c | unique)} ] } ' /tmp/nodos.ndjson > "$OUT" echo "Grafo generado en $OUT" jq '{nodos: (.nodes | length), aristas: (.edges | length)}' "$OUT"