virtualshell 0.1.2__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.
Binary file
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.2
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,42 +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.
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.
224
225
 
225
226
  ---
226
227
 
227
228
  ## Features
228
229
 
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
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
235
235
 
236
236
  ---
237
237
 
238
238
  ## Install
239
239
 
240
- Preview packages are published to TestPyPI:
241
-
242
240
  ```bash
243
- pip install -i https://test.pypi.org/simple/ virtualshell==0.1.2
244
- ```
245
-
246
- ### Available distributions (Windows/Linux, amd64/x86_64)
241
+ pip install virtualshell
242
+ ````
247
243
 
244
+ ### Supported platforms
248
245
 
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)
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
254
250
 
255
- Linux wheels will be added after validation (initial target: `manylinux_2_28_x86_64`).
251
+ > Requires PowerShell on `PATH` (`pwsh` preferred, `powershell` also supported).
256
252
 
257
253
  ---
258
254
 
@@ -265,88 +261,75 @@ import virtualshell
265
261
  sh = virtualshell.Shell(timeout_seconds=5).start()
266
262
 
267
263
  # 1) One-liners (sync)
268
- res = sh.execute("Write-Output 'hello'")
269
- print(res.output.strip()) # -> hello
264
+ res = sh.run("Write-Output 'hello'")
265
+ print(res.out.strip()) # -> hello
270
266
 
267
+ # 2) Async single command
268
+ fut = sh.run_async("Write-Output 'async!'")
269
+ print(fut.result().out.strip())
271
270
 
272
- # 3) Async single command
273
- fut = sh.execute_async("Write-Output 'async!'")
274
- 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)
275
274
 
276
- # 4) Scripts with positional args
277
- r = sh.execute_script(r"C:\temp\demo.ps1", args=["alpha", "42"])
278
- 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)
279
278
 
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)
283
-
284
- # 6) Context manager (auto-stop on exit)
279
+ # 5) Context manager (auto-stop on exit)
285
280
  with virtualshell.Shell(timeout_seconds=3) as s:
286
- print(s.execute("Write-Output 'inside with'").output.strip())
281
+ print(s.run("Write-Output 'inside with'").out.strip())
287
282
 
288
283
  sh.stop()
289
284
  ```
290
285
 
286
+ Another example (stateful session):
287
+
291
288
  ```python
292
289
  from virtualshell import Shell
293
290
  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
-
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']
298
294
  ```
299
295
 
300
296
  ---
301
297
 
302
- ## Python API (high-level façade)
298
+ ## API (overview)
303
299
 
304
300
  ```python
305
301
  import virtualshell
306
- from virtualshell import ExecutionResult # optional: Python dataclass view
302
+ from virtualshell import ExecutionResult # dataclass view
307
303
 
308
304
  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"})
324
-
325
- # Dotsource script
326
- res = sh.execute_script(r"C:\scripts\init.ps1", dot_source=True)
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()
327
311
 
328
- # --- Async ---
329
- f = sh.execute_async("Write-Output 'ping'")
330
- print(f.result().output.strip())
312
+ # Sync
313
+ res: ExecutionResult = sh.run("Get-Location | Select-Object -Expand Path")
331
314
 
332
- def on_done(r: ExecutionResult) -> None:
333
- print("DONE:", r.success, r.output.strip())
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)
334
319
 
335
- sh.execute_async("Write-Output 'callback!'", callback=on_done)
320
+ # Async
321
+ f = sh.run_async("Write-Output 'ping'")
322
+ f2 = sh.run_async_batch(["$PSVersionTable", "Get-Random"])
336
323
 
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
324
+ # Convenience
325
+ res = sh.pwsh("literal 'quoted' string") # safe single-quoted literal
343
326
 
344
327
  sh.stop()
345
328
  ```
346
329
 
347
- ### Return types
330
+ ### Return type
348
331
 
349
- By default, methods return a Python `ExecutionResult` dataclass:
332
+ By default you get a Python dataclass:
350
333
 
351
334
  ```python
352
335
  @dataclass(frozen=True)
@@ -358,44 +341,39 @@ class ExecutionResult:
358
341
  execution_time: float
359
342
  ```
360
343
 
361
- 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.
362
345
 
363
346
  ### Timeouts
364
347
 
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.
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++.
368
351
 
369
352
  ---
370
353
 
371
- ## Design goals (production-readiness)
354
+ ## Design notes
372
355
 
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.
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.
378
361
 
379
- ### Security notes
362
+ ### Security
380
363
 
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.
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=...)`.
384
367
 
