shellsim 0.1.22__tar.gz → 0.1.27__tar.gz

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 (362) hide show
  1. {shellsim-0.1.22 → shellsim-0.1.27}/Cargo.lock +47 -5
  2. {shellsim-0.1.22 → shellsim-0.1.27}/Cargo.toml +2 -1
  3. {shellsim-0.1.22 → shellsim-0.1.27}/PKG-INFO +14 -1
  4. {shellsim-0.1.22 → shellsim-0.1.27}/README.md +11 -0
  5. {shellsim-0.1.22 → shellsim-0.1.27}/pyproject.toml +4 -0
  6. {shellsim-0.1.22 → shellsim-0.1.27}/python/native/Cargo.lock +49 -6
  7. {shellsim-0.1.22 → shellsim-0.1.27}/python/native/Cargo.toml +2 -1
  8. {shellsim-0.1.22 → shellsim-0.1.27}/python/native/src/lib.rs +261 -2
  9. {shellsim-0.1.22 → shellsim-0.1.27}/python/shellsim/__init__.py +15 -0
  10. {shellsim-0.1.22 → shellsim-0.1.27}/python/shellsim/_api.py +277 -1
  11. {shellsim-0.1.22 → shellsim-0.1.27}/python/shellsim/_cli.py +68 -1
  12. shellsim-0.1.27/python/shellsim/display_host.py +205 -0
  13. shellsim-0.1.27/python/shellsim/package.py +620 -0
  14. {shellsim-0.1.22 → shellsim-0.1.27}/src/bin/shellsim-python.rs +2 -0
  15. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/awk/eval.rs +146 -19
  16. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/awk/parser.rs +84 -22
  17. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/builtins.rs +47 -24
  18. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/expr.rs +19 -0
  19. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/find.rs +55 -10
  20. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/mod.rs +13 -8
  21. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/net.rs +7 -6
  22. shellsim-0.1.27/src/commands/printf.rs +227 -0
  23. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/text.rs +4 -0
  24. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/wasm.rs +191 -101
  25. {shellsim-0.1.22 → shellsim-0.1.27}/src/display.rs +7 -0
  26. {shellsim-0.1.22 → shellsim-0.1.27}/src/exec.rs +43 -12
  27. {shellsim-0.1.22 → shellsim-0.1.27}/src/expand.rs +84 -11
  28. {shellsim-0.1.22 → shellsim-0.1.27}/src/harness.rs +351 -12
  29. {shellsim-0.1.22 → shellsim-0.1.27}/src/harness_manager.rs +2 -2
  30. {shellsim-0.1.22 → shellsim-0.1.27}/src/interp.rs +150 -71
  31. {shellsim-0.1.22 → shellsim-0.1.27}/src/lib.rs +6 -0
  32. {shellsim-0.1.22 → shellsim-0.1.27}/src/main.rs +21 -8
  33. {shellsim-0.1.22 → shellsim-0.1.27}/src/net.rs +248 -5
  34. {shellsim-0.1.22 → shellsim-0.1.27}/src/netcmd.rs +50 -22
  35. {shellsim-0.1.22 → shellsim-0.1.27}/src/program.rs +1 -1
  36. shellsim-0.1.27/src/python/attributes.rs +465 -0
  37. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/bytecode.rs +4 -0
  38. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/compiler.rs +111 -16
  39. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/complex.rs +111 -95
  40. shellsim-0.1.27/src/python/definitions.rs +84 -0
  41. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/exception_types.rs +22 -0
  42. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/filesystem.rs +93 -36
  43. shellsim-0.1.27/src/python/heap/gc.rs +482 -0
  44. shellsim-0.1.27/src/python/heap/mapping.rs +427 -0
  45. shellsim-0.1.27/src/python/heap/mod.rs +1353 -0
  46. shellsim-0.1.27/src/python/heap/snapshot.rs +304 -0
  47. shellsim-0.1.27/src/python/heap/stack.rs +99 -0
  48. shellsim-0.1.27/src/python/heap/tests.rs +305 -0
  49. shellsim-0.1.27/src/python/heap/value.rs +512 -0
  50. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/http.rs +53 -42
  51. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/lexer.rs +11 -7
  52. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/mod.rs +102 -319
  53. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/native.rs +648 -438
  54. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/number.rs +452 -327
  55. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/object_model.rs +190 -58
  56. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/parser.rs +129 -7
  57. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/process.rs +33 -31
  58. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/protocol.rs +422 -266
  59. shellsim-0.1.27/src/python/scopes.rs +259 -0
  60. shellsim-0.1.27/src/python/sort.rs +83 -0
  61. shellsim-0.1.27/src/python/source.rs +48 -0
  62. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/argparse.rs +119 -62
  63. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/asyncio.rs +30 -18
  64. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/base64.rs +12 -12
  65. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/collections.rs +1 -1
  66. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/core.rs +2041 -1035
  67. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/dataclasses.rs +2 -2
  68. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/enum.rs +1 -1
  69. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/frozen.rs +17 -1
  70. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/functools.rs +19 -9
  71. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/hashlib.rs +1 -1
  72. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/heapq.rs +11 -8
  73. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/http.rs +1 -1
  74. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/importlib.rs +3 -3
  75. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/introspect.rs +25 -7
  76. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/itertools.rs +85 -50
  77. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/json.rs +37 -26
  78. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/mapping_views.rs +200 -152
  79. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/math.rs +697 -76
  80. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/mod.rs +10 -8
  81. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/args.rs +45 -36
  82. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/array.rs +95 -83
  83. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/construct.rs +136 -64
  84. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/convert.rs +115 -88
  85. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/dtype.rs +6 -6
  86. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/dtype_object.rs +50 -41
  87. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/errstate.rs +13 -9
  88. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/index.rs +71 -63
  89. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/io.rs +12 -4
  90. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/layout.rs +25 -21
  91. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/linalg/dense.rs +21 -13
  92. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/linalg.rs +65 -45
  93. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/math.rs +27 -17
  94. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/mod.rs +10 -7
  95. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/ndarray.rs +212 -145
  96. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/products.rs +62 -49
  97. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/random.rs +70 -36
  98. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/reduce.rs +183 -111
  99. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/scalar.rs +105 -60
  100. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/select.rs +41 -32
  101. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/shape/broadcast.rs +8 -5
  102. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/shape/diagonal.rs +13 -10
  103. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/shape/join.rs +21 -12
  104. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/shape/repeat.rs +16 -13
  105. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/shape.rs +101 -43
  106. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/sort/bincount.rs +15 -8
  107. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/sort/search.rs +25 -22
  108. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/sort.rs +122 -99
  109. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/ufunc/masked.rs +8 -8
  110. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/ufunc.rs +227 -191
  111. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/operator.rs +1 -1
  112. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/os.rs +12 -8
  113. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/pytest.rs +6 -6
  114. shellsim-0.1.27/src/python/stdlib/re.rs +1400 -0
  115. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/special/meter.rs +3 -3
  116. shellsim-0.1.27/src/python/stdlib/source/_exceptions.py +90 -0
  117. shellsim-0.1.27/src/python/stdlib/source/_io.py +1331 -0
  118. shellsim-0.1.27/src/python/stdlib/source/_iteration.py +45 -0
  119. shellsim-0.1.27/src/python/stdlib/source/abc.py +211 -0
  120. shellsim-0.1.27/src/python/stdlib/source/bisect.py +47 -0
  121. shellsim-0.1.27/src/python/stdlib/source/cmath.py +183 -0
  122. shellsim-0.1.27/src/python/stdlib/source/codecs.py +716 -0
  123. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/collections.py +3 -0
  124. shellsim-0.1.27/src/python/stdlib/source/collections_abc.py +761 -0
  125. shellsim-0.1.27/src/python/stdlib/source/contextlib.py +502 -0
  126. shellsim-0.1.27/src/python/stdlib/source/copy.py +213 -0
  127. shellsim-0.1.27/src/python/stdlib/source/datetime.py +1858 -0
  128. shellsim-0.1.27/src/python/stdlib/source/errno.py +98 -0
  129. shellsim-0.1.27/src/python/stdlib/source/fnmatch.py +80 -0
  130. shellsim-0.1.27/src/python/stdlib/source/functools.py +577 -0
  131. shellsim-0.1.27/src/python/stdlib/source/hashlib.py +79 -0
  132. shellsim-0.1.27/src/python/stdlib/source/heapq.py +163 -0
  133. shellsim-0.1.27/src/python/stdlib/source/inspect.py +960 -0
  134. shellsim-0.1.27/src/python/stdlib/source/io.py +16 -0
  135. shellsim-0.1.27/src/python/stdlib/source/itertools.py +250 -0
  136. shellsim-0.1.27/src/python/stdlib/source/json.py +492 -0
  137. shellsim-0.1.27/src/python/stdlib/source/os.py +1013 -0
  138. shellsim-0.1.27/src/python/stdlib/source/pathlib.py +631 -0
  139. shellsim-0.1.27/src/python/stdlib/source/posixpath.py +312 -0
  140. shellsim-0.1.27/src/python/stdlib/source/random.py +422 -0
  141. shellsim-0.1.27/src/python/stdlib/source/re.py +148 -0
  142. shellsim-0.1.27/src/python/stdlib/source/shutil.py +549 -0
  143. shellsim-0.1.27/src/python/stdlib/source/stat.py +169 -0
  144. shellsim-0.1.27/src/python/stdlib/source/string.py +272 -0
  145. shellsim-0.1.27/src/python/stdlib/source/struct.py +86 -0
  146. shellsim-0.1.27/src/python/stdlib/source/sys.py +448 -0
  147. shellsim-0.1.27/src/python/stdlib/source/textwrap.py +238 -0
  148. shellsim-0.1.27/src/python/stdlib/source/time.py +425 -0
  149. shellsim-0.1.27/src/python/stdlib/source/types.py +210 -0
  150. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/urllib.py +1 -0
  151. shellsim-0.1.27/src/python/stdlib/source/urllib_parse.py +460 -0
  152. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/zipfile.py +9 -1
  153. shellsim-0.1.27/src/python/stdlib/source/zlib.py +177 -0
  154. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/string.rs +1 -1
  155. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/struct.rs +28 -25
  156. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/subprocess.rs +41 -25
  157. shellsim-0.1.27/src/python/stdlib/sys.rs +521 -0
  158. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/time.rs +9 -9
  159. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/typing.rs +7 -7
  160. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/unittest.rs +42 -14
  161. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/vfs.rs +120 -22
  162. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/warnings.rs +1 -1
  163. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/zlib.rs +3 -3
  164. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/string.rs +10 -9
  165. shellsim-0.1.27/src/python/symbols.rs +75 -0
  166. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/calls.rs +670 -486
  167. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/dispatch.rs +241 -172
  168. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/equality.rs +107 -54
  169. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/format.rs +7 -0
  170. shellsim-0.1.27/src/python/vm/handles.rs +387 -0
  171. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/hashing.rs +58 -61
  172. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/host.rs +28 -17
  173. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/iteration.rs +410 -329
  174. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/mappings.rs +24 -11
  175. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/namespace.rs +390 -330
  176. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/native_runtime.rs +1254 -903
  177. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/objects.rs +1298 -898
  178. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/operations.rs +250 -156
  179. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm/summation.rs +15 -18
  180. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/vm.rs +853 -313
  181. {shellsim-0.1.22 → shellsim-0.1.27}/src/resources.rs +17 -3
  182. {shellsim-0.1.22 → shellsim-0.1.27}/src/sandbox.rs +3 -0
  183. {shellsim-0.1.22 → shellsim-0.1.27}/src/scheduler.rs +2 -0
  184. {shellsim-0.1.22 → shellsim-0.1.27}/src/shell.rs +63 -13
  185. shellsim-0.1.27/src/stack.rs +132 -0
  186. {shellsim-0.1.22 → shellsim-0.1.27}/src/syscalls.rs +7 -5
  187. {shellsim-0.1.22 → shellsim-0.1.27}/src/telemetry.rs +72 -16
  188. shellsim-0.1.27/src/variables.rs +351 -0
  189. {shellsim-0.1.22 → shellsim-0.1.27}/src/vfs.rs +215 -65
  190. shellsim-0.1.22/src/commands/printf.rs +0 -152
  191. shellsim-0.1.22/src/python/heap.rs +0 -2145
  192. shellsim-0.1.22/src/python/mapping.rs +0 -206
  193. shellsim-0.1.22/src/python/source.rs +0 -29
  194. shellsim-0.1.22/src/python/stdlib/bisect.rs +0 -272
  195. shellsim-0.1.22/src/python/stdlib/re.rs +0 -602
  196. shellsim-0.1.22/src/python/stdlib/source/abc.py +0 -12
  197. shellsim-0.1.22/src/python/stdlib/source/cmath.py +0 -65
  198. shellsim-0.1.22/src/python/stdlib/source/codecs.py +0 -27
  199. shellsim-0.1.22/src/python/stdlib/source/contextlib.py +0 -173
  200. shellsim-0.1.22/src/python/stdlib/source/copy.py +0 -29
  201. shellsim-0.1.22/src/python/stdlib/source/datetime.py +0 -236
  202. shellsim-0.1.22/src/python/stdlib/source/functools.py +0 -16
  203. shellsim-0.1.22/src/python/stdlib/source/hashlib.py +0 -34
  204. shellsim-0.1.22/src/python/stdlib/source/inspect.py +0 -190
  205. shellsim-0.1.22/src/python/stdlib/source/io.py +0 -299
  206. shellsim-0.1.22/src/python/stdlib/source/json.py +0 -25
  207. shellsim-0.1.22/src/python/stdlib/source/os.py +0 -181
  208. shellsim-0.1.22/src/python/stdlib/source/pathlib.py +0 -205
  209. shellsim-0.1.22/src/python/stdlib/source/random.py +0 -183
  210. shellsim-0.1.22/src/python/stdlib/source/shutil.py +0 -57
  211. shellsim-0.1.22/src/python/stdlib/source/struct.py +0 -6
  212. shellsim-0.1.22/src/python/stdlib/source/textwrap.py +0 -73
  213. shellsim-0.1.22/src/python/stdlib/source/zlib.py +0 -3
  214. shellsim-0.1.22/src/python/stdlib/sys.rs +0 -273
  215. {shellsim-0.1.22 → shellsim-0.1.27}/LICENSE +0 -0
  216. {shellsim-0.1.22 → shellsim-0.1.27}/python/shellsim/__main__.py +0 -0
  217. {shellsim-0.1.22 → shellsim-0.1.27}/python/shellsim/py.typed +0 -0
  218. {shellsim-0.1.22 → shellsim-0.1.27}/python/shellsim/python.py +0 -0
  219. {shellsim-0.1.22 → shellsim-0.1.27}/rust-toolchain.toml +0 -0
  220. {shellsim-0.1.22 → shellsim-0.1.27}/src/arith.rs +0 -0
  221. {shellsim-0.1.22 → shellsim-0.1.27}/src/clock.rs +0 -0
  222. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/archives.rs +0 -0
  223. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/arcmd.rs +0 -0
  224. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/awk/ast.rs +0 -0
  225. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/awk/lexer.rs +0 -0
  226. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/awk.rs +0 -0
  227. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/bc.rs +0 -0
  228. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/dd.rs +0 -0
  229. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/diff.rs +0 -0
  230. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/echo.rs +0 -0
  231. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/format.rs +0 -0
  232. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/fs.rs +0 -0
  233. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/apply.rs +0 -0
  234. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/commit.rs +0 -0
  235. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/compare.rs +0 -0
  236. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/config.rs +0 -0
  237. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/conflict.rs +0 -0
  238. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/diff.rs +0 -0
  239. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/ignore.rs +0 -0
  240. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/import.rs +0 -0
  241. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/log.rs +0 -0
  242. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/merge.rs +0 -0
  243. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/mod.rs +0 -0
  244. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/plumbing.rs +0 -0
  245. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/rebase.rs +0 -0
  246. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/refs.rs +0 -0
  247. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/repo.rs +0 -0
  248. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/stash.rs +0 -0
  249. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/switch.rs +0 -0
  250. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/git/worktree.rs +0 -0
  251. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/grep.rs +0 -0
  252. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/hashing.rs +0 -0
  253. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/makecmd.rs +0 -0
  254. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/options.rs +0 -0
  255. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/patch.rs +0 -0
  256. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/pkg.rs +0 -0
  257. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/proc.rs +0 -0
  258. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/regex_compat.rs +0 -0
  259. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/rgcmd.rs +0 -0
  260. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/sed.rs +0 -0
  261. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/sort.rs +0 -0
  262. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/streams.rs +0 -0
  263. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/system.rs +0 -0
  264. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/tarcmd.rs +0 -0
  265. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/unavailable.rs +0 -0
  266. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/util.rs +0 -0
  267. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/xargs.rs +0 -0
  268. {shellsim-0.1.22 → shellsim-0.1.27}/src/commands/zipcmd.rs +0 -0
  269. {shellsim-0.1.22 → shellsim-0.1.27}/src/corpus.rs +0 -0
  270. {shellsim-0.1.22 → shellsim-0.1.27}/src/descriptors.rs +0 -0
  271. {shellsim-0.1.22 → shellsim-0.1.27}/src/hashes.rs +0 -0
  272. {shellsim-0.1.22 → shellsim-0.1.27}/src/host_ingest.rs +0 -0
  273. {shellsim-0.1.22 → shellsim-0.1.27}/src/jqcmd.rs +0 -0
  274. {shellsim-0.1.22 → shellsim-0.1.27}/src/mcp.rs +0 -0
  275. {shellsim-0.1.22 → shellsim-0.1.27}/src/process.rs +0 -0
  276. {shellsim-0.1.22 → shellsim-0.1.27}/src/profile.rs +0 -0
  277. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/cat.rs +0 -0
  278. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/env.rs +0 -0
  279. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/find.rs +0 -0
  280. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/head.rs +0 -0
  281. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/make.rs +0 -0
  282. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/nice.rs +0 -0
  283. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/nohup.rs +0 -0
  284. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/sleep.rs +0 -0
  285. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/tee.rs +0 -0
  286. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/timeout.rs +0 -0
  287. {shellsim-0.1.22 → shellsim-0.1.27}/src/program/xargs.rs +0 -0
  288. {shellsim-0.1.22 → shellsim-0.1.27}/src/pseudo_fs.rs +0 -0
  289. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/ast.rs +0 -0
  290. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/cpython_names.rs +0 -0
  291. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/float_text.rs +0 -0
  292. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/hash.rs +0 -0
  293. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/slice.rs +0 -0
  294. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/element.rs +0 -0
  295. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/format.rs +0 -0
  296. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/ops.rs +0 -0
  297. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/random/bitgen.rs +0 -0
  298. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/random/discrete.rs +0 -0
  299. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/random/gamma.rs +0 -0
  300. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/random/integers.rs +0 -0
  301. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/random/normal.rs +0 -0
  302. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/random/sequence.rs +0 -0
  303. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/numpy/underflow.rs +0 -0
  304. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/mod.rs +0 -0
  305. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/special/erf.rs +0 -0
  306. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/special/gamma.rs +0 -0
  307. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/special/ibeta.rs +0 -0
  308. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/special/igam.rs +0 -0
  309. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/special/mod.rs +0 -0
  310. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/scipy/special/zeta.rs +0 -0
  311. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/asyncio.py +0 -0
  312. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/base64.py +0 -0
  313. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/csv.py +0 -0
  314. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/fractions.py +0 -0
  315. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/glob.py +0 -0
  316. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/http.py +0 -0
  317. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/http_client.py +0 -0
  318. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/importlib.py +0 -0
  319. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/keyword.py +0 -0
  320. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/logging.py +0 -0
  321. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/__init__.py +0 -0
  322. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_creation.py +0 -0
  323. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_errors.py +0 -0
  324. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_io.py +0 -0
  325. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_math.py +0 -0
  326. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_printing.py +0 -0
  327. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_products.py +0 -0
  328. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_sets.py +0 -0
  329. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_shapes.py +0 -0
  330. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/_stats.py +0 -0
  331. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/exceptions.py +0 -0
  332. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/fft.py +0 -0
  333. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/linalg.py +0 -0
  334. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/random.py +0 -0
  335. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/numpy/testing.py +0 -0
  336. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/operator.py +0 -0
  337. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/pytest.py +0 -0
  338. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/__init__.py +0 -0
  339. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/integrate.py +0 -0
  340. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/interpolate.py +0 -0
  341. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/linalg.py +0 -0
  342. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/optimize.py +0 -0
  343. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/spatial/__init__.py +0 -0
  344. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/spatial/distance.py +0 -0
  345. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/special.py +0 -0
  346. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/stats/__init__.py +0 -0
  347. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/stats/_describe.py +0 -0
  348. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/stats/_distributions.py +0 -0
  349. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/scipy/stats/_tests.py +0 -0
  350. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/signal.py +0 -0
  351. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/statistics.py +0 -0
  352. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/subprocess.py +0 -0
  353. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/tempfile.py +0 -0
  354. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/urllib_error.py +0 -0
  355. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/urllib_request.py +0 -0
  356. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/uuid.py +0 -0
  357. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/stdlib/source/warnings.py +0 -0
  358. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/token.rs +0 -0
  359. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/unicode/tables.rs +0 -0
  360. {shellsim-0.1.22 → shellsim-0.1.27}/src/python/unicode.rs +0 -0
  361. {shellsim-0.1.22 → shellsim-0.1.27}/src/realtime.rs +0 -0
  362. {shellsim-0.1.22 → shellsim-0.1.27}/src/scenario.rs +0 -0
