mcp-ticketer 0.1.8__py3-none-any.whl → 0.1.12__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/__version__.py +1 -1
- mcp_ticketer/adapters/__init__.py +8 -1
- mcp_ticketer/adapters/aitrackdown.py +9 -5
- mcp_ticketer/adapters/github.py +263 -0
- mcp_ticketer/adapters/hybrid.py +505 -0
- mcp_ticketer/adapters/linear.py +220 -0
- mcp_ticketer/cli/configure.py +532 -0
- mcp_ticketer/cli/main.py +107 -0
- mcp_ticketer/cli/migrate_config.py +204 -0
- mcp_ticketer/core/project_config.py +553 -0
- mcp_ticketer/mcp/server.py +349 -15
- mcp_ticketer/queue/queue.py +4 -1
- {mcp_ticketer-0.1.8.dist-info → mcp_ticketer-0.1.12.dist-info}/METADATA +6 -5
- {mcp_ticketer-0.1.8.dist-info → mcp_ticketer-0.1.12.dist-info}/RECORD +18 -14
- {mcp_ticketer-0.1.8.dist-info → mcp_ticketer-0.1.12.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.1.8.dist-info → mcp_ticketer-0.1.12.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.1.8.dist-info → mcp_ticketer-0.1.12.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.1.8.dist-info → mcp_ticketer-0.1.12.dist-info}/top_level.txt +0 -0
mcp_ticketer/mcp/server.py
CHANGED
|
@@ -63,6 +63,10 @@ class MCPTicketServer:
|
|
|
63
63
|
result = await self._handle_comment(params)
|
|
64
64
|
elif method == "ticket/status":
|
|
65
65
|
result = await self._handle_queue_status(params)
|
|
66
|
+
elif method == "ticket/create_pr":
|
|
67
|
+
result = await self._handle_create_pr(params)
|
|
68
|
+
elif method == "ticket/link_pr":
|
|
69
|
+
result = await self._handle_link_pr(params)
|
|
66
70
|
elif method == "tools/list":
|
|
67
71
|
result = await self._handle_tools_list()
|
|
68
72
|
elif method == "tools/call":
|
|
@@ -134,11 +138,72 @@ class MCPTicketServer:
|
|
|
134
138
|
manager = WorkerManager()
|
|
135
139
|
manager.start_if_needed()
|
|
136
140
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
# Check if async mode is requested (for backward compatibility)
|
|
142
|
+
if params.get("async_mode", False):
|
|
143
|
+
return {
|
|
144
|
+
"queue_id": queue_id,
|
|
145
|
+
"status": "queued",
|
|
146
|
+
"message": f"Ticket creation queued with ID: {queue_id}"
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
# Poll for completion with timeout (default synchronous behavior)
|
|
150
|
+
max_wait_time = params.get("timeout", 30) # seconds, allow override
|
|
151
|
+
poll_interval = 0.5 # seconds
|
|
152
|
+
start_time = asyncio.get_event_loop().time()
|
|
153
|
+
|
|
154
|
+
while True:
|
|
155
|
+
# Check queue status
|
|
156
|
+
item = queue.get_item(queue_id)
|
|
157
|
+
|
|
158
|
+
if not item:
|
|
159
|
+
return {
|
|
160
|
+
"queue_id": queue_id,
|
|
161
|
+
"status": "error",
|
|
162
|
+
"error": f"Queue item {queue_id} not found"
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
# If completed, return with ticket ID
|
|
166
|
+
if item.status == QueueStatus.COMPLETED:
|
|
167
|
+
response = {
|
|
168
|
+
"queue_id": queue_id,
|
|
169
|
+
"status": "completed",
|
|
170
|
+
"title": params["title"]
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
# Add ticket ID and other result data if available
|
|
174
|
+
if item.result:
|
|
175
|
+
response["ticket_id"] = item.result.get("id")
|
|
176
|
+
if "state" in item.result:
|
|
177
|
+
response["state"] = item.result["state"]
|
|
178
|
+
# Try to construct URL if we have enough information
|
|
179
|
+
if response.get("ticket_id"):
|
|
180
|
+
# This is adapter-specific, but we can add URL generation later
|
|
181
|
+
response["id"] = response["ticket_id"] # Also include as "id" for compatibility
|
|
182
|
+
|
|
183
|
+
response["message"] = f"Ticket created successfully: {response.get('ticket_id', queue_id)}"
|
|
184
|
+
return response
|
|
185
|
+
|
|
186
|
+
# If failed, return error
|
|
187
|
+
if item.status == QueueStatus.FAILED:
|
|
188
|
+
return {
|
|
189
|
+
"queue_id": queue_id,
|
|
190
|
+
"status": "failed",
|
|
191
|
+
"error": item.error_message or "Ticket creation failed",
|
|
192
|
+
"title": params["title"]
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
# Check timeout
|
|
196
|
+
elapsed = asyncio.get_event_loop().time() - start_time
|
|
197
|
+
if elapsed > max_wait_time:
|
|
198
|
+
return {
|
|
199
|
+
"queue_id": queue_id,
|
|
200
|
+
"status": "timeout",
|
|
201
|
+
"message": f"Ticket creation timed out after {max_wait_time} seconds. Use ticket_status with queue_id to check status.",
|
|
202
|
+
"title": params["title"]
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
# Wait before next poll
|
|
206
|
+
await asyncio.sleep(poll_interval)
|
|
142
207
|
|
|
143
208
|
async def _handle_read(self, params: Dict[str, Any]) -> Optional[Dict[str, Any]]:
|
|
144
209
|
"""Handle ticket read."""
|
|
@@ -162,11 +227,60 @@ class MCPTicketServer:
|
|
|
162
227
|
manager = WorkerManager()
|
|
163
228
|
manager.start_if_needed()
|
|
164
229
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
230
|
+
# Poll for completion with timeout
|
|
231
|
+
max_wait_time = 30 # seconds
|
|
232
|
+
poll_interval = 0.5 # seconds
|
|
233
|
+
start_time = asyncio.get_event_loop().time()
|
|
234
|
+
|
|
235
|
+
while True:
|
|
236
|
+
# Check queue status
|
|
237
|
+
item = queue.get_item(queue_id)
|
|
238
|
+
|
|
239
|
+
if not item:
|
|
240
|
+
return {
|
|
241
|
+
"queue_id": queue_id,
|
|
242
|
+
"status": "error",
|
|
243
|
+
"error": f"Queue item {queue_id} not found"
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
# If completed, return with ticket ID
|
|
247
|
+
if item.status == QueueStatus.COMPLETED:
|
|
248
|
+
response = {
|
|
249
|
+
"queue_id": queue_id,
|
|
250
|
+
"status": "completed",
|
|
251
|
+
"ticket_id": params["ticket_id"]
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
# Add result data if available
|
|
255
|
+
if item.result:
|
|
256
|
+
if item.result.get("id"):
|
|
257
|
+
response["ticket_id"] = item.result["id"]
|
|
258
|
+
response["success"] = item.result.get("success", True)
|
|
259
|
+
|
|
260
|
+
response["message"] = f"Ticket updated successfully: {response['ticket_id']}"
|
|
261
|
+
return response
|
|
262
|
+
|
|
263
|
+
# If failed, return error
|
|
264
|
+
if item.status == QueueStatus.FAILED:
|
|
265
|
+
return {
|
|
266
|
+
"queue_id": queue_id,
|
|
267
|
+
"status": "failed",
|
|
268
|
+
"error": item.error_message or "Ticket update failed",
|
|
269
|
+
"ticket_id": params["ticket_id"]
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
# Check timeout
|
|
273
|
+
elapsed = asyncio.get_event_loop().time() - start_time
|
|
274
|
+
if elapsed > max_wait_time:
|
|
275
|
+
return {
|
|
276
|
+
"queue_id": queue_id,
|
|
277
|
+
"status": "timeout",
|
|
278
|
+
"message": f"Ticket update timed out after {max_wait_time} seconds. Use ticket_status with queue_id to check status.",
|
|
279
|
+
"ticket_id": params["ticket_id"]
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
# Wait before next poll
|
|
283
|
+
await asyncio.sleep(poll_interval)
|
|
170
284
|
|
|
171
285
|
async def _handle_delete(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
172
286
|
"""Handle ticket deletion."""
|
|
@@ -220,11 +334,61 @@ class MCPTicketServer:
|
|
|
220
334
|
manager = WorkerManager()
|
|
221
335
|
manager.start_if_needed()
|
|
222
336
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
337
|
+
# Poll for completion with timeout
|
|
338
|
+
max_wait_time = 30 # seconds
|
|
339
|
+
poll_interval = 0.5 # seconds
|
|
340
|
+
start_time = asyncio.get_event_loop().time()
|
|
341
|
+
|
|
342
|
+
while True:
|
|
343
|
+
# Check queue status
|
|
344
|
+
item = queue.get_item(queue_id)
|
|
345
|
+
|
|
346
|
+
if not item:
|
|
347
|
+
return {
|
|
348
|
+
"queue_id": queue_id,
|
|
349
|
+
"status": "error",
|
|
350
|
+
"error": f"Queue item {queue_id} not found"
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
# If completed, return with ticket ID
|
|
354
|
+
if item.status == QueueStatus.COMPLETED:
|
|
355
|
+
response = {
|
|
356
|
+
"queue_id": queue_id,
|
|
357
|
+
"status": "completed",
|
|
358
|
+
"ticket_id": params["ticket_id"],
|
|
359
|
+
"state": params["target_state"]
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
# Add result data if available
|
|
363
|
+
if item.result:
|
|
364
|
+
if item.result.get("id"):
|
|
365
|
+
response["ticket_id"] = item.result["id"]
|
|
366
|
+
response["success"] = item.result.get("success", True)
|
|
367
|
+
|
|
368
|
+
response["message"] = f"State transition completed successfully: {response['ticket_id']} → {params['target_state']}"
|
|
369
|
+
return response
|
|
370
|
+
|
|
371
|
+
# If failed, return error
|
|
372
|
+
if item.status == QueueStatus.FAILED:
|
|
373
|
+
return {
|
|
374
|
+
"queue_id": queue_id,
|
|
375
|
+
"status": "failed",
|
|
376
|
+
"error": item.error_message or "State transition failed",
|
|
377
|
+
"ticket_id": params["ticket_id"]
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
# Check timeout
|
|
381
|
+
elapsed = asyncio.get_event_loop().time() - start_time
|
|
382
|
+
if elapsed > max_wait_time:
|
|
383
|
+
return {
|
|
384
|
+
"queue_id": queue_id,
|
|
385
|
+
"status": "timeout",
|
|
386
|
+
"message": f"State transition timed out after {max_wait_time} seconds. Use ticket_status with queue_id to check status.",
|
|
387
|
+
"ticket_id": params["ticket_id"]
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
# Wait before next poll
|
|
391
|
+
await asyncio.sleep(poll_interval)
|
|
228
392
|
|
|
229
393
|
async def _handle_comment(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
230
394
|
"""Handle comment operations."""
|
|
@@ -298,6 +462,144 @@ class MCPTicketServer:
|
|
|
298
462
|
|
|
299
463
|
return response
|
|
300
464
|
|
|
465
|
+
async def _handle_create_pr(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
466
|
+
"""Handle PR creation for a ticket."""
|
|
467
|
+
ticket_id = params.get("ticket_id")
|
|
468
|
+
if not ticket_id:
|
|
469
|
+
raise ValueError("ticket_id is required")
|
|
470
|
+
|
|
471
|
+
# Check if adapter supports PR creation
|
|
472
|
+
adapter_name = self.adapter.__class__.__name__.lower()
|
|
473
|
+
|
|
474
|
+
if "github" in adapter_name:
|
|
475
|
+
# GitHub adapter supports direct PR creation
|
|
476
|
+
from ..adapters.github import GitHubAdapter
|
|
477
|
+
if isinstance(self.adapter, GitHubAdapter):
|
|
478
|
+
try:
|
|
479
|
+
result = await self.adapter.create_pull_request(
|
|
480
|
+
ticket_id=ticket_id,
|
|
481
|
+
base_branch=params.get("base_branch", "main"),
|
|
482
|
+
head_branch=params.get("head_branch"),
|
|
483
|
+
title=params.get("title"),
|
|
484
|
+
body=params.get("body"),
|
|
485
|
+
draft=params.get("draft", False),
|
|
486
|
+
)
|
|
487
|
+
return {
|
|
488
|
+
"success": True,
|
|
489
|
+
"pr_number": result.get("number"),
|
|
490
|
+
"pr_url": result.get("url"),
|
|
491
|
+
"branch": result.get("branch"),
|
|
492
|
+
"linked_issue": result.get("linked_issue"),
|
|
493
|
+
"message": f"Pull request created successfully: {result.get('url')}",
|
|
494
|
+
}
|
|
495
|
+
except Exception as e:
|
|
496
|
+
return {
|
|
497
|
+
"success": False,
|
|
498
|
+
"error": str(e),
|
|
499
|
+
"ticket_id": ticket_id,
|
|
500
|
+
}
|
|
501
|
+
elif "linear" in adapter_name:
|
|
502
|
+
# Linear adapter needs GitHub config for PR creation
|
|
503
|
+
from ..adapters.linear import LinearAdapter
|
|
504
|
+
if isinstance(self.adapter, LinearAdapter):
|
|
505
|
+
# For Linear, we prepare the branch and metadata but can't create the actual PR
|
|
506
|
+
# without GitHub integration configured
|
|
507
|
+
try:
|
|
508
|
+
github_config = {
|
|
509
|
+
"owner": params.get("github_owner"),
|
|
510
|
+
"repo": params.get("github_repo"),
|
|
511
|
+
"base_branch": params.get("base_branch", "main"),
|
|
512
|
+
"head_branch": params.get("head_branch"),
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
# Validate GitHub config for Linear
|
|
516
|
+
if not github_config.get("owner") or not github_config.get("repo"):
|
|
517
|
+
return {
|
|
518
|
+
"success": False,
|
|
519
|
+
"error": "GitHub owner and repo are required for Linear PR creation",
|
|
520
|
+
"ticket_id": ticket_id,
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
result = await self.adapter.create_pull_request_for_issue(
|
|
524
|
+
ticket_id=ticket_id,
|
|
525
|
+
github_config=github_config,
|
|
526
|
+
)
|
|
527
|
+
return {
|
|
528
|
+
"success": True,
|
|
529
|
+
"branch_name": result.get("branch_name"),
|
|
530
|
+
"ticket_id": ticket_id,
|
|
531
|
+
"message": result.get("message"),
|
|
532
|
+
"github_config": {
|
|
533
|
+
"owner": result.get("github_owner"),
|
|
534
|
+
"repo": result.get("github_repo"),
|
|
535
|
+
"base_branch": result.get("base_branch"),
|
|
536
|
+
},
|
|
537
|
+
}
|
|
538
|
+
except Exception as e:
|
|
539
|
+
return {
|
|
540
|
+
"success": False,
|
|
541
|
+
"error": str(e),
|
|
542
|
+
"ticket_id": ticket_id,
|
|
543
|
+
}
|
|
544
|
+
else:
|
|
545
|
+
return {
|
|
546
|
+
"success": False,
|
|
547
|
+
"error": f"PR creation not supported for adapter: {adapter_name}",
|
|
548
|
+
"ticket_id": ticket_id,
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
async def _handle_link_pr(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
552
|
+
"""Handle linking an existing PR to a ticket."""
|
|
553
|
+
ticket_id = params.get("ticket_id")
|
|
554
|
+
pr_url = params.get("pr_url")
|
|
555
|
+
|
|
556
|
+
if not ticket_id:
|
|
557
|
+
raise ValueError("ticket_id is required")
|
|
558
|
+
if not pr_url:
|
|
559
|
+
raise ValueError("pr_url is required")
|
|
560
|
+
|
|
561
|
+
adapter_name = self.adapter.__class__.__name__.lower()
|
|
562
|
+
|
|
563
|
+
if "github" in adapter_name:
|
|
564
|
+
from ..adapters.github import GitHubAdapter
|
|
565
|
+
if isinstance(self.adapter, GitHubAdapter):
|
|
566
|
+
try:
|
|
567
|
+
result = await self.adapter.link_existing_pull_request(
|
|
568
|
+
ticket_id=ticket_id,
|
|
569
|
+
pr_url=pr_url,
|
|
570
|
+
)
|
|
571
|
+
return result
|
|
572
|
+
except Exception as e:
|
|
573
|
+
return {
|
|
574
|
+
"success": False,
|
|
575
|
+
"error": str(e),
|
|
576
|
+
"ticket_id": ticket_id,
|
|
577
|
+
"pr_url": pr_url,
|
|
578
|
+
}
|
|
579
|
+
elif "linear" in adapter_name:
|
|
580
|
+
from ..adapters.linear import LinearAdapter
|
|
581
|
+
if isinstance(self.adapter, LinearAdapter):
|
|
582
|
+
try:
|
|
583
|
+
result = await self.adapter.link_to_pull_request(
|
|
584
|
+
ticket_id=ticket_id,
|
|
585
|
+
pr_url=pr_url,
|
|
586
|
+
)
|
|
587
|
+
return result
|
|
588
|
+
except Exception as e:
|
|
589
|
+
return {
|
|
590
|
+
"success": False,
|
|
591
|
+
"error": str(e),
|
|
592
|
+
"ticket_id": ticket_id,
|
|
593
|
+
"pr_url": pr_url,
|
|
594
|
+
}
|
|
595
|
+
else:
|
|
596
|
+
return {
|
|
597
|
+
"success": False,
|
|
598
|
+
"error": f"PR linking not supported for adapter: {adapter_name}",
|
|
599
|
+
"ticket_id": ticket_id,
|
|
600
|
+
"pr_url": pr_url,
|
|
601
|
+
}
|
|
602
|
+
|
|
301
603
|
async def _handle_initialize(self, params: Dict[str, Any]) -> Dict[str, Any]:
|
|
302
604
|
"""Handle initialize request from MCP client.
|
|
303
605
|
|
|
@@ -324,6 +626,34 @@ class MCPTicketServer:
|
|
|
324
626
|
"""List available MCP tools."""
|
|
325
627
|
return {
|
|
326
628
|
"tools": [
|
|
629
|
+
{
|
|
630
|
+
"name": "ticket_create_pr",
|
|
631
|
+
"description": "Create a GitHub PR linked to a ticket",
|
|
632
|
+
"inputSchema": {
|
|
633
|
+
"type": "object",
|
|
634
|
+
"properties": {
|
|
635
|
+
"ticket_id": {"type": "string", "description": "Ticket ID to link the PR to"},
|
|
636
|
+
"base_branch": {"type": "string", "description": "Target branch for the PR", "default": "main"},
|
|
637
|
+
"head_branch": {"type": "string", "description": "Source branch name (auto-generated if not provided)"},
|
|
638
|
+
"title": {"type": "string", "description": "PR title (uses ticket title if not provided)"},
|
|
639
|
+
"body": {"type": "string", "description": "PR description (auto-generated with issue link if not provided)"},
|
|
640
|
+
"draft": {"type": "boolean", "description": "Create as draft PR", "default": False},
|
|
641
|
+
},
|
|
642
|
+
"required": ["ticket_id"]
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
"name": "ticket_link_pr",
|
|
647
|
+
"description": "Link an existing PR to a ticket",
|
|
648
|
+
"inputSchema": {
|
|
649
|
+
"type": "object",
|
|
650
|
+
"properties": {
|
|
651
|
+
"ticket_id": {"type": "string", "description": "Ticket ID to link the PR to"},
|
|
652
|
+
"pr_url": {"type": "string", "description": "GitHub PR URL to link"},
|
|
653
|
+
},
|
|
654
|
+
"required": ["ticket_id", "pr_url"]
|
|
655
|
+
}
|
|
656
|
+
},
|
|
327
657
|
{
|
|
328
658
|
"name": "ticket_create",
|
|
329
659
|
"description": "Create a new ticket",
|
|
@@ -428,6 +758,10 @@ class MCPTicketServer:
|
|
|
428
758
|
result = await self._handle_search(arguments)
|
|
429
759
|
elif tool_name == "ticket_status":
|
|
430
760
|
result = await self._handle_queue_status(arguments)
|
|
761
|
+
elif tool_name == "ticket_create_pr":
|
|
762
|
+
result = await self._handle_create_pr(arguments)
|
|
763
|
+
elif tool_name == "ticket_link_pr":
|
|
764
|
+
result = await self._handle_link_pr(arguments)
|
|
431
765
|
else:
|
|
432
766
|
return {
|
|
433
767
|
"content": [
|
mcp_ticketer/queue/queue.py
CHANGED
|
@@ -173,7 +173,10 @@ class Queue:
|
|
|
173
173
|
''', (QueueStatus.PROCESSING.value, row[0]))
|
|
174
174
|
conn.commit()
|
|
175
175
|
|
|
176
|
-
|
|
176
|
+
# Create QueueItem from row and update status
|
|
177
|
+
item = QueueItem.from_row(row)
|
|
178
|
+
item.status = QueueStatus.PROCESSING
|
|
179
|
+
return item
|
|
177
180
|
|
|
178
181
|
return None
|
|
179
182
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-ticketer
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.12
|
|
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>
|
|
@@ -33,13 +33,14 @@ Classifier: Typing :: Typed
|
|
|
33
33
|
Requires-Python: >=3.9
|
|
34
34
|
Description-Content-Type: text/markdown
|
|
35
35
|
License-File: LICENSE
|
|
36
|
+
Requires-Dist: gql[httpx]>=3.0.0
|
|
37
|
+
Requires-Dist: httpx>=0.25.0
|
|
38
|
+
Requires-Dist: psutil>=5.9.0
|
|
36
39
|
Requires-Dist: pydantic>=2.0
|
|
37
|
-
Requires-Dist:
|
|
40
|
+
Requires-Dist: python-dotenv>=1.0.0
|
|
38
41
|
Requires-Dist: rich>=13.0.0
|
|
39
|
-
Requires-Dist:
|
|
42
|
+
Requires-Dist: typer>=0.9.0
|
|
40
43
|
Requires-Dist: typing-extensions>=4.8.0
|
|
41
|
-
Requires-Dist: python-dotenv>=1.0.0
|
|
42
|
-
Requires-Dist: psutil>=5.9.0
|
|
43
44
|
Provides-Extra: all
|
|
44
45
|
Requires-Dist: mcp-ticketer[github,jira,linear,mcp]; extra == "all"
|
|
45
46
|
Provides-Extra: dev
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
mcp_ticketer/__init__.py,sha256=ayPQdFr6msypD06_G96a1H0bdFCT1m1wDtv8MZBpY4I,496
|
|
2
|
-
mcp_ticketer/__version__.py,sha256=
|
|
2
|
+
mcp_ticketer/__version__.py,sha256=2z2sS0X87sc9LRMGkMvT42tCltfdduz3SdYRWzVz6sg,1115
|
|
3
3
|
mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
-
mcp_ticketer/adapters/__init__.py,sha256=
|
|
5
|
-
mcp_ticketer/adapters/aitrackdown.py,sha256=
|
|
6
|
-
mcp_ticketer/adapters/github.py,sha256=
|
|
4
|
+
mcp_ticketer/adapters/__init__.py,sha256=K_1egvhHb5F_7yFceUx2YzPGEoc7vX-q8dMVaS4K6gw,356
|
|
5
|
+
mcp_ticketer/adapters/aitrackdown.py,sha256=gqS_N6VGLoG5itUu17ANG5SefaAITYoW-t2xL9SrY-Y,15372
|
|
6
|
+
mcp_ticketer/adapters/github.py,sha256=onT8NhYaf9fIw2eCOTbZSkk7q4IoM7ZADRvRl9qrUz8,43850
|
|
7
|
+
mcp_ticketer/adapters/hybrid.py,sha256=H9B-pfWmDKXO3GgzxB8undEcZTMzLz_1a6zWhj7xfR0,18556
|
|
7
8
|
mcp_ticketer/adapters/jira.py,sha256=rd-8PseTsRyQNPjsrUJ8vJ8vfBpa6HWFBieOUyvw0Tg,28954
|
|
8
|
-
mcp_ticketer/adapters/linear.py,sha256=
|
|
9
|
+
mcp_ticketer/adapters/linear.py,sha256=neTxVy-QD23tTI7XKtnc5CBCpm3yVCULlgxG5oFSQI4,51752
|
|
9
10
|
mcp_ticketer/cache/__init__.py,sha256=MSi3GLXancfP2-edPC9TFAJk7r0j6H5-XmpMHnkGPbI,137
|
|
10
11
|
mcp_ticketer/cache/memory.py,sha256=gTzv-xF7qGfiYVUjG7lnzo0ZcqgXQajMl4NAYUcaytg,5133
|
|
11
12
|
mcp_ticketer/cli/__init__.py,sha256=YeljyLtv906TqkvRuEPhmKO-Uk0CberQ9I6kx1tx2UA,88
|
|
12
|
-
mcp_ticketer/cli/
|
|
13
|
+
mcp_ticketer/cli/configure.py,sha256=etFutvc0QpaVDMOsZiiN7wKuaT98Od1Tj9W6lsEWw5A,16351
|
|
14
|
+
mcp_ticketer/cli/main.py,sha256=K-Onbn5xla4SGpB1SD1tlby7cdEH44w4le-oKeDt6uI,30338
|
|
15
|
+
mcp_ticketer/cli/migrate_config.py,sha256=iZIstnlr9vkhiW_MlnSyJOkMi4KHQqrZ6Hz1ECD_VUk,6045
|
|
13
16
|
mcp_ticketer/cli/queue_commands.py,sha256=f3pEHKZ43dBHEIoCBvdfvjfMB9_WJltps9ATwTzorY0,8160
|
|
14
17
|
mcp_ticketer/cli/utils.py,sha256=NxsS91vKA8xZnDXKU2y0Gcyc4I_ctRyJj-wT7Xd1Q_Q,18589
|
|
15
18
|
mcp_ticketer/core/__init__.py,sha256=NA-rDvwuAOZ9sUZVYJOWp8bR6mOBG8w_5lpWTT75JNI,318
|
|
@@ -18,18 +21,19 @@ mcp_ticketer/core/config.py,sha256=9a2bksbcFr7KXeHSPY6KoSP5Pzt54utYPCmbM-1QKmk,1
|
|
|
18
21
|
mcp_ticketer/core/http_client.py,sha256=RM9CEMNcuRb-FxhAijmM_FeBMgxgh1OII9HIPBdJue0,13855
|
|
19
22
|
mcp_ticketer/core/mappers.py,sha256=8I4jcqDqoQEdWlteDMpVeVF3Wo0fDCkmFPRr8oNv8gA,16933
|
|
20
23
|
mcp_ticketer/core/models.py,sha256=K-bLuU_DNNVgjHnVFzAIbSa0kJwT2I3Hj24sCklwIYo,4374
|
|
24
|
+
mcp_ticketer/core/project_config.py,sha256=uVhlA9r6GI7h-fWCJeM_s4VMbbj8E7t4QGGOIoC3jd0,19913
|
|
21
25
|
mcp_ticketer/core/registry.py,sha256=fwje0fnjp0YKPZ0SrVWk82SMNLs7CD0JlHQmx7SigNo,3537
|
|
22
26
|
mcp_ticketer/mcp/__init__.py,sha256=Bvzof9vBu6VwcXcIZK8RgKv6ycRV9tDlO-9TUmd8zqQ,122
|
|
23
|
-
mcp_ticketer/mcp/server.py,sha256=
|
|
27
|
+
mcp_ticketer/mcp/server.py,sha256=TDuU8ChZC2QYSRo0uGHkVReblTf--hriOjxo-pSAF_Y,34068
|
|
24
28
|
mcp_ticketer/queue/__init__.py,sha256=xHBoUwor8ZdO8bIHc7nP25EsAp5Si5Co4g_8ybb7fes,230
|
|
25
29
|
mcp_ticketer/queue/__main__.py,sha256=kQd6iOCKbbFqpRdbIRavuI4_G7-oE898JE4a0yLEYPE,108
|
|
26
30
|
mcp_ticketer/queue/manager.py,sha256=79AH9oUxdBXH3lmJ3kIlFf2GQkWHL6XB6u5JqVWPq60,7571
|
|
27
|
-
mcp_ticketer/queue/queue.py,sha256=
|
|
31
|
+
mcp_ticketer/queue/queue.py,sha256=z4aivQCtsH5_OUr2OfXSfnFKzugTahNnwHw0LS3ZhZc,11549
|
|
28
32
|
mcp_ticketer/queue/run_worker.py,sha256=HFoykfDpOoz8OUxWbQ2Fka_UlGrYwjPVZ-DEimGFH9o,802
|
|
29
33
|
mcp_ticketer/queue/worker.py,sha256=cVjHR_kfnGKAkiUg0HuXCnbKeKNBBEuj0XZHgIuIn4k,14017
|
|
30
|
-
mcp_ticketer-0.1.
|
|
31
|
-
mcp_ticketer-0.1.
|
|
32
|
-
mcp_ticketer-0.1.
|
|
33
|
-
mcp_ticketer-0.1.
|
|
34
|
-
mcp_ticketer-0.1.
|
|
35
|
-
mcp_ticketer-0.1.
|
|
34
|
+
mcp_ticketer-0.1.12.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
|
|
35
|
+
mcp_ticketer-0.1.12.dist-info/METADATA,sha256=7acr6QDWin0CGPNxlHTjzcCgVQ12fERtS68xhFQW-No,11211
|
|
36
|
+
mcp_ticketer-0.1.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
37
|
+
mcp_ticketer-0.1.12.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
|
|
38
|
+
mcp_ticketer-0.1.12.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
|
|
39
|
+
mcp_ticketer-0.1.12.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|