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
@@ -5,13 +5,13 @@ import sqlite3
5
5
  import threading
6
6
  from datetime import datetime, timedelta
7
7
  from pathlib import Path
8
- from typing import Any, Optional
8
+ from typing import Any
9
9
 
10
10
 
11
11
  class TicketRegistry:
12
12
  """Persistent registry for tracking ticket IDs and their lifecycle."""
13
13
 
14
- def __init__(self, db_path: Optional[Path] = None):
14
+ def __init__(self, db_path: Path | None = None):
15
15
  """Initialize ticket registry.
16
16
 
17
17
  Args:
@@ -27,7 +27,7 @@ class TicketRegistry:
27
27
  self._lock = threading.Lock()
28
28
  self._init_database()
29
29
 
30
- def _init_database(self):
30
+ def _init_database(self) -> None:
31
31
  """Initialize database schema."""
32
32
  with sqlite3.connect(self.db_path) as conn:
33
33
  # Ticket registry table
@@ -130,10 +130,10 @@ class TicketRegistry:
130
130
  self,
131
131
  queue_id: str,
132
132
  status: str,
133
- ticket_id: Optional[str] = None,
134
- result_data: Optional[dict[str, Any]] = None,
135
- error_message: Optional[str] = None,
136
- retry_count: Optional[int] = None,
133
+ ticket_id: str | None = None,
134
+ result_data: dict[str, Any] | None = None,
135
+ error_message: str | None = None,
136
+ retry_count: int | None = None,
137
137
  ) -> None:
138
138
  """Update ticket operation status.
139
139
 
@@ -149,7 +149,7 @@ class TicketRegistry:
149
149
  with self._lock:
150
150
  with sqlite3.connect(self.db_path) as conn:
151
151
  update_fields = ["status = ?", "updated_at = ?"]
152
- values = [status, datetime.now().isoformat()]
152
+ values: list[Any] = [status, datetime.now().isoformat()]
153
153
 
154
154
  if ticket_id is not None:
155
155
  update_fields.append("ticket_id = ?")
@@ -179,7 +179,7 @@ class TicketRegistry:
179
179
  )
180
180
  conn.commit()
181
181
 
182
- def get_ticket_info(self, queue_id: str) -> Optional[dict[str, Any]]:
182
+ def get_ticket_info(self, queue_id: str) -> dict[str, Any] | None:
183
183
  """Get ticket information by queue ID.
184
184
 
185
185
  Args:
@@ -202,7 +202,7 @@ class TicketRegistry:
202
202
  return None
203
203
 
204
204
  columns = [desc[0] for desc in cursor.description]
205
- ticket_info = dict(zip(columns, row))
205
+ ticket_info = dict(zip(columns, row, strict=False))
206
206
 
207
207
  # Parse JSON fields
208
208
  if ticket_info.get("ticket_data"):
@@ -236,7 +236,7 @@ class TicketRegistry:
236
236
  columns = [desc[0] for desc in cursor.description]
237
237
 
238
238
  for row in cursor.fetchall():
239
- ticket_info = dict(zip(columns, row))
239
+ ticket_info = dict(zip(columns, row, strict=False))
240
240
 
241
241
  # Parse JSON fields
242
242
  if ticket_info.get("ticket_data"):
@@ -273,7 +273,7 @@ class TicketRegistry:
273
273
  columns = [desc[0] for desc in cursor.description]
274
274
 
275
275
  for row in cursor.fetchall():
276
- ticket_info = dict(zip(columns, row))
276
+ ticket_info = dict(zip(columns, row, strict=False))
277
277
 
278
278
  # Parse JSON fields
279
279
  if ticket_info.get("ticket_data"):
@@ -306,7 +306,7 @@ class TicketRegistry:
306
306
  columns = [desc[0] for desc in cursor.description]
307
307
 
308
308
  for row in cursor.fetchall():
309
- ticket_info = dict(zip(columns, row))
309
+ ticket_info = dict(zip(columns, row, strict=False))
310
310
 
311
311
  # Parse JSON fields
312
312
  if ticket_info.get("ticket_data"):
@@ -436,7 +436,7 @@ class TicketRegistry:
436
436
  columns = [desc[0] for desc in cursor.description]
437
437
 
438
438
  for row in cursor.fetchall():
439
- recovery_info = dict(zip(columns, row))
439
+ recovery_info = dict(zip(columns, row, strict=False))
440
440
  if recovery_info.get("recovery_data"):
441
441
  recovery_info["recovery_data"] = json.loads(
442
442
  recovery_info["recovery_data"]
@@ -7,7 +7,7 @@ import threading
7
7
  import time
8
8
  from datetime import datetime
9
9
  from pathlib import Path
10
- from typing import Any, Optional
10
+ from typing import Any
11
11
 
12
12
  from dotenv import load_dotenv
13
13
 
@@ -58,7 +58,7 @@ class Worker:
58
58
 
59
59
  def __init__(
60
60
  self,
61
- queue: Optional[Queue] = None,
61
+ queue: Queue | None = None,
62
62
  batch_size: int = DEFAULT_BATCH_SIZE,
63
63
  max_concurrent: int = DEFAULT_MAX_CONCURRENT,
64
64
  ):
@@ -97,12 +97,12 @@ class Worker:
97
97
  f"Worker initialized with batch_size={batch_size}, max_concurrent={max_concurrent}"
98
98
  )
99
99
 
100
- def _signal_handler(self, signum, frame):
100
+ def _signal_handler(self, signum: int, frame: Any) -> None:
101
101
  """Handle shutdown signals."""
102
102
  logger.info(f"Received signal {signum}, shutting down...")
103
103
  self.stop()
104
104
 
105
- def start(self, daemon: bool = True):
105
+ def start(self, daemon: bool = True) -> None:
106
106
  """Start the worker.
107
107
 
108
108
  Args:
@@ -126,14 +126,14 @@ class Worker:
126
126
  # Run in main thread
127
127
  self._run_loop()
128
128
 
129
- def stop(self):
129
+ def stop(self) -> None:
130
130
  """Stop the worker."""
131
131
  logger.info("Stopping worker...")
132
132
  self.running = False
133
133
  self.stop_event.set()
134
134
 
