{"version":3,"file":"child-status.d.ts","sourceRoot":"","sources":["../../../src/watchdog/child-status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAE5E,eAAO,MAAM,yBAAyB,sCAAsC,CAAC;AAC7E,eAAO,MAAM,2BAA2B,6BAA6B,CAAC;AAEtE,eAAO,MAAM,qBAAqB,6EAA8E,CAAC;AACjH,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE,MAAM,WAAW,mBAAmB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IAC1B,GAAG,EAAE,iBAAiB,CAAC;IACvB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,wBAAwB;IACxC,IAAI,EAAE,OAAO,2BAA2B,CAAC;IACzC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,kBAAkB,CAAC;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,0BAA0B;IAC1C,KAAK,EAAE,kBAAkB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,sBAAsB,CAAC;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,mBAAmB,GAAG,SAAS,CAqBlC;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,mBAAmB,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAErG;AAiED,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,mBAAmB,GAAG,SAAS,CA4BlG;AAED,wBAAgB,0BAA0B,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,wBAAwB,CAc5F;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,0BAA0B,GAAG,SAAS,GAAG,OAAO,CAQ/F;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE;IAC/C,OAAO,EAAE,0BAA0B,GAAG,SAAS,CAAC;IAChD,KAAK,EAAE,wBAAwB,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,0BAA0B,GAAG,SAAS,CAazC","sourcesContent":["import type { ResolvedWatchdogConfig, WatchdogLspConfig } from \"./types.ts\";\n\nexport const CHILD_WATCHDOG_CONFIG_ENV = \"PI_SUBAGENT_WATCHDOG_CHILD_CONFIG\";\nexport const CHILD_WATCHDOG_STATUS_EVENT = \"subagent.watchdog.status\";\n\nexport const CHILD_WATCHDOG_PHASES = [\"idle\", \"reviewing\", \"autofollow\", \"settling\", \"stale\", \"failed\"] as const;\nexport type ChildWatchdogPhase = (typeof CHILD_WATCHDOG_PHASES)[number];\n\nexport interface ChildWatchdogConfig {\n\tenabled: boolean;\n\trunId?: string;\n\tagent?: string;\n\tchildIndex?: number;\n\twatchdogTailTimeoutMs: number;\n\tagentEndTimeoutMs: number;\n\tmaxWarnings: number | null;\n\tmodel?: string;\n\tthinking?: string | false;\n\tlsp: WatchdogLspConfig;\n\tautoFollowBlockers: boolean;\n\tautoFollowMaxAttempts: number | null;\n\tstalemateRepeats: number;\n}\n\nexport interface ChildWatchdogStatusEvent {\n\ttype: typeof CHILD_WATCHDOG_STATUS_EVENT;\n\trunId?: string;\n\tagent?: string;\n\tchildIndex?: number;\n\tstepIndex?: number;\n\tseq: number;\n\tphase: ChildWatchdogPhase;\n\tts: number;\n\tfollowUpPending: boolean;\n\treason?: string;\n}\n\nexport interface ChildWatchdogStateSnapshot {\n\tphase: ChildWatchdogPhase;\n\tseq: number;\n\tlastUpdate: number;\n\tfollowUpPending: boolean;\n\treason?: string;\n\ttimedOut?: boolean;\n}\n\nexport function resolveChildWatchdogConfig(input: {\n\tconfig: ResolvedWatchdogConfig;\n\tagent?: string;\n\trunId?: string;\n\tchildIndex?: number;\n}): ChildWatchdogConfig | undefined {\n\tconst override = input.agent ? input.config.children.overrides[input.agent] : undefined;\n\tconst enabled = input.config.enabled && (override?.enabled ?? input.config.children.enabled);\n\tif (!enabled) return undefined;\n\tconst model = override?.model ?? input.config.children.model;\n\tconst thinking = override?.thinking ?? input.config.children.thinking;\n\treturn {\n\t\tenabled: true,\n\t\t...(input.runId ? { runId: input.runId } : {}),\n\t\t...(input.agent ? { agent: input.agent } : {}),\n\t\t...(input.childIndex !== undefined ? { childIndex: input.childIndex } : {}),\n\t\twatchdogTailTimeoutMs: input.config.children.watchdogTailTimeoutMs,\n\t\tagentEndTimeoutMs: input.config.agentEndTimeoutMs,\n\t\tmaxWarnings: input.config.maxWarnings,\n\t\t...(model ? { model } : {}),\n\t\t...(thinking !== undefined ? { thinking } : {}),\n\t\tlsp: { ...input.config.lsp },\n\t\tautoFollowBlockers: input.config.children.autoFollow.blockers,\n\t\tautoFollowMaxAttempts: input.config.children.autoFollow.maxAttempts,\n\t\tstalemateRepeats: input.config.children.autoFollow.stalemateRepeats,\n\t};\n}\n\nexport function encodeChildWatchdogConfig(config: ChildWatchdogConfig | undefined): string | undefined {\n\treturn config ? JSON.stringify(config) : undefined;\n}\n\nfunction childConfigObject(value: unknown, field: string): Record<string, unknown> {\n\tif (value && typeof value === \"object\" && !Array.isArray(value)) return value as Record<string, unknown>;\n\tthrow new Error(`Invalid child watchdog config: ${field} must be an object.`);\n}\n\nfunction childConfigOptionalString(input: Record<string, unknown>, field: string): string | undefined {\n\tif (!(field in input)) return undefined;\n\tconst value = input[field];\n\tif (typeof value === \"string\" && value.trim()) return value;\n\tthrow new Error(`Invalid child watchdog config: ${field} must be a non-empty string.`);\n}\n\nfunction childConfigOptionalIndex(input: Record<string, unknown>, field: string): number | undefined {\n\tif (!(field in input)) return undefined;\n\tconst value = input[field];\n\tif (typeof value === \"number\" && Number.isInteger(value) && value >= 0) return value;\n\tthrow new Error(`Invalid child watchdog config: ${field} must be a non-negative integer.`);\n}\n\nfunction childConfigPositiveInteger(input: Record<string, unknown>, field: string): number {\n\tconst value = input[field];\n\tif (typeof value === \"number\" && Number.isInteger(value) && value >= 1) return value;\n\tthrow new Error(`Invalid child watchdog config: ${field} must be a positive integer.`);\n}\n\nfunction childConfigNullableNonNegativeInteger(input: Record<string, unknown>, field: string): number | null {\n\tconst value = input[field];\n\tif (value === null) return null;\n\tif (typeof value === \"number\" && Number.isInteger(value) && value >= 0) return value;\n\tthrow new Error(`Invalid child watchdog config: ${field} must be null or a non-negative integer.`);\n}\n\nfunction childConfigBoolean(input: Record<string, unknown>, field: string): boolean {\n\tconst value = input[field];\n\tif (typeof value === \"boolean\") return value;\n\tthrow new Error(`Invalid child watchdog config: ${field} must be a boolean.`);\n}\n\nfunction childConfigLsp(value: unknown): WatchdogLspConfig {\n\tconst input = childConfigObject(value, \"lsp\");\n\tif (typeof input.enabled !== \"boolean\")\n\t\tthrow new Error(\"Invalid child watchdog config: lsp.enabled must be a boolean.\");\n\tif (typeof input.timeoutMs !== \"number\" || !Number.isInteger(input.timeoutMs) || input.timeoutMs < 1) {\n\t\tthrow new Error(\"Invalid child watchdog config: lsp.timeoutMs must be a positive integer.\");\n\t}\n\tif (typeof input.maxFiles !== \"number\" || !Number.isInteger(input.maxFiles) || input.maxFiles < 1) {\n\t\tthrow new Error(\"Invalid child watchdog config: lsp.maxFiles must be a positive integer.\");\n\t}\n\tif (\n\t\ttypeof input.maxDiagnostics !== \"number\" ||\n\t\t!Number.isInteger(input.maxDiagnostics) ||\n\t\tinput.maxDiagnostics < 0\n\t) {\n\t\tthrow new Error(\"Invalid child watchdog config: lsp.maxDiagnostics must be a non-negative integer.\");\n\t}\n\treturn {\n\t\tenabled: input.enabled,\n\t\ttimeoutMs: input.timeoutMs,\n\t\tmaxFiles: input.maxFiles,\n\t\tmaxDiagnostics: input.maxDiagnostics,\n\t};\n}\n\nexport function decodeChildWatchdogConfig(raw: string | undefined): ChildWatchdogConfig | undefined {\n\tif (!raw) return undefined;\n\tconst parsed = childConfigObject(JSON.parse(raw), \"root\");\n\tif (parsed.enabled === false) return undefined;\n\tif (parsed.enabled !== true) throw new Error(\"Invalid child watchdog config: enabled must be true or false.\");\n\tconst thinking = parsed.thinking;\n\tif (thinking !== undefined && typeof thinking !== \"string\" && thinking !== false) {\n\t\tthrow new Error(\"Invalid child watchdog config: thinking must be a string or false.\");\n\t}\n\tconst runId = childConfigOptionalString(parsed, \"runId\");\n\tconst agent = childConfigOptionalString(parsed, \"agent\");\n\tconst childIndex = childConfigOptionalIndex(parsed, \"childIndex\");\n\tconst model = childConfigOptionalString(parsed, \"model\");\n\treturn {\n\t\tenabled: true,\n\t\t...(runId ? { runId } : {}),\n\t\t...(agent ? { agent } : {}),\n\t\t...(childIndex !== undefined ? { childIndex } : {}),\n\t\twatchdogTailTimeoutMs: childConfigPositiveInteger(parsed, \"watchdogTailTimeoutMs\"),\n\t\tagentEndTimeoutMs: childConfigPositiveInteger(parsed, \"agentEndTimeoutMs\"),\n\t\tmaxWarnings: childConfigNullableNonNegativeInteger(parsed, \"maxWarnings\"),\n\t\t...(model ? { model } : {}),\n\t\t...(thinking !== undefined ? { thinking: thinking as string | false } : {}),\n\t\tlsp: childConfigLsp(parsed.lsp),\n\t\tautoFollowBlockers: childConfigBoolean(parsed, \"autoFollowBlockers\"),\n\t\tautoFollowMaxAttempts: childConfigNullableNonNegativeInteger(parsed, \"autoFollowMaxAttempts\"),\n\t\tstalemateRepeats: childConfigPositiveInteger(parsed, \"stalemateRepeats\"),\n\t};\n}\n\nexport function isChildWatchdogStatusEvent(value: unknown): value is ChildWatchdogStatusEvent {\n\tif (!value || typeof value !== \"object\") return false;\n\tconst event = value as Partial<ChildWatchdogStatusEvent>;\n\treturn (\n\t\tevent.type === CHILD_WATCHDOG_STATUS_EVENT &&\n\t\ttypeof event.seq === \"number\" &&\n\t\tNumber.isInteger(event.seq) &&\n\t\tevent.seq >= 0 &&\n\t\ttypeof event.ts === \"number\" &&\n\t\tNumber.isFinite(event.ts) &&\n\t\ttypeof event.followUpPending === \"boolean\" &&\n\t\ttypeof event.phase === \"string\" &&\n\t\t(CHILD_WATCHDOG_PHASES as readonly string[]).includes(event.phase)\n\t);\n}\n\nexport function childWatchdogIsActive(snapshot: ChildWatchdogStateSnapshot | undefined): boolean {\n\tif (!snapshot) return false;\n\treturn (\n\t\tsnapshot.followUpPending ||\n\t\tsnapshot.phase === \"reviewing\" ||\n\t\tsnapshot.phase === \"autofollow\" ||\n\t\tsnapshot.phase === \"settling\"\n\t);\n}\n\nexport function acceptChildWatchdogEvent(input: {\n\tcurrent: ChildWatchdogStateSnapshot | undefined;\n\tevent: ChildWatchdogStatusEvent;\n\trunId?: string;\n\tagent?: string;\n\tchildIndex?: number;\n}): ChildWatchdogStateSnapshot | undefined {\n\tif (input.runId !== undefined && input.event.runId !== input.runId) return undefined;\n\tif (input.agent !== undefined && input.event.agent !== input.agent) return undefined;\n\tconst eventIndex = input.event.childIndex ?? input.event.stepIndex;\n\tif (input.childIndex !== undefined && eventIndex !== input.childIndex) return undefined;\n\tif (input.current && input.event.seq <= input.current.seq) return undefined;\n\treturn {\n\t\tphase: input.event.phase,\n\t\tseq: input.event.seq,\n\t\tlastUpdate: input.event.ts,\n\t\tfollowUpPending: input.event.followUpPending,\n\t\t...(input.event.reason ? { reason: input.event.reason } : {}),\n\t};\n}\n"]}