better-dsh 0.0.0 → 0.2.3

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 (142) hide show
  1. package/LICENSE +24 -0
  2. package/README.md +294 -4
  3. package/control-prompt.md +37 -0
  4. package/cordis.patch.yml +53 -0
  5. package/docs/00_adr/0001-bridge-tool-layer-not-service-layer.md +14 -0
  6. package/docs/00_adr/0002-masking-is-presentation-only.md +15 -0
  7. package/docs/10_plans/A2A-messaging-channel-test-archive.md +256 -0
  8. package/docs/10_plans/code-mode-vs-rlm-ipython-comparison.md +137 -0
  9. package/docs/10_plans/dashr-blueprint-review.md +201 -0
  10. package/docs/10_plans/dashr-blueprint.md +561 -0
  11. package/docs/10_plans/dashr-compaction-window-and-archive.md +307 -0
  12. package/docs/10_plans/dashr-profile-layer-feasibility.md +367 -0
  13. package/docs/10_plans/dashr-sandbox-escalation-semantics-gap.md +171 -0
  14. package/docs/10_plans/dashr-security-sandbox-analysis.md +187 -0
  15. package/docs/10_plans/dashr-surface-invariant-and-omp-imports.md +97 -0
  16. package/docs/10_plans/ipython-kernel-interactive-interface-test-report.md +152 -0
  17. package/docs/10_plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +146 -0
  18. package/docs/10_plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +50 -0
  19. package/docs/10_plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +79 -0
  20. package/docs/10_plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +138 -0
  21. package/docs/10_plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +161 -0
  22. package/docs/10_plans/kernel-refactoring/V0.1.5-development-plan.md +109 -0
  23. package/docs/10_plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +50 -0
  24. package/docs/10_plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +113 -0
  25. package/docs/10_plans/recallable-compaction.md +147 -0
  26. package/docs/10_plans/spike-tag-repro.mjs +102 -0
  27. package/docs/10_plans/upstream-analysis.md +128 -0
  28. package/docs/50_test-reports/REPL-/345/267/245/345/205/267/350/260/203/347/224/250-/346/210/252/346/226/255/350/257/212/346/226/255.md +110 -0
  29. package/docs/50_test-reports/kernel-provisioning.md +44 -0
  30. package/docs/50_test-reports/repl-kernel-provisioning-test-report.md +87 -0
  31. package/docs/50_test-reports/upstream-dsh-0.1.2-alpha.5-local-test-report.md +81 -0
  32. package/docs/50_test-reports/upstream-dsh-0.1.2-alpha.5-report.md +93 -0
  33. package/docs/50_test-reports/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +142 -0
  34. package/docs/50_test-reports/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +193 -0
  35. package/docs/50_test-reports/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +96 -0
  36. package/docs/50_test-reports/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +127 -0
  37. package/docs/50_test-reports/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +150 -0
  38. package/docs/50_test-reports/v0.1.8d_artifacts/README.md +138 -0
  39. package/docs/50_test-reports/v0.1.8d_artifacts/code-mode-repl-only.observation.md +74 -0
  40. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +3890 -0
  41. package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +544 -0
  42. package/docs/50_test-reports/v0.1.8d_artifacts/functions.json +592 -0
  43. package/docs/50_test-reports/v0.1.8d_artifacts/skills-catalog.snapshot.md +30 -0
  44. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.output-schemas.json +1236 -0
  45. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.python.txt +592 -0
  46. package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.typescript.txt +516 -0
  47. package/docs/50_test-reports/v0.1.8d_artifacts/wire-vs-transcription.diff.md +54 -0
  48. package/docs/50_test-reports/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +224 -0
  49. package/docs/50_test-reports/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +168 -0
  50. package/docs/50_test-reports/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +123 -0
  51. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.lock +7 -0
  52. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.toml +6 -0
  53. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +8 -0
  54. package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/main.rs +4 -0
  55. package/docs/50_test-reports/v0.2.0b_artifacts/hashline-probe.md +5 -0
  56. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.lock +7 -0
  57. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.toml +7 -0
  58. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/build.rs +4 -0
  59. package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/src/main.rs +13 -0
  60. package/docs/50_test-reports/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +110 -0
  61. package/docs/50_test-reports/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +86 -0
  62. package/docs/50_test-reports/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +66 -0
  63. package/docs/50_test-reports/v0.2.1d-/345/256/236/346/265/213/346/212/245/345/221/212.md +67 -0
  64. package/docs/50_test-reports/v0.2.1e-P1-/345/256/236/346/265/213/346/212/245/345/221/212.md +136 -0
  65. package/docs/50_test-reports/v0.2.1ef-dev-audit-report.md +73 -0
  66. package/docs/50_test-reports/v0.2.1f-plugin-shipped-ui-patches/345/256/236/346/265/213/346/212/245/345/221/212.md +102 -0
  67. package/docs/60_exploration-and-research/cordis-research.md +350 -0
  68. package/docs/60_exploration-and-research/dsh-web-profile-package-map.md +186 -0
  69. package/docs/60_exploration-and-research/dsh-web-ui-slot-system-research.md +310 -0
  70. package/docs/60_exploration-and-research/dsh-webui-strip-boundary-research.md +300 -0
  71. package/docs/60_exploration-and-research/ios-chat-app-bridge-research.md +324 -0
  72. package/docs/60_exploration-and-research/web-frontend-composability-research.md +191 -0
  73. package/docs/REPL-/345/267/245/345/205/267/350/260/203/347/224/250-/346/210/252/346/226/255/350/257/212/346/226/255.md +110 -0
  74. package/docs/adr/0001-bridge-tool-layer-not-service-layer.md +14 -0
  75. package/docs/adr/0002-masking-is-presentation-only.md +15 -0
  76. package/docs/distro-blueprint.md +81 -0
  77. package/docs/dsh-webUI-with-rlm-mode.png +0 -0
  78. package/docs/plans/A2A-messaging-channel-test-archive.md +256 -0
  79. package/docs/plans/code-mode-vs-rlm-ipython-comparison.md +137 -0
  80. package/docs/plans/dashr-blueprint-review.md +201 -0
  81. package/docs/plans/dashr-blueprint.md +561 -0
  82. package/docs/plans/dashr-compaction-window-and-archive.md +307 -0
  83. package/docs/plans/dashr-profile-layer-feasibility.md +367 -0
  84. package/docs/plans/dashr-sandbox-escalation-semantics-gap.md +171 -0
  85. package/docs/plans/dashr-security-sandbox-analysis.md +187 -0
  86. package/docs/plans/dashr-surface-invariant-and-omp-imports.md +97 -0
  87. package/docs/plans/ipython-kernel-interactive-interface-test-report.md +152 -0
  88. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +146 -0
  89. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +50 -0
  90. package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +79 -0
  91. package/docs/plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +138 -0
  92. package/docs/plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +161 -0
  93. package/docs/plans/kernel-refactoring/V0.1.5-development-plan.md +109 -0
  94. package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +50 -0
  95. package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +113 -0
  96. package/docs/plans/recallable-compaction.md +147 -0
  97. package/docs/plans/spike-tag-repro.mjs +102 -0
  98. package/docs/plans/upstream-analysis.md +128 -0
  99. package/docs/repositioning-and-rebranding.md +102 -0
  100. package/docs/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +142 -0
  101. package/docs/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +193 -0
  102. package/docs/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +96 -0
  103. package/docs/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +127 -0
  104. package/docs/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +150 -0
  105. package/docs/v0.1.8d_artifacts/README.md +138 -0
  106. package/docs/v0.1.8d_artifacts/code-mode-repl-only.observation.md +74 -0
  107. package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +3890 -0
  108. package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +544 -0
  109. package/docs/v0.1.8d_artifacts/functions.json +592 -0
  110. package/docs/v0.1.8d_artifacts/skills-catalog.snapshot.md +30 -0
  111. package/docs/v0.1.8d_artifacts/tools-sdk.output-schemas.json +1236 -0
  112. package/docs/v0.1.8d_artifacts/tools-sdk.python.txt +592 -0
  113. package/docs/v0.1.8d_artifacts/tools-sdk.typescript.txt +516 -0
  114. package/docs/v0.1.8d_artifacts/wire-vs-transcription.diff.md +54 -0
  115. package/docs/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +224 -0
  116. package/docs/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +168 -0
  117. package/docs/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +123 -0
  118. package/docs/v0.2.0b_artifacts/f2probe/Cargo.lock +7 -0
  119. package/docs/v0.2.0b_artifacts/f2probe/Cargo.toml +6 -0
  120. package/docs/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +8 -0
  121. package/docs/v0.2.0b_artifacts/f2probe/src/main.rs +4 -0
  122. package/docs/v0.2.0b_artifacts/hashline-probe.md +5 -0
  123. package/docs/v0.2.0b_artifacts/slowprobe/Cargo.lock +7 -0
  124. package/docs/v0.2.0b_artifacts/slowprobe/Cargo.toml +7 -0
  125. package/docs/v0.2.0b_artifacts/slowprobe/build.rs +4 -0
  126. package/docs/v0.2.0b_artifacts/slowprobe/src/main.rs +13 -0
  127. package/docs/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +110 -0
  128. package/docs/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +86 -0
  129. package/docs/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +66 -0
  130. package/lib/client/index.js +473 -0
  131. package/lib/index.d.ts +736 -0
  132. package/lib/index.js +11518 -0
  133. package/lib/kernel-env-hxaihi9C.js +195 -0
  134. package/lib/kernel-env.d.ts +80 -0
  135. package/lib/kernel-env.js +3 -0
  136. package/lib/py-sdk-BCaOGYz7.d.ts +125 -0
  137. package/lib/py-sdk-CbgYiX8O.js +691 -0
  138. package/lib/py-sdk.d.ts +2 -0
  139. package/lib/py-sdk.js +3 -0
  140. package/package.json +325 -4
  141. package/scripts/kernel-provision.mjs +35 -0
  142. package/index.js +0 -3
