Commit 609b05e

Anton Golub <antongolub@antongolub.com>
2025-07-11 14:52:38
fix: update @webpod/ps to v0.1.3, add smoke test for `ps` API (#1256)
* fix(deps): update @webpod/ingrid to v1.0.2 * test: add smoke test for `abort()` * chore: minor test code imprs * fix: update @webpod/ps to v0.1.3 * chore: update bundles
1 parent 5e5fb36
build/3rd-party-licenses
@@ -20,7 +20,7 @@ THIRD PARTY LICENSES
   sindresorhus/merge-streams
   MIT
 
-@webpod/ps@0.1.2
+@webpod/ps@0.1.3
   <unknown>
   git://github.com/webpod/ps.git
   MIT
build/vendor-core.cjs
@@ -771,6 +771,7 @@ var import_node_os2 = require("os");
 
 // node_modules/@webpod/ingrid/target/esm/index.mjs
 var EOL = /\r?\n|\r|\n/;
+var EMPTY = "-";
 var parseLine = (line, sep = " ") => {
   if (typeof line !== "string") throw new Error("parseLine: line must be a string");
   const result = {
@@ -813,7 +814,7 @@ var parseLine = (line, sep = " ") => {
   capture();
   return result;
 };
-var parseLines = (input, sep) => input.split(EOL).map((l) => parseLine(l, sep));
+var parseLines = (input, sep) => input.split(EOL).filter(Boolean).map((l) => parseLine(l, sep));
 var countWordsByIndex = ({ words }, index) => words.filter(({ e }) => e < index).length;
 var getBorders = (lines) => lines[0].spaces.reduce((m, i) => {
   const c = countWordsByIndex(lines[0], i);
@@ -864,50 +865,78 @@ var gridToData = (grid) => {
   }
   return data;
 };
-var cut = (line, points, pad = 2) => {
-  const chunks = [];
-  let s = 0;
-  for (const i in [...points, Number.POSITIVE_INFINITY]) {
-    const chunk = line.slice(s, points[i]);
-    chunks.push(chunk);
-    s = points[i] + pad;
+var parseWinGrid = (input, debug = false) => {
+  const lines = input.split(/\r*\n+/).filter(Boolean);
+  const headline = lines.shift();
+  const headers = headline.trim().split(/\s\s+/);
+  const hl = headers.length;
+  const ll = headline.length;
+  if (debug) {
+    console.log("Headers:", headers);
+    console.log("Line lengths:", lines.map((l) => l.length));
   }
-  return chunks;
-};
-var parseWinGrid = (input) => {
-  var _a;
-  const lines = input.split(EOL);
-  const headers = lines[0].trim().split(/\s+/);
+  if (lines.every((l) => ll / l.length < 2)) {
+    const spaces = Array.from({ length: ll }).map(
+      (_, i) => lines.every((l) => l[i] === " ")
+    );
+    const borders = spaces.reduce((m, v, i, a) => {
+      if (v && !a[i - 1]) m.push(i);
+      return m;
+    }, [0]);
+    const data2 = [];
+    debug && console.log("Borders:", borders);
+    for (const line of lines) {
+      const props = [];
+      for (const i in headers) {
+        const k = headers[i];
+        const s = borders[i];
+        const e = borders[+i + 1] || ll;
+        const v = line.slice(s, e).trim();
+        props.push([k, [v || EMPTY]]);
+      }
+      data2.push(Object.fromEntries(props));
+    }
+    return data2;
+  }
+  let w = "";
+  let p;
+  const body = input.slice(headline.length);
+  const vals = [];
   const data = [];
-  let memo = null;
-  for (const line of lines.slice(1)) {
-    if (!line) continue;
-    const { spaces } = parseLine(line);
-    const borders = spaces.filter((s, i) => spaces[i + 1] === s + 1 && spaces[i + 2] !== s + 2);
-    let chunks = (borders.length > 0 ? cut(line, borders, 2) : [line]).map((l) => l.trim());
-    if (chunks.length < headers.length) {
-      memo = chunks;
-      continue;
-    } else if ((_a = chunks[0]) == null ? void 0 : _a.trim()) {
-      memo = null;
-    } else {
-      chunks = [...memo || ["<unknown>"], ...chunks].filter(Boolean);
+  const cap = (v) => {
+    const _v = w.trim() || (vals.length === 0 ? v : w.trim());
+    if (!_v) return;
+    vals.push(_v);
+    if (vals.length === hl) {
+      data.push(Object.fromEntries(headers.map((h, i) => [h, [vals[i]]])));
+      vals.length = 0;
     }
-    const entry = Object.fromEntries(headers.map(
-      (header, i) => [header, parseLine(chunks[i] || "").words.map(({ w }) => w)]
-    ));
-    data.push(entry);
+    w = "";
+  };
+  for (const c of body) {
+    w += c;
+    if (c === " ") {
+      if (p === "\n") {
+        cap(EMPTY);
+      } else if (p === " ") {
+        cap();
+      }
+    } else if (c === "\n") {
+      cap();
+    }
+    p = c;
   }
+  cap();
   return data;
 };
 var parsers = {
   unix: parseUnixGrid,
   win: parseWinGrid
 };
-var parse = (input, { format = "unix" } = {}) => {
+var parse = (input, { format = "unix", debug = false } = {}) => {
   const parser = parsers[format];
   if (!parser) throw new Error(`unsupported format: ${format}`);
-  return parser(input);
+  return parser(input, debug);
 };
 
 // node_modules/zurk/target/esm/spawn.mjs
@@ -1161,10 +1190,13 @@ var exec = (ctx) => invoke(normalizeCtx(ctx));
 
 // node_modules/@webpod/ps/target/esm/index.mjs
 var IS_WIN = import_node_process4.default.platform === "win32";
-var WMIC_INPUT = "wmic process get ProcessId,ParentProcessId,CommandLine" + import_node_os2.EOL;
+var WMIC_INPUT = "wmic process get ProcessId,ParentProcessId,CommandLine";
 var isBin = (f) => {
   if (f === "") return false;
   if (!f.includes("/")) return true;
+  if (!f.includes("\\")) return true;
+  if (f.length > 3 && f[0] === '"')
+    return f[f.length - 1] === '"' ? isBin(f.slice(1, -1)) : false;
   if (!import_node_fs.default.existsSync(f)) return false;
   const stat = import_node_fs.default.lstatSync(f);
   return stat.isFile() || stat.isSymbolicLink();
@@ -1194,8 +1226,8 @@ var _lookup = ({
     cb(null, result);
   };
   const ctx = IS_WIN ? {
-    cmd: "cmd",
-    input: `wmic process get ProcessId,ParentProcessId,CommandLine${import_node_os2.EOL}`,
+    cmd: WMIC_INPUT,
+    args: [],
     callback,
     sync,
     run(cb2) {
@@ -1214,7 +1246,7 @@ var _lookup = ({
   return Object.assign(promise, result);
 };
 var parseProcessList = (output, query = {}) => {
-  const processList = parseGrid(output.trim());
+  const processList = parseGrid(output);
   const pidList = (query.pid === void 0 ? [] : [query.pid].flat(1)).map((v) => v + "");
   const filters = [
     (p) => query.command ? new RegExp(query.command, "i").test(p.command) : true,
@@ -1226,9 +1258,9 @@ var parseProcessList = (output, query = {}) => {
   );
 };
 var removeWmicPrefix = (stdout) => {
-  const s = stdout.indexOf(WMIC_INPUT);
-  const e = stdout.lastIndexOf(import_node_os2.EOL);
-  return (s > 0 ? stdout.slice(s + WMIC_INPUT.length, e) : stdout.slice(0, e)).trim();
+  const s = stdout.indexOf(WMIC_INPUT + import_node_os2.EOL);
+  const e = stdout.includes(">") ? stdout.trimEnd().lastIndexOf(import_node_os2.EOL) : stdout.length;
+  return (s > 0 ? stdout.slice(s + WMIC_INPUT.length, e) : stdout.slice(0, e)).trimStart();
 };
 var pickTree = (list, pid, recursive = false) => {
   const children = list.filter((p) => p.ppid === pid + "");
@@ -1327,7 +1359,8 @@ var formatOutput = (data) => data.reduce((m, d) => {
   var _a, _b, _c, _d;
   const pid = ((_a = d.PID) == null ? void 0 : _a[0]) || ((_b = d.ProcessId) == null ? void 0 : _b[0]);
   const ppid = ((_c = d.PPID) == null ? void 0 : _c[0]) || ((_d = d.ParentProcessId) == null ? void 0 : _d[0]);
-  const cmd = d.CMD || d.CommandLine || d.COMMAND || [];
+  const _cmd = d.CMD || d.CommandLine || d.COMMAND || [];
+  const cmd = _cmd.length === 1 ? _cmd[0].split(/\s+/) : _cmd;
   if (pid && cmd.length > 0) {
     const c = cmd.findIndex((_v, i) => isBin(cmd.slice(0, i).join(" ")));
     const command = cmd.slice(0, c).join(" ");
test/smoke/node.test.mjs
@@ -58,6 +58,38 @@ import 'zx/globals'
       await w
     })
   }
+
+  // ps works fine
+  {
+    const [root] = await ps.lookup({ pid: process.pid })
+    assert.equal(root.pid, process.pid)
+  }
+
+  // abort controller
+  {
+    const ac = new AbortController()
+    const { signal } = ac
+    const p = $({
+      signal,
+      timeout: '5s',
+      nothrow: true,
+      killSignal: 'SIGKILL',
+    })`sleep 10`
+
+    setTimeout(async () => {
+      assert.throws(
+        () => p.abort('SIGINT'),
+        /signal is controlled by another process/
+      )
+      setTimeout(() => {
+        ac.abort('stop')
+      }, 500)
+    }, 500)
+
+    const o = await p
+    assert.equal(o.signal, 'SIGTERM')
+    assert.throws(() => p.kill(), /Too late to kill the process/)
+  }
 })()
 
 console.log('smoke mjs: ok')
test/smoke/win32.test.js
@@ -14,6 +14,7 @@
 
 import assert from 'node:assert'
 import { test, describe } from 'node:test'
+import process from 'node:process'
 import '../../build/globals.js'
 
 const _describe = process.platform === 'win32' ? describe : describe.skip
@@ -65,4 +66,37 @@ _describe('win32', () => {
     assert.match(stdout, /AA-zx-test/)
     assert.match(stdout, /BB-zx-test/)
   })
+
+  test('ps detects self process', async () => {
+    const [root] = await ps.lookup({ pid: process.pid })
+    console.log('process.pid:', process.pid)
+    console.log('process list', JSON.stringify(await ps.lookup(), null, 2))
+
+    assert.equal(root.pid, process.pid)
+  })
+
+  test('abort controller works', async () => {
+    const ac = new AbortController()
+    const { signal } = ac
+    const p = $({
+      signal,
+      timeout: '5s',
+      nothrow: true,
+      killSignal: 'SIGKILL',
+    })`sleep 10`
+
+    setTimeout(async () => {
+      assert.throws(
+        () => p.abort('SIGINT'),
+        /signal is controlled by another process/
+      )
+      setTimeout(() => {
+        ac.abort('stop')
+      }, 500)
+    }, 500)
+
+    const o = await p
+    assert.equal(o.signal, 'SIGTERM')
+    assert.throws(() => p.kill(), /Too late to kill the process/)
+  })
 })
.size-limit.json
@@ -15,7 +15,7 @@
       "README.md",
       "LICENSE"
     ],
-    "limit": "122.10 kB",
+    "limit": "122.85 kB",
     "brotli": false,
     "gzip": false
   },
@@ -29,7 +29,7 @@
       "build/globals.js",
       "build/deno.js"
     ],
-    "limit": "812.70 kB",
+    "limit": "813.35 kB",
     "brotli": false,
     "gzip": false
   },
@@ -43,7 +43,7 @@
   {
     "name": "vendor",
     "path": "build/vendor-*.{cjs,d.ts}",
-    "limit": "765.70 kB",
+    "limit": "766.50 kB",
     "brotli": false,
     "gzip": false
   },
@@ -62,7 +62,7 @@
       "README.md",
       "LICENSE"
     ],
-    "limit": "868.60 kB",
+    "limit": "869.40 kB",
     "brotli": false,
     "gzip": false
   }
package-lock.json
@@ -17,10 +17,10 @@
         "@size-limit/file": "11.2.0",
         "@types/fs-extra": "11.0.4",
         "@types/minimist": "1.2.5",
-        "@types/node": "24.0.8",
+        "@types/node": "24.0.13",
         "@types/which": "3.0.4",
-        "@webpod/ingrid": "1.0.1",
-        "@webpod/ps": "0.1.2",
+        "@webpod/ingrid": "1.1.1",
+        "@webpod/ps": "0.1.3",
         "c8": "10.1.3",
         "chalk": "5.4.1",
         "create-require": "1.1.1",
@@ -28,7 +28,7 @@
         "depseek": "0.4.1",
         "dts-bundle-generator": "9.5.1",
         "envapi": "0.2.3",
-        "esbuild": "0.25.5",
+        "esbuild": "0.25.6",
         "esbuild-node-externals": "1.18.0",
         "esbuild-plugin-entry-chunks": "0.1.15",
         "esbuild-plugin-extract-helpers": "0.0.6",
@@ -39,8 +39,8 @@
         "fs-extra": "11.3.0",
         "get-port": "7.1.0",
         "globby": "14.1.0",
-        "jsr": "0.13.4",
-        "lefthook": "1.11.14",
+        "jsr": "0.13.5",
+        "lefthook": "1.12.2",
         "madge": "8.0.0",
         "minimist": "1.2.8",
         "node-fetch-native": "1.6.6",
@@ -821,9 +821,9 @@
       }
     },
     "node_modules/@esbuild/aix-ppc64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
-      "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz",
+      "integrity": "sha512-ShbM/3XxwuxjFiuVBHA+d3j5dyac0aEVVq1oluIDf71hUw0aRF59dV/efUsIwFnR6m8JNM2FjZOzmaZ8yG61kw==",
       "cpu": [
         "ppc64"
       ],
@@ -838,9 +838,9 @@
       }
     },
     "node_modules/@esbuild/android-arm": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
-      "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.6.tgz",
+      "integrity": "sha512-S8ToEOVfg++AU/bHwdksHNnyLyVM+eMVAOf6yRKFitnwnbwwPNqKr3srzFRe7nzV69RQKb5DgchIX5pt3L53xg==",
       "cpu": [
         "arm"
       ],
@@ -855,9 +855,9 @@
       }
     },
     "node_modules/@esbuild/android-arm64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
