painapple-code 1.0.2__tar.gz → 1.0.3__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 (511) hide show
  1. {painapple_code-1.0.2/src/painapple_code.egg-info → painapple_code-1.0.3}/PKG-INFO +1 -1
  2. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/_version.py +3 -3
  3. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/deploy/container.py +4 -0
  4. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/lifecycle_cmd.py +3 -0
  5. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/netinfo.py +31 -3
  6. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/serve_args.py +6 -0
  7. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/paths.py +24 -0
  8. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_session_welcome.py +33 -1
  9. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/server.py +44 -7
  10. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/67-file-preview-widget.css +17 -0
  11. {painapple_code-1.0.2 → painapple_code-1.0.3/src/painapple_code.egg-info}/PKG-INFO +1 -1
  12. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code.egg-info/scm_file_list.json +2 -0
  13. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code.egg-info/scm_version.json +2 -2
  14. {painapple_code-1.0.2 → painapple_code-1.0.3}/.devcontainer/devcontainer.json +0 -0
  15. {painapple_code-1.0.2 → painapple_code-1.0.3}/.dockerignore +0 -0
  16. {painapple_code-1.0.2 → painapple_code-1.0.3}/.gitignore +0 -0
  17. {painapple_code-1.0.2 → painapple_code-1.0.3}/CHANGELOG.md +0 -0
  18. {painapple_code-1.0.2 → painapple_code-1.0.3}/CONTRIBUTING.md +0 -0
  19. {painapple_code-1.0.2 → painapple_code-1.0.3}/Dockerfile +0 -0
  20. {painapple_code-1.0.2 → painapple_code-1.0.3}/LICENSE +0 -0
  21. {painapple_code-1.0.2 → painapple_code-1.0.3}/MANIFEST.in +0 -0
  22. {painapple_code-1.0.2 → painapple_code-1.0.3}/README.dockerhub.md +0 -0
  23. {painapple_code-1.0.2 → painapple_code-1.0.3}/README.md +0 -0
  24. {painapple_code-1.0.2 → painapple_code-1.0.3}/SECURITY.md +0 -0
  25. {painapple_code-1.0.2 → painapple_code-1.0.3}/THIRD_PARTY_NOTICES.md +0 -0
  26. {painapple_code-1.0.2 → painapple_code-1.0.3}/build-frontend.sh +0 -0
  27. {painapple_code-1.0.2 → painapple_code-1.0.3}/docker-compose.yml +0 -0
  28. {painapple_code-1.0.2 → painapple_code-1.0.3}/docker-entrypoint.sh +0 -0
  29. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/annotate-editor.png +0 -0
  30. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/browser-widget.png +0 -0
  31. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/comments-stash.gif +0 -0
  32. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/cost-analytics.png +0 -0
  33. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/favicon.png +0 -0
  34. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/input-autocomplete.gif +0 -0
  35. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/logo.png +0 -0
  36. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/markdown-quick-edit.gif +0 -0
  37. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/overview.png +0 -0
  38. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/prompt-history.png +0 -0
  39. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/quick-switcher.gif +0 -0
  40. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/quick-switcher.png +0 -0
  41. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/settings-appearance.png +0 -0
  42. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/settings-claude.png +0 -0
  43. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/shadow-journal.png +0 -0
  44. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/snippets-picker.png +0 -0
  45. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/terminal.gif +0 -0
  46. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/turn-summary-bar-expanded.png +0 -0
  47. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/turn-summary-bar.png +0 -0
  48. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/welcome-screen.png +0 -0
  49. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/assets/zen-mode.png +0 -0
  50. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/features.md +0 -0
  51. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/getting-started/first-run.md +0 -0
  52. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/getting-started/install-devcontainer.md +0 -0
  53. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/getting-started/install-docker.md +0 -0
  54. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/getting-started/install-pip.md +0 -0
  55. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/getting-started/requirements.md +0 -0
  56. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/getting-started/security.md +0 -0
  57. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/analytics-and-history.md +0 -0
  58. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/claude-artifacts.md +0 -0
  59. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/customization.md +0 -0
  60. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/files.md +0 -0
  61. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/git-and-diffs.md +0 -0
  62. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/images-and-annotation.md +0 -0
  63. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/input-and-commands.md +0 -0
  64. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/ipad-and-mobile.md +0 -0
  65. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/permissions-and-thinking.md +0 -0
  66. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/providers.md +0 -0
  67. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/sessions.md +0 -0
  68. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/shadow-git.md +0 -0
  69. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/stash-and-discussions.md +0 -0
  70. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/terminal.md +0 -0
  71. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/welcome-screen.md +0 -0
  72. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/guides/zen-mode.md +0 -0
  73. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/index.md +0 -0
  74. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/reference/api.md +0 -0
  75. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/reference/commands.md +0 -0
  76. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/reference/data-storage.md +0 -0
  77. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/reference/keyboard-shortcuts.md +0 -0
  78. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/reference/optional-helpers.md +0 -0
  79. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/reference/profiles.md +0 -0
  80. {painapple_code-1.0.2 → painapple_code-1.0.3}/docs-site/reference/server-cli.md +0 -0
  81. {painapple_code-1.0.2 → painapple_code-1.0.3}/mkdocs.yml +0 -0
  82. {painapple_code-1.0.2 → painapple_code-1.0.3}/painapple-docker.sh +0 -0
  83. {painapple_code-1.0.2 → painapple_code-1.0.3}/pyproject.toml +0 -0
  84. {painapple_code-1.0.2 → painapple_code-1.0.3}/requirements-docs.txt +0 -0
  85. {painapple_code-1.0.2 → painapple_code-1.0.3}/requirements.txt +0 -0
  86. {painapple_code-1.0.2 → painapple_code-1.0.3}/setup.cfg +0 -0
  87. {painapple_code-1.0.2 → painapple_code-1.0.3}/setup.py +0 -0
  88. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/__init__.py +0 -0
  89. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/__main__.py +0 -0
  90. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/auth_middleware.py +0 -0
  91. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/__init__.py +0 -0
  92. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/deploy/__init__.py +0 -0
  93. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/deploy/claude_seed.py +0 -0
  94. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/deploy/config.py +0 -0
  95. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/deploy/launch.py +0 -0
  96. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/deploy/runtime.py +0 -0
  97. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/list_cmd.py +0 -0
  98. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/manage_cmd.py +0 -0
  99. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/profiles.py +0 -0
  100. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/serve_config.py +0 -0
  101. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/setup_cmd.py +0 -0
  102. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cli/ui.py +0 -0
  103. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/cost_analytics.py +0 -0
  104. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/data/models.defaults.yaml +0 -0
  105. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/data/models.yaml +0 -0
  106. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/data/presets.defaults.json +0 -0
  107. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/data/strings.yaml +0 -0
  108. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/helpers.py +0 -0
  109. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/prompt_explorer.py +0 -0
  110. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/__init__.py +0 -0
  111. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/base.py +0 -0
  112. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude/__init__.py +0 -0
  113. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude/capabilities.py +0 -0
  114. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude/errors.py +0 -0
  115. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude/launch.py +0 -0
  116. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude/summary.py +0 -0
  117. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude/translate.py +0 -0
  118. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude_sdk/__init__.py +0 -0
  119. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/claude_sdk/driver.py +0 -0
  120. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex/__init__.py +0 -0
  121. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex/capabilities.py +0 -0
  122. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex/errors.py +0 -0
  123. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex/translate.py +0 -0
  124. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex_app_server/__init__.py +0 -0
  125. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex_app_server/capabilities.py +0 -0
  126. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex_app_server/launch.py +0 -0
  127. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex_app_server/summary.py +0 -0
  128. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex_app_server/translate.py +0 -0
  129. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/providers/codex_app_server/transport.py +0 -0
  130. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/__init__.py +0 -0
  131. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_agents.py +0 -0
  132. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_app.py +0 -0
  133. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_app_commit_sections.py +0 -0
  134. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_app_config.py +0 -0
  135. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_app_session_prefs.py +0 -0
  136. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_browser.py +0 -0
  137. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_commands.py +0 -0
  138. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_costs.py +0 -0
  139. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_drafts.py +0 -0
  140. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_exec.py +0 -0
  141. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_files.py +0 -0
  142. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_git.py +0 -0
  143. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_logs.py +0 -0
  144. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_plugins.py +0 -0
  145. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_project_config.py +0 -0
  146. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_prompts.py +0 -0
  147. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_providers.py +0 -0
  148. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_search.py +0 -0
  149. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_session_stash.py +0 -0
  150. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_sessions.py +0 -0
  151. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_shadow.py +0 -0
  152. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_shadow_db.py +0 -0
  153. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_shadow_files.py +0 -0
  154. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_shadow_search.py +0 -0
  155. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_skills.py +0 -0
  156. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_tasks.py +0 -0
  157. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_terminal.py +0 -0
  158. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_upload.py +0 -0
  159. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/api_viewer.py +0 -0
  160. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/dependencies.py +0 -0
  161. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/routes/ws_chat.py +0 -0
  162. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/server_logging.py +0 -0
  163. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/services/__init__.py +0 -0
  164. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/services/agent_session.py +0 -0
  165. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/session_store.py +0 -0
  166. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/session_store_core.py +0 -0
  167. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_db.py +0 -0
  168. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_db_plans.py +0 -0
  169. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_db_queries.py +0 -0
  170. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_db_schema.py +0 -0
  171. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_git.py +0 -0
  172. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_git_frontmatter.py +0 -0
  173. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_git_sections.py +0 -0
  174. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_git_summary.py +0 -0
  175. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/shadow_parser.py +0 -0
  176. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/00-variables.css +0 -0
  177. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/01-base.css +0 -0
  178. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/02-tooltips.css +0 -0
  179. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/09-left-rail.css +0 -0
  180. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/10-header.css +0 -0
  181. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/11-connection-bar.css +0 -0
  182. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/20-messages.css +0 -0
  183. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/21-tool-blocks.css +0 -0
  184. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/22-edit-diff.css +0 -0
  185. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/23-thinking.css +0 -0
  186. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/24-background-tasks.css +0 -0
  187. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/25-context-block.css +0 -0
  188. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/26-session-setup.css +0 -0
  189. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/30-markdown.css +0 -0
  190. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/40-input.css +0 -0
  191. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/41-autocomplete.css +0 -0
  192. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/42-activity-strip.css +0 -0
  193. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/43-file-autocomplete.css +0 -0
  194. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/44-snippets-autocomplete.css +0 -0
  195. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/45-selection-bar.css +0 -0
  196. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/46-keyboard-bar.css +0 -0
  197. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/47-keyboard-longpress.css +0 -0
  198. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/47-token-profile.css +0 -0
  199. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/50-welcome.css +0 -0
  200. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/51-modals.css +0 -0
  201. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/52-utilities.css +0 -0
  202. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/53-image-upload.css +0 -0
  203. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/54-todo-list.css +0 -0
  204. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/55-file-upload.css +0 -0
  205. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/56-chat-navigator.css +0 -0
  206. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/56-permission-card.css +0 -0
  207. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/56-plan-approval.css +0 -0
  208. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/56-question-form.css +0 -0
  209. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/57-swipe-indicator.css +0 -0
  210. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/58-session-families.css +0 -0
  211. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/59-about.css +0 -0
  212. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/61-log-explorer.css +0 -0
  213. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/62-json-tree.css +0 -0
  214. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/62-skills-widget.css +0 -0
  215. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/63-commands-widget.css +0 -0
  216. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/63-plugins-widget.css +0 -0
  217. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/63-terminal.css +0 -0
  218. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/64-search-files-widget.css +0 -0
  219. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/65-snippets-widget.css +0 -0
  220. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/66-active-sessions.css +0 -0
  221. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/66-agents-widget.css +0 -0
  222. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/66-file-explorer-widget.css +0 -0
  223. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/66-git-panel.css +0 -0
  224. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/66-history-explorer.css +0 -0
  225. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/67-diff-viewer.css +0 -0
  226. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/67-editor-view.css +0 -0
  227. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-browser-widget.css +0 -0
  228. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-compare-wizard.css +0 -0
  229. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-csv-preview.css +0 -0
  230. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-diff-preview.css +0 -0
  231. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-helpers-install-widget.css +0 -0
  232. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-image-annotate.css +0 -0
  233. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-terminal-view.css +0 -0
  234. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/68-uploads-widget.css +0 -0
  235. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/69-cost-analytics.css +0 -0
  236. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/70-config-panel.css +0 -0
  237. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/70-excalidraw.css +0 -0
  238. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/70-prompt-explorer.css +0 -0
  239. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/71-chart.css +0 -0
  240. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/72-discussion-sidebar.css +0 -0
  241. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/74-debug-logs.css +0 -0
  242. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/80-open-dialog.css +0 -0
  243. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/80-quick-switcher.css +0 -0
  244. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/80-widget-system.css +0 -0
  245. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/81-quick-actions.css +0 -0
  246. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/82-context-popover.css +0 -0
  247. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/83-context-menu.css +0 -0
  248. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/85-lazy-loading.css +0 -0
  249. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/86-zen-mode.css +0 -0
  250. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/87-grid-switcher.css +0 -0
  251. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/css/login.css +0 -0
  252. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/dist/app.bundle.js +0 -0
  253. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/feature-triage.html +0 -0
  254. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/apple-touch-icon.png +0 -0
  255. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/favicon-32.png +0 -0
  256. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/favicon.ico +0 -0
  257. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-128.png +0 -0
  258. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-144.png +0 -0
  259. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-152.png +0 -0
  260. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-180.png +0 -0
  261. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-192.png +0 -0
  262. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-384.png +0 -0
  263. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-512.png +0 -0
  264. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-72.png +0 -0
  265. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/icons/icon-96.png +0 -0
  266. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/action-delegate.js +0 -0
  267. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/activity-strip.js +0 -0
  268. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/context-menus.js +0 -0
  269. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/file-preview.js +0 -0
  270. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/init-ui.js +0 -0
  271. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/input-events.js +0 -0
  272. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/input-resize.js +0 -0
  273. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/message-actions.js +0 -0
  274. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/panels.js +0 -0
  275. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/rendering-delegators.js +0 -0
  276. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/server-loading.js +0 -0
  277. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/session-ops.js +0 -0
  278. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/session-switch.js +0 -0
  279. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/settings-helpers.js +0 -0
  280. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app/startup-welcome.js +0 -0
  281. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app-context.js +0 -0
  282. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/app.js +0 -0
  283. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/auth-fetch.js +0 -0
  284. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/background-tasks.js +0 -0
  285. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/boot.js +0 -0
  286. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/caret-position.js +0 -0
  287. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/chat-navigator.js +0 -0
  288. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/chat-search.js +0 -0
  289. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/command-executor.js +0 -0
  290. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/command-store.js +0 -0
  291. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/components.js +0 -0
  292. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/config.js +0 -0
  293. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/context-menu.js +0 -0
  294. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/controllers/chat-controller.js +0 -0
  295. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/controllers/dialog-controller.js +0 -0
  296. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/controllers/tab-controller.js +0 -0
  297. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/controllers/thinking-controller.js +0 -0
  298. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/diff-utils.js +0 -0
  299. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/drafts-pill.js +0 -0
  300. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/editor-view.js +0 -0
  301. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/effort-settings.js +0 -0
  302. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/feature-triage.js +0 -0
  303. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/file-autocomplete.js +0 -0
  304. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/file-tabs.js +0 -0
  305. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/gestures.js +0 -0
  306. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/grid-switcher.js +0 -0
  307. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/input-handler.js +0 -0
  308. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/keyboard-bar.js +0 -0
  309. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/layout-switcher.js +0 -0
  310. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/linkify-utils.js +0 -0
  311. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/login.js +0 -0
  312. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/open-dialog.js +0 -0
  313. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/orphan-terminals.js +0 -0
  314. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/path-utils.js +0 -0
  315. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/perf-marks.js +0 -0
  316. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/permission-settings.js +0 -0
  317. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/pointer-input.js +0 -0
  318. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/json-tree-menu.js +0 -0
  319. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/json-tree-toolbar.js +0 -0
  320. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/json-tree.js +0 -0
  321. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-breadcrumb.js +0 -0
  322. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-edit.js +0 -0
  323. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-events.js +0 -0
  324. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-history.js +0 -0
  325. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-inline-edit.js +0 -0
  326. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-poll.js +0 -0
  327. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-render.js +0 -0
  328. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-search.js +0 -0
  329. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-state.js +0 -0
  330. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview/preview-utils.js +0 -0
  331. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/chart-plugin.js +0 -0
  332. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/csv-plugin.js +0 -0
  333. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/diff-plugin.js +0 -0
  334. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/excalidraw-plugin.js +0 -0
  335. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/html-plugin.js +0 -0
  336. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/image-plugin.js +0 -0
  337. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/index.js +0 -0
  338. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/json-plugin.js +0 -0
  339. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/jsonl-plugin.js +0 -0
  340. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/markdown-plugin.js +0 -0
  341. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/panzoom-plugin.js +0 -0
  342. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/preview-plugins/plugin-helpers.js +0 -0
  343. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/project-color-picker.js +0 -0
  344. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/project-colors.js +0 -0
  345. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/prompt-favorites.js +0 -0
  346. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-actions-menu.js +0 -0
  347. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-actions-registry.js +0 -0
  348. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/controller.js +0 -0
  349. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/fuzzy-scorer.js +0 -0
  350. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/index.js +0 -0
  351. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/providers/base-provider.js +0 -0
  352. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/providers/command-provider.js +0 -0
  353. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/providers/file-provider.js +0 -0
  354. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/providers/panel-provider.js +0 -0
  355. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/providers/project-provider.js +0 -0
  356. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/providers/read-files-provider.js +0 -0
  357. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/providers/skills-provider.js +0 -0
  358. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/registry.js +0 -0
  359. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/ui/item.js +0 -0
  360. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/quick-switcher/ui/picker.js +0 -0
  361. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/recent-opens.js +0 -0
  362. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/scroll-manager.js +0 -0
  363. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/scroll-state-machine.js +0 -0
  364. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/selection/action-bar.js +0 -0
  365. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/selection/index.js +0 -0
  366. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/selection/selection-handler.js +0 -0
  367. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/selection/state.js +0 -0
  368. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/agent-progress.js +0 -0
  369. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/handle-agent-message.js +0 -0
  370. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/handle-message.js +0 -0
  371. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/interactive.js +0 -0
  372. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/message-store.js +0 -0
  373. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/messages.js +0 -0
  374. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/persistence.js +0 -0
  375. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/restore.js +0 -0
  376. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session/sync.js +0 -0
  377. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session-container-pool.js +0 -0
  378. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session-setup-panel.js +0 -0
  379. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/session.js +0 -0
  380. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/shortcut-hints.js +0 -0
  381. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/shortcuts.js +0 -0
  382. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/skills-autocomplete.js +0 -0
  383. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/snippets-autocomplete.js +0 -0
  384. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/stash-refs-view.js +0 -0
  385. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/stash-ui.js +0 -0
  386. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/stash.js +0 -0
  387. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/status-bar.js +0 -0
  388. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/token-profile.js +0 -0
  389. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/tool-renderer-blocks.js +0 -0
  390. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/tool-renderer-thinking.js +0 -0
  391. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/tool-renderer.js +0 -0
  392. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/tooltips.js +0 -0
  393. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/upload-manager.js +0 -0
  394. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/utils.js +0 -0
  395. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/welcome/api.js +0 -0
  396. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/welcome/cards.js +0 -0
  397. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/welcome/context-menu.js +0 -0
  398. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/welcome/families.js +0 -0
  399. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/welcome/preview.js +0 -0
  400. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/welcome/state.js +0 -0
  401. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/welcome.js +0 -0
  402. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/base-widget.js +0 -0
  403. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/device-manager.js +0 -0
  404. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/event-bus.js +0 -0
  405. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/icons.js +0 -0
  406. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/index.js +0 -0
  407. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/init.js +0 -0
  408. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/types/bottom-sheet.js +0 -0
  409. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/types/floating.js +0 -0
  410. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/types/index.js +0 -0
  411. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/types/modal.js +0 -0
  412. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/types/sidebar.js +0 -0
  413. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/types/tab.js +0 -0
  414. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/types/top-sheet.js +0 -0
  415. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widget-system/widget-manager.js +0 -0
  416. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/about-widget.js +0 -0
  417. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/active-sessions-widget.js +0 -0
  418. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/agents-widget.js +0 -0
  419. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/browser-widget.js +0 -0
  420. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/commands-widget.js +0 -0
  421. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/commit-sections.js +0 -0
  422. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/dir-autocomplete.js +0 -0
  423. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/gestures.js +0 -0
  424. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/models-tab.js +0 -0
  425. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/quick-actions-tab.js +0 -0
  426. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/shortcut-editor.js +0 -0
  427. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/state.js +0 -0
  428. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config/system-controls.js +0 -0
  429. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/config-widget.js +0 -0
  430. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/cost-analytics-widget.js +0 -0
  431. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/debug-widget.js +0 -0
  432. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/diff-viewer-widget.js +0 -0
  433. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/discussion-widget.js +0 -0
  434. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/file-explorer-widget.js +0 -0
  435. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/file-preview-widget.js +0 -0
  436. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/git-widget.js +0 -0
  437. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/helpers-install-widget.js +0 -0
  438. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/history-explorer-widget.js +0 -0
  439. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/image-annotate-widget.js +0 -0
  440. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/image-preview-widget.js +0 -0
  441. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/index.js +0 -0
  442. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/log-explorer-widget.js +0 -0
  443. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/plugins-widget.js +0 -0
  444. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/prompt-explorer-widget.js +0 -0
  445. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/search-files-widget.js +0 -0
  446. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/skills-widget.js +0 -0
  447. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/snippets-widget.js +0 -0
  448. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/sub-agents-widget.js +0 -0
  449. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/tasks-widget.js +0 -0
  450. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/connection.js +0 -0
  451. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/gestures.js +0 -0
  452. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/init.js +0 -0
  453. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/link-providers.js +0 -0
  454. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/osc52.js +0 -0
  455. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/render.js +0 -0
  456. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/size.js +0 -0
  457. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/state.js +0 -0
  458. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal/wrap-utils.js +0 -0
  459. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/terminal-widget.js +0 -0
  460. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/uploads-widget.js +0 -0
  461. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/js/widgets/zen-widget.js +0 -0
  462. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/login.html +0 -0
  463. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/manifest.json +0 -0
  464. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/sw.js +0 -0
  465. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/LICENSES.txt +0 -0
  466. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/README.md +0 -0
  467. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/codemirror.js +0 -0
  468. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/codemirror.js.LEGAL.txt +0 -0
  469. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/github-markdown-dark.min.css +0 -0
  470. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/highlight-github-dark.min.css +0 -0
  471. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/highlight-lang-dockerfile.min.js +0 -0
  472. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/highlight-lang-nginx.min.js +0 -0
  473. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/highlight-lang-properties.min.js +0 -0
  474. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/highlight-lang-scala.min.js +0 -0
  475. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/highlight.min.js +0 -0
  476. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/marked.min.js +0 -0
  477. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/purify.min.js +0 -0
  478. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/xterm-addon-fit.js +0 -0
  479. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/xterm.css +0 -0
  480. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/vendor/xterm.js +0 -0
  481. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/static/web-client.html +0 -0
  482. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/subprocess_registry.py +0 -0
  483. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/tls_cert.py +0 -0
  484. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/tools/agents/shadow-git-helper.md +0 -0
  485. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/tools/excalidraw-to-svg.js +0 -0
  486. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/tools/install-helpers.sh +0 -0
  487. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/tools/shadow-git +0 -0
  488. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/tools/shadow-query +0 -0
  489. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/tools/vegalite-to-svg.js +0 -0
  490. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/turn_query.py +0 -0
  491. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/turn_tracker.py +0 -0
  492. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/__init__.py +0 -0
  493. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/agent_cli.py +0 -0
  494. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/chart.py +0 -0
  495. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/excalidraw.py +0 -0
  496. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/file_lock.py +0 -0
  497. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/file_paths.py +0 -0
  498. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/generate_icons.py +0 -0
  499. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/proc.py +0 -0
  500. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/pty_backend.py +0 -0
  501. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/pty_posix.py +0 -0
  502. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/pty_windows.py +0 -0
  503. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/utils/token_profiles.py +0 -0
  504. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/viewer_templates.py +0 -0
  505. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code/welcome_search.py +0 -0
  506. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code.egg-info/SOURCES.txt +0 -0
  507. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code.egg-info/dependency_links.txt +0 -0
  508. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code.egg-info/entry_points.txt +0 -0
  509. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code.egg-info/requires.txt +0 -0
  510. {painapple_code-1.0.2 → painapple_code-1.0.3}/src/painapple_code.egg-info/top_level.txt +0 -0
  511. {painapple_code-1.0.2 → painapple_code-1.0.3}/start.sh +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: painapple-code
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: Self-hosted remote UI for Claude Code that journals every turn - background AI summaries become shadow-git commits and a queryable DuckDB history
5
5
  Author-email: Michał Booth-Wrotkowski <michal@boothw.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -18,7 +18,7 @@ version_tuple: tuple[int | str, ...]
