copper-pilot-cli 0.1.1__tar.gz → 0.1.2__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.
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/HISTORY.md +11 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/PKG-INFO +9 -23
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/README.md +1 -0
- copper_pilot_cli-0.1.2/VERSION +1 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/pyproject.toml +10 -1
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_app.py +1 -1
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_widgets.py +3 -1
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_release_gates.py +17 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_tui.py +51 -20
- copper_pilot_cli-0.1.1/VERSION +0 -1
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/.gitignore +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/CODE_OF_CONDUCT.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/CONTRIBUTING.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/LICENSE +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/NOTICE +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/SECURITY.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/SUPPORT.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/UPSTREAM.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/docs/assets/esp32-mini-1-h4.gif +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/docs/assets/logo-dark.png +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/docs/assets/logo-light.png +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/docs/assets/logo.png +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/docs/cli.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/docs/development.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/.copperpilot/PLANS.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/.copperpilot/README.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/.copperpilot/TOOLS.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/.copperpilot/plans/esp32-dev-board.plan.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/.gitignore +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/README.md +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/esp32/3d-models/SW-SMD_L3.9-W2.9-H2.0-LS4.8.step +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/esp32/3d-models/TYPE-C-31-M-12.step +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/esp32/esp32.kicad_pcb +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/esp32/esp32.kicad_pro +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/esp32/esp32.kicad_sch +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/esp32/esp32.png +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/helper.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/examples/001_esp32/main.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/__init__.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/__main__.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/_upstream/__init__.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/_upstream/dcode_0_1_69/PROVENANCE.json +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/_upstream/dcode_0_1_69/__init__.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/_upstream/dcode_0_1_69/diff_utils.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/_version.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/clipboard.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_api.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_auth.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_config.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_features.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_graph.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_hooks.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_main.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_preferences.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_presentation.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_protocol.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_theme.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_tools.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_update.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_workspace.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/deepagents_tools.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/diagnostics.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/langchain.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/media_utils.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/py.typed +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/sessions.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/textual_patches.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_auth.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_clipboard.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_e2e.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_esp32_example.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_features.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_langchain.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_live_chat_e2e.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_main.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_preferences.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_presentation.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_protocol.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_sessions.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_tools.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_upstream_provenance.py +0 -0
- {copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/tests/test_workspace.py +0 -0
|
@@ -2,6 +2,17 @@ Changelog
|
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
(unreleased)
|
|
6
|
+
------------
|
|
7
|
+
- Ci(pyproject.toml) [AdityaNG]
|
|
8
|
+
- Fix(tests/test_tui.py) [AdityaNG]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
0.1.1 (2026-09-17)
|
|
12
|
+
------------------
|
|
13
|
+
- Release: version 0.1.1 🚀 [AdityaNG]
|
|
14
|
+
|
|
15
|
+
|
|
5
16
|
0.1.0 (2026-09-17)
|
|
6
17
|
------------------
|
|
7
18
|
- Release: version 0.1.0 🚀 [AdityaNG]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: copper-pilot-cli
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.2
|
|
4
4
|
Summary: CopperPilot hosted agent for the terminal and LangChain
|
|
5
5
|
Project-URL: Homepage, https://copperpilot.ai
|
|
6
6
|
Project-URL: Repository, https://github.com/CopperPilot/copper-pilot-cli
|
|
@@ -8,30 +8,15 @@ Project-URL: Issues, https://github.com/CopperPilot/copper-pilot-cli/issues
|
|
|
8
8
|
Project-URL: Documentation, https://github.com/CopperPilot/copper-pilot-cli#readme
|
|
9
9
|
Project-URL: Changelog, https://github.com/CopperPilot/copper-pilot-cli/releases
|
|
10
10
|
Author: CopperPilot
|
|
11
|
-
License: MIT
|
|
12
|
-
|
|
13
|
-
Copyright (c) 2026 CopperPilot, Inc.
|
|
14
|
-
Copyright (c) LangChain, Inc.
|
|
15
|
-
|
|
16
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
17
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
18
|
-
in the Software without restriction, including without limitation the rights
|
|
19
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
20
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
21
|
-
furnished to do so, subject to the following conditions:
|
|
22
|
-
|
|
23
|
-
The above copyright notice and this permission notice shall be included in all
|
|
24
|
-
copies or substantial portions of the Software.
|
|
25
|
-
|
|
26
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
27
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
28
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
29
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
30
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
31
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
32
|
-
SOFTWARE.
|
|
11
|
+
License-Expression: MIT
|
|
33
12
|
License-File: LICENSE
|
|
34
13
|
License-File: NOTICE
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
35
20
|
Requires-Python: <4,>=3.12
|
|
36
21
|
Requires-Dist: aiosqlite<1,>=0.22
|
|
37
22
|
Requires-Dist: certifi>=2024.8.30
|
|
@@ -80,6 +65,7 @@ Description-Content-Type: text/markdown
|
|
|
80
65
|
<a href="https://github.com/CopperPilot/copper-pilot-cli/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/copper-pilot-cli" alt="License"></a>
|
|
81
66
|
<a href="https://pypi.org/project/copper-pilot-cli/"><img src="https://img.shields.io/pypi/v/copper-pilot-cli" alt="PyPI version"></a>
|
|
82
67
|
<a href="https://pypi.org/project/copper-pilot-cli/"><img src="https://img.shields.io/pypi/pyversions/copper-pilot-cli" alt="Python"></a>
|
|
68
|
+
<a href="https://pepy.tech/projects/copper-pilot-cli"><img src="https://img.shields.io/pepy/dt/copper-pilot-cli" alt="Downloads"></a>
|
|
83
69
|
<a href="https://github.com/CopperPilot/copper-pilot-cli/actions/workflows/ci.yml"><img src="https://github.com/CopperPilot/copper-pilot-cli/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
84
70
|
</div>
|
|
85
71
|
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
<a href="https://github.com/CopperPilot/copper-pilot-cli/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/copper-pilot-cli" alt="License"></a>
|
|
17
17
|
<a href="https://pypi.org/project/copper-pilot-cli/"><img src="https://img.shields.io/pypi/v/copper-pilot-cli" alt="PyPI version"></a>
|
|
18
18
|
<a href="https://pypi.org/project/copper-pilot-cli/"><img src="https://img.shields.io/pypi/pyversions/copper-pilot-cli" alt="Python"></a>
|
|
19
|
+
<a href="https://pepy.tech/projects/copper-pilot-cli"><img src="https://img.shields.io/pepy/dt/copper-pilot-cli" alt="Downloads"></a>
|
|
19
20
|
<a href="https://github.com/CopperPilot/copper-pilot-cli/actions/workflows/ci.yml"><img src="https://github.com/CopperPilot/copper-pilot-cli/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
|
|
20
21
|
</div>
|
|
21
22
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
0.1.2
|
|
@@ -7,9 +7,18 @@ name = "copper-pilot-cli"
|
|
|
7
7
|
dynamic = ["version"]
|
|
8
8
|
description = "CopperPilot hosted agent for the terminal and LangChain"
|
|
9
9
|
readme = "README.md"
|
|
10
|
-
license =
|
|
10
|
+
license = "MIT"
|
|
11
|
+
license-files = ["LICENSE", "NOTICE"]
|
|
11
12
|
requires-python = ">=3.12,<4"
|
|
12
13
|
authors = [{ name = "CopperPilot" }]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"License :: OSI Approved :: MIT License",
|
|
16
|
+
"Programming Language :: Python :: 3",
|
|
17
|
+
"Programming Language :: Python :: 3 :: Only",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Programming Language :: Python :: 3.14",
|
|
21
|
+
]
|
|
13
22
|
dependencies = [
|
|
14
23
|
"aiosqlite>=0.22,<1",
|
|
15
24
|
"certifi>=2024.8.30",
|
|
@@ -1004,7 +1004,7 @@ class CopperPilotApp(App[None]):
|
|
|
1004
1004
|
finally:
|
|
1005
1005
|
if self._loading is not None:
|
|
1006
1006
|
self._loading.resume()
|
|
1007
|
-
if composer.is_mounted:
|
|
1007
|
+
if composer.is_mounted and composer.query(TextArea):
|
|
1008
1008
|
composer.focus()
|
|
1009
1009
|
if not isinstance(decision, ApprovalDecision):
|
|
1010
1010
|
if tool:
|
|
@@ -183,7 +183,9 @@ class ChatInput(Vertical):
|
|
|
183
183
|
yield OptionList(id="completions")
|
|
184
184
|
|
|
185
185
|
def focus(self, scroll_visible: bool = True) -> ChatInput:
|
|
186
|
-
self.
|
|
186
|
+
text_area = self.query(TextArea)
|
|
187
|
+
if text_area:
|
|
188
|
+
text_area.first().focus(scroll_visible)
|
|
187
189
|
return self
|
|
188
190
|
|
|
189
191
|
def update_slash_commands(self, commands: Sequence[Any]) -> None:
|
|
@@ -159,3 +159,20 @@ def test_project_urls_include_community_links() -> None:
|
|
|
159
159
|
urls = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))["project"]["urls"]
|
|
160
160
|
for key in ("Homepage", "Repository", "Issues", "Documentation", "Changelog"):
|
|
161
161
|
assert key in urls, key
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def test_pypi_badge_metadata_is_declared() -> None:
|
|
165
|
+
project = tomllib.loads((ROOT / "pyproject.toml").read_text(encoding="utf-8"))["project"]
|
|
166
|
+
assert project.get("license") == "MIT"
|
|
167
|
+
assert "LICENSE" in project.get("license-files", [])
|
|
168
|
+
classifiers = project.get("classifiers", [])
|
|
169
|
+
assert "License :: OSI Approved :: MIT License" in classifiers
|
|
170
|
+
for version in ("3.12", "3.13", "3.14"):
|
|
171
|
+
assert f"Programming Language :: Python :: {version}" in classifiers
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_readme_header_includes_download_badge() -> None:
|
|
175
|
+
readme = (ROOT / "README.md").read_text(encoding="utf-8")
|
|
176
|
+
assert "img.shields.io/pypi/l/copper-pilot-cli" in readme
|
|
177
|
+
assert "img.shields.io/pypi/pyversions/copper-pilot-cli" in readme
|
|
178
|
+
assert "img.shields.io/pepy/dt/copper-pilot-cli" in readme
|
|
@@ -63,6 +63,20 @@ class FakeRuntime:
|
|
|
63
63
|
yield (), "custom", {"type": "copper.text", "data": "chat response"}
|
|
64
64
|
|
|
65
65
|
|
|
66
|
+
async def _wait_until(pilot, predicate, *, seconds: float = 2) -> None:
|
|
67
|
+
"""Advance the event loop until `predicate()` is true.
|
|
68
|
+
|
|
69
|
+
Avoid `pilot.pause()` here: its `_wait_for_screen()` can deadlock with
|
|
70
|
+
cancelled-turn widget teardown (`AwaitRemove` / prune).
|
|
71
|
+
"""
|
|
72
|
+
async with asyncio.timeout(seconds):
|
|
73
|
+
while not predicate():
|
|
74
|
+
await asyncio.sleep(0.02)
|
|
75
|
+
screen = getattr(pilot.app, "screen", None)
|
|
76
|
+
if screen is not None:
|
|
77
|
+
screen._on_timer_update()
|
|
78
|
+
|
|
79
|
+
|
|
66
80
|
@pytest.mark.asyncio
|
|
67
81
|
async def test_tui_mounts_branded_composer_and_status(tmp_path) -> None:
|
|
68
82
|
app = CopperPilotApp(
|
|
@@ -359,12 +373,15 @@ async def test_cancel_during_active_turn_does_not_quit_or_crash(tmp_path) -> Non
|
|
|
359
373
|
app = CopperPilotApp(runtime, LocalToolBroker(tmp_path), tmp_path, "thread")
|
|
360
374
|
async with app.run_test(size=(100, 30)) as pilot:
|
|
361
375
|
await app._submit("long task")
|
|
362
|
-
await
|
|
363
|
-
|
|
376
|
+
await _wait_until(
|
|
377
|
+
pilot,
|
|
378
|
+
lambda: (
|
|
379
|
+
app._turn_task is not None and app._loading is not None and app._loading.is_mounted
|
|
380
|
+
),
|
|
381
|
+
)
|
|
364
382
|
await app.action_cancel_or_quit()
|
|
365
|
-
await pilot.
|
|
383
|
+
await _wait_until(pilot, lambda: app._turn_task is None)
|
|
366
384
|
assert runtime.cancelled is True
|
|
367
|
-
assert app._turn_task is None
|
|
368
385
|
|
|
369
386
|
|
|
370
387
|
@pytest.mark.asyncio
|
|
@@ -391,10 +408,12 @@ async def test_cancel_settles_active_tool_and_removes_loading(tmp_path) -> None:
|
|
|
391
408
|
app = CopperPilotApp(runtime, LocalToolBroker(tmp_path), tmp_path, "thread")
|
|
392
409
|
async with app.run_test(size=(100, 30)) as pilot:
|
|
393
410
|
await app._submit("long task")
|
|
394
|
-
await
|
|
395
|
-
|
|
411
|
+
await _wait_until(
|
|
412
|
+
pilot,
|
|
413
|
+
lambda: app._loading is not None and app._loading.is_mounted,
|
|
414
|
+
)
|
|
396
415
|
await app.action_cancel_or_quit()
|
|
397
|
-
await pilot.
|
|
416
|
+
await _wait_until(pilot, lambda: app._turn_task is None)
|
|
398
417
|
assert app._tools["read-1"].status == "error"
|
|
399
418
|
assert not list(app.query(LoadingWidget))
|
|
400
419
|
|
|
@@ -418,11 +437,15 @@ async def test_cancel_still_cleans_up_when_transport_cancel_fails(tmp_path) -> N
|
|
|
418
437
|
app = CopperPilotApp(runtime, LocalToolBroker(tmp_path), tmp_path, "thread")
|
|
419
438
|
async with app.run_test(size=(100, 30)) as pilot:
|
|
420
439
|
await app._submit("long task")
|
|
421
|
-
await
|
|
440
|
+
await _wait_until(
|
|
441
|
+
pilot,
|
|
442
|
+
lambda: (
|
|
443
|
+
app._turn_task is not None and app._loading is not None and app._loading.is_mounted
|
|
444
|
+
),
|
|
445
|
+
)
|
|
422
446
|
await app.action_cancel_or_quit()
|
|
423
|
-
await pilot.
|
|
447
|
+
await _wait_until(pilot, lambda: app._turn_task is None)
|
|
424
448
|
assert runtime.cancelled is True
|
|
425
|
-
assert app._turn_task is None
|
|
426
449
|
|
|
427
450
|
|
|
428
451
|
@pytest.mark.asyncio
|
|
@@ -437,9 +460,7 @@ async def test_hosted_error_event_is_rendered_only_once(tmp_path) -> None:
|
|
|
437
460
|
app = CopperPilotApp(runtime, LocalToolBroker(tmp_path), tmp_path, "thread")
|
|
438
461
|
async with app.run_test(size=(100, 30)) as pilot:
|
|
439
462
|
await app._submit("fail")
|
|
440
|
-
|
|
441
|
-
while app._turn_task is not None:
|
|
442
|
-
await pilot.pause()
|
|
463
|
+
await _wait_until(pilot, lambda: app._turn_task is None)
|
|
443
464
|
assert len(list(app.query(ErrorMessage))) == 1
|
|
444
465
|
|
|
445
466
|
|
|
@@ -626,7 +647,10 @@ async def test_tool_approval_uses_dcode_style_preview_and_resumes_row(tmp_path)
|
|
|
626
647
|
}
|
|
627
648
|
)
|
|
628
649
|
decision = asyncio.create_task(app.request_approval(request))
|
|
629
|
-
await
|
|
650
|
+
await _wait_until(
|
|
651
|
+
pilot,
|
|
652
|
+
lambda: any(menu.has_focus for menu in app.query(ApprovalMenu)),
|
|
653
|
+
)
|
|
630
654
|
menu = app.query_one(ApprovalMenu)
|
|
631
655
|
assert "copper" in str(menu.query_one(".approval-preview Static").render())
|
|
632
656
|
await pilot.press("y")
|
|
@@ -656,7 +680,10 @@ async def test_inline_approval_tab_collects_rejection_feedback(tmp_path) -> None
|
|
|
656
680
|
}
|
|
657
681
|
)
|
|
658
682
|
decision = asyncio.create_task(app.request_approval(request))
|
|
659
|
-
await
|
|
683
|
+
await _wait_until(
|
|
684
|
+
pilot,
|
|
685
|
+
lambda: any(menu.has_focus for menu in app.query(ApprovalMenu)),
|
|
686
|
+
)
|
|
660
687
|
await pilot.press("tab")
|
|
661
688
|
reason = app.query_one(ApprovalMenu).query_one(Input)
|
|
662
689
|
assert reason.display is True
|
|
@@ -689,13 +716,17 @@ async def test_cancelling_auto_notice_keeps_current_approval_pending(tmp_path, m
|
|
|
689
716
|
}
|
|
690
717
|
)
|
|
691
718
|
decision = asyncio.create_task(app.request_approval(request))
|
|
692
|
-
await
|
|
719
|
+
await _wait_until(
|
|
720
|
+
pilot,
|
|
721
|
+
lambda: any(menu.has_focus for menu in app.query(ApprovalMenu)),
|
|
722
|
+
)
|
|
693
723
|
await pilot.press("a")
|
|
694
|
-
await pilot.
|
|
695
|
-
assert isinstance(app.screen, ChoiceScreen)
|
|
724
|
+
await _wait_until(pilot, lambda: isinstance(app.screen, ChoiceScreen))
|
|
696
725
|
app.screen.dismiss("cancel")
|
|
697
|
-
await
|
|
698
|
-
|
|
726
|
+
await _wait_until(
|
|
727
|
+
pilot,
|
|
728
|
+
lambda: any(menu.has_focus for menu in app.query(ApprovalMenu)),
|
|
729
|
+
)
|
|
699
730
|
assert decision.done() is False
|
|
700
731
|
await pilot.press("y")
|
|
701
732
|
assert await decision is True
|
copper_pilot_cli-0.1.1/VERSION
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
0.1.1
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/_upstream/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_preferences.py
RENAMED
|
File without changes
|
{copper_pilot_cli-0.1.1 → copper_pilot_cli-0.1.2}/src/copper_pilot_cli/copper_presentation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|