@oh-my-pi/pi-utils 18.8.6 → 18.8.8
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 +16 -0
- package/dist/types/dirs.d.ts +6 -0
- package/dist/types/temp.d.ts +7 -0
- package/package.json +2 -2
- package/src/dirs.ts +9 -0
- package/src/format.ts +5 -1
- package/src/temp.ts +7 -0
- package/src/vterm/terminal.ts +34 -14
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [18.8.8] - 2026-10-10
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- Fixed `formatDuration` printing `60.0s` for durations just under a minute; they now read `1m` ([#15121](https://github.com/can1357/oh-my-pi/pull/15121) by [@H4vC](https://github.com/H4vC))
|
|
10
|
+
|
|
11
|
+
## [18.8.7] - 2026-10-09
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
|
|
15
|
+
- Added `getNativeGrammarsDir()`, where the native addon loads downloaded tree-sitter grammars from (`~/.omp/natives/grammars`).
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- Fixed the virtual terminal misreading private CSI sequences such as kitty keyboard `CSI < u` and modifyOtherKeys `CSI > 4;1 m` as cursor restores or text styling, which garbled replayed PTY output.
|
|
20
|
+
|
|
5
21
|
## [18.8.1] - 2026-10-07
|
|
6
22
|
|
|
7
23
|
### Added
|
package/dist/types/dirs.d.ts
CHANGED
|
@@ -247,6 +247,12 @@ export declare function getAvatarCacheDir(): string;
|
|
|
247
247
|
export declare function getFastembedCacheDir(): string;
|
|
248
248
|
/** Get the on-demand fastembed runtime install root (~/.omp/cache/fastembed-runtime). */
|
|
249
249
|
export declare function getFastembedRuntimeDir(): string;
|
|
250
|
+
/**
|
|
251
|
+
* Get the directory the native addon loads downloaded tree-sitter wasm grammars
|
|
252
|
+
* from (`<natives dir>/grammars`, ~/.omp/natives/grammars). The natives loader
|
|
253
|
+
* configures the addon with the same path.
|
|
254
|
+
*/
|
|
255
|
+
export declare function getNativeGrammarsDir(): string;
|
|
250
256
|
/** Get the natives directory. PI_NATIVES_DIR overrides the usual cache root; relative values are ignored. */
|
|
251
257
|
export declare function getNativesDir(): string;
|
|
252
258
|
/** Get the stats database path (~/.omp/stats.db). */
|
package/dist/types/temp.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Owned temporary directory, removed via `remove()` or `using`/`await using`.
|
|
3
|
+
*
|
|
4
|
+
* Prefixes follow `mkdtemp`: `"@name-"` creates under the OS temp dir, any other
|
|
5
|
+
* prefix is a path (a bare `"name-"` lands in the process cwd), and no prefix
|
|
6
|
+
* means `"@pi-temp-"`.
|
|
7
|
+
*/
|
|
1
8
|
export declare class TempDir {
|
|
2
9
|
#private;
|
|
3
10
|
private constructor();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-utils",
|
|
3
|
-
"version": "18.8.
|
|
3
|
+
"version": "18.8.8",
|
|
4
4
|
"description": "Shared utilities for pi packages",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cli",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@oh-my-pi/pi-natives": "18.8.
|
|
60
|
+
"@oh-my-pi/pi-natives": "18.8.8"
|
|
61
61
|
},
|
|
62
62
|
"devDependencies": {
|
|
63
63
|
"@types/bun": "^1.3.14"
|
package/src/dirs.ts
CHANGED
|
@@ -865,6 +865,15 @@ export function getFastembedRuntimeDir(): string {
|
|
|
865
865
|
return dirs.rootSubdir(path.join("cache", "fastembed-runtime"), "cache");
|
|
866
866
|
}
|
|
867
867
|
|
|
868
|
+
/**
|
|
869
|
+
* Get the directory the native addon loads downloaded tree-sitter wasm grammars
|
|
870
|
+
* from (`<natives dir>/grammars`, ~/.omp/natives/grammars). The natives loader
|
|
871
|
+
* configures the addon with the same path.
|
|
872
|
+
*/
|
|
873
|
+
export function getNativeGrammarsDir(): string {
|
|
874
|
+
return path.join(getNativesDir(), "grammars");
|
|
875
|
+
}
|
|
876
|
+
|
|
868
877
|
/** Get the natives directory. PI_NATIVES_DIR overrides the usual cache root; relative values are ignored. */
|
|
869
878
|
export function getNativesDir(): string {
|
|
870
879
|
return resolveAbsoluteDir(process.env.PI_NATIVES_DIR) ?? dirs.rootSubdir("natives", "cache");
|
package/src/format.ts
CHANGED
|
@@ -10,7 +10,11 @@ const DAY = 24 * HOUR;
|
|
|
10
10
|
export function formatDuration(ms: number): string {
|
|
11
11
|
if (!Number.isFinite(ms) || ms <= 0) return "0ms";
|
|
12
12
|
if (ms < SEC) return `${Math.floor(ms)}ms`;
|
|
13
|
-
if (ms < MIN)
|
|
13
|
+
if (ms < MIN) {
|
|
14
|
+
// Round to tenths first: `toFixed(1)` alone turns 59.95s+ into an impossible `60.0s`.
|
|
15
|
+
const tenths = Math.round(ms / 100);
|
|
16
|
+
return tenths < 600 ? `${(tenths / 10).toFixed(1)}s` : "1m";
|
|
17
|
+
}
|
|
14
18
|
if (ms < HOUR) {
|
|
15
19
|
const mins = Math.floor(ms / MIN);
|
|
16
20
|
const secs = Math.floor((ms % MIN) / SEC);
|
package/src/temp.ts
CHANGED
|
@@ -3,6 +3,13 @@ import * as fsPromises from "node:fs/promises";
|
|
|
3
3
|
import * as os from "node:os";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Owned temporary directory, removed via `remove()` or `using`/`await using`.
|
|
8
|
+
*
|
|
9
|
+
* Prefixes follow `mkdtemp`: `"@name-"` creates under the OS temp dir, any other
|
|
10
|
+
* prefix is a path (a bare `"name-"` lands in the process cwd), and no prefix
|
|
11
|
+
* means `"@pi-temp-"`.
|
|
12
|
+
*/
|
|
6
13
|
export class TempDir {
|
|
7
14
|
#path: string;
|
|
8
15
|
private constructor(path: string) {
|
package/src/vterm/terminal.ts
CHANGED
|
@@ -319,17 +319,38 @@ export class Terminal {
|
|
|
319
319
|
}
|
|
320
320
|
}
|
|
321
321
|
|
|
322
|
+
/**
|
|
323
|
+
* Dispatches a CSI sequence on its whole identifier (private prefix,
|
|
324
|
+
* intermediates, final), dropping the ones without a handler as xterm does:
|
|
325
|
+
* `CSI < u` pops the kitty keyboard stack rather than restoring the cursor,
|
|
326
|
+
* `CSI > 4;1 m` sets modifyOtherKeys rather than SGR, and `CSI 0 SP q` sets
|
|
327
|
+
* the cursor shape rather than anything this buffer models.
|
|
328
|
+
*/
|
|
322
329
|
#handleCsi(raw: string, final: string): void {
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
const
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
.replaceAll(":", ";")
|
|
330
|
-
.split(";")
|
|
331
|
-
.map(value => (value === "" ? 0 : Number(value)));
|
|
330
|
+
const marker = raw.charCodeAt(0);
|
|
331
|
+
// `<`, `=`, `>`, `?` open a private sequence family.
|
|
332
|
+
const prefixed = marker >= 0x3c && marker <= 0x3f;
|
|
333
|
+
// Null when intermediates or a misplaced private marker follow the parameters.
|
|
334
|
+
const params = parseCsiParams(prefixed ? raw.slice(1) : raw);
|
|
335
|
+
if (!params) return;
|
|
332
336
|
const first = params[0] ?? 0;
|
|
337
|
+
if (prefixed) {
|
|
338
|
+
if (marker !== 0x3f) return;
|
|
339
|
+
switch (final) {
|
|
340
|
+
case "h":
|
|
341
|
+
case "l":
|
|
342
|
+
this.#setModes(params, true, final === "h");
|
|
343
|
+
break;
|
|
344
|
+
// DECSED/DECSEL: no cell is ever protected, so selective erase is plain erase.
|
|
345
|
+
case "J":
|
|
346
|
+
this.#eraseDisplay(first);
|
|
347
|
+
break;
|
|
348
|
+
case "K":
|
|
349
|
+
this.#eraseLine(first);
|
|
350
|
+
break;
|
|
351
|
+
}
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
333
354
|
const amount = Math.max(1, first);
|
|
334
355
|
switch (final) {
|
|
335
356
|
case "A":
|
|
@@ -399,7 +420,7 @@ export class Terminal {
|
|
|
399
420
|
this.#setRendition(params);
|
|
400
421
|
break;
|
|
401
422
|
case "r":
|
|
402
|
-
|
|
423
|
+
this.#setScrollRegion(params);
|
|
403
424
|
break;
|
|
404
425
|
case "s":
|
|
405
426
|
this.#saveCursor();
|
|
@@ -409,14 +430,13 @@ export class Terminal {
|
|
|
409
430
|
break;
|
|
410
431
|
case "h":
|
|
411
432
|
case "l":
|
|
412
|
-
this.#setModes(params,
|
|
433
|
+
this.#setModes(params, false, final === "h");
|
|
413
434
|
break;
|
|
414
435
|
case "n":
|
|
415
|
-
if (
|
|
416
|
-
this.#emitData(`\x1b[${this.#active.cursorY + 1};${this.#active.cursorX + 1}R`);
|
|
436
|
+
if (first === 6) this.#emitData(`\x1b[${this.#active.cursorY + 1};${this.#active.cursorX + 1}R`);
|
|
417
437
|
break;
|
|
418
438
|
case "c":
|
|
419
|
-
|
|
439
|
+
this.#emitData("\x1b[?1;2c");
|
|
420
440
|
break;
|
|
421
441
|
}
|
|
422
442
|
}
|