nova-terminal-ai 0.3.4

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 (649) hide show
  1. package/README.md +84 -0
  2. package/bin/nova +38 -0
  3. package/bin/nova.js +11 -0
  4. package/dist/commands/SmartCompletion.d.ts +71 -0
  5. package/dist/commands/SmartCompletion.d.ts.map +1 -0
  6. package/dist/commands/SmartCompletion.js +377 -0
  7. package/dist/commands/SmartCompletion.js.map +1 -0
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.d.ts.map +1 -0
  10. package/dist/index.js +5 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/packages/cli/src/commands/SmartCompletion.d.ts +71 -0
  13. package/dist/packages/cli/src/commands/SmartCompletion.d.ts.map +1 -0
  14. package/dist/packages/cli/src/commands/SmartCompletion.js +377 -0
  15. package/dist/packages/cli/src/commands/SmartCompletion.js.map +1 -0
  16. package/dist/packages/cli/src/index.d.ts +2 -0
  17. package/dist/packages/cli/src/index.d.ts.map +1 -0
  18. package/dist/packages/cli/src/index.js +5 -0
  19. package/dist/packages/cli/src/index.js.map +1 -0
  20. package/dist/packages/cli/src/startup/IFlowRepl.d.ts +50 -0
  21. package/dist/packages/cli/src/startup/IFlowRepl.d.ts.map +1 -0
  22. package/dist/packages/cli/src/startup/IFlowRepl.js +178 -0
  23. package/dist/packages/cli/src/startup/IFlowRepl.js.map +1 -0
  24. package/dist/packages/cli/src/startup/InkBasedRepl.d.ts +151 -0
  25. package/dist/packages/cli/src/startup/InkBasedRepl.d.ts.map +1 -0
  26. package/dist/packages/cli/src/startup/InkBasedRepl.js +1415 -0
  27. package/dist/packages/cli/src/startup/InkBasedRepl.js.map +1 -0
  28. package/dist/packages/cli/src/startup/InteractiveRepl.d.ts +141 -0
  29. package/dist/packages/cli/src/startup/InteractiveRepl.d.ts.map +1 -0
  30. package/dist/packages/cli/src/startup/InteractiveRepl.js +2561 -0
  31. package/dist/packages/cli/src/startup/InteractiveRepl.js.map +1 -0
  32. package/dist/packages/cli/src/startup/NovaApp.d.ts +57 -0
  33. package/dist/packages/cli/src/startup/NovaApp.d.ts.map +1 -0
  34. package/dist/packages/cli/src/startup/NovaApp.js +1978 -0
  35. package/dist/packages/cli/src/startup/NovaApp.js.map +1 -0
  36. package/dist/packages/cli/src/startup/index.d.ts +5 -0
  37. package/dist/packages/cli/src/startup/index.d.ts.map +1 -0
  38. package/dist/packages/cli/src/startup/index.js +4 -0
  39. package/dist/packages/cli/src/startup/index.js.map +1 -0
  40. package/dist/packages/cli/src/startup/parseArgs.d.ts +47 -0
  41. package/dist/packages/cli/src/startup/parseArgs.d.ts.map +1 -0
  42. package/dist/packages/cli/src/startup/parseArgs.js +262 -0
  43. package/dist/packages/cli/src/startup/parseArgs.js.map +1 -0
  44. package/dist/packages/cli/src/ui/IFlowDropdown.d.ts +63 -0
  45. package/dist/packages/cli/src/ui/IFlowDropdown.d.ts.map +1 -0
  46. package/dist/packages/cli/src/ui/IFlowDropdown.js +362 -0
  47. package/dist/packages/cli/src/ui/IFlowDropdown.js.map +1 -0
  48. package/dist/packages/cli/src/ui/ModernReplUI.d.ts +55 -0
  49. package/dist/packages/cli/src/ui/ModernReplUI.d.ts.map +1 -0
  50. package/dist/packages/cli/src/ui/ModernReplUI.js +207 -0
  51. package/dist/packages/cli/src/ui/ModernReplUI.js.map +1 -0
  52. package/dist/packages/cli/src/ui/SimpleSelector2.d.ts +28 -0
  53. package/dist/packages/cli/src/ui/SimpleSelector2.d.ts.map +1 -0
  54. package/dist/packages/cli/src/ui/SimpleSelector2.js +181 -0
  55. package/dist/packages/cli/src/ui/SimpleSelector2.js.map +1 -0
  56. package/dist/packages/cli/src/ui/components/ActiveCursor.d.ts +128 -0
  57. package/dist/packages/cli/src/ui/components/ActiveCursor.d.ts.map +1 -0
  58. package/dist/packages/cli/src/ui/components/ActiveCursor.js +273 -0
  59. package/dist/packages/cli/src/ui/components/ActiveCursor.js.map +1 -0
  60. package/dist/packages/cli/src/ui/components/ConfirmDialog.d.ts +51 -0
  61. package/dist/packages/cli/src/ui/components/ConfirmDialog.d.ts.map +1 -0
  62. package/dist/packages/cli/src/ui/components/ConfirmDialog.js +147 -0
  63. package/dist/packages/cli/src/ui/components/ConfirmDialog.js.map +1 -0
  64. package/dist/packages/cli/src/ui/components/ErrorPanel.d.ts +33 -0
  65. package/dist/packages/cli/src/ui/components/ErrorPanel.d.ts.map +1 -0
  66. package/dist/packages/cli/src/ui/components/ErrorPanel.js +309 -0
  67. package/dist/packages/cli/src/ui/components/ErrorPanel.js.map +1 -0
  68. package/dist/packages/cli/src/ui/components/InkAppRunner.d.ts +18 -0
  69. package/dist/packages/cli/src/ui/components/InkAppRunner.d.ts.map +1 -0
  70. package/dist/packages/cli/src/ui/components/InkAppRunner.js +33 -0
  71. package/dist/packages/cli/src/ui/components/InkAppRunner.js.map +1 -0
  72. package/dist/packages/cli/src/ui/components/InkComponents.d.ts +126 -0
  73. package/dist/packages/cli/src/ui/components/InkComponents.d.ts.map +1 -0
  74. package/dist/packages/cli/src/ui/components/InkComponents.js +216 -0
  75. package/dist/packages/cli/src/ui/components/InkComponents.js.map +1 -0
  76. package/dist/packages/cli/src/ui/components/NovaInkApp.d.ts +11 -0
  77. package/dist/packages/cli/src/ui/components/NovaInkApp.d.ts.map +1 -0
  78. package/dist/packages/cli/src/ui/components/NovaInkApp.js +148 -0
  79. package/dist/packages/cli/src/ui/components/NovaInkApp.js.map +1 -0
  80. package/dist/packages/cli/src/ui/components/ProgressBar.d.ts +65 -0
  81. package/dist/packages/cli/src/ui/components/ProgressBar.d.ts.map +1 -0
  82. package/dist/packages/cli/src/ui/components/ProgressBar.js +135 -0
  83. package/dist/packages/cli/src/ui/components/ProgressBar.js.map +1 -0
  84. package/dist/packages/cli/src/ui/components/ProgressIndicator.d.ts +41 -0
  85. package/dist/packages/cli/src/ui/components/ProgressIndicator.d.ts.map +1 -0
  86. package/dist/packages/cli/src/ui/components/ProgressIndicator.js +235 -0
  87. package/dist/packages/cli/src/ui/components/ProgressIndicator.js.map +1 -0
  88. package/dist/packages/cli/src/ui/components/QuickActions.d.ts +36 -0
  89. package/dist/packages/cli/src/ui/components/QuickActions.d.ts.map +1 -0
  90. package/dist/packages/cli/src/ui/components/QuickActions.js +328 -0
  91. package/dist/packages/cli/src/ui/components/QuickActions.js.map +1 -0
  92. package/dist/packages/cli/src/ui/components/SimpleErrorPanel.d.ts +16 -0
  93. package/dist/packages/cli/src/ui/components/SimpleErrorPanel.d.ts.map +1 -0
  94. package/dist/packages/cli/src/ui/components/SimpleErrorPanel.js +193 -0
  95. package/dist/packages/cli/src/ui/components/SimpleErrorPanel.js.map +1 -0
  96. package/dist/packages/cli/src/ui/components/StatusBar.d.ts +30 -0
  97. package/dist/packages/cli/src/ui/components/StatusBar.d.ts.map +1 -0
  98. package/dist/packages/cli/src/ui/components/StatusBar.js +154 -0
  99. package/dist/packages/cli/src/ui/components/StatusBar.js.map +1 -0
  100. package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.d.ts +109 -0
  101. package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.d.ts.map +1 -0
  102. package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.js +335 -0
  103. package/dist/packages/cli/src/ui/components/ThinkingBlockRenderer.js.map +1 -0
  104. package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.d.ts +59 -0
  105. package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.d.ts.map +1 -0
  106. package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.js +172 -0
  107. package/dist/packages/cli/src/ui/components/ThinkingContentDisplay.js.map +1 -0
  108. package/dist/packages/cli/src/ui/components/TodoProgressPanel.d.ts +91 -0
  109. package/dist/packages/cli/src/ui/components/TodoProgressPanel.d.ts.map +1 -0
  110. package/dist/packages/cli/src/ui/components/TodoProgressPanel.js +284 -0
  111. package/dist/packages/cli/src/ui/components/TodoProgressPanel.js.map +1 -0
  112. package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.d.ts +89 -0
  113. package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.d.ts.map +1 -0
  114. package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.js +246 -0
  115. package/dist/packages/cli/src/ui/components/ToolCallStatusDisplay.js.map +1 -0
  116. package/dist/packages/cli/src/ui/components/UserMessageHighlight.d.ts +48 -0
  117. package/dist/packages/cli/src/ui/components/UserMessageHighlight.d.ts.map +1 -0
  118. package/dist/packages/cli/src/ui/components/UserMessageHighlight.js +196 -0
  119. package/dist/packages/cli/src/ui/components/UserMessageHighlight.js.map +1 -0
  120. package/dist/packages/cli/src/ui/components/index.d.ts +17 -0
  121. package/dist/packages/cli/src/ui/components/index.d.ts.map +1 -0
  122. package/dist/packages/cli/src/ui/components/index.js +18 -0
  123. package/dist/packages/cli/src/ui/components/index.js.map +1 -0
  124. package/dist/packages/cli/src/ui/ink-prototype.d.ts +3 -0
  125. package/dist/packages/cli/src/ui/ink-prototype.d.ts.map +1 -0
  126. package/dist/packages/cli/src/ui/ink-prototype.js +160 -0
  127. package/dist/packages/cli/src/ui/ink-prototype.js.map +1 -0
  128. package/dist/packages/cli/src/utils/CliUI.d.ts +163 -0
  129. package/dist/packages/cli/src/utils/CliUI.d.ts.map +1 -0
  130. package/dist/packages/cli/src/utils/CliUI.js +292 -0
  131. package/dist/packages/cli/src/utils/CliUI.js.map +1 -0
  132. package/dist/packages/cli/src/utils/CompletionHelper.d.ts +112 -0
  133. package/dist/packages/cli/src/utils/CompletionHelper.d.ts.map +1 -0
  134. package/dist/packages/cli/src/utils/CompletionHelper.js +304 -0
  135. package/dist/packages/cli/src/utils/CompletionHelper.js.map +1 -0
  136. package/dist/packages/cli/src/utils/EnhancedCompleter.d.ts +107 -0
  137. package/dist/packages/cli/src/utils/EnhancedCompleter.d.ts.map +1 -0
  138. package/dist/packages/cli/src/utils/EnhancedCompleter.js +428 -0
  139. package/dist/packages/cli/src/utils/EnhancedCompleter.js.map +1 -0
  140. package/dist/packages/cli/src/utils/ErrorEnhancer.d.ts +103 -0
  141. package/dist/packages/cli/src/utils/ErrorEnhancer.d.ts.map +1 -0
  142. package/dist/packages/cli/src/utils/ErrorEnhancer.js +350 -0
  143. package/dist/packages/cli/src/utils/ErrorEnhancer.js.map +1 -0
  144. package/dist/packages/cli/src/utils/OutputFormatter.d.ts +65 -0
  145. package/dist/packages/cli/src/utils/OutputFormatter.d.ts.map +1 -0
  146. package/dist/packages/cli/src/utils/OutputFormatter.js +145 -0
  147. package/dist/packages/cli/src/utils/OutputFormatter.js.map +1 -0
  148. package/dist/packages/cli/src/utils/index.d.ts +5 -0
  149. package/dist/packages/cli/src/utils/index.d.ts.map +1 -0
  150. package/dist/packages/cli/src/utils/index.js +8 -0
  151. package/dist/packages/cli/src/utils/index.js.map +1 -0
  152. package/dist/packages/cli/tsconfig.tsbuildinfo +1 -0
  153. package/dist/packages/core/src/agents/AgentOrchestrator.d.ts +147 -0
  154. package/dist/packages/core/src/agents/AgentOrchestrator.d.ts.map +1 -0
  155. package/dist/packages/core/src/agents/AgentOrchestrator.js +358 -0
  156. package/dist/packages/core/src/agents/AgentOrchestrator.js.map +1 -0
  157. package/dist/packages/core/src/agents/index.d.ts +3 -0
  158. package/dist/packages/core/src/agents/index.d.ts.map +1 -0
  159. package/dist/packages/core/src/agents/index.js +5 -0
  160. package/dist/packages/core/src/agents/index.js.map +1 -0
  161. package/dist/packages/core/src/analysis/ProjectAnalyzer.d.ts +95 -0
  162. package/dist/packages/core/src/analysis/ProjectAnalyzer.d.ts.map +1 -0
  163. package/dist/packages/core/src/analysis/ProjectAnalyzer.js +656 -0
  164. package/dist/packages/core/src/analysis/ProjectAnalyzer.js.map +1 -0
  165. package/dist/packages/core/src/audit/AuditLogger.d.ts +140 -0
  166. package/dist/packages/core/src/audit/AuditLogger.d.ts.map +1 -0
  167. package/dist/packages/core/src/audit/AuditLogger.js +357 -0
  168. package/dist/packages/core/src/audit/AuditLogger.js.map +1 -0
  169. package/dist/packages/core/src/audit/index.d.ts +3 -0
  170. package/dist/packages/core/src/audit/index.d.ts.map +1 -0
  171. package/dist/packages/core/src/audit/index.js +5 -0
  172. package/dist/packages/core/src/audit/index.js.map +1 -0
  173. package/dist/packages/core/src/auth/AuthManager.d.ts +38 -0
  174. package/dist/packages/core/src/auth/AuthManager.d.ts.map +1 -0
  175. package/dist/packages/core/src/auth/AuthManager.js +120 -0
  176. package/dist/packages/core/src/auth/AuthManager.js.map +1 -0
  177. package/dist/packages/core/src/auth/index.d.ts +3 -0
  178. package/dist/packages/core/src/auth/index.d.ts.map +1 -0
  179. package/dist/packages/core/src/auth/index.js +2 -0
  180. package/dist/packages/core/src/auth/index.js.map +1 -0
  181. package/dist/packages/core/src/config/ConfigManager.d.ts +47 -0
  182. package/dist/packages/core/src/config/ConfigManager.d.ts.map +1 -0
  183. package/dist/packages/core/src/config/ConfigManager.js +1197 -0
  184. package/dist/packages/core/src/config/ConfigManager.js.map +1 -0
  185. package/dist/packages/core/src/config/index.d.ts +2 -0
  186. package/dist/packages/core/src/config/index.d.ts.map +1 -0
  187. package/dist/packages/core/src/config/index.js +2 -0
  188. package/dist/packages/core/src/config/index.js.map +1 -0
  189. package/dist/packages/core/src/context/ContextBuilder.d.ts +39 -0
  190. package/dist/packages/core/src/context/ContextBuilder.d.ts.map +1 -0
  191. package/dist/packages/core/src/context/ContextBuilder.js +132 -0
  192. package/dist/packages/core/src/context/ContextBuilder.js.map +1 -0
  193. package/dist/packages/core/src/context/ContextCompressor.d.ts +147 -0
  194. package/dist/packages/core/src/context/ContextCompressor.d.ts.map +1 -0
  195. package/dist/packages/core/src/context/ContextCompressor.js +451 -0
  196. package/dist/packages/core/src/context/ContextCompressor.js.map +1 -0
  197. package/dist/packages/core/src/context/LayeredMemoryManager.d.ts +160 -0
  198. package/dist/packages/core/src/context/LayeredMemoryManager.d.ts.map +1 -0
  199. package/dist/packages/core/src/context/LayeredMemoryManager.js +505 -0
  200. package/dist/packages/core/src/context/LayeredMemoryManager.js.map +1 -0
  201. package/dist/packages/core/src/context/MemoryDiscovery.d.ts +33 -0
  202. package/dist/packages/core/src/context/MemoryDiscovery.d.ts.map +1 -0
  203. package/dist/packages/core/src/context/MemoryDiscovery.js +146 -0
  204. package/dist/packages/core/src/context/MemoryDiscovery.js.map +1 -0
  205. package/dist/packages/core/src/context/defaultSystemPrompt.d.ts +12 -0
  206. package/dist/packages/core/src/context/defaultSystemPrompt.d.ts.map +1 -0
  207. package/dist/packages/core/src/context/defaultSystemPrompt.js +32 -0
  208. package/dist/packages/core/src/context/defaultSystemPrompt.js.map +1 -0
  209. package/dist/packages/core/src/context/index.d.ts +9 -0
  210. package/dist/packages/core/src/context/index.d.ts.map +1 -0
  211. package/dist/packages/core/src/context/index.js +5 -0
  212. package/dist/packages/core/src/context/index.js.map +1 -0
  213. package/dist/packages/core/src/extensions/SkillGenerator.d.ts +77 -0
  214. package/dist/packages/core/src/extensions/SkillGenerator.d.ts.map +1 -0
  215. package/dist/packages/core/src/extensions/SkillGenerator.js +323 -0
  216. package/dist/packages/core/src/extensions/SkillGenerator.js.map +1 -0
  217. package/dist/packages/core/src/extensions/SkillInstaller.d.ts +74 -0
  218. package/dist/packages/core/src/extensions/SkillInstaller.d.ts.map +1 -0
  219. package/dist/packages/core/src/extensions/SkillInstaller.js +216 -0
  220. package/dist/packages/core/src/extensions/SkillInstaller.js.map +1 -0
  221. package/dist/packages/core/src/extensions/SkillRegistry.d.ts +99 -0
  222. package/dist/packages/core/src/extensions/SkillRegistry.d.ts.map +1 -0
  223. package/dist/packages/core/src/extensions/SkillRegistry.js +263 -0
  224. package/dist/packages/core/src/extensions/SkillRegistry.js.map +1 -0
  225. package/dist/packages/core/src/extensions/SkillValidator.d.ts +51 -0
  226. package/dist/packages/core/src/extensions/SkillValidator.d.ts.map +1 -0
  227. package/dist/packages/core/src/extensions/SkillValidator.js +465 -0
  228. package/dist/packages/core/src/extensions/SkillValidator.js.map +1 -0
  229. package/dist/packages/core/src/extensions/index.d.ts +11 -0
  230. package/dist/packages/core/src/extensions/index.d.ts.map +1 -0
  231. package/dist/packages/core/src/extensions/index.js +8 -0
  232. package/dist/packages/core/src/extensions/index.js.map +1 -0
  233. package/dist/packages/core/src/index.d.ts +14 -0
  234. package/dist/packages/core/src/index.d.ts.map +1 -0
  235. package/dist/packages/core/src/index.js +30 -0
  236. package/dist/packages/core/src/index.js.map +1 -0
  237. package/dist/packages/core/src/mcp/McpManager.d.ts +94 -0
  238. package/dist/packages/core/src/mcp/McpManager.d.ts.map +1 -0
  239. package/dist/packages/core/src/mcp/McpManager.js +494 -0
  240. package/dist/packages/core/src/mcp/McpManager.js.map +1 -0
  241. package/dist/packages/core/src/mcp/index.d.ts +2 -0
  242. package/dist/packages/core/src/mcp/index.d.ts.map +1 -0
  243. package/dist/packages/core/src/mcp/index.js +3 -0
  244. package/dist/packages/core/src/mcp/index.js.map +1 -0
  245. package/dist/packages/core/src/model/ModelClient.d.ts +40 -0
  246. package/dist/packages/core/src/model/ModelClient.d.ts.map +1 -0
  247. package/dist/packages/core/src/model/ModelClient.js +163 -0
  248. package/dist/packages/core/src/model/ModelClient.js.map +1 -0
  249. package/dist/packages/core/src/model/ModelConnectionTester.d.ts +58 -0
  250. package/dist/packages/core/src/model/ModelConnectionTester.d.ts.map +1 -0
  251. package/dist/packages/core/src/model/ModelConnectionTester.js +311 -0
  252. package/dist/packages/core/src/model/ModelConnectionTester.js.map +1 -0
  253. package/dist/packages/core/src/model/ModelValidator.d.ts +39 -0
  254. package/dist/packages/core/src/model/ModelValidator.d.ts.map +1 -0
  255. package/dist/packages/core/src/model/ModelValidator.js +296 -0
  256. package/dist/packages/core/src/model/ModelValidator.js.map +1 -0
  257. package/dist/packages/core/src/model/index.d.ts +7 -0
  258. package/dist/packages/core/src/model/index.d.ts.map +1 -0
  259. package/dist/packages/core/src/model/index.js +5 -0
  260. package/dist/packages/core/src/model/index.js.map +1 -0
  261. package/dist/packages/core/src/model/providers/AnthropicProvider.d.ts +25 -0
  262. package/dist/packages/core/src/model/providers/AnthropicProvider.d.ts.map +1 -0
  263. package/dist/packages/core/src/model/providers/AnthropicProvider.js +258 -0
  264. package/dist/packages/core/src/model/providers/AnthropicProvider.js.map +1 -0
  265. package/dist/packages/core/src/model/providers/CodingPlanProvider.d.ts +66 -0
  266. package/dist/packages/core/src/model/providers/CodingPlanProvider.d.ts.map +1 -0
  267. package/dist/packages/core/src/model/providers/CodingPlanProvider.js +161 -0
  268. package/dist/packages/core/src/model/providers/CodingPlanProvider.js.map +1 -0
  269. package/dist/packages/core/src/model/providers/OllamaCloudProvider.d.ts +38 -0
  270. package/dist/packages/core/src/model/providers/OllamaCloudProvider.d.ts.map +1 -0
  271. package/dist/packages/core/src/model/providers/OllamaCloudProvider.js +365 -0
  272. package/dist/packages/core/src/model/providers/OllamaCloudProvider.js.map +1 -0
  273. package/dist/packages/core/src/model/providers/OllamaManager.d.ts +72 -0
  274. package/dist/packages/core/src/model/providers/OllamaManager.d.ts.map +1 -0
  275. package/dist/packages/core/src/model/providers/OllamaManager.js +144 -0
  276. package/dist/packages/core/src/model/providers/OllamaManager.js.map +1 -0
  277. package/dist/packages/core/src/model/providers/OllamaProvider.d.ts +23 -0
  278. package/dist/packages/core/src/model/providers/OllamaProvider.d.ts.map +1 -0
  279. package/dist/packages/core/src/model/providers/OllamaProvider.js +56 -0
  280. package/dist/packages/core/src/model/providers/OllamaProvider.js.map +1 -0
  281. package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.d.ts +53 -0
  282. package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.d.ts.map +1 -0
  283. package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.js +383 -0
  284. package/dist/packages/core/src/model/providers/OpenAICompatibleProvider.js.map +1 -0
  285. package/dist/packages/core/src/model/providers/OpenAIProvider.d.ts +12 -0
  286. package/dist/packages/core/src/model/providers/OpenAIProvider.d.ts.map +1 -0
  287. package/dist/packages/core/src/model/providers/OpenAIProvider.js +19 -0
  288. package/dist/packages/core/src/model/providers/OpenAIProvider.js.map +1 -0
  289. package/dist/packages/core/src/model/providers/index.d.ts +13 -0
  290. package/dist/packages/core/src/model/providers/index.d.ts.map +1 -0
  291. package/dist/packages/core/src/model/providers/index.js +7 -0
  292. package/dist/packages/core/src/model/providers/index.js.map +1 -0
  293. package/dist/packages/core/src/model/types.d.ts +81 -0
  294. package/dist/packages/core/src/model/types.d.ts.map +1 -0
  295. package/dist/packages/core/src/model/types.js +12 -0
  296. package/dist/packages/core/src/model/types.js.map +1 -0
  297. package/dist/packages/core/src/security/ApprovalManager.d.ts +56 -0
  298. package/dist/packages/core/src/security/ApprovalManager.d.ts.map +1 -0
  299. package/dist/packages/core/src/security/ApprovalManager.js +122 -0
  300. package/dist/packages/core/src/security/ApprovalManager.js.map +1 -0
  301. package/dist/packages/core/src/security/FileFilter.d.ts +47 -0
  302. package/dist/packages/core/src/security/FileFilter.d.ts.map +1 -0
  303. package/dist/packages/core/src/security/FileFilter.js +111 -0
  304. package/dist/packages/core/src/security/FileFilter.js.map +1 -0
  305. package/dist/packages/core/src/security/HookExecutor.d.ts +37 -0
  306. package/dist/packages/core/src/security/HookExecutor.d.ts.map +1 -0
  307. package/dist/packages/core/src/security/HookExecutor.js +142 -0
  308. package/dist/packages/core/src/security/HookExecutor.js.map +1 -0
  309. package/dist/packages/core/src/security/SandboxExecutor.d.ts +90 -0
  310. package/dist/packages/core/src/security/SandboxExecutor.d.ts.map +1 -0
  311. package/dist/packages/core/src/security/SandboxExecutor.js +345 -0
  312. package/dist/packages/core/src/security/SandboxExecutor.js.map +1 -0
  313. package/dist/packages/core/src/security/index.d.ts +8 -0
  314. package/dist/packages/core/src/security/index.d.ts.map +1 -0
  315. package/dist/packages/core/src/security/index.js +6 -0
  316. package/dist/packages/core/src/security/index.js.map +1 -0
  317. package/dist/packages/core/src/session/AgentLoop.d.ts +75 -0
  318. package/dist/packages/core/src/session/AgentLoop.d.ts.map +1 -0
  319. package/dist/packages/core/src/session/AgentLoop.js +381 -0
  320. package/dist/packages/core/src/session/AgentLoop.js.map +1 -0
  321. package/dist/packages/core/src/session/SessionManager.d.ts +96 -0
  322. package/dist/packages/core/src/session/SessionManager.d.ts.map +1 -0
  323. package/dist/packages/core/src/session/SessionManager.js +390 -0
  324. package/dist/packages/core/src/session/SessionManager.js.map +1 -0
  325. package/dist/packages/core/src/session/index.d.ts +4 -0
  326. package/dist/packages/core/src/session/index.d.ts.map +1 -0
  327. package/dist/packages/core/src/session/index.js +3 -0
  328. package/dist/packages/core/src/session/index.js.map +1 -0
  329. package/dist/packages/core/src/telemetry/Telemetry.d.ts +25 -0
  330. package/dist/packages/core/src/telemetry/Telemetry.d.ts.map +1 -0
  331. package/dist/packages/core/src/telemetry/Telemetry.js +73 -0
  332. package/dist/packages/core/src/telemetry/Telemetry.js.map +1 -0
  333. package/dist/packages/core/src/telemetry/TelemetryService.d.ts +152 -0
  334. package/dist/packages/core/src/telemetry/TelemetryService.d.ts.map +1 -0
  335. package/dist/packages/core/src/telemetry/TelemetryService.js +410 -0
  336. package/dist/packages/core/src/telemetry/TelemetryService.js.map +1 -0
  337. package/dist/packages/core/src/telemetry/index.d.ts +5 -0
  338. package/dist/packages/core/src/telemetry/index.d.ts.map +1 -0
  339. package/dist/packages/core/src/telemetry/index.js +3 -0
  340. package/dist/packages/core/src/telemetry/index.js.map +1 -0
  341. package/dist/packages/core/src/testing/AutoFixer.d.ts +98 -0
  342. package/dist/packages/core/src/testing/AutoFixer.d.ts.map +1 -0
  343. package/dist/packages/core/src/testing/AutoFixer.js +262 -0
  344. package/dist/packages/core/src/testing/AutoFixer.js.map +1 -0
  345. package/dist/packages/core/src/testing/ErrorAnalyzer.d.ts +74 -0
  346. package/dist/packages/core/src/testing/ErrorAnalyzer.d.ts.map +1 -0
  347. package/dist/packages/core/src/testing/ErrorAnalyzer.js +407 -0
  348. package/dist/packages/core/src/testing/ErrorAnalyzer.js.map +1 -0
  349. package/dist/packages/core/src/testing/TestRunner.d.ts +57 -0
  350. package/dist/packages/core/src/testing/TestRunner.d.ts.map +1 -0
  351. package/dist/packages/core/src/testing/TestRunner.js +205 -0
  352. package/dist/packages/core/src/testing/TestRunner.js.map +1 -0
  353. package/dist/packages/core/src/testing/agent-cli-tests.d.ts +2 -0
  354. package/dist/packages/core/src/testing/agent-cli-tests.d.ts.map +1 -0
  355. package/dist/packages/core/src/testing/agent-cli-tests.js +493 -0
  356. package/dist/packages/core/src/testing/agent-cli-tests.js.map +1 -0
  357. package/dist/packages/core/src/testing/index.d.ts +7 -0
  358. package/dist/packages/core/src/testing/index.d.ts.map +1 -0
  359. package/dist/packages/core/src/testing/index.js +8 -0
  360. package/dist/packages/core/src/testing/index.js.map +1 -0
  361. package/dist/packages/core/src/tools/ToolRegistry.d.ts +72 -0
  362. package/dist/packages/core/src/tools/ToolRegistry.d.ts.map +1 -0
  363. package/dist/packages/core/src/tools/ToolRegistry.js +208 -0
  364. package/dist/packages/core/src/tools/ToolRegistry.js.map +1 -0
  365. package/dist/packages/core/src/tools/impl/EditFileTool.d.ts +3 -0
  366. package/dist/packages/core/src/tools/impl/EditFileTool.d.ts.map +1 -0
  367. package/dist/packages/core/src/tools/impl/EditFileTool.js +76 -0
  368. package/dist/packages/core/src/tools/impl/EditFileTool.js.map +1 -0
  369. package/dist/packages/core/src/tools/impl/FileProcessor.d.ts +85 -0
  370. package/dist/packages/core/src/tools/impl/FileProcessor.d.ts.map +1 -0
  371. package/dist/packages/core/src/tools/impl/FileProcessor.js +512 -0
  372. package/dist/packages/core/src/tools/impl/FileProcessor.js.map +1 -0
  373. package/dist/packages/core/src/tools/impl/FileProcessorTool.d.ts +151 -0
  374. package/dist/packages/core/src/tools/impl/FileProcessorTool.d.ts.map +1 -0
  375. package/dist/packages/core/src/tools/impl/FileProcessorTool.js +100 -0
  376. package/dist/packages/core/src/tools/impl/FileProcessorTool.js.map +1 -0
  377. package/dist/packages/core/src/tools/impl/ImageProcessorTool.d.ts +43 -0
  378. package/dist/packages/core/src/tools/impl/ImageProcessorTool.d.ts.map +1 -0
  379. package/dist/packages/core/src/tools/impl/ImageProcessorTool.js +104 -0
  380. package/dist/packages/core/src/tools/impl/ImageProcessorTool.js.map +1 -0
  381. package/dist/packages/core/src/tools/impl/ListDirectoryTool.d.ts +3 -0
  382. package/dist/packages/core/src/tools/impl/ListDirectoryTool.d.ts.map +1 -0
  383. package/dist/packages/core/src/tools/impl/ListDirectoryTool.js +120 -0
  384. package/dist/packages/core/src/tools/impl/ListDirectoryTool.js.map +1 -0
  385. package/dist/packages/core/src/tools/impl/MemoryTool.d.ts +4 -0
  386. package/dist/packages/core/src/tools/impl/MemoryTool.d.ts.map +1 -0
  387. package/dist/packages/core/src/tools/impl/MemoryTool.js +80 -0
  388. package/dist/packages/core/src/tools/impl/MemoryTool.js.map +1 -0
  389. package/dist/packages/core/src/tools/impl/ReadFileTool.d.ts +3 -0
  390. package/dist/packages/core/src/tools/impl/ReadFileTool.d.ts.map +1 -0
  391. package/dist/packages/core/src/tools/impl/ReadFileTool.js +223 -0
  392. package/dist/packages/core/src/tools/impl/ReadFileTool.js.map +1 -0
  393. package/dist/packages/core/src/tools/impl/SearchContentTool.d.ts +3 -0
  394. package/dist/packages/core/src/tools/impl/SearchContentTool.d.ts.map +1 -0
  395. package/dist/packages/core/src/tools/impl/SearchContentTool.js +65 -0
  396. package/dist/packages/core/src/tools/impl/SearchContentTool.js.map +1 -0
  397. package/dist/packages/core/src/tools/impl/SearchFileTool.d.ts +3 -0
  398. package/dist/packages/core/src/tools/impl/SearchFileTool.d.ts.map +1 -0
  399. package/dist/packages/core/src/tools/impl/SearchFileTool.js +48 -0
  400. package/dist/packages/core/src/tools/impl/SearchFileTool.js.map +1 -0
  401. package/dist/packages/core/src/tools/impl/ShellTool.d.ts +3 -0
  402. package/dist/packages/core/src/tools/impl/ShellTool.d.ts.map +1 -0
  403. package/dist/packages/core/src/tools/impl/ShellTool.js +92 -0
  404. package/dist/packages/core/src/tools/impl/ShellTool.js.map +1 -0
  405. package/dist/packages/core/src/tools/impl/TaskTool.d.ts +51 -0
  406. package/dist/packages/core/src/tools/impl/TaskTool.d.ts.map +1 -0
  407. package/dist/packages/core/src/tools/impl/TaskTool.js +172 -0
  408. package/dist/packages/core/src/tools/impl/TaskTool.js.map +1 -0
  409. package/dist/packages/core/src/tools/impl/TodoTool.d.ts +31 -0
  410. package/dist/packages/core/src/tools/impl/TodoTool.d.ts.map +1 -0
  411. package/dist/packages/core/src/tools/impl/TodoTool.js +102 -0
  412. package/dist/packages/core/src/tools/impl/TodoTool.js.map +1 -0
  413. package/dist/packages/core/src/tools/impl/WebFetchTool.d.ts +3 -0
  414. package/dist/packages/core/src/tools/impl/WebFetchTool.d.ts.map +1 -0
  415. package/dist/packages/core/src/tools/impl/WebFetchTool.js +77 -0
  416. package/dist/packages/core/src/tools/impl/WebFetchTool.js.map +1 -0
  417. package/dist/packages/core/src/tools/impl/WebSearchTool.d.ts +3 -0
  418. package/dist/packages/core/src/tools/impl/WebSearchTool.d.ts.map +1 -0
  419. package/dist/packages/core/src/tools/impl/WebSearchTool.js +67 -0
  420. package/dist/packages/core/src/tools/impl/WebSearchTool.js.map +1 -0
  421. package/dist/packages/core/src/tools/impl/WriteFileTool.d.ts +3 -0
  422. package/dist/packages/core/src/tools/impl/WriteFileTool.d.ts.map +1 -0
  423. package/dist/packages/core/src/tools/impl/WriteFileTool.js +41 -0
  424. package/dist/packages/core/src/tools/impl/WriteFileTool.js.map +1 -0
  425. package/dist/packages/core/src/tools/impl/index.d.ts +14 -0
  426. package/dist/packages/core/src/tools/impl/index.d.ts.map +1 -0
  427. package/dist/packages/core/src/tools/impl/index.js +21 -0
  428. package/dist/packages/core/src/tools/impl/index.js.map +1 -0
  429. package/dist/packages/core/src/tools/index.d.ts +16 -0
  430. package/dist/packages/core/src/tools/index.d.ts.map +1 -0
  431. package/dist/packages/core/src/tools/index.js +21 -0
  432. package/dist/packages/core/src/tools/index.js.map +1 -0
  433. package/dist/packages/core/src/tools/schemas/execution.d.ts +41 -0
  434. package/dist/packages/core/src/tools/schemas/execution.d.ts.map +1 -0
  435. package/dist/packages/core/src/tools/schemas/execution.js +42 -0
  436. package/dist/packages/core/src/tools/schemas/execution.js.map +1 -0
  437. package/dist/packages/core/src/tools/schemas/file.d.ts +113 -0
  438. package/dist/packages/core/src/tools/schemas/file.d.ts.map +1 -0
  439. package/dist/packages/core/src/tools/schemas/file.js +116 -0
  440. package/dist/packages/core/src/tools/schemas/file.js.map +1 -0
  441. package/dist/packages/core/src/tools/schemas/fileProcessorSchema.d.ts +278 -0
  442. package/dist/packages/core/src/tools/schemas/fileProcessorSchema.d.ts.map +1 -0
  443. package/dist/packages/core/src/tools/schemas/fileProcessorSchema.js +61 -0
  444. package/dist/packages/core/src/tools/schemas/fileProcessorSchema.js.map +1 -0
  445. package/dist/packages/core/src/tools/schemas/index.d.ts +8 -0
  446. package/dist/packages/core/src/tools/schemas/index.d.ts.map +1 -0
  447. package/dist/packages/core/src/tools/schemas/index.js +11 -0
  448. package/dist/packages/core/src/tools/schemas/index.js.map +1 -0
  449. package/dist/packages/core/src/tools/schemas/memory.d.ts +50 -0
  450. package/dist/packages/core/src/tools/schemas/memory.d.ts.map +1 -0
  451. package/dist/packages/core/src/tools/schemas/memory.js +51 -0
  452. package/dist/packages/core/src/tools/schemas/memory.js.map +1 -0
  453. package/dist/packages/core/src/tools/schemas/orchestration.d.ts +41 -0
  454. package/dist/packages/core/src/tools/schemas/orchestration.d.ts.map +1 -0
  455. package/dist/packages/core/src/tools/schemas/orchestration.js +44 -0
  456. package/dist/packages/core/src/tools/schemas/orchestration.js.map +1 -0
  457. package/dist/packages/core/src/tools/schemas/search.d.ts +111 -0
  458. package/dist/packages/core/src/tools/schemas/search.d.ts.map +1 -0
  459. package/dist/packages/core/src/tools/schemas/search.js +110 -0
  460. package/dist/packages/core/src/tools/schemas/search.js.map +1 -0
  461. package/dist/packages/core/src/tools/schemas/todo.d.ts +29 -0
  462. package/dist/packages/core/src/tools/schemas/todo.d.ts.map +1 -0
  463. package/dist/packages/core/src/tools/schemas/todo.js +32 -0
  464. package/dist/packages/core/src/tools/schemas/todo.js.map +1 -0
  465. package/dist/packages/core/src/tools/schemas/web.d.ts +84 -0
  466. package/dist/packages/core/src/tools/schemas/web.d.ts.map +1 -0
  467. package/dist/packages/core/src/tools/schemas/web.js +85 -0
  468. package/dist/packages/core/src/tools/schemas/web.js.map +1 -0
  469. package/dist/packages/core/src/types/config.d.ts +212 -0
  470. package/dist/packages/core/src/types/config.d.ts.map +1 -0
  471. package/dist/packages/core/src/types/config.js +5 -0
  472. package/dist/packages/core/src/types/config.js.map +1 -0
  473. package/dist/packages/core/src/types/errors.d.ts +92 -0
  474. package/dist/packages/core/src/types/errors.d.ts.map +1 -0
  475. package/dist/packages/core/src/types/errors.js +172 -0
  476. package/dist/packages/core/src/types/errors.js.map +1 -0
  477. package/dist/packages/core/src/types/index.d.ts +5 -0
  478. package/dist/packages/core/src/types/index.d.ts.map +1 -0
  479. package/dist/packages/core/src/types/index.js +8 -0
  480. package/dist/packages/core/src/types/index.js.map +1 -0
  481. package/dist/packages/core/src/types/session.d.ts +141 -0
  482. package/dist/packages/core/src/types/session.d.ts.map +1 -0
  483. package/dist/packages/core/src/types/session.js +16 -0
  484. package/dist/packages/core/src/types/session.js.map +1 -0
  485. package/dist/packages/core/src/types/tools.d.ts +126 -0
  486. package/dist/packages/core/src/types/tools.d.ts.map +1 -0
  487. package/dist/packages/core/src/types/tools.js +26 -0
  488. package/dist/packages/core/src/types/tools.js.map +1 -0
  489. package/dist/packages/core/src/utils/CheckpointManager.d.ts +100 -0
  490. package/dist/packages/core/src/utils/CheckpointManager.d.ts.map +1 -0
  491. package/dist/packages/core/src/utils/CheckpointManager.js +255 -0
  492. package/dist/packages/core/src/utils/CheckpointManager.js.map +1 -0
  493. package/dist/packages/core/src/utils/Logger.d.ts +29 -0
  494. package/dist/packages/core/src/utils/Logger.d.ts.map +1 -0
  495. package/dist/packages/core/src/utils/Logger.js +77 -0
  496. package/dist/packages/core/src/utils/Logger.js.map +1 -0
  497. package/dist/packages/core/src/utils/RetryManager.d.ts +125 -0
  498. package/dist/packages/core/src/utils/RetryManager.d.ts.map +1 -0
  499. package/dist/packages/core/src/utils/RetryManager.js +348 -0
  500. package/dist/packages/core/src/utils/RetryManager.js.map +1 -0
  501. package/dist/packages/core/src/utils/TokenCounter.d.ts +73 -0
  502. package/dist/packages/core/src/utils/TokenCounter.d.ts.map +1 -0
  503. package/dist/packages/core/src/utils/TokenCounter.js +338 -0
  504. package/dist/packages/core/src/utils/TokenCounter.js.map +1 -0
  505. package/dist/packages/core/src/utils/VectorMemoryStore.d.ts +110 -0
  506. package/dist/packages/core/src/utils/VectorMemoryStore.d.ts.map +1 -0
  507. package/dist/packages/core/src/utils/VectorMemoryStore.js +320 -0
  508. package/dist/packages/core/src/utils/VectorMemoryStore.js.map +1 -0
  509. package/dist/packages/core/src/utils/helpers.d.ts +24 -0
  510. package/dist/packages/core/src/utils/helpers.d.ts.map +1 -0
  511. package/dist/packages/core/src/utils/helpers.js +77 -0
  512. package/dist/packages/core/src/utils/helpers.js.map +1 -0
  513. package/dist/packages/core/src/utils/index.d.ts +11 -0
  514. package/dist/packages/core/src/utils/index.d.ts.map +1 -0
  515. package/dist/packages/core/src/utils/index.js +7 -0
  516. package/dist/packages/core/src/utils/index.js.map +1 -0
  517. package/dist/startup/IFlowRepl.d.ts +50 -0
  518. package/dist/startup/IFlowRepl.d.ts.map +1 -0
  519. package/dist/startup/IFlowRepl.js +178 -0
  520. package/dist/startup/IFlowRepl.js.map +1 -0
  521. package/dist/startup/InkBasedRepl.d.ts +151 -0
  522. package/dist/startup/InkBasedRepl.d.ts.map +1 -0
  523. package/dist/startup/InkBasedRepl.js +1415 -0
  524. package/dist/startup/InkBasedRepl.js.map +1 -0
  525. package/dist/startup/InteractiveRepl.d.ts +141 -0
  526. package/dist/startup/InteractiveRepl.d.ts.map +1 -0
  527. package/dist/startup/InteractiveRepl.js +2561 -0
  528. package/dist/startup/InteractiveRepl.js.map +1 -0
  529. package/dist/startup/NovaApp.d.ts +57 -0
  530. package/dist/startup/NovaApp.d.ts.map +1 -0
  531. package/dist/startup/NovaApp.js +1978 -0
  532. package/dist/startup/NovaApp.js.map +1 -0
  533. package/dist/startup/index.d.ts +5 -0
  534. package/dist/startup/index.d.ts.map +1 -0
  535. package/dist/startup/index.js +4 -0
  536. package/dist/startup/index.js.map +1 -0
  537. package/dist/startup/parseArgs.d.ts +47 -0
  538. package/dist/startup/parseArgs.d.ts.map +1 -0
  539. package/dist/startup/parseArgs.js +262 -0
  540. package/dist/startup/parseArgs.js.map +1 -0
  541. package/dist/ui/IFlowDropdown.d.ts +63 -0
  542. package/dist/ui/IFlowDropdown.d.ts.map +1 -0
  543. package/dist/ui/IFlowDropdown.js +362 -0
  544. package/dist/ui/IFlowDropdown.js.map +1 -0
  545. package/dist/ui/ModernReplUI.d.ts +55 -0
  546. package/dist/ui/ModernReplUI.d.ts.map +1 -0
  547. package/dist/ui/ModernReplUI.js +207 -0
  548. package/dist/ui/ModernReplUI.js.map +1 -0
  549. package/dist/ui/SimpleSelector2.d.ts +28 -0
  550. package/dist/ui/SimpleSelector2.d.ts.map +1 -0
  551. package/dist/ui/SimpleSelector2.js +181 -0
  552. package/dist/ui/SimpleSelector2.js.map +1 -0
  553. package/dist/ui/components/ActiveCursor.d.ts +128 -0
  554. package/dist/ui/components/ActiveCursor.d.ts.map +1 -0
  555. package/dist/ui/components/ActiveCursor.js +273 -0
  556. package/dist/ui/components/ActiveCursor.js.map +1 -0
  557. package/dist/ui/components/ConfirmDialog.d.ts +51 -0
  558. package/dist/ui/components/ConfirmDialog.d.ts.map +1 -0
  559. package/dist/ui/components/ConfirmDialog.js +147 -0
  560. package/dist/ui/components/ConfirmDialog.js.map +1 -0
  561. package/dist/ui/components/ErrorPanel.d.ts +33 -0
  562. package/dist/ui/components/ErrorPanel.d.ts.map +1 -0
  563. package/dist/ui/components/ErrorPanel.js +309 -0
  564. package/dist/ui/components/ErrorPanel.js.map +1 -0
  565. package/dist/ui/components/InkAppRunner.d.ts +18 -0
  566. package/dist/ui/components/InkAppRunner.d.ts.map +1 -0
  567. package/dist/ui/components/InkAppRunner.js +33 -0
  568. package/dist/ui/components/InkAppRunner.js.map +1 -0
  569. package/dist/ui/components/InkComponents.d.ts +126 -0
  570. package/dist/ui/components/InkComponents.d.ts.map +1 -0
  571. package/dist/ui/components/InkComponents.js +216 -0
  572. package/dist/ui/components/InkComponents.js.map +1 -0
  573. package/dist/ui/components/NovaInkApp.d.ts +11 -0
  574. package/dist/ui/components/NovaInkApp.d.ts.map +1 -0
  575. package/dist/ui/components/NovaInkApp.js +148 -0
  576. package/dist/ui/components/NovaInkApp.js.map +1 -0
  577. package/dist/ui/components/ProgressBar.d.ts +65 -0
  578. package/dist/ui/components/ProgressBar.d.ts.map +1 -0
  579. package/dist/ui/components/ProgressBar.js +135 -0
  580. package/dist/ui/components/ProgressBar.js.map +1 -0
  581. package/dist/ui/components/ProgressIndicator.d.ts +41 -0
  582. package/dist/ui/components/ProgressIndicator.d.ts.map +1 -0
  583. package/dist/ui/components/ProgressIndicator.js +235 -0
  584. package/dist/ui/components/ProgressIndicator.js.map +1 -0
  585. package/dist/ui/components/QuickActions.d.ts +36 -0
  586. package/dist/ui/components/QuickActions.d.ts.map +1 -0
  587. package/dist/ui/components/QuickActions.js +328 -0
  588. package/dist/ui/components/QuickActions.js.map +1 -0
  589. package/dist/ui/components/SimpleErrorPanel.d.ts +16 -0
  590. package/dist/ui/components/SimpleErrorPanel.d.ts.map +1 -0
  591. package/dist/ui/components/SimpleErrorPanel.js +193 -0
  592. package/dist/ui/components/SimpleErrorPanel.js.map +1 -0
  593. package/dist/ui/components/StatusBar.d.ts +30 -0
  594. package/dist/ui/components/StatusBar.d.ts.map +1 -0
  595. package/dist/ui/components/StatusBar.js +154 -0
  596. package/dist/ui/components/StatusBar.js.map +1 -0
  597. package/dist/ui/components/ThinkingBlockRenderer.d.ts +109 -0
  598. package/dist/ui/components/ThinkingBlockRenderer.d.ts.map +1 -0
  599. package/dist/ui/components/ThinkingBlockRenderer.js +335 -0
  600. package/dist/ui/components/ThinkingBlockRenderer.js.map +1 -0
  601. package/dist/ui/components/ThinkingContentDisplay.d.ts +59 -0
  602. package/dist/ui/components/ThinkingContentDisplay.d.ts.map +1 -0
  603. package/dist/ui/components/ThinkingContentDisplay.js +172 -0
  604. package/dist/ui/components/ThinkingContentDisplay.js.map +1 -0
  605. package/dist/ui/components/TodoProgressPanel.d.ts +91 -0
  606. package/dist/ui/components/TodoProgressPanel.d.ts.map +1 -0
  607. package/dist/ui/components/TodoProgressPanel.js +284 -0
  608. package/dist/ui/components/TodoProgressPanel.js.map +1 -0
  609. package/dist/ui/components/ToolCallStatusDisplay.d.ts +89 -0
  610. package/dist/ui/components/ToolCallStatusDisplay.d.ts.map +1 -0
  611. package/dist/ui/components/ToolCallStatusDisplay.js +246 -0
  612. package/dist/ui/components/ToolCallStatusDisplay.js.map +1 -0
  613. package/dist/ui/components/UserMessageHighlight.d.ts +48 -0
  614. package/dist/ui/components/UserMessageHighlight.d.ts.map +1 -0
  615. package/dist/ui/components/UserMessageHighlight.js +196 -0
  616. package/dist/ui/components/UserMessageHighlight.js.map +1 -0
  617. package/dist/ui/components/index.d.ts +17 -0
  618. package/dist/ui/components/index.d.ts.map +1 -0
  619. package/dist/ui/components/index.js +18 -0
  620. package/dist/ui/components/index.js.map +1 -0
  621. package/dist/ui/ink-prototype.d.ts +3 -0
  622. package/dist/ui/ink-prototype.d.ts.map +1 -0
  623. package/dist/ui/ink-prototype.js +160 -0
  624. package/dist/ui/ink-prototype.js.map +1 -0
  625. package/dist/utils/CliUI.d.ts +163 -0
  626. package/dist/utils/CliUI.d.ts.map +1 -0
  627. package/dist/utils/CliUI.js +292 -0
  628. package/dist/utils/CliUI.js.map +1 -0
  629. package/dist/utils/CompletionHelper.d.ts +112 -0
  630. package/dist/utils/CompletionHelper.d.ts.map +1 -0
  631. package/dist/utils/CompletionHelper.js +304 -0
  632. package/dist/utils/CompletionHelper.js.map +1 -0
  633. package/dist/utils/EnhancedCompleter.d.ts +107 -0
  634. package/dist/utils/EnhancedCompleter.d.ts.map +1 -0
  635. package/dist/utils/EnhancedCompleter.js +428 -0
  636. package/dist/utils/EnhancedCompleter.js.map +1 -0
  637. package/dist/utils/ErrorEnhancer.d.ts +103 -0
  638. package/dist/utils/ErrorEnhancer.d.ts.map +1 -0
  639. package/dist/utils/ErrorEnhancer.js +350 -0
  640. package/dist/utils/ErrorEnhancer.js.map +1 -0
  641. package/dist/utils/OutputFormatter.d.ts +65 -0
  642. package/dist/utils/OutputFormatter.d.ts.map +1 -0
  643. package/dist/utils/OutputFormatter.js +145 -0
  644. package/dist/utils/OutputFormatter.js.map +1 -0
  645. package/dist/utils/index.d.ts +5 -0
  646. package/dist/utils/index.d.ts.map +1 -0
  647. package/dist/utils/index.js +8 -0
  648. package/dist/utils/index.js.map +1 -0
  649. package/package.json +99 -0
