Memories / Documentation

Sur cette page

Memories

Dépôt : https://github.com/mbcc2006/memories. La CLI est memories, le relais est memories-relay et la bibliothèque native est memories_ffi.

Mémoires chiffrées, fichiers privés et identifiants sous le contrôle du client, avec une CLI Rust, un client Android/iOS, un serveur MCP local et un relais WebSocket fonctionnant uniquement en mémoire.

Version de développement, version de format 1. Ce dépôt comprend du code exécutable et des tests de non-régression de sécurité. Il n'a pas fait l'objet d'un examen indépendant de sa cryptographie ou de la sécurité de l'application. Consultez SECURITY.md pour les garanties, les frontières de confiance et les limites actuelles.

Comment les éléments s'articulent

En utilisation autonome, Memories conserve un stockage local chiffré sur chaque appareil. Utilisez-le pour enregistrer des connaissances consultables, transporter une persona d'IA entre clients, ou utiliser des fichiers privés et des secrets au moyen d'une autorisation explicite. Le stockage cloud conserve le texte chiffré ; le relais connecte uniquement les pairs en ligne. Aucun des deux ne remplace un client autorisé.

L'application mobile propose aussi les modes Center (votre serveur auto-hébergé) et SaaS (https://memories.ivjn.us). Ces modes utilisent un stockage hébergé distinct dont l'opérateur peut lire le contenu. Choisir ou changer de mode ne téléverse, ne déplace ni ne fusionne une bibliothèque locale existante. Consultez les modes mobiles.

Memories Web se connecte à votre Center hébergé existant pour gérer mémoires, cartes et fichiers dans un navigateur. Les nouvelles versions de Center le servent aussi à /app/. Consultez le guide du client Web pour les jetons d'accès, les origines autorisées et les opérations prises en charge. L'API SaaS hébergée est disponible à https://memories.ivjn.us ; utilisez un jeton de membre émis pour ce service.

Concept Utilisation
Stockage (--home) Répertoire de données, mot de passe local et identité de cet appareil. Un stockage peut contenir plusieurs coffres ; le daemon et les clients doivent sélectionner le même stockage.
Coffre Collection avec ses propres membres, rôles, permissions d'appareil et historique signé. Partagez un coffre, pas le répertoire de stockage actif.
Mémoire Document textuel comme une note ou une entrée de journal.
Carte de connaissances Connaissances de type wiki avec étiquettes, sources, catégorie et relations.
Carte Brain Connaissances structurées avec résumé et liens typés, y compris des références entre coffres. Ce n'est ni un modèle ni un moteur d'inférence.
Carte Persona Noyau d'identité lié à des archives, à l'état du monde et à des événements de comportement. Consultez les personas.
Carte de workflow Étapes ordonnées avec un état en attente/actif/terminé/ignoré et un état global, stockées comme une révision de carte normale.
Fichier Contenu binaire original à importer/exporter, et non texte consultable extrait automatiquement.
Identifiant Secret protégé utilisé par des opérations autorisées, et non texte ordinaire à rechercher ou afficher. Les cartes protégées associent des métadonnées sûres à un identifiant distinct.

unlock permet le travail ordinaire autorisé dans le stockage. memories sudo ajoute une session de courte durée pour le contenu privé, les fichiers, les identifiants et la gestion sensible ; il n'accorde pas les droits d'administrateur du système et ne contourne pas les permissions du coffre. Une autorisation MCP ordinaire limitée à un coffre est une capacité d'IA distincte et limitée, et non l'autorité sudo du terminal. L'accès sans surveillance est une capacité distincte, en lecture seule et activée volontairement, qui peut exposer du contenu privé et des valeurs secrètes.

Commencez ici

Tâche Guide Prise en charge actuelle
Enregistrer et lire votre première note Démarrage rapide local Initialiser un stockage, créer un coffre, écrire et rechercher du texte
Commencer sur téléphone ou changer son mode de stockage Modes mobiles Standalone, Center auto-hébergé ou SaaS ; sélection mémorisée et profils de connexion distincts
Donner à un client IA un accès limité aux connaissances MCP local Autorisations limitées au coffre ; contenu privé et identifiants exclus
Vérifier l'état du service de bureau Zone de notification et WebUI Zone de notification Windows, barre de menus macOS, état en lecture seule et modification limitée des cartes
Configurer les valeurs par défaut du stockage et du relais Configuration Paramètres TOML partagés sur Windows, Linux et macOS
Rechercher dans des documents et poser des questions Recherche et RAG BM25 chinois, fragments, EmbeddingGemma local, recherche vectorielle/hybride et réponses citées
Signer/chiffrer du courrier ou signer une application Opérations cryptographiques S/MIME, OpenPGP, APK/AAB ; .app iOS provisionnée sur macOS
Ajouter la compétence Memories à un client IA Injection de compétence Codex, OpenCode et Claude Code ; portée utilisateur ou projet
Autoriser les lectures de bureau sans surveillance, secrets compris CLI/MCP sans surveillance Autorité locale en lecture seule activée volontairement ; testée de bout en bout sur Linux, vérifications natives Windows/macOS et trousseaux réels en attente
Générer AGENTS.md / une compétence persona Génération de compétence CLI skill generate / agents generate ; persona facultative
Définir les valeurs par défaut de la CLI cliente Valeurs par défaut du client persona, vault, type, … sous le répertoire Memories
Capturer un mot de passe ou une sortie de commande Capture d'identifiants Saisie masquée, stdin, stdout de commande, sélection regex et JSON
Protéger ou copier un secret dans un document wiki Références de secrets wiki Remplacement exact du corps, identifiants chiffrés et copies autorisées dans le presse-papiers
Connecter OneDrive ou Google Drive Autorisation cloud Connexion de bureau, jetons locaux chiffrés, état et déconnexion
Transférer des coffres entre appareils Appairage d'appareils Appairage explicite et transfert chiffré de coffre
Synchroniser le texte chiffré via le stockage cloud Conception du stockage Files d'envoi/réception durables, memories cloud sync, adaptateurs OneDrive/Google Drive ; vérification sur comptes réels en attente

Pour le développement, consultez les consignes du dépôt, l'architecture et les résultats de validation.

Chinois simplifié : Présentation du produit, Guide d'utilisation, Documentation technique.

Site de présentation du projet : website/, site statique anglais/chinois avec instructions de déploiement Cloudflare Pages.

Compiler et exécuter

Installez Rust 1.88 ou plus récent et la chaîne d'outils C de la plateforme (SQLite est compilé depuis les sources).

cargo build --workspace --locked
cargo test --workspace --locked
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo install --path crates/cli --locked

Démarrez memories daemon dans un terminal distinct. Il sert uniquement l'utilisateur courant du système via un canal nommé sur Windows ou un socket Unix sur Linux/macOS. Utilisez un répertoire de données dédié avec --home PATH ou MEMORIES_HOME ; par défaut, il s'agit du répertoire de données d'application du système. Ne faites pas pointer --home vers un dossier généraliste existant : ses permissions sont restreintes pour protéger le service local.

Démarrage rapide local

Avec memories installé et le daemon démarré, utilisez un second terminal interactif. Pour un nouveau stockage autonome :

memories init --name laptop
memories vault create Personal
memories vault list

Créez un fichier UTF-8 nommé notes.md avec une courte note contenant « project ». Remplacez VAULT_ID ci-dessous par l'id renvoyé par vault create ou vault list, puis exécutez :

memories memory put VAULT_ID --title "Project notes" --input notes.md
memories memory search VAULT_ID "project"
memories memory grep VAULT_ID 'project|release' -i -n

memory grep applique une expression régulière à chaque ligne déchiffrée du corps des documents mémoire ordinaires du coffre sélectionné. Il affiche DOCUMENT_ID:LINE, ou DOCUMENT_ID:LINE_NUMBER:LINE avec -n / --line-number ; -i / --ignore-case ignore la casse. Les documents privés, versions en conflit, cartes, fichiers et identifiants sont exclus, comme le contenu privé dans la recherche ordinaire. Aucune correspondance ne produit aucune sortie.

Remplacez ASSET_ID par l'id de la note enregistrée. Pour FROM_REVISION, utilisez le champ revision renvoyé par history ; le diff compare cette révision à la tête actuelle :

memories memory read VAULT_ID ASSET_ID
memories memory history VAULT_ID ASSET_ID
memories memory diff VAULT_ID ASSET_ID FROM_REVISION
memories lock
memories unlock

Lors des visites suivantes, utilisez unlock, et non init. Si c'est un nouvel appareil rejoignant une identité existante, appairez-le avant de créer des coffres. Pour un stockage personnalisé, passez le même --home PATH au daemon et à chaque commande cliente.

Découvrez les tâches avec memories --help, puis approfondissez avec memories memory --help ou memories memory put --help. Ajoutez --lang zh pour l'aide en chinois, par exemple memories --lang zh memory put --help. L'aide ne nécessite pas de daemon.

Les mots de passe sont lus dans un terminal interactif sans écho. Il n'existe ni argument de mot de passe ni variable d'environnement de mot de passe. Les mots de passe locaux et de sauvegarde n'ont aucune restriction de longueur au niveau de l'application, y compris une saisie vide ; la confirmation du mot de passe et l'authentification restent applicables. Les commandes émettent du JSON versionné ; les commandes en échec renvoient un état de sortie non nul. Les clés publiques et empreintes des appareils sont volontairement visibles ; les clés privées et valeurs d'identifiants ne sont pas affichées par les commandes ordinaires. Les lectures explicites d'identifiants sans surveillance constituent une exception décrite dans CLI/MCP sans surveillance.

