pocketshell 0.3.7__tar.gz → 0.3.9__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 (30) hide show
  1. {pocketshell-0.3.7 → pocketshell-0.3.9}/PKG-INFO +40 -28
  2. {pocketshell-0.3.7 → pocketshell-0.3.9}/README.md +39 -27
  3. {pocketshell-0.3.7 → pocketshell-0.3.9}/pyproject.toml +1 -1
  4. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/__init__.py +16 -1
  5. pocketshell-0.3.9/tests/test_cli.py +27 -0
  6. {pocketshell-0.3.7 → pocketshell-0.3.9}/uv.lock +1 -1
  7. {pocketshell-0.3.7 → pocketshell-0.3.9}/.gitignore +0 -0
  8. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/__main__.py +0 -0
  9. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/agent_log.py +0 -0
  10. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/cli.py +0 -0
  11. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/daemon.py +0 -0
  12. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/env.py +0 -0
  13. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/hooks.py +0 -0
  14. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/jobs.py +0 -0
  15. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/logs.py +0 -0
  16. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/qr_share.py +0 -0
  17. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/repos.py +0 -0
  18. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/sessions.py +0 -0
  19. {pocketshell-0.3.7 → pocketshell-0.3.9}/src/pocketshell/usage.py +0 -0
  20. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/__init__.py +0 -0
  21. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_agent_log.py +0 -0
  22. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_daemon.py +0 -0
  23. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_env.py +0 -0
  24. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_hooks.py +0 -0
  25. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_jobs.py +0 -0
  26. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_logs.py +0 -0
  27. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_qr_share.py +0 -0
  28. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_repos.py +0 -0
  29. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_sessions.py +0 -0
  30. {pocketshell-0.3.7 → pocketshell-0.3.9}/tests/test_usage.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pocketshell
3
- Version: 0.3.7
3
+ Version: 0.3.9
4
4
  Summary: Unified server-side Python utility for the PocketShell Android client.
5
5
  Project-URL: Homepage, https://github.com/alexeygrigorev/pocketshell
6
6
  Project-URL: Issues, https://github.com/alexeygrigorev/pocketshell/issues
@@ -29,14 +29,10 @@ Description-Content-Type: text/markdown
29
29
  # pocketshell
30
30
 
