11 de agosto de 2026 # Visual Card Writer: he creado y publicado un plugin de Obsidian sin llegar a ver el código ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-9.webp) Quería comprobar el estado real del *vibe coding* a mediados de 2026. Así que ayer creé un plugin de Obsidian y lo publiqué en el directorio de la comunidad. Se llama Visual Card Writer y sirve para escribir una nota como un árbol de tarjetas en columnas, en vez de un documento largo que baja y baja. Mi primer *vibe coding* serio. No he escrito el código, y tampoco lo he leído. Ni una línea, y no es una manera de hablar: si abro el repositorio ahora mismo, será la primera vez que veo lo que hay dentro. Lo cuento por el recorrido, no tanto por el plugin, que es una primera versión y ya veremos en qué queda - aunque de momento promete. Os lo cuento porque es interesante ver dónde estamos con esto del *vibe coding* en 2026. ## Qué hace Visual Card Writer ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-10.webp) Antes de entrar en el proceso, cuento qué es, que si no lo que viene después no se entiende. Obsidian es una app para leer y escribir ficheros Markdown. Es gratis, muy popular, y extensible mediante plugins y temas hechos por la comunidad. Interesante pieza de software, para mí especialmente por los conceptos de [file-over-app](https://stephango.com/file-over-app) y [local-first software](https://www.inkandswitch.com/essay/local-first/). Mi plugin coge una nota de esas y la enseña como un árbol de tarjetas en columnas, una tarjeta por encabezado. La primera columna son los apartados de primer nivel, la siguiente sus subapartados, y hacia la derecha vas bajando por la rama que te interese. Escribes dentro de las tarjetas, y lo que se guarda sigue siendo la misma nota de siempre. Y esto tiene más interés del que parece. Un texto largo tiene una forma, pero esa forma no se ve: está repartida a lo largo de una tira que hay que subir y bajar para acordarse de qué había dónde. Con el árbol delante se ve de un vistazo. Se nota enseguida qué apartado se ha comido a los demás, cuál sigue teniendo tres líneas después de una semana, y si el orden en que has ido colocando las cosas tiene sentido para quien va a leerlas. En un documento que solo baja, todo eso hay que llevarlo en la memoria. Con navegar pasa lo mismo. En vez de buscar por dónde ibas, seleccionas una tarjeta y trabajas dentro de ella con el resto del documento a la vista alrededor. Puedes meterte en un párrafo muy concreto sin perder de vista dónde encaja, que es justo lo que se pierde cuando haces zoom sobre un trozo de texto. Y la parte que a mí me importaba: **no hay un formato nuevo**. Debajo sigue habiendo tu fichero `.md` de siempre, con sus encabezados normales, sin comentarios raros ni metadatos escondidos. Si desinstalas el plugin mañana, tus notas se quedan exactamente igual. Cada tarjeta edita el trozo del fichero que le toca, y ya está. Lo tenéis aquí por si queréis verlo --> [Visual Card Writer - Obsidian Plugin](https://community.obsidian.md/plugins/visual-card-writer) ## De dónde sale ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-2.webp) Escribo casi a diario, y escribo en Obsidian. Esta web es un vault de Obsidian publicado, así que paso ahí muchas horas. Pero tengo otros vaults para las notas, los ensayos y todo lo demás. Y llevo tiempo con una idea dando vueltas. Cuando preparo algo largo (una newsletter, una ponencia, un guion) no pienso en línea recta. Pienso en trozos que luego coloco. Escribir eso en un documento normal obliga a cortar y pegar párrafos arriba y abajo, y siempre acabo perdiendo el sitio. Hay productos que resuelven eso, como Gingko Writer o Branch Writing, y funcionan bien. Pero están fuera: son otra aplicación, con otro fichero, y mis notas están donde están. Lo que quería era eso mismo dentro de Obsidian y sobre la misma nota Markdown de siempre. Sin formato propio, sin metadatos escondidos, sin una segunda copia del texto. Los encabezados de toda la vida definen el árbol, y ya está: lo único que el plugin escribe por su cuenta es un `#` con el nombre del fichero, y solo si la nota no tiene ninguno, porque sin raíz no hay árbol. ## Mi parte: la especificación ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-3.webp) Aquí está mi parte de verdad, y conviene decir exactamente cuál es: decidir qué tenía que hacer el plugin y cómo debía comportarse. Eso no lo delegué en ningún momento. Antes de que se escribiera nada, le expliqué a Máquina, que es como llamo a mi sistema de agentes, lo que quería. Y juntos fuimos sacando la especificación funcional del producto. Me quedó larga: más de 1.500 líneas. Qué es una tarjeta, cómo se deriva la jerarquía de los encabezados, qué pasa si el usuario mete un encabezado a mano desde fuera y rompe el árbol, qué se hace cuando alguien edita el fichero en otro sitio mientras tú tienes la vista abierta, qué teclas hacen qué, qué ocurre al pegar tres párrafos con sangría, qué pasa cuando llegas a un H6 y ya no hay más niveles de Markdown. Eso no es un prompt, y desde luego no va *por vibras*. Es un documento de producto. El debate sobre *vibe coding* se está moviendo hacia lo que se llama *spec driven development*, donde tú especificas y la IA programa. Pero cuidado, que aquí hay un matiz. Redactar el documento tampoco lo hice yo. Yo explicaba lo que quería, Máquina lo escribía, yo lo leía y le decía qué estaba mal, Máquina corregía. Y así un ratito. Lo mío fue el criterio y la decisión en cada vuelta; la escritura, no. Con lo cual el resultado es una especificación que sirve para ejecutar y que dice exactamente lo que yo quiero, pero que *no he tenido que escribir yo*. ## El código: ¿requiere saber programar? ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-4.webp) Yo he sido desarrollador muchos años. Entiendo cómo funciona el software por dentro. Pero hace años que no programo, no tengo ni idea de los frameworks actuales y tampoco mucha experiencia de cómo se trabaja hoy. Diría que sé lo suficiente para reconocer el trabajo, pero no lo bastante para hacerlo. Entonces, ¿el *vibe coding* a mediados de 2026 pide saber programar? Yo diría que no, pero hay que matizarlo bastante, porque tampoco vale con no tener ni idea. Lo que no hace falta es el conocimiento práctico y profundo, el de quien programa hoy y sabría escribir esto con las manos. Yo no lo tengo, y hace años que no lo tengo. Lo que sí viene muy bien es haber estado cerca del software alguna vez: entender cómo se estructura un desarrollo, entender cómo debe comportarse el programa en los casos raros, que es donde se rompen las cosas, y ser capaz de ver pequeños detalles en los que solo se fija quien ha desarrollado software. Por ejemplo, durante la conversación Máquina me iba haciendo preguntas del tipo: si implementar el editor sobre una `MarkdownView` existente, si crear una vista propia con CodeMirror 6, o si acceder al `view.editor.cm` interno. No tengo ni idea de qué es CodeMirror ni de cómo va la abstracción del `MarkdownView` de Obsidian. Pero como en su día trabajé con arquitectura de aplicaciones, con dos preguntas lo entiendo lo suficiente para decidir. Otro ejemplo: las animaciones al expandir o colapsar los nodos hijos, o la visibilidad degradada de los nodos no seleccionados. Son detalles que todo el mundo nota, pero que solo entiendes bien si has trabajado en interfaz y experiencia de usuario. ## Todo lo que hay alrededor del código ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-5.webp) Y aquí viene lo que me parece que casi nadie se imagina. Escribir el código es una parte pequeña del trabajo. Publicar un plugin de Obsidian de verdad, uno que cualquiera pueda instalar desde el propio programa, exige siete bloques de cosas distintas. Aquí lo tenéis dibujado entero, todos los pasos técnicos. Más abajo os dejo el detalle, por si alguien lo quiere ver, pero básicamente **no he hecho nada de eso**. Lo que hice con las manos fue crear el vault de pruebas, y ni eso habría hecho falta. ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo.webp) Yo iba pidiendo, mirando lo que salía y decidiendo cuando había que elegir. Todo lo demás lo hacía Máquina. > [!example]- El detalle técnico, fase por fase > Esto es para quien desarrolle. Quien no, que se lo salte entero. Son las mismas siete fases del dibujo de arriba, con su nombre técnico. > > **1 · Entorno local** > - Node.js 22.13+, pnpm 11, Git y `gh` CLI autenticado con scopes `repo` y `workflow`. > - TypeScript 5.9 como lenguaje, esbuild 0.25 como bundler, vitest 3.2 como runner de pruebas. > - Vault de Obsidian separado solo para desarrollo. La documentación oficial insiste mucho en esto: un fallo del plugin escribe sobre notas reales. > - Dos rutas distintas: el repo en `Development\visual-card-writer` y el plugin compilado en `<vault-de-pruebas>\.obsidian\plugins\visual-card-writer\` con `main.js`, `manifest.json` y `styles.css`. > > **2 · Esqueleto del repositorio** > - Obligatorios para el directorio: `README.md`, `LICENSE` (MIT) y `manifest.json`. > - `manifest.json`: `id` único que no puede contener la cadena `obsidian`, `version` en semver `x.y.z`, `minAppVersion` (aquí `1.12.2`) e `isDesktopOnly: true`, que es como se declara que el plugin es solo de escritorio. > - `versions.json` mapea versión de plugin → `minAppVersion`, para que Obsidian sirva la release correcta a cada usuario. > - Resto: `package.json`, `tsconfig.json`, `esbuild.config.mjs`, `pnpm-workspace.yaml`, `CHANGELOG.md`, `CONTRIBUTING.md`, `.gitignore`. > - `main.js` va ignorado por Git. Se distribuye solo como asset de release, nunca en el historial. > > **3 · Bucle de desarrollo** > - `src/` en siete módulos: `plugin.ts` (registro de vista y comandos), `view.ts` (interfaz, edición, layout), `parser.ts` (Markdown ↔ árbol), `operations.ts` (insertar tarjetas), `layout.ts` (posiciones y columnas), `session.ts` (sesión compartida de documento), `live-preview.ts` (extensiones de CodeMirror). > - `corepack pnpm run dev` deja esbuild en watch; cada guardado regenera `main.js`. > - Copiar los tres artefactos al vault de pruebas y recargar el plugin. Con Hot-Reload se automatiza. > - Depuración sobre la vista `visual-card-writer-view` con el CLI de Obsidian. > - Se repite decenas de veces por sesión. > > **4 · Verificación** > - `corepack pnpm run check` = `vitest run` + `tsc --noEmit` + build de producción minificado. > - 49 pruebas unitarias, sobre todo del parser y del cálculo de layout. > - `corepack pnpm audit --prod` para dependencias vulnerables. > - `corepack pnpm run release:check -- <versión>` valida que `package.json`, `manifest.json`, `versions.json` y `CHANGELOG.md` digan lo mismo. Script propio en `scripts/validate-release.mjs`. > - Detalle que cuesta caro si se ignora: `@codemirror/state` y `@codemirror/view` van fijados a versión exacta, con overrides en `pnpm-workspace.yaml`. Obsidian ya trae su propia copia de CodeMirror 6 y una segunda copia en el bundle rompe la vista en tiempo de ejecución sin dar error de compilación. > > **5 · Git y CI** > - Rama por cambio desde `main`, commits, PR, merge. Cinco PR en total. > - `.github/workflows/ci.yml` corre en cada push a `main` y en cada PR: checkout, pnpm, Node 24 (más nuevo que el mínimo local, a propósito, para que la CI sea el entorno exigente), `pnpm install --frozen-lockfile` y `pnpm run check` sobre un runner limpio de Ubuntu. > > **6 · Release** > - Etiqueta anotada con el número exacto y sin prefijo `v`: `git tag -a 0.1.5 origin/main -m "0.1.5"` y `git push origin refs/tags/0.1.5`. Obsidian exige coincidencia literal con `manifest.json`. > - Eso dispara `.github/workflows/release.yml` con permisos `contents: write`, `id-token: write` y `attestations: write`: instala, pasa `pnpm run check`, valida metadatos, genera atestaciones de procedencia con `actions/attest@v4` para `main.js`, `manifest.json` y `styles.css`, y crea la release en borrador con `gh release create --draft` adjuntando los tres ficheros. > - Publicación manual del borrador tras revisar los assets. > > **7 · Directorio de Obsidian Community** > - Alta en community.obsidian.md con la cuenta de Obsidian vinculada a GitHub por OAuth de solo lectura, para verificar la propiedad del repo. > - El directorio lee el `manifest.json` del HEAD de la rama por defecto y descarga los assets de la release cuya etiqueta coincide con `version`. > - Revisión automática: atestación verificable de `main.js` y `styles.css`, patrones de red, dependencias vulnerables y **reproducción del build byte a byte** contra el `main.js` publicado. > - Los dos hallazgos que tumbaron la `0.1.1`: un error, `onunload()` llamaba a `detachLeavesOfType()`, que resetea la posición de una vista que el usuario haya movido; y un aviso, `styles.css` usaba `text-decoration-thickness`, marcada como soporte parcial. Corregidos en `0.1.2`. > - Revisión humana aparte, más lenta, y sin bloquear la instalación. > - Las versiones siguientes no se reenvían: Obsidian relee `manifest.json` y `versions.json` del repo y se descarga sola cada release nueva. ## La revisión de Obsidian ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-6.webp) Este es el punto donde me quedé mirando la pantalla. Cuando envías el plugin al directorio, Obsidian pasa una revisión automática. Comprueba que los ficheros llevan una firma verificable de procedencia, que no hay patrones de red sospechosos, que el código fuente no hace nada raro y que la hoja de estilos no usa cosas a medio soportar. Y hace además algo bastante bonito, que aquí no se ve porque va por dentro: recompila tu código por su cuenta y comprueba que el resultado coincide byte a byte con el fichero que has publicado. Es su manera de asegurarse de que lo que se descarga la gente sale de verdad del código que ellos han podido leer. La primera versión que envié, la 0.1.1, no pasó. Un error y un aviso. ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-1.webp) Yo esas dos cosas no las habría encontrado. Ni sabría lo que significan sin buscarlas. Pero no ha hecho falta: Máquina se ha quedado esperando, mirando la página de Obsidian Community, ha visto los dos hallazgos, los ha corregido, ha subido una versión nueva, ha comprobado que estaba todo bien y me ha contado el resultado final. Y ese es un poco el punto. La IA escribe código desde hace tiempo, eso ya no sorprende a nadie. Lo que ha cambiado es que ahora se ocupa de todo lo de alrededor, que es lo que separaba a alguien que hace un experimento en su ordenador de alguien que publica algo que otros instalan. El trámite, la herramienta, el estándar del sitio donde publicas, el fallo que te devuelve el revisor. Antes eso era una barrera de conocimiento y de horas o días. Todo esto ha salido en aproximadamente un día. Los números, para que veáis el volumen: - 6 versiones publicadas, de la 0.1.0 a la 0.1.5. - 28 commits y 5 pull requests. - 49 pruebas automáticas, ejecutadas y pasadas en cada cambio y en cada compilación. - 3.825 líneas entre el TypeScript del plugin, las pruebas y el CSS. Otras 288 en herramientas, workflows y metadatos, y 181 más de documentación. - Un total de 33 ficheros. ## Las pegas ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-7.webp) Todo esto tiene pegas. Primero, un plugin de Obsidian no es un software completo. No hay que gestionar almacenamiento, ni seguridad, ni escalabilidad, ni rendimiento (bueno, rendimiento sí, pero muy simple). Segundo, no he leído el código, y eso significa que no puedo responder por él. Puedo decir que las pruebas pasan, que la revisión automática de Obsidian lo ha dado por bueno y que a mí me funciona. No puedo decir que esté bien hecho, porque no lo sé. Y en cuanto alguien abra una incidencia rara, dependo enteramente de que la IA sepa arreglarla, porque yo no voy a poder abrir el fichero y entenderlo en diez minutos. Aquí es donde encaja lo que escribí hace unas semanas sobre [[94-no-delegues-el-entendimiento-a-la-IA|no delegar el entendimiento]]. Porque yo he delegado el entendimiento del código, que es justo lo que decía que no había que hacer. Me parece asumible, y he intentado poner por escrito por qué, para no engañarme. Lo delego cuando se cumplen cuatro cosas a la vez: no vivo de ello, no hay datos de nadie dentro, el fallo peor que se me ocurre es reversible, y alguien de fuera me lo verifica antes de que llegue a nadie. Ese último punto es el que más pesa y el que casi nunca se nombra: aquí la revisión de Obsidian hace de segundo par de ojos, y sin ella no habría publicado. Un plugin gratuito, sin red, sin cuentas, con la beta declarada en su propia página y con la recomendación de hacer copia de seguridad, cumple las cuatro. Y sé qué tendría que cambiar para que dejara de cumplirlas. Que empezara a guardar datos de otras personas. Que alguien lo metiera en un trabajo del que depende. O que yo empezara a cobrar por él, que es el momento en que dejas de ser un aficionado que comparte algo y pasas a responder por ello. Con cualquiera de las tres, o me leo el código o no lo publico. Con software de una empresa, con datos de clientes dentro, esta misma decisión me parecería una barbaridad. ## Dónde queda la profesión de desarrollador ![](./attachments/95-plugin-obsidian-sin-ver-el-codigo-8.webp) Empiezo por lo que a mí me parece que sigue siendo humano, y es lo más pequeño y lo más difícil de sustituir. Lo único que no habría salido sin mí no es el código, ni la especificación: es saber qué quería. Y eso no lo sé porque haya sido desarrollador, lo sé porque llevo años escribiendo y tengo muy medido cómo quiero escribir. El plugin lo he podido pedir porque el usuario soy yo. Lo demás se ha movido, y bastante. Que la IA escriba código ya no era noticia. Que lleve el proyecto entero de punta a punta (el entorno, el repositorio, las pruebas, las versiones, los trámites de publicación) durante horas seguidas y sin que haya que estar encima cada pocos minutos, eso sí es nuevo de este año. Y va con lo otro que ha cambiado: ejecuta pruebas, lee lo que falla, entiende el error y se mete en el bucle de corregirse a sí misma. A fuerza de tokens y reintentos, los fallos se acaban arreglando. Con lo cual el título de esta sección promete un sitio para la profesión de desarrollador, y el sitio va quedando pequeño. Yo creo que a la parte de saber qué construir le queda menos de lo que nos gustaría. Lo digo por algo concreto de este proyecto: la especificación tampoco la escribí yo, la fui corrigiendo. Y en cada vuelta corregía menos. ## Bonus > [!tip]+ Más en esta web > - [[88-El-formato-del-futuro-es-texto-plano|Open Knowledge Format: el formato del futuro para guardar tu conocimiento]] - De aquí sale el principio que está detrás de todo el plugin: *file-over-app*, tus ficheros por encima de la aplicación que los abre. > - [[Eco-Open-Knowledge-Format|El wiki-LLM de Karpathy convertido en estándar corporativo]] - El OKF al detalle: una carpeta de ficheros Markdown con frontmatter, sin SDK y sin plataforma. > - [[28-llm-wiki-karpathy-factura-tokens|El wiki con IA de Karpathy: barato de consultar, caro de mantener]] - La otra cara del texto plano: guardar así es sencillo, mantenerlo al día con IA tiene factura. > - [[89-Vibe-coding-la-otra-cara|Vibe coding frente al SaaS: la otra cara del conflicto]] - Por qué el software de un solo usuario se puede construir uno mismo, y qué SaaS se lleva eso por delante. > - [[76-Vibe-coding-tsunami-de-software-malo|Vibe coding y la próxima oleada de software malo]] - El contrapeso: todo lo que sale mal cuando esto se hace sin criterio. > - [[94-no-delegues-el-entendimiento-a-la-IA|No delegues el entendimiento a la IA]] - Hasta dónde se puede delegar y qué conviene seguir entendiendo para responder por el resultado. > [!tip]+ Los enlaces de este artículo > - [Visual Card Writer en Obsidian Community](https://community.obsidian.md/plugins/visual-card-writer) - La ficha del plugin, por si quieres instalarlo y probarlo. > - [El repositorio en GitHub](https://github.com/DavidHurtadoAI/visual-card-writer) - El código, las versiones y el historial completo del proceso. > - [File over app](https://stephango.com/file-over-app) · Steph Ango - Lo escribe el CEO de Obsidian, y es la razón por la que el plugin no inventa un formato propio: tus ficheros tienen que sobrevivir a la aplicación que los abre. > - [Local-first software](https://www.inkandswitch.com/essay/local-first/) · Ink & Switch - El ensayo de referencia sobre trabajar contra tus propios ficheros y sincronizar después, no al revés. > - [Build a plugin](https://docs.obsidian.md/Plugins/Getting+started/Build+a+plugin) · Obsidian - La guía oficial, incluido el aviso de no desarrollar nunca sobre tu vault real. > - [Submit your plugin](https://docs.obsidian.md/Plugins/Releasing/Submit+your+plugin) · Obsidian - Los requisitos para entrar en el directorio y el proceso de revisión. > - [Plugin guidelines](https://docs.obsidian.md/Plugins/Releasing/Plugin+guidelines) · Obsidian - La lista de errores típicos que devuelve el revisor. De aquí salen los dos que me tumbaron la 0.1.1. --- Publicado el 11 de agosto de 2026, [LinkedIn](https://www.linkedin.com/pulse/visual-card-writer-he-creado-y-publicado-un-plugin-de-hurtado-tor%25C3%25A1n-qv7je), [Substack](https://davidhurtado.substack.com/p/visual-card-writer-he-creado-y-publicado?r=4uyjfg&utm_campaign=post&utm_medium=web&showWelcomeOnShare=true), [X](https://x.com/dhtoran/status/2087066964950696157?s=20)