Files
oh-my-opencode/src/hooks/atlas/final-wave-plan-state.ts
T
YeonGyu-Kim 16b0d9eb77 fix(atlas): gate final-wave approval on real plan state
Ignore nested plan checkboxes and track parallel final-wave approvals so Atlas only pauses for user approval when the real top-level review wave is complete.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
2026-03-16 10:38:55 +09:00

61 lines
1.7 KiB
TypeScript

import { existsSync, readFileSync } from "node:fs"
const TODO_HEADING_PATTERN = /^##\s+TODOs\b/i
const FINAL_VERIFICATION_HEADING_PATTERN = /^##\s+Final Verification Wave\b/i
const SECOND_LEVEL_HEADING_PATTERN = /^##\s+/
const UNCHECKED_CHECKBOX_PATTERN = /^\s*[-*]\s*\[\s*\]\s*(.+)$/
const TODO_TASK_PATTERN = /^\d+\./
const FINAL_WAVE_TASK_PATTERN = /^F\d+\./i
type PlanSection = "todo" | "final-wave" | "other"
export type FinalWavePlanState = {
pendingImplementationTaskCount: number
pendingFinalWaveTaskCount: number
}
export function readFinalWavePlanState(planPath: string): FinalWavePlanState | null {
if (!existsSync(planPath)) {
return null
}
try {
const content = readFileSync(planPath, "utf-8")
const lines = content.split(/\r?\n/)
let section: PlanSection = "other"
let pendingImplementationTaskCount = 0
let pendingFinalWaveTaskCount = 0
for (const line of lines) {
if (SECOND_LEVEL_HEADING_PATTERN.test(line)) {
section = TODO_HEADING_PATTERN.test(line)
? "todo"
: FINAL_VERIFICATION_HEADING_PATTERN.test(line)
? "final-wave"
: "other"
}
const uncheckedTaskMatch = line.match(UNCHECKED_CHECKBOX_PATTERN)
if (!uncheckedTaskMatch) {
continue
}
const taskLabel = uncheckedTaskMatch[1].trim()
if (section === "todo" && TODO_TASK_PATTERN.test(taskLabel)) {
pendingImplementationTaskCount += 1
}
if (section === "final-wave" && FINAL_WAVE_TASK_PATTERN.test(taskLabel)) {
pendingFinalWaveTaskCount += 1
}
}
return {
pendingImplementationTaskCount,
pendingFinalWaveTaskCount,
}
} catch {
return null
}
}