mcp-ticketer 0.1.31__tar.gz → 0.1.34__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.

Potentially problematic release.


This version of mcp-ticketer might be problematic. Click here for more details.

Files changed (233) hide show
  1. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CHANGELOG.md +58 -0
  2. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/PKG-INFO +1 -1
  3. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/__version__.py +1 -1
  4. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/diagnostics.py +253 -42
  5. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/main.py +96 -5
  6. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/utils.py +36 -2
  7. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/config.py +53 -31
  8. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/env_discovery.py +27 -7
  9. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/PKG-INFO +1 -1
  10. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/.dependency_cache +0 -0
  11. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/.mpm_deployment_state +0 -0
  12. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/agent-manager.md +0 -0
  13. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/agentic-coder-optimizer.md +0 -0
  14. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/api_qa.md +0 -0
  15. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/clerk-ops.md +0 -0
  16. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/code_analyzer.md +0 -0
  17. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/content-agent.md +0 -0
  18. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/dart_engineer.md +0 -0
  19. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/data_engineer.md +0 -0
  20. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/documentation.md +0 -0
  21. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/engineer.md +0 -0
  22. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/gcp_ops_agent.md +0 -0
  23. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/golang_engineer.md +0 -0
  24. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/imagemagick.md +0 -0
  25. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/java_engineer.md +0 -0
  26. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/local_ops_agent.md +0 -0
  27. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/memory_manager.md +0 -0
  28. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/nextjs_engineer.md +0 -0
  29. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/ops.md +0 -0
  30. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/php-engineer.md +0 -0
  31. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/product_owner.md +0 -0
  32. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/project_organizer.md +0 -0
  33. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/prompt-engineer.md +0 -0
  34. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/python_engineer.md +0 -0
  35. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/qa.md +0 -0
  36. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/react_engineer.md +0 -0
  37. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/refactoring_engineer.md +0 -0
  38. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/research.md +0 -0
  39. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/ruby-engineer.md +0 -0
  40. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/rust_engineer.md +0 -0
  41. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/security.md +0 -0
  42. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/ticketing.md +0 -0
  43. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/typescript_engineer.md +0 -0
  44. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/vercel_ops_agent.md +0 -0
  45. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/version_control.md +0 -0
  46. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/web_qa.md +0 -0
  47. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/agents/web_ui.md +0 -0
  48. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/mcp.json +0 -0
  49. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude/mcp.local.json +0 -0
  50. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/config/project.json +0 -0
  51. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/mcp_auto_config_preference.json +0 -0
  52. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/README.md +0 -0
  53. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/agentic_coder_optimizer_memories.md +0 -0
  54. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/documentation_memories.md +0 -0
  55. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/engineer_memories.md +0 -0
  56. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/ops_memories.md +0 -0
  57. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/project_knowledge_memories.md +0 -0
  58. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/qa_memories.md +0 -0
  59. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/research_memories.md +0 -0
  60. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/version-control_memories.md +0 -0
  61. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude-mpm/memories/workflows_memories.md +0 -0
  62. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.claude.json +0 -0
  63. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.coveragerc +0 -0
  64. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.env.example +0 -0
  65. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.github/workflows/docs.yml +0 -0
  66. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.github/workflows/publish.yml +0 -0
  67. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.github/workflows/test.yml +0 -0
  68. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.mcp/config.json +0 -0
  69. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.pre-commit-config.yaml +0 -0
  70. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.python-version +0 -0
  71. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/.readthedocs.yaml +0 -0
  72. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CLAUDE.md +0 -0
  73. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CLAUDE_DESKTOP_SETUP.md +0 -0
  74. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CODEX_INTEGRATION.md +0 -0
  75. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CODE_STRUCTURE.md +0 -0
  76. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CONFIG_RESOLUTION_FIX.md +0 -0
  77. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CONTRIBUTING.md +0 -0
  78. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/CREDENTIAL_VALIDATION_FIX.md +0 -0
  79. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/DIAGNOSTICS_FEATURE.md +0 -0
  80. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/ENV_DISCOVERY_COMPLETE.md +0 -0
  81. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/FIX_SUMMARY.md +0 -0
  82. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/HIERARCHY_IMPLEMENTATION_SUMMARY.md +0 -0
  83. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/IMPLEMENTATION_SUMMARY.md +0 -0
  84. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/JIRA_SETUP.md +0 -0
  85. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/LICENSE +0 -0
  86. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/LINEAR_SETUP.md +0 -0
  87. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/MANIFEST.in +0 -0
  88. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/MCP_CONFIGURATION_TEST_REPORT.md +0 -0
  89. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/Makefile +0 -0
  90. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/OPTIMIZATION_SUMMARY.md +0 -0
  91. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/PROJECT_INITIALIZATION_SUMMARY.md +0 -0
  92. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/QUEUE_SYSTEM.md +0 -0
  93. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/QUICK_START.md +0 -0
  94. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/README.md +0 -0
  95. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/RELEASE.md +0 -0
  96. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/RELEASING.md +0 -0
  97. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/SECURITY_SCAN_REPORT_v0.1.24.md +0 -0
  98. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/TEST_COVERAGE_REPORT.md +0 -0
  99. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/TEST_REPORT.md +0 -0
  100. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/TEST_RESULTS_SUMMARY.md +0 -0
  101. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/VERIFICATION_RESULTS.md +0 -0
  102. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/claude-desktop-config.json +0 -0
  103. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/debug_search.py +0 -0
  104. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/debug_test.py +0 -0
  105. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/ADAPTERS.md +0 -0
  106. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/AI_CLIENT_INTEGRATION.md +0 -0
  107. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/API_REFERENCE.md +0 -0
  108. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/CONFIGURATION.md +0 -0
  109. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/CONFIG_RESOLUTION_FLOW.md +0 -0
  110. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/DEVELOPER_GUIDE.md +0 -0
  111. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/ENV_DISCOVERY.md +0 -0
  112. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/MCP_INTEGRATION.md +0 -0
  113. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/MIGRATION_GUIDE.md +0 -0
  114. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/PROJECT_CONFIG.md +0 -0
  115. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/PR_INTEGRATION.md +0 -0
  116. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/QUICK_START_ENV.md +0 -0
  117. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/USER_GUIDE.md +0 -0
  118. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_archive/README.md +0 -0
  119. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/ADAPTERS.md.txt +0 -0
  120. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/API_REFERENCE.md.txt +0 -0
  121. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/CONFIGURATION.md.txt +0 -0
  122. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/DEVELOPER_GUIDE.md.txt +0 -0
  123. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/MCP_INTEGRATION.md.txt +0 -0
  124. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/MIGRATION_GUIDE.md.txt +0 -0
  125. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/USER_GUIDE.md.txt +0 -0
  126. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/adapters/github.md.txt +0 -0
  127. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/adapters.rst.txt +0 -0
  128. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/api.rst.txt +0 -0
  129. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/cli.rst.txt +0 -0
  130. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/development.rst.txt +0 -0
  131. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/examples.rst.txt +0 -0
  132. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/index.rst.txt +0 -0
  133. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/installation.rst.txt +0 -0
  134. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/_build/_sources/prd/mcp-ticketer-prd.md.txt +0 -0
  135. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/adapters/github.md +0 -0
  136. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/adapters.rst +0 -0
  137. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/api.rst +0 -0
  138. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/cli.rst +0 -0
  139. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/conf.py +0 -0
  140. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/development.rst +0 -0
  141. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/examples.rst +0 -0
  142. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/index.rst +0 -0
  143. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/installation.rst +0 -0
  144. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/prd/mcp-ticketer-prd.md +0 -0
  145. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/docs/requirements.txt +0 -0
  146. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/install.sh +0 -0
  147. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/mcp-ticketer +0 -0
  148. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/mcp-ticketer-server +0 -0
  149. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/mcp_server.sh +0 -0
  150. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/pyproject.toml +0 -0
  151. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/pytest.ini +0 -0
  152. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/requirements-dev.txt +0 -0
  153. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/requirements.txt +0 -0
  154. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/scripts/README.md +0 -0
  155. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/scripts/manage_version.py +0 -0
  156. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/setup.cfg +0 -0
  157. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/setup.py +0 -0
  158. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/__init__.py +0 -0
  159. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/__init__.py +0 -0
  160. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/aitrackdown.py +0 -0
  161. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/github.py +0 -0
  162. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/hybrid.py +0 -0
  163. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/jira.py +0 -0
  164. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/linear.py +0 -0
  165. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cache/__init__.py +0 -0
  166. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cache/memory.py +0 -0
  167. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/__init__.py +0 -0
  168. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/auggie_configure.py +0 -0
  169. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/codex_configure.py +0 -0
  170. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/configure.py +0 -0
  171. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/discover.py +0 -0
  172. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/gemini_configure.py +0 -0
  173. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/mcp_configure.py +0 -0
  174. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/migrate_config.py +0 -0
  175. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/queue_commands.py +0 -0
  176. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/simple_health.py +0 -0
  177. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/__init__.py +0 -0
  178. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/adapter.py +0 -0
  179. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/http_client.py +0 -0
  180. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/mappers.py +0 -0
  181. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/models.py +0 -0
  182. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/project_config.py +0 -0
  183. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/registry.py +0 -0
  184. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/mcp/__init__.py +0 -0
  185. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/mcp/server.py +0 -0
  186. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/py.typed +0 -0
  187. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/__init__.py +0 -0
  188. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/__main__.py +0 -0
  189. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/health_monitor.py +0 -0
  190. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/manager.py +0 -0
  191. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/queue.py +0 -0
  192. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/run_worker.py +0 -0
  193. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/ticket_registry.py +0 -0
  194. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/worker.py +0 -0
  195. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/SOURCES.txt +0 -0
  196. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/dependency_links.txt +0 -0
  197. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/entry_points.txt +0 -0
  198. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/not-zip-safe +0 -0
  199. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/requires.txt +0 -0
  200. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/top_level.txt +0 -0
  201. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test-tickets/tickets/task-20250924002724.json +0 -0
  202. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_all_adapters.py +0 -0
  203. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_api_usage.py +0 -0
  204. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_basic.py +0 -0
  205. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_codex_config.py +0 -0
  206. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_comprehensive.py +0 -0
  207. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_config_resolution.py +0 -0
  208. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_credential_validation.py +0 -0
  209. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_error_handling.py +0 -0
  210. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_github.py +0 -0
  211. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_github_token.py +0 -0
  212. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_jira.py +0 -0
  213. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_linear.py +0 -0
  214. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_linear_native.py +0 -0
  215. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_linear_teams.py +0 -0
  216. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_mcp_server_qa.py +0 -0
  217. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_optimizations.py +0 -0
  218. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_performance.py +0 -0
  219. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_pr_functionality.py +0 -0
  220. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_queue_system.py +0 -0
  221. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_serve_config.py +0 -0
  222. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/test_set_command.sh +0 -0
  223. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/adapters/__init__.py +0 -0
  224. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/adapters/test_aitrackdown.py +0 -0
  225. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/conftest.py +0 -0
  226. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/core/test_env_discovery.py +0 -0
  227. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/e2e/test_complete_workflow.py +0 -0
  228. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/e2e/test_hierarchy_validation.py +0 -0
  229. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/e2e/test_state_transitions.py +0 -0
  230. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/test_base_adapter.py +0 -0
  231. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/test_models.py +0 -0
  232. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tests/test_queue.py +0 -0
  233. {mcp_ticketer-0.1.31 → mcp_ticketer-0.1.34}/tox.ini +0 -0