18
18
  commit_id: str | None
19
19
  __commit_id__: str | None
20
20
 
21
- __version__ = version = '1.0.2'
22
- __version_tuple__ = version_tuple = (1, 0, 2)
21
+ __version__ = version = '1.0.3'
22
+ __version_tuple__ = version_tuple = (1, 0, 3)
23
23
 
24
- __commit_id__ = commit_id = 'ge157c77'
24
+ __commit_id__ = commit_id = 'g1be1164'
@@ -533,6 +533,10 @@ def run_container(cfg, detach, profile=None):
533
533
  from painapple_code.cli.netinfo import port_holder, port_taken
534
534
  reason = port_taken(cfg.listen_host, cfg.port)
535
535
  if reason:
536
+ if getattr(reason, "bad_host", False):
537
+ err(f"Cannot bind {cfg.listen_host}:{cfg.port} — {reason}")
538
+ say(f" {DIM}Fix the bind host: {hint('setup', profile)}{RESET}")
539
+ return 1
536
540
  holder = port_holder(cfg.port)
537
541
  err(f"Port {cfg.port} on {cfg.listen_host} is already in use — {reason}"
538
542
  + (f" (held by {holder})" if holder else ""))
@@ -283,6 +283,9 @@ def _start(target, extra):
283
283
  from painapple_code.cli.netinfo import port_holder, port_taken
