@oh-my-pi/pi-natives 18.16.0 → 18.18.0
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/THIRD-PARTY-NOTICES.txt +0 -80
- package/native/index.d.ts +95 -9
- package/native/index.js +28 -25
- package/native/loader-state.d.ts +23 -0
- package/native/loader-state.js +143 -0
- package/package.json +8 -9
package/THIRD-PARTY-NOTICES.txt
CHANGED
|
@@ -9,56 +9,6 @@ governs only the material it names.
|
|
|
9
9
|
VENDORED SOURCE AND DATA
|
|
10
10
|
========================
|
|
11
11
|
|
|
12
|
-
-------------------------------------------------------------------------------
|
|
13
|
-
brush-core 0.5.0 — crates/vendor/brush-core
|
|
14
|
-
|
|
15
|
-
This directory contains a vendored, locally-patched copy of brush-core from the
|
|
16
|
-
brush shell project (https://github.com/reubeno/brush), used under the MIT
|
|
17
|
-
License. It is wired into the workspace via `[patch.crates-io]` so these
|
|
18
|
-
modifications can be maintained against the published release (brush-core
|
|
19
|
-
0.5.0).
|
|
20
|
-
|
|
21
|
-
Copyright (c) 2024 reuben olinsky
|
|
22
|
-
|
|
23
|
-
Local modifications include: Windows path handling fixes (drive-alias and
|
|
24
|
-
rooted-path normalization in globs), an async background-PID fix for the nohup
|
|
25
|
-
wrapper, treating `/dev/null` as poll-ready to avoid an infinite poll on macOS,
|
|
26
|
-
and indentation/formatting standardization. The remaining logic tracks upstream
|
|
27
|
-
so behavior matches the published crate.
|
|
28
|
-
|
|
29
|
-
MIT License
|
|
30
|
-
|
|
31
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
32
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
33
|
-
in the Software without restriction, including without limitation the rights
|
|
34
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
35
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
36
|
-
furnished to do so, subject to the following conditions:
|
|
37
|
-
|
|
38
|
-
The above copyright notice and this permission notice shall be included in all
|
|
39
|
-
copies or substantial portions of the Software.
|
|
40
|
-
|
|
41
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
42
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
43
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
44
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
45
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
46
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
47
|
-
SOFTWARE.
|
|
48
|
-
|
|
49
|
-
-------------------------------------------------------------------------------
|
|
50
|
-
brush-builtins — crates/pi-builtins
|
|
51
|
-
|
|
52
|
-
The POSIX/bash builtins began as a locally-patched copy of brush-builtins from
|
|
53
|
-
the brush shell project (https://github.com/reubeno/brush), used under the MIT
|
|
54
|
-
License; the full license text is reproduced with brush-core above.
|
|
55
|
-
|
|
56
|
-
Copyright (c) 2024 reuben olinsky
|
|
57
|
-
|
|
58
|
-
Local modifications include: implementing previously-stubbed builtins, the
|
|
59
|
-
`wait` builtin (PID targeting plus the `-f`/`-n`/`-p` flags), and cancellation
|
|
60
|
-
support for the `read` builtin via poll.
|
|
61
|
-
|
|
62
12
|
-------------------------------------------------------------------------------
|
|
63
13
|
Command-line utilities — crates/pi-builtins
|
|
64
14
|
|
|
@@ -11855,35 +11805,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
11855
11805
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
11856
11806
|
SOFTWARE.
|
|
11857
11807
|
|
|
11858
|
-
-------------------------------------------------------------------------------
|
|
11859
|
-
License: MIT License (MIT)
|
|
11860
|
-
Used by:
|
|
11861
|
-
- brush-parser 0.4.0 (https://github.com/reubeno/brush)
|
|
11862
|
-
|
|
11863
|
-
Full license text:
|
|
11864
|
-
|
|
11865
|
-
MIT License
|
|
11866
|
-
|
|
11867
|
-
Copyright (c) 2024 reuben olinsky
|
|
11868
|
-
|
|
11869
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11870
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
11871
|
-
in the Software without restriction, including without limitation the rights
|
|
11872
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
11873
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
11874
|
-
furnished to do so, subject to the following conditions:
|
|
11875
|
-
|
|
11876
|
-
The above copyright notice and this permission notice shall be included in all
|
|
11877
|
-
copies or substantial portions of the Software.
|
|
11878
|
-
|
|
11879
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
11880
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
11881
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
11882
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
11883
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
11884
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
11885
|
-
SOFTWARE.
|
|
11886
|
-
|
|
11887
11808
|
-------------------------------------------------------------------------------
|
|
11888
11809
|
License: MIT License (MIT)
|
|
11889
11810
|
Used by:
|
|
@@ -12098,7 +12019,6 @@ SOFTWARE.
|
|
|
12098
12019
|
-------------------------------------------------------------------------------
|
|
12099
12020
|
License: MIT License (MIT)
|
|
12100
12021
|
Used by:
|
|
12101
|
-
- brush-core 0.5.0 (https://github.com/reubeno/brush)
|
|
12102
12022
|
- napi 3.14.2 (https://github.com/napi-rs/napi-rs)
|
|
12103
12023
|
- asn1-rs-impl 0.2.0 (https://github.com/rusticata/asn1-rs.git)
|
|
12104
12024
|
- ast-grep-core 0.39.9 (https://github.com/ast-grep/ast-grep)
|
package/native/index.d.ts
CHANGED
|
@@ -87,8 +87,8 @@ export declare class DesktopSession {
|
|
|
87
87
|
retire(): void
|
|
88
88
|
/**
|
|
89
89
|
* Sets when the current run ends, `remaining_ms` from now; each run sets
|
|
90
|
-
* it before its first call.
|
|
91
|
-
*
|
|
90
|
+
* it before its first call. Input waiting for the user to pause in its app
|
|
91
|
+
* (macOS) or for a Wayland permission prompt gives up shortly before it.
|
|
92
92
|
*/
|
|
93
93
|
setRunDeadline(remainingMs: number): void
|
|
94
94
|
capture(target: string, caps?: CaptureCaps | undefined | null): Promise<DesktopCapture>
|
|
@@ -567,7 +567,46 @@ export declare class PtySession {
|
|
|
567
567
|
kill(): void
|
|
568
568
|
}
|
|
569
569
|
|
|
570
|
-
/**
|
|
570
|
+
/**
|
|
571
|
+
* Actual command state, source units and bounded history for one shell run,
|
|
572
|
+
* including observed assignments and producer-attributed output.
|
|
573
|
+
*
|
|
574
|
+
* Create one over the command text and
|
|
575
|
+
* pass it as [`ShellRunOptions::trace`]; poll [`RunTrace::version`] while the
|
|
576
|
+
* run is in flight and take [`RunTrace::snapshot`] when it changed.
|
|
577
|
+
*/
|
|
578
|
+
export declare class RunTrace {
|
|
579
|
+
/** A trace of `script`, the exact command text about to run. */
|
|
580
|
+
constructor(script: string)
|
|
581
|
+
/**
|
|
582
|
+
* Revision of semantic events, assignments and visible output; unchanged
|
|
583
|
+
* means `snapshot()` is unchanged, even when adjacent output coalesces.
|
|
584
|
+
*/
|
|
585
|
+
version(): number
|
|
586
|
+
/**
|
|
587
|
+
* The `ShellTrace` JSON with byte-offset layout, current node states and
|
|
588
|
+
* ordered replay `history`. The newest 20,000 records retain at most
|
|
589
|
+
* 2 MiB visible output and 8 MiB payload; `historyTruncated` explicitly
|
|
590
|
+
* reports eviction. History timestamps are measured ns since `RunStart`;
|
|
591
|
+
* output identifies its real producer (`u`, `n`, `command`) when known.
|
|
592
|
+
* Semantic entries carry their actual `vpid`; `rootVpid` distinguishes
|
|
593
|
+
* root lifecycle from owned tool children even after journal trimming.
|
|
594
|
+
* A UTF-8 scalar spanning producers has exact byte `contributors`
|
|
595
|
+
* instead of an invented primary producer. Decoding ends at capture EOF.
|
|
596
|
+
* Segmented minimizer submissions share one epoch and final status;
|
|
597
|
+
* their history carries `segment`, with `logicalEnd`/`logicalStatus`
|
|
598
|
+
* finalizing the last actual root RunEnd after output draining.
|
|
599
|
+
* Serialization borrows the locked model rather than cloning its history.
|
|
600
|
+
*/
|
|
601
|
+
snapshot(): string
|
|
602
|
+
/**
|
|
603
|
+
* Render directly over the borrowed native state; no snapshot or syntax
|
|
604
|
+
* roundtrip.
|
|
605
|
+
*/
|
|
606
|
+
present(options: ShellVizOptions): string
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
/** Persistent embedded bash engine (pi-shell) shell session. */
|
|
571
610
|
export declare class Shell {
|
|
572
611
|
/**
|
|
573
612
|
* Create a new shell session from optional configuration.
|
|
@@ -607,6 +646,15 @@ export declare class Shell {
|
|
|
607
646
|
pids(): Array<number>
|
|
608
647
|
}
|
|
609
648
|
|
|
649
|
+
/**
|
|
650
|
+
* Persisted native visualization, restored once rather than reparsed on each
|
|
651
|
+
* frame.
|
|
652
|
+
*/
|
|
653
|
+
export declare class ShellVisualization {
|
|
654
|
+
constructor(snapshot: string)
|
|
655
|
+
present(options: ShellVizOptions): string
|
|
656
|
+
}
|
|
657
|
+
|
|
610
658
|
/** One word-completion engine running on its own thread. */
|
|
611
659
|
export declare class TextPredictor {
|
|
612
660
|
/**
|
|
@@ -1442,10 +1490,8 @@ export declare function countTokens(input: string | string[], encoding?: Encodin
|
|
|
1442
1490
|
/**
|
|
1443
1491
|
* Decode one complete SIXEL control string into a PNG on the calling thread.
|
|
1444
1492
|
*
|
|
1445
|
-
*
|
|
1446
|
-
*
|
|
1447
|
-
* first so hostile dimensions cannot make the dependency allocate its much
|
|
1448
|
-
* larger internal maximum.
|
|
1493
|
+
* Raster declarations, repeats, and row advances are bounded before allocating
|
|
1494
|
+
* the decoded RGBA buffer.
|
|
1449
1495
|
*/
|
|
1450
1496
|
export declare function decodeSixelToPng(bytes: Uint8Array): Uint8Array
|
|
1451
1497
|
|
|
@@ -2035,7 +2081,7 @@ export declare enum Encoding {
|
|
|
2035
2081
|
export declare function execReplace(argv: Array<string>): void
|
|
2036
2082
|
|
|
2037
2083
|
/**
|
|
2038
|
-
* Execute a
|
|
2084
|
+
* Execute a command in the embedded bash engine (pi-shell).
|
|
2039
2085
|
*
|
|
2040
2086
|
* Creates a fresh session for each call. The `on_chunk` callback receives
|
|
2041
2087
|
* streamed stdout/stderr output. Returns the exit code when the command
|
|
@@ -3364,6 +3410,19 @@ export declare function renderMermaidAscii(text: string, options?: MermaidRender
|
|
|
3364
3410
|
*/
|
|
3365
3411
|
export declare function renderSnapcompactPng(text: string, options: SnapcompactRenderOptions): Promise<string>
|
|
3366
3412
|
|
|
3413
|
+
/**
|
|
3414
|
+
* Run the pi-shell engine as a process shell in this process (`omp zsh`,
|
|
3415
|
+
* `omp bash`, `omp sh`): `argv` is the shell's whole command line,
|
|
3416
|
+
* `argv[0]` naming it (`zsh`, `bash` or `sh` pick the dialect), as a real
|
|
3417
|
+
* shell gets it. Synchronous: blocks the calling thread until the shell
|
|
3418
|
+
* exits and returns the status the process should exit with (0–255; 101
|
|
3419
|
+
* after a panic). The shell uses the process's own stdin, stdout, stderr,
|
|
3420
|
+
* terminal and inherited descriptors (duplicated, never taken over); the
|
|
3421
|
+
* job-control and termination signals the runtime handles are reset to
|
|
3422
|
+
* their defaults for the run and restored after it.
|
|
3423
|
+
*/
|
|
3424
|
+
export declare function runShellMain(argv: Array<string>): number
|
|
3425
|
+
|
|
3367
3426
|
/**
|
|
3368
3427
|
* Search content for a pattern (one-shot, compiles pattern each time).
|
|
3369
3428
|
* For repeated searches with the same pattern, use [`grep`] with file filters.
|
|
@@ -3415,7 +3474,10 @@ export interface SearchResult {
|
|
|
3415
3474
|
|
|
3416
3475
|
export declare function setHangulCompatJamoWidthOverride(value: number): void
|
|
3417
3476
|
|
|
3418
|
-
/**
|
|
3477
|
+
/**
|
|
3478
|
+
* Options for executing a shell command via the embedded bash engine
|
|
3479
|
+
* (pi-shell).
|
|
3480
|
+
*/
|
|
3419
3481
|
export interface ShellExecuteOptions {
|
|
3420
3482
|
/** Command string to execute in the shell. */
|
|
3421
3483
|
command: string
|
|
@@ -3785,6 +3847,8 @@ export interface ShellRunOptions {
|
|
|
3785
3847
|
filesystem?: ShellFilesystem
|
|
3786
3848
|
/** Receives a copy of every byte crossing the run's pipeline pipes. */
|
|
3787
3849
|
streams?: PipeStreams
|
|
3850
|
+
/** Folds the run's engine events into a live model of the command. */
|
|
3851
|
+
trace?: RunTrace
|
|
3788
3852
|
}
|
|
3789
3853
|
|
|
3790
3854
|
/** Result of running a shell command. */
|
|
@@ -3806,6 +3870,28 @@ export interface ShellRunResult {
|
|
|
3806
3870
|
workingDir?: string
|
|
3807
3871
|
}
|
|
3808
3872
|
|
|
3873
|
+
/** Native non-executing visualization transformations. */
|
|
3874
|
+
export interface ShellVizLayers {
|
|
3875
|
+
color: boolean
|
|
3876
|
+
inline: boolean
|
|
3877
|
+
idioms: boolean
|
|
3878
|
+
effects: boolean
|
|
3879
|
+
unwrap: boolean
|
|
3880
|
+
}
|
|
3881
|
+
|
|
3882
|
+
/** Native presentation controls. Node identities are opaque engine keys. */
|
|
3883
|
+
export interface ShellVizOptions {
|
|
3884
|
+
view: 'raw' | 'pseudo'
|
|
3885
|
+
layers: ShellVizLayers
|
|
3886
|
+
split: boolean
|
|
3887
|
+
cursor?: number
|
|
3888
|
+
cursorSeq?: number
|
|
3889
|
+
playing: boolean
|
|
3890
|
+
speed: number
|
|
3891
|
+
selectedNode?: string
|
|
3892
|
+
expandedNodes: Array<string>
|
|
3893
|
+
}
|
|
3894
|
+
|
|
3809
3895
|
/**
|
|
3810
3896
|
* Visible slice of a line after ANSI-aware column selection
|
|
3811
3897
|
* (`sliceWithWidth`).
|
package/native/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { loadNative, missingNativeExport } from "./loader-state.js";
|
|
1
|
+
import { loadNative, missingNativeClass, missingNativeExport } from "./loader-state.js";
|
|
2
2
|
import { adaptDesktopSession } from "./desktop-adapter.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -23,31 +23,33 @@ import { adaptDesktopSession } from "./desktop-adapter.js";
|
|
|
23
23
|
const nativeBindings = loadNative();
|
|
24
24
|
// --- generated native exports (do not edit) ---
|
|
25
25
|
// classes
|
|
26
|
-
export const AudioCapture = nativeBindings.AudioCapture;
|
|
27
|
-
export const AudioPlayback = nativeBindings.AudioPlayback;
|
|
26
|
+
export const AudioCapture = nativeBindings.AudioCapture ?? missingNativeClass("AudioCapture");
|
|
27
|
+
export const AudioPlayback = nativeBindings.AudioPlayback ?? missingNativeClass("AudioPlayback");
|
|
28
28
|
export const DesktopSession = adaptDesktopSession(nativeBindings.DesktopSession);
|
|
29
|
-
export const DiffStream = nativeBindings.DiffStream;
|
|
30
|
-
export const EditSession = nativeBindings.EditSession;
|
|
31
|
-
export const EditStore = nativeBindings.EditStore;
|
|
32
|
-
export const FileLock = nativeBindings.FileLock;
|
|
33
|
-
export const HighlightStream = nativeBindings.HighlightStream;
|
|
34
|
-
export const IpcConnection = nativeBindings.IpcConnection;
|
|
35
|
-
export const IpcServer = nativeBindings.IpcServer;
|
|
36
|
-
export const LineMatcher = nativeBindings.LineMatcher;
|
|
37
|
-
export const LiveWebRtcPeer = nativeBindings.LiveWebRtcPeer;
|
|
38
|
-
export const MacAppearanceObserver = nativeBindings.MacAppearanceObserver;
|
|
39
|
-
export const MacOSFrontApp = nativeBindings.MacOSFrontApp;
|
|
40
|
-
export const NativeOAuthCallback = nativeBindings.NativeOAuthCallback;
|
|
41
|
-
export const PipeStreams = nativeBindings.PipeStreams;
|
|
42
|
-
export const PowerAssertion = nativeBindings.PowerAssertion;
|
|
43
|
-
export const Process = nativeBindings.Process;
|
|
44
|
-
export const PtySession = nativeBindings.PtySession;
|
|
45
|
-
export const
|
|
46
|
-
export const
|
|
47
|
-
export const
|
|
48
|
-
export const
|
|
49
|
-
export const
|
|
50
|
-
export const
|
|
29
|
+
export const DiffStream = nativeBindings.DiffStream ?? missingNativeClass("DiffStream");
|
|
30
|
+
export const EditSession = nativeBindings.EditSession ?? missingNativeClass("EditSession");
|
|
31
|
+
export const EditStore = nativeBindings.EditStore ?? missingNativeClass("EditStore");
|
|
32
|
+
export const FileLock = nativeBindings.FileLock ?? missingNativeClass("FileLock");
|
|
33
|
+
export const HighlightStream = nativeBindings.HighlightStream ?? missingNativeClass("HighlightStream");
|
|
34
|
+
export const IpcConnection = nativeBindings.IpcConnection ?? missingNativeClass("IpcConnection");
|
|
35
|
+
export const IpcServer = nativeBindings.IpcServer ?? missingNativeClass("IpcServer");
|
|
36
|
+
export const LineMatcher = nativeBindings.LineMatcher ?? missingNativeClass("LineMatcher");
|
|
37
|
+
export const LiveWebRtcPeer = nativeBindings.LiveWebRtcPeer ?? missingNativeClass("LiveWebRtcPeer");
|
|
38
|
+
export const MacAppearanceObserver = nativeBindings.MacAppearanceObserver ?? missingNativeClass("MacAppearanceObserver");
|
|
39
|
+
export const MacOSFrontApp = nativeBindings.MacOSFrontApp ?? missingNativeClass("MacOSFrontApp");
|
|
40
|
+
export const NativeOAuthCallback = nativeBindings.NativeOAuthCallback ?? missingNativeClass("NativeOAuthCallback");
|
|
41
|
+
export const PipeStreams = nativeBindings.PipeStreams ?? missingNativeClass("PipeStreams");
|
|
42
|
+
export const PowerAssertion = nativeBindings.PowerAssertion ?? missingNativeClass("PowerAssertion");
|
|
43
|
+
export const Process = nativeBindings.Process ?? missingNativeClass("Process");
|
|
44
|
+
export const PtySession = nativeBindings.PtySession ?? missingNativeClass("PtySession");
|
|
45
|
+
export const RunTrace = nativeBindings.RunTrace ?? missingNativeClass("RunTrace");
|
|
46
|
+
export const Shell = nativeBindings.Shell ?? missingNativeClass("Shell");
|
|
47
|
+
export const ShellVisualization = nativeBindings.ShellVisualization ?? missingNativeClass("ShellVisualization");
|
|
48
|
+
export const TextPredictor = nativeBindings.TextPredictor ?? missingNativeClass("TextPredictor");
|
|
49
|
+
export const TtyWriter = nativeBindings.TtyWriter ?? missingNativeClass("TtyWriter");
|
|
50
|
+
export const VcsGitRepo = nativeBindings.VcsGitRepo ?? missingNativeClass("VcsGitRepo");
|
|
51
|
+
export const VcsJjWorkspace = nativeBindings.VcsJjWorkspace ?? missingNativeClass("VcsJjWorkspace");
|
|
52
|
+
export const VcsRepo = nativeBindings.VcsRepo ?? missingNativeClass("VcsRepo");
|
|
51
53
|
|
|
52
54
|
// functions
|
|
53
55
|
export const __ompInstallTokioRuntime = nativeBindings.__ompInstallTokioRuntime ?? missingNativeExport("__ompInstallTokioRuntime");
|
|
@@ -135,6 +137,7 @@ export const readImageFromClipboard = nativeBindings.readImageFromClipboard ?? m
|
|
|
135
137
|
export const readTextFromClipboard = nativeBindings.readTextFromClipboard ?? missingNativeExport("readTextFromClipboard");
|
|
136
138
|
export const renderMermaidAscii = nativeBindings.renderMermaidAscii ?? missingNativeExport("renderMermaidAscii");
|
|
137
139
|
export const renderSnapcompactPng = nativeBindings.renderSnapcompactPng ?? missingNativeExport("renderSnapcompactPng");
|
|
140
|
+
export const runShellMain = nativeBindings.runShellMain ?? missingNativeExport("runShellMain");
|
|
138
141
|
export const search = nativeBindings.search ?? missingNativeExport("search");
|
|
139
142
|
export const setHangulCompatJamoWidthOverride = nativeBindings.setHangulCompatJamoWidthOverride ?? missingNativeExport("setHangulCompatJamoWidthOverride");
|
|
140
143
|
export const sliceWithWidth = nativeBindings.sliceWithWidth ?? missingNativeExport("sliceWithWidth");
|
package/native/loader-state.d.ts
CHANGED
|
@@ -145,6 +145,29 @@ export function missingNativeExport(
|
|
|
145
145
|
addon?: NativeAddonStatus | null,
|
|
146
146
|
): (() => never) | undefined;
|
|
147
147
|
|
|
148
|
+
/**
|
|
149
|
+
* Stub for a class the addon does not provide: `undefined` on a current addon,
|
|
150
|
+
* a class whose constructor throws on a stale one.
|
|
151
|
+
*/
|
|
152
|
+
export function missingNativeClass(
|
|
153
|
+
symbolName: string,
|
|
154
|
+
addon?: NativeAddonStatus | null,
|
|
155
|
+
): (new (...args: unknown[]) => never) | undefined;
|
|
156
|
+
|
|
157
|
+
/** Notice a workspace tree prints when its addon is from another release. */
|
|
158
|
+
export function staleWorkspaceAddonNotice(addon: NativeAddonStatus): string;
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* Write {@link staleWorkspaceAddonNotice} once, from the main thread, and only
|
|
162
|
+
* on a workspace load. The latch is per loaded copy of this module. Returns
|
|
163
|
+
* whether this call wrote it.
|
|
164
|
+
*/
|
|
165
|
+
export function reportStaleWorkspaceAddon(
|
|
166
|
+
ctx: { isWorkspaceLoad: boolean },
|
|
167
|
+
addon: NativeAddonStatus,
|
|
168
|
+
deps?: { write?: (text: string) => void; state?: { reported: boolean } },
|
|
169
|
+
): boolean;
|
|
170
|
+
|
|
148
171
|
/** Actionable text for {@link missingNativeExport}. */
|
|
149
172
|
export function missingNativeExportMessage(symbolName: string, addon?: NativeAddonStatus | null): string;
|
|
150
173
|
|
package/native/loader-state.js
CHANGED
|
@@ -693,6 +693,48 @@ export function missingNativeExport(symbolName, addon = loadedAddon) {
|
|
|
693
693
|
};
|
|
694
694
|
}
|
|
695
695
|
|
|
696
|
+
/**
|
|
697
|
+
* Static reads a {@link missingNativeClass} stand-in answers normally rather
|
|
698
|
+
* than throwing: the function-object intrinsics every caller and inspector
|
|
699
|
+
* touches, and `then`, so an accidental `await` on the export resolves to the
|
|
700
|
+
* class instead of exploding somewhere unrelated.
|
|
701
|
+
*/
|
|
702
|
+
const CLASS_STUB_PLAIN_STATICS = new Set(["prototype", "name", "length", "constructor", "then"]);
|
|
703
|
+
|
|
704
|
+
/**
|
|
705
|
+
* Class counterpart of {@link missingNativeExport}: a stand-in that fails with
|
|
706
|
+
* the addon's identity attached instead of as a bare `undefined` export, which
|
|
707
|
+
* surfaces as `undefined is not a constructor` at the callsite and names
|
|
708
|
+
* nothing.
|
|
709
|
+
*
|
|
710
|
+
* Same staleness rule as the function stub: only a stale addon gets a
|
|
711
|
+
* stand-in, so `typeof native.Thing === "function"` capability probes against
|
|
712
|
+
* a current addon keep their meaning.
|
|
713
|
+
*
|
|
714
|
+
* Several of these classes are entered through a static rather than a
|
|
715
|
+
* constructor — `FileLock.tryAcquire`, `IpcServer.listen`, `Process.fromPid`,
|
|
716
|
+
* `PowerAssertion.start` — so the stand-in answers any other static read with
|
|
717
|
+
* the same diagnostic. Only a stale addon reaches it, and only for a class
|
|
718
|
+
* that addon does not carry, so nothing on a healthy tree meets a proxy.
|
|
719
|
+
* @param {string} symbolName
|
|
720
|
+
* @param {ReturnType<typeof nativeAddonStatus>} [addon]
|
|
721
|
+
* @returns {(new (...args: unknown[]) => never) | undefined}
|
|
722
|
+
*/
|
|
723
|
+
export function missingNativeClass(symbolName, addon = loadedAddon) {
|
|
724
|
+
if (!addon?.stale) return undefined;
|
|
725
|
+
const stub = class MissingNativeClass {
|
|
726
|
+
constructor() {
|
|
727
|
+
throw new Error(missingNativeExportMessage(symbolName, addon));
|
|
728
|
+
}
|
|
729
|
+
};
|
|
730
|
+
return new Proxy(stub, {
|
|
731
|
+
get(target, key, receiver) {
|
|
732
|
+
if (typeof key === "symbol" || CLASS_STUB_PLAIN_STATICS.has(key)) return Reflect.get(target, key, receiver);
|
|
733
|
+
throw new Error(missingNativeExportMessage(`${symbolName}.${key}`, addon));
|
|
734
|
+
},
|
|
735
|
+
});
|
|
736
|
+
}
|
|
737
|
+
|
|
696
738
|
/**
|
|
697
739
|
* Actionable text for {@link missingNativeExport}. `addon` is injectable so the
|
|
698
740
|
* wording can be pinned without a stale `.node` on disk.
|
|
@@ -715,6 +757,106 @@ export function missingNativeExportMessage(symbolName, addon = loadedAddon) {
|
|
|
715
757
|
);
|
|
716
758
|
}
|
|
717
759
|
|
|
760
|
+
/**
|
|
761
|
+
* One-line notice for a workspace tree running an addon from another release.
|
|
762
|
+
*
|
|
763
|
+
* The missing-symbol stubs only speak when a caller touches a symbol the addon
|
|
764
|
+
* does not carry. A symbol it does carry runs that release's behaviour — an
|
|
765
|
+
* older shell, an older grep — with no marker at all, so this notice is the
|
|
766
|
+
* only provenance those failures get.
|
|
767
|
+
*
|
|
768
|
+
* `stale` is any release difference, so the wording must not assume the addon
|
|
769
|
+
* is the older side.
|
|
770
|
+
* @param {NonNullable<ReturnType<typeof nativeAddonStatus>>} addon
|
|
771
|
+
* @returns {string}
|
|
772
|
+
*/
|
|
773
|
+
export function staleWorkspaceAddonNotice(addon) {
|
|
774
|
+
const loaded = addon.version ? `@oh-my-pi/pi-natives@${addon.version}` : "an addon without a release stamp";
|
|
775
|
+
return (
|
|
776
|
+
`[pi-natives] ${addon.path} is ${loaded}, but this checkout is @${addon.packageVersion}. ` +
|
|
777
|
+
"Symbols this checkout expects may be missing and shared ones may behave differently; " +
|
|
778
|
+
"run `bun run build:native` before trusting results from this tree.\n"
|
|
779
|
+
);
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
/**
|
|
783
|
+
* Whether the copy of this module running on the current thread has already
|
|
784
|
+
* written the mismatched-addon notice. One per loaded copy, which is one per
|
|
785
|
+
* main thread in every shape this package ships; the write itself is confined
|
|
786
|
+
* to the main thread by {@link onMainThread}.
|
|
787
|
+
*/
|
|
788
|
+
const staleNoticeState = { reported: false };
|
|
789
|
+
|
|
790
|
+
/** Memoized answer from {@link onMainThread}; `undefined` until first asked. */
|
|
791
|
+
let mainThreadAnswer;
|
|
792
|
+
|
|
793
|
+
/**
|
|
794
|
+
* True on a process's main thread, false inside a worker thread.
|
|
795
|
+
*
|
|
796
|
+
* Resolved through `createRequire` on first use rather than imported at module
|
|
797
|
+
* scope: `packages/coding-agent/src/cli.ts` keeps `node:worker_threads` out of
|
|
798
|
+
* ordinary startup on purpose, and this module is reached statically from
|
|
799
|
+
* `sqlite-locks` on launches that never load an addon. Asking only when a
|
|
800
|
+
* mismatch has already been found keeps that boundary. A runtime without the
|
|
801
|
+
* builtin answers "main thread", which is the safe side: the notice prints.
|
|
802
|
+
* @returns {boolean}
|
|
803
|
+
*/
|
|
804
|
+
function onMainThread() {
|
|
805
|
+
if (mainThreadAnswer === undefined) {
|
|
806
|
+
try {
|
|
807
|
+
mainThreadAnswer = createRequire(import.meta.url)("node:worker_threads").isMainThread !== false;
|
|
808
|
+
} catch {
|
|
809
|
+
mainThreadAnswer = true;
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
return mainThreadAnswer;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
/**
|
|
816
|
+
* Write {@link staleWorkspaceAddonNotice} once, from the main thread, when a
|
|
817
|
+
* workspace tree loads an addon of another release.
|
|
818
|
+
*
|
|
819
|
+
* Three guards, each load-bearing.
|
|
820
|
+
*
|
|
821
|
+
* Main thread only, because fd 2 is shared and a worker reaches `loadNative()`
|
|
822
|
+
* long after interactive mode owns the terminal — the subagent, JS-eval and
|
|
823
|
+
* tab workers all start then, so a per-worker write paints into a rendered
|
|
824
|
+
* frame. The main thread has already said it at startup; a worker repeating it
|
|
825
|
+
* adds nothing and costs the display. A worker *process* keeps the notice: it
|
|
826
|
+
* has its own main thread, and `subprocess/worker-client.ts` captures its
|
|
827
|
+
* stderr to a file rather than the terminal.
|
|
828
|
+
*
|
|
829
|
+
* Latched, because `loadNative()` is not a startup-only call: the lazy
|
|
830
|
+
* entrypoints in `clipboard.js` and friends call it on every invocation.
|
|
831
|
+
*
|
|
832
|
+
* Workspace loads only, because {@link validateLoadedBindings} has a second
|
|
833
|
+
* success path — it accepts a pre-sentinel addon on an installed load
|
|
834
|
+
* (`isCompatiblePreSentinelNativeAddon`), which reports no release and so
|
|
835
|
+
* counts as `stale`. That user has no repository to build.
|
|
836
|
+
*
|
|
837
|
+
* The write is a synchronous `fs.writeSync` to fd 2 for the same reason as
|
|
838
|
+
* {@link startupMarker}: it must survive a crash that follows it. `write` and
|
|
839
|
+
* `state` are injectable so a test can exercise the guards without consuming
|
|
840
|
+
* this copy's latch.
|
|
841
|
+
* @param {{ isWorkspaceLoad: boolean }} ctx
|
|
842
|
+
* @param {NonNullable<ReturnType<typeof nativeAddonStatus>>} addon
|
|
843
|
+
* @param {{ write?: (text: string) => void; state?: { reported: boolean } }} [deps]
|
|
844
|
+
* @returns {boolean} whether this call wrote the notice
|
|
845
|
+
*/
|
|
846
|
+
export function reportStaleWorkspaceAddon(ctx, addon, deps = {}) {
|
|
847
|
+
const state = deps.state ?? staleNoticeState;
|
|
848
|
+
// Thread identity last: the three cheap gates reject every ordinary launch
|
|
849
|
+
// before `node:worker_threads` is resolved at all.
|
|
850
|
+
if (!ctx.isWorkspaceLoad || !addon.stale || state.reported || !onMainThread()) return false;
|
|
851
|
+
state.reported = true;
|
|
852
|
+
try {
|
|
853
|
+
(deps.write ?? (text => fs.writeSync(2, text)))(staleWorkspaceAddonNotice(addon));
|
|
854
|
+
} catch {
|
|
855
|
+
// stderr unavailable; the notice is best-effort, the stubs still speak
|
|
856
|
+
}
|
|
857
|
+
return true;
|
|
858
|
+
}
|
|
859
|
+
|
|
718
860
|
/**
|
|
719
861
|
* Install the addon's bounded Tokio runtime now that `dlopen` has returned and
|
|
720
862
|
* the dynamic-loader lock is released. The Rust `#[module_init]` deliberately
|
|
@@ -881,6 +1023,7 @@ export function loadNative() {
|
|
|
881
1023
|
installNativeTokioRuntime(bindings);
|
|
882
1024
|
configureGrammarDir(bindings, ctx.nativesDir);
|
|
883
1025
|
loadedAddon = describeLoadedAddon(bindings, candidate, ctx);
|
|
1026
|
+
reportStaleWorkspaceAddon(ctx, loadedAddon);
|
|
884
1027
|
cleanupStaleNativeVersions({ nativesDir: ctx.nativesDir, currentVersion: ctx.packageVersion });
|
|
885
1028
|
startupMarker("native:loadNative:done");
|
|
886
1029
|
return bindings;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oh-my-pi/pi-natives",
|
|
3
|
-
"version": "18.
|
|
3
|
+
"version": "18.18.0",
|
|
4
4
|
"description": "Native Rust bindings for PDF conversion, audio, WebRTC, grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"build": "bun ../../scripts/bazel-natives.ts host --dest native",
|
|
36
36
|
"build:bindings": "bun scripts/build-bindings.ts",
|
|
37
37
|
"check": "oxlint . && oxfmt --check --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts' && bun run check:types",
|
|
38
|
-
"check:types": "
|
|
38
|
+
"check:types": "bun check --no-script -p tsconfig.json",
|
|
39
39
|
"lint": "oxlint .",
|
|
40
40
|
"test": "bun test --parallel",
|
|
41
41
|
"fix": "oxlint --fix --fix-suggestions . && bun run fmt",
|
|
@@ -49,7 +49,6 @@
|
|
|
49
49
|
"@napi-rs/cli": "3.7.2",
|
|
50
50
|
"@types/bun": "^1.3.14",
|
|
51
51
|
"cli-truncate": "6.1.1",
|
|
52
|
-
"diff": "9.0.0",
|
|
53
52
|
"gpt-tokenizer": "4.0.0",
|
|
54
53
|
"mitata": "1.0.34",
|
|
55
54
|
"slice-ansi": "9.0.0",
|
|
@@ -121,11 +120,11 @@
|
|
|
121
120
|
}
|
|
122
121
|
},
|
|
123
122
|
"optionalDependencies": {
|
|
124
|
-
"@oh-my-pi/pi-natives-linux-x64": "18.
|
|
125
|
-
"@oh-my-pi/pi-natives-linux-arm64": "18.
|
|
126
|
-
"@oh-my-pi/pi-natives-darwin-x64": "18.
|
|
127
|
-
"@oh-my-pi/pi-natives-darwin-arm64": "18.
|
|
128
|
-
"@oh-my-pi/pi-natives-win32-x64": "18.
|
|
129
|
-
"@oh-my-pi/pi-natives-win32-arm64": "18.
|
|
123
|
+
"@oh-my-pi/pi-natives-linux-x64": "18.18.0",
|
|
124
|
+
"@oh-my-pi/pi-natives-linux-arm64": "18.18.0",
|
|
125
|
+
"@oh-my-pi/pi-natives-darwin-x64": "18.18.0",
|
|
126
|
+
"@oh-my-pi/pi-natives-darwin-arm64": "18.18.0",
|
|
127
|
+
"@oh-my-pi/pi-natives-win32-x64": "18.18.0",
|
|
128
|
+
"@oh-my-pi/pi-natives-win32-arm64": "18.18.0"
|
|
130
129
|
}
|
|
131
130
|
}
|