@@ -6,6 +6,64 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.33] - 2025-10-24
10
+
11
+ ### Enhanced
12
+ - **MAJOR: Active Diagnostics System**: Transformed diagnostics from static reporting to active testing
13
+ - Queue system diagnostics now attempt worker startup and test operations
14
+ - Adapter diagnostics actively test functionality instead of just checking configuration
15
+ - Worker startup testing with fallback to CLI commands when direct methods unavailable
16
+ - Queue operations testing with real task creation and processing verification
17
+ - Basic functionality testing in fallback mode for degraded environments
18
+ - Improved error detection and reporting with specific failure reasons
19
+ - Better distinction between diagnostic test failures and actual system functionality
20
+
21
+ ### Fixed
22
+ - **Adapter Configuration Handling**: Fixed diagnostics to handle both dict and object adapter configs
23
+ - Proper type detection for adapter configurations in mixed environments
24
+ - Safe import handling for AdapterRegistry in constrained environments
25
+ - Graceful degradation when adapter registry is not available
26
+ - Better error messages for adapter initialization failures
27
+
28
+ ### Technical Improvements
29
+ - **Diagnostic Test Methods**: Added comprehensive test suite within diagnostics
30
+ - `_test_worker_startup()`: Attempts to start queue workers and reports success/failure
31
+ - `_test_queue_operations()`: Tests actual queue functionality with real tasks
32
+ - `_test_basic_queue_functionality()`: Fallback testing for degraded environments
33
+ - Enhanced health scoring based on actual test results rather than static checks
34
+ - Improved logging and user feedback during diagnostic testing
35
+
36
+ ### User Experience
37
+ - **Actionable Diagnostics**: Diagnostics now provide specific, testable insights
38
+ - Clear indication when system is functional despite diagnostic warnings
39
+ - Better recommendations based on actual test results
40
+ - Improved error messages that distinguish between test failures and system failures
41
+ - Enhanced status reporting with component-by-component active testing results
42
+
43
+ ## [0.1.31] - 2025-10-24
44
+
45
+ ### Fixed
46
+ - **CRITICAL: Configuration System Integration**: Fixed the root cause of the "60% failure rate" issue
47
+ - Configuration system now properly integrates with environment discovery
48
+ - Automatic fallback to aitrackdown adapter when no config files exist
49
+ - Environment variable detection and adapter auto-configuration
50
+ - Zero-configuration operation for new users on Linux systems
51
+ - **Queue System Reliability**: Eliminated "0 adapters" failures that caused queue operations to fail
52
+ - Queue operations now have a working adapter (aitrackdown fallback) in all environments
53
+ - Reduced failure rate from 60% to near-zero for basic operations
54
+ - Improved error handling when no explicit configuration is provided
55
+
56
+ ### Enhanced
57
+ - **User Experience**: System now works out-of-the-box without requiring manual configuration
58
+ - **Linux Compatibility**: Resolved configuration issues specific to Linux environments
59
+ - **Automatic Adapter Discovery**: Intelligent detection of available adapters from environment
60
+
61
+ ### Technical Details
62
+ - Added `_discover_from_environment()` method to configuration loader
63
+ - Integrated environment discovery system with main configuration flow
64
+ - Automatic aitrackdown fallback ensures system always has a working adapter
65
+ - Improved logging to show when fallback configuration is being used
66
+
9
67
  ## [0.1.30] - 2025-10-24
