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,342 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""What a terminal sends to the program: keys, pointer reports, pastes and focus changes.
|
|
4
|
+
|
|
5
|
+
Keys follow xterm until the program asks for more. A function key is a fixed sequence with the
|
|
6
|
+
held modifiers in its second parameter, one more than their bits. A text key sends its text, Ctrl
|
|
7
|
+
folds it into a C0 control and Alt prefixes ESC, which is where the classic encoding runs out:
|
|
8
|
+
Shift+Enter is Enter, Ctrl+Shift+A is Ctrl+A. A program that wants those told apart asks for one of
|
|
9
|
+
the extended encodings (`KeyProtocol`), and only then are they sent, because a shell that never
|
|
10
|
+
asked would print the unfamiliar sequence as text.
|
|
11
|
+
|
|
12
|
+
The extended encodings are two families, and each is followed by its own definition. xterm's
|
|
13
|
+
modifyOtherKeys respells text keys only, and how many of them is a matter of the level asked for.
|
|
14
|
+
The kitty keyboard protocol has its own modifier bits, and respells the function keys as well:
|
|
15
|
+
none of them is an SS3 sequence any more, whatever the cursor key mode, and F3 stops looking like
|
|
16
|
+
a cursor position report.
|
|
17
|
+
|
|
18
|
+
Key names are Textual's: modifiers first, ``+`` between (``ctrl+shift+left``).
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
from __future__ import annotations
|
|
22
|
+
|
|
23
|
+
import unicodedata
|
|
24
|
+
from enum import Enum
|
|
25
|
+
from typing import Final
|
|
26
|
+
|
|
27
|
+
from chrys.app.tui.terminal.emulator.core import KeyProtocol, MouseEncoding, MouseTracking
|
|
28
|
+
|
|
29
|
+
FOCUS_IN: Final = "\x1b[I"
|
|
30
|
+
FOCUS_OUT: Final = "\x1b[O"
|
|
31
|
+
|
|
32
|
+
_PASTE_START: Final = "\x1b[200~"
|
|
33
|
+
_PASTE_END: Final = "\x1b[201~"
|
|
34
|
+
|
|
35
|
+
_SHIFT, _ALT, _CTRL = 1, 2, 4
|
|
36
|
+
# xterm has a bit for Meta and none for Super or Hyper, which it cannot say at all. kitty has all
|
|
37
|
+
# three, and its Meta is not where xterm's is.
|
|
38
|
+
_XTERM_MODIFIER_BITS: Final = {"shift": _SHIFT, "alt": _ALT, "ctrl": _CTRL, "meta": 8, "super": 0, "hyper": 0}
|
|
39
|
+
_KITTY_MODIFIER_BITS: Final = {"shift": _SHIFT, "alt": _ALT, "ctrl": _CTRL, "super": 8, "hyper": 16, "meta": 32}
|
|
40
|
+
|
|
41
|
+
# Keys spelled ``CSI 1 ; modifiers <final>``. Bare, xterm has the cursor keys honor application mode
|
|
42
|
+
# (DECCKM) and F1-F4 always SS3; the kitty protocol keeps both where they are.
|
|
43
|
+
_CURSOR_KEYS: Final = {"up": "A", "down": "B", "right": "C", "left": "D", "home": "H", "end": "F"}
|
|
44
|
+
_FUNCTION_KEYS_SS3: Final = {"f1": "P", "f2": "Q", "f3": "R", "f4": "S"}
|
|
45
|
+
# Keys spelled ``CSI <number> ; modifiers ~``. The gaps in the numbering are DEC's.
|
|
46
|
+
_TILDE_KEYS: Final = {
|
|
47
|
+
"insert": 2,
|
|
48
|
+
"delete": 3,
|
|
49
|
+
"pageup": 5,
|
|
50
|
+
"pagedown": 6,
|
|
51
|
+
"f5": 15,
|
|
52
|
+
"f6": 17,
|
|
53
|
+
"f7": 18,
|
|
54
|
+
"f8": 19,
|
|
55
|
+
"f9": 20,
|
|
56
|
+
"f10": 21,
|
|
57
|
+
"f11": 23,
|
|
58
|
+
"f12": 24,
|
|
59
|
+
"f13": 25,
|
|
60
|
+
"f14": 26,
|
|
61
|
+
"f15": 28,
|
|
62
|
+
"f16": 29,
|
|
63
|
+
"f17": 31,
|
|
64
|
+
"f18": 32,
|
|
65
|
+
"f19": 33,
|
|
66
|
+
"f20": 34,
|
|
67
|
+
}
|
|
68
|
+
# Where kitty parts with xterm: F3 by number, since ``CSI 1 ; modifiers R`` is also how a terminal
|
|
69
|
+
# reports the cursor position, and the keys past F12 by numbers of kitty's own, up to F35.
|
|
70
|
+
_FIRST_KITTY_NUMBERED_FUNCTION_KEY: Final = 13
|
|
71
|
+
_KITTY_FUNCTION_KEYS: Final = {
|
|
72
|
+
"f3": (13, "~"),
|
|
73
|
+
**{f"f{number}": (57376 + number - _FIRST_KITTY_NUMBERED_FUNCTION_KEY, "u") for number in range(13, 36)},
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
# Keys that are a character but not a printable one, and the names Textual gives punctuation where
|
|
77
|
+
# the Unicode name would not lead back to the character.
|
|
78
|
+
_EDITING_KEYS: Final = {"enter": "\r", "tab": "\t", "escape": "\x1b", "backspace": "\x7f", "space": " "}
|
|
79
|
+
_PUNCTUATION_NAMES: Final = {
|
|
80
|
+
"slash": "/",
|
|
81
|
+
"backslash": "\\",
|
|
82
|
+
"at": "@",
|
|
83
|
+
"minus": "-",
|
|
84
|
+
"plus": "+",
|
|
85
|
+
"underscore": "_",
|
|
86
|
+
"less_than_sign": "<",
|
|
87
|
+
"greater_than_sign": ">",
|
|
88
|
+
}
|
|
89
|
+
# What a key types with Shift held, where that is not the capital of what it types without. Textual
|
|
90
|
+
# names such a key by the latter and nothing records the layout that turns one into the other, so
|
|
91
|
+
# it is the US one: what xterm's own table of these encodings is written for.
|
|
92
|
+
_US_SHIFTED: Final = dict(zip("`1234567890-=[]\\;',./", '~!@#$%^&*()_+{}|:"<>?', strict=True))
|
|
93
|
+
# What Ctrl makes of a character besides the letters: the C0 control sharing its low five bits,
|
|
94
|
+
# plus the digit row and the few aliases every terminal has inherited from the VT100 keyboard.
|
|
95
|
+
_CONTROL_CHARACTERS: Final = {
|
|
96
|
+
"@": "\x00",
|
|
97
|
+
" ": "\x00",
|
|
98
|
+
"`": "\x00",
|
|
99
|
+
"2": "\x00",
|
|
100
|
+
"[": "\x1b",
|
|
101
|
+
"{": "\x1b",
|
|
102
|
+
"3": "\x1b",
|
|
103
|
+
"\\": "\x1c",
|
|
104
|
+
"|": "\x1c",
|
|
105
|
+
"4": "\x1c",
|
|
106
|
+
"]": "\x1d",
|
|
107
|
+
"}": "\x1d",
|
|
108
|
+
"5": "\x1d",
|
|
109
|
+
"^": "\x1e",
|
|
110
|
+
"~": "\x1e",
|
|
111
|
+
"6": "\x1e",
|
|
112
|
+
"_": "\x1f",
|
|
113
|
+
"-": "\x1f",
|
|
114
|
+
"/": "\x1f",
|
|
115
|
+
"7": "\x1f",
|
|
116
|
+
"8": "\x7f",
|
|
117
|
+
"?": "\x7f",
|
|
118
|
+
"\x7f": "\x08",
|
|
119
|
+
}
|
|
120
|
+
# The two of those xterm does not count as well known: it sends "-" as itself, and makes DEL of "?"
|
|
121
|
+
# only once it has decided how the key is spelled.
|
|
122
|
+
_LESSER_CONTROL_ALIASES: Final = frozenset("-?")
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def encode_key(
|
|
126
|
+
key: str,
|
|
127
|
+
character: str | None,
|
|
128
|
+
*,
|
|
129
|
+
application_cursor_keys: bool = False,
|
|
130
|
+
protocol: KeyProtocol = KeyProtocol.LEGACY,
|
|
131
|
+
) -> str | None:
|
|
132
|
+
"""The bytes for a key press, or ``None`` if the key sends nothing.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
key: Textual's key name.
|
|
136
|
+
character: The text the key produced, if any. It may be several code points: an input
|
|
137
|
+
method commits a whole word as one key.
|
|
138
|
+
application_cursor_keys: Whether the program switched the cursor keys to application mode.
|
|
139
|
+
protocol: The encoding the program asked for.
|
|
140
|
+
"""
|
|
141
|
+
kitty = protocol is KeyProtocol.KITTY
|
|
142
|
+
bits = _KITTY_MODIFIER_BITS if kitty else _XTERM_MODIFIER_BITS
|
|
143
|
+
*modifiers, base = key.split("+")
|
|
144
|
+
if any(modifier not in bits for modifier in modifiers):
|
|
145
|
+
# Not a modified key after all, just text that happens to contain a plus sign.
|
|
146
|
+
return character
|
|
147
|
+
held = sum(bits[modifier] for modifier in modifiers)
|
|
148
|
+
|
|
149
|
+
if (final := _CURSOR_KEYS.get(base)) is not None:
|
|
150
|
+
application = application_cursor_keys and not held and not kitty
|
|
151
|
+
return f"\x1bO{final}" if application else _control_sequence(1, held, final)
|
|
152
|
+
if kitty and (spelling := _KITTY_FUNCTION_KEYS.get(base)) is not None:
|
|
153
|
+
return _control_sequence(spelling[0], held, spelling[1])
|
|
154
|
+
if (final := _FUNCTION_KEYS_SS3.get(base)) is not None:
|
|
155
|
+
return _control_sequence(1, held, final) if held or kitty else f"\x1bO{final}"
|
|
156
|
+
if (number := _TILDE_KEYS.get(base)) is not None:
|
|
157
|
+
return _control_sequence(number, held, "~")
|
|
158
|
+
|
|
159
|
+
typed = _key_character(base)
|
|
160
|
+
if typed is None:
|
|
161
|
+
return character
|
|
162
|
+
if kitty:
|
|
163
|
+
if typed != typed.lower() and len(typed.lower()) == 1:
|
|
164
|
+
# The key is named by what it types unshifted, and Shift is a modifier like any other.
|
|
165
|
+
typed, held = typed.lower(), held | _SHIFT
|
|
166
|
+
if typed == "\x1b" or held & ~_SHIFT or (held and base in _EDITING_KEYS):
|
|
167
|
+
return _control_sequence(ord(typed), held, "u")
|
|
168
|
+
if held & _SHIFT:
|
|
169
|
+
# xterm goes the other way: by what was typed, Shift's part in it included. That is what Ctrl
|
|
170
|
+
# folds, what is asked whether it has a classic spelling, and the code that is reported.
|
|
171
|
+
typed = _shifted(typed)
|
|
172
|
+
if _modify_other_keys_applies(protocol, base, typed, held):
|
|
173
|
+
return f"\x1b[27;{held + 1};{ord(typed)}~"
|
|
174
|
+
return _classic_encoding(base, typed, held, character)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
def _control_sequence(number: int, held: int, final: str) -> str:
|
|
178
|
+
"""``CSI number ; modifiers final``, less the parameters that would only state a default."""
|
|
179
|
+
if held:
|
|
180
|
+
return f"\x1b[{number};{held + 1}{final}"
|
|
181
|
+
return f"\x1b[{final}" if number == 1 else f"\x1b[{number}{final}"
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def _key_character(base: str) -> str | None:
|
|
185
|
+
"""The character a key name stands for, or ``None`` for a key that is not a character."""
|
|
186
|
+
if len(base) == 1:
|
|
187
|
+
return base
|
|
188
|
+
if (known := _EDITING_KEYS.get(base) or _PUNCTUATION_NAMES.get(base)) is not None:
|
|
189
|
+
return known
|
|
190
|
+
try:
|
|
191
|
+
return unicodedata.lookup(base.replace("_", " "))
|
|
192
|
+
except KeyError:
|
|
193
|
+
return None
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def _shifted(typed: str) -> str:
|
|
197
|
+
"""What the key that types this types with Shift held, as far as that can be told."""
|
|
198
|
+
capital = typed.upper()
|
|
199
|
+
if capital != typed:
|
|
200
|
+
return capital if len(capital) == 1 else typed
|
|
201
|
+
return _US_SHIFTED.get(typed, typed)
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def _classic_encoding(base: str, typed: str, held: int, character: str | None) -> str | None:
|
|
205
|
+
if base == "tab" and held & _SHIFT:
|
|
206
|
+
typed = "\x1b[Z"
|
|
207
|
+
elif held & _CTRL:
|
|
208
|
+
is_letter = typed.isascii() and typed.isalpha()
|
|
209
|
+
typed = chr(ord(typed) & 0x1F) if is_letter else _CONTROL_CHARACTERS.get(typed, typed)
|
|
210
|
+
elif base not in _EDITING_KEYS:
|
|
211
|
+
# Whatever the key name says, the text the key produced is what was typed.
|
|
212
|
+
typed = character if character is not None else typed
|
|
213
|
+
return f"\x1b{typed}" if held & _ALT else typed
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
def _modify_other_keys_applies(protocol: KeyProtocol, base: str, typed: str, held: int) -> bool:
|
|
217
|
+
"""Whether xterm spells a text key ``CSI 27 ; modifiers ; code ~`` at the level the program asked for.
|
|
218
|
+
|
|
219
|
+
xterm as it is when Alt sends ESC, the only Alt the classic encoding here knows, going as it
|
|
220
|
+
does by ``typed`` with Shift's part already in it. One departure: at level 2 xterm also
|
|
221
|
+
respells Shift with a letter, and not Shift with a digit. Shift with something printable is
|
|
222
|
+
sent as what it types, everywhere.
|
|
223
|
+
"""
|
|
224
|
+
if not held or protocol not in (KeyProtocol.MODIFY_OTHER_KEYS_1, KeyProtocol.MODIFY_OTHER_KEYS_2):
|
|
225
|
+
return False
|
|
226
|
+
if base == "backspace" and held == _CTRL:
|
|
227
|
+
# Not a chord to xterm but the other backspace: Ctrl swaps which of BS and DEL the key sends.
|
|
228
|
+
return False
|
|
229
|
+
if held & ~(_SHIFT | _ALT | _CTRL):
|
|
230
|
+
# Meta. There is no classic spelling to keep.
|
|
231
|
+
return True
|
|
232
|
+
if protocol is KeyProtocol.MODIFY_OTHER_KEYS_2:
|
|
233
|
+
return held != _SHIFT or base in _EDITING_KEYS
|
|
234
|
+
# Level 1 leaves alone whatever has a well-known spelling, even one that drops a modifier.
|
|
235
|
+
if base in ("tab", "enter"):
|
|
236
|
+
# Back-tab is the one such spelling these two have; Alt has none, as ESC is not put before them.
|
|
237
|
+
return (base, held) != ("tab", _SHIFT)
|
|
238
|
+
if base == "escape":
|
|
239
|
+
return bool(held & _ALT)
|
|
240
|
+
if base in _EDITING_KEYS:
|
|
241
|
+
return False
|
|
242
|
+
is_letter = typed.isascii() and typed.isalpha()
|
|
243
|
+
has_control = is_letter or (typed in _CONTROL_CHARACTERS and typed not in _LESSER_CONTROL_ALIASES)
|
|
244
|
+
return bool(held & _CTRL) and not has_control
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def encode_paste(text: str, *, bracketed: bool) -> str:
|
|
248
|
+
"""The bytes for pasted text.
|
|
249
|
+
|
|
250
|
+
Bracketed, the program is told where the paste starts and ends, so the paste itself must not be
|
|
251
|
+
able to say so first. Unbracketed, the text arrives as if typed, where Return ends a line.
|
|
252
|
+
"""
|
|
253
|
+
if bracketed:
|
|
254
|
+
return f"{_PASTE_START}{text.replace(_PASTE_END, '')}{_PASTE_END}"
|
|
255
|
+
return text.replace("\r\n", "\r").replace("\n", "\r")
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class PointerAction(Enum):
|
|
259
|
+
PRESS = "press"
|
|
260
|
+
RELEASE = "release"
|
|
261
|
+
MOVE = "move"
|
|
262
|
+
WHEEL_UP = "wheel_up"
|
|
263
|
+
WHEEL_DOWN = "wheel_down"
|
|
264
|
+
WHEEL_LEFT = "wheel_left"
|
|
265
|
+
WHEEL_RIGHT = "wheel_right"
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
_NO_BUTTON: Final = 3
|
|
269
|
+
_MOTION: Final = 32
|
|
270
|
+
_WHEEL: Final = {
|
|
271
|
+
PointerAction.WHEEL_UP: 64,
|
|
272
|
+
PointerAction.WHEEL_DOWN: 65,
|
|
273
|
+
PointerAction.WHEEL_LEFT: 66,
|
|
274
|
+
PointerAction.WHEEL_RIGHT: 67,
|
|
275
|
+
}
|
|
276
|
+
_MAX_DEFAULT_COORDINATE: Final = 223
|
|
277
|
+
_MAX_UTF8_COORDINATE: Final = 2015
|
|
278
|
+
_FIRST_BYTE_THAT_IS_NOT_TEXT: Final = 0x80
|
|
279
|
+
_SURROGATE_ESCAPE: Final = 0xDC00
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def encode_pointer(
|
|
283
|
+
tracking: MouseTracking,
|
|
284
|
+
encoding: MouseEncoding,
|
|
285
|
+
action: PointerAction,
|
|
286
|
+
*,
|
|
287
|
+
x: int,
|
|
288
|
+
y: int,
|
|
289
|
+
button: int | None = None,
|
|
290
|
+
shift: bool = False,
|
|
291
|
+
alt: bool = False,
|
|
292
|
+
ctrl: bool = False,
|
|
293
|
+
) -> str | None:
|
|
294
|
+
"""The report for a pointer event, or ``None`` when the program did not ask to hear of it.
|
|
295
|
+
|
|
296
|
+
xterm's original format spends one byte on each coordinate, and from column 96 on that byte is
|
|
297
|
+
not text. It is returned as the lone surrogate the ``surrogateescape`` error handler turns back
|
|
298
|
+
into the byte, which is how whoever encodes the report for the program has to encode it. Only
|
|
299
|
+
the UTF-8 format (mode 1005) sends such a value as a character.
|
|
300
|
+
|
|
301
|
+
Args:
|
|
302
|
+
tracking: The tracking mode the program selected.
|
|
303
|
+
encoding: The report format the program selected.
|
|
304
|
+
action: What the pointer did.
|
|
305
|
+
x: Zero-based column.
|
|
306
|
+
y: Zero-based row.
|
|
307
|
+
button: 0 left, 1 middle, 2 right; ``None`` when no button is involved or held.
|
|
308
|
+
shift: Shift is held.
|
|
309
|
+
alt: Alt (Meta) is held.
|
|
310
|
+
ctrl: Control is held.
|
|
311
|
+
"""
|
|
312
|
+
if tracking is MouseTracking.OFF:
|
|
313
|
+
return None
|
|
314
|
+
if tracking is MouseTracking.PRESS and action is not PointerAction.PRESS:
|
|
315
|
+
return None
|
|
316
|
+
if action is PointerAction.MOVE and (
|
|
317
|
+
tracking is MouseTracking.PRESS_RELEASE or (tracking is MouseTracking.DRAG and button is None)
|
|
318
|
+
):
|
|
319
|
+
return None
|
|
320
|
+
|
|
321
|
+
released = action is PointerAction.RELEASE
|
|
322
|
+
if (code := _WHEEL.get(action)) is None:
|
|
323
|
+
# Only the SGR format can say which button was released; the others report "no button".
|
|
324
|
+
code = _NO_BUTTON if button is None or (released and encoding is not MouseEncoding.SGR) else button
|
|
325
|
+
if action is PointerAction.MOVE:
|
|
326
|
+
code += _MOTION
|
|
327
|
+
if tracking is not MouseTracking.PRESS:
|
|
328
|
+
code += 4 * shift + 8 * alt + 16 * ctrl
|
|
329
|
+
|
|
330
|
+
column, row = x + 1, y + 1
|
|
331
|
+
if encoding is MouseEncoding.SGR:
|
|
332
|
+
return f"\x1b[<{code};{column};{row}{'m' if released else 'M'}"
|
|
333
|
+
if encoding is MouseEncoding.URXVT:
|
|
334
|
+
return f"\x1b[{code + 32};{column};{row}M"
|
|
335
|
+
limit = _MAX_UTF8_COORDINATE if encoding is MouseEncoding.UTF8 else _MAX_DEFAULT_COORDINATE
|
|
336
|
+
if column > limit or row > limit:
|
|
337
|
+
# These formats spend one character, or one byte, per coordinate and cannot count any higher.
|
|
338
|
+
return None
|
|
339
|
+
values = (code + 32, column + 32, row + 32)
|
|
340
|
+
if encoding is not MouseEncoding.UTF8:
|
|
341
|
+
values = (value + _SURROGATE_ESCAPE * (value >= _FIRST_BYTE_THAT_IS_NOT_TEXT) for value in values)
|
|
342
|
+
return "\x1b[M" + "".join(map(chr, values))
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Control-sequence parser: splits a terminal's output stream into printable runs and controls.
|
|
4
|
+
|
|
5
|
+
The grammar is ECMA-48's, driven as a resumable state machine so a sequence may be cut anywhere by
|
|
6
|
+
a read boundary, and the recovery rules are the ones DEC terminals established: a control
|
|
7
|
+
character inside a sequence acts immediately without ending it, ESC abandons the sequence in
|
|
8
|
+
progress and starts another, CAN and SUB cancel it. Whole runs of text and whole control sequences
|
|
9
|
+
are matched in one step when they arrive intact, which is nearly always; the character-at-a-time
|
|
10
|
+
states only finish what a boundary or an embedded control interrupted.
|
|
11
|
+
|
|
12
|
+
The parser holds no terminal state. It reports what it recognized to a `SequenceHandler`. A handler
|
|
13
|
+
that fails costs the rest of that `feed` and the sequence in progress, never the parse of what is
|
|
14
|
+
fed next.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import re
|
|
20
|
+
from typing import Final, Protocol
|
|
21
|
+
|
|
22
|
+
ESC: Final = "\x1b"
|
|
23
|
+
BEL: Final = "\x07"
|
|
24
|
+
_CAN: Final = "\x18"
|
|
25
|
+
_SUB: Final = "\x1a"
|
|
26
|
+
_DEL: Final = "\x7f"
|
|
27
|
+
_ST: Final = "\x9c"
|
|
28
|
+
|
|
29
|
+
# C0, DEL and C1 never print. Decoded C1 code points are dropped rather than obeyed: in a UTF-8
|
|
30
|
+
# stream they are far likelier to be damage than an 8-bit control.
|
|
31
|
+
_PRINTABLE_RUN = re.compile(r"[^\x00-\x1f\x7f-\x9f]+")
|
|
32
|
+
_CONTROL_SEQUENCE = re.compile(r"([<=>?]?)([0-9:;]*)([ -/]*)([@-~])")
|
|
33
|
+
_STRING_RUN = re.compile(r"[^\x00-\x1f\x9c]+")
|
|
34
|
+
|
|
35
|
+
_MAX_PARAMETER_LENGTH: Final = 256
|
|
36
|
+
_MAX_STRING_LENGTH: Final = 1 << 18
|
|
37
|
+
|
|
38
|
+
_GROUND: Final = 0
|
|
39
|
+
_ESCAPE: Final = 1
|
|
40
|
+
_CSI_PARAMETERS: Final = 2
|
|
41
|
+
_CSI_INTERMEDIATES: Final = 3
|
|
42
|
+
_CSI_IGNORE: Final = 4
|
|
43
|
+
_OSC_STRING: Final = 5
|
|
44
|
+
_DCS_STRING: Final = 6
|
|
45
|
+
_IGNORED_STRING: Final = 7
|
|
46
|
+
|
|
47
|
+
# OSC and DCS carry data we act on; SOS, PM and APC are consumed so their text never prints.
|
|
48
|
+
_STRING_INTRODUCERS: Final = {
|
|
49
|
+
"]": _OSC_STRING,
|
|
50
|
+
"P": _DCS_STRING,
|
|
51
|
+
"X": _IGNORED_STRING,
|
|
52
|
+
"^": _IGNORED_STRING,
|
|
53
|
+
"_": _IGNORED_STRING,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class SequenceHandler(Protocol):
|
|
58
|
+
"""What a parser reports to."""
|
|
59
|
+
|
|
60
|
+
def print(self, text: str) -> None:
|
|
61
|
+
"""A run of printable characters."""
|
|
62
|
+
|
|
63
|
+
def execute(self, control: str) -> None:
|
|
64
|
+
"""A C0 control character."""
|
|
65
|
+
|
|
66
|
+
def escape(self, intermediates: str, final: str) -> None:
|
|
67
|
+
"""An escape sequence: ``ESC intermediates final``."""
|
|
68
|
+
|
|
69
|
+
def control_sequence(self, marker: str, parameters: str, intermediates: str, final: str) -> None:
|
|
70
|
+
"""A control sequence: ``CSI marker parameters intermediates final``.
|
|
71
|
+
|
|
72
|
+
``marker`` is the private-use prefix (one of ``<=>?``) or empty; ``parameters`` is the raw
|
|
73
|
+
parameter text, digits with ``;`` between parameters and ``:`` between sub-parameters.
|
|
74
|
+
"""
|
|
75
|
+
|
|
76
|
+
def operating_system_command(self, payload: str) -> None:
|
|
77
|
+
"""The text of an OSC string."""
|
|
78
|
+
|
|
79
|
+
def device_control(self, payload: str) -> None:
|
|
80
|
+
"""The text of a DCS string, introducer parameters included."""
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
class SequenceParser:
|
|
84
|
+
"""Feeds a `SequenceHandler` from a stream of decoded terminal output."""
|
|
85
|
+
|
|
86
|
+
__slots__ = ("_collected", "_collected_length", "_handler", "_intermediates", "_marker", "_state")
|
|
87
|
+
|
|
88
|
+
def __init__(self, handler: SequenceHandler) -> None:
|
|
89
|
+
self._handler = handler
|
|
90
|
+
self._state = _GROUND
|
|
91
|
+
self._marker = ""
|
|
92
|
+
self._collected: list[str] = []
|
|
93
|
+
self._collected_length = 0
|
|
94
|
+
self._intermediates = ""
|
|
95
|
+
|
|
96
|
+
def reset(self) -> None:
|
|
97
|
+
"""Forget any sequence in progress."""
|
|
98
|
+
self._state = _GROUND
|
|
99
|
+
self._begin_collecting()
|
|
100
|
+
|
|
101
|
+
def feed(self, data: str) -> None:
|
|
102
|
+
"""Parse the next piece of the stream."""
|
|
103
|
+
try:
|
|
104
|
+
self._feed(data)
|
|
105
|
+
except BaseException:
|
|
106
|
+
# Reports are made from inside a sequence as well: a string is still open while its
|
|
107
|
+
# text is handed over, a control character acts in the middle of whatever it interrupts.
|
|
108
|
+
# Left there, the parser would read what comes next as more of the same.
|
|
109
|
+
self.reset()
|
|
110
|
+
raise
|
|
111
|
+
|
|
112
|
+
def _feed(self, data: str) -> None:
|
|
113
|
+
handler = self._handler
|
|
114
|
+
position = 0
|
|
115
|
+
end = len(data)
|
|
116
|
+
while position < end:
|
|
117
|
+
state = self._state
|
|
118
|
+
if state == _GROUND:
|
|
119
|
+
if (run := _PRINTABLE_RUN.match(data, position)) is not None:
|
|
120
|
+
handler.print(run.group())
|
|
121
|
+
position = run.end()
|
|
122
|
+
continue
|
|
123
|
+
char = data[position]
|
|
124
|
+
position += 1
|
|
125
|
+
if char == ESC:
|
|
126
|
+
self._state = _ESCAPE
|
|
127
|
+
self._begin_collecting()
|
|
128
|
+
elif char < " ":
|
|
129
|
+
handler.execute(char)
|
|
130
|
+
continue
|
|
131
|
+
|
|
132
|
+
if state >= _OSC_STRING:
|
|
133
|
+
position = self._feed_string(data, position)
|
|
134
|
+
continue
|
|
135
|
+
|
|
136
|
+
char = data[position]
|
|
137
|
+
position += 1
|
|
138
|
+
if char == ESC:
|
|
139
|
+
self._state = _ESCAPE
|
|
140
|
+
self._begin_collecting()
|
|
141
|
+
elif char in (_CAN, _SUB):
|
|
142
|
+
self._state = _GROUND
|
|
143
|
+
elif char < " ":
|
|
144
|
+
handler.execute(char)
|
|
145
|
+
elif char >= _DEL:
|
|
146
|
+
if char != _DEL:
|
|
147
|
+
# Not part of any sequence: the sequence is damaged, the character still prints.
|
|
148
|
+
self._state = _GROUND
|
|
149
|
+
position -= 1
|
|
150
|
+
elif state == _ESCAPE:
|
|
151
|
+
position = self._feed_escape(char, data, position)
|
|
152
|
+
else:
|
|
153
|
+
self._feed_control_sequence(char)
|
|
154
|
+
|
|
155
|
+
def _begin_collecting(self) -> None:
|
|
156
|
+
self._marker = ""
|
|
157
|
+
self._collected = []
|
|
158
|
+
self._collected_length = 0
|
|
159
|
+
self._intermediates = ""
|
|
160
|
+
|
|
161
|
+
def _feed_escape(self, char: str, data: str, position: int) -> int:
|
|
162
|
+
if char < "0":
|
|
163
|
+
self._intermediates += char
|
|
164
|
+
return position
|
|
165
|
+
self._state = _GROUND
|
|
166
|
+
if self._intermediates:
|
|
167
|
+
self._handler.escape(self._intermediates, char)
|
|
168
|
+
elif char == "[":
|
|
169
|
+
if (sequence := _CONTROL_SEQUENCE.match(data, position)) is not None:
|
|
170
|
+
if len(sequence[2]) <= _MAX_PARAMETER_LENGTH:
|
|
171
|
+
self._handler.control_sequence(*sequence.groups())
|
|
172
|
+
return sequence.end()
|
|
173
|
+
self._state = _CSI_PARAMETERS
|
|
174
|
+
elif (string_state := _STRING_INTRODUCERS.get(char)) is not None:
|
|
175
|
+
self._state = string_state
|
|
176
|
+
else:
|
|
177
|
+
self._handler.escape("", char)
|
|
178
|
+
return position
|
|
179
|
+
|
|
180
|
+
def _feed_control_sequence(self, char: str) -> None:
|
|
181
|
+
if char >= "@":
|
|
182
|
+
if self._state != _CSI_IGNORE:
|
|
183
|
+
self._handler.control_sequence(self._marker, "".join(self._collected), self._intermediates, char)
|
|
184
|
+
self._state = _GROUND
|
|
185
|
+
elif self._state == _CSI_IGNORE:
|
|
186
|
+
pass
|
|
187
|
+
elif char < "0":
|
|
188
|
+
self._intermediates += char
|
|
189
|
+
self._state = _CSI_INTERMEDIATES
|
|
190
|
+
elif self._state == _CSI_INTERMEDIATES:
|
|
191
|
+
# A parameter byte after an intermediate is malformed; swallow through the final byte.
|
|
192
|
+
self._state = _CSI_IGNORE
|
|
193
|
+
elif char < "<":
|
|
194
|
+
self._collected.append(char)
|
|
195
|
+
if len(self._collected) > _MAX_PARAMETER_LENGTH:
|
|
196
|
+
self._state = _CSI_IGNORE
|
|
197
|
+
elif self._collected or self._marker:
|
|
198
|
+
self._state = _CSI_IGNORE
|
|
199
|
+
else:
|
|
200
|
+
self._marker = char
|
|
201
|
+
|
|
202
|
+
def _feed_string(self, data: str, position: int) -> int:
|
|
203
|
+
if (run := _STRING_RUN.match(data, position)) is not None:
|
|
204
|
+
if self._state != _IGNORED_STRING and self._collected_length <= _MAX_STRING_LENGTH:
|
|
205
|
+
self._collected.append(run.group())
|
|
206
|
+
self._collected_length += run.end() - position
|
|
207
|
+
return run.end()
|
|
208
|
+
char = data[position]
|
|
209
|
+
if char == ESC:
|
|
210
|
+
# Normally the first half of ST (ESC \); whatever follows, the string is over.
|
|
211
|
+
self._end_string()
|
|
212
|
+
self._state = _ESCAPE
|
|
213
|
+
self._begin_collecting()
|
|
214
|
+
elif char == _ST or (char == BEL and self._state == _OSC_STRING):
|
|
215
|
+
self._end_string()
|
|
216
|
+
self._state = _GROUND
|
|
217
|
+
elif char in (_CAN, _SUB):
|
|
218
|
+
self._state = _GROUND
|
|
219
|
+
return position + 1
|
|
220
|
+
|
|
221
|
+
def _end_string(self) -> None:
|
|
222
|
+
if self._collected_length > _MAX_STRING_LENGTH:
|
|
223
|
+
return
|
|
224
|
+
if self._state == _OSC_STRING:
|
|
225
|
+
self._handler.operating_system_command("".join(self._collected))
|
|
226
|
+
elif self._state == _DCS_STRING:
|
|
227
|
+
self._handler.device_control("".join(self._collected))
|