@oh-my-pi/pi-natives 18.11.0 → 18.11.2

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.
@@ -15,6 +15,8 @@ const REQUIRED_METHODS = [
15
15
  "releaseControl",
16
16
  "controlState",
17
17
  "bringToCurrentSpace",
18
+ "holdDisplayUntilReleased",
19
+ "releaseDisplayAwake",
18
20
  ];
19
21
 
20
22
  /** Require the current desktop ABI; partial legacy emulation cannot preserve input ownership. */
package/native/index.d.ts CHANGED
@@ -43,6 +43,19 @@ export declare class DesktopSession {
43
43
  * behind the worker, so it answers at once even while a request is stuck.
44
44
  */
45
45
  get screenState(): DesktopScreenState
46
+ /**
47
+ * Keeps the display awake from the next activity request until
48
+ * `releaseDisplayAwake()`, however long the session sits idle in between,
49
+ * instead of for the grace period after the last request. An agent calls
50
+ * this when it acts inside a turn.
51
+ */
52
+ holdDisplayUntilReleased(): void
53
+ /**
54
+ * Lets the display sleep now if a turn holds it, without waiting behind
55
+ * queued requests, and returns later activity to the grace period. Activity
56
+ * outside a turn keeps its grace. An agent calls this when its turn ends.
57
+ */
58
+ releaseDisplayAwake(): void
46
59
  listDisplays(): Promise<Array<DesktopDisplay>>
47
60
  listWindows(): Promise<Array<DesktopWindow>>
48
61
  listApplications(options?: ApplicationQuery | undefined | null): Promise<Array<Application>>
@@ -2058,7 +2071,10 @@ export interface GrepOptions {
2058
2071
  pattern: string
2059
2072
  /** Directory or file to search: a host path or an absolute `scheme://` URL. */
2060
2073
  path: string
2061
- /** Glob filter for filenames (e.g., "*.ts"). */
2074
+ /**
2075
+ * Glob filter for file paths (e.g., "*.ts"); a matched directory selects
2076
+ * every file under it.
2077
+ */
2062
2078
  glob?: string
2063
2079
  /**
2064
2080
  * Match simple glob patterns at any depth (default: true; `*.ts` ->
@@ -2459,6 +2475,13 @@ export interface ListWorkspaceOptions {
2459
2475
  * to find them. Default: false.
2460
2476
  */
2461
2477
  collectAgentsMd?: boolean
2478
+ /**
2479
+ * Report unreadable directories instead of silently skipping them: an
2480
+ * unreadable root fails the scan, and unreadable subdirectories are
2481
+ * returned in `unreadableDirectories` while the walk continues. Default:
2482
+ * false (startup discovery stays best-effort).
2483
+ */
2484
+ reportDirectoryErrors?: boolean
2462
2485
  /** Timeout in milliseconds for the operation. */
2463
2486
  timeoutMs?: number
2464
2487
  /** Abort signal for cancelling the operation. */
@@ -2476,6 +2499,11 @@ export interface ListWorkspaceResult {
2476
2499
  agentsMdFiles: Array<string>
2477
2500
  /** True when any output cap was hit. */
2478
2501
  truncated: boolean
2502
+ /**
2503
+ * Subdirectories whose contents could not be listed. Always empty unless
2504
+ * `reportDirectoryErrors` is set.
2505
+ */
2506
+ unreadableDirectories: Array<WorkspaceDirectoryError>
2479
2507
  }
2480
2508
 
2481
2509
  /**
@@ -2709,6 +2737,9 @@ export interface NodeSpan {
2709
2737
  /** Decode notebook JSON into the editable cell-marker text. */
2710
2738
  export declare function notebookToEditableText(json: string, displayPath: string): string
2711
2739
 
2740
+ /** Check syntax through the shared parse cache without constructing a summary. */
2741
+ export declare function parseCodeStatus(options: ParseStatusOptions): ParseStatus
2742
+
2712
2743
  /** Parsed Kitty keyboard protocol sequence result for a Kitty input sequence. */
2713
2744
  export interface ParsedKittyResult {
2714
2745
  /** Primary codepoint associated with the key. */
@@ -2737,6 +2768,23 @@ export declare function parseKey(data: string, kittyProtocolActive: boolean): st
2737
2768
  */
2738
2769
  export declare function parseKittySequence(data: string): ParsedKittyResult | null
2739
2770
 
2771
+ export interface ParseStatus {
2772
+ /** Canonical language name only when parsing succeeded. */
2773
+ language?: string
2774
+ /** True when non-empty source parses without syntax errors. */
2775
+ parsed: boolean
2776
+ }
2777
+
2778
+ /** Options for checking source syntax without generating a summary. */
2779
+ export interface ParseStatusOptions {
2780
+ /** Source code to parse; empty input is not parsed. */
2781
+ code: string
2782
+ /** Language alias; a non-blank value overrides path-based detection. */
2783
+ lang?: string
2784
+ /** File path used to infer language when `lang` is omitted or blank. */
2785
+ path?: string
2786
+ }
2787
+
2740
2788
  /** One hunk of a unified diff, matching jsdiff `structuredPatch` hunks. */
2741
2789
  export interface PatchHunk {
2742
2790
  /** 1-based first line of the hunk in the old text. */
@@ -3850,8 +3898,8 @@ export declare function visibleWidth(text: string, tabWidth: number): number
3850
3898
  * [`enclosing_block_boundaries`], [`block_range_at`] and [`node_chain_at`]
3851
3899
  * are synchronous and parse on the JS thread when their source is not
3852
3900
  * cached; awaiting this first makes that parse a cache hit. Resolves without
3853
- * parsing when the language is unrecognized or the source is too large for
3854
- * the cache to keep.
3901
+ * parsing when the language is unrecognized or the source is over 2 MiB,
3902
+ * where a typical tree would not fit the cache's memory budget.
3855
3903
  */
3856
3904
  export declare function warmBlockParse(options: BlockParseOptions): Promise<undefined>
3857
3905
 
@@ -3908,6 +3956,14 @@ export interface WorkProfile {
3908
3956
  sampleCount: number
3909
3957
  }
3910
3958
 
3959
+ /** A subdirectory the scan could not list. */
3960
+ export interface WorkspaceDirectoryError {
3961
+ /** Forward-slash path relative to the scan root. */
3962
+ path: string
3963
+ /** Platform error, e.g. `Permission denied (os error 13)`. */
3964
+ message: string
3965
+ }
3966
+
3911
3967
  /**
3912
3968
  * Wrap text to a visible width, preserving ANSI escape codes across line
3913
3969
  * breaks.
package/native/index.js CHANGED
@@ -116,6 +116,7 @@ export const matchesLegacySequence = nativeBindings.matchesLegacySequence ?? mis
116
116
  export const mmrRerankIndices = nativeBindings.mmrRerankIndices ?? missingNativeExport("mmrRerankIndices");
117
117
  export const nodeChainAt = nativeBindings.nodeChainAt ?? missingNativeExport("nodeChainAt");
118
118
  export const notebookToEditableText = nativeBindings.notebookToEditableText ?? missingNativeExport("notebookToEditableText");
119
+ export const parseCodeStatus = nativeBindings.parseCodeStatus ?? missingNativeExport("parseCodeStatus");
119
120
  export const parseKey = nativeBindings.parseKey ?? missingNativeExport("parseKey");
120
121
  export const parseKittySequence = nativeBindings.parseKittySequence ?? missingNativeExport("parseKittySequence");
121
122
  export const pdfToMarkdown = nativeBindings.pdfToMarkdown ?? missingNativeExport("pdfToMarkdown");
package/native/vcs.js CHANGED
@@ -97,28 +97,55 @@ export function detachGitDir(worktreeRoot, sourceCommonDir, signal) {
97
97
  return api().vcsDetachGitDir(worktreeRoot, sourceCommonDir, signal);
98
98
  }
99
99
 
100
+ /**
101
+ * Publish `from` at `to` only once fully written: copy to a sibling temp name,
102
+ * then hard-link it into place (Git's own `finalize_object_file` strategy) so
103
+ * readers never see a partial file and an interrupted copy leaves only a
104
+ * `tmp_` file that `git gc` prunes. An existing `to` was itself published
105
+ * whole and holds the same content-addressed bytes, so it is kept.
106
+ */
107
+ async function publishGitObjectFile(from, to) {
108
+ const tmp = path.join(path.dirname(to), `tmp_obj_omp_${crypto.randomUUID()}`);
109
+ try {
110
+ await fs.promises.copyFile(from, tmp, fs.constants.COPYFILE_EXCL);
111
+ try {
112
+ await fs.promises.link(tmp, to);
113
+ } catch (error) {
114
+ if (error?.code === "EEXIST") return;
115
+ // Filesystems without hard links: rename is still atomic, and any
116
+ // file it replaces holds identical content-addressed bytes.
117
+ if (error?.code !== "EPERM" && error?.code !== "ENOTSUP" && error?.code !== "EXDEV") throw error;
118
+ await fs.promises.rename(tmp, to);
119
+ }
120
+ } finally {
121
+ await fs.promises.rm(tmp, { force: true });
122
+ }
123
+ }
124
+
100
125
  /**
101
126
  * Keep objects created in an isolated Git repository reachable after its
102
127
  * worktree is removed, without changing the destination's refs or index.
128
+ * Every file is published atomically; a pack is published before its index.
103
129
  */
104
130
  export async function copyGitObjects(isolationRoot, sourceRoot) {
105
131
  const from = path.join(requireGit(isolationRoot).info().commonDir, "objects");
106
132
  const to = path.join(requireGit(sourceRoot).info().commonDir, "objects");
107
133
  for (const entry of await fs.promises.readdir(from, { withFileTypes: true })) {
108
- if (entry.isDirectory() && /^[0-9a-f]{2}$/.test(entry.name)) {
109
- await fs.promises.cp(path.join(from, entry.name), path.join(to, entry.name), {
110
- recursive: true,
111
- force: false,
112
- });
134
+ if (!entry.isDirectory() || !/^[0-9a-f]{2}$/.test(entry.name)) continue;
135
+ await fs.promises.mkdir(path.join(to, entry.name), { recursive: true });
136
+ for (const name of await fs.promises.readdir(path.join(from, entry.name))) {
137
+ if (!/^[0-9a-f]{38,62}$/.test(name)) continue;
138
+ await publishGitObjectFile(path.join(from, entry.name, name), path.join(to, entry.name, name));
113
139
  }
114
140
  }
115
- const packs = await fs.promises.readdir(path.join(from, "pack"));
141
+ const packs = (await fs.promises.readdir(path.join(from, "pack"))).filter(name => name.startsWith("pack-"));
142
+ await fs.promises.mkdir(path.join(to, "pack"), { recursive: true });
116
143
  // The index must only become visible after the pack it describes.
117
144
  for (const name of packs.filter(name => name.endsWith(".pack"))) {
118
- await fs.promises.cp(path.join(from, "pack", name), path.join(to, "pack", name), { force: false });
145
+ await publishGitObjectFile(path.join(from, "pack", name), path.join(to, "pack", name));
119
146
  }
120
147
  for (const name of packs.filter(name => /\.(?:idx|rev|keep|promisor|mtimes)$/.test(name))) {
121
- await fs.promises.cp(path.join(from, "pack", name), path.join(to, "pack", name), { force: false });
148
+ await publishGitObjectFile(path.join(from, "pack", name), path.join(to, "pack", name));
122
149
  }
123
150
  }
124
151
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oh-my-pi/pi-natives",
3
- "version": "18.11.0",
3
+ "version": "18.11.2",
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",
@@ -113,11 +113,11 @@
113
113
  }
114
114
  },
115
115
  "optionalDependencies": {
116
- "@oh-my-pi/pi-natives-linux-x64": "18.11.0",
117
- "@oh-my-pi/pi-natives-linux-arm64": "18.11.0",
118
- "@oh-my-pi/pi-natives-darwin-x64": "18.11.0",
119
- "@oh-my-pi/pi-natives-darwin-arm64": "18.11.0",
120
- "@oh-my-pi/pi-natives-win32-x64": "18.11.0",
121
- "@oh-my-pi/pi-natives-win32-arm64": "18.11.0"
116
+ "@oh-my-pi/pi-natives-linux-x64": "18.11.2",
117
+ "@oh-my-pi/pi-natives-linux-arm64": "18.11.2",
118
+ "@oh-my-pi/pi-natives-darwin-x64": "18.11.2",
119
+ "@oh-my-pi/pi-natives-darwin-arm64": "18.11.2",
120
+ "@oh-my-pi/pi-natives-win32-x64": "18.11.2",
121
+ "@oh-my-pi/pi-natives-win32-arm64": "18.11.2"
122
122
  }
123
123
  }