31
31
  Unified server-side Python utility for the [PocketShell](https://github.com/alexeygrigorev/pocketshell)
32
- Android client. Replaces the separately-installed `quse` and `tmuxctl`
33
- utilities the app currently probes for on every remote host.
34
-
35
- This first release ships the **skeleton plus the `pocketshell usage`
36
- subcommand only**. Follow-up rounds will add `jobs`, `agent-log`,
37
- `sessions`, `repos`, and an optional daemon mode. See
38
- [issue #170](https://github.com/alexeygrigorev/pocketshell/issues/170) for
39
- the design spike and phased roll-out plan.
32
+ Android client. The app probes for this single helper on each remote
33
+ host and uses its subcommands for usage, tmux session/job metadata,
34
+ agent conversations, QR host setup, repository discovery, environment
35
+ files, hooks, logs, and daemon lifecycle checks.
40
36
 
41
37
  ## Install
42
38
 
@@ -77,18 +73,38 @@ Without the extra, every other subcommand keeps working; only
77
73
 
78
74
  ## Usage
79
75
 
76
+ Top-level commands in the current helper:
77
+
78
+ ```text
79
+ pocketshell usage [provider] [--json] # provider quota / usage
80
+ pocketshell sessions list [--by activity] # tmux session summaries
81
+ pocketshell jobs ... # tmux recurring jobs
82
+ pocketshell agent-log ... # agent conversation logs
83
+ pocketshell repos list ... # local / GitHub repositories
84
+ pocketshell env ... # .env / .envrc management
85
+ pocketshell hooks ... # Claude/Codex/OpenCode hooks
86
+ pocketshell logs ... # server-side trace sink
87
+ pocketshell daemon ... # IPC daemon lifecycle
88
+ pocketshell qr-share ... # SSH host QR import payloads
89
+ ```
90
+
91
+ Run `pocketshell --help` or `pocketshell <command> --help` for the live
92
+ flag set. Some parity subcommands still proxy through the existing host
93
+ tools internally so their output remains byte-identical to what the app
94
+ already parses.
95
+
96
+ ### `pocketshell usage`
97
+
80
98
  ```text
81
99
  pocketshell usage # human-readable lines, one per provider
82
100
  pocketshell usage --json # machine-readable JSON (consumed by the app)
83
101
  pocketshell usage codex # filter to a single provider
84
102
  ```
85
103
 
86
- The output shape is byte-identical to `quse [provider] [--json]` so any
87
- consumer that already parses `quse` output keeps working when the app
88
- routes through `pocketshell usage` instead. Under the hood the first
89
- release delegates to the `quse` CLI via subprocess; later rounds will
90
- fold the provider-detection logic in directly and drop the subprocess
91
- hop.
104
+ The output shape is byte-identical to `quse [provider] [--json]`. When
105
+ the IPC daemon is running, `usage --json` dispatches `usage.fetch` over
106
+ the daemon socket and uses the daemon's short TTL cache; otherwise it
107
+ falls through to the one-shot subprocess path.
92
108
 
93
109
  If `quse` is not installed, `pocketshell usage` exits with code 127 and
94
110
  prints an install hint to stderr.
@@ -284,7 +300,7 @@ Run it locally before tagging:
284
300
 
285
301
  ```bash
286
302
  scripts/check-pypi-version.sh # local match check
287
- scripts/check-pypi-version.sh --check-tag v0.3.0
303
+ scripts/check-pypi-version.sh --check-tag vX.Y.Z
288
304
  ```
289
305
 
290
306
  ### Bumping a release
@@ -364,15 +380,11 @@ as a permanent fallback.
364
380
 
365
381
  ## Why a unified CLI?
366
382
 
367
- The PocketShell app previously probed for two binaries (`quse`,
368
- `tmuxctl`) on every host. That meant two installs to keep up to date,
369
- two probes to surface failures from, and two PATH-discovery edge cases.
370
- A single `pocketshell` binary collapses those into one install, one
371
- probe, one bootstrap row. The Android bootstrap probe now derives PATH
372
- from the user's shell rc and prepends `$HOME/.local/bin`, `$HOME/bin`,
373
- and `$HOME/.cargo/bin` before probing, so cloned-repo or venv installs
374
- can be discovered without a manual app-side PATH field. The app keeps
375
- detecting `quse` and `tmuxctl` as a parallel path while `pocketshell`
376
- ramps up to feature parity; once parity is reached, the legacy probes
377
- are removed in a hard-cut follow-up (no compat shim — see decision D22
378
- in `docs/decisions.md`).
383
+ The PocketShell app previously depended on multiple host-side tools.
384
+ That meant separate installs to keep up to date, separate probes to
385
+ surface failures from, and multiple PATH-discovery edge cases. A single
386
+ `pocketshell` binary collapses that app-facing contract into one install,
387
+ one probe, and one bootstrap row. The Android bootstrap probe now derives
388
+ PATH from the user's shell rc and prepends `$HOME/.local/bin`,
389
+ `$HOME/bin`, and `$HOME/.cargo/bin` before probing, so cloned-repo or
390
+ venv installs can be discovered without a manual app-side PATH field.
@@ -1,14 +1,10 @@
1
1
  # pocketshell
2
2
 
3
3
  Unified server-side Python utility for the [PocketShell](https://github.com/alexeygrigorev/pocketshell)
4
- Android client. Replaces the separately-installed `quse` and `tmuxctl`
5
- utilities the app currently probes for on every remote host.
6
-
7
- This first release ships the **skeleton plus the `pocketshell usage`
8
- subcommand only**. Follow-up rounds will add `jobs`, `agent-log`,
9
- `sessions`, `repos`, and an optional daemon mode. See
10
- [issue #170](https://github.com/alexeygrigorev/pocketshell/issues/170) for
11
- the design spike and phased roll-out plan.
4
+ Android client. The app probes for this single helper on each remote
5
+ host and uses its subcommands for usage, tmux session/job metadata,
6
+ agent conversations, QR host setup, repository discovery, environment
7
+ files, hooks, logs, and daemon lifecycle checks.
12
8
 
13
9
  ## Install
14
10
 
@@ -49,18 +45,38 @@ Without the extra, every other subcommand keeps working; only
49
45
 
50
46
  ## Usage
51
47
 
48
+ Top-level commands in the current helper:
49
+
50
+ ```text
51
+ pocketshell usage [provider] [--json] # provider quota / usage
52
+ pocketshell sessions list [--by activity] # tmux session summaries
53
+ pocketshell jobs ... # tmux recurring jobs
54
+ pocketshell agent-log ... # agent conversation logs
55
+ pocketshell repos list ... # local / GitHub repositories
56
+ pocketshell env ... # .env / .envrc management
57
+ pocketshell hooks ... # Claude/Codex/OpenCode hooks
58
+ pocketshell logs ... # server-side trace sink
59
+ pocketshell daemon ... # IPC daemon lifecycle
60
+ pocketshell qr-share ... # SSH host QR import payloads
61
+ ```
62
+
63
+ Run `pocketshell --help` or `pocketshell <command> --help` for the live
64
+ flag set. Some parity subcommands still proxy through the existing host
65
+ tools internally so their output remains byte-identical to what the app
66
+ already parses.
67
+
68
+ ### `pocketshell usage`
69
+
52
70
  ```text
53
71
  pocketshell usage # human-readable lines, one per provider
54
72
  pocketshell usage --json # machine-readable JSON (consumed by the app)
55
73
  pocketshell usage codex # filter to a single provider
56
74
  ```
57
75
 
58
- The output shape is byte-identical to `quse [provider] [--json]` so any
59
- consumer that already parses `quse` output keeps working when the app
60
- routes through `pocketshell usage` instead. Under the hood the first
61
- release delegates to the `quse` CLI via subprocess; later rounds will
62
- fold the provider-detection logic in directly and drop the subprocess
63
- hop.
76
+ The output shape is byte-identical to `quse [provider] [--json]`. When
77
+ the IPC daemon is running, `usage --json` dispatches `usage.fetch` over
78
+ the daemon socket and uses the daemon's short TTL cache; otherwise it
79
+ falls through to the one-shot subprocess path.
64
80
 
65
81
  If `quse` is not installed, `pocketshell usage` exits with code 127 and
66
82
  prints an install hint to stderr.
@@ -256,7 +272,7 @@ Run it locally before tagging:
256
272
 
257
273
  ```bash
258
274
  scripts/check-pypi-version.sh # local match check
259
- scripts/check-pypi-version.sh --check-tag v0.3.0
275
+ scripts/check-pypi-version.sh --check-tag vX.Y.Z
260
276
  ```
261
277
 
262
278
  ### Bumping a release
@@ -336,15 +352,11 @@ as a permanent fallback.
336
352
 
337
353
  ## Why a unified CLI?
338
354
 
339
- The PocketShell app previously probed for two binaries (`quse`,
340
- `tmuxctl`) on every host. That meant two installs to keep up to date,
341
- two probes to surface failures from, and two PATH-discovery edge cases.
342
- A single `pocketshell` binary collapses those into one install, one
343
- probe, one bootstrap row. The Android bootstrap probe now derives PATH
344
- from the user's shell rc and prepends `$HOME/.local/bin`, `$HOME/bin`,
345
- and `$HOME/.cargo/bin` before probing, so cloned-repo or venv installs
346
- can be discovered without a manual app-side PATH field. The app keeps
347
- detecting `quse` and `tmuxctl` as a parallel path while `pocketshell`
348
- ramps up to feature parity; once parity is reached, the legacy probes
349
- are removed in a hard-cut follow-up (no compat shim — see decision D22
350
- in `docs/decisions.md`).
355
+ The PocketShell app previously depended on multiple host-side tools.
356
+ That meant separate installs to keep up to date, separate probes to
357
+ surface failures from, and multiple PATH-discovery edge cases. A single
358
+ `pocketshell` binary collapses that app-facing contract into one install,
359
+ one probe, and one bootstrap row. The Android bootstrap probe now derives
360
+ PATH from the user's shell rc and prepends `$HOME/.local/bin`,
361
+ `$HOME/bin`, and `$HOME/.cargo/bin` before probing, so cloned-repo or
362
+ venv installs can be discovered without a manual app-side PATH field.
@@ -8,7 +8,7 @@ name = "pocketshell"
8
8
  # scripts/check-pypi-version.sh enforces this; .github/workflows/build.yml
9
9
  # runs that check before publishing to PyPI. See
10
10
  # tools/pocketshell/README.md ("Release flow") for the bump procedure.
11
- version = "0.3.7"
11
+ version = "0.3.9"
12
12
  description = "Unified server-side Python utility for the PocketShell Android client."
13
13
  readme = "README.md"
14
14
  requires-python = ">=3.11"
@@ -10,5 +10,20 @@ See https://github.com/alexeygrigorev/pocketshell/issues/170.
10
10
 
11
11
  from __future__ import annotations
12
12
 
13
+ import tomllib
14
+ from importlib.metadata import PackageNotFoundError, version
15
+ from pathlib import Path
16
+
13
17
  __all__ = ["__version__"]
14
- __version__ = "0.3.6"
18
+
19
+
20
+ def _metadata_version() -> str:
21
+ try:
22
+ return version("pocketshell")
23
+ except PackageNotFoundError:
24
+ pyproject = Path(__file__).resolve().parents[2] / "pyproject.toml"
25
+ with pyproject.open("rb") as handle:
26
+ return tomllib.load(handle)["project"]["version"]
27
+
28
+
29
+ __version__ = _metadata_version()
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ import tomllib
4
+ from pathlib import Path
5
+
6
+ from click.testing import CliRunner
7
+
8
+ from pocketshell import __version__
9
+ from pocketshell.cli import cli
10
+
11
+
12
+ def _pyproject_version() -> str:
13
+ pyproject = Path(__file__).resolve().parents[1] / "pyproject.toml"
14
+ with pyproject.open("rb") as handle:
15
+ return tomllib.load(handle)["project"]["version"]
16
+
17
+
18
+ def test_internal_version_matches_pyproject_metadata() -> None:
19
+ assert __version__ == _pyproject_version()
20
+
21
+
22
+ def test_top_level_version_matches_pyproject_metadata() -> None:
23
+ runner = CliRunner()
24
+ result = runner.invoke(cli, ["--version"])
25
+
26
+ assert result.exit_code == 0, result.output
27
+ assert result.output == f"pocketshell, version {_pyproject_version()}\n"
@@ -143,7 +143,7 @@ wheels = [
143
143
 
144
144
  [[package]]
145
145
  name = "pocketshell"
146
- version = "0.3.6"
146
+ version = "0.3.9"
147
147
  source = { editable = "." }
148
148
  dependencies = [
149
149
  { name = "click" },
File without changes