@@ -0,0 +1,691 @@
1
+ import { Context, Service } from "@deepseek-ai/cordis";
2
+ import { assertSupportedJsonSchema } from "@deepseek-ai/dsh-tools";
3
+
4
+ //#region src/vendored/repl-runtime.ts
5
+ /**
6
+ * Binding globals EVERY backend refuses because SOME backend owns the slot in
7
+ * the program's namespace: `console` (the worker's log capture), and
8
+ * `__dsh_main__`/`__builtins__`/`__name__` (the Python backend's bootstrap
9
+ * wrapper and seeded module globals; see upstream's Agent Note
10
+ * `2026-07-31-code-runtime-portable-identifier-seam.md` in the dsh monorepo),
11
+ * and `__debug__`. One shared set — rather than each backend refusing only its
12
+ * own slots — keeps the portability promise real: a namespace list valid on
13
+ * one backend is valid on all, so a caller cannot pick a name that works on
14
+ * the worker and collides on Python (or vice versa). `__name__` et al. ARE
15
+ * valid portable identifiers, so the identifier rule on
16
+ * `CodeBindingNamespace.global` never rejects them — hence this explicit set.
17
+ * (Error members differ: {@link DUNDER_MEMBER} refuses every dunder form
18
+ * wholesale; binding globals refuse only the names listed here.) `__debug__`
19
+ * is listed for a different reason than a collision: CPython compiles a bare
20
+ * `__debug__` reference to the constant `True` and rejects any assignment to
21
+ * the name at COMPILE time, so an injected global under that name is
22
+ * unreachable from the program — accepted by validation, unusable on the
23
+ * Python backend, which is exactly the split the shared set exists to prevent.
24
+ */
25
+ const RESERVED_BINDING_GLOBALS = new Set([
26
+ "console",
27
+ "__dsh_main__",
28
+ "__builtins__",
29
+ "__name__",
30
+ "__debug__"
31
+ ]);
32
+ /**
33
+ * `CodeBindingErrorClass.memberNameProperty` names EVERY backend refuses, as
34
+ * one shared contract so a request valid on one backend is valid on all. The
35
+ * JS `Error` exclusions (`name`, `message`, `stack`) and Python's
36
+ * exception-protocol members (`args`, `with_traceback`, `add_note`) are
37
+ * listed by name; dunder-form names (`__x__`, non-empty middle) are refused
38
+ * wholesale — several are constrained CPython descriptors whose `setattr`
39
+ * raises while constructing the rejection, and the exact set is an interpreter
40
+ * version detail. Any other non-empty own property name is accepted everywhere.
41
+ */
42
+ const RESERVED_ERROR_MEMBERS = new Set([
43
+ "name",
44
+ "message",
45
+ "stack",
46
+ "args",
47
+ "with_traceback",
48
+ "add_note"
49
+ ]);
50
+ /**
51
+ * Dunder form (`__x__`, non-empty middle): object-protocol slots in Python,
52
+ * refused as {@link RESERVED_ERROR_MEMBERS | error members} on every backend.
53
+ */
54
+ const DUNDER_MEMBER = /^__.+__$/;
55
+ /**
56
+ * Reserved words of every portable target language (ECMAScript ∪ Python),
57
+ * refused as {@link CodeBindingNamespace.global} / error-class names by all
58
+ * backends. Python is a portability target here even though only the
59
+ * TypeScript worker has a published backend. The portable-identifier contract
60
+ * promises a namespace list valid on one backend is valid on every backend; a
61
+ * per-language check would let `lambda` pass the TypeScript backend and fail
62
+ * the Python one. Extending the seam with a new language means widening this
63
+ * union (a breaking review of existing binding names, by design).
64
+ */
65
+ const PORTABLE_RESERVED_WORDS = new Set([
66
+ "await",
67
+ "break",
68
+ "case",
69
+ "catch",
70
+ "class",
71
+ "const",
72
+ "continue",
73
+ "debugger",
74
+ "default",
75
+ "delete",
76
+ "do",
77
+ "else",
78
+ "enum",
79
+ "export",
80
+ "extends",
81
+ "false",
82
+ "finally",
83
+ "for",
84
+ "function",
85
+ "if",
86
+ "import",
87
+ "in",
88
+ "instanceof",
89
+ "new",
90
+ "null",
91
+ "return",
92
+ "super",
93
+ "switch",
94
+ "this",
95
+ "throw",
96
+ "true",
97
+ "try",
98
+ "typeof",
99
+ "var",
100
+ "void",
101
+ "while",
102
+ "with",
103
+ "yield",
104
+ "let",
105
+ "static",
106
+ "implements",
107
+ "interface",
108
+ "package",
109
+ "private",
110
+ "protected",
111
+ "public",
112
+ "arguments",
113
+ "eval",
114
+ "False",
115
+ "None",
116
+ "True",
117
+ "and",
118
+ "as",
119
+ "assert",
120
+ "async",
121
+ "def",
122
+ "del",
123
+ "elif",
124
+ "except",
125
+ "from",
126
+ "global",
127
+ "is",
128
+ "lambda",
129
+ "nonlocal",
130
+ "not",
131
+ "or",
132
+ "pass",
133
+ "raise",
134
+ "match",
135
+ "type",
136
+ "_"
137
+ ]);
138
+ /**
139
+ * Registers one `ctx.replRuntime` implementation. Program, budget, abort, and substrate
140
+ * failures resolve in {@link CodeRunResult}; only Service Definition contract misuse rejects. Implementations bridge
141
+ * structured-cloneable bindings, materialize each declared namespace rejection
142
+ * class, treat programs as hostile peers — budget, interrupt, and substrate
143
+ * semantics apply per program and are unchanged by this seam's statefulness —
144
+ * share one persistent per-session user namespace across runs (state
145
+ * codification across runs IS the product; this replaces upstream's
146
+ * isolate-runs-from-one-another clause), and terminate and await in-flight
147
+ * runs during disposal.
148
+ */
149
+ var ReplRuntime = class extends Service {
150
+ constructor(ctx) {
151
+ super(ctx, "replRuntime");
152
+ }
153
+ };
154
+
155
+ //#endregion
156
+ //#region src/py-sdk.ts
157
+ /**
158
+ * The reference grammar's `xid_start xid_continue*` — the set
159
+ * `str.isidentifier()` accepts on a CPython whose Unicode tables match the
160
+ * engine's. See {@link isBareIdentifier} for the version-skew stance.
161
+ */
162
+ const IDENTIFIER = /^[\p{XID_Start}_]\p{XID_Continue}*$/u;
163
+ /**
164
+ * Whether a name can be emitted as a bare Python identifier rather than
165
+ * routed to the subscript/`dict[str, Any]` path. Two conditions, both
166
+ * ported from upstream `py-types.ts`:
167
+ *
168
+ * 1. `IDENTIFIER` matches — Python identifiers are not ASCII (`路径` is a
169
+ * legal field name), and rejecting such a name would degrade the whole
170
+ * enclosing object, dropping every field's name, requiredness, and type.
171
+ * 2. NFKC stability (`name.normalize('NFKC') === name`) — CPython normalizes
172
+ * identifiers at compile time while JSON keys are compared as written, so
173
+ * an unstable name (`field`) would be advertised under a spelling the
174
+ * harness never accepts.
175
+ *
176
+ * Both conditions are evaluated against the ENGINE's tables; a CPython older
177
+ * than the engine could reject a character this accepts (the dangerous
178
+ * direction — the tokenizer refuses the character and the whole SDK block
179
+ * goes down). DASHR targets the kernel venv shipped with the runtime
180
+ * (`npm run kernel:venv`, Python 3.11), which tracks modern CPython; the
181
+ * residual skew is accepted rather than carrying upstream's deferred
182
+ * target-interpreter-version plumbing.
183
+ */
184
+ function isBareIdentifier(name) {
185
+ return IDENTIFIER.test(name) && name.normalize("NFKC") === name;
186
+ }
187
+ /**
188
+ * Python hard keywords: reserved everywhere, so a tool or field named
189
+ * `class` or `lambda` is legal on the wire but not as a def name and not
190
+ * as a class-syntax `TypedDict` field. Such FIELDS make the enclosing
191
+ * object degrade to `dict[str, Any]`; tool NAME reserving additionally
192
+ * follows the portable seam set (see {@link isFlatBindableName}), which is
193
+ * narrower than Python alone. Soft keywords (`match`, `case`, `type`,
194
+ * `_`) are deliberately absent from this FIELD set (each is special in
195
+ * exactly one syntactic position); `__debug__` joins as a compile-time
196
+ * assignment refusal. Ported near-verbatim from upstream.
197
+ */
198
+ const RESERVED = new Set([
199
+ "False",
200
+ "None",
201
+ "True",
202
+ "and",
203
+ "as",
204
+ "assert",
205
+ "async",
206
+ "await",
207
+ "break",
208
+ "class",
209
+ "continue",
210
+ "def",
211
+ "del",
212
+ "elif",
213
+ "else",
214
+ "except",
215
+ "finally",
216
+ "for",
217
+ "from",
218
+ "global",
219
+ "if",
220
+ "import",
221
+ "in",
222
+ "is",
223
+ "lambda",
224
+ "nonlocal",
225
+ "not",
226
+ "or",
227
+ "pass",
228
+ "raise",
229
+ "return",
230
+ "try",
231
+ "while",
232
+ "with",
233
+ "yield",
234
+ "__debug__"
235
+ ]);
236
+ /** The language-portable identifier subset the seam accepts as a binding global (mirrors the runtime's private rule). */
237
+ const PORTABLE_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
238
+ /** `typing` symbols this module may emit, in the deterministic import order. */
239
+ const TYPING_ORDER = [
240
+ "Any",
241
+ "Literal",
242
+ "NotRequired",
243
+ "TypedDict"
244
+ ];
245
+ /** `indent`-deep line prefix (four spaces per level, PEP 8). */
246
+ function pad(indent) {
247
+ return " ".repeat(indent);
248
+ }
249
+ /**
250
+ * The `Cc` code points with no printable form (C0, DEL, C1): CPython rejects
251
+ * NUL anywhere in source and the rest are invisible, so one `\xNN` escape
252
+ * form (covering U+0000–U+00FF exactly) keeps the SDK parseable and readable.
253
+ * Ported from upstream.
254
+ */
255
+ const UNPRINTABLE = /[\u0000-\u0008\u000e-\u001f\u007f-\u009f]/g;
256
+ /**
257
+ * Unpaired surrogate code points, escaped as `\uNNNN`: Python source must be
258
+ * UTF-8-encodable and a lone surrogate is not, so `compile()` raises for one
259
+ * anywhere in the text. Reachable from a wire description carrying `"\ud800"`.
260
+ */
261
+ const LONE_SURROGATE = /[\ud800-\udfff]/gu;
262
+ /**
263
+ * The collapsed one-line `description` of a schema node, or `undefined` when
264
+ * the node carries none that survives collapsing. Control characters left
265
+ * after the whitespace collapse render as `\xNN` / `\uNNNN` escapes so the
266
+ * emitted block stays valid Python.
267
+ */
268
+ function describe(schema) {
269
+ const description = schema.description;
270
+ if (typeof description !== "string") return void 0;
271
+ const collapsed = description.replace(/\s+/g, " ").replace(UNPRINTABLE, (char) => `\\x${char.charCodeAt(0).toString(16).padStart(2, "0")}`).replace(LONE_SURROGATE, (char) => `\\u${char.charCodeAt(0).toString(16).padStart(4, "0")}`).trim();
272
+ return collapsed.length === 0 ? void 0 : collapsed;
273
+ }
274
+ /**
275
+ * CamelCase a name into a Python type identifier: non-identifier characters
276
+ * and `_` split words, a head that cannot start an identifier takes a
277
+ * `Tool` prefix, and the result is NFKC-normalized so what CPython compiles
278
+ * is identical to what is emitted. Ported from upstream.
279
+ */
280
+ function camelCase(raw) {
281
+ const joined = raw.split(/[^\p{XID_Continue}]+|_+/u).filter((part) => part.length > 0).map((part) => `${part.charAt(0).toUpperCase()}${part.slice(1)}`).join("").normalize("NFKC");
282
+ return (/^\p{XID_Start}/u.test(joined) ? joined : `Tool${joined}`).normalize("NFKC");
283
+ }
284
+ /** Class-name base cap keeping each emitted name — and total text — linear in schema depth. */
285
+ const MAX_CLASS_NAME_BASE = 120;
286
+ /**
287
+ * Deepest `list[…]` nesting emitted into one annotation before the item type
288
+ * degrades to `Any`: CPython's tokenizer rejects more than 200 simultaneously
289
+ * open brackets, and an array chain deeper than this would render an SDK block
290
+ * that is not valid Python at all.
291
+ */
292
+ const MAX_LIST_NESTING = 180;
293
+ /**
294
+ * Cap a class-name base at {@link MAX_CLASS_NAME_BASE}. `slice` counts UTF-16
295
+ * code units, so an astral character straddling the boundary would leave a
296
+ * lone surrogate; drop it rather than emit it.
297
+ */
298
+ function capClassNameBase(base) {
299
+ if (base.length <= MAX_CLASS_NAME_BASE) return base;
300
+ const capped = base.slice(0, MAX_CLASS_NAME_BASE);
301
+ return /[\uD800-\uDBFF]$/.test(capped) ? capped.slice(0, -1) : capped;
302
+ }
303
+ /**
304
+ * Reserve a unique class name from a base, suffixing `2`, `3`, … on
305
+ * collision; the per-base counter keeps a deep chain sharing one capped base
306
+ * amortized O(1) instead of rescanning from `2`.
307
+ */
308
+ function allocateClassName(base, state) {
309
+ const capped = capClassNameBase(base);
310
+ let name = capped;
311
+ if (state.usedClassNames.has(name)) {
312
+ let n = state.nextClassCounter.get(capped) ?? 2;
313
+ while (state.usedClassNames.has(`${capped}${n}`)) n++;
314
+ name = `${capped}${n}`;
315
+ state.nextClassCounter.set(capped, n + 1);
316
+ }
317
+ state.usedClassNames.add(name);
318
+ return name;
319
+ }
320
+ /**
321
+ * Append a child-name segment to a parent class-name base, capping at
322
+ * propagation so each level stays O(1) and normalizing the join (Hangul jamo
323
+ * composition at the seam) so the emitted name is the symbol CPython sees.
324
+ */
325
+ function childClassName(base, segment) {
326
+ return capClassNameBase(`${base}${segment}`.normalize("NFKC"));
327
+ }
328
+ /**
329
+ * Render one validated scalar as Python literal text. A beyond-safe-range
330
+ * integer takes `BigInt` digits — Python integers are arbitrary-precision,
331
+ * and `String`'s shortest-round-trip padding can name an integer no double
332
+ * holds. `JSON.stringify` for strings is what keeps the literal parseable
333
+ * (its escapes are Python escapes too; ES2019 well-formedness covers
334
+ * surrogates).
335
+ */
336
+ function pyScalar(value) {
337
+ if (value === true) return "True";
338
+ if (value === false) return "False";
339
+ if (typeof value === "string") return JSON.stringify(value);
340
+ if (typeof value === "number" && Number.isInteger(value) && !Number.isSafeInteger(value)) return BigInt(value).toString();
341
+ return String(value);
342
+ }
343
+ /** Render a validated scalar `const`/`enum` as `Literal[...]`, else the broad type. */
344
+ function renderConstrainedScalar(node, broad, state) {
345
+ if (node.const !== void 0) {
346
+ state.typing.add("Literal");
347
+ return `Literal[${pyScalar(node.const)}]`;
348
+ }
349
+ if (node.enum !== void 0) {
350
+ state.typing.add("Literal");
351
+ return `Literal[${node.enum.map(pyScalar).join(", ")}]`;
352
+ }
353
+ return broad;
354
+ }
355
+ /**
356
+ * Map one JSON-Schema node to a Python type expression, threading `state`
357
+ * for the `TypedDict` declarations and `typing` symbols a full render needs.
358
+ * Iterative explicit-stack walk (ported): a hostile 5 000-deep schema must
359
+ * not blow the host stack, and class declarations must precede the parent
360
+ * that references them. An unsupported or malformed schema degrades to `Any`
361
+ * without throwing — the stub is advisory prompt text, only required to
362
+ * parse — exactly as upstream treats schemas trusted-after-validation.
363
+ */
364
+ function renderType(schema, className, state) {
365
+ const newFrame = (schema$1, className$1, listDepth) => ({
366
+ schema: schema$1,
367
+ className: className$1,
368
+ phase: "start",
369
+ listDepth,
370
+ children: [],
371
+ childIndex: 0,
372
+ childTypes: [],
373
+ entries: []
374
+ });
375
+ try {
376
+ assertSupportedJsonSchema(schema);
377
+ const frames = [newFrame(schema, className, 0)];
378
+ let result;
379
+ const finish = (type) => {
380
+ frames.pop();
381
+ const parent = frames.at(-1);
382
+ if (parent === void 0) result = type;
383
+ else parent.childTypes.push(type);
384
+ };
385
+ while (frames.length > 0) {
386
+ const frame = frames.at(-1);
387
+ if (frame === void 0) break;
388
+ if (frame.phase === "children") {
389
+ if (frame.childIndex < frame.children.length) {
390
+ const child = frame.children[frame.childIndex];
391
+ if (child === void 0) throw new Error("dashr-repl: missing python render child");
392
+ frame.childIndex++;
393
+ frames.push(newFrame(child.schema, child.className, child.listDepth));
394
+ continue;
395
+ }
396
+ if (frame.kind === "oneOf") {
397
+ let union = "";
398
+ for (const [index, childType] of frame.childTypes.entries()) union = index === 0 ? childType : `${union} | ${childType}`;
399
+ finish(union);
400
+ continue;
401
+ }
402
+ if (frame.kind === "array") {
403
+ finish(`list[${frame.childTypes[0] ?? "Any"}]`);
404
+ continue;
405
+ }
406
+ const node$1 = frame.node;
407
+ const name = frame.allocated;
408
+ if (node$1 === void 0 || name === void 0) throw new Error("dashr-repl: missing typeddict frame state");
409
+ const required = new Set(node$1.required);
410
+ const lines = [`class ${name}(TypedDict):`];
411
+ for (let index = 0; index < frame.entries.length; index++) {
412
+ const entry = frame.entries[index];
413
+ const fieldType = frame.childTypes[index];
414
+ if (entry === void 0 || fieldType === void 0) throw new Error("dashr-repl: missing typeddict field type");
415
+ const [field, fieldSchema] = entry;
416
+ const description = describe(fieldSchema);
417
+ if (description !== void 0) lines.push(`${pad(1)}# ${description}`);
418
+ if (required.has(field)) lines.push(`${pad(1)}${field}: ${fieldType}`);
419
+ else {
420
+ state.typing.add("NotRequired");
421
+ lines.push(`${pad(1)}${field}: NotRequired[${fieldType}]`);
422
+ }
423
+ }
424
+ if (node$1.additionalProperties !== false) lines.push(`${pad(1)}# Additional keys beyond those declared are allowed.`);
425
+ if (lines.length === 1) lines.push(`${pad(1)}pass`);
426
+ state.classes.push(lines.join("\n"));
427
+ finish(name);
428
+ continue;
429
+ }
430
+ frame.phase = "children";
431
+ const node = frame.schema;
432
+ if (node.oneOf !== void 0) {
433
+ frame.kind = "oneOf";
434
+ frame.children = node.oneOf.map((branch, index) => ({
435
+ schema: branch,
436
+ className: childClassName(frame.className, `${index + 1}`),
437
+ listDepth: frame.listDepth
438
+ }));
439
+ continue;
440
+ }
441
+ if (node.type === void 0) {
442
+ state.typing.add("Any");
443
+ finish("Any");
444
+ continue;
445
+ }
446
+ switch (node.type) {
447
+ case "string":
448
+ finish(renderConstrainedScalar(node, "str", state));
449
+ break;
450
+ case "number":
451
+ finish(renderConstrainedScalar(node, "float", state));
452
+ break;
453
+ case "integer":
454
+ finish(renderConstrainedScalar(node, "int", state));
455
+ break;
456
+ case "boolean":
457
+ finish(renderConstrainedScalar(node, "bool", state));
458
+ break;
459
+ case "null":
460
+ finish("None");
461
+ break;
462
+ case "array":
463
+ if (node.items === void 0) {
464
+ state.typing.add("Any");
465
+ finish("list[Any]");
466
+ break;
467
+ }
468
+ if (frame.listDepth >= MAX_LIST_NESTING) {
469
+ state.typing.add("Any");
470
+ finish("Any");
471
+ break;
472
+ }
473
+ frame.kind = "array";
474
+ frame.children = [{
475
+ schema: node.items,
476
+ className: frame.className,
477
+ listDepth: frame.listDepth + 1
478
+ }];
479
+ break;
480
+ case "object": {
481
+ const entries = Object.entries(node.properties ?? {});
482
+ if (!entries.every(([name]) => isBareIdentifier(name) && !RESERVED.has(name) && !(name.startsWith("__") && !name.endsWith("__")))) {
483
+ state.typing.add("Any");
484
+ finish("dict[str, Any]");
485
+ break;
486
+ }
487
+ if (entries.length === 0 && node.additionalProperties !== false) {
488
+ state.typing.add("Any");
489
+ finish("dict[str, Any]");
490
+ break;
491
+ }
492
+ frame.kind = "typeddict";
493
+ frame.node = node;
494
+ frame.allocated = allocateClassName(frame.className, state);
495
+ state.typing.add("TypedDict");
496
+ frame.entries = entries;
497
+ frame.children = entries.map(([field, child]) => ({
498
+ schema: child,
499
+ className: childClassName(frame.allocated ?? "", camelCase(field)),
500
+ listDepth: 1
501
+ }));
502
+ break;
503
+ }
504
+ default:
505
+ state.typing.add("Any");
506
+ finish("Any");
507
+ }
508
+ }
509
+ return result ?? "Any";
510
+ } catch {
511
+ state.typing.add("Any");
512
+ return "Any";
513
+ }
514
+ }
515
+ /**
516
+ * Whether a tool name can be emitted AND bound as a `tool` member — the ONE
517
+ * policy shared by this renderer and the bridge's binding
518
+ * loop (src/index.ts), so the catalog never promises a name the kernel does
519
+ * not bind. Strictly narrower than the runtime's validation: the
520
+ * language-portable identifier subset (`[A-Za-z_][A-Za-z0-9_]*`, ASCII — a
521
+ * non-ASCII XID name is legal CPython but not portable, so the runtime
522
+ * refuses it as a binding global and the catalog must not teach it), minus
523
+ * every portable reserved word (ECMAScript ∪ Python — `type` and `match`
524
+ * are legal Python but reserved on the seam), minus the seam's reserved
525
+ * binding globals (`console`, dunders), minus underscore-leading names
526
+ * (kernel-shim prefix plus the call-site hazards; not callable as taught
527
+ * flat globals). The runtime's `validateBindings` remains the authoritative
528
+ * backstop: everything this accepts, it accepts.
529
+ */
530
+ function isFlatBindableName(name) {
531
+ return PORTABLE_IDENTIFIER.test(name) && !name.startsWith("_") && !PORTABLE_RESERVED_WORDS.has(name) && !RESERVED_BINDING_GLOBALS.has(name);
532
+ }
533
+ /**
534
+ * The fixed model-facing usage contract rendered above the declarations —
535
+ * DASHR's OWN text (do not copy upstream `py-types.ts` SDK_INSTRUCTIONS: it
536
+ * promises one-shot program semantics, and our kernel is persistent).
537
+ *
538
+ * Every statement here must match what the `eval` transport actually
539
+ * enforces: cell semantics (variables survive across calls), top-level
540
+ * `await`/`return`, the completion-value contract (lossless JSON; explicit
541
+ * `return None` → null; no `return` → no value), the flat binding set
542
+ * (every tool function below plus `ToolCallError` — registry tools and
543
+ * bridge tools alike are one flat surface), the static-stub caveat
544
+ * for `TypedDict`s, and the sub-call concurrency contract implemented by
545
+ * the transport's scheduler (submission-ordered starts; only
546
+ * concurrency-safe tools overlap, up to the configured cap; exclusive
547
+ * tools run alone as barriers).
548
+ */
549
+ const SDK_INSTRUCTIONS = `## Writing cells for eval
550
+
551
+ \`eval\` takes two required arguments — \`cell\` (the Python program) and \`description\` (a short summary of what the cell does) — plus optional \`timeout\` (seconds, wall-clock budget) and \`reset\` (restart the kernel with an empty namespace). The cell runs on a PERSISTENT IPython kernel: variables, imports, and definitions created in any earlier \`eval\` call of this session are still alive in later ones (and in this one), so treat the kernel's namespace as your working memory. Top-level \`await\` works; a top-level \`return\` is a SyntaxError — the cell is module scope, exactly like a native IPython cell. At run time the bound names are \`ToolCallError\` and every tool function declared below. Everything else here is a STATIC STUB describing argument and return types — in particular the \`TypedDict\` classes do NOT exist at run time, so build arguments as plain \`dict\`/\`list\` JSON values: \`await tool.echo({"field": 1})\`, never \`EchoArgs(field=1)\`, which raises \`NameError\`. Inside a cell:
552
+
553
+ - Call tools as \`await tool.name(args)\` — the members of the \`tool\` object declared below. Every call resolves to the tool's typed canonical JSON value (each function's return type below). Tool arguments must be lossless JSON.
554
+ - A FAILED tool call raises \`ToolCallError\`, whose \`toolName\` identifies the failed tool and whose message is human-readable — wrap in \`try\`/\`except\` to handle and continue.
555
+ - Independent calls may overlap under \`asyncio.gather\`: cells dispatch sub-calls in submission order, and only tools marked safe to run side by side actually overlap (bounded by a cap); any other tool runs alone, waiting for overlapping calls to drain first. Sequence dependent work with plain \`await\`.
556
+ - Emit the answer with \`print(...)\`, or end the cell with a bare expression — its value becomes the cell's result, like a REPL. A value should be JSON-serializable — anything that isn't comes back as its repr text. A cell ending in a statement (or a \`None\` expression) yields no value. ONLY what you print and the final value come back — intermediate tool results never enter the conversation, so extract just what you need.
557
+
558
+ The available tools:`;
559
+ /**
560
+ * Render the `dashr:tool-catalog` prompt section body from the registry
561
+ * schemas: the cell-flavored usage instructions above, the
562
+ * `ToolCallError` declaration, one named `TypedDict` per tool argument or
563
+ * output object (and per nested object), and one
564
+ * `tool.<name>(args: XArgs) -> XOutput` member per visible tool — no `Tools`
565
+ * protocol, no `tools` singleton, every tool is a member of the `tool`
566
+ * object exactly as the kernel binds it — inside one fenced
567
+ * ```python block. The `typing` import line lists exactly the symbols the
568
+ * render used (and is omitted entirely when none are).
569
+ *
570
+ * Deterministic — tools are emitted in lexicographic name order and class
571
+ * declarations precede the function that references them in that same
572
+ * order (nested classes before the parent that references them), so an
573
+ * unchanged tool set produces byte-identical text across assemblies.
574
+ *
575
+ * Non-bindable names (reserved, exotic, or underscore-leading) render as
576
+ * comment lines: they are registered upstream but NOT callable from cells,
577
+ * and the comment keeps the signature and description visible instead of
578
+ * silently dropping the tool.
579
+ * @param schemas - the calling scope's visible tools (caller excludes
580
+ * `eval` and the masked delegation names).
581
+ * @returns the complete section body.
582
+ */
583
+ function renderToolsSdkPy(schemas) {
584
+ const sorted = [...schemas].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
585
+ const state = {
586
+ classes: [],
587
+ usedClassNames: /* @__PURE__ */ new Set(),
588
+ nextClassCounter: /* @__PURE__ */ new Map(),
589
+ typing: /* @__PURE__ */ new Set()
590
+ };
591
+ const defs = [];
592
+ for (const schema of sorted) {
593
+ const argType = renderType(schema.parameters, `${camelCase(schema.name)}Args`, state);
594
+ const outputType = renderType(schema.output, `${camelCase(schema.name)}Output`, state);
595
+ if (isFlatBindableName(schema.name)) {
596
+ const lines = [];
597
+ const description = describe(schema);
598
+ if (description !== void 0) lines.push(`# ${description}`);
599
+ lines.push(`tool.${schema.name}(args: ${argType}) -> ${outputType}`);
600
+ defs.push(lines.join("\n"));
601
+ } else {
602
+ defs.push(`# ${JSON.stringify(schema.name)}: registered but NOT callable from cells (its name is not a usable member name) — (args: ${argType}) -> ${outputType}`);
603
+ const description = describe(schema);
604
+ if (description !== void 0) defs.push(`# ${description}`);
605
+ }
606
+ }
607
+ const imports = TYPING_ORDER.filter((symbol) => state.typing.has(symbol));
608
+ return `${SDK_INSTRUCTIONS}\n\n\`\`\`python\n${`${imports.length > 0 ? `from typing import ${imports.join(", ")}\n\n` : ""}class ToolCallError(Exception):
609
+ toolName: str\n\n${state.classes.length > 0 ? `${state.classes.join("\n\n")}\n\n` : ""}${defs.join("\n\n")}`}\n\`\`\``;
610
+ }
611
+ /** The deployed presentation mode; flip to `'convention'` to ship arm A. */
612
+ const REPL_BRIDGE_CATALOG_MODE = "signatures";
613
+ /** Abbreviation depth for the compact sketches: root, children, grandchildren; deeper degrades to `Any`. */
614
+ const COMPACT_SKETCH_DEPTH = 2;
615
+ /**
616
+ * Render one JSON-Schema node as a compact Python-flavored shape sketch:
617
+ * scalar names map to Python (`str`/`int`/`float`/`bool`), objects render
618
+ * as the dict literal the call actually takes (`{'path': str, 'offset'?: int}` —
619
+ * `?` marks optional keys), string enums render as quoted unions, arrays as
620
+ * `list[…]`. Nodes deeper than {@link COMPACT_SKETCH_DEPTH}, and anything
621
+ * malformed or unsupported, degrade to `Any` — the sketch is advisory
622
+ * prompt text, mirroring the omp `tsType` simplification (depth-capped,
623
+ * never throwing) rather than the full TypedDict codegen above.
624
+ */
625
+ function compactSketch(schema, depth) {
626
+ if (schema === null || typeof schema !== "object" || depth > COMPACT_SKETCH_DEPTH) return "Any";
627
+ const node = schema;
628
+ if (Array.isArray(node.enum) && node.enum.length > 0 && node.enum.every((value) => typeof value === "string")) return node.enum.map((value) => `'${value.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'`).join(" | ");
629
+ switch (node.type) {
630
+ case "string": return "str";
631
+ case "integer": return "int";
632
+ case "number": return "float";
633
+ case "boolean": return "bool";
634
+ case "null": return "None";
635
+ case "array": return `list[${compactSketch(node.items, depth + 1)}]`;
636
+ case "object": {
637
+ const properties = node.properties;
638
+ if (properties === void 0) return "dict";
639
+ const required = new Set(Array.isArray(node.required) ? node.required : []);
640
+ const entries = Object.entries(properties).map(([key, child]) => {
641
+ return `${`'${key.replaceAll("\\", "\\\\").replaceAll("'", "\\'")}'${required.has(key) ? "" : "?"}`}: ${compactSketch(child, depth + 1)}`;
642
+ });
643
+ return entries.length === 0 ? "dict" : `{${entries.join(", ")}}`;
644
+ }
645
+ default: return "Any";
646
+ }
647
+ }
648
+ /**
649
+ * The fixed model-facing convention rendered above any declaration lines —
650
+ * the REPL scripting pad positioning (design D5): a session-persistent
651
+ * environment (Python today) that is one working surface beside direct tool
652
+ * calls, never a privileged entry point. The wording deliberately avoids
653
+ * the word "kernel": the model's real environment is the runtime surface
654
+ * presented to it, and importing a second name for it only blurs that.
655
+ */
656
+ const REPL_BRIDGE_INSTRUCTIONS = `## Calling tools from the scripting pad
657
+
658
+ \`eval\` runs each cell on a session-persistent scripting pad (Python today; other languages are natural extensions): variables, imports, and definitions from earlier cells stay alive, top-level \`await\` works, and the pad is one working surface beside your direct tool calls — same tools, composed in code.
659
+
660
+ Every tool this conversation declares is callable inside a cell as \`await tool.<name>(args)\` with ONE positional arguments object; the awaited value is that tool's canonical JSON output (the output shape declared with each signature) and a failed call raises \`ToolCallError\`, whose \`.toolName\` names the tool. Tool names that are not plain identifiers (non-identifier characters, e.g. hyphens) have no \`tool.<name>\` member — call those as direct tool calls. The declaration lines below ARE the live callable surface for this scope.`;
661
+ /**
662
+ * Render the `dashr:tool-catalog` prompt section body as the REPL bridge
663
+ * instructions (design D4/D5): the scripting-pad positioning and the
664
+ * calling convention above, then — in the default `'signatures'` mode —
665
+ * one compact declaration line per visible tool
666
+ * (`tool.<name>(args: {…}) -> <output shape>`, omp code-mode shape with
667
+ * the output contract kept), inside one fenced ```python block.
668
+ * Non-bindable names (reserved, exotic, underscore-leading) are omitted
669
+ * from the lines; the convention sentence above states that limit once.
670
+ *
671
+ * Deterministic — lines are emitted in lexicographic name order, so an
672
+ * unchanged tool set produces byte-identical text across assemblies.
673
+ * @param schemas - the calling scope's visible tools (the caller already
674
+ * excluded the transport and the wire-masked names).
675
+ * @param mode - override the deployed {@link REPL_BRIDGE_CATALOG_MODE}
676
+ * (the two render states; tests exercise both).
677
+ * @returns the complete section body.
678
+ */
679
+ function renderReplBridgeInstructions(schemas, mode = REPL_BRIDGE_CATALOG_MODE) {
680
+ if (mode === "convention") return REPL_BRIDGE_INSTRUCTIONS;
681
+ const lines = [];
682
+ for (const schema of [...schemas].sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0)) {
683
+ if (!isFlatBindableName(schema.name)) continue;
684
+ lines.push(`tool.${schema.name}(args: ${compactSketch(schema.parameters, 0)}) -> ${compactSketch(schema.output, 0)}`);
685
+ }
686
+ if (lines.length === 0) return REPL_BRIDGE_INSTRUCTIONS;
687
+ return `${REPL_BRIDGE_INSTRUCTIONS}\n\nTool declarations (one line per tool; \`?\` marks optional keys, deeper structure is abbreviated):\n\n\`\`\`python\n${lines.join("\n")}\n\`\`\``;
688
+ }
689
+
690
+ //#endregion
691
+ export { DUNDER_MEMBER as a, RESERVED_ERROR_MEMBERS as c, renderToolsSdkPy as i, ReplRuntime as l, isFlatBindableName as n, PORTABLE_RESERVED_WORDS as o, renderReplBridgeInstructions as r, RESERVED_BINDING_GLOBALS as s, REPL_BRIDGE_CATALOG_MODE as t };