@gajae-code/natives 0.16.7 → 0.17.1

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 CHANGED
@@ -52,6 +52,12 @@ export declare class ComputerController {
52
52
  wait(expectedEpoch: number | undefined | null, ms: number): void
53
53
  }
54
54
 
55
+ export declare class DoctorJournalAuthority {
56
+ static createExact(root: string, runId: string): DoctorJournalCreateResult
57
+ append(record: string): void
58
+ close(): void
59
+ }
60
+
55
61
  /**
56
62
  * Long-lived macOS appearance observer.
57
63
  *
@@ -124,6 +130,29 @@ export declare class NativeRetainedBrokerPublication {
124
130
  * unbounded write is exactly the wedge this must not reproduce.
125
131
  */
126
132
  close(): NativeBrokerPublicationOperation
133
+ /**
134
+ * Owner-side prepare: exclusively creates the retained restart-intent slot
135
+ * and keeps its descriptor open, so a later commit/cancel from this same
136
+ * process never reopens by name.
137
+ */
138
+ prepareRestartIntentAsync(intent: NativeBrokerRestartIntent): Promise<NativeBrokerPublicationOperation>
139
+ /**
140
+ * Owner-side commit: rewrites the SAME retained descriptor from prepare, so
141
+ * the transition can never race a different file occupying the name.
142
+ */
143
+ commitRestartIntentAsync(intent: NativeBrokerRestartIntent): Promise<NativeBrokerPublicationOperation>
144
+ /**
145
+ * Owner-side cancel: exact-identity unlink of this process's own retained
146
+ * slot. A lease expiry (no live owner to call this) leaves the file for the
147
+ * successor's verified `clear_restart_intent_async` instead.
148
+ */
149
+ cancelRestartIntentAsync(): Promise<NativeBrokerPublicationOperation>
150
+ /**
151
+ * Successor-side clear: exact-identity unlink of a predecessor's restart
152
+ * slot this process never prepared itself. Only removes the name when its
153
+ * current on-disk identity still matches the caller-proven dev/ino.
154
+ */
155
+ clearRestartIntentAsync(identity: NativeBrokerRestartIntentIdentity): Promise<NativeBrokerPublicationOperation>
127
156
  }
128
157
 
129
158
  /** In-process notification server handle exposed to TypeScript. */
