erosolar-cli 1.7.413 → 1.7.415

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 (1008) hide show
  1. package/agents/erosolar-code.rules.json +1 -1
  2. package/agents/general.rules.json +1 -1
  3. package/dist/core/bashCommandGuidance.d.ts +16 -0
  4. package/dist/core/bashCommandGuidance.d.ts.map +1 -0
  5. package/dist/core/bashCommandGuidance.js +40 -0
  6. package/dist/core/bashCommandGuidance.js.map +1 -0
  7. package/dist/core/toolPreconditions.d.ts.map +1 -1
  8. package/dist/core/toolPreconditions.js +8 -18
  9. package/dist/core/toolPreconditions.js.map +1 -1
  10. package/dist/core/toolRuntime.js +1 -1
  11. package/dist/core/toolRuntime.js.map +1 -1
  12. package/dist/core/toolValidation.d.ts +1 -2
  13. package/dist/core/toolValidation.d.ts.map +1 -1
  14. package/dist/core/toolValidation.js +27 -27
  15. package/dist/core/toolValidation.js.map +1 -1
  16. package/dist/shell/interactiveShell.d.ts +1 -0
  17. package/dist/shell/interactiveShell.d.ts.map +1 -1
  18. package/dist/shell/interactiveShell.js +32 -20
  19. package/dist/shell/interactiveShell.js.map +1 -1
  20. package/dist/shell/systemPrompt.js +1 -1
  21. package/dist/shell/systemPrompt.js.map +1 -1
  22. package/dist/tools/bashTools.d.ts.map +1 -1
  23. package/dist/tools/bashTools.js +7 -18
  24. package/dist/tools/bashTools.js.map +1 -1
  25. package/dist/ui/toolDisplay.d.ts.map +1 -1
  26. package/dist/ui/toolDisplay.js +0 -1
  27. package/dist/ui/toolDisplay.js.map +1 -1
  28. package/package.json +1 -1
  29. package/dist/StringUtils.d.ts +0 -8
  30. package/dist/StringUtils.d.ts.map +0 -1
  31. package/dist/StringUtils.js +0 -11
  32. package/dist/StringUtils.js.map +0 -1
  33. package/dist/adapters/browser/index.d.ts +0 -12
  34. package/dist/adapters/browser/index.d.ts.map +0 -1
  35. package/dist/adapters/browser/index.js +0 -11
  36. package/dist/adapters/browser/index.js.map +0 -1
  37. package/dist/adapters/node/index.d.ts +0 -17
  38. package/dist/adapters/node/index.d.ts.map +0 -1
  39. package/dist/adapters/node/index.js +0 -35
  40. package/dist/adapters/node/index.js.map +0 -1
  41. package/dist/adapters/remote/index.d.ts +0 -13
  42. package/dist/adapters/remote/index.d.ts.map +0 -1
  43. package/dist/adapters/remote/index.js +0 -20
  44. package/dist/adapters/remote/index.js.map +0 -1
  45. package/dist/adapters/types.d.ts +0 -14
  46. package/dist/adapters/types.d.ts.map +0 -1
  47. package/dist/adapters/types.js +0 -2
  48. package/dist/adapters/types.js.map +0 -1
  49. package/dist/bin/erosolar.d.ts +0 -9
  50. package/dist/bin/erosolar.d.ts.map +0 -1
  51. package/dist/bin/erosolar.js +0 -93
  52. package/dist/bin/erosolar.js.map +0 -1
  53. package/dist/bin/selfTest.d.ts +0 -14
  54. package/dist/bin/selfTest.d.ts.map +0 -1
  55. package/dist/bin/selfTest.js +0 -304
  56. package/dist/bin/selfTest.js.map +0 -1
  57. package/dist/browser/BrowserSessionManager.d.ts +0 -307
  58. package/dist/browser/BrowserSessionManager.d.ts.map +0 -1
  59. package/dist/browser/BrowserSessionManager.js +0 -713
  60. package/dist/browser/BrowserSessionManager.js.map +0 -1
  61. package/dist/capabilities/advancedTestGenerationCapability.d.ts +0 -17
  62. package/dist/capabilities/advancedTestGenerationCapability.d.ts.map +0 -1
  63. package/dist/capabilities/advancedTestGenerationCapability.js +0 -28
  64. package/dist/capabilities/advancedTestGenerationCapability.js.map +0 -1
  65. package/dist/capabilities/agentSpawningCapability.d.ts +0 -6
  66. package/dist/capabilities/agentSpawningCapability.d.ts.map +0 -1
  67. package/dist/capabilities/agentSpawningCapability.js +0 -168
  68. package/dist/capabilities/agentSpawningCapability.js.map +0 -1
  69. package/dist/capabilities/askUserCapability.d.ts +0 -21
  70. package/dist/capabilities/askUserCapability.d.ts.map +0 -1
  71. package/dist/capabilities/askUserCapability.js +0 -155
  72. package/dist/capabilities/askUserCapability.js.map +0 -1
  73. package/dist/capabilities/bashCapability.d.ts +0 -13
  74. package/dist/capabilities/bashCapability.d.ts.map +0 -1
  75. package/dist/capabilities/bashCapability.js +0 -24
  76. package/dist/capabilities/bashCapability.js.map +0 -1
  77. package/dist/capabilities/browserAutomationCapability.d.ts +0 -37
  78. package/dist/capabilities/browserAutomationCapability.d.ts.map +0 -1
  79. package/dist/capabilities/browserAutomationCapability.js +0 -49
  80. package/dist/capabilities/browserAutomationCapability.js.map +0 -1
  81. package/dist/capabilities/buildCapability.d.ts +0 -24
  82. package/dist/capabilities/buildCapability.d.ts.map +0 -1
  83. package/dist/capabilities/buildCapability.js +0 -25
  84. package/dist/capabilities/buildCapability.js.map +0 -1
  85. package/dist/capabilities/cloudCapability.d.ts +0 -13
  86. package/dist/capabilities/cloudCapability.d.ts.map +0 -1
  87. package/dist/capabilities/cloudCapability.js +0 -38
  88. package/dist/capabilities/cloudCapability.js.map +0 -1
  89. package/dist/capabilities/codeAnalysisCapability.d.ts +0 -13
  90. package/dist/capabilities/codeAnalysisCapability.d.ts.map +0 -1
  91. package/dist/capabilities/codeAnalysisCapability.js +0 -24
  92. package/dist/capabilities/codeAnalysisCapability.js.map +0 -1
  93. package/dist/capabilities/codeGenerationCapability.d.ts +0 -13
  94. package/dist/capabilities/codeGenerationCapability.d.ts.map +0 -1
  95. package/dist/capabilities/codeGenerationCapability.js +0 -25
  96. package/dist/capabilities/codeGenerationCapability.js.map +0 -1
  97. package/dist/capabilities/codeQualityCapability.d.ts +0 -13
  98. package/dist/capabilities/codeQualityCapability.d.ts.map +0 -1
  99. package/dist/capabilities/codeQualityCapability.js +0 -25
  100. package/dist/capabilities/codeQualityCapability.js.map +0 -1
  101. package/dist/capabilities/dependencySecurityCapability.d.ts +0 -13
  102. package/dist/capabilities/dependencySecurityCapability.d.ts.map +0 -1
  103. package/dist/capabilities/dependencySecurityCapability.js +0 -24
  104. package/dist/capabilities/dependencySecurityCapability.js.map +0 -1
  105. package/dist/capabilities/devCapability.d.ts +0 -13
  106. package/dist/capabilities/devCapability.d.ts.map +0 -1
  107. package/dist/capabilities/devCapability.js +0 -24
  108. package/dist/capabilities/devCapability.js.map +0 -1
  109. package/dist/capabilities/editCapability.d.ts +0 -17
  110. package/dist/capabilities/editCapability.d.ts.map +0 -1
  111. package/dist/capabilities/editCapability.js +0 -27
  112. package/dist/capabilities/editCapability.js.map +0 -1
  113. package/dist/capabilities/emailCapability.d.ts +0 -12
  114. package/dist/capabilities/emailCapability.d.ts.map +0 -1
  115. package/dist/capabilities/emailCapability.js +0 -22
  116. package/dist/capabilities/emailCapability.js.map +0 -1
  117. package/dist/capabilities/enhancedCodeIntelligenceCapability.d.ts +0 -17
  118. package/dist/capabilities/enhancedCodeIntelligenceCapability.d.ts.map +0 -1
  119. package/dist/capabilities/enhancedCodeIntelligenceCapability.js +0 -28
  120. package/dist/capabilities/enhancedCodeIntelligenceCapability.js.map +0 -1
  121. package/dist/capabilities/enhancedDevWorkflowCapability.d.ts +0 -17
  122. package/dist/capabilities/enhancedDevWorkflowCapability.d.ts.map +0 -1
  123. package/dist/capabilities/enhancedDevWorkflowCapability.js +0 -28
  124. package/dist/capabilities/enhancedDevWorkflowCapability.js.map +0 -1
  125. package/dist/capabilities/enhancedGitCapability.d.ts +0 -7
  126. package/dist/capabilities/enhancedGitCapability.d.ts.map +0 -1
  127. package/dist/capabilities/enhancedGitCapability.js +0 -220
  128. package/dist/capabilities/enhancedGitCapability.js.map +0 -1
  129. package/dist/capabilities/filesystemCapability.d.ts +0 -13
  130. package/dist/capabilities/filesystemCapability.d.ts.map +0 -1
  131. package/dist/capabilities/filesystemCapability.js +0 -24
  132. package/dist/capabilities/filesystemCapability.js.map +0 -1
  133. package/dist/capabilities/frontendTestingCapability.d.ts +0 -13
  134. package/dist/capabilities/frontendTestingCapability.d.ts.map +0 -1
  135. package/dist/capabilities/frontendTestingCapability.js +0 -28
  136. package/dist/capabilities/frontendTestingCapability.js.map +0 -1
  137. package/dist/capabilities/globCapability.d.ts +0 -17
  138. package/dist/capabilities/globCapability.d.ts.map +0 -1
  139. package/dist/capabilities/globCapability.js +0 -27
  140. package/dist/capabilities/globCapability.js.map +0 -1
  141. package/dist/capabilities/index.d.ts +0 -26
  142. package/dist/capabilities/index.d.ts.map +0 -1
  143. package/dist/capabilities/index.js +0 -26
  144. package/dist/capabilities/index.js.map +0 -1
  145. package/dist/capabilities/interactionCapability.d.ts +0 -12
  146. package/dist/capabilities/interactionCapability.d.ts.map +0 -1
  147. package/dist/capabilities/interactionCapability.js +0 -22
  148. package/dist/capabilities/interactionCapability.js.map +0 -1
  149. package/dist/capabilities/learnCapability.d.ts +0 -22
  150. package/dist/capabilities/learnCapability.d.ts.map +0 -1
  151. package/dist/capabilities/learnCapability.js +0 -37
  152. package/dist/capabilities/learnCapability.js.map +0 -1
  153. package/dist/capabilities/mcpCapability.d.ts +0 -6
  154. package/dist/capabilities/mcpCapability.d.ts.map +0 -1
  155. package/dist/capabilities/mcpCapability.js +0 -19
  156. package/dist/capabilities/mcpCapability.js.map +0 -1
  157. package/dist/capabilities/notebookCapability.d.ts +0 -17
  158. package/dist/capabilities/notebookCapability.d.ts.map +0 -1
  159. package/dist/capabilities/notebookCapability.js +0 -27
  160. package/dist/capabilities/notebookCapability.js.map +0 -1
  161. package/dist/capabilities/performanceMonitoringCapability.d.ts +0 -108
  162. package/dist/capabilities/performanceMonitoringCapability.d.ts.map +0 -1
  163. package/dist/capabilities/performanceMonitoringCapability.js +0 -176
  164. package/dist/capabilities/performanceMonitoringCapability.js.map +0 -1
  165. package/dist/capabilities/planningCapability.d.ts +0 -16
  166. package/dist/capabilities/planningCapability.d.ts.map +0 -1
  167. package/dist/capabilities/planningCapability.js +0 -26
  168. package/dist/capabilities/planningCapability.js.map +0 -1
  169. package/dist/capabilities/refactoringCapability.d.ts +0 -13
  170. package/dist/capabilities/refactoringCapability.d.ts.map +0 -1
  171. package/dist/capabilities/refactoringCapability.js +0 -25
  172. package/dist/capabilities/refactoringCapability.js.map +0 -1
  173. package/dist/capabilities/repoChecksCapability.d.ts +0 -10
  174. package/dist/capabilities/repoChecksCapability.d.ts.map +0 -1
  175. package/dist/capabilities/repoChecksCapability.js +0 -24
  176. package/dist/capabilities/repoChecksCapability.js.map +0 -1
  177. package/dist/capabilities/searchCapability.d.ts +0 -13
  178. package/dist/capabilities/searchCapability.d.ts.map +0 -1
  179. package/dist/capabilities/searchCapability.js +0 -24
  180. package/dist/capabilities/searchCapability.js.map +0 -1
  181. package/dist/capabilities/skillCapability.d.ts +0 -3
  182. package/dist/capabilities/skillCapability.d.ts.map +0 -1
  183. package/dist/capabilities/skillCapability.js +0 -77
  184. package/dist/capabilities/skillCapability.js.map +0 -1
  185. package/dist/capabilities/taskManagementCapability.d.ts +0 -12
  186. package/dist/capabilities/taskManagementCapability.d.ts.map +0 -1
  187. package/dist/capabilities/taskManagementCapability.js +0 -22
  188. package/dist/capabilities/taskManagementCapability.js.map +0 -1
  189. package/dist/capabilities/testingCapability.d.ts +0 -13
  190. package/dist/capabilities/testingCapability.d.ts.map +0 -1
  191. package/dist/capabilities/testingCapability.js +0 -25
  192. package/dist/capabilities/testingCapability.js.map +0 -1
  193. package/dist/capabilities/todoCapability.d.ts +0 -19
  194. package/dist/capabilities/todoCapability.d.ts.map +0 -1
  195. package/dist/capabilities/todoCapability.js +0 -169
  196. package/dist/capabilities/todoCapability.js.map +0 -1
  197. package/dist/capabilities/toolManifest.d.ts +0 -3
  198. package/dist/capabilities/toolManifest.d.ts.map +0 -1
  199. package/dist/capabilities/toolManifest.js +0 -160
  200. package/dist/capabilities/toolManifest.js.map +0 -1
  201. package/dist/capabilities/toolRegistry.d.ts +0 -24
  202. package/dist/capabilities/toolRegistry.d.ts.map +0 -1
  203. package/dist/capabilities/toolRegistry.js +0 -150
  204. package/dist/capabilities/toolRegistry.js.map +0 -1
  205. package/dist/capabilities/validationCapability.d.ts +0 -13
  206. package/dist/capabilities/validationCapability.d.ts.map +0 -1
  207. package/dist/capabilities/validationCapability.js +0 -24
  208. package/dist/capabilities/validationCapability.js.map +0 -1
  209. package/dist/capabilities/webCapability.d.ts +0 -12
  210. package/dist/capabilities/webCapability.d.ts.map +0 -1
  211. package/dist/capabilities/webCapability.js +0 -22
  212. package/dist/capabilities/webCapability.js.map +0 -1
  213. package/dist/config.d.ts +0 -25
  214. package/dist/config.d.ts.map +0 -1
  215. package/dist/config.js +0 -140
  216. package/dist/config.js.map +0 -1
  217. package/dist/contracts/v1/agent.d.ts +0 -147
  218. package/dist/contracts/v1/agent.d.ts.map +0 -1
  219. package/dist/contracts/v1/agent.js +0 -8
  220. package/dist/contracts/v1/agent.js.map +0 -1
  221. package/dist/contracts/v1/agentProfileManifest.d.ts +0 -60
  222. package/dist/contracts/v1/agentProfileManifest.d.ts.map +0 -1
  223. package/dist/contracts/v1/agentProfileManifest.js +0 -9
  224. package/dist/contracts/v1/agentProfileManifest.js.map +0 -1
  225. package/dist/contracts/v1/agentRules.d.ts +0 -60
  226. package/dist/contracts/v1/agentRules.d.ts.map +0 -1
  227. package/dist/contracts/v1/agentRules.js +0 -10
  228. package/dist/contracts/v1/agentRules.js.map +0 -1
  229. package/dist/contracts/v1/provider.d.ts +0 -149
  230. package/dist/contracts/v1/provider.d.ts.map +0 -1
  231. package/dist/contracts/v1/provider.js +0 -7
  232. package/dist/contracts/v1/provider.js.map +0 -1
  233. package/dist/contracts/v1/tool.d.ts +0 -136
  234. package/dist/contracts/v1/tool.d.ts.map +0 -1
  235. package/dist/contracts/v1/tool.js +0 -7
  236. package/dist/contracts/v1/tool.js.map +0 -1
  237. package/dist/contracts/v1/toolAccess.d.ts +0 -43
  238. package/dist/contracts/v1/toolAccess.d.ts.map +0 -1
  239. package/dist/contracts/v1/toolAccess.js +0 -9
  240. package/dist/contracts/v1/toolAccess.js.map +0 -1
  241. package/dist/core/LazyLoader.d.ts +0 -129
  242. package/dist/core/LazyLoader.d.ts.map +0 -1
  243. package/dist/core/LazyLoader.js +0 -240
  244. package/dist/core/LazyLoader.js.map +0 -1
  245. package/dist/core/agent.d.ts +0 -153
  246. package/dist/core/agent.d.ts.map +0 -1
  247. package/dist/core/agent.js +0 -881
  248. package/dist/core/agent.js.map +0 -1
  249. package/dist/core/agentProfileManifest.d.ts +0 -3
  250. package/dist/core/agentProfileManifest.d.ts.map +0 -1
  251. package/dist/core/agentProfileManifest.js +0 -188
  252. package/dist/core/agentProfileManifest.js.map +0 -1
  253. package/dist/core/agentProfiles.d.ts +0 -22
  254. package/dist/core/agentProfiles.d.ts.map +0 -1
  255. package/dist/core/agentProfiles.js +0 -35
  256. package/dist/core/agentProfiles.js.map +0 -1
  257. package/dist/core/agentRulebook.d.ts +0 -11
  258. package/dist/core/agentRulebook.d.ts.map +0 -1
  259. package/dist/core/agentRulebook.js +0 -136
  260. package/dist/core/agentRulebook.js.map +0 -1
  261. package/dist/core/agentSchemaLoader.d.ts +0 -131
  262. package/dist/core/agentSchemaLoader.d.ts.map +0 -1
  263. package/dist/core/agentSchemaLoader.js +0 -234
  264. package/dist/core/agentSchemaLoader.js.map +0 -1
  265. package/dist/core/aiErrorFixer.d.ts +0 -70
  266. package/dist/core/aiErrorFixer.d.ts.map +0 -1
  267. package/dist/core/aiErrorFixer.js +0 -402
  268. package/dist/core/aiErrorFixer.js.map +0 -1
  269. package/dist/core/alphaZeroEngine.d.ts +0 -269
  270. package/dist/core/alphaZeroEngine.d.ts.map +0 -1
  271. package/dist/core/alphaZeroEngine.js +0 -523
  272. package/dist/core/alphaZeroEngine.js.map +0 -1
  273. package/dist/core/alphaZeroModular.d.ts +0 -186
  274. package/dist/core/alphaZeroModular.d.ts.map +0 -1
  275. package/dist/core/alphaZeroModular.js +0 -755
  276. package/dist/core/alphaZeroModular.js.map +0 -1
  277. package/dist/core/alphaZeroOrchestrator.d.ts +0 -140
  278. package/dist/core/alphaZeroOrchestrator.d.ts.map +0 -1
  279. package/dist/core/alphaZeroOrchestrator.js +0 -418
  280. package/dist/core/alphaZeroOrchestrator.js.map +0 -1
  281. package/dist/core/checkpoint.d.ts +0 -76
  282. package/dist/core/checkpoint.d.ts.map +0 -1
  283. package/dist/core/checkpoint.js +0 -278
  284. package/dist/core/checkpoint.js.map +0 -1
  285. package/dist/core/claudeCodeFeatures.d.ts +0 -64
  286. package/dist/core/claudeCodeFeatures.d.ts.map +0 -1
  287. package/dist/core/claudeCodeFeatures.js +0 -163
  288. package/dist/core/claudeCodeFeatures.js.map +0 -1
  289. package/dist/core/cliTestHarness.d.ts +0 -200
  290. package/dist/core/cliTestHarness.d.ts.map +0 -1
  291. package/dist/core/cliTestHarness.js +0 -549
  292. package/dist/core/cliTestHarness.js.map +0 -1
  293. package/dist/core/contextManager.d.ts +0 -265
  294. package/dist/core/contextManager.d.ts.map +0 -1
  295. package/dist/core/contextManager.js +0 -1060
  296. package/dist/core/contextManager.js.map +0 -1
  297. package/dist/core/contextWindow.d.ts +0 -42
  298. package/dist/core/contextWindow.d.ts.map +0 -1
  299. package/dist/core/contextWindow.js +0 -123
  300. package/dist/core/contextWindow.js.map +0 -1
  301. package/dist/core/costTracker.d.ts +0 -87
  302. package/dist/core/costTracker.d.ts.map +0 -1
  303. package/dist/core/costTracker.js +0 -285
  304. package/dist/core/costTracker.js.map +0 -1
  305. package/dist/core/customCommands.d.ts +0 -19
  306. package/dist/core/customCommands.d.ts.map +0 -1
  307. package/dist/core/customCommands.js +0 -84
  308. package/dist/core/customCommands.js.map +0 -1
  309. package/dist/core/errors/apiKeyErrors.d.ts +0 -11
  310. package/dist/core/errors/apiKeyErrors.d.ts.map +0 -1
  311. package/dist/core/errors/apiKeyErrors.js +0 -159
  312. package/dist/core/errors/apiKeyErrors.js.map +0 -1
  313. package/dist/core/errors/errorTypes.d.ts +0 -111
  314. package/dist/core/errors/errorTypes.d.ts.map +0 -1
  315. package/dist/core/errors/errorTypes.js +0 -348
  316. package/dist/core/errors/errorTypes.js.map +0 -1
  317. package/dist/core/errors/errorUtils.d.ts +0 -87
  318. package/dist/core/errors/errorUtils.d.ts.map +0 -1
  319. package/dist/core/errors/errorUtils.js +0 -158
  320. package/dist/core/errors/errorUtils.js.map +0 -1
  321. package/dist/core/errors/safetyValidator.d.ts +0 -71
  322. package/dist/core/errors/safetyValidator.d.ts.map +0 -1
  323. package/dist/core/errors/safetyValidator.js +0 -302
  324. package/dist/core/errors/safetyValidator.js.map +0 -1
  325. package/dist/core/errors.d.ts +0 -4
  326. package/dist/core/errors.d.ts.map +0 -1
  327. package/dist/core/errors.js +0 -33
  328. package/dist/core/errors.js.map +0 -1
  329. package/dist/core/failureRecovery.d.ts +0 -122
  330. package/dist/core/failureRecovery.d.ts.map +0 -1
  331. package/dist/core/failureRecovery.js +0 -477
  332. package/dist/core/failureRecovery.js.map +0 -1
  333. package/dist/core/hooks.d.ts +0 -113
  334. package/dist/core/hooks.d.ts.map +0 -1
  335. package/dist/core/hooks.js +0 -267
  336. package/dist/core/hooks.js.map +0 -1
  337. package/dist/core/intelligentTestFlows.d.ts +0 -126
  338. package/dist/core/intelligentTestFlows.d.ts.map +0 -1
  339. package/dist/core/intelligentTestFlows.js +0 -678
  340. package/dist/core/intelligentTestFlows.js.map +0 -1
  341. package/dist/core/isolatedVerifier.d.ts +0 -40
  342. package/dist/core/isolatedVerifier.d.ts.map +0 -1
  343. package/dist/core/isolatedVerifier.js +0 -129
  344. package/dist/core/isolatedVerifier.js.map +0 -1
  345. package/dist/core/learningPersistence.d.ts +0 -145
  346. package/dist/core/learningPersistence.d.ts.map +0 -1
  347. package/dist/core/learningPersistence.js +0 -477
  348. package/dist/core/learningPersistence.js.map +0 -1
  349. package/dist/core/memorySystem.d.ts +0 -67
  350. package/dist/core/memorySystem.d.ts.map +0 -1
  351. package/dist/core/memorySystem.js +0 -334
  352. package/dist/core/memorySystem.js.map +0 -1
  353. package/dist/core/metricsTracker.d.ts +0 -157
  354. package/dist/core/metricsTracker.d.ts.map +0 -1
  355. package/dist/core/metricsTracker.js +0 -273
  356. package/dist/core/metricsTracker.js.map +0 -1
  357. package/dist/core/modelDiscovery.d.ts +0 -101
  358. package/dist/core/modelDiscovery.d.ts.map +0 -1
  359. package/dist/core/modelDiscovery.js +0 -780
  360. package/dist/core/modelDiscovery.js.map +0 -1
  361. package/dist/core/multilinePasteHandler.d.ts +0 -35
  362. package/dist/core/multilinePasteHandler.d.ts.map +0 -1
  363. package/dist/core/multilinePasteHandler.js +0 -80
  364. package/dist/core/multilinePasteHandler.js.map +0 -1
  365. package/dist/core/offsecAlphaZero.d.ts +0 -56
  366. package/dist/core/offsecAlphaZero.d.ts.map +0 -1
  367. package/dist/core/offsecAlphaZero.js +0 -395
  368. package/dist/core/offsecAlphaZero.js.map +0 -1
  369. package/dist/core/outputStyles.d.ts +0 -48
  370. package/dist/core/outputStyles.d.ts.map +0 -1
  371. package/dist/core/outputStyles.js +0 -270
  372. package/dist/core/outputStyles.js.map +0 -1
  373. package/dist/core/performanceMonitor.d.ts +0 -124
  374. package/dist/core/performanceMonitor.d.ts.map +0 -1
  375. package/dist/core/performanceMonitor.js +0 -192
  376. package/dist/core/performanceMonitor.js.map +0 -1
  377. package/dist/core/preferences.d.ts +0 -67
  378. package/dist/core/preferences.d.ts.map +0 -1
  379. package/dist/core/preferences.js +0 -314
  380. package/dist/core/preferences.js.map +0 -1
  381. package/dist/core/responseVerifier.d.ts +0 -98
  382. package/dist/core/responseVerifier.d.ts.map +0 -1
  383. package/dist/core/responseVerifier.js +0 -509
  384. package/dist/core/responseVerifier.js.map +0 -1
  385. package/dist/core/resultVerification.d.ts +0 -141
  386. package/dist/core/resultVerification.d.ts.map +0 -1
  387. package/dist/core/resultVerification.js +0 -482
  388. package/dist/core/resultVerification.js.map +0 -1
  389. package/dist/core/schemaValidator.d.ts +0 -44
  390. package/dist/core/schemaValidator.d.ts.map +0 -1
  391. package/dist/core/schemaValidator.js +0 -155
  392. package/dist/core/schemaValidator.js.map +0 -1
  393. package/dist/core/secretStore.d.ts +0 -48
  394. package/dist/core/secretStore.d.ts.map +0 -1
  395. package/dist/core/secretStore.js +0 -367
  396. package/dist/core/secretStore.js.map +0 -1
  397. package/dist/core/securityAssessment.d.ts +0 -91
  398. package/dist/core/securityAssessment.d.ts.map +0 -1
  399. package/dist/core/securityAssessment.js +0 -580
  400. package/dist/core/securityAssessment.js.map +0 -1
  401. package/dist/core/selfEvolution.d.ts +0 -155
  402. package/dist/core/selfEvolution.d.ts.map +0 -1
  403. package/dist/core/selfEvolution.js +0 -1000
  404. package/dist/core/selfEvolution.js.map +0 -1
  405. package/dist/core/selfImprovement.d.ts +0 -141
  406. package/dist/core/selfImprovement.d.ts.map +0 -1
  407. package/dist/core/selfImprovement.js +0 -700
  408. package/dist/core/selfImprovement.js.map +0 -1
  409. package/dist/core/sessionStore.d.ts +0 -35
  410. package/dist/core/sessionStore.d.ts.map +0 -1
  411. package/dist/core/sessionStore.js +0 -189
  412. package/dist/core/sessionStore.js.map +0 -1
  413. package/dist/core/testUtils.d.ts +0 -121
  414. package/dist/core/testUtils.d.ts.map +0 -1
  415. package/dist/core/testUtils.js +0 -235
  416. package/dist/core/testUtils.js.map +0 -1
  417. package/dist/core/types/utilityTypes.d.ts +0 -192
  418. package/dist/core/types/utilityTypes.d.ts.map +0 -1
  419. package/dist/core/types/utilityTypes.js +0 -272
  420. package/dist/core/types/utilityTypes.js.map +0 -1
  421. package/dist/core/types.d.ts +0 -306
  422. package/dist/core/types.d.ts.map +0 -1
  423. package/dist/core/types.js +0 -76
  424. package/dist/core/types.js.map +0 -1
  425. package/dist/core/updateManager.d.ts +0 -62
  426. package/dist/core/updateManager.d.ts.map +0 -1
  427. package/dist/core/updateManager.js +0 -266
  428. package/dist/core/updateManager.js.map +0 -1
  429. package/dist/core/validationRunner.d.ts +0 -106
  430. package/dist/core/validationRunner.d.ts.map +0 -1
  431. package/dist/core/validationRunner.js +0 -888
  432. package/dist/core/validationRunner.js.map +0 -1
  433. package/dist/core/verification.d.ts +0 -137
  434. package/dist/core/verification.d.ts.map +0 -1
  435. package/dist/core/verification.js +0 -323
  436. package/dist/core/verification.js.map +0 -1
  437. package/dist/headless/headlessApp.d.ts +0 -5
  438. package/dist/headless/headlessApp.d.ts.map +0 -1
  439. package/dist/headless/headlessApp.js +0 -210
  440. package/dist/headless/headlessApp.js.map +0 -1
  441. package/dist/intelligence/codeIntelligence.d.ts +0 -118
  442. package/dist/intelligence/codeIntelligence.d.ts.map +0 -1
  443. package/dist/intelligence/codeIntelligence.js +0 -552
  444. package/dist/intelligence/codeIntelligence.js.map +0 -1
  445. package/dist/intelligence/docGenerator.d.ts +0 -86
  446. package/dist/intelligence/docGenerator.d.ts.map +0 -1
  447. package/dist/intelligence/docGenerator.js +0 -564
  448. package/dist/intelligence/docGenerator.js.map +0 -1
  449. package/dist/intelligence/index.d.ts +0 -51
  450. package/dist/intelligence/index.d.ts.map +0 -1
  451. package/dist/intelligence/index.js +0 -253
  452. package/dist/intelligence/index.js.map +0 -1
  453. package/dist/intelligence/refactoring.d.ts +0 -50
  454. package/dist/intelligence/refactoring.d.ts.map +0 -1
  455. package/dist/intelligence/refactoring.js +0 -354
  456. package/dist/intelligence/refactoring.js.map +0 -1
  457. package/dist/intelligence/testGenerator.d.ts +0 -74
  458. package/dist/intelligence/testGenerator.d.ts.map +0 -1
  459. package/dist/intelligence/testGenerator.js +0 -483
  460. package/dist/intelligence/testGenerator.js.map +0 -1
  461. package/dist/mcp/config.d.ts +0 -8
  462. package/dist/mcp/config.d.ts.map +0 -1
  463. package/dist/mcp/config.js +0 -252
  464. package/dist/mcp/config.js.map +0 -1
  465. package/dist/mcp/sseClient.d.ts +0 -34
  466. package/dist/mcp/sseClient.d.ts.map +0 -1
  467. package/dist/mcp/sseClient.js +0 -327
  468. package/dist/mcp/sseClient.js.map +0 -1
  469. package/dist/mcp/stdioClient.d.ts +0 -24
  470. package/dist/mcp/stdioClient.d.ts.map +0 -1
  471. package/dist/mcp/stdioClient.js +0 -179
  472. package/dist/mcp/stdioClient.js.map +0 -1
  473. package/dist/mcp/toolBridge.d.ts +0 -12
  474. package/dist/mcp/toolBridge.d.ts.map +0 -1
  475. package/dist/mcp/toolBridge.js +0 -117
  476. package/dist/mcp/toolBridge.js.map +0 -1
  477. package/dist/mcp/types.d.ts +0 -60
  478. package/dist/mcp/types.d.ts.map +0 -1
  479. package/dist/mcp/types.js +0 -2
  480. package/dist/mcp/types.js.map +0 -1
  481. package/dist/plugins/index.d.ts +0 -49
  482. package/dist/plugins/index.d.ts.map +0 -1
  483. package/dist/plugins/index.js +0 -114
  484. package/dist/plugins/index.js.map +0 -1
  485. package/dist/plugins/providers/anthropic/index.d.ts +0 -11
  486. package/dist/plugins/providers/anthropic/index.d.ts.map +0 -1
  487. package/dist/plugins/providers/anthropic/index.js +0 -38
  488. package/dist/plugins/providers/anthropic/index.js.map +0 -1
  489. package/dist/plugins/providers/deepseek/index.d.ts +0 -11
  490. package/dist/plugins/providers/deepseek/index.d.ts.map +0 -1
  491. package/dist/plugins/providers/deepseek/index.js +0 -52
  492. package/dist/plugins/providers/deepseek/index.js.map +0 -1
  493. package/dist/plugins/providers/google/index.d.ts +0 -11
  494. package/dist/plugins/providers/google/index.d.ts.map +0 -1
  495. package/dist/plugins/providers/google/index.js +0 -40
  496. package/dist/plugins/providers/google/index.js.map +0 -1
  497. package/dist/plugins/providers/index.d.ts +0 -2
  498. package/dist/plugins/providers/index.d.ts.map +0 -1
  499. package/dist/plugins/providers/index.js +0 -20
  500. package/dist/plugins/providers/index.js.map +0 -1
  501. package/dist/plugins/providers/ollama/index.d.ts +0 -21
  502. package/dist/plugins/providers/ollama/index.d.ts.map +0 -1
  503. package/dist/plugins/providers/ollama/index.js +0 -69
  504. package/dist/plugins/providers/ollama/index.js.map +0 -1
  505. package/dist/plugins/providers/openai/index.d.ts +0 -12
  506. package/dist/plugins/providers/openai/index.d.ts.map +0 -1
  507. package/dist/plugins/providers/openai/index.js +0 -39
  508. package/dist/plugins/providers/openai/index.js.map +0 -1
  509. package/dist/plugins/providers/xai/index.d.ts +0 -11
  510. package/dist/plugins/providers/xai/index.d.ts.map +0 -1
  511. package/dist/plugins/providers/xai/index.js +0 -39
  512. package/dist/plugins/providers/xai/index.js.map +0 -1
  513. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.d.ts +0 -3
  514. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.d.ts.map +0 -1
  515. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.js +0 -9
  516. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.js.map +0 -1
  517. package/dist/plugins/tools/bash/localBashPlugin.d.ts +0 -3
  518. package/dist/plugins/tools/bash/localBashPlugin.d.ts.map +0 -1
  519. package/dist/plugins/tools/bash/localBashPlugin.js +0 -14
  520. package/dist/plugins/tools/bash/localBashPlugin.js.map +0 -1
  521. package/dist/plugins/tools/browser/browserAutomationPlugin.d.ts +0 -14
  522. package/dist/plugins/tools/browser/browserAutomationPlugin.d.ts.map +0 -1
  523. package/dist/plugins/tools/browser/browserAutomationPlugin.js +0 -26
  524. package/dist/plugins/tools/browser/browserAutomationPlugin.js.map +0 -1
  525. package/dist/plugins/tools/checks/localRepoChecksPlugin.d.ts +0 -3
  526. package/dist/plugins/tools/checks/localRepoChecksPlugin.d.ts.map +0 -1
  527. package/dist/plugins/tools/checks/localRepoChecksPlugin.js +0 -14
  528. package/dist/plugins/tools/checks/localRepoChecksPlugin.js.map +0 -1
  529. package/dist/plugins/tools/cloud/cloudPlugin.d.ts +0 -3
  530. package/dist/plugins/tools/cloud/cloudPlugin.d.ts.map +0 -1
  531. package/dist/plugins/tools/cloud/cloudPlugin.js +0 -14
  532. package/dist/plugins/tools/cloud/cloudPlugin.js.map +0 -1
  533. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.d.ts +0 -3
  534. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.d.ts.map +0 -1
  535. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.js +0 -14
  536. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.js.map +0 -1
  537. package/dist/plugins/tools/codeQuality/codeQualityPlugin.d.ts +0 -3
  538. package/dist/plugins/tools/codeQuality/codeQualityPlugin.d.ts.map +0 -1
  539. package/dist/plugins/tools/codeQuality/codeQualityPlugin.js +0 -14
  540. package/dist/plugins/tools/codeQuality/codeQualityPlugin.js.map +0 -1
  541. package/dist/plugins/tools/dependency/dependencyPlugin.d.ts +0 -3
  542. package/dist/plugins/tools/dependency/dependencyPlugin.d.ts.map +0 -1
  543. package/dist/plugins/tools/dependency/dependencyPlugin.js +0 -12
  544. package/dist/plugins/tools/dependency/dependencyPlugin.js.map +0 -1
  545. package/dist/plugins/tools/development/devPlugin.d.ts +0 -3
  546. package/dist/plugins/tools/development/devPlugin.d.ts.map +0 -1
  547. package/dist/plugins/tools/development/devPlugin.js +0 -14
  548. package/dist/plugins/tools/development/devPlugin.js.map +0 -1
  549. package/dist/plugins/tools/edit/editPlugin.d.ts +0 -9
  550. package/dist/plugins/tools/edit/editPlugin.d.ts.map +0 -1
  551. package/dist/plugins/tools/edit/editPlugin.js +0 -15
  552. package/dist/plugins/tools/edit/editPlugin.js.map +0 -1
  553. package/dist/plugins/tools/email/emailPlugin.d.ts +0 -3
  554. package/dist/plugins/tools/email/emailPlugin.d.ts.map +0 -1
  555. package/dist/plugins/tools/email/emailPlugin.js +0 -12
  556. package/dist/plugins/tools/email/emailPlugin.js.map +0 -1
  557. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.d.ts +0 -3
  558. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.d.ts.map +0 -1
  559. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.js +0 -9
  560. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.js.map +0 -1
  561. package/dist/plugins/tools/filesystem/localFilesystemPlugin.d.ts +0 -3
  562. package/dist/plugins/tools/filesystem/localFilesystemPlugin.d.ts.map +0 -1
  563. package/dist/plugins/tools/filesystem/localFilesystemPlugin.js +0 -14
  564. package/dist/plugins/tools/filesystem/localFilesystemPlugin.js.map +0 -1
  565. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.d.ts +0 -3
  566. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.d.ts.map +0 -1
  567. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.js +0 -14
  568. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.js.map +0 -1
  569. package/dist/plugins/tools/glob/globPlugin.d.ts +0 -9
  570. package/dist/plugins/tools/glob/globPlugin.d.ts.map +0 -1
  571. package/dist/plugins/tools/glob/globPlugin.js +0 -15
  572. package/dist/plugins/tools/glob/globPlugin.js.map +0 -1
  573. package/dist/plugins/tools/index.d.ts +0 -3
  574. package/dist/plugins/tools/index.d.ts.map +0 -1
  575. package/dist/plugins/tools/index.js +0 -3
  576. package/dist/plugins/tools/index.js.map +0 -1
  577. package/dist/plugins/tools/interaction/interactionPlugin.d.ts +0 -3
  578. package/dist/plugins/tools/interaction/interactionPlugin.d.ts.map +0 -1
  579. package/dist/plugins/tools/interaction/interactionPlugin.js +0 -12
  580. package/dist/plugins/tools/interaction/interactionPlugin.js.map +0 -1
  581. package/dist/plugins/tools/learn/learnPlugin.d.ts +0 -3
  582. package/dist/plugins/tools/learn/learnPlugin.d.ts.map +0 -1
  583. package/dist/plugins/tools/learn/learnPlugin.js +0 -14
  584. package/dist/plugins/tools/learn/learnPlugin.js.map +0 -1
  585. package/dist/plugins/tools/mcp/mcpPlugin.d.ts +0 -3
  586. package/dist/plugins/tools/mcp/mcpPlugin.d.ts.map +0 -1
  587. package/dist/plugins/tools/mcp/mcpPlugin.js +0 -9
  588. package/dist/plugins/tools/mcp/mcpPlugin.js.map +0 -1
  589. package/dist/plugins/tools/nodeDefaults.d.ts +0 -2
  590. package/dist/plugins/tools/nodeDefaults.d.ts.map +0 -1
  591. package/dist/plugins/tools/nodeDefaults.js +0 -65
  592. package/dist/plugins/tools/nodeDefaults.js.map +0 -1
  593. package/dist/plugins/tools/notebook/notebookPlugin.d.ts +0 -9
  594. package/dist/plugins/tools/notebook/notebookPlugin.d.ts.map +0 -1
  595. package/dist/plugins/tools/notebook/notebookPlugin.js +0 -15
  596. package/dist/plugins/tools/notebook/notebookPlugin.js.map +0 -1
  597. package/dist/plugins/tools/planning/planningPlugin.d.ts +0 -9
  598. package/dist/plugins/tools/planning/planningPlugin.d.ts.map +0 -1
  599. package/dist/plugins/tools/planning/planningPlugin.js +0 -15
  600. package/dist/plugins/tools/planning/planningPlugin.js.map +0 -1
  601. package/dist/plugins/tools/refactoring/refactoringPlugin.d.ts +0 -3
  602. package/dist/plugins/tools/refactoring/refactoringPlugin.d.ts.map +0 -1
  603. package/dist/plugins/tools/refactoring/refactoringPlugin.js +0 -12
  604. package/dist/plugins/tools/refactoring/refactoringPlugin.js.map +0 -1
  605. package/dist/plugins/tools/registry.d.ts +0 -22
  606. package/dist/plugins/tools/registry.d.ts.map +0 -1
  607. package/dist/plugins/tools/registry.js +0 -58
  608. package/dist/plugins/tools/registry.js.map +0 -1
  609. package/dist/plugins/tools/search/localSearchPlugin.d.ts +0 -3
  610. package/dist/plugins/tools/search/localSearchPlugin.d.ts.map +0 -1
  611. package/dist/plugins/tools/search/localSearchPlugin.js +0 -14
  612. package/dist/plugins/tools/search/localSearchPlugin.js.map +0 -1
  613. package/dist/plugins/tools/skills/skillPlugin.d.ts +0 -3
  614. package/dist/plugins/tools/skills/skillPlugin.d.ts.map +0 -1
  615. package/dist/plugins/tools/skills/skillPlugin.js +0 -9
  616. package/dist/plugins/tools/skills/skillPlugin.js.map +0 -1
  617. package/dist/plugins/tools/taskManagement/taskManagementPlugin.d.ts +0 -3
  618. package/dist/plugins/tools/taskManagement/taskManagementPlugin.d.ts.map +0 -1
  619. package/dist/plugins/tools/taskManagement/taskManagementPlugin.js +0 -12
  620. package/dist/plugins/tools/taskManagement/taskManagementPlugin.js.map +0 -1
  621. package/dist/plugins/tools/testing/testingPlugin.d.ts +0 -3
  622. package/dist/plugins/tools/testing/testingPlugin.d.ts.map +0 -1
  623. package/dist/plugins/tools/testing/testingPlugin.js +0 -12
  624. package/dist/plugins/tools/testing/testingPlugin.js.map +0 -1
  625. package/dist/plugins/tools/validation/validationPlugin.d.ts +0 -3
  626. package/dist/plugins/tools/validation/validationPlugin.d.ts.map +0 -1
  627. package/dist/plugins/tools/validation/validationPlugin.js +0 -14
  628. package/dist/plugins/tools/validation/validationPlugin.js.map +0 -1
  629. package/dist/plugins/tools/web/webPlugin.d.ts +0 -3
  630. package/dist/plugins/tools/web/webPlugin.d.ts.map +0 -1
  631. package/dist/plugins/tools/web/webPlugin.js +0 -12
  632. package/dist/plugins/tools/web/webPlugin.js.map +0 -1
  633. package/dist/providers/anthropicProvider.d.ts +0 -41
  634. package/dist/providers/anthropicProvider.d.ts.map +0 -1
  635. package/dist/providers/anthropicProvider.js +0 -446
  636. package/dist/providers/anthropicProvider.js.map +0 -1
  637. package/dist/providers/googleProvider.d.ts +0 -36
  638. package/dist/providers/googleProvider.d.ts.map +0 -1
  639. package/dist/providers/googleProvider.js +0 -312
  640. package/dist/providers/googleProvider.js.map +0 -1
  641. package/dist/providers/openaiChatCompletionsProvider.d.ts +0 -43
  642. package/dist/providers/openaiChatCompletionsProvider.d.ts.map +0 -1
  643. package/dist/providers/openaiChatCompletionsProvider.js +0 -475
  644. package/dist/providers/openaiChatCompletionsProvider.js.map +0 -1
  645. package/dist/providers/openaiResponsesProvider.d.ts +0 -38
  646. package/dist/providers/openaiResponsesProvider.d.ts.map +0 -1
  647. package/dist/providers/openaiResponsesProvider.js +0 -364
  648. package/dist/providers/openaiResponsesProvider.js.map +0 -1
  649. package/dist/providers/providerFactory.d.ts +0 -18
  650. package/dist/providers/providerFactory.d.ts.map +0 -1
  651. package/dist/providers/providerFactory.js +0 -25
  652. package/dist/providers/providerFactory.js.map +0 -1
  653. package/dist/providers/resilientProvider.d.ts +0 -94
  654. package/dist/providers/resilientProvider.d.ts.map +0 -1
  655. package/dist/providers/resilientProvider.js +0 -370
  656. package/dist/providers/resilientProvider.js.map +0 -1
  657. package/dist/runtime/agentController.d.ts +0 -65
  658. package/dist/runtime/agentController.d.ts.map +0 -1
  659. package/dist/runtime/agentController.js +0 -353
  660. package/dist/runtime/agentController.js.map +0 -1
  661. package/dist/runtime/agentHost.d.ts +0 -61
  662. package/dist/runtime/agentHost.d.ts.map +0 -1
  663. package/dist/runtime/agentHost.js +0 -156
  664. package/dist/runtime/agentHost.js.map +0 -1
  665. package/dist/runtime/agentSession.d.ts +0 -40
  666. package/dist/runtime/agentSession.d.ts.map +0 -1
  667. package/dist/runtime/agentSession.js +0 -205
  668. package/dist/runtime/agentSession.js.map +0 -1
  669. package/dist/runtime/browser.d.ts +0 -7
  670. package/dist/runtime/browser.d.ts.map +0 -1
  671. package/dist/runtime/browser.js +0 -10
  672. package/dist/runtime/browser.js.map +0 -1
  673. package/dist/runtime/cloud.d.ts +0 -7
  674. package/dist/runtime/cloud.d.ts.map +0 -1
  675. package/dist/runtime/cloud.js +0 -10
  676. package/dist/runtime/cloud.js.map +0 -1
  677. package/dist/runtime/node.d.ts +0 -8
  678. package/dist/runtime/node.d.ts.map +0 -1
  679. package/dist/runtime/node.js +0 -11
  680. package/dist/runtime/node.js.map +0 -1
  681. package/dist/runtime/universal.d.ts +0 -21
  682. package/dist/runtime/universal.d.ts.map +0 -1
  683. package/dist/runtime/universal.js +0 -29
  684. package/dist/runtime/universal.js.map +0 -1
  685. package/dist/shell/autoExecutor.d.ts +0 -70
  686. package/dist/shell/autoExecutor.d.ts.map +0 -1
  687. package/dist/shell/autoExecutor.js +0 -288
  688. package/dist/shell/autoExecutor.js.map +0 -1
  689. package/dist/shell/composableMessage.d.ts +0 -183
  690. package/dist/shell/composableMessage.d.ts.map +0 -1
  691. package/dist/shell/composableMessage.js +0 -420
  692. package/dist/shell/composableMessage.js.map +0 -1
  693. package/dist/shell/fileChangeTracker.d.ts +0 -39
  694. package/dist/shell/fileChangeTracker.d.ts.map +0 -1
  695. package/dist/shell/fileChangeTracker.js +0 -64
  696. package/dist/shell/fileChangeTracker.js.map +0 -1
  697. package/dist/shell/keyboardShortcuts.d.ts +0 -53
  698. package/dist/shell/keyboardShortcuts.d.ts.map +0 -1
  699. package/dist/shell/keyboardShortcuts.js +0 -166
  700. package/dist/shell/keyboardShortcuts.js.map +0 -1
  701. package/dist/shell/liveStatus.d.ts +0 -30
  702. package/dist/shell/liveStatus.d.ts.map +0 -1
  703. package/dist/shell/liveStatus.js +0 -102
  704. package/dist/shell/liveStatus.js.map +0 -1
  705. package/dist/shell/shellApp.d.ts +0 -19
  706. package/dist/shell/shellApp.d.ts.map +0 -1
  707. package/dist/shell/shellApp.js +0 -408
  708. package/dist/shell/shellApp.js.map +0 -1
  709. package/dist/shell/taskCompletionDetector.d.ts +0 -106
  710. package/dist/shell/taskCompletionDetector.d.ts.map +0 -1
  711. package/dist/shell/taskCompletionDetector.js +0 -402
  712. package/dist/shell/taskCompletionDetector.js.map +0 -1
  713. package/dist/shell/terminalInput.d.ts +0 -617
  714. package/dist/shell/terminalInput.d.ts.map +0 -1
  715. package/dist/shell/terminalInput.js +0 -2633
  716. package/dist/shell/terminalInput.js.map +0 -1
  717. package/dist/shell/terminalInputAdapter.d.ts +0 -263
  718. package/dist/shell/terminalInputAdapter.d.ts.map +0 -1
  719. package/dist/shell/terminalInputAdapter.js +0 -406
  720. package/dist/shell/terminalInputAdapter.js.map +0 -1
  721. package/dist/shell/updateManager.d.ts +0 -3
  722. package/dist/shell/updateManager.d.ts.map +0 -1
  723. package/dist/shell/updateManager.js +0 -120
  724. package/dist/shell/updateManager.js.map +0 -1
  725. package/dist/shell/vimMode.d.ts +0 -66
  726. package/dist/shell/vimMode.d.ts.map +0 -1
  727. package/dist/shell/vimMode.js +0 -434
  728. package/dist/shell/vimMode.js.map +0 -1
  729. package/dist/skills/skillRepository.d.ts +0 -103
  730. package/dist/skills/skillRepository.d.ts.map +0 -1
  731. package/dist/skills/skillRepository.js +0 -237
  732. package/dist/skills/skillRepository.js.map +0 -1
  733. package/dist/skills/types.d.ts +0 -37
  734. package/dist/skills/types.d.ts.map +0 -1
  735. package/dist/skills/types.js +0 -2
  736. package/dist/skills/types.js.map +0 -1
  737. package/dist/subagents/agentConfig.d.ts +0 -27
  738. package/dist/subagents/agentConfig.d.ts.map +0 -1
  739. package/dist/subagents/agentConfig.js +0 -89
  740. package/dist/subagents/agentConfig.js.map +0 -1
  741. package/dist/subagents/agentRegistry.d.ts +0 -33
  742. package/dist/subagents/agentRegistry.d.ts.map +0 -1
  743. package/dist/subagents/agentRegistry.js +0 -162
  744. package/dist/subagents/agentRegistry.js.map +0 -1
  745. package/dist/subagents/parallelAgentManager.d.ts +0 -99
  746. package/dist/subagents/parallelAgentManager.d.ts.map +0 -1
  747. package/dist/subagents/parallelAgentManager.js +0 -248
  748. package/dist/subagents/parallelAgentManager.js.map +0 -1
  749. package/dist/subagents/taskRunner.d.ts +0 -34
  750. package/dist/subagents/taskRunner.d.ts.map +0 -1
  751. package/dist/subagents/taskRunner.js +0 -459
  752. package/dist/subagents/taskRunner.js.map +0 -1
  753. package/dist/tools/advancedTestGenerationTools.d.ts +0 -21
  754. package/dist/tools/advancedTestGenerationTools.d.ts.map +0 -1
  755. package/dist/tools/advancedTestGenerationTools.js +0 -301
  756. package/dist/tools/advancedTestGenerationTools.js.map +0 -1
  757. package/dist/tools/backgroundBashTools.d.ts +0 -21
  758. package/dist/tools/backgroundBashTools.d.ts.map +0 -1
  759. package/dist/tools/backgroundBashTools.js +0 -215
  760. package/dist/tools/backgroundBashTools.js.map +0 -1
  761. package/dist/tools/browserAutomationTools.d.ts +0 -23
  762. package/dist/tools/browserAutomationTools.d.ts.map +0 -1
  763. package/dist/tools/browserAutomationTools.js +0 -916
  764. package/dist/tools/browserAutomationTools.js.map +0 -1
  765. package/dist/tools/buildTools.d.ts +0 -9
  766. package/dist/tools/buildTools.d.ts.map +0 -1
  767. package/dist/tools/buildTools.js +0 -344
  768. package/dist/tools/buildTools.js.map +0 -1
  769. package/dist/tools/cloudTools.d.ts +0 -49
  770. package/dist/tools/cloudTools.d.ts.map +0 -1
  771. package/dist/tools/cloudTools.js +0 -1258
  772. package/dist/tools/cloudTools.js.map +0 -1
  773. package/dist/tools/code-quality-dashboard.d.ts +0 -57
  774. package/dist/tools/code-quality-dashboard.d.ts.map +0 -1
  775. package/dist/tools/code-quality-dashboard.js +0 -218
  776. package/dist/tools/code-quality-dashboard.js.map +0 -1
  777. package/dist/tools/codeAnalysisTools.d.ts +0 -74
  778. package/dist/tools/codeAnalysisTools.d.ts.map +0 -1
  779. package/dist/tools/codeAnalysisTools.js +0 -664
  780. package/dist/tools/codeAnalysisTools.js.map +0 -1
  781. package/dist/tools/codeGenerationTools.d.ts +0 -3
  782. package/dist/tools/codeGenerationTools.d.ts.map +0 -1
  783. package/dist/tools/codeGenerationTools.js +0 -439
  784. package/dist/tools/codeGenerationTools.js.map +0 -1
  785. package/dist/tools/codeQualityTools.d.ts +0 -3
  786. package/dist/tools/codeQualityTools.d.ts.map +0 -1
  787. package/dist/tools/codeQualityTools.js +0 -296
  788. package/dist/tools/codeQualityTools.js.map +0 -1
  789. package/dist/tools/dependencyTools.d.ts +0 -3
  790. package/dist/tools/dependencyTools.d.ts.map +0 -1
  791. package/dist/tools/dependencyTools.js +0 -283
  792. package/dist/tools/dependencyTools.js.map +0 -1
  793. package/dist/tools/devTools.d.ts +0 -10
  794. package/dist/tools/devTools.d.ts.map +0 -1
  795. package/dist/tools/devTools.js +0 -2125
  796. package/dist/tools/devTools.js.map +0 -1
  797. package/dist/tools/diffUtils.d.ts +0 -36
  798. package/dist/tools/diffUtils.d.ts.map +0 -1
  799. package/dist/tools/diffUtils.js +0 -528
  800. package/dist/tools/diffUtils.js.map +0 -1
  801. package/dist/tools/editTools.d.ts +0 -29
  802. package/dist/tools/editTools.d.ts.map +0 -1
  803. package/dist/tools/editTools.js +0 -419
  804. package/dist/tools/editTools.js.map +0 -1
  805. package/dist/tools/emailTools.d.ts +0 -21
  806. package/dist/tools/emailTools.d.ts.map +0 -1
  807. package/dist/tools/emailTools.js +0 -449
  808. package/dist/tools/emailTools.js.map +0 -1
  809. package/dist/tools/enhancedCodeIntelligenceTools.d.ts +0 -27
  810. package/dist/tools/enhancedCodeIntelligenceTools.d.ts.map +0 -1
  811. package/dist/tools/enhancedCodeIntelligenceTools.js +0 -418
  812. package/dist/tools/enhancedCodeIntelligenceTools.js.map +0 -1
  813. package/dist/tools/enhancedDevWorkflowTools.d.ts +0 -15
  814. package/dist/tools/enhancedDevWorkflowTools.d.ts.map +0 -1
  815. package/dist/tools/enhancedDevWorkflowTools.js +0 -303
  816. package/dist/tools/enhancedDevWorkflowTools.js.map +0 -1
  817. package/dist/tools/fileTools.d.ts +0 -3
  818. package/dist/tools/fileTools.d.ts.map +0 -1
  819. package/dist/tools/fileTools.js +0 -334
  820. package/dist/tools/fileTools.js.map +0 -1
  821. package/dist/tools/frontendTestingTools.d.ts +0 -35
  822. package/dist/tools/frontendTestingTools.d.ts.map +0 -1
  823. package/dist/tools/frontendTestingTools.js +0 -1254
  824. package/dist/tools/frontendTestingTools.js.map +0 -1
  825. package/dist/tools/globTools.d.ts +0 -15
  826. package/dist/tools/globTools.d.ts.map +0 -1
  827. package/dist/tools/globTools.js +0 -174
  828. package/dist/tools/globTools.js.map +0 -1
  829. package/dist/tools/grepTools.d.ts +0 -19
  830. package/dist/tools/grepTools.d.ts.map +0 -1
  831. package/dist/tools/grepTools.js +0 -358
  832. package/dist/tools/grepTools.js.map +0 -1
  833. package/dist/tools/interactionTools.d.ts +0 -13
  834. package/dist/tools/interactionTools.d.ts.map +0 -1
  835. package/dist/tools/interactionTools.js +0 -171
  836. package/dist/tools/interactionTools.js.map +0 -1
  837. package/dist/tools/learnTools.d.ts +0 -152
  838. package/dist/tools/learnTools.d.ts.map +0 -1
  839. package/dist/tools/learnTools.js +0 -1942
  840. package/dist/tools/learnTools.js.map +0 -1
  841. package/dist/tools/localExplore.d.ts +0 -225
  842. package/dist/tools/localExplore.d.ts.map +0 -1
  843. package/dist/tools/localExplore.js +0 -1291
  844. package/dist/tools/localExplore.js.map +0 -1
  845. package/dist/tools/notebookEditTools.d.ts +0 -15
  846. package/dist/tools/notebookEditTools.d.ts.map +0 -1
  847. package/dist/tools/notebookEditTools.js +0 -197
  848. package/dist/tools/notebookEditTools.js.map +0 -1
  849. package/dist/tools/planningTools.d.ts +0 -21
  850. package/dist/tools/planningTools.d.ts.map +0 -1
  851. package/dist/tools/planningTools.js +0 -185
  852. package/dist/tools/planningTools.js.map +0 -1
  853. package/dist/tools/refactoringTools.d.ts +0 -3
  854. package/dist/tools/refactoringTools.d.ts.map +0 -1
  855. package/dist/tools/refactoringTools.js +0 -294
  856. package/dist/tools/refactoringTools.js.map +0 -1
  857. package/dist/tools/repoChecksTools.d.ts +0 -3
  858. package/dist/tools/repoChecksTools.d.ts.map +0 -1
  859. package/dist/tools/repoChecksTools.js +0 -161
  860. package/dist/tools/repoChecksTools.js.map +0 -1
  861. package/dist/tools/searchTools.d.ts +0 -3
  862. package/dist/tools/searchTools.d.ts.map +0 -1
  863. package/dist/tools/searchTools.js +0 -207
  864. package/dist/tools/searchTools.js.map +0 -1
  865. package/dist/tools/skillTools.d.ts +0 -8
  866. package/dist/tools/skillTools.d.ts.map +0 -1
  867. package/dist/tools/skillTools.js +0 -178
  868. package/dist/tools/skillTools.js.map +0 -1
  869. package/dist/tools/softwareEngineeringTools.d.ts +0 -7
  870. package/dist/tools/softwareEngineeringTools.d.ts.map +0 -1
  871. package/dist/tools/softwareEngineeringTools.js +0 -338
  872. package/dist/tools/softwareEngineeringTools.js.map +0 -1
  873. package/dist/tools/taskManagementTools.d.ts +0 -10
  874. package/dist/tools/taskManagementTools.d.ts.map +0 -1
  875. package/dist/tools/taskManagementTools.js +0 -157
  876. package/dist/tools/taskManagementTools.js.map +0 -1
  877. package/dist/tools/testingTools.d.ts +0 -3
  878. package/dist/tools/testingTools.d.ts.map +0 -1
  879. package/dist/tools/testingTools.js +0 -233
  880. package/dist/tools/testingTools.js.map +0 -1
  881. package/dist/tools/validationTools.d.ts +0 -7
  882. package/dist/tools/validationTools.d.ts.map +0 -1
  883. package/dist/tools/validationTools.js +0 -344
  884. package/dist/tools/validationTools.js.map +0 -1
  885. package/dist/tools/webTools.d.ts +0 -3
  886. package/dist/tools/webTools.d.ts.map +0 -1
  887. package/dist/tools/webTools.js +0 -502
  888. package/dist/tools/webTools.js.map +0 -1
  889. package/dist/ui/ShellUIAdapter.d.ts +0 -194
  890. package/dist/ui/ShellUIAdapter.d.ts.map +0 -1
  891. package/dist/ui/ShellUIAdapter.js +0 -1069
  892. package/dist/ui/ShellUIAdapter.js.map +0 -1
  893. package/dist/ui/UnifiedUIController.d.ts +0 -70
  894. package/dist/ui/UnifiedUIController.d.ts.map +0 -1
  895. package/dist/ui/UnifiedUIController.js +0 -190
  896. package/dist/ui/UnifiedUIController.js.map +0 -1
  897. package/dist/ui/animation/AnimationScheduler.d.ts +0 -192
  898. package/dist/ui/animation/AnimationScheduler.d.ts.map +0 -1
  899. package/dist/ui/animation/AnimationScheduler.js +0 -432
  900. package/dist/ui/animation/AnimationScheduler.js.map +0 -1
  901. package/dist/ui/codeHighlighter.d.ts +0 -6
  902. package/dist/ui/codeHighlighter.d.ts.map +0 -1
  903. package/dist/ui/codeHighlighter.js +0 -855
  904. package/dist/ui/codeHighlighter.js.map +0 -1
  905. package/dist/ui/compactRenderer.d.ts +0 -139
  906. package/dist/ui/compactRenderer.d.ts.map +0 -1
  907. package/dist/ui/compactRenderer.js +0 -398
  908. package/dist/ui/compactRenderer.js.map +0 -1
  909. package/dist/ui/designSystem.d.ts +0 -26
  910. package/dist/ui/designSystem.d.ts.map +0 -1
  911. package/dist/ui/designSystem.js +0 -122
  912. package/dist/ui/designSystem.js.map +0 -1
  913. package/dist/ui/display.d.ts +0 -324
  914. package/dist/ui/display.d.ts.map +0 -1
  915. package/dist/ui/display.js +0 -1328
  916. package/dist/ui/display.js.map +0 -1
  917. package/dist/ui/errorFormatter.d.ts +0 -54
  918. package/dist/ui/errorFormatter.d.ts.map +0 -1
  919. package/dist/ui/errorFormatter.js +0 -251
  920. package/dist/ui/errorFormatter.js.map +0 -1
  921. package/dist/ui/globalWriteLock.d.ts +0 -38
  922. package/dist/ui/globalWriteLock.d.ts.map +0 -1
  923. package/dist/ui/globalWriteLock.js +0 -54
  924. package/dist/ui/globalWriteLock.js.map +0 -1
  925. package/dist/ui/inPlaceUpdater.d.ts +0 -181
  926. package/dist/ui/inPlaceUpdater.d.ts.map +0 -1
  927. package/dist/ui/inPlaceUpdater.js +0 -515
  928. package/dist/ui/inPlaceUpdater.js.map +0 -1
  929. package/dist/ui/interrupts/InterruptManager.d.ts +0 -142
  930. package/dist/ui/interrupts/InterruptManager.d.ts.map +0 -1
  931. package/dist/ui/interrupts/InterruptManager.js +0 -439
  932. package/dist/ui/interrupts/InterruptManager.js.map +0 -1
  933. package/dist/ui/layout.d.ts +0 -17
  934. package/dist/ui/layout.d.ts.map +0 -1
  935. package/dist/ui/layout.js +0 -140
  936. package/dist/ui/layout.js.map +0 -1
  937. package/dist/ui/orchestration/StatusOrchestrator.d.ts +0 -156
  938. package/dist/ui/orchestration/StatusOrchestrator.d.ts.map +0 -1
  939. package/dist/ui/orchestration/StatusOrchestrator.js +0 -406
  940. package/dist/ui/orchestration/StatusOrchestrator.js.map +0 -1
  941. package/dist/ui/orchestration/UIUpdateCoordinator.d.ts +0 -77
  942. package/dist/ui/orchestration/UIUpdateCoordinator.d.ts.map +0 -1
  943. package/dist/ui/orchestration/UIUpdateCoordinator.js +0 -265
  944. package/dist/ui/orchestration/UIUpdateCoordinator.js.map +0 -1
  945. package/dist/ui/outputMode.d.ts +0 -22
  946. package/dist/ui/outputMode.d.ts.map +0 -1
  947. package/dist/ui/outputMode.js +0 -40
  948. package/dist/ui/outputMode.js.map +0 -1
  949. package/dist/ui/richText.d.ts +0 -6
  950. package/dist/ui/richText.d.ts.map +0 -1
  951. package/dist/ui/richText.js +0 -391
  952. package/dist/ui/richText.js.map +0 -1
  953. package/dist/ui/shortcutsHelp.d.ts +0 -39
  954. package/dist/ui/shortcutsHelp.d.ts.map +0 -1
  955. package/dist/ui/shortcutsHelp.js +0 -152
  956. package/dist/ui/shortcutsHelp.js.map +0 -1
  957. package/dist/ui/streamingFormatter.d.ts +0 -20
  958. package/dist/ui/streamingFormatter.d.ts.map +0 -1
  959. package/dist/ui/streamingFormatter.js +0 -92
  960. package/dist/ui/streamingFormatter.js.map +0 -1
  961. package/dist/ui/telemetry/UITelemetry.d.ts +0 -181
  962. package/dist/ui/telemetry/UITelemetry.d.ts.map +0 -1
  963. package/dist/ui/telemetry/UITelemetry.js +0 -446
  964. package/dist/ui/telemetry/UITelemetry.js.map +0 -1
  965. package/dist/ui/textHighlighter.d.ts +0 -83
  966. package/dist/ui/textHighlighter.d.ts.map +0 -1
  967. package/dist/ui/textHighlighter.js +0 -267
  968. package/dist/ui/textHighlighter.js.map +0 -1
  969. package/dist/ui/theme.d.ts +0 -208
  970. package/dist/ui/theme.d.ts.map +0 -1
  971. package/dist/ui/theme.js +0 -249
  972. package/dist/ui/theme.js.map +0 -1
  973. package/dist/ui/unified/index.d.ts +0 -50
  974. package/dist/ui/unified/index.d.ts.map +0 -1
  975. package/dist/ui/unified/index.js +0 -77
  976. package/dist/ui/unified/index.js.map +0 -1
  977. package/dist/ui/unified/layout.d.ts +0 -12
  978. package/dist/ui/unified/layout.d.ts.map +0 -1
  979. package/dist/ui/unified/layout.js +0 -96
  980. package/dist/ui/unified/layout.js.map +0 -1
  981. package/dist/ui/writeLock.d.ts +0 -65
  982. package/dist/ui/writeLock.d.ts.map +0 -1
  983. package/dist/ui/writeLock.js +0 -114
  984. package/dist/ui/writeLock.js.map +0 -1
  985. package/dist/utils/asyncUtils.d.ts +0 -95
  986. package/dist/utils/asyncUtils.d.ts.map +0 -1
  987. package/dist/utils/asyncUtils.js +0 -286
  988. package/dist/utils/asyncUtils.js.map +0 -1
  989. package/dist/utils/errorUtils.d.ts +0 -16
  990. package/dist/utils/errorUtils.d.ts.map +0 -1
  991. package/dist/utils/errorUtils.js +0 -66
  992. package/dist/utils/errorUtils.js.map +0 -1
  993. package/dist/utils/frontmatter.d.ts +0 -10
  994. package/dist/utils/frontmatter.d.ts.map +0 -1
  995. package/dist/utils/frontmatter.js +0 -78
  996. package/dist/utils/frontmatter.js.map +0 -1
  997. package/dist/utils/planFormatter.d.ts +0 -34
  998. package/dist/utils/planFormatter.d.ts.map +0 -1
  999. package/dist/utils/planFormatter.js +0 -140
  1000. package/dist/utils/planFormatter.js.map +0 -1
  1001. package/dist/workspace.d.ts +0 -8
  1002. package/dist/workspace.d.ts.map +0 -1
  1003. package/dist/workspace.js +0 -107
  1004. package/dist/workspace.js.map +0 -1
  1005. package/dist/workspace.validator.d.ts +0 -49
  1006. package/dist/workspace.validator.d.ts.map +0 -1
  1007. package/dist/workspace.validator.js +0 -214
  1008. package/dist/workspace.validator.js.map +0 -1
