titan-cli 0.1.16__tar.gz → 0.2.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.
- {titan_cli-0.1.16 → titan_cli-0.2.0}/PKG-INFO +7 -4
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/push_step.py +17 -2
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/status_step.py +7 -6
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/github_client.py +4 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/network/graphql_queries.py +23 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/services/review_service.py +63 -16
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/view.py +30 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/operations/__init__.py +4 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/operations/comment_operations.py +50 -18
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/operations/pr_operations.py +49 -7
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/pr_review_steps.py +171 -87
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/workflows/create-pr-ai.yaml +8 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/pyproject.toml +9 -2
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/config.py +16 -13
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/logging/config.py +6 -1
- titan_cli-0.2.0/titan_cli/core/plugins/community.py +543 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/plugins/plugin_base.py +18 -2
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/plugins/plugin_registry.py +11 -4
- titan_cli-0.2.0/titan_cli/core/utils.py +44 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/workflows/models.py +1 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/workflows/workflow_filter_service.py +3 -3
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/workflows/workflow_registry.py +44 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/workflows/workflow_sources.py +28 -9
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/steps/ai_assistant_step.py +0 -1
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/steps/command_step.py +3 -6
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/__init__.py +18 -16
- titan_cli-0.2.0/titan_cli/ui/tui/screens/install_plugin_screen.py +567 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/main_menu.py +25 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/plugin_config_wizard.py +33 -30
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/plugin_management.py +224 -16
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/workflow_execution.py +9 -8
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/textual_components.py +117 -3
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/__init__.py +4 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/panel.py +45 -12
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/prompt_input.py +3 -1
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/table.py +30 -3
- titan_cli-0.2.0/titan_cli/ui/tui/widgets/wizard.py +49 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/LICENSE +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/README.md +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/git_client.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/network/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/network/git_network.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/branch_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/commit_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/diff_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/remote_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/stash_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/status_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/tag_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/clients/services/worktree_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/exceptions.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/messages.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/branch_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/commit_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/status_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/tag_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/mappers/worktree_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/network/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/network/branch.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/network/commit.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/network/status.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/network/tag.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/network/worktree.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/view/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/view/branch.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/view/commit.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/view/status.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/view/tag.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/models/view/worktree.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/operations/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/operations/branch_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/operations/commit_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/operations/diff_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/plugin.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/ai_commit_message_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/branch_steps.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/checkout_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/commit_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/create_branch_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/create_worktree_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/diff_summary_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/pull_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/remove_worktree_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/restore_original_branch_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/save_current_branch_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/worktree_command_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/workflows/__previews__/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/workflows/__previews__/commit_ai_preview.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/workflows/commit-ai.yaml +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/agents/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/agents/config_loader.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/agents/issue_generator.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/agents/pr_agent.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/network/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/network/gh_network.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/network/graphql_network.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/protocols.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/services/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/services/issue_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/services/pr_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/clients/services/team_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/config/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/config/pr_agent.toml +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/exceptions.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/messages.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/formatting.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/comment_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/issue_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/pr_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/review_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/mappers/thread_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/issue_comment.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/review_comment.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/review_thread.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/graphql/user.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/issue.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/pull_request.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/review.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/network/rest/user.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/operations/issue_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/operations/pr_creation_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/operations/worktree_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/plugin.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/ai_pr_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/create_pr_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/github_prompt_steps.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/issue_steps.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/preview_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/steps/worktree_steps.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/utils.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/widgets/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/widgets/code_block.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/widgets/comment.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/widgets/comment_thread.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/widgets/comment_utils.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/widgets/reply_comment.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/workflows/__previews__/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/workflows/__previews__/create_pr_ai_preview.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/workflows/create-issue-ai.yaml +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/workflows/review-pr-comments.yaml +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/agents/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/agents/config_loader.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/agents/jira_agent.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/agents/prompts.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/agents/response_parser.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/agents/token_tracker.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/agents/validators.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/jira_client.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/network/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/network/jira_network.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/comment_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/issue_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/link_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/metadata_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/project_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/clients/services/transition_service.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/config/jira_agent.toml +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/config/templates/issue_analysis.md.j2 +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/exceptions.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/formatters/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/formatters/markdown_formatter.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/messages.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/formatting.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/comment_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/issue_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/project_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/mappers/transition_mapper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/comment.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/issue.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/issue_type.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/priority.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/project.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/status.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/transition.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/network/rest/user.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/models/view.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/operations/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/operations/issue_formatting_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/operations/jql_operations.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/plugin.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/steps/ai_analyze_issue_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/steps/get_issue_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/steps/list_versions_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/steps/prompt_select_issue_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/steps/search_jql_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/steps/search_saved_query_step.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/utils/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/utils/issue_sorter.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/utils/saved_queries.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-jira/titan_plugin_jira/workflows/analyze-jira-issues.yaml +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/__main__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/agents/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/agents/base.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/client.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/constants.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/exceptions.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/llm_tools.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/models.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/oauth_helper.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/providers/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/providers/anthropic.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/providers/base.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ai/providers/gemini.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/cli.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/clients/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/clients/gcloud_client.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/discovery.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/errors.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/logging/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/logging/decorators.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/models.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/plugins/available.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/plugins/models.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/result.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/secrets.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/workflows/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/workflows/project_step_source.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/core/workflows/workflow_exceptions.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/builder.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/context.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/mock_context.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/results.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/utils/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/utils/venv.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/engine/workflow_executor.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/external_cli/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/external_cli/configs.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/external_cli/launcher.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/messages.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/__previews__/statusbar_preview.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/app.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/colors.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/icons.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/ai_config.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/ai_config_wizard.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/base.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/cli_launcher.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/global_setup_wizard.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/project_setup_wizard.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/screens/workflows.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/textual_workflow_executor.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/theme.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/button.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/decision_badge.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/header.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/multiline_input.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/panel_container.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/prompt_choice.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/prompt_option_list.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/prompt_selection_list.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/prompt_textarea.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/status_bar.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/step_container.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/styled_option_list.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/ui/tui/widgets/text.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/utils/__init__.py +0 -0
- {titan_cli-0.1.16 → titan_cli-0.2.0}/titan_cli/utils/autoupdate.py +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: titan-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.0
|
|
4
4
|
Summary: Modular development tools orchestrator - Streamline your workflows with AI integration and intuitive terminal UI
|
|
5
|
-
Home-page: https://github.com/masorange/titan-cli
|
|
6
5
|
License: MIT
|
|
6
|
+
License-File: LICENSE
|
|
7
7
|
Keywords: cli,workflow,orchestrator,automation,devtools,ai
|
|
8
8
|
Author: MasOrange Apps Team
|
|
9
9
|
Author-email: apps-management-stores@masorange.es
|
|
@@ -17,6 +17,8 @@ Classifier: Programming Language :: Python :: 3
|
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
22
|
Requires-Dist: anthropic (>=0.75.0,<0.76.0)
|
|
21
23
|
Requires-Dist: google-auth (>=2.43.0,<3.0.0)
|
|
22
24
|
Requires-Dist: google-genai (>=1.58.0,<2.0.0)
|
|
@@ -32,7 +34,8 @@ Requires-Dist: textual (>=1.0.0,<2.0.0)
|
|
|
32
34
|
Requires-Dist: tomli (>=2.0.0,<3.0.0)
|
|
33
35
|
Requires-Dist: tomli-w (>=1.0.0,<2.0.0)
|
|
34
36
|
Requires-Dist: typer (>=0.20.0,<1.0.0)
|
|
35
|
-
Project-URL: Documentation, https://github.
|
|
37
|
+
Project-URL: Documentation, https://masorange.github.io/titan-cli/
|
|
38
|
+
Project-URL: Homepage, https://github.com/masorange/titan-cli
|
|
36
39
|
Project-URL: Repository, https://github.com/masorange/titan-cli
|
|
37
40
|
Description-Content-Type: text/markdown
|
|
38
41
|
|
{titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/push_step.py
RENAMED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# plugins/titan-plugin-git/titan_plugin_git/steps/push_step.py
|
|
2
|
-
from titan_cli.engine import WorkflowContext, WorkflowResult, Success, Error
|
|
2
|
+
from titan_cli.engine import WorkflowContext, WorkflowResult, Success, Error, Skip
|
|
3
3
|
from titan_cli.core.result import ClientSuccess, ClientError
|
|
4
4
|
from titan_plugin_git.messages import msg
|
|
5
5
|
|
|
@@ -57,9 +57,24 @@ def create_git_push_step(ctx: WorkflowContext) -> WorkflowResult:
|
|
|
57
57
|
exists_result = ctx.git.branch_exists_on_remote(branch=branch_to_use, remote=remote_to_use)
|
|
58
58
|
match exists_result:
|
|
59
59
|
case ClientSuccess(data=exists):
|
|
60
|
-
# The first push of a branch should set the upstream
|
|
61
60
|
if not exists:
|
|
61
|
+
# The first push of a branch should set the upstream
|
|
62
62
|
set_upstream = True
|
|
63
|
+
else:
|
|
64
|
+
# Branch exists on remote — check if there's anything to push
|
|
65
|
+
unpushed_result = ctx.git.count_unpushed_commits(branch=branch_to_use, remote=remote_to_use)
|
|
66
|
+
match unpushed_result:
|
|
67
|
+
case ClientSuccess(data=unpushed_count):
|
|
68
|
+
if unpushed_count == 0:
|
|
69
|
+
ctx.textual.success_text(f"Branch {branch_to_use} is already up to date with {remote_to_use}")
|
|
70
|
+
ctx.textual.end_step("success")
|
|
71
|
+
return Skip(
|
|
72
|
+
"Branch already pushed",
|
|
73
|
+
metadata={"pr_head_branch": branch_to_use}
|
|
74
|
+
)
|
|
75
|
+
case ClientError():
|
|
76
|
+
# If we can't count, proceed with push anyway
|
|
77
|
+
pass
|
|
63
78
|
case ClientError(error_message=err):
|
|
64
79
|
ctx.textual.end_step("error")
|
|
65
80
|
return Error(f"Failed to check remote branch: {err}")
|
{titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-git/titan_plugin_git/steps/status_step.py
RENAMED
|
@@ -16,7 +16,9 @@ def get_git_status_step(ctx: WorkflowContext) -> WorkflowResult:
|
|
|
16
16
|
|
|
17
17
|
Behavior:
|
|
18
18
|
- If there are uncommitted changes: Returns Success and continues workflow
|
|
19
|
-
- If working directory is clean: Returns Exit
|
|
19
|
+
- If working directory is clean: Returns Exit — nothing to commit.
|
|
20
|
+
In nested workflows (e.g. commit-ai called from create-pr-ai), the engine
|
|
21
|
+
converts Exit to Success so the parent workflow continues normally.
|
|
20
22
|
|
|
21
23
|
Requires:
|
|
22
24
|
ctx.git: An initialized GitClient.
|
|
@@ -26,7 +28,7 @@ def get_git_status_step(ctx: WorkflowContext) -> WorkflowResult:
|
|
|
26
28
|
|
|
27
29
|
Returns:
|
|
28
30
|
Success: If there are changes to commit (workflow continues)
|
|
29
|
-
Exit: If working directory is clean (
|
|
31
|
+
Exit: If working directory is clean (stops commit workflow; parent continues)
|
|
30
32
|
Error: If the GitClient is not available or the git command fails.
|
|
31
33
|
"""
|
|
32
34
|
if not ctx.textual:
|
|
@@ -54,13 +56,12 @@ def get_git_status_step(ctx: WorkflowContext) -> WorkflowResult:
|
|
|
54
56
|
metadata={"git_status": status}
|
|
55
57
|
)
|
|
56
58
|
else:
|
|
57
|
-
# Working directory is clean
|
|
59
|
+
# Working directory is clean — nothing to commit, exit early.
|
|
60
|
+
# If commit-ai is nested inside another workflow (e.g. create-pr-ai),
|
|
61
|
+
# the engine converts this Exit to Success so the parent continues.
|
|
58
62
|
ctx.textual.success_text(msg.Steps.Status.WORKING_DIRECTORY_IS_CLEAN)
|
|
59
|
-
ctx.textual.text("")
|
|
60
|
-
ctx.textual.dim_text("Nothing to commit. Skipping workflow.")
|
|
61
63
|
ctx.textual.end_step("success")
|
|
62
64
|
|
|
63
|
-
# Exit workflow early (not an error)
|
|
64
65
|
return Exit("No changes to commit", metadata={"git_status": status})
|
|
65
66
|
|
|
66
67
|
case ClientError(error_message=err):
|
|
@@ -215,6 +215,10 @@ class GitHubClient:
|
|
|
215
215
|
"""Reply to a PR comment."""
|
|
216
216
|
return self._review_service.reply_to_comment(pr_number, comment_id, body)
|
|
217
217
|
|
|
218
|
+
def get_pr_general_comments(self, pr_number: int) -> ClientResult[List[UICommentThread]]:
|
|
219
|
+
"""Get general PR comments (not attached to code lines)."""
|
|
220
|
+
return self._review_service.get_pr_general_comments(pr_number)
|
|
221
|
+
|
|
218
222
|
def add_issue_comment(self, pr_number: int, body: str) -> ClientResult[None]:
|
|
219
223
|
"""Add a general comment to PR (issue comment)."""
|
|
220
224
|
return self._review_service.add_issue_comment(pr_number, body)
|
|
@@ -44,6 +44,29 @@ query($owner: String!, $repo: String!, $prNumber: Int!) {
|
|
|
44
44
|
}
|
|
45
45
|
'''
|
|
46
46
|
|
|
47
|
+
GET_PR_ISSUE_COMMENTS = '''
|
|
48
|
+
query($owner: String!, $repo: String!, $prNumber: Int!) {
|
|
49
|
+
repository(owner: $owner, name: $repo) {
|
|
50
|
+
pullRequest(number: $prNumber) {
|
|
51
|
+
comments(first: 100) {
|
|
52
|
+
nodes {
|
|
53
|
+
databaseId
|
|
54
|
+
body
|
|
55
|
+
author {
|
|
56
|
+
login
|
|
57
|
+
... on User {
|
|
58
|
+
name
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
createdAt
|
|
62
|
+
updatedAt
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
'''
|
|
69
|
+
|
|
47
70
|
GET_PR_NODE_ID = '''
|
|
48
71
|
query($owner: String!, $repo: String!, $prNumber: Int!) {
|
|
49
72
|
repository(owner: $owner, name: $repo) {
|
|
@@ -6,14 +6,13 @@ Business logic for PR review operations.
|
|
|
6
6
|
Uses GraphQL for complex operations (threads, comments, resolve).
|
|
7
7
|
"""
|
|
8
8
|
import json
|
|
9
|
-
import subprocess
|
|
10
9
|
from typing import List, Optional, Dict, Any
|
|
11
10
|
|
|
12
11
|
from titan_cli.core.result import ClientResult, ClientSuccess, ClientError
|
|
13
12
|
from titan_cli.core.logging import log_client_operation
|
|
14
13
|
from ..network import GHNetwork, GraphQLNetwork, graphql_queries
|
|
15
14
|
from ...models.network.rest import NetworkReview
|
|
16
|
-
from ...models.network.graphql import GraphQLPullRequestReviewThread
|
|
15
|
+
from ...models.network.graphql import GraphQLPullRequestReviewThread, GraphQLIssueComment
|
|
17
16
|
from ...models.view import UICommentThread, UIReview
|
|
18
17
|
from ...models.mappers import from_graphql_review_thread, from_network_review
|
|
19
18
|
from ...exceptions import GitHubAPIError
|
|
@@ -106,6 +105,66 @@ class ReviewService:
|
|
|
106
105
|
except GitHubAPIError as e:
|
|
107
106
|
return ClientError(error_message=str(e), error_code="API_ERROR")
|
|
108
107
|
|
|
108
|
+
@log_client_operation()
|
|
109
|
+
def get_pr_general_comments(
|
|
110
|
+
self, pr_number: int
|
|
111
|
+
) -> ClientResult[List[UICommentThread]]:
|
|
112
|
+
"""
|
|
113
|
+
Get general PR comments (not attached to code lines).
|
|
114
|
+
|
|
115
|
+
Uses GraphQL to fetch top-level PR comments and wraps each one as
|
|
116
|
+
a pseudo-thread (thread_id = "general_{id}") for uniform rendering.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
pr_number: PR number
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
ClientResult[List[UICommentThread]]
|
|
123
|
+
"""
|
|
124
|
+
try:
|
|
125
|
+
repo_string = self.gh.get_repo_string()
|
|
126
|
+
owner, repo = repo_string.split('/')
|
|
127
|
+
|
|
128
|
+
variables = {
|
|
129
|
+
"owner": owner,
|
|
130
|
+
"repo": repo,
|
|
131
|
+
"prNumber": pr_number
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
response = self.graphql.run_query(
|
|
135
|
+
graphql_queries.GET_PR_ISSUE_COMMENTS,
|
|
136
|
+
variables
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
comments_data = (
|
|
140
|
+
response.get("data", {})
|
|
141
|
+
.get("repository", {})
|
|
142
|
+
.get("pullRequest", {})
|
|
143
|
+
.get("comments", {})
|
|
144
|
+
.get("nodes", [])
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
network_comments = [
|
|
148
|
+
GraphQLIssueComment.from_graphql(c) for c in comments_data
|
|
149
|
+
]
|
|
150
|
+
|
|
151
|
+
ui_threads = [
|
|
152
|
+
UICommentThread.from_issue_comment(c) for c in network_comments
|
|
153
|
+
]
|
|
154
|
+
|
|
155
|
+
return ClientSuccess(
|
|
156
|
+
data=ui_threads,
|
|
157
|
+
message=f"Found {len(ui_threads)} general comments"
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
except (KeyError, ValueError) as e:
|
|
161
|
+
return ClientError(
|
|
162
|
+
error_message=f"Failed to parse general comments: {e}",
|
|
163
|
+
error_code="PARSE_ERROR"
|
|
164
|
+
)
|
|
165
|
+
except GitHubAPIError as e:
|
|
166
|
+
return ClientError(error_message=str(e), error_code="API_ERROR")
|
|
167
|
+
|
|
109
168
|
@log_client_operation()
|
|
110
169
|
def resolve_review_thread(self, thread_node_id: str) -> ClientResult[None]:
|
|
111
170
|
"""
|
|
@@ -191,16 +250,9 @@ class ReviewService:
|
|
|
191
250
|
"--input", "-",
|
|
192
251
|
]
|
|
193
252
|
|
|
194
|
-
|
|
195
|
-
result = subprocess.run(
|
|
196
|
-
["gh"] + args,
|
|
197
|
-
input=json.dumps(payload),
|
|
198
|
-
capture_output=True,
|
|
199
|
-
text=True,
|
|
200
|
-
check=True,
|
|
201
|
-
)
|
|
253
|
+
result = self.gh.run_command(args, stdin_input=json.dumps(payload))
|
|
202
254
|
|
|
203
|
-
response = json.loads(result
|
|
255
|
+
response = json.loads(result)
|
|
204
256
|
review_id = response["id"]
|
|
205
257
|
|
|
206
258
|
return ClientSuccess(
|
|
@@ -213,11 +265,6 @@ class ReviewService:
|
|
|
213
265
|
error_message=f"Failed to parse review response: {e}",
|
|
214
266
|
error_code="PARSE_ERROR"
|
|
215
267
|
)
|
|
216
|
-
except subprocess.CalledProcessError as e:
|
|
217
|
-
return ClientError(
|
|
218
|
-
error_message=f"Failed to create draft review: gh API returned exit code {e.returncode}",
|
|
219
|
-
error_code="API_ERROR"
|
|
220
|
-
)
|
|
221
268
|
except GitHubAPIError as e:
|
|
222
269
|
return ClientError(error_message=str(e), error_code="API_ERROR")
|
|
223
270
|
|
{titan_cli-0.1.16 → titan_cli-0.2.0}/plugins/titan-plugin-github/titan_plugin_github/models/view.py
RENAMED
|
@@ -94,6 +94,36 @@ class UICommentThread:
|
|
|
94
94
|
from .mappers import from_graphql_review_thread
|
|
95
95
|
return from_graphql_review_thread(thread)
|
|
96
96
|
|
|
97
|
+
@classmethod
|
|
98
|
+
def from_issue_comment(cls, comment: 'Any') -> 'UICommentThread':
|
|
99
|
+
"""
|
|
100
|
+
Wrap a GraphQLIssueComment as a pseudo-thread for uniform rendering.
|
|
101
|
+
|
|
102
|
+
General PR comments have no thread concept, so they are wrapped in a
|
|
103
|
+
UICommentThread with a synthetic thread_id ("general_{id}") that
|
|
104
|
+
downstream code uses to distinguish them from review threads.
|
|
105
|
+
|
|
106
|
+
Args:
|
|
107
|
+
comment: GraphQLIssueComment instance from GraphQL
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
UICommentThread with thread_id="general_{id}", no replies, not resolved
|
|
111
|
+
"""
|
|
112
|
+
from .mappers import from_graphql_issue_comment
|
|
113
|
+
ui_comment = from_graphql_issue_comment(comment)
|
|
114
|
+
return cls(
|
|
115
|
+
thread_id=f"general_{comment.databaseId}",
|
|
116
|
+
main_comment=ui_comment,
|
|
117
|
+
replies=[],
|
|
118
|
+
is_resolved=False,
|
|
119
|
+
is_outdated=False
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def is_general_comment(self) -> bool:
|
|
124
|
+
"""True if this thread wraps a general PR comment (not an inline review thread)."""
|
|
125
|
+
return self.thread_id.startswith("general_")
|
|
126
|
+
|
|
97
127
|
|
|
98
128
|
@dataclass
|
|
99
129
|
class UIPullRequest:
|
|
@@ -14,6 +14,7 @@ Modules:
|
|
|
14
14
|
|
|
15
15
|
from .comment_operations import (
|
|
16
16
|
build_ai_review_context,
|
|
17
|
+
build_ai_review_prompt,
|
|
17
18
|
find_ai_response_file,
|
|
18
19
|
create_commit_message,
|
|
19
20
|
reply_to_comment_batch,
|
|
@@ -22,6 +23,7 @@ from .comment_operations import (
|
|
|
22
23
|
|
|
23
24
|
from .pr_operations import (
|
|
24
25
|
fetch_pr_threads,
|
|
26
|
+
fetch_pr_general_comments,
|
|
25
27
|
)
|
|
26
28
|
|
|
27
29
|
from .worktree_operations import (
|
|
@@ -44,6 +46,7 @@ from .issue_operations import (
|
|
|
44
46
|
__all__ = [
|
|
45
47
|
# Comment operations
|
|
46
48
|
"build_ai_review_context",
|
|
49
|
+
"build_ai_review_prompt",
|
|
47
50
|
"find_ai_response_file",
|
|
48
51
|
"create_commit_message",
|
|
49
52
|
"reply_to_comment_batch",
|
|
@@ -51,6 +54,7 @@ __all__ = [
|
|
|
51
54
|
|
|
52
55
|
# PR operations
|
|
53
56
|
"fetch_pr_threads",
|
|
57
|
+
"fetch_pr_general_comments",
|
|
54
58
|
|
|
55
59
|
# Worktree operations
|
|
56
60
|
"setup_worktree",
|
|
@@ -35,13 +35,6 @@ def build_ai_review_context(
|
|
|
35
35
|
"diff_hunk": str (acotado),
|
|
36
36
|
"thread": [{"author": str, "date": str, "body": str}, ...]
|
|
37
37
|
}
|
|
38
|
-
|
|
39
|
-
Example:
|
|
40
|
-
>>> context = build_ai_review_context(pr_thread, "feat: Add feature")
|
|
41
|
-
>>> context['pr']
|
|
42
|
-
'feat: Add feature'
|
|
43
|
-
>>> len(context['diff_hunk'].split('\\n'))
|
|
44
|
-
11 # ~11 lines instead of 200+
|
|
45
38
|
"""
|
|
46
39
|
main_comment = pr_thread.main_comment
|
|
47
40
|
|
|
@@ -93,11 +86,6 @@ def find_ai_response_file(comment_id: int, expected_path: str) -> Optional[str]:
|
|
|
93
86
|
|
|
94
87
|
Returns:
|
|
95
88
|
Path to the found file, or None if not found
|
|
96
|
-
|
|
97
|
-
Example:
|
|
98
|
-
>>> path = find_ai_response_file(123, "/tmp/titan-ai-response-comment-123.txt")
|
|
99
|
-
>>> path
|
|
100
|
-
'/home/user/.gemini/tmp/.../titan-ai-response-comment-123.txt'
|
|
101
89
|
"""
|
|
102
90
|
# Try expected location first
|
|
103
91
|
if os.path.exists(expected_path):
|
|
@@ -145,6 +133,56 @@ def create_commit_message(comment_body: str, comment_author: str, comment_path:
|
|
|
145
133
|
return message
|
|
146
134
|
|
|
147
135
|
|
|
136
|
+
def build_ai_review_prompt(response_file: str) -> str:
|
|
137
|
+
"""
|
|
138
|
+
Build the prompt template for AI review of a PR comment thread.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
response_file: Path where the AI should write text responses
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Prompt string with {context} placeholder for the JSON context
|
|
145
|
+
"""
|
|
146
|
+
return f"""Review this PR comment thread:
|
|
147
|
+
|
|
148
|
+
```json
|
|
149
|
+
{{context}}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Your Task
|
|
153
|
+
|
|
154
|
+
1. **First, evaluate if the review comment makes sense:**
|
|
155
|
+
- Is the feedback valid and applicable to the current code?
|
|
156
|
+
- Is the requested change appropriate?
|
|
157
|
+
- Could previous attempts have already addressed this (check the thread conversation)?
|
|
158
|
+
|
|
159
|
+
2. **Then, based on your evaluation:**
|
|
160
|
+
- **If the comment makes sense**: Make the necessary code changes to address it
|
|
161
|
+
- **If the comment doesn't make sense or is outdated**:
|
|
162
|
+
* DO NOT make code changes
|
|
163
|
+
* Write your explanation/response EXACTLY to this file path: {response_file}
|
|
164
|
+
* IMPORTANT: Use this exact command to write the response:
|
|
165
|
+
```bash
|
|
166
|
+
cat > {response_file} << 'EOF'
|
|
167
|
+
Your response text here
|
|
168
|
+
EOF
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Response Style (CRITICAL)
|
|
172
|
+
- **Keep responses SHORT and CONCISE** (maximum 2-3 sentences)
|
|
173
|
+
- **Be direct and to the point** - no verbose explanations
|
|
174
|
+
- **Avoid multiple paragraphs** - use a single short paragraph
|
|
175
|
+
- **Don't over-explain** - state the key point clearly and move on
|
|
176
|
+
- Example GOOD: "This is intentional. The logic handles X at layer Y, ensuring Z."
|
|
177
|
+
- Example BAD: Long multi-paragraph explanations with bullet points and detailed justifications
|
|
178
|
+
|
|
179
|
+
Note: Review the entire conversation thread carefully - previous fix attempts may have failed or been incomplete.
|
|
180
|
+
|
|
181
|
+
## When You're Done
|
|
182
|
+
Once you have completed your single action (code fix OR written the response file), tell the user:
|
|
183
|
+
"Done. Press Ctrl+C twice to exit and return to Titan." """
|
|
184
|
+
|
|
185
|
+
|
|
148
186
|
def prepare_replies_for_sending(
|
|
149
187
|
pending_responses: Dict[int, Dict],
|
|
150
188
|
comment_commits: Dict[int, str],
|
|
@@ -202,12 +240,6 @@ def reply_to_comment_batch(
|
|
|
202
240
|
|
|
203
241
|
Returns:
|
|
204
242
|
Dictionary mapping comment_id -> success (bool)
|
|
205
|
-
|
|
206
|
-
Example:
|
|
207
|
-
>>> replies = {123: "Fixed", 456: "Done"}
|
|
208
|
-
>>> results = reply_to_comment_batch(github, 789, replies)
|
|
209
|
-
>>> results
|
|
210
|
-
{123: True, 456: True}
|
|
211
243
|
"""
|
|
212
244
|
results = {}
|
|
213
245
|
|
|
@@ -10,6 +10,55 @@ from titan_cli.core.result import ClientSuccess, ClientError
|
|
|
10
10
|
from ..models.view import UICommentThread
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
def fetch_pr_general_comments(
|
|
14
|
+
github_client,
|
|
15
|
+
pr_number: int,
|
|
16
|
+
) -> List[UICommentThread]:
|
|
17
|
+
"""
|
|
18
|
+
Fetch general PR comments (not attached to code lines).
|
|
19
|
+
|
|
20
|
+
Filters out:
|
|
21
|
+
- Bot comments
|
|
22
|
+
- Empty comments
|
|
23
|
+
- JSON-only comments (coverage reports, CI badges, etc.)
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
github_client: GitHub client instance
|
|
27
|
+
pr_number: PR number
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
List of UICommentThread pseudo-threads (thread_id starts with "general_")
|
|
31
|
+
|
|
32
|
+
Raises:
|
|
33
|
+
Exception: If fetching comments fails
|
|
34
|
+
"""
|
|
35
|
+
result = github_client.get_pr_general_comments(pr_number)
|
|
36
|
+
|
|
37
|
+
match result:
|
|
38
|
+
case ClientSuccess(data=threads):
|
|
39
|
+
all_threads = threads
|
|
40
|
+
case ClientError(error_message=err):
|
|
41
|
+
raise Exception(f"Failed to fetch general comments: {err}")
|
|
42
|
+
case _:
|
|
43
|
+
raise Exception("Unexpected result type")
|
|
44
|
+
|
|
45
|
+
filtered = []
|
|
46
|
+
for thread in all_threads:
|
|
47
|
+
comment = thread.main_comment
|
|
48
|
+
if not comment:
|
|
49
|
+
continue
|
|
50
|
+
if comment.author_login and 'bot' in comment.author_login.lower():
|
|
51
|
+
continue
|
|
52
|
+
if not comment.body or not comment.body.strip():
|
|
53
|
+
continue
|
|
54
|
+
body_stripped = comment.body.strip()
|
|
55
|
+
if body_stripped.startswith('{') and body_stripped.endswith('}'):
|
|
56
|
+
continue
|
|
57
|
+
filtered.append(thread)
|
|
58
|
+
|
|
59
|
+
return filtered
|
|
60
|
+
|
|
61
|
+
|
|
13
62
|
def fetch_pr_threads(
|
|
14
63
|
github_client,
|
|
15
64
|
pr_number: int,
|
|
@@ -34,13 +83,6 @@ def fetch_pr_threads(
|
|
|
34
83
|
|
|
35
84
|
Raises:
|
|
36
85
|
Exception: If fetching threads fails
|
|
37
|
-
|
|
38
|
-
Example:
|
|
39
|
-
>>> threads = fetch_pr_threads(github, 123, include_resolved=False)
|
|
40
|
-
>>> len(threads)
|
|
41
|
-
5
|
|
42
|
-
>>> all(not t.is_resolved for t in threads)
|
|
43
|
-
True
|
|
44
86
|
"""
|
|
45
87
|
# Fetch all threads using GraphQL
|
|
46
88
|
result = github_client.get_pr_review_threads(
|