kolega-code 0.15.0__tar.gz → 0.16.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.gitignore +1 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/CHANGELOG.md +29 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/PKG-INFO +2 -2
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/astro.config.mjs +4 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/coverage.svg +1 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/providers-and-models.mdx +2 -0
- kolega_code-0.16.0/docs/src/content/docs/troubleshooting/terminal-tmux.md +67 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/composer.md +21 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/interface.md +4 -2
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/slash-commands.md +2 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/__init__.py +1 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/__init__.py +1 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/edit_tool.py +53 -5
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/lsp_tool.py +60 -8
- kolega_code-0.16.0/kolega_code/agent/tool_backend/snapshot_tool.py +191 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tools.py +124 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/app.py +21 -2
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/messages.py +11 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/provider_registry.py +2 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/slash_commands.py +5 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/command_handlers.py +10 -8
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/widgets.py +33 -10
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/openai.py +13 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/xai.py +13 -0
- kolega_code-0.16.0/kolega_code/services/snapshots.py +600 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/pyproject.toml +2 -2
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_model_specs.py +12 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_reasoning_replay.py +1 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_supports_vision.py +1 -0
- kolega_code-0.16.0/tests/agent/llm/test_xai_prompt_cache_header.py +38 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_agent_tools_inventory.py +1 -1
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_config.py +3 -0
- kolega_code-0.16.0/tests/agent/tool_backend/test_snapshot_tool.py +345 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_composer_input.py +99 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_image_vision_warning.py +3 -3
- kolega_code-0.16.0/tests/cli/test_app_tmux_shortcuts.py +193 -0
- kolega_code-0.16.0/tests/services/test_snapshots.py +138 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/uv.lock +104 -104
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.env.example +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.githooks/pre-commit +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/workflows/ci.yml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/workflows/docs.yml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.github/workflows/release.yml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/.pre-commit-config.yaml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/CONTRIBUTING.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/LICENSE +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/README.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/RELEASING.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/SECURITY.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/.gitignore +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/README.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/package-lock.json +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/package.json +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/public/favicon.svg +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/demo.gif +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/kolega-dark.svg +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/assets/kolega-light.svg +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/ask.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/doctor.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/overview.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/cli/sessions.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/concepts/agents.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/concepts/how-it-works.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/concepts/tools.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/environment-variables.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/lsp.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/mcp.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/prompt-overrides.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/settings-and-api-keys.mdx +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/configuration/sign-in-with-chatgpt.mdx +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/getting-started/installation.mdx +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/getting-started/quick-start.mdx +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/gigacode.mdx +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/goal.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/hooks.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/index.mdx +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/skills.mdx +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/troubleshooting/diagnostics.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/modes.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content/docs/tui/sessions-and-resume.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/content.config.ts +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/src/styles/brand.css +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/docs/tsconfig.json +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/baseagent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/browseragent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/coder.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/common.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/compression.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/context.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/conversation.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/errors.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/generalagent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/goal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/investigationagent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/budget.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/errors.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/executor.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/guide.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/journal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/runtime.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/orchestration/types.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/planningagent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_dump.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_overrides.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_provider.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.system.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/compression/summary.user.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/output_summary.system.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/terminal/safety.system.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/auxiliary/tools/think_hard.system.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/cli/current_plan_artifact.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/cli/planning_questions.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/cli/shared_task_list.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/extensions/skills/catalog.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/browser.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/coder_cli.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/general.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/investigation.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/agents/planning.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/agents_md_instructions.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/environment_variables/workspace_env_vars.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/frontend_guidance.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/expo.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/html_website.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/mern_stack.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/system/includes/starter_templates/react_vite_shadcdn.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/user_tasks/cli/implement_plan.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompt_templates/user_tasks/cli/init_agents.md.j2 +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/prompts.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/agent_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/base_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/browser_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/build_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/edit_preview.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/glob_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/list_directory_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/memory_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/read_file_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/read_image_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/base.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/duckduckgo.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/errors.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/firecrawl.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/models.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/searxng.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_backends/tavily.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/search_codebase_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/streaming_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/terminal_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/think_hard_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/web_fetch_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/web_search_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/tool_backend/workflow_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/agent/utils/commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/_jwt.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/chatgpt_oauth.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/constants.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/auth/tokens.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/clipboard_image.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/connection.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/diagnostics.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/file_index.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/goal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/main.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/mentions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/plan_artifacts.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/session_store.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/settings.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/skills.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/theme.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/agent_runtime.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/app_base.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/changes_screen.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/constants.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/prompt_flows.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/session_diff.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/settings_panel.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/state.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/status_dashboard.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/styles.tcss +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/sub_agent_screen.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/terminal_display.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/tui/transcript.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/cli/updater.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/events.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/backends.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/dispatcher.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/events.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/matcher.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/hooks/outcome.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/client.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/exceptions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/instrumented_client.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/models.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/anthropic.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/base.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/chatgpt_oauth.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/google.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/models.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/openai_responses.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/providers/responses_common.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/ratelimit.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/accessors.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/anthropic.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/dashscope.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/deepseek.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/fireworks.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/google.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/kimi_coding.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/moonshot.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/ollama_cloud.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/openai.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/openai_chatgpt.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/together.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/catalog/zai.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/thinking.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/specs/types.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/timeouts.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/llm/tool_execution_ids.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/local_state.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/oauth.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/service.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/state.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/tools.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/mcp/transport.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/models/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/models/sandbox_terminal_state.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/permissions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/runtime.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/README.md +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/async_filesystem.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/base.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/browser.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/event_loop.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/filesystem.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/local.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/serializer.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/terminal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/sandbox/utils.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/base.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/browser.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/file_system.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/html.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/client.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/detector.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/diagnostics.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/edits.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/manager.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/registry.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/lsp/registry.yaml +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/terminal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/services/terminal_buffer.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/core.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/definitions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/tools/registry.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/utils/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/kolega_code/utils/images.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/run_tests.sh +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/bench_hotpaths.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/check-dev-hooks.sh +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/install-kolega-code.sh +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/scripts/setup-dev.sh +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/compaction_helpers.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/conftest.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/_token_counting_utils.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_anthropic_local_token_counting_incremental.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_anthropic_token_counting.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_billing_openai_cache.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_live.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_auth_config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_conversion.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_provider.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_provider_generate.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_chatgpt_oauth_streaming.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_client.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_client_live.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_client_runtime.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_dashscope_mapping.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_error_boundary.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_exceptions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_google_thought_signature.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_google_tool_signature_live.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_instrumented_client.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_instrumented_client_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_instrumented_client_stream.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_langfuse_normalization.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_live_providers.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_message_conversion.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_cached_tokens.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_cached_tokens_stream.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_message_conversion.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_responses_provider.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_stream_accumulation.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_token_counting.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_openai_token_counting_incremental.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_provider_usage_mapping.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_streaming_timeouts.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_thinking_effort.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/llm/test_tool_execution_ids.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/orchestration/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/orchestration/test_orchestration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_console_logs.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_content.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_browser_parity.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_file_system.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_file_system_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_file_system_path.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_local_file_system.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_sandbox_terminal_input.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_terminal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_terminal_buffer.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/services/test_terminal_state_serializer.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_anthropic_history_validation.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_compaction.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_effective_history.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_history_serialization.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_prompt_context.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_role_overrides.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_runtime.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_tool_call_repair.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_tool_call_repair_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_base_agent_tool_execution.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_coder_attachments.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_coder_prompt_extensions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_persistence.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_subagent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compaction_tui_events.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compress_command.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_compression.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_conversation_compaction.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_duplicate_tool_results.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_empty_message_handling.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_event_emitter.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_general_agent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_gigacode_gating.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_goal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_goal_evaluate.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_history_adapter_thinking.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_history_image_blocks.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_hooks_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_html.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_image_compat.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_parallel_tool_calls.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_permissions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_planning_agent.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompt_dump.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompt_overrides.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompt_provider.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_prompts.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_read_image_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_builtin_dispatch.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_extensions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_initialization.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_collection_memory.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tool_registry.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/test_tools.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_agent_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_base_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_browser_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_build_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_edit_preview.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_edit_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_glob_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_glob_tool_sandbox_parity.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_list_directory_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_lsp_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_read_file_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_search_codebase_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_terminal_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming_content.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming_errors.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_think_hard_streaming_updates.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_web_fetch_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_web_search_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/agent/tool_backend/test_workflow_tool.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/auth/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/auth/test_chatgpt_oauth.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/auth/test_tokens.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/_app_test_utils.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_agent_wiring.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_bootstrap_settings.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_changes_inspector.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_compaction_restore.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_composer_commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_conversation_rendering.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_diagnostics.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_focus_behavior.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_goal_command.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_lsp_settings_status.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_mention_dropdown.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_misc_commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_model_effort_commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_model_switch_vision.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_modes_planning.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_navigation_commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_permission_prompts.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_persistence_history.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_plan_lifecycle.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_planning_questions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_planning_restore.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_entries.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_errors.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_scroll.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_selection.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_status.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_streaming.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_terminal_logs.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_rendering_tools.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_session_diff_async.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_skill_commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_slash_dropdown.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_status_modes.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_app_sub_agents_workflows.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_ask_goal.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_cli_config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_clipboard_image.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_connection.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_diagnostics.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_file_index.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_main.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_mcp_cli.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_mcp_settings_formatting.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_mentions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_plan_artifacts.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_provider_registry.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_session_diff.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_session_store.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_settings.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_skills.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_slash_commands.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_sub_agent_stream_accumulation.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_terminal_display.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_themes.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_transcript_streaming_render.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_tui_stylesheet.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/cli/test_updater.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/conftest.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/hooks/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/hooks/test_hooks.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/mcp/test_config_state_tools.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/_fake_server.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/conftest.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_client.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_detector.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_diagnostics.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_edits.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_lsp_edit_tool_integration.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_manager.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_project_config.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_registry.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/services/lsp/test_trust.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/test_agent_config_serialization.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/test_mcp_permissions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/test_mcp_transport.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/tools/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/tools/test_definitions.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/utils/__init__.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/utils/test_images.py +0 -0
- {kolega_code-0.15.0 → kolega_code-0.16.0}/tests/utils/test_images_ascii.py +0 -0
|
@@ -6,6 +6,35 @@ This project uses GitHub Releases for detailed generated release notes. This fil
|
|
|
6
6
|
|
|
7
7
|
## Unreleased
|
|
8
8
|
|
|
9
|
+
## 0.16.0 - 2026-07-09
|
|
10
|
+
|
|
11
|
+
### Added
|
|
12
|
+
|
|
13
|
+
- Added support for xAI Grok 4.5 (`grok-4.5`): 500K-token context, vision input,
|
|
14
|
+
and `low`/`medium`/`high` reasoning effort. Selectable in the Settings UI,
|
|
15
|
+
`/model` picker, CLI flags, and env vars; now the default `xai` model.
|
|
16
|
+
- Send a stable `x-grok-conv-id` header on xAI Chat Completions requests so
|
|
17
|
+
multi-turn agent loops pin to a cache-warm server (xAI prompt-caching guidance).
|
|
18
|
+
- Added session-scoped workspace snapshots for agent file mutations: `snapshot`
|
|
19
|
+
(list/show/create/restore, including `snapshot_id='latest'` undo) and `resolve`
|
|
20
|
+
for applying or discarding pending `lsp_edit` preview actions. Restore refuses
|
|
21
|
+
on post-snapshot drift unless `force=true`.
|
|
22
|
+
- Improved TUI usability inside tmux/screen when Shift-modified keys never reach
|
|
23
|
+
the app: `/attach` with no path pastes an image from the system clipboard,
|
|
24
|
+
`Alt+V` is a portable image-paste binding alongside `Ctrl+Shift+V`, startup
|
|
25
|
+
help highlights `Ctrl+J` / `/plan` / `/build` fallbacks, and a one-time
|
|
26
|
+
startup hint appears under tmux. Documented optional tmux extended-keys config
|
|
27
|
+
under Troubleshooting.
|
|
28
|
+
|
|
29
|
+
### Fixed
|
|
30
|
+
|
|
31
|
+
- Prevented a TUI crash when pasting long multi-line text into the composer
|
|
32
|
+
(`OSError: File name too long` from treating paste content as a path).
|
|
33
|
+
- Stopped advertising host lifecycle `initialize` as a model-callable tool while
|
|
34
|
+
keeping it available for CLI/TUI startup (LSP setup).
|
|
35
|
+
- Bumped `lxml-html-clean` to 0.4.5 (and transitive `lxml` to 6.1.1) to clear
|
|
36
|
+
GHSA-4jhm-jv67-739f from the dependency audit.
|
|
37
|
+
|
|
9
38
|
## 0.15.0 - 2026-07-07
|
|
10
39
|
|
|
11
40
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: kolega-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.16.0
|
|
4
4
|
Summary: Multi-agent coding in the terminal
|
|
5
5
|
Project-URL: Homepage, https://kolega-ai.github.io/kolega-code/
|
|
6
6
|
Project-URL: Documentation, https://kolega-ai.github.io/kolega-code/
|
|
@@ -234,7 +234,7 @@ Requires-Dist: google-genai==2.0.1
|
|
|
234
234
|
Requires-Dist: httpx==0.28.1
|
|
235
235
|
Requires-Dist: jinja2==3.1.6
|
|
236
236
|
Requires-Dist: langfuse==3.14.5
|
|
237
|
-
Requires-Dist: lxml-html-clean==0.4.
|
|
237
|
+
Requires-Dist: lxml-html-clean==0.4.5
|
|
238
238
|
Requires-Dist: mcp>=1.21.2
|
|
239
239
|
Requires-Dist: nest-asyncio==1.6.0
|
|
240
240
|
Requires-Dist: openai==1.109.1
|
|
@@ -1 +1 @@
|
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 79.
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="114" height="20" role="img" aria-label="coverage: 79.93%"><title>coverage: 79.93%</title><filter id="blur"><feGaussianBlur stdDeviation="16"/></filter><linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="r"><rect width="114" height="20" rx="3"/></clipPath><g clip-path="url(#r)"><rect width="61" height="20" fill="#555"/><rect x="61" width="53" height="20" fill="#67ac09"/><rect width="114" height="20" fill="url(#s)"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="110"><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="315" y="150" fill-opacity=".8" filter="url(#blur)" textLength="510">coverage</text><text x="315" y="150" fill-opacity=".3" textLength="510">coverage</text></g><text x="315" y="140" textLength="510">coverage</text></g><g transform="scale(.1)"><g aria-hidden="true" fill="#010101"><text x="865" y="150" fill-opacity=".8" filter="url(#blur)" textLength="430">79.93%</text><text x="865" y="150" fill-opacity=".3" textLength="430">79.93%</text></g><text x="865" y="140" textLength="430">79.93%</text></g></g></svg>
|
|
@@ -184,6 +184,8 @@ models in the TUI.
|
|
|
184
184
|
| Ollama Cloud `gpt-oss:*` | `low`, `medium`, `high` | `medium` |
|
|
185
185
|
| Google `gemini-2.5-pro` | `auto`, `low`, `medium`, `high` | `medium` |
|
|
186
186
|
| OpenAI reasoning models | `low`, `medium`, `high` | `medium` |
|
|
187
|
+
| xAI `grok-4.5` | `low`, `medium`, `high` | `medium` |
|
|
188
|
+
| xAI `grok-4.3` | `none`, `low`, `medium`, `high` | `low` |
|
|
187
189
|
|
|
188
190
|
## Check what's active
|
|
189
191
|
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Terminal & tmux shortcuts
|
|
3
|
+
description: Why Shift chords fail in tmux/screen and the portable fallbacks Kolega Code supports.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Kolega Code’s TUI uses some Shift-modified shortcuts (`Shift+Enter`, `Shift+Tab`,
|
|
7
|
+
`Ctrl+Shift+V`). In a modern terminal with the [Kitty keyboard protocol](https://sw.kovidgoyal.net/kitty/keyboard-protocol/),
|
|
8
|
+
those chords reach the app. Inside **tmux** or **GNU screen**, the multiplexer
|
|
9
|
+
often sits between the terminal and the app and either drops modifiers or
|
|
10
|
+
never forwards the extended key sequences — so Shift chords look like plain
|
|
11
|
+
keys, or never arrive at all.
|
|
12
|
+
|
|
13
|
+
Kolega Code cannot invent modifier information the terminal never sends. Instead
|
|
14
|
+
it provides **portable fallbacks** that work without Shift, plus optional tmux
|
|
15
|
+
config if you want the original chords restored.
|
|
16
|
+
|
|
17
|
+
## Portable shortcuts
|
|
18
|
+
|
|
19
|
+
| Action | Preferred (capable terminals) | Portable fallback |
|
|
20
|
+
| --- | --- | --- |
|
|
21
|
+
| Send prompt | `Enter` | — |
|
|
22
|
+
| Insert newline | `Shift+Enter` | `Ctrl+J` or `Ctrl+Enter` |
|
|
23
|
+
| Toggle Plan ⇄ Build | `Shift+Tab` | `/plan` or `/build` |
|
|
24
|
+
| Paste image from system clipboard | `Ctrl+Shift+V` | `Alt+V` (Option+V on macOS when the terminal treats Option as Meta) or `/attach` with no path |
|
|
25
|
+
| Attach image from a file | — | `/attach <path>` or `@image.png` |
|
|
26
|
+
|
|
27
|
+
On session start inside tmux/screen, the startup block prints a short reminder
|
|
28
|
+
of these fallbacks.
|
|
29
|
+
|
|
30
|
+
### Image paste notes
|
|
31
|
+
|
|
32
|
+
- `/attach` with **no path** reads an image from the **system** clipboard (same
|
|
33
|
+
path as `Ctrl+Shift+V` / `Alt+V`). This is the most reliable option under
|
|
34
|
+
plain tmux.
|
|
35
|
+
- Clipboard image reading uses host tools independent of tmux:
|
|
36
|
+
- **macOS:** `osascript` (built-in), or `pngpaste` if installed
|
|
37
|
+
- **Linux:** `xclip` or `wl-paste`
|
|
38
|
+
- **Windows / WSL:** PowerShell clipboard APIs
|
|
39
|
+
- If Option+V types a special character (e.g. `√`) instead of pasting an image,
|
|
40
|
+
your terminal is not sending Alt as a modifier. Prefer `/attach`, or enable
|
|
41
|
+
“Option as Meta” / “Left Option key acts as +Esc” in the terminal settings.
|
|
42
|
+
|
|
43
|
+
## Optional: restore Shift+Enter in tmux
|
|
44
|
+
|
|
45
|
+
With **tmux 3.2+** and an outer terminal that supports extended keys, add to
|
|
46
|
+
`~/.tmux.conf`:
|
|
47
|
+
|
|
48
|
+
```tmux
|
|
49
|
+
set -g extended-keys always
|
|
50
|
+
set -g extended-keys-format csi-u
|
|
51
|
+
set -as terminal-features 'xterm*:extkeys'
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Then reload (`tmux source-file ~/.tmux.conf`) or restart tmux.
|
|
55
|
+
|
|
56
|
+
Also make sure `default-terminal` / `terminal-overrides` match the outer
|
|
57
|
+
terminal’s `$TERM` family (`xterm-256color`, `xterm-ghostty`, etc.) so the
|
|
58
|
+
`extkeys` feature actually applies.
|
|
59
|
+
|
|
60
|
+
After that, `Shift+Enter` and similar chords often work again inside Kolega Code.
|
|
61
|
+
If they still do not, keep using the portable fallbacks above.
|
|
62
|
+
|
|
63
|
+
## Related
|
|
64
|
+
|
|
65
|
+
- [Chat Composer](../../tui/composer/) — full composer key reference
|
|
66
|
+
- [Interface Tour](../../tui/interface/) — key bindings at a glance
|
|
67
|
+
- [Slash Commands](../../tui/slash-commands/) — `/attach`, `/plan`, `/build`
|
|
@@ -13,17 +13,24 @@ multi-line input, and drives the option lists the agent shows you.
|
|
|
13
13
|
| --- | --- |
|
|
14
14
|
| `Enter` | Send the prompt |
|
|
15
15
|
| `Shift+Enter` | Insert a newline (keep typing) |
|
|
16
|
-
| `Ctrl+J` | Insert a newline (
|
|
16
|
+
| `Ctrl+J` / `Ctrl+Enter` | Insert a newline (portable alternatives; prefer these inside tmux) |
|
|
17
17
|
| `Ctrl+L` | Select all composer text |
|
|
18
18
|
| `Cmd+A` / `⌘A` | Select all composer text on macOS, when forwarded by the terminal |
|
|
19
19
|
| `Ctrl+A` | Move to the start of the current line (intentionally not select-all) |
|
|
20
20
|
| `Ctrl+U` | Delete backward to the start of the line; at line start, delete the previous line |
|
|
21
|
+
| `Ctrl+Shift+V` | Paste an image from the system clipboard |
|
|
22
|
+
| `Alt+V` | Paste an image from the system clipboard (portable alternative when Shift chords fail) |
|
|
21
23
|
|
|
22
24
|
`Ctrl+L` is the portable select-all shortcut because `Ctrl+A` is preserved for
|
|
23
25
|
terminal-style line navigation. Some macOS terminal emulators reserve `Cmd+A` for
|
|
24
26
|
terminal scrollback selection before the TUI can see it; `Ctrl+L` still works in
|
|
25
27
|
the composer.
|
|
26
28
|
|
|
29
|
+
Inside **tmux** or **screen**, Shift-modified keys often never reach the app.
|
|
30
|
+
Use `Ctrl+J` for newlines and `Alt+V` or `/attach` for images. See
|
|
31
|
+
[Terminal & tmux shortcuts](../../troubleshooting/terminal-tmux/) for optional
|
|
32
|
+
tmux config to restore Shift+Enter.
|
|
33
|
+
|
|
27
34
|
## Queuing follow-up prompts
|
|
28
35
|
|
|
29
36
|
You can keep typing while the agent is still generating. Pressing `Enter` during
|
|
@@ -45,6 +52,19 @@ If you cancel the active turn with `Ctrl+C` or `Escape`, queued follow-ups are
|
|
|
45
52
|
restored into the composer instead of being silently sent. To discard pending
|
|
46
53
|
follow-ups without stopping the active turn, run [`/queue-clear`](../slash-commands/).
|
|
47
54
|
|
|
55
|
+
## Attaching images
|
|
56
|
+
|
|
57
|
+
You can attach images for vision-capable models in several ways:
|
|
58
|
+
|
|
59
|
+
| Method | How |
|
|
60
|
+
| --- | --- |
|
|
61
|
+
| System clipboard | `Ctrl+Shift+V` or `Alt+V`, or run `/attach` with no path |
|
|
62
|
+
| File path | `/attach path/to/image.png` |
|
|
63
|
+
| File mention | `@screenshot.png` (supported image extensions only) |
|
|
64
|
+
|
|
65
|
+
Use `/detach` to clear pending attachments before sending. On a non-vision
|
|
66
|
+
model, Kolega Code warns and blocks the send until you detach or switch models.
|
|
67
|
+
|
|
48
68
|
## File mentions with `@`
|
|
49
69
|
|
|
50
70
|
Type `@` to reference a file. A fuzzy-searchable dropdown of project files appears
|
|
@@ -82,14 +82,16 @@ the turn keeps running while you look around.
|
|
|
82
82
|
|
|
83
83
|
| Keys | Action |
|
|
84
84
|
| --- | --- |
|
|
85
|
-
| `Shift+Tab` | Toggle Build ⇄ Plan mode |
|
|
85
|
+
| `Shift+Tab` | Toggle Build ⇄ Plan mode (`/plan` / `/build` if Shift is unavailable) |
|
|
86
86
|
| `Ctrl+P` | Toggle shell/edit permissions between Ask ⇄ Auto |
|
|
87
87
|
| `Ctrl+O` | Show or hide the side panel |
|
|
88
88
|
| `Ctrl+G` | Open the sub-agent inspector |
|
|
89
89
|
| `Enter` | Send the prompt |
|
|
90
90
|
| `Shift+Enter` / `Ctrl+J` | Insert a newline |
|
|
91
|
+
| `Ctrl+Shift+V` / `Alt+V` | Paste an image from the system clipboard (`/attach` also works) |
|
|
91
92
|
| `Ctrl+C` / `Escape` | Cancel the current generation |
|
|
92
93
|
| `Ctrl+Q` | Save the session and quit |
|
|
93
94
|
|
|
94
95
|
A complete composer-and-completion key reference is in
|
|
95
|
-
[Chat Composer](../composer/).
|
|
96
|
+
[Chat Composer](../composer/). If Shift chords fail inside tmux, see
|
|
97
|
+
[Terminal & tmux shortcuts](../../troubleshooting/terminal-tmux/).
|
|
@@ -34,6 +34,8 @@ These control the app and your session.
|
|
|
34
34
|
| --- | --- |
|
|
35
35
|
| `/skills` | List available Agent Skills |
|
|
36
36
|
| `/init` | Create or update `AGENTS.md` for this repository |
|
|
37
|
+
| `/attach` | Attach an image: clipboard if no path, or `/attach <path>` for a file |
|
|
38
|
+
| `/detach` | Remove pending image attachments |
|
|
37
39
|
| `/plan` | Switch to [Plan mode](../modes/) |
|
|
38
40
|
| `/build` | Switch to [Build mode](../modes/) |
|
|
39
41
|
| `/sidebar` | Show or hide the side panel |
|
|
@@ -9,6 +9,7 @@ from .edit_preview import build_diff_preview, build_head_preview
|
|
|
9
9
|
|
|
10
10
|
if TYPE_CHECKING:
|
|
11
11
|
from kolega_code.services.lsp import LspManager
|
|
12
|
+
from kolega_code.services.snapshots import SnapshotService
|
|
12
13
|
|
|
13
14
|
|
|
14
15
|
_BLOCK_PATTERN = re.compile(r"<<<<<<< SEARCH\r?\n(.*?)\r?\n=======\r?\n(.*?)\r?\n>>>>>>> REPLACE", re.DOTALL)
|
|
@@ -43,9 +44,16 @@ class ResolvedReplacement:
|
|
|
43
44
|
|
|
44
45
|
|
|
45
46
|
class EditTool(BaseTool):
|
|
46
|
-
def __init__(
|
|
47
|
+
def __init__(
|
|
48
|
+
self,
|
|
49
|
+
*args,
|
|
50
|
+
lsp_manager: Optional["LspManager"] = None,
|
|
51
|
+
snapshot_service: Optional["SnapshotService"] = None,
|
|
52
|
+
**kwargs,
|
|
53
|
+
) -> None:
|
|
47
54
|
super().__init__(*args, **kwargs)
|
|
48
55
|
self._lsp_manager = lsp_manager
|
|
56
|
+
self._snapshot_service = snapshot_service
|
|
49
57
|
|
|
50
58
|
async def edit(self, path: str, block: str) -> str:
|
|
51
59
|
"""
|
|
@@ -115,8 +123,6 @@ class EditTool(BaseTool):
|
|
|
115
123
|
old_content = None
|
|
116
124
|
|
|
117
125
|
parent_dir = self.filesystem.get_parent(path)
|
|
118
|
-
if parent_dir and parent_dir != "." and not self.filesystem.exists(parent_dir):
|
|
119
|
-
self.filesystem.create_directory(parent_dir)
|
|
120
126
|
|
|
121
127
|
# Preserve the file's dominant line ending on overwrite; new files
|
|
122
128
|
# keep the line endings the caller provided (typically LF).
|
|
@@ -124,7 +130,17 @@ class EditTool(BaseTool):
|
|
|
124
130
|
line_ending = self._detect_dominant_line_ending(path, old_content)
|
|
125
131
|
content = self._normalize_line_endings(content, line_ending)
|
|
126
132
|
|
|
127
|
-
|
|
133
|
+
def _write() -> None:
|
|
134
|
+
if parent_dir and parent_dir != "." and not self.filesystem.exists(parent_dir):
|
|
135
|
+
self.filesystem.create_directory(parent_dir)
|
|
136
|
+
self.filesystem.write_text(path, content)
|
|
137
|
+
|
|
138
|
+
self._record_snapshot_mutation(
|
|
139
|
+
tool_name="write",
|
|
140
|
+
reason=f"write {path}",
|
|
141
|
+
paths=self._snapshot_paths_for_write(path),
|
|
142
|
+
mutate=_write,
|
|
143
|
+
)
|
|
128
144
|
|
|
129
145
|
preview = (
|
|
130
146
|
build_diff_preview(old_content, content, path)
|
|
@@ -180,7 +196,12 @@ class EditTool(BaseTool):
|
|
|
180
196
|
blocked_msg = self._enforce_vibe_edit_policy(path)
|
|
181
197
|
if blocked_msg:
|
|
182
198
|
return blocked_msg
|
|
183
|
-
self.
|
|
199
|
+
self._record_snapshot_mutation(
|
|
200
|
+
tool_name=tool_name,
|
|
201
|
+
reason=f"{tool_name} {path}",
|
|
202
|
+
paths=[path],
|
|
203
|
+
mutate=lambda: self.filesystem.write_text(path, normalized_updated),
|
|
204
|
+
)
|
|
184
205
|
|
|
185
206
|
await self.send_edit_preview(
|
|
186
207
|
build_diff_preview(original_content, normalized_updated, path),
|
|
@@ -223,6 +244,33 @@ class EditTool(BaseTool):
|
|
|
223
244
|
)
|
|
224
245
|
return parsed_blocks
|
|
225
246
|
|
|
247
|
+
def _record_snapshot_mutation(
|
|
248
|
+
self,
|
|
249
|
+
*,
|
|
250
|
+
tool_name: str,
|
|
251
|
+
reason: str,
|
|
252
|
+
paths: list[str],
|
|
253
|
+
mutate: Callable[[], None],
|
|
254
|
+
) -> None:
|
|
255
|
+
if self._snapshot_service is None or not self._snapshot_service.can_snapshot_paths(paths):
|
|
256
|
+
mutate()
|
|
257
|
+
return
|
|
258
|
+
self._snapshot_service.record_mutation(
|
|
259
|
+
tool_name=tool_name,
|
|
260
|
+
tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
|
|
261
|
+
reason=reason,
|
|
262
|
+
paths=paths,
|
|
263
|
+
mutate=mutate,
|
|
264
|
+
)
|
|
265
|
+
|
|
266
|
+
def _snapshot_paths_for_write(self, path: str) -> list[str]:
|
|
267
|
+
paths = [path]
|
|
268
|
+
parent = self.filesystem.get_parent(path)
|
|
269
|
+
while parent and parent != "." and not self.filesystem.exists(parent):
|
|
270
|
+
paths.append(parent)
|
|
271
|
+
parent = self.filesystem.get_parent(parent)
|
|
272
|
+
return paths
|
|
273
|
+
|
|
226
274
|
def _resolve_replacement(self, content: str, block: SearchReplaceBlock) -> ResolvedReplacement:
|
|
227
275
|
passes: list[tuple[str, Callable[[str, str], list[tuple[int, int]]]]] = [
|
|
228
276
|
("exact", self._exact_spans),
|
|
@@ -5,7 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
import hashlib
|
|
6
6
|
import json
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import Any, Optional, cast
|
|
8
|
+
from typing import TYPE_CHECKING, Any, Optional, cast
|
|
9
9
|
from urllib.parse import unquote, urlparse
|
|
10
10
|
|
|
11
11
|
from .base_tool import BaseTool
|
|
@@ -13,6 +13,9 @@ from .edit_preview import build_diff_preview
|
|
|
13
13
|
from kolega_code.services.lsp import LspManager, format_diagnostics, format_no_diagnostics
|
|
14
14
|
from kolega_code.services.lsp.edits import WorkspaceEditApplier, WorkspaceEditError, WorkspaceEditResult
|
|
15
15
|
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from kolega_code.services.snapshots import SnapshotService
|
|
18
|
+
|
|
16
19
|
|
|
17
20
|
class LspTool(BaseTool):
|
|
18
21
|
"""Exposes read-only LSP operations as an agent-callable tool."""
|
|
@@ -563,9 +566,16 @@ class LspEditTool(BaseTool):
|
|
|
563
566
|
|
|
564
567
|
_ALL_OPS = {"rename", "rename_file", "format_document", "format_range", "apply_code_action"}
|
|
565
568
|
|
|
566
|
-
def __init__(
|
|
569
|
+
def __init__(
|
|
570
|
+
self,
|
|
571
|
+
*args,
|
|
572
|
+
lsp_manager: Optional[LspManager] = None,
|
|
573
|
+
snapshot_service: Optional["SnapshotService"] = None,
|
|
574
|
+
**kwargs,
|
|
575
|
+
) -> None:
|
|
567
576
|
super().__init__(*args, **kwargs)
|
|
568
577
|
self._lsp_manager = lsp_manager
|
|
578
|
+
self._snapshot_service = snapshot_service
|
|
569
579
|
|
|
570
580
|
async def lsp_edit(
|
|
571
581
|
self,
|
|
@@ -842,7 +852,17 @@ class LspEditTool(BaseTool):
|
|
|
842
852
|
blocked = self._first_blocked_path(preview.touched_paths)
|
|
843
853
|
if blocked:
|
|
844
854
|
return {"applied": False, "failureReason": blocked}
|
|
845
|
-
|
|
855
|
+
if self._snapshot_service is not None:
|
|
856
|
+
mutation = self._snapshot_service.record_mutation(
|
|
857
|
+
tool_name="lsp_edit",
|
|
858
|
+
tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
|
|
859
|
+
reason="lsp apply_code_action workspace/applyEdit",
|
|
860
|
+
paths=preview.touched_paths,
|
|
861
|
+
mutate=lambda: applier.apply(workspace_edit),
|
|
862
|
+
)
|
|
863
|
+
applied = mutation.result
|
|
864
|
+
else:
|
|
865
|
+
applied = applier.apply(workspace_edit)
|
|
846
866
|
server_results.append(applied)
|
|
847
867
|
return {"applied": True}
|
|
848
868
|
except WorkspaceEditError as exc:
|
|
@@ -896,9 +916,33 @@ class LspEditTool(BaseTool):
|
|
|
896
916
|
if should_apply and blocked:
|
|
897
917
|
return blocked
|
|
898
918
|
|
|
899
|
-
|
|
919
|
+
if should_apply:
|
|
920
|
+
if self._snapshot_service is not None:
|
|
921
|
+
mutation = self._snapshot_service.record_mutation(
|
|
922
|
+
tool_name="lsp_edit",
|
|
923
|
+
tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
|
|
924
|
+
reason=f"lsp_edit {operation}",
|
|
925
|
+
paths=preview.touched_paths,
|
|
926
|
+
mutate=lambda: applier.apply(edit),
|
|
927
|
+
)
|
|
928
|
+
result = mutation.result
|
|
929
|
+
else:
|
|
930
|
+
result = applier.apply(edit)
|
|
931
|
+
else:
|
|
932
|
+
result = preview
|
|
900
933
|
await self._send_previews(result, operation)
|
|
901
934
|
lines = [self._format_workspace_edit_result(operation, result)]
|
|
935
|
+
if not should_apply and self._snapshot_service is not None:
|
|
936
|
+
pending = self._snapshot_service.create_pending_workspace_edit(
|
|
937
|
+
tool_name="lsp_edit",
|
|
938
|
+
tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
|
|
939
|
+
operation=operation,
|
|
940
|
+
workspace_edit=edit,
|
|
941
|
+
touched_paths=preview.touched_paths,
|
|
942
|
+
summaries=preview.summaries,
|
|
943
|
+
previews=self._preview_payloads(preview),
|
|
944
|
+
)
|
|
945
|
+
lines.append(f'Pending action: `{pending.action_id}`. Use resolve(decision="apply") to apply it.')
|
|
902
946
|
if should_apply and include_diagnostics:
|
|
903
947
|
diagnostics = await self._diagnostics_for_paths(result.touched_paths)
|
|
904
948
|
if diagnostics:
|
|
@@ -909,15 +953,23 @@ class LspEditTool(BaseTool):
|
|
|
909
953
|
return WorkspaceEditApplier(self.project_path, self.filesystem).preview(edit)
|
|
910
954
|
|
|
911
955
|
async def _send_previews(self, result: WorkspaceEditResult, operation: str) -> None:
|
|
912
|
-
for
|
|
913
|
-
if change.old_text == change.new_text:
|
|
914
|
-
continue
|
|
956
|
+
for preview in self._preview_payloads(result):
|
|
915
957
|
await self.send_edit_preview(
|
|
916
|
-
|
|
958
|
+
preview,
|
|
917
959
|
tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
|
|
918
960
|
tool_name="lsp_edit",
|
|
919
961
|
)
|
|
920
962
|
|
|
963
|
+
def _preview_payloads(self, result: WorkspaceEditResult) -> list[dict[str, Any]]:
|
|
964
|
+
previews: list[dict[str, Any]] = []
|
|
965
|
+
for change in result.text_changes:
|
|
966
|
+
if change.old_text == change.new_text:
|
|
967
|
+
continue
|
|
968
|
+
preview = build_diff_preview(change.old_text, change.new_text, change.path)
|
|
969
|
+
if preview:
|
|
970
|
+
previews.append(preview)
|
|
971
|
+
return previews
|
|
972
|
+
|
|
921
973
|
def _format_workspace_edit_result(self, operation: str, result: WorkspaceEditResult) -> str:
|
|
922
974
|
label = "Applied" if result.applied else "Preview"
|
|
923
975
|
lines = [f"{label} LSP edit `{operation}`."]
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
4
|
+
|
|
5
|
+
from kolega_code.services.lsp.edits import WorkspaceEditApplier
|
|
6
|
+
from kolega_code.services.snapshots import PendingAction, SnapshotError, SnapshotRecord, SnapshotService
|
|
7
|
+
from kolega_code.tools import ToolError
|
|
8
|
+
|
|
9
|
+
from .base_tool import BaseTool
|
|
10
|
+
from .edit_preview import build_diff_preview
|
|
11
|
+
|
|
12
|
+
if TYPE_CHECKING:
|
|
13
|
+
from kolega_code.services.lsp.edits import WorkspaceEditResult
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SnapshotTool(BaseTool):
|
|
17
|
+
def __init__(self, *args, snapshot_service: SnapshotService, **kwargs) -> None:
|
|
18
|
+
super().__init__(*args, **kwargs)
|
|
19
|
+
self.snapshot_service = snapshot_service
|
|
20
|
+
|
|
21
|
+
async def snapshot(
|
|
22
|
+
self,
|
|
23
|
+
action: str = "list",
|
|
24
|
+
snapshot_id: str = "",
|
|
25
|
+
paths: Optional[list[str]] = None,
|
|
26
|
+
force: bool = False,
|
|
27
|
+
limit: int = 20,
|
|
28
|
+
) -> str:
|
|
29
|
+
"""Manage file snapshots for undo, inspection, and manual checkpoints.
|
|
30
|
+
|
|
31
|
+
Actions:
|
|
32
|
+
- list: show recent snapshots for this session.
|
|
33
|
+
- show: show one snapshot's metadata and touched paths.
|
|
34
|
+
- create: create a manual checkpoint for the provided paths.
|
|
35
|
+
- restore: restore a snapshot's before-state. Use snapshot_id="latest" for undo.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
action: One of list, show, create, or restore.
|
|
39
|
+
snapshot_id: Snapshot id to show or restore. Use latest for the newest snapshot.
|
|
40
|
+
paths: Project-relative paths for create.
|
|
41
|
+
force: Restore even when tracked files changed after the snapshot.
|
|
42
|
+
limit: Maximum number of snapshots to list.
|
|
43
|
+
|
|
44
|
+
Returns:
|
|
45
|
+
Markdown summary of the requested snapshot operation.
|
|
46
|
+
"""
|
|
47
|
+
try:
|
|
48
|
+
normalized_action = action.strip().lower()
|
|
49
|
+
if normalized_action == "list":
|
|
50
|
+
return self._format_snapshot_list(self.snapshot_service.list_snapshots(limit=limit))
|
|
51
|
+
if normalized_action == "show":
|
|
52
|
+
if not snapshot_id:
|
|
53
|
+
raise SnapshotError("snapshot_id is required for action=show.")
|
|
54
|
+
return self._format_snapshot_detail(self.snapshot_service.load_snapshot(snapshot_id))
|
|
55
|
+
if normalized_action == "create":
|
|
56
|
+
record = self.snapshot_service.create_manual_snapshot(
|
|
57
|
+
paths=paths or (),
|
|
58
|
+
reason="manual snapshot",
|
|
59
|
+
tool_call_id=getattr(self.caller, "current_tool_execution_id", None),
|
|
60
|
+
)
|
|
61
|
+
return f"Created manual snapshot `{record.snapshot_id}` for {', '.join(record.touched_paths)}."
|
|
62
|
+
if normalized_action == "restore":
|
|
63
|
+
target_id = snapshot_id or "latest"
|
|
64
|
+
result = self.snapshot_service.restore_snapshot(target_id, force=force)
|
|
65
|
+
forced = " with force=true" if result.forced else ""
|
|
66
|
+
return (
|
|
67
|
+
f"Restored snapshot `{result.snapshot_id}`{forced}.\n\n"
|
|
68
|
+
f"Touched paths: {', '.join(result.restored_paths) or '(none)'}"
|
|
69
|
+
)
|
|
70
|
+
raise SnapshotError("action must be one of: list, show, create, restore.")
|
|
71
|
+
except SnapshotError as exc:
|
|
72
|
+
raise ToolError(str(exc)) from exc
|
|
73
|
+
|
|
74
|
+
async def resolve(self, action_id: str, decision: str, force: bool = False) -> str:
|
|
75
|
+
"""Apply or discard a pending preview action.
|
|
76
|
+
|
|
77
|
+
Pending actions are created by preview-only tools such as lsp_edit(apply=false).
|
|
78
|
+
Applying a pending action checks that the source files still match the preview
|
|
79
|
+
inputs before writing, unless force=true is explicitly provided.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
action_id: Pending action id returned by a preview-only tool.
|
|
83
|
+
decision: apply or discard.
|
|
84
|
+
force: Apply even if source hashes no longer match.
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
Markdown summary of the resolve decision.
|
|
88
|
+
"""
|
|
89
|
+
try:
|
|
90
|
+
action = self.snapshot_service.load_pending_action(action_id)
|
|
91
|
+
normalized_decision = decision.strip().lower()
|
|
92
|
+
if normalized_decision == "discard":
|
|
93
|
+
updated = self.snapshot_service.update_pending_action(action, status="discarded", message="discarded")
|
|
94
|
+
return f"Discarded pending action `{updated.action_id}`."
|
|
95
|
+
if normalized_decision != "apply":
|
|
96
|
+
raise SnapshotError("decision must be apply or discard.")
|
|
97
|
+
if action.status != "pending":
|
|
98
|
+
raise SnapshotError(f"Pending action `{action.action_id}` is already {action.status}.")
|
|
99
|
+
|
|
100
|
+
mismatches = self.snapshot_service.diff_expected_current(action.source)
|
|
101
|
+
if mismatches and not force:
|
|
102
|
+
message = self.snapshot_service._format_mismatch_error(action.action_id, mismatches)
|
|
103
|
+
self.snapshot_service.update_pending_action(action, status="stale", message=message)
|
|
104
|
+
raise SnapshotError(message)
|
|
105
|
+
|
|
106
|
+
applier = WorkspaceEditApplier(self.project_path, self.filesystem)
|
|
107
|
+
preview = applier.preview(action.workspace_edit)
|
|
108
|
+
|
|
109
|
+
def _apply() -> "WorkspaceEditResult":
|
|
110
|
+
return applier.apply(action.workspace_edit)
|
|
111
|
+
|
|
112
|
+
mutation = self.snapshot_service.record_mutation(
|
|
113
|
+
tool_name=action.tool_name or "resolve",
|
|
114
|
+
tool_call_id=getattr(self.caller, "current_tool_execution_id", None) or action.tool_call_id,
|
|
115
|
+
reason=f"resolve {action.action_id} ({action.operation})",
|
|
116
|
+
paths=preview.touched_paths,
|
|
117
|
+
mutate=_apply,
|
|
118
|
+
)
|
|
119
|
+
result = mutation.result
|
|
120
|
+
await self._send_previews(result, action)
|
|
121
|
+
updated = self.snapshot_service.update_pending_action(
|
|
122
|
+
action,
|
|
123
|
+
status="applied",
|
|
124
|
+
snapshot_id=mutation.snapshot.snapshot_id if mutation.snapshot else None,
|
|
125
|
+
message="applied",
|
|
126
|
+
)
|
|
127
|
+
snapshot_line = f"\nSnapshot: `{updated.snapshot_id}`" if updated.snapshot_id else ""
|
|
128
|
+
forced = " with force=true" if force else ""
|
|
129
|
+
return (
|
|
130
|
+
f"Applied pending action `{updated.action_id}`{forced}.\n\n"
|
|
131
|
+
+ self._format_workspace_edit_result(action.operation, result)
|
|
132
|
+
+ snapshot_line
|
|
133
|
+
)
|
|
134
|
+
except SnapshotError as exc:
|
|
135
|
+
raise ToolError(str(exc)) from exc
|
|
136
|
+
|
|
137
|
+
async def _send_previews(self, result: "WorkspaceEditResult", action: PendingAction) -> None:
|
|
138
|
+
for change in result.text_changes:
|
|
139
|
+
if change.old_text == change.new_text:
|
|
140
|
+
continue
|
|
141
|
+
await self.send_edit_preview(
|
|
142
|
+
build_diff_preview(change.old_text, change.new_text, change.path),
|
|
143
|
+
tool_call_id=getattr(self.caller, "current_tool_execution_id", None) or action.tool_call_id,
|
|
144
|
+
tool_name="resolve",
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
@staticmethod
|
|
148
|
+
def _format_snapshot_list(records: list[SnapshotRecord]) -> str:
|
|
149
|
+
if not records:
|
|
150
|
+
return "No snapshots recorded for this session."
|
|
151
|
+
lines = ["# Snapshots", ""]
|
|
152
|
+
for record in records:
|
|
153
|
+
marker = " manual" if record.manual else ""
|
|
154
|
+
lines.append(
|
|
155
|
+
f"- `{record.snapshot_id}`{marker} - {record.tool_name} - "
|
|
156
|
+
f"{record.created_at} - {', '.join(record.touched_paths) or '(none)'}"
|
|
157
|
+
)
|
|
158
|
+
return "\n".join(lines)
|
|
159
|
+
|
|
160
|
+
@staticmethod
|
|
161
|
+
def _format_snapshot_detail(record: SnapshotRecord) -> str:
|
|
162
|
+
lines = [
|
|
163
|
+
f"# Snapshot `{record.snapshot_id}`",
|
|
164
|
+
"",
|
|
165
|
+
f"- Tool: `{record.tool_name}`",
|
|
166
|
+
f"- Tool call: `{record.tool_call_id or '-'}`",
|
|
167
|
+
f"- Created: {record.created_at}",
|
|
168
|
+
f"- Reason: {record.reason or '-'}",
|
|
169
|
+
f"- Manual: {str(record.manual).lower()}",
|
|
170
|
+
"",
|
|
171
|
+
"## Paths",
|
|
172
|
+
]
|
|
173
|
+
for path in record.touched_paths:
|
|
174
|
+
before = record.before.get(path)
|
|
175
|
+
after = record.after.get(path)
|
|
176
|
+
lines.append(f"- `{path}`: {SnapshotTool._state_label(before)} -> {SnapshotTool._state_label(after)}")
|
|
177
|
+
return "\n".join(lines)
|
|
178
|
+
|
|
179
|
+
@staticmethod
|
|
180
|
+
def _format_workspace_edit_result(operation: str, result: Any) -> str:
|
|
181
|
+
lines = [f"Applied LSP edit `{operation}`."]
|
|
182
|
+
for summary in result.summaries:
|
|
183
|
+
lines.append(f"- {summary}")
|
|
184
|
+
return "\n".join(lines)
|
|
185
|
+
|
|
186
|
+
@staticmethod
|
|
187
|
+
def _state_label(state: Any) -> str:
|
|
188
|
+
if state is None:
|
|
189
|
+
return "missing"
|
|
190
|
+
suffix = f":{state.sha256[:12]}" if getattr(state, "sha256", None) else ""
|
|
191
|
+
return f"{state.kind}{suffix}"
|