{"version":3,"file":"operability-cli.d.ts","sourceRoot":"","sources":["../../src/core/operability-cli.ts"],"names":[],"mappings":"AA0BA,iBAAS,KAAK,IAAI,MAAM,CAWvB;AAED,wBAAsB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAwB/E;AAoGD,OAAO,EAAE,KAAK,IAAI,gBAAgB,EAAE,CAAC","sourcesContent":["import { existsSync, readFileSync, statSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { validateMcpConfig, validateMcpToolSchemas } from \"./mcp.js\";\nimport { createMcpClient } from \"./mcp-client.js\";\nimport {\n\tcollectDiagnostics,\n\tcreateSupportBundle,\n\tdiffRuns,\n\tlistEvidence,\n\tloadProjectionFromSession,\n\trenderReplay,\n\tsupportBundlePreview,\n} from \"./operability.js\";\nimport {\n\tinspectSupportBundle,\n\trebuildStorageIndex,\n\treexecuteRun,\n\tsimulateReplay,\n\tstoragePrune,\n} from \"./operability-runtime.js\";\nimport { handleSubagentCommand } from \"./subagent-cli.js\";\n\nfunction output(value: unknown): void {\n\tconsole.log(JSON.stringify(value, null, 2));\n}\n\nfunction usage(): string {\n\treturn [\n\t\t\"Usage: jensen <run|evidence|doctor|support-bundle|mcp|storage> ...\",\n\t\t\"  run inspect|status|timeline|events|replay|simulate|reexecute|replay-state|diff <session-file> [other-session-file]\",\n\t\t\"  evidence list|inspect <session-file>\",\n\t\t\"  doctor [providers|tools|workspace|safety|web|lsp|jobs|budgets|routing|events|evidence|mcp|release|index|embeddings|retrieval]\",\n\t\t\"  support-bundle create|preview|inspect|verify <session-file|bundle> <destination>\",\n\t\t\"  mcp validate-config|validate-tools|resources|resource|prompts|prompt <json-file|config-file>\",\n\t\t\"  storage prune --preview|--execute <directory>\",\n\t\t\"  storage index status|rebuild <session-file> [index-file]\",\n\t].join(\"\\n\");\n}\n\nexport async function handleOperabilityCommand(args: string[]): Promise<boolean> {\n\tif (args[0] === \"doctor\" && (args[1] === \"subagents\" || args[1] === \"skills\")) {\n\t\treturn handleSubagentCommand([args[1] === \"subagents\" ? \"agents\" : \"skills\", \"validate\", \"--json\"]);\n\t}\n\tconst namespace = args[0];\n\tif (![\"run\", \"evidence\", \"doctor\", \"support-bundle\", \"mcp\", \"storage\"].includes(namespace ?? \"\")) return false;\n\ttry {\n\t\tif (namespace === \"doctor\") {\n\t\t\tconst sessionFile = args[1]?.endsWith(\".jsonl\") ? resolve(args[1]) : undefined;\n\t\t\tconst report = collectDiagnostics({ cwd: process.cwd(), sessionFile, checkMcp: args.includes(\"mcp\") });\n\t\t\toutput(report);\n\t\t\tprocess.exitCode = report.exitCode;\n\t\t\treturn true;\n\t\t}\n\t\tif (namespace === \"run\") return handleRun(args.slice(1));\n\t\tif (namespace === \"evidence\") return handleEvidence(args.slice(1));\n\t\tif (namespace === \"support-bundle\") return handleBundle(args.slice(1));\n\t\tif (namespace === \"storage\") return handleStorage(args.slice(1));\n\t\treturn handleMcp(args.slice(1));\n\t} catch (error) {\n\t\tconsole.error(error instanceof Error ? error.message : String(error));\n\t\tprocess.exitCode = 2;\n\t\treturn true;\n\t}\n}\n\nasync function handleRun(args: string[]): Promise<boolean> {\n\tconst command = args[0];\n\tconst file = args[1];\n\tif (command === \"diff\") {\n\t\tif (!file || !args[2]) throw new Error(usage());\n\t\tconst left = loadProjectionFromSession(resolve(file)).projection;\n\t\tconst right = loadProjectionFromSession(resolve(args[2])).projection;\n\t\toutput(diffRuns(left, right));\n\t\treturn true;\n\t}\n\tif (!file) throw new Error(usage());\n\tconst loaded = loadProjectionFromSession(resolve(file));\n\tif (command === \"replay\") output(renderReplay(loaded.events));\n\telse if (command === \"simulate\") output(simulateReplay(loaded.events));\n\telse if (command === \"reexecute\")\n\t\toutput(reexecuteRun(loaded.events, { cwd: process.cwd(), plan: true, outputDir: dirname(resolve(file)) }));\n\telse if (command === \"replay-state\" || command === \"inspect\" || command === \"status\")\n\t\toutput({ projection: loaded.projection, issues: loaded.events.issues });\n\telse if (command === \"timeline\" || command === \"events\") output(loaded.events);\n\telse throw new Error(usage());\n\treturn true;\n}\n\nasync function handleEvidence(args: string[]): Promise<boolean> {\n\tconst file = args[1];\n\tif (!file) throw new Error(usage());\n\tconst loaded = loadProjectionFromSession(resolve(file));\n\toutput({ evidence: listEvidence(loaded.events), projection: loaded.projection });\n\treturn true;\n}\n\nasync function handleBundle(args: string[]): Promise<boolean> {\n\tconst command = args[0];\n\tconst file = args[1];\n\tif (!file) throw new Error(usage());\n\tconst loaded = loadProjectionFromSession(resolve(file));\n\tconst report = collectDiagnostics({ cwd: process.cwd(), sessionFile: resolve(file) });\n\tif (command === \"preview\") output(supportBundlePreview(report, loaded.projection));\n\telse if (command === \"create\") {\n\t\tif (!args[2]) throw new Error(\"support-bundle create requires a destination\");\n\t\toutput(createSupportBundle(resolve(args[2]), report, loaded.projection));\n\t} else if (command === \"inspect\" || command === \"verify\") output(inspectSupportBundle(resolve(file)));\n\telse throw new Error(usage());\n\treturn true;\n}\n\nasync function handleStorage(args: string[]): Promise<boolean> {\n\tif (args[0] === \"prune\") {\n\t\tconst root = args.find((arg) => !arg.startsWith(\"--\") && arg !== \"prune\") ?? process.cwd();\n\t\toutput(storagePrune(root, { preview: !args.includes(\"--execute\") }));\n\t\treturn true;\n\t}\n\tif (args[0] === \"index\") {\n\t\tconst file = args[2];\n\t\tif (!file) throw new Error(usage());\n\t\tif (args[1] === \"rebuild\") output(rebuildStorageIndex(resolve(file), args[3] ? resolve(args[3]) : undefined));\n\t\telse if (args[1] === \"status\")\n\t\t\toutput({\n\t\t\t\tpath: resolve(file),\n\t\t\t\texists: existsSync(resolve(file)),\n\t\t\t\tbytes: existsSync(resolve(file)) ? statSync(resolve(file)).size : 0,\n\t\t\t});\n\t\telse throw new Error(usage());\n\t\treturn true;\n\t}\n\tthrow new Error(usage());\n}\n\nasync function handleMcp(args: string[]): Promise<boolean> {\n\tconst command = args[0];\n\tconst file = args[1];\n\tif (!file || !existsSync(file)) throw new Error(\"MCP validation requires a JSON file\");\n\tconst value = JSON.parse(readFileSync(file, \"utf8\"));\n\tif (command === \"validate-config\") {\n\t\tif (!value || typeof value !== \"object\" || Array.isArray(value))\n\t\t\tthrow new Error(\"MCP configuration must be a JSON object\");\n\t\tconst issues = validateMcpConfig(value);\n\t\toutput({ valid: issues.length === 0, issues });\n\t} else if (command === \"validate-tools\") {\n\t\tif (!Array.isArray(value)) throw new Error(\"MCP tools must be a JSON array\");\n\t\toutput(validateMcpToolSchemas(value));\n\t} else if ([\"resources\", \"resource\", \"prompts\", \"prompt\"].includes(command ?? \"\")) {\n\t\tconst client = createMcpClient(value, { env: process.env });\n\t\tawait client.connect();\n\t\tconst response =\n\t\t\tcommand === \"resources\"\n\t\t\t\t? await client.listResources()\n\t\t\t\t: command === \"resource\"\n\t\t\t\t\t? await client.readResource(args[2] ?? \"\")\n\t\t\t\t\t: command === \"prompts\"\n\t\t\t\t\t\t? await client.listPrompts()\n\t\t\t\t\t\t: await client.inspectPrompt(args[2] ?? \"\");\n\t\toutput(response.result ?? response);\n\t\tawait client.close();\n\t} else throw new Error(usage());\n\treturn true;\n}\n\nexport { usage as operabilityUsage };\n"]}