@danya-ai/cli 0.1.0

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 (184) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +336 -0
  3. package/cli-acp.js +82 -0
  4. package/cli.js +105 -0
  5. package/dist/REPL-EYUOXCEC.js +42 -0
  6. package/dist/REPL-EYUOXCEC.js.map +7 -0
  7. package/dist/acp-S5WNCLMD.js +1372 -0
  8. package/dist/acp-S5WNCLMD.js.map +7 -0
  9. package/dist/agentsValidate-RQ2QDGNY.js +373 -0
  10. package/dist/agentsValidate-RQ2QDGNY.js.map +7 -0
  11. package/dist/ask-TX526UBD.js +129 -0
  12. package/dist/ask-TX526UBD.js.map +7 -0
  13. package/dist/autoUpdater-63RAZ24N.js +17 -0
  14. package/dist/autoUpdater-63RAZ24N.js.map +7 -0
  15. package/dist/chunk-2VQWLLDU.js +16 -0
  16. package/dist/chunk-2VQWLLDU.js.map +7 -0
  17. package/dist/chunk-4CLHMO4I.js +656 -0
  18. package/dist/chunk-4CLHMO4I.js.map +7 -0
  19. package/dist/chunk-4ZNNWJZU.js +5696 -0
  20. package/dist/chunk-4ZNNWJZU.js.map +7 -0
  21. package/dist/chunk-66EZC7Y7.js +149 -0
  22. package/dist/chunk-66EZC7Y7.js.map +7 -0
  23. package/dist/chunk-6EPQRP3S.js +96 -0
  24. package/dist/chunk-6EPQRP3S.js.map +7 -0
  25. package/dist/chunk-77IRSDFR.js +195 -0
  26. package/dist/chunk-77IRSDFR.js.map +7 -0
  27. package/dist/chunk-7RZNLBEK.js +136 -0
  28. package/dist/chunk-7RZNLBEK.js.map +7 -0
  29. package/dist/chunk-BNBV2FXC.js +19 -0
  30. package/dist/chunk-BNBV2FXC.js.map +7 -0
  31. package/dist/chunk-CQCREBDO.js +248 -0
  32. package/dist/chunk-CQCREBDO.js.map +7 -0
  33. package/dist/chunk-D77XS6TB.js +74 -0
  34. package/dist/chunk-D77XS6TB.js.map +7 -0
  35. package/dist/chunk-DHYBJN3V.js +474 -0
  36. package/dist/chunk-DHYBJN3V.js.map +7 -0
  37. package/dist/chunk-DLSLSLTR.js +842 -0
  38. package/dist/chunk-DLSLSLTR.js.map +7 -0
  39. package/dist/chunk-ELAE6Z4H.js +514 -0
  40. package/dist/chunk-ELAE6Z4H.js.map +7 -0
  41. package/dist/chunk-ELZQD7ZR.js +531 -0
  42. package/dist/chunk-ELZQD7ZR.js.map +7 -0
  43. package/dist/chunk-F6DEGMX6.js +31269 -0
  44. package/dist/chunk-F6DEGMX6.js.map +7 -0
  45. package/dist/chunk-GDF2AON2.js +124 -0
  46. package/dist/chunk-GDF2AON2.js.map +7 -0
  47. package/dist/chunk-H7BGBV4P.js +498 -0
  48. package/dist/chunk-H7BGBV4P.js.map +7 -0
  49. package/dist/chunk-HIIHGKXP.js +24 -0
  50. package/dist/chunk-HIIHGKXP.js.map +7 -0
  51. package/dist/chunk-HJCCXED7.js +17 -0
  52. package/dist/chunk-HJCCXED7.js.map +7 -0
  53. package/dist/chunk-IQ6VZB2Y.js +139 -0
  54. package/dist/chunk-IQ6VZB2Y.js.map +7 -0
  55. package/dist/chunk-J4D7AELD.js +518 -0
  56. package/dist/chunk-J4D7AELD.js.map +7 -0
  57. package/dist/chunk-JVGG2YQR.js +23 -0
  58. package/dist/chunk-JVGG2YQR.js.map +7 -0
  59. package/dist/chunk-LGEK2NV7.js +939 -0
  60. package/dist/chunk-LGEK2NV7.js.map +7 -0
  61. package/dist/chunk-LWXT5RGE.js +95 -0
  62. package/dist/chunk-LWXT5RGE.js.map +7 -0
  63. package/dist/chunk-M3TKNAUR.js +35 -0
  64. package/dist/chunk-M3TKNAUR.js.map +7 -0
  65. package/dist/chunk-MRFO7QO5.js +170 -0
  66. package/dist/chunk-MRFO7QO5.js.map +7 -0
  67. package/dist/chunk-MVN3DHQF.js +95 -0
  68. package/dist/chunk-MVN3DHQF.js.map +7 -0
  69. package/dist/chunk-O25PXGOC.js +772 -0
  70. package/dist/chunk-O25PXGOC.js.map +7 -0
  71. package/dist/chunk-OBGVKM3N.js +1618 -0
  72. package/dist/chunk-OBGVKM3N.js.map +7 -0
  73. package/dist/chunk-OV5HJXXQ.js +198 -0
  74. package/dist/chunk-OV5HJXXQ.js.map +7 -0
  75. package/dist/chunk-P5VWDMRD.js +249 -0
  76. package/dist/chunk-P5VWDMRD.js.map +7 -0
  77. package/dist/chunk-PDSAJX7G.js +49 -0
  78. package/dist/chunk-PDSAJX7G.js.map +7 -0
  79. package/dist/chunk-RHNEZOPO.js +739 -0
  80. package/dist/chunk-RHNEZOPO.js.map +7 -0
  81. package/dist/chunk-SQGAHZPM.js +3004 -0
  82. package/dist/chunk-SQGAHZPM.js.map +7 -0
  83. package/dist/chunk-U7Z4MXY4.js +21 -0
  84. package/dist/chunk-U7Z4MXY4.js.map +7 -0
  85. package/dist/chunk-UNCTVIS7.js +146 -0
  86. package/dist/chunk-UNCTVIS7.js.map +7 -0
  87. package/dist/chunk-VMEOI6MH.js +1103 -0
  88. package/dist/chunk-VMEOI6MH.js.map +7 -0
  89. package/dist/chunk-WAY3DKFO.js +47 -0
  90. package/dist/chunk-WAY3DKFO.js.map +7 -0
  91. package/dist/chunk-XEYEKVFT.js +24 -0
  92. package/dist/chunk-XEYEKVFT.js.map +7 -0
  93. package/dist/chunk-Y4BQ36T4.js +796 -0
  94. package/dist/chunk-Y4BQ36T4.js.map +7 -0
  95. package/dist/chunk-Y5LQPJWK.js +12 -0
  96. package/dist/chunk-Y5LQPJWK.js.map +7 -0
  97. package/dist/chunk-YIJWUNWF.js +1260 -0
  98. package/dist/chunk-YIJWUNWF.js.map +7 -0
  99. package/dist/chunk-YMIWYEZ7.js +34 -0
  100. package/dist/chunk-YMIWYEZ7.js.map +7 -0
  101. package/dist/cli-PQNZWJX4.js +3952 -0
  102. package/dist/cli-PQNZWJX4.js.map +7 -0
  103. package/dist/commands-HOBCZ3VQ.js +46 -0
  104. package/dist/commands-HOBCZ3VQ.js.map +7 -0
  105. package/dist/config-MLH7ZTFA.js +81 -0
  106. package/dist/config-MLH7ZTFA.js.map +7 -0
  107. package/dist/context-FZ6G4J63.js +30 -0
  108. package/dist/context-FZ6G4J63.js.map +7 -0
  109. package/dist/costTracker-5WKZXN5S.js +19 -0
  110. package/dist/costTracker-5WKZXN5S.js.map +7 -0
  111. package/dist/customCommands-EB4MMZSS.js +25 -0
  112. package/dist/customCommands-EB4MMZSS.js.map +7 -0
  113. package/dist/env-VMEIP4EW.js +28 -0
  114. package/dist/env-VMEIP4EW.js.map +7 -0
  115. package/dist/index.js +36 -0
  116. package/dist/index.js.map +7 -0
  117. package/dist/kodeAgentSessionId-WUT74FSH.js +16 -0
  118. package/dist/kodeAgentSessionId-WUT74FSH.js.map +7 -0
  119. package/dist/kodeAgentSessionLoad-KR4JSD6D.js +21 -0
  120. package/dist/kodeAgentSessionLoad-KR4JSD6D.js.map +7 -0
  121. package/dist/kodeAgentSessionResume-BCD6UV74.js +18 -0
  122. package/dist/kodeAgentSessionResume-BCD6UV74.js.map +7 -0
  123. package/dist/kodeAgentStreamJson-EDHHWNNX.js +15 -0
  124. package/dist/kodeAgentStreamJson-EDHHWNNX.js.map +7 -0
  125. package/dist/kodeAgentStreamJsonSession-G4RBNZRN.js +133 -0
  126. package/dist/kodeAgentStreamJsonSession-G4RBNZRN.js.map +7 -0
  127. package/dist/kodeAgentStructuredStdio-UA5P5UNU.js +11 -0
  128. package/dist/kodeAgentStructuredStdio-UA5P5UNU.js.map +7 -0
  129. package/dist/kodeHooks-EHM6GSIQ.js +37 -0
  130. package/dist/kodeHooks-EHM6GSIQ.js.map +7 -0
  131. package/dist/llm-SJXCV7DA.js +3138 -0
  132. package/dist/llm-SJXCV7DA.js.map +7 -0
  133. package/dist/llmLazy-2QYJVD6K.js +15 -0
  134. package/dist/llmLazy-2QYJVD6K.js.map +7 -0
  135. package/dist/loader-LJX77EFL.js +28 -0
  136. package/dist/loader-LJX77EFL.js.map +7 -0
  137. package/dist/mcp-DOROSLPN.js +49 -0
  138. package/dist/mcp-DOROSLPN.js.map +7 -0
  139. package/dist/mentionProcessor-5UZRHCGH.js +215 -0
  140. package/dist/mentionProcessor-5UZRHCGH.js.map +7 -0
  141. package/dist/messages-N5KBI53P.js +65 -0
  142. package/dist/messages-N5KBI53P.js.map +7 -0
  143. package/dist/model-HPLBR53R.js +30 -0
  144. package/dist/model-HPLBR53R.js.map +7 -0
  145. package/dist/openai-YP4OJYKF.js +29 -0
  146. package/dist/openai-YP4OJYKF.js.map +7 -0
  147. package/dist/outputStyles-NNALI5D7.js +28 -0
  148. package/dist/outputStyles-NNALI5D7.js.map +7 -0
  149. package/dist/package.json +4 -0
  150. package/dist/pluginRuntime-JYYI5BSQ.js +220 -0
  151. package/dist/pluginRuntime-JYYI5BSQ.js.map +7 -0
  152. package/dist/pluginValidation-JWUFPZUE.js +17 -0
  153. package/dist/pluginValidation-JWUFPZUE.js.map +7 -0
  154. package/dist/prompts-B2SS7CWI.js +50 -0
  155. package/dist/prompts-B2SS7CWI.js.map +7 -0
  156. package/dist/query-HIK457UU.js +50 -0
  157. package/dist/query-HIK457UU.js.map +7 -0
  158. package/dist/responsesStreaming-L2BSN37C.js +10 -0
  159. package/dist/responsesStreaming-L2BSN37C.js.map +7 -0
  160. package/dist/ripgrep-GCKI4UTL.js +17 -0
  161. package/dist/ripgrep-GCKI4UTL.js.map +7 -0
  162. package/dist/skillMarketplace-PCTUUX46.js +37 -0
  163. package/dist/skillMarketplace-PCTUUX46.js.map +7 -0
  164. package/dist/state-XJICGOUA.js +18 -0
  165. package/dist/state-XJICGOUA.js.map +7 -0
  166. package/dist/theme-DP7O4SGH.js +14 -0
  167. package/dist/theme-DP7O4SGH.js.map +7 -0
  168. package/dist/toolPermissionContext-DHAGUPEW.js +17 -0
  169. package/dist/toolPermissionContext-DHAGUPEW.js.map +7 -0
  170. package/dist/toolPermissionSettings-PT65MQIQ.js +18 -0
  171. package/dist/toolPermissionSettings-PT65MQIQ.js.map +7 -0
  172. package/dist/tools-BHW37PCF.js +47 -0
  173. package/dist/tools-BHW37PCF.js.map +7 -0
  174. package/dist/userInput-XDRYT5TI.js +316 -0
  175. package/dist/userInput-XDRYT5TI.js.map +7 -0
  176. package/dist/uuid-QUYJMIUV.js +9 -0
  177. package/dist/uuid-QUYJMIUV.js.map +7 -0
  178. package/dist/yoga.wasm +0 -0
  179. package/package.json +115 -0
  180. package/scripts/binary-utils.cjs +62 -0
  181. package/scripts/cli-acp-wrapper.cjs +82 -0
  182. package/scripts/cli-wrapper.cjs +105 -0
  183. package/scripts/postinstall.js +144 -0
  184. package/yoga.wasm +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/core/config/schema.ts", "../src/core/config/defaults.ts", "../src/core/config/loader.ts", "../src/utils/text/json.ts", "../src/core/config/migrations.ts", "../src/core/config/validator.ts"],
