virtualshell 0.1.2__cp311-cp311-win_amd64.whl → 1.0.1__cp311-cp311-win_amd64.whl

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.
virtualshell/__init__.py CHANGED
@@ -8,7 +8,7 @@ if TYPE_CHECKING:
8
8
  try:
9
9
  from ._version import version as __version__
10
10
  except Exception:
11
- __version__ = "0.1.2"
11
+ __version__ = "1.0.1"
12
12
 
13
13
 
14
14
  from .errors import (
Binary file
virtualshell/_version.py CHANGED
@@ -1 +1 @@
1
- version = "0.1.2"
1
+ version = "1.0.1"
virtualshell/shell.py CHANGED
@@ -158,8 +158,8 @@ class ExecutionResult:
158
158
  Use this class when you need a stable Pythonic type. If you require the raw C++
159
159
  object (e.g., for zero-copy interop), pass `as_dataclass=False` to public APIs.
160
160
  """
161
- output: str
162
- error: str
161
+ out: str
162
+ err: str
163
163
  exit_code: int
164
164
  success: bool
165
165
  execution_time: float
@@ -168,8 +168,8 @@ class ExecutionResult:
168
168
  def from_cpp(cls, r: _CPP_ExecResult) -> "ExecutionResult":
169
169
  # Attribute access is defensive to tolerate ABI field name differences.
170
170
  return cls(
171
- output=getattr(r, "output", ""),
172
- error=getattr(r, "error", ""),
171
+ out=getattr(r, "out", ""),
172
+ err=getattr(r, "err", ""),
173
173
  exit_code=int(getattr(r, "exit_code", getattr(r, "exitCode", -1))),
174
174
  success=bool(getattr(r, "success", False)),
175
175
  execution_time=float(getattr(r, "execution_time", getattr(r, "executionTime", 0.0))),
@@ -265,7 +265,7 @@ class Shell:
265
265
  return bool(self._core.is_alive())
266
266
 
267
267
  # -------- sync --------
268
- def execute(
268
+ def run(
269
269
  self,
270
270
  command: str,
271
271
  timeout: Optional[float] = None,
@@ -291,7 +291,7 @@ class Shell:
291
291
  _raise_on_failure(res, raise_on_error=raise_on_error, label="Command", timeout_used=to)
292
292
  return ExecutionResult.from_cpp(res) if as_dataclass else res
293
293
 
294
- def execute_script(
294
+ def run_script(
295
295
  self,
296
296
  script_path: Union[str, Path],
297
297
  args: Optional[Iterable[str]] = None,
@@ -320,7 +320,7 @@ class Shell:
320
320
  _raise_on_failure(res, raise_on_error=raise_on_error, label="Script", timeout_used=to)
321
321
  return ExecutionResult.from_cpp(res) if as_dataclass else res
322
322
 
323
- def execute_script_kv(
323
+ def run_script_kv(
324
324
  self,
325
325
  script_path: Union[str, Path],
326
326
  named_args: Optional[Dict[str, str]] = None,
@@ -346,7 +346,7 @@ class Shell:
346
346
  _raise_on_failure(res, raise_on_error=raise_on_error, label="ScriptKV", timeout_used=to)
347
347
  return ExecutionResult.from_cpp(res) if as_dataclass else res
348
348
 
349
- def execute_batch(
349
+ def run_batch(
350
350
  self,
351
351
  commands: Iterable[str],
352
352
  *,
@@ -369,7 +369,7 @@ class Shell:
369
369
  return [ExecutionResult.from_cpp(r) for r in vec]
370
370
  return vec
371
371
 
372
- def execute_async(self, command: str, callback: Optional[Callable[[ExecutionResult], None]] = None, *, as_dataclass: bool = True):
372
+ def run_async(self, command: str, callback: Optional[Callable[[ExecutionResult], None]] = None, *, as_dataclass: bool = True):
373
373
  """Asynchronously execute a single command.
374
374
 
375
375
  - If `callback` is provided, it is invoked on completion with the result type
@@ -390,7 +390,7 @@ class Shell:
390
390
  c_fut = self._core.execute_async(command=command, callback=_cb if callback else None)
391
391
  return _map_future(c_fut, lambda r: ExecutionResult.from_cpp(r)) if as_dataclass else c_fut
392
392
 
393
- def execute_async_batch(
393
+ def run_async_batch(
394
394
  self,
395
395
  commands: Iterable[str],
396
396
  progress: Optional[Callable[[ _CPP_BatchProg ], None]] = None,
@@ -416,7 +416,7 @@ class Shell:
416
416
  return _map_future(fut, lambda vec: [ExecutionResult.from_cpp(r) for r in vec])
417
417
  return fut
418
418
 
419
- def execute_async_script(
419
+ def run_async_script(
420
420
  self,
421
421
  script_path: Union[str, Path],
422
422
  args: Optional[Iterable[str]] = None,
@@ -453,7 +453,7 @@ class Shell:
453
453
  return _map_future(fut, lambda r: ExecutionResult.from_cpp(r))
454
454
  return fut
455
455
 
456
- def execute_async_script_kv(
456
+ def run_async_script_kv(
457
457
  self,
458
458
  script_path: Union[str, Path],
459
459
  named_args: Optional[Dict[str, str]] = None,
@@ -501,7 +501,7 @@ class Shell:
501
501
  `shell.pwsh("Hello 'World'")` -> runs `Write-Output 'Hello ''World'''` semantics;
502
502
  here we only quote the literal; you still provide the full command.
503
503
  """
504
- return self.execute(quote_pwsh_literal(s), timeout=timeout, raise_on_error=raise_on_error)
504
+ return self.run(quote_pwsh_literal(s), timeout=timeout, raise_on_error=raise_on_error)
505
505
 
506
506
  def __enter__(self) -> "Shell":
507
507
  """Context manager entry: ensure backend is running."""
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: virtualshell
3
- Version: 0.1.2
3
+ Version: 1.0.1
4
4
  Summary: High-performance PowerShell bridge (C++ pybind11 backend)
5
5
  Keywords: powershell,automation,shell,cpp,pybind11
6
6
  Author: Kim-Andre Myrvold
@@ -219,40 +219,45 @@ Description-Content-Type: text/markdown
219
219
 
220
220
  # virtualshell
221
221
 
222
- High-performance Python façade over a **C++ PowerShell runner**.
223
- All heavy I/O (pipes, threads, timeouts, demux) is implemented in C++ for low latency and high throughput; Python exposes a thin API.
222
+ High-performance Python façade over a **C++ PowerShell runner**.
223
+ A single long-lived PowerShell process is managed in C++, handling pipes, threads, timeouts and output demux; Python exposes a small, predictable API.
224
224
 
225
225
  ---
226
226
 
227
227
  ## Features
228
228
 
229
- * **Single persistent session** to `pwsh`/`powershell` (low overhead)
230
- * **Sync & async** execution (futures + optional callbacks)
231
- * **Script execution** with positional or named args
232
- * **Batch execution** with per-command timeout & early-stop
233
- * **Clean error model** with typed Python exceptions
234
- * **Context manager** (`with Shell(...)`) for lifecycle safety
229
+ - **Persistent session** to `pwsh`/`powershell` (reuse modules, `$env:*`, functions, cwd)
230
+ - **Sync & async** execution (Futures + optional callbacks)
231
+ - **Script execution** (positional / named args, optional dot-sourcing)
232
+ - **Batch** with per-command timeout & early-stop
233
+ - **Clear failures** (typed exceptions), **context manager** lifecycle
235
234
 
236
235
  ---
237
236
 
238
237
  ## Install
239
238
 
240
- Preview packages are published to TestPyPI:
241
-
242
239
  ```bash
243
- pip install -i https://test.pypi.org/simple/ virtualshell==0.1.2
244
- ```
240
+ pip install virtualshell
241
+ ````
242
+
243
+ ## Platform & Python Support
245
244
 
246
- ### Available distributions (Windows/Linux, amd64/x86_64)
245
+ Prebuilt wheels are provided via PyPI for common platforms and Python versions.
246
+ This means you can usually `pip install virtualshell` without needing a compiler.
247
247
 
248
+ **Supported Python versions:**
249
+ - 3.8, 3.9, 3.10, 3.11, 3.12, 3.13
248
250
 
249
- > **Requirements**
250
- >
251
- > * Windows 10/11 x64 | Linux x86_64
252
- > * PowerShell available as `pwsh` (preferred) or `powershell` on `PATH`
253
- > * Python 3.8–3.13 (matching the wheel you install)
251
+ **Supported platforms:**
252
+ - **Windows** (x86_64, MSVC build)
253
+ - **Linux** (x86_64, aarch64, manylinux2014/2.28)
254
+ - **macOS** (universal2: x86_64 + arm64)
254
255
 
255
- Linux wheels will be added after validation (initial target: `manylinux_2_28_x86_64`).
256
+ If your platform is not listed above, pip will fall back to building from source.
257
+ See [Building from source](#building-from-source-advanced) for details.
258
+
259
+
260
+ > Requires PowerShell on `PATH` (`pwsh` preferred, `powershell` also supported).
256
261
 
257
262
  ---
258
263
 
@@ -265,88 +270,75 @@ import virtualshell
265
270
  sh = virtualshell.Shell(timeout_seconds=5).start()
266
271
 
267
272
  # 1) One-liners (sync)
268
- res = sh.execute("Write-Output 'hello'")
269
- print(res.output.strip()) # -> hello
270
-
273
+ res = sh.run("Write-Output 'hello'")
274
+ print(res.out.strip()) # -> hello
271
275
 
272
- # 3) Async single command
273
- fut = sh.execute_async("Write-Output 'async!'")
274
- print(fut.result().output.strip())
276
+ # 2) Async single command
277
+ fut = sh.run_async("Write-Output 'async!'")
278
+ print(fut.result().out.strip())
275
279
 
276
- # 4) Scripts with positional args
277
- r = sh.execute_script(r"C:\temp\demo.ps1", args=["alpha", "42"])
278
- print(r.output)
280
+ # 3) Scripts with positional args
281
+ r = sh.run_script(r"C:\temp\demo.ps1", args=["alpha", "42"])
282
+ print(r.out)
279
283
 
280
- # 5) Scripts with named args
281
- r = sh.execute_script_kv(r"C:\temp\demo.ps1", named_args={"Name":"Alice", "Count":"3"})
282
- print(r.output)
284
+ # 4) Scripts with named args
285
+ r = sh.run_script_kv(r"C:\temp\demo.ps1", named_args={"Name":"Alice","Count":"3"})
286
+ print(r.out)
283
287
 
284
- # 6) Context manager (auto-stop on exit)
288
+ # 5) Context manager (auto-stop on exit)
285
289
  with virtualshell.Shell(timeout_seconds=3) as s:
286
- print(s.execute("Write-Output 'inside with'").output.strip())
290
+ print(s.run("Write-Output 'inside with'").out.strip())
287
291
 
288
292
  sh.stop()
289
293
  ```
290
294
 
295
+ Another example (stateful session):
296
+
291
297
  ```python
292
298
  from virtualshell import Shell
293
299
  with Shell(timeout_seconds=3) as sh:
294
- sh.execute("function Inc { $global:i++; $global:i }")
295
- nums = [sh.execute("Inc").output.strip() for _ in range(5)]
296
- print(nums) # -> ['1', '2', '3', '4', '5']
297
-
300
+ sh.run("function Inc { $global:i++; $global:i }")
301
+ nums = [sh.run("Inc").out.strip() for _ in range(5)]
302
+ print(nums) # ['1','2','3','4','5']
298
303
  ```
299
304
 
300
305
  ---
301
306
 
302
- ## Python API (high-level façade)
307
+ ## API (overview)
303
308
 
304
309
  ```python
305
310
  import virtualshell
306
- from virtualshell import ExecutionResult # optional: Python dataclass view
311
+ from virtualshell import ExecutionResult # dataclass view
307
312
 
308
313
  sh = virtualshell.Shell(
309
- powershell_path=None, # optional explicit path to pwsh/powershell
310
- working_directory=None, # resolved to absolute path if provided
311
- timeout_seconds=5.0, # default per-command timeout
312
- environment={"FOO":"BAR"}, # extra env vars for the child process
313
- initial_commands=["$ErrorActionPreference='Stop'"] # run after start()
314
- )
315
-
316
- sh.start() # idempotent, safe if already running
317
-
318
- # --- Sync ---
319
- res: ExecutionResult = sh.execute("Get-Location | Select-Object -Expand Path")
320
- print(res.success, res.exit_code, res.output)
321
-
322
- res = sh.execute_script(r"C:\scripts\job.ps1", args=["--fast","1"])
323
- res = sh.execute_script_kv(r"C:\scripts\job.ps1", named_args={"Mode":"Fast","Count":"1"})
314
+ powershell_path=None, # optional explicit path
315
+ working_directory=None, # resolved to absolute path
316
+ timeout_seconds=5.0, # default per-command timeout
317
+ environment={"FOO": "BAR"}, # extra child env vars
318
+ initial_commands=["$ErrorActionPreference='Stop'"], # post-start setup
319
+ ).start()
324
320
 
325
- # Dotsource script
326
- res = sh.execute_script(r"C:\scripts\init.ps1", dot_source=True)
321
+ # Sync
322
+ res: ExecutionResult = sh.run("Get-Location | Select-Object -Expand Path")
327
323
 
328
- # --- Async ---
329
- f = sh.execute_async("Write-Output 'ping'")
330
- print(f.result().output.strip())
324
+ # Scripts
325
+ res = sh.run_script(r"/path/to/job.ps1", args=["--fast","1"])
326
+ res = sh.run_script_kv(r"/path/to/job.ps1", named_args={"Mode":"Fast","Count":"1"})
327
+ res = sh.run_script(r"/path/init.ps1", dot_source=True)
331
328
 
332
- def on_done(r: ExecutionResult) -> None:
333
- print("DONE:", r.success, r.output.strip())
329
+ # Async
330
+ f = sh.run_async("Write-Output 'ping'")
331
+ f2 = sh.run_async_batch(["$PSVersionTable", "Get-Random"])
334
332
 
335
- sh.execute_async("Write-Output 'callback!'", callback=on_done)
336
-
337
- # Async batch
338
- f2 = sh.execute_async_batch(["$PSVersionTable", "Get-Random"])
339
- print([r.success for r in f2.result()])
340
-
341
- # --- Convenience ---
342
- res = sh.pwsh("literal 'quoted' string") # safely single-quote literal data
333
+ # Convenience
334
+ res = sh.pwsh("literal 'quoted' string") # safe single-quoted literal
343
335
 
344
336
  sh.stop()
345
337
  ```
346
338
 
347
- ### Return types
339
+ ### Return type
348
340
 
349
- By default, methods return a Python `ExecutionResult` dataclass:
341
+ By default you get a Python dataclass:
350
342
 
351
343
  ```python
352
344
  @dataclass(frozen=True)
@@ -358,44 +350,39 @@ class ExecutionResult:
358
350
  execution_time: float
359
351
  ```
360
352
 
361
- Pass `as_dataclass=False` to receive the **raw C++ result object** for zero-copy scenarios.
353
+ Pass `as_dataclass=False` to receive the raw C++ result object.
362
354
 
363
355
  ### Timeouts
364
356
 
365
- * Each API accepts a `timeout` (or `per_command_timeout`) in **seconds**.
366
- * On timeout, `success=False`, `exit_code=-1`, `error` contains `"timeout"`.
367
- * Async futures resolve with the timeout result; late output is discarded by the C++ layer.
357
+ * Every method accepts a `timeout` (or `per_command_timeout`) in seconds.
358
+ * On timeout: `success=False`, `exit_code=-1`, `error` contains `"timeout"`.
359
+ * Async futures resolve with the timeout result; late output is dropped in C++.
368
360
 
369
361
  ---
370
362
 
371
- ## Design goals (production-readiness)
363
+ ## Design notes
372
364
 
373
- * **Thin wrapper:** All heavy I/O and process orchestration live in C++ for performance.
374
- * **No surprises:** Stable API; no implicit state mutations beyond what is documented.
375
- * **Clear failure modes:** Dedicated exceptions and `raise_on_error` semantics.
376
- * **Thread-friendly:** Async methods return Futures and accept callbacks; no Python-side locks.
377
- * **Boundary hygiene:** Minimal data marshalling; explicit conversions for paths/args.
365
+ * **Thin wrapper:** heavy I/O in C++; Python does orchestration only.
366
+ * **No surprises:** stable API, documented side-effects.
367
+ * **Clear failure modes:** `raise_on_error` and typed exceptions.
368
+ * **Thread-friendly:** async returns Futures/callbacks; no Python GIL-level locking.
369
+ * **Boundary hygiene:** explicit path/arg conversions, minimal marshalling.
378
370
 
379
- ### Security notes
371
+ ### Security
380
372
 
381
- * The wrapper **does not sanitize** raw commands. Only `pwsh()` uses literal single-quoting to protect data as arguments.
382
- * Do **not** pass untrusted strings to `execute*` without proper quoting/sanitization.
383
- * Environment injection happens via the `Shell` config; avoid secrets in logs/tracebacks.
373
+ * The wrapper **does not sanitize** raw commands. Only `pwsh()` applies literal single-quoting for data.
374
+ * Don’t pass untrusted strings to `run*` without proper quoting/sanitization.
375
+ * Avoid logging secrets; env injection happens via `Shell(..., environment=...)`.
384
376
 
385
- ### Performance notes
377
+ ### Performance
386
378
 
387
- * Sync/async routes call into C++ directly; Python overhead is mostly object allocation and callback dispatch.
388
- * Prefer **batch** or **async** when issuing many small commands to amortize round-trips.
379
+ * Sync/async routes call into C++ directly; Python overhead is object creation + callback dispatch.
380
+ * Prefer **batch/async** for many small commands to amortize round-trips.
389
381
 
390
382
  ### Lifetime
391
383
 
392
- * `Shell.start()` initializes/ensures a running backend; `Shell.stop()` tears it down.
393
- * `with Shell(...) as sh:` guarantees **stop-on-exit**, even on exceptions.
394
-
395
- ### Compatibility
396
-
397
- * The C++ layer may expose both `snake_case` and `camelCase`.
398
- * `ExecutionResult.from_cpp()` normalizes fields to keep ABI compatibility.
384
+ * `Shell.start()` ensures a running backend; `Shell.stop()` tears it down.
385
+ * `with Shell(...)` guarantees stop-on-exit, even on exceptions.
399
386
 
400
387
  ---
401
388
 
@@ -403,29 +390,34 @@ Pass `as_dataclass=False` to receive the **raw C++ result object** for zero-copy
403
390
 
404
391
  ```python
405
392
  from virtualshell.errors import (
406
- SmartShellError,
393
+ VirtualShellError,
407
394
  PowerShellNotFoundError,
408
395
  ExecutionTimeoutError,
409
396
  ExecutionError,
410
397
  )
411
398
 
412
399
  try:
413
- res = sh.execute("throw 'boom'", raise_on_error=True)
400
+ res = sh.run("throw 'boom'", raise_on_error=True)
414
401
  except ExecutionTimeoutError:
415
402
  ...
416
403
  except ExecutionError as e:
417
- print("PS failed:", e)
404
+ print("PowerShell failed:", e)
418
405
  ```
419
406
 
420
- * `ExecutionTimeoutError` is raised when `exit_code == -1` and the error mentions `timeout`, **if** `raise_on_error=True`.
421
- * Otherwise APIs return an `ExecutionResult` with `success=False`.
407
+ * `ExecutionTimeoutError` is raised on timeouts **if** `raise_on_error=True`.
408
+ * Otherwise, APIs return `ExecutionResult(success=False)`.
422
409
 
423
410
  ---
424
411
 
425
412
  ## Configuration tips
426
413
 
427
- * If `pwsh`/`powershell` isn’t on `PATH`, pass `powershell_path` to `Shell(...)`.
428
- * Use `initial_commands` for per-session setup, e.g. UTF-8:
414
+ If PowerShell isn’t on `PATH`, pass `powershell_path`:
415
+
416
+ ```python
417
+ Shell(powershell_path=r"C:\Program Files\PowerShell\7\pwsh.exe")
418
+ ```
419
+
420
+ Session setup example:
429
421
 
430
422
  ```python
431
423
  Shell(initial_commands=[
@@ -436,107 +428,42 @@ Shell(initial_commands=[
436
428
 
437
429
  ---
438
430
 
439
- ## Building from source (advanced)
440
-
441
- You typically don’t need this when using wheels, but if you want to build locally:
442
-
443
- ### Prerequisites
444
-
445
- * **Python** ≥ 3.8 with dev headers
446
- * **C++17** compiler
447
- * **CMake** ≥ 3.20
448
- * **Build backend:** [`scikit-build-core`](https://github.com/scikit-build/scikit-build-core) + [`pybind11`](https://pybind11.readthedocs.io/)
449
- * **Windows:** MSVC (VS 2019/2022)
450
- * **Linux:** GCC/Clang (Linux wheels not verified yet)
431
+ # Building from source (advanced)
432
+ Source builds require a C++ toolchain and CMake.
451
433
 
452
- The project is already configured via **`pyproject.toml`** and **`CMakeLists.txt`**. The compiled extension is installed as **`virtualshell._core`**, so `import virtualshell` works out of the box.
453
-
454
- ### One-shot local build (recommended)
434
+ **Prereqs:** Python ≥3.8, C++17, CMake ≥3.20, `scikit-build-core`, `pybind11`.
455
435
 
456
436
  ```bash
457
437
  # in repo root
458
438
  python -m pip install -U pip build
459
- python -m build # produces sdist and wheel under ./dist
439
+ python -m build # -> dist/*.whl, dist/*.tar.gz
460
440
  python -m pip install dist/virtualshell-*.whl
461
441
  ```
462
442
 
463
- ### Editable/dev install
443
+ Editable install:
464
444
 
465
445
  ```bash
466
- python -m pip install -U pip
467
- python -m pip install -e . # uses scikit-build-core to build the C++ extension
446
+ python -m pip install -e .
468
447
  ```
469
448
 
470
- ### Platform notes
471
-
472
- **Windows (x64)**
473
-
474
- * Visual Studio 2022 generator is used by default (see `[tool.scikit-build.cmake]` in `pyproject.toml`).
475
- * If you have multiple VS versions, ensure the correct **x64** toolchain is active (Developer Command Prompt or `vcvars64.bat`).
476
-
477
- **Linux (x86_64)**
478
-
479
- * Source builds work with a recent GCC/Clang + CMake.
480
- * Prebuilt manylinux wheels are **not** published yet; CI configuration exists, but the Linux runtime matrix is still being validated.
481
-
482
- ### Build configuration
483
-
484
- Most options are declared in `pyproject.toml`:
485
-
486
- * **Backend:** `scikit_build_core.build`
487
- * **Build args:** CMake generator and `PYBIND11_FINDPYTHON=ON` are set (auto-discovers the active Python).
488
- * **Wheel layout:** packaged under `src/virtualshell/`
489
- * **Versioning:** `setuptools_scm` writes `src/virtualshell/_version.py` from Git tags.
490
-
491
- You can override or pass extra CMake definitions at build time if needed:
492
-
493
- ```bash
494
- # Example: switch generator or tweak parallelism
495
- SCIKIT_BUILD_VERBOSE=1 \
496
- CMAKE_BUILD_PARALLEL_LEVEL=8 \
497
- python -m build
498
- ```
499
-
500
- ### Smoke test after build
501
-
502
- ```bash
503
- python - << 'PY'
504
- import virtualshell
505
- s = virtualshell.Shell(timeout_seconds=2)
506
- print("import_ok:", bool(s._core))
507
- # Optional: only if PowerShell is available on PATH
508
- # if s.start().is_running:
509
- # print("exec_ok:", virtualshell.Shell().start().execute("Write-Output 'ok'").success)
510
- PY
511
- ```
512
-
513
- ### Troubleshooting
514
-
515
- * **Cannot find MSVC/CMake:** open a *Developer Command Prompt for VS 2022* or ensure `cmake` and the MSVC toolchain are on `PATH`.
516
- * **ImportError: cannot import name `_core`:** the extension didn’t build or wasn’t placed under `virtualshell/_core.*`. Reinstall (`python -m pip install -e .` or `python -m build && pip install dist/*.whl`).
517
- * **PowerShell not found at runtime:** pass an explicit path: `Shell(powershell_path=r"C:\Program Files\PowerShell\7\pwsh.exe")`.
449
+ * Linux wheels target **manylinux_2_28** (x86_64/aarch64).
450
+ * macOS builds target **universal2** (x86_64 + arm64).
518
451
 
519
452
  ---
520
453
 
521
454
  ## Roadmap
522
455
 
523
456
  * ✅ Windows x64 wheels (3.8–3.13)
524
- * ✅ Linux x64 wheels (manylinux)
457
+ * ✅ Linux x64/aarch64 wheels (manylinux_2_28)
458
+ * ✅ macOS x86_64/arm64 wheels
525
459
  * ⏳ Streaming APIs and richer progress events
526
- * ✅ Packaging polish (`pyproject`, build matrices, GitHub Actions)
527
460
 
528
461
  ---
529
462
 
530
463
  ## License
531
464
 
532
- Apache 2.0, see [LICENSE](LICENSE) for details.
533
-
534
- ---
535
-
536
- ## Acknowledgments
537
-
538
- * Built with `pybind11`, and a lot of care around cross-platform pipes & process control.
465
+ Apache 2.0 see [LICENSE](LICENSE).
539
466
 
540
467
  ---
541
468
 
542
- *If you hit issues, please open an issue with your Python version, OS, `pwsh`/`powershell` path, and a minimal repro.*
469
+ *Issues & feedback are welcome. Please include Python version, OS, your PowerShell path (`pwsh`/`powershell`), and a minimal repro.*
@@ -0,0 +1,9 @@
1
+ virtualshell/__init__.py,sha256=tmoVoFldry6oDZzejC_9ogkNcNkMe7X-DGEM0GKupEA,912
2
+ virtualshell/_core.cp311-win_amd64.pyd,sha256=ecE7Od0Rdsoji4DBMYJxaFGbE7r_-oPf5qZ5I4m2Lr8,400384
3
+ virtualshell/_version.py,sha256=VAHPzEVbVY57udXNeljbTM8BnJ-ZHOJ6hSmLAd4CYgA,17
4
+ virtualshell/errors.py,sha256=fDblFND_Lz37HV5l6eKCkWXvrPXnI9_FfZs0bpEYFIU,196
5
+ virtualshell/shell.py,sha256=yR_i4S7DxdV-nmFop-fOnzXUAsUE52dTTkgP_uYPp2A,20910
6
+ virtualshell-1.0.1.dist-info/METADATA,sha256=zPJqTmAs3bCD9vD3RWKe458wfPAB1XMOLuoVZnIgAo0,20452
7
+ virtualshell-1.0.1.dist-info/WHEEL,sha256=oXhHG6ewLm-FNdEna2zwgy-K0KEl4claZ1ztR4VTx0I,106
8
+ virtualshell-1.0.1.dist-info/licenses/LICENSE,sha256=34HMvl-jxuw-TVFRK7do9XGJkawVmiiwmPGFfZACBpI,11548
9
+ virtualshell-1.0.1.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- virtualshell/__init__.py,sha256=8PE1B8yiMyZg2gwG18EvXt2vDEflvBeAdh7mNn58-GE,912
2
- virtualshell/_core.cp311-win_amd64.pyd,sha256=fDg1omFayGJ-bQNTsD9jf7uJJQMNjb0x8x-n2Sa8qMc,400384
3
- virtualshell/_version.py,sha256=ZgAXEMjAMZx3cZroB6PgojYwdhTZjPbU5RqZEfdYQv0,17
4
- virtualshell/errors.py,sha256=fDblFND_Lz37HV5l6eKCkWXvrPXnI9_FfZs0bpEYFIU,196
5
- virtualshell/shell.py,sha256=gMknFPVMWpQzsEbc-JX9VD0xtPHkxz5SS5TU521lP0Q,20961
6
- virtualshell-0.1.2.dist-info/METADATA,sha256=qdLeHdMI-gCwyIrAwNeN5i1S1n7A0Z6ZB6b_56Ri5mM,23684
7
- virtualshell-0.1.2.dist-info/WHEEL,sha256=oXhHG6ewLm-FNdEna2zwgy-K0KEl4claZ1ztR4VTx0I,106
8
- virtualshell-0.1.2.dist-info/licenses/LICENSE,sha256=34HMvl-jxuw-TVFRK7do9XGJkawVmiiwmPGFfZACBpI,11548
9
- virtualshell-0.1.2.dist-info/RECORD,,