pythonhere 0.2.2__tar.gz → 0.3.0__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 (78) hide show
  1. {pythonhere-0.2.2/pythonhere.egg-info → pythonhere-0.3.0}/PKG-INFO +11 -2
  2. {pythonhere-0.2.2 → pythonhere-0.3.0}/README.rst +9 -0
  3. {pythonhere-0.2.2 → pythonhere-0.3.0}/pyproject.toml +4 -1
  4. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/SKILL.md +230 -0
  5. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/agents/openai.yaml +4 -0
  6. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references/able.md +554 -0
  7. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references/android-permissions.md +195 -0
  8. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references/kivy-kv.md +241 -0
  9. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references/kivy-runtime.md +305 -0
  10. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references/midi.md +248 -0
  11. pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references/plyer.md +202 -0
  12. pythonhere-0.3.0/pythonhere/magic_here/prompts/android-media.md +130 -0
  13. pythonhere-0.3.0/pythonhere/magic_here/prompts/android-packages.md +69 -0
  14. pythonhere-0.3.0/pythonhere/magic_here/prompts/android-runtime.md +34 -0
  15. pythonhere-0.3.0/pythonhere/magic_here/prompts/jnius.md +432 -0
  16. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/shortcuts.py +2 -2
  17. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/server_here.py +1 -1
  18. pythonhere-0.3.0/pythonhere/tools_here.py +359 -0
  19. pythonhere-0.3.0/pythonhere/version_here.py +1 -0
  20. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/window_here.py +24 -9
  21. {pythonhere-0.2.2 → pythonhere-0.3.0/pythonhere.egg-info}/PKG-INFO +11 -2
  22. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere.egg-info/SOURCES.txt +15 -0
  23. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere.egg-info/requires.txt +1 -1
  24. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_main.py +47 -0
  25. pythonhere-0.3.0/tests/test_pythonhere_skill.py +86 -0
  26. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_server_here.py +47 -1
  27. pythonhere-0.3.0/tests/test_tools_here.py +659 -0
  28. pythonhere-0.2.2/pythonhere/version_here.py +0 -1
  29. {pythonhere-0.2.2 → pythonhere-0.3.0}/LICENSE +0 -0
  30. {pythonhere-0.2.2/pythonhere/magic_here/prompts → pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references}/android-media.md +0 -0
  31. {pythonhere-0.2.2/pythonhere/magic_here/prompts → pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references}/android-packages.md +0 -0
  32. {pythonhere-0.2.2/pythonhere/magic_here/prompts → pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references}/android-runtime.md +0 -0
  33. {pythonhere-0.2.2/pythonhere/magic_here/prompts → pythonhere-0.3.0/pythonhere/.agents/skills/pythonhere/references}/jnius.md +0 -0
  34. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/__init__.py +0 -0
  35. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/android_here.py +0 -0
  36. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/data/logo/logo-128.png +0 -0
  37. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/data/logo/logo-32.png +0 -0
  38. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/data/logo/logo-splash.png +0 -0
  39. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/enum_here.py +0 -0
  40. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/exception_manager_here.kv +0 -0
  41. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/exception_manager_here.py +0 -0
  42. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/launcher_here.py +0 -0
  43. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/__init__.py +0 -0
  44. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts/README.md +0 -0
  45. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts/able.md +0 -0
  46. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts/android-permissions.md +0 -0
  47. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts/kivy-kv.md +0 -0
  48. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts/kivy-runtime.md +0 -0
  49. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts/midi.md +0 -0
  50. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts/plyer.md +0 -0
  51. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/magic_here/prompts.py +0 -0
  52. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/main.py +0 -0
  53. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/network_here.py +0 -0
  54. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/patches_here.py +0 -0
  55. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/pythonhere.kv +0 -0
  56. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/__init__.py +0 -0
  57. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/actionbar_here.kv +0 -0
  58. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/common_here.kv +0 -0
  59. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/connection_address_here.kv +0 -0
  60. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/connection_address_here.py +0 -0
  61. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/layout_here.py +0 -0
  62. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/server_screen_here.kv +0 -0
  63. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/server_screen_here.py +0 -0
  64. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/settings_here.kv +0 -0
  65. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere/ui_here/settings_here.py +0 -0
  66. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere.egg-info/dependency_links.txt +0 -0
  67. {pythonhere-0.2.2 → pythonhere-0.3.0}/pythonhere.egg-info/top_level.txt +0 -0
  68. {pythonhere-0.2.2 → pythonhere-0.3.0}/setup.cfg +0 -0
  69. {pythonhere-0.2.2 → pythonhere-0.3.0}/setup.py +0 -0
  70. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_ai_prompts.py +0 -0
  71. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_android_here.py +0 -0
  72. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_exception_manager_here.py +0 -0
  73. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_launcher_here.py +0 -0
  74. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_magic.py +0 -0
  75. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_network.py +0 -0
  76. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_patches.py +0 -0
  77. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_settings.py +0 -0
  78. {pythonhere-0.2.2 → pythonhere-0.3.0}/tests/test_window_here.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pythonhere
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Here is the Kivy based app to run code from the Jupyter magic %there
5
5
  Author-email: b3b <ash.b3b@gmail.com>
