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.
Files changed (55) hide show
  1. {pocketshell-0.4.9 → pocketshell-0.4.11}/PKG-INFO +1 -1
  2. {pocketshell-0.4.9 → pocketshell-0.4.11}/pyproject.toml +1 -1
  3. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/cli.py +2 -0
  4. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/daemon.py +42 -0
  5. pocketshell-0.4.11/src/pocketshell/tree.py +620 -0
  6. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/usage.py +28 -0
  7. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_daemon.py +50 -0
  8. pocketshell-0.4.11/tests/test_tree.py +353 -0
  9. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_usage.py +89 -0
  10. {pocketshell-0.4.9 → pocketshell-0.4.11}/.gitignore +0 -0
  11. {pocketshell-0.4.9 → pocketshell-0.4.11}/README.md +0 -0
  12. {pocketshell-0.4.9 → pocketshell-0.4.11}/scheduler/README.md +0 -0
  13. {pocketshell-0.4.9 → pocketshell-0.4.11}/scheduler/pocketshell-usage-capture.service +0 -0
  14. {pocketshell-0.4.9 → pocketshell-0.4.11}/scheduler/pocketshell-usage-capture.timer +0 -0
  15. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/__init__.py +0 -0
  16. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/__main__.py +0 -0
  17. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/agent_log.py +0 -0
  18. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/agents.py +0 -0
  19. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/agents_kind.py +0 -0
  20. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/cgroup_agents.py +0 -0
  21. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/env.py +0 -0
  22. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/github.py +0 -0
  23. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/hooks.py +0 -0
  24. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/jobs.py +0 -0
  25. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/logs.py +0 -0
  26. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/profiles.py +0 -0
  27. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/prune_attachments.py +0 -0
  28. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/push.py +0 -0
  29. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/qr_share.py +0 -0
  30. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/repos.py +0 -0
  31. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/resume.py +0 -0
  32. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/sessions.py +0 -0
  33. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/usage_capture.py +0 -0
  34. {pocketshell-0.4.9 → pocketshell-0.4.11}/src/pocketshell/usage_reset.py +0 -0
  35. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/__init__.py +0 -0
  36. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_agent_log.py +0 -0
  37. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_agents.py +0 -0
  38. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_agents_kind.py +0 -0
  39. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_cgroup_agents.py +0 -0
  40. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_cli.py +0 -0
  41. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_env.py +0 -0
  42. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_github.py +0 -0
  43. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_hooks.py +0 -0
  44. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_jobs.py +0 -0
  45. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_logs.py +0 -0
  46. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_profiles.py +0 -0
  47. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_prune_attachments.py +0 -0
  48. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_push.py +0 -0
  49. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_qr_share.py +0 -0
  50. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_repos.py +0 -0
  51. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_resume.py +0 -0
  52. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_sessions.py +0 -0
  53. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_usage_capture.py +0 -0
  54. {pocketshell-0.4.9 → pocketshell-0.4.11}/tests/test_usage_reset.py +0 -0
  55. {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.9
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.9"
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