Files
ArcaSuite/README.md
T
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

100 lines
5.7 KiB
Markdown

# ArcaSuite
Monorepo per il **sistema documentale personale+aziendale** di Adriano e gli **MCP server** che lo supportano.
## Cos'è
Due pezzi, stesso repo:
1. **Sistema Documentale** — vault multi-wiki Markdown versionati su Gitea, pubblicati in sola lettura via Quartz, editabili da Obsidian + Claude Code. Vedi [`docs/sistema-documentale.md`](docs/sistema-documentale.md).
2. **MCP server** — microservizi MCP riusabili dai wiki (e da altri client Claude). Ogni MCP vive in `services/mcp-<nome>/` come membro del workspace `uv`.
## MCP previsti
| Servizio | Stato | Funzione |
|---|---|---|
| `mcp-docugen` | Implementato, 76 test verde, deploy Docker via gateway Caddy (porta 8090), 6 tool MCP esposti, template seed versionati con auto-seed al boot, CSS Tielogic iniettato inline nel Markdown generato | Genera Markdown formale da template + LLM (OpenRouter). Vedi [`docs/mcp-docugen-design.md`](docs/mcp-docugen-design.md) + [`docs/mcp-docugen-implementation.md`](docs/mcp-docugen-implementation.md). |
| `mcp-convert` | Da progettare | Conversione Markdown → PDF / DOCX / HTML (pandoc/typst backend). |
| `mcp-inbox` | Da progettare | Ingest da Telegram (+ STT opzionale via Whisper) verso draft inbox consumati da Claude Code desktop. |
Ogni MCP ha il suo `pyproject.toml`, `src/mcp_<nome>/`, `tests/` e Dockerfile. Viene registrato in `pyproject.toml` root come workspace member.
## Layout
```
ArcaSuite/
├── docs/ # design + implementation plan per componente
│ ├── sistema-documentale.md
│ ├── mcp-docugen-design.md
│ └── mcp-docugen-implementation.md
├── services/ # workspace members uv (uno per MCP)
│ └── mcp-<nome>/ # src/ tests/ pyproject.toml Dockerfile
├── scripts/ # script operativi (provisioning, backup, smoke)
├── secrets/ # chiavi, token (gitignored)
├── docker/ # base.Dockerfile condiviso multi-stage
├── gateway/ # Caddy reverse proxy (Caddyfile)
├── themes/ # CSS condivisi (theme Tielogic unico per md-to-pdf, copre report e offerte)
├── docker-compose.yml # stack completo (gateway + servizi MCP)
├── pyproject.toml # workspace uv + ruff + pytest root
├── .env.example # config root stack
├── .mcp.json.example # template registrazione client MCP
└── .gitignore
```
## Convenzioni
- **Nomenclatura**: `mcp-<nome>` per tutti gli MCP (pattern Cerbero). Package Python: `mcp_<nome>` (snake_case).
- **Package manager**: `uv` workspace. Nessun `requirements.txt`. `uv.lock` committato.
- **Python**: 3.11+, async-first, Pydantic v2 per ogni I/O.
- **Testing**: `pytest` + `pytest-asyncio`, `asyncio_mode = "auto"`, test sotto `services/<svc>/tests/`.
- **Lint**: `ruff` (config root), line 100.
- **Config**: ogni servizio ha un proprio `.env.example`. Root `.env` solo per cose cross-cutting (gateway port, dominio pubblico).
- **Secrets**: mai committati. `.mcp.json` locale gitignored, solo `.mcp.json.example` tracciato.
## Riferimento spec Python
Servizi non-MCP (es. eventuali `inbox-service` REST) seguono [`/home/adriano/Documenti/Struttura_Progetti/2026-04-01-python-project-spec-design.md`](/home/adriano/Documenti/Struttura_Progetti/2026-04-01-python-project-spec-design.md). Gli MCP server seguono la struttura specifica descritta nei rispettivi design doc (FastMCP come root ASGI).
## Setup
```bash
cp .env.example .env # imposta OPENROUTER_API_KEY, DOCUGEN_API_KEY, GATEWAY_PORT
cp .mcp.json.example .mcp.json # compila con URL + API key per registrazione client
uv sync --all-groups
docker compose up -d --build # avvia gateway + mcp-docugen
```
Smoke test:
```bash
curl -H "Authorization: Bearer $DOCUGEN_API_KEY" http://localhost:8090/mcp-docugen/health
```
Endpoint utili (richiede Bearer per quelli MCP, pubblici per la documentazione):
- `GET /mcp-docugen/health` — healthcheck (pubblico)
- `GET /mcp-docugen/docs` — Swagger UI REST (pubblico)
- `GET /mcp-docugen/redoc` — ReDoc REST (pubblico)
- `POST /mcp-docugen/mcp` — endpoint MCP JSON-RPC (Bearer + sessione MCP)
## Template `mcp-docugen`
I template ufficiali sono versionati in `services/mcp-docugen/templates_seed/<nome>/template.md` e copiati nel volume `docugen-data` al primo boot. La copia è **idempotente**: se un template esiste già nel volume (es. modificato a runtime via tool MCP `template_update`) non viene sovrascritto.
Template attualmente disponibili:
- `report-analisi` — report tecnico stile DEVNOTES Tielogic (analisi sperimentali, criticità, fattibilità, roadmap, accettazione)
- `offerta` — offerta economica stile docx Tielogic (cover FORNITORE/CLIENTE, modello commerciale setup+canone+sconto+proiezione, condizioni, accettazione)
Per propagare modifiche al template versionato su un'installazione esistente: usare il tool MCP `template_update`, oppure rimuovere il template dal volume e fare restart del container.
Conversione Markdown→PDF (in attesa di `mcp-convert`): `md-to-pdf <file>.md`.
Il CSS Tielogic non viene referenziato come path esterno: il `Renderer` lo legge da `themes/tielogic.css` (copiato nell'immagine Docker in `/app/themes/`) e lo inietta come blocco `<style>` inline subito dopo il frontmatter del Markdown generato. Vantaggio: il file `.md` prodotto è **autocontenuto e portabile** — chi lo riceve può convertirlo in PDF stilizzato anche senza avere il CSS sull'host.
Per documenti `.md` legacy che ancora referenziano `stylesheet:` come path host: usare `scripts/bundle-css.py <file.md> [--in-place]` per rimuovere la riga e iniettare il CSS inline.
## Remote
- Gitea: `ssh://git@git.tielogic.xyz:222/Adriano/ArcaSuite.git`