mcp-ticketer 0.3.5__py3-none-any.whl → 0.12.0__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.

Files changed (84) hide show
  1. mcp_ticketer/__version__.py +3 -3
  2. mcp_ticketer/adapters/__init__.py +2 -0
  3. mcp_ticketer/adapters/aitrackdown.py +263 -14
  4. mcp_ticketer/adapters/asana/__init__.py +15 -0
  5. mcp_ticketer/adapters/asana/adapter.py +1308 -0
  6. mcp_ticketer/adapters/asana/client.py +292 -0
  7. mcp_ticketer/adapters/asana/mappers.py +334 -0
  8. mcp_ticketer/adapters/asana/types.py +146 -0
  9. mcp_ticketer/adapters/github.py +326 -109
  10. mcp_ticketer/adapters/hybrid.py +11 -11
  11. mcp_ticketer/adapters/jira.py +271 -25
  12. mcp_ticketer/adapters/linear/adapter.py +693 -39
  13. mcp_ticketer/adapters/linear/client.py +61 -9
  14. mcp_ticketer/adapters/linear/mappers.py +9 -3
  15. mcp_ticketer/adapters/linear/queries.py +9 -7
  16. mcp_ticketer/cache/memory.py +9 -8
  17. mcp_ticketer/cli/adapter_diagnostics.py +1 -1
  18. mcp_ticketer/cli/auggie_configure.py +104 -15
  19. mcp_ticketer/cli/codex_configure.py +188 -32
  20. mcp_ticketer/cli/configure.py +37 -48
  21. mcp_ticketer/cli/diagnostics.py +20 -18
  22. mcp_ticketer/cli/discover.py +292 -26
  23. mcp_ticketer/cli/gemini_configure.py +107 -26
  24. mcp_ticketer/cli/instruction_commands.py +429 -0
  25. mcp_ticketer/cli/linear_commands.py +105 -22
  26. mcp_ticketer/cli/main.py +1830 -435
  27. mcp_ticketer/cli/mcp_configure.py +296 -89
  28. mcp_ticketer/cli/migrate_config.py +12 -8
  29. mcp_ticketer/cli/platform_commands.py +123 -0
  30. mcp_ticketer/cli/platform_detection.py +412 -0
  31. mcp_ticketer/cli/python_detection.py +126 -0
  32. mcp_ticketer/cli/queue_commands.py +15 -15
  33. mcp_ticketer/cli/simple_health.py +1 -1
  34. mcp_ticketer/cli/ticket_commands.py +773 -0
  35. mcp_ticketer/cli/update_checker.py +313 -0
  36. mcp_ticketer/cli/utils.py +67 -62
  37. mcp_ticketer/core/__init__.py +14 -1
  38. mcp_ticketer/core/adapter.py +84 -15
  39. mcp_ticketer/core/config.py +44 -39
  40. mcp_ticketer/core/env_discovery.py +42 -12
  41. mcp_ticketer/core/env_loader.py +15 -14
  42. mcp_ticketer/core/exceptions.py +3 -3
  43. mcp_ticketer/core/http_client.py +26 -26
  44. mcp_ticketer/core/instructions.py +405 -0
  45. mcp_ticketer/core/mappers.py +11 -11
  46. mcp_ticketer/core/models.py +50 -20
  47. mcp_ticketer/core/onepassword_secrets.py +379 -0
  48. mcp_ticketer/core/project_config.py +57 -35
  49. mcp_ticketer/core/registry.py +3 -3
  50. mcp_ticketer/defaults/ticket_instructions.md +644 -0
  51. mcp_ticketer/mcp/__init__.py +29 -1
  52. mcp_ticketer/mcp/__main__.py +60 -0
  53. mcp_ticketer/mcp/server/__init__.py +25 -0
  54. mcp_ticketer/mcp/server/__main__.py +60 -0
  55. mcp_ticketer/mcp/{dto.py → server/dto.py} +32 -32
  56. mcp_ticketer/mcp/{server.py → server/main.py} +127 -74
  57. mcp_ticketer/mcp/{response_builder.py → server/response_builder.py} +2 -2
  58. mcp_ticketer/mcp/server/server_sdk.py +93 -0
  59. mcp_ticketer/mcp/server/tools/__init__.py +47 -0
  60. mcp_ticketer/mcp/server/tools/attachment_tools.py +226 -0
  61. mcp_ticketer/mcp/server/tools/bulk_tools.py +273 -0
  62. mcp_ticketer/mcp/server/tools/comment_tools.py +90 -0
  63. mcp_ticketer/mcp/server/tools/config_tools.py +381 -0
  64. mcp_ticketer/mcp/server/tools/hierarchy_tools.py +532 -0
  65. mcp_ticketer/mcp/server/tools/instruction_tools.py +293 -0
  66. mcp_ticketer/mcp/server/tools/pr_tools.py +154 -0
  67. mcp_ticketer/mcp/server/tools/search_tools.py +206 -0
  68. mcp_ticketer/mcp/server/tools/ticket_tools.py +430 -0
  69. mcp_ticketer/mcp/server/tools/user_ticket_tools.py +382 -0
  70. mcp_ticketer/queue/__init__.py +1 -0
  71. mcp_ticketer/queue/health_monitor.py +5 -4
  72. mcp_ticketer/queue/manager.py +15 -51
  73. mcp_ticketer/queue/queue.py +19 -19
  74. mcp_ticketer/queue/run_worker.py +1 -1
  75. mcp_ticketer/queue/ticket_registry.py +14 -14
  76. mcp_ticketer/queue/worker.py +16 -14
  77. {mcp_ticketer-0.3.5.dist-info → mcp_ticketer-0.12.0.dist-info}/METADATA +168 -32
  78. mcp_ticketer-0.12.0.dist-info/RECORD +91 -0
  79. mcp_ticketer-0.3.5.dist-info/RECORD +0 -62
  80. /mcp_ticketer/mcp/{constants.py → server/constants.py} +0 -0
  81. {mcp_ticketer-0.3.5.dist-info → mcp_ticketer-0.12.0.dist-info}/WHEEL +0 -0
  82. {mcp_ticketer-0.3.5.dist-info → mcp_ticketer-0.12.0.dist-info}/entry_points.txt +0 -0
  83. {mcp_ticketer-0.3.5.dist-info → mcp_ticketer-0.12.0.dist-info}/licenses/LICENSE +0 -0
  84. {mcp_ticketer-0.3.5.dist-info → mcp_ticketer-0.12.0.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)