@oh-my-pi/pi-natives 18.11.0 → 18.11.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
@@ -2058,7 +2058,10 @@ export interface GrepOptions {
2058
2058
  pattern: string
2059
2059
  /** Directory or file to search: a host path or an absolute `scheme://` URL. */
2060
2060
  path: string
2061
- /** Glob filter for filenames (e.g., "*.ts"). */
2061
+ /**
2062
+ * Glob filter for file paths (e.g., "*.ts"); a matched directory selects
2063
+ * every file under it.
2064
+ */
2062
2065
  glob?: string
2063
2066
  /**
2064
2067
  * Match simple glob patterns at any depth (default: true; `*.ts` ->
@@ -2459,6 +2462,13 @@ export interface ListWorkspaceOptions {
2459
2462
  * to find them. Default: false.
2460
2463
  */
2461
2464
  collectAgentsMd?: boolean
2465
+ /**
2466
+ * Report unreadable directories instead of silently skipping them: an
2467
+ * unreadable root fails the scan, and unreadable subdirectories are
2468
+ * returned in `unreadableDirectories` while the walk continues. Default:
2469
+ * false (startup discovery stays best-effort).
2470
+ */
2471
+ reportDirectoryErrors?: boolean
2462
2472
  /** Timeout in milliseconds for the operation. */
2463
2473
  timeoutMs?: number
2464
2474
  /** Abort signal for cancelling the operation. */
@@ -2476,6 +2486,11 @@ export interface ListWorkspaceResult {
2476
2486
  agentsMdFiles: Array<string>
2477
2487
  /** True when any output cap was hit. */
2478
2488
  truncated: boolean
2489
+ /**
2490
+ * Subdirectories whose contents could not be listed. Always empty unless
2491
+ * `reportDirectoryErrors` is set.
2492
+ */
2493
+ unreadableDirectories: Array<WorkspaceDirectoryError>
2479
2494
  }
2480
2495
 
2481
2496
  /**
@@ -3908,6 +3923,14 @@ export interface WorkProfile {
3908
3923
  sampleCount: number
3909
3924
  }
3910
3925
 
3926
+ /** A subdirectory the scan could not list. */
3927
+ export interface WorkspaceDirectoryError {
3928
+ /** Forward-slash path relative to the scan root. */
3929
+ path: string
3930
+ /** Platform error, e.g. `Permission denied (os error 13)`. */
3931
+ message: string
3932
+ }
3933
+
3911
3934
  /**
3912
3935
  * Wrap text to a visible width, preserving ANSI escape codes across line
3913
3936
  * breaks.
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.1",
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.1",
117
+ "@oh-my-pi/pi-natives-linux-arm64": "18.11.1",
118
+ "@oh-my-pi/pi-natives-darwin-x64": "18.11.1",
119
+ "@oh-my-pi/pi-natives-darwin-arm64": "18.11.1",
120
+ "@oh-my-pi/pi-natives-win32-x64": "18.11.1",
121
+ "@oh-my-pi/pi-natives-win32-arm64": "18.11.1"
122
122
  }
123
123
  }