openprompt-lang 1.2.7 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/README.md +62 -8
  2. package/bin/cli.js +2 -0
  3. package/docs/00-ARCHITECTURE/OPL-BOOST-MULTI-AGENT.md +406 -0
  4. package/docs/02-STANDARDS/AGENTS.template.md +89 -0
  5. package/docs/02-STANDARDS/ticket-driven-development.md +99 -0
  6. package/docs/04-TICKETS/BOOST-001-profile-registry.md +66 -0
  7. package/docs/04-TICKETS/BOOST-002-context-compression.md +58 -0
  8. package/docs/04-TICKETS/BOOST-003-template-hydration.md +69 -0
  9. package/docs/04-TICKETS/BOOST-004-fewshot-engine.md +58 -0
  10. package/docs/04-TICKETS/BOOST-005-agent-pool.md +69 -0
  11. package/docs/04-TICKETS/BOOST-006-specialized-agents.md +53 -0
  12. package/docs/04-TICKETS/BOOST-007-validation-loop.md +56 -0
  13. package/docs/04-TICKETS/BOOST-008-orchestrator.md +71 -0
  14. package/docs/04-TICKETS/BOOST-009-cache-system.md +56 -0
  15. package/docs/04-TICKETS/BOOST-010-cli-mcp.md +67 -0
  16. package/docs/04-TICKETS/BOOST-011-self-learning.md +50 -0
  17. package/docs/04-TICKETS/BOOST-012-prompt-preamble.md +109 -0
  18. package/docs/04-TICKETS/BOOST-013-hydrator-duplicate-code.md +132 -0
  19. package/docs/04-TICKETS/BOOST-014-multiagent-missing-parts.md +87 -0
  20. package/docs/04-TICKETS/BOOST-015-skeleton-type-missing.md +76 -0
  21. package/docs/04-TICKETS/BOOST-016-output-path-duplicate.md +68 -0
  22. package/docs/04-TICKETS/INDEX.md +89 -0
  23. package/docs/04-TICKETS/_archive/BOOST-005-micro-tasking.md +67 -0
  24. package/docs/04-TICKETS/_archive/BOOST-006-validation-loop.md +66 -0
  25. package/docs/04-TICKETS/_archive/BOOST-007-progressive-pipeline.md +69 -0
  26. package/docs/04-TICKETS/_archive/BOOST-008-cli-mcp-integration.md +74 -0
  27. package/docs/AI_CONTEXT.md +16 -0
  28. package/docs/EMBEDDINGS.md +214 -0
  29. package/docs/ONBOARDING_WORKFLOW.md +151 -0
  30. package/docs/OPL_ACADEMIC_ISSUES.md +158 -0
  31. package/docs/WEB_SCRAPER_PLAN.md +454 -0
  32. package/package.json +9 -2
  33. package/scripts/postinstall.js +37 -0
  34. package/src/boost/agent-pool.js +442 -0
  35. package/src/boost/agents/index.js +79 -0
  36. package/src/boost/cache.js +241 -0
  37. package/src/boost/context-compressor.js +354 -0
  38. package/src/boost/fewshot-retriever.js +332 -0
  39. package/src/boost/hardware-detector.js +486 -0
  40. package/src/boost/hydrator.js +398 -0
  41. package/src/boost/index.js +60 -0
  42. package/src/boost/orchestrator.js +615 -0
  43. package/src/boost/preamble.js +217 -0
  44. package/src/boost/profile-registry.js +264 -0
  45. package/src/boost/self-learn.js +247 -0
  46. package/src/boost/skeletons/component.skeleton.js +24 -0
  47. package/src/boost/skeletons/hook.skeleton.js +27 -0
  48. package/src/boost/skeletons/index.js +67 -0
  49. package/src/boost/skeletons/page.skeleton.js +22 -0
  50. package/src/boost/skeletons/service.skeleton.js +20 -0
  51. package/src/boost/skeletons/store.skeleton.js +18 -0
  52. package/src/boost/skeletons/type.skeleton.js +11 -0
  53. package/src/boost/task-dispatcher.js +142 -0
  54. package/src/boost/validation-loop.js +495 -0
  55. package/src/cli/commands-boost.js +394 -0
  56. package/src/cli/commands-knowledge.js +1 -0
  57. package/src/cli/commands-opl.js +79 -1
  58. package/src/cli/commands-workflow.js +125 -6
  59. package/src/commands/init-core.js +169 -5
  60. package/src/commands/knowledge-ops.js +52 -0
  61. package/src/commands/opl-embeddings.js +556 -0
  62. package/src/commands/opl-help.js +26 -2
  63. package/src/commands/opl-search.js +106 -2
  64. package/src/commands/opl-webscrape.js +390 -0
  65. package/src/commands/workflow/epic-cli.js +192 -0
  66. package/src/commands/workflow/select.js +146 -0
  67. package/src/commands/workflow/sprint-cli.js +174 -0
  68. package/src/core/webscrape/analyzer.js +481 -0
  69. package/src/core/webscrape/deep-scraper.js +1027 -0
  70. package/src/core/workflow/epic-manager.js +845 -0
  71. package/src/core/workflow/gates.js +180 -1
  72. package/src/core/workflow/selector.js +707 -0
  73. package/src/embeddings/chunker.js +450 -0
  74. package/src/embeddings/embedder.js +431 -0
  75. package/src/embeddings/index-pipeline.js +320 -0
  76. package/src/embeddings/vector-store.js +505 -0
  77. package/src/mcp-refactor/handlers/boost.js +295 -0
  78. package/src/mcp-refactor/router.js +19 -0
  79. package/src/mcp-refactor/tools.js +113 -0