284
284
  reason = port_taken(host, port)
285
285
  if reason:
286
+ if getattr(reason, "bad_host", False):
287
+ err(f"Cannot bind {host}:{port} — {reason}. Check the host address.")
288
+ return 1
286
289
  holder = port_holder(port)
287
290
  err(f"Port {port} on {host} is already in use — {reason}"
288
291
  + (f" (held by {holder})" if holder else ""))
@@ -37,18 +37,36 @@ def detect_local_ips():
37
37
  return results
38
38
 
39
39
 
40
+ class BindFailure(str):
41
+ """Reason string from port_taken(). `bad_host` is True when the HOST is
42
+ the problem (unresolvable, or not an address on this machine —
43
+ EADDRNOTAVAIL) rather than the port being held by another process, so
44
+ callers can skip the "already in use" framing and the holder lookup."""
45
+ bad_host = False
46
+
47
+
48
+ def _bind_failure(reason, bad_host=False):
49
+ out = BindFailure(reason)
50
+ out.bad_host = bad_host
51
+ return out
52
+
53
+
40
54
  def port_taken(host, port):
41
55
  """Reason string when `host:port` can't be bound, '' when it's free.
42
56
 
43
57
  A plain bind test — catches ANY holder, unlike a scan of painapple's
44
58
  own process table. Used by the server's own pre-flight and by
45
59
  `painapple start` so the failure is reported before a detached child
46
- inherits it. Unresolvable host counts as taken (with the reason)."""
60
+ inherits it. Non-empty returns are BindFailure: `bad_host` marks a
61
+ wrong bind address (unresolvable / not local) as opposed to a port
62
+ genuinely held by another process."""
63
+ import errno
47
64
  import socket
48
65
  try:
49
66
  infos = socket.getaddrinfo(host, port, type=socket.SOCK_STREAM)
50
67
  except socket.gaierror as e:
51
- return f"cannot resolve host {host!r} ({e})"
68
+ return _bind_failure(f"cannot resolve host {host!r} ({e})",
69
+ bad_host=True)
52
70
  family, socktype, proto, _canon, sockaddr = infos[0]
53
71
  with socket.socket(family, socktype, proto) as sock:
54
72
  # SO_REUSEADDR means opposite things on the two platforms. On POSIX
@@ -65,7 +83,17 @@ def port_taken(host, port):
65
83
  try:
66
84
  sock.bind(sockaddr)
67
85
  except OSError as e:
68
- return e.strerror or str(e)
86
+ msg = e.strerror or str(e)
87
+ # EADDRNOTAVAIL ("Cannot assign requested address") is not a
88
+ # port conflict — the IP isn't assigned to any interface here.
89
+ # Framing it as "already in use" sent users hunting for a
90
+ # holder that doesn't exist (winsock code on Windows differs).
91
+ if e.errno in (errno.EADDRNOTAVAIL,
92
+ getattr(errno, "WSAEADDRNOTAVAIL", None)):
93
+ return _bind_failure(
94
+ f"{msg} — {host!r} is not an address on this machine",
95
+ bad_host=True)
96
+ return _bind_failure(msg)
69
97
  return ""
70
98
 
71
99
 
@@ -85,6 +85,12 @@ def build_parser():
85
85
  "its own directory. This anchors the file explorer and "
86
86
  "the welcome screen's project suggestions. Mapped to "
87
87
  "/workspace inside Docker. (--cwd is an alias)")
88
+ core.add_argument("--project", dest="project",
89
+ action=argparse.BooleanOptionalAction, default=None,
90
+ help="Treat the workspace as ONE project (the welcome screen "
91
+ "offers it as a single entry) instead of a folder of "
92
+ "projects. Default: auto-detect by a top-level .git; "
93
+ "--no-project disables the auto-detect.")
88
94
  core.add_argument("--instance-name", default=None,
89
95
  help="Instance label for PWA icon and UI (e.g., DEV, STABLE)")
90
96
  core.add_argument("--accent", default=None,
@@ -494,6 +494,30 @@ def _looks_like_project(child: Path) -> bool:
494
494
  return False
495
495
 
496
496
 
497
+ def resolve_workspace_is_project(workspace: str, flag: Optional[bool]) -> tuple[bool, str]:
498
+ """Decide whether the workspace IS one project (vs a wrapper dir of projects).
499
+
500
+ flag: True/False = forced by --project/--no-project, None = auto-detect.
501
+ Auto-detect keys on a top-level ``.git`` ONLY (dir for a normal repo,
502
+ file for a git worktree) — the same zero-config pick the Docker launch
503
+ path uses (cli/deploy/launch.py), deliberately NOT the broader
504
+ ``_looks_like_project`` manifest list: a wrapper dir with a stray
505
+ requirements.txt must not silently flip modes.
506
+
507
+ Returns:
508
+ (is_project, reason) — reason is human-readable for the startup log.
509
+ """
510
+ if flag is True:
511
+ return True, "forced by --project"
512
+ if flag is False:
513
+ return False, "forced by --no-project"
514
+ try:
515
+ has_git = (Path(workspace).expanduser() / ".git").exists()
516
+ except OSError:
517
+ has_git = False
518
+ return (True, "found .git") if has_git else (False, "no .git")
519
+
520
+
497
521
  def list_workspace_dirs(root: str, exclude_paths: Optional[list[str]] = None,
498
522
  limit: int = 100) -> list[dict]:
499
523
  """List immediate sub-directories of a workspace root, excluding ones