-      "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.6.tgz",
+      "integrity": "sha512-hd5zdUarsK6strW+3Wxi5qWws+rJhCCbMiC9QZyzoxfk5uHRIE8T287giQxzVpEvCwuJ9Qjg6bEjcRJcgfLqoA==",
       "cpu": [
         "arm64"
       ],
@@ -872,9 +872,9 @@
       }
     },
     "node_modules/@esbuild/android-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
-      "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.6.tgz",
+      "integrity": "sha512-0Z7KpHSr3VBIO9A/1wcT3NTy7EB4oNC4upJ5ye3R7taCc2GUdeynSLArnon5G8scPwaU866d3H4BCrE5xLW25A==",
       "cpu": [
         "x64"
       ],
@@ -889,9 +889,9 @@
       }
     },
     "node_modules/@esbuild/darwin-arm64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
-      "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.6.tgz",
+      "integrity": "sha512-FFCssz3XBavjxcFxKsGy2DYK5VSvJqa6y5HXljKzhRZ87LvEi13brPrf/wdyl/BbpbMKJNOr1Sd0jtW4Ge1pAA==",
       "cpu": [
         "arm64"
       ],
@@ -906,9 +906,9 @@
       }
     },
     "node_modules/@esbuild/darwin-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
-      "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.6.tgz",
+      "integrity": "sha512-GfXs5kry/TkGM2vKqK2oyiLFygJRqKVhawu3+DOCk7OxLy/6jYkWXhlHwOoTb0WqGnWGAS7sooxbZowy+pK9Yg==",
       "cpu": [
         "x64"
       ],
