@linxiraos/pi-natives 1.1.4 → 1.1.6

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
@@ -61,6 +61,43 @@ export declare class DesktopSession {
61
61
  close(): Promise<undefined>
62
62
  }
63
63
 
64
+ /**
65
+ * Incrementally ingests old/new text and computes an exact line diff on a
66
+ * worker thread once both sides finish.
67
+ *
68
+ * Complete lines are observable during ingestion. Only equal leading lines
69
+ * are declared stable before EOF; future input can change Myers alignment
70
+ * after the first mismatch.
71
+ */
72
+ export declare class DiffStream {
73
+ /** Create an empty two-sided stream. */
74
+ constructor()
75
+ /** Append a JavaScript text chunk to one side. */
76
+ push(side: DiffSide, chunk: string): DiffStreamProgress
77
+ /** Append a UTF-8 subprocess/file chunk without a JS string conversion. */
78
+ pushBytes(side: DiffSide, chunk: Uint8Array): DiffStreamProgress
79
+ /** Mark one side complete; an unfinished final line then becomes visible. */
80
+ finishSide(side: DiffSide): DiffStreamProgress
81
+ /** Mark one side too large and complete without further ingestion. */
82
+ markTooLarge(side: DiffSide): DiffStreamProgress
83
+ /** Current ingestion state. */
84
+ progress(): DiffStreamProgress
85
+ /** Complete display lines from `from`, excluding newline terminators. */
86
+ lines(side: DiffSide, from: number, limit?: number | undefined | null): Array<string>
87
+ /** Snapshot all ingested text for one side. */
88
+ text(side: DiffSide): string
89
+ /**
90
+ * Read a filesystem path directly into one side on the native worker pool.
91
+ *
92
+ * JavaScript can poll [`DiffStream::progress`] and [`DiffStream::lines`]
93
+ * while this promise is pending; file bytes never need to cross into JS
94
+ * and back into the differ.
95
+ */
96
+ openFile(side: DiffSide, path: string, maxBytes?: number | undefined | null, signal?: unknown | undefined | null): Promise<DiffStreamProgress>
97
+ /** Compute exact Myers runs and unified hunks off the JavaScript thread. */
98
+ finish(context?: number | undefined | null): Promise<DiffStreamResult>
99
+ }
100
+
64
101
  /**
65
102
  * Process-owned cross-platform advisory lock.
66
103
  *
@@ -294,6 +331,203 @@ export declare class TtyWriter {
294
331
  stop(flushTimeoutMs: number): void
295
332
  }
296
333
 
334
+ /** In-process Git repository handle. */
335
+ export declare class VcsGitRepo {
336
+ /** Repository metadata. */
337
+ info(): VcsGitRepoInfo
338
+ /** Primary checkout root. */
339
+ primaryRoot(): string
340
+ /** Linked-worktree metadata. */
341
+ linkedWorktree(): VcsLinkedWorktree | null
342
+ /** Resolve HEAD synchronously. */
343
+ headSync(): VcsHeadState
344
+ /** Worktree-relative prefix of a directory. */
345
+ prefixOf(dir: string): string | null
346
+ /** Resolve HEAD. */
347
+ head(signal?: unknown | undefined | null): Promise<VcsHeadState>
348
+ /** Resolve HEAD SHA. */
349
+ headSha(signal?: unknown | undefined | null): Promise<string | undefined | null>
350
+ /** Current branch. */
351
+ currentBranch(signal?: unknown | undefined | null): Promise<string | undefined | null>
352
+ /** Default remote branch. */
353
+ defaultBranch(signal?: unknown | undefined | null): Promise<string | undefined | null>
354
+ /** Resolve a revision. */
355
+ resolveRef(name: string, signal?: unknown | undefined | null): Promise<string | undefined | null>
356
+ /** Test revision existence. */
357
+ refExists(name: string, signal?: unknown | undefined | null): Promise<boolean>
358
+ /** Tags pointing at a revision. */
359
+ tagsAt(rev: string, signal?: unknown | undefined | null): Promise<Array<string>>
360
+ /** List branches. */
361
+ listBranches(all: boolean, signal?: unknown | undefined | null): Promise<Array<string>>
362
+ /**
363
+ * Whether default porcelain status reports a staged, unstaged, or untracked
364
+ * change.
365
+ */
366
+ isDirty(signal?: unknown | undefined | null): Promise<boolean>
367
+ /** Porcelain status. */
368
+ statusPorcelain(options: VcsStatusOptions, signal?: unknown | undefined | null): Promise<string>
369
+ /** Status counts. */
370
+ statusSummary(signal?: unknown | undefined | null): Promise<VcsStatusSummary>
371
+ /** Read config. */
372
+ configGet(key: string, signal?: unknown | undefined | null): Promise<string | undefined | null>
373
+ /** Set config. */
374
+ configSet(key: string, value: string, signal?: unknown | undefined | null): Promise<undefined>
375
+ /** List remotes. */
376
+ remoteList(signal?: unknown | undefined | null): Promise<Array<string>>
377
+ /** Remote URL. */
378
+ remoteUrl(name: string, signal?: unknown | undefined | null): Promise<string | undefined | null>
379
+ /** Add remote. */
380
+ remoteAdd(name: string, url: string, signal?: unknown | undefined | null): Promise<undefined>
381
+ /** List worktrees. */
382
+ worktrees(signal?: unknown | undefined | null): Promise<Array<VcsWorktreeEntry>>
383
+ /** Add worktree. */
384
+ worktreeAdd(path: string, refName: string, detach: boolean, signal?: unknown | undefined | null): Promise<undefined>
385
+ /** Remove worktree. */
386
+ worktreeRemove(path: string, force: boolean, signal?: unknown | undefined | null): Promise<boolean>
387
+ /** Prune worktrees. */
388
+ worktreePrune(signal?: unknown | undefined | null): Promise<undefined>
389
+ /** Recent subjects. */
390
+ logSubjects(count: number, signal?: unknown | undefined | null): Promise<Array<string>>
391
+ /** Recent one-line commits. */
392
+ logOnelines(count: number, signal?: unknown | undefined | null): Promise<Array<string>>
393
+ /** Commits in a range. */
394
+ revListRange(base: string, head: string, signal?: unknown | undefined | null): Promise<Array<string>>
395
+ /** Best common ancestor of two revisions. */
396
+ mergeBase(a: string, b: string, signal?: unknown | undefined | null): Promise<string | undefined | null>
397
+ /** Commits touching a file. */
398
+ revListTouching(rev: string, file: string, limit: number, signal?: unknown | undefined | null): Promise<Array<string>>
399
+ /** Commit details. */
400
+ commitDetails(rev: string, signal?: unknown | undefined | null): Promise<VcsCommitDetails>
401
+ /** List index or untracked paths. */
402
+ lsFiles(others: boolean, excludeStandard: boolean, signal?: unknown | undefined | null): Promise<Array<string>>
403
+ /** List tree paths. */
404
+ lsTree(rev: string, paths: Array<string>, signal?: unknown | undefined | null): Promise<Array<string>>
405
+ /** List submodule paths. */
406
+ submodulePaths(signal?: unknown | undefined | null): Promise<Array<string>>
407
+ /** Read blob bytes. */
408
+ showBlob(spec: string, maxBytes?: number | undefined | null, signal?: unknown | undefined | null): Promise<VcsShowResult>
409
+ /** Read commit and patch bytes. */
410
+ showCommit(rev: string, maxBytes?: number | undefined | null, signal?: unknown | undefined | null): Promise<VcsShowResult>
411
+ /** Local LFS media directory. */
412
+ lfsMediaDir(signal?: unknown | undefined | null): Promise<string | undefined | null>
413
+ /** Render a patch. */
414
+ diffText(options: VcsDiffOptions, signal?: unknown | undefined | null): Promise<string>
415
+ /** Render a no-index patch between two filesystem paths. */
416
+ diffNoIndex(left: string, right: string, binary: boolean, signal?: unknown | undefined | null): Promise<string>
417
+ /** Changed paths. */
418
+ changedFiles(options: VcsDiffOptions, signal?: unknown | undefined | null): Promise<Array<string>>
419
+ /** Per-file line counts. */
420
+ numstat(options: VcsDiffOptions, signal?: unknown | undefined | null): Promise<Array<VcsNumstatEntry>>
421
+ /** Test for a diff. */
422
+ hasDiff(options: VcsDiffOptions, signal?: unknown | undefined | null): Promise<boolean>
423
+ /** Diff two trees. */
424
+ diffTree(base: string, head: string, binary: boolean, signal?: unknown | undefined | null): Promise<string>
425
+ /** Stage paths. */
426
+ stageFiles(files: Array<string>, signal?: unknown | undefined | null): Promise<undefined>
427
+ /** Unstage paths. */
428
+ unstage(files: Array<string>, signal?: unknown | undefined | null): Promise<undefined>
429
+ /** Stage selected hunks. */
430
+ stageHunks(selections: Array<VcsHunkSelection>, rawDiff?: string | undefined | null, signal?: unknown | undefined | null): Promise<undefined>
431
+ /** Create commit. */
432
+ commitCreate(message: string, options: VcsCommitOptions, signal?: unknown | undefined | null): Promise<string>
433
+ /** Checkout revision. */
434
+ checkout(rev: string, signal?: unknown | undefined | null): Promise<undefined>
435
+ /** Create branch. */
436
+ createBranch(name: string, start: string, force: boolean, signal?: unknown | undefined | null): Promise<undefined>
437
+ /** Delete branch. */
438
+ deleteBranch(name: string, force: boolean, signal?: unknown | undefined | null): Promise<boolean>
439
+ /** Create and checkout branch. */
440
+ checkoutNewBranch(name: string, signal?: unknown | undefined | null): Promise<undefined>
441
+ /** Restore paths. */
442
+ restore(options: VcsRestoreOptions, signal?: unknown | undefined | null): Promise<undefined>
443
+ /** Reset repository state. */
444
+ reset(mode: string, target?: string | undefined | null, signal?: unknown | undefined | null): Promise<undefined>
445
+ /** Clean untracked paths. */
446
+ clean(options: VcsCleanOptions, signal?: unknown | undefined | null): Promise<undefined>
447
+ /** Read tree into index. */
448
+ readTree(treeish: string, indexPath?: string | undefined | null, signal?: unknown | undefined | null): Promise<undefined>
449
+ /** Write index tree. */
450
+ writeTree(indexPath?: string | undefined | null, signal?: unknown | undefined | null): Promise<string>
451
+ /** Apply patch. */
452
+ applyPatch(patch: string, options: VcsApplyOptions, signal?: unknown | undefined | null): Promise<undefined>
453
+ /** Check patch applicability. */
454
+ canApplyPatch(patch: string, options: VcsApplyOptions, signal?: unknown | undefined | null): Promise<boolean>
455
+ /** Cherry-pick commit. */
456
+ cherryPick(rev: string, signal?: unknown | undefined | null): Promise<undefined>
457
+ /** Abort cherry-pick. */
458
+ cherryPickAbort(signal?: unknown | undefined | null): Promise<undefined>
459
+ /** Skip cherry-pick. */
460
+ cherryPickSkip(signal?: unknown | undefined | null): Promise<undefined>
461
+ /** Push stash. */
462
+ stashPush(message?: string | undefined | null, signal?: unknown | undefined | null): Promise<boolean>
463
+ /** Pop stash if cleanly applicable. */
464
+ stashTryPop(reinstateIndex: boolean, signal?: unknown | undefined | null): Promise<boolean>
465
+ /** Push via Git CLI. */
466
+ push(options: VcsPushOptions, signal?: unknown | undefined | null): Promise<void>
467
+ /** Fetch a refspec via Git CLI. */
468
+ fetch(remote: string, source: string, target: string, timeoutMs?: number | undefined | null, signal?: unknown | undefined | null): Promise<void>
469
+ }
470
+
471
+ /** In-process Jujutsu workspace handle. */
472
+ export declare class VcsJjWorkspace {
473
+ /** Workspace root. */
474
+ root(): string
475
+ /** Shared store directory. */
476
+ storeDir(): string
477
+ /** Working-copy label. */
478
+ workingCopyLabel(signal?: unknown | undefined | null): Promise<string | undefined | null>
479
+ /** Status counts. */
480
+ statusSummary(signal?: unknown | undefined | null): Promise<VcsStatusSummary>
481
+ /** Render working-copy patch. */
482
+ diffText(files: Array<string>, snapshot: boolean, signal?: unknown | undefined | null): Promise<string>
483
+ /** List changed paths. */
484
+ changedFiles(files: Array<string>, snapshot: boolean, signal?: unknown | undefined | null): Promise<Array<string>>
485
+ }
486
+
487
+ /** Backend-agnostic repository handle for portable VCS reads. */
488
+ export declare class VcsRepo {
489
+ /** Backend kind (`"git"` or `"jj"`). */
490
+ kind(): string
491
+ /** Checkout or workspace root. */
492
+ root(): string
493
+ /** Primary checkout or default workspace root. */
494
+ primaryRoot(): string
495
+ /** Worktree-relative prefix of a directory. */
496
+ prefixOf(dir: string): string | null
497
+ /** Filesystem target to watch for repository-head changes. */
498
+ watchTarget(): string
499
+ /** Whether this backend implements a portable feature. */
500
+ supports(feature: string): boolean
501
+ /** Git-specific handle when this repository is backed by Git. */
502
+ asGit(): VcsGitRepo | null
503
+ /** Jujutsu-specific handle when this repository is backed by Jujutsu. */
504
+ asJj(): VcsJjWorkspace | null
505
+ /** Human label for the working copy. */
506
+ label(signal?: unknown | undefined | null): Promise<string | undefined | null>
507
+ /** Working-copy commit id. */
508
+ headId(signal?: unknown | undefined | null): Promise<string | undefined | null>
509
+ /** Status counts. */
510
+ statusSummary(signal?: unknown | undefined | null): Promise<VcsStatusSummary>
511
+ /** Porcelain status. */
512
+ statusPorcelain(options: VcsStatusOptions, signal?: unknown | undefined | null): Promise<string>
513
+ /** Render a patch. */
514
+ diffText(options: VcsDiffOptions, signal?: unknown | undefined | null): Promise<string>
515
+ /** Changed paths. */
516
+ changedFiles(options: VcsDiffOptions, signal?: unknown | undefined | null): Promise<Array<string>>
517
+ /** Per-file line counts. */
518
+ numstat(options: VcsDiffOptions, signal?: unknown | undefined | null): Promise<Array<VcsNumstatEntry>>
519
+ /** Every working-copy change since the last commit. */
520
+ uncommittedDiff(files: Array<string>, signal?: unknown | undefined | null): Promise<string>
521
+ /** Recent subjects. */
522
+ logSubjects(count: number, signal?: unknown | undefined | null): Promise<Array<string>>
523
+ /** Recent one-line commits. */
524
+ logOnelines(count: number, signal?: unknown | undefined | null): Promise<Array<string>>
525
+ /** Commit details. */
526
+ commitDetails(rev: string, signal?: unknown | undefined | null): Promise<VcsCommitDetails>
527
+ /** List tracked or untracked paths. */
528
+ lsFiles(others: boolean, excludeStandard: boolean, signal?: unknown | undefined | null): Promise<Array<string>>
529
+ }
530
+
297
531
  /**
298
532
  * Install the bounded Tokio runtime napi-rs adopts for async exports and the
299
533
  * bounded Rayon global pool used by native parallel iterators.
@@ -339,8 +573,7 @@ export declare function __ompInstallTokioRuntime(): void
339
573
  * `packages/natives/native/index.js` (which derives the name from
340
574
  * `package.json#version`).
341
575
  */