@@ -93,18 +93,50 @@ async def get_welcome_projects(request: Request):
93
93
  enriched.sort(key=lambda x: x["name"].lower())
94
94
 
95
95
  workspace_root = getattr(request.app.state, "workspace_root", None)
96
+ is_project = bool(getattr(request.app.state, "workspace_is_project", False))
96
97
  workspace_dirs: list[dict] = []
97
- if workspace_root:
98
+ if workspace_root and is_project:
99
+ # The workspace IS one project — never list its internals
100
+ # (src/, node_modules/, …). Offer the root itself as the single
101
+ # "unvisited" chip until the first session tracks it as a project.
102
+ workspace_dirs = _root_as_workspace_entry(workspace_root, projects)
103
+ elif workspace_root:
98
104
  exclude = [p["path"] for p in projects]
99
105
  workspace_dirs = list_workspace_dirs(workspace_root, exclude_paths=exclude)
100
106
 
101
107
  return {
102
108
  "projects": enriched,
103
109
  "workspace_root": workspace_root,
110
+ "workspace_is_project": is_project,
104
111
  "workspace_dirs": workspace_dirs,
105
112
  }
106
113
 
107
114
 
115
+ def _root_as_workspace_entry(workspace_root: str, projects: list[dict]) -> list[dict]:
116
+ """Project-mode chip list: the workspace root itself, in the same shape
117
+ `list_workspace_dirs` emits — or [] once it's already a tracked project
118
+ (it then appears in `projects` instead)."""
119
+ root = Path(workspace_root)
120
+ tracked = set()
121
+ for p in projects:
122
+ try:
123
+ tracked.add(str(Path(p["path"]).expanduser().resolve()))
124
+ except (OSError, RuntimeError):
125
+ continue
126
+ if str(root) in tracked:
127
+ return []
128
+ try:
129
+ mtime = root.stat().st_mtime
130
+ except OSError:
131
+ return []
132
+ return [{
133
+ "path": str(root),
134
+ "name": root.name,
135
+ "mtime": mtime,
136
+ "looks_like_project": True,
137
+ }]
138
+
139
+
108
140
  @router.get("/api/welcome/projects/sessions")
