@code-yeongyu/senpi-codemode 2026.8.21-3 → 2026.8.22

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,20 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## [2026.8.22] - 2026-08-22
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ ### Fixed
24
+
25
+ - Ruby and Julia eval cells now wait for the subprocess `ready` signal before execution timeouts begin, so interpreter startup under load cannot time out a state-setting cell and silently restart the kernel before the next cell runs.
26
+
27
+ ### Removed
28
+
15
29
  ## [2026.8.21-3] - 2026-08-21
16
30
 
17
31
  ### Breaking Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.8.21-3",
3
+ "version": "2026.8.22",
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.8.21-3",
33
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.8.22",
34
34
  "typebox": "1.3.16"
35
35
  },
36
36
  "peerDependencies": {
37
- "@code-yeongyu/senpi": "2026.8.21-3"
37
+ "@code-yeongyu/senpi": "2026.8.22"
38
38
  },
39
39
  "devDependencies": {
40
- "@code-yeongyu/senpi": "2026.8.21-3"
40
+ "@code-yeongyu/senpi": "2026.8.22"
41
41
  },
42
42
  "keywords": [
43
43
  "senpi",
@@ -26,6 +26,7 @@ export class SubprocessKernel {
26
26
  private readonly onMessage?: (message: KernelToHostMessage) => void;
27
27
  private readonly runs = new SubprocessRunQueue();
28
28
  private process: SubprocessProcess | null = null;
29
+ private processReady = false;
29
30
  private retirementPromise: Promise<void> | null = null;
30
31
  private retirementProcess: SubprocessProcess | null = null;
31
32
  private retirementFailure: Error | null = null;
@@ -109,7 +110,7 @@ export class SubprocessKernel {
109
110
 
110
111
  private pumpRuns(): void {
111
112
  const process = this.process;
112
- if (this.closed || this.runs.active || !process || process.isRetiring) return;
113
+ if (this.closed || this.runs.active || !process || process.isRetiring || !this.processReady) return;
113
114
  const run = this.runs.startNext(performance.now());
114
115
  if (!run) return;
115
116
  const timeoutMs = run.input.timeoutMs;
@@ -142,6 +143,7 @@ export class SubprocessKernel {
142
143
  },
143
144
  });
144
145
  this.process = process;
146
+ this.processReady = false;
145
147
  try {
146
148
  process.send(
147
149
  encodeBridgeFrame({ type: "init", sessionId: this.options.sessionId, connection: this.options.connection }),
@@ -165,6 +167,17 @@ export class SubprocessKernel {
165
167
 
166
168
  private handleMessage(process: SubprocessProcess, message: KernelToHostMessage): void {
167
169
  if (!this.accepts(process)) return;
170
+ if (message.type === "ready") {
171
+ this.processReady = true;
172
+ this.runs.handleMessage(message, this.onMessage);
173
+ this.pumpRuns();
174
+ return;
175
+ }
176
+ if (message.type === "init-failed") {
177
+ this.runs.handleMessage(message, this.onMessage);
178
+ this.failClosed(new KernelStartupError(message.error.message));
179
+ return;
180
+ }
168
181
  if (this.runs.handleMessage(message, this.onMessage)) this.pumpRuns();
169
182
  }
170
183
 
@@ -176,6 +189,7 @@ export class SubprocessKernel {
176
189
  return;
177
190
  }
178
191
  this.process = null;
192
+ this.processReady = false;
179
193
  this.failClosed(new KernelExitedError(signal ?? code ?? "unknown"));
180
194
  }
181
195