@oh-my-pi/pi-coding-agent 13.3.9 → 13.3.10

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.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-coding-agent",
4
- "version": "13.3.9",
4
+ "version": "13.3.10",
5
5
  "description": "Coding agent CLI with read, bash, edit, write tools and session management",
6
6
  "homepage": "https://github.com/can1357/oh-my-pi",
7
7
  "author": "Can Boluk",
@@ -41,12 +41,12 @@
41
41
  },
42
42
  "dependencies": {
43
43
  "@mozilla/readability": "^0.6",
44
- "@oh-my-pi/omp-stats": "13.3.9",
45
- "@oh-my-pi/pi-agent-core": "13.3.9",
46
- "@oh-my-pi/pi-ai": "13.3.9",
47
- "@oh-my-pi/pi-natives": "13.3.9",
48
- "@oh-my-pi/pi-tui": "13.3.9",
49
- "@oh-my-pi/pi-utils": "13.3.9",
44
+ "@oh-my-pi/omp-stats": "13.3.10",
45
+ "@oh-my-pi/pi-agent-core": "13.3.10",
46
+ "@oh-my-pi/pi-ai": "13.3.10",
47
+ "@oh-my-pi/pi-natives": "13.3.10",
48
+ "@oh-my-pi/pi-tui": "13.3.10",
49
+ "@oh-my-pi/pi-utils": "13.3.10",
50
50
  "@sinclair/typebox": "^0.34",
51
51
  "@xterm/headless": "^6.0",
52
52
  "ajv": "^8.18",
@@ -1,9 +1,11 @@
1
1
  import * as fs from "node:fs";
2
2
  import * as path from "node:path";
3
3
  import {
4
+ detectMacOSAppearance,
4
5
  type HighlightColors as NativeHighlightColors,
5
6
  highlightCode as nativeHighlightCode,
6
7
  supportsLanguage as nativeSupportsLanguage,
8
+ startMacAppearanceObserver as startNativeMacObserver,
7
9
  } from "@oh-my-pi/pi-natives";
8
10
  import type { EditorTheme, MarkdownTheme, SelectListTheme, SymbolTheme } from "@oh-my-pi/pi-tui";
9
11
  import { adjustHsv, getCustomThemesDir, isEnoent, logger } from "@oh-my-pi/pi-utils";
@@ -1619,11 +1621,21 @@ export async function getThemeByName(name: string): Promise<Theme | undefined> {
1619
1621
  /** Appearance reported by Mode 2031 (terminal DSR), or undefined if not (yet) available. */
1620
1622
  var terminalReportedAppearance: "dark" | "light" | undefined;
1621
1623
 
1624
+ /** Appearance reported by native macOS observer, or undefined if not (yet) available. */
1625
+ var macOSReportedAppearance: "dark" | "light" | undefined;
1626
+
1622
1627
  function detectTerminalBackground(): "dark" | "light" {
1623
1628
  // Prefer terminal-reported appearance from Mode 2031 (CSI ? 997 ; {1,2} n)
1624
1629
  if (terminalReportedAppearance) {
1625
1630
  return terminalReportedAppearance;
1626
1631
  }
1632
+ // macOS: query system appearance via CoreFoundation (native, no shell).
1633
+ // Uses cached observer value, or falls back to CFPreferencesCopyAppValue.
1634
+ // Works on all terminals including Warp which lacks Mode 2031 / OSC 11.
1635
+ const macAppearance = macOSReportedAppearance ?? detectMacOSAppearance();
1636
+ if (macAppearance) {
1637
+ return macAppearance;
1638
+ }
1627
1639
  // Fallback: COLORFGBG environment variable (static, set once at terminal launch)
1628
1640
  const colorfgbg = Bun.env.COLORFGBG || "";
1629
1641
  if (colorfgbg) {
@@ -1763,19 +1775,7 @@ export async function previewTheme(name: string): Promise<{ success: boolean; er
1763
1775
  */
1764
1776
  export function enableAutoTheme(): void {
1765
1777
  autoDetectedTheme = true;
1766
- const resolved = getDefaultTheme();
1767
- if (resolved === currentThemeName) return;
1768
- currentThemeName = resolved;
1769
- loadTheme(resolved, getCurrentThemeOptions())
1770
- .then(loadedTheme => {
1771
- theme = loadedTheme;
1772
- if (onThemeChangeCallback) {
1773
- onThemeChangeCallback();
1774
- }
1775
- })
1776
- .catch(err => {
1777
- logger.debug("Auto theme switch failed", { error: String(err) });
1778
- });
1778
+ reevaluateAutoTheme("enableAutoTheme");
1779
1779
  }
1780
1780
 
1781
1781
  /**
@@ -1785,20 +1785,7 @@ export function enableAutoTheme(): void {
1785
1785
  export function setAutoThemeMapping(mode: "dark" | "light", themeName: string): void {
1786
1786
  if (mode === "dark") autoDarkTheme = themeName;
1787
1787
  else autoLightTheme = themeName;
1788
- if (!autoDetectedTheme) return;
1789
- const resolved = getDefaultTheme();
1790
- if (resolved === currentThemeName) return;
1791
- currentThemeName = resolved;
1792
- loadTheme(resolved, getCurrentThemeOptions())
1793
- .then(loadedTheme => {
1794
- theme = loadedTheme;
1795
- if (onThemeChangeCallback) {
1796
- onThemeChangeCallback();
1797
- }
1798
- })
1799
- .catch(err => {
1800
- logger.debug("Auto theme mapping switch failed", { error: String(err) });
1801
- });
1788
+ reevaluateAutoTheme("setAutoThemeMapping");
1802
1789
  }
1803
1790
 
1804
1791
  /**
@@ -1810,20 +1797,7 @@ export function setAutoThemeMapping(mode: "dark" | "light", themeName: string):
1810
1797
  export function onTerminalAppearanceChange(mode: "dark" | "light"): void {
1811
1798
  if (terminalReportedAppearance === mode) return;
1812
1799
  terminalReportedAppearance = mode;
1813
- if (!autoDetectedTheme) return;
1814
- const resolved = getDefaultTheme();
1815
- if (resolved === currentThemeName) return;
1816
- currentThemeName = resolved;
1817
- loadTheme(resolved, getCurrentThemeOptions())
1818
- .then(loadedTheme => {
1819
- theme = loadedTheme;
1820
- if (onThemeChangeCallback) {
1821
- onThemeChangeCallback();
1822
- }
1823
- })
1824
- .catch(err => {
1825
- logger.debug("Mode 2031 appearance switch failed", { error: String(err) });
1826
- });
1800
+ reevaluateAutoTheme("Mode 2031");
1827
1801
  }
1828
1802
 
1829
1803
  export function setThemeInstance(themeInstance: Theme): void {
@@ -1969,26 +1943,68 @@ async function startThemeWatcher(): Promise<void> {
1969
1943
  }
1970
1944
  }
1971
1945
 
1972
- /** Re-check COLORFGBG on SIGWINCH and switch dark/light when using auto-detected theme. */
1946
+ /**
1947
+ * Shared logic for re-evaluating the auto-detected theme.
1948
+ * Called from SIGWINCH, macOS observer, and Mode 2031 handler.
1949
+ */
1950
+ function reevaluateAutoTheme(debugLabel: string): void {
1951
+ if (!autoDetectedTheme) return;
1952
+ const resolved = getDefaultTheme();
1953
+ if (resolved === currentThemeName) return;
1954
+ currentThemeName = resolved;
1955
+ loadTheme(resolved, getCurrentThemeOptions())
1956
+ .then(loadedTheme => {
1957
+ theme = loadedTheme;
1958
+ if (onThemeChangeCallback) {
1959
+ onThemeChangeCallback();
1960
+ }
1961
+ })
1962
+ .catch(err => {
1963
+ logger.debug(`Theme switch on ${debugLabel} failed`, { error: String(err) });
1964
+ });
1965
+ }
1966
+
1967
+ // ============================================================================
1968
+ // macOS Appearance Observer
1969
+ // ============================================================================
1970
+
1971
+ var macObserver: { stop(): void } | undefined;
1972
+
1973
+ /** Start the native macOS appearance observer (CFDistributedNotificationCenter). */
1974
+ function startMacAppearanceObserver(): void {
1975
+ stopMacAppearanceObserver();
1976
+ if (process.platform !== "darwin") return;
1977
+ try {
1978
+ macObserver = startNativeMacObserver(appearance => {
1979
+ macOSReportedAppearance = appearance;
1980
+ if (!terminalReportedAppearance) reevaluateAutoTheme("macOS observer");
1981
+ });
1982
+ } catch (err) {
1983
+ logger.warn("Failed to start macOS appearance observer", { err });
1984
+ }
1985
+ }
1986
+
1987
+ function stopMacAppearanceObserver(): void {
1988
+ if (macObserver) {
1989
+ macObserver.stop();
1990
+ macObserver = undefined;
1991
+ }
1992
+ macOSReportedAppearance = undefined;
1993
+ }
1994
+
1995
+ // ============================================================================
1996
+ // SIGWINCH Listener
1997
+ // ============================================================================
1998
+
1999
+ /** Re-check appearance on SIGWINCH and switch dark/light when using auto-detected theme. */
1973
2000
  function startSigwinchListener(): void {
1974
2001
  stopSigwinchListener();
1975
2002
  sigwinchHandler = () => {
1976
- if (!autoDetectedTheme) return;
1977
- const resolved = getDefaultTheme();
1978
- if (resolved === currentThemeName) return;
1979
- currentThemeName = resolved;
1980
- loadTheme(resolved, getCurrentThemeOptions())
1981
- .then(loadedTheme => {
1982
- theme = loadedTheme;
1983
- if (onThemeChangeCallback) {
1984
- onThemeChangeCallback();
1985
- }
1986
- })
1987
- .catch(err => {
1988
- logger.debug("Theme switch on SIGWINCH failed", { error: String(err) });
1989
- });
2003
+ reevaluateAutoTheme("SIGWINCH");
1990
2004
  };
1991
2005
  process.on("SIGWINCH", sigwinchHandler);
2006
+ // Start macOS appearance observer alongside SIGWINCH listener.
2007
+ startMacAppearanceObserver();
1992
2008
  }
1993
2009
 
1994
2010
  function stopSigwinchListener(): void {
@@ -1996,6 +2012,7 @@ function stopSigwinchListener(): void {
1996
2012
  process.removeListener("SIGWINCH", sigwinchHandler);
1997
2013
  sigwinchHandler = undefined;
1998
2014
  }
2015
+ stopMacAppearanceObserver();
1999
2016
  }
2000
2017
 
2001
2018
  export function stopThemeWatcher(): void {