panopticon-cli 0.6.7 → 0.6.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/dist/{agents-D_2oRFVf.js → agents-BQOqo27C.js} +1 -1
  2. package/dist/{agents-CfFDs52G.js → agents-DezveQ1x.js} +4 -4
  3. package/dist/{agents-CfFDs52G.js.map → agents-DezveQ1x.js.map} +1 -1
  4. package/dist/cli/index.js +34 -34
  5. package/dist/{config-yaml-DGbLSMCa.js → config-yaml-BHD2Qdd8.js} +22 -1
  6. package/dist/config-yaml-BHD2Qdd8.js.map +1 -0
  7. package/dist/{config-yaml-Dqt4FWQH.js → config-yaml-IlSnFzJQ.js} +1 -1
  8. package/dist/dashboard/{agent-enrichment-DdO7ZqjI.js → agent-enrichment-BKZjVvlL.js} +3 -3
  9. package/dist/dashboard/{agent-enrichment-DdO7ZqjI.js.map → agent-enrichment-BKZjVvlL.js.map} +1 -1
  10. package/dist/dashboard/{agent-enrichment-dLeGE1fX.js → agent-enrichment-iY3_PylI.js} +1 -1
  11. package/dist/dashboard/{agents-DCpQQ_W5.js → agents-BQWA-Vps.js} +4 -4
  12. package/dist/dashboard/{agents-DCpQQ_W5.js.map → agents-BQWA-Vps.js.map} +1 -1
  13. package/dist/dashboard/{agents-Dgh2TjSp.js → agents-Dinc9j_8.js} +1 -1
  14. package/dist/dashboard/{config-yaml-DkresmrS.js → config-yaml-CNNnB4Mu.js} +1 -1
  15. package/dist/dashboard/{config-yaml-DSfYpzN6.js → config-yaml-DUu0JI25.js} +22 -1
  16. package/dist/dashboard/{config-yaml-DSfYpzN6.js.map → config-yaml-DUu0JI25.js.map} +1 -1
  17. package/dist/dashboard/{factory-C8nhLGHB.js → factory-CBY0WWeE.js} +2 -2
  18. package/dist/dashboard/{factory-C8nhLGHB.js.map → factory-CBY0WWeE.js.map} +1 -1
  19. package/dist/dashboard/{inspect-agent-7eour7EA.js → inspect-agent-KKOeNR7E.js} +3 -3
  20. package/dist/dashboard/{inspect-agent-7eour7EA.js.map → inspect-agent-KKOeNR7E.js.map} +1 -1
  21. package/dist/dashboard/{issue-service-singleton-Wv4xBm3y.js → issue-service-singleton-BCZ62hLj.js} +3 -3
  22. package/dist/dashboard/{issue-service-singleton-Wv4xBm3y.js.map → issue-service-singleton-BCZ62hLj.js.map} +1 -1
  23. package/dist/dashboard/{issue-service-singleton-Co__-6kL.js → issue-service-singleton-BGKf0A95.js} +1 -1
  24. package/dist/dashboard/{lifecycle-BcUmtkR4.js → lifecycle-Dpgg-IeP.js} +1 -1
  25. package/dist/dashboard/{merge-agent-CGN3TT0a.js → merge-agent-CqvQu-n_.js} +1 -1
  26. package/dist/dashboard/{merge-agent-yudQOPZc.js → merge-agent-Dxxc4JEE.js} +5 -5
  27. package/dist/dashboard/{merge-agent-yudQOPZc.js.map → merge-agent-Dxxc4JEE.js.map} +1 -1
  28. package/dist/dashboard/public/assets/{dist-CXaO6nOE.js → dist-DS1gmhe1.js} +1 -1
  29. package/dist/dashboard/public/assets/index-DjGsaJLv.js +212 -0
  30. package/dist/dashboard/public/index.html +1 -1
  31. package/dist/dashboard/{review-status-BtXqWBhS.js → review-status-Dww2OKUX.js} +1 -1
  32. package/dist/dashboard/{review-status-Bymwzh2i.js → review-status-d_wOE-XQ.js} +3 -3
  33. package/dist/dashboard/{review-status-Bymwzh2i.js.map → review-status-d_wOE-XQ.js.map} +1 -1
  34. package/dist/dashboard/server.js +97 -97
  35. package/dist/dashboard/settings-BHlDG7TK.js.map +1 -1
  36. package/dist/dashboard/{spawn-planning-session-D5hrVdWM.js → spawn-planning-session-D5uEpHzf.js} +1 -1
  37. package/dist/dashboard/{spawn-planning-session-33Jf-d5T.js → spawn-planning-session-DtbNfA2Q.js} +3 -3
  38. package/dist/dashboard/{spawn-planning-session-33Jf-d5T.js.map → spawn-planning-session-DtbNfA2Q.js.map} +1 -1
  39. package/dist/dashboard/{specialist-context-DGukHSn8.js → specialist-context-CEKqWqyF.js} +4 -4
  40. package/dist/dashboard/{specialist-context-DGukHSn8.js.map → specialist-context-CEKqWqyF.js.map} +1 -1
  41. package/dist/dashboard/{specialist-logs-CIw4qfTy.js → specialist-logs-CBGVRoQF.js} +1 -1
  42. package/dist/dashboard/{specialists-Cp-PgspS.js → specialists-sIFlMd3s.js} +1 -1
  43. package/dist/dashboard/{specialists-B_zrayaP.js → specialists-saEYE0-z.js} +20 -20
  44. package/dist/dashboard/{specialists-B_zrayaP.js.map → specialists-saEYE0-z.js.map} +1 -1
  45. package/dist/dashboard/{test-agent-queue-ypF_ecHo.js → test-agent-queue-7jXB2KkN.js} +3 -3
  46. package/dist/dashboard/{test-agent-queue-ypF_ecHo.js.map → test-agent-queue-7jXB2KkN.js.map} +1 -1
  47. package/dist/dashboard/{tracker-config-BP59uH4V.js → tracker-config-BX6ijWOc.js} +1 -1
  48. package/dist/dashboard/{tracker-config-e7ph1QqT.js → tracker-config-tD22z5sv.js} +2 -2
  49. package/dist/dashboard/{tracker-config-e7ph1QqT.js.map → tracker-config-tD22z5sv.js.map} +1 -1
  50. package/dist/dashboard/{work-agent-prompt-fCg67nyo.js → work-agent-prompt-D3tPzPvb.js} +2 -2
  51. package/dist/dashboard/{work-agent-prompt-fCg67nyo.js.map → work-agent-prompt-D3tPzPvb.js.map} +1 -1
  52. package/dist/dashboard/{work-type-router-CWVW2Wk_.js → work-type-router-7kwLSwrP.js} +4 -2
  53. package/dist/dashboard/work-type-router-7kwLSwrP.js.map +1 -0
  54. package/dist/dashboard/{work-type-router-Di5gCQwh.js → work-type-router-ByOOudGz.js} +1 -1
  55. package/dist/dashboard/workflows-BDpPjK18.js +2 -0
  56. package/dist/dashboard/{workflows-BSMipN07.js → workflows-DcEeDkbS.js} +3 -3
  57. package/dist/dashboard/{workflows-BSMipN07.js.map → workflows-DcEeDkbS.js.map} +1 -1
  58. package/dist/{factory-BRBGw6OB.js → factory-BR48tuUR.js} +1 -1
  59. package/dist/{factory-DzsOiZVc.js → factory-D6LJaZ__.js} +2 -2
  60. package/dist/{factory-DzsOiZVc.js.map → factory-D6LJaZ__.js.map} +1 -1
  61. package/dist/index.d.ts +1 -1
  62. package/dist/index.js +3 -3
  63. package/dist/{merge-agent-DlUiUanN.js → merge-agent-BBwHwpn2.js} +3 -3
  64. package/dist/{merge-agent-DlUiUanN.js.map → merge-agent-BBwHwpn2.js.map} +1 -1
  65. package/dist/{review-status-DEDvCKMP.js → review-status-Ba6llgCb.js} +3 -3
  66. package/dist/{review-status-DEDvCKMP.js.map → review-status-Ba6llgCb.js.map} +1 -1
  67. package/dist/{review-status-D6H2WOw8.js → review-status-Chxzuwn2.js} +1 -1
  68. package/dist/{settings-BcWPTrua.js → settings-A-CWz_ph.js} +6 -2
  69. package/dist/{settings-BcWPTrua.js.map → settings-A-CWz_ph.js.map} +1 -1
  70. package/dist/{specialist-context-BAUWL1Fl.js → specialist-context-B3lknlwi.js} +4 -4
  71. package/dist/{specialist-context-BAUWL1Fl.js.map → specialist-context-B3lknlwi.js.map} +1 -1
  72. package/dist/{specialist-logs-DQKKQV9B.js → specialist-logs-DDyY4xqo.js} +1 -1
  73. package/dist/{specialists-D7Kj5o6s.js → specialists-DvTYu1VZ.js} +20 -20
  74. package/dist/{specialists-D7Kj5o6s.js.map → specialists-DvTYu1VZ.js.map} +1 -1
  75. package/dist/{specialists-Bfb9ATzw.js → specialists-DyB4IRlM.js} +1 -1
  76. package/dist/sync-CLVqiGl4.js +2 -0
  77. package/dist/{sync-DMfgd389.js → sync-DTHFlEc-.js} +2 -2
  78. package/dist/{sync-DMfgd389.js.map → sync-DTHFlEc-.js.map} +1 -1
  79. package/dist/{tracker-BhYYvU3p.js → tracker-CYpb7oUa.js} +2 -2
  80. package/dist/{tracker-BhYYvU3p.js.map → tracker-CYpb7oUa.js.map} +1 -1
  81. package/dist/{work-type-router-CHjciPyS.js → work-type-router-oCgTPXsP.js} +4 -2
  82. package/dist/work-type-router-oCgTPXsP.js.map +1 -0
  83. package/package.json +1 -1
  84. package/dist/config-yaml-DGbLSMCa.js.map +0 -1
  85. package/dist/dashboard/public/assets/index-CzFZIb87.js +0 -212
  86. package/dist/dashboard/work-type-router-CWVW2Wk_.js.map +0 -1
  87. package/dist/dashboard/workflows-DaYWQIS2.js +0 -2
  88. package/dist/sync-TL6y-8K6.js +0 -2
  89. package/dist/work-type-router-CHjciPyS.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"config-yaml-DGbLSMCa.js","names":[],"sources":["../src/lib/model-capabilities.ts","../src/lib/config-yaml.ts"],"sourcesContent":["/**\n * Model Capability Matrix\n *\n * Defines capability scores for each model across different skill dimensions.\n * This enables intelligent model selection based on what the user has enabled\n * rather than static presets.\n *\n * Scores: 0-100 where 100 = best in class\n * Cost: $/1M tokens (input + output average)\n *\n * Last updated: 2026-01-29\n * Sources:\n * - SWE-bench Verified leaderboard (vals.ai)\n * - LiveCodeBench v6\n * - LMSYS Chatbot Arena\n * - Artificial Analysis\n * - Official provider pricing pages\n */\n\nimport { ModelId } from './settings.js';\n\n/**\n * Model ID deprecation mapping\n *\n * Maps deprecated model IDs to their current replacements.\n * When a model ID changes (e.g., claude-opus-4-5 → claude-opus-4-6),\n * add the mapping here to enable automatic migration.\n *\n * Strategy: Single-hop only. When a newer version arrives (e.g., 4-7),\n * add both old→new mappings (4-5→4-7 and 4-6→4-7).\n */\nexport const MODEL_DEPRECATIONS: Record<string, ModelId> = {\n 'claude-opus-4-5': 'claude-opus-4-6',\n 'claude-sonnet-4-5': 'claude-sonnet-4-6',\n};\n\n/**\n * Resolve a model ID to its current version\n *\n * If the model ID is deprecated, returns the replacement.\n * Otherwise, returns the model ID unchanged.\n *\n * @param modelId - Model ID to resolve (may be deprecated)\n * @returns Current model ID\n */\nexport function resolveModelId(modelId: string): ModelId {\n return (MODEL_DEPRECATIONS[modelId] as ModelId) || (modelId as ModelId);\n}\n\n/**\n * Skill dimensions that models are evaluated on\n */\nexport type SkillDimension =\n | 'code-generation' // Writing new code\n | 'code-review' // Finding issues in code\n | 'debugging' // Root cause analysis\n | 'planning' // Architecture and strategy\n | 'documentation' // Writing docs, PRDs\n | 'testing' // Test generation and analysis\n | 'security' // Security analysis\n | 'performance' // Performance optimization\n | 'synthesis' // Combining information\n | 'speed' // Response latency\n | 'context-length'; // Max context window\n\n/**\n * Capability profile for a single model\n */\nexport interface ModelCapability {\n /** Model identifier */\n model: ModelId;\n /** Provider for this model */\n provider: 'anthropic' | 'openai' | 'google' | 'zai' | 'kimi' | 'minimax' | 'openrouter';\n /** Display name */\n displayName: string;\n /** Cost per 1M tokens (average of input/output) in USD */\n costPer1MTokens: number;\n /** Capability scores (0-100) for each skill dimension */\n skills: Record<SkillDimension, number>;\n /** Context window size in tokens */\n contextWindow: number;\n /** Additional notes about this model's strengths */\n notes?: string;\n}\n\n/**\n * Master capability database\n *\n * Scores are based on:\n * - Public benchmarks (HumanEval, SWE-bench, MBPP)\n * - Community consensus\n * - Practical experience\n *\n * These are baseline scores - run Kimi 2.5 research to refine.\n */\nexport const MODEL_CAPABILITIES: Record<ModelId, ModelCapability> = {\n // ═══════════════════════════════════════════════════════════════════════════\n // ANTHROPIC MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n 'claude-opus-4-6': {\n model: 'claude-opus-4-6',\n provider: 'anthropic',\n displayName: 'Claude Opus 4.6',\n costPer1MTokens: 45.0, // $5 in / $25 out → same pricing as 4.5\n contextWindow: 200000, // 1M available via opt-in beta, but we use 200K\n skills: {\n 'code-generation': 96, // 80.9% SWE-bench (first >80%), 89.4% Aider Polyglot\n 'code-review': 98,\n debugging: 97,\n planning: 99, // User confirms: \"Opus 4.6 planning for sure\"\n documentation: 95,\n testing: 92,\n security: 98, // Best for security review\n performance: 90,\n synthesis: 98, // Best for combining info across domains\n speed: 40, // Slower but 76% more token efficient\n 'context-length': 95,\n },\n notes: 'Successor to Opus 4.5. Same pricing, 1M context available (opt-in beta). Best for planning, security, complex reasoning.',\n },\n\n 'claude-sonnet-4-6': {\n model: 'claude-sonnet-4-6',\n provider: 'anthropic',\n displayName: 'Claude Sonnet 4.6',\n costPer1MTokens: 9.0, // $3 in / $15 out → avg ~$9\n contextWindow: 200000,\n skills: {\n 'code-generation': 94,\n 'code-review': 94,\n debugging: 92,\n planning: 90,\n documentation: 92,\n testing: 92,\n security: 88,\n performance: 88,\n synthesis: 90,\n speed: 70,\n 'context-length': 95,\n },\n notes: 'Successor to Sonnet 4.5. Same pricing tier. Improved coding and reasoning.',\n },\n\n 'claude-sonnet-4-5': {\n model: 'claude-sonnet-4-5',\n provider: 'anthropic',\n displayName: 'Claude Sonnet 4.5',\n costPer1MTokens: 9.0, // $3 in / $15 out → avg ~$9\n contextWindow: 200000,\n skills: {\n 'code-generation': 92, // 77.2% SWE-bench (82% parallel), beats GPT-5 Codex (74.5%)\n 'code-review': 92,\n debugging: 90,\n planning: 88,\n documentation: 90, // 100% AIME with Python\n testing: 90, // 50% Terminal-Bench, 61.4% OSWorld\n security: 85,\n performance: 85,\n synthesis: 88,\n speed: 70,\n 'context-length': 95,\n },\n notes: 'Best value: 77.2% SWE-bench at 1/5th Opus cost. Beats GPT-5 Codex.',\n },\n\n 'claude-haiku-4-5': {\n model: 'claude-haiku-4-5',\n provider: 'anthropic',\n displayName: 'Claude Haiku 4.5',\n costPer1MTokens: 4.0, // $0.80 in / $4 out → avg ~$2.4\n contextWindow: 200000,\n skills: {\n 'code-generation': 75,\n 'code-review': 72,\n debugging: 70,\n planning: 65,\n documentation: 75,\n testing: 70,\n security: 60,\n performance: 65,\n synthesis: 68,\n speed: 95, // Fastest Anthropic\n 'context-length': 95,\n },\n notes: 'Fast and cheap, good for simple tasks and exploration',\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // OPENAI MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n 'gpt-5.2-codex': {\n model: 'gpt-5.2-codex',\n provider: 'openai',\n displayName: 'GPT-5.2 Codex',\n costPer1MTokens: 75.0, // Premium tier ~$75/M\n contextWindow: 128000,\n skills: {\n 'code-generation': 95, // 80% SWE-bench Verified, 55.6% SWE-bench Pro\n 'code-review': 90,\n debugging: 92, // 92.4% GPQA Diamond\n planning: 88,\n documentation: 85,\n testing: 90,\n security: 85,\n performance: 88, // 52.9% ARC-AGI-2 (best reasoning)\n synthesis: 88, // 100% AIME 2025 without tools\n speed: 55,\n 'context-length': 75,\n },\n notes: 'Premium coding: 80% SWE-bench. Best raw reasoning (52.9% ARC-AGI-2). Expensive.',\n },\n\n 'o3-deep-research': {\n model: 'o3-deep-research',\n provider: 'openai',\n displayName: 'O3 Deep Research',\n costPer1MTokens: 100.0, // Expensive reasoning model\n contextWindow: 200000,\n skills: {\n 'code-generation': 85,\n 'code-review': 95,\n debugging: 98, // Best for debugging\n planning: 95,\n documentation: 88,\n testing: 85,\n security: 92,\n performance: 92,\n synthesis: 95,\n speed: 20, // Very slow (reasoning chains)\n 'context-length': 95,\n },\n notes: 'Deep reasoning model, excellent for complex debugging and analysis',\n },\n\n 'gpt-4o': {\n model: 'gpt-4o',\n provider: 'openai',\n displayName: 'GPT-4o',\n costPer1MTokens: 15.0, // $5 in / $15 out\n contextWindow: 128000,\n skills: {\n 'code-generation': 88,\n 'code-review': 85,\n debugging: 85,\n planning: 82,\n documentation: 88,\n testing: 82,\n security: 78,\n performance: 80,\n synthesis: 85,\n speed: 75,\n 'context-length': 75,\n },\n notes: 'Good all-rounder, competitive with Sonnet',\n },\n\n 'gpt-4o-mini': {\n model: 'gpt-4o-mini',\n provider: 'openai',\n displayName: 'GPT-4o Mini',\n costPer1MTokens: 1.0, // Very cheap\n contextWindow: 128000,\n skills: {\n 'code-generation': 72,\n 'code-review': 68,\n debugging: 65,\n planning: 60,\n documentation: 70,\n testing: 65,\n security: 55,\n performance: 60,\n synthesis: 62,\n speed: 92,\n 'context-length': 75,\n },\n notes: 'Budget option, good for simple tasks',\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // GOOGLE MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n 'gemini-3-pro-preview': {\n model: 'gemini-3-pro-preview',\n provider: 'google',\n displayName: 'Gemini 3 Pro',\n costPer1MTokens: 12.0, // $4.2 in / $18.9 out\n contextWindow: 1000000, // 1M context!\n skills: {\n 'code-generation': 90, // 2439 Elo LiveCodeBench Pro (first >1500 on LMArena)\n 'code-review': 88,\n debugging: 85,\n planning: 85,\n documentation: 88,\n testing: 85, // ~95% AIME 2025\n security: 78,\n performance: 85, // Strong multimodal\n synthesis: 90, // Best for combining large codebases\n speed: 80,\n 'context-length': 100, // Best context - 1M tokens\n },\n notes: 'First to exceed 1500 Elo on LMArena. Best for large codebase analysis with 1M context.',\n },\n\n 'gemini-3-flash-preview': {\n model: 'gemini-3-flash-preview',\n provider: 'google',\n displayName: 'Gemini 3 Flash',\n costPer1MTokens: 0.5, // Very cheap\n contextWindow: 1000000,\n skills: {\n 'code-generation': 75,\n 'code-review': 70,\n debugging: 68,\n planning: 62,\n documentation: 72,\n testing: 68,\n security: 55,\n performance: 65,\n synthesis: 70,\n speed: 98, // Fastest overall\n 'context-length': 100,\n },\n notes: 'Extremely fast and cheap, huge context, great for exploration',\n },\n\n 'gemini-2.5-pro': {\n model: 'gemini-2.5-pro',\n provider: 'google',\n displayName: 'Gemini 2.5 Pro',\n costPer1MTokens: 12.0,\n contextWindow: 1000000,\n skills: {\n 'code-generation': 92,\n 'code-review': 90,\n debugging: 88,\n planning: 88,\n documentation: 90,\n testing: 87,\n security: 82,\n performance: 88,\n synthesis: 92,\n speed: 75,\n 'context-length': 100,\n },\n notes: 'Advanced reasoning and code capabilities with 1M context',\n },\n\n 'gemini-2.5-flash': {\n model: 'gemini-2.5-flash',\n provider: 'google',\n displayName: 'Gemini 2.5 Flash',\n costPer1MTokens: 0.6,\n contextWindow: 1000000,\n skills: {\n 'code-generation': 78,\n 'code-review': 73,\n debugging: 70,\n planning: 65,\n documentation: 75,\n testing: 70,\n security: 58,\n performance: 68,\n synthesis: 73,\n speed: 95,\n 'context-length': 100,\n },\n notes: 'Fast and efficient with large context support',\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // Z.AI MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n 'glm-4.7': {\n model: 'glm-4.7',\n provider: 'zai',\n displayName: 'GLM 4.7',\n costPer1MTokens: 5.0,\n contextWindow: 200000, // 200K context, 128K output\n skills: {\n 'code-generation': 88, // 73.8% SWE-bench, 84.9 LiveCodeBench v6 (open-source SOTA)\n 'code-review': 85,\n debugging: 85, // Strong debugging with Interleaved Thinking\n planning: 82, // 95.7% AIME 2025 (beats Gemini 3 & GPT-5.1)\n documentation: 80,\n testing: 82, // 87.4 τ²-Bench (SOTA for tool use)\n security: 72,\n performance: 78,\n synthesis: 85, // Preserved Thinking retains context across turns\n speed: 80,\n 'context-length': 95, // 200K context\n },\n notes: 'Top open-source for agentic coding. 73.8% SWE-bench, best tool use. 400B params with Interleaved Thinking.',\n },\n\n 'glm-4.7-flash': {\n model: 'glm-4.7-flash',\n provider: 'zai',\n displayName: 'GLM 4.7 Flash',\n costPer1MTokens: 1.5,\n contextWindow: 128000,\n skills: {\n 'code-generation': 72,\n 'code-review': 68,\n debugging: 65,\n planning: 62,\n documentation: 70,\n testing: 65,\n security: 55,\n performance: 62,\n synthesis: 65,\n speed: 92, // Fast inference\n 'context-length': 75,\n },\n notes: 'Fast and affordable. Good for quick iterations and exploration.',\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // KIMI MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n 'kimi-k2': {\n model: 'kimi-k2',\n provider: 'kimi',\n displayName: 'Kimi K2',\n costPer1MTokens: 1.4, // $0.16 in / $2.63 out → very cheap\n contextWindow: 131000,\n skills: {\n 'code-generation': 82, // 65.8% SWE-bench (beats GPT-4.1 at 54.6%)\n 'code-review': 80,\n debugging: 78,\n planning: 75,\n documentation: 80,\n testing: 75,\n security: 70,\n performance: 72,\n synthesis: 78,\n speed: 80,\n 'context-length': 75,\n },\n notes: 'Strong value: 65.8% SWE-bench at very low cost. Good for routine tasks.',\n },\n\n 'kimi-k2.5': {\n model: 'kimi-k2.5',\n provider: 'kimi',\n displayName: 'Kimi K2.5',\n costPer1MTokens: 8.0, // ~5.1x cheaper than GPT-5.2\n contextWindow: 256000,\n skills: {\n 'code-generation': 92, // 76.8% SWE-bench, 85 LiveCodeBench v6\n 'code-review': 90,\n debugging: 90, // Strong analytical capabilities\n planning: 88, // User confirms \"highly capable\"\n documentation: 88,\n testing: 88, // 92% coding accuracy\n security: 82,\n performance: 85,\n synthesis: 92, // Can coordinate 100 sub-agents, 1500 tool calls\n speed: 75, // MoE: 1T total params, 32B active\n 'context-length': 98, // 256K context\n },\n notes: 'Best open-source coding model. 5x cheaper than GPT-5.2. Excellent for frontend dev and multi-agent orchestration.',\n },\n\n // ═══════════════════════════════════════════════════════════════════════════\n // MINIMAX MODELS\n // ═══════════════════════════════════════════════════════════════════════════\n\n 'minimax-m2.7': {\n model: 'minimax-m2.7',\n provider: 'minimax',\n displayName: 'MiniMax M2.7',\n costPer1MTokens: 1.5, // $0.30/M in + $1.20/M out, blended ~$0.06/M with auto-cache\n contextWindow: 204800,\n skills: {\n 'code-generation': 90, // 56.22% SWE-Pro (Opus ~57-58%), 55.6% VIBE-Pro\n 'code-review': 88,\n debugging: 88, // 57.0% Terminal Bench 2\n planning: 85,\n documentation: 85,\n testing: 86,\n security: 80,\n performance: 82,\n synthesis: 90, // Self-evolving agent, 97% skill adherence on complex tasks\n speed: 80, // 10B active params (MoE)\n 'context-length': 92, // 204K context\n },\n notes: '10B active params, 56.22% SWE-Pro, 1495 ELO GDPval-AA. $0.06/M blended with auto-cache.',\n },\n\n 'minimax-m2.7-highspeed': {\n model: 'minimax-m2.7-highspeed',\n provider: 'minimax',\n displayName: 'MiniMax M2.7 Highspeed',\n costPer1MTokens: 1.5, // Same pricing as M2.7\n contextWindow: 204800,\n skills: {\n 'code-generation': 90,\n 'code-review': 88,\n debugging: 88,\n planning: 85,\n documentation: 85,\n testing: 86,\n security: 80,\n performance: 82,\n synthesis: 90,\n speed: 92, // 100 tps, 3x faster than Opus\n 'context-length': 92,\n },\n notes: 'Identical quality to M2.7, 100 tps (3x Opus speed). Best for high-throughput agent work.',\n },\n};\n\n/**\n * Get capability profile for a model\n */\nexport function getModelCapability(model: ModelId): ModelCapability {\n return MODEL_CAPABILITIES[model];\n}\n\n/**\n * Get all models sorted by a specific skill (descending)\n */\nexport function getModelsBySkill(skill: SkillDimension): ModelId[] {\n return (Object.keys(MODEL_CAPABILITIES) as ModelId[]).sort(\n (a, b) => MODEL_CAPABILITIES[b].skills[skill] - MODEL_CAPABILITIES[a].skills[skill]\n );\n}\n\n/**\n * Get all models for a provider\n */\nexport function getModelsForProvider(\n provider: ModelCapability['provider']\n): ModelId[] {\n return (Object.keys(MODEL_CAPABILITIES) as ModelId[]).filter(\n (model) => MODEL_CAPABILITIES[model].provider === provider\n );\n}\n\n/**\n * Get cheapest models (sorted by cost ascending)\n */\nexport function getCheapestModels(): ModelId[] {\n return (Object.keys(MODEL_CAPABILITIES) as ModelId[]).sort(\n (a, b) => MODEL_CAPABILITIES[a].costPer1MTokens - MODEL_CAPABILITIES[b].costPer1MTokens\n );\n}\n\n/**\n * Calculate cost efficiency score for a skill\n * Higher = better value (skill score / cost)\n */\nexport function getValueScore(model: ModelId, skill: SkillDimension): number {\n const cap = MODEL_CAPABILITIES[model];\n return cap.skills[skill] / Math.log10(cap.costPer1MTokens + 1);\n}\n\n/**\n * Get all skill dimensions\n */\nexport function getAllSkillDimensions(): SkillDimension[] {\n return [\n 'code-generation',\n 'code-review',\n 'debugging',\n 'planning',\n 'documentation',\n 'testing',\n 'security',\n 'performance',\n 'synthesis',\n 'speed',\n 'context-length',\n ];\n}\n","/**\n * YAML Configuration Loader\n *\n * Loads and merges configuration from:\n * 1. Global config: ~/.panopticon/config.yaml\n * 2. Per-project config: .pan.yaml (project root, falls back to .panopticon.yaml with deprecation warning)\n *\n * Uses smart (capability-based) model selection - no legacy presets.\n */\n\nimport { readFileSync, existsSync, writeFileSync, copyFileSync } from 'fs';\nimport { join } from 'path';\nimport { homedir } from 'os';\nimport yaml from 'js-yaml';\nimport { WorkTypeId } from './work-types.js';\nimport { ModelId } from './settings.js';\nimport { ModelProvider } from './model-fallback.js';\nimport { MODEL_DEPRECATIONS, resolveModelId } from './model-capabilities.js';\n\n/**\n * Provider configuration (enable/disable + API keys)\n */\nexport interface ProviderConfig {\n /** Whether this provider is enabled */\n enabled: boolean;\n /** API key (optional, can use env var) */\n api_key?: string;\n}\n\n/**\n * Shadow mode configuration\n */\nexport interface ShadowConfig {\n /** Global shadow mode default */\n enabled?: boolean;\n\n /** Per-tracker overrides */\n trackers?: {\n linear?: boolean;\n github?: boolean;\n gitlab?: boolean;\n rally?: boolean;\n };\n}\n\n/**\n * Complete configuration structure (YAML schema)\n */\nexport interface YamlConfig {\n /** Model configuration */\n models?: {\n /** Provider enable/disable and API keys */\n providers?: {\n anthropic?: ProviderConfig | boolean;\n openai?: ProviderConfig | boolean;\n google?: ProviderConfig | boolean;\n zai?: ProviderConfig | boolean;\n kimi?: ProviderConfig | boolean;\n minimax?: ProviderConfig | boolean;\n openrouter?: ProviderConfig | boolean;\n };\n\n /** Per-work-type overrides (explicit model for specific tasks) */\n overrides?: Partial<Record<WorkTypeId, ModelId>>;\n\n /** Gemini thinking level (1-4) */\n gemini_thinking_level?: 1 | 2 | 3 | 4;\n };\n\n /** OpenRouter-specific configuration */\n openrouter?: {\n /** Favorite model IDs to show in ModelPicker */\n favorites?: string[];\n };\n\n /** Legacy API keys (for backward compatibility) */\n api_keys?: {\n openai?: string;\n google?: string;\n zai?: string;\n kimi?: string;\n minimax?: string;\n openrouter?: string;\n };\n\n /** Tracker API keys (override environment variables) */\n tracker_keys?: {\n linear?: string;\n github?: string;\n gitlab?: string;\n rally?: string;\n };\n\n /** Shadow mode configuration */\n shadow?: ShadowConfig;\n\n /** Multi-tool sync configuration */\n tools?: {\n /**\n * Additional AI tools to sync skills to.\n * Supported: 'cursor' | 'codex' | 'windsurf' | 'cline' | 'copilot' | 'aider'\n * Per-project .pan.yaml values merge additively with global config.\n */\n also_sync?: string[];\n };\n}\n\n/**\n * Normalized shadow configuration\n */\nexport interface NormalizedShadowConfig {\n /** Global shadow mode enabled */\n enabled: boolean;\n\n /** Per-tracker overrides */\n trackers: {\n linear: boolean;\n github: boolean;\n gitlab: boolean;\n rally: boolean;\n };\n}\n\n/**\n * Normalized configuration (after loading and merging)\n */\nexport interface NormalizedConfig {\n /** Enabled providers */\n enabledProviders: Set<ModelProvider>;\n\n /** API keys by provider */\n apiKeys: {\n openai?: string;\n google?: string;\n zai?: string;\n kimi?: string;\n minimax?: string;\n openrouter?: string;\n };\n\n /** OpenRouter favorite model IDs (shown in ModelPicker) */\n openrouterFavorites: string[];\n\n /** Per-work-type overrides */\n overrides: Partial<Record<WorkTypeId, ModelId>>;\n\n /** Gemini thinking level */\n geminiThinkingLevel: 1 | 2 | 3 | 4;\n\n /** Tracker API keys */\n trackerKeys: {\n linear?: string;\n github?: string;\n gitlab?: string;\n rally?: string;\n };\n\n /** Shadow mode configuration */\n shadow: NormalizedShadowConfig;\n}\n\n/**\n * Model ID migration result\n *\n * Returned when deprecated model IDs are automatically migrated\n * during config load.\n */\nexport interface MigrationResult {\n /** List of migrated model IDs */\n migrated: Array<{\n /** Work type that was migrated */\n workType: WorkTypeId;\n /** Old (deprecated) model ID */\n from: string;\n /** New (current) model ID */\n to: string;\n }>;\n /** Whether config.yaml was backed up before migration */\n backedUp: boolean;\n}\n\n/**\n * Config load result (config + optional migration info)\n */\nexport interface ConfigLoadResult {\n /** Normalized configuration */\n config: NormalizedConfig;\n /** Migration result (if any deprecated models were migrated) */\n migration?: MigrationResult;\n}\n\n/**\n * Default configuration (used when no config files exist)\n */\nconst DEFAULT_CONFIG: NormalizedConfig = {\n enabledProviders: new Set(['anthropic']), // Only Anthropic by default\n apiKeys: {},\n openrouterFavorites: [],\n overrides: {},\n geminiThinkingLevel: 3,\n trackerKeys: {},\n shadow: {\n enabled: false,\n trackers: {\n linear: false,\n github: false,\n gitlab: false,\n rally: false,\n },\n },\n};\n\n/**\n * Path to global config file\n */\nconst GLOBAL_CONFIG_PATH = join(homedir(), '.panopticon', 'config.yaml');\n\n/**\n * Normalize a provider config (handle both boolean and object forms)\n */\nfunction normalizeProviderConfig(\n providerConfig: ProviderConfig | boolean | undefined,\n fallbackKey?: string\n): { enabled: boolean; api_key?: string } {\n if (providerConfig === undefined) {\n return { enabled: false };\n }\n\n if (typeof providerConfig === 'boolean') {\n return { enabled: providerConfig, api_key: fallbackKey };\n }\n\n return {\n enabled: providerConfig.enabled,\n api_key: providerConfig.api_key || fallbackKey,\n };\n}\n\n/**\n * Resolve environment variables in config values.\n * If the env var is not set, returns the original reference (e.g., \"$OPENAI_API_KEY\")\n * so the UI can show that it's configured via env var but not resolved.\n */\nfunction resolveEnvVar(value: string | undefined): string | undefined {\n if (!value) return undefined;\n\n // Replace $VAR_NAME or ${VAR_NAME} with environment variable\n // If env var is not set, keep the original reference\n return value.replace(/\\$\\{?([A-Z_][A-Z0-9_]*)\\}?/g, (match, varName) => {\n const envValue = process.env[varName];\n return envValue !== undefined ? envValue : match; // Keep $VAR_NAME if not set\n });\n}\n\n/**\n * Load and parse a YAML config file\n */\nfunction loadYamlFile(filePath: string): YamlConfig | null {\n if (!existsSync(filePath)) {\n return null;\n }\n\n try {\n const content = readFileSync(filePath, 'utf-8');\n const parsed = yaml.load(content) as YamlConfig;\n return parsed || {};\n } catch (error) {\n console.error(`Error loading YAML config from ${filePath}:`, error);\n return null;\n }\n}\n\n/**\n * Find project root by looking for .git directory\n */\nfunction findProjectRoot(startDir: string = process.cwd()): string | null {\n let currentDir = startDir;\n\n while (currentDir !== '/') {\n if (existsSync(join(currentDir, '.git'))) {\n return currentDir;\n }\n currentDir = join(currentDir, '..');\n }\n\n return null;\n}\n\n/**\n * Load per-project config (.pan.yaml in project root, with fallback to .panopticon.yaml)\n */\nfunction loadProjectConfig(): YamlConfig | null {\n const projectRoot = findProjectRoot();\n if (!projectRoot) {\n return null;\n }\n\n const newConfigPath = join(projectRoot, '.pan.yaml');\n if (existsSync(newConfigPath)) {\n return loadYamlFile(newConfigPath);\n }\n\n const legacyConfigPath = join(projectRoot, '.panopticon.yaml');\n if (existsSync(legacyConfigPath)) {\n process.stderr.write(\n `[panopticon] Deprecation warning: .panopticon.yaml is deprecated. Rename it to .pan.yaml.\\n`\n );\n return loadYamlFile(legacyConfigPath);\n }\n\n return null;\n}\n\n/**\n * Load global config (~/.panopticon/config.yaml)\n */\nfunction loadGlobalConfig(): YamlConfig | null {\n return loadYamlFile(GLOBAL_CONFIG_PATH);\n}\n\n/**\n * Merge shadow configuration from multiple sources\n */\nfunction mergeShadowConfig(\n result: NormalizedShadowConfig,\n config: YamlConfig | null\n): void {\n if (!config?.shadow) return;\n\n // Merge global enabled flag\n if (config.shadow.enabled !== undefined) {\n result.enabled = config.shadow.enabled;\n }\n\n // Merge per-tracker overrides\n if (config.shadow.trackers) {\n if (config.shadow.trackers.linear !== undefined) {\n result.trackers.linear = config.shadow.trackers.linear;\n }\n if (config.shadow.trackers.github !== undefined) {\n result.trackers.github = config.shadow.trackers.github;\n }\n if (config.shadow.trackers.gitlab !== undefined) {\n result.trackers.gitlab = config.shadow.trackers.gitlab;\n }\n if (config.shadow.trackers.rally !== undefined) {\n result.trackers.rally = config.shadow.trackers.rally;\n }\n }\n}\n\n/**\n * Merge multiple configs with precedence: project > global > defaults\n */\nfunction mergeConfigs(...configs: (YamlConfig | null)[]): NormalizedConfig {\n const result: NormalizedConfig = {\n ...DEFAULT_CONFIG,\n enabledProviders: new Set(DEFAULT_CONFIG.enabledProviders),\n shadow: {\n enabled: DEFAULT_CONFIG.shadow.enabled,\n trackers: { ...DEFAULT_CONFIG.shadow.trackers },\n },\n };\n\n // Filter out null configs\n const validConfigs = configs.filter((c): c is YamlConfig => c !== null);\n\n // Merge in reverse order (lowest precedence first)\n for (const config of validConfigs.reverse()) {\n // Merge providers\n if (config.models?.providers) {\n const providers = config.models.providers;\n const legacyKeys = config.api_keys || {};\n\n // Anthropic\n const anthropic = normalizeProviderConfig(providers.anthropic);\n if (anthropic.enabled) {\n result.enabledProviders.add('anthropic');\n }\n\n // OpenAI\n const openai = normalizeProviderConfig(providers.openai, legacyKeys.openai);\n if (openai.enabled) {\n result.enabledProviders.add('openai');\n if (openai.api_key) {\n result.apiKeys.openai = resolveEnvVar(openai.api_key);\n }\n }\n\n // Google\n const google = normalizeProviderConfig(providers.google, legacyKeys.google);\n if (google.enabled) {\n result.enabledProviders.add('google');\n if (google.api_key) {\n result.apiKeys.google = resolveEnvVar(google.api_key);\n }\n }\n\n // Z.AI\n const zai = normalizeProviderConfig(providers.zai, legacyKeys.zai);\n if (zai.enabled) {\n result.enabledProviders.add('zai');\n if (zai.api_key) {\n result.apiKeys.zai = resolveEnvVar(zai.api_key);\n }\n }\n\n // Kimi\n const kimi = normalizeProviderConfig(providers.kimi, legacyKeys.kimi);\n if (kimi.enabled) {\n result.enabledProviders.add('kimi');\n if (kimi.api_key) {\n result.apiKeys.kimi = resolveEnvVar(kimi.api_key);\n }\n }\n\n // MiniMax\n const minimax = normalizeProviderConfig(providers.minimax, legacyKeys.minimax);\n if (minimax.enabled) {\n result.enabledProviders.add('minimax');\n if (minimax.api_key) {\n result.apiKeys.minimax = resolveEnvVar(minimax.api_key);\n }\n }\n\n // OpenRouter\n const openrouter = normalizeProviderConfig(providers.openrouter);\n if (openrouter.enabled) {\n result.enabledProviders.add('openrouter');\n if (openrouter.api_key) {\n result.apiKeys.openrouter = resolveEnvVar(openrouter.api_key);\n }\n }\n }\n\n // Merge OpenRouter favorites\n if (config.openrouter?.favorites) {\n result.openrouterFavorites = config.openrouter.favorites;\n }\n\n // Merge legacy API keys (for backward compatibility)\n // If a `models.providers` section exists, the enabled state is already set above — don't\n // override it here. Only auto-enable from API keys when there's no explicit providers config.\n if (config.api_keys) {\n const hasProvidersConfig = !!config.models?.providers;\n if (config.api_keys.openai) {\n result.apiKeys.openai = resolveEnvVar(config.api_keys.openai);\n if (!hasProvidersConfig) result.enabledProviders.add('openai');\n }\n if (config.api_keys.google) {\n result.apiKeys.google = resolveEnvVar(config.api_keys.google);\n if (!hasProvidersConfig) result.enabledProviders.add('google');\n }\n if (config.api_keys.zai) {\n result.apiKeys.zai = resolveEnvVar(config.api_keys.zai);\n if (!hasProvidersConfig) result.enabledProviders.add('zai');\n }\n if (config.api_keys.kimi) {\n result.apiKeys.kimi = resolveEnvVar(config.api_keys.kimi);\n if (!hasProvidersConfig) result.enabledProviders.add('kimi');\n }\n if (config.api_keys.minimax) {\n result.apiKeys.minimax = resolveEnvVar(config.api_keys.minimax);\n if (!hasProvidersConfig) result.enabledProviders.add('minimax');\n }\n if (config.api_keys.openrouter) {\n result.apiKeys.openrouter = resolveEnvVar(config.api_keys.openrouter);\n if (!hasProvidersConfig) result.enabledProviders.add('openrouter');\n }\n }\n\n // Merge overrides\n if (config.models?.overrides) {\n result.overrides = {\n ...result.overrides,\n ...config.models.overrides,\n };\n }\n\n // Merge Gemini thinking level\n if (config.models?.gemini_thinking_level) {\n result.geminiThinkingLevel = config.models.gemini_thinking_level;\n }\n\n // Merge tracker keys\n if (config.tracker_keys) {\n if (config.tracker_keys.linear) {\n result.trackerKeys.linear = resolveEnvVar(config.tracker_keys.linear);\n }\n if (config.tracker_keys.github) {\n result.trackerKeys.github = resolveEnvVar(config.tracker_keys.github);\n }\n if (config.tracker_keys.gitlab) {\n result.trackerKeys.gitlab = resolveEnvVar(config.tracker_keys.gitlab);\n }\n if (config.tracker_keys.rally) {\n result.trackerKeys.rally = resolveEnvVar(config.tracker_keys.rally);\n }\n }\n\n // Merge shadow configuration\n mergeShadowConfig(result.shadow, config);\n }\n\n return result;\n}\n\n/**\n * Detect deprecated model IDs in config overrides\n *\n * Returns array of migrations to perform, or empty array if none found.\n */\nfunction detectDeprecatedModels(config: YamlConfig | null): Array<{\n workType: WorkTypeId;\n from: string;\n to: string;\n}> {\n if (!config?.models?.overrides) {\n return [];\n }\n\n const migrations: Array<{ workType: WorkTypeId; from: string; to: string }> = [];\n\n for (const [workType, modelId] of Object.entries(config.models.overrides)) {\n if (modelId && MODEL_DEPRECATIONS[modelId]) {\n migrations.push({\n workType: workType as WorkTypeId,\n from: modelId,\n to: MODEL_DEPRECATIONS[modelId],\n });\n }\n }\n\n return migrations;\n}\n\n/**\n * Apply deprecation migrations to a YamlConfig (in-place)\n */\nfunction applyMigrations(\n config: YamlConfig,\n migrations: Array<{ workType: WorkTypeId; from: string; to: string }>\n): void {\n if (!config.models) {\n config.models = {};\n }\n if (!config.models.overrides) {\n config.models.overrides = {};\n }\n\n for (const { workType, to } of migrations) {\n config.models.overrides[workType] = to as ModelId;\n }\n}\n\n/**\n * Create backup of global config file\n */\nfunction backupGlobalConfig(): boolean {\n try {\n const backupPath = `${GLOBAL_CONFIG_PATH}.bak`;\n copyFileSync(GLOBAL_CONFIG_PATH, backupPath);\n console.log(`✓ Backed up config.yaml → config.yaml.bak`);\n return true;\n } catch (error) {\n console.error(`Failed to create config backup:`, error);\n return false;\n }\n}\n\n/**\n * Write YamlConfig back to global config file\n */\nfunction writeGlobalConfig(config: YamlConfig): void {\n const yamlContent = yaml.dump(config, {\n indent: 2,\n lineWidth: 100,\n noRefs: true,\n });\n\n writeFileSync(GLOBAL_CONFIG_PATH, yamlContent, 'utf-8');\n}\n\n/**\n * Load complete configuration (global + project + defaults)\n * Also loads API keys from environment variables as fallback\n *\n * IMPORTANT: This function may modify config.yaml if deprecated model IDs\n * are detected. A backup is created before any modifications.\n */\nexport function loadConfig(): ConfigLoadResult {\n let globalConfig = loadGlobalConfig();\n const projectConfig = loadProjectConfig();\n\n // Check for deprecated models in global config\n let migrationResult: MigrationResult | undefined;\n if (globalConfig && hasGlobalConfig()) {\n const migrations = detectDeprecatedModels(globalConfig);\n\n if (migrations.length > 0) {\n // Create backup\n const backedUp = backupGlobalConfig();\n\n // Apply migrations to global config\n applyMigrations(globalConfig, migrations);\n\n // Write migrated config back to disk\n writeGlobalConfig(globalConfig);\n\n // Log migrations\n console.log('\\n🔄 Model ID Migration:');\n for (const { workType, from, to } of migrations) {\n console.log(` ${workType}: ${from} → ${to}`);\n }\n console.log('');\n\n migrationResult = { migrated: migrations, backedUp };\n }\n }\n\n const config = mergeConfigs(projectConfig, globalConfig);\n\n // Load API keys from environment variables as fallback\n // This allows using ~/.panopticon.env for API keys\n if (process.env.OPENAI_API_KEY && !config.apiKeys.openai) {\n config.apiKeys.openai = process.env.OPENAI_API_KEY;\n config.enabledProviders.add('openai');\n }\n if (process.env.GOOGLE_API_KEY && !config.apiKeys.google) {\n config.apiKeys.google = process.env.GOOGLE_API_KEY;\n config.enabledProviders.add('google');\n }\n if (process.env.ZAI_API_KEY && !config.apiKeys.zai) {\n config.apiKeys.zai = process.env.ZAI_API_KEY;\n config.enabledProviders.add('zai');\n }\n if (process.env.KIMI_API_KEY && !config.apiKeys.kimi) {\n config.apiKeys.kimi = process.env.KIMI_API_KEY;\n config.enabledProviders.add('kimi');\n }\n if (process.env.OPENROUTER_API_KEY && !config.apiKeys.openrouter) {\n config.apiKeys.openrouter = process.env.OPENROUTER_API_KEY;\n config.enabledProviders.add('openrouter');\n }\n\n // Load tracker API keys from environment variables as fallback\n if (process.env.LINEAR_API_KEY && !config.trackerKeys.linear) {\n config.trackerKeys.linear = process.env.LINEAR_API_KEY;\n }\n if (process.env.GITHUB_TOKEN && !config.trackerKeys.github) {\n config.trackerKeys.github = process.env.GITHUB_TOKEN;\n }\n if (process.env.GITLAB_TOKEN && !config.trackerKeys.gitlab) {\n config.trackerKeys.gitlab = process.env.GITLAB_TOKEN;\n }\n if (process.env.RALLY_API_KEY && !config.trackerKeys.rally) {\n config.trackerKeys.rally = process.env.RALLY_API_KEY;\n }\n\n // Load shadow mode from environment as fallback\n // Environment variable takes precedence over config file\n if (process.env.SHADOW_MODE !== undefined) {\n const envShadowMode = ['true', '1', 'yes'].includes(process.env.SHADOW_MODE.toLowerCase());\n config.shadow.enabled = envShadowMode;\n }\n\n return { config, migration: migrationResult };\n}\n\n/**\n * Check if a project-level config exists (.pan.yaml or .panopticon.yaml)\n */\nexport function hasProjectConfig(): boolean {\n const projectRoot = findProjectRoot();\n if (!projectRoot) return false;\n return existsSync(join(projectRoot, '.pan.yaml')) || existsSync(join(projectRoot, '.panopticon.yaml'));\n}\n\n/**\n * Check if global config exists\n */\nexport function hasGlobalConfig(): boolean {\n return existsSync(GLOBAL_CONFIG_PATH);\n}\n\n/**\n * Get path to global config file\n */\nexport function getGlobalConfigPath(): string {\n return GLOBAL_CONFIG_PATH;\n}\n\n/**\n * Get path to project config file (null if not in a project).\n * Returns .pan.yaml if it exists, falls back to .panopticon.yaml, otherwise returns .pan.yaml as default.\n */\nexport function getProjectConfigPath(): string | null {\n const projectRoot = findProjectRoot();\n if (!projectRoot) return null;\n if (existsSync(join(projectRoot, '.pan.yaml'))) {\n return join(projectRoot, '.pan.yaml');\n }\n if (existsSync(join(projectRoot, '.panopticon.yaml'))) {\n return join(projectRoot, '.panopticon.yaml');\n }\n return join(projectRoot, '.pan.yaml');\n}\n"],"mappings":";;;;;;;;;AAwgBA,SAAgB,mBAAmB,OAAiC;AAClE,QAAO,mBAAmB;;;;AA1ef,sBAA8C;EACzD,mBAAmB;EACnB,qBAAqB;EACtB;AA6DY,sBAAuD;EAKlE,mBAAmB;GACjB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,qBAAqB;GACnB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,qBAAqB;GACnB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,oBAAoB;GAClB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAMD,iBAAiB;GACf,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,oBAAoB;GAClB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,UAAU;GACR,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,eAAe;GACb,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAMD,wBAAwB;GACtB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,0BAA0B;GACxB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,kBAAkB;GAChB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,oBAAoB;GAClB,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAMD,WAAW;GACT,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,iBAAiB;GACf,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAMD,WAAW;GACT,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAED,aAAa;GACX,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IACX,UAAU;IACV,eAAe;IACf,SAAS;IACT,UAAU;IACV,aAAa;IACb,WAAW;IACX,OAAO;IACP,kBAAkB;IACnB;GACD,OAAO;GACR;EAMD,gBAAgB;GACd,OAAO;GACP,UAAU;GACV,aAAa;GACb,iBAAiB;GACjB,eAAe;GACf,QAAQ;IACN,mBAAmB;IACnB,eAAe;IACf,WAAW;IA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"}