mcp-ticketer 0.1.33__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.33 → mcp_ticketer-0.1.34}/CHANGELOG.md +34 -0
  2. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/PKG-INFO +1 -1
  3. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/__version__.py +1 -1
  4. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/diagnostics.py +10 -2
  5. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/main.py +96 -5
  6. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/utils.py +36 -2
  7. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/config.py +53 -31
  8. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/env_discovery.py +27 -7
  9. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/PKG-INFO +1 -1
  10. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/.dependency_cache +0 -0
  11. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/.mpm_deployment_state +0 -0
  12. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/agent-manager.md +0 -0
  13. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/agentic-coder-optimizer.md +0 -0
  14. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/api_qa.md +0 -0
  15. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/clerk-ops.md +0 -0
  16. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/code_analyzer.md +0 -0
  17. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/content-agent.md +0 -0
  18. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/dart_engineer.md +0 -0
  19. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/data_engineer.md +0 -0
  20. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/documentation.md +0 -0
  21. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/engineer.md +0 -0
  22. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/gcp_ops_agent.md +0 -0
  23. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/golang_engineer.md +0 -0
  24. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/imagemagick.md +0 -0
  25. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/java_engineer.md +0 -0
  26. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/local_ops_agent.md +0 -0
  27. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/memory_manager.md +0 -0
  28. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/nextjs_engineer.md +0 -0
  29. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/ops.md +0 -0
  30. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/php-engineer.md +0 -0
  31. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/product_owner.md +0 -0
  32. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/project_organizer.md +0 -0
  33. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/prompt-engineer.md +0 -0
  34. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/python_engineer.md +0 -0
  35. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/qa.md +0 -0
  36. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/react_engineer.md +0 -0
  37. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/refactoring_engineer.md +0 -0
  38. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/research.md +0 -0
  39. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/ruby-engineer.md +0 -0
  40. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/rust_engineer.md +0 -0
  41. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/security.md +0 -0
  42. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/ticketing.md +0 -0
  43. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/typescript_engineer.md +0 -0
  44. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/vercel_ops_agent.md +0 -0
  45. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/version_control.md +0 -0
  46. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/web_qa.md +0 -0
  47. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/agents/web_ui.md +0 -0
  48. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/mcp.json +0 -0
  49. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude/mcp.local.json +0 -0
  50. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/config/project.json +0 -0
  51. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/mcp_auto_config_preference.json +0 -0
  52. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/README.md +0 -0
  53. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/agentic_coder_optimizer_memories.md +0 -0
  54. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/documentation_memories.md +0 -0
  55. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/engineer_memories.md +0 -0
  56. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/ops_memories.md +0 -0
  57. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/project_knowledge_memories.md +0 -0
  58. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/qa_memories.md +0 -0
  59. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/research_memories.md +0 -0
  60. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/version-control_memories.md +0 -0
  61. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude-mpm/memories/workflows_memories.md +0 -0
  62. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.claude.json +0 -0
  63. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.coveragerc +0 -0
  64. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.env.example +0 -0
  65. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.github/workflows/docs.yml +0 -0
  66. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.github/workflows/publish.yml +0 -0
  67. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.github/workflows/test.yml +0 -0
  68. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.mcp/config.json +0 -0
  69. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.pre-commit-config.yaml +0 -0
  70. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.python-version +0 -0
  71. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/.readthedocs.yaml +0 -0
  72. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/CLAUDE.md +0 -0
  73. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/CLAUDE_DESKTOP_SETUP.md +0 -0
  74. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/CODEX_INTEGRATION.md +0 -0
  75. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/CODE_STRUCTURE.md +0 -0
  76. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/CONFIG_RESOLUTION_FIX.md +0 -0
  77. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/CONTRIBUTING.md +0 -0
  78. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/CREDENTIAL_VALIDATION_FIX.md +0 -0
  79. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/DIAGNOSTICS_FEATURE.md +0 -0
  80. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/ENV_DISCOVERY_COMPLETE.md +0 -0
  81. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/FIX_SUMMARY.md +0 -0
  82. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/HIERARCHY_IMPLEMENTATION_SUMMARY.md +0 -0
  83. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/IMPLEMENTATION_SUMMARY.md +0 -0
  84. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/JIRA_SETUP.md +0 -0
  85. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/LICENSE +0 -0
  86. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/LINEAR_SETUP.md +0 -0
  87. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/MANIFEST.in +0 -0
  88. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/MCP_CONFIGURATION_TEST_REPORT.md +0 -0
  89. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/Makefile +0 -0
  90. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/OPTIMIZATION_SUMMARY.md +0 -0
  91. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/PROJECT_INITIALIZATION_SUMMARY.md +0 -0
  92. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/QUEUE_SYSTEM.md +0 -0
  93. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/QUICK_START.md +0 -0
  94. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/README.md +0 -0
  95. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/RELEASE.md +0 -0
  96. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/RELEASING.md +0 -0
  97. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/SECURITY_SCAN_REPORT_v0.1.24.md +0 -0
  98. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/TEST_COVERAGE_REPORT.md +0 -0
  99. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/TEST_REPORT.md +0 -0
  100. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/TEST_RESULTS_SUMMARY.md +0 -0
  101. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/VERIFICATION_RESULTS.md +0 -0
  102. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/claude-desktop-config.json +0 -0
  103. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/debug_search.py +0 -0
  104. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/debug_test.py +0 -0
  105. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/ADAPTERS.md +0 -0
  106. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/AI_CLIENT_INTEGRATION.md +0 -0
  107. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/API_REFERENCE.md +0 -0
  108. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/CONFIGURATION.md +0 -0
  109. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/CONFIG_RESOLUTION_FLOW.md +0 -0
  110. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/DEVELOPER_GUIDE.md +0 -0
  111. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/ENV_DISCOVERY.md +0 -0
  112. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/MCP_INTEGRATION.md +0 -0
  113. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/MIGRATION_GUIDE.md +0 -0
  114. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/PROJECT_CONFIG.md +0 -0
  115. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/PR_INTEGRATION.md +0 -0
  116. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/QUICK_START_ENV.md +0 -0
  117. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/USER_GUIDE.md +0 -0
  118. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_archive/README.md +0 -0
  119. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/ADAPTERS.md.txt +0 -0
  120. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/API_REFERENCE.md.txt +0 -0
  121. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/CONFIGURATION.md.txt +0 -0
  122. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/DEVELOPER_GUIDE.md.txt +0 -0
  123. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/MCP_INTEGRATION.md.txt +0 -0
  124. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/MIGRATION_GUIDE.md.txt +0 -0
  125. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/USER_GUIDE.md.txt +0 -0
  126. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/adapters/github.md.txt +0 -0
  127. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/adapters.rst.txt +0 -0
  128. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/api.rst.txt +0 -0
  129. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/cli.rst.txt +0 -0
  130. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/development.rst.txt +0 -0
  131. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/examples.rst.txt +0 -0
  132. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/index.rst.txt +0 -0
  133. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/installation.rst.txt +0 -0
  134. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/_build/_sources/prd/mcp-ticketer-prd.md.txt +0 -0
  135. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/adapters/github.md +0 -0
  136. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/adapters.rst +0 -0
  137. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/api.rst +0 -0
  138. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/cli.rst +0 -0
  139. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/conf.py +0 -0
  140. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/development.rst +0 -0
  141. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/examples.rst +0 -0
  142. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/index.rst +0 -0
  143. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/installation.rst +0 -0
  144. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/prd/mcp-ticketer-prd.md +0 -0
  145. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/docs/requirements.txt +0 -0
  146. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/install.sh +0 -0
  147. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/mcp-ticketer +0 -0
  148. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/mcp-ticketer-server +0 -0
  149. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/mcp_server.sh +0 -0
  150. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/pyproject.toml +0 -0
  151. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/pytest.ini +0 -0
  152. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/requirements-dev.txt +0 -0
  153. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/requirements.txt +0 -0
  154. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/scripts/README.md +0 -0
  155. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/scripts/manage_version.py +0 -0
  156. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/setup.cfg +0 -0
  157. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/setup.py +0 -0
  158. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/__init__.py +0 -0
  159. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/__init__.py +0 -0
  160. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/aitrackdown.py +0 -0
  161. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/github.py +0 -0
  162. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/hybrid.py +0 -0
  163. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/jira.py +0 -0
  164. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/adapters/linear.py +0 -0
  165. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cache/__init__.py +0 -0
  166. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cache/memory.py +0 -0
  167. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/__init__.py +0 -0
  168. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/auggie_configure.py +0 -0
  169. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/codex_configure.py +0 -0
  170. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/configure.py +0 -0
  171. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/discover.py +0 -0
  172. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/gemini_configure.py +0 -0
  173. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/mcp_configure.py +0 -0
  174. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/migrate_config.py +0 -0
  175. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/queue_commands.py +0 -0
  176. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/cli/simple_health.py +0 -0
  177. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/__init__.py +0 -0
  178. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/adapter.py +0 -0
  179. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/http_client.py +0 -0
  180. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/mappers.py +0 -0
  181. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/models.py +0 -0
  182. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/project_config.py +0 -0
  183. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/core/registry.py +0 -0
  184. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/mcp/__init__.py +0 -0
  185. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/mcp/server.py +0 -0
  186. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/py.typed +0 -0
  187. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/__init__.py +0 -0
  188. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/__main__.py +0 -0
  189. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/health_monitor.py +0 -0
  190. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/manager.py +0 -0
  191. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/queue.py +0 -0
  192. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/run_worker.py +0 -0
  193. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/ticket_registry.py +0 -0
  194. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer/queue/worker.py +0 -0
  195. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/SOURCES.txt +0 -0
  196. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/dependency_links.txt +0 -0
  197. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/entry_points.txt +0 -0
  198. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/not-zip-safe +0 -0
  199. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/requires.txt +0 -0
  200. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/src/mcp_ticketer.egg-info/top_level.txt +0 -0
  201. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test-tickets/tickets/task-20250924002724.json +0 -0
  202. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_all_adapters.py +0 -0
  203. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_api_usage.py +0 -0
  204. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_basic.py +0 -0
  205. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_codex_config.py +0 -0
  206. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_comprehensive.py +0 -0
  207. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_config_resolution.py +0 -0
  208. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_credential_validation.py +0 -0
  209. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_error_handling.py +0 -0
  210. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_github.py +0 -0
  211. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_github_token.py +0 -0
  212. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_jira.py +0 -0
  213. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_linear.py +0 -0
  214. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_linear_native.py +0 -0
  215. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_linear_teams.py +0 -0
  216. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_mcp_server_qa.py +0 -0
  217. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_optimizations.py +0 -0
  218. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_performance.py +0 -0
  219. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_pr_functionality.py +0 -0
  220. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_queue_system.py +0 -0
  221. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_serve_config.py +0 -0
  222. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/test_set_command.sh +0 -0
  223. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/adapters/__init__.py +0 -0
  224. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/adapters/test_aitrackdown.py +0 -0
  225. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/conftest.py +0 -0
  226. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/core/test_env_discovery.py +0 -0
  227. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/e2e/test_complete_workflow.py +0 -0
  228. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/e2e/test_hierarchy_validation.py +0 -0
  229. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/e2e/test_state_transitions.py +0 -0
  230. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/test_base_adapter.py +0 -0
  231. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/test_models.py +0 -0
  232. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tests/test_queue.py +0 -0
  233. {mcp_ticketer-0.1.33 → mcp_ticketer-0.1.34}/tox.ini +0 -0
