@leanandmean/coding-agent 0.74.1-scramjet.16 → 0.74.1-scramjet.17

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.
@@ -58,7 +58,7 @@ import { TreeSelectorComponent } from "./components/tree-selector.js";
58
58
  import { UserMessageComponent } from "./components/user-message.js";
59
59
  import { UserMessageSelectorComponent } from "./components/user-message-selector.js";
60
60
  import { NspellProvider } from "./spellcheck.js";
61
- import { classifyBackgroundColor, detectThemeFromEnvironment, getAvailableThemes, getAvailableThemesWithPaths, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
61
+ import { classifyBackgroundColor, detectThemeFromEnvironment, getAvailableThemes, getAvailableThemesWithPaths, getCurrentThemeName, getEditorTheme, getMarkdownTheme, getThemeByName, initTheme, onThemeChange, resolveThemeName, setRegisteredThemes, setTheme, setThemeInstance, stopThemeWatcher, Theme, theme, } from "./theme/theme.js";
62
62
  function isExpandable(obj) {
63
63
  return typeof obj === "object" && obj !== null && "setExpanded" in obj && typeof obj.setExpanded === "function";
64
64
  }
@@ -129,6 +129,9 @@ export class InteractiveMode {
129
129
  workingVisible = true;
130
130
  // SCRAMJET-DIVERGENCE: title provider for extension-owned terminal titles.
131
131
  titleProvider = undefined;
132
+ // SCRAMJET-DIVERGENCE: captured terminal classification (env-seeded in the constructor, updated
133
+ // by the OSC 11 query) used to re-resolve the default theme once extension themes register.
134
+ detectedClassification = undefined;
132
135
  workingIndicatorOptions = undefined;
133
136
  defaultWorkingMessage = "Working...";
134
137
  defaultHiddenThinkingLabel = "Thinking...";
@@ -240,8 +243,32 @@ export class InteractiveMode {
240
243
  this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
241
244
  // Register themes from resource loader and initialize
242
245
  setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
246
+ // SCRAMJET-DIVERGENCE: capture the env classification so the post-extension-bind reapplication
247
+ // can honor COLORFGBG/Apple-Terminal-detected (never-OSC) terminals. Without this seed, those
248
+ // terminals would resolve the dark branch and clobber light terminals to scramjet-dark.
249
+ this.detectedClassification = detectThemeFromEnvironment()?.theme;
243
250
  initTheme(this.settingsManager.getTheme(), true);
244
251
  }
252
+ // SCRAMJET-DIVERGENCE: re-resolve the theme after extension themes register (or after a reload),
253
+ // so scramjet-dark can take effect once it becomes available. An explicit user setting still wins
254
+ // via the resolver; the captured classification (env-seeded + OSC-updated) drives auto-detection.
255
+ // Skips the apply when the resolved name already matches the active theme, unless `force` is set:
256
+ // the reload path forces a re-read from disk (registered extension themes have no file watcher, so
257
+ // /reload is their only refresh path even when the active theme's name is unchanged).
258
+ reapplyResolvedTheme(force = false) {
259
+ const name = resolveThemeName({
260
+ explicitSetting: this.settingsManager.getTheme(),
261
+ detectedClassification: this.detectedClassification,
262
+ hasScramjetDark: getAvailableThemes().includes("scramjet-dark"),
263
+ });
264
+ if (!force && name === getCurrentThemeName()) {
265
+ return;
266
+ }
267
+ const result = setTheme(name, true);
268
+ if (!result.success) {
269
+ this.showError(`Failed to load theme "${name}": ${result.error}\nFell back to pi-dark theme.`);
270
+ }
271
+ }
245
272
  getAutocompleteSourceTag(sourceInfo) {
246
273
  if (!sourceInfo) {
247
274
  return undefined;
@@ -427,10 +454,11 @@ export class InteractiveMode {
427
454
  if (!this.settingsManager.getTheme() && !detectThemeFromEnvironment()) {
428
455
  const rgb = await this.ui.queryTerminalBackgroundColor({ timeoutMs: 100 });
429
456
  if (rgb) {
430
- const detected = classifyBackgroundColor(rgb);
431
- if (detected !== "dark") {
432
- setTheme(detected);
433
- }
457
+ // SCRAMJET-DIVERGENCE: capture the OSC 11 classification and resolve through the shared
458
+ // resolver so a dark terminal maps to scramjet-dark (when available) and a light one to
459
+ // pi-light. Skips the apply when the resolved name is already active.
460
+ this.detectedClassification = classifyBackgroundColor(rgb);
461
+ this.reapplyResolvedTheme();
434
462
  }
435
463
  }
436
464
  // Build themed header content (after theme detection so colors are correct)
@@ -1167,6 +1195,9 @@ export class InteractiveMode {
1167
1195
  },
1168
1196
  });
1169
1197
  setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
1198
+ // SCRAMJET-DIVERGENCE: extension themes (e.g. scramjet-dark) register after the constructor's
1199
+ // initTheme, so re-resolve now that they are available.
1200
+ this.reapplyResolvedTheme();
1170
1201
  this.setupAutocompleteProvider();
1171
1202
  const extensionRunner = this.session.extensionRunner;
1172
1203
  this.setupExtensionShortcuts(extensionRunner);
@@ -3189,7 +3220,8 @@ export class InteractiveMode {
3189
3220
  transport: this.settingsManager.getTransport(),
3190
3221
  thinkingLevel: this.session.thinkingLevel,
3191
3222
  availableThinkingLevels: this.session.getAvailableThinkingLevels(),
3192
- currentTheme: this.settingsManager.getTheme() || "dark",
3223
+ // SCRAMJET-DIVERGENCE: display fallback routed to the renamed builtin.
3224
+ currentTheme: this.settingsManager.getTheme() || "pi-dark",
3193
3225
  availableThemes: getAvailableThemes(),
3194
3226
  hideThinkingBlock: this.hideThinkingBlock,
3195
3227
  collapseChangelog: this.settingsManager.getCollapseChangelog(),
@@ -3254,7 +3286,8 @@ export class InteractiveMode {
3254
3286
  this.settingsManager.setTheme(themeName);
3255
3287
  this.ui.invalidate();
3256
3288
  if (!result.success) {
3257
- this.showError(`Failed to load theme "${themeName}": ${result.error}\nFell back to dark theme.`);
3289
+ // SCRAMJET-DIVERGENCE: fallback message names the renamed builtin.
3290
+ this.showError(`Failed to load theme "${themeName}": ${result.error}\nFell back to pi-dark theme.`);
3258
3291
  }
3259
3292
  },
3260
3293
  onThemePreview: (themeName) => {
@@ -4065,11 +4098,10 @@ export class InteractiveMode {
4065
4098
  }
4066
4099
  setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
4067
4100
  this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
4068
- const themeName = this.settingsManager.getTheme();
4069
- const themeResult = themeName ? setTheme(themeName, true) : { success: true };
4070
- if (!themeResult.success) {
4071
- this.showError(`Failed to load theme "${themeName}": ${themeResult.error}\nFell back to dark theme.`);
4072
- }
4101
+ // SCRAMJET-DIVERGENCE: re-resolve through the resolver after reload so newly registered
4102
+ // themes (and the captured classification) are honored; force a re-read since reload's purpose
4103
+ // is to pick up on-disk theme edits even when the active theme's name is unchanged.
4104
+ this.reapplyResolvedTheme(true);
4073
4105
  const editorPaddingX = this.settingsManager.getEditorPaddingX();
4074
4106
  const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
4075
4107
  this.defaultEditor.setPaddingX(editorPaddingX);