mcp-ticketer 0.3.6__py3-none-any.whl → 0.4.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.
- mcp_ticketer/__init__.py +12 -3
- mcp_ticketer/__version__.py +1 -1
- mcp_ticketer/adapters/aitrackdown.py +1 -2
- mcp_ticketer/adapters/github.py +1 -2
- mcp_ticketer/adapters/jira.py +1 -2
- mcp_ticketer/adapters/linear/adapter.py +64 -22
- mcp_ticketer/adapters/linear/client.py +1 -2
- mcp_ticketer/adapters/linear/mappers.py +1 -2
- mcp_ticketer/cli/adapter_diagnostics.py +2 -4
- mcp_ticketer/cli/configure.py +9 -3
- mcp_ticketer/cli/discover.py +6 -2
- mcp_ticketer/cli/main.py +109 -35
- mcp_ticketer/cli/platform_commands.py +133 -0
- mcp_ticketer/cli/ticket_commands.py +765 -0
- mcp_ticketer/mcp/server.py +74 -14
- {mcp_ticketer-0.3.6.dist-info → mcp_ticketer-0.4.0.dist-info}/METADATA +1 -1
- {mcp_ticketer-0.3.6.dist-info → mcp_ticketer-0.4.0.dist-info}/RECORD +21 -19
- {mcp_ticketer-0.3.6.dist-info → mcp_ticketer-0.4.0.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.3.6.dist-info → mcp_ticketer-0.4.0.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.3.6.dist-info → mcp_ticketer-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.3.6.dist-info → mcp_ticketer-0.4.0.dist-info}/top_level.txt +0 -0
mcp_ticketer/__init__.py
CHANGED
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
"""MCP Ticketer - Universal ticket management interface."""
|
|
2
2
|
|
|
3
|
-
from .__version__ import (
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
from .__version__ import (
|
|
4
|
+
__author__,
|
|
5
|
+
__author_email__,
|
|
6
|
+
__copyright__,
|
|
7
|
+
__description__,
|
|
8
|
+
__license__,
|
|
9
|
+
__title__,
|
|
10
|
+
__version__,
|
|
11
|
+
__version_info__,
|
|
12
|
+
get_user_agent,
|
|
13
|
+
get_version,
|
|
14
|
+
)
|
|
6
15
|
|
|
7
16
|
__all__ = [
|
|
8
17
|
"__version__",
|
mcp_ticketer/__version__.py
CHANGED
|
@@ -7,8 +7,7 @@ from pathlib import Path
|
|
|
7
7
|
from typing import Any, Optional, Union
|
|
8
8
|
|
|
9
9
|
from ..core.adapter import BaseAdapter
|
|
10
|
-
from ..core.models import
|
|
11
|
-
TicketState)
|
|
10
|
+
from ..core.models import Comment, Epic, Priority, SearchQuery, Task, TicketState
|
|
12
11
|
from ..core.registry import AdapterRegistry
|
|
13
12
|
|
|
14
13
|
# Import ai-trackdown-pytools when available
|
mcp_ticketer/adapters/github.py
CHANGED
|
@@ -9,8 +9,7 @@ import httpx
|
|
|
9
9
|
|
|
10
10
|
from ..core.adapter import BaseAdapter
|
|
11
11
|
from ..core.env_loader import load_adapter_config, validate_adapter_config
|
|
12
|
-
from ..core.models import
|
|
13
|
-
TicketState)
|
|
12
|
+
from ..core.models import Comment, Epic, Priority, SearchQuery, Task, TicketState
|
|
14
13
|
from ..core.registry import AdapterRegistry
|
|
15
14
|
|
|
16
15
|
|
mcp_ticketer/adapters/jira.py
CHANGED
|
@@ -13,8 +13,7 @@ from httpx import AsyncClient, HTTPStatusError, TimeoutException
|
|
|
13
13
|
|
|
14
14
|
from ..core.adapter import BaseAdapter
|
|
15
15
|
from ..core.env_loader import load_adapter_config, validate_adapter_config
|
|
16
|
-
from ..core.models import
|
|
17
|
-
TicketState)
|
|
16
|
+
from ..core.models import Comment, Epic, Priority, SearchQuery, Task, TicketState
|
|
18
17
|
from ..core.registry import AdapterRegistry
|
|
19
18
|
|
|
20
19
|
logger = logging.getLogger(__name__)
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import asyncio
|
|
6
|
+
import logging
|
|
5
7
|
import os
|
|
6
8
|
from typing import Any
|
|
7
9
|
|
|
@@ -18,15 +20,27 @@ from ...core.adapter import BaseAdapter
|
|
|
18
20
|
from ...core.models import Comment, Epic, SearchQuery, Task, TicketState
|
|
19
21
|
from ...core.registry import AdapterRegistry
|
|
20
22
|
from .client import LinearGraphQLClient
|
|
21
|
-
from .mappers import (
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
from .
|
|
29
|
-
|
|
23
|
+
from .mappers import (
|
|
24
|
+
build_linear_issue_input,
|
|
25
|
+
build_linear_issue_update_input,
|
|
26
|
+
map_linear_comment_to_comment,
|
|
27
|
+
map_linear_issue_to_task,
|
|
28
|
+
map_linear_project_to_epic,
|
|
29
|
+
)
|
|
30
|
+
from .queries import (
|
|
31
|
+
ALL_FRAGMENTS,
|
|
32
|
+
CREATE_ISSUE_MUTATION,
|
|
33
|
+
LIST_ISSUES_QUERY,
|
|
34
|
+
SEARCH_ISSUES_QUERY,
|
|
35
|
+
UPDATE_ISSUE_MUTATION,
|
|
36
|
+
WORKFLOW_STATES_QUERY,
|
|
37
|
+
)
|
|
38
|
+
from .types import (
|
|
39
|
+
LinearStateMapping,
|
|
40
|
+
build_issue_filter,
|
|
41
|
+
get_linear_priority,
|
|
42
|
+
get_linear_state_type,
|
|
43
|
+
)
|
|
30
44
|
|
|
31
45
|
|
|
32
46
|
class LinearAdapter(BaseAdapter[Task]):
|
|
@@ -206,12 +220,14 @@ class LinearAdapter(BaseAdapter[Task]):
|
|
|
206
220
|
raise ValueError(f"Failed to load workflow states: {e}")
|
|
207
221
|
|
|
208
222
|
async def _load_team_labels(self, team_id: str) -> None:
|
|
209
|
-
"""Load and cache labels for the team.
|
|
223
|
+
"""Load and cache labels for the team with retry logic.
|
|
210
224
|
|
|
211
225
|
Args:
|
|
212
226
|
team_id: Linear team ID
|
|
213
227
|
|
|
214
228
|
"""
|
|
229
|
+
logger = logging.getLogger(__name__)
|
|
230
|
+
|
|
215
231
|
query = """
|
|
216
232
|
query GetTeamLabels($teamId: String!) {
|
|
217
233
|
team(id: $teamId) {
|
|
@@ -227,15 +243,32 @@ class LinearAdapter(BaseAdapter[Task]):
|
|
|
227
243
|
}
|
|
228
244
|
"""
|
|
229
245
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
246
|
+
max_retries = 3
|
|
247
|
+
for attempt in range(max_retries):
|
|
248
|
+
try:
|
|
249
|
+
result = await self.client.execute_query(query, {"teamId": team_id})
|
|
250
|
+
labels = result.get("team", {}).get("labels", {}).get("nodes", [])
|
|
251
|
+
self._labels_cache = labels
|
|
252
|
+
logger.info(f"Loaded {len(labels)} labels for team {team_id}")
|
|
253
|
+
return # Success
|
|
254
|
+
|
|
255
|
+
except Exception as e:
|
|
256
|
+
if attempt < max_retries - 1:
|
|
257
|
+
wait_time = 2**attempt
|
|
258
|
+
logger.warning(
|
|
259
|
+
f"Failed to load labels (attempt {attempt + 1}/{max_retries}): {e}. "
|
|
260
|
+
f"Retrying in {wait_time}s..."
|
|
261
|
+
)
|
|
262
|
+
await asyncio.sleep(wait_time)
|
|
263
|
+
else:
|
|
264
|
+
logger.error(
|
|
265
|
+
f"Failed to load team labels after {max_retries} attempts: {e}",
|
|
266
|
+
exc_info=True,
|
|
267
|
+
)
|
|
268
|
+
self._labels_cache = [] # Explicitly empty on failure
|
|
236
269
|
|
|
237
270
|
async def _resolve_label_ids(self, label_names: list[str]) -> list[str]:
|
|
238
|
-
"""Resolve label names to Linear label IDs.
|
|
271
|
+
"""Resolve label names to Linear label IDs with proper None vs empty list handling.
|
|
239
272
|
|
|
240
273
|
Args:
|
|
241
274
|
label_names: List of label names
|
|
@@ -244,16 +277,25 @@ class LinearAdapter(BaseAdapter[Task]):
|
|
|
244
277
|
List of Linear label IDs that exist
|
|
245
278
|
|
|
246
279
|
"""
|
|
247
|
-
import logging
|
|
248
|
-
|
|
249
280
|
logger = logging.getLogger(__name__)
|
|
250
281
|
|
|
251
|
-
|
|
282
|
+
# None = not loaded yet, [] = loaded but empty or failed
|
|
283
|
+
if self._labels_cache is None:
|
|
252
284
|
team_id = await self._ensure_team_id()
|
|
253
285
|
await self._load_team_labels(team_id)
|
|
254
286
|
|
|
287
|
+
if self._labels_cache is None:
|
|
288
|
+
# Still None after load attempt - should not happen
|
|
289
|
+
logger.error(
|
|
290
|
+
"Label cache is None after load attempt. Tags will be skipped."
|
|
291
|
+
)
|
|
292
|
+
return []
|
|
293
|
+
|
|
255
294
|
if not self._labels_cache:
|
|
256
|
-
|
|
295
|
+
# Empty list - either no labels in team or load failed
|
|
296
|
+
logger.warning(
|
|
297
|
+
f"Team has no labels available. Cannot resolve tags: {label_names}"
|
|
298
|
+
)
|
|
257
299
|
return []
|
|
258
300
|
|
|
259
301
|
# Create name -> ID mapping (case-insensitive)
|
|
@@ -823,7 +865,7 @@ class LinearAdapter(BaseAdapter[Task]):
|
|
|
823
865
|
|
|
824
866
|
comment_input = {
|
|
825
867
|
"issueId": linear_id,
|
|
826
|
-
"body": comment.
|
|
868
|
+
"body": comment.content,
|
|
827
869
|
}
|
|
828
870
|
|
|
829
871
|
result = await self.client.execute_mutation(
|
|
@@ -16,8 +16,7 @@ except ImportError:
|
|
|
16
16
|
HTTPXAsyncTransport = None
|
|
17
17
|
TransportError = Exception
|
|
18
18
|
|
|
19
|
-
from ...core.exceptions import
|
|
20
|
-
RateLimitError)
|
|
19
|
+
from ...core.exceptions import AdapterError, AuthenticationError, RateLimitError
|
|
21
20
|
|
|
22
21
|
|
|
23
22
|
class LinearGraphQLClient:
|
|
@@ -6,8 +6,7 @@ from datetime import datetime
|
|
|
6
6
|
from typing import Any
|
|
7
7
|
|
|
8
8
|
from ...core.models import Comment, Epic, Priority, Task, TicketState
|
|
9
|
-
from .types import
|
|
10
|
-
get_universal_state)
|
|
9
|
+
from .types import extract_linear_metadata, get_universal_priority, get_universal_state
|
|
11
10
|
|
|
12
11
|
|
|
13
12
|
def map_linear_issue_to_task(issue_data: dict[str, Any]) -> Task:
|
|
@@ -197,8 +197,7 @@ def _test_adapter_instantiation(console: Console) -> None:
|
|
|
197
197
|
if primary:
|
|
198
198
|
adapter_type = primary.adapter_type
|
|
199
199
|
# Build config from discovery
|
|
200
|
-
from ..mcp.server import
|
|
201
|
-
_build_adapter_config_from_env_vars
|
|
200
|
+
from ..mcp.server import _build_adapter_config_from_env_vars
|
|
202
201
|
|
|
203
202
|
config = _build_adapter_config_from_env_vars(adapter_type, {})
|
|
204
203
|
else:
|
|
@@ -385,8 +384,7 @@ def get_adapter_status() -> dict[str, Any]:
|
|
|
385
384
|
adapter_type = primary.adapter_type
|
|
386
385
|
status["configuration_source"] = primary.found_in
|
|
387
386
|
# Build basic config
|
|
388
|
-
from ..mcp.server import
|
|
389
|
-
_build_adapter_config_from_env_vars
|
|
387
|
+
from ..mcp.server import _build_adapter_config_from_env_vars
|
|
390
388
|
|
|
391
389
|
config = _build_adapter_config_from_env_vars(adapter_type, {})
|
|
392
390
|
else:
|
mcp_ticketer/cli/configure.py
CHANGED
|
@@ -9,9 +9,15 @@ from rich.panel import Panel
|
|
|
9
9
|
from rich.prompt import Confirm, Prompt
|
|
10
10
|
from rich.table import Table
|
|
11
11
|
|
|
12
|
-
from ..core.project_config import (
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
from ..core.project_config import (
|
|
13
|
+
AdapterConfig,
|
|
14
|
+
AdapterType,
|
|
15
|
+
ConfigResolver,
|
|
16
|
+
ConfigValidator,
|
|
17
|
+
HybridConfig,
|
|
18
|
+
SyncStrategy,
|
|
19
|
+
TicketerConfig,
|
|
20
|
+
)
|
|
15
21
|
|
|
16
22
|
console = Console()
|
|
17
23
|
|
mcp_ticketer/cli/discover.py
CHANGED
|
@@ -7,8 +7,12 @@ import typer
|
|
|
7
7
|
from rich.console import Console
|
|
8
8
|
|
|
9
9
|
from ..core.env_discovery import DiscoveredAdapter, EnvDiscovery
|
|
10
|
-
from ..core.project_config import (
|
|
11
|
-
|
|
10
|
+
from ..core.project_config import (
|
|
11
|
+
AdapterConfig,
|
|
12
|
+
ConfigResolver,
|
|
13
|
+
ConfigValidator,
|
|
14
|
+
TicketerConfig,
|
|
15
|
+
)
|
|
12
16
|
|
|
13
17
|
console = Console()
|
|
14
18
|
app = typer.Typer(help="Auto-discover configuration from .env files")
|
mcp_ticketer/cli/main.py
CHANGED
|
@@ -21,13 +21,13 @@ from ..core.models import Comment, SearchQuery
|
|
|
21
21
|
from ..queue import Queue, QueueStatus, WorkerManager
|
|
22
22
|
from ..queue.health_monitor import HealthStatus, QueueHealthMonitor
|
|
23
23
|
from ..queue.ticket_registry import TicketRegistry
|
|
24
|
-
from .configure import
|
|
25
|
-
show_current_config)
|
|
24
|
+
from .configure import configure_wizard, set_adapter_config, show_current_config
|
|
26
25
|
from .diagnostics import run_diagnostics
|
|
27
26
|
from .discover import app as discover_app
|
|
28
|
-
from .linear_commands import app as linear_app
|
|
29
27
|
from .migrate_config import migrate_config_command
|
|
28
|
+
from .platform_commands import app as platform_app
|
|
30
29
|
from .queue_commands import app as queue_app
|
|
30
|
+
from .ticket_commands import app as ticket_app
|
|
31
31
|
|
|
32
32
|
# Load environment variables from .env files
|
|
33
33
|
# Priority: .env.local (highest) > .env (base)
|
|
@@ -1143,9 +1143,14 @@ def migrate_config(
|
|
|
1143
1143
|
migrate_config_command(dry_run=dry_run)
|
|
1144
1144
|
|
|
1145
1145
|
|
|
1146
|
-
@app.command("status")
|
|
1147
|
-
def
|
|
1148
|
-
"""Show queue and worker status.
|
|
1146
|
+
@app.command("queue-status", deprecated=True, hidden=True)
|
|
1147
|
+
def old_queue_status_command():
|
|
1148
|
+
"""Show queue and worker status.
|
|
1149
|
+
|
|
1150
|
+
DEPRECATED: Use 'mcp-ticketer queue status' instead.
|
|
1151
|
+
"""
|
|
1152
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer queue status' instead.[/yellow]\n")
|
|
1153
|
+
|
|
1149
1154
|
queue = Queue()
|
|
1150
1155
|
manager = WorkerManager()
|
|
1151
1156
|
|
|
@@ -1170,12 +1175,12 @@ def status_command():
|
|
|
1170
1175
|
console.print("\n[red]○ Worker is not running[/red]")
|
|
1171
1176
|
if pending > 0:
|
|
1172
1177
|
console.print(
|
|
1173
|
-
"[yellow]Note: There are pending items. Start worker with 'mcp-ticketer worker start'[/yellow]"
|
|
1178
|
+
"[yellow]Note: There are pending items. Start worker with 'mcp-ticketer queue worker start'[/yellow]"
|
|
1174
1179
|
)
|
|
1175
1180
|
|
|
1176
1181
|
|
|
1177
|
-
@app.command()
|
|
1178
|
-
def
|
|
1182
|
+
@app.command("queue-health", deprecated=True, hidden=True)
|
|
1183
|
+
def old_queue_health_command(
|
|
1179
1184
|
auto_repair: bool = typer.Option(
|
|
1180
1185
|
False, "--auto-repair", help="Attempt automatic repair of issues"
|
|
1181
1186
|
),
|
|
@@ -1183,7 +1188,11 @@ def health(
|
|
|
1183
1188
|
False, "--verbose", "-v", help="Show detailed health information"
|
|
1184
1189
|
),
|
|
1185
1190
|
) -> None:
|
|
1186
|
-
"""Check queue system health and detect issues immediately.
|
|
1191
|
+
"""Check queue system health and detect issues immediately.
|
|
1192
|
+
|
|
1193
|
+
DEPRECATED: Use 'mcp-ticketer queue health' instead.
|
|
1194
|
+
"""
|
|
1195
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer queue health' instead.[/yellow]\n")
|
|
1187
1196
|
health_monitor = QueueHealthMonitor()
|
|
1188
1197
|
health = health_monitor.check_health()
|
|
1189
1198
|
|
|
@@ -1252,7 +1261,7 @@ def health(
|
|
|
1252
1261
|
raise typer.Exit(2)
|
|
1253
1262
|
|
|
1254
1263
|
|
|
1255
|
-
@app.command()
|
|
1264
|
+
@app.command(deprecated=True, hidden=True)
|
|
1256
1265
|
def create(
|
|
1257
1266
|
title: str = typer.Argument(..., help="Ticket title"),
|
|
1258
1267
|
description: Optional[str] = typer.Option(
|
|
@@ -1281,7 +1290,12 @@ def create(
|
|
|
1281
1290
|
None, "--adapter", help="Override default adapter"
|
|
1282
1291
|
),
|
|
1283
1292
|
) -> None:
|
|
1284
|
-
"""Create a new ticket with comprehensive health checks.
|
|
1293
|
+
"""Create a new ticket with comprehensive health checks.
|
|
1294
|
+
|
|
1295
|
+
DEPRECATED: Use 'mcp-ticketer ticket create' instead.
|
|
1296
|
+
"""
|
|
1297
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket create' instead.[/yellow]\n")
|
|
1298
|
+
|
|
1285
1299
|
# IMMEDIATE HEALTH CHECK - Critical for reliability
|
|
1286
1300
|
health_monitor = QueueHealthMonitor()
|
|
1287
1301
|
health = health_monitor.check_health()
|
|
@@ -1477,7 +1491,7 @@ def create(
|
|
|
1477
1491
|
)
|
|
1478
1492
|
|
|
1479
1493
|
|
|
1480
|
-
@app.command("list")
|
|
1494
|
+
@app.command("list", deprecated=True, hidden=True)
|
|
1481
1495
|
def list_tickets(
|
|
1482
1496
|
state: Optional[TicketState] = typer.Option(
|
|
1483
1497
|
None, "--state", "-s", help="Filter by state"
|
|
@@ -1490,7 +1504,11 @@ def list_tickets(
|
|
|
1490
1504
|
None, "--adapter", help="Override default adapter"
|
|
1491
1505
|
),
|
|
1492
1506
|
) -> None:
|
|
1493
|
-
"""List tickets with optional filters.
|
|
1507
|
+
"""List tickets with optional filters.
|
|
1508
|
+
|
|
1509
|
+
DEPRECATED: Use 'mcp-ticketer ticket list' instead.
|
|
1510
|
+
"""
|
|
1511
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket list' instead.[/yellow]\n")
|
|
1494
1512
|
|
|
1495
1513
|
async def _list():
|
|
1496
1514
|
adapter_instance = get_adapter(
|
|
@@ -1532,7 +1550,7 @@ def list_tickets(
|
|
|
1532
1550
|
console.print(table)
|
|
1533
1551
|
|
|
1534
1552
|
|
|
1535
|
-
@app.command()
|
|
1553
|
+
@app.command(deprecated=True, hidden=True)
|
|
1536
1554
|
def show(
|
|
1537
1555
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1538
1556
|
comments: bool = typer.Option(False, "--comments", "-c", help="Show comments"),
|
|
@@ -1540,7 +1558,11 @@ def show(
|
|
|
1540
1558
|
None, "--adapter", help="Override default adapter"
|
|
1541
1559
|
),
|
|
1542
1560
|
) -> None:
|
|
1543
|
-
"""Show detailed ticket information.
|
|
1561
|
+
"""Show detailed ticket information.
|
|
1562
|
+
|
|
1563
|
+
DEPRECATED: Use 'mcp-ticketer ticket show' instead.
|
|
1564
|
+
"""
|
|
1565
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket show' instead.[/yellow]\n")
|
|
1544
1566
|
|
|
1545
1567
|
async def _show():
|
|
1546
1568
|
adapter_instance = get_adapter(
|
|
@@ -1582,7 +1604,7 @@ def show(
|
|
|
1582
1604
|
console.print(comment.content)
|
|
1583
1605
|
|
|
1584
1606
|
|
|
1585
|
-
@app.command()
|
|
1607
|
+
@app.command(deprecated=True, hidden=True)
|
|
1586
1608
|
def comment(
|
|
1587
1609
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1588
1610
|
content: str = typer.Argument(..., help="Comment content"),
|
|
@@ -1590,7 +1612,11 @@ def comment(
|
|
|
1590
1612
|
None, "--adapter", help="Override default adapter"
|
|
1591
1613
|
),
|
|
1592
1614
|
) -> None:
|
|
1593
|
-
"""Add a comment to a ticket.
|
|
1615
|
+
"""Add a comment to a ticket.
|
|
1616
|
+
|
|
1617
|
+
DEPRECATED: Use 'mcp-ticketer ticket comment' instead.
|
|
1618
|
+
"""
|
|
1619
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket comment' instead.[/yellow]\n")
|
|
1594
1620
|
|
|
1595
1621
|
async def _comment():
|
|
1596
1622
|
adapter_instance = get_adapter(
|
|
@@ -1618,7 +1644,7 @@ def comment(
|
|
|
1618
1644
|
raise typer.Exit(1)
|
|
1619
1645
|
|
|
1620
1646
|
|
|
1621
|
-
@app.command()
|
|
1647
|
+
@app.command(deprecated=True, hidden=True)
|
|
1622
1648
|
def update(
|
|
1623
1649
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1624
1650
|
title: Optional[str] = typer.Option(None, "--title", help="New title"),
|
|
@@ -1635,7 +1661,11 @@ def update(
|
|
|
1635
1661
|
None, "--adapter", help="Override default adapter"
|
|
1636
1662
|
),
|
|
1637
1663
|
) -> None:
|
|
1638
|
-
"""Update ticket fields.
|
|
1664
|
+
"""Update ticket fields.
|
|
1665
|
+
|
|
1666
|
+
DEPRECATED: Use 'mcp-ticketer ticket update' instead.
|
|
1667
|
+
"""
|
|
1668
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket update' instead.[/yellow]\n")
|
|
1639
1669
|
updates = {}
|
|
1640
1670
|
if title:
|
|
1641
1671
|
updates["title"] = title
|
|
@@ -1682,7 +1712,7 @@ def update(
|
|
|
1682
1712
|
console.print("[dim]Worker started to process request[/dim]")
|
|
1683
1713
|
|
|
1684
1714
|
|
|
1685
|
-
@app.command()
|
|
1715
|
+
@app.command(deprecated=True, hidden=True)
|
|
1686
1716
|
def transition(
|
|
1687
1717
|
ticket_id: str = typer.Argument(..., help="Ticket ID"),
|
|
1688
1718
|
state_positional: Optional[TicketState] = typer.Argument(
|
|
@@ -1697,15 +1727,19 @@ def transition(
|
|
|
1697
1727
|
) -> None:
|
|
1698
1728
|
"""Change ticket state with validation.
|
|
1699
1729
|
|
|
1730
|
+
DEPRECATED: Use 'mcp-ticketer ticket transition' instead.
|
|
1731
|
+
|
|
1700
1732
|
Examples:
|
|
1701
1733
|
# Recommended syntax with flag:
|
|
1702
|
-
mcp-ticketer transition BTA-215 --state done
|
|
1703
|
-
mcp-ticketer transition BTA-215 -s in_progress
|
|
1734
|
+
mcp-ticketer ticket transition BTA-215 --state done
|
|
1735
|
+
mcp-ticketer ticket transition BTA-215 -s in_progress
|
|
1704
1736
|
|
|
1705
1737
|
# Legacy positional syntax (still supported):
|
|
1706
|
-
mcp-ticketer transition BTA-215 done
|
|
1738
|
+
mcp-ticketer ticket transition BTA-215 done
|
|
1707
1739
|
|
|
1708
1740
|
"""
|
|
1741
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket transition' instead.[/yellow]\n")
|
|
1742
|
+
|
|
1709
1743
|
# Determine which state to use (prefer flag over positional)
|
|
1710
1744
|
target_state = state if state is not None else state_positional
|
|
1711
1745
|
|
|
@@ -1748,7 +1782,7 @@ def transition(
|
|
|
1748
1782
|
console.print("[dim]Worker started to process request[/dim]")
|
|
1749
1783
|
|
|
1750
1784
|
|
|
1751
|
-
@app.command()
|
|
1785
|
+
@app.command(deprecated=True, hidden=True)
|
|
1752
1786
|
def search(
|
|
1753
1787
|
query: Optional[str] = typer.Argument(None, help="Search query"),
|
|
1754
1788
|
state: Optional[TicketState] = typer.Option(None, "--state", "-s"),
|
|
@@ -1759,7 +1793,11 @@ def search(
|
|
|
1759
1793
|
None, "--adapter", help="Override default adapter"
|
|
1760
1794
|
),
|
|
1761
1795
|
) -> None:
|
|
1762
|
-
"""Search tickets with advanced query.
|
|
1796
|
+
"""Search tickets with advanced query.
|
|
1797
|
+
|
|
1798
|
+
DEPRECATED: Use 'mcp-ticketer ticket search' instead.
|
|
1799
|
+
"""
|
|
1800
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket search' instead.[/yellow]\n")
|
|
1763
1801
|
|
|
1764
1802
|
async def _search():
|
|
1765
1803
|
adapter_instance = get_adapter(
|
|
@@ -1791,6 +1829,12 @@ def search(
|
|
|
1791
1829
|
console.print()
|
|
1792
1830
|
|
|
1793
1831
|
|
|
1832
|
+
# Add ticket command group to main app
|
|
1833
|
+
app.add_typer(ticket_app, name="ticket")
|
|
1834
|
+
|
|
1835
|
+
# Add platform command group to main app
|
|
1836
|
+
app.add_typer(platform_app, name="platform")
|
|
1837
|
+
|
|
1794
1838
|
# Add queue command to main app
|
|
1795
1839
|
app.add_typer(queue_app, name="queue")
|
|
1796
1840
|
|
|
@@ -1799,8 +1843,8 @@ app.add_typer(discover_app, name="discover")
|
|
|
1799
1843
|
|
|
1800
1844
|
|
|
1801
1845
|
# Add diagnostics command
|
|
1802
|
-
@app.command()
|
|
1803
|
-
def
|
|
1846
|
+
@app.command("diagnose")
|
|
1847
|
+
def diagnose_command(
|
|
1804
1848
|
output_file: Optional[str] = typer.Option(
|
|
1805
1849
|
None, "--output", "-o", help="Save full report to file"
|
|
1806
1850
|
),
|
|
@@ -1811,7 +1855,7 @@ def diagnose(
|
|
|
1811
1855
|
False, "--simple", help="Use simple diagnostics (no heavy dependencies)"
|
|
1812
1856
|
),
|
|
1813
1857
|
) -> None:
|
|
1814
|
-
"""Run comprehensive system diagnostics and health check."""
|
|
1858
|
+
"""Run comprehensive system diagnostics and health check (alias: doctor)."""
|
|
1815
1859
|
if simple:
|
|
1816
1860
|
from .simple_health import simple_diagnose
|
|
1817
1861
|
|
|
@@ -1846,9 +1890,36 @@ def diagnose(
|
|
|
1846
1890
|
raise typer.Exit(1)
|
|
1847
1891
|
|
|
1848
1892
|
|
|
1849
|
-
@app.command()
|
|
1850
|
-
def
|
|
1851
|
-
|
|
1893
|
+
@app.command("doctor")
|
|
1894
|
+
def doctor_alias(
|
|
1895
|
+
output_file: Optional[str] = typer.Option(
|
|
1896
|
+
None, "--output", "-o", help="Save full report to file"
|
|
1897
|
+
),
|
|
1898
|
+
json_output: bool = typer.Option(
|
|
1899
|
+
False, "--json", help="Output report in JSON format"
|
|
1900
|
+
),
|
|
1901
|
+
simple: bool = typer.Option(
|
|
1902
|
+
False, "--simple", help="Use simple diagnostics (no heavy dependencies)"
|
|
1903
|
+
),
|
|
1904
|
+
) -> None:
|
|
1905
|
+
"""Run comprehensive system diagnostics and health check (alias for diagnose)."""
|
|
1906
|
+
# Call the diagnose_command function with the same parameters
|
|
1907
|
+
diagnose_command(output_file=output_file, json_output=json_output, simple=simple)
|
|
1908
|
+
|
|
1909
|
+
|
|
1910
|
+
@app.command("status")
|
|
1911
|
+
def status_command() -> None:
|
|
1912
|
+
"""Quick health check - shows system status summary (alias: health)."""
|
|
1913
|
+
from .simple_health import simple_health_check
|
|
1914
|
+
|
|
1915
|
+
result = simple_health_check()
|
|
1916
|
+
if result != 0:
|
|
1917
|
+
raise typer.Exit(result)
|
|
1918
|
+
|
|
1919
|
+
|
|
1920
|
+
@app.command("health")
|
|
1921
|
+
def health_alias() -> None:
|
|
1922
|
+
"""Quick health check - shows system status summary (alias for status)."""
|
|
1852
1923
|
from .simple_health import simple_health_check
|
|
1853
1924
|
|
|
1854
1925
|
result = simple_health_check()
|
|
@@ -1864,9 +1935,13 @@ mcp_app = typer.Typer(
|
|
|
1864
1935
|
)
|
|
1865
1936
|
|
|
1866
1937
|
|
|
1867
|
-
@app.command()
|
|
1938
|
+
@app.command(deprecated=True, hidden=True)
|
|
1868
1939
|
def check(queue_id: str = typer.Argument(..., help="Queue ID to check")):
|
|
1869
|
-
"""Check status of a queued operation.
|
|
1940
|
+
"""Check status of a queued operation.
|
|
1941
|
+
|
|
1942
|
+
DEPRECATED: Use 'mcp-ticketer ticket check' instead.
|
|
1943
|
+
"""
|
|
1944
|
+
console.print("[yellow]⚠️ This command is deprecated. Use 'mcp-ticketer ticket check' instead.[/yellow]\n")
|
|
1870
1945
|
queue = Queue()
|
|
1871
1946
|
item = queue.get_item(queue_id)
|
|
1872
1947
|
|
|
@@ -2142,7 +2217,6 @@ def mcp_auggie(
|
|
|
2142
2217
|
|
|
2143
2218
|
|
|
2144
2219
|
# Add command groups to main app (must be after all subcommands are defined)
|
|
2145
|
-
app.add_typer(linear_app, name="linear")
|
|
2146
2220
|
app.add_typer(mcp_app, name="mcp")
|
|
2147
2221
|
|
|
2148
2222
|
|