{"version":3,"file":"execution-diagnostics.d.ts","sourceRoot":"","sources":["../../src/core/execution-diagnostics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAEhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;;;GAKG;AAEH,MAAM,WAAW,yBAAyB;IACzC,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,gEAAgE;IAChE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACpC,GAAG,EAAE;QACJ,eAAe,EAAE,KAAK,CAAC;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,OAAO,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACvG,aAAa,EAAE,KAAK,CAAC;YAAE,QAAQ,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAClG,WAAW,EAAE,KAAK,CAAC;YAAE,UAAU,EAAE,MAAM,CAAC;YAAC,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;KAC3D,CAAC;IACF,KAAK,EAAE;QACN,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACvC,uBAAuB,EAAE,MAAM,CAAC;QAChC,gBAAgB,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,SAAS,EAAE;QACV,MAAM,EAAE;YAAE,SAAS,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,OAAO,EAAE,MAAM,CAAC;YAAC,SAAS,EAAE,MAAM,CAAA;SAAE,CAAC;QACnF,YAAY,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,IAAI,EAAE;QACL,OAAO,EAAE,KAAK,CAAC;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,eAAe,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QAC3F,gBAAgB,EAAE,MAAM,CAAC;KACzB,CAAC;CACF;AAED,+DAA+D;AAC/D,wBAAsB,2BAA2B,CAChD,KAAK,GAAE,yBAA8B,GACnC,OAAO,CAAC,oBAAoB,CAAC,CA+C/B;AAED,8DAA8D;AAC9D,wBAAgB,0BAA0B,CAAC,CAAC,EAAE,oBAAoB,GAAG,MAAM,CAoB1E","sourcesContent":["import type { BackgroundJobRegistry } from \"./jobs/registry.js\";\nimport { reportAllServers } from \"./lsp/discovery.js\";\nimport type { LspServerManager } from \"./lsp/manager.js\";\nimport type { StormBreaker } from \"./storm/breaker.js\";\n\n/**\n * Aggregated diagnostics for the 1.4.0 capabilities. Provides the data behind\n * `jensen doctor lsp|tools|scheduler|jobs` and `jensen lsp status` /\n * `jensen jobs list`. Never exposes secrets, tokens, full files or raw\n * sensitive arguments.\n */\n\nexport interface ExecutionDiagnosticsInput {\n\tmanager?: LspServerManager;\n\tjobs?: BackgroundJobRegistry;\n\tstorm?: StormBreaker;\n\t/** Scheduler limits (opaque; diagnostics treats it as data). */\n\tscheduler?: unknown;\n\tworkspaceRoot?: string;\n}\n\nexport interface ExecutionDiagnostics {\n\tlsp: {\n\t\tserverDiscovery: Array<{ languageId: string; candidate: string; available: boolean; reason?: string }>;\n\t\tactiveServers: Array<{ serverId: string; languageId: string; executable: string; state: string }>;\n\t\tunavailable: Array<{ languageId: string; reason: string }>;\n\t};\n\ttools: {\n\t\trepairCounters: Record<string, number>;\n\t\tblockedAmbiguousRepairs: number;\n\t\tstormHistorySize: number;\n\t};\n\tscheduler: {\n\t\tlimits: { globalMax: number; perTool: number; perHost: number; perServer: number };\n\t\tactiveGroups: number;\n\t};\n\tjobs: {\n\t\trecords: Array<{ jobId: string; state: string; health?: string; processIdentity: string }>;\n\t\torphanOrAdoption: number;\n\t};\n}\n\n/** Success or short-circuit: pure aggregation, no mutation. */\nexport async function collectExecutionDiagnostics(\n\tinput: ExecutionDiagnosticsInput = {},\n): Promise<ExecutionDiagnostics> {\n\tconst discovery = await reportAllServers();\n\tconst unavailable = discovery\n\t\t.filter((d) => !d.available)\n\t\t.map((d) => ({ languageId: d.languageId, reason: d.reason ?? \"missing\" }));\n\n\tconst activeServers = input.manager?.listServers() ?? [];\n\tconst jobRecords = input.jobs ? await input.jobs.list() : [];\n\tconst orphanOrAdoption = jobRecords.filter((r) => r.state === \"orphaned\" || r.state === \"adoption_required\").length;\n\n\tconst stormSnapshot = input.storm?.snapshot();\n\n\treturn {\n\t\tlsp: {\n\t\t\tserverDiscovery: discovery.map((d) => ({\n\t\t\t\tlanguageId: d.languageId,\n\t\t\t\tcandidate: d.candidate,\n\t\t\t\tavailable: d.available,\n\t\t\t\treason: d.reason,\n\t\t\t})),\n\t\t\tactiveServers,\n\t\t\tunavailable,\n\t\t},\n\t\ttools: {\n\t\t\trepairCounters: stormSnapshot?.counts ?? {},\n\t\t\tblockedAmbiguousRepairs: 0,\n\t\t\tstormHistorySize: stormSnapshot?.historySize ?? 0,\n\t\t},\n\t\tscheduler: {\n\t\t\tlimits: {\n\t\t\t\tglobalMax: 8,\n\t\t\t\tperTool: 4,\n\t\t\t\tperHost: 3,\n\t\t\t\tperServer: 2,\n\t\t\t},\n\t\t\tactiveGroups: 0,\n\t\t},\n\t\tjobs: {\n\t\t\trecords: jobRecords.map((r) => ({\n\t\t\t\tjobId: r.jobId,\n\t\t\t\tstate: r.state,\n\t\t\t\thealth: r.health,\n\t\t\t\tprocessIdentity: r.processIdentity,\n\t\t\t})),\n\t\t\torphanOrAdoption,\n\t\t},\n\t};\n}\n\n/** Human-readable rendering of the aggregated diagnostics. */\nexport function formatExecutionDiagnostics(d: ExecutionDiagnostics): string {\n\tconst lines: string[] = [];\n\tlines.push(\"LSP: registered server candidates\");\n\tfor (const s of d.lsp.serverDiscovery) {\n\t\tlines.push(\n\t\t\t`  ${s.languageId}: ${s.candidate} ${s.available ? \"available\" : \"UNAVAILABLE\"}${s.reason ? ` (${s.reason})` : \"\"}`,\n\t\t);\n\t}\n\tlines.push(`LSP: active servers: ${d.lsp.activeServers.length}`);\n\tfor (const s of d.lsp.activeServers) {\n\t\tlines.push(`  ${s.serverId} [${s.languageId}] state=${s.state}`);\n\t}\n\tlines.push(`LSP: unavailable: ${d.lsp.unavailable.length}`);\n\tlines.push(`Scheduler limits: ${JSON.stringify(d.scheduler.limits)} activeGroups=${d.scheduler.activeGroups}`);\n\tlines.push(`Storm breaker history: ${d.tools.stormHistorySize}`);\n\tlines.push(`Background jobs: ${d.jobs.records.length} (orphan/adoption: ${d.jobs.orphanOrAdoption})`);\n\tfor (const j of d.jobs.records) {\n\t\tlines.push(`  ${j.jobId}: ${j.state} health=${j.health ?? \"unknown\"} pid=${j.processIdentity}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n"]}