109
141
  async def get_project_sessions(path: str, limit: int = 15):
110
142
  """Recent sessions for a specific project — drives the quick-switcher drill-in.
@@ -1794,6 +1794,24 @@ def _preflight_port(host: str, port: int) -> None:
1794
1794
  if not reason:
1795
1795
  return
1796
1796
 
1797
+ if getattr(reason, "bad_host", False):
1798
+ # The HOST is wrong (unresolvable / not a local address), not the
1799
+ # port — the "already in use" box below would send the user cycling
1800
+ # through ports that were never the problem.
1801
+ print(f"""
1802
+ ╔══════════════════════════════════════════════════════════════╗
1803
+ ║ pAInapple Code Server — cannot start
1804
+ ╠══════════════════════════════════════════════════════════════╣
1805
+ ║ Cannot bind {host}:{port} — the bind host is wrong.
1806
+ ║ {reason}
1807
+ ║
1808
+ ║ Try: {'painapple --host 0.0.0.0':<27} (listen on all interfaces)
1809
+ ║ {'painapple --host 127.0.0.1':<27} (this machine only)
1810
+ ╚══════════════════════════════════════════════════════════════╝
1811
+ """, file=sys.__stderr__ or sys.stdout)
1812
+ logger.error(f"Cannot bind {host}:{port} — {reason}; not starting")
1813
+ sys.exit(1)
1814
+
1797
1815
  holder = port_holder(port)
1798
1816
  port_flag = f"painapple --port {port + 1}"
1799
1817
  print(f"""