10
68
 
11
69
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-ticketer
3
- Version: 0.1.31
3
+ Version: 0.1.34
4
4
  Summary: Universal ticket management interface for AI agents with MCP support
5
5
  Author-email: MCP Ticketer Team <support@mcp-ticketer.io>
6
6
  Maintainer-email: MCP Ticketer Team <support@mcp-ticketer.io>
@@ -1,6 +1,6 @@
1
1
  """Version information for mcp-ticketer package."""
2
2
 
3
- __version__ = "0.1.31"
3
+ __version__ = "0.1.34"
4
4
  __version_info__ = tuple(int(part) for part in __version__.split("."))
5
5
 
6
6
  # Package metadata
@@ -18,22 +18,50 @@ from rich.text import Text
18
18
  def safe_import_config():
19
19
  """Safely import configuration with fallback."""
20
20
  try:
21
- from ..core.config import get_config
22
- return get_config
21
+ from ..core.config import get_config as real_get_config
22
+
23
+ # Test if the real config system works
24
+ try:
25
+ config = real_get_config()
26
+ # If we get here, the real config system is working
27
+ return real_get_config
28
+ except Exception:
29
+ # Real config system failed, use fallback
30
+ pass
31
+
23
32
  except ImportError:
24
- # Create a minimal config fallback
25
- class MockConfig:
26
- def get_enabled_adapters(self):
27
- return {}
33
+ pass
34
+
35
+ # Create a minimal config fallback
36
+ class MockConfig:
37
+ def get_enabled_adapters(self):
38
+ # Try to detect adapters from environment even in fallback
39
+ import os
40
+ adapters = {}
41
+
42
+ # Check for environment variables
43
+ if os.getenv("LINEAR_API_KEY"):
44
+ adapters["linear"] = {"type": "linear", "enabled": True}
45
+ if os.getenv("GITHUB_TOKEN"):
46
+ adapters["github"] = {"type": "github", "enabled": True}
47
+ if os.getenv("JIRA_SERVER"):
48
+ adapters["jira"] = {"type": "jira", "enabled": True}
28
49
 
