titan-cli 0.7.0__tar.gz → 0.7.2__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.
- {titan_cli-0.7.0 → titan_cli-0.7.2}/PKG-INFO +1 -1
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/github_client.py +42 -1
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/services/__init__.py +2 -0
- titan_cli-0.7.2/plugins/titan-plugin-github/titan_plugin_github/clients/services/contents_service.py +144 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/services/pr_service.py +1 -1
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/pr_mapper.py +9 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/pull_request.py +7 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/view.py +7 -1
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/thread_resolution_operations.py +51 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/code_review_steps.py +88 -38
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/workflows/review-pr-thread-resolution.yaml +1 -1
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/services/auth_service.py +3 -1
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/services/conversation_service.py +14 -10
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/services/directory_service.py +9 -8
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/services/message_service.py +6 -4
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/slack_client.py +124 -42
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/plugin.py +66 -17
- {titan_cli-0.7.0 → titan_cli-0.7.2}/pyproject.toml +1 -1
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/workflows/workflow_filter_service.py +7 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/LICENSE +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/README.md +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/git_client.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/network/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/network/git_network.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/branch_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/commit_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/diff_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/remote_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/stash_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/status_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/tag_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/clients/services/worktree_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/exceptions.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/messages.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/branch_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/commit_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/status_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/tag_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/worktree_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/network/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/network/branch.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/network/commit.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/network/status.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/network/tag.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/network/worktree.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/view/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/view/branch.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/view/commit.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/view/status.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/view/tag.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/models/view/worktree.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/operations/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/operations/branch_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/operations/commit_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/operations/diff_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/plugin.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/ai_commit_message_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/branch_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/checkout_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/commit_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/create_branch_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/create_worktree_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/diff_summary_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/pull_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/push_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/remove_worktree_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/restore_original_branch_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/save_current_branch_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/status_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/steps/worktree_command_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/workflows/__previews__/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/workflows/__previews__/commit_ai_preview.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-git/titan_plugin_git/workflows/commit-ai.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/agents/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/agents/code_review_agent.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/agents/config_loader.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/agents/issue_generator.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/agents/pr_agent.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/checklists/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/checklists/defaults.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/network/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/network/gh_network.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/network/graphql_network.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/network/graphql_queries.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/protocols.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/services/issue_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/services/release_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/services/review_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/clients/services/team_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/config/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/config/pr_agent.toml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/exceptions.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/managers/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/managers/checklist_manager.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/managers/diff_context_manager.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/managers/prompt_budget_manager.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/managers/review_profile_manager.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/messages.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/diff_models.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/formatting.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/comment_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/issue_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/release_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/review_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/thread_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/issue_comment.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/review_comment.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/review_thread.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/user.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/issue.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/release.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/review.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/user.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/pr_enums.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/review_enums.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/review_models.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/review_profile_models.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/validators.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/ai_response_parsing_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/code_review_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/comment_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/context_resolution_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/findings_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/issue_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/manifest_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/plan_prompt_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/pr_creation_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/pr_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/pr_selection_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/prompt_formatting_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/review_action_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/review_profile_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/review_strategy_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/operations/worktree_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/plugin.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/review_profiles/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/review_profiles/defaults.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/ai_pr_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/create_pr_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/github_prompt_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/issue_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/pr_review_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/preview_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/pull_request_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/release_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/steps/worktree_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/utils.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/widgets/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/widgets/code_block.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/widgets/comment_thread.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/widgets/comment_utils.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/widgets/comment_view.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/widgets/reply_comment.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/workflows/__previews__/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/workflows/__previews__/create_pr_ai_preview.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/workflows/create-issue-ai.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/workflows/create-pr-ai.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/workflows/respond-pr-comments.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/workflows/review-pr.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/agents/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/agents/config_loader.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/agents/jira_agent.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/agents/prompts.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/agents/response_parser.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/agents/token_tracker.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/agents/validators.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/jira_client.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/network/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/network/jira_network.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/comment_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/issue_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/link_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/metadata_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/project_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/transition_service.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/config/jira_agent.toml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/config/templates/generic_issue.md.j2 +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/config/templates/issue_analysis.md.j2 +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/constants/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/constants/defaults.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/constants/messages.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/constants/templates.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/constants.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/exceptions.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/formatters/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/formatters/markdown_formatter.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/messages.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/enums.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/formatting.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/comment_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/issue_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/issue_type_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/priority_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/project_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/status_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/transition_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/user_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/version_mapper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/comment.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/issue.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/issue_type.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/priority.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/project.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/status.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/transition.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/user.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/version.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/models/view.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/operations/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/operations/issue_formatting_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/operations/issue_management_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/operations/issue_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/operations/jql_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/operations/plan_prompt_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/plugin.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/ai_analyze_issue_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/ai_enhance_issue_description_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/build_jira_task_context_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/confirm_and_assign_issue_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/confirm_assignee_for_new_issue_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/create_generic_issue_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/get_comments_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/get_issue_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/issue_management_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/list_versions_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/prompt_issue_description_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/prompt_select_issue_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/review_issue_description_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/search_jql_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/search_saved_query_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/select_issue_priority_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/select_issue_type_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/steps/select_jira_issue_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/utils/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/utils/input_validation.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/utils/issue_sorter.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/utils/saved_queries.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/utils.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/workflows/analyze-jira-issues.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/workflows/create-generic-issue.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-jira/titan_plugin_jira/workflows/plan-jira-issue.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/sdk.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/services/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/clients/services/identity_resolver.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/config/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/exceptions.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/formatting.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/models.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/oauth.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/operations/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/operations/identity_resolution_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/operations/message_summary_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/operations/target_resolution_operations.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/screens/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/screens/slack_config_screen.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/steps/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/steps/discovery_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/steps/message_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/steps/summary_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/steps/target_steps.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/workflows/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/workflows/post-message.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-slack/titan_plugin_slack/workflows/summarize-slack-target.yaml +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/__main__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/agents/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/agents/base.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/client.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/constants.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/dependencies.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/exceptions.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/litellm_client.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/llm_tools.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/models.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/oauth_helper.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/providers/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/providers/anthropic.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/providers/base.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/providers/gemini.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/providers/litellm.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ai/providers/openai.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/cli.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/clients/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/clients/gcloud_client.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/config.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/discovery.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/errors.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/logging/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/logging/config.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/logging/decorators.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/migrations/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/migrations/base.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/migrations/legacy_to_v1.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/migrations/manager.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/models/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/models/code_review.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/plugins/available.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/plugins/community_sources.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/plugins/local_sources.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/plugins/models.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/plugins/plugin_base.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/plugins/plugin_registry.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/plugins/runtime.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/result.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/secrets.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/utils.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/validators/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/workflows/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/workflows/models.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/workflows/project_step_source.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/workflows/workflow_exceptions.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/workflows/workflow_registry.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/core/workflows/workflow_sources.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/builder.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/context.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/mock_context.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/option_item.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/results.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/steps/ai_assistant_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/steps/command_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/steps/select_cli_step.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/utils/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/utils/venv.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/engine/workflow_executor.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/adapters/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/adapters/base.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/adapters/claude.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/adapters/codex.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/adapters/gemini.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/adapters/registry.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/configs.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/external_cli/launcher.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/messages.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/__previews__/statusbar_preview.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/app.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/colors.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/icons.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/ai_config.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/ai_config_wizard.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/base.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/cli_launcher.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/global_setup_wizard.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/install_plugin_screen.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/main_menu.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/plugin_config_resolver.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/plugin_config_wizard.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/plugin_management.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/project_setup_wizard.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/workflow_execution.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/screens/workflows.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/textual_components.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/textual_workflow_executor.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/theme.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/button.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/decision_badge.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/dev_source_path_modal.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/header.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/multiline_input.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/panel.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/panel_container.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/prompt_choice.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/prompt_input.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/prompt_option_list.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/prompt_selection_list.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/prompt_textarea.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/segmented_switch.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/status_bar.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/step_container.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/styled_option_list.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/table.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/text.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/ui/tui/widgets/wizard.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/utils/__init__.py +0 -0
- {titan_cli-0.7.0 → titan_cli-0.7.2}/titan_cli/utils/autoupdate.py +0 -0
|
@@ -14,7 +14,7 @@ from titan_cli.core.plugins.models import GitHubPluginConfig
|
|
|
14
14
|
from titan_plugin_git.clients.git_client import GitClient
|
|
15
15
|
|
|
16
16
|
from .network import GHNetwork, GraphQLNetwork
|
|
17
|
-
from .services import PRService, ReviewService, IssueService, TeamService, ReleaseService
|
|
17
|
+
from .services import PRService, ReviewService, IssueService, TeamService, ReleaseService, ContentsService
|
|
18
18
|
from ..models.review_models import ReferencedCommitContext
|
|
19
19
|
from ..models.view import UIPullRequest, UICommentThread, UIIssue, UIPRMergeResult, UIReview, UIFileChange, UIPRCreated, UIRelease
|
|
20
20
|
|
|
@@ -77,6 +77,7 @@ class GitHubClient:
|
|
|
77
77
|
self._issue_service = IssueService(self._gh_network)
|
|
78
78
|
self._team_service = TeamService(self._gh_network)
|
|
79
79
|
self._release_service = ReleaseService(self._gh_network)
|
|
80
|
+
self._contents_service = ContentsService(self._gh_network)
|
|
80
81
|
|
|
81
82
|
def get_pr_template(self) -> Optional[str]:
|
|
82
83
|
"""Get the PR template if available."""
|
|
@@ -315,6 +316,46 @@ class GitHubClient:
|
|
|
315
316
|
"""Get a single GitHub release, including its full notes body."""
|
|
316
317
|
return self._release_service.get_release(tag_name)
|
|
317
318
|
|
|
319
|
+
# ============================================================================
|
|
320
|
+
# Contents Operations
|
|
321
|
+
# ============================================================================
|
|
322
|
+
|
|
323
|
+
def list_repository_directory(
|
|
324
|
+
self,
|
|
325
|
+
path: str,
|
|
326
|
+
ref: Optional[str] = None,
|
|
327
|
+
*,
|
|
328
|
+
repo_owner: Optional[str] = None,
|
|
329
|
+
repo_name: Optional[str] = None,
|
|
330
|
+
) -> ClientResult[List[Dict[str, Any]]]:
|
|
331
|
+
"""
|
|
332
|
+
List the entries of a directory in a repository.
|
|
333
|
+
|
|
334
|
+
Defaults to this client's own repo; pass repo_owner/repo_name to read
|
|
335
|
+
from a different repository without instantiating a new client.
|
|
336
|
+
"""
|
|
337
|
+
return self._contents_service.list_directory(
|
|
338
|
+
path, ref, repo_owner=repo_owner, repo_name=repo_name
|
|
339
|
+
)
|
|
340
|
+
|
|
341
|
+
def path_exists(
|
|
342
|
+
self,
|
|
343
|
+
path: str,
|
|
344
|
+
ref: Optional[str] = None,
|
|
345
|
+
*,
|
|
346
|
+
repo_owner: Optional[str] = None,
|
|
347
|
+
repo_name: Optional[str] = None,
|
|
348
|
+
) -> ClientResult[bool]:
|
|
349
|
+
"""
|
|
350
|
+
Check whether a path exists in a repository.
|
|
351
|
+
|
|
352
|
+
Defaults to this client's own repo; pass repo_owner/repo_name to check
|
|
353
|
+
against a different repository without instantiating a new client.
|
|
354
|
+
"""
|
|
355
|
+
return self._contents_service.path_exists(
|
|
356
|
+
path, ref, repo_owner=repo_owner, repo_name=repo_name
|
|
357
|
+
)
|
|
358
|
+
|
|
318
359
|
# ============================================================================
|
|
319
360
|
# Team Operations
|
|
320
361
|
# ============================================================================
|
|
@@ -10,6 +10,7 @@ from .review_service import ReviewService
|
|
|
10
10
|
from .issue_service import IssueService
|
|
11
11
|
from .team_service import TeamService
|
|
12
12
|
from .release_service import ReleaseService
|
|
13
|
+
from .contents_service import ContentsService
|
|
13
14
|
|
|
14
15
|
__all__ = [
|
|
15
16
|
"PRService",
|
|
@@ -17,4 +18,5 @@ __all__ = [
|
|
|
17
18
|
"IssueService",
|
|
18
19
|
"TeamService",
|
|
19
20
|
"ReleaseService",
|
|
21
|
+
"ContentsService",
|
|
20
22
|
]
|
titan_cli-0.7.2/plugins/titan-plugin-github/titan_plugin_github/clients/services/contents_service.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# plugins/titan-plugin-github/titan_plugin_github/clients/services/contents_service.py
|
|
2
|
+
"""
|
|
3
|
+
Contents Service
|
|
4
|
+
|
|
5
|
+
Business logic for navigating a GitHub repository's contents (Contents API).
|
|
6
|
+
Uses gh CLI through the network layer.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
from typing import List, Optional
|
|
11
|
+
from urllib.parse import quote, urlencode
|
|
12
|
+
|
|
13
|
+
from titan_cli.core.result import ClientResult, ClientSuccess, ClientError
|
|
14
|
+
from titan_cli.core.logging import log_client_operation
|
|
15
|
+
|
|
16
|
+
from ..network import GHNetwork
|
|
17
|
+
from ...exceptions import GitHubAPIError
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class ContentsService:
|
|
21
|
+
"""
|
|
22
|
+
Service for GitHub repository contents operations.
|
|
23
|
+
|
|
24
|
+
Lets callers navigate a repository's tree (list a directory, check whether
|
|
25
|
+
a path exists) without cloning it locally.
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
def __init__(self, gh_network: GHNetwork):
|
|
29
|
+
"""
|
|
30
|
+
Initialize contents service.
|
|
31
|
+
|
|
32
|
+
Args:
|
|
33
|
+
gh_network: GHNetwork instance for REST/CLI operations
|
|
34
|
+
"""
|
|
35
|
+
self.gh = gh_network
|
|
36
|
+
|
|
37
|
+
def _contents_endpoint(
|
|
38
|
+
self,
|
|
39
|
+
path: str,
|
|
40
|
+
ref: Optional[str],
|
|
41
|
+
repo_owner: Optional[str],
|
|
42
|
+
repo_name: Optional[str],
|
|
43
|
+
) -> List[str]:
|
|
44
|
+
owner = repo_owner or self.gh.repo_owner
|
|
45
|
+
name = repo_name or self.gh.repo_name
|
|
46
|
+
clean_path = "/".join(quote(segment) for segment in path.strip("/").split("/") if segment)
|
|
47
|
+
|
|
48
|
+
endpoint = f"repos/{owner}/{name}/contents"
|
|
49
|
+
if clean_path:
|
|
50
|
+
endpoint = f"{endpoint}/{clean_path}"
|
|
51
|
+
if ref:
|
|
52
|
+
endpoint = f"{endpoint}?{urlencode({'ref': ref})}"
|
|
53
|
+
|
|
54
|
+
return ["api", endpoint]
|
|
55
|
+
|
|
56
|
+
@staticmethod
|
|
57
|
+
def _is_not_found(error: GitHubAPIError) -> bool:
|
|
58
|
+
return "404" in (error.stderr or "")
|
|
59
|
+
|
|
60
|
+
@log_client_operation()
|
|
61
|
+
def list_directory(
|
|
62
|
+
self,
|
|
63
|
+
path: str,
|
|
64
|
+
ref: Optional[str] = None,
|
|
65
|
+
*,
|
|
66
|
+
repo_owner: Optional[str] = None,
|
|
67
|
+
repo_name: Optional[str] = None,
|
|
68
|
+
) -> ClientResult[List[dict]]:
|
|
69
|
+
"""
|
|
70
|
+
List the entries of a directory in a repository.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
path: Directory path relative to the repo root ("" for repo root)
|
|
74
|
+
ref: Optional branch/tag/commit SHA to read from (defaults to the repo's default branch)
|
|
75
|
+
repo_owner: Optional owner override (defaults to the client's configured repo)
|
|
76
|
+
repo_name: Optional repo name override (defaults to the client's configured repo)
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
ClientResult[List[dict]] with entries shaped like
|
|
80
|
+
{"name": str, "path": str, "type": "dir" | "file"}
|
|
81
|
+
"""
|
|
82
|
+
try:
|
|
83
|
+
args = self._contents_endpoint(path, ref, repo_owner, repo_name)
|
|
84
|
+
output = self.gh.run_command(args)
|
|
85
|
+
data = json.loads(output)
|
|
86
|
+
|
|
87
|
+
if isinstance(data, dict):
|
|
88
|
+
return ClientError(
|
|
89
|
+
error_message=f"'{path}' is a file, not a directory",
|
|
90
|
+
error_code="NOT_A_DIRECTORY",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
entries = [
|
|
94
|
+
{"name": item["name"], "path": item["path"], "type": item["type"]}
|
|
95
|
+
for item in data
|
|
96
|
+
]
|
|
97
|
+
|
|
98
|
+
return ClientSuccess(
|
|
99
|
+
data=entries,
|
|
100
|
+
message=f"Retrieved {len(entries)} entries from '{path or '/'}'"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
except json.JSONDecodeError as e:
|
|
104
|
+
return ClientError(
|
|
105
|
+
error_message=f"Failed to parse contents data: {e}",
|
|
106
|
+
error_code="JSON_PARSE_ERROR",
|
|
107
|
+
)
|
|
108
|
+
except GitHubAPIError as e:
|
|
109
|
+
if self._is_not_found(e):
|
|
110
|
+
return ClientError(
|
|
111
|
+
error_message=f"Path '{path}' not found",
|
|
112
|
+
error_code="NOT_FOUND",
|
|
113
|
+
)
|
|
114
|
+
return ClientError(error_message=str(e), error_code="API_ERROR")
|
|
115
|
+
|
|
116
|
+
@log_client_operation()
|
|
117
|
+
def path_exists(
|
|
118
|
+
self,
|
|
119
|
+
path: str,
|
|
120
|
+
ref: Optional[str] = None,
|
|
121
|
+
*,
|
|
122
|
+
repo_owner: Optional[str] = None,
|
|
123
|
+
repo_name: Optional[str] = None,
|
|
124
|
+
) -> ClientResult[bool]:
|
|
125
|
+
"""
|
|
126
|
+
Check whether a path exists in a repository.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
path: Path relative to the repo root
|
|
130
|
+
ref: Optional branch/tag/commit SHA to check against (defaults to the repo's default branch)
|
|
131
|
+
repo_owner: Optional owner override (defaults to the client's configured repo)
|
|
132
|
+
repo_name: Optional repo name override (defaults to the client's configured repo)
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
ClientResult[bool]
|
|
136
|
+
"""
|
|
137
|
+
try:
|
|
138
|
+
args = self._contents_endpoint(path, ref, repo_owner, repo_name)
|
|
139
|
+
self.gh.run_command(args)
|
|
140
|
+
return ClientSuccess(data=True, message=f"'{path}' exists")
|
|
141
|
+
except GitHubAPIError as e:
|
|
142
|
+
if self._is_not_found(e):
|
|
143
|
+
return ClientSuccess(data=False, message=f"'{path}' does not exist")
|
|
144
|
+
return ClientError(error_message=str(e), error_code="API_ERROR")
|
|
@@ -56,7 +56,7 @@ class PRService:
|
|
|
56
56
|
"baseRefName", "headRefName", "additions", "deletions",
|
|
57
57
|
"changedFiles", "mergeable", "isDraft", "createdAt",
|
|
58
58
|
"updatedAt", "mergedAt", "reviews", "labels",
|
|
59
|
-
"statusCheckRollup", "reviewDecision",
|
|
59
|
+
"statusCheckRollup", "reviewDecision", "reviewRequests",
|
|
60
60
|
"isCrossRepository", "headRepositoryOwner", "headRepository",
|
|
61
61
|
]
|
|
62
62
|
|
|
@@ -35,6 +35,13 @@ def from_rest_pr(rest_pr: NetworkPullRequest) -> UIPullRequest:
|
|
|
35
35
|
# Extract label names from label objects
|
|
36
36
|
label_names = [label.get("name", "") for label in rest_pr.labels]
|
|
37
37
|
|
|
38
|
+
# Extract requested reviewers
|
|
39
|
+
requested_reviewers = [user.login for user in rest_pr.requestedReviewers]
|
|
40
|
+
|
|
41
|
+
# Calculate pending reviewers (requested but not yet reviewed)
|
|
42
|
+
reviewed_logins = {review.user.login for review in rest_pr.reviews if review.state != "PENDING"}
|
|
43
|
+
pending_reviewers = [login for login in requested_reviewers if login not in reviewed_logins]
|
|
44
|
+
|
|
38
45
|
return UIPullRequest(
|
|
39
46
|
number=rest_pr.number,
|
|
40
47
|
title=rest_pr.title,
|
|
@@ -58,6 +65,8 @@ def from_rest_pr(rest_pr: NetworkPullRequest) -> UIPullRequest:
|
|
|
58
65
|
is_cross_repository=rest_pr.isCrossRepository,
|
|
59
66
|
head_repository_owner=rest_pr.headRepositoryOwnerLogin,
|
|
60
67
|
head_repository_name=rest_pr.headRepositoryName,
|
|
68
|
+
requested_reviewers=requested_reviewers,
|
|
69
|
+
pending_reviewers=pending_reviewers,
|
|
61
70
|
)
|
|
62
71
|
|
|
63
72
|
|
|
@@ -48,6 +48,7 @@ class NetworkPullRequest:
|
|
|
48
48
|
mergedAt: Merge timestamp if merged (ISO 8601, camelCase as in API)
|
|
49
49
|
reviews: List of reviews
|
|
50
50
|
labels: List of label objects with 'name' field
|
|
51
|
+
requestedReviewers: List of users requested to review the PR
|
|
51
52
|
"""
|
|
52
53
|
number: int
|
|
53
54
|
title: str
|
|
@@ -71,6 +72,7 @@ class NetworkPullRequest:
|
|
|
71
72
|
isCrossRepository: bool = False
|
|
72
73
|
headRepositoryOwnerLogin: Optional[str] = None
|
|
73
74
|
headRepositoryName: Optional[str] = None
|
|
75
|
+
requestedReviewers: List[NetworkUser] = field(default_factory=list) # Users requested to review
|
|
74
76
|
|
|
75
77
|
@classmethod
|
|
76
78
|
def from_json(cls, data: Dict[str, Any]) -> 'NetworkPullRequest':
|
|
@@ -97,6 +99,10 @@ class NetworkPullRequest:
|
|
|
97
99
|
reviews_data = data.get("reviews", [])
|
|
98
100
|
reviews = [NetworkReview.from_json(r) for r in reviews_data]
|
|
99
101
|
|
|
102
|
+
# Parse requested reviewers (gh CLI JSON field is "reviewRequests")
|
|
103
|
+
requested_reviewers_data = data.get("reviewRequests", [])
|
|
104
|
+
requested_reviewers = [NetworkUser.from_json(r) for r in requested_reviewers_data]
|
|
105
|
+
|
|
100
106
|
return cls(
|
|
101
107
|
number=data.get("number", 0),
|
|
102
108
|
title=data.get("title", ""),
|
|
@@ -128,6 +134,7 @@ class NetworkPullRequest:
|
|
|
128
134
|
isCrossRepository=data.get("isCrossRepository", False),
|
|
129
135
|
headRepositoryOwnerLogin=(data.get("headRepositoryOwner") or {}).get("login"),
|
|
130
136
|
headRepositoryName=(data.get("headRepository") or {}).get("name"),
|
|
137
|
+
requestedReviewers=requested_reviewers,
|
|
131
138
|
)
|
|
132
139
|
|
|
133
140
|
|
{titan_cli-0.7.0 → titan_cli-0.7.2}/plugins/titan-plugin-github/titan_plugin_github/models/view.py
RENAMED
|
@@ -10,7 +10,7 @@ Network models contain raw API data; view models contain UI-ready data.
|
|
|
10
10
|
These models are GitHub-specific and live in the GitHub plugin, not in the core.
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
-
from dataclasses import dataclass
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
14
|
from typing import Any, List, Optional
|
|
15
15
|
|
|
16
16
|
from .pr_enums import PRState
|
|
@@ -137,6 +137,10 @@ class UIPullRequest:
|
|
|
137
137
|
|
|
138
138
|
All fields are pre-formatted and ready for widget rendering.
|
|
139
139
|
Computed/derived fields are calculated once during construction.
|
|
140
|
+
|
|
141
|
+
Fields:
|
|
142
|
+
requested_reviewers: All GitHub logins of users requested to review
|
|
143
|
+
pending_reviewers: Logins of reviewers who haven't submitted a review yet
|
|
140
144
|
"""
|
|
141
145
|
number: int
|
|
142
146
|
title: str
|
|
@@ -160,6 +164,8 @@ class UIPullRequest:
|
|
|
160
164
|
is_cross_repository: bool = False
|
|
161
165
|
head_repository_owner: Optional[str] = None
|
|
162
166
|
head_repository_name: Optional[str] = None
|
|
167
|
+
requested_reviewers: List[str] = field(default_factory=list) # All requested reviewer logins
|
|
168
|
+
pending_reviewers: List[str] = field(default_factory=list) # Reviewers who haven't reviewed yet
|
|
163
169
|
|
|
164
170
|
|
|
165
171
|
@dataclass
|
|
@@ -218,6 +218,57 @@ Respond ONLY with a valid JSON array matching this exact schema for each element
|
|
|
218
218
|
Return ONLY the JSON array. No explanation, no markdown fences."""
|
|
219
219
|
|
|
220
220
|
|
|
221
|
+
DEFAULT_THREAD_BATCH_MAX_PROMPT_CHARS = 20_000
|
|
222
|
+
DEFAULT_THREAD_BATCH_MAX_THREADS = 8
|
|
223
|
+
|
|
224
|
+
|
|
225
|
+
def batch_thread_review_contexts(
|
|
226
|
+
contexts: list[ThreadReviewContext],
|
|
227
|
+
max_prompt_chars: int = DEFAULT_THREAD_BATCH_MAX_PROMPT_CHARS,
|
|
228
|
+
max_threads_per_batch: int = DEFAULT_THREAD_BATCH_MAX_THREADS,
|
|
229
|
+
) -> list[list[ThreadReviewContext]]:
|
|
230
|
+
"""
|
|
231
|
+
Split thread contexts into batches that keep each AI call within a prompt budget.
|
|
232
|
+
|
|
233
|
+
Each thread keeps its full conversation, code hunk, and referenced commit
|
|
234
|
+
context untouched — batching only controls how many threads share one AI
|
|
235
|
+
call, so no per-thread content is trimmed. A thread that alone exceeds the
|
|
236
|
+
budget is still sent by itself rather than being degraded.
|
|
237
|
+
|
|
238
|
+
Args:
|
|
239
|
+
contexts: Enriched thread contexts from build_thread_review_contexts
|
|
240
|
+
max_prompt_chars: Target prompt size per batch (soft budget)
|
|
241
|
+
max_threads_per_batch: Upper bound on threads per batch regardless of size
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
List of thread-context batches, each safe to pass to build_thread_resolution_prompt
|
|
245
|
+
"""
|
|
246
|
+
if not contexts:
|
|
247
|
+
return []
|
|
248
|
+
|
|
249
|
+
queue = [
|
|
250
|
+
contexts[i : i + max_threads_per_batch]
|
|
251
|
+
for i in range(0, len(contexts), max_threads_per_batch)
|
|
252
|
+
]
|
|
253
|
+
batches: list[list[ThreadReviewContext]] = []
|
|
254
|
+
|
|
255
|
+
while queue:
|
|
256
|
+
batch = queue.pop(0)
|
|
257
|
+
if len(batch) == 1:
|
|
258
|
+
batches.append(batch)
|
|
259
|
+
continue
|
|
260
|
+
|
|
261
|
+
if len(build_thread_resolution_prompt(batch)) <= max_prompt_chars:
|
|
262
|
+
batches.append(batch)
|
|
263
|
+
continue
|
|
264
|
+
|
|
265
|
+
midpoint = max(1, len(batch) // 2)
|
|
266
|
+
queue.insert(0, batch[midpoint:])
|
|
267
|
+
queue.insert(0, batch[:midpoint])
|
|
268
|
+
|
|
269
|
+
return batches
|
|
270
|
+
|
|
271
|
+
|
|
221
272
|
def _threads_to_text(contexts: list[ThreadReviewContext]) -> str:
|
|
222
273
|
if not contexts:
|
|
223
274
|
return "(no threads to review)"
|
|
@@ -43,6 +43,7 @@ from ..operations.review_action_operations import (
|
|
|
43
43
|
resolve_action_anchors,
|
|
44
44
|
)
|
|
45
45
|
from ..operations.thread_resolution_operations import (
|
|
46
|
+
batch_thread_review_contexts,
|
|
46
47
|
build_thread_review_candidates as build_thread_review_candidates_operation,
|
|
47
48
|
build_thread_review_contexts as build_thread_review_contexts_operation,
|
|
48
49
|
build_thread_resolution_prompt,
|
|
@@ -2741,18 +2742,23 @@ def ai_thread_resolution(ctx: WorkflowContext) -> WorkflowResult:
|
|
|
2741
2742
|
"""
|
|
2742
2743
|
AI call: decide what to do with each open thread.
|
|
2743
2744
|
|
|
2744
|
-
|
|
2745
|
+
Splits thread contexts into prompt-budget-bound batches (see
|
|
2746
|
+
batch_thread_review_contexts) and sends each batch — original comment +
|
|
2747
|
+
replies + current code + referenced commits, all untouched — to the
|
|
2745
2748
|
selected headless CLI. The AI decides per thread: resolved / insist /
|
|
2746
|
-
reply / skip.
|
|
2749
|
+
reply / skip. Batches run sequentially and their decisions are aggregated;
|
|
2750
|
+
a batch that fails (CLI error or parse error) is skipped without aborting
|
|
2751
|
+
the remaining batches.
|
|
2747
2752
|
|
|
2748
|
-
On
|
|
2753
|
+
On total failure (no batch produced usable output), falls back to empty
|
|
2754
|
+
decisions (no actions).
|
|
2749
2755
|
|
|
2750
2756
|
Requires (from ctx.data):
|
|
2751
2757
|
thread_review_contexts (List[ThreadReviewContext])
|
|
2752
2758
|
cli_preference (str): "claude" | "gemini" | "codex" | "auto"
|
|
2753
2759
|
|
|
2754
2760
|
Outputs (saved to ctx.data):
|
|
2755
|
-
raw_thread_decisions (list): Raw AI output before normalization
|
|
2761
|
+
raw_thread_decisions (list): Raw AI output aggregated across batches, before normalization
|
|
2756
2762
|
|
|
2757
2763
|
Returns:
|
|
2758
2764
|
Success or Error
|
|
@@ -2779,46 +2785,90 @@ def ai_thread_resolution(ctx: WorkflowContext) -> WorkflowResult:
|
|
|
2779
2785
|
ctx.textual.end_step("success")
|
|
2780
2786
|
return Success("No decisions (no CLI available)", metadata={"raw_thread_decisions": []})
|
|
2781
2787
|
|
|
2782
|
-
|
|
2783
|
-
|
|
2788
|
+
# Split into batches so one call never has to carry every open thread at
|
|
2789
|
+
# once — each thread's full conversation/hunk/commit context stays intact,
|
|
2790
|
+
# only the number of threads sharing a single AI call is bounded.
|
|
2791
|
+
batches = batch_thread_review_contexts(contexts)
|
|
2784
2792
|
cli_display = adapter.cli_name.value.capitalize()
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
with ctx.textual.loading(f"Asking {cli_display} to analyse {thread_count} thread(s)…"):
|
|
2788
|
-
response = adapter.execute(prompt, cwd=project_root, timeout=300)
|
|
2789
|
-
adapter_duration_seconds = time.monotonic() - adapter_started_at
|
|
2790
|
-
logger.info(
|
|
2791
|
-
"thread_resolution_adapter_call",
|
|
2792
|
-
cli=adapter.cli_name.value,
|
|
2793
|
-
thread_count=thread_count,
|
|
2794
|
-
prompt_actual_chars=len(prompt),
|
|
2795
|
-
duration_seconds=round(adapter_duration_seconds, 3),
|
|
2796
|
-
exit_code=response.exit_code,
|
|
2797
|
-
timed_out=response.exit_code == 124,
|
|
2793
|
+
ctx.textual.dim_text(
|
|
2794
|
+
f"Reviewing {len(contexts)} thread(s) in {len(batches)} batch(es) with {cli_display}"
|
|
2798
2795
|
)
|
|
2799
2796
|
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
if response.stderr:
|
|
2803
|
-
ctx.textual.dim_text(response.stderr[:200])
|
|
2804
|
-
ctx.data["raw_thread_decisions"] = []
|
|
2805
|
-
ctx.textual.end_step("success")
|
|
2806
|
-
return Success("No decisions (CLI error)", metadata={"raw_thread_decisions": []})
|
|
2797
|
+
aggregated_raw: list = []
|
|
2798
|
+
any_batch_failed = False
|
|
2807
2799
|
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
ctx.textual.warning_text(f"Thread decisions parsing failed ({err}) — no decisions")
|
|
2812
|
-
ctx.data["raw_thread_decisions"] = []
|
|
2813
|
-
ctx.textual.end_step("success")
|
|
2814
|
-
return Success("No decisions (parse error)", metadata={"raw_thread_decisions": []})
|
|
2815
|
-
case ClientSuccess(data=raw):
|
|
2816
|
-
pass
|
|
2800
|
+
for batch_index, batch in enumerate(batches, start=1):
|
|
2801
|
+
batch_label = f"batch {batch_index}/{len(batches)}"
|
|
2802
|
+
prompt = build_thread_resolution_prompt(batch)
|
|
2817
2803
|
|
|
2818
|
-
|
|
2819
|
-
|
|
2804
|
+
_log_ai_prompt(
|
|
2805
|
+
step_name="ai_thread_resolution",
|
|
2806
|
+
cli_name=adapter.cli_name.value,
|
|
2807
|
+
prompt=prompt,
|
|
2808
|
+
batch_index=batch_index,
|
|
2809
|
+
batch_count=len(batches),
|
|
2810
|
+
thread_count=len(batch),
|
|
2811
|
+
)
|
|
2812
|
+
|
|
2813
|
+
adapter_started_at = time.monotonic()
|
|
2814
|
+
with ctx.textual.loading(
|
|
2815
|
+
f"Asking {cli_display} to analyse {batch_label} ({len(batch)} thread(s))…"
|
|
2816
|
+
):
|
|
2817
|
+
response = adapter.execute(prompt, cwd=project_root, timeout=300)
|
|
2818
|
+
adapter_duration_seconds = time.monotonic() - adapter_started_at
|
|
2819
|
+
logger.info(
|
|
2820
|
+
"thread_resolution_adapter_call",
|
|
2821
|
+
cli=adapter.cli_name.value,
|
|
2822
|
+
batch_index=batch_index,
|
|
2823
|
+
batch_count=len(batches),
|
|
2824
|
+
thread_count=len(batch),
|
|
2825
|
+
prompt_actual_chars=len(prompt),
|
|
2826
|
+
duration_seconds=round(adapter_duration_seconds, 3),
|
|
2827
|
+
exit_code=response.exit_code,
|
|
2828
|
+
timed_out=response.exit_code == 124,
|
|
2829
|
+
)
|
|
2830
|
+
_log_ai_response(
|
|
2831
|
+
step_name="ai_thread_resolution",
|
|
2832
|
+
cli_name=adapter.cli_name.value,
|
|
2833
|
+
stdout=response.stdout,
|
|
2834
|
+
stderr=response.stderr,
|
|
2835
|
+
exit_code=response.exit_code,
|
|
2836
|
+
batch_index=batch_index,
|
|
2837
|
+
batch_count=len(batches),
|
|
2838
|
+
)
|
|
2839
|
+
|
|
2840
|
+
if not response.succeeded:
|
|
2841
|
+
any_batch_failed = True
|
|
2842
|
+
ctx.textual.warning_text(f"{batch_label}: CLI call failed (exit {response.exit_code}) — skipped")
|
|
2843
|
+
if response.stderr:
|
|
2844
|
+
ctx.textual.dim_text(response.stderr[:200])
|
|
2845
|
+
continue
|
|
2846
|
+
|
|
2847
|
+
match extract_json_payload(response.stdout, kind="array"):
|
|
2848
|
+
case ClientError(error_message=err):
|
|
2849
|
+
any_batch_failed = True
|
|
2850
|
+
ctx.textual.warning_text(f"{batch_label}: decisions parsing failed ({err}) — skipped")
|
|
2851
|
+
continue
|
|
2852
|
+
case ClientSuccess(data=raw):
|
|
2853
|
+
aggregated_raw.extend(raw)
|
|
2854
|
+
|
|
2855
|
+
ctx.data["raw_thread_decisions"] = aggregated_raw
|
|
2856
|
+
|
|
2857
|
+
if not aggregated_raw:
|
|
2858
|
+
status = "No decisions (all batches failed)" if any_batch_failed else "No decisions"
|
|
2859
|
+
ctx.textual.warning_text(status)
|
|
2860
|
+
ctx.textual.end_step("success")
|
|
2861
|
+
return Success(status, metadata={"raw_thread_decisions": []})
|
|
2862
|
+
|
|
2863
|
+
summary = f"✓ AI returned {len(aggregated_raw)} thread decision(s)"
|
|
2864
|
+
if any_batch_failed:
|
|
2865
|
+
summary += " (some batches failed — partial results)"
|
|
2866
|
+
ctx.textual.success_text(summary)
|
|
2820
2867
|
ctx.textual.end_step("success")
|
|
2821
|
-
return Success(
|
|
2868
|
+
return Success(
|
|
2869
|
+
"AI thread decisions retrieved",
|
|
2870
|
+
metadata={"raw_thread_decisions_count": len(aggregated_raw)},
|
|
2871
|
+
)
|
|
2822
2872
|
|
|
2823
2873
|
|
|
2824
2874
|
def normalize_thread_decisions(ctx: WorkflowContext) -> WorkflowResult:
|
|
@@ -41,9 +41,11 @@ class AuthService:
|
|
|
41
41
|
)
|
|
42
42
|
|
|
43
43
|
if not response.get("ok", False):
|
|
44
|
+
error_code = response.get("error", "unknown_error")
|
|
44
45
|
return ClientError(
|
|
45
|
-
error_message=f"Slack auth failed: {
|
|
46
|
+
error_message=f"Slack auth failed: {error_code}",
|
|
46
47
|
error_code="AUTH_ERROR",
|
|
48
|
+
details={"slack_error": error_code},
|
|
47
49
|
)
|
|
48
50
|
|
|
49
51
|
return ClientSuccess(
|
|
@@ -104,14 +104,17 @@ class ConversationService:
|
|
|
104
104
|
if not response.get("ok", False):
|
|
105
105
|
needed = response.get("needed")
|
|
106
106
|
provided = response.get("provided")
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
slack_error = response.get("error", "unknown_error")
|
|
108
|
+
message = f"Slack read_channel failed: {slack_error}"
|
|
109
|
+
details = {"slack_error": slack_error}
|
|
110
|
+
if slack_error == "missing_scope" and needed:
|
|
110
111
|
message += (
|
|
111
112
|
f". Missing scopes: {needed}. "
|
|
112
113
|
"Reconnect Slack configuration to grant the required scopes."
|
|
113
114
|
)
|
|
114
|
-
details
|
|
115
|
+
details["needed_scopes"] = needed
|
|
116
|
+
if provided:
|
|
117
|
+
details["provided_scopes"] = provided
|
|
115
118
|
return ClientError(
|
|
116
119
|
error_message=message,
|
|
117
120
|
error_code="READ_CHANNEL_ERROR",
|
|
@@ -154,16 +157,17 @@ class ConversationService:
|
|
|
154
157
|
if not response.get("ok", False):
|
|
155
158
|
needed = response.get("needed")
|
|
156
159
|
provided = response.get("provided")
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if response.get("error") == "missing_scope" and needed:
|
|
160
|
+
slack_error = response.get("error", "unknown_error")
|
|
161
|
+
message = f"Slack open_direct_message failed: {slack_error}"
|
|
162
|
+
details = {"slack_error": slack_error}
|
|
163
|
+
if slack_error == "missing_scope" and needed:
|
|
162
164
|
message += (
|
|
163
165
|
f". Missing scopes: {needed}. "
|
|
164
166
|
"Reconnect Slack configuration to grant the required scopes."
|
|
165
167
|
)
|
|
166
|
-
details
|
|
168
|
+
details["needed_scopes"] = needed
|
|
169
|
+
if provided:
|
|
170
|
+
details["provided_scopes"] = provided
|
|
167
171
|
return ClientError(
|
|
168
172
|
error_message=message,
|
|
169
173
|
error_code="OPEN_DIRECT_MESSAGE_ERROR",
|
|
@@ -149,9 +149,11 @@ class DirectoryService:
|
|
|
149
149
|
)
|
|
150
150
|
|
|
151
151
|
if not response.get("ok", False):
|
|
152
|
+
error_code = response.get("error", "unknown_error")
|
|
152
153
|
return ClientError(
|
|
153
|
-
error_message=f"Slack list_users failed: {
|
|
154
|
+
error_message=f"Slack list_users failed: {error_code}",
|
|
154
155
|
error_code="LIST_USERS_ERROR",
|
|
156
|
+
details={"slack_error": error_code},
|
|
155
157
|
)
|
|
156
158
|
|
|
157
159
|
members = [self._map_user(member) for member in response.get("members", [])]
|
|
@@ -195,12 +197,11 @@ class DirectoryService:
|
|
|
195
197
|
)
|
|
196
198
|
|
|
197
199
|
if not response.get("ok", False):
|
|
200
|
+
error_code = response.get("error", "unknown_error")
|
|
198
201
|
return ClientError(
|
|
199
|
-
error_message=
|
|
200
|
-
"Slack list_public_channels failed: "
|
|
201
|
-
f"{response.get('error', 'unknown_error')}"
|
|
202
|
-
),
|
|
202
|
+
error_message=f"Slack list_public_channels failed: {error_code}",
|
|
203
203
|
error_code="LIST_PUBLIC_CHANNELS_ERROR",
|
|
204
|
+
details={"slack_error": error_code},
|
|
204
205
|
)
|
|
205
206
|
|
|
206
207
|
channels = [self._map_channel(channel) for channel in response.get("channels", [])]
|
|
@@ -353,11 +354,11 @@ class DirectoryService:
|
|
|
353
354
|
)
|
|
354
355
|
|
|
355
356
|
if not response.get("ok", False):
|
|
357
|
+
error_code = response.get("error", "unknown_error")
|
|
356
358
|
return ClientError(
|
|
357
|
-
error_message=
|
|
358
|
-
f"Slack search_channels failed: {response.get('error', 'unknown_error')}"
|
|
359
|
-
),
|
|
359
|
+
error_message=f"Slack search_channels failed: {error_code}",
|
|
360
360
|
error_code="SEARCH_CHANNELS_ERROR",
|
|
361
|
+
details={"slack_error": error_code},
|
|
361
362
|
)
|
|
362
363
|
|
|
363
364
|
channels = [self._map_channel(channel) for channel in response.get("channels", [])]
|