@code-yeongyu/senpi-codemode 2026.9.20 → 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 +16 -0
- package/package.json +5 -5
- package/src/kernels/py/prelude.py +23 -0
- package/src/kernels/py/process.ts +5 -1
package/CHANGELOG.md
CHANGED
|
@@ -12,6 +12,22 @@
|
|
|
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
|
+
|
|
15
31
|
## [2026.9.20] - 2026-09-20
|
|
16
32
|
|
|
17
33
|
### Breaking Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/senpi-codemode",
|
|
3
|
-
"version": "2026.9.
|
|
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.
|
|
34
|
-
"typebox": "1.3.
|
|
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.
|
|
37
|
+
"@code-yeongyu/senpi": "2026.9.21"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
|
-
"@code-yeongyu/senpi": "2026.9.
|
|
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
|
|
39
|
+
env,
|
|
36
40
|
stdio: "pipe",
|
|
37
41
|
detached: process.platform !== "win32",
|
|
38
42
|
windowsHide: true,
|