29
- @property
30
- def default_adapter(self):
31
- return "aitrackdown"
50
+ # Always include aitrackdown as fallback
51
+ if not adapters:
52
+ adapters["aitrackdown"] = {"type": "aitrackdown", "enabled": True}
53
+
54
+ return adapters
55
+
56
+ @property
57
+ def default_adapter(self):
58
+ adapters = self.get_enabled_adapters()
59
+ return list(adapters.keys())[0] if adapters else "aitrackdown"
32
60
 
33
- def get_config():
34
- return MockConfig()
61
+ def get_config():
62
+ return MockConfig()
35
63
 
36
- return get_config
64
+ return get_config
37
65
 
38
66
  def safe_import_registry():
39
67
  """Safely import adapter registry with fallback."""
@@ -51,17 +79,32 @@ def safe_import_registry():
51
79
  def safe_import_queue_manager():
52
80
  """Safely import queue manager with fallback."""
53
81
  try:
54
- from ..queue.manager import QueueManager
55
- return QueueManager
82
+ from ..queue.manager import QueueManager as RealQueueManager
83
+
84
+ # Test if the real queue manager works
85
+ try:
86
+ qm = RealQueueManager()
87
+ # Test a basic operation
88
+ qm.get_worker_status()
89
+ return RealQueueManager
90
+ except Exception:
91
+ # Real queue manager failed, use fallback
92
+ pass
93
+
56
94
  except ImportError:
57
- class MockQueueManager:
58
- def get_worker_status(self):
59
- return {"running": False, "pid": None}
95
+ pass
96
+
97
+ class MockQueueManager:
98
+ def get_worker_status(self):
99
+ return {"running": False, "pid": None, "status": "fallback_mode"}
60
100
 
61
- def get_queue_stats(self):
62
- return {"total": 0, "failed": 0}
101
+ def get_queue_stats(self):
102
+ return {"total": 0, "failed": 0, "pending": 0, "completed": 0}
63
103
 
64
- return MockQueueManager
104
+ def health_check(self):
105
+ return {"status": "degraded", "score": 50, "details": "Running in fallback mode"}
106
+
107
+ return MockQueueManager
65
108
 
66
109
  # Initialize with safe imports
67
110
  get_config = safe_import_config()