@@ -923,9 +923,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-arm64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
-      "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.6.tgz",
+      "integrity": "sha512-aoLF2c3OvDn2XDTRvn8hN6DRzVVpDlj2B/F66clWd/FHLiHaG3aVZjxQX2DYphA5y/evbdGvC6Us13tvyt4pWg==",
       "cpu": [
         "arm64"
       ],
@@ -940,9 +940,9 @@
       }
     },
     "node_modules/@esbuild/freebsd-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
-      "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.6.tgz",
+      "integrity": "sha512-2SkqTjTSo2dYi/jzFbU9Plt1vk0+nNg8YC8rOXXea+iA3hfNJWebKYPs3xnOUf9+ZWhKAaxnQNUf2X9LOpeiMQ==",
       "cpu": [
         "x64"
       ],
@@ -957,9 +957,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
-      "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.6.tgz",
+      "integrity": "sha512-SZHQlzvqv4Du5PrKE2faN0qlbsaW/3QQfUUc6yO2EjFcA83xnwm91UbEEVx4ApZ9Z5oG8Bxz4qPE+HFwtVcfyw==",
       "cpu": [
         "arm"
       ],
@@ -974,9 +974,9 @@
       }
     },
     "node_modules/@esbuild/linux-arm64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
-      "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.6.tgz",
+      "integrity": "sha512-b967hU0gqKd9Drsh/UuAm21Khpoh6mPBSgz8mKRq4P5mVK8bpA+hQzmm/ZwGVULSNBzKdZPQBRT3+WuVavcWsQ==",
       "cpu": [
         "arm64"
       ],
