3 Commits

Author SHA1 Message Date
Adriano c783fff040 feat(mcp-docugen): output Word (.docx) via Pandoc con reference Tielogic
Aggiunge la generazione di documenti Word coerenti con l'identità
visiva Tielogic, in parallelo al render PDF già esistente. Il flusso
completo è ora `bullet input → Markdown formattato → PDF e/o DOCX`
in una singola chiamata MCP.

- docx_renderer.py: subprocess Pandoc che legge il Markdown da stdin,
  emette il binario .docx su stdout. Strippa il YAML frontmatter e i
  blocchi `<style>` (presenti per il PDF, irrilevanti in DOCX) prima
  della conversione.
- mcp_tools.py: nuovo tool `document_to_docx(markdown)` che ritorna
  `{docx_b64, size_bytes}`; `document_generate` esteso con
  `output_format ∈ {md, pdf, docx, all}`. La firma di
  `build_mcp_server` accetta ora `docx_reference_path` opzionale.
- config.py: `Settings.docx_reference_path` (default
  /app/themes/tielogic-reference.docx).
- main.py: passa la nuova setting a `build_mcp_server`.
- mcp-docugen.Dockerfile: installazione di pandoc accanto alle libs
  Chromium.
- themes/tielogic-reference.docx: reference Word (10 KB) con stili
  Tielogic — heading colors blu/dark, font Inter, dimensioni allineate
  al CSS web. Generato da `scripts/build-reference-docx.py` che parte
  dal reference.docx di default di Pandoc e riscrive `word/styles.xml`
  con regex sui blocchi `<w:style>`. Pandoc lo applica in automatico
  agli output DOCX prodotti dal servizio.
- 9 nuovi test unit per docx_renderer (strip frontmatter/style,
  preprocess combinato, error empty input, smoke skippato in
  ambienti senza Pandoc): 92 test totali.

Smoke E2E via MCP: una sola chiamata `document_generate` con
`output_format=all` produce MD (14 KB), PDF (137 KB, 4 pagine A4) e
DOCX (12.7 KB) coerenti tra loro.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 11:13:11 +02:00
Adriano b32669caa7 feat(mcp-docugen): Markdown autocontenuto con CSS Tielogic iniettato inline
Problema: i template puntavano a un path host hardcoded
(stylesheet: /home/adriano/.../themes/tielogic.css), quindi il file .md
generato non era portabile — su un'altra macchina md-to-pdf non trovava
il CSS e produceva PDF senza stile.

Soluzione: il Renderer legge il CSS da Settings.inline_stylesheet_path
(default /app/themes/tielogic.css nel container) e lo inietta come
blocco <style>...</style> subito dopo il frontmatter YAML del Markdown
restituito dall'LLM. Il file .md risultante è autocontenuto e portabile.

- renderer.py: nuovo arg inline_stylesheet_path + funzione
  _inject_inline_stylesheet (idempotente, gestisce Markdown senza
  frontmatter, no-op se CSS vuoto)
- config.py: Settings.inline_stylesheet_path: Path | None
- main.py: passa il path al Renderer
- mcp-docugen.Dockerfile: COPY themes ./themes nello stage builder per
  trasportare /app/themes/tielogic.css nell'immagine runtime
- templates_seed/{offerta,report-analisi}/template.md: rimossa la riga
  `stylesheet:` dal frontmatter di output + regola tassativa che vieta
  all'LLM di emettere blocchi <style> di sua iniziativa (evita
  conflitti di cascade visti in test)
- 4 nuovi test unit (76 totali): iniezione dopo frontmatter, prepend
  quando frontmatter assente, no-op CSS vuoto, integrazione full E2E
  via Renderer.generate

scripts/bundle-css.py: utility per fixare file .md legacy che
referenziavano stylesheet: come path host (sostituisce la riga con
<style> inline pescando il CSS dal repo)

README aggiornato con rationale e workflow.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:35:41 +02:00
Adriano 7b169fb8db chore: organize repo as uv workspace multi-MCP monorepo
Layout stile CerberoSuite/Cerbero:
- services/ per MCP workspace members (futuri: mcp-docugen, mcp-convert, mcp-inbox)
- docs/ flat con design+implementation per componente
- scripts/, secrets/ placeholder
- pyproject.toml root (uv workspace vuoto + ruff + pytest)
- .gitignore, .env.example, .mcp.json.example, README.md

Rinominate le doc: Docs/<comp>/2026-04-21-*.md -> docs/<comp>-*.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:06:38 +02:00