{"version":3,"file":"run-id-resolver.d.ts","sourceRoot":"","sources":["../../../../src/runs/background/run-id-resolver.ts"],"names":[],"mappings":"AAEA,OAAO,EAAQ,KAAK,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EAIN,KAAK,cAAc,EACnB,KAAK,wBAAwB,EAC7B,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,KAAK,gBAAgB,EAA6B,MAAM,mBAAmB,CAAC;AAErF,MAAM,MAAM,qBAAqB,GAC9B;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GACzD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,cAAc,CAAA;CAAE,CAAC;AAEzD,MAAM,WAAW,wBAAwB;IACxC,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,wBAAwB,CAAC;CAClC;AAsDD,wBAAgB,oBAAoB,CACnC,EAAE,EAAE,MAAM,EACV,IAAI,GAAE,wBAA6B,GACjC,qBAAqB,GAAG,SAAS,CAqCnC","sourcesContent":["import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DIRS, type SubagentState } from \"../../shared/types.ts\";\nimport {\n\tassertSafeNestedId,\n\tfindNestedRunMatchesById,\n\ttype NestedRoute,\n\ttype NestedRunMatch,\n\ttype NestedRunResolutionScope,\n} from \"../shared/nested-events.ts\";\nimport { type AsyncRunLocation, findAsyncRunPrefixMatches } from \"./async-resume.ts\";\n\nexport type ResolvedSubagentRunId =\n\t| { kind: \"foreground\"; id: string }\n\t| { kind: \"async\"; id: string; location: AsyncRunLocation }\n\t| { kind: \"nested\"; id: string; match: NestedRunMatch };\n\nexport interface ResolveSubagentRunIdDeps {\n\tstate?: SubagentState;\n\tasyncDirRoot?: string;\n\tresultsDir?: string;\n\tnested?: NestedRunResolutionScope;\n}\n\nfunction exactAsyncLocation(id: string, asyncDirRoot: string, resultsDir: string): AsyncRunLocation | undefined {\n\tconst asyncDir = path.join(asyncDirRoot, id);\n\tconst resultPath = path.join(resultsDir, `${id}.json`);\n\tif (!fs.existsSync(asyncDir) && !fs.existsSync(resultPath)) return undefined;\n\treturn {\n\t\tasyncDir: fs.existsSync(asyncDir) ? asyncDir : null,\n\t\tresultPath: fs.existsSync(resultPath) ? resultPath : null,\n\t\tresolvedId: id,\n\t};\n}\n\nfunction foregroundIds(state: SubagentState | undefined): string[] {\n\tif (!state) return [];\n\tconst remembered = state.currentSessionId\n\t\t? [...(state.foregroundRuns?.values() ?? [])]\n\t\t\t\t.filter((run) => run.sessionId === state.currentSessionId)\n\t\t\t\t.map((run) => run.runId)\n\t\t: [];\n\treturn [...new Set([...state.foregroundControls.keys(), ...remembered])];\n}\n\nfunction hasExactForegroundId(state: SubagentState | undefined, id: string): boolean {\n\tif (!state) return false;\n\tif (state.foregroundControls.has(id)) return true;\n\tconst remembered = state.foregroundRuns?.get(id);\n\treturn Boolean(remembered && state.currentSessionId && remembered.sessionId === state.currentSessionId);\n}\n\nfunction nestedScopeFromState(state: SubagentState | undefined): NestedRunResolutionScope | undefined {\n\tif (!state) return undefined;\n\tconst routes: NestedRoute[] = [];\n\tconst seen = new Set<string>();\n\tconst add = (route: NestedRoute | undefined) => {\n\t\tif (!route) return;\n\t\tconst key = `${route.rootRunId}:${route.eventSink}:${route.controlInbox}`;\n\t\tif (seen.has(key)) return;\n\t\tseen.add(key);\n\t\troutes.push(route);\n\t};\n\tfor (const control of state.foregroundControls.values()) add(control.nestedRoute as NestedRoute | undefined);\n\tfor (const job of state.asyncJobs.values()) add(job.nestedRoute as NestedRoute | undefined);\n\treturn { routes };\n}\n\nfunction asyncPrefixMatches(\n\tprefix: string,\n\tasyncDirRoot: string,\n\tresultsDir: string,\n): Array<{ id: string; location: AsyncRunLocation }> {\n\treturn findAsyncRunPrefixMatches(prefix, asyncDirRoot, resultsDir);\n}\n\nexport function resolveSubagentRunId(\n\tid: string,\n\tdeps: ResolveSubagentRunIdDeps = {},\n): ResolvedSubagentRunId | undefined {\n\tassertSafeNestedId(\"id\", id);\n\tconst asyncDirRoot = deps.asyncDirRoot ?? DIRS.async;\n\tconst resultsDir = deps.resultsDir ?? DIRS.results;\n\n\tconst nestedScope = deps.nested ?? nestedScopeFromState(deps.state);\n\tif (hasExactForegroundId(deps.state, id)) return { kind: \"foreground\", id };\n\tconst exactAsync = exactAsyncLocation(id, asyncDirRoot, resultsDir);\n\tif (exactAsync) return { kind: \"async\", id, location: exactAsync };\n\tconst exactNested = findNestedRunMatchesById(id, nestedScope ? { scope: nestedScope } : {});\n\tif (exactNested.length > 1)\n\t\tthrow new Error(\n\t\t\t`Nested run id '${id}' is ambiguous across authorized registries. Provide the full id after stale registries are cleaned up.`,\n\t\t);\n\tif (exactNested[0]) return { kind: \"nested\", id, match: exactNested[0] };\n\n\tconst matches: ResolvedSubagentRunId[] = [];\n\tfor (const foregroundId of foregroundIds(deps.state).filter((candidate) => candidate.startsWith(id))) {\n\t\tmatches.push({ kind: \"foreground\", id: foregroundId });\n\t}\n\tfor (const match of asyncPrefixMatches(id, asyncDirRoot, resultsDir)) {\n\t\tmatches.push({ kind: \"async\", id: match.id, location: match.location });\n\t}\n\tfor (const match of findNestedRunMatchesById(\n\t\tid,\n\t\tnestedScope ? { prefix: true, scope: nestedScope } : { prefix: true },\n\t)) {\n\t\tmatches.push({ kind: \"nested\", id: match.run.id, match });\n\t}\n\tconst unique = new Map(matches.map((match) => [`${match.kind}:${match.id}`, match]));\n\tconst values = [...unique.values()];\n\tif (values.length > 1) {\n\t\tthrow new Error(\n\t\t\t`Ambiguous subagent run id prefix '${id}' matched: ${values.map((match) => `${match.kind}:${match.id}`).join(\", \")}. Provide a longer id.`,\n\t\t);\n\t}\n\treturn values[0];\n}\n"]}