erosolar-cli 1.7.269 → 1.7.270

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 (323) hide show
  1. package/README.md +24 -148
  2. package/dist/bin/erosolar.js +1 -0
  3. package/dist/bin/erosolar.js.map +1 -1
  4. package/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
  5. package/dist/capabilities/agentSpawningCapability.js +56 -31
  6. package/dist/capabilities/agentSpawningCapability.js.map +1 -1
  7. package/dist/contracts/agent-schemas.json +0 -15
  8. package/dist/contracts/tools.schema.json +0 -9
  9. package/dist/core/agent.d.ts +2 -2
  10. package/dist/core/agent.d.ts.map +1 -1
  11. package/dist/core/agent.js.map +1 -1
  12. package/dist/core/customCommands.d.ts +1 -0
  13. package/dist/core/customCommands.d.ts.map +1 -1
  14. package/dist/core/customCommands.js +3 -0
  15. package/dist/core/customCommands.js.map +1 -1
  16. package/dist/core/hooks.d.ts +113 -0
  17. package/dist/core/hooks.d.ts.map +1 -0
  18. package/dist/core/hooks.js +267 -0
  19. package/dist/core/hooks.js.map +1 -0
  20. package/dist/core/metricsTracker.d.ts +122 -0
  21. package/dist/core/metricsTracker.d.ts.map +1 -0
  22. package/dist/{alpha-zero → core}/metricsTracker.js +2 -5
  23. package/dist/core/metricsTracker.js.map +1 -0
  24. package/dist/core/securityAssessment.d.ts +91 -0
  25. package/dist/core/securityAssessment.d.ts.map +1 -0
  26. package/dist/core/securityAssessment.js +580 -0
  27. package/dist/core/securityAssessment.js.map +1 -0
  28. package/dist/core/toolPreconditions.d.ts.map +1 -1
  29. package/dist/core/toolPreconditions.js +0 -14
  30. package/dist/core/toolPreconditions.js.map +1 -1
  31. package/dist/core/toolRuntime.d.ts +22 -1
  32. package/dist/core/toolRuntime.d.ts.map +1 -1
  33. package/dist/core/toolRuntime.js +0 -5
  34. package/dist/core/toolRuntime.js.map +1 -1
  35. package/dist/core/toolValidation.d.ts.map +1 -1
  36. package/dist/core/toolValidation.js +14 -3
  37. package/dist/core/toolValidation.js.map +1 -1
  38. package/dist/core/validationRunner.d.ts +1 -3
  39. package/dist/core/validationRunner.d.ts.map +1 -1
  40. package/dist/core/validationRunner.js.map +1 -1
  41. package/dist/core/verification.d.ts +137 -0
  42. package/dist/core/verification.d.ts.map +1 -0
  43. package/dist/core/verification.js +323 -0
  44. package/dist/core/verification.js.map +1 -0
  45. package/dist/headless/headlessApp.d.ts.map +1 -1
  46. package/dist/headless/headlessApp.js +21 -0
  47. package/dist/headless/headlessApp.js.map +1 -1
  48. package/dist/mcp/sseClient.d.ts.map +1 -1
  49. package/dist/mcp/sseClient.js +9 -18
  50. package/dist/mcp/sseClient.js.map +1 -1
  51. package/dist/plugins/tools/build/buildPlugin.d.ts +0 -6
  52. package/dist/plugins/tools/build/buildPlugin.d.ts.map +1 -1
  53. package/dist/plugins/tools/build/buildPlugin.js +4 -10
  54. package/dist/plugins/tools/build/buildPlugin.js.map +1 -1
  55. package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
  56. package/dist/plugins/tools/nodeDefaults.js +0 -2
  57. package/dist/plugins/tools/nodeDefaults.js.map +1 -1
  58. package/dist/runtime/agentSession.d.ts +2 -2
  59. package/dist/runtime/agentSession.d.ts.map +1 -1
  60. package/dist/runtime/agentSession.js +2 -2
  61. package/dist/runtime/agentSession.js.map +1 -1
  62. package/dist/shell/interactiveShell.d.ts +11 -7
  63. package/dist/shell/interactiveShell.d.ts.map +1 -1
  64. package/dist/shell/interactiveShell.js +195 -157
  65. package/dist/shell/interactiveShell.js.map +1 -1
  66. package/dist/shell/shellApp.d.ts +2 -0
  67. package/dist/shell/shellApp.d.ts.map +1 -1
  68. package/dist/shell/shellApp.js +36 -1
  69. package/dist/shell/shellApp.js.map +1 -1
  70. package/dist/shell/systemPrompt.d.ts.map +1 -1
  71. package/dist/shell/systemPrompt.js +1 -4
  72. package/dist/shell/systemPrompt.js.map +1 -1
  73. package/dist/shell/terminalInput.d.ts +76 -158
  74. package/dist/shell/terminalInput.d.ts.map +1 -1
  75. package/dist/shell/terminalInput.js +476 -803
  76. package/dist/shell/terminalInput.js.map +1 -1
  77. package/dist/shell/terminalInputAdapter.d.ts +28 -25
  78. package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
  79. package/dist/shell/terminalInputAdapter.js +26 -36
  80. package/dist/shell/terminalInputAdapter.js.map +1 -1
  81. package/dist/subagents/agentConfig.d.ts +27 -0
  82. package/dist/subagents/agentConfig.d.ts.map +1 -0
  83. package/dist/subagents/agentConfig.js +89 -0
  84. package/dist/subagents/agentConfig.js.map +1 -0
  85. package/dist/subagents/agentRegistry.d.ts +33 -0
  86. package/dist/subagents/agentRegistry.d.ts.map +1 -0
  87. package/dist/subagents/agentRegistry.js +162 -0
  88. package/dist/subagents/agentRegistry.js.map +1 -0
  89. package/dist/subagents/taskRunner.d.ts +7 -1
  90. package/dist/subagents/taskRunner.d.ts.map +1 -1
  91. package/dist/subagents/taskRunner.js +180 -47
  92. package/dist/subagents/taskRunner.js.map +1 -1
  93. package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
  94. package/dist/ui/ShellUIAdapter.js +13 -12
  95. package/dist/ui/ShellUIAdapter.js.map +1 -1
  96. package/dist/ui/display.d.ts +23 -0
  97. package/dist/ui/display.d.ts.map +1 -1
  98. package/dist/ui/display.js +137 -33
  99. package/dist/ui/display.js.map +1 -1
  100. package/dist/ui/theme.d.ts.map +1 -1
  101. package/dist/ui/theme.js +6 -8
  102. package/dist/ui/theme.js.map +1 -1
  103. package/dist/ui/toolDisplay.d.ts +0 -158
  104. package/dist/ui/toolDisplay.d.ts.map +1 -1
  105. package/dist/ui/toolDisplay.js +0 -348
  106. package/dist/ui/toolDisplay.js.map +1 -1
  107. package/dist/ui/unified/layout.d.ts +1 -0
  108. package/dist/ui/unified/layout.d.ts.map +1 -1
  109. package/dist/ui/unified/layout.js +15 -25
  110. package/dist/ui/unified/layout.js.map +1 -1
  111. package/dist/utils/frontmatter.d.ts +10 -0
  112. package/dist/utils/frontmatter.d.ts.map +1 -0
  113. package/dist/utils/frontmatter.js +78 -0
  114. package/dist/utils/frontmatter.js.map +1 -0
  115. package/package.json +1 -1
  116. package/dist/alpha-zero/agentWrapper.d.ts +0 -84
  117. package/dist/alpha-zero/agentWrapper.d.ts.map +0 -1
  118. package/dist/alpha-zero/agentWrapper.js +0 -171
  119. package/dist/alpha-zero/agentWrapper.js.map +0 -1
  120. package/dist/alpha-zero/codeEvaluator.d.ts +0 -25
  121. package/dist/alpha-zero/codeEvaluator.d.ts.map +0 -1
  122. package/dist/alpha-zero/codeEvaluator.js +0 -273
  123. package/dist/alpha-zero/codeEvaluator.js.map +0 -1
  124. package/dist/alpha-zero/competitiveRunner.d.ts +0 -66
  125. package/dist/alpha-zero/competitiveRunner.d.ts.map +0 -1
  126. package/dist/alpha-zero/competitiveRunner.js +0 -224
  127. package/dist/alpha-zero/competitiveRunner.js.map +0 -1
  128. package/dist/alpha-zero/index.d.ts +0 -67
  129. package/dist/alpha-zero/index.d.ts.map +0 -1
  130. package/dist/alpha-zero/index.js +0 -99
  131. package/dist/alpha-zero/index.js.map +0 -1
  132. package/dist/alpha-zero/introspection.d.ts +0 -128
  133. package/dist/alpha-zero/introspection.d.ts.map +0 -1
  134. package/dist/alpha-zero/introspection.js +0 -300
  135. package/dist/alpha-zero/introspection.js.map +0 -1
  136. package/dist/alpha-zero/metricsTracker.d.ts +0 -71
  137. package/dist/alpha-zero/metricsTracker.d.ts.map +0 -1
  138. package/dist/alpha-zero/metricsTracker.js.map +0 -1
  139. package/dist/alpha-zero/security/core.d.ts +0 -125
  140. package/dist/alpha-zero/security/core.d.ts.map +0 -1
  141. package/dist/alpha-zero/security/core.js +0 -271
  142. package/dist/alpha-zero/security/core.js.map +0 -1
  143. package/dist/alpha-zero/security/google.d.ts +0 -125
  144. package/dist/alpha-zero/security/google.d.ts.map +0 -1
  145. package/dist/alpha-zero/security/google.js +0 -311
  146. package/dist/alpha-zero/security/google.js.map +0 -1
  147. package/dist/alpha-zero/security/googleLoader.d.ts +0 -17
  148. package/dist/alpha-zero/security/googleLoader.d.ts.map +0 -1
  149. package/dist/alpha-zero/security/googleLoader.js +0 -41
  150. package/dist/alpha-zero/security/googleLoader.js.map +0 -1
  151. package/dist/alpha-zero/security/index.d.ts +0 -29
  152. package/dist/alpha-zero/security/index.d.ts.map +0 -1
  153. package/dist/alpha-zero/security/index.js +0 -32
  154. package/dist/alpha-zero/security/index.js.map +0 -1
  155. package/dist/alpha-zero/security/simulation.d.ts +0 -124
  156. package/dist/alpha-zero/security/simulation.d.ts.map +0 -1
  157. package/dist/alpha-zero/security/simulation.js +0 -277
  158. package/dist/alpha-zero/security/simulation.js.map +0 -1
  159. package/dist/alpha-zero/selfModification.d.ts +0 -109
  160. package/dist/alpha-zero/selfModification.d.ts.map +0 -1
  161. package/dist/alpha-zero/selfModification.js +0 -233
  162. package/dist/alpha-zero/selfModification.js.map +0 -1
  163. package/dist/alpha-zero/types.d.ts +0 -170
  164. package/dist/alpha-zero/types.d.ts.map +0 -1
  165. package/dist/alpha-zero/types.js +0 -31
  166. package/dist/alpha-zero/types.js.map +0 -1
  167. package/dist/capabilities/securityTestingCapability.d.ts +0 -13
  168. package/dist/capabilities/securityTestingCapability.d.ts.map +0 -1
  169. package/dist/capabilities/securityTestingCapability.js +0 -25
  170. package/dist/capabilities/securityTestingCapability.js.map +0 -1
  171. package/dist/core/aiFlowOptimizer.d.ts +0 -26
  172. package/dist/core/aiFlowOptimizer.d.ts.map +0 -1
  173. package/dist/core/aiFlowOptimizer.js +0 -31
  174. package/dist/core/aiFlowOptimizer.js.map +0 -1
  175. package/dist/core/aiOptimizationEngine.d.ts +0 -158
  176. package/dist/core/aiOptimizationEngine.d.ts.map +0 -1
  177. package/dist/core/aiOptimizationEngine.js +0 -428
  178. package/dist/core/aiOptimizationEngine.js.map +0 -1
  179. package/dist/core/aiOptimizationIntegration.d.ts +0 -93
  180. package/dist/core/aiOptimizationIntegration.d.ts.map +0 -1
  181. package/dist/core/aiOptimizationIntegration.js +0 -250
  182. package/dist/core/aiOptimizationIntegration.js.map +0 -1
  183. package/dist/core/enhancedErrorRecovery.d.ts +0 -100
  184. package/dist/core/enhancedErrorRecovery.d.ts.map +0 -1
  185. package/dist/core/enhancedErrorRecovery.js +0 -345
  186. package/dist/core/enhancedErrorRecovery.js.map +0 -1
  187. package/dist/core/hooksSystem.d.ts +0 -65
  188. package/dist/core/hooksSystem.d.ts.map +0 -1
  189. package/dist/core/hooksSystem.js +0 -273
  190. package/dist/core/hooksSystem.js.map +0 -1
  191. package/dist/core/memorySystem.d.ts +0 -48
  192. package/dist/core/memorySystem.d.ts.map +0 -1
  193. package/dist/core/memorySystem.js +0 -271
  194. package/dist/core/memorySystem.js.map +0 -1
  195. package/dist/core/unified/errors.d.ts +0 -189
  196. package/dist/core/unified/errors.d.ts.map +0 -1
  197. package/dist/core/unified/errors.js +0 -497
  198. package/dist/core/unified/errors.js.map +0 -1
  199. package/dist/core/unified/index.d.ts +0 -19
  200. package/dist/core/unified/index.d.ts.map +0 -1
  201. package/dist/core/unified/index.js +0 -68
  202. package/dist/core/unified/index.js.map +0 -1
  203. package/dist/core/unified/schema.d.ts +0 -101
  204. package/dist/core/unified/schema.d.ts.map +0 -1
  205. package/dist/core/unified/schema.js +0 -350
  206. package/dist/core/unified/schema.js.map +0 -1
  207. package/dist/core/unified/toolRuntime.d.ts +0 -179
  208. package/dist/core/unified/toolRuntime.d.ts.map +0 -1
  209. package/dist/core/unified/toolRuntime.js +0 -517
  210. package/dist/core/unified/toolRuntime.js.map +0 -1
  211. package/dist/core/unified/tools.d.ts +0 -127
  212. package/dist/core/unified/tools.d.ts.map +0 -1
  213. package/dist/core/unified/tools.js +0 -1333
  214. package/dist/core/unified/tools.js.map +0 -1
  215. package/dist/core/unified/types.d.ts +0 -352
  216. package/dist/core/unified/types.d.ts.map +0 -1
  217. package/dist/core/unified/types.js +0 -12
  218. package/dist/core/unified/types.js.map +0 -1
  219. package/dist/core/unified/version.d.ts +0 -209
  220. package/dist/core/unified/version.d.ts.map +0 -1
  221. package/dist/core/unified/version.js +0 -454
  222. package/dist/core/unified/version.js.map +0 -1
  223. package/dist/plugins/tools/security/securityPlugin.d.ts +0 -3
  224. package/dist/plugins/tools/security/securityPlugin.d.ts.map +0 -1
  225. package/dist/plugins/tools/security/securityPlugin.js +0 -12
  226. package/dist/plugins/tools/security/securityPlugin.js.map +0 -1
  227. package/dist/security/active-stack-security.d.ts +0 -112
  228. package/dist/security/active-stack-security.d.ts.map +0 -1
  229. package/dist/security/active-stack-security.js +0 -296
  230. package/dist/security/active-stack-security.js.map +0 -1
  231. package/dist/security/advanced-persistence-research.d.ts +0 -92
  232. package/dist/security/advanced-persistence-research.d.ts.map +0 -1
  233. package/dist/security/advanced-persistence-research.js +0 -195
  234. package/dist/security/advanced-persistence-research.js.map +0 -1
  235. package/dist/security/advanced-targeting.d.ts +0 -119
  236. package/dist/security/advanced-targeting.d.ts.map +0 -1
  237. package/dist/security/advanced-targeting.js +0 -233
  238. package/dist/security/advanced-targeting.js.map +0 -1
  239. package/dist/security/assessment/vulnerabilityAssessment.d.ts +0 -104
  240. package/dist/security/assessment/vulnerabilityAssessment.d.ts.map +0 -1
  241. package/dist/security/assessment/vulnerabilityAssessment.js +0 -315
  242. package/dist/security/assessment/vulnerabilityAssessment.js.map +0 -1
  243. package/dist/security/authorization/securityAuthorization.d.ts +0 -88
  244. package/dist/security/authorization/securityAuthorization.d.ts.map +0 -1
  245. package/dist/security/authorization/securityAuthorization.js +0 -172
  246. package/dist/security/authorization/securityAuthorization.js.map +0 -1
  247. package/dist/security/comprehensive-targeting.d.ts +0 -85
  248. package/dist/security/comprehensive-targeting.d.ts.map +0 -1
  249. package/dist/security/comprehensive-targeting.js +0 -438
  250. package/dist/security/comprehensive-targeting.js.map +0 -1
  251. package/dist/security/global-security-integration.d.ts +0 -91
  252. package/dist/security/global-security-integration.d.ts.map +0 -1
  253. package/dist/security/global-security-integration.js +0 -218
  254. package/dist/security/global-security-integration.js.map +0 -1
  255. package/dist/security/index.d.ts +0 -38
  256. package/dist/security/index.d.ts.map +0 -1
  257. package/dist/security/index.js +0 -47
  258. package/dist/security/index.js.map +0 -1
  259. package/dist/security/persistence-analyzer.d.ts +0 -56
  260. package/dist/security/persistence-analyzer.d.ts.map +0 -1
  261. package/dist/security/persistence-analyzer.js +0 -187
  262. package/dist/security/persistence-analyzer.js.map +0 -1
  263. package/dist/security/persistence-cli.d.ts +0 -36
  264. package/dist/security/persistence-cli.d.ts.map +0 -1
  265. package/dist/security/persistence-cli.js +0 -160
  266. package/dist/security/persistence-cli.js.map +0 -1
  267. package/dist/security/persistence-research.d.ts +0 -92
  268. package/dist/security/persistence-research.d.ts.map +0 -1
  269. package/dist/security/persistence-research.js +0 -364
  270. package/dist/security/persistence-research.js.map +0 -1
  271. package/dist/security/research/persistenceResearch.d.ts +0 -97
  272. package/dist/security/research/persistenceResearch.d.ts.map +0 -1
  273. package/dist/security/research/persistenceResearch.js +0 -282
  274. package/dist/security/research/persistenceResearch.js.map +0 -1
  275. package/dist/security/security-integration.d.ts +0 -74
  276. package/dist/security/security-integration.d.ts.map +0 -1
  277. package/dist/security/security-integration.js +0 -137
  278. package/dist/security/security-integration.js.map +0 -1
  279. package/dist/security/security-testing-framework.d.ts +0 -112
  280. package/dist/security/security-testing-framework.d.ts.map +0 -1
  281. package/dist/security/security-testing-framework.js +0 -364
  282. package/dist/security/security-testing-framework.js.map +0 -1
  283. package/dist/security/simulation/attackSimulation.d.ts +0 -93
  284. package/dist/security/simulation/attackSimulation.d.ts.map +0 -1
  285. package/dist/security/simulation/attackSimulation.js +0 -341
  286. package/dist/security/simulation/attackSimulation.js.map +0 -1
  287. package/dist/security/strategic-operations.d.ts +0 -100
  288. package/dist/security/strategic-operations.d.ts.map +0 -1
  289. package/dist/security/strategic-operations.js +0 -276
  290. package/dist/security/strategic-operations.js.map +0 -1
  291. package/dist/security/tool-security-wrapper.d.ts +0 -58
  292. package/dist/security/tool-security-wrapper.d.ts.map +0 -1
  293. package/dist/security/tool-security-wrapper.js +0 -156
  294. package/dist/security/tool-security-wrapper.js.map +0 -1
  295. package/dist/shell/claudeCodeStreamHandler.d.ts +0 -145
  296. package/dist/shell/claudeCodeStreamHandler.d.ts.map +0 -1
  297. package/dist/shell/claudeCodeStreamHandler.js +0 -322
  298. package/dist/shell/claudeCodeStreamHandler.js.map +0 -1
  299. package/dist/shell/inputQueueManager.d.ts +0 -144
  300. package/dist/shell/inputQueueManager.d.ts.map +0 -1
  301. package/dist/shell/inputQueueManager.js +0 -290
  302. package/dist/shell/inputQueueManager.js.map +0 -1
  303. package/dist/shell/metricsTracker.d.ts +0 -60
  304. package/dist/shell/metricsTracker.d.ts.map +0 -1
  305. package/dist/shell/metricsTracker.js +0 -119
  306. package/dist/shell/metricsTracker.js.map +0 -1
  307. package/dist/shell/streamingOutputManager.d.ts +0 -115
  308. package/dist/shell/streamingOutputManager.d.ts.map +0 -1
  309. package/dist/shell/streamingOutputManager.js +0 -225
  310. package/dist/shell/streamingOutputManager.js.map +0 -1
  311. package/dist/tools/securityTools.d.ts +0 -22
  312. package/dist/tools/securityTools.d.ts.map +0 -1
  313. package/dist/tools/securityTools.js +0 -448
  314. package/dist/tools/securityTools.js.map +0 -1
  315. package/dist/ui/persistentPrompt.d.ts +0 -50
  316. package/dist/ui/persistentPrompt.d.ts.map +0 -1
  317. package/dist/ui/persistentPrompt.js +0 -92
  318. package/dist/ui/persistentPrompt.js.map +0 -1
  319. package/dist/ui/terminalUISchema.d.ts +0 -195
  320. package/dist/ui/terminalUISchema.d.ts.map +0 -1
  321. package/dist/ui/terminalUISchema.js +0 -113
  322. package/dist/ui/terminalUISchema.js.map +0 -1
  323. package/scripts/deploy-security-capabilities.js +0 -178