@@ -1,2633 +0,0 @@
1
- /**
2
- * TerminalInput - Clean, unified terminal input handling
3
- *
4
- * Design principles:
5
- * - Single source of truth for input state
6
- * - Hybrid floating/scroll approach:
7
- * - Initially: chat box floats below content
8
- * - When terminal fills: scroll region activates, chat box pins to bottom
9
- * - Native bracketed paste support (no heuristics)
10
- * - Clean cursor model with render-time wrapping
11
- * - State machine for different input modes
12
- * - No readline dependency for display
13
- * - Text selection enabled: mouse tracking disabled by default to preserve
14
- * native terminal text selection and copy/paste functionality
15
- * - Scrollback navigation via keyboard: PageUp/PageDown, Ctrl+Home/End
16
- */
17
- import { EventEmitter } from 'node:events';
18
- import { isMultilinePaste } from '../core/multilinePasteHandler.js';
19
- import { writeLock } from '../ui/writeLock.js';
20
- import { renderDivider, renderStatusLine, renderStatusLines } from '../ui/unified/layout.js';
21
- import { isStreamingMode } from '../ui/globalWriteLock.js';
22
- import { formatThinking } from '../ui/toolDisplay.js';
23
- import { theme } from '../ui/theme.js';
24
- import { formatEditModeIndicator } from '../ui/shortcutsHelp.js';
25
- // ANSI escape codes
26
- const ESC = {
27
- // Cursor control
28
- SAVE: '\x1b7',
29
- RESTORE: '\x1b8',
30
- HIDE: '\x1b[?25l',
31
- SHOW: '\x1b[?25h',
32
- TO: (row, col) => `\x1b[${row};${col}H`,
33
- TO_COL: (col) => `\x1b[${col}G`,
34
- // Line control
35
- CLEAR_LINE: '\x1b[2K',
36
- CLEAR_TO_END: '\x1b[0J',
37
- // Screen control
38
- HOME: '\x1b[H',
39
- CLEAR_SCREEN: '\x1b[2J',
40
- // Alternate screen buffer (like vim/tmux)
41
- ENTER_ALT_SCREEN: '\x1b[?1049h',
42
- EXIT_ALT_SCREEN: '\x1b[?1049l',
43
- // Scroll region
44
- SET_SCROLL: (top, bottom) => `\x1b[${top};${bottom}r`,
45
- RESET_SCROLL: '\x1b[r',
46
- // Style
47
- RESET: '\x1b[0m',
48
- DIM: '\x1b[2m',
49
- REVERSE: '\x1b[7m',
50
- BOLD: '\x1b[1m',
51
- BG_DARK: '\x1b[48;5;236m', // Dark gray background
52
- // Bracketed paste mode
53
- PASTE_ENABLE: '\x1b[?2004h',
54
- PASTE_DISABLE: '\x1b[?2004l',
55
- PASTE_START: '\x1b[200~',
56
- PASTE_END: '\x1b[201~',
57
- // Mouse tracking - Button events only (allows Shift+drag for text selection)
58
- // Mode 1000: Track button presses/releases (wheel events included)
59
- // Mode 1006: SGR extended format for better coordinate handling
60
- // Note: NOT using mode 1003 (all motion) to preserve terminal text selection
61
- MOUSE_ENABLE: '\x1b[?1000h\x1b[?1006h', // Enable button tracking + SGR mode
62
- MOUSE_DISABLE: '\x1b[?1006l\x1b[?1000l', // Disable mouse tracking
63
- };
64
- /**
65
- * Unified terminal input handler
66
- */
67
- export class TerminalInput extends EventEmitter {
68
- out;
69
- config;
70
- // Core state
71
- buffer = '';
72
- cursor = 0;
73
- mode = 'idle';
74
- // Paste accumulation
75
- pasteBuffer = '';
76
- isPasting = false;
77
- pastePlaceholders = [];
78
- pasteCounter = 0;
79
- // History
80
- history = [];
81
- historyIndex = -1;
82
- tempInput = '';
83
- maxHistory = 100;
84
- // Queue for streaming mode
85
- queue = [];
86
- queueIdCounter = 0;
87
- // Display state
88
- statusMessage = null;
89
- overrideStatusMessage = null; // Secondary status (warnings, etc.)
90
- streamingLabel = null; // Streaming progress indicator
91
- metaElapsedSeconds = null; // Optional elapsed time for header line
92
- metaTokensUsed = null; // Optional token usage
93
- metaTokenLimit = null; // Optional token window
94
- metaThinkingMs = null; // Optional thinking duration
95
- metaThinkingHasContent = false; // Whether collapsed thinking content exists
96
- lastRenderContent = '';
97
- lastRenderCursor = -1;
98
- renderDirty = false;
99
- isRendering = false;
100
- // Lifecycle
101
- disposed = false;
102
- enabled = true;
103
- contextUsage = null;
104
- contextAutoCompactThreshold = 90;
105
- // Track current content row (starts at top, moves down)
106
- contentRow = 1;
107
- // Track if scroll region is currently active
108
- scrollRegionActive = false;
109
- thinkingModeLabel = null;
110
- // Scrollback buffer
111
- scrollbackBuffer = [];
112
- maxScrollbackLines = 10000;
113
- scrollbackOffset = 0; // 0 = at bottom (live), > 0 = scrolled up
114
- isInScrollbackMode = false;
115
- scrollIndicatorFrame = 0; // For animated scroll indicator
116
- // Alternate screen state
117
- alternateScreenActive = false;
118
- editMode = 'display-edits';
119
- verificationEnabled = false;
120
- autoContinueEnabled = false;
121
- verificationHotkey = 'ctrl+shift+v';
122
- autoContinueHotkey = 'ctrl+shift+c';
123
- thinkingHotkey = 'tab';
124
- modelLabel = null;
125
- providerLabel = null;
126
- // Streaming render throttle
127
- lastStreamingRender = 0;
128
- streamingRenderInterval = 250; // ms between renders during streaming
129
- streamingRenderTimer = null;
130
- // Command autocomplete state
131
- commandSuggestions = [];
132
- showingSuggestions = false;
133
- selectedSuggestionIndex = 0;
134
- maxVisibleSuggestions = 10;
135
- suggestionRenderState = null;
136
- lastSuggestionStartRow = null;
137
- lastChatBoxStartRow = null;
138
- lastChatBoxHeight = 0;
139
- displayInterceptorDispose = null;
140
- constructor(writeStream = process.stdout, config = {}) {
141
- super();
142
- this.out = writeStream;
143
- this.config = {
144
- maxLines: config.maxLines ?? 1000,
145
- maxLength: config.maxLength ?? 10000,
146
- maxQueueSize: config.maxQueueSize ?? 100,
147
- promptChar: config.promptChar ?? '> ',
148
- continuationChar: config.continuationChar ?? '│ ',
149
- };
150
- }
151
- // ===========================================================================
152
- // PUBLIC API
153
- // ===========================================================================
154
- /**
155
- * Enable bracketed paste mode in terminal
156
- */
157
- enableBracketedPaste() {
158
- if (this.isTTY()) {
159
- this.write(ESC.PASTE_ENABLE);
160
- }
161
- }
162
- /**
163
- * Disable bracketed paste mode
164
- */
165
- disableBracketedPaste() {
166
- if (this.isTTY()) {
167
- this.write(ESC.PASTE_DISABLE);
168
- }
169
- }
170
- /**
171
- * Enable mouse tracking in terminal
172
- */
173
- enableMouseTracking() {
174
- if (this.isTTY()) {
175
- this.write(ESC.MOUSE_ENABLE);
176
- }
177
- }
178
- /**
179
- * Disable mouse tracking
180
- */
181
- disableMouseTracking() {
182
- if (this.isTTY()) {
183
- this.write(ESC.MOUSE_DISABLE);
184
- }
185
- }
186
- /**
187
- * Process raw terminal data (handles bracketed paste sequences and mouse events)
188
- * Returns true if the data was consumed (paste sequence)
189
- */
190
- processRawData(data) {
191
- // Handle ALL mouse events in the data (SGR mode: \x1b[<button;x;yM or m)
192
- // Process repeatedly until no more mouse events
193
- const mousePattern = /\x1b\[<(\d+);(\d+);(\d+)([Mm])/g;
194
- let remaining = data;
195
- let hadMouseEvents = false;
196
- // Remove all mouse escape sequences from the data
197
- let match;
198
- while ((match = mousePattern.exec(data)) !== null) {
199
- const button = parseInt(match[1], 10);
200
- const x = parseInt(match[2], 10);
201
- const y = parseInt(match[3], 10);
202
- this.handleMouseEvent(button, x, y, match[4]);
203
- hadMouseEvents = true;
204
- }
205
- if (hadMouseEvents) {
206
- // Strip all mouse sequences from the data
207
- remaining = data.replace(/\x1b\[<\d+;\d+;\d+[Mm]/g, '');
208
- if (!remaining) {
209
- return { consumed: true, passthrough: '' };
210
- }
211
- // If there's remaining content, continue processing it
212
- }
213
- // Check for paste start
214
- if (remaining.includes(ESC.PASTE_START)) {
215
- this.isPasting = true;
216
- this.pasteBuffer = '';
217
- // Extract content after paste start
218
- const startIdx = remaining.indexOf(ESC.PASTE_START) + ESC.PASTE_START.length;
219
- const afterStart = remaining.slice(startIdx);
220
- // Check if paste end is also in this chunk
221
- if (afterStart.includes(ESC.PASTE_END)) {
222
- const endIdx = afterStart.indexOf(ESC.PASTE_END);
223
- this.pasteBuffer = afterStart.slice(0, endIdx);
224
- this.finishPaste();
225
- return { consumed: true, passthrough: afterStart.slice(endIdx + ESC.PASTE_END.length) };
226
- }
227
- this.pasteBuffer = afterStart;
228
- return { consumed: true, passthrough: '' };
229
- }
230
- // Accumulating paste
231
- if (this.isPasting) {
232
- if (remaining.includes(ESC.PASTE_END)) {
233
- const endIdx = remaining.indexOf(ESC.PASTE_END);
234
- this.pasteBuffer += remaining.slice(0, endIdx);
235
- this.finishPaste();
236
- return { consumed: true, passthrough: remaining.slice(endIdx + ESC.PASTE_END.length) };
237
- }
238
- this.pasteBuffer += remaining;
239
- return { consumed: true, passthrough: '' };
240
- }
241
- // If we processed mouse events but have remaining text, return it as passthrough
242
- if (hadMouseEvents && remaining) {
243
- return { consumed: true, passthrough: remaining };
244
- }
245
- return { consumed: false, passthrough: remaining };
246
- }
247
- /**
248
- * Handle mouse events (button, x, y coordinates, action)
249
- */
250
- handleMouseEvent(button, x, y, action) {
251
- // Mouse wheel events: button 64 = scroll up, button 65 = scroll down
252
- if (button === 64) {
253
- // Scroll up (3 lines per wheel tick)
254
- this.scrollUp(3);
255
- return;
256
- }
257
- if (button === 65) {
258
- // Scroll down (3 lines per wheel tick)
259
- this.scrollDown(3);
260
- return;
261
- }
262
- // Left-click selection inside the command suggestions menu
263
- if (button === 0 && action === 'M') {
264
- if (this.handleSuggestionClick(y)) {
265
- return;
266
- }
267
- // No other left-click handling needed; fall through to consume silently
268
- }
269
- // Left button (0), middle button (1), right button (2)
270
- // These are captured by SGR mouse tracking but we don't need to handle them
271
- // Just consume silently - the escape sequence has already been processed
272
- // The 'M' action is press, 'm' is release
273
- if (button <= 2) {
274
- // Silently consume click events to prevent artifacts
275
- // Left clicks (button=0) in the input area could focus the input
276
- // but terminal apps typically handle this natively
277
- return;
278
- }
279
- // Button with motion flag (button + 32) - drag events
280
- if (button >= 32 && button <= 34) {
281
- // Drag events - consume silently
282
- return;
283
- }
284
- // Any other unrecognized button - log for debugging in dev mode
285
- // but don't output anything to prevent artifacts
286
- }
287
- /**
288
- * Handle a keypress event
289
- */
290
- handleKeypress(str, key) {
291
- if (this.disposed || !this.enabled)
292
- return;
293
- const normalizedName = key?.name ?? this.getArrowKeyName(key?.sequence ?? str);
294
- const effectiveKey = normalizedName ? { ...key, name: normalizedName } : key;
295
- const safeStr = this.isArrowEscapeFragment(str) ? undefined : str;
296
- let handled = false;
297
- // Handle control keys
298
- if (effectiveKey?.ctrl) {
299
- handled = this.handleCtrlKey(effectiveKey);
300
- if (handled) {
301
- return;
302
- }
303
- }
304
- // Handle meta/alt keys
305
- if (effectiveKey?.meta) {
306
- this.handleMetaKey(effectiveKey);
307
- return;
308
- }
309
- // Handle special keys
310
- if (effectiveKey?.name) {
311
- const handled = this.handleSpecialKey(safeStr, effectiveKey);
312
- if (handled)
313
- return;
314
- }
315
- // Ignore orphaned escape fragments that sometimes leak through (e.g., "[D" from arrow keys)
316
- if (safeStr && this.isOrphanedEscapeSequence(safeStr, effectiveKey)) {
317
- return;
318
- }
319
- // Insert printable characters
320
- if (safeStr && !effectiveKey?.ctrl && !effectiveKey?.meta) {
321
- this.insertText(safeStr);
322
- }
323
- }
324
- /**
325
- * Set the input mode
326
- *
327
- * Content flows naturally - no scroll region pinning.
328
- */
329
- setMode(mode) {
330
- const prevMode = this.mode;
331
- this.mode = mode;
332
- if (mode === 'streaming' && prevMode !== 'streaming') {
333
- this.resetStreamingRenderThrottle();
334
- this.renderDirty = true;
335
- this.render();
336
- }
337
- else if (mode !== 'streaming' && prevMode === 'streaming') {
338
- // Streaming ended - render the input area
339
- this.resetStreamingRenderThrottle();
340
- this.forceRender();
341
- }
342
- }
343
- /**
344
- * Legacy method - no longer used (content flows naturally).
345
- * @deprecated Use setContentRow instead
346
- */
347
- setPinnedHeaderLines(_count) {
348
- // No-op: scroll region pinning removed
349
- }
350
- /**
351
- * Get current mode
352
- */
353
- getMode() {
354
- return this.mode;
355
- }
356
- /**
357
- * Get the current buffer content (may contain placeholders for pasted text)
358
- */
359
- getBuffer() {
360
- return this.buffer;
361
- }
362
- /**
363
- * Get the actual text with paste placeholders expanded
364
- */
365
- getText() {
366
- return this.assembleText();
367
- }
368
- /**
369
- * Set buffer content
370
- */
371
- setBuffer(text, cursorPos) {
372
- this.pastePlaceholders = [];
373
- const clean = this.sanitize(text).slice(0, this.config.maxLength);
374
- this.buffer = clean;
375
- this.cursor = cursorPos ?? this.buffer.length;
376
- this.clampCursor();
377
- this.scheduleRender();
378
- }
379
- /**
380
- * Clear the buffer
381
- */
382
- clear() {
383
- this.buffer = '';
384
- this.cursor = 0;
385
- this.historyIndex = -1;
386
- this.tempInput = '';
387
- this.pastePlaceholders = [];
388
- this.showingSuggestions = false;
389
- this.selectedSuggestionIndex = 0;
390
- this.scheduleRender();
391
- }
392
- /**
393
- * Get queued inputs
394
- */
395
- getQueue() {
396
- return [...this.queue];
397
- }
398
- /**
399
- * Dequeue next input
400
- */
401
- dequeue() {
402
- const item = this.queue.shift();
403
- this.scheduleRender();
404
- return item;
405
- }
406
- /**
407
- * Clear the queue
408
- */
409
- clearQueue() {
410
- this.queue = [];
411
- this.scheduleRender();
412
- }
413
- // ===========================================================================
414
- // COMMAND AUTOCOMPLETE
415
- // ===========================================================================
416
- /**
417
- * Set available commands for autocomplete.
418
- * Call this once during initialization with all slash commands.
419
- */
420
- setAvailableCommands(commands) {
421
- this.commandSuggestions = commands;
422
- }
423
- /**
424
- * Check if command suggestions are currently being shown
425
- */
426
- isShowingSuggestions() {
427
- return this.showingSuggestions;
428
- }
429
- /**
430
- * Get filtered commands based on current input
431
- */
432
- getFilteredCommands() {
433
- const input = this.buffer.trim().toLowerCase();
434
- // Only show suggestions if buffer starts with "/"
435
- if (!input.startsWith('/')) {
436
- return [];
437
- }
438
- // If just "/", show all commands
439
- if (input === '/') {
440
- return this.commandSuggestions;
441
- }
442
- // Filter commands that match the typed prefix
443
- return this.commandSuggestions.filter(cmd => cmd.command.toLowerCase().startsWith(input));
444
- }
445
- /**
446
- * Update suggestion visibility based on current buffer
447
- */
448
- updateSuggestionVisibility() {
449
- const filtered = this.getFilteredCommands();
450
- const shouldShow = filtered.length > 0 && this.buffer.startsWith('/');
451
- if (shouldShow !== this.showingSuggestions) {
452
- this.showingSuggestions = shouldShow;
453
- this.selectedSuggestionIndex = 0;
454
- this.scheduleRender();
455
- }
456
- else if (shouldShow) {
457
- // Clamp selection index
458
- this.selectedSuggestionIndex = Math.min(this.selectedSuggestionIndex, Math.max(0, filtered.length - 1));
459
- }
460
- }
461
- /**
462
- * Handle selecting a suggestion (Enter key or click)
463
- */
464
- selectSuggestion(options = {}) {
465
- const { submit = false } = options;
466
- if (!this.showingSuggestions)
467
- return false;
468
- const filtered = this.getFilteredCommands();
469
- if (filtered.length === 0)
470
- return false;
471
- const selected = filtered[this.selectedSuggestionIndex];
472
- if (!selected)
473
- return false;
474
- // Replace buffer with selected command
475
- const nextBuffer = submit ? selected.command : `${selected.command} `;
476
- this.buffer = nextBuffer;
477
- this.cursor = this.buffer.length;
478
- this.showingSuggestions = false;
479
- this.scheduleRender();
480
- if (submit) {
481
- this.submit();
482
- }
483
- return true;
484
- }
485
- /**
486
- * Move selection up in suggestions list
487
- */
488
- moveSuggestionUp() {
489
- if (!this.showingSuggestions)
490
- return false;
491
- const filtered = this.getFilteredCommands();
492
- if (filtered.length === 0)
493
- return false;
494
- this.selectedSuggestionIndex = Math.max(0, this.selectedSuggestionIndex - 1);
495
- this.scheduleRender();
496
- return true;
497
- }
498
- /**
499
- * Move selection down in suggestions list
500
- */
501
- moveSuggestionDown() {
502
- if (!this.showingSuggestions)
503
- return false;
504
- const filtered = this.getFilteredCommands();
505
- if (filtered.length === 0)
506
- return false;
507
- this.selectedSuggestionIndex = Math.min(filtered.length - 1, this.selectedSuggestionIndex + 1);
508
- this.scheduleRender();
509
- return true;
510
- }
511
- /**
512
- * Handle mouse selection inside the suggestions list.
513
- * Returns true if the click selected a command.
514
- */
515
- handleSuggestionClick(clickRow) {
516
- if (!this.showingSuggestions || !this.suggestionRenderState)
517
- return false;
518
- if (this.lastSuggestionStartRow === null)
519
- return false;
520
- // First line is the header; suggestions start on the next row
521
- const relativeRow = clickRow - this.lastSuggestionStartRow - 1;
522
- if (relativeRow < 0)
523
- return false;
524
- const { startIdx, visibleCount } = this.suggestionRenderState;
525
- if (relativeRow >= visibleCount)
526
- return false;
527
- this.selectedSuggestionIndex = startIdx + relativeRow;
528
- this.selectSuggestion();
529
- return true;
530
- }
531
- /**
532
- * Cancel suggestion display (Escape)
533
- */
534
- cancelSuggestions() {
535
- if (!this.showingSuggestions)
536
- return false;
537
- this.showingSuggestions = false;
538
- this.scheduleRender();
539
- return true;
540
- }
541
- /**
542
- * Build command suggestion display lines
543
- */
544
- buildSuggestionLines(width) {
545
- this.suggestionRenderState = null;
546
- if (!this.showingSuggestions)
547
- return [];
548
- const filtered = this.getFilteredCommands();
549
- if (filtered.length === 0)
550
- return [];
551
- const lines = [];
552
- const maxDisplay = Math.min(filtered.length, this.maxVisibleSuggestions);
553
- // Calculate scroll window for long lists
554
- let startIdx = 0;
555
- if (filtered.length > maxDisplay) {
556
- // Keep selected item in view with some context
557
- const padding = Math.floor(maxDisplay / 3);
558
- startIdx = Math.max(0, this.selectedSuggestionIndex - padding);
559
- startIdx = Math.min(startIdx, filtered.length - maxDisplay);
560
- }
561
- this.suggestionRenderState = {
562
- startIdx,
563
- visibleCount: Math.min(maxDisplay, Math.max(0, filtered.length - startIdx))
564
- };
565
- // Header with navigation hint - keep it short
566
- lines.push(theme.ui.muted(`Commands (↑↓ Enter to run · Tab to fill)`));
567
- // Render visible suggestions
568
- for (let i = 0; i < maxDisplay; i++) {
569
- const idx = startIdx + i;
570
- if (idx >= filtered.length)
571
- break;
572
- const cmd = filtered[idx];
573
- const isSelected = idx === this.selectedSuggestionIndex;
574
- // Format: [indicator] /command description
575
- const indicator = isSelected ? theme.accent('▸') : ' ';
576
- // Command name - use available space wisely
577
- const cmdWidth = Math.min(20, Math.max(12, Math.floor(width * 0.3)));
578
- const cmdText = isSelected
579
- ? theme.accent(cmd.command.padEnd(cmdWidth))
580
- : theme.primary(cmd.command.padEnd(cmdWidth));
581
- // Description - use remaining space
582
- const descMaxLen = Math.max(20, width - cmdWidth - 4);
583
- const desc = cmd.description.length > descMaxLen
584
- ? cmd.description.slice(0, descMaxLen - 1) + '…'
585
- : cmd.description;
586
- const descText = isSelected
587
- ? theme.info(desc)
588
- : theme.ui.muted(desc);
589
- lines.push(`${indicator}${cmdText} ${descText}`);
590
- }
591
- // Show scroll indicator if needed
592
- if (filtered.length > maxDisplay) {
593
- const position = startIdx + 1;
594
- const endPos = Math.min(startIdx + maxDisplay, filtered.length);
595
- lines.push(theme.ui.muted(` [${position}-${endPos} of ${filtered.length}]`));
596
- }
597
- return lines;
598
- }
599
- /**
600
- * Update the inline status message shown before the prompt (e.g., streaming heartbeat).
601
- */
602
- setStatusMessage(message) {
603
- const normalized = message ? message.replace(/\s+/g, ' ').trim() : null;
604
- const maxLen = 48;
605
- const next = normalized && normalized.length > maxLen
606
- ? `${normalized.slice(0, maxLen - 3)}...`
607
- : normalized;
608
- if (this.statusMessage === next) {
609
- return;
610
- }
611
- this.statusMessage = next;
612
- // Schedule render - throttling during streaming is handled in render()
613
- this.scheduleRender();
614
- }
615
- /**
616
- * Set an override status message (warnings, errors) that shows alongside the main status.
617
- * Both streaming label and override can be displayed simultaneously.
618
- */
619
- setOverrideStatus(message) {
620
- const normalized = message ? message.replace(/\s+/g, ' ').trim() : null;
621
- const maxLen = 32;
622
- const next = normalized && normalized.length > maxLen
623
- ? `${normalized.slice(0, maxLen - 3)}...`
624
- : normalized;
625
- if (this.overrideStatusMessage === next) {
626
- return;
627
- }
628
- this.overrideStatusMessage = next;
629
- this.scheduleRender();
630
- }
631
- /**
632
- * Set the streaming label (e.g., "Streaming response...").
633
- * Can be shown alongside override status messages.
634
- */
635
- setStreamingLabel(label) {
636
- const normalized = label ? label.replace(/\s+/g, ' ').trim() : null;
637
- const maxLen = 24;
638
- const next = normalized && normalized.length > maxLen
639
- ? `${normalized.slice(0, maxLen - 3)}...`
640
- : normalized;
641
- if (this.streamingLabel === next) {
642
- return;
643
- }
644
- this.streamingLabel = next;
645
- this.scheduleRender();
646
- }
647
- /**
648
- * Surface meta status just above the divider (e.g., elapsed time or token usage).
649
- */
650
- setMetaStatus(meta) {
651
- const nextElapsed = typeof meta.elapsedSeconds === 'number' && Number.isFinite(meta.elapsedSeconds) && meta.elapsedSeconds >= 0
652
- ? Math.floor(meta.elapsedSeconds)
653
- : null;
654
- const nextTokens = typeof meta.tokensUsed === 'number' && Number.isFinite(meta.tokensUsed) && meta.tokensUsed >= 0
655
- ? Math.floor(meta.tokensUsed)
656
- : null;
657
- const nextLimit = typeof meta.tokenLimit === 'number' && Number.isFinite(meta.tokenLimit) && meta.tokenLimit > 0
658
- ? Math.floor(meta.tokenLimit)
659
- : null;
660
- const nextThinking = typeof meta.thinkingMs === 'number' && Number.isFinite(meta.thinkingMs) && meta.thinkingMs >= 0
661
- ? Math.floor(meta.thinkingMs)
662
- : null;
663
- const nextThinkingHasContent = !!meta.thinkingHasContent;
664
- if (this.metaElapsedSeconds === nextElapsed &&
665
- this.metaTokensUsed === nextTokens &&
666
- this.metaTokenLimit === nextLimit &&
667
- this.metaThinkingMs === nextThinking &&
668
- this.metaThinkingHasContent === nextThinkingHasContent) {
669
- return;
670
- }
671
- this.metaElapsedSeconds = nextElapsed;
672
- this.metaTokensUsed = nextTokens;
673
- this.metaTokenLimit = nextLimit;
674
- this.metaThinkingMs = nextThinking;
675
- this.metaThinkingHasContent = nextThinkingHasContent;
676
- this.scheduleRender();
677
- }
678
- /**
679
- * Keep mode toggles (verification/auto-continue) visible in the control bar.
680
- * Hotkey labels remain stable so the bar looks the same before/during streaming.
681
- */
682
- setModeToggles(options) {
683
- const nextVerification = !!options.verificationEnabled;
684
- const nextAutoContinue = !!options.autoContinueEnabled;
685
- const nextVerifyHotkey = options.verificationHotkey ?? this.verificationHotkey;
686
- const nextAutoHotkey = options.autoContinueHotkey ?? this.autoContinueHotkey;
687
- const nextThinkingHotkey = options.thinkingHotkey ?? this.thinkingHotkey;
688
- const nextThinkingLabel = options.thinkingModeLabel === undefined ? this.thinkingModeLabel : (options.thinkingModeLabel || null);
689
- if (this.verificationEnabled === nextVerification &&
690
- this.autoContinueEnabled === nextAutoContinue &&
691
- this.verificationHotkey === nextVerifyHotkey &&
692
- this.autoContinueHotkey === nextAutoHotkey &&
693
- this.thinkingHotkey === nextThinkingHotkey &&
694
- this.thinkingModeLabel === nextThinkingLabel) {
695
- return;
696
- }
697
- this.verificationEnabled = nextVerification;
698
- this.autoContinueEnabled = nextAutoContinue;
699
- this.verificationHotkey = nextVerifyHotkey;
700
- this.autoContinueHotkey = nextAutoHotkey;
701
- this.thinkingHotkey = nextThinkingHotkey;
702
- this.thinkingModeLabel = nextThinkingLabel;
703
- this.scheduleRender();
704
- }
705
- /**
706
- * Clear all status messages at once (convenience method).
707
- */
708
- clearAllStatus() {
709
- this.statusMessage = null;
710
- this.overrideStatusMessage = null;
711
- this.streamingLabel = null;
712
- this.scheduleRender();
713
- }
714
- /**
715
- * Surface model/provider context in the controls bar.
716
- */
717
- setModelContext(options) {
718
- const nextModel = options.model?.trim() || null;
719
- const nextProvider = options.provider?.trim() || null;
720
- if (this.modelLabel === nextModel && this.providerLabel === nextProvider) {
721
- return;
722
- }
723
- this.modelLabel = nextModel;
724
- this.providerLabel = nextProvider;
725
- this.scheduleRender();
726
- }
727
- /**
728
- * Render the floating input area at contentRow.
729
- *
730
- * The chat box "floats" - it renders right below the last streamed content.
731
- * As content is added, contentRow advances, and the chat box moves down.
732
- * No scroll regions - pure floating behavior.
733
- */
734
- render() {
735
- if (!this.canRender())
736
- return;
737
- if (this.isRendering)
738
- return;
739
- const streamingActive = this.mode === 'streaming' || isStreamingMode();
740
- const bufferChanged = this.buffer !== this.lastRenderContent || this.cursor !== this.lastRenderCursor;
741
- // During streaming, throttle re-renders unless the buffer actually changed
742
- // (e.g., typing slash commands while streaming should update immediately).
743
- const shouldThrottle = streamingActive &&
744
- this.lastStreamingRender > 0 &&
745
- !this.renderDirty &&
746
- !bufferChanged &&
747
- !this.showingSuggestions;
748
- if (shouldThrottle) {
749
- const elapsed = Date.now() - this.lastStreamingRender;
750
- const waitMs = Math.max(0, this.streamingRenderInterval - elapsed);
751
- if (waitMs > 0) {
752
- this.renderDirty = true;
753
- this.scheduleStreamingRender(waitMs);
754
- return;
755
- }
756
- }
757
- const shouldSkip = !this.renderDirty && !bufferChanged;
758
- this.renderDirty = false;
759
- if (shouldSkip) {
760
- return;
761
- }
762
- if (writeLock.isLocked()) {
763
- writeLock.safeWrite(() => this.render());
764
- return;
765
- }
766
- this.renderPinnedChatBox();
767
- }
768
- /**
769
- * Unified scroll region renderer.
770
- * Chat box is ALWAYS pinned at the bottom of the terminal.
771
- * Content scrolls in the region above the chat box.
772
- */
773
- renderPinnedChatBox() {
774
- const { rows, cols } = this.getSize();
775
- const maxWidth = Math.max(8, cols - 4);
776
- const streamingActive = this.mode === 'streaming' || isStreamingMode();
777
- const prevChatBoxStart = this.lastChatBoxStartRow;
778
- const prevChatBoxHeight = this.lastChatBoxHeight;
779
- // Wrap buffer into display lines
780
- const { lines, cursorLine, cursorCol } = this.wrapBuffer(maxWidth);
781
- const maxVisible = Math.max(1, Math.min(this.config.maxLines, rows - 3));
782
- const displayLines = Math.min(lines.length, maxVisible);
783
- const metaLines = this.buildMetaLines(cols - 2);
784
- // Calculate display window (keep cursor visible)
785
- let startLine = 0;
786
- if (lines.length > displayLines) {
787
- startLine = Math.max(0, cursorLine - displayLines + 1);
788
- startLine = Math.min(startLine, lines.length - displayLines);
789
- }
790
- const visibleLines = lines.slice(startLine, startLine + displayLines);
791
- const adjustedCursorLine = cursorLine - startLine;
792
- // Chat box height
793
- const chatBoxHeight = this.getChatBoxHeight();
794
- // ALWAYS pin chat box at absolute bottom
795
- const chatBoxStartRow = Math.max(1, rows - chatBoxHeight + 1);
796
- const scrollEnd = chatBoxStartRow - 1;
797
- this.lastChatBoxStartRow = chatBoxStartRow;
798
- this.lastChatBoxHeight = chatBoxHeight;
799
- this.lastSuggestionStartRow = null;
800
- writeLock.lock('terminalInput.renderPinned');
801
- this.isRendering = true;
802
- try {
803
- // Ensure content stays above the expanded chat/menu area when idle
804
- if (!streamingActive && !this.scrollRegionActive) {
805
- this.ensureContentAboveChatBox(chatBoxStartRow, rows);
806
- }
807
- this.write(ESC.SAVE);
808
- this.write(ESC.HIDE);
809
- // Temporarily reset scroll region to write chat box cleanly
810
- if (this.scrollRegionActive) {
811
- this.write(ESC.RESET_SCROLL);
812
- }
813
- // Clear the current and previous chat box footprint to avoid ghost text when the height shrinks
814
- const prevHeight = prevChatBoxStart !== null ? Math.max(1, prevChatBoxHeight) : chatBoxHeight;
815
- const prevStart = prevChatBoxStart ?? chatBoxStartRow;
816
- const prevEnd = prevStart + prevHeight - 1;
817
- const newEnd = chatBoxStartRow + chatBoxHeight - 1;
818
- const clearStart = Math.max(1, Math.min(prevStart, chatBoxStartRow));
819
- const clearEnd = Math.min(rows, Math.max(prevEnd, newEnd));
820
- for (let row = clearStart; row <= clearEnd; row++) {
821
- this.write(ESC.TO(row, 1));
822
- this.write(ESC.CLEAR_LINE);
823
- }
824
- let currentRow = chatBoxStartRow;
825
- // Render scroll/status indicator on the left (Claude Code style)
826
- const scrollIndicator = this.buildScrollIndicator();
827
- // Meta/status header with scroll indicator
828
- for (const metaLine of metaLines) {
829
- this.write(ESC.TO(currentRow, 1));
830
- this.write(metaLine);
831
- currentRow += 1;
832
- }
833
- // Separator line with scroll status
834
- this.write(ESC.TO(currentRow, 1));
835
- const dividerLabel = scrollIndicator || undefined;
836
- this.write(renderDivider(cols - 2, dividerLabel));
837
- currentRow += 1;
838
- // Render input lines
839
- let finalRow = currentRow;
840
- let finalCol = 3;
841
- for (let i = 0; i < visibleLines.length; i++) {
842
- const rowNum = currentRow + i;
843
- this.write(ESC.TO(rowNum, 1));
844
- const line = visibleLines[i] ?? '';
845
- const isFirstLine = (startLine + i) === 0;
846
- const isCursorLine = i === adjustedCursorLine;
847
- const col = isCursorLine ? Math.max(0, Math.min(cursorCol, line.length)) : 0;
848
- this.write(ESC.BG_DARK);
849
- this.write(ESC.DIM);
850
- this.write(isFirstLine ? this.config.promptChar : this.config.continuationChar);
851
- this.write(ESC.RESET);
852
- this.write(ESC.BG_DARK);
853
- if (isCursorLine) {
854
- const before = line.slice(0, col);
855
- const at = line.charAt(col) || ' ';
856
- const after = col < line.length ? line.slice(col + 1) : '';
857
- this.write(before);
858
- this.write(ESC.REVERSE + ESC.BOLD);
859
- this.write(at);
860
- this.write(ESC.RESET + ESC.BG_DARK);
861
- this.write(after);
862
- finalRow = rowNum;
863
- finalCol = this.config.promptChar.length + col + 1;
864
- }
865
- else {
866
- this.write(line);
867
- }
868
- // Pad to edge
869
- const lineLen = this.config.promptChar.length +
870
- line.length +
871
- (isCursorLine && col >= line.length ? 1 : 0);
872
- const padding = Math.max(0, cols - lineLen - 1);
873
- if (padding > 0)
874
- this.write(' '.repeat(padding));
875
- this.write(ESC.RESET);
876
- }
877
- // Command suggestions (shown above controls when "/" is typed)
878
- const suggestionLines = this.buildSuggestionLines(cols - 2);
879
- let suggestionRow = currentRow + visibleLines.length;
880
- if (suggestionLines.length > 0) {
881
- this.lastSuggestionStartRow = suggestionRow;
882
- }
883
- for (const suggestionLine of suggestionLines) {
884
- this.write(ESC.TO(suggestionRow, 1));
885
- this.write(' '); // Indent to match input
886
- this.write(suggestionLine);
887
- suggestionRow += 1;
888
- }
889
- // Mode controls lines with all keyboard shortcuts
890
- // Can be multiple lines during streaming (status + toggles)
891
- const controlLines = this.buildModeControls(cols);
892
- let controlRow = suggestionRow;
893
- for (const controlLine of controlLines) {
894
- this.write(ESC.TO(controlRow, 1));
895
- this.write(controlLine);
896
- controlRow += 1;
897
- }
898
- // Restore scroll region and cursor
899
- if (this.scrollRegionActive) {
900
- // Restore scroll region
901
- this.write(ESC.SET_SCROLL(1, scrollEnd));
902
- // Restore cursor to where it was before rendering (preserves column position)
903
- this.write(ESC.RESTORE);
904
- }
905
- else {
906
- // Not streaming - position cursor in input box
907
- this.write(ESC.RESTORE);
908
- this.write(ESC.TO(finalRow, Math.min(finalCol, cols)));
909
- }
910
- this.write(ESC.SHOW);
911
- // Update state
912
- this.lastRenderContent = this.buffer;
913
- this.lastRenderCursor = this.cursor;
914
- this.lastStreamingRender = streamingActive ? Date.now() : 0;
915
- if (this.streamingRenderTimer) {
916
- clearTimeout(this.streamingRenderTimer);
917
- this.streamingRenderTimer = null;
918
- }
919
- }
920
- finally {
921
- writeLock.unlock();
922
- this.isRendering = false;
923
- }
924
- }
925
- /**
926
- * Keep assistant/user content above the chat box when it expands (e.g., slash menu).
927
- * Scrolls just enough to free space without moving the cursor.
928
- */
929
- ensureContentAboveChatBox(chatBoxStartRow, rows) {
930
- const contentMaxRow = Math.max(1, chatBoxStartRow - 1);
931
- if (this.contentRow < contentMaxRow)
932
- return;
933
- const overflow = (this.contentRow - contentMaxRow) + 1;
934
- const scrollLines = Math.min(overflow, rows);
935
- this.write(ESC.SAVE);
936
- this.write(ESC.TO(rows, 1));
937
- this.write('\n'.repeat(scrollLines));
938
- this.write(ESC.RESTORE);
939
- this.contentRow = contentMaxRow;
940
- }
941
- /**
942
- * Track output written directly by the display (system/assistant messages) so
943
- * it is captured in scrollback and accounted for when re-rendering the chat box.
944
- */
945
- trackExternalOutput(content) {
946
- if (!content)
947
- return;
948
- // Normalize and capture in scrollback for history
949
- const normalized = content.replace(/\r/g, '\n');
950
- this.addToScrollback(normalized);
951
- // Advance content row based on rendered height (accounts for wrapping)
952
- const rowsUsed = this.countRenderedRows(normalized);
953
- if (rowsUsed > 0) {
954
- this.contentRow += rowsUsed;
955
- if (!this.scrollRegionActive) {
956
- this.scheduleRender();
957
- }
958
- }
959
- }
960
- /**
961
- * Estimate how many terminal rows the provided content will consume.
962
- * Considers ANSI-stripped visible length and terminal width so wrapped lines
963
- * correctly advance the tracked cursor position.
964
- */
965
- countRenderedRows(content) {
966
- if (!content)
967
- return 0;
968
- const width = Math.max(1, this.getSize().cols);
969
- const normalized = content.replace(/\r\n/g, '\n');
970
- const lines = normalized.split('\n');
971
- let rows = 0;
972
- for (let i = 0; i < lines.length; i++) {
973
- const line = this.normalizeCarriageReturnLine(lines[i] ?? '');
974
- const visibleLen = this.visibleLength(line);
975
- if (visibleLen > 0) {
976
- const wraps = Math.ceil(visibleLen / width);
977
- if (wraps > 1) {
978
- rows += wraps - 1;
979
- }
980
- }
981
- // Each newline moves the cursor to the start of the next row
982
- if (i < lines.length - 1) {
983
- rows += 1;
984
- }
985
- }
986
- return rows;
987
- }
988
- /**
989
- * Treat carriage returns as line rewrites rather than newlines for row estimates.
990
- * If a CR is followed by text, only the text after the last CR is visible.
991
- * If the line ends with a CR, the existing text stays visible.
992
- */
993
- normalizeCarriageReturnLine(line) {
994
- if (!line.includes('\r')) {
995
- return line;
996
- }
997
- const lastCr = line.lastIndexOf('\r');
998
- const after = line.slice(lastCr + 1);
999
- if (after.length > 0) {
1000
- return after;
1001
- }
1002
- return line.slice(0, lastCr);
1003
- }
1004
- /**
1005
- * Build compact meta line above the divider.
1006
- * Shows model/provider and key metrics in a single line.
1007
- */
1008
- buildMetaLines(width) {
1009
- const leftParts = [];
1010
- const rightParts = [];
1011
- // Model/provider info (left side)
1012
- if (this.modelLabel) {
1013
- const modelText = this.providerLabel
1014
- ? `${this.modelLabel} @ ${this.providerLabel}`
1015
- : this.modelLabel;
1016
- leftParts.push({ text: modelText, tone: 'info' });
1017
- }
1018
- // Elapsed time (right side)
1019
- if (this.metaElapsedSeconds !== null) {
1020
- rightParts.push({ text: `⏱ ${this.formatElapsedLabel(this.metaElapsedSeconds)}`, tone: 'muted' });
1021
- }
1022
- // Token usage (right side)
1023
- if (this.metaTokensUsed !== null) {
1024
- const formattedUsed = this.formatTokenCount(this.metaTokensUsed);
1025
- const formattedLimit = this.metaTokenLimit ? `/${this.formatTokenCount(this.metaTokenLimit)}` : '';
1026
- rightParts.push({ text: `⊛ ${formattedUsed}${formattedLimit}`, tone: 'muted' });
1027
- }
1028
- // Context remaining warning
1029
- const tokensRemaining = this.computeTokensRemaining();
1030
- if (tokensRemaining !== null) {
1031
- const contextPct = this.contextUsage !== null ? `${100 - this.contextUsage}%` : '';
1032
- rightParts.push({ text: `↓${tokensRemaining} ${contextPct}`, tone: this.contextUsage && this.contextUsage > 80 ? 'warn' : 'muted' });
1033
- }
1034
- // Thinking indicator
1035
- if (this.metaThinkingMs !== null) {
1036
- leftParts.push({ text: formatThinking(this.metaThinkingMs, this.metaThinkingHasContent), tone: 'info' });
1037
- }
1038
- if (!leftParts.length && !rightParts.length) {
1039
- return [];
1040
- }
1041
- // Render left and right aligned
1042
- if (!rightParts.length || width < 50) {
1043
- return [renderStatusLine([...leftParts, ...rightParts], width)];
1044
- }
1045
- const leftWidth = Math.max(12, Math.floor(width * 0.5));
1046
- const rightWidth = Math.max(14, width - leftWidth - 1);
1047
- const leftText = renderStatusLine(leftParts, leftWidth);
1048
- const rightText = renderStatusLine(rightParts, rightWidth);
1049
- const spacing = Math.max(1, width - this.visibleLength(leftText) - this.visibleLength(rightText));
1050
- return [`${leftText}${' '.repeat(spacing)}${rightText}`];
1051
- }
1052
- /**
1053
- * Build mode controls lines with all keyboard shortcuts.
1054
- * Shows status, all toggles, and contextual information.
1055
- * Enhanced with comprehensive feature status display.
1056
- *
1057
- * Returns multiple lines to ensure all context is visible during streaming:
1058
- * - Line 1 (during streaming): Status/spinner + interrupt shortcut
1059
- * - Line 2: Mode toggles (edit, verify, auto-continue, thinking)
1060
- *
1061
- * Format: [Key] Label:status · [Key] Label:status · context% · model
1062
- */
1063
- buildModeControls(cols) {
1064
- const width = Math.max(8, cols - 2);
1065
- const streamingActive = this.mode === 'streaming' || this.scrollRegionActive;
1066
- // === LINE 1: STATUS LINE (streaming status + interrupt) ===
1067
- const statusParts = [];
1068
- // Streaming indicator with animated spinner
1069
- if (this.streamingLabel) {
1070
- statusParts.push({ text: `◐ ${this.streamingLabel}`, tone: 'info' });
1071
- }
1072
- // Override status (warnings, errors)
1073
- if (this.overrideStatusMessage) {
1074
- statusParts.push({ text: `⚠ ${this.overrideStatusMessage}`, tone: 'warn' });
1075
- }
1076
- // Main status message
1077
- if (this.statusMessage) {
1078
- statusParts.push({ text: this.statusMessage, tone: this.streamingLabel ? 'muted' : 'info' });
1079
- }
1080
- // Interrupt shortcut (during streaming)
1081
- // Queued commands
1082
- if (this.queue.length > 0) {
1083
- const queueIcon = streamingActive ? '⏳' : '▸';
1084
- statusParts.push({ text: `${queueIcon}${this.queue.length} queued`, tone: 'info' });
1085
- }
1086
- // === LINE 2: MODE TOGGLES (always visible, same as before streaming) ===
1087
- const toggleParts = [];
1088
- // Claude Code style mode indicator: "⏵⏵ accept edits on (shift+tab to cycle)"
1089
- const editModeLabel = this.editMode === 'display-edits' ? 'auto' :
1090
- this.editMode === 'ask-permission' ? 'ask' : 'plan';
1091
- toggleParts.push({ text: formatEditModeIndicator(editModeLabel), tone: editModeLabel === 'plan' ? 'info' : undefined });
1092
- // Context usage (show percentage remaining)
1093
- if (this.contextUsage !== null) {
1094
- const remaining = 100 - this.contextUsage;
1095
- const contextTone = this.contextUsage > 80 ? 'warn' : this.contextUsage > 60 ? 'info' : 'muted';
1096
- toggleParts.push({ text: `ctx:${remaining}%`, tone: contextTone });
1097
- }
1098
- const verifyHotkey = this.formatHotkey(this.verificationHotkey);
1099
- const verifyStatus = this.verificationEnabled ? 'Verify on' : 'Verify off';
1100
- toggleParts.push({
1101
- text: `${verifyHotkey} ${verifyStatus}`,
1102
- tone: this.verificationEnabled ? 'success' : 'muted'
1103
- });
1104
- const autoHotkey = this.formatHotkey(this.autoContinueHotkey);
1105
- const autoStatus = this.autoContinueEnabled ? 'Auto-continue on' : 'Auto-continue off';
1106
- toggleParts.push({
1107
- text: `${autoHotkey} ${autoStatus}`,
1108
- tone: this.autoContinueEnabled ? 'info' : 'muted'
1109
- });
1110
- // Thinking mode toggle
1111
- if (this.thinkingModeLabel) {
1112
- const shortThinking = this.thinkingModeLabel.length > 10
1113
- ? this.thinkingModeLabel.slice(0, 8) + '..'
1114
- : this.thinkingModeLabel;
1115
- const thinkingHotkey = this.formatHotkey(this.thinkingHotkey);
1116
- toggleParts.push({ text: `${thinkingHotkey} Thinking ${shortThinking}`, tone: 'info' });
1117
- }
1118
- // Navigation shortcuts - always show these
1119
- toggleParts.push({ text: 'PgUp/Dn:scroll', tone: 'muted' });
1120
- toggleParts.push({ text: '/help', tone: 'muted' });
1121
- // Multi-line indicator
1122
- if (this.buffer.includes('\n')) {
1123
- const lineCount = this.buffer.split('\n').length;
1124
- toggleParts.push({ text: `${lineCount}L`, tone: 'muted' });
1125
- }
1126
- // Paste indicator
1127
- if (this.pastePlaceholders.length > 0) {
1128
- const latest = this.pastePlaceholders[this.pastePlaceholders.length - 1];
1129
- toggleParts.push({
1130
- text: `📋${latest.lineCount}L`,
1131
- tone: 'info',
1132
- });
1133
- }
1134
- // Build the output lines - use wrapping to never truncate
1135
- const lines = [];
1136
- // During streaming: show status line first, then toggles (wrapped as needed)
1137
- // Not streaming: show combined or just toggles (wrapped as needed)
1138
- if (streamingActive && statusParts.length > 0) {
1139
- // Status line (usually fits on one line)
1140
- lines.push(renderStatusLine(statusParts, width));
1141
- // Toggle parts - wrap to multiple lines if needed
1142
- lines.push(...renderStatusLines(toggleParts, width));
1143
- }
1144
- else if (statusParts.length > 0) {
1145
- // Not streaming but have status - use wrapping for all parts
1146
- const combined = [...statusParts, ...toggleParts];
1147
- lines.push(...renderStatusLines(combined, width));
1148
- }
1149
- else {
1150
- // No streaming, no status - just show toggles (wrapped as needed)
1151
- lines.push(...renderStatusLines(toggleParts, width));
1152
- }
1153
- // Ensure at least one line is returned
1154
- if (lines.length === 0) {
1155
- lines.push('');
1156
- }
1157
- return lines;
1158
- }
1159
- /**
1160
- * Render a mini context usage bar (5 chars)
1161
- */
1162
- renderMiniContextBar(percentRemaining) {
1163
- const bars = 5;
1164
- const filled = Math.round((percentRemaining / 100) * bars);
1165
- const empty = bars - filled;
1166
- return '█'.repeat(filled) + '░'.repeat(empty);
1167
- }
1168
- formatHotkey(hotkey) {
1169
- const normalized = hotkey.trim().toLowerCase();
1170
- if (!normalized)
1171
- return hotkey;
1172
- const parts = normalized.split('+').filter(Boolean);
1173
- const map = {
1174
- shift: 'Shift',
1175
- sh: 'Shift',
1176
- alt: 'Alt',
1177
- option: 'Alt',
1178
- opt: 'Alt',
1179
- ctrl: 'Ctrl',
1180
- control: 'Ctrl',
1181
- cmd: 'Cmd',
1182
- meta: 'Cmd',
1183
- };
1184
- const formatted = parts
1185
- .map((part) => {
1186
- const symbol = map[part];
1187
- if (symbol)
1188
- return symbol;
1189
- if (part.startsWith('/'))
1190
- return part;
1191
- if (part.length === 1)
1192
- return part.toUpperCase();
1193
- return part.charAt(0).toUpperCase() + part.slice(1);
1194
- })
1195
- .join('+');
1196
- return formatted || hotkey;
1197
- }
1198
- computeContextRemaining() {
1199
- if (this.contextUsage === null) {
1200
- return null;
1201
- }
1202
- return Math.max(0, this.contextAutoCompactThreshold - this.contextUsage);
1203
- }
1204
- computeTokensRemaining() {
1205
- if (this.metaTokensUsed === null || this.metaTokenLimit === null) {
1206
- return null;
1207
- }
1208
- const remaining = Math.max(0, this.metaTokenLimit - this.metaTokensUsed);
1209
- return this.formatTokenCount(remaining);
1210
- }
1211
- formatElapsedLabel(seconds) {
1212
- if (seconds < 60) {
1213
- return `${seconds}s`;
1214
- }
1215
- const mins = Math.floor(seconds / 60);
1216
- const secs = seconds % 60;
1217
- return secs > 0 ? `${mins}m ${secs}s` : `${mins}m`;
1218
- }
1219
- formatTokenCount(value) {
1220
- if (!Number.isFinite(value)) {
1221
- return `${value}`;
1222
- }
1223
- if (value >= 1_000_000) {
1224
- return `${(value / 1_000_000).toFixed(1)}M`;
1225
- }
1226
- if (value >= 1_000) {
1227
- return `${(value / 1_000).toFixed(1)}k`;
1228
- }
1229
- return `${Math.round(value)}`;
1230
- }
1231
- visibleLength(value) {
1232
- const ansiPattern = /\u001B\[[0-?]*[ -/]*[@-~]/g;
1233
- return value.replace(ansiPattern, '').length;
1234
- }
1235
- /**
1236
- * Debug-only snapshot used by tests to assert rendered strings without
1237
- * needing a TTY. Not used by production code.
1238
- */
1239
- getDebugUiSnapshot(width) {
1240
- const cols = Math.max(8, width ?? this.getSize().cols);
1241
- return {
1242
- meta: this.buildMetaLines(cols - 2),
1243
- controls: this.buildModeControls(cols),
1244
- };
1245
- }
1246
- /**
1247
- * Force a re-render
1248
- */
1249
- forceRender() {
1250
- this.lastRenderContent = '';
1251
- this.lastRenderCursor = -1;
1252
- this.renderDirty = true;
1253
- this.render();
1254
- }
1255
- /**
1256
- * Enable/disable input
1257
- */
1258
- setEnabled(enabled) {
1259
- this.enabled = enabled;
1260
- }
1261
- /**
1262
- * Handle terminal resize
1263
- */
1264
- handleResize() {
1265
- this.lastRenderContent = '';
1266
- this.lastRenderCursor = -1;
1267
- this.resetStreamingRenderThrottle();
1268
- // If in scrollback mode, re-render the scrollback view with new dimensions
1269
- if (this.isInScrollbackMode) {
1270
- this.renderScrollbackView();
1271
- }
1272
- else {
1273
- this.scheduleRender();
1274
- }
1275
- }
1276
- /**
1277
- * Enter streaming mode with scroll region.
1278
- * Sets up terminal scroll region to exclude chat box.
1279
- */
1280
- enterStreamingScrollRegion() {
1281
- const { rows } = this.getSize();
1282
- const chatBoxHeight = this.getChatBoxHeight();
1283
- const scrollEnd = Math.max(1, rows - chatBoxHeight);
1284
- writeLock.lock('enterStreamingScrollRegion');
1285
- try {
1286
- // Set scroll region for content area (above chat box)
1287
- this.write(ESC.SET_SCROLL(1, scrollEnd));
1288
- // Position cursor at current content row
1289
- this.write(ESC.TO(Math.min(this.contentRow, scrollEnd), 1));
1290
- this.scrollRegionActive = true;
1291
- this.setStatusMessage('esc to interrupt');
1292
- }
1293
- finally {
1294
- writeLock.unlock();
1295
- }
1296
- // Render pinned chat box at bottom
1297
- this.forceRender();
1298
- }
1299
- /**
1300
- * Exit streaming mode and restore normal operation.
1301
- * Clears the old pinned chat box area to prevent duplication.
1302
- */
1303
- exitStreamingScrollRegion() {
1304
- const { rows } = this.getSize();
1305
- const chatBoxHeight = this.getChatBoxHeight();
1306
- writeLock.lock('exitStreamingScrollRegion');
1307
- try {
1308
- // Reset scroll region to full terminal
1309
- this.write(ESC.RESET_SCROLL);
1310
- // Clear the old pinned chat box area to prevent duplication
1311
- // The old chat box was rendered at fixed bottom positions
1312
- const oldChatBoxStart = Math.max(1, rows - chatBoxHeight + 1);
1313
- for (let i = 0; i < chatBoxHeight; i++) {
1314
- const row = oldChatBoxStart + i;
1315
- if (row <= rows) {
1316
- this.write(ESC.TO(row, 1));
1317
- this.write(ESC.CLEAR_LINE);
1318
- }
1319
- }
1320
- // Move cursor back up to where content should continue
1321
- this.write(ESC.TO(oldChatBoxStart, 1));
1322
- this.scrollRegionActive = false;
1323
- this.setStatusMessage('Ready for prompts');
1324
- }
1325
- finally {
1326
- writeLock.unlock();
1327
- }
1328
- // Final render - will render new chat box at correct position
1329
- this.forceRender();
1330
- }
1331
- /**
1332
- * Render chat box at bottom - now uses unified renderer.
1333
- * @deprecated Use renderPinnedChatBox() directly via render()/forceRender()
1334
- */
1335
- renderChatBoxAtBottom() {
1336
- this.renderPinnedChatBox();
1337
- }
1338
- /**
1339
- * Stream content within the scroll region.
1340
- * Content is written directly and scrolls naturally.
1341
- */
1342
- streamContent(content) {
1343
- if (!content)
1344
- return;
1345
- // Capture content in scrollback buffer
1346
- this.addToScrollback(content);
1347
- writeLock.lock('streamContent');
1348
- try {
1349
- // Write content - scroll region handles scrolling
1350
- this.write(content);
1351
- // Track rendered rows (handles wrapping)
1352
- const rowsUsed = this.countRenderedRows(content);
1353
- this.contentRow += rowsUsed;
1354
- }
1355
- finally {
1356
- writeLock.unlock();
1357
- }
1358
- // Throttle chat box updates only when a re-render is needed.
1359
- // In streaming mode the chat box stays pinned, so skip redundant redraws.
1360
- const needsRender = !this.scrollRegionActive || this.renderDirty;
1361
- if (needsRender) {
1362
- if (!this.scrollRegionActive) {
1363
- // Content moved; force a render so the chat box follows.
1364
- this.renderDirty = true;
1365
- }
1366
- this.scheduleStreamingRender(200);
1367
- }
1368
- }
1369
- /**
1370
- * Enable scroll region (no-op in floating mode).
1371
- */
1372
- enableScrollRegion() {
1373
- // No-op: using pure floating approach
1374
- }
1375
- /**
1376
- * Disable scroll region (no-op in floating mode).
1377
- */
1378
- disableScrollRegion() {
1379
- // No-op: using pure floating approach
1380
- }
1381
- /**
1382
- * Calculate chat box height dynamically.
1383
- * Accounts for:
1384
- * - Meta lines (model, elapsed, tokens)
1385
- * - Divider
1386
- * - Input line(s) - expands for multi-line/wrapped input
1387
- * - Command suggestions (when showing)
1388
- * - Control lines (wraps as needed to fit all toggles)
1389
- * - Buffer
1390
- */
1391
- getChatBoxHeight() {
1392
- const { rows, cols } = this.getSize();
1393
- // Calculate actual input lines needed (wrapped buffer)
1394
- const maxWidth = Math.max(1, cols - 4); // Account for prompt and padding
1395
- const { lines: wrappedLines } = this.wrapBuffer(maxWidth);
1396
- // Allow the chat box to grow with the prompt while respecting any explicit limit
1397
- const inputLines = Math.max(1, Math.min(wrappedLines.length, this.config.maxLines));
1398
- // Calculate actual control lines (they wrap as needed)
1399
- const controlLines = this.buildModeControls(cols);
1400
- const controlLineCount = Math.max(1, controlLines.length);
1401
- // Meta line only if we have model/elapsed info
1402
- const hasMetaInfo = this.modelLabel || this.metaElapsedSeconds !== null || this.metaTokensUsed !== null;
1403
- const metaLines = hasMetaInfo ? 1 : 0;
1404
- // Command suggestion lines (when showing)
1405
- let suggestionLines = 0;
1406
- if (this.showingSuggestions) {
1407
- const filtered = this.getFilteredCommands();
1408
- suggestionLines = Math.min(filtered.length, this.maxVisibleSuggestions) + 1; // +1 for header
1409
- }
1410
- // Total: meta + divider + input lines + suggestions + controls + buffer
1411
- // Leave a small buffer so streamed content still has space above the chat box
1412
- const totalHeight = metaLines + 1 + inputLines + suggestionLines + controlLineCount + 1;
1413
- const minContentRows = 2;
1414
- const maxHeight = Math.max(4, rows - minContentRows);
1415
- return Math.min(totalHeight, maxHeight);
1416
- }
1417
- /**
1418
- * @deprecated Use streamContent() instead
1419
- * Register with display's output interceptor - kept for backwards compatibility
1420
- */
1421
- registerOutputInterceptor(_display) {
1422
- const display = _display;
1423
- if (!display?.registerOutputInterceptor)
1424
- return;
1425
- // Remove prior hook if present
1426
- if (this.displayInterceptorDispose) {
1427
- this.displayInterceptorDispose();
1428
- this.displayInterceptorDispose = null;
1429
- }
1430
- this.displayInterceptorDispose = display.registerOutputInterceptor({
1431
- afterWrite: (content) => {
1432
- if (!content)
1433
- return;
1434
- this.trackExternalOutput(content);
1435
- },
1436
- });
1437
- }
1438
- /**
1439
- * Write content above the floating chat box.
1440
- * Works both during streaming and when idle.
1441
- */
1442
- writeToScrollRegion(content) {
1443
- if (!content)
1444
- return;
1445
- // Capture content in scrollback buffer
1446
- this.addToScrollback(content);
1447
- writeLock.lock('writeToScrollRegion');
1448
- try {
1449
- // Position cursor at content row and write
1450
- this.write(ESC.TO(this.contentRow, 1));
1451
- this.write(content);
1452
- // Track rendered rows (handles wrapping)
1453
- const rowsUsed = this.countRenderedRows(content);
1454
- this.contentRow += rowsUsed;
1455
- }
1456
- finally {
1457
- writeLock.unlock();
1458
- }
1459
- // Re-render chat box below new content (only when not streaming)
1460
- if (!this.scrollRegionActive) {
1461
- this.forceRender();
1462
- }
1463
- }
1464
- /**
1465
- * Enter alternate screen buffer.
1466
- * DISABLED: Using terminal-native mode for proper scrollback and text selection.
1467
- */
1468
- enterAlternateScreen() {
1469
- // Disabled - using terminal-native mode
1470
- this.contentRow = 1;
1471
- }
1472
- /**
1473
- * Exit alternate screen buffer.
1474
- * DISABLED: Using terminal-native mode.
1475
- */
1476
- exitAlternateScreen() {
1477
- // Disabled - using terminal-native mode
1478
- }
1479
- /**
1480
- * Check if alternate screen buffer is currently active.
1481
- * Always returns false - using terminal-native mode.
1482
- */
1483
- isAlternateScreenActive() {
1484
- return false;
1485
- }
1486
- /**
1487
- * Get a snapshot of the scrollback buffer (for display on exit).
1488
- */
1489
- getScrollbackSnapshot() {
1490
- return [...this.scrollbackBuffer];
1491
- }
1492
- /**
1493
- * Clear the visible terminal area and reset content position.
1494
- * In terminal-native mode, this just adds newlines to scroll past content
1495
- * rather than clearing history (preserving scrollback).
1496
- */
1497
- clearScreen() {
1498
- writeLock.lock('clearScreen');
1499
- try {
1500
- // In native mode, scroll past existing content rather than clearing
1501
- const { rows } = this.getSize();
1502
- this.write('\n'.repeat(rows));
1503
- this.write(ESC.HOME);
1504
- this.contentRow = 1;
1505
- }
1506
- finally {
1507
- writeLock.unlock();
1508
- }
1509
- }
1510
- /**
1511
- * Reset content position to row 1.
1512
- * Does NOT clear the terminal - content starts from current position.
1513
- */
1514
- resetContentPosition() {
1515
- this.contentRow = 1;
1516
- }
1517
- /**
1518
- * Set the content row explicitly (used after banner is written).
1519
- * This tells the input where content should start flowing from.
1520
- */
1521
- setContentRow(row) {
1522
- this.contentRow = Math.max(1, row);
1523
- }
1524
- /**
1525
- * Get the current content row position.
1526
- */
1527
- getContentRow() {
1528
- return this.contentRow;
1529
- }
1530
- /**
1531
- * Dispose and clean up
1532
- */
1533
- dispose() {
1534
- if (this.disposed)
1535
- return;
1536
- this.disposed = true;
1537
- this.enabled = false;
1538
- if (this.displayInterceptorDispose) {
1539
- this.displayInterceptorDispose();
1540
- this.displayInterceptorDispose = null;
1541
- }
1542
- this.disableScrollRegion();
1543
- this.resetStreamingRenderThrottle();
1544
- this.disableBracketedPaste();
1545
- this.buffer = '';
1546
- this.queue = [];
1547
- this.removeAllListeners();
1548
- }
1549
- // ===========================================================================
1550
- // INPUT HANDLING
1551
- // ===========================================================================
1552
- handleCtrlKey(key) {
1553
- switch (key.name) {
1554
- case 'c':
1555
- if (this.buffer.length > 0) {
1556
- this.clear();
1557
- }
1558
- else {
1559
- this.emit('interrupt');
1560
- }
1561
- return true;
1562
- case 'a': // Home
1563
- this.moveCursorToLineStart();
1564
- return true;
1565
- case 'e': // End
1566
- if (key.shift) {
1567
- this.toggleEditMode();
1568
- this.emit('toggleEditMode');
1569
- return true;
1570
- }
1571
- this.moveCursorToLineEnd();
1572
- return true;
1573
- case 'u': // Delete to start
1574
- this.deleteToStart();
1575
- return true;
1576
- case 'k': // Delete to end
1577
- this.deleteToEnd();
1578
- return true;
1579
- case 'w': // Delete word
1580
- this.deleteWord();
1581
- return true;
1582
- case 'left': // Word left
1583
- this.moveCursorWordLeft();
1584
- return true;
1585
- case 'right': // Word right
1586
- this.moveCursorWordRight();
1587
- return true;
1588
- case 'return': // Ctrl+Enter => newline instead of submit
1589
- this.insertNewline();
1590
- return true;
1591
- case 'v':
1592
- if (key.shift) {
1593
- this.emit('toggleVerify');
1594
- return true;
1595
- }
1596
- break;
1597
- case 'c':
1598
- if (key.shift) {
1599
- this.emit('toggleAutoContinue');
1600
- return true;
1601
- }
1602
- break;
1603
- case 't':
1604
- if (key.shift) {
1605
- this.emit('toggleThinking');
1606
- return true;
1607
- }
1608
- break;
1609
- case 'x':
1610
- if (key.shift) {
1611
- this.emit('clearContext');
1612
- return true;
1613
- }
1614
- break;
1615
- case 's':
1616
- if (key.shift) {
1617
- this.toggleScrollbackMode();
1618
- return true;
1619
- }
1620
- break;
1621
- }
1622
- return false;
1623
- }
1624
- /**
1625
- * Handle Alt/Meta key combinations for mode toggles and navigation.
1626
- * Ctrl-based shortcuts are primary; Alt/Meta remains as a compatibility fallback.
1627
- */
1628
- handleMetaKey(key) {
1629
- switch (key.name) {
1630
- // === CURSOR MOVEMENT ===
1631
- case 'left':
1632
- case 'b':
1633
- this.moveCursorWordLeft();
1634
- break;
1635
- case 'right':
1636
- case 'f':
1637
- this.moveCursorWordRight();
1638
- break;
1639
- case 'backspace':
1640
- this.deleteWord();
1641
- break;
1642
- case 'return':
1643
- this.insertNewline();
1644
- break;
1645
- // === MODE TOGGLES ===
1646
- case 'v':
1647
- // Alt+V: Toggle verification mode (auto-tests after edits)
1648
- this.emit('toggleVerify');
1649
- break;
1650
- case 'c':
1651
- // Alt+C: Toggle auto-continue mode
1652
- this.emit('toggleAutoContinue');
1653
- break;
1654
- case 't':
1655
- // Alt+T: Toggle/cycle thinking mode
1656
- this.emit('toggleThinking');
1657
- break;
1658
- case 'e':
1659
- // Alt+E: Toggle edit permission mode (ask/auto)
1660
- this.toggleEditMode();
1661
- this.emit('toggleEditMode');
1662
- break;
1663
- case 'x':
1664
- // Alt+X: Clear/compact context
1665
- this.emit('clearContext');
1666
- break;
1667
- // === SCROLLBACK NAVIGATION ===
1668
- case 's':
1669
- // Alt+S: Toggle scrollback mode
1670
- this.toggleScrollbackMode();
1671
- break;
1672
- case 'up':
1673
- // Alt+Up: Quick scroll up into history
1674
- if (!this.isInScrollbackMode) {
1675
- this.scrollUp(10);
1676
- }
1677
- else {
1678
- this.scrollUp(1);
1679
- }
1680
- break;
1681
- case 'down':
1682
- // Alt+Down: Quick scroll down
1683
- if (this.isInScrollbackMode) {
1684
- this.scrollDown(1);
1685
- }
1686
- break;
1687
- case 'pageup':
1688
- // Alt+PageUp: Page up in scrollback
1689
- this.scrollUp(this.getPageSize());
1690
- break;
1691
- case 'pagedown':
1692
- // Alt+PageDown: Page down in scrollback
1693
- this.scrollDown(this.getPageSize());
1694
- break;
1695
- case 'home':
1696
- // Alt+Home: Jump to top of scrollback
1697
- this.scrollToTop();
1698
- break;
1699
- case 'end':
1700
- // Alt+End: Jump to bottom (live)
1701
- this.scrollToBottom();
1702
- break;
1703
- }
1704
- }
1705
- /**
1706
- * Get page size for scrollback navigation.
1707
- */
1708
- getPageSize() {
1709
- const { rows } = this.getSize();
1710
- const chatBoxHeight = this.getChatBoxHeight();
1711
- return Math.max(5, rows - chatBoxHeight - 2);
1712
- }
1713
- /**
1714
- * Build scroll indicator for the divider line.
1715
- * Scrollback navigation is disabled in alternate screen mode.
1716
- * This returns null - no scroll indicator is shown.
1717
- */
1718
- buildScrollIndicator() {
1719
- // Scrollback navigation disabled - no indicator needed
1720
- return null;
1721
- }
1722
- handleSpecialKey(_str, key) {
1723
- switch (key.name) {
1724
- case 'return':
1725
- if (key.shift || key.meta || key.ctrl) {
1726
- this.insertNewline();
1727
- }
1728
- else if (this.showingSuggestions) {
1729
- // Select highlighted suggestion and submit immediately
1730
- this.selectSuggestion({ submit: true });
1731
- }
1732
- else {
1733
- this.submit();
1734
- }
1735
- return true;
1736
- case 'escape':
1737
- // Cancel suggestions first, or emit interrupt
1738
- if (this.cancelSuggestions()) {
1739
- return true;
1740
- }
1741
- this.emit('interrupt');
1742
- return true;
1743
- case 'backspace':
1744
- this.deleteBackward();
1745
- return true;
1746
- case 'delete':
1747
- this.deleteForward();
1748
- return true;
1749
- case 'left':
1750
- // Cancel suggestions on cursor movement
1751
- if (this.showingSuggestions) {
1752
- this.cancelSuggestions();
1753
- }
1754
- this.moveCursorLeft();
1755
- return true;
1756
- case 'right':
1757
- // Cancel suggestions on cursor movement
1758
- if (this.showingSuggestions) {
1759
- this.cancelSuggestions();
1760
- }
1761
- this.moveCursorRight();
1762
- return true;
1763
- case 'up':
1764
- // When showing suggestions, navigate up
1765
- if (this.showingSuggestions) {
1766
- this.moveSuggestionUp();
1767
- return true;
1768
- }
1769
- // Ctrl+Shift+Up or Shift+Up: Quick scroll up in scrollback
1770
- if ((key.ctrl && key.shift) || key.shift) {
1771
- this.scrollUp(5);
1772
- }
1773
- else {
1774
- this.handleUp();
1775
- }
1776
- return true;
1777
- case 'down':
1778
- // When showing suggestions, navigate down
1779
- if (this.showingSuggestions) {
1780
- this.moveSuggestionDown();
1781
- return true;
1782
- }
1783
- // Ctrl+Shift+Down or Shift+Down: Quick scroll down in scrollback
1784
- if ((key.ctrl && key.shift) || key.shift) {
1785
- this.scrollDown(5);
1786
- }
1787
- else {
1788
- this.handleDown();
1789
- }
1790
- return true;
1791
- case 'home':
1792
- // Ctrl+Home or in scrollback mode: scroll to top
1793
- if (key.ctrl || this.isInScrollbackMode) {
1794
- this.scrollToTop();
1795
- }
1796
- else {
1797
- this.moveCursorToLineStart();
1798
- }
1799
- return true;
1800
- case 'end':
1801
- // Ctrl+End or in scrollback mode: scroll to bottom (live mode)
1802
- if (key.ctrl || this.isInScrollbackMode) {
1803
- this.scrollToBottom();
1804
- }
1805
- else {
1806
- this.moveCursorToLineEnd();
1807
- }
1808
- return true;
1809
- case 'pageup':
1810
- // Scrollback disabled in alternate screen mode
1811
- // Users should use terminal's native scrollback if available
1812
- return true;
1813
- case 'pagedown':
1814
- // Scrollback disabled in alternate screen mode
1815
- return true;
1816
- case 'tab':
1817
- // Tab can select suggestion too without submitting
1818
- if (this.showingSuggestions && !key.shift) {
1819
- this.selectSuggestion();
1820
- return true;
1821
- }
1822
- if (key.shift) {
1823
- this.toggleEditMode();
1824
- return true;
1825
- }
1826
- this.emit('toggleThinking');
1827
- return true;
1828
- }
1829
- return false;
1830
- }
1831
- insertText(text) {
1832
- const clean = this.sanitize(text);
1833
- if (!clean)
1834
- return;
1835
- const available = this.config.maxLength - this.getComposedLength();
1836
- if (available <= 0)
1837
- return;
1838
- const chunk = clean.slice(0, available);
1839
- const placeholder = this.findPlaceholderAt(this.cursor);
1840
- const insertPos = placeholder && this.cursor > placeholder.start ? placeholder.end : this.cursor;
1841
- this.insertPlainText(chunk, insertPos);
1842
- this.cursor = insertPos + chunk.length;
1843
- this.emit('change', this.buffer);
1844
- // Update command autocomplete visibility
1845
- this.updateSuggestionVisibility();
1846
- this.scheduleRender();
1847
- }
1848
- insertNewline() {
1849
- if (this.getComposedLength() >= this.config.maxLength)
1850
- return;
1851
- const placeholder = this.findPlaceholderAt(this.cursor);
1852
- const insertPos = placeholder && this.cursor > placeholder.start ? placeholder.end : this.cursor;
1853
- this.insertPlainText('\n', insertPos);
1854
- this.cursor = insertPos + 1;
1855
- this.emit('change', this.buffer);
1856
- this.scheduleRender();
1857
- }
1858
- deleteBackward() {
1859
- if (this.cursor === 0)
1860
- return;
1861
- const placeholder = this.findPlaceholderAt(this.cursor - 1);
1862
- if (placeholder) {
1863
- this.deletePlaceholder(placeholder);
1864
- }
1865
- else {
1866
- this.removeRange(this.cursor - 1, this.cursor);
1867
- this.cursor = Math.max(0, this.cursor - 1);
1868
- }
1869
- this.emit('change', this.buffer);
1870
- this.updateSuggestionVisibility();
1871
- this.scheduleRender();
1872
- }
1873
- deleteForward() {
1874
- if (this.cursor >= this.buffer.length)
1875
- return;
1876
- const placeholder = this.findPlaceholderAt(this.cursor);
1877
- if (placeholder) {
1878
- this.deletePlaceholder(placeholder);
1879
- }
1880
- else {
1881
- this.removeRange(this.cursor, this.cursor + 1);
1882
- }
1883
- this.emit('change', this.buffer);
1884
- this.updateSuggestionVisibility();
1885
- this.scheduleRender();
1886
- }
1887
- deleteToStart() {
1888
- if (this.cursor === 0)
1889
- return;
1890
- this.removeRange(0, this.cursor);
1891
- this.cursor = 0;
1892
- this.emit('change', this.buffer);
1893
- this.updateSuggestionVisibility();
1894
- this.scheduleRender();
1895
- }
1896
- deleteToEnd() {
1897
- if (this.cursor >= this.buffer.length)
1898
- return;
1899
- this.removeRange(this.cursor, this.buffer.length);
1900
- this.emit('change', this.buffer);
1901
- this.updateSuggestionVisibility();
1902
- this.scheduleRender();
1903
- }
1904
- deleteWord() {
1905
- if (this.cursor === 0)
1906
- return;
1907
- const placeholder = this.findPlaceholderAt(this.cursor - 1);
1908
- if (placeholder) {
1909
- this.deletePlaceholder(placeholder);
1910
- this.emit('change', this.buffer);
1911
- this.scheduleRender();
1912
- return;
1913
- }
1914
- let pos = this.cursor;
1915
- // Skip whitespace
1916
- while (pos > 0 && this.isWhitespace(this.buffer[pos - 1]))
1917
- pos--;
1918
- // Skip word
1919
- while (pos > 0 && !this.isWhitespace(this.buffer[pos - 1]))
1920
- pos--;
1921
- this.buffer = this.buffer.slice(0, pos) + this.buffer.slice(this.cursor);
1922
- this.cursor = pos;
1923
- this.emit('change', this.buffer);
1924
- this.scheduleRender();
1925
- }
1926
- moveCursorLeft() {
1927
- if (this.cursor > 0) {
1928
- this.cursor--;
1929
- this.scheduleRender();
1930
- }
1931
- }
1932
- moveCursorRight() {
1933
- if (this.cursor < this.buffer.length) {
1934
- this.cursor++;
1935
- this.scheduleRender();
1936
- }
1937
- }
1938
- moveCursorWordLeft() {
1939
- let pos = this.cursor;
1940
- while (pos > 0 && this.isWhitespace(this.buffer[pos - 1]))
1941
- pos--;
1942
- while (pos > 0 && !this.isWhitespace(this.buffer[pos - 1]))
1943
- pos--;
1944
- this.cursor = pos;
1945
- this.scheduleRender();
1946
- }
1947
- moveCursorWordRight() {
1948
- let pos = this.cursor;
1949
- while (pos < this.buffer.length && !this.isWhitespace(this.buffer[pos]))
1950
- pos++;
1951
- while (pos < this.buffer.length && this.isWhitespace(this.buffer[pos]))
1952
- pos++;
1953
- this.cursor = pos;
1954
- this.scheduleRender();
1955
- }
1956
- moveCursorToLineStart() {
1957
- // Find start of current line
1958
- let pos = this.cursor;
1959
- while (pos > 0 && this.buffer[pos - 1] !== '\n')
1960
- pos--;
1961
- this.cursor = pos;
1962
- this.scheduleRender();
1963
- }
1964
- moveCursorToLineEnd() {
1965
- // Find end of current line
1966
- let pos = this.cursor;
1967
- while (pos < this.buffer.length && this.buffer[pos] !== '\n')
1968
- pos++;
1969
- this.cursor = pos;
1970
- this.scheduleRender();
1971
- }
1972
- handleUp() {
1973
- // Check if we can move up within buffer (multi-line)
1974
- const { cursorLine } = this.getCursorPosition();
1975
- if (cursorLine > 0) {
1976
- this.moveCursorUp();
1977
- return;
1978
- }
1979
- // Otherwise navigate history
1980
- if (this.history.length === 0)
1981
- return;
1982
- if (this.historyIndex === -1) {
1983
- this.tempInput = this.buffer;
1984
- }
1985
- if (this.historyIndex < this.history.length - 1) {
1986
- this.historyIndex++;
1987
- this.buffer = this.history[this.history.length - 1 - this.historyIndex] ?? '';
1988
- this.cursor = this.buffer.length;
1989
- this.scheduleRender();
1990
- }
1991
- }
1992
- handleDown() {
1993
- // Check if we can move down within buffer
1994
- const { cursorLine, totalLines } = this.getCursorPosition();
1995
- if (cursorLine < totalLines - 1) {
1996
- this.moveCursorDown();
1997
- return;
1998
- }
1999
- // Otherwise navigate history
2000
- if (this.historyIndex > 0) {
2001
- this.historyIndex--;
2002
- this.buffer = this.history[this.history.length - 1 - this.historyIndex] ?? '';
2003
- this.cursor = this.buffer.length;
2004
- this.scheduleRender();
2005
- }
2006
- else if (this.historyIndex === 0) {
2007
- this.historyIndex = -1;
2008
- this.buffer = this.tempInput;
2009
- this.cursor = this.buffer.length;
2010
- this.scheduleRender();
2011
- }
2012
- }
2013
- moveCursorUp() {
2014
- const lines = this.buffer.split('\n');
2015
- let lineStart = 0;
2016
- let lineIdx = 0;
2017
- // Find current line
2018
- for (let i = 0; i < lines.length; i++) {
2019
- const lineEnd = lineStart + (lines[i]?.length ?? 0);
2020
- if (this.cursor <= lineEnd) {
2021
- lineIdx = i;
2022
- break;
2023
- }
2024
- lineStart = lineEnd + 1; // +1 for newline
2025
- }
2026
- if (lineIdx === 0)
2027
- return;
2028
- // Calculate column in current line
2029
- const colInLine = this.cursor - lineStart;
2030
- // Move to previous line
2031
- const prevLineStart = lineStart - 1 - (lines[lineIdx - 1]?.length ?? 0);
2032
- const prevLineLen = lines[lineIdx - 1]?.length ?? 0;
2033
- this.cursor = prevLineStart + Math.min(colInLine, prevLineLen);
2034
- this.scheduleRender();
2035
- }
2036
- moveCursorDown() {
2037
- const lines = this.buffer.split('\n');
2038
- let lineStart = 0;
2039
- let lineIdx = 0;
2040
- // Find current line
2041
- for (let i = 0; i < lines.length; i++) {
2042
- const lineEnd = lineStart + (lines[i]?.length ?? 0);
2043
- if (this.cursor <= lineEnd) {
2044
- lineIdx = i;
2045
- break;
2046
- }
2047
- lineStart = lineEnd + 1;
2048
- }
2049
- if (lineIdx >= lines.length - 1)
2050
- return;
2051
- const colInLine = this.cursor - lineStart;
2052
- const nextLineStart = lineStart + (lines[lineIdx]?.length ?? 0) + 1;
2053
- const nextLineLen = lines[lineIdx + 1]?.length ?? 0;
2054
- this.cursor = nextLineStart + Math.min(colInLine, nextLineLen);
2055
- this.scheduleRender();
2056
- }
2057
- getCursorPosition() {
2058
- const lines = this.buffer.split('\n');
2059
- let pos = 0;
2060
- for (let i = 0; i < lines.length; i++) {
2061
- const lineLen = lines[i]?.length ?? 0;
2062
- if (this.cursor <= pos + lineLen) {
2063
- return {
2064
- cursorLine: i,
2065
- cursorCol: this.cursor - pos,
2066
- totalLines: lines.length,
2067
- };
2068
- }
2069
- pos += lineLen + 1;
2070
- }
2071
- return {
2072
- cursorLine: lines.length - 1,
2073
- cursorCol: lines[lines.length - 1]?.length ?? 0,
2074
- totalLines: lines.length,
2075
- };
2076
- }
2077
- submit() {
2078
- const text = this.assembleText();
2079
- if (!text.trim())
2080
- return;
2081
- const submission = text;
2082
- // Add to history
2083
- if (this.history[this.history.length - 1] !== submission) {
2084
- this.history.push(submission);
2085
- if (this.history.length > this.maxHistory) {
2086
- this.history.shift();
2087
- }
2088
- }
2089
- this.historyIndex = -1;
2090
- this.tempInput = '';
2091
- // Queue or submit based on mode
2092
- if (this.mode === 'streaming') {
2093
- if (this.queue.length >= this.config.maxQueueSize) {
2094
- return; // Queue full
2095
- }
2096
- this.queue.push({
2097
- id: ++this.queueIdCounter,
2098
- text: submission,
2099
- timestamp: Date.now(),
2100
- });
2101
- this.emit('queue', submission);
2102
- this.clear(); // Clear immediately for queued input
2103
- }
2104
- else {
2105
- // In idle mode, clear the input first, then emit submit.
2106
- // The prompt will be logged as a visible message by the caller.
2107
- this.clear();
2108
- this.emit('submit', submission);
2109
- }
2110
- }
2111
- finishPaste() {
2112
- const content = this.pasteBuffer;
2113
- this.pasteBuffer = '';
2114
- this.isPasting = false;
2115
- if (!content)
2116
- return;
2117
- const clean = this.sanitize(content);
2118
- if (!clean)
2119
- return;
2120
- const available = this.config.maxLength - this.getComposedLength();
2121
- if (available <= 0)
2122
- return;
2123
- const chunk = clean.slice(0, available);
2124
- const isMultiline = isMultilinePaste(chunk);
2125
- const isShortMultiline = isMultiline && this.shouldInlineMultiline(chunk);
2126
- if (isMultiline && !isShortMultiline) {
2127
- this.insertPastePlaceholder(chunk);
2128
- }
2129
- else {
2130
- const placeholder = this.findPlaceholderAt(this.cursor);
2131
- const insertPos = placeholder && this.cursor > placeholder.start ? placeholder.end : this.cursor;
2132
- this.insertPlainText(chunk, insertPos);
2133
- this.cursor = insertPos + chunk.length;
2134
- }
2135
- this.emit('change', this.buffer);
2136
- this.scheduleRender();
2137
- }
2138
- // ===========================================================================
2139
- // BUFFER WRAPPING
2140
- // ===========================================================================
2141
- wrapBuffer(maxWidth) {
2142
- const width = Math.max(1, maxWidth);
2143
- const lines = [];
2144
- let cursorLine = 0;
2145
- let cursorCol = 0;
2146
- let charIndex = 0;
2147
- if (this.buffer.length === 0) {
2148
- return { lines: [''], cursorLine: 0, cursorCol: 0 };
2149
- }
2150
- const rawLines = this.buffer.split('\n');
2151
- for (let i = 0; i < rawLines.length; i++) {
2152
- const raw = rawLines[i] ?? '';
2153
- if (raw.length === 0) {
2154
- // Empty line from newline
2155
- if (this.cursor === charIndex) {
2156
- cursorLine = lines.length;
2157
- cursorCol = 0;
2158
- }
2159
- lines.push('');
2160
- }
2161
- else {
2162
- // Wrap long lines
2163
- for (let start = 0; start < raw.length; start += width) {
2164
- const segment = raw.slice(start, start + width);
2165
- const segmentStart = charIndex + start;
2166
- const segmentEnd = segmentStart + segment.length;
2167
- if (this.cursor >= segmentStart && this.cursor <= segmentEnd) {
2168
- cursorLine = lines.length;
2169
- cursorCol = this.cursor - segmentStart;
2170
- }
2171
- lines.push(segment);
2172
- }
2173
- }
2174
- charIndex += raw.length;
2175
- // Account for newline between raw lines
2176
- if (i < rawLines.length - 1) {
2177
- if (this.cursor === charIndex) {
2178
- cursorLine = lines.length;
2179
- cursorCol = 0;
2180
- }
2181
- charIndex++;
2182
- }
2183
- }
2184
- // Safety: clamp values
2185
- cursorLine = Math.max(0, Math.min(cursorLine, lines.length - 1));
2186
- cursorCol = Math.max(0, Math.min(cursorCol, lines[cursorLine]?.length ?? 0));
2187
- return { lines, cursorLine, cursorCol };
2188
- }
2189
- // ===========================================================================
2190
- // SCROLLBACK BUFFER
2191
- // ===========================================================================
2192
- /**
2193
- * Add content to the scrollback buffer for history retention
2194
- */
2195
- addToScrollback(content) {
2196
- if (!content)
2197
- return;
2198
- // Split content into lines and add to buffer
2199
- const lines = content.split('\n');
2200
- for (let i = 0; i < lines.length; i++) {
2201
- const line = lines[i];
2202
- if (line !== undefined) {
2203
- // Only add non-empty lines or preserve newlines between content
2204
- if (i < lines.length - 1 || line.length > 0) {
2205
- this.scrollbackBuffer.push(line);
2206
- }
2207
- }
2208
- }
2209
- // Trim buffer if it exceeds max size
2210
- while (this.scrollbackBuffer.length > this.maxScrollbackLines) {
2211
- this.scrollbackBuffer.shift();
2212
- }
2213
- // If we're in live mode (not scrolled up), keep offset at 0
2214
- if (this.scrollbackOffset === 0) {
2215
- this.isInScrollbackMode = false;
2216
- }
2217
- }
2218
- /**
2219
- * Scroll up by a number of lines (PageUp)
2220
- * Note: Scrollback is disabled in alternate screen mode to avoid display corruption.
2221
- * Users should use their terminal's native scrollback or copy/paste features.
2222
- */
2223
- scrollUp(_lines = 10) {
2224
- // Scrollback disabled - alternate screen buffer doesn't support it well
2225
- // The scrollback buffer is still maintained for potential future use
2226
- // Users can select and copy text normally since mouse tracking is off
2227
- }
2228
- /**
2229
- * Scroll down by a number of lines (PageDown)
2230
- * Note: Scrollback disabled - see scrollUp comment
2231
- */
2232
- scrollDown(_lines = 10) {
2233
- // Scrollback disabled
2234
- }
2235
- /**
2236
- * Jump to the top of scrollback buffer
2237
- * DISABLED: Scrollback navigation causes display corruption in alternate screen mode.
2238
- * The scrollback buffer is maintained but cannot be rendered properly.
2239
- */
2240
- scrollToTop() {
2241
- // Disabled - causes display corruption in alternate screen buffer
2242
- }
2243
- /**
2244
- * Jump to the bottom (live mode)
2245
- * DISABLED: Scrollback navigation causes display corruption.
2246
- */
2247
- scrollToBottom() {
2248
- // Reset scrollback state in case it was somehow enabled
2249
- this.scrollbackOffset = 0;
2250
- this.isInScrollbackMode = false;
2251
- }
2252
- /**
2253
- * Toggle scrollback mode on/off (Ctrl+Shift+S hotkey; Alt+S legacy)
2254
- * DISABLED: Scrollback navigation causes display corruption in alternate screen mode.
2255
- */
2256
- toggleScrollbackMode() {
2257
- // Disabled - alternate screen buffer doesn't support manual scrollback rendering
2258
- }
2259
- /**
2260
- * Render the scrollback buffer view.
2261
- * DISABLED: This causes display corruption in alternate screen mode.
2262
- * The alternate screen buffer has its own rendering model that conflicts with
2263
- * manual scroll region manipulation.
2264
- */
2265
- renderScrollbackView() {
2266
- // Disabled - causes display corruption
2267
- }
2268
- /**
2269
- * Build scrollback header with navigation hints
2270
- */
2271
- buildScrollbackHeader(cols, totalLines, startIdx, endIdx) {
2272
- const percentage = Math.round((endIdx / totalLines) * 100);
2273
- // Animated scroll indicator
2274
- const scrollFrames = ['◆', '◇', '◆', '◈'];
2275
- this.scrollIndicatorFrame = (this.scrollIndicatorFrame + 1) % scrollFrames.length;
2276
- const indicator = scrollFrames[this.scrollIndicatorFrame];
2277
- // Build header parts
2278
- const leftPart = theme.info(`${indicator} SCROLLBACK`) +
2279
- theme.ui.muted(` [${startIdx + 1}-${endIdx} of ${totalLines}]`);
2280
- const progressBar = this.buildProgressBar(percentage, 15);
2281
- const rightPart = progressBar +
2282
- theme.ui.muted(` ${percentage}%`) +
2283
- theme.ui.muted(' │ ') +
2284
- theme.primary('PgUp') + theme.ui.muted('/') + theme.primary('PgDn') +
2285
- theme.ui.muted(' scroll · ') +
2286
- theme.primary('End') + theme.ui.muted(' exit');
2287
- const leftLen = this.visibleLength(leftPart);
2288
- const rightLen = this.visibleLength(rightPart);
2289
- const padding = Math.max(1, cols - leftLen - rightLen - 2);
2290
- return `${leftPart}${' '.repeat(padding)}${rightPart}`;
2291
- }
2292
- /**
2293
- * Render visual scroll track on the right side
2294
- */
2295
- renderScrollTrack(cols, contentHeight, totalLines, startIdx, endIdx) {
2296
- if (totalLines <= contentHeight || cols < 40)
2297
- return;
2298
- const trackHeight = contentHeight - 1; // Exclude header
2299
- const viewportRatio = (endIdx - startIdx) / totalLines;
2300
- const positionRatio = startIdx / Math.max(1, totalLines - (endIdx - startIdx));
2301
- // Calculate thumb size and position
2302
- const thumbSize = Math.max(1, Math.round(viewportRatio * trackHeight));
2303
- const thumbStart = Math.round(positionRatio * (trackHeight - thumbSize));
2304
- // Render track on right edge
2305
- for (let i = 0; i < trackHeight; i++) {
2306
- const row = 2 + i; // Start after header
2307
- this.write(ESC.TO(row, cols));
2308
- if (i >= thumbStart && i < thumbStart + thumbSize) {
2309
- // Thumb (viewport indicator)
2310
- this.write(theme.accent('█'));
2311
- }
2312
- else {
2313
- // Track background
2314
- this.write(theme.ui.muted('░'));
2315
- }
2316
- }
2317
- }
2318
- /**
2319
- * Build a visual progress bar
2320
- */
2321
- buildProgressBar(percentage, width = 10) {
2322
- const filled = Math.round((percentage / 100) * width);
2323
- const empty = width - filled;
2324
- const bar = theme.accent('█'.repeat(filled)) +
2325
- theme.ui.muted('░'.repeat(empty));
2326
- return `${theme.ui.muted('[')}${bar}${theme.ui.muted(']')}`;
2327
- }
2328
- /**
2329
- * Get scrollback buffer content (for persistence)
2330
- */
2331
- getScrollbackBuffer() {
2332
- return [...this.scrollbackBuffer];
2333
- }
2334
- /**
2335
- * Load scrollback buffer (for restoration)
2336
- */
2337
- loadScrollbackBuffer(lines) {
2338
- this.scrollbackBuffer = [...lines];
2339
- // Trim if necessary
2340
- while (this.scrollbackBuffer.length > this.maxScrollbackLines) {
2341
- this.scrollbackBuffer.shift();
2342
- }
2343
- }
2344
- /**
2345
- * Clear scrollback buffer
2346
- */
2347
- clearScrollbackBuffer() {
2348
- this.scrollbackBuffer = [];
2349
- this.scrollbackOffset = 0;
2350
- this.isInScrollbackMode = false;
2351
- }
2352
- // ===========================================================================
2353
- // UTILITIES
2354
- // ===========================================================================
2355
- getComposedLength() {
2356
- if (this.pastePlaceholders.length === 0) {
2357
- return this.buffer.length;
2358
- }
2359
- const sorted = [...this.pastePlaceholders].sort((a, b) => a.start - b.start);
2360
- let composed = 0;
2361
- let cursor = 0;
2362
- for (const placeholder of sorted) {
2363
- composed += Math.max(0, placeholder.start - cursor);
2364
- composed += placeholder.content.length;
2365
- cursor = placeholder.end;
2366
- }
2367
- composed += Math.max(0, this.buffer.length - cursor);
2368
- return composed;
2369
- }
2370
- assembleText() {
2371
- if (this.pastePlaceholders.length === 0) {
2372
- return this.buffer;
2373
- }
2374
- const sorted = [...this.pastePlaceholders].sort((a, b) => a.start - b.start);
2375
- let result = '';
2376
- let cursor = 0;
2377
- for (const placeholder of sorted) {
2378
- result += this.buffer.slice(cursor, placeholder.start);
2379
- result += placeholder.content;
2380
- cursor = placeholder.end;
2381
- }
2382
- result += this.buffer.slice(cursor);
2383
- return result;
2384
- }
2385
- shiftPlaceholders(start, delta, excludeId) {
2386
- if (delta === 0)
2387
- return;
2388
- for (const placeholder of this.pastePlaceholders) {
2389
- if (excludeId && placeholder.id === excludeId)
2390
- continue;
2391
- if (placeholder.start >= start) {
2392
- placeholder.start += delta;
2393
- placeholder.end += delta;
2394
- }
2395
- }
2396
- }
2397
- removeRange(start, end) {
2398
- // Expand deletion to cover any placeholder that overlaps the range
2399
- let adjustedStart = start;
2400
- let adjustedEnd = end;
2401
- for (const ph of this.pastePlaceholders) {
2402
- if (ph.start < adjustedEnd && ph.end > adjustedStart) {
2403
- adjustedStart = Math.min(adjustedStart, ph.start);
2404
- adjustedEnd = Math.max(adjustedEnd, ph.end);
2405
- }
2406
- }
2407
- const length = Math.max(0, adjustedEnd - adjustedStart);
2408
- if (length === 0)
2409
- return;
2410
- this.buffer = this.buffer.slice(0, adjustedStart) + this.buffer.slice(adjustedEnd);
2411
- // Remove any placeholders that were within the deleted range
2412
- this.pastePlaceholders = this.pastePlaceholders.filter((ph) => {
2413
- return ph.end <= adjustedStart || ph.start >= adjustedEnd;
2414
- });
2415
- // Shift remaining placeholders that were after the deleted range
2416
- this.shiftPlaceholders(adjustedEnd, -length);
2417
- this.clampCursor();
2418
- }
2419
- insertPlainText(text, position) {
2420
- if (!text)
2421
- return;
2422
- this.shiftPlaceholders(position, text.length);
2423
- this.buffer = this.buffer.slice(0, position) + text + this.buffer.slice(position);
2424
- }
2425
- shouldInlineMultiline(content) {
2426
- const lines = content.split('\n').length;
2427
- const maxInlineLines = 4;
2428
- const maxInlineChars = 240;
2429
- return lines <= maxInlineLines && content.length <= maxInlineChars;
2430
- }
2431
- findPlaceholderAt(position) {
2432
- return this.pastePlaceholders.find((ph) => position >= ph.start && position < ph.end) ?? null;
2433
- }
2434
- buildPlaceholder(lineCount) {
2435
- const id = ++this.pasteCounter;
2436
- const plural = lineCount === 1 ? '' : 's';
2437
- const placeholder = `[Pasted text #${id} +${lineCount} line${plural}]`;
2438
- return { id, placeholder };
2439
- }
2440
- insertPastePlaceholder(content) {
2441
- const available = this.config.maxLength - this.getComposedLength();
2442
- if (available <= 0)
2443
- return;
2444
- const cleanContent = content.slice(0, available);
2445
- const lineCount = cleanContent.split('\n').length;
2446
- const { id, placeholder } = this.buildPlaceholder(lineCount);
2447
- const insertPos = this.cursor;
2448
- this.shiftPlaceholders(insertPos, placeholder.length);
2449
- this.pastePlaceholders.push({
2450
- id,
2451
- content: cleanContent,
2452
- lineCount,
2453
- placeholder,
2454
- start: insertPos,
2455
- end: insertPos + placeholder.length,
2456
- });
2457
- this.buffer = this.buffer.slice(0, insertPos) + placeholder + this.buffer.slice(insertPos);
2458
- this.cursor = insertPos + placeholder.length;
2459
- }
2460
- deletePlaceholder(placeholder) {
2461
- const length = placeholder.end - placeholder.start;
2462
- this.buffer = this.buffer.slice(0, placeholder.start) + this.buffer.slice(placeholder.end);
2463
- this.pastePlaceholders = this.pastePlaceholders.filter((ph) => ph.id !== placeholder.id);
2464
- this.shiftPlaceholders(placeholder.end, -length, placeholder.id);
2465
- this.cursor = placeholder.start;
2466
- }
2467
- updateContextUsage(value, autoCompactThreshold) {
2468
- if (typeof autoCompactThreshold === 'number' && Number.isFinite(autoCompactThreshold)) {
2469
- const boundedThreshold = Math.max(1, Math.min(100, Math.round(autoCompactThreshold)));
2470
- this.contextAutoCompactThreshold = boundedThreshold;
2471
- }
2472
- if (value === null || !Number.isFinite(value)) {
2473
- this.contextUsage = null;
2474
- }
2475
- else {
2476
- const bounded = Math.max(0, Math.min(100, Math.round(value)));
2477
- this.contextUsage = bounded;
2478
- }
2479
- this.scheduleRender();
2480
- }
2481
- getEditMode() {
2482
- return this.editMode;
2483
- }
2484
- applyEditMode(mode) {
2485
- this.setEditMode(mode);
2486
- }
2487
- setEditMode(mode) {
2488
- if (this.editMode === mode)
2489
- return;
2490
- this.editMode = mode;
2491
- this.emit('mode-change', this.editMode);
2492
- this.scheduleRender();
2493
- }
2494
- toggleEditMode() {
2495
- // Cycle through: display-edits → ask-permission → plan → display-edits
2496
- const cycle = ['display-edits', 'ask-permission', 'plan'];
2497
- const currentIndex = cycle.indexOf(this.editMode);
2498
- const nextIndex = (currentIndex + 1) % cycle.length;
2499
- this.setEditMode(cycle[nextIndex]);
2500
- }
2501
- scheduleStreamingRender(delayMs) {
2502
- if (this.streamingRenderTimer)
2503
- return;
2504
- const wait = Math.max(16, delayMs);
2505
- this.streamingRenderTimer = setTimeout(() => {
2506
- this.streamingRenderTimer = null;
2507
- // During streaming, only update chat box (not full render)
2508
- if (this.scrollRegionActive) {
2509
- this.renderStreamingFrame();
2510
- }
2511
- else {
2512
- this.render();
2513
- }
2514
- }, wait);
2515
- }
2516
- /**
2517
- * Render the pinned chat box during streaming only when we actually have
2518
- * pending UI changes. Prevents meta/header lines from being echoed into the
2519
- * streamed log when nothing changed.
2520
- */
2521
- renderStreamingFrame() {
2522
- if (!this.canRender())
2523
- return;
2524
- if (this.isRendering)
2525
- return;
2526
- const shouldSkip = !this.renderDirty &&
2527
- this.buffer === this.lastRenderContent &&
2528
- this.cursor === this.lastRenderCursor;
2529
- // Clear the dirty flag even when skipping to avoid runaway retries.
2530
- this.renderDirty = false;
2531
- if (shouldSkip) {
2532
- return;
2533
- }
2534
- if (writeLock.isLocked()) {
2535
- writeLock.safeWrite(() => this.renderStreamingFrame());
2536
- return;
2537
- }
2538
- this.renderPinnedChatBox();
2539
- }
2540
- resetStreamingRenderThrottle() {
2541
- if (this.streamingRenderTimer) {
2542
- clearTimeout(this.streamingRenderTimer);
2543
- this.streamingRenderTimer = null;
2544
- }
2545
- this.lastStreamingRender = 0;
2546
- }
2547
- scheduleRender() {
2548
- if (!this.canRender())
2549
- return;
2550
- this.renderDirty = true;
2551
- queueMicrotask(() => this.render());
2552
- }
2553
- canRender() {
2554
- return !this.disposed && this.enabled && this.isTTY();
2555
- }
2556
- isTTY() {
2557
- return !!this.out.isTTY && this.out.writable !== false;
2558
- }
2559
- getSize() {
2560
- return {
2561
- rows: this.out.rows ?? 24,
2562
- cols: this.out.columns ?? 80,
2563
- };
2564
- }
2565
- write(data) {
2566
- try {
2567
- if (this.out.writable) {
2568
- this.out.write(data);
2569
- }
2570
- }
2571
- catch {
2572
- // Ignore write errors
2573
- }
2574
- }
2575
- sanitize(text) {
2576
- if (!text)
2577
- return '';
2578
- // Remove ANSI codes and control chars (except newlines)
2579
- return text
2580
- .replace(/\x1b\][^\x07]*(?:\x07|\x1b\\)/g, '') // OSC sequences
2581
- .replace(/\x1b\[[0-9;]*[A-Za-z]/g, '') // CSI sequences
2582
- .replace(/[\x00-\x08\x0B\x0C\x0E-\x1F]/g, '') // Control chars except \n and \r
2583
- .replace(/\r\n?/g, '\n'); // Normalize line endings
2584
- }
2585
- getArrowKeyName(sequence) {
2586
- if (!sequence)
2587
- return null;
2588
- const match = sequence.match(/\x1b(?:\[[0-9;]*|O)([ABCD])$/) ||
2589
- sequence.match(/^\[?[0-9;]*([ABCD])$/);
2590
- if (!match)
2591
- return null;
2592
- switch (match[1]) {
2593
- case 'A':
2594
- return 'up';
2595
- case 'B':
2596
- return 'down';
2597
- case 'C':
2598
- return 'right';
2599
- case 'D':
2600
- return 'left';
2601
- default:
2602
- return null;
2603
- }
2604
- }
2605
- isArrowEscapeFragment(text) {
2606
- if (!text)
2607
- return false;
2608
- if (text.length > 8)
2609
- return false;
2610
- return (/^\x1b?(?:\[[0-9;]*|O)[ABCD]$/.test(text) ||
2611
- (/^\[?[0-9;]*[ABCD]$/.test(text) && text.length <= 6));
2612
- }
2613
- isOrphanedEscapeSequence(text, key) {
2614
- if (!text || key?.name)
2615
- return false;
2616
- // If sanitizing leaves printable content, treat it as user input.
2617
- const sanitized = this.sanitize(text);
2618
- if (sanitized.length > 0) {
2619
- return false;
2620
- }
2621
- if (text.includes('\x1b'))
2622
- return true;
2623
- // Common stray fragments when terminals partially echo arrow sequences (e.g., "[D")
2624
- return text.length <= 5 && (/^[\[O][0-9;]*[A-Za-z]$/.test(text));
2625
- }
2626
- isWhitespace(char) {
2627
- return char === ' ' || char === '\t' || char === '\n';
2628
- }
2629
- clampCursor() {
2630
- this.cursor = Math.max(0, Math.min(this.cursor, this.buffer.length));
2631
- }
2632
- }
2633
- //# sourceMappingURL=terminalInput.js.map