@gajae-code/natives 0.11.1 → 0.11.3
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/native/index.d.ts +208 -13
- package/native/index.js +9 -1
- package/native/loader-state.d.ts +8 -0
- package/native/loader-state.js +34 -1
- package/package.json +6 -6
package/native/index.d.ts
CHANGED
|
@@ -114,8 +114,9 @@ export declare class NotificationServer {
|
|
|
114
114
|
/** Register the reply callback. Must be called before [`Self::start`]. */
|
|
115
115
|
onReply(callback: (err: null | Error, reply: ReplyEvent) => void): void
|
|
116
116
|
/**
|
|
117
|
-
* Register the inbound-message callback (free-text
|
|
118
|
-
*
|
|
117
|
+
* Register the authenticated inbound-message callback (free-text,
|
|
118
|
+
* side-question request/cancel, and in-thread config/control commands).
|
|
119
|
+
* Must be called before [`Self::start`].
|
|
119
120
|
*/
|
|
120
121
|
onInbound(callback: (err: null | Error, msg: InboundEvent) => void): void
|
|
121
122
|
/**
|
|
@@ -123,6 +124,11 @@ export declare class NotificationServer {
|
|
|
123
124
|
* [`Self::start`].
|
|
124
125
|
*/
|
|
125
126
|
onSdkFrame(callback: (err: null | Error, frame: SdkFrameEvent) => void): void
|
|
127
|
+
/**
|
|
128
|
+
* Register the negotiated-capabilities callback. Must be called before
|
|
129
|
+
* [`Self::start`].
|
|
130
|
+
*/
|
|
131
|
+
onNegotiatedCapabilities(callback: (err: null | Error, connectionId: string, capabilities: string[]) => void): void
|
|
126
132
|
/**
|
|
127
133
|
* Register the connection-close callback. Must be called before
|
|
128
134
|
* [`Self::start`].
|
|
@@ -176,14 +182,30 @@ export declare class NotificationServer {
|
|
|
176
182
|
/**
|
|
177
183
|
* Broadcast an ephemeral threaded-session frame. `frame_json` is a JSON
|
|
178
184
|
* `ServerMessage` (e.g. `identity_header`, `context_update`, `turn_stream`,
|
|
179
|
-
* `
|
|
180
|
-
* buffered for replay.
|
|
185
|
+
* `ephemeral_turn_result`, `image_attachment`, `session_closed`,
|
|
186
|
+
* `config_update`, `hello`). Not buffered for replay.
|
|
181
187
|
*
|
|
182
188
|
* # Errors
|
|
183
189
|
* Fails if not started or `frame_json` is not a valid `ServerMessage`.
|
|
184
190
|
*/
|
|
185
191
|
pushFrame(frameJson: string): void
|
|
186
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* Broadcast a TypeScript-constructed turn frame without re-parsing JSON.
|
|
194
|
+
* External frames must continue through [`Self::push_frame`] for serde
|
|
195
|
+
* validation.
|
|
196
|
+
*/
|
|
197
|
+
pushTurnStreamUnchecked(sessionId: string, phase: string, text: string, finalAnswer?: boolean | undefined | null, messageRef?: string | undefined | null): void
|
|
198
|
+
/**
|
|
199
|
+
* Broadcast a file attachment from raw N-API bytes, encoding the unchanged
|
|
200
|
+
* base64 wire field only in Rust.
|
|
201
|
+
*/
|
|
202
|
+
pushFileAttachmentUnchecked(sessionId: string, name: string, mime: string | undefined | null, data: Buffer, caption?: string | undefined | null): void
|
|
203
|
+
/**
|
|
204
|
+
* Return counters guarding the known-good frame crossing against
|
|
205
|
+
* regressions.
|
|
206
|
+
*/
|
|
207
|
+
knownGoodFrameStats(): KnownGoodFrameStats
|
|
208
|
+
/** Send a validated, bounded JSON envelope to one connected v3 SDK client. */
|
|
187
209
|
sendTo(connectionId: string, json: string): void
|
|
188
210
|
/**
|
|
189
211
|
* Publish a replayable `session_ready` readiness signal. `ready_json` is a
|
|
@@ -351,7 +373,7 @@ export declare class Shell {
|
|
|
351
373
|
* `packages/natives/native/index.js` (which derives the name from
|
|
352
374
|
* `package.json#version`).
|
|
353
375
|
*/
|
|
354
|
-
export declare function
|
|
376
|
+
export declare function __piNativesV0_11_3(): void
|
|
355
377
|
|
|
356
378
|
/**
|
|
357
379
|
* Apply conservative pre-execution rewrites to a bash command.
|
|
@@ -362,6 +384,8 @@ export declare function __piNativesV0_11_1(): void
|
|
|
362
384
|
*/
|
|
363
385
|
export declare function applyBashFixups(command: string): BashFixupResult
|
|
364
386
|
|
|
387
|
+
export declare function applyOwnerOnlyPathSecurity(path: string, kind: "directory" | "file"): NativeOwnerOnlySecurityResult
|
|
388
|
+
|
|
365
389
|
/** Typed terminal acknowledgement result returned by acknowledgement promises. */
|
|
366
390
|
export interface AskSelectedAckOutcomeEvent {
|
|
367
391
|
status: string
|
|
@@ -571,6 +595,8 @@ export interface BuildInfo {
|
|
|
571
595
|
languageSet: string
|
|
572
596
|
}
|
|
573
597
|
|
|
598
|
+
export declare function canonicalExistingDirectoryIdentity(path: string | Uint8Array): NativeCanonicalDirectoryIdentity
|
|
599
|
+
|
|
574
600
|
/** Clipboard image payload encoded as PNG bytes. */
|
|
575
601
|
export interface ClipboardImage {
|
|
576
602
|
/** PNG-encoded image bytes. */
|
|
@@ -683,6 +709,29 @@ export declare enum Ellipsis {
|
|
|
683
709
|
*/
|
|
684
710
|
export declare function encodeSixel(bytes: Uint8Array, targetWidthPx: number, targetHeightPx: number): string
|
|
685
711
|
|
|
712
|
+
/**
|
|
713
|
+
* Remove an already durably planned detached directory only when a fresh
|
|
714
|
+
* descriptor-relative snapshot exactly equals the persisted snapshot. The
|
|
715
|
+
* caller-planned root remains in place while its opened descriptor is
|
|
716
|
+
* authoritative throughout recursive removal.
|
|
717
|
+
*/
|
|
718
|
+
export declare function exactRemoveDirectoryTree(path: string, snapshot: NativeDirectoryTreeSnapshot): NativeExactUnlinkResult
|
|
719
|
+
|
|
720
|
+
/**
|
|
721
|
+
* Restore only the detached object that still has the supplied platform
|
|
722
|
+
* identity. The detached and original paths must retain the same validated
|
|
723
|
+
* parent, and restoration never replaces an existing original path.
|
|
724
|
+
*/
|
|
725
|
+
export declare function exactRestore(detachedPath: string, originalPath: string, identity: NativeExactFileIdentity): NativeExactUnlinkResult
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Delete only the regular file that still has the supplied platform identity.
|
|
729
|
+
*
|
|
730
|
+
* This never follows a symlink or reparse point in the target path and reports
|
|
731
|
+
* validation failures as typed results rather than deleting a replacement.
|
|
732
|
+
*/
|
|
733
|
+
export declare function exactUnlink(path: string, identity: NativeExactFileIdentity): NativeExactUnlinkResult
|
|
734
|
+
|
|
686
735
|
/**
|
|
687
736
|
* Execute a brush shell command.
|
|
688
737
|
*
|
|
@@ -1045,26 +1094,51 @@ export interface HtmlToMarkdownOptions {
|
|
|
1045
1094
|
}
|
|
1046
1095
|
|
|
1047
1096
|
/**
|
|
1048
|
-
* An inbound message forwarded to the TypeScript host:
|
|
1049
|
-
* in-thread config command,
|
|
1097
|
+
* An authenticated inbound message forwarded to the TypeScript host: free-text
|
|
1098
|
+
* injection, ephemeral side-question request/cancel, in-thread config command,
|
|
1099
|
+
* or deterministic control command.
|
|
1050
1100
|
*/
|
|
1051
1101
|
export interface InboundEvent {
|
|
1052
|
-
/**
|
|
1102
|
+
/**
|
|
1103
|
+
* Inbound kind (`user_message`, `ephemeral_turn`,
|
|
1104
|
+
* `ephemeral_turn_cancel`, `config_command`, or `control_command`).
|
|
1105
|
+
*/
|
|
1053
1106
|
kind: string
|
|
1107
|
+
/**
|
|
1108
|
+
* Server-authenticated identity of the WebSocket connection that delivered
|
|
1109
|
+
* this event.
|
|
1110
|
+
*/
|
|
1111
|
+
connectionId: string
|
|
1054
1112
|
/** The session this inbound belongs to. */
|
|
1055
1113
|
sessionId: string
|
|
1056
|
-
/** Free-text body (`user_message` only). */
|
|
1114
|
+
/** Free-text body (`user_message` or `ephemeral_turn` only). */
|
|
1057
1115
|
text?: string
|
|
1058
|
-
/**
|
|
1116
|
+
/**
|
|
1117
|
+
* Telegram update id for dedupe (`user_message`, `ephemeral_turn`, or
|
|
1118
|
+
* `ephemeral_turn_cancel` only).
|
|
1119
|
+
*/
|
|
1059
1120
|
updateId?: number
|
|
1060
|
-
/**
|
|
1121
|
+
/**
|
|
1122
|
+
* Originating thread/topic id (`user_message`, `ephemeral_turn`, or
|
|
1123
|
+
* `ephemeral_turn_cancel` only).
|
|
1124
|
+
*/
|
|
1061
1125
|
threadId?: string
|
|
1126
|
+
/**
|
|
1127
|
+
* Originating Telegram message id (`ephemeral_turn` and
|
|
1128
|
+
* `ephemeral_turn_cancel` only).
|
|
1129
|
+
*/
|
|
1130
|
+
messageId?: number
|
|
1062
1131
|
/** Requested verbosity `"lean"|"verbose"` (`config_command` only). */
|
|
1063
1132
|
verbosity?: string
|
|
1064
1133
|
/** Requested redaction state (`config_command` only). */
|
|
1065
1134
|
redact?: boolean
|
|
1066
|
-
/**
|
|
1135
|
+
/**
|
|
1136
|
+
* Client-generated request id (`ephemeral_turn`, `ephemeral_turn_cancel`,
|
|
1137
|
+
* or `control_command` only).
|
|
1138
|
+
*/
|
|
1067
1139
|
requestId?: string
|
|
1140
|
+
/** Cancellation reason (`ephemeral_turn_cancel` only). */
|
|
1141
|
+
reason?: string
|
|
1068
1142
|
/** JSON-encoded command payload (`control_command` only). */
|
|
1069
1143
|
commandJson?: string
|
|
1070
1144
|
/**
|
|
@@ -1216,6 +1290,19 @@ export declare enum KeyEventType {
|
|
|
1216
1290
|
Release = 3
|
|
1217
1291
|
}
|
|
1218
1292
|
|
|
1293
|
+
/** Observable counters for the internal known-good N-API frame lane. */
|
|
1294
|
+
export interface KnownGoodFrameStats {
|
|
1295
|
+
/** Frames constructed as `TurnStream` without parsing a JSON string. */
|
|
1296
|
+
knownGoodTurnStreamFrames: number
|
|
1297
|
+
/** JSON serde parses of externally supplied `turn_stream` frames. */
|
|
1298
|
+
turnStreamSerdeValidationParses: number
|
|
1299
|
+
/**
|
|
1300
|
+
* Base64 characters encoded in Rust for `file_attachment` frames (the JS
|
|
1301
|
+
* side crosses raw `Buffer` bytes and never allocates the base64 string).
|
|
1302
|
+
*/
|
|
1303
|
+
fileAttachmentRustBase64Chars: number
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1219
1306
|
/** A lifecycle request forwarded to the TypeScript daemon for orchestration. */
|
|
1220
1307
|
export interface LifecycleRequestEvent {
|
|
1221
1308
|
/** One of `"session_create"`, `"session_close"`, `"session_resume"`. */
|
|
@@ -1415,6 +1502,103 @@ export interface MinimizerResult {
|
|
|
1415
1502
|
|
|
1416
1503
|
export declare function nativeBuildInfo(): BuildInfo
|
|
1417
1504
|
|
|
1505
|
+
/** Result of resolving an existing directory to its stable platform identity. */
|
|
1506
|
+
export type NativeCanonicalDirectoryIdentity =
|
|
1507
|
+
| { ok: true; platform: "posix" | "win32"; canonicalPath: string; code?: never }
|
|
1508
|
+
| {
|
|
1509
|
+
ok: false;
|
|
1510
|
+
platform?: never;
|
|
1511
|
+
canonicalPath?: never;
|
|
1512
|
+
code: "not_found" | "not_directory" | "not_utf8" | "network_unsupported" | "identity_unavailable" | "io_error";
|
|
1513
|
+
}
|
|
1514
|
+
|
|
1515
|
+
/**
|
|
1516
|
+
* A deterministic, no-follow description of a directory tree. `relative_path`
|
|
1517
|
+
* is UTF-8, uses `/` separators, and is empty only for the root entry.
|
|
1518
|
+
*/
|
|
1519
|
+
export interface NativeDirectoryTreeEntry {
|
|
1520
|
+
relativePath: string
|
|
1521
|
+
kind: string
|
|
1522
|
+
dev: string
|
|
1523
|
+
ino: string
|
|
1524
|
+
size: string
|
|
1525
|
+
mtimeNs: string
|
|
1526
|
+
sha256?: string
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
export interface NativeDirectoryTreeResult {
|
|
1530
|
+
ok: boolean
|
|
1531
|
+
code?: string
|
|
1532
|
+
snapshot?: NativeDirectoryTreeSnapshot
|
|
1533
|
+
}
|
|
1534
|
+
|
|
1535
|
+
/**
|
|
1536
|
+
* Stable evidence returned by `snapshot_directory_tree` and consumed verbatim
|
|
1537
|
+
* by `exact_remove_directory_tree`.
|
|
1538
|
+
*/
|
|
1539
|
+
export interface NativeDirectoryTreeSnapshot {
|
|
1540
|
+
rootDev: string
|
|
1541
|
+
rootIno: string
|
|
1542
|
+
entries: Array<NativeDirectoryTreeEntry>
|
|
1543
|
+
}
|
|
1544
|
+
|
|
1545
|
+
/**
|
|
1546
|
+
* Caller-supplied identity and preauthorized quarantine evidence for exact
|
|
1547
|
+
* deletion.
|
|
1548
|
+
*/
|
|
1549
|
+
export interface NativeExactFileIdentity {
|
|
1550
|
+
dev: bigint
|
|
1551
|
+
ino: bigint
|
|
1552
|
+
size: bigint
|
|
1553
|
+
mtimeNs: bigint
|
|
1554
|
+
/**
|
|
1555
|
+
* When true, atomically detach a directory rather than deleting a regular
|
|
1556
|
+
* file.
|
|
1557
|
+
*/
|
|
1558
|
+
directory?: boolean
|
|
1559
|
+
/**
|
|
1560
|
+
* Keep a regular file in quarantine after its identity has been verified
|
|
1561
|
+
* instead of unlinking it. This makes cross-device retirement recoverable.
|
|
1562
|
+
*/
|
|
1563
|
+
detachOnly?: boolean
|
|
1564
|
+
/**
|
|
1565
|
+
* A caller-persisted, single-component no-replace quarantine destination.
|
|
1566
|
+
* Required for every exact deletion so authority survives a post-detach
|
|
1567
|
+
* crash.
|
|
1568
|
+
*/
|
|
1569
|
+
quarantineName?: string
|
|
1570
|
+
/**
|
|
1571
|
+
* SHA-256 of regular-file bytes. Required for regular-file deletion and
|
|
1572
|
+
* verified from the detached object before unlinking it.
|
|
1573
|
+
*/
|
|
1574
|
+
sha256?: string
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
/** Typed result of an identity-bound regular-file deletion or directory detach. */
|
|
1578
|
+
export interface NativeExactUnlinkResult {
|
|
1579
|
+
ok: boolean
|
|
1580
|
+
code?: string
|
|
1581
|
+
detachedPath?: string
|
|
1582
|
+
}
|
|
1583
|
+
|
|
1584
|
+
/** Result of applying or checking owner-only path security. */
|
|
1585
|
+
export type NativeOwnerOnlySecurityResult =
|
|
1586
|
+
| { ok: true; code?: never }
|
|
1587
|
+
| {
|
|
1588
|
+
ok: false;
|
|
1589
|
+
code:
|
|
1590
|
+
| "not_found"
|
|
1591
|
+
| "not_directory"
|
|
1592
|
+
| "network_unsupported"
|
|
1593
|
+
| "reparse_point"
|
|
1594
|
+
| "acl_unavailable"
|
|
1595
|
+
| "acl_apply_failed"
|
|
1596
|
+
| "acl_verify_failed"
|
|
1597
|
+
| "identity_unavailable"
|
|
1598
|
+
| "owner_mismatch"
|
|
1599
|
+
| "io_error";
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1418
1602
|
/** Bound endpoint info returned from [`NotificationServer::start`]. */
|
|
1419
1603
|
export interface NotificationEndpoint {
|
|
1420
1604
|
/** Bind host (loopback). */
|
|
@@ -1543,6 +1727,8 @@ export declare function ptyTimeoutCount(): bigint
|
|
|
1543
1727
|
*/
|
|
1544
1728
|
export declare function readImageFromClipboard(): Promise<ClipboardImage | undefined | null>
|
|
1545
1729
|
|
|
1730
|
+
export declare function renameNoReplacePath(sourcePath: string, destinationPath: string): NativeExactUnlinkResult
|
|
1731
|
+
|
|
1546
1732
|
/** A client reply forwarded to the TypeScript host for gate resolution. */
|
|
1547
1733
|
export interface ReplyEvent {
|
|
1548
1734
|
/**
|
|
@@ -1698,6 +1884,13 @@ export interface SliceResult {
|
|
|
1698
1884
|
*/
|
|
1699
1885
|
export declare function sliceWithWidth(line: string, startCol: number, length: number, strict: boolean | undefined | null, tabWidth: number): SliceResult
|
|
1700
1886
|
|
|
1887
|
+
/**
|
|
1888
|
+
* Capture a deterministic, descriptor-relative snapshot of a regular-file and
|
|
1889
|
+
* directory-only tree. Symlinks, special files, non-UTF-8 names, and topology
|
|
1890
|
+
* changes are rejected rather than followed.
|
|
1891
|
+
*/
|
|
1892
|
+
export declare function snapshotDirectoryTree(path: string): NativeDirectoryTreeResult
|
|
1893
|
+
|
|
1701
1894
|
export declare function summarizeCode(options: SummaryOptions): SummaryResult
|
|
1702
1895
|
|
|
1703
1896
|
export interface SummaryOptions {
|
|
@@ -1749,6 +1942,8 @@ export declare function truncateLinesToWidth(lines: Array<string>, maxWidth: num
|
|
|
1749
1942
|
|
|
1750
1943
|
export declare function truncateToWidth(text: string, maxWidth: number, ellipsisKind: Ellipsis | undefined | null, pad: boolean | undefined | null, tabWidth: number): string
|
|
1751
1944
|
|
|
1945
|
+
export declare function verifyOwnerOnlyPathSecurity(path: string, kind: "directory" | "file"): NativeOwnerOnlySecurityResult
|
|
1946
|
+
|
|
1752
1947
|
/**
|
|
1753
1948
|
* Calculate visible width of text, excluding ANSI escape sequences.
|
|
1754
1949
|
*
|
package/native/index.js
CHANGED
|
@@ -27,15 +27,20 @@ export const PtySession = nativeBindings.PtySession;
|
|
|
27
27
|
export const Shell = nativeBindings.Shell;
|
|
28
28
|
|
|
29
29
|
// functions
|
|
30
|
-
export const
|
|
30
|
+
export const __piNativesV0_11_3 = nativeBindings.__piNativesV0_11_3;
|
|
31
31
|
export const applyBashFixups = nativeBindings.applyBashFixups;
|
|
32
|
+
export const applyOwnerOnlyPathSecurity = nativeBindings.applyOwnerOnlyPathSecurity;
|
|
32
33
|
export const astEdit = nativeBindings.astEdit;
|
|
33
34
|
export const astGrep = nativeBindings.astGrep;
|
|
35
|
+
export const canonicalExistingDirectoryIdentity = nativeBindings.canonicalExistingDirectoryIdentity;
|
|
34
36
|
export const computerScreenshot = nativeBindings.computerScreenshot;
|
|
35
37
|
export const copyToClipboard = nativeBindings.copyToClipboard;
|
|
36
38
|
export const detectMacOSAppearance = nativeBindings.detectMacOSAppearance;
|
|
37
39
|
export const diffLines = nativeBindings.diffLines;
|
|
38
40
|
export const encodeSixel = nativeBindings.encodeSixel;
|
|
41
|
+
export const exactRemoveDirectoryTree = nativeBindings.exactRemoveDirectoryTree;
|
|
42
|
+
export const exactRestore = nativeBindings.exactRestore;
|
|
43
|
+
export const exactUnlink = nativeBindings.exactUnlink;
|
|
39
44
|
export const executeShell = nativeBindings.executeShell;
|
|
40
45
|
export const extractSegments = nativeBindings.extractSegments;
|
|
41
46
|
export const fuzzyFind = nativeBindings.fuzzyFind;
|
|
@@ -67,12 +72,15 @@ export const parseKey = nativeBindings.parseKey;
|
|
|
67
72
|
export const parseKittySequence = nativeBindings.parseKittySequence;
|
|
68
73
|
export const ptyTimeoutCount = nativeBindings.ptyTimeoutCount;
|
|
69
74
|
export const readImageFromClipboard = nativeBindings.readImageFromClipboard;
|
|
75
|
+
export const renameNoReplacePath = nativeBindings.renameNoReplacePath;
|
|
70
76
|
export const search = nativeBindings.search;
|
|
71
77
|
export const sliceWithWidth = nativeBindings.sliceWithWidth;
|
|
78
|
+
export const snapshotDirectoryTree = nativeBindings.snapshotDirectoryTree;
|
|
72
79
|
export const summarizeCode = nativeBindings.summarizeCode;
|
|
73
80
|
export const supportsLanguage = nativeBindings.supportsLanguage;
|
|
74
81
|
export const truncateLinesToWidth = nativeBindings.truncateLinesToWidth;
|
|
75
82
|
export const truncateToWidth = nativeBindings.truncateToWidth;
|
|
83
|
+
export const verifyOwnerOnlyPathSecurity = nativeBindings.verifyOwnerOnlyPathSecurity;
|
|
76
84
|
export const visibleWidth = nativeBindings.visibleWidth;
|
|
77
85
|
export const visibleWidths = nativeBindings.visibleWidths;
|
|
78
86
|
export const wrapTextWithAnsi = nativeBindings.wrapTextWithAnsi;
|
package/native/loader-state.d.ts
CHANGED
|
@@ -71,4 +71,12 @@ export interface LoadFromCandidatesResult<T> {
|
|
|
71
71
|
|
|
72
72
|
export function loadFromCandidates<T>(input: LoadFromCandidatesInput<T>): LoadFromCandidatesResult<T>;
|
|
73
73
|
|
|
74
|
+
export interface CachedEmbeddedExtractionIsFreshInput {
|
|
75
|
+
targetPath: string;
|
|
76
|
+
embeddedPath: string;
|
|
77
|
+
sizeOf: (path: string) => number | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function cachedEmbeddedExtractionIsFresh(input: CachedEmbeddedExtractionIsFreshInput): boolean;
|
|
81
|
+
|
|
74
82
|
export function loadNative(): Record<string, unknown>;
|
package/native/loader-state.js
CHANGED
|
@@ -223,6 +223,23 @@ export function loadFromCandidates({ candidates, requireCandidate, validateCandi
|
|
|
223
223
|
return { bindings: null, errors };
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
+
/**
|
|
227
|
+
* Decide whether a previously extracted embedded addon may be reused. A cached
|
|
228
|
+
* extraction from an earlier build of the same version carries the same version
|
|
229
|
+
* sentinel yet can expose a different native surface, so it is fresh only when
|
|
230
|
+
* its byte size matches the embedded payload. `sizeOf` returns the byte size of
|
|
231
|
+
* a path, or `null` when it cannot be inspected.
|
|
232
|
+
* @param {{ targetPath: string; embeddedPath: string; sizeOf: (path: string) => number | null }} input
|
|
233
|
+
* @returns {boolean}
|
|
234
|
+
*/
|
|
235
|
+
export function cachedEmbeddedExtractionIsFresh({ targetPath, embeddedPath, sizeOf }) {
|
|
236
|
+
const cachedSize = sizeOf(targetPath);
|
|
237
|
+
if (cachedSize === null) return false;
|
|
238
|
+
const embeddedSize = sizeOf(embeddedPath);
|
|
239
|
+
if (embeddedSize === null) return false;
|
|
240
|
+
return cachedSize === embeddedSize;
|
|
241
|
+
}
|
|
242
|
+
|
|
226
243
|
// =========================================================================
|
|
227
244
|
// Side-effectful loader. Everything below runs only when `loadNative()` is
|
|
228
245
|
// called from `native/index.js` — tests that only import the pure helpers
|
|
@@ -310,7 +327,23 @@ function maybeExtractEmbeddedAddon(ctx, errors) {
|
|
|
310
327
|
const selectedEmbeddedFile = selectEmbeddedAddonFile(ctx.selectedVariant);
|
|
311
328
|
if (!selectedEmbeddedFile) return null;
|
|
312
329
|
const targetPath = path.join(ctx.versionedDir, selectedEmbeddedFile.filename);
|
|
313
|
-
if (fs.existsSync(targetPath))
|
|
330
|
+
if (fs.existsSync(targetPath)) {
|
|
331
|
+
// Guard against intra-version drift: a cached extraction written by an earlier
|
|
332
|
+
// build of the same version carries the same version sentinel but can expose a
|
|
333
|
+
// different native surface (e.g. a symbol added mid-cycle). The embedded addon
|
|
334
|
+
// is the source of truth, so reuse the cached file only when it matches the
|
|
335
|
+
// embedded payload size and re-extract otherwise.
|
|
336
|
+
const sizeOf = candidate => {
|
|
337
|
+
try {
|
|
338
|
+
return fs.statSync(candidate).size;
|
|
339
|
+
} catch {
|
|
340
|
+
return null;
|
|
341
|
+
}
|
|
342
|
+
};
|
|
343
|
+
if (cachedEmbeddedExtractionIsFresh({ targetPath, embeddedPath: selectedEmbeddedFile.filePath, sizeOf })) {
|
|
344
|
+
return targetPath;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
314
347
|
|
|
315
348
|
try {
|
|
316
349
|
fs.mkdirSync(ctx.versionedDir, { recursive: true });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gajae-code/natives",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.3",
|
|
4
4
|
"description": "Native Rust bindings for grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
@@ -61,11 +61,11 @@
|
|
|
61
61
|
"README.md"
|
|
62
62
|
],
|
|
63
63
|
"optionalDependencies": {
|
|
64
|
-
"@gajae-code/natives-darwin-arm64": "0.11.
|
|
65
|
-
"@gajae-code/natives-darwin-x64": "0.11.
|
|
66
|
-
"@gajae-code/natives-linux-arm64": "0.11.
|
|
67
|
-
"@gajae-code/natives-linux-x64": "0.11.
|
|
68
|
-
"@gajae-code/natives-win32-x64": "0.11.
|
|
64
|
+
"@gajae-code/natives-darwin-arm64": "0.11.3",
|
|
65
|
+
"@gajae-code/natives-darwin-x64": "0.11.3",
|
|
66
|
+
"@gajae-code/natives-linux-arm64": "0.11.3",
|
|
67
|
+
"@gajae-code/natives-linux-x64": "0.11.3",
|
|
68
|
+
"@gajae-code/natives-win32-x64": "0.11.3"
|
|
69
69
|
},
|
|
70
70
|
"exports": {
|
|
71
71
|
".": {
|