portacode 1.5.14.dev1__tar.gz → 1.5.14.dev3__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.
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/PKG-INFO +1 -1
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/_version.py +2 -2
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/codex_app_server.py +15 -5
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/codex_handlers.py +135 -19
- portacode-1.5.14.dev3/portacode/link_capture/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tests/test_codex_app_server.py +51 -6
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tests/test_codex_handlers.py +21 -5
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode.egg-info/PKG-INFO +1 -1
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode.egg-info/SOURCES.txt +1 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/.claude/agents/communication-manager.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/.claude/settings.local.json +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/.gitignore +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/.gitmodules +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/LICENSE +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/MANIFEST.in +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/Makefile +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/backup.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/build_android.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/connect.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/connect.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docker-compose.yaml +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/cloudflared-domain-connect-containers-audit.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/creative-team-brief-portacode.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/device-health-alerting-plan.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/devops-messaging-ab-tests.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/homepage-dashboard-positioning-fixes.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/images/device-transfer-button.png +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/images/device-transfer-modal.png +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/images/pair-device-button.png +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/images/pairing-request.png +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/images/student-workspace.png +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/template-guide.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/simple_device/Dockerfile +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/simple_device/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/simple_device/docker-compose.yaml +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/Dockerfile +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/.local/share/portacode/run/gateway.pid +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/.gitignore +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/db.sqlite3 +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/settings.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/urls.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/wsgi.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/admin.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/apps.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/menu.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/models.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/urls.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/views.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/docker-compose.yaml +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/manage.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/templates/treats/home.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/admin.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/apps.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/menu.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/migrations/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/urls.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/initial_content/treats/views.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/examples/workshop_fleet/instructions/WELCOME.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/__main__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/cli.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/codex_loopback_proxy.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/codex_prepare.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/client.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/automation_v2_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/base.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/chunked_content.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/cloudflare_forwarding.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/cloudflare_tunnel.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/diff_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/file_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/file_transfer_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_aware_file_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/file_system_watcher.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/git_manager.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/manager.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/models.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/test_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state/utils.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/project_state_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/proxmox_infra.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/registry.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/runtime_user.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/session.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/system_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/tab_factory.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/terminal_handlers.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/test_cloudflare_forwarding.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/test_proxmox_infra.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/test_runtime_user.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/update_handler.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/multiplex.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/terminal.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/test_webmin_proxy_config.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/webmin_proxy_config.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/data.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/exit_codes.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/keypair.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/elinks +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/gio-open +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/gnome-open +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/gvfs-open +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/kde-open +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/kfmclient +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/link_capture_exec.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/link_capture_wrapper.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/links +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/links2 +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/lynx +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/mate-open +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/netsurf +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/sensible-browser +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/w3m +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/x-www-browser +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/link_capture/bin/xdg-open +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/logging_categories.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/pairing.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/restart.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/service.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/static/js/test-ntp-clock.html +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/static/js/utils/ntp-clock.js +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/test_runtime_paths.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/test_service.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/test_terminal_exposed_services.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/cloudflared_login.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/ensure_cloudflared.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/ensure_pyyaml.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/forwarding_state.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/get_domain.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/privileged.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/service_install.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/tunneling/state.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/updater.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/utils/NTP_ARCHITECTURE.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/utils/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/utils/diff_apply.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/utils/diff_renderer.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/utils/ntp_clock.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/utils/runtime_paths.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode.egg-info/dependency_links.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode.egg-info/entry_points.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode.egg-info/requires.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode.egg-info/top_level.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/.gitignore +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/persistent_workspace/Dockerfile +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/persistent_workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/persistent_workspace/entrypoint.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/persistent_workspace/manage_classroom.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/temporary_workspace/Dockerfile +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/temporary_workspace/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/temporary_workspace/docker-compose.yaml +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/temporary_workspace/docs/device_transfere.png +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/temporary_workspace/docs/pairing_approval.png +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode_for_school/temporary_workspace/entrypoint.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/pyproject.toml +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/restore.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/run_tests.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/scripts/diagnose_codex_gateway.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/setup.cfg +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/setup.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_device_online.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_file_operations.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_git_status_ui.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_login_flow.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_navigate_testing_folder.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_play_store_screenshots.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_terminal_buffer_performance.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_terminal_interaction.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_terminal_loading_race_condition.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_modules/test_terminal_start.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_request_id.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/test_session_terminal_shutdown.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/.env.example +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/README.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/cli.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/__init__.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/base_test.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/cli_manager.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/hierarchical_runner.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/playwright_manager.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/runner.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/shared_cli_manager.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/core/test_discovery.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/testing_framework/requirements.txt +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/UI_UX/opening_a_file_on_desktop_results_in_nothing.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/UI_UX/server_occasionally_stops_communicating_with_all_devices.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/agent_context_management.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/django_server_time_sync.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/device_performance_degradation.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/git_data_not_captured_in_proxmox.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/indefinite_resource_loading.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/portacode_service_silently_down.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/premature_terminal_exit.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/project_cpu_hotspots.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/terminals_exit_upon_starting.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/websocket_client_silently_dead.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/issues/wrong_item_classification_on_client_side.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/todo/smartphone_terminal_input_frustrations.md +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/tools/generate_play_store_assets.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/tools/pairing_tester.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/tools/run_screenshot_suite.sh +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/tools/test_python_ntp_clock.py +0 -0
- {portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/validate.sh +0 -0
|
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
|
|
|
18
18
|
commit_id: str | None
|
|
19
19
|
__commit_id__: str | None
|
|
20
20
|
|
|
21
|
-
__version__ = version = '1.5.14.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 5, 14, '
|
|
21
|
+
__version__ = version = '1.5.14.dev3'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 5, 14, 'dev3')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
|
@@ -126,8 +126,12 @@ class CodexAppServer:
|
|
|
126
126
|
# JSON-RPC I/O
|
|
127
127
|
# ------------------------------------------------------------------
|
|
128
128
|
async def _initialize(self) -> None:
|
|
129
|
-
"""Send the initialize handshake and wait for its response.
|
|
130
|
-
|
|
129
|
+
"""Send the initialize handshake and wait for its response.
|
|
130
|
+
|
|
131
|
+
Uses `_request_on_running_proc` so we do not re-enter `start()` while
|
|
132
|
+
`start()` already holds `_lock` (asyncio.Lock is not reentrant).
|
|
133
|
+
"""
|
|
134
|
+
response = await self._request_on_running_proc(
|
|
131
135
|
"initialize",
|
|
132
136
|
{
|
|
133
137
|
"clientInfo": self.client_info,
|
|
@@ -143,12 +147,18 @@ class CodexAppServer:
|
|
|
143
147
|
) -> Dict[str, Any]:
|
|
144
148
|
"""Send a JSON-RPC request and return the response object."""
|
|
145
149
|
await self.start()
|
|
150
|
+
return await self._request_on_running_proc(method, params, timeout=timeout)
|
|
151
|
+
|
|
152
|
+
async def _request_on_running_proc(
|
|
153
|
+
self, method: str, params: Dict[str, Any], timeout: float = 60.0
|
|
154
|
+
) -> Dict[str, Any]:
|
|
155
|
+
"""Write a JSON-RPC request to an already-spawned app-server process."""
|
|
146
156
|
assert self._proc is not None and self._proc.stdin is not None
|
|
147
157
|
|
|
148
158
|
request_id = self._next_id
|
|
149
159
|
self._next_id += 1
|
|
150
160
|
message = {"jsonrpc": "2.0", "id": request_id, "method": method, "params": params}
|
|
151
|
-
payload = json.dumps(message, ensure_ascii=False)
|
|
161
|
+
payload = json.dumps(message, ensure_ascii=False, separators=(",", ":"))
|
|
152
162
|
|
|
153
163
|
loop = asyncio.get_running_loop()
|
|
154
164
|
future: asyncio.Future = loop.create_future()
|
|
@@ -172,7 +182,7 @@ class CodexAppServer:
|
|
|
172
182
|
await self.start()
|
|
173
183
|
assert self._proc is not None and self._proc.stdin is not None
|
|
174
184
|
message = {"jsonrpc": "2.0", "method": method, "params": params}
|
|
175
|
-
payload = json.dumps(message, ensure_ascii=False)
|
|
185
|
+
payload = json.dumps(message, ensure_ascii=False, separators=(",", ":"))
|
|
176
186
|
self._proc.stdin.write((payload + "\n").encode("utf-8"))
|
|
177
187
|
await self._proc.stdin.drain()
|
|
178
188
|
|
|
@@ -180,7 +190,7 @@ class CodexAppServer:
|
|
|
180
190
|
"""Reply to a server->client request with a JSON-RPC error."""
|
|
181
191
|
assert self._proc is not None and self._proc.stdin is not None
|
|
182
192
|
response = {"jsonrpc": "2.0", "id": request_id, "error": {"code": code, "message": message}}
|
|
183
|
-
payload = json.dumps(response, ensure_ascii=False)
|
|
193
|
+
payload = json.dumps(response, ensure_ascii=False, separators=(",", ":"))
|
|
184
194
|
self._proc.stdin.write((payload + "\n").encode("utf-8"))
|
|
185
195
|
await self._proc.stdin.drain()
|
|
186
196
|
|
{portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/portacode/connection/handlers/codex_handlers.py
RENAMED
|
@@ -86,20 +86,122 @@ def _project_id(message: Dict[str, Any]) -> Optional[str]:
|
|
|
86
86
|
return message.get("project_id")
|
|
87
87
|
|
|
88
88
|
|
|
89
|
-
|
|
89
|
+
def _thread_from_result(result: Dict[str, Any]) -> Dict[str, Any]:
|
|
90
|
+
"""Normalize thread/start|resume|read results to a thread object.
|
|
91
|
+
|
|
92
|
+
Current app-server returns `{ "thread": { "id": ... } }`. Older fakes /
|
|
93
|
+
builds may return the thread fields at the top level.
|
|
94
|
+
"""
|
|
95
|
+
if not isinstance(result, dict):
|
|
96
|
+
return {}
|
|
97
|
+
thread = result.get("thread")
|
|
98
|
+
if isinstance(thread, dict):
|
|
99
|
+
return thread
|
|
100
|
+
return result
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _thread_id_from_result(result: Dict[str, Any]) -> Optional[str]:
|
|
104
|
+
thread = _thread_from_result(result)
|
|
105
|
+
return thread.get("id") or result.get("id") or result.get("threadId")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _threads_from_list_result(result: Dict[str, Any]) -> tuple[list, Optional[str]]:
|
|
109
|
+
"""Normalize thread/list results.
|
|
110
|
+
|
|
111
|
+
Current app-server returns `{ "data": [...], "nextCursor": ... }`.
|
|
112
|
+
"""
|
|
113
|
+
if not isinstance(result, dict):
|
|
114
|
+
return [], None
|
|
115
|
+
threads = result.get("data")
|
|
116
|
+
if threads is None:
|
|
117
|
+
threads = result.get("threads")
|
|
118
|
+
if not isinstance(threads, list):
|
|
119
|
+
threads = []
|
|
120
|
+
return threads, result.get("nextCursor")
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def _items_from_read_result(result: Dict[str, Any]) -> list:
|
|
124
|
+
"""Extract conversation items from thread/read (or legacy shapes)."""
|
|
125
|
+
if not isinstance(result, dict):
|
|
126
|
+
return []
|
|
127
|
+
if isinstance(result.get("items"), list):
|
|
128
|
+
return result["items"]
|
|
129
|
+
if isinstance(result.get("messages"), list):
|
|
130
|
+
return result["messages"]
|
|
131
|
+
|
|
132
|
+
thread = _thread_from_result(result)
|
|
133
|
+
turns = thread.get("turns") or result.get("turns") or []
|
|
134
|
+
items: list = []
|
|
135
|
+
if isinstance(turns, list):
|
|
136
|
+
for turn in turns:
|
|
137
|
+
if not isinstance(turn, dict):
|
|
138
|
+
continue
|
|
139
|
+
turn_items = turn.get("items")
|
|
140
|
+
if isinstance(turn_items, list):
|
|
141
|
+
items.extend(turn_items)
|
|
142
|
+
return items
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _turn_from_result(result: Dict[str, Any]) -> Dict[str, Any]:
|
|
146
|
+
if not isinstance(result, dict):
|
|
147
|
+
return {}
|
|
148
|
+
turn = result.get("turn")
|
|
149
|
+
if isinstance(turn, dict):
|
|
150
|
+
return turn
|
|
151
|
+
return result
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
class CodexAsyncHandler(AsyncHandler):
|
|
155
|
+
"""AsyncHandler that replies to `source_client_session` per WEBSOCKET_PROTOCOL.md."""
|
|
156
|
+
|
|
157
|
+
async def handle(self, message: Dict[str, Any], reply_channel: Optional[str] = None) -> None:
|
|
158
|
+
try:
|
|
159
|
+
response = await self.execute(message)
|
|
160
|
+
if response is None:
|
|
161
|
+
return
|
|
162
|
+
if "request_id" in message and "request_id" not in response:
|
|
163
|
+
response["request_id"] = message["request_id"]
|
|
164
|
+
|
|
165
|
+
source_client_session = message.get("source_client_session")
|
|
166
|
+
project_id = response.get("project_id") or _project_id(message)
|
|
167
|
+
if project_id and "project_id" not in response:
|
|
168
|
+
response["project_id"] = project_id
|
|
169
|
+
|
|
170
|
+
if source_client_session:
|
|
171
|
+
payload = dict(response)
|
|
172
|
+
payload["client_sessions"] = [source_client_session]
|
|
173
|
+
await self.control_channel.send(payload)
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
await self.send_response(response, reply_channel, project_id)
|
|
177
|
+
except Exception as exc:
|
|
178
|
+
LOGGER.exception("handler: Error in codex handler %s: %s", self.command_name, exc)
|
|
179
|
+
await self.send_error(
|
|
180
|
+
str(exc),
|
|
181
|
+
reply_channel,
|
|
182
|
+
_project_id(message),
|
|
183
|
+
request_id=message.get("request_id"),
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class CodexStatusHandler(CodexAsyncHandler):
|
|
90
188
|
"""Report whether Codex is installed and the app-server is healthy."""
|
|
91
189
|
|
|
190
|
+
@property
|
|
92
191
|
def command_name(self) -> str:
|
|
93
192
|
return "codex_status"
|
|
94
193
|
|
|
95
194
|
async def execute(self, message: Dict[str, Any]) -> Dict[str, Any]:
|
|
96
195
|
installed = bool(CodexAppServer.get_binary_path())
|
|
97
|
-
|
|
196
|
+
# Avoid blocking the asyncio loop with a sync subprocess during status.
|
|
197
|
+
version = None
|
|
98
198
|
ready = False
|
|
99
199
|
error_message: Optional[str] = None
|
|
100
200
|
|
|
101
201
|
if installed:
|
|
102
202
|
try:
|
|
203
|
+
loop = asyncio.get_running_loop()
|
|
204
|
+
version = await loop.run_in_executor(None, CodexAppServer.version)
|
|
103
205
|
manager = _get_manager(self)
|
|
104
206
|
await manager.ensure_started()
|
|
105
207
|
ready = await manager.bridge.healthy()
|
|
@@ -121,9 +223,10 @@ class CodexStatusHandler(AsyncHandler):
|
|
|
121
223
|
return payload
|
|
122
224
|
|
|
123
225
|
|
|
124
|
-
class CodexThreadListHandler(
|
|
226
|
+
class CodexThreadListHandler(CodexAsyncHandler):
|
|
125
227
|
"""List Codex threads for a given project cwd."""
|
|
126
228
|
|
|
229
|
+
@property
|
|
127
230
|
def command_name(self) -> str:
|
|
128
231
|
return "codex_thread_list"
|
|
129
232
|
|
|
@@ -135,19 +238,23 @@ class CodexThreadListHandler(AsyncHandler):
|
|
|
135
238
|
manager = _get_manager(self)
|
|
136
239
|
await manager.ensure_started()
|
|
137
240
|
|
|
138
|
-
|
|
139
|
-
|
|
241
|
+
# Default sourceKinds is cli+vscode only; include appServer so IDE chats appear.
|
|
242
|
+
# Avoid useStateDbOnly:true — it has returned empty lists in some Codex builds.
|
|
243
|
+
params: Dict[str, Any] = {
|
|
244
|
+
"cwd": cwd,
|
|
245
|
+
"sourceKinds": ["cli", "vscode", "appServer"],
|
|
246
|
+
"limit": message.get("limit") if message.get("limit") is not None else 50,
|
|
247
|
+
}
|
|
140
248
|
cursor = message.get("cursor")
|
|
141
|
-
if limit is not None:
|
|
142
|
-
params["limit"] = limit
|
|
143
249
|
if cursor is not None:
|
|
144
250
|
params["cursor"] = cursor
|
|
145
251
|
|
|
146
252
|
result = await manager.bridge.call("thread/list", params)
|
|
253
|
+
threads, next_cursor = _threads_from_list_result(result)
|
|
147
254
|
payload = {
|
|
148
255
|
"event": "codex_thread_list",
|
|
149
|
-
"threads":
|
|
150
|
-
"nextCursor":
|
|
256
|
+
"threads": threads,
|
|
257
|
+
"nextCursor": next_cursor,
|
|
151
258
|
}
|
|
152
259
|
project_id = _project_id(message)
|
|
153
260
|
if project_id:
|
|
@@ -155,9 +262,10 @@ class CodexThreadListHandler(AsyncHandler):
|
|
|
155
262
|
return payload
|
|
156
263
|
|
|
157
264
|
|
|
158
|
-
class CodexThreadStartHandler(
|
|
265
|
+
class CodexThreadStartHandler(CodexAsyncHandler):
|
|
159
266
|
"""Start a new Codex thread in the project directory."""
|
|
160
267
|
|
|
268
|
+
@property
|
|
161
269
|
def command_name(self) -> str:
|
|
162
270
|
return "codex_thread_start"
|
|
163
271
|
|
|
@@ -178,7 +286,8 @@ class CodexThreadStartHandler(AsyncHandler):
|
|
|
178
286
|
params["modelProvider"] = message["modelProvider"]
|
|
179
287
|
|
|
180
288
|
result = await manager.bridge.call("thread/start", params)
|
|
181
|
-
|
|
289
|
+
thread = _thread_from_result(result)
|
|
290
|
+
thread_id = _thread_id_from_result(result)
|
|
182
291
|
if not thread_id:
|
|
183
292
|
raise CodexAppServerError("thread/start did not return a thread id")
|
|
184
293
|
|
|
@@ -187,16 +296,17 @@ class CodexThreadStartHandler(AsyncHandler):
|
|
|
187
296
|
payload = {
|
|
188
297
|
"event": "codex_thread_started",
|
|
189
298
|
"threadId": thread_id,
|
|
190
|
-
"thread":
|
|
299
|
+
"thread": thread,
|
|
191
300
|
}
|
|
192
301
|
if project_id:
|
|
193
302
|
payload["project_id"] = project_id
|
|
194
303
|
return payload
|
|
195
304
|
|
|
196
305
|
|
|
197
|
-
class CodexThreadResumeHandler(
|
|
306
|
+
class CodexThreadResumeHandler(CodexAsyncHandler):
|
|
198
307
|
"""Resume a Codex thread and return its history."""
|
|
199
308
|
|
|
309
|
+
@property
|
|
200
310
|
def command_name(self) -> str:
|
|
201
311
|
return "codex_thread_resume"
|
|
202
312
|
|
|
@@ -215,8 +325,11 @@ class CodexThreadResumeHandler(AsyncHandler):
|
|
|
215
325
|
resume_params["cwd"] = cwd
|
|
216
326
|
await manager.bridge.call("thread/resume", resume_params)
|
|
217
327
|
|
|
218
|
-
read_result = await manager.bridge.call(
|
|
219
|
-
|
|
328
|
+
read_result = await manager.bridge.call(
|
|
329
|
+
"thread/read",
|
|
330
|
+
{"threadId": thread_id, "includeTurns": True},
|
|
331
|
+
)
|
|
332
|
+
items = _items_from_read_result(read_result)
|
|
220
333
|
|
|
221
334
|
if cwd and project_id:
|
|
222
335
|
manager.record_thread(thread_id, cwd, project_id)
|
|
@@ -231,9 +344,10 @@ class CodexThreadResumeHandler(AsyncHandler):
|
|
|
231
344
|
return payload
|
|
232
345
|
|
|
233
346
|
|
|
234
|
-
class CodexTurnStartHandler(
|
|
347
|
+
class CodexTurnStartHandler(CodexAsyncHandler):
|
|
235
348
|
"""Send a user turn to a Codex thread."""
|
|
236
349
|
|
|
350
|
+
@property
|
|
237
351
|
def command_name(self) -> str:
|
|
238
352
|
return "codex_turn_start"
|
|
239
353
|
|
|
@@ -264,16 +378,17 @@ class CodexTurnStartHandler(AsyncHandler):
|
|
|
264
378
|
payload = {
|
|
265
379
|
"event": "codex_turn_started",
|
|
266
380
|
"threadId": thread_id,
|
|
267
|
-
"turn": result,
|
|
381
|
+
"turn": _turn_from_result(result),
|
|
268
382
|
}
|
|
269
383
|
if project_id:
|
|
270
384
|
payload["project_id"] = project_id
|
|
271
385
|
return payload
|
|
272
386
|
|
|
273
387
|
|
|
274
|
-
class CodexTurnInterruptHandler(
|
|
388
|
+
class CodexTurnInterruptHandler(CodexAsyncHandler):
|
|
275
389
|
"""Interrupt a running Codex turn."""
|
|
276
390
|
|
|
391
|
+
@property
|
|
277
392
|
def command_name(self) -> str:
|
|
278
393
|
return "codex_turn_interrupt"
|
|
279
394
|
|
|
@@ -294,7 +409,7 @@ class CodexTurnInterruptHandler(AsyncHandler):
|
|
|
294
409
|
return payload
|
|
295
410
|
|
|
296
411
|
|
|
297
|
-
class CodexPrepareHandler(
|
|
412
|
+
class CodexPrepareHandler(CodexAsyncHandler):
|
|
298
413
|
"""Run `portacode prepare codex` on the device in the background.
|
|
299
414
|
|
|
300
415
|
Streams progress as `codex_prepare_progress` events and finishes with a
|
|
@@ -302,6 +417,7 @@ class CodexPrepareHandler(AsyncHandler):
|
|
|
302
417
|
show manual instructions when sudo is required).
|
|
303
418
|
"""
|
|
304
419
|
|
|
420
|
+
@property
|
|
305
421
|
def command_name(self) -> str:
|
|
306
422
|
return "codex_prepare"
|
|
307
423
|
|
|
@@ -11,11 +11,14 @@ from portacode.connection.codex_app_server import CodexAppServer, CodexAppServer
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
class FakeWriteStream:
|
|
14
|
-
def __init__(self) -> None:
|
|
14
|
+
def __init__(self, process: "FakeProcess | None" = None) -> None:
|
|
15
15
|
self.written: list[bytes] = []
|
|
16
|
+
self._process = process
|
|
16
17
|
|
|
17
18
|
def write(self, data: bytes) -> None:
|
|
18
19
|
self.written.append(data)
|
|
20
|
+
if self._process is not None:
|
|
21
|
+
self._process._maybe_auto_respond(data)
|
|
19
22
|
|
|
20
23
|
async def drain(self) -> None:
|
|
21
24
|
pass
|
|
@@ -41,13 +44,38 @@ class FakeReadStream:
|
|
|
41
44
|
class FakeProcess:
|
|
42
45
|
returncode: int | None = None
|
|
43
46
|
|
|
44
|
-
def __init__(
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
responses: list[dict] | None = None,
|
|
50
|
+
*,
|
|
51
|
+
auto_initialize: bool = False,
|
|
52
|
+
) -> None:
|
|
45
53
|
self.queue: asyncio.Queue[bytes] = asyncio.Queue()
|
|
46
54
|
for response in responses or []:
|
|
47
|
-
self.queue.put_nowait(
|
|
48
|
-
|
|
55
|
+
self.queue.put_nowait(
|
|
56
|
+
(json.dumps(response, separators=(",", ":")) + "\n").encode("utf-8")
|
|
57
|
+
)
|
|
58
|
+
self.stdin = FakeWriteStream(self if auto_initialize else None)
|
|
49
59
|
self.stdout = FakeReadStream(self.queue)
|
|
50
60
|
self.stderr = FakeReadStream(asyncio.Queue())
|
|
61
|
+
self._auto_initialize = auto_initialize
|
|
62
|
+
|
|
63
|
+
def _maybe_auto_respond(self, data: bytes) -> None:
|
|
64
|
+
if not self._auto_initialize:
|
|
65
|
+
return
|
|
66
|
+
try:
|
|
67
|
+
message = json.loads(data.decode("utf-8").strip())
|
|
68
|
+
except Exception:
|
|
69
|
+
return
|
|
70
|
+
if message.get("method") != "initialize":
|
|
71
|
+
return
|
|
72
|
+
request_id = message.get("id")
|
|
73
|
+
if request_id is None:
|
|
74
|
+
return
|
|
75
|
+
self.queue.put_nowait((json.dumps(
|
|
76
|
+
{"jsonrpc": "2.0", "id": request_id, "result": {"protocolVersion": "v2"}},
|
|
77
|
+
separators=(",", ":"),
|
|
78
|
+
) + "\n").encode("utf-8"))
|
|
51
79
|
|
|
52
80
|
async def wait(self) -> int:
|
|
53
81
|
return self.returncode or 0
|
|
@@ -85,12 +113,28 @@ async def test_initialize_handshake():
|
|
|
85
113
|
|
|
86
114
|
@pytest.mark.asyncio
|
|
87
115
|
async def test_request_response_correlation():
|
|
116
|
+
# Only preload the initialize response. Queuing the call response early can
|
|
117
|
+
# race the reader ahead of the pending-future registration.
|
|
88
118
|
proc = FakeProcess([
|
|
89
119
|
{"jsonrpc": "2.0", "id": 1, "result": {"protocolVersion": "v2"}},
|
|
90
|
-
{"jsonrpc": "2.0", "id": 2, "result": {"id": "th-abc", "name": "test"}},
|
|
91
120
|
])
|
|
92
121
|
bridge = CodexAppServer(_process_factory=_factory_for(proc))
|
|
122
|
+
await bridge.start()
|
|
123
|
+
|
|
124
|
+
async def _respond_to_thread_start() -> None:
|
|
125
|
+
# Wait until the request is written, then enqueue the matching response.
|
|
126
|
+
for _ in range(50):
|
|
127
|
+
if any(b'"method":"thread/start"' in chunk for chunk in proc.stdin.written):
|
|
128
|
+
break
|
|
129
|
+
await asyncio.sleep(0.01)
|
|
130
|
+
proc.queue.put_nowait((json.dumps(
|
|
131
|
+
{"jsonrpc": "2.0", "id": 2, "result": {"id": "th-abc", "name": "test"}},
|
|
132
|
+
separators=(",", ":"),
|
|
133
|
+
) + "\n").encode("utf-8"))
|
|
134
|
+
|
|
135
|
+
respond_task = asyncio.create_task(_respond_to_thread_start())
|
|
93
136
|
result = await bridge.call("thread/start", {"cwd": "/tmp/proj"})
|
|
137
|
+
await respond_task
|
|
94
138
|
|
|
95
139
|
assert result["id"] == "th-abc"
|
|
96
140
|
assert any(b'"method":"thread/start"' in chunk and b'/tmp/proj' in chunk for chunk in proc.stdin.written)
|
|
@@ -148,7 +192,8 @@ async def test_missing_binary_raises():
|
|
|
148
192
|
@pytest.mark.asyncio
|
|
149
193
|
async def test_restart_after_crash():
|
|
150
194
|
first = FakeProcess([{"jsonrpc": "2.0", "id": 1, "result": {"protocolVersion": "v2"}}])
|
|
151
|
-
|
|
195
|
+
# Auto-echo initialize with whatever request id the restarted bridge uses.
|
|
196
|
+
second = FakeProcess(auto_initialize=True)
|
|
152
197
|
|
|
153
198
|
bridge = CodexAppServer(_process_factory=_factory_for(first, second))
|
|
154
199
|
await bridge.start()
|
|
@@ -43,11 +43,20 @@ class FakeBridge:
|
|
|
43
43
|
def __init__(self) -> None:
|
|
44
44
|
self.calls: list[tuple[str, dict]] = []
|
|
45
45
|
self.responses: dict[str, Any] = {
|
|
46
|
-
|
|
47
|
-
"thread/
|
|
48
|
-
"thread/
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
# Match current Codex app-server response shapes.
|
|
47
|
+
"thread/start": {"thread": {"id": "th-1", "name": "New chat"}},
|
|
48
|
+
"thread/list": {
|
|
49
|
+
"data": [{"id": "th-1", "name": "Existing chat", "preview": "hi"}],
|
|
50
|
+
"nextCursor": None,
|
|
51
|
+
},
|
|
52
|
+
"thread/resume": {"thread": {"id": "th-1"}},
|
|
53
|
+
"thread/read": {
|
|
54
|
+
"thread": {
|
|
55
|
+
"id": "th-1",
|
|
56
|
+
"turns": [{"id": "turn-1", "items": [{"id": "msg-1", "role": "user", "text": "hello"}]}],
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
"turn/start": {"turn": {"id": "turn-1", "threadId": "th-1"}},
|
|
51
60
|
"turn/interrupt": {},
|
|
52
61
|
}
|
|
53
62
|
|
|
@@ -103,6 +112,11 @@ async def test_codex_thread_list():
|
|
|
103
112
|
assert payload["event"] == "codex_thread_list"
|
|
104
113
|
assert payload["threads"][0]["id"] == "th-1"
|
|
105
114
|
assert payload["project_id"] == "p-1"
|
|
115
|
+
list_call = manager.bridge.calls[-1]
|
|
116
|
+
assert list_call[0] == "thread/list"
|
|
117
|
+
assert list_call[1]["cwd"] == "/tmp/proj"
|
|
118
|
+
assert "appServer" in list_call[1]["sourceKinds"]
|
|
119
|
+
assert "useStateDbOnly" not in list_call[1]
|
|
106
120
|
|
|
107
121
|
|
|
108
122
|
@pytest.mark.asyncio
|
|
@@ -138,6 +152,8 @@ async def test_codex_thread_resume():
|
|
|
138
152
|
assert payload["event"] == "codex_thread_resumed"
|
|
139
153
|
assert payload["items"][0]["text"] == "hello"
|
|
140
154
|
assert manager._thread_project["th-1"] == "p-1"
|
|
155
|
+
read_call = next(c for c in manager.bridge.calls if c[0] == "thread/read")
|
|
156
|
+
assert read_call[1]["includeTurns"] is True
|
|
141
157
|
|
|
142
158
|
|
|
143
159
|
@pytest.mark.asyncio
|
|
@@ -340,6 +340,7 @@ portacode/connection/handlers/project_state/models.py
|
|
|
340
340
|
portacode/connection/handlers/project_state/test_handlers.py
|
|
341
341
|
portacode/connection/handlers/project_state/utils.py
|
|
342
342
|
portacode/link_capture/__init__.py
|
|
343
|
+
portacode/link_capture/__pycache__/__init__.cpython-311.pyc
|
|
343
344
|
portacode/link_capture/bin/elinks
|
|
344
345
|
portacode/link_capture/bin/gio-open
|
|
345
346
|
portacode/link_capture/bin/gnome-open
|
|
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
|
{portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/cloudflared-domain-connect-containers-audit.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-1.5.14.dev1 → portacode-1.5.14.dev3}/docs/homepage-dashboard-positioning-fixes.md
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|