6
6
  License-Expression: MIT
@@ -16,7 +16,7 @@ Classifier: Programming Language :: Python :: 3.14
16
16
  Requires-Python: >=3.10
17
17
  Description-Content-Type: text/x-rst
18
18
  License-File: LICENSE
19
- Requires-Dist: herethere[magic]>=0.2.3
19
+ Requires-Dist: herethere[magic]>=0.3.1
20
20
  Requires-Dist: ipython
21
21
  Requires-Dist: ipywidgets
22
22
  Requires-Dist: Pillow
@@ -111,6 +111,15 @@ Commands to run locally::
111
111
  jupyter notebook
112
112
 
113
113
 
114
+ Coding agents
115
+ -------------
116
+
117
+ PythonHere includes agent skills for working with the live app through the
118
+ ``there`` command-line interface. See `Coding agent skills
119
+ <https://herethere.me/pythonhere/examples/coding-agents.html>`_ for skill setup
120
+ and practical examples.
121
+
122
+
114
123
  Build Android app
115
124
  -----------------
116
125
 
@@ -87,6 +87,15 @@ Commands to run locally::
87
87
  jupyter notebook
88
88
 
89
89
 
90
+ Coding agents
91
+ -------------
92
+
93
+ PythonHere includes agent skills for working with the live app through the
94
+ ``there`` command-line interface. See `Coding agent skills
95
+ <https://herethere.me/pythonhere/examples/coding-agents.html>`_ for skill setup
96
+ and practical examples.
97
+
98
+
90
99
  Build Android app
91
100
  -----------------
92
101
 
@@ -22,7 +22,7 @@ classifiers = [
22
22
  "Programming Language :: Python :: 3.14",
23
23
  ]