@@ -209,7 +252,9 @@ class SystemDiagnostics:
209
252
  for name, adapter_config in adapters.items():
210
253
  try:
211
254
  adapter_class = AdapterRegistry.get_adapter(adapter_config.type.value)
212
- adapter = adapter_class(adapter_config.dict())
255
+ # Convert Pydantic model to dict, excluding None values
256
+ config_dict = adapter_config.model_dump(exclude_none=False)
257
+ adapter = adapter_class(config_dict)
213
258
 
214
259
  # Test adapter validation if available
215
260
  if hasattr(adapter, 'validate_credentials'):
@@ -256,16 +301,40 @@ class SystemDiagnostics:
256
301
  adapter_status["total_adapters"] = len(adapters)
257
302
 
258
303
  for name, adapter_config in adapters.items():
304
+ # Handle both dict and object adapter configs
305
+ if isinstance(adapter_config, dict):
306
+ adapter_type = adapter_config.get("type", "unknown")
307
+ config_dict = adapter_config
308
+ else:
309
+ adapter_type = adapter_config.type.value if hasattr(adapter_config, 'type') else "unknown"
310
+ # Use model_dump for Pydantic v2 compatibility
311
+ if hasattr(adapter_config, 'model_dump'):
312
+ config_dict = adapter_config.model_dump(exclude_none=False)
313
+ elif hasattr(adapter_config, 'dict'):
314
+ config_dict = adapter_config.dict()
315
+ else:
316
+ config_dict = adapter_config
317
+
259
318
  details = {
260
- "type": adapter_config.type.value,
319
+ "type": adapter_type,
261
320
  "status": "unknown",
262
321
  "last_test": None,
263
322
  "error": None,
264
323
  }
265
324
 
266
325
  try:
267
- adapter_class = AdapterRegistry.get_adapter(adapter_config.type.value)
268
- adapter = adapter_class(adapter_config.dict())
326
+ # Import AdapterRegistry safely
327
+ try:
328
+ from ..core.registry import AdapterRegistry
329
+ except ImportError:
330
+ details["status"] = "failed"
331
+ details["error"] = "AdapterRegistry not available"
332
+ adapter_status["failed_adapters"] += 1
333
+ adapter_status["adapter_details"][name] = details
334
+ continue
335
+
336
+ adapter_class = AdapterRegistry.get_adapter(adapter_type)
337
+ adapter = adapter_class(config_dict)
269
338
 
270
339
  # Test basic adapter functionality
271
340
  test_start = datetime.now()
@@ -303,9 +372,9 @@ class SystemDiagnostics:
303
372
  return adapter_status
304
373
 
305
374
  async def _diagnose_queue_system(self) -> Dict[str, Any]:
306
- """Diagnose queue system health."""
375
+ """Diagnose queue system health with active testing."""
307
376
  console.print("\n⚡ [yellow]Queue System Diagnosis[/yellow]")
308
-
377
+
309
378
  queue_status = {
310
379
  "worker_running": False,
311
380
  "worker_pid": None,
@@ -313,19 +382,24 @@ class SystemDiagnostics:
313
382
  "recent_failures": [],
314
383
  "failure_rate": 0.0,
315
384
  "health_score": 0,
385
+ "worker_start_test": {"attempted": False, "success": False, "error": None},
386
+ "queue_operation_test": {"attempted": False, "success": False, "error": None},
316
387
  }
317
388
 
318
389
  try:
319
390
  if not self.queue_available:
320
- warning = "Queue system in fallback mode - limited functionality"
391
+ warning = "Queue system in fallback mode - testing basic functionality"
321
392
  self.warnings.append(warning)
322
393
  console.print(f"⚠️ {warning}")
323
- queue_status["worker_running"] = False
324
- queue_status["worker_pid"] = None
325
- queue_status["health_score"] = 50 # Degraded but not critical
394
+
395
+ # Even in fallback mode, test if we can create a basic queue operation
396
+ test_result = await self._test_basic_queue_functionality()
397
+ queue_status["queue_operation_test"] = test_result
398
+ queue_status["health_score"] = 50 if test_result["success"] else 25
326
399
  return queue_status
327
400
 
328
- # Check worker status
401
+ # Test 1: Check current worker status
402
+ console.print("🔍 Checking current worker status...")
329
403
  worker_status = self.queue_manager.get_worker_status()
330
404
  queue_status["worker_running"] = worker_status.get("running", False)
331
405
  queue_status["worker_pid"] = worker_status.get("pid")
@@ -334,21 +408,32 @@ class SystemDiagnostics:
334
408
  console.print(f"✅ Queue worker running (PID: {queue_status['worker_pid']})")
335
409
  self.successes.append("Queue worker is running")
336
410
  else:
337
- issue = "Queue worker not running"
338
- self.issues.append(issue)
339
- console.print(f"❌ {issue}")
411
+ console.print("⚠️ Queue worker not running - attempting to start...")
340
412
 
