1. 项目概述:一个为AI编程工作流设计的“航海日志”

如果你和我一样,日常开发重度依赖像 Cursor、Claude Code 或 GitHub Copilot 这类 AI 编程助手,那你肯定遇到过这样的场景:你向 AI 提了一个复杂的需求,它生成了一大段代码,你测试后发现有问题,于是你开始和它反复对话、修改。几轮下来,你突然发现,你记不清最初的需求是什么了,也搞不懂 AI 为什么在第三次迭代时把那个循环条件改成了 i <= length - 1 而不是 i < length 。整个思考过程就像一场没有记录的头脑风暴,最终只留下一个看似正确的结果,而所有关键的决策路径和上下文都丢失了。

这就是 inthearto/shiplog 这个项目要解决的问题。你可以把它理解为一个专为 AI 辅助编程设计的“黑匣子”或“航海日志”。它的核心功能是自动、结构化地记录你与 AI 助手(目前深度集成 Cursor)之间的每一次对话、每一次代码生成与修改,并将这些记录整理成清晰、可追溯的变更日志。 shiplog 这个名字非常贴切——在软件开发这艘大船上,它负责记录每一次航行的细节,确保我们不会在 AI 生成的代码海洋中迷失方向。

这个工具的价值远不止于“记录”。它通过强制性的上下文记录,实质上是在推动一种更工程化的“提示工程”实践。它让你不得不思考如何向 AI 清晰地表述问题,因为每一次不清晰的提问都会被记录下来,成为日后复盘和改进的素材。对于团队协作来说,它更是无价之宝。当同事接手一段由 AI 生成、经过多次迭代的代码时,他不再需要去猜测“这段代码为什么这么写”,而是可以直接查阅 shiplog 生成的日志,看到完整的决策链,从而快速理解代码意图,甚至发现其中隐藏的假设或潜在问题。

2. 核心设计思路与架构解析

2.1 核心需求:从混沌对话到可追溯工程

在深入代码之前,我们必须先理解 shiplog 要解决的根本痛点。传统的 AI 编程交互是线性的、易失的。用户提问,AI 回答,用户基于回答继续提问或修改。这个循环发生在 IDE 的聊天窗口里,一旦窗口关闭或对话过长被截断,历史上下文就变得难以检索。更糟糕的是,AI 生成的代码被直接插入项目文件,但生成这些代码的“原因”——即当时的对话上下文、用户的具体指令、AI 的推理过程——却与代码本身分离了。

因此, shiplog 的核心需求可以拆解为三点:

  1. 无感记录 :工具应该尽可能少地干扰开发者现有的工作流。理想状态是,开发者像往常一样使用 Cursor 和 AI 聊天、生成代码,而记录在后台自动完成。
  2. 结构化存储 :记录不能是杂乱无章的聊天记录导出。它需要被结构化,以便于程序化处理和查询。例如,需要能清晰地关联“哪次对话”生成了“哪个文件的哪段代码”。
  3. 上下文关联 :记录必须保留完整的上下文链。一次代码生成可能源于之前三次对话的逐步澄清,这些关联必须被捕获,形成一棵“决策树”,而不仅仅是一条时间线。

2.2 技术选型与架构拆解

shiplog 的仓库信息显示它是一个 TypeScript 项目,并且与 Electron、CLI 工具相关。结合其要与 Cursor(一个基于 Electron 的 IDE)深度集成的目标,其技术选型的逻辑就非常清晰了。

2.2.1 为什么是 TypeScript 和 Electron? Cursor IDE 本身是用 Electron 框架构建的。Electron 允许使用 Web 技术(HTML, CSS, JavaScript/TypeScript)来开发跨平台的桌面应用。为了能够深度集成到 Cursor 中, shiplog 很可能需要以“插件”或“扩展”的形式运行在 Cursor 的进程内。使用 TypeScript 开发,一方面能获得优秀的类型安全和现代 JavaScript 特性,另一方面其编译产物(JavaScript)能无缝运行在 Electron 的 Node.js 环境中。这是一种“用同生态的语言做同生态的集成”的最务实选择,能最大程度地保证兼容性和降低集成复杂度。

