portacode 0.3.20.dev11__tar.gz → 1.4.11.dev0__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.
Potentially problematic release.
This version of portacode might be problematic. Click here for more details.
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/.claude/settings.local.json +6 -2
- portacode-1.4.11.dev0/.gitignore +16 -0
- portacode-1.4.11.dev0/.gitmodules +6 -0
- portacode-1.4.11.dev0/MANIFEST.in +5 -0
- portacode-1.4.11.dev0/PKG-INFO +298 -0
- portacode-1.4.11.dev0/README.md +251 -0
- portacode-1.4.11.dev0/connect.py +11 -0
- portacode-1.4.11.dev0/connect.sh +15 -0
- portacode-1.4.11.dev0/docker-compose.yaml +98 -0
- portacode-1.4.11.dev0/docs/images/device-transfer-button.png +0 -0
- portacode-1.4.11.dev0/docs/images/device-transfer-modal.png +0 -0
- portacode-1.4.11.dev0/docs/images/pair-device-button.png +0 -0
- portacode-1.4.11.dev0/docs/images/pairing-request.png +0 -0
- portacode-1.4.11.dev0/docs/images/student-workspace.png +0 -0
- portacode-1.4.11.dev0/examples/README.md +9 -0
- portacode-1.4.11.dev0/examples/simple_device/Dockerfile +8 -0
- portacode-1.4.11.dev0/examples/simple_device/README.md +35 -0
- portacode-1.4.11.dev0/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/simple_device/docker-compose.yaml +14 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/Dockerfile +16 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/README.md +152 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/.local/share/portacode/run/gateway.pid +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/.gitignore +2 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/db.sqlite3 +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/__init__.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/settings.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/urls.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/wsgi.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/templates/treats/home.html +137 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/__init__.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/admin.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/apps.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/menu.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/models.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/urls.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/views.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/menu.py +69 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__pycache__/__init__.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-01/workspace/treats/views.py +28 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-02/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-03/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-04/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-05/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-06/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-07/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-08/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-09/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode.pub +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/data/student-10/workspace/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/docker-compose.yaml +121 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/README.md +38 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/galactic_bakeshop/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/galactic_bakeshop/asgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/galactic_bakeshop/settings.py +87 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/galactic_bakeshop/urls.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/galactic_bakeshop/wsgi.py +13 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/manage.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/requirements.txt +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/templates/treats/home.html +85 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/admin.py +3 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/apps.py +6 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/menu.py +43 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/migrations/__init__.py +1 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/models.py +11 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/tests.py +15 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/urls.py +9 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/initial_content/treats/views.py +22 -0
- portacode-1.4.11.dev0/examples/workshop_fleet/instructions/WELCOME.md +25 -0
- portacode-1.4.11.dev0/portacode/_version.py +34 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/cli.py +143 -17
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/client.py +149 -10
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +649 -33
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/__init__.py +16 -1
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/base.py +78 -16
- portacode-1.4.11.dev0/portacode/connection/handlers/chunked_content.py +244 -0
- portacode-1.4.11.dev0/portacode/connection/handlers/diff_handlers.py +603 -0
- portacode-1.4.11.dev0/portacode/connection/handlers/file_handlers.py +1094 -0
- portacode-1.4.11.dev0/portacode/connection/handlers/project_aware_file_handlers.py +226 -0
- portacode-1.4.11.dev0/portacode/connection/handlers/project_state/__init__.py +92 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/project_state/file_system_watcher.py +61 -35
- portacode-1.4.11.dev0/portacode/connection/handlers/project_state/git_manager.py +1502 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/project_state/handlers.py +393 -72
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/project_state/manager.py +458 -234
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/project_state/models.py +7 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/project_state/utils.py +17 -28
- portacode-1.4.11.dev0/portacode/connection/handlers/project_state_handlers.py +45 -0
- portacode-1.4.11.dev0/portacode/connection/handlers/proxmox_infra.py +307 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/registry.py +15 -4
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/session.py +483 -32
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/system_handlers.py +140 -8
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/tab_factory.py +53 -46
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/terminal_handlers.py +21 -8
- portacode-1.4.11.dev0/portacode/connection/handlers/update_handler.py +61 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/terminal.py +83 -20
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/keypair.py +63 -1
- portacode-1.4.11.dev0/portacode/link_capture/__init__.py +38 -0
- portacode-1.4.11.dev0/portacode/link_capture/__pycache__/__init__.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/__pycache__/link_capture_wrapper.cpython-311.pyc +0 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/elinks +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/gio-open +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/gnome-open +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/gvfs-open +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/kde-open +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/kfmclient +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/link_capture_exec.sh +11 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/link_capture_wrapper.py +75 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/links +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/links2 +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/lynx +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/mate-open +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/netsurf +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/sensible-browser +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/w3m +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/x-www-browser +3 -0
- portacode-1.4.11.dev0/portacode/link_capture/bin/xdg-open +3 -0
- portacode-1.4.11.dev0/portacode/logging_categories.py +140 -0
- portacode-1.4.11.dev0/portacode/pairing.py +103 -0
- portacode-1.4.11.dev0/portacode/static/js/test-ntp-clock.html +63 -0
- portacode-1.4.11.dev0/portacode/static/js/utils/ntp-clock.js +232 -0
- portacode-1.4.11.dev0/portacode/utils/NTP_ARCHITECTURE.md +136 -0
- portacode-1.4.11.dev0/portacode/utils/__init__.py +1 -0
- portacode-1.4.11.dev0/portacode/utils/diff_apply.py +456 -0
- portacode-1.4.11.dev0/portacode/utils/diff_renderer.py +371 -0
- portacode-1.4.11.dev0/portacode/utils/ntp_clock.py +65 -0
- portacode-1.4.11.dev0/portacode.egg-info/PKG-INFO +298 -0
- portacode-1.4.11.dev0/portacode.egg-info/SOURCES.txt +380 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode.egg-info/requires.txt +2 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/setup.py +33 -20
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/test_device_online.py +1 -1
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/test_file_operations.py +93 -3
- portacode-1.4.11.dev0/test_modules/test_git_status_ui.py +370 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/test_login_flow.py +8 -4
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/test_navigate_testing_folder.py +156 -72
- portacode-1.4.11.dev0/test_modules/test_play_store_screenshots.py +294 -0
- portacode-1.4.11.dev0/test_modules/test_terminal_buffer_performance.py +261 -0
- portacode-1.4.11.dev0/test_modules/test_terminal_loading_race_condition.py +95 -0
- portacode-1.4.11.dev0/test_request_id.py +146 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/.env.example +4 -1
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/hierarchical_runner.py +77 -5
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/playwright_manager.py +92 -9
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/runner.py +10 -2
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/test_discovery.py +7 -3
- portacode-1.4.11.dev0/todo/UI_UX/opening_a_file_on_desktop_results_in_nothing.md +1 -0
- portacode-1.4.11.dev0/todo/agent_context_management.md +12 -0
- portacode-1.4.11.dev0/todo/django_server_time_sync.md +54 -0
- portacode-1.4.11.dev0/todo/issues/device_performance_degradation.md +129 -0
- portacode-1.4.11.dev0/todo/issues/git_data_not_captured_in_proxmox.md +2004 -0
- portacode-1.4.11.dev0/todo/issues/indefinite_resource_loading.md +5 -0
- portacode-1.4.11.dev0/todo/issues/portacode_service_silently_down.md +74 -0
- portacode-1.4.11.dev0/todo/issues/premature_terminal_exit.md +66 -0
- portacode-1.4.11.dev0/todo/issues/project_cpu_hotspots.md +33 -0
- portacode-1.4.11.dev0/todo/issues/terminals_exit_upon_starting.md +3 -0
- portacode-1.4.11.dev0/todo/issues/wrong_item_classification_on_client_side.md +15 -0
- portacode-1.4.11.dev0/todo/smartphone_terminal_input_frustrations.md +11 -0
- portacode-1.4.11.dev0/tools/generate_play_store_assets.py +1033 -0
- portacode-1.4.11.dev0/tools/pairing_tester.py +97 -0
- portacode-1.4.11.dev0/tools/run_screenshot_suite.sh +92 -0
- portacode-1.4.11.dev0/tools/test_python_ntp_clock.py +39 -0
- portacode-1.4.11.dev0/validate.sh +146 -0
- portacode-0.3.20.dev11/.gitignore +0 -10
- portacode-0.3.20.dev11/.gitmodules +0 -3
- portacode-0.3.20.dev11/MANIFEST.in +0 -2
- portacode-0.3.20.dev11/PKG-INFO +0 -241
- portacode-0.3.20.dev11/README.md +0 -211
- portacode-0.3.20.dev11/docker-compose.yaml +0 -37
- portacode-0.3.20.dev11/portacode/_version.py +0 -21
- portacode-0.3.20.dev11/portacode/connection/handlers/file_handlers.py +0 -368
- portacode-0.3.20.dev11/portacode/connection/handlers/project_state/__init__.py +0 -145
- portacode-0.3.20.dev11/portacode/connection/handlers/project_state/centralized_handlers.py +0 -395
- portacode-0.3.20.dev11/portacode/connection/handlers/project_state/centralized_manager.py +0 -760
- portacode-0.3.20.dev11/portacode/connection/handlers/project_state/centralized_state.py +0 -477
- portacode-0.3.20.dev11/portacode/connection/handlers/project_state/git_manager.py +0 -1177
- portacode-0.3.20.dev11/portacode/connection/handlers/project_state/simplified_file_watcher.py +0 -162
- portacode-0.3.20.dev11/portacode/connection/handlers/project_state_handlers.py +0 -43
- portacode-0.3.20.dev11/portacode.egg-info/PKG-INFO +0 -241
- portacode-0.3.20.dev11/portacode.egg-info/SOURCES.txt +0 -78
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/.claude/agents/communication-manager.md +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/LICENSE +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/Makefile +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/backup.sh +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/README.md +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/__init__.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/__main__.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/README.md +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/__init__.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/README.md +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/handlers/project_state/README.md +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/connection/multiplex.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/data.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode/service.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode.egg-info/dependency_links.txt +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode.egg-info/entry_points.txt +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/portacode.egg-info/top_level.txt +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/pyproject.toml +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/restore.sh +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/run_tests.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/setup.cfg +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test.sh +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/README.md +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/__init__.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/test_terminal_interaction.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/test_modules/test_terminal_start.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/README.md +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/__init__.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/cli.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/__init__.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/base_test.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/cli_manager.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/core/shared_cli_manager.py +0 -0
- {portacode-0.3.20.dev11 → portacode-1.4.11.dev0}/testing_framework/requirements.txt +0 -0
|
@@ -12,8 +12,12 @@
|
|
|
12
12
|
"Bash(grep:*)",
|
|
13
13
|
"Bash(./test.sh)",
|
|
14
14
|
"Bash(./test.sh:*)",
|
|
15
|
-
"Bash(mkdir:*)"
|
|
15
|
+
"Bash(mkdir:*)",
|
|
16
|
+
"Bash(./connect.sh)",
|
|
17
|
+
"Bash(git -C /home/menas/testing_folder status --porcelain)",
|
|
18
|
+
"Bash(docker-compose restart:*)",
|
|
19
|
+
"Bash(./debug/list_user_devices_and_projects.sh:*)"
|
|
16
20
|
],
|
|
17
21
|
"deny": []
|
|
18
22
|
}
|
|
19
|
-
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.pyc
|
|
3
|
+
*.egg-info
|
|
4
|
+
*.env
|
|
5
|
+
*.env.*
|
|
6
|
+
dist
|
|
7
|
+
.pypirc
|
|
8
|
+
_version.py
|
|
9
|
+
client_sessions.json
|
|
10
|
+
project_state_debug.json
|
|
11
|
+
test_results
|
|
12
|
+
logs
|
|
13
|
+
|
|
14
|
+
# Example-generated volumes
|
|
15
|
+
examples/simple_device/data/
|
|
16
|
+
examples/workshop_fleet/data/
|
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: portacode
|
|
3
|
+
Version: 1.4.11.dev0
|
|
4
|
+
Summary: Portacode CLI client and SDK
|
|
5
|
+
Home-page: https://github.com/portacode/portacode
|
|
6
|
+
Author: Meena Erian
|
|
7
|
+
Author-email: hi@menas.pro
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: click>=8.0
|
|
19
|
+
Requires-Dist: platformdirs>=3.0
|
|
20
|
+
Requires-Dist: cryptography>=41.0
|
|
21
|
+
Requires-Dist: websockets>=12.0
|
|
22
|
+
Requires-Dist: pyperclip>=1.8
|
|
23
|
+
Requires-Dist: psutil>=5.9
|
|
24
|
+
Requires-Dist: pyte>=0.8
|
|
25
|
+
Requires-Dist: pywinpty>=2.0; platform_system == "Windows"
|
|
26
|
+
Requires-Dist: GitPython>=3.1.45
|
|
27
|
+
Requires-Dist: watchdog>=3.0
|
|
28
|
+
Requires-Dist: diff-match-patch>=20230430
|
|
29
|
+
Requires-Dist: Pygments>=2.14.0
|
|
30
|
+
Requires-Dist: ntplib>=0.4.0
|
|
31
|
+
Requires-Dist: importlib_resources>=6.0
|
|
32
|
+
Provides-Extra: dev
|
|
33
|
+
Requires-Dist: black; extra == "dev"
|
|
34
|
+
Requires-Dist: flake8; extra == "dev"
|
|
35
|
+
Requires-Dist: pytest; extra == "dev"
|
|
36
|
+
Dynamic: author
|
|
37
|
+
Dynamic: author-email
|
|
38
|
+
Dynamic: classifier
|
|
39
|
+
Dynamic: description
|
|
40
|
+
Dynamic: description-content-type
|
|
41
|
+
Dynamic: home-page
|
|
42
|
+
Dynamic: license-file
|
|
43
|
+
Dynamic: provides-extra
|
|
44
|
+
Dynamic: requires-dist
|
|
45
|
+
Dynamic: requires-python
|
|
46
|
+
Dynamic: summary
|
|
47
|
+
|
|
48
|
+
# Portacode
|
|
49
|
+
|
|
50
|
+
**An AI-first, mobile-first IDE and admin tool, made with love and passion by software engineers, for software engineers.**
|
|
51
|
+
|
|
52
|
+
Portacode transforms any device with python into a remotely accessible development environment. Access your home lab, server or even embedded system chip from your phone, code on your desktop or your smartphone from anywhere, or help a colleague debug their server - all through a beautiful web interface designed for the modern developer.
|
|
53
|
+
|
|
54
|
+
## ✨ Why Portacode?
|
|
55
|
+
|
|
56
|
+
- **🤖 AI-First**: Built from the ground up with AI integration in mind
|
|
57
|
+
- **📱 Mobile-First**: Code and administrate from your phone or tablet
|
|
58
|
+
- **🌍 Global Access**: Connect to your devices from anywhere with internet
|
|
59
|
+
- **🔐 Secure**: HTTPS encrypted with RSA key authentication
|
|
60
|
+
- **⚡ Fast Setup**: Get connected in under 60 seconds
|
|
61
|
+
- **🔄 Always Connected**: Automatic reconnection and persistent service options
|
|
62
|
+
- **🆓 Free Account**: Create your account and start connecting immediately
|
|
63
|
+
- **🖥️ Cross-Platform**: Works on Windows, macOS, and Linux
|
|
64
|
+
|
|
65
|
+
## 🚀 Quick Start
|
|
66
|
+
|
|
67
|
+
### 1. Install Portacode
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
pip install portacode
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 2. Connect Your Device
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
portacode connect
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Follow the on-screen instructions to:
|
|
80
|
+
- Visit [https://portacode.com](https://portacode.com)
|
|
81
|
+
- Create your free account
|
|
82
|
+
- Add your device using the generated key
|
|
83
|
+
- Start coding and administrating!
|
|
84
|
+
|
|
85
|
+
### 3. Access Your Development Environment
|
|
86
|
+
|
|
87
|
+
Once connected, you can:
|
|
88
|
+
- Open terminal sessions from the web dashboard
|
|
89
|
+
- Execute commands remotely
|
|
90
|
+
- Monitor system status
|
|
91
|
+
- Access your development environment from any device
|
|
92
|
+
|
|
93
|
+
Want to see Portacode running inside containers or powering classrooms? Browse the [`examples/` directory](https://github.com/portacode/portacode/tree/master/examples) (also bundled in the PyPI source) for copy-paste Docker Compose setups ranging from a single-device sandbox to a ten-seat workshop fleet.
|
|
94
|
+
|
|
95
|
+
## 🔑 Pair Devices with Zero-Touch Codes
|
|
96
|
+
|
|
97
|
+
The fastest way to bring a new machine online is with a short-lived pairing code:
|
|
98
|
+
|
|
99
|
+
1. Log in to [https://portacode.com](https://portacode.com) and press **Pair Device** on the dashboard:
|
|
100
|
+

|
|
101
|
+
2. A four-digit code appears (valid for 15 minutes). This code only authorizes a pairing **request**—no device can reach your account until you approve it.
|
|
102
|
+
3. On the device, run Portacode with the code:
|
|
103
|
+
```bash
|
|
104
|
+
PORTACODE_PAIRING_CODE=1234 portacode connect \
|
|
105
|
+
--device-name "My Laptop" \
|
|
106
|
+
--project-path /srv/project-one \
|
|
107
|
+
--project-path /srv/project-two
|
|
108
|
+
```
|
|
109
|
+
- `--device-name` (or `PORTACODE_DEVICE_NAME`) pre-fills the friendly label shown in the dashboard.
|
|
110
|
+
- Repeat `--project-path /abs/path` to register up to ten Projects automatically once the request is approved.
|
|
111
|
+
- Automating inside Docker? Export your own `PORTACODE_PROJECT_PATHS=/srv/a:/srv/b` and convert it into repeated `--project-path` switches before invoking the CLI—see `portacode_for_school/persistent_workspace/entrypoint.sh` for a reference implementation.
|
|
112
|
+
4. Because the device has no fingerprint yet, the CLI bootstraps an in-memory keypair and announces a pending request to the dashboard. You immediately see the card with the supplied metadata:
|
|
113
|
+

|
|
114
|
+
5. Click **Approve**. The CLI persists the keypair on disk and transitions into a normal authenticated connection. Future `portacode connect` runs reuse the stored RSA keys—no additional codes required unless you revoke the device.
|
|
115
|
+
|
|
116
|
+
Need to pair multiple machines at once? A single pairing code can be reused concurrently: every device that launches `portacode connect` with that code shows up as its own approval card until you accept or decline it.
|
|
117
|
+
|
|
118
|
+
This workflow works great for headless setups and containers: export the environment variables, run `portacode connect --non-interactive`, and finish the approval from the dashboard.
|
|
119
|
+
|
|
120
|
+
## 💡 Use Cases
|
|
121
|
+
|
|
122
|
+
- **Remote Development**: Code, build, and debug from anywhere - even your phone
|
|
123
|
+
- **Server Administration**: 24/7 server access with persistent service installation
|
|
124
|
+
- **Mobile Development**: Full IDE experience on mobile devices
|
|
125
|
+
|
|
126
|
+
## 🔧 Essential Commands
|
|
127
|
+
|
|
128
|
+
### Basic Usage
|
|
129
|
+
```bash
|
|
130
|
+
# Start a connection (runs until closed)
|
|
131
|
+
portacode connect
|
|
132
|
+
|
|
133
|
+
# Run connection in background
|
|
134
|
+
portacode connect --detach
|
|
135
|
+
|
|
136
|
+
# Check version
|
|
137
|
+
portacode --version
|
|
138
|
+
|
|
139
|
+
# Get help
|
|
140
|
+
portacode --help
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Service Management
|
|
144
|
+
```bash
|
|
145
|
+
# First, authenticate your device
|
|
146
|
+
portacode connect
|
|
147
|
+
|
|
148
|
+
# For system services, install package system-wide
|
|
149
|
+
sudo pip install portacode --system
|
|
150
|
+
|
|
151
|
+
# Install persistent service (auto-start on boot)
|
|
152
|
+
sudo portacode service install
|
|
153
|
+
|
|
154
|
+
# Check service status (use -v for verbose debugging)
|
|
155
|
+
sudo portacode service status
|
|
156
|
+
sudo portacode service status -v
|
|
157
|
+
|
|
158
|
+
# Stop/remove the service
|
|
159
|
+
sudo portacode service stop
|
|
160
|
+
sudo portacode service uninstall
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## 🌐 Web Dashboard
|
|
164
|
+
|
|
165
|
+
Access your connected devices at [https://portacode.com](https://portacode.com)
|
|
166
|
+
|
|
167
|
+
**Current Features:**
|
|
168
|
+
- Real-time terminal access
|
|
169
|
+
- System monitoring
|
|
170
|
+
- Device management
|
|
171
|
+
- Multi-device switching
|
|
172
|
+
- Secure authentication
|
|
173
|
+
|
|
174
|
+
**Coming Soon:**
|
|
175
|
+
- AI-powered code assistance
|
|
176
|
+
- Mobile-optimized IDE interface
|
|
177
|
+
- File management and editing
|
|
178
|
+
- Collaborative development tools
|
|
179
|
+
|
|
180
|
+
## 🔐 Security
|
|
181
|
+
|
|
182
|
+
- **RSA Key Authentication**: Each device gets a unique RSA key pair
|
|
183
|
+
- **HTTPS Encrypted**: All communication is encrypted in transit
|
|
184
|
+
- **No Passwords**: Key-based authentication eliminates password risks
|
|
185
|
+
- **Revocable Access**: Remove devices instantly from the web dashboard
|
|
186
|
+
- **Local Key Storage**: Private keys never leave your device
|
|
187
|
+
|
|
188
|
+
## 🆘 Troubleshooting
|
|
189
|
+
|
|
190
|
+
### Connection Issues
|
|
191
|
+
```bash
|
|
192
|
+
# Check if another connection is running
|
|
193
|
+
portacode connect
|
|
194
|
+
|
|
195
|
+
# View service logs
|
|
196
|
+
sudo portacode service status --verbose
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
### Service Installation Issues
|
|
200
|
+
```bash
|
|
201
|
+
# First authenticate your device
|
|
202
|
+
portacode connect
|
|
203
|
+
|
|
204
|
+
# If service commands fail, ensure system-wide installation
|
|
205
|
+
sudo pip install portacode --system
|
|
206
|
+
|
|
207
|
+
# Then try service installation again
|
|
208
|
+
sudo portacode service install
|
|
209
|
+
|
|
210
|
+
# Use verbose status to debug connection issues
|
|
211
|
+
sudo portacode service status -v
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### Clipboard Issues (Linux)
|
|
215
|
+
```bash
|
|
216
|
+
# Install clipboard support
|
|
217
|
+
sudo apt-get install xclip
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Key Management
|
|
221
|
+
Portacode follows the OS-specific *user data* directory (via [`platformdirs`](https://pypi.org/project/platformdirs/)) and keeps its identity in `portacode/keys/`:
|
|
222
|
+
- **Linux**: `~/.local/share/portacode/keys/`
|
|
223
|
+
- **macOS**: `~/Library/Application Support/portacode/keys/`
|
|
224
|
+
- **Windows**: `%APPDATA%\portacode\keys\`
|
|
225
|
+
|
|
226
|
+
When `PORTACODE_PAIRING_CODE` is set, the CLI generates an in-memory keypair, waits for dashboard approval, and only then writes the files to this directory. If that folder disappears, the CLI will create a fresh identity next time it runs.
|
|
227
|
+
|
|
228
|
+
#### Persisting Keys in Containers
|
|
229
|
+
Docker images (including the simple `python:3.11-slim` example that runs Portacode as `root`) store the data inside `/root/.local/share/portacode`. Bind-mount that path or override `XDG_DATA_HOME` so the keys survive container restarts:
|
|
230
|
+
|
|
231
|
+
```yaml
|
|
232
|
+
services:
|
|
233
|
+
device-01:
|
|
234
|
+
build: .
|
|
235
|
+
environment:
|
|
236
|
+
PORTACODE_PAIRING_CODE: "${PORTACODE_PAIRING_CODE:-}"
|
|
237
|
+
volumes:
|
|
238
|
+
- ./data/device-01/workspace:/root/workspace
|
|
239
|
+
- ./data/device-01/.local/share/portacode:/root/.local/share/portacode # persists device keys
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Alternatively, set `XDG_DATA_HOME=/root/.portacode` before running `portacode connect` and mount that directory from the host. The rule of thumb: **persist whichever folder contains `.local/share/portacode/keys/`** so your device fingerprint sticks around.
|
|
243
|
+
|
|
244
|
+
#### Minimal Docker Example
|
|
245
|
+
If you want a plug-and-play container, check the `examples/simple_device/` folder that ships with this repo and the PyPI source distribution. It contains a tiny `Dockerfile` and `docker-compose.yaml` you can copy as-is. The Dockerfile installs `git` before `pip install portacode` so GitPython can interact with repositories—remember to do the same in your own images if you expect to work inside version-controlled projects.
|
|
246
|
+
|
|
247
|
+
The accompanying Compose file demonstrates how to:
|
|
248
|
+
- run `portacode connect --non-interactive` with a predefined `--device-name` and `--project-path`
|
|
249
|
+
- pass `PORTACODE_PAIRING_CODE` via environment variables
|
|
250
|
+
- bind-mount your workspace plus `/root/.local/share/portacode` for key persistence
|
|
251
|
+
|
|
252
|
+
Together, those 10 lines illustrate the complete flow for remotely accessing a Docker-hosted machine with Portacode.
|
|
253
|
+
|
|
254
|
+
#### Workshop Fleet Example
|
|
255
|
+
Training a group? `examples/workshop_fleet/` spins up ten identical containers—one per student—with their own workspace bind mounts plus a shared read-only `instructions/` folder. The Dockerfile in that folder copies everything from `initial_content/` into the image (`COPY initial_content/ /opt/initial_content/`), and the compose command seeds each student workspace on boot via `cp -an /opt/initial_content/. /root/workspace/`. That means:
|
|
256
|
+
- Instructors drop starter code into `initial_content/` before `docker compose up` and every container gets the same seed files without overwriting student changes after the first sync.
|
|
257
|
+
- The host `instructions/` directory is mounted at `/root/workspace/instructions` in **read-only** mode, so you can update agendas or hints live while students can only view them.
|
|
258
|
+
- Each seat persists its Portacode identity in `data/student-XX/.local/share/portacode`, so reconnecting after a restart does not need new pairing codes.
|
|
259
|
+
|
|
260
|
+
See the full walkthrough and assets in [`examples/workshop_fleet/`](https://github.com/portacode/portacode/tree/master/examples/workshop_fleet), which is also shipped inside the PyPI source tarball for offline access.
|
|
261
|
+
|
|
262
|
+
## 🌱 Early Stage Project
|
|
263
|
+
|
|
264
|
+
**Portacode is a young project with big dreams.** We're building the future of remote development and mobile-first coding experiences. As a new project, we're actively seeking:
|
|
265
|
+
|
|
266
|
+
- **👥 Community Feedback**: Does this solve a real problem for you?
|
|
267
|
+
- **🤝 Contributors**: Help us build the IDE of the future
|
|
268
|
+
- **📢 Early Adopters**: Try it out and let us know what you think
|
|
269
|
+
- **💡 Feature Ideas**: What would make your remote development workflow better?
|
|
270
|
+
|
|
271
|
+
**Your support matters!** Whether you contribute code, report bugs, share ideas, or simply let us know that you find value in what we're building - every bit of feedback helps us decide whether to continue investing in this vision or focus on other projects.
|
|
272
|
+
|
|
273
|
+
## 📞 Get In Touch
|
|
274
|
+
|
|
275
|
+
- **Email**: hi@menas.pro
|
|
276
|
+
- **Support**: support@portacode.com
|
|
277
|
+
- **GitHub**: [https://github.com/portacode/portacode](https://github.com/portacode/portacode)
|
|
278
|
+
|
|
279
|
+
## 🤝 Contributing
|
|
280
|
+
|
|
281
|
+
We welcome all forms of contribution:
|
|
282
|
+
- 🐛 **Bug Reports**: Found something broken? Let us know!
|
|
283
|
+
- ✨ **Feature Requests**: What would make Portacode better for you?
|
|
284
|
+
- 📖 **Documentation**: Help others get started
|
|
285
|
+
- 💻 **Code Contributions**: Help us build the future of remote development
|
|
286
|
+
- 💬 **Feedback**: Tell us if you find this useful!
|
|
287
|
+
|
|
288
|
+
Check out our [GitHub repository](https://github.com/portacode/portacode) to get started.
|
|
289
|
+
|
|
290
|
+
## 📄 License
|
|
291
|
+
|
|
292
|
+
MIT License - see [LICENSE](https://github.com/portacode/portacode/blob/master/LICENSE) file for details.
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
**Get started today**: `pip install portacode && portacode connect`
|
|
297
|
+
|
|
298
|
+
*Built with ❤️ and ☕ by passionate software engineers*
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# Portacode
|
|
2
|
+
|
|
3
|
+
**An AI-first, mobile-first IDE and admin tool, made with love and passion by software engineers, for software engineers.**
|
|
4
|
+
|
|
5
|
+
Portacode transforms any device with python into a remotely accessible development environment. Access your home lab, server or even embedded system chip from your phone, code on your desktop or your smartphone from anywhere, or help a colleague debug their server - all through a beautiful web interface designed for the modern developer.
|
|
6
|
+
|
|
7
|
+
## ✨ Why Portacode?
|
|
8
|
+
|
|
9
|
+
- **🤖 AI-First**: Built from the ground up with AI integration in mind
|
|
10
|
+
- **📱 Mobile-First**: Code and administrate from your phone or tablet
|
|
11
|
+
- **🌍 Global Access**: Connect to your devices from anywhere with internet
|
|
12
|
+
- **🔐 Secure**: HTTPS encrypted with RSA key authentication
|
|
13
|
+
- **⚡ Fast Setup**: Get connected in under 60 seconds
|
|
14
|
+
- **🔄 Always Connected**: Automatic reconnection and persistent service options
|
|
15
|
+
- **🆓 Free Account**: Create your account and start connecting immediately
|
|
16
|
+
- **🖥️ Cross-Platform**: Works on Windows, macOS, and Linux
|
|
17
|
+
|
|
18
|
+
## 🚀 Quick Start
|
|
19
|
+
|
|
20
|
+
### 1. Install Portacode
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install portacode
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. Connect Your Device
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
portacode connect
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Follow the on-screen instructions to:
|
|
33
|
+
- Visit [https://portacode.com](https://portacode.com)
|
|
34
|
+
- Create your free account
|
|
35
|
+
- Add your device using the generated key
|
|
36
|
+
- Start coding and administrating!
|
|
37
|
+
|
|
38
|
+
### 3. Access Your Development Environment
|
|
39
|
+
|
|
40
|
+
Once connected, you can:
|
|
41
|
+
- Open terminal sessions from the web dashboard
|
|
42
|
+
- Execute commands remotely
|
|
43
|
+
- Monitor system status
|
|
44
|
+
- Access your development environment from any device
|
|
45
|
+
|
|
46
|
+
Want to see Portacode running inside containers or powering classrooms? Browse the [`examples/` directory](https://github.com/portacode/portacode/tree/master/examples) (also bundled in the PyPI source) for copy-paste Docker Compose setups ranging from a single-device sandbox to a ten-seat workshop fleet.
|
|
47
|
+
|
|
48
|
+
## 🔑 Pair Devices with Zero-Touch Codes
|
|
49
|
+
|
|
50
|
+
The fastest way to bring a new machine online is with a short-lived pairing code:
|
|
51
|
+
|
|
52
|
+
1. Log in to [https://portacode.com](https://portacode.com) and press **Pair Device** on the dashboard:
|
|
53
|
+

|
|
54
|
+
2. A four-digit code appears (valid for 15 minutes). This code only authorizes a pairing **request**—no device can reach your account until you approve it.
|
|
55
|
+
3. On the device, run Portacode with the code:
|
|
56
|
+
```bash
|
|
57
|
+
PORTACODE_PAIRING_CODE=1234 portacode connect \
|
|
58
|
+
--device-name "My Laptop" \
|
|
59
|
+
--project-path /srv/project-one \
|
|
60
|
+
--project-path /srv/project-two
|
|
61
|
+
```
|
|
62
|
+
- `--device-name` (or `PORTACODE_DEVICE_NAME`) pre-fills the friendly label shown in the dashboard.
|
|
63
|
+
- Repeat `--project-path /abs/path` to register up to ten Projects automatically once the request is approved.
|
|
64
|
+
- Automating inside Docker? Export your own `PORTACODE_PROJECT_PATHS=/srv/a:/srv/b` and convert it into repeated `--project-path` switches before invoking the CLI—see `portacode_for_school/persistent_workspace/entrypoint.sh` for a reference implementation.
|
|
65
|
+
4. Because the device has no fingerprint yet, the CLI bootstraps an in-memory keypair and announces a pending request to the dashboard. You immediately see the card with the supplied metadata:
|
|
66
|
+

|
|
67
|
+
5. Click **Approve**. The CLI persists the keypair on disk and transitions into a normal authenticated connection. Future `portacode connect` runs reuse the stored RSA keys—no additional codes required unless you revoke the device.
|
|
68
|
+
|
|
69
|
+
Need to pair multiple machines at once? A single pairing code can be reused concurrently: every device that launches `portacode connect` with that code shows up as its own approval card until you accept or decline it.
|
|
70
|
+
|
|
71
|
+
This workflow works great for headless setups and containers: export the environment variables, run `portacode connect --non-interactive`, and finish the approval from the dashboard.
|
|
72
|
+
|
|
73
|
+
## 💡 Use Cases
|
|
74
|
+
|
|
75
|
+
- **Remote Development**: Code, build, and debug from anywhere - even your phone
|
|
76
|
+
- **Server Administration**: 24/7 server access with persistent service installation
|
|
77
|
+
- **Mobile Development**: Full IDE experience on mobile devices
|
|
78
|
+
|
|
79
|
+
## 🔧 Essential Commands
|
|
80
|
+
|
|
81
|
+
### Basic Usage
|
|
82
|
+
```bash
|
|
83
|
+
# Start a connection (runs until closed)
|
|
84
|
+
portacode connect
|
|
85
|
+
|
|
86
|
+
# Run connection in background
|
|
87
|
+
portacode connect --detach
|
|
88
|
+
|
|
89
|
+
# Check version
|
|
90
|
+
portacode --version
|
|
91
|
+
|
|
92
|
+
# Get help
|
|
93
|
+
portacode --help
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Service Management
|
|
97
|
+
```bash
|
|
98
|
+
# First, authenticate your device
|
|
99
|
+
portacode connect
|
|
100
|
+
|
|
101
|
+
# For system services, install package system-wide
|
|
102
|
+
sudo pip install portacode --system
|
|
103
|
+
|
|
104
|
+
# Install persistent service (auto-start on boot)
|
|
105
|
+
sudo portacode service install
|
|
106
|
+
|
|
107
|
+
# Check service status (use -v for verbose debugging)
|
|
108
|
+
sudo portacode service status
|
|
109
|
+
sudo portacode service status -v
|
|
110
|
+
|
|
111
|
+
# Stop/remove the service
|
|
112
|
+
sudo portacode service stop
|
|
113
|
+
sudo portacode service uninstall
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 🌐 Web Dashboard
|
|
117
|
+
|
|
118
|
+
Access your connected devices at [https://portacode.com](https://portacode.com)
|
|
119
|
+
|
|
120
|
+
**Current Features:**
|
|
121
|
+
- Real-time terminal access
|
|
122
|
+
- System monitoring
|
|
123
|
+
- Device management
|
|
124
|
+
- Multi-device switching
|
|
125
|
+
- Secure authentication
|
|
126
|
+
|
|
127
|
+
**Coming Soon:**
|
|
128
|
+
- AI-powered code assistance
|
|
129
|
+
- Mobile-optimized IDE interface
|
|
130
|
+
- File management and editing
|
|
131
|
+
- Collaborative development tools
|
|
132
|
+
|
|
133
|
+
## 🔐 Security
|
|
134
|
+
|
|
135
|
+
- **RSA Key Authentication**: Each device gets a unique RSA key pair
|
|
136
|
+
- **HTTPS Encrypted**: All communication is encrypted in transit
|
|
137
|
+
- **No Passwords**: Key-based authentication eliminates password risks
|
|
138
|
+
- **Revocable Access**: Remove devices instantly from the web dashboard
|
|
139
|
+
- **Local Key Storage**: Private keys never leave your device
|
|
140
|
+
|
|
141
|
+
## 🆘 Troubleshooting
|
|
142
|
+
|
|
143
|
+
### Connection Issues
|
|
144
|
+
```bash
|
|
145
|
+
# Check if another connection is running
|
|
146
|
+
portacode connect
|
|
147
|
+
|
|
148
|
+
# View service logs
|
|
149
|
+
sudo portacode service status --verbose
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Service Installation Issues
|
|
153
|
+
```bash
|
|
154
|
+
# First authenticate your device
|
|
155
|
+
portacode connect
|
|
156
|
+
|
|
157
|
+
# If service commands fail, ensure system-wide installation
|
|
158
|
+
sudo pip install portacode --system
|
|
159
|
+
|
|
160
|
+
# Then try service installation again
|
|
161
|
+
sudo portacode service install
|
|
162
|
+
|
|
163
|
+
# Use verbose status to debug connection issues
|
|
164
|
+
sudo portacode service status -v
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Clipboard Issues (Linux)
|
|
168
|
+
```bash
|
|
169
|
+
# Install clipboard support
|
|
170
|
+
sudo apt-get install xclip
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Key Management
|
|
174
|
+
Portacode follows the OS-specific *user data* directory (via [`platformdirs`](https://pypi.org/project/platformdirs/)) and keeps its identity in `portacode/keys/`:
|
|
175
|
+
- **Linux**: `~/.local/share/portacode/keys/`
|
|
176
|
+
- **macOS**: `~/Library/Application Support/portacode/keys/`
|
|
177
|
+
- **Windows**: `%APPDATA%\portacode\keys\`
|
|
178
|
+
|
|
179
|
+
When `PORTACODE_PAIRING_CODE` is set, the CLI generates an in-memory keypair, waits for dashboard approval, and only then writes the files to this directory. If that folder disappears, the CLI will create a fresh identity next time it runs.
|
|
180
|
+
|
|
181
|
+
#### Persisting Keys in Containers
|
|
182
|
+
Docker images (including the simple `python:3.11-slim` example that runs Portacode as `root`) store the data inside `/root/.local/share/portacode`. Bind-mount that path or override `XDG_DATA_HOME` so the keys survive container restarts:
|
|
183
|
+
|
|
184
|
+
```yaml
|
|
185
|
+
services:
|
|
186
|
+
device-01:
|
|
187
|
+
build: .
|
|
188
|
+
environment:
|
|
189
|
+
PORTACODE_PAIRING_CODE: "${PORTACODE_PAIRING_CODE:-}"
|
|
190
|
+
volumes:
|
|
191
|
+
- ./data/device-01/workspace:/root/workspace
|
|
192
|
+
- ./data/device-01/.local/share/portacode:/root/.local/share/portacode # persists device keys
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Alternatively, set `XDG_DATA_HOME=/root/.portacode` before running `portacode connect` and mount that directory from the host. The rule of thumb: **persist whichever folder contains `.local/share/portacode/keys/`** so your device fingerprint sticks around.
|
|
196
|
+
|
|
197
|
+
#### Minimal Docker Example
|
|
198
|
+
If you want a plug-and-play container, check the `examples/simple_device/` folder that ships with this repo and the PyPI source distribution. It contains a tiny `Dockerfile` and `docker-compose.yaml` you can copy as-is. The Dockerfile installs `git` before `pip install portacode` so GitPython can interact with repositories—remember to do the same in your own images if you expect to work inside version-controlled projects.
|
|
199
|
+
|
|
200
|
+
The accompanying Compose file demonstrates how to:
|
|
201
|
+
- run `portacode connect --non-interactive` with a predefined `--device-name` and `--project-path`
|
|
202
|
+
- pass `PORTACODE_PAIRING_CODE` via environment variables
|
|
203
|
+
- bind-mount your workspace plus `/root/.local/share/portacode` for key persistence
|
|
204
|
+
|
|
205
|
+
Together, those 10 lines illustrate the complete flow for remotely accessing a Docker-hosted machine with Portacode.
|
|
206
|
+
|
|
207
|
+
#### Workshop Fleet Example
|
|
208
|
+
Training a group? `examples/workshop_fleet/` spins up ten identical containers—one per student—with their own workspace bind mounts plus a shared read-only `instructions/` folder. The Dockerfile in that folder copies everything from `initial_content/` into the image (`COPY initial_content/ /opt/initial_content/`), and the compose command seeds each student workspace on boot via `cp -an /opt/initial_content/. /root/workspace/`. That means:
|
|
209
|
+
- Instructors drop starter code into `initial_content/` before `docker compose up` and every container gets the same seed files without overwriting student changes after the first sync.
|
|
210
|
+
- The host `instructions/` directory is mounted at `/root/workspace/instructions` in **read-only** mode, so you can update agendas or hints live while students can only view them.
|
|
211
|
+
- Each seat persists its Portacode identity in `data/student-XX/.local/share/portacode`, so reconnecting after a restart does not need new pairing codes.
|
|
212
|
+
|
|
213
|
+
See the full walkthrough and assets in [`examples/workshop_fleet/`](https://github.com/portacode/portacode/tree/master/examples/workshop_fleet), which is also shipped inside the PyPI source tarball for offline access.
|
|
214
|
+
|
|
215
|
+
## 🌱 Early Stage Project
|
|
216
|
+
|
|
217
|
+
**Portacode is a young project with big dreams.** We're building the future of remote development and mobile-first coding experiences. As a new project, we're actively seeking:
|
|
218
|
+
|
|
219
|
+
- **👥 Community Feedback**: Does this solve a real problem for you?
|
|
220
|
+
- **🤝 Contributors**: Help us build the IDE of the future
|
|
221
|
+
- **📢 Early Adopters**: Try it out and let us know what you think
|
|
222
|
+
- **💡 Feature Ideas**: What would make your remote development workflow better?
|
|
223
|
+
|
|
224
|
+
**Your support matters!** Whether you contribute code, report bugs, share ideas, or simply let us know that you find value in what we're building - every bit of feedback helps us decide whether to continue investing in this vision or focus on other projects.
|
|
225
|
+
|
|
226
|
+
## 📞 Get In Touch
|
|
227
|
+
|
|
228
|
+
- **Email**: hi@menas.pro
|
|
229
|
+
- **Support**: support@portacode.com
|
|
230
|
+
- **GitHub**: [https://github.com/portacode/portacode](https://github.com/portacode/portacode)
|
|
231
|
+
|
|
232
|
+
## 🤝 Contributing
|
|
233
|
+
|
|
234
|
+
We welcome all forms of contribution:
|
|
235
|
+
- 🐛 **Bug Reports**: Found something broken? Let us know!
|
|
236
|
+
- ✨ **Feature Requests**: What would make Portacode better for you?
|
|
237
|
+
- 📖 **Documentation**: Help others get started
|
|
238
|
+
- 💻 **Code Contributions**: Help us build the future of remote development
|
|
239
|
+
- 💬 **Feedback**: Tell us if you find this useful!
|
|
240
|
+
|
|
241
|
+
Check out our [GitHub repository](https://github.com/portacode/portacode) to get started.
|
|
242
|
+
|
|
243
|
+
## 📄 License
|
|
244
|
+
|
|
245
|
+
MIT License - see [LICENSE](https://github.com/portacode/portacode/blob/master/LICENSE) file for details.
|
|
246
|
+
|
|
247
|
+
---
|
|
248
|
+
|
|
249
|
+
**Get started today**: `pip install portacode && portacode connect`
|
|
250
|
+
|
|
251
|
+
*Built with ❤️ and ☕ by passionate software engineers*
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from portacode.cli import cli
|
|
3
|
+
|
|
4
|
+
# Build command arguments
|
|
5
|
+
args = ['connect', '--non-interactive', '--debug']
|
|
6
|
+
|
|
7
|
+
# Add log categories if provided
|
|
8
|
+
if len(sys.argv) > 1 and sys.argv[1]:
|
|
9
|
+
args.extend(['--log-categories', sys.argv[1]])
|
|
10
|
+
|
|
11
|
+
cli(args)
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# Portacode connection script with optional log category filtering
|
|
4
|
+
#
|
|
5
|
+
# Usage examples:
|
|
6
|
+
# ./connect.sh # Normal debug mode (all logs)
|
|
7
|
+
# ./connect.sh connection,git # Only connection and git logs
|
|
8
|
+
# ./connect.sh project_state # Only project state logs (useful for debugging project sync issues)
|
|
9
|
+
# ./connect.sh filesystem,git # Only filesystem and git logs
|
|
10
|
+
# ./connect.sh list # Show available log categories
|
|
11
|
+
#
|
|
12
|
+
# Available categories: connection, auth, websocket, terminal, project_state, filesystem, git, handlers, mux, system, debug
|
|
13
|
+
|
|
14
|
+
# Pass log categories as first argument to connect.py
|
|
15
|
+
python connect.py "$1"
|