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,601 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Headless ``chrys workflow`` commands: list the workflows a session would find, check one, and run one."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
import argparse
|
|
8
|
+
import asyncio
|
|
9
|
+
import json
|
|
10
|
+
import math
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
import time
|
|
14
|
+
from dataclasses import dataclass
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Any, Final
|
|
17
|
+
|
|
18
|
+
from rich.cells import cell_len
|
|
19
|
+
from rich.console import Console
|
|
20
|
+
from rich.table import Table
|
|
21
|
+
from rich.text import Text
|
|
22
|
+
|
|
23
|
+
from chrys.app.cli import headless
|
|
24
|
+
from chrys.app.cli.headless import PreparedRuntime
|
|
25
|
+
from chrys.app.cli.launch_cwd import LAUNCH_CWD_MISSING_CODE, launch_cwd_missing_message
|
|
26
|
+
from chrys.app.cli.progress import ProgressWriter, WorkflowProgress, guarded, progress_console
|
|
27
|
+
from chrys.app.parsing import SanitizingArgumentParser
|
|
28
|
+
from chrys.foundation.branding import APP_COMMAND, APP_DISPLAY_NAME
|
|
29
|
+
from chrys.foundation.config.settings import DEFAULT_AGENT_PROFILE
|
|
30
|
+
from chrys.foundation.events.types import WorkflowRunAccepted
|
|
31
|
+
from chrys.foundation.i18n.formatting import sanitize_legacy_scalar, sanitize_terminal_block
|
|
32
|
+
from chrys.foundation.models.session_surface import SessionSurface
|
|
33
|
+
from chrys.foundation.platform import get_platform
|
|
34
|
+
from chrys.foundation.platform.files import surrogate_safe_text
|
|
35
|
+
from chrys.orchestration.session_host import (
|
|
36
|
+
AgentProfileNotFoundError,
|
|
37
|
+
AmbiguousSessionIdError,
|
|
38
|
+
ChrysSessionHost,
|
|
39
|
+
SessionNotFoundError,
|
|
40
|
+
WorkflowRunRejectedError,
|
|
41
|
+
WorkflowRunTimeoutError,
|
|
42
|
+
)
|
|
43
|
+
from chrys.orchestration.workflows.catalog import WorkflowCatalog, WorkflowNotFoundError
|
|
44
|
+
from chrys.orchestration.workflows.coordinator import REJECT_NOT_CONFIRMED
|
|
45
|
+
from chrys.orchestration.workflows.preview import WorkflowPreviewError
|
|
46
|
+
from chrys.orchestration.workflows.runner import WorkflowRunResult
|
|
47
|
+
from chrys.orchestration.workflows.validation import Diagnostic, ValidationReport, validate_workflow_path
|
|
48
|
+
from chrys.service.approval.policy import ApprovalMode
|
|
49
|
+
from chrys.service.workflows.discovery import (
|
|
50
|
+
SOURCE_KIND_BUILTIN,
|
|
51
|
+
Discovery,
|
|
52
|
+
)
|
|
53
|
+
from chrys.service.workflows.layout import run_dir
|
|
54
|
+
from chrys.service.workflows.outcomes import REASON_DEADLINE_EXCEEDED, RunOutcome
|
|
55
|
+
from chrys.service.workflows.store import read_run_output
|
|
56
|
+
|
|
57
|
+
EXIT_TIMEOUT: Final = 124
|
|
58
|
+
EXIT_INTERRUPTED: Final = 130
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
62
|
+
"""Build the ``chrys workflow`` parser: ``list``, ``validate`` and ``run`` sub-commands."""
|
|
63
|
+
parser = SanitizingArgumentParser(
|
|
64
|
+
prog=f"{APP_COMMAND} workflow",
|
|
65
|
+
description=f"List {APP_DISPLAY_NAME} workflows, check one, and run one headlessly until its outputs are ready.",
|
|
66
|
+
add_help=False,
|
|
67
|
+
)
|
|
68
|
+
_add_help(parser)
|
|
69
|
+
commands = parser.add_subparsers(
|
|
70
|
+
dest="command", metavar="command", required=True, parser_class=SanitizingArgumentParser
|
|
71
|
+
)
|
|
72
|
+
list_parser = commands.add_parser(
|
|
73
|
+
"list",
|
|
74
|
+
help="List the workflows found for the current directory",
|
|
75
|
+
description="List the workflows found for the current directory: builtin templates, the user's global "
|
|
76
|
+
"directory, and the project's .chrys/workflows directory. A workflow is a .py file, or a folder holding a "
|
|
77
|
+
".py file of the same name; a project workflow shadows a global one, which shadows a builtin.",
|
|
78
|
+
add_help=False,
|
|
79
|
+
)
|
|
80
|
+
_add_help(list_parser)
|
|
81
|
+
list_parser.add_argument("--json", action="store_true", help="Emit JSON output")
|
|
82
|
+
validate_parser = commands.add_parser(
|
|
83
|
+
"validate",
|
|
84
|
+
help="Check a workflow file or folder and report where it goes wrong",
|
|
85
|
+
description="Check a workflow file (.py) or folder the way a run would load it, and report each problem "
|
|
86
|
+
"with its file, line and column. This runs the workflow's top-level code, as a preview does, but no node; "
|
|
87
|
+
"it records no confirmation. Exit code 0 means PASS (warnings allowed), 1 means FAIL.",
|
|
88
|
+
add_help=False,
|
|
89
|
+
)
|
|
90
|
+
_add_help(validate_parser)
|
|
91
|
+
validate_parser.add_argument("path", help="The workflow file or folder, relative to the current directory")
|
|
92
|
+
validate_parser.add_argument("--json", action="store_true", help="Emit one JSON report on stdout")
|
|
93
|
+
run_parser = commands.add_parser(
|
|
94
|
+
"run",
|
|
95
|
+
help="Run one workflow until it finishes and print its outputs",
|
|
96
|
+
description="Run one workflow until it finishes and print its outputs. A user workflow must have been "
|
|
97
|
+
"confirmed before; --trust confirms it as it is now.",
|
|
98
|
+
add_help=False,
|
|
99
|
+
)
|
|
100
|
+
_add_help(run_parser)
|
|
101
|
+
run_parser.add_argument(
|
|
102
|
+
"workflow_id",
|
|
103
|
+
help=f"Workflow id (the file name without .py, or the folder name), as listed by '{APP_COMMAND} workflow list'",
|
|
104
|
+
)
|
|
105
|
+
run_parser.add_argument(
|
|
106
|
+
"--input", metavar="TEXT", default="", help="Input text handed to the workflow's start node (default: empty)"
|
|
107
|
+
)
|
|
108
|
+
run_parser.add_argument("-s", "--session", default=None, help="Optional session id to restore before running")
|
|
109
|
+
run_parser.add_argument(
|
|
110
|
+
"--trust",
|
|
111
|
+
action="store_true",
|
|
112
|
+
help="Confirm the workflow as it is now (its files, topology and environment) instead of requiring "
|
|
113
|
+
"an earlier confirmation; builtin templates need no confirmation",
|
|
114
|
+
)
|
|
115
|
+
run_parser.add_argument(
|
|
116
|
+
"--timeout",
|
|
117
|
+
metavar="SECONDS",
|
|
118
|
+
type=float,
|
|
119
|
+
default=None,
|
|
120
|
+
help="Limit workflow preview, loading and execution to this many seconds (exit code 124)",
|
|
121
|
+
)
|
|
122
|
+
run_parser.add_argument("--json", action="store_true", help="Emit JSON output")
|
|
123
|
+
run_parser.add_argument(
|
|
124
|
+
"-q",
|
|
125
|
+
"--quiet",
|
|
126
|
+
action="store_true",
|
|
127
|
+
help=(
|
|
128
|
+
"Do not show progress on stderr; only warnings, errors, captured load output and output outside nodes,"
|
|
129
|
+
" and the outputs are printed"
|
|
130
|
+
),
|
|
131
|
+
)
|
|
132
|
+
return parser
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
def _add_help(parser: argparse.ArgumentParser) -> None:
|
|
136
|
+
parser.add_argument(
|
|
137
|
+
"-h", "--help", action="help", default=argparse.SUPPRESS, help="Show this help message and exit"
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
@dataclass(frozen=True, slots=True)
|
|
142
|
+
class _WorkflowRow:
|
|
143
|
+
workflow_id: str
|
|
144
|
+
source_kind: str
|
|
145
|
+
layout: str
|
|
146
|
+
path: str
|
|
147
|
+
title: str
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def _rows(catalog: WorkflowCatalog, discovery: Discovery) -> list[_WorkflowRow]:
|
|
151
|
+
"""List builtin and confirmed user titles without executing workflow code."""
|
|
152
|
+
ledger = catalog.ledger()
|
|
153
|
+
return [
|
|
154
|
+
_WorkflowRow(
|
|
155
|
+
source.workflow_id,
|
|
156
|
+
source.source_kind,
|
|
157
|
+
source.layout,
|
|
158
|
+
source.canonical_path,
|
|
159
|
+
catalog.title(source, ledger=ledger) or "",
|
|
160
|
+
)
|
|
161
|
+
for source in discovery.sources
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
def _list_command(args: argparse.Namespace) -> int:
|
|
166
|
+
prepared = headless.prepare_runtime()
|
|
167
|
+
headless.write_pending_warnings(prepared, as_json=args.json)
|
|
168
|
+
catalog = WorkflowCatalog(config_dir=get_platform().config_dir, project_cwd=Path.cwd())
|
|
169
|
+
discovery = catalog.discover()
|
|
170
|
+
for skipped in discovery.skipped:
|
|
171
|
+
headless.write_warning(f"Skipped {skipped.path}: {skipped.reason}", as_json=args.json, code="workflow_skipped")
|
|
172
|
+
rows = _rows(catalog, discovery)
|
|
173
|
+
if args.json:
|
|
174
|
+
headless.write_json(
|
|
175
|
+
{
|
|
176
|
+
"workflows": [
|
|
177
|
+
{
|
|
178
|
+
"id": row.workflow_id,
|
|
179
|
+
"source": row.source_kind,
|
|
180
|
+
"layout": row.layout,
|
|
181
|
+
"title": row.title,
|
|
182
|
+
"path": row.path,
|
|
183
|
+
}
|
|
184
|
+
for row in rows
|
|
185
|
+
]
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
return 0
|
|
189
|
+
_print_workflows(rows)
|
|
190
|
+
return 0
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _print_workflows(rows: list[_WorkflowRow]) -> None:
|
|
194
|
+
console = Console(file=sys.stdout, highlight=False)
|
|
195
|
+
if not rows:
|
|
196
|
+
console.print(Text("No workflows found."))
|
|
197
|
+
return
|
|
198
|
+
table = Table(box=None, show_edge=False, pad_edge=False)
|
|
199
|
+
table.add_column("ID", no_wrap=True)
|
|
200
|
+
table.add_column("Source", no_wrap=True)
|
|
201
|
+
table.add_column("Title", overflow="fold")
|
|
202
|
+
table.add_column("Path", overflow="fold")
|
|
203
|
+
for row in rows:
|
|
204
|
+
table.add_row(
|
|
205
|
+
_cell(row.workflow_id),
|
|
206
|
+
Text(row.source_kind),
|
|
207
|
+
_cell(row.title or "-"),
|
|
208
|
+
_cell(row.path),
|
|
209
|
+
)
|
|
210
|
+
console.print(table)
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def _cell(value: str) -> Text:
|
|
214
|
+
"""A name, title or path from the user's files, without controls or lone surrogates."""
|
|
215
|
+
return Text(sanitize_legacy_scalar(surrogate_safe_text(value)))
|
|
216
|
+
|
|
217
|
+
|
|
218
|
+
def _validate_main(args: argparse.Namespace) -> int:
|
|
219
|
+
"""``workflow validate``: once the runtime is prepared, stdout carries a full report whatever happens."""
|
|
220
|
+
try:
|
|
221
|
+
runtime = headless.prepare_runtime()
|
|
222
|
+
headless.write_pending_warnings(runtime, as_json=args.json)
|
|
223
|
+
workspace = Path.cwd()
|
|
224
|
+
report = asyncio.run(
|
|
225
|
+
validate_workflow_path(
|
|
226
|
+
args.path, config_dir=get_platform().config_dir, workspace=workspace, settings=runtime.settings
|
|
227
|
+
)
|
|
228
|
+
)
|
|
229
|
+
except KeyboardInterrupt:
|
|
230
|
+
headless.write_error("Interrupted by user.", as_json=args.json, code="interrupted")
|
|
231
|
+
return EXIT_INTERRUPTED
|
|
232
|
+
except Exception as exc:
|
|
233
|
+
headless.write_error(headless.exception_message(exc), as_json=args.json)
|
|
234
|
+
return 1
|
|
235
|
+
if args.json:
|
|
236
|
+
sys.stdout.write(json.dumps(_report_json(report), ensure_ascii=True) + "\n")
|
|
237
|
+
else:
|
|
238
|
+
sys.stdout.write("".join(f"{line}\n" for line in _report_lines(report, workspace)))
|
|
239
|
+
return 0 if report.passed else 1
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
def _report_lines(report: ValidationReport, workspace: Path) -> list[str]:
|
|
243
|
+
"""The human report: compiler-style diagnostics, then one ``PASS``/``FAIL`` line.
|
|
244
|
+
|
|
245
|
+
Every value from the files is shown on one line with controls replaced,
|
|
246
|
+
and only the renderer's own lines start at column 0, so nothing a
|
|
247
|
+
workflow prints or names can pass for the status line.
|
|
248
|
+
"""
|
|
249
|
+
lines: list[str] = []
|
|
250
|
+
for diagnostic in report.diagnostics:
|
|
251
|
+
lines.extend(_diagnostic_lines(diagnostic, workspace))
|
|
252
|
+
if report.diagnostics_truncated:
|
|
253
|
+
lines.append(" note: more diagnostics were found than are shown")
|
|
254
|
+
if not report.passed and report.output.text:
|
|
255
|
+
lines.append("captured output (load, truncated):" if report.output.truncated else "captured output (load):")
|
|
256
|
+
lines.extend(f" | {_one_line(text)}" for text in report.output.text.splitlines())
|
|
257
|
+
lines.append(_status_line(report, workspace))
|
|
258
|
+
return lines
|
|
259
|
+
|
|
260
|
+
|
|
261
|
+
def _diagnostic_lines(diagnostic: Diagnostic, workspace: Path) -> list[str]:
|
|
262
|
+
place = ""
|
|
263
|
+
if diagnostic.file is not None:
|
|
264
|
+
place = _shown_path(diagnostic.file, workspace)
|
|
265
|
+
if diagnostic.line is not None:
|
|
266
|
+
place += f":{diagnostic.line}"
|
|
267
|
+
if diagnostic.column is not None:
|
|
268
|
+
place += f":{diagnostic.column}"
|
|
269
|
+
place += ": "
|
|
270
|
+
first, *rest = diagnostic.message.splitlines() or [""]
|
|
271
|
+
lines = [f"{place}{diagnostic.severity}: {_one_line(first)} [{_one_line(diagnostic.code)}]"]
|
|
272
|
+
lines.extend(f" {_one_line(text)}" for text in rest)
|
|
273
|
+
if diagnostic.line is not None and diagnostic.source_line is not None:
|
|
274
|
+
gutter = f"{diagnostic.line:>5}"
|
|
275
|
+
lines.append(f"{gutter} | {_one_line(diagnostic.source_line.replace(chr(9), ' '))}")
|
|
276
|
+
if diagnostic.column is not None:
|
|
277
|
+
lines.append(f"{' ' * len(gutter)} | {_caret(diagnostic)}")
|
|
278
|
+
for note in diagnostic.notes:
|
|
279
|
+
where = ""
|
|
280
|
+
if note.file is not None:
|
|
281
|
+
where = " " + _shown_path(note.file, workspace) + (f":{note.line}" if note.line is not None else "")
|
|
282
|
+
lines.append(f" note: {_one_line(note.message)}{where}")
|
|
283
|
+
if diagnostic.hint is not None:
|
|
284
|
+
lines.append(f" help: {_one_line(diagnostic.hint)}")
|
|
285
|
+
return lines
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
def _caret(diagnostic: Diagnostic) -> str:
|
|
289
|
+
"""``^`` under the column (by display width, a tab counted as one cell), ``~`` along the rest of the range."""
|
|
290
|
+
text = (diagnostic.source_line or "").replace("\t", " ")
|
|
291
|
+
column = diagnostic.column or 1
|
|
292
|
+
start = cell_len(_one_line(text[: column - 1]))
|
|
293
|
+
width = 1
|
|
294
|
+
end = diagnostic.end_column
|
|
295
|
+
if diagnostic.end_line == diagnostic.line and end is not None and end > column:
|
|
296
|
+
width = max(1, cell_len(_one_line(text[column - 1 : end - 1])))
|
|
297
|
+
return " " * start + "^" + "~" * (width - 1)
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
def _status_line(report: ValidationReport, workspace: Path) -> str:
|
|
301
|
+
name = _one_line(report.workflow_id) if report.workflow_id is not None else _shown_path(report.path, workspace)
|
|
302
|
+
if report.layout is not None:
|
|
303
|
+
name += f" ({report.layout})"
|
|
304
|
+
errors = sum(diagnostic.severity == "error" for diagnostic in report.diagnostics)
|
|
305
|
+
warnings = len(report.diagnostics) - errors
|
|
306
|
+
if report.passed and report.workflow is not None:
|
|
307
|
+
parts = [
|
|
308
|
+
f"PASS {name}",
|
|
309
|
+
_count(report.workflow.node_count, "node"),
|
|
310
|
+
_count(report.workflow.edge_count, "edge"),
|
|
311
|
+
]
|
|
312
|
+
if warnings:
|
|
313
|
+
parts.append(_count(warnings, "warning"))
|
|
314
|
+
return " · ".join(parts)
|
|
315
|
+
counts = _count(errors, "error") + (f", {_count(warnings, 'warning')}" if warnings else "")
|
|
316
|
+
return f"FAIL {name}: {counts}"
|
|
317
|
+
|
|
318
|
+
|
|
319
|
+
def _count(number: int, noun: str) -> str:
|
|
320
|
+
return f"{number} {noun}" if number == 1 else f"{number} {noun}s"
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def _shown_path(path: str, workspace: Path) -> str:
|
|
324
|
+
"""``./`` and the path below the current directory, or the absolute path, on one line."""
|
|
325
|
+
try:
|
|
326
|
+
relative = Path(path).relative_to(workspace)
|
|
327
|
+
except ValueError:
|
|
328
|
+
shown = path
|
|
329
|
+
else:
|
|
330
|
+
shown = "." if not relative.parts else f".{os.sep}{relative}"
|
|
331
|
+
return _one_line(shown)
|
|
332
|
+
|
|
333
|
+
|
|
334
|
+
def _one_line(text: str) -> str:
|
|
335
|
+
"""*text* as one display line: lone surrogates made safe, controls and Unicode line breaks replaced."""
|
|
336
|
+
return sanitize_legacy_scalar(surrogate_safe_text(text)).replace("\u2028", "\ufffd").replace("\u2029", "\ufffd")
|
|
337
|
+
|
|
338
|
+
|
|
339
|
+
def _report_json(report: ValidationReport) -> dict[str, Any]:
|
|
340
|
+
"""Version 1 of the ``--json`` report; every key is always present, unknown values are null."""
|
|
341
|
+
workflow = report.workflow
|
|
342
|
+
return {
|
|
343
|
+
"version": 1,
|
|
344
|
+
"status": "pass" if report.passed else "fail",
|
|
345
|
+
"target": {
|
|
346
|
+
"path": report.path,
|
|
347
|
+
"layout": report.layout,
|
|
348
|
+
"workflow_id": report.workflow_id,
|
|
349
|
+
"entry": report.entry,
|
|
350
|
+
"package_dir": report.package_dir,
|
|
351
|
+
"source_digest": report.source_digest,
|
|
352
|
+
"files": report.files,
|
|
353
|
+
},
|
|
354
|
+
"stages": [{"name": name, "status": status} for name, status in report.stages],
|
|
355
|
+
"diagnostics": [
|
|
356
|
+
{
|
|
357
|
+
"severity": diagnostic.severity,
|
|
358
|
+
"code": diagnostic.code,
|
|
359
|
+
"stage": diagnostic.stage,
|
|
360
|
+
"message": diagnostic.message,
|
|
361
|
+
"file": diagnostic.file,
|
|
362
|
+
"line": diagnostic.line,
|
|
363
|
+
"column": diagnostic.column,
|
|
364
|
+
"end_line": diagnostic.end_line,
|
|
365
|
+
"end_column": diagnostic.end_column,
|
|
366
|
+
"node": diagnostic.node,
|
|
367
|
+
"source_line": diagnostic.source_line,
|
|
368
|
+
"notes": [{"message": note.message, "file": note.file, "line": note.line} for note in diagnostic.notes],
|
|
369
|
+
"hint": diagnostic.hint,
|
|
370
|
+
"traceback": diagnostic.traceback,
|
|
371
|
+
}
|
|
372
|
+
for diagnostic in report.diagnostics
|
|
373
|
+
],
|
|
374
|
+
"diagnostics_truncated": report.diagnostics_truncated,
|
|
375
|
+
"sites_truncated": report.sites_truncated,
|
|
376
|
+
"workflow": None
|
|
377
|
+
if workflow is None
|
|
378
|
+
else {
|
|
379
|
+
"title": workflow.title,
|
|
380
|
+
"node_count": workflow.node_count,
|
|
381
|
+
"edge_count": workflow.edge_count,
|
|
382
|
+
"outputs": list(workflow.outputs),
|
|
383
|
+
},
|
|
384
|
+
"output": {"text": report.output.text, "truncated": report.output.truncated},
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def _workflow_progress(args: argparse.Namespace, runtime: PreparedRuntime) -> WorkflowProgress | None:
|
|
389
|
+
"""Progress on stderr (only its warnings for quiet output); nothing for JSON."""
|
|
390
|
+
if args.json:
|
|
391
|
+
return None
|
|
392
|
+
writer = ProgressWriter(
|
|
393
|
+
progress_console(), reported_warnings=headless.reported_warning_keys(runtime), quiet=args.quiet
|
|
394
|
+
)
|
|
395
|
+
return WorkflowProgress(writer, render=runtime.localizer.render)
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
async def _run_command(args: argparse.Namespace) -> int:
|
|
399
|
+
session_id = (args.session or "").strip()
|
|
400
|
+
runtime = headless.prepare_runtime(restoring_session=bool(session_id))
|
|
401
|
+
headless.write_pending_warnings(runtime, as_json=args.json)
|
|
402
|
+
progress = _workflow_progress(args, runtime)
|
|
403
|
+
loaded = runtime.loaded
|
|
404
|
+
host = ChrysSessionHost(
|
|
405
|
+
profile_name=loaded.settings.default_agent.strip() or DEFAULT_AGENT_PROFILE,
|
|
406
|
+
loaded_settings=loaded,
|
|
407
|
+
approval_mode=ApprovalMode.BYPASS,
|
|
408
|
+
surface=SessionSurface.CLI,
|
|
409
|
+
)
|
|
410
|
+
started = time.monotonic()
|
|
411
|
+
try:
|
|
412
|
+
if session_id:
|
|
413
|
+
await host.load_workflow_session(session_id)
|
|
414
|
+
target = host.workflow_target(args.workflow_id)
|
|
415
|
+
timeout = args.timeout or 0.0
|
|
416
|
+
if progress is not None:
|
|
417
|
+
progress.starting(args.workflow_id, checking=args.trust)
|
|
418
|
+
if args.trust:
|
|
419
|
+
preview_started = time.monotonic()
|
|
420
|
+
preview_deadline = asyncio.timeout(timeout or None)
|
|
421
|
+
try:
|
|
422
|
+
async with preview_deadline:
|
|
423
|
+
prepared = await host.preview_workflow(target, trust=True)
|
|
424
|
+
except TimeoutError as exc:
|
|
425
|
+
if not preview_deadline.expired():
|
|
426
|
+
raise
|
|
427
|
+
raise WorkflowRunTimeoutError("Workflow run timed out during preview.") from exc
|
|
428
|
+
if prepared.preview.source.source_kind != SOURCE_KIND_BUILTIN:
|
|
429
|
+
host.confirm_workflow(prepared)
|
|
430
|
+
for warning in prepared.preview.warnings:
|
|
431
|
+
headless.write_warning(warning.message, as_json=args.json, code=warning.code)
|
|
432
|
+
if progress is not None:
|
|
433
|
+
progress.reported(warning.code, warning.message)
|
|
434
|
+
target = prepared
|
|
435
|
+
if timeout:
|
|
436
|
+
timeout -= time.monotonic() - preview_started
|
|
437
|
+
if timeout <= 0:
|
|
438
|
+
raise WorkflowRunTimeoutError("Workflow run timed out during preview.")
|
|
439
|
+
run_id = ""
|
|
440
|
+
on_event = None if progress is None else guarded(progress.handle)
|
|
441
|
+
async for event in host.iter_workflow_events(
|
|
442
|
+
target,
|
|
443
|
+
input_text=args.input,
|
|
444
|
+
timeout=timeout,
|
|
445
|
+
include_node_activity=progress is not None,
|
|
446
|
+
):
|
|
447
|
+
if isinstance(event, WorkflowRunAccepted):
|
|
448
|
+
run_id = event.run_id
|
|
449
|
+
if on_event is not None:
|
|
450
|
+
on_event(event)
|
|
451
|
+
result = host.engine.workflows.result(run_id)
|
|
452
|
+
if result is None:
|
|
453
|
+
error_message = "Workflow run ended without a recorded result."
|
|
454
|
+
raise RuntimeError(error_message)
|
|
455
|
+
diagnostics = None
|
|
456
|
+
if host.workflow_session_dir is not None:
|
|
457
|
+
try:
|
|
458
|
+
diagnostics = await asyncio.to_thread(read_run_output, run_dir(host.workflow_session_dir, run_id))
|
|
459
|
+
except (OSError, ValueError) as exc:
|
|
460
|
+
diagnostics = {"error": str(exc)}
|
|
461
|
+
duration = time.monotonic() - started
|
|
462
|
+
if progress is not None and diagnostics:
|
|
463
|
+
progress.captured(diagnostics)
|
|
464
|
+
if progress is not None and result.outcome is RunOutcome.COMPLETED:
|
|
465
|
+
progress.succeeded(duration=duration)
|
|
466
|
+
return _report(
|
|
467
|
+
result,
|
|
468
|
+
session_id=host.workflow_session_id,
|
|
469
|
+
as_json=args.json,
|
|
470
|
+
duration=duration,
|
|
471
|
+
diagnostics=diagnostics,
|
|
472
|
+
)
|
|
473
|
+
finally:
|
|
474
|
+
await host.shutdown()
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
def _report(
|
|
478
|
+
result: WorkflowRunResult,
|
|
479
|
+
*,
|
|
480
|
+
session_id: str | None,
|
|
481
|
+
as_json: bool,
|
|
482
|
+
duration: float,
|
|
483
|
+
diagnostics: dict[str, Any] | None = None,
|
|
484
|
+
) -> int:
|
|
485
|
+
"""Write the outputs (text or JSON), then the outcome when the run did not complete.
|
|
486
|
+
|
|
487
|
+
Text mode's ``diagnostics`` were already written to stderr (``WorkflowProgress.captured``); JSON carries them.
|
|
488
|
+
"""
|
|
489
|
+
outcome = result.outcome.value
|
|
490
|
+
if as_json:
|
|
491
|
+
headless.write_json(
|
|
492
|
+
{
|
|
493
|
+
"session_id": session_id,
|
|
494
|
+
"run_id": result.run_id,
|
|
495
|
+
"outcome": outcome,
|
|
496
|
+
"reason": result.reason,
|
|
497
|
+
"node_id": result.node_id,
|
|
498
|
+
"error": result.error,
|
|
499
|
+
"duration": round(duration, 3),
|
|
500
|
+
"diagnostics": diagnostics,
|
|
501
|
+
"outputs": [
|
|
502
|
+
{
|
|
503
|
+
"node_id": output.node_id,
|
|
504
|
+
"activation_id": output.activation_id,
|
|
505
|
+
"text": output.value.text,
|
|
506
|
+
"data": output.value.data,
|
|
507
|
+
}
|
|
508
|
+
for output in result.outputs
|
|
509
|
+
],
|
|
510
|
+
}
|
|
511
|
+
)
|
|
512
|
+
else:
|
|
513
|
+
text = "\n\n".join(output.value.text for output in result.outputs)
|
|
514
|
+
# Node output can carry model text: neutralize terminal control
|
|
515
|
+
# sequences on a terminal, keep redirected output byte-for-byte.
|
|
516
|
+
if sys.stdout.isatty():
|
|
517
|
+
text = sanitize_terminal_block(text)
|
|
518
|
+
if text:
|
|
519
|
+
sys.stdout.write(text if text.endswith("\n") else f"{text}\n")
|
|
520
|
+
if result.outcome is not RunOutcome.COMPLETED:
|
|
521
|
+
headless.write_error(_outcome_message(result), as_json=as_json, code=outcome, session_id=session_id)
|
|
522
|
+
return _exit_code(result)
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
def _outcome_message(result: WorkflowRunResult) -> str:
|
|
526
|
+
match result.outcome:
|
|
527
|
+
case RunOutcome.NODE_FAILED:
|
|
528
|
+
message = f"Workflow run failed at node {result.node_id!r}"
|
|
529
|
+
case RunOutcome.LOOP_EXHAUSTED:
|
|
530
|
+
message = f"Workflow loop {result.node_id!r} exhausted its iterations"
|
|
531
|
+
case RunOutcome.CANCELLED if result.reason == REASON_DEADLINE_EXCEEDED:
|
|
532
|
+
message = "Workflow run timed out"
|
|
533
|
+
case RunOutcome.CANCELLED:
|
|
534
|
+
message = f"Workflow run was cancelled ({result.reason})" if result.reason else "Workflow run was cancelled"
|
|
535
|
+
case RunOutcome.WORKER_LOST:
|
|
536
|
+
message = "The workflow worker was lost"
|
|
537
|
+
case RunOutcome.STORAGE_FAILED:
|
|
538
|
+
message = "The workflow run record could not be written"
|
|
539
|
+
case _:
|
|
540
|
+
message = f"Workflow run ended with outcome {result.outcome.value}"
|
|
541
|
+
return f"{message}: {result.error}" if result.error else f"{message}."
|
|
542
|
+
|
|
543
|
+
|
|
544
|
+
def _exit_code(result: WorkflowRunResult) -> int:
|
|
545
|
+
if result.outcome is RunOutcome.COMPLETED:
|
|
546
|
+
return 0
|
|
547
|
+
if result.outcome is RunOutcome.CANCELLED and result.reason == REASON_DEADLINE_EXCEEDED:
|
|
548
|
+
return EXIT_TIMEOUT
|
|
549
|
+
return 1
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def main(argv: list[str] | None = None) -> int:
|
|
553
|
+
"""Entry point for ``chrys workflow``."""
|
|
554
|
+
headless.configure_logging()
|
|
555
|
+
parser = build_parser()
|
|
556
|
+
args = parser.parse_args(argv)
|
|
557
|
+
if (missing_cwd := launch_cwd_missing_message(workdir_flag=False)) is not None:
|
|
558
|
+
headless.write_error(missing_cwd, as_json=args.json, code=LAUNCH_CWD_MISSING_CODE)
|
|
559
|
+
return 1
|
|
560
|
+
if args.command == "list":
|
|
561
|
+
return _list_command(args)
|
|
562
|
+
if args.command == "validate":
|
|
563
|
+
return _validate_main(args)
|
|
564
|
+
if args.timeout is not None and not (math.isfinite(args.timeout) and args.timeout > 0):
|
|
565
|
+
parser.error("--timeout must be a positive number of seconds")
|
|
566
|
+
try:
|
|
567
|
+
return asyncio.run(_run_command(args))
|
|
568
|
+
except WorkflowRunTimeoutError as exc:
|
|
569
|
+
headless.write_error(str(exc), as_json=args.json, code=REASON_DEADLINE_EXCEEDED)
|
|
570
|
+
return EXIT_TIMEOUT
|
|
571
|
+
except WorkflowRunRejectedError as exc:
|
|
572
|
+
message = exc.event.message
|
|
573
|
+
if exc.event.error == REJECT_NOT_CONFIRMED:
|
|
574
|
+
message = f"{message} Pass --trust to confirm it."
|
|
575
|
+
headless.write_error(message, as_json=args.json, code=exc.event.error or "workflow_rejected")
|
|
576
|
+
return 1
|
|
577
|
+
except WorkflowNotFoundError as exc:
|
|
578
|
+
headless.write_error(headless.exception_message(exc), as_json=args.json, code="workflow_not_found")
|
|
579
|
+
return 1
|
|
580
|
+
except WorkflowPreviewError as exc:
|
|
581
|
+
headless.write_error(exc.message, as_json=args.json, code=exc.code)
|
|
582
|
+
return 1
|
|
583
|
+
except SessionNotFoundError as exc:
|
|
584
|
+
headless.write_error(headless.exception_message(exc), as_json=args.json, code="session_not_found")
|
|
585
|
+
return 1
|
|
586
|
+
except AmbiguousSessionIdError as exc:
|
|
587
|
+
headless.write_error(headless.exception_message(exc), as_json=args.json, code="session_ambiguous")
|
|
588
|
+
return 1
|
|
589
|
+
except AgentProfileNotFoundError as exc:
|
|
590
|
+
headless.write_error(headless.exception_message(exc), as_json=args.json, code="profile_not_found")
|
|
591
|
+
return 1
|
|
592
|
+
except KeyboardInterrupt:
|
|
593
|
+
headless.write_error("Interrupted by user.", as_json=args.json, code="interrupted")
|
|
594
|
+
return EXIT_INTERRUPTED
|
|
595
|
+
except Exception as exc:
|
|
596
|
+
headless.write_error(headless.exception_message(exc), as_json=args.json)
|
|
597
|
+
return 1
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
if __name__ == "__main__":
|
|
601
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# Copyright (c) Huawei Technologies Co., Ltd. 2026. All rights reserved.
|
|
2
|
+
|
|
3
|
+
"""Everything that can happen to the buddy. Each change is one locked read-modify-write of the save file.
|
|
4
|
+
|
|
5
|
+
A change raises ``OSError`` when the save file cannot be written, which includes the
|
|
6
|
+
``TimeoutError`` of another instance holding it for too long. Reading never raises.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from __future__ import annotations
|
|
10
|
+
|
|
11
|
+
from dataclasses import replace
|
|
12
|
+
from random import SystemRandom
|
|
13
|
+
from typing import TYPE_CHECKING
|
|
14
|
+
|
|
15
|
+
from chrys.app.features.buddy.hatchery import hatchling
|
|
16
|
+
from chrys.app.features.buddy.model import Buddy, BuddyRecord, clean_name
|
|
17
|
+
from chrys.app.features.buddy.store import BuddyStore
|
|
18
|
+
|
|
19
|
+
if TYPE_CHECKING:
|
|
20
|
+
from collections.abc import Callable
|
|
21
|
+
from random import Random
|
|
22
|
+
|
|
23
|
+
_STORE = BuddyStore()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def current_buddy() -> Buddy | None:
|
|
27
|
+
"""The user's buddy, or None before one has hatched."""
|
|
28
|
+
return _grown(_STORE.load())
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def hatch(rng: Random | None = None) -> Buddy:
|
|
32
|
+
"""Hatch a buddy. When one already exists, in this instance or another, that one is returned."""
|
|
33
|
+
newborn = hatchling(rng if rng is not None else SystemRandom())
|
|
34
|
+
record = _STORE.update(lambda current: current if current is not None else newborn)
|
|
35
|
+
if record is None:
|
|
36
|
+
raise RuntimeError("Hatching a buddy did not produce a stored record.")
|
|
37
|
+
return Buddy.of(record)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def rename(name: str) -> Buddy | None:
|
|
41
|
+
"""Give the buddy a new name. A name that cleans up to nothing changes nothing."""
|
|
42
|
+
cleaned = clean_name(name)
|
|
43
|
+
return _change(lambda record: replace(record, name=cleaned) if cleaned else record)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def set_muted(muted: bool) -> Buddy | None:
|
|
47
|
+
return _change(lambda record: replace(record, muted=muted))
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def record_pet() -> Buddy | None:
|
|
51
|
+
return _change(lambda record: replace(record, pets=record.pets + 1))
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def record_turn() -> Buddy | None:
|
|
55
|
+
return _change(lambda record: replace(record, turns=record.turns + 1))
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def _change(edit: Callable[[BuddyRecord], BuddyRecord]) -> Buddy | None:
|
|
59
|
+
"""Apply *edit* to the hatched buddy. Without one, nothing happens and None comes back."""
|
|
60
|
+
# Most users never hatch one, and every finished turn ends up here: look before queueing for the
|
|
61
|
+
# lock, so that for them a turn touches nothing on disk and cannot wait on another instance.
|
|
62
|
+
if _STORE.load() is None:
|
|
63
|
+
return None
|
|
64
|
+
return _grown(_STORE.update(lambda current: edit(current) if current is not None else None))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def _grown(record: BuddyRecord | None) -> Buddy | None:
|
|
68
|
+
return Buddy.of(record) if record is not None else None
|