iCode-TUI 0.29.1__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.
- chrys/__init__.py +16 -0
- chrys/app/__init__.py +3 -0
- chrys/app/acp/__init__.py +3 -0
- chrys/app/acp/bridge.py +664 -0
- chrys/app/acp/content.py +132 -0
- chrys/app/acp/doc/frontend-api.md +425 -0
- chrys/app/acp/history.py +585 -0
- chrys/app/acp/server.py +1796 -0
- chrys/app/acp/session_manager.py +1815 -0
- chrys/app/acp/tool_status.py +45 -0
- chrys/app/cli/__init__.py +3 -0
- chrys/app/cli/acp.py +178 -0
- chrys/app/cli/app.py +165 -0
- chrys/app/cli/approvals.py +101 -0
- chrys/app/cli/headless.py +223 -0
- chrys/app/cli/launch_cwd.py +42 -0
- chrys/app/cli/profiles.py +298 -0
- chrys/app/cli/progress.py +857 -0
- chrys/app/cli/run.py +425 -0
- chrys/app/cli/serve.py +1593 -0
- chrys/app/cli/tool_summary.py +225 -0
- chrys/app/cli/trajectory.py +201 -0
- chrys/app/cli/workflow.py +601 -0
- chrys/app/features/__init__.py +3 -0
- chrys/app/features/buddy/__init__.py +3 -0
- chrys/app/features/buddy/actions.py +68 -0
- chrys/app/features/buddy/animation.py +76 -0
- chrys/app/features/buddy/commands.py +196 -0
- chrys/app/features/buddy/docs/design.md +187 -0
- chrys/app/features/buddy/hatchery.py +80 -0
- chrys/app/features/buddy/lifecycle.py +41 -0
- chrys/app/features/buddy/model.py +265 -0
- chrys/app/features/buddy/pixel_renderer.py +113 -0
- chrys/app/features/buddy/pixel_sprites.py +279 -0
- chrys/app/features/buddy/portrait.py +76 -0
- chrys/app/features/buddy/progression.py +58 -0
- chrys/app/features/buddy/replies.py +191 -0
- chrys/app/features/buddy/sprites/alien.toml +70 -0
- chrys/app/features/buddy/sprites/axolotl.toml +71 -0
- chrys/app/features/buddy/sprites/bat.toml +69 -0
- chrys/app/features/buddy/sprites/bee.toml +69 -0
- chrys/app/features/buddy/sprites/cactus.toml +73 -0
- chrys/app/features/buddy/sprites/capybara.toml +70 -0
- chrys/app/features/buddy/sprites/cat.toml +69 -0
- chrys/app/features/buddy/sprites/crab.toml +70 -0
- chrys/app/features/buddy/sprites/dragon.toml +71 -0
- chrys/app/features/buddy/sprites/duck.toml +69 -0
- chrys/app/features/buddy/sprites/fox.toml +69 -0
- chrys/app/features/buddy/sprites/frog.toml +70 -0
- chrys/app/features/buddy/sprites/ghost.toml +70 -0
- chrys/app/features/buddy/sprites/goose.toml +69 -0
- chrys/app/features/buddy/sprites/jelly.toml +70 -0
- chrys/app/features/buddy/sprites/llama.toml +70 -0
- chrys/app/features/buddy/sprites/mushroom.toml +69 -0
- chrys/app/features/buddy/sprites/octopus.toml +70 -0
- chrys/app/features/buddy/sprites/owl.toml +70 -0
- chrys/app/features/buddy/sprites/panda.toml +71 -0
- chrys/app/features/buddy/sprites/penguin.toml +69 -0
- chrys/app/features/buddy/sprites/rabbit.toml +70 -0
- chrys/app/features/buddy/sprites/robot.toml +72 -0
- chrys/app/features/buddy/sprites/shark.toml +70 -0
- chrys/app/features/buddy/sprites/snail.toml +69 -0
- chrys/app/features/buddy/sprites/snake.toml +69 -0
- chrys/app/features/buddy/sprites/tabby.toml +69 -0
- chrys/app/features/buddy/sprites/turtle.toml +69 -0
- chrys/app/features/buddy/store.py +143 -0
- chrys/app/features/session_title/__init__.py +7 -0
- chrys/app/features/session_title/updater.py +582 -0
- chrys/app/installer.py +651 -0
- chrys/app/parsing.py +17 -0
- chrys/app/tui/__init__.py +3 -0
- chrys/app/tui/app.py +1287 -0
- chrys/app/tui/behaviors/__init__.py +3 -0
- chrys/app/tui/behaviors/click_outside_dismiss.py +90 -0
- chrys/app/tui/behaviors/insert_clipboard.py +73 -0
- chrys/app/tui/behaviors/right_click_copy.py +146 -0
- chrys/app/tui/binding_display.py +139 -0
- chrys/app/tui/buddy_messages.py +17 -0
- chrys/app/tui/buddy_reply.py +86 -0
- chrys/app/tui/chrys.tcss +549 -0
- chrys/app/tui/clipboard.py +109 -0
- chrys/app/tui/copy_messages.py +10 -0
- chrys/app/tui/i18n.py +230 -0
- chrys/app/tui/language.py +58 -0
- chrys/app/tui/notifications/__init__.py +12 -0
- chrys/app/tui/notifications/drivers.py +180 -0
- chrys/app/tui/notifications/service.py +126 -0
- chrys/app/tui/notifications/settings.py +141 -0
- chrys/app/tui/screens/__init__.py +3 -0
- chrys/app/tui/screens/agents/__init__.py +8 -0
- chrys/app/tui/screens/agents/agent_draft_store.py +937 -0
- chrys/app/tui/screens/agents/config.py +2142 -0
- chrys/app/tui/screens/agents/config.tcss +169 -0
- chrys/app/tui/screens/agents/panels/__init__.py +3 -0
- chrys/app/tui/screens/agents/panels/acp.py +1176 -0
- chrys/app/tui/screens/agents/panels/basic.py +497 -0
- chrys/app/tui/screens/agents/panels/compaction.py +231 -0
- chrys/app/tui/screens/agents/panels/config_card.py +218 -0
- chrys/app/tui/screens/agents/panels/instructions.py +91 -0
- chrys/app/tui/screens/agents/panels/markdown_report.py +76 -0
- chrys/app/tui/screens/agents/panels/mcp.py +2262 -0
- chrys/app/tui/screens/agents/panels/memory.py +684 -0
- chrys/app/tui/screens/agents/panels/path_entry.py +227 -0
- chrys/app/tui/screens/agents/panels/skills.py +806 -0
- chrys/app/tui/screens/agents/panels/subagents.py +652 -0
- chrys/app/tui/screens/agents/panels/tools.py +205 -0
- chrys/app/tui/screens/agents/picker.py +103 -0
- chrys/app/tui/screens/agents/skill_paths.py +38 -0
- chrys/app/tui/screens/agents/validation_messages.py +452 -0
- chrys/app/tui/screens/dialogs/__init__.py +35 -0
- chrys/app/tui/screens/dialogs/agent_load.py +834 -0
- chrys/app/tui/screens/dialogs/agent_load.tcss +78 -0
- chrys/app/tui/screens/dialogs/app_mode.py +55 -0
- chrys/app/tui/screens/dialogs/approval/__init__.py +15 -0
- chrys/app/tui/screens/dialogs/approval/approval.tcss +311 -0
- chrys/app/tui/screens/dialogs/approval/bodies/__init__.py +3 -0
- chrys/app/tui/screens/dialogs/approval/bodies/file_edit.py +210 -0
- chrys/app/tui/screens/dialogs/approval/bodies/sub_agent.py +82 -0
- chrys/app/tui/screens/dialogs/approval/body.py +110 -0
- chrys/app/tui/screens/dialogs/approval/dialog.py +565 -0
- chrys/app/tui/screens/dialogs/approval/mode.py +105 -0
- chrys/app/tui/screens/dialogs/ask_user.py +148 -0
- chrys/app/tui/screens/dialogs/ask_user.tcss +62 -0
- chrys/app/tui/screens/dialogs/base.py +84 -0
- chrys/app/tui/screens/dialogs/confirm.py +184 -0
- chrys/app/tui/screens/dialogs/confirm.tcss +46 -0
- chrys/app/tui/screens/dialogs/connection_test.py +183 -0
- chrys/app/tui/screens/dialogs/connection_test.tcss +92 -0
- chrys/app/tui/screens/dialogs/diagram.py +102 -0
- chrys/app/tui/screens/dialogs/diagram.tcss +24 -0
- chrys/app/tui/screens/dialogs/editor.py +378 -0
- chrys/app/tui/screens/dialogs/editor.tcss +132 -0
- chrys/app/tui/screens/dialogs/file_picker.py +582 -0
- chrys/app/tui/screens/dialogs/file_picker.tcss +78 -0
- chrys/app/tui/screens/dialogs/fork_session.py +219 -0
- chrys/app/tui/screens/dialogs/fork_session.tcss +75 -0
- chrys/app/tui/screens/dialogs/image_compression.py +102 -0
- chrys/app/tui/screens/dialogs/image_compression.tcss +28 -0
- chrys/app/tui/screens/dialogs/man_page.py +172 -0
- chrys/app/tui/screens/dialogs/man_page.tcss +39 -0
- chrys/app/tui/screens/dialogs/new_folder.py +277 -0
- chrys/app/tui/screens/dialogs/new_folder.tcss +51 -0
- chrys/app/tui/screens/dialogs/notice.tcss +14 -0
- chrys/app/tui/screens/dialogs/prompt_cache.py +144 -0
- chrys/app/tui/screens/dialogs/prompt_cache.tcss +38 -0
- chrys/app/tui/screens/dialogs/runtime_details.py +371 -0
- chrys/app/tui/screens/dialogs/runtime_details.tcss +49 -0
- chrys/app/tui/screens/dialogs/session_title.py +110 -0
- chrys/app/tui/screens/dialogs/session_title.tcss +43 -0
- chrys/app/tui/screens/dialogs/tool_view.py +207 -0
- chrys/app/tui/screens/dialogs/tool_view.tcss +43 -0
- chrys/app/tui/screens/dialogs/vision_unsupported.py +122 -0
- chrys/app/tui/screens/dialogs/vision_unsupported.tcss +35 -0
- chrys/app/tui/screens/dialogs/workflow_confirm.py +91 -0
- chrys/app/tui/screens/dialogs/workflow_confirm.tcss +17 -0
- chrys/app/tui/screens/dialogs/workflow_input.py +258 -0
- chrys/app/tui/screens/dialogs/workflow_input.tcss +73 -0
- chrys/app/tui/screens/dialogs/workflow_node.py +462 -0
- chrys/app/tui/screens/dialogs/workflow_node.tcss +41 -0
- chrys/app/tui/screens/dialogs/workflow_picker.py +46 -0
- chrys/app/tui/screens/dialogs/workflow_result.py +136 -0
- chrys/app/tui/screens/dialogs/workflow_result.tcss +14 -0
- chrys/app/tui/screens/diff/__init__.py +22 -0
- chrys/app/tui/screens/diff/rollback_modal.py +1381 -0
- chrys/app/tui/screens/diff/rollback_modal.tcss +248 -0
- chrys/app/tui/screens/diff/screen.py +1532 -0
- chrys/app/tui/screens/diff/screen.tcss +104 -0
- chrys/app/tui/screens/guides/__init__.py +7 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/agents.md +178 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/approval.md +117 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/chat-options.md +276 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/compaction.md +42 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/memory.md +48 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/models.md +158 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/settings.md +210 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/themes.md +61 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/tools.md +60 -0
- chrys/app/tui/screens/guides/_docs/en/guides/configuration/web-tools.md +286 -0
- chrys/app/tui/screens/guides/_docs/en/guides/daily-use/sessions.md +77 -0
- chrys/app/tui/screens/guides/_docs/en/guides/daily-use/workspaces.md +51 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/external-acp-agents.md +126 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/hooks.md +167 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/mcp.md +95 -0
- chrys/app/tui/screens/guides/_docs/en/guides/extensions/skills.md +175 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/icode-acp.md +61 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/icode-run.md +190 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/icode-serve.md +239 -0
- chrys/app/tui/screens/guides/_docs/en/guides/running/workflows.md +664 -0
- chrys/app/tui/screens/guides/_docs/en/reference/agent-profile.md +548 -0
- chrys/app/tui/screens/guides/_docs/en/reference/hooks.md +602 -0
- chrys/app/tui/screens/guides/_docs/en/reference/opentelemetry.md +177 -0
- chrys/app/tui/screens/guides/_docs/en/reference/settings.md +245 -0
- chrys/app/tui/screens/guides/_docs/en/reference/themes.md +149 -0
- chrys/app/tui/screens/guides/_docs/en/reference/tool-kinds-and-names.md +58 -0
- chrys/app/tui/screens/guides/_docs/en/reference/tui-slash-commands.md +76 -0
- chrys/app/tui/screens/guides/_docs/en/reference/workflows.md +1006 -0
- chrys/app/tui/screens/guides/_docs/en/start/getting-started.md +170 -0
- chrys/app/tui/screens/guides/_docs/en/start/what-is-icode.md +34 -0
- chrys/app/tui/screens/guides/_docs/index.yaml +100 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/agents.md +178 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/approval.md +117 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/chat-options.md +276 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/compaction.md +42 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/memory.md +48 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/models.md +158 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/settings.md +210 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/themes.md +61 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/tools.md +60 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/configuration/web-tools.md +286 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/daily-use/sessions.md +77 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/daily-use/workspaces.md +51 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/external-acp-agents.md +126 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/hooks.md +167 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/mcp.md +95 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/extensions/skills.md +175 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/icode-acp.md +61 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/icode-run.md +190 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/icode-serve.md +239 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/guides/running/workflows.md +664 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/agent-profile.md +548 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/hooks.md +602 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/opentelemetry.md +177 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/settings.md +245 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/themes.md +149 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/tool-kinds-and-names.md +58 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/tui-slash-commands.md +76 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/reference/workflows.md +1005 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/start/getting-started.md +170 -0
- chrys/app/tui/screens/guides/_docs/zh-Hans/start/what-is-icode.md +34 -0
- chrys/app/tui/screens/guides/index.py +215 -0
- chrys/app/tui/screens/guides/reader.py +173 -0
- chrys/app/tui/screens/guides/screen.py +442 -0
- chrys/app/tui/screens/guides/screen.tcss +52 -0
- chrys/app/tui/screens/logs/__init__.py +7 -0
- chrys/app/tui/screens/logs/screen.py +504 -0
- chrys/app/tui/screens/logs/screen.tcss +45 -0
- chrys/app/tui/screens/main/__init__.py +7 -0
- chrys/app/tui/screens/main/action_availability.py +30 -0
- chrys/app/tui/screens/main/buddy_command.py +143 -0
- chrys/app/tui/screens/main/commands.py +1073 -0
- chrys/app/tui/screens/main/config_actions.py +464 -0
- chrys/app/tui/screens/main/copy_actions.py +117 -0
- chrys/app/tui/screens/main/dialog_controllers.py +826 -0
- chrys/app/tui/screens/main/dialog_gateway.py +166 -0
- chrys/app/tui/screens/main/diff_controller.py +478 -0
- chrys/app/tui/screens/main/engine_read_model.py +184 -0
- chrys/app/tui/screens/main/event_handlers.py +2014 -0
- chrys/app/tui/screens/main/input_flow.py +241 -0
- chrys/app/tui/screens/main/live_diff.py +244 -0
- chrys/app/tui/screens/main/main_screen_presenter.py +295 -0
- chrys/app/tui/screens/main/model_indicator.py +217 -0
- chrys/app/tui/screens/main/navigation.py +343 -0
- chrys/app/tui/screens/main/ports.py +571 -0
- chrys/app/tui/screens/main/recent_dirs.py +123 -0
- chrys/app/tui/screens/main/rollback_controller.py +586 -0
- chrys/app/tui/screens/main/runtime_info.py +71 -0
- chrys/app/tui/screens/main/screen.py +2265 -0
- chrys/app/tui/screens/main/screen.tcss +21 -0
- chrys/app/tui/screens/main/session_handlers.py +1127 -0
- chrys/app/tui/screens/main/session_title.py +239 -0
- chrys/app/tui/screens/main/settings_coordinator.py +365 -0
- chrys/app/tui/screens/main/settings_persistence.py +184 -0
- chrys/app/tui/screens/main/shell_mode.py +112 -0
- chrys/app/tui/screens/main/state.py +289 -0
- chrys/app/tui/screens/main/submit_state.py +11 -0
- chrys/app/tui/screens/main/subscriptions.py +177 -0
- chrys/app/tui/screens/main/suggestions.py +982 -0
- chrys/app/tui/screens/main/tool_action_bridge.py +75 -0
- chrys/app/tui/screens/main/view_adapter.py +1567 -0
- chrys/app/tui/screens/main/workflow_browser.py +747 -0
- chrys/app/tui/screens/main/workflow_content.py +248 -0
- chrys/app/tui/screens/main/workflow_controller.py +240 -0
- chrys/app/tui/screens/main/workflow_feedback.py +137 -0
- chrys/app/tui/screens/main/workflow_flow.py +49 -0
- chrys/app/tui/screens/main/workflow_run_control.py +456 -0
- chrys/app/tui/screens/main/workflow_session_view.py +316 -0
- chrys/app/tui/screens/main/workspace_actions.py +272 -0
- chrys/app/tui/screens/main/workspace_branch.py +194 -0
- chrys/app/tui/screens/menus/__init__.py +8 -0
- chrys/app/tui/screens/menus/languages.py +114 -0
- chrys/app/tui/screens/models/__init__.py +7 -0
- chrys/app/tui/screens/models/picker.py +147 -0
- chrys/app/tui/screens/models/screen.py +2043 -0
- chrys/app/tui/screens/models/screen.tcss +255 -0
- chrys/app/tui/screens/sessions/__init__.py +8 -0
- chrys/app/tui/screens/sessions/presenter.py +586 -0
- chrys/app/tui/screens/sessions/screen.py +779 -0
- chrys/app/tui/screens/sessions/screen.tcss +127 -0
- chrys/app/tui/screens/settings/__init__.py +29 -0
- chrys/app/tui/screens/settings/danger.py +26 -0
- chrys/app/tui/screens/settings/dialog.py +281 -0
- chrys/app/tui/screens/settings/layout.py +519 -0
- chrys/app/tui/screens/settings/migrate_dialog.py +253 -0
- chrys/app/tui/screens/settings/panes/__init__.py +3 -0
- chrys/app/tui/screens/settings/panes/notifications.py +248 -0
- chrys/app/tui/screens/settings/panes/sessions.py +148 -0
- chrys/app/tui/screens/settings/ports.py +55 -0
- chrys/app/tui/screens/settings/provenance.py +102 -0
- chrys/app/tui/screens/settings/rows.py +546 -0
- chrys/app/tui/screens/settings/settings.tcss +406 -0
- chrys/app/tui/screens/themes/__init__.py +8 -0
- chrys/app/tui/screens/themes/dialogs.py +330 -0
- chrys/app/tui/screens/themes/editor.py +632 -0
- chrys/app/tui/screens/themes/editor.tcss +268 -0
- chrys/app/tui/screens/themes/messages.py +95 -0
- chrys/app/tui/screens/themes/palette.py +694 -0
- chrys/app/tui/screens/themes/panel.py +113 -0
- chrys/app/tui/screens/themes/picker.py +203 -0
- chrys/app/tui/screens/themes/save.py +191 -0
- chrys/app/tui/support/__init__.py +3 -0
- chrys/app/tui/support/file_manager.py +64 -0
- chrys/app/tui/support/gc_freeze.py +1114 -0
- chrys/app/tui/support/path_shortcuts.py +50 -0
- chrys/app/tui/support/prompt_history.py +298 -0
- chrys/app/tui/support/workspace_mru.py +476 -0
- chrys/app/tui/terminal/__init__.py +6 -0
- chrys/app/tui/terminal/_pty_backend.py +114 -0
- chrys/app/tui/terminal/emulator/__init__.py +24 -0
- chrys/app/tui/terminal/emulator/buffer.py +456 -0
- chrys/app/tui/terminal/emulator/charsets.py +113 -0
- chrys/app/tui/terminal/emulator/core.py +963 -0
- chrys/app/tui/terminal/emulator/input.py +342 -0
- chrys/app/tui/terminal/emulator/parser.py +227 -0
- chrys/app/tui/terminal/emulator/pen.py +158 -0
- chrys/app/tui/terminal/launcher.py +455 -0
- chrys/app/tui/terminal/leaked_reports.py +44 -0
- chrys/app/tui/terminal/panel.py +323 -0
- chrys/app/tui/terminal/pty_process.py +405 -0
- chrys/app/tui/terminal/rendering.py +151 -0
- chrys/app/tui/terminal/shell.py +273 -0
- chrys/app/tui/terminal/shell_integration.py +199 -0
- chrys/app/tui/terminal/title.py +224 -0
- chrys/app/tui/terminal/widget.py +654 -0
- chrys/app/tui/theme.py +422 -0
- chrys/app/tui/theme_loader.py +201 -0
- chrys/app/tui/theme_stylesheet.py +49 -0
- chrys/app/tui/themes/__init__.py +3 -0
- chrys/app/tui/themes/document.py +120 -0
- chrys/app/tui/themes/preview.py +170 -0
- chrys/app/tui/themes/store.py +176 -0
- chrys/app/tui/toasts.py +69 -0
- chrys/app/tui/util/__init__.py +3 -0
- chrys/app/tui/util/context_pressure.py +146 -0
- chrys/app/tui/util/debug_log.py +292 -0
- chrys/app/tui/util/diff_entries.py +64 -0
- chrys/app/tui/util/formatting.py +53 -0
- chrys/app/tui/util/git_branch.py +326 -0
- chrys/app/tui/util/invocation_progress.py +57 -0
- chrys/app/tui/util/logo.py +32 -0
- chrys/app/tui/util/message_gate.py +35 -0
- chrys/app/tui/util/mutation_sources.py +14 -0
- chrys/app/tui/util/picker_text.py +27 -0
- chrys/app/tui/util/removal.py +47 -0
- chrys/app/tui/util/rich_style.py +36 -0
- chrys/app/tui/util/source_text.py +12 -0
- chrys/app/tui/util/static_update.py +88 -0
- chrys/app/tui/util/todo_format.py +51 -0
- chrys/app/tui/util/visibility.py +214 -0
- chrys/app/tui/widgets/__init__.py +60 -0
- chrys/app/tui/widgets/ask_user_controls.py +652 -0
- chrys/app/tui/widgets/ask_user_markdown.py +17 -0
- chrys/app/tui/widgets/ask_user_prompt.py +606 -0
- chrys/app/tui/widgets/buttons.py +52 -0
- chrys/app/tui/widgets/chat/__init__.py +3 -0
- chrys/app/tui/widgets/chat/agent_transcript_surface.py +818 -0
- chrys/app/tui/widgets/chat/chrome.py +296 -0
- chrys/app/tui/widgets/chat/compaction_card.py +353 -0
- chrys/app/tui/widgets/chat/context_fold.py +77 -0
- chrys/app/tui/widgets/chat/file_snapshot.py +91 -0
- chrys/app/tui/widgets/chat/image_preview.py +214 -0
- chrys/app/tui/widgets/chat/live_renderer.py +383 -0
- chrys/app/tui/widgets/chat/messages.py +1039 -0
- chrys/app/tui/widgets/chat/panel.py +1769 -0
- chrys/app/tui/widgets/chat/ports.py +245 -0
- chrys/app/tui/widgets/chat/renderers/__init__.py +7 -0
- chrys/app/tui/widgets/chat/renderers/ask_user.py +747 -0
- chrys/app/tui/widgets/chat/renderers/execute.py +431 -0
- chrys/app/tui/widgets/chat/renderers/file_edit.py +925 -0
- chrys/app/tui/widgets/chat/renderers/hosted_code.py +83 -0
- chrys/app/tui/widgets/chat/renderers/hosted_generic.py +330 -0
- chrys/app/tui/widgets/chat/renderers/hosted_image.py +107 -0
- chrys/app/tui/widgets/chat/renderers/hosted_mcp.py +43 -0
- chrys/app/tui/widgets/chat/renderers/hosted_search.py +167 -0
- chrys/app/tui/widgets/chat/renderers/hosted_shell.py +132 -0
- chrys/app/tui/widgets/chat/renderers/read_file.py +399 -0
- chrys/app/tui/widgets/chat/renderers/search.py +348 -0
- chrys/app/tui/widgets/chat/renderers/skill.py +564 -0
- chrys/app/tui/widgets/chat/renderers/sleep.py +287 -0
- chrys/app/tui/widgets/chat/renderers/sub_agent.py +1385 -0
- chrys/app/tui/widgets/chat/renderers/todo.py +114 -0
- chrys/app/tui/widgets/chat/renderers/web.py +69 -0
- chrys/app/tui/widgets/chat/replay.py +1605 -0
- chrys/app/tui/widgets/chat/replay_mount.py +322 -0
- chrys/app/tui/widgets/chat/scroll_controller.py +579 -0
- chrys/app/tui/widgets/chat/selection_controller.py +435 -0
- chrys/app/tui/widgets/chat/session_json.py +508 -0
- chrys/app/tui/widgets/chat/toc_model.py +156 -0
- chrys/app/tui/widgets/chat/tool_call.py +2478 -0
- chrys/app/tui/widgets/chat/tool_registry.py +753 -0
- chrys/app/tui/widgets/chat/tool_renderers.py +247 -0
- chrys/app/tui/widgets/chat/tool_view_builders.py +260 -0
- chrys/app/tui/widgets/chat/transcript_reader.py +57 -0
- chrys/app/tui/widgets/checkbox.py +24 -0
- chrys/app/tui/widgets/chrome/__init__.py +3 -0
- chrys/app/tui/widgets/chrome/app_header.py +283 -0
- chrys/app/tui/widgets/chrome/commands.py +95 -0
- chrys/app/tui/widgets/chrome/file_index.py +68 -0
- chrys/app/tui/widgets/chrome/file_scanner.py +670 -0
- chrys/app/tui/widgets/chrome/footer.py +284 -0
- chrys/app/tui/widgets/chrome/image_paste.py +351 -0
- chrys/app/tui/widgets/chrome/input_bar.py +1299 -0
- chrys/app/tui/widgets/chrome/status_bar.py +911 -0
- chrys/app/tui/widgets/chrome/suggestion_list.py +652 -0
- chrys/app/tui/widgets/click_affordance.py +24 -0
- chrys/app/tui/widgets/color_picker/__init__.py +254 -0
- chrys/app/tui/widgets/color_picker/controls.py +171 -0
- chrys/app/tui/widgets/color_picker/model.py +89 -0
- chrys/app/tui/widgets/dialog_buttons.py +58 -0
- chrys/app/tui/widgets/dialog_scroll.py +24 -0
- chrys/app/tui/widgets/diff_view/__init__.py +20 -0
- chrys/app/tui/widgets/diff_view/cells.py +59 -0
- chrys/app/tui/widgets/diff_view/code.py +280 -0
- chrys/app/tui/widgets/diff_view/compute.py +286 -0
- chrys/app/tui/widgets/diff_view/gutter.py +161 -0
- chrys/app/tui/widgets/diff_view/inline.py +77 -0
- chrys/app/tui/widgets/diff_view/palette.py +87 -0
- chrys/app/tui/widgets/diff_view/protocols.py +24 -0
- chrys/app/tui/widgets/diff_view/rows.py +138 -0
- chrys/app/tui/widgets/diff_view/unified.py +267 -0
- chrys/app/tui/widgets/diff_view/widget.py +209 -0
- chrys/app/tui/widgets/editor/__init__.py +79 -0
- chrys/app/tui/widgets/editor/coordinates.py +30 -0
- chrys/app/tui/widgets/editor/highlighter.py +139 -0
- chrys/app/tui/widgets/editor/keymaps.py +357 -0
- chrys/app/tui/widgets/editor/types.py +216 -0
- chrys/app/tui/widgets/editor/vim.py +1195 -0
- chrys/app/tui/widgets/editor/widget.py +401 -0
- chrys/app/tui/widgets/file_preview.py +58 -0
- chrys/app/tui/widgets/hatch.py +138 -0
- chrys/app/tui/widgets/input.py +66 -0
- chrys/app/tui/widgets/loading.py +125 -0
- chrys/app/tui/widgets/markdown/__init__.py +25 -0
- chrys/app/tui/widgets/markdown/_utils.py +21 -0
- chrys/app/tui/widgets/markdown/anchors.py +71 -0
- chrys/app/tui/widgets/markdown/blocks.py +115 -0
- chrys/app/tui/widgets/markdown/copyable.py +163 -0
- chrys/app/tui/widgets/markdown/diagram/__init__.py +35 -0
- chrys/app/tui/widgets/markdown/diagram/canvas.py +409 -0
- chrys/app/tui/widgets/markdown/diagram/charts.py +52 -0
- chrys/app/tui/widgets/markdown/diagram/diagnostics.py +101 -0
- chrys/app/tui/widgets/markdown/diagram/geometry.py +46 -0
- chrys/app/tui/widgets/markdown/diagram/layout.py +494 -0
- chrys/app/tui/widgets/markdown/diagram/messages.py +18 -0
- chrys/app/tui/widgets/markdown/diagram/model.py +275 -0
- chrys/app/tui/widgets/markdown/diagram/parser.py +173 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/__init__.py +3 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/charts.py +349 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/common.py +403 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/graphs.py +1072 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/planning.py +317 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/schedule.py +298 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/schemas.py +241 -0
- chrys/app/tui/widgets/markdown/diagram/parsers/structure.py +221 -0
- chrys/app/tui/widgets/markdown/diagram/presentation.py +32 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/__init__.py +3 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/charts.py +275 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/common.py +73 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/planning.py +157 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/schedule.py +202 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/structure.py +77 -0
- chrys/app/tui/widgets/markdown/diagram/renderers/xy.py +385 -0
- chrys/app/tui/widgets/markdown/diagram/router.py +651 -0
- chrys/app/tui/widgets/markdown/diagram/specs/__init__.py +3 -0
- chrys/app/tui/widgets/markdown/diagram/specs/charts.py +94 -0
- chrys/app/tui/widgets/markdown/diagram/specs/planning.py +68 -0
- chrys/app/tui/widgets/markdown/diagram/specs/schedule.py +65 -0
- chrys/app/tui/widgets/markdown/diagram/specs/structure.py +23 -0
- chrys/app/tui/widgets/markdown/diagram/viewer.py +92 -0
- chrys/app/tui/widgets/markdown/links.py +47 -0
- chrys/app/tui/widgets/markdown/math/__init__.py +36 -0
- chrys/app/tui/widgets/markdown/math/layout.py +739 -0
- chrys/app/tui/widgets/markdown/math/markdown.py +291 -0
- chrys/app/tui/widgets/markdown/math/parser.py +325 -0
- chrys/app/tui/widgets/markdown/math/symbols.py +325 -0
- chrys/app/tui/widgets/markdown/navigator.py +80 -0
- chrys/app/tui/widgets/markdown/parser.py +1057 -0
- chrys/app/tui/widgets/markdown/stream.py +73 -0
- chrys/app/tui/widgets/markdown/toc.py +98 -0
- chrys/app/tui/widgets/markdown/viewer.py +146 -0
- chrys/app/tui/widgets/markdown/widget.py +2046 -0
- chrys/app/tui/widgets/marquee.py +101 -0
- chrys/app/tui/widgets/option_menu.py +82 -0
- chrys/app/tui/widgets/page_navigator.py +118 -0
- chrys/app/tui/widgets/select.py +196 -0
- chrys/app/tui/widgets/selection.py +59 -0
- chrys/app/tui/widgets/sidebar/__init__.py +3 -0
- chrys/app/tui/widgets/sidebar/buddy.py +367 -0
- chrys/app/tui/widgets/sidebar/context.py +482 -0
- chrys/app/tui/widgets/sidebar/debug.py +195 -0
- chrys/app/tui/widgets/sidebar/empty_state.py +11 -0
- chrys/app/tui/widgets/sidebar/panel.py +198 -0
- chrys/app/tui/widgets/sidebar/tasks.py +198 -0
- chrys/app/tui/widgets/sidebar/toc.py +166 -0
- chrys/app/tui/widgets/sidebar/toc_types.py +30 -0
- chrys/app/tui/widgets/syntax_theme.py +85 -0
- chrys/app/tui/widgets/text_area.py +258 -0
- chrys/app/tui/widgets/trajectory/__init__.py +8 -0
- chrys/app/tui/widgets/trajectory/chartkit.py +264 -0
- chrys/app/tui/widgets/trajectory/insights.py +1266 -0
- chrys/app/tui/widgets/trajectory/overview.py +1101 -0
- chrys/app/tui/widgets/trajectory/panel.py +983 -0
- chrys/app/tui/widgets/trajectory/presentation.py +311 -0
- chrys/app/tui/widgets/trajectory/session_info.py +124 -0
- chrys/app/tui/widgets/trajectory/text_view.py +124 -0
- chrys/app/tui/widgets/trajectory/timeline.py +380 -0
- chrys/app/tui/widgets/welcome.py +126 -0
- chrys/app/tui/widgets/workflow/__init__.py +5 -0
- chrys/app/tui/widgets/workflow/edges.py +89 -0
- chrys/app/tui/widgets/workflow/graph.py +869 -0
- chrys/app/tui/widgets/workflow/info.py +310 -0
- chrys/app/tui/widgets/workflow/node_view.py +27 -0
- chrys/app/tui/widgets/workflow/output.py +225 -0
- chrys/app/tui/widgets/workflow/panel.py +658 -0
- chrys/app/tui/widgets/workflow/projector.py +324 -0
- chrys/app/tui/widgets/workflow/records.py +69 -0
- chrys/app/tui/widgets/workflow/scrollbar.py +82 -0
- chrys/app/tui/widgets/workflow/selection.py +151 -0
- chrys/app/tui/widgets/workflow/source.py +65 -0
- chrys/app/tui/widgets/workflow/text.py +257 -0
- chrys/app/tui/widgets/workflow/values.py +317 -0
- chrys/foundation/__init__.py +0 -0
- chrys/foundation/branding.py +15 -0
- chrys/foundation/config/__init__.py +7 -0
- chrys/foundation/config/coercion.py +374 -0
- chrys/foundation/config/context.py +34 -0
- chrys/foundation/config/env_file.py +141 -0
- chrys/foundation/config/env_layers.py +370 -0
- chrys/foundation/config/migrations.py +521 -0
- chrys/foundation/config/notification_events.py +22 -0
- chrys/foundation/config/process_settings.py +332 -0
- chrys/foundation/config/runtime_pointer.py +133 -0
- chrys/foundation/config/settings.py +1952 -0
- chrys/foundation/config/settings_store.py +996 -0
- chrys/foundation/config/spec.py +396 -0
- chrys/foundation/config/user_settings.py +140 -0
- chrys/foundation/config/warnings.py +262 -0
- chrys/foundation/config/web_values.py +135 -0
- chrys/foundation/config/yaml_store.py +487 -0
- chrys/foundation/errors/__init__.py +68 -0
- chrys/foundation/errors/_legacy.py +117 -0
- chrys/foundation/errors/_text.py +13 -0
- chrys/foundation/errors/_walk.py +85 -0
- chrys/foundation/errors/classify.py +278 -0
- chrys/foundation/errors/display.py +274 -0
- chrys/foundation/errors/formatting.py +283 -0
- chrys/foundation/errors/kinds.py +67 -0
- chrys/foundation/errors/network.py +497 -0
- chrys/foundation/errors/provider.py +445 -0
- chrys/foundation/errors/route.py +85 -0
- chrys/foundation/events/__init__.py +8 -0
- chrys/foundation/events/bus.py +143 -0
- chrys/foundation/events/types.py +1629 -0
- chrys/foundation/events/workflow.py +38 -0
- chrys/foundation/hosted_tools.py +142 -0
- chrys/foundation/i18n/__init__.py +32 -0
- chrys/foundation/i18n/_catalogs/zh-Hans/LC_MESSAGES/chrys.mo +0 -0
- chrys/foundation/i18n/catalogs.py +42 -0
- chrys/foundation/i18n/formatting.py +202 -0
- chrys/foundation/i18n/locale.py +92 -0
- chrys/foundation/i18n/localizer.py +187 -0
- chrys/foundation/i18n/messages.py +268 -0
- chrys/foundation/io/__init__.py +3 -0
- chrys/foundation/io/result_content.py +237 -0
- chrys/foundation/models/__init__.py +3 -0
- chrys/foundation/models/approval_reuse.py +23 -0
- chrys/foundation/models/ask_user.py +468 -0
- chrys/foundation/models/execution.py +18 -0
- chrys/foundation/models/history_markers.py +115 -0
- chrys/foundation/models/invocations.py +63 -0
- chrys/foundation/models/mutation_scope.py +28 -0
- chrys/foundation/models/session_env.py +87 -0
- chrys/foundation/models/session_surface.py +29 -0
- chrys/foundation/models/todos.py +74 -0
- chrys/foundation/models/turns.py +125 -0
- chrys/foundation/models/workflow_session.py +89 -0
- chrys/foundation/models/workspace.py +59 -0
- chrys/foundation/net/__init__.py +3 -0
- chrys/foundation/net/address_class.py +57 -0
- chrys/foundation/net/route_probe.py +94 -0
- chrys/foundation/net/url.py +107 -0
- chrys/foundation/observability/__init__.py +3 -0
- chrys/foundation/observability/exporters.py +174 -0
- chrys/foundation/observability/gate.py +31 -0
- chrys/foundation/observability/setup.py +497 -0
- chrys/foundation/observability/sink.py +228 -0
- chrys/foundation/patches/__init__.py +19 -0
- chrys/foundation/patches/mdurl_cache.py +59 -0
- chrys/foundation/patches/patcher.py +287 -0
- chrys/foundation/patches/staged_members.py +205 -0
- chrys/foundation/patches/textual_block_border.py +105 -0
- chrys/foundation/patches/textual_button_ansi.py +65 -0
- chrys/foundation/patches/textual_button_ansi_old.txt +68 -0
- chrys/foundation/patches/textual_callback_cache.py +248 -0
- chrys/foundation/patches/textual_callback_dispatch.py +109 -0
- chrys/foundation/patches/textual_compositor_cjk.py +566 -0
- chrys/foundation/patches/textual_dispatch_cache.py +150 -0
- chrys/foundation/patches/textual_ime_cursor_anchor.py +92 -0
- chrys/foundation/patches/textual_kitty_keyboard.py +268 -0
- chrys/foundation/patches/textual_lru_acyclic.py +241 -0
- chrys/foundation/patches/textual_message_pump.py +136 -0
- chrys/foundation/patches/textual_node_diet.py +875 -0
- chrys/foundation/patches/textual_one_shot_timer.py +48 -0
- chrys/foundation/patches/textual_option_list.py +90 -0
- chrys/foundation/patches/textual_precompose.py +89 -0
- chrys/foundation/patches/textual_pruned_tabs.py +69 -0
- chrys/foundation/patches/textual_reflow_reuse.py +1753 -0
- chrys/foundation/patches/textual_removed_node_caches.py +86 -0
- chrys/foundation/patches/textual_removed_screen_callbacks.py +55 -0
- chrys/foundation/patches/textual_selection_extract.py +48 -0
- chrys/foundation/patches/textual_strip_cycles.py +119 -0
- chrys/foundation/patches/textual_tab_selection.py +1611 -0
- chrys/foundation/patches/textual_timer_skip.py +70 -0
- chrys/foundation/patches/textual_utf8_decoder.py +106 -0
- chrys/foundation/patches/textual_win_sleep.py +167 -0
- chrys/foundation/patches/watchdog_fsevents.py +70 -0
- chrys/foundation/patches/watchdog_windows.py +52 -0
- chrys/foundation/platform/__init__.py +556 -0
- chrys/foundation/platform/c_api.py +32 -0
- chrys/foundation/platform/child_reap.py +107 -0
- chrys/foundation/platform/command_line.py +95 -0
- chrys/foundation/platform/files.py +1470 -0
- chrys/foundation/platform/output_capture.py +113 -0
- chrys/foundation/platform/paths.py +193 -0
- chrys/foundation/platform/process.py +1468 -0
- chrys/foundation/platform/pty_output.py +19 -0
- chrys/foundation/platform/runtime_paths.py +281 -0
- chrys/foundation/platform/win_console.py +129 -0
- chrys/foundation/reasoning_origin.py +67 -0
- chrys/foundation/recovery.py +16 -0
- chrys/foundation/retry.py +278 -0
- chrys/foundation/text/__init__.py +3 -0
- chrys/foundation/text/encoding.py +603 -0
- chrys/foundation/text/images.py +304 -0
- chrys/foundation/text/lines.py +24 -0
- chrys/foundation/text/mentions.py +90 -0
- chrys/foundation/text/model_json.py +25 -0
- chrys/foundation/text/reading_order.py +20 -0
- chrys/foundation/text/tokenizer.py +25 -0
- chrys/foundation/text/tool_output.py +287 -0
- chrys/foundation/text/yaml_io.py +62 -0
- chrys/foundation/tool_call_context.py +202 -0
- chrys/foundation/tool_execution_stamp.py +184 -0
- chrys/foundation/tool_invocation_order.py +48 -0
- chrys/foundation/tool_kinds.py +102 -0
- chrys/foundation/tool_result_metadata.py +287 -0
- chrys/foundation/trajectory/__init__.py +10 -0
- chrys/foundation/trajectory/context.py +481 -0
- chrys/foundation/trajectory/envelope.py +571 -0
- chrys/foundation/trajectory/event_types.py +294 -0
- chrys/foundation/trajectory/finalizers.py +46 -0
- chrys/foundation/trajectory/fingerprint.py +62 -0
- chrys/foundation/trajectory/ids.py +155 -0
- chrys/foundation/trajectory/keys.py +99 -0
- chrys/foundation/trajectory/lease.py +173 -0
- chrys/foundation/trajectory/metadata.py +72 -0
- chrys/foundation/trajectory/reader.py +271 -0
- chrys/foundation/trajectory/recovery.py +225 -0
- chrys/foundation/trajectory/revisions.py +152 -0
- chrys/foundation/trajectory/segments.py +225 -0
- chrys/foundation/trajectory/tools.py +117 -0
- chrys/foundation/trajectory/usage.py +151 -0
- chrys/foundation/trajectory/writer.py +972 -0
- chrys/foundation/trajectory_timing.py +97 -0
- chrys/foundation/util/__init__.py +3 -0
- chrys/foundation/util/async_tasks.py +29 -0
- chrys/foundation/util/chrys_headers.py +23 -0
- chrys/foundation/util/env_templates.py +104 -0
- chrys/foundation/util/filenames.py +96 -0
- chrys/foundation/util/header_charset.py +138 -0
- chrys/foundation/util/httpx_helpers.py +12 -0
- chrys/foundation/util/lock.py +236 -0
- chrys/foundation/util/once_close.py +46 -0
- chrys/foundation/util/session_ids.py +29 -0
- chrys/foundation/util/shell_tokens.py +88 -0
- chrys/foundation/util/sub_agent_context.py +38 -0
- chrys/foundation/util/time.py +35 -0
- chrys/foundation/util/unicode_scalars.py +36 -0
- chrys/foundation/vendor/__init__.py +43 -0
- chrys/foundation/vendor/ripgrep/rg-aarch64-apple-darwin +0 -0
- chrys/foundation/vendor/ripgrep/rg-aarch64-pc-windows-msvc.exe +0 -0
- chrys/foundation/vendor/ripgrep/rg-aarch64-unknown-linux-gnu +0 -0
- chrys/foundation/vendor/ripgrep/rg-x86_64-apple-darwin +0 -0
- chrys/foundation/vendor/ripgrep/rg-x86_64-pc-windows-msvc.exe +0 -0
- chrys/foundation/vendor/ripgrep/rg-x86_64-unknown-linux-musl +0 -0
- chrys/kernel/__init__.py +256 -0
- chrys/kernel/_content.py +1866 -0
- chrys/kernel/_loop_recorder.py +631 -0
- chrys/kernel/_null_overlay.py +1026 -0
- chrys/kernel/_result_ceiling.py +216 -0
- chrys/kernel/_serialization.py +431 -0
- chrys/kernel/_tool_arg_errors.py +1629 -0
- chrys/kernel/_tool_execution.py +1172 -0
- chrys/kernel/_tool_expansion.py +26 -0
- chrys/kernel/_types.py +2598 -0
- chrys/kernel/agent.py +994 -0
- chrys/kernel/client.py +1084 -0
- chrys/kernel/compaction.py +1315 -0
- chrys/kernel/exceptions.py +211 -0
- chrys/kernel/exchanges.py +683 -0
- chrys/kernel/identity.py +95 -0
- chrys/kernel/images.py +36 -0
- chrys/kernel/instrumentation.py +1618 -0
- chrys/kernel/loop.py +2308 -0
- chrys/kernel/middleware.py +616 -0
- chrys/kernel/sessions.py +604 -0
- chrys/kernel/tools.py +1061 -0
- chrys/kernel/types.py +126 -0
- chrys/orchestration/__init__.py +3 -0
- chrys/orchestration/engine/__init__.py +3 -0
- chrys/orchestration/engine/assembly.py +236 -0
- chrys/orchestration/engine/build/__init__.py +3 -0
- chrys/orchestration/engine/build/builder.py +1061 -0
- chrys/orchestration/engine/build/construction.py +408 -0
- chrys/orchestration/engine/build/loaded.py +139 -0
- chrys/orchestration/engine/engine.py +789 -0
- chrys/orchestration/engine/execution.py +771 -0
- chrys/orchestration/engine/loader.py +865 -0
- chrys/orchestration/engine/rollback.py +918 -0
- chrys/orchestration/engine/run/__init__.py +3 -0
- chrys/orchestration/engine/run/active_injection.py +419 -0
- chrys/orchestration/engine/run/attachments.py +519 -0
- chrys/orchestration/engine/run/bindings.py +1095 -0
- chrys/orchestration/engine/run/coordinator.py +1062 -0
- chrys/orchestration/engine/run/finalizer.py +417 -0
- chrys/orchestration/engine/run/input_refs.py +60 -0
- chrys/orchestration/engine/run/prompt_content.py +457 -0
- chrys/orchestration/engine/run/resume.py +299 -0
- chrys/orchestration/engine/run/retry.py +948 -0
- chrys/orchestration/engine/run/runner.py +625 -0
- chrys/orchestration/engine/run/runtime_skills.py +146 -0
- chrys/orchestration/engine/run/sub_agent_coordination.py +126 -0
- chrys/orchestration/engine/run/turn_hooks.py +258 -0
- chrys/orchestration/engine/run/turn_state.py +149 -0
- chrys/orchestration/engine/run/working_dir.py +50 -0
- chrys/orchestration/engine/session_lifecycle.py +2013 -0
- chrys/orchestration/engine/state/__init__.py +3 -0
- chrys/orchestration/engine/state/active_session.py +183 -0
- chrys/orchestration/engine/state/controls.py +639 -0
- chrys/orchestration/engine/state/current_agent.py +26 -0
- chrys/orchestration/engine/state/lifecycle_permits.py +395 -0
- chrys/orchestration/engine/state/machine.py +193 -0
- chrys/orchestration/engine/state/session_writer.py +434 -0
- chrys/orchestration/engine/trajectory.py +714 -0
- chrys/orchestration/engine/usage.py +118 -0
- chrys/orchestration/invoker/__init__.py +3 -0
- chrys/orchestration/invoker/acp.py +727 -0
- chrys/orchestration/invoker/acp_protocol.py +1115 -0
- chrys/orchestration/invoker/acp_spec.py +79 -0
- chrys/orchestration/invoker/attempts.py +994 -0
- chrys/orchestration/invoker/child_compaction.py +131 -0
- chrys/orchestration/invoker/child_history.py +99 -0
- chrys/orchestration/invoker/contracts.py +253 -0
- chrys/orchestration/invoker/evidence.py +94 -0
- chrys/orchestration/invoker/kernel.py +343 -0
- chrys/orchestration/invoker/origin.py +79 -0
- chrys/orchestration/invoker/resources.py +343 -0
- chrys/orchestration/invoker/runtime.py +299 -0
- chrys/orchestration/invoker/usage.py +80 -0
- chrys/orchestration/session_hooks.py +117 -0
- chrys/orchestration/session_host.py +1023 -0
- chrys/orchestration/session_resources.py +95 -0
- chrys/orchestration/session_usage.py +219 -0
- chrys/orchestration/startup.py +255 -0
- chrys/orchestration/sub_agents/__init__.py +3 -0
- chrys/orchestration/sub_agents/acp_policy.py +269 -0
- chrys/orchestration/sub_agents/kernel_policy.py +848 -0
- chrys/orchestration/sub_agents/registration.py +44 -0
- chrys/orchestration/sub_agents/shell.py +337 -0
- chrys/orchestration/sub_agents/tools.py +2228 -0
- chrys/orchestration/workflows/__init__.py +3 -0
- chrys/orchestration/workflows/agent_archive.py +156 -0
- chrys/orchestration/workflows/agent_node.py +894 -0
- chrys/orchestration/workflows/agent_node_build.py +687 -0
- chrys/orchestration/workflows/catalog.py +332 -0
- chrys/orchestration/workflows/coordinator.py +771 -0
- chrys/orchestration/workflows/hooks.py +176 -0
- chrys/orchestration/workflows/preview.py +322 -0
- chrys/orchestration/workflows/rollback.py +151 -0
- chrys/orchestration/workflows/runner.py +986 -0
- chrys/orchestration/workflows/session.py +390 -0
- chrys/orchestration/workflows/settings.py +97 -0
- chrys/orchestration/workflows/validation.py +674 -0
- chrys/orchestration/workflows/worker_client.py +1002 -0
- chrys/service/__init__.py +3 -0
- chrys/service/acp_client/__init__.py +65 -0
- chrys/service/acp_client/_transport.py +922 -0
- chrys/service/acp_client/client.py +1311 -0
- chrys/service/acp_client/errors.py +224 -0
- chrys/service/acp_client/protocol.py +220 -0
- chrys/service/acp_client/spawn.py +239 -0
- chrys/service/acp_client/spec.py +100 -0
- chrys/service/agent_middleware/__init__.py +60 -0
- chrys/service/agent_middleware/_metadata_keys.py +52 -0
- chrys/service/agent_middleware/control/__init__.py +3 -0
- chrys/service/agent_middleware/control/approval.py +769 -0
- chrys/service/agent_middleware/control/approval_hooks.py +62 -0
- chrys/service/agent_middleware/control/ask_user.py +207 -0
- chrys/service/agent_middleware/control/interrupt.py +50 -0
- chrys/service/agent_middleware/control/sleep.py +118 -0
- chrys/service/agent_middleware/control/todo.py +117 -0
- chrys/service/agent_middleware/events/__init__.py +3 -0
- chrys/service/agent_middleware/events/hook_dispatch.py +250 -0
- chrys/service/agent_middleware/events/hosted_tools.py +1762 -0
- chrys/service/agent_middleware/events/intermediate_text.py +128 -0
- chrys/service/agent_middleware/events/rejection_metadata.py +50 -0
- chrys/service/agent_middleware/events/result_persistence.py +98 -0
- chrys/service/agent_middleware/events/sub_agent_events.py +951 -0
- chrys/service/agent_middleware/events/tool_error_text.py +22 -0
- chrys/service/agent_middleware/events/tool_events.py +779 -0
- chrys/service/agent_middleware/injection.py +510 -0
- chrys/service/agent_middleware/reminders/__init__.py +91 -0
- chrys/service/agent_middleware/reminders/archive_pointer.py +154 -0
- chrys/service/agent_middleware/reminders/base.py +25 -0
- chrys/service/agent_middleware/reminders/context_usage.py +74 -0
- chrys/service/agent_middleware/reminders/file_change.py +63 -0
- chrys/service/agent_middleware/reminders/mcp.py +39 -0
- chrys/service/agent_middleware/reminders/profile_switch.py +106 -0
- chrys/service/agent_middleware/reminders/runtime_env.py +190 -0
- chrys/service/agent_middleware/reminders/skills.py +44 -0
- chrys/service/agent_middleware/reminders/sub_agents.py +35 -0
- chrys/service/agent_middleware/reminders/todo.py +35 -0
- chrys/service/agent_middleware/reminders/turn_line.py +48 -0
- chrys/service/agent_middleware/response_validation.py +1380 -0
- chrys/service/agent_middleware/system_reminder.py +1107 -0
- chrys/service/agent_middleware/validators.py +396 -0
- chrys/service/analytics/__init__.py +124 -0
- chrys/service/analytics/_actions.py +896 -0
- chrys/service/analytics/_context_evidence.py +357 -0
- chrys/service/analytics/_critical_path.py +179 -0
- chrys/service/analytics/_facts.py +919 -0
- chrys/service/analytics/_insights.py +769 -0
- chrys/service/analytics/_metric_ops.py +83 -0
- chrys/service/analytics/_session_projection.py +460 -0
- chrys/service/analytics/_timeline.py +434 -0
- chrys/service/analytics/_turn_graph.py +1237 -0
- chrys/service/analytics/_turns.py +1377 -0
- chrys/service/analytics/_workflows.py +171 -0
- chrys/service/analytics/aggregation.py +1474 -0
- chrys/service/analytics/classification.py +128 -0
- chrys/service/analytics/export.py +803 -0
- chrys/service/analytics/findings.py +282 -0
- chrys/service/analytics/math.py +79 -0
- chrys/service/analytics/model.py +886 -0
- chrys/service/analytics/reader.py +321 -0
- chrys/service/approval/__init__.py +3 -0
- chrys/service/approval/arbitration.py +102 -0
- chrys/service/approval/command_identity.py +109 -0
- chrys/service/approval/correlation.py +57 -0
- chrys/service/approval/grant_store.py +108 -0
- chrys/service/approval/judge.py +589 -0
- chrys/service/approval/level.py +15 -0
- chrys/service/approval/policy.py +209 -0
- chrys/service/approval/reuse.py +223 -0
- chrys/service/approval/reuse_binding.py +133 -0
- chrys/service/approval/safety_classifier.py +536 -0
- chrys/service/approval/turn_context.py +49 -0
- chrys/service/context/__init__.py +3 -0
- chrys/service/context/compaction/__init__.py +38 -0
- chrys/service/context/compaction/breaker.py +156 -0
- chrys/service/context/compaction/budgets.py +93 -0
- chrys/service/context/compaction/calibration.py +77 -0
- chrys/service/context/compaction/compression.py +690 -0
- chrys/service/context/compaction/current_turn_drop.py +458 -0
- chrys/service/context/compaction/events.py +201 -0
- chrys/service/context/compaction/exclusions.py +261 -0
- chrys/service/context/compaction/groups.py +361 -0
- chrys/service/context/compaction/last_words.py +1996 -0
- chrys/service/context/compaction/last_words_state.py +752 -0
- chrys/service/context/compaction/scoped.py +472 -0
- chrys/service/context/compaction/spill.py +1947 -0
- chrys/service/context/compaction/strategy.py +1116 -0
- chrys/service/context/compaction/summaries.py +319 -0
- chrys/service/context/compaction/turns.py +375 -0
- chrys/service/context/manager.py +174 -0
- chrys/service/context/memory_loader.py +792 -0
- chrys/service/context/middleware/__init__.py +3 -0
- chrys/service/context/middleware/usage.py +332 -0
- chrys/service/context/providers/__init__.py +3 -0
- chrys/service/context/providers/context_management.py +432 -0
- chrys/service/context/providers/history.py +647 -0
- chrys/service/context/providers/memory.py +50 -0
- chrys/service/context/tool_content.py +22 -0
- chrys/service/hooks/__init__.py +37 -0
- chrys/service/hooks/detached_worker.py +118 -0
- chrys/service/hooks/docs/README.md +14 -0
- chrys/service/hooks/docs/authoring.md +684 -0
- chrys/service/hooks/docs/configuration.md +499 -0
- chrys/service/hooks/docs/design.md +359 -0
- chrys/service/hooks/docs/project-hooks.md +348 -0
- chrys/service/hooks/events.py +157 -0
- chrys/service/hooks/loader.py +665 -0
- chrys/service/hooks/manager.py +807 -0
- chrys/service/hooks/matcher.py +111 -0
- chrys/service/hooks/outbox.py +294 -0
- chrys/service/hooks/runner.py +572 -0
- chrys/service/hooks/schema.py +407 -0
- chrys/service/llm/__init__.py +7 -0
- chrys/service/llm/_structured_outputs.py +192 -0
- chrys/service/llm/anthropic_messages/__init__.py +9 -0
- chrys/service/llm/anthropic_messages/client.py +254 -0
- chrys/service/llm/anthropic_messages/decode.py +331 -0
- chrys/service/llm/anthropic_messages/history.py +279 -0
- chrys/service/llm/anthropic_messages/request.py +323 -0
- chrys/service/llm/anthropic_messages/server_tools.py +319 -0
- chrys/service/llm/anthropic_messages/stream.py +297 -0
- chrys/service/llm/anthropic_messages/thinking_binding.py +156 -0
- chrys/service/llm/chat_completions/__init__.py +9 -0
- chrys/service/llm/chat_completions/client.py +369 -0
- chrys/service/llm/chat_completions/decode.py +338 -0
- chrys/service/llm/chat_completions/history.py +657 -0
- chrys/service/llm/chat_completions/reasoning.py +244 -0
- chrys/service/llm/chat_completions/request.py +192 -0
- chrys/service/llm/chat_completions/stream.py +546 -0
- chrys/service/llm/chat_completions/validation.py +308 -0
- chrys/service/llm/clients.py +613 -0
- chrys/service/llm/images.py +65 -0
- chrys/service/llm/mock.py +413 -0
- chrys/service/llm/observer.py +446 -0
- chrys/service/llm/one_shot.py +106 -0
- chrys/service/llm/openai_exceptions.py +93 -0
- chrys/service/llm/openai_responses/__init__.py +10 -0
- chrys/service/llm/openai_responses/client.py +323 -0
- chrys/service/llm/openai_responses/decode.py +432 -0
- chrys/service/llm/openai_responses/history.py +519 -0
- chrys/service/llm/openai_responses/hosted.py +625 -0
- chrys/service/llm/openai_responses/replay.py +629 -0
- chrys/service/llm/openai_responses/request.py +342 -0
- chrys/service/llm/openai_responses/stream.py +847 -0
- chrys/service/llm/openai_timestamps.py +57 -0
- chrys/service/llm/providers.py +107 -0
- chrys/service/llm/proxy_route.py +54 -0
- chrys/service/llm/raw_http_log.py +309 -0
- chrys/service/llm/route_facts.py +63 -0
- chrys/service/llm/route_sessions.py +49 -0
- chrys/service/llm/sdk_anthropic.py +18 -0
- chrys/service/llm/sdk_headers.py +47 -0
- chrys/service/llm/sdk_openai.py +18 -0
- chrys/service/llm/sdk_retry.py +59 -0
- chrys/service/llm/wire_client.py +246 -0
- chrys/service/mcp/__init__.py +3 -0
- chrys/service/mcp/_connection.py +235 -0
- chrys/service/mcp/_http_transport.py +350 -0
- chrys/service/mcp/_progressive.py +459 -0
- chrys/service/mcp/_stdio_transport.py +614 -0
- chrys/service/mcp/_tool_mixins.py +96 -0
- chrys/service/mcp/adapter.py +1031 -0
- chrys/service/mcp/cache.py +476 -0
- chrys/service/mcp/content.py +32 -0
- chrys/service/mcp/errors.py +169 -0
- chrys/service/mcp/owned.py +1330 -0
- chrys/service/mcp/result_limits.py +168 -0
- chrys/service/mcp/thinking_warning.py +95 -0
- chrys/service/mcp/validation.py +74 -0
- chrys/service/mutations/__init__.py +84 -0
- chrys/service/mutations/coordination.py +894 -0
- chrys/service/mutations/detector.py +458 -0
- chrys/service/mutations/git_calibrator.py +397 -0
- chrys/service/mutations/git_state.py +647 -0
- chrys/service/mutations/pipeline.py +779 -0
- chrys/service/mutations/scanner.py +466 -0
- chrys/service/mutations/snapshot_files.py +233 -0
- chrys/service/mutations/store.py +625 -0
- chrys/service/mutations/tool_names.py +15 -0
- chrys/service/mutations/trace.py +246 -0
- chrys/service/mutations/tracker.py +1289 -0
- chrys/service/mutations/types.py +559 -0
- chrys/service/mutations/workspace_changes.py +1583 -0
- chrys/service/profiles/__init__.py +2 -0
- chrys/service/profiles/agents/__init__.py +3 -0
- chrys/service/profiles/agents/builtins/Code.yaml +199 -0
- chrys/service/profiles/agents/builtins/Explore.yaml +62 -0
- chrys/service/profiles/agents/builtins/General.yaml +114 -0
- chrys/service/profiles/agents/builtins/QA.yaml +128 -0
- chrys/service/profiles/agents/loader.py +808 -0
- chrys/service/profiles/agents/registry.py +727 -0
- chrys/service/profiles/agents/schema.py +371 -0
- chrys/service/profiles/agents/serializer.py +196 -0
- chrys/service/profiles/coercion.py +22 -0
- chrys/service/profiles/models/__init__.py +3 -0
- chrys/service/profiles/models/env_bridge.py +157 -0
- chrys/service/profiles/models/loader.py +282 -0
- chrys/service/profiles/models/options.py +438 -0
- chrys/service/profiles/models/registry.py +104 -0
- chrys/service/profiles/models/resolver.py +286 -0
- chrys/service/profiles/models/schema.py +91 -0
- chrys/service/profiles/models/serializer.py +76 -0
- chrys/service/session/__init__.py +3 -0
- chrys/service/session/checkpoint.py +156 -0
- chrys/service/session/history.py +1616 -0
- chrys/service/session/message_metadata.py +151 -0
- chrys/service/session/persistence.py +435 -0
- chrys/service/session/runtime_metadata.py +210 -0
- chrys/service/session/sub_agent_logs.py +1069 -0
- chrys/service/session/sub_agent_transcript.py +654 -0
- chrys/service/skills/__init__.py +3 -0
- chrys/service/skills/adapter.py +408 -0
- chrys/service/skills/constants.py +8 -0
- chrys/service/skills/loader.py +575 -0
- chrys/service/skills/model.py +130 -0
- chrys/service/skills/provider.py +841 -0
- chrys/service/skills/runner.py +390 -0
- chrys/service/state/__init__.py +3 -0
- chrys/service/state/_fork.py +710 -0
- chrys/service/state/_session_files.py +175 -0
- chrys/service/state/_session_meta.py +552 -0
- chrys/service/state/locks.py +154 -0
- chrys/service/state/serializers.py +156 -0
- chrys/service/state/session_catalog.py +361 -0
- chrys/service/state/session_listing.py +84 -0
- chrys/service/state/session_migration.py +446 -0
- chrys/service/state/session_mru.py +315 -0
- chrys/service/state/store.py +2132 -0
- chrys/service/state/workflow.py +158 -0
- chrys/service/text_blocks.py +47 -0
- chrys/service/todos/__init__.py +3 -0
- chrys/service/todos/reminder.py +31 -0
- chrys/service/todos/tracker.py +58 -0
- chrys/service/tools/__init__.py +3 -0
- chrys/service/tools/approval_targets.py +92 -0
- chrys/service/tools/builtins/__init__.py +3 -0
- chrys/service/tools/builtins/ask_user.py +326 -0
- chrys/service/tools/builtins/doc_converter/__init__.py +494 -0
- chrys/service/tools/builtins/doc_converter/artifacts.py +392 -0
- chrys/service/tools/builtins/doc_converter/parsers/__init__.py +3 -0
- chrys/service/tools/builtins/doc_converter/parsers/_table.py +34 -0
- chrys/service/tools/builtins/doc_converter/parsers/base.py +101 -0
- chrys/service/tools/builtins/doc_converter/parsers/docx.py +88 -0
- chrys/service/tools/builtins/doc_converter/parsers/pdf.py +144 -0
- chrys/service/tools/builtins/doc_converter/parsers/pptx.py +103 -0
- chrys/service/tools/builtins/doc_converter/parsers/xls.py +32 -0
- chrys/service/tools/builtins/doc_converter/parsers/xlsx.py +51 -0
- chrys/service/tools/builtins/doc_converter/registry.py +55 -0
- chrys/service/tools/builtins/filesystem.py +1071 -0
- chrys/service/tools/builtins/search.py +1265 -0
- chrys/service/tools/builtins/shell.py +967 -0
- chrys/service/tools/builtins/shell_command_filtering/__init__.py +5 -0
- chrys/service/tools/builtins/shell_command_filtering/policy.py +60 -0
- chrys/service/tools/builtins/shell_command_filtering/presets.py +152 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/__init__.py +358 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/commands.py +416 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/git.py +408 -0
- chrys/service/tools/builtins/shell_command_filtering/readonly/syntax.py +87 -0
- chrys/service/tools/builtins/shell_command_filtering/tokenizer.py +214 -0
- chrys/service/tools/builtins/shell_filter.py +24 -0
- chrys/service/tools/builtins/sleep.py +91 -0
- chrys/service/tools/builtins/todo.py +64 -0
- chrys/service/tools/builtins/web/__init__.py +6 -0
- chrys/service/tools/builtins/web/build.py +268 -0
- chrys/service/tools/builtins/web/config.py +338 -0
- chrys/service/tools/builtins/web/credentials.py +37 -0
- chrys/service/tools/builtins/web/fetch/__init__.py +3 -0
- chrys/service/tools/builtins/web/fetch/cache.py +68 -0
- chrys/service/tools/builtins/web/fetch/convert.py +56 -0
- chrys/service/tools/builtins/web/fetch/tool.py +223 -0
- chrys/service/tools/builtins/web/hosted.py +61 -0
- chrys/service/tools/builtins/web/http.py +330 -0
- chrys/service/tools/builtins/web/progress.py +18 -0
- chrys/service/tools/builtins/web/search/__init__.py +3 -0
- chrys/service/tools/builtins/web/search/exa_mcp.py +146 -0
- chrys/service/tools/builtins/web/search/html.py +152 -0
- chrys/service/tools/builtins/web/search/json_api.py +227 -0
- chrys/service/tools/builtins/web/search/providers.py +77 -0
- chrys/service/tools/builtins/web/search/tool.py +218 -0
- chrys/service/tools/builtins/web/search/types.py +28 -0
- chrys/service/tools/builtins/web/tls_identity.py +66 -0
- chrys/service/tools/kinds.py +115 -0
- chrys/service/tools/names.py +47 -0
- chrys/service/tools/registry.py +242 -0
- chrys/service/tools/result_metadata.py +103 -0
- chrys/service/tools/session_artifacts.py +196 -0
- chrys/service/tools/spill.py +218 -0
- chrys/service/tools/workspace_paths.py +81 -0
- chrys/service/trajectory/__init__.py +11 -0
- chrys/service/trajectory/approvals.py +201 -0
- chrys/service/trajectory/compaction.py +420 -0
- chrys/service/trajectory/fork.py +75 -0
- chrys/service/trajectory/hooks.py +217 -0
- chrys/service/trajectory/items.py +41 -0
- chrys/service/trajectory/preparation.py +374 -0
- chrys/service/trajectory/retries.py +95 -0
- chrys/service/trajectory/revisions.py +129 -0
- chrys/service/trajectory/segmented.py +163 -0
- chrys/service/trajectory/session.py +762 -0
- chrys/service/trajectory/state.py +83 -0
- chrys/service/trajectory/sub_agents.py +169 -0
- chrys/service/trajectory/tombstone.py +262 -0
- chrys/service/trajectory/tools.py +323 -0
- chrys/service/trajectory/validation.py +130 -0
- chrys/service/trajectory/waits.py +161 -0
- chrys/service/trajectory/workflow.py +148 -0
- chrys/service/vision.py +128 -0
- chrys/service/workflows/__init__.py +3 -0
- chrys/service/workflows/admission.py +151 -0
- chrys/service/workflows/artifacts.py +109 -0
- chrys/service/workflows/asks.py +130 -0
- chrys/service/workflows/builtins/__init__.py +12 -0
- chrys/service/workflows/builtins/demo-workflow.manifest.json +635 -0
- chrys/service/workflows/builtins/demo-workflow.py +756 -0
- chrys/service/workflows/discovery.py +554 -0
- chrys/service/workflows/environment.py +284 -0
- chrys/service/workflows/graph.py +430 -0
- chrys/service/workflows/history.py +82 -0
- chrys/service/workflows/interpreter.py +107 -0
- chrys/service/workflows/journal.py +334 -0
- chrys/service/workflows/layout.py +56 -0
- chrys/service/workflows/ledger.py +149 -0
- chrys/service/workflows/model_selection.py +18 -0
- chrys/service/workflows/orphans.py +209 -0
- chrys/service/workflows/outcomes.py +46 -0
- chrys/service/workflows/protocol.py +210 -0
- chrys/service/workflows/records.py +142 -0
- chrys/service/workflows/scheduler.py +770 -0
- chrys/service/workflows/sdk/__init__.py +51 -0
- chrys/service/workflows/sdk/_ask.py +167 -0
- chrys/service/workflows/sdk/_builder.py +781 -0
- chrys/service/workflows/sdk/_values.py +92 -0
- chrys/service/workflows/sdk_artifact.py +74 -0
- chrys/service/workflows/store.py +494 -0
- chrys/service/workflows/transcript.py +102 -0
- chrys/service/workflows/values.py +73 -0
- chrys/service/workflows/worker_host.py +1820 -0
- chrys/workflows.py +38 -0
- icode_tui-0.29.1.dist-info/METADATA +104 -0
- icode_tui-0.29.1.dist-info/RECORD +1138 -0
- icode_tui-0.29.1.dist-info/WHEEL +4 -0
- icode_tui-0.29.1.dist-info/entry_points.txt +2 -0
- icode_tui-0.29.1.dist-info/licenses/LICENSE +202 -0
- icode_tui-0.29.1.dist-info/licenses/NOTICE +1955 -0
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Copyright (c) 2021 Will McGugan
|
|
2
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
3
|
+
# Contains code adapted from Textual (MIT License; see NOTICE).
|
|
4
|
+
|
|
5
|
+
"""Patch: fast-path default Textual ``events.Callback`` dispatch.
|
|
6
|
+
|
|
7
|
+
Textual schedules many internal callbacks while scrolling. The default
|
|
8
|
+
``events.Callback`` handler only guards app shutdown / missing-screen cases and
|
|
9
|
+
then invokes the stored callable, but Textual still routes it through the full
|
|
10
|
+
event dispatch pipeline: handler-name lookup, MRO dispatch lookup, event
|
|
11
|
+
logging, and generic ``on_event`` indirection.
|
|
12
|
+
|
|
13
|
+
This runtime patch specializes that one internal event when the receiving pump
|
|
14
|
+
uses Textual's default event and callback handlers. Pumps with custom
|
|
15
|
+
``on_event``, ``_on_callback``, or ``on_callback`` handlers stay on the
|
|
16
|
+
original dispatch path.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
_RUNTIME_PATCH_MARKER = "_chrys_callback_dispatch_fast_path"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def apply_runtime_patch() -> None:
|
|
27
|
+
"""Install a default ``events.Callback`` fast path on ``MessagePump``."""
|
|
28
|
+
try:
|
|
29
|
+
import textual.message_pump as message_pump_mod
|
|
30
|
+
from textual import events
|
|
31
|
+
from textual.message import Message
|
|
32
|
+
from textual.message_pump import MessagePump
|
|
33
|
+
except ImportError:
|
|
34
|
+
return
|
|
35
|
+
|
|
36
|
+
existing = MessagePump._dispatch_message
|
|
37
|
+
if getattr(existing, _RUNTIME_PATCH_MARKER, False):
|
|
38
|
+
return
|
|
39
|
+
|
|
40
|
+
original_dispatch_message = existing
|
|
41
|
+
default_callback_handler_cache: dict[type, bool] = {}
|
|
42
|
+
callback_message_mro = tuple(t for t in events.Callback.__mro__ if issubclass(t, Message))
|
|
43
|
+
|
|
44
|
+
def uses_default_callback_handler(pump: Any) -> bool:
|
|
45
|
+
"""Return true when ``pump`` would use Textual's default callback path."""
|
|
46
|
+
pump_cls = type(pump)
|
|
47
|
+
cached = default_callback_handler_cache.get(pump_cls)
|
|
48
|
+
if cached is not None:
|
|
49
|
+
return cached
|
|
50
|
+
|
|
51
|
+
for cls in pump_cls.__mro__:
|
|
52
|
+
method = cls.__dict__.get("on_event")
|
|
53
|
+
if method is not None:
|
|
54
|
+
if cls is not MessagePump and method is not MessagePump.on_event:
|
|
55
|
+
default_callback_handler_cache[pump_cls] = False
|
|
56
|
+
return False
|
|
57
|
+
break
|
|
58
|
+
|
|
59
|
+
for cls in pump_cls.__mro__:
|
|
60
|
+
decorated_handlers = cls.__dict__.get("_decorated_handlers")
|
|
61
|
+
if decorated_handlers:
|
|
62
|
+
for message_cls in callback_message_mro:
|
|
63
|
+
if decorated_handlers.get(message_cls):
|
|
64
|
+
default_callback_handler_cache[pump_cls] = False
|
|
65
|
+
return False
|
|
66
|
+
|
|
67
|
+
method = cls.__dict__.get("_on_callback") or cls.__dict__.get("on_callback")
|
|
68
|
+
if method is None:
|
|
69
|
+
continue
|
|
70
|
+
cached = cls is MessagePump and method is MessagePump.on_callback
|
|
71
|
+
default_callback_handler_cache[pump_cls] = cached
|
|
72
|
+
return cached
|
|
73
|
+
|
|
74
|
+
default_callback_handler_cache[pump_cls] = False
|
|
75
|
+
return False
|
|
76
|
+
|
|
77
|
+
async def _dispatch_message(self: Any, message: Any) -> None:
|
|
78
|
+
_rich_traceback_guard = True
|
|
79
|
+
if not isinstance(message, events.Callback) or not uses_default_callback_handler(self):
|
|
80
|
+
await original_dispatch_message(self, message)
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if message.no_dispatch:
|
|
84
|
+
return
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
message_hook = message_pump_mod.message_hook_context_var.get()
|
|
88
|
+
except LookupError:
|
|
89
|
+
pass
|
|
90
|
+
else:
|
|
91
|
+
message_hook(message)
|
|
92
|
+
|
|
93
|
+
with self.prevent(*message._prevent):
|
|
94
|
+
app = self.app
|
|
95
|
+
if not message._no_default_action and not app._closing:
|
|
96
|
+
try:
|
|
97
|
+
_ = app.screen
|
|
98
|
+
except Exception:
|
|
99
|
+
self.log.warning(f"Not invoking timer callback {message.callback!r} because there is no screen.")
|
|
100
|
+
else:
|
|
101
|
+
await message_pump_mod.invoke(message.callback)
|
|
102
|
+
if self._next_callbacks:
|
|
103
|
+
await self._flush_next_callbacks()
|
|
104
|
+
|
|
105
|
+
setattr(_dispatch_message, _RUNTIME_PATCH_MARKER, True)
|
|
106
|
+
_dispatch_message._original = original_dispatch_message
|
|
107
|
+
_dispatch_message._default_callback_handler_cache = default_callback_handler_cache
|
|
108
|
+
_dispatch_message._uses_default_callback_handler = uses_default_callback_handler
|
|
109
|
+
MessagePump._dispatch_message = _dispatch_message
|
|
@@ -0,0 +1,566 @@
|
|
|
1
|
+
# Copyright (c) 2021 Will McGugan
|
|
2
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
3
|
+
# Contains code adapted from Textual (MIT License; see NOTICE).
|
|
4
|
+
|
|
5
|
+
"""Patch: fix CJK double-width character rendering corruption in Textual compositor.
|
|
6
|
+
|
|
7
|
+
Problem
|
|
8
|
+
-------
|
|
9
|
+
The compositor divides widget strips at "cut" boundaries (vertical lines where
|
|
10
|
+
widget edges align). When a cut falls inside a double-width CJK character,
|
|
11
|
+
``strip.divide()`` replaces it with two single-width spaces. This corrupts the
|
|
12
|
+
display whenever overlapping widget boundaries happen to bisect a wide character.
|
|
13
|
+
|
|
14
|
+
Partial terminal updates have a second boundary: the right edge of a dirty span.
|
|
15
|
+
``ChopsUpdate.render_segments()`` crops a winning strip to that edge, and
|
|
16
|
+
``Strip.crop()`` likewise substitutes a space when the edge lands inside a
|
|
17
|
+
double-width character. The next cells are left from the previous frame, which
|
|
18
|
+
makes the missing character appear to blink as the underlying widget refreshes.
|
|
19
|
+
|
|
20
|
+
Solution
|
|
21
|
+
--------
|
|
22
|
+
Introduce "effective cuts" -- only divide strips at cuts where at least one
|
|
23
|
+
adjacent chop is already claimed by a higher-priority widget. When the same
|
|
24
|
+
widget owns both sides of a cut, the division is skipped and the wider strip
|
|
25
|
+
is preserved intact. Follower chop positions receive a ``_MERGED_STRIP``
|
|
26
|
+
sentinel that prevents lower-priority widgets from filling those slots.
|
|
27
|
+
|
|
28
|
+
Additionally, ``ChopsUpdate`` no longer pre-computes ``chop_ends`` from the cut
|
|
29
|
+
array; instead it derives each strip's end from its actual ``cell_length``, which
|
|
30
|
+
correctly accounts for merged (wider-than-bucket) strips.
|
|
31
|
+
|
|
32
|
+
Before the raw terminal path crops at a dirty-span edge, advance that edge to the
|
|
33
|
+
next complete character boundary. This can overdraw at most one cell for the
|
|
34
|
+
double-width characters covered here; ZWJ grapheme sequences and zero-width
|
|
35
|
+
combining-mark boundaries remain outside this patch's scope.
|
|
36
|
+
|
|
37
|
+
Upgrade warning: ``_compositor.py`` is one all-or-nothing patch group containing
|
|
38
|
+
these 11 CJK fragments plus one tab-selection fragment. A mismatch in any of the
|
|
39
|
+
12 fragments aborts the entire file group. Textual is imported before
|
|
40
|
+
``bootstrap_runtime()`` on the TUI path, so the runtime patch stages the same CJK
|
|
41
|
+
fragments in memory and installs all affected methods on the existing classes.
|
|
42
|
+
It preserves imported class aliases and instances, and applies independently of
|
|
43
|
+
whether the file patch has already written the next-process implementation.
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
from __future__ import annotations
|
|
47
|
+
import __future__
|
|
48
|
+
|
|
49
|
+
import ast
|
|
50
|
+
import logging
|
|
51
|
+
from bisect import bisect_left, bisect_right
|
|
52
|
+
from pathlib import Path
|
|
53
|
+
from typing import Any
|
|
54
|
+
|
|
55
|
+
from chrys.foundation.patches.patcher import FilePatch, register
|
|
56
|
+
|
|
57
|
+
_RUNTIME_PATCH_MARKER = "_chrys_complete_cjk_compositor"
|
|
58
|
+
_RUNTIME_PATCH_TEXTUAL_VERSION = "8.2.7"
|
|
59
|
+
logger = logging.getLogger(__name__)
|
|
60
|
+
_RUNTIME_TARGETS = {
|
|
61
|
+
"ChopsUpdate": ("__init__", "__rich_console__", "render_segments"),
|
|
62
|
+
"Compositor": ("_get_renders", "render_full_update", "render_partial_update", "render_strips", "_render_chops"),
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
# ---------------------------------------------------------------------------
|
|
66
|
+
# Patch 1: add bisect imports
|
|
67
|
+
# ---------------------------------------------------------------------------
|
|
68
|
+
_OLD_IMPORT = "from operator import itemgetter"
|
|
69
|
+
|
|
70
|
+
_NEW_IMPORT = """\
|
|
71
|
+
from bisect import bisect_left, bisect_right
|
|
72
|
+
from operator import itemgetter"""
|
|
73
|
+
|
|
74
|
+
# ---------------------------------------------------------------------------
|
|
75
|
+
# Patch 2: add _MERGED_STRIP and _ALWAYS_TRUE sentinels
|
|
76
|
+
# ---------------------------------------------------------------------------
|
|
77
|
+
_OLD_SENTINELS = """\
|
|
78
|
+
from textual.strip import Strip, StripRenderable
|
|
79
|
+
from textual.widget import Widget
|
|
80
|
+
|
|
81
|
+
if TYPE_CHECKING:"""
|
|
82
|
+
|
|
83
|
+
_NEW_SENTINELS = """\
|
|
84
|
+
from textual.strip import Strip, StripRenderable
|
|
85
|
+
from textual.widget import Widget
|
|
86
|
+
|
|
87
|
+
# Sentinel strip used to mark "merged" chop positions.
|
|
88
|
+
# When a higher-priority widget wins both sides of a cut, we avoid dividing its
|
|
89
|
+
# strip there (which would split double-width CJK characters). The leader chop
|
|
90
|
+
# gets the wide un-split strip; follower chops get this sentinel so that
|
|
91
|
+
# lower-priority widgets cannot fill them (which would corrupt the display).
|
|
92
|
+
_MERGED_STRIP: Strip = Strip([], 0)
|
|
93
|
+
|
|
94
|
+
_ALWAYS_TRUE: Callable[[int], bool] = lambda _: True
|
|
95
|
+
|
|
96
|
+
if TYPE_CHECKING:"""
|
|
97
|
+
|
|
98
|
+
# ---------------------------------------------------------------------------
|
|
99
|
+
# Patch 3: remove chop_ends from ChopsUpdate.__init__
|
|
100
|
+
# ---------------------------------------------------------------------------
|
|
101
|
+
_OLD_CHOPS_INIT = """\
|
|
102
|
+
def __init__(
|
|
103
|
+
self,
|
|
104
|
+
chops: Sequence[Mapping[int, Strip | None]],
|
|
105
|
+
spans: list[tuple[int, int, int]],
|
|
106
|
+
chop_ends: list[list[int]],
|
|
107
|
+
) -> None:
|
|
108
|
+
\"\"\"A renderable which updates chops (fragments of lines).
|
|
109
|
+
|
|
110
|
+
Args:
|
|
111
|
+
chops: A mapping of offsets to list of segments, per line.
|
|
112
|
+
crop: Region to restrict update to.
|
|
113
|
+
chop_ends: A list of the end offsets for each line
|
|
114
|
+
\"\"\"
|
|
115
|
+
self.chops = chops
|
|
116
|
+
self.spans = spans
|
|
117
|
+
self.chop_ends = chop_ends"""
|
|
118
|
+
|
|
119
|
+
_NEW_CHOPS_INIT = """\
|
|
120
|
+
def __init__(
|
|
121
|
+
self,
|
|
122
|
+
chops: Sequence[Mapping[int, Strip | None]],
|
|
123
|
+
spans: list[tuple[int, int, int]],
|
|
124
|
+
) -> None:
|
|
125
|
+
\"\"\"A renderable which updates chops (fragments of lines).
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
chops: A mapping of offsets to list of segments, per line.
|
|
129
|
+
spans: List of (y, x1, x2) spans to update.
|
|
130
|
+
\"\"\"
|
|
131
|
+
self.chops = chops
|
|
132
|
+
self.spans = spans"""
|
|
133
|
+
|
|
134
|
+
# ---------------------------------------------------------------------------
|
|
135
|
+
# Patch 4: update ChopsUpdate.__rich_console__ loop
|
|
136
|
+
# ---------------------------------------------------------------------------
|
|
137
|
+
_OLD_RICH_CONSOLE = """\
|
|
138
|
+
chop_ends = self.chop_ends
|
|
139
|
+
last_y = self.spans[-1][0]
|
|
140
|
+
|
|
141
|
+
_cell_len = cell_len
|
|
142
|
+
for y, x1, x2 in self.spans:
|
|
143
|
+
line = chops[y]
|
|
144
|
+
ends = chop_ends[y]
|
|
145
|
+
for end, (x, strip) in zip(ends, line.items()):
|
|
146
|
+
# TODO: crop to x extents
|
|
147
|
+
if strip is None:
|
|
148
|
+
continue
|
|
149
|
+
|
|
150
|
+
if x > x2 or end <= x1:"""
|
|
151
|
+
|
|
152
|
+
_NEW_RICH_CONSOLE = """\
|
|
153
|
+
last_y = self.spans[-1][0]
|
|
154
|
+
|
|
155
|
+
_cell_len = cell_len
|
|
156
|
+
for y, x1, x2 in self.spans:
|
|
157
|
+
line = chops[y]
|
|
158
|
+
for x, strip in line.items():
|
|
159
|
+
# TODO: crop to x extents
|
|
160
|
+
if strip is None or strip is _MERGED_STRIP:
|
|
161
|
+
# Skip unfilled chops (None) and _MERGED_STRIP sentinels.
|
|
162
|
+
continue
|
|
163
|
+
|
|
164
|
+
# Use actual strip width rather than the nominal cut-based end so
|
|
165
|
+
# that merged leader strips (wider than their nominal chop bucket)
|
|
166
|
+
# are rendered correctly for double-width character preservation.
|
|
167
|
+
end = x + strip.cell_length
|
|
168
|
+
|
|
169
|
+
if x > x2 or end <= x1:"""
|
|
170
|
+
|
|
171
|
+
# ---------------------------------------------------------------------------
|
|
172
|
+
# Patch 5: update ChopsUpdate.render_segments loop
|
|
173
|
+
# ---------------------------------------------------------------------------
|
|
174
|
+
_OLD_RENDER_SEGMENTS = """\
|
|
175
|
+
chop_ends = self.chop_ends
|
|
176
|
+
last_y = self.spans[-1][0]
|
|
177
|
+
|
|
178
|
+
for y, x1, x2 in self.spans:
|
|
179
|
+
line = chops[y]
|
|
180
|
+
ends = chop_ends[y]
|
|
181
|
+
for end, (x, strip) in zip(ends, line.items()):
|
|
182
|
+
if strip is None:
|
|
183
|
+
continue
|
|
184
|
+
|
|
185
|
+
if x > x2 or end <= x1:"""
|
|
186
|
+
|
|
187
|
+
_NEW_RENDER_SEGMENTS = """\
|
|
188
|
+
last_y = self.spans[-1][0]
|
|
189
|
+
|
|
190
|
+
for y, x1, x2 in self.spans:
|
|
191
|
+
line = chops[y]
|
|
192
|
+
for x, strip in line.items():
|
|
193
|
+
if strip is None or strip is _MERGED_STRIP:
|
|
194
|
+
# Skip unfilled chops (None) and _MERGED_STRIP sentinels.
|
|
195
|
+
continue
|
|
196
|
+
|
|
197
|
+
# Use actual strip width rather than the nominal cut-based end so
|
|
198
|
+
# that merged leader strips (wider than their nominal chop bucket)
|
|
199
|
+
# are rendered correctly for double-width character preservation.
|
|
200
|
+
end = x + strip.cell_length
|
|
201
|
+
|
|
202
|
+
if x > x2 or end <= x1:"""
|
|
203
|
+
|
|
204
|
+
# ---------------------------------------------------------------------------
|
|
205
|
+
# Patch 6: keep dirty-span crops on complete character boundaries
|
|
206
|
+
# ---------------------------------------------------------------------------
|
|
207
|
+
_OLD_RENDER_SEGMENTS_CROP = """\
|
|
208
|
+
strip = strip.crop(0, min(end, x2) - x)
|
|
209
|
+
append(move_to(x, y).segment.text)
|
|
210
|
+
append(strip.render(console))"""
|
|
211
|
+
|
|
212
|
+
_NEW_RENDER_SEGMENTS_CROP = """\
|
|
213
|
+
crop_end = min(end, x2) - x
|
|
214
|
+
if 0 < crop_end < strip.cell_length:
|
|
215
|
+
position = 0
|
|
216
|
+
for segment in strip:
|
|
217
|
+
segment_end = position + cell_len(segment.text)
|
|
218
|
+
if segment_end < crop_end:
|
|
219
|
+
position = segment_end
|
|
220
|
+
continue
|
|
221
|
+
if segment_end == crop_end:
|
|
222
|
+
break
|
|
223
|
+
for character in segment.text:
|
|
224
|
+
position += cell_len(character)
|
|
225
|
+
if position >= crop_end:
|
|
226
|
+
crop_end = position
|
|
227
|
+
break
|
|
228
|
+
break
|
|
229
|
+
strip = strip.crop(0, crop_end)
|
|
230
|
+
append(move_to(x, y).segment.text)
|
|
231
|
+
append(strip.render(console))"""
|
|
232
|
+
|
|
233
|
+
_DIRTY_SPAN_CROP_PATCH = FilePatch(
|
|
234
|
+
package="textual",
|
|
235
|
+
module_file="_compositor.py",
|
|
236
|
+
old_fragment=_OLD_RENDER_SEGMENTS_CROP,
|
|
237
|
+
new_fragment=_NEW_RENDER_SEGMENTS_CROP,
|
|
238
|
+
description="Keep dirty-span crops on complete character boundaries",
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def apply_runtime_patch() -> None:
|
|
243
|
+
"""Install the complete CJK fix on classes already imported by the TUI."""
|
|
244
|
+
try:
|
|
245
|
+
import textual
|
|
246
|
+
import textual._compositor as compositor_mod
|
|
247
|
+
except ImportError:
|
|
248
|
+
return
|
|
249
|
+
|
|
250
|
+
if getattr(textual, "__version__", None) != _RUNTIME_PATCH_TEXTUAL_VERSION:
|
|
251
|
+
logger.warning(
|
|
252
|
+
"Skipping Textual compositor CJK runtime patch: loaded Textual is not the pinned %s that the patch targets.",
|
|
253
|
+
_RUNTIME_PATCH_TEXTUAL_VERSION,
|
|
254
|
+
)
|
|
255
|
+
return
|
|
256
|
+
|
|
257
|
+
targets = [
|
|
258
|
+
(getattr(compositor_mod, class_name), name) for class_name, names in _RUNTIME_TARGETS.items() for name in names
|
|
259
|
+
]
|
|
260
|
+
if all(getattr(getattr(cls, name), _RUNTIME_PATCH_MARKER, False) for cls, name in targets):
|
|
261
|
+
return
|
|
262
|
+
|
|
263
|
+
# Read the module source directly: file patching shifts line numbers after
|
|
264
|
+
# import, so inspect.getsource(live_method) can return an unrelated body.
|
|
265
|
+
# Stage the same fragments for both pristine and already-patched installs.
|
|
266
|
+
source = Path(compositor_mod.__file__).read_text(encoding="utf-8")
|
|
267
|
+
for patch in _PATCHES:
|
|
268
|
+
if patch.new_fragment in source:
|
|
269
|
+
continue
|
|
270
|
+
if patch.old_fragment not in source:
|
|
271
|
+
logger.warning("Skipping Textual compositor CJK runtime patch: fragment drifted: %s", patch.description)
|
|
272
|
+
return
|
|
273
|
+
source = source.replace(patch.old_fragment, patch.new_fragment, 1)
|
|
274
|
+
|
|
275
|
+
tree = ast.parse(source)
|
|
276
|
+
classes = {node.name: node for node in tree.body if isinstance(node, ast.ClassDef)}
|
|
277
|
+
methods: list[ast.stmt] = []
|
|
278
|
+
for class_name, names in _RUNTIME_TARGETS.items():
|
|
279
|
+
definitions = {node.name: node for node in classes[class_name].body if isinstance(node, ast.FunctionDef)}
|
|
280
|
+
for name in names:
|
|
281
|
+
method = definitions[name]
|
|
282
|
+
if method.decorator_list:
|
|
283
|
+
raise ValueError(f"Unexpected decorator on Textual {class_name}.{name}")
|
|
284
|
+
methods.append(method)
|
|
285
|
+
code = compile(
|
|
286
|
+
ast.Module(body=methods, type_ignores=[]),
|
|
287
|
+
"<Chrys CJK patch: textual._compositor>",
|
|
288
|
+
"exec",
|
|
289
|
+
flags=__future__.annotations.compiler_flag,
|
|
290
|
+
dont_inherit=True,
|
|
291
|
+
)
|
|
292
|
+
namespace: dict[str, Any] = {}
|
|
293
|
+
# Compile only the selected methods from the pinned, fragment-validated
|
|
294
|
+
# dependency. Their globals stay bound to the live module. Do not reload
|
|
295
|
+
# its classes: textual.screen and existing instances retain those identities.
|
|
296
|
+
exec(code, vars(compositor_mod), namespace) # noqa: S102
|
|
297
|
+
replacements = [(cls, name, namespace[name]) for cls, name in targets]
|
|
298
|
+
for cls, name, implementation in replacements:
|
|
299
|
+
implementation.__qualname__ = f"{cls.__name__}.{name}"
|
|
300
|
+
setattr(implementation, _RUNTIME_PATCH_MARKER, True)
|
|
301
|
+
|
|
302
|
+
# Publish only after every method has been staged and compiled successfully.
|
|
303
|
+
# Keep an existing sentinel so already-produced chops still recognize it.
|
|
304
|
+
merged_strip = getattr(compositor_mod, "_MERGED_STRIP", None)
|
|
305
|
+
if merged_strip is None:
|
|
306
|
+
merged_strip = compositor_mod.Strip([], 0)
|
|
307
|
+
compositor_mod.bisect_left = bisect_left
|
|
308
|
+
compositor_mod.bisect_right = bisect_right
|
|
309
|
+
compositor_mod._MERGED_STRIP = merged_strip
|
|
310
|
+
compositor_mod._ALWAYS_TRUE = getattr(compositor_mod, "_ALWAYS_TRUE", lambda _: True)
|
|
311
|
+
for cls, name, implementation in replacements:
|
|
312
|
+
setattr(cls, name, implementation)
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
# ---------------------------------------------------------------------------
|
|
316
|
+
# Patch 7: _get_renders -- lists to generators
|
|
317
|
+
# ---------------------------------------------------------------------------
|
|
318
|
+
_OLD_GET_RENDERS = """\
|
|
319
|
+
widget_regions = [
|
|
320
|
+
(widget, region, clip)
|
|
321
|
+
for widget, (region, clip) in visible_widgets.items()
|
|
322
|
+
if crop_overlaps(clip)
|
|
323
|
+
]
|
|
324
|
+
else:
|
|
325
|
+
widget_regions = [
|
|
326
|
+
(widget, region, clip)
|
|
327
|
+
for widget, (region, clip) in visible_widgets.items()
|
|
328
|
+
]
|
|
329
|
+
|
|
330
|
+
intersection = _Region.intersection
|
|
331
|
+
contains_region = _Region.contains_region
|
|
332
|
+
|
|
333
|
+
for widget, region, clip in widget_regions:"""
|
|
334
|
+
|
|
335
|
+
_NEW_GET_RENDERS = """\
|
|
336
|
+
widgets_iter = (
|
|
337
|
+
(widget, region, clip)
|
|
338
|
+
for widget, (region, clip) in visible_widgets.items()
|
|
339
|
+
if crop_overlaps(clip)
|
|
340
|
+
)
|
|
341
|
+
else:
|
|
342
|
+
widgets_iter = (
|
|
343
|
+
(widget, region, clip)
|
|
344
|
+
for widget, (region, clip) in visible_widgets.items()
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
intersection = _Region.intersection
|
|
348
|
+
contains_region = _Region.contains_region
|
|
349
|
+
|
|
350
|
+
for widget, region, clip in widgets_iter:"""
|
|
351
|
+
|
|
352
|
+
# ---------------------------------------------------------------------------
|
|
353
|
+
# Patch 8: render_full_update -- lambda to _ALWAYS_TRUE
|
|
354
|
+
# ---------------------------------------------------------------------------
|
|
355
|
+
_OLD_FULL_UPDATE = """\
|
|
356
|
+
chops = self._render_chops(crop, lambda y: True)
|
|
357
|
+
render_strips: list[Iterable[Strip]]"""
|
|
358
|
+
|
|
359
|
+
_NEW_FULL_UPDATE = """\
|
|
360
|
+
chops = self._render_chops(crop, _ALWAYS_TRUE)
|
|
361
|
+
render_strips: list[Iterable[Strip]]"""
|
|
362
|
+
|
|
363
|
+
# ---------------------------------------------------------------------------
|
|
364
|
+
# Patch 9: render_partial_update -- remove chop_ends
|
|
365
|
+
# ---------------------------------------------------------------------------
|
|
366
|
+
_OLD_PARTIAL_UPDATE = """\
|
|
367
|
+
chops = self._render_chops(crop, is_rendered_line)
|
|
368
|
+
chop_ends = [cut_set[1:] for cut_set in self.cuts]
|
|
369
|
+
return ChopsUpdate(chops, spans, chop_ends)"""
|
|
370
|
+
|
|
371
|
+
_NEW_PARTIAL_UPDATE = """\
|
|
372
|
+
chops = self._render_chops(crop, is_rendered_line)
|
|
373
|
+
return ChopsUpdate(chops, spans)"""
|
|
374
|
+
|
|
375
|
+
# ---------------------------------------------------------------------------
|
|
376
|
+
# Patch 10: render_strips -- lambda to _ALWAYS_TRUE
|
|
377
|
+
# ---------------------------------------------------------------------------
|
|
378
|
+
_OLD_RENDER_STRIPS = """\
|
|
379
|
+
chops = self._render_chops(size.region, lambda y: True)
|
|
380
|
+
render_strips = [Strip.join(chop.values())"""
|
|
381
|
+
|
|
382
|
+
_NEW_RENDER_STRIPS = """\
|
|
383
|
+
chops = self._render_chops(size.region, _ALWAYS_TRUE)
|
|
384
|
+
render_strips = [Strip.join(chop.values())"""
|
|
385
|
+
|
|
386
|
+
# ---------------------------------------------------------------------------
|
|
387
|
+
# Patch 11: _render_chops -- CJK-safe effective cuts + bisect optimization
|
|
388
|
+
# ---------------------------------------------------------------------------
|
|
389
|
+
_OLD_RENDER_CHOPS = """\
|
|
390
|
+
renders = self._get_renders(crop)
|
|
391
|
+
intersection = Region.intersection
|
|
392
|
+
|
|
393
|
+
for region, clip, strips in renders:
|
|
394
|
+
render_region = intersection(region, clip)
|
|
395
|
+
render_x = render_region.x
|
|
396
|
+
first_cut, last_cut = render_region.column_span
|
|
397
|
+
|
|
398
|
+
for y, strip in zip(render_region.line_range, strips):
|
|
399
|
+
if not is_rendered_line(y):
|
|
400
|
+
continue
|
|
401
|
+
|
|
402
|
+
chops_line = chops[y]
|
|
403
|
+
final_cuts = [cut for cut in cuts[y] if (last_cut >= cut >= first_cut)]
|
|
404
|
+
cut_strips = strip.divide([cut - render_x for cut in final_cuts[1:]])
|
|
405
|
+
|
|
406
|
+
# Since we are painting front to back, the first segments for a cut "wins"
|
|
407
|
+
get_chops_line = chops_line.get
|
|
408
|
+
for cut, strip in zip(final_cuts, cut_strips):
|
|
409
|
+
if get_chops_line(cut) is None:
|
|
410
|
+
chops_line[cut] = strip
|
|
411
|
+
return cast("Sequence[Mapping[int, Strip]]", chops)"""
|
|
412
|
+
|
|
413
|
+
_NEW_RENDER_CHOPS = """\
|
|
414
|
+
renders = self._get_renders(crop)
|
|
415
|
+
intersection = Region.intersection
|
|
416
|
+
|
|
417
|
+
_bisect_left = bisect_left
|
|
418
|
+
_bisect_right = bisect_right
|
|
419
|
+
|
|
420
|
+
for region, clip, strips in renders:
|
|
421
|
+
render_region = intersection(region, clip)
|
|
422
|
+
render_x = render_region.x
|
|
423
|
+
first_cut, last_cut = render_region.column_span
|
|
424
|
+
|
|
425
|
+
for y, strip in zip(render_region.line_range, strips):
|
|
426
|
+
if not is_rendered_line(y):
|
|
427
|
+
continue
|
|
428
|
+
|
|
429
|
+
chops_line = chops[y]
|
|
430
|
+
# cuts[y] is sorted; use bisect to extract the relevant range.
|
|
431
|
+
line_cuts = cuts[y]
|
|
432
|
+
lo = _bisect_left(line_cuts, first_cut)
|
|
433
|
+
hi = _bisect_right(line_cuts, last_cut)
|
|
434
|
+
final_cuts = line_cuts[lo:hi]
|
|
435
|
+
|
|
436
|
+
if len(final_cuts) < 2:
|
|
437
|
+
continue
|
|
438
|
+
|
|
439
|
+
# Compute effective cuts: skip "internal" cuts where both adjacent
|
|
440
|
+
# chops are currently unfilled (None). When the same widget wins
|
|
441
|
+
# both sides of a cut the division is unnecessary, and -- crucially
|
|
442
|
+
# -- it can split a double-width (CJK) character into two spaces.
|
|
443
|
+
# A cut is a *real* boundary only when the chop on at least one side
|
|
444
|
+
# is already claimed by a higher-priority widget (not None).
|
|
445
|
+
effective_cuts = [final_cuts[0]]
|
|
446
|
+
for _i in range(1, len(final_cuts) - 1):
|
|
447
|
+
if (
|
|
448
|
+
chops_line.get(final_cuts[_i - 1]) is not None
|
|
449
|
+
or chops_line.get(final_cuts[_i]) is not None
|
|
450
|
+
):
|
|
451
|
+
effective_cuts.append(final_cuts[_i])
|
|
452
|
+
effective_cuts.append(final_cuts[-1])
|
|
453
|
+
|
|
454
|
+
cut_strips = strip.divide([cut - render_x for cut in effective_cuts[1:]])
|
|
455
|
+
|
|
456
|
+
# Since we are painting front to back, the first segments for a cut "wins".
|
|
457
|
+
# Leader chops (at effective_cuts boundaries) receive the actual strip.
|
|
458
|
+
# Follower chops (internal cuts that were skipped) receive _MERGED_STRIP
|
|
459
|
+
# so that lower-priority widgets cannot claim those positions -- the leader
|
|
460
|
+
# strip is wider than its nominal chop size and covers them visually.
|
|
461
|
+
#
|
|
462
|
+
# Walk effective_cuts by index instead of building a set -- both
|
|
463
|
+
# lists are sorted and effective_cuts is a subsequence of
|
|
464
|
+
# final_cuts, so a simple index comparison suffices.
|
|
465
|
+
get_chops_line = chops_line.get
|
|
466
|
+
num_effective = len(effective_cuts) - 1
|
|
467
|
+
eff_idx = 0
|
|
468
|
+
eff_iter = iter(cut_strips)
|
|
469
|
+
for cut in final_cuts[:-1]:
|
|
470
|
+
if eff_idx < num_effective and cut == effective_cuts[eff_idx]:
|
|
471
|
+
strip_part = next(eff_iter, None)
|
|
472
|
+
if strip_part is None:
|
|
473
|
+
# strip.divide() filters out cuts beyond the
|
|
474
|
+
# strip's cell_length, so fewer strips may be
|
|
475
|
+
# returned than effective cuts. Once exhausted,
|
|
476
|
+
# remaining chops stay None for lower-priority
|
|
477
|
+
# widgets to fill.
|
|
478
|
+
break
|
|
479
|
+
eff_idx += 1
|
|
480
|
+
if get_chops_line(cut) is None:
|
|
481
|
+
chops_line[cut] = strip_part
|
|
482
|
+
else:
|
|
483
|
+
if get_chops_line(cut) is None:
|
|
484
|
+
chops_line[cut] = _MERGED_STRIP
|
|
485
|
+
return cast("Sequence[Mapping[int, Strip]]", chops)"""
|
|
486
|
+
|
|
487
|
+
# ---------------------------------------------------------------------------
|
|
488
|
+
# Register all patches (order: imports first, then code changes)
|
|
489
|
+
# ---------------------------------------------------------------------------
|
|
490
|
+
_TARGET = "_compositor.py"
|
|
491
|
+
|
|
492
|
+
_PATCHES = (
|
|
493
|
+
FilePatch(
|
|
494
|
+
package="textual",
|
|
495
|
+
module_file=_TARGET,
|
|
496
|
+
old_fragment=_OLD_IMPORT,
|
|
497
|
+
new_fragment=_NEW_IMPORT,
|
|
498
|
+
description="Add bisect imports for CJK compositor fix",
|
|
499
|
+
),
|
|
500
|
+
FilePatch(
|
|
501
|
+
package="textual",
|
|
502
|
+
module_file=_TARGET,
|
|
503
|
+
old_fragment=_OLD_SENTINELS,
|
|
504
|
+
new_fragment=_NEW_SENTINELS,
|
|
505
|
+
description="Add _MERGED_STRIP and _ALWAYS_TRUE sentinels",
|
|
506
|
+
),
|
|
507
|
+
FilePatch(
|
|
508
|
+
package="textual",
|
|
509
|
+
module_file=_TARGET,
|
|
510
|
+
old_fragment=_OLD_CHOPS_INIT,
|
|
511
|
+
new_fragment=_NEW_CHOPS_INIT,
|
|
512
|
+
description="Remove chop_ends from ChopsUpdate.__init__",
|
|
513
|
+
),
|
|
514
|
+
FilePatch(
|
|
515
|
+
package="textual",
|
|
516
|
+
module_file=_TARGET,
|
|
517
|
+
old_fragment=_OLD_RICH_CONSOLE,
|
|
518
|
+
new_fragment=_NEW_RICH_CONSOLE,
|
|
519
|
+
description="Update ChopsUpdate.__rich_console__ for merged strips",
|
|
520
|
+
),
|
|
521
|
+
FilePatch(
|
|
522
|
+
package="textual",
|
|
523
|
+
module_file=_TARGET,
|
|
524
|
+
old_fragment=_OLD_RENDER_SEGMENTS,
|
|
525
|
+
new_fragment=_NEW_RENDER_SEGMENTS,
|
|
526
|
+
description="Update ChopsUpdate.render_segments for merged strips",
|
|
527
|
+
),
|
|
528
|
+
_DIRTY_SPAN_CROP_PATCH,
|
|
529
|
+
FilePatch(
|
|
530
|
+
package="textual",
|
|
531
|
+
module_file=_TARGET,
|
|
532
|
+
old_fragment=_OLD_GET_RENDERS,
|
|
533
|
+
new_fragment=_NEW_GET_RENDERS,
|
|
534
|
+
description="Use generators in _get_renders for lazy evaluation",
|
|
535
|
+
),
|
|
536
|
+
FilePatch(
|
|
537
|
+
package="textual",
|
|
538
|
+
module_file=_TARGET,
|
|
539
|
+
old_fragment=_OLD_FULL_UPDATE,
|
|
540
|
+
new_fragment=_NEW_FULL_UPDATE,
|
|
541
|
+
description="Use cached _ALWAYS_TRUE in render_full_update",
|
|
542
|
+
),
|
|
543
|
+
FilePatch(
|
|
544
|
+
package="textual",
|
|
545
|
+
module_file=_TARGET,
|
|
546
|
+
old_fragment=_OLD_PARTIAL_UPDATE,
|
|
547
|
+
new_fragment=_NEW_PARTIAL_UPDATE,
|
|
548
|
+
description="Remove chop_ends from render_partial_update",
|
|
549
|
+
),
|
|
550
|
+
FilePatch(
|
|
551
|
+
package="textual",
|
|
552
|
+
module_file=_TARGET,
|
|
553
|
+
old_fragment=_OLD_RENDER_STRIPS,
|
|
554
|
+
new_fragment=_NEW_RENDER_STRIPS,
|
|
555
|
+
description="Use cached _ALWAYS_TRUE in render_strips",
|
|
556
|
+
),
|
|
557
|
+
FilePatch(
|
|
558
|
+
package="textual",
|
|
559
|
+
module_file=_TARGET,
|
|
560
|
+
old_fragment=_OLD_RENDER_CHOPS,
|
|
561
|
+
new_fragment=_NEW_RENDER_CHOPS,
|
|
562
|
+
description="CJK-safe effective cuts with bisect optimization in _render_chops",
|
|
563
|
+
),
|
|
564
|
+
)
|
|
565
|
+
|
|
566
|
+
register(*_PATCHES)
|