@@ -38,6 +38,15 @@ version = "1.0.104"
38
38
  source = "registry+https://github.com/rust-lang/crates.io-index"
39
39
  checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
40
40
 
41
+ [[package]]
42
+ name = "ar_archive_writer"
43
+ version = "0.5.3"
44
+ source = "registry+https://github.com/rust-lang/crates.io-index"
45
+ checksum = "73cd58deff2140a0a8eae87e417bd01db68a33e148aa93d1e8cd837e55e312b6"
46
+ dependencies = [
47
+ "object 0.39.1",
48
+ ]
49
+
41
50
  [[package]]
42
51
  name = "arbitrary"
43
52
  version = "1.4.2"
@@ -619,6 +628,15 @@ dependencies = [
619
628
  "autocfg",
620
629
  ]
621
630
 
631
+ [[package]]
632
+ name = "object"
633
+ version = "0.39.1"
634
+ source = "registry+https://github.com/rust-lang/crates.io-index"
635
+ checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b"
636
+ dependencies = [
637
+ "memchr",
638
+ ]
639
+
622
640
  [[package]]
623
641
  name = "object"
624
642
  version = "0.40.0"
@@ -664,6 +682,16 @@ dependencies = [
664
682
  "unicode-ident",
665
683
  ]
666
684
 
