pocketshell 0.3.2__tar.gz → 0.3.6__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.
- {pocketshell-0.3.2 → pocketshell-0.3.6}/PKG-INFO +79 -7
- {pocketshell-0.3.2 → pocketshell-0.3.6}/README.md +78 -6
- {pocketshell-0.3.2 → pocketshell-0.3.6}/pyproject.toml +1 -1
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/__init__.py +1 -1
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/cli.py +6 -0
- pocketshell-0.3.6/src/pocketshell/env.py +681 -0
- pocketshell-0.3.6/src/pocketshell/hooks.py +926 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/jobs.py +4 -4
- pocketshell-0.3.6/src/pocketshell/logs.py +668 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/sessions.py +4 -4
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/usage.py +4 -4
- pocketshell-0.3.6/tests/test_env.py +415 -0
- pocketshell-0.3.6/tests/test_hooks.py +521 -0
- pocketshell-0.3.6/tests/test_logs.py +346 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/uv.lock +2 -2
- {pocketshell-0.3.2 → pocketshell-0.3.6}/.gitignore +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/__main__.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/agent_log.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/daemon.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/qr_share.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/src/pocketshell/repos.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/__init__.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/test_agent_log.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/test_daemon.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/test_jobs.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/test_qr_share.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/test_repos.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/test_sessions.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.6}/tests/test_usage.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pocketshell
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
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
|
|
@@ -173,6 +173,75 @@ Requires the optional `qr` extra (see [Optional extras](#optional-extras)).
|
|
|
173
173
|
Without it, the command exits 127 with the install hint and every other
|
|
174
174
|
subcommand keeps working.
|
|
175
175
|
|
|
176
|
+
#### Running from a repo clone (no install)
|
|
177
|
+
|
|
178
|
+
To run `qr-share` straight from a checkout without installing the tool,
|
|
179
|
+
use `uv run` from `tools/pocketshell` and include the `qr` extra:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
cd tools/pocketshell
|
|
183
|
+
uv run --extra qr pocketshell qr-share prod
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The first run creates `.venv` and installs the QR dependency; later runs
|
|
187
|
+
are instant. Run it in an interactive terminal so stdout is a TTY and the
|
|
188
|
+
QR renders inline — otherwise it falls back to writing PNGs (add
|
|
189
|
+
`--png --out-dir ./qr` to force PNGs). Omitting `--extra qr` makes the
|
|
190
|
+
command exit 127 with the install hint.
|
|
191
|
+
|
|
192
|
+
### `pocketshell hooks`
|
|
193
|
+
|
|
194
|
+
Installs agent **stop / idle-detection** hooks across Claude Code,
|
|
195
|
+
Codex, and OpenCode and normalizes their events into a single
|
|
196
|
+
append-only JSONL bus the app can read back. Server-side only;
|
|
197
|
+
integration only — no "tell the agent to continue" action yet (deferred;
|
|
198
|
+
see issue #267 and locked decision **D26** in `docs/decisions.md`).
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
pocketshell hooks install [--engine claude|codex|opencode|all] # default: all
|
|
202
|
+
pocketshell hooks status [--engine ...] [--json] [--last N]
|
|
203
|
+
pocketshell hooks events [--since ISO8601] [--limit N] [--json]
|
|
204
|
+
pocketshell hooks uninstall [--engine ...]
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
`install` is **non-destructive — it merges, it never clobbers**:
|
|
208
|
+
|
|
209
|
+
- **Claude Code** — adds a `{type: "command", command: "python3 <handler>"}`
|
|
210
|
+
entry under the `Stop`, `SubagentStop`, and `Notification` hook events
|
|
211
|
+
in `~/.claude/settings.json`, only when absent. All other top-level
|
|
212
|
+
keys and any pre-existing user hooks are preserved.
|
|
213
|
+
- **Codex** — sets the top-level `notify` program in `~/.codex/config.toml`
|
|
214
|
+
to our handler (Codex hooks do not fire under `codex exec`, so `notify`
|
|
215
|
+
is the headless-safe signal). If `notify` is already set to something
|
|
216
|
+
else, it warns and **skips** rather than overwriting. The rest of the
|
|
217
|
+
TOML is preserved.
|
|
218
|
+
- **OpenCode** — drops a `pocketshell-idle-signal.js` plugin into
|
|
219
|
+
`~/.config/opencode/plugin/` without disturbing other plugins.
|
|
220
|
+
|
|
221
|
+
`install` is idempotent (running twice adds nothing new). Handler scripts
|
|
222
|
+
and the event bus live under `~/.cache/pocketshell/hooks/` (override with
|
|
223
|
+
`$POCKETSHELL_HOOKS_DIR`); each handler appends a normalized record
|
|
224
|
+
`{ts, engine, state, source, session_id, cwd, ...}` to
|
|
225
|
+
`events.jsonl`.
|
|
226
|
+
|
|
227
|
+
**Per-engine uninstall** (`pocketshell hooks uninstall`) removes only what
|
|
228
|
+
we added and is idempotent:
|
|
229
|
+
|
|
230
|
+
- **Claude Code** — drops our command group from each hook event; an
|
|
231
|
+
event key (and the top-level `hooks` object) is deleted only if we
|
|
232
|
+
created it and it ends up empty. A user's pre-existing hooks always
|
|
233
|
+
survive, so a pre-populated `settings.json` comes back
|
|
234
|
+
byte-equivalent for the unrelated parts.
|
|
235
|
+
- **Codex** — removes the top-level `notify` line only when it still
|
|
236
|
+
points at our handler. A `notify` the user pointed elsewhere is left
|
|
237
|
+
alone.
|
|
238
|
+
- **OpenCode** — deletes our plugin file; other plugins and the dir
|
|
239
|
+
itself are left in place.
|
|
240
|
+
|
|
241
|
+
The event bus (`events.jsonl`) is preserved on uninstall so
|
|
242
|
+
already-emitted records stay readable; only the generated handler
|
|
243
|
+
scripts are cleaned up.
|
|
244
|
+
|
|
176
245
|
## Development
|
|
177
246
|
|
|
178
247
|
```bash
|
|
@@ -297,10 +366,13 @@ as a permanent fallback.
|
|
|
297
366
|
|
|
298
367
|
The PocketShell app previously probed for two binaries (`quse`,
|
|
299
368
|
`tmuxctl`) on every host. That meant two installs to keep up to date,
|
|
300
|
-
two probes to surface failures from, and two PATH-discovery edge cases
|
|
301
|
-
(see [issue #41](https://github.com/alexeygrigorev/pocketshell/issues/41)).
|
|
369
|
+
two probes to surface failures from, and two PATH-discovery edge cases.
|
|
302
370
|
A single `pocketshell` binary collapses those into one install, one
|
|
303
|
-
probe, one bootstrap row. The
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
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`).
|
|
@@ -145,6 +145,75 @@ Requires the optional `qr` extra (see [Optional extras](#optional-extras)).
|
|
|
145
145
|
Without it, the command exits 127 with the install hint and every other
|
|
146
146
|
subcommand keeps working.
|
|
147
147
|
|
|
148
|
+
#### Running from a repo clone (no install)
|
|
149
|
+
|
|
150
|
+
To run `qr-share` straight from a checkout without installing the tool,
|
|
151
|
+
use `uv run` from `tools/pocketshell` and include the `qr` extra:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
cd tools/pocketshell
|
|
155
|
+
uv run --extra qr pocketshell qr-share prod
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
The first run creates `.venv` and installs the QR dependency; later runs
|
|
159
|
+
are instant. Run it in an interactive terminal so stdout is a TTY and the
|
|
160
|
+
QR renders inline — otherwise it falls back to writing PNGs (add
|
|
161
|
+
`--png --out-dir ./qr` to force PNGs). Omitting `--extra qr` makes the
|
|
162
|
+
command exit 127 with the install hint.
|
|
163
|
+
|
|
164
|
+
### `pocketshell hooks`
|
|
165
|
+
|
|
166
|
+
Installs agent **stop / idle-detection** hooks across Claude Code,
|
|
167
|
+
Codex, and OpenCode and normalizes their events into a single
|
|
168
|
+
append-only JSONL bus the app can read back. Server-side only;
|
|
169
|
+
integration only — no "tell the agent to continue" action yet (deferred;
|
|
170
|
+
see issue #267 and locked decision **D26** in `docs/decisions.md`).
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
pocketshell hooks install [--engine claude|codex|opencode|all] # default: all
|
|
174
|
+
pocketshell hooks status [--engine ...] [--json] [--last N]
|
|
175
|
+
pocketshell hooks events [--since ISO8601] [--limit N] [--json]
|
|
176
|
+
pocketshell hooks uninstall [--engine ...]
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
`install` is **non-destructive — it merges, it never clobbers**:
|
|
180
|
+
|
|
181
|
+
- **Claude Code** — adds a `{type: "command", command: "python3 <handler>"}`
|
|
182
|
+
entry under the `Stop`, `SubagentStop`, and `Notification` hook events
|
|
183
|
+
in `~/.claude/settings.json`, only when absent. All other top-level
|
|
184
|
+
keys and any pre-existing user hooks are preserved.
|
|
185
|
+
- **Codex** — sets the top-level `notify` program in `~/.codex/config.toml`
|
|
186
|
+
to our handler (Codex hooks do not fire under `codex exec`, so `notify`
|
|
187
|
+
is the headless-safe signal). If `notify` is already set to something
|
|
188
|
+
else, it warns and **skips** rather than overwriting. The rest of the
|
|
189
|
+
TOML is preserved.
|
|
190
|
+
- **OpenCode** — drops a `pocketshell-idle-signal.js` plugin into
|
|
191
|
+
`~/.config/opencode/plugin/` without disturbing other plugins.
|
|
192
|
+
|
|
193
|
+
`install` is idempotent (running twice adds nothing new). Handler scripts
|
|
194
|
+
and the event bus live under `~/.cache/pocketshell/hooks/` (override with
|
|
195
|
+
`$POCKETSHELL_HOOKS_DIR`); each handler appends a normalized record
|
|
196
|
+
`{ts, engine, state, source, session_id, cwd, ...}` to
|
|
197
|
+
`events.jsonl`.
|
|
198
|
+
|
|
199
|
+
**Per-engine uninstall** (`pocketshell hooks uninstall`) removes only what
|
|
200
|
+
we added and is idempotent:
|
|
201
|
+
|
|
202
|
+
- **Claude Code** — drops our command group from each hook event; an
|
|
203
|
+
event key (and the top-level `hooks` object) is deleted only if we
|
|
204
|
+
created it and it ends up empty. A user's pre-existing hooks always
|
|
205
|
+
survive, so a pre-populated `settings.json` comes back
|
|
206
|
+
byte-equivalent for the unrelated parts.
|
|
207
|
+
- **Codex** — removes the top-level `notify` line only when it still
|
|
208
|
+
points at our handler. A `notify` the user pointed elsewhere is left
|
|
209
|
+
alone.
|
|
210
|
+
- **OpenCode** — deletes our plugin file; other plugins and the dir
|
|
211
|
+
itself are left in place.
|
|
212
|
+
|
|
213
|
+
The event bus (`events.jsonl`) is preserved on uninstall so
|
|
214
|
+
already-emitted records stay readable; only the generated handler
|
|
215
|
+
scripts are cleaned up.
|
|
216
|
+
|
|
148
217
|
## Development
|
|
149
218
|
|
|
150
219
|
```bash
|
|
@@ -269,10 +338,13 @@ as a permanent fallback.
|
|
|
269
338
|
|
|
270
339
|
The PocketShell app previously probed for two binaries (`quse`,
|
|
271
340
|
`tmuxctl`) on every host. That meant two installs to keep up to date,
|
|
272
|
-
two probes to surface failures from, and two PATH-discovery edge cases
|
|
273
|
-
(see [issue #41](https://github.com/alexeygrigorev/pocketshell/issues/41)).
|
|
341
|
+
two probes to surface failures from, and two PATH-discovery edge cases.
|
|
274
342
|
A single `pocketshell` binary collapses those into one install, one
|
|
275
|
-
probe, one bootstrap row. The
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
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`).
|
|
@@ -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.
|
|
11
|
+
version = "0.3.6"
|
|
12
12
|
description = "Unified server-side Python utility for the PocketShell Android client."
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
requires-python = ">=3.11"
|
|
@@ -23,7 +23,10 @@ import click
|
|
|
23
23
|
|
|
24
24
|
from pocketshell import __version__
|
|
25
25
|
from pocketshell.agent_log import agent_log_command
|
|
26
|
+
from pocketshell.env import env_group
|
|
27
|
+
from pocketshell.hooks import hooks_group
|
|
26
28
|
from pocketshell.jobs import jobs_group
|
|
29
|
+
from pocketshell.logs import logs_group
|
|
27
30
|
from pocketshell.qr_share import qr_share_command
|
|
28
31
|
from pocketshell.repos import repos_group
|
|
29
32
|
from pocketshell.sessions import sessions_group
|
|
@@ -50,6 +53,9 @@ cli.add_command(jobs_group, name="jobs")
|
|
|
50
53
|
cli.add_command(sessions_group, name="sessions")
|
|
51
54
|
cli.add_command(agent_log_command, name="agent-log")
|
|
52
55
|
cli.add_command(repos_group, name="repos")
|
|
56
|
+
cli.add_command(env_group, name="env")
|
|
57
|
+
cli.add_command(hooks_group, name="hooks")
|
|
58
|
+
cli.add_command(logs_group, name="logs")
|
|
53
59
|
cli.add_command(qr_share_command, name="qr-share")
|
|
54
60
|
|
|
55
61
|
|