Tests:
- tests/test_commands.py: unit coverage for Commands/AsyncCommands —
payload construction (cwd, envs, tag, timeout), background dispatch,
base64 response decoding, stream-event parsing, stream/connect iterators.
- tests/test_integration_advanced.py: live tests for cwd/env handling,
long-running commands (apt-get), PTY sessions, streaming exec,
process connect, and git workflows including cloning wrennhq/wrenn.
- test_filesystem_pty.py: PTY ping/pong reply tests.
- test_integration.py: poll for async process-registry prune in
test_kill_process instead of asserting on a zero-delay list().
Fixes:
- commands.py / pty.py: stream(), connect() and the PTY iterators only
caught WebSocketDisconnect. The server closes exec/process streams
abruptly, raising WebSocketNetworkError — a sibling under
HTTPXWSException — which crashed connect() entirely. Both are now
caught via _WS_CLOSED so abrupt closes end iteration cleanly.
- pty.py: reply to the server keepalive ping with a pong so idle PTY
sessions stay open.
Resolve conflicts in api/openapi.yaml and src/wrenn/models/_generated.py
by keeping the fix/0.2-compatibility versions (v0.2 API is authoritative).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop AuthResponse from models __init__ (renamed SessionResponse server-side; SDK auths via API key, doesn't need either)
- Regenerate models from updated 0.2 openapi spec
- Add wait: bool = False kwarg to Capsule/AsyncCapsule destroy/pause/resume (instance + _static_*); 500ms poll for resume/destroy, 2s for pause
- Unify polling into _poll_until / _apoll_until + _wait_for_status helper; remove duplicated _POLL_INTERVALS tables
- wait_ready: drop implicit paused->resume side effect; treat missing as fail
- Capsule.connect: handle transient pausing (wait for paused first) before resuming, fixes hang when caller pauses then connects immediately
- Drop dead "if self._id is None" branch in Capsule.__init__ after assigning from already-truthy _capsule_id
- files.make_dir: detect already_exists across 409/wrapped error messages via shared _is_already_exists helper
- tests/test_integration.py: assertions on final lifecycle state use wait=True
- Update Woodpecker to run unit and integration tests in parallel
- Add GitHub Actions workflow for PyPI trusted publishing on main
- Add license, classifiers, keywords, and URLs to pyproject.toml
- Fix ruff lint errors (unused imports, duplicate class name) and formatting
43 tests across 4 classes hitting the live API. Shared capsule per class
to minimize VM boot overhead. All capsules destroyed in teardown.
Skips automatically when WRENN_API_KEY is not available.
Add sandbox filesystem methods (list_dir, mkdir, remove, upload,
download, stream_upload, stream_download) and interactive PTY sessions
(PtySession, AsyncPtySession) with reconnect support per
FILE_TERMINAL.md spec. Refactor error handling into exceptions.py as
shared handle_response(). Replace API-key-only proxy auth with unified
_proxy_headers() supporting both API key and JWT. Fix stream_upload to
build multipart manually instead of relying on httpx files= with
generators. Switch Makefile SPEC_URL from main to dev branch. Regenerate
models from updated OpenAPI spec (adds teams, channels, metrics, PTY
endpoints). Add comprehensive unit and integration tests. Trim AGENTS.md
to verified facts only.
Introduces the core Wrenn client and a dedicated sandbox execution
environment. This includes automated model generation and a custom
exception hierarchy to support robust integration.
- Add `WrennClient` in `src/wrenn/client.py` for API interaction.
- Implement `Sandbox` in `src/wrenn/sandbox.py` for isolated execution.
- Add Pydantic/model support via `_generated.py`.
- Define project-specific error types in `exceptions.py`.
- Include AGENTS.md documentation for specialized logic.
- Add comprehensive unit and integration tests.
- Update build system (Makefile, uv.lock, pyproject.toml) and LICENSE.