@vybestack/llxprt-code-core 0.1.15 → 0.1.16-hotfix1

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 (358) hide show
  1. package/README.md +37 -2
  2. package/dist/src/code_assist/converter.d.ts +2 -1
  3. package/dist/src/code_assist/converter.js +2 -1
  4. package/dist/src/code_assist/converter.js.map +1 -1
  5. package/dist/src/code_assist/converter.test.js +13 -10
  6. package/dist/src/code_assist/converter.test.js.map +1 -1
  7. package/dist/src/code_assist/server.d.ts +2 -2
  8. package/dist/src/code_assist/server.js +4 -4
  9. package/dist/src/code_assist/server.js.map +1 -1
  10. package/dist/src/code_assist/server.test.js +9 -9
  11. package/dist/src/code_assist/server.test.js.map +1 -1
  12. package/dist/src/code_assist/setup.js +1 -1
  13. package/dist/src/code_assist/setup.js.map +1 -1
  14. package/dist/src/code_assist/setup.test.js +2 -2
  15. package/dist/src/code_assist/setup.test.js.map +1 -1
  16. package/dist/src/config/config.d.ts +22 -4
  17. package/dist/src/config/config.js +58 -10
  18. package/dist/src/config/config.js.map +1 -1
  19. package/dist/src/config/config.test.js +28 -0
  20. package/dist/src/config/config.test.js.map +1 -1
  21. package/dist/src/config/flashFallback.test.js +11 -1
  22. package/dist/src/config/flashFallback.test.js.map +1 -1
  23. package/dist/src/config/models.js.map +1 -1
  24. package/dist/src/config/profileManager.d.ts +42 -0
  25. package/dist/src/config/profileManager.js +114 -0
  26. package/dist/src/config/profileManager.js.map +1 -0
  27. package/dist/src/core/client.d.ts +11 -1
  28. package/dist/src/core/client.js +86 -30
  29. package/dist/src/core/client.js.map +1 -1
  30. package/dist/src/core/client.test.d.ts +1 -1
  31. package/dist/src/core/client.test.js +95 -28
  32. package/dist/src/core/client.test.js.map +1 -1
  33. package/dist/src/core/contentGenerator.d.ts +2 -2
  34. package/dist/src/core/contentGenerator.js.map +1 -1
  35. package/dist/src/core/coreToolScheduler.js +39 -15
  36. package/dist/src/core/coreToolScheduler.js.map +1 -1
  37. package/dist/src/core/coreToolScheduler.test.js +14 -17
  38. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  39. package/dist/src/core/geminiChat.js +36 -2
  40. package/dist/src/core/geminiChat.js.map +1 -1
  41. package/dist/src/core/geminiChat.test.js +2 -2
  42. package/dist/src/core/geminiChat.test.js.map +1 -1
  43. package/dist/src/core/nonInteractiveToolExecutor.js +11 -3
  44. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  45. package/dist/src/core/nonInteractiveToolExecutor.test.js +5 -2
  46. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  47. package/dist/src/core/prompts-async.test.d.ts +6 -0
  48. package/dist/src/core/prompts-async.test.js +115 -0
  49. package/dist/src/core/prompts-async.test.js.map +1 -0
  50. package/dist/src/core/prompts.d.ts +8 -1
  51. package/dist/src/core/prompts.js +97 -377
  52. package/dist/src/core/prompts.js.map +1 -1
  53. package/dist/src/core/prompts.test.js +46 -192
  54. package/dist/src/core/prompts.test.js.map +1 -1
  55. package/dist/src/core/tokenLimits.d.ts +1 -1
  56. package/dist/src/core/tokenLimits.js +5 -1
  57. package/dist/src/core/tokenLimits.js.map +1 -1
  58. package/dist/src/core/turn.d.ts +3 -0
  59. package/dist/src/core/turn.js +3 -0
  60. package/dist/src/core/turn.js.map +1 -1
  61. package/dist/src/ide/detect-ide.d.ts +10 -0
  62. package/dist/src/ide/detect-ide.js +24 -0
  63. package/dist/src/ide/detect-ide.js.map +1 -0
  64. package/dist/src/ide/ide-client.d.ts +11 -1
  65. package/dist/src/ide/ide-client.js +37 -1
  66. package/dist/src/ide/ide-client.js.map +1 -1
  67. package/dist/src/ide/ide-installer.d.ts +15 -0
  68. package/dist/src/ide/ide-installer.js +111 -0
  69. package/dist/src/ide/ide-installer.js.map +1 -0
  70. package/dist/src/ide/ide-installer.test.d.ts +6 -0
  71. package/dist/src/ide/ide-installer.test.js +78 -0
  72. package/dist/src/ide/ide-installer.test.js.map +1 -0
  73. package/dist/src/index.d.ts +9 -0
  74. package/dist/src/index.js +11 -0
  75. package/dist/src/index.js.map +1 -1
  76. package/dist/src/mcp/oauth-provider.js +3 -3
  77. package/dist/src/mcp/oauth-provider.js.map +1 -1
  78. package/dist/src/mcp/oauth-provider.test.js +9 -8
  79. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  80. package/dist/src/mcp/oauth-utils.js +12 -4
  81. package/dist/src/mcp/oauth-utils.js.map +1 -1
  82. package/dist/src/parsers/TextToolCallParser.d.ts +1 -0
  83. package/dist/src/parsers/TextToolCallParser.js +45 -3
  84. package/dist/src/parsers/TextToolCallParser.js.map +1 -1
  85. package/dist/src/parsers/TextToolCallParser.multibyte.test.d.ts +1 -0
  86. package/dist/src/parsers/TextToolCallParser.multibyte.test.js +42 -0
  87. package/dist/src/parsers/TextToolCallParser.multibyte.test.js.map +1 -0
  88. package/dist/src/prompt-config/TemplateEngine.d.ts +35 -0
  89. package/dist/src/prompt-config/TemplateEngine.js +149 -0
  90. package/dist/src/prompt-config/TemplateEngine.js.map +1 -0
  91. package/dist/src/prompt-config/TemplateEngine.test.d.ts +1 -0
  92. package/dist/src/prompt-config/TemplateEngine.test.js +494 -0
  93. package/dist/src/prompt-config/TemplateEngine.test.js.map +1 -0
  94. package/dist/src/prompt-config/defaults/compression.md +58 -0
  95. package/dist/src/prompt-config/defaults/core-defaults.d.ts +5 -0
  96. package/dist/src/prompt-config/defaults/core-defaults.js +332 -0
  97. package/dist/src/prompt-config/defaults/core-defaults.js.map +1 -0
  98. package/dist/src/prompt-config/defaults/core.md +267 -0
  99. package/dist/src/prompt-config/defaults/env/git-repository.md +15 -0
  100. package/dist/src/prompt-config/defaults/env/ide-mode.md +3 -0
  101. package/dist/src/prompt-config/defaults/env/macos-seatbelt.md +3 -0
  102. package/dist/src/prompt-config/defaults/env/outside-of-sandbox.md +3 -0
  103. package/dist/src/prompt-config/defaults/env/sandbox.md +3 -0
  104. package/dist/src/prompt-config/defaults/index.d.ts +14 -0
  105. package/dist/src/prompt-config/defaults/index.js +21 -0
  106. package/dist/src/prompt-config/defaults/index.js.map +1 -0
  107. package/dist/src/prompt-config/defaults/provider-defaults.d.ts +5 -0
  108. package/dist/src/prompt-config/defaults/provider-defaults.js +26 -0
  109. package/dist/src/prompt-config/defaults/provider-defaults.js.map +1 -0
  110. package/dist/src/prompt-config/defaults/providers/gemini/models/gemini-2.5-flash/core.md +10 -0
  111. package/dist/src/prompt-config/defaults/service-defaults.d.ts +5 -0
  112. package/dist/src/prompt-config/defaults/service-defaults.js +52 -0
  113. package/dist/src/prompt-config/defaults/service-defaults.js.map +1 -0
  114. package/dist/src/prompt-config/defaults/tool-defaults.d.ts +5 -0
  115. package/dist/src/prompt-config/defaults/tool-defaults.js +81 -0
  116. package/dist/src/prompt-config/defaults/tool-defaults.js.map +1 -0
  117. package/dist/src/prompt-config/defaults/tools/edit.md +2 -0
  118. package/dist/src/prompt-config/defaults/tools/glob.md +2 -0
  119. package/dist/src/prompt-config/defaults/tools/grep.md +2 -0
  120. package/dist/src/prompt-config/defaults/tools/ls.md +1 -0
  121. package/dist/src/prompt-config/defaults/tools/memory.md +1 -0
  122. package/dist/src/prompt-config/defaults/tools/read-file.md +4 -0
  123. package/dist/src/prompt-config/defaults/tools/read-many-files.md +2 -0
  124. package/dist/src/prompt-config/defaults/tools/shell.md +5 -0
  125. package/dist/src/prompt-config/defaults/tools/todo-read.md +3 -0
  126. package/dist/src/prompt-config/defaults/tools/todo-write.md +50 -0
  127. package/dist/src/prompt-config/defaults/tools/web-fetch.md +3 -0
  128. package/dist/src/prompt-config/defaults/tools/web-search.md +3 -0
  129. package/dist/src/prompt-config/defaults/tools/write-file.md +4 -0
  130. package/dist/src/prompt-config/index.d.ts +16 -0
  131. package/dist/src/prompt-config/index.js +11 -0
  132. package/dist/src/prompt-config/index.js.map +1 -0
  133. package/dist/src/prompt-config/prompt-cache.d.ts +72 -0
  134. package/dist/src/prompt-config/prompt-cache.js +271 -0
  135. package/dist/src/prompt-config/prompt-cache.js.map +1 -0
  136. package/dist/src/prompt-config/prompt-cache.test.d.ts +6 -0
  137. package/dist/src/prompt-config/prompt-cache.test.js +437 -0
  138. package/dist/src/prompt-config/prompt-cache.test.js.map +1 -0
  139. package/dist/src/prompt-config/prompt-installer.d.ts +118 -0
  140. package/dist/src/prompt-config/prompt-installer.js +723 -0
  141. package/dist/src/prompt-config/prompt-installer.js.map +1 -0
  142. package/dist/src/prompt-config/prompt-installer.test.d.ts +7 -0
  143. package/dist/src/prompt-config/prompt-installer.test.js +503 -0
  144. package/dist/src/prompt-config/prompt-installer.test.js.map +1 -0
  145. package/dist/src/prompt-config/prompt-loader.d.ts +49 -0
  146. package/dist/src/prompt-config/prompt-loader.js +331 -0
  147. package/dist/src/prompt-config/prompt-loader.js.map +1 -0
  148. package/dist/src/prompt-config/prompt-loader.test.d.ts +5 -0
  149. package/dist/src/prompt-config/prompt-loader.test.js +413 -0
  150. package/dist/src/prompt-config/prompt-loader.test.js.map +1 -0
  151. package/dist/src/prompt-config/prompt-resolver.d.ts +74 -0
  152. package/dist/src/prompt-config/prompt-resolver.js +600 -0
  153. package/dist/src/prompt-config/prompt-resolver.js.map +1 -0
  154. package/dist/src/prompt-config/prompt-resolver.test.d.ts +1 -0
  155. package/dist/src/prompt-config/prompt-resolver.test.js +529 -0
  156. package/dist/src/prompt-config/prompt-resolver.test.js.map +1 -0
  157. package/dist/src/prompt-config/prompt-service.d.ts +108 -0
  158. package/dist/src/prompt-config/prompt-service.js +435 -0
  159. package/dist/src/prompt-config/prompt-service.js.map +1 -0
  160. package/dist/src/prompt-config/prompt-service.test.d.ts +1 -0
  161. package/dist/src/prompt-config/prompt-service.test.js +811 -0
  162. package/dist/src/prompt-config/prompt-service.test.js.map +1 -0
  163. package/dist/src/prompt-config/types.d.ts +30 -0
  164. package/dist/src/prompt-config/types.js +10 -0
  165. package/dist/src/prompt-config/types.js.map +1 -0
  166. package/dist/src/providers/IProvider.d.ts +10 -0
  167. package/dist/src/providers/anthropic/AnthropicProvider.d.ts +14 -1
  168. package/dist/src/providers/anthropic/AnthropicProvider.js +28 -2
  169. package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -1
  170. package/dist/src/providers/anthropic/AnthropicProvider.modelParams.test.d.ts +1 -0
  171. package/dist/src/providers/anthropic/AnthropicProvider.modelParams.test.js +48 -0
  172. package/dist/src/providers/anthropic/AnthropicProvider.modelParams.test.js.map +1 -0
  173. package/dist/src/providers/anthropic/AnthropicProvider.test.js +2 -1
  174. package/dist/src/providers/anthropic/AnthropicProvider.test.js.map +1 -1
  175. package/dist/src/providers/gemini/GeminiProvider.d.ts +11 -2
  176. package/dist/src/providers/gemini/GeminiProvider.integration.test.js +1 -1
  177. package/dist/src/providers/gemini/GeminiProvider.js +34 -9
  178. package/dist/src/providers/gemini/GeminiProvider.js.map +1 -1
  179. package/dist/src/providers/openai/OpenAIProvider.d.ts +11 -0
  180. package/dist/src/providers/openai/OpenAIProvider.js +100 -31
  181. package/dist/src/providers/openai/OpenAIProvider.js.map +1 -1
  182. package/dist/src/providers/openai/OpenAIProvider.responses.test.js +27 -3
  183. package/dist/src/providers/openai/OpenAIProvider.responses.test.js.map +1 -1
  184. package/dist/src/providers/openai/OpenAIProvider.shouldUseResponses.test.js +2 -1
  185. package/dist/src/providers/openai/OpenAIProvider.shouldUseResponses.test.js.map +1 -1
  186. package/dist/src/providers/openai/OpenAIProvider.stateful.integration.test.js +1 -1
  187. package/dist/src/providers/openai/OpenAIProvider.stateful.integration.test.js.map +1 -1
  188. package/dist/src/providers/openai/OpenAIProvider.test.js +307 -7
  189. package/dist/src/providers/openai/OpenAIProvider.test.js.map +1 -1
  190. package/dist/src/providers/openai/buildResponsesRequest.js +19 -2
  191. package/dist/src/providers/openai/buildResponsesRequest.js.map +1 -1
  192. package/dist/src/providers/test-utils/providerTestConfig.d.ts +21 -0
  193. package/dist/src/providers/test-utils/providerTestConfig.js +23 -0
  194. package/dist/src/providers/test-utils/providerTestConfig.js.map +1 -0
  195. package/dist/src/providers/types/IProviderConfig.d.ts +6 -0
  196. package/dist/src/services/loopDetectionService.d.ts +9 -0
  197. package/dist/src/services/loopDetectionService.js +44 -12
  198. package/dist/src/services/loopDetectionService.js.map +1 -1
  199. package/dist/src/services/shellExecutionService.d.ts +1 -37
  200. package/dist/src/services/shellExecutionService.js +24 -55
  201. package/dist/src/services/shellExecutionService.js.map +1 -1
  202. package/dist/src/{providers/IProviderConfig.js → services/shellExecutionService.multibyte.test.d.ts} +0 -1
  203. package/dist/src/services/shellExecutionService.multibyte.test.js +72 -0
  204. package/dist/src/services/shellExecutionService.multibyte.test.js.map +1 -0
  205. package/dist/src/services/shellExecutionService.test.js +11 -5
  206. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  207. package/dist/src/services/shellExecutionService.windows.multibyte.test.d.ts +6 -0
  208. package/dist/src/services/shellExecutionService.windows.multibyte.test.js +98 -0
  209. package/dist/src/services/shellExecutionService.windows.multibyte.test.js.map +1 -0
  210. package/dist/src/services/shellExecutionService.windows.test.d.ts +6 -0
  211. package/dist/src/services/shellExecutionService.windows.test.js +79 -0
  212. package/dist/src/services/shellExecutionService.windows.test.js.map +1 -0
  213. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +3 -2
  214. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +22 -3
  215. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  216. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +4 -1
  217. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +12 -0
  218. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  219. package/dist/src/telemetry/constants.d.ts +1 -1
  220. package/dist/src/telemetry/constants.js +1 -1
  221. package/dist/src/telemetry/constants.js.map +1 -1
  222. package/dist/src/telemetry/file-exporters.d.ts +2 -2
  223. package/dist/src/telemetry/file-exporters.js +47 -20
  224. package/dist/src/telemetry/file-exporters.js.map +1 -1
  225. package/dist/src/telemetry/loggers.d.ts +2 -2
  226. package/dist/src/telemetry/loggers.js +13 -6
  227. package/dist/src/telemetry/loggers.js.map +1 -1
  228. package/dist/src/telemetry/loggers.test.circular.js +2 -0
  229. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  230. package/dist/src/telemetry/loggers.test.js +8 -3
  231. package/dist/src/telemetry/loggers.test.js.map +1 -1
  232. package/dist/src/telemetry/sdk.d.ts +1 -1
  233. package/dist/src/telemetry/sdk.js +71 -73
  234. package/dist/src/telemetry/sdk.js.map +1 -1
  235. package/dist/src/telemetry/telemetry.test.js +7 -5
  236. package/dist/src/telemetry/telemetry.test.js.map +1 -1
  237. package/dist/src/telemetry/types.d.ts +12 -4
  238. package/dist/src/telemetry/types.js +18 -4
  239. package/dist/src/telemetry/types.js.map +1 -1
  240. package/dist/src/telemetry/uiTelemetry.test.js +3 -0
  241. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  242. package/dist/src/test-utils/mockWorkspaceContext.d.ts +13 -0
  243. package/dist/src/test-utils/mockWorkspaceContext.js +24 -0
  244. package/dist/src/test-utils/mockWorkspaceContext.js.map +1 -0
  245. package/dist/src/tools/edit.js +27 -3
  246. package/dist/src/tools/edit.js.map +1 -1
  247. package/dist/src/tools/edit.test.js +104 -1
  248. package/dist/src/tools/edit.test.js.map +1 -1
  249. package/dist/src/tools/glob.js +53 -17
  250. package/dist/src/tools/glob.js.map +1 -1
  251. package/dist/src/tools/glob.test.js +25 -2
  252. package/dist/src/tools/glob.test.js.map +1 -1
  253. package/dist/src/tools/grep.d.ts +1 -1
  254. package/dist/src/tools/grep.js +81 -29
  255. package/dist/src/tools/grep.js.map +1 -1
  256. package/dist/src/tools/grep.test.js +72 -5
  257. package/dist/src/tools/grep.test.js.map +1 -1
  258. package/dist/src/tools/ls.js +4 -3
  259. package/dist/src/tools/ls.js.map +1 -1
  260. package/dist/src/tools/ls.test.d.ts +6 -0
  261. package/dist/src/tools/ls.test.js +356 -0
  262. package/dist/src/tools/ls.test.js.map +1 -0
  263. package/dist/src/tools/mcp-client.js +32 -11
  264. package/dist/src/tools/mcp-client.js.map +1 -1
  265. package/dist/src/tools/mcp-client.test.js +34 -0
  266. package/dist/src/tools/mcp-client.test.js.map +1 -1
  267. package/dist/src/tools/memoryTool.d.ts +17 -2
  268. package/dist/src/tools/memoryTool.js +130 -13
  269. package/dist/src/tools/memoryTool.js.map +1 -1
  270. package/dist/src/tools/memoryTool.test.js +88 -3
  271. package/dist/src/tools/memoryTool.test.js.map +1 -1
  272. package/dist/src/tools/read-file.js +8 -6
  273. package/dist/src/tools/read-file.js.map +1 -1
  274. package/dist/src/tools/read-file.test.js +30 -2
  275. package/dist/src/tools/read-file.test.js.map +1 -1
  276. package/dist/src/tools/read-many-files.js +22 -12
  277. package/dist/src/tools/read-many-files.js.map +1 -1
  278. package/dist/src/tools/read-many-files.test.js +35 -2
  279. package/dist/src/tools/read-many-files.test.js.map +1 -1
  280. package/dist/src/tools/shell.js +16 -0
  281. package/dist/src/tools/shell.js.map +1 -1
  282. package/dist/src/tools/shell.multibyte.test.d.ts +6 -0
  283. package/dist/src/tools/shell.multibyte.test.js +74 -0
  284. package/dist/src/tools/shell.multibyte.test.js.map +1 -0
  285. package/dist/src/tools/shell.test.js +33 -1
  286. package/dist/src/tools/shell.test.js.map +1 -1
  287. package/dist/src/tools/tool-error.d.ts +22 -0
  288. package/dist/src/tools/tool-error.js +27 -0
  289. package/dist/src/tools/tool-error.js.map +1 -0
  290. package/dist/src/tools/tool-registry.test.js +8 -0
  291. package/dist/src/tools/tool-registry.test.js.map +1 -1
  292. package/dist/src/tools/tools.d.ts +8 -0
  293. package/dist/src/tools/tools.js.map +1 -1
  294. package/dist/src/tools/write-file.js +5 -3
  295. package/dist/src/tools/write-file.js.map +1 -1
  296. package/dist/src/tools/write-file.test.js +36 -2
  297. package/dist/src/tools/write-file.test.js.map +1 -1
  298. package/dist/src/types/modelParams.d.ts +62 -0
  299. package/dist/src/types/modelParams.js +7 -0
  300. package/dist/src/types/modelParams.js.map +1 -0
  301. package/dist/src/utils/bfsFileSearch.test.js +4 -2
  302. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  303. package/dist/src/utils/editCorrector.js +2 -2
  304. package/dist/src/utils/editCorrector.js.map +1 -1
  305. package/dist/src/utils/editor.d.ts +1 -1
  306. package/dist/src/utils/editor.js +9 -0
  307. package/dist/src/utils/editor.js.map +1 -1
  308. package/dist/src/utils/editor.test.js +21 -1
  309. package/dist/src/utils/editor.test.js.map +1 -1
  310. package/dist/src/utils/fileUtils.js +12 -1
  311. package/dist/src/utils/fileUtils.js.map +1 -1
  312. package/dist/src/utils/fileUtils.test.js +29 -1
  313. package/dist/src/utils/fileUtils.test.js.map +1 -1
  314. package/dist/src/utils/flashFallback.integration.test.js +8 -0
  315. package/dist/src/utils/flashFallback.integration.test.js.map +1 -1
  316. package/dist/src/utils/memoryDiscovery.d.ts +1 -1
  317. package/dist/src/utils/memoryDiscovery.js +61 -73
  318. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  319. package/dist/src/utils/memoryDiscovery.test.js +4 -3
  320. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  321. package/dist/src/utils/memoryImportProcessor.d.ts +19 -12
  322. package/dist/src/utils/memoryImportProcessor.js +241 -82
  323. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  324. package/dist/src/utils/memoryImportProcessor.test.js +595 -50
  325. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  326. package/dist/src/utils/nextSpeakerChecker.js +10 -25
  327. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  328. package/dist/src/utils/nextSpeakerChecker.test.js +6 -2
  329. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  330. package/dist/src/utils/sanitization.d.ts +20 -0
  331. package/dist/src/utils/sanitization.js +66 -0
  332. package/dist/src/utils/sanitization.js.map +1 -0
  333. package/dist/src/utils/sanitization.test.d.ts +6 -0
  334. package/dist/src/utils/sanitization.test.js +81 -0
  335. package/dist/src/utils/sanitization.test.js.map +1 -0
  336. package/dist/src/utils/secure-browser-launcher.d.ts +23 -0
  337. package/dist/src/utils/secure-browser-launcher.js +164 -0
  338. package/dist/src/utils/secure-browser-launcher.js.map +1 -0
  339. package/dist/src/utils/secure-browser-launcher.test.d.ts +6 -0
  340. package/dist/src/utils/secure-browser-launcher.test.js +149 -0
  341. package/dist/src/utils/secure-browser-launcher.test.js.map +1 -0
  342. package/dist/src/utils/summarizer.js +2 -2
  343. package/dist/src/utils/summarizer.js.map +1 -1
  344. package/dist/src/utils/unicodeUtils.d.ts +44 -0
  345. package/dist/src/utils/unicodeUtils.js +93 -0
  346. package/dist/src/utils/unicodeUtils.js.map +1 -0
  347. package/dist/src/utils/unicodeUtils.test.d.ts +6 -0
  348. package/dist/src/utils/unicodeUtils.test.js +120 -0
  349. package/dist/src/utils/unicodeUtils.test.js.map +1 -0
  350. package/dist/src/utils/workspaceContext.d.ts +47 -0
  351. package/dist/src/utils/workspaceContext.js +106 -0
  352. package/dist/src/utils/workspaceContext.js.map +1 -0
  353. package/dist/src/utils/workspaceContext.test.d.ts +6 -0
  354. package/dist/src/utils/workspaceContext.test.js +209 -0
  355. package/dist/src/utils/workspaceContext.test.js.map +1 -0
  356. package/package.json +2 -1
  357. package/dist/src/providers/IProviderConfig.d.ts +0 -31
  358. package/dist/src/providers/IProviderConfig.js.map +0 -1