@@ -6,6 +6,40 @@ 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
+
9
43
  ## [0.1.31] - 2025-10-24
10
44
 
11
45
  ### Fixed
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-ticketer
3
- Version: 0.1.33
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.33"
3
+ __version__ = "0.1.34"
4
4
  __version_info__ = tuple(int(part) for part in __version__.split("."))
5
5
 
6
6
  # Package metadata
@@ -252,7 +252,9 @@ class SystemDiagnostics:
252
252
  for name, adapter_config in adapters.items():
253
253
  try:
254
254
  adapter_class = AdapterRegistry.get_adapter(adapter_config.type.value)
255
- 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)
256
258
 
257
259
  # Test adapter validation if available
258
260
  if hasattr(adapter, 'validate_credentials'):
@@ -305,7 +307,13 @@ class SystemDiagnostics:
305
307
  config_dict = adapter_config
306
308
  else:
307
309
  adapter_type = adapter_config.type.value if hasattr(adapter_config, 'type') else "unknown"
308
- config_dict = adapter_config.dict() if hasattr(adapter_config, 'dict') else adapter_config
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
309
317
 
310
318
  details = {
311
319
  "type": adapter_type,
@@ -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"}}
@@ -118,9 +118,17 @@ class LinearConfig(BaseAdapterConfig):
118
118
  type: AdapterType = AdapterType.LINEAR
119
119
  api_key: Optional[str] = Field(None, env="LINEAR_API_KEY")
120
120
  workspace: Optional[str] = None
121
- team_key: str
121
+ team_key: Optional[str] = None # Short team key like "BTA"
122
+ team_id: Optional[str] = None # UUID team identifier
122
123
  api_url: str = "https://api.linear.app/graphql"
123
124
 
125
+ @model_validator(mode="after")
126
+ def validate_team_identifier(self):
127
+ """Ensure either team_key or team_id is provided."""
128
+ if not self.team_key and not self.team_id:
129
+ raise ValueError("Either team_key or team_id is required")
130
+ return self
131
+
124
132
  @field_validator("api_key", mode="before")
125
133
  @classmethod
126
134
  def validate_api_key(cls, v):
@@ -284,9 +292,27 @@ class ConfigurationManager:
284
292
  config_data = self._load_config_file(self._config_file_paths[0])
285
293
  logger.info(f"Loaded configuration from: {self._config_file_paths[0]}")
286
294
  else:
287
- # No config file found - try environment discovery
288
- logger.info("No configuration file found, attempting environment discovery")
289
- config_data = self._discover_from_environment()
295
+ # No config file found - use empty config
296
+ config_data = {"adapters": {}, "default_adapter": None}
297
+
298
+ # Always try environment discovery and merge with file-based config
299
+ logger.info("Attempting environment discovery to supplement configuration")
300
+ env_config_data = self._discover_from_environment()
301
+
302
+ # Merge environment-discovered adapters with file-based config
303
+ if env_config_data and "adapters" in env_config_data:
304
+ if "adapters" not in config_data:
305
+ config_data["adapters"] = {}
306
+
307
+ # Add discovered adapters that aren't already configured
308
+ for adapter_name, adapter_config in env_config_data["adapters"].items():
309
+ if adapter_name not in config_data["adapters"]:
310
+ config_data["adapters"][adapter_name] = adapter_config
311
+ logger.info(f"Added environment-discovered adapter: {adapter_name}")
312
+
313
+ # Set default adapter if not already set
314
+ if not config_data.get("default_adapter") and env_config_data.get("default_adapter"):
315
+ config_data["default_adapter"] = env_config_data["default_adapter"]
290
316
 
291
317
  # Parse adapter configurations
292
318
  if "adapters" in config_data:
@@ -294,13 +320,21 @@ class ConfigurationManager:
294
320
  for name, adapter_config in config_data["adapters"].items():
295
321
  adapter_type = adapter_config.get("type", "").lower()
296
322
 
323
+ # If no type specified, try to infer from adapter name
324
+ if not adapter_type:
325
+ adapter_type = name.lower()
326
+
297
327
  if adapter_type == "github":
328
+ adapter_config["type"] = "github"
298
329
  parsed_adapters[name] = GitHubConfig(**adapter_config)
299
330
  elif adapter_type == "jira":
331
+ adapter_config["type"] = "jira"
300
332
  parsed_adapters[name] = JiraConfig(**adapter_config)
301
333
  elif adapter_type == "linear":
334
+ adapter_config["type"] = "linear"
302
335
  parsed_adapters[name] = LinearConfig(**adapter_config)
303
336
  elif adapter_type == "aitrackdown":
337
+ adapter_config["type"] = "aitrackdown"
304
338
  parsed_adapters[name] = AITrackdownConfig(**adapter_config)
305
339
  else:
306
340
  logger.warning(
@@ -335,10 +369,10 @@ class ConfigurationManager:
335
369
  def _discover_from_environment(self) -> dict[str, Any]:
336
370
  """Discover configuration from environment variables."""
337
371
  try:
338
- from .env_discovery import EnvironmentDiscovery
372
+ from .env_discovery import EnvDiscovery
339
373
 
340
- discovery = EnvironmentDiscovery()
341
- discovered = discovery.discover_all()
374
+ discovery = EnvDiscovery()
375
+ discovered = discovery.discover()
342
376
 
343
377
  if not discovered.adapters:
344
378
  logger.info("No adapters discovered from environment variables")
@@ -362,36 +396,24 @@ class ConfigurationManager:
362
396
 
363
397
  for adapter in discovered.adapters:
364
398
  adapter_config = {
365
- "type": adapter.type.value,
399
+ "type": adapter.adapter_type,
366
400
  "enabled": True
367
401
  }
368
402
 
369
- # Add adapter-specific configuration
370
- if adapter.type.value == "linear":
371
- adapter_config.update({
372
- "api_key": adapter.credentials.get("api_key"),
373
- "team_id": adapter.credentials.get("team_id"),
374
- "project_id": adapter.credentials.get("project_id")
375
- })
376
- elif adapter.type.value == "github":
377
- adapter_config.update({
378
- "token": adapter.credentials.get("token"),
379
- "repo": adapter.credentials.get("repo"),
380
- "owner": adapter.credentials.get("owner")
381
- })
382
- elif adapter.type.value == "jira":
383
- adapter_config.update({
384
- "server": adapter.credentials.get("server"),
385
- "email": adapter.credentials.get("email"),
386
- "api_token": adapter.credentials.get("api_token"),
387
- "project_key": adapter.credentials.get("project_key")
388
- })
389
-
390
- config_data["adapters"][adapter.name] = adapter_config
403
+ # Add adapter-specific configuration from discovered config
404
+ adapter_config.update(adapter.config)
405
+
406
+ # Ensure type is set correctly (remove 'adapter' key if present)
407
+ if 'adapter' in adapter_config:
408
+ del adapter_config['adapter']
409
+
410
+ # Use adapter type as the key name
411
+ adapter_name = adapter.adapter_type
412
+ config_data["adapters"][adapter_name] = adapter_config
391
413
 
392
414
  # Set first discovered adapter as default
393
415
  if config_data["default_adapter"] is None:
394
- config_data["default_adapter"] = adapter.name
416
+ config_data["default_adapter"] = adapter.adapter_type
395
417
 
396
418
  logger.info(f"Discovered {len(config_data['adapters'])} adapter(s) from environment")
397
419
  return config_data
@@ -30,8 +30,10 @@ LINEAR_KEY_PATTERNS = [
30
30
 
31
31
  LINEAR_TEAM_PATTERNS = [
32
32
  "LINEAR_TEAM_ID",
33
+ "LINEAR_TEAM_KEY", # Added support for team key (e.g., "BTA")
33
34
  "LINEAR_TEAM",
34
35
  "MCP_TICKETER_LINEAR_TEAM_ID",
36
+ "MCP_TICKETER_LINEAR_TEAM_KEY",
35
37
  ]
36
38
 
37
39
  LINEAR_PROJECT_PATTERNS = [
@@ -210,7 +212,11 @@ class EnvDiscovery:
210
212
  return result
211
213
 
212
214
  def _load_env_files(self, result: DiscoveryResult) -> dict[str, str]:
213
- """Load environment variables from files.
215
+ """Load environment variables from files and actual environment.
216
+
217
+ Priority order (highest to lowest):
218
+ 1. .env files (highest priority)
219
+ 2. Environment variables (lowest priority)
214
220
 
215
221
  Args:
216
222
  result: DiscoveryResult to update with found files
@@ -221,7 +227,15 @@ class EnvDiscovery:
221
227
  """
222
228
  merged_env: dict[str, str] = {}
223
229
 
224
- # Load files in reverse order (lowest priority first)
230
+ # First, load from actual environment variables (lowest priority)
231
+ import os
232
+ actual_env = {k: v for k, v in os.environ.items() if v}
233
+ merged_env.update(actual_env)
234
+ if actual_env:
235
+ result.env_files_found.append("environment")
236
+ logger.debug(f"Loaded {len(actual_env)} variables from environment")
237
+
238
+ # Load files in reverse order (higher priority than environment)
225
239
  for env_file in reversed(self.ENV_FILE_ORDER):
226
240
  file_path = self.project_path / env_file
227
241
  if file_path.exists():
@@ -282,13 +296,19 @@ class EnvDiscovery:
282
296
  missing_fields: list[str] = []
283
297
  confidence = 0.6 # Has API key
284
298
 
285
- # Extract team ID (recommended but not required)
286
- team_id = self._find_key_value(env_vars, LINEAR_TEAM_PATTERNS)
287
- if team_id:
288
- config["team_id"] = team_id
299
+ # Extract team identifier (either team_id or team_key is required)
300
+ team_identifier = self._find_key_value(env_vars, LINEAR_TEAM_PATTERNS)
301
+ if team_identifier:
302
+ # Determine if it's a team_id (UUID format) or team_key (short string)
303
+ if len(team_identifier) > 20 and '-' in team_identifier:
304
+ # Looks like a UUID (team_id)
305
+ config["team_id"] = team_identifier
306
+ else:
307
+ # Looks like a short key (team_key)
308
+ config["team_key"] = team_identifier
289
309
  confidence += 0.3
290
310
  else:
291
- missing_fields.append("team_id (recommended)")
311
+ missing_fields.append("team_id or team_key (required)")
292
312
 
293
313
  # Extract project ID (optional)
294
314
  project_id = self._find_key_value(env_vars, LINEAR_PROJECT_PATTERNS)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-ticketer
3
- Version: 0.1.33
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>
File without changes
File without changes