2.2.2 核心架构猜想 虽然我们看不到完整的源码,但根据其目标可以推断出核心架构模块:

  1. 监听器模块 :这是核心。它需要挂载到 Cursor 的进程中,监听所有与 AI 聊天相关的 IPC(进程间通信)消息或 DOM 事件。例如,当用户发送一条消息,或者 AI 返回一段代码并被接受插入编辑器时,监听器需要捕获这些事件及其负载(消息内容、代码块、目标文件路径等)。
  2. 上下文管理器 :这个模块负责为每一次交互会话创建和维护一个上下文标识。例如,当用户在某个文件上开启一个新的 AI 聊天时,管理器会生成一个唯一的 Session ID。之后这个文件上所有相关的 AI 交互都关联到这个 Session ID 下。它还需要处理上下文的串联,比如用户基于 AI 的上一个回答继续追问,这需要被识别为同一个会话的延续。
  3. 存储与序列化模块 :捕获到的数据需要被持久化。考虑到性能和对本地文件系统的操作,很可能会使用轻量级的本地数据库(如 SQLite)或直接写入结构化的日志文件(如 JSON Lines 格式)。这个模块决定了日志的查询效率。
  4. 日志生成与渲染模块 :这是面向用户的部分。它需要将存储的原始数据,按照时间线或会话树的形式,渲染成人类可读的 Markdown 或 HTML 报告。关键词中的 changelog 暗示了其输出可能类似于传统的版本更新日志,但内容是关于 AI 交互的。
  5. CLI 工具 :为了方便用户在不打开 Cursor 的情况下查询、导出或分析日志,一个独立的命令行工具是必要的。这可能是通过将核心模块打包成一个独立的 Node.js CLI 应用来实现。

2.2.3 与“Skills”和“Mod”的关联 关键词中出现了 claudeskills , skills , mod 。这揭示了 shiplog 可能更宏大的愿景。在一些 AI 智能体框架中,“Skill” 指代一个可复用的、完成特定任务的能力单元。 shiplog 可能不仅是一个记录工具,它记录下的、被验证有效的“用户指令-AI 响应”对,本身就可以被抽象、封装成一种可复用的 “Skill”。例如,记录显示“如何优雅地解析这个特定格式的配置文件”这个交互过程非常成功,那么这个过程就可以被转化为一个“配置文件解析 Skill”,供未来或其他项目直接调用。而 mod (模块)可能指代这种可插拔的技能包管理方式。这使得 shiplog 从一个被动记录工具,演变为一个主动的“AI 编程经验知识库”构建工具。

3. 核心功能实现与实操要点

3.1 如何实现无感监听与数据捕获

这是 shiplog 工程上最具挑战性的部分。Cursor 作为一个闭源商业软件,没有公开的插件 API 来直接获取 AI 聊天数据。因此,实现监听可能需要一些“创造性”的技术手段。

3.1.1 基于 Electron 进程的注入 最直接的方式是利用 Electron 应用的特点。Electron 应用由主进程和渲染进程组成。Cursor 的 UI 和聊天界面运行在渲染进程中。 shiplog 可以通过以下几种方式之一进行集成:

  • 作为独立 Electron 应用运行 :通过 Electron 的 remote 模块或自定义 IPC 协议,与 Cursor 进程通信。但这需要 Cursor 暴露相应的接口,可能性较低。
  • 修改 Cursor 本地安装包 :直接以“补丁”形式,将 shiplog 的编译代码注入到 Cursor 的源代码或打包产物中。这种方式侵入性强,且每次 Cursor 更新都可能失效,维护成本高。
  • 使用全局键盘/鼠标事件监听与 OCR/自动化 :这是一种“曲线救国”的外挂式方案。工具在系统全局监听快捷键,当用户触发时,通过自动化脚本获取 Cursor 窗口的聊天文本和代码编辑器内容。这种方式不依赖 Cursor 内部实现,但极不可靠,容易受界面变化影响,且无法获取完整的元数据(如会话 ID)。

