arclith-cli 0.20.0__tar.gz → 0.22.0__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.
Files changed (78) hide show
  1. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/PKG-INFO +91 -17
  2. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/README.md +89 -15
  3. arclith_cli-0.22.0/arclith_cli/__init__.py +1 -0
  4. arclith_cli-0.22.0/arclith_cli/adapter_blueprints.py +398 -0
  5. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/adapter_generator.py +95 -19
  6. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/adapter_selection.py +63 -1
  7. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/adapter_templates.py +6 -37
  8. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/add_adapter.py +39 -21
  9. arclith_cli-0.22.0/arclith_cli/binding_cli.py +65 -0
  10. arclith_cli-0.22.0/arclith_cli/binding_contract.py +287 -0
  11. arclith_cli-0.22.0/arclith_cli/binding_options.py +78 -0
  12. arclith_cli-0.22.0/arclith_cli/binding_rendering.py +187 -0
  13. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/capabilities.py +19 -1
  14. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/ai.py +0 -38
  15. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/persistence.py +4 -81
  16. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/repository_facets.py +3 -3
  17. arclith_cli-0.22.0/arclith_cli/catalogs/repository_postgresql.py +107 -0
  18. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/transports.py +2 -0
  19. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/core_scaffold.py +183 -40
  20. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/init_project.py +96 -33
  21. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/main.py +70 -10
  22. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/new_project.py +39 -0
  23. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/recipe.py +20 -1
  24. arclith_cli-0.22.0/arclith_cli/scaffold_interactive.py +105 -0
  25. arclith_cli-0.22.0/arclith_cli/scaffold_templates.py +140 -0
  26. arclith_cli-0.22.0/arclith_cli/templates/adapters/agent/agent.py.tmpl +10 -0
  27. arclith_cli-0.22.0/arclith_cli/templates/adapters/agent/context.py.tmpl +10 -0
  28. arclith_cli-0.22.0/arclith_cli/templates/adapters/agent/dependencies.py.tmpl +5 -0
  29. arclith_cli-0.22.0/arclith_cli/templates/adapters/agent/graph.py.tmpl +19 -0
  30. arclith_cli-0.22.0/arclith_cli/templates/adapters/agent/nodes/example.py.tmpl +12 -0
  31. arclith_cli-0.22.0/arclith_cli/templates/adapters/agent/state.py.tmpl +11 -0
  32. arclith_cli-0.22.0/arclith_cli/templates/adapters/api/register.py.tmpl +10 -0
  33. arclith_cli-0.22.0/arclith_cli/templates/adapters/api/routers/v1/router.py.tmpl +5 -0
  34. arclith_cli-0.22.0/arclith_cli/templates/adapters/command-bus/consumer.py.tmpl +5 -0
  35. arclith_cli-0.22.0/arclith_cli/templates/adapters/command-bus/register.py.tmpl +7 -0
  36. arclith_cli-0.22.0/arclith_cli/templates/adapters/mcp/register.py.tmpl +10 -0
  37. arclith_cli-0.22.0/arclith_cli/usecase_binding.py +397 -0
  38. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/pyproject.toml +3 -2
  39. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/e2e_manual.sh +1 -1
  40. arclith_cli-0.22.0/tests/test_adapter_blueprints.py +216 -0
  41. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_add_adapter.py +96 -40
  42. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_capabilities.py +2 -2
  43. arclith_cli-0.22.0/tests/test_core_scaffold.py +617 -0
  44. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_e2e_scaffold.py +5 -5
  45. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_embedding_capability.py +3 -3
  46. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_recipe.py +24 -4
  47. arclith_cli-0.22.0/tests/test_scaffold_cli.py +292 -0
  48. arclith_cli-0.22.0/tests/test_usecase_binding.py +497 -0
  49. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_vector_store_capability.py +1 -1
  50. arclith_cli-0.22.0/uv.lock +2811 -0
  51. arclith_cli-0.20.0/arclith_cli/__init__.py +0 -1
  52. arclith_cli-0.20.0/tests/test_core_scaffold.py +0 -248
  53. arclith_cli-0.20.0/uv.lock +0 -1420
  54. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/.gitignore +0 -0
  55. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/LICENSE +0 -0
  56. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/Makefile +0 -0
  57. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/adapter_config.py +0 -0
  58. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/adapter_parameters.py +0 -0
  59. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/adapter_rendering.py +0 -0
  60. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/capability_models.py +0 -0
  61. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/__init__.py +0 -0
  62. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/channels.py +0 -0
  63. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/core.py +0 -0
  64. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/observability.py +0 -0
  65. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/catalogs/security.py +0 -0
  66. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/entity_scanner.py +0 -0
  67. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/export_config.py +0 -0
  68. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/project_paths.py +0 -0
  69. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/recipe_cli.py +0 -0
  70. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/recipe_models.py +0 -0
  71. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/rename.py +0 -0
  72. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/runtime_templates.py +0 -0
  73. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/scaffold.py +0 -0
  74. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/arclith_cli/updater.py +0 -0
  75. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/__init__.py +0 -0
  76. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_adapter_templates.py +0 -0
  77. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_project_paths.py +0 -0
  78. {arclith_cli-0.20.0 → arclith_cli-0.22.0}/tests/test_rename.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: arclith-cli
