pi-sync-system-theme 0.2.0 → 0.2.2
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/README.md +37 -1
- package/index.ts +23 -9
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,6 +33,17 @@ pi install npm:pi-sync-system-theme
|
|
|
33
33
|
> pi remove npm:pi-system-theme
|
|
34
34
|
> ```
|
|
35
35
|
|
|
36
|
+
## Package rename migration
|
|
37
|
+
|
|
38
|
+
This package was renamed from `pi-system-theme-ssh-bridge` to `pi-sync-system-theme`.
|
|
39
|
+
|
|
40
|
+
If you installed the old package name, run:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pi remove npm:pi-system-theme-ssh-bridge
|
|
44
|
+
pi install npm:pi-sync-system-theme
|
|
45
|
+
```
|
|
46
|
+
|
|
36
47
|
## Configuration
|
|
37
48
|
|
|
38
49
|
Use the `/system-theme` command inside pi to configure:
|
|
@@ -67,6 +78,30 @@ For environments where neither OSC 11 nor OS detection works, you can push an ov
|
|
|
67
78
|
}
|
|
68
79
|
```
|
|
69
80
|
|
|
81
|
+
## ⚠️ Performance tuning notes (important)
|
|
82
|
+
|
|
83
|
+
This extension queries terminal background color (OSC 11) in SSH/tmux sessions. Aggressive polling can cause terminal artifacts (garbled startup output) or input lag on some terminal/SSH combinations.
|
|
84
|
+
|
|
85
|
+
Recommended ranges:
|
|
86
|
+
|
|
87
|
+
- `pollMs`: **3000–8000** (default `8000`)
|
|
88
|
+
- `PI_SYSTEM_THEME_OSC11_MIN_INTERVAL_MS`: **8000–15000** (default `15000`)
|
|
89
|
+
|
|
90
|
+
Avoid overly aggressive values unless you have tested your environment thoroughly:
|
|
91
|
+
|
|
92
|
+
- `pollMs < 2000`
|
|
93
|
+
- `PI_SYSTEM_THEME_OSC11_MIN_INTERVAL_MS < 5000`
|
|
94
|
+
|
|
95
|
+
If you notice lag, slash-command stutter, or startup artifacts:
|
|
96
|
+
|
|
97
|
+
1. Increase `pollMs`
|
|
98
|
+
2. Increase `PI_SYSTEM_THEME_OSC11_MIN_INTERVAL_MS`
|
|
99
|
+
3. Temporarily disable OSC11 probing with:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
export PI_SYSTEM_THEME_OSC11_ENABLED=0
|
|
103
|
+
```
|
|
104
|
+
|
|
70
105
|
## Environment variables
|
|
71
106
|
|
|
72
107
|
| Variable | Default | Description |
|
|
@@ -74,13 +109,14 @@ For environments where neither OSC 11 nor OS detection works, you can push an ov
|
|
|
74
109
|
| `PI_SYSTEM_THEME_OVERRIDE_FILE` | `~/.pi/agent/system-theme-override.json` | Override file path |
|
|
75
110
|
| `PI_SYSTEM_THEME_OVERRIDE_MAX_AGE_MS` | `60000` | Max age before override is considered stale |
|
|
76
111
|
| `PI_SYSTEM_THEME_OSC11_ENABLED` | `1` | Enable/disable OSC 11 terminal query (`0` to disable) |
|
|
77
|
-
| `PI_SYSTEM_THEME_OSC11_MIN_INTERVAL_MS` | `15000` | Minimum interval between OSC 11 probes in SSH sessions |
|
|
112
|
+
| `PI_SYSTEM_THEME_OSC11_MIN_INTERVAL_MS` | `15000` | Minimum interval between OSC 11 probes in SSH/tmux sessions |
|
|
78
113
|
|
|
79
114
|
## Compatibility
|
|
80
115
|
|
|
81
116
|
- **Terminals:** Any terminal supporting OSC 11 color queries (Ghostty, iTerm2, kitty, foot, WezTerm, xterm, etc.)
|
|
82
117
|
- **OS detection:** macOS, Linux (GNOME gsettings), Windows
|
|
83
118
|
- **SSH:** Works transparently — no special setup required
|
|
119
|
+
- **tmux:** Supported (including long-lived sessions where `SSH_*` env vars may be missing)
|
|
84
120
|
- **Ghostty `theme = auto`:** Fully supported. When Ghostty switches colors, the next poll detects it.
|
|
85
121
|
|
|
86
122
|
## Migrating from pi-system-theme
|
package/index.ts
CHANGED
|
@@ -116,6 +116,10 @@ function isSSHSession(): boolean {
|
|
|
116
116
|
return !!(process.env.SSH_CONNECTION || process.env.SSH_TTY || process.env.SSH_CLIENT);
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
function isTmuxSession(): boolean {
|
|
120
|
+
return typeof process.env.TMUX === "string" && process.env.TMUX.length > 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
119
123
|
// ---------------------------------------------------------------------------
|
|
120
124
|
// Config I/O (reads ~/.pi/agent/system-theme.json written by /system-theme)
|
|
121
125
|
// ---------------------------------------------------------------------------
|
|
@@ -212,8 +216,9 @@ let fd;
|
|
|
212
216
|
try { fd = fs.openSync('/dev/tty', fs.constants.O_RDWR | fs.constants.O_NOCTTY | O_NONBLOCK); }
|
|
213
217
|
catch { process.exit(1); }
|
|
214
218
|
|
|
215
|
-
// Send OSC 11 query
|
|
216
|
-
|
|
219
|
+
// Send OSC 11 query.
|
|
220
|
+
// Use ST terminator for better compatibility with tmux passthrough.
|
|
221
|
+
try { fs.writeSync(fd, '\x1b]11;?\x1b\\'); }
|
|
217
222
|
catch { try { fs.closeSync(fd); } catch {} process.exit(1); }
|
|
218
223
|
|
|
219
224
|
const buf = Buffer.alloc(1024);
|
|
@@ -235,13 +240,21 @@ function tryRead() {
|
|
|
235
240
|
}
|
|
236
241
|
}
|
|
237
242
|
|
|
243
|
+
function to8Bit(hex) {
|
|
244
|
+
if (!hex) return 0;
|
|
245
|
+
const h = String(hex);
|
|
246
|
+
if (h.length <= 2) return parseInt(h.padEnd(2, h[h.length - 1] || '0'), 16);
|
|
247
|
+
return parseInt(h.slice(0, 2), 16);
|
|
248
|
+
}
|
|
249
|
+
|
|
238
250
|
function done() {
|
|
239
251
|
try { fs.closeSync(fd); } catch {}
|
|
240
|
-
|
|
252
|
+
// Keep parser permissive: tmux may wrap control sequences, but rgb payload remains stable.
|
|
253
|
+
const m = response.match(/rgb:([0-9a-fA-F]{2,4})\\/([0-9a-fA-F]{2,4})\\/([0-9a-fA-F]{2,4})/);
|
|
241
254
|
if (m) {
|
|
242
|
-
const r =
|
|
243
|
-
const g =
|
|
244
|
-
const b =
|
|
255
|
+
const r = to8Bit(m[1]);
|
|
256
|
+
const g = to8Bit(m[2]);
|
|
257
|
+
const b = to8Bit(m[3]);
|
|
245
258
|
const luminance = 0.299 * r + 0.587 * g + 0.114 * b;
|
|
246
259
|
process.stdout.write(luminance < 128 ? 'dark' : 'light');
|
|
247
260
|
}
|
|
@@ -250,7 +263,7 @@ function done() {
|
|
|
250
263
|
|
|
251
264
|
function poll() {
|
|
252
265
|
tryRead();
|
|
253
|
-
if (response.includes('
|
|
266
|
+
if (response.includes('rgb:') || Date.now() > deadline) return done();
|
|
254
267
|
setTimeout(poll, 16);
|
|
255
268
|
}
|
|
256
269
|
|
|
@@ -406,8 +419,9 @@ async function resolveAppearance(config: Config, osc11State: Osc11State): Promis
|
|
|
406
419
|
if (override === "dark" || override === "light") return override;
|
|
407
420
|
// "auto" or null → continue
|
|
408
421
|
|
|
409
|
-
// 2. Terminal query via OSC 11 (SSH
|
|
410
|
-
|
|
422
|
+
// 2. Terminal query via OSC 11 (SSH/tmux, throttled)
|
|
423
|
+
// tmux sessions may not carry SSH_* vars, so include TMUX explicitly.
|
|
424
|
+
if ((isSSHSession() || isTmuxSession()) && isOsc11Enabled()) {
|
|
411
425
|
const now = Date.now();
|
|
412
426
|
const minIntervalMs = getOsc11MinIntervalMs();
|
|
413
427
|
|