@hasna/hooks 0.6.4 → 0.6.5

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/index.js CHANGED
@@ -5868,7 +5868,7 @@ async function executeVerifiedScript(options) {
5868
5868
  let timedOut = false;
5869
5869
  const timeoutTimer = options.timeout ? setTimeout(() => {
5870
5870
  timedOut = true;
5871
- killGroup(proc);
5871
+ killGroup(proc, { leaderAlive: proc !== null && proc.exitCode === null });
5872
5872
  }, options.timeout) : null;
5873
5873
  try {
5874
5874
  writeFileSync6(tempPath, options.content, { flag: "wx", mode: 384 });
@@ -5887,7 +5887,7 @@ async function executeVerifiedScript(options) {
5887
5887
  readPipeWithDeadline(proc.stdout, 750),
5888
5888
  readPipeWithDeadline(proc.stderr, 750)
5889
5889
  ]);
5890
- killGroup(proc);
5890
+ killGroup(proc, { leaderAlive: false });
5891
5891
  return { stdout: stdoutText, stderr: stderrText, exitCode };
5892
5892
  } finally {
5893
5893
  if (timeoutTimer)
@@ -5897,12 +5897,36 @@ async function executeVerifiedScript(options) {
5897
5897
  } catch {}
5898
5898
  }
5899
5899
  }
5900
- function killGroup(proc) {
5900
+ function killGroup(proc, options) {
5901
5901
  if (!proc)
5902
5902
  return;
5903
- try {
5904
- process.kill(-proc.pid, "SIGKILL");
5905
- } catch {
5903
+ const pgid = proc.pid;
5904
+ for (let pass = 0;pass < 5; pass++) {
5905
+ let members = [];
5906
+ try {
5907
+ const res = Bun.spawnSync(["ps", "-eo", "pid=,pgid="], { stdout: "pipe", stderr: "pipe" });
5908
+ if (res.exitCode === 0) {
5909
+ members = res.stdout.toString().split(`
5910
+ `).map((line) => line.trim().split(/\s+/)).filter((cols) => cols.length === 2 && cols[1] === String(pgid)).map((cols) => Number(cols[0])).filter((pid) => Number.isInteger(pid) && pid > 1).filter((pid) => options.leaderAlive || pid !== proc.pid);
5911
+ }
5912
+ } catch {}
5913
+ if (members.length === 0)
5914
+ break;
5915
+ let killed = 0;
5916
+ for (const pid of members) {
5917
+ try {
5918
+ const probe = Bun.spawnSync(["ps", "-o", "pid=,pgid=", "-p", String(pid)], { stdout: "pipe", stderr: "pipe" });
5919
+ const cols = probe.stdout.toString().trim().split(/\s+/);
5920
+ if (cols.length === 2 && cols[1] === String(pgid)) {
5921
+ process.kill(pid, "SIGKILL");
5922
+ killed++;
5923
+ }
5924
+ } catch {}
5925
+ }
5926
+ if (killed === 0)
5927
+ break;
5928
+ }
5929
+ if (options.leaderAlive) {
5906
5930
  try {
5907
5931
  process.kill(proc.pid, "SIGKILL");
5908
5932
  } catch {}
package/dist/index.js CHANGED
@@ -4979,7 +4979,7 @@ async function executeVerifiedScript(options) {
4979
4979
  let timedOut = false;
4980
4980
  const timeoutTimer = options.timeout ? setTimeout(() => {
4981
4981
  timedOut = true;
4982
- killGroup(proc);
4982
+ killGroup(proc, { leaderAlive: proc !== null && proc.exitCode === null });
4983
4983
  }, options.timeout) : null;
4984
4984
  try {
4985
4985
  writeFileSync6(tempPath, options.content, { flag: "wx", mode: 384 });
@@ -4998,7 +4998,7 @@ async function executeVerifiedScript(options) {
4998
4998
  readPipeWithDeadline(proc.stdout, 750),
4999
4999
  readPipeWithDeadline(proc.stderr, 750)
5000
5000
  ]);
5001
- killGroup(proc);
5001
+ killGroup(proc, { leaderAlive: false });
5002
5002
  return { stdout: stdoutText, stderr: stderrText, exitCode };
5003
5003
  } finally {
5004
5004
  if (timeoutTimer)
@@ -5008,12 +5008,36 @@ async function executeVerifiedScript(options) {
5008
5008
  } catch {}
5009
5009
  }
5010
5010
  }
5011
- function killGroup(proc) {
5011
+ function killGroup(proc, options) {
5012
5012
  if (!proc)
5013
5013
  return;
5014
- try {
5015
- process.kill(-proc.pid, "SIGKILL");
5016
- } catch {
5014
+ const pgid = proc.pid;
5015
+ for (let pass = 0;pass < 5; pass++) {
5016
+ let members = [];
5017
+ try {
5018
+ const res = Bun.spawnSync(["ps", "-eo", "pid=,pgid="], { stdout: "pipe", stderr: "pipe" });
5019
+ if (res.exitCode === 0) {
5020
+ members = res.stdout.toString().split(`
5021
+ `).map((line) => line.trim().split(/\s+/)).filter((cols) => cols.length === 2 && cols[1] === String(pgid)).map((cols) => Number(cols[0])).filter((pid) => Number.isInteger(pid) && pid > 1).filter((pid) => options.leaderAlive || pid !== proc.pid);
5022
+ }
5023
+ } catch {}
5024
+ if (members.length === 0)
5025
+ break;
5026
+ let killed = 0;
5027
+ for (const pid of members) {
5028
+ try {
5029
+ const probe = Bun.spawnSync(["ps", "-o", "pid=,pgid=", "-p", String(pid)], { stdout: "pipe", stderr: "pipe" });
5030
+ const cols = probe.stdout.toString().trim().split(/\s+/);
5031
+ if (cols.length === 2 && cols[1] === String(pgid)) {
5032
+ process.kill(pid, "SIGKILL");
5033
+ killed++;
5034
+ }
5035
+ } catch {}
5036
+ }
5037
+ if (killed === 0)
5038
+ break;
5039
+ }
5040
+ if (options.leaderAlive) {
5017
5041
  try {
5018
5042
  process.kill(proc.pid, "SIGKILL");
5019
5043
  } catch {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/hooks",
3
- "version": "0.6.4",
3
+ "version": "0.6.5",
4
4
  "description": "Open source hooks library for AI coding agents - Install safety, quality, and automation hooks with a single command",
5
5
  "type": "module",
6
6
  "bin": {