3
- Version: 0.20.0
3
+ Version: 0.22.0
4
4
  Summary: CLI scaffolding tool for arclith — hexagonal architecture framework
5
5
  Author-email: Killian KOPP <killiankopp@gmail.com>
6
6
  License: Apache License
@@ -186,7 +186,7 @@ License: Apache License
186
186
  License-File: LICENSE
187
187
  Keywords: arclith,cli,ddd,hexagonal-architecture,scaffold
188
188
  Requires-Python: >=3.13
189
- Requires-Dist: arclith>=0.23.0
189
+ Requires-Dist: arclith>=0.25.0
190
190
  Requires-Dist: httpx>=0.27.0
191
191
  Requires-Dist: rich>=13.0.0
192
192
  Requires-Dist: typer>=0.15.0
@@ -194,7 +194,9 @@ Description-Content-Type: text/markdown
194
194
 
195
195
  # arclith-cli
196
196
 
197
- `arclith-cli` génère instantanément un projet Python en architecture hexagonale prêt à démarrer, en téléchargeant le template officiel `_sample` depuis GitHub et en remplaçant l'entité de démo `Ingredient` par le nom de votre choix. Tout type de projet peut être scaffoldé — service REST, agent IA, API MCP — avec les ports, le nom de projet et le backend de persistance configurés d'emblée.
197
+ `arclith-cli` construit un projet Python hexagonal par étapes. `init` pose uniquement le socle
198
+ installable ; chaque adapter, transport et dépendance optionnelle est ensuite ajouté explicitement.
199
+ `new` reste disponible pour générer un projet depuis le template officiel `_sample`.
198
200
 
199
201
  ## Installation
200
202
 
@@ -204,6 +206,8 @@ uv tool install "git+https://github.com/karned-rekipe/arclith.git#subdirectory=c
204
206
 
205
207
  ## Commandes
206
208
 
209
+ Exécuter `arclith-cli` sans argument affiche cette liste de commandes et termine sans erreur.
210
+
207
211
  ### `init` — Initialiser un projet minimal
208
212
 
209
213
  Crée un projet Arclith vide de métier, avec le layout canonique `src/<package>/...`, une
@@ -221,6 +225,39 @@ arclith-cli init todo-list-service --dir ~/projects
221
225
 
222
226
  Cette commande ne crée aucune entité, aucun CRUD et aucun endpoint métier. Elle sert quand on veut
223
227
  construire le projet étape par étape avec `add-entity`, `add-usecase`, puis `add-adapter`.
