¿Qué hace Sincronización de proyectos de Obsidian?
El vault se describe a sí mismo. Dónde están los proyectos, dónde van los terminados, dónde el hook deja sus registros y qué nota declara las convenciones del vault: todo eso viene de .claude-vault.json en la raíz del vault, y scan lo devuelve. Esta habilidad no asume nombres de carpeta.
Un vault no son solo proyectos, y su nota de convenciones dice qué contiene cada carpeta. Tenlo en cuenta al ofrecer dónde poner algo nuevo: una decisión o un hecho que afecta a varios proyectos no va en la nota de un solo proyecto.
Mapa local primero
Busca el mapa local de esta habilidad antes que cualquier otra cosa: una sección llamada obsidian-project-sync local map en las instrucciones permanentes del usuario (sus archivos CLAUDE.md en Claude Code, leídos desde el disco en lugar de la copia en contexto, que puede ser anterior a una edición; Instrucciones del proyecto o las preferencias del usuario en claude.ai). Una sección llamada Local map for this install dentro de este SKILL.md, añadida cuando la habilidad se empaquetó para una cuenta de claude.ai, también cuenta; las instrucciones permanentes que digan lo contrario ganan. Contiene lo que solo esa configuración sabe: la ruta del vault, las convenciones propias del usuario además de las del vault (notas complementarias que cada proyecto lleva, estilos de callout), otros archivos que apuntan al vault y deben cambiar con él. Síguelo donde hable; anula los valores predeterminados aquí.
El script y el vault
El script es scripts/vault.py, junto a este SKILL.md: construye su ruta desde la propia carpeta de la habilidad (Claude Code indica el directorio base cuando la habilidad se carga). Cada ejemplo a continuación lo escribe como vault.py. Necesita Python 3.8 o posterior; si no se encuentra python, prueba python3, luego py.
La ruta del vault viene, en este orden, del mapa local, de la variable de entorno OBSIDIAN_VAULT, o preguntando al usuario. Pásala con --vault, antes o después del subcomando. El script no tiene un valor predeterminado incorporado a propósito: sin un vault se detiene y lo dice.
Siempre primero: mira antes de escribir
python vault.py scan --vault "<vault>"
Sin --project devuelve el inventario del vault: qué proyectos existen, en qué zona y con qué status. statuses_in_use lista los valores que el usuario ya usa; elige uno de esos y no inventes etiquetas.
Luego el proyecto en sí:
python vault.py scan --vault "<vault>" --project "<nombre de carpeta>"
Devuelve la carpeta, la nota principal, su frontmatter, la lista exacta de sus encabezados, los otros archivos en la carpeta, el registro de sesión (y qué archivo de registro leyó, en session_log_file), y sessions_since_note_changed: las sesiones registradas más recientes que el último cambio de la nota en disco. Esa última lista es por donde empieza "lo que aún no está en la nota", no una prueba de ello: compárala con la nota antes de afirmar que falta algo.
--project toma el nombre de la carpeta del proyecto en el vault, comparado sin distinción de mayúsculas ni acentos. Cuando trabajes desde un repositorio de código, la carpeta suele tener el nombre del repositorio; si no, ejecuta scan sin --project y empareja por el frontmatter de la nota principal (una clave path o url, si el vault usa una), y pregunta cuando no coincida nada.
Un proyecto en la zona de archivo está terminado. No lo recrees entre los activos ni lo actualices sin preguntar.
Segundo: lee las convenciones del vault
scan devuelve un bloque config:
"config": {
"source": ".claude-vault.json",
"projects": "Projects",
"archive": "Archive",
"logs": "Toolbox/Claude Sync",
"conventions": "/path/to/vault/Meta/Convenciones.md"
}
conventions es la nota que manda. Léele antes de escribir en cualquier otra: declara el esquema de frontmatter, cómo se escriben las notas en ese vault, qué puede cambiar sin preguntar y qué no. Esta habilidad no lleva copia de ello a propósito: una copia envejece, y una versión anterior de esta habilidad terminó apuntando a una carpeta que ya no existía.
Si conventions es null, el vault no declara ninguna. Pregunta antes de escribir en cualquier nota.
El mismo bloque dice de dónde vinieron las carpetas. Si source es defaults, el vault no se ha descrito a sí mismo y estás trabajando sobre suposiciones: dilo, y ofrece escribir .claude-vault.json (formato en references/mechanics.md). Si aparece un warning, la configuración está rota y necesita arreglarse antes de continuar.
Cada carpeta de proyecto es diferente: algunas solo contienen la nota y un canvas, otras llevan notas sueltas. Confía en scan, nunca en lo que había la última vez.
Escribir en una nota
Las notas están escritas a mano. No hay plantilla ni marcadores ocultos, y no se añaden ninguno. El cuerpo de una sección específica se reemplaza:
python vault.py section --vault "<vault>" --note "<ruta>" --heading "Despliegue" --content "<archivo>" --dry-run
El encabezado se compara sin emoji y por coincidencia parcial, así que Despliegue encuentra ## 🚀 Despliegue. Si no hay coincidencia, el script lista los encabezados que existen en lugar de inventar uno.
--content es un archivo que contiene el nuevo markdown. Escríbelo en una carpeta temporal (el scratchpad de la sesión, o la carpeta temporal del sistema), nunca dentro del vault o de un repositorio de código, y bórralo después.
Reglas que realmente importan:
--dry-runprimero, siempre, y el sí del usuario antes de la escritura real. Muestra al usuario el diff del dry-run, di si cada cambio es factual o de prosa, y espera. Ejecuta el mismo comando sin--dry-runsolo después de que acepten; un sí cubre los diffs que vieron, nada más.--contentlleva toda la sección, no solo lo que cambia.replaceintercambia todo el cuerpo bajo ese encabezado. Envía solo una tabla y la prosa debajo desaparece. Lee la sección actual, trabaja el cambio en ella y envía el resultado completo.- La última sección de la nota está protegida. Los enlaces de pie de página suelen vivir debajo de ella, no pertenecen a ninguna sección y se perderían. El script se detiene con código de salida 2 y lo dice. Usa
--mode appendpara añadir sin eliminar, que casi siempre es lo correcto para un registro continuo como Cambios recientes. appendrespeta los callouts. Cuando una sección es un callout delimitado (```ad-note, del plugin Admonition), el texto nuevo va dentro del delimitador, antes de su línea de cierre; cuando es un callout nativo (> [!note]), las nuevas líneas se citan para que permanezcan dentro de él. El pie de página sigue al final de cualquier manera.- Imita lo que hay. Idioma, voz, prosa o viñetas, longitud: la nota de convenciones del vault lo declara, y la nota que estás a punto de tocar lo confirma. Léela antes de redactar.
- Verifica antes de afirmar. Un conteo, una versión o un estado escritos en una nota deben provenir de algo que leíste o ejecutaste en esta sesión. Si no se puede verificar ahora, déjalo fuera o di que no está verificado.
Añadir una nueva sección requiere decir dónde va:
--heading "Pruebas" --after "Trampas". Pregunta primero: una nueva sección cambia la estructura de un documento que el usuario escribió.
Lo que puedes cambiar sin preguntar
El vault lo declara, en su nota de convenciones: la parte que dice qué es factual y comprobable (y por lo tanto se corrige sin preguntar) y qué es prosa, que no se toca sin permiso.
Hasta que lo hayas leído, trata todo como prosa y pregunta.
Cuando nueva información no encaja en ninguna sección existente, ofrece ambas salidas y deja que el usuario elija: extender una sección, o una nota separada enlazada desde la principal. No decidas tú mismo.
Frontmatter
El esquema pertenece a cada vault y su nota de convenciones lo declara. scan devuelve el frontmatter real de cada nota, que es la otra forma de verlo.
python vault.py frontmatter --vault "<vault>" --note "<ruta>" --set updated=2026-09-13 --dry-run
Solo claves escalares. El script rechaza listas de bloque a propósito: cambiar los temas de una nota es decisión del autor. section --touch-updated ya establece la fecha, así que esto rara vez se necesita por sí solo.
Un campo propiedad de un plugin (una etiqueta, un icono) nunca se toca.
Canvas
Los archivos .canvas son JSON con nodes y edges (JSON Canvas 1.0). La disposición fue hecha a mano, con grupos y conexiones deliberados.
python vault.py canvas --vault "<vault>" --file "<ruta>.canvas" --report
Da nodos, aristas, nombres de grupo, qué notas están enlazadas y si alguna apunta a un archivo que ya no existe.
Y state_outside_its_group, el campo que realmente necesita vigilancia. Un canvas que agrupa notas por su state almacena ese hecho dos veces: en el frontmatter y en la posición y color del nodo. Cambia el state, deja la tarjeta donde estaba, y el canvas no se rompe; todavía apunta a un archivo que existe y todavía muestra el color antiguo. Empieza a mentir sin que nada lo advierta.
Así que cada vez que cambies un state, verifica si ese proyecto o carpeta tiene un canvas que agrupe por estado, y ejecuta el informe. Lo contrario también se aplica: después de crear una nota, verifica que tenga una tarjeta. Una nota que no está en el tablero no existe para quien lee el tablero.
Arreglarlo significa mover el nodo y recolorearlo, que es edición manual: el script informa, no reordena. Dilo y propón el cambio.
python vault.py canvas --file "<ruta>.canvas" --add-file "Ruta/Relativa/Nota.md" --color 6 --dry-run
Los nuevos nodos caen en un espacio debajo de todo lo que existe: nada de lo que ya está se mueve. Colocarlos dentro de un grupo es trabajo manual del usuario, y con razón. Ejecútalo de nuevo sin --dry-run una vez que el usuario acepte.
Si el informe muestra enlaces rotos, dilos y detente. No elimines nodos.
El registro de sesión
Un hook SessionEnd registra los datos brutos de cada sesión de Claude Code en la carpeta de registros que el vault declara (config.logs), un JSON por repositorio: fecha, rama, nuevos commits desde la última vez, archivos tocados y si algo quedó sin commitear. No escribe en ninguna nota.
Esa es la materia prima. Cuando el usuario pida una actualización, scan --project la trae ya leída, en session_log y sessions_since_note_changed. Compara esos commits con lo que dice la nota y propón qué secciones han quedado obsoletas.
Si el hook aún no está instalado, lee references/hook-install.md.
Notas desde una conversación de claude.ai
Los proyectos de claude.ai no están en disco, por lo que no hay script allí. Escribe el markdown completo en un bloque de código, con frontmatter que siga el esquema del vault del usuario (pídelo, o pide una nota existente para copiar, si no lo sabes), y di dónde guardarlo. Si el proyecto ya tiene una nota, di en qué sección pegarlo en lugar de crear un archivo suelto.
Cuando algo falla
pythonno se reconoce: pruebapython3, luegopy. Si ninguno funciona, no hay Python; dilo y ofrece hacer la edición a mano con las herramientas de archivo, que es más lento y más arriesgado.- "No se ha proporcionado un vault": el mapa local no tiene ruta de vault y
OBSIDIAN_VAULTno está establecido. Pregunta al usuario por la ruta y ofrece añadirla al mapa local. - El script se detiene con código de salida 2: es la protección de la última sección haciendo su trabajo. Cambia a
--mode append. - El diff muestra más eliminado de lo esperado: no escribas. Casi siempre
--contentestaba incompleto. - La carpeta del proyecto no existe: pregunta. No crees nuevas carpetas en la zona de proyectos por tu cuenta.
Referencias
references/hook-install.md: instalación del hook de registro de sesiones, en Windows, macOS y Linux.references/mechanics.md: cómo funciona el script y qué garantiza: el archivo de configuración, cómo se encuentra un encabezado, las protecciones, el formato de registro.
Las convenciones de escritura no están aquí. Viven en el vault, en la nota que scan devuelve en config.conventions.