linersh 1.1.2 → 1.1.3
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/bin/liner.js +47 -7
- package/package.json +6 -6
package/bin/liner.js
CHANGED
|
@@ -11,14 +11,22 @@
|
|
|
11
11
|
import { fileURLToPath } from "node:url";
|
|
12
12
|
import { createRequire } from "node:module";
|
|
13
13
|
import { spawn, spawnSync } from "node:child_process";
|
|
14
|
-
import { existsSync, readFileSync, rmSync } from "node:fs";
|
|
14
|
+
import { existsSync, readFileSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
15
15
|
import { homedir } from "node:os";
|
|
16
|
-
import { dirname, join } from "node:path";
|
|
16
|
+
import { basename, dirname, join } from "node:path";
|
|
17
17
|
|
|
18
18
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
19
19
|
const packageRoot = join(here, "..");
|
|
20
20
|
const argv = process.argv.slice(2);
|
|
21
21
|
|
|
22
|
+
// How many Liner launchers are already running above this one. The PATH
|
|
23
|
+
// fallback below must never start another launcher, and this depth limit
|
|
24
|
+
// stops a loop even where symlink checks can't see one (Windows .cmd shims).
|
|
25
|
+
const LAUNCHER_DEPTH_ENV = "LINER_LAUNCHER_DEPTH";
|
|
26
|
+
const launcherDepth = Number.parseInt(process.env[LAUNCHER_DEPTH_ENV] ?? "0", 10) || 0;
|
|
27
|
+
const MAX_PATH_FALLBACK_DEPTH = 1;
|
|
28
|
+
process.env[LAUNCHER_DEPTH_ENV] = String(launcherDepth + 1);
|
|
29
|
+
|
|
22
30
|
const COMMAND_GROUPS = [
|
|
23
31
|
{
|
|
24
32
|
title: "Common workflow commands:",
|
|
@@ -373,17 +381,49 @@ function findRepoVenvBinary() {
|
|
|
373
381
|
return null;
|
|
374
382
|
}
|
|
375
383
|
|
|
384
|
+
// A separately installed Liner CLI on PATH, never a Liner launcher: npm puts
|
|
385
|
+
// this script on PATH through a symlink, so running the first hit would start
|
|
386
|
+
// this launcher again, which would do the same, without end.
|
|
376
387
|
function findPathBinary() {
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
388
|
+
if (launcherDepth > MAX_PATH_FALLBACK_DEPTH) return null;
|
|
389
|
+
// `where` lists every match; `which` needs -a, or it stops at the first one,
|
|
390
|
+
// which is usually this launcher.
|
|
391
|
+
const probe = spawnSync(
|
|
392
|
+
process.platform === "win32" ? "where" : "which",
|
|
393
|
+
process.platform === "win32" ? ["liner"] : ["-a", "liner"],
|
|
394
|
+
{ encoding: "utf8" },
|
|
395
|
+
);
|
|
380
396
|
if (probe.status !== 0) return null;
|
|
381
397
|
const hits = probe.stdout
|
|
382
398
|
.split(/\r?\n/)
|
|
383
399
|
.map((s) => s.trim())
|
|
384
400
|
.filter(Boolean);
|
|
385
|
-
|
|
386
|
-
|
|
401
|
+
return hits.find((hit) => !isLinerLauncher(hit)) ?? null;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function isLinerLauncher(candidate) {
|
|
405
|
+
let real;
|
|
406
|
+
try {
|
|
407
|
+
real = realpathSync(candidate);
|
|
408
|
+
} catch {
|
|
409
|
+
return true;
|
|
410
|
+
}
|
|
411
|
+
if (real === realpathSync(fileURLToPath(import.meta.url))) return true;
|
|
412
|
+
// Another linersh install's launcher.
|
|
413
|
+
if (basename(real) === "liner.js" && basename(dirname(real)) === "bin") return true;
|
|
414
|
+
// npm's wrapper scripts (Windows .cmd/.ps1, and extensionless shell
|
|
415
|
+
// wrappers where symlinks aren't used) name the launcher they run, in any
|
|
416
|
+
// install layout. Real CLI binaries are not small text files that do.
|
|
417
|
+
return wrapperRunsLinerLauncher(real);
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
function wrapperRunsLinerLauncher(path) {
|
|
421
|
+
try {
|
|
422
|
+
if (statSync(path).size > 64 * 1024) return false;
|
|
423
|
+
return /linersh[\\/]+bin[\\/]+liner\.js/.test(readFileSync(path, "utf8"));
|
|
424
|
+
} catch {
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
387
427
|
}
|
|
388
428
|
|
|
389
429
|
function exeName() {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "linersh",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.3",
|
|
4
4
|
"description": "Liner — npm shim, Go TUI launcher, and headless methodology runner.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -48,11 +48,11 @@
|
|
|
48
48
|
"yaml": "^2.6.1"
|
|
49
49
|
},
|
|
50
50
|
"optionalDependencies": {
|
|
51
|
-
"linersh-darwin-arm64": "1.1.
|
|
52
|
-
"linersh-darwin-x64": "1.1.
|
|
53
|
-
"linersh-linux-arm64": "1.1.
|
|
54
|
-
"linersh-linux-x64": "1.1.
|
|
55
|
-
"linersh-win32-x64": "1.1.
|
|
51
|
+
"linersh-darwin-arm64": "1.1.3",
|
|
52
|
+
"linersh-darwin-x64": "1.1.3",
|
|
53
|
+
"linersh-linux-arm64": "1.1.3",
|
|
54
|
+
"linersh-linux-x64": "1.1.3",
|
|
55
|
+
"linersh-win32-x64": "1.1.3"
|
|
56
56
|
},
|
|
57
57
|
"devDependencies": {
|
|
58
58
|
"@types/node": "^22.10.0",
|