portacode 1.4.15.dev1__tar.gz → 1.4.15.dev3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (383) hide show
  1. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/PKG-INFO +1 -1
  2. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/_version.py +2 -2
  3. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/WEBSOCKET_PROTOCOL.md +15 -8
  4. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/__init__.py +6 -0
  5. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/proxmox_infra.py +101 -29
  6. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode.egg-info/PKG-INFO +1 -1
  7. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/.claude/agents/communication-manager.md +0 -0
  8. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/.claude/settings.local.json +0 -0
  9. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/.gitignore +0 -0
  10. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/.gitmodules +0 -0
  11. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/LICENSE +0 -0
  12. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/MANIFEST.in +0 -0
  13. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/Makefile +0 -0
  14. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/README.md +0 -0
  15. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/backup.sh +0 -0
  16. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/connect.py +0 -0
  17. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/connect.sh +0 -0
  18. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/docker-compose.yaml +0 -0
  19. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/docs/images/device-transfer-button.png +0 -0
  20. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/docs/images/device-transfer-modal.png +0 -0
  21. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/docs/images/pair-device-button.png +0 -0
  22. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/docs/images/pairing-request.png +0 -0
  23. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/docs/images/student-workspace.png +0 -0
  24. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/README.md +0 -0
  25. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/simple_device/Dockerfile +0 -0
  26. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/simple_device/README.md +0 -0
  27. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode +0 -0
  28. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/simple_device/data/device-01/.local/share/portacode/keys/id_portacode.pub +0 -0
  29. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/simple_device/docker-compose.yaml +0 -0
  30. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/Dockerfile +0 -0
  31. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/README.md +0 -0
  32. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode +0 -0
  33. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/.local/share/portacode/keys/id_portacode.pub +0 -0
  34. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/.local/share/portacode/run/gateway.pid +0 -0
  35. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/.gitignore +0 -0
  36. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/README.md +0 -0
  37. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/db.sqlite3 +0 -0
  38. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__init__.py +0 -0
  39. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/__init__.cpython-311.pyc +0 -0
  40. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/settings.cpython-311.pyc +0 -0
  41. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/urls.cpython-311.pyc +0 -0
  42. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/__pycache__/wsgi.cpython-311.pyc +0 -0
  43. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/asgi.py +0 -0
  44. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/settings.py +0 -0
  45. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/urls.py +0 -0
  46. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/galactic_bakeshop/wsgi.py +0 -0
  47. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/manage.py +0 -0
  48. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/requirements.txt +0 -0
  49. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/templates/treats/home.html +0 -0
  50. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__init__.py +0 -0
  51. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/__init__.cpython-311.pyc +0 -0
  52. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/admin.cpython-311.pyc +0 -0
  53. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/apps.cpython-311.pyc +0 -0
  54. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/menu.cpython-311.pyc +0 -0
  55. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/models.cpython-311.pyc +0 -0
  56. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/urls.cpython-311.pyc +0 -0
  57. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/__pycache__/views.cpython-311.pyc +0 -0
  58. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/admin.py +0 -0
  59. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/apps.py +0 -0
  60. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/menu.py +0 -0
  61. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__init__.py +0 -0
  62. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/migrations/__pycache__/__init__.cpython-311.pyc +0 -0
  63. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/models.py +0 -0
  64. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/tests.py +0 -0
  65. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/urls.py +0 -0
  66. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-01/workspace/treats/views.py +0 -0
  67. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode +0 -0
  68. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/.local/share/portacode/keys/id_portacode.pub +0 -0
  69. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/README.md +0 -0
  70. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/__init__.py +0 -0
  71. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/asgi.py +0 -0
  72. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/settings.py +0 -0
  73. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/urls.py +0 -0
  74. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/galactic_bakeshop/wsgi.py +0 -0
  75. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/manage.py +0 -0
  76. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/requirements.txt +0 -0
  77. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/templates/treats/home.html +0 -0
  78. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/__init__.py +0 -0
  79. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/admin.py +0 -0
  80. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/apps.py +0 -0
  81. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/menu.py +0 -0
  82. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/migrations/__init__.py +0 -0
  83. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/models.py +0 -0
  84. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/tests.py +0 -0
  85. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/urls.py +0 -0
  86. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-02/workspace/treats/views.py +0 -0
  87. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode +0 -0
  88. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/.local/share/portacode/keys/id_portacode.pub +0 -0
  89. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/README.md +0 -0
  90. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/__init__.py +0 -0
  91. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/asgi.py +0 -0
  92. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/settings.py +0 -0
  93. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/urls.py +0 -0
  94. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/galactic_bakeshop/wsgi.py +0 -0
  95. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/manage.py +0 -0
  96. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/requirements.txt +0 -0
  97. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/templates/treats/home.html +0 -0
  98. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/__init__.py +0 -0
  99. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/admin.py +0 -0
  100. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/apps.py +0 -0
  101. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/menu.py +0 -0
  102. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/migrations/__init__.py +0 -0
  103. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/models.py +0 -0
  104. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/tests.py +0 -0
  105. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/urls.py +0 -0
  106. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-03/workspace/treats/views.py +0 -0
  107. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode +0 -0
  108. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/.local/share/portacode/keys/id_portacode.pub +0 -0
  109. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/README.md +0 -0
  110. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/__init__.py +0 -0
  111. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/asgi.py +0 -0
  112. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/settings.py +0 -0
  113. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/urls.py +0 -0
  114. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/galactic_bakeshop/wsgi.py +0 -0
  115. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/manage.py +0 -0
  116. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/requirements.txt +0 -0
  117. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/templates/treats/home.html +0 -0
  118. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/__init__.py +0 -0
  119. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/admin.py +0 -0
  120. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/apps.py +0 -0
  121. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/menu.py +0 -0
  122. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/migrations/__init__.py +0 -0
  123. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/models.py +0 -0
  124. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/tests.py +0 -0
  125. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/urls.py +0 -0
  126. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-04/workspace/treats/views.py +0 -0
  127. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode +0 -0
  128. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/.local/share/portacode/keys/id_portacode.pub +0 -0
  129. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/README.md +0 -0
  130. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/__init__.py +0 -0
  131. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/asgi.py +0 -0
  132. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/settings.py +0 -0
  133. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/urls.py +0 -0
  134. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/galactic_bakeshop/wsgi.py +0 -0
  135. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/manage.py +0 -0
  136. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/requirements.txt +0 -0
  137. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/templates/treats/home.html +0 -0
  138. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/__init__.py +0 -0
  139. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/admin.py +0 -0
  140. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/apps.py +0 -0
  141. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/menu.py +0 -0
  142. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/migrations/__init__.py +0 -0
  143. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/models.py +0 -0
  144. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/tests.py +0 -0
  145. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/urls.py +0 -0
  146. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-05/workspace/treats/views.py +0 -0
  147. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode +0 -0
  148. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/.local/share/portacode/keys/id_portacode.pub +0 -0
  149. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/README.md +0 -0
  150. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/__init__.py +0 -0
  151. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/asgi.py +0 -0
  152. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/settings.py +0 -0
  153. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/urls.py +0 -0
  154. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/galactic_bakeshop/wsgi.py +0 -0
  155. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/manage.py +0 -0
  156. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/requirements.txt +0 -0
  157. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/templates/treats/home.html +0 -0
  158. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/__init__.py +0 -0
  159. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/admin.py +0 -0
  160. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/apps.py +0 -0
  161. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/menu.py +0 -0
  162. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/migrations/__init__.py +0 -0
  163. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/models.py +0 -0
  164. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/tests.py +0 -0
  165. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/urls.py +0 -0
  166. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-06/workspace/treats/views.py +0 -0
  167. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode +0 -0
  168. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/.local/share/portacode/keys/id_portacode.pub +0 -0
  169. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/README.md +0 -0
  170. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/__init__.py +0 -0
  171. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/asgi.py +0 -0
  172. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/settings.py +0 -0
  173. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/urls.py +0 -0
  174. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/galactic_bakeshop/wsgi.py +0 -0
  175. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/manage.py +0 -0
  176. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/requirements.txt +0 -0
  177. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/templates/treats/home.html +0 -0
  178. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/__init__.py +0 -0
  179. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/admin.py +0 -0
  180. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/apps.py +0 -0
  181. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/menu.py +0 -0
  182. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/migrations/__init__.py +0 -0
  183. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/models.py +0 -0
  184. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/tests.py +0 -0
  185. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/urls.py +0 -0
  186. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-07/workspace/treats/views.py +0 -0
  187. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode +0 -0
  188. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/.local/share/portacode/keys/id_portacode.pub +0 -0
  189. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/README.md +0 -0
  190. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/__init__.py +0 -0
  191. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/asgi.py +0 -0
  192. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/settings.py +0 -0
  193. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/urls.py +0 -0
  194. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/galactic_bakeshop/wsgi.py +0 -0
  195. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/manage.py +0 -0
  196. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/requirements.txt +0 -0
  197. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/templates/treats/home.html +0 -0
  198. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/__init__.py +0 -0
  199. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/admin.py +0 -0
  200. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/apps.py +0 -0
  201. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/menu.py +0 -0
  202. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/migrations/__init__.py +0 -0
  203. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/models.py +0 -0
  204. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/tests.py +0 -0
  205. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/urls.py +0 -0
  206. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-08/workspace/treats/views.py +0 -0
  207. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode +0 -0
  208. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/.local/share/portacode/keys/id_portacode.pub +0 -0
  209. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/README.md +0 -0
  210. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/__init__.py +0 -0
  211. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/asgi.py +0 -0
  212. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/settings.py +0 -0
  213. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/urls.py +0 -0
  214. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/galactic_bakeshop/wsgi.py +0 -0
  215. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/manage.py +0 -0
  216. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/requirements.txt +0 -0
  217. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/templates/treats/home.html +0 -0
  218. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/__init__.py +0 -0
  219. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/admin.py +0 -0
  220. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/apps.py +0 -0
  221. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/menu.py +0 -0
  222. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/migrations/__init__.py +0 -0
  223. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/models.py +0 -0
  224. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/tests.py +0 -0
  225. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/urls.py +0 -0
  226. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-09/workspace/treats/views.py +0 -0
  227. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode +0 -0
  228. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/.local/share/portacode/keys/id_portacode.pub +0 -0
  229. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/README.md +0 -0
  230. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/__init__.py +0 -0
  231. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/asgi.py +0 -0
  232. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/settings.py +0 -0
  233. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/urls.py +0 -0
  234. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/galactic_bakeshop/wsgi.py +0 -0
  235. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/manage.py +0 -0
  236. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/requirements.txt +0 -0
  237. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/templates/treats/home.html +0 -0
  238. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/__init__.py +0 -0
  239. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/admin.py +0 -0
  240. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/apps.py +0 -0
  241. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/menu.py +0 -0
  242. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/migrations/__init__.py +0 -0
  243. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/models.py +0 -0
  244. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/tests.py +0 -0
  245. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/urls.py +0 -0
  246. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/data/student-10/workspace/treats/views.py +0 -0
  247. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/docker-compose.yaml +0 -0
  248. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/README.md +0 -0
  249. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/__init__.py +0 -0
  250. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/asgi.py +0 -0
  251. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/settings.py +0 -0
  252. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/urls.py +0 -0
  253. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/galactic_bakeshop/wsgi.py +0 -0
  254. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/manage.py +0 -0
  255. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/requirements.txt +0 -0
  256. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/templates/treats/home.html +0 -0
  257. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/__init__.py +0 -0
  258. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/admin.py +0 -0
  259. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/apps.py +0 -0
  260. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/menu.py +0 -0
  261. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/migrations/__init__.py +0 -0
  262. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/models.py +0 -0
  263. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/tests.py +0 -0
  264. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/urls.py +0 -0
  265. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/initial_content/treats/views.py +0 -0
  266. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/examples/workshop_fleet/instructions/WELCOME.md +0 -0
  267. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/README.md +0 -0
  268. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/__init__.py +0 -0
  269. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/__main__.py +0 -0
  270. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/cli.py +0 -0
  271. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/README.md +0 -0
  272. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/__init__.py +0 -0
  273. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/client.py +0 -0
  274. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/README.md +0 -0
  275. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/base.py +0 -0
  276. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/chunked_content.py +0 -0
  277. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/diff_handlers.py +0 -0
  278. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/file_handlers.py +0 -0
  279. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_aware_file_handlers.py +0 -0
  280. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/README.md +0 -0
  281. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/__init__.py +0 -0
  282. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/file_system_watcher.py +0 -0
  283. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/git_manager.py +0 -0
  284. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/handlers.py +0 -0
  285. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/manager.py +0 -0
  286. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/models.py +0 -0
  287. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state/utils.py +0 -0
  288. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/project_state_handlers.py +0 -0
  289. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/registry.py +0 -0
  290. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/session.py +0 -0
  291. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/system_handlers.py +0 -0
  292. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/tab_factory.py +0 -0
  293. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/terminal_handlers.py +0 -0
  294. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/test_proxmox_infra.py +0 -0
  295. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/handlers/update_handler.py +0 -0
  296. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/multiplex.py +0 -0
  297. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/connection/terminal.py +0 -0
  298. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/data.py +0 -0
  299. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/keypair.py +0 -0
  300. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/__init__.py +0 -0
  301. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/__pycache__/__init__.cpython-311.pyc +0 -0
  302. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/__pycache__/link_capture_wrapper.cpython-311.pyc +0 -0
  303. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/elinks +0 -0
  304. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/gio-open +0 -0
  305. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/gnome-open +0 -0
  306. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/gvfs-open +0 -0
  307. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/kde-open +0 -0
  308. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/kfmclient +0 -0
  309. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/link_capture_exec.sh +0 -0
  310. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/link_capture_wrapper.py +0 -0
  311. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/links +0 -0
  312. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/links2 +0 -0
  313. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/lynx +0 -0
  314. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/mate-open +0 -0
  315. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/netsurf +0 -0
  316. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/sensible-browser +0 -0
  317. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/w3m +0 -0
  318. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/x-www-browser +0 -0
  319. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/link_capture/bin/xdg-open +0 -0
  320. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/logging_categories.py +0 -0
  321. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/pairing.py +0 -0
  322. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/service.py +0 -0
  323. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/static/js/test-ntp-clock.html +0 -0
  324. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/static/js/utils/ntp-clock.js +0 -0
  325. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/utils/NTP_ARCHITECTURE.md +0 -0
  326. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/utils/__init__.py +0 -0
  327. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/utils/diff_apply.py +0 -0
  328. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/utils/diff_renderer.py +0 -0
  329. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode/utils/ntp_clock.py +0 -0
  330. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode.egg-info/SOURCES.txt +0 -0
  331. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode.egg-info/dependency_links.txt +0 -0
  332. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode.egg-info/entry_points.txt +0 -0
  333. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode.egg-info/requires.txt +0 -0
  334. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/portacode.egg-info/top_level.txt +0 -0
  335. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/pyproject.toml +0 -0
  336. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/restore.sh +0 -0
  337. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/run_tests.py +0 -0
  338. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/setup.cfg +0 -0
  339. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/setup.py +0 -0
  340. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test.sh +0 -0
  341. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/README.md +0 -0
  342. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/__init__.py +0 -0
  343. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_device_online.py +0 -0
  344. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_file_operations.py +0 -0
  345. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_git_status_ui.py +0 -0
  346. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_login_flow.py +0 -0
  347. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_navigate_testing_folder.py +0 -0
  348. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_play_store_screenshots.py +0 -0
  349. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_terminal_buffer_performance.py +0 -0
  350. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_terminal_interaction.py +0 -0
  351. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_terminal_loading_race_condition.py +0 -0
  352. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_modules/test_terminal_start.py +0 -0
  353. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/test_request_id.py +0 -0
  354. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/.env.example +0 -0
  355. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/README.md +0 -0
  356. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/__init__.py +0 -0
  357. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/cli.py +0 -0
  358. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/__init__.py +0 -0
  359. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/base_test.py +0 -0
  360. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/cli_manager.py +0 -0
  361. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/hierarchical_runner.py +0 -0
  362. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/playwright_manager.py +0 -0
  363. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/runner.py +0 -0
  364. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/shared_cli_manager.py +0 -0
  365. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/core/test_discovery.py +0 -0
  366. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/testing_framework/requirements.txt +0 -0
  367. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/UI_UX/opening_a_file_on_desktop_results_in_nothing.md +0 -0
  368. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/agent_context_management.md +0 -0
  369. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/django_server_time_sync.md +0 -0
  370. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/device_performance_degradation.md +0 -0
  371. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/git_data_not_captured_in_proxmox.md +0 -0
  372. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/indefinite_resource_loading.md +0 -0
  373. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/portacode_service_silently_down.md +0 -0
  374. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/premature_terminal_exit.md +0 -0
  375. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/project_cpu_hotspots.md +0 -0
  376. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/terminals_exit_upon_starting.md +0 -0
  377. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/issues/wrong_item_classification_on_client_side.md +0 -0
  378. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/todo/smartphone_terminal_input_frustrations.md +0 -0
  379. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/tools/generate_play_store_assets.py +0 -0
  380. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/tools/pairing_tester.py +0 -0
  381. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/tools/run_screenshot_suite.sh +0 -0
  382. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/tools/test_python_ntp_clock.py +0 -0
  383. {portacode-1.4.15.dev1 → portacode-1.4.15.dev3}/validate.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: portacode
