mcp-ticketer 0.1.21__tar.gz → 0.1.23__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.1.23/.mcp/config.json +12 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/PKG-INFO +1 -1
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/pyproject.toml +1 -1
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/__init__.py +7 -7
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/__version__.py +4 -2
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/adapters/__init__.py +4 -4
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/adapters/aitrackdown.py +66 -49
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/adapters/github.py +192 -125
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/adapters/hybrid.py +99 -53
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/adapters/jira.py +161 -151
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/adapters/linear.py +396 -246
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cache/__init__.py +1 -1
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cache/memory.py +15 -16
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/__init__.py +1 -1
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/configure.py +69 -93
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/discover.py +43 -35
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/main.py +283 -298
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/mcp_configure.py +39 -15
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/migrate_config.py +11 -13
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/queue_commands.py +21 -58
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/cli/utils.py +121 -66
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/__init__.py +2 -2
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/adapter.py +46 -39
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/config.py +128 -92
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/env_discovery.py +69 -37
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/http_client.py +57 -40
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/mappers.py +98 -54
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/models.py +38 -24
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/project_config.py +145 -80
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/core/registry.py +16 -16
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/mcp/__init__.py +1 -1
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/mcp/server.py +199 -145
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/queue/__init__.py +2 -2
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/queue/__main__.py +1 -1
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/queue/manager.py +30 -26
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/queue/queue.py +147 -85
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/queue/run_worker.py +2 -3
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/queue/worker.py +55 -40
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer.egg-info/PKG-INFO +1 -1
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer.egg-info/SOURCES.txt +3 -2
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tests/adapters/test_aitrackdown.py +45 -16
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tests/conftest.py +8 -5
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tests/core/test_env_discovery.py +11 -8
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tests/test_base_adapter.py +15 -10
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tests/test_models.py +4 -4
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tests/test_queue.py +3 -6
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/.dependency_cache +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/.mpm_deployment_state +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/agent-manager.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/agentic-coder-optimizer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/api_qa.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/clerk-ops.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/code_analyzer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/content-agent.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/dart_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/data_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/documentation.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/gcp_ops_agent.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/golang_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/imagemagick.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/java_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/local_ops_agent.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/memory_manager.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/nextjs_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/ops.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/php-engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/product_owner.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/project_organizer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/prompt-engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/python_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/qa.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/react_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/refactoring_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/research.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/ruby-engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/rust_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/security.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/ticketing.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/typescript_engineer.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/vercel_ops_agent.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/version_control.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/web_qa.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/agents/web_ui.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude/mcp.json +0 -0
- /mcp_ticketer-0.1.21/.mcp/config.json → /mcp_ticketer-0.1.23/.claude/mcp.local.json +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/config/project.json +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/mcp_auto_config_preference.json +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/README.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/agentic_coder_optimizer_memories.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/documentation_memories.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/engineer_memories.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/ops_memories.md +0 -0
- /mcp_ticketer-0.1.21/.claude-mpm/memories/project_knowledge.md → /mcp_ticketer-0.1.23/.claude-mpm/memories/project_knowledge_memories.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/qa_memories.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/research_memories.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude-mpm/memories/version-control_memories.md +0 -0
- /mcp_ticketer-0.1.21/.claude-mpm/memories/workflows.md → /mcp_ticketer-0.1.23/.claude-mpm/memories/workflows_memories.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.claude.json +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.coveragerc +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.env.example +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.github/workflows/docs.yml +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.github/workflows/publish.yml +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.github/workflows/test.yml +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.pre-commit-config.yaml +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.python-version +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/.readthedocs.yaml +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/CHANGELOG.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/CLAUDE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/CLAUDE_DESKTOP_SETUP.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/CODE_STRUCTURE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/CONFIG_RESOLUTION_FIX.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/CONTRIBUTING.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/CREDENTIAL_VALIDATION_FIX.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/ENV_DISCOVERY_COMPLETE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/FIX_SUMMARY.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/HIERARCHY_IMPLEMENTATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/IMPLEMENTATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/JIRA_SETUP.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/LICENSE +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/LINEAR_SETUP.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/MANIFEST.in +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/Makefile +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/OPTIMIZATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/PROJECT_INITIALIZATION_SUMMARY.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/QUEUE_SYSTEM.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/QUICK_START.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/README.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/RELEASE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/RELEASING.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/TEST_COVERAGE_REPORT.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/TEST_REPORT.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/TEST_RESULTS_SUMMARY.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/VERIFICATION_RESULTS.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/claude-desktop-config.json +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/debug_search.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/debug_test.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/ADAPTERS.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/API_REFERENCE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/CONFIGURATION.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/CONFIG_RESOLUTION_FLOW.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/DEVELOPER_GUIDE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/ENV_DISCOVERY.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/MCP_INTEGRATION.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/MIGRATION_GUIDE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/PROJECT_CONFIG.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/PR_INTEGRATION.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/QUICK_START_ENV.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/USER_GUIDE.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_archive/README.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/ADAPTERS.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/API_REFERENCE.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/CONFIGURATION.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/DEVELOPER_GUIDE.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/MCP_INTEGRATION.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/MIGRATION_GUIDE.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/USER_GUIDE.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/adapters/github.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/adapters.rst.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/api.rst.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/cli.rst.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/development.rst.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/examples.rst.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/index.rst.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/installation.rst.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/_build/_sources/prd/mcp-ticketer-prd.md.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/adapters/github.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/adapters.rst +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/api.rst +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/cli.rst +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/conf.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/development.rst +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/examples.rst +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/index.rst +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/installation.rst +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/prd/mcp-ticketer-prd.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/docs/requirements.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/install.sh +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/mcp-ticketer +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/mcp-ticketer-server +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/mcp_server.sh +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/pytest.ini +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/requirements-dev.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/requirements.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/scripts/README.md +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/scripts/manage_version.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/setup.cfg +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/setup.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer/py.typed +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer.egg-info/dependency_links.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer.egg-info/entry_points.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer.egg-info/not-zip-safe +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer.egg-info/requires.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/src/mcp_ticketer.egg-info/top_level.txt +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test-tickets/tickets/task-20250924002724.json +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_all_adapters.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_api_usage.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_basic.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_comprehensive.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_config_resolution.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_credential_validation.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_error_handling.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_github.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_github_token.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_jira.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_linear.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_linear_native.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_linear_teams.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_mcp_server_qa.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_optimizations.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_performance.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_pr_functionality.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_queue_system.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_serve_config.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/test_set_command.sh +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tests/adapters/__init__.py +0 -0
- {mcp_ticketer-0.1.21 → mcp_ticketer-0.1.23}/tox.ini +0 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"mcp-ticketer": {
|
|
4
|
+
"command": "/Users/masa/Projects/mcp-ticketer/.venv/bin/mcp-ticketer",
|
|
5
|
+
"args": ["serve"],
|
|
6
|
+
"cwd": "/Users/masa/Projects/mcp-ticketer",
|
|
7
|
+
"env": {
|
|
8
|
+
"PYTHONPATH": "/Users/masa/Projects/mcp-ticketer/src"
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-ticketer
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.23
|
|
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,16 +1,16 @@
|
|
|
1
1
|
"""MCP Ticketer - Universal ticket management interface."""
|
|
2
2
|
|
|
3
3
|
from .__version__ import (
|
|
4
|
-
__version__,
|
|
5
|
-
__version_info__,
|
|
6
|
-
__title__,
|
|
7
|
-
__description__,
|
|
8
4
|
__author__,
|
|
9
5
|
__author_email__,
|
|
10
|
-
__license__,
|
|
11
6
|
__copyright__,
|
|
12
|
-
|
|
7
|
+
__description__,
|
|
8
|
+
__license__,
|
|
9
|
+
__title__,
|
|
10
|
+
__version__,
|
|
11
|
+
__version_info__,
|
|
13
12
|
get_user_agent,
|
|
13
|
+
get_version,
|
|
14
14
|
)
|
|
15
15
|
|
|
16
16
|
__all__ = [
|
|
@@ -24,4 +24,4 @@ __all__ = [
|
|
|
24
24
|
"__copyright__",
|
|
25
25
|
"get_version",
|
|
26
26
|
"get_user_agent",
|
|
27
|
-
]
|
|
27
|
+
]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"""Version information for mcp-ticketer package."""
|
|
2
2
|
|
|
3
|
-
__version__ = "0.1.
|
|
3
|
+
__version__ = "0.1.23"
|
|
4
4
|
__version_info__ = tuple(int(part) for part in __version__.split("."))
|
|
5
5
|
|
|
6
6
|
# Package metadata
|
|
@@ -26,6 +26,7 @@ __features__ = {
|
|
|
26
26
|
"queue_system": True,
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
+
|
|
29
30
|
def get_version():
|
|
30
31
|
"""Return the full version string with build metadata if available."""
|
|
31
32
|
version = __version__
|
|
@@ -35,6 +36,7 @@ def get_version():
|
|
|
35
36
|
version += f".{__commit__[:7]}"
|
|
36
37
|
return version
|
|
37
38
|
|
|
39
|
+
|
|
38
40
|
def get_user_agent():
|
|
39
41
|
"""Return a user agent string for API requests."""
|
|
40
|
-
return f"{__title__}/{__version__}"
|
|
42
|
+
return f"{__title__}/{__version__}"
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
"""Adapter implementations for various ticket systems."""
|
|
2
2
|
|
|
3
3
|
from .aitrackdown import AITrackdownAdapter
|
|
4
|
-
from .linear import LinearAdapter
|
|
5
|
-
from .jira import JiraAdapter
|
|
6
4
|
from .github import GitHubAdapter
|
|
7
5
|
from .hybrid import HybridAdapter
|
|
6
|
+
from .jira import JiraAdapter
|
|
7
|
+
from .linear import LinearAdapter
|
|
8
8
|
|
|
9
9
|
__all__ = [
|
|
10
10
|
"AITrackdownAdapter",
|
|
11
11
|
"LinearAdapter",
|
|
12
12
|
"JiraAdapter",
|
|
13
13
|
"GitHubAdapter",
|
|
14
|
-
"HybridAdapter"
|
|
15
|
-
]
|
|
14
|
+
"HybridAdapter",
|
|
15
|
+
]
|
|
@@ -1,17 +1,20 @@
|
|
|
1
1
|
"""AI-Trackdown adapter implementation."""
|
|
2
2
|
|
|
3
|
+
import builtins
|
|
3
4
|
import json
|
|
4
|
-
from pathlib import Path
|
|
5
|
-
from typing import List, Optional, Dict, Any, Union
|
|
6
5
|
from datetime import datetime
|
|
6
|
+
from pathlib import Path
|
|
7
|
+
from typing import Any, Optional, Union
|
|
7
8
|
|
|
8
9
|
from ..core.adapter import BaseAdapter
|
|
9
|
-
from ..core.models import
|
|
10
|
+
from ..core.models import Comment, Epic, Priority, SearchQuery, Task, TicketState
|
|
10
11
|
from ..core.registry import AdapterRegistry
|
|
11
12
|
|
|
12
13
|
# Import ai-trackdown-pytools when available
|
|
13
14
|
try:
|
|
14
|
-
from ai_trackdown_pytools import AITrackdown
|
|
15
|
+
from ai_trackdown_pytools import AITrackdown
|
|
16
|
+
from ai_trackdown_pytools import Ticket as AITicket
|
|
17
|
+
|
|
15
18
|
HAS_AITRACKDOWN = True
|
|
16
19
|
except ImportError:
|
|
17
20
|
HAS_AITRACKDOWN = False
|
|
@@ -22,11 +25,12 @@ except ImportError:
|
|
|
22
25
|
class AITrackdownAdapter(BaseAdapter[Task]):
|
|
23
26
|
"""Adapter for AI-Trackdown ticket system."""
|
|
24
27
|
|
|
25
|
-
def __init__(self, config:
|
|
28
|
+
def __init__(self, config: dict[str, Any]):
|
|
26
29
|
"""Initialize AI-Trackdown adapter.
|
|
27
30
|
|
|
28
31
|
Args:
|
|
29
32
|
config: Configuration with 'base_path' for tickets directory
|
|
33
|
+
|
|
30
34
|
"""
|
|
31
35
|
super().__init__(config)
|
|
32
36
|
self.base_path = Path(config.get("base_path", ".aitrackdown"))
|
|
@@ -47,6 +51,7 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
47
51
|
|
|
48
52
|
Returns:
|
|
49
53
|
(is_valid, error_message) - Always returns (True, "") for AITrackdown
|
|
54
|
+
|
|
50
55
|
"""
|
|
51
56
|
# AITrackdown is file-based and doesn't require API credentials
|
|
52
57
|
# Just verify the base_path is accessible
|
|
@@ -54,7 +59,7 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
54
59
|
return False, "AITrackdown base_path is required in configuration"
|
|
55
60
|
return True, ""
|
|
56
61
|
|
|
57
|
-
def _get_state_mapping(self) ->
|
|
62
|
+
def _get_state_mapping(self) -> dict[TicketState, str]:
|
|
58
63
|
"""Map universal states to AI-Trackdown states."""
|
|
59
64
|
return {
|
|
60
65
|
TicketState.OPEN: "open",
|
|
@@ -80,7 +85,7 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
80
85
|
except ValueError:
|
|
81
86
|
return Priority.MEDIUM
|
|
82
87
|
|
|
83
|
-
def _task_from_ai_ticket(self, ai_ticket:
|
|
88
|
+
def _task_from_ai_ticket(self, ai_ticket: dict[str, Any]) -> Task:
|
|
84
89
|
"""Convert AI-Trackdown ticket to universal Task."""
|
|
85
90
|
return Task(
|
|
86
91
|
id=ai_ticket.get("id"),
|
|
@@ -92,14 +97,20 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
92
97
|
parent_issue=ai_ticket.get("parent_issue"),
|
|
93
98
|
parent_epic=ai_ticket.get("parent_epic"),
|
|
94
99
|
assignee=ai_ticket.get("assignee"),
|
|
95
|
-
created_at=
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
100
|
+
created_at=(
|
|
101
|
+
datetime.fromisoformat(ai_ticket["created_at"])
|
|
102
|
+
if "created_at" in ai_ticket
|
|
103
|
+
else None
|
|
104
|
+
),
|
|
105
|
+
updated_at=(
|
|
106
|
+
datetime.fromisoformat(ai_ticket["updated_at"])
|
|
107
|
+
if "updated_at" in ai_ticket
|
|
108
|
+
else None
|
|
109
|
+
),
|
|
99
110
|
metadata={"ai_trackdown": ai_ticket},
|
|
100
111
|
)
|
|
101
112
|
|
|
102
|
-
def _epic_from_ai_ticket(self, ai_ticket:
|
|
113
|
+
def _epic_from_ai_ticket(self, ai_ticket: dict[str, Any]) -> Epic:
|
|
103
114
|
"""Convert AI-Trackdown ticket to universal Epic."""
|
|
104
115
|
return Epic(
|
|
105
116
|
id=ai_ticket.get("id"),
|
|
@@ -109,14 +120,20 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
109
120
|
priority=self._priority_from_ai(ai_ticket.get("priority", "medium")),
|
|
110
121
|
tags=ai_ticket.get("tags", []),
|
|
111
122
|
child_issues=ai_ticket.get("child_issues", []),
|
|
112
|
-
created_at=
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
123
|
+
created_at=(
|
|
124
|
+
datetime.fromisoformat(ai_ticket["created_at"])
|
|
125
|
+
if "created_at" in ai_ticket and ai_ticket["created_at"]
|
|
126
|
+
else None
|
|
127
|
+
),
|
|
128
|
+
updated_at=(
|
|
129
|
+
datetime.fromisoformat(ai_ticket["updated_at"])
|
|
130
|
+
if "updated_at" in ai_ticket and ai_ticket["updated_at"]
|
|
131
|
+
else None
|
|
132
|
+
),
|
|
116
133
|
metadata={"ai_trackdown": ai_ticket},
|
|
117
134
|
)
|
|
118
135
|
|
|
119
|
-
def _task_to_ai_ticket(self, task: Task) ->
|
|
136
|
+
def _task_to_ai_ticket(self, task: Task) -> dict[str, Any]:
|
|
120
137
|
"""Convert universal Task to AI-Trackdown ticket."""
|
|
121
138
|
# Handle enum values that may be stored as strings due to use_enum_values=True
|
|
122
139
|
state_value = task.state
|
|
@@ -124,7 +141,9 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
124
141
|
state_value = self._get_state_mapping()[task.state]
|
|
125
142
|
elif isinstance(task.state, str):
|
|
126
143
|
# Already a string, map to AI-Trackdown format if needed
|
|
127
|
-
state_value = task.state.replace(
|
|
144
|
+
state_value = task.state.replace(
|
|
145
|
+
"_", "-"
|
|
146
|
+
) # Convert snake_case to kebab-case
|
|
128
147
|
|
|
129
148
|
return {
|
|
130
149
|
"id": task.id,
|
|
@@ -141,7 +160,7 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
141
160
|
"type": "task",
|
|
142
161
|
}
|
|
143
162
|
|
|
144
|
-
def _epic_to_ai_ticket(self, epic: Epic) ->
|
|
163
|
+
def _epic_to_ai_ticket(self, epic: Epic) -> dict[str, Any]:
|
|
145
164
|
"""Convert universal Epic to AI-Trackdown ticket."""
|
|
146
165
|
# Handle enum values that may be stored as strings due to use_enum_values=True
|
|
147
166
|
state_value = epic.state
|
|
@@ -149,7 +168,9 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
149
168
|
state_value = self._get_state_mapping()[epic.state]
|
|
150
169
|
elif isinstance(epic.state, str):
|
|
151
170
|
# Already a string, map to AI-Trackdown format if needed
|
|
152
|
-
state_value = epic.state.replace(
|
|
171
|
+
state_value = epic.state.replace(
|
|
172
|
+
"_", "-"
|
|
173
|
+
) # Convert snake_case to kebab-case
|
|
153
174
|
|
|
154
175
|
return {
|
|
155
176
|
"id": epic.id,
|
|
@@ -164,15 +185,15 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
164
185
|
"type": "epic",
|
|
165
186
|
}
|
|
166
187
|
|
|
167
|
-
def _read_ticket_file(self, ticket_id: str) -> Optional[
|
|
188
|
+
def _read_ticket_file(self, ticket_id: str) -> Optional[dict[str, Any]]:
|
|
168
189
|
"""Read ticket from file system."""
|
|
169
190
|
ticket_file = self.tickets_dir / f"{ticket_id}.json"
|
|
170
191
|
if ticket_file.exists():
|
|
171
|
-
with open(ticket_file
|
|
192
|
+
with open(ticket_file) as f:
|
|
172
193
|
return json.load(f)
|
|
173
194
|
return None
|
|
174
195
|
|
|
175
|
-
def _write_ticket_file(self, ticket_id: str, data:
|
|
196
|
+
def _write_ticket_file(self, ticket_id: str, data: dict[str, Any]) -> None:
|
|
176
197
|
"""Write ticket to file system."""
|
|
177
198
|
ticket_file = self.tickets_dir / f"{ticket_id}.json"
|
|
178
199
|
with open(ticket_file, "w") as f:
|
|
@@ -230,9 +251,7 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
230
251
|
return None
|
|
231
252
|
|
|
232
253
|
async def update(
|
|
233
|
-
self,
|
|
234
|
-
ticket_id: str,
|
|
235
|
-
updates: Union[Dict[str, Any], Task]
|
|
254
|
+
self, ticket_id: str, updates: Union[dict[str, Any], Task]
|
|
236
255
|
) -> Optional[Task]:
|
|
237
256
|
"""Update a task."""
|
|
238
257
|
# Read existing ticket
|
|
@@ -244,7 +263,11 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
244
263
|
if isinstance(updates, Task):
|
|
245
264
|
# If updates is a Task object, copy all fields except frozen ones
|
|
246
265
|
for field in updates.__fields__:
|
|
247
|
-
if
|
|
266
|
+
if (
|
|
267
|
+
field not in ["ticket_type"]
|
|
268
|
+
and hasattr(updates, field)
|
|
269
|
+
and getattr(updates, field) is not None
|
|
270
|
+
):
|
|
248
271
|
setattr(existing, field, getattr(updates, field))
|
|
249
272
|
else:
|
|
250
273
|
# If updates is a dictionary
|
|
@@ -275,11 +298,8 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
275
298
|
return False
|
|
276
299
|
|
|
277
300
|
async def list(
|
|
278
|
-
self,
|
|
279
|
-
|
|
280
|
-
offset: int = 0,
|
|
281
|
-
filters: Optional[Dict[str, Any]] = None
|
|
282
|
-
) -> List[Task]:
|
|
301
|
+
self, limit: int = 10, offset: int = 0, filters: Optional[dict[str, Any]] = None
|
|
302
|
+
) -> list[Task]:
|
|
283
303
|
"""List tasks with pagination."""
|
|
284
304
|
tasks = []
|
|
285
305
|
|
|
@@ -295,7 +315,7 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
295
315
|
# Direct file operation - read all files, filter, then paginate
|
|
296
316
|
ticket_files = sorted(self.tickets_dir.glob("*.json"))
|
|
297
317
|
for ticket_file in ticket_files:
|
|
298
|
-
with open(ticket_file
|
|
318
|
+
with open(ticket_file) as f:
|
|
299
319
|
ai_ticket = json.load(f)
|
|
300
320
|
task = self._task_from_ai_ticket(ai_ticket)
|
|
301
321
|
|
|
@@ -319,11 +339,11 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
319
339
|
tasks.append(task)
|
|
320
340
|
|
|
321
341
|
# Apply pagination after filtering
|
|
322
|
-
tasks = tasks[offset:offset + limit]
|
|
342
|
+
tasks = tasks[offset : offset + limit]
|
|
323
343
|
|
|
324
344
|
return tasks
|
|
325
345
|
|
|
326
|
-
async def search(self, query: SearchQuery) ->
|
|
346
|
+
async def search(self, query: SearchQuery) -> builtins.list[Task]:
|
|
327
347
|
"""Search tasks using query parameters."""
|
|
328
348
|
filters = {}
|
|
329
349
|
if query.state:
|
|
@@ -340,8 +360,10 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
340
360
|
# Text search in title and description
|
|
341
361
|
if query.query:
|
|
342
362
|
search_text = query.query.lower()
|
|
343
|
-
if (
|
|
344
|
-
search_text not in (task.
|
|
363
|
+
if (
|
|
364
|
+
search_text not in (task.title or "").lower()
|
|
365
|
+
and search_text not in (task.description or "").lower()
|
|
366
|
+
):
|
|
345
367
|
continue
|
|
346
368
|
|
|
347
369
|
# Tag filtering
|
|
@@ -356,12 +378,10 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
356
378
|
results.append(task)
|
|
357
379
|
|
|
358
380
|
# Apply pagination
|
|
359
|
-
return results[query.offset:query.offset + query.limit]
|
|
381
|
+
return results[query.offset : query.offset + query.limit]
|
|
360
382
|
|
|
361
383
|
async def transition_state(
|
|
362
|
-
self,
|
|
363
|
-
ticket_id: str,
|
|
364
|
-
target_state: TicketState
|
|
384
|
+
self, ticket_id: str, target_state: TicketState
|
|
365
385
|
) -> Optional[Task]:
|
|
366
386
|
"""Transition task to new state."""
|
|
367
387
|
# Validate transition
|
|
@@ -390,19 +410,16 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
390
410
|
return comment
|
|
391
411
|
|
|
392
412
|
async def get_comments(
|
|
393
|
-
self,
|
|
394
|
-
|
|
395
|
-
limit: int = 10,
|
|
396
|
-
offset: int = 0
|
|
397
|
-
) -> List[Comment]:
|
|
413
|
+
self, ticket_id: str, limit: int = 10, offset: int = 0
|
|
414
|
+
) -> builtins.list[Comment]:
|
|
398
415
|
"""Get comments for a task."""
|
|
399
416
|
comments = []
|
|
400
417
|
comments_dir = self.base_path / "comments"
|
|
401
418
|
|
|
402
419
|
if comments_dir.exists():
|
|
403
420
|
comment_files = sorted(comments_dir.glob("*.json"))
|
|
404
|
-
for comment_file in comment_files[offset:offset + limit]:
|
|
405
|
-
with open(comment_file
|
|
421
|
+
for comment_file in comment_files[offset : offset + limit]:
|
|
422
|
+
with open(comment_file) as f:
|
|
406
423
|
data = json.load(f)
|
|
407
424
|
if data.get("ticket_id") == ticket_id:
|
|
408
425
|
comments.append(Comment(**data))
|
|
@@ -411,4 +428,4 @@ class AITrackdownAdapter(BaseAdapter[Task]):
|
|
|
411
428
|
|
|
412
429
|
|
|
413
430
|
# Register the adapter
|
|
414
|
-
AdapterRegistry.register("aitrackdown", AITrackdownAdapter)
|
|
431
|
+
AdapterRegistry.register("aitrackdown", AITrackdownAdapter)
|