@@ -0,0 +1,158 @@
1
+ # 🎓 OPL Academic — Bitácora de Problemas
2
+
3
+ > Documento para registrar problemas, fricciones y errores detectados en el sistema de enseñanza (Teaching System) de openPrompt-Lang.
4
+ > Cada entrada documenta: síntoma, causa raíz, impacto, solución propuesta y estado.
5
+
6
+ ---
7
+
8
+ ## 📋 Índice de Problemas
9
+
10
+ | # | Fecha | Título | Severidad | Estado |
11
+ |---|-------|--------|-----------|--------|
12
+ | 1 | 2026-05-24 | Onboarding IA en proyecto existente | 🔴 Alta | Abierto |
13
+ | 2 | 2026-05-24 | `opl rebuild` no detecta OPL automáticamente | 🟡 Media | Abierto |
14
+ | 3 | 2026-05-24 | Falta documento post-init para IA | 🔴 Alta | Abierto |
15
+
16
+ ---
17
+
18
+ ## 🐛 Problemas Reportados
19
+
20
+ ### P-001: Onboarding IA en proyecto existente
21
+
22
+ | Campo | Valor |
23
+ |-------|-------|
24
+ | **Fecha** | 2026-05-24 |
25
+ | **Reportado por** | usuario |
26
+ | **Severidad** | 🔴 Alta |
27
+ | **Módulo** | Academic — Init / Onboarding |
28
+ | **Estado** | 🔴 Abierto |
29
+
30
+ **Síntoma:**
31
+ Al iniciar una sesión con IA en un proyecto existente que ya tiene elementos de OPL, la IA no sabe qué hacer. No hay un punto de entrada claro que le diga "esto ya tiene OPL, aquí está el estado actual, continúa desde aquí".
32
+
33
+ **Causa raíz:**
34
+ No existe un documento de onboarding generado automáticamente que la IA pueda leer al inicio de cada sesión para restaurar contexto.
35
+
36
+ **Impacto:**
37
+ - La IA pierde ~15 minutos regenerando contexto cada sesión
38
+ - Toma decisiones inconsistentes porque no conoce el estado real del proyecto
39
+ - El usuario tiene que re-explicar manualmente lo que ya se hizo
40
+
41
+ **Solución propuesta:**
42
+ - Crear `docs/ONBOARDING_WORKFLOW.md` — documento canónico que la IA lee al iniciar
43
+ - Integrar `opl init` para que genere este documento automáticamente
44
+ - Dos versiones: `INICIAR_NUEVO.md` (proyecto nuevo) e `INICIAR_EXISTENTE.md` (proyecto en curso)
45
+
46
+ **Referencias:**
47
+ - `erroresDeFlujo.md` (línea 2)
48
+ - Sprint embeddings → TICKET-011 (propuesto)
49
+
50
+ ---
51
+
52
+ ### P-002: `opl rebuild` no detecta OPL automáticamente
53
+
54
+ | Campo | Valor |
55
+ |-------|-------|
56
+ | **Fecha** | 2026-05-24 |
57
+ | **Reportado por** | usuario |
58
+ | **Severidad** | 🟡 Media |
59
+ | **Módulo** | CLI — rebuild |
60
+ | **Estado** | 🟡 Abierto |
61
+
62
+ **Síntoma:**
63
+ `opl rebuild` falla o funciona incorrectamente cuando los elementos de OPL no están presentes o no son detectables automáticamente.
64
+
65
+ **Causa raíz:**
66
+ El comando `rebuild` asume cierta estructura pre-existente en lugar de ser autosuficiente.
67
+
68
+ **Solución propuesta:**
69
+ Hacer que `rebuild` funciones en dos modos:
70
+ 1. **Con detección**: Si encuentra elementos OPL, los respeta y reconstruye
71
+ 2. **Sin detección**: Si no encuentra nada, crea la estructura desde cero con defaults inteligentes
72
+
73
+ **Referencias:**
74
+ - `erroresDeFlujo.md` (línea 4)
75
+
76
+ ---
77
+
78
+ ### P-003: Falta documento post-init para IA
79
+
80
+ | Campo | Valor |
81
+ |-------|-------|
82
+ | **Fecha** | 2026-05-24 |
83
+ | **Reportado por** | usuario |
84
+ | **Severidad** | 🔴 Alta |
85
+ | **Módulo** | CLI — init |
86
+ | **Estado** | 🔴 Abierto |
87
+
88
+ **Síntoma:**
89
+ Después de ejecutar `opl init`, no se genera ningún documento que la IA pueda usar para entender el contexto del proyecto. La IA llega "en frío" a cada sesión.
90
+
91
+ **Causa raíz:**
92
+ `opl init` configura el proyecto (crea prompt-lang.json, AGENTS.md, etc.) pero no genera un punto de entrada específico para la IA que le diga "esto es lo que hay, esto es lo que falta, continúa".
93
+
94
+ **Solución propuesta:**
95
+ Que `opl init` genere automáticamente:
96
+ - `INICIAR_NUEVO.md` si es proyecto nuevo
97
+ - `INICIAR_EXISTENTE.md` si es proyecto existente con OPL
98
+
99
+ Estos documentos deben incluir:
100
+ - Stack detectado
101
+ - Estado de la configuración OPL
102
+ - Próximos pasos recomendados
103
+ - Enlace a `AGENTS.md` y `docs/AI_CONTEXT.md`
104
+
105
+ **Referencias:**
106
+ - `erroresDeFlujo.md` (línea 6)
107
+ - `docs/ONBOARDING_WORKFLOW.md`
108
+
109
+ ---
110
+
111
+ ## 📊 Estadísticas
112
+
113
+ | Métrica | Valor |
114
+ |---------|-------|
115
+ | Total problemas | 3 |
116
+ | Severidad Alta | 2 |
117
+ | Severidad Media | 1 |
118
+ | Severidad Baja | 0 |
119
+ | Abiertos | 3 |
120
+ | En Progreso | 0 |
121
+ | Resueltos | 0 |
122
+
123
+ ---
124
+
125
+ ## 📝 Cómo Reportar un Problema Nuevo
126
+
127
+ Usa esta plantilla al añadir una nueva entrada:
128
+
129
+ ```markdown
130
+ ### P-XXX: Título descriptivo
131
+
132
+ | Campo | Valor |
133
+ |-------|-------|
134
+ | **Fecha** | YYYY-MM-DD |
135
+ | **Reportado por** | — |
136
+ | **Severidad** | 🔴 Alta / 🟡 Media / 🟢 Baja |
137
+ | **Módulo** | — |
138
+ | **Estado** | 🔴 Abierto |
139
+
140
+ **Síntoma:**
141
+ _¿Qué ocurre exactamente?_
142
+
143
+ **Causa raíz:**
144
+ _¿Por qué ocurre?_
145
+
146
+ **Impacto:**
147
+ _¿A quién afecta y cómo?_
148
+
149
+ **Solución propuesta:**
150
+ _¿Cómo se arreglaría?_
151
+
152
+ **Referencias:**
153
+ - _enlaces a código, docs, commits_
154
+ ```
155
+
156
+ ---
157
+
158
+ *Última actualización: 2026-05-24*
@@ -0,0 +1,454 @@
1
+ # Web Scraper Evolution — Plan Ollama-Driven
2
+
3
+ > **Versión:** 2.0 (revisado)
4
+ > **Objetivo:** Reemplazar `opl webscrape` (Readability.js + Turndown) por un extractor
5
+ > **inteligente asistido por Ollama** que analiza la estructura de cada página y genera
6
+ > un plan de extracción personalizado.
7
+ >
8
+ > **Stack:** 100% Node.js + Ollama (local) → Sin dependencia de Python.
9
+ > **Principio:** Cada página es única → cada página merece un plan de extracción único.
10
+
11
+ ---
12
+
13
+ ## 1. Filosofía: Por qué IA en vez de Reglas Fijas
14
+
15
+ ### Enfoque tradicional (hardcoded)
16
+ ```python
17
+ # Reglas fijas que fallan en el 50% de las páginas
18
+ extract_og_tags(html)
19
+ extract_metadata(html)
20
+ extract_articles(html)
21
+ extract_tables(html)
22
+ ```
23
+ ❌ Cada sitio tiene markup distinto → reglas imposibles de mantener
24
+ ❌ No entiende el **significado** de las secciones
25
+ ❌ No distingue contenido principal de navegación/publicidad
26
+ ❌ Cada nuevo tipo de página requiere más reglas
27
+
28
+ ### Enfoque Ollama-driven
29
+ ```
30
+ fetch(url) → HTML + layout estructurado
31
+
32
+ 🧠 Ollama analiza: "¿qué hay aquí?"
33
+
34
+ ← plan de extracción JSON ←
35
+
36
+ Ejecuta el plan (selectores dinámicos)
37
+
38
+ knowledge/<domain>/<slug>/
39
+ ```
40
+ ✅ Se adapta a cualquier página
41
+ ✅ Entiende semántica del contenido
42
+ ✅ Decide QUÉ extraer según el tipo de página
43
+ ✅ Sin reglas hardcodeadas — el LLM decide
44
+
45
+ ---
46
+
47
+ ## 2. Arquitectura General
48
+
49
+ ```
50
+ ┌──────────────────────────────────────────────────────────────────┐
51
+ │ Input │
52
+ │ url → fetchPage(url) │
53
+ │ ├── simple: node-fetch (rápido, HTML estático) │
54
+ │ └── headless: @playwright (SPA, JS-heavy, lazy-load) │
55
+ │ │
56
+ │ Resultado: PageSnapshot { html, text, links, meta, ...} │
57
+ └──────────────────┬───────────────────────────────────────────────┘
58
+
59
+ ┌──────────────────┴───────────────────────────────────────────────┐
60
+ │ PASO 1: 🧠 Escaneo con Ollama (analyzePage) │
61
+ │ │
62
+ │ Envía a Ollama: │
63
+ │ - Título de la página │
64
+ │ - Meta tags básicos │
65
+ │ - HTML estructural resumido (árbol de secciones, no el HTML │
66
+ │ completo — eso sería demasiado tokens) │
67
+ │ - Texto visible (primeros ~2000 chars) │
68
+ │ - Cantidad y tipos de elementos (cuántos <article>, <section>, │
69
+ │ <table>, <img>, <form>, cards, listas, etc.) │
70
+ │ │
71
+ │ Ollama responde: │
72
+ │ { │
73
+ │ pageType: "article" | "product" | "docs" | "blog" | │
74
+ │ "catalog" | "landing" | "profile" | "generic", │
75
+ │ title: "Título detectado", │
76
+ │ description: "Descripción detectada", │
77
+ │ contentBlocks: [ │
78
+ │ { │
79
+ │ type: "main-content" | "sidebar" | "nav" | "footer" | │
80
+ │ "cards" | "table" | "form" | "gallery", │
81
+ │ selector: "main article", ← selector CSS sugerido │
82
+ │ importance: 1-10, ← qué tan importante │
83
+ │ extractMode: "markdown" | "json" | "table" | "cards", │
84
+ │ description: "El artículo principal con su contenido" │
85
+ │ } │
86
+ │ ], │
87
+ │ metadata: { │
88
+ │ og: true, twitter: true, jsonld: true, microdata: false │
89
+ │ }, │
90
+ │ specialFeatures: ["scroll-infinity", "load-more", │
91
+ │ "pagination", "tabs", "accordion"], │
92
+ │ extractionPlan: { │
93
+ │ steps: ["extract-main-content", "extract-og", │
94
+ │ "extract-images", "extract-tables"], │
95
+ │ outputFormat: "markdown+json" │
96
+ │ } │
97
+ │ } │
98
+ └──────────────────┬───────────────────────────────────────────────┘
99
+
100
+ ┌──────────────────┴───────────────────────────────────────────────┐
101
+ │ PASO 2: Ejecutar el plan (executePlan) │
102
+ │ │
103
+ │ Según el plan de Ollama, ejecuta SOLO los extractores │
104
+ │ necesarios para esta página: │
105
+ │ │
106
+ │ ├── main-content: Readability.js + limpieza │
107
+ │ ├── og/twitter/jsonld: extractores específicos (jsdom) │
108
+ │ ├── images: src, alt, caption, dimensiones │
109
+ │ ├── tables: caption + headers + rows (markdown/JSON) │
110
+ │ ├── cards: tarjetas de producto/artículo/post │
111
+ │ ├── forms: action, method, inputs │
112
+ │ └── special: auto-scroll, load-more, pagination │
113
+ │ │
114
+ │ Resultado: ExtractedPage { ... } │
115
+ └──────────────────┬───────────────────────────────────────────────┘
116
+
117
+ ┌──────────────────┴───────────────────────────────────────────────┐
118
+ │ PASO 3: Post-procesamiento (postProcess) │
119
+ │ │
120
+ │ ├── Convertir a markdown estructurado │
121
+ │ ├── Clasificar contenido (dominio OPL) │
122
+ │ ├── Generar resumen con Ollama (opcional) │
123
+ │ ├── Generar embeddings vía pipeline existente │
124
+ │ └── Guardar en knowledge/<domain>/<slug>/ │
125
+ │ ├── page.md ← markdown completo │
126
+ │ ├── metadata.json ← datos estructurados │
127
+ │ ├── plan.json ← el plan que usó Ollama │
128
+ │ └── embeddings.json ← vectores │
129
+ └──────────────────────────────────────────────────────────────────┘
130
+ ```
131
+
132
+ ---
133
+
134
+ ## 3. Componentes a Implementar
135
+
136
+ ### 3.1 Core (`src/core/webscrape/`)
137
+
138
+ | Archivo | Descripción | Deps |
139
+ |---------|-------------|------|
140
+ | `analyzer.js` | Envía estructura de página a Ollama, recibe plan JSON | `@xenova/transformers`? No, es puro Ollama API |
141
+ | `executor.js` | Ejecuta el plan de extracción paso a paso | `jsdom` |
142
+ | `fetcher.js` | Fetch de página (simple + headless) | `node-fetch`, `playwright` (opt) |
143
+ | `models.js` | PageSnapshot, ExtractPlan, ExtractedPage, PageType | — |
144
+ | `postprocessor.js` | Markdown, metadata, embeddings, guardado | — |
145
+ | `config.js` | URL de Ollama, timeouts, modelos, cache | — |
146
+
147
+ ### 3.2 Extractores (`src/core/webscrape/extractors/`)
148
+
149
+ | Archivo | Descripción |
150
+ |---------|-------------|
151
+ | `extract-content.js` | Extrae contenido principal (Readability.js mejorado) |
152
+ | `extract-og.js` | Open Graph + Twitter Cards |
153
+ | `extract-jsonld.js` | JSON-LD structured data |
154
+ | `extract-microdata.js` | Microdata / schema.org |
155
+ | `extract-images.js` | Imágenes con alt, caption, dimensiones |
156
+ | `extract-tables.js` | Tablas con caption, headers, rows |
157
+ | `extract-cards.js` | Tarjetas de producto/artículo/post |
158
+ | `extract-forms.js` | Formularios con campos |
159
+ | `extract-special.js` | Load-more, paginación, scroll infinito |
160
+
161
+ ### 3.3 CLI (`src/commands/opl-webscrape.js`)
162
+
163
+ ```bash
164
+ opl webscrape <url> # Modo normal (Ollama analyze + execute)
165
+ opl webscrape <url> --plan-only # Solo mostrar el plan de Ollama, no ejecutar
166
+ opl webscrape <url> --plan <plan.json> # Usar un plan guardado (re-ejecutar)
167
+ opl webscrape <url> --simple # Forzar Readability.js (sin Ollama)
168
+ opl webscrape <url> --headless # Forzar Playwright (para SPAs)
169
+ opl webscrape <url> --output json # Salida JSON estructurada
170
+ opl webscrape <url> --no-embeddings # No generar embeddings
171
+ opl webscrape <url> --dry-run # Mostrar plan sin guardar
172
+ opl webscrape plan <url> # Shorthand para --plan-only
173
+ ```
174
+
175
+ ---
176
+
177
+ ## 4. Prompt de Análisis (Ollama)
178
+
179
+ El prompt que se envía a Ollama es **la pieza clave**. Debe ser:
180
+
181
+ - Compacto (no enviar HTML completo — solo resumen estructural)
182
+ - Rico en señales semánticas (tipo de elementos, no su contenido)
183
+ - Determinista en la respuesta (JSON estructurado)
184
+
185
+ ### Formato del prompt
186
+
187
+ ```
188
+ Eres un analista de páginas web. Tu trabajo es examinar la estructura
189
+ de una página web y generar un plan de extracción.
190
+
191
+ ## Información de la página
192
+ URL: {url}
193
+ Título: {title}
194
+ Meta description: {description}
195
+ Tamaño HTML: {htmlSize} chars
196
+
197
+ ## Resumen estructural
198
+ - Tipo de elementos en la página:
199
+ {summary: article: 3, section: 5, nav: 1, main: 1, aside: 2,
200
+ footer: 1, table: 1, form: 0, img: 12, video: 0, article_card: 6,
201
+ list: 4, breadcrumb: 0}
202
+ - Primeros 2000 caracteres del texto visible:
203
+ "{truncatedText}"
204
+
205
+ ## Enlaces principales (primeros 10)
206
+ {links: [
207
+ {href: "/articulo-1", text: "Cómo hacer X", type: "internal"},
208
+ {href: "/categoria/y", text: "Categoría Y", type: "internal"},
209
+ ...
210
+ ]}
211
+
212
+ ## Meta tags encontrados
213
+ {meta: {
214
+ og: ["og:title", "og:description", "og:image"],
215
+ twitter: ["twitter:card", "twitter:site"],
216
+ jsonld: true,
217
+ microdata: false
218
+ }}
219
+
220
+ ## Instrucciones
221
+ Analiza esta página y devuelve un JSON con:
222
+ 1. pageType: qué tipo de página es
223
+ 2. contentBlocks: qué bloques de contenido identificas y cómo extraerlos
224
+ 3. extractionPlan: pasos concretos a seguir
225
+ 4. metadata: qué meta tags extraer
226
+ 5. specialFeatures: si hay scroll infinito, load-more, paginación, etc.
227
+
228
+ Responde ÚNICAMENTE con el JSON. No incluyas explicaciones.
229
+ ```
230
+
231
+ ### Respuesta esperada
232
+
233
+ ```json
234
+ {
235
+ "pageType": "article",
236
+ "confidence": 0.92,
237
+ "title": "Cómo implementar un scraper con IA",
238
+ "description": "Guía paso a paso para construir un extractor web inteligente",
239
+ "contentBlocks": [
240
+ {
241
+ "type": "main-content",
242
+ "selector": "main article",
243
+ "importance": 10,
244
+ "extractMode": "markdown",
245
+ "description": "Artículo principal con contenido completo"
246
+ },
247
+ {
248
+ "type": "sidebar",
249
+ "selector": "aside.related-posts",
250
+ "importance": 3,
251
+ "extractMode": "links",
252
+ "description": "Artículos relacionados en la barra lateral"
253
+ }
254
+ ],
255
+ "metadata": {
256
+ "og": true,
257
+ "twitter": true,
258
+ "jsonld": true,
259
+ "microdata": false,
260
+ "priority": ["og:title", "og:description", "og:image"]
261
+ },
262
+ "specialFeatures": [],
263
+ "extractionPlan": {
264
+ "steps": [
265
+ "extract-main-content",
266
+ "extract-og",
267
+ "extract-jsonld",
268
+ "extract-images"
269
+ ],
270
+ "outputFormat": "markdown+json",
271
+ "notes": "Página de blog estándar con contenido principal rico en imágenes"
272
+ }
273
+ }
274
+ ```
275
+
276
+ ---
277
+
278
+ ## 5. Integración con el Sistema OPL Existente
279
+
280
+ ### Pipeline completo con embeddings
281
+
282
+ ```
283
+ cli: opl webscrape https://ejemplo.com/articulo
284
+
285
+ fetcher.fetch(url) → PageSnapshot { html, text, links, meta, elementCounts }
286
+
287
+ analyzer.analyze(snapshot, ollama) → ExtractPlan { pageType, blocks, steps }
288
+
289
+ executor.execute(html, plan) → ExtractedPage { content, metadata, media, ... }
290
+
291
+ postprocessor.process(extracted) → { markdown, metadata, cards }
292
+
293
+ → knowledge/<domain>/<slug>/page.md
294
+ → knowledge/<domain>/<slug>/metadata.json
295
+ → knowledge/<domain>/<slug>/plan.json
296
+ → knowledge/<domain>/<slug>/cards.json (si aplica)
297
+
298
+ embedder.indexDocument(slug) ← pipeline de embeddings existente
299
+ ```
300
+
301
+ ### Reutilización de infraestructura existente
302
+
303
+ | Componente OPL existente | Se reutiliza |
304
+ |--------------------------|:------------:|
305
+ | `src/embeddings/pipeline.js` | ✅ Indexación automática |
306
+ | `src/embeddings/sqlite-store.js` | ✅ Cache + almacenamiento |
307
+ | `src/commands/opl-webscrape.js` | ✅ Refactorizado como entry point |
308
+ | `src/cli/commands-opl.js` | ✅ Flags nuevos (`--plan-only`, `--headless`) |
309
+ | Readability.js + Turndown | ✅ Como extractores de contenido (PASO 2) |
310
+ | `opl knowledge` | ✅ Integración con knowledge base |
311
+
312
+ ---
313
+
314
+ ## 6. Estrategia de Implementación por Fases
315
+
316
+ | Fase | Qué se hace | Archivos | Esfuerzo |
317
+ |------|-------------|----------|:--------:|
318
+ | **F0** | Models + Fetcher | `models.js`, `fetcher.js`, `config.js` | 1 día |
319
+ | **F1** | **Analyzer (Ollama) — el corazón** | `analyzer.js`, prompt template | 2-3 días |
320
+ | **F2** | Executor básico (main-content + og + jsonld) | `executor.js`, `extract-content.js`, `extract-og.js`, `extract-jsonld.js` | 3-4 días |
321
+ | **F3** | Extractores avanzados (images, tables, cards, forms) | `extract-images.js`, `extract-tables.js`, `extract-cards.js`, `extract-forms.js` | 3-4 días |
322
+ | **F4** | Post-processor + integración knowledge/embeddings | `postprocessor.js`, refactor `opl-webscrape.js` | 2 días |
323
+ | **F5** | Headless browser (Playwright opcional) | `fetcher.js` (modo headless), `extract-special.js` | 2 días |
324
+ | **F6** | Tests + documentación + CLI flags | tests, docs, `commands-opl.js` | 2 días |
325
+
326
+ **Total estimado:** 2-3 semanas (trabajo parcial, OLLAMA-first)
327
+
328
+ ---
329
+
330
+ ## 7. Beneficios Clave del Enfoque IA
331
+
332
+ | Aspecto | Readability.js | Scraper Python hardcoded | **Ollama-driven (esta propuesta)** |
333
+ |---------|:--------------:|:------------------------:|:----------------------------------:|
334
+ | **Adaptabilidad** | Solo artículos | Media (reglas fijas) | **Alta (analiza cada página)** |
335
+ | **Clasificación** | No | Heurística | **IA entiende el tipo** |
336
+ | **Metadata** | Mínima | Completa | **Selectiva (solo lo relevante)** |
337
+ | **SPA/JS** | No | Sí (Playwright) | **Sí (Playwright opcional)** |
338
+ | **Mantenimiento** | Nulo | Alto (nuevas reglas) | **Bajo (mejora el prompt)** |
339
+ | **Precisión** | 60-70% | 70-85% | **85-95% (IA entiende contexto)** |
340
+ | **Cobertura** | Blogs/news | Sitios conocidos | **Cualquier página web** |
341
+ | **Dependencias** | Mínimas | Python + librerías | **Node.js + Ollama** |
342
+
343
+ ---
344
+
345
+ ## 8. Riesgos y Mitigaciones
346
+
347
+ | Riesgo | Probabilidad | Impacto | Mitigación |
348
+ |--------|:------------:|:-------:|------------|
349
+ | Ollama no disponible | Alta | Alto | Fallback automático a Readability.js + Turndown |
350
+ | Prompts largos (>4K tokens) | Media | Medio | Resumir HTML estructuralmente (árbol, no HTML crudo) |
351
+ | Respuesta JSON malformada de Ollama | Media | Medio | Validar JSON + reintentar con `--strict` |
352
+ | Páginas con anti-bot | Media | Alto | Modo headless + User-Agent rotación |
353
+ | Latencia (Ollama analyse = 2-5s) | Alta | Bajo | Cache de planes por dominio + extracción async |
354
+ | Precisión del plan depende del modelo | Alta | Medio | Usar modelos >= 7B (phi-4, llama3.2, qwen2.5) |
355
+
356
+ ---
357
+
358
+ ## 9. Comandos Futuros (Post-F6)
359
+
360
+ ```bash
361
+ # Extracción básica con IA
362
+ opl webscrape https://ejemplo.com
363
+
364
+ # Solo ver el plan que Ollama generaría (sin extraer)
365
+ opl webscrape https://ejemplo.com --plan-only
366
+
367
+ # Re-ejecutar con un plan guardado
368
+ opl webscrape https://ejemplo.com --plan ./plan.json
369
+
370
+ # Crawl completo de un sitio con IA por página
371
+ opl webscrape https://ejemplo.com --crawl --depth 2
372
+
373
+ # Forzar Playwright para SPAs pesados
374
+ opl webscrape https://spa-ejemplo.com --headless
375
+
376
+ # Salida JSON para pipeline
377
+ opl webscrape https://ejemplo.com --output json
378
+
379
+ # Forzar Readability.js (sin IA)
380
+ opl webscrape https://ejemplo.com --simple
381
+
382
+ # Extraer diseño visual (colores, tipografía, componentes)
383
+ opl webscrape https://ejemplo.com --extract-design
384
+
385
+ # Ver el prompt que se envía a Ollama
386
+ opl webscrape https://ejemplo.com --debug-prompt
387
+ ```
388
+
389
+ ---
390
+
391
+ ## 10. Primeros Pasos Concretos
392
+
393
+ ### Fase 0: Preparación
394
+
395
+ 1. Verificar que Ollama corre localmente:
396
+ ```bash
397
+ curl http://localhost:11434/api/tags
398
+ ```
399
+
400
+ 2. Elegir modelo base (recomendado: `phi-4:14b` o `llama3.2:8b`):
401
+ ```bash
402
+ ollama pull phi-4:14b # Buen balance calidad/velocidad
403
+ ```
404
+
405
+ 3. Crear estructura de directorios:
406
+ ```
407
+ src/core/webscrape/
408
+ ├── index.js # Re-export
409
+ ├── config.js # Ollama URL, modelo, timeouts
410
+ ├── models.js # PageSnapshot, ExtractPlan, ExtractedPage
411
+ ├── fetcher.js # node-fetch + Playwright opcional
412
+ ├── analyzer.js # Ollama prompt + parseo JSON
413
+ ├── executor.js # Ejecuta plan paso a paso
414
+ ├── postprocessor.js # Markdown + metadata + guardado
415
+ └── extractors/
416
+ ├── extract-content.js
417
+ ├── extract-og.js
418
+ ├── extract-jsonld.js
419
+ ├── extract-images.js
420
+ ├── extract-tables.js
421
+ └── ...
422
+ ```
423
+
424
+ 4. Implementar `models.js` + `config.js` + `fetcher.js` (F0, 1 día)
425
+
426
+ ### Fase 1: Analyzer (el corazón)
427
+
428
+ 5. Implementar `analyzer.js`:
429
+ - Construir resumen estructural del HTML (árbol de secciones, conteo de elementos)
430
+ - Extraer texto visible (primeros ~2000 chars)
431
+ - Detectar meta tags OG, Twitter, JSON-LD
432
+ - Enviar prompt a Ollama (`POST /api/generate`)
433
+ - Parsear y validar respuesta JSON
434
+ - Cachear plan por URL en SQLite
435
+
436
+ 6. Probar con 5 tipos de página distintos (article, product, docs, blog, landing)
437
+
438
+ ### Fase 2: Executor básico
439
+
440
+ 7. Implementar extractores core + `executor.js`
441
+ 8. Probar end-to-end con `opl webscrape <url>`
442
+
443
+ ---
444
+
445
+ ## 11. Medición de Éxito
446
+
447
+ | Métrica | Objetivo | Cómo se mide |
448
+ |---------|:--------:|--------------|
449
+ | Precisión del plan | >90% | Validación manual de 50 páginas |
450
+ | Tiempo total por URL | <10s | Benchmark automático |
451
+ | Fallback a Readability | <20% de los casos | Log de modo usado |
452
+ | Tokens por análisis | <3000 | Prompt logging |
453
+ | Cobertura de tipos de página | >80% | Test con 100 URLs diversas |
454
+ | Embeddings generados por scraper | >90% de URLs | Pipeline count |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openprompt-lang",
3
- "version": "1.2.7",
3
+ "version": "1.4.0",
4
4
  "description": "PromptLang CLI — Context Engine de anotaciones para desarrollo asistido por IA",
