1实现原理 · 为什么它能做到
核心是一条 Node 脚本:扫描 Codex 生成图目录,选图,组装 item_add 载荷,把图片路径与提示词写入 Eagle 素材库。
Archive images generated by Codex into Eagle and preserve the prompt as searchable metadata.
与 Eagle 的通路有两条:默认走本地 HTTP 回环端点;若本机 Codex 配置里有 Eagle stdio MCP 条目,则自动改走 stdio(spawn 子进程)。
Stdio mode: the script reads the current user's `~/.codex/config.toml`, prefers `[mcp_servers.eagle]`, and can auto-detect other Eagle-like stdio MCP entries. Use `--transport http` to force the legacy HTTP path.
HTTP 路径就是对一个本地回环地址做 POST /api/tools/call,请求体是 {tool, params} 的 JSON。
path: '/api/tools/call',
stdio 路径用 child_process.spawn 拉起配置里的命令,并且把宿主的整个 process.env 透传进子进程(再叠加配置里的 env)。
this.child = spawn(this.config.command, this.config.args || [], {
文件夹解析按「精确父子路径」而非名字:先向上解析根目录,再只在根下按 name+parentId 找日期目录,避免同名串台。
- Folder safety: resolve folders by exact parent-child path, not by name alone.
并发安全用本地文件锁(os.tmpdir 下以参数哈希命名的 lock 目录)串行化「查目录 → 建目录」临界区。
const lockDir = path.join(os.tmpdir(), `codex-image-to-eagle-${hashKey(key)}.lock`);
提示词与溯源信息以固定文本模板写入 Eagle 的 annotation 字段,构成可检索的复盘元数据。
'- source: Codex',
幂等与防重复:同一根目录下若已存在多个同名日期目录,复用最旧的那个并报告重复,而不是再造一个。
If more than one matching date folder already exists under the same root, reuse the oldest existing folder ID and report the duplicate instead of creating another one.
2核心能力
3外部依赖
| Kind | Dependency / Endpoint |
|---|---|
| package | Node.js(无 npm 依赖,仅内置 fs/path/http/os/child_process) |
| network | Eagle MCP Server(本地回环 HTTP) |
| network | Eagle MCP Server(本地回环,README 侧写为 localhost 同端口) |
| cli | Eagle 桌面应用 + Eagle MCP 插件(第三方,必须运行才能写入) |
| cli | stdio MCP 代理子进程(从 ~/.codex/config.toml 解析出的 command/args,如 mcp-proxy.js) |
4管控建议与判定依据
- scripts/: 执行本地脚本或命令: node scripts/archive-codex-image-to-eagle.js(随包脚本,agent 通过 Bash(node *) 触发,
- 网络端点: 声明外部网络访问: 仅本地回环:HTTP POST http://127.0.0.1:41596/api/tools/call(可被 EAGLE_SERVER_URL 改
- 本地工作目录: 文件读写与工件输出: 本地:仅在 os.tmpdir() 下创建/删除 <hash>.lock 目录用于串行化目录创建;不写图片、不改源文件
5第二遍独立确认
- [ok] 每条外部依赖的反查 — Node 依赖:脚本 require 仅 fs/path/http/os/child_process,无 node_modules、无 package.json;Eagle 回环端点:DEFAULT_SERVER 常量 + callTool() 的 http.request 两处互证;stdio 子进程:spawn 调用点 + README 的 mcp-proxy.js 示例互证。
- [ok] 是否有被遗漏的网络调用 — 全文件仅 import http 一处,唯一 http.request 出现在 httpRequest(),被 callTool() 以 DEFAULT_SERVER 构造的 hostname/port 使用;无 fetch/https/axios/WebSocket。
- [ok] 凭证读取结论的反例搜索 — process.env 命中集中在配置项(图片目录/服务地址/文件夹 ID/MCP 参数/锁超时),未见读取密钥文件、keychain、.env 或打印敏感值;但 spawn 透传全量 env 确认成立,故归入橙档依据之一。
- [ok] 文件夹安全规则 vs 代码实现 — SKILL 第 1–5 条规则均可在代码定位:fixedFolderId 短路、folder_get(getAllHierarchy/fullDetails)、findFolderByNameAndParent(name+parentId)、folder_create(parentId)、复用最旧(按 createdAt 升序取 matches[0])。
- [ok] 默认服务地址描述一致性 — SKILL.md/脚本为 127.0.0.1:41596 并说明优先 IPv4 回环的原因;README 写 localhost:41596。二者同端口不同写法,已分别作为独立条目取证,不视为出入。
- [ok] 功能声明与实现相符度 — description 承诺的 save/archive/import/sync + prompt/tags/folders 全部有对应实现(item_add 载荷含 tags/items、annotation、folders);『不泛化为任意素材库迁移』与代码仅面向 Eagle 相符。
- [ok] dry-run 是否真的不写库 — resolveFolderPath() 在 dryRun 时直接返回伪造的 folder-path 字符串,main() 在 dryRun 分支提前 return,未调用 item_add —— 预览路径无写入,结论成立。
6结论
5914cacc5fbf46dc…