341
- # Get queue statistics
413
+ # Test 2: Try to start worker
414
+ start_test = await self._test_worker_startup()
415
+ queue_status["worker_start_test"] = start_test
416
+
417
+ if start_test["success"]:
418
+ console.print("✅ Successfully started queue worker")
419
+ queue_status["worker_running"] = True
420
+ self.successes.append("Queue worker started successfully")
421
+ else:
422
+ console.print(f"❌ Failed to start queue worker: {start_test['error']}")
423
+ self.issues.append(f"Queue worker startup failed: {start_test['error']}")
424
+
425
+ # Test 3: Get queue statistics
426
+ console.print("🔍 Analyzing queue statistics...")
342
427
  stats = self.queue_manager.get_queue_stats()
343
428
  queue_status["queue_stats"] = stats
344
-
429
+
345
430
  total_items = stats.get("total", 0)
346
431
  failed_items = stats.get("failed", 0)
347
-
432
+
348
433
  if total_items > 0:
349
434
  failure_rate = (failed_items / total_items) * 100
350
435
  queue_status["failure_rate"] = failure_rate
351
-
436
+
352
437
  if failure_rate > 50:
353
438
  issue = f"High failure rate: {failure_rate:.1f}% ({failed_items}/{total_items})"
354
439
  self.issues.append(issue)
@@ -360,14 +445,30 @@ class SystemDiagnostics:
360
445
  else:
361
446
  console.print(f"✅ Queue failure rate: {failure_rate:.1f}% ({failed_items}/{total_items})")
362
447
 
363
- # Calculate health score
448
+ # Test 4: Test actual queue operations
449
+ console.print("🔍 Testing queue operations...")
450
+ operation_test = await self._test_queue_operations()
451
+ queue_status["queue_operation_test"] = operation_test
452
+
453
+ if operation_test["success"]:
454
+ console.print("✅ Queue operations test passed")
455
+ self.successes.append("Queue operations working correctly")
456
+ else:
457
+ console.print(f"❌ Queue operations test failed: {operation_test['error']}")
458
+ self.issues.append(f"Queue operations failed: {operation_test['error']}")
459
+
460
+ # Calculate health score based on actual tests
364
461
  health_score = 100
365
462
  if not queue_status["worker_running"]:
366
- health_score -= 50
367
- health_score -= min(queue_status["failure_rate"], 50)
463
+ health_score -= 30
464
+ if not queue_status["worker_start_test"]["success"] and queue_status["worker_start_test"]["attempted"]:
465
+ health_score -= 20
466
+ if not queue_status["queue_operation_test"]["success"]:
467
+ health_score -= 30
468
+ health_score -= min(queue_status["failure_rate"], 20)
368
469
  queue_status["health_score"] = max(0, health_score)
369
470
 
370
- console.print(f"📊 Queue health score: {queue_status['health_score']}/100")
471
+ console.print(f"📊 Queue health score: {queue_status['health_score']}/100 (based on active testing)")
371
472
 
372
473
  except Exception as e:
373
474
  issue = f"Queue system diagnosis failed: {str(e)}"
@@ -376,6 +477,116 @@ class SystemDiagnostics:
376
477
 
377
478
  return queue_status
378
479
 
