Metadata-Version: 2.4
Name: magicbox-dk
Version: 0.0.1
Summary: Magicbox for help DigitalKin developpers.
Author-email: Alexandre TRESALLET <a.tresall@digitalkin.ai>
License-Expression: MIT
Keywords: digitalkin,magicbox,kin,sdk
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: typer>=0.25.1
Requires-Dist: pydantic>=2.13.4
Requires-Dist: pyyaml>=6.0.3
Requires-Dist: questionary>=2.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: jinja2>=3.1
Dynamic: license-file

# Magicbox

> **`dk`** — orchestrateur d'environnement de développement pour les services et archétypes DigitalKin.

Magicbox pilote **Docker Compose** à partir d'un **profil YAML par scénario de dev**. Une seule CLI (`dk`), un profil
décrit *ce que* vous voulez faire tourner (front, services, infra, archétypes, kins) et *comment* (version distante,
clone git, ou dépôt local), et Magicbox génère les composes, résout l'environnement, alloue les ports et démarre la
stack — le tout stocké hors du repo, dans le dossier de config standard de votre OS.

[![PyPI](https://img.shields.io/pypi/v/magicbox-dk.svg)](https://pypi.org/project/magicbox-dk/)
[![Python](https://img.shields.io/pypi/pyversions/magicbox-dk.svg)](https://pypi.org/project/magicbox-dk/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](#license)

---

## Sommaire

- [Pourquoi Magicbox](#pourquoi-magicbox)
- [Installation](#installation)
- [Démarrage rapide](#démarrage-rapide)
- [Concepts](#concepts)
- [Commandes](#commandes)
- [Organisation des fichiers (`config_root`)](#organisation-des-fichiers-config_root)
- [Le profil](#le-profil)
- [Settings, globals & credentials](#settings-globals--credentials)
- [Multi-profils](#multi-profils)
- [Auth git](#auth-git)
- [Dépannage](#dépannage)
- [License](#license)

---

## Pourquoi Magicbox

Faire tourner la plateforme DigitalKin implique de coordonner plusieurs briques : un front (Chainlit ou Horizon), des
services applicatifs (`node-service-provider`, `back`), de l'infra (Redis, SurrealDB, S3), un ou plusieurs archétypes
(serveurs d'agents) et les kins (sessions de chat). Chaque brique peut pointer vers la **prod**, être **clonée depuis
git**, ou tourner depuis un **dépôt local** en cours de dev.

Magicbox encapsule tout ça derrière un seul workflow :

```
dk init → dk edit → dk prepare → dk start
```

- **Reproductible** — le profil est la seule source de vérité ; deux devs partagent un profil, obtiennent la même stack.
- **Isolé** — chaque profil a ses propres clones, composes et ports ; deux profils ne se marchent jamais dessus.
- **Sans secret dans le repo** — profils, settings et credentials vivent dans votre dossier de config OS, pas dans le
  code.

---

## Installation

```bash
pip install magicbox-dk
```

La CLI expose deux entrypoints équivalents : **`dk`** (court) et **`digitalkin`**. Python **≥ 3.10** requis, et un démon
**Docker** avec le plugin **Compose v2** en état de marche (`dk doctor` vérifie tout ça).

### Depuis les sources (dev)

Le projet est géré avec [`uv`](https://docs.astral.sh/uv/) :

```bash
uv sync                 # résout les dépendances depuis uv.lock
uv pip install -e .     # expose l'entrypoint `dk` en mode éditable
```

---

## Démarrage rapide

```bash
dk init                  # bootstrap : structure utilisateur + profil « Default »
dk edit                  # édite le profil (menus interactifs)
dk prepare               # clone les remotes, génère les composes, écrit network.yml
dk start                 # régénère les <entry>.env (live) + docker compose up -d
dk status                # état des conteneurs, section par section
dk stop                  # docker compose down + supprime les .env
```

Sans sous-commande, `dk` affiche le **tableau de bord** (profil actif, liste des profils, commandes clés).

---

## Concepts

| Terme         | Ce que c'est                                                                                                       |
|---------------|--------------------------------------------------------------------------------------------------------------------|
| **Profil**    | Un scénario de dev complet, décrit en YAML. Identifié par un id court (6 hex) + un libellé.                        |
| **Entrée**    | Un élément exécutable du profil : frontend, service, infra, archétype, tool ou kin.                                |
| **Mode**      | Comment une entrée tourne : `remote` (prod), `git` (clone + build), `dev` (dépôt local). Infra : `local`/`remote`. |
| **`prepare`** | Étape sans effet runtime : valide, clone, alloue les ports, génère les composes + `network.yml`.                   |
| **`start`**   | Régénère les `.env` à partir des sources, puis `docker compose up -d` + attente des healthchecks.                  |
| **Actif**     | Le profil ciblé par défaut quand vous ne passez pas de nom. Changé avec `dk switch`.                               |
| **Préparé**   | Un profil dont le dossier `composes/` existe (`dk prepare` l'a créé).                                              |

---

## Commandes

Tous les alias sont interchangeables (`dk rm` == `dk delete`). Le nom de profil est toujours **optionnel** : sans lui,
la commande cible le **profil actif** (`dk status dev` cible ponctuellement `dev`).

### Cycle de vie

| Commande                       | Rôle                                                                                                   |
|--------------------------------|--------------------------------------------------------------------------------------------------------|
| `dk init`                      | Bootstrap : crée `<config_root>/profiles`, `settings.yaml`, un profil par défaut. **Idempotent**.      |
| `dk create [name]`             | Crée un nouveau profil à partir du template `profile.base.yaml`.                                       |
| `dk delete, rm <name>`         | Supprime un profil (et ses clones) définitivement.                                                     |
| `dk prepare [profile]`         | Valide le YAML, clone les remotes, alloue les ports, génère les composes, écrit `network.yml`.         |
| `dk start, run, up [profile]`  | Régénère les `<entry>.env` (live) + `docker compose up -d` + attend les healthchecks.                  |
| `dk stop, down [profile]`      | `docker compose down --remove-orphans` + supprime les `.env`. `--all` arrête toutes les stacks.        |
| `dk restart, reload [profile]` | `stop` puis `start`.                                                                                   |
| `dk clean [profile]`           | Tear-down Docker + purge images / clones / composes. `--all` pour tous, `--env` inclut le dossier env. |
| `dk switch <name>`             | Change le profil actif.                                                                                |
| `dk update [name...]`          | `git pull --ff-only` sur les clones du profil actif.                                                   |

### Édition

| Commande                | Rôle                                                                                        |
|-------------------------|---------------------------------------------------------------------------------------------|
| `dk edit [profile]`     | Éditeur interactif du profil (menus navigables) : front, services, infra, archétypes, kins. |
| `dk settings`           | Édite les settings globaux (env globales, start, ports, timeouts, docker, infra).           |
| `dk env`                | Raccourci vers l'éditeur des variables d'env globales (`settings.env`).                     |
| `dk credentials, creds` | Édite les credentials infra partagés (SurrealDB logins / S3 accounts).                      |

### Inspection & utilitaires

| Commande                   | Rôle                                                                             |
|----------------------------|----------------------------------------------------------------------------------|
| `dk dashboard`             | Tableau de bord : profil actif, liste des profils, commandes clés (défaut).      |
| `dk list, ls`              | Liste les profils avec marqueurs d'état. Supporte `--json`.                      |
| `dk show, info [profile]`  | Vue compacte de la config d'un profil. Supporte `--json`.                        |
| `dk status, stats, ps`     | État des conteneurs, section par section.                                        |
| `dk logs [service]`        | `docker compose logs`.                                                           |
| `dk shell, exec <service>` | Ouvre un shell dans un conteneur du profil actif (`/bin/bash`, sinon `/bin/sh`). |
| `dk validate [profile]`    | Valide le YAML (Pydantic), sans effet de bord.                                   |
| `dk doctor`                | Vérifie Docker, Compose, git et la structure utilisateur.                        |
| `dk version`               | Affiche la version de Magicbox.                                                  |

> Toutes les commandes (sauf `init` et `doctor`) s'arrêtent si la structure utilisateur n'existe pas — un message invite
> à lancer `dk init`.
>
> Ajoutez **`-d`** (ou `--debug`) à n'importe quelle commande pour voir les étapes internes et les commandes docker/git
> exécutées (secrets masqués).

---

## Organisation des fichiers (`config_root`)

Tout l'état côté utilisateur vit dans le dossier de config standard de l'OS :

| OS      | `config_root`                               |
|---------|---------------------------------------------|
| macOS   | `~/Library/Application Support/digitalkin/` |
| Linux   | `~/.config/digitalkin/`                     |
| Windows | `%APPDATA%\digitalkin\`                     |

```
<config_root>/
├── profiles/<profile_id>/     ← un dossier par profil (profile_id = id court 6 hex)
│   ├── profile.yaml           ← la spec du profil (source de vérité)
│   ├── composes/              ← overrides docker-compose générés par `dk prepare`
│   ├── env/                   ← env par entrée : <entry>.yml (source) + <entry>.env (aplati)
│   ├── repos/                 ← clones git du profil (un dossier par entrée git)
│   └── network.yml            ← host/port/url résolus de chaque service (généré par `dk prepare`)
├── settings.yaml              ← settings core (profil actif, ports, timeouts, docker, start)
├── globals.yaml               ← variables d'env globales, partagées entre profils
└── credentials.yaml           ← credentials infra partagés (surrealdb_logins + s3_accounts)
```

Points clés :

- **Les clones vivent *dans* chaque profil** (`<profile>/repos/`) — deux profils qui pointent le même dépôt ne se
  partagent pas un clone potentiellement checkout sur des refs incompatibles. Supprimer un profil emporte ses clones.
- **L'env par entrée est scindé en deux fichiers** :
  - `<profile>/env/<entry>.yml` — **source de vérité**, éditée via `dk edit → Edit env`. Catégorisée (secret /
    connection / other) + un bloc `network:` en lecture seule reflétant les adresses des autres services.
  - `<profile>/env/<entry>.env` — **artefact transitoire** régénéré par `dk start` (merge source + template +
    `network.yml` + globals + credentials + résolution Jinja), consommé comme `env_file:` par Compose, **supprimé par
    `dk stop`**.
- **Conséquence pratique** : tout changement dans `dk settings` / `dk edit` est pris en compte au prochain `dk start`,
  sans re-lancer `dk prepare`.
- **`dk clean`** purge `composes/`, `repos/` et les `.env` aplatis ; il **préserve** les sources `.yml` (les secrets
  saisis survivent à un `clean` → `prepare`). Seuls `dk clean --env` ou `dk delete` suppriment tout le dossier `env/`.

> Aucun secret irremplaçable ne vit ici : c'est de la config régénérable. Un `rm -rf <config_root>` suivi de `dk init`
> repart de zéro proprement.

---

## Le profil

Un profil déclare un bloc méta (`profile:` — nom, description) puis les clés racine :
`frontend`, `node-service-provider`, `back`, `infra`, `archetypes`, `tools`, `kins`.

### Mode unifié — `remote` / `git` / `dev`

Chaque élément exécutable (frontend Horizon, services, archétypes, tools) porte un seul `mode` :

- **`remote`** — utilise une version en prod / managée ; seul `endpoint` est requis (référence à une variable de
  connexion globale).
- **`git`** — clone le dépôt et le build/run en local ; `ref` (branche). L'`url` est éditable pour les
  archétypes/tools ;
  pour les services et Horizon, le dépôt est prédéfini.
- **`dev`** — version locale ; `path` (chemin vers le dépôt local).

Les entrées d'infra (redis, surrealdb, s3) utilisent `local` / `remote` : `local` lance le conteneur préfabriqué,
`remote` résout son adresse depuis `settings.env.connection.<endpoint>`.

> Les services / infra / frontend sont **toujours actifs** dans un profil — pas de flag `enabled`, c'est le `mode` qui
> décide local vs externe. Seuls les **kins** gardent un `enabled` (activer/désactiver une session de chat sans la
> supprimer).

### Exemple

```yaml
profile:
  name: Default
  description: Profil full-local (sauf DB)

frontend:
  type: chainlit          # ou horizon (avec mode/ref)

node-service-provider:
  mode: remote
  endpoint: node-service-provider

back:
  mode: dev
  path: ~/dev/digitalkin/back

infra:
  redis:     { mode: local }
  surrealdb: { mode: remote, endpoint: surrealdb-prod }
  s3:        { mode: local }

archetypes:
  Template:
    mode: git
    url: git@github.com:DigitalKin-ai/template-archetype.git
    ref: dev
    endpoint: template
    module_id: modules:template
    sdk:
      source: pypi
      version: stable

tools: {}

kins:
  Template:
    enabled: true
    archetype: Template          # référence une clé de `archetypes`
    description: Kin de démarrage minimal tournant sur l'archetype Template.
    has_config_setup: false
```

La validation est **stricte** (`extra: forbid`) — toute clé inconnue fait échouer `dk prepare` / `dk validate`. La façon
recommandée d'éditer un profil reste `dk edit`.

---

## Settings, globals & credentials

Trois fichiers, chargés ensemble en un seul modèle Pydantic `Settings`, réécrits par `dk settings` :

- **`settings.yaml`** — settings core, éditables via `dk settings` :
  - **Env globals** — `secret` / `connection` / `other` partagés entre profils, consommables depuis n'importe quelle
    entrée via des références Jinja `{{ globals.NOM }}`.
  - **Start** — `attach` (est-ce que `dk start` suit les logs par défaut).
  - **Ports** — port hôte unique du front (`frontend_host`, défaut `8080`, partagé Chainlit/Horizon) + plage
    d'allocation
    des archétypes (`archetype_pool_start`/`_end`, défaut `50050-50070`).
  - **Timeouts** — poll/timeout des healthchecks, limite de restart, passes de résolution Jinja, timeout fetch git.
  - **Docker** — préfixes de nom conteneur/projet, montages de volumes.
- **`globals.yaml`** — le bloc d'env globales (`settings.env`), partagé entre profils. Éditable via `dk env`.
- **`credentials.yaml`** — credentials infra partagés (`surrealdb_logins` + `s3_accounts`), référencés par les services
  par leur nom de profil. Éditable via `dk credentials`.

Les défauts sont codés en dur : les fichiers YAML n'ont besoin que de surcharger ce qui diffère.

---

## Multi-profils

```bash
dk create dev            # crée un profil « dev » depuis le template
dk edit dev              # personnalise-le
dk prepare dev
dk switch dev            # en fait le profil actif
```

Surcharger le profil actif pour une seule commande : `dk status dev`, `dk start dev`, etc.

---

## Auth git

Magicbox délègue l'authentification au système : configurez votre credential helper (`osxkeychain`, `gh`, clé SSH dans
`~/.ssh/config`, …) **avant** de lancer `dk prepare`. Les URLs des profils ne contiennent jamais de secret.

---

## Dépannage

| Symptôme                      | Remède                                                                       |
|-------------------------------|------------------------------------------------------------------------------|
| Dépendances / structure KO    | `dk doctor` — diagnostique Docker, Compose, git et la structure utilisateur. |
| Profil corrompu               | `dk delete <profil>` puis `dk create`.                                       |
| Clones pollués                | `dk clean <profil>` puis `dk prepare`.                                       |
| Reset complet                 | `rm -rf <config_root>` puis `dk init` (aucun secret irremplaçable n'y vit).  |
| Comprendre ce qui se passe    | Ajouter `-d` / `--debug` : étapes internes + commandes docker/git échoées.   |
| Build BuildKit `EOF` (Colima) | Souvent un OOM de la VM Colima — augmenter sa RAM.                           |

---

## License

MIT — © DigitalKin.