135
- def _run_loop(self):
136
- """Main worker loop with batch processing."""
135
+ def _run_loop(self) -> None:
136
+ """Run main worker loop with batch processing."""
137
137
  logger.info("Worker loop started")
138
138
 
139
139
  # Reset any stuck items on startup
@@ -174,7 +174,7 @@ class Worker:
174
174
  break
175
175
  return batch
176
176
 
177
- async def _process_batch(self, batch: list[QueueItem]):
177
+ async def _process_batch(self, batch: list[QueueItem]) -> None:
178
178
  """Process a batch of queue items with concurrency control.
179
179
 
180
180
  Args:
@@ -199,7 +199,9 @@ class Worker:
199
199
  # Wait for all adapter groups to complete
200
200
  await asyncio.gather(*tasks, return_exceptions=True)
201
201
 
202
- async def _process_adapter_group(self, adapter: str, items: list[QueueItem]):
202
+ async def _process_adapter_group(
203
+ self, adapter: str, items: list[QueueItem]
204
+ ) -> None:
203
205
  """Process items for a specific adapter with concurrency control.
204
206
 
205
207
  Args:
@@ -216,7 +218,7 @@ class Worker:
216
218
  semaphore = self.adapter_semaphores[adapter]
217
219
 
218
220
  # Process items with concurrency control
219
- async def process_with_semaphore(item):
221
+ async def process_with_semaphore(item: QueueItem) -> None:
220
222
  async with semaphore:
221
223
  await self._process_item(item)
222
224
 
@@ -226,7 +228,7 @@ class Worker:
226
228
  # Process with concurrency control
227
229
  await asyncio.gather(*tasks, return_exceptions=True)
228
230
 
229
- async def _process_item(self, item: QueueItem):
231
+ async def _process_item(self, item: QueueItem) -> None:
230
232
  """Process a single queue item.
231
233
 
232
234
  Args:
@@ -333,7 +335,7 @@ class Worker:
333
335
  self.stats["items_failed"] += 1
334
336
  logger.error(f"Max retries exceeded for {item.id}, marking as failed")
335
337
 
336
- async def _check_rate_limit(self, adapter: str):
338
+ async def _check_rate_limit(self, adapter: str) -> None:
337
339
  """Check and enforce rate limits.
338
340
 
339
341
  Args:
@@ -357,7 +359,7 @@ class Worker:
357
359
 
358
360
  self.last_request_times[adapter] = datetime.now()
359
361
 
360
- def _get_adapter(self, item: QueueItem):
362
+ def _get_adapter(self, item: QueueItem) -> Any:
361
363
  """Get adapter instance for item.
362
364
 
363
365
  Args:
@@ -442,7 +444,7 @@ class Worker:
442
444
 
443
445
  return adapter
444
446
 
445
- async def _execute_operation(self, adapter, item: QueueItem) -> dict[str, Any]:
447
+ async def _execute_operation(self, adapter: Any, item: QueueItem) -> dict[str, Any]:
446
448
  """Execute the queued operation.
447
449
 
448
450
  Args:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mcp-ticketer
3
- Version: 0.3.5
3
+ Version: 0.12.0
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>
@@ -18,7 +18,6 @@ Classifier: License :: OSI Approved :: MIT License
18
18
  Classifier: Operating System :: OS Independent
19
19
  Classifier: Programming Language :: Python
20
20
  Classifier: Programming Language :: Python :: 3
21
- Classifier: Programming Language :: Python :: 3.9
22
21
  Classifier: Programming Language :: Python :: 3.10
23
22
  Classifier: Programming Language :: Python :: 3.11
24
23
  Classifier: Programming Language :: Python :: 3.12
@@ -30,11 +29,12 @@ Classifier: Topic :: Software Development :: Bug Tracking
30
29
  Classifier: Topic :: System :: Monitoring
31
30
  Classifier: Topic :: Internet :: WWW/HTTP
32
31
  Classifier: Typing :: Typed
33
- Requires-Python: >=3.9
32
+ Requires-Python: >=3.10
34
33
  Description-Content-Type: text/markdown
35
34
  License-File: LICENSE
36
35
  Requires-Dist: gql[httpx]>=3.0.0
37
36
  Requires-Dist: httpx>=0.25.0
37
+ Requires-Dist: mcp>=1.2.0
38
38
  Requires-Dist: psutil>=5.9.0
39
39
  Requires-Dist: pydantic>=2.0
40
40
  Requires-Dist: python-dotenv>=1.0.0
@@ -65,7 +65,7 @@ Requires-Dist: sphinx-autodoc-typehints>=1.25.0; extra == "docs"
65
65
  Requires-Dist: sphinx-click>=5.1.0; extra == "docs"
66
66
  Requires-Dist: myst-parser>=2.0.0; extra == "docs"
67
67
  Provides-Extra: mcp
68
- Requires-Dist: mcp>=0.1.0; extra == "mcp"
68
+ Requires-Dist: mcp>=1.2.0; extra == "mcp"
69
69
  Provides-Extra: jira
70
70
  Requires-Dist: jira>=3.5.0; extra == "jira"
71
71
  Requires-Dist: ai-trackdown-pytools>=1.5.0; extra == "jira"