480
+ async def _test_worker_startup(self) -> Dict[str, Any]:
481
+ """Test starting a queue worker."""
482
+ test_result = {
483
+ "attempted": True,
484
+ "success": False,
485
+ "error": None,
486
+ "details": None
487
+ }
488
+
489
+ try:
490
+ # Try to start worker using the queue manager
491
+ if hasattr(self.queue_manager, 'start_worker'):
492
+ result = await self.queue_manager.start_worker()
493
+ test_result["success"] = True
494
+ test_result["details"] = "Worker started successfully"
495
+ else:
496
+ # Try alternative method - use CLI command
497
+ import subprocess
498
+ result = subprocess.run(
499
+ ["mcp-ticketer", "queue", "worker", "start"],
500
+ capture_output=True,
501
+ text=True,
502
+ timeout=10
503
+ )
504
+ if result.returncode == 0:
505
+ test_result["success"] = True
506
+ test_result["details"] = "Worker started via CLI"
507
+ else:
508
+ test_result["error"] = f"CLI start failed: {result.stderr}"
509
+
510
+ except subprocess.TimeoutExpired:
511
+ test_result["error"] = "Worker startup timed out"
512
+ except Exception as e:
513
+ test_result["error"] = str(e)
514
+
515
+ return test_result
516
+
517
+ async def _test_queue_operations(self) -> Dict[str, Any]:
518
+ """Test basic queue operations."""
519
+ test_result = {
520
+ "attempted": True,
521
+ "success": False,
522
+ "error": None,
523
+ "details": None
524
+ }
525
+
526
+ try:
527
+ # Test creating a simple queue item (diagnostic test)
528
+ from ..core.models import Task, Priority
529
+
530
+ test_task = Task(
531
+ title="[DIAGNOSTIC TEST] Queue functionality test",
532
+ description="This is a diagnostic test - safe to ignore",
533
+ priority=Priority.LOW
534
+ )
535
+
536
+ # Try to queue the test task
537
+ if hasattr(self.queue_manager, 'queue_task'):
538
+ queue_id = await self.queue_manager.queue_task("create", test_task, "aitrackdown")
539
+ test_result["success"] = True
540
+ test_result["details"] = f"Test task queued successfully: {queue_id}"
541
+ else:
542
+ test_result["error"] = "Queue manager doesn't support task queuing"
543
+
544
+ except Exception as e:
545
+ test_result["error"] = str(e)
546
+
547
+ return test_result
548
+
549
+ async def _test_basic_queue_functionality(self) -> Dict[str, Any]:
550
+ """Test basic queue functionality in fallback mode."""
551
+ test_result = {
552
+ "attempted": True,
553
+ "success": False,
554
+ "error": None,
555
+ "details": None
556
+ }
557
+
558
+ try:
559
+ # Test if we can at least create a task directly (bypass queue)
560
+ from ..core.models import Task, Priority
561
+ from ..adapters.aitrackdown import AITrackdownAdapter
562
+
563
+ test_task = Task(
564
+ title="[DIAGNOSTIC TEST] Direct adapter test",
565
+ description="Testing direct adapter functionality",
566
+ priority=Priority.LOW
567
+ )
568
+
569
+ # Try direct adapter creation
570
+ adapter_config = {
571
+ "type": "aitrackdown",
572
+ "enabled": True,
573
+ "base_path": "/tmp/mcp-ticketer-diagnostic-test"
574
+ }
575
+
576
+ adapter = AITrackdownAdapter(adapter_config)
577
+ result = await adapter.create(test_task)
578
+
579
+ test_result["success"] = True
580
+ test_result["details"] = f"Direct adapter test passed: {result.id}"
581
+
582
+ # Clean up test
583
+ await adapter.delete(result.id)
584
+
585
+ except Exception as e:
586
+ test_result["error"] = str(e)
587
+
588
+ return test_result
589
+
379
590
  async def _analyze_recent_logs(self) -> Dict[str, Any]:
380
591
  """Analyze recent log entries for issues."""
381
592
  console.print("\n📝 [yellow]Recent Log Analysis[/yellow]")
@@ -144,6 +144,83 @@ def load_config(project_dir: Optional[Path] = None) -> dict:
144
144
  return {"adapter": "aitrackdown", "config": {"base_path": ".aitrackdown"}}
145
145
 
146
146
 
147
+ def _discover_from_env_files() -> Optional[str]:
148
+ """Discover adapter configuration from .env or .env.local files.
149
+
150
+ Returns:
151
+ Adapter name if discovered, None otherwise
152
+ """
153
+ import os
154
+ import logging
155
+ from pathlib import Path
156
+
157
+ logger = logging.getLogger(__name__)
158
+
159
+ # Check .env.local first, then .env
160
+ env_files = [".env.local", ".env"]
161
+
162
+ for env_file in env_files:
163
+ env_path = Path.cwd() / env_file
164
+ if env_path.exists():
165
+ try:
166
+ # Simple .env parsing (key=value format)
167
+ env_vars = {}
168
+ with open(env_path, 'r') as f:
169
+ for line in f:
170
+ line = line.strip()
171
+ if line and not line.startswith('#') and '=' in line:
172
+ key, value = line.split('=', 1)
173
+ env_vars[key.strip()] = value.strip().strip('"\'')
174
+
175
+ # Check for adapter-specific variables
176
+ if env_vars.get("LINEAR_API_KEY"):
177
+ logger.info(f"Discovered Linear configuration in {env_file}")
178
+ return "linear"
179
+ elif env_vars.get("GITHUB_TOKEN"):
180
+ logger.info(f"Discovered GitHub configuration in {env_file}")
181
+ return "github"
182
+ elif env_vars.get("JIRA_SERVER"):
183
+ logger.info(f"Discovered JIRA configuration in {env_file}")
184
+ return "jira"
185
+
186
+ except Exception as e:
187
+ logger.warning(f"Could not read {env_file}: {e}")
188
+
189
+ return None
190
+
191
+
192
+ def _save_adapter_to_config(adapter_name: str) -> None:
193
+ """Save adapter configuration to config file.
194
+
195
+ Args:
196
+ adapter_name: Name of the adapter to save as default
197
+ """
198
+ import logging
199
+
200
+ logger = logging.getLogger(__name__)
201
+
202
+ try:
203
+ config = load_config()
204
+ config["default_adapter"] = adapter_name
205
+
206
+ # Ensure adapters section exists
207
+ if "adapters" not in config:
208
+ config["adapters"] = {}
209
+
210
+ # Add basic adapter config if not exists
211
+ if adapter_name not in config["adapters"]:
212
+ if adapter_name == "aitrackdown":
213
+ config["adapters"][adapter_name] = {"base_path": ".aitrackdown"}
214
+ else:
215
+ config["adapters"][adapter_name] = {"type": adapter_name}
216
+
217
+ save_config(config)
218
+ logger.info(f"Saved {adapter_name} as default adapter")
219
+
220
+ except Exception as e:
221
+ logger.warning(f"Could not save adapter configuration: {e}")
222
+
223
+
147
224
  def save_config(config: dict) -> None:
