erosolar-cli 1.7.266 → 1.7.267

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 (321) hide show
  1. package/README.md +24 -148
  2. package/dist/capabilities/agentSpawningCapability.d.ts.map +1 -1
  3. package/dist/capabilities/agentSpawningCapability.js +56 -31
  4. package/dist/capabilities/agentSpawningCapability.js.map +1 -1
  5. package/dist/contracts/agent-schemas.json +0 -15
  6. package/dist/contracts/tools.schema.json +0 -9
  7. package/dist/core/agent.d.ts +2 -2
  8. package/dist/core/agent.d.ts.map +1 -1
  9. package/dist/core/agent.js.map +1 -1
  10. package/dist/core/customCommands.d.ts +1 -0
  11. package/dist/core/customCommands.d.ts.map +1 -1
  12. package/dist/core/customCommands.js +3 -0
  13. package/dist/core/customCommands.js.map +1 -1
  14. package/dist/core/hooks.d.ts +113 -0
  15. package/dist/core/hooks.d.ts.map +1 -0
  16. package/dist/core/hooks.js +267 -0
  17. package/dist/core/hooks.js.map +1 -0
  18. package/dist/core/metricsTracker.d.ts +122 -0
  19. package/dist/core/metricsTracker.d.ts.map +1 -0
  20. package/dist/{alpha-zero → core}/metricsTracker.js +2 -5
  21. package/dist/core/metricsTracker.js.map +1 -0
  22. package/dist/core/securityAssessment.d.ts +91 -0
  23. package/dist/core/securityAssessment.d.ts.map +1 -0
  24. package/dist/core/securityAssessment.js +580 -0
  25. package/dist/core/securityAssessment.js.map +1 -0
  26. package/dist/core/toolPreconditions.d.ts.map +1 -1
  27. package/dist/core/toolPreconditions.js +0 -14
  28. package/dist/core/toolPreconditions.js.map +1 -1
  29. package/dist/core/toolRuntime.d.ts +22 -1
  30. package/dist/core/toolRuntime.d.ts.map +1 -1
  31. package/dist/core/toolRuntime.js +0 -5
  32. package/dist/core/toolRuntime.js.map +1 -1
  33. package/dist/core/toolValidation.d.ts.map +1 -1
  34. package/dist/core/toolValidation.js +14 -3
  35. package/dist/core/toolValidation.js.map +1 -1
  36. package/dist/core/validationRunner.d.ts +1 -3
  37. package/dist/core/validationRunner.d.ts.map +1 -1
  38. package/dist/core/validationRunner.js.map +1 -1
  39. package/dist/core/verification.d.ts +137 -0
  40. package/dist/core/verification.d.ts.map +1 -0
  41. package/dist/core/verification.js +323 -0
  42. package/dist/core/verification.js.map +1 -0
  43. package/dist/headless/headlessApp.d.ts.map +1 -1
  44. package/dist/headless/headlessApp.js +21 -0
  45. package/dist/headless/headlessApp.js.map +1 -1
  46. package/dist/mcp/sseClient.d.ts.map +1 -1
  47. package/dist/mcp/sseClient.js +9 -18
  48. package/dist/mcp/sseClient.js.map +1 -1
  49. package/dist/plugins/tools/build/buildPlugin.d.ts +0 -6
  50. package/dist/plugins/tools/build/buildPlugin.d.ts.map +1 -1
  51. package/dist/plugins/tools/build/buildPlugin.js +4 -10
  52. package/dist/plugins/tools/build/buildPlugin.js.map +1 -1
  53. package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
  54. package/dist/plugins/tools/nodeDefaults.js +0 -2
  55. package/dist/plugins/tools/nodeDefaults.js.map +1 -1
  56. package/dist/runtime/agentSession.d.ts +2 -2
  57. package/dist/runtime/agentSession.d.ts.map +1 -1
  58. package/dist/runtime/agentSession.js +2 -2
  59. package/dist/runtime/agentSession.js.map +1 -1
  60. package/dist/shell/interactiveShell.d.ts +11 -7
  61. package/dist/shell/interactiveShell.d.ts.map +1 -1
  62. package/dist/shell/interactiveShell.js +190 -157
  63. package/dist/shell/interactiveShell.js.map +1 -1
  64. package/dist/shell/shellApp.d.ts +2 -0
  65. package/dist/shell/shellApp.d.ts.map +1 -1
  66. package/dist/shell/shellApp.js +36 -1
  67. package/dist/shell/shellApp.js.map +1 -1
  68. package/dist/shell/systemPrompt.d.ts.map +1 -1
  69. package/dist/shell/systemPrompt.js +1 -4
  70. package/dist/shell/systemPrompt.js.map +1 -1
  71. package/dist/shell/terminalInput.d.ts +77 -153
  72. package/dist/shell/terminalInput.d.ts.map +1 -1
  73. package/dist/shell/terminalInput.js +490 -726
  74. package/dist/shell/terminalInput.js.map +1 -1
  75. package/dist/shell/terminalInputAdapter.d.ts +20 -25
  76. package/dist/shell/terminalInputAdapter.d.ts.map +1 -1
  77. package/dist/shell/terminalInputAdapter.js +14 -36
  78. package/dist/shell/terminalInputAdapter.js.map +1 -1
  79. package/dist/subagents/agentConfig.d.ts +27 -0
  80. package/dist/subagents/agentConfig.d.ts.map +1 -0
  81. package/dist/subagents/agentConfig.js +89 -0
  82. package/dist/subagents/agentConfig.js.map +1 -0
  83. package/dist/subagents/agentRegistry.d.ts +33 -0
  84. package/dist/subagents/agentRegistry.d.ts.map +1 -0
  85. package/dist/subagents/agentRegistry.js +162 -0
  86. package/dist/subagents/agentRegistry.js.map +1 -0
  87. package/dist/subagents/taskRunner.d.ts +7 -1
  88. package/dist/subagents/taskRunner.d.ts.map +1 -1
  89. package/dist/subagents/taskRunner.js +180 -47
  90. package/dist/subagents/taskRunner.js.map +1 -1
  91. package/dist/ui/ShellUIAdapter.d.ts.map +1 -1
  92. package/dist/ui/ShellUIAdapter.js +13 -12
  93. package/dist/ui/ShellUIAdapter.js.map +1 -1
  94. package/dist/ui/display.d.ts +19 -0
  95. package/dist/ui/display.d.ts.map +1 -1
  96. package/dist/ui/display.js +131 -33
  97. package/dist/ui/display.js.map +1 -1
  98. package/dist/ui/theme.d.ts.map +1 -1
  99. package/dist/ui/theme.js +6 -8
  100. package/dist/ui/theme.js.map +1 -1
  101. package/dist/ui/toolDisplay.d.ts +0 -158
  102. package/dist/ui/toolDisplay.d.ts.map +1 -1
  103. package/dist/ui/toolDisplay.js +0 -348
  104. package/dist/ui/toolDisplay.js.map +1 -1
  105. package/dist/ui/unified/layout.d.ts +1 -0
  106. package/dist/ui/unified/layout.d.ts.map +1 -1
  107. package/dist/ui/unified/layout.js +15 -25
  108. package/dist/ui/unified/layout.js.map +1 -1
  109. package/dist/utils/frontmatter.d.ts +10 -0
  110. package/dist/utils/frontmatter.d.ts.map +1 -0
  111. package/dist/utils/frontmatter.js +78 -0
  112. package/dist/utils/frontmatter.js.map +1 -0
  113. package/package.json +1 -1
  114. package/dist/alpha-zero/agentWrapper.d.ts +0 -84
  115. package/dist/alpha-zero/agentWrapper.d.ts.map +0 -1
  116. package/dist/alpha-zero/agentWrapper.js +0 -171
  117. package/dist/alpha-zero/agentWrapper.js.map +0 -1
  118. package/dist/alpha-zero/codeEvaluator.d.ts +0 -25
  119. package/dist/alpha-zero/codeEvaluator.d.ts.map +0 -1
  120. package/dist/alpha-zero/codeEvaluator.js +0 -273
  121. package/dist/alpha-zero/codeEvaluator.js.map +0 -1
  122. package/dist/alpha-zero/competitiveRunner.d.ts +0 -66
  123. package/dist/alpha-zero/competitiveRunner.d.ts.map +0 -1
  124. package/dist/alpha-zero/competitiveRunner.js +0 -224
  125. package/dist/alpha-zero/competitiveRunner.js.map +0 -1
  126. package/dist/alpha-zero/index.d.ts +0 -67
  127. package/dist/alpha-zero/index.d.ts.map +0 -1
  128. package/dist/alpha-zero/index.js +0 -99
  129. package/dist/alpha-zero/index.js.map +0 -1
  130. package/dist/alpha-zero/introspection.d.ts +0 -128
  131. package/dist/alpha-zero/introspection.d.ts.map +0 -1
  132. package/dist/alpha-zero/introspection.js +0 -300
  133. package/dist/alpha-zero/introspection.js.map +0 -1
  134. package/dist/alpha-zero/metricsTracker.d.ts +0 -71
  135. package/dist/alpha-zero/metricsTracker.d.ts.map +0 -1
  136. package/dist/alpha-zero/metricsTracker.js.map +0 -1
  137. package/dist/alpha-zero/security/core.d.ts +0 -125
  138. package/dist/alpha-zero/security/core.d.ts.map +0 -1
  139. package/dist/alpha-zero/security/core.js +0 -271
  140. package/dist/alpha-zero/security/core.js.map +0 -1
  141. package/dist/alpha-zero/security/google.d.ts +0 -125
  142. package/dist/alpha-zero/security/google.d.ts.map +0 -1
  143. package/dist/alpha-zero/security/google.js +0 -311
  144. package/dist/alpha-zero/security/google.js.map +0 -1
  145. package/dist/alpha-zero/security/googleLoader.d.ts +0 -17
  146. package/dist/alpha-zero/security/googleLoader.d.ts.map +0 -1
  147. package/dist/alpha-zero/security/googleLoader.js +0 -41
  148. package/dist/alpha-zero/security/googleLoader.js.map +0 -1
  149. package/dist/alpha-zero/security/index.d.ts +0 -29
  150. package/dist/alpha-zero/security/index.d.ts.map +0 -1
  151. package/dist/alpha-zero/security/index.js +0 -32
  152. package/dist/alpha-zero/security/index.js.map +0 -1
  153. package/dist/alpha-zero/security/simulation.d.ts +0 -124
  154. package/dist/alpha-zero/security/simulation.d.ts.map +0 -1
  155. package/dist/alpha-zero/security/simulation.js +0 -277
  156. package/dist/alpha-zero/security/simulation.js.map +0 -1
  157. package/dist/alpha-zero/selfModification.d.ts +0 -109
  158. package/dist/alpha-zero/selfModification.d.ts.map +0 -1
  159. package/dist/alpha-zero/selfModification.js +0 -233
  160. package/dist/alpha-zero/selfModification.js.map +0 -1
  161. package/dist/alpha-zero/types.d.ts +0 -170
  162. package/dist/alpha-zero/types.d.ts.map +0 -1
  163. package/dist/alpha-zero/types.js +0 -31
  164. package/dist/alpha-zero/types.js.map +0 -1
  165. package/dist/capabilities/securityTestingCapability.d.ts +0 -13
  166. package/dist/capabilities/securityTestingCapability.d.ts.map +0 -1
  167. package/dist/capabilities/securityTestingCapability.js +0 -25
  168. package/dist/capabilities/securityTestingCapability.js.map +0 -1
  169. package/dist/core/aiFlowOptimizer.d.ts +0 -26
  170. package/dist/core/aiFlowOptimizer.d.ts.map +0 -1
  171. package/dist/core/aiFlowOptimizer.js +0 -31
  172. package/dist/core/aiFlowOptimizer.js.map +0 -1
  173. package/dist/core/aiOptimizationEngine.d.ts +0 -158
  174. package/dist/core/aiOptimizationEngine.d.ts.map +0 -1
  175. package/dist/core/aiOptimizationEngine.js +0 -428
  176. package/dist/core/aiOptimizationEngine.js.map +0 -1
  177. package/dist/core/aiOptimizationIntegration.d.ts +0 -93
  178. package/dist/core/aiOptimizationIntegration.d.ts.map +0 -1
  179. package/dist/core/aiOptimizationIntegration.js +0 -250
  180. package/dist/core/aiOptimizationIntegration.js.map +0 -1
  181. package/dist/core/enhancedErrorRecovery.d.ts +0 -100
  182. package/dist/core/enhancedErrorRecovery.d.ts.map +0 -1
  183. package/dist/core/enhancedErrorRecovery.js +0 -345
  184. package/dist/core/enhancedErrorRecovery.js.map +0 -1
  185. package/dist/core/hooksSystem.d.ts +0 -65
  186. package/dist/core/hooksSystem.d.ts.map +0 -1
  187. package/dist/core/hooksSystem.js +0 -273
  188. package/dist/core/hooksSystem.js.map +0 -1
  189. package/dist/core/memorySystem.d.ts +0 -48
  190. package/dist/core/memorySystem.d.ts.map +0 -1
  191. package/dist/core/memorySystem.js +0 -271
  192. package/dist/core/memorySystem.js.map +0 -1
  193. package/dist/core/unified/errors.d.ts +0 -189
  194. package/dist/core/unified/errors.d.ts.map +0 -1
  195. package/dist/core/unified/errors.js +0 -497
  196. package/dist/core/unified/errors.js.map +0 -1
  197. package/dist/core/unified/index.d.ts +0 -19
  198. package/dist/core/unified/index.d.ts.map +0 -1
  199. package/dist/core/unified/index.js +0 -68
  200. package/dist/core/unified/index.js.map +0 -1
  201. package/dist/core/unified/schema.d.ts +0 -101
  202. package/dist/core/unified/schema.d.ts.map +0 -1
  203. package/dist/core/unified/schema.js +0 -350
  204. package/dist/core/unified/schema.js.map +0 -1
  205. package/dist/core/unified/toolRuntime.d.ts +0 -179
  206. package/dist/core/unified/toolRuntime.d.ts.map +0 -1
  207. package/dist/core/unified/toolRuntime.js +0 -517
  208. package/dist/core/unified/toolRuntime.js.map +0 -1
  209. package/dist/core/unified/tools.d.ts +0 -127
  210. package/dist/core/unified/tools.d.ts.map +0 -1
  211. package/dist/core/unified/tools.js +0 -1333
  212. package/dist/core/unified/tools.js.map +0 -1
  213. package/dist/core/unified/types.d.ts +0 -352
  214. package/dist/core/unified/types.d.ts.map +0 -1
  215. package/dist/core/unified/types.js +0 -12
  216. package/dist/core/unified/types.js.map +0 -1
  217. package/dist/core/unified/version.d.ts +0 -209
  218. package/dist/core/unified/version.d.ts.map +0 -1
  219. package/dist/core/unified/version.js +0 -454
  220. package/dist/core/unified/version.js.map +0 -1
  221. package/dist/plugins/tools/security/securityPlugin.d.ts +0 -3
  222. package/dist/plugins/tools/security/securityPlugin.d.ts.map +0 -1
  223. package/dist/plugins/tools/security/securityPlugin.js +0 -12
  224. package/dist/plugins/tools/security/securityPlugin.js.map +0 -1
  225. package/dist/security/active-stack-security.d.ts +0 -112
  226. package/dist/security/active-stack-security.d.ts.map +0 -1
  227. package/dist/security/active-stack-security.js +0 -296
  228. package/dist/security/active-stack-security.js.map +0 -1
  229. package/dist/security/advanced-persistence-research.d.ts +0 -92
  230. package/dist/security/advanced-persistence-research.d.ts.map +0 -1
  231. package/dist/security/advanced-persistence-research.js +0 -195
  232. package/dist/security/advanced-persistence-research.js.map +0 -1
  233. package/dist/security/advanced-targeting.d.ts +0 -119
  234. package/dist/security/advanced-targeting.d.ts.map +0 -1
  235. package/dist/security/advanced-targeting.js +0 -233
  236. package/dist/security/advanced-targeting.js.map +0 -1
  237. package/dist/security/assessment/vulnerabilityAssessment.d.ts +0 -104
  238. package/dist/security/assessment/vulnerabilityAssessment.d.ts.map +0 -1
  239. package/dist/security/assessment/vulnerabilityAssessment.js +0 -315
  240. package/dist/security/assessment/vulnerabilityAssessment.js.map +0 -1
  241. package/dist/security/authorization/securityAuthorization.d.ts +0 -88
  242. package/dist/security/authorization/securityAuthorization.d.ts.map +0 -1
  243. package/dist/security/authorization/securityAuthorization.js +0 -172
  244. package/dist/security/authorization/securityAuthorization.js.map +0 -1
  245. package/dist/security/comprehensive-targeting.d.ts +0 -85
  246. package/dist/security/comprehensive-targeting.d.ts.map +0 -1
  247. package/dist/security/comprehensive-targeting.js +0 -438
  248. package/dist/security/comprehensive-targeting.js.map +0 -1
  249. package/dist/security/global-security-integration.d.ts +0 -91
  250. package/dist/security/global-security-integration.d.ts.map +0 -1
  251. package/dist/security/global-security-integration.js +0 -218
  252. package/dist/security/global-security-integration.js.map +0 -1
  253. package/dist/security/index.d.ts +0 -38
  254. package/dist/security/index.d.ts.map +0 -1
  255. package/dist/security/index.js +0 -47
  256. package/dist/security/index.js.map +0 -1
  257. package/dist/security/persistence-analyzer.d.ts +0 -56
  258. package/dist/security/persistence-analyzer.d.ts.map +0 -1
  259. package/dist/security/persistence-analyzer.js +0 -187
  260. package/dist/security/persistence-analyzer.js.map +0 -1
  261. package/dist/security/persistence-cli.d.ts +0 -36
  262. package/dist/security/persistence-cli.d.ts.map +0 -1
  263. package/dist/security/persistence-cli.js +0 -160
  264. package/dist/security/persistence-cli.js.map +0 -1
  265. package/dist/security/persistence-research.d.ts +0 -92
  266. package/dist/security/persistence-research.d.ts.map +0 -1
  267. package/dist/security/persistence-research.js +0 -364
  268. package/dist/security/persistence-research.js.map +0 -1
  269. package/dist/security/research/persistenceResearch.d.ts +0 -97
  270. package/dist/security/research/persistenceResearch.d.ts.map +0 -1
  271. package/dist/security/research/persistenceResearch.js +0 -282
  272. package/dist/security/research/persistenceResearch.js.map +0 -1
  273. package/dist/security/security-integration.d.ts +0 -74
  274. package/dist/security/security-integration.d.ts.map +0 -1
  275. package/dist/security/security-integration.js +0 -137
  276. package/dist/security/security-integration.js.map +0 -1
  277. package/dist/security/security-testing-framework.d.ts +0 -112
  278. package/dist/security/security-testing-framework.d.ts.map +0 -1
  279. package/dist/security/security-testing-framework.js +0 -364
  280. package/dist/security/security-testing-framework.js.map +0 -1
  281. package/dist/security/simulation/attackSimulation.d.ts +0 -93
  282. package/dist/security/simulation/attackSimulation.d.ts.map +0 -1
  283. package/dist/security/simulation/attackSimulation.js +0 -341
  284. package/dist/security/simulation/attackSimulation.js.map +0 -1
  285. package/dist/security/strategic-operations.d.ts +0 -100
  286. package/dist/security/strategic-operations.d.ts.map +0 -1
  287. package/dist/security/strategic-operations.js +0 -276
  288. package/dist/security/strategic-operations.js.map +0 -1
  289. package/dist/security/tool-security-wrapper.d.ts +0 -58
  290. package/dist/security/tool-security-wrapper.d.ts.map +0 -1
  291. package/dist/security/tool-security-wrapper.js +0 -156
  292. package/dist/security/tool-security-wrapper.js.map +0 -1
  293. package/dist/shell/claudeCodeStreamHandler.d.ts +0 -145
  294. package/dist/shell/claudeCodeStreamHandler.d.ts.map +0 -1
  295. package/dist/shell/claudeCodeStreamHandler.js +0 -322
  296. package/dist/shell/claudeCodeStreamHandler.js.map +0 -1
  297. package/dist/shell/inputQueueManager.d.ts +0 -144
  298. package/dist/shell/inputQueueManager.d.ts.map +0 -1
  299. package/dist/shell/inputQueueManager.js +0 -290
  300. package/dist/shell/inputQueueManager.js.map +0 -1
  301. package/dist/shell/metricsTracker.d.ts +0 -60
  302. package/dist/shell/metricsTracker.d.ts.map +0 -1
  303. package/dist/shell/metricsTracker.js +0 -119
  304. package/dist/shell/metricsTracker.js.map +0 -1
  305. package/dist/shell/streamingOutputManager.d.ts +0 -115
  306. package/dist/shell/streamingOutputManager.d.ts.map +0 -1
  307. package/dist/shell/streamingOutputManager.js +0 -225
  308. package/dist/shell/streamingOutputManager.js.map +0 -1
  309. package/dist/tools/securityTools.d.ts +0 -22
  310. package/dist/tools/securityTools.d.ts.map +0 -1
  311. package/dist/tools/securityTools.js +0 -448
  312. package/dist/tools/securityTools.js.map +0 -1
  313. package/dist/ui/persistentPrompt.d.ts +0 -50
  314. package/dist/ui/persistentPrompt.d.ts.map +0 -1
  315. package/dist/ui/persistentPrompt.js +0 -92
  316. package/dist/ui/persistentPrompt.js.map +0 -1
  317. package/dist/ui/terminalUISchema.d.ts +0 -195
  318. package/dist/ui/terminalUISchema.d.ts.map +0 -1
  319. package/dist/ui/terminalUISchema.js +0 -113
  320. package/dist/ui/terminalUISchema.js.map +0 -1
  321. 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,8 @@ 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());