@@ -2,7 +2,7 @@ import { stdin as input, stdout as output, exit } from 'node:process';
2
2
  import { exec } from 'node:child_process';
3
3
  import { promisify } from 'node:util';
4
4
  import { display } from '../ui/display.js';
5
- import { theme, formatUserPrompt } from '../ui/theme.js';
5
+ import { theme } from '../ui/theme.js';
6
6
  import { getContextWindowTokens } from '../core/contextWindow.js';
7
7
  import { ensureSecretForProvider, getSecretDefinitionForProvider, getSecretValue, listSecretDefinitions, maskSecret, setSecretValue, } from '../core/secretStore.js';
8
8
  import { saveActiveProfilePreference, saveModelPreference, loadToolSettings, saveToolSettings, clearToolSettings, clearActiveProfilePreference, loadSessionPreferences, saveSessionPreferences, } from '../core/preferences.js';
@@ -19,9 +19,8 @@ import { SkillRepository } from '../skills/skillRepository.js';
19
19
  import { createSkillTools } from '../tools/skillTools.js';
20
20
  import { FileChangeTracker } from './fileChangeTracker.js';
21
21
  import { formatShortcutsHelp } from '../ui/shortcutsHelp.js';
22
- import { MetricsTracker } from './metricsTracker.js';
22
+ import { MetricsTracker } from '../core/metricsTracker.js';
23
23
  import { listAvailablePlugins } from '../plugins/index.js';