@@ -327,6 +356,16 @@ export declare class Process {
327
356
  static fromPid(pid: number): Process | null
328
357
  /** Open stable process references whose executable path matches exactly. */
329
358
  static fromPath(path: string): Array<Process>
359
+ /**
360
+ * Read-only observation of whether `pid` currently names a verifiable
361
+ * process incarnation.
362
+ *
363
+ * Unlike [`Self::from_pid`] returning `null` (which conflates a confirmed-
364
+ * dead pid with one that simply could not be queried), this keeps positive
365
+ * OS-reported absence separate from every inconclusive outcome. It never
366
+ * signals, kills, reaps, waits on, or spawns any process.
367
+ */
368
+ static observe(pid: number): NativeProcessObservation
330
369
  /** Operating-system process identifier for this process reference. */
331
370
  get pid(): number
332
371
  /** Kernel-derived identity evidence for this exact process incarnation. */
@@ -544,7 +583,7 @@ export declare function __piNativesPublishOutcomeV1(): void
544
583
  * `packages/natives/native/index.js` (which derives the name from
545
584
  * `package.json#version`).
546
585
  */
547
- export declare function __piNativesV0_16_7(): void
586
+ export declare function __piNativesV0_17_1(): void
548
587
 
549
588
  /**
550
589
  * Apply conservative pre-execution rewrites to a bash command.
@@ -868,6 +907,19 @@ export declare function detectMacOSAppearance(): MacOSAppearance | null
868
907
  */
869
908
  export declare function diffLines(oldStr: string, newStr: string): Array<LineDiffPart>
870
909
 
910
+ export interface DoctorJournalCreateResult {
911
+ authority?: DoctorJournalAuthority
912
+ sideEffectStarted: boolean
913
+ reasonCode?: string
914
+ }
915
+
916
+ export interface DoctorLinkSwapResult {
917
+ status: string
918
+ changed: boolean
919
+ verified: boolean
920
+ code?: string
921
+ }
922
+
871
923
  /** Ellipsis strategy for [`truncate_to_width`]. */
872
924
  export declare enum Ellipsis {
873
925
  /** Use a single Unicode ellipsis character ("…"). */
@@ -896,7 +948,7 @@ export declare function encodeSixel(bytes: Uint8Array, targetWidthPx: number, ta
896
948
  * detached descriptor remains authoritative throughout payload scrubbing and
897
949
  * replay.
898
950
  */
899
- export declare function exactRemoveDirectoryTree(path: string, snapshot: NativeDirectoryTreeSnapshot, parentIdentity?: NativeDirectoryParentIdentity | undefined | null): NativeExactUnlinkResult
951
+ export declare function exactRemoveDirectoryTree(path: string, snapshot: NativeDirectoryTreeSnapshot, parentIdentity?: NativeDirectoryParentIdentity | undefined | null, detachOnly?: boolean | undefined | null): NativeExactUnlinkResult
900
952
 
901
953
  /**
902
954
  * Atomically replace a staged regular file only after validating the exact
@@ -908,6 +960,45 @@ export declare function exactRemoveDirectoryTree(path: string, snapshot: NativeD
908
960
  */
909
961
  export declare function exactReplacePath(sourcePath: string, destinationPath: string, expectedSource: NativeExactFileIdentity, expectedDestination: NativeExactFileIdentity): NativeExactUnlinkResult
910
962
 
963
+ /**
964
+ * Atomically replace an in-place executable (or other running-process
965
+ * payload) only after validating the exact staged source and current
966
+ * destination.
967
+ *
968
+ * The old destination bytes are retired to a caller-preauthorized backup
969
+ * name instead of being scrubbed or unlinked.
970
+ *
971
+ * This exists for D4 self-replacement: [`exact_replace_path`] retires its
972
+ * predecessor through the same descriptor-scrub/exchange-cleanup protocol
973
+ * [`exact_unlink`] uses, which either truncates the old bytes in place
974
+ * (POSIX, when the exchange succeeds) or deletes them outright (Windows).
975
+ * Both are safe for a config file with no open executing mapping, but unsafe
976
+ * for a binary a running process may still be mapped from or about to
977
+ * re-exec: scrubbing or deleting those bytes out from under a live mapping
978
+ * can crash the very process performing the update. `exact_replace_retained`
979
+ * therefore never truncates or deletes the predecessor at all -- it commits
980
+ * the atomic exchange (POSIX) or native rename swap (Windows) and then
981
+ * renames the old destination to `backup_name` in the same parent, leaving
982
+ * its bytes byte-for-byte intact and readable at that retained path.
983
+ *
984
+ * `backup_name` must be a bounded (<=255 bytes), single-path-component,
985
+ * separator-free, non-`.`/`..` name; it is used verbatim, with no
986
+ * auto-suffixing, and an already-occupied backup name is refused rather than
987
+ * overwritten -- the caller is responsible for choosing a name that will not
988
+ * collide with a foreign object, and a collision leaves the retired
989
+ * predecessor's replacement decision to a later caller rather than losing
990
+ * data. Both identities must describe regular files in the same retained
991
+ * parent, never directories or detach-only requests, and both are
992
+ * CAS-checked (parent identity + dev/ino/size/mtime/hash + regular/
993
+ * single-link ownership; hard-linked or symlinked source/destination are
994
+ * rejected) before anything is mutated. On Windows a pre-mutation
995
+ * `STATUS_SHARING_VIOLATION` on the destination open is reported as a
996
+ * distinct `sharing_violation` code with `windows_error_code` set -- exactly
997
+ * as [`exact_replace_path`] already reports it -- and is always surfaced
998
+ * before any rename, so it is never mistaken for a post-effect failure.
999
+ */
1000
+ export declare function exactReplaceRetained(sourcePath: string, destinationPath: string, backupName: string, expectedSource: NativeExactFileIdentity, expectedDestination: NativeExactFileIdentity): NativeExactUnlinkResult
1001
+
911
1002
  /**
912
1003
  * Restore only the detached object that still has the supplied exact
913
1004
  * identity. The detached and original paths must retain the same validated
@@ -915,6 +1006,17 @@ export declare function exactReplacePath(sourcePath: string, destinationPath: st
915
1006
  */
916
1007
  export declare function exactRestore(detachedPath: string, originalPath: string, identity: NativeExactFileIdentity): NativeExactUnlinkResult
917
1008
 
1009
+ /**
1010
+ * Exchange a staged symlink with the expected destination using the platform
1011
+ * atomic name-exchange primitive.
1012
+ *
1013
+ * The destination's parent is retained as a single opened descriptor for
1014
+ * every check and mutation. The retired link is moved into `quarantine_path`
1015
+ * with a no-replace rename; it is never deleted and a foreign occupant at
1016
+ * any of the three names is always refused rather than overwritten.
1017
+ */
1018
+ export declare function exactSwapManagedLink(stagedPath: string, destinationPath: string, quarantinePath: string, parentDev: string, parentIno: string, oldDev: string, oldIno: string, oldTarget: string, stagedDev: string, stagedIno: string, newTarget: string): DoctorLinkSwapResult
1019
+
918
1020
  /**
919
1021
  * Delete only the regular file that still has the supplied platform identity.
920
1022
  *
@@ -1026,6 +1128,15 @@ export interface FuzzyFindResult {
1026
1128
  totalMatches: number
1027
1129
  }
1028
1130
 
1131
+ /**
1132
+ * Protocol version for [`exact_swap_managed_link`]'s argument contract.
1133
+ *
1134
+ * The caller checks this before staging anything so a stale addon (old
1135
+ * argument order/count) is refused up front rather than discovered
1136
+ * mid-mutation.
1137
+ */
1138
+ export declare function getDoctorLinkProtocolVersion(): number
1139
+
1029
1140
  /** Get list of supported languages. */
1030
1141
  export declare function getSupportedLanguages(): Array<string>
1031
1142
 
@@ -1379,6 +1490,12 @@ export interface InboundImageEvent {
1379
1490
  */
1380
1491
  export declare function initNativeCrashDiagnostics(): boolean
1381
1492
 
1493
+ /**
1494
+ * Validate the exact permission repair preconditions without changing
1495
+ * metadata.
1496
+ */
1497
+ export declare function inspectConfigFilePermissionRepair(path: string, identity: NativeExactFileIdentity, expectedMode: number): NativePermissionRepairResult
1498
+
1382
1499
  /**
1383
1500
  * Invalidate the filesystem scan cache.
1384
1501
  *
@@ -1742,6 +1859,22 @@ export interface NativeBrokerPublicationOperation {
1742
1859
  kind: string
1743
1860
  }
1744
1861
 
1862
+ export interface NativeBrokerRestartIntent {
1863
+ requestId: string
1864
+ lease: string
1865
+ expiresAt: number
1866
+ }
1867
+
1868
+ /**
1869
+ * Existing file-identity cross-bind (never a secret) that authorizes a
1870
+ * successor to remove a predecessor's restart-intent slot it never itself
1871
+ * prepared.
1872
+ */
1873
+ export interface NativeBrokerRestartIntentIdentity {
1874
+ dev: bigint
1875
+ ino: bigint
1876
+ }
1877
+
1745
1878
  export declare function nativeBuildInfo(): BuildInfo
1746
1879
 
1747
1880
  /** Result of resolving an existing directory to its stable platform identity. */
@@ -1965,6 +2098,50 @@ export type NativeOwnerOnlySecurityResult =
1965
2098
  aclEvidence?: never;
1966
2099
  }
1967
2100
 
2101
+ /** Result of removing group/other permission bits from one exact config file. */
2102
+ export interface NativePermissionRepairResult {
2103
+ status: string
2104
+ changed: boolean
2105
+ verified: boolean
2106
+ code?: string
2107
+ }
2108
+
2109
+ /**
2110
+ * Read-only, non-mutating observation of whether a pid currently names a
2111
+ * verifiable process incarnation.
2112
+ *
2113
+ * `status` discriminates the three outcomes described on
2114
+ * [`pi_shell::process::ProcessObservation`]:
2115
+ * - `"present"` — `incarnation` is the exact kernel-reported identity
2116
+ * evidence.
2117
+ * - `"absent"` — the OS positively confirmed no process currently has this
2118
+ * pid.
2119
+ * - `"unknown"` — `reasonCode` explains why liveness could not be determined
2120
+ * (e.g. an invalid pid, a permission denial, or a platform limitation); this
2121
+ * is never proof of death.
2122
+ */
2123
+ export interface NativeProcessObservation {
2124
+ status: 'present' | 'absent' | 'unknown'
2125
+ incarnation?: string
2126
+ reasonCode?: string
2127
+ }
2128
+
2129
+ /** Bounded, path-free evidence for one publish operation. */
2130
+ export interface NativePublishDiagnostic {
2131
+ schemaVersion: number
2132
+ collectionState: string
2133
+ osCode?: number
2134
+ syncFailures?: Array<NativePublishSyncFailure>
2135
+ }
2136
+
2137
+ /** Bounded, path-free evidence for one publish operation. */
2138
+ export interface NativePublishSyncFailure {
2139
+ phase: string
2140
+ parentRole: string
2141
+ osCode: number
2142
+ kind: string
2143
+ }
2144
+
1968
2145
  /** Bound endpoint info returned from [`NotificationServer::start`]. */
1969
2146
  export interface NotificationEndpoint {
1970
2147
  /** Bind host (loopback). */
@@ -2195,6 +2372,12 @@ export declare function renameNoReplacePath(sourcePath: string, destinationPath:
2195
2372
  */
2196
2373
  export declare function renameNoReplacePathAsync(sourcePath: string, destinationPath: string): Promise<NativeNoReplaceResult>
2197
2374
 
2375
+ /**
2376
+ * Remove only group/other permission bits from an exact, user-owned regular
2377
+ * file.
2378
+ */
2379
+ export declare function repairConfigFilePermissions(path: string, identity: NativeExactFileIdentity, expectedMode: number): NativePermissionRepairResult
2380
+
2198
2381
  /**
2199
2382
  * Repair an owner-only ACL on a retained expected path.
2200
2383
  *
@@ -2494,19 +2677,3 @@ export interface WorkProfile {
2494
2677
  * Returns UTF-16 lines with active SGR codes carried across line boundaries.
2495
2678
  */
2496
2679
  export declare function wrapTextWithAnsi(text: string, width: number, tabWidth: number): Array<string>
2497
-
2498
- /** Bounded, path-free evidence for a parent-directory durability failure. */
2499
- export interface NativePublishSyncFailure {
2500
- phase: string
2501
- parentRole: string
2502
- osCode: number
2503
- kind: string
2504
- }
2505
-
2506
- /** Bounded, path-free evidence for one atomic publication. */
2507
- export interface NativePublishDiagnostic {
2508
- schemaVersion: number
2509
- collectionState: string
2510
- osCode?: number
2511
- syncFailures?: Array<NativePublishSyncFailure>
2512
- }
package/native/index.js CHANGED
@@ -18,6 +18,7 @@ nativeBindings.initNativeCrashDiagnostics?.();
18
18
  // --- generated native exports (do not edit) ---
19
19
  // classes
20
20
  export const ComputerController = nativeBindings.ComputerController;
21
+ export const DoctorJournalAuthority = nativeBindings.DoctorJournalAuthority;
21
22
  export const MacAppearanceObserver = nativeBindings.MacAppearanceObserver;
22
23
  export const MacOSPowerAssertion = nativeBindings.MacOSPowerAssertion;
23
24
  export const NativeRetainedBrokerPublication = nativeBindings.NativeRetainedBrokerPublication;
@@ -30,7 +31,7 @@ export const Shell = nativeBindings.Shell;
30
31
 
31
32
  // functions
32
33
  export const __piNativesPublishOutcomeV1 = nativeBindings.__piNativesPublishOutcomeV1;
33
- export const __piNativesV0_16_7 = nativeBindings.__piNativesV0_16_7;
34
+ export const __piNativesV0_17_1 = nativeBindings.__piNativesV0_17_1;
34
35
  export const applyBashFixups = nativeBindings.applyBashFixups;
35
36
  export const applyOwnerOnlyFdSecurity = nativeBindings.applyOwnerOnlyFdSecurity;
36
37
  export const applyOwnerOnlyPathSecurity = nativeBindings.applyOwnerOnlyPathSecurity;
@@ -45,13 +46,16 @@ export const diffLines = nativeBindings.diffLines;
45
46
  export const encodeSixel = nativeBindings.encodeSixel;
46
47
  export const exactRemoveDirectoryTree = nativeBindings.exactRemoveDirectoryTree;
47
48
  export const exactReplacePath = nativeBindings.exactReplacePath;
49
+ export const exactReplaceRetained = nativeBindings.exactReplaceRetained;
48
50
  export const exactRestore = nativeBindings.exactRestore;
51
+ export const exactSwapManagedLink = nativeBindings.exactSwapManagedLink;
49
52
  export const exactUnlink = nativeBindings.exactUnlink;
50
53
  export const exactUnlinkDirect = nativeBindings.exactUnlinkDirect;
51
54
  export const exactUnlinkDirectDetached = nativeBindings.exactUnlinkDirectDetached;
52
55
  export const executeShell = nativeBindings.executeShell;
53
56
  export const extractSegments = nativeBindings.extractSegments;
54
57
  export const fuzzyFind = nativeBindings.fuzzyFind;
58
+ export const getDoctorLinkProtocolVersion = nativeBindings.getDoctorLinkProtocolVersion;
55
59
  export const getSupportedLanguages = nativeBindings.getSupportedLanguages;
56
60
  export const getWorkProfile = nativeBindings.getWorkProfile;
57
61
  export const glob = nativeBindings.glob;
@@ -63,6 +67,7 @@ export const hasMatch = nativeBindings.hasMatch;
63
67
  export const highlightCode = nativeBindings.highlightCode;
64
68
  export const htmlToMarkdown = nativeBindings.htmlToMarkdown;
65
69
  export const initNativeCrashDiagnostics = nativeBindings.initNativeCrashDiagnostics;
70
+ export const inspectConfigFilePermissionRepair = nativeBindings.inspectConfigFilePermissionRepair;
66
71
  export const invalidateFsScanCache = nativeBindings.invalidateFsScanCache;
67
72
  export const isoBackend = nativeBindings.isoBackend;
68
73
  export const isoDiff = nativeBindings.isoDiff;
@@ -88,6 +93,7 @@ export const renameDirectoryNoReplacePath = nativeBindings.renameDirectoryNoRepl
88
93
  export const renameDirectoryNoReplacePathAsync = nativeBindings.renameDirectoryNoReplacePathAsync;
89
94
  export const renameNoReplacePath = nativeBindings.renameNoReplacePath;
90
95
  export const renameNoReplacePathAsync = nativeBindings.renameNoReplacePathAsync;
96
+ export const repairConfigFilePermissions = nativeBindings.repairConfigFilePermissions;
91
97
  export const repairOwnerOnlyPathSecurityExpected = nativeBindings.repairOwnerOnlyPathSecurityExpected;
92
98
  export const retainBrokerPublication = nativeBindings.retainBrokerPublication;
93
99
  export const search = nativeBindings.search;
@@ -107,6 +107,7 @@ export function validateLoadedBindings(
107
107
 
108
108
  export interface LoaderContext {
109
109
  isCompiledBinary: boolean;
110
+ isWorkspaceLoad?: boolean;
110
111
  platformTag: string;
111
112
  packageVersion?: string;
112
113
  addonLabel?: string;
@@ -777,6 +777,9 @@ function buildHelpMessage(ctx) {
777
777
  return (
778
778
  "If installed via npm/bun, try reinstalling: bun install @gajae-code/natives\n" +
779
779
  "If developing locally, build with: bun --cwd=packages/natives run build\n" +
780
+ (ctx.isWorkspaceLoad
781
+ ? "In a fresh `git worktree add` checkout, run the worktree-safe setup: bun run setup:worktree\n"
782
+ : "") +
780
783
  "Optional x64 variants: TARGET_VARIANT=baseline|modern bun --cwd=packages/natives run build"
781
784
  );
782
785
  }
@@ -847,6 +850,7 @@ function initLoaderContext(require_) {
847
850
  nativeDir,
848
851
  versionedDir,
849
852
  isCompiledBinary,
853
+ isWorkspaceLoad,
850
854
  stageFromNodeModules,
851
855
  selectedVariant,
852
856
  addonFilenames,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gajae-code/natives",
3
- "version": "0.16.7",
3
+ "version": "0.17.1",
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.16.7",
65
- "@gajae-code/natives-darwin-x64": "0.16.7",
66
- "@gajae-code/natives-linux-arm64": "0.16.7",
67
- "@gajae-code/natives-linux-x64": "0.16.7",
68
- "@gajae-code/natives-win32-x64": "0.16.7"
64
+ "@gajae-code/natives-darwin-arm64": "0.17.1",
65
+ "@gajae-code/natives-darwin-x64": "0.17.1",
66
+ "@gajae-code/natives-linux-arm64": "0.17.1",
67
+ "@gajae-code/natives-linux-x64": "0.17.1",
68
+ "@gajae-code/natives-win32-x64": "0.17.1"
69
69
  },
70
70
  "exports": {
71
71
  ".": {