224
227
  // Initialize Alpha Zero 2 metrics tracking
225
- this.sessionMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
228
+ this.alphaZeroMetrics = new MetricsTracker(`${this.profile}-${Date.now()}`);
226
229
  this.setupStatusTracking();
227
230
  this.refreshContextGauge();
228
231
  this.terminalInput.start();
@@ -278,9 +281,15 @@ export class InteractiveShell {
278
281
  await this.processInputBlock(initialPrompt);
279
282
  return;
280
283
  }
284
+ this.showLaunchCommandPalette();
281
285
  // Ensure the terminal input is visible
282
286
  this.terminalInput.render();
283
287
  }
288
+ showLaunchCommandPalette() {
289
+ // Disabled: Quick commands palette takes up too much space
290
+ // Users can type /help to see available commands
291
+ this.launchPaletteShown = true;
292
+ }
284
293
  /**
285
294
  * TerminalInputAdapter submit handler
286
295
  */
@@ -294,9 +303,8 @@ export class InteractiveShell {
294
303
  this.handleInputChange('');
295
304
  return;
296
305
  }
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);
306
+ // DON'T clear the input here - keep it visible while streaming.
307
+ // The input will be cleared after streaming completes in the finally block.
300
308
  this.logUserPrompt(approved);
301
309
  void this.processInputBlock(approved).catch((err) => {
302
310
  display.showError(err instanceof Error ? err.message : String(err), err);
@@ -498,10 +506,9 @@ export class InteractiveShell {
498
506
  // Dispose unified UI adapter
499
507
  this.uiAdapter.dispose();
500
508
  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)));
