@code-yeongyu/senpi-codemode 2026.9.19 → 2026.9.21

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/CHANGELOG.md CHANGED
@@ -12,6 +12,46 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## [2026.9.21] - 2026-09-21
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ - Updated the bundled dependencies: typebox 1.3.27 -> 1.3.34. ([#1895](https://github.com/code-yeongyu/senpi/issues/1895))
24
+
25
+ ### Fixed
26
+
27
+ - Python eval kernel: a kernel whose host process died mid-cell now exits instead of being orphaned forever. ([#1659](https://github.com/code-yeongyu/senpi/issues/1659))
28
+
29
+ ### Removed
30
+
31
+ ## [2026.9.20] - 2026-09-20
32
+
33
+ ### Breaking Changes
34
+
35
+ ### Added
36
+
37
+ ### Changed
38
+
39
+ ### Fixed
40
+
41
+ ### Removed
42
+
43
+ ## [2026.9.19-2] - 2026-09-19
44
+
45
+ ### Breaking Changes
46
+
47
+ ### Added
48
+
49
+ ### Changed
50
+
51
+ ### Fixed
52
+
53
+ ### Removed
54
+
15
55
  ## [2026.9.19] - 2026-09-19
16
56
 
17
57
  ### Breaking Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.9.19",
3
+ "version": "2026.9.21",
4
4
  "description": "Source-only senpi extension package for codemode evaluation tools",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -30,14 +30,14 @@
30
30
  },
31
31
  "dependencies": {
32
32
  "@babel/parser": "8.0.4",
33
- "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.19",
34
- "typebox": "1.3.27"
33
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.21",
34
+ "typebox": "1.3.34"
35
35
  },
36
36
  "peerDependencies": {
37
- "@code-yeongyu/senpi": "2026.9.19"
37
+ "@code-yeongyu/senpi": "2026.9.21"
38
38
  },
39
39
  "devDependencies": {
40
- "@code-yeongyu/senpi": "2026.9.19"
40
+ "@code-yeongyu/senpi": "2026.9.21"
41
41
  },
42
42
  "keywords": [
43
43
  "senpi",
@@ -1097,10 +1097,33 @@ def _watch_parent(initial_ppid: int) -> None:
1097
1097
  return
1098
1098
 
1099
1099
 
1100
+ def _watch_named_parent(parent_pid: int) -> None:
1101
+ # The ppid watch above can only observe a change from the ppid captured at boot. A
1102
+ # host that died before the interpreter reached that capture is already replaced in
1103
+ # getppid() by the posthumous value, so no transition ever fires. The host passes its
1104
+ # own pid at spawn (SENPI_PY_KERNEL_PARENT_PID) precisely so this loss is detectable:
1105
+ # poll the named pid instead of the ppid and take the whole group down once it is gone.
1106
+ while True:
1107
+ time.sleep(0.5)
1108
+ try:
1109
+ os.kill(parent_pid, 0)
1110
+ except ProcessLookupError:
1111
+ _terminate_process_group()
1112
+ return
1113
+
1114
+
1100
1115
  def _start_parent_watch() -> None:
1101
1116
  if os.name != "posix":
1102
1117
  return
1103
1118
  Thread(target=_watch_parent, args=(os.getppid(),), name="senpi-parent-watch", daemon=True).start()
1119
+ named_parent = os.environ.get("SENPI_PY_KERNEL_PARENT_PID")
1120
+ if named_parent and named_parent.isdigit():
1121
+ Thread(
1122
+ target=_watch_named_parent,
1123
+ args=(int(named_parent),),
1124
+ name="senpi-named-parent-watch",
1125
+ daemon=True,
1126
+ ).start()
1104
1127
 
1105
1128
 
1106
1129
  def main() -> None:
@@ -30,9 +30,13 @@ export class PythonKernelRetirementError extends Error {
30
30
  }
31
31
 
32
32
  export function defaultSpawn(options: KernelSpawnOptions): KernelChild {
33
+ // Detached children survive their host, so the prelude needs the host pid to
34
+ // watch for a parent that is already gone by the time the interpreter boots.
35
+ const env =
36
+ process.platform === "win32" ? options.env : { ...options.env, SENPI_PY_KERNEL_PARENT_PID: String(process.pid) };
33
37
  return spawn(options.command, [...options.args], {
34
38
  cwd: options.cwd,
35
- env: options.env,
39
+ env,
36
40
  stdio: "pipe",
37
41
  detached: process.platform !== "win32",
38
42
  windowsHide: true,