考虑到项目的可行性,更可能采用一种 “混合模式” :开发一个 Cursor 的配套 CLI 工具。用户在使用 Cursor 时,同时运行这个 CLI 工具。该工具通过监听 Cursor 工作区目录下特定文件(如 .cursor 缓存文件、项目文件本身)的变化,结合对用户主动触发的“保存日志”命令的响应,来近似地重建交互上下文。虽然做不到 100% 无感,但能在很大程度上实现自动化记录。

3.1.2 数据结构设计 捕获到的数据需要精心设计。一个最小化的有效记录单元可能包含以下字段:

{
  “session_id”: “uuid-xxxx”,
  “timestamp”: “2023-10-27T10:00:00Z”,
  “file_path”: “/src/utils/parser.ts”,
  “event_type”: “code_insertion”, // 或 “user_message”, “ai_response”
  “content”: {
    “user_prompt”: “Convert this string to camelCase.”,
    “ai_raw_response”: “Here’s the code...```typescript\nexport function toCamelCase(str: string): string { ... }\n```”,
    “accepted_code_snippet”: “export function toCamelCase(str: string): string { ... }”,
    “accepted_code_range”: { “start”: { “line”: 45, “column”: 0 }, “end”: { “line”: 50, “column”: 1 } }
  },
  “context”: {
    “previous_message_id”: “uuid-yyyy”,
    “surrounding_code_before”: “...”, // 插入点前的代码
    “surrounding_code_after”: “...”  // 插入点后的代码
  }
}

这样的结构保证了每一条记录都是自解释的,并且通过 session_id previous_message_id 可以构建出完整的对话树。

3.2 日志生成与可读性呈现

原始的结构化数据对机器友好,但对人不友好。 shiplog 的核心价值在于生成人类可读的日志。

3.2.1 变更日志生成逻辑 它的生成器会遍历一个会话中的所有记录,然后按以下逻辑组织:

  1. 按会话分组 :将所有记录按 session_id 分组,每个会话代表一个相对独立的开发任务或问题。
  2. 按文件聚合 :在每个会话内,再按 file_path 聚合。这样就能清晰地看到,在这个会话中,哪些文件被 AI 修改过。
  3. 时间线渲染 :对于每个文件,按照 timestamp 顺序,渲染出每一次代码变更。关键技巧在于,不仅要显示插入的代码,还要利用 context.surrounding_code_before/after 来显示一个简短的代码上下文(例如,变更前后的几行),这比只看孤立的代码片段更容易理解。
  4. 关联对话 :在每一次代码变更的下方,以引用的形式附上导致这次变更的用户提示和 AI 的完整响应。这直接建立了“需求”到“实现”的追溯链路。

最终生成的 Markdown 日志可能长这样:

# AI 开发日志 - 项目:MyApp
## 会话:为 utils/parser.ts 添加字符串处理函数 (session_id: uuid-xxxx)
**文件:** `src/utils/parser.ts`
*   **2023-10-27 10:00:05** - 在行 45-50 插入函数 `toCamelCase`
    ```typescript
    // 上下文:行 40-44
    export function someOtherFunc() {}
    // 插入开始:行 45
    export function toCamelCase(str: string): string {
      return str.replace(/_(\w)/g, (_, c) => c.toUpperCase());
    }
    // 上下文:行 51-55
    export function anotherFunc() {}
    ```
    **触发此次生成的对话:**
    > **用户:** Convert this string to camelCase.
    > **AI:** Here’s the code... (代码如上)

这样的日志,任何一个开发者打开,都能在 30 秒内理解这段代码的来龙去脉。

3.2.2 高级功能:差异对比与模式识别 一个更进阶的功能是代码差异对比。 shiplog 可以记录同一段代码在多次 AI 交互后的变化序列,并自动生成类似 git diff 的对比视图,直观展示 AI 是如何一步步修正代码的。更进一步,通过对大量日志的分析,工具可以识别出高效的提示模式(例如,哪些措辞总能得到高质量的代码)和常见的错误模式(例如,哪些模糊的指令会导致 AI 引入 Bug),从而反向指导用户优化自己的提问技巧。

