painapple-code 1.0.0__py3-none-any.whl
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/__init__.py +30 -0
- painapple_code/__main__.py +18 -0
- painapple_code/_version.py +24 -0
- painapple_code/auth_middleware.py +930 -0
- painapple_code/cli/__init__.py +204 -0
- painapple_code/cli/deploy/__init__.py +15 -0
- painapple_code/cli/deploy/claude_seed.py +41 -0
- painapple_code/cli/deploy/config.py +260 -0
- painapple_code/cli/deploy/container.py +715 -0
- painapple_code/cli/deploy/launch.py +163 -0
- painapple_code/cli/deploy/runtime.py +223 -0
- painapple_code/cli/lifecycle_cmd.py +443 -0
- painapple_code/cli/list_cmd.py +572 -0
- painapple_code/cli/manage_cmd.py +670 -0
- painapple_code/cli/netinfo.py +125 -0
- painapple_code/cli/profiles.py +390 -0
- painapple_code/cli/serve_args.py +163 -0
- painapple_code/cli/serve_config.py +256 -0
- painapple_code/cli/setup_cmd.py +664 -0
- painapple_code/cli/ui.py +438 -0
- painapple_code/cost_analytics.py +879 -0
- painapple_code/data/models.defaults.yaml +18 -0
- painapple_code/data/models.yaml +18 -0
- painapple_code/data/presets.defaults.json +32 -0
- painapple_code/data/strings.yaml +2269 -0
- painapple_code/helpers.py +406 -0
- painapple_code/paths.py +1514 -0
- painapple_code/prompt_explorer.py +984 -0
- painapple_code/providers/__init__.py +224 -0
- painapple_code/providers/base.py +710 -0
- painapple_code/providers/claude/__init__.py +74 -0
- painapple_code/providers/claude/capabilities.py +218 -0
- painapple_code/providers/claude/errors.py +79 -0
- painapple_code/providers/claude/launch.py +50 -0
- painapple_code/providers/claude/summary.py +89 -0
- painapple_code/providers/claude/translate.py +74 -0
- painapple_code/providers/claude_sdk/__init__.py +139 -0
- painapple_code/providers/claude_sdk/driver.py +412 -0
- painapple_code/providers/codex/__init__.py +87 -0
- painapple_code/providers/codex/capabilities.py +321 -0
- painapple_code/providers/codex/errors.py +70 -0
- painapple_code/providers/codex/launch.py +142 -0
- painapple_code/providers/codex/summary.py +196 -0
- painapple_code/providers/codex/translate.py +204 -0
- painapple_code/providers/codex_app_server/__init__.py +100 -0
- painapple_code/providers/codex_app_server/capabilities.py +41 -0
- painapple_code/providers/codex_app_server/launch.py +202 -0
- painapple_code/providers/codex_app_server/summary.py +291 -0
- painapple_code/providers/codex_app_server/translate.py +263 -0
- painapple_code/providers/codex_app_server/transport.py +238 -0
- painapple_code/routes/__init__.py +0 -0
- painapple_code/routes/api_agents.py +441 -0
- painapple_code/routes/api_app.py +368 -0
- painapple_code/routes/api_app_commit_sections.py +127 -0
- painapple_code/routes/api_app_config.py +997 -0
- painapple_code/routes/api_app_session_prefs.py +217 -0
- painapple_code/routes/api_browser.py +690 -0
- painapple_code/routes/api_commands.py +374 -0
- painapple_code/routes/api_costs.py +128 -0
- painapple_code/routes/api_drafts.py +139 -0
- painapple_code/routes/api_exec.py +149 -0
- painapple_code/routes/api_files.py +542 -0
- painapple_code/routes/api_git.py +657 -0
- painapple_code/routes/api_logs.py +649 -0
- painapple_code/routes/api_plugins.py +275 -0
- painapple_code/routes/api_project_config.py +418 -0
- painapple_code/routes/api_prompts.py +231 -0
- painapple_code/routes/api_providers.py +53 -0
- painapple_code/routes/api_search.py +411 -0
- painapple_code/routes/api_session_stash.py +234 -0
- painapple_code/routes/api_session_welcome.py +151 -0
- painapple_code/routes/api_sessions.py +742 -0
- painapple_code/routes/api_shadow.py +323 -0
- painapple_code/routes/api_shadow_db.py +512 -0
- painapple_code/routes/api_shadow_files.py +332 -0
- painapple_code/routes/api_shadow_search.py +476 -0
- painapple_code/routes/api_skills.py +610 -0
- painapple_code/routes/api_tasks.py +147 -0
- painapple_code/routes/api_terminal.py +540 -0
- painapple_code/routes/api_upload.py +293 -0
- painapple_code/routes/api_viewer.py +229 -0
- painapple_code/routes/dependencies.py +109 -0
- painapple_code/routes/ws_chat.py +837 -0
- painapple_code/server.py +2208 -0
- painapple_code/server_logging.py +263 -0
- painapple_code/services/__init__.py +0 -0
- painapple_code/services/agent_session.py +2738 -0
- painapple_code/session_store.py +253 -0
- painapple_code/session_store_core.py +879 -0
- painapple_code/shadow_db.py +830 -0
- painapple_code/shadow_db_plans.py +369 -0
- painapple_code/shadow_db_queries.py +595 -0
- painapple_code/shadow_db_schema.py +676 -0
- painapple_code/shadow_git.py +1296 -0
- painapple_code/shadow_git_frontmatter.py +314 -0
- painapple_code/shadow_git_sections.py +520 -0
- painapple_code/shadow_git_summary.py +462 -0
- painapple_code/shadow_parser.py +560 -0
- painapple_code/static/css/00-variables.css +276 -0
- painapple_code/static/css/01-base.css +245 -0
- painapple_code/static/css/02-tooltips.css +36 -0
- painapple_code/static/css/09-left-rail.css +448 -0
- painapple_code/static/css/10-header.css +777 -0
- painapple_code/static/css/11-connection-bar.css +120 -0
- painapple_code/static/css/20-messages.css +750 -0
- painapple_code/static/css/21-tool-blocks.css +2340 -0
- painapple_code/static/css/22-edit-diff.css +619 -0
- painapple_code/static/css/23-thinking.css +1584 -0
- painapple_code/static/css/24-background-tasks.css +359 -0
- painapple_code/static/css/25-context-block.css +252 -0
- painapple_code/static/css/26-session-setup.css +144 -0
- painapple_code/static/css/30-markdown.css +854 -0
- painapple_code/static/css/40-input.css +2418 -0
- painapple_code/static/css/41-autocomplete.css +127 -0
- painapple_code/static/css/42-activity-strip.css +97 -0
- painapple_code/static/css/43-file-autocomplete.css +121 -0
- painapple_code/static/css/44-snippets-autocomplete.css +224 -0
- painapple_code/static/css/45-selection-bar.css +433 -0
- painapple_code/static/css/46-keyboard-bar.css +119 -0
- painapple_code/static/css/47-keyboard-longpress.css +116 -0
- painapple_code/static/css/47-token-profile.css +106 -0
- painapple_code/static/css/50-welcome.css +3095 -0
- painapple_code/static/css/51-modals.css +301 -0
- painapple_code/static/css/52-utilities.css +77 -0
- painapple_code/static/css/53-image-upload.css +456 -0
- painapple_code/static/css/54-todo-list.css +102 -0
- painapple_code/static/css/55-file-upload.css +113 -0
- painapple_code/static/css/56-chat-navigator.css +218 -0
- painapple_code/static/css/56-permission-card.css +332 -0
- painapple_code/static/css/56-plan-approval.css +204 -0
- painapple_code/static/css/56-question-form.css +602 -0
- painapple_code/static/css/57-swipe-indicator.css +95 -0
- painapple_code/static/css/58-session-families.css +627 -0
- painapple_code/static/css/59-about.css +196 -0
- painapple_code/static/css/61-log-explorer.css +723 -0
- painapple_code/static/css/62-json-tree.css +489 -0
- painapple_code/static/css/62-skills-widget.css +650 -0
- painapple_code/static/css/63-commands-widget.css +30 -0
- painapple_code/static/css/63-plugins-widget.css +174 -0
- painapple_code/static/css/63-terminal.css +516 -0
- painapple_code/static/css/64-search-files-widget.css +448 -0
- painapple_code/static/css/65-snippets-widget.css +426 -0
- painapple_code/static/css/66-active-sessions.css +979 -0
- painapple_code/static/css/66-agents-widget.css +265 -0
- painapple_code/static/css/66-file-explorer-widget.css +855 -0
- painapple_code/static/css/66-git-panel.css +791 -0
- painapple_code/static/css/66-history-explorer.css +1496 -0
- painapple_code/static/css/67-diff-viewer.css +602 -0
- painapple_code/static/css/67-editor-view.css +748 -0
- painapple_code/static/css/67-file-preview-widget.css +1873 -0
- painapple_code/static/css/68-browser-widget.css +337 -0
- painapple_code/static/css/68-compare-wizard.css +355 -0
- painapple_code/static/css/68-csv-preview.css +106 -0
- painapple_code/static/css/68-diff-preview.css +103 -0
- painapple_code/static/css/68-helpers-install-widget.css +491 -0
- painapple_code/static/css/68-image-annotate.css +346 -0
- painapple_code/static/css/68-terminal-view.css +98 -0
- painapple_code/static/css/68-uploads-widget.css +229 -0
- painapple_code/static/css/69-cost-analytics.css +537 -0
- painapple_code/static/css/70-config-panel.css +3736 -0
- painapple_code/static/css/70-excalidraw.css +136 -0
- painapple_code/static/css/70-prompt-explorer.css +890 -0
- painapple_code/static/css/71-chart.css +111 -0
- painapple_code/static/css/72-discussion-sidebar.css +678 -0
- painapple_code/static/css/74-debug-logs.css +656 -0
- painapple_code/static/css/80-open-dialog.css +146 -0
- painapple_code/static/css/80-quick-switcher.css +383 -0
- painapple_code/static/css/80-widget-system.css +1763 -0
- painapple_code/static/css/81-quick-actions.css +1020 -0
- painapple_code/static/css/82-context-popover.css +1233 -0
- painapple_code/static/css/83-context-menu.css +339 -0
- painapple_code/static/css/85-lazy-loading.css +102 -0
- painapple_code/static/css/86-zen-mode.css +708 -0
- painapple_code/static/css/87-grid-switcher.css +346 -0
- painapple_code/static/css/login.css +198 -0
- painapple_code/static/dist/app.bundle.js +7177 -0
- painapple_code/static/feature-triage.html +446 -0
- painapple_code/static/icons/apple-touch-icon.png +0 -0
- painapple_code/static/icons/favicon-32.png +0 -0
- painapple_code/static/icons/favicon.ico +0 -0
- painapple_code/static/icons/icon-128.png +0 -0
- painapple_code/static/icons/icon-144.png +0 -0
- painapple_code/static/icons/icon-152.png +0 -0
- painapple_code/static/icons/icon-180.png +0 -0
- painapple_code/static/icons/icon-192.png +0 -0
- painapple_code/static/icons/icon-384.png +0 -0
- painapple_code/static/icons/icon-512.png +0 -0
- painapple_code/static/icons/icon-72.png +0 -0
- painapple_code/static/icons/icon-96.png +0 -0
- painapple_code/static/js/action-delegate.js +187 -0
- painapple_code/static/js/activity-strip.js +193 -0
- painapple_code/static/js/app/context-menus.js +619 -0
- painapple_code/static/js/app/file-preview.js +163 -0
- painapple_code/static/js/app/init-ui.js +574 -0
- painapple_code/static/js/app/input-events.js +561 -0
- painapple_code/static/js/app/input-resize.js +313 -0
- painapple_code/static/js/app/message-actions.js +419 -0
- painapple_code/static/js/app/panels.js +210 -0
- painapple_code/static/js/app/rendering-delegators.js +246 -0
- painapple_code/static/js/app/server-loading.js +365 -0
- painapple_code/static/js/app/session-ops.js +287 -0
- painapple_code/static/js/app/session-switch.js +443 -0
- painapple_code/static/js/app/settings-helpers.js +280 -0
- painapple_code/static/js/app/startup-welcome.js +290 -0
- painapple_code/static/js/app-context.js +157 -0
- painapple_code/static/js/app.js +2134 -0
- painapple_code/static/js/auth-fetch.js +46 -0
- painapple_code/static/js/background-tasks.js +274 -0
- painapple_code/static/js/boot.js +73 -0
- painapple_code/static/js/caret-position.js +171 -0
- painapple_code/static/js/chat-navigator.js +710 -0
- painapple_code/static/js/chat-search.js +323 -0
- painapple_code/static/js/command-executor.js +176 -0
- painapple_code/static/js/command-store.js +497 -0
- painapple_code/static/js/components.js +1414 -0
- painapple_code/static/js/config.js +218 -0
- painapple_code/static/js/context-menu.js +740 -0
- painapple_code/static/js/controllers/chat-controller.js +4252 -0
- painapple_code/static/js/controllers/dialog-controller.js +217 -0
- painapple_code/static/js/controllers/tab-controller.js +1828 -0
- painapple_code/static/js/controllers/thinking-controller.js +915 -0
- painapple_code/static/js/diff-utils.js +486 -0
- painapple_code/static/js/drafts-pill.js +95 -0
- painapple_code/static/js/editor-view.js +815 -0
- painapple_code/static/js/effort-settings.js +430 -0
- painapple_code/static/js/feature-triage.js +811 -0
- painapple_code/static/js/file-autocomplete.js +516 -0
- painapple_code/static/js/file-tabs.js +123 -0
- painapple_code/static/js/gestures.js +448 -0
- painapple_code/static/js/grid-switcher.js +334 -0
- painapple_code/static/js/input-handler.js +1472 -0
- painapple_code/static/js/keyboard-bar.js +495 -0
- painapple_code/static/js/layout-switcher.js +109 -0
- painapple_code/static/js/linkify-utils.js +200 -0
- painapple_code/static/js/login.js +141 -0
- painapple_code/static/js/open-dialog.js +879 -0
- painapple_code/static/js/orphan-terminals.js +373 -0
- painapple_code/static/js/path-utils.js +179 -0
- painapple_code/static/js/perf-marks.js +102 -0
- painapple_code/static/js/permission-settings.js +475 -0
- painapple_code/static/js/pointer-input.js +59 -0
- painapple_code/static/js/preview/json-tree-menu.js +226 -0
- painapple_code/static/js/preview/json-tree-toolbar.js +291 -0
- painapple_code/static/js/preview/json-tree.js +457 -0
- painapple_code/static/js/preview/preview-breadcrumb.js +387 -0
- painapple_code/static/js/preview/preview-edit.js +367 -0
- painapple_code/static/js/preview/preview-events.js +361 -0
- painapple_code/static/js/preview/preview-history.js +567 -0
- painapple_code/static/js/preview/preview-inline-edit.js +869 -0
- painapple_code/static/js/preview/preview-poll.js +108 -0
- painapple_code/static/js/preview/preview-render.js +572 -0
- painapple_code/static/js/preview/preview-search.js +421 -0
- painapple_code/static/js/preview/preview-state.js +256 -0
- painapple_code/static/js/preview/preview-utils.js +251 -0
- painapple_code/static/js/preview-plugins/chart-plugin.js +22 -0
- painapple_code/static/js/preview-plugins/csv-plugin.js +188 -0
- painapple_code/static/js/preview-plugins/diff-plugin.js +258 -0
- painapple_code/static/js/preview-plugins/excalidraw-plugin.js +25 -0
- painapple_code/static/js/preview-plugins/html-plugin.js +104 -0
- painapple_code/static/js/preview-plugins/image-plugin.js +20 -0
- painapple_code/static/js/preview-plugins/index.js +34 -0
- painapple_code/static/js/preview-plugins/json-plugin.js +99 -0
- painapple_code/static/js/preview-plugins/jsonl-plugin.js +152 -0
- painapple_code/static/js/preview-plugins/markdown-plugin.js +266 -0
- painapple_code/static/js/preview-plugins/panzoom-plugin.js +63 -0
- painapple_code/static/js/preview-plugins/plugin-helpers.js +282 -0
- painapple_code/static/js/project-color-picker.js +110 -0
- painapple_code/static/js/project-colors.js +163 -0
- painapple_code/static/js/prompt-favorites.js +187 -0
- painapple_code/static/js/quick-actions-menu.js +1736 -0
- painapple_code/static/js/quick-actions-registry.js +1239 -0
- painapple_code/static/js/quick-switcher/controller.js +294 -0
- painapple_code/static/js/quick-switcher/fuzzy-scorer.js +123 -0
- painapple_code/static/js/quick-switcher/index.js +30 -0
- painapple_code/static/js/quick-switcher/providers/base-provider.js +51 -0
- painapple_code/static/js/quick-switcher/providers/command-provider.js +56 -0
- painapple_code/static/js/quick-switcher/providers/file-provider.js +291 -0
- painapple_code/static/js/quick-switcher/providers/panel-provider.js +132 -0
- painapple_code/static/js/quick-switcher/providers/project-provider.js +361 -0
- painapple_code/static/js/quick-switcher/providers/read-files-provider.js +104 -0
- painapple_code/static/js/quick-switcher/providers/skills-provider.js +129 -0
- painapple_code/static/js/quick-switcher/registry.js +69 -0
- painapple_code/static/js/quick-switcher/ui/item.js +54 -0
- painapple_code/static/js/quick-switcher/ui/picker.js +464 -0
- painapple_code/static/js/recent-opens.js +40 -0
- painapple_code/static/js/scroll-manager.js +530 -0
- painapple_code/static/js/scroll-state-machine.js +359 -0
- painapple_code/static/js/selection/action-bar.js +793 -0
- painapple_code/static/js/selection/index.js +15 -0
- painapple_code/static/js/selection/selection-handler.js +877 -0
- painapple_code/static/js/selection/state.js +181 -0
- painapple_code/static/js/session/agent-progress.js +202 -0
- painapple_code/static/js/session/handle-agent-message.js +481 -0
- painapple_code/static/js/session/handle-message.js +550 -0
- painapple_code/static/js/session/interactive.js +587 -0
- painapple_code/static/js/session/message-store.js +271 -0
- painapple_code/static/js/session/messages.js +253 -0
- painapple_code/static/js/session/persistence.js +179 -0
- painapple_code/static/js/session/restore.js +136 -0
- painapple_code/static/js/session/sync.js +333 -0
- painapple_code/static/js/session-container-pool.js +371 -0
- painapple_code/static/js/session-setup-panel.js +274 -0
- painapple_code/static/js/session.js +1047 -0
- painapple_code/static/js/shortcut-hints.js +272 -0
- painapple_code/static/js/shortcuts.js +1146 -0
- painapple_code/static/js/skills-autocomplete.js +262 -0
- painapple_code/static/js/snippets-autocomplete.js +738 -0
- painapple_code/static/js/stash-refs-view.js +83 -0
- painapple_code/static/js/stash-ui.js +768 -0
- painapple_code/static/js/stash.js +785 -0
- painapple_code/static/js/status-bar.js +1184 -0
- painapple_code/static/js/token-profile.js +274 -0
- painapple_code/static/js/tool-renderer-blocks.js +1626 -0
- painapple_code/static/js/tool-renderer-thinking.js +813 -0
- painapple_code/static/js/tool-renderer.js +1500 -0
- painapple_code/static/js/tooltips.js +197 -0
- painapple_code/static/js/upload-manager.js +1019 -0
- painapple_code/static/js/utils.js +521 -0
- painapple_code/static/js/welcome/api.js +363 -0
- painapple_code/static/js/welcome/cards.js +626 -0
- painapple_code/static/js/welcome/context-menu.js +585 -0
- painapple_code/static/js/welcome/families.js +801 -0
- painapple_code/static/js/welcome/preview.js +234 -0
- painapple_code/static/js/welcome/state.js +129 -0
- painapple_code/static/js/welcome.js +1874 -0
- painapple_code/static/js/widget-system/base-widget.js +717 -0
- painapple_code/static/js/widget-system/device-manager.js +178 -0
- painapple_code/static/js/widget-system/event-bus.js +152 -0
- painapple_code/static/js/widget-system/icons.js +120 -0
- painapple_code/static/js/widget-system/index.js +49 -0
- painapple_code/static/js/widget-system/init.js +54 -0
- painapple_code/static/js/widget-system/types/bottom-sheet.js +307 -0
- painapple_code/static/js/widget-system/types/floating.js +915 -0
- painapple_code/static/js/widget-system/types/index.js +40 -0
- painapple_code/static/js/widget-system/types/modal.js +147 -0
- painapple_code/static/js/widget-system/types/sidebar.js +158 -0
- painapple_code/static/js/widget-system/types/tab.js +146 -0
- painapple_code/static/js/widget-system/types/top-sheet.js +203 -0
- painapple_code/static/js/widget-system/widget-manager.js +1187 -0
- painapple_code/static/js/widgets/about-widget.js +260 -0
- painapple_code/static/js/widgets/active-sessions-widget.js +760 -0
- painapple_code/static/js/widgets/agents-widget.js +897 -0
- painapple_code/static/js/widgets/browser-widget.js +579 -0
- painapple_code/static/js/widgets/commands-widget.js +694 -0
- painapple_code/static/js/widgets/config/commit-sections.js +449 -0
- painapple_code/static/js/widgets/config/dir-autocomplete.js +224 -0
- painapple_code/static/js/widgets/config/gestures.js +161 -0
- painapple_code/static/js/widgets/config/models-tab.js +988 -0
- painapple_code/static/js/widgets/config/quick-actions-tab.js +882 -0
- painapple_code/static/js/widgets/config/shortcut-editor.js +587 -0
- painapple_code/static/js/widgets/config/state.js +517 -0
- painapple_code/static/js/widgets/config/system-controls.js +90 -0
- painapple_code/static/js/widgets/config-widget.js +1535 -0
- painapple_code/static/js/widgets/cost-analytics-widget.js +621 -0
- painapple_code/static/js/widgets/debug-widget.js +693 -0
- painapple_code/static/js/widgets/diff-viewer-widget.js +1420 -0
- painapple_code/static/js/widgets/discussion-widget.js +1107 -0
- painapple_code/static/js/widgets/file-explorer-widget.js +2166 -0
- painapple_code/static/js/widgets/file-preview-widget.js +861 -0
- painapple_code/static/js/widgets/git-widget.js +794 -0
- painapple_code/static/js/widgets/helpers-install-widget.js +720 -0
- painapple_code/static/js/widgets/history-explorer-widget.js +1804 -0
- painapple_code/static/js/widgets/image-annotate-widget.js +951 -0
- painapple_code/static/js/widgets/image-preview-widget.js +692 -0
- painapple_code/static/js/widgets/index.js +176 -0
- painapple_code/static/js/widgets/log-explorer-widget.js +1057 -0
- painapple_code/static/js/widgets/plugins-widget.js +305 -0
- painapple_code/static/js/widgets/prompt-explorer-widget.js +1119 -0
- painapple_code/static/js/widgets/search-files-widget.js +529 -0
- painapple_code/static/js/widgets/skills-widget.js +843 -0
- painapple_code/static/js/widgets/snippets-widget.js +479 -0
- painapple_code/static/js/widgets/sub-agents-widget.js +333 -0
- painapple_code/static/js/widgets/tasks-widget.js +379 -0
- painapple_code/static/js/widgets/terminal/connection.js +283 -0
- painapple_code/static/js/widgets/terminal/gestures.js +357 -0
- painapple_code/static/js/widgets/terminal/init.js +642 -0
- painapple_code/static/js/widgets/terminal/link-providers.js +532 -0
- painapple_code/static/js/widgets/terminal/osc52.js +213 -0
- painapple_code/static/js/widgets/terminal/render.js +159 -0
- painapple_code/static/js/widgets/terminal/size.js +54 -0
- painapple_code/static/js/widgets/terminal/state.js +211 -0
- painapple_code/static/js/widgets/terminal/wrap-utils.js +101 -0
- painapple_code/static/js/widgets/terminal-widget.js +793 -0
- painapple_code/static/js/widgets/uploads-widget.js +461 -0
- painapple_code/static/js/widgets/zen-widget.js +1001 -0
- painapple_code/static/login.html +51 -0
- painapple_code/static/manifest.json +73 -0
- painapple_code/static/sw.js +293 -0
- painapple_code/static/vendor/LICENSES.txt +769 -0
- painapple_code/static/vendor/README.md +103 -0
- painapple_code/static/vendor/codemirror.js +35 -0
- painapple_code/static/vendor/codemirror.js.LEGAL.txt +304 -0
- painapple_code/static/vendor/github-markdown-dark.min.css +1124 -0
- painapple_code/static/vendor/highlight-github-dark.min.css +10 -0
- painapple_code/static/vendor/highlight-lang-dockerfile.min.js +8 -0
- painapple_code/static/vendor/highlight-lang-nginx.min.js +21 -0
- painapple_code/static/vendor/highlight-lang-properties.min.js +10 -0
- painapple_code/static/vendor/highlight-lang-scala.min.js +28 -0
- painapple_code/static/vendor/highlight.min.js +1213 -0
- painapple_code/static/vendor/marked.min.js +6 -0
- painapple_code/static/vendor/purify.min.js +3 -0
- painapple_code/static/vendor/xterm-addon-fit.js +2 -0
- painapple_code/static/vendor/xterm.css +209 -0
- painapple_code/static/vendor/xterm.js +2 -0
- painapple_code/static/web-client.html +635 -0
- painapple_code/subprocess_registry.py +535 -0
- painapple_code/tls_cert.py +79 -0
- painapple_code/tools/agents/shadow-git-helper.md +400 -0
- painapple_code/tools/excalidraw-to-svg.js +143 -0
- painapple_code/tools/install-helpers.sh +148 -0
- painapple_code/tools/shadow-git +320 -0
- painapple_code/tools/shadow-query +120 -0
- painapple_code/tools/vegalite-to-svg.js +79 -0
- painapple_code/turn_query.py +766 -0
- painapple_code/turn_tracker.py +221 -0
- painapple_code/utils/__init__.py +0 -0
- painapple_code/utils/agent_cli.py +306 -0
- painapple_code/utils/chart.py +103 -0
- painapple_code/utils/excalidraw.py +107 -0
- painapple_code/utils/file_lock.py +162 -0
- painapple_code/utils/file_paths.py +648 -0
- painapple_code/utils/generate_icons.py +251 -0
- painapple_code/utils/proc.py +205 -0
- painapple_code/utils/pty_backend.py +59 -0
- painapple_code/utils/pty_posix.py +160 -0
- painapple_code/utils/pty_windows.py +245 -0
- painapple_code/utils/token_profiles.py +91 -0
- painapple_code/viewer_templates.py +657 -0
- painapple_code/welcome_search.py +879 -0
- painapple_code-1.0.0.dist-info/METADATA +292 -0
- painapple_code-1.0.0.dist-info/RECORD +436 -0
- painapple_code-1.0.0.dist-info/WHEEL +5 -0
- painapple_code-1.0.0.dist-info/entry_points.txt +2 -0
- painapple_code-1.0.0.dist-info/licenses/LICENSE +661 -0
- painapple_code-1.0.0.dist-info/licenses/THIRD_PARTY_NOTICES.md +261 -0
- painapple_code-1.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Shadow Git - Configurable commit sections.
|
|
3
|
+
|
|
4
|
+
The section definitions in `BUILTIN_SECTIONS` drive what the summary fork emits in
|
|
5
|
+
each rich commit: each entry becomes a key in the JSON schema fed to the model
|
|
6
|
+
and a `## Title` block in the resulting markdown commit body. Users can extend
|
|
7
|
+
or override sections via per-project config (`shadow_git.commit_sections`).
|
|
8
|
+
|
|
9
|
+
Public functions (consumed by ShadowGit and `routes/api_app_commit_sections.py`):
|
|
10
|
+
- `get_sections_config` — merge builtins with user overrides
|
|
11
|
+
- `build_commit_schema` — JSON schema for `--json-schema` output mode
|
|
12
|
+
- `build_commit_prompt_for_json` — natural-language prompt that mirrors the schema
|
|
13
|
+
- `structured_to_markdown` — render the summary fork's JSON response back into commit-body markdown
|
|
14
|
+
|
|
15
|
+
Also exposes `COMMIT_PROMPT_COMPACTION` — the prompt used when capturing a
|
|
16
|
+
compaction-checkpoint commit (no schema; freeform text).
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
# Built-in sections that users can enable/disable but not delete
|
|
20
|
+
# Each section has:
|
|
21
|
+
# - id: unique identifier (used in config)
|
|
22
|
+
# - title: markdown header (## Title)
|
|
23
|
+
# - prompt: instructions for the summarizer
|
|
24
|
+
# - required: if True, cannot be disabled
|
|
25
|
+
# - default_enabled: initial state
|
|
26
|
+
# - order: default sort order (10, 20, 30...)
|
|
27
|
+
# - applies_to: list of prompt types ["file_changes", "tool_only"]
|
|
28
|
+
|
|
29
|
+
BUILTIN_SECTIONS = {
|
|
30
|
+
"summary": {
|
|
31
|
+
"id": "summary",
|
|
32
|
+
"title": "Summary",
|
|
33
|
+
"prompt": "ONE SENTENCE: what was accomplished this turn. Future turns will see this as journey context, so make it concrete and informative — reference earlier turns when building on them (e.g., \"Fixed the CORS issue from turn 2 by switching to Authorization headers\"). Just the sentence, no prefix.",
|
|
34
|
+
"prompt_tool_only": "ONE SENTENCE: what was investigated and the key finding. Future turns will see this as journey context, so include the discovery (e.g., \"Investigated API routing — found 12 handlers across 4 controllers, all using JWT auth\"). Just the sentence, no prefix.",
|
|
35
|
+
"required": True,
|
|
36
|
+
"default_enabled": True,
|
|
37
|
+
"order": 10,
|
|
38
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
39
|
+
},
|
|
40
|
+
"tags": {
|
|
41
|
+
"id": "tags",
|
|
42
|
+
"title": "Tags",
|
|
43
|
+
"prompt": "Searchable tags for this work. Include relevant: work type (bugfix, feature, refactor), domain (ui, api, auth), code elements (class names, functions, components), and technical concepts.",
|
|
44
|
+
"field_type": "array",
|
|
45
|
+
"required": False,
|
|
46
|
+
"default_enabled": True,
|
|
47
|
+
"order": 11,
|
|
48
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
49
|
+
},
|
|
50
|
+
"entities": {
|
|
51
|
+
"id": "entities",
|
|
52
|
+
"title": "Entities",
|
|
53
|
+
"prompt": "Named code elements referenced or modified. Format: name:type (e.g., SessionManager:class, handleClick:function, deploy:endpoint). Skip filenames — they are tracked separately. Use consistent type labels.",
|
|
54
|
+
"prompt_tool_only": "Named code elements examined or discussed. Format: name:type (e.g., SessionManager:class, handleClick:function, deploy:endpoint). Skip filenames — they are tracked separately. Use consistent type labels.",
|
|
55
|
+
"field_type": "array",
|
|
56
|
+
"required": False,
|
|
57
|
+
"default_enabled": True,
|
|
58
|
+
"order": 12,
|
|
59
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
60
|
+
},
|
|
61
|
+
"plan_title": {
|
|
62
|
+
"id": "plan_title",
|
|
63
|
+
"title": "Plan Title",
|
|
64
|
+
"prompt": "Short title (3-6 words) for the plan designed in this turn. What is being planned? Examples: 'Background Tasks Feature', 'JWT Auth Refactor', 'DuckDB Plan Tracking'. Just the title, no prefix.",
|
|
65
|
+
"required": False,
|
|
66
|
+
"default_enabled": True,
|
|
67
|
+
"order": 14,
|
|
68
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
69
|
+
"only_when_tools": ["EnterPlanMode", "ExitPlanMode"],
|
|
70
|
+
},
|
|
71
|
+
"plan_summary": {
|
|
72
|
+
"id": "plan_summary",
|
|
73
|
+
"title": "Plan Summary",
|
|
74
|
+
"prompt": "2-3 sentence summary of what this plan proposes. What problem does it solve? What's the approach? What are the key components or changes?",
|
|
75
|
+
"required": False,
|
|
76
|
+
"default_enabled": True,
|
|
77
|
+
"order": 15,
|
|
78
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
79
|
+
"only_when_tools": ["EnterPlanMode", "ExitPlanMode"],
|
|
80
|
+
},
|
|
81
|
+
"work_done": {
|
|
82
|
+
"id": "work_done",
|
|
83
|
+
"title": "Work Done",
|
|
84
|
+
"prompt": "- Bullet points of specific changes\n- Include patterns introduced or modified",
|
|
85
|
+
"required": False,
|
|
86
|
+
"default_enabled": True,
|
|
87
|
+
"order": 20,
|
|
88
|
+
"applies_to": ["file_changes"],
|
|
89
|
+
},
|
|
90
|
+
"investigation": {
|
|
91
|
+
"id": "investigation",
|
|
92
|
+
"title": "Investigation",
|
|
93
|
+
"prompt": "- What you examined and why\n- Hypothesis tested",
|
|
94
|
+
"required": False,
|
|
95
|
+
"default_enabled": True,
|
|
96
|
+
"order": 20,
|
|
97
|
+
"applies_to": ["tool_only"],
|
|
98
|
+
},
|
|
99
|
+
"findings": {
|
|
100
|
+
"id": "findings",
|
|
101
|
+
"title": "Findings",
|
|
102
|
+
"prompt": "- Key discoveries\n- Conclusions reached\n- Questions answered",
|
|
103
|
+
"required": False,
|
|
104
|
+
"default_enabled": True,
|
|
105
|
+
"order": 25,
|
|
106
|
+
"applies_to": ["tool_only"],
|
|
107
|
+
},
|
|
108
|
+
"decisions": {
|
|
109
|
+
"id": "decisions",
|
|
110
|
+
"title": "Decisions",
|
|
111
|
+
"prompt": "- Why this approach (vs alternatives considered)\n- Trade-offs made\n- Patterns chosen and why",
|
|
112
|
+
"required": False,
|
|
113
|
+
"default_enabled": True,
|
|
114
|
+
"order": 30,
|
|
115
|
+
"applies_to": ["file_changes"],
|
|
116
|
+
},
|
|
117
|
+
"problems_solved": {
|
|
118
|
+
"id": "problems_solved",
|
|
119
|
+
"title": "Problems Solved",
|
|
120
|
+
"prompt": "- What issue/bug was fixed (if any)\n- Root cause identified\n- Solution approach\n- Reference previous turns if this fixes an earlier issue",
|
|
121
|
+
"required": False,
|
|
122
|
+
"default_enabled": True,
|
|
123
|
+
"order": 40,
|
|
124
|
+
"applies_to": ["file_changes"],
|
|
125
|
+
},
|
|
126
|
+
"verification": {
|
|
127
|
+
"id": "verification",
|
|
128
|
+
"title": "Verification",
|
|
129
|
+
"prompt": "Commands to verify/test this work (only if tests/checks were run). Format: `command` - what it verifies\nExample: `pytest test_session.py::test_reconnect -v` - WebSocket reconnect\nExample: `curl localhost:8765/api/sessions | jq length` - API returns sessions\nSkip if no verification was done.",
|
|
130
|
+
"prompt_tool_only": "Commands used to investigate/verify. Format: `command` - what it checked\nExample: `curl -s localhost:8765/api/sessions | jq .` - checked API response\nSkip if no commands worth remembering.",
|
|
131
|
+
"required": False,
|
|
132
|
+
"default_enabled": True,
|
|
133
|
+
"order": 45,
|
|
134
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
135
|
+
},
|
|
136
|
+
"commands": {
|
|
137
|
+
"id": "commands",
|
|
138
|
+
"title": "Commands",
|
|
139
|
+
"prompt": (
|
|
140
|
+
"Reusable shell commands from this turn worth remembering. "
|
|
141
|
+
"Include: diagnostic one-liners, curl/API calls, build/install commands, "
|
|
142
|
+
"project-specific scripts, data extraction pipelines, "
|
|
143
|
+
"and any command someone might search for later.\n"
|
|
144
|
+
"Exclude: trivial navigation (cd, ls, cat), routine git (add, commit, push), "
|
|
145
|
+
"and simple file reads.\n"
|
|
146
|
+
"Format: `command` - what it does\n"
|
|
147
|
+
"Example: `curl -s localhost:8765/api/sessions | jq '.[].name'` - list session names\n"
|
|
148
|
+
"Example: `lsof -i :8880 -t | xargs kill` - kill process on dev port\n"
|
|
149
|
+
"Example: `python3 -c \"import ast; ast.parse(open('server.py').read())\"` - syntax check\n"
|
|
150
|
+
"Skip if no interesting commands were run."
|
|
151
|
+
),
|
|
152
|
+
"prompt_tool_only": (
|
|
153
|
+
"Reusable shell commands from this investigation worth remembering. "
|
|
154
|
+
"Include: diagnostic one-liners, curl/API calls, search commands with useful flags, "
|
|
155
|
+
"project-specific scripts, data extraction pipelines, "
|
|
156
|
+
"and any command someone might search for later.\n"
|
|
157
|
+
"Exclude: trivial navigation (cd, ls, cat), routine git (add, commit, push), "
|
|
158
|
+
"and simple file reads.\n"
|
|
159
|
+
"Format: `command` - what it does\n"
|
|
160
|
+
"Example: `du -sh ~/.painapple-code/projects/*/shadow-git/` - shadow git repo sizes\n"
|
|
161
|
+
"Example: `shadow-query 'SELECT count(*) FROM turns'` - total turn count via /api/shadow-db/sql\n"
|
|
162
|
+
"Example: `grep -rn 'ORPHAN_PROCESS_TIMEOUT' services/` - find timeout constant\n"
|
|
163
|
+
"Skip if no interesting commands were run."
|
|
164
|
+
),
|
|
165
|
+
"field_type": "array",
|
|
166
|
+
"required": False,
|
|
167
|
+
"default_enabled": True,
|
|
168
|
+
"order": 47,
|
|
169
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
170
|
+
},
|
|
171
|
+
"tools_used": {
|
|
172
|
+
"id": "tools_used",
|
|
173
|
+
"title": "Tools Used",
|
|
174
|
+
"prompt": "- Tool: input → key finding",
|
|
175
|
+
"required": False,
|
|
176
|
+
"default_enabled": True,
|
|
177
|
+
"order": 50,
|
|
178
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
179
|
+
},
|
|
180
|
+
"context_for_resume": {
|
|
181
|
+
"id": "context_for_resume",
|
|
182
|
+
"title": "Context for Resume",
|
|
183
|
+
"prompt": "- Current state: what works now\n- Open items: what's left to do\n- Gotchas: things to remember",
|
|
184
|
+
"prompt_tool_only": "- Current understanding\n- Next steps to try\n- Related areas to explore",
|
|
185
|
+
"required": False,
|
|
186
|
+
"default_enabled": True,
|
|
187
|
+
"order": 60,
|
|
188
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
189
|
+
},
|
|
190
|
+
"learnings": {
|
|
191
|
+
"id": "learnings",
|
|
192
|
+
"title": "Learnings",
|
|
193
|
+
"prompt": "- Discoveries worth remembering\n- Warnings for future work",
|
|
194
|
+
"prompt_tool_only": "- Things discovered worth remembering\n- Gotchas or warnings",
|
|
195
|
+
"required": False,
|
|
196
|
+
"default_enabled": True,
|
|
197
|
+
"order": 70,
|
|
198
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
199
|
+
},
|
|
200
|
+
"session_title": {
|
|
201
|
+
"id": "session_title",
|
|
202
|
+
"title": "Session Title",
|
|
203
|
+
"prompt": """A SHORT title (3-6 words) for this entire session. This helps identify the session later.
|
|
204
|
+
- Capture the main goal or theme of the work
|
|
205
|
+
- Update if the focus has shifted from previous turns
|
|
206
|
+
- Examples: "JWT Auth Refactor", "Widget Empty Fix", "Cost Analytics Feature"
|
|
207
|
+
- Just the title, no prefix or formatting.""",
|
|
208
|
+
"required": True,
|
|
209
|
+
"default_enabled": True,
|
|
210
|
+
"order": 10,
|
|
211
|
+
"applies_to": ["file_changes", "tool_only"],
|
|
212
|
+
},
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def get_sections_config(project_config: dict) -> dict:
|
|
217
|
+
"""
|
|
218
|
+
Merge user's section config with built-in defaults.
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
project_config: Project config dict (from load_project_config)
|
|
222
|
+
|
|
223
|
+
Returns:
|
|
224
|
+
Dict of section_id -> merged section config
|
|
225
|
+
"""
|
|
226
|
+
user_sections = project_config.get("shadow_git", {}).get("commit_sections", {})
|
|
227
|
+
result = {}
|
|
228
|
+
|
|
229
|
+
# Start with built-in sections
|
|
230
|
+
for section_id, builtin in BUILTIN_SECTIONS.items():
|
|
231
|
+
merged = builtin.copy()
|
|
232
|
+
|
|
233
|
+
# Apply user overrides
|
|
234
|
+
if section_id in user_sections:
|
|
235
|
+
user = user_sections[section_id]
|
|
236
|
+
if "enabled" in user:
|
|
237
|
+
# Can't disable required sections
|
|
238
|
+
if not builtin["required"]:
|
|
239
|
+
merged["enabled"] = user["enabled"]
|
|
240
|
+
else:
|
|
241
|
+
merged["enabled"] = True
|
|
242
|
+
else:
|
|
243
|
+
merged["enabled"] = builtin["default_enabled"]
|
|
244
|
+
|
|
245
|
+
if "order" in user:
|
|
246
|
+
merged["order"] = user["order"]
|
|
247
|
+
|
|
248
|
+
# Allow customizing prompt for non-required sections
|
|
249
|
+
if "prompt" in user and not builtin["required"]:
|
|
250
|
+
merged["prompt"] = user["prompt"]
|
|
251
|
+
else:
|
|
252
|
+
merged["enabled"] = builtin["default_enabled"]
|
|
253
|
+
|
|
254
|
+
merged["builtin"] = True
|
|
255
|
+
result[section_id] = merged
|
|
256
|
+
|
|
257
|
+
# Add custom user sections
|
|
258
|
+
for section_id, user_section in user_sections.items():
|
|
259
|
+
if section_id not in BUILTIN_SECTIONS:
|
|
260
|
+
# Custom section - must have title and prompt
|
|
261
|
+
if "title" in user_section and "prompt" in user_section:
|
|
262
|
+
result[section_id] = {
|
|
263
|
+
"id": section_id,
|
|
264
|
+
"title": user_section["title"],
|
|
265
|
+
"prompt": user_section["prompt"],
|
|
266
|
+
"prompt_tool_only": user_section.get("prompt_tool_only", user_section["prompt"]),
|
|
267
|
+
"required": False,
|
|
268
|
+
"enabled": user_section.get("enabled", True),
|
|
269
|
+
"order": user_section.get("order", 55), # Default between tools_used and context
|
|
270
|
+
"applies_to": user_section.get("applies_to", ["file_changes", "tool_only"]),
|
|
271
|
+
"field_type": user_section.get("field_type", "array"), # "string" or "array"
|
|
272
|
+
"builtin": False,
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return result
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def build_commit_schema(project_config: dict, prompt_type: str) -> dict:
|
|
279
|
+
"""
|
|
280
|
+
Build JSON schema for structured commit message output.
|
|
281
|
+
|
|
282
|
+
The schema is dynamic based on which sections are enabled.
|
|
283
|
+
|
|
284
|
+
Args:
|
|
285
|
+
project_config: Project config dict
|
|
286
|
+
prompt_type: "file_changes" or "tool_only"
|
|
287
|
+
|
|
288
|
+
Returns:
|
|
289
|
+
JSON schema dict for --json-schema flag
|
|
290
|
+
"""
|
|
291
|
+
sections_config = get_sections_config(project_config)
|
|
292
|
+
|
|
293
|
+
# Filter enabled sections for this prompt type
|
|
294
|
+
enabled_sections = [
|
|
295
|
+
s for s in sections_config.values()
|
|
296
|
+
if s.get("enabled", True) and prompt_type in s.get("applies_to", [])
|
|
297
|
+
]
|
|
298
|
+
|
|
299
|
+
# Build properties for each enabled section
|
|
300
|
+
properties = {}
|
|
301
|
+
required = []
|
|
302
|
+
|
|
303
|
+
for section in enabled_sections:
|
|
304
|
+
section_id = section["id"]
|
|
305
|
+
|
|
306
|
+
# Determine field type - user can override, defaults based on section
|
|
307
|
+
# field_type: "string" for single value, "array" for bullet points
|
|
308
|
+
field_type = section.get("field_type")
|
|
309
|
+
if not field_type:
|
|
310
|
+
# Default: summary/title are strings, rest are arrays
|
|
311
|
+
if section_id in ("summary", "session_title"):
|
|
312
|
+
field_type = "string"
|
|
313
|
+
else:
|
|
314
|
+
field_type = "array"
|
|
315
|
+
|
|
316
|
+
if field_type == "string":
|
|
317
|
+
properties[section_id] = {
|
|
318
|
+
"type": "string",
|
|
319
|
+
"description": section.get("prompt", "")
|
|
320
|
+
}
|
|
321
|
+
else:
|
|
322
|
+
properties[section_id] = {
|
|
323
|
+
"type": "array",
|
|
324
|
+
"items": {"type": "string"},
|
|
325
|
+
"description": section.get("prompt", "")
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
# Required sections must be present
|
|
329
|
+
if section.get("required"):
|
|
330
|
+
required.append(section_id)
|
|
331
|
+
|
|
332
|
+
return {
|
|
333
|
+
"type": "object",
|
|
334
|
+
"properties": properties,
|
|
335
|
+
"required": required,
|
|
336
|
+
"additionalProperties": False
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def build_commit_prompt_for_json(
|
|
341
|
+
project_config: dict,
|
|
342
|
+
prompt_type: str,
|
|
343
|
+
journey_section: str,
|
|
344
|
+
user_prompt: str,
|
|
345
|
+
files: str = "",
|
|
346
|
+
tools: str = ""
|
|
347
|
+
) -> str:
|
|
348
|
+
"""
|
|
349
|
+
Build prompt for JSON structured output (used with --json-schema).
|
|
350
|
+
|
|
351
|
+
Simpler than markdown prompt since schema enforces structure.
|
|
352
|
+
|
|
353
|
+
Args:
|
|
354
|
+
project_config: Project config dict
|
|
355
|
+
prompt_type: "file_changes" or "tool_only"
|
|
356
|
+
journey_section: Formatted journey context
|
|
357
|
+
user_prompt: User's original request
|
|
358
|
+
files: Comma-separated file list (for file_changes)
|
|
359
|
+
tools: Formatted tools list
|
|
360
|
+
|
|
361
|
+
Returns:
|
|
362
|
+
Prompt string for the summarizer (JSON output)
|
|
363
|
+
"""
|
|
364
|
+
sections_config = get_sections_config(project_config)
|
|
365
|
+
|
|
366
|
+
# Parse tool names from the tools string for conditional section filtering
|
|
367
|
+
tools_set = set(t.strip() for t in tools.split(",")) if tools else set()
|
|
368
|
+
|
|
369
|
+
# Filter and sort enabled sections for this prompt type
|
|
370
|
+
enabled_sections = []
|
|
371
|
+
for s in sections_config.values():
|
|
372
|
+
if not s.get("enabled", True):
|
|
373
|
+
continue
|
|
374
|
+
if prompt_type not in s.get("applies_to", []):
|
|
375
|
+
continue
|
|
376
|
+
# Conditional sections: only include when specific tools were used
|
|
377
|
+
only_when = s.get("only_when_tools")
|
|
378
|
+
if only_when and not (set(only_when) & tools_set):
|
|
379
|
+
continue
|
|
380
|
+
enabled_sections.append(s)
|
|
381
|
+
enabled_sections.sort(key=lambda s: s.get("order", 50))
|
|
382
|
+
|
|
383
|
+
# Build intro
|
|
384
|
+
if prompt_type == "file_changes":
|
|
385
|
+
intro = "You just completed a turn helping the user. Generate a structured commit message as JSON."
|
|
386
|
+
else:
|
|
387
|
+
intro = "You just completed a turn (no files modified). Generate a structured commit message documenting your investigation as JSON."
|
|
388
|
+
|
|
389
|
+
# Build context
|
|
390
|
+
parts = [intro, ""]
|
|
391
|
+
|
|
392
|
+
if journey_section:
|
|
393
|
+
parts.append(journey_section)
|
|
394
|
+
|
|
395
|
+
parts.append(f"USER'S REQUEST:\n{user_prompt}")
|
|
396
|
+
parts.append("")
|
|
397
|
+
|
|
398
|
+
if prompt_type == "file_changes" and files:
|
|
399
|
+
parts.append(f"FILES MODIFIED: {files}")
|
|
400
|
+
parts.append("")
|
|
401
|
+
|
|
402
|
+
parts.append(f"TOOLS USED: {tools}")
|
|
403
|
+
parts.append("")
|
|
404
|
+
|
|
405
|
+
# Field instructions
|
|
406
|
+
parts.append("Fill each JSON field according to these guidelines:")
|
|
407
|
+
parts.append("")
|
|
408
|
+
|
|
409
|
+
for section in enabled_sections:
|
|
410
|
+
section_id = section["id"]
|
|
411
|
+
if prompt_type == "tool_only" and "prompt_tool_only" in section:
|
|
412
|
+
prompt_text = section["prompt_tool_only"]
|
|
413
|
+
else:
|
|
414
|
+
prompt_text = section["prompt"]
|
|
415
|
+
|
|
416
|
+
clean_prompt = prompt_text.replace("\n", " ").strip()
|
|
417
|
+
parts.append(f"- {section_id}: {clean_prompt}")
|
|
418
|
+
|
|
419
|
+
parts.append("")
|
|
420
|
+
parts.append("Be concise. Use keywords that are searchable.")
|
|
421
|
+
|
|
422
|
+
return "\n".join(parts)
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
def structured_to_markdown(structured: dict, project_config: dict, prompt_type: str) -> str:
|
|
426
|
+
"""
|
|
427
|
+
Convert structured JSON response back to markdown for git commit message.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
structured: Parsed JSON response from the summary fork
|
|
431
|
+
project_config: Project config dict
|
|
432
|
+
prompt_type: "file_changes" or "tool_only"
|
|
433
|
+
|
|
434
|
+
Returns:
|
|
435
|
+
Markdown formatted commit message body
|
|
436
|
+
"""
|
|
437
|
+
sections_config = get_sections_config(project_config)
|
|
438
|
+
|
|
439
|
+
# Filter and sort enabled sections
|
|
440
|
+
enabled_sections = [
|
|
441
|
+
s for s in sections_config.values()
|
|
442
|
+
if s.get("enabled", True) and prompt_type in s.get("applies_to", [])
|
|
443
|
+
]
|
|
444
|
+
enabled_sections.sort(key=lambda s: s.get("order", 50))
|
|
445
|
+
|
|
446
|
+
# Internal-only fields: produced by the summary fork and consumed elsewhere
|
|
447
|
+
# (session.name update, etc.) but not rendered as a commit-body section.
|
|
448
|
+
INTERNAL_ONLY = {"session_title"}
|
|
449
|
+
|
|
450
|
+
parts = []
|
|
451
|
+
|
|
452
|
+
for section in enabled_sections:
|
|
453
|
+
section_id = section["id"]
|
|
454
|
+
if section_id in INTERNAL_ONLY:
|
|
455
|
+
continue
|
|
456
|
+
title = section["title"]
|
|
457
|
+
value = structured.get(section_id)
|
|
458
|
+
|
|
459
|
+
if not value:
|
|
460
|
+
continue
|
|
461
|
+
|
|
462
|
+
parts.append(f"## {title}")
|
|
463
|
+
|
|
464
|
+
if isinstance(value, list):
|
|
465
|
+
for item in value:
|
|
466
|
+
if item:
|
|
467
|
+
parts.append(f"- {item}")
|
|
468
|
+
else:
|
|
469
|
+
parts.append(str(value))
|
|
470
|
+
|
|
471
|
+
parts.append("")
|
|
472
|
+
|
|
473
|
+
return "\n".join(parts).strip()
|
|
474
|
+
|
|
475
|
+
|
|
476
|
+
COMMIT_PROMPT_COMPACTION = """This conversation is about to be compacted. Generate a COMPREHENSIVE summary to preserve important context that will be lost.
|
|
477
|
+
|
|
478
|
+
Generate with this EXACT structure:
|
|
479
|
+
|
|
480
|
+
## Session Overview
|
|
481
|
+
What was the user trying to accomplish? Key goals.
|
|
482
|
+
|
|
483
|
+
## Tags
|
|
484
|
+
All relevant tags from the session: #feature #bugfix etc. + domain tags
|
|
485
|
+
|
|
486
|
+
## Work Completed
|
|
487
|
+
- Major features/changes implemented
|
|
488
|
+
- Key milestones reached
|
|
489
|
+
|
|
490
|
+
## Decisions Made
|
|
491
|
+
- Architectural decisions and rationale
|
|
492
|
+
- Trade-offs chosen
|
|
493
|
+
- Patterns established
|
|
494
|
+
|
|
495
|
+
## Problems Solved
|
|
496
|
+
- Issues debugged
|
|
497
|
+
- Root causes found
|
|
498
|
+
- Solutions that worked
|
|
499
|
+
|
|
500
|
+
## Files Changed
|
|
501
|
+
- Key files modified and why
|
|
502
|
+
- New files created
|
|
503
|
+
- Dependencies added
|
|
504
|
+
|
|
505
|
+
## Current State
|
|
506
|
+
- What works now
|
|
507
|
+
- What's partially done
|
|
508
|
+
- Known issues
|
|
509
|
+
|
|
510
|
+
## Critical Context
|
|
511
|
+
- Things that MUST be remembered
|
|
512
|
+
- Gotchas discovered
|
|
513
|
+
- Warnings for future work
|
|
514
|
+
|
|
515
|
+
## Open Items
|
|
516
|
+
- What's left to do
|
|
517
|
+
- Blockers encountered
|
|
518
|
+
- Questions unanswered
|
|
519
|
+
|
|
520
|
+
Be THOROUGH - this is the only record of the full context."""
|