@@ -0,0 +1,723 @@
1
+ /**
2
+ * Prompt Installer - Creates directory structure and installs default prompt files
3
+ * while preserving user customizations.
4
+ *
5
+ * This is a TDD stub implementation. All methods throw "Not implemented" errors.
6
+ */
7
+ import { z } from 'zod';
8
+ import * as fs from 'fs/promises';
9
+ import * as path from 'path';
10
+ import * as os from 'os';
11
+ import { existsSync } from 'fs';
12
+ // Constants
13
+ export const DEFAULT_BASE_DIR = '~/.llxprt/prompts';
14
+ export const REQUIRED_DIRECTORIES = [
15
+ '', // Base directory
16
+ 'env', // Environment-specific prompts
17
+ 'tools', // Tool-specific prompts
18
+ 'providers', // Provider overrides
19
+ ];
20
+ // Schema for defaults map
21
+ export const DefaultsMapSchema = z.record(z.string(), z.string());
22
+ /**
23
+ * PromptInstaller handles installation, validation, and maintenance of prompt files
24
+ */
25
+ export class PromptInstaller {
26
+ /**
27
+ * Install default prompt files
28
+ * @param baseDir - Base directory for prompts (defaults to DEFAULT_BASE_DIR)
29
+ * @param defaults - Map of relative path to file content
30
+ * @param options - Installation options
31
+ * @returns Installation result with success status and details
32
+ */
33
+ async install(baseDir, defaults, options) {
34
+ const installed = [];
35
+ const skipped = [];
36
+ const errors = [];
37
+ // Prepare installation
38
+ let expandedBaseDir = baseDir;
39
+ if (!expandedBaseDir) {
40
+ expandedBaseDir = this.expandPath(DEFAULT_BASE_DIR);
41
+ }
42
+ // Validate baseDir
43
+ if (expandedBaseDir.includes('..') || !path.isAbsolute(expandedBaseDir)) {
44
+ return {
45
+ success: false,
46
+ installed: [],
47
+ skipped: [],
48
+ errors: ['Invalid base directory'],
49
+ baseDir: expandedBaseDir,
50
+ };
51
+ }
52
+ // Create directory structure
53
+ for (const dir of REQUIRED_DIRECTORIES) {
54
+ const fullPath = path.join(expandedBaseDir, dir);
55
+ if (options?.dryRun) {
56
+ if (options?.verbose) {
57
+ console.log('Would create:', fullPath);
58
+ }
59
+ }
60
+ else {
61
+ try {
62
+ await fs.mkdir(fullPath, { recursive: true, mode: 0o755 });
63
+ if (options?.verbose) {
64
+ console.log('Created directory:', fullPath);
65
+ }
66
+ }
67
+ catch (error) {
68
+ const errorMsg = error instanceof Error ? error.message : String(error);
69
+ if (errorMsg.includes('EACCES') ||
70
+ errorMsg.includes('permission denied')) {
71
+ errors.push(`Permission denied: ${fullPath}`);
72
+ }
73
+ else {
74
+ errors.push(`Failed to create directory ${fullPath}: ${errorMsg}`);
75
+ }
76
+ }
77
+ }
78
+ }
79
+ // Install default files
80
+ for (const [relativePath, content] of Object.entries(defaults)) {
81
+ const fullPath = path.join(expandedBaseDir, relativePath);
82
+ const fileDir = path.dirname(fullPath);
83
+ // Create parent directory if needed
84
+ if (!existsSync(fileDir) && !options?.dryRun) {
85
+ try {
86
+ await fs.mkdir(fileDir, { recursive: true, mode: 0o755 });
87
+ }
88
+ catch (error) {
89
+ errors.push(`Failed to create directory ${fileDir}: ${error instanceof Error ? error.message : String(error)}`);
90
+ continue;
91
+ }
92
+ }
93
+ // Check existing file
94
+ if (!options?.dryRun && existsSync(fullPath) && !options?.force) {
95
+ skipped.push(relativePath);
96
+ if (options?.verbose) {
97
+ console.log('Preserving existing:', relativePath);
98
+ }
99
+ continue;
100
+ }
101
+ // Write file
102
+ if (options?.dryRun) {
103
+ if (options?.verbose) {
104
+ console.log('Would write:', fullPath);
105
+ }
106
+ installed.push(relativePath);
107
+ }
108
+ else {
109
+ const tempPath = `${fullPath}.tmp.${Date.now()}.${Math.random().toString(36).substring(7)}`;
110
+ try {
111
+ // Write to temp file first (atomic write)
112
+ await fs.writeFile(tempPath, content, { mode: 0o644 });
113
+ // Rename temp to final - this is atomic and will fail if file exists
114
+ try {
115
+ await fs.rename(tempPath, fullPath);
116
+ installed.push(relativePath);
117
+ if (options?.verbose) {
118
+ console.log('Installed:', relativePath);
119
+ }
120
+ }
121
+ catch (renameError) {
122
+ // If rename failed because file already exists, it's OK (race condition)
123
+ const renameMsg = renameError instanceof Error
124
+ ? renameError.message
125
+ : String(renameError);
126
+ if (renameMsg.includes('EEXIST') || existsSync(fullPath)) {
127
+ skipped.push(relativePath);
128
+ // Clean up temp file
129
+ await fs.unlink(tempPath);
130
+ }
131
+ else {
132
+ throw renameError;
133
+ }
134
+ }
135
+ }
136
+ catch (error) {
137
+ const errorMsg = error instanceof Error ? error.message : String(error);
138
+ if (errorMsg.includes('EACCES') ||
139
+ errorMsg.includes('Permission denied')) {
140
+ errors.push(`Permission denied: ${fullPath}. Try running with elevated permissions or changing the directory ownership.`);
141
+ }
142
+ else if (errorMsg.includes('ENOSPC')) {
143
+ errors.push(`Disk full: Cannot write ${fullPath}. Free up some disk space and try again.`);
144
+ }
145
+ else {
146
+ errors.push(`Failed to write ${fullPath}: ${errorMsg}`);
147
+ }
148
+ // Clean up temp file if it exists
149
+ try {
150
+ await fs.unlink(tempPath);
151
+ }
152
+ catch {
153
+ // Ignore cleanup errors
154
+ }
155
+ }
156
+ }
157
+ }
158
+ // Set permissions on all files (if not dry run)
159
+ if (!options?.dryRun && errors.length === 0) {
160
+ try {
161
+ // Set base directory permissions
162
+ await fs.chmod(expandedBaseDir, 0o755);
163
+ // Set permissions on all subdirectories
164
+ for (const dir of REQUIRED_DIRECTORIES) {
165
+ if (dir !== '') {
166
+ const dirPath = path.join(expandedBaseDir, dir);
167
+ if (existsSync(dirPath)) {
168
+ await fs.chmod(dirPath, 0o755);
169
+ }
170
+ }
171
+ }
172
+ // Set permissions on all installed files
173
+ for (const file of installed) {
174
+ const filePath = path.join(expandedBaseDir, file);
175
+ if (existsSync(filePath)) {
176
+ await fs.chmod(filePath, 0o644);
177
+ }
178
+ }
179
+ }
180
+ catch (error) {
181
+ // Non-critical error, don't fail the installation
182
+ if (options?.verbose) {
183
+ console.log('Could not set permissions:', error);
184
+ }
185
+ }
186
+ }
187
+ return {
188
+ success: errors.length === 0,
189
+ installed,
190
+ skipped,
191
+ errors,
192
+ baseDir: expandedBaseDir,
193
+ };
194
+ }
195
+ /**
196
+ * Uninstall prompt files
197
+ * @param baseDir - Base directory for prompts
198
+ * @param options - Uninstallation options
199
+ * @returns Uninstallation result with removed files
200
+ */
201
+ async uninstall(baseDir, options) {
202
+ const removed = [];
203
+ const errors = [];
204
+ // Validate inputs
205
+ let expandedBaseDir = baseDir;
206
+ if (!expandedBaseDir) {
207
+ expandedBaseDir = this.expandPath(DEFAULT_BASE_DIR);
208
+ }
209
+ // If base directory doesn't exist, return success with empty arrays
210
+ if (!existsSync(expandedBaseDir)) {
211
+ return {
212
+ success: true,
213
+ removed: [],
214
+ errors: [],
215
+ };
216
+ }
217
+ // Build removal list
218
+ const toRemove = [];
219
+ if (options?.removeUserFiles) {
220
+ // Remove all files
221
+ try {
222
+ await this.collectAllFiles(expandedBaseDir, expandedBaseDir, toRemove);
223
+ }
224
+ catch (error) {
225
+ errors.push(`Failed to list files: ${error instanceof Error ? error.message : String(error)}`);
226
+ }
227
+ }
228
+ else {
229
+ // Remove only default files (core.md and files in standard directories)
230
+ const defaultPaths = [
231
+ 'core.md',
232
+ 'env/development.md',
233
+ 'env/dev.md',
234
+ 'tools/git.md',
235
+ 'providers/openai.md',
236
+ ];
237
+ for (const filePath of defaultPaths) {
238
+ const fullPath = path.join(expandedBaseDir, filePath);
239
+ if (existsSync(fullPath)) {
240
+ toRemove.push(filePath);
241
+ }
242
+ }
243
+ }
244
+ // Remove files
245
+ for (const file of toRemove) {
246
+ const fullPath = path.join(expandedBaseDir, file);
247
+ if (options?.dryRun) {
248
+ console.log('Would remove:', fullPath);
249
+ removed.push(file);
250
+ }
251
+ else {
252
+ try {
253
+ await fs.unlink(fullPath);
254
+ removed.push(file);
255
+ }
256
+ catch (error) {
257
+ const errorMsg = error instanceof Error ? error.message : String(error);
258
+ if (errorMsg.includes('EBUSY')) {
259
+ errors.push(`File in use: ${file}. Close any programs using this file and try again.`);
260
+ }
261
+ else if (errorMsg.includes('EACCES') ||
262
+ errorMsg.includes('Permission denied')) {
263
+ errors.push(`Permission denied: ${file}`);
264
+ }
265
+ else if (!errorMsg.includes('ENOENT')) {
266
+ // Ignore "file not found" errors
267
+ errors.push(`Failed to remove ${file}: ${errorMsg}`);
268
+ }
269
+ }
270
+ }
271
+ }
272
+ // Remove empty directories (in reverse order to remove children first)
273
+ if (!options?.dryRun) {
274
+ const dirsToCheck = [...REQUIRED_DIRECTORIES].reverse();
275
+ for (const dir of dirsToCheck) {
276
+ const fullPath = dir === '' ? expandedBaseDir : path.join(expandedBaseDir, dir);
277
+ try {
278
+ const contents = await fs.readdir(fullPath);
279
+ if (contents.length === 0) {
280
+ await fs.rmdir(fullPath);
281
+ removed.push(dir === '' ? 'base directory' : dir);
282
+ }
283
+ }
284
+ catch {
285
+ // Ignore errors when removing directories
286
+ }
287
+ }
288
+ }
289
+ return {
290
+ success: errors.length === 0,
291
+ removed,
292
+ errors,
293
+ };
294
+ }
295
+ /**
296
+ * Helper method to recursively collect all files in a directory
297
+ */
298
+ async collectAllFiles(baseDir, currentDir, files) {
299
+ const entries = await fs.readdir(currentDir, { withFileTypes: true });
300
+ for (const entry of entries) {
301
+ const fullPath = path.join(currentDir, entry.name);
302
+ const relativePath = path.relative(baseDir, fullPath);
303
+ if (entry.isDirectory()) {
304
+ await this.collectAllFiles(baseDir, fullPath, files);
305
+ }
306
+ else if (entry.isFile()) {
307
+ files.push(relativePath);
308
+ }
309
+ }
310
+ }
311
+ /**
312
+ * Validate prompt installation
313
+ * @param baseDir - Base directory to validate
314
+ * @returns Validation result with issues found
315
+ */
316
+ async validate(baseDir) {
317
+ // Setup validation
318
+ let expandedBaseDir = baseDir;
319
+ if (!expandedBaseDir) {
320
+ expandedBaseDir = this.expandPath(DEFAULT_BASE_DIR);
321
+ }
322
+ let isValid = true;
323
+ const errors = [];
324
+ const warnings = [];
325
+ const missing = [];
326
+ // Check base directory
327
+ if (!existsSync(expandedBaseDir)) {
328
+ errors.push('Base directory does not exist');
329
+ isValid = false;
330
+ return {
331
+ isValid,
332
+ errors,
333
+ warnings,
334
+ missing,
335
+ baseDir: expandedBaseDir,
336
+ };
337
+ }
338
+ // Check directory structure
339
+ for (const dir of REQUIRED_DIRECTORIES) {
340
+ if (dir === '')
341
+ continue; // Skip base directory itself
342
+ const fullPath = path.join(expandedBaseDir, dir);
343
+ if (!existsSync(fullPath)) {
344
+ missing.push(dir);
345
+ warnings.push(`Missing directory: ${dir}`);
346
+ }
347
+ }
348
+ // Check required files
349
+ const corePath = path.join(expandedBaseDir, 'core.md');
350
+ if (!existsSync(corePath)) {
351
+ missing.push('core.md');
352
+ errors.push('Missing required core.md');
353
+ isValid = false;
354
+ }
355
+ // Check permissions
356
+ try {
357
+ // Check read permission
358
+ await fs.access(expandedBaseDir, fs.constants.R_OK);
359
+ }
360
+ catch {
361
+ errors.push('Cannot read from directory');
362
+ isValid = false;
363
+ }
364
+ try {
365
+ // Check write permission
366
+ await fs.access(expandedBaseDir, fs.constants.W_OK);
367
+ }
368
+ catch {
369
+ warnings.push('Cannot write to directory');
370
+ }
371
+ // Check file integrity
372
+ if (existsSync(corePath)) {
373
+ try {
374
+ const stats = await fs.stat(corePath);
375
+ if (stats.size === 0) {
376
+ warnings.push('Empty file: core.md');
377
+ }
378
+ // Check if file is readable
379
+ try {
380
+ await fs.access(corePath, fs.constants.R_OK);
381
+ }
382
+ catch {
383
+ errors.push('Cannot read: core.md');
384
+ }
385
+ }
386
+ catch (error) {
387
+ errors.push(`Error checking core.md: ${error instanceof Error ? error.message : String(error)}`);
388
+ }
389
+ }
390
+ // Check other default files if they exist
391
+ const defaultFiles = [
392
+ 'env/development.md',
393
+ 'tools/git.md',
394
+ 'providers/openai.md',
395
+ ];
396
+ for (const file of defaultFiles) {
397
+ const filePath = path.join(expandedBaseDir, file);
398
+ if (existsSync(filePath)) {
399
+ try {
400
+ const stats = await fs.stat(filePath);
401
+ if (stats.size === 0) {
402
+ warnings.push(`Empty file: ${file}`);
403
+ }
404
+ // Check if file is readable
405
+ try {
406
+ await fs.access(filePath, fs.constants.R_OK);
407
+ }
408
+ catch {
409
+ errors.push(`Cannot read: ${file}`);
410
+ }
411
+ }
412
+ catch {
413
+ // Ignore errors for optional files
414
+ }
415
+ }
416
+ }
417
+ return {
418
+ isValid,
419
+ errors,
420
+ warnings,
421
+ missing,
422
+ baseDir: expandedBaseDir,
423
+ };
424
+ }
425
+ /**
426
+ * Repair prompt installation
427
+ * @param baseDir - Base directory to repair
428
+ * @param defaults - Map of default files to restore
429
+ * @param options - Repair options
430
+ * @returns Repair result with fixed issues
431
+ */
432
+ async repair(baseDir, defaults, options) {
433
+ // Run validation first
434
+ const validation = await this.validate(baseDir);
435
+ const expandedBaseDir = validation.baseDir;
436
+ const repaired = [];
437
+ const errors = [];
438
+ // Create base directory if it doesn't exist
439
+ if (!existsSync(expandedBaseDir)) {
440
+ try {
441
+ await fs.mkdir(expandedBaseDir, { recursive: true, mode: 0o755 });
442
+ repaired.push('base directory');
443
+ if (options?.verbose) {
444
+ console.log('Created base directory:', expandedBaseDir);
445
+ }
446
+ }
447
+ catch (error) {
448
+ errors.push(`Failed to create base directory: ${error instanceof Error ? error.message : String(error)}`);
449
+ return {
450
+ success: false,
451
+ repaired,
452
+ errors,
453
+ stillInvalid: validation.errors,
454
+ };
455
+ }
456
+ }
457
+ // Fix missing directories
458
+ for (const missingItem of validation.missing) {
459
+ // Check if it's a directory (from REQUIRED_DIRECTORIES)
460
+ if (REQUIRED_DIRECTORIES.includes(missingItem)) {
461
+ const dirPath = path.join(expandedBaseDir, missingItem);
462
+ try {
463
+ await fs.mkdir(dirPath, { recursive: true, mode: 0o755 });
464
+ repaired.push(missingItem);
465
+ if (options?.verbose) {
466
+ console.log('Created directory:', dirPath);
467
+ }
468
+ }
469
+ catch (error) {
470
+ errors.push(`Failed to create directory ${missingItem}: ${error instanceof Error ? error.message : String(error)}`);
471
+ }
472
+ }
473
+ }
474
+ // Fix missing default files
475
+ for (const missingItem of validation.missing) {
476
+ // Check if it's a file (has content in defaults)
477
+ if (defaults[missingItem]) {
478
+ const filePath = path.join(expandedBaseDir, missingItem);
479
+ const fileDir = path.dirname(filePath);
480
+ // Ensure parent directory exists
481
+ try {
482
+ await fs.mkdir(fileDir, { recursive: true, mode: 0o755 });
483
+ }
484
+ catch (error) {
485
+ errors.push(`Failed to create directory for ${missingItem}: ${error instanceof Error ? error.message : String(error)}`);
486
+ continue;
487
+ }
488
+ // Write the file
489
+ const tempPath = `${filePath}.tmp.${Date.now()}`;
490
+ try {
491
+ await fs.writeFile(tempPath, defaults[missingItem], { mode: 0o644 });
492
+ await fs.rename(tempPath, filePath);
493
+ repaired.push(missingItem);
494
+ if (options?.verbose) {
495
+ console.log('Restored file:', filePath);
496
+ }
497
+ }
498
+ catch (error) {
499
+ errors.push(`Failed to restore ${missingItem}: ${error instanceof Error ? error.message : String(error)}`);
500
+ try {
501
+ await fs.unlink(tempPath);
502
+ }
503
+ catch {
504
+ // Ignore cleanup errors
505
+ }
506
+ }
507
+ }
508
+ }
509
+ // Always fix permissions (even if validation passed)
510
+ let permissionsFixed = false;
511
+ try {
512
+ // Fix directory permissions
513
+ await fs.chmod(expandedBaseDir, 0o755);
514
+ // Fix all file and directory permissions recursively
515
+ await this.fixFilePermissions(expandedBaseDir);
516
+ permissionsFixed = true;
517
+ if (options?.verbose) {
518
+ console.log('Fixed file permissions');
519
+ }
520
+ }
521
+ catch (error) {
522
+ errors.push(`Failed to fix permissions: ${error instanceof Error ? error.message : String(error)}`);
523
+ }
524
+ // If we started with a valid installation, don't report permissions as repaired
525
+ // Only report actual repairs that fixed validation issues
526
+ if (!validation.isValid && permissionsFixed && errors.length === 0) {
527
+ repaired.push('file permissions');
528
+ }
529
+ // Run validation again
530
+ const finalValidation = await this.validate(baseDir);
531
+ return {
532
+ success: finalValidation.isValid && errors.length === 0,
533
+ repaired,
534
+ errors,
535
+ stillInvalid: finalValidation.errors,
536
+ };
537
+ }
538
+ /**
539
+ * Create backup of current prompts
540
+ * @param baseDir - Base directory to backup
541
+ * @param backupPath - Where to save backup
542
+ * @returns Backup result with location and stats
543
+ */
544
+ async backup(baseDir, backupPath) {
545
+ // Validate inputs
546
+ let expandedBaseDir = baseDir;
547
+ if (!expandedBaseDir) {
548
+ expandedBaseDir = this.expandPath(DEFAULT_BASE_DIR);
549
+ }
550
+ if (!existsSync(expandedBaseDir)) {
551
+ return {
552
+ success: false,
553
+ error: 'Nothing to backup',
554
+ };
555
+ }
556
+ if (!backupPath || backupPath.trim() === '') {
557
+ return {
558
+ success: false,
559
+ error: 'Invalid backup path',
560
+ };
561
+ }
562
+ // Create backup
563
+ const now = new Date();
564
+ const year = now.getFullYear();
565
+ const month = String(now.getMonth() + 1).padStart(2, '0');
566
+ const day = String(now.getDate()).padStart(2, '0');
567
+ const hours = String(now.getHours()).padStart(2, '0');
568
+ const minutes = String(now.getMinutes()).padStart(2, '0');
569
+ const seconds = String(now.getSeconds()).padStart(2, '0');
570
+ const timestamp = `${year}${month}${day}_${hours}${minutes}${seconds}`;
571
+ const backupDir = path.join(backupPath, `prompt-backup-${timestamp}`);
572
+ try {
573
+ // Create backup directory
574
+ await fs.mkdir(backupDir, { recursive: true });
575
+ // Copy files
576
+ let fileCount = 0;
577
+ let totalSize = 0;
578
+ await this.copyDirectory(expandedBaseDir, backupDir, async (filePath) => {
579
+ fileCount++;
580
+ const stats = await fs.stat(filePath);
581
+ totalSize += stats.size;
582
+ });
583
+ // Create manifest
584
+ const manifest = {
585
+ backupDate: new Date().toISOString(),
586
+ sourcePath: expandedBaseDir,
587
+ fileCount,
588
+ totalSize,
589
+ };
590
+ await fs.writeFile(path.join(backupDir, 'backup-manifest.json'), JSON.stringify(manifest, null, 2));
591
+ // Verify backup
592
+ const verifyCount = await this.countFiles(backupDir);
593
+ if (verifyCount !== fileCount + 1) {
594
+ // +1 for manifest
595
+ console.warn(`Backup verification warning: expected ${fileCount + 1} files, found ${verifyCount}`);
596
+ }
597
+ return {
598
+ success: true,
599
+ backupPath: backupDir,
600
+ fileCount,
601
+ totalSize,
602
+ };
603
+ }
604
+ catch (error) {
605
+ const errorMsg = error instanceof Error ? error.message : String(error);
606
+ // Clean up partial backup on error
607
+ try {
608
+ await fs.rm(backupDir, { recursive: true, force: true });
609
+ }
610
+ catch {
611
+ // Ignore cleanup errors
612
+ }
613
+ if (errorMsg.includes('ENOSPC')) {
614
+ return {
615
+ success: false,
616
+ error: 'Insufficient space: Not enough disk space for backup. Try a different location.',
617
+ };
618
+ }
619
+ else if (errorMsg.includes('EACCES') ||
620
+ errorMsg.includes('Permission denied')) {
621
+ return {
622
+ success: false,
623
+ error: `Permission denied: Cannot write to backup location. Try a different location or check permissions.`,
624
+ };
625
+ }
626
+ return {
627
+ success: false,
628
+ error: `Backup failed: ${errorMsg}`,
629
+ };
630
+ }
631
+ }
632
+ /**
633
+ * Helper method to copy a directory recursively
634
+ */
635
+ async copyDirectory(source, dest, onFile) {
636
+ await fs.mkdir(dest, { recursive: true });
637
+ const entries = await fs.readdir(source, { withFileTypes: true });
638
+ for (const entry of entries) {
639
+ const sourcePath = path.join(source, entry.name);
640
+ const destPath = path.join(dest, entry.name);
641
+ if (entry.isDirectory()) {
642
+ await this.copyDirectory(sourcePath, destPath, onFile);
643
+ }
644
+ else if (entry.isFile()) {
645
+ await fs.copyFile(sourcePath, destPath);
646
+ await fs.chmod(destPath, 0o644);
647
+ if (onFile) {
648
+ await onFile(sourcePath);
649
+ }
650
+ }
651
+ }
652
+ }
653
+ /**
654
+ * Helper method to count files in a directory
655
+ */
656
+ async countFiles(dir) {
657
+ let count = 0;
658
+ const entries = await fs.readdir(dir, { withFileTypes: true });
659
+ for (const entry of entries) {
660
+ if (entry.isDirectory()) {
661
+ count += await this.countFiles(path.join(dir, entry.name));
662
+ }
663
+ else if (entry.isFile()) {
664
+ count++;
665
+ }
666
+ }
667
+ return count;
668
+ }
669
+ /**
670
+ * Helper method to fix file permissions recursively
671
+ */
672
+ async fixFilePermissions(dir) {
673
+ try {
674
+ const entries = await fs.readdir(dir, { withFileTypes: true });
675
+ for (const entry of entries) {
676
+ const fullPath = path.join(dir, entry.name);
677
+ try {
678
+ if (entry.isDirectory()) {
679
+ await fs.chmod(fullPath, 0o755);
680
+ await this.fixFilePermissions(fullPath);
681
+ }
682
+ else if (entry.isFile()) {
683
+ await fs.chmod(fullPath, 0o644);
684
+ }
685
+ }
686
+ catch {
687
+ // Silently continue with other files - some filesystems don't support chmod
688
+ }
689
+ }
690
+ }
691
+ catch {
692
+ // Silently continue - permissions might not be changeable in some environments
693
+ }
694
+ }
695
+ /**
696
+ * Expand path with home directory and environment variables
697
+ * @param path - Path to expand
698
+ * @returns Expanded absolute path
699
+ */
700
+ expandPath(inputPath) {
701
+ // Handle null or empty input
702
+ if (!inputPath) {
703
+ return '';
704
+ }
705
+ let expandedPath = inputPath;
706
+ // Expand home directory
707
+ if (expandedPath.startsWith('~')) {
708
+ const homeDir = os.homedir();
709
+ expandedPath = expandedPath.replace(/^~/, homeDir);
710
+ }
711
+ // Expand environment variables with curly braces ${VAR}
712
+ expandedPath = expandedPath.replace(/\$\{([^}]+)\}/g, (match, varName) => process.env[varName] || match);
713
+ // Expand environment variables without curly braces $VAR
714
+ expandedPath = expandedPath.replace(/\$([A-Za-z_][A-Za-z0-9_]*)/g, (match, varName) => process.env[varName] || match);
715
+ // Resolve to absolute path
716
+ if (!path.isAbsolute(expandedPath)) {
717
+ expandedPath = path.resolve(expandedPath);
718
+ }
719
+ // Normalize path (remove redundant separators, resolve . and ..)
720
+ return path.normalize(expandedPath);
721
+ }
722
+ }
723
+ //# sourceMappingURL=prompt-installer.js.map