3
- Version: 1.4.15.dev1
3
+ Version: 1.4.15.dev3
4
4
  Summary: Portacode CLI client and SDK
5
5
  Home-page: https://github.com/portacode/portacode
6
6
  Author: Meena Erian
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.4.15.dev1'
32
- __version_tuple__ = version_tuple = (1, 4, 15, 'dev1')
31
+ __version__ = version = '1.4.15.dev3'
32
+ __version_tuple__ = version_tuple = (1, 4, 15, 'dev3')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -420,12 +420,12 @@ Creates or updates a Cloudflare tunnel in front of a managed container. The cont
420
420
 
421
421
  * `ctid` (string, required): Identifier of the container.
422
422
  * `container_port` (integer, required): Port inside the container to expose through Cloudflare.
423
- * `cloudflare_url` (string, required): Hostname (e.g., `app.example.com`) that the tunnel should serve.
423
+ * `cloudflare_url` (string, optional): Hostname (e.g., `app.example.com`) that the tunnel should serve. Leave blank to let Cloudflare create a quick tunnel (`*.cfargotunnel.com`) automatically.
424
424
  * `protocol` (string, optional): One of `http`, `https`, or `tcp` (defaults to `http`).
425
425
 
426
426
  **Responses:**
427
427
 
428
- * Emits a [`cloudflare_tunnel_created`](#cloudflare_tunnel_created-event) event with the tunnel metadata.
428
+ * Emits a [`cloudflare_tunnel_created`](#cloudflare_tunnel_created-event) event with the tunnel metadata, the refreshed infra snapshot, and the optional `device_id` so dashboards can refresh the CT list.
429
429
  * Emits an [`error`](#error) event on failure.
430
430
 
431
431
  ### `update_cloudflare_tunnel`
@@ -436,12 +436,12 @@ Refreshes the tunnel configuration for an existing tunnel (different port, URL,
436
436
 
437
437
  * `ctid` (string, required): Identifier of the container.
438
438
  * `container_port` (integer, optional): New container port.
439
- * `cloudflare_url` (string, optional): New hostname.
439
+ * `cloudflare_url` (string, optional): New hostname (leave blank to keep the current hostname or let Cloudflare assign a quick tunnel).
440
440
  * `protocol` (string, optional): New protocol (`http`, `https`, or `tcp`).
441
441
 
442
442
  **Responses:**
443
443
 
444
- * Emits a [`cloudflare_tunnel_updated`](#cloudflare_tunnel_updated-event) event with the refreshed tunnel metadata.
444
+ * Emits a [`cloudflare_tunnel_updated`](#cloudflare_tunnel_updated-event) event with the refreshed tunnel metadata, the refreshed infra snapshot, and the optional `device_id`.
445
445
  * Emits an [`error`](#error) event on failure.
446
446
 
447
447
  ### `remove_cloudflare_tunnel`
@@ -454,7 +454,7 @@ Stops and removes any tunnel metadata associated with a container.
454
454
 
455
455
  **Responses:**
456
456
 
457
- * Emits a [`cloudflare_tunnel_removed`](#cloudflare_tunnel_removed-event) event.
457
+ * Emits a [`cloudflare_tunnel_removed`](#cloudflare_tunnel_removed-event) event with the refreshed infra snapshot and optional `device_id`.
458
458
  * Emits an [`error`](#error) event on failure.
459
459
 
460
460
  ### `proxmox_container_created`
@@ -1272,8 +1272,10 @@ Submitted after a successful `create_cloudflare_tunnel` action.
1272
1272
  * `event` (string): `cloudflare_tunnel_created`.
1273
1273
  * `ctid` (string): Container ID associated with the tunnel.
1274
1274
  * `success` (boolean): True when the tunnel is running.
1275
- * `message` (string): Summary text.
1276
- * `tunnel` (object): Tunnel metadata matching the manager view.
1275
+ * `device_id` (string, optional): Mirrors the `device_id` supplied with the command, letting dashboards refresh that device immediately.
1276
+ * `message` (string): Summary text; when a hostname was assigned (including Quick Tunnel), the host is appended (e.g., `Created ... -> example.com`).
1277
+ * `tunnel` (object): Tunnel metadata matching the manager view. When using Cloudflare Quick Tunnel (no hostname supplied), `tunnel.url` holds the autogenerated `*.cfargotunnel.com` hostname.
1278
+ * `infra` (object): Snapshot produced by `get_infra_snapshot`, including the refreshed `managed_containers` list.
1277
1279
 
1278
1280
  ### `cloudflare_tunnel_updated`
1279
1281
 
@@ -1284,8 +1286,10 @@ Sent when `update_cloudflare_tunnel` completes.
1284
1286
  * `event` (string): `cloudflare_tunnel_updated`.
1285
1287
  * `ctid` (string): Container ID associated with the tunnel.
1286
1288
  * `success` (boolean): True on success.
1287
- * `message` (string): Summary text.
1289
+ * `device_id` (string, optional): Mirrors the command's `device_id`.
1290
+ * `message` (string): Summary text; includes the new hostname when one was assigned or changed.
1288
1291
  * `tunnel` (object): Updated tunnel metadata.
1292
+ * `infra` (object): Snapshot produced by `get_infra_snapshot` so dashboards can refresh the managed container list.
1289
1293
 
1290
1294
  ### `cloudflare_tunnel_removed`
1291
1295
 
@@ -1296,7 +1300,10 @@ Sent after a tunnel has been removed from a container record.
1296
1300
  * `event` (string): `cloudflare_tunnel_removed`.
1297
1301
  * `ctid` (string): Container ID that no longer has a tunnel.
1298
1302
  * `success` (boolean): True on success.
1303
+ * `device_id` (string, optional): Mirrors the command's `device_id`.
1299
1304
  * `message` (string): Summary text.
1305
+ * `tunnel` (null): Always `null` to explicitly clear the stored tunnel metadata.
1306
+ * `infra` (object): The refreshed snapshot so dashboards see the updated container list.
1300
1307
 
1301
1308
  ### <a name="clock_sync_response"></a>`clock_sync_response`
1302
1309
 
@@ -43,12 +43,15 @@ from .project_state_handlers import (
43
43
  )
44
44
  from .proxmox_infra import (
45
45
  ConfigureProxmoxInfraHandler,
46
+ CreateCloudflareTunnelHandler,
46
47
  CreateProxmoxContainerHandler,
47
48
  RevertProxmoxInfraHandler,
48
49
  StartPortacodeServiceHandler,
49
50
  StartProxmoxContainerHandler,
50
51
  StopProxmoxContainerHandler,
52
+ RemoveCloudflareTunnelHandler,
51
53
  RemoveProxmoxContainerHandler,
54
+ UpdateCloudflareTunnelHandler,
52
55
  )
53
56
 
54
57
  __all__ = [
@@ -62,6 +65,7 @@ __all__ = [
62
65
  "TerminalListHandler",
63
66
  "SystemInfoHandler",
64
67
  "ConfigureProxmoxInfraHandler",
68
+ "CreateCloudflareTunnelHandler",
65
69
  "CreateProxmoxContainerHandler",
66
70
  # File operation handlers (optional - register as needed)
67
71
  "FileReadHandler",
@@ -91,7 +95,9 @@ __all__ = [
91
95
  "StartPortacodeServiceHandler",
92
96
  "StartProxmoxContainerHandler",
93
97
  "StopProxmoxContainerHandler",
98
+ "RemoveCloudflareTunnelHandler",
94
99
  "RemoveProxmoxContainerHandler",
100
+ "UpdateCloudflareTunnelHandler",
95
101
  "UpdatePortacodeHandler",
96
102
  "RevertProxmoxInfraHandler",
97
103
  ]
@@ -8,6 +8,8 @@ import logging
8
8
  import os
9
9
  import secrets
10
10
  import shlex
11
+ import re
12
+ import select
11
13
  import shutil
12
14
  import stat
13
15
  import subprocess
@@ -637,19 +639,19 @@ def _launch_container_tunnel(proxmox: Any, node: str, vmid: int, tunnel: Dict[st
637
639
  port = int(tunnel.get("container_port") or 0)
638
640
  if not port:
639
641
  raise ValueError("container_port is required to create a tunnel.")
640
- hostname = tunnel.get("url")
641
- if not hostname:
642
- raise ValueError("cloudflare_url is required to expose the tunnel.")
642
+ requested_hostname = tunnel.get("url") or None
643
643
  protocol = (tunnel.get("protocol") or "http").lower()
644
644
  ip_address = _resolve_container_ip(proxmox, node, vmid)
645
645
  target_url = f"{protocol}://{ip_address}:{port}"
646
646
  name = tunnel.get("name") or _build_tunnel_name(vmid, port)
647
647
  _stop_cloudflare_process(name)
648
- proc = _start_cloudflare_process(name, hostname, target_url)
648
+ proc, assigned_url = _start_cloudflare_process(name, target_url, hostname=requested_hostname)
649
+ if not assigned_url:
650
+ raise RuntimeError("Failed to determine Cloudflare hostname for the tunnel.")
649
651
  updated = {
650
652
  "name": name,
651
653
  "container_port": port,
652
- "url": hostname,
654
+ "url": assigned_url,
653
655
  "protocol": protocol,
654
656
  "status": "running",
655
657
  "pid": proc.pid,
@@ -671,13 +673,14 @@ def _stop_container_tunnel(vmid: int) -> None:
671
673
  return
672
674
  name = tunnel.get("name") or _build_tunnel_name(vmid, int(tunnel.get("container_port") or 0))
673
675
  stopped = _stop_cloudflare_process(name)
674
- if stopped or tunnel.get("status") != "stopped":
675
- tunnel_update = {
676
- **tunnel,
677
- "status": "stopped",
678
- "pid": None,
679
- "last_updated": datetime.utcnow().isoformat() + "Z",
680
- }
676
+ if not stopped and tunnel.get("status") == "stopped":
677
+ return
678
+ tunnel_update = {
679
+ **tunnel,
680
+ "status": "stopped",
681
+ "pid": None,
682
+ "last_updated": datetime.utcnow().isoformat() + "Z",
683
+ }
681
684
  _update_container_tunnel(vmid, tunnel_update)
682
685
 
683
686
 
@@ -827,25 +830,67 @@ def _get_cloudflared_binary() -> str:
827
830
  return binary
828
831
 
829
832
 
830
- def _start_cloudflare_process(name: str, hostname: str, target_url: str) -> subprocess.Popen:
833
+ def _drain_stream(stream: Optional[Any]) -> None:
834
+ if stream is None:
835
+ return
836
+ try:
837
+ for _ in iter(stream.readline, ""):
838
+ continue
839
+ except Exception:
840
+ pass
841
+ finally:
842
+ try:
843
+ stream.close()
844
+ except Exception:
845
+ pass
846
+
847
+
848
+ def _await_quick_tunnel_url(proc: subprocess.Popen, timeout: float = 15.0) -> Optional[str]:
849
+ if not proc.stdout:
850
+ return None
851
+ cf_re = re.compile(r"https://[A-Za-z0-9\-.]+\.cfargotunnel\.com")
852
+ deadline = time.time() + timeout
853
+ while time.time() < deadline:
854
+ ready, _, _ = select.select([proc.stdout], [], [], 1)
855
+ if not ready:
856
+ continue
857
+ line = proc.stdout.readline()
858
+ if not line:
859
+ continue
860
+ match = cf_re.search(line)
861
+ if match:
862
+ return match.group(0)
863
+ return None
864
+
865
+
866
+ def _start_cloudflare_process(name: str, target_url: str, hostname: Optional[str] = None) -> Tuple[subprocess.Popen, Optional[str]]:
831
867
  binary = _get_cloudflared_binary()
832
868
  cmd = [
833
869
  binary,
834
870
  "tunnel",
835
- "--hostname",
836
- hostname,
837
871
  "--url",
838
872
  target_url,
839
873
  "--no-autoupdate",
840
874
  ]
875
+ if hostname:
876
+ cmd.extend(["--hostname", hostname])
877
+ stdout_target = subprocess.DEVNULL
878
+ else:
879
+ stdout_target = subprocess.PIPE
841
880
  proc = subprocess.Popen(
842
881
  cmd,
843
- stdout=subprocess.DEVNULL,
844
- stderr=subprocess.DEVNULL,
882
+ stdout=stdout_target,
883
+ stderr=subprocess.PIPE,
884
+ text=True,
845
885
  )
846
886
  with _CLOUDFLARE_TUNNELS_LOCK:
847
887
  _CLOUDFLARE_TUNNEL_PROCESSES[name] = proc
848
- return proc
888
+ assigned_url = hostname
889
+ if not hostname:
890
+ assigned_url = _await_quick_tunnel_url(proc)
891
+ threading.Thread(target=_drain_stream, args=(proc.stdout,), daemon=True).start()
892
+ threading.Thread(target=_drain_stream, args=(proc.stderr,), daemon=True).start()
893
+ return proc, assigned_url
849
894
 
850
895
 
851
896
  def _stop_cloudflare_process(name: str) -> bool:
@@ -1884,8 +1929,7 @@ class CreateCloudflareTunnelHandler(SyncHandler):
1884
1929
  if container_port <= 0:
1885
1930
  raise ValueError("container_port is required and must be greater than zero.")
1886
1931
  hostname = (message.get("cloudflare_url") or message.get("hostname") or "").strip()
1887
- if not hostname:
1888
- raise ValueError("cloudflare_url is required.")
1932
+ hostname = hostname or None
1889
1933
  protocol = (message.get("protocol") or "http").strip().lower()
1890
1934
  if protocol not in {"http", "https", "tcp"}:
1891
1935
  raise ValueError("protocol must be one of http, https, or tcp.")
@@ -1899,17 +1943,28 @@ class CreateCloudflareTunnelHandler(SyncHandler):
1899
1943
  raise RuntimeError("Container must be running to create a tunnel.")
1900
1944
  tunnel = {
1901
1945
  "container_port": container_port,
1902
- "url": hostname,
1903
1946
  "protocol": protocol,
1904
1947
  }
1948
+ if hostname:
1949
+ tunnel["url"] = hostname
1905
1950
  created = _launch_container_tunnel(proxmox, node, vmid, tunnel)
1906
- return {
1951
+ infra = get_infra_snapshot()
1952
+ host_url = created.get("url")
1953
+ response_message = f"Created Cloudflare tunnel for container {vmid}."
1954
+ if host_url:
1955
+ response_message = f"{response_message[:-1]} -> {host_url}."
1956
+ response = {
1907
1957
  "event": "cloudflare_tunnel_created",
1908
1958
  "ctid": str(vmid),
1909
1959
  "success": True,
1910
- "message": f"Created Cloudflare tunnel for container {vmid}.",
1960
+ "message": response_message,
1911
1961
  "tunnel": created,
1962
+ "infra": infra,
1912
1963
  }
1964
+ device_id = message.get("device_id")
1965
+ if device_id:
1966
+ response["device_id"] = device_id
1967
+ return response
1913
1968
 
1914
1969
 
1915
1970
  class UpdateCloudflareTunnelHandler(SyncHandler):
@@ -1934,24 +1989,34 @@ class UpdateCloudflareTunnelHandler(SyncHandler):
1934
1989
  if container_port <= 0:
1935
1990
  raise ValueError("container_port must be greater than zero.")
1936
1991
  hostname = (message.get("cloudflare_url") or tunnel.get("url") or "").strip()
1937
- if not hostname:
1938
- raise ValueError("cloudflare_url is required.")
1992
+ hostname = hostname or None
1939
1993
  protocol = (message.get("protocol") or tunnel.get("protocol") or "http").strip().lower()
1940
1994
  if protocol not in {"http", "https", "tcp"}:
1941
1995
  raise ValueError("protocol must be one of http, https, or tcp.")
1942
1996
  updated_tunnel = {
1943
1997
  "container_port": container_port,
1944
- "url": hostname,
1945
1998
  "protocol": protocol,
1946
1999
  }
2000
+ if hostname:
2001
+ updated_tunnel["url"] = hostname
1947
2002
  result = _launch_container_tunnel(proxmox, node, vmid, updated_tunnel)
1948
- return {
2003
+ infra = get_infra_snapshot()
2004
+ host_url = result.get("url")
2005
+ response_message = f"Updated Cloudflare tunnel for container {vmid}."
2006
+ if host_url:
2007
+ response_message = f"{response_message[:-1]} -> {host_url}."
2008
+ response = {
1949
2009
  "event": "cloudflare_tunnel_updated",
1950
2010
  "ctid": str(vmid),
1951
2011
  "success": True,
1952
- "message": f"Updated Cloudflare tunnel for container {vmid}.",
2012
+ "message": response_message,
1953
2013
  "tunnel": result,
2014
+ "infra": infra,
1954
2015
  }
2016
+ device_id = message.get("device_id")
2017
+ if device_id:
2018
+ response["device_id"] = device_id
2019
+ return response
1955
2020
 
1956
2021
 
1957
2022
  class RemoveCloudflareTunnelHandler(SyncHandler):
@@ -1964,12 +2029,19 @@ class RemoveCloudflareTunnelHandler(SyncHandler):
1964
2029
  def execute(self, message: Dict[str, Any]) -> Dict[str, Any]:
1965
2030
  vmid = _parse_ctid(message)
1966
2031
  _remove_container_tunnel_state(vmid)
1967
- return {
2032
+ infra = get_infra_snapshot()
2033
+ response = {
1968
2034
  "event": "cloudflare_tunnel_removed",
1969
2035
  "ctid": str(vmid),
1970
2036
  "success": True,
1971
2037
  "message": f"Removed Cloudflare tunnel state for container {vmid}.",
2038
+ "tunnel": None,
2039
+ "infra": infra,
1972
2040
  }
2041
+ device_id = message.get("device_id")
2042
+ if device_id:
2043
+ response["device_id"] = device_id
2044
+ return response
1973
2045
 
1974
2046
 
1975
2047
  class ConfigureProxmoxInfraHandler(SyncHandler):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: portacode
3
- Version: 1.4.15.dev1
3
+ Version: 1.4.15.dev3
4
4
  Summary: Portacode CLI client and SDK
5
5
  Home-page: https://github.com/portacode/portacode
6
6
  Author: Meena Erian
File without changes