@code-yeongyu/senpi-codemode 2026.9.17 → 2026.9.18

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,56 @@
12
12
 
13
13
  ### Removed
14
14
 
15
+ ## [2026.9.18] - 2026-09-18
16
+
17
+ ### Breaking Changes
18
+
19
+ ### Added
20
+
21
+ ### Changed
22
+
23
+ ### Fixed
24
+
25
+ ### Removed
26
+
27
+ ## [2026.9.17-4] - 2026-09-17
28
+
29
+ ### Breaking Changes
30
+
31
+ ### Added
32
+
33
+ ### Changed
34
+
35
+ ### Fixed
36
+
37
+ ### Removed
38
+
39
+ ## [2026.9.17-3] - 2026-09-17
40
+
41
+ ### Breaking Changes
42
+
43
+ ### Added
44
+
45
+ ### Changed
46
+
47
+ ### Fixed
48
+
49
+ ### Removed
50
+
51
+ ## [2026.9.17-2] - 2026-09-17
52
+
53
+ ### Breaking Changes
54
+
55
+ ### Added
56
+
57
+ ### Changed
58
+
59
+ ### Fixed
60
+
61
+ - JS eval kernel: a cell whose top-level declaration (`const`/`let`/`var`, plain or destructured) names an existing platform or prelude global (for example `const fetch = ...`) is now rejected before execution with an error naming the identifier and the rename remedy, instead of silently replacing that global for every later cell and wedging the session until a kernel reset. Cell-created globals stay re-declarable across cells, and explicit `globalThis.<name> = ...` assignments remain untouched as the deliberate escape hatch. (#1784)
62
+
63
+ ### Removed
64
+
15
65
  ## [2026.9.17] - 2026-09-17
16
66
 
17
67
  ### Breaking Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-yeongyu/senpi-codemode",
3
- "version": "2026.9.17",
3
+ "version": "2026.9.18",
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.17",
33
+ "@earendil-works/pi-ai": "npm:@code-yeongyu/senpi-ai@2026.9.18",
34
34
  "typebox": "1.3.27"
35
35
  },
36
36
  "peerDependencies": {
37
- "@code-yeongyu/senpi": "2026.9.17"
37
+ "@code-yeongyu/senpi": "2026.9.18"
38
38
  },
39
39
  "devDependencies": {
40
- "@code-yeongyu/senpi": "2026.9.17"
40
+ "@code-yeongyu/senpi": "2026.9.18"
41
41
  },
42
42
  "keywords": [
43
43
  "senpi",
@@ -1,3 +1,5 @@
1
+ import { findShadowedGlobalName } from "./worker-shadow-guard.js";
2
+
1
3
  export function indirectEval(source, filename) {
2
4
  const withPragma = filename ? `${source}\n//# sourceURL=${filename}` : source;
3
5
  const geval = globalThis.eval;
@@ -265,6 +267,12 @@ function rewriteDeclaration(code, declarationStart, start, end, keyword) {
265
267
  const bindings = [];
266
268
  collectPatternNames(pattern, bindings);
267
269
  if (bindings.length === 0) return undefined;
270
+ const shadowed = findShadowedGlobalName(bindings);
271
+ if (shadowed !== undefined) {
272
+ throw new Error(
273
+ `eval cell declares top-level \`${shadowed}\`, but a global with that name already exists in the JS kernel. Persisting it would replace that global for every later cell. Rename the binding (for example \`${shadowed}Local\`), or assign globalThis.${shadowed} explicitly if replacing it is truly intended.`,
274
+ );
275
+ }
268
276
  if (preserveDeclaration) {
269
277
  for (const name of bindings) assignments.push(`globalThis[${JSON.stringify(name)}] = ${name};`);
270
278
  continue;
@@ -0,0 +1,21 @@
1
+ // Snapshot is lazy on purpose: the first guard call is the first cell's
2
+ // transform, when prelude globals exist but no cell-created global does.
3
+ // A module-level snapshot would miss prelude globals; re-snapshotting later
4
+ // would wrongly protect cell-created names that must stay re-declarable.
5
+
6
+ let protectedGlobalNames;
7
+
8
+ function protectedGlobals() {
9
+ if (protectedGlobalNames === undefined) {
10
+ protectedGlobalNames = new Set(Object.getOwnPropertyNames(globalThis));
11
+ }
12
+ return protectedGlobalNames;
13
+ }
14
+
15
+ export function findShadowedGlobalName(bindings) {
16
+ const names = protectedGlobals();
17
+ for (const name of bindings) {
18
+ if (names.has(name)) return name;
19
+ }
20
+ return undefined;
21
+ }