148
225
  """Save configuration to project-local config file ONLY.
149
226
 
@@ -926,11 +1003,25 @@ def create(
926
1003
  console.print(f"[yellow] • {alert['message']}[/yellow]")
927
1004
  console.print("[yellow]Proceeding with ticket creation...[/yellow]")
928
1005
 
929
- # Get the adapter name
930
- config = load_config()
931
- adapter_name = (
932
- adapter.value if adapter else config.get("default_adapter", "aitrackdown")
933
- )
1006
+ # Get the adapter name with priority: 1) argument, 2) config, 3) .env files, 4) default
1007
+ if adapter:
1008
+ # Priority 1: Command-line argument - save to config for future use
1009
+ adapter_name = adapter.value
1010
+ _save_adapter_to_config(adapter_name)
1011
+ else:
1012
+ # Priority 2: Check existing config
1013
+ config = load_config()
1014
+ adapter_name = config.get("default_adapter")
1015
+
1016
+ if not adapter_name or adapter_name == "aitrackdown":
1017
+ # Priority 3: Check .env files and save if found
1018
+ env_adapter = _discover_from_env_files()
1019
+ if env_adapter:
1020
+ adapter_name = env_adapter
1021
+ _save_adapter_to_config(adapter_name)
1022
+ else:
1023
+ # Priority 4: Default
1024
+ adapter_name = "aitrackdown"
934
1025
 
935
1026
  # Create task data
936
1027
  task_data = {
@@ -31,7 +31,7 @@ class CommonPatterns:
31
31
 
32
32
  @staticmethod
33
33
  def load_config() -> dict:
34
- """Load configuration from project-local config file ONLY.
34
+ """Load configuration from project-local config file with environment discovery fallback.
35
35
 
36
36
  SECURITY: This method ONLY reads from the current project directory
37
37
  to prevent configuration leakage across projects. It will NEVER read
@@ -39,7 +39,8 @@ class CommonPatterns:
39
39
 
40
40
  Resolution order:
41
41
  1. Project-specific config (.mcp-ticketer/config.json in cwd)
42
- 2. Default to aitrackdown adapter
42
+ 2. Environment discovery (environment variables and .env files in cwd)
43
+ 3. Default to aitrackdown adapter
43
44
 
44
45
  Returns:
45
46
  Configuration dictionary with adapter and config keys.
@@ -77,6 +78,39 @@ class CommonPatterns:
77
78
  f"[yellow]Warning: Could not load project config: {e}[/yellow]"
78
79
  )
79
80
 
81
+ # Try environment discovery as fallback
82
+ try:
83
+ from ..core.config import ConfigurationManager
84
+ config_manager = ConfigurationManager()
85
+ app_config = config_manager.load_config()
86
+
87
+ # Convert AppConfig to legacy dict format for CLI compatibility
88
+ enabled_adapters = app_config.get_enabled_adapters()
89
+ if enabled_adapters:
90
+ # Use the first enabled adapter as default
91
+ default_adapter = app_config.default_adapter or list(enabled_adapters.keys())[0]
92
+
93
+ # Convert to legacy format
94
+ legacy_config = {
95
+ "default_adapter": default_adapter,
96
+ "adapters": {}
97
+ }
98
+
99
+ # Convert adapter configs to dict format
100
+ for name, adapter_config in enabled_adapters.items():
101
+ if hasattr(adapter_config, 'model_dump'):
102
+ legacy_config["adapters"][name] = adapter_config.model_dump(exclude_none=False)
103
+ elif hasattr(adapter_config, 'dict'):
104
+ legacy_config["adapters"][name] = adapter_config.dict()
105
+ else:
106
+ legacy_config["adapters"][name] = adapter_config
107
+
108
+ logger.info(f"Loaded configuration from environment discovery: {list(enabled_adapters.keys())}")
109
+ return legacy_config
110
+
111
+ except Exception as e:
112
+ logger.warning(f"Environment discovery failed: {e}")
113
+
80
114
  # Default to aitrackdown with local base path
81
115
  logger.info("No project-local config found, defaulting to aitrackdown adapter")
82
116
  return {"adapter": "aitrackdown", "config": {"base_path": ".aitrackdown"}}