011ccfb8cd
Plugin fino (id osint-db) que habla HTTP con el service local osint_db (FastAPI + DuckDB) y renderiza tablas de datos en las notas del vault osint mediante el code block osintdb. Incluye parser puro de directivas con tests (node --test), settings tab, comando de paleta, enlaces internos para columnas note_path, build con esbuild + tsc y deploy.sh al vault. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
121 lines
4.9 KiB
Markdown
121 lines
4.9 KiB
Markdown
---
|
|
name: osint_obsidian_plugin
|
|
lang: ts
|
|
domain: osint
|
|
version: 0.1.0
|
|
description: "Plugin de Obsidian (id osint-db) para el vault osint: ejecuta queries SQL y queries nombradas contra el service local osint_db (FastAPI + DuckDB) via HTTP y renderiza tablas de datos dentro de las notas mediante el code block osintdb. Plugin fino: no embebe ninguna base de datos."
|
|
tags: [osint, obsidian, plugin, duckdb]
|
|
uses_functions: []
|
|
uses_types: []
|
|
framework: "obsidian-plugin"
|
|
entry_point: "main.ts"
|
|
dir_path: "projects/osint/apps/osint_obsidian_plugin"
|
|
repo_url: "https://gitea-dgg044oo04woo4ggcsws4gk0.organic-machine.com/dataforge/osint_obsidian_plugin"
|
|
e2e_checks:
|
|
- id: build
|
|
cmd: "pnpm install --frozen-lockfile=false && pnpm build"
|
|
timeout_s: 300
|
|
- id: artifact
|
|
cmd: "test -f main.js"
|
|
- id: tests
|
|
cmd: "pnpm test"
|
|
timeout_s: 60
|
|
---
|
|
|
|
# osint_obsidian_plugin
|
|
|
|
Plugin de Obsidian para el vault `~/Obsidian/osint`. Es deliberadamente fino: no embebe
|
|
DuckDB ni ninguna otra base de datos. Toda la lógica de datos vive en el service local
|
|
`osint_db` (FastAPI, dueño de la DuckDB con datos OSINT), con el que el plugin habla por
|
|
HTTP usando `requestUrl` de la API de Obsidian (evita CORS; nunca `fetch`).
|
|
|
|
## Qué hace
|
|
|
|
1. **Code block `osintdb`**: dentro de cualquier nota, un bloque de código con lenguaje
|
|
`osintdb` se renderiza como una tabla de datos. Dos formas de contenido:
|
|
- SQL crudo (el bloque entero es un SELECT, va a `POST /api/query`).
|
|
- Directivas `clave: valor` al inicio del bloque: `query` (nombre de query guardada,
|
|
va a `POST /api/query/named`), `max_rows` y `title`.
|
|
2. **Render seguro**: tabla HTML construida con `createEl` (los valores se insertan como
|
|
texto, nunca como HTML crudo), header sticky, conteo de filas y nota "(truncado)"
|
|
cuando el service recorta el resultado. Errores del service y service caído se
|
|
muestran con mensajes claros, incluido el comando para arrancar `osint_db`.
|
|
3. **Botón "Refrescar"** por bloque: re-ejecuta la query sin recargar la nota.
|
|
4. **Enlaces a notas**: si una columna se llama `note_path` y el valor termina en `.md`,
|
|
la celda se renderiza como enlace interno de Obsidian que abre la nota al hacer clic.
|
|
5. **Settings tab**: URL base del service (default `http://127.0.0.1:8771`) y `max_rows`
|
|
por defecto (500), persistidos con `loadData`/`saveData`.
|
|
6. **Comando de paleta** "OSINT DB: Insertar bloque de query": inserta una plantilla de
|
|
bloque `osintdb` en el editor.
|
|
|
|
## Ejemplo de bloque
|
|
|
|
Forma con SQL crudo:
|
|
|
|
```osintdb
|
|
title: Personas del caso X
|
|
max_rows: 100
|
|
SELECT nombre, contexto, note_path FROM main.personas WHERE contexto = 'caso_x';
|
|
```
|
|
|
|
Forma con query nombrada (definida en el service):
|
|
|
|
```osintdb
|
|
query: personas_por_contexto
|
|
max_rows: 100
|
|
```
|
|
|
|
## Contrato API del service osint_db
|
|
|
|
Base URL por defecto: `http://127.0.0.1:8771`. El service responde siempre HTTP 200 y el
|
|
plugin decide por el campo `status` del body.
|
|
|
|
- `GET /api/health` → `{"status":"ok","db_path":"...","tables":N}`
|
|
- `GET /api/tables` → listado de tablas con schema, kind, row_count y columnas.
|
|
- `POST /api/query` body `{"sql":"SELECT ...","params":[],"max_rows":500}` →
|
|
`{"status":"ok","columns":[...],"rows":[...],"row_count":N,"truncated":bool}` o
|
|
`{"status":"error","error":"..."}`.
|
|
- `GET /api/queries` → queries nombradas disponibles.
|
|
- `POST /api/query/named` body `{"name":"...","max_rows":500}` → misma shape que `/api/query`.
|
|
|
|
## Cómo construir
|
|
|
|
```bash
|
|
cd projects/osint/apps/osint_obsidian_plugin
|
|
pnpm install
|
|
pnpm build # tsc --noEmit + esbuild -> main.js
|
|
pnpm test # tests del parser de bloques (node --test, sin Obsidian)
|
|
```
|
|
|
|
Requiere Node >= 23 para los tests (usa el type stripping nativo de `node --test` sobre
|
|
archivos `.ts`).
|
|
|
|
## Cómo desplegar
|
|
|
|
```bash
|
|
./deploy.sh
|
|
```
|
|
|
|
Copia `manifest.json`, `main.js` y `styles.css` a
|
|
`/home/enmanuel/Obsidian/osint/.obsidian/plugins/osint-db/`.
|
|
|
|
**Activación manual (la hace el humano, no un agente):** tras el deploy, abrir Obsidian →
|
|
Settings → Community plugins → activar "OSINT DB". Si Obsidian ya estaba abierto, hace
|
|
falta recargar la app (Ctrl+R) o reiniciarla para que detecte el plugin nuevo o la
|
|
versión nueva de `main.js`.
|
|
|
|
## Estructura
|
|
|
|
- `main.ts` — plugin completo (processor, render, settings, comando).
|
|
- `parse.ts` — parser puro del contenido de los bloques `osintdb` (testeable sin Obsidian).
|
|
- `tests/parse.test.ts` — tests del parser con `node --test`.
|
|
- `esbuild.config.mjs` — bundle CommonJS a `main.js` con `obsidian` como external.
|
|
- `deploy.sh` — copia los artefactos al vault.
|
|
|
|
## Gotchas
|
|
|
|
- El plugin no arranca el service: si `osint_db` no está corriendo, los bloques muestran
|
|
"osint_db no responde en <url>" con el comando de arranque como hint.
|
|
- `main.js` es artefacto de build (gitignored): siempre `pnpm build` antes de `deploy.sh`.
|
|
- `isDesktopOnly: true` en el manifest — el service es local, no tiene sentido en móvil.
|