mcp-ticketer 0.12.0__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 +1 -1
- mcp_ticketer/adapters/aitrackdown.py +385 -6
- mcp_ticketer/adapters/asana/adapter.py +108 -0
- mcp_ticketer/adapters/asana/mappers.py +14 -0
- mcp_ticketer/adapters/github.py +525 -11
- mcp_ticketer/adapters/hybrid.py +47 -5
- mcp_ticketer/adapters/jira.py +521 -0
- mcp_ticketer/adapters/linear/adapter.py +1784 -101
- mcp_ticketer/adapters/linear/client.py +85 -3
- mcp_ticketer/adapters/linear/mappers.py +96 -8
- 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/cli/adapter_diagnostics.py +3 -1
- mcp_ticketer/cli/auggie_configure.py +17 -5
- mcp_ticketer/cli/codex_configure.py +97 -61
- mcp_ticketer/cli/configure.py +851 -103
- mcp_ticketer/cli/cursor_configure.py +314 -0
- mcp_ticketer/cli/diagnostics.py +13 -12
- mcp_ticketer/cli/discover.py +5 -0
- mcp_ticketer/cli/gemini_configure.py +17 -5
- mcp_ticketer/cli/init_command.py +880 -0
- mcp_ticketer/cli/instruction_commands.py +6 -0
- mcp_ticketer/cli/main.py +233 -3151
- mcp_ticketer/cli/mcp_configure.py +672 -98
- mcp_ticketer/cli/mcp_server_commands.py +415 -0
- mcp_ticketer/cli/platform_detection.py +77 -12
- mcp_ticketer/cli/platform_installer.py +536 -0
- mcp_ticketer/cli/project_update_commands.py +350 -0
- mcp_ticketer/cli/setup_command.py +639 -0
- mcp_ticketer/cli/simple_health.py +12 -10
- mcp_ticketer/cli/ticket_commands.py +264 -24
- mcp_ticketer/core/__init__.py +28 -6
- mcp_ticketer/core/adapter.py +166 -1
- mcp_ticketer/core/config.py +21 -21
- mcp_ticketer/core/exceptions.py +7 -1
- mcp_ticketer/core/label_manager.py +732 -0
- mcp_ticketer/core/mappers.py +31 -19
- mcp_ticketer/core/models.py +135 -0
- mcp_ticketer/core/onepassword_secrets.py +1 -1
- mcp_ticketer/core/priority_matcher.py +463 -0
- mcp_ticketer/core/project_config.py +132 -14
- 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/mcp/server/diagnostic_helper.py +175 -0
- mcp_ticketer/mcp/server/main.py +106 -25
- mcp_ticketer/mcp/server/routing.py +655 -0
- mcp_ticketer/mcp/server/server_sdk.py +58 -0
- mcp_ticketer/mcp/server/tools/__init__.py +31 -12
- mcp_ticketer/mcp/server/tools/analysis_tools.py +854 -0
- mcp_ticketer/mcp/server/tools/attachment_tools.py +6 -8
- 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 +1184 -136
- mcp_ticketer/mcp/server/tools/diagnostic_tools.py +211 -0
- mcp_ticketer/mcp/server/tools/hierarchy_tools.py +870 -460
- mcp_ticketer/mcp/server/tools/instruction_tools.py +7 -5
- 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 +1070 -123
- mcp_ticketer/mcp/server/tools/user_ticket_tools.py +218 -236
- mcp_ticketer/queue/worker.py +1 -1
- 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.12.0.dist-info/METADATA +0 -550
- mcp_ticketer-0.12.0.dist-info/RECORD +0 -91
- {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.12.0.dist-info → mcp_ticketer-2.0.1.dist-info}/top_level.txt +0 -0
mcp_ticketer/adapters/hybrid.py
CHANGED
|
@@ -73,6 +73,9 @@ class HybridAdapter(BaseAdapter):
|
|
|
73
73
|
|
|
74
74
|
def _get_state_mapping(self) -> dict[TicketState, str]:
|
|
75
75
|
"""Get state mapping from primary adapter."""
|
|
76
|
+
# Type narrowing: primary_adapter_name is validated in __init__
|
|
77
|
+
if self.primary_adapter_name is None:
|
|
78
|
+
raise ValueError("Primary adapter name is not set")
|
|
76
79
|
primary = self.adapters[self.primary_adapter_name]
|
|
77
80
|
return primary._get_state_mapping()
|
|
78
81
|
|
|
@@ -163,8 +166,11 @@ class HybridAdapter(BaseAdapter):
|
|
|
163
166
|
Created ticket with universal ID
|
|
164
167
|
|
|
165
168
|
"""
|
|
169
|
+
if self.primary_adapter_name is None:
|
|
170
|
+
raise ValueError("Primary adapter name is not set")
|
|
171
|
+
|
|
166
172
|
universal_id = self._generate_universal_id()
|
|
167
|
-
results = []
|
|
173
|
+
results: list[tuple[str, Task | Epic]] = []
|
|
168
174
|
|
|
169
175
|
# Create in primary adapter first
|
|
170
176
|
primary = self.adapters[self.primary_adapter_name]
|
|
@@ -236,6 +242,9 @@ class HybridAdapter(BaseAdapter):
|
|
|
236
242
|
Ticket if found, None otherwise
|
|
237
243
|
|
|
238
244
|
"""
|
|
245
|
+
if self.primary_adapter_name is None:
|
|
246
|
+
raise ValueError("Primary adapter name is not set")
|
|
247
|
+
|
|
239
248
|
# Check if this is a universal ID
|
|
240
249
|
if ticket_id.startswith("hybrid-"):
|
|
241
250
|
# Get primary adapter ticket ID
|
|
@@ -266,7 +275,10 @@ class HybridAdapter(BaseAdapter):
|
|
|
266
275
|
Updated ticket from primary adapter
|
|
267
276
|
|
|
268
277
|
"""
|
|
269
|
-
|
|
278
|
+
if self.primary_adapter_name is None:
|
|
279
|
+
raise ValueError("Primary adapter name is not set")
|
|
280
|
+
|
|
281
|
+
universal_id: str | None = ticket_id
|
|
270
282
|
if not ticket_id.startswith("hybrid-"):
|
|
271
283
|
# Try to find universal ID by searching mapping
|
|
272
284
|
universal_id = self._find_universal_id(ticket_id)
|
|
@@ -279,6 +291,9 @@ class HybridAdapter(BaseAdapter):
|
|
|
279
291
|
# Update in all adapters
|
|
280
292
|
results = []
|
|
281
293
|
for adapter_name, adapter in self.adapters.items():
|
|
294
|
+
if universal_id is None:
|
|
295
|
+
logger.warning(f"No universal ID available for ticket: {ticket_id}")
|
|
296
|
+
continue
|
|
282
297
|
adapter_ticket_id = self._get_adapter_ticket_id(universal_id, adapter_name)
|
|
283
298
|
if not adapter_ticket_id:
|
|
284
299
|
logger.warning(f"No ticket ID for adapter {adapter_name}")
|
|
@@ -325,7 +340,10 @@ class HybridAdapter(BaseAdapter):
|
|
|
325
340
|
True if deleted from at least one adapter
|
|
326
341
|
|
|
327
342
|
"""
|
|
328
|
-
|
|
343
|
+
if self.primary_adapter_name is None:
|
|
344
|
+
raise ValueError("Primary adapter name is not set")
|
|
345
|
+
|
|
346
|
+
universal_id: str | None = ticket_id
|
|
329
347
|
if not ticket_id.startswith("hybrid-"):
|
|
330
348
|
universal_id = self._find_universal_id(ticket_id)
|
|
331
349
|
if not universal_id:
|
|
@@ -336,6 +354,9 @@ class HybridAdapter(BaseAdapter):
|
|
|
336
354
|
# Delete from all adapters
|
|
337
355
|
success_count = 0
|
|
338
356
|
for adapter_name, adapter in self.adapters.items():
|
|
357
|
+
if universal_id is None:
|
|
358
|
+
logger.warning(f"No universal ID available for ticket: {ticket_id}")
|
|
359
|
+
continue
|
|
339
360
|
adapter_ticket_id = self._get_adapter_ticket_id(universal_id, adapter_name)
|
|
340
361
|
if not adapter_ticket_id:
|
|
341
362
|
continue
|
|
@@ -372,6 +393,8 @@ class HybridAdapter(BaseAdapter):
|
|
|
372
393
|
List of tickets from primary adapter
|
|
373
394
|
|
|
374
395
|
"""
|
|
396
|
+
if self.primary_adapter_name is None:
|
|
397
|
+
raise ValueError("Primary adapter name is not set")
|
|
375
398
|
primary = self.adapters[self.primary_adapter_name]
|
|
376
399
|
return await primary.list(limit, offset, filters)
|
|
377
400
|
|
|
@@ -385,6 +408,8 @@ class HybridAdapter(BaseAdapter):
|
|
|
385
408
|
List of tickets matching search criteria
|
|
386
409
|
|
|
387
410
|
"""
|
|
411
|
+
if self.primary_adapter_name is None:
|
|
412
|
+
raise ValueError("Primary adapter name is not set")
|
|
388
413
|
primary = self.adapters[self.primary_adapter_name]
|
|
389
414
|
return await primary.search(query)
|
|
390
415
|
|
|
@@ -401,7 +426,10 @@ class HybridAdapter(BaseAdapter):
|
|
|
401
426
|
Updated ticket from primary adapter
|
|
402
427
|
|
|
403
428
|
"""
|
|
404
|
-
|
|
429
|
+
if self.primary_adapter_name is None:
|
|
430
|
+
raise ValueError("Primary adapter name is not set")
|
|
431
|
+
|
|
432
|
+
universal_id: str | None = ticket_id
|
|
405
433
|
if not ticket_id.startswith("hybrid-"):
|
|
406
434
|
universal_id = self._find_universal_id(ticket_id)
|
|
407
435
|
if not universal_id:
|
|
@@ -412,6 +440,9 @@ class HybridAdapter(BaseAdapter):
|
|
|
412
440
|
# Transition in all adapters
|
|
413
441
|
results = []
|
|
414
442
|
for adapter_name, adapter in self.adapters.items():
|
|
443
|
+
if universal_id is None:
|
|
444
|
+
logger.warning(f"No universal ID available for ticket: {ticket_id}")
|
|
445
|
+
continue
|
|
415
446
|
adapter_ticket_id = self._get_adapter_ticket_id(universal_id, adapter_name)
|
|
416
447
|
if not adapter_ticket_id:
|
|
417
448
|
continue
|
|
@@ -446,7 +477,10 @@ class HybridAdapter(BaseAdapter):
|
|
|
446
477
|
Created comment from primary adapter
|
|
447
478
|
|
|
448
479
|
"""
|
|
449
|
-
|
|
480
|
+
if self.primary_adapter_name is None:
|
|
481
|
+
raise ValueError("Primary adapter name is not set")
|
|
482
|
+
|
|
483
|
+
universal_id: str | None = comment.ticket_id
|
|
450
484
|
if not comment.ticket_id.startswith("hybrid-"):
|
|
451
485
|
universal_id = self._find_universal_id(comment.ticket_id)
|
|
452
486
|
if not universal_id:
|
|
@@ -457,6 +491,11 @@ class HybridAdapter(BaseAdapter):
|
|
|
457
491
|
# Add comment to all adapters
|
|
458
492
|
results = []
|
|
459
493
|
for adapter_name, adapter in self.adapters.items():
|
|
494
|
+
if universal_id is None:
|
|
495
|
+
logger.warning(
|
|
496
|
+
f"No universal ID available for ticket: {comment.ticket_id}"
|
|
497
|
+
)
|
|
498
|
+
continue
|
|
460
499
|
adapter_ticket_id = self._get_adapter_ticket_id(universal_id, adapter_name)
|
|
461
500
|
if not adapter_ticket_id:
|
|
462
501
|
continue
|
|
@@ -501,6 +540,9 @@ class HybridAdapter(BaseAdapter):
|
|
|
501
540
|
List of comments from primary adapter
|
|
502
541
|
|
|
503
542
|
"""
|
|
543
|
+
if self.primary_adapter_name is None:
|
|
544
|
+
raise ValueError("Primary adapter name is not set")
|
|
545
|
+
|
|
504
546
|
if ticket_id.startswith("hybrid-"):
|
|
505
547
|
# Get primary adapter ticket ID
|
|
506
548
|
primary_id = self._get_adapter_ticket_id(
|