pi-readseek 0.3.21 → 0.3.22
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/package.json +2 -2
- package/src/readseek-client.ts +65 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-readseek",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.22",
|
|
4
4
|
"description": "Pi extension for readseek-backed hash-anchored read/edit/grep, structural code maps, structural search, and file exploration",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"node": ">=20.0.0"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@jarkkojs/readseek": "^0.3.
|
|
42
|
+
"@jarkkojs/readseek": "^0.3.20",
|
|
43
43
|
"diff": "^8.0.3",
|
|
44
44
|
"ignore": "^7.0.5",
|
|
45
45
|
"picomatch": "^4.0.4",
|
package/src/readseek-client.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { spawn, type StdioOptions } from "node:child_process";
|
|
2
|
+
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
2
3
|
import { createRequire } from "node:module";
|
|
4
|
+
import { homedir } from "node:os";
|
|
3
5
|
import path from "node:path";
|
|
4
6
|
|
|
5
7
|
import { DetailLevel } from "./readseek/enums.js";
|
|
@@ -165,6 +167,8 @@ function symbolsFromReadseek(symbols: ReadseekSymbol[]): FileSymbol[] {
|
|
|
165
167
|
}
|
|
166
168
|
|
|
167
169
|
const require = createRequire(import.meta.url);
|
|
170
|
+
const READSEEK_REPO_PACKAGE_NAMES = new Set(["@jarkkojs/readseek", "readseek"]);
|
|
171
|
+
let defaultReadseekDirInit: Promise<string | null> | undefined;
|
|
168
172
|
|
|
169
173
|
function readseekPackageDir(): string {
|
|
170
174
|
return path.dirname(require.resolve("@jarkkojs/readseek/package.json"));
|
|
@@ -199,12 +203,39 @@ export function isReadseekAvailable(): boolean {
|
|
|
199
203
|
}
|
|
200
204
|
}
|
|
201
205
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
206
|
+
function directoryExists(dirPath: string): boolean {
|
|
207
|
+
try {
|
|
208
|
+
return statSync(dirPath).isDirectory();
|
|
209
|
+
} catch {
|
|
210
|
+
return false;
|
|
211
|
+
}
|
|
205
212
|
}
|
|
206
213
|
|
|
207
|
-
|
|
214
|
+
function isOwnReadseekRepository(cwd = process.cwd()): boolean {
|
|
215
|
+
let dir = path.resolve(cwd);
|
|
216
|
+
while (true) {
|
|
217
|
+
const packageJsonPath = path.join(dir, "package.json");
|
|
218
|
+
if (existsSync(packageJsonPath)) {
|
|
219
|
+
try {
|
|
220
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8")) as { name?: unknown };
|
|
221
|
+
if (typeof packageJson.name === "string" && READSEEK_REPO_PACKAGE_NAMES.has(packageJson.name)) return true;
|
|
222
|
+
} catch {
|
|
223
|
+
// Ignore unreadable or invalid package manifests while walking up.
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const parent = path.dirname(dir);
|
|
228
|
+
if (parent === dir) return false;
|
|
229
|
+
dir = parent;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
function defaultReadseekDir(): string | null {
|
|
234
|
+
const home = homedir();
|
|
235
|
+
return home ? path.join(home, ".pi", "readseek") : null;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function spawnReadseekRaw(args: string[], options: RunReadseekOptions = {}): Promise<string> {
|
|
208
239
|
return new Promise<string>((resolve, reject) => {
|
|
209
240
|
let settled = false;
|
|
210
241
|
const fail = (error: Error): void => {
|
|
@@ -265,6 +296,36 @@ async function runReadseekRaw(args: string[], options: RunReadseekOptions = {}):
|
|
|
265
296
|
});
|
|
266
297
|
}
|
|
267
298
|
|
|
299
|
+
async function ensureDefaultReadseekDir(): Promise<string | null> {
|
|
300
|
+
const dir = defaultReadseekDir();
|
|
301
|
+
if (!dir) return null;
|
|
302
|
+
if (directoryExists(dir)) return dir;
|
|
303
|
+
|
|
304
|
+
defaultReadseekDirInit ??= spawnReadseekRaw(["--readseek-dir", dir, "init"])
|
|
305
|
+
.then(() => (directoryExists(dir) ? dir : null))
|
|
306
|
+
.catch(() => null)
|
|
307
|
+
.finally(() => {
|
|
308
|
+
defaultReadseekDirInit = undefined;
|
|
309
|
+
});
|
|
310
|
+
return defaultReadseekDirInit;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async function readseekInvocationArgs(args: string[]): Promise<string[]> {
|
|
314
|
+
if (isOwnReadseekRepository()) return args;
|
|
315
|
+
|
|
316
|
+
const readseekDir = await ensureDefaultReadseekDir();
|
|
317
|
+
return readseekDir ? ["--readseek-dir", readseekDir, ...args] : args;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
interface RunReadseekOptions {
|
|
321
|
+
signal?: AbortSignal;
|
|
322
|
+
stdin?: string;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
async function runReadseekRaw(args: string[], options: RunReadseekOptions = {}): Promise<string> {
|
|
326
|
+
return spawnReadseekRaw(await readseekInvocationArgs(args), options);
|
|
327
|
+
}
|
|
328
|
+
|
|
268
329
|
async function runReadseek(args: string[], options: RunReadseekOptions = {}): Promise<unknown> {
|
|
269
330
|
const stdout = await runReadseekRaw(args, options);
|
|
270
331
|
return JSON.parse(stdout) as unknown;
|