385
- ### Performance notes
368
+ ### Performance
386
369
 
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.
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.
389
372
 
390
373
  ### Lifetime
391
374
 
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.
375
+ * `Shell.start()` ensures a running backend; `Shell.stop()` tears it down.
376
+ * `with Shell(...)` guarantees stop-on-exit, even on exceptions.
399
377
 
400
378
  ---
401
379
 
@@ -403,29 +381,34 @@ Pass `as_dataclass=False` to receive the **raw C++ result object** for zero-copy
403
381
 
404
382
  ```python
405
383
  from virtualshell.errors import (
406
- SmartShellError,
384
+ VirtualShellError,
407
385
  PowerShellNotFoundError,
408
386
  ExecutionTimeoutError,
409
387
  ExecutionError,
410
388
  )
411
389
 
412
390
  try:
413
- res = sh.execute("throw 'boom'", raise_on_error=True)
391
+ res = sh.run("throw 'boom'", raise_on_error=True)
414
392
  except ExecutionTimeoutError:
415
393
  ...
416
394
  except ExecutionError as e:
417
- print("PS failed:", e)
395
+ print("PowerShell failed:", e)
418
396
  ```
419
397
 
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`.
398
+ * `ExecutionTimeoutError` is raised on timeouts **if** `raise_on_error=True`.
399
+ * Otherwise, APIs return `ExecutionResult(success=False)`.
422
400
 
423
401
  ---
424
402
 
425
403
  ## Configuration tips
426
404
 
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:
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:
429
412
 
430
413
  ```python
431
414
  Shell(initial_commands=[
@@ -436,107 +419,43 @@ Shell(initial_commands=[
436
419
 
437
420
  ---
438
421
 
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
422
+ ## Building from source (optional)
444
423
 
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)
424
+ You normally won’t need this when using wheels.
451
425
 
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)
426
+ **Prereqs:** Python ≥3.8, C++17, CMake ≥3.20, `scikit-build-core`, `pybind11`.
455
427
 
456
428
  ```bash
457
429
  # in repo root
458
430
  python -m pip install -U pip build
459
- python -m build # produces sdist and wheel under ./dist
431
+ python -m build # -> dist/*.whl, dist/*.tar.gz
460
432
  python -m pip install dist/virtualshell-*.whl
461
433
  ```
462
434
 
463
- ### Editable/dev install
435
+ Editable install:
464
436
 
465
437
  ```bash
466
- python -m pip install -U pip
467
- python -m pip install -e . # uses scikit-build-core to build the C++ extension
438
+ python -m pip install -e .
468
439
  ```
469
440
 
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")`.
441
+ * Linux wheels target **manylinux_2_28** (x86_64/aarch64).
442
+ * macOS builds target **x86_64** and **arm64** (may be universal2).
518
443
 
519
444
  ---
520
445
 
521
446
  ## Roadmap
522
447
 
523
448
  * ✅ Windows x64 wheels (3.8–3.13)
524
- * ✅ Linux x64 wheels (manylinux)
449
+ * ✅ Linux x64/aarch64 wheels (manylinux_2_28)
450
+ * ✅ macOS x86_64/arm64 wheels
525
451
  * ⏳ Streaming APIs and richer progress events
526
- * ✅ Packaging polish (`pyproject`, build matrices, GitHub Actions)
527
452
 
528
453
  ---
529
454
 
530
455
  ## License
531
456
 
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.
457
+ Apache 2.0 see [LICENSE](LICENSE).
539
458
 
540
459
  ---
541
460
 
542
- *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=8PE1B8yiMyZg2gwG18EvXt2vDEflvBeAdh7mNn58-GE,912
2
- virtualshell/_core.cp312-win_amd64.pyd,sha256=YfykJq36il74NZVKxcpm3BEdeZdmQjJRTpWud_T41tI,407040
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=chqeLhPBtPdrOoreR34YMcofSk3yWDQhkrsDJ2n48LU,106
8
- virtualshell-0.1.2.dist-info/licenses/LICENSE,sha256=34HMvl-jxuw-TVFRK7do9XGJkawVmiiwmPGFfZACBpI,11548
9
- virtualshell-0.1.2.dist-info/RECORD,,