litmus-cli 1.4.70 → 1.4.72

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.
Files changed (45) hide show
  1. package/README.md +39 -9
  2. package/dist/commands/connect.d.ts +16 -1
  3. package/dist/commands/connect.d.ts.map +1 -1
  4. package/dist/commands/connect.js +68 -41
  5. package/dist/commands/connect.js.map +1 -1
  6. package/dist/commands/forward.d.ts +4 -16
  7. package/dist/commands/forward.d.ts.map +1 -1
  8. package/dist/commands/forward.js +19 -70
  9. package/dist/commands/forward.js.map +1 -1
  10. package/dist/commands/ssh.d.ts +3 -0
  11. package/dist/commands/ssh.d.ts.map +1 -0
  12. package/dist/commands/ssh.js +50 -0
  13. package/dist/commands/ssh.js.map +1 -0
  14. package/dist/index.js +16 -5
  15. package/dist/index.js.map +1 -1
  16. package/dist/lib/auto-forward.d.ts +29 -0
  17. package/dist/lib/auto-forward.d.ts.map +1 -0
  18. package/dist/lib/auto-forward.js +229 -0
  19. package/dist/lib/auto-forward.js.map +1 -0
  20. package/dist/lib/cursor-session.d.ts +6 -0
  21. package/dist/lib/cursor-session.d.ts.map +1 -1
  22. package/dist/lib/cursor-session.js +21 -1
  23. package/dist/lib/cursor-session.js.map +1 -1
  24. package/dist/lib/environment-checks.d.ts +1 -2
  25. package/dist/lib/environment-checks.d.ts.map +1 -1
  26. package/dist/lib/environment-checks.js +4 -9
  27. package/dist/lib/environment-checks.js.map +1 -1
  28. package/dist/lib/hook-logger.cjs +25 -19
  29. package/dist/lib/install-ssh-forward-hook.d.ts +6 -0
  30. package/dist/lib/install-ssh-forward-hook.d.ts.map +1 -0
  31. package/dist/lib/install-ssh-forward-hook.js +57 -0
  32. package/dist/lib/install-ssh-forward-hook.js.map +1 -0
  33. package/dist/lib/port-forward.d.ts +16 -0
  34. package/dist/lib/port-forward.d.ts.map +1 -0
  35. package/dist/lib/port-forward.js +46 -0
  36. package/dist/lib/port-forward.js.map +1 -0
  37. package/dist/lib/ssh-client.d.ts +6 -1
  38. package/dist/lib/ssh-client.d.ts.map +1 -1
  39. package/dist/lib/ssh-client.js +44 -4
  40. package/dist/lib/ssh-client.js.map +1 -1
  41. package/dist/lib/ssh-forward-hook.d.ts +13 -0
  42. package/dist/lib/ssh-forward-hook.d.ts.map +1 -0
  43. package/dist/lib/ssh-forward-hook.js +93 -0
  44. package/dist/lib/ssh-forward-hook.js.map +1 -0
  45. package/package.json +2 -2
