@oh-my-pi/pi-tui 16.3.12 → 16.3.13

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/CHANGELOG.md CHANGED
@@ -2,6 +2,13 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [16.3.13] - 2026-07-09
6
+
7
+ ### Fixed
8
+
9
+ - Fixed late terminal appearance subscribers missing the already-detected OSC 11 light/dark result, so theme auto-detection picks up the terminal appearance even when the response arrives before the UI subscribes ([#4731](https://github.com/can1357/oh-my-pi/issues/4731)).
10
+ - Fixed slash command Tab completion reopening the file autocomplete drawer after accepting no-argument commands ([#4808](https://github.com/can1357/oh-my-pi/issues/4808)).
11
+
5
12
  ## [16.3.12] - 2026-07-08
6
13
 
7
14
  ### Fixed
@@ -59,6 +59,8 @@ export interface Terminal {
59
59
  * Register a callback for terminal appearance (dark/light) changes.
60
60
  * Detection uses OSC 11 background color query with Mode 2031 as a change trigger.
61
61
  * Fires when the detected appearance changes, including the initial detection.
62
+ * Subscribers registered after detection are invoked immediately with the
63
+ * already-detected appearance so late subscribers never miss it.
62
64
  */
63
65
  onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void;
64
66
  /** The last detected terminal appearance, or undefined if not yet known. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "type": "module",
3
3
  "name": "@oh-my-pi/pi-tui",
4
- "version": "16.3.12",
4
+ "version": "16.3.13",
5
5
  "description": "Terminal User Interface library with differential rendering for efficient text-based applications",
6
6
  "homepage": "https://omp.sh",
7
7
  "author": "Can Boluk",
@@ -37,8 +37,8 @@
37
37
  "fmt": "biome format --write ."
38
38
  },
39
39
  "dependencies": {
40
- "@oh-my-pi/pi-natives": "16.3.12",
41
- "@oh-my-pi/pi-utils": "16.3.12",
40
+ "@oh-my-pi/pi-natives": "16.3.13",
41
+ "@oh-my-pi/pi-utils": "16.3.13",
42
42
  "lru-cache": "11.5.1",
43
43
  "marked": "^18.0.5"
44
44
  },
@@ -437,6 +437,9 @@ export class CombinedAutocompleteProvider implements AutocompleteProvider {
437
437
  const argumentText = commandText.slice(spaceIndex + 1); // Text after space
438
438
 
439
439
  const command = this.#commands.find(cmd => commandMatchesNameOrAlias(cmd, commandName));
440
+ if (command && "allowArgs" in command && command.allowArgs === false && !/\S/.test(argumentText)) {
441
+ return null;
442
+ }
440
443
  if (command && (!("allowArgs" in command) || command.allowArgs !== false)) {
441
444
  if (!("getArgumentCompletions" in command) || !command.getArgumentCompletions) {
442
445
  return null; // No argument completion for this command
package/src/terminal.ts CHANGED
@@ -382,6 +382,8 @@ export interface Terminal {
382
382
  * Register a callback for terminal appearance (dark/light) changes.
383
383
  * Detection uses OSC 11 background color query with Mode 2031 as a change trigger.
384
384
  * Fires when the detected appearance changes, including the initial detection.
385
+ * Subscribers registered after detection are invoked immediately with the
386
+ * already-detected appearance so late subscribers never miss it.
385
387
  */
386
388
  onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void;
387
389
  /** The last detected terminal appearance, or undefined if not yet known. */
@@ -516,6 +518,17 @@ export class ProcessTerminal implements Terminal {
516
518
 
517
519
  onAppearanceChange(callback: (appearance: TerminalAppearance) => void): void {
518
520
  this.#appearanceCallbacks.push(callback);
521
+ // Replay an already-detected appearance: the startup OSC 11 response can
522
+ // arrive before consumers (e.g. the theme bridge) subscribe, and the
523
+ // dedup in #handleOsc11Response would otherwise suppress the value for
524
+ // them forever (#4731).
525
+ if (this.#appearance) {
526
+ try {
527
+ callback(this.#appearance);
528
+ } catch {
529
+ /* ignore callback errors */
530
+ }
531
+ }
519
532
  }
520
533
 
521
534
  onPrivateModeReport(callback: (mode: number, supported: boolean) => void): void {
@@ -704,7 +717,10 @@ export class ProcessTerminal implements Terminal {
704
717
  const decrpmResponsePattern = /^\x1b\[\?(\d+);(\d+)\$y$/;
705
718
 
706
719
  // In-band resize report (DEC mode 2048): \x1b[48;rows;cols;yPixels;xPixels t
707
- const inBandResizePattern = /^\x1b\[48;(\d+);(\d+);(\d+);(\d+)t$/;
720
+ // Any field may carry `:`-separated subparameters, which clients MUST
721
+ // ignore per spec (#4748): capture the leading digits of each field and
722
+ // skip the subparameter tail instead of dropping the whole report.
723
+ const inBandResizePattern = /^\x1b\[48;(\d+)(?::[\d:]*)?;(\d+)(?::[\d:]*)?;(\d+)(?::[\d:]*)?;(\d+)(?::[\d:]*)?t$/;
708
724
 
709
725
  this.#stdinBuffer.on("data", (sequence: string) => {
710
726
  // Fast path for plain-text bytes: every escape-probe regex below
@@ -776,7 +792,7 @@ export class ProcessTerminal implements Terminal {
776
792
  // reassembled sequence that turns out not to be a resize report (e.g. a
777
793
  // split kitty `\x1b[48;…u` for a digit key) is forwarded to the input
778
794
  // handler rather than dropped.
779
- const inBandResizePartialPattern = /^\x1b\[4[\d;]*$/;
795
+ const inBandResizePartialPattern = /^\x1b\[4[\d;:]*$/;
780
796
  const isInBandResizePartial = this.#inBandResizeActive && inBandResizePartialPattern.test(sequence);
781
797
  if (this.#inBandResizeBuffer && sequence.startsWith("\x1b")) {
782
798
  // A new escape interrupted the partial; the stale partial is
@@ -1185,9 +1201,9 @@ export class ProcessTerminal implements Terminal {
1185
1201
  * `rows` before the `resize` event fires, so they are authoritative for the
1186
1202
  * new cell geometry. A cached DEC 2048 report can be stale: the matching
1187
1203
  * post-resize report may be dropped (split across stdin reads past the flush
1188
- * window) or carry `:`-subparameters the parser skips, leaving the getters
1189
- * pinned to the old size — which freezes the rendered width because the
1190
- * renderer reflows against {@link columns}/{@link rows}, not the live OS
1204
+ * window, or interrupted by another escape mid-reassembly), leaving the
1205
+ * getters pinned to the old size — which freezes the rendered width because
1206
+ * the renderer reflows against {@link columns}/{@link rows}, not the live OS
1191
1207
  * value. Drop a cached dimension that disagrees with the live OS value; the
1192
1208
  * terminal's next valid in-band report re-seeds pixel sizing.
1193
1209
  */