509
+ console.log(theme.ui.muted('━'.repeat(44)));
510
+ console.log(theme.ui.muted(' Goodbye! · support@ero.solar'));
511
+ console.log(theme.ui.muted(''.repeat(44)));
505
512
  exit(0);
506
513
  }
507
514
  /**
@@ -671,13 +678,14 @@ export class InteractiveShell {
671
678
  });
672
679
  }
673
680
  setProcessingStatus(detail) {
681
+ this.latestTokenUsage = { used: null, limit: this.latestTokenUsage.limit };
674
682
  this.statusTracker.setBase('Working on your request', {
675
683
  detail: this.describeStatusDetail(detail),
676
684
  tone: 'info',
677
685
  });
678
686
  }
679
687
  describeStatusDetail(detail) {
680
- const parts = [detail?.trim() || this.describeModelDetail()];
688
+ const parts = detail?.trim() ? [detail.trim()] : [];
681
689
  const queued = this.followUpQueue.length;
682
690
  if (queued > 0) {
683
691
  parts.push(`${queued} follow-up${queued === 1 ? '' : 's'} queued`);
@@ -690,12 +698,18 @@ export class InteractiveShell {
690
698
  }
691
699
  refreshContextGauge() {
692
700
  const tokens = getContextWindowTokens(this.sessionState.model);
693
- this.activeContextWindowTokens =
694
- typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
701
+ const normalizedTokens = typeof tokens === 'number' && Number.isFinite(tokens) ? tokens : null;
702
+ this.activeContextWindowTokens = normalizedTokens;
703
+ if (normalizedTokens !== null) {
704
+ this.latestTokenUsage = {
705
+ used: this.latestTokenUsage.used,
706
+ limit: normalizedTokens,
707
+ };
708
+ }
695
709
  }
696
710
  updateContextUsage(percentage) {
697
711
  this.uiAdapter.updateContextUsage(percentage);
698
- this.terminalInput.setContextUsage(percentage);
712
+ this.terminalInput.setContextUsage(percentage, CONTEXT_AUTOCOMPACT_PERCENT);
699
713
  }
700
714
  refreshControlBar() {
701
715
  this.terminalInput.setModeToggles({
@@ -703,9 +717,9 @@ export class InteractiveShell {
703
717
  autoContinueEnabled: this.autoContinueEnabled,
704
718
  verificationHotkey: 'alt+v',
705
719
  autoContinueHotkey: 'alt+c',
720
+ thinkingModeLabel: this.thinkingMode,
721
+ thinkingHotkey: '/thinking',
706
722
  });
707
- // Update persistent model info display
708
- this.terminalInput.setModelInfo(this.describeModelDetail());
709
723
  this.refreshStatusLine();
710
724
  this.terminalInput.render();
711
725
  }
@@ -736,6 +750,25 @@ export class InteractiveShell {
736
750
  // Set main status (tool execution, etc.) - shown when not overridden
737
751
  const statusText = this.formatStatusLine(this.statusLineState);
738
752
  this.terminalInput.setStatusMessage(statusText);
753
+ // Surface meta header (elapsed + context usage) above the divider
754
+ const elapsedSeconds = this.statusLineState
755
+ ? Math.max(0, Math.floor((Date.now() - this.statusLineState.startedAt) / 1000))
756
+ : null;
757
+ const thinkingMs = display.isSpinnerActive() ? display.getThinkingElapsedMs() : null;
758
+ const tokensUsed = this.latestTokenUsage.used;
759
+ const tokenLimit = this.latestTokenUsage.limit ?? this.activeContextWindowTokens;
760
+ this.terminalInput.setMetaStatus({
761
+ elapsedSeconds,
762
+ tokensUsed,
763
+ tokenLimit,
764
+ thinkingMs,
765
+ thinkingHasContent: display.isSpinnerActive(),
766
+ });
767
+ // Keep model/provider visible in the controls bar
768
+ this.terminalInput.setModelContext({
769
+ model: this.sessionState.model,
770
+ provider: this.providerLabel(this.sessionState.provider),
771
+ });
739
772
  if (forceRender) {
740
773
  this.terminalInput.render();
741
774
  }
@@ -795,13 +828,11 @@ export class InteractiveShell {
795
828
  this.terminalInput.render();
796
829
  }
797
830
  /**
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.
831
+ * Keep submissions out of the transcript to preserve the persistent input area.
832
+ * The chat box already holds the user's prompt, so avoid echoing it into output.
800
833
  */
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`);
834
+ logUserPrompt(_text) {
835
+ // Intentionally no-op to keep the input area persistent and uncluttered.
805
836
  }
806
837
  requestPromptRefresh(force = false) {
807
838
  if (force) {
@@ -829,9 +860,29 @@ export class InteractiveShell {
829
860
  this.uiUpdates.setMode('streaming');
830
861
  this.streamingHeartbeatStart = Date.now();
831
862
  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.
863
+ const initialFrame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
864
+ this.streamingStatusLabel = this.buildStreamingStatus(`${initialFrame} ${label}`, 0);
865
+ display.updateStreamingStatus(this.streamingStatusLabel);
866
+ this.refreshStatusLine(true);
867
+ // Periodically refresh the pinned input/status region while streaming so
868
+ // elapsed time remains visible without interrupting the scroll region.
869
+ this.uiUpdates.startHeartbeat('streaming', {
870
+ intervalMs: 1000,
871
+ lane: 'heartbeat',
872
+ mode: ['streaming', 'processing'],
873
+ coalesceKey: 'streaming:heartbeat',
874
+ run: () => {
875
+ const elapsedSeconds = this.streamingHeartbeatStart
876
+ ? Math.max(0, Math.floor((Date.now() - this.streamingHeartbeatStart) / 1000))
877
+ : 0;
878
+ this.streamingHeartbeatFrame =
879
+ (this.streamingHeartbeatFrame + 1) % STREAMING_SPINNER_FRAMES.length;
880
+ const frame = STREAMING_SPINNER_FRAMES[this.streamingHeartbeatFrame];
881
+ this.streamingStatusLabel = this.buildStreamingStatus(`${frame} ${label}`, elapsedSeconds);
882
+ display.updateStreamingStatus(this.streamingStatusLabel);
883
+ this.refreshStatusLine(true);
884
+ },
885
+ });
835
886
  }
836
887
  stopStreamingHeartbeat() {
837
888
  // Exit global streaming mode - allows UI to render again
@@ -847,10 +898,28 @@ export class InteractiveShell {
847
898
  // Force refresh to update the input area now that streaming has ended
848
899
  this.refreshStatusLine(true);
849
900
  }
850
- buildStreamingStatus(label) {
901
+ buildStreamingStatus(label, elapsedSeconds) {
851
902
  const detail = this.describeModelDetail();
852
- const prefix = theme.info('');
853
- return detail ? `${prefix} ${label} ${theme.ui.muted('·')} ${detail}` : `${prefix} ${label}`;
903
+ const elapsedLabel = typeof elapsedSeconds === 'number' && elapsedSeconds >= 0
904
+ ? theme.ui.muted(this.formatElapsedShort(elapsedSeconds))
905
+ : null;
906
+ const prefix = theme.info('⏺');
907
+ const parts = [label];
908
+ if (detail) {
909
+ parts.push(theme.ui.muted('·'), detail);
910
+ }
911
+ if (elapsedLabel) {
912
+ parts.push(theme.ui.muted('·'), elapsedLabel);
913
+ }
914
+ return `${prefix} ${parts.join(' ')}`.trim();
915
+ }
916
+ formatElapsedShort(seconds) {
917
+ if (seconds < 60) {
918
+ return `${seconds}s`;
919
+ }
920
+ const minutes = Math.floor(seconds / 60);
921
+ const remaining = seconds % 60;
922
+ return remaining > 0 ? `${minutes}m ${remaining}s` : `${minutes}m`;
854
923
  }
855
924
  refreshQueueIndicators() {
856
925
  if (this.isProcessing) {
@@ -1098,17 +1167,6 @@ export class InteractiveShell {
1098
1167
  case '/discover':
1099
1168
  await this.discoverModelsCommand();
1100
1169
  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
1170
  default:
1113
1171
  if (!(await this.tryCustomSlashCommand(command, input))) {
1114
1172
  display.showWarning(`Unknown command "${command}".`);
@@ -1417,99 +1475,6 @@ export class InteractiveShell {
1417
1475
  // Display keyboard shortcuts help (Claude Code style)
1418
1476
  display.showSystemMessage(formatShortcutsHelp());
1419
1477
  }
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
1478
  showFileChangeSummary() {
1514
1479
  const summary = this._fileChangeTracker.getSummary();
1515
1480
  const changes = this._fileChangeTracker.getAllChanges();
@@ -1552,11 +1517,11 @@ When working in this codebase:
1552
1517
  display.showSystemMessage(lines.join('\n'));
1553
1518
  }
1554
1519
  showAlphaZeroMetrics() {
1555
- const summary = this.sessionMetrics.getPerformanceSummary();
1520
+ const summary = this.alphaZeroMetrics.getPerformanceSummary();
1556
1521
  display.showSystemMessage(summary);
1557
1522
  }
1558
1523
  showImprovementSuggestions() {
1559
- const suggestions = this.sessionMetrics.getImprovementSuggestions();
1524
+ const suggestions = this.alphaZeroMetrics.getImprovementSuggestions();
1560
1525
  if (suggestions.length === 0) {
1561
1526
  display.showInfo('No improvement suggestions at this time. Keep using the shell to generate metrics!');
1562
1527
  return;
@@ -1602,7 +1567,9 @@ When working in this codebase:
1602
1567
  }
1603
1568
  }
1604
1569
  lines.push(theme.secondary('CLI Flags:'));
1570
+ lines.push(' --alpha-zero Enable Alpha Zero 2 RL framework');
1605
1571
  lines.push(' --coding Enable enhanced coding tools');
1572
+ lines.push(' --security Enable security research tools');
1606
1573
  lines.push(' --all-plugins Enable all optional plugins');
1607
1574
  display.showSystemMessage(lines.join('\n'));
1608
1575
  }
@@ -1846,6 +1813,75 @@ When working in this codebase:
1846
1813
  }
1847
1814
  return `${warning.label}: ${warning.reason}.`;
1848
1815
  }
1816
+ buildLaunchCommandPalette() {
1817
+ const entries = [];
1818
+ const secretsSummary = this.summarizeSecretsForPalette();
1819
+ const toolSummary = this.getToolSelectionSummary();
1820
+ const autosaveLabel = this.autosaveEnabled ? 'on' : 'off';
1821
+ for (const command of this.slashCommands) {
1822
+ const entry = {
1823
+ command: command.command,
1824
+ description: command.description,
1825
+ category: command.category ?? 'other',
1826
+ };
1827
+ switch (command.command) {
1828
+ case '/secrets':
1829
+ if (secretsSummary.text) {
1830
+ entry.description = `${command.description} (${secretsSummary.text})`;
1831
+ entry.tone = secretsSummary.tone;
1832
+ }
1833
+ break;
1834
+ case '/tools':
1835
+ if (toolSummary) {
1836
+ entry.description = `${command.description} (${toolSummary})`;
1837
+ }
1838
+ break;
1839
+ case '/sessions':
1840
+ entry.description = `${command.description} (autosave ${autosaveLabel})`;
1841
+ break;
1842
+ case '/model':
1843
+ entry.description = `${command.description} (current: ${this.sessionState.model})`;
1844
+ break;
1845
+ case '/provider':
1846
+ entry.description = `${command.description} (current: ${this.providerLabel(this.sessionState.provider)})`;
1847
+ break;
1848
+ default:
1849
+ break;
1850
+ }
1851
+ entries.push(entry);
1852
+ }
1853
+ return entries;
1854
+ }
1855
+ summarizeSecretsForPalette() {
1856
+ const definitions = listSecretDefinitions();
1857
+ if (!definitions.length) {
1858
+ return { text: null };
1859
+ }
1860
+ const missing = definitions.filter((definition) => !getSecretValue(definition.id));
1861
+ if (missing.length === 0) {
1862
+ return { text: 'all configured', tone: 'success' };
1863
+ }
1864
+ const labels = missing.map((definition) => definition.label ?? definition.id);
1865
+ return { text: `missing ${this.formatList(labels)}`, tone: 'warn' };
1866
+ }
1867
+ getToolSelectionSummary() {
1868
+ const toolSettings = loadToolSettings();
1869
+ const selection = buildEnabledToolSet(toolSettings);
1870
+ const options = getToolToggleOptions();
1871
+ if (!options.length) {
1872
+ return null;
1873
+ }
1874
+ const enabledCount = options.filter((option) => selection.has(option.id)).length;
1875
+ return `${enabledCount}/${options.length} enabled`;
1876
+ }
1877
+ formatList(values, maxItems = 3) {
1878
+ if (!values.length) {
1879
+ return '';
1880
+ }
1881
+ const shown = values.slice(0, maxItems);
1882
+ const suffix = values.length > maxItems ? ', …' : '';
1883
+ return `${shown.join(', ')}${suffix}`;
1884
+ }
1849
1885
  buildSlashCommandList(header) {
1850
1886
  const lines = [theme.gradient.primary(header), ''];
1851
1887
  for (const command of this.slashCommands) {
@@ -2314,7 +2350,7 @@ When working in this codebase:
2314
2350
  this.autosaveIfEnabled();
2315
2351
  // Track metrics with Alpha Zero 2
2316
2352
  const elapsedMs = Date.now() - requestStartTime;
2317
- this.sessionMetrics.recordMessage(elapsedMs);
2353
+ this.alphaZeroMetrics.recordMessage(elapsedMs);
2318
2354
  if (!responseText?.trim()) {
2319
2355
  display.showWarning('The provider returned an empty response. Check your API key/provider selection or retry the prompt.');
2320
2356
  }
@@ -2332,14 +2368,10 @@ When working in this codebase:
2332
2368
  this.stopStreamingHeartbeat();
2333
2369
  this.isProcessing = false;
2334
2370
  this.terminalInput.setStreaming(false);
2335
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
2336
2371
  this.uiAdapter.endProcessing('Ready for prompts');
2337
2372
  this.setIdleStatus();
2338
2373
  display.newLine();
2339
2374
  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
2375
  queueMicrotask(() => this.uiUpdates.setMode('idle'));
2344
2376
  // CRITICAL: Ensure readline prompt is active for user input
2345
2377
  // Claude Code style: New prompt naturally appears at bottom
@@ -2416,13 +2448,14 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
2416
2448
  try {
2417
2449
  // Send the request and capture the response (streaming disabled)
2418
2450
  display.showThinking('Responding...');
2451
+ this.refreshStatusLine(true);
2419
2452
  const response = await agent.send(currentPrompt, true);
2420
2453
  await this.awaitPendingCleanup();
2421
2454
  this.captureHistorySnapshot();
2422
2455
  this.autosaveIfEnabled();
2423
2456
  // Track metrics
2424
2457
  const elapsedMs = Date.now() - overallStartTime;
2425
- this.sessionMetrics.recordMessage(elapsedMs);
2458
+ this.alphaZeroMetrics.recordMessage(elapsedMs);
2426
2459
  if (!response?.trim()) {
2427
2460
  display.showWarning('Model returned an empty response. Retrying this iteration...');
2428
2461
  consecutiveNoProgress++;
@@ -2559,7 +2592,6 @@ What's the next action?`;
2559
2592
  this.stopStreamingHeartbeat();
