import { SessionStore } from "./session-store.js"; /** * v0.3.0 — boot-time reconciliation. * * Two recovery paths: * * 1. **In-flight workflow stages** — if `/workflows//_status.yaml` * has any stage with `status: in_progress` but no matching spawn.complete * event in `_events.jsonl`, the stage was killed mid-run. Flip it to * `needs_revision` so the PM (on next user message) asks the user how * to proceed. Append a workflow.stage_needs_revision event. * * 2. **Undelivered Chief messages** — if the Chief session's `events.jsonl` * has a `chief.message_in` without a paired `chief.message_out` (legacy * `pm.*` logs are accepted too), the assistant * reply may exist inside Claude Code's session jsonl (Claude Code * writes it to disk independent of our stdout pipe — see PoC #2 §1.2). * Read it and surface via the `pendingDeliveries` array so the bot can * deliver it back to the messenger. * * Per docs/plan/v0.3-pm-mode-orchestration.md §3 + RECOVERY-AND-TEST-DESIGN.md §3. */ export interface PendingDelivery { orgSlug: string; userId: string; text: string; source: "cc-jsonl" | "fallback-notice"; } export interface RecoveredStage { orgSlug: string; workflowId: string; stageId: string; action: "marked_needs_revision" | "completed_post_hoc"; } export interface ReconcileReport { scannedWorkflows: number; scannedSessions: number; recoveredStages: RecoveredStage[]; pendingDeliveries: PendingDelivery[]; } export declare class WorkflowReconciler { private readonly workspace; private readonly sessions; constructor(workspace: string, sessions: SessionStore); /** Bot-startup call. Scans every org for orphaned state. */ reconcileAll(): Promise; /** Reconcile a single workflow. Returns the list of stages flipped. */ reconcileWorkflow(orgSlug: string, workflowId: string): RecoveredStage[]; /** * Check whether the user's last PM turn was delivered. If not, try to * pull the assistant reply from Claude Code's session jsonl. */ private recoverUndeliveredMessage; private readWorkflowEvents; private appendWorkflowEvent; }