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