228
+ Elle ne crée pas non plus FastAPI ou FastMCP et n'installe aucun de leurs extras.
229
+
230
+ #### Pourquoi `src/<package>/...` ?
231
+
232
+ `src/` est la racine des imports du projet installé ; `<package>` est le namespace propre au
233
+ service. Les couches restent donc importées comme `todo_service.domain` ou
234
+ `todo_service.application`, au lieu de créer des packages Python globaux et génériques nommés
235
+ `domain`, `application` et `adapters`. Cette structure évite les collisions, empêche les tests
236
+ d'importer accidentellement le dépôt courant à la place du package installé et suit le `src layout`
237
+ standard de l'écosystème Python.
238
+
239
+ #### Parcours complet vers une API
240
+
241
+ ```bash
242
+ arclith-cli init todo-api
243
+ cd todo-api
244
+ arclith-cli add-entity Todo
245
+ arclith-cli add-usecase CreateTodo --entity Todo
246
+
247
+ # Choisir explicitement la persistance et le transport utilisés.
248
+ arclith-cli add-adapter --capability repository --adapter memory --entity Todo --yes
249
+ arclith-cli add-adapter --capability api --adapter fastapi --yes
250
+
251
+ # Après avoir défini les champs et implémenté CreateTodoUseCase.execute :
252
+ arclith-cli expose-usecase create-todo --via fastapi --feature todos \
253
+ --path /v1/todos --method POST --status-code 201
254
+ uv sync
255
+ MODE=api uv run python main.py
256
+ ```
257
+
258
+ Le registre de binding généré reste à appeler depuis le composition root avec l'instance typée du
259
+ use case ; le CLI ne devine pas ses dépendances métier. Voir le
260
+ [guide des bindings](https://karned-rekipe.github.io/arclith/deep-dives/use-case-bindings/).
224
261
 
225
262
  ---
226
263
 
@@ -252,7 +289,10 @@ template est régénéré côté CLI pour appliquer le contrat `runtime/docker-i
252
289
 
253
290
  ### `add-entity` — Ajouter une entité métier
254
291
 
255
- Crée uniquement le fichier minimal d'une entité dans `src/<package>/domain/models/`.
292
+ Crée un squelette minimal et guidé dans `src/<package>/domain/models/`. Le fichier
293
+ signale où déclarer les champs et invariants, rappelle les champs déjà fournis par
294
+ `Entity` et renvoie vers les guides Arclith et Pydantic. L'exemple `Field(...)`
295
+ reste commenté, donc aucun import inutilisé n'est ajouté.
256
296
 
257
297
  ```bash
258
298
  cd my-recipe-service
@@ -265,21 +305,41 @@ Fichier généré :
265
305
  src/<package>/domain/models/shopping_item.py
266
306
  ```
267
307
 
268
- La commande ne génère aucun CRUD, aucun port repository, aucun adapter et aucun endpoint. Elle pose seulement le point d'ancrage du modèle métier ; le développeur complète ensuite les champs et invariants de l'entité.
308
+ La commande ne génère aucun CRUD, aucun port repository, aucun adapter et aucun
309
+ endpoint. Elle pose seulement le point d'ancrage du modèle métier ; le
310
+ développeur complète ensuite les champs et invariants de l'entité.
269
311
 
270
312
  ---
271
313
 
272
314
  ### `add-usecase` — Ajouter un cas d'usage
273
315
 
274
- Crée le port inbound minimal dans `src/<package>/domain/ports/inbound/`, puis le fichier minimal du
275
- cas d'usage dans `src/<package>/application/use_cases/`.
316
+ Crée un port inbound guidé dans `src/<package>/domain/ports/inbound/`, puis le
317
+ cas d'usage dans `src/<package>/application/use_cases/`. Sans option de liaison,
318
+ la commande interactive propose les entités détectées par analyse AST, la
319
+ création d'une nouvelle entité ou un cas d'usage transverse.
276
320
 
277
321
  ```bash
278
322
  cd my-recipe-service
323
+
324
+ # Mode interactif : choisir une entité détectée, en créer une ou rester transverse
279
325
  arclith-cli add-usecase PlanShoppingList
280
- arclith-cli add-usecase find-by-name
326
+
327
+ # Modes directs, complets pour les agents et la CI
328
+ arclith-cli add-usecase CreateTodo --entity Todo
329
+ arclith-cli add-usecase CreateRecipe --new-entity Recipe
330
+ arclith-cli add-usecase RunMaintenance --no-entity
281
331
  ```
282
332
 
333
+ | Option | Effet |
334
+ |---|---|
335
+ | `--entity Todo` | lie le use case à une entité détectée et échoue si elle est absente |
336
+ | `--new-entity Todo` | crée l'entité si nécessaire, puis génère le use case lié |
337
+ | `--no-entity` | génère un `Command`, un `Result` et un use case transverse sans repository |
338
+
339
+ Ces options sont mutuellement exclusives. `--new-entity` réutilise une entité
340
+ valide déjà présente, mais refuse un fichier homonyme qui ne déclare pas la
341
+ classe `Entity` attendue.
342
+
283
343
  Fichier généré :
284
344
 
285
345
  ```text
@@ -287,9 +347,17 @@ src/<package>/domain/ports/inbound/plan_shopping_list.py
287
347
  src/<package>/application/use_cases/plan_shopping_list.py
288
348
  ```
289
349
 
290
- Le nom peut être fourni en PascalCase, snake_case ou kebab-case. Le suffixe `UseCase` est normalisé : `PlanShoppingListUseCase` et `plan-shopping-list-use-case` génèrent tous les deux `PlanShoppingListUseCase`.
350
+ Le nom peut être fourni en PascalCase, snake_case ou kebab-case. Le suffixe
351
+ `UseCase` est normalisé : `PlanShoppingListUseCase` et
352
+ `plan-shopping-list-use-case` génèrent tous les deux
353
+ `PlanShoppingListUseCase`.
291
354
 
292
- Comme `add-entity`, cette commande ne câble pas FastAPI, FastMCP, LangGraph, un repository ou un service. Les adapters se branchent ensuite explicitement avec `add-adapter` et devraient dépendre du port inbound généré.
355
+ Pour une entité principale, le squelette injecte explicitement
356
+ `Repository[Entity]` et type `execute` avec un `Command` Pydantic et l'entité en
357
+ retour. Le mode transverse génère plutôt un `Command` et un `Result` Pydantic,
358
+ sans repository implicite. Aucun mode ne câble FastAPI, FastMCP ou LangGraph.
359
+ Les exemples complets et les règles de séparation sont dans le
360
+ [deep dive du scaffold CLI](https://karned-rekipe.github.io/arclith/deep-dives/cli-scaffold/).
293
361
 
294
362
  ---
295
363
 
@@ -319,7 +387,9 @@ logique métier.
319
387
 
320
388
  ### `add-adapter` — Ajouter un adapter
321
389
 
322
- Wizard interactif à lancer **depuis la racine du projet cible**. Scaffold le code Python et/ou les fichiers de configuration pour un nouvel adapter. Par défaut, la capacité cible est `repository`.
390
+ Wizard interactif à lancer **depuis la racine du projet cible**. Sans option, il affiche toutes les
391
+ capabilities et leurs adapters, notamment `api/fastapi` et `mcp/fastmcp`, puis demande le choix.
392
+ Il scaffold uniquement le code, la configuration et l'extra de dépendance du choix effectué.
323
393
 
324
394
  ```bash
325
395
  cd my-recipe-service
@@ -346,9 +416,10 @@ arclith-cli add-adapter --capability repository --adapter memory --entity Recipe
346
416
 
347
417
  **Étapes du wizard :**
348
418
 
349
- 1. **Type d'adapter** — selon la capacité : `memory` · `mongodb` · `duckdb` · `mariadb` · `fastapi` · `fastmcp` · `rabbitmq` · `docker-image` · `lmstudio` · `openai` · `anthropic` · `langgraph` · `langsmith` · `opentelemetry`
350
- 2. **Entité(s) cible(s)** — détectées automatiquement pour les adapters entity-scoped ; ignorées pour les transports globaux, `cache/*`, `llm/*`, `agent/langgraph`, `runtime/docker-image` et les adapters d'observability
351
- 3. **Paramètres** — questions spécifiques à l'adapter :
419
+ 1. **Capability** — toutes les capabilities du catalogue sont proposées avec leurs adapters
420
+ 2. **Type d'adapter** — selon la capability : `memory` · `mongodb` · `duckdb` · `mariadb` · `fastapi` · `fastmcp` · `rabbitmq` · `docker-image` · `lmstudio` · `openai` · `anthropic` · `langgraph` · `langsmith` · `opentelemetry`
421
+ 3. **Entité(s) cible(s)** — détectées automatiquement pour les adapters entity-scoped ; ignorées pour les transports globaux, `cache/*`, `llm/*`, `agent/langgraph`, `runtime/docker-image` et les adapters d'observability
422
+ 4. **Paramètres** — questions spécifiques à l'adapter :
352
423
  - `mongodb` → `db_name`, `collection_name`, `multitenant`
353
424
  - `duckdb` → `path`
354
425
  - `mariadb` → `host`, `port`, `database`, `user`, `driver`, `table_prefix`
@@ -366,12 +437,12 @@ arclith-cli add-adapter --capability repository --adapter memory --entity Recipe
366
437
  - `command-bus/rabbitmq` → `url`, `exchange`, `exchange_type`, `queue`, `routing_key`, `prefetch`, `consumer_name`, `concurrency`, `publisher_confirms`, `durable`, `retry_enabled`, `retry_requeue`, `dead_letter_exchange`, `dead_letter_routing_key`
367
438
  - `runtime/docker-image` → `uv_version`, `api_port`, `mcp_port`, `probe_port`, `agent_port`
368
439
  - `repository/memory` → aucun paramètre
369
- 4. **Activation** — met à jour `config/adapters/adapters.yaml` pour les capacités activables (`repository: <adapter>` ou `observability.enabled: [<adapter>, ...]`) ; `api/fastapi`, `mcp/fastmcp`, `cache/*`, `llm/*`, `agent/langgraph`, `command-bus/rabbitmq` et `runtime/docker-image` sont exposés par leurs fichiers dédiés
370
- 5. **Récapitulatif** — liste des fichiers créés ou remplacés avant confirmation
440
+ 5. **Activation** — met à jour `config/adapters/adapters.yaml` pour les capacités activables (`repository: <adapter>` ou `observability.enabled: [<adapter>, ...]`) ; `api/fastapi`, `mcp/fastmcp`, `cache/*`, `llm/*`, `agent/langgraph`, `command-bus/rabbitmq` et `runtime/docker-image` sont exposés par leurs fichiers dédiés
441
+ 6. **Récapitulatif** — liste des fichiers créés ou remplacés avant confirmation
371
442
 
372
443
  | Option | Défaut | Description |
373
444
  |--------|--------|-------------|
374
- | `--capability` | `repository` | Capacité cible du catalogue standardisé (`repository`, `cache`, `api`, `mcp`, `http`, `command-bus`, `runtime`, `llm`, `agent`, `observability`) |
445
+ | `--capability` | interactif | Capacité cible du catalogue standardisé (`repository`, `cache`, `api`, `mcp`, `http`, `command-bus`, `runtime`, `llm`, `agent`, `observability`) |
375
446
  | `--adapter` / `-a` | interactif | Adapter du catalogue : `memory`, `mongodb`, `duckdb`, `mariadb`, `fastapi`, `fastmcp`, `idempotency`, `etag`, `cache-control`, `rabbitmq`, `docker-image`, `lmstudio`, `openai`, `anthropic`, `langgraph`, `langsmith`, `opentelemetry` |
376
447
  | `--entity` / `-e` | auto si une seule entité | Entité cible, liste séparée par virgule acceptée |
377
448
  | `--all-entities` | `false` | Génère l'adapter pour toutes les entités détectées |
@@ -430,6 +501,9 @@ LM Studio ou tout endpoint OpenAI-compatible avec `base_url`.
430
501
  L'adapter `repository/mongodb` génère `config/adapters/outbound/mongodb.yaml` avec `uri: null`, puis
431
502
  mappe `adapters.mongodb.uri` vers `MONGODB_URI` dans `config/secrets.yaml`. L'URI réelle reste dans
432
503
  l'environnement, un fichier local de secrets ou Vault selon le resolver choisi.
504
+ Il ne génère pas de repository `memory` applicatif. L'implémentation mémoire du framework peut être
505
+ utilisée directement dans des tests ; une spécialisation mémoire du projet n'est créée que par un
506
+ choix explicite de `repository/memory`.
433
507
 
434
508
  L'adapter `agent/langgraph` génère `langgraph.json`, `config/adapters/inbound/langgraph.yaml` et
435
509
  `src/<package>/adapters/inbound/langgraph/agent.py`. Le projet ne modifie ensuite que ce fichier pour
@@ -1,6 +1,8 @@
1
1
  # arclith-cli
2
2
 
3
- `arclith-cli` génère instantanément un projet Python en architecture hexagonale prêt à démarrer, en téléchargeant le template officiel `_sample` depuis GitHub et en remplaçant l'entité de démo `Ingredient` par le nom de votre choix. Tout type de projet peut être scaffoldé — service REST, agent IA, API MCP — avec les ports, le nom de projet et le backend de persistance configurés d'emblée.
3
+ `arclith-cli` construit un projet Python hexagonal par étapes. `init` pose uniquement le socle
4
+ installable ; chaque adapter, transport et dépendance optionnelle est ensuite ajouté explicitement.
5
+ `new` reste disponible pour générer un projet depuis le template officiel `_sample`.
4
6
 
5
7
  ## Installation
6
8
 
@@ -10,6 +12,8 @@ uv tool install "git+https://github.com/karned-rekipe/arclith.git#subdirectory=c
10
12
 
11
13
  ## Commandes
12
14
 
15
+ Exécuter `arclith-cli` sans argument affiche cette liste de commandes et termine sans erreur.
16
+
13
17
  ### `init` — Initialiser un projet minimal
14
18
 
15
19
  Crée un projet Arclith vide de métier, avec le layout canonique `src/<package>/...`, une
@@ -27,6 +31,39 @@ arclith-cli init todo-list-service --dir ~/projects
27
31
 
28
32
  Cette commande ne crée aucune entité, aucun CRUD et aucun endpoint métier. Elle sert quand on veut
29
33
  construire le projet étape par étape avec `add-entity`, `add-usecase`, puis `add-adapter`.
34
+ Elle ne crée pas non plus FastAPI ou FastMCP et n'installe aucun de leurs extras.
35
+
36
+ #### Pourquoi `src/<package>/...` ?
37
+
38
+ `src/` est la racine des imports du projet installé ; `<package>` est le namespace propre au
39
+ service. Les couches restent donc importées comme `todo_service.domain` ou
40
+ `todo_service.application`, au lieu de créer des packages Python globaux et génériques nommés
41
+ `domain`, `application` et `adapters`. Cette structure évite les collisions, empêche les tests
42
+ d'importer accidentellement le dépôt courant à la place du package installé et suit le `src layout`
43
+ standard de l'écosystème Python.
44
+
45
+ #### Parcours complet vers une API
46
+
47
+ ```bash
48
+ arclith-cli init todo-api
49
+ cd todo-api
50
+ arclith-cli add-entity Todo
51
+ arclith-cli add-usecase CreateTodo --entity Todo
52
+
53
+ # Choisir explicitement la persistance et le transport utilisés.
54
+ arclith-cli add-adapter --capability repository --adapter memory --entity Todo --yes
55
+ arclith-cli add-adapter --capability api --adapter fastapi --yes
56
+
57
+ # Après avoir défini les champs et implémenté CreateTodoUseCase.execute :
58
+ arclith-cli expose-usecase create-todo --via fastapi --feature todos \
59
+ --path /v1/todos --method POST --status-code 201
60
+ uv sync
61
+ MODE=api uv run python main.py
62
+ ```
63
+
64
+ Le registre de binding généré reste à appeler depuis le composition root avec l'instance typée du
65
+ use case ; le CLI ne devine pas ses dépendances métier. Voir le
66
+ [guide des bindings](https://karned-rekipe.github.io/arclith/deep-dives/use-case-bindings/).
30
67
 
31
68
  ---
32
69
 
@@ -58,7 +95,10 @@ template est régénéré côté CLI pour appliquer le contrat `runtime/docker-i
58
95
 
59
96
  ### `add-entity` — Ajouter une entité métier
60
97
 
61
- Crée uniquement le fichier minimal d'une entité dans `src/<package>/domain/models/`.
98
+ Crée un squelette minimal et guidé dans `src/<package>/domain/models/`. Le fichier
99
+ signale où déclarer les champs et invariants, rappelle les champs déjà fournis par
100
+ `Entity` et renvoie vers les guides Arclith et Pydantic. L'exemple `Field(...)`
101
+ reste commenté, donc aucun import inutilisé n'est ajouté.
62
102
 
63
103
  ```bash
64
104
  cd my-recipe-service
@@ -71,21 +111,41 @@ Fichier généré :
71
111
  src/<package>/domain/models/shopping_item.py
72
112
  ```
73
113
 
74
- La commande ne génère aucun CRUD, aucun port repository, aucun adapter et aucun endpoint. Elle pose seulement le point d'ancrage du modèle métier ; le développeur complète ensuite les champs et invariants de l'entité.
114
+ La commande ne génère aucun CRUD, aucun port repository, aucun adapter et aucun
115
+ endpoint. Elle pose seulement le point d'ancrage du modèle métier ; le
116
+ développeur complète ensuite les champs et invariants de l'entité.
75
117
 
76
118
  ---
77
119
 
78
120
  ### `add-usecase` — Ajouter un cas d'usage
79
121
 
80
- Crée le port inbound minimal dans `src/<package>/domain/ports/inbound/`, puis le fichier minimal du
81
- cas d'usage dans `src/<package>/application/use_cases/`.
122
+ Crée un port inbound guidé dans `src/<package>/domain/ports/inbound/`, puis le
123
+ cas d'usage dans `src/<package>/application/use_cases/`. Sans option de liaison,
124
+ la commande interactive propose les entités détectées par analyse AST, la
125
+ création d'une nouvelle entité ou un cas d'usage transverse.
82
126
 
83
127
  ```bash
84
128
  cd my-recipe-service
129
+
130
+ # Mode interactif : choisir une entité détectée, en créer une ou rester transverse
85
131
  arclith-cli add-usecase PlanShoppingList
86
- arclith-cli add-usecase find-by-name
132
+
133
+ # Modes directs, complets pour les agents et la CI
134
+ arclith-cli add-usecase CreateTodo --entity Todo
135
+ arclith-cli add-usecase CreateRecipe --new-entity Recipe
136
+ arclith-cli add-usecase RunMaintenance --no-entity
87
137
  ```
88
138
 
139
+ | Option | Effet |
140
+ |---|---|
141
+ | `--entity Todo` | lie le use case à une entité détectée et échoue si elle est absente |
142
+ | `--new-entity Todo` | crée l'entité si nécessaire, puis génère le use case lié |
143
+ | `--no-entity` | génère un `Command`, un `Result` et un use case transverse sans repository |
144
+
145
+ Ces options sont mutuellement exclusives. `--new-entity` réutilise une entité
146
+ valide déjà présente, mais refuse un fichier homonyme qui ne déclare pas la
147
+ classe `Entity` attendue.
148
+
89
149
  Fichier généré :
90
150
 
91
151
  ```text
@@ -93,9 +153,17 @@ src/<package>/domain/ports/inbound/plan_shopping_list.py
93
153
  src/<package>/application/use_cases/plan_shopping_list.py
94
154
  ```
95
155
 
96
- Le nom peut être fourni en PascalCase, snake_case ou kebab-case. Le suffixe `UseCase` est normalisé : `PlanShoppingListUseCase` et `plan-shopping-list-use-case` génèrent tous les deux `PlanShoppingListUseCase`.
156
+ Le nom peut être fourni en PascalCase, snake_case ou kebab-case. Le suffixe
157
+ `UseCase` est normalisé : `PlanShoppingListUseCase` et
158
+ `plan-shopping-list-use-case` génèrent tous les deux
159
+ `PlanShoppingListUseCase`.
97
160
 
98
- Comme `add-entity`, cette commande ne câble pas FastAPI, FastMCP, LangGraph, un repository ou un service. Les adapters se branchent ensuite explicitement avec `add-adapter` et devraient dépendre du port inbound généré.
161
+ Pour une entité principale, le squelette injecte explicitement
162
+ `Repository[Entity]` et type `execute` avec un `Command` Pydantic et l'entité en
163
+ retour. Le mode transverse génère plutôt un `Command` et un `Result` Pydantic,
164
+ sans repository implicite. Aucun mode ne câble FastAPI, FastMCP ou LangGraph.
165
+ Les exemples complets et les règles de séparation sont dans le
166
+ [deep dive du scaffold CLI](https://karned-rekipe.github.io/arclith/deep-dives/cli-scaffold/).
99
167
 
100
168
  ---
101
169
 
@@ -125,7 +193,9 @@ logique métier.
125
193
 
126
194
  ### `add-adapter` — Ajouter un adapter
127
195
 
128
- Wizard interactif à lancer **depuis la racine du projet cible**. Scaffold le code Python et/ou les fichiers de configuration pour un nouvel adapter. Par défaut, la capacité cible est `repository`.
196
+ Wizard interactif à lancer **depuis la racine du projet cible**. Sans option, il affiche toutes les
197
+ capabilities et leurs adapters, notamment `api/fastapi` et `mcp/fastmcp`, puis demande le choix.
198
+ Il scaffold uniquement le code, la configuration et l'extra de dépendance du choix effectué.
129
199
 
130
200
  ```bash
131
201
  cd my-recipe-service
@@ -152,9 +222,10 @@ arclith-cli add-adapter --capability repository --adapter memory --entity Recipe
152
222
 
153
223
  **Étapes du wizard :**
154
224
 
155
- 1. **Type d'adapter** — selon la capacité : `memory` · `mongodb` · `duckdb` · `mariadb` · `fastapi` · `fastmcp` · `rabbitmq` · `docker-image` · `lmstudio` · `openai` · `anthropic` · `langgraph` · `langsmith` · `opentelemetry`
156
- 2. **Entité(s) cible(s)** — détectées automatiquement pour les adapters entity-scoped ; ignorées pour les transports globaux, `cache/*`, `llm/*`, `agent/langgraph`, `runtime/docker-image` et les adapters d'observability
157
- 3. **Paramètres** — questions spécifiques à l'adapter :
225
+ 1. **Capability** — toutes les capabilities du catalogue sont proposées avec leurs adapters
226
+ 2. **Type d'adapter** — selon la capability : `memory` · `mongodb` · `duckdb` · `mariadb` · `fastapi` · `fastmcp` · `rabbitmq` · `docker-image` · `lmstudio` · `openai` · `anthropic` · `langgraph` · `langsmith` · `opentelemetry`
227
+ 3. **Entité(s) cible(s)** — détectées automatiquement pour les adapters entity-scoped ; ignorées pour les transports globaux, `cache/*`, `llm/*`, `agent/langgraph`, `runtime/docker-image` et les adapters d'observability
228
+ 4. **Paramètres** — questions spécifiques à l'adapter :
158
229
  - `mongodb` → `db_name`, `collection_name`, `multitenant`
159
230
  - `duckdb` → `path`
160
231
  - `mariadb` → `host`, `port`, `database`, `user`, `driver`, `table_prefix`
@@ -172,12 +243,12 @@ arclith-cli add-adapter --capability repository --adapter memory --entity Recipe
172
243
  - `command-bus/rabbitmq` → `url`, `exchange`, `exchange_type`, `queue`, `routing_key`, `prefetch`, `consumer_name`, `concurrency`, `publisher_confirms`, `durable`, `retry_enabled`, `retry_requeue`, `dead_letter_exchange`, `dead_letter_routing_key`
173
244
  - `runtime/docker-image` → `uv_version`, `api_port`, `mcp_port`, `probe_port`, `agent_port`
174
245
  - `repository/memory` → aucun paramètre
175
- 4. **Activation** — met à jour `config/adapters/adapters.yaml` pour les capacités activables (`repository: <adapter>` ou `observability.enabled: [<adapter>, ...]`) ; `api/fastapi`, `mcp/fastmcp`, `cache/*`, `llm/*`, `agent/langgraph`, `command-bus/rabbitmq` et `runtime/docker-image` sont exposés par leurs fichiers dédiés
176
- 5. **Récapitulatif** — liste des fichiers créés ou remplacés avant confirmation
246
+ 5. **Activation** — met à jour `config/adapters/adapters.yaml` pour les capacités activables (`repository: <adapter>` ou `observability.enabled: [<adapter>, ...]`) ; `api/fastapi`, `mcp/fastmcp`, `cache/*`, `llm/*`, `agent/langgraph`, `command-bus/rabbitmq` et `runtime/docker-image` sont exposés par leurs fichiers dédiés
247
+ 6. **Récapitulatif** — liste des fichiers créés ou remplacés avant confirmation
177
248
 
178
249
  | Option | Défaut | Description |
179
250
  |--------|--------|-------------|
180
- | `--capability` | `repository` | Capacité cible du catalogue standardisé (`repository`, `cache`, `api`, `mcp`, `http`, `command-bus`, `runtime`, `llm`, `agent`, `observability`) |
251
+ | `--capability` | interactif | Capacité cible du catalogue standardisé (`repository`, `cache`, `api`, `mcp`, `http`, `command-bus`, `runtime`, `llm`, `agent`, `observability`) |
181
252
  | `--adapter` / `-a` | interactif | Adapter du catalogue : `memory`, `mongodb`, `duckdb`, `mariadb`, `fastapi`, `fastmcp`, `idempotency`, `etag`, `cache-control`, `rabbitmq`, `docker-image`, `lmstudio`, `openai`, `anthropic`, `langgraph`, `langsmith`, `opentelemetry` |
182
253
  | `--entity` / `-e` | auto si une seule entité | Entité cible, liste séparée par virgule acceptée |
183
254
  | `--all-entities` | `false` | Génère l'adapter pour toutes les entités détectées |
@@ -236,6 +307,9 @@ LM Studio ou tout endpoint OpenAI-compatible avec `base_url`.
236
307
  L'adapter `repository/mongodb` génère `config/adapters/outbound/mongodb.yaml` avec `uri: null`, puis
237
308
  mappe `adapters.mongodb.uri` vers `MONGODB_URI` dans `config/secrets.yaml`. L'URI réelle reste dans
238
309
  l'environnement, un fichier local de secrets ou Vault selon le resolver choisi.
310
+ Il ne génère pas de repository `memory` applicatif. L'implémentation mémoire du framework peut être
311
+ utilisée directement dans des tests ; une spécialisation mémoire du projet n'est créée que par un
312
+ choix explicite de `repository/memory`.
239
313
 
240
314
  L'adapter `agent/langgraph` génère `langgraph.json`, `config/adapters/inbound/langgraph.yaml` et
241
315
  `src/<package>/adapters/inbound/langgraph/agent.py`. Le projet ne modifie ensuite que ce fichier pour
@@ -0,0 +1 @@
1
+ __version__ = "0.22.0"