diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 08ae8a7..ba74cf0 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -20,7 +20,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.10", "3.12"] + python-version: ["3.11", "3.12"] steps: - uses: actions/checkout@v7 @@ -51,12 +51,19 @@ jobs: with: python-version: "3.12" + - uses: astral-sh/setup-uv@v8.1.0 + with: + version: "latest" + - uses: actions/setup-node@v7 with: node-version: "22" - name: Install bridge + test deps - run: pip install -e . pytest + run: | + uv pip install --system \ + "inkbox @ git+https://github.com/inkbox-ai/inkbox.git@8f4b37c56cd153a2acc6cfabe27dbbeb43510f00#subdirectory=sdk/python" \ + -e . pytest # @alpha is the prerelease channel cut from codex main near-daily — the # freshest main build available without compiling the host from source. diff --git a/README.md b/README.md index ef39cbb..e47b14c 100644 --- a/README.md +++ b/README.md @@ -20,13 +20,13 @@ ## Prerequisites - **Codex installed and logged in.** The bridge drives a real Codex session, so the `codex` CLI has to be on the machine and authenticated — install it ([developers.openai.com/codex](https://developers.openai.com/codex)), then either sign in with a ChatGPT/Codex login or set `OPENAI_API_KEY`. `inkbox-codex doctor` checks for it. -- **Python 3.10+.** The installer finds one and builds the bridge its own venv. +- **Python 3.11+.** The installer finds one and builds the bridge its own venv. - **macOS or Linux.** Boot persistence uses a systemd user unit on Linux and a launchd agent on macOS. - **An Inkbox agent** — nothing to set up in advance; the setup wizard self-signs up for you (or takes an existing API key). ## Get started — one command -This finds a Python 3.10+, installs the bridge in its own venv, puts `inkbox-codex` on your PATH, and runs the setup wizard: +This finds a Python 3.11+, installs the bridge in its own venv, puts `inkbox-codex` on your PATH, and runs the setup wizard: ```bash curl -fsSL https://raw.githubusercontent.com/inkbox-ai/codex-plugin/main/install.sh | bash @@ -70,7 +70,7 @@ you (phone) ── SMS / iMessage / email / call ──▶ Inkbox ──▶ ## Manual install -If you'd rather not run the installer (any Python 3.10+ environment): +If you'd rather not run the installer (any Python 3.11+ environment): ```bash pip install -e . diff --git a/inkbox_codex/doctor.py b/inkbox_codex/doctor.py index aabe80a..df3f45e 100644 --- a/inkbox_codex/doctor.py +++ b/inkbox_codex/doctor.py @@ -33,7 +33,7 @@ def run_doctor() -> List[Tuple[str, bool, str]]: import inkbox # noqa: F401 checks.append(("inkbox SDK", True, "installed")) except ImportError: - checks.append(("inkbox SDK", False, "pip install 'inkbox>=0.4.15,<1.0.0'")) + checks.append(("inkbox SDK", False, "pip install 'inkbox>=0.5.0,<1.0.0'")) try: import aiohttp # noqa: F401 diff --git a/inkbox_codex/gateway.py b/inkbox_codex/gateway.py index faa8119..5615932 100644 --- a/inkbox_codex/gateway.py +++ b/inkbox_codex/gateway.py @@ -509,7 +509,7 @@ async def run(self) -> None: if not AIOHTTP_AVAILABLE: raise RuntimeError("aiohttp is not installed; run: pip install aiohttp") if not INKBOX_AVAILABLE: - raise RuntimeError("inkbox SDK is not installed; run: pip install 'inkbox>=0.4.15,<1.0.0'") + raise RuntimeError("inkbox SDK is not installed; run: pip install 'inkbox>=0.5.0,<1.0.0'") if not self.cfg.api_key or not self.cfg.identity: raise RuntimeError("INKBOX_API_KEY and INKBOX_IDENTITY must be set (see README)") diff --git a/inkbox_codex/setup_wizard.py b/inkbox_codex/setup_wizard.py index 10f1587..6a98784 100644 --- a/inkbox_codex/setup_wizard.py +++ b/inkbox_codex/setup_wizard.py @@ -35,8 +35,8 @@ # Packages the wizard itself needs to talk to Inkbox during setup. The # gateway's Codex CLI dependency is checked by doctor. -INKBOX_REQUIREMENTS = ("inkbox>=0.4.20,<1.0.0", "aiohttp>=3.9") -MIN_INKBOX_VERSION = (0, 4, 20) +INKBOX_REQUIREMENTS = ("inkbox>=0.5.0,<1.0.0", "aiohttp>=3.9") +MIN_INKBOX_VERSION = (0, 5, 0) _BRACKETED_PASTE_PATTERN = re.compile(r"\x1b\[\s*200~|\x1b\[\s*201~") # Bundled avatar attached to the agent's Inkbox contact card during setup. diff --git a/install.sh b/install.sh index 142c4f6..facc29d 100755 --- a/install.sh +++ b/install.sh @@ -8,7 +8,7 @@ # # ./install.sh # -# Finds a Python 3.10+, sets up an isolated venv, installs the bridge, puts +# Finds a Python 3.11+, sets up an isolated venv, installs the bridge, puts # `inkbox-codex` on your PATH, then runs the setup wizard. Re-runnable. # # Flags: @@ -54,22 +54,22 @@ ok() { echo " ${GREEN}✓${RESET} $*"; } warn() { echo " ${YELLOW}!${RESET} $*"; } die() { echo "${RED}✗ $*${RESET}" >&2; exit 1; } -# --- 1. find Python 3.10+ -------------------------------------------------- +# --- 1. find Python 3.11+ -------------------------------------------------- find_python() { local c v maj min - for c in python3.13 python3.12 python3.11 python3.10 python3 python; do + for c in python3.13 python3.12 python3.11 python3 python; do command -v "$c" >/dev/null 2>&1 || continue v="$("$c" -c 'import sys;print("%d.%d"%sys.version_info[:2])' 2>/dev/null || echo 0.0)" maj="${v%.*}"; min="${v#*.}" - if [ "$maj" = "3" ] && [ "$min" -ge 10 ] 2>/dev/null; then + if [ "$maj" = "3" ] && [ "$min" -ge 11 ] 2>/dev/null; then echo "$c"; return 0 fi done return 1 } -step "Looking for Python 3.10+" -PY="$(find_python)" || die "No Python 3.10+ found. Install python3.11+ and re-run." +step "Looking for Python 3.11+" +PY="$(find_python)" || die "No Python 3.11+ found. Install Python 3.11 or newer and re-run." ok "using $($PY --version 2>&1) at $(command -v "$PY")" # --- 2. get the source ----------------------------------------------------- diff --git a/pyproject.toml b/pyproject.toml index 41afc18..853e7c0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,10 +2,10 @@ name = "codex-plugin" version = "0.1.4" description = "Inkbox bridge for Codex — talk to your coding agent over email, SMS, iMessage, and voice" -requires-python = ">=3.10" +requires-python = ">=3.11" dependencies = [ "aiohttp>=3.9", - "inkbox>=0.4.24,<1.0.0", + "inkbox>=0.5.0,<1.0.0", "segno>=1.5", # terminal QR codes for the iMessage connect step ] diff --git a/tests/live/test_sms.py b/tests/live/test_sms.py index fdf6edb..e5476f9 100644 --- a/tests/live/test_sms.py +++ b/tests/live/test_sms.py @@ -124,10 +124,10 @@ def _settle_inbound(sms) -> set: def _wait_new_inbound(sms, before: set, timeout_s: float, context: str) -> str: - """Poll for the first inbound not in ``before``; return its body lowercased.""" + """Poll for the earliest inbound not in ``before``; return its body lowercased.""" deadline = time.monotonic() + timeout_s while time.monotonic() < deadline: - for m in _inbound_from_aut(sms): + for m in reversed(_inbound_from_aut(sms)): if m.id not in before: body = getattr(m, "text", "") or "" bad = [x for x in ERROR_MARKERS if x in body.lower()] diff --git a/tests/test_setup_wizard.py b/tests/test_setup_wizard.py index ec4a104..3bd2386 100644 --- a/tests/test_setup_wizard.py +++ b/tests/test_setup_wizard.py @@ -88,7 +88,7 @@ def test_install_command_prefers_uv_when_available(monkeypatch): "install", "--python", "/tmp/venv/bin/python", - "inkbox>=0.4.20,<1.0.0", + "inkbox>=0.5.0,<1.0.0", "aiohttp>=3.9", ]] @@ -98,10 +98,10 @@ def test_install_command_falls_back_to_pip_and_ensurepip(monkeypatch): monkeypatch.setattr(setup_wizard.shutil, "which", lambda _name: None) assert setup_wizard._install_commands() == [ - [["/tmp/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.20,<1.0.0", "aiohttp>=3.9"]], + [["/tmp/venv/bin/python", "-m", "pip", "install", "inkbox>=0.5.0,<1.0.0", "aiohttp>=3.9"]], [ ["/tmp/venv/bin/python", "-m", "ensurepip", "--upgrade"], - ["/tmp/venv/bin/python", "-m", "pip", "install", "inkbox>=0.4.20,<1.0.0", "aiohttp>=3.9"], + ["/tmp/venv/bin/python", "-m", "pip", "install", "inkbox>=0.5.0,<1.0.0", "aiohttp>=3.9"], ], ] @@ -120,7 +120,7 @@ def fail_import(): out = capsys.readouterr().out assert "/tmp/venv/bin/python" in out assert "uv pip install --python" in out - assert "inkbox>=0.4.20,<1.0.0" in out + assert "inkbox>=0.5.0,<1.0.0" in out # ----------------------------------------------------------------------