342
- export declare function __piNativesV1_1_4(): void
343
-
576
+ export declare function __piNativesV1_1_6(): void
344
577
 
345
578
  /**
346
579
  * Apply ast-grep rewrite rules to matching files; honors `dryRun` and returns
@@ -856,6 +1089,44 @@ export interface DiffRun {
856
1089
  removed: boolean
857
1090
  }
858
1091
 
1092
+ /** One side of a streamed line diff. */
1093
+ export declare enum DiffSide {
1094
+ /** Original/base text. */
1095
+ Old = 'Old',
1096
+ /** Updated/target text. */
1097
+ New = 'New'
1098
+ }
1099
+
1100
+ /** Observable ingestion state for [`DiffStream`]. */
1101
+ export interface DiffStreamProgress {
1102
+ /** Complete old-side lines available for rendering. */
1103
+ oldLines: number
1104
+ /** Complete new-side lines available for rendering. */
1105
+ newLines: number
1106
+ /** Leading complete lines proven equal on both sides. */
1107
+ stableCommonLines: number
1108
+ /** Whether old-side ingestion has finished. */
1109
+ oldDone: boolean
1110
+ /** Whether new-side ingestion has finished. */
1111
+ newDone: boolean
1112
+ /** Whether either side contains a NUL byte/code unit. */
1113
+ binary: boolean
1114
+ /** Whether either native file exceeded its caller-provided size limit. */
1115
+ tooLarge: boolean
1116
+ }
1117
+
1118
+ /** Exact line-diff output produced when a [`DiffStream`] finishes. */
1119
+ export interface DiffStreamResult {
1120
+ /** Line-token Myers runs used to align the complete files. */
1121
+ runs: Array<DiffRun>
1122
+ /** Unified hunks for the requested context. */
1123
+ hunks: Array<PatchHunk>
1124
+ /** Whether the old text ends in a newline. */
1125
+ oldEndsNewline: boolean
1126
+ /** Whether the new text ends in a newline. */
1127
+ newEndsNewline: boolean
1128
+ }
1129
+
859
1130
  /**
860
1131
  * Word diff with jsdiff `diffWords(oldText, newText)` semantics (default
861
1132
  * options).
@@ -935,6 +1206,22 @@ export declare enum Encoding {
935
1206
  Glm5 = 'Glm5'
936
1207
  }
937
1208
 
1209
+ /**
1210
+ * Replace the current process image via `execvp(3)`.
1211
+ *
1212
+ * On success this never returns: the kernel tears down every other thread and
1213
+ * the new program takes over this PID, controlling terminal, and inherited
1214
+ * (non-`CLOEXEC`) file descriptors. Callers must flush logs and restore the
1215
+ * terminal first — no JS or native cleanup runs after a successful call.
1216
+ *
1217
+ * # Errors
1218
+ * Returns an error, leaving the process untouched, when `argv` is empty, an
1219
+ * argument contains an interior NUL byte, or the exec itself fails (e.g.
1220
+ * executable not found). Windows has no exec-replace semantics, so this
1221
+ * always errors there; callers fall back to spawn-and-wait.
1222
+ */
1223
+ export declare function execReplace(argv: Array<string>): void
1224
+
938
1225
  /**
939
1226
  * Execute a brush shell command.
940
1227
  *
@@ -1830,6 +2117,18 @@ export interface PtyStartOptions {
1830
2117
  shell?: string
1831
2118
  }
1832
2119
 
2120
+ /**
2121
+ * Rasterize SVG/SVGZ bytes into a bounded PNG without resolving local files.
2122
+ *
2123
+ * Conversion runs on the native blocking pool so parsing and rendering do not
2124
+ * stall the JavaScript event loop.
2125
+ *
2126
+ * # Errors
2127
+ * Returns an error for invalid SVG data, zero/oversized limits, allocation
2128
+ * failure, or PNG encoding failure.
2129
+ */
2130
+ export declare function rasterizeSvg(input: Uint8Array, maxWidthPx: number, maxHeightPx: number): Promise<Uint8Array>
2131
+
1833
2132
  /**
1834
2133
  * Read an image from the system clipboard.
1835
2134
  *
@@ -2127,6 +2426,177 @@ export declare function supportsLanguage(lang: string): boolean
2127
2426
  */
