pocketshell 0.4.9__tar.gz → 0.4.11__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.4.9 → pocketshell-0.4.11}/PKG-INFO +1 -1
- {pocketshell-0.4.9 → pocketshell-0.4.11}/pyproject.toml +1 -1
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/cli.py +2 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/daemon.py +42 -0
- pocketshell-0.4.11/src/pocketshell/tree.py +620 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/usage.py +28 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_daemon.py +50 -0
- pocketshell-0.4.11/tests/test_tree.py +353 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_usage.py +89 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/.gitignore +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/README.md +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/scheduler/README.md +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/scheduler/pocketshell-usage-capture.service +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/scheduler/pocketshell-usage-capture.timer +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/__init__.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/__main__.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/agent_log.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/agents.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/agents_kind.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/cgroup_agents.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/env.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/github.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/hooks.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/jobs.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/logs.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/profiles.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/prune_attachments.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/push.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/qr_share.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/repos.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/resume.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/sessions.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/usage_capture.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/usage_reset.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/__init__.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_agent_log.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_agents.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_agents_kind.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_cgroup_agents.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_cli.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_env.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_github.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_hooks.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_jobs.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_logs.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_profiles.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_prune_attachments.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_push.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_qr_share.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_repos.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_resume.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_sessions.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_usage_capture.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_usage_reset.py +0 -0
- {pocketshell-0.4.9 → pocketshell-0.4.11}/uv.lock +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pocketshell
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.11
|
|
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
|
|
@@ -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.4.
|
|
11
|
+
version = "0.4.11"
|
|
12
12
|
description = "Unified server-side Python utility for the PocketShell Android client."
|
|
13
13
|
readme = "README.md"
|
|
14
14
|
requires-python = ">=3.11"
|
|
@@ -36,6 +36,7 @@ from pocketshell.push import push_group
|
|
|
36
36
|
from pocketshell.qr_share import qr_share_command
|
|
37
37
|
from pocketshell.repos import repos_group
|
|
38
38
|
from pocketshell.sessions import sessions_group
|
|
39
|
+
from pocketshell.tree import tree_group
|
|
39
40
|
from pocketshell.usage import usage_command
|
|
40
41
|
|
|
41
42
|
|
|
@@ -60,6 +61,7 @@ cli.add_command(agents_group, name="agents")
|
|
|
60
61
|
cli.add_command(profiles_group, name="profiles")
|
|
61
62
|
cli.add_command(jobs_group, name="jobs")
|
|
62
63
|
cli.add_command(sessions_group, name="sessions")
|
|
64
|
+
cli.add_command(tree_group, name="tree")
|
|
63
65
|
cli.add_command(agent_log_command, name="agent-log")
|
|
64
66
|
cli.add_command(repos_group, name="repos")
|
|
65
67
|
cli.add_command(github_group, name="github")
|
|
@@ -92,6 +92,12 @@ METHOD_TTLS: Mapping[str, float] = {
|
|
|
92
92
|
# not hidden for long.
|
|
93
93
|
"sessions.list": 5.0,
|
|
94
94
|
"jobs.list": 5.0,
|
|
95
|
+
# `tree.get` is the cold-start hydrate read. Short TTL like `sessions.list`
|
|
96
|
+
# so a `tree.upsert` mutation (which also invalidates it explicitly) is not
|
|
97
|
+
# masked for long and an external edit is not hidden. `tree.upsert` and
|
|
98
|
+
# `tree.reconcile` carry NO TTL (mutations) so their results are never
|
|
99
|
+
# cached.
|
|
100
|
+
"tree.get": 5.0,
|
|
95
101
|
}
|
|
96
102
|
|
|
97
103
|
# Length-prefix is a 4-byte unsigned big-endian integer. ``struct``
|
|
@@ -574,6 +580,32 @@ def _agents_kind_for_panes_handler(params: Mapping[str, Any]) -> dict[str, Any]:
|
|
|
574
580
|
return {"results": _cgroup_agents.kind_for_panes(panes)}
|
|
575
581
|
|
|
576
582
|
|
|
583
|
+
# ---------------------------------------------------------------------------
|
|
584
|
+
# Methods: tree.* (epic #821 slice C / issue #837)
|
|
585
|
+
# ---------------------------------------------------------------------------
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
def _tree_get_handler(params: Mapping[str, Any]) -> dict[str, Any]:
|
|
589
|
+
"""Delegate ``tree.get`` to the durable per-host tree registry."""
|
|
590
|
+
from pocketshell import tree as _tree
|
|
591
|
+
|
|
592
|
+
return _tree.daemon_handler_get(dict(params))
|
|
593
|
+
|
|
594
|
+
|
|
595
|
+
def _tree_upsert_handler(params: Mapping[str, Any]) -> dict[str, Any]:
|
|
596
|
+
"""Delegate ``tree.upsert`` to the durable per-host tree registry."""
|
|
597
|
+
from pocketshell import tree as _tree
|
|
598
|
+
|
|
599
|
+
return _tree.daemon_handler_upsert(dict(params))
|
|
600
|
+
|
|
601
|
+
|
|
602
|
+
def _tree_reconcile_handler(params: Mapping[str, Any]) -> dict[str, Any]:
|
|
603
|
+
"""Delegate ``tree.reconcile`` to the durable per-host tree registry."""
|
|
604
|
+
from pocketshell import tree as _tree
|
|
605
|
+
|
|
606
|
+
return _tree.daemon_handler_reconcile(dict(params))
|
|
607
|
+
|
|
608
|
+
|
|
577
609
|
# Single shared registry; tests can register additional methods via
|
|
578
610
|
# :meth:`Daemon.register_method` on a fresh instance without touching
|
|
579
611
|
# this dict.
|
|
@@ -592,6 +624,9 @@ DEFAULT_METHODS: Mapping[str, RpcHandler] = {
|
|
|
592
624
|
"jobs.remove": _jobs_remove_handler,
|
|
593
625
|
"jobs.status": _jobs_status_handler,
|
|
594
626
|
"agents.kind_for_panes": _agents_kind_for_panes_handler,
|
|
627
|
+
"tree.get": _tree_get_handler,
|
|
628
|
+
"tree.upsert": _tree_upsert_handler,
|
|
629
|
+
"tree.reconcile": _tree_reconcile_handler,
|
|
595
630
|
}
|
|
596
631
|
|
|
597
632
|
|
|
@@ -612,6 +647,13 @@ METHOD_CACHE_INVALIDATIONS: Mapping[str, tuple[str, ...]] = {
|
|
|
612
647
|
"jobs.edit": ("jobs.list",),
|
|
613
648
|
"jobs.remove": ("jobs.list",),
|
|
614
649
|
"jobs.trigger": ("jobs.list",),
|
|
650
|
+
# `tree.upsert` rewrites the host's persisted node list, so the cached
|
|
651
|
+
# `tree.get` cold-start read is stale the moment it lands — drop it so the
|
|
652
|
+
# very next `tree.get` reflects the just-persisted ordering/expansion.
|
|
653
|
+
# `tree.reconcile` prunes gone nodes from the registry, so it must also
|
|
654
|
+
# invalidate the `tree.get` cache.
|
|
655
|
+
"tree.upsert": ("tree.get",),
|
|
656
|
+
"tree.reconcile": ("tree.get",),
|
|
615
657
|
}
|
|
616
658
|
|
|
617
659
|
|