@@ -2039,16 +2057,23 @@ def main(argv=None):
2039
2057
  app.state.agents = agents
2040
2058
  app.state.workspace = args.workspace
2041
2059
 
2042
- # --workspace IS the root: the dir that holds the project subdirs, not
2043
- # one project. Sessions pick their own cwd from the welcome screen and
2044
- # files/git/terminal follow THAT, so this only anchors discovery (the
2045
- # welcome "Unvisited" chips, the file-explorer browse root) and supplies
2046
- # a fallback cwd for sessions created without one. Stored as absolute
2047
- # string (or None) for route modules to read.
2060
+ # --workspace anchors discovery (the welcome "Unvisited" chips, the
2061
+ # file-explorer browse root) and supplies a fallback cwd for sessions
2062
+ # created without one — sessions pick their own cwd from the welcome
2063
+ # screen and files/git/terminal follow THAT. Two modes: a WRAPPER dir
2064
+ # holding project subdirs (welcome lists them), or ONE project
2065
+ # (welcome offers just the workspace itself — never its internals like
2066
+ # src/ or node_modules/). Mode from --project/--no-project, else
2067
+ # auto-detected by a top-level .git (same pick as Docker's launch
2068
+ # path, which sidesteps this via the one-level-down mount). Stored as
2069
+ # absolute string (or None) for route modules to read.
2048
2070
  try:
2049
2071
  app.state.workspace_root = str(Path(args.workspace).expanduser().resolve())
2050
2072
  except (OSError, RuntimeError):
2051
2073
  app.state.workspace_root = None
2074
+ is_project, project_reason = paths.resolve_workspace_is_project(
2075
+ args.workspace, args.project)
2076
+ app.state.workspace_is_project = is_project
2052
2077
 
2053
2078
  # Load config file and populate auth state (fails open if the directory
2054
2079
  # can't be written — intentional: we want a noisy permissions error).
@@ -2116,6 +2141,13 @@ def main(argv=None):
2116
2141
  "Use --tls=auto (default) unless you have a reason."
2117
2142
  )
2118
2143
 
2144
+ # Project-mode annotation on the Workspace banner line; a fuller notice
2145
+ # prints below the box ONLY when the mode was auto-detected (explicit
2146
+ # --project/--no-project users already know what they asked for).
2147
+ workspace_mode = ""
2148
+ if app.state.workspace_is_project:
2149
+ workspace_mode = f" (single project: {project_reason})"
2150
+
2119
2151
  instance_line = ""
2120
2152
  if instance_config.get("name"):
2121
2153
  instance_line = f"\n║ Instance: {instance_config['name']} (accent: {instance_config.get('accent', 'default')})"