2128
2427
  export declare function truncateToWidth(text: string, maxWidth: number, ellipsisKind: Ellipsis | undefined | null, pad: boolean | undefined | null, tabWidth: number): string
2129
2428
 
2429
+ /** Patch application options. */
2430
+ export interface VcsApplyOptions {
2431
+ cached?: boolean
2432
+ indexPath?: string
2433
+ reverse?: boolean
2434
+ threeWay?: boolean
2435
+ }
2436
+
2437
+ /** Clean options. */
2438
+ export interface VcsCleanOptions {
2439
+ ignoredOnly?: boolean
2440
+ includeIgnored?: boolean
2441
+ paths?: Array<string>
2442
+ }
2443
+
2444
+ /** Clone options. */
2445
+ export interface VcsCloneOptions {
2446
+ refName?: string
2447
+ sha?: string
2448
+ timeoutMs?: number
2449
+ }
2450
+
2451
+ /** Commit author identity. */
2452
+ export interface VcsCommitAuthor {
2453
+ name: string
2454
+ email: string
2455
+ date?: string
2456
+ }
2457
+
2458
+ /** Commit metadata. */
2459
+ export interface VcsCommitDetails {
2460
+ sha: string
2461
+ parents: Array<string>
2462
+ author: VcsCommitAuthor
2463
+ message: string
2464
+ }
2465
+
2466
+ /** Commit creation options. */
2467
+ export interface VcsCommitOptions {
2468
+ author?: VcsCommitAuthor
2469
+ allowEmpty?: boolean
2470
+ amend?: boolean
2471
+ files?: Array<string>
2472
+ }
2473
+
2474
+ /** Detach copied Git metadata. */
2475
+ export declare function vcsDetachGitDir(worktreeRoot: string, sourceCommonDir: string, signal?: unknown | undefined | null): Promise<string>
2476
+
2477
+ /** Diff generation options. */
2478
+ export interface VcsDiffOptions {
2479
+ cached?: boolean
2480
+ base?: string
2481
+ head?: string
2482
+ files?: Array<string>
2483
+ context?: number
2484
+ binary?: boolean
2485
+ }
2486
+
2487
+ /** Discover the repository owning a directory. */
2488
+ export declare function vcsDiscover(dir: string): VcsRepo | null
2489
+
2490
+ /** Clone a Git repository. */
2491
+ export declare function vcsGitClone(url: string, target: string, options: VcsCloneOptions, signal?: unknown | undefined | null): Promise<void>
2492
+
2493
+ /** Discover the Git checkout containing a directory. */
2494
+ export declare function vcsGitDiscover(dir: string): VcsGitRepo | null
2495
+
2496
+ /** Discover Git metadata without opening the repository. */
2497
+ export declare function vcsGitRepoInfo(dir: string): VcsGitRepoInfo | null
2498
+
2499
+ /** Discovered Git repository paths. */
2500
+ export interface VcsGitRepoInfo {
2501
+ repoRoot: string
2502
+ gitEntryPath: string
2503
+ gitDir: string
2504
+ commonDir: string
2505
+ headPath: string
2506
+ isReftable: boolean
2507
+ }
2508
+
2509
+ /** Resolved HEAD state. */
2510
+ export interface VcsHeadState {
2511
+ kind: string
2512
+ refName?: string
2513
+ branch?: string
2514
+ commit?: string
2515
+ }
2516
+
2517
+ /** Selected hunks or line range for a path. */
2518
+ export interface VcsHunkSelection {
2519
+ path: string
2520
+ kind: string
2521
+ indices?: Array<number>
2522
+ start?: number
2523
+ end?: number
2524
+ }
2525
+
2526
+ /** Invalid hunk selection. */
2527
+ export interface VcsHunkSelectionError {
2528
+ path: string
2529
+ message: string
2530
+ }
2531
+
2532
+ /** Test whether a directory is a pure jj workspace. */
2533
+ export declare function vcsIsPureJj(dir: string): boolean
2534
+
2535
+ /** Discover a Jujutsu workspace. */
2536
+ export declare function vcsJjDiscover(dir: string): VcsJjWorkspace | null
2537
+
2538
+ /** Join patch fragments. */
2539
+ export declare function vcsJoinPatches(parts: Array<string>): string
2540
+
2541
+ /** Linked worktree metadata. */
2542
+ export interface VcsLinkedWorktree {
2543
+ root: string
2544
+ primaryRoot: string
2545
+ }
2546
+
2547
+ /** Per-file line counts. */
2548
+ export interface VcsNumstatEntry {
2549
+ path: string
2550
+ added?: number
2551
+ removed?: number
2552
+ }
2553
+
2554
+ /** Push options. */
2555
+ export interface VcsPushOptions {
2556
+ remote?: string
2557
+ refspec?: string
2558
+ forceWithLease?: boolean
2559
+ }
2560
+
2561
+ /** Restore options. */
2562
+ export interface VcsRestoreOptions {
2563
+ source?: string
2564
+ staged?: boolean
2565
+ worktree?: boolean
2566
+ files?: Array<string>
2567
+ }
2568
+
2569
+ /** Bounded object contents. */
2570
+ export interface VcsShowResult {
2571
+ data: Buffer
2572
+ truncated: boolean
2573
+ }
2574
+
2575
+ /** Status query options. */
2576
+ export interface VcsStatusOptions {
2577
+ untracked?: string
2578
+ pathspecs?: Array<string>
2579
+ nulTerminated?: boolean
2580
+ }
2581
+
2582
+ /** Git status counts. */
2583
+ export interface VcsStatusSummary {
2584
+ staged: number
2585
+ unstaged: number
2586
+ untracked: number
2587
+ }
2588
+
2589
+ /** Validate hunk selections. */
2590
+ export declare function vcsValidateHunkSelections(rawDiff: string, selections: Array<VcsHunkSelection>): Array<VcsHunkSelectionError>
2591
+
2592
+ /** One worktree listing row. */
2593
+ export interface VcsWorktreeEntry {
2594
+ path: string
2595
+ head?: string
2596
+ branch?: string
2597
+ detached: boolean
2598
+ }
2599
+
2130
2600
  /**
2131
2601
  * Score every row of a normalized `f32` matrix against `query` and return
2132
2602
  * the top `limit` rows.
@@ -2159,6 +2629,9 @@ export interface VectorTopK {
2159
2629
  */
