Git 集成:代理中的版本控制工作流


Git 集成:代理中的版本控制工作流 场景:Agent 修改完文件后,怎么知道它改了什么、怎么 review 变更、怎么回退?opencode 用两层抽象把 git 封装成类型安全的 Service。 路径:packages/opencode/src/git/index.ts → packages/

@Async 异步方法没走代理导致同步执行,接口慢 2 倍


@Async 异步方法没走代理导致同步执行,接口慢 2 倍 场景:接口 P99 从 200ms 涨到 400ms,调用量没变——耗时操作本该异步却被同步阻塞 路径:断言 → 现场 → 拆解 → 处方 → 雷标 断言 @Async 写在方法上,大多数人以为异步了 但真相是——同一个类里另一个方法用 t

线程池满了:拒绝策略选型失误导致任务丢失


线程池满了:拒绝策略选型失误导致任务丢失 场景:凌晨批处理对账发现 2 万条数据丢失,系统无任何错误日志 路径:模拟提交 → 观察各策略行为 → 检查 handler 类型 → 修复为自定义策略 上篇讲了线程池队列积压导致接口全面超时的排查过程,最后提到「拒绝策略不要轻易用 AbortPolicy」

多数据源事务:@Transactional 只管了一个库


多数据源事务:@Transactional 只管了一个库 场景:@Transactional 嵌套调用导致数据半改——一个注解管不到两个数据库连接 路径:现场 → 三层边界拆解(JDBC/传播/数据源)→ 处方 → 雷标 上篇文章讲了同一个类里方法调方法不走代理导致 @Transactional 不

Propagation.REQUIRES_NEW 嵌套后连接翻倍?事务传播级别的三个隐形成本陷阱


Propagation.REQUIRES_NEW 嵌套后连接翻倍?事务传播级别的三个隐形成本陷阱 上篇文章解决了"同一个类里方法调方法不走代理"的问题——你在方法 A 上加 @Transactional,调本类方法 B,B 的事务配置被无视,退化为 outer 事务的一部分。 现在你知道了,把方法

@Transactional 配了等于没配?同一个类里方法调方法的隐形陷阱


@Transactional 配了等于没配?同一个类里方法调方法的隐形陷阱 场景:运营批量导入 48 条用户数据,@Transactional 加了但只成功了 30 条——同类自调用导致事务没生效 排查链路:检查代理状态 → 验证 @Transactional 可见性 → 定位调用方式 → 三种修复

MAT 打开 4GB dump 直接 OOM?字符串泄漏的 OQL 定位实战


MAT 打开 4GB dump 直接 OOM?字符串泄漏的 OQL 定位实战 当 Dominator Tree 失效时,OQL 才是字符串泄漏的真正入口。4GB dump 里 6000 万个 String 的排查实录。 14:02,告警弹窗:Old Gen 82.5%,FullGC 32 分钟一次。

第二章总结:入口即架构


第二章总结:入口即架构 拆解 opencode 源码 · 第二章 CLI 入口与启动流程 · 总结篇 如果你要设计一个 CLI 入口层,你会先做什么? 大部分人从框架选型开始:yargs 还是 commander.js?但 opencode 的第二章揭示了另一个顺序——技术栈选型先于框架选型。因为整

第一章总结:前置篇的设计哲学


第一章总结:前置篇的设计哲学 读完前置篇的 4 篇文章,你手上已经有了理解 opencode 源码的三块基石:monorepo 全景图(29 个 package 怎样分层组织)、调试环境(怎样从源码跑起来到断点跟进去)和 Effect-ts 基础(怎样读懂满屏的 yield* 和 Effect<>)

/config:配置管理的命令行入口


/config:配置管理的命令行入口 如果你要设计一个 AI Agent 的配置系统——用户用 JSON 配置 provider、Agent、权限规则、MCP 服务——你会怎么组织? 一个直观的想法是:全局一个 config.json,每个模块 import 自己需要的字段,各管各的。但这样 ser