import type { Complexity } from './complexity.js'; /** 任务执行状态机(设计见 DESIGN.md §5) */ export type TaskStatus = | 'init' // 新建,未分析 / 未定方案 | 'analyzing' // (Hard)plan 分析 + 拆解中 | 'plan_review' // (Hard)拆解完成,待 accept | 'decomposed' // (Hard)已拆解,作为容器,进度由子任务汇总 | 'speccing' // (Medium)写方案中 | 'spec_review' // (Medium)方案完成,待 accept | 'ready' // 可执行叶子 | 'blocked' // 依赖未满足 | 'queued' // 编排器已领取,等 worker 槽位 | 'executing' // agent 在 worktree 跑 headless Claude Code | 'exec_review' // 执行完成,改动在分支,待审 / 合 | 'failed' // 执行失败 | 'needs_attention' // 失败超阈值 / 冲突 / 歧义,需人工 | 'done' // 已合并 / 已接受 | 'paused' | 'cancelled'; export const STATUS_LABEL: Record = { init: '新建', analyzing: '分析拆解中', plan_review: '待确认拆解', decomposed: '已拆解', speccing: '写方案中', spec_review: '待确认方案', ready: '可执行', blocked: '被阻塞', queued: '排队中', executing: '执行中', exec_review: '待审/合', failed: '失败', needs_attention: '需人工', done: '完成', paused: '暂停', cancelled: '取消', }; /** 审批闸类型 */ export type GateKind = 'plan' | 'spec' | 'exec'; /** 哪些状态在等待用户审批,以及对应的闸类型 */ export const GATE_STATUS: Partial> = { plan_review: 'plan', spec_review: 'spec', exec_review: 'exec', }; export function gateOf(s: TaskStatus): GateKind | null { return GATE_STATUS[s] ?? null; } export const TERMINAL_STATUS: ReadonlySet = new Set(['done', 'cancelled']); /** 合法状态流转表:from → 允许的 to[] */ export const TRANSITIONS: Record = { init: ['analyzing', 'speccing', 'ready', 'cancelled'], // 按复杂度分流 analyzing: ['plan_review', 'cancelled', 'paused'], plan_review: ['decomposed', 'analyzing', 'cancelled'], // accept / reject(+意见) decomposed: ['done', 'analyzing', 'cancelled', 'paused'], // 子全 done / 重拆 speccing: ['spec_review', 'cancelled', 'paused'], spec_review: ['ready', 'speccing', 'cancelled'], // accept / reject(+意见) ready: ['blocked', 'queued', 'speccing', 'analyzing', 'cancelled', 'paused'], blocked: ['ready', 'cancelled', 'paused'], queued: ['executing', 'ready', 'cancelled', 'paused'], executing: ['exec_review', 'failed', 'cancelled'], exec_review: ['done', 'ready', 'failed', 'cancelled'], // accept(合并) / reject(返工) failed: ['queued', 'needs_attention', 'cancelled'], // 重试 / 升级 needs_attention: ['ready', 'queued', 'analyzing', 'speccing', 'cancelled', 'paused'], done: [], paused: ['ready', 'analyzing', 'speccing', 'queued', 'cancelled'], cancelled: [], }; export function canTransition(from: TaskStatus, to: TaskStatus): boolean { return TRANSITIONS[from]?.includes(to) ?? false; } /** 新建任务按复杂度决定从 init 进入的下一个状态 */ export function initialNextStatus(c: Complexity): TaskStatus { if (c === 'hard') return 'analyzing'; // 强制分析 + 拆解 if (c === 'medium') return 'speccing'; // 写方案 return 'ready'; // Easy:写完 operations 即可执行 } /** 可被执行器领取的状态(叶子 + 依赖满足由调用方另判) */ export function isExecutable(s: TaskStatus): boolean { return s === 'ready'; } export function isGate(s: TaskStatus): boolean { return s in GATE_STATUS; }