erosolar-cli 1.7.413 → 1.7.414

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 (1009) hide show
  1. package/dist/shell/interactiveShell.d.ts +1 -0
  2. package/dist/shell/interactiveShell.d.ts.map +1 -1
  3. package/dist/shell/interactiveShell.js +32 -20
  4. package/dist/shell/interactiveShell.js.map +1 -1
  5. package/package.json +1 -1
  6. package/dist/StringUtils.d.ts +0 -8
  7. package/dist/StringUtils.d.ts.map +0 -1
  8. package/dist/StringUtils.js +0 -11
  9. package/dist/StringUtils.js.map +0 -1
  10. package/dist/adapters/browser/index.d.ts +0 -12
  11. package/dist/adapters/browser/index.d.ts.map +0 -1
  12. package/dist/adapters/browser/index.js +0 -11
  13. package/dist/adapters/browser/index.js.map +0 -1
  14. package/dist/adapters/node/index.d.ts +0 -17
  15. package/dist/adapters/node/index.d.ts.map +0 -1
  16. package/dist/adapters/node/index.js +0 -35
  17. package/dist/adapters/node/index.js.map +0 -1
  18. package/dist/adapters/remote/index.d.ts +0 -13
  19. package/dist/adapters/remote/index.d.ts.map +0 -1
  20. package/dist/adapters/remote/index.js +0 -20
  21. package/dist/adapters/remote/index.js.map +0 -1
  22. package/dist/adapters/types.d.ts +0 -14
  23. package/dist/adapters/types.d.ts.map +0 -1
  24. package/dist/adapters/types.js +0 -2
  25. package/dist/adapters/types.js.map +0 -1
  26. package/dist/bin/erosolar.d.ts +0 -9
  27. package/dist/bin/erosolar.d.ts.map +0 -1
  28. package/dist/bin/erosolar.js +0 -93
  29. package/dist/bin/erosolar.js.map +0 -1
  30. package/dist/bin/selfTest.d.ts +0 -14
  31. package/dist/bin/selfTest.d.ts.map +0 -1
  32. package/dist/bin/selfTest.js +0 -304
  33. package/dist/bin/selfTest.js.map +0 -1
  34. package/dist/browser/BrowserSessionManager.d.ts +0 -307
  35. package/dist/browser/BrowserSessionManager.d.ts.map +0 -1
  36. package/dist/browser/BrowserSessionManager.js +0 -713
  37. package/dist/browser/BrowserSessionManager.js.map +0 -1
  38. package/dist/capabilities/advancedTestGenerationCapability.d.ts +0 -17
  39. package/dist/capabilities/advancedTestGenerationCapability.d.ts.map +0 -1
  40. package/dist/capabilities/advancedTestGenerationCapability.js +0 -28
  41. package/dist/capabilities/advancedTestGenerationCapability.js.map +0 -1
  42. package/dist/capabilities/agentSpawningCapability.d.ts +0 -6
  43. package/dist/capabilities/agentSpawningCapability.d.ts.map +0 -1
  44. package/dist/capabilities/agentSpawningCapability.js +0 -168
  45. package/dist/capabilities/agentSpawningCapability.js.map +0 -1
  46. package/dist/capabilities/askUserCapability.d.ts +0 -21
  47. package/dist/capabilities/askUserCapability.d.ts.map +0 -1
  48. package/dist/capabilities/askUserCapability.js +0 -155
  49. package/dist/capabilities/askUserCapability.js.map +0 -1
  50. package/dist/capabilities/bashCapability.d.ts +0 -13
  51. package/dist/capabilities/bashCapability.d.ts.map +0 -1
  52. package/dist/capabilities/bashCapability.js +0 -24
  53. package/dist/capabilities/bashCapability.js.map +0 -1
  54. package/dist/capabilities/browserAutomationCapability.d.ts +0 -37
  55. package/dist/capabilities/browserAutomationCapability.d.ts.map +0 -1
  56. package/dist/capabilities/browserAutomationCapability.js +0 -49
  57. package/dist/capabilities/browserAutomationCapability.js.map +0 -1
  58. package/dist/capabilities/buildCapability.d.ts +0 -24
  59. package/dist/capabilities/buildCapability.d.ts.map +0 -1
  60. package/dist/capabilities/buildCapability.js +0 -25
  61. package/dist/capabilities/buildCapability.js.map +0 -1
  62. package/dist/capabilities/cloudCapability.d.ts +0 -13
  63. package/dist/capabilities/cloudCapability.d.ts.map +0 -1
  64. package/dist/capabilities/cloudCapability.js +0 -38
  65. package/dist/capabilities/cloudCapability.js.map +0 -1
  66. package/dist/capabilities/codeAnalysisCapability.d.ts +0 -13
  67. package/dist/capabilities/codeAnalysisCapability.d.ts.map +0 -1
  68. package/dist/capabilities/codeAnalysisCapability.js +0 -24
  69. package/dist/capabilities/codeAnalysisCapability.js.map +0 -1
  70. package/dist/capabilities/codeGenerationCapability.d.ts +0 -13
  71. package/dist/capabilities/codeGenerationCapability.d.ts.map +0 -1
  72. package/dist/capabilities/codeGenerationCapability.js +0 -25
  73. package/dist/capabilities/codeGenerationCapability.js.map +0 -1
  74. package/dist/capabilities/codeQualityCapability.d.ts +0 -13
  75. package/dist/capabilities/codeQualityCapability.d.ts.map +0 -1
  76. package/dist/capabilities/codeQualityCapability.js +0 -25
  77. package/dist/capabilities/codeQualityCapability.js.map +0 -1
  78. package/dist/capabilities/dependencySecurityCapability.d.ts +0 -13
  79. package/dist/capabilities/dependencySecurityCapability.d.ts.map +0 -1
  80. package/dist/capabilities/dependencySecurityCapability.js +0 -24
  81. package/dist/capabilities/dependencySecurityCapability.js.map +0 -1
  82. package/dist/capabilities/devCapability.d.ts +0 -13
  83. package/dist/capabilities/devCapability.d.ts.map +0 -1
  84. package/dist/capabilities/devCapability.js +0 -24
  85. package/dist/capabilities/devCapability.js.map +0 -1
  86. package/dist/capabilities/editCapability.d.ts +0 -17
  87. package/dist/capabilities/editCapability.d.ts.map +0 -1
  88. package/dist/capabilities/editCapability.js +0 -27
  89. package/dist/capabilities/editCapability.js.map +0 -1
  90. package/dist/capabilities/emailCapability.d.ts +0 -12
  91. package/dist/capabilities/emailCapability.d.ts.map +0 -1
  92. package/dist/capabilities/emailCapability.js +0 -22
  93. package/dist/capabilities/emailCapability.js.map +0 -1
  94. package/dist/capabilities/enhancedCodeIntelligenceCapability.d.ts +0 -17
  95. package/dist/capabilities/enhancedCodeIntelligenceCapability.d.ts.map +0 -1
  96. package/dist/capabilities/enhancedCodeIntelligenceCapability.js +0 -28
  97. package/dist/capabilities/enhancedCodeIntelligenceCapability.js.map +0 -1
  98. package/dist/capabilities/enhancedDevWorkflowCapability.d.ts +0 -17
  99. package/dist/capabilities/enhancedDevWorkflowCapability.d.ts.map +0 -1
  100. package/dist/capabilities/enhancedDevWorkflowCapability.js +0 -28
  101. package/dist/capabilities/enhancedDevWorkflowCapability.js.map +0 -1
  102. package/dist/capabilities/enhancedGitCapability.d.ts +0 -7
  103. package/dist/capabilities/enhancedGitCapability.d.ts.map +0 -1
  104. package/dist/capabilities/enhancedGitCapability.js +0 -220
  105. package/dist/capabilities/enhancedGitCapability.js.map +0 -1
  106. package/dist/capabilities/filesystemCapability.d.ts +0 -13
  107. package/dist/capabilities/filesystemCapability.d.ts.map +0 -1
  108. package/dist/capabilities/filesystemCapability.js +0 -24
  109. package/dist/capabilities/filesystemCapability.js.map +0 -1
  110. package/dist/capabilities/frontendTestingCapability.d.ts +0 -13
  111. package/dist/capabilities/frontendTestingCapability.d.ts.map +0 -1
  112. package/dist/capabilities/frontendTestingCapability.js +0 -28
  113. package/dist/capabilities/frontendTestingCapability.js.map +0 -1
  114. package/dist/capabilities/globCapability.d.ts +0 -17
  115. package/dist/capabilities/globCapability.d.ts.map +0 -1
  116. package/dist/capabilities/globCapability.js +0 -27
  117. package/dist/capabilities/globCapability.js.map +0 -1
  118. package/dist/capabilities/index.d.ts +0 -26
  119. package/dist/capabilities/index.d.ts.map +0 -1
  120. package/dist/capabilities/index.js +0 -26
  121. package/dist/capabilities/index.js.map +0 -1
  122. package/dist/capabilities/interactionCapability.d.ts +0 -12
  123. package/dist/capabilities/interactionCapability.d.ts.map +0 -1
  124. package/dist/capabilities/interactionCapability.js +0 -22
  125. package/dist/capabilities/interactionCapability.js.map +0 -1
  126. package/dist/capabilities/learnCapability.d.ts +0 -22
  127. package/dist/capabilities/learnCapability.d.ts.map +0 -1
  128. package/dist/capabilities/learnCapability.js +0 -37
  129. package/dist/capabilities/learnCapability.js.map +0 -1
  130. package/dist/capabilities/mcpCapability.d.ts +0 -6
  131. package/dist/capabilities/mcpCapability.d.ts.map +0 -1
  132. package/dist/capabilities/mcpCapability.js +0 -19
  133. package/dist/capabilities/mcpCapability.js.map +0 -1
  134. package/dist/capabilities/notebookCapability.d.ts +0 -17
  135. package/dist/capabilities/notebookCapability.d.ts.map +0 -1
  136. package/dist/capabilities/notebookCapability.js +0 -27
  137. package/dist/capabilities/notebookCapability.js.map +0 -1
  138. package/dist/capabilities/performanceMonitoringCapability.d.ts +0 -108
  139. package/dist/capabilities/performanceMonitoringCapability.d.ts.map +0 -1
  140. package/dist/capabilities/performanceMonitoringCapability.js +0 -176
  141. package/dist/capabilities/performanceMonitoringCapability.js.map +0 -1
  142. package/dist/capabilities/planningCapability.d.ts +0 -16
  143. package/dist/capabilities/planningCapability.d.ts.map +0 -1
  144. package/dist/capabilities/planningCapability.js +0 -26
  145. package/dist/capabilities/planningCapability.js.map +0 -1
  146. package/dist/capabilities/refactoringCapability.d.ts +0 -13
  147. package/dist/capabilities/refactoringCapability.d.ts.map +0 -1
  148. package/dist/capabilities/refactoringCapability.js +0 -25
  149. package/dist/capabilities/refactoringCapability.js.map +0 -1
  150. package/dist/capabilities/repoChecksCapability.d.ts +0 -10
  151. package/dist/capabilities/repoChecksCapability.d.ts.map +0 -1
  152. package/dist/capabilities/repoChecksCapability.js +0 -24
  153. package/dist/capabilities/repoChecksCapability.js.map +0 -1
  154. package/dist/capabilities/searchCapability.d.ts +0 -13
  155. package/dist/capabilities/searchCapability.d.ts.map +0 -1
  156. package/dist/capabilities/searchCapability.js +0 -24
  157. package/dist/capabilities/searchCapability.js.map +0 -1
  158. package/dist/capabilities/skillCapability.d.ts +0 -3
  159. package/dist/capabilities/skillCapability.d.ts.map +0 -1
  160. package/dist/capabilities/skillCapability.js +0 -77
  161. package/dist/capabilities/skillCapability.js.map +0 -1
  162. package/dist/capabilities/taskManagementCapability.d.ts +0 -12
  163. package/dist/capabilities/taskManagementCapability.d.ts.map +0 -1
  164. package/dist/capabilities/taskManagementCapability.js +0 -22
  165. package/dist/capabilities/taskManagementCapability.js.map +0 -1
  166. package/dist/capabilities/testingCapability.d.ts +0 -13
  167. package/dist/capabilities/testingCapability.d.ts.map +0 -1
  168. package/dist/capabilities/testingCapability.js +0 -25
  169. package/dist/capabilities/testingCapability.js.map +0 -1
  170. package/dist/capabilities/todoCapability.d.ts +0 -19
  171. package/dist/capabilities/todoCapability.d.ts.map +0 -1
  172. package/dist/capabilities/todoCapability.js +0 -169
  173. package/dist/capabilities/todoCapability.js.map +0 -1
  174. package/dist/capabilities/toolManifest.d.ts +0 -3
  175. package/dist/capabilities/toolManifest.d.ts.map +0 -1
  176. package/dist/capabilities/toolManifest.js +0 -160
  177. package/dist/capabilities/toolManifest.js.map +0 -1
  178. package/dist/capabilities/toolRegistry.d.ts +0 -24
  179. package/dist/capabilities/toolRegistry.d.ts.map +0 -1
  180. package/dist/capabilities/toolRegistry.js +0 -150
  181. package/dist/capabilities/toolRegistry.js.map +0 -1
  182. package/dist/capabilities/validationCapability.d.ts +0 -13
  183. package/dist/capabilities/validationCapability.d.ts.map +0 -1
  184. package/dist/capabilities/validationCapability.js +0 -24
  185. package/dist/capabilities/validationCapability.js.map +0 -1
  186. package/dist/capabilities/webCapability.d.ts +0 -12
  187. package/dist/capabilities/webCapability.d.ts.map +0 -1
  188. package/dist/capabilities/webCapability.js +0 -22
  189. package/dist/capabilities/webCapability.js.map +0 -1
  190. package/dist/config.d.ts +0 -25
  191. package/dist/config.d.ts.map +0 -1
  192. package/dist/config.js +0 -140
  193. package/dist/config.js.map +0 -1
  194. package/dist/contracts/v1/agent.d.ts +0 -147
  195. package/dist/contracts/v1/agent.d.ts.map +0 -1
  196. package/dist/contracts/v1/agent.js +0 -8
  197. package/dist/contracts/v1/agent.js.map +0 -1
  198. package/dist/contracts/v1/agentProfileManifest.d.ts +0 -60
  199. package/dist/contracts/v1/agentProfileManifest.d.ts.map +0 -1
  200. package/dist/contracts/v1/agentProfileManifest.js +0 -9
  201. package/dist/contracts/v1/agentProfileManifest.js.map +0 -1
  202. package/dist/contracts/v1/agentRules.d.ts +0 -60
  203. package/dist/contracts/v1/agentRules.d.ts.map +0 -1
  204. package/dist/contracts/v1/agentRules.js +0 -10
  205. package/dist/contracts/v1/agentRules.js.map +0 -1
  206. package/dist/contracts/v1/provider.d.ts +0 -149
  207. package/dist/contracts/v1/provider.d.ts.map +0 -1
  208. package/dist/contracts/v1/provider.js +0 -7
  209. package/dist/contracts/v1/provider.js.map +0 -1
  210. package/dist/contracts/v1/tool.d.ts +0 -136
  211. package/dist/contracts/v1/tool.d.ts.map +0 -1
  212. package/dist/contracts/v1/tool.js +0 -7
  213. package/dist/contracts/v1/tool.js.map +0 -1
  214. package/dist/contracts/v1/toolAccess.d.ts +0 -43
  215. package/dist/contracts/v1/toolAccess.d.ts.map +0 -1
  216. package/dist/contracts/v1/toolAccess.js +0 -9
  217. package/dist/contracts/v1/toolAccess.js.map +0 -1
  218. package/dist/core/LazyLoader.d.ts +0 -129
  219. package/dist/core/LazyLoader.d.ts.map +0 -1
  220. package/dist/core/LazyLoader.js +0 -240
  221. package/dist/core/LazyLoader.js.map +0 -1
  222. package/dist/core/agent.d.ts +0 -153
  223. package/dist/core/agent.d.ts.map +0 -1
  224. package/dist/core/agent.js +0 -881
  225. package/dist/core/agent.js.map +0 -1
  226. package/dist/core/agentProfileManifest.d.ts +0 -3
  227. package/dist/core/agentProfileManifest.d.ts.map +0 -1
  228. package/dist/core/agentProfileManifest.js +0 -188
  229. package/dist/core/agentProfileManifest.js.map +0 -1
  230. package/dist/core/agentProfiles.d.ts +0 -22
  231. package/dist/core/agentProfiles.d.ts.map +0 -1
  232. package/dist/core/agentProfiles.js +0 -35
  233. package/dist/core/agentProfiles.js.map +0 -1
  234. package/dist/core/agentRulebook.d.ts +0 -11
  235. package/dist/core/agentRulebook.d.ts.map +0 -1
  236. package/dist/core/agentRulebook.js +0 -136
  237. package/dist/core/agentRulebook.js.map +0 -1
  238. package/dist/core/agentSchemaLoader.d.ts +0 -131
  239. package/dist/core/agentSchemaLoader.d.ts.map +0 -1
  240. package/dist/core/agentSchemaLoader.js +0 -234
  241. package/dist/core/agentSchemaLoader.js.map +0 -1
  242. package/dist/core/aiErrorFixer.d.ts +0 -70
  243. package/dist/core/aiErrorFixer.d.ts.map +0 -1
  244. package/dist/core/aiErrorFixer.js +0 -402
  245. package/dist/core/aiErrorFixer.js.map +0 -1
  246. package/dist/core/alphaZeroEngine.d.ts +0 -269
  247. package/dist/core/alphaZeroEngine.d.ts.map +0 -1
  248. package/dist/core/alphaZeroEngine.js +0 -523
  249. package/dist/core/alphaZeroEngine.js.map +0 -1
  250. package/dist/core/alphaZeroModular.d.ts +0 -186
  251. package/dist/core/alphaZeroModular.d.ts.map +0 -1
  252. package/dist/core/alphaZeroModular.js +0 -755
  253. package/dist/core/alphaZeroModular.js.map +0 -1
  254. package/dist/core/alphaZeroOrchestrator.d.ts +0 -140
  255. package/dist/core/alphaZeroOrchestrator.d.ts.map +0 -1
  256. package/dist/core/alphaZeroOrchestrator.js +0 -418
  257. package/dist/core/alphaZeroOrchestrator.js.map +0 -1
  258. package/dist/core/checkpoint.d.ts +0 -76
  259. package/dist/core/checkpoint.d.ts.map +0 -1
  260. package/dist/core/checkpoint.js +0 -278
  261. package/dist/core/checkpoint.js.map +0 -1
  262. package/dist/core/claudeCodeFeatures.d.ts +0 -64
  263. package/dist/core/claudeCodeFeatures.d.ts.map +0 -1
  264. package/dist/core/claudeCodeFeatures.js +0 -163
  265. package/dist/core/claudeCodeFeatures.js.map +0 -1
  266. package/dist/core/cliTestHarness.d.ts +0 -200
  267. package/dist/core/cliTestHarness.d.ts.map +0 -1
  268. package/dist/core/cliTestHarness.js +0 -549
  269. package/dist/core/cliTestHarness.js.map +0 -1
  270. package/dist/core/contextManager.d.ts +0 -265
  271. package/dist/core/contextManager.d.ts.map +0 -1
  272. package/dist/core/contextManager.js +0 -1060
  273. package/dist/core/contextManager.js.map +0 -1
  274. package/dist/core/contextWindow.d.ts +0 -42
  275. package/dist/core/contextWindow.d.ts.map +0 -1
  276. package/dist/core/contextWindow.js +0 -123
  277. package/dist/core/contextWindow.js.map +0 -1
  278. package/dist/core/costTracker.d.ts +0 -87
  279. package/dist/core/costTracker.d.ts.map +0 -1
  280. package/dist/core/costTracker.js +0 -285
  281. package/dist/core/costTracker.js.map +0 -1
  282. package/dist/core/customCommands.d.ts +0 -19
  283. package/dist/core/customCommands.d.ts.map +0 -1
  284. package/dist/core/customCommands.js +0 -84
  285. package/dist/core/customCommands.js.map +0 -1
  286. package/dist/core/errors/apiKeyErrors.d.ts +0 -11
  287. package/dist/core/errors/apiKeyErrors.d.ts.map +0 -1
  288. package/dist/core/errors/apiKeyErrors.js +0 -159
  289. package/dist/core/errors/apiKeyErrors.js.map +0 -1
  290. package/dist/core/errors/errorTypes.d.ts +0 -111
  291. package/dist/core/errors/errorTypes.d.ts.map +0 -1
  292. package/dist/core/errors/errorTypes.js +0 -348
  293. package/dist/core/errors/errorTypes.js.map +0 -1
  294. package/dist/core/errors/errorUtils.d.ts +0 -87
  295. package/dist/core/errors/errorUtils.d.ts.map +0 -1
  296. package/dist/core/errors/errorUtils.js +0 -158
  297. package/dist/core/errors/errorUtils.js.map +0 -1
  298. package/dist/core/errors/safetyValidator.d.ts +0 -71
  299. package/dist/core/errors/safetyValidator.d.ts.map +0 -1
  300. package/dist/core/errors/safetyValidator.js +0 -302
  301. package/dist/core/errors/safetyValidator.js.map +0 -1
  302. package/dist/core/errors.d.ts +0 -4
  303. package/dist/core/errors.d.ts.map +0 -1
  304. package/dist/core/errors.js +0 -33
  305. package/dist/core/errors.js.map +0 -1
  306. package/dist/core/failureRecovery.d.ts +0 -122
  307. package/dist/core/failureRecovery.d.ts.map +0 -1
  308. package/dist/core/failureRecovery.js +0 -477
  309. package/dist/core/failureRecovery.js.map +0 -1
  310. package/dist/core/hooks.d.ts +0 -113
  311. package/dist/core/hooks.d.ts.map +0 -1
  312. package/dist/core/hooks.js +0 -267
  313. package/dist/core/hooks.js.map +0 -1
  314. package/dist/core/intelligentTestFlows.d.ts +0 -126
  315. package/dist/core/intelligentTestFlows.d.ts.map +0 -1
  316. package/dist/core/intelligentTestFlows.js +0 -678
  317. package/dist/core/intelligentTestFlows.js.map +0 -1
  318. package/dist/core/isolatedVerifier.d.ts +0 -40
  319. package/dist/core/isolatedVerifier.d.ts.map +0 -1
  320. package/dist/core/isolatedVerifier.js +0 -129
  321. package/dist/core/isolatedVerifier.js.map +0 -1
  322. package/dist/core/learningPersistence.d.ts +0 -145
  323. package/dist/core/learningPersistence.d.ts.map +0 -1
  324. package/dist/core/learningPersistence.js +0 -477
  325. package/dist/core/learningPersistence.js.map +0 -1
  326. package/dist/core/memorySystem.d.ts +0 -67
  327. package/dist/core/memorySystem.d.ts.map +0 -1
  328. package/dist/core/memorySystem.js +0 -334
  329. package/dist/core/memorySystem.js.map +0 -1
  330. package/dist/core/metricsTracker.d.ts +0 -157
  331. package/dist/core/metricsTracker.d.ts.map +0 -1
  332. package/dist/core/metricsTracker.js +0 -273
  333. package/dist/core/metricsTracker.js.map +0 -1
  334. package/dist/core/modelDiscovery.d.ts +0 -101
  335. package/dist/core/modelDiscovery.d.ts.map +0 -1
  336. package/dist/core/modelDiscovery.js +0 -780
  337. package/dist/core/modelDiscovery.js.map +0 -1
  338. package/dist/core/multilinePasteHandler.d.ts +0 -35
  339. package/dist/core/multilinePasteHandler.d.ts.map +0 -1
  340. package/dist/core/multilinePasteHandler.js +0 -80
  341. package/dist/core/multilinePasteHandler.js.map +0 -1
  342. package/dist/core/offsecAlphaZero.d.ts +0 -56
  343. package/dist/core/offsecAlphaZero.d.ts.map +0 -1
  344. package/dist/core/offsecAlphaZero.js +0 -395
  345. package/dist/core/offsecAlphaZero.js.map +0 -1
  346. package/dist/core/outputStyles.d.ts +0 -48
  347. package/dist/core/outputStyles.d.ts.map +0 -1
  348. package/dist/core/outputStyles.js +0 -270
  349. package/dist/core/outputStyles.js.map +0 -1
  350. package/dist/core/performanceMonitor.d.ts +0 -124
  351. package/dist/core/performanceMonitor.d.ts.map +0 -1
  352. package/dist/core/performanceMonitor.js +0 -192
  353. package/dist/core/performanceMonitor.js.map +0 -1
  354. package/dist/core/preferences.d.ts +0 -67
  355. package/dist/core/preferences.d.ts.map +0 -1
  356. package/dist/core/preferences.js +0 -314
  357. package/dist/core/preferences.js.map +0 -1
  358. package/dist/core/responseVerifier.d.ts +0 -98
  359. package/dist/core/responseVerifier.d.ts.map +0 -1
  360. package/dist/core/responseVerifier.js +0 -509
  361. package/dist/core/responseVerifier.js.map +0 -1
  362. package/dist/core/resultVerification.d.ts +0 -141
  363. package/dist/core/resultVerification.d.ts.map +0 -1
  364. package/dist/core/resultVerification.js +0 -482
  365. package/dist/core/resultVerification.js.map +0 -1
  366. package/dist/core/schemaValidator.d.ts +0 -44
  367. package/dist/core/schemaValidator.d.ts.map +0 -1
  368. package/dist/core/schemaValidator.js +0 -155
  369. package/dist/core/schemaValidator.js.map +0 -1
  370. package/dist/core/secretStore.d.ts +0 -48
  371. package/dist/core/secretStore.d.ts.map +0 -1
  372. package/dist/core/secretStore.js +0 -367
  373. package/dist/core/secretStore.js.map +0 -1
  374. package/dist/core/securityAssessment.d.ts +0 -91
  375. package/dist/core/securityAssessment.d.ts.map +0 -1
  376. package/dist/core/securityAssessment.js +0 -580
  377. package/dist/core/securityAssessment.js.map +0 -1
  378. package/dist/core/selfEvolution.d.ts +0 -155
  379. package/dist/core/selfEvolution.d.ts.map +0 -1
  380. package/dist/core/selfEvolution.js +0 -1000
  381. package/dist/core/selfEvolution.js.map +0 -1
  382. package/dist/core/selfImprovement.d.ts +0 -141
  383. package/dist/core/selfImprovement.d.ts.map +0 -1
  384. package/dist/core/selfImprovement.js +0 -700
  385. package/dist/core/selfImprovement.js.map +0 -1
  386. package/dist/core/sessionStore.d.ts +0 -35
  387. package/dist/core/sessionStore.d.ts.map +0 -1
  388. package/dist/core/sessionStore.js +0 -189
  389. package/dist/core/sessionStore.js.map +0 -1
  390. package/dist/core/testUtils.d.ts +0 -121
  391. package/dist/core/testUtils.d.ts.map +0 -1
  392. package/dist/core/testUtils.js +0 -235
  393. package/dist/core/testUtils.js.map +0 -1
  394. package/dist/core/toolPreconditions.d.ts +0 -42
  395. package/dist/core/toolPreconditions.d.ts.map +0 -1
  396. package/dist/core/toolPreconditions.js +0 -357
  397. package/dist/core/toolPreconditions.js.map +0 -1
  398. package/dist/core/toolRuntime.d.ts +0 -158
  399. package/dist/core/toolRuntime.d.ts.map +0 -1
  400. package/dist/core/toolRuntime.js +0 -415
  401. package/dist/core/toolRuntime.js.map +0 -1
  402. package/dist/core/toolValidation.d.ts +0 -117
  403. package/dist/core/toolValidation.d.ts.map +0 -1
  404. package/dist/core/toolValidation.js +0 -282
  405. package/dist/core/toolValidation.js.map +0 -1
  406. package/dist/core/types/utilityTypes.d.ts +0 -192
  407. package/dist/core/types/utilityTypes.d.ts.map +0 -1
  408. package/dist/core/types/utilityTypes.js +0 -272
  409. package/dist/core/types/utilityTypes.js.map +0 -1
  410. package/dist/core/types.d.ts +0 -306
  411. package/dist/core/types.d.ts.map +0 -1
  412. package/dist/core/types.js +0 -76
  413. package/dist/core/types.js.map +0 -1
  414. package/dist/core/updateManager.d.ts +0 -62
  415. package/dist/core/updateManager.d.ts.map +0 -1
  416. package/dist/core/updateManager.js +0 -266
  417. package/dist/core/updateManager.js.map +0 -1
  418. package/dist/core/validationRunner.d.ts +0 -106
  419. package/dist/core/validationRunner.d.ts.map +0 -1
  420. package/dist/core/validationRunner.js +0 -888
  421. package/dist/core/validationRunner.js.map +0 -1
  422. package/dist/core/verification.d.ts +0 -137
  423. package/dist/core/verification.d.ts.map +0 -1
  424. package/dist/core/verification.js +0 -323
  425. package/dist/core/verification.js.map +0 -1
  426. package/dist/headless/headlessApp.d.ts +0 -5
  427. package/dist/headless/headlessApp.d.ts.map +0 -1
  428. package/dist/headless/headlessApp.js +0 -210
  429. package/dist/headless/headlessApp.js.map +0 -1
  430. package/dist/intelligence/codeIntelligence.d.ts +0 -118
  431. package/dist/intelligence/codeIntelligence.d.ts.map +0 -1
  432. package/dist/intelligence/codeIntelligence.js +0 -552
  433. package/dist/intelligence/codeIntelligence.js.map +0 -1
  434. package/dist/intelligence/docGenerator.d.ts +0 -86
  435. package/dist/intelligence/docGenerator.d.ts.map +0 -1
  436. package/dist/intelligence/docGenerator.js +0 -564
  437. package/dist/intelligence/docGenerator.js.map +0 -1
  438. package/dist/intelligence/index.d.ts +0 -51
  439. package/dist/intelligence/index.d.ts.map +0 -1
  440. package/dist/intelligence/index.js +0 -253
  441. package/dist/intelligence/index.js.map +0 -1
  442. package/dist/intelligence/refactoring.d.ts +0 -50
  443. package/dist/intelligence/refactoring.d.ts.map +0 -1
  444. package/dist/intelligence/refactoring.js +0 -354
  445. package/dist/intelligence/refactoring.js.map +0 -1
  446. package/dist/intelligence/testGenerator.d.ts +0 -74
  447. package/dist/intelligence/testGenerator.d.ts.map +0 -1
  448. package/dist/intelligence/testGenerator.js +0 -483
  449. package/dist/intelligence/testGenerator.js.map +0 -1
  450. package/dist/mcp/config.d.ts +0 -8
  451. package/dist/mcp/config.d.ts.map +0 -1
  452. package/dist/mcp/config.js +0 -252
  453. package/dist/mcp/config.js.map +0 -1
  454. package/dist/mcp/sseClient.d.ts +0 -34
  455. package/dist/mcp/sseClient.d.ts.map +0 -1
  456. package/dist/mcp/sseClient.js +0 -327
  457. package/dist/mcp/sseClient.js.map +0 -1
  458. package/dist/mcp/stdioClient.d.ts +0 -24
  459. package/dist/mcp/stdioClient.d.ts.map +0 -1
  460. package/dist/mcp/stdioClient.js +0 -179
  461. package/dist/mcp/stdioClient.js.map +0 -1
  462. package/dist/mcp/toolBridge.d.ts +0 -12
  463. package/dist/mcp/toolBridge.d.ts.map +0 -1
  464. package/dist/mcp/toolBridge.js +0 -117
  465. package/dist/mcp/toolBridge.js.map +0 -1
  466. package/dist/mcp/types.d.ts +0 -60
  467. package/dist/mcp/types.d.ts.map +0 -1
  468. package/dist/mcp/types.js +0 -2
  469. package/dist/mcp/types.js.map +0 -1
  470. package/dist/plugins/index.d.ts +0 -49
  471. package/dist/plugins/index.d.ts.map +0 -1
  472. package/dist/plugins/index.js +0 -114
  473. package/dist/plugins/index.js.map +0 -1
  474. package/dist/plugins/providers/anthropic/index.d.ts +0 -11
  475. package/dist/plugins/providers/anthropic/index.d.ts.map +0 -1
  476. package/dist/plugins/providers/anthropic/index.js +0 -38
  477. package/dist/plugins/providers/anthropic/index.js.map +0 -1
  478. package/dist/plugins/providers/deepseek/index.d.ts +0 -11
  479. package/dist/plugins/providers/deepseek/index.d.ts.map +0 -1
  480. package/dist/plugins/providers/deepseek/index.js +0 -52
  481. package/dist/plugins/providers/deepseek/index.js.map +0 -1
  482. package/dist/plugins/providers/google/index.d.ts +0 -11
  483. package/dist/plugins/providers/google/index.d.ts.map +0 -1
  484. package/dist/plugins/providers/google/index.js +0 -40
  485. package/dist/plugins/providers/google/index.js.map +0 -1
  486. package/dist/plugins/providers/index.d.ts +0 -2
  487. package/dist/plugins/providers/index.d.ts.map +0 -1
  488. package/dist/plugins/providers/index.js +0 -20
  489. package/dist/plugins/providers/index.js.map +0 -1
  490. package/dist/plugins/providers/ollama/index.d.ts +0 -21
  491. package/dist/plugins/providers/ollama/index.d.ts.map +0 -1
  492. package/dist/plugins/providers/ollama/index.js +0 -69
  493. package/dist/plugins/providers/ollama/index.js.map +0 -1
  494. package/dist/plugins/providers/openai/index.d.ts +0 -12
  495. package/dist/plugins/providers/openai/index.d.ts.map +0 -1
  496. package/dist/plugins/providers/openai/index.js +0 -39
  497. package/dist/plugins/providers/openai/index.js.map +0 -1
  498. package/dist/plugins/providers/xai/index.d.ts +0 -11
  499. package/dist/plugins/providers/xai/index.d.ts.map +0 -1
  500. package/dist/plugins/providers/xai/index.js +0 -39
  501. package/dist/plugins/providers/xai/index.js.map +0 -1
  502. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.d.ts +0 -3
  503. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.d.ts.map +0 -1
  504. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.js +0 -9
  505. package/dist/plugins/tools/agentSpawning/agentSpawningPlugin.js.map +0 -1
  506. package/dist/plugins/tools/bash/localBashPlugin.d.ts +0 -3
  507. package/dist/plugins/tools/bash/localBashPlugin.d.ts.map +0 -1
  508. package/dist/plugins/tools/bash/localBashPlugin.js +0 -14
  509. package/dist/plugins/tools/bash/localBashPlugin.js.map +0 -1
  510. package/dist/plugins/tools/browser/browserAutomationPlugin.d.ts +0 -14
  511. package/dist/plugins/tools/browser/browserAutomationPlugin.d.ts.map +0 -1
  512. package/dist/plugins/tools/browser/browserAutomationPlugin.js +0 -26
  513. package/dist/plugins/tools/browser/browserAutomationPlugin.js.map +0 -1
  514. package/dist/plugins/tools/checks/localRepoChecksPlugin.d.ts +0 -3
  515. package/dist/plugins/tools/checks/localRepoChecksPlugin.d.ts.map +0 -1
  516. package/dist/plugins/tools/checks/localRepoChecksPlugin.js +0 -14
  517. package/dist/plugins/tools/checks/localRepoChecksPlugin.js.map +0 -1
  518. package/dist/plugins/tools/cloud/cloudPlugin.d.ts +0 -3
  519. package/dist/plugins/tools/cloud/cloudPlugin.d.ts.map +0 -1
  520. package/dist/plugins/tools/cloud/cloudPlugin.js +0 -14
  521. package/dist/plugins/tools/cloud/cloudPlugin.js.map +0 -1
  522. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.d.ts +0 -3
  523. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.d.ts.map +0 -1
  524. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.js +0 -14
  525. package/dist/plugins/tools/codeAnalysis/codeAnalysisPlugin.js.map +0 -1
  526. package/dist/plugins/tools/codeQuality/codeQualityPlugin.d.ts +0 -3
  527. package/dist/plugins/tools/codeQuality/codeQualityPlugin.d.ts.map +0 -1
  528. package/dist/plugins/tools/codeQuality/codeQualityPlugin.js +0 -14
  529. package/dist/plugins/tools/codeQuality/codeQualityPlugin.js.map +0 -1
  530. package/dist/plugins/tools/dependency/dependencyPlugin.d.ts +0 -3
  531. package/dist/plugins/tools/dependency/dependencyPlugin.d.ts.map +0 -1
  532. package/dist/plugins/tools/dependency/dependencyPlugin.js +0 -12
  533. package/dist/plugins/tools/dependency/dependencyPlugin.js.map +0 -1
  534. package/dist/plugins/tools/development/devPlugin.d.ts +0 -3
  535. package/dist/plugins/tools/development/devPlugin.d.ts.map +0 -1
  536. package/dist/plugins/tools/development/devPlugin.js +0 -14
  537. package/dist/plugins/tools/development/devPlugin.js.map +0 -1
  538. package/dist/plugins/tools/edit/editPlugin.d.ts +0 -9
  539. package/dist/plugins/tools/edit/editPlugin.d.ts.map +0 -1
  540. package/dist/plugins/tools/edit/editPlugin.js +0 -15
  541. package/dist/plugins/tools/edit/editPlugin.js.map +0 -1
  542. package/dist/plugins/tools/email/emailPlugin.d.ts +0 -3
  543. package/dist/plugins/tools/email/emailPlugin.d.ts.map +0 -1
  544. package/dist/plugins/tools/email/emailPlugin.js +0 -12
  545. package/dist/plugins/tools/email/emailPlugin.js.map +0 -1
  546. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.d.ts +0 -3
  547. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.d.ts.map +0 -1
  548. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.js +0 -9
  549. package/dist/plugins/tools/enhancedGit/enhancedGitPlugin.js.map +0 -1
  550. package/dist/plugins/tools/filesystem/localFilesystemPlugin.d.ts +0 -3
  551. package/dist/plugins/tools/filesystem/localFilesystemPlugin.d.ts.map +0 -1
  552. package/dist/plugins/tools/filesystem/localFilesystemPlugin.js +0 -14
  553. package/dist/plugins/tools/filesystem/localFilesystemPlugin.js.map +0 -1
  554. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.d.ts +0 -3
  555. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.d.ts.map +0 -1
  556. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.js +0 -14
  557. package/dist/plugins/tools/frontendTesting/frontendTestingPlugin.js.map +0 -1
  558. package/dist/plugins/tools/glob/globPlugin.d.ts +0 -9
  559. package/dist/plugins/tools/glob/globPlugin.d.ts.map +0 -1
  560. package/dist/plugins/tools/glob/globPlugin.js +0 -15
  561. package/dist/plugins/tools/glob/globPlugin.js.map +0 -1
  562. package/dist/plugins/tools/index.d.ts +0 -3
  563. package/dist/plugins/tools/index.d.ts.map +0 -1
  564. package/dist/plugins/tools/index.js +0 -3
  565. package/dist/plugins/tools/index.js.map +0 -1
  566. package/dist/plugins/tools/interaction/interactionPlugin.d.ts +0 -3
  567. package/dist/plugins/tools/interaction/interactionPlugin.d.ts.map +0 -1
  568. package/dist/plugins/tools/interaction/interactionPlugin.js +0 -12
  569. package/dist/plugins/tools/interaction/interactionPlugin.js.map +0 -1
  570. package/dist/plugins/tools/learn/learnPlugin.d.ts +0 -3
  571. package/dist/plugins/tools/learn/learnPlugin.d.ts.map +0 -1
  572. package/dist/plugins/tools/learn/learnPlugin.js +0 -14
  573. package/dist/plugins/tools/learn/learnPlugin.js.map +0 -1
  574. package/dist/plugins/tools/mcp/mcpPlugin.d.ts +0 -3
  575. package/dist/plugins/tools/mcp/mcpPlugin.d.ts.map +0 -1
  576. package/dist/plugins/tools/mcp/mcpPlugin.js +0 -9
  577. package/dist/plugins/tools/mcp/mcpPlugin.js.map +0 -1
  578. package/dist/plugins/tools/nodeDefaults.d.ts +0 -2
  579. package/dist/plugins/tools/nodeDefaults.d.ts.map +0 -1
  580. package/dist/plugins/tools/nodeDefaults.js +0 -65
  581. package/dist/plugins/tools/nodeDefaults.js.map +0 -1
  582. package/dist/plugins/tools/notebook/notebookPlugin.d.ts +0 -9
  583. package/dist/plugins/tools/notebook/notebookPlugin.d.ts.map +0 -1
  584. package/dist/plugins/tools/notebook/notebookPlugin.js +0 -15
  585. package/dist/plugins/tools/notebook/notebookPlugin.js.map +0 -1
  586. package/dist/plugins/tools/planning/planningPlugin.d.ts +0 -9
  587. package/dist/plugins/tools/planning/planningPlugin.d.ts.map +0 -1
  588. package/dist/plugins/tools/planning/planningPlugin.js +0 -15
  589. package/dist/plugins/tools/planning/planningPlugin.js.map +0 -1
  590. package/dist/plugins/tools/refactoring/refactoringPlugin.d.ts +0 -3
  591. package/dist/plugins/tools/refactoring/refactoringPlugin.d.ts.map +0 -1
  592. package/dist/plugins/tools/refactoring/refactoringPlugin.js +0 -12
  593. package/dist/plugins/tools/refactoring/refactoringPlugin.js.map +0 -1
  594. package/dist/plugins/tools/registry.d.ts +0 -22
  595. package/dist/plugins/tools/registry.d.ts.map +0 -1
  596. package/dist/plugins/tools/registry.js +0 -58
  597. package/dist/plugins/tools/registry.js.map +0 -1
  598. package/dist/plugins/tools/search/localSearchPlugin.d.ts +0 -3
  599. package/dist/plugins/tools/search/localSearchPlugin.d.ts.map +0 -1
  600. package/dist/plugins/tools/search/localSearchPlugin.js +0 -14
  601. package/dist/plugins/tools/search/localSearchPlugin.js.map +0 -1
  602. package/dist/plugins/tools/skills/skillPlugin.d.ts +0 -3
  603. package/dist/plugins/tools/skills/skillPlugin.d.ts.map +0 -1
  604. package/dist/plugins/tools/skills/skillPlugin.js +0 -9
  605. package/dist/plugins/tools/skills/skillPlugin.js.map +0 -1
  606. package/dist/plugins/tools/taskManagement/taskManagementPlugin.d.ts +0 -3
  607. package/dist/plugins/tools/taskManagement/taskManagementPlugin.d.ts.map +0 -1
  608. package/dist/plugins/tools/taskManagement/taskManagementPlugin.js +0 -12
  609. package/dist/plugins/tools/taskManagement/taskManagementPlugin.js.map +0 -1
  610. package/dist/plugins/tools/testing/testingPlugin.d.ts +0 -3
  611. package/dist/plugins/tools/testing/testingPlugin.d.ts.map +0 -1
  612. package/dist/plugins/tools/testing/testingPlugin.js +0 -12
  613. package/dist/plugins/tools/testing/testingPlugin.js.map +0 -1
  614. package/dist/plugins/tools/validation/validationPlugin.d.ts +0 -3
  615. package/dist/plugins/tools/validation/validationPlugin.d.ts.map +0 -1
  616. package/dist/plugins/tools/validation/validationPlugin.js +0 -14
  617. package/dist/plugins/tools/validation/validationPlugin.js.map +0 -1
  618. package/dist/plugins/tools/web/webPlugin.d.ts +0 -3
  619. package/dist/plugins/tools/web/webPlugin.d.ts.map +0 -1
  620. package/dist/plugins/tools/web/webPlugin.js +0 -12
  621. package/dist/plugins/tools/web/webPlugin.js.map +0 -1
  622. package/dist/providers/anthropicProvider.d.ts +0 -41
  623. package/dist/providers/anthropicProvider.d.ts.map +0 -1
  624. package/dist/providers/anthropicProvider.js +0 -446
  625. package/dist/providers/anthropicProvider.js.map +0 -1
  626. package/dist/providers/googleProvider.d.ts +0 -36
  627. package/dist/providers/googleProvider.d.ts.map +0 -1
  628. package/dist/providers/googleProvider.js +0 -312
  629. package/dist/providers/googleProvider.js.map +0 -1
  630. package/dist/providers/openaiChatCompletionsProvider.d.ts +0 -43
  631. package/dist/providers/openaiChatCompletionsProvider.d.ts.map +0 -1
  632. package/dist/providers/openaiChatCompletionsProvider.js +0 -475
  633. package/dist/providers/openaiChatCompletionsProvider.js.map +0 -1
  634. package/dist/providers/openaiResponsesProvider.d.ts +0 -38
  635. package/dist/providers/openaiResponsesProvider.d.ts.map +0 -1
  636. package/dist/providers/openaiResponsesProvider.js +0 -364
  637. package/dist/providers/openaiResponsesProvider.js.map +0 -1
  638. package/dist/providers/providerFactory.d.ts +0 -18
  639. package/dist/providers/providerFactory.d.ts.map +0 -1
  640. package/dist/providers/providerFactory.js +0 -25
  641. package/dist/providers/providerFactory.js.map +0 -1
  642. package/dist/providers/resilientProvider.d.ts +0 -94
  643. package/dist/providers/resilientProvider.d.ts.map +0 -1
  644. package/dist/providers/resilientProvider.js +0 -370
  645. package/dist/providers/resilientProvider.js.map +0 -1
  646. package/dist/runtime/agentController.d.ts +0 -65
  647. package/dist/runtime/agentController.d.ts.map +0 -1
  648. package/dist/runtime/agentController.js +0 -353
  649. package/dist/runtime/agentController.js.map +0 -1
  650. package/dist/runtime/agentHost.d.ts +0 -61
  651. package/dist/runtime/agentHost.d.ts.map +0 -1
  652. package/dist/runtime/agentHost.js +0 -156
  653. package/dist/runtime/agentHost.js.map +0 -1
  654. package/dist/runtime/agentSession.d.ts +0 -40
  655. package/dist/runtime/agentSession.d.ts.map +0 -1
  656. package/dist/runtime/agentSession.js +0 -205
  657. package/dist/runtime/agentSession.js.map +0 -1
  658. package/dist/runtime/browser.d.ts +0 -7
  659. package/dist/runtime/browser.d.ts.map +0 -1
  660. package/dist/runtime/browser.js +0 -10
  661. package/dist/runtime/browser.js.map +0 -1
  662. package/dist/runtime/cloud.d.ts +0 -7
  663. package/dist/runtime/cloud.d.ts.map +0 -1
  664. package/dist/runtime/cloud.js +0 -10
  665. package/dist/runtime/cloud.js.map +0 -1
  666. package/dist/runtime/node.d.ts +0 -8
  667. package/dist/runtime/node.d.ts.map +0 -1
  668. package/dist/runtime/node.js +0 -11
  669. package/dist/runtime/node.js.map +0 -1
  670. package/dist/runtime/universal.d.ts +0 -21
  671. package/dist/runtime/universal.d.ts.map +0 -1
  672. package/dist/runtime/universal.js +0 -29
  673. package/dist/runtime/universal.js.map +0 -1
  674. package/dist/shell/autoExecutor.d.ts +0 -70
  675. package/dist/shell/autoExecutor.d.ts.map +0 -1
  676. package/dist/shell/autoExecutor.js +0 -288
  677. package/dist/shell/autoExecutor.js.map +0 -1
  678. package/dist/shell/composableMessage.d.ts +0 -183
  679. package/dist/shell/composableMessage.d.ts.map +0 -1
  680. package/dist/shell/composableMessage.js +0 -420
  681. package/dist/shell/composableMessage.js.map +0 -1
  682. package/dist/shell/fileChangeTracker.d.ts +0 -39
  683. package/dist/shell/fileChangeTracker.d.ts.map +0 -1
  684. package/dist/shell/fileChangeTracker.js +0 -64
  685. package/dist/shell/fileChangeTracker.js.map +0 -1
  686. package/dist/shell/keyboardShortcuts.d.ts +0 -53
  687. package/dist/shell/keyboardShortcuts.d.ts.map +0 -1
  688. package/dist/shell/keyboardShortcuts.js +0 -166
  689. package/dist/shell/keyboardShortcuts.js.map +0 -1
  690. package/dist/shell/liveStatus.d.ts +0 -30
  691. package/dist/shell/liveStatus.d.ts.map +0 -1
  692. package/dist/shell/liveStatus.js +0 -102
  693. package/dist/shell/liveStatus.js.map +0 -1
  694. package/dist/shell/shellApp.d.ts +0 -19
  695. package/dist/shell/shellApp.d.ts.map +0 -1
  696. package/dist/shell/shellApp.js +0 -408
  697. package/dist/shell/shellApp.js.map +0 -1
  698. package/dist/shell/systemPrompt.d.ts +0 -3
  699. package/dist/shell/systemPrompt.d.ts.map +0 -1
  700. package/dist/shell/systemPrompt.js +0 -81
  701. package/dist/shell/systemPrompt.js.map +0 -1
  702. package/dist/shell/taskCompletionDetector.d.ts +0 -106
  703. package/dist/shell/taskCompletionDetector.d.ts.map +0 -1
  704. package/dist/shell/taskCompletionDetector.js +0 -402
  705. package/dist/shell/taskCompletionDetector.js.map +0 -1
  706. package/dist/shell/terminalInput.d.ts +0 -617
  707. package/dist/shell/terminalInput.d.ts.map +0 -1
  708. package/dist/shell/terminalInput.js +0 -2633
  709. package/dist/shell/terminalInput.js.map +0 -1
  710. package/dist/shell/terminalInputAdapter.d.ts +0 -263
  711. package/dist/shell/terminalInputAdapter.d.ts.map +0 -1
  712. package/dist/shell/terminalInputAdapter.js +0 -406
  713. package/dist/shell/terminalInputAdapter.js.map +0 -1
  714. package/dist/shell/updateManager.d.ts +0 -3
  715. package/dist/shell/updateManager.d.ts.map +0 -1
  716. package/dist/shell/updateManager.js +0 -120
  717. package/dist/shell/updateManager.js.map +0 -1
  718. package/dist/shell/vimMode.d.ts +0 -66
  719. package/dist/shell/vimMode.d.ts.map +0 -1
  720. package/dist/shell/vimMode.js +0 -434
  721. package/dist/shell/vimMode.js.map +0 -1
  722. package/dist/skills/skillRepository.d.ts +0 -103
  723. package/dist/skills/skillRepository.d.ts.map +0 -1
  724. package/dist/skills/skillRepository.js +0 -237
  725. package/dist/skills/skillRepository.js.map +0 -1
  726. package/dist/skills/types.d.ts +0 -37
  727. package/dist/skills/types.d.ts.map +0 -1
  728. package/dist/skills/types.js +0 -2
  729. package/dist/skills/types.js.map +0 -1
  730. package/dist/subagents/agentConfig.d.ts +0 -27
  731. package/dist/subagents/agentConfig.d.ts.map +0 -1
  732. package/dist/subagents/agentConfig.js +0 -89
  733. package/dist/subagents/agentConfig.js.map +0 -1
  734. package/dist/subagents/agentRegistry.d.ts +0 -33
  735. package/dist/subagents/agentRegistry.d.ts.map +0 -1
  736. package/dist/subagents/agentRegistry.js +0 -162
  737. package/dist/subagents/agentRegistry.js.map +0 -1
  738. package/dist/subagents/parallelAgentManager.d.ts +0 -99
  739. package/dist/subagents/parallelAgentManager.d.ts.map +0 -1
  740. package/dist/subagents/parallelAgentManager.js +0 -248
  741. package/dist/subagents/parallelAgentManager.js.map +0 -1
  742. package/dist/subagents/taskRunner.d.ts +0 -34
  743. package/dist/subagents/taskRunner.d.ts.map +0 -1
  744. package/dist/subagents/taskRunner.js +0 -459
  745. package/dist/subagents/taskRunner.js.map +0 -1
  746. package/dist/tools/advancedTestGenerationTools.d.ts +0 -21
  747. package/dist/tools/advancedTestGenerationTools.d.ts.map +0 -1
  748. package/dist/tools/advancedTestGenerationTools.js +0 -301
  749. package/dist/tools/advancedTestGenerationTools.js.map +0 -1
  750. package/dist/tools/backgroundBashTools.d.ts +0 -21
  751. package/dist/tools/backgroundBashTools.d.ts.map +0 -1
  752. package/dist/tools/backgroundBashTools.js +0 -215
  753. package/dist/tools/backgroundBashTools.js.map +0 -1
  754. package/dist/tools/bashTools.d.ts +0 -8
  755. package/dist/tools/bashTools.d.ts.map +0 -1
  756. package/dist/tools/bashTools.js +0 -251
  757. package/dist/tools/bashTools.js.map +0 -1
  758. package/dist/tools/browserAutomationTools.d.ts +0 -23
  759. package/dist/tools/browserAutomationTools.d.ts.map +0 -1
  760. package/dist/tools/browserAutomationTools.js +0 -916
  761. package/dist/tools/browserAutomationTools.js.map +0 -1
  762. package/dist/tools/buildTools.d.ts +0 -9
  763. package/dist/tools/buildTools.d.ts.map +0 -1
  764. package/dist/tools/buildTools.js +0 -344
  765. package/dist/tools/buildTools.js.map +0 -1
  766. package/dist/tools/cloudTools.d.ts +0 -49
  767. package/dist/tools/cloudTools.d.ts.map +0 -1
  768. package/dist/tools/cloudTools.js +0 -1258
  769. package/dist/tools/cloudTools.js.map +0 -1
  770. package/dist/tools/code-quality-dashboard.d.ts +0 -57
  771. package/dist/tools/code-quality-dashboard.d.ts.map +0 -1
  772. package/dist/tools/code-quality-dashboard.js +0 -218
  773. package/dist/tools/code-quality-dashboard.js.map +0 -1
  774. package/dist/tools/codeAnalysisTools.d.ts +0 -74
  775. package/dist/tools/codeAnalysisTools.d.ts.map +0 -1
  776. package/dist/tools/codeAnalysisTools.js +0 -664
  777. package/dist/tools/codeAnalysisTools.js.map +0 -1
  778. package/dist/tools/codeGenerationTools.d.ts +0 -3
  779. package/dist/tools/codeGenerationTools.d.ts.map +0 -1
  780. package/dist/tools/codeGenerationTools.js +0 -439
  781. package/dist/tools/codeGenerationTools.js.map +0 -1
  782. package/dist/tools/codeQualityTools.d.ts +0 -3
  783. package/dist/tools/codeQualityTools.d.ts.map +0 -1
  784. package/dist/tools/codeQualityTools.js +0 -296
  785. package/dist/tools/codeQualityTools.js.map +0 -1
  786. package/dist/tools/dependencyTools.d.ts +0 -3
  787. package/dist/tools/dependencyTools.d.ts.map +0 -1
  788. package/dist/tools/dependencyTools.js +0 -283
  789. package/dist/tools/dependencyTools.js.map +0 -1
  790. package/dist/tools/devTools.d.ts +0 -10
  791. package/dist/tools/devTools.d.ts.map +0 -1
  792. package/dist/tools/devTools.js +0 -2125
  793. package/dist/tools/devTools.js.map +0 -1
  794. package/dist/tools/diffUtils.d.ts +0 -36
  795. package/dist/tools/diffUtils.d.ts.map +0 -1
  796. package/dist/tools/diffUtils.js +0 -528
  797. package/dist/tools/diffUtils.js.map +0 -1
  798. package/dist/tools/editTools.d.ts +0 -29
  799. package/dist/tools/editTools.d.ts.map +0 -1
  800. package/dist/tools/editTools.js +0 -419
  801. package/dist/tools/editTools.js.map +0 -1
  802. package/dist/tools/emailTools.d.ts +0 -21
  803. package/dist/tools/emailTools.d.ts.map +0 -1
  804. package/dist/tools/emailTools.js +0 -449
  805. package/dist/tools/emailTools.js.map +0 -1
  806. package/dist/tools/enhancedCodeIntelligenceTools.d.ts +0 -27
  807. package/dist/tools/enhancedCodeIntelligenceTools.d.ts.map +0 -1
  808. package/dist/tools/enhancedCodeIntelligenceTools.js +0 -418
  809. package/dist/tools/enhancedCodeIntelligenceTools.js.map +0 -1
  810. package/dist/tools/enhancedDevWorkflowTools.d.ts +0 -15
  811. package/dist/tools/enhancedDevWorkflowTools.d.ts.map +0 -1
  812. package/dist/tools/enhancedDevWorkflowTools.js +0 -303
  813. package/dist/tools/enhancedDevWorkflowTools.js.map +0 -1
  814. package/dist/tools/fileTools.d.ts +0 -3
  815. package/dist/tools/fileTools.d.ts.map +0 -1
  816. package/dist/tools/fileTools.js +0 -334
  817. package/dist/tools/fileTools.js.map +0 -1
  818. package/dist/tools/frontendTestingTools.d.ts +0 -35
  819. package/dist/tools/frontendTestingTools.d.ts.map +0 -1
  820. package/dist/tools/frontendTestingTools.js +0 -1254
  821. package/dist/tools/frontendTestingTools.js.map +0 -1
  822. package/dist/tools/globTools.d.ts +0 -15
  823. package/dist/tools/globTools.d.ts.map +0 -1
  824. package/dist/tools/globTools.js +0 -174
  825. package/dist/tools/globTools.js.map +0 -1
  826. package/dist/tools/grepTools.d.ts +0 -19
  827. package/dist/tools/grepTools.d.ts.map +0 -1
  828. package/dist/tools/grepTools.js +0 -358
  829. package/dist/tools/grepTools.js.map +0 -1
  830. package/dist/tools/interactionTools.d.ts +0 -13
  831. package/dist/tools/interactionTools.d.ts.map +0 -1
  832. package/dist/tools/interactionTools.js +0 -171
  833. package/dist/tools/interactionTools.js.map +0 -1
  834. package/dist/tools/learnTools.d.ts +0 -152
  835. package/dist/tools/learnTools.d.ts.map +0 -1
  836. package/dist/tools/learnTools.js +0 -1942
  837. package/dist/tools/learnTools.js.map +0 -1
  838. package/dist/tools/localExplore.d.ts +0 -225
  839. package/dist/tools/localExplore.d.ts.map +0 -1
  840. package/dist/tools/localExplore.js +0 -1291
  841. package/dist/tools/localExplore.js.map +0 -1
  842. package/dist/tools/notebookEditTools.d.ts +0 -15
  843. package/dist/tools/notebookEditTools.d.ts.map +0 -1
  844. package/dist/tools/notebookEditTools.js +0 -197
  845. package/dist/tools/notebookEditTools.js.map +0 -1
  846. package/dist/tools/planningTools.d.ts +0 -21
  847. package/dist/tools/planningTools.d.ts.map +0 -1
  848. package/dist/tools/planningTools.js +0 -185
  849. package/dist/tools/planningTools.js.map +0 -1
  850. package/dist/tools/refactoringTools.d.ts +0 -3
  851. package/dist/tools/refactoringTools.d.ts.map +0 -1
  852. package/dist/tools/refactoringTools.js +0 -294
  853. package/dist/tools/refactoringTools.js.map +0 -1
  854. package/dist/tools/repoChecksTools.d.ts +0 -3
  855. package/dist/tools/repoChecksTools.d.ts.map +0 -1
  856. package/dist/tools/repoChecksTools.js +0 -161
  857. package/dist/tools/repoChecksTools.js.map +0 -1
  858. package/dist/tools/searchTools.d.ts +0 -3
  859. package/dist/tools/searchTools.d.ts.map +0 -1
  860. package/dist/tools/searchTools.js +0 -207
  861. package/dist/tools/searchTools.js.map +0 -1
  862. package/dist/tools/skillTools.d.ts +0 -8
  863. package/dist/tools/skillTools.d.ts.map +0 -1
  864. package/dist/tools/skillTools.js +0 -178
  865. package/dist/tools/skillTools.js.map +0 -1
  866. package/dist/tools/softwareEngineeringTools.d.ts +0 -7
  867. package/dist/tools/softwareEngineeringTools.d.ts.map +0 -1
  868. package/dist/tools/softwareEngineeringTools.js +0 -338
  869. package/dist/tools/softwareEngineeringTools.js.map +0 -1
  870. package/dist/tools/taskManagementTools.d.ts +0 -10
  871. package/dist/tools/taskManagementTools.d.ts.map +0 -1
  872. package/dist/tools/taskManagementTools.js +0 -157
  873. package/dist/tools/taskManagementTools.js.map +0 -1
  874. package/dist/tools/testingTools.d.ts +0 -3
  875. package/dist/tools/testingTools.d.ts.map +0 -1
  876. package/dist/tools/testingTools.js +0 -233
  877. package/dist/tools/testingTools.js.map +0 -1
  878. package/dist/tools/validationTools.d.ts +0 -7
  879. package/dist/tools/validationTools.d.ts.map +0 -1
  880. package/dist/tools/validationTools.js +0 -344
  881. package/dist/tools/validationTools.js.map +0 -1
  882. package/dist/tools/webTools.d.ts +0 -3
  883. package/dist/tools/webTools.d.ts.map +0 -1
  884. package/dist/tools/webTools.js +0 -502
  885. package/dist/tools/webTools.js.map +0 -1
  886. package/dist/ui/ShellUIAdapter.d.ts +0 -194
  887. package/dist/ui/ShellUIAdapter.d.ts.map +0 -1
  888. package/dist/ui/ShellUIAdapter.js +0 -1069
  889. package/dist/ui/ShellUIAdapter.js.map +0 -1
  890. package/dist/ui/UnifiedUIController.d.ts +0 -70
  891. package/dist/ui/UnifiedUIController.d.ts.map +0 -1
  892. package/dist/ui/UnifiedUIController.js +0 -190
  893. package/dist/ui/UnifiedUIController.js.map +0 -1
  894. package/dist/ui/animation/AnimationScheduler.d.ts +0 -192
  895. package/dist/ui/animation/AnimationScheduler.d.ts.map +0 -1
  896. package/dist/ui/animation/AnimationScheduler.js +0 -432
  897. package/dist/ui/animation/AnimationScheduler.js.map +0 -1
  898. package/dist/ui/codeHighlighter.d.ts +0 -6
  899. package/dist/ui/codeHighlighter.d.ts.map +0 -1
  900. package/dist/ui/codeHighlighter.js +0 -855
  901. package/dist/ui/codeHighlighter.js.map +0 -1
  902. package/dist/ui/compactRenderer.d.ts +0 -139
  903. package/dist/ui/compactRenderer.d.ts.map +0 -1
  904. package/dist/ui/compactRenderer.js +0 -398
  905. package/dist/ui/compactRenderer.js.map +0 -1
  906. package/dist/ui/designSystem.d.ts +0 -26
  907. package/dist/ui/designSystem.d.ts.map +0 -1
  908. package/dist/ui/designSystem.js +0 -122
  909. package/dist/ui/designSystem.js.map +0 -1
  910. package/dist/ui/display.d.ts +0 -324
  911. package/dist/ui/display.d.ts.map +0 -1
  912. package/dist/ui/display.js +0 -1328
  913. package/dist/ui/display.js.map +0 -1
  914. package/dist/ui/errorFormatter.d.ts +0 -54
  915. package/dist/ui/errorFormatter.d.ts.map +0 -1
  916. package/dist/ui/errorFormatter.js +0 -251
  917. package/dist/ui/errorFormatter.js.map +0 -1
  918. package/dist/ui/globalWriteLock.d.ts +0 -38
  919. package/dist/ui/globalWriteLock.d.ts.map +0 -1
  920. package/dist/ui/globalWriteLock.js +0 -54
  921. package/dist/ui/globalWriteLock.js.map +0 -1
  922. package/dist/ui/inPlaceUpdater.d.ts +0 -181
  923. package/dist/ui/inPlaceUpdater.d.ts.map +0 -1
  924. package/dist/ui/inPlaceUpdater.js +0 -515
  925. package/dist/ui/inPlaceUpdater.js.map +0 -1
  926. package/dist/ui/interrupts/InterruptManager.d.ts +0 -142
  927. package/dist/ui/interrupts/InterruptManager.d.ts.map +0 -1
  928. package/dist/ui/interrupts/InterruptManager.js +0 -439
  929. package/dist/ui/interrupts/InterruptManager.js.map +0 -1
  930. package/dist/ui/layout.d.ts +0 -17
  931. package/dist/ui/layout.d.ts.map +0 -1
  932. package/dist/ui/layout.js +0 -140
  933. package/dist/ui/layout.js.map +0 -1
  934. package/dist/ui/orchestration/StatusOrchestrator.d.ts +0 -156
  935. package/dist/ui/orchestration/StatusOrchestrator.d.ts.map +0 -1
  936. package/dist/ui/orchestration/StatusOrchestrator.js +0 -406
  937. package/dist/ui/orchestration/StatusOrchestrator.js.map +0 -1
  938. package/dist/ui/orchestration/UIUpdateCoordinator.d.ts +0 -77
  939. package/dist/ui/orchestration/UIUpdateCoordinator.d.ts.map +0 -1
  940. package/dist/ui/orchestration/UIUpdateCoordinator.js +0 -265
  941. package/dist/ui/orchestration/UIUpdateCoordinator.js.map +0 -1
  942. package/dist/ui/outputMode.d.ts +0 -22
  943. package/dist/ui/outputMode.d.ts.map +0 -1
  944. package/dist/ui/outputMode.js +0 -40
  945. package/dist/ui/outputMode.js.map +0 -1
  946. package/dist/ui/richText.d.ts +0 -6
  947. package/dist/ui/richText.d.ts.map +0 -1
  948. package/dist/ui/richText.js +0 -391
  949. package/dist/ui/richText.js.map +0 -1
  950. package/dist/ui/shortcutsHelp.d.ts +0 -39
  951. package/dist/ui/shortcutsHelp.d.ts.map +0 -1
  952. package/dist/ui/shortcutsHelp.js +0 -152
  953. package/dist/ui/shortcutsHelp.js.map +0 -1
  954. package/dist/ui/streamingFormatter.d.ts +0 -20
  955. package/dist/ui/streamingFormatter.d.ts.map +0 -1
  956. package/dist/ui/streamingFormatter.js +0 -92
  957. package/dist/ui/streamingFormatter.js.map +0 -1
  958. package/dist/ui/telemetry/UITelemetry.d.ts +0 -181
  959. package/dist/ui/telemetry/UITelemetry.d.ts.map +0 -1
  960. package/dist/ui/telemetry/UITelemetry.js +0 -446
  961. package/dist/ui/telemetry/UITelemetry.js.map +0 -1
  962. package/dist/ui/textHighlighter.d.ts +0 -83
  963. package/dist/ui/textHighlighter.d.ts.map +0 -1
  964. package/dist/ui/textHighlighter.js +0 -267
  965. package/dist/ui/textHighlighter.js.map +0 -1
  966. package/dist/ui/theme.d.ts +0 -208
  967. package/dist/ui/theme.d.ts.map +0 -1
  968. package/dist/ui/theme.js +0 -249
  969. package/dist/ui/theme.js.map +0 -1
  970. package/dist/ui/toolDisplay.d.ts +0 -195
  971. package/dist/ui/toolDisplay.d.ts.map +0 -1
  972. package/dist/ui/toolDisplay.js +0 -1527
  973. package/dist/ui/toolDisplay.js.map +0 -1
  974. package/dist/ui/unified/index.d.ts +0 -50
  975. package/dist/ui/unified/index.d.ts.map +0 -1
  976. package/dist/ui/unified/index.js +0 -77
  977. package/dist/ui/unified/index.js.map +0 -1
  978. package/dist/ui/unified/layout.d.ts +0 -12
  979. package/dist/ui/unified/layout.d.ts.map +0 -1
  980. package/dist/ui/unified/layout.js +0 -96
  981. package/dist/ui/unified/layout.js.map +0 -1
  982. package/dist/ui/writeLock.d.ts +0 -65
  983. package/dist/ui/writeLock.d.ts.map +0 -1
  984. package/dist/ui/writeLock.js +0 -114
  985. package/dist/ui/writeLock.js.map +0 -1
  986. package/dist/utils/asyncUtils.d.ts +0 -95
  987. package/dist/utils/asyncUtils.d.ts.map +0 -1
  988. package/dist/utils/asyncUtils.js +0 -286
  989. package/dist/utils/asyncUtils.js.map +0 -1
  990. package/dist/utils/errorUtils.d.ts +0 -16
  991. package/dist/utils/errorUtils.d.ts.map +0 -1
  992. package/dist/utils/errorUtils.js +0 -66
  993. package/dist/utils/errorUtils.js.map +0 -1
  994. package/dist/utils/frontmatter.d.ts +0 -10
  995. package/dist/utils/frontmatter.d.ts.map +0 -1
  996. package/dist/utils/frontmatter.js +0 -78
  997. package/dist/utils/frontmatter.js.map +0 -1
  998. package/dist/utils/planFormatter.d.ts +0 -34
  999. package/dist/utils/planFormatter.d.ts.map +0 -1
  1000. package/dist/utils/planFormatter.js +0 -140
  1001. package/dist/utils/planFormatter.js.map +0 -1
  1002. package/dist/workspace.d.ts +0 -8
  1003. package/dist/workspace.d.ts.map +0 -1
  1004. package/dist/workspace.js +0 -107
  1005. package/dist/workspace.js.map +0 -1
  1006. package/dist/workspace.validator.d.ts +0 -49
  1007. package/dist/workspace.validator.d.ts.map +0 -1
  1008. package/dist/workspace.validator.js +0 -214
  1009. 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