@@ -991,9 +991,9 @@
       }
     },
     "node_modules/@esbuild/linux-ia32": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
-      "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.6.tgz",
+      "integrity": "sha512-aHWdQ2AAltRkLPOsKdi3xv0mZ8fUGPdlKEjIEhxCPm5yKEThcUjHpWB1idN74lfXGnZ5SULQSgtr5Qos5B0bPw==",
       "cpu": [
         "ia32"
       ],
@@ -1008,9 +1008,9 @@
       }
     },
     "node_modules/@esbuild/linux-loong64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
-      "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.6.tgz",
+      "integrity": "sha512-VgKCsHdXRSQ7E1+QXGdRPlQ/e08bN6WMQb27/TMfV+vPjjTImuT9PmLXupRlC90S1JeNNW5lzkAEO/McKeJ2yg==",
       "cpu": [
         "loong64"
       ],
@@ -1025,9 +1025,9 @@
       }
     },
     "node_modules/@esbuild/linux-mips64el": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
-      "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.6.tgz",
+      "integrity": "sha512-WViNlpivRKT9/py3kCmkHnn44GkGXVdXfdc4drNmRl15zVQ2+D2uFwdlGh6IuK5AAnGTo2qPB1Djppj+t78rzw==",
       "cpu": [
         "mips64el"
       ],
@@ -1042,9 +1042,9 @@
       }
     },
     "node_modules/@esbuild/linux-ppc64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
-      "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.6.tgz",
+      "integrity": "sha512-wyYKZ9NTdmAMb5730I38lBqVu6cKl4ZfYXIs31Baf8aoOtB4xSGi3THmDYt4BTFHk7/EcVixkOV2uZfwU3Q2Jw==",
       "cpu": [
         "ppc64"
       ],
@@ -1059,9 +1059,9 @@
       }
     },
     "node_modules/@esbuild/linux-riscv64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
-      "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.6.tgz",
+      "integrity": "sha512-KZh7bAGGcrinEj4qzilJ4hqTY3Dg2U82c8bv+e1xqNqZCrCyc+TL9AUEn5WGKDzm3CfC5RODE/qc96OcbIe33w==",
       "cpu": [
         "riscv64"
       ],
@@ -1076,9 +1076,9 @@
       }
     },
     "node_modules/@esbuild/linux-s390x": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
-      "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.6.tgz",
+      "integrity": "sha512-9N1LsTwAuE9oj6lHMyyAM+ucxGiVnEqUdp4v7IaMmrwb06ZTEVCIs3oPPplVsnjPfyjmxwHxHMF8b6vzUVAUGw==",
       "cpu": [
         "s390x"
       ],
@@ -1093,9 +1093,9 @@
       }
     },
     "node_modules/@esbuild/linux-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
-      "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.6.tgz",
+      "integrity": "sha512-A6bJB41b4lKFWRKNrWoP2LHsjVzNiaurf7wyj/XtFNTsnPuxwEBWHLty+ZE0dWBKuSK1fvKgrKaNjBS7qbFKig==",
       "cpu": [
         "x64"
       ],
@@ -1110,9 +1110,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-arm64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
-      "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.6.tgz",
+      "integrity": "sha512-IjA+DcwoVpjEvyxZddDqBY+uJ2Snc6duLpjmkXm/v4xuS3H+3FkLZlDm9ZsAbF9rsfP3zeA0/ArNDORZgrxR/Q==",
       "cpu": [
         "arm64"
       ],
@@ -1127,9 +1127,9 @@
       }
     },
     "node_modules/@esbuild/netbsd-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