@@ -0,0 +1,93 @@
1
+ import { spawn, spawnSync } from "child_process";
2
+ import path from "path";
3
+ import { realpathSync } from "fs";
4
+ import { fileURLToPath } from "url";
5
+ import { autoForward } from "./auto-forward.js";
6
+ import { tunnelArgs, localPortFree, localPortListening } from "./port-forward.js";
7
+ /** Read process identity only; never command lines, environment, or terminal input. */
8
+ export function processIdentity(pid) {
9
+ if (!Number.isSafeInteger(pid) || pid < 2)
10
+ return;
11
+ if (process.platform === "win32") {
12
+ const result = spawnSync("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command",
13
+ `$p=Get-CimInstance Win32_Process -Filter 'ProcessId = ${pid}'; if ($p) { @{pid=$p.ProcessId;parent=$p.ParentProcessId;started=$p.CreationDate.ToString('o');name=$p.Name} | ConvertTo-Json -Compress }`], { encoding: "utf8", timeout: 3000, windowsHide: true });
14
+ try {
15
+ return JSON.parse(result.stdout);
16
+ }
17
+ catch {
18
+ return;
19
+ }
20
+ }
21
+ const result = spawnSync("ps", ["-p", String(pid), "-o", "ppid=", "-o", "lstart=", "-o", "comm="], { encoding: "utf8", timeout: 1000, env: { ...process.env, LC_ALL: "C" } });
22
+ const match = result.stdout?.trim().match(/^(\d+)\s+((?:\S+\s+){4}\S+)\s+(.+)$/);
23
+ if (match)
24
+ return { pid, parent: Number(match[1]), started: match[2], name: path.basename(match[3]) };
25
+ }
26
+ export function findSshOwner(pid = process.ppid) {
27
+ for (let depth = 0; depth < 4; depth++) {
28
+ const owner = processIdentity(pid);
29
+ if (!owner)
30
+ return;
31
+ if (/^ssh(?:\.exe)?$/i.test(owner.name))
32
+ return owner;
33
+ pid = owner.parent;
34
+ }
35
+ }
36
+ export async function watchSsh(alias, owner) {
37
+ const abort = new AbortController();
38
+ const stop = () => abort.abort();
39
+ process.on("SIGTERM", stop);
40
+ process.on("SIGHUP", stop);
41
+ // The original ssh remains alive while LocalCommand launches us. Compare the
42
+ // start time as well as PID so PID reuse can never adopt another connection.
43
+ const alive = () => {
44
+ const current = processIdentity(owner.pid);
45
+ if (!current || current.started !== owner.started || current.name !== owner.name)
46
+ stop();
47
+ };
48
+ alive();
49
+ // Windows waits in one process instead of starting PowerShell every poll.
50
+ const waiter = process.platform === "win32" && !abort.signal.aborted
51
+ ? spawn("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command",
52
+ `$p=Get-CimInstance Win32_Process -Filter 'ProcessId = ${owner.pid}'; if ($p -and $p.CreationDate.ToString('o') -eq '${owner.started.replace(/'/g, "''")}') { Wait-Process -Id ${owner.pid} -ErrorAction SilentlyContinue }`], { stdio: "ignore", windowsHide: true }) : undefined;
53
+ waiter?.once("exit", stop);
54
+ waiter?.once("error", stop);
55
+ const timer = waiter ? undefined : setInterval(alive, 2000);
56
+ try {
57
+ await autoForward(alias, { args: tunnelArgs, free: localPortFree, listening: localPortListening }, { log: (line) => console.error(`\r\n${line}`) }, abort.signal, { handleSignals: false, startupMessage: " App ports will forward automatically to localhost while this SSH session is open." });
58
+ }
59
+ finally {
60
+ clearInterval(timer);
61
+ waiter?.kill();
62
+ process.off("SIGTERM", stop);
63
+ process.off("SIGHUP", stop);
64
+ }
65
+ }
66
+ export async function launchHook(args) {
67
+ const [mode, alias, encodedOwner] = args;
68
+ if (!/^litmus-[a-zA-Z0-9-]+$/.test(alias ?? ""))
69
+ return;
70
+ if (mode === "watch") {
71
+ const owner = JSON.parse(encodedOwner);
72
+ if (!Number.isSafeInteger(owner.pid) || owner.pid < 2 || typeof owner.started !== "string")
73
+ return;
74
+ await watchSsh(alias, owner);
75
+ }
76
+ else if (mode === "launch" && process.stdout.isTTY && process.stderr.isTTY) {
77
+ // Editor transports have piped output. Gate on terminal output and
78
+ // never read input belonging to the SSH shell.
79
+ const owner = findSshOwner();
80
+ if (!owner)
81
+ throw new Error("Could not identify the SSH connection");
82
+ const child = spawn(process.execPath, [fileURLToPath(import.meta.url), "watch", alias, JSON.stringify(owner)], { detached: true, stdio: ["ignore", "ignore", "inherit"], windowsHide: true });
83
+ await new Promise((resolve, reject) => { child.once("spawn", resolve); child.once("error", reject); });
84
+ child.unref();
85
+ }
86
+ }
87
+ if (process.argv[1] && realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)) {
88
+ launchHook(process.argv.slice(2)).catch(() => {
89
+ console.error("\r\n Automatic forwarding unavailable. Re-run the Litmus connection setup to repair it.");
90
+ // A helper failure must never prevent opening the SSH shell.
91
+ });
92
+ }
93
+ //# sourceMappingURL=ssh-forward-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ssh-forward-hook.js","sourceRoot":"","sources":["../../src/lib/ssh-forward-hook.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litmus-cli",
3
- "version": "1.4.70",
3
+ "version": "1.4.72",
4
4
  "description": "CLI tool for Litmus engineering assessments",
5
5
  "license": "MIT",
6
6
  "author": "elenazhao",
@@ -48,6 +48,6 @@
48
48
  "vitest": "^4.1.4"
49
49
  },
50
50
  "engines": {
51
- "node": ">=18.0.0"
51
+ "node": ">=20.19.0"
52
52
  }
53
53
  }