685
+ [[package]]
686
+ name = "psm"
687
+ version = "0.1.32"
688
+ source = "registry+https://github.com/rust-lang/crates.io-index"
689
+ checksum = "4dcd034599e63b970727f70d79e02d62390a4a84f7c6b827c27c46d5ac3fa622"
690
+ dependencies = [
691
+ "ar_archive_writer",
692
+ "cc",
693
+ ]
694
+
667
695
  [[package]]
668
696
  name = "pulley-interpreter"
669
697
  version = "49.0.0"
@@ -861,7 +889,7 @@ dependencies = [
861
889
 
862
890
  [[package]]
863
891
  name = "shellsim"
864
- version = "0.1.22"
892
+ version = "0.1.27"
865
893
  dependencies = [
866
894
  "base64",
867
895
  "crc32fast",
@@ -879,6 +907,7 @@ dependencies = [
879
907
  "serde_json",
880
908
  "sha1",
881
909
  "sha2",
910
+ "stacker",
882
911
  "toml",
883
912
  "wasmtime",
884
913
  "wat",
@@ -917,6 +946,19 @@ version = "1.2.1"
917
946
  source = "registry+https://github.com/rust-lang/crates.io-index"
918
947
  checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
919
948
 
949
+ [[package]]
950
+ name = "stacker"
951
+ version = "0.1.25"
952
+ source = "registry+https://github.com/rust-lang/crates.io-index"
953
+ checksum = "707f49d46706bacf8a2b00d51dace3f9de527c13eec3778f570c411f89e69967"
954
+ dependencies = [
955
+ "cc",
956
+ "cfg-if",
957
+ "libc",
958
+ "psm",
959
+ "windows-sys",
960
+ ]
961
+
920
962
  [[package]]
921
963
  name = "syn"
922
964
  version = "2.0.118"
@@ -1122,7 +1164,7 @@ dependencies = [
1122
1164
  "log",
1123
1165
  "mach2",
1124
1166
  "memfd",
1125
- "object",
1167
+ "object 0.40.0",
1126
1168
  "once_cell",
1127
1169
  "postcard",
1128
1170
  "pulley-interpreter",
@@ -1159,7 +1201,7 @@ dependencies = [
1159
1201
  "hashbrown 0.17.1",
1160
1202
  "indexmap",
1161
1203
  "log",
1162
- "object",
1204
+ "object 0.40.0",
1163
1205
  "postcard",
1164
1206
  "rustc-demangle",
1165
1207
  "semver",
@@ -1221,7 +1263,7 @@ dependencies = [
1221
1263
  "gimli",
1222
1264
  "itertools",
1223
1265
  "log",
1224
- "object",
1266
+ "object 0.40.0",
1225
1267
  "pulley-interpreter",
1226
1268
  "smallvec",
1227
1269
  "target-lexicon",
@@ -1276,7 +1318,7 @@ checksum = "5978e43aa5e9a3a03ebea8a4d4a015c92144268167abb27d99ab1b53224b28ae"
1276
1318
  dependencies = [
1277
1319
  "cranelift-codegen",
1278
1320
  "log",
1279
- "object",
1321
+ "object 0.40.0",
1280
1322
  "wasmtime-environ",
1281
1323
  ]
1282
1324
 
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "shellsim"
3
- version = "0.1.22"
3
+ version = "0.1.27"
4
4
  edition = "2021"
5
5
  description = "In-process BusyBox-like environment for RL rollouts and agent tests"
6
6
  license = "Apache-2.0"
@@ -44,6 +44,7 @@ wasmtime = { version = "49.0.0", default-features = false, features = ["runtime"
44
44
  num-bigint = "0.4"
45
45
  num-traits = "0.2"
46
46
  libm = "0.2"
47
+ stacker = "0.1"
47
48
 
48
49
  # Process-level syscall sandbox (Linux only): a startup seccomp filter that denies
49
50
  # network/exec/fork so no Python-level trick can reach the real OS for those. shellsim
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shellsim
3
- Version: 0.1.22
3
+ Version: 0.1.27
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Operating System :: MacOS :: MacOS X
6
6
  Classifier: Operating System :: Microsoft :: Windows
@@ -10,6 +10,8 @@ Classifier: Programming Language :: Python :: Implementation :: CPython
10
10
  Classifier: Programming Language :: Rust
11
11
  Classifier: Topic :: Software Development :: Testing
12
12
  Classifier: Typing :: Typed
13
+ Requires-Dist: shellsim-c-toolchain==0.1.27 ; extra == 'c'
14
+ Provides-Extra: c
13
15
  License-File: LICENSE
14
16
  Summary: In-process BusyBox-like environment for RL rollouts and agent tests
15
17
  Keywords: agents,containers,reinforcement-learning,sandbox,simulation,testing
@@ -84,6 +86,10 @@ shellsim -c 'printf "b\na\n" | sort'
84
86
  shellsim --root ./project -c 'python3.14 test.py'
85
87
  ```
86
88
 
89
+ Install `shellsim[c]` instead when a `.shl` package needs the separately distributed C-to-Wasm
90
+ toolchain. The core wheel does not contain TinyCC or the WASI sysroot. See
91
+ [the C toolchain contract](docs/shl-packages.md#optional-c-toolchain).
92
+
87
93
  `--root` copies the selected host tree into a disposable `/work` snapshot. With no `-c` and a
88
94
  terminal attached, `shellsim` starts a persistent interactive session.
89
95
 
@@ -206,6 +212,13 @@ as a stdio MCP server. `shellsim replay scenario.ndjson` reruns checked action t
206
212
  `shellsim corpus manifest.json` runs frozen shell and Python workloads under a versioned stock
207
213
  environment and emits a classified JSON report. See [compatibility testing](docs/compatibility-testing.md).
208
214
 
215
+ `shellsim serve --host-tools` grants a virtual guest-to-host tool route at construction. The
216
+ trusted runner receives typed calls in `poll_action` and completes them with `respond_tool_call`;
217
+ ordinary sessions have no such route. See [`.shl` package design](docs/shl-packages.md).
218
+
219
+ Python hosts can instead use `shellsim.Container(tools={"name": handler})` to register handlers
220
+ at construction and call `container.run(...)` without a CLI subprocess or manual polling.
221
+
209
222
  ```sh
210
223
  printf '%s\n' \
211
224
  '{"id":1,"op":"execute","source":"printf hello > result"}' \
@@ -61,6 +61,10 @@ shellsim -c 'printf "b\na\n" | sort'
61
61
  shellsim --root ./project -c 'python3.14 test.py'
62
62
  ```
63
63
 
64
+ Install `shellsim[c]` instead when a `.shl` package needs the separately distributed C-to-Wasm
65
+ toolchain. The core wheel does not contain TinyCC or the WASI sysroot. See
66
+ [the C toolchain contract](docs/shl-packages.md#optional-c-toolchain).
67
+
64
68
  `--root` copies the selected host tree into a disposable `/work` snapshot. With no `-c` and a
65
69
  terminal attached, `shellsim` starts a persistent interactive session.
66
70
 
@@ -183,6 +187,13 @@ as a stdio MCP server. `shellsim replay scenario.ndjson` reruns checked action t
183
187
  `shellsim corpus manifest.json` runs frozen shell and Python workloads under a versioned stock
184
188
  environment and emits a classified JSON report. See [compatibility testing](docs/compatibility-testing.md).
185
189
 
190
+ `shellsim serve --host-tools` grants a virtual guest-to-host tool route at construction. The
191
+ trusted runner receives typed calls in `poll_action` and completes them with `respond_tool_call`;
192
+ ordinary sessions have no such route. See [`.shl` package design](docs/shl-packages.md).
193
+
194
+ Python hosts can instead use `shellsim.Container(tools={"name": handler})` to register handlers
195
+ at construction and call `container.run(...)` without a CLI subprocess or manual polling.
196
+
186
197
  ```sh
187
198
  printf '%s\n' \
188
199
  '{"id":1,"op":"execute","source":"printf hello > result"}' \
@@ -24,6 +24,9 @@ classifiers = [
24
24
  ]
25
25
  keywords = ["agents", "containers", "reinforcement-learning", "sandbox", "simulation", "testing"]
26
26
 
27
+ [project.optional-dependencies]
28
+ c = ["shellsim-c-toolchain==0.1.27"]
29
+
27
30
  [project.urls]
28
31
  Homepage = "https://github.com/rjpower/shellsim"
29
32
  Issues = "https://github.com/rjpower/shellsim/issues"
@@ -52,6 +55,7 @@ include = [
52
55
  "infra/*.py",
53
56
  "infra/**/*.py",
54
57
  "python/**/*.py",
58
+ "toolchain/**/*.py",
55
59
  "tests/python/test_*.py",
56
60
  "tests/python_package/**/*.py",
57
61
  "tests/tooling/**/*.py",
@@ -38,6 +38,15 @@ version = "1.0.104"
38
38
  source = "registry+https://github.com/rust-lang/crates.io-index"
39
39
  checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
40
40
 
41
+ [[package]]
42
+ name = "ar_archive_writer"
43
+ version = "0.5.3"
44
+ source = "registry+https://github.com/rust-lang/crates.io-index"
45
+ checksum = "73cd58deff2140a0a8eae87e417bd01db68a33e148aa93d1e8cd837e55e312b6"
46
+ dependencies = [
47
+ "object 0.39.1",
48
+ ]
49
+
41
50
  [[package]]
42
51
  name = "arbitrary"
43
52
  version = "1.4.2"
@@ -619,6 +628,15 @@ dependencies = [
619
628
  "autocfg",
620
629
  ]
621
630
 
631
+ [[package]]
632
+ name = "object"
633
+ version = "0.39.1"
634
+ source = "registry+https://github.com/rust-lang/crates.io-index"
635
+ checksum = "2e5a6c098c7a3b6547378093f5cc30bc54fd361ce711e05293a5cc589562739b"
636
+ dependencies = [
637
+ "memchr",
638
+ ]
639
+
622
640
  [[package]]
623
641
  name = "object"
624
642
  version = "0.40.0"
@@ -670,6 +688,16 @@ dependencies = [
670
688
  "unicode-ident",
671
689
  ]
672
690
 
691
+ [[package]]
692
+ name = "psm"
693
+ version = "0.1.32"
694
+ source = "registry+https://github.com/rust-lang/crates.io-index"
695
+ checksum = "4dcd034599e63b970727f70d79e02d62390a4a84f7c6b827c27c46d5ac3fa622"
696
+ dependencies = [
697
+ "ar_archive_writer",
698
+ "cc",
699
+ ]
700
+
673
701
  [[package]]
674
702
  name = "pulley-interpreter"
675
703
  version = "49.0.0"
@@ -925,7 +953,7 @@ dependencies = [
925
953
 
926
954
  [[package]]
927
955
  name = "shellsim"
928
- version = "0.1.22"
956
+ version = "0.1.27"
929
957
  dependencies = [
930
958
  "base64",
931
959
  "crc32fast",
@@ -943,14 +971,16 @@ dependencies = [
943
971
  "serde_json",
944
972
  "sha1",
945
973
  "sha2",
974
+ "stacker",
946
975
  "toml",
947
976
  "wasmtime",
948
977
  ]
949
978
 
950
979
  [[package]]
951
980
  name = "shellsim-python-bindings"
952
- version = "0.1.22"
981
+ version = "0.1.27"
953
982
  dependencies = [
983
+ "base64",
954
984
  "pyo3",
955
985
  "serde",
956
986
  "serde_json",
@@ -990,6 +1020,19 @@ version = "1.2.1"
990
1020
  source = "registry+https://github.com/rust-lang/crates.io-index"
991
1021
  checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
992
1022
 
1023
+ [[package]]
1024
+ name = "stacker"
1025
+ version = "0.1.25"
1026
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1027
+ checksum = "707f49d46706bacf8a2b00d51dace3f9de527c13eec3778f570c411f89e69967"
1028
+ dependencies = [
1029
+ "cc",
1030
+ "cfg-if",
1031
+ "libc",
1032
+ "psm",
1033
+ "windows-sys",
1034
+ ]
1035
+
993
1036
  [[package]]
994
1037
  name = "syn"
995
1038
  version = "2.0.119"
@@ -1168,7 +1211,7 @@ dependencies = [
1168
1211
  "log",
1169
1212
  "mach2",
1170
1213
  "memfd",
1171
- "object",
1214
+ "object 0.40.0",
1172
1215
  "once_cell",
1173
1216
  "postcard",
1174
1217
  "pulley-interpreter",
@@ -1205,7 +1248,7 @@ dependencies = [
1205
1248
  "hashbrown 0.17.1",
1206
1249
  "indexmap",
1207
1250
  "log",
1208
- "object",
1251
+ "object 0.40.0",
1209
1252
  "postcard",
1210
1253
  "rustc-demangle",
1211
1254
  "semver",
@@ -1267,7 +1310,7 @@ dependencies = [
1267
1310
  "gimli",
1268
1311
  "itertools",
1269
1312
  "log",
1270
- "object",
1313
+ "object 0.40.0",
1271
1314
  "pulley-interpreter",
1272
1315
  "smallvec",
1273
1316
  "target-lexicon",
@@ -1322,7 +1365,7 @@ checksum = "5978e43aa5e9a3a03ebea8a4d4a015c92144268167abb27d99ab1b53224b28ae"
1322
1365
  dependencies = [
1323
1366
  "cranelift-codegen",
1324
1367
  "log",
1325
- "object",
1368
+ "object 0.40.0",
1326
1369
  "wasmtime-environ",
1327
1370
  ]
1328
1371
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  [package]
4
4
  name = "shellsim-python-bindings"
5
- version = "0.1.22"
5
+ version = "0.1.27"
6
6
  edition = "2021"
7
7
  description = "Python bindings for shellsim"
8
8
  license = "Apache-2.0"
@@ -14,6 +14,7 @@ name = "shellsim_native"
14
14
  crate-type = ["cdylib"]
15
15
 
16
16
  [dependencies]
17
+ base64 = "0.22"
17
18
  pyo3 = { version = "0.28", features = ["abi3-py39", "extension-module"] }
18
19
  serde = { version = "1", features = ["derive"] }
19
20
  serde_json = "1"
@@ -12,15 +12,21 @@ use std::path::Path;
12
12
  use std::sync::Mutex;
13
13
  use std::thread;
14
14
 
15
+ use base64::engine::general_purpose::STANDARD;
16
+ use base64::Engine;
15
17
  use pyo3::create_exception;
16
18
  use pyo3::exceptions::PyException;
17
19
  use pyo3::prelude::*;
18
20
  use pyo3::types::PyBytes;
19
21
  use serde::Serialize;
22
+ use shellsim::display::KeyEvent;
23
+ use shellsim::harness::{HarnessOperation, HarnessRequest, HarnessSession};
20
24
  use shellsim::net::NetworkRequest;
25
+ use shellsim::realtime::ClockMode;
21
26
  use shellsim::{CommandTrust, InvocationEvent, Limits, RunOutcome};
22
27
 
23
28
  const ACTION_STACK_BYTES: usize = 8 * 1024 * 1024;
29
+ type PythonFrame = (u64, u32, u32, Py<PyBytes>);
24
30
 
25
31
  create_exception!(
26
32
  shellsim._native,
@@ -67,6 +73,253 @@ struct NativeEnvironment {
67
73
  environment: Mutex<shellsim::Environment>,
68
74
  }
69
75
 
76
+ /// In-process host control for a machine granted the virtual tool endpoint.
77
+ #[pyclass(module = "shellsim._native")]
78
+ struct NativeContainer {
79
+ session: Mutex<HarnessSession>,
80
+ }
81
+
82
+ #[pymethods]
83
+ impl NativeContainer {
84
+ #[new]
85
+ fn new(cpu: u64, memory: u64, disk: u64, output: u64, real_time: bool) -> Self {
86
+ Self {
87
+ session: Mutex::new(HarnessSession::with_clock_and_host_tools(
88
+ Limits {
89
+ cpu,
90
+ memory,
91
+ disk,
92
+ output,
93
+ },
94
+ if real_time {
95
+ ClockMode::RealTime
96
+ } else {
97
+ ClockMode::Virtual
98
+ },
99
+ )),
100
+ }
101
+ }
102
+
103
+ fn write_file(&self, py: Python<'_>, path: String, data: Vec<u8>, mode: u32) -> PyResult<()> {
104
+ let path = container_vfs_path(&path).map_err(SimulationError::new_err)?;
105
+ if mode > 0o7777 {
106
+ return Err(SimulationError::new_err("invalid file mode"));
107
+ }
108
+ py.detach(|| {
109
+ let mut session = self
110
+ .session
111
+ .lock()
112
+ .map_err(|_| "shellsim container lock is poisoned".to_string())?;
113
+ on_worker(&mut session, move |session| {
114
+ session.environment.sync_vfs_time();
115
+ session
116
+ .environment
117
+ .vfs
118
+ .put_file(&path, data, mode)
119
+ .map_err(|error| error.to_string())
120
+ })
121
+ })
122
+ .map_err(SimulationError::new_err)
123
+ }
124
+
125
+ fn read_file(&self, py: Python<'_>, path: String) -> PyResult<Py<PyBytes>> {
126
+ let path = container_vfs_path(&path).map_err(SimulationError::new_err)?;
127
+ let bytes = py
128
+ .detach(|| {
129
+ let mut session = self
130
+ .session
131
+ .lock()
132
+ .map_err(|_| "shellsim container lock is poisoned".to_string())?;
133
+ on_worker(&mut session, move |session| {
134
+ session
135
+ .environment
136
+ .vfs
137
+ .read("/", &path)
138
+ .map_err(|error| error.to_string())
139
+ })
140
+ })
141
+ .map_err(SimulationError::new_err)?;
142
+ Ok(PyBytes::new(py, &bytes).unbind())
143
+ }
144
+
145
+ fn mkdir(&self, py: Python<'_>, path: String, mode: u32) -> PyResult<()> {
146
+ let path = container_vfs_path(&path).map_err(SimulationError::new_err)?;
147
+ if mode > 0o7777 {
148
+ return Err(SimulationError::new_err("invalid directory mode"));
149
+ }
150
+ py.detach(|| {
151
+ let mut session = self
152
+ .session
153
+ .lock()
154
+ .map_err(|_| "shellsim container lock is poisoned".to_string())?;
155
+ on_worker(&mut session, move |session| {
156
+ session.environment.sync_vfs_time();
157
+ session
158
+ .environment
159
+ .vfs
160
+ .put_dir(&path, mode)
161
+ .map_err(|error| error.to_string())
162
+ })
163
+ })
164
+ .map_err(SimulationError::new_err)
165
+ }
166
+
167
+ fn snapshot_workspace(&self, py: Python<'_>) -> PyResult<String> {
168
+ py.detach(|| {
169
+ let mut session = self
170
+ .session
171
+ .lock()
172
+ .map_err(|_| "shellsim container lock is poisoned".to_string())?;
173
+ on_worker(&mut session, |session| {
174
+ let entries = session.snapshot_workspace()?;
175
+ serde_json::to_string(&entries).map_err(|error| error.to_string())
176
+ })
177
+ })
178
+ .map_err(SimulationError::new_err)
179
+ }
180
+
181
+ fn start_execute(&self, py: Python<'_>, source: String, stdin: Vec<u8>) -> PyResult<String> {
182
+ self.apply(
183
+ py,
184
+ HarnessOperation::StartExecute {
185
+ source,
186
+ stdin_base64: STANDARD.encode(stdin),
187
+ stdin_closed: true,
188
+ },
189
+ )
190
+ .and_then(serialize_result)
191
+ }
192
+
193
+ fn poll_action(&self, py: Python<'_>, action_id: u64) -> PyResult<String> {
194
+ self.apply(
195
+ py,
196
+ HarnessOperation::PollAction {
197
+ action_id,
198
+ work_quanta: 100_000,
199
+ advance_time: true,
200
+ },
201
+ )
202
+ .and_then(serialize_result)
203
+ }
204
+
205
+ fn respond_tool_call(
206
+ &self,
207
+ py: Python<'_>,
208
+ request_id: u64,
209
+ result_json: Option<String>,
210
+ error: Option<String>,
211
+ ) -> PyResult<()> {
212
+ let result = result_json
213
+ .map(|json| serde_json::from_str(&json))
214
+ .transpose()
215
+ .map_err(|error| SimulationError::new_err(error.to_string()))?;
216
+ self.apply(
217
+ py,
218
+ HarnessOperation::RespondToolCall {
219
+ request_id,
220
+ result,
221
+ error,
222
+ },
223
+ )?;
224
+ Ok(())
225
+ }
226
+
227
+ fn read_action_output(&self, py: Python<'_>, action_id: u64) -> PyResult<String> {
228
+ self.apply(py, HarnessOperation::ReadActionOutput { action_id })
229
+ .and_then(serialize_result)
230
+ }
231
+
232
+ fn cancel_action(&self, py: Python<'_>, action_id: u64) -> PyResult<()> {
233
+ self.apply(py, HarnessOperation::CancelAction { action_id })?;
234
+ Ok(())
235
+ }
236
+
237
+ fn drop_action(&self, py: Python<'_>, action_id: u64) -> PyResult<()> {
238
+ self.apply(py, HarnessOperation::DropAction { action_id })?;
239
+ Ok(())
240
+ }
241
+
242
+ fn display_frame(&self, py: Python<'_>, action_id: u64) -> PyResult<Option<PythonFrame>> {
243
+ let frame = py
244
+ .detach(|| {
245
+ let mut session = self
246
+ .session
247
+ .lock()
248
+ .map_err(|_| "shellsim container lock is poisoned".to_string())?;
249
+ on_worker(&mut session, |session| session.display_frame(action_id))
250
+ })
251
+ .map_err(SimulationError::new_err)?;
252
+ Ok(frame.map(|(generation, frame)| {
253
+ (
254
+ generation,
255
+ frame.width,
256
+ frame.height,
257
+ PyBytes::new(py, &frame.pixels).unbind(),
258
+ )
259
+ }))
260
+ }
261
+
262
+ fn inject_key(&self, py: Python<'_>, action_id: u64, code: u32, pressed: bool) -> PyResult<()> {
263
+ py.detach(|| {
264
+ let mut session = self
265
+ .session
266
+ .lock()
267
+ .map_err(|_| "shellsim container lock is poisoned".to_string())?;
268
+ on_worker(&mut session, |session| {
269
+ session.inject_action_key(action_id, KeyEvent { code, pressed })
270
+ })
271
+ })
272
+ .map_err(SimulationError::new_err)
273
+ }
274
+
275
+ fn clock_mode(&self) -> PyResult<&'static str> {
276
+ let session = self
277
+ .session
278
+ .lock()
279
+ .map_err(|_| SimulationError::new_err("shellsim container lock is poisoned"))?;
280
+ Ok(match session.environment.clock_mode() {
281
+ ClockMode::Virtual => "virtual",
282
+ ClockMode::RealTime => "real_time",
283
+ })
284
+ }
285
+ }
286
+
287
+ impl NativeContainer {
288
+ fn apply(&self, py: Python<'_>, operation: HarnessOperation) -> PyResult<serde_json::Value> {
289
+ py.detach(|| {
290
+ let mut session = self
291
+ .session
292
+ .lock()
293
+ .map_err(|_| "shellsim container lock is poisoned".to_string())?;
294
+ on_worker(&mut session, move |session| {
295
+ let response = session.handle(HarnessRequest {
296
+ id: None,
297
+ session_id: None,
298
+ operation,
299
+ });
300
+ if !response.ok {
301
+ return Err(response
302
+ .error
303
+ .unwrap_or_else(|| "container operation failed".into()));
304
+ }
305
+ serde_json::to_value(response.result).map_err(|error| error.to_string())
306
+ })
307
+ })
308
+ .map_err(SimulationError::new_err)
309
+ }
310
+ }
311
+
312
+ fn container_vfs_path(path: &str) -> Result<String, String> {
313
+ if path.contains('\0') {
314
+ return Err("container path contains NUL".to_string());
315
+ }
316
+ Ok(shellsim::vfs::resolve_against("/work", path))
317
+ }
318
+
319
+ fn serialize_result(result: serde_json::Value) -> PyResult<String> {
320
+ serde_json::to_string(&result).map_err(|error| SimulationError::new_err(error.to_string()))
321
+ }
322
+
70
323
  #[pymethods]
71
324
  impl NativeEnvironment {
72
325
  #[new]
@@ -380,11 +633,16 @@ fn invocation_names(events: &[InvocationEvent], trust: CommandTrust) -> Vec<Stri
380
633
  }
381
634
 
382
635
  /// Run an environment operation with a predictable native stack and contain all Rust unwinds.
383
- fn on_worker<T, F>(environment: &mut shellsim::Environment, operation: F) -> Result<T, String>
636
+ fn on_worker<State, T, F>(
637
+ guard: &mut std::sync::MutexGuard<'_, State>,
638
+ operation: F,
639
+ ) -> Result<T, String>
384
640
  where
641
+ State: Send,
385
642
  T: Send,
386
- F: FnOnce(&mut shellsim::Environment) -> Result<T, String> + Send,
643
+ F: FnOnce(&mut State) -> Result<T, String> + Send,
387
644
  {
645
+ let environment = &mut **guard;
388
646
  thread::scope(|scope| {
389
647
  let worker = thread::Builder::new()
390
648
  .name("shellsim-python".to_string())
@@ -416,6 +674,7 @@ fn panic_suffix(payload: &(dyn Any + Send)) -> String {
416
674
  #[pymodule]
417
675
  fn _native(module: &Bound<'_, PyModule>) -> PyResult<()> {
418
676
  module.add_class::<NativeEnvironment>()?;
677
+ module.add_class::<NativeContainer>()?;
419
678
  module.add("SimulationError", module.py().get_type::<SimulationError>())?;
420
679
  Ok(())
421
680
  }