import { type CycleResult } from "./tracker.js"; export type StopDirection = "≥" | "≤" | ">" | "<" | "=="; export interface StopWhenCommand { command: string; /** Override default 5s timeout. */ timeoutMs?: number; } export interface StopWhenMetric { metric: { name: string; threshold: number; direction: StopDirection; }; } export interface StopWhenNatural { natural: string; } export type StopWhenDsl = StopWhenCommand | StopWhenMetric | StopWhenNatural; export type StopWhenForm = "command" | "metric" | "natural"; /** Normalized form — what the adapter actually evaluates. */ export interface NormalizedStopWhen { form: StopWhenForm; dsl: StopWhenDsl; } export interface StopHookCycleResult { cycle: number; /** Latest results.tsv rows for this cycle — adapter only consumes those. */ rows?: CycleResult[]; } /** * v0.5 typed `loop_mode.stop_when` as `string`. v0.6 admits an object form * (DSL). Accept either; normalize is local to this module. */ export type LoopModeStopWhen = string | StopWhenDsl; export interface LoopModeForHook { kind: "spec-gate"; stop_when?: LoopModeStopWhen; } export interface EvaluateStopOpts { workspace: string; orgSlug: string; goalId: string; cycleResult: StopHookCycleResult; loopMode: LoopModeForHook; /** * Optional LLM evaluator for the natural form (§5b.6 form 3). Caller is * responsible for applying the v0.5 author-budget cap. When absent and * the DSL form is natural, the adapter returns `continue` (conservative). */ naturalEvaluator?: NaturalEvaluator; /** Override "now" for deterministic test logging. */ now?: string; /** Override the 5s command timeout (tests). */ commandTimeoutMs?: number; } export interface NaturalEvaluator { evaluate(args: { natural: string; cycleRows: CycleResult[]; }): Promise<{ stop: boolean; reason: string; }>; } export interface EvaluateStopResult { stop: boolean; reason: string; /** "command" | "metric" | "natural" | "none" — what form was evaluated. */ form: StopWhenForm | "none"; /** True when the evaluation hit the timeout path. */ timedOut: boolean; } export declare function evaluateStopCondition(opts: EvaluateStopOpts): Promise; /** * Accept v0.5 string form *or* v0.6 object form. The object form is decided * by which DSL key is present; priority command > metric > natural so a * SKILL that accidentally sets more than one still gets a deterministic * resolution. * * Why normalize *here* and not in `skill-parser.ts`: the v0.5 parser is * frozen for this sprint (`DO NOT` scope), and putting the string→DSL bridge * in the adapter keeps the parser's surface unchanged so workspaces that * mix v0.5 and v0.6 SKILLs do not need a migration to keep loading. */ export declare function normalizeStopWhen(raw: LoopModeStopWhen | undefined): NormalizedStopWhen | null; /** Exposed for `solosquad memory stats` + consumers that want to tail the log. */ export declare function stopHookEventsPath(workspace: string, orgSlug: string): string; /** Read all stop-hook events from the org's log. Read-only — for tests/CLI. */ export declare function readStopHookEvents(workspace: string, orgSlug: string): unknown[];