erosolar-cli 2.1.167 → 2.1.169

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.
@@ -134,8 +134,6 @@ export class InteractiveShell {
134
134
  lastContextWarningLevel = null;
135
135
  sessionPreferences;
136
136
  autosaveEnabled;
137
- autoContinueEnabled;
138
- autoContinueEnforced = true;
139
137
  verificationEnabled = false;
140
138
  criticalApprovalMode = 'auto';
141
139
  editGuardMode = 'display-edits';
@@ -162,10 +160,6 @@ export class InteractiveShell {
162
160
  lastUserQuery = '';
163
161
  lastAssistantResponse = null;
164
162
  responseRendered = false;
165
- autoContinueInsightState = {
166
- attempt: 0,
167
- lastMessage: null,
168
- };
169
163
  lastFailure = null;
170
164
  lastAutoTestRun = null;
171
165
  // Auto-build tracking
@@ -209,12 +203,6 @@ export class InteractiveShell {
209
203
  this.sessionPreferences = loadSessionPreferences();
210
204
  this.thinkingMode = this.sessionPreferences.thinkingMode;
211
205
  this.autosaveEnabled = this.sessionPreferences.autosave;
212
- this.autoContinueEnabled = this.sessionPreferences.autoContinue;
213
- if (this.autoContinueEnforced && !this.autoContinueEnabled) {
214
- // Project policy: keep auto-continue locked on to avoid stalls
215
- this.autoContinueEnabled = true;
216
- saveSessionPreferences({ autoContinue: true });
217
- }
218
206
  this.criticalApprovalMode = this.sessionPreferences.criticalApprovalMode;
219
207
  const featureFlags = loadFeatureFlags();
220
208
  this.verificationEnabled = featureFlags.verification === true;
@@ -312,7 +300,6 @@ export class InteractiveShell {
312
300
  onChange: ({ text, cursor }) => this.handleInputChange(text, cursor, 'renderer'),
313
301
  onEditModeChange: (mode) => this.handleEditModeChange(mode),
314
302
  onToggleVerify: () => this.toggleVerificationMode(),
315
- onToggleAutoContinue: () => this.toggleAutoContinueMode(),
316
303
  onToggleThinking: () => this.cycleThinkingMode(),
317
304
  onClearContext: () => this.handleClearContext(),
318
305
  onToggleCriticalApproval: () => this.toggleCriticalApprovalMode('shortcut'),
@@ -818,7 +805,6 @@ export class InteractiveShell {
818
805
  '/output-style',
819
806
  // Mode toggles
820
807
  '/thinking',
821
- '/autocontinue',
822
808
  // Discovery and plugins
823
809
  '/local', '/discover',
824
810
  '/plugins',
@@ -908,65 +894,6 @@ export class InteractiveShell {
908
894
  : '🛡️ High-impact actions now require your approval. (Ctrl+Shift+A to toggle; use /approvals ask to persist)';
909
895
  display.showSystemMessage(message);
910
896
  }
911
- enforceAutoContinuePolicy() {
912
- if (!this.autoContinueEnforced) {
913
- return;
914
- }
915
- if (!this.autoContinueEnabled) {
916
- this.autoContinueEnabled = true;
917
- saveSessionPreferences({ autoContinue: true });
918
- if (this.agent) {
919
- this.agent.setAutoContinue(true);
920
- }
921
- this.refreshControlBar();
922
- }
923
- }
924
- resetAutoContinueInsights() {
925
- this.autoContinueInsightState = { attempt: 0, lastMessage: null };
926
- }
927
- showAutoContinueInsight(attempt, maxAttempts, message) {
928
- const normalized = (message || '').trim();
929
- const isDuplicate = this.autoContinueInsightState.attempt === attempt &&
930
- this.autoContinueInsightState.lastMessage === normalized;
931
- if (isDuplicate) {
932
- return;
933
- }
934
- this.autoContinueInsightState = { attempt, lastMessage: normalized };
935
- const detail = normalized || 'Continuing automatically after intent without action.';
936
- display.showSystemMessage(`Auto-continue ${attempt}/${maxAttempts}: ${detail}`);
937
- }
938
- toggleAutoContinueMode() {
939
- if (this.autoContinueEnforced) {
940
- this.enforceAutoContinuePolicy();
941
- display.showInfo('Auto-continue is enforced ON for erosolar-cli reliability and cannot be disabled.');
942
- return;
943
- }
944
- this.setAutoContinueMode(!this.autoContinueEnabled, 'shortcut');
945
- }
946
- setAutoContinueMode(enabled, source) {
947
- if (this.autoContinueEnforced && !enabled) {
948
- this.enforceAutoContinuePolicy();
949
- if (source === 'command') {
950
- display.showInfo('Auto-continue is enforced ON for erosolar-cli reliability and cannot be disabled.');
951
- }
952
- return;
953
- }
954
- const changed = this.autoContinueEnabled !== enabled;
955
- this.autoContinueEnabled = enabled;
956
- saveSessionPreferences({ autoContinue: this.autoContinueEnabled });
957
- if (this.agent) {
958
- this.agent.setAutoContinue(this.autoContinueEnabled);
959
- }
960
- this.refreshControlBar();
961
- if (!changed && source === 'shortcut') {
962
- return;
963
- }
964
- const modeLabel = this.autoContinueEnabled ? 'enabled' : 'disabled';
965
- const behavior = this.autoContinueEnabled
966
- ? 'The model will be auto-prompted to continue when it expresses intent but does not use tools.'
967
- : 'The model will not be auto-prompted to continue.';
968
- display.showInfo(`Auto-continue ${modeLabel}. ${behavior} Toggle with Ctrl+Shift+C.`);
969
- }
970
897
  /**
971
898
  * Expand the last tool result (Ctrl+O shortcut).
972
899
  * Shows the full output from the most recent tool call.
@@ -1712,9 +1639,7 @@ export class InteractiveShell {
1712
1639
  refreshControlBar() {
1713
1640
  this.terminalInput.setModeToggles({
1714
1641
  verificationEnabled: this.verificationEnabled,
1715
- autoContinueEnabled: this.autoContinueEnabled,
1716
1642
  verificationHotkey: 'ctrl+shift+v',
1717
- autoContinueHotkey: 'ctrl+shift+c',
1718
1643
  thinkingModeLabel: (this.thinkingMode || 'off').toString(),
1719
1644
  thinkingHotkey: 'tab',
1720
1645
  criticalApprovalMode: this.criticalApprovalMode,
@@ -2493,9 +2418,6 @@ export class InteractiveShell {
2493
2418
  case '/thinking':
2494
2419
  this.handleThinkingCommand(input);
2495
2420
  break;
2496
- case '/autocontinue':
2497
- this.handleAutoContinueCommand(input);
2498
- break;
2499
2421
  case '/shortcuts':
2500
2422
  case '/keys':
2501
2423
  this.handleShortcutsCommand();
@@ -2659,7 +2581,6 @@ export class InteractiveShell {
2659
2581
  theme.bold(' Mode Toggles'),
2660
2582
  ` ${theme.info('Shift+Tab')} ${theme.ui.muted('Toggle edit mode (auto/ask)')}`,
2661
2583
  ` ${theme.info('Option+V')} ${theme.ui.muted('Toggle verification')}`,
2662
- ` ${theme.info('Option+C')} ${theme.ui.muted('Toggle auto-continue')}`,
2663
2584
  ` ${theme.info('Ctrl+Shift+A')} ${theme.ui.muted('Toggle approvals for high-impact actions')}`,
2664
2585
  ` ${theme.info('Option+T')} ${theme.ui.muted('Cycle thinking mode')}`,
2665
2586
  ` ${theme.info('Option+E')} ${theme.ui.muted('Toggle edit permission mode')}`,
@@ -4373,28 +4294,6 @@ export class InteractiveShell {
4373
4294
  clearAutosaveSnapshot(this.profile);
4374
4295
  display.showInfo('Cleared autosave history.');
4375
4296
  }
4376
- handleAutoContinueCommand(input) {
4377
- const tokens = input.split(/\s+/).slice(1);
4378
- const value = tokens[0]?.toLowerCase();
4379
- if (!value) {
4380
- // Show current status
4381
- const lockedNote = this.autoContinueEnforced
4382
- ? ' (locked ON for erosolar-cli reliability)'
4383
- : ' Use /autocontinue on|off or Ctrl+Shift+C to toggle.';
4384
- display.showInfo(`Auto-continue is ${this.autoContinueEnabled ? 'enabled' : 'disabled'}.${lockedNote}`);
4385
- return;
4386
- }
4387
- if (value !== 'on' && value !== 'off') {
4388
- display.showWarning('Usage: /autocontinue on|off');
4389
- return;
4390
- }
4391
- if (value === 'off' && this.autoContinueEnforced) {
4392
- this.enforceAutoContinuePolicy();
4393
- display.showInfo('Auto-continue is enforced ON for erosolar-cli reliability and cannot be disabled.');
4394
- return;
4395
- }
4396
- this.setAutoContinueMode(value === 'on', 'command');
4397
- }
4398
4297
  // ==================== Erosolar-CLI Style Commands ====================
4399
4298
  async handleRewindCommand(_input) {
4400
4299
  const lines = [];
@@ -4626,9 +4525,6 @@ export class InteractiveShell {
4626
4525
  lines.push(`${theme.primary('Provider/Model')}: ${theme.info(`${this.providerLabel(this.sessionState.provider)} · ${this.sessionState.model}`)}`);
4627
4526
  lines.push(`${theme.primary('Workspace')}: ${theme.ui.muted(this.abbreviatePath(this.workingDir))}`);
4628
4527
  lines.push(`${theme.primary('Autosave')}: ${this.autosaveEnabled ? theme.success('on') : theme.ui.muted('off')}`);
4629
- const autoContinueStatus = this.autoContinueEnabled ? 'on' : 'off';
4630
- const autoContinueLabel = this.autoContinueEnforced ? `${autoContinueStatus} (locked)` : autoContinueStatus;
4631
- lines.push(`${theme.primary('Auto-continue')}: ${this.autoContinueEnabled ? theme.success(autoContinueLabel) : theme.ui.muted(autoContinueLabel)}`);
4632
4528
  lines.push(`${theme.primary('Verification')}: ${this.verificationEnabled ? theme.success('on') : theme.ui.muted('off')}`);
4633
4529
  lines.push(`${theme.primary('Approvals')}: ${theme.ui.muted(this.describeEditGuardMode())}`);
4634
4530
  lines.push(`${theme.primary('Critical approvals')}: ${this.criticalApprovalMode === 'approval' ? theme.warning('ask') : theme.ui.muted('auto')}`);
@@ -5840,9 +5736,6 @@ export class InteractiveShell {
5840
5736
  this.clearInlinePanel();
5841
5737
  this.syncRendererInput();
5842
5738
  }
5843
- // NOTE: emitPromptAcknowledgement has been removed - acknowledgement is now handled
5844
- // by the onRequestReceived callback in agent.send(), which fires IMMEDIATELY when
5845
- // the request is received, guaranteeing instant user feedback before any processing.
5846
5739
  async processRequest(request) {
5847
5740
  if (this.isProcessing) {
5848
5741
  this.enqueueFollowUpAction({ type: 'request', text: request });
@@ -5858,8 +5751,6 @@ export class InteractiveShell {
5858
5751
  if (!agent) {
5859
5752
  return;
5860
5753
  }
5861
- this.enforceAutoContinuePolicy();
5862
- this.resetAutoContinueInsights();
5863
5754
  this.runtimeSession.toolRuntime.clearDiffSnapshots?.();
5864
5755
  if (this.suppressNextNetworkReset) {
5865
5756
  this.suppressNextNetworkReset = false;
@@ -5889,8 +5780,6 @@ export class InteractiveShell {
5889
5780
  this.currentTaskType = classifyTaskType(request);
5890
5781
  this.currentToolCalls = [];
5891
5782
  this.clearToolUsageMeta();
5892
- // NOTE: Acknowledgement is now handled by onRequestReceived callback in agent.send()
5893
- // This fires IMMEDIATELY when the request is received, before any provider call
5894
5783
  this.renderer?.setActivity('Starting...');
5895
5784
  this.uiAdapter.startProcessing('Working on your request');
5896
5785
  this.setProcessingStatus();
@@ -6013,8 +5902,6 @@ export class InteractiveShell {
6013
5902
  if (!agent) {
6014
5903
  return;
6015
5904
  }
6016
- this.enforceAutoContinuePolicy();
6017
- this.resetAutoContinueInsights();
6018
5905
  this.lastUserQuery = initialRequest;
6019
5906
  this.clearToolUsageMeta();
6020
5907
  this.isProcessing = true;
@@ -6037,7 +5924,6 @@ export class InteractiveShell {
6037
5924
  completionDetector.reset();
6038
5925
  // Display user prompt in scrollback (Claude Code style)
6039
5926
  this.logUserPrompt(initialRequest);
6040
- // NOTE: Acknowledgement is now handled by onRequestReceived callback in agent.send()
6041
5927
  display.showSystemMessage(`Continuous mode active. Ctrl+C to stop.`);
6042
5928
  this.uiAdapter.startProcessing('Continuous execution mode');
6043
5929
  this.setProcessingStatus();
@@ -6074,8 +5960,6 @@ When truly finished with ALL tasks, explicitly state "TASK_FULLY_COMPLETE".`;
6074
5960
  // Send the request and capture the response (streaming disabled)
6075
5961
  display.showThinking('Responding...');
6076
5962
  this.refreshStatusLine(true);
6077
- this.enforceAutoContinuePolicy();
6078
- this.resetAutoContinueInsights();
6079
5963
  const response = await agent.send(currentPrompt, true);
6080
5964
  this.finishStreamingFormatter(undefined, { refreshPrompt: false, mode: 'complete' });
6081
5965
  await this.awaitPendingCleanup();
@@ -6782,8 +6666,6 @@ Return ONLY JSON array:
6782
6666
  // Send the error to the agent for fixing
6783
6667
  display.showThinking('Analyzing build errors');
6784
6668
  this.refreshStatusLine(true);
6785
- this.enforceAutoContinuePolicy();
6786
- this.resetAutoContinueInsights();
6787
6669
  const response = await this.agent.send(prompt, true);
6788
6670
  display.stopThinking();
6789
6671
  this.refreshStatusLine(true);
@@ -6803,7 +6685,6 @@ Return ONLY JSON array:
6803
6685
  rebuildAgent() {
6804
6686
  try {
6805
6687
  ensureSecretForProvider(this.sessionState.provider);
6806
- this.enforceAutoContinuePolicy();
6807
6688
  this.runtimeSession.updateToolContext(this.sessionState);
6808
6689
  this.ensureActiveSummarizer(this.runtimeSession.contextManager);
6809
6690
  const selection = {
@@ -6813,16 +6694,26 @@ Return ONLY JSON array:
6813
6694
  maxTokens: this.sessionState.maxTokens,
6814
6695
  systemPrompt: this.buildSystemPrompt(),
6815
6696
  reasoningEffort: this.sessionState.reasoningEffort,
6816
- autoContinue: this.autoContinueEnabled,
6817
6697
  };
6818
6698
  this.agent = this.runtimeSession.createAgent(selection, {
6699
+ onRequestReceived: (requestPreview) => {
6700
+ const normalized = requestPreview?.trim();
6701
+ const activity = normalized ? `Working: ${normalized}` : 'Working';
6702
+ this.renderer?.setActivity(activity);
6703
+ },
6704
+ onBeforeFirstToolCall: (toolNames) => {
6705
+ const primaryTool = toolNames[0];
6706
+ if (primaryTool) {
6707
+ this.renderer?.setActivity(`Running ${primaryTool}`);
6708
+ }
6709
+ return undefined;
6710
+ },
6819
6711
  onStreamChunk: (chunk, type) => {
6820
6712
  this.handleStreamChunk(chunk, type ?? 'content');
6821
6713
  },
6822
6714
  onAssistantMessage: (content, metadata) => {
6823
6715
  const enriched = this.buildDisplayMetadata(metadata);
6824
6716
  const streamedVisible = metadata.wasStreamed && this.streamingContentSeen && !this.streamingOutputSuppressed;
6825
- const displaySuppressed = metadata.suppressDisplay === true;
6826
6717
  let renderedFinal = false;
6827
6718
  // Update streaming token count from usage info (more accurate than chunk counting)
6828
6719
  if (metadata.usage) {
@@ -6842,16 +6733,14 @@ Return ONLY JSON array:
6842
6733
  // Show the response if it wasn't already rendered during streaming
6843
6734
  if (!streamedVisible) {
6844
6735
  if (thoughtContent) {
6845
- if (!displaySuppressed) {
6846
- const summary = this.extractThoughtSummary(thoughtContent);
6847
- if (summary) {
6848
- display.updateThinking(`💭 ${summary}`);
6849
- }
6850
- display.showAssistantMessage(thoughtContent, { ...enriched, isFinal: false });
6851
- renderedFinal = true;
6736
+ const summary = this.extractThoughtSummary(thoughtContent);
6737
+ if (summary) {
6738
+ display.updateThinking(`💭 ${summary}`);
6852
6739
  }
6740
+ display.showAssistantMessage(thoughtContent, { ...enriched, isFinal: false });
6741
+ renderedFinal = true;
6853
6742
  }
6854
- if (finalContent && !displaySuppressed) {
6743
+ if (finalContent) {
6855
6744
  display.showAssistantMessage(finalContent, enriched);
6856
6745
  renderedFinal = true;
6857
6746
  }
@@ -6869,7 +6758,7 @@ Return ONLY JSON array:
6869
6758
  this.updateContextUsage(percentage);
6870
6759
  }
6871
6760
  }
6872
- if (finalContent && !displaySuppressed) {
6761
+ if (finalContent) {
6873
6762
  this.lastAssistantResponse = finalContent;
6874
6763
  }
6875
6764
  // Track thought + response as a single response event for telemetry
@@ -6891,7 +6780,7 @@ Return ONLY JSON array:
6891
6780
  // Stop spinner and show the narrative text directly
6892
6781
  display.stopThinking();
6893
6782
  // Skip display if content was already streamed to avoid double-display
6894
- if (!streamedVisible && !displaySuppressed) {
6783
+ if (!streamedVisible) {
6895
6784
  const narrative = content.trim();
6896
6785
  if (narrative) {
6897
6786
  display.showNarrative(narrative);
@@ -6942,11 +6831,6 @@ Return ONLY JSON array:
6942
6831
  this.updateStatusMessage('Retrying with reduced context...');
6943
6832
  this.syncRendererInput();
6944
6833
  },
6945
- onAutoContinue: (attempt, maxAttempts, message) => {
6946
- // Surface insight about why auto-continue fired while keeping UX responsive
6947
- this.renderer?.setActivity('Continuing...');
6948
- this.showAutoContinueInsight(attempt, maxAttempts, message);
6949
- },
6950
6834
  onCancelled: () => {
6951
6835
  // Update UI to show operation was cancelled
6952
6836
  display.showWarning('Operation cancelled.');
@@ -6981,48 +6865,11 @@ Return ONLY JSON array:
6981
6865
  this.renderer?.setActivity('Thinking');
6982
6866
  }
6983
6867
  },
6984
- onBeforeFirstToolCall: (toolNames, hasModelNarration) => {
6985
- // ALWAYS inject acknowledgement - even if model provided narration
6986
- // This ensures user always sees immediate feedback that their request was received
6987
- // The acknowledgement appears BEFORE any tool output
6988
- const primaryTool = toolNames[0] || 'tools';
6989
- const toolDescriptions = {
6990
- 'list_files': 'Looking at the project files...',
6991
- 'Glob': 'Searching for files...',
6992
- 'read_file': 'Reading the file...',
6993
- 'Read': 'Reading the file...',
6994
- 'execute_bash': 'Running command...',
6995
- 'Bash': 'Running command...',
6996
- 'grep_search': 'Searching the code...',
6997
- 'Grep': 'Searching the code...',
6998
- 'write_file': 'Writing the file...',
6999
- 'Write': 'Writing the file...',
7000
- 'edit_file': 'Editing the file...',
7001
- 'Edit': 'Editing the file...',
7002
- 'WebFetch': 'Fetching web content...',
7003
- 'WebSearch': 'Searching the web...',
7004
- 'Task': 'Starting task...',
7005
- };
7006
- // Return acknowledgement regardless of hasModelNarration
7007
- // If model provided narration, it will appear after this acknowledgement
7008
- return toolDescriptions[primaryTool] || 'Running tools to advance your request...';
7009
- },
7010
6868
  onVerificationNeeded: (response, context) => {
7011
6869
  this.lastAssistantResponse = response;
7012
6870
  void this.runAutoQualityChecks('verification', response, context);
7013
6871
  },
7014
- // NEW: Immediate acknowledgement when request is received (BEFORE provider call)
7015
- onRequestReceived: (requestPreview) => {
7016
- // This fires IMMEDIATELY when user submits request, guaranteeing instant feedback
7017
- // The message appears before any AI processing begins
7018
- const normalized = requestPreview?.trim();
7019
- const message = normalized
7020
- ? `⚡ Acknowledged — focusing on "${normalized}" and acting now.`
7021
- : '⚡ Acknowledged — acting now.';
7022
- display.showAssistantMessage(message, { isFinal: false });
7023
- this.renderer?.setActivity('Acknowledged');
7024
- },
7025
- // NEW: Retry notification for transient errors
6872
+ // Retry notification for transient errors
7026
6873
  onRetrying: (attempt, maxAttempts, error) => {
7027
6874
  const shortError = error.message.slice(0, 100);
7028
6875
  display.showSystemMessage(`⚡ Retry ${attempt}/${maxAttempts}: ${shortError}${error.message.length > 100 ? '...' : ''}`);