2560
2593
  this.isProcessing = false;
2561
2594
  this.terminalInput.setStreaming(false);
2562
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
2563
2595
  this.uiAdapter.endProcessing('Ready for prompts');
2564
2596
  this.setIdleStatus();
2565
2597
  this.updateStatusMessage(null);
@@ -2916,8 +2948,10 @@ What's the next action?`;
2916
2948
  try {
2917
2949
  // Send the error to the agent for fixing
2918
2950
  display.showThinking('Analyzing build errors');
2951
+ this.refreshStatusLine(true);
2919
2952
  const response = await this.agent.send(prompt, true);
2920
2953
  display.stopThinking();
2954
+ this.refreshStatusLine(true);
2921
2955
  if (response) {
2922
2956
  display.showAssistantMessage(response, { isFinal: true });
2923
2957
  }
@@ -2967,18 +3001,16 @@ What's the next action?`;
2967
3001
  display.showAssistantMessage(finalContent, enriched);
2968
3002
  }
2969
3003
  }
2970
- // Show status line at end (Claude Code style: "• Context X% used • Ready for prompts (2s)")
3004
+ // Status shown in mode controls bar - no separate status line needed
2971
3005
  display.stopThinking();
2972
- // Calculate context usage
2973
- let contextInfo;
3006
+ // Update context usage for mode controls display
2974
3007
  if (enriched.contextWindowTokens && metadata.usage) {
2975
3008
  const total = this.totalTokens(metadata.usage);
2976
3009
  if (total && total > 0) {
2977
3010
  const percentage = Math.round((total / enriched.contextWindowTokens) * 100);
2978
- contextInfo = { percentage, tokens: total };
3011
+ this.updateContextUsage(percentage);
2979
3012
  }
2980
3013
  }