5
5
  "type": "module",
6
6
  "main": "./bin/cli.js",
@@ -55,7 +55,8 @@
55
55
  "opencode:wizard": "openprompt-lang wizard",
56
56
  "opencode:plan": "openprompt-lang plan",
57
57
  "opencode:execute": "openprompt-lang execute",
58
- "opencode:mode": "openprompt-lang mode"
58
+ "opencode:mode": "openprompt-lang mode",
59
+ "opl:enforce": "node scripts/opl-enforce-setup.mjs"
59
60
  },
60
61
  "keywords": [
61
62
  "prompt-lang",
@@ -72,14 +73,17 @@
72
73
  "node": ">=18"
73
74
  },
74
75
  "dependencies": {
76
+ "@mozilla/readability": "^0.6.0",
75
77
  "ajv": "^8.20.0",
76
78
  "better-sqlite3": "^12.10.0",
77
79
  "chalk": "^5.3.0",
78
80
  "commander": "^12.0.0",
79
81
  "handlebars": "^4.7.9",
80
82
  "inquirer": "^9.3.0",
83
+ "jsdom": "^29.1.1",
81
84
  "pdf-parse": "^2.4.5",
82
85
  "tesseract.js": "^7.0.0",
86
+ "turndown": "^7.2.4",
83
87
  "typescript": "^6.0.3"
84
88
  },
85
89
  "devDependencies": {
@@ -105,5 +109,8 @@
105
109
  "*.{ts,tsx,js,jsx}": [
106
110
  "openprompt-lang lint-file"
107
111
  ]
112
+ },
113
+ "optionalDependencies": {
114
+ "@xenova/transformers": "^2.17.2"
108
115
  }
109
116
  }