24
- import { loadMemory, listMemoryPaths, getDefaultProjectMemoryPath, getUserMemoryEditPath, } from '../core/memorySystem.js';
25
24
  import { TerminalInputAdapter } from './terminalInputAdapter.js';
26
25
  import { isUpdateInProgress } from './updateManager.js';
27
26
  import { writeLock } from '../ui/writeLock.js';
@@ -35,6 +34,7 @@ const DROPDOWN_COLORS = [
35
34
  theme.success,
36
35
  theme.warning,
37
36
  ];
37
+ const STREAMING_SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];
38
38
  // Load MODEL_PRESETS from centralized schema
39
39
  const MODEL_PRESETS = getModels().map((model) => ({
40
40
  id: model.id,
@@ -49,11 +49,13 @@ const MODEL_PRESETS = getModels().map((model) => ({
49
49
  const BASE_SLASH_COMMANDS = getSlashCommands().map((cmd) => ({
50
50
  command: cmd.command,
51
51
  description: cmd.description,
52
+ category: cmd.category,
52
53
  }));
53
54
  // Load PROVIDER_LABELS from centralized schema
54
55
  const PROVIDER_LABELS = Object.fromEntries(getProviders().map((provider) => [provider.id, provider.label]));
55
56
  // Allow enough time for paste detection to kick in before flushing buffered lines
56
57
  const CONTEXT_USAGE_THRESHOLD = 0.9;
58
+ const CONTEXT_AUTOCOMPACT_PERCENT = Math.round(CONTEXT_USAGE_THRESHOLD * 100);
57
59
  const CONTEXT_RECENT_MESSAGE_COUNT = 12;
58
60
  const CONTEXT_CLEANUP_CHARS_PER_CHUNK = 6000;
59
61
  const CONTEXT_CLEANUP_MAX_OUTPUT_TOKENS = 800;
@@ -94,11 +96,12 @@ export class InteractiveShell {
94
96
  uiAdapter;
95
97
  uiUpdates;
96
98
  _fileChangeTracker = new FileChangeTracker(); // Reserved for future file tracking features
97
- sessionMetrics; // Session performance tracking
99
+ alphaZeroMetrics; // Alpha Zero 2 performance tracking
98
100
  statusSubscription = null;
99
101
  followUpQueue = [];
100
102
  isDrainingQueue = false;
101
103
  activeContextWindowTokens = null;
104
+ latestTokenUsage = { used: null, limit: null };
102
105
  sessionPreferences;
103
106
  autosaveEnabled;
104
107
  autoContinueEnabled;
@@ -129,6 +132,7 @@ export class InteractiveShell {
129
132
  statusLineState = null;
130
133
  statusMessageOverride = null;
131
134
  promptRefreshTimer = null;
135
+ launchPaletteShown = false;
132
136
  constructor(config) {
133
137
  this.profile = config.profile;
134
138
  this.profileLabel = config.profileLabel;
@@ -162,6 +166,7 @@ export class InteractiveShell {
162
166
  this.slashCommands.push({
163
167
  command: '/agents',
164
168
  description: 'Select the default agent profile (applies on next launch)',
169
+ category: 'configuration',
165
170
  });
166
171
  }
167
172
  this.customCommands = loadCustomSlashCommands();
@@ -170,18 +175,21 @@ export class InteractiveShell {
170
175
  this.slashCommands.push({
171
176
  command: custom.command,
172
177
  description: `${custom.description} (custom)`,
178
+ category: custom.category ?? 'other',
173
179
  });
174
180
  }
175
181
  if (!this.slashCommands.some((cmd) => cmd.command === '/exit')) {
176
182
  this.slashCommands.push({
177
183
  command: '/exit',
178
184
  description: 'Quit the CLI immediately',
185
+ category: 'other',
179
186
  });
180
187
  }
181
188
  // Add /plugins command
182
189
  this.slashCommands.push({
183
190
  command: '/plugins',
184
191
  description: 'Show available and loaded plugins',
192
+ category: 'configuration',
185
193
  });
186
194
  this.statusTracker = config.statusTracker;
187
195
  this.ui = config.ui;
@@ -216,13 +224,13 @@ export class InteractiveShell {
216
224
  });
217
225
  // Register output interceptor for cursor positioning during streaming
218
226
  this.terminalInput.registerOutputInterceptor(display);
219
- // Use flow mode: input renders inline after content for a unified layout
220
- // This eliminates the blank space between banner and input area
221
- this.terminalInput.setFlowMode(true);
222
- // Set content end row so input renders right after startup content
223
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
227
+ // Advance content cursor past the banner so streaming content appears below it
228
+ const bannerHeight = display.getBannerHeight();
229
+ if (bannerHeight > 0) {
230
+ this.terminalInput.advanceContentRow(bannerHeight);
231
+ }
224
232
  // Initialize Alpha Zero 2 metrics tracking
225
- this.sessionMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
233
+ this.alphaZeroMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
226
234
  this.setupStatusTracking();
227
235
  this.refreshContextGauge();
228
236
  this.terminalInput.start();
@@ -278,9 +286,15 @@ export class InteractiveShell {
278
286
  await this.processInputBlock(initialPrompt);
279
287
  return;
280
288
  }
289
+ this.showLaunchCommandPalette();
281
290
  // Ensure the terminal input is visible
282
291
  this.terminalInput.render();
283
292
  }
293
+ showLaunchCommandPalette() {
294
+ // Disabled: Quick commands palette takes up too much space
295
+ // Users can type /help to see available commands
296
+ this.launchPaletteShown = true;
297
+ }
284
298
  /**
285
299
  * TerminalInputAdapter submit handler
286
300
  */
@@ -294,9 +308,8 @@ export class InteractiveShell {
294
308
  this.handleInputChange('');
295
309
  return;
296
310
  }
297
- // Enter streaming mode BEFORE logging prompt - this positions cursor correctly
298
- // so content appears right after the banner, not at bottom with blank space above
299
- this.terminalInput.setStreaming(true);
311
+ // DON'T clear the input here - keep it visible while streaming.
312
+ // The input will be cleared after streaming completes in the finally block.
300
313
  this.logUserPrompt(approved);
301
314
  void this.processInputBlock(approved).catch((err) => {
302
315
  display.showError(err instanceof Error ? err.message : String(err), err);
@@ -498,10 +511,9 @@ export class InteractiveShell {
498
511
  // Dispose unified UI adapter
499
512
  this.uiAdapter.dispose();
500
513
  display.newLine();
501
- console.log(theme.gradient.warm('━'.repeat(50)));
502
- console.log(` ${theme.gradient.cool('Goodbye!')} ${theme.ui.muted('·')} ${theme.info('support@ero.solar')}`);
503
- console.log(` ${theme.ui.muted('Read:')} ${theme.accent('anthropic.com/news/disrupting-AI-espionage')}`);
504
- console.log(theme.gradient.warm('━'.repeat(50)));
514
+ console.log(theme.ui.muted('━'.repeat(44)));
515
+ console.log(theme.ui.muted(' Goodbye! · support@ero.solar'));
516
+ console.log(theme.ui.muted(''.repeat(44)));
505
517
  exit(0);
506
518
  }
507
519
  /**
@@ -671,13 +683,14 @@ export class InteractiveShell {
671
683
  });
672
684
  }
673
685
  setProcessingStatus(detail) {
686
+ this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
674
687
  this.statusTracker.setBase('Working on your request', {
675
688
  detail: this.describeStatusDetail(detail),
676
689
  tone: 'info',
677
690
  });
678
691
  }
679
692
  describeStatusDetail(detail) {
680
- const parts = [detail?.trim() || this.describeModelDetail()];
693
+ const parts = detail?.trim() ? [detail.trim()] : [];
681
694
  const queued = this.followUpQueue.length;
682
695
  if (queued > 0) {
683
696
  parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
@@ -690,12 +703,18 @@ export class InteractiveShell {
690
703
  }
691
704
  refreshContextGauge() {
692
705
  const tokens = getContextWindowTokens(this.sessionState.model);
693
- this.activeContextWindowTokens =
694
- typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
706
+ const normalizedTokens = typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
707
+ this.activeContextWindowTokens = normalizedTokens;
708
+ if (normalizedTokens !== null) {
709
+ this.latestTokenUsage = {
710
+ used: this.latestTokenUsage.used,
711
+ limit: normalizedTokens,
712
+ };
713
+ }
695
714
  }
696
715
  updateContextUsage(percentage) {
697
716
  this.uiAdapter.updateContextUsage(percentage);
698
- this.terminalInput.setContextUsage(percentage);
717
+ this.terminalInput.setContextUsage(percentage, CONTEXT_AUTOCOMPACT_PERCENT);
699
718
  }
700
719
  refreshControlBar() {
701
720
  this.terminalInput.setModeToggles({
@@ -703,9 +722,9 @@ export class InteractiveShell {
703
722
  autoContinueEnabled: this.autoContinueEnabled,
704
723
  verificationHotkey: 'alt+v',
705
724
  autoContinueHotkey: 'alt+c',
725
+ thinkingModeLabel: this.thinkingMode,
726
+ thinkingHotkey: '/thinking',
706
727
  });
707
- // Update persistent model info display
708
- this.terminalInput.setModelInfo(this.describeModelDetail());
709
728
  this.refreshStatusLine();
710
729
  this.terminalInput.render();
711
730
  }
@@ -736,6 +755,25 @@ export class InteractiveShell {
736
755
  // Set main status (tool execution, etc.) - shown when not overridden
737
756
  const statusText = this.formatStatusLine(this.statusLineState);
738
757
  this.terminalInput.setStatusMessage(statusText);
758
+ // Surface meta header (elapsed + context usage) above the divider
759
+ const elapsedSeconds = this.statusLineState
760
+ ? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
761
+ : null;
762
+ const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
763
+ const tokensUsed = this.latestTokenUsage.used;
764
+ const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
765
+ this.terminalInput.setMetaStatus({
766
+ elapsedSeconds,
767
+ tokensUsed,
768
+ tokenLimit,
769
+ thinkingMs,
770
+ thinkingHasContent: display.isSpinnerActive(),
771
+ });
772
+ // Keep model/provider visible in the controls bar
773
+ this.terminalInput.setModelContext({
774
+ model: this.sessionState.model,
775
+ provider: this.providerLabel(this.sessionState.provider),
776
+ });
739
777
  if (forceRender) {
740
778
  this.terminalInput.render();
741
779
  }
@@ -795,13 +833,11 @@ export class InteractiveShell {
795
833
  this.terminalInput.render();
796
834
  }
797
835
  /**
798
- * Log the user's prompt as a visible message in the conversation.
799
- * This creates a persistent log entry that remains visible during and after streaming.
836
+ * Keep submissions out of the transcript to preserve the persistent input area.
837
+ * The chat box already holds the user's prompt, so avoid echoing it into output.
800
838
  */
801
- logUserPrompt(text) {
802
- // Display the user's prompt with the standard prefix
803
- const prefix = formatUserPrompt();
804
- display.stream(`\n${prefix}${text}\n\n`);
839
+ logUserPrompt(_text) {
840
+ // Intentionally no-op to keep the input area persistent and uncluttered.
805
841
  }
806
842
  requestPromptRefresh(force = false) {
807
843
  if (force) {
@@ -829,9 +865,29 @@ export class InteractiveShell {
829
865
  this.uiUpdates.setMode('streaming');
830
866
  this.streamingHeartbeatStart = Date.now();
831
867
  this.streamingHeartbeatFrame = 0;
832
- // Note: We don't start a heartbeat during streaming anymore
833
- // because the UI shouldn't be rendering during streaming.
834
- // The streaming status is shown in the streaming header instead.
868
+ const initialFrame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
869
+ this.streamingStatusLabel = this.buildStreamingStatus(`${initialFrame} ${label}`, 0);
870
+ display.updateStreamingStatus(this.streamingStatusLabel);
871
+ this.refreshStatusLine(true);
872
+ // Periodically refresh the pinned input/status region while streaming so
873
+ // elapsed time remains visible without interrupting the scroll region.
874
+ this.uiUpdates.startHeartbeat('streaming', {
875
+ intervalMs: 1000,
876
+ lane: 'heartbeat',
877
+ mode: ['streaming', 'processing'],
878
+ coalesceKey: 'streaming:heartbeat',
879
+ run: () => {
880
+ const elapsedSeconds = this.streamingHeartbeatStart
881
+ ? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
882
+ : 0;
883
+ this.streamingHeartbeatFrame =
884
+ (this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
885
+ const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
886
+ this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
887
+ display.updateStreamingStatus(this.streamingStatusLabel);
888
+ this.refreshStatusLine(true);
889
+ },
890
+ });
835
891
  }
836
892
  stopStreamingHeartbeat() {
837
893
  // Exit global streaming mode - allows UI to render again
@@ -847,10 +903,28 @@ export class InteractiveShell {
847
903
  // Force refresh to update the input area now that streaming has ended
848
904
  this.refreshStatusLine(true);
849
905
  }
850
- buildStreamingStatus(label) {
906
+ buildStreamingStatus(label, elapsedSeconds) {
851
907
  const detail = this.describeModelDetail();
852
- const prefix = theme.info('');
853
- return detail ? `${prefix} ${label} ${theme.ui.muted('·')} ${detail}` : `${prefix} ${label}`;
908
+ const elapsedLabel = typeof elapsedSeconds === 'number' && elapsedSeconds >= 0
909
+ ? theme.ui.muted(this.formatElapsedShort(elapsedSeconds))
910
+ : null;
911
+ const prefix = theme.info('⏺');
912
+ const parts = [label];
913
+ if (detail) {
914
+ parts.push(theme.ui.muted('·'), detail);
915
+ }
916
+ if (elapsedLabel) {
917
+ parts.push(theme.ui.muted('·'), elapsedLabel);
918
+ }
919
+ return `${prefix} ${parts.join(' ')}`.trim();
920
+ }
921
+ formatElapsedShort(seconds) {
922
+ if (seconds < 60) {
923
+ return `${seconds}s`;
924
+ }
925
+ const minutes = Math.floor(seconds / 60);
926
+ const remaining = seconds % 60;
927
+ return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
854
928
  }
855
929
  refreshQueueIndicators() {
856
930
  if (this.isProcessing) {
@@ -1098,17 +1172,6 @@ export class InteractiveShell {
1098
1172
  case '/discover':
1099
1173
  await this.discoverModelsCommand();
1100
1174
  break;
1101
- case '/memory':
1102
- this.handleMemoryCommand(input);
1103
- break;
1104
- case '/clear':
1105
- display.clear();
1106
- this.cachedHistory = [];
1107
- display.showInfo('Conversation cleared.');
1108
- break;
1109
- case '/help':
1110
- this.showHelp();
1111
- break;
1112
1175
  default:
1113
1176
  if (!(await this.tryCustomSlashCommand(command, input))) {
1114
1177
  display.showWarning(`Unknown command "${command}".`);
@@ -1417,99 +1480,6 @@ export class InteractiveShell {
1417
1480
  // Display keyboard shortcuts help (Claude Code style)
1418
1481
  display.showSystemMessage(formatShortcutsHelp());
1419
1482
  }
1420
- handleMemoryCommand(input) {
1421
- const tokens = input.trim().split(/\s+/).slice(1);
1422
- const action = (tokens.shift() ?? 'show').toLowerCase();
1423
- switch (action) {
1424
- case '':
1425
- case 'show':
1426
- case 'list': {
1427
- this.showMemoryStatus();
1428
- break;
1429
- }
1430
- case 'paths': {
1431
- this.showMemoryPaths();
1432
- break;
1433
- }
1434
- case 'edit': {
1435
- const level = (tokens[0] ?? 'project').toLowerCase();
1436
- this.openMemoryForEdit(level);
1437
- break;
1438
- }
1439
- default:
1440
- display.showWarning('Usage: /memory [show|paths|edit <user|project>]');
1441
- break;
1442
- }
1443
- }
1444
- showMemoryStatus() {
1445
- const memory = loadMemory(this.workingDir);
1446
- const lines = [];
1447
- lines.push(theme.bold('Persistent Memory'));
1448
- lines.push('');
1449
- if (memory.sources.length === 0) {
1450
- lines.push(theme.secondary('No memory files found.'));
1451
- lines.push('');
1452
- lines.push(`Create ${theme.info('EROSOLAR.md')} in your project to add persistent context.`);
1453
- lines.push(`Use ${theme.info('/memory edit project')} to create one.`);
1454
- }
1455
- else {
1456
- for (const source of memory.sources) {
1457
- const levelLabel = source.level === 'enterprise' ? 'Enterprise' :
1458
- source.level === 'user' ? 'User' : 'Project';
1459
- const preview = source.content.slice(0, 200).replace(/\n/g, ' ').trim();
1460
- const truncated = source.content.length > 200 ? '...' : '';
1461
- lines.push(`${theme.success('●')} ${theme.bold(levelLabel)}: ${source.path}`);
1462
- lines.push(` ${theme.dim(preview + truncated)}`);
1463
- lines.push('');
1464
- }
1465
- if (memory.importedPaths.length > memory.sources.length) {
1466
- lines.push(theme.secondary(`Imported ${memory.importedPaths.length - memory.sources.length} additional files via @imports.`));
1467
- }
1468
- }
1469
- display.showSystemMessage(lines.join('\n'));
1470
- }
1471
- showMemoryPaths() {
1472
- const paths = listMemoryPaths(this.workingDir);
1473
- const lines = [];
1474
- lines.push(theme.bold('Memory File Locations'));
1475
- lines.push('');
1476
- for (const { level, path, exists } of paths) {
1477
- const icon = exists ? theme.success('✓') : theme.dim('○');
1478
- const levelLabel = level.charAt(0).toUpperCase() + level.slice(1);
1479
- lines.push(`${icon} ${levelLabel}: ${path}`);
1480
- }
1481
- lines.push('');
1482
- lines.push(theme.secondary('Create any of these files to add persistent memory.'));
1483
- lines.push(theme.secondary('Use @path/to/file.md syntax to import other files.'));
1484
- display.showSystemMessage(lines.join('\n'));
1485
- }
1486
- openMemoryForEdit(level) {
1487
- let targetPath;
1488
- if (level === 'user') {
1489
- targetPath = getUserMemoryEditPath();
1490
- }
1491
- else if (level === 'project') {
1492
- targetPath = getDefaultProjectMemoryPath(this.workingDir);
1493
- }
1494
- else {
1495
- display.showWarning('Specify "user" or "project" to edit. Enterprise memory is read-only.');
1496
- return;
1497
- }
1498
- display.showInfo(`Memory file: ${targetPath}`);
1499
- display.showInfo('Create or edit this file to add persistent context for the AI.');
1500
- display.showInfo('');
1501
- display.showInfo('Example EROSOLAR.md content:');
1502
- display.showInfo('');
1503
- display.showInfo(theme.dim(`# Project Guidelines
1504
-
1505
- When working in this codebase:
1506
- - Follow TypeScript strict mode conventions
1507
- - Use functional patterns where appropriate
1508
- - Run tests before committing
1509
-
1510
- @./docs/coding-standards.md
1511
- `));
1512
- }
1513
1483
  showFileChangeSummary() {
1514
1484
  const summary = this._fileChangeTracker.getSummary();
1515
1485
  const changes = this._fileChangeTracker.getAllChanges();
@@ -1552,11 +1522,11 @@ When working in this codebase:
1552
1522
  display.showSystemMessage(lines.join('\n'));
1553
1523
  }
1554
1524
  showAlphaZeroMetrics() {
1555
- const summary = this.sessionMetrics.getPerformanceSummary();
1525
+ const summary = this.alphaZeroMetrics.getPerformanceSummary();
1556
1526
  display.showSystemMessage(summary);
1557
1527
  }
1558
1528
  showImprovementSuggestions() {
1559
- const suggestions = this.sessionMetrics.getImprovementSuggestions();
1529
+ const suggestions = this.alphaZeroMetrics.getImprovementSuggestions();
1560
1530
  if (suggestions.length === 0) {
1561
1531
  display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
1562
1532
  return;
@@ -1602,7 +1572,9 @@ When working in this codebase:
1602
1572
  }
1603
1573
  }
1604
1574
  lines.push(theme.secondary('CLI Flags:'));
1575
+ lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
1605
1576
  lines.push(' --coding Enable enhanced coding tools');
1577
+ lines.push(' --security Enable security research tools');
1606
1578
  lines.push(' --all-plugins Enable all optional plugins');
1607
1579
  display.showSystemMessage(lines.join('\n'));
1608
1580
  }
@@ -1846,6 +1818,75 @@ When working in this codebase:
1846
1818
  }
1847
1819
  return `${warning.label}: ${warning.reason}.`;
1848
1820
  }
1821
+ buildLaunchCommandPalette() {
1822
+ const entries = [];
1823
+ const secretsSummary = this.summarizeSecretsForPalette();
1824
+ const toolSummary = this.getToolSelectionSummary();
1825
+ const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
1826
+ for (const command of this.slashCommands) {
1827
+ const entry = {
1828
+ command: command.command,
1829
+ description: command.description,
1830
+ category: command.category ?? 'other',
1831
+ };
1832
+ switch (command.command) {
1833
+ case '/secrets':
1834
+ if (secretsSummary.text) {
1835
+ entry.description = `${command.description} (${secretsSummary.text})`;
1836
+ entry.tone = secretsSummary.tone;
1837
+ }
1838
+ break;
1839
+ case '/tools':
1840
+ if (toolSummary) {
1841
+ entry.description = `${command.description} (${toolSummary})`;
1842
+ }
1843
+ break;
1844
+ case '/sessions':
1845
+ entry.description = `${command.description} (autosave ${autosaveLabel})`;
1846
+ break;
1847
+ case '/model':
1848
+ entry.description = `${command.description} (current: ${this.sessionState.model})`;
1849
+ break;
1850
+ case '/provider':
1851
+ entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
1852
+ break;
1853
+ default:
1854
+ break;
1855
+ }
1856
+ entries.push(entry);
1857
+ }
1858
+ return entries;
1859
+ }
1860
+ summarizeSecretsForPalette() {
1861
+ const definitions = listSecretDefinitions();
1862
+ if (!definitions.length) {
1863
+ return { text: null };
1864
+ }
1865
+ const missing = definitions.filter((definition) => !getSecretValue(definition.id));
1866
+ if (missing.length === 0) {
1867
+ return { text: 'all configured', tone: 'success' };
1868
+ }
1869
+ const labels = missing.map((definition) => definition.label ?? definition.id);
1870
+ return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
1871
+ }
1872
+ getToolSelectionSummary() {
1873
+ const toolSettings = loadToolSettings();
1874
+ const selection = buildEnabledToolSet(toolSettings);
1875
+ const options = getToolToggleOptions();
1876
+ if (!options.length) {
1877
+ return null;
1878
+ }
1879
+ const enabledCount = options.filter((option) => selection.has(option.id)).length;
1880
+ return `${enabledCount}/${options.length} enabled`;
1881
+ }
1882
+ formatList(values, maxItems = 3) {
1883
+ if (!values.length) {
1884
+ return '';
1885
+ }
1886
+ const shown = values.slice(0, maxItems);
1887
+ const suffix = values.length > maxItems ? ', …' : '';
1888
+ return `${shown.join(', ')}${suffix}`;
1889
+ }
1849
1890
  buildSlashCommandList(header) {
1850
1891
  const lines = [theme.gradient.primary(header), ''];
1851
1892
  for (const command of this.slashCommands) {
@@ -2314,7 +2355,7 @@ When working in this codebase:
2314
2355
  this.autosaveIfEnabled();
2315
2356
  // Track metrics with Alpha Zero 2
2316
2357
  const elapsedMs = Date.now() - requestStartTime;
2317
- this.sessionMetrics.recordMessage(elapsedMs);
2358
+ this.alphaZeroMetrics.recordMessage(elapsedMs);
2318
2359
  if (!responseText?.trim()) {
2319
2360
  display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
2320
2361
  }
@@ -2332,14 +2373,10 @@ When working in this codebase:
2332
2373
  this.stopStreamingHeartbeat();
2333
2374
  this.isProcessing = false;
2334
2375
  this.terminalInput.setStreaming(false);
2335
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
2336
2376
  this.uiAdapter.endProcessing('Ready for prompts');
2337
2377
  this.setIdleStatus();
2338
2378
  display.newLine();
2339
2379
  this.updateStatusMessage(null);
2340
- // Claude Code style: Show unified status bar before prompt
2341
- // This creates consistent UI between startup and post-streaming
2342
- this.showUnifiedStatusBar();
2343
2380
  queueMicrotask(() => this.uiUpdates.setMode('idle'));
2344
2381
  // CRITICAL: Ensure readline prompt is active for user input
2345
2382
  // Claude Code style: New prompt naturally appears at bottom
@@ -2416,13 +2453,14 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
2416
2453
  try {
2417
2454
  // Send the request and capture the response (streaming disabled)
2418
2455
  display.showThinking('Responding...');
2456
+ this.refreshStatusLine(true);
2419
2457
  const response = await agent.send(currentPrompt, true);
2420
2458
  await this.awaitPendingCleanup();
2421
2459
  this.captureHistorySnapshot();
2422
2460
  this.autosaveIfEnabled();
2423
2461
  // Track metrics
2424
2462
  const elapsedMs = Date.now() - overallStartTime;
2425
- this.sessionMetrics.recordMessage(elapsedMs);
2463
+ this.alphaZeroMetrics.recordMessage(elapsedMs);
2426
2464
  if (!response?.trim()) {
2427
2465
  display.showWarning('Model returned an empty response. Retrying this iteration...');
2428
2466
  consecutiveNoProgress++;
@@ -2559,7 +2597,6 @@ What's the next action?`;
2559
2597
  this.stopStreamingHeartbeat();
2560
2598
  this.isProcessing = false;
2561
2599
  this.terminalInput.setStreaming(false);
2562
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
2563
2600
  this.uiAdapter.endProcessing('Ready for prompts');
2564
2601
  this.setIdleStatus();
2565
2602
  this.updateStatusMessage(null);
@@ -2916,8 +2953,10 @@ What's the next action?`;
2916
2953
  try {
2917
2954
  // Send the error to the agent for fixing
2918
2955
  display.showThinking('Analyzing build errors');
2956
+ this.refreshStatusLine(true);
2919
2957
  const response = await this.agent.send(prompt, true);
2920
2958
  display.stopThinking();
2959
+ this.refreshStatusLine(true);
2921
2960
  if (response) {
2922
2961
  display.showAssistantMessage(response, { isFinal: true });
2923
2962
  }
@@ -2967,18 +3006,16 @@ What's the next action?`;
2967
3006
  display.showAssistantMessage(finalContent, enriched);
2968
3007
  }
2969
3008
  }
2970
- // Show status line at end (Claude Code style: "• Context X% used • Ready for prompts (2s)")
3009
+ // Status shown in mode controls bar - no separate status line needed
2971
3010
  display.stopThinking();
2972
- // Calculate context usage
2973
- let contextInfo;
3011
+ // Update context usage for mode controls display
2974
3012
  if (enriched.contextWindowTokens && metadata.usage) {
2975
3013
  const total = this.totalTokens(metadata.usage);
2976
3014
  if (total && total > 0) {
2977
3015
  const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
2978
- contextInfo = { percentage, tokens: total };
3016
+ this.updateContextUsage(percentage);
2979
3017
  }
2980
3018
  }
2981
- display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
2982
3019
  // Auto-verify changes: build first (catches type errors), then tests
2983
3020
  void this.enforceAutoBuild('final-response');
2984
3021
  void this.enforceAutoTests('final-response');
@@ -3048,7 +3085,6 @@ What's the next action?`;
3048
3085
  this.stopStreamingHeartbeat();
3049
3086
  this.updateStatusMessage(null);
3050
3087
  this.terminalInput.setStreaming(false);
3051
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
3052
3088
  this.terminalInput.render();
3053
3089
  },
3054
3090
  onVerificationNeeded: () => {
@@ -3085,7 +3121,6 @@ What's the next action?`;
3085
3121
  resetChatBoxAfterModelSwap() {
3086
3122
  this.updateStatusMessage(null);
3087
3123
  this.terminalInput.setStreaming(false);
3088
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
3089
3124
  this.terminalInput.render();
3090
3125
  this.ensureReadlineReady();
3091
3126
  }
@@ -3150,9 +3185,14 @@ What's the next action?`;
3150
3185
  return null;
3151
3186
  }
3152
3187
  const usageRatio = total / windowTokens;
3188
+ this.latestTokenUsage = {
3189
+ used: total,
3190
+ limit: windowTokens,
3191
+ };
3153
3192
  // Always update context usage in the UI
3154
3193
  const percentUsed = Math.round(usageRatio * 100);
3155
3194
  this.updateContextUsage(percentUsed);
3195
+ this.refreshStatusLine(true);
3156
3196
  if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
3157
3197
  return null;
3158
3198
  }
@@ -3430,8 +3470,6 @@ What's the next action?`;
3430
3470
  }
3431
3471
  this.refreshContextGauge();
3432
3472
  display.updateSessionInfo(nextState.model, nextState.provider);
3433
- // Update the persistent model info display in terminal input
3434
- this.terminalInput.setModelInfo(this.describeModelDetail());
3435
3473
  if (!this.isProcessing) {
3436
3474
  this.setIdleStatus();
3437
3475
  }