关于 aim-init
aim-init 是将代码仓库接入 ai-memory 实例的 Agent 技能,适用于设置或更新项目记忆的团队与开发者。它涵盖诊断、安装、从 qmd 迁移,以及更新本地 CLI 和钩子。
主要功能
- 01只读设置诊断
- 02全新配置 ai-memory
- 03从 qmd 迁移
- 04更新 CLI 和钩子
- 05配置项目路由
适用场景
- 01检查仓库是否需要迁移
- 02启用会话自动捕获
- 03将 qmd 仓库迁至 ai-memory
- 04更新本地 CLI 和 Agent 钩子
MCP 相关
此技能为受支持的客户端配置 MCP 服务条目,以连接 ai-memory 实例;项目范围的记忆召回也通过 ai-memory MCP 完成。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ djalmajr/ skills --skill aim-init安装后在 Claude Code 中输入/aim-init确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/usage.mdscripts/dev-setup-hooks.ps1dev-setup-hooks.shkc-create-device-client.shtemplates/ai-memory.toml.exampleai-memory.toml.tmplmcp-entry.json.tmplrouting-snippet.md.tmpl详细介绍
aim-init
将仓库接入 ai-memory,让会话自动捕获信息,并让 Agent 回忆持久知识。适用于全新项目或已有项目(包括从旧的 qmd/wiki/ 技术栈迁移)。
ai-memory 取代了 qmd 的
wiki/+ 本地索引技术栈:知识存储在 ai-memory 实例的服务端(通过 MCP 回忆),而不是每个仓库各自的wiki/文件夹中。 完整使用模式见 references/usage.md。 服务端(安装新实例、升级引擎、配置提供商、使用者密钥、备份/恢复)由 aim-ops 负责——此技能仅负责将客户端接入服务端。
路由意图
- “how's it looking?”, “do I need to migrate?”, “doctor”(也包括 PT:“como está?”, “preciso migrar?”)→ 运行 doctor(只读诊断)。
- “set up ai-memory here”, “turn on capture”, “init”(也包括 PT:“configura ai-memory aqui”, “liga a captura”)→ install(全新安装)。
- “migrate off qmd”, “drop qmd and use ai-memory”(也包括 PT:“migra do qmd”, “tira o qmd e põe ai-memory”)→ migrate(已有项目迁移)。
- “update/pair the CLI”, “refresh the hooks”, “it's on an old version”, “upgrade”(也包括 PT:“atualiza/pareia o CLI”, “refresca os hooks”, “tá numa versão velha”)→ refresh (检测环境 + 使本地 CLI 和 hooks 与服务端保持同步——不更改标记/代码片段/MCP)。
开始写入任何内容之前,请先与用户确认三个路由参数——ai-memory 实例可能有多个(例如个人的 memory.example.dev,以及单独的组织实例),因此绝不可将端点写死:
- MCP 端点——ai-memory 实例 URL(例如
https://memory.example.dev/mcp),以及注册该实例时使用的服务名称(例如memory-personal、memory-acme)。询问此仓库应连接哪个实例。 - 工作区——个人项目使用
default;组织仓库使用专属工作区(例如acmecorp)。 - 项目——默认为仓库目录名;允许用户自行指定。
此处选定的端点就是 aim-query / aim-write 后续将(按服务名称)使用的目标。
CLI 前置条件(默认不使用 Docker 包装器)
aim-init 需要 ai-memory CLI 来安装 MCP 条目、安装钩子并刷新路由片段。优先使用原生 CLI 二进制文件,而非 Docker 包装器:
- 如果
ai-memory已在PATH中,运行ai-memory --version并与上游最新版本比较(gh release view -R akitaonrails/ai-memory --json tagName -q .tagName,或 releases/latest 页面)。仅当它处于近期版本时才保留——落后的 CLI 会缺少较新的子命令(例如auto-improve、pending-writes、curator)和钩子修复,因此请升级(见刷新)。服务端的确切.version位于GET /admin/status,该接口需要 admin 令牌(用户的 OIDC/JWT 会收到401)——因此,最新版本是实际可用的版本一致性目标;已连接的 MCP 客户端也会在initialize握手中获知服务端版本。 - 如果未安装或版本过旧,请先检查上游最新版本:
https://github.com/akitaonrails/ai-memory/releases/latest。- Linux:下载对应的
ai-memory-linux-<arch>.tar.gz资源,验证其.sha256,并将二进制文件安装到~/.local/bin/ai-memory(或其他由用户拥有的PATH目录)。 - Windows:下载
ai-memory-windows-x86_64.zip,验证其.sha256,并按照其中附带的 Windows 文档操作。 - macOS/Darwin:下载对应的
ai-memory-macos-<arch>.tar.gz资源(Apple Silicon 设备使用ai-memory-macos-aarch64.tar.gz,Intel 设备使用-x86_64),验证其.sha256,并将二进制文件安装到~/.local/bin/ai-memory。仅当没有适用于你架构的资源时,才使用回退方案:cargo install --git https://github.com/akitaonrails/ai-memory --tag <latest-tag>。
- Linux:下载对应的
- 仅当用户明确要求使用 Docker 时,才使用 Docker 包装器(
bin/ai-memory或 GitHub 上的快速入门包装器)。不要将其作为 macOS 上的默认本地 CLI 推荐,也不要在用户要求非 Docker 配置时推荐。
安装后,验证:
command -v ai-memory
ai-memory --version
AI_MEMORY_SERVER_URL=https://memory.example.dev AI_MEMORY_AUTH_TOKEN=<token-or-env> ai-memory status --json
接入后的仓库内容
-
仓库根目录中的
.ai-memory.toml— 用于将捕获内容和回忆路由到工作区/项目的稳定、非机密配置,以及(可选)此仓库加入的 Keycloak/OIDC 实例。 跟踪策略取决于具体情况,并非自动设置:- **使用共享路由的私有/团队仓库:**提交该文件,以便每位开发者克隆仓库后都使用相同的工作区/项目和加入配置文件。这些值是实例配置,不是凭据,设置后通常不会更改。
- 公共仓库、个人分叉或每位操作者使用独立路由:通过仓库本地的
.git/info/exclude将其保留在本地。 不要将其添加到全局core.excludesfile,除非用户明确选择仅本地路由,否则不要运行git rm --cached .ai-memory.toml。
workspace = "default" project = "<repo-name>" # Optional routing/policy (defaults shown; uncomment to change — commented = no-op): # project_strategy = "repo-root" # collapse worktrees/subdirs to the git root (default: basename) # drop_subagent_captures = "true" # accept-but-don't-store THIS project's subagent captures (default: off) # Optional: Keycloak/OIDC onboarding profile the agent reads to wire hooks # WITHOUT asking (see "Keycloak-gated instance"). Non-secret. The native hook # reads the routing/policy keys above but NOT this [instance] block, so the # block is inert at runtime — it exists purely so `aim-init` can self-serve # the device-flow setup. [instance] issuer = "https://kc.example/auth/realms/<realm>" server_url = "https://memory.example.dev/wiki" # ai-memory URL incl. base path client_id = "ai-memory-cli" # device-flow client agents = ["claude-code"] # agents to wire hooks for -
CLAUDE.md和AGENTS.md中的路由片段 —…end -->代码块。它会在会话中途主动触发回忆。代码块文本由 ai-memory 二进制文件管理,而非此技能管理——从源获取当前规范代码块,并将其写在标记之间;不要在此手动维护副本(副本会与二进制文件中的内容不一致):- Agent:
memory_install_self_routing(返回供你的 Write/Edit 工具使用的代码块)。 - CLI:
ai-memory install-instructions(写入CLAUDE.md;使用--target AGENTS.md)。 规范配置块本身已经是通用的(不包含工作区/项目/服务名称,也不包含页面路径——.ai-memory.toml标记用于限定回忆范围,MCP 会自动限定范围),因此即使提交到公开仓库也安全。无论如何,切勿将已提交的配置块扩展为枚举知识库的“内容位置”地图——这会泄露项目的内部信息架构。跨范围/共享规则的连接应放在运维人员全局配置(~/.claude/CLAUDE.md)中,而不是各仓库的配置块中。
- Agent:
-
MCP 服务条目:位于
.mcp.json(Claude)、opencode.json(OpenCode)、.codex/config.toml(Codex)中,指向 ai-memory 实例(模板:templates/mcp-entry.json.tmpl)。 建议使用 CLI 安装程序,这样每个 Agent 都会获得其原生全局配置:ai-memory install-mcp --client codex --server-url https://memory.example.dev/mcp --name memory-personal --apply ai-memory install-mcp --client open-code --server-url https://memory.example.dev/mcp --name memory-personal --apply ai-memory install-mcp --client claude-code --server-url https://memory.example.dev/mcp --name memory-personal --apply如果 MCP 定义只包含服务名称/URL,不包含凭据,则它们属于稳定的仓库配置。私有/团队仓库可以提交
.mcp.json,这样每个 Agent 克隆仓库后都会发现相同的 MCP 端点。个人端点或包含身份验证信息的条目(例如Authorization标头、Bearer 令牌或用户专属密钥)应放在 Agent 的全局/用户配置中,或者通过.git/info/exclude将本地专用的.mcp.json排除在版本控制之外。 不要将.mcp.json添加到全局core.excludesfile中,也不要自动取消跟踪现有的.mcp.json。只有在用户明确选择使用本地专用 MCP 配置后,才运行git rm --cached .mcp.json。 -
自动捕获钩子属于全局配置(Claude 设置、Codex
~/.codex/hooks.json、 OpenCode 插件配置,以及平台数据目录下暂存的钩子脚本: Linux 上的~/.local/share/ai-memory/hooks/、 macOS 上的~/Library/Application Support/ai-memory/hooks/,以及 Windows 上的%LOCALAPPDATA%\ai-memory\hooks\)。这些钩子受标记控制:凡是包含.ai-memory.toml的仓库都会触发。仓库无需配置仓库专用钩子脚本,只需添加标记即可。 为每个 Agent 安装或刷新钩子时,应使用捕获基础 URL,而不是/mcpURL。 钩子身份验证——选择与服务端匹配的模式。这是捕获静默失败的首要原因:模式错误会导致每次排空时都返回 401,暂存区不断填满,最终丢失捕获内容。 共有四种模式:- 开放钩子路由(
/hook+/handoff不要求身份验证)→ 安装时不要使用--auth-token。 - 静态 Bearer 令牌——服务端接受
/hook+/handoff上的共享/用户专属令牌 (例如,单租户引擎上的AI_MEMORY_AUTH_TOKEN,或通过ai-memory user add获取的令牌)→ 通过--auth-token传入。令牌会嵌入每个 Agent 的钩子配置中,因此应将该文件视为敏感文件(chmod 600)。 - 使用者密钥(
amk_,仅密钥网关)——mcp-auth边车不使用身份提供方,而是在本地解析每个使用者的密钥(KEYS_DB)。每个 Agent/CLI 都需要单独的密钥(通过带admin作用域的密钥调用POST /keys获取;由aim-ops keys签发),并限定为read,write;钩子通过--auth-token传入该密钥,MCP 则将其用作Authorization标头。归属信息来自密钥的actor_user。使用非管理员密钥访问/admin/*时会返回 403,这是预期行为,并非服务端故障。轮换方式:签发新密钥,然后撤销旧密钥。 - OIDC/Keycloak 网关——forwardAuth 边车(
mcp-auth)用于验证 JWT,并返回401 WWW-Authenticate: Bearer resource_metadata=…(RFC 9728)。静态十六进制令牌在此处会被拒绝(401)——网关只接受 Keycloak JWT,而引擎的上游 Bearer 令牌由代理注入,客户端无法自行发送。每位开发者都应使用专属的 OIDC 设备令牌:运行一次ai-memory auth login oidc-device --issuer <oidc-issuer> --client-id <public-device-client>(在浏览器中批准),然后安装钩子时不要使用--auth-token——钩子的resolve_bearer会从auth.json加载令牌,并在无界面模式下刷新令牌。完整操作步骤见下文“第二个/自定义实例”。 快速检查服务器所处模式:curl -sI <server>/hook→ 返回401,且包含WWW-Authenticate: Bearer resource_metadata=标头,表示使用 OIDC/Keycloak(设备流); 如果返回不带该标头的普通401/200,则表示使用静态 Bearer/开放模式。GET <server>/keys/whoami→ 返回包含{identity, can_issue}的200,表示存在仅处理密钥的网关 (使用者密钥);返回404表示 sidecar 没有KEYS_DB。
如果二进制文件无法定位其随附脚本(例如通过
cargo install构建),请添加--hooks-dir <ai-memory/hooks>:# static-bearer server: TOKEN=<HOOK_AUTH_TOKEN> ai-memory install-hooks --apply --agent claude-code --server-url https://memory.example.dev --auth-token "$TOKEN" # OIDC/Keycloak server (after `auth login oidc-device`) OR open server — NO --auth-token: ai-memory install-hooks --apply --agent claude-code --server-url https://memory.example.dev ai-memory install-hooks --apply --agent codex --server-url https://memory.example.dev ai-memory install-hooks --apply --agent open-code --server-url https://memory.example.dev新版
install-hooks会配置 原生钩子(ai-memory hook --event …直接调用二进制文件),而非 shell 脚本——二进制文件会输出符合各 Agent 要求的 stdout 格式(例如用于注入交接内容的 Claude CodehookSpecificOutput.additionalContextJSON 封装),因此不需要手动修补钩子脚本,以免脚本发生偏离。请勿为身份验证手动维护自定义的_lib.sh覆盖层(例如,在前置部分添加 Keycloak 令牌生成代码)——受支持的方式是使用--auth-token(静态 Bearer 服务器),或使用auth login oidc-device且不带--auth-token(OIDC/Keycloak 服务器)。设备令牌不会在每次事件发生时生成:它只会存储一次到auth.json中,并在清空队列时以无头方式刷新。 在 Codex 上,请确认~/.codex/hooks.json包含 ai-memory 生命周期钩子,并在 Codex 下次启动时提示信任新钩子命令后予以信任。Grok Build CLI(~/.grok/hooks/*.json)目前尚不受--agent支持——请手动集成,并注意其SessionStart会忽略钩子 stdout(无法注入交接内容;请改用 MCPmemory_handoff_accept)。(旧版 qmd 仓库为每个仓库配置了wiki-reindex钩子;迁移时会将其移除。) - 开放钩子路由(
Hook 配置 — 各平台路径与投递模式(macOS / Linux / Windows)
install-hooks 和 auth login oidc-device 都默认使用平台的数据目录
(dirs::data_local_dir()),auth.json、hook-spool/ 和暂存的 hook 脚本都存放在此处,因此 OIDC 设备令牌会写入 hook 查找令牌的位置。三个操作系统的流程相同;只有路径不同:
| OS | 数据目录(auth.json、hook-spool/、hooks/) | Claude Code 设置 |
|---|---|---|
| macOS | ~/Library/Application Support/ai-memory | ~/.claude/settings.json |
| Linux | ~/.local/share/ai-memory | ~/.claude/settings.json |
| Windows | %LOCALAPPDATA%\ai-memory | %USERPROFILE%\.claude\settings.json |
Hook 是原生的(ai-memory hook --event … 直接调用二进制文件,不会启动 shell;Windows 使用 WindowsNative 配置,并采用相同的 spool + OIDC 令牌回退机制)。Codex → ~/.codex/hooks.json;OpenCode → 其插件配置。如果二进制文件找不到随附的脚本(例如通过 cargo install 构建),请传入 --hooks-dir <data_dir>/hooks。auth.json 包含敏感信息 → 在 POSIX 系统上使用 chmod 600(CLI 会以此权限写入)。
投递会在会话边界批量进行,而非逐事件进行。 逐事件 hook(user-prompt-submit、pre/post-tool-use、pre-compact、stop)只会将内容加入队列,写入 <data_dir>/hook-spool(即时完成,且不等待结果)。spool 会在**session-start** 时排空(清除上一会话积压的内容),并在**session-end** 时排空(主要投递点)。因此,“捕获的内容不会立即显示”是正常现象——它们会在下一个边界刷新。排空时的 resolve_bearer:显式设置的 --auth-token 优先(静态令牌);否则使用 auth.json 中的 OIDC 令牌(即将过期时会刷新);否则匿名访问。spool 中的条目在失败 8 次或存放 7 天后会被丢弃,文件数量上限为 10000 个。错误认证模式的症状: hook-spool 中 auth_mode: static 条目不断增加,接近 10000 个,且持续返回 401(将静态令牌用于 Keycloak 网关)→ 切换到设备授权流程,并清除无效积压内容。
令牌有效期(设备授权流程):访问令牌会自动刷新;刷新令牌的有效期与签发方设置的离线会话空闲时限相同——长期不活动后,请重新运行 auth login oidc-device。随时可通过 ai-memory auth status 验证状态。
Keycloak 保护的实例 — 由 Agent 引导完成配置(mac / Linux / Windows)
开发者不应手动运行设置脚本。当开发者需要在 Keycloak/OIDC 实例上捕获钩子时,由你(Agent)引导完成:收集输入、检查或创建设备客户端、运行单机设置并验证。开发者只需回答几个问题,并在浏览器提示出现时批准一次。scripts/ 是你的权威跨平台命令参考(macOS/Linux 使用 *.sh,Windows 使用 *.ps1)——调用这些脚本,或直接运行等效的 ai-memory 命令。
所需输入——先从仓库的 .ai-memory.toml [instance] 区块中读取(issuer / server_url / client_id / agents,参见“What a wired repo has”);仅当该区块不存在时,才询问开发者(或回退到操作员全局配置):
ISSUER— realm URL,例如https://kc.example/auth/realms/<realm>。SERVER_URL— ai-memory 服务 URL,包括任何基础路径,例如https://memory.example.dev或https://memory.example.dev/wiki。CLIENT_ID— 设备流客户端(默认为ai-memory-cli)。- 开发者使用的
AGENTS(claude-code、codex、open-code等)。
存在 [instance] 区块时(例如,已提交到私有团队仓库),Agent 会使用该区块,且不会提问——下一位开发者只需执行 git clone 和 aim-init 即可完成配置。
1. 检查设备流客户端是否存在(只读):
对 GET <ISSUER>/.well-known/openid-configuration 发起请求(确认 device_authorization_endpoint),然后向该端点 POST client_id=<CLIENT_ID>&scope=openid。收到 device_code → 已就绪。invalid_client(不存在此客户端)或 unauthorized_client … device flow is disabled → realm 需要该客户端(步骤 2)。浏览器/MCP 客户端强制使用 PKCE,并会因 Missing parameter: code_challenge_method 返回 400,因此无法复用——这就是需要专用客户端的原因。
2. 仅在客户端缺失时创建——每个 realm 只需一次,需要 Keycloak 管理员权限。
如果你有 Keycloak 管理员权限,请使用 scripts/kc-create-device-client.sh(幂等;公开客户端,仅支持设备流,不使用 PKCE)。如果 Keycloak 在容器中运行,请在 Pod 内运行(无论你的操作系统是什么,它都会在那里运行 sh),并复用 Pod 自带的管理员环境变量,避免机密离开集群:
# macOS/Linux/WSL:
kubectl exec -i <keycloak-pod> -- sh -c \
'CLIENT_ID=ai-memory-cli KC_SERVER=http://localhost:8080/auth KC_REALM=<realm> \
KC_ADMIN_USER="$KEYCLOAK_ADMIN" KC_ADMIN_PASS="$KEYCLOAK_ADMIN_PASSWORD" sh -s' \
< scripts/kc-create-device-client.sh
# Windows PowerShell: Get-Content scripts/kc-create-device-client.sh | kubectl exec -i <pod> -- sh -c '…'
根据 realm 的 KC_HTTP_RELATIVE_PATH,将 KC_SERVER 调整为 …:8080 或 …:8080/auth(登录时出现 404 Not Found 表示需要切换)。如果你没有管理员权限,请让操作员运行一次,然后继续。
3. 自行运行单机设置——不要让开发者运行脚本。根据开发者的操作系统执行:
- macOS/Linux:
ISSUER=… SERVER_URL=… CLIENT_ID=… AGENTS="…" sh scripts/dev-setup-hooks.sh - Windows:
pwsh scripts/dev-setup-hooks.ps1 -Issuer … -ServerUrl … -Agents "…" - 两种方式都会运行
ai-memory auth login oidc-device --issuer <ISSUER> --client-id <CLIENT_ID>(开发者只需在浏览器中批准一次打印出的 URL),然后运行ai-memory install-hooks --apply --agent <each> --server-url <SERVER_URL>(不使用--auth-token)。
4. 验证:ai-memory auth status → oidc-device: logged in。开发者需要具备服务端检查的 realm 角色(mcp:read/mcp:write)——这与 MCP 登录所需的角色相同。
在操作员全局配置(~/.claude/CLAUDE.md 或私有操作手册)中记录每个实例的 ISSUER/SERVER_URL/CLIENT_ID,不要记录在此技能中——脚本应保持通用;这些端点因操作员和实例而异。
第二个/自定义实例(例如客户端 Keycloak 实例)
有些代码仓库会连接两个 ai-memory 实例——一个个人实例,以及一个通过 OAuth/OIDC(Keycloak,RFC 9728)进行身份验证的客户端/组织实例,而非(或除)静态 bearer 之外的其他方式。两个实例都支持读写;请让它们保持同步,并将个人实例作为超集(它会累积所有自定义实例中的内容)。
- Hook 捕获也适用于 OAuth/Keycloak 实例。 Hook 是无头的,无法针对每个事件运行交互式 OAuth PKCE 流程,因此它使用已存储的 OIDC 设备流令牌:运行一次
ai-memory auth login oidc-device --issuer <oidc-issuer> --client-id <public-device-client>(在浏览器中批准),然后 Hook(resolve_bearer)从auth.json加载该令牌,并以无头方式刷新它。之后运行不带--auth-token的install-hooks。- 仅支持 forwardAuth-JWT 的网关会拒绝静态 bearer。 如果网关返回
401 WWW-Authenticate: Bearer resource_metadata=…(RFC 9728),静态十六进制令牌会收到 401——上游 bearer 由代理注入,客户端不能自行发送——因此设备流是此处唯一的无头选项。只有当实例确实接受/hook上的静态HOOK_AUTH_TOKEN时,才传入--auth-token。 - 设备流客户端要求(发行方侧): 一个启用了设备授权授权类型且未强制执行 PKCE的公共客户端(设备授权流程不适用 PKCE——它没有重定向;请将会强制执行 PKCE 的浏览器/DCR/MCP 客户端设为独立客户端,这样就不必降低其安全要求)。用户需要具备服务器检查的 realm 角色(例如
mcp:read/mcp:write)——这些角色通过 realm-role 映射器写入 JWT,而不是通过 scope 传递。
- 仅支持 forwardAuth-JWT 的网关会拒绝静态 bearer。 如果网关返回
- **双路捕获:**全局 Hook → 个人实例;项目级 Hook(
.claude/settings.local.json)→ 客户端实例。每一路使用对应实例的身份验证模式(静态 bearer 或 OIDC 设备令牌,两者相互独立)。两路都配置后,每个生命周期事件都会捕获到两个实例。(也可以只捕获到一个实例,再通过同步协调。) - 持久化页面双写:在双实例项目中,
memory_write_page会写入两个 MCP,使用相同的(workspace, project)。 - 对客户端实例执行回忆/写入时,显式传入
workspace+project——使用per_actor和作用域串漏失败即关闭修复后,未指定作用域的调用会落到该实例预设的默认值。.ai-memory.toml标记提供了规范作用域。 - 保持同步(双向、按需):个人实例 ⊇ 所有内容;双向协调差异,同时保留
(workspace, project)。
这种特定于运维人员的双实例配置应放在运维人员全局配置(~/.claude/CLAUDE.md 或共享记忆规则)中,而不是提交到代码仓库的逐仓库 CLAUDE.md ai-memory 块中——该块是通用的,且由二进制文件管理;在共享/客户端代码仓库中,它会泄露双实例/捕获配置以及项目的信息架构。
doctor(只读)
报告以下内容,不要执行写入操作:
ai-memoryCLI 是否已在PATH中?版本是什么?如果缺失或过旧,请报告最新上游版本的原生安装路径——下载ai-memory-<os>-<arch>.tar.gz资源(macOS 提供ai-memory-macos-aarch64/-x86_64;Linux 提供ai-memory-linux-aarch64/-x86_64),验证其.sha256;只有在没有适用于当前架构的资源时,才使用cargo install。除非用户希望使用 Docker,否则不要退回到 Docker 封装程序。- CLI 能否连接到选定的服务(使用正确的
AI_MEMORY_SERVER_URL/ auth 环境变量或标志运行ai-memory status --json)? - CLI 版本是否一致。 将
ai-memory --version(本地版本)与最新上游版本(gh release view -R akitaonrails/ai-memory --json tagName -q .tagName)进行比较。标记落后的 CLI——它缺少较新的子命令(auto-improve、pending-writes、curator)和钩子修复——并建议更新。(服务器的精确.version需要管理员权限才能通过/admin/status查看:用户的 OIDC/JWT 会收到401,因此不要依赖ai-memory status向服务器查询;最新版本是可检查的目标,MCPinitialize握手中也会携带版本信息。) - 是否存在
.ai-memory.toml?对应哪个工作区/项目?其跟踪策略是否符合预期(为共享且稳定的路由而提交,还是仅供本地使用而忽略)? - CLAUDE.md / AGENTS.md 中是否包含路由片段?
- 片段是否说明了搜索策略? 标记缺少“当前项目未找到时扩大搜索范围”指导的过期片段——也就是说,未提及
scopes/ 同级项目,或未警告memory_query返回的是片段(而非完整页面正文)。重新安装当前模板(如下)即可补上这部分内容。这一点很重要,因为memory_query不支持全局搜索:只搜索当前项目便停止的 Agent 会错过同级(infra/ops)项目中的跨领域知识。 - 是否存在 ai-memory MCP 条目?先检查 Agent 的全局配置——MCP 通常安装在这里(
~/.claude.json顶层的mcpServers,例如memory-personal;~/.codex/config.toml;OpenCode 全局配置),然后再检查仓库级.mcp.json/opencode.json。不要因为仓库级.mcp.json为空就断定“没有记忆召回”——全局条目适用于每个仓库。如果使用了仓库级.mcp.json,请检查其中是否仅包含稳定的非机密定义,还是也包含身份验证材料;然后确认其跟踪策略符合仓库惯例;对于拥有共享 MCP 的私有/团队仓库,跟踪.mcp.json是合理的。 - 对于 Codex,
~/.codex/hooks.json中是否存在全局 ai-memory 钩子(SessionStart、UserPromptSubmit、PreToolUse、PostToolUse、PreCompact、Stop),且暂存的脚本是否存在于平台对应的 ai-memory 钩子目录下? - 钩子是否为原生且已通过身份验证? 标记任何仍在自定义覆盖层下调用手工修改的 shell 脚本的 Agent(例如
~/.config/ai-memory/hooks/中引入 Keycloak 令牌生成_lib.sh的脚本),而不是使用二进制文件的ai-memory hook --event …形式——这类脚本会逐渐偏离上游版本,并漏掉上游修复(例如交接注入所依赖的hookSpecificOutputJSON 包装和制表符转义修复)。如果服务器对/hook//handoff设有访问限制,请确认钩子携带了适用于该服务器模式的凭据(否则会静默捕获401——CLI 会在本地暂存数据并始终返回{}):static-bearer 服务器需要--auth-token;OIDC/Keycloak 网关(401 WWW-Authenticate: Bearer resource_metadata=…)需要设备流令牌(auth login oidc-device),并且安装钩子时不带--auth-token——静态令牌会在此被拒绝。重新运行install-hooks --apply(根据模式决定是否带--auth-token),以迁移并移除对覆盖层的依赖。 hook-spool达到或接近 10000 上限——有两种不同的原因;查看几条条目的auth_mode/attempts/last_error以区分:- 身份验证错误(可修复):在 Keycloak/JWT 网关上使用
auth_mode: static→attempts持续增加,last_error显示 401,条目在尝试 8 次后丢弃。修复方法:使用设备流(auth login oidc-device)并且不带--auth-token运行install-hooks --apply,然后清除失效的积压条目。 - 排空频率问题(不是身份验证错误):
auth_mode: oidc(正确)、attempts: 0、last_error: null——投递正常,但只在session-start/session-end时排空,因此马拉松式会话会在结束前超过MAX_SPOOL_FILES(10000),并淘汰最旧的条目。缓解方法:在会话边界排空(启动新会话,或手动运行session-start钩子来排空),或缩短会话;持久性修复方案是在会话中增量排空(上游待处理事项——跟踪 hook-spool 投递可靠性工作)。同一数据目录下所有 Agent 共享 spool,因此并行的长会话会共同累积条目。
- 身份验证错误(可修复):在 Keycloak/JWT 网关上使用
- MCP 身份验证(DCR): 如果 Agent 的 MCP 登录显示 Keycloak “Client not found”,说明其缓存的 Dynamic-Client-Registration ID 已失效(realm 重建/迁移所致)。从 Agent 的 MCP 身份验证缓存中清除过期条目(例如 OpenCode 的
~/.local/share/opencode/mcp-auth.json),然后重新进行身份验证以触发新的 DCR。 - MCP OAuth 发现失败: 如果客户端的
reauth报错Could not discover OAuth endpoints from server response(它不会继续执行 RFC 9728 → 8414 发现——曾在 OMP 的原生 MCP 客户端中发现此问题),请在该客户端自身(不纳入 Git 跟踪)的配置中,通过npx -y mcp-remote <url> <port>将远程服务桥接为stdio服务,同时保持已提交的.mcp.json使用可移植的type: http。如果发现和授权都通过,但令牌 POST 返回 404,说明 SDK 在域名根路径查找 auth-server 元数据,并丢弃了基于路径的 issuer 中的/<base>/realms/<realm>——原生客户端(Claude Code)通过相对于 issuer 的 OIDC 连接,因此该端点并未失效,且无法通过mcp-remote的版本或标志解决;应在服务器端添加指向该 realm 的根路径.well-known/oauth-authorization-server(以及openid-configuration)别名,否则使用原生客户端。完整操作指南:references/usage.md§MCP OAuth compatibility。 - 双实例(例如客户端 Keycloak)仓库? 如果仓库注册了第二个 MCP(客户端/组织实例),请确认:两个实例都作为可读写实例处理,且个人实例是其超集;持久性写入会双写;如果需要自动捕获到客户端实例,项目级钩子应指向该实例,并使用静态
HOOK_AUTH_TOKEN或已存储的 OIDC 设备流令牌(ai-memory auth login oidc-device …→resolve_bearer会在无交互的情况下刷新)——捕获是可行的,并非“无法实现”;召回/写入时应显式传入workspace+project(per_actor失败时关闭)。标记任何硬编码了此双实例/捕获配置的已提交 CLAUDE.md——这类配置应放在运维人员的全局配置中,而不是共享的仓库级片段中。 - 遗留 qmd? 标记以下任意情况:存在
qmdMCP 条目;存在包含CONVENTIONS.md的wiki/目录;存在仓库级*/hooks/wiki-reindex.sh;CLAUDE.md/AGENTS.md 中存在 “Wiki (wiki/)" 区块;存在.wiki-guardrails.yml。
install(全新项目)
- 与用户确认工作区和项目。
- 确保已安装并且
ai-memory原生命令行工具可正常使用(参见上文“CLI 前置条件”)。 从上游发布资源安装或升级(macOS 提供ai-memory-macos-<arch>.tar.gz, Linux 提供ai-memory-linux-<arch>.tar.gz;请验证.sha256);仅当没有适用于当前架构的资源时,才使用cargo install/从源代码构建。除非用户明确要求,否则避免使用 Docker 封装。 - 根据仓库情况和用户意见,决定
.ai-memory.toml的跟踪策略。对于路由稳定且需要共享的私有/团队仓库,写入该文件并保持跟踪/可提交。 对于公开仓库、个人分支或按操作人员区分的路由,将其添加到仓库本地的.git/info/exclude。不要使用全局core.excludesfile;除非用户明确选择仅本地路由,否则不要取消跟踪现有标记文件。 - 从二进制文件获取规范的路由代码块(使用
memory_install_self_routing或ai-memory install-instructions),并将其写入CLAUDE.md和AGENTS.md(确保幂等; 放在/标记之间;如果已存在则替换)。 不要粘贴手动维护的副本。 - 将 ai-memory MCP 条目添加到仓库所用的 Agent 配置中。如果该条目稳定且不包含凭据,可以放在已跟踪的仓库级
.mcp.json中;如果它属于个人配置或包含身份验证信息,则将其安装在 Agent 的全局/用户配置中,或通过.git/info/exclude将其设为仅本地使用。除非用户明确要求仅本地 MCP 配置,否则不要运行git rm --cached .mcp.json。 对于 Codex,优先使用ai-memory install-mcp --client codex ... --apply,以便将服务写入~/.codex/config.toml。 - 确保当前使用的 Agent 已安装全局自动捕获钩子。对于 Codex,运行
ai-memory install-hooks --agent codex --server-url https://memory.example.dev --apply,并验证~/.codex/hooks.json以及已暂存的ai-memory/hooks/codex脚本。 - 告知用户自动捕获现已启用(全局钩子 + 新标记);可通过会话启动交接信息 + 路由代码片段进行回忆。
迁移(brownfield:qmd → ai-memory)
先运行 doctor;然后在获得用户确认后:
- 标记文件 — 写入
.ai-memory.toml(工作区/项目),并保留或选择跟踪策略:在私有/团队仓库中提交稳定的共享路由;个人/公共路由仅保留在本地,通过.git/info/exclude排除。 - MCP — 在
.mcp.json/opencode.json/.codex/config.toml中,用 ai-memory 条目替换qmd服务条目。保留仓库现有的跟踪策略;如果仓库有意共享 MCP,则提交稳定且不含机密的服务定义;含认证信息的端点或个人端点则保留在本地/全局。 - CLAUDE.md / AGENTS.md — 用路由片段替换“Wiki (
wiki/)”/qmd-MCP 区块。删除要求 Agent 查询qmd或维护wiki/的说明。 - 移除所有 qmd 时代的遗留内容。 旧的 qmd/wiki 设置安装的不只是钩子——请逐一列出并移除:
.wiki-guardrails.yml(防护规则配置)。- 钩子 —
.claude/hooks/wiki-*.sh(policy-check、reindex、drift-audit、suggest-ingest);.codex/hooks/wiki-*.sh(policy-check、reindex、drift-audit、consider)以及.codex/hooks.json;.opencode/hooks/wiki-*.sh以及.opencode/plugins/wiki-guardrails.js。从.claude/settings.json中移除对应的钩子条目,并从.codex/config.toml中移除[features] codex_hooks = true(它仅用于启用 codex wiki 钩子)。 opencode.json中的permission.skill."wiki-*"(替换为"aim-*"或删除)。- ANTIGRAVITY(如果仓库使用它)——托管的指令区块以及任何
.antigravity*钩子/配置。 - 自动捕获现在由全局 ai-memory 钩子提供——不需要每个仓库的钩子脚本。
- 全局 QMD 检出副本/包装器(操作员层级,位于仓库之外)——每个项目的包装器(
~/.local/share/skills/qmd/wrappers/<project>-qmd,或旧版~/.local/share/essential-skills/qmd/...)以及托管的qmd检出副本/缓存现在都已成为孤立内容。移除包装器;只有在其他仓库都不再使用 qmd 时,才移除共享检出副本。 wiki/内容 — 默认保留原样作为历史记录。如果用户希望将其放入 ai-memory,请将 Markdown 导入所选的工作区/项目(每个文件对应一个页面,并删除任何明文机密),之后用户可以移除wiki/。未经明确确认,不要删除wiki/。- 重新运行 doctor 以确认:标记文件存在且跟踪策略符合预期,CLAUDE/AGENTS 中包含片段,ai-memory MCP 已接入且未提交机密,并且没有 qmd 遗留内容(没有
.wiki-guardrails.yml、没有wiki-*钩子/插件、没有 qmd MCP 条目、没有codex_hooks/wiki-*权限残留)。
refresh(升级 CLI + 重新暂存 Hooks 以保持一致)
适用于已完成接线但与服务端状态不一致的环境——CLI 版本落后,或服务端升级后。不会更改标记、代码片段或 MCP 配置;检测已安装的内容并使其保持一致:
- 检测当前状态(只读):比较本地
ai-memory --version与上游最新发行版(gh release view -R akitaonrails/ai-memory --json tagName -q .tagName;服务端自身的.version受管理员权限限制,用户访问/admin/status会得到401,因此发行版是可检查的目标);检查哪些 Agent 安装了 ai-memory Hooks——ai-memory install-hooks --help会列出规范支持的 Agent(不要硬编码过时的子集):claude-code(~/.claude/settings.json)、codex(~/.codex/hooks.json)、gemini-cli(~/.gemini/settings.json)、antigravity-cli /agy(~/.gemini/config/hooks.json)、grok(~/.grok/hooks/ai-memory.json)、cursor(~/.cursor/hooks.json)、open-code(~/.config/opencode/plugins/)、omp(~/.omp/agent/extensions/)、openclaw;以及ai-memory auth status(OIDC 设备令牌是否有效)。 - 升级 CLI(如果版本落后于最新发行版,参见“CLI 前置条件”):下载
ai-memory-<os>-<arch>.tar.gz资源,验证其.sha256,备份当前二进制文件,然后安装到~/.local/bin/ai-memory并覆盖原文件。确认现在的ai-memory --version≥ 服务端版本。 - 为检测到的每个 Agent 重新暂存 Hooks:
ai-memory install-hooks --apply --agent <agent> --server-url <capture-url>(OIDC/Keycloak 服务端 → 不要使用--auth-token;静态 Bearer → 使用--auth-token)。该命令会重新验证暂存的脚本并刷新 Agent 配置(同时写入备份)。原生 Hooks(ai-memory hook --event …)会自动使用新的二进制文件;此操作会刷新配置和暂存的后备脚本,并移除任何旧版_lib.sh覆盖文件。 - 验证:
ai-memory --version与服务端版本一致;ai-memory auth status→ 已登录;Agent 配置仍会原生调用ai-memory hook --event;<data_dir>/hook-spool远低于 10000 上限。 - ≥ 2.0 版本说明:
install-hooks --apply现在会将 Bearer 存储在<data_dir>/auth-token(0600)中,并在生成的 TypeScript 集成中渲染resolveToken()辅助函数;托管的 Agent Skills 已变更——使用memory_install_self_routing(或ai-memory install-instructions)刷新。下次启动时,Codex 会提示 Hooks need review:请信任这些 Hooks。CLI ≥ 2.0 可正常与 1.3x 服务端配合使用 Hooks(/hook/batch未变),但请在同一天先升级服务端(aim-ops upgrade),再升级客户端。
refresh 不会触碰标记、路由代码片段或 MCP 条目(它们与版本无关,且代码片段由二进制文件管理)——要处理这些内容,请运行 install / migrate。Hooks 是全局的(所有 Agent 共用一个数据目录),因此刷新一次即可更新所有已接线的仓库,而不只是当前仓库。
验证
git check-ignore .ai-memory.toml→ 已忽略(不会提交)。- CLAUDE.md + AGENTS.md 中的路由代码片段只出现一次(位于标记之间)。
- 不再有
qmdMCP 条目 /wiki-reindexHooks(适用于 migrate)。 - 一次捕获完整往返:仓库中的真实 Agent 会话在所选工作区/项目下生成一个页面(通过
aim-status/memory_status或/api/v1/projects检查)。
多用户模式(可选)
上述说明涵盖单个操作员的情况(一名用户,一个 ai-memory 实例)。 当多名用户共用一个实例时,或者一名操作员希望在多个并行的 Claude Code 窗口之间严格隔离各个仓库时,请将引擎切换为多用户模式,并为每位用户显式完成接入。ai-memory CLI 已内置此工作流。
**前置条件:**引擎必须设置 [auth].token_pepper(由 ai-memory init 自动生成;否则多用户管理端点会返回 503)。使用
curl <endpoint>/admin/status 或 ai-memory status 确认。
按用户设置(规范:一人一个身份)
-
在引擎上创建用户(需要 root token)。令牌只会原样显示一次:
ai-memory user add --username alice --email alice@home # → {"id": "...", "username": "alice", "token": "<COPY-THIS-NOW>"}生命周期子命令:
user list(不显示任何令牌)、user expire/revive、user rotate-token(签发新的明文令牌,仅显示一次)。 -
安装以该用户的 bearer 标记的 hooks——每个用户使用的 Agent CLI 都要运行一条命令(
claude-code、codex、cursor、gemini-cli、open-code、omp、openclaw、antigravity-cli):ai-memory install-hooks --apply \ --agent codex \ --as-user alice \ --auth-token <alice-token>对于这些 harness,请使用
--agent claude-code或--agent open-code。--apply会直接修改 Agent 配置(幂等;会写入带时间戳的备份)。 默认使用全局 hook 配置(~/.claude/settings.json、~/.codex/hooks.json、 OpenCode 插件配置等)。 若要改为指定项目级配置,请传入--config-file ./.claude/settings.json(参见下文“按上下文配置令牌”)。 -
将 bearer 接入 MCP 入口,使 MCP 工具调用与 hooks 一样以同一用户身份进行身份验证:
{ "mcpServers": { "memory-personal": { "type": "http", "url": "https://memory.example.dev/mcp", "httpHeaders": { "Authorization": "Bearer <alice-token>" } } } }ai-memory install-mcp --apply --auth-token <alice-token>会为你写入此入口。 -
以
per_actor模式运行引擎(chart:aiMemory.autoScope.mode: per_actor)。 活跃项目映射以(user, session_id)为键,并回退到仅按用户映射——在没有 session 的探测中,Alice 不会继承 Bob 上次使用的项目;Alice 的写入也不会发布到 Bob 的槽位。
按上下文配置令牌(不使用 Agent hooks 实现并行会话隔离)
同一个人在不同仓库中同时打开两个 Claude Code 窗口 → MCP 工具调用不会转发 hook 的
session_id,因此引擎会将两个窗口合并到同一个仅按用户区分的槽位。解决方法:将每个仓库视为独立的逻辑用户。
ai-memory user add --username alice-foo --email [email protected] # token T-foo
ai-memory user add --username alice-bar --email [email protected] # token T-bar
在每个仓库的项目级 .claude/settings.json 中(Claude Code 会合并项目级配置和
全局配置),固定使用一个独立令牌:
{
"mcpServers": {
"memory-personal": {
"type": "http",
"url": "https://memory.example.dev/mcp",
"httpHeaders": { "Authorization": "Bearer <T-foo>" }
}
}
}
以相同方式按作用域安装 hooks:
cd ~/repo-foo && ai-memory install-hooks --apply \
--as-user alice-foo --auth-token T-foo \
--config-file ./.claude/settings.json
现在,这两个窗口会以不同用户身份向引擎进行身份验证;per_actor 键控会自动隔离它们的槽位。运维成本:每位实际用户需要 N 个令牌 × 需要隔离的 M 个仓库。确实需要并行隔离时,这种取舍可以接受;否则,上述按用户设置已足够。
服务端 scope-guard(纵深防御)
引擎内置准入 webhook 链。运维 chart 提供可选的
scope-guard webhook,用于强制执行按用户划分的写入边界——一个 ACL,形式为
user → [(workspace pattern, project pattern), …]。即使令牌被粘贴到了错误的
.ai-memory.toml 或 MCP 配置中,引擎也会在准入时拒绝写入:
# values.yaml
webhooks:
scopeGuard:
enabled: true
rules:
alice: [{ workspace: "alice|shared", project: ".*" }]
client-x: [{ workspace: "client-x|shared", project: ".*" }]
启用 scope-guard ⇒ 写入的 actor 必须非空,否则 ACL 会拒绝所有请求。 ACL 使用
ActorContext.user 作为键。OIDC 客户端会在 JWT 中携带该值
(preferred_username),因此多用户实例可以自然地匹配规则。但使用静态
HOOK_AUTH_TOKEN 对 hooks 进行身份验证的客户端,其 actor 会为空,除非你还设置了
mcpAuth.hookAuth.username(→ HOOK_AUTH_USERNAME,即 mcp-auth 在 hook-token 请求上标记的用户名),并将其设为 ACL 允许的用户。若未设置,所有静态令牌 hook 捕获都会在准入时被静默地以 403 拒绝——数据丢失只会显示在引擎日志中(scope-guard: user '' not allowed to write_page …)。请注意,
aiMemory.rootUsername 不适用于此处:它标记的是第 1 层/MCP 路径,而非 hook 路径。因此,启用
scopeGuard 的单操作员静态令牌实例必须将
mcpAuth.hookAuth.username 设置为 ACL 用户;多用户实例则应使用 OIDC(绝不要共用 hook 用户名)。
读取不受限制——引擎没有读取侧的准入链。若要实现真正的读取隐私保护 (防范恶意用户),请在每个信任边界运行独立的 ai-memory 实例。
多用户的 doctor 检查
除了上述单用户检查外,多用户安装的 doctor 还应报告:
- 引擎上已设置
[auth].token_pepper ai-memory user list返回预期用户- Agent MCP 配置(
~/.claude/settings.json、~/.codex/config.toml、OpenCode 配置或项目级等效配置)包含Authorization: Bearer … - 当前启用的 hook 配置已标注
--as-user(每次 hook 调用都携带用户的 bearer,而不是 root token) - 如果 autoscope 为
per_session,且 MCP 客户端不转发session_id,则发出警告,说明该模式会静默降级为单槽位,并建议改用per_actor
有关 recall 模型(按项目交接、自动捕获、MCP 工具),请参阅 references/usage.md;有关手动 recall/write,请参阅 aim-query / aim-write。