portacode 1.5.21.dev2__tar.gz → 1.5.21.dev4__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.21.dev4/AGENTS.md +53 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/PKG-INFO +1 -1
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/_version.py +2 -2
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/codex_handlers.py +17 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/system_handlers.py +9 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tests/test_codex_handlers.py +25 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode.egg-info/PKG-INFO +1 -1
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode.egg-info/SOURCES.txt +1 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_play_store_screenshots.py +70 -17
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/.claude/agents/communication-manager.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/.claude/settings.local.json +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/.gitignore +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/.gitmodules +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/LICENSE +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/MANIFEST.in +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/Makefile +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/build_android.sh +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/connect.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/connect.sh +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/cloudflared-domain-connect-containers-audit.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/creative-team-brief-portacode.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/device-health-alerting-plan.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/devops-messaging-ab-tests.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/homepage-dashboard-positioning-fixes.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/images/device-transfer-button.png +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/images/device-transfer-modal.png +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/images/pair-device-button.png +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/images/pairing-request.png +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/images/student-workspace.png +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/docs/template-guide.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/simple_device/Dockerfile +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/simple_device/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/simple_device/docker-compose.yaml +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/Dockerfile +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/.local/share/portacode/run/gateway.pid +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/.gitignore +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/db.sqlite3 +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/settings.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/urls.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/wsgi.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/admin.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/apps.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/menu.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/models.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/urls.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/views.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-01/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-02/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-03/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-04/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-05/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-06/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-07/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-08/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-09/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode.pub +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/data/student-10/workspace/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/docker-compose.yaml +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/asgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/settings.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/galactic_bakeshop/wsgi.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/manage.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/templates/treats/home.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/admin.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/apps.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/menu.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/migrations/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/urls.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/initial_content/treats/views.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/examples/workshop_fleet/instructions/WELCOME.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/__main__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/cli.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/codex_loopback_proxy.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/codex_prepare.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/codex_usage_limit.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/client.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/codex_app_server.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/automation_v2_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/base.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/chunked_content.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/cloudflare_forwarding.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/cloudflare_tunnel.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/diff_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/file_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/file_transfer_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_aware_file_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/file_system_watcher.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/git_manager.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/manager.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/models.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/test_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state/utils.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/project_state_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/proxmox_infra.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/registry.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/resumable_transfer_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/runtime_user.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/session.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/tab_factory.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/terminal_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/test_cloudflare_forwarding.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/test_file_move_copy.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/test_proxmox_infra.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/test_runtime_user.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/update_handler.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/multiplex.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/terminal.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/test_webmin_proxy_config.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/webmin_proxy_config.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/data.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/exit_codes.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/github_credential.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/keypair.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/__pycache__/__init__.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/__pycache__/__init__.cpython-38.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/__pycache__/link_capture_wrapper.cpython-311.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/__pycache__/link_capture_wrapper.cpython-38.pyc +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/elinks +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/gio-open +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/gnome-open +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/gvfs-open +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/kde-open +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/kfmclient +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/link_capture_exec.sh +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/link_capture_wrapper.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/links +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/links2 +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/lynx +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/mate-open +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/netsurf +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/sensible-browser +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/w3m +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/x-www-browser +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/link_capture/bin/xdg-open +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/logging_categories.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/pairing.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/restart.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/service.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/singleton.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/static/js/test-ntp-clock.html +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/static/js/utils/ntp-clock.js +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/test_runtime_paths.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/test_service.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/test_singleton.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/test_terminal_exposed_services.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tests/test_codex_app_server.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tests/test_codex_loopback_proxy.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tests/test_codex_prepare.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tests/test_github_credential.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tests/test_resumable_transfer_handlers.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/cloudflared_login.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/ensure_cloudflared.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/ensure_pyyaml.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/forwarding_state.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/get_domain.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/privileged.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/service_install.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/tunneling/state.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/updater.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/utils/NTP_ARCHITECTURE.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/utils/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/utils/diff_apply.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/utils/diff_renderer.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/utils/ntp_clock.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/utils/runtime_paths.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode.egg-info/dependency_links.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode.egg-info/entry_points.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode.egg-info/requires.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode.egg-info/top_level.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/.gitignore +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/persistent_workspace/Dockerfile +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/persistent_workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/persistent_workspace/entrypoint.sh +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/persistent_workspace/manage_classroom.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/temporary_workspace/Dockerfile +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/temporary_workspace/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/temporary_workspace/docker-compose.yaml +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/temporary_workspace/docs/device_transfere.png +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/temporary_workspace/docs/pairing_approval.png +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode_for_school/temporary_workspace/entrypoint.sh +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/pyproject.toml +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/run_tests.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/scripts/diagnose_codex_gateway.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/setup.cfg +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/setup.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test.sh +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_device_online.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_file_operations.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_git_status_ui.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_login_flow.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_navigate_testing_folder.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_terminal_buffer_performance.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_terminal_interaction.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_terminal_loading_race_condition.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_modules/test_terminal_start.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_request_id.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/test_session_terminal_shutdown.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/.env.example +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/README.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/cli.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/__init__.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/base_test.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/cli_manager.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/hierarchical_runner.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/playwright_manager.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/runner.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/shared_cli_manager.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/core/test_discovery.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/testing_framework/requirements.txt +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/UI_UX/opening_a_file_on_desktop_results_in_nothing.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/UI_UX/server_occasionally_stops_communicating_with_all_devices.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/agent_context_management.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/django_server_time_sync.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/device_performance_degradation.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/git_data_not_captured_in_proxmox.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/indefinite_resource_loading.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/portacode_service_silently_down.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/premature_terminal_exit.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/project_cpu_hotspots.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/terminals_exit_upon_starting.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/websocket_client_silently_dead.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/issues/wrong_item_classification_on_client_side.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/todo/smartphone_terminal_input_frustrations.md +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/tools/generate_play_store_assets.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/tools/pairing_tester.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/tools/run_screenshot_suite.sh +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/tools/test_python_ntp_clock.py +0 -0
- {portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/validate.sh +0 -0
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Portacode agent guidance
|
|
2
|
+
|
|
3
|
+
These rules apply to the whole repository. More specific `AGENTS.md` files add
|
|
4
|
+
instructions for their subtrees.
|
|
5
|
+
|
|
6
|
+
## Private server submodule
|
|
7
|
+
|
|
8
|
+
- `server/` is a private, confidential submodule available only to authorized
|
|
9
|
+
Portacode team members. Do not copy its source, credentials, configuration,
|
|
10
|
+
deployment details, or other non-public information into the public parent
|
|
11
|
+
repository, public issues, release notes, logs, or responses to unauthorized
|
|
12
|
+
users.
|
|
13
|
+
- When a task touches server-side behavior, enter the `server/` submodule and
|
|
14
|
+
read `server/AGENTS.md` completely before inspecting or changing server code.
|
|
15
|
+
Follow both files, with the more specific server instructions taking
|
|
16
|
+
precedence for that subtree.
|
|
17
|
+
- Keep parent-repository and server-submodule changes clearly separated when
|
|
18
|
+
reviewing status, diffs, tests, commits, and releases. Never assume committing
|
|
19
|
+
the parent repository also commits unpublished server changes.
|
|
20
|
+
|
|
21
|
+
## Device-side CLI deployment and live debugging
|
|
22
|
+
|
|
23
|
+
- Treat the repository checkout and the installed `portacode` CLI as separate
|
|
24
|
+
artifacts. The system service runs the installed PyPI package; restarting
|
|
25
|
+
`portacode.service` does **not** load Python changes from this checkout.
|
|
26
|
+
- Never run `systemctl restart portacode.service`, kill its process, or otherwise
|
|
27
|
+
manipulate the Portacode system service merely to activate source edits.
|
|
28
|
+
Doing so interrupts the device connection and active Codex app-server
|
|
29
|
+
sessions without deploying the edited code.
|
|
30
|
+
- The normal device-side deployment workflow is:
|
|
31
|
+
1. After tests pass and the user has authorized publishing, publish an explicit
|
|
32
|
+
development version with `make release VERSION=<version>`.
|
|
33
|
+
2. Install and activate that package with `portacode setversion <version>`.
|
|
34
|
+
This command owns installation and the appropriate supervised restart.
|
|
35
|
+
- Publishing a package/tag is an external release action. Do not choose a
|
|
36
|
+
version or run `make release` without the user's explicit authorization.
|
|
37
|
+
- Before running `portacode setversion`, check the device and privilege context
|
|
38
|
+
with a non-mutating test such as `sudo -n true`. When the required privileges
|
|
39
|
+
are unavailable, ask the user to run the command. Do not substitute direct
|
|
40
|
+
`systemctl`, process signals, or ad hoc `pip` installation. On an authorized
|
|
41
|
+
managed device with verified passwordless sudo, the agent may run the command
|
|
42
|
+
after the user has authorized the update.
|
|
43
|
+
- For a faster edit/debug loop, use `./connect.sh [log-categories]` to run the
|
|
44
|
+
checkout directly instead of publishing and installing a package. It starts
|
|
45
|
+
a non-interactive debug connection and enforces the singleton connection.
|
|
46
|
+
- Do not launch `./connect.sh` from a session hosted by the active Portacode
|
|
47
|
+
connection. Replacing the singleton connection can terminate the session that
|
|
48
|
+
launched it. Arrange an independent shell with the user first, then have the
|
|
49
|
+
user stop/replace the installed connection or start the debug connection from
|
|
50
|
+
that independent shell.
|
|
51
|
+
- Before any device-side activation, state which mode is being used: published
|
|
52
|
+
PyPI version via `portacode setversion`, or live checkout via `./connect.sh`.
|
|
53
|
+
Confirm the installed/running version or process source afterward.
|
|
@@ -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.21.
|
|
22
|
-
__version_tuple__ = version_tuple = (1, 5, 21, '
|
|
21
|
+
__version__ = version = '1.5.21.dev4'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 5, 21, 'dev4')
|
|
23
23
|
|
|
24
24
|
__commit_id__ = commit_id = None
|
{portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/codex_handlers.py
RENAMED
|
@@ -195,6 +195,9 @@ class CodexChatManager:
|
|
|
195
195
|
# its reconnect snapshot would make resume return the same turn in
|
|
196
196
|
# both `items` and `liveItems`.
|
|
197
197
|
self._thread_live_items.pop(str(thread_id), None)
|
|
198
|
+
elif thread_id and method == "error" and not params.get("willRetry"):
|
|
199
|
+
self._thread_active_turn.pop(str(thread_id), None)
|
|
200
|
+
self._thread_live_items.pop(str(thread_id), None)
|
|
198
201
|
if thread_id:
|
|
199
202
|
params = self._materialize_and_bound_notification(str(thread_id), method, params)
|
|
200
203
|
project_id = self._resolve_project_id(params)
|
|
@@ -694,6 +697,20 @@ class CodexThreadListHandler(CodexAsyncHandler):
|
|
|
694
697
|
|
|
695
698
|
result = await manager.bridge.call("thread/list", params)
|
|
696
699
|
threads, next_cursor = _threads_from_list_result(result)
|
|
700
|
+
# app-server metadata is not consistently refreshed while a turn is
|
|
701
|
+
# running. The manager receives the authoritative lifecycle events.
|
|
702
|
+
for thread in threads:
|
|
703
|
+
if not isinstance(thread, dict) or not thread.get("id"):
|
|
704
|
+
continue
|
|
705
|
+
active_turn_id = manager._thread_active_turn.get(str(thread["id"]))
|
|
706
|
+
listed_status = str(thread.get("status") or "").lower().replace("_", "")
|
|
707
|
+
thread["isWorking"] = bool(active_turn_id) or listed_status in {
|
|
708
|
+
"inprogress", "active", "running", "working"
|
|
709
|
+
}
|
|
710
|
+
if active_turn_id:
|
|
711
|
+
thread["activeTurnId"] = active_turn_id
|
|
712
|
+
else:
|
|
713
|
+
thread.pop("activeTurnId", None)
|
|
697
714
|
payload = {
|
|
698
715
|
"event": "codex_thread_list",
|
|
699
716
|
"threads": threads,
|
{portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/portacode/connection/handlers/system_handlers.py
RENAMED
|
@@ -27,6 +27,7 @@ from .base import SyncHandler
|
|
|
27
27
|
from .proxmox_infra import get_infra_snapshot
|
|
28
28
|
from .runtime_user import get_default_runtime_user, get_runtime_user_home
|
|
29
29
|
from portacode.tunneling.forwarding_state import load_forwarding_state
|
|
30
|
+
from portacode.connection.codex_app_server import CodexAppServer
|
|
30
31
|
|
|
31
32
|
logger = logging.getLogger(__name__)
|
|
32
33
|
|
|
@@ -617,6 +618,14 @@ class SystemInfoHandler(SyncHandler):
|
|
|
617
618
|
info["proxmox"] = _get_proxmox_info()
|
|
618
619
|
info["cloudflare_tunnel"] = _get_cloudflare_tunnel_state()
|
|
619
620
|
info["cloudflare_forwarding"] = _get_cloudflare_forwarding_state()
|
|
621
|
+
# Capability discovery belongs in the device snapshot. The dashboard
|
|
622
|
+
# receives system_info on connect and periodically, so it should not
|
|
623
|
+
# need a separate request merely to decide whether to show Codex UI.
|
|
624
|
+
codex_installed = bool(CodexAppServer.get_binary_path())
|
|
625
|
+
info["codex"] = {
|
|
626
|
+
"installed": codex_installed,
|
|
627
|
+
"app_server_supported": codex_installed,
|
|
628
|
+
}
|
|
620
629
|
# logger.info("System info collected successfully with OS info: %s", info.get("os_info", {}).get("os_type", "Unknown"))
|
|
621
630
|
|
|
622
631
|
info["portacode_version"] = __version__
|
|
@@ -133,6 +133,31 @@ async def test_codex_thread_list():
|
|
|
133
133
|
assert "useStateDbOnly" not in list_call[1]
|
|
134
134
|
|
|
135
135
|
|
|
136
|
+
@pytest.mark.asyncio
|
|
137
|
+
async def test_codex_thread_list_marks_all_manager_active_threads():
|
|
138
|
+
channel = DummyControlChannel()
|
|
139
|
+
context = _context()
|
|
140
|
+
manager = CodexChatManager(channel, context)
|
|
141
|
+
manager.bridge = FakeBridge()
|
|
142
|
+
manager.bridge.responses["thread/list"] = {
|
|
143
|
+
"data": [{"id": "th-idle"}, {"id": "th-live"}],
|
|
144
|
+
"nextCursor": None,
|
|
145
|
+
}
|
|
146
|
+
manager._thread_active_turn["th-live"] = "turn-live"
|
|
147
|
+
context["codex_manager"] = manager
|
|
148
|
+
|
|
149
|
+
handler = CodexThreadListHandler(channel, context)
|
|
150
|
+
await handler.handle(
|
|
151
|
+
{"cmd": "codex_thread_list", "project_id": "p-1", "cwd": "/tmp/proj"},
|
|
152
|
+
reply_channel="rc-1",
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
threads = {thread["id"]: thread for thread in channel.sent[0]["threads"]}
|
|
156
|
+
assert threads["th-idle"]["isWorking"] is False
|
|
157
|
+
assert threads["th-live"]["isWorking"] is True
|
|
158
|
+
assert threads["th-live"]["activeTurnId"] == "turn-live"
|
|
159
|
+
|
|
160
|
+
|
|
136
161
|
@pytest.mark.asyncio
|
|
137
162
|
async def test_codex_thread_start_records_mapping():
|
|
138
163
|
channel = DummyControlChannel()
|
|
@@ -24,8 +24,10 @@ class PlayStoreScreenshotLogic:
|
|
|
24
24
|
f"document.body.style.zoom='{percent}%'"
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
CODEX_PROMPT_MARKER = "exactly three short bullets"
|
|
28
|
+
|
|
29
|
+
async def select_terra(self, page):
|
|
30
|
+
"""Select the inexpensive model used by the screenshot fixture."""
|
|
29
31
|
model_trigger = page.locator("codex-chat .model-trigger").first
|
|
30
32
|
await model_trigger.click()
|
|
31
33
|
terra = page.locator("codex-chat .model-option").filter(
|
|
@@ -34,6 +36,35 @@ class PlayStoreScreenshotLogic:
|
|
|
34
36
|
await terra.wait_for(timeout=10000)
|
|
35
37
|
await terra.click()
|
|
36
38
|
|
|
39
|
+
async def close_codex_sidebar(self, page):
|
|
40
|
+
await page.locator("codex-chat").first.evaluate(
|
|
41
|
+
"""chat => {
|
|
42
|
+
if (chat._layoutCompact && chat._showSidebar) {
|
|
43
|
+
chat._showSidebar = false;
|
|
44
|
+
chat.requestUpdate();
|
|
45
|
+
}
|
|
46
|
+
}"""
|
|
47
|
+
)
|
|
48
|
+
await page.wait_for_timeout(200)
|
|
49
|
+
|
|
50
|
+
async def hide_duplicate_codex_messages(self, page):
|
|
51
|
+
"""Keep reconnect replay duplicates out of the marketing capture."""
|
|
52
|
+
for role in ("user", "assistant"):
|
|
53
|
+
messages = page.locator(f"codex-chat .message.{role}")
|
|
54
|
+
seen = set()
|
|
55
|
+
for index in range(await messages.count()):
|
|
56
|
+
message = messages.nth(index)
|
|
57
|
+
text = " ".join((await message.text_content() or "").split())
|
|
58
|
+
if text in seen:
|
|
59
|
+
await message.evaluate("element => element.style.display = 'none'")
|
|
60
|
+
elif text:
|
|
61
|
+
seen.add(text)
|
|
62
|
+
|
|
63
|
+
async def seed_codex_review(self, page):
|
|
64
|
+
"""Create one small, deterministic Terra review for the fixture."""
|
|
65
|
+
await self.close_codex_sidebar(page)
|
|
66
|
+
await self.select_terra(page)
|
|
67
|
+
|
|
37
68
|
composer = page.locator('codex-chat textarea[placeholder="Ask Codex…"]').first
|
|
38
69
|
await composer.fill(
|
|
39
70
|
"Without using tools or modifying files, reply with exactly three "
|
|
@@ -43,9 +74,18 @@ class PlayStoreScreenshotLogic:
|
|
|
43
74
|
)
|
|
44
75
|
await page.locator('codex-chat button[aria-label="Send"]').first.click()
|
|
45
76
|
await page.locator("codex-chat .message.user").last.wait_for(timeout=30000)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
)
|
|
77
|
+
reply = page.locator("codex-chat .message.assistant").last
|
|
78
|
+
await reply.wait_for(timeout=90000)
|
|
79
|
+
for _ in range(45):
|
|
80
|
+
reply_text = (await reply.text_content() or "").strip()
|
|
81
|
+
streaming = await page.locator("codex-chat").first.evaluate(
|
|
82
|
+
"chat => chat._isStreaming"
|
|
83
|
+
)
|
|
84
|
+
if len(reply_text) > 20 and not streaming:
|
|
85
|
+
await self.hide_duplicate_codex_messages(page)
|
|
86
|
+
return
|
|
87
|
+
await page.wait_for_timeout(2000)
|
|
88
|
+
raise TimeoutError("Codex Terra response did not finish within 90 seconds")
|
|
49
89
|
|
|
50
90
|
async def open_first_codex_thread(self, page):
|
|
51
91
|
"""Open the newest Codex thread, creating the fixture thread if needed."""
|
|
@@ -59,22 +99,35 @@ class PlayStoreScreenshotLogic:
|
|
|
59
99
|
await thread.wait_for(timeout=5000)
|
|
60
100
|
await thread.click(force=True)
|
|
61
101
|
await page.wait_for_timeout(700)
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
102
|
+
await self.close_codex_sidebar(page)
|
|
103
|
+
|
|
104
|
+
user_text = await page.locator(
|
|
105
|
+
"codex-chat .message.user"
|
|
106
|
+
).all_text_contents()
|
|
107
|
+
assistant_text = await page.locator(
|
|
108
|
+
"codex-chat .message.assistant"
|
|
109
|
+
).all_text_contents()
|
|
110
|
+
last_reply = assistant_text[-1].strip() if assistant_text else ""
|
|
111
|
+
invalid_reply = any(
|
|
112
|
+
word in last_reply.lower()
|
|
113
|
+
for word in ("error", "insufficient", "balance", "ai_setup_required")
|
|
114
|
+
)
|
|
115
|
+
if (
|
|
116
|
+
any(self.CODEX_PROMPT_MARKER in text for text in user_text)
|
|
117
|
+
and len(last_reply) > 20
|
|
118
|
+
and not invalid_reply
|
|
119
|
+
):
|
|
120
|
+
await self.select_terra(page)
|
|
121
|
+
await self.hide_duplicate_codex_messages(page)
|
|
122
|
+
return
|
|
123
|
+
|
|
124
|
+
await page.locator("codex-chat .header-new").first.click()
|
|
125
|
+
await self.seed_codex_review(page)
|
|
68
126
|
return
|
|
69
127
|
except Exception:
|
|
70
128
|
pass
|
|
71
129
|
|
|
72
|
-
|
|
73
|
-
'codex-chat button[aria-label="Close sidebar"]'
|
|
74
|
-
).first
|
|
75
|
-
if await close_chats.count() and await close_chats.is_visible():
|
|
76
|
-
await close_chats.click()
|
|
77
|
-
|
|
130
|
+
await self.close_codex_sidebar(page)
|
|
78
131
|
await self.seed_codex_review(page)
|
|
79
132
|
|
|
80
133
|
async def expand_demo_tree(self, page):
|
|
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.21.dev2 → portacode-1.5.21.dev4}/docs/cloudflared-domain-connect-containers-audit.md
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{portacode-1.5.21.dev2 → portacode-1.5.21.dev4}/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
|
|
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
|
|
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
|