codex-image-to-eagle
Archive Codex-generated images from the current user's Codex generated_images directory into Eagle with the prompt saved as annotation. Use when the user asks to save, archive, import, or sync Codex generated images to Eagle with prompts, tags, and folders.
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…