24
24
  dependencies = [
25
- "herethere[magic]>=0.2.3",
25
+ "herethere[magic]>=0.3.1",
26
26
  "ipython",
27
27
  "ipywidgets",
28
28
  "Pillow",
@@ -75,6 +75,9 @@ version = { attr = "pythonhere.version_here.__version__" }
75
75
 
76
76
  [tool.setuptools.package-data]
77
77
  pythonhere = [
78
+ ".agents/skills/pythonhere/SKILL.md",
79
+ ".agents/skills/pythonhere/agents/openai.yaml",
80
+ ".agents/skills/pythonhere/references/*.md",
78
81
  "*.kv",
79
82
  "data/logo/*.png",
80
83
  "magic_here/prompts/*.md",
@@ -0,0 +1,230 @@
1
+ ---
2
+ name: pythonhere
3
+ description: "Build, inspect, and debug PythonHere applications by executing Python through the `there` CLI in an already-running Kivy/Python-for-Android process. Use when a task targets a PythonHere device or `there.env` connection and involves live Kivy UI, KV language, Android APIs, Pyjnius, permissions, installed Android packages, media/files, Plyer device features, BLE with able, or MIDI with midistream."
4
+ ---
5
+
6
+ # Operate PythonHere with `there`
7
+
8
+ Treat the target as a live Android/Kivy application. Use the installed `there`
9
+ CLI for transport and execution. Consult the `there-cli` skill when the task
10
+ needs connection discovery, unfamiliar or version-sensitive syntax, transfers,
11
+ timeout or failure diagnosis, or its fuller remote-execution safety guidance.
12
+ For routine `ping`, `get`, `logs`, or `run` calls whose invocation is already
13
+ established, use the common workflow below without loading `there-cli` solely
14
+ because it is the transport.
15
+
16
+ ## Load the relevant runtime rules
17
+
18
+ The common runtime contract and guardrails are in this file. Consult a reference
19
+ only when the task needs its additional detail and that detail is not already
20
+ available in the current context. Do not reopen a reference merely because the
21
+ request mentions its topic. Read the applicable sections, or the complete file
22
+ when the task depends on it broadly or requires its exact current contents.
23
+
24
+ - Consult [kivy-runtime.md](references/kivy-runtime.md) for nontrivial Kivy
25
+ runtime, lifecycle, threading, state, or UI-construction details beyond the
26
+ guardrails below. A simple property change does not require it.
27
+ - Consult [kivy-kv.md](references/kivy-kv.md) for nontrivial KV generation or
28
+ modification details.
29
+ - Consult [android-runtime.md](references/android-runtime.md) for Android
30
+ activity, service, context, or lifecycle details.
31
+ - Consult [jnius.md](references/jnius.md) for Java/Android API calls through
32
+ Pyjnius.
33
+ - Consult [android-permissions.md](references/android-permissions.md) for
34
+ permission checks or requests.
35
+ - Consult [android-packages.md](references/android-packages.md) for installed
36
+ applications or package metadata.
37
+ - Consult [android-media.md](references/android-media.md) for shared storage,
38
+ MediaStore, images, video, downloads, or galleries.
39
+ - Consult [plyer.md](references/plyer.md) for notifications, vibration, TTS,
40
+ recording, camera, file selection, GPS, battery, or sensors.
41
+ - Consult [able.md](references/able.md) for Bluetooth Low Energy work.
42
+ - Consult [midi.md](references/midi.md) for MIDI or synthesizer work.
43
+
44
+ Combine references when a feature genuinely needs details from several
45
+ concerns; for example, an Android gallery may need permission, MediaStore, and
46
+ Pyjnius guidance. Do not load every potentially related reference in advance.
47
+
48
+ ## Use the shared runtime tools
49
+
50
+ PythonHere provides general helpers in `tools_here`; they are available to
51
+ Jupyter commands, agents, and arbitrary code executed in the live runtime.
52
+ They complement rather than restrict normal Python:
53
+
54
+ - `snapshot_ui(widget=None, max_depth=6, max_widgets=200,
55
+ widget_record_callback=None)` returns a bounded, JSON-compatible diagnostic
56
+ snapshot. It reports observable widget paths, classes, text, original text
57
+ length, disabled state, geometry, and child counts. It does not infer KV `id`
58
+ ownership. Lower the soft limits for a narrow inspection; hard ceilings
59
+ prevent more than 48 levels or 500 widgets.
60
+ - `runtime_info(app=None, root=None)` returns compact Kivy runtime information.
61
+ - `save_screenshot(path="pythonhere-screenshot.png", widget=None)` writes a PNG.
62
+ Relative paths are rooted in the PythonHere upload/SFTP directory.
63
+ - `encoded_screenshot(widget=None)` returns the visible content as base64 PNG.
64
+ - `pin_shortcut(script, label=None)` requests an Android launcher shortcut.
65
+
66
+ These helpers may be called on Kivy's main thread or from a worker. Worker calls
67
+ are transparently marshaled to Kivy's thread and block that worker until Kivy
68
+ finishes the operation, normally on its next frame. Continue to prefer normal
69
+ foreground `there get` and `there run` for quick UI operations. Background
70
+ execution is useful when surrounding work would otherwise block the UI; it does
71
+ not make other Kivy access thread-safe.
72
+
73
+ Do not call a worker-marshaled helper while Kivy's main thread is synchronously
74
+ waiting for that same worker. Neither side can progress in that cross-thread
75
+ wait. A bridge timeout prevents an indefinite wait, but a mutation that already
76
+ started may still complete and must not be retried blindly.
77
+
78
+ Inspect the UI directly with an expression:
79
+
80
+ ```console
81
+ there --json get "__import__('tools_here').snapshot_ui(root)"
82
+ ```
83
+
84
+ The returned value has this shape:
85
+
86
+ ```json
87
+ {
88
+ "widgets": [
89
+ {
90
+ "path": "0/2/1",
91
+ "class": "Button",
92
+ "text": "Expand all",
93
+ "text_length": 10,
94
+ "disabled": false,
95
+ "pos": [16.0, 520.0],
96
+ "size": [180.0, 46.0],
97
+ "child_count": 0
98
+ }
99
+ ],
100
+ "widget_count": 12,
101
+ "truncated": false
102
+ }
103
+ ```
104
+
105
+ Treat `path` as structural and local to that snapshot. Do not use it as a
106
+ persistent widget selector: the path can change whenever the widget tree
107
+ changes. When `truncated` is true and the missing portion matters, rerun with
108
+ higher soft limits up to `max_depth=48` and `max_widgets=500`. Filter the
109
+ returned JSON locally or use arbitrary remote Python for more specific
110
+ inspection.
111
+
112
+ After mounting or changing UI, inspect in a subsequent `there` request or after
113
+ one Kivy frame; earlier geometry may still be pre-layout.
114
+
115
+ For application-specific state, pass `widget_record_callback`. It receives each
116
+ live widget and its default record on Kivy's main thread. It may mutate and
117
+ return that record, return a replacement dictionary, or return `None` to omit
118
+ the record without pruning its children:
119
+
120
+ ```python
121
+ def inspect_widget(widget, record):
122
+ if hasattr(widget, "value"):
123
+ record["value"] = widget.value
124
+ return record
125
+
126
+ snapshot = snapshot_ui(root, widget_record_callback=inspect_widget)
127
+ ```
128
+
129
+ For enrichment or redaction, prefer mutating and returning the provided record.
130
+ Return a replacement dictionary only when intentionally creating a reduced
131
+ custom schema.
132
+
133
+ The callback may similarly add `str(widget.text)` under a custom `full_text`
134
+ field when untruncated text is explicitly needed. Keep the callback fast and
135
+ nonblocking: do not sleep, perform I/O, wait for threads, mutate the widget
136
+ tree, or start a Kivy event loop. Returned records and all nested values must be
137
+ JSON-compatible. A callback exception or invalid result preserves that widget's
138
+ default record and adds a compact `inspection_error`; inspection then continues
139
+ with later widgets. Omitted records still count toward `max_widgets`.
140
+
141
+ Inspect compact runtime metadata when diagnosing the target:
142
+
143
+ ```console
144
+ there --json get "__import__('tools_here').runtime_info(app, root)"
145
+ ```
146
+
147
+ For a screenshot, execute the helper, retrieve the artifact, then inspect the
148
+ local image:
149
+
150
+ ```console
151
+ there --json run --code "from tools_here import save_screenshot; pythonhere_screenshot = save_screenshot('pythonhere-agent-screenshot.png', root)"
152
+ there --json download pythonhere-agent-screenshot.png ./pythonhere-agent-screenshot.png
153
+ ```
154
+
155
+ Use `pin_shortcut` only when the user explicitly asks to add a launcher
156
+ shortcut. Upload the referenced script first and remember that Android may show
157
+ a launcher confirmation:
158
+
159
+ ```console
160
+ there --json upload ./demo.py
161
+ there --json run --code "from tools_here import pin_shortcut; pin_shortcut('demo.py', 'Demo')"
162
+ ```
163
+
164
+ ## Workflow
165
+
166
+ 1. Establish the installed CLI interface and target using the `there-cli`
167
+ workflow. Prefer JSON mode and start with `there --json ping` when target
168
+ readiness is not already established.
169
+ 2. Inspect only the state needed for the task. Prefer small `there --json get`
170
+ expressions for named globals or compact summaries, and `there --json logs`
171
+ for diagnostics. Use `tools_here` inspection or screenshots when structure or
172
+ rendering matters. Remember that `get` evaluates code and is not inherently
173
+ read-only.
174
+ 3. Design for the live runtime:
175
+ - Assume the Kivy event loop is already running.
176
+ - Assume `app` and the visible `root` container already exist.
177
+ - Preserve useful objects in clearly named globals so later commands can
178
+ inspect, reuse, stop, or release them.
179
+ - Keep callbacks non-blocking and marshal UI changes to the Kivy thread.
180
+ 4. For more than a short expression, create a local UTF-8 Python file and run it
181
+ with `there --json run FILE`. Prefer a file over fragile shell quoting or a
182
+ long `--code` value. Keep within the installed CLI's input limit.
183
+ 5. Make only the requested live-app mutation. Reuse existing state when
184
+ practical and provide cleanup helpers for scheduled events, sensors,
185
+ Bluetooth, MIDI, files, or other held resources.
186
+ 6. Verify with the narrowest useful observation:
187
+ - inspect a named result/status global with `there --json get`;
188
+ - retrieve relevant recent logs;
189
+ - or inspect the specific widget/state changed.
190
+ Check `ok`, `error`, exit status, and truncation fields before declaring
191
+ success.
192
+
193
+ ## Live-app guardrails
194
+
195
+ - Do not generate a standalone Kivy application or start/stop an event loop.
196
+ - Do not use ADB or local host Android tooling to operate the remote app.
197
+ - Do not replace the visible UI unless the user asks. When replacement is
198
+ requested, update the existing `root` container according to the Kivy
199
+ references.
200
+ - Do not block the main thread with sleeps, polling loops, network calls, media
201
+ decoding, or long computation.
202
+ - Do not rely on callback `print` output. Store callback results/errors in named
203
+ globals and use visible UI status when user feedback is needed.
204
+ - Do not blindly retry after an ambiguous mutating failure. Inspect state first
205
+ because the code may already have run.
206
+ - Treat permissions, sensors, camera, microphone, location, private files, and
207
+ remote shell execution as capability-sensitive operations. Request or access
208
+ only what the task requires.
209
+ - Preserve the running app after expected failures: log the exception, store a
210
+ compact error, and show a useful UI error where appropriate.
211
+
212
+ ## Examples
213
+
214
+ Inspect the current live root without dumping the widget tree:
215
+
216
+ ```console
217
+ there --json get "(type(root).__name__, len(root.children))"
218
+ ```
219
+
220
+ Run a prepared UI change:
221
+
222
+ ```console
223
+ there --json run /tmp/pythonhere-ui.py
224
+ ```
225
+
226
+ Verify a named status left by that code:
227
+
228
+ ```console
229
+ there --json get "pythonhere_feature_status"
230
+ ```
@@ -0,0 +1,4 @@
1
+ interface:
2
+ display_name: "Use PythonHere"
3
+ short_description: "Build and debug live Android Kivy apps"
4
+ default_prompt: "Use $pythonhere to build or debug this live Android/Kivy app through the there CLI."