Memories
代码仓库:https://github.com/mbcc2006/memories。CLI 为 memories,中继为 memories-relay,原生库为 memories_ffi。
由客户端持有的加密记忆、私密文件和凭据,配有 Rust CLI、Android/iOS 客户端、本地 MCP 服务器和仅使用内存的 WebSocket 中继。
开发版本,格式版本 1。 本仓库包含可执行代码和安全回归测试。它尚未经过独立的密码学或应用安全审查。有关保证、信任边界和当前限制,请参阅 SECURITY.md。
各部分如何协作
独立使用时,Memories 在每台设备上保留加密本地存储。你可以用它保存可检索的知识、在客户端之间携带 AI 人格,或通过明确授权使用私密文件和秘密。云存储保存密文;中继只连接在线节点。两者都不能替代获授权的客户端。
移动应用还提供 Center(你的自托管服务器)和 SaaS(https://memories.ivjn.us)模式。这些模式使用独立的托管存储,其运营者能够读取内容。选择或切换模式不会上传、移动或合并现有本地资料库。参阅移动端模式。
Memories Web 连接到现有托管 Center,让你在浏览器中管理记忆、卡片和文件。新版 Center 也在 /app/ 提供它。访问令牌、允许的来源和支持的操作请参阅 Web 客户端指南。托管 SaaS API 位于 https://memories.ivjn.us;请使用为该服务签发的成员令牌。
| 概念 | 用途 |
|---|---|
存储(--home) |
此设备的数据目录、本地密码和身份。一个存储可以包含多个保险库;守护进程和客户端必须选择同一存储。 |
| 保险库 | 拥有独立成员、角色、设备权限和签名历史的集合。分享保险库,而非正在使用的存储目录。 |
| 记忆 | 笔记或日记等文本文档。 |
| 知识卡片 | 带有标签、来源、分类和关系的 Wiki 风格知识。 |
| 脑图卡片 | 带有摘要和类型化链接的结构化知识,包括跨保险库引用。它不是模型或推理引擎。 |
| 人格卡片 | 与归档、世界状态和行为事件关联的身份核心。参阅人格。 |
| 工作流卡片 | 有序步骤,具有待处理/进行中/已完成/已跳过状态和整体状态,以普通卡片修订存储。 |
| 文件 | 用于导入/导出的原始二进制内容,不会自动提取为可检索文本。 |
| 凭据 | 通过获授权操作使用的受保护秘密,不是用于检索或打印的普通文本。受保护卡片将安全元数据与独立凭据配对。 |
unlock 启用存储中的普通授权操作。memories sudo 为私密内容、文件、凭据和敏感管理添加短期会话;它不授予操作系统管理员权限,也不绕过保险库权限。普通保险库范围 MCP 授权是独立且受限的 AI 能力,不是终端的 sudo 权限。无人值守访问 是另行主动启用的只读能力,可以暴露私密内容和秘密值。
从这里开始
| 任务 | 指南 | 当前支持 |
|---|---|---|
| 保存并读取第一篇笔记 | 本地快速入门 | 初始化存储、创建保险库、写入和检索文本 |
| 在手机上开始使用或切换存储模式 | 移动端模式 | 独立模式、自托管 Center 或 SaaS;记住选择并保留独立连接配置 |
| 为 AI 客户端授予限定范围的知识访问权限 | 本地 MCP | 保险库范围授权;排除私密内容和凭据 |
| 检查桌面服务状态 | 托盘和 WebUI | Windows 托盘、macOS 菜单栏、只读状态和受限卡片编辑 |
| 配置存储和中继默认值 | 配置 | Windows、Linux 和 macOS 共用的 TOML 设置 |
| 检索文档并围绕文档提问 | 检索和 RAG | 中文 BM25、分块、本地 EmbeddingGemma、向量/混合检索和带引用的回答 |
| 签名/加密邮件或为应用签名 | 密码学任务 | S/MIME、OpenPGP、APK/AAB;macOS 上配置描述文件的 iOS .app |
| 向 AI 客户端添加 Memories 技能 | 技能注入 | Codex、OpenCode 和 Claude Code;用户或项目范围 |
| 允许无人值守桌面读取,包括秘密 | 无人值守 CLI/MCP | 主动启用的本地只读权限;Linux 已完成端到端测试,原生 Windows/macOS 和真实密钥环检查待完成 |
| 生成 AGENTS.md / 人格技能 | 技能生成 | CLI skill generate / agents generate;可选人格 |
| 设置客户端 CLI 默认值 | 客户端默认值 | Memories 主目录中的 persona、vault、type 等 |
| 捕获密码或命令输出 | 凭据捕获 | 隐藏输入、stdin、命令 stdout、正则表达式和 JSON 选择 |
| 保护或复制 Wiki 文档中的秘密 | Wiki 秘密引用 | 精确正文替换、加密凭据和获授权剪贴板复制 |
| 连接 OneDrive 或 Google Drive | 云授权 | 桌面登录、加密本地令牌、状态和退出登录 |
| 在设备之间传输保险库 | 设备配对 | 明确配对和加密保险库传输 |
| 通过云存储同步密文 | 存储设计 | 持久发件箱/收件箱、memories cloud sync、OneDrive/Google Drive 适配器;真实账号验证待完成 |
项目介绍网站:网站目录,提供静态英文/中文网站及 Cloudflare Pages 部署说明。
构建和运行
安装 Rust 1.88 或更新版本以及平台 C 工具链(SQLite 从源码编译)。
cargo build --workspace --locked
cargo test --workspace --locked
cargo clippy --workspace --all-targets --locked -- -D warnings
cargo install --path crates/cli --locked
在独立终端中启动 memories daemon。它在 Windows 上通过命名管道、在 Linux/macOS 上通过 Unix 套接字,仅为当前操作系统用户提供服务。通过 --home PATH 或 MEMORIES_HOME 使用专用数据目录;默认目录是操作系统应用数据目录。不要将 --home 指向已有通用文件夹:为保护本地服务,其权限会受到限制。
本地快速入门
安装 memories 并启动守护进程后,使用第二个交互式终端。对于新的独立存储:
memories init --name laptop
memories vault create Personal
memories vault list
创建名为 notes.md 的 UTF-8 文件,其中包含带有“project”的简短笔记。将下方 VAULT_ID 替换为 vault create 或 vault list 返回的 id,然后运行:
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 将正则表达式与所选保险库中普通记忆文档解密后的每一行正文进行匹配。它打印 DOCUMENT_ID:LINE,使用 -n / --line-number 时打印 DOCUMENT_ID:LINE_NUMBER:LINE;-i / --ignore-case 忽略大小写。与普通检索排除私密内容一样,它排除私密文档、冲突版本、卡片、文件和凭据。没有匹配时不产生输出。
将 ASSET_ID 替换为已保存笔记的 id。FROM_REVISION 使用 history 返回的 revision 字段;差异比较该修订与当前头部版本:
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
以后使用 unlock,不要使用 init。如果是加入已有身份的新设备,请先配对,再创建任何保险库。使用自定义存储时,为守护进程和每条客户端命令传递相同的 --home PATH。
用 memories --help 查看任务,再通过 memories memory --help 或 memories memory put --help 查看详细帮助。添加 --lang zh 获取中文帮助,例如 memories --lang zh memory put --help。帮助不需要守护进程。
密码从交互式终端读取且不回显。没有密码参数或密码环境变量。本地和备份密码没有应用级长度限制,包括空输入;密码确认和认证仍然适用。命令输出带版本的 JSON;失败命令返回非零退出状态。公开设备密钥和指纹有意保持可见;普通命令不打印私钥和凭据值。明确启用的无人值守凭据读取是例外,详见无人值守 CLI/MCP。
远程守护进程(HTTP/WebSocket / 中继 RPC)
可选的令牌认证 HTTP/WebSocket 监听和 WSS 中继 RPC 与本地 IPC 使用相同的带帧 service::Request 协议(桌面端 unlock/sudo 后具有完整功能;移动端共享保留 FFI 拒绝列表)。使用 memories daemon --listen http://127.0.0.1:7900(HTTPS/WSS 可选 --tls-cert / --tls-key)。RPC 在主机存储上执行操作;它不同步本地副本。监听/客户端参数、残余风险和移动端共享请参阅远程守护进程。
可选授权 Center 可以禁止本地自行初始化,并向端点分发注册/MCP 授权票据。memories-center --data DIR 还运行完整托管保险库:具有 mode = "saas" Center 条目的守护进程受其控制,运营者可以远程解锁,成员在 Center 上管理。
授权链
保险库角色为 Owner、Admin、Editor 和 Reader。只有 Admin 或 Owner 可以签发或委托授权;签发需要已解锁保险库但不需要终端提权,批准角色请求则需要提权。授权以签发者角色(及任何父授权)为上限,被授权者不得具有更高角色,且 center-admin 不能成为被授权者。委托深度最多为 2。省略范围意味着 read,而非 allow_all。权限请求发送给所有符合条件的审批者或指定的 --approver 成员;任何人都不能决定自己的请求。批准不返回令牌:请求者一次性领取(memories request claim、memories center request claim、MCP request_claim 或 POST /v1/requests/{id}/claim)。限制:每个请求者在每个保险库中最多 20 个待处理请求,每个保险库最多 200 个(Center 返回 HTTP 429),待处理 TTL 为 7 天,保留期为 30 天,守护进程和托管 Center 各自最多 10,000 个有效授权。memories access list VAULT 按层级展示成员、设备、待处理请求及已批准但未领取请求;memories grant list VAULT 列出授权。移除成员会级联撤销其授权(按成员代次);授权仅以哈希持久化,审计日志使用哈希链(Center:DIR/audit.jsonl)。参阅授权。
人格聊天(memories persona chat send|list|history|mark-read)触发 chat_message 自动化钩子;入站自动化 webhook 也可以通过 memories-relay 的 POST /v1/persona/{room}/{vault}/{persona}/automation/trigger 到达(参阅人格、远程守护进程)。
Linux 构建和打包
在 Debian/Ubuntu(包括 WSL2 中的 Ubuntu)上,安装 Rust 1.88+ 和原生构建依赖:
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
脚本为主机 GNU 目标构建 Rust 工作区:x86_64 或 aarch64。发布输出位于 target/<host-target>/release/(或配置的 Cargo 目标目录);调试输出使用 debug/。无需 Flutter SDK。Linux 支持 CLI、守护进程、中继、FFI 库和 memories webui;原生托盘当前仅支持 Windows/macOS。
从干净且已提交的检出目录创建 Linux 发布归档:
bash scripts/package-linux.sh
这会重新构建发布二进制,并将 .tar.gz、BUILD-INFO.json、SHA256SUMS 和示例配置写入 dist/vVERSION-linux-ARCH/。归档包含 memories、memories-relay、libmemories_ffi.so、C 头文件、文档和许可证,并保留可执行权限。不覆盖现有输出目录。手动的构建桌面安装包工作流也会构建并上传 Linux x86_64 包。
这些是原生 GNU/Linux 构建,不是静态或交叉编译二进制。使用兼容的 glibc/OpenSSL 运行时;在计划支持的最旧发行版上构建。系统 TLS 需要 ca-certificates,在桌面浏览器打开仪表板需要 xdg-utils。凭据剪贴板复制还需要 wl-clipboard(Wayland)或 xclip(X11)。模型权重通过 memories rag model-install 单独安装。
配置
运行 memories config init 创建 TOML 配置,运行 memories config path 查找位置,运行 memories config show 检查实际生效的设置。发布版本包含带有存储目录、中继和桌面选项的 memories.example.toml。通过 --config PATH 或 MEMORIES_CONFIG 选择其他文件。CLI 选项优先于环境变量,其次是配置,最后是默认值。参阅配置指南。
桌面托盘和状态仪表板
在 Windows 上,双击解压发布目录中的 memories-tray.exe。在 macOS 上打开打包的 Memories.app,或使用命令行:
memories tray
memories webui
托盘/菜单栏展示守护进程和保险库状态、打开本地 WebUI,并可以启动守护进程。仪表板报告锁定状态、资料库数量、连接数量和云同步队列,不显示已存内容。--home 选择与 CLI 相同的存储;--no-open 在启动时保持浏览器关闭。照常通过 CLI 初始化/解锁。行为和打包请参阅桌面指南。
语言
移动客户端和 CLI 支持英语(en)、简体中文(zh)、日语(ja)、德语(de)和法语(fr)。移动端语言菜单位于锁屏和资料库中。默认跟随系统,并在重启后记住手动选择。
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
CLI 语言选择依次使用 --lang、MEMORIES_LANG、已保存语言偏好,最后使用 LC_ALL、LC_MESSAGES 或 LANG 中第一个非空值。偏好按 --home / MEMORIES_HOME 存储,无需守护进程即可使用。在 Windows 上,若这些变量均未设置,也会使用操作系统语言。不支持的区域设置回退到英语;接受 fr_FR.UTF-8 和 zh-CN 等环境值。命令、选项名称、JSON 字段、错误码及确认词 USE 和 APPROVE 保持稳定。不翻译用户内容。没有译文的底层诊断保留原始详细信息,同时提供本地化错误摘要。维护请参阅本地化指南。
短 ID
CLI、MCP 和移动请求使用普通短十六进制 ID,通常为六个字符(例如 0b0668)。ID 不包含类型或分类含义,没有前缀或下划线。直接在对应命令中使用 vault list、card list、card search 或历史返回的 ID。拒绝长 UUID、完整修订哈希和带前缀 ID;没有长 ID 输出选项。
现有八字符 ID 仍然有效。前缀冲突时自动以两个字符为增量扩展,最多 16 个字符;拒绝有歧义的输入。这不会缩短设备密钥或安全指纹。
memories card list eb7abf
memories card search eb7abf "claude relay"
memories card read eb7abf 0b0668
ID 在各命令参数的范围内解析。冲突会将返回 ID 延长两个字符,最多 16 个;有歧义的输入失败,而不是选择某个对象。冲突后请重新列出或检索。已删除资产仍保留在冲突索引中。短 ID 是引用,不是授权:解锁、sudo、保险库权限和 MCP 授权仍然适用。
签名存储记录保留原始标识符,无需迁移。证书、公钥、验证指纹、审计记录和加密传输信封不会缩短或重写。
检索与 RAG
普通搜索现在会对中文进行分词,并支持多个关键词。其 BM25 索引缓存在内存中,在内容或策略变更时失效,并在锁定时清除。高级检索增加了分块偏移量、向量分数、混合排名融合、轻量重排,以及通过配置的 URL 启用的可选学习式重排。凭据和私有内容仍被排除。
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"
内置 CPU 推理引擎在 Memories 进程中运行 EmbeddingGemma,无需 Ollama 或其他推理应用。模型文件是公开数据,可通过 model-install 一次性安装,也可通过 rag.local_model_dir 提供。Gemini Embedding 是独立的在线 API。远程嵌入、生成和可选重排使用客户选择的 URL。HTTP(S)/SOCKS 代理、超时和有界重试均可配置。参见 RAG 指南。
私有文件与凭据
sudo 是内部授权会话,不是操作系统管理员权限。它使用相同的本地密码。提权最长持续 15 分钟,空闲五分钟后过期,且作用域限定为终端的父进程。锁定或重启服务会清除该会话。普通解锁在空闲 15 分钟后过期。
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
使用已存储的配置文件运行程序
memories file exec VAULT_ID FILE_ID -- PROGRAM ARGS... 读取已授权的文件,并将程序参数中的每个 {file} 替换为临时文件的绝对路径。在 -- 前使用 --revision REVISION 可选择历史版本。它与文件导出一样,需要解锁、保险库访问权限和终端中的 memories sudo。远程或托管守护进程可以提供文件;程序始终在 CLI 所在机器上,以 CLI 用户的账户运行。
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
子进程继承工作目录、环境和标准流;其退出码直接返回,不附带 JSON 成功封装。不插入 shell,也没有五分钟执行时限。请在前台运行程序。临时目录和文件仅所有者可访问(Unix 0700/0600;Windows 用户 ACL),并在子进程退出或启动失败后删除。Windows 上的 Ctrl+C/Ctrl+Break,以及 Unix 上的 SIGINT/SIGTERM/SIGHUP 会触发关闭流程,等待十秒后终止直接子进程并清理。Unix 信号会转发给子进程;Windows 控制台事件会传递给共享该控制台的进程。
这会在子进程存续期间导出明文。请信任程序及其插件:其输出不会脱敏。锁定或撤销授权无法收回已交付的副本,也无法停止子进程。强制终止 Memories、断电或关闭 Windows 控制台可能留下临时文件;删除不等于安全擦除。脱离的后代进程不受管理。每次调用使用一个名为 config 的固定文件快照,不会自动更新、重新加载、展开模板或导入关联文件。相对路径遵循目标程序的规则,因此外部包含文件和证书应使用绝对路径;当程序原本根据文件名推断格式时,请显式指定格式。
向进程注入凭据
凭据的 memories run 进程注入使用 stdin;--env 则显式允许使用环境变量。必须确认程序的 SHA-256 指纹,或通过 --approve-digest 提供。子进程的两个输出流都会被抑制。不过,接收程序仍可复制或传输凭据,因此必须可信。运行绑定将一个凭据固定到一个程序指纹,使编程代理无需使用你的终端 sudo 会话即可调用它。credential bind gh(需要 sudo 并输入 USE)从 PATH 解析 gh、记录其 SHA-256,并仅将绑定存储在此设备的加密状态中;它不会同步,并会在恢复时清除。绑定在 --hours 指定的时间后过期(默认 8,最多 720),且仅在库处于解锁状态时有效。随后,run --binding gh -- ARGS 会在当前目录运行程序,将凭据放入选定的环境变量,并转发程序输出,将每一处凭据替换为 [REDACTED](--suppress-output 则丢弃输出),最后以程序的退出码退出。--deny WORDS 会拒绝非标志参数按顺序包含这些词的命令;--ask WORDS 会使钩子在运行前询问。对于 gh,默认拒绝 auth、alias 和 extension(包括 extensions 和 ext),并在执行 pr merge、repo delete 和 release delete 前询问,除非使用 --no-default-rules。规则按输入的词匹配;先前通过 gh alias set 定义的别名不会展开。在绑定过期前,任何以你的身份运行的程序都能携带凭据运行绑定程序,但无法通过 Memories 读取凭据。程序自身、其扩展和子进程则可以读取,因此只应绑定可信程序。不带 --credential 和 --env 的绑定仅应用规则。
hook install --commands gh 会向 Claude Code 的用户设置添加 PreToolUse 钩子(先展示配置条目,并要求输入 APPROVE)。当 Claude Code 即将在 Bash 或 PowerShell 中运行 gh ... 时,钩子将该命令词改写为 memories run --binding gh --,并保持命令行其余部分不变。在 $( )、反引号、sh -c、xargs 和类似包装结构中运行的 gh 会被拒绝并说明原因;heredoc 内容及用作参数的替换表达式(例如 --body "$(cat <<'EOF' ... EOF)")可以使用。管道或重定向输入通过 --stdin 转发(最多 16 MiB)。程序在守护进程的环境中运行,因此不允许 NAME=value gh ... 前缀;请改用程序的标志。shell 在运行时展开的参数($var、通配符)无法按规则检查,因此钩子会在运行前询问。只有命令完全由绑定运行组成时,钩子才会直接批准;如果还运行其他程序或写入文件,仍需 Claude Code 的常规确认。对于仍在读取由绑定程序残留后代进程持有的管道的工作线程,其数量受到限制;残留数量过多时,会拒绝后续绑定运行。Claude Code 自身的拒绝和询问权限规则仍然有效,但它们可能看到改写后的命令,因此请在绑定规则中保留敏感子命令。绑定程序在服务锁之外运行,因此较长的 gh run watch 不会阻塞其他客户端;五分钟时限仍然适用。
HTTPS 接口仅通过 HTTPS/443 向配置的主机发送 Bearer 令牌,不跟随重定向,也不继承代理设置,并且仅返回状态码,以避免响应正文回显凭据。由守护进程持有的 SSH、FTP、TCP、MySQL、Redis 和 PostgreSQL 会话将秘密保留在服务中。每条指令先提出,经 APPROVE 批准后,在实际会话中执行一次。remote run 完成这三个步骤;脚本可以通过 remote propose(排队一张票据)、remote approve(需要 sudo,单次使用)和 remote exec(同一提权调用方)分别执行。SSH 接受密码凭据、导入的 OpenSSH 私钥(credential import),或在保险库内生成的密钥(credential generate)。生成操作不会打印私钥;credential public 仅返回 SSH 公钥或 TLS 证书。还可附加第二个 OpenSSH 证书凭据(--certificate)。SSH 还要求固定来自 remote probe 的主机密钥指纹。MySQL、Redis 和 PostgreSQL 会话默认使用 TLS 并验证主机名。Redis 和 PostgreSQL 使用 rustls 及 webpki 根证书;MySQL 使用平台 TLS 库。--tls-ca 添加保险库凭据中存储的 PEM CA;它与全局 --ca-file PATH(MEMORIES_CA_FILE)不同,后者为守护进程/中继 WSS 以及出站 HTTPS/数据库客户端添加文件系统中的 PEM CA 证书包。这些选项应设置在实际建立连接的进程上(对于守护进程持有的上游操作,应在启动守护进程时设置)。全局 --insecure 跳过证书和主机名验证,但不会禁用 TLS:危险,仅用于开发或自签名场景;优先使用 --ca-file。服务端的 --tls-cert / --tls-key 保持不变。参见客户端 TLS 示例。传入 --no-tls 可禁用数据库 TLS。MCP 不能使用此路径。文件操作使用 FTP;已批准的 SSH 会话仅接受 exec。
保护 wiki 文档中的秘密
在应用中,打开记忆/卡片菜单,选择 保护文档中的秘密(中文界面:替换资料中的密钥)。为引用命名(例如 API_KEY),然后通过隐藏输入填写准确的秘密并授权操作。该文档正文中所有完全匹配的内容都会替换为 {{secret:API_KEY}};值作为加密凭据存储。普通读取、搜索和 MCP 只能看到引用。
从文档或凭据菜单选择 复制密钥(复制密钥)。对于包含多个引用的文档,先选择标签。确认并授权后,将当前值复制到系统剪贴板,而不显示它。
CLI 提供相同操作(使用 list 或 search 中的短 ID):
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
替换命令会提示输入秘密;不要将秘密放在参数或引用名称中。标签允许使用 1-64 个 ASCII 字母、数字、下划线或连字符,且必须尚未在该文档中使用。复制文档引用必须提供 --label,即使只有一个引用。复制仅返回复制状态("copied": true)。Windows 使用原生剪贴板,macOS 使用 pbcopy,Linux 需要 wl-copy(Wayland)或 xclip(X11)。受保护的账户/令牌/env/OTP 卡片也可直接复制;复制 OTP 返回的是种子,而不是一次性验证码。
替换仅影响当前文档正文。旧的签名版本、备份、其他文档和共享副本仍保留原有内容;请通过提供商撤销或轮换已暴露的密钥。锁定后剪贴板内容仍然存在,其他应用或操作系统剪贴板历史可能读取到它。使用后请清除。该功能不会自动发现秘密或轮换密钥。在同步包含秘密引用的文档前,请更新所有客户端。有关拒绝条件、编辑与凭据更新、平台要求和剪贴板故障排查,参见完整指南。
无密码 SSH 与数据库代理
memories proxy start 在终端 sudo 和凭据主机允许列表检查通过后,打开一个 127.0.0.1 监听器。它返回 id、listen 地址以及可直接使用的 command。在守护进程所在机器上,从代理的终端运行该命令;不会返回已存储的密码或私钥。上游账户、主机和初始数据库由代理启动参数选择。代理授权该账户的命令,无需逐条批准。
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
先使用 credential allow-host VAULT_ID CREDENTIAL_ID HOSTNAME 授权凭据的目标主机。提供 --host-key 前,请通过可信渠道验证由 remote probe 获取的 SSH 指纹。SSH 代理转发 exec、shell、PTY 和子系统请求;上游主机密钥仍然固定。本地 SSH 主机密钥是临时的,因此返回的命令仅为本地端点禁用主机密钥持久化。
数据库上游默认使用经过验证的 TLS,可选用 --tls-ca CA_ID。本地数据库一跳是明文回环连接。PostgreSQL 支持 SCRAM-SHA-256、MD5 和密码认证。MySQL 支持 mysql_native_password 和 caching_sha2_password;完整 SHA-256 密码认证需要 TLS。尚未实现 PostgreSQL 取消请求/启动选项转发以及 MySQL 压缩。本地登录名和初始数据库请求不会覆盖配置的上游账户/数据库。
任何能访问本地端口的进程都能使用其授权的远程账户。请保持端口仅限本地访问。锁定、保险库自动空闲锁定、proxy stop 及守护进程关闭都会关闭监听器和现有连接。代理即使在使用中,也会在 30 分钟后过期;最多允许四个代理,每个代理最多 16 个连接。MCP 无法启动、列出或停止代理;用户启动代理后,代理程序使用其普通终端客户端连接。
捕获密码与命令输出
memories catch(也可使用 memories credential catch)捕获 UTF-8 秘密,并将其存储为加密凭据。请先在同一终端运行 memories sudo。不提供来源标志时,它会像 credential add 一样提示隐藏输入:
memories sudo
memories catch VAULT_ID "Database password"
对管道或重定向文件使用 --stdin。以下示例适用于 Windows CMD;secret-tool 代表你自己用于输出该值的程序:
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... 直接启动指定程序并捕获 stdout。它关闭子进程的 stdin,并抑制 stderr。对于 CMD 脚本,请使用 --exec cmd.exe -- /d /c script.cmd;shell 运算符需要显式选择 shell。此模式不支持需要终端的交互式外部程序;请改用隐藏输入或非交互式输出命令。
没有选择器时,捕获会保留完整文本,仅去掉最后一个 LF/CRLF。正则表达式必须恰好匹配一次;若有一个捕获组则保存该组,否则保存整个匹配。额外分组请使用 (?:...)。--json-pointer 选择 JSON 字符串(例如 /credentials/password);它不能与 --regex 组合使用。JSON 对象的键必须唯一,包括嵌套对象及 password 和 pass\u0077ord 等转义后等价的键。空值、无效 UTF-8、含糊的匹配、重复键和失败的命令都会被拒绝,不会保存。使用 --id CREDENTIAL_ID 可替换凭据。
输入上限为 1 MiB。命令在 30 秒后超时;如有需要,可将 --timeout 设置为 1-300 秒。超时或输出过多时,捕获会终止其直接子进程,但不会约束整个进程树。管道 stdin 等待 EOF,且没有超时。成功输出包含凭据 ID,绝不会包含捕获值。使用 memories run 或已授权的 HTTP 操作来使用该值。不要将真实秘密放在命令参数、正则表达式模式或标题中。捕获不会擦除源文件、shell 历史或来源程序生成的日志。
设备、成员与同步
云账户授权
使用你自行注册的 OAuth 应用,在当前设备上授权 OneDrive 或 Google Drive。启动当前守护进程,解锁资料库,并在登录前于同一终端运行 sudo:
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
登录会打开浏览器,并使用 PKCE/state 验证本地回调。令牌保存在设备本地的加密状态中,不包含在备份或设备交换中。状态命令从不输出令牌。注销会移除本地授权;提供商端的授权同意需要单独管理。memories cloud sync 刷新令牌后,通过已连接的 OneDrive 或 Google Drive 应用文件夹上传和下载不可变的密文对象。移动端提供云连接与前台同步控制;需要注册原生 OAuth 客户端。参见移动端云设置。
有关提供商注册、重定向 URI、--no-browser、过期和故障排查,请参见 docs/cloud-authorization.md。
设备配对与保险库传输
使用新设备自己的密码初始化设备,然后运行:
memories sudo
memories device invite request.json
将请求传输到现有设备。批准前,直接与发起请求的设备核对完整的邀请指纹:
memories sudo
memories device approve request.json approval.json --fingerprint REQUEST_FINGERPRINT
批准命令会返回批准设备的公钥。通过可信渠道验证该公钥后,再在新设备上接受响应。接受前,在新设备的同一终端运行 sudo:
memories sudo
memories device accept approval.json --sender APPROVING_DEVICE_PUBLIC_KEY
请求在十分钟后过期,且只能使用一次。新初始化的设备必须没有任何保险库,才能加入现有身份。每台设备保留自己的传输私钥和设备签名密钥;用户身份的签名权限仅在加密的批准响应内传输。仅有用户签名的证书并不能获得保险库访问权限:保险库签名的设备允许列表也必须批准该设备。
对于其他人,应改为批准其访问某个特定保险库的请求:
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
所有者管理管理员和所有权;管理员管理普通成员;编辑者写入资产;读取者读取和使用资产。设备撤销按保险库生效,需要对每个受影响的保险库执行。切勿认为移除成员就会删除其已有副本。
加密文件交换无需中继:
memories sync export VAULT_ID RECIPIENT_DEVICE_PUBLIC_KEY packet.json
memories sync import packet.json
若要在线传输,在 TLS 反向代理后运行 memories-relay,并使用 memories sync room 创建房间。先在接收端、再在发送端运行:
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
中继不会为离线设备排队保存数据包。发送成功表示数据包已交给中继,并不表示对端已验证或导入它;接收端会单独报告导入成功。sync export/import 和中继 sync send/receive 是显式执行的完整保险库传输,并非自动增量云同步。cloud sync PROVIDER 则通过持久云队列交换不可变的密文对象;真实账户验证仍待完成。中继 RPC 又有所不同:它调用远程守护进程,而不将远程保险库导入客户端存储。用户拥有的常在线客户端可以持有副本,但该客户端属于可信端点,而非不受信任的存储服务器。
每次创建或更新都会在保险库 DAG 中写入新的签名修订(包括记忆、知识/脑卡片、受保护卡片元数据、文件和凭据)。使用 memory history / card history / file history 列出修订(revision、时间戳、作者、头节点、摘要)。使用 read --revision 获取修订,并通过 memory diff / card diff / file diff 比较(对标题、结构化元数据和正文生成统一文本差异;文件差异省略二进制载荷;绝不返回凭据的秘密正文)。修订随保险库无限期保留,不会自动裁剪。资产的并发编辑会保留为多个头节点。使用 memory history 查看并审查后,再显式执行 memory put --id ASSET_ID --resolve。此前未知的旧纪元变更会进入 sync quarantine;sync reapply 会签署一个当前纪元的新修订。权限链发生分歧时会拒绝操作。同时在两个分支上有效的所有者可以审查它们并运行 sync resolve-policy VAULT_ID packet.json --keep-local,然后分发签名的解决结果。涉及不兼容所有权转移的冲突会继续阻止操作,不会授予任一方单方面控制权。
审计与恢复
memories audit VAULT_ID --verify
memories sudo
memories audit VAULT_ID
memories backup offline-backup.memories
备份使用独立密码。请在设备之外保留一份副本。恢复时,使用新的 --home 启动守护进程,然后运行:
memories --home NEW_DIRECTORY restore offline-backup.memories --name replacement
memories --home NEW_DIRECTORY sudo
memories --home NEW_DIRECTORY archive list
恢复会创建独立保险库,包含当前资产和保留的冲突头节点。它不会恢复已失效的共享保险库权限。原始版本、删除标记和签名审计记录会保留在加密、只读的恢复归档中(archive history、archive read、archive audit)。请通过当前已获授权的成员重新加入正在使用的共享保险库。普通接口和归档接口均不能输出历史凭据值。
AI 客户端技能注入
安装内置的 memories 技能,让 AI 客户端了解如何搜索、检索和保存 Memories 知识,依据已授权文档回答问题,并使用已授权的凭据操作:
memories inject all --dry-run
memories inject all
memories inject codex
memories inject opencode claude
memories inject all --project /path/to/project
默认安装范围是当前用户。--project DIRECTORY 仅安装到现有项目目录(使用 --project . 指定当前目录)。claude 指向 Claude Code,也接受 claude-code 作为别名。
| 客户端 | 用户级位置 | 项目级位置 |
|---|---|---|
| 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 |
~ 表示操作系统用户的主目录,在 Windows 上包括 %USERPROFILE%。OpenCode 优先使用 OPENCODE_CONFIG_DIR,其次使用绝对路径的 XDG_CONFIG_HOME 加上 opencode,最后使用上表中的默认位置。Claude Code 使用 CLAUDE_CONFIG_DIR。Codex 使用其文档规定的 .agents/skills 位置,与 CODEX_HOME 无关。项目级安装忽略这些全局覆盖设置。OpenCode 也会发现兼容 Claude/agent 的技能目录;使用多个客户端时,请让所有位置的 memories 技能内容保持一致,以免定义冲突。
安装完全离线,不需要守护进程或已初始化的存储。它仅写入内置技能,不读取或导出保险库内容,不创建授权,也不修改 MCP/客户端配置。--home/MEMORIES_HOME 为常规操作选择 Memories 数据存储,不决定技能安装位置;安装过程不会嵌入该路径。使用非默认存储时,请在客户端环境或 MCP 命令中配置相同的主目录。
已有的相同文件保持不变。若现有 SKILL.md 内容不同,包括旧版 Memories 留下的技能,安装会拒绝覆盖,除非传入 --force;该选项仅替换此文件,保留同目录中的其他文件。即使使用 --force,也会拒绝链接形式的技能文件或目录。写入前会检查所有目标是否存在冲突,并以原子方式发布每个文件。之后发生的文件系统 I/O 故障可能导致较早的目标已完成安装;修复错误后重新运行即可。--dry-run 执行相同检查并报告计划路径和操作,但不写入任何内容;使用 --dry-run --force 可预览替换操作。
确保 memories 位于客户端的 PATH 中。若客户端未立即发现技能,请开启新的客户端会话。在 Codex 中调用 $memories;在 Claude Code 中调用 /memories;在 OpenCode 中请求加载 memories 技能。本地技能安装不会为 Claude Desktop/Cowork 或云端会话安装账户级技能。若已有 MCP 连接,技能会使用该连接;请按下文说明单独配置。
发现约定:Codex、OpenCode、Claude Code。
生成 AGENTS.md / 人设技能
编写项目 AGENTS.md(或 Cursor/Codex 风格的技能目录),说明如何操作 Memories:保险库、卡片、人设/世界/事物、历史/差异,以及远程守护进程基础。还可选择嵌入人设核心概览:
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(默认)写入单个 Markdown 文件。--layout skill 在输出目录下写入 SKILL.md(若路径已以 .md 结尾,则写入该路径)。省略 --persona 时,若客户端设置了默认 persona,则使用该值。指定人设进行生成时,会通过守护进程读取该卡片(需先解锁)。不指定人设时,生成完全离线,无需守护进程。使用 --force 替换内容不同的现有文件;--dry-run 可预览计划而不写入。
memories inject 仍是独立的离线安装器,用于将内置通用技能安装到 Codex / OpenCode / Claude Code 路径。
客户端 CLI 默认值
非秘密默认值保存在 Memories 主目录(MEMORIES_HOME / --home)下的 defaults.json 中,不存入保险库密文:
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
| 键 | 含义 |
|---|---|
persona |
人设命令省略保险库/资产时使用的 VAULT/ASSET |
vault |
list / card list 和单参数人设形式的默认保险库 |
type |
列表命令的默认 --type 筛选条件 |
category |
列表命令的默认 --category 筛选条件 |
daemon |
默认 --daemon URL |
daemon_relay |
默认 --daemon-relay URL |
daemon_room |
默认 --daemon-room |
显式标志始终优先。接受保险库/资产的人设子命令会将省略的位置参数视为默认值(world-get、thing、append-event、…)。persona import 仍要求在技能路径之前显式提供保险库 ID(遵循 clap 的位置参数顺序)。
本地 MCP
本节介绍常规的保险库范围 MCP 授权。需要单独启用的无人值守服务器具有更广的读取边界。
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
授权是一种本地持有者能力,写入文件而不会直接输出。请保护该文件。授权默认提供读取访问;使用 --scope read_write 允许写入普通内容,或使用 --scope read_write_delete 同时允许删除。--write 是兼容性简写,等同于 --scope read_write。这些范围不授予私密内容、文件、凭据或 sudo 访问权限。将 AI 客户端的 stdio MCP 命令配置为 memories mcp serve --grant-file ...,并使用与运行中守护进程相同的主目录。工具包括 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 和 workflow_list,以及人设卡片中列出的人设工具。workflow_card 创建步骤工作流、检查清单模板或从模板复制的任务,workflow_update 编辑检查清单字段或推进步骤;两者都需要写入范围。workflow_read 和 workflow_list 只需读取访问权限。每次调用都包含已授权的保险库 ID。memory_retrieve 返回带有引用的文档片段。默认模式为本地 BM25;vector 和 hybrid 使用守护进程配置的嵌入提供商。配置生成 URL 后,memory_ask 会依据这些来源回答,并拒绝不在检索证据中的引用。参见检索与 RAG。私密记忆、文件、凭据访问、进程执行和保险库成员变更均不在范围内。授权签发、列出、撤销和权限请求是独立的 MCP 工具,不继承 sudo。锁定会移除内存中的授权;尚未过期的授权会在解锁后恢复。MCP 协议:2024-11-05。
MCP 读取不会解析秘密引用。目前的 card_write 工具无法更新包含秘密引用的卡片,因为它不能保留这些引用的映射;请通过 CLI 或移动应用编辑此类卡片。
无人值守桌面 CLI/MCP
显式启用需要输入 ENABLE 表示同意,并在设置时完成一次密码解锁/sudo。请明确选择 windows-dpapi、macos-keychain、linux-secret-service 或保护程度较低的 owner-file 后端,然后签发限定到保险库范围的客户端文件。通过 unattended ... --client-file PATH 或 mcp serve-unattended --client-file PATH 选择该文件。这些客户端可读取普通/私密内容、原始文件、历史记录及显式请求的凭据明文,但不能修改资产或继承 sudo。
守护进程启动仅加载密钥,不自动提供常规授权。手动执行 lock 会持续禁止无人值守访问,直到通过密码授权执行 unattended resume;revoke 移除一项授权,disable 移除所有无人值守权限。由 Center 管理的存储、远程传输和移动端无法使用此功能。常规 MCP 的行为不变。凭据的 base64 是编码,而非加密:AI 客户端或其日志可能保留秘密。参见设置、字节范围读取与安全限制。
知识卡片与受保护卡片
所有知识卡片都支持卡片类型和自定义字段:
笔记、联系人、链接、代码片段、清单、事件和凭据,以及可复用的保险库模板。
字段按顺序排列并经过验证;敏感值保持遮蔽,只有在经过验证的授权下主动显示时才会显露。
使用 memories type 和 memories card field,或 Flutter 和受限桌面端的卡片编辑器。
卡片支持标签、来源、可选别名、备注、分类、有向关系和反向链接。
普通卡片内容和安全的账户摘要可在本地搜索;常规读取私密卡片需要
sudo,且私密卡片不包含在普通搜索和 MCP 中。独立的无人值守授权可读取
授权范围内的私密卡片。创建或更新时使用 --alias、--notes 和 --category。
card list(也可使用顶层命令 memories list / memories ls)可省略保险库 ID,以扫描所有可访问的保险库
(每条结果都包含 vault)。--type knowledge|brain|persona|workflow|account|env|token|totp|hotp|otp 按
summary.type 筛选(knowledge 是普通 wiki/知识卡片;brain 是带摘要和类型化链接的结构化知识;otp 表示 totp+hotp);
--otp 是 --type otp 的简写。--category NAME 用于筛选;--group-by-category 按分类分组输出。
列表会显示已有的别名、备注和分类。
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(与 memory delete 一样)会从当前视图中移除卡片;签名历史保留
较早的修订版本。删除私密或受保护卡片需要 sudo。
Brain 卡片存储明文 abstract(可在保险库权限范围内搜索,不属于受保护秘密),以及可跨保险库的类型化链接 { vault?, card, role?, note? }。当 --link 值包含 | 或空格时,请为整个值加上引号,以免 shell 将其解释为管道。summary.type 为 brain,并带有 link_count。列表、图谱和读取操作会在权限允许时解析链接目标的标题和类型,并将缺失或未授权的目标标记为 broken(不执行级联删除)。搜索会索引标题、摘要、链接角色/备注,以及同一保险库内公开目标的摘要,绝不索引秘密。同一保险库内的 brain 链接也会出现在 card graph 中。
Persona 卡片(summary.type = persona)存储跨产品的身份核心、关联的归档资产、用于本地日期/时段推理(隔日 / 早课晚课)的 IANA timezone、世界领域(place / pose / look / 带自由 JSON 属性的通用 things / 账本 / 天气 / 骰子 / 转盘 / 日程),以及同时记录 UTC 和本地时间、仅可追加的行为事件。参见 docs/persona.md。使用 memories persona import VAULT_ID ./xiaoya-persona --timezone Asia/Shanghai 导入;使用 memories persona world-set 更新世界状态。
Workflow 卡片(summary.type = workflow)在卡片修订版本中保存有序步骤,每一步的状态为 pending、active、done 或 skipped,并带有整体状态;memories card workflow VAULT --title Release --step "Write notes" --step Ship 创建工作流,memories card workflow-update VAULT ASSET --advance 推进步骤,memories card list --type workflow 列出工作流。
使用 memories card workflow VAULT --template --assignee NAME --summary OVERVIEW --goal GOAL 创建清单模板(summary.type 仍为 workflow,配置字段 template 为 true),使用 memories card list --type workflow --template 列出模板,使用 memories card workflow VAULT --template TEMPLATE 将模板复制为任务工作流。任务工作流可通过 --workflow WORKFLOW 关联另一张工作流卡片,并通过 --archive MEMORY 归档记忆。
普通有向链接(card link)引用同一保险库内的卡片。图谱会省略已删除、存在冲突和
未授权的节点及其关联边。引用仍保留在加密历史中。
恢复会保留无歧义资产的 ID,使关系和凭据引用在恢复后的独立保险库中
继续有效;指向冲突资产的引用可能需要修复。移动端显示出站链接、
反向链接,以及可平移/缩放的图谱(画布最多显示 24 个节点,同时提供完整图谱
选择和关系列表)。
受保护卡片将元数据和独立凭据作为一个事务存储:
| 卡片 | 搜索 / 显示 | 受保护值 |
|---|---|---|
| 邮箱账户 | 邮箱、SMTP 主机、端口、SSL | 密码 |
| 网站登录 | 网站 URL、用户名 | 密码 |
.env |
每个变量名后跟 *** |
原始 UTF-8 文件 |
| Cookie / JWT | 精确授权的 HTTPS 主机、请求头类型 | Cookie 请求头值或 bearer token |
| TOTP | 签发者、账户、算法、位数、周期 | Base32 种子 |
| HOTP | 签发者、账户、算法、位数、计数器 | Base32 种子 |
网站登录通常批量导入,而不是逐条输入;参见 导入和导出网站登录。
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
OTP 标题可保留导入时的 issuer / account 格式,而 --alias 和
--notes 分别保存显示名称和备注;--category 用于在
card list 中分组。
密码、令牌、Cookie 和 OTP 种子使用终端隐藏输入,绝不通过命令参数传递。
bearer 模式输入原始 JWT,cookie 模式输入 name=value; other=value。
账户 SMTP 默认使用 SSL 端口 465;这只记录配置,不发送邮件。
添加 --id CARD_ID 可替换受保护卡片的元数据和秘密;
凭据 ID 和卡片链接会保留。凭据 ID 是引用,不是秘密值。
通用卡片写入不能替换受保护引用。
dotenv 导入器遮蔽所有值,包括空值和非秘密值,且绝不索引值或注释。
它接受每行一个 KEY=value、可选的 export、空行和注释。
重复键和多行引号值会被拒绝。它不会展开变量或执行文件。
原始源文件仍保留在原位置;导入不会更改其权限或删除它。
自由格式的卡片标题/备注不具备自动秘密检测功能。
HTTPS 适配器在客户端注入 Authorization: Bearer ... 或 Cookie: ...。
它要求 sudo、精确获批的主机、HTTPS 端口 443,以及 GET/POST。
重定向和环境代理被禁用;仅返回状态,并隐藏响应正文/请求头,
以防秘密经响应回显输出。这是经过授权的请求适配器,不是通用转发代理或浏览器
Cookie 存储。尚未实现 Cookie 过期、JWT 刷新和自动登录。
TOTP 支持 SHA-1/SHA-256/SHA-512(--algorithm)、6/8 位数字(--digits),以及
30/60 秒周期(--period)。HOTP 使用相同的算法和位数,
通过 --hotp 和初始 --counter 配置(每次 otp-code 时递增)。使用
otp-import 导入 Google Key URI(otpauth://totp/... 或 otpauth://hotp/...)、
Google Authenticator 迁移 URI(otpauth-migration://offline?data=...),或通过
--image 导入二维码图片(使用纯 Rust 的 rqrr 解码)。TOTP/HOTP 类型
来自 URI 或迁移记录。省略类型时,带有 counter 的账户
使用 HOTP,其余账户使用 TOTP。迁移载荷可能
创建多张卡片;--title 用作单张卡片的标题或批次前缀。
otp-code 在 sudo 后返回短期验证码,并审计生成操作,但不会
在审计记录中存储验证码;HOTP 响应包含下一个计数器值。
搜索和 MCP 绝不生成验证码或返回种子。移动端隐藏过期验证码,
并在锁定/进入后台时关闭对话框。使用 TOTP 时请保持设备时钟准确。
移动端不支持通过摄像头扫描 OTP 二维码;请使用 CLI --image,或粘贴
otpauth:// / 迁移 URI。托管设备配对有独立的摄像头流程;
参见 center。
移动端提供受保护卡片、导入 .env 和导入登录(CSV)操作。 账户/凭据的基本信息直接显示在搜索结果和卡片详情中。 Token 和 OTP 卡片提供授权请求和生成 OTP 菜单操作。通用卡片编辑会保留受保护元数据;目前需使用 CLI 替换秘密。
导入和导出网站登录
网站登录保存在 login 受保护卡片中,支持批量迁移。导入和
导出需要 memories sudo 和可写角色。
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
若登录信息的网站主机和用户名与现有卡片相同,密码一致时跳过,
密码不同时报告冲突;使用 --update 则覆盖现有信息。
无效 CSV 行会跳过并报告行号;一次导入最多 2000 条登录信息。
浏览器 note 列仅在使用 --with-notes 时导入,因为备注会作为普通文本索引。
Firefox 直接读取支持现代密钥格式(Firefox 58+);较旧的配置文件请
从 about:logins 导出 CSV。在某些平台上读取浏览器保存的密码需要
关闭浏览器;读取绝不会修改浏览器的存储。
加密导出使用独立密码,可导入任意保险库。 CSV 导出为明文,用于将登录信息迁回浏览器或其他密码管理器: 它仅可通过本地 CLI 使用,会显示警告,写入仅所有者可访问且必须尚不存在的文件, 消除电子表格公式注入风险,并应在使用后删除。 仅限本设备的保险库不可导出。
仅限本设备的配置
memories local-python
memories local-python --program /path/to/python
memories vault list
memories card search LOCAL_VAULT_ID Python
此命令以隔离模式运行所选 Python 解释器,以记录其版本
和可执行文件目录。它不收集环境变量。每次调用都会
在加密的此设备保险库中记录一条新的观测,带有
local_only: true。整个保险库都被排除在设备授权包
和导出的备份之外;成员邀请、同步导出/导入和
策略同步会被拒绝。它仍可在本设备上搜索,并在锁定/重启后保留,
但导出备份的恢复过程有意不恢复它。
可在此保险库中创建知识卡片,记录其他本地配置。设备
配对仍要求目标设备上没有现有保险库;请先配对,
再创建目标设备的本地配置观测。
交换卡片前请升级所有参与的客户端:旧客户端无法
识别新的 card 类型和受保护元数据。
移动端
首次启动时,选择独立模式、中心模式或 SaaS。独立模式使用
加密的本地资料库。中心模式要求输入托管服务器 URL 和成员
令牌;SaaS 使用 https://memories.ivjn.us,并要求输入成员令牌。托管
模式无需创建或解锁本地资料库。之后可使用主工具栏中的切换模式
进行更改;现有数据仍保存在原存储中。
连接步骤、可用功能、授权、编辑和故障排查请参见
移动端指南,或
中文使用指南。
构建和验证移动客户端
使用 Flutter 3.44.2(CI 版本)、JDK 17+、Android SDK/NDK,以及
cargo install cargo-ndk --locked。此检出使用 NDK 28.2.13676358
和 SDK 平台 35、36、37.0 构建(Flutter SDK 和插件选择各自的编译
平台)。构建前接受 Android SDK 许可。确保 flutter 在
PATH 中可用,并使用 rustup target add 安装 aarch64-linux-android 和 x86_64-linux-android Rust
目标。
.\scripts\build-android.ps1 -Apk
此命令构建 ARM64/x86_64 原生库,并在
mobile/build/app/outputs/flutter-apk/app-debug.apk 生成调试 APK。未包含发布签名凭据。
在安装 Xcode 的 macOS 上,使用 bash scripts/build-ios.sh,然后
使用自己的开发团队签名并运行应用。iOS 静态库会被强制
链接,以保持 Dart FFI 符号可用。
构建原生库后,从 mobile 在已连接的
设备或模拟器上运行实际的移动端 ABI 冒烟测试:
flutter test integration_test/native_smoke_test.dart -d DEVICE_ID
此测试使用临时资料库,并通过 Rust FFI 检查加密存储、授权、 拒绝凭据读取、审计验证,以及锁定/解锁。 之后请重新构建普通 APK,因为 Flutter 集成测试会将 调试 APK 的入口替换为测试运行器。
独立模式下,移动客户端通过 C FFI 使用同一 Rust 服务、本地全文搜索、 文件选择器、设备/成员审批文件、在线中继传输、历史和 审计视图。受 Keychain/Keystore 保护的本地因子作为密码的补充。 进入后台会清除授权并关闭内容对话框;Android 禁止 截图,iOS 遮盖应用切换器快照。此版本未启用 后台同步。
中心模式和 SaaS 通过 FFI 使用 Rust 托管客户端,支持请求审批、 知识浏览、服务器端搜索、详情、编辑、删除和设备 配对。操作遵循令牌范围;结构化/密封卡片需要各自的 专用编辑器。进入后台会关闭托管会话;返回时使用重新连接已保存的 会话,或再次输入令牌。选择工作方式前请参见 模式比较。
仓库
| 组件 | 路径 |
|---|---|
| 密码学、模型、存储、会话、服务 | crates/core |
| CLI、经操作系统认证的 IPC、MCP、中继客户端 | crates/cli |
| 无状态 WebSocket 中继 | crates/relay |
| 移动端 C ABI | crates/ffi |
| Flutter Android/iOS 客户端 | mobile |
| 构建辅助工具和验证 | scripts、.github/workflows |
实现和验证详情请参见 docs/architecture.md 和
docs/validation.md。
OneDrive/Google Drive 存储和同步设计记录于
docs/cloud-storage-design.md。CLI 授权
和 cloud sync 已实现;提供商传输已使用本地测试数据验证,
未使用真实账户。移动端登录/同步控件使用 AppAuth 和共享 Rust
工作器;真实授权同意流程和平台验证仍是发布门槛。