painapple-code 1.0.1__tar.gz → 1.0.2__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.
- painapple_code-1.0.2/CHANGELOG.md +17 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/PKG-INFO +10 -8
- {painapple_code-1.0.1 → painapple_code-1.0.2}/README.dockerhub.md +4 -4
- {painapple_code-1.0.1 → painapple_code-1.0.2}/README.md +9 -7
- {painapple_code-1.0.1 → painapple_code-1.0.2}/SECURITY.md +11 -11
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/features.md +3 -3
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/getting-started/install-docker.md +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/getting-started/requirements.md +3 -3
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/getting-started/security.md +13 -11
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/customization.md +6 -6
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/ipad-and-mobile.md +3 -2
- painapple_code-1.0.2/docs-site/guides/permissions-and-thinking.md +76 -0
- painapple_code-1.0.2/docs-site/guides/providers.md +58 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/sessions.md +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/shadow-git.md +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/index.md +3 -3
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/reference/api.md +7 -7
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/reference/commands.md +3 -3
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/reference/data-storage.md +5 -5
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/reference/server-cli.md +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/mkdocs.yml +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/_version.py +3 -3
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/data/models.yaml +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/data/strings.yaml +59 -59
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/paths.py +24 -24
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/__init__.py +6 -6
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/base.py +45 -45
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude/__init__.py +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude/capabilities.py +4 -4
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude_sdk/__init__.py +3 -3
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude_sdk/driver.py +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex/__init__.py +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex/capabilities.py +5 -5
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex/errors.py +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_app_config.py +84 -84
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_project_config.py +26 -8
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_providers.py +9 -9
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_session_welcome.py +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_sessions.py +34 -34
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/dependencies.py +15 -15
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/ws_chat.py +13 -13
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/server.py +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/services/agent_session.py +19 -19
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/02-tooltips.css +10 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/26-session-setup.css +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/40-input.css +16 -16
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/41-autocomplete.css +19 -4
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/56-permission-card.css +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/70-config-panel.css +46 -46
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/dist/app.bundle.js +264 -264
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/init-ui.js +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/server-loading.js +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/session-ops.js +6 -6
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app.js +7 -7
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/components.js +3 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/controllers/chat-controller.js +13 -11
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/effort-settings.js +15 -15
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/permission-settings.js +19 -19
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-actions-registry.js +6 -6
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/handle-agent-message.js +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/handle-message.js +17 -15
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/interactive.js +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/persistence.js +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session-setup-panel.js +45 -45
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session.js +11 -11
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/status-bar.js +153 -153
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/token-profile.js +5 -5
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/tooltips.js +4 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/models-tab.js +228 -228
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/system-controls.js +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config-widget.js +13 -13
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/discussion-widget.js +3 -3
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/log-explorer-widget.js +4 -4
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/zen-widget.js +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/web-client.html +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/token_profiles.py +4 -4
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/PKG-INFO +10 -8
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/SOURCES.txt +1 -1
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/scm_file_list.json +2 -2
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/scm_version.json +2 -2
- painapple_code-1.0.1/CHANGELOG.md +0 -7
- painapple_code-1.0.1/docs-site/guides/engines.md +0 -58
- painapple_code-1.0.1/docs-site/guides/permissions-and-thinking.md +0 -70
- {painapple_code-1.0.1 → painapple_code-1.0.2}/.devcontainer/devcontainer.json +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/.dockerignore +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/.gitignore +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/CONTRIBUTING.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/Dockerfile +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/LICENSE +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/MANIFEST.in +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/THIRD_PARTY_NOTICES.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/build-frontend.sh +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docker-compose.yml +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docker-entrypoint.sh +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/annotate-editor.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/browser-widget.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/comments-stash.gif +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/cost-analytics.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/favicon.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/input-autocomplete.gif +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/logo.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/markdown-quick-edit.gif +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/overview.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/prompt-history.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/quick-switcher.gif +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/quick-switcher.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/settings-appearance.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/settings-claude.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/shadow-journal.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/snippets-picker.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/terminal.gif +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/turn-summary-bar-expanded.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/turn-summary-bar.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/welcome-screen.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/assets/zen-mode.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/getting-started/first-run.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/getting-started/install-devcontainer.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/getting-started/install-pip.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/analytics-and-history.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/claude-artifacts.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/files.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/git-and-diffs.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/images-and-annotation.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/input-and-commands.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/stash-and-discussions.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/terminal.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/welcome-screen.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/guides/zen-mode.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/reference/keyboard-shortcuts.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/reference/optional-helpers.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/docs-site/reference/profiles.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/painapple-docker.sh +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/pyproject.toml +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/requirements-docs.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/requirements.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/setup.cfg +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/setup.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/__init__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/__main__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/auth_middleware.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/__init__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/deploy/__init__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/deploy/claude_seed.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/deploy/config.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/deploy/container.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/deploy/launch.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/deploy/runtime.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/lifecycle_cmd.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/list_cmd.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/manage_cmd.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/netinfo.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/profiles.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/serve_args.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/serve_config.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/setup_cmd.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cli/ui.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/cost_analytics.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/data/models.defaults.yaml +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/data/presets.defaults.json +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/helpers.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/prompt_explorer.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude/errors.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude/launch.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude/summary.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/claude/translate.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex/translate.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex_app_server/__init__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex_app_server/capabilities.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex_app_server/launch.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex_app_server/summary.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex_app_server/translate.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/providers/codex_app_server/transport.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/__init__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_agents.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_app.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_app_commit_sections.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_app_session_prefs.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_browser.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_commands.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_costs.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_drafts.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_exec.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_files.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_git.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_logs.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_plugins.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_prompts.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_search.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_session_stash.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_shadow.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_shadow_db.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_shadow_files.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_shadow_search.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_skills.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_tasks.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_terminal.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_upload.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/routes/api_viewer.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/server_logging.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/services/__init__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/session_store.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/session_store_core.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_db.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_db_plans.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_db_queries.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_db_schema.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_git.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_git_frontmatter.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_git_sections.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_git_summary.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/shadow_parser.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/00-variables.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/01-base.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/09-left-rail.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/10-header.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/11-connection-bar.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/20-messages.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/21-tool-blocks.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/22-edit-diff.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/23-thinking.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/24-background-tasks.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/25-context-block.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/30-markdown.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/42-activity-strip.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/43-file-autocomplete.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/44-snippets-autocomplete.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/45-selection-bar.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/46-keyboard-bar.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/47-keyboard-longpress.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/47-token-profile.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/50-welcome.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/51-modals.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/52-utilities.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/53-image-upload.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/54-todo-list.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/55-file-upload.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/56-chat-navigator.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/56-plan-approval.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/56-question-form.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/57-swipe-indicator.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/58-session-families.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/59-about.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/61-log-explorer.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/62-json-tree.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/62-skills-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/63-commands-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/63-plugins-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/63-terminal.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/64-search-files-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/65-snippets-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/66-active-sessions.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/66-agents-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/66-file-explorer-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/66-git-panel.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/66-history-explorer.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/67-diff-viewer.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/67-editor-view.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/67-file-preview-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-browser-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-compare-wizard.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-csv-preview.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-diff-preview.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-helpers-install-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-image-annotate.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-terminal-view.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/68-uploads-widget.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/69-cost-analytics.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/70-excalidraw.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/70-prompt-explorer.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/71-chart.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/72-discussion-sidebar.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/74-debug-logs.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/80-open-dialog.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/80-quick-switcher.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/80-widget-system.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/81-quick-actions.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/82-context-popover.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/83-context-menu.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/85-lazy-loading.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/86-zen-mode.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/87-grid-switcher.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/css/login.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/feature-triage.html +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/apple-touch-icon.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/favicon-32.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/favicon.ico +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-128.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-144.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-152.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-180.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-192.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-384.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-512.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-72.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/icons/icon-96.png +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/action-delegate.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/activity-strip.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/context-menus.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/file-preview.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/input-events.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/input-resize.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/message-actions.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/panels.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/rendering-delegators.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/session-switch.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/settings-helpers.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app/startup-welcome.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/app-context.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/auth-fetch.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/background-tasks.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/boot.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/caret-position.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/chat-navigator.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/chat-search.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/command-executor.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/command-store.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/config.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/context-menu.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/controllers/dialog-controller.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/controllers/tab-controller.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/controllers/thinking-controller.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/diff-utils.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/drafts-pill.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/editor-view.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/feature-triage.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/file-autocomplete.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/file-tabs.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/gestures.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/grid-switcher.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/input-handler.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/keyboard-bar.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/layout-switcher.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/linkify-utils.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/login.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/open-dialog.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/orphan-terminals.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/path-utils.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/perf-marks.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/pointer-input.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/json-tree-menu.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/json-tree-toolbar.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/json-tree.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-breadcrumb.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-edit.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-events.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-history.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-inline-edit.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-poll.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-render.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-search.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-state.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview/preview-utils.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/chart-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/csv-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/diff-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/excalidraw-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/html-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/image-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/index.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/json-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/jsonl-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/markdown-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/panzoom-plugin.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/preview-plugins/plugin-helpers.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/project-color-picker.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/project-colors.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/prompt-favorites.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-actions-menu.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/controller.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/fuzzy-scorer.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/index.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/providers/base-provider.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/providers/command-provider.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/providers/file-provider.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/providers/panel-provider.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/providers/project-provider.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/providers/read-files-provider.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/providers/skills-provider.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/registry.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/ui/item.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/quick-switcher/ui/picker.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/recent-opens.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/scroll-manager.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/scroll-state-machine.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/selection/action-bar.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/selection/index.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/selection/selection-handler.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/selection/state.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/agent-progress.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/message-store.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/messages.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/restore.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session/sync.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/session-container-pool.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/shortcut-hints.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/shortcuts.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/skills-autocomplete.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/snippets-autocomplete.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/stash-refs-view.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/stash-ui.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/stash.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/tool-renderer-blocks.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/tool-renderer-thinking.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/tool-renderer.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/upload-manager.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/utils.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/welcome/api.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/welcome/cards.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/welcome/context-menu.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/welcome/families.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/welcome/preview.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/welcome/state.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/welcome.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/base-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/device-manager.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/event-bus.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/icons.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/index.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/init.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/types/bottom-sheet.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/types/floating.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/types/index.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/types/modal.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/types/sidebar.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/types/tab.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/types/top-sheet.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widget-system/widget-manager.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/about-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/active-sessions-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/agents-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/browser-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/commands-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/commit-sections.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/dir-autocomplete.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/gestures.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/quick-actions-tab.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/shortcut-editor.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/config/state.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/cost-analytics-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/debug-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/diff-viewer-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/file-explorer-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/file-preview-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/git-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/helpers-install-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/history-explorer-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/image-annotate-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/image-preview-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/index.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/plugins-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/prompt-explorer-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/search-files-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/skills-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/snippets-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/sub-agents-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/tasks-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/connection.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/gestures.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/init.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/link-providers.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/osc52.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/render.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/size.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/state.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal/wrap-utils.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/terminal-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/js/widgets/uploads-widget.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/login.html +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/manifest.json +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/sw.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/LICENSES.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/README.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/codemirror.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/codemirror.js.LEGAL.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/github-markdown-dark.min.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/highlight-github-dark.min.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/highlight-lang-dockerfile.min.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/highlight-lang-nginx.min.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/highlight-lang-properties.min.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/highlight-lang-scala.min.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/highlight.min.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/marked.min.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/purify.min.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/xterm-addon-fit.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/xterm.css +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/static/vendor/xterm.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/subprocess_registry.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/tls_cert.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/tools/agents/shadow-git-helper.md +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/tools/excalidraw-to-svg.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/tools/install-helpers.sh +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/tools/shadow-git +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/tools/shadow-query +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/tools/vegalite-to-svg.js +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/turn_query.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/turn_tracker.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/__init__.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/agent_cli.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/chart.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/excalidraw.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/file_lock.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/file_paths.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/generate_icons.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/proc.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/pty_backend.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/pty_posix.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/utils/pty_windows.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/viewer_templates.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code/welcome_search.py +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/dependency_links.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/entry_points.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/requires.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/src/painapple_code.egg-info/top_level.txt +0 -0
- {painapple_code-1.0.1 → painapple_code-1.0.2}/start.sh +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Notable changes are documented here per release. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow [SemVer](https://semver.org/), and the git tag is the single source of truth for the version (the PyPI wheel, the Docker image tag, and `__version__` all derive from it).
|
|
4
|
+
|
|
5
|
+
## 1.0.1 — 2026-08-31
|
|
6
|
+
|
|
7
|
+
### Removed
|
|
8
|
+
|
|
9
|
+
- The two "plain CLI" fallback drivers: the `claude` line-protocol driver (superseded by the wire-identical `claude-sdk` provider) and the `codex` exec driver (`codex exec --json` had no stdin protocol — every prompt rode argv, readable via `ps` by any local account; see SECURITY.md). Saved configs keep working: the legacy provider names alias to `claude-sdk` and `codex-app-server`, and old Codex exec sessions resume natively through the same `$CODEX_HOME` thread store.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Docs: TLS opt-in now points at the `[tls]` extra instead of a hardcoded dependency pin.
|
|
14
|
+
|
|
15
|
+
## 1.0.0 — 2026-08-26
|
|
16
|
+
|
|
17
|
+
First public release.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: painapple-code
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.2
|
|
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
|
|
@@ -53,7 +53,7 @@ Dynamic: license-file
|
|
|
53
53
|
|
|
54
54
|
# pAInapple Code
|
|
55
55
|
|
|
56
|
-
A self-hosted web client for [Claude Code](https://github.com/anthropics/claude-code), installable as a PWA. The server **runs on your own machine** and drives Claude Code through the **official Agent SDK**, using **your own Claude subscription**. [OpenAI Codex CLI](https://painapple.ai/guides/
|
|
56
|
+
A self-hosted web client for [Claude Code](https://github.com/anthropics/claude-code), installable as a PWA. The server **runs on your own machine** and drives Claude Code through the **official Agent SDK**, using **your own Claude subscription**. [OpenAI Codex CLI](https://painapple.ai/guides/providers/) support is experimental.
|
|
57
57
|
Inspired by [code-server](https://github.com/coder/code-server).
|
|
58
58
|
|
|
59
59
|
[**Auto Journal**](#auto-journal-shadow-git): after every turn, a background fork to a fast model (Haiku by default) summarizes it into a local DuckDB and a shadow-git commit — so the **full history of any topic or file stays searchable**, by you *and* by future Claude sessions.
|
|
@@ -66,7 +66,7 @@ Right now it's a PWA, but **desktop and mobile apps are in development**.
|
|
|
66
66
|
|
|
67
67
|
## What it is, and what it isn't
|
|
68
68
|
|
|
69
|
-
**It is** a thin wrapper around Claude Code — every prompt streams through the official CLI/Agent SDK, and any session started here can be resumed in the plain CLI with `claude --resume <id>`. **It never modifies Claude's system prompt, tool policy, or behavior** — no injected planning steps, no hidden instructions. What it does add to a prompt is the context you attached: the output of `!bang` commands you ran, paths of files you uploaded, and snippets from the comments stash are prepended as plain text. The same wrapper can drive the [OpenAI Codex CLI](https://painapple.ai/guides/
|
|
69
|
+
**It is** a thin wrapper around Claude Code — every prompt streams through the official CLI/Agent SDK, and any session started here can be resumed in the plain CLI with `claude --resume <id>`. **It never modifies Claude's system prompt, tool policy, or behavior** — no injected planning steps, no hidden instructions. What it does add to a prompt is the context you attached: the output of `!bang` commands you ran, paths of files you uploaded, and snippets from the comments stash are prepended as plain text. The same wrapper can drive the [OpenAI Codex CLI](https://painapple.ai/guides/providers/), selected per session, resumable with `codex exec resume <id>` — the Codex path is **newer and has had less testing** than the Claude path.
|
|
70
70
|
|
|
71
71
|
**It is not** a hosted service. You run it, on your hardware, with your own Claude account.
|
|
72
72
|
|
|
@@ -141,7 +141,7 @@ Search **every prompt you've ever sent**, across all sessions and projects, with
|
|
|
141
141
|
- **Server:** Linux, macOS, or Windows 11 (Windows 10 is untested, but will probably work)
|
|
142
142
|
- **Direct install:** Python 3.12+ and the [Claude Code CLI](https://github.com/anthropics/claude-code), installed and authenticated. (The Docker image ships Python and Node, and installs the agent CLIs itself on first start.)
|
|
143
143
|
- **Git** on `PATH` — the auto-journal records every turn as a shadow-git commit, and the Git panel shells out to it. **Without git the server still runs, but journals nothing.** (Windows: [Git for Windows](https://git-scm.com/download/win).)
|
|
144
|
-
- **Optional:** Docker or Podman for the sandboxed `--in-docker` mode and named container instances; the [OpenAI Codex CLI](https://github.com/openai/codex) for the Codex
|
|
144
|
+
- **Optional:** Docker or Podman for the sandboxed `--in-docker` mode and named container instances; the [OpenAI Codex CLI](https://github.com/openai/codex) for the Codex provider.
|
|
145
145
|
- **Client:** any modern browser with network access to the server.
|
|
146
146
|
|
|
147
147
|
## Quick start
|
|
@@ -199,7 +199,9 @@ Git for Windows is worth installing even if you use another git: the optional [h
|
|
|
199
199
|
|
|
200
200
|
### Then what?
|
|
201
201
|
|
|
202
|
-
The console prints the **app URL with a login token embedded** — open it in
|
|
202
|
+
The console prints the **app URL with a login token embedded** — open it in a browser on that machine, pick a project on the welcome screen, and you're in. It's a full PWA, so you can install it as a standalone app: **macOS Safari** → File → *Add to Dock*, **Chrome / Edge** (Windows, Linux, macOS) → the install icon in the address bar.
|
|
203
|
+
|
|
204
|
+
By default the server binds to `127.0.0.1`, so that URL only works on the machine it runs on. **Reaching it from a phone or tablet is optional and takes a bit more setup**: bind wider with `--host 0.0.0.0` (non-loopback binds auto-enable TLS with a self-signed certificate — you'll accept a one-time browser warning), or put a reverse proxy with a real domain and certificate in front, which is what iOS/iPadOS wants before it will install the PWA properly. Read the [security notes](https://painapple.ai/getting-started/security/) before exposing it beyond your own machine, and the [iPad & mobile guide](https://painapple.ai/guides/ipad-and-mobile/) for the full walkthrough.
|
|
203
205
|
|
|
204
206
|
In container mode the image is pulled automatically on the first run (`painapple pull` re-fetches it to update or pin a release); state persists in named volumes and your projects are bind-mounted. Running it inside a single project works too, and `--workspace /path` serves any folder without `cd`-ing there.
|
|
205
207
|
|
|
@@ -210,7 +212,7 @@ In container mode the image is pulled automatically on the first run (`painapple
|
|
|
210
212
|
- **GitHub Codespaces / Dev Containers** — one line in `devcontainer.json` boots every Codespace with pAInapple Code installed, started, and port-forwarded → [Dev Container Feature](https://painapple.ai/getting-started/install-devcontainer/)
|
|
211
213
|
- **From source** — `git clone`, `venv/bin/pip install -e .`, run with `venv/bin/painapple` → [source install](https://painapple.ai/getting-started/install-pip/#from-a-source-checkout)
|
|
212
214
|
|
|
213
|
-
**Full documentation** — configuration,
|
|
215
|
+
**Full documentation** — configuration, providers, every feature, and the CLI/API reference — lives at **[painapple.ai](https://painapple.ai/)**.
|
|
214
216
|
|
|
215
217
|
## Authentication
|
|
216
218
|
|
|
@@ -239,7 +241,7 @@ The most common flags:
|
|
|
239
241
|
| `--workspace` | `.` | Workspace root — the directory holding your projects. You pick the project in-app from the welcome screen (`--cwd` is an alias) |
|
|
240
242
|
| `--instance-name`, `--accent` | — | Label + accent color to distinguish multiple instances |
|
|
241
243
|
| `--tls` | `auto` | Self-signed TLS, auto-enabled on non-loopback binds |
|
|
242
|
-
| `--default-provider` | `claude-sdk` | Default [AI
|
|
244
|
+
| `--default-provider` | `claude-sdk` | Default [AI provider](https://painapple.ai/guides/providers/) for new sessions — Claude Code (Agent SDK) or OpenAI Codex |
|
|
243
245
|
| `--profile` | — | Run a named profile — several independent deployments (host or docker mode) under one user |
|
|
244
246
|
| `--in-docker` | off | Run the same invocation in a container instead (prebuilt image, cwd mounted) |
|
|
245
247
|
|
|
@@ -283,7 +285,7 @@ This is an MVP — there are tradeoffs.
|
|
|
283
285
|
2. **Windowing system** — works, but doesn't support multiple instances of the same widget and could use a rethink.
|
|
284
286
|
3. **Code editor** — currently a notepad with syntax highlighting. The plan is a review-driven workflow rather than a VSCode-grade editor; the markdown inline editor is the exception and works well for plan/doc tweaks.
|
|
285
287
|
4. **GUI for OS-level features** (git widget, file explorer) — exists, but I prefer the embedded terminal for `grep`/`sed`/`find`/`du`, so these widgets have not been a priority.
|
|
286
|
-
5. **Codex
|
|
288
|
+
5. **Codex provider** — functional, but much newer than the Claude path and not yet as thoroughly tested.
|
|
287
289
|
|
|
288
290
|
## License
|
|
289
291
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pAInapple Code
|
|
2
2
|
|
|
3
|
-
A self-hosted web UI for [Claude Code](https://github.com/anthropics/claude-code) sessions — a Python server that runs the CLI as a subprocess and serves a vanilla-JS PWA on top. Inspired by [code-server](https://github.com/coder/code-server). It can also drive the [OpenAI Codex CLI](https://painapple.ai/guides/
|
|
3
|
+
A self-hosted web UI for [Claude Code](https://github.com/anthropics/claude-code) sessions — a Python server that runs the CLI as a subprocess and serves a vanilla-JS PWA on top. Inspired by [code-server](https://github.com/coder/code-server). It can also drive the [OpenAI Codex CLI](https://painapple.ai/guides/providers/) as a second provider (experimental).
|
|
4
4
|
|
|
5
5
|
Thanks to the [**Auto Journal**](https://painapple.ai/guides/shadow-git/), you can easily pull up the full history of any topic or file you've already worked on. After each turn finishes, the session is forked in the background to a fast model (Haiku by default) that summarizes the turn — and the summary is stored in a local DuckDB and in the project's shadow git, as the commit message over everything that changed during the turn. It's not just for you: the optional `shadow-git-helper` agent gives Claude the same access, digging through past turns to brief the session with full historical context.
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ The image ships Python 3.13 and Node 20; the agent CLIs (`@anthropic-ai/claude-c
|
|
|
14
14
|
|
|
15
15
|
**pAInapple Code effectively gives whoever holds its password a remote shell on the host.** Claude Code can execute commands, edit files, and reach the network on the user that started the container. The built-in auth is a single-password gate — useful, but not a substitute for proper network controls.
|
|
16
16
|
|
|
17
|
-
- The default `docker run` example below binds **`127.0.0.1:8765`**. Don't change that to `0.0.0.0` (or a public IP) without putting a reverse proxy with TLS and ideally a VPN
|
|
17
|
+
- The default `docker run` example below binds **`127.0.0.1:8765`**. Don't change that to `0.0.0.0` (or a public IP) without putting a reverse proxy with TLS and ideally a VPN or SSH-tunnel layer in front.
|
|
18
18
|
- The auth password is generated on first start but **not printed to the container's logs** (inside the container the bind is non-loopback, so credentials are hidden from stdout by default — `docker logs` persists). Reveal the login URL with `painapple password` (pip CLI), or read it directly: `docker exec painapple-code awk '/^password:/ {print $2}' /home/app/.config/painapple-code/config.yaml`. Open it once — the cookie keeps you logged in afterwards.
|
|
19
19
|
- The terminal widget is a real PTY running as the container user. In `YOLO` permission mode anyone with the password can run arbitrary commands.
|
|
20
20
|
|
|
@@ -159,7 +159,7 @@ docker buildx imagetools inspect wrotek/painapple-code:latest
|
|
|
159
159
|
|
|
160
160
|
## What it is, and what it isn't
|
|
161
161
|
|
|
162
|
-
**It is** a thin wrapper around Claude Code — every prompt streams through the official CLI/Agent SDK, and any session started here can be resumed in the plain CLI with `claude --resume <id>`. **It never modifies Claude's system prompt, tool policy, or behavior** — no injected planning steps, no hidden instructions. What it does add to a prompt is the context you attached: the output of `!bang` commands you ran, paths of files you uploaded, and snippets from the comments stash are prepended as plain text. The same wrapper can drive the [OpenAI Codex CLI](https://painapple.ai/guides/
|
|
162
|
+
**It is** a thin wrapper around Claude Code — every prompt streams through the official CLI/Agent SDK, and any session started here can be resumed in the plain CLI with `claude --resume <id>`. **It never modifies Claude's system prompt, tool policy, or behavior** — no injected planning steps, no hidden instructions. What it does add to a prompt is the context you attached: the output of `!bang` commands you ran, paths of files you uploaded, and snippets from the comments stash are prepended as plain text. The same wrapper can drive the [OpenAI Codex CLI](https://painapple.ai/guides/providers/), selected per session, resumable with `codex exec resume <id>` — the Codex path is **newer and has had less testing** than the Claude path.
|
|
163
163
|
|
|
164
164
|
**It is not** a hosted service. You run it, on your hardware, with your own Claude account.
|
|
165
165
|
|
|
@@ -172,7 +172,7 @@ Full list on [GitHub](https://github.com/wrotek/painapple-code):
|
|
|
172
172
|
- **Shadow Git auto-journal** — after each turn the session forks itself to a fast summarizer model (Haiku by default); its structured write-up becomes the commit message for a per-project shadow git repo holding that turn's file changes, and a queryable DuckDB row.
|
|
173
173
|
- **Multi-session tabs**, real PTY terminal, cost analytics, prompt history search, comments stash, discussion threads.
|
|
174
174
|
- **PWA** — installable on iPad / Android / desktop, offline fallback.
|
|
175
|
-
- **Permission modes** per session: `Ask` (the default — every edit/command waits on
|
|
175
|
+
- **Permission modes** — Claude Code's own modes, picked per session instead of at startup, with its approval prompts rendered as in-chat cards: `Ask` (the default — every edit/command waits on a card), `Plan` (read-only), `Accept-Edits`, `Don't Ask`, `Auto` (Claude's AI classifier), `YOLO`.
|
|
176
176
|
|
|
177
177
|
## Source & support
|
|
178
178
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pAInapple Code
|
|
2
2
|
|
|
3
|
-
A self-hosted web client for [Claude Code](https://github.com/anthropics/claude-code), installable as a PWA. The server **runs on your own machine** and drives Claude Code through the **official Agent SDK**, using **your own Claude subscription**. [OpenAI Codex CLI](https://painapple.ai/guides/
|
|
3
|
+
A self-hosted web client for [Claude Code](https://github.com/anthropics/claude-code), installable as a PWA. The server **runs on your own machine** and drives Claude Code through the **official Agent SDK**, using **your own Claude subscription**. [OpenAI Codex CLI](https://painapple.ai/guides/providers/) support is experimental.
|
|
4
4
|
Inspired by [code-server](https://github.com/coder/code-server).
|
|
5
5
|
|
|
6
6
|
[**Auto Journal**](#auto-journal-shadow-git): after every turn, a background fork to a fast model (Haiku by default) summarizes it into a local DuckDB and a shadow-git commit — so the **full history of any topic or file stays searchable**, by you *and* by future Claude sessions.
|
|
@@ -13,7 +13,7 @@ Right now it's a PWA, but **desktop and mobile apps are in development**.
|
|
|
13
13
|
|
|
14
14
|
## What it is, and what it isn't
|
|
15
15
|
|
|
16
|
-
**It is** a thin wrapper around Claude Code — every prompt streams through the official CLI/Agent SDK, and any session started here can be resumed in the plain CLI with `claude --resume <id>`. **It never modifies Claude's system prompt, tool policy, or behavior** — no injected planning steps, no hidden instructions. What it does add to a prompt is the context you attached: the output of `!bang` commands you ran, paths of files you uploaded, and snippets from the comments stash are prepended as plain text. The same wrapper can drive the [OpenAI Codex CLI](https://painapple.ai/guides/
|
|
16
|
+
**It is** a thin wrapper around Claude Code — every prompt streams through the official CLI/Agent SDK, and any session started here can be resumed in the plain CLI with `claude --resume <id>`. **It never modifies Claude's system prompt, tool policy, or behavior** — no injected planning steps, no hidden instructions. What it does add to a prompt is the context you attached: the output of `!bang` commands you ran, paths of files you uploaded, and snippets from the comments stash are prepended as plain text. The same wrapper can drive the [OpenAI Codex CLI](https://painapple.ai/guides/providers/), selected per session, resumable with `codex exec resume <id>` — the Codex path is **newer and has had less testing** than the Claude path.
|
|
17
17
|
|
|
18
18
|
**It is not** a hosted service. You run it, on your hardware, with your own Claude account.
|
|
19
19
|
|
|
@@ -88,7 +88,7 @@ Search **every prompt you've ever sent**, across all sessions and projects, with
|
|
|
88
88
|
- **Server:** Linux, macOS, or Windows 11 (Windows 10 is untested, but will probably work)
|
|
89
89
|
- **Direct install:** Python 3.12+ and the [Claude Code CLI](https://github.com/anthropics/claude-code), installed and authenticated. (The Docker image ships Python and Node, and installs the agent CLIs itself on first start.)
|
|
90
90
|
- **Git** on `PATH` — the auto-journal records every turn as a shadow-git commit, and the Git panel shells out to it. **Without git the server still runs, but journals nothing.** (Windows: [Git for Windows](https://git-scm.com/download/win).)
|
|
91
|
-
- **Optional:** Docker or Podman for the sandboxed `--in-docker` mode and named container instances; the [OpenAI Codex CLI](https://github.com/openai/codex) for the Codex
|
|
91
|
+
- **Optional:** Docker or Podman for the sandboxed `--in-docker` mode and named container instances; the [OpenAI Codex CLI](https://github.com/openai/codex) for the Codex provider.
|
|
92
92
|
- **Client:** any modern browser with network access to the server.
|
|
93
93
|
|
|
94
94
|
## Quick start
|
|
@@ -146,7 +146,9 @@ Git for Windows is worth installing even if you use another git: the optional [h
|
|
|
146
146
|
|
|
147
147
|
### Then what?
|
|
148
148
|
|
|
149
|
-
The console prints the **app URL with a login token embedded** — open it in
|
|
149
|
+
The console prints the **app URL with a login token embedded** — open it in a browser on that machine, pick a project on the welcome screen, and you're in. It's a full PWA, so you can install it as a standalone app: **macOS Safari** → File → *Add to Dock*, **Chrome / Edge** (Windows, Linux, macOS) → the install icon in the address bar.
|
|
150
|
+
|
|
151
|
+
By default the server binds to `127.0.0.1`, so that URL only works on the machine it runs on. **Reaching it from a phone or tablet is optional and takes a bit more setup**: bind wider with `--host 0.0.0.0` (non-loopback binds auto-enable TLS with a self-signed certificate — you'll accept a one-time browser warning), or put a reverse proxy with a real domain and certificate in front, which is what iOS/iPadOS wants before it will install the PWA properly. Read the [security notes](https://painapple.ai/getting-started/security/) before exposing it beyond your own machine, and the [iPad & mobile guide](https://painapple.ai/guides/ipad-and-mobile/) for the full walkthrough.
|
|
150
152
|
|
|
151
153
|
In container mode the image is pulled automatically on the first run (`painapple pull` re-fetches it to update or pin a release); state persists in named volumes and your projects are bind-mounted. Running it inside a single project works too, and `--workspace /path` serves any folder without `cd`-ing there.
|
|
152
154
|
|
|
@@ -157,7 +159,7 @@ In container mode the image is pulled automatically on the first run (`painapple
|
|
|
157
159
|
- **GitHub Codespaces / Dev Containers** — one line in `devcontainer.json` boots every Codespace with pAInapple Code installed, started, and port-forwarded → [Dev Container Feature](https://painapple.ai/getting-started/install-devcontainer/)
|
|
158
160
|
- **From source** — `git clone`, `venv/bin/pip install -e .`, run with `venv/bin/painapple` → [source install](https://painapple.ai/getting-started/install-pip/#from-a-source-checkout)
|
|
159
161
|
|
|
160
|
-
**Full documentation** — configuration,
|
|
162
|
+
**Full documentation** — configuration, providers, every feature, and the CLI/API reference — lives at **[painapple.ai](https://painapple.ai/)**.
|
|
161
163
|
|
|
162
164
|
## Authentication
|
|
163
165
|
|
|
@@ -186,7 +188,7 @@ The most common flags:
|
|
|
186
188
|
| `--workspace` | `.` | Workspace root — the directory holding your projects. You pick the project in-app from the welcome screen (`--cwd` is an alias) |
|
|
187
189
|
| `--instance-name`, `--accent` | — | Label + accent color to distinguish multiple instances |
|
|
188
190
|
| `--tls` | `auto` | Self-signed TLS, auto-enabled on non-loopback binds |
|
|
189
|
-
| `--default-provider` | `claude-sdk` | Default [AI
|
|
191
|
+
| `--default-provider` | `claude-sdk` | Default [AI provider](https://painapple.ai/guides/providers/) for new sessions — Claude Code (Agent SDK) or OpenAI Codex |
|
|
190
192
|
| `--profile` | — | Run a named profile — several independent deployments (host or docker mode) under one user |
|
|
191
193
|
| `--in-docker` | off | Run the same invocation in a container instead (prebuilt image, cwd mounted) |
|
|
192
194
|
|
|
@@ -230,7 +232,7 @@ This is an MVP — there are tradeoffs.
|
|
|
230
232
|
2. **Windowing system** — works, but doesn't support multiple instances of the same widget and could use a rethink.
|
|
231
233
|
3. **Code editor** — currently a notepad with syntax highlighting. The plan is a review-driven workflow rather than a VSCode-grade editor; the markdown inline editor is the exception and works well for plan/doc tweaks.
|
|
232
234
|
4. **GUI for OS-level features** (git widget, file explorer) — exists, but I prefer the embedded terminal for `grep`/`sed`/`find`/`du`, so these widgets have not been a priority.
|
|
233
|
-
5. **Codex
|
|
235
|
+
5. **Codex provider** — functional, but much newer than the Claude path and not yet as thoroughly tested.
|
|
234
236
|
|
|
235
237
|
## License
|
|
236
238
|
|
|
@@ -77,7 +77,7 @@ Auto-journal, or the status-bar pill).
|
|
|
77
77
|
|
|
78
78
|
Accepted by design: it is a core feature of the tool, matching how editor
|
|
79
79
|
local-history features behave. Everything stays on your machine — except the
|
|
80
|
-
optional summaries, which are generated by the same agent
|
|
80
|
+
optional summaries, which are generated by the same agent provider the session
|
|
81
81
|
already uses. Turn off *Rich Commits* to keep the journal local-only.
|
|
82
82
|
|
|
83
83
|
### Subprocess tracking is incomplete
|
|
@@ -92,26 +92,26 @@ Impact is a resource leak on a machine the user already controls.
|
|
|
92
92
|
than its own OS user. (This entry is about *tracking* only — for what a
|
|
93
93
|
child process exposes while it runs, see the next item.)
|
|
94
94
|
|
|
95
|
-
### Prompts never reach `ps` (the `codex` exec
|
|
95
|
+
### Prompts never reach `ps` (the `codex` exec provider was removed)
|
|
96
96
|
|
|
97
|
-
Historical: the `codex` exec
|
|
97
|
+
Historical: the `codex` exec provider (`codex exec --json`, off by default)
|
|
98
98
|
accepted its prompt only as a command-line argument — no stdin protocol —
|
|
99
99
|
so on a session bound to it, each turn's prompt and the background summary
|
|
100
100
|
fork's prompt were visible in `ps` and in `/proc/<pid>/cmdline`
|
|
101
101
|
(world-readable on Linux) for as long as the turn ran. The server could not
|
|
102
102
|
route around it; the constraint was the CLI's argument interface.
|
|
103
103
|
|
|
104
|
-
Resolved by **removing the
|
|
105
|
-
registered
|
|
104
|
+
Resolved by **removing the provider** rather than accepting the risk: every
|
|
105
|
+
registered provider passes prompts over stdio (`claude-sdk` via the SDK
|
|
106
106
|
driver's stdin protocol, `codex-app-server` via JSON-RPC over stdio).
|
|
107
|
-
Sessions persisted with the removed
|
|
107
|
+
Sessions persisted with the removed provider names resolve to their
|
|
108
108
|
same-family successor (`codex` → `codex-app-server`, which reads the same
|
|
109
109
|
`$CODEX_HOME` thread store; `claude` → the wire-identical `claude-sdk`).
|
|
110
110
|
|
|
111
111
|
The `Capabilities.prompt_in_argv` seam survives: a drop-in third-party
|
|
112
|
-
|
|
113
|
-
Settings →
|
|
114
|
-
(`
|
|
112
|
+
provider that takes prompts in argv must declare it and gets the
|
|
113
|
+
Settings → Providers warning automatically
|
|
114
|
+
(`test_no_registered_provider_puts_prompts_in_argv` keeps the shipped set
|
|
115
115
|
clean). Note that commands you run yourself — the terminal, `!bang`
|
|
116
116
|
commands, `/api/exec` — appear in `ps` like any shell command; only
|
|
117
117
|
*prompts* are guaranteed off the command line.
|
|
@@ -186,8 +186,8 @@ mid-transfer, rather than buffering then measuring.
|
|
|
186
186
|
|
|
187
187
|
## Supported versions
|
|
188
188
|
|
|
189
|
-
|
|
190
|
-
|
|
189
|
+
Security fixes land on the latest released version only; there are no
|
|
190
|
+
long-term support branches.
|
|
191
191
|
|
|
192
192
|
| Version | Supported |
|
|
193
193
|
|---------|-----------|
|
|
@@ -7,8 +7,8 @@ Everything pAInapple Code and the web client can do, in one place. Each area lin
|
|
|
7
7
|
| Feature | What it does | Guide |
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| Multi-session tabs | Several concurrent sessions in browser-style tabs; terminals and file previews can sit in the same tab strip | [Sessions & tabs](guides/sessions.md) |
|
|
10
|
-
| AI
|
|
11
|
-
| Session setup panel | One-tap
|
|
10
|
+
| AI providers | Pick Claude Code or OpenAI Codex per session — per-provider models, permission vocabularies, effort scales, defaults, and in-app CLI login. Codex support is experimental | [AI providers](guides/providers.md) |
|
|
11
|
+
| Session setup panel | One-tap provider / model / permissions / effort / account pills on every fresh session, gone after the first message | [AI providers](guides/providers.md) |
|
|
12
12
|
| Streaming chat | Live-rendered markdown, collapsible tool and thinking blocks, syntax highlighting, per-block line-wrap toggle, clickable file references | [Sessions & tabs](guides/sessions.md) |
|
|
13
13
|
| Per-turn summary bar | Context usage, token delta, files changed, tools used, duration, cost, and model after every turn | [Sessions & tabs](guides/sessions.md) |
|
|
14
14
|
| Reconnect & resume | Claude keeps running when the tab disconnects; page refresh reattaches; resume any session in the CLI with `claude --resume` | [Sessions & tabs](guides/sessions.md) |
|
|
@@ -25,7 +25,7 @@ Everything pAInapple Code and the web client can do, in one place. Each area lin
|
|
|
25
25
|
| Bang commands | `!git status` runs locally, shows as a tool block, and rides along as context for your next prompt | [Slash & bang commands](reference/commands.md) |
|
|
26
26
|
| Draft autosave | In-progress messages persist per session across refreshes | [Writing prompts & commands](guides/input-and-commands.md) |
|
|
27
27
|
| Uploads & annotation | Paste/drag images and files; draw markers, arrows, and text on screenshots before sending | [Images & annotation](guides/images-and-annotation.md) |
|
|
28
|
-
| Permission modes | Plan / Ask / Don't Ask / Accept Edits / Auto / YOLO
|
|
28
|
+
| Permission modes | Claude Code's own modes (Plan / Ask / Don't Ask / Accept Edits / Auto / YOLO) selectable per session, with its approval prompts rendered as in-chat cards — Codex sessions get Codex's sandbox tiers instead | [Permission modes & thinking](guides/permissions-and-thinking.md) |
|
|
29
29
|
| Thinking & effort | Extended-thinking budgets and effort cycling, per session | [Permission modes & thinking](guides/permissions-and-thinking.md) |
|
|
30
30
|
|
|
31
31
|
## Tool widgets
|
|
@@ -153,7 +153,7 @@ They land in `/data/npm-global`, on the persistent volume, owned by the unprivil
|
|
|
153
153
|
| `PAINAPPLE_AGENT_CLIS` | Override the set: space-separated `binary=npm-spec` pairs. Default `claude=@anthropic-ai/claude-code@2 codex=@openai/codex@latest`. Drop one to skip it, or pin an exact version. |
|
|
154
154
|
| `PAINAPPLE_AGENT_CLI_PREFIX` | Install location. Default `/data/npm-global`. |
|
|
155
155
|
|
|
156
|
-
A CLI already on `PATH` is left alone, checked per binary — so a baked-in `claude` doesn't suppress the `codex` install. A failed install is **not** fatal: the server still starts and serves the UI, terminal, git panel and history; only prompting that
|
|
156
|
+
A CLI already on `PATH` is left alone, checked per binary — so a baked-in `claude` doesn't suppress the `codex` install. A failed install is **not** fatal: the server still starts and serves the UI, terminal, git panel and history; only prompting that provider fails, with an explanation in the container log.
|
|
157
157
|
|
|
158
158
|
!!! tip "Air-gapped hosts"
|
|
159
159
|
Bake the CLIs into a derived image — the already-on-`PATH` check then leaves them alone:
|
|
@@ -10,7 +10,7 @@ Running the server directly on a host (pip / pipx / source checkout):
|
|
|
10
10
|
- **[Claude Code CLI](https://github.com/anthropics/claude-code)** installed and authenticated — either a Claude subscription (`claude login`) or an Anthropic API key
|
|
11
11
|
- **Git** on `PATH` — the [auto-journal](../guides/shadow-git.md) records every turn as a commit in a shadow repository, and the Git panel shells out to it for diffs. Without git the server still runs, but it journals nothing and the Git panel stays empty; you'll get a warning in the log at startup.
|
|
12
12
|
- **Network access between client and server** — any modern browser works as a client
|
|
13
|
-
- *Optional:* the **[OpenAI Codex CLI](https://github.com/openai/codex)** if you want sessions on the Codex [
|
|
13
|
+
- *Optional:* the **[OpenAI Codex CLI](https://github.com/openai/codex)** if you want sessions on the Codex [provider](../guides/providers.md) — you can even log it in from inside the app. **Codex support is experimental** — newer and less exercised than the Claude path.
|
|
14
14
|
|
|
15
15
|
### Server platforms
|
|
16
16
|
|
|
@@ -24,7 +24,7 @@ pAInapple Code runs natively on all three desktop platforms. No WSL required.
|
|
|
24
24
|
|
|
25
25
|
#### Windows notes
|
|
26
26
|
|
|
27
|
-
- **Install the Claude CLI with the native installer**, not npm: `irm https://claude.ai/install.ps1 | iex`. The Agent SDK that the default
|
|
27
|
+
- **Install the Claude CLI with the native installer**, not npm: `irm https://claude.ai/install.ps1 | iex`. The Agent SDK that the default provider uses refuses to execute npm's `claude.cmd` shim (batch files are a command-injection vector — the same class as CVE-2024-27980), and will tell you so with a link to this fix. If you already logged in via the npm install, your credentials carry over.
|
|
28
28
|
- **Get git from [Git for Windows](https://git-scm.com/download/win)**, which is what `winget install Git.Git` installs too. Besides `git.exe` it ships a `bash.exe`, and the optional `shadow-git` / `shadow-query` [helpers](../reference/optional-helpers.md) are shell scripts that run under it — the installer generates a small `.cmd` wrapper so you can still call them by name from PowerShell. (It deliberately does *not* use `C:\Windows\System32\bash.exe`; that one is the WSL launcher, which would look for your data inside the Linux filesystem.)
|
|
29
29
|
- **The terminal tab runs PowerShell** through ConPTY. `pwsh` (PowerShell 7) is preferred when present, otherwise Windows PowerShell; override with `PAINAPPLE_CODE_SHELL`.
|
|
30
30
|
- **`!bang` commands are PowerShell-flavored** on Windows, not `sh`.
|
|
@@ -44,7 +44,7 @@ The desktop browser is the primary target, but the UI is mobile-friendly and ins
|
|
|
44
44
|
|
|
45
45
|
## What it is, and what it isn't
|
|
46
46
|
|
|
47
|
-
**It is** a thin wrapper around Claude Code — every prompt streams through the official **Agent SDK
|
|
47
|
+
**It is** a thin wrapper around Claude Code — every prompt streams through the official **Agent SDK**. Sessions you create here can be resumed in the regular CLI with `claude --resume <id>`.
|
|
48
48
|
|
|
49
49
|
**It is not** an AI agent of its own. It never modifies Claude's system prompt, tool policy, or behavior — no injected planning steps, no hidden instructions, no parallelized work. What it *does* add to a prompt is the context **you** attached: the output of `!bang` commands you ran, paths of files you uploaded, and snippets from the comments stash are prepended as plain text. The one other exception is the optional `shadow-git-helper` agent, which knows how to query the Shadow Git history.
|
|
50
50
|
|
|
@@ -6,20 +6,22 @@
|
|
|
6
6
|
|
|
7
7
|
## Permissions
|
|
8
8
|
|
|
9
|
-
The default
|
|
9
|
+
**pAInapple Code does not implement permissions. Claude Code does.** The default provider drives Claude through the official **Agent SDK**, and what the app contributes is a per-session way to pick one of [Claude Code's own permission modes](https://code.claude.com/docs/en/permission-modes#available-modes) and a place to answer the CLI's approval prompts. Your existing `settings.json` allow/deny rules apply exactly as they do in the terminal. Don't read the list below as a safety layer this project provides — read it as the mode you are handing to Claude Code.
|
|
10
10
|
|
|
11
|
-
The
|
|
11
|
+
The default mode is **Ask**: reads run freely, but every edit and command pauses the turn on an approve/deny card in the chat — with a preview of the edit or command — until you decide. That's the safe out-of-the-box posture. The more permissive modes are opt-in, per session, and they're also where the app is most fun — which is exactly why the isolation advice below matters.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|------|----------|
|
|
15
|
-
| **Plan** | Read-only |
|
|
16
|
-
| **Ask** *(default)* | Reads auto-allowed; every edit/command waits on an approval card |
|
|
17
|
-
| **Don't Ask** | Auto-deny unless pre-approved by your allow rules |
|
|
18
|
-
| **Accept Edits** | Auto-approve workspace edits plus in-scope file commands like `cp` or `mv`; ask for the rest |
|
|
19
|
-
| **Auto** | Claude's AI classifier gates each tool call |
|
|
20
|
-
| **YOLO** | `bypassPermissions` — full access |
|
|
13
|
+
The modes available on the default provider (set per session via the button next to the input):
|
|
21
14
|
|
|
22
|
-
|
|
15
|
+
| Mode | CLI mode | Behavior |
|
|
16
|
+
|------|----------|----------|
|
|
17
|
+
| **Plan** | `plan` | Read-only |
|
|
18
|
+
| **Ask** *(default)* | `default` | Reads auto-allowed; every edit/command waits on an approval card |
|
|
19
|
+
| **Don't Ask** | `dontAsk` | Auto-deny unless pre-approved by your allow rules |
|
|
20
|
+
| **Accept Edits** | `acceptEdits` | Auto-approve workspace edits plus in-scope file commands like `cp` or `mv`; ask for the rest |
|
|
21
|
+
| **Auto** | `auto` | Claude's AI classifier gates each tool call |
|
|
22
|
+
| **YOLO** | `bypassPermissions` | Full access |
|
|
23
|
+
|
|
24
|
+
Three caveats. First, the approval cards only protect you while you're the one clicking them — in **YOLO** and **Auto** nothing asks, and those are the modes that give Claude the most freedom. Second, the cards exist only on the Claude provider: Codex enforces its own sandbox tiers instead. Third — and this is the point of this whole section — the boundary that actually holds is the one *below* the agent: the OS user, the container, the VM. A permission mode is the agent cooperating, not a sandbox. See the [permissions guide](../guides/permissions-and-thinking.md) for the full story.
|
|
23
25
|
|
|
24
26
|
## Terminal
|
|
25
27
|
|
|
@@ -35,14 +35,14 @@ Your overrides are pushed to the server, so they follow you across browsers and
|
|
|
35
35
|
|
|
36
36
|
Configures the radial FAB menu (see below): FAB visibility (Always / Mobile / Disabled), behavior options (context-aware action swapping, tooltips, press-drag-release selection, haptic feedback on mobile), which action sits in each slot, and preset switching.
|
|
37
37
|
|
|
38
|
-
###
|
|
38
|
+
### Providers
|
|
39
39
|
|
|
40
|
-
Everything about the [AI
|
|
40
|
+
Everything about the [AI providers](providers.md) — Claude and Codex — lives here:
|
|
41
41
|
|
|
42
|
-
- **
|
|
43
|
-
- **One sub-tab per enabled
|
|
42
|
+
- **Providers list** — enable/disable each provider and pick the default for new sessions (**Make default**).
|
|
43
|
+
- **One sub-tab per enabled provider** — CLI path and detected version, login status with an in-app **Log in** flow, the provider's model catalog (per-model show/hide; Claude's is fully editable), its **New Session Defaults** (model, effort, account), and its auto-journal summarizer model.
|
|
44
44
|
|
|
45
|
-
Full walkthrough: [AI
|
|
45
|
+
Full walkthrough: [AI providers → Settings → Providers](providers.md#settings-providers).
|
|
46
46
|
|
|
47
47
|
### System
|
|
48
48
|
|
|
@@ -81,7 +81,7 @@ Handy for pinning one terminal or file preview across a set of related sessions.
|
|
|
81
81
|
|
|
82
82
|
Some customization is stored server-side, so it follows you to any browser or device that logs into the same server; the rest is per-browser `localStorage`.
|
|
83
83
|
|
|
84
|
-
**Server-side:** shortcut overrides, quick-action presets, everything on the
|
|
84
|
+
**Server-side:** shortcut overrides, quick-action presets, everything on the Providers tab — which providers are enabled, which one is the default for new sessions, each provider's CLI path override, its per-model show/hide list, its editable model catalog (Claude only), its new-session defaults (model, effort, account) and its auto-journal summarizer model — per-project config (extra dirs, Shadow Git, commit sections), global Shadow Git defaults, global extra dirs, and [tab state](sessions.md). **Per-browser:** appearance settings (density, font scale, opacity, tool-block modes), input toggles, and the FAB position/slots.
|
|
85
85
|
|
|
86
86
|
## Related
|
|
87
87
|
|
|
@@ -8,7 +8,8 @@ Log into the web client from the device's browser first, then install:
|
|
|
8
8
|
|
|
9
9
|
- **iOS / iPadOS** — in Safari, tap the share button and choose **Add to Home Screen**.
|
|
10
10
|
- **Android** — Chrome offers **Install app** from the ⋮ menu (or an install banner).
|
|
11
|
-
- **
|
|
11
|
+
- **macOS** — in Safari 17+, choose **File → Add to Dock**; Chrome and Edge show an install icon in the address bar.
|
|
12
|
+
- **Windows / Linux** — Chrome and Edge show an install icon in the address bar (or **⋮ → Install**).
|
|
12
13
|
|
|
13
14
|
Why bother, instead of a browser tab:
|
|
14
15
|
|
|
@@ -22,7 +23,7 @@ Why bother, instead of a browser tab:
|
|
|
22
23
|
Your phone or tablet needs a route to the server — `localhost` won't cut it:
|
|
23
24
|
|
|
24
25
|
- **Bind beyond loopback** — start the server with `--host 0.0.0.0` (or a LAN IP). Binding a non-loopback host auto-enables TLS with a self-signed certificate; the browser shows a one-time certificate warning you accept on first visit.
|
|
25
|
-
- **Or put a reverse proxy in front** — Caddy/nginx
|
|
26
|
+
- **Or put a reverse proxy in front** — Caddy/nginx with a real certificate gives you a clean HTTPS origin, which PWAs and service workers prefer.
|
|
26
27
|
|
|
27
28
|
Either way, read [Read this first (security)](../getting-started/security.md) before exposing the server to anything wider than your desk, and [First run & login](../getting-started/first-run.md) for the password flow.
|
|
28
29
|
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Permission modes & thinking
|
|
2
|
+
|
|
3
|
+
Two controls next to the message input decide how much rope Claude gets: the **permission mode** button (what it may do without asking) and the **effort** gauge (how hard it thinks). Both are per-session with a global default.
|
|
4
|
+
|
|
5
|
+
## Permission modes
|
|
6
|
+
|
|
7
|
+
**These are Claude Code's own permission modes — pAInapple Code has no permission system of its own.** Picking a mode sets the CLI's `--permission-mode` for that session; Claude Code decides what to allow, deny or ask about, using the same allow/deny rules from your `settings.json` that the terminal CLI uses. Nothing here is a second layer of enforcement on top, and nothing here can make the agent safer than the mode you chose. The authoritative description of what each mode does is the [Claude Code permission-modes documentation](https://code.claude.com/docs/en/permission-modes#available-modes); the table below is a summary of it.
|
|
8
|
+
|
|
9
|
+
What pAInapple Code adds is the interface: a per-session switcher instead of a startup flag, approval prompts rendered as cards in the chat, and a colored input border so you always know which session is armed and which is read-only. The list of modes comes from the [provider](providers.md) the session runs on — the Claude provider offers these six, and the Codex provider offers Codex's own sandbox tiers instead.
|
|
10
|
+
|
|
11
|
+
| Mode | CLI mode | What Claude Code does |
|
|
12
|
+
|------|----------|-----------------------|
|
|
13
|
+
| **Plan** | `plan` | Read-only — explore and design, no writes |
|
|
14
|
+
| **Ask** *(default)* | `default` | Reads auto-allowed; every edit and command waits for your approval |
|
|
15
|
+
| **Don't Ask** | `dontAsk` | Auto-deny anything your Claude Code allow rules don't already cover |
|
|
16
|
+
| **Accept Edits** | `acceptEdits` | Auto-approve edits in the workspace (plus in-scope file commands like `mkdir`/`mv`/`cp`); ask for the rest |
|
|
17
|
+
| **Auto** | `auto` | An AI classifier reviews each tool call — reads and in-project edits sail through, riskier operations get blocked |
|
|
18
|
+
| **YOLO** | `bypassPermissions` | Skip all permission checks |
|
|
19
|
+
|
|
20
|
+
They're listed roughly from most restrictive to most permissive — roughly, because **Don't Ask** sits above **Ask** while actually granting *less* (it auto-denies rather than asking you).
|
|
21
|
+
|
|
22
|
+
### Interactive permission cards
|
|
23
|
+
|
|
24
|
+
A card is Claude Code's own approval prompt, drawn in the chat instead of the terminal. On the default SDK provider, when the agent asks, the SDK blocks the turn and hands the request to the app; the card is how you answer it. The elapsed timer freezes, background tabs get a badge plus a click-to-go toast so you notice the wait from another session, and you can deny with an optional note back to Claude, or approve.
|
|
25
|
+
|
|
26
|
+
The **"always allow"** options on a card are the CLI's own "don't ask again" suggestions — allow this exact command in this project, allow a directory, or switch mode. Pick one and *Claude Code* persists the rule (into your project's `.claude/settings.local.json`, say), in the same file the terminal CLI reads. Rules you already wrote there apply here unchanged, and rules you accept here apply the next time you run `claude` in that project.
|
|
27
|
+
|
|
28
|
+
The default mode is **Ask** — reads run freely, but every edit and command waits for your approval on a card. Prefer **Accept Edits** to wave edits through and only get carded for commands, **YOLO** or **Auto** to let Claude just work, or **Don't Ask** to auto-deny anything your allow rules don't already cover. **Plan** stays read-only.
|
|
29
|
+
|
|
30
|
+
!!! note "Other providers"
|
|
31
|
+
Sessions can also run on OpenAI Codex — see [AI providers](providers.md) for picking one per session (or pinning a server-wide default with `--default-provider`). The same pass-through applies: Codex doesn't use these modes at all, so the button maps to the Codex CLI's own **sandbox tiers** (Read-only / Workspace write / Full access), enforced by Codex.
|
|
32
|
+
|
|
33
|
+
!!! note "Auto mode is a research preview"
|
|
34
|
+
Auto is the CLI's `--permission-mode auto`, where a classifier model on Claude Code's side gates each call. It needs a recent CLI and model (Sonnet 4.6+/Opus 4.6+ on the Anthropic API; Team/Enterprise plans need an org owner to enable it). Also, headless auto sessions abort after 3 consecutive classifier blocks (or 20 total) — if Claude keeps getting blocked, the turn ends rather than looping.
|
|
35
|
+
|
|
36
|
+
!!! warning "Read the security notes before going YOLO"
|
|
37
|
+
YOLO means Claude can run any command as the server user. That is the intended way to use this app — inside an isolated container or VM. See [Read this first](../getting-started/security.md).
|
|
38
|
+
|
|
39
|
+
### Per-session, with a default
|
|
40
|
+
|
|
41
|
+
The one thing the app really does own here is *when* you get to choose. The CLI takes its mode at startup; here it's a per-session setting, saved with the session and restored when you reopen it. On the default SDK provider a mode switch applies **immediately, even mid-turn** — the running provider changes gear in place, so you can flip to Accept Edits while approval cards are stacking up and the rest of the turn follows the new mode (the system log confirms "applied to the running provider"). Whenever the live switch isn't possible, it takes effect on your next message instead, when the server respawns the idle provider process with the new mode. The **Set as default** button in the popup makes the current mode the global default for new sessions (also editable in Settings).
|
|
42
|
+
|
|
43
|
+
### Plan mode and plan approval
|
|
44
|
+
|
|
45
|
+
In **Plan** mode Claude explores read-only and ends with a plan. The plan renders as an interactive approval card — approve it and the session drops out of plan mode to execute; reject it and you stay planning. Tabs show a *Plan ready for review* badge while a plan waits. You can also enter plan mode for a single message by typing `/plan ` in the input — see [input modes](input-and-commands.md#input-modes).
|
|
46
|
+
|
|
47
|
+
Related: when Claude asks a clarifying question mid-turn (AskUserQuestion), pAInapple Code by default stops it so you can answer — see [When Claude asks you a question](sessions.md#when-claude-asks-you-a-question).
|
|
48
|
+
|
|
49
|
+
## Effort levels
|
|
50
|
+
|
|
51
|
+
The circular gauge button next to the input controls Claude's effort — how many thinking tokens it spends — on a five-step scale: **low**, **medium**, **high** (the default), **xhigh**, **max**. The conic fill of the gauge shows the level at a glance (a fifth per step, glowing at max). It maps to the CLI's `--effort` flag. The scale is per-[provider](providers.md): Codex sessions render Codex's own reasoning levels (up to `ultra` on recent models), narrowed to what the selected model supports.
|
|
52
|
+
|
|
53
|
+
- **Click the gauge** (or ++cmd+apostrophe++ / ++ctrl+apostrophe++) to open the level picker. Like permission modes, effort is per-session, with **Set as default** to change the global fallback.
|
|
54
|
+
- **One-shot override:** ++cmd+shift+apostrophe++ / ++ctrl+shift+apostrophe++ arms a temporary level for the *next message only* — first press bumps one level above your persistent setting, further presses cycle through the rest (including below it), and landing back on the persistent level disarms. A badge on the gauge shows the armed level; it clears itself after one send. Perfect for "give this one question the max treatment" without re-configuring.
|
|
55
|
+
|
|
56
|
+
Changing effort applies on your next message by respawning the idle process (unlike permission mode there's no live-apply here — the provider has no mid-session effort control).
|
|
57
|
+
|
|
58
|
+
## Token profiles
|
|
59
|
+
|
|
60
|
+
If you have more than one Claude account (say, a personal Max plan and a work team seat), drop each OAuth token in a plain-text file under `~/.config/painapple-code/tokens/` — the filename becomes the profile name:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
~/.config/painapple-code/tokens/
|
|
64
|
+
├── max # contents: the OAuth token string
|
|
65
|
+
└── work
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
A profile chip then appears in the status bar next to the model name (it's hidden when the directory is empty). Click it to pick which account the *current session* bills to; the server sets `CLAUDE_CODE_OAUTH_TOKEN` accordingly when it spawns Claude. Each session remembers its profile, and a global default is available.
|
|
69
|
+
|
|
70
|
+
The killer feature: when a turn ends **rate-limited**, the turn summary bar replaces its context bar with a *Switch token:* strip — one tap on another profile and you keep working on the other account's quota.
|
|
71
|
+
|
|
72
|
+
## Choosing a model
|
|
73
|
+
|
|
74
|
+
The model name in the status bar is a selector — click it to switch the session's model. The catalog is the session [provider's](providers.md) own: for Claude it comes from the server's `models.yaml` (editable in **Settings → Providers** or by hand), including `[1m]` variants that run the same model with a 1M-token context window; for Codex it mirrors the Codex CLI's model list. A model switch applies from your next message onward, in the same conversation — on the default SDK provider the warm process changes model in place, so there's no respawn pause on your first message with the new model.
|
|
75
|
+
|
|
76
|
+
Optionally, a server-wide `fallback_model` key in `~/.painapple-code/config.json` names a model to fall back to automatically when the primary is overloaded or unavailable (the CLI's `--fallback-model`) — the turn completes on the fallback instead of dying with an overload error.
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# AI providers (Claude & Codex)
|
|
2
|
+
|
|
3
|
+
Every session runs on an **provider** — the AI CLI pAInapple Code drives under the hood. The default is Claude Code via the official Agent SDK, but pAInapple Code can also drive the **OpenAI Codex CLI**, and you pick per session: a Claude tab and a Codex tab can sit side by side in the same strip, each with its own models, permission vocabulary, and effort scale.
|
|
4
|
+
|
|
5
|
+
!!! warning "The Codex path is experimental"
|
|
6
|
+
Codex support is **newer and has had less testing** than the Claude path — it works, but expect rougher edges. Claude Code via the Agent SDK is the default and the well-trodden route.
|
|
7
|
+
|
|
8
|
+
## The providers
|
|
9
|
+
|
|
10
|
+
| Provider | What it is |
|
|
11
|
+
|--------|-----------|
|
|
12
|
+
| **Claude Code** | Claude Code via the Agent SDK — interactive permission cards, live mode/model switching mid-turn. The default. |
|
|
13
|
+
| **Codex** | OpenAI Codex over its persistent app-server protocol — native forking, server-reported context window, graceful interrupt. |
|
|
14
|
+
|
|
15
|
+
Earlier releases also shipped two "plain CLI" fallback drivers (line-protocol `claude -p`, and Codex `exec` mode — one process per turn). Both were removed: the SDK and app-server drivers supersede them on every axis, and the Codex `exec` mode had a real downside — it could only take the prompt as a command-line argument, which made prompts readable in the process list by other accounts on the same machine. Sessions created on the old drivers keep working; they resume on the matching current provider automatically. Enable or hide providers in **Settings → Providers**.
|
|
16
|
+
|
|
17
|
+
!!! note "What Codex needs"
|
|
18
|
+
The Codex provider requires the [Codex CLI](https://github.com/openai/codex) (`@openai/codex`) installed on the *server* and logged in. A provider whose CLI is missing shows up greyed-out with a hint; a CLI that isn't logged in gets a **Log in** button right in Settings (see [below](#logging-in)). The Docker image doesn't bundle Codex, but it doesn't need to: the entrypoint installs it on first start alongside the Claude CLI, onto the `/data` volume. Override the set with `PAINAPPLE_AGENT_CLIS`, or skip it entirely with `PAINAPPLE_SKIP_AGENT_CLI=1`. See [container mode](../getting-started/install-docker.md).
|
|
19
|
+
|
|
20
|
+
## Picking a provider per session
|
|
21
|
+
|
|
22
|
+
Provider choice happens **in chat**, while a session is still fresh:
|
|
23
|
+
|
|
24
|
+
- **Session setup panel** — every new session (project picked, nothing sent yet) shows a card of one-tap pill rows directly above the input: **provider, model, permissions, effort, account**. Tap through your setup and start typing; the panel disappears with your first message.
|
|
25
|
+
- **Status-bar provider chip** — the provider name in the status bar opens the same picker at any time before the first message.
|
|
26
|
+
|
|
27
|
+
A session **locks to its provider with the first message** — the conversation history lives with that CLI. Picking a different provider on a locked session doesn't fail, though: it opens a **clone tab** in the same working directory running the provider you picked. **Clone** (++cmd+n++) also inherits the source session's provider.
|
|
28
|
+
|
|
29
|
+
The **default provider** for new sessions is set with the **Make default** button in Settings → Providers (or the `--default-provider` flag / `default_provider` config key — the flag pins the choice and hides the button).
|
|
30
|
+
|
|
31
|
+
## What changes with the provider
|
|
32
|
+
|
|
33
|
+
Each provider self-describes its capabilities, and the UI follows:
|
|
34
|
+
|
|
35
|
+
- **Models** — the model picker shows the *active provider's* catalog. Claude's comes from the server's editable `models.yaml`; Codex's mirrors the Codex CLI's own model list (so it updates when Codex does). Per-provider default models are configured in Settings → Providers.
|
|
36
|
+
- **Permission modes** — the Claude provider speaks Claude's modes (Plan / Ask / Don't Ask / Accept Edits / Auto / YOLO — see [Permission modes](permissions-and-thinking.md)); the Codex provider maps to Codex **sandbox tiers**: Read-only, Workspace write, and Full access.
|
|
37
|
+
- **Effort** — the effort gauge renders each provider's own scale. Claude has five levels (low → max); Codex levels come from its model catalog and can reach `xhigh` / `ultra` on recent models, with the picker narrowing to what the selected model supports.
|
|
38
|
+
- **Cost** — Codex reports tokens only, no dollar figure, so the `$` cost readouts hide on Codex sessions and the turn bar shows token counts.
|
|
39
|
+
- **Continue in the CLI** — the **Continue in CLI** quick action is provider-aware: a Claude session gives you `claude -r <id>`, a Codex session `codex exec resume <id>`.
|
|
40
|
+
- **Auto-journal** — the [Shadow Git journal](shadow-git.md) fork always runs on the session's own provider (only the owner of a conversation can fork it), and each provider has its own journal-summarizer model setting.
|
|
41
|
+
|
|
42
|
+
## Settings → Providers
|
|
43
|
+
|
|
44
|
+
**Settings → Providers** (++ctrl+comma++) is the control room:
|
|
45
|
+
|
|
46
|
+
- **Providers list** — a toggle per provider (the default provider is forced on), and a **Make default** button on every other available provider. Disabling a provider hides it from pickers; sessions already bound to it keep working.
|
|
47
|
+
- **One sub-tab per enabled provider**, all with the same layout:
|
|
48
|
+
- **CLI status** — the resolved binary path and live `--version`, plus a path-override field per provider CLI.
|
|
49
|
+
- <a id="logging-in"></a>**Login status** — whether the CLI is authenticated ("Logged in — email · plan" for Claude, exit status for Codex). When it isn't, a **Log in** button opens a terminal tab running the provider's login flow; the row polls and flips green when you finish. Codex uses device-code auth (`codex login --device-auth`) so the flow works even when the server is remote.
|
|
50
|
+
- **Model catalog** — every model with a show/hide toggle (hidden models disappear from all pickers). Claude's catalog is fully editable (add/edit/delete, restore defaults); Codex's is read-only because the Codex CLI owns it.
|
|
51
|
+
- **New Session Defaults** — that provider's default model, default effort (its own vocabulary), and default account/token profile where applicable.
|
|
52
|
+
- **Auto-journal model** — which model writes the [Shadow Git](shadow-git.md) summaries for sessions on this provider.
|
|
53
|
+
|
|
54
|
+
## Related
|
|
55
|
+
|
|
56
|
+
- [Permission modes & thinking](permissions-and-thinking.md) — what the modes and effort levels mean.
|
|
57
|
+
- [Sessions & tabs](sessions.md) — cloning, forking, and continuing sessions in the CLI.
|
|
58
|
+
- [Server CLI](../reference/server-cli.md) — `--default-provider` and config keys.
|
|
@@ -4,7 +4,7 @@ Each tab in pAInapple Code is its own Claude Code session — its own conversati
|
|
|
4
4
|
|
|
5
5
|
## The tab strip
|
|
6
6
|
|
|
7
|
-
Press ++cmd+t++ / ++ctrl+t++ (or the **+** button) to open a new tab. It lands on the [welcome screen](welcome-screen.md), where you pick a project and type your first prompt. While a session is still empty, a **setup panel** above the input offers one-tap rows for the [AI
|
|
7
|
+
Press ++cmd+t++ / ++ctrl+t++ (or the **+** button) to open a new tab. It lands on the [welcome screen](welcome-screen.md), where you pick a project and type your first prompt. While a session is still empty, a **setup panel** above the input offers one-tap rows for the [AI provider](providers.md), model, permission mode, effort, and account — tune the session, then just start typing. There is no limit on how many sessions you can have open at once — once the tab strip runs out of room it collapses the overflow into a **+N** chip.
|
|
8
8
|
|
|
9
9
|
Session tabs share one strip with *widget tabs* — terminals, file previews, and scratch editors opened as tabs interleave freely with sessions, so a terminal can sit right between two conversations. Each session tab shows a status dot (lit while Claude or the auto-journal is working), an unread dot for background activity, and a **?** badge when Claude is waiting for [an answer from you](#when-claude-asks-you-a-question).
|
|
10
10
|
|
|
@@ -103,4 +103,4 @@ Every session here is a real CLI session. Grab the ID from the tab context menu
|
|
|
103
103
|
claude --resume <session-id>
|
|
104
104
|
```
|
|
105
105
|
|
|
106
|
-
Easier still, the **Continue in CLI** quick action copies the exact resume command for the session's [
|
|
106
|
+
Easier still, the **Continue in CLI** quick action copies the exact resume command for the session's [provider](providers.md) — `claude -r <id>` for a Claude session, `codex exec resume <id>` for a Codex one.
|
|
@@ -16,7 +16,7 @@ A few properties worth internalizing:
|
|
|
16
16
|
|
|
17
17
|
## Rich commits: the Haiku auto-journal
|
|
18
18
|
|
|
19
|
-
On top of the raw commits sits the second layer: **rich commits**. After each turn, the server forks a background summarizer (Haiku by default; the model is configurable per [
|
|
19
|
+
On top of the raw commits sits the second layer: **rich commits**. After each turn, the server forks a background summarizer (Haiku by default; the model is configurable per [provider](providers.md) in **Settings → Providers** — the fork runs on the session's own provider, so Codex sessions self-summarize with a Codex model) that reads the **whole turn, not just the diff** — with the running "journey" context of previous turn summaries — and writes a structured commit message: a one-line summary, tags, plus sections like *work done*, *investigation*, *findings*, *decisions*, *problems solved*, *verification*, and *learnings*. You can customize which sections are generated per project.
|
|
20
20
|
|
|
21
21
|
Everything is parsed and stored in a local DuckDB alongside the git data, so it's queryable: every turn's prompt, cost, tokens, duration, model, files touched, tools used, tags, and all the generated sections.
|
|
22
22
|
|