painapple-code 1.0.0rc1__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.0rc1/.devcontainer/devcontainer.json +44 -0
- painapple_code-1.0.0rc1/.dockerignore +19 -0
- painapple_code-1.0.0rc1/.github/workflows/docker-publish.yml +187 -0
- painapple_code-1.0.0rc1/.github/workflows/pypi-publish.yml +94 -0
- painapple_code-1.0.0rc1/.github/workflows/release-features.yml +38 -0
- painapple_code-1.0.0rc1/.github/workflows/test-features.yml +33 -0
- painapple_code-1.0.0rc1/.gitignore +80 -0
- painapple_code-1.0.0rc1/Dockerfile +155 -0
- painapple_code-1.0.0rc1/LICENSE +661 -0
- painapple_code-1.0.0rc1/PKG-INFO +382 -0
- painapple_code-1.0.0rc1/README.dockerhub.md +164 -0
- painapple_code-1.0.0rc1/README.md +344 -0
- painapple_code-1.0.0rc1/docker-compose.yml +50 -0
- painapple_code-1.0.0rc1/docker-entrypoint.sh +53 -0
- painapple_code-1.0.0rc1/examples/devcontainer/README.md +76 -0
- painapple_code-1.0.0rc1/examples/devcontainer/devcontainer.json +30 -0
- painapple_code-1.0.0rc1/examples/personalize/README.md +84 -0
- painapple_code-1.0.0rc1/examples/personalize/devcontainer.json +30 -0
- painapple_code-1.0.0rc1/examples/personalize-dockerfile/Dockerfile +38 -0
- painapple_code-1.0.0rc1/examples/personalize-dockerfile/README.md +86 -0
- painapple_code-1.0.0rc1/features/src/painapple-code/README.md +179 -0
- painapple_code-1.0.0rc1/features/src/painapple-code/devcontainer-feature.json +53 -0
- painapple_code-1.0.0rc1/features/src/painapple-code/install.sh +391 -0
- painapple_code-1.0.0rc1/features/test/painapple-code/test.sh +65 -0
- painapple_code-1.0.0rc1/painapple-docker.sh +2584 -0
- painapple_code-1.0.0rc1/pyproject.toml +69 -0
- painapple_code-1.0.0rc1/requirements.txt +11 -0
- painapple_code-1.0.0rc1/setup.cfg +4 -0
- painapple_code-1.0.0rc1/src/painapple_code/__init__.py +30 -0
- painapple_code-1.0.0rc1/src/painapple_code/__main__.py +13 -0
- painapple_code-1.0.0rc1/src/painapple_code/_version.py +24 -0
- painapple_code-1.0.0rc1/src/painapple_code/auth_middleware.py +507 -0
- painapple_code-1.0.0rc1/src/painapple_code/bridge_paths.py +1028 -0
- painapple_code-1.0.0rc1/src/painapple_code/cli/__init__.py +32 -0
- painapple_code-1.0.0rc1/src/painapple_code/cli/docker/__init__.py +116 -0
- painapple_code-1.0.0rc1/src/painapple_code/cli/docker/commands.py +757 -0
- painapple_code-1.0.0rc1/src/painapple_code/cli/docker/config.py +364 -0
- painapple_code-1.0.0rc1/src/painapple_code/cli/docker/runtime.py +88 -0
- painapple_code-1.0.0rc1/src/painapple_code/cli/docker/wizard.py +415 -0
- painapple_code-1.0.0rc1/src/painapple_code/cli/ui.py +404 -0
- painapple_code-1.0.0rc1/src/painapple_code/cost_analytics.py +884 -0
- painapple_code-1.0.0rc1/src/painapple_code/data/models.defaults.yaml +15 -0
- painapple_code-1.0.0rc1/src/painapple_code/data/models.yaml +15 -0
- painapple_code-1.0.0rc1/src/painapple_code/data/presets.defaults.json +32 -0
- painapple_code-1.0.0rc1/src/painapple_code/data/strings.yaml +1573 -0
- painapple_code-1.0.0rc1/src/painapple_code/helpers.py +140 -0
- painapple_code-1.0.0rc1/src/painapple_code/prompt_explorer.py +984 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/__init__.py +215 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/base.py +515 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/claude/__init__.py +69 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/claude/capabilities.py +167 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/claude/errors.py +66 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/claude/launch.py +47 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/claude/summary.py +83 -0
- painapple_code-1.0.0rc1/src/painapple_code/providers/claude/translate.py +61 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/__init__.py +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_agents.py +440 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_bridge.py +132 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_bridge_commit_sections.py +127 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_bridge_config.py +506 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_bridge_session_prefs.py +212 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_browser.py +521 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_commands.py +368 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_costs.py +128 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_exec.py +50 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_files.py +493 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_git.py +651 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_logs.py +532 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_plugins.py +273 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_project_config.py +294 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_prompts.py +231 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_session_stash.py +205 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_session_welcome.py +138 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_sessions.py +540 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_shadow.py +323 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_shadow_db.py +473 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_shadow_files.py +327 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_shadow_search.py +476 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_skills.py +609 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_tasks.py +138 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_terminal.py +589 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_upload.py +213 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/api_viewer.py +188 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/dependencies.py +17 -0
- painapple_code-1.0.0rc1/src/painapple_code/routes/ws_chat.py +679 -0
- painapple_code-1.0.0rc1/src/painapple_code/server.py +1349 -0
- painapple_code-1.0.0rc1/src/painapple_code/server_logging.py +242 -0
- painapple_code-1.0.0rc1/src/painapple_code/services/__init__.py +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/services/agent_session.py +2236 -0
- painapple_code-1.0.0rc1/src/painapple_code/session_store.py +254 -0
- painapple_code-1.0.0rc1/src/painapple_code/session_store_core.py +820 -0
- painapple_code-1.0.0rc1/src/painapple_code/session_store_migration.py +144 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_db.py +760 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_db_plans.py +369 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_db_queries.py +595 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_db_schema.py +676 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_git.py +1133 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_git_frontmatter.py +314 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_git_sections.py +520 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_git_summary.py +457 -0
- painapple_code-1.0.0rc1/src/painapple_code/shadow_parser.py +560 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/00-variables.css +177 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/01-base.css +150 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/02-tooltips.css +36 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/09-left-rail.css +311 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/10-header.css +691 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/11-connection-bar.css +120 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/20-messages.css +739 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/21-tool-blocks.css +2326 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/22-edit-diff.css +574 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/23-thinking.css +1570 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/24-background-tasks.css +355 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/25-context-block.css +252 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/30-markdown.css +531 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/40-input.css +1955 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/41-autocomplete.css +127 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/42-activity-strip.css +88 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/43-file-autocomplete.css +136 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/44-snippets-autocomplete.css +237 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/45-selection-bar.css +362 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/46-keyboard-bar.css +119 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/47-keyboard-longpress.css +116 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/47-token-profile.css +105 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/50-welcome.css +2969 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/51-modals.css +294 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/52-utilities.css +77 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/53-image-upload.css +415 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/54-todo-list.css +102 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/55-file-upload.css +113 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/56-chat-navigator.css +218 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/56-plan-approval.css +204 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/56-question-form.css +496 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/57-swipe-indicator.css +95 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/58-session-families.css +626 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/61-log-explorer.css +683 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/62-json-tree.css +411 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/62-skills-widget.css +648 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/63-commands-widget.css +30 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/63-plugins-widget.css +174 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/63-terminal.css +514 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/65-snippets-widget.css +425 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/66-active-sessions.css +979 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/66-agents-widget.css +265 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/66-file-explorer-widget.css +854 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/66-git-panel.css +795 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/67-diff-viewer.css +576 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/67-editor-view.css +675 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/67-file-preview-widget.css +1317 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/68-browser-widget.css +254 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/68-compare-wizard.css +355 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/68-csv-preview.css +106 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/68-helpers-install-widget.css +437 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/68-terminal-view.css +98 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/68-uploads-widget.css +163 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/69-cost-analytics.css +537 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/70-config-panel.css +3227 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/70-excalidraw.css +136 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/70-prompt-explorer.css +782 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/71-chart.css +111 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/72-discussion-sidebar.css +685 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/74-debug-logs.css +656 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/76-history-explorer.css +680 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/80-open-dialog.css +146 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/80-quick-switcher.css +260 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/80-widget-system.css +1733 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/81-quick-actions.css +1011 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/82-context-popover.css +1180 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/83-context-menu.css +300 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/85-lazy-loading.css +102 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/86-zen-mode.css +708 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/87-grid-switcher.css +341 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/css/login.css +198 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/feature-triage.html +1208 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/apple-touch-icon.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/favicon-32.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/favicon.ico +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-128.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-144.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-152.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-180.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-192.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-384.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-512.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-72.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/icons/icon-96.png +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/activity-strip.js +181 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/app-context.js +157 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/app.js +5875 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/auth-fetch.js +46 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/background-tasks.js +274 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/caret-position.js +171 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/chat-navigator.js +683 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/chat-search.js +323 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/command-executor.js +172 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/command-store.js +497 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/components.js +982 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/config.js +158 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/context-menu.js +570 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/controllers/chat-controller.js +3667 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/controllers/dialog-controller.js +185 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/controllers/tab-controller.js +1505 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/controllers/thinking-controller.js +905 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/diff-utils.js +484 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/editor-view.js +597 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/effort-settings.js +369 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/file-autocomplete.js +515 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/file-tabs.js +120 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/gestures.js +448 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/grid-switcher.js +332 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/input-handler.js +922 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/keyboard-bar.js +495 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/linkify-utils.js +200 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/open-dialog.js +870 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/orphan-terminals.js +366 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/perf-marks.js +102 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/permission-settings.js +347 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/json-tree.js +213 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-edit.js +366 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-events.js +239 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-history.js +533 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-inline-edit.js +785 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-poll.js +102 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-render.js +445 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-search.js +391 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-state.js +175 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview/preview-utils.js +244 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/chart-plugin.js +22 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/csv-plugin.js +188 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/excalidraw-plugin.js +25 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/html-plugin.js +104 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/image-plugin.js +20 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/index.js +32 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/json-plugin.js +131 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/jsonl-plugin.js +170 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/markdown-plugin.js +76 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/panzoom-plugin.js +62 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/preview-plugins/plugin-helpers.js +264 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/prompt-favorites.js +187 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-actions-menu.js +1708 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-actions-registry.js +1147 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/controller.js +217 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/fuzzy-scorer.js +123 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/index.js +28 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/providers/base-provider.js +51 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/providers/command-provider.js +56 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/providers/file-provider.js +296 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/providers/panel-provider.js +130 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/providers/project-provider.js +254 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/providers/skills-provider.js +108 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/registry.js +69 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/ui/item.js +54 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/quick-switcher/ui/picker.js +350 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/recent-opens.js +40 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/scroll-manager.js +488 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/scroll-state-machine.js +359 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/selection/action-bar.js +749 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/selection/index.js +15 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/selection/selection-handler.js +779 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/selection/state.js +107 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/agent-progress.js +202 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/handle-agent-message.js +448 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/handle-message.js +435 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/interactive.js +305 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/message-store.js +204 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/messages.js +244 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/persistence.js +111 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/restore.js +123 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session/sync.js +227 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session-container-pool.js +340 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/session.js +912 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/shortcut-hints.js +240 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/shortcuts.js +929 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/skills-autocomplete.js +262 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/snippets-autocomplete.js +738 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/stash-ui.js +458 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/stash.js +555 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/status-bar.js +737 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/token-profile.js +250 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/tool-renderer-blocks.js +1576 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/tool-renderer-thinking.js +819 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/tool-renderer.js +1473 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/tooltips.js +193 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/upload-manager.js +688 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/utils.js +453 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/welcome/api.js +356 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/welcome/cards.js +547 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/welcome/context-menu.js +563 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/welcome/families.js +763 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/welcome/preview.js +234 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/welcome/state.js +128 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/welcome.js +1777 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/base-widget.js +708 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/device-manager.js +178 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/event-bus.js +152 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/icons.js +114 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/index.js +49 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/init.js +54 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/types/bottom-sheet.js +307 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/types/floating.js +813 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/types/index.js +40 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/types/modal.js +147 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/types/sidebar.js +158 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/types/tab.js +146 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/types/top-sheet.js +203 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widget-system/widget-manager.js +1170 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/active-sessions-widget.js +748 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/agents-widget.js +897 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/browser-widget.js +409 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/commands-widget.js +694 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/commit-sections.js +449 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/dir-autocomplete.js +223 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/gestures.js +161 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/models-tab.js +296 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/quick-actions-tab.js +641 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/shortcut-editor.js +587 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/state.js +483 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config/system-controls.js +304 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/config-widget.js +1384 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/cost-analytics-widget.js +629 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/debug-widget.js +693 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/diff-viewer-widget.js +1606 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/discussion-widget.js +1074 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/file-explorer-widget.js +2147 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/file-preview-widget.js +754 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/git-widget.js +793 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/helpers-install-widget.js +569 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/history-explorer-widget.js +2699 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/image-preview-widget.js +433 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/index.js +162 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/log-explorer-widget.js +1002 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/plugins-widget.js +305 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/prompt-explorer-widget.js +833 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/skills-widget.js +843 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/snippets-widget.js +479 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/sub-agents-widget.js +335 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/tasks-widget.js +381 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal/connection.js +283 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal/gestures.js +330 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal/init.js +518 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal/link-providers.js +440 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal/render.js +159 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal/size.js +54 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal/state.js +210 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/terminal-widget.js +791 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/uploads-widget.js +309 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/js/widgets/zen-widget.js +999 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/login.html +156 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/manifest.json +73 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/sw.js +277 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/README.md +49 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/codemirror.js +32 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/github-markdown-dark.min.css +1124 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/highlight-github-dark.min.css +10 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/highlight-lang-dockerfile.min.js +8 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/highlight-lang-nginx.min.js +21 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/highlight-lang-properties.min.js +10 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/highlight-lang-scala.min.js +28 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/highlight.min.js +1213 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/marked.min.js +6 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/xterm-addon-fit.js +2 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/xterm.css +209 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/vendor/xterm.js +2 -0
- painapple_code-1.0.0rc1/src/painapple_code/static/web-client.html +660 -0
- painapple_code-1.0.0rc1/src/painapple_code/subprocess_registry.py +535 -0
- painapple_code-1.0.0rc1/src/painapple_code/tls_cert.py +86 -0
- painapple_code-1.0.0rc1/src/painapple_code/tools/agents/shadow-git-helper.md +399 -0
- painapple_code-1.0.0rc1/src/painapple_code/tools/excalidraw-to-svg.js +143 -0
- painapple_code-1.0.0rc1/src/painapple_code/tools/install-helpers.sh +148 -0
- painapple_code-1.0.0rc1/src/painapple_code/tools/shadow-git +262 -0
- painapple_code-1.0.0rc1/src/painapple_code/tools/shadow-query +108 -0
- painapple_code-1.0.0rc1/src/painapple_code/tools/vegalite-to-svg.js +79 -0
- painapple_code-1.0.0rc1/src/painapple_code/turn_query.py +766 -0
- painapple_code-1.0.0rc1/src/painapple_code/turn_tracker.py +194 -0
- painapple_code-1.0.0rc1/src/painapple_code/utils/__init__.py +0 -0
- painapple_code-1.0.0rc1/src/painapple_code/utils/agent_cli.py +297 -0
- painapple_code-1.0.0rc1/src/painapple_code/utils/chart.py +103 -0
- painapple_code-1.0.0rc1/src/painapple_code/utils/excalidraw.py +107 -0
- painapple_code-1.0.0rc1/src/painapple_code/utils/file_paths.py +340 -0
- painapple_code-1.0.0rc1/src/painapple_code/utils/generate_icons.py +154 -0
- painapple_code-1.0.0rc1/src/painapple_code/utils/token_profiles.py +83 -0
- painapple_code-1.0.0rc1/src/painapple_code/viewer_templates.py +647 -0
- painapple_code-1.0.0rc1/src/painapple_code/welcome_search.py +829 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/PKG-INFO +382 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/SOURCES.txt +481 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/dependency_links.txt +1 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/entry_points.txt +2 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/requires.txt +11 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/scm_file_list.json +476 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/scm_version.json +8 -0
- painapple_code-1.0.0rc1/src/painapple_code.egg-info/top_level.txt +1 -0
- painapple_code-1.0.0rc1/start.sh +132 -0
- painapple_code-1.0.0rc1/tauri-app/.gitignore +7 -0
- painapple_code-1.0.0rc1/tauri-app/APP.md +75 -0
- painapple_code-1.0.0rc1/tauri-app/CAPACITOR-VS-TAURI.md +125 -0
- painapple_code-1.0.0rc1/tauri-app/README.md +86 -0
- painapple_code-1.0.0rc1/tauri-app/WINDOWS.md +82 -0
- painapple_code-1.0.0rc1/tauri-app/package-lock.json +245 -0
- painapple_code-1.0.0rc1/tauri-app/package.json +24 -0
- painapple_code-1.0.0rc1/tauri-app/scripts/ios-install.sh +60 -0
- painapple_code-1.0.0rc1/tauri-app/scripts/ios-postinit.sh +225 -0
- painapple_code-1.0.0rc1/tauri-app/scripts/macos-install.sh +65 -0
- painapple_code-1.0.0rc1/tauri-app/scripts/tao-fix.patch +127 -0
- painapple_code-1.0.0rc1/tauri-app/scripts/tao-setup.sh +68 -0
- painapple_code-1.0.0rc1/tauri-app/src/icon.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src/index.html +345 -0
- painapple_code-1.0.0rc1/tauri-app/src/launcher.js +651 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/Cargo.lock +5578 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/Cargo.toml +87 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/build.rs +3 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/capabilities/default.json +11 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/capabilities/server-pages.json +15 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/128x128.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/128x128@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/32x32.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/64x64.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square107x107Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square142x142Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square150x150Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square284x284Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square30x30Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square310x310Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square44x44Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square71x71Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/Square89x89Logo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/StoreLogo.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-anydpi-v26/ic_launcher.xml +5 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-hdpi/ic_launcher.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_foreground.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-hdpi/ic_launcher_round.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-mdpi/ic_launcher.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_foreground.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-mdpi/ic_launcher_round.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_foreground.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xhdpi/ic_launcher_round.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_foreground.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xxhdpi/ic_launcher_round.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_foreground.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/mipmap-xxxhdpi/ic_launcher_round.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/android/values/ic_launcher_background.xml +4 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/icon.icns +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/icon.ico +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/icon.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-20x20@1x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-20x20@2x-1.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-20x20@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-20x20@3x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-29x29@1x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-29x29@2x-1.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-29x29@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-29x29@3x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-40x40@1x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-40x40@2x-1.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-40x40@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-40x40@3x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-512@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-60x60@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-60x60@3x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-76x76@1x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-76x76@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/icons/ios/AppIcon-83.5x83.5@2x.png +0 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/native-ios/KeyCommandShim.mm +244 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/permissions/app-commands.toml +30 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/src/dock_menu.rs +208 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/src/ios_quick_actions.rs +190 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/src/lib.rs +996 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/src/main.rs +5 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/src/proxy.rs +444 -0
- painapple_code-1.0.0rc1/tauri-app/src-tauri/tauri.conf.json +39 -0
- painapple_code-1.0.0rc1/tools/backfill_cumulative_cost.py +449 -0
- painapple_code-1.0.0rc1/tools/backfill_from_shadow_git.py +414 -0
- painapple_code-1.0.0rc1/tools/benchmark-fork.fish +444 -0
- painapple_code-1.0.0rc1/tools/bundle-feature-source.sh +99 -0
- painapple_code-1.0.0rc1/tools/codemirror-entry.js +72 -0
- painapple_code-1.0.0rc1/tools/obsidian-to-excalidraw.js +76 -0
- painapple_code-1.0.0rc1/tools/package-lock.json +3098 -0
- painapple_code-1.0.0rc1/tools/package.json +50 -0
- painapple_code-1.0.0rc1/tools/personalize-devcontainer.js +169 -0
- painapple_code-1.0.0rc1/tools/prototype-builder.py +1596 -0
- painapple_code-1.0.0rc1/tools/rebuild_shadow_db.py +861 -0
- painapple_code-1.0.0rc1/tools/shortcut_dna_gen.py +606 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pAInapple Code",
|
|
3
|
+
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
|
|
4
|
+
|
|
5
|
+
// pAInapple Code itself isn't auto-installed — open a terminal and run
|
|
6
|
+
// curl -fsSL https://raw.githubusercontent.com/wrotek/painapple-code/main/features/src/painapple-code/install.sh | sudo bash
|
|
7
|
+
// (see features/src/painapple-code/README.md). The forwarded port and
|
|
8
|
+
// the VS Code settings below are everything Codespaces needs prepared
|
|
9
|
+
// up front; the rest is on-demand.
|
|
10
|
+
//
|
|
11
|
+
// Python + Node come from the official Features so npm / node-gyp /
|
|
12
|
+
// native-module builds work out of the box. (The base:ubuntu image is
|
|
13
|
+
// bare — common-utils only.)
|
|
14
|
+
"features": {
|
|
15
|
+
"ghcr.io/devcontainers/features/python:1": {},
|
|
16
|
+
"ghcr.io/devcontainers/features/node:1": {}
|
|
17
|
+
},
|
|
18
|
+
|
|
19
|
+
"forwardPorts": [8765],
|
|
20
|
+
"portsAttributes": {
|
|
21
|
+
"8765": {
|
|
22
|
+
"label": "pAInapple Code",
|
|
23
|
+
"onAutoForward": "notify",
|
|
24
|
+
"visibility": "private"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
"customizations": {
|
|
29
|
+
"vscode": {
|
|
30
|
+
"extensions": [
|
|
31
|
+
"ms-python.python",
|
|
32
|
+
"redhat.vscode-yaml"
|
|
33
|
+
],
|
|
34
|
+
// Default-hide the secondary side bar (Copilot Chat lives there).
|
|
35
|
+
// Users who want it can toggle with Ctrl+Alt+B at any time — this
|
|
36
|
+
// just keeps it out of the way on first open so the terminal has
|
|
37
|
+
// room to show the painapple-code login URL without wrapping.
|
|
38
|
+
// Setting added in VS Code 1.94 (Sept 2024).
|
|
39
|
+
"settings": {
|
|
40
|
+
"workbench.secondarySideBar.defaultVisibility": "hidden"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Deny-by-default. Only the explicit allowlist below ships into the image.
|
|
2
|
+
# Why deny-first: the repo has ~1.4GB of side projects (tauri-app/, tao/),
|
|
3
|
+
# build-time deps (top-level tools/node_modules/), local-only docs, and
|
|
4
|
+
# multiple worktrees that have no business in a runtime image.
|
|
5
|
+
*
|
|
6
|
+
|
|
7
|
+
# --- Runtime essentials ---
|
|
8
|
+
!src/
|
|
9
|
+
!requirements.txt
|
|
10
|
+
!pyproject.toml
|
|
11
|
+
!docker-entrypoint.sh
|
|
12
|
+
!README.md
|
|
13
|
+
!LICENSE
|
|
14
|
+
|
|
15
|
+
# --- Re-exclusions inside the allowlist (cruft that sneaks in via src/) ---
|
|
16
|
+
**/__pycache__/
|
|
17
|
+
**/*.pyc
|
|
18
|
+
**/.pytest_cache/
|
|
19
|
+
**/.DS_Store
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
name: Publish Docker Image
|
|
2
|
+
|
|
3
|
+
# Builds and publishes the painapple-code image to Docker Hub.
|
|
4
|
+
#
|
|
5
|
+
# Versioning scheme: SemVer — git tags shaped like vMAJOR.MINOR.PATCH
|
|
6
|
+
# (e.g. v0.1.0, v1.2.3, v1.2.3-rc1). The git tag is the single source of
|
|
7
|
+
# truth — both the Docker image tag and the pip package version
|
|
8
|
+
# (via setuptools-scm) derive from it.
|
|
9
|
+
#
|
|
10
|
+
# Triggers:
|
|
11
|
+
# - push of a tag matching v*.*.* → publishes :<tag> and :latest
|
|
12
|
+
# (pre-release tags like v0.1.0-rc1
|
|
13
|
+
# publish :<tag> and skip :latest)
|
|
14
|
+
# - workflow_dispatch → publishes :edge (does not move :latest)
|
|
15
|
+
#
|
|
16
|
+
# Required repository secrets:
|
|
17
|
+
# - DOCKERHUB_USERNAME (wrotek)
|
|
18
|
+
# - DOCKERHUB_TOKEN (Hub access token, NOT account password)
|
|
19
|
+
#
|
|
20
|
+
# Multi-arch: builds linux/amd64 + linux/arm64 via buildx + QEMU.
|
|
21
|
+
|
|
22
|
+
on:
|
|
23
|
+
push:
|
|
24
|
+
tags:
|
|
25
|
+
- "v*.*.*"
|
|
26
|
+
workflow_dispatch:
|
|
27
|
+
|
|
28
|
+
env:
|
|
29
|
+
IMAGE: docker.io/wrotek/painapple-code
|
|
30
|
+
|
|
31
|
+
jobs:
|
|
32
|
+
build-and-push:
|
|
33
|
+
runs-on: ubuntu-latest
|
|
34
|
+
permissions:
|
|
35
|
+
contents: read
|
|
36
|
+
steps:
|
|
37
|
+
# fetch-depth: 0 so setuptools-scm can `git describe` against
|
|
38
|
+
# all tags. Default shallow clone hides everything but HEAD.
|
|
39
|
+
- uses: actions/checkout@v4
|
|
40
|
+
with:
|
|
41
|
+
fetch-depth: 0
|
|
42
|
+
|
|
43
|
+
- name: Set up Python
|
|
44
|
+
uses: actions/setup-python@v5
|
|
45
|
+
with:
|
|
46
|
+
python-version: "3.12"
|
|
47
|
+
|
|
48
|
+
# Single source-of-truth version. Same value gets baked into
|
|
49
|
+
# the wheel (via SETUPTOOLS_SCM_PRETEND_VERSION_FOR_… inside
|
|
50
|
+
# the image) and surfaces as `painapple-code --version`.
|
|
51
|
+
- name: Resolve package version from git
|
|
52
|
+
id: scm
|
|
53
|
+
run: |
|
|
54
|
+
pip install --quiet 'setuptools-scm>=8'
|
|
55
|
+
version=$(python -m setuptools_scm)
|
|
56
|
+
echo "version=$version" >> "$GITHUB_OUTPUT"
|
|
57
|
+
echo "→ setuptools-scm resolved: $version"
|
|
58
|
+
|
|
59
|
+
- name: Set up QEMU
|
|
60
|
+
uses: docker/setup-qemu-action@v3
|
|
61
|
+
|
|
62
|
+
- name: Set up Buildx
|
|
63
|
+
uses: docker/setup-buildx-action@v3
|
|
64
|
+
|
|
65
|
+
- name: Log in to Docker Hub
|
|
66
|
+
uses: docker/login-action@v3
|
|
67
|
+
with:
|
|
68
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
69
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
70
|
+
|
|
71
|
+
# Tag policy:
|
|
72
|
+
# tag push v0.1.0 → :v0.1.0, :latest
|
|
73
|
+
# tag push v0.1.0-rc1 → :v0.1.0-rc1 (skip :latest)
|
|
74
|
+
# workflow_dispatch → :edge (skip :latest)
|
|
75
|
+
#
|
|
76
|
+
# type=ref,event=tag takes the tag name verbatim (keeps the
|
|
77
|
+
# leading `v`). We deliberately don't use type=semver — it
|
|
78
|
+
# would auto-emit :0.1 and :0 alias tags, which is library
|
|
79
|
+
# ergonomics we don't want for an end-user app.
|
|
80
|
+
- name: Derive image tags
|
|
81
|
+
id: meta
|
|
82
|
+
uses: docker/metadata-action@v5
|
|
83
|
+
with:
|
|
84
|
+
images: ${{ env.IMAGE }}
|
|
85
|
+
tags: |
|
|
86
|
+
type=ref,event=tag
|
|
87
|
+
type=raw,value=latest,enable=${{ startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-') }}
|
|
88
|
+
type=raw,value=edge,enable=${{ github.event_name == 'workflow_dispatch' }}
|
|
89
|
+
labels: |
|
|
90
|
+
org.opencontainers.image.version=${{ steps.scm.outputs.version }}
|
|
91
|
+
org.opencontainers.image.revision=${{ github.sha }}
|
|
92
|
+
org.opencontainers.image.created=${{ github.event.repository.updated_at }}
|
|
93
|
+
|
|
94
|
+
- name: Build and push
|
|
95
|
+
id: build
|
|
96
|
+
uses: docker/build-push-action@v6
|
|
97
|
+
with:
|
|
98
|
+
context: .
|
|
99
|
+
platforms: linux/amd64,linux/arm64
|
|
100
|
+
push: true
|
|
101
|
+
tags: ${{ steps.meta.outputs.tags }}
|
|
102
|
+
labels: ${{ steps.meta.outputs.labels }}
|
|
103
|
+
build-args: |
|
|
104
|
+
SCM_VERSION=${{ steps.scm.outputs.version }}
|
|
105
|
+
cache-from: type=gha
|
|
106
|
+
cache-to: type=gha,mode=max
|
|
107
|
+
|
|
108
|
+
smoke-test:
|
|
109
|
+
# Pulls the freshly-pushed image on a clean runner and verifies the
|
|
110
|
+
# bridge boots: /health must return HTTP 200 within 30 s. Runs only
|
|
111
|
+
# for amd64 — buildx publishes the same code for both arches, so
|
|
112
|
+
# one platform is sufficient to catch packaging regressions.
|
|
113
|
+
needs: build-and-push
|
|
114
|
+
runs-on: ubuntu-latest
|
|
115
|
+
steps:
|
|
116
|
+
- name: Pick the tag we just published
|
|
117
|
+
id: tag
|
|
118
|
+
run: |
|
|
119
|
+
if [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
|
120
|
+
echo "ref=edge" >> "$GITHUB_OUTPUT"
|
|
121
|
+
else
|
|
122
|
+
# strip refs/tags/ prefix → vMAJOR.MINOR.PATCH[-prerelease]
|
|
123
|
+
echo "ref=${GITHUB_REF#refs/tags/}" >> "$GITHUB_OUTPUT"
|
|
124
|
+
fi
|
|
125
|
+
|
|
126
|
+
- name: Boot container and curl /health
|
|
127
|
+
run: |
|
|
128
|
+
set -euo pipefail
|
|
129
|
+
IMG="${{ env.IMAGE }}:${{ steps.tag.outputs.ref }}"
|
|
130
|
+
echo "→ Pulling $IMG"
|
|
131
|
+
docker pull "$IMG"
|
|
132
|
+
|
|
133
|
+
# Workspace mount: the entrypoint refuses to start unless
|
|
134
|
+
# /workspace is non-empty. Use a one-file dir as a stand-in.
|
|
135
|
+
mkdir -p /tmp/ws && echo "smoke" > /tmp/ws/README
|
|
136
|
+
|
|
137
|
+
echo "→ Starting smoke container"
|
|
138
|
+
docker run -d --name papple-smoke \
|
|
139
|
+
-p 127.0.0.1:8765:8765 \
|
|
140
|
+
-v /tmp/ws:/workspace \
|
|
141
|
+
"$IMG"
|
|
142
|
+
|
|
143
|
+
echo "→ Waiting for /health"
|
|
144
|
+
for i in $(seq 1 30); do
|
|
145
|
+
if curl -fsS http://127.0.0.1:8765/health > /dev/null 2>&1; then
|
|
146
|
+
echo "✓ /health responded after ${i}s"
|
|
147
|
+
# Also confirm the version we shipped is the one we baked in.
|
|
148
|
+
docker exec papple-smoke python -c \
|
|
149
|
+
"import painapple_code; print('version:', painapple_code.__version__)"
|
|
150
|
+
exit 0
|
|
151
|
+
fi
|
|
152
|
+
sleep 1
|
|
153
|
+
done
|
|
154
|
+
|
|
155
|
+
echo "✗ /health never responded"
|
|
156
|
+
docker logs papple-smoke || true
|
|
157
|
+
exit 1
|
|
158
|
+
|
|
159
|
+
- name: Cleanup
|
|
160
|
+
if: always()
|
|
161
|
+
run: docker rm -f papple-smoke 2>/dev/null || true
|
|
162
|
+
|
|
163
|
+
sync-dockerhub-readme:
|
|
164
|
+
# Pushes README.dockerhub.md to the Docker Hub repo's Overview tab
|
|
165
|
+
# and updates the short description. Runs only on real SemVer tag
|
|
166
|
+
# pushes — pre-releases and :edge builds don't move the public docs.
|
|
167
|
+
#
|
|
168
|
+
# If you later want the Hub docs to track main between releases,
|
|
169
|
+
# split this into its own workflow on `push: branches: [main]` with
|
|
170
|
+
# `paths: [README.dockerhub.md]`.
|
|
171
|
+
needs: build-and-push
|
|
172
|
+
if: startsWith(github.ref, 'refs/tags/v') && !contains(github.ref, '-')
|
|
173
|
+
runs-on: ubuntu-latest
|
|
174
|
+
steps:
|
|
175
|
+
- uses: actions/checkout@v4
|
|
176
|
+
|
|
177
|
+
- name: Sync Docker Hub description
|
|
178
|
+
uses: peter-evans/dockerhub-description@v5
|
|
179
|
+
with:
|
|
180
|
+
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
181
|
+
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
|
182
|
+
repository: wrotek/painapple-code
|
|
183
|
+
short-description: "WebSocket bridge that serves a vanilla-JS PWA for Claude Code sessions"
|
|
184
|
+
readme-filepath: ./README.dockerhub.md
|
|
185
|
+
# Rewrites relative links (e.g. [LICENSE](LICENSE)) into
|
|
186
|
+
# absolute github.com URLs so they resolve on the Hub page.
|
|
187
|
+
enable-url-completion: true
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Builds the sdist + wheel and publishes them to PyPI, then creates a
|
|
4
|
+
# GitHub Release for the tag.
|
|
5
|
+
#
|
|
6
|
+
# Versioning: same scheme as docker-publish.yml — the git tag (vX.Y.Z)
|
|
7
|
+
# is the single source of truth; setuptools-scm derives the package
|
|
8
|
+
# version from it at build time.
|
|
9
|
+
#
|
|
10
|
+
# Auth: PyPI Trusted Publishing (OIDC) — no API token secrets. One-time
|
|
11
|
+
# setup on pypi.org: add a publisher for project `painapple-code` with
|
|
12
|
+
# owner: wrotek, repo: painapple-code,
|
|
13
|
+
# workflow: pypi-publish.yml, environment: pypi
|
|
14
|
+
# Pre-release tags (v1.1.0-rc1) publish to PyPI as 1.1.0rc1 (pip only
|
|
15
|
+
# installs those with --pre) and are marked pre-release on GitHub.
|
|
16
|
+
|
|
17
|
+
on:
|
|
18
|
+
push:
|
|
19
|
+
tags:
|
|
20
|
+
- "v*.*.*"
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
build:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
steps:
|
|
26
|
+
# fetch-depth: 0 so setuptools-scm can `git describe` against
|
|
27
|
+
# all tags. Default shallow clone hides everything but HEAD.
|
|
28
|
+
- uses: actions/checkout@v4
|
|
29
|
+
with:
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- name: Set up Python
|
|
33
|
+
uses: actions/setup-python@v5
|
|
34
|
+
with:
|
|
35
|
+
python-version: "3.12"
|
|
36
|
+
|
|
37
|
+
- name: Build sdist and wheel
|
|
38
|
+
run: |
|
|
39
|
+
pip install --quiet build
|
|
40
|
+
python -m build
|
|
41
|
+
ls -l dist/
|
|
42
|
+
|
|
43
|
+
# Sanity check: the version baked into the wheel must match the
|
|
44
|
+
# tag that triggered us (v1.2.3 → 1.2.3, v1.2.3-rc1 → 1.2.3rc1).
|
|
45
|
+
- name: Verify version matches tag
|
|
46
|
+
run: |
|
|
47
|
+
tag="${GITHUB_REF#refs/tags/v}"
|
|
48
|
+
expected=$(python -c "from packaging.version import Version; import sys; print(Version(sys.argv[1]))" "$tag")
|
|
49
|
+
built=$(ls dist/*.whl | sed -E 's|dist/painapple_code-([^-]+)-.*|\1|')
|
|
50
|
+
echo "tag=$expected built=$built"
|
|
51
|
+
test "$expected" = "$built"
|
|
52
|
+
|
|
53
|
+
- uses: actions/upload-artifact@v4
|
|
54
|
+
with:
|
|
55
|
+
name: dist
|
|
56
|
+
path: dist/
|
|
57
|
+
|
|
58
|
+
publish-pypi:
|
|
59
|
+
needs: build
|
|
60
|
+
runs-on: ubuntu-latest
|
|
61
|
+
environment:
|
|
62
|
+
name: pypi
|
|
63
|
+
url: https://pypi.org/p/painapple-code
|
|
64
|
+
permissions:
|
|
65
|
+
id-token: write # OIDC token for Trusted Publishing
|
|
66
|
+
steps:
|
|
67
|
+
- uses: actions/download-artifact@v4
|
|
68
|
+
with:
|
|
69
|
+
name: dist
|
|
70
|
+
path: dist/
|
|
71
|
+
|
|
72
|
+
- name: Publish to PyPI
|
|
73
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
74
|
+
|
|
75
|
+
github-release:
|
|
76
|
+
needs: publish-pypi
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
permissions:
|
|
79
|
+
contents: write
|
|
80
|
+
steps:
|
|
81
|
+
- uses: actions/download-artifact@v4
|
|
82
|
+
with:
|
|
83
|
+
name: dist
|
|
84
|
+
path: dist/
|
|
85
|
+
|
|
86
|
+
- name: Create GitHub Release
|
|
87
|
+
env:
|
|
88
|
+
GH_TOKEN: ${{ github.token }}
|
|
89
|
+
run: |
|
|
90
|
+
tag="${GITHUB_REF#refs/tags/}"
|
|
91
|
+
args=(--generate-notes --title "$tag")
|
|
92
|
+
[[ "$tag" == *-* ]] && args+=(--prerelease)
|
|
93
|
+
gh release create "$tag" dist/* \
|
|
94
|
+
--repo "${{ github.repository }}" "${args[@]}"
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
name: Release Dev Container Features
|
|
2
|
+
|
|
3
|
+
# Publishes the Dev Container Features under features/src/ to GHCR.
|
|
4
|
+
# Consumers reference them via ghcr.io/<owner>/<repo>/<feature-id>:<major>.
|
|
5
|
+
#
|
|
6
|
+
# Triggers:
|
|
7
|
+
# - push to main that touches features/**
|
|
8
|
+
# - manual dispatch (for re-publishing after a metadata-only edit)
|
|
9
|
+
|
|
10
|
+
on:
|
|
11
|
+
push:
|
|
12
|
+
branches:
|
|
13
|
+
- main
|
|
14
|
+
paths:
|
|
15
|
+
- "features/src/**"
|
|
16
|
+
- ".github/workflows/release-features.yml"
|
|
17
|
+
workflow_dispatch:
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
publish:
|
|
21
|
+
runs-on: ubuntu-latest
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
packages: write
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v4
|
|
27
|
+
|
|
28
|
+
- name: Bundle bridge source into Feature
|
|
29
|
+
run: tools/bundle-feature-source.sh --feature-only
|
|
30
|
+
|
|
31
|
+
- name: Publish Features to GHCR
|
|
32
|
+
uses: devcontainers/action@v1
|
|
33
|
+
with:
|
|
34
|
+
publish-features: "true"
|
|
35
|
+
base-path-to-features: "./features/src"
|
|
36
|
+
generate-docs: "false"
|
|
37
|
+
env:
|
|
38
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
name: Test Dev Container Features
|
|
2
|
+
|
|
3
|
+
# Runs the `devcontainer features test` harness on every PR that touches
|
|
4
|
+
# features/. Catches install.sh regressions before they ship to GHCR.
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
pull_request:
|
|
8
|
+
paths:
|
|
9
|
+
- "features/**"
|
|
10
|
+
- ".github/workflows/test-features.yml"
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
test:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
strategy:
|
|
17
|
+
fail-fast: false
|
|
18
|
+
matrix:
|
|
19
|
+
feature: [painapple-code]
|
|
20
|
+
baseImage:
|
|
21
|
+
- mcr.microsoft.com/devcontainers/base:ubuntu
|
|
22
|
+
- debian:bookworm-slim
|
|
23
|
+
steps:
|
|
24
|
+
- uses: actions/checkout@v4
|
|
25
|
+
- name: Install devcontainers CLI
|
|
26
|
+
run: npm install -g @devcontainers/cli
|
|
27
|
+
- name: Test ${{ matrix.feature }} on ${{ matrix.baseImage }}
|
|
28
|
+
run: |
|
|
29
|
+
devcontainer features test \
|
|
30
|
+
--features "${{ matrix.feature }}" \
|
|
31
|
+
--base-image "${{ matrix.baseImage }}" \
|
|
32
|
+
--project-folder . \
|
|
33
|
+
./features
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# Python virtual environment
|
|
2
|
+
venv/
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.pyc
|
|
5
|
+
|
|
6
|
+
# Python build artifacts (from `pip install -e .` or `python -m build`)
|
|
7
|
+
*.egg-info/
|
|
8
|
+
build/
|
|
9
|
+
dist/
|
|
10
|
+
|
|
11
|
+
# IDE
|
|
12
|
+
.idea/
|
|
13
|
+
.vscode/
|
|
14
|
+
*.swp
|
|
15
|
+
|
|
16
|
+
# Logs
|
|
17
|
+
*.log
|
|
18
|
+
|
|
19
|
+
# OS
|
|
20
|
+
.DS_Store
|
|
21
|
+
sessions/
|
|
22
|
+
|
|
23
|
+
# Runtime worktrees
|
|
24
|
+
.painapple-code-worktrees/
|
|
25
|
+
|
|
26
|
+
# Review metadata (per-project, not committed)
|
|
27
|
+
.code-meta/
|
|
28
|
+
|
|
29
|
+
# Test results
|
|
30
|
+
test-results/
|
|
31
|
+
|
|
32
|
+
# Node.js (root package.json is for claude CLI only, not committed)
|
|
33
|
+
node_modules/
|
|
34
|
+
package.json
|
|
35
|
+
package-lock.json
|
|
36
|
+
|
|
37
|
+
# But tools/ has its own tracked package.json & lockfile
|
|
38
|
+
!tools/package.json
|
|
39
|
+
!tools/package-lock.json
|
|
40
|
+
|
|
41
|
+
# And tauri-app/ has its own tracked package.json & lockfile (native app shell)
|
|
42
|
+
!tauri-app/package.json
|
|
43
|
+
!tauri-app/package-lock.json
|
|
44
|
+
|
|
45
|
+
# Secrets / local data
|
|
46
|
+
.env*
|
|
47
|
+
*.duckdb
|
|
48
|
+
|
|
49
|
+
# Stray screenshot dumps
|
|
50
|
+
screenshots/
|
|
51
|
+
|
|
52
|
+
# Internal agent / personal infra (not for public)
|
|
53
|
+
.claude/
|
|
54
|
+
CLAUDE.md
|
|
55
|
+
deploy.fish
|
|
56
|
+
start-server.sh
|
|
57
|
+
TODO.md
|
|
58
|
+
TODO-PROD.md
|
|
59
|
+
bugs/
|
|
60
|
+
claude-stats.fish
|
|
61
|
+
docs/
|
|
62
|
+
docs-ai/
|
|
63
|
+
ideas/
|
|
64
|
+
tests/
|
|
65
|
+
|
|
66
|
+
# Devcontainer CLI build artifact
|
|
67
|
+
.devcontainer/devcontainer-lock.json
|
|
68
|
+
|
|
69
|
+
# Generated by setuptools-scm at build time — derived from git tag.
|
|
70
|
+
src/painapple_code/_version.py
|
|
71
|
+
|
|
72
|
+
# Local tao fork carrying the iOS scene-delegate UAF patch
|
|
73
|
+
# (see tauri-app/src-tauri/Cargo.toml [patch.crates-io]).
|
|
74
|
+
tao/
|
|
75
|
+
|
|
76
|
+
# Generated by tools/bundle-feature-source.sh — mirror of features/src/painapple-code/
|
|
77
|
+
# (the canonical Feature) plus the bundled bridge source. Regenerated by the
|
|
78
|
+
# initializeCommand in .devcontainer/devcontainer.json on every build.
|
|
79
|
+
.devcontainer/painapple-code/
|
|
80
|
+
features/src/painapple-code/bridge-source/
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# syntax=docker/dockerfile:1.7
|
|
2
|
+
# Fully-qualified registry path — podman has no default registry and otherwise
|
|
3
|
+
# prompts to pick one when ~/.config/containers/registries.conf lists multiple
|
|
4
|
+
# unqualified-search-registries (quay.io / ghcr.io / docker.io). Docker ignores
|
|
5
|
+
# the prefix, so the same Dockerfile works on both runtimes.
|
|
6
|
+
FROM docker.io/library/python:3.13-slim-bookworm
|
|
7
|
+
|
|
8
|
+
# OCI image metadata — surfaces on Docker Hub / GHCR as the image's title,
|
|
9
|
+
# description, license, and "Source" link. The CI workflow overrides
|
|
10
|
+
# `revision` / `created` / `version` per build via --label.
|
|
11
|
+
LABEL org.opencontainers.image.title="painapple-code" \
|
|
12
|
+
org.opencontainers.image.description="WebSocket bridge that serves a vanilla-JS PWA for Claude Code sessions" \
|
|
13
|
+
org.opencontainers.image.source="https://github.com/wrotek/painapple-code" \
|
|
14
|
+
org.opencontainers.image.licenses="AGPL-3.0-or-later" \
|
|
15
|
+
org.opencontainers.image.vendor="wrotek"
|
|
16
|
+
|
|
17
|
+
# Disable apt's _apt sandbox user — required when building under rootless
|
|
18
|
+
# Docker with fuse-overlayfs (the unprivileged _apt UID can't write /tmp).
|
|
19
|
+
RUN echo 'APT::Sandbox::User "root";' > /etc/apt/apt.conf.d/00no-sandbox
|
|
20
|
+
|
|
21
|
+
# System deps:
|
|
22
|
+
# git — used by api_git.py and shadow_git.py
|
|
23
|
+
# curl — NodeSource bootstrap
|
|
24
|
+
# tini — clean PID 1 / signal forwarding so SIGTERM kills child claude procs
|
|
25
|
+
# fd-find — fast file enumeration for /api/files/list (.gitignore-aware).
|
|
26
|
+
# Debian ships the binary as `fdfind`; symlink to `fd` so
|
|
27
|
+
# routes/api_files.py finds it without a fallback shim.
|
|
28
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
29
|
+
ca-certificates curl git tini fd-find \
|
|
30
|
+
&& ln -s /usr/bin/fdfind /usr/local/bin/fd \
|
|
31
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
32
|
+
|
|
33
|
+
# Developer tools for the in-container terminal. The bridge exposes a PTY
|
|
34
|
+
# the user runs commands in, so a base slim image with no editor / pager /
|
|
35
|
+
# search / multiplexer is painful. Adds ~80 MB. Anything bigger (compilers,
|
|
36
|
+
# language toolchains, language servers) belongs in a user-built derived
|
|
37
|
+
# image, not the base.
|
|
38
|
+
#
|
|
39
|
+
# editors — vim, nano
|
|
40
|
+
# pagers/text — less, jq
|
|
41
|
+
# search — ripgrep (`rg`); `fd` is already installed above
|
|
42
|
+
# process/system — htop, lsof, procps (ps/top), psmisc (killall/pstree)
|
|
43
|
+
# files/inspection — tree, ncdu, file
|
|
44
|
+
# network — iproute2 (ip), iputils-ping, dnsutils (dig/nslookup),
|
|
45
|
+
# netcat-openbsd, wget, rsync, openssh-client
|
|
46
|
+
# compression — zip, unzip, xz-utils
|
|
47
|
+
# shell — zsh (default user shell), tmux, bash-completion
|
|
48
|
+
# build — make
|
|
49
|
+
# misc — git-lfs, gettext-base (envsubst)
|
|
50
|
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
|
51
|
+
vim nano \
|
|
52
|
+
less jq ripgrep \
|
|
53
|
+
htop lsof procps psmisc tree ncdu file \
|
|
54
|
+
iproute2 iputils-ping dnsutils netcat-openbsd wget rsync openssh-client \
|
|
55
|
+
zip unzip xz-utils \
|
|
56
|
+
zsh tmux bash-completion \
|
|
57
|
+
make \
|
|
58
|
+
git-lfs gettext-base \
|
|
59
|
+
&& rm -rf /var/lib/apt/lists/*
|
|
60
|
+
|
|
61
|
+
# Node.js 20 LTS + Claude Code CLI (the bridge spawns `claude` as a subprocess).
|
|
62
|
+
# Pinned to the 2.x line — each image build resolves the newest 2.x.y at
|
|
63
|
+
# build time, but the SemVer-2 ceiling protects us from a 3.0 with breaking
|
|
64
|
+
# arg/output changes. DISABLE_AUTOUPDATER stops the bundled CLI from trying
|
|
65
|
+
# to overwrite itself inside the immutable image layer at runtime, and
|
|
66
|
+
# CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC suppresses the update-check
|
|
67
|
+
# / telemetry calls that go with it.
|
|
68
|
+
ENV DISABLE_AUTOUPDATER=1 \
|
|
69
|
+
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
|
|
70
|
+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - \
|
|
71
|
+
&& apt-get install -y --no-install-recommends nodejs \
|
|
72
|
+
&& rm -rf /var/lib/apt/lists/* \
|
|
73
|
+
&& npm install -g @anthropic-ai/claude-code@2 \
|
|
74
|
+
&& npm cache clean --force
|
|
75
|
+
|
|
76
|
+
# Non-root user — override UID/GID at build time to match your host so bind mounts
|
|
77
|
+
# (notably ~/.claude) keep correct ownership: docker compose build --build-arg USER_UID=$(id -u)
|
|
78
|
+
ARG USER_UID=1000
|
|
79
|
+
ARG USER_GID=1000
|
|
80
|
+
RUN groupadd --gid ${USER_GID} app \
|
|
81
|
+
&& useradd --uid ${USER_UID} --gid ${USER_GID} --create-home --shell /usr/bin/zsh app
|
|
82
|
+
|
|
83
|
+
WORKDIR /app
|
|
84
|
+
|
|
85
|
+
COPY requirements.txt ./
|
|
86
|
+
RUN pip install --no-cache-dir -r requirements.txt
|
|
87
|
+
|
|
88
|
+
# --chown collapses what used to be COPY + a separate `RUN chown -R app:app`
|
|
89
|
+
# layer that duplicated every file (~1GB rewritten just to flip metadata).
|
|
90
|
+
COPY --chown=app:app . /app
|
|
91
|
+
|
|
92
|
+
# Package version — setuptools-scm normally derives this from `git describe`,
|
|
93
|
+
# but .git is excluded from the build context (see .dockerignore), so we
|
|
94
|
+
# pass it in as a build arg and let setuptools-scm read it from the env.
|
|
95
|
+
# CI populates it from the git tag; local builds without --build-arg fall
|
|
96
|
+
# back to "0.0.0+docker".
|
|
97
|
+
ARG SCM_VERSION=0.0.0+docker
|
|
98
|
+
ENV SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PAINAPPLE_CODE=${SCM_VERSION}
|
|
99
|
+
|
|
100
|
+
# Editable install registers the painapple_code package against /app/src so
|
|
101
|
+
# `python -m painapple_code` resolves correctly without setting PYTHONPATH.
|
|
102
|
+
RUN pip install --no-cache-dir -e .
|
|
103
|
+
|
|
104
|
+
# Mountpoints — created up-front so volume mounts inherit the right ownership.
|
|
105
|
+
# /workspace gets a sentinel file that the entrypoint script checks for: any
|
|
106
|
+
# real bind mount overlays it, so its presence means the user forgot to mount.
|
|
107
|
+
RUN mkdir -p /data /workspace /home/app/.claude /home/app/.config/painapple-code \
|
|
108
|
+
&& touch /workspace/.painapple-not-mounted \
|
|
109
|
+
&& chown -R app:app /data /workspace /home/app/.claude /home/app/.config
|
|
110
|
+
|
|
111
|
+
# Entrypoint guard — refuses to start if /workspace isn't bind-mounted.
|
|
112
|
+
COPY --chmod=755 docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
|
|
113
|
+
|
|
114
|
+
USER app
|
|
115
|
+
|
|
116
|
+
# Install user-scoped helpers — same script a host install would run.
|
|
117
|
+
# Drops tools/shadow-git and tools/shadow-query into ~/.local/bin and the
|
|
118
|
+
# shadow-git-helper agent template into ~/.claude/agents, so users get
|
|
119
|
+
# `shadow-git` / `shadow-query` in the in-container terminal and the agent shows
|
|
120
|
+
# up inside Claude Code without a separate setup step.
|
|
121
|
+
RUN /app/src/painapple_code/tools/install-helpers.sh
|
|
122
|
+
|
|
123
|
+
# zsh config — the bridge spawns its PTY via $SHELL (see
|
|
124
|
+
# routes/api_terminal.py), so an interactive terminal opened in the web UI
|
|
125
|
+
# lands in zsh. Bake a couple of conveniences in.
|
|
126
|
+
RUN printf '%s\n' \
|
|
127
|
+
'alias ll="ls -lahtr"' \
|
|
128
|
+
'autoload -Uz promptinit && promptinit && prompt adam1 2>/dev/null || PROMPT="%n@%m %~ %# "' \
|
|
129
|
+
'setopt HIST_IGNORE_DUPS SHARE_HISTORY' \
|
|
130
|
+
'HISTFILE=~/.zsh_history HISTSIZE=10000 SAVEHIST=10000' \
|
|
131
|
+
> /home/app/.zshrc
|
|
132
|
+
|
|
133
|
+
# Mirror the alias for bash too, in case a script or `docker exec` lands
|
|
134
|
+
# the user there explicitly.
|
|
135
|
+
RUN echo "alias ll='ls -lahtr'" >> /home/app/.bashrc
|
|
136
|
+
|
|
137
|
+
# PAINAPPLE_CODE_HOME relocates all bridge state (logs, shadow DB, sessions,
|
|
138
|
+
# uploads, presets) to /data so a single named volume covers everything.
|
|
139
|
+
# SHELL is read by the bridge's PTY spawn (routes/api_terminal.py) — set it
|
|
140
|
+
# explicitly so the web terminal opens zsh even though the bridge process
|
|
141
|
+
# itself wasn't started via login(1).
|
|
142
|
+
# PAINAPPLE_IN_CONTAINER marks "running containerized" — a build-time constant
|
|
143
|
+
# (the image only ever runs in a container). It's a last-resort fallback in
|
|
144
|
+
# bridge_paths.detect_environment(); the docker-vs-podman decision is made at
|
|
145
|
+
# runtime from /.dockerenv vs /run/.containerenv, NOT from this marker — a baked
|
|
146
|
+
# ENV can't tell the two apart since the same image runs on both engines.
|
|
147
|
+
ENV PAINAPPLE_CODE_HOME=/data \
|
|
148
|
+
PYTHONUNBUFFERED=1 \
|
|
149
|
+
SHELL=/usr/bin/zsh \
|
|
150
|
+
PAINAPPLE_IN_CONTAINER=1
|
|
151
|
+
|
|
152
|
+
EXPOSE 8765
|
|
153
|
+
|
|
154
|
+
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/docker-entrypoint.sh"]
|
|
155
|
+
CMD ["python", "-m", "painapple_code", "--host", "0.0.0.0", "--port", "8765", "--workspace", "/workspace"]
|