2160
2630
  export declare function visibleWidth(text: string, tabWidth: number): number
2161
2631
 
2632
+ /** Warm syntax grammars and scope matchers on the native worker pool. */
2633
+ export declare function warmHighlighter(): Promise<undefined>
2634
+
2162
2635
  /** Profiling results returned to JavaScript. */
2163
2636
  export interface WorkProfile {
2164
2637
  /** Folded stack format for flamegraph tools. */
package/native/index.js CHANGED
@@ -20,6 +20,7 @@ const nativeBindings = loadNative();
20
20
  export const AudioCapture = nativeBindings.AudioCapture;
21
21
  export const AudioPlayback = nativeBindings.AudioPlayback;
22
22
  export const DesktopSession = adaptDesktopSession(nativeBindings.DesktopSession);
23
+ export const DiffStream = nativeBindings.DiffStream;
23
24
  export const FileLock = nativeBindings.FileLock;
24
25
  export const HighlightStream = nativeBindings.HighlightStream;
25
26
  export const LiveWebRtcPeer = nativeBindings.LiveWebRtcPeer;
@@ -29,11 +30,13 @@ export const Process = nativeBindings.Process;
29
30
  export const PtySession = nativeBindings.PtySession;
30
31
  export const Shell = nativeBindings.Shell;
31
32
  export const TtyWriter = nativeBindings.TtyWriter;
33
+ export const VcsGitRepo = nativeBindings.VcsGitRepo;
34
+ export const VcsJjWorkspace = nativeBindings.VcsJjWorkspace;
35
+ export const VcsRepo = nativeBindings.VcsRepo;
32
36
 
33
37
  // functions
34
38
  export const __ompInstallTokioRuntime = nativeBindings.__ompInstallTokioRuntime;
35
- export const __piNativesV1_1_4 = nativeBindings.__piNativesV1_1_4;
36
- export const pdfToMarkdown = nativeBindings.pdfToMarkdown;
39
+ export const __piNativesV1_1_6 = nativeBindings.__piNativesV1_1_6;
37
40
  export const astEdit = nativeBindings.astEdit;
38
41
  export const astGrep = nativeBindings.astGrep;
39
42
  export const astMatch = nativeBindings.astMatch;
@@ -48,6 +51,7 @@ export const diffLines = nativeBindings.diffLines;
48
51
  export const diffWords = nativeBindings.diffWords;
49
52
  export const enclosingBlockBoundaries = nativeBindings.enclosingBlockBoundaries;
50
53
  export const encodeSixel = nativeBindings.encodeSixel;
54
+ export const execReplace = nativeBindings.execReplace;
51
55
  export const executeShell = nativeBindings.executeShell;
52
56
  export const extractSegments = nativeBindings.extractSegments;
53
57
  export const fuzzyFind = nativeBindings.fuzzyFind;
@@ -79,6 +83,8 @@ export const mmrRerankIndices = nativeBindings.mmrRerankIndices;
79
83
  export const nodeChainAt = nativeBindings.nodeChainAt;
80
84
  export const parseKey = nativeBindings.parseKey;
81
85
  export const parseKittySequence = nativeBindings.parseKittySequence;
86
+ export const pdfToMarkdown = nativeBindings.pdfToMarkdown;
87
+ export const rasterizeSvg = nativeBindings.rasterizeSvg;
82
88
  export const readImageFromClipboard = nativeBindings.readImageFromClipboard;
83
89
  export const renderSnapcompactPng = nativeBindings.renderSnapcompactPng;
84
90
  export const search = nativeBindings.search;
@@ -89,8 +95,18 @@ export const structuredPatchHunks = nativeBindings.structuredPatchHunks;
89
95
  export const summarizeCode = nativeBindings.summarizeCode;
90
96
  export const supportsLanguage = nativeBindings.supportsLanguage;
91
97
  export const truncateToWidth = nativeBindings.truncateToWidth;
98
+ export const vcsDetachGitDir = nativeBindings.vcsDetachGitDir;
99
+ export const vcsDiscover = nativeBindings.vcsDiscover;
100
+ export const vcsGitClone = nativeBindings.vcsGitClone;
101
+ export const vcsGitDiscover = nativeBindings.vcsGitDiscover;
102
+ export const vcsGitRepoInfo = nativeBindings.vcsGitRepoInfo;
103
+ export const vcsIsPureJj = nativeBindings.vcsIsPureJj;
104
+ export const vcsJjDiscover = nativeBindings.vcsJjDiscover;
105
+ export const vcsJoinPatches = nativeBindings.vcsJoinPatches;
106
+ export const vcsValidateHunkSelections = nativeBindings.vcsValidateHunkSelections;
92
107
  export const vectorIndexTopK = nativeBindings.vectorIndexTopK;
93
108
  export const visibleWidth = nativeBindings.visibleWidth;
109
+ export const warmHighlighter = nativeBindings.warmHighlighter;
94
110
  export const wrapTextWithAnsi = nativeBindings.wrapTextWithAnsi;
95
111
 
96
112
  // string/numeric enums (napi-rs string_enum produces TS-only const enum)
@@ -102,6 +118,10 @@ export const AstMatchStrictness = {
102
118
  Signature: "signature",
103
119
  Template: "template",
104
120
  };
121
+ export const DiffSide = {
122
+ Old: "Old",
123
+ New: "New",
124
+ };
105
125
  export const Ellipsis = {
106
126
  Unicode: 0,
107
127
  Ascii: 1,
@@ -724,12 +724,12 @@ export function validateLoadedBindings(ctx, bindings, candidate) {
724
724
  * Install the addon's bounded Tokio runtime now that `dlopen` has returned and
725
725
  * the dynamic-loader lock is released. The Rust `#[module_init]` deliberately
726
726
  * does NOT build the runtime — spawning worker threads under the loader lock
727
- * deadlocks on some hosts — so it exposes `__zetaInstallTokioRuntime` for the
727
+ * deadlocks on some hosts — so it exposes `__ompInstallTokioRuntime` for the
728
728
  * loader to call once, before any async native runs. Best-effort: older addons
729
729
  * predating this export simply fall back to napi-rs's default runtime.
730
730
  */
731
731
  function installNativeTokioRuntime(bindings) {
732
- const install = bindings.__zetaInstallTokioRuntime;
732
+ const install = bindings.__ompInstallTokioRuntime;
733
733
  if (typeof install !== "function") return;
734
734
  try {
735
735
  install();
@@ -0,0 +1,94 @@
1
+ import type {
2
+ VcsCloneOptions,
3
+ VcsGitRepo,
4
+ VcsGitRepoInfo,
5
+ VcsHunkSelection,
6
+ VcsHunkSelectionError,
7
+ VcsJjWorkspace,
8
+ VcsRepo,
9
+ } from "./index.js";
10
+ /** Portable capabilities that differ between Git and Jujutsu. */
11
+ export type VcsFeature = "stagedDiff" | "revDiff";
12
+
13
+ /**
14
+ * A native VCS failure: a real `Error` constructed by the Rust layer on the
15
+ * JS thread, carrying a machine-readable `code` and the CLI result fields.
16
+ * Non-CLI failures synthesize `exitCode: 1` and mirror `message` into
17
+ * `stderr`. Identify with {@link isVcsError} — `instanceof` cannot work for
18
+ * foreign-constructed errors.
19
+ */
20
+ export interface VcsError extends Error {
21
+ name: "VcsError";
22
+ code:
23
+ | "NotARepository"
24
+ | "RefNotFound"
25
+ | "ObjectNotFound"
26
+ | "EmptyCherryPick"
27
+ | "Conflict"
28
+ | "PatchFailed"
29
+ | "Cli"
30
+ | "CliTimeout"
31
+ | "Io"
32
+ | "Backend"
33
+ | "Canceled"
34
+ | "Unsupported";
35
+ exitCode: number;
36
+ stdout: string;
37
+ stderr: string;
38
+ }
39
+
40
+ /** True when `error` is a native VCS failure. */
41
+ export declare function isVcsError(error: unknown): error is VcsError;
42
+
43
+ /** True when a cherry-pick failed because the commit is already applied. */
44
+ export declare function isEmptyCherryPick(error: unknown): error is VcsError & { code: "EmptyCherryPick" };
45
+
46
+ /** Discover the git repository containing `dir`; `null` outside any checkout. */
47
+ export declare function git(dir: string): VcsGitRepo | null;
48
+ /** Discover the repository owning `dir`; `null` outside any repository. */
49
+ export declare function repo(dir: string): VcsRepo | null;
50
+
51
+ /** Like {@link repo}, asserting any requested backend capabilities. */
52
+ export declare function require(dir: string, ...features: VcsFeature[]): VcsRepo;
53
+
54
+ /** Like {@link git}, but throws a `NotARepository` {@link VcsError}. */
55
+ export declare function requireGit(dir: string): VcsGitRepo;
56
+
57
+ /** Repository metadata only (cheap fs walk) — for synchronous render paths. */
58
+ export declare function gitInfo(dir: string): VcsGitRepoInfo | null;
59
+
60
+ /** Discover the Jujutsu workspace containing `dir`; `null` when absent. */
61
+ export declare function jj(dir: string): VcsJjWorkspace | null;
62
+
63
+ /** Whether jj is the nearest VCS ancestor, making git automation unsafe. */
64
+ export declare function isPureJj(dir: string): boolean;
65
+
66
+ /** Clone a repository (git CLI under the hood for credential parity). */
67
+ export declare function clone(
68
+ url: string,
69
+ target: string,
70
+ options?: VcsCloneOptions,
71
+ signal?: AbortSignal,
72
+ ): Promise<void>;
73
+
74
+ /** Sever a copied working tree from shared git metadata. */
75
+ export declare function detachGitDir(
76
+ worktreeRoot: string,
77
+ sourceCommonDir: string,
78
+ signal?: AbortSignal,
79
+ ): Promise<"no-git" | "independent" | "detached">;
80
+
81
+ /** Join patch fragments, preserving each part's trailing newline. */
82
+ export declare function joinPatches(parts: string[]): string;
83
+
84
+ /** Validate hunk selections against a raw diff. */
85
+ export declare function validateHunkSelections(
86
+ rawDiff: string,
87
+ selections: VcsHunkSelection[],
88
+ ): VcsHunkSelectionError[];
89
+
90
+ /** Stat-poll interval for {@link watch}. */
91
+ export declare const HEAD_WATCH_INTERVAL_MS: number;
92
+
93
+ /** Watch a repository for head changes; returns a disposer. */
94
+ export declare function watch(repo: VcsRepo, onChange: () => void, intervalMs?: number): () => void;
package/native/vcs.js ADDED
@@ -0,0 +1,119 @@
1
+ import * as fs from "node:fs";
2
+ import { loadNative } from "./loader-state.js";
3
+
4
+ let native;
5
+ function api() {
6
+ native ??= loadNative();
7
+ return native;
8
+ }
9
+ function vcsError(code, message) {
10
+ const error = new Error(message);
11
+ error.name = "VcsError";
12
+ error.code = code;
13
+ error.exitCode = 1;
14
+ error.stdout = "";
15
+ error.stderr = message;
16
+ return error;
17
+ }
18
+
19
+ /**
20
+ * True when `error` is a native VCS failure. The native layer constructs these
21
+ * on the JS thread as real `Error` objects with `name: "VcsError"`, a
22
+ * machine-readable `code`, and `exitCode`/`stdout`/`stderr` properties — an
23
+ * `instanceof` check is impossible for foreign-constructed errors, so identity
24
+ * rides on `name`.
25
+ */
26
+ export function isVcsError(error) {
27
+ return error instanceof Error && error.name === "VcsError";
28
+ }
29
+
30
+ /** True when a cherry-pick failed because the commit is already applied. */
31
+ export function isEmptyCherryPick(error) {
32
+ return isVcsError(error) && error.code === "EmptyCherryPick";
33
+ }
34
+
35
+ /** Discover the git repository containing `dir`; `null` outside any checkout. */
36
+ export function git(dir) {
37
+ return api().vcsGitDiscover(dir);
38
+ }
39
+ /** Discover the repository owning `dir`; `null` outside any repository. */
40
+ export function repo(dir) {
41
+ return api().vcsDiscover(dir);
42
+ }
43
+
44
+ /** Like {@link repo}, asserting any requested backend capabilities. */
45
+ export function require(dir, ...features) {
46
+ const discovered = repo(dir);
47
+ if (!discovered) throw vcsError("NotARepository", `not a repository: ${dir}`);
48
+ for (const feature of features) {
49
+ if (!discovered.supports(feature)) {
50
+ throw vcsError(
51
+ "Unsupported",
52
+ `\`${feature}\` is not supported on a ${discovered.kind()} repository`,
53
+ );
54
+ }
55
+ }
56
+ return discovered;
57
+ }
58
+
59
+ /** Like {@link git}, but throws a `NotARepository` VcsError. */
60
+ export function requireGit(dir) {
61
+ const repo = git(dir);
62
+ if (!repo) {
63
+ throw vcsError("NotARepository", `not a repository: ${dir}`);
64
+ }
65
+ return repo;
66
+ }
67
+
68
+ /** Repository metadata only (cheap fs walk) — for synchronous render paths. */
69
+ export function gitInfo(dir) {
70
+ return api().vcsGitRepoInfo(dir);
71
+ }
72
+
73
+ /** Discover the Jujutsu workspace containing `dir`; `null` when absent. */
74
+ export function jj(dir) {
75
+ return api().vcsJjDiscover(dir);
76
+ }
77
+
78
+ /** Whether jj is the nearest VCS ancestor, making git automation unsafe. */
79
+ export function isPureJj(dir) {
80
+ return api().vcsIsPureJj(dir);
81
+ }
82
+
83
+ /** Clone a repository (git CLI under the hood for credential parity). */
84
+ export function clone(url, target, options = {}, signal) {
85
+ return api().vcsGitClone(url, target, options, signal);
86
+ }
87
+
88
+ /** Sever a copied working tree from shared git metadata. */
89
+ export function detachGitDir(worktreeRoot, sourceCommonDir, signal) {
90
+ return api().vcsDetachGitDir(worktreeRoot, sourceCommonDir, signal);
91
+ }
92
+
93
+ /** Join patch fragments, preserving each part's trailing newline. */
94
+ export function joinPatches(parts) {
95
+ return api().vcsJoinPatches(parts);
96
+ }
97
+
98
+ /** Validate hunk selections against a raw diff. */
99
+ export function validateHunkSelections(rawDiff, selections) {
100
+ return api().vcsValidateHunkSelections(rawDiff, selections);
101
+ }
102
+
103
+ /** Stat-poll interval for {@link watch}. */
104
+ export const HEAD_WATCH_INTERVAL_MS = 1000;
105
+
106
+ /**
107
+ * Watch a repository for head changes; returns a disposer.
108
+ *
109
+ * Stat-polls via `fs.watchFile` instead of `fs.watch`: backends may atomically
110
+ * replace the watched entry, permanently silencing inotify-backed watchers.
111
+ */
112
+ export function watch(repo, onChange, intervalMs = HEAD_WATCH_INTERVAL_MS) {
113
+ const target = repo.watchTarget();
114
+ const listener = (curr, prev) => {
115
+ if (curr.mtimeMs !== prev.mtimeMs || curr.ino !== prev.ino || curr.size !== prev.size) onChange();
116
+ };
117
+ fs.watchFile(target, { interval: intervalMs }, listener).unref();
118
+ return () => fs.unwatchFile(target, listener);
119
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@linxiraos/pi-natives",
3
- "version": "1.1.4",
3
+ "version": "1.1.6",
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://linxira-os.github.io/zeta/",
@@ -72,6 +72,8 @@
72
72
  "native/desktop-adapter.d.ts",
73
73
  "native/loader-state.js",
74
74
  "native/loader-state.d.ts",
75
+ "native/vcs.js",
76
+ "native/vcs.d.ts",
75
77
  "native/embedded-addon.js",
76
78
  "README.md",
77
79
  "LICENSE",
@@ -89,13 +91,17 @@
89
91
  "./clipboard": {
90
92
  "types": "./native/clipboard.d.ts",
91
93
  "import": "./native/clipboard.js"
94
+ },
95
+ "./vcs": {
96
+ "types": "./native/vcs.d.ts",
97
+ "import": "./native/vcs.js"
92
98
  }
93
99
  },
94
100
  "optionalDependencies": {
95
- "@linxiraos/pi-natives-linux-x64": "1.1.4",
96
- "@linxiraos/pi-natives-linux-arm64": "1.1.4",
97
- "@linxiraos/pi-natives-darwin-x64": "1.1.4",
98
- "@linxiraos/pi-natives-darwin-arm64": "1.1.4",
99
- "@linxiraos/pi-natives-win32-x64": "1.1.4"
101
+ "@linxiraos/pi-natives-linux-x64": "1.1.6",
102
+ "@linxiraos/pi-natives-linux-arm64": "1.1.6",
103
+ "@linxiraos/pi-natives-darwin-x64": "1.1.6",
104
+ "@linxiraos/pi-natives-darwin-arm64": "1.1.6",
105
+ "@linxiraos/pi-natives-win32-x64": "1.1.6"
100
106
  }
101
107
  }