@@ -103,6 +103,8 @@ Universal ticket management interface for AI agents with MCP (Model Context Prot
103
103
  - **🎨 Rich CLI**: Beautiful terminal interface with colors and tables
104
104
  - **📊 State Machine**: Built-in state transitions with validation
105
105
  - **🔍 Advanced Search**: Full-text search with multiple filters
106
+ - **📎 File Attachments**: Upload, list, and manage ticket attachments (AITrackdown adapter)
107
+ - **📝 Custom Instructions**: Customize ticket writing guidelines for your team
106
108
  - **📦 Easy Installation**: Available on PyPI with simple pip install
107
109
 
108
110
  ## 📦 Installation
@@ -138,29 +140,33 @@ MCP Ticketer integrates with multiple AI clients via the Model Context Protocol
138
140
 
139
141
  | AI Client | Support | Config Type | Project-Level | Setup Command |
140
142
  |-----------|---------|-------------|---------------|---------------|
141
- | **Claude Code** | ✅ Native | JSON | ✅ Yes | `mcp-ticketer mcp claude` |
142
- | **Gemini CLI** | ✅ Full | JSON | Yes | `mcp-ticketer mcp gemini` |
143
- | **Codex CLI** | ✅ Full | TOML | Global only | `mcp-ticketer mcp codex` |
144
- | **Auggie** | ✅ Full | JSON | ❌ Global only | `mcp-ticketer mcp auggie` |
143
+ | **Claude Code** | ✅ Native | JSON | ✅ Yes | `mcp-ticketer install claude-code` |
144
+ | **Claude Desktop** | ✅ Full | JSON | Global only | `mcp-ticketer install claude-desktop` |
145
+ | **Gemini CLI** | ✅ Full | JSON | Yes | `mcp-ticketer install gemini` |
146
+ | **Codex CLI** | ✅ Full | TOML | ❌ Global only | `mcp-ticketer install codex` |
147
+ | **Auggie** | ✅ Full | JSON | ❌ Global only | `mcp-ticketer install auggie` |
145
148
 
146
149
  ### Quick MCP Setup
147
150
 
148
151
  ```bash
149
- # Claude Code (recommended for project-specific workflows)
150
- mcp-ticketer init --adapter aitrackdown # First, initialize an adapter
151
- mcp-ticketer mcp claude # Then configure MCP
152
-
153
- # Gemini CLI (Google's AI client)
152
+ # Initialize adapter first (required)
154
153
  mcp-ticketer init --adapter aitrackdown
155
- mcp-ticketer mcp gemini --scope project
156
154
 
157
- # Codex CLI (global configuration, requires restart)
158
- mcp-ticketer init --adapter aitrackdown
159
- mcp-ticketer mcp codex
155
+ # Auto-detection (Recommended) - Interactive platform selection
156
+ mcp-ticketer install # Auto-detect and prompt for platform
160
157
 
161
- # Auggie (simple global setup)
162
- mcp-ticketer init --adapter aitrackdown
163
- mcp-ticketer mcp auggie
158
+ # See all detected platforms
159
+ mcp-ticketer install --auto-detect # Show what's installed on your system
160
+
161
+ # Install for all detected platforms at once
162
+ mcp-ticketer install --all # Configure all detected AI clients
163
+
164
+ # Or install for specific platform
165
+ mcp-ticketer install claude-code # Claude Code (project-level)
166
+ mcp-ticketer install claude-desktop # Claude Desktop (global)
167
+ mcp-ticketer install gemini # Gemini CLI
168
+ mcp-ticketer install codex # Codex CLI
169
+ mcp-ticketer install auggie # Auggie
164
170
  ```
165
171
 
166
172
  **See [AI Client Integration Guide](docs/AI_CLIENT_INTEGRATION.md) for detailed setup instructions.**
@@ -174,6 +180,13 @@ mcp-ticketer mcp auggie
174
180
  mcp-ticketer init --adapter aitrackdown
175
181
 
176
182
  # For Linear (requires API key)
183
+ # Option 1: Using team URL (easiest - paste your Linear team issues URL)
184
+ mcp-ticketer init --adapter linear --team-url https://linear.app/your-org/team/ENG/active
185
+
186
+ # Option 2: Using team key
187
+ mcp-ticketer init --adapter linear --team-key ENG
188
+
189
+ # Option 3: Using team ID
177
190
  mcp-ticketer init --adapter linear --team-id YOUR_TEAM_ID
178
191
 
179
192
  # For JIRA (requires server and credentials)
@@ -185,6 +198,22 @@ mcp-ticketer init --adapter jira \
185
198
  mcp-ticketer init --adapter github --repo owner/repo
186
199
  ```
187
200
 
201
+ **Note:** The following commands are synonymous and can be used interchangeably:
202
+ - `mcp-ticketer init` - Initialize configuration
203
+ - `mcp-ticketer install` - Install and configure (same as init)
204
+ - `mcp-ticketer setup` - Setup (same as init)
205
+
206
+ #### Automatic Validation
207
+
208
+ The init command now automatically validates your configuration after setup:
209
+ - Valid credentials → Setup completes immediately
210
+ - Invalid credentials → You'll be prompted to:
211
+ 1. Re-enter configuration (up to 3 retries)
212
+ 2. Continue anyway (skip validation)
213
+ 3. Exit and fix manually
214
+
215
+ You can always re-validate later with: `mcp-ticketer doctor`
216
+
188
217
  ### 2. Create Your First Ticket
189
218
 
190
219
  ```bash
@@ -213,19 +242,76 @@ mcp-ticketer transition TICKET-123 in_progress
213
242
  mcp-ticketer search "login bug" --state open
214
243
  ```
215
244
 
245
+ ### 4. Working with Attachments (AITrackdown)
246
+
247
+ ```bash
248
+ # Working with attachments through MCP
249
+ # (Requires MCP server running - see MCP Server Integration section)
250
+
251
+ # Attachments are managed through your AI client when using MCP
252
+ # Ask your AI assistant: "Add the document.pdf as an attachment to task-123"
253
+ ```
254
+
255
+ For programmatic access, see the [Attachments Guide](docs/ATTACHMENTS.md).
256
+
257
+ ### 5. Customize Ticket Writing Instructions
258
+
259
+ Customize ticket guidelines to match your team's conventions:
260
+
261
+ ```bash
262
+ # View current instructions
263
+ mcp-ticketer instructions show
264
+
265
+ # Add custom instructions from file
266
+ mcp-ticketer instructions add team_guidelines.md
267
+
268
+ # Edit instructions interactively
269
+ mcp-ticketer instructions edit
270
+
271
+ # Reset to defaults
272
+ mcp-ticketer instructions delete --yes
273
+ ```
274
+
275
+ **Example custom instructions:**
276
+ ```markdown
277
+ # Our Team's Ticket Guidelines
278
+
279
+ ## Title Format
280
+ [TEAM-ID] [Type] Brief description
281
+
282
+ ## Required Sections
283
+ 1. Problem Statement
284
+ 2. Acceptance Criteria (minimum 3)
285
+ 3. Testing Notes
286
+ ```
287
+
288
+ For details, see the [Ticket Instructions Guide](docs/features/ticket_instructions.md).
289
+
216
290
  ## 🤖 MCP Server Integration
217
291
 
218
- MCP Ticketer provides seamless integration with AI clients through automatic configuration:
292
+ MCP Ticketer provides seamless integration with AI clients through automatic configuration and platform detection:
219
293
 
220
294
  ```bash
221
- # Run MCP server manually (for testing)
222
- mcp-ticketer serve
223
-
224
- # Or configure your AI client automatically (recommended)
225
- mcp-ticketer mcp claude # For Claude Code
226
- mcp-ticketer mcp gemini # For Gemini CLI
227
- mcp-ticketer mcp codex # For Codex CLI
228
- mcp-ticketer mcp auggie # For Auggie
295
+ # Auto-detection (Recommended)
296
+ mcp-ticketer install # Interactive: detect and prompt for platform
297
+ mcp-ticketer install --auto-detect # Show all detected AI platforms
298
+ mcp-ticketer install --all # Install for all detected platforms
299
+ mcp-ticketer install --all --dry-run # Preview what would be installed
300
+
301
+ # Platform-specific installation
302
+ mcp-ticketer install claude-code # For Claude Code (project-level)
303
+ mcp-ticketer install claude-desktop # For Claude Desktop (global)
304
+ mcp-ticketer install gemini # For Gemini CLI
305
+ mcp-ticketer install codex # For Codex CLI
306
+ mcp-ticketer install auggie # For Auggie
307
+
308
+ # Manual MCP server control (advanced)
309
+ mcp-ticketer mcp # Start MCP server in current directory
310
+ mcp-ticketer mcp --path /path/to/project # Start in specific directory
311
+
312
+ # Remove MCP configuration when needed
313
+ mcp-ticketer remove claude-code # Remove from Claude Code
314
+ mcp-ticketer uninstall auggie # Alias for remove
229
315
  ```
230
316
 
231
317
  **Configuration is automatic** - the commands above will:
@@ -240,18 +326,68 @@ mcp-ticketer mcp auggie # For Auggie
240
326
  {
241
327
  "mcpServers": {
242
328
  "mcp-ticketer": {
243
- "command": "/path/to/mcp-ticketer",
244
- "args": ["serve"],
329
+ "command": "/path/to/venv/bin/python",
330
+ "args": ["-m", "mcp_ticketer.mcp.server", "/absolute/path/to/project"],
245
331
  "env": {
246
- "MCP_TICKETER_ADAPTER": "aitrackdown"
332
+ "MCP_TICKETER_ADAPTER": "aitrackdown",
333
+ "PYTHONPATH": "/absolute/path/to/project"
247
334
  }
248
335
  }
249
336
  }
250
337
  }
251
338
  ```
252
339
 
340
+ **Why this pattern?**
341
+ - **More Reliable**: Uses venv Python directly instead of binary wrapper
342
+ - **Consistent**: Matches proven mcp-vector-search pattern
343
+ - **Universal**: Works across pipx, pip, and uv installations
344
+ - **Better Errors**: Python module invocation provides clearer error messages
345
+
346
+ **Automatic Detection**: The `mcp-ticketer install` commands automatically detect your venv Python and generate the correct configuration.
347
+
253
348
  **See [AI Client Integration Guide](docs/AI_CLIENT_INTEGRATION.md) for client-specific details.**
254
349
 
350
+ ## ⚙️ Configuration
351
+
352
+ ### Linear Configuration
353
+
354
+ Configure Linear using a team **URL** (easiest), team **key**, or team **ID**:
355
+
356
+ **Option 1: Team URL** (Easiest)
357
+ ```bash
358
+ # Paste your Linear team issues URL during setup
359
+ mcp-ticketer init --adapter linear --team-url https://linear.app/your-org/team/ENG/active
360
+
361
+ # The system automatically extracts the team key and resolves it to the team ID
362
+ ```
363
+
364
+ **Option 2: Team Key**
365
+ ```bash
366
+ # In .env or environment
367
+ LINEAR_API_KEY=lin_api_...
368
+ LINEAR_TEAM_KEY=ENG
369
+ ```
370
+
371
+ **Option 3: Team ID**
372
+ ```bash
373
+ # In .env or environment
374
+ LINEAR_API_KEY=lin_api_...
375
+ LINEAR_TEAM_ID=02d15669-7351-4451-9719-807576c16049
376
+ ```
377
+
378
+ **Supported URL formats:**
379
+ - `https://linear.app/your-org/team/ABC/active` (full issues page)
380
+ - `https://linear.app/your-org/team/ABC/` (team page)
381
+ - `https://linear.app/your-org/team/ABC` (short form)
382
+
383
+ **Finding your team information:**
384
+ 1. **Easiest**: Copy the URL from your Linear team's issues page
385
+ 2. **Alternative**: Go to Linear Settings → Teams → Your Team → "Key" field (e.g., "ENG", "DESIGN", "PRODUCT")
386
+
387
+ ### Environment Variables
388
+
389
+ See [.env.example](.env.example) for a complete list of supported environment variables for all adapters.
390
+
255
391
  ## 📚 Documentation
256
392
 
257
393
  Full documentation is available at [https://mcp-ticketerer.readthedocs.io](https://mcp-ticketerer.readthedocs.io)
@@ -0,0 +1,91 @@
1
+ mcp_ticketer/__init__.py,sha256=Xx4WaprO5PXhVPbYi1L6tBmwmJMkYS-lMyG4ieN6QP0,717
2
+ mcp_ticketer/__version__.py,sha256=ipmyMyoWjL9gdtZT-t_XSPwAlB1yua9KCJpwqmJBvBc,1132
3
+ mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ mcp_ticketer/adapters/__init__.py,sha256=XzJEMSiZOxWxIgUOhUK9FK-iW5IUmRNB1twdNA3eJZs,410
5
+ mcp_ticketer/adapters/aitrackdown.py,sha256=eDLaarM6YQ4NPg66_NGgJ2AJ4VPKkDaFyldhSQdadXc,30382
6
+ mcp_ticketer/adapters/github.py,sha256=mkmOeA0i0EDWGWbdmhvS7x0k6ZUoW5HQH5ZRhksRPYs,54791
7
+ mcp_ticketer/adapters/hybrid.py,sha256=7ocRjK7N7FdXSUCeFc23jFevfVwcPvHPIsEPXV_4o1w,18997
8
+ mcp_ticketer/adapters/jira.py,sha256=TRX_SHDCJlkfL5HQrK_3AQv2PAAb0rTp92uwxsQiAp8,43993
9
+ mcp_ticketer/adapters/linear.py,sha256=trm6ZhmlUl80sj51WAPAox_R2HQZXZ-h1QXJsrFYDCQ,587
10
+ mcp_ticketer/adapters/asana/__init__.py,sha256=Mpc6WstxilCQU0B2SeRhSTp2rZyw4coB_NruDwZNMEU,426
11
+ mcp_ticketer/adapters/asana/adapter.py,sha256=W1ViNfeqad6zaYjJvqfcaBKSF5kQDWelHihqOSCnGB0,44229
12
+ mcp_ticketer/adapters/asana/client.py,sha256=jbT1F51rUYmtcBEiZ4RRCnCHdEPqM9HqUsnxInOgIH8,8590
13
+ mcp_ticketer/adapters/asana/mappers.py,sha256=sDjUteihmMkbG5rroa3OQxtL5E2Sb6u65ahpSPVExFI,10274
14
+ mcp_ticketer/adapters/asana/types.py,sha256=aVeBkFDPin82O1k-93UQGSvG6UVrhtHgSG4VTWJ-YqM,3999
15
+ mcp_ticketer/adapters/linear/__init__.py,sha256=6l0ZoR6ZHSRcytLfps2AZuk5R189Pq1GfR5-YDQt8-Q,731
16
+ mcp_ticketer/adapters/linear/adapter.py,sha256=W9Dhkne6VaOlBOQ1-X59s4iUIfiNKWL6rTM_88TQ_-0,54252
17
+ mcp_ticketer/adapters/linear/client.py,sha256=puVNqX3W2vJ7RLcVWXyja7j8-irciqc60MqgQQuQHzU,10522
18
+ mcp_ticketer/adapters/linear/mappers.py,sha256=k4XE10575vgCkYXKn5ZCCrxDX7Ss3Ntn9ebuJw11Eb8,9909
19
+ mcp_ticketer/adapters/linear/queries.py,sha256=K8y7xc3iH-q9LEUmg-0YDBhh546LAwLZDvVLkzx3yY4,7223
20
+ mcp_ticketer/adapters/linear/types.py,sha256=ugXtRGLljDw6yoCnEVgdFs0xLR9ErLdnv4ffh9EAUhk,7874
21
+ mcp_ticketer/cache/__init__.py,sha256=Xcd-cKnt-Cx7jBzvfzUUUPaGkmyXFi5XUFWw3Z4b7d4,138
22
+ mcp_ticketer/cache/memory.py,sha256=ZLzDryFbuxJL4J4d4i9uS_QkIKu4V7ZOnkGxFHFW7FA,5074
23
+ mcp_ticketer/cli/__init__.py,sha256=l9Q8iKmfGkTu0cssHBVqNZTsL4eAtFzOB25AED_0G6g,89
24
+ mcp_ticketer/cli/adapter_diagnostics.py,sha256=CIWW0_3pYSatwH3PXiPyPT2t33n4GFBgB827RThrakY,14986
25
+ mcp_ticketer/cli/auggie_configure.py,sha256=qxTZrVx27BYM7C_B23TCA8i58Zda70tvr4E1OBdFxaM,11802
26
+ mcp_ticketer/cli/codex_configure.py,sha256=CQKJ54IE_MRH3Z4ZnH7-YOnmK0paLKuFeAVeSfTyX8s,15273
27
+ mcp_ticketer/cli/configure.py,sha256=rDwD-dpxr8Fl3SnNXZqPnfP_W_bCQYQ6z0RlohwaD04,15732
28
+ mcp_ticketer/cli/diagnostics.py,sha256=XGq_XRfVOUZXfbhrowZ4HESrkH2A_82l35NTiGk5HVk,30150
29
+ mcp_ticketer/cli/discover.py,sha256=mGt6tJSiEgNGlCgcEhRPr2j895KWkfMCoQ3W1DhoD-o,22408
30
+ mcp_ticketer/cli/gemini_configure.py,sha256=CaQ6nqyuM_XiQc-76EarbVdydhla4EufDscbn0DiHSo,12716
31
+ mcp_ticketer/cli/instruction_commands.py,sha256=6X4gZLVVNRTgEeThUfq6C4jztYGDcryXsSflR3bwVlA,14208
32
+ mcp_ticketer/cli/linear_commands.py,sha256=hLb4MAVdSLsQxHbaa4f50t49B8A6sEFzCeWswf8j8_k,19851
33
+ mcp_ticketer/cli/main.py,sha256=fzdKjNNtqbU3S-kbz1y3gWAlWa1Kzt46lseWIank9F8,127403
34
+ mcp_ticketer/cli/mcp_configure.py,sha256=JVDgYvWc8DgU2gV59XWu9Gg7ZQ2aF_OhtzMjtp3eUKg,19457
35
+ mcp_ticketer/cli/migrate_config.py,sha256=5zeN1jtj6seKuQXEgSvL6PjZ_c6qkqx9w3VGFR4dwKY,6164
36
+ mcp_ticketer/cli/platform_commands.py,sha256=p1rkkkzGYexAugx9cmt1yNGI4oEPuD8sKMl60qBbTmY,3672
37
+ mcp_ticketer/cli/platform_detection.py,sha256=U7aGrfzVq3FFvm4fjfmoarGw8TPlbx77yXIbJ_YFpmE,13410
38
+ mcp_ticketer/cli/python_detection.py,sha256=qmhi0CIDKH_AUVGkJ9jyY1zBpx1cwiQNv0vnEvMYDFQ,4272
39
+ mcp_ticketer/cli/queue_commands.py,sha256=xVhGJH3rUB-_uV40KULTLeFqxI94CA5Ff8rO6sgM-f4,8018
40
+ mcp_ticketer/cli/simple_health.py,sha256=0c2QEKdWPykgR-4cLh2CsGDKjutLP-ghqyAFFh6qoeQ,7947
41
+ mcp_ticketer/cli/ticket_commands.py,sha256=00NNh2Ci_zDZHYUP_s4BIQ0LIaAXUUDXu-wdqUQGV7c,26753
42
+ mcp_ticketer/cli/update_checker.py,sha256=BsUeXe12sfW-v6YIsRaCg6OQrxzZwsB7mwYmyU9mwkk,9563
43
+ mcp_ticketer/cli/utils.py,sha256=YTPq2i09NO2xKvxJOaamQjb8sK_-JShYH43UTLWm8ys,23629
44
+ mcp_ticketer/core/__init__.py,sha256=hBeG-WjaOvha6pffREUN_Ns5pf76yAVmDIey9HQe1g4,814
45
+ mcp_ticketer/core/adapter.py,sha256=kowXMtvzRPHAXeGEAy3oFGwtVBnPRyBa-Og44_gsNjw,12156
46
+ mcp_ticketer/core/config.py,sha256=Wezm0waAdHOXUvmK7OkO_cVXNUJSztkUiHaGwX4J2Qk,19855
47
+ mcp_ticketer/core/env_discovery.py,sha256=hTPmztjzgAjkbtyUVjHNpgeTONKhDzDZ3hYnkNSH2NA,21331
48
+ mcp_ticketer/core/env_loader.py,sha256=ulV6pqziUcsdtAU-Ll5HiEJZmXObTDDRFxVQ6ZR-NP8,11801
49
+ mcp_ticketer/core/exceptions.py,sha256=g7d-8sQ_lpvtjMu_OkugG1WfegNLd_oN5D_7EDCv2eU,3642
50
+ mcp_ticketer/core/http_client.py,sha256=f8duQwqTimgC3UMTCynyPYeULYzYKHszjfwscbJ67eA,13950
51
+ mcp_ticketer/core/instructions.py,sha256=i3otZW_ClYnejFsur8hvW2ezsL92RjlrjzrKlL_vTLA,14428
52
+ mcp_ticketer/core/mappers.py,sha256=KXO_DUUYnbZFLdAU1RK7F1wwYPnVNjkuyicE_T61Kak,17418
53
+ mcp_ticketer/core/models.py,sha256=E4eKHPYP9oLca7kojqEe659jkYojuUN0ut21FXxod2Y,14455
54
+ mcp_ticketer/core/onepassword_secrets.py,sha256=HwvyTbKyHOh7EuNEXhssAKoCoyHdGIVyr71tP3SGPaU,12678
55
+ mcp_ticketer/core/project_config.py,sha256=zZC6vxzfb05csl0VGYS310JpLjhK4Izfal4_SjFIDz8,24397
56
+ mcp_ticketer/core/registry.py,sha256=D7jiQ2V3Q9NJzQy15TxT2ePo44pmI_ajRl7tr6kgAS0,3477
57
+ mcp_ticketer/defaults/ticket_instructions.md,sha256=gLyKghAy7WmhRnltN3YjaD_X18csBY2-orX80SUNHOA,18165
58
+ mcp_ticketer/mcp/__init__.py,sha256=iJfA61v2N-C1_I4WdVc1HV4I57OaqI9ciY6zywVYcLE,885
59
+ mcp_ticketer/mcp/__main__.py,sha256=Fo_5KJOFako2gi1Z1kk5zEt2sGJW6BX6oXlYp7twYTs,1713
60
+ mcp_ticketer/mcp/server/__init__.py,sha256=4uys8Wv29Ve9OgvP5QbiNiCWawGBtz56l4Xs7lje8cU,665
61
+ mcp_ticketer/mcp/server/__main__.py,sha256=xE1n94M5n2tKyT6qFIOXaqRXX7L--SxmCglKUPcljG0,1711
62
+ mcp_ticketer/mcp/server/constants.py,sha256=EBGsJtBPaTCvAm5rOMknckrXActrNIls7lRklnh1L4s,2072
63
+ mcp_ticketer/mcp/server/dto.py,sha256=FR_OBtaxrno8AsHynPwUUW715iAoaBkrr7Ud8HZTQW8,7233
64
+ mcp_ticketer/mcp/server/main.py,sha256=Cvyemnu65zNu6lpsy66n1wsmM0cKjgeY1su1allIBDM,49424
65
+ mcp_ticketer/mcp/server/response_builder.py,sha256=DUfe1e0CcXPlepLq-cGH6b_THqoZEynYfVKkZEeLe0M,4933
66
+ mcp_ticketer/mcp/server/server_sdk.py,sha256=KGpMvvJAckKl5ReLsyYvNJCM44nZRgY-V7dkgENTFX0,2554
67
+ mcp_ticketer/mcp/server/tools/__init__.py,sha256=6gat_3jPMhI55SbmvTW0rzDR20QYGPVjRY1Q8tJ_kd4,1444
68
+ mcp_ticketer/mcp/server/tools/attachment_tools.py,sha256=pOgRvdIGX0gW61ztHg23Is_VnzWGEfYSpmf9gDER6ig,7653
69
+ mcp_ticketer/mcp/server/tools/bulk_tools.py,sha256=H5RZylDsrYuTCDF1afUcVcm-Yv3cu052JwwBPW9-4YA,9200
70
+ mcp_ticketer/mcp/server/tools/comment_tools.py,sha256=XXPS4TCIDaxnoITdG4B38iOX9LOElqCZFus4FnULJeg,2702
71
+ mcp_ticketer/mcp/server/tools/config_tools.py,sha256=zHCclGE7Hs4JnJw5lkCaff_Fd7qfxo-P-NHmP2tE9eM,13086
72
+ mcp_ticketer/mcp/server/tools/hierarchy_tools.py,sha256=8h565_B5LAvTFX9M0P-NfGvEPGB6vYrEdi03tj4UyzI,16121
73
+ mcp_ticketer/mcp/server/tools/instruction_tools.py,sha256=0dntc978jJIhbnVTujAPFeAxW5vA7z3moGUOWSYzIws,9117
74
+ mcp_ticketer/mcp/server/tools/pr_tools.py,sha256=PoB5YABYIlrABw5-RPA8bTh8uHH3hituslV9ib9xUUU,4540
75
+ mcp_ticketer/mcp/server/tools/search_tools.py,sha256=60OwDXN9bLQKbe9apLmJDyM0TcTPCAv9Vp2X2gPBQX4,6952
76
+ mcp_ticketer/mcp/server/tools/ticket_tools.py,sha256=PdhIDQIOh_p4KklSLfMpAtFvsNXSHYjuG7xWIjKmD6Y,14282
77
+ mcp_ticketer/mcp/server/tools/user_ticket_tools.py,sha256=z6K4jkg_F-iOxDGrYwsqKkmg8Tc6MwK0x5jUOGPlbxs,13940
78
+ mcp_ticketer/queue/__init__.py,sha256=ut4EkrXng9RJlFPZRKUa3elhHo3MFGhshBXquZ16vcs,278
79
+ mcp_ticketer/queue/__main__.py,sha256=gc_tE9NUdK07OJfTZuD4t6KeBD_vxFQIhknGTQUG_jk,109
80
+ mcp_ticketer/queue/health_monitor.py,sha256=Mtp0_HC72VmkJY_zc1soXhWr7KBebThF63JPF5JcKaE,12279
81
+ mcp_ticketer/queue/manager.py,sha256=Fz-mcx9jdRBCt8ujwXNfi0wgn7heavTdzcM8269hX-Q,10752
82
+ mcp_ticketer/queue/queue.py,sha256=8I9Jqk4kbzBulOkG6wX9xvd5KqHQiOsyJxBT5ka5UiM,17947
83
+ mcp_ticketer/queue/run_worker.py,sha256=WTYvNxvyXxBOVYvMOVVC9F5_FCGV1oT3uJRppDAFA0k,1027
84
+ mcp_ticketer/queue/ticket_registry.py,sha256=wT5kN0xjBHYNNj4hgnZ1DYGv8pkHcSXV-FR-eViOoL4,15510
85
+ mcp_ticketer/queue/worker.py,sha256=HirWcSCVNaM-_5_dMdw-su8jNlaR_-5DU8vM9uY7CD4,21093
86
+ mcp_ticketer-0.12.0.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
87
+ mcp_ticketer-0.12.0.dist-info/METADATA,sha256=B_yiNS_fk6SOl-rUis64OdIjsv44AB2ntjszE8zGuI4,18320
88
+ mcp_ticketer-0.12.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
89
+ mcp_ticketer-0.12.0.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
90
+ mcp_ticketer-0.12.0.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
91
+ mcp_ticketer-0.12.0.dist-info/RECORD,,
@@ -1,62 +0,0 @@
1
- mcp_ticketer/__init__.py,sha256=Xx4WaprO5PXhVPbYi1L6tBmwmJMkYS-lMyG4ieN6QP0,717
2
- mcp_ticketer/__version__.py,sha256=RfLkvzGZCRZI8388D91iayKn1UOAoAbVt1mUwpoGOR8,1117
3
- mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- mcp_ticketer/adapters/__init__.py,sha256=B5DFllWn23hkhmrLykNO5uMMSdcFuuPHXyLw_jyFzuE,358
5
- mcp_ticketer/adapters/aitrackdown.py,sha256=Ecw2SQAGVQs5yMH6m2pj61LxCJsuy-g2bvF8uwTpLUE,22588
6
- mcp_ticketer/adapters/github.py,sha256=YbZ8hj4nOy4pGIbZ_0zwciNbNnwK69zqfljb-wc2tSY,47384
7
- mcp_ticketer/adapters/hybrid.py,sha256=UADYZLc_UNw0xHPSbgguBNzvUCnuYn12Qi9ea-zdlMk,19086
8
- mcp_ticketer/adapters/jira.py,sha256=labZFqOy_mmMmizC-RD1EQbu9m4LLtJywwZ956-_x5E,35347
9
- mcp_ticketer/adapters/linear.py,sha256=trm6ZhmlUl80sj51WAPAox_R2HQZXZ-h1QXJsrFYDCQ,587
10
- mcp_ticketer/adapters/linear/__init__.py,sha256=6l0ZoR6ZHSRcytLfps2AZuk5R189Pq1GfR5-YDQt8-Q,731
11
- mcp_ticketer/adapters/linear/adapter.py,sha256=EvF9FrxMQBVTtO6H3wd9aC8Xv_IeMPt4jM7e2WrsGWU,29610
12
- mcp_ticketer/adapters/linear/client.py,sha256=0UmWlSEcRiwnSMFYKL89KMrPPL8S8uZ5V6rIY_KFOQU,8803
13
- mcp_ticketer/adapters/linear/mappers.py,sha256=GN1X7bOcU-5dhDW3dAtSEGivinhFBc8hoKYot8c5tCo,9631
14
- mcp_ticketer/adapters/linear/queries.py,sha256=lT6z64eUjX50Mz00Mk7jkFCRKPM9GptHPelWMj2csXc,7200
15
- mcp_ticketer/adapters/linear/types.py,sha256=ugXtRGLljDw6yoCnEVgdFs0xLR9ErLdnv4ffh9EAUhk,7874
16
- mcp_ticketer/cache/__init__.py,sha256=Xcd-cKnt-Cx7jBzvfzUUUPaGkmyXFi5XUFWw3Z4b7d4,138
17
- mcp_ticketer/cache/memory.py,sha256=2yBqGi9i0SanlUhJoOC7nijWjoMa3_ntPe-V-AV-LfU,5042
18
- mcp_ticketer/cli/__init__.py,sha256=l9Q8iKmfGkTu0cssHBVqNZTsL4eAtFzOB25AED_0G6g,89
19
- mcp_ticketer/cli/adapter_diagnostics.py,sha256=pQDdtDgBwSW04wdFEPVzwbul3KgfB9g6ZMS85qpYulY,14988
20
- mcp_ticketer/cli/auggie_configure.py,sha256=MXKzLtqe3K_UTQ2GacHAWbvf_B0779KL325smiAKE0Q,8212
21
- mcp_ticketer/cli/codex_configure.py,sha256=k7-q5d7NICjm7Vxa-z0mejJNAG-bicAHKcwqrzdRDyU,9080
22
- mcp_ticketer/cli/configure.py,sha256=BsA_pSHQMQS0t1bJO_wMM8LWsd5sWJDASjEPRHvwC18,16198
23
- mcp_ticketer/cli/diagnostics.py,sha256=jHF68ydW3RNVGumBnHUjUmq6YOjQD2UDkx0O7M__xv0,29965
24
- mcp_ticketer/cli/discover.py,sha256=AF_qlQc1Oo0UkWayoF5pmRChS5J3fJjH6f2YZzd_k8w,13188
25
- mcp_ticketer/cli/gemini_configure.py,sha256=ZNSA1lBW-itVToza-JxW95Po7daVXKiZAh7lp6pmXMU,9343
26
- mcp_ticketer/cli/linear_commands.py,sha256=_8f8ze_1MbiUweU6RFHpldgfHLirysIdPjHr2_S0YhI,17319
27
- mcp_ticketer/cli/main.py,sha256=BFo7QYU0tTOHWSfTmegzDqflSYFytCE8Jw6QGB7TwaY,74470
28
- mcp_ticketer/cli/mcp_configure.py,sha256=RzV50UjXgOmvMp-9S0zS39psuvjffVByaMrqrUaAGAM,9594
29
- mcp_ticketer/cli/migrate_config.py,sha256=MYsr_C5ZxsGg0P13etWTWNrJ_lc6ElRCkzfQADYr3DM,5956
30
- mcp_ticketer/cli/queue_commands.py,sha256=mm-3H6jmkUGJDyU_E46o9iRpek8tvFCm77F19OtHiZI,7884
31
- mcp_ticketer/cli/simple_health.py,sha256=GlOLRRFoifCna995NoHuKpb3xmFkLi2b3Ke1hyeDvq4,7950
32
- mcp_ticketer/cli/utils.py,sha256=IOycMmhwtCDpL3RN_wVEZkYMg9FHyDr4mg5M9Bxzfbo,23041
33
- mcp_ticketer/core/__init__.py,sha256=eXovsaJymQRP2AwOBuOy6mFtI3I68D7gGenZ5V-IMqo,349
34
- mcp_ticketer/core/adapter.py,sha256=q64LxOInIno7EIbmuxItf8KEsd-g9grCs__Z4uwZHto,10273
35
- mcp_ticketer/core/config.py,sha256=ZaooOtim4ZgaQrDPjL5TWJ-K03N9hb0s63YehCsNqR0,19372
36
- mcp_ticketer/core/env_discovery.py,sha256=bHOfj7YVExhqFVxto3G-zZ8p6T12BOhF0J4IXCjdll8,19971
37
- mcp_ticketer/core/env_loader.py,sha256=VLCQhK50quM5e3LkrAGHD5on5vTBj18Z2IgNMNES14M,11866
38
- mcp_ticketer/core/exceptions.py,sha256=H1gUmNiOjVXn4CT-JLQcGXmjWxHaxxdFvwcpJLTrs-U,3621
39
- mcp_ticketer/core/http_client.py,sha256=s5ikMiwEJ8TJjNn73wu3gv3OdAtyBEpAqPnSroRMW2k,13971
40
- mcp_ticketer/core/mappers.py,sha256=1aG1jFsHTCwmGRVgOlXW-VOSTGzc86gv7qjDfiR1ups,17462
41
- mcp_ticketer/core/models.py,sha256=r3BqH0pK2ag2_7c7SSKMZe2G0K7eQID6qy2tkC-GvfI,13155
42
- mcp_ticketer/core/project_config.py,sha256=5W9YvDBBASEo5fBcSF-rlA1W3LwzkTv6_CEJXxnsOjc,23346
43
- mcp_ticketer/core/registry.py,sha256=ShYLDPE62KFJpB0kj_zFyQzRxSH3LkQEEuo1jaakb1k,3483
44
- mcp_ticketer/mcp/__init__.py,sha256=Y05eTzsPk0wH8yKNIM-ekpGjgSDO0bQr0EME-vOP4GE,123
45
- mcp_ticketer/mcp/constants.py,sha256=EBGsJtBPaTCvAm5rOMknckrXActrNIls7lRklnh1L4s,2072
46
- mcp_ticketer/mcp/dto.py,sha256=fUNAdCnPNp80s6RYLFqSmgqQZX04BHYry4GArmFkdG0,7336
47
- mcp_ticketer/mcp/response_builder.py,sha256=sEYiwQddlfQmIOcbQ-yBsDvH1EJfbTDwCEUJNf7q5Vk,4946
48
- mcp_ticketer/mcp/server.py,sha256=l9DQ4e9pzdIyIS3Y-gKQwzOzBiVxDi0YJO0U6EeCz5M,46825
49
- mcp_ticketer/queue/__init__.py,sha256=1YIaCpZpFqPcqvDEQXiEvDLiw94DXRdCJkBaVIFQrms,231
50
- mcp_ticketer/queue/__main__.py,sha256=gc_tE9NUdK07OJfTZuD4t6KeBD_vxFQIhknGTQUG_jk,109
51
- mcp_ticketer/queue/health_monitor.py,sha256=KFOzksomUFnS94XKBiuHFPmGK6b4QXWzsrjwhHkR9vI,12245
52
- mcp_ticketer/queue/manager.py,sha256=qo7splhIIqzPxINpD8Yflr335sRpuqXtWr2JlsjB8Us,12246
53
- mcp_ticketer/queue/queue.py,sha256=PIB_8gOE4rCb5_tBNKw9qD6YhSgH3Ei3IzVrUSY3F_o,17978
54
- mcp_ticketer/queue/run_worker.py,sha256=WhoeamL8LKZ66TM8W1PkMPwjF2w_EDFMP-mevs6C1TM,1019
55
- mcp_ticketer/queue/ticket_registry.py,sha256=FE6W_D8NA-66cJQ6VqghChF3JasYW845JVfEZdiqLbA,15449
56
- mcp_ticketer/queue/worker.py,sha256=AF6W1bdxWnHiJd6-iBWqTHkZ4lFflsS65CAtgFPR0FA,20983
57
- mcp_ticketer-0.3.5.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
58
- mcp_ticketer-0.3.5.dist-info/METADATA,sha256=P_TStpQVYOyHeSxjHnvIQ7WUP3jTbwBDnlL0DmwrORw,13219
59
- mcp_ticketer-0.3.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
60
- mcp_ticketer-0.3.5.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
61
- mcp_ticketer-0.3.5.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
62
- mcp_ticketer-0.3.5.dist-info/RECORD,,
File without changes