2981
- display.showStatusLine('Ready for prompts', enriched.elapsedMs, contextInfo);
2982
3014
  // Auto-verify changes: build first (catches type errors), then tests
2983
3015
  void this.enforceAutoBuild('final-response');
2984
3016
  void this.enforceAutoTests('final-response');
@@ -3048,7 +3080,6 @@ What's the next action?`;
3048
3080
  this.stopStreamingHeartbeat();
3049
3081
  this.updateStatusMessage(null);
3050
3082
  this.terminalInput.setStreaming(false);
3051
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
3052
3083
  this.terminalInput.render();
3053
3084
  },
3054
3085
  onVerificationNeeded: () => {
@@ -3085,7 +3116,6 @@ What's the next action?`;
3085
3116
  resetChatBoxAfterModelSwap() {
3086
3117
  this.updateStatusMessage(null);
3087
3118
  this.terminalInput.setStreaming(false);
3088
- this.terminalInput.setContentEndRow(display.getTotalWrittenLines());
3089
3119
  this.terminalInput.render();
3090
3120
  this.ensureReadlineReady();
3091
3121
  }
@@ -3150,9 +3180,14 @@ What's the next action?`;
3150
3180
  return null;
3151
3181
  }
3152
3182
  const usageRatio = total / windowTokens;
3183
+ this.latestTokenUsage = {
3184
+ used: total,
3185
+ limit: windowTokens,
3186
+ };
3153
3187
  // Always update context usage in the UI
3154
3188
  const percentUsed = Math.round(usageRatio * 100);
3155
3189
  this.updateContextUsage(percentUsed);
3190
+ this.refreshStatusLine(true);
3156
3191
  if (usageRatio < CONTEXT_USAGE_THRESHOLD) {
3157
3192
  return null;
3158
3193
  }
@@ -3430,8 +3465,6 @@ What's the next action?`;
3430
3465
  }
3431
3466
  this.refreshContextGauge();
3432
3467
  display.updateSessionInfo(nextState.model, nextState.provider);
3433
- // Update the persistent model info display in terminal input
3434
- this.terminalInput.setModelInfo(this.describeModelDetail());
3435
3468
  if (!this.isProcessing) {
3436
3469
  this.setIdleStatus();
3437
3470
  }