mcp-ticketer 0.4.4__tar.gz → 0.6.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of mcp-ticketer might be problematic. Click here for more details.
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.github/workflows/publish.yml +1 -1
- mcp_ticketer-0.6.2/BEFORE_AFTER_COMPARISON.md +271 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/CHANGELOG.md +77 -0
- mcp_ticketer-0.6.2/ENV_LOADING_FIX.md +134 -0
- mcp_ticketer-0.6.2/FINAL_SUMMARY.md +291 -0
- mcp_ticketer-0.6.2/FINAL_VERIFICATION_REPORT.md +507 -0
- mcp_ticketer-0.6.2/FIXES_v0.4.10.md +282 -0
- mcp_ticketer-0.6.2/FIX_DISCOVERED_FLAG_BUG.md +145 -0
- mcp_ticketer-0.6.2/FIX_VERIFICATION_CHECKLIST.md +185 -0
- mcp_ticketer-0.6.2/IMPLEMENTATION_SUMMARY.md +300 -0
- mcp_ticketer-0.6.2/LINEAR_BUG_FIX_SUMMARY_FINAL.md +196 -0
- mcp_ticketer-0.6.2/LINEAR_INIT_BUG_FIX.md +202 -0
- mcp_ticketer-0.6.2/LINEAR_INIT_FIX_SUMMARY.md +200 -0
- mcp_ticketer-0.6.2/MCP_CONFIGURE_FIX.md +227 -0
- mcp_ticketer-0.6.2/MCP_INSTALLER_FIX_COMPLETE.md +124 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/Makefile +16 -2
- {mcp_ticketer-0.4.4/src/mcp_ticketer.egg-info → mcp_ticketer-0.6.2}/PKG-INFO +84 -55
- mcp_ticketer-0.6.2/QA_REPORT_PLATFORM_DETECTION.md +509 -0
- mcp_ticketer-0.6.2/QA_TEST_REPORT.md +481 -0
- mcp_ticketer-0.6.2/QUALITY_GATE_REPORT.md +220 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/README.md +83 -53
- mcp_ticketer-0.6.2/TEST_RESULTS.txt +149 -0
- mcp_ticketer-0.6.2/VERIFICATION_COMPLETE.md +341 -0
- mcp_ticketer-0.6.2/VERIFICATION_REPORT.md +469 -0
- mcp_ticketer-0.6.2/VERIFICATION_SUMMARY.md +338 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/AI_CLIENT_INTEGRATION.md +318 -33
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/CONFIGURATION.md +31 -1
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/MIGRATION_GUIDE.md +126 -11
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/QUICK_START.md +130 -19
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/USER_GUIDE.md +48 -3
- mcp_ticketer-0.6.2/docs/features/AUTOMATIC_VALIDATION.md +184 -0
- mcp_ticketer-0.6.2/docs/features/UPDATE_CHECKING.md +223 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/guides/BULLETPROOF_TICKET_CREATION_GUIDE.md +4 -2
- mcp_ticketer-0.6.2/docs/linear_parent_issue_fix.md +212 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/CONFIG_RESOLUTION_FIX.md +9 -10
- mcp_ticketer-0.6.2/docs/reports/MCP_COMMAND_SIMPLIFICATION_UPDATE.md +253 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/setup/CLAUDE_DESKTOP_SETUP.md +16 -8
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/setup/CODEX_INTEGRATION.md +6 -3
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/setup/LINEAR_SETUP.md +119 -14
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/pyproject.toml +8 -5
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/__version__.py +1 -1
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/github.py +6 -6
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/linear/adapter.py +210 -12
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/linear/mappers.py +8 -2
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/adapter_diagnostics.py +1 -1
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/auggie_configure.py +38 -15
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/codex_configure.py +119 -31
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/gemini_configure.py +40 -25
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/linear_commands.py +89 -5
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/main.py +779 -61
- mcp_ticketer-0.6.2/src/mcp_ticketer/cli/mcp_configure.py +516 -0
- mcp_ticketer-0.6.2/src/mcp_ticketer/cli/platform_detection.py +412 -0
- mcp_ticketer-0.6.2/src/mcp_ticketer/cli/python_detection.py +126 -0
- mcp_ticketer-0.6.2/src/mcp_ticketer/cli/update_checker.py +313 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/utils.py +1 -1
- mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/__init__.py +33 -0
- mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/__main__.py +60 -0
- mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server/__init__.py +25 -0
- mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server/__main__.py +60 -0
- mcp_ticketer-0.4.4/src/mcp_ticketer/mcp/server.py → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server/main.py +24 -22
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/server_sdk.py +2 -2
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/attachment_tools.py +1 -1
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/bulk_tools.py +1 -1
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/comment_tools.py +1 -1
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/hierarchy_tools.py +1 -1
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/pr_tools.py +1 -1
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/search_tools.py +1 -1
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/ticket_tools.py +1 -1
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/__init__.py +1 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/manager.py +10 -46
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/ticket_registry.py +5 -5
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2/src/mcp_ticketer.egg-info}/PKG-INFO +84 -55
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer.egg-info/SOURCES.txt +53 -13
- mcp_ticketer-0.6.2/test_discovered_fix.py +234 -0
- mcp_ticketer-0.6.2/test_mcp_integration.py +312 -0
- mcp_ticketer-0.6.2/test_structure_validation.py +140 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/linear/test_adapter.py +23 -23
- mcp_ticketer-0.6.2/tests/adapters/linear/test_adapter_validation.py +183 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/linear/test_client.py +19 -19
- mcp_ticketer-0.6.2/tests/adapters/linear/test_issue_resolution.py +200 -0
- mcp_ticketer-0.6.2/tests/adapters/linear/test_project_resolution.py +295 -0
- mcp_ticketer-0.6.2/tests/cli/test_python_detection.py +147 -0
- mcp_ticketer-0.6.2/tests/cli/test_update_checker.py +237 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/conftest.py +24 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/test_actual_worker_execution.py +3 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/test_config_resolution.py +21 -47
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/test_env_discovery.py +24 -8
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/test_unified_env_loading.py +3 -0
- mcp_ticketer-0.6.2/tests/e2e/test_mcp_jsonrpc.py +548 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_all_adapters.py +5 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_base_adapter.py +4 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_codex_config.py +6 -9
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/unit/test_core_registry.py +2 -2
- mcp_ticketer-0.6.2/verify_fixes.sh +73 -0
- mcp_ticketer-0.4.4/src/mcp_ticketer/cli/mcp_configure.py +0 -371
- mcp_ticketer-0.4.4/src/mcp_ticketer/mcp/__init__.py +0 -5
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/comments/comment-20251024141042175430.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/comments/comment-20251024141042175768.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/comments/comment-20251024141042175888.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/comments/comment-20251024141042175987.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/comments/comment-20251024141042176075.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/comments/comment-20251024141042176163.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/tickets/task-20251024141042175062.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.aitrackdown-test/tickets/task-20251024141042175285.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.claude.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.coveragerc +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.cursor/mcp.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.env.example +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.github/workflows/docs.yml +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.github/workflows/test.yml +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.mcp/config.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.pre-commit-config.yaml +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.python-version +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/.readthedocs.yaml +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/CLAUDE.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/CLI_RESTRUCTURE_REPORT.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/CLI_RESTRUCTURE_TEST_REPORT.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/LICENSE +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/MANIFEST.in +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/PATH_TRAVERSAL_SECURITY_TEST_REPORT.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/SECURITY_RESCAN_REPORT.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/VERIFICATION_v0.4.3.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/debug_epic_creation.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/debug_full_flow.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/debug_worker_epic.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/ADAPTERS.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/API_REFERENCE.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/ATTACHMENTS.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/CONFIG_RESOLUTION_FLOW.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/DEVELOPER_GUIDE.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/ENV_DISCOVERY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/MCP_INTEGRATION.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/PROJECT_CONFIG.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/PR_INTEGRATION.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/QUEUE_SYSTEM.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/QUICK_START_ENV.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/README.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/VERSIONING_AND_BUILD_TRACKING.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_archive/README.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/ADAPTERS.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/API_REFERENCE.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/CONFIGURATION.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/DEVELOPER_GUIDE.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/MCP_INTEGRATION.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/MIGRATION_GUIDE.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/USER_GUIDE.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/adapters/github.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/adapters.rst.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/api.rst.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/cli.rst.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/development.rst.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/examples.rst.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/index.rst.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/installation.rst.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/_build/_sources/prd/mcp-ticketer-prd.md.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/adapters/github.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/adapters.rst +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/api.rst +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/changelogs/CHANGELOG_v0.2.0.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/changelogs/CHANGELOG_v0.3.0.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/changelogs/CHANGELOG_v0.3.1.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/cli.rst +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/conf.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/development/CODE_STRUCTURE.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/development/CONTRIBUTING.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/development/RELEASE.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/development/RELEASING.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/development.rst +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/examples.rst +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/index.rst +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/installation.rst +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/prd/mcp-ticketer-prd.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/PUBLICATION_GUIDE_v0.2.0.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/PUBLICATION_SUCCESS_v0.2.0.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/PUBLICATION_SUCCESS_v0.3.0.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/PUBLICATION_SUCCESS_v0.3.1.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/PUBLICATION_SUCCESS_v0.3.4.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/PUBLICATION_SUCCESS_v0.3.5.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/RELEASE_v0.1.39_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/releases/RELEASE_v0.2.0_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/CREDENTIAL_VALIDATION_FIX.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/DIAGNOSTICS_FEATURE.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/ENV_DISCOVERY_COMPLETE.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/FIX_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/HIERARCHY_IMPLEMENTATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/IMPLEMENTATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/MCP_CONFIGURATION_TEST_REPORT.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/OPTIMIZATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/PROJECT_INITIALIZATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/TEST_COVERAGE_REPORT.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/TEST_REPORT.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/TEST_RESULTS_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/reports/VERIFICATION_RESULTS.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/requirements.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/setup/JIRA_SETUP.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/AUTO_DISCOVERY_BUG_FIX_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/BULLETPROOF_IMPROVEMENTS_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/COMMAND_SYNONYMS_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/COMPREHENSIVE_TESTING_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/INTERACTIVE_CLI_SETUP_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/LINEAR_ADAPTER_INITIALIZATION_BUG_FIX.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/MODULE_REFACTORING_ANALYSIS.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/MODULE_REFACTORING_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/PROJECT_CLEANUP_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/docs/summaries/REFACTORED_ENV_SOLUTION_SUMMARY.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/mcp-ticketer +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/mcp-ticketer-server +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/pytest.ini +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/requirements-dev.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/requirements.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/scripts/README.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/scripts/install.sh +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/scripts/manage_version.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/scripts/mcp_server.sh +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/scripts/test_set_command.sh +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/setup.cfg +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/setup.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/aitrackdown.py +2 -2
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/hybrid.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/jira.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/linear/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/linear/client.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/linear/queries.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/linear/types.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/adapters/linear.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cache/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cache/memory.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/configure.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/diagnostics.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/discover.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/migrate_config.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/platform_commands.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/queue_commands.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/simple_health.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/cli/ticket_commands.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/adapter.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/config.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/env_discovery.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/env_loader.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/exceptions.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/http_client.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/mappers.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/models.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/project_config.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/core/registry.py +0 -0
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/constants.py +0 -0
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/dto.py +0 -0
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/response_builder.py +0 -0
- {mcp_ticketer-0.4.4/src/mcp_ticketer/mcp → mcp_ticketer-0.6.2/src/mcp_ticketer/mcp/server}/tools/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/py.typed +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/__main__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/health_monitor.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/queue.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/run_worker.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer/queue/worker.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer.egg-info/dependency_links.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer.egg-info/entry_points.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer.egg-info/not-zip-safe +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer.egg-info/requires.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/src/mcp_ticketer.egg-info/top_level.txt +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/test-tickets/tickets/task-20250924002724.json +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/test_linear_fixes.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/test_worker_persistence.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/README.md +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/linear/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/linear/test_mappers.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/linear/test_queries.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/linear/test_types.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_aitrackdown.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_aitrackdown_security.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_github.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_github_token.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_jira.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_jira_direct.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_jira_projects.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_linear.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_linear_config.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/adapters/test_linear_native.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/debug_credential_validation.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/test_environment_handoff.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/test_queue_processing.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/core/test_queue_system.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_adapter_cache.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_cli_config.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_cli_vs_simulation.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_linear_teams.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_search.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_test.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_worker_adapter.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_worker_simulation.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/debug/debug_worker_subprocess.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/e2e/test_comments_and_attachments.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/e2e/test_complete_ticket_workflow.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/e2e/test_complete_workflow.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/e2e/test_hierarchy_validation.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/e2e/test_state_transitions.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_aitrackdown_commenting.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_commenting_functionality.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_comprehensive.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_hierarchy_and_workflow.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_jira_github_adapters.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_mcp_server_qa.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_pr_functionality.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_serve_config.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/integration/test_user_assignment.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/performance/test_optimizations.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/performance/test_performance.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/run_comprehensive_tests.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_api_usage.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_basic.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_comprehensive_qa.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_error_handling.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_linear_teams.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_models.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/test_queue.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/unit/__init__.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/unit/test_cache_memory.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/unit/test_core_exceptions.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tests/unit/test_core_models.py +0 -0
- {mcp_ticketer-0.4.4 → mcp_ticketer-0.6.2}/tox.ini +0 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# Before/After Code Comparison - Linear Init Fix
|
|
2
|
+
|
|
3
|
+
## The Bug
|
|
4
|
+
|
|
5
|
+
When running `mcp-ticketer init` and selecting Linear from the interactive menu without environment variables, users would get an error instead of being prompted for credentials.
|
|
6
|
+
|
|
7
|
+
## Code Changes
|
|
8
|
+
|
|
9
|
+
### BEFORE (Lines 652-743) - BROKEN
|
|
10
|
+
|
|
11
|
+
```python
|
|
12
|
+
elif adapter_type == "linear":
|
|
13
|
+
# If not auto-discovered, build from CLI params or prompt
|
|
14
|
+
if adapter_type not in config["adapters"]:
|
|
15
|
+
linear_config = {} # ❌ Build dict too early
|
|
16
|
+
|
|
17
|
+
# API Key
|
|
18
|
+
linear_api_key = api_key or os.getenv("LINEAR_API_KEY")
|
|
19
|
+
if not linear_api_key and not discovered:
|
|
20
|
+
# ... prompt ...
|
|
21
|
+
linear_api_key = typer.prompt("Enter your Linear API key", hide_input=True)
|
|
22
|
+
|
|
23
|
+
if linear_api_key: # ❌ Only add if exists
|
|
24
|
+
linear_config["api_key"] = linear_api_key
|
|
25
|
+
|
|
26
|
+
# Team info collection...
|
|
27
|
+
linear_team_key = os.getenv("LINEAR_TEAM_KEY")
|
|
28
|
+
linear_team_id = team_id or os.getenv("LINEAR_TEAM_ID")
|
|
29
|
+
|
|
30
|
+
if not linear_team_key and not linear_team_id and not discovered:
|
|
31
|
+
# ... prompt ...
|
|
32
|
+
team_input = typer.prompt("Team URL, key, or ID")
|
|
33
|
+
# ... URL derivation logic ...
|
|
34
|
+
|
|
35
|
+
# Save whichever was provided
|
|
36
|
+
if linear_team_key:
|
|
37
|
+
linear_config["team_key"] = linear_team_key
|
|
38
|
+
if linear_team_id:
|
|
39
|
+
linear_config["team_id"] = linear_team_id
|
|
40
|
+
|
|
41
|
+
# ❌ EARLY VALIDATION - This would exit before saving!
|
|
42
|
+
if not linear_config.get("api_key") or (
|
|
43
|
+
not linear_config.get("team_id") and not linear_config.get("team_key")
|
|
44
|
+
):
|
|
45
|
+
console.print("[red]Error:[/red] Linear requires both API key and team ID/key")
|
|
46
|
+
console.print("Run 'mcp-ticketer init --adapter linear' with proper credentials")
|
|
47
|
+
raise typer.Exit(1)
|
|
48
|
+
|
|
49
|
+
linear_config["type"] = "linear"
|
|
50
|
+
config["adapters"]["linear"] = linear_config # Never reached if validation failed
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### AFTER (Lines 652-741) - FIXED
|
|
54
|
+
|
|
55
|
+
```python
|
|
56
|
+
elif adapter_type == "linear":
|
|
57
|
+
# If not auto-discovered, build from CLI params or prompt
|
|
58
|
+
if adapter_type not in config["adapters"]:
|
|
59
|
+
# ✅ Collect variables first, no dict yet
|
|
60
|
+
|
|
61
|
+
# API Key
|
|
62
|
+
linear_api_key = api_key or os.getenv("LINEAR_API_KEY")
|
|
63
|
+
if not linear_api_key and not discovered:
|
|
64
|
+
console.print("\n[bold]Linear Configuration[/bold]")
|
|
65
|
+
console.print("You need a Linear API key to connect to Linear.")
|
|
66
|
+
console.print("[dim]Get your API key at: https://linear.app/settings/api[/dim]\n")
|
|
67
|
+
|
|
68
|
+
linear_api_key = typer.prompt("Enter your Linear API key", hide_input=True)
|
|
69
|
+
|
|
70
|
+
# Team ID or Team Key or Team URL
|
|
71
|
+
linear_team_key = os.getenv("LINEAR_TEAM_KEY")
|
|
72
|
+
linear_team_id = team_id or os.getenv("LINEAR_TEAM_ID")
|
|
73
|
+
|
|
74
|
+
if not linear_team_key and not linear_team_id and not discovered:
|
|
75
|
+
console.print("\n[bold]Linear Team Configuration[/bold]")
|
|
76
|
+
console.print("You can provide either:")
|
|
77
|
+
console.print(" 1. Team URL (e.g., https://linear.app/workspace/team/TEAMKEY/active)")
|
|
78
|
+
console.print(" 2. Team key (e.g., 'ENG', 'DESIGN', 'PRODUCT')")
|
|
79
|
+
console.print(" 3. Team ID (UUID)")
|
|
80
|
+
console.print("[dim]Find team URL or key in: Linear → Your Team → Team Issues Page[/dim]\n")
|
|
81
|
+
|
|
82
|
+
team_input = typer.prompt("Team URL, key, or ID")
|
|
83
|
+
|
|
84
|
+
# Check if input is a URL
|
|
85
|
+
if team_input.startswith("https://linear.app/"):
|
|
86
|
+
# ... URL derivation logic (unchanged) ...
|
|
87
|
+
else:
|
|
88
|
+
# Input is team key or ID
|
|
89
|
+
if len(team_input) > 20: # Likely a UUID
|
|
90
|
+
linear_team_id = team_input
|
|
91
|
+
else:
|
|
92
|
+
linear_team_key = team_input
|
|
93
|
+
|
|
94
|
+
# ✅ Validate AFTER collection (JIRA pattern)
|
|
95
|
+
if not linear_api_key:
|
|
96
|
+
console.print("[red]Error:[/red] Linear API key is required")
|
|
97
|
+
raise typer.Exit(1)
|
|
98
|
+
|
|
99
|
+
if not linear_team_id and not linear_team_key:
|
|
100
|
+
console.print("[red]Error:[/red] Linear requires either team ID or team key")
|
|
101
|
+
raise typer.Exit(1)
|
|
102
|
+
|
|
103
|
+
# ✅ Build config dict AFTER validation passes
|
|
104
|
+
linear_config = {
|
|
105
|
+
"api_key": linear_api_key,
|
|
106
|
+
"type": "linear",
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
# Save whichever was provided
|
|
110
|
+
if linear_team_key:
|
|
111
|
+
linear_config["team_key"] = linear_team_key
|
|
112
|
+
if linear_team_id:
|
|
113
|
+
linear_config["team_id"] = linear_team_id
|
|
114
|
+
|
|
115
|
+
# ✅ Save config (only reached if validation passed)
|
|
116
|
+
config["adapters"]["linear"] = linear_config
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Key Differences
|
|
120
|
+
|
|
121
|
+
| Aspect | BEFORE (Broken) | AFTER (Fixed) |
|
|
122
|
+
|--------|-----------------|---------------|
|
|
123
|
+
| Dict Creation | Created `linear_config = {}` immediately | Created after validation passes |
|
|
124
|
+
| Validation Timing | Validated partial dict (line 731) | Validates collected variables (line 721) |
|
|
125
|
+
| Error Handling | Could exit before prompts completed | Exits only after all prompts run |
|
|
126
|
+
| Config Building | Built incrementally with `if` checks | Built once with all validated values |
|
|
127
|
+
| Pattern Match | Different from JIRA adapter | Matches JIRA adapter pattern |
|
|
128
|
+
|
|
129
|
+
## Execution Flow Comparison
|
|
130
|
+
|
|
131
|
+
### BEFORE - Broken Flow
|
|
132
|
+
```
|
|
133
|
+
1. User selects Linear from menu
|
|
134
|
+
2. linear_config = {} (empty dict created)
|
|
135
|
+
3. Prompt for API key
|
|
136
|
+
→ User enters key
|
|
137
|
+
→ linear_config["api_key"] = key
|
|
138
|
+
4. Prompt for team info
|
|
139
|
+
→ User enters team
|
|
140
|
+
→ linear_config["team_key"] = team
|
|
141
|
+
5. ❌ Validation checks linear_config
|
|
142
|
+
→ If any field missing: EXIT with error
|
|
143
|
+
→ Never saves config
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
**Problem:** Validation happened on a partially-built dict that might be incomplete due to prompt logic.
|
|
147
|
+
|
|
148
|
+
### AFTER - Fixed Flow
|
|
149
|
+
```
|
|
150
|
+
1. User selects Linear from menu
|
|
151
|
+
2. Collect API key → linear_api_key variable
|
|
152
|
+
3. Prompt if needed → linear_api_key = "user_input"
|
|
153
|
+
4. Collect team info → linear_team_id/key variables
|
|
154
|
+
5. Prompt if needed → linear_team_key = "user_input"
|
|
155
|
+
6. ✅ Validate collected variables
|
|
156
|
+
→ If missing: EXIT with clear error
|
|
157
|
+
→ If present: Continue
|
|
158
|
+
7. Build linear_config dict
|
|
159
|
+
8. Save config to adapters
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
**Solution:** Validation happens on collected variables, then config dict is built only if valid.
|
|
163
|
+
|
|
164
|
+
## Why This Pattern Works
|
|
165
|
+
|
|
166
|
+
The JIRA adapter (lines 745-803) demonstrates the correct pattern:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
# 1. Collect into variables
|
|
170
|
+
server = jira_server or os.getenv("JIRA_SERVER")
|
|
171
|
+
email = jira_email or os.getenv("JIRA_EMAIL")
|
|
172
|
+
token = api_key or os.getenv("JIRA_API_TOKEN")
|
|
173
|
+
|
|
174
|
+
# 2. Prompt for missing values
|
|
175
|
+
if not server and not discovered:
|
|
176
|
+
server = typer.prompt("JIRA server URL")
|
|
177
|
+
if not email and not discovered:
|
|
178
|
+
email = typer.prompt("Your JIRA email address")
|
|
179
|
+
|
|
180
|
+
# 3. Validate collected variables
|
|
181
|
+
if not server:
|
|
182
|
+
console.print("[red]Error:[/red] JIRA server URL is required")
|
|
183
|
+
raise typer.Exit(1)
|
|
184
|
+
|
|
185
|
+
# 4. Build config dict (only if valid)
|
|
186
|
+
jira_config = {
|
|
187
|
+
"server": server,
|
|
188
|
+
"email": email,
|
|
189
|
+
"api_token": token,
|
|
190
|
+
"type": "jira",
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
# 5. Save config
|
|
194
|
+
config["adapters"]["jira"] = jira_config
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Linear now follows the same pattern.
|
|
198
|
+
|
|
199
|
+
## Impact
|
|
200
|
+
|
|
201
|
+
### User Experience
|
|
202
|
+
- **Before:** Confusing error message immediately after menu selection
|
|
203
|
+
- **After:** Smooth interactive prompting experience
|
|
204
|
+
|
|
205
|
+
### Code Consistency
|
|
206
|
+
- **Before:** Linear used different pattern than JIRA
|
|
207
|
+
- **After:** All adapters follow the same pattern
|
|
208
|
+
|
|
209
|
+
### Test Coverage
|
|
210
|
+
- No existing tests for this functionality (manual testing required)
|
|
211
|
+
- Future improvement: Add unit tests for init command
|
|
212
|
+
|
|
213
|
+
## Testing the Fix
|
|
214
|
+
|
|
215
|
+
### Manual Test 1: Interactive Selection
|
|
216
|
+
```bash
|
|
217
|
+
# Clean environment
|
|
218
|
+
unset LINEAR_API_KEY LINEAR_TEAM_KEY LINEAR_TEAM_ID
|
|
219
|
+
rm -rf ~/.mcp_ticketer
|
|
220
|
+
|
|
221
|
+
# Run init
|
|
222
|
+
mcp-ticketer init
|
|
223
|
+
|
|
224
|
+
# Expected:
|
|
225
|
+
# - No adapter detected
|
|
226
|
+
# - Shows menu: "1. Linear, 2. JIRA, 3. AitRackdown"
|
|
227
|
+
# - Select 1 (Linear)
|
|
228
|
+
# - Prompts: "Enter your Linear API key"
|
|
229
|
+
# - Prompts: "Team URL, key, or ID"
|
|
230
|
+
# - Success message
|
|
231
|
+
# - Config saved to ~/.mcp_ticketer/config.json
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
### Manual Test 2: Partial Credentials
|
|
235
|
+
```bash
|
|
236
|
+
# Set only API key
|
|
237
|
+
export LINEAR_API_KEY="test_key_123"
|
|
238
|
+
unset LINEAR_TEAM_KEY LINEAR_TEAM_ID
|
|
239
|
+
|
|
240
|
+
# Run init
|
|
241
|
+
mcp-ticketer init
|
|
242
|
+
|
|
243
|
+
# Expected:
|
|
244
|
+
# - Detects Linear from environment
|
|
245
|
+
# - Prompts ONLY for team info (not API key)
|
|
246
|
+
# - Success
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Manual Test 3: Validation Works
|
|
250
|
+
```bash
|
|
251
|
+
# Try to bypass prompts (hit Enter without input)
|
|
252
|
+
# This should fail with clear error message
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
## Verification Checklist
|
|
256
|
+
|
|
257
|
+
- [x] Code compiles (Python syntax valid)
|
|
258
|
+
- [x] Follows JIRA adapter pattern
|
|
259
|
+
- [x] Validation moved after collection
|
|
260
|
+
- [x] Config dict built after validation
|
|
261
|
+
- [x] Error messages are clear
|
|
262
|
+
- [x] All features preserved (URL derivation, discovery)
|
|
263
|
+
- [x] No regressions in CLI parameters
|
|
264
|
+
- [ ] Manual testing completed (requires user interaction)
|
|
265
|
+
- [ ] Unit tests added (future work)
|
|
266
|
+
|
|
267
|
+
## Related Documentation
|
|
268
|
+
|
|
269
|
+
- See `LINEAR_INIT_FIX_SUMMARY.md` for detailed implementation notes
|
|
270
|
+
- See `/src/mcp_ticketer/cli/main.py` lines 652-741 for actual code
|
|
271
|
+
- Compare with JIRA adapter (lines 743-803) for reference pattern
|
|
@@ -4,6 +4,83 @@ All notable changes to MCP Ticketer will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
+
## [0.4.15] - 2025-11-07
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- **Linear Task Creation with Parent Issues**: Fixed Linear adapter to resolve issue identifiers to UUIDs
|
|
11
|
+
- Task creation with `parent_issue` parameter now works with both issue identifiers (e.g., "ENG-842") and UUIDs
|
|
12
|
+
- Added automatic identifier resolution via GraphQL query
|
|
13
|
+
- Eliminates "Variable '$issueId' of non-null type 'UUID!' must not be null" errors
|
|
14
|
+
- Resolves validation failures when creating tasks under parent issues
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
- **Linear Issue Resolution Method**: Added `_resolve_issue_id()` for automatic identifier resolution
|
|
18
|
+
- Resolves issue identifiers (like "ENG-842") to UUIDs via GraphQL
|
|
19
|
+
- Provides clear error messages when issues cannot be found
|
|
20
|
+
- Enables flexible parent issue specification in task creation
|
|
21
|
+
- Comprehensive test coverage with 13 new tests
|
|
22
|
+
|
|
23
|
+
### Changed
|
|
24
|
+
- **Code Quality**: Import formatting standardization across codebase
|
|
25
|
+
- Applied consistent import ordering to 38 files
|
|
26
|
+
- Improved code consistency and maintainability
|
|
27
|
+
- No functional changes to core logic
|
|
28
|
+
|
|
29
|
+
### Testing
|
|
30
|
+
- **Issue Resolution Tests**: Added comprehensive test suite for Linear issue resolution
|
|
31
|
+
- Created `tests/adapters/linear/test_issue_resolution.py` with 13 tests
|
|
32
|
+
- Tests cover identifier resolution, UUID handling, and error cases
|
|
33
|
+
- Validates task creation with parent issues
|
|
34
|
+
- 100% test coverage for new resolution functionality
|
|
35
|
+
|
|
36
|
+
### Documentation
|
|
37
|
+
- **Linear Parent Issue Fix**: Added detailed documentation in `docs/linear_parent_issue_fix.md`
|
|
38
|
+
- Explains the root cause of the issue
|
|
39
|
+
- Documents the resolution approach
|
|
40
|
+
- Provides examples and testing guidance
|
|
41
|
+
|
|
42
|
+
## [0.4.11] - 2025-10-28
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
- **CRITICAL: MCP Installer Command Structure**: Fixed all MCP installers to use Python module invocation pattern
|
|
46
|
+
- Changed from: `command: {venv}/bin/mcp-ticketer`, `args: ["mcp", project_path]`
|
|
47
|
+
- Changed to: `command: {venv}/bin/python`, `args: ["-m", "mcp_ticketer.mcp.server", project_path]`
|
|
48
|
+
- Affects: Claude Code, Auggie CLI, Gemini CLI, and Codex CLI installers
|
|
49
|
+
- Impact: Installer now works with any Python environment (pip, pipx, editable installs)
|
|
50
|
+
- Matches established pattern from mcp-vector-search and other MCP servers
|
|
51
|
+
|
|
52
|
+
### Files Modified
|
|
53
|
+
- `src/mcp_ticketer/cli/mcp_configure.py` - Claude Code/Desktop installer
|
|
54
|
+
- `src/mcp_ticketer/cli/auggie_configure.py` - Auggie CLI installer
|
|
55
|
+
- `src/mcp_ticketer/cli/gemini_configure.py` - Gemini CLI installer
|
|
56
|
+
- `src/mcp_ticketer/cli/codex_configure.py` - Codex CLI installer
|
|
57
|
+
|
|
58
|
+
### Technical Details
|
|
59
|
+
- Uses Python executable directly with `-m` module flag
|
|
60
|
+
- No longer depends on `mcp-ticketer` binary existing in target venv
|
|
61
|
+
- Works across all installation methods and Python environments
|
|
62
|
+
- Provides consistent behavior with other MCP ecosystem tools
|
|
63
|
+
|
|
64
|
+
## [0.4.10] - 2025-10-28
|
|
65
|
+
|
|
66
|
+
### Fixed
|
|
67
|
+
- **CRITICAL: MCP Installer Configuration**: Fixed Claude Code MCP installer to write to correct config location
|
|
68
|
+
- Changed config path from `.claude/settings.local.json` to `~/.claude.json`
|
|
69
|
+
- Updated to use project-specific structure: `.projects[path].mcpServers["mcp-ticketer"]`
|
|
70
|
+
- Added backward compatibility with `.claude/mcp.local.json`
|
|
71
|
+
- Enhanced error handling for invalid JSON and empty config files
|
|
72
|
+
- Added `type: "stdio"` field required by Claude Code
|
|
73
|
+
- Uses absolute project paths with `Path.cwd().resolve()`
|
|
74
|
+
- Matches working pattern from mcp-vector-search installation
|
|
75
|
+
- Resolves issue where mcp-ticketer server failed to connect in Claude Code
|
|
76
|
+
|
|
77
|
+
### Technical Details
|
|
78
|
+
- Updated `find_claude_mcp_config()` to return `~/.claude.json` for Claude Code
|
|
79
|
+
- Enhanced `load_claude_mcp_config()` with platform-specific structure support
|
|
80
|
+
- Refactored `configure_claude_mcp()` to write to both primary and legacy locations
|
|
81
|
+
- Updated `remove_claude_mcp()` to clean up both config locations
|
|
82
|
+
- Added comprehensive JSON parsing and empty file handling
|
|
83
|
+
|
|
7
84
|
## [0.4.4] - 2025-10-27
|
|
8
85
|
|
|
9
86
|
### Changed
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Environment Loading Timing Fix
|
|
2
|
+
|
|
3
|
+
## Problem
|
|
4
|
+
The `.env.local` file loading was happening at Python module import time, which occurred BEFORE the working directory was changed to the target project directory in `__main__.py`. This caused the MCP server to load environment variables from the wrong directory.
|
|
5
|
+
|
|
6
|
+
## Root Cause Analysis
|
|
7
|
+
|
|
8
|
+
### Execution Flow (Before Fix)
|
|
9
|
+
```
|
|
10
|
+
1. claude-code runs: python -m mcp_ticketer.mcp.server /Users/masa/Projects/claude-mpm
|
|
11
|
+
2. Python imports mcp_ticketer.mcp.server.__main__
|
|
12
|
+
3. __main__.py imports from .main (line 16) ← Triggers module load
|
|
13
|
+
4. main.py module-level code (lines 31-46): load_dotenv(Path.cwd() / ".env.local") ← WRONG directory!
|
|
14
|
+
5. THEN __main__.py changes directory (line 43) ← TOO LATE
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
### The Issue
|
|
18
|
+
- Module-level code runs during `import`, not during function execution
|
|
19
|
+
- `__main__.py` imports `main` before changing directories
|
|
20
|
+
- Environment variables were loaded from the directory where the command was executed, not the target project
|
|
21
|
+
|
|
22
|
+
## Solution
|
|
23
|
+
|
|
24
|
+
### Changes Made
|
|
25
|
+
1. **Removed** module-level `load_dotenv()` calls from `src/mcp_ticketer/mcp/server/main.py` (lines 31-46)
|
|
26
|
+
2. **Moved** environment loading INTO the `main()` async function (after logger initialization, line 1034)
|
|
27
|
+
3. **Added** clarifying comments explaining the timing
|
|
28
|
+
4. **Added** debug logging for better visibility
|
|
29
|
+
|
|
30
|
+
### Execution Flow (After Fix)
|
|
31
|
+
```
|
|
32
|
+
1. claude-code runs: python -m mcp_ticketer.mcp.server /Users/masa/Projects/claude-mpm
|
|
33
|
+
2. Python imports mcp_ticketer.mcp.server.__main__
|
|
34
|
+
3. __main__.py imports from .main (line 16) ← Module loads WITHOUT env loading
|
|
35
|
+
4. __main__.py changes directory (line 43) ← Sets correct working directory
|
|
36
|
+
5. __main__.py calls main() (line 50)
|
|
37
|
+
6. main() loads .env.local from Path.cwd() ← CORRECT directory!
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Testing
|
|
41
|
+
|
|
42
|
+
### Test Results
|
|
43
|
+
✅ Module import does not trigger environment loading
|
|
44
|
+
✅ Correct `.env.local` file is detected in target project directory
|
|
45
|
+
✅ Working directory is correctly set before `main()` executes
|
|
46
|
+
|
|
47
|
+
### Test Commands
|
|
48
|
+
```bash
|
|
49
|
+
# From mcp-ticketer directory
|
|
50
|
+
uv run python -m mcp_ticketer.mcp.server /Users/masa/Projects/claude-mpm
|
|
51
|
+
|
|
52
|
+
# Should output:
|
|
53
|
+
# [MCP Server] Working directory: /Users/masa/Projects/claude-mpm
|
|
54
|
+
# [MCP Server] Loaded environment from: /Users/masa/Projects/claude-mpm/.env.local
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Files Modified
|
|
58
|
+
- `src/mcp_ticketer/mcp/server/main.py`
|
|
59
|
+
|
|
60
|
+
## Impact
|
|
61
|
+
- **Before**: MCP server loaded `.env.local` from command execution directory
|
|
62
|
+
- **After**: MCP server loads `.env.local` from target project directory
|
|
63
|
+
- **Result**: Environment variables are now correctly loaded for the target project
|
|
64
|
+
|
|
65
|
+
## Success Criteria
|
|
66
|
+
- ✅ Server loads `.env.local` from target project directory, not from where command is executed
|
|
67
|
+
- ✅ MCP server successfully initializes when called by claude-code
|
|
68
|
+
- ✅ Debug logs show correct `.env.local` path being loaded
|
|
69
|
+
- ✅ No environment loading happens during module import
|
|
70
|
+
|
|
71
|
+
## Technical Details
|
|
72
|
+
|
|
73
|
+
### Why Module-Level Code is Problematic
|
|
74
|
+
Python executes module-level code immediately when the module is imported, before any function calls. This means:
|
|
75
|
+
- Module-level code in `main.py` runs when `__main__.py` imports it
|
|
76
|
+
- At that point, the working directory hasn't been changed yet
|
|
77
|
+
- Environment loading happens from the wrong directory
|
|
78
|
+
|
|
79
|
+
### Why Function-Level Code Works
|
|
80
|
+
By moving the environment loading into the `main()` function:
|
|
81
|
+
- Code only runs when `main()` is explicitly called
|
|
82
|
+
- `__main__.py` has already changed the working directory
|
|
83
|
+
- Environment loading happens from the correct target project directory
|
|
84
|
+
|
|
85
|
+
## Code Changes
|
|
86
|
+
|
|
87
|
+
### Before (lines 31-46, module level)
|
|
88
|
+
```python
|
|
89
|
+
# Load environment variables early (prioritize .env.local)
|
|
90
|
+
# Check for .env.local first (takes precedence)
|
|
91
|
+
env_local_file = Path.cwd() / ".env.local"
|
|
92
|
+
if env_local_file.exists():
|
|
93
|
+
load_dotenv(env_local_file, override=True)
|
|
94
|
+
sys.stderr.write(f"[MCP Server] Loaded environment from: {env_local_file}\n")
|
|
95
|
+
else:
|
|
96
|
+
# Fall back to .env
|
|
97
|
+
env_file = Path.cwd() / ".env"
|
|
98
|
+
if env_file.exists():
|
|
99
|
+
load_dotenv(env_file, override=True)
|
|
100
|
+
sys.stderr.write(f"[MCP Server] Loaded environment from: {env_file}\n")
|
|
101
|
+
else:
|
|
102
|
+
# Try default dotenv loading (searches upward)
|
|
103
|
+
load_dotenv(override=True)
|
|
104
|
+
sys.stderr.write("[MCP Server] Loaded environment from default search path\n")
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### After (inside main() function, around line 1034)
|
|
108
|
+
```python
|
|
109
|
+
# Load environment variables AFTER working directory has been set by __main__.py
|
|
110
|
+
# This ensures we load .env files from the target project directory, not from where the command is executed
|
|
111
|
+
env_local_file = Path.cwd() / ".env.local"
|
|
112
|
+
if env_local_file.exists():
|
|
113
|
+
load_dotenv(env_local_file, override=True)
|
|
114
|
+
sys.stderr.write(f"[MCP Server] Loaded environment from: {env_local_file}\n")
|
|
115
|
+
logger.debug(f"Loaded environment from: {env_local_file}")
|
|
116
|
+
else:
|
|
117
|
+
# Fall back to .env
|
|
118
|
+
env_file = Path.cwd() / ".env"
|
|
119
|
+
if env_file.exists():
|
|
120
|
+
load_dotenv(env_file, override=True)
|
|
121
|
+
sys.stderr.write(f"[MCP Server] Loaded environment from: {env_file}\n")
|
|
122
|
+
logger.debug(f"Loaded environment from: {env_file}")
|
|
123
|
+
else:
|
|
124
|
+
# Try default dotenv loading (searches upward)
|
|
125
|
+
load_dotenv(override=True)
|
|
126
|
+
sys.stderr.write("[MCP Server] Loaded environment from default search path\n")
|
|
127
|
+
logger.debug("Loaded environment from default search path")
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## LOC Impact
|
|
131
|
+
- **Net LOC**: 0 (moved code, not added)
|
|
132
|
+
- **Lines Removed**: 16 (module-level)
|
|
133
|
+
- **Lines Added**: 20 (function-level with debug logging)
|
|
134
|
+
- **Impact**: +4 LOC (due to additional debug logging)
|