SPB Git forge

spb/admin-ka

Public
41commits 1branches 0releases
172.9 MBsize
maindefault branch
19 days agolast push
JavaScript 65.5% Python 17.8% CSS 13% HTML 3.7%
23.4 KB · 334 lines markdown
Rendered Raw Blame History
1<p align="center">2  <img src="docs/screenshots/01-accueil.jpg" alt="Admin-Ka — écran de connexion" width="720">3</p>45<h1 align="center">Admin-Ka — administration-ka.com</h1>67<p align="center">8  <strong>Le Control Center du Groupe Ka.</strong><br>9  Console d'administration privée qui pilote le <em>vrai</em> Claude Code CLI sur le cluster MacLustr,<br>10  surveille les 19 sites de l'écosystème en temps réel et mesure le trafic humain de toutes les plateformes.11</p>1213<p align="center">14  <a href="https://www.administration-ka.com">www.administration-ka.com</a> · nœud <strong>M3U96a</strong> · port <strong>3300</strong> · launchd + ngrok15</p>1617---1819> **Console privée.** L'accès est protégé par un mot de passe d'application (haché scrypt, cookie de session HttpOnly/Secure). Il n'y a pas d'inscription : c'est l'outil interne d'exploitation du Groupe Ka. Aucun secret n'est présent dans ce dépôt — la configuration sensible vit dans `data/config.json` (non versionné) et la clé Anthropic est lue depuis `~/.claude/.env` sur le nœud.2021---2223## Sommaire24251. [C'est quoi, Admin-Ka ?](#cest-quoi-admin-ka-)262. [Visite guidée en 10 captures](#visite-guidée-en-10-captures)273. [Les modules, en détail](#les-modules-en-détail)28   - [Claude Code — pilotage du vrai CLI](#1-claude-code--pilotage-du-vrai-cli)29   - [Sessions — détachées, reprenables, rejouables](#2-sessions--détachées-reprenables-rejouables)30   - [Prompts — bibliothèque + upgradeur](#3-prompts--bibliothèque--upgradeur-de-prompts)31   - [Écosystème — monitoring 19 sites](#4-écosystème--monitoring-des-19-sites)32   - [Visiteurs — analytics v2 « humains d'abord »](#5-visiteurs--analytics-v2--trafic-humain)33   - [Vue d'ensemble — le cockpit](#6-vue-densemble--le-cockpit)34   - [Studio — module Social](#7-studio--module-social-facebook--reels)35   - [Gardiens KA Guardian (ka2 / ka4 / ka6)](#8-gardiens-ka-guardian-ka2--ka4--ka6)36   - [Écran du nœud (noVNC)](#9-écran-du-nœud-novnc)374. [Identité visuelle](#identité-visuelle)385. [Architecture](#architecture)396. [Modes de permission](#modes-de-permission)407. [Auth & sécurité](#auth--sécurité)418. [Structure du dépôt](#structure-du-dépôt)429. [Déploiement & exploitation](#déploiement--exploitation-sur-m3u96a)4310. [Apps natives compagnes](#apps-natives-compagnes)4411. [Contact](#contact)4546---4748## C'est quoi, Admin-Ka ?4950Admin-Ka est né comme une console chat mobile-first pour lancer **Claude Code** sur le nœud M3U96a depuis un iPhone. C'est devenu, au fil des versions (v2 puis **v3 « Control Center »**), le poste de commandement complet du Groupe Ka :5152```53iPhone / Mac ⇄ https://www.administration-ka.com (ngrok) ⇄ backend :3300 (M3U96a)54                                                              ├── claude CLI local (apps M3U96a)55                                                              ├── ssh <nœud> → claude CLI (apps distantes, repo de prod)56                                                              ├── monitor.js  → health checks 19 sites, sweep nœuds57                                                              ├── analytics.js → trafic humain des plateformes Ka58                                                              └── social.js  → Studio (posts FB, Reels, musique)59```6061**Principe fondateur — rien de simulé** : le chat parle au vrai binaire `claude` (jamais à l'API Messages pour coder), le monitoring frappe les vrais sites en HTTPS, les analytics comptent les vrais visiteurs, les actions d'admin exécutent de vrais `pm2 restart` / `git log` sur les nœuds.6263Un seul opérateur, dix-neuf sites, vingt nœuds : tout se pilote depuis cette page.6465---6667## Visite guidée en 10 captures6869> Les captures 03 à 10 montrent la console **connectée** (après authentification) ; les captures 01, 02 et le login mobile montrent ce que voit un visiteur non authentifié : un simple mot de passe, rien d'autre.7071### 01 — Écran de connexion (desktop)7273![Écran de connexion](docs/screenshots/01-accueil.jpg)7475La porte d'entrée : pastille « Ka » orange, un champ mot de passe, un bouton. Aucune information n'est exposée avant l'authentification — la mention discrète `M3U96a · MacLustr` rappelle seulement sur quel nœud la console tourne.7677### 02 — Écran de connexion (mobile)7879<img src="docs/screenshots/02-accueil-mobile.jpg" alt="Connexion mobile" width="390">8081Le même login, pensé iPhone d'abord : carte centrée, safe-areas respectées, champ à 16 px (anti-zoom iOS).8283### 03 — Console connectée : la Vue d'ensemble8485![Console connectée](docs/screenshots/03-console-connectee.jpg)8687Premier écran après connexion : le **cockpit**. Sidebar de navigation à gauche (Vue d'ensemble, Claude Code, Sessions, Prompts, Écosystème, Visiteurs, Studio, Réglages), KPIs en tuiles (humains en ligne / aujourd'hui, sessions, pages vues, **19/19 sites en ligne**, incidents, uptime 24 h, latence moyenne, sessions Claude actives, **coût Claude cumulé**), graphique « Visiteurs humains — 30 jours » avec l'ancienne série v1 en pointillé, chips d'état des 19 sites avec leur latence live, et le journal des incidents récents.8889### 04 — Onglet Sessions9091![Onglet Sessions](docs/screenshots/04-onglet-sessions.jpg)9293Toutes les conversations Claude Code, filtrables par recherche, application et statut. Chaque ligne affiche le premier prompt, l'app cible (ou « Orchestrateur multi-sites »), le modèle, la taille de contexte (`ctx`), le **coût en dollars** et l'ancienneté — avec un bouton **Reprendre** (le `--resume` du CLI, transcript rejoué) et une suppression.9495### 05 — Onglet Écosystème9697![Onglet Écosystème](docs/screenshots/05-onglet-ecosysteme.jpg)9899Le monitoring temps réel : bandeau global (19/19 en ligne, uptime 24 h, latence moyenne, 36,5 k checks/24 h, échecs, incidents), puis une carte par site — sparkline de latence, barre d'uptime, p95/p99, nombre de checks, et la ligne d'infrastructure : **nœud, état du process (pm2/launchd), âge du dernier commit, jours restants sur le certificat SSL**.100101### 06 — Console mobile102103<img src="docs/screenshots/06-console-mobile.jpg" alt="Console mobile" width="390">104105La même console sur iPhone : bottom nav 5 entrées (Vue d'ensemble, Claude Code, Écosystème, Visiteurs, Plus), cartes empilées, tout le contenu de l'Écosystème accessible au pouce. C'est l'usage d'origine d'Admin-Ka : administrer le groupe depuis n'importe où.106107### 07 — Vue d'ensemble (rafraîchie)108109![Vue d'ensemble](docs/screenshots/07-onglet-vue-d-ensemble.jpg)110111Le cockpit se met à jour en continu (horodatage `maj` en haut à droite) : latences recalculées à chaque cycle de checks, ligne de synthèse du filtrage de trafic du jour (ex. « 92 humains · trafic filtré : 51 149 crawler + 36 datacenter + 274 automation »), anomalies de la dernière heure.112113### 08 — Onglet Claude Code114115![Onglet Claude Code](docs/screenshots/08-onglet-claude-code.jpg)116117Le cœur historique : « **Le vrai Claude Code, lancé sur le nœud de chaque app du Groupe KA** ». Picker de cible (une app précise, ou **Tous les sites KA (20)** = mode orchestrateur multi-sites), choix du modèle et du mode de permissions, suggestions de démarrage, reprise en un tap des dernières sessions, et le champ « Demander à Claude Code… » avec son bouton d'envoi orange.118119### 09 — Onglet Prompts120121![Onglet Prompts](docs/screenshots/09-onglet-prompts.jpg)122123La bibliothèque de prompts réutilisables : chaque prompt a un titre, une app cible (ou « app au choix »), un aperçu, et quatre actions — **Lancer** (démarre une session Claude Code avec ce prompt), **✨ Améliorer** (l'upgradeur de prompts réécrit la demande via l'API Anthropic avec la connaissance du Groupe Ka injectée), **Éditer**, **Dupliquer**, plus favoris ★ et compteur d'usage.124125### 10 — Onglet Visiteurs126127![Onglet Visiteurs](docs/screenshots/10-onglet-visiteurs.jpg)128129Les analytics v2 : bascule **Humains / Tout le trafic**, KPIs (en ligne < 2 min, humains du jour avec variation vs hier, sessions, pages vues, uniques 7 j / 30 j), **barre de répartition par classe** (humains / crawlers / datacenter / automation / interne — ici 900 humains pour 51 153 hits de crawlers filtrés), temps réel, panneau d'anomalies avec inspecteur d'IP/visiteur, puis les cartes **par application** (humains, sessions, pages, 7 j, tendance vs hier).130131---132133## Les modules, en détail134135### 1) Claude Code — pilotage du vrai CLI136137L'exigence non négociable du projet : **jamais l'API Messages pour coder, toujours le binaire `claude`**, en mode headless :138139```140claude -p --output-format stream-json --verbose --include-partial-messages141```142143- **`cwd` = le repo de prod de l'app choisie**, sur son nœud de déploiement. Les apps de M3U96a tournent en local ; les autres (lou-ka sur M3U96b, immo-ka sur M4M64a, house-ka sur M4M64b, trouve-ka sur M2M32…) sont pilotées **via SSH sur leur nœud** — le repo de prod est la seule source de vérité, aucun clone.144- **Streaming intégral** : chaque événement du stream (texte, thinking, `tool_use`, `tool_result`, result) est relayé au navigateur et rendu comme dans le terminal — diffs colorés pour Edit/Write, blocs outils repliables, TodoWrite en checklist, Markdown (marked) + coloration syntaxique (highlight.js), copie des blocs de code.145- **Options exposées dans l'UI** : modèle par session (Fable 5 par défaut, Opus, Sonnet, Haiku — `--model` toujours passé explicitement, sinon les nœuds retombent sur leur défaut local), mode de permissions, choix du projet, `/clear` `/compact` `/cost` `/resume`, modèle actif, session ID, **coût cumulé en direct**, tokens de contexte (+ %), file d'attente de messages, chrono d'exécution.146- **Mode orchestrateur multi-sites** : la cible « Tous les sites KA » lance une session qui coordonne des changements sur l'ensemble du parc (c'est le mode utilisé pour les campagnes transverses — mobile, stats, README…).147- Chaque run reçoit un `--append-system-prompt` maison : après toute modification → rebuild + `pm2 restart` + healthcheck + commit/push **spbgit** (origin, jamais GitHub).148149### 2) Sessions — détachées, reprenables, rejouables150151Le process `claude` **ne dépend jamais du WebSocket** :152153- On peut fermer l'onglet, verrouiller l'iPhone, perdre le réseau — la tâche continue sur le nœud.154- Le transcript est persisté en JSONL (`data/transcripts/*.jsonl`) ; à la reconnexion, l'app **rejoue l'historique manqué puis reprend le live**.155- **Reprise auto durcie** : la console rouvre la dernière conversation au lancement (`lastChatId`) et force reconnexion + resync au retour au premier plan (`visibilitychange` / `online` — iOS coupe le WS à l'écran verrouillé). Reconnexion avec backoff + indicateur d'état.156- États clairs : en cours / en attente de permission / inactive ; notifications in-app en fin de tâche ou quand une permission attend.157- `--resume <session-id>` pour continuer une session CLI existante, coût et contexte conservés.158159### 3) Prompts — bibliothèque + upgradeur de prompts160161- Prompts réutilisables associés à une app (ou « app au choix »), avec favoris ★, duplication, compteur d'usage, recherche et filtre par app.162- **Upgradeur de prompts** : le bouton ✨ Améliorer envoie la demande brute à l'API Anthropic (modèle configurable, Opus par défaut) avec un système de connaissance du Groupe Ka injecté (les 19 sites, leurs nœuds, leurs process managers, les conventions remote-first) — et renvoie un prompt excellent, prêt pour Claude Code. L'upgradeur ne répond jamais lui-même : il ne fait que réécrire.163164### 4) Écosystème — monitoring des 19 sites165166`server/monitor.js`, zéro dépendance native (`node:sqlite` intégré) :167168- **Health checks HTTPS toutes les 45 s** de chacun des 19 sites du groupe depuis M3U96a : latence, code HTTP, jours restants sur le certificat SSL.169- **Sweep des nœuds toutes les 5 min** : charge / RAM / disque + statut, CPU et mémoire des process PM2 + âge du dernier commit git. Les sites sous launchd (KA Guardian sur M4M36) sont gérés spécifiquement — pas de pm2 sur ce nœud.170- **Historique SQLite** (`data/eco.sqlite`, rétention 35 j) : uptime 24 h / 7 j / 30 j, latence moyenne et p95/p99, sparklines, graphique 24 h, barres d'uptime 14 j.171- **Incidents** : 2 échecs consécutifs → alerte ; rétablissement → alerte verte ; vue Incidents globale avec durées.172- **Actions d'admin par site**, exécutées localement ou via ssh sur le nœud du site : redémarrer PM2 (`/api/admin/action`), logs récents (`/api/admin/logs`), git & derniers commits (`/api/admin/commits`).173- Push temps réel vers l'UI via le même WebSocket que le chat.174175### 5) Visiteurs — analytics v2 « trafic humain »176177`server/analytics.js` + le beacon `public/ka-a.js`, déployé sur les sites du groupe. Définitions officielles :178179- **Visiteur humain** : identifiant classé `human` = UA navigateur + JS réellement exécuté + réseau non-datacenter/non-proxy + pas interne + pas de flood.180- **Session** : trou > 30 min = nouvelle session. **Page vue** : événement `pv` réel (navigation, SPA incluse) — un heartbeat n'est **jamais** une page vue. **En ligne** : dernier événement humain < 120 s, expire tout seul.181- **5 classes** : `human / crawler / datacenter / automation / internal`, classées à l'insertion (regex UA + cache IP-intelligence avec hosting/proxy/ASN, reclassement rétroactif, anti-flood). Les métriques principales n'affichent **que les humains** ; le reste vit dans la barre de répartition et le toggle « Tout le trafic ».182- **Beacon v2** (`ka-a.js`) : vid/sid en localStorage, pv SPA via `pushState`, heartbeat 25 s seulement onglet visible + interaction récente. Le beacon v1 reste supporté (dé-duplication côté serveur) et l'ancienne série s'affiche en pointillé « ancien comptage v1 (non filtré) » — jamais comparée directement.183- Tables SQLite : `events` (brut, 45 j), `ipinfo` (cache), `daily2` (rollup quotidien par classe, long terme). Anomalies de trafic + **inspecteur d'IP / de visiteur** intégré.184- Suite de tests : `node server/test-analytics.mjs` — 28 scénarios (humain/refresh/SPA, Googlebot, bot d'uptime, IP AWS, curl, interne, dédup v1, invariants uniques ≤ sessions ≤ pv, expiration en ligne). À lancer depuis une **copie** du dépôt (écrit dans `data/`).185186### 6) Vue d'ensemble — le cockpit187188La page d'accueil de la v3 « Control Center » : elle agrège tout ce qui précède en un écran — KPIs humains + écosystème + Claude (dont le coût cumulé), graphique 30 jours, chips des 19 sites, incidents récents, anomalies de la dernière heure, raccourcis vers les sessions Claude.189190### 7) Studio — module Social (Facebook & Reels)191192`server/social.js` + `server/social/*.py` :193194- **Auto-post Facebook** : cartes statistiques et carrousels générés aux couleurs de chaque site du groupe (rendu HTML → image), publiés sur la page Facebook Groupe Ka.195- **Reels multi-scènes** : `make_reel.py` assemble des vidéos verticales multi-scènes à partir des données live des plateformes.196- **Moteur musical numpy** : `music_engine.py` synthétise les pistes audio des Reels (pas de banque de sons externe).197- Galerie des rendus dans l'onglet Studio, insights de page (`insights.py`).198- Les rendus vivent dans `data/social/` (non versionné).199200### 8) Gardiens KA Guardian (ka2 / ka4 / ka6)201202Les trois agents gardiens autonomes des connecteurs (ka2.bot / ka4.bot / ka6.bot — un seul repo FastAPI sur **M4M36**, sous launchd) sont intégrés à la console :203204- **Chat direct avec chaque gardien** depuis Admin-Ka.205- Cartes dédiées dans l'Écosystème (health checks, latence, uptime comme les autres sites).206- **Actions launchd** sur M4M36 (redémarrage des gardiens) depuis l'interface.207208### 9) Écran du nœud (noVNC)209210Un pont WebSocket intégré (`/vncws`) relie le client **noVNC embarqué** au Partage d'écran du nœud (127.0.0.1:5900) : on voit et contrôle l'écran de M3U96a directement dans le navigateur, sans exposer VNC sur le réseau — utile notamment pour le module Social (automatisation d'interface).211212---213214## Identité visuelle215216L'identité Groupe Ka, déclinée « console » :217218- **Crème** `#F2F1EC` en fond, **orange** `#F97316` en accent (traits de graphe `#e05f00`), encre `#1a1611`.219- Héritage néo-brutaliste (cartes à bords francs, pills, pastille « Ka », typo ronde) modernisé en v3.1 : hairlines + ombres douces, rayons contenus, segmented controls nets — esprit Linear/Vercel, identité crème + orange conservée.220- **Dark mode réel** (`ka_theme` auto / clair / sombre) via variables CSS.221- Desktop-first depuis la v3 : sidebar ≥ 1020 px + topbar ; mobile : bottom nav 5 entrées avec safe-areas iPhone.222- Statuts jamais en couleur seule (● ▲ ■ + libellé).223224---225226## Architecture227228```229iPhone / Mac ⇄ wss://www.administration-ka.com (ngrok) ⇄ backend :3300 (M3U96a, loopback)230   backend ⇄ claude CLI (local — apps M3U96a)231   backend ⇄ ssh <nœud> claude CLI (apps distantes, repo de prod)232             └ tunnel SSH inverse -R : cartes de permission (perm-mcp MCP)233   backend ⇄ monitor.js  : health checks 45 s + sweep nœuds 5 min + SQLite + push WS234   backend ⇄ analytics.js: beacon ka-a.js → events/ipinfo/daily2 (SQLite)235   backend ⇄ social.js   : Studio (Python : cartes, Reels, musique)236   backend ⇄ /vncws      : pont noVNC → Partage d'écran 127.0.0.1:5900237```238239- **Node.js pur** (modules ES), serveur HTTP + WebSocket maison — deux seules dépendances npm : `ws` et `@novnc/novnc`. SQLite via `node:sqlite` intégré (aucune dépendance native).240- **Frontend une page, aucun framework** : `public/index.html` + `app.js` + `style.css`, vendors locaux (marked, highlight.js, noVNC).241- **Permissions distantes** : `server/perm-mcp.js` est un serveur MCP stdio (`--permission-prompt-tool mcp__adminka__approve`), déployé aussi sur M3U96b / M4M64a / M4M64b / M2M32 dans `~/.adminka/`. Chaque demande de permission devient une carte **Autoriser / Refuser** dans le chat (long-poll, timeout 10 min → refus). Comme l'IPv4 LAN n'est pas routée entre tous les nœuds et que Tailscale inter-nœuds est bloqué, les réponses transitent par un **tunnel SSH inverse (`-R`)**.242- **Persistance** (`data/`, non versionné) : `config.json` (secrets et réglages), `sessions.json`, `chats.json`, `transcripts/*.jsonl`, `eco.sqlite`, `analytics.sqlite`, `audit.jsonl`, logs.243244## Modes de permission245246- **Sûr** (défaut) : lecture libre (`Read, Glob, Grep, LS, WebFetch, WebSearch, TodoWrite, NotebookRead, Task`) ; tout le reste (Bash, Edit, Write…) déclenche une carte dans le chat : **Autoriser / Toujours (cet outil) / Tout autoriser / Refuser**.247- **« Tout autoriser »** : le serveur approuve toutes les permissions suivantes jusqu'à la fin de la conversation — la tâche va au bout sans jamais réattendre l'utilisateur.248- Modes CLI également exposés : `acceptEdits`, `plan`, et bypass (`--dangerously-skip-permissions`) derrière une confirmation explicite dans l'UI.249250## Auth & sécurité251252- Mot de passe d'application haché **scrypt** → cookie `akid` HttpOnly/Secure, 7 j d'inactivité / 30 j max.253- **Rate-limit login** : 8 échecs / 15 min / IP.254- Backend lié à **127.0.0.1** — seul le tunnel ngrok y accède.255- **Audit complet** : `data/audit.jsonl` (logins, prompts, tool_use, permissions, coûts).256- Changement de mot de passe : `node server/set-password.js '<nouveau>'` puis redémarrage du backend.257- Aucun secret dans le dépôt : `data/` est hors git (config, bases, transcripts), la clé Anthropic vient de `~/.claude/.env` du nœud.258259## Structure du dépôt260261```262admin-ka/263├── server/264│   ├── server.js          # HTTP + WS :3300, orchestration claude (local + ssh), upgradeur de prompts, pont /vncws265│   ├── monitor.js         # Écosystème : checks 45 s, sweep nœuds, eco.sqlite, incidents, push WS266│   ├── analytics.js       # Analytics v2 : classification humain/crawler/…, sessions, rollups, API267│   ├── perm-mcp.js        # Serveur MCP stdio (permission-prompt-tool) — aussi déployé sur les nœuds distants268│   ├── social.js          # Studio : posts FB, Reels, galerie, insights269│   ├── social/            # Python : make_reel.py, music_engine.py (numpy), render_card_html.py, insights.py270│   ├── set-password.js    # Changement du mot de passe d'app (scrypt)271│   └── test-analytics.mjs # 28 tests analytics272├── public/273│   ├── index.html         # SPA sans framework — 8 vues274│   ├── app.js             # logique complète du front (WS, replay, rendu stream-json, thème…)275│   ├── style.css          # design system crème/orange, dark mode, mobile276│   ├── ka-a.js            # beacon analytics v2 embarqué par les sites Ka277│   └── vendor/            # marked, highlight.js, noVNC (locaux)278├── deploy/279│   ├── io.adminka.backend.plist   # launchd : node server/server.js (KeepAlive)280│   └── io.adminka.ngrok.plist     # launchd : ngrok http --url=www.administration-ka.com 3300281├── docs/screenshots/      # les 10 captures de la visite guidée282├── CLAUDE.md              # exigences + pièges connus (à lire avant toute modif)283└── data/                  # NON VERSIONNÉ : config.json, SQLite, transcripts, audit, logs284```285286## Déploiement & exploitation (sur M3U96a)287288Le service tourne sous **launchd** (`KeepAlive`) sur le nœud M3U96a, exposé par **ngrok** sur le domaine réservé :289290```bash291# statut292launchctl print gui/501/io.adminka.backend | head -20293curl -s http://127.0.0.1:3300/healthz294295# redémarrer296launchctl kickstart -k gui/501/io.adminka.backend297launchctl kickstart -k gui/501/io.adminka.ngrok298299# logs300tail -f ~/apps/admin-ka/data/backend.err.log ~/apps/admin-ka/data/ngrok.log301302# changer le mot de passe d'app303node server/set-password.js '<nouveau>' && launchctl kickstart -k gui/501/io.adminka.backend304```305306- Clé API : lue depuis `~/.claude/.env` (`ANTHROPIC_API_KEY`) au démarrage du backend (pas de login OAuth sur les nœuds).307- Projets proposés dans le sélecteur : `~/groupe-ka/*` (clones des repos spbgit), `~/apps/*` (apps déployées sur ce nœud), et `~` (home).308- Registre des déploiements du cluster : `cluster-deployments.json` (laptop, source de vérité).309- **Repo git** : spbgit (git perso) — `~/srv/git/admin-ka.git` sur M3U96a, remote `origin`. Pas GitHub.310311### Pièges connus (ne pas re-découvrir)312313- Tailscale inter-nœuds **bloqué** (ACL) : depuis M3U96a, joindre les nœuds via les noms Bonjour `.local` ; M2U64 = sous-réseau 192.168.0.x.314- IPv4 LAN non routée entre certains nœuds (EHOSTUNREACH) : les permissions distantes passent par le tunnel SSH inverse.315- `ControlPath` ssh trop long avec les hostnames `.local` → `%C`.316- Sans `--model`, un nœud retombe sur son défaut local → toujours le passer explicitement.317318## Apps natives compagnes319320La console a deux enveloppes natives (WKWebView + identité Ka), distribuées hors de ce dépôt :321322- **Admin-Ka iOS** — app SwiftUI (repo spbgit `admin-ka-ios.git`), distribuée via **TestFlight** ; panneaux JS natifs (WKUIDelegate), icône et splash Ka.323- **Admin-Ka macOS** — app SwiftUI **notarisée** (Developer ID, repo spbgit `admin-ka-macos.git`), livrée en DMG.324325## Contact326327- **Groupe Ka** — [www.groupe-ka.com](https://www.groupe-ka.com) · [groupe-ka.com/contact](https://www.groupe-ka.com/contact)328- Console : [www.administration-ka.com](https://www.administration-ka.com) (accès privé)329- Infra : cluster MacLustr — nœud M3U96a330331---332333<p align="center">© Groupe Ka — Admin-Ka v3 « Control Center ». Console privée d'exploitation ; tout est branché sur le vrai CLI et les vrais sites, rien n'est simulé.</p>334