Daemon distant (HTTP/WebSocket / RPC du relais)

L'écoute HTTP/WebSocket facultative authentifiée par jeton et le RPC du relais WSS transportent le même protocole encadré service::Request que l'IPC local (toutes les fonctions sur bureau après unlock/sudo ; Share mobile conserve la liste d'interdiction FFI). Utilisez memories daemon --listen http://127.0.0.1:7900 (--tls-cert / --tls-key facultatifs pour HTTPS/WSS). Le RPC exécute des opérations sur le stockage de l'hôte ; il ne synchronise pas une réplique locale. Consultez le daemon distant pour les options d'écoute/client, les risques résiduels et Share mobile.

Les Centers d'autorisation facultatifs peuvent interdire l'auto-amorçage local et distribuer des tickets d'inscription/d'autorisation MCP aux points de terminaison. memories-center --data DIR exécute en plus un coffre hébergé complet : il contrôle les daemons ayant une entrée Center mode = "saas", l'opérateur peut le déverrouiller à distance et les membres sont gérés sur le Center.

Chaîne d'autorisation

Les rôles de coffre sont Owner, Admin, Editor et Reader. Seuls Admin ou Owner peuvent émettre ou déléguer des autorisations ; l'émission nécessite un coffre déverrouillé mais aucune élévation du terminal, tandis que l'approbation d'une demande de rôle nécessite une élévation. Une autorisation est plafonnée par le rôle de son émetteur (et toute autorisation parente), le bénéficiaire ne peut pas avoir un rôle supérieur et center-admin ne peut pas être bénéficiaire. La profondeur de délégation est au maximum de 2. Une portée omise signifie read, pas allow_all. Les demandes de permission vont à tous les approbateurs admissibles ou à des membres --approver précis ; personne ne décide de sa propre demande. L'approbation ne renvoie aucun jeton : le demandeur le réclame une fois (memories request claim, memories center request claim, MCP request_claim, ou POST /v1/requests/{id}/claim). Limites : 20 demandes en attente par demandeur par coffre, 200 par coffre (HTTP 429 sur Center), TTL en attente de 7 jours, conservation de 30 jours et au maximum 10,000 autorisations actives sur le daemon comme sur un Center hébergé. memories access list VAULT affiche les membres par niveau, les appareils, les demandes en attente et approuvées non réclamées ; memories grant list VAULT liste les autorisations. Supprimer un membre révoque ses autorisations en cascade (génération par membre) ; les autorisations sont conservées uniquement sous forme de hachages et le journal d'audit est chaîné par hachage (Center : DIR/audit.jsonl). Consultez l'autorisation.

Le chat persona (memories persona chat send|list|history|mark-read) déclenche des hooks d'automatisation chat_message ; les webhooks entrants d'automatisation sont aussi accessibles via memories-relay à POST /v1/persona/{room}/{vault}/{persona}/automation/trigger (voir persona, daemon distant).

Compilation et paquet Linux

Sur Debian/Ubuntu (y compris Ubuntu dans WSL2), installez Rust 1.88+ et les dépendances natives de compilation :

sudo apt-get update
sudo apt-get install -y build-essential pkg-config libssl-dev python3 git
bash scripts/build-linux.sh
# Optional development build:
bash scripts/build-linux.sh --debug

Le script compile l'espace de travail Rust pour la cible GNU de l'hôte : x86_64 ou aarch64. Les sorties release se trouvent dans target/<host-target>/release/ (ou le répertoire cible Cargo configuré) ; les sorties debug utilisent debug/. Aucun SDK Flutter n'est nécessaire. Linux prend en charge la CLI, le daemon, le relais, la bibliothèque FFI et memories webui ; l'icône native de notification n'est actuellement disponible que sur Windows/macOS.

Depuis une copie de travail propre et commitée, créez une archive release Linux :

bash scripts/package-linux.sh

Cela recompile les binaires release et écrit un .tar.gz, BUILD-INFO.json, SHA256SUMS et un exemple de configuration dans dist/vVERSION-linux-ARCH/. L'archive comprend memories, memories-relay, libmemories_ffi.so, l'en-tête C, la documentation et les licences, en conservant les permissions d'exécution. Les répertoires de sortie existants ne sont pas écrasés. Le workflow manuel Build desktop packages compile et téléverse aussi un paquet Linux x86_64.

Ce sont des compilations GNU/Linux natives, et non des binaires statiques ou compilés de manière croisée. Utilisez un environnement d'exécution glibc/OpenSSL compatible ; compilez sur la plus ancienne distribution que vous souhaitez prendre en charge. ca-certificates est nécessaire pour le TLS système et xdg-utils pour ouvrir le tableau de bord dans un navigateur de bureau. La copie d'identifiants dans le presse-papiers nécessite aussi wl-clipboard (Wayland) ou xclip (X11). Les poids du modèle s'installent séparément avec memories rag model-install.

Configuration

Exécutez memories config init pour créer une configuration TOML, memories config path pour la trouver et memories config show pour examiner les paramètres effectifs. La version distribuée inclut memories.example.toml avec les options de répertoire de stockage, de relais et de bureau. Sélectionnez un autre fichier avec --config PATH ou MEMORIES_CONFIG. Les options CLI priment sur les variables d'environnement, puis la configuration, puis les valeurs par défaut. Consultez le guide de configuration.

Zone de notification et tableau de bord d'état du bureau

Sur Windows, double-cliquez sur memories-tray.exe dans le répertoire de la version extraite. Sur macOS, ouvrez le paquet Memories.app, ou utilisez la ligne de commande :

memories tray
memories webui

La zone de notification/barre de menus affiche l'état du daemon et du coffre, ouvre la WebUI locale et peut démarrer le daemon. Le tableau de bord indique l'état de verrouillage, le nombre de bibliothèques, de connexions et les files de synchronisation cloud sans afficher le contenu stocké. --home sélectionne le même stockage que la CLI ; --no-open garde le navigateur fermé au démarrage. Initialisez/déverrouillez via la CLI comme d'habitude. Consultez le guide du bureau pour le comportement et les paquets.

Langues

Le client mobile et la CLI prennent en charge l'anglais (en), le chinois simplifié (zh), le japonais (ja), l'allemand (de) et le français (fr). Le menu de langue mobile est disponible sur l'écran de verrouillage et dans la bibliothèque. Il suit le système par défaut et mémorise un choix manuel entre les redémarrages.

memories --lang zh --help
memories cloud login --lang ja --help
memories --lang de status
memories language zh       # Remember this language
memories language          # Show saved and effective language
memories language system   # Follow the system again

La sélection de langue CLI utilise --lang, puis MEMORIES_LANG, puis une préférence de langue enregistrée, puis la première variable non vide parmi LC_ALL, LC_MESSAGES ou LANG. La préférence est stockée par --home / MEMORIES_HOME et fonctionne sans daemon. Sur Windows, elle utilise aussi la langue du système lorsqu'aucune de ces variables n'est définie. Les paramètres régionaux non pris en charge reviennent à l'anglais ; des valeurs d'environnement comme fr_FR.UTF-8 et zh-CN sont acceptées. Les commandes, noms d'options, champs JSON, codes d'erreur et mots de confirmation USE et APPROVE restent stables. Le contenu utilisateur n'est pas traduit. Les diagnostics de bas niveau sans traduction conservent leurs détails d'origine avec un résumé d'erreur localisé. Consultez le guide de localisation pour la maintenance.

Identifiants courts

Les requêtes CLI, MCP et mobiles utilisent des identifiants hexadécimaux courts simples, normalement de six caractères (par exemple 0b0668). Les identifiants n'indiquent aucun type ni classification et n'ont ni préfixe ni trait de soulignement. Utilisez directement dans la commande correspondante les identifiants renvoyés par vault list, card list, card search ou l'historique. Les UUID longs, hachages complets de révision et identifiants préfixés sont rejetés ; aucune option de sortie d'identifiants longs n'existe.

Les identifiants existants de huit caractères restent valides. Les préfixes en collision s'allongent automatiquement par incréments de deux caractères jusqu'à 16 caractères ; les saisies ambiguës sont rejetées. Cela ne raccourcit pas les clés d'appareil ni les empreintes de sécurité.

memories card list eb7abf
memories card search eb7abf "claude relay"
memories card read eb7abf 0b0668

Les identifiants sont résolus dans la portée de chaque argument de commande. Une collision allonge l'identifiant renvoyé de deux caractères, jusqu'à 16 ; une saisie ambiguë échoue au lieu de sélectionner un objet. Relancez la liste ou la recherche après une collision. Les éléments supprimés restent dans l'index des collisions. Les identifiants courts sont des références, pas des autorisations : déverrouillage, sudo, permissions de coffre et autorisations MCP restent applicables.

Les enregistrements de stockage signés conservent leurs identifiants d'origine sans migration. Les certificats, clés publiques, empreintes de vérification, enregistrements d'audit et enveloppes de transport chiffrées ne sont ni raccourcis ni réécrits.

Recherche et RAG

La recherche ordinaire segmente désormais le chinois et prend en charge plusieurs mots-clés. Son index BM25 est mis en cache en mémoire, invalidé lors des changements de contenu/politique et vidé au verrouillage. La recherche avancée ajoute les positions des fragments, les scores vectoriels, la fusion de rangs hybride, un reclassement léger et un reclassement appris facultatif via une URL configurée. Les identifiants et le contenu privé restent exclus.

memories rag ingest VAULT_ID notes.md --title "Research notes"
memories rag search VAULT_ID "Chinese and English keywords" --mode bm25
memories rag model-install
memories rag index VAULT_ID
memories rag search VAULT_ID "What does this document mean?" --mode hybrid
memories rag ask VAULT_ID "Summarize the evidence"

Le moteur d'inférence CPU intégré exécute EmbeddingGemma dans le processus Memories ; Ollama ou une autre application d'inférence n'est pas nécessaire. Les fichiers du modèle sont des données publiques installées une fois par model-install, ou fournies dans rag.local_model_dir. Gemini Embedding est une API en ligne distincte. Configurez les URL choisies par le client pour les plongements distants, la génération et le reclassement facultatif. Les proxies HTTP(S)/SOCKS, délais et tentatives bornées sont configurables. Consultez le guide RAG.

Fichiers privés et identifiants

sudo est une session d'autorisation interne, pas un accès administrateur du système. Il utilise le même mot de passe local. L'élévation dure au maximum 15 minutes, expire après cinq minutes d'inactivité et se limite au processus parent du terminal. Verrouiller ou redémarrer le service la supprime. Le déverrouillage ordinaire expire après 15 minutes d'inactivité.

memories sudo
memories file import VAULT_ID document.pdf
memories file export VAULT_ID FILE_ID exported.pdf
memories file exec VAULT_ID FILE_ID -- caddy run --config "{file}" --adapter caddyfile
memories credential add VAULT_ID "API token"
memories credential import VAULT_ID "SSH identity" existing-private-key
memories credential generate VAULT_ID "laptop ssh"
memories credential generate VAULT_ID "laptop ssh" --algorithm rsa --bits 4096
memories credential generate VAULT_ID "db ca" --kind tls-ca --algorithm rsa --subject memories-ca
memories credential generate VAULT_ID "db server" --kind tls --ca CA_ID --algorithm rsa --name db.example.test
memories credential public VAULT_ID KEY_ID
memories run --vault VAULT_ID --credential CREDENTIAL_ID /absolute/program/path
memories run --vault VAULT_ID --credential CREDENTIAL_ID --env API_TOKEN /absolute/program/path
memories credential bind gh --vault VAULT_ID --credential CREDENTIAL_ID --env GH_TOKEN
memories credential bindings
memories credential unbind gh
memories run --binding gh -- pr list --state open
memories hook install --commands gh
memories hook uninstall
memories credential allow-host VAULT_ID CREDENTIAL_ID api.example.com
memories credential http VAULT_ID CREDENTIAL_ID https://api.example.com/status
memories remote probe example.test --port 22
memories remote open ssh --vault VAULT_ID --credential KEY_ID --host example.test --user alice --host-key HOST_KEY
memories remote open ssh --vault VAULT_ID --credential KEY_ID --certificate CERT_ID --host example.test --user alice --host-key HOST_KEY
memories remote open mysql --vault VAULT_ID --credential CREDENTIAL_ID --host db.example.test --user app --database appdb
memories remote open redis --vault VAULT_ID --credential CREDENTIAL_ID --host redis.example.test --user default
memories remote open postgres --vault VAULT_ID --credential CREDENTIAL_ID --host db.example.test --user app --database appdb
memories remote open postgres --vault VAULT_ID --credential CREDENTIAL_ID --tls-ca CA_ID --host db.example.test --user app --database appdb
memories remote open mysql --vault VAULT_ID --credential CREDENTIAL_ID --host db.example.test --user app --database appdb --no-tls
memories remote run SESSION_ID -- uname -a
memories remote run SESSION_ID --op query -- SELECT 1
memories remote propose SESSION_ID -- uname -a
memories remote approve TICKET_ID
memories remote exec TICKET_ID
memories remote close SESSION_ID
memories proxy start ssh --vault VAULT_ID --credential KEY_ID --host example.test --user alice --host-key HOST_KEY
memories proxy start postgres --vault VAULT_ID --credential CREDENTIAL_ID --host db.example.test --user app --database appdb
memories proxy list
memories proxy stop PROXY_ID

Exécuter un programme avec un fichier de configuration stocké

memories file exec VAULT_ID FILE_ID -- PROGRAM ARGS... lit un fichier autorisé et remplace chaque {file} dans les arguments du programme par un chemin absolu de fichier temporaire. Utilisez --revision REVISION avant -- pour sélectionner une version historique. Il nécessite les mêmes déverrouillage, accès au coffre et memories sudo du terminal que l'export de fichier. Un daemon distant/hébergé peut fournir le fichier ; le programme s'exécute toujours sur la machine de la CLI, sous le compte de son utilisateur.

memories sudo
memories file import VAULT_ID ./Caddyfile
# Use the returned file ID. Caddy 2 Caddyfile syntax needs an explicit adapter.
memories file exec VAULT_ID FILE_ID -- caddy run --config "{file}" --adapter caddyfile

Le processus enfant hérite du répertoire de travail, de l'environnement et des flux standard ; son code de sortie est renvoyé sans enveloppe JSON de réussite. Aucun shell n'est inséré et aucune limite d'exécution de cinq minutes ne s'applique. Exécutez le programme au premier plan. Le répertoire/fichier temporaire est réservé au propriétaire (Unix 0700/0600 ; ACL utilisateur Windows) et supprimé à la sortie de l'enfant ou en cas d'échec de son démarrage. Ctrl+C/Ctrl+Break sur Windows et SIGINT/SIGTERM/SIGHUP sur Unix déclenchent l'arrêt, accordant dix secondes avant de tuer l'enfant direct et de nettoyer. Les signaux Unix sont transmis à l'enfant ; les événements de console Windows atteignent les processus partageant cette console.

Cela exporte du texte clair pendant la durée de vie de l'enfant. Faites confiance au programme et à ses extensions : sa sortie n'est pas expurgée. Le verrouillage/la révocation ne peuvent récupérer la copie remise ni arrêter l'enfant. L'arrêt forcé de Memories, une coupure de courant ou la fermeture d'une console Windows peuvent laisser le fichier temporaire ; la suppression n'est pas un effacement sécurisé. Les descendants détachés ne sont pas gérés. Chaque appel utilise un instantané fixe du fichier nommé config ; aucune mise à jour, aucun rechargement, développement de modèle ou import de fichiers associés automatiques n'a lieu. Les chemins relatifs suivent les règles du programme cible ; utilisez donc des chemins absolus pour les inclusions/certificats externes et indiquez explicitement le format lorsque le programme le déduit sinon du nom du fichier.

Injection d'identifiants dans un processus

L'injection d'identifiant dans un processus par memories run utilise stdin ; --env autorise explicitement une variable d'environnement. L'empreinte SHA-256 du programme doit être confirmée ou fournie via --approve-digest. Les deux flux de sortie de l'enfant sont supprimés. Le programme destinataire peut néanmoins copier ou transmettre l'identifiant et doit être digne de confiance. Une liaison d'exécution fixe un identifiant à une empreinte de programme pour qu'un agent de programmation puisse l'utiliser sans la session sudo de votre terminal. credential bind gh (sudo, saisie de USE) résout gh sur PATH, enregistre son SHA-256 et conserve la liaison uniquement dans l'état chiffré de cet appareil ; elle n'est jamais synchronisée et est supprimée à la restauration. Elle expire après --hours (8 par défaut, 720 au maximum) et fonctionne uniquement lorsque la bibliothèque est déverrouillée. run --binding gh -- ARGS exécute ensuite le programme dans le répertoire courant avec l'identifiant dans la variable d'environnement choisie, reproduit sa sortie en remplaçant chaque occurrence de l'identifiant par [REDACTED] (--suppress-output la supprime à la place) et termine avec le code du programme. --deny WORDS refuse les commandes dont les arguments autres que des options contiennent ces mots dans l'ordre ; --ask WORDS fait demander confirmation au hook avant de les exécuter. Pour gh, auth, alias et extension (aussi extensions et ext) sont interdits et pr merge, repo delete et release delete demandent confirmation, sauf avec --no-default-rules. Les règles correspondent aux mots tels que saisis ; les alias définis précédemment avec gh alias set ne sont pas développés. Jusqu'à l'expiration de la liaison, tout programme exécuté sous votre identité peut exécuter le programme lié avec l'identifiant ; il ne peut pas lire l'identifiant via Memories. Le programme lui-même, ses extensions et ses processus enfants le peuvent ; ne liez donc que des programmes de confiance. Une liaison sans --credential et --env applique uniquement les règles.

hook install --commands gh ajoute un hook PreToolUse aux paramètres utilisateur de Claude Code (après affichage de l'entrée et demande de APPROVE). Lorsque Claude Code va exécuter gh ... dans Bash ou PowerShell, le hook remplace ce mot de commande par memories run --binding gh -- et laisse le reste de la ligne inchangé. gh exécuté dans $( ), des accents graves, sh -c, xargs et des enveloppes similaires est refusé avec une raison ; les corps heredoc et substitutions utilisés comme arguments (comme --body "$(cat <<'EOF' ... EOF)") conviennent. L'entrée par tube ou redirigée est transmise avec --stdin (jusqu'à 16 MiB). Le programme s'exécute dans l'environnement du daemon, donc un préfixe NAME=value gh ... est refusé ; utilisez plutôt les options du programme. Les arguments développés par le shell à l'exécution ($var, motifs glob) ne peuvent être vérifiés par les règles ; le hook demande donc confirmation avant de les exécuter. Le hook n'approuve directement une commande que si elle consiste uniquement en exécutions liées ; si elle exécute aussi d'autres programmes ou écrit des fichiers, la confirmation habituelle de Claude Code s'applique. Le nombre de workers restant à lire des tubes détenus par les descendants persistants d'un programme lié est plafonné, et les exécutions liées suivantes sont refusées tant qu'il en reste trop. Les règles de permission deny et ask de Claude Code restent applicables, mais peuvent voir la commande réécrite ; conservez donc les sous-commandes sensibles dans les règles de la liaison. Les programmes liés s'exécutent hors du verrou du service ; un long gh run watch ne bloque donc pas les autres clients ; la limite de cinq minutes reste applicable.

L'interface HTTPS n'envoie un jeton Bearer qu'à un hôte configuré via HTTPS/443, ne suit pas les redirections, n'hérite pas des paramètres de proxy et ne renvoie que le code d'état pour éviter de refléter un identifiant dans un corps de réponse. Les sessions SSH, FTP, TCP, MySQL, Redis et PostgreSQL détenues par le daemon gardent les secrets dans le service. Chaque instruction est proposée, approuvée avec APPROVE, puis exécutée une fois sur la session active. remote run effectue les trois étapes ; les scripts peuvent les séparer avec remote propose (met un ticket en file), remote approve (sudo, usage unique) et remote exec (même appelant élevé). SSH accepte un identifiant de mot de passe, une clé privée OpenSSH importée (credential import) ou une clé générée dans le coffre (credential generate). Generate n'affiche jamais la clé privée ; credential public ne renvoie que la clé publique SSH ou le certificat TLS. Joignez éventuellement un second identifiant de certificat OpenSSH (--certificate). SSH exige aussi une empreinte de clé d'hôte épinglée provenant de remote probe. Les sessions MySQL, Redis et PostgreSQL utilisent TLS par défaut avec vérification du nom d'hôte. Redis et PostgreSQL utilisent rustls avec les racines webpki ; MySQL utilise la bibliothèque TLS de la plateforme. --tls-ca ajoute une autorité PEM stockée dans un identifiant de coffre ; il reste distinct de l'option globale --ca-file PATH (MEMORIES_CA_FILE), qui ajoute un bundle d'autorités PEM du système de fichiers pour le WSS daemon/relais et les clients HTTPS/base de données sortants. Définissez ces options sur le processus qui établit la connexion (démarrez le daemon avec elles pour les opérations amont qu'il détient). L'option globale --insecure ignore la vérification du certificat et du nom d'hôte sans désactiver TLS : dangereux, uniquement pour le développement/les certificats autosignés ; préférez --ca-file. Les options serveur --tls-cert / --tls-key sont inchangées. Consultez les exemples TLS client. Passez --no-tls pour désactiver TLS des bases de données. MCP ne peut pas utiliser cette voie. Les opérations de fichier utilisent FTP ; les sessions SSH approuvées n'acceptent que exec.

Protéger les secrets dans les documents wiki

Dans l'application, ouvrez le menu d'une mémoire/carte et choisissez Protéger un secret dans le document (chinois : 替换资料中的密钥). Nommez la référence (par exemple API_KEY), puis saisissez le secret exact avec une saisie masquée et autorisez l'opération. Toutes les correspondances exactes du corps de ce document deviennent {{secret:API_KEY}} ; la valeur est stockée comme identifiant chiffré. Les lectures ordinaires, la recherche et MCP ne voient que la référence.

Choisissez Copier le secret (复制密钥) dans le menu d'un document ou identifiant. Pour un document à plusieurs références, sélectionnez d'abord l'étiquette. Confirmez et autorisez pour copier sa valeur actuelle dans le presse-papiers système sans l'afficher.

La CLI fournit les mêmes opérations (utilisez les identifiants courts de list ou search) :

memories sudo
memories memory protect-secret VAULT_ID DOCUMENT_ID API_KEY
# For a knowledge card, use: memories card protect-secret VAULT_ID CARD_ID API_KEY
memories credential copy VAULT_ID DOCUMENT_ID --label API_KEY
memories credential copy VAULT_ID CREDENTIAL_ID

La commande de remplacement demande le secret ; ne placez pas de secrets dans les arguments ou les noms de référence. Les étiquettes acceptent 1-64 lettres ASCII, chiffres, traits de soulignement ou traits d'union et doivent être inutilisées dans ce document. Copier une référence de document nécessite --label, même pour une seule référence. La copie ne renvoie que l'état de copie ("copied": true). Windows utilise le presse-papiers natif, macOS utilise pbcopy et Linux nécessite wl-copy (Wayland) ou xclip (X11). Les cartes protégées account/token/env/OTP peuvent aussi être copiées directement ; les copies OTP renvoient la graine, pas un code à usage unique.

Le remplacement ne touche que le corps actuel du document. Les anciennes versions signées, sauvegardes, autres documents et copies partagées conservent leur contenu précédent ; révoquez ou renouvelez les clés exposées auprès de leur fournisseur. Le contenu du presse-papiers reste après verrouillage et peut être visible par d'autres applications ou l'historique du presse-papiers du système. Effacez-le après usage. Cette fonction ne découvre pas automatiquement les secrets et ne renouvelle pas les clés. Mettez à jour tous les clients avant de synchroniser des documents contenant des références de secrets. Consultez le guide complet pour les conditions de rejet, la modification et la mise à jour des identifiants, les exigences de plateforme et le dépannage du presse-papiers.

Proxies SSH et bases de données sans mot de passe

memories proxy start ouvre une écoute 127.0.0.1 après sudo du terminal et vérifications de la liste d'hôtes autorisés de l'identifiant. Il renvoie un id, une adresse listen et une command prête à l'emploi. Exécutez cette commande dans le terminal de l'agent sur la machine du daemon ; aucun mot de passe stocké ni clé privée n'est renvoyé. Le compte amont, l'hôte et la base initiale sont sélectionnés par les arguments de démarrage du proxy. Un proxy autorise les commandes pour ce compte sans approbation par commande.

memories sudo
memories proxy start ssh --vault VAULT_ID --credential KEY_ID --host example.test --user alice --host-key HOST_KEY
memories proxy start postgres --vault VAULT_ID --credential PASSWORD_ID --host db.example.test --user app --database appdb
memories proxy start mysql --vault VAULT_ID --credential PASSWORD_ID --host db.example.test --user app --database appdb
memories proxy start redis --vault VAULT_ID --credential PASSWORD_ID --host cache.example.test --user default
memories proxy list
memories proxy stop PROXY_ID

Utilisez credential allow-host VAULT_ID CREDENTIAL_ID HOSTNAME pour autoriser d'abord la destination d'un identifiant. Vérifiez via un canal de confiance une empreinte SSH obtenue avec remote probe avant de fournir --host-key. Les proxies SSH transmettent les requêtes exec, shell, PTY et sous-système ; les clés d'hôte amont restent épinglées. Les clés d'hôte SSH locales sont éphémères ; la commande renvoyée désactive donc la persistance des clés d'hôte uniquement pour le point de terminaison local.

Les connexions amont aux bases utilisent TLS vérifié par défaut, avec --tls-ca CA_ID facultatif. Le segment local vers la base est en clair sur la boucle locale. PostgreSQL prend en charge SCRAM-SHA-256, MD5 et l'authentification par mot de passe. MySQL prend en charge mysql_native_password et caching_sha2_password ; l'authentification complète par mot de passe SHA-256 nécessite TLS. La transmission des annulations/options de démarrage PostgreSQL et la compression MySQL ne sont pas implémentées. Les noms de connexion locaux et demandes de base initiale ne remplacent pas le compte/la base amont configurés.

Tout processus pouvant atteindre le port local peut utiliser son compte distant autorisé. Gardez le port local. Le verrouillage, le verrouillage automatique du coffre après inactivité, proxy stop et l'arrêt du daemon ferment les écoutes et connexions existantes. Les proxies expirent aussi après 30 minutes même lorsqu'ils sont utilisés, avec au maximum quatre proxies et 16 connexions par proxy. MCP ne peut ni démarrer, ni lister, ni arrêter les proxies ; un agent utilise son client de terminal ordinaire après que l'utilisateur en a démarré un.

Capturer des mots de passe et des sorties de commande

memories catch (aussi memories credential catch) capture un secret UTF-8 et le stocke comme identifiant chiffré. Exécutez d'abord memories sudo dans le même terminal. Sans option de source, il demande une saisie masquée, comme credential add :

memories sudo
memories catch VAULT_ID "Database password"

Utilisez --stdin pour un tube ou fichier redirigé. Ces exemples fonctionnent dans Windows CMD ; secret-tool représente votre propre programme qui émet la valeur :

secret-tool.exe | memories catch VAULT_ID "Database password" --stdin --regex "password=([^\r\n]+)"
memories catch VAULT_ID "API token" --stdin --json-pointer /token < response.json
memories catch VAULT_ID "API token" --exec secret-tool.exe --json-pointer /token -- issue --format json

--exec PROGRAM -- ARGS... démarre directement le programme indiqué et capture stdout. Il ferme stdin de l'enfant et supprime stderr. Pour un script CMD, utilisez --exec cmd.exe -- /d /c script.cmd ; les opérateurs shell nécessitent un shell explicitement sélectionné. Ce mode ne prend pas en charge les programmes externes interactifs nécessitant un terminal ; utilisez plutôt une saisie masquée ou une commande de sortie non interactive.

Sans sélecteur, la capture conserve le texte complet sauf un LF/CRLF final. Une regex doit correspondre exactement une fois ; son unique groupe de capture est enregistré, ou la correspondance entière si elle n'a aucun groupe. Utilisez (?:...) pour un regroupement supplémentaire. --json-pointer sélectionne une chaîne JSON (par exemple /credentials/password) ; il ne peut être combiné avec --regex. Les objets JSON doivent avoir des clés uniques, y compris les objets imbriqués et les équivalents échappés comme password et pass\u0077ord. Les valeurs vides, UTF-8 invalide, correspondances ambiguës, clés dupliquées et commandes en échec sont rejetés sans enregistrement. Utilisez --id CREDENTIAL_ID pour remplacer un identifiant.

L'entrée est limitée à 1 MiB. Les commandes expirent après 30 secondes ; définissez --timeout entre 1-300 secondes si nécessaire. En cas de délai dépassé ou de sortie excessive, la capture termine son enfant direct ; elle ne confine pas l'arbre de processus. Stdin par tube attend EOF et n'a aucun délai maximal. La sortie réussie contient l'identifiant du secret enregistré, jamais la valeur capturée. Utilisez memories run ou des opérations HTTP autorisées pour l'utiliser. Ne placez pas de vrais secrets dans les arguments de commande, motifs regex ou titres. La capture n'efface ni les fichiers source, ni l'historique shell, ni les journaux produits par le programme source.

Appareils, membres et synchronisation

Autorisation de compte cloud

Autorisez OneDrive ou Google Drive sur cet appareil avec votre propre application OAuth enregistrée. Démarrez le daemon actuel, déverrouillez la bibliothèque et exécutez sudo dans le même terminal avant la connexion :

memories sudo
memories cloud login onedrive --client-id YOUR_MICROSOFT_CLIENT_ID
memories cloud login google-drive --client-config /path/to/google-desktop-client.json
memories cloud status
memories cloud logout onedrive

La connexion ouvre le navigateur et valide un rappel local avec PKCE/state. Les jetons sont stockés dans l'état local chiffré de l'appareil et exclus des sauvegardes/échanges d'appareil. L'état n'affiche jamais les jetons. La déconnexion supprime l'autorisation locale ; le consentement du fournisseur est géré séparément. memories cloud sync téléverse et télécharge des objets chiffrés immuables via le dossier d'application OneDrive ou Google Drive connecté après actualisation des jetons. Le mobile fournit des contrôles de connexion cloud et de synchronisation au premier plan ; l'enregistrement d'un client OAuth natif est nécessaire. Consultez la configuration cloud mobile.

Consultez docs/cloud-authorization.md pour l'enregistrement fournisseur, les URI de redirection, --no-browser, l'expiration et le dépannage.

Appairage d'appareils et transfert de coffres

Initialisez le nouvel appareil avec son propre mot de passe et exécutez :

memories sudo
memories device invite request.json

Transférez la demande à un appareil existant. Comparez l'empreinte complète de l'invitation directement avec l'appareil demandeur avant de l'approuver :

memories sudo
memories device approve request.json approval.json --fingerprint REQUEST_FINGERPRINT

La commande d'approbation renvoie sa clé publique d'appareil. Vérifiez cette clé via un canal de confiance avant d'accepter la réponse sur le nouvel appareil. Exécutez sudo dans le même terminal sur le nouvel appareil avant l'acceptation :

memories sudo
memories device accept approval.json --sender APPROVING_DEVICE_PUBLIC_KEY

Les demandes expirent après dix minutes et sont à usage unique. Un appareil nouvellement initialisé ne doit avoir aucun coffre avant de rejoindre une identité existante. Chaque appareil conserve sa propre clé privée de transport et clé de signature d'appareil ; l'autorité de signature de l'identité utilisateur n'est transférée que dans l'approbation chiffrée. Un certificat signé par l'utilisateur ne suffit pas à accorder l'accès au coffre : la liste signée d'appareils autorisés du coffre doit aussi l'approuver.

Pour une personne différente, approuvez plutôt sa demande pour un coffre particulier :

memories member approve VAULT_ID request.json approval.json --fingerprint REQUEST_FINGERPRINT --role reader
memories member list VAULT_ID
memories member role VAULT_ID USER_PUBLIC_KEY editor
memories member remove VAULT_ID USER_PUBLIC_KEY
memories device revoke VAULT_ID DEVICE_PUBLIC_KEY

Les propriétaires gèrent les administrateurs et la propriété ; les administrateurs gèrent les membres ordinaires ; les éditeurs écrivent les éléments ; les lecteurs lisent et utilisent les éléments. La révocation d'appareil est propre à chaque coffre. Appliquez-la à chaque coffre concerné. Ne supposez jamais que supprimer un membre efface ses copies existantes.

L'échange de fichiers chiffrés fonctionne sans relais :

memories sync export VAULT_ID RECIPIENT_DEVICE_PUBLIC_KEY packet.json
memories sync import packet.json

Pour un transfert en ligne, exécutez memories-relay derrière un proxy inverse TLS et créez une salle avec memories sync room. Sur le destinataire, puis l'expéditeur :

memories sync receive --relay wss://relay.example.com --room ROOM
memories sync send VAULT_ID RECIPIENT_DEVICE_PUBLIC_KEY --relay wss://relay.example.com --room ROOM

Le relais ne met pas les paquets en attente pour les appareils hors ligne. Un envoi réussi signifie qu'un paquet a été remis au relais, pas qu'un pair l'a vérifié/importé ; le destinataire signale séparément la réussite de l'import. sync export/import et sync send/receive du relais sont des transferts explicites de coffres complets, pas une synchronisation cloud incrémentale automatique. cloud sync PROVIDER échange plutôt des objets chiffrés immuables via des files cloud durables ; la vérification sur comptes réels reste en attente. Le RPC du relais est encore différent : il appelle le daemon distant sans importer son coffre dans le stockage du client. Un client toujours connecté appartenant à l'utilisateur peut conserver une réplique, mais ce client est un point de terminaison de confiance plutôt qu'un serveur de stockage non fiable.

Chaque création/mise à jour écrit une nouvelle révision signée dans le DAG du coffre (mémoires, cartes de connaissances/Brain, métadonnées de cartes protégées, fichiers et identifiants). Utilisez memory history / card history / file history pour lister les révisions (revision, horodatage, auteur, tête, résumé). Récupérez une révision avec read --revision et comparez avec memory diff / card diff / file diff (texte unifié sur le titre, les métadonnées structurées et le corps ; les diffs de fichiers omettent les charges binaires ; les corps secrets des identifiants ne sont jamais renvoyés). Les révisions sont conservées indéfiniment avec le coffre, sans élagage automatique. Les modifications concurrentes d'éléments restent sous forme de plusieurs têtes. Utilisez memory history et explicitement memory put --id ASSET_ID --resolve après les avoir examinées. Les modifications d'une ancienne époque auparavant inconnues entrent dans sync quarantine ; sync reapply signe une nouvelle révision de l'époque actuelle. Les chaînes de permissions divergentes échouent en refusant l'accès. Un propriétaire valide sur les deux branches peut les examiner et exécuter sync resolve-policy VAULT_ID packet.json --keep-local, puis distribuer la résolution signée. Les conflits impliquant des transferts de propriété incompatibles restent bloqués plutôt que d'accorder un contrôle unilatéral à l'une des parties.

Audit et récupération

memories audit VAULT_ID --verify
memories sudo
memories audit VAULT_ID
memories backup offline-backup.memories

Les sauvegardes utilisent un mot de passe indépendant. Gardez-en une copie hors de l'appareil. Pour récupérer, démarrez un daemon avec un nouveau --home, puis exécutez :

memories --home NEW_DIRECTORY restore offline-backup.memories --name replacement
memories --home NEW_DIRECTORY sudo
memories --home NEW_DIRECTORY archive list

La récupération crée des coffres indépendants contenant les éléments actuels et les têtes de conflit conservées. Elle ne réactive pas d'anciennes autorisations de coffre partagé. Les versions d'origine, marqueurs de suppression et enregistrements d'audit signés restent dans l'archive de récupération chiffrée en lecture seule (archive history, archive read, archive audit). Rejoignez les coffres partagés actifs par un membre actuellement autorisé. Les valeurs historiques d'identifiants ne peuvent être affichées ni par les interfaces normales ni par celles des archives.

Injection de compétence dans les clients IA

Installez la compétence memories fournie pour qu'un client IA découvre comment rechercher, récupérer et enregistrer des connaissances Memories, répondre à partir de documents autorisés et utiliser les opérations autorisées sur les identifiants :

memories inject all --dry-run
memories inject all
memories inject codex
memories inject opencode claude
memories inject all --project /path/to/project

Par défaut, l'installation s'applique à tout l'utilisateur. --project DIRECTORY installe uniquement dans un répertoire de projet existant (utilisez --project . pour le répertoire courant). claude cible Claude Code, avec claude-code accepté comme alias.

Client Emplacement utilisateur Emplacement du projet
Codex ~/.agents/skills/memories/SKILL.md .agents/skills/memories/SKILL.md
OpenCode ~/.config/opencode/skills/memories/SKILL.md .opencode/skills/memories/SKILL.md
Claude Code ~/.claude/skills/memories/SKILL.md .claude/skills/memories/SKILL.md

~ est le répertoire personnel de l'utilisateur système, y compris %USERPROFILE% sur Windows. OpenCode respecte OPENCODE_CONFIG_DIR, puis un XDG_CONFIG_HOME absolu suivi de opencode, puis la valeur par défaut ci-dessus. Claude Code respecte CLAUDE_CONFIG_DIR. Codex utilise son emplacement documenté .agents/skills, indépendamment de CODEX_HOME. L'installation de projet ignore ces remplacements globaux. OpenCode découvre aussi les répertoires de compétences compatibles Claude/agent ; si vous utilisez plusieurs clients, conservez le même contenu de compétence memories partout pour éviter les définitions contradictoires.

L'installation est hors ligne et ne nécessite ni daemon ni stockage initialisé. Elle écrit uniquement la compétence fournie, sans lire/exporter le contenu des coffres, créer des autorisations ou modifier la configuration MCP/cliente. --home/MEMORIES_HOME sélectionnent le stockage de données Memories pour les opérations normales, pas la destination de la compétence ; l'installation n'intègre pas ce chemin. Configurez le même répertoire dans l'environnement du client ou la commande MCP si vous utilisez un stockage autre que celui par défaut.

Les fichiers existants identiques restent intacts. Un SKILL.md différent, y compris une ancienne compétence laissée par une version précédente de Memories, est refusé sauf si --force est passé ; cette option ne remplace que ce fichier, conservant les fichiers voisins. Les fichiers/répertoires de compétences liés sont refusés même avec --force. Toutes les cibles sont vérifiées pour les conflits avant écriture et chaque fichier est publié atomiquement. Un échec ultérieur d'E/S du système de fichiers peut laisser les premières cibles installées ; corrigez l'erreur et relancez. --dry-run effectue les mêmes vérifications et indique les chemins/actions prévus sans rien écrire ; utilisez --dry-run --force pour prévisualiser les remplacements.

Assurez-vous que memories est sur le PATH du client. Ouvrez une nouvelle session cliente si elle ne découvre pas immédiatement la compétence. Dans Codex, invoquez $memories ; dans Claude Code, /memories ; dans OpenCode, demandez le chargement de la compétence memories. L'installation locale d'une compétence n'installe pas de compétences au niveau du compte dans Claude Desktop/Cowork ou les sessions cloud. La compétence utilise une connexion MCP déjà configurée lorsqu'elle est disponible ; configurez-la séparément comme indiqué ci-dessous.

Conventions de découverte : Codex, OpenCode, Claude Code.

Générer AGENTS.md / une compétence persona

Écrivez un AGENTS.md de projet (ou un répertoire de compétence de type Cursor/Codex) expliquant comment utiliser Memories : coffres, cartes, persona/monde/objets, historique/diff et bases du daemon distant. Intégrez éventuellement un aperçu du noyau de persona :

memories skill generate --out AGENTS.md
memories skill generate --out AGENTS.md --persona VAULT/PERSONA
memories agents generate --out ./skills/memories-persona --layout skill --persona VAULT/PERSONA

--layout agents (par défaut) écrit un seul fichier markdown. --layout skill écrit SKILL.md sous le répertoire de sortie (ou le chemin s'il se termine déjà par .md). Lorsque --persona est omis, la valeur par défaut cliente persona est utilisée si elle est définie. Générer avec une persona lit cette carte via le daemon (déverrouillez d'abord). Sans persona, la génération est hors ligne et ne nécessite pas le daemon. Utilisez --force pour remplacer un fichier existant différent ; --dry-run prévisualise le plan sans écriture.

memories inject reste l'installateur hors ligne distinct de la compétence générique fournie vers les chemins Codex / OpenCode / Claude Code.

Valeurs par défaut de la CLI cliente

Les valeurs par défaut non secrètes résident dans defaults.json sous le répertoire Memories (MEMORIES_HOME / --home), pas dans le texte chiffré du coffre :

memories default set persona VAULT/PERSONA
memories default set vault VAULT_ID
memories default set type persona
memories default get
memories default get type
memories default delete type
Clé Signification
persona VAULT/ASSET utilisé lorsque les commandes persona omettent coffre/élément
vault Coffre par défaut pour list / card list et les formes persona à un argument
type Filtre --type par défaut pour les commandes de liste
category Filtre --category par défaut pour les commandes de liste
daemon URL --daemon par défaut
daemon_relay URL --daemon-relay par défaut
daemon_room --daemon-room par défaut

Les options explicites priment toujours. Les sous-commandes persona prenant coffre/élément traitent les arguments positionnels omis comme des valeurs par défaut (world-get, thing, append-event, …). persona import exige toujours un identifiant de coffre explicite avant le chemin de compétence (ordre positionnel clap).

MCP local

Cette section décrit les autorisations MCP ordinaires limitées au coffre. Le serveur sans surveillance distinct, activé volontairement, a un périmètre de lecture plus large.

memories sudo
memories mcp grant VAULT_ID PRIVATE_GRANT_FILE --minutes 15
memories mcp serve --grant-file PRIVATE_GRANT_FILE
memories mcp revoke PRIVATE_GRANT_FILE

L'autorisation est une capacité locale au porteur, écrite dans un fichier plutôt qu'affichée. Protégez ce fichier. Les autorisations donnent par défaut accès en lecture ; utilisez --scope read_write pour écrire du contenu ordinaire ou --scope read_write_delete pour inclure la suppression. --write est un raccourci de compatibilité pour --scope read_write. Ces portées ne donnent pas accès au contenu privé, aux fichiers, aux identifiants ou à sudo. Configurez la commande MCP stdio de votre client IA comme memories mcp serve --grant-file ... avec le même répertoire que le daemon actif. Les outils sont memory_search, memory_retrieve, memory_ask, memory_read, memory_read_revision, memory_history, memory_diff, memory_write, memory_delete, card_write, card_graph, card_link, workflow_card, workflow_read, workflow_update et workflow_list, plus les outils persona listés dans Cartes Persona. workflow_card crée des workflows à étapes, des modèles de checklist ou des tâches copiées depuis un modèle, et workflow_update modifie les champs de checklist ou avance les étapes ; les deux nécessitent une portée d'écriture. workflow_read et workflow_list fonctionnent avec l'accès en lecture. Chaque appel inclut l'identifiant du coffre autorisé. memory_retrieve renvoie des fragments de documents cités. Son mode par défaut est BM25 local ; vector et hybrid utilisent le fournisseur de plongements configuré du daemon. memory_ask répond depuis ces sources lorsqu'une URL de génération est configurée et rejette les citations absentes des preuves récupérées. Consultez Recherche et RAG. Les mémoires privées, fichiers, accès aux identifiants, exécution de processus et changements de membres des coffres sont exclus. L'émission, la liste, la révocation d'autorisations et les demandes de permission sont des outils MCP distincts et n'héritent pas de sudo. Le verrouillage abandonne les autorisations en mémoire ; les autorisations non expirées reprennent après déverrouillage. Protocole MCP : 2024-11-05. Les lectures MCP laissent les références de secrets non résolues. L'outil card_write actuel ne peut pas mettre à jour les cartes contenant des références de secrets car il ne préserve pas leur correspondance ; modifiez ces cartes via la CLI ou l'application mobile.

CLI/MCP de bureau sans surveillance

L'inscription explicite exige le consentement saisi ENABLE et un déverrouillage/sudo par mot de passe une fois pour la configuration. Choisissez délibérément le backend windows-dpapi, macos-keychain, linux-secret-service ou owner-file, moins protecteur, puis émettez un fichier client limité au coffre. Sélectionnez ce fichier avec unattended ... --client-file PATH ou mcp serve-unattended --client-file PATH. Ces clients peuvent lire le contenu ordinaire/privé, les fichiers originaux, l'historique et le texte clair des identifiants explicitement demandé, mais ne peuvent ni modifier les éléments ni hériter de sudo.

Le démarrage du daemon charge uniquement les clés, pas une autorisation ambiante ordinaire. lock manuel inhibe durablement l'accès sans surveillance jusqu'à unattended resume autorisé par mot de passe ; revoke supprime une autorisation et disable supprime toute autorité sans surveillance. Les stockages gérés par Center, transports distants et mobiles ne peuvent pas l'utiliser. MCP ordinaire est inchangé. Le base64 des identifiants est un encodage, pas un chiffrement : un client IA ou ses journaux peuvent conserver le secret. Consultez la configuration, les lectures par plage d'octets et les limites de sécurité.

Cartes de connaissances et cartes protégées

Toutes les cartes de connaissances prennent en charge les types de cartes et champs personnalisés : note, contact, lien, extrait de code, checklist, événement et identifiant, ainsi que des modèles de coffre réutilisables. Les champs sont ordonnés et validés ; les valeurs sensibles restent masquées sauf révélation explicite avec autorisation vérifiée. Utilisez memories type et memories card field, ou les éditeurs Flutter et les éditeurs de cartes de bureau restreints.

Les cartes prennent en charge étiquettes, sources, alias facultatif (别名), notes/remarque (备注), catégorie (分类), relations dirigées et liens retour. Le contenu ordinaire des cartes et les résumés sûrs des comptes sont consultables localement ; les lectures ordinaires de cartes privées nécessitent sudo et sont exclues de la recherche ordinaire et de MCP. L'autorité sans surveillance distincte peut lire les cartes privées dans sa portée. Utilisez --alias, --notes et --category à la création/mise à jour. card list (aussi memories list / memories ls au premier niveau) peut omettre l'identifiant de coffre pour parcourir tous les coffres accessibles (chaque résultat inclut vault). --type knowledge|brain|persona|workflow|account|env|token|totp|hotp|otp filtre par summary.type (knowledge désigne les cartes wiki/de connaissances simples ; brain désigne les connaissances structurées avec résumé et liens typés ; otp signifie totp+hotp) ; --otp est un raccourci pour --type otp. --category NAME filtre ; --group-by-category regroupe la sortie. La liste affiche alias, notes et catégorie lorsqu'ils sont présents.

memories card put VAULT_ID --title "An idea" --input notes.md --tag design --alias "Design note" --notes "from workshop" --category design
memories card list VAULT_ID
memories list
memories ls --type knowledge
memories card list --type brain
memories list --type otp
memories ls --otp --category security
memories card list VAULT_ID --type account
memories card list VAULT_ID --category design
memories card list VAULT_ID --group-by-category
memories card brain VAULT_ID --title "Alice" --abstract "Product lead bridging design and eng" \
  --link CARD_A=reports-to --link "OTHER_VAULT/CARD_B=collaborates|shared roadmap" \
  --alias "Alice" --notes "org chart" --category people
memories card brain VAULT_ID --id BRAIN_ID --title "Alice" --abstract "Updated abstract" --link CARD_B=partner
memories card link VAULT_ID CARD_A CARD_B --relation supports
memories card graph VAULT_ID
memories card graph VAULT_ID --include-private
memories card search VAULT_ID design
memories card unlink VAULT_ID CARD_A CARD_B --relation supports
memories card delete VAULT_ID CARD_ID

card delete (comme memory delete) retire la carte des vues actuelles ; l'historique signé conserve les révisions antérieures. Supprimer des cartes privées ou protégées nécessite sudo.

Les cartes Brain stockent un abstract en clair (consultable selon les permissions du coffre, pas un secret protégé) et des liens typés { vault?, card, role?, note? } pouvant traverser les coffres. Mettez entre guillemets toute la valeur --link lorsqu'elle contient | ou des espaces afin que le shell ne l'interprète pas comme un pipeline. summary.type est brain avec link_count. Liste/graphe/lecture résolvent les titres et types des liens lorsque permis et marquent les cibles absentes ou non autorisées broken (pas de suppression en cascade). La recherche indexe titre, résumé, rôles/notes des liens et résumés publics des cibles du même coffre, jamais les secrets. Les liens Brain du même coffre apparaissent aussi dans card graph.

Les cartes Persona (summary.type = persona) stockent un noyau d'identité interproduits avec des éléments d'archive liés, un timezone IANA pour raisonner sur les jours/périodes locaux (隔日 / 早课晚课), un domaine de monde (place / pose / look / things génériques avec attributs JSON libres / registre / météo / dés / roue / planning) et des événements de comportement en ajout seul horodatés en UTC et heure locale. Consultez docs/persona.md. Importez avec memories persona import VAULT_ID ./xiaoya-persona --timezone Asia/Shanghai ; mettez à jour l'état du monde avec memories persona world-set.

Les cartes de workflow (summary.type = workflow) conservent des étapes ordonnées sur la révision de carte, chacune pending, active, done ou skipped, plus un état global ; memories card workflow VAULT --title Release --step "Write notes" --step Ship en crée une, memories card workflow-update VAULT ASSET --advance avance d'une étape et memories card list --type workflow les liste.

Un modèle de checklist est créé avec memories card workflow VAULT --template --assignee NAME --summary OVERVIEW --goal GOAL (summary.type reste workflow, le champ de profil template est vrai), listé avec memories card list --type workflow --template et copié dans un workflow de tâche avec memories card workflow VAULT --template TEMPLATE, qui peut lier une autre carte de workflow avec --workflow WORKFLOW et archiver une mémoire avec --archive MEMORY.

Les liens dirigés ordinaires (card link) référencent les cartes du même coffre. Les graphes omettent les nœuds supprimés, en conflit et non autorisés ainsi que leurs arêtes incidentes. Les références restent dans l'historique chiffré. La récupération préserve les identifiants des éléments non ambigus pour que relations et références d'identifiants continuent de fonctionner dans le coffre indépendant récupéré ; les références aux éléments en conflit peuvent nécessiter une réparation. Le mobile affiche les liens sortants, liens retour et un graphe déplaçable/zoomable (jusqu'à 24 nœuds sur le canevas, avec sélection du graphe complet et listes de relations).

Les cartes protégées stockent les métadonnées et un identifiant distinct en une transaction :

Carte Recherche / affichage Valeur protégée
Compte e-mail E-mail, hôte SMTP, port, SSL Mot de passe
Connexion à un site web URL du site, nom d'utilisateur Mot de passe
.env Chaque nom de variable suivi de *** Fichier UTF-8 original
Cookie / JWT Hôte HTTPS autorisé exact, type d'en-tête Valeur d'en-tête Cookie ou jeton au porteur
TOTP Émetteur, compte, algorithme, chiffres, période Graine Base32
HOTP Émetteur, compte, algorithme, chiffres, compteur Graine Base32

Les connexions à des sites web sont généralement importées en lot plutôt que saisies une par une ; consultez Importer et exporter des connexions à des sites web.

memories sudo
memories card account VAULT_ID --title "Example mail" --email user@example.test --smtp smtp.example.test
memories card env VAULT_ID ./app.env --title "Application config"
memories card token VAULT_ID --title "API session" --host api.example.test
memories card token VAULT_ID --title "Browser session" --host app.example.test --cookie
memories card request VAULT_ID TOKEN_CARD_ID https://api.example.test/session
memories card otp VAULT_ID --title "Example OTP" --issuer Example --account user@example.test
memories card otp VAULT_ID --title "Example HOTP" --issuer Example --account user@example.test --hotp --counter 0
memories card otp-import VAULT_ID --title "Imported OTP" --alias "Work 2FA" --notes "laptop" --category otp 'otpauth://totp/Example:user@example.test?secret=GEZDGNBVGY3TQOJQGEZDGNBVGY3TQOJQ&issuer=Example'
memories card otp-import VAULT_ID --image ./ga-export.png --title "GA import" --category otp
memories card otp-code VAULT_ID OTP_CARD_ID

Les titres OTP peuvent conserver la forme issuer / account de l'import tandis que --alias et --notes stockent séparément un nom d'affichage et une remarque ; --category les regroupe dans card list.

Mots de passe, jetons, cookies et graines OTP utilisent une saisie masquée au terminal, jamais des arguments de commande. Entrez un JWT brut pour le mode bearer, ou name=value; other=value pour le mode cookie. Le SMTP des comptes utilise par défaut SSL sur le port 465 ; cela enregistre une configuration et n'envoie pas de courrier. Ajoutez --id CARD_ID pour remplacer les métadonnées et le secret d'une carte protégée ; l'identifiant du secret et les liens de carte sont conservés. Les identifiants d'identifiants sont des références, pas des valeurs secrètes. Les écritures génériques de cartes ne peuvent remplacer les références protégées.

L'importateur dotenv masque toutes les valeurs, y compris vides/non secrètes, et n'indexe jamais les valeurs ou commentaires. Il accepte un KEY=value par ligne, export facultatif, lignes vides et commentaires. Les clés dupliquées et valeurs multilignes entre guillemets sont rejetées. Il ne développe pas les variables et n'exécute pas le fichier. Le fichier source original reste à son emplacement ; l'import ne change pas ses permissions et ne l'efface pas. Les titres/notes libres des cartes ne constituent pas un système automatique de détection des secrets.

L'adaptateur HTTPS injecte Authorization: Bearer ... ou Cookie: ... sur le client. Il exige sudo, l'hôte approuvé exact, le port HTTPS 443 et GET/POST. Les redirections et proxies d'environnement sont désactivés ; seul l'état est renvoyé, les corps/en-têtes de réponse étant supprimés pour éviter une sortie reflétant un secret. C'est un adaptateur de requêtes autorisées, pas un proxy de transmission général ni un magasin de cookies de navigateur. L'expiration des cookies, le renouvellement JWT et la connexion automatique ne sont pas implémentés.

TOTP prend en charge SHA-1/SHA-256/SHA-512 (--algorithm), 6/8 chiffres (--digits) et des périodes de 30/60 secondes (--period). HOTP utilise les mêmes algorithmes et tailles de chiffres avec --hotp et un --counter initial (avancé à chaque otp-code). Importez des URI Google Key avec otp-import (otpauth://totp/... ou otpauth://hotp/...), des URI de migration Google Authenticator (otpauth-migration://offline?data=...) ou une image QR via --image (décodée avec rqrr en Rust pur). Le type TOTP/HOTP vient de l'URI ou de l'enregistrement de migration. Lorsque ce type est omis, un counter sélectionne HOTP et tout autre compte est TOTP. Les charges de migration peuvent créer plusieurs cartes ; --title est le titre d'une carte unique ou un préfixe de lot. otp-code renvoie le code de courte durée après sudo et audite la génération sans stocker le code dans les enregistrements d'audit ; les réponses HOTP incluent le compteur suivant. La recherche et MCP ne génèrent jamais de codes et ne renvoient jamais de graines. Le mobile masque les codes expirés et ferme la boîte de dialogue au verrouillage/passage en arrière-plan. Gardez l'horloge de l'appareil exacte pour TOTP. Le mobile ne scanne pas les QR OTP avec la caméra ; utilisez --image de la CLI ou collez une URI otpauth:// / de migration. L'appairage d'appareils hébergé a un flux caméra distinct ; consultez center.

Le mobile propose les actions Carte protégée, Importer .env et Importer des connexions (CSV). Les informations de base des comptes/identifiants apparaissent directement dans les résultats de recherche et détails de carte. Les cartes de jeton et OTP proposent les actions de menu Requête autorisée et Générer un OTP. La modification générique de carte préserve les métadonnées protégées ; le remplacement des secrets utilise actuellement la CLI.

Importer et exporter des connexions à des sites web

Les connexions à des sites web résident dans des cartes protégées login et sont déplacées en lot. L'import et l'export nécessitent memories sudo et un rôle autorisant l'écriture.

memories sudo
# Browser CSV (Chrome/Edge/Brave or Firefox about:logins); the header is detected.
memories login import VAULT_ID --from chrome passwords.csv
memories login import VAULT_ID --from firefox firefox-logins.csv --with-notes
# Read a Firefox profile directly (modern key4.db; prompts for any primary password).
memories login import VAULT_ID --from firefox-profile "/path/to/Profiles/xxxx.default"
# Windows Credential Manager generic credentials (Windows only).
memories login import VAULT_ID --from windows --filter github
memories login import VAULT_ID --from windows --all
# A previous encrypted export.
memories login import VAULT_ID --from memories logins.mlx

# Export: portable encrypted file (recommended) or a browser-compatible CSV.
memories login export VAULT_ID --format encrypted logins.mlx
memories login export VAULT_ID --format csv logins.csv

Une connexion ayant le même hôte de site et nom d'utilisateur qu'une carte existante est ignorée lorsque le mot de passe correspond et signalée comme conflit lorsqu'il diffère ; --update écrase à la place. Les lignes CSV incorrectes sont ignorées et signalées par numéro de ligne ; un import unique est plafonné à 2000 connexions. La colonne note du navigateur n'est importée qu'avec --with-notes, car les notes sont indexées comme texte ordinaire. La lecture directe Firefox gère le format de clé moderne (Firefox 58+) ; pour les anciens profils, exportez un CSV depuis about:logins. Lire les mots de passe enregistrés d'un navigateur nécessite de le fermer sur certaines plateformes et ne modifie jamais son stockage.

L'export chiffré utilise un mot de passe indépendant et s'importe dans n'importe quel coffre. L'export CSV est en clair pour déplacer les connexions vers un navigateur ou un autre gestionnaire de mots de passe : il est réservé à la CLI locale, affiche un avertissement, écrit un fichier réservé au propriétaire qui ne doit pas déjà exister, neutralise l'injection de formules de tableur et doit être supprimé après usage. Les coffres réservés à l'appareil ne peuvent être exportés.

Configuration réservée à l'appareil

memories local-python
memories local-python --program /path/to/python
memories vault list
memories card search LOCAL_VAULT_ID Python

Cela exécute l'interpréteur Python sélectionné en mode isolé pour enregistrer sa version et son répertoire exécutable. Cela ne collecte pas de variables d'environnement. Chaque appel enregistre une nouvelle observation dans le coffre chiffré Cet appareil avec local_only: true. Ce coffre entier est exclu des paquets d'autorisation d'appareil et des sauvegardes exportées ; les invitations de membres, exports/imports de synchronisation et synchronisations de politique sont rejetés. Il reste consultable sur cet appareil et survit au verrouillage/redémarrage, mais la récupération d'une sauvegarde exportée ne le restaure délibérément pas. Créez des cartes de connaissances dans ce coffre pour enregistrer d'autres configurations locales. L'appairage exige toujours une destination sans coffres existants ; appairez d'abord avant de créer ses observations de configuration locale.

Mettez à niveau tous les clients participants avant d'échanger des cartes : les anciens clients ne comprennent pas le nouveau type card et les métadonnées protégées.

Mobile

Au premier lancement, choisissez Standalone, Center ou SaaS. Standalone utilise la bibliothèque locale chiffrée. Center demande l'URL de votre serveur hébergé et le jeton de membre ; SaaS utilise https://memories.ivjn.us et demande un jeton de membre. Les modes hébergés ne nécessitent pas de créer ou déverrouiller une bibliothèque locale. Utilisez Changer de mode dans la barre d'outils principale pour changer ultérieurement ; les données existantes restent dans leur stockage d'origine. Consultez le guide mobile pour les étapes de connexion, fonctions disponibles, autorisation, modification et dépannage, ou le guide d'utilisation chinois.

Compiler et valider le client mobile

Utilisez Flutter 3.44.2 (version CI), JDK 17+, le SDK/NDK Android et cargo install cargo-ndk --locked. Cette copie de travail a été compilée avec NDK 28.2.13676358 et les plateformes SDK 35, 36 et 37.0 (le SDK Flutter et les plugins sélectionnent leurs plateformes de compilation). Acceptez les licences SDK Android avant de compiler. Rendez flutter disponible sur PATH et installez les cibles Rust aarch64-linux-android et x86_64-linux-android avec rustup target add.

.\scripts\build-android.ps1 -Apk

Cela compile les bibliothèques natives ARM64/x86_64 et un APK debug à mobile/build/app/outputs/flutter-apk/app-debug.apk. Les identifiants de signature release ne sont pas inclus. Sur macOS avec Xcode, utilisez bash scripts/build-ios.sh, puis signez et exécutez l'application avec votre propre équipe de développement. Les bibliothèques statiques iOS sont liées de force pour que les symboles FFI Dart restent disponibles.

Après compilation des bibliothèques natives, exécutez le véritable test de fumée de l'ABI mobile sur un appareil ou émulateur connecté depuis mobile :

flutter test integration_test/native_smoke_test.dart -d DEVICE_ID

Ce test utilise une bibliothèque temporaire et vérifie le stockage chiffré, l'autorisation, le refus de lecture d'identifiant, la vérification d'audit et le verrouillage/déverrouillage via Rust FFI. Recompilez ensuite l'APK normal car les tests d'intégration Flutter remplacent le point d'entrée de l'APK debug par leur lanceur de tests.

En mode Standalone, le client mobile utilise le même service Rust via C FFI, la recherche locale en texte intégral, les sélecteurs de fichiers, les fichiers d'approbation d'appareil/membre, les transferts en ligne par relais, les vues d'historique et d'audit. Un facteur local protégé par Keychain/Keystore complète le mot de passe. Le passage en arrière-plan efface l'autorisation et ferme les boîtes de dialogue de contenu ; Android bloque les captures d'écran et iOS masque l'aperçu du sélecteur d'applications. La synchronisation en arrière-plan n'est pas activée dans cette version.

Center et SaaS utilisent le client hébergé Rust via FFI pour les approbations de demandes, la consultation des connaissances, la recherche serveur, les détails, modifications, suppressions et l'appairage d'appareils. Les actions suivent la portée du jeton ; les cartes structurées/scellées nécessitent leurs éditeurs spécialisés. Le passage en arrière-plan ferme la session hébergée ; utilisez Reconnecter la session enregistrée ou saisissez à nouveau un jeton au retour. Consultez la comparaison des modes avant de choisir un workflow.

Dépôt

Composant Chemin
Cryptographie, modèle, stockage, sessions, service crates/core
CLI, IPC authentifié par le système, MCP, client relais crates/cli
Relais WebSocket sans état crates/relay
ABI C mobile crates/ffi
Client Flutter Android/iOS mobile
Aides de compilation et validation scripts, .github/workflows

Consultez docs/architecture.md et docs/validation.md pour les détails d'implémentation et de vérification. La conception du stockage et de la synchronisation OneDrive/Google Drive est documentée dans docs/cloud-storage-design.md. L'autorisation CLI et cloud sync sont implémentés ; les transferts des fournisseurs ont été testés avec des données de test locales, sans comptes réels. Les contrôles de connexion/synchronisation mobiles utilisent AppAuth et le worker Rust partagé ; le consentement réel et la vérification des plateformes restent des conditions de publication.