4. 集成使用与工作流适配

4.1 安装与基础配置

假设 shiplog 提供了一个 CLI 工具,典型的安装和使用流程如下:

  1. 安装 :通过 npm 或直接下载二进制包。

    npm install -g @inthearto/shiplog
    # 或
    curl -L https://github.com/inthearto/shiplog/releases/download/vx.x.x/shiplog-cli -o /usr/local/bin/shiplog && chmod +x /usr/local/bin/shiplog
    
  2. 初始化 :在你的项目根目录运行初始化命令。这会在项目中创建一个 .shiplog 的隐藏目录和配置文件。

    cd your-project
    shiplog init
    

    初始化过程会生成一个 shiplog.config.json 文件,你可以在这里配置:

    • logDirectory : 日志存储路径。
    • ignoredFiles : 需要忽略的文件模式(如 node_modules/ , *.log )。
    • autoSnapshotInterval : 自动为项目创建快照的间隔(用于辅助代码变化检测)。
  3. 启动后台监听服务 :运行一个常驻进程来监听项目变化(这是实现“半自动”记录的关键)。

    shiplog daemon start
    

    这个守护进程会监控项目文件的变化,并结合一些启发式规则(如文件在 AI 聊天窗口活跃后短时间内被修改)来尝试关联 AI 交互。

4.2 与 Cursor 的协同工作流

真正的无缝体验需要一定的“约定”或“手动触发”来弥补无法深度监听 Cursor 内部的不足。我推荐以下工作流:

  1. 开启会话 :当你准备就一个具体任务(例如,“重构用户认证模块”)开始使用 Cursor AI 时,在终端手动标记一下:

    shiplog session start --tag “refactor-auth-module”
    

    这会在后台创建一个新的、带标签的会话记录。

  2. 正常开发 :像往常一样在 Cursor 中与 AI 聊天、生成并接受代码。

  3. 关键节点快照 :在完成一个重要的子任务,或者 AI 生成了一段你觉得特别重要或复杂的代码后,手动触发一次记录:

    shiplog capture --reason “Implemented JWT token validation logic as per AI suggestion”
    

    这个命令会引导你选择当前编辑的文件,并记录下当前的代码状态和最近的相关聊天记录(如果守护进程能捕捉到的话)。

  4. 结束会话 :任务完成后,结束会话。

    shiplog session end
    
  5. 生成与查看日志 :随时可以生成可读的日志。

    shiplog generate --session-tag “refactor-auth-module” --output ./logs/auth-refactor.md
    

    你也可以在 CI/CD 流水线中集成此命令,将每次重要特性开发的 AI 日志作为制品保存下来,附在 Pull Request 中,极大地便利代码审查。

注意: 这种“手动标记+自动辅助”的模式,虽然增加了一点点操作成本,但它迫使你在开发过程中进行有意识的“阶段性总结”,这本身就是一个非常好的工程习惯。它把被动的记录变成了主动的知识管理。

4.3 进阶用法:从日志到可复用技能

这是 shiplog 最具想象力的部分。当你积累了足够多的日志后,你可以开始“挖掘”其中的宝藏。

  1. 技能提取 :你可以手动或通过简单的脚本,从成功的交互记录中提取模式。例如,你发现每次用“写一个接收 X 参数,返回 Y 格式,处理 Z 边界条件的 React 组件”这样的模板提问,效果都很好。你就可以把这个“提示模板”保存为一个技能。
  2. 技能库管理 shiplog 可以提供一个技能库管理功能。你可以将提取的技能分类存放(如“数据结构操作”、“API 封装”、“错误处理”)。
  3. 技能调用 :在未来遇到类似任务时,你不再需要从头构思提示词,而是可以直接调用技能库中的模板,稍作修改即可。CLI 可能提供这样的功能:
    shiplog skill apply “react-component-with-props-and-error-boundary” --output ./prompt.txt
    
    这会生成一个预设好结构的提示词文件,你复制到 Cursor 中,填入具体参数即可。

