mcp-ticketer 0.4.11__py3-none-any.whl → 2.0.1__py3-none-any.whl
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/__init__.py +10 -10
- mcp_ticketer/__version__.py +3 -3
- mcp_ticketer/adapters/__init__.py +2 -0
- mcp_ticketer/adapters/aitrackdown.py +394 -9
- mcp_ticketer/adapters/asana/__init__.py +15 -0
- mcp_ticketer/adapters/asana/adapter.py +1416 -0
- mcp_ticketer/adapters/asana/client.py +292 -0
- mcp_ticketer/adapters/asana/mappers.py +348 -0
- mcp_ticketer/adapters/asana/types.py +146 -0
- mcp_ticketer/adapters/github.py +836 -105
- mcp_ticketer/adapters/hybrid.py +47 -5
- mcp_ticketer/adapters/jira.py +772 -1
- mcp_ticketer/adapters/linear/adapter.py +2293 -108
- mcp_ticketer/adapters/linear/client.py +146 -12
- mcp_ticketer/adapters/linear/mappers.py +105 -11
- mcp_ticketer/adapters/linear/queries.py +168 -1
- mcp_ticketer/adapters/linear/types.py +80 -4
- mcp_ticketer/analysis/__init__.py +56 -0
- mcp_ticketer/analysis/dependency_graph.py +255 -0
- mcp_ticketer/analysis/health_assessment.py +304 -0
- mcp_ticketer/analysis/orphaned.py +218 -0
- mcp_ticketer/analysis/project_status.py +594 -0
- mcp_ticketer/analysis/similarity.py +224 -0
- mcp_ticketer/analysis/staleness.py +266 -0
- mcp_ticketer/automation/__init__.py +11 -0
- mcp_ticketer/automation/project_updates.py +378 -0
- mcp_ticketer/cache/memory.py +3 -3
- mcp_ticketer/cli/adapter_diagnostics.py +4 -2
- mcp_ticketer/cli/auggie_configure.py +18 -6
- mcp_ticketer/cli/codex_configure.py +175 -60
- mcp_ticketer/cli/configure.py +884 -146
- mcp_ticketer/cli/cursor_configure.py +314 -0
- mcp_ticketer/cli/diagnostics.py +31 -28
- mcp_ticketer/cli/discover.py +293 -21
- mcp_ticketer/cli/gemini_configure.py +18 -6
- mcp_ticketer/cli/init_command.py +880 -0
- mcp_ticketer/cli/instruction_commands.py +435 -0
- mcp_ticketer/cli/linear_commands.py +99 -15
- mcp_ticketer/cli/main.py +109 -2055
- mcp_ticketer/cli/mcp_configure.py +673 -99
- mcp_ticketer/cli/mcp_server_commands.py +415 -0
- mcp_ticketer/cli/migrate_config.py +12 -8
- mcp_ticketer/cli/platform_commands.py +6 -6
- mcp_ticketer/cli/platform_detection.py +477 -0
- mcp_ticketer/cli/platform_installer.py +536 -0
- mcp_ticketer/cli/project_update_commands.py +350 -0
- mcp_ticketer/cli/queue_commands.py +15 -15
- mcp_ticketer/cli/setup_command.py +639 -0
- mcp_ticketer/cli/simple_health.py +13 -11
- mcp_ticketer/cli/ticket_commands.py +277 -36
- mcp_ticketer/cli/update_checker.py +313 -0
- mcp_ticketer/cli/utils.py +45 -41
- mcp_ticketer/core/__init__.py +35 -1
- mcp_ticketer/core/adapter.py +170 -5
- mcp_ticketer/core/config.py +38 -31
- mcp_ticketer/core/env_discovery.py +33 -3
- mcp_ticketer/core/env_loader.py +7 -6
- mcp_ticketer/core/exceptions.py +10 -4
- mcp_ticketer/core/http_client.py +10 -10
- mcp_ticketer/core/instructions.py +405 -0
- mcp_ticketer/core/label_manager.py +732 -0
- mcp_ticketer/core/mappers.py +32 -20
- mcp_ticketer/core/models.py +136 -1
- mcp_ticketer/core/onepassword_secrets.py +379 -0
- mcp_ticketer/core/priority_matcher.py +463 -0
- mcp_ticketer/core/project_config.py +148 -14
- mcp_ticketer/core/registry.py +1 -1
- mcp_ticketer/core/session_state.py +171 -0
- mcp_ticketer/core/state_matcher.py +592 -0
- mcp_ticketer/core/url_parser.py +425 -0
- mcp_ticketer/core/validators.py +69 -0
- mcp_ticketer/defaults/ticket_instructions.md +644 -0
- mcp_ticketer/mcp/__init__.py +2 -2
- mcp_ticketer/mcp/server/__init__.py +2 -2
- mcp_ticketer/mcp/server/diagnostic_helper.py +175 -0
- mcp_ticketer/mcp/server/main.py +187 -93
- mcp_ticketer/mcp/server/routing.py +655 -0
- mcp_ticketer/mcp/server/server_sdk.py +58 -0
- mcp_ticketer/mcp/server/tools/__init__.py +37 -9
- mcp_ticketer/mcp/server/tools/analysis_tools.py +854 -0
- mcp_ticketer/mcp/server/tools/attachment_tools.py +65 -20
- mcp_ticketer/mcp/server/tools/bulk_tools.py +259 -202
- mcp_ticketer/mcp/server/tools/comment_tools.py +74 -12
- mcp_ticketer/mcp/server/tools/config_tools.py +1429 -0
- mcp_ticketer/mcp/server/tools/diagnostic_tools.py +211 -0
- mcp_ticketer/mcp/server/tools/hierarchy_tools.py +878 -319
- mcp_ticketer/mcp/server/tools/instruction_tools.py +295 -0
- mcp_ticketer/mcp/server/tools/label_tools.py +942 -0
- mcp_ticketer/mcp/server/tools/pr_tools.py +3 -7
- mcp_ticketer/mcp/server/tools/project_status_tools.py +158 -0
- mcp_ticketer/mcp/server/tools/project_update_tools.py +473 -0
- mcp_ticketer/mcp/server/tools/search_tools.py +180 -97
- mcp_ticketer/mcp/server/tools/session_tools.py +308 -0
- mcp_ticketer/mcp/server/tools/ticket_tools.py +1182 -82
- mcp_ticketer/mcp/server/tools/user_ticket_tools.py +364 -0
- mcp_ticketer/queue/health_monitor.py +1 -0
- mcp_ticketer/queue/manager.py +4 -4
- mcp_ticketer/queue/queue.py +3 -3
- mcp_ticketer/queue/run_worker.py +1 -1
- mcp_ticketer/queue/ticket_registry.py +2 -2
- mcp_ticketer/queue/worker.py +15 -13
- mcp_ticketer/utils/__init__.py +5 -0
- mcp_ticketer/utils/token_utils.py +246 -0
- mcp_ticketer-2.0.1.dist-info/METADATA +1366 -0
- mcp_ticketer-2.0.1.dist-info/RECORD +122 -0
- mcp_ticketer-0.4.11.dist-info/METADATA +0 -496
- mcp_ticketer-0.4.11.dist-info/RECORD +0 -77
- {mcp_ticketer-0.4.11.dist-info → mcp_ticketer-2.0.1.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.4.11.dist-info → mcp_ticketer-2.0.1.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.4.11.dist-info → mcp_ticketer-2.0.1.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.4.11.dist-info → mcp_ticketer-2.0.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"""Asana-specific types, constants, and state mappings."""
|
|
2
|
+
|
|
3
|
+
from enum import Enum
|
|
4
|
+
|
|
5
|
+
from ...core.models import Priority, TicketState
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class AsanaCustomFieldType(str, Enum):
|
|
9
|
+
"""Asana custom field types."""
|
|
10
|
+
|
|
11
|
+
TEXT = "text"
|
|
12
|
+
NUMBER = "number"
|
|
13
|
+
ENUM = "enum"
|
|
14
|
+
MULTI_ENUM = "multi_enum"
|
|
15
|
+
DATE = "date"
|
|
16
|
+
PEOPLE = "people"
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class AsanaStateMapping:
|
|
20
|
+
"""Mapping between universal TicketState and Asana states.
|
|
21
|
+
|
|
22
|
+
Asana doesn't have built-in workflow states like Linear or JIRA.
|
|
23
|
+
Instead, we use:
|
|
24
|
+
- completed boolean field (true/false)
|
|
25
|
+
- Custom field for extended states (if configured)
|
|
26
|
+
|
|
27
|
+
For now, we'll use a simple completed boolean mapping:
|
|
28
|
+
- DONE, CLOSED → completed = true
|
|
29
|
+
- All others → completed = false
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
TO_ASANA = {
|
|
33
|
+
TicketState.OPEN: False,
|
|
34
|
+
TicketState.IN_PROGRESS: False,
|
|
35
|
+
TicketState.READY: False,
|
|
36
|
+
TicketState.TESTED: False,
|
|
37
|
+
TicketState.DONE: True,
|
|
38
|
+
TicketState.WAITING: False,
|
|
39
|
+
TicketState.BLOCKED: False,
|
|
40
|
+
TicketState.CLOSED: True,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
FROM_ASANA = {
|
|
44
|
+
True: TicketState.DONE, # completed = true
|
|
45
|
+
False: TicketState.OPEN, # completed = false (default to OPEN)
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class AsanaPriorityMapping:
|
|
50
|
+
"""Mapping between universal Priority and Asana custom field values.
|
|
51
|
+
|
|
52
|
+
Asana doesn't have built-in priority field. We'll use custom enum field.
|
|
53
|
+
If no custom field exists, we store priority in tags.
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
TO_ASANA = {
|
|
57
|
+
Priority.LOW: "Low",
|
|
58
|
+
Priority.MEDIUM: "Medium",
|
|
59
|
+
Priority.HIGH: "High",
|
|
60
|
+
Priority.CRITICAL: "Critical",
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
FROM_ASANA = {
|
|
64
|
+
"low": Priority.LOW,
|
|
65
|
+
"medium": Priority.MEDIUM,
|
|
66
|
+
"high": Priority.HIGH,
|
|
67
|
+
"critical": Priority.CRITICAL,
|
|
68
|
+
"urgent": Priority.CRITICAL, # Map "urgent" to critical
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def map_priority_to_asana(priority: Priority) -> str:
|
|
73
|
+
"""Map universal priority to Asana custom field value.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
priority: Universal priority level
|
|
77
|
+
|
|
78
|
+
Returns:
|
|
79
|
+
Asana priority string
|
|
80
|
+
|
|
81
|
+
"""
|
|
82
|
+
return AsanaPriorityMapping.TO_ASANA.get(priority, "Medium")
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def map_priority_from_asana(asana_priority: str | None) -> Priority:
|
|
86
|
+
"""Map Asana custom field value to universal priority.
|
|
87
|
+
|
|
88
|
+
Args:
|
|
89
|
+
asana_priority: Asana priority string (can be None)
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
Universal priority level
|
|
93
|
+
|
|
94
|
+
"""
|
|
95
|
+
if not asana_priority:
|
|
96
|
+
return Priority.MEDIUM
|
|
97
|
+
|
|
98
|
+
return AsanaPriorityMapping.FROM_ASANA.get(asana_priority.lower(), Priority.MEDIUM)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def map_state_to_asana(state: TicketState) -> bool:
|
|
102
|
+
"""Map universal state to Asana completed boolean.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
state: Universal ticket state
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
True if completed, False otherwise
|
|
109
|
+
|
|
110
|
+
"""
|
|
111
|
+
return AsanaStateMapping.TO_ASANA.get(state, False)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def map_state_from_asana(
|
|
115
|
+
completed: bool, custom_state: str | None = None
|
|
116
|
+
) -> TicketState:
|
|
117
|
+
"""Map Asana completed boolean to universal state.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
completed: Asana completed boolean
|
|
121
|
+
custom_state: Optional custom field state value
|
|
122
|
+
|
|
123
|
+
Returns:
|
|
124
|
+
Universal ticket state
|
|
125
|
+
|
|
126
|
+
"""
|
|
127
|
+
# If custom state provided, try to map it
|
|
128
|
+
if custom_state:
|
|
129
|
+
state_lower = custom_state.lower()
|
|
130
|
+
if "progress" in state_lower or "started" in state_lower:
|
|
131
|
+
return TicketState.IN_PROGRESS
|
|
132
|
+
if "ready" in state_lower or "review" in state_lower:
|
|
133
|
+
return TicketState.READY
|
|
134
|
+
if "test" in state_lower:
|
|
135
|
+
return TicketState.TESTED
|
|
136
|
+
if "wait" in state_lower:
|
|
137
|
+
return TicketState.WAITING
|
|
138
|
+
if "block" in state_lower:
|
|
139
|
+
return TicketState.BLOCKED
|
|
140
|
+
if "done" in state_lower or "complete" in state_lower:
|
|
141
|
+
return TicketState.DONE
|
|
142
|
+
if "closed" in state_lower or "cancel" in state_lower:
|
|
143
|
+
return TicketState.CLOSED
|
|
144
|
+
|
|
145
|
+
# Fallback to simple completed boolean mapping
|
|
146
|
+
return AsanaStateMapping.FROM_ASANA.get(completed, TicketState.OPEN)
|