/** * 跨会话构建互斥锁(同一 worktree 并发 npm run build 互斥)。 * * 背景:oh-my-opencode-cohub 的构建会写 src/prompts/*.ts(generate-prompts) * 与 dist/(bun build + tsc)。若同一 worktree 上多个会话并行构建, * 两个进程会互相覆盖生成物,产生撕裂的中间态。 * * 锁文件放在 stateDir/build-locks/{lockKey}.lock(用户级状态目录, * 不依赖仓库内路径,避免污染构建产物目录): * - 锁键 = sha256(path.resolve(projectDir)).slice(0, 16):不同 worktree 不互斥; * - 获取 = openSync(lockPath, 'wx') 原子创建(EEXIST 即被占用),内容含唯一 token; * - 陈旧锁 = pid 不存活(kill(pid, 0) 抛 ESRCH)或超 TTL(默认 30 分钟); * - 陈旧清理 = 原子 rename 抢占到唯一 stalePath + token 二次校验(杜绝 * 「A 清理后建新锁、B 再删 A 新锁」竞态,绝不误删他人新锁); * - 释放 = 仅当锁记录的 sessionID 与 callID 均匹配才删除,绝不删他人锁; * - 兜底 = TTL + pid 存活检测(不依赖 dispose 一定被调用)。 */ /** 构建锁冲突错误:上抛给宿主/会话感知(不静默吞掉) */ export declare class BuildLockError extends Error { } /** 计算锁文件路径:stateDir/build-locks/{sha256(projectDir)前16位}.lock */ export declare function resolveLockPath(stateDir: string, projectDir: string): string; export interface AcquireLockOptions { stateDir: string; projectDir: string; sessionID: string; callID: string; command: string; /** 测试/调试用:当前时间(毫秒),默认 Date.now() */ now?: number; /** 锁 TTL(毫秒),默认 30 分钟 */ ttlMs?: number; } /** * 获取构建锁:openSync('wx') 原子创建锁文件并写入持有者记录(含唯一 token)。 * - 成功 → 返回 lockPath; * - EEXIST 且锁陈旧(pid 不存活或超 TTL)→ 原子 rename 抢占 + token 二次校验后重试一次; * - EEXIST 且锁非陈旧 / 抢占到他人新锁 → 抛 BuildLockError(含持有者信息与建议)。 */ export declare function acquireBuildLock(opts: AcquireLockOptions): string; export interface ReleaseLockOptions { stateDir: string; projectDir: string; sessionID: string; callID: string; } /** * 释放构建锁:仅当锁记录的 sessionID 与 callID 均匹配才删除。 * 不匹配 / 锁不存在 / 锁文件损坏 → 返回 false,绝不删除他人锁。 */ export declare function releaseBuildLock(opts: ReleaseLockOptions): boolean; /** * 判断命令是否为构建类命令:按 &&、||、;、换行拆分成子命令, * 任一子命令(trim 后)以构建命令开头即返回 true。 */ export declare function isBuildCommand(command: string): boolean; //# sourceMappingURL=build-lock.d.ts.map