-      "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.6.tgz",
+      "integrity": "sha512-dUXuZr5WenIDlMHdMkvDc1FAu4xdWixTCRgP7RQLBOkkGgwuuzaGSYcOpW4jFxzpzL1ejb8yF620UxAqnBrR9g==",
       "cpu": [
         "x64"
       ],
@@ -1144,9 +1144,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-arm64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
-      "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.6.tgz",
+      "integrity": "sha512-l8ZCvXP0tbTJ3iaqdNf3pjaOSd5ex/e6/omLIQCVBLmHTlfXW3zAxQ4fnDmPLOB1x9xrcSi/xtCWFwCZRIaEwg==",
       "cpu": [
         "arm64"
       ],
@@ -1161,9 +1161,9 @@
       }
     },
     "node_modules/@esbuild/openbsd-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
-      "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.6.tgz",
+      "integrity": "sha512-hKrmDa0aOFOr71KQ/19JC7az1P0GWtCN1t2ahYAf4O007DHZt/dW8ym5+CUdJhQ/qkZmI1HAF8KkJbEFtCL7gw==",
       "cpu": [
         "x64"
       ],
@@ -1177,10 +1177,27 @@
         "node": ">=18"
       }
     },
+    "node_modules/@esbuild/openharmony-arm64": {
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.6.tgz",
+      "integrity": "sha512-+SqBcAWoB1fYKmpWoQP4pGtx+pUUC//RNYhFdbcSA16617cchuryuhOCRpPsjCblKukAckWsV+aQ3UKT/RMPcA==",
+      "cpu": [
+        "arm64"
+      ],
+      "dev": true,
+      "license": "MIT",
+      "optional": true,
+      "os": [
+        "openharmony"
+      ],
+      "engines": {
+        "node": ">=18"
+      }
+    },
     "node_modules/@esbuild/sunos-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
-      "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.6.tgz",
+      "integrity": "sha512-dyCGxv1/Br7MiSC42qinGL8KkG4kX0pEsdb0+TKhmJZgCUDBGmyo1/ArCjNGiOLiIAgdbWgmWgib4HoCi5t7kA==",
       "cpu": [
         "x64"
       ],
@@ -1195,9 +1212,9 @@
       }
     },
     "node_modules/@esbuild/win32-arm64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
-      "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.6.tgz",
+      "integrity": "sha512-42QOgcZeZOvXfsCBJF5Afw73t4veOId//XD3i+/9gSkhSV6Gk3VPlWncctI+JcOyERv85FUo7RxuxGy+z8A43Q==",
       "cpu": [
         "arm64"
       ],
@@ -1212,9 +1229,9 @@
       }
     },
     "node_modules/@esbuild/win32-ia32": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
-      "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.6.tgz",
+      "integrity": "sha512-4AWhgXmDuYN7rJI6ORB+uU9DHLq/erBbuMoAuB4VWJTu5KtCgcKYPynF0YI1VkBNuEfjNlLrFr9KZPJzrtLkrQ==",
       "cpu": [
         "ia32"
       ],
@@ -1229,9 +1246,9 @@
       }
     },
     "node_modules/@esbuild/win32-x64": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
-      "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.6.tgz",
+      "integrity": "sha512-NgJPHHbEpLQgDH2MjQu90pzW/5vvXIZ7KOnPyNBm92A6WgZ/7b6fJyUBjoumLqeOQQGqY2QjQxRo97ah4Sj0cA==",
       "cpu": [
         "x64"
       ],
@@ -2109,9 +2126,9 @@
       "license": "MIT"
     },
     "node_modules/@types/node": {
-      "version": "24.0.8",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.8.tgz",
-      "integrity": "sha512-WytNrFSgWO/esSH9NbpWUfTMGQwCGIKfCmNlmFDNiI5gGhgMmEA+V1AEvKLeBNvvtBnailJtkrEa2OIISwrVAA==",
+      "version": "24.0.13",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.13.tgz",
+      "integrity": "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -2545,21 +2562,21 @@
       }
     },
     "node_modules/@webpod/ingrid": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/@webpod/ingrid/-/ingrid-1.0.1.tgz",
-      "integrity": "sha512-cKr6uLaAfl/9KcVtjbntBReUlPtAwmLaJXzmwETyvc5QaNMqDKFGYVuKBwBmCIc8+l3iuoTTxsRp9X7RJqhXmw==",
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/@webpod/ingrid/-/ingrid-1.1.1.tgz",
+      "integrity": "sha512-qTCBeMZkLZ8WoHVuKLxALyre7e4udBU3K2sTnDAh5PE1W0+CFaUTAzV4tozJHaBHwJx8GVic8bGvLCso07QLQA==",
       "dev": true,
       "license": "MIT"
     },
     "node_modules/@webpod/ps": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/@webpod/ps/-/ps-0.1.2.tgz",
