kandev 0.58.0 → 0.59.0

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 (2) hide show
  1. package/dist/process.js +33 -0
  2. package/package.json +6 -6
package/dist/process.js CHANGED
@@ -4,6 +4,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.createProcessSupervisor = createProcessSupervisor;
7
+ exports.ignoreBrokenPipe = ignoreBrokenPipe;
8
+ exports.__resetBrokenPipeGuard = __resetBrokenPipeGuard;
7
9
  const tree_kill_1 = __importDefault(require("tree-kill"));
8
10
  const SHUTDOWN_TIMEOUT_MS = 10000;
9
11
  function createProcessSupervisor() {
@@ -25,6 +27,12 @@ function createProcessSupervisor() {
25
27
  void shutdown(`signal ${signal}`).then(() => process.exit(0));
26
28
  };
27
29
  const attachSignalHandlers = () => {
30
+ // Ctrl-C sends SIGINT to the whole process group, so the parent (make/shell)
31
+ // exits and closes the pipe our stdout/stderr write to. Any console.log during
32
+ // shutdown then triggers an EPIPE 'error' event with no listener, which Node
33
+ // treats as fatal and crashes us before children are gracefully terminated.
34
+ // Swallow EPIPE so shutdown can finish.
35
+ ignoreBrokenPipe();
28
36
  process.on("SIGINT", onSignal);
29
37
  // SIGTERM is not available on Windows — only attach where supported
30
38
  if (process.platform !== "win32") {
@@ -33,6 +41,31 @@ function createProcessSupervisor() {
33
41
  };
34
42
  return { children, shutdown, attachSignalHandlers };
35
43
  }
44
+ let brokenPipeGuarded = false;
45
+ /**
46
+ * Install error handlers on stdout/stderr that swallow EPIPE (broken pipe).
47
+ * Idempotent: only attaches once per process.
48
+ */
49
+ function ignoreBrokenPipe() {
50
+ if (brokenPipeGuarded)
51
+ return;
52
+ brokenPipeGuarded = true;
53
+ const onPipeError = (err) => {
54
+ if (err.code === "EPIPE")
55
+ return;
56
+ throw err;
57
+ };
58
+ process.stdout.on("error", onPipeError);
59
+ process.stderr.on("error", onPipeError);
60
+ }
61
+ /**
62
+ * Test-only: resets the broken-pipe guard so a later `ignoreBrokenPipe()` call
63
+ * reattaches listeners. Keeps the module guard consistent with suites that
64
+ * remove the listeners they installed.
65
+ */
66
+ function __resetBrokenPipeGuard() {
67
+ brokenPipeGuarded = false;
68
+ }
36
69
  /**
37
70
  * Terminate a process and wait for it to exit.
38
71
  * On Unix: sends SIGTERM, falls back to SIGKILL after timeout.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kandev",
3
- "version": "0.58.0",
3
+ "version": "0.59.0",
4
4
  "private": false,
5
5
  "description": "Launcher for Kandev — manage tasks, orchestrate agents, review changes, and ship value",
6
6
  "license": "AGPL-3.0-only",
@@ -22,11 +22,11 @@
22
22
  "npm": ">=7"
23
23
  },
24
24
  "optionalDependencies": {
25
- "@kdlbs/runtime-linux-x64": "0.58.0",
26
- "@kdlbs/runtime-linux-arm64": "0.58.0",
27
- "@kdlbs/runtime-darwin-x64": "0.58.0",
28
- "@kdlbs/runtime-darwin-arm64": "0.58.0",
29
- "@kdlbs/runtime-win32-x64": "0.58.0"
25
+ "@kdlbs/runtime-linux-x64": "0.59.0",
26
+ "@kdlbs/runtime-linux-arm64": "0.59.0",
27
+ "@kdlbs/runtime-darwin-x64": "0.59.0",
28
+ "@kdlbs/runtime-darwin-arm64": "0.59.0",
29
+ "@kdlbs/runtime-win32-x64": "0.59.0"
30
30
  },
31
31
  "dependencies": {
32
32
  "tar": "^7.5.11",