lovarch-cli 0.2.1__tar.gz → 0.3.1__tar.gz
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.
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/CHANGELOG.md +45 -1
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/PKG-INFO +45 -5
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/README.md +44 -4
- lovarch_cli-0.3.1/lovarch_cli/agents/__init__.py +5 -0
- lovarch_cli-0.3.1/lovarch_cli/agents/prompts.py +85 -0
- lovarch_cli-0.3.1/lovarch_cli/agents/runner.py +66 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/cli.py +16 -0
- lovarch_cli-0.3.1/lovarch_cli/commands/agent_cmd.py +80 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/context_cmd.py +7 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/do_cmd.py +70 -0
- lovarch_cli-0.3.1/lovarch_cli/commands/mcp_cmd.py +83 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/run.py +71 -0
- lovarch_cli-0.3.1/lovarch_cli/commands/skills_cmd.py +88 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/verifica_cmd.py +82 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/mcp/server.py +22 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/mcp/tools.py +63 -0
- lovarch_cli-0.3.1/lovarch_cli/skills/lovarch-capitolato/SKILL.md +37 -0
- lovarch_cli-0.3.1/lovarch_cli/skills/lovarch-direzione-lavori/SKILL.md +29 -0
- lovarch_cli-0.3.1/lovarch_cli/skills/lovarch-interior-designer/SKILL.md +47 -0
- lovarch_cli-0.3.1/lovarch_cli/skills/lovarch-preventivi/SKILL.md +34 -0
- lovarch_cli-0.3.1/lovarch_cli/skills/lovarch-render/SKILL.md +36 -0
- lovarch_cli-0.3.1/lovarch_cli/skills/lovarch-verifica-normativa/SKILL.md +40 -0
- lovarch_cli-0.3.1/lovarch_cli/squad/scripts/input_parser.py +225 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/pipeline_runner.py +494 -306
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/verify/__init__.py +6 -1
- lovarch_cli-0.3.1/lovarch_cli/verify/computo.py +149 -0
- lovarch_cli-0.3.1/lovarch_cli/verify/pratica.py +122 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/version.py +1 -1
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/workflows/platform.py +78 -0
- lovarch_cli-0.2.1/lovarch_cli/commands/mcp_cmd.py +0 -26
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/.gitignore +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/LICENSE +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/__main__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/ai/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/ai/gateway.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/api.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/auth/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/auth/keyring_store.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/auth/local_server.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/auth/pkce.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/auth/session.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/clients/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/clients/factory.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/clients/local_client.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/clients/lovarch_storage.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/clients/lovarch_supabase.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/clients/persistence.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/clients/storage.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/account.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/audit.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/config_cmd.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/consolidate.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/dev.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/init.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/jobs_cmd.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/login.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/signup.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/status.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/commands/upgrade.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/config.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/config_store.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/credits/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/credits/base.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/credits/factory.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/credits/local.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/credits/lovarch.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/i18n/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/i18n/loader.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/i18n/translations/en.json +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/i18n/translations/es.json +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/i18n/translations/it.json +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/i18n/translations/pt.json +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/mcp/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/sample_downloader.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/README.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/auditor-input.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/bim-engineer.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/briefing-architect.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/cad-engineer.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/capitolato-writer.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/computo-engineer.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/concept-designer.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/contratto-architect.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/deliverable-builder.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/energy-prelim.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/pratiche-it.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/progetto-chief.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/quality-dati.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/quality-misure.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/quality-normativa.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/quality-output.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/agents/regolatorio-it.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/checklists/handoff-quality-gate.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/checklists/quality-dati-checklist.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/checklists/quality-misure-checklist.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/checklists/quality-normativa-checklist.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/checklists/quality-output-checklist.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/config.yaml +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/data/CHANGELOG.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/data/agents-prd.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/data/architettura-progetto-rules.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/data/handoff-card-template.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/data/mocks/catasto-visura.json +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/data/mocks/firma-envelope.json +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/data/prezzario-lombardia-sample.json +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/api_clients.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/architect_profile.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/deliverable_generators.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/generate_attico_brera_dwg.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/generate_chianti_dxf.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/generate_chianti_images.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/generate_real_sample_images.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/generate_sample_assets.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/lovarch_client.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/render_dxf_to_png.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/run_palestra_demo.sh +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/simulate_squad_execution.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/scripts/validate-squad.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/tasks/audit-input.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/tasks/compute-metric.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/tasks/consolidate-dossier.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/tasks/generate-cad-plan.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/tasks/generate-ifc-model.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/tasks/write-capitolato.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/templates/asseverazione-tecnica.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/templates/capitolato-uni-11337.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/templates/cila-comune-milano.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/templates/contratto-cnappc.md +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad/workflows/dal-brief-al-cantiere.yaml +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/squad_loader.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/verify/contratto.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/verify/dossier.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/verify/misure.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/verify/normativa.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/lovarch_cli/workflows/__init__.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/pyproject.toml +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/scripts/refresh_squad_vendor.py +0 -0
- {lovarch_cli-0.2.1 → lovarch_cli-0.3.1}/scripts/sync_squad.py +0 -0
|
@@ -5,9 +5,53 @@ All notable changes to `lovarch-cli` are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.3.1] — 2026-07-04
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `lovarch do script <topic>` — script di contenuto strutturato via piattaforma (schema drift della EF scripts-generate corretto lato monorepo; refund resiliente).
|
|
12
|
+
- `lovarch verifica computo <file> [--region --version]` — confronto deterministico (gratis) delle voci di un computo col prezzario regionale (tabella `prezzari`, seed Lombardia): codici inesistenti, prezzi fuori tolleranza (±20%), unità incoerenti, totale.
|
|
13
|
+
- `lovarch verifica pratica <file> [--tipo CILA|SCIA]` — verifica adversarial (2 modelli) di una pratica edilizia: completezza (catasto, titolo, asseverazione) e coerenza titolo↔intervento.
|
|
14
|
+
|
|
15
|
+
### Notes
|
|
16
|
+
- Persistenza premium: il runner ora crea il progetto CRM completo nell'account dell'utente tramite la EF `cli-persist` (scrittura controllata lato server, nessuna scrittura cross-tenant).
|
|
17
|
+
|
|
8
18
|
## [Unreleased]
|
|
9
19
|
|
|
10
|
-
(No unreleased changes yet — last release was v0.
|
|
20
|
+
(No unreleased changes yet — last release was v0.3.0.)
|
|
21
|
+
|
|
22
|
+
## [0.3.0] — 2026-07-04
|
|
23
|
+
|
|
24
|
+
### Added — MCP remoto, Skills, agenti, verifica, workflows
|
|
25
|
+
|
|
26
|
+
Il rilascio che porta agli utenti tutto ciò che è stato costruito dopo v0.2.1:
|
|
27
|
+
|
|
28
|
+
- **Skills** (`lovarch skills install`) — 6 skill (interior-designer, capitolato,
|
|
29
|
+
preventivi, direzione-lavori, verifica-normativa, render) che il TUO agente
|
|
30
|
+
(Claude Code) esegue col PROPRIO modello: il testo non consuma crediti Lovarch,
|
|
31
|
+
la piattaforma addebita solo immagini/dati/deliverable/verifica. Regola
|
|
32
|
+
architetturale: "il cervello è dell'utente, la piattaforma fa ciò che solo lei fa".
|
|
33
|
+
- **MCP remoto** `https://mcp.lovarch.com/mcp` (Streamable HTTP) + chiavi `lvk_`
|
|
34
|
+
(`lovarch mcp key`) — connetti Lovarch a qualsiasi client MCP con URL + header,
|
|
35
|
+
come le altre piattaforme.
|
|
36
|
+
- **Agenti** (`lovarch agent`) — interior-designer, direzione-lavori, preventivi,
|
|
37
|
+
geometra-catasto, personalizzati col brand dell'utente (executor=Sonnet 5,
|
|
38
|
+
verifier=Opus 4.8).
|
|
39
|
+
- **verifica** (`lovarch verifica`) — misure (DXF, gratis), normativa, contratto
|
|
40
|
+
(regola QN_007), dossier: controllo adversariale a 2 modelli.
|
|
41
|
+
- **do** (`lovarch do`) — render, colors, copy, logo, site: workflow della
|
|
42
|
+
piattaforma dal terminale.
|
|
43
|
+
- **context** (`lovarch context show [--json]`) — il bundle di personalizzazione.
|
|
44
|
+
- **jobs** (`lovarch jobs`) — job asincroni (video/export/upscale).
|
|
45
|
+
- **config** (`lovarch config`) — preferenze + API keys BYO per il Free.
|
|
46
|
+
- Runner v5: input reale dal progetto (fine del demo hardcoded), run faseadas
|
|
47
|
+
(`--deliverables`), 3 agenti redigono via LLM, chief Opus sul REJECT,
|
|
48
|
+
retry-loop reale del QA.
|
|
49
|
+
|
|
50
|
+
### Rules
|
|
51
|
+
|
|
52
|
+
- Costo sempre in crediti (mai USD). Lingua dell'utente sempre. Modello
|
|
53
|
+
scegliibile dal catalogo. Il testo, con un agente proprio, gira in locale.
|
|
54
|
+
|
|
11
55
|
|
|
12
56
|
## [0.2.1] — 2026-07-03
|
|
13
57
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lovarch-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: AI-powered architectural project execution CLI by Lovarch
|
|
5
5
|
Project-URL: Homepage, https://archprime.io
|
|
6
6
|
Project-URL: Documentation, https://lovarch.com/cli-docs
|
|
@@ -135,7 +135,7 @@ WSL, o se hai già pipx configurato):
|
|
|
135
135
|
|
|
136
136
|
```bash
|
|
137
137
|
# Ultima release (anche pre-release):
|
|
138
|
-
pipx install git+https://github.com/ArchPrime-official/lovarch-cli.git@v0.
|
|
138
|
+
pipx install git+https://github.com/ArchPrime-official/lovarch-cli.git@v0.3.0
|
|
139
139
|
|
|
140
140
|
# Oppure dal branch main (rolling):
|
|
141
141
|
pipx install git+https://github.com/ArchPrime-official/lovarch-cli.git
|
|
@@ -150,7 +150,7 @@ git clone https://github.com/ArchPrime-official/lovarch-cli.git
|
|
|
150
150
|
cd lovarch-cli
|
|
151
151
|
python3.12 -m venv .venv && source .venv/bin/activate
|
|
152
152
|
pip install -e ".[dev]"
|
|
153
|
-
pytest tests/ # →
|
|
153
|
+
pytest tests/ # → 198 passing
|
|
154
154
|
lovarch --version
|
|
155
155
|
```
|
|
156
156
|
|
|
@@ -164,7 +164,7 @@ Vedi [CONTRIBUTING.md](./CONTRIBUTING.md) per il workflow di sviluppo.
|
|
|
164
164
|
|
|
165
165
|
```bash
|
|
166
166
|
# Verifica installazione
|
|
167
|
-
lovarch --version # → lovarch-cli 0.
|
|
167
|
+
lovarch --version # → lovarch-cli 0.3.0
|
|
168
168
|
|
|
169
169
|
# Primo login (interattivo: Free o Premium)
|
|
170
170
|
lovarch login
|
|
@@ -191,7 +191,7 @@ lovarch status
|
|
|
191
191
|
|---------|-------------|
|
|
192
192
|
| `arch login` | Login Free o Premium |
|
|
193
193
|
| `arch signup` | Cadastro Free interattivo |
|
|
194
|
-
| `arch config` | Configurazione (API keys, lingua, storage path)
|
|
194
|
+
| `arch config` | Configurazione (API keys, lingua, storage path) |
|
|
195
195
|
| `arch init <progetto>` | Crea nuovo progetto con struttura sample-input |
|
|
196
196
|
| `arch audit <progetto>` | Esegue audit input (gate di ingresso) |
|
|
197
197
|
| `arch run <workflow>` | Esegue workflow completo |
|
|
@@ -199,9 +199,49 @@ lovarch status
|
|
|
199
199
|
| `arch status <id>` | Stato di una esecuzione |
|
|
200
200
|
| `arch upgrade` | CTA per passare da Free a Premium |
|
|
201
201
|
| `arch account delete` | Right-to-erasure GDPR |
|
|
202
|
+
| `arch context show` | Contesto di personalizzazione usato dagli agenti AI (premium) |
|
|
203
|
+
| `arch do render\|colors\|copy` | Workflow della piattaforma dal terminale (premium) |
|
|
204
|
+
| `arch verifica misure <dxf>` | Verifica DXF: layer ISO, ambienti, cartiglio (gratis) |
|
|
205
|
+
| `arch verifica normativa\|contratto <doc>` | Verifica adversariale 2 modelli (premium) |
|
|
206
|
+
| `arch verifica dossier <cartella>` | QA completo standalone su una cartella (premium) |
|
|
207
|
+
| `arch jobs list\|status` | Job asincroni (video, export, upscale) |
|
|
208
|
+
| `arch mcp serve` | Server MCP per Claude Code / IDE |
|
|
202
209
|
|
|
203
210
|
Vedi `arch --help` per dettagli completi.
|
|
204
211
|
|
|
212
|
+
## Skills — usa il TUO agente (Claude Code, Codex...)
|
|
213
|
+
|
|
214
|
+
Se usi già un agente con un suo modello, il TESTO lo genera lui (zero crediti
|
|
215
|
+
Lovarch); la piattaforma addebita solo immagini, dati e verifiche di piattaforma.
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
lovarch skills install # → ~/.claude/skills
|
|
219
|
+
# poi, nel tuo agente: "progetto di interni per un attico 90mq..." → parte lovarch-interior-designer
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
Skill disponibili: `interior-designer`, `capitolato`, `preventivi`,
|
|
223
|
+
`direzione-lavori`, `verifica-normativa`, `render`.
|
|
224
|
+
|
|
225
|
+
## Server MCP (Claude Code / Claude / IDE)
|
|
226
|
+
|
|
227
|
+
Il CLI espone le sue capacità come server **MCP** — 15 tools (render, verifica,
|
|
228
|
+
crediti, contesto, testo multi-modello...). Registrazione in Claude Code:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
claude mcp add lovarch -- lovarch mcp serve
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Oppure il **server MCP remoto** (nessuna installazione — una URL + una chiave):
|
|
235
|
+
|
|
236
|
+
```bash
|
|
237
|
+
lovarch mcp key # crea una chiave lvk_...
|
|
238
|
+
claude mcp add lovarch --transport http https://mcp.lovarch.com/mcp \\
|
|
239
|
+
--header "Authorization: Bearer lvk_..."
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Ogni tool-call addebita i crediti Lovarch dell'utente esattamente come il CLI
|
|
243
|
+
(i costi sono SEMPRE espressi in crediti).
|
|
244
|
+
|
|
205
245
|
## Limiti dichiarati
|
|
206
246
|
|
|
207
247
|
`lovarch-cli` **NON** sostituisce:
|
|
@@ -76,7 +76,7 @@ WSL, o se hai già pipx configurato):
|
|
|
76
76
|
|
|
77
77
|
```bash
|
|
78
78
|
# Ultima release (anche pre-release):
|
|
79
|
-
pipx install git+https://github.com/ArchPrime-official/lovarch-cli.git@v0.
|
|
79
|
+
pipx install git+https://github.com/ArchPrime-official/lovarch-cli.git@v0.3.0
|
|
80
80
|
|
|
81
81
|
# Oppure dal branch main (rolling):
|
|
82
82
|
pipx install git+https://github.com/ArchPrime-official/lovarch-cli.git
|
|
@@ -91,7 +91,7 @@ git clone https://github.com/ArchPrime-official/lovarch-cli.git
|
|
|
91
91
|
cd lovarch-cli
|
|
92
92
|
python3.12 -m venv .venv && source .venv/bin/activate
|
|
93
93
|
pip install -e ".[dev]"
|
|
94
|
-
pytest tests/ # →
|
|
94
|
+
pytest tests/ # → 198 passing
|
|
95
95
|
lovarch --version
|
|
96
96
|
```
|
|
97
97
|
|
|
@@ -105,7 +105,7 @@ Vedi [CONTRIBUTING.md](./CONTRIBUTING.md) per il workflow di sviluppo.
|
|
|
105
105
|
|
|
106
106
|
```bash
|
|
107
107
|
# Verifica installazione
|
|
108
|
-
lovarch --version # → lovarch-cli 0.
|
|
108
|
+
lovarch --version # → lovarch-cli 0.3.0
|
|
109
109
|
|
|
110
110
|
# Primo login (interattivo: Free o Premium)
|
|
111
111
|
lovarch login
|
|
@@ -132,7 +132,7 @@ lovarch status
|
|
|
132
132
|
|---------|-------------|
|
|
133
133
|
| `arch login` | Login Free o Premium |
|
|
134
134
|
| `arch signup` | Cadastro Free interattivo |
|
|
135
|
-
| `arch config` | Configurazione (API keys, lingua, storage path)
|
|
135
|
+
| `arch config` | Configurazione (API keys, lingua, storage path) |
|
|
136
136
|
| `arch init <progetto>` | Crea nuovo progetto con struttura sample-input |
|
|
137
137
|
| `arch audit <progetto>` | Esegue audit input (gate di ingresso) |
|
|
138
138
|
| `arch run <workflow>` | Esegue workflow completo |
|
|
@@ -140,9 +140,49 @@ lovarch status
|
|
|
140
140
|
| `arch status <id>` | Stato di una esecuzione |
|
|
141
141
|
| `arch upgrade` | CTA per passare da Free a Premium |
|
|
142
142
|
| `arch account delete` | Right-to-erasure GDPR |
|
|
143
|
+
| `arch context show` | Contesto di personalizzazione usato dagli agenti AI (premium) |
|
|
144
|
+
| `arch do render\|colors\|copy` | Workflow della piattaforma dal terminale (premium) |
|
|
145
|
+
| `arch verifica misure <dxf>` | Verifica DXF: layer ISO, ambienti, cartiglio (gratis) |
|
|
146
|
+
| `arch verifica normativa\|contratto <doc>` | Verifica adversariale 2 modelli (premium) |
|
|
147
|
+
| `arch verifica dossier <cartella>` | QA completo standalone su una cartella (premium) |
|
|
148
|
+
| `arch jobs list\|status` | Job asincroni (video, export, upscale) |
|
|
149
|
+
| `arch mcp serve` | Server MCP per Claude Code / IDE |
|
|
143
150
|
|
|
144
151
|
Vedi `arch --help` per dettagli completi.
|
|
145
152
|
|
|
153
|
+
## Skills — usa il TUO agente (Claude Code, Codex...)
|
|
154
|
+
|
|
155
|
+
Se usi già un agente con un suo modello, il TESTO lo genera lui (zero crediti
|
|
156
|
+
Lovarch); la piattaforma addebita solo immagini, dati e verifiche di piattaforma.
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
lovarch skills install # → ~/.claude/skills
|
|
160
|
+
# poi, nel tuo agente: "progetto di interni per un attico 90mq..." → parte lovarch-interior-designer
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Skill disponibili: `interior-designer`, `capitolato`, `preventivi`,
|
|
164
|
+
`direzione-lavori`, `verifica-normativa`, `render`.
|
|
165
|
+
|
|
166
|
+
## Server MCP (Claude Code / Claude / IDE)
|
|
167
|
+
|
|
168
|
+
Il CLI espone le sue capacità come server **MCP** — 15 tools (render, verifica,
|
|
169
|
+
crediti, contesto, testo multi-modello...). Registrazione in Claude Code:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
claude mcp add lovarch -- lovarch mcp serve
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Oppure il **server MCP remoto** (nessuna installazione — una URL + una chiave):
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
lovarch mcp key # crea una chiave lvk_...
|
|
179
|
+
claude mcp add lovarch --transport http https://mcp.lovarch.com/mcp \\
|
|
180
|
+
--header "Authorization: Bearer lvk_..."
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Ogni tool-call addebita i crediti Lovarch dell'utente esattamente come il CLI
|
|
184
|
+
(i costi sono SEMPRE espressi in crediti).
|
|
185
|
+
|
|
146
186
|
## Limiti dichiarati
|
|
147
187
|
|
|
148
188
|
`lovarch-cli` **NON** sostituisce:
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""Curated architecture/interior/construction agent personas.
|
|
2
|
+
|
|
3
|
+
Each agent runs through the platform text gateway (cli-ai-text) with the user's
|
|
4
|
+
personalization context prepended, so the output speaks in the user's brand and
|
|
5
|
+
language and debits the user's credits. These extend the squad
|
|
6
|
+
(architettura-progetto) with roles focused on interior design and construction —
|
|
7
|
+
usable standalone from the CLI/MCP, the way each professional prefers.
|
|
8
|
+
"""
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@dataclass
|
|
15
|
+
class AgentPersona:
|
|
16
|
+
id: str
|
|
17
|
+
label: str
|
|
18
|
+
role: str # executor (Sonnet) | verifier/chief (Opus)
|
|
19
|
+
system: str
|
|
20
|
+
default_max_tokens: int = 3500
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
AGENTS: dict[str, AgentPersona] = {
|
|
24
|
+
"interior-designer": AgentPersona(
|
|
25
|
+
id="interior-designer",
|
|
26
|
+
label="Interior Designer",
|
|
27
|
+
role="executor",
|
|
28
|
+
system=(
|
|
29
|
+
"Sei @interior-designer, interior designer esperto (metodo ispirato a "
|
|
30
|
+
"Patricia Urquiola: materia, colore, comfort, dettaglio artigianale). "
|
|
31
|
+
"Dato un brief di progetto, produci in markdown un PROGETTO DI INTERNI "
|
|
32
|
+
"concreto e realizzabile con: (1) concept e atmosfera; (2) layout per "
|
|
33
|
+
"ambiente con mq e flussi; (3) palette materiali e finiture (pavimenti, "
|
|
34
|
+
"pareti, superfici) con motivazione; (4) FF&E — arredi e illuminazione "
|
|
35
|
+
"chiave con criteri di scelta; (5) palette cromatica; (6) note di "
|
|
36
|
+
"comfort e sostenibilità. Coerente con lo stile e i vincoli del cliente. "
|
|
37
|
+
"Concreto, niente riempitivi."
|
|
38
|
+
),
|
|
39
|
+
),
|
|
40
|
+
"direzione-lavori": AgentPersona(
|
|
41
|
+
id="direzione-lavori",
|
|
42
|
+
label="Direzione Lavori",
|
|
43
|
+
role="executor",
|
|
44
|
+
system=(
|
|
45
|
+
"Sei @direzione-lavori, direttore dei lavori esperto di cantieri edili "
|
|
46
|
+
"italiani. Dato un progetto, produci in markdown: (1) CRONOPROGRAMMA "
|
|
47
|
+
"realistico per fasi (demolizioni, impianti, opere edili, finiture, "
|
|
48
|
+
"collaudo) con durate e dipendenze; (2) SAL (stati di avanzamento) con "
|
|
49
|
+
"milestone; (3) checklist VISITE DI CANTIERE per fase; (4) verbale-tipo "
|
|
50
|
+
"di sopralluogo; (5) punti di controllo qualità e sicurezza (D.Lgs "
|
|
51
|
+
"81/2008 — CSP/CSE dove necessario). Segnala sempre che firme e "
|
|
52
|
+
"responsabilità sono del professionista abilitato (banner BOZZA)."
|
|
53
|
+
),
|
|
54
|
+
),
|
|
55
|
+
"preventivi": AgentPersona(
|
|
56
|
+
id="preventivi",
|
|
57
|
+
label="Preventivi / Proposta",
|
|
58
|
+
role="executor",
|
|
59
|
+
system=(
|
|
60
|
+
"Sei @preventivi, esperto di preventivi e proposte commerciali per "
|
|
61
|
+
"studi di architettura italiani. Dato un progetto e (se disponibili) i "
|
|
62
|
+
"dati fiscali del professionista, produci in markdown una PROPOSTA "
|
|
63
|
+
"professionale con: (1) oggetto e perimetro dell'incarico; (2) fasi e "
|
|
64
|
+
"deliverable; (3) onorario e articolazione in SAL; (4) tempi; (5) note "
|
|
65
|
+
"su oneri (cassa, IVA) e condizioni. Per un cliente PRIVATO i parametri "
|
|
66
|
+
"DM 17/06/2016 sono ORIENTATIVI: un eventuale scostamento va motivato, "
|
|
67
|
+
"MAI presentato come obbligo di legge (la L.49/2023 vincola solo "
|
|
68
|
+
"contraenti forti). Tono professionale ma caldo."
|
|
69
|
+
),
|
|
70
|
+
),
|
|
71
|
+
"geometra-catasto": AgentPersona(
|
|
72
|
+
id="geometra-catasto",
|
|
73
|
+
label="Geometra / Catasto",
|
|
74
|
+
role="verifier",
|
|
75
|
+
system=(
|
|
76
|
+
"Sei @geometra-catasto, esperto di dati catastali e pratiche DOCFA. "
|
|
77
|
+
"Dato un input (dati immobile / visura), verifica la COERENZA dei dati "
|
|
78
|
+
"catastali e produci in markdown: (1) riepilogo identificativi (foglio, "
|
|
79
|
+
"mappale, subalterno, categoria, classe) segnalando incongruenze; (2) "
|
|
80
|
+
"check di preparazione per DOCFA/visura; (3) rilievi mancanti o dubbi. "
|
|
81
|
+
"Sei un supporto di CONTROLLO: firma, rilievo metrico e responsabilità "
|
|
82
|
+
"restano del geometra/tecnico abilitato (banner BOZZA)."
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Run a curated agent persona via the platform text gateway.
|
|
2
|
+
|
|
3
|
+
Prepends the user's personalization bundle (brand, style, signature, language)
|
|
4
|
+
to the agent's system prompt, so every agent speaks in the user's brand and
|
|
5
|
+
language, and debits the user's credits by real tokens.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
from dataclasses import dataclass
|
|
10
|
+
|
|
11
|
+
from lovarch_cli.agents.prompts import AGENTS
|
|
12
|
+
from lovarch_cli.ai import AiGatewayError, LovarchAiGateway
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass
|
|
16
|
+
class AgentResult:
|
|
17
|
+
agent_id: str
|
|
18
|
+
text: str
|
|
19
|
+
model: str
|
|
20
|
+
credits_charged: int
|
|
21
|
+
balance: int | None
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
async def run_agent(
|
|
25
|
+
gateway: LovarchAiGateway,
|
|
26
|
+
agent_id: str,
|
|
27
|
+
brief: str,
|
|
28
|
+
*,
|
|
29
|
+
language: str = "it",
|
|
30
|
+
lead_id: str | None = None,
|
|
31
|
+
) -> AgentResult:
|
|
32
|
+
"""Run the agent on a brief, personalized with the user's context bundle."""
|
|
33
|
+
persona = AGENTS.get(agent_id)
|
|
34
|
+
if persona is None:
|
|
35
|
+
raise AiGatewayError(
|
|
36
|
+
f"Agente sconosciuto: {agent_id}. Disponibili: {', '.join(AGENTS)}"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
system = persona.system
|
|
40
|
+
# Best-effort personalization: prepend the user's context prompt_block.
|
|
41
|
+
try:
|
|
42
|
+
bundle = await gateway.get_user_context(lead_id=lead_id)
|
|
43
|
+
block = bundle.get("prompt_block") if isinstance(bundle, dict) else None
|
|
44
|
+
if block:
|
|
45
|
+
system = f"{block}\n\n{system}"
|
|
46
|
+
lang = ((bundle or {}).get("preferences") or {}).get("preferred_language") if isinstance(bundle, dict) else None
|
|
47
|
+
if lang:
|
|
48
|
+
language = lang
|
|
49
|
+
except AiGatewayError:
|
|
50
|
+
pass # personalization is optional; the agent still runs
|
|
51
|
+
|
|
52
|
+
result = await gateway.generate_text(
|
|
53
|
+
brief,
|
|
54
|
+
role=persona.role, # type: ignore[arg-type]
|
|
55
|
+
system=system,
|
|
56
|
+
max_tokens=persona.default_max_tokens,
|
|
57
|
+
language=language,
|
|
58
|
+
operation_type=f"agent:{agent_id}",
|
|
59
|
+
)
|
|
60
|
+
return AgentResult(
|
|
61
|
+
agent_id=agent_id,
|
|
62
|
+
text=result.text,
|
|
63
|
+
model=result.model,
|
|
64
|
+
credits_charged=result.credits_charged,
|
|
65
|
+
balance=result.balance,
|
|
66
|
+
)
|
|
@@ -249,6 +249,22 @@ app.add_typer(
|
|
|
249
249
|
help="Job asincroni (video, export, upscale) — stato e output.",
|
|
250
250
|
)
|
|
251
251
|
|
|
252
|
+
from lovarch_cli.commands.agent_cmd import agent_app # noqa: E402
|
|
253
|
+
|
|
254
|
+
app.add_typer(
|
|
255
|
+
agent_app,
|
|
256
|
+
name="agent",
|
|
257
|
+
help="Agenti architetto/interior/cantiere (interior-designer, direzione-lavori...).",
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
from lovarch_cli.commands.skills_cmd import skills_app # noqa: E402
|
|
261
|
+
|
|
262
|
+
app.add_typer(
|
|
263
|
+
skills_app,
|
|
264
|
+
name="skills",
|
|
265
|
+
help="Skills per il tuo agente (Claude Code): testo col TUO modello, zero crediti.",
|
|
266
|
+
)
|
|
267
|
+
|
|
252
268
|
from lovarch_cli.commands.config_cmd import config_app # noqa: E402
|
|
253
269
|
|
|
254
270
|
app.add_typer(
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""`lovarch agent` — run architecture/interior/construction agents.
|
|
2
|
+
|
|
3
|
+
lovarch agent list
|
|
4
|
+
lovarch agent interior-designer "attico 90mq, stile caldo minimale, cliente ama il legno"
|
|
5
|
+
lovarch agent direzione-lavori "ristrutturazione 120mq, consegna 90 giorni"
|
|
6
|
+
|
|
7
|
+
Each agent runs via the platform (debits credits), personalized with your brand
|
|
8
|
+
and language.
|
|
9
|
+
"""
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import asyncio
|
|
13
|
+
|
|
14
|
+
import typer
|
|
15
|
+
from rich.console import Console
|
|
16
|
+
from rich.markdown import Markdown
|
|
17
|
+
|
|
18
|
+
from lovarch_cli.agents import AGENTS
|
|
19
|
+
|
|
20
|
+
console = Console()
|
|
21
|
+
err_console = Console(stderr=True)
|
|
22
|
+
|
|
23
|
+
agent_app = typer.Typer(
|
|
24
|
+
help="Agenti per architetti, interior designer e cantiere (premium).",
|
|
25
|
+
no_args_is_help=True,
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@agent_app.command("list")
|
|
30
|
+
def list_command() -> None:
|
|
31
|
+
"""Elenca gli agenti disponibili."""
|
|
32
|
+
for a in AGENTS.values():
|
|
33
|
+
model = "Opus 4.8" if a.role in ("verifier", "chief") else "Sonnet 5"
|
|
34
|
+
console.print(f" [cyan]{a.id}[/cyan] — {a.label} [dim]({model})[/dim]")
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@agent_app.command("run")
|
|
38
|
+
def run_command(
|
|
39
|
+
agent_id: str = typer.Argument(..., help="ID agente (vedi `lovarch agent list`)."),
|
|
40
|
+
brief: str = typer.Argument(..., help="Brief / richiesta per l'agente."),
|
|
41
|
+
lead: str = typer.Option(None, "--lead", help="ID di un cliente CRM da usare come contesto."),
|
|
42
|
+
language: str = typer.Option(None, "--language", help="Lingua dell'output."),
|
|
43
|
+
output: str = typer.Option(None, "--output", "-o", help="Salva il markdown su file."),
|
|
44
|
+
) -> None:
|
|
45
|
+
"""Esegui un agente su un brief (personalizzato + addebita crediti)."""
|
|
46
|
+
from lovarch_cli.agents import run_agent
|
|
47
|
+
from lovarch_cli.ai import AiGatewayError, InsufficientCreditsError, LovarchAiGateway
|
|
48
|
+
from lovarch_cli.auth.session import LovarchSession
|
|
49
|
+
from lovarch_cli.i18n import current_lang
|
|
50
|
+
|
|
51
|
+
if agent_id not in AGENTS:
|
|
52
|
+
err_console.print(
|
|
53
|
+
f"[red]✗ Agente sconosciuto: {agent_id}. Disponibili: {', '.join(AGENTS)}[/red]"
|
|
54
|
+
)
|
|
55
|
+
raise typer.Exit(2)
|
|
56
|
+
|
|
57
|
+
session = LovarchSession.load()
|
|
58
|
+
if session is None:
|
|
59
|
+
err_console.print("[red]✗ Non autenticato. Esegui `lovarch login --premium`.[/red]")
|
|
60
|
+
raise typer.Exit(1)
|
|
61
|
+
|
|
62
|
+
try:
|
|
63
|
+
result = asyncio.run(run_agent(
|
|
64
|
+
LovarchAiGateway(session), agent_id, brief,
|
|
65
|
+
language=language or current_lang(), lead_id=lead,
|
|
66
|
+
))
|
|
67
|
+
except InsufficientCreditsError as exc:
|
|
68
|
+
err_console.print(f"[red]✗ Crediti insufficienti: disponibili {exc.available}, richiesti {exc.needed}.[/red]")
|
|
69
|
+
raise typer.Exit(1)
|
|
70
|
+
except AiGatewayError as exc:
|
|
71
|
+
err_console.print(f"[red]✗ {exc}[/red]")
|
|
72
|
+
raise typer.Exit(1)
|
|
73
|
+
|
|
74
|
+
console.print(Markdown(result.text))
|
|
75
|
+
console.print(f"\n[dim]— @{result.agent_id} · crediti addebitati: {result.credits_charged}[/dim]")
|
|
76
|
+
if output:
|
|
77
|
+
from pathlib import Path
|
|
78
|
+
|
|
79
|
+
Path(output).expanduser().write_text(result.text, encoding="utf-8")
|
|
80
|
+
console.print(f"[green]✓[/green] salvato: {output}")
|
|
@@ -35,6 +35,7 @@ _CHIP_LABELS = {
|
|
|
35
35
|
@context_app.command("show")
|
|
36
36
|
def show_command(
|
|
37
37
|
lead_id: str = typer.Option(None, "--lead", help="ID di un lead CRM da includere."),
|
|
38
|
+
as_json: bool = typer.Option(False, "--json", help="Output JSON completo (per skills/agenti)."),
|
|
38
39
|
) -> None:
|
|
39
40
|
"""Mostra il bundle di personalizzazione (richiede login premium)."""
|
|
40
41
|
from lovarch_cli.ai import AiGatewayError, LovarchAiGateway
|
|
@@ -51,6 +52,12 @@ def show_command(
|
|
|
51
52
|
err_console.print(f"[red]✗ {exc}[/red]")
|
|
52
53
|
raise typer.Exit(1)
|
|
53
54
|
|
|
55
|
+
if as_json:
|
|
56
|
+
import json as _json
|
|
57
|
+
|
|
58
|
+
print(_json.dumps(bundle, ensure_ascii=False, indent=2))
|
|
59
|
+
return
|
|
60
|
+
|
|
54
61
|
summary = bundle.get("context_summary", {})
|
|
55
62
|
table = Table(title="Contesto AI — cosa viene usato per personalizzare",
|
|
56
63
|
show_header=True, header_style="bold gold1")
|
|
@@ -118,3 +118,73 @@ def copy_command(
|
|
|
118
118
|
rest = {k: v for k, v in out.items() if k not in ("caption", "hashtags")}
|
|
119
119
|
if rest:
|
|
120
120
|
console.print_json(json.dumps(rest, ensure_ascii=False))
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@do_app.command("logo")
|
|
124
|
+
def logo_command(
|
|
125
|
+
prompt: str = typer.Argument(..., help="Descrizione del logo / brand."),
|
|
126
|
+
output: Path = typer.Option(Path("logo.png"), "--output", "-o"),
|
|
127
|
+
ref: Path = typer.Option(None, "--ref", help="Immagine di riferimento."),
|
|
128
|
+
language: str = typer.Option(None, "--language"),
|
|
129
|
+
) -> None:
|
|
130
|
+
"""Logo pack del brand via piattaforma."""
|
|
131
|
+
from lovarch_cli.mcp.tools import tool_logo
|
|
132
|
+
|
|
133
|
+
out = asyncio.run(tool_logo(_workflows(), prompt=prompt, output_path=str(output),
|
|
134
|
+
reference_image_path=str(ref) if ref else None, language=_lang(language)))
|
|
135
|
+
if not out.get("ok"):
|
|
136
|
+
err_console.print(f"[red]✗ {out.get('error')}[/red]"); raise typer.Exit(1)
|
|
137
|
+
if out.get("saved_to"):
|
|
138
|
+
console.print(f"[green]✓[/green] Logo: [bold]{out['saved_to']}[/bold]")
|
|
139
|
+
if out.get("image_url"):
|
|
140
|
+
console.print(f"[dim]Nel tuo account: {out['image_url']}[/dim]")
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@do_app.command("site")
|
|
144
|
+
def site_command(
|
|
145
|
+
prompt: str = typer.Argument(..., help="Descrizione del sito web."),
|
|
146
|
+
output: Path = typer.Option(Path("site.html"), "--output", "-o"),
|
|
147
|
+
language: str = typer.Option(None, "--language"),
|
|
148
|
+
) -> None:
|
|
149
|
+
"""Genera un sito web (HTML) via piattaforma."""
|
|
150
|
+
from lovarch_cli.mcp.tools import tool_site
|
|
151
|
+
|
|
152
|
+
out = asyncio.run(tool_site(_workflows(), prompt=prompt, output_path=str(output), language=_lang(language)))
|
|
153
|
+
if not out.get("ok"):
|
|
154
|
+
err_console.print(f"[red]✗ {out.get('error')}[/red]"); raise typer.Exit(1)
|
|
155
|
+
console.print(f"[green]✓[/green] Sito: [bold]{out['saved_to']}[/bold] ({out.get('bytes', 0)} bytes)")
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@do_app.command("script")
|
|
159
|
+
def script_command(
|
|
160
|
+
topic: str = typer.Argument(..., help="Argomento dello script."),
|
|
161
|
+
type: str = typer.Option("reel", "--type", help="reel | post | carousel | video…"),
|
|
162
|
+
goal: str = typer.Option("educare", "--goal", help="Obiettivo del contenuto."),
|
|
163
|
+
tone: str = typer.Option("professionale", "--tone", help="Tono di voce."),
|
|
164
|
+
cta: str = typer.Option("", "--cta", help="Call-to-action."),
|
|
165
|
+
output: Path = typer.Option(None, "--output", "-o", help="Salva lo script su file."),
|
|
166
|
+
language: str = typer.Option(None, "--language"),
|
|
167
|
+
) -> None:
|
|
168
|
+
"""Script di contenuto strutturato via piattaforma (addebita crediti)."""
|
|
169
|
+
wf = _workflows()
|
|
170
|
+
from lovarch_cli.workflows import WorkflowError
|
|
171
|
+
|
|
172
|
+
try:
|
|
173
|
+
s = asyncio.run(wf.script(topic, type=type, goal=goal, tone=tone, cta=cta,
|
|
174
|
+
language=_lang(language)))
|
|
175
|
+
except WorkflowError as exc:
|
|
176
|
+
err_console.print(f"[red]✗ {exc}[/red]"); raise typer.Exit(1)
|
|
177
|
+
|
|
178
|
+
title = s.get("title") or topic
|
|
179
|
+
content = s.get("content") or ""
|
|
180
|
+
console.print(f"\n[bold gold1]{title}[/bold gold1]\n")
|
|
181
|
+
if content:
|
|
182
|
+
console.print(content)
|
|
183
|
+
if s.get("keywords"):
|
|
184
|
+
console.print("\n[dim]" + " ".join(s["keywords"]) + "[/dim]")
|
|
185
|
+
if not s.get("persisted", True):
|
|
186
|
+
console.print("\n[yellow]⚠ Non salvato nel tuo account (crediti rimborsati).[/yellow]")
|
|
187
|
+
if output:
|
|
188
|
+
Path(output).expanduser().write_text(content or title, encoding="utf-8")
|
|
189
|
+
console.print(f"\n[green]✓[/green] salvato: {output}")
|
|
190
|
+
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""`lovarch mcp` — run the Lovarch MCP server.
|
|
2
|
+
|
|
3
|
+
The heavy ``mcp`` SDK import is lazy (inside the command) so that
|
|
4
|
+
``lovarch --help`` and every other command keep working even when the optional
|
|
5
|
+
``[mcp]`` extra is not installed.
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import typer
|
|
10
|
+
|
|
11
|
+
mcp_app = typer.Typer(
|
|
12
|
+
help="Server MCP di Lovarch (per Claude Code / IDE). Richiede l'extra [mcp].",
|
|
13
|
+
no_args_is_help=True,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@mcp_app.command("serve")
|
|
18
|
+
def serve_command() -> None:
|
|
19
|
+
"""Avvia il server MCP su stdio.
|
|
20
|
+
|
|
21
|
+
Registra in Claude Code con:
|
|
22
|
+
claude mcp add lovarch -- lovarch mcp serve
|
|
23
|
+
"""
|
|
24
|
+
from lovarch_cli.mcp.server import serve
|
|
25
|
+
|
|
26
|
+
serve()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@mcp_app.command("key")
|
|
30
|
+
def key_command(
|
|
31
|
+
label: str = typer.Option(None, "--label", "-l", help="Etichetta della chiave (es. 'claude-code macbook')."),
|
|
32
|
+
revoke: str = typer.Option(None, "--revoke", help="ID di una chiave da revocare."),
|
|
33
|
+
list_keys: bool = typer.Option(False, "--list", help="Elenca le chiavi esistenti."),
|
|
34
|
+
) -> None:
|
|
35
|
+
"""Crea (o gestisce) una chiave di connessione per il MCP REMOTO
|
|
36
|
+
(https://mcp.lovarch.com/mcp). La chiave è mostrata UNA sola volta."""
|
|
37
|
+
import asyncio
|
|
38
|
+
|
|
39
|
+
from rich.console import Console
|
|
40
|
+
|
|
41
|
+
from lovarch_cli.auth.session import LovarchSession
|
|
42
|
+
|
|
43
|
+
console = Console()
|
|
44
|
+
err_console = Console(stderr=True)
|
|
45
|
+
|
|
46
|
+
session = LovarchSession.load()
|
|
47
|
+
if session is None:
|
|
48
|
+
err_console.print("[red]✗ Non autenticato. Esegui `lovarch login --premium`.[/red]")
|
|
49
|
+
raise typer.Exit(1)
|
|
50
|
+
|
|
51
|
+
async def _call(body: dict) -> dict:
|
|
52
|
+
resp = await session.request("POST", "/functions/v1/mcp-key-create", json=body)
|
|
53
|
+
try:
|
|
54
|
+
return resp.json()
|
|
55
|
+
except ValueError:
|
|
56
|
+
return {"ok": False, "error": f"HTTP {resp.status_code}"}
|
|
57
|
+
|
|
58
|
+
if list_keys:
|
|
59
|
+
data = asyncio.run(_call({"action": "list"}))
|
|
60
|
+
for k in data.get("keys", []):
|
|
61
|
+
state = "revocata" if k.get("revoked_at") else "attiva"
|
|
62
|
+
console.print(f" {k['id'][:8]} · {k.get('label') or '—'} · {state} · creata {str(k.get('created_at'))[:10]}")
|
|
63
|
+
if not data.get("keys"):
|
|
64
|
+
console.print("[dim]Nessuna chiave.[/dim]")
|
|
65
|
+
return
|
|
66
|
+
|
|
67
|
+
if revoke:
|
|
68
|
+
data = asyncio.run(_call({"action": "revoke", "key_id": revoke}))
|
|
69
|
+
if data.get("ok"):
|
|
70
|
+
console.print(f"[green]✓[/green] chiave revocata: {revoke}")
|
|
71
|
+
else:
|
|
72
|
+
err_console.print(f"[red]✗ {data.get('error')}[/red]")
|
|
73
|
+
raise typer.Exit(1)
|
|
74
|
+
return
|
|
75
|
+
|
|
76
|
+
data = asyncio.run(_call({"action": "create", "label": label}))
|
|
77
|
+
if not data.get("ok"):
|
|
78
|
+
err_console.print(f"[red]✗ {data.get('error')}[/red]")
|
|
79
|
+
raise typer.Exit(1)
|
|
80
|
+
console.print("\n[bold gold1]Chiave MCP creata[/bold gold1] [dim](mostrata solo ORA — salvala)[/dim]\n")
|
|
81
|
+
console.print(f" [bold]{data['key']}[/bold]\n")
|
|
82
|
+
console.print("Collega a Claude Code:\n")
|
|
83
|
+
console.print(f" [cyan]claude mcp add lovarch --transport http {data.get('mcp_url', 'https://mcp.lovarch.com/mcp')} --header \"Authorization: Bearer {data['key']}\"[/cyan]\n")
|