-      "integrity": "sha512-0u5nRWrqZCpZcs8qZn3RDEXEe3B9oadF5oC+EwgBZi2Ur8tbeg/p1EIQbblUUFqwK0+amIIHiH+oUWP6SXJ2CA==",
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@webpod/ps/-/ps-0.1.3.tgz",
+      "integrity": "sha512-M6u51Qbk9QHE1Rv2tjUaikcxj9vGUMmtl7Ma5ylE1GAx1djpViNZDMO33pE5Sw7wNlsyHt2ymrzpuBb0xoKaNg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "@webpod/ingrid": "^1.0.0",
-        "zurk": "^0.11.3"
+        "@webpod/ingrid": "^1.1.1",
+        "zurk": "^0.11.4"
       }
     },
     "node_modules/acorn": {
@@ -3761,9 +3778,9 @@
       }
     },
     "node_modules/esbuild": {
-      "version": "0.25.5",
-      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
-      "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
+      "version": "0.25.6",
+      "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.6.tgz",
+      "integrity": "sha512-GVuzuUwtdsghE3ocJ9Bs8PNoF13HNQ5TXbEi2AhvVb8xU1Iwt9Fos9FEamfoee+u/TOsn7GUWc04lz46n2bbTg==",
       "dev": true,
       "hasInstallScript": true,
       "license": "MIT",
@@ -3774,31 +3791,32 @@
         "node": ">=18"
       },
       "optionalDependencies": {
-        "@esbuild/aix-ppc64": "0.25.5",
-        "@esbuild/android-arm": "0.25.5",
-        "@esbuild/android-arm64": "0.25.5",
-        "@esbuild/android-x64": "0.25.5",
-        "@esbuild/darwin-arm64": "0.25.5",
-        "@esbuild/darwin-x64": "0.25.5",
-        "@esbuild/freebsd-arm64": "0.25.5",
-        "@esbuild/freebsd-x64": "0.25.5",
-        "@esbuild/linux-arm": "0.25.5",
-        "@esbuild/linux-arm64": "0.25.5",
-        "@esbuild/linux-ia32": "0.25.5",
-        "@esbuild/linux-loong64": "0.25.5",
-        "@esbuild/linux-mips64el": "0.25.5",
-        "@esbuild/linux-ppc64": "0.25.5",
-        "@esbuild/linux-riscv64": "0.25.5",
-        "@esbuild/linux-s390x": "0.25.5",
-        "@esbuild/linux-x64": "0.25.5",
-        "@esbuild/netbsd-arm64": "0.25.5",
-        "@esbuild/netbsd-x64": "0.25.5",
-        "@esbuild/openbsd-arm64": "0.25.5",
-        "@esbuild/openbsd-x64": "0.25.5",
-        "@esbuild/sunos-x64": "0.25.5",
-        "@esbuild/win32-arm64": "0.25.5",
-        "@esbuild/win32-ia32": "0.25.5",
-        "@esbuild/win32-x64": "0.25.5"
+        "@esbuild/aix-ppc64": "0.25.6",
+        "@esbuild/android-arm": "0.25.6",
+        "@esbuild/android-arm64": "0.25.6",
+        "@esbuild/android-x64": "0.25.6",
+        "@esbuild/darwin-arm64": "0.25.6",
+        "@esbuild/darwin-x64": "0.25.6",
+        "@esbuild/freebsd-arm64": "0.25.6",
+        "@esbuild/freebsd-x64": "0.25.6",
+        "@esbuild/linux-arm": "0.25.6",
+        "@esbuild/linux-arm64": "0.25.6",
+        "@esbuild/linux-ia32": "0.25.6",
+        "@esbuild/linux-loong64": "0.25.6",
+        "@esbuild/linux-mips64el": "0.25.6",
+        "@esbuild/linux-ppc64": "0.25.6",
+        "@esbuild/linux-riscv64": "0.25.6",
+        "@esbuild/linux-s390x": "0.25.6",
+        "@esbuild/linux-x64": "0.25.6",
+        "@esbuild/netbsd-arm64": "0.25.6",
+        "@esbuild/netbsd-x64": "0.25.6",
+        "@esbuild/openbsd-arm64": "0.25.6",
+        "@esbuild/openbsd-x64": "0.25.6",
+        "@esbuild/openharmony-arm64": "0.25.6",
+        "@esbuild/sunos-x64": "0.25.6",
+        "@esbuild/win32-arm64": "0.25.6",
+        "@esbuild/win32-ia32": "0.25.6",
+        "@esbuild/win32-x64": "0.25.6"
       }
     },
     "node_modules/esbuild-node-externals": {
@@ -5014,13 +5032,12 @@
       }
     },
     "node_modules/jsr": {
-      "version": "0.13.4",
-      "resolved": "https://registry.npmjs.org/jsr/-/jsr-0.13.4.tgz",
-      "integrity": "sha512-GJ9Ju8kf2SxH90C1AqANrMKBFlDjrZu1YoFm4SoMCOBOxix3Bvirdg5JB31gbF8FwPBo3196dAaqV0WUjeuq8Q==",
+      "version": "0.13.5",
+      "resolved": "https://registry.npmjs.org/jsr/-/jsr-0.13.5.tgz",
+      "integrity": "sha512-qQP20ZcG28pYes7bCq3uuvixl1TL1EpJzwLPfoQadSyWk9j2AID66qhW8+aXpRDRFDvDkXFnONsSRhpnnQAupg==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
-        "kolorist": "^1.8.0",
         "node-stream-zip": "^1.15.0",
         "semiver": "^1.1.0"
       },
@@ -5038,17 +5055,10 @@
         "node": ">=0.10.0"
       }
     },
-    "node_modules/kolorist": {
-      "version": "1.8.0",
-      "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
-      "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
-      "dev": true,
-      "license": "MIT"
-    },
     "node_modules/lefthook": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-1.11.14.tgz",
