pocketshell 0.3.2__tar.gz → 0.3.5__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.5}/PKG-INFO +54 -1
- {pocketshell-0.3.2 → pocketshell-0.3.5}/README.md +53 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/pyproject.toml +1 -1
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/cli.py +4 -0
- pocketshell-0.3.5/src/pocketshell/env.py +681 -0
- pocketshell-0.3.5/src/pocketshell/hooks.py +926 -0
- pocketshell-0.3.5/tests/test_env.py +415 -0
- pocketshell-0.3.5/tests/test_hooks.py +521 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/uv.lock +1 -1
- {pocketshell-0.3.2 → pocketshell-0.3.5}/.gitignore +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/__init__.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/__main__.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/agent_log.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/daemon.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/jobs.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/qr_share.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/repos.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/sessions.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/src/pocketshell/usage.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/tests/__init__.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/tests/test_agent_log.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/tests/test_daemon.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/tests/test_jobs.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/tests/test_qr_share.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/tests/test_repos.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/tests/test_sessions.py +0 -0
- {pocketshell-0.3.2 → pocketshell-0.3.5}/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.5
|
|
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,59 @@ 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
|
+
### `pocketshell hooks`
|
|
177
|
+
|
|
178
|
+
Installs agent **stop / idle-detection** hooks across Claude Code,
|
|
179
|
+
Codex, and OpenCode and normalizes their events into a single
|
|
180
|
+
append-only JSONL bus the app can read back. Server-side only;
|
|
181
|
+
integration only — no "tell the agent to continue" action yet (deferred;
|
|
182
|
+
see issue #267 and locked decision **D26** in `docs/decisions.md`).
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
pocketshell hooks install [--engine claude|codex|opencode|all] # default: all
|
|
186
|
+
pocketshell hooks status [--engine ...] [--json] [--last N]
|
|
187
|
+
pocketshell hooks events [--since ISO8601] [--limit N] [--json]
|
|
188
|
+
pocketshell hooks uninstall [--engine ...]
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
`install` is **non-destructive — it merges, it never clobbers**:
|
|
192
|
+
|
|
193
|
+
- **Claude Code** — adds a `{type: "command", command: "python3 <handler>"}`
|
|
194
|
+
entry under the `Stop`, `SubagentStop`, and `Notification` hook events
|
|
195
|
+
in `~/.claude/settings.json`, only when absent. All other top-level
|
|
196
|
+
keys and any pre-existing user hooks are preserved.
|
|
197
|
+
- **Codex** — sets the top-level `notify` program in `~/.codex/config.toml`
|
|
198
|
+
to our handler (Codex hooks do not fire under `codex exec`, so `notify`
|
|
199
|
+
is the headless-safe signal). If `notify` is already set to something
|
|
200
|
+
else, it warns and **skips** rather than overwriting. The rest of the
|
|
201
|
+
TOML is preserved.
|
|
202
|
+
- **OpenCode** — drops a `pocketshell-idle-signal.js` plugin into
|
|
203
|
+
`~/.config/opencode/plugin/` without disturbing other plugins.
|
|
204
|
+
|
|
205
|
+
`install` is idempotent (running twice adds nothing new). Handler scripts
|
|
206
|
+
and the event bus live under `~/.cache/pocketshell/hooks/` (override with
|
|
207
|
+
`$POCKETSHELL_HOOKS_DIR`); each handler appends a normalized record
|
|
208
|
+
`{ts, engine, state, source, session_id, cwd, ...}` to
|
|
209
|
+
`events.jsonl`.
|
|
210
|
+
|
|
211
|
+
**Per-engine uninstall** (`pocketshell hooks uninstall`) removes only what
|
|
212
|
+
we added and is idempotent:
|
|
213
|
+
|
|
214
|
+
- **Claude Code** — drops our command group from each hook event; an
|
|
215
|
+
event key (and the top-level `hooks` object) is deleted only if we
|
|
216
|
+
created it and it ends up empty. A user's pre-existing hooks always
|
|
217
|
+
survive, so a pre-populated `settings.json` comes back
|
|
218
|
+
byte-equivalent for the unrelated parts.
|
|
219
|
+
- **Codex** — removes the top-level `notify` line only when it still
|
|
220
|
+
points at our handler. A `notify` the user pointed elsewhere is left
|
|
221
|
+
alone.
|
|
222
|
+
- **OpenCode** — deletes our plugin file; other plugins and the dir
|
|
223
|
+
itself are left in place.
|
|
224
|
+
|
|
225
|
+
The event bus (`events.jsonl`) is preserved on uninstall so
|
|
226
|
+
already-emitted records stay readable; only the generated handler
|
|
227
|
+
scripts are cleaned up.
|
|
228
|
+
|
|
176
229
|
## Development
|
|
177
230
|
|
|
178
231
|
```bash
|
|
@@ -145,6 +145,59 @@ 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
|
+
### `pocketshell hooks`
|
|
149
|
+
|
|
150
|
+
Installs agent **stop / idle-detection** hooks across Claude Code,
|
|
151
|
+
Codex, and OpenCode and normalizes their events into a single
|
|
152
|
+
append-only JSONL bus the app can read back. Server-side only;
|
|
153
|
+
integration only — no "tell the agent to continue" action yet (deferred;
|
|
154
|
+
see issue #267 and locked decision **D26** in `docs/decisions.md`).
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
pocketshell hooks install [--engine claude|codex|opencode|all] # default: all
|
|
158
|
+
pocketshell hooks status [--engine ...] [--json] [--last N]
|
|
159
|
+
pocketshell hooks events [--since ISO8601] [--limit N] [--json]
|
|
160
|
+
pocketshell hooks uninstall [--engine ...]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`install` is **non-destructive — it merges, it never clobbers**:
|
|
164
|
+
|
|
165
|
+
- **Claude Code** — adds a `{type: "command", command: "python3 <handler>"}`
|
|
166
|
+
entry under the `Stop`, `SubagentStop`, and `Notification` hook events
|
|
167
|
+
in `~/.claude/settings.json`, only when absent. All other top-level
|
|
168
|
+
keys and any pre-existing user hooks are preserved.
|
|
169
|
+
- **Codex** — sets the top-level `notify` program in `~/.codex/config.toml`
|
|
170
|
+
to our handler (Codex hooks do not fire under `codex exec`, so `notify`
|
|
171
|
+
is the headless-safe signal). If `notify` is already set to something
|
|
172
|
+
else, it warns and **skips** rather than overwriting. The rest of the
|
|
173
|
+
TOML is preserved.
|
|
174
|
+
- **OpenCode** — drops a `pocketshell-idle-signal.js` plugin into
|
|
175
|
+
`~/.config/opencode/plugin/` without disturbing other plugins.
|
|
176
|
+
|
|
177
|
+
`install` is idempotent (running twice adds nothing new). Handler scripts
|
|
178
|
+
and the event bus live under `~/.cache/pocketshell/hooks/` (override with
|
|
179
|
+
`$POCKETSHELL_HOOKS_DIR`); each handler appends a normalized record
|
|
180
|
+
`{ts, engine, state, source, session_id, cwd, ...}` to
|
|
181
|
+
`events.jsonl`.
|
|
182
|
+
|
|
183
|
+
**Per-engine uninstall** (`pocketshell hooks uninstall`) removes only what
|
|
184
|
+
we added and is idempotent:
|
|
185
|
+
|
|
186
|
+
- **Claude Code** — drops our command group from each hook event; an
|
|
187
|
+
event key (and the top-level `hooks` object) is deleted only if we
|
|
188
|
+
created it and it ends up empty. A user's pre-existing hooks always
|
|
189
|
+
survive, so a pre-populated `settings.json` comes back
|
|
190
|
+
byte-equivalent for the unrelated parts.
|
|
191
|
+
- **Codex** — removes the top-level `notify` line only when it still
|
|
192
|
+
points at our handler. A `notify` the user pointed elsewhere is left
|
|
193
|
+
alone.
|
|
194
|
+
- **OpenCode** — deletes our plugin file; other plugins and the dir
|
|
195
|
+
itself are left in place.
|
|
196
|
+
|
|
197
|
+
The event bus (`events.jsonl`) is preserved on uninstall so
|
|
198
|
+
already-emitted records stay readable; only the generated handler
|
|
199
|
+
scripts are cleaned up.
|
|
200
|
+
|
|
148
201
|
## Development
|
|
149
202
|
|
|
150
203
|
```bash
|
|
@@ -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.5"
|
|
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,6 +23,8 @@ 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
|
|
27
29
|
from pocketshell.qr_share import qr_share_command
|
|
28
30
|
from pocketshell.repos import repos_group
|
|
@@ -50,6 +52,8 @@ cli.add_command(jobs_group, name="jobs")
|
|
|
50
52
|
cli.add_command(sessions_group, name="sessions")
|
|
51
53
|
cli.add_command(agent_log_command, name="agent-log")
|
|
52
54
|
cli.add_command(repos_group, name="repos")
|
|
55
|
+
cli.add_command(env_group, name="env")
|
|
56
|
+
cli.add_command(hooks_group, name="hooks")
|
|
53
57
|
cli.add_command(qr_share_command, name="qr-share")
|
|
54
58
|
|
|
55
59
|
|