这实际上是将个人的、隐性的 AI 使用经验,转化为了显性的、可积累、可复用的团队知识资产。

5. 常见问题、排查与最佳实践

5.1 常见问题与解决方案

在实际构想和使用这类工具时,你可能会遇到以下问题:

问题 可能原因 解决方案
日志中无法关联 AI 对话 守护进程无法捕获 Cursor 内部通信;手动捕获未在聊天后及时执行。 1. 确保在开始 AI 对话前启动了 shiplog session start
2. 养成在获得关键 AI 输出后立即运行 shiplog capture 的习惯。
3. 检查 Cursor 版本,某些版本可能修改了内部结构。
生成的日志过于冗长 记录了太多细碎的、无关的文件变动或对话。 1. 在配置中优化 ignoredFiles ,排除构建目录、日志文件等。
2. 使用 session capture 命令进行更精细的手动控制,而非完全依赖自动监听。
3. 在生成日志时使用过滤选项: shiplog generate --min-significance high
日志文件体积增长过快 项目庞大,AI 交互频繁,且记录了完整的代码上下文。 1. 配置中限制上下文的记录范围,例如只记录变更行前后 5 行代码。
2. 定期归档旧的会话日志。
3. 考虑使用压缩存储格式。
团队其他成员不习惯使用 增加了工作流步骤,感到麻烦。 1. 将 shiplog 集成到团队共享的脚本或 IDE 启动项中,降低使用门槛。
2. 在代码审查中,要求对复杂或 AI 生成的代码必须附上 shiplog 日志链接,将其流程化。
3. 展示价值:用具体案例说明日志如何在调试和知识传递中节省了大量时间。

5.2 最佳实践心得

基于我对这类工具的理解和工程实践,分享几点心得:

  1. 为会话赋予明确目标 :在使用 shiplog session start 时,务必用 --tag 或描述写清本次会话要解决的具体问题(如“修复用户登录超时问题”)。模糊的标签(如“今天的工作”)会让后续检索失去意义。
  2. 捕获时机是关键 :不要等到一个包含 20 次来回对话的大任务结束才记录。应该在每个 可验证的子目标达成时 就进行 capture 。例如,AI 帮你写好了一个函数,你运行测试通过了,这时就应立即捕获。这保证了每次记录的上下文都是最小且完整的。
  3. 日志是代码的补充文档 :在编写传统的代码注释时,可以简略。对于复杂的、由 AI 生成的逻辑,可以在注释中直接引用 shiplog 的会话 ID。
    /**
     * 使用 Smith-Waterman 算法进行局部序列比对。
     * @see shiplog-session:session_id_xxxx (包含了算法选择和参数调优的完整讨论)
     */
    function localSequenceAlign(seqA, seqB) { ... }
    
  4. 定期回顾与提炼 :每周或每两周,花半小时浏览一下生成的日志。重点看两类:一是解决了棘手问题的会话,思考其中成功的提示模式;二是那些来回次数特别多的失败会话,分析是需求表述不清,还是 AI 能力边界问题。这个过程是提升你“AI 编程”技能的最快途径。

inthearto/shiplog 代表了一种新的编程范式下的基础设施思考。在 AI 成为编程核心助手的时代,过程的可追溯性、决策的可解释性以及经验的可持续积累,变得和最终的代码正确性一样重要。它不仅仅是一个工具,更是一种促使开发者与 AI 进行更结构化、更工程化协作的思维框架。虽然完全自动化的理想状态尚有技术障碍,但即使通过当前这种半自动、需要少量手动干预的方式,它所带来的在代码理解、团队协作和知识沉淀方面的收益,已经足以证明其价值。开始有意识地记录你与 AI 的“对话”,或许就是你构建未来人机协同编程优势的第一步。

更多推荐