-      "integrity": "sha512-Dv91Lnu/0jLT5pCZE0IkEfrpTXUhyX9WG4upEMPkKPCl5aBgJdoqVw/hbh8drcVrC6y7k1PqsRmWSERmO57weQ==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook/-/lefthook-1.12.2.tgz",
+      "integrity": "sha512-2CeTu5NcmoT9YnqsHTq/TF36MlqlzHzhivGx3DrXHwcff4TdvrkIwUTA56huM3Nlo5ODAF/0hlPzaKLmNHCBnQ==",
       "dev": true,
       "hasInstallScript": true,
       "license": "MIT",
@@ -5056,22 +5066,22 @@
         "lefthook": "bin/index.js"
       },
       "optionalDependencies": {
-        "lefthook-darwin-arm64": "1.11.14",
-        "lefthook-darwin-x64": "1.11.14",
-        "lefthook-freebsd-arm64": "1.11.14",
-        "lefthook-freebsd-x64": "1.11.14",
-        "lefthook-linux-arm64": "1.11.14",
-        "lefthook-linux-x64": "1.11.14",
-        "lefthook-openbsd-arm64": "1.11.14",
-        "lefthook-openbsd-x64": "1.11.14",
-        "lefthook-windows-arm64": "1.11.14",
-        "lefthook-windows-x64": "1.11.14"
+        "lefthook-darwin-arm64": "1.12.2",
+        "lefthook-darwin-x64": "1.12.2",
+        "lefthook-freebsd-arm64": "1.12.2",
+        "lefthook-freebsd-x64": "1.12.2",
+        "lefthook-linux-arm64": "1.12.2",
+        "lefthook-linux-x64": "1.12.2",
+        "lefthook-openbsd-arm64": "1.12.2",
+        "lefthook-openbsd-x64": "1.12.2",
+        "lefthook-windows-arm64": "1.12.2",
+        "lefthook-windows-x64": "1.12.2"
       }
     },
     "node_modules/lefthook-darwin-arm64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.11.14.tgz",
-      "integrity": "sha512-YPbUK6kGytY5W6aNUrzK7Vod3ynLVvj5JQiBh0DjlxCHMgIQPpFkDfwQzGw1E8CySyC95HXO83En5Ule8umS7g==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.12.2.tgz",
+      "integrity": "sha512-fTxeI9tEskrHjc3QyEO+AG7impBXY2Ed8V5aiRc3fw9POfYtVh9b5jRx90fjk2+ld5hf+Z1DsyyLq/vOHDFskQ==",
       "cpu": [
         "arm64"
       ],
@@ -5083,9 +5093,9 @@
       ]
     },
     "node_modules/lefthook-darwin-x64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-1.11.14.tgz",
-      "integrity": "sha512-l9RhSBp1SHqLCjSGWoeeVWqKcTBOMW8v2CCYrUt5eb6sik7AjT6+Neqf3sClsXH7SjELjj43yjmg6loqPtfDgg==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-darwin-x64/-/lefthook-darwin-x64-1.12.2.tgz",
+      "integrity": "sha512-T1dCDKAAfdHgYZ8qtrS02SJSHoR52RFcrGArFNll9Mu4ZSV19Sp8BO+kTwDUOcLYdcPGNaqOp9PkRBQGZWQC7g==",
       "cpu": [
         "x64"
       ],
@@ -5097,9 +5107,9 @@
       ]
     },
     "node_modules/lefthook-freebsd-arm64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.11.14.tgz",
-      "integrity": "sha512-oSdJKGGMohktFXC6faZCUt5afyHpDwWGIWAkHGgOXUVD/LiZDEn6U/8cQmKm1UAfBySuPTtfir0VeM04y6188g==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.12.2.tgz",
+      "integrity": "sha512-2n9z7Q4BKeMBoB9cuEdv0UBQH82Z4GgBQpCrfjCtyzpDnYQwrH8Tkrlnlko4qPh9MM6nLLGIYMKsA5nltzo8Cg==",
       "cpu": [
         "arm64"
       ],
@@ -5111,9 +5121,9 @@
       ]
     },
     "node_modules/lefthook-freebsd-x64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.11.14.tgz",
-      "integrity": "sha512-gZdMWZwOtIhIPK3GPYac7JhXrxF188gkw65i6O7CedS/meDlK2vjBv5BUVLeD/satv4+jibEdV0h4Qqu/xIh2A==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.12.2.tgz",
+      "integrity": "sha512-1hNY/irY+/3kjRzKoJYxG+m3BYI8QxopJUK1PQnknGo1Wy5u302SdX+tR7pnpz6JM5chrNw4ozSbKKOvdZ5VEw==",
       "cpu": [
         "x64"
       ],
@@ -5125,9 +5135,9 @@
       ]
     },
     "node_modules/lefthook-linux-arm64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-1.11.14.tgz",
-      "integrity": "sha512-sZmqbTsGQFQw7gbfi9eIHFOxfcs66QfZYLRMh1DktODhyhRXB8RtI6KMeKCtPEGLhbK55/I4TprC8Qvj86UBgw==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-linux-arm64/-/lefthook-linux-arm64-1.12.2.tgz",
+      "integrity": "sha512-1W4swYIVRkxq/LFTuuK4oVpd6NtTKY4E3VY2Uq2JDkIOJV46+8qGBF+C/QA9K3O9chLffgN7c+i+NhIuGiZ/Vw==",
       "cpu": [
         "arm64"
       ],
