export type GrillStatus = 'grilling' | 'spec_ready' | 'spec_approved' | 'architect_running' | 'dag_ready' | 'dag_approved'; export declare const GRILL_STATUS_FILE = "grill.state.json"; export declare const GRILL_STATE_SCHEMA_VERSION = 1; /** * Where a daemon-driven run posts its humanGate approval cards. Captured at * run birth from the grill worker's injected env (`BOTMUX_CHAT_ID` / * `_LARK_APP_ID` / `_ROOT_MESSAGE_ID` / `_SESSION_ID`). WHY persist it: the * daemon's ability to post a card is NOT from in-process context — after a * restart, `cold-attach` reads this off disk to know which topic to re-post a * pending gate card to (see humanGate daemon-card design §4.2). CLI/dev runs * (no grill, terminal y/N gate) simply omit it. */ export interface RunChatBinding { larkAppId: string; chatId: string; /** Exact IM kind used when a schedule later creates a session. Optional only * for envelopes written before the v3 host protocol existed. */ chatType?: 'group' | 'p2p'; /** thread anchor (rootMessageId) so the card lands in the grill topic. */ rootMessageId?: string; sessionId?: string; /** open_id of the grill initiator, if known — used for the approve gate. */ ownerOpenId?: string; } export interface GrillState { schemaVersion: number; runId: string; /** 触发 grill 的原始模糊需求(grill 的种子). */ goal: string; status: GrillStatus; createdAt: string; updatedAt: string; /** /spec.md(grill 写的人读叙事 + fenced json 块). */ specPath: string; /** /spec.json(spec-finalize 物化的 canonical 结构). */ specJsonPath: string; /** architect 产物路径(dag_ready 起有值;codex 断言3:后续别重猜路径). */ dagPath?: string; notesPath?: string; architectManifestPath?: string; /** validateDag / architect 失败的问题列表(供 grill 回修;codex 断言2). */ problems?: string[]; /** 飞书话题绑定(daemon 发 humanGate 审批卡用);CLI/dev 出生时无. */ chatBinding?: RunChatBinding; } export declare class GrillTransitionError extends Error { readonly from: GrillStatus; readonly to: GrillStatus; constructor(from: GrillStatus, to: GrillStatus); } /** Default run root, aligned with `cli-run.ts`'s `~/.botmux/v3-runs`. */ export declare function defaultBaseDir(): string; /** Atomic write (tmp + rename), mirroring state.ts so a crash never leaves a * half-written grill.state.json. */ export declare function writeGrillState(runDir: string, state: GrillState): void; /** * Read a run's grill state, or `undefined` if it's missing OR corrupt * (unparseable / mid-write torn JSON). Defensive-on-purpose (codex review): * cold-attach reconcile scans every runDir, so one corrupt grill.state must not * throw and kill the whole scan — it just makes that run look stateless. */ export declare function readGrillState(runDir: string): GrillState | undefined; /** * Mint a readable, path-safe, collision-resistant v3 run id. * * The previous `-` shape made every CJK goal fall back to the * same `run` prefix and could reuse the same directory twice in one minute. * Millisecond precision helps operators sort runs, while the UUID suffix is * the actual collision guard across concurrent daemon processes. */ export declare function mintV3RunId(goal: string, now?: Date, randomSuffix?: string): string; export interface BirthResult { runId: string; runDir: string; state: GrillState; } /** * Birth a run: allocate a readable collision-resistant runId unless one is * given (OQ-D), create its runDir, and write the initial `grilling` state. * grill is the birth point of a run; spec.md and the later dag.json both live * in runDir. */ export declare function birthRun(opts: { goal: string; baseDir?: string; runId?: string; now?: Date; /** Test seam for deterministic generated ids; production callers omit it. */ randomSuffix?: string; /** 飞书话题绑定(grill 经 daemon 出生时带;CLI/dev 出生省略). */ chatBinding?: RunChatBinding; }): BirthResult; /** * Read a run's chat binding off disk (from grill.state.json). The daemon's * run driver + cold-attach recovery use this to know where to post / re-post a * humanGate approval card. Returns undefined for CLI/dev runs (no binding) or * a missing/unparseable state file. */ export declare function readRunChatBinding(runDir: string): RunChatBinding | undefined; /** * Apply a status transition with a legality check + field patch, atomically. * Throws `GrillTransitionError` on an illegal transition (the state-machine * backstop behind the friendlier guards the `workflow` subcommands surface). */ export declare function transition(runDir: string, to: GrillStatus, patch?: Partial>, now?: Date): GrillState; export declare function canTransition(from: GrillStatus, to: GrillStatus): boolean; //# sourceMappingURL=grill-state.d.ts.map