@@ -0,0 +1,1415 @@
1
+ // ============================================================================
2
+ // InkBasedRepl - Interactive REPL using Ink UI framework
3
+ // A modern, component-based terminal UI similar to Claude Code
4
+ // ============================================================================
5
+ import * as fs from 'node:fs';
6
+ import * as path from 'node:path';
7
+ import { spawn } from 'node:child_process';
8
+ import chalk from 'chalk';
9
+ import { AgentLoop } from '../../../core/src/session/AgentLoop.js';
10
+ import { ModelClient } from '../../../core/src/model/ModelClient.js';
11
+ import { buildSystemPrompt } from '../../../core/src/context/defaultSystemPrompt.js';
12
+ import { ThinkingBlockRenderer } from '../ui/components/ThinkingBlockRenderer.js';
13
+ import { TodoProgressPanel } from '../ui/components/TodoProgressPanel.js';
14
+ import { UserMessageHighlight } from '../ui/components/UserMessageHighlight.js';
15
+ import { ThinkingContentDisplay } from '../ui/components/ThinkingContentDisplay.js';
16
+ import { ToolCallStatusDisplay } from '../ui/components/ToolCallStatusDisplay.js';
17
+ import { selectModelInteractive, selectSkillInteractive } from '../ui/SimpleSelector2.js';
18
+ // ============================================================================
19
+ // Box drawing characters
20
+ // ============================================================================
21
+ const BOX = {
22
+ tl: '╭', tr: '╮', bl: '╰', br: '╯',
23
+ h: '─', v: '│', ht: '├', htr: '┤',
24
+ hThick: '━', vThick: '┃',
25
+ arrow: '›', bullet: '•', check: '✓', crossX: '✗', dot: '·',
26
+ diamond: '◆', star: '★',
27
+ spinner: ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'],
28
+ };
29
+ const MODE_LABELS = {
30
+ auto: { label: 'AUTO', color: chalk.green.bold, description: 'Full autonomous' },
31
+ plan: { label: 'PLAN', color: chalk.yellow.bold, description: 'Plan first' },
32
+ ask: { label: 'ASK', color: chalk.cyan.bold, description: 'Answer only' },
33
+ };
34
+ // ============================================================================
35
+ // InkBasedRepl Class
36
+ // ============================================================================
37
+ export class InkBasedRepl {
38
+ modelClient;
39
+ sessionManager;
40
+ toolRegistry;
41
+ approvalManager;
42
+ authManager;
43
+ config;
44
+ configManager;
45
+ cwd;
46
+ contextCompressor;
47
+ mcpManager;
48
+ skillRegistry;
49
+ sessionId = null;
50
+ restoreSessionId;
51
+ currentLoop = null;
52
+ state;
53
+ _pendingSkillInject = null;
54
+ // Thinking renderer for non-Ink fallback
55
+ thinkingRenderer;
56
+ // New UI components
57
+ todoProgressPanel;
58
+ userMessageHighlight;
59
+ thinkingContentDisplay;
60
+ toolCallStatusDisplay;
61
+ activeCursor; // ActiveCursor instance
62
+ // Execution tracking for compact display
63
+ turnCount = 0;
64
+ toolCallCount = 0;
65
+ lastStatusLine = '';
66
+ // UI state
67
+ showHelp = false;
68
+ showModelSelector = false;
69
+ processing = false;
70
+ currentText = '';
71
+ pendingToolCalls = new Map();
72
+ // Store initial config for recreating ModelClient
73
+ initialConfig;
74
+ // Agent-first options
75
+ json;
76
+ noInput;
77
+ limit;
78
+ constructor(options) {
79
+ this.modelClient = options.modelClient;
80
+ this.sessionManager = options.sessionManager;
81
+ this.toolRegistry = options.toolRegistry;
82
+ this.approvalManager = options.approvalManager;
83
+ this.authManager = options.authManager;
84
+ this.config = options.config;
85
+ this.initialConfig = JSON.parse(JSON.stringify(options.config)); // Deep copy
86
+ this.configManager = options.configManager;
87
+ this.cwd = options.cwd;
88
+ this.contextCompressor = options.contextCompressor;
89
+ this.mcpManager = options.mcpManager;
90
+ this.skillRegistry = options.skillRegistry;
91
+ this.restoreSessionId = options.restoreSessionId;
92
+ // Agent-first options
93
+ this.json = options.json ?? false;
94
+ this.noInput = options.noInput ?? false;
95
+ this.limit = options.limit ?? 20; // Default limit for bounded output
96
+ this.thinkingRenderer = new ThinkingBlockRenderer({
97
+ expanded: false,
98
+ maxPreviewLines: 4,
99
+ maxLineLength: 80,
100
+ showStreamingPreview: false,
101
+ });
102
+ // Initialize TODO progress panel for fixed-position task display
103
+ this.todoProgressPanel = new TodoProgressPanel({
104
+ showPriority: true,
105
+ compact: true,
106
+ });
107
+ // Initialize user message highlighter
108
+ this.userMessageHighlight = new UserMessageHighlight({
109
+ highlightColor: 'purple',
110
+ showTimestamp: true,
111
+ });
112
+ // Initialize thinking content display (green dashed box)
113
+ this.thinkingContentDisplay = new ThinkingContentDisplay({
114
+ maxPreviewLines: 6,
115
+ expanded: false,
116
+ });
117
+ // Initialize tool call status display
118
+ this.toolCallStatusDisplay = new ToolCallStatusDisplay({
119
+ showInput: true,
120
+ showResult: false,
121
+ });
122
+ // Initialize active cursor (purple circle animation)
123
+ // Note: ActiveCursor will be initialized when first needed
124
+ this.activeCursor = null;
125
+ // Initialize state
126
+ this.state = {
127
+ model: this.modelClient.getModel(),
128
+ mode: (this.config.core.defaultApprovalMode === 'yolo' ? 'auto' :
129
+ this.config.core.defaultApprovalMode === 'plan' ? 'plan' : 'ask'),
130
+ contextUsage: 0,
131
+ sessionId: 'new',
132
+ messages: [],
133
+ activeTools: [],
134
+ processing: false,
135
+ thinkingContent: '',
136
+ showThinking: true,
137
+ mcpConnected: 0,
138
+ mcpTotal: 0,
139
+ };
140
+ }
141
+ // ========================================================================
142
+ // Lifecycle
143
+ // ========================================================================
144
+ async start() {
145
+ // Restore or create session
146
+ if (this.restoreSessionId) {
147
+ const existing = this.sessionManager.get(this.restoreSessionId);
148
+ this.sessionId = existing ? this.restoreSessionId : this.createInitialSession();
149
+ }
150
+ else {
151
+ this.sessionId = this.createInitialSession();
152
+ }
153
+ // Set approval handler
154
+ this.approvalManager.setHandler(this.handleApproval.bind(this));
155
+ // Print initial banner (simplified)
156
+ this.printBanner();
157
+ // Start interactive loop
158
+ await this.runInputLoop();
159
+ }
160
+ createInitialSession() {
161
+ const session = this.sessionManager.create({
162
+ workingDirectory: this.cwd,
163
+ model: this.modelClient.getModel(),
164
+ maxTokens: this.config.core.maxTokens,
165
+ temperature: this.config.core.temperature,
166
+ approvalMode: this.getEffectiveApprovalMode(),
167
+ streaming: true,
168
+ maxTurns: this.config.core.maxTurns,
169
+ });
170
+ return session.id;
171
+ }
172
+ // ========================================================================
173
+ // Agent-First: JSON Output Helpers
174
+ // ========================================================================
175
+ /**
176
+ * Output structured JSON data when --json flag is set
177
+ * This enables machine-parseable output for Agent consumers
178
+ */
179
+ outputJSON(data) {
180
+ if (this.json) {
181
+ console.log(JSON.stringify(data, null, 2));
182
+ }
183
+ }
184
+ /**
185
+ * Output structured error in JSON format
186
+ */
187
+ outputErrorJSON(code, message, suggestion, example) {
188
+ if (this.json) {
189
+ console.log(JSON.stringify({
190
+ error: {
191
+ code,
192
+ message,
193
+ suggestion,
194
+ example
195
+ }
196
+ }, null, 2));
197
+ }
198
+ }
199
+ /**
200
+ * Check if we should suppress interactive elements
201
+ */
202
+ shouldSuppressInteractive() {
203
+ return this.noInput || this.json;
204
+ }
205
+ /**
206
+ * Apply limit to array results for bounded output
207
+ */
208
+ applyLimit(items) {
209
+ const total = items.length;
210
+ const limited = items.slice(0, this.limit);
211
+ const showing = `Showing ${limited.length} of ${total}`;
212
+ const hint = total > this.limit ? `Use --limit ${total} to see all items` : undefined;
213
+ return { items: limited, total, showing, hint };
214
+ }
215
+ // ========================================================================
216
+ // Banner & UI
217
+ // ========================================================================
218
+ printBanner() {
219
+ const w = 70;
220
+ const hr = chalk.hex('#7C3AED').dim(BOX.h.repeat(w));
221
+ const hrThick = chalk.hex('#7C3AED')(BOX.hThick.repeat(w));
222
+ const vl = chalk.hex('#7C3AED').dim(BOX.v);
223
+ const modelShort = this.modelClient.getModel().split('/').pop() || this.modelClient.getModel();
224
+ const modeInfo = MODE_LABELS[this.state.mode];
225
+ console.log('');
226
+ console.log(chalk.hex('#7C3AED')(BOX.tl) + hrThick + chalk.hex('#7C3AED')(BOX.tr));
227
+ // Logo
228
+ console.log(vl + chalk.hex('#7C3AED').bold(' NOVA ') +
229
+ chalk.hex('#A78BFA')('CLI') +
230
+ chalk.dim(' · AI-powered terminal assistant') + ' '.repeat(24) + vl);
231
+ console.log(chalk.hex('#7C3AED')(BOX.ht) + hr + chalk.hex('#7C3AED')(BOX.htr));
232
+ // Status line
233
+ console.log(vl + ' Model: ' + chalk.white(modelShort) + ' '.repeat(Math.max(0, 52 - modelShort.length)) + vl);
234
+ console.log(vl + ' Mode: ' + modeInfo.color(modeInfo.label) + ' '.repeat(52) + vl);
235
+ console.log(vl + ' Dir: ' + chalk.gray(this.cwd.slice(-50)) + ' '.repeat(Math.max(0, 52 - Math.min(50, this.cwd.length))) + vl);
236
+ console.log(chalk.hex('#7C3AED')(BOX.bl) + hrThick + chalk.hex('#7C3AED')(BOX.br));
237
+ console.log('');
238
+ }
239
+ printPrompt() {
240
+ const modeInfo = MODE_LABELS[this.state.mode];
241
+ const modelShort = this.modelClient.getModel().split('/').pop() || this.modelClient.getModel();
242
+ const modeBadge = modeInfo.color(`[${modeInfo.label}]`);
243
+ const ctxStr = this.state.contextUsage > 0 ?
244
+ chalk.dim(` (${this.state.contextUsage}% ctx)`) : '';
245
+ process.stdout.write(`\n${modeBadge} ${chalk.gray(modelShort)}${ctxStr} ${chalk.hex('#7C3AED')('›')} `);
246
+ }
247
+ // ========================================================================
248
+ // Input Loop
249
+ // ========================================================================
250
+ async runInputLoop() {
251
+ const readline = await import('node:readline');
252
+ const rl = readline.createInterface({
253
+ input: process.stdin,
254
+ output: process.stdout,
255
+ historySize: 200,
256
+ removeHistoryDuplicates: true,
257
+ });
258
+ // Guard flag: when true, rl 'close' is a false alarm from raw-mode pause/resume
259
+ let closeGuard = false;
260
+ // Handle Ctrl+C
261
+ process.on('SIGINT', () => {
262
+ if (this.currentLoop?.isActive()) {
263
+ this.currentLoop.cancel();
264
+ this.processing = false;
265
+ process.stdout.write('\n');
266
+ this.printPrompt();
267
+ }
268
+ else {
269
+ console.log(chalk.dim('\n Use /quit or Ctrl+D to exit'));
270
+ this.printPrompt();
271
+ }
272
+ });
273
+ rl.on('close', () => {
274
+ // Ignore close events triggered by raw-mode pause/resume during
275
+ // interactive selectors (SimpleSelector2, etc.)
276
+ if (closeGuard) {
277
+ closeGuard = false;
278
+ process.stdin.resume();
279
+ return;
280
+ }
281
+ if (this.sessionId)
282
+ this.sessionManager.persist(this.sessionId);
283
+ console.log(chalk.dim('\nGoodbye!'));
284
+ process.exit(0);
285
+ });
286
+ // Main loop
287
+ while (true) {
288
+ this.printPrompt();
289
+ const input = await new Promise((resolve) => {
290
+ rl.question('', resolve);
291
+ });
292
+ if (!input.trim())
293
+ continue;
294
+ // Set guard before dispatching — commands may enter/leave raw mode
295
+ closeGuard = true;
296
+ this.processing = true;
297
+ await this.dispatchInput(input.trim());
298
+ this.processing = false;
299
+ closeGuard = false;
300
+ }
301
+ }
302
+ async dispatchInput(input) {
303
+ // Handle commands
304
+ if (input.startsWith('/')) {
305
+ await this.handleCommand(input);
306
+ return;
307
+ }
308
+ // Handle shell commands
309
+ if (input.startsWith('!')) {
310
+ await this.handleShellCommand(input.slice(1).trim());
311
+ return;
312
+ }
313
+ // Process normal input
314
+ await this.processInput(input);
315
+ }
316
+ // ========================================================================
317
+ // Command Handlers
318
+ // ========================================================================
319
+ async handleCommand(cmd) {
320
+ const parts = cmd.slice(1).split(/\s+/);
321
+ const command = (parts[0] || '').toLowerCase();
322
+ const arg = parts.slice(1).join(' ');
323
+ switch (command) {
324
+ case 'init':
325
+ await this.handleProjectAnalyze();
326
+ break;
327
+ case 'quit':
328
+ case 'exit':
329
+ case 'q':
330
+ if (this.sessionId)
331
+ this.sessionManager.persist(this.sessionId);
332
+ if (this.activeCursor)
333
+ this.activeCursor.stop();
334
+ console.log(chalk.dim('Goodbye!'));
335
+ process.exit(0);
336
+ case 'help':
337
+ case 'h':
338
+ case '?':
339
+ this.printHelp();
340
+ break;
341
+ case 'clear':
342
+ if (this.sessionId)
343
+ this.sessionManager.persist(this.sessionId);
344
+ this.sessionId = this.createInitialSession();
345
+ this.state.messages = [];
346
+ this.state.contextUsage = 0;
347
+ console.log(chalk.dim(' Conversation cleared.'));
348
+ break;
349
+ case 'mode':
350
+ if (arg && ['auto', 'plan', 'ask'].includes(arg)) {
351
+ this.state.mode = arg;
352
+ console.log(chalk.dim(` Mode: ${arg}`));
353
+ }
354
+ else {
355
+ // Cycle mode
356
+ const modes = ['auto', 'plan', 'ask'];
357
+ const idx = modes.indexOf(this.state.mode);
358
+ this.state.mode = modes[(idx + 1) % 3];
359
+ console.log(chalk.dim(` Mode: ${this.state.mode}`));
360
+ }
361
+ break;
362
+ case 'model':
363
+ await this.handleModelCommand(arg);
364
+ break;
365
+ case 'ollama':
366
+ await this.handleOllamaCommand(arg);
367
+ break;
368
+ case 'status':
369
+ this.printStatus();
370
+ break;
371
+ case 'mcp':
372
+ await this.handleMcpCommand(arg);
373
+ break;
374
+ case 'skills':
375
+ await this.handleSkillsCommand(arg);
376
+ break;
377
+ case 'thinking':
378
+ this.state.showThinking = !this.state.showThinking;
379
+ console.log(chalk.dim(` Thinking: ${this.state.showThinking ? 'ON' : 'OFF'}`));
380
+ break;
381
+ case 'project':
382
+ await this.handleProjectCommand(arg);
383
+ break;
384
+ default:
385
+ console.log(chalk.yellow(` Unknown command: /${command}`));
386
+ }
387
+ }
388
+ printHelp() {
389
+ console.log('');
390
+ console.log(chalk.hex('#7C3AED').bold(' Commands:'));
391
+ console.log(chalk.gray(' /help, /h Show this help'));
392
+ console.log(chalk.gray(' /init Analyze project and initialize context'));
393
+ console.log(chalk.gray(' /quit, /q Exit Nova CLI'));
394
+ console.log(chalk.gray(' /clear Clear conversation'));
395
+ console.log(chalk.gray(' /mode Cycle mode (AUTO → PLAN → ASK)'));
396
+ console.log(chalk.gray(' /model Switch model'));
397
+ console.log(chalk.gray(' /ollama Ollama status'));
398
+ console.log(chalk.gray(' /status Session status'));
399
+ console.log(chalk.gray(' /mcp MCP servers'));
400
+ console.log(chalk.gray(' /skills Available skills'));
401
+ console.log(chalk.gray(' /thinking Toggle thinking display'));
402
+ console.log('');
403
+ console.log(chalk.gray(' @file Inject file content'));
404
+ console.log(chalk.gray(' !command Run shell command'));
405
+ console.log('');
406
+ }
407
+ async handleModelCommand(arg) {
408
+ if (!arg) {
409
+ // Interactive model selection — only show configured providers
410
+ const config = this.configManager.getConfig();
411
+ const models = [];
412
+ // Collect models only from configured/available providers
413
+ for (const [provider, providerConfig] of Object.entries(config.models.providers)) {
414
+ const hasCreds = this.authManager.hasCredentials(provider);
415
+ const isOllama = providerConfig.type === 'ollama';
416
+ const isOllamaCloud = providerConfig.type === 'ollama-cloud';
417
+ // Skip providers that are not configured
418
+ if (!hasCreds && !isOllama && !isOllamaCloud)
419
+ continue;
420
+ // For Ollama, verify it's actually running
421
+ if (isOllama && !hasCreds) {
422
+ try {
423
+ const baseUrl = process.env.OLLAMA_HOST || 'http://localhost:11434';
424
+ const resp = await fetch(`${baseUrl}/api/tags`, { signal: AbortSignal.timeout(2000) });
425
+ if (!resp.ok)
426
+ continue; // Ollama not running
427
+ }
428
+ catch {
429
+ continue; // Ollama not running
430
+ }
431
+ }
432
+ for (const [modelId, modelConfig] of Object.entries(providerConfig.models)) {
433
+ const features = [];
434
+ if (modelConfig.supportsVision)
435
+ features.push('vision');
436
+ if (modelConfig.supportsTools)
437
+ features.push('tools');
438
+ if (modelConfig.supportsThinking)
439
+ features.push('thinking');
440
+ const description = features.length > 0 ? `[${features.join(', ')}]` : '';
441
+ models.push({
442
+ provider,
443
+ model: modelId,
444
+ description,
445
+ });
446
+ }
447
+ }
448
+ if (models.length === 0) {
449
+ console.log(chalk.yellow(' No models available. Configure a provider first.'));
450
+ console.log(chalk.gray(' Use: nova auth set <provider>'));
451
+ return;
452
+ }
453
+ // Show interactive selector (returns "provider/model" format)
454
+ const selectedModel = await selectModelInteractive(models);
455
+ if (selectedModel && selectedModel !== 'separator' && !selectedModel.startsWith('provider:')) {
456
+ const success = await this.switchModel(selectedModel);
457
+ if (success) {
458
+ console.log(chalk.green(` ✓ Switched to: ${selectedModel}`));
459
+ }
460
+ // If failed, switchModel already printed an error message
461
+ }
462
+ else if (selectedModel && selectedModel.startsWith('provider:')) {
463
+ console.log(chalk.dim(' Please select a specific model, not a provider header'));
464
+ }
465
+ else {
466
+ console.log(chalk.dim(' Model selection cancelled'));
467
+ }
468
+ }
469
+ else {
470
+ // Direct model switch
471
+ const success = await this.switchModel(arg);
472
+ if (success) {
473
+ console.log(chalk.green(` ✓ Switched to: ${arg}`));
474
+ }
475
+ }
476
+ }
477
+ async handleOllamaCommand(arg) {
478
+ const creds = this.authManager.getCredentials('ollama');
479
+ const baseUrl = creds?.baseUrl || process.env.OLLAMA_HOST || 'http://localhost:11434';
480
+ console.log(chalk.hex('#7C3AED')('\n Ollama Status:'));
481
+ console.log(chalk.gray(` Host: ${baseUrl}`));
482
+ try {
483
+ const response = await fetch(`${baseUrl}/api/tags`);
484
+ if (response.ok) {
485
+ const data = await response.json();
486
+ console.log(chalk.green(' Status: Running'));
487
+ console.log(chalk.gray(` Models: ${data.models?.length || 0} installed`));
488
+ if (data.models?.length > 0) {
489
+ data.models.slice(0, 5).forEach((m) => {
490
+ console.log(chalk.gray(` - ${m.name}`));
491
+ });
492
+ }
493
+ }
494
+ else {
495
+ console.log(chalk.yellow(' Status: Not responding'));
496
+ }
497
+ }
498
+ catch {
499
+ console.log(chalk.red(' Status: Not running'));
500
+ console.log(chalk.gray(' Start with: ollama serve'));
501
+ }
502
+ console.log('');
503
+ }
504
+ /**
505
+ * Switch to a different model, potentially across providers.
506
+ * Accepts "provider/model" or bare "model" format.
507
+ * Persists selection to global config.
508
+ */
509
+ async switchModel(modelId) {
510
+ try {
511
+ // Parse provider/model format (e.g., "ollama/gemma3:4b")
512
+ let providerName;
513
+ let actualModelId;
514
+ if (modelId.includes('/')) {
515
+ const idx = modelId.indexOf('/');
516
+ providerName = modelId.substring(0, idx);
517
+ actualModelId = modelId.substring(idx + 1);
518
+ }
519
+ else {
520
+ // Bare model name — look up in config to find provider
521
+ const modelConfig = this.configManager.getModelConfig(modelId);
522
+ if (!modelConfig) {
523
+ // Might be an Ollama model
524
+ if (this.authManager.hasCredentials('ollama') || process.env.OLLAMA_HOST) {
525
+ providerName = 'ollama';
526
+ actualModelId = modelId;
527
+ }
528
+ else {
529
+ console.log(chalk.red(` ✗ Model "${modelId}" not found in config`));
530
+ return false;
531
+ }
532
+ }
533
+ else {
534
+ const config = this.configManager.getConfig();
535
+ for (const [name, p] of Object.entries(config.models.providers)) {
536
+ if (p === modelConfig.provider || p.models === modelConfig.provider.models) {
537
+ providerName = name;
538
+ break;
539
+ }
540
+ }
541
+ actualModelId = modelId;
542
+ if (!providerName) {
543
+ console.log(chalk.red(` ✗ Cannot determine provider for "${modelId}"`));
544
+ return false;
545
+ }
546
+ }
547
+ }
548
+ // Get provider config
549
+ const config = this.configManager.getConfig();
550
+ const providerConfig = config.models.providers[providerName];
551
+ if (!providerConfig) {
552
+ console.log(chalk.red(` ✗ Unknown provider: "${providerName}"`));
553
+ return false;
554
+ }
555
+ const providerType = providerConfig.type;
556
+ const creds = this.authManager.getCredentials(providerName);
557
+ // For non-Ollama providers, require API key
558
+ const isOllamaType = providerType === 'ollama' || providerName === 'ollama' || providerName === 'ollama-cloud';
559
+ if (!isOllamaType && !creds?.apiKey) {
560
+ console.log(chalk.yellow(` ⚠ No API key found for "${providerName}"`));
561
+ console.log(chalk.gray(` Set it with: nova auth set ${providerName}`));
562
+ return false;
563
+ }
564
+ // Create new ModelClient with correct provider
565
+ this.modelClient = new ModelClient({
566
+ provider: providerType,
567
+ apiKey: creds?.apiKey,
568
+ baseUrl: creds?.baseUrl || providerConfig.baseUrl,
569
+ model: actualModelId,
570
+ maxTokens: this.config.core.maxTokens,
571
+ temperature: this.config.core.temperature,
572
+ organizationId: creds?.organizationId,
573
+ codingPlanPlatform: providerConfig.codingPlanPlatform,
574
+ });
575
+ // Update state
576
+ this.state.model = `${providerName}/${actualModelId}`;
577
+ // Persist to global config
578
+ config.core.defaultModel = `${providerName}/${actualModelId}`;
579
+ await this.configManager.save(config);
580
+ return true;
581
+ }
582
+ catch (err) {
583
+ console.log(chalk.red(` ✗ Error switching model: ${err.message}`));
584
+ return false;
585
+ }
586
+ }
587
+ printStatus() {
588
+ console.log(chalk.hex('#7C3AED')('\n Session Status:'));
589
+ console.log(chalk.gray(` Session: ${this.sessionId?.slice(0, 8) || 'none'}`));
590
+ console.log(chalk.gray(` Model: ${this.state.model}`));
591
+ console.log(chalk.gray(` Mode: ${this.state.mode}`));
592
+ console.log(chalk.gray(` Context: ${this.state.contextUsage}%`));
593
+ console.log(chalk.gray(` Messages: ${this.state.messages.length}`));
594
+ console.log('');
595
+ }
596
+ printMcpStatus() {
597
+ if (!this.mcpManager) {
598
+ console.log(chalk.gray(' MCP not initialized'));
599
+ return;
600
+ }
601
+ const statuses = this.mcpManager.listServers();
602
+ if (statuses.length === 0) {
603
+ console.log(chalk.gray(' No MCP servers configured'));
604
+ return;
605
+ }
606
+ console.log(chalk.hex('#7C3AED')('\n MCP Servers:'));
607
+ for (const s of statuses) {
608
+ const icon = s.connected ? chalk.green('✓') : chalk.red('✗');
609
+ console.log(chalk.gray(` ${icon} ${s.name}: ${s.connected ? 'connected' : 'disconnected'}`));
610
+ }
611
+ console.log('');
612
+ }
613
+ async handleMcpCommand(arg) {
614
+ if (!this.mcpManager) {
615
+ console.log(chalk.gray(' MCP not initialized'));
616
+ return;
617
+ }
618
+ const statuses = this.mcpManager.listServers();
619
+ if (statuses.length === 0) {
620
+ console.log(chalk.gray(' No MCP servers configured'));
621
+ console.log(chalk.dim(' Add servers to ~/.nova/config.yaml under "mcp:"'));
622
+ return;
623
+ }
624
+ if (!arg) {
625
+ // Show status (non-interactive for now)
626
+ this.printMcpStatus();
627
+ }
628
+ else {
629
+ // Specific server action requested
630
+ console.log(chalk.green(` MCP server: ${arg}`));
631
+ console.log(chalk.dim(' Note: MCP server management not yet implemented in interactive mode'));
632
+ }
633
+ }
634
+ printSkillsStatus() {
635
+ if (!this.skillRegistry) {
636
+ console.log(chalk.gray(' Skills not initialized'));
637
+ return;
638
+ }
639
+ // We'd need async for this, but for now just show a message
640
+ console.log(chalk.hex('#7C3AED')('\n Skills:'));
641
+ console.log(chalk.gray(' Use /skills <name> to inject a skill'));
642
+ console.log('');
643
+ }
644
+ async handleSkillsCommand(arg) {
645
+ if (!this.skillRegistry) {
646
+ console.log(chalk.gray(' Skills not initialized'));
647
+ return;
648
+ }
649
+ // Parse command arguments
650
+ const args = arg.trim().split(/\s+/);
651
+ const subcommand = args[0]?.toLowerCase();
652
+ if (subcommand === 'add') {
653
+ // Handle /skills add <global|local> [file-path]
654
+ const scope = args[1]?.toLowerCase();
655
+ const filePath = args.slice(2).join(' ').trim();
656
+ if (!scope || (scope !== 'global' && scope !== 'local')) {
657
+ await this.handleAddSkillCommand('local');
658
+ return;
659
+ }
660
+ if (!filePath) {
661
+ await this.handleAddSkillCommand(scope);
662
+ return;
663
+ }
664
+ await this.handleAddSkillFromFile(scope, filePath);
665
+ return;
666
+ }
667
+ if (subcommand === 'list') {
668
+ // Handle /skills list
669
+ try {
670
+ const skills = await this.skillRegistry.list();
671
+ const localSkills = this.state.activeSkills || [];
672
+ if (skills.length === 0 && localSkills.length === 0) {
673
+ console.log(chalk.dim(' No skills installed. Use "/skills add" to add skills from local files.'));
674
+ return;
675
+ }
676
+ console.log('');
677
+ console.log(chalk.hex('#7C3AED').bold(' Available Skills:'));
678
+ console.log('');
679
+ // Show global skills
680
+ if (skills.length > 0) {
681
+ console.log(chalk.hex('#7C3AED').bold(' Global Skills:'));
682
+ console.log('');
683
+ skills.forEach(skill => {
684
+ console.log(chalk.white(` • ${skill.metadata.name}`));
685
+ console.log(chalk.dim(` ${skill.metadata.description}`));
686
+ console.log('');
687
+ });
688
+ }
689
+ // Show local skills (current session)
690
+ if (localSkills.length > 0) {
691
+ console.log(chalk.hex('#7C3AED').bold(' Local Skills (Current Session):'));
692
+ console.log('');
693
+ localSkills.forEach(skill => {
694
+ console.log(chalk.white(` • ${skill.name}`));
695
+ console.log(chalk.dim(` ${skill.description}`));
696
+ console.log('');
697
+ });
698
+ }
699
+ }
700
+ catch (error) {
701
+ console.log(chalk.red(` Error loading skills: ${error.message}`));
702
+ }
703
+ return;
704
+ }
705
+ if (subcommand === 'rm') {
706
+ // Handle /skills rm <skill-name>
707
+ const skillName = args[1]?.toLowerCase();
708
+ if (!skillName) {
709
+ console.log(chalk.yellow(' Usage: /skills rm <skill-name>'));
710
+ console.log(chalk.dim(' Example: /skills rm code-simplifier'));
711
+ return;
712
+ }
713
+ await this.handleRemoveSkillCommand(skillName);
714
+ return;
715
+ }
716
+ // Default behavior: interactive skill selection or specific skill
717
+ if (!arg) {
718
+ // Interactive skill selection
719
+ try {
720
+ const skills = await this.skillRegistry.list();
721
+ if (skills.length === 0) {
722
+ console.log(chalk.dim(' No skills installed. Use "/skills add" to add skills from local files.'));
723
+ return;
724
+ }
725
+ const skillItems = skills.map(skill => ({
726
+ name: skill.metadata.name,
727
+ description: skill.metadata.description,
728
+ }));
729
+ const selectedSkill = await selectSkillInteractive(skillItems);
730
+ if (selectedSkill) {
731
+ console.log(chalk.green(` ✓ Selected skill: ${selectedSkill}`));
732
+ console.log(chalk.dim(' Note: Skill injection not yet implemented in interactive mode'));
733
+ }
734
+ else {
735
+ console.log(chalk.dim(' Skill selection cancelled'));
736
+ }
737
+ }
738
+ catch (error) {
739
+ console.log(chalk.red(` Error loading skills: ${error.message}`));
740
+ }
741
+ }
742
+ else {
743
+ // Specific skill requested
744
+ console.log(chalk.green(` ✓ Selected skill: ${arg}`));
745
+ console.log(chalk.dim(' Note: Skill injection not yet implemented in interactive mode'));
746
+ }
747
+ }
748
+ // ========================================================================
749
+ // Add Skill Handler
750
+ // ========================================================================
751
+ async handleAddSkillCommand(scope) {
752
+ const { resolve } = await import('path');
753
+ const { readFile } = await import('fs/promises');
754
+ console.log('');
755
+ console.log(chalk.hex('#7C3AED').bold(` ${scope === 'global' ? 'Add Skill (Global)' : 'Add Skill (Local)'}`));
756
+ console.log(chalk.dim(` Scope: ${scope === 'global' ? 'All sessions' : 'Current session only'}`));
757
+ console.log('');
758
+ console.log(chalk.yellow(' Usage: /skills add <global|local> <file-path>'));
759
+ console.log(chalk.dim(' Example: /skills add local code-simplifier.md'));
760
+ console.log('');
761
+ }
762
+ /**
763
+ * Add skill from file path (called with file path argument)
764
+ */
765
+ async handleAddSkillFromFile(scope, filePath) {
766
+ const { resolve } = await import('path');
767
+ const { readFile } = await import('fs/promises');
768
+ console.log('');
769
+ console.log(chalk.hex('#7C3AED').bold(` ${scope === 'global' ? 'Add Skill (Global)' : 'Add Skill (Local)'}`));
770
+ console.log(chalk.dim(` Scope: ${scope === 'global' ? 'All sessions' : 'Current session only'}`));
771
+ console.log('');
772
+ if (!filePath) {
773
+ console.log(chalk.yellow(' No file path provided.'));
774
+ console.log(chalk.dim(' Usage: /skills add <global|local> <file-path>'));
775
+ return;
776
+ }
777
+ // Resolve absolute path
778
+ const absolutePath = resolve(filePath);
779
+ // Read file
780
+ let fileContent;
781
+ try {
782
+ fileContent = await readFile(absolutePath, 'utf-8');
783
+ }
784
+ catch (error) {
785
+ console.log(chalk.red(` Error reading file: ${error.message}`));
786
+ return;
787
+ }
788
+ // Parse skill file
789
+ const skill = this.parseSkillFile(absolutePath, fileContent);
790
+ if (!skill) {
791
+ console.log(chalk.red(' Invalid skill file format.'));
792
+ console.log(chalk.dim(' Expected format: YAML frontmatter with name, description, and content'));
793
+ return;
794
+ }
795
+ console.log('');
796
+ console.log(chalk.hex('#7C3AED').bold(' Skill Information:'));
797
+ console.log(chalk.white(` Name: ${skill.name}`));
798
+ console.log(chalk.white(` Description: ${skill.description}`));
799
+ console.log(chalk.dim(` Model: ${skill.model || 'default'}`));
800
+ console.log('');
801
+ // Store skill based on scope
802
+ if (scope === 'global') {
803
+ // Register to SkillRegistry
804
+ try {
805
+ await this.skillRegistry.register({
806
+ metadata: {
807
+ name: skill.name,
808
+ description: skill.description,
809
+ version: '1.0.0',
810
+ tags: ['user-added'],
811
+ createdAt: new Date().toISOString(),
812
+ updatedAt: new Date().toISOString(),
813
+ },
814
+ content: skill.content,
815
+ });
816
+ console.log(chalk.green(` ✓ Skill "${skill.name}" added to global configuration`));
817
+ }
818
+ catch (error) {
819
+ console.log(chalk.red(` Error registering skill: ${error.message}`));
820
+ return;
821
+ }
822
+ }
823
+ else {
824
+ // Add to current session
825
+ if (!this.state.activeSkills) {
826
+ this.state.activeSkills = [];
827
+ }
828
+ this.state.activeSkills.push(skill);
829
+ console.log(chalk.green(` ✓ Skill "${skill.name}" added to current session`));
830
+ }
831
+ console.log('');
832
+ console.log(chalk.dim(' The skill will be applied to all subsequent conversations.'));
833
+ }
834
+ /**
835
+ * Remove skill from current session or global configuration
836
+ */
837
+ async handleRemoveSkillCommand(skillName) {
838
+ console.log('');
839
+ // First, try to remove from current session (local skills)
840
+ if (this.state.activeSkills) {
841
+ const localIndex = this.state.activeSkills.findIndex(s => s.name.toLowerCase() === skillName);
842
+ if (localIndex !== -1) {
843
+ const removed = this.state.activeSkills.splice(localIndex, 1)[0];
844
+ console.log(chalk.hex('#7C3AED').bold(' Remove Skill (Local)'));
845
+ console.log('');
846
+ console.log(chalk.white(` Name: ${removed.name}`));
847
+ console.log(chalk.white(` Description: ${removed.description}`));
848
+ console.log('');
849
+ console.log(chalk.green(` ✓ Skill "${removed.name}" removed from current session`));
850
+ console.log('');
851
+ return;
852
+ }
853
+ }
854
+ // If not found in local skills, try global skills
855
+ try {
856
+ const globalSkills = await this.skillRegistry.list();
857
+ const globalSkill = globalSkills.find(s => s.metadata.name.toLowerCase() === skillName);
858
+ if (globalSkill) {
859
+ console.log(chalk.hex('#7C3AED').bold(' Remove Skill (Global)'));
860
+ console.log('');
861
+ console.log(chalk.white(` Name: ${globalSkill.metadata.name}`));
862
+ console.log(chalk.white(` Description: ${globalSkill.metadata.description}`));
863
+ console.log('');
864
+ const success = await this.skillRegistry.remove(globalSkill.metadata.name);
865
+ if (success) {
866
+ console.log(chalk.green(` ✓ Skill "${globalSkill.metadata.name}" removed from global configuration`));
867
+ }
868
+ else {
869
+ console.log(chalk.red(` ✗ Failed to remove skill "${globalSkill.metadata.name}"`));
870
+ }
871
+ console.log('');
872
+ return;
873
+ }
874
+ }
875
+ catch (error) {
876
+ console.log(chalk.red(` Error removing skill: ${error.message}`));
877
+ console.log('');
878
+ return;
879
+ }
880
+ // Skill not found
881
+ console.log(chalk.yellow(` Skill "${skillName}" not found`));
882
+ console.log(chalk.dim(' Use "/skills list" to see available skills'));
883
+ console.log('');
884
+ }
885
+ /**
886
+ * Parse skill file with YAML frontmatter
887
+ */
888
+ parseSkillFile(filePath, content) {
889
+ // Match YAML frontmatter
890
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
891
+ if (!frontmatterMatch) {
892
+ return null;
893
+ }
894
+ const frontmatter = frontmatterMatch[1];
895
+ const body = frontmatterMatch[2];
896
+ // Parse fields
897
+ const parseField = (field) => {
898
+ const match = frontmatter.match(new RegExp(`^${field}:\\s*(.+)$`, 'm'));
899
+ return match ? match[1].trim() : '';
900
+ };
901
+ const name = parseField('name');
902
+ const description = parseField('description');
903
+ const model = parseField('model') || undefined;
904
+ if (!name || !description) {
905
+ return null;
906
+ }
907
+ return {
908
+ name,
909
+ description,
910
+ model,
911
+ content: body,
912
+ };
913
+ }
914
+ // ========================================================================
915
+ // Project Analysis Handler
916
+ // ========================================================================
917
+ async handleProjectCommand(arg) {
918
+ const { ProjectAnalyzer } = await import('../../../core/src/analysis/ProjectAnalyzer.js');
919
+ // Parse command arguments
920
+ const args = arg.trim().split(/\s+/);
921
+ const subcommand = args[0]?.toLowerCase();
922
+ if (subcommand === 'analyze') {
923
+ await this.handleProjectAnalyze();
924
+ return;
925
+ }
926
+ // Default: show usage
927
+ console.log('');
928
+ console.log(chalk.hex('#7C3AED').bold(' Project Analysis'));
929
+ console.log('');
930
+ console.log(chalk.yellow(' Usage: /project analyze'));
931
+ console.log(chalk.dim(' Analyze current project and generate documentation'));
932
+ console.log('');
933
+ }
934
+ /**
935
+ * Analyze current project and generate documentation
936
+ */
937
+ async handleProjectAnalyze() {
938
+ const { ProjectAnalyzer } = await import('../../../core/src/analysis/ProjectAnalyzer.js');
939
+ console.log('');
940
+ console.log(chalk.hex('#7C3AED').bold(' Analyzing Project...'));
941
+ console.log('');
942
+ try {
943
+ const analyzer = new ProjectAnalyzer(this.cwd, {
944
+ maxDepth: 5,
945
+ includeTests: true,
946
+ includeNodeModules: false,
947
+ analyzeImports: true,
948
+ });
949
+ const structure = await analyzer.analyze();
950
+ console.log(chalk.green(' ✓ Analysis complete'));
951
+ console.log('');
952
+ // Generate markdown documentation
953
+ const markdown = analyzer.generateMarkdown(structure);
954
+ // Save to file
955
+ const { writeFile } = await import('fs/promises');
956
+ const { join } = await import('path');
957
+ const docPath = join(this.cwd, 'PROJECT_ANALYSIS.md');
958
+ await writeFile(docPath, markdown, 'utf-8');
959
+ console.log(chalk.hex('#7C3AED').bold(' Project Summary:'));
960
+ console.log('');
961
+ console.log(chalk.white(` Name: ${structure.name}`));
962
+ console.log(chalk.white(` Type: ${this.formatProjectType(structure.type)}`));
963
+ console.log(chalk.white(` Files: ${structure.codeMetrics.totalFiles}`));
964
+ console.log(chalk.white(` Lines: ${structure.codeMetrics.totalLines.toLocaleString()}`));
965
+ console.log('');
966
+ console.log(chalk.hex('#7C3AED').bold(' Tech Stack:'));
967
+ console.log('');
968
+ if (structure.techStack.languages.length > 0) {
969
+ console.log(chalk.white(' Languages:'));
970
+ structure.techStack.languages.forEach(lang => console.log(chalk.dim(` - ${lang}`)));
971
+ }
972
+ if (structure.techStack.frameworks.length > 0) {
973
+ console.log(chalk.white(' Frameworks:'));
974
+ structure.techStack.frameworks.forEach(fw => console.log(chalk.dim(` - ${fw}`)));
975
+ }
976
+ console.log('');
977
+ console.log(chalk.hex('#7C3AED').bold(' Key Directories:'));
978
+ console.log('');
979
+ structure.directories.slice(0, 5).forEach(dir => {
980
+ console.log(chalk.white(` ${dir.name}/`));
981
+ console.log(chalk.dim(` ${dir.purpose} (${dir.fileCount} files)`));
982
+ });
983
+ console.log('');
984
+ console.log(chalk.green(` ✓ Full documentation saved to: ${docPath}`));
985
+ console.log('');
986
+ console.log(chalk.dim(' The analysis will be used to help the AI understand your project structure.'));
987
+ console.log('');
988
+ // Store analysis in state for injection into system prompt
989
+ this.state.projectAnalysis = markdown;
990
+ }
991
+ catch (error) {
992
+ console.log(chalk.red(` ✗ Error analyzing project: ${error.message}`));
993
+ console.log('');
994
+ }
995
+ }
996
+ /**
997
+ * Format project type for display
998
+ */
999
+ formatProjectType(type) {
1000
+ const typeNames = {
1001
+ unknown: 'Unknown',
1002
+ frontend: 'Frontend Application',
1003
+ backend: 'Backend Application',
1004
+ fullstack: 'Full Stack Application',
1005
+ mobile: 'Mobile Application',
1006
+ desktop: 'Desktop Application',
1007
+ library: 'Library/Package',
1008
+ cli: 'CLI Tool',
1009
+ monorepo: 'Monorepo',
1010
+ };
1011
+ return typeNames[type] || type;
1012
+ }
1013
+ // ========================================================================
1014
+ // Shell Command Handler
1015
+ // ========================================================================
1016
+ async handleShellCommand(cmd) {
1017
+ if (!cmd) {
1018
+ console.log(chalk.gray(' Usage: !<command>'));
1019
+ return;
1020
+ }
1021
+ console.log(chalk.gray(` $ ${cmd}`));
1022
+ const startTime = Date.now();
1023
+ try {
1024
+ const isWin = process.platform === 'win32';
1025
+ const shell = isWin ? 'powershell.exe' : '/bin/sh';
1026
+ const shellArgs = isWin ? ['-Command', cmd] : ['-c', cmd];
1027
+ await new Promise((resolve, reject) => {
1028
+ const child = spawn(shell, shellArgs, {
1029
+ cwd: this.cwd,
1030
+ stdio: ['inherit', 'pipe', 'pipe'],
1031
+ });
1032
+ child.stdout?.on('data', (chunk) => process.stdout.write(chunk.toString()));
1033
+ child.stderr?.on('data', (chunk) => process.stderr.write(chunk.toString()));
1034
+ child.on('close', (code) => {
1035
+ const duration = ((Date.now() - startTime) / 1000).toFixed(2);
1036
+ if (code === 0) {
1037
+ console.log(chalk.green(` ✓ exit 0`) + chalk.dim(` (${duration}s)`));
1038
+ }
1039
+ else {
1040
+ console.log(chalk.red(` ✗ exit ${code}`) + chalk.dim(` (${duration}s)`));
1041
+ }
1042
+ resolve();
1043
+ });
1044
+ child.on('error', reject);
1045
+ });
1046
+ }
1047
+ catch (err) {
1048
+ console.log(chalk.red(` Error: ${err.message}`));
1049
+ }
1050
+ }
1051
+ // ========================================================================
1052
+ // Input Processing
1053
+ // ========================================================================
1054
+ async processInput(input) {
1055
+ if (!this.sessionId)
1056
+ return;
1057
+ // Initialize active cursor on first use
1058
+ if (!this.activeCursor) {
1059
+ const { createPurpleCursor } = await import('../ui/components/ActiveCursor.js');
1060
+ this.activeCursor = createPurpleCursor();
1061
+ }
1062
+ // Expand @file references
1063
+ const expandedInput = await this.expandAtReferences(input);
1064
+ // Show user message with highlighted box (distinctive from AI responses)
1065
+ this.userMessageHighlight.render(input);
1066
+ // Clear any previous TODO panel
1067
+ this.todoProgressPanel.hide();
1068
+ // Add to messages
1069
+ this.state.messages.push({
1070
+ id: Date.now().toString(),
1071
+ role: 'user',
1072
+ content: input,
1073
+ timestamp: new Date(),
1074
+ });
1075
+ // Get mode prefix
1076
+ const modePrefix = this.getModePrefix();
1077
+ const fullInput = modePrefix ? `${modePrefix}\n\n${expandedInput}` : expandedInput;
1078
+ // Get model config to check for built-in search capability
1079
+ const modelConfigResult = this.configManager.getModelConfig(this.modelClient.getModel());
1080
+ // Build system prompt
1081
+ // Build system prompt with active skills
1082
+ let systemPrompt = buildSystemPrompt({
1083
+ workingDirectory: this.cwd,
1084
+ model: this.modelClient.getModel(),
1085
+ approvalMode: this.getEffectiveApprovalMode(),
1086
+ supportsBuiltinSearch: modelConfigResult?.model?.supportsBuiltinSearch,
1087
+ });
1088
+ // Inject active skills into system prompt
1089
+ if (this.state.activeSkills && this.state.activeSkills.length > 0) {
1090
+ systemPrompt += '\n\n';
1091
+ systemPrompt += '# Active Skills\n\n';
1092
+ for (const skill of this.state.activeSkills) {
1093
+ systemPrompt += `## ${skill.name}\n`;
1094
+ systemPrompt += `${skill.description}\n\n`;
1095
+ systemPrompt += `${skill.content}\n\n`;
1096
+ systemPrompt += '---\n\n';
1097
+ }
1098
+ }
1099
+ // Inject project analysis into system prompt
1100
+ if (this.state.projectAnalysis) {
1101
+ systemPrompt += '\n\n';
1102
+ systemPrompt += '# Project Context\n\n';
1103
+ systemPrompt += 'The following is an analysis of the current project structure and tech stack:\n\n';
1104
+ systemPrompt += this.state.projectAnalysis;
1105
+ systemPrompt += '\n';
1106
+ }
1107
+ // Reset tracking counters
1108
+ this.turnCount = 0;
1109
+ this.toolCallCount = 0;
1110
+ this.toolCallStatusDisplay.clear();
1111
+ // Start active cursor (purple circle animation)
1112
+ this.activeCursor.start();
1113
+ // Show compact execution status header
1114
+ this.showExecutionHeader();
1115
+ // Create agent loop
1116
+ this.currentLoop = new AgentLoop({
1117
+ modelClient: this.modelClient,
1118
+ sessionManager: this.sessionManager,
1119
+ toolRegistry: this.toolRegistry,
1120
+ systemPrompt,
1121
+ contextCompressor: this.contextCompressor,
1122
+ maxContextTokens: (this.config.core.maxTokens || 16384) * 8,
1123
+ onTextDelta: (text) => {
1124
+ // Stop cursor when text output starts (prevents cursor symbols in output)
1125
+ if (this.activeCursor && this.activeCursor.isVisible()) {
1126
+ this.activeCursor.stop();
1127
+ }
1128
+ this.currentText += text;
1129
+ process.stdout.write(text);
1130
+ },
1131
+ onToolStart: (name, toolCallId, input) => {
1132
+ this.toolCallCount++;
1133
+ this.toolCallStatusDisplay.startCall(toolCallId, name, input);
1134
+ this.updateStatusLine();
1135
+ },
1136
+ onToolComplete: (name, toolCallId, result) => {
1137
+ if (result.isError) {
1138
+ this.toolCallStatusDisplay.completeError(toolCallId, result.content || 'Unknown error');
1139
+ }
1140
+ else {
1141
+ this.toolCallStatusDisplay.completeSuccess(toolCallId, result.content);
1142
+ }
1143
+ // Handle TODO panel display for todo tool
1144
+ if (name === 'todo' && !result.isError && result.content) {
1145
+ this.handleTodoResult(result.content);
1146
+ }
1147
+ // Handle code file changes display
1148
+ if ((name === 'write_file' || name === 'replace' || name === 'edit_file') && !result.isError) {
1149
+ this.showCodeChangeIndicator(name, result.content);
1150
+ }
1151
+ this.updateStatusLine();
1152
+ },
1153
+ onThinkingStart: () => {
1154
+ if (this.state.showThinking) {
1155
+ this.thinkingContentDisplay.start();
1156
+ }
1157
+ },
1158
+ onThinkingDelta: (delta) => {
1159
+ if (this.state.showThinking) {
1160
+ this.thinkingContentDisplay.append(delta);
1161
+ }
1162
+ },
1163
+ onThinkingEnd: () => {
1164
+ if (this.state.showThinking) {
1165
+ this.thinkingContentDisplay.complete();
1166
+ }
1167
+ },
1168
+ onApprovalRequired: this.handleApproval.bind(this),
1169
+ onTurnStart: (turn) => {
1170
+ this.turnCount = turn;
1171
+ this.updateStatusLine();
1172
+ },
1173
+ onTurnEnd: () => {
1174
+ // Nothing
1175
+ },
1176
+ onContextCompress: (orig, result, action) => {
1177
+ console.log(chalk.dim(` 🔄 context: ${orig} → ${result} tokens (${action})`));
1178
+ },
1179
+ });
1180
+ try {
1181
+ const result = await this.currentLoop.runStream(this.sessionId, fullInput);
1182
+ // Add assistant message
1183
+ this.state.messages.push({
1184
+ id: (Date.now() + 1).toString(),
1185
+ role: 'assistant',
1186
+ content: this.currentText,
1187
+ timestamp: new Date(),
1188
+ });
1189
+ // Update context usage
1190
+ const totalTokens = result.totalInputTokens + result.totalOutputTokens;
1191
+ this.state.contextUsage = Math.min(100, Math.round((totalTokens / 128000) * 100));
1192
+ // Show summary
1193
+ console.log('');
1194
+ console.log(chalk.dim(` ✓ ${result.turnsCompleted} turns · ${totalTokens.toLocaleString()} tokens`));
1195
+ // Persist session
1196
+ this.sessionManager.persist(this.sessionId);
1197
+ }
1198
+ catch (err) {
1199
+ if (err.name !== 'CancelledError') {
1200
+ console.log(chalk.red(`\n Error: ${err.message}`));
1201
+ }
1202
+ }
1203
+ finally {
1204
+ this.currentLoop = null;
1205
+ this.currentText = '';
1206
+ // Stop active cursor
1207
+ if (this.activeCursor)
1208
+ this.activeCursor.stop();
1209
+ }
1210
+ }
1211
+ // ========================================================================
1212
+ // @ File Reference Expansion
1213
+ // ========================================================================
1214
+ async expandAtReferences(input) {
1215
+ const atPattern = /@([\w./\-\\]+)/g;
1216
+ const matches = [...input.matchAll(atPattern)];
1217
+ if (matches.length === 0)
1218
+ return input;
1219
+ const injections = [];
1220
+ for (const match of matches) {
1221
+ const refPath = match[1];
1222
+ if (!refPath)
1223
+ continue;
1224
+ const absPath = path.isAbsolute(refPath)
1225
+ ? refPath
1226
+ : path.resolve(this.cwd, refPath);
1227
+ try {
1228
+ if (!fs.existsSync(absPath)) {
1229
+ injections.push(`[@${refPath}: not found]`);
1230
+ continue;
1231
+ }
1232
+ const stat = fs.statSync(absPath);
1233
+ if (stat.isDirectory()) {
1234
+ const files = fs.readdirSync(absPath).slice(0, 20);
1235
+ injections.push(`\n\`\`\`\n# Directory: ${refPath}\n${files.join('\n')}\n\`\`\`\n`);
1236
+ }
1237
+ else {
1238
+ const content = fs.readFileSync(absPath, 'utf-8');
1239
+ const ext = path.extname(refPath).slice(1) || 'txt';
1240
+ injections.push(`\n\`\`\`${ext}\n# ${refPath}\n${content}\n\`\`\`\n`);
1241
+ }
1242
+ console.log(chalk.dim(` @ ${refPath}`));
1243
+ }
1244
+ catch (err) {
1245
+ injections.push(`[@${refPath}: error]`);
1246
+ }
1247
+ }
1248
+ return input + '\n' + injections.join('\n');
1249
+ }
1250
+ // ========================================================================
1251
+ // Approval Handler
1252
+ // ========================================================================
1253
+ async handleApproval(request) {
1254
+ const mode = this.getEffectiveApprovalMode();
1255
+ if (mode === 'yolo' || mode === 'accepting_edits') {
1256
+ return { requestId: request.id, approved: true };
1257
+ }
1258
+ console.log('');
1259
+ console.log(chalk.yellow.bold(' ⚠ Approval Required'));
1260
+ console.log(chalk.gray(` Tool: ${request.toolName}`));
1261
+ console.log(chalk.gray(` Risk: ${request.risk}`));
1262
+ console.log('');
1263
+ // For now, auto-approve in non-interactive mode
1264
+ // In a full implementation, this would use a ConfirmDialog
1265
+ return { requestId: request.id, approved: true };
1266
+ }
1267
+ // ========================================================================
1268
+ // Helpers
1269
+ // ========================================================================
1270
+ getModePrefix() {
1271
+ switch (this.state.mode) {
1272
+ case 'plan':
1273
+ return '[PLAN MODE] First analyze and create a step-by-step plan. Wait for confirmation before executing.';
1274
+ case 'ask':
1275
+ return '[ASK MODE] Only answer questions. Do NOT modify files or execute commands.';
1276
+ default:
1277
+ return '';
1278
+ }
1279
+ }
1280
+ getEffectiveApprovalMode() {
1281
+ switch (this.state.mode) {
1282
+ case 'auto': return 'yolo';
1283
+ case 'plan': return 'plan';
1284
+ case 'ask': return 'plan';
1285
+ default: return 'default';
1286
+ }
1287
+ }
1288
+ summarizeToolInput(name, input) {
1289
+ switch (name) {
1290
+ case 'read_file':
1291
+ case 'list_directory':
1292
+ return String(input.file_path || input.path || input.target_directory || '').replace(/\\/g, '/').split('/').slice(-2).join('/');
1293
+ case 'write_file':
1294
+ return String(input.file_path || input.path || '').replace(/\\/g, '/').split('/').slice(-2).join('/') + ' (write)';
1295
+ case 'edit_file':
1296
+ case 'replace_in_file':
1297
+ return String(input.file_path || '').replace(/\\/g, '/').split('/').slice(-2).join('/') + ' (edit)';
1298
+ case 'execute_command':
1299
+ return String(input.command || '').slice(0, 60);
1300
+ case 'search_file':
1301
+ return String(input.pattern || '') + ' in ' + String(input.path || '.').split('/').pop();
1302
+ case 'search_content':
1303
+ return '"' + String(input.pattern || '').slice(0, 40) + '"';
1304
+ case 'web_search':
1305
+ return '"' + String(input.query || '').slice(0, 40) + '"';
1306
+ default:
1307
+ const vals = Object.values(input).filter((v) => typeof v === 'string' && v.length > 0);
1308
+ return vals.length > 0 ? vals[0].slice(0, 50) : '';
1309
+ }
1310
+ }
1311
+ /**
1312
+ * Handle TODO tool result and display in fixed-position panel
1313
+ */
1314
+ handleTodoResult(result) {
1315
+ if (!result || result === 'No tasks tracked.' || result === 'All tasks cleared.') {
1316
+ this.todoProgressPanel.hide();
1317
+ return;
1318
+ }
1319
+ const lines = result.split('\n').filter((l) => l.trim());
1320
+ if (lines.length === 0) {
1321
+ this.todoProgressPanel.hide();
1322
+ return;
1323
+ }
1324
+ // Parse TODO items from the result string
1325
+ const todos = [];
1326
+ let idx = 0;
1327
+ for (const line of lines) {
1328
+ const pendingMatch = line.match(/^○\s+\[pending\s*\]\s+(.+)/);
1329
+ const inProgressMatch = line.match(/^◉\s+\[in_progress\s*\]\s+(.+)/);
1330
+ const completedMatch = line.match(/^●\s+\[completed\s*\]\s+(.+)/);
1331
+ const failedMatch = line.match(/^✗\s+\[failed\s*\]\s+(.+)/);
1332
+ // Detect priority from task text
1333
+ const detectPriority = (text) => {
1334
+ if (/high|critical|urgent|重要/i.test(text))
1335
+ return 'high';
1336
+ if (/low|minor|低/i.test(text))
1337
+ return 'low';
1338
+ if (/medium|normal|中/i.test(text))
1339
+ return 'medium';
1340
+ return undefined;
1341
+ };
1342
+ if (completedMatch) {
1343
+ todos.push({
1344
+ id: String(idx++),
1345
+ task: completedMatch[1].trim(),
1346
+ status: 'completed',
1347
+ priority: detectPriority(completedMatch[1]),
1348
+ });
1349
+ }
1350
+ else if (inProgressMatch) {
1351
+ todos.push({
1352
+ id: String(idx++),
1353
+ task: inProgressMatch[1].trim(),
1354
+ status: 'in_progress',
1355
+ priority: detectPriority(inProgressMatch[1]),
1356
+ });
1357
+ }
1358
+ else if (pendingMatch) {
1359
+ todos.push({
1360
+ id: String(idx++),
1361
+ task: pendingMatch[1].trim(),
1362
+ status: 'pending',
1363
+ priority: detectPriority(pendingMatch[1]),
1364
+ });
1365
+ }
1366
+ else if (failedMatch) {
1367
+ todos.push({
1368
+ id: String(idx++),
1369
+ task: failedMatch[1].trim(),
1370
+ status: 'failed',
1371
+ priority: detectPriority(failedMatch[1]),
1372
+ });
1373
+ }
1374
+ }
1375
+ // Update and show the fixed-position TODO panel
1376
+ if (todos.length > 0) {
1377
+ this.todoProgressPanel.setTodos(todos);
1378
+ this.todoProgressPanel.show();
1379
+ }
1380
+ }
1381
+ /**
1382
+ * Show compact execution status header
1383
+ */
1384
+ showExecutionHeader() {
1385
+ console.log(chalk.dim(' ┌─ 执行开始 ' + '─'.repeat(40)));
1386
+ }
1387
+ /**
1388
+ * Update the compact status line showing current progress
1389
+ */
1390
+ updateStatusLine() {
1391
+ const stats = this.toolCallStatusDisplay.getStats();
1392
+ const statusIcon = stats.error > 0 ? chalk.red('⚠') : stats.running > 0 ? chalk.yellow('◉') : chalk.green('✓');
1393
+ const turnStr = this.turnCount > 0 ? `turn ${this.turnCount}` : 'init';
1394
+ const toolStr = `${stats.success}✓ ${stats.error}✗`;
1395
+ const status = `${statusIcon} ${chalk.dim(turnStr)} ${chalk.dim('·')} ${chalk.dim(toolStr)}`;
1396
+ // Only update if changed
1397
+ if (status !== this.lastStatusLine) {
1398
+ this.lastStatusLine = status;
1399
+ // Write status to a fixed position (compact inline update)
1400
+ process.stdout.write(`\r${status} `);
1401
+ }
1402
+ }
1403
+ /**
1404
+ * Show indicator when code files are modified
1405
+ */
1406
+ showCodeChangeIndicator(name, result) {
1407
+ // Extract file path from result if available
1408
+ const pathMatch = result?.match(/(.+\.\w+)/);
1409
+ const filePath = pathMatch ? pathMatch[1].split('/').slice(-2).join('/') : 'file';
1410
+ // Show compact code change indicator
1411
+ const icon = name === 'write_file' ? chalk.cyan('📝') : chalk.yellow('✏️');
1412
+ console.log(`\n ${icon} ${chalk.dim(filePath)}`);
1413
+ }
1414
+ }
1415
+ //# sourceMappingURL=InkBasedRepl.js.map