@@ -2164,11 +2196,16 @@ def main(argv=None):
2164
2196
  ╠══════════════════════════════════════════════════════════════╣
2165
2197
  ║ WebSocket: {ws_scheme}://{args.host}:{args.port}/chat
2166
2198
  ║ Files API: {scheme}://{args.host}:{args.port}/api/files
2167
- ║ Workspace: {args.workspace}{instance_line}{shadow_db_line}{log_dir_line}{state_suffix_line}
2199
+ ║ Workspace: {args.workspace}{workspace_mode}{instance_line}{shadow_db_line}{log_dir_line}{state_suffix_line}
2168
2200
  ║ Auth File: {app.state.auth_config_file}{tls_line}{auth_lines}
2169
2201
  ╚══════════════════════════════════════════════════════════════╝
2170
2202
  """)
2171
2203
 
2204
+ if args.project is None and app.state.workspace_is_project:
2205
+ print(f"{DIM}Workspace looks like a project (found .git) — the welcome "
2206
+ f"screen shows it as one project, not its subfolders. Pass "
2207
+ f"--no-project to treat it as a folder of projects.{_ANSI_RESET}")
2208
+
2172
2209
  # Trust X-Forwarded-* only from loopback by default (a reverse proxy on
2173
2210
  # the same host). A remote proxy sets FORWARDED_ALLOW_IPS explicitly. The
2174
2211
  # old "*" let ANY direct client spoof X-Forwarded-Proto and flip the
@@ -1031,6 +1031,23 @@
1031
1031
  transition: all 0.15s;
1032
1032
  }
1033
1033
 
1034
+ /* Icon buttons in the panzoom toolbar (e.g. annotate): the inline SVG ships
1035
+ only a viewBox, so without explicit sizing it renders at the 300×150
1036
+ replaced-element default and the icon clips out of the button entirely. */
1037
+ .panzoom-annotate-btn {
1038
+ display: inline-flex;
1039
+ align-items: center;
1040
+ justify-content: center;
1041
+ width: var(--layout-btn-sm);
1042
+ padding: 0;
1043
+ flex-shrink: 0;
1044
+ }
1045
+
1046
+ .panzoom-annotate-btn svg {
1047
+ width: 14px;
1048
+ height: 14px;
1049
+ }
1050
+
1034
1051
  .panzoom-ctrl-btn:hover, .panzoom-ctrl-btn:active {
1035
1052
  background: var(--surface-hover, #30363d);
1036
1053
  color: var(--text-primary, #e6edf3);
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: painapple-code
3
- Version: 1.0.2
3
+ Version: 1.0.3
4
4
  Summary: Self-hosted remote UI for Claude Code that journals every turn - background AI summaries become shadow-git commits and a queryable DuckDB history
5
5
  Author-email: Michał Booth-Wrotkowski <michal@boothw.com>
6
6
  License-Expression: AGPL-3.0-or-later
@@ -634,12 +634,14 @@
634
634
  "tests/test_text_io_encoding.py",
635
635
  "tests/test_tls_optional.py",
636
636
  "tests/test_turn_model_attribution.py",
637
+ "tests/test_workspace_project_mode.py",
637
638
  "tests/web/account_credentials_test.json",
638
639
  "tests/web/journal_defaults_test.json",
639
640
  "tests/web/journal_naming_test.json",
640
641
  "tests/web/provider_prompt_argv_note_test.json",
641
642
  "tests/web/status_bar_journal_test.json",
642
643
  "tests/web/sw_never_caches_project_content_test.json",
644
+ "tests/web/welcome_project_mode_test.json",
643
645
  "tools/bundle-feature-source.sh",
644
646
  "tools/bundler/build-app.mjs",
645
647
  "tools/bundler/package-lock.json",
@@ -1,7 +1,7 @@
1
1
  {
2
- "tag": "1.0.2",
2
+ "tag": "1.0.3",
3
3
  "distance": 0,
4
- "node": "ge157c77",
4
+ "node": "g1be1164",
5
5
  "dirty": false,
6
6
  "branch": "HEAD",
7
7
  "node_date": "2026-08-31"
File without changes
File without changes
File without changes
File without changes