@@ -5139,9 +5149,9 @@
       ]
     },
     "node_modules/lefthook-linux-x64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-1.11.14.tgz",
-      "integrity": "sha512-c+to1BRzFe419SNXAR6YpCBP8EVWxvUxlON3Z+efzmrHhdlhm7LvEoJcN4RQE4Gc2rJQJNe87OjsEZQkc4uQLg==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-linux-x64/-/lefthook-linux-x64-1.12.2.tgz",
+      "integrity": "sha512-J6VGuMfhq5iCsg1Pv7xULbuXC63gP5LaikT0PhkyBNMi3HQneZFDJ8k/sp0Ue9HkQv6QfWIo3/FgB9gz38MCFw==",
       "cpu": [
         "x64"
       ],
@@ -5153,9 +5163,9 @@
       ]
     },
     "node_modules/lefthook-openbsd-arm64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-1.11.14.tgz",
-      "integrity": "sha512-fivG3D9G4ASRCTf3ecfz1WdnrHCW9pezaI8v1NVve8t6B2q0d0yeaje5dfhoAsAvwiFPRaMzka1Qaoyu8O8G9Q==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-1.12.2.tgz",
+      "integrity": "sha512-wncDRW3ml24DaOyH22KINumjvCohswbQqbxyH2GORRCykSnE859cTjOrRIchTKBIARF7PSeGPUtS7EK0+oDbaw==",
       "cpu": [
         "arm64"
       ],
@@ -5167,9 +5177,9 @@
       ]
     },
     "node_modules/lefthook-openbsd-x64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-openbsd-x64/-/lefthook-openbsd-x64-1.11.14.tgz",
-      "integrity": "sha512-vikmG0jf7JVKR3be6Wk3l1jtEdedEqk1BTdsaHFX1bj0qk0azcqlZ819Wt/IoyIYDzQCHKowZ6DuXsRjT+RXWA==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-openbsd-x64/-/lefthook-openbsd-x64-1.12.2.tgz",
+      "integrity": "sha512-2jDOkCHNnc/oK/vR62hAf3vZb1EQ6Md2GjIlgZ/V7A3ztOsM8QZ5IxwYN3D1UOIR5ZnwMBy7PtmTJC/HJrig5w==",
       "cpu": [
         "x64"
       ],
@@ -5181,9 +5191,9 @@
       ]
     },
     "node_modules/lefthook-windows-arm64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-1.11.14.tgz",
-      "integrity": "sha512-5PoAJ9QKaqxJn1NWrhrhXpAROpl/dT7bGTo7VMj2ATO1cpRatbn6p+ssvc3tgeriFThowFb1D11Fg6OlFLi6UQ==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-windows-arm64/-/lefthook-windows-arm64-1.12.2.tgz",
+      "integrity": "sha512-ZMH/q6UNSidhHEG/1QoqIl1n4yPTBWuVmKx5bONtKHicoz4QCQ+QEiNjKsG5OO4C62nfyHGThmweCzZVUQECJw==",
       "cpu": [
         "arm64"
       ],
@@ -5195,9 +5205,9 @@
       ]
     },
     "node_modules/lefthook-windows-x64": {
-      "version": "1.11.14",
-      "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-1.11.14.tgz",
-      "integrity": "sha512-kBeOPR0Aj5hQGxoBBntgz5/e/xaH5Vnzlq9lJjHW8sf23qu/JVUGg6ceCoicyVWJi+ZOBliTa8KzwCu+mgyJjw==",
+      "version": "1.12.2",
+      "resolved": "https://registry.npmjs.org/lefthook-windows-x64/-/lefthook-windows-x64-1.12.2.tgz",
+      "integrity": "sha512-TqT2jIPcTQ9uwaw+v+DTmvnUHM/p7bbsSrPoPX+fRXSGLzFjyiY+12C9dObSwfCQq6rT70xqQJ9AmftJQsa5/Q==",
       "cpu": [
         "x64"
       ],
package.json
@@ -109,10 +109,10 @@
     "@size-limit/file": "11.2.0",
     "@types/fs-extra": "11.0.4",
     "@types/minimist": "1.2.5",
-    "@types/node": "24.0.8",
+    "@types/node": "24.0.13",
     "@types/which": "3.0.4",
-    "@webpod/ingrid": "1.0.1",
-    "@webpod/ps": "0.1.2",
+    "@webpod/ingrid": "1.1.1",
+    "@webpod/ps": "0.1.3",
     "c8": "10.1.3",
     "chalk": "5.4.1",
     "create-require": "1.1.1",
@@ -120,7 +120,7 @@
     "depseek": "0.4.1",
     "dts-bundle-generator": "9.5.1",
     "envapi": "0.2.3",
-    "esbuild": "0.25.5",
+    "esbuild": "0.25.6",
     "esbuild-node-externals": "1.18.0",
     "esbuild-plugin-entry-chunks": "0.1.15",
     "esbuild-plugin-extract-helpers": "0.0.6",
@@ -131,8 +131,8 @@
     "fs-extra": "11.3.0",
     "get-port": "7.1.0",
     "globby": "14.1.0",
-    "jsr": "0.13.4",
-    "lefthook": "1.11.14",
+    "jsr": "0.13.5",
+    "lefthook": "1.12.2",
     "madge": "8.0.0",
     "minimist": "1.2.8",
     "node-fetch-native": "1.6.6",