4
+ "sourcesContent": ["import type { ThemeNames } from '@utils/theme'\r\n\r\nexport type McpStdioServerConfig = {\r\n type?: 'stdio'\r\n command: string\r\n args: string[]\r\n env?: Record<string, string>\r\n}\r\n\r\nexport type McpSSEServerConfig = {\r\n type: 'sse'\r\n url: string\r\n headers?: Record<string, string>\r\n headersHelper?: string\r\n}\r\n\r\nexport type McpHttpServerConfig = {\r\n type: 'http'\r\n url: string\r\n headers?: Record<string, string>\r\n headersHelper?: string\r\n}\r\n\r\nexport type McpSSEIdeServerConfig = {\r\n type: 'sse-ide'\r\n url: string\r\n ideName: string\r\n ideRunningInWindows?: boolean\r\n headers?: Record<string, string>\r\n headersHelper?: string\r\n}\r\n\r\nexport type McpWsServerConfig = {\r\n type: 'ws'\r\n url: string\r\n}\r\n\r\nexport type McpWsIdeServerConfig = {\r\n type: 'ws-ide'\r\n url: string\r\n ideName: string\r\n authToken?: string\r\n ideRunningInWindows?: boolean\r\n}\r\n\r\nexport type McpServerConfig =\r\n | McpStdioServerConfig\r\n | McpSSEServerConfig\r\n | McpHttpServerConfig\r\n | McpSSEIdeServerConfig\r\n | McpWsServerConfig\r\n | McpWsIdeServerConfig\r\n\r\nexport type ProjectConfig = {\r\n allowedTools: string[]\r\n deniedTools?: string[]\r\n askedTools?: string[]\r\n context: Record<string, string>\r\n contextFiles?: string[]\r\n history: string[]\r\n dontCrawlDirectory?: boolean\r\n enableArchitectTool?: boolean\r\n mcpContextUris: string[]\r\n mcpServers?: Record<string, McpServerConfig>\r\n approvedMcprcServers?: string[]\r\n rejectedMcprcServers?: string[]\r\n lastAPIDuration?: number\r\n lastCost?: number\r\n lastDuration?: number\r\n lastSessionId?: string\r\n exampleFiles?: string[]\r\n exampleFilesGeneratedAt?: number\r\n hasTrustDialogAccepted?: boolean\r\n hasCompletedProjectOnboarding?: boolean\r\n}\r\n\r\nexport type AutoUpdaterStatus =\r\n | 'disabled'\r\n | 'enabled'\r\n | 'no_permissions'\r\n | 'not_configured'\r\n\r\nexport function isAutoUpdaterStatus(value: string): value is AutoUpdaterStatus {\r\n return ['disabled', 'enabled', 'no_permissions', 'not_configured'].includes(\r\n value as AutoUpdaterStatus,\r\n )\r\n}\r\n\r\nexport type NotificationChannel =\r\n | 'iterm2'\r\n | 'terminal_bell'\r\n | 'iterm2_with_bell'\r\n | 'notifications_disabled'\r\n\r\nexport type ProviderType =\r\n | 'anthropic'\r\n | 'openai'\r\n | 'mistral'\r\n | 'deepseek'\r\n | 'kimi'\r\n | 'qwen'\r\n | 'glm'\r\n | 'minimax'\r\n | 'baidu-qianfan'\r\n | 'siliconflow'\r\n | 'bigdream'\r\n | 'opendev'\r\n | 'xai'\r\n | 'groq'\r\n | 'gemini'\r\n | 'ollama'\r\n | 'azure'\r\n | 'custom'\r\n | 'custom-openai'\r\n | (string & {})\r\n\r\nexport type ModelProfile = {\r\n name: string\r\n provider: ProviderType\r\n modelName: string\r\n baseURL?: string\r\n apiKey: string\r\n maxTokens: number\r\n contextLength: number\r\n reasoningEffort?: 'low' | 'medium' | 'high' | 'minimal' | string\r\n isActive: boolean\r\n createdAt: number\r\n lastUsed?: number\r\n isGPT5?: boolean\r\n validationStatus?: 'valid' | 'needs_repair' | 'auto_repaired'\r\n lastValidation?: number\r\n}\r\n\r\nexport type ModelPointerType = 'main' | 'task' | 'compact' | 'quick'\r\n\r\nexport type ModelPointers = {\r\n main: string\r\n task: string\r\n compact: string\r\n quick: string\r\n}\r\n\r\nexport type AccountInfo = {\r\n accountUuid: string\r\n emailAddress: string\r\n organizationUuid?: string\r\n}\r\n\r\nexport type GlobalConfig = {\r\n projects?: Record<string, ProjectConfig>\r\n numStartups: number\r\n autoUpdaterStatus?: AutoUpdaterStatus\r\n userID?: string\r\n theme: ThemeNames\r\n hasCompletedOnboarding?: boolean\r\n lastPlanModeUse?: number\r\n lastOnboardingVersion?: string\r\n lastReleaseNotesSeen?: string\r\n mcpServers?: Record<string, McpServerConfig>\r\n preferredNotifChannel: NotificationChannel\r\n verbose: boolean\r\n customApiKeyResponses?: {\r\n approved?: string[]\r\n rejected?: string[]\r\n }\r\n primaryProvider?: ProviderType\r\n maxTokens?: number\r\n autoCompactThreshold?: number\r\n hasAcknowledgedCostThreshold?: boolean\r\n oauthAccount?: AccountInfo\r\n proxy?: string\r\n stream?: boolean\r\n\r\n modelProfiles?: ModelProfile[]\r\n modelPointers?: ModelPointers\r\n defaultModelName?: string\r\n lastDismissedUpdateVersion?: string\r\n}\r\n\r\nexport const GLOBAL_CONFIG_KEYS = [\r\n 'autoUpdaterStatus',\r\n 'theme',\r\n 'hasCompletedOnboarding',\r\n 'lastOnboardingVersion',\r\n 'lastReleaseNotesSeen',\r\n 'verbose',\r\n 'customApiKeyResponses',\r\n 'primaryProvider',\r\n 'preferredNotifChannel',\r\n 'maxTokens',\r\n 'autoCompactThreshold',\r\n] as const\r\n\r\nexport type GlobalConfigKey = (typeof GLOBAL_CONFIG_KEYS)[number]\r\n\r\nexport function isGlobalConfigKey(key: string): key is GlobalConfigKey {\r\n return GLOBAL_CONFIG_KEYS.includes(key as GlobalConfigKey)\r\n}\r\n\r\nexport const PROJECT_CONFIG_KEYS = [\r\n 'dontCrawlDirectory',\r\n 'enableArchitectTool',\r\n 'hasTrustDialogAccepted',\r\n 'hasCompletedProjectOnboarding',\r\n] as const\r\n\r\nexport type ProjectConfigKey = (typeof PROJECT_CONFIG_KEYS)[number]\r\n\r\nexport function isProjectConfigKey(key: string): key is ProjectConfigKey {\r\n return PROJECT_CONFIG_KEYS.includes(key as ProjectConfigKey)\r\n}\r\n\r\nexport type ProjectMcpServerDefinitions = {\r\n servers: Record<string, McpServerConfig>\r\n sources: Record<string, '.mcp.json' | '.mcprc'>\r\n mcpJsonPath: string\r\n mcprcPath: string\r\n}\r\n", "import { homedir } from 'os'\r\nimport type { GlobalConfig, ProjectConfig, ProviderType } from './schema'\r\nimport type { ThemeNames } from '@utils/theme'\r\n\r\nexport const DEFAULT_PROJECT_CONFIG: ProjectConfig = {\r\n allowedTools: [],\r\n deniedTools: [],\r\n askedTools: [],\r\n context: {},\r\n history: [],\r\n dontCrawlDirectory: false,\r\n enableArchitectTool: false,\r\n mcpContextUris: [],\r\n mcpServers: {},\r\n approvedMcprcServers: [],\r\n rejectedMcprcServers: [],\r\n hasTrustDialogAccepted: false,\r\n}\r\n\r\nexport function defaultConfigForProject(projectPath: string): ProjectConfig {\r\n const config = { ...DEFAULT_PROJECT_CONFIG }\r\n if (projectPath === homedir()) {\r\n config.dontCrawlDirectory = true\r\n }\r\n return config\r\n}\r\n\r\nexport const DEFAULT_GLOBAL_CONFIG: GlobalConfig = {\r\n numStartups: 0,\r\n autoUpdaterStatus: 'not_configured',\r\n theme: 'dark' as ThemeNames,\r\n preferredNotifChannel: 'iterm2',\r\n verbose: false,\r\n primaryProvider: 'anthropic' as ProviderType,\r\n customApiKeyResponses: {\r\n approved: [],\r\n rejected: [],\r\n },\r\n stream: true,\r\n\r\n modelProfiles: [],\r\n modelPointers: {\r\n main: '',\r\n task: '',\r\n compact: '',\r\n quick: '',\r\n },\r\n lastDismissedUpdateVersion: undefined,\r\n}\r\n\r\n", "import { existsSync, readFileSync, writeFileSync } from 'fs'\r\nimport { join, posix, resolve, win32 } from 'path'\r\nimport { cloneDeep, memoize, pick } from 'lodash-es'\r\nimport { homedir } from 'os'\r\nimport { randomBytes } from 'crypto'\r\nimport { getGlobalConfigFilePath } from '@utils/config/env'\r\nimport { getCwd } from '@utils/state'\r\nimport { safeParseJSON } from '@utils/text/json'\r\nimport { ConfigParseError } from '@utils/text/errors'\r\nimport { debug as debugLogger } from '@utils/log/debugLogger'\r\nimport {\r\n DEFAULT_GLOBAL_CONFIG,\r\n DEFAULT_PROJECT_CONFIG,\r\n defaultConfigForProject,\r\n} from './defaults'\r\nimport {\r\n GLOBAL_CONFIG_KEYS,\r\n PROJECT_CONFIG_KEYS,\r\n isGlobalConfigKey,\r\n isAutoUpdaterStatus,\r\n isProjectConfigKey,\r\n type GlobalConfig,\r\n type McpServerConfig,\r\n type ProjectConfig,\r\n type ProjectMcpServerDefinitions,\r\n} from './schema'\r\nimport { migrateModelProfilesRemoveId } from './migrations'\r\n\r\nfunction expandHomeDirForPlatform(\r\n input: string,\r\n homeDirPath: string,\r\n platform: NodeJS.Platform,\r\n): string {\r\n const trimmed = input.trim()\r\n if (!trimmed) return trimmed\r\n if (trimmed === '~') return homeDirPath\r\n if (trimmed.startsWith('~/') || trimmed.startsWith('~\\\\')) {\r\n const rest = trimmed.slice(2)\r\n return platform === 'win32'\r\n ? win32.join(homeDirPath, rest)\r\n : posix.join(homeDirPath, rest)\r\n }\r\n return trimmed\r\n}\r\n\r\nexport function normalizeProjectPathForComparison(\r\n projectPath: string,\r\n baseDir: string,\r\n opts?: { platform?: NodeJS.Platform; homeDir?: string },\r\n): string {\r\n const platform = opts?.platform ?? process.platform\r\n const homeDirPath = opts?.homeDir ?? homedir()\r\n const expanded = expandHomeDirForPlatform(projectPath, homeDirPath, platform)\r\n if (!expanded) return ''\r\n\r\n if (platform === 'win32') {\r\n const resolved = win32.isAbsolute(expanded)\r\n ? win32.resolve(expanded)\r\n : win32.resolve(baseDir, expanded)\r\n return resolved.toLowerCase()\r\n }\r\n\r\n const resolved = posix.isAbsolute(expanded)\r\n ? posix.resolve(expanded)\r\n : posix.resolve(baseDir, expanded)\r\n return resolved\r\n}\r\n\r\nfunction findMatchingProjectKey(\r\n projects: Record<string, ProjectConfig> | undefined,\r\n absolutePath: string,\r\n): string | undefined {\r\n if (!projects) return undefined\r\n if (projects[absolutePath]) return absolutePath\r\n\r\n const normalizedTarget = normalizeProjectPathForComparison(\r\n absolutePath,\r\n absolutePath,\r\n )\r\n\r\n for (const key of Object.keys(projects)) {\r\n if (\r\n normalizeProjectPathForComparison(key, absolutePath) === normalizedTarget\r\n ) {\r\n return key\r\n }\r\n }\r\n\r\n return undefined\r\n}\r\n\r\nexport function checkHasTrustDialogAccepted(): boolean {\r\n let currentPath = getCwd()\r\n const config = getConfig(getGlobalConfigFilePath(), DEFAULT_GLOBAL_CONFIG)\r\n\r\n while (true) {\r\n const projectKey = findMatchingProjectKey(config.projects, currentPath)\r\n const projectConfig = projectKey ? config.projects?.[projectKey] : undefined\r\n if (projectConfig?.hasTrustDialogAccepted) {\r\n return true\r\n }\r\n const parentPath = resolve(currentPath, '..')\r\n if (parentPath === currentPath) {\r\n break\r\n }\r\n currentPath = parentPath\r\n }\r\n\r\n return false\r\n}\r\n\r\nconst TEST_GLOBAL_CONFIG_FOR_TESTING: GlobalConfig = {\r\n ...DEFAULT_GLOBAL_CONFIG,\r\n autoUpdaterStatus: 'disabled',\r\n}\r\nconst TEST_PROJECT_CONFIG_FOR_TESTING: ProjectConfig = {\r\n ...DEFAULT_PROJECT_CONFIG,\r\n}\r\n\r\nexport function saveGlobalConfig(config: GlobalConfig): void {\r\n if (process.env.NODE_ENV === 'test') {\r\n for (const key in config) {\r\n TEST_GLOBAL_CONFIG_FOR_TESTING[key] = config[key]\r\n }\r\n return\r\n }\r\n\r\n saveConfig(\r\n getGlobalConfigFilePath(),\r\n {\r\n ...config,\r\n projects: getConfig(getGlobalConfigFilePath(), DEFAULT_GLOBAL_CONFIG)\r\n .projects,\r\n },\r\n DEFAULT_GLOBAL_CONFIG,\r\n )\r\n}\r\n\r\nexport function getGlobalConfig(): GlobalConfig {\r\n if (process.env.NODE_ENV === 'test') {\r\n return TEST_GLOBAL_CONFIG_FOR_TESTING\r\n }\r\n const config = getConfig(getGlobalConfigFilePath(), DEFAULT_GLOBAL_CONFIG)\r\n return migrateModelProfilesRemoveId(config)\r\n}\r\n\r\nexport function normalizeApiKeyForConfig(apiKey: string): string {\r\n return apiKey?.slice(-20) ?? ''\r\n}\r\n\r\nexport function getCustomApiKeyStatus(\r\n truncatedApiKey: string,\r\n): 'approved' | 'rejected' | 'new' {\r\n const config = getGlobalConfig()\r\n if (config.customApiKeyResponses?.approved?.includes(truncatedApiKey)) {\r\n return 'approved'\r\n }\r\n if (config.customApiKeyResponses?.rejected?.includes(truncatedApiKey)) {\r\n return 'rejected'\r\n }\r\n return 'new'\r\n}\r\n\r\nfunction saveConfig<A extends object>(\r\n file: string,\r\n config: A,\r\n defaultConfig: A,\r\n): void {\r\n const filteredConfig = Object.fromEntries(\r\n Object.entries(config).filter(\r\n ([key, value]) =>\r\n JSON.stringify(value) !== JSON.stringify(defaultConfig[key as keyof A]),\r\n ),\r\n )\r\n try {\r\n writeFileSync(file, JSON.stringify(filteredConfig, null, 2), 'utf-8')\r\n } catch (error) {\r\n const err = error as NodeJS.ErrnoException\r\n if (\r\n err?.code === 'EACCES' ||\r\n err?.code === 'EPERM' ||\r\n err?.code === 'EROFS'\r\n ) {\r\n debugLogger.state('CONFIG_SAVE_SKIPPED', {\r\n file,\r\n reason: String(err.code),\r\n })\r\n return\r\n }\r\n throw error\r\n }\r\n}\r\n\r\nlet configReadingAllowed = false\r\n\r\nexport function enableConfigs(): void {\r\n configReadingAllowed = true\r\n getConfig(\r\n getGlobalConfigFilePath(),\r\n DEFAULT_GLOBAL_CONFIG,\r\n true,\r\n )\r\n}\r\n\r\nfunction getConfig<A>(\r\n file: string,\r\n defaultConfig: A,\r\n throwOnInvalid?: boolean,\r\n): A {\r\n void configReadingAllowed\r\n\r\n debugLogger.state('CONFIG_LOAD_START', {\r\n file,\r\n fileExists: String(existsSync(file)),\r\n throwOnInvalid: String(!!throwOnInvalid),\r\n })\r\n\r\n if (!existsSync(file)) {\r\n debugLogger.state('CONFIG_LOAD_DEFAULT', {\r\n file,\r\n reason: 'file_not_exists',\r\n defaultConfigKeys: Object.keys(defaultConfig as object).join(', '),\r\n })\r\n return cloneDeep(defaultConfig)\r\n }\r\n\r\n try {\r\n const fileContent = readFileSync(file, 'utf-8')\r\n debugLogger.state('CONFIG_FILE_READ', {\r\n file,\r\n contentLength: String(fileContent.length),\r\n contentPreview:\r\n fileContent.substring(0, 100) + (fileContent.length > 100 ? '...' : ''),\r\n })\r\n\r\n try {\r\n const parsedConfig = JSON.parse(fileContent)\r\n debugLogger.state('CONFIG_JSON_PARSED', {\r\n file,\r\n parsedKeys: Object.keys(parsedConfig).join(', '),\r\n })\r\n\r\n const finalConfig = {\r\n ...cloneDeep(defaultConfig),\r\n ...parsedConfig,\r\n }\r\n\r\n debugLogger.state('CONFIG_LOAD_SUCCESS', {\r\n file,\r\n finalConfigKeys: Object.keys(finalConfig as object).join(', '),\r\n })\r\n\r\n return finalConfig\r\n } catch (error) {\r\n const errorMessage =\r\n error instanceof Error ? error.message : String(error)\r\n\r\n debugLogger.error('CONFIG_JSON_PARSE_ERROR', {\r\n file,\r\n errorMessage,\r\n errorType: error instanceof Error ? error.constructor.name : typeof error,\r\n contentLength: String(fileContent.length),\r\n })\r\n\r\n throw new ConfigParseError(errorMessage, file, defaultConfig)\r\n }\r\n } catch (error: unknown) {\r\n if (error instanceof ConfigParseError && throwOnInvalid) {\r\n debugLogger.error('CONFIG_PARSE_ERROR_RETHROWN', {\r\n file,\r\n throwOnInvalid: String(throwOnInvalid),\r\n errorMessage: error.message,\r\n })\r\n throw error\r\n }\r\n\r\n debugLogger.warn('CONFIG_FALLBACK_TO_DEFAULT', {\r\n file,\r\n errorType: error instanceof Error ? error.constructor.name : typeof error,\r\n errorMessage: error instanceof Error ? error.message : String(error),\r\n action: 'using_default_config',\r\n })\r\n\r\n return cloneDeep(defaultConfig)\r\n }\r\n}\r\n\r\nexport function getCurrentProjectConfig(): ProjectConfig {\r\n if (process.env.NODE_ENV === 'test') {\r\n return TEST_PROJECT_CONFIG_FOR_TESTING\r\n }\r\n\r\n const absolutePath = resolve(getCwd())\r\n const config = getConfig(getGlobalConfigFilePath(), DEFAULT_GLOBAL_CONFIG)\r\n\r\n if (!config.projects) {\r\n return defaultConfigForProject(absolutePath)\r\n }\r\n\r\n const projectKey = findMatchingProjectKey(config.projects, absolutePath)\r\n const projectConfig =\r\n projectKey && config.projects[projectKey]\r\n ? config.projects[projectKey]\r\n : defaultConfigForProject(absolutePath)\r\n if (typeof projectConfig.allowedTools === 'string') {\r\n projectConfig.allowedTools =\r\n (safeParseJSON(projectConfig.allowedTools) as string[]) ?? []\r\n }\r\n if (typeof (projectConfig as any).deniedTools === 'string') {\r\n ;(projectConfig as any).deniedTools =\r\n (safeParseJSON((projectConfig as any).deniedTools) as string[]) ?? []\r\n }\r\n if (typeof (projectConfig as any).askedTools === 'string') {\r\n ;(projectConfig as any).askedTools =\r\n (safeParseJSON((projectConfig as any).askedTools) as string[]) ?? []\r\n }\r\n return projectConfig\r\n}\r\n\r\nexport function saveCurrentProjectConfig(projectConfig: ProjectConfig): void {\r\n if (process.env.NODE_ENV === 'test') {\r\n for (const key in projectConfig) {\r\n TEST_PROJECT_CONFIG_FOR_TESTING[key] = projectConfig[key]\r\n }\r\n return\r\n }\r\n const config = getConfig(getGlobalConfigFilePath(), DEFAULT_GLOBAL_CONFIG)\r\n const resolvedCwd = resolve(getCwd())\r\n const existingKey = findMatchingProjectKey(config.projects, resolvedCwd)\r\n const storageKey = existingKey ?? resolvedCwd\r\n\r\n saveConfig(\r\n getGlobalConfigFilePath(),\r\n {\r\n ...config,\r\n projects: {\r\n ...config.projects,\r\n [storageKey]: projectConfig,\r\n },\r\n },\r\n DEFAULT_GLOBAL_CONFIG,\r\n )\r\n}\r\n\r\nexport async function isAutoUpdaterDisabled(): Promise<boolean> {\r\n const status = getGlobalConfig().autoUpdaterStatus\r\n return status !== 'enabled'\r\n}\r\n\r\nexport const TEST_MCPRC_CONFIG_FOR_TESTING: Record<string, McpServerConfig> = {}\r\n\r\nexport function clearMcprcConfigForTesting(): void {\r\n if (process.env.NODE_ENV === 'test') {\r\n Object.keys(TEST_MCPRC_CONFIG_FOR_TESTING).forEach(key => {\r\n delete TEST_MCPRC_CONFIG_FOR_TESTING[key]\r\n })\r\n }\r\n}\r\n\r\nexport function addMcprcServerForTesting(\r\n name: string,\r\n server: McpServerConfig,\r\n): void {\r\n if (process.env.NODE_ENV === 'test') {\r\n TEST_MCPRC_CONFIG_FOR_TESTING[name] = server\r\n }\r\n}\r\n\r\nexport function removeMcprcServerForTesting(name: string): void {\r\n if (process.env.NODE_ENV === 'test') {\r\n if (!TEST_MCPRC_CONFIG_FOR_TESTING[name]) {\r\n throw new Error(`No MCP server found with name: ${name} in .mcprc`)\r\n }\r\n delete TEST_MCPRC_CONFIG_FOR_TESTING[name]\r\n }\r\n}\r\n\r\nexport const getMcprcConfig = memoize(\r\n (): Record<string, McpServerConfig> => {\r\n if (process.env.NODE_ENV === 'test') {\r\n return TEST_MCPRC_CONFIG_FOR_TESTING\r\n }\r\n\r\n const mcprcPath = join(getCwd(), '.mcprc')\r\n if (!existsSync(mcprcPath)) {\r\n return {}\r\n }\r\n\r\n try {\r\n const mcprcContent = readFileSync(mcprcPath, 'utf-8')\r\n const config = safeParseJSON(mcprcContent)\r\n if (config && typeof config === 'object') {\r\n return config as Record<string, McpServerConfig>\r\n }\r\n } catch {}\r\n return {}\r\n },\r\n () => {\r\n const cwd = getCwd()\r\n const mcprcPath = join(cwd, '.mcprc')\r\n if (existsSync(mcprcPath)) {\r\n try {\r\n const stat = readFileSync(mcprcPath, 'utf-8')\r\n return `${cwd}:${stat}`\r\n } catch {\r\n return cwd\r\n }\r\n }\r\n return cwd\r\n },\r\n)\r\n\r\nfunction parseMcpServersFromMcpJson(\r\n value: unknown,\r\n): Record<string, McpServerConfig> {\r\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\r\n const raw = (value as { mcpServers?: unknown }).mcpServers\r\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {}\r\n return raw as Record<string, McpServerConfig>\r\n}\r\n\r\nfunction parseMcpServersFromMcprc(\r\n value: unknown,\r\n): Record<string, McpServerConfig> {\r\n if (!value || typeof value !== 'object' || Array.isArray(value)) return {}\r\n const maybeNested = (value as { mcpServers?: unknown }).mcpServers\r\n if (\r\n maybeNested &&\r\n typeof maybeNested === 'object' &&\r\n !Array.isArray(maybeNested)\r\n ) {\r\n return maybeNested as Record<string, McpServerConfig>\r\n }\r\n return value as Record<string, McpServerConfig>\r\n}\r\n\r\nexport const getProjectMcpServerDefinitions = memoize(\r\n (): ProjectMcpServerDefinitions => {\r\n if (process.env.NODE_ENV === 'test') {\r\n return {\r\n servers: {},\r\n sources: {},\r\n mcpJsonPath: join(getCwd(), '.mcp.json'),\r\n mcprcPath: join(getCwd(), '.mcprc'),\r\n }\r\n }\r\n\r\n const cwd = getCwd()\r\n const mcpJsonPath = join(cwd, '.mcp.json')\r\n const mcprcPath = join(cwd, '.mcprc')\r\n\r\n let mcpJsonServers: Record<string, McpServerConfig> = {}\r\n let mcprcServers: Record<string, McpServerConfig> = {}\r\n\r\n if (existsSync(mcpJsonPath)) {\r\n try {\r\n const content = readFileSync(mcpJsonPath, 'utf-8')\r\n const parsed = safeParseJSON(content)\r\n mcpJsonServers = parseMcpServersFromMcpJson(parsed)\r\n } catch {}\r\n }\r\n\r\n if (existsSync(mcprcPath)) {\r\n try {\r\n const content = readFileSync(mcprcPath, 'utf-8')\r\n const parsed = safeParseJSON(content)\r\n mcprcServers = parseMcpServersFromMcprc(parsed)\r\n } catch {}\r\n }\r\n\r\n const sources: Record<string, '.mcp.json' | '.mcprc'> = {}\r\n for (const name of Object.keys(mcpJsonServers)) {\r\n sources[name] = '.mcp.json'\r\n }\r\n for (const name of Object.keys(mcprcServers)) {\r\n sources[name] = '.mcprc'\r\n }\r\n\r\n return {\r\n servers: { ...mcpJsonServers, ...mcprcServers },\r\n sources,\r\n mcpJsonPath,\r\n mcprcPath,\r\n }\r\n },\r\n () => {\r\n const cwd = getCwd()\r\n const mcpJsonPath = join(cwd, '.mcp.json')\r\n const mcprcPath = join(cwd, '.mcprc')\r\n\r\n const parts: string[] = [cwd]\r\n\r\n if (existsSync(mcpJsonPath)) {\r\n try {\r\n parts.push('mcp.json')\r\n parts.push(readFileSync(mcpJsonPath, 'utf-8'))\r\n } catch {}\r\n }\r\n\r\n if (existsSync(mcprcPath)) {\r\n try {\r\n parts.push('mcprc')\r\n parts.push(readFileSync(mcprcPath, 'utf-8'))\r\n } catch {}\r\n }\r\n\r\n return parts.join(':')\r\n },\r\n)\r\n\r\nexport function getOrCreateUserID(): string {\r\n const config = getGlobalConfig()\r\n if (config.userID) {\r\n return config.userID\r\n }\r\n\r\n const userID = randomBytes(32).toString('hex')\r\n saveGlobalConfig({ ...config, userID })\r\n return userID\r\n}\r\n\r\nexport function getConfigForCLI(key: string, global: boolean): unknown {\r\n if (global) {\r\n if (!isGlobalConfigKey(key)) {\r\n console.error(\r\n `Error: '${key}' is not a valid config key. Valid keys are: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\r\n )\r\n process.exit(1)\r\n }\r\n return getGlobalConfig()[key]\r\n } else {\r\n if (!isProjectConfigKey(key)) {\r\n console.error(\r\n `Error: '${key}' is not a valid config key. Valid keys are: ${PROJECT_CONFIG_KEYS.join(', ')}`,\r\n )\r\n process.exit(1)\r\n }\r\n return getCurrentProjectConfig()[key]\r\n }\r\n}\r\n\r\nexport function setConfigForCLI(\r\n key: string,\r\n value: unknown,\r\n global: boolean,\r\n): void {\r\n if (global) {\r\n if (!isGlobalConfigKey(key)) {\r\n console.error(\r\n `Error: Cannot set '${key}'. Only these keys can be modified: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\r\n )\r\n process.exit(1)\r\n }\r\n\r\n if (key === 'autoUpdaterStatus' && !isAutoUpdaterStatus(value as string)) {\r\n console.error(\r\n `Error: Invalid value for autoUpdaterStatus. Must be one of: disabled, enabled, no_permissions, not_configured`,\r\n )\r\n process.exit(1)\r\n }\r\n\r\n const currentConfig = getGlobalConfig()\r\n saveGlobalConfig({\r\n ...currentConfig,\r\n [key]: value,\r\n })\r\n } else {\r\n if (!isProjectConfigKey(key)) {\r\n console.error(\r\n `Error: Cannot set '${key}'. Only these keys can be modified: ${PROJECT_CONFIG_KEYS.join(', ')}. Did you mean --global?`,\r\n )\r\n process.exit(1)\r\n }\r\n const currentConfig = getCurrentProjectConfig()\r\n saveCurrentProjectConfig({\r\n ...currentConfig,\r\n [key]: value,\r\n })\r\n }\r\n setTimeout(() => {\r\n process.exit(0)\r\n }, 100)\r\n}\r\n\r\nexport function deleteConfigForCLI(key: string, global: boolean): void {\r\n if (global) {\r\n if (!isGlobalConfigKey(key)) {\r\n console.error(\r\n `Error: Cannot delete '${key}'. Only these keys can be modified: ${GLOBAL_CONFIG_KEYS.join(', ')}`,\r\n )\r\n process.exit(1)\r\n }\r\n const currentConfig = getGlobalConfig()\r\n delete currentConfig[key]\r\n saveGlobalConfig(currentConfig)\r\n } else {\r\n if (!isProjectConfigKey(key)) {\r\n console.error(\r\n `Error: Cannot delete '${key}'. Only these keys can be modified: ${PROJECT_CONFIG_KEYS.join(', ')}. Did you mean --global?`,\r\n )\r\n process.exit(1)\r\n }\r\n const currentConfig = getCurrentProjectConfig()\r\n delete currentConfig[key]\r\n saveCurrentProjectConfig(currentConfig)\r\n }\r\n}\r\n\r\nexport function listConfigForCLI(global: true): GlobalConfig\r\nexport function listConfigForCLI(global: false): ProjectConfig\r\nexport function listConfigForCLI(global: boolean): object {\r\n if (global) {\r\n const currentConfig = pick(getGlobalConfig(), GLOBAL_CONFIG_KEYS)\r\n return currentConfig\r\n } else {\r\n return pick(getCurrentProjectConfig(), PROJECT_CONFIG_KEYS)\r\n }\r\n}\r\n\r\nexport function getOpenAIApiKey(): string | undefined {\r\n return process.env.OPENAI_API_KEY\r\n}\r\n\r\nexport function getAnthropicApiKey(): string {\r\n return process.env.ANTHROPIC_API_KEY || ''\r\n}\r\n", "import { logError } from '@utils/log'\r\n\r\nexport function safeParseJSON(json: string | null | undefined): unknown {\r\n if (!json) {\r\n return null\r\n }\r\n try {\r\n return JSON.parse(json)\r\n } catch (e) {\r\n logError(e)\r\n return null\r\n }\r\n}\r\n", "import type { GlobalConfig, ModelPointers, ModelProfile } from './schema'\r\n\r\nexport function migrateModelProfilesRemoveId(config: GlobalConfig): GlobalConfig {\r\n if (!config.modelProfiles) return config\r\n\r\n const idToModelNameMap = new Map<string, string>()\r\n const migratedProfiles = config.modelProfiles.map(profile => {\r\n if ((profile as any).id && profile.modelName) {\r\n idToModelNameMap.set((profile as any).id, profile.modelName)\r\n }\r\n\r\n const { id, ...profileWithoutId } = profile as any\r\n return profileWithoutId as ModelProfile\r\n })\r\n\r\n const migratedPointers: ModelPointers = {\r\n main: '',\r\n task: '',\r\n compact: '',\r\n quick: '',\r\n }\r\n\r\n const rawPointers = config.modelPointers as\r\n | Record<string, unknown>\r\n | undefined\r\n const rawMain = typeof rawPointers?.main === 'string' ? rawPointers.main : ''\r\n const rawTask = typeof rawPointers?.task === 'string' ? rawPointers.task : ''\r\n const rawQuick =\r\n typeof rawPointers?.quick === 'string' ? rawPointers.quick : ''\r\n const rawCompact =\r\n typeof rawPointers?.compact === 'string'\r\n ? rawPointers.compact\r\n : typeof rawPointers?.reasoning === 'string'\r\n ? rawPointers.reasoning\r\n : ''\r\n\r\n if (rawMain) migratedPointers.main = idToModelNameMap.get(rawMain) || rawMain\r\n if (rawTask) migratedPointers.task = idToModelNameMap.get(rawTask) || rawTask\r\n if (rawCompact)\r\n migratedPointers.compact = idToModelNameMap.get(rawCompact) || rawCompact\r\n if (rawQuick)\r\n migratedPointers.quick = idToModelNameMap.get(rawQuick) || rawQuick\r\n\r\n let defaultModelName: string | undefined\r\n if ((config as any).defaultModelId) {\r\n defaultModelName =\r\n idToModelNameMap.get((config as any).defaultModelId) ||\r\n (config as any).defaultModelId\r\n } else if ((config as any).defaultModelName) {\r\n defaultModelName = (config as any).defaultModelName\r\n }\r\n\r\n const migratedConfig = { ...config }\r\n delete (migratedConfig as any).defaultModelId\r\n delete (migratedConfig as any).currentSelectedModelId\r\n delete (migratedConfig as any).mainAgentModelId\r\n delete (migratedConfig as any).taskToolModelId\r\n\r\n return {\r\n ...migratedConfig,\r\n modelProfiles: migratedProfiles,\r\n modelPointers: migratedPointers,\r\n defaultModelName,\r\n }\r\n}\r\n\r\n", "import type { ModelPointerType, ModelProfile, ProviderType } from './schema'\r\nimport { debug as debugLogger } from '@utils/log/debugLogger'\r\nimport { getGlobalConfig, saveGlobalConfig } from './loader'\r\n\r\nexport function setAllPointersToModel(modelName: string): void {\r\n const config = getGlobalConfig()\r\n const updatedConfig = {\r\n ...config,\r\n modelPointers: {\r\n main: modelName,\r\n task: modelName,\r\n compact: modelName,\r\n quick: modelName,\r\n },\r\n defaultModelName: modelName,\r\n }\r\n saveGlobalConfig(updatedConfig)\r\n}\r\n\r\nexport function setModelPointer(\r\n pointer: ModelPointerType,\r\n modelName: string,\r\n): void {\r\n const config = getGlobalConfig()\r\n const updatedConfig = {\r\n ...config,\r\n modelPointers: {\r\n ...config.modelPointers,\r\n [pointer]: modelName,\r\n },\r\n }\r\n saveGlobalConfig(updatedConfig)\r\n\r\n import('../../utils/model').then(({ reloadModelManager }) => {\r\n reloadModelManager()\r\n })\r\n}\r\n\r\nexport function isGPT5ModelName(modelName: string): boolean {\r\n if (!modelName || typeof modelName !== 'string') return false\r\n const lowerName = modelName.toLowerCase()\r\n return lowerName.startsWith('gpt-5') || lowerName.includes('gpt-5')\r\n}\r\n\r\nexport function validateAndRepairGPT5Profile(\r\n profile: ModelProfile,\r\n): ModelProfile {\r\n const isGPT5 = isGPT5ModelName(profile.modelName)\r\n const now = Date.now()\r\n\r\n const repairedProfile: ModelProfile = { ...profile }\r\n let wasRepaired = false\r\n\r\n if (isGPT5 !== profile.isGPT5) {\r\n repairedProfile.isGPT5 = isGPT5\r\n wasRepaired = true\r\n }\r\n\r\n if (isGPT5) {\r\n\r\n const validReasoningEfforts = ['minimal', 'low', 'medium', 'high']\r\n if (\r\n !profile.reasoningEffort ||\r\n !validReasoningEfforts.includes(profile.reasoningEffort)\r\n ) {\r\n repairedProfile.reasoningEffort = 'medium'\r\n wasRepaired = true\r\n debugLogger.state('GPT5_CONFIG_AUTO_REPAIR', {\r\n model: profile.modelName,\r\n field: 'reasoningEffort',\r\n value: 'medium',\r\n })\r\n }\r\n\r\n if (profile.contextLength < 128000) {\r\n repairedProfile.contextLength = 128000\r\n wasRepaired = true\r\n debugLogger.state('GPT5_CONFIG_AUTO_REPAIR', {\r\n model: profile.modelName,\r\n field: 'contextLength',\r\n value: 128000,\r\n })\r\n }\r\n\r\n if (profile.maxTokens < 4000) {\r\n repairedProfile.maxTokens = 8192\r\n wasRepaired = true\r\n debugLogger.state('GPT5_CONFIG_AUTO_REPAIR', {\r\n model: profile.modelName,\r\n field: 'maxTokens',\r\n value: 8192,\r\n })\r\n }\r\n\r\n if (\r\n profile.provider !== 'openai' &&\r\n profile.provider !== 'custom-openai' &&\r\n profile.provider !== 'azure'\r\n ) {\r\n debugLogger.warn('GPT5_CONFIG_UNEXPECTED_PROVIDER', {\r\n model: profile.modelName,\r\n provider: profile.provider,\r\n expectedProviders: ['openai', 'custom-openai', 'azure'],\r\n })\r\n }\r\n\r\n if (profile.modelName.includes('gpt-5') && !profile.baseURL) {\r\n repairedProfile.baseURL = 'https://api.openai.com/v1'\r\n wasRepaired = true\r\n debugLogger.state('GPT5_CONFIG_AUTO_REPAIR', {\r\n model: profile.modelName,\r\n field: 'baseURL',\r\n value: 'https://api.openai.com/v1',\r\n })\r\n }\r\n }\r\n\r\n repairedProfile.validationStatus = wasRepaired ? 'auto_repaired' : 'valid'\r\n repairedProfile.lastValidation = now\r\n\r\n if (wasRepaired) {\r\n debugLogger.info('GPT5_CONFIG_AUTO_REPAIRED', { model: profile.modelName })\r\n }\r\n\r\n return repairedProfile\r\n}\r\n\r\nexport function validateAndRepairAllGPT5Profiles(): {\r\n repaired: number\r\n total: number\r\n} {\r\n const config = getGlobalConfig()\r\n if (!config.modelProfiles) {\r\n return { repaired: 0, total: 0 }\r\n }\r\n\r\n let repairCount = 0\r\n const repairedProfiles = config.modelProfiles.map(profile => {\r\n const repairedProfile = validateAndRepairGPT5Profile(profile)\r\n if (repairedProfile.validationStatus === 'auto_repaired') {\r\n repairCount++\r\n }\r\n return repairedProfile\r\n })\r\n\r\n if (repairCount > 0) {\r\n const updatedConfig = {\r\n ...config,\r\n modelProfiles: repairedProfiles,\r\n }\r\n saveGlobalConfig(updatedConfig)\r\n debugLogger.info('GPT5_CONFIG_AUTO_REPAIR_SUMMARY', {\r\n repaired: repairCount,\r\n total: config.modelProfiles.length,\r\n })\r\n }\r\n\r\n return { repaired: repairCount, total: config.modelProfiles.length }\r\n}\r\n\r\nexport function getGPT5ConfigRecommendations(\r\n modelName: string,\r\n): Partial<ModelProfile> {\r\n if (!isGPT5ModelName(modelName)) {\r\n return {}\r\n }\r\n\r\n const recommendations: Partial<ModelProfile> = {\r\n contextLength: 128000,\r\n maxTokens: 8192,\r\n reasoningEffort: 'medium',\r\n isGPT5: true,\r\n }\r\n\r\n if (modelName.includes('gpt-5-mini')) {\r\n recommendations.maxTokens = 4096\r\n recommendations.reasoningEffort = 'low'\r\n } else if (modelName.includes('gpt-5-nano')) {\r\n recommendations.maxTokens = 2048\r\n recommendations.reasoningEffort = 'minimal'\r\n }\r\n\r\n return recommendations\r\n}\r\n\r\nexport function createGPT5ModelProfile(\r\n name: string,\r\n modelName: string,\r\n apiKey: string,\r\n baseURL?: string,\r\n provider: ProviderType = 'openai',\r\n): ModelProfile {\r\n const recommendations = getGPT5ConfigRecommendations(modelName)\r\n\r\n const profile: ModelProfile = {\r\n name,\r\n provider,\r\n modelName,\r\n baseURL: baseURL || 'https://api.openai.com/v1',\r\n apiKey,\r\n maxTokens: recommendations.maxTokens || 8192,\r\n contextLength: recommendations.contextLength || 128000,\r\n reasoningEffort: recommendations.reasoningEffort || 'medium',\r\n isActive: true,\r\n createdAt: Date.now(),\r\n isGPT5: true,\r\n validationStatus: 'valid',\r\n lastValidation: Date.now(),\r\n }\r\n\r\n return profile\r\n}\r\n\r\n"],
5
+ "mappings": "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",
6
+ "names": ["homedir", "homedir", "resolved"]
7
+ }
@@ -0,0 +1,514 @@
1
+ import { createRequire as __kodeCreateRequire } from "node:module";
2
+ const require = __kodeCreateRequire(import.meta.url);
3
+ import {
4
+ getSettingsFileCandidates,
5
+ loadSettingsWithLegacyFallback,
6
+ saveSettingsToPrimaryAndSyncLegacy
7
+ } from "./chunk-66EZC7Y7.js";
8
+ import {
9
+ isSettingSourceEnabled
10
+ } from "./chunk-WAY3DKFO.js";
11
+ import {
12
+ getSessionPlugins
13
+ } from "./chunk-2VQWLLDU.js";
14
+ import {
15
+ getCwd,
16
+ init_state
17
+ } from "./chunk-SQGAHZPM.js";
18
+
19
+ // src/services/ui/outputStyles.ts
20
+ import figures from "figures";
21
+ import { memoize } from "lodash-es";
22
+ import { existsSync, readdirSync, readFileSync, statSync } from "fs";
23
+ import { basename, dirname, join, resolve } from "path";
24
+ import { homedir } from "os";
25
+ import matter from "gray-matter";
26
+ import yaml from "js-yaml";
27
+
28
+ // src/utils/config/localSettings.ts
29
+ init_state();
30
+ function readLocalSettings(options) {
31
+ const projectDir = options?.projectDir ?? getCwd();
32
+ const loaded = loadSettingsWithLegacyFallback({
33
+ destination: "localSettings",
34
+ projectDir,
35
+ migrateToPrimary: true
36
+ });
37
+ return loaded.settings ?? {};
38
+ }
39
+ function updateLocalSettings(patch, options) {
40
+ const projectDir = options?.projectDir ?? getCwd();
41
+ const candidates = getSettingsFileCandidates({
42
+ destination: "localSettings",
43
+ projectDir
44
+ });
45
+ const existing = (candidates ? loadSettingsWithLegacyFallback({
46
+ destination: "localSettings",
47
+ projectDir,
48
+ migrateToPrimary: true
49
+ }).settings : null) ?? {};
50
+ const next = { ...existing, ...patch };
51
+ if (candidates) {
52
+ saveSettingsToPrimaryAndSyncLegacy({
53
+ destination: "localSettings",
54
+ projectDir,
55
+ settings: next,
56
+ syncLegacyIfExists: true
57
+ });
58
+ }
59
+ return next;
60
+ }
61
+
62
+ // src/services/ui/outputStyles.ts
63
+ init_state();
64
+ var DEFAULT_OUTPUT_STYLE = "default";
65
+ function normalizeString(value) {
66
+ if (typeof value !== "string") return null;
67
+ const trimmed = value.trim();
68
+ return trimmed ? trimmed : null;
69
+ }
70
+ function getClaudePolicyBaseDir() {
71
+ switch (process.platform) {
72
+ case "darwin":
73
+ return "/Library/Application Support/ClaudeCode";
74
+ case "win32":
75
+ return existsSync("C:\\Program Files\\ClaudeCode") ? "C:\\Program Files\\ClaudeCode" : "C:\\ProgramData\\ClaudeCode";
76
+ default:
77
+ return "/etc/claude-code";
78
+ }
79
+ }
80
+ function getUserConfigBaseDirs() {
81
+ const out = [];
82
+ const hasAnyOverride = typeof process.env.CLAUDE_CONFIG_DIR === "string" || typeof process.env.DANYA_CONFIG_DIR === "string" || typeof process.env.KODE_CONFIG_DIR === "string";
83
+ const claudeBase = normalizeString(process.env.CLAUDE_CONFIG_DIR);
84
+ const danyaBase = normalizeString(process.env.DANYA_CONFIG_DIR ?? process.env.KODE_CONFIG_DIR);
85
+ if (claudeBase) out.push({ claude: resolve(claudeBase), danya: resolve(claudeBase) });
86
+ if (danyaBase) out.push({ claude: resolve(danyaBase), danya: resolve(danyaBase) });
87
+ if (hasAnyOverride) {
88
+ return dedupeConfigBases(out);
89
+ }
90
+ return dedupeConfigBases([
91
+ { claude: join(homedir(), ".claude"), danya: join(homedir(), ".claude") },
92
+ { claude: join(homedir(), ".danya"), danya: join(homedir(), ".danya") }
93
+ ]);
94
+ }
95
+ function dedupeConfigBases(bases) {
96
+ const seen = /* @__PURE__ */ new Set();
97
+ const out = [];
98
+ for (const base of bases) {
99
+ const key = `${base.claude}::${base.danya}`;
100
+ if (seen.has(key)) continue;
101
+ seen.add(key);
102
+ out.push(base);
103
+ }
104
+ return out;
105
+ }
106
+ function findProjectSubdirs(subdir, cwd) {
107
+ const result = [];
108
+ const home = resolve(homedir());
109
+ let current = resolve(cwd);
110
+ while (current !== home) {
111
+ const claudeDir = join(current, ".claude", subdir);
112
+ if (existsSync(claudeDir)) result.push(claudeDir);
113
+ const danyaDir = join(current, ".danya", subdir);
114
+ if (existsSync(danyaDir)) result.push(danyaDir);
115
+ const parent = dirname(current);
116
+ if (parent === current) break;
117
+ current = parent;
118
+ }
119
+ return result;
120
+ }
121
+ function markdownFirstLineOrHeading(content, fallback) {
122
+ const lines = content.split("\n");
123
+ for (const line of lines) {
124
+ const trimmed = line.trim();
125
+ if (!trimmed) continue;
126
+ const heading = trimmed.match(/^#+\s+(.+)$/)?.[1] ?? trimmed;
127
+ return heading.length > 100 ? `${heading.substring(0, 97)}...` : heading;
128
+ }
129
+ return fallback;
130
+ }
131
+ function listMarkdownFilesRecursively(rootDir) {
132
+ const files = [];
133
+ const visitedDirs = /* @__PURE__ */ new Set();
134
+ const walk = (dirPath) => {
135
+ let dirStat;
136
+ try {
137
+ dirStat = statSync(dirPath);
138
+ } catch {
139
+ return;
140
+ }
141
+ if (!dirStat.isDirectory()) return;
142
+ const dirKey = `${dirStat.dev}:${dirStat.ino}`;
143
+ if (visitedDirs.has(dirKey)) return;
144
+ visitedDirs.add(dirKey);
145
+ let entries;
146
+ try {
147
+ entries = readdirSync(dirPath, { withFileTypes: true, encoding: "utf8" });
148
+ } catch {
149
+ return;
150
+ }
151
+ for (const entry of entries) {
152
+ const name = String(entry.name ?? "");
153
+ const fullPath = join(dirPath, name);
154
+ if (entry.isDirectory()) {
155
+ walk(fullPath);
156
+ continue;
157
+ }
158
+ if (entry.isFile()) {
159
+ if (name.endsWith(".md")) files.push(fullPath);
160
+ continue;
161
+ }
162
+ if (entry.isSymbolicLink()) {
163
+ try {
164
+ const st = statSync(fullPath);
165
+ if (st.isDirectory()) {
166
+ walk(fullPath);
167
+ } else if (st.isFile() && name.endsWith(".md")) {
168
+ files.push(fullPath);
169
+ }
170
+ } catch {
171
+ continue;
172
+ }
173
+ }
174
+ }
175
+ };
176
+ if (!existsSync(rootDir)) return [];
177
+ walk(rootDir);
178
+ return files;
179
+ }
180
+ function readMarkdownFile(filePath) {
181
+ try {
182
+ const raw = readFileSync(filePath, "utf8");
183
+ const yamlSchema = yaml.JSON_SCHEMA;
184
+ const matterOptions = {
185
+ engines: {
186
+ yaml: {
187
+ parse: (input) => yaml.load(input, yamlSchema ? { schema: yamlSchema } : void 0) ?? {}
188
+ }
189
+ }
190
+ };
191
+ const parsed = matter(raw, matterOptions);
192
+ return { frontmatter: parsed.data ?? {}, content: String(parsed.content ?? "") };
193
+ } catch {
194
+ return null;
195
+ }
196
+ }
197
+ function inodeKeyForPath(filePath) {
198
+ try {
199
+ const st = statSync(filePath);
200
+ if (typeof st.dev === "number" && typeof st.ino === "number") {
201
+ return `${st.dev}:${st.ino}`;
202
+ }
203
+ return null;
204
+ } catch {
205
+ return null;
206
+ }
207
+ }
208
+ var INSIGHTS_SECTION = `
209
+ ## Insights
210
+ In order to encourage learning, before and after writing code, always provide brief educational explanations about implementation choices using (with backticks):
211
+ "\`${figures.star} Insight \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\`
212
+ [2-3 key educational points]
213
+ \`\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\`"
214
+
215
+ These insights should be included in the conversation, not in the codebase. You should generally focus on interesting insights that are specific to the codebase or the code you just wrote, rather than general programming concepts.`;
216
+ function getBuiltInOutputStyles() {
217
+ return {
218
+ [DEFAULT_OUTPUT_STYLE]: null,
219
+ Explanatory: {
220
+ name: "Explanatory",
221
+ source: "built-in",
222
+ description: "Claude explains its implementation choices and codebase patterns",
223
+ keepCodingInstructions: true,
224
+ prompt: `You are an interactive CLI tool that helps users with software engineering tasks. In addition to software engineering tasks, you should provide educational insights about the codebase along the way.
225
+
226
+ You should be clear and educational, providing helpful explanations while remaining focused on the task. Balance educational content with task completion. When providing insights, you may exceed typical length constraints, but remain focused and relevant.
227
+
228
+ # Explanatory Style Active
229
+ ${INSIGHTS_SECTION}`
230
+ },
231
+ Learning: {
232
+ name: "Learning",
233
+ source: "built-in",
234
+ description: "Claude pauses and asks you to write small pieces of code for hands-on practice",
235
+ keepCodingInstructions: true,
236
+ prompt: `You are an interactive CLI tool that helps users with software engineering tasks. In addition to software engineering tasks, you should help users learn more about the codebase through hands-on practice and educational insights.
237
+
238
+ You should be collaborative and encouraging. Balance task completion with learning by requesting user input for meaningful design decisions while handling routine implementation yourself.
239
+
240
+ # Learning Style Active
241
+ ## Requesting Human Contributions
242
+ In order to encourage learning, ask the human to contribute 2-10 line code pieces when generating 20+ lines involving:
243
+ - Design decisions (error handling, data structures)
244
+ - Business logic with multiple valid approaches
245
+ - Key algorithms or interface definitions
246
+
247
+ **TodoList Integration**: If using a TodoList for the overall task, include a specific todo item like "Request human input on [specific decision]" when planning to request human input. This ensures proper task tracking. Note: TodoList is not required for all tasks.
248
+
249
+ Example TodoList flow:
250
+ \u2713 "Set up component structure with placeholder for logic"
251
+ \u2713 "Request human collaboration on decision logic implementation"
252
+ \u2713 "Integrate contribution and complete feature"
253
+
254
+ ### Request Format
255
+ \`\`\`
256
+ ${figures.bullet} **Learn by Doing**
257
+ **Context:** [what's built and why this decision matters]
258
+ **Your Task:** [specific function/section in file, mention file and TODO(human) but do not include line numbers]
259
+ **Guidance:** [trade-offs and constraints to consider]
260
+ \`\`\`
261
+
262
+ ### Key Guidelines
263
+ - Frame contributions as valuable design decisions, not busy work
264
+ - You must first add a TODO(human) section into the codebase with your editing tools before making the Learn by Doing request
265
+ - Make sure there is one and only one TODO(human) section in the code
266
+ - Don't take any action or output anything after the Learn by Doing request. Wait for human implementation before proceeding.
267
+
268
+ ### Example Requests
269
+
270
+ **Whole Function Example:**
271
+ \`\`\`
272
+ ${figures.bullet} **Learn by Doing**
273
+
274
+ **Context:** I've set up the hint feature UI with a button that triggers the hint system. The infrastructure is ready: when clicked, it calls selectHintCell() to determine which cell to hint, then highlights that cell with a yellow background and shows possible values. The hint system needs to decide which empty cell would be most helpful to reveal to the user.
275
+
276
+ **Your Task:** In sudoku.js, implement the selectHintCell(board) function. Look for TODO(human). This function should analyze the board and return {row, col} for the best cell to hint, or null if the puzzle is complete.
277
+
278
+ **Guidance:** Consider multiple strategies: prioritize cells with only one possible value (naked singles), or cells that appear in rows/columns/boxes with many filled cells. You could also consider a balanced approach that helps without making it too easy. The board parameter is a 9x9 array where 0 represents empty cells.
279
+ \`\`\`
280
+
281
+ **Partial Function Example:**
282
+ \`\`\`
283
+ ${figures.bullet} **Learn by Doing**
284
+
285
+ **Context:** I've built a file upload component that validates files before accepting them. The main validation logic is complete, but it needs specific handling for different file type categories in the switch statement.
286
+
287
+ **Your Task:** In upload.js, inside the validateFile() function's switch statement, implement the 'case "document":' branch. Look for TODO(human). This should validate document files (pdf, doc, docx).
288
+
289
+ **Guidance:** Consider checking file size limits (maybe 10MB for documents?), validating the file extension matches the MIME type, and returning {valid: boolean, error?: string}. The file object has properties: name, size, type.
290
+ \`\`\`
291
+
292
+ **Debugging Example:**
293
+ \`\`\`
294
+ ${figures.bullet} **Learn by Doing**
295
+
296
+ **Context:** The user reported that number inputs aren't working correctly in the calculator. I've identified the handleInput() function as the likely source, but need to understand what values are being processed.
297
+
298
+ **Your Task:** In calculator.js, inside the handleInput() function, add 2-3 console.log statements after the TODO(human) comment to help debug why number inputs fail.
299
+
300
+ **Guidance:** Consider logging: the raw input value, the parsed result, and any validation state. This will help us understand where the conversion breaks.
301
+ \`\`\`
302
+
303
+ ### After Contributions
304
+ Share one insight connecting their code to broader patterns or system effects. Avoid praise or repetition.
305
+
306
+ ## Insights
307
+ ${INSIGHTS_SECTION}`
308
+ }
309
+ };
310
+ }
311
+ function parseKeepCodingInstructions(value) {
312
+ if (value === "true") return true;
313
+ if (value === "false") return false;
314
+ return void 0;
315
+ }
316
+ function parseCustomOutputStyleFile(options) {
317
+ const parsed = readMarkdownFile(options.filePath);
318
+ if (!parsed) return null;
319
+ const base = basename(options.filePath, ".md");
320
+ const name = normalizeString(parsed.frontmatter?.name) ?? base;
321
+ const description = normalizeString(parsed.frontmatter?.description) ?? markdownFirstLineOrHeading(parsed.content, `Custom ${base} output style`);
322
+ const keepCodingInstructions = parseKeepCodingInstructions(
323
+ parsed.frontmatter?.["keep-coding-instructions"]
324
+ );
325
+ const prompt = parsed.content.trim();
326
+ return {
327
+ name,
328
+ description,
329
+ prompt,
330
+ source: options.source,
331
+ ...keepCodingInstructions !== void 0 ? { keepCodingInstructions } : {}
332
+ };
333
+ }
334
+ function parsePluginOutputStyleFile(options) {
335
+ const inodeKey = inodeKeyForPath(options.filePath);
336
+ const dedupeKey = inodeKey ? `inode:${inodeKey}` : `path:${options.filePath}`;
337
+ if (options.seen.has(dedupeKey)) return null;
338
+ options.seen.add(dedupeKey);
339
+ const parsed = readMarkdownFile(options.filePath);
340
+ if (!parsed) return null;
341
+ const base = basename(options.filePath, ".md");
342
+ const styleName = normalizeString(parsed.frontmatter?.name) ?? base;
343
+ const fullName = `${options.pluginName}:${styleName}`;
344
+ const description = normalizeString(parsed.frontmatter?.description) ?? markdownFirstLineOrHeading(
345
+ parsed.content,
346
+ `Output style from ${options.pluginName} plugin`
347
+ );
348
+ const prompt = parsed.content.trim();
349
+ return {
350
+ name: fullName,
351
+ description,
352
+ prompt,
353
+ source: "plugin"
354
+ };
355
+ }
356
+ function loadPluginOutputStyles() {
357
+ const out = [];
358
+ const plugins = getSessionPlugins();
359
+ for (const plugin of plugins) {
360
+ const pluginName = plugin.name;
361
+ const seen = /* @__PURE__ */ new Set();
362
+ for (const dir of plugin.outputStylesDirs ?? []) {
363
+ let st;
364
+ try {
365
+ st = statSync(dir);
366
+ } catch {
367
+ continue;
368
+ }
369
+ if (st.isFile()) {
370
+ if (!dir.endsWith(".md")) continue;
371
+ const style = parsePluginOutputStyleFile({
372
+ filePath: dir,
373
+ pluginName,
374
+ seen
375
+ });
376
+ if (style) out.push(style);
377
+ continue;
378
+ }
379
+ if (st.isDirectory()) {
380
+ const files = listMarkdownFilesRecursively(dir);
381
+ for (const filePath of files) {
382
+ const style = parsePluginOutputStyleFile({
383
+ filePath,
384
+ pluginName,
385
+ seen
386
+ });
387
+ if (style) out.push(style);
388
+ }
389
+ }
390
+ }
391
+ }
392
+ return out;
393
+ }
394
+ function loadCustomOutputStyles(options) {
395
+ const out = [];
396
+ const seen = /* @__PURE__ */ new Set();
397
+ const policyDir = join(
398
+ getClaudePolicyBaseDir(),
399
+ ".claude",
400
+ "output-styles"
401
+ );
402
+ for (const filePath of listMarkdownFilesRecursively(policyDir)) {
403
+ const inodeKey = inodeKeyForPath(filePath);
404
+ const dedupeKey = inodeKey ? `inode:${inodeKey}` : `path:${filePath}`;
405
+ if (seen.has(dedupeKey)) continue;
406
+ seen.add(dedupeKey);
407
+ const style = parseCustomOutputStyleFile({
408
+ filePath,
409
+ source: "policySettings"
410
+ });
411
+ if (style) out.push(style);
412
+ }
413
+ if (isSettingSourceEnabled("userSettings")) {
414
+ const userBases = getUserConfigBaseDirs();
415
+ for (const base of userBases) {
416
+ for (const userBaseDir of /* @__PURE__ */ new Set([base.claude, base.danya])) {
417
+ const dirPath = join(userBaseDir, "output-styles");
418
+ for (const filePath of listMarkdownFilesRecursively(dirPath)) {
419
+ const inodeKey = inodeKeyForPath(filePath);
420
+ const dedupeKey = inodeKey ? `inode:${inodeKey}` : `path:${filePath}`;
421
+ if (seen.has(dedupeKey)) continue;
422
+ seen.add(dedupeKey);
423
+ const style = parseCustomOutputStyleFile({
424
+ filePath,
425
+ source: "userSettings"
426
+ });
427
+ if (style) out.push(style);
428
+ }
429
+ }
430
+ }
431
+ }
432
+ if (isSettingSourceEnabled("projectSettings")) {
433
+ for (const dirPath of findProjectSubdirs("output-styles", options.cwd)) {
434
+ for (const filePath of listMarkdownFilesRecursively(dirPath)) {
435
+ const inodeKey = inodeKeyForPath(filePath);
436
+ const dedupeKey = inodeKey ? `inode:${inodeKey}` : `path:${filePath}`;
437
+ if (seen.has(dedupeKey)) continue;
438
+ seen.add(dedupeKey);
439
+ const style = parseCustomOutputStyleFile({
440
+ filePath,
441
+ source: "projectSettings"
442
+ });
443
+ if (style) out.push(style);
444
+ }
445
+ }
446
+ }
447
+ return out;
448
+ }
449
+ var getAvailableOutputStyles = memoize(() => {
450
+ const cwd = getCwd();
451
+ const builtIn = getBuiltInOutputStyles();
452
+ const merged = { ...builtIn };
453
+ for (const style of loadPluginOutputStyles()) {
454
+ merged[style.name] = style;
455
+ }
456
+ const custom = loadCustomOutputStyles({ cwd });
457
+ const user = custom.filter((s) => s.source === "userSettings");
458
+ const project = custom.filter((s) => s.source === "projectSettings");
459
+ const policy = custom.filter((s) => s.source === "policySettings");
460
+ for (const style of user) merged[style.name] = style;
461
+ for (const style of project) merged[style.name] = style;
462
+ for (const style of policy) merged[style.name] = style;
463
+ return merged;
464
+ });
465
+ function clearOutputStyleCache() {
466
+ ;
467
+ getAvailableOutputStyles.cache?.clear?.();
468
+ }
469
+ function getCurrentOutputStyle() {
470
+ if (!isSettingSourceEnabled("localSettings")) return DEFAULT_OUTPUT_STYLE;
471
+ const settings = readLocalSettings();
472
+ const candidate = normalizeString(settings.outputStyle);
473
+ return candidate ?? DEFAULT_OUTPUT_STYLE;
474
+ }
475
+ function setCurrentOutputStyle(styleName) {
476
+ updateLocalSettings({ outputStyle: styleName });
477
+ }
478
+ function resolveOutputStyleName(input) {
479
+ const raw = normalizeString(input);
480
+ if (!raw) return null;
481
+ const styles = getAvailableOutputStyles();
482
+ if (raw in styles) return raw;
483
+ const lower = raw.toLowerCase();
484
+ for (const name of Object.keys(styles)) {
485
+ if (name.toLowerCase() === lower) return name;
486
+ }
487
+ return null;
488
+ }
489
+ function getCurrentOutputStyleDefinition() {
490
+ const current = getCurrentOutputStyle();
491
+ const styles = getAvailableOutputStyles();
492
+ return styles[current] ?? null;
493
+ }
494
+ function getOutputStyleSystemPromptAdditions() {
495
+ const style = getCurrentOutputStyleDefinition();
496
+ if (!style) return [];
497
+ const prompt = style.prompt.trim();
498
+ if (!prompt) return [];
499
+ return [`
500
+ # Output Style: ${style.name}
501
+ ${prompt}
502
+ `];
503
+ }
504
+
505
+ export {
506
+ DEFAULT_OUTPUT_STYLE,
507
+ getAvailableOutputStyles,
508
+ clearOutputStyleCache,
509
+ getCurrentOutputStyle,
510
+ setCurrentOutputStyle,
511
+ resolveOutputStyleName,
512
+ getCurrentOutputStyleDefinition,
513
+ getOutputStyleSystemPromptAdditions
514
+ };