mcp-ticketer 0.1.38__py3-none-any.whl → 0.2.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.
- mcp_ticketer/__version__.py +1 -1
- mcp_ticketer/adapters/github.py +27 -11
- mcp_ticketer/adapters/jira.py +185 -53
- mcp_ticketer/adapters/linear/__init__.py +24 -0
- mcp_ticketer/adapters/linear/adapter.py +813 -0
- mcp_ticketer/adapters/linear/client.py +257 -0
- mcp_ticketer/adapters/linear/mappers.py +307 -0
- mcp_ticketer/adapters/linear/queries.py +366 -0
- mcp_ticketer/adapters/linear/types.py +277 -0
- mcp_ticketer/adapters/linear.py +10 -2315
- mcp_ticketer/cli/linear_commands.py +490 -0
- mcp_ticketer/cli/main.py +102 -9
- mcp_ticketer/cli/utils.py +6 -2
- mcp_ticketer/core/env_loader.py +325 -0
- mcp_ticketer/core/exceptions.py +152 -0
- mcp_ticketer/core/models.py +163 -10
- mcp_ticketer/queue/manager.py +57 -2
- mcp_ticketer/queue/run_worker.py +5 -0
- mcp_ticketer/queue/worker.py +24 -2
- {mcp_ticketer-0.1.38.dist-info → mcp_ticketer-0.2.0.dist-info}/METADATA +1 -1
- {mcp_ticketer-0.1.38.dist-info → mcp_ticketer-0.2.0.dist-info}/RECORD +25 -16
- {mcp_ticketer-0.1.38.dist-info → mcp_ticketer-0.2.0.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.1.38.dist-info → mcp_ticketer-0.2.0.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.1.38.dist-info → mcp_ticketer-0.2.0.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.1.38.dist-info → mcp_ticketer-0.2.0.dist-info}/top_level.txt +0 -0
mcp_ticketer/queue/manager.py
CHANGED
|
@@ -99,8 +99,23 @@ class WorkerManager:
|
|
|
99
99
|
return False
|
|
100
100
|
|
|
101
101
|
try:
|
|
102
|
-
# Start worker in subprocess
|
|
103
|
-
|
|
102
|
+
# Start worker in subprocess using the same Python executable as the CLI
|
|
103
|
+
# This ensures the worker can import mcp_ticketer modules
|
|
104
|
+
python_executable = self._get_python_executable()
|
|
105
|
+
cmd = [python_executable, "-m", "mcp_ticketer.queue.run_worker"]
|
|
106
|
+
|
|
107
|
+
# Prepare environment for subprocess
|
|
108
|
+
# Ensure the subprocess gets the same environment as the parent
|
|
109
|
+
subprocess_env = os.environ.copy()
|
|
110
|
+
|
|
111
|
+
# Explicitly load environment variables from .env.local if it exists
|
|
112
|
+
env_file = Path.cwd() / ".env.local"
|
|
113
|
+
if env_file.exists():
|
|
114
|
+
logger.debug(f"Loading environment from {env_file} for subprocess")
|
|
115
|
+
from dotenv import dotenv_values
|
|
116
|
+
env_vars = dotenv_values(env_file)
|
|
117
|
+
subprocess_env.update(env_vars)
|
|
118
|
+
logger.debug(f"Added {len(env_vars)} environment variables from .env.local")
|
|
104
119
|
|
|
105
120
|
# Start as background process
|
|
106
121
|
process = subprocess.Popen(
|
|
@@ -108,6 +123,8 @@ class WorkerManager:
|
|
|
108
123
|
stdout=subprocess.DEVNULL,
|
|
109
124
|
stderr=subprocess.DEVNULL,
|
|
110
125
|
start_new_session=True,
|
|
126
|
+
env=subprocess_env, # Pass environment explicitly
|
|
127
|
+
cwd=str(Path.cwd()), # Ensure correct working directory
|
|
111
128
|
)
|
|
112
129
|
|
|
113
130
|
# Save PID
|
|
@@ -256,6 +273,44 @@ class WorkerManager:
|
|
|
256
273
|
except (OSError, ValueError):
|
|
257
274
|
return None
|
|
258
275
|
|
|
276
|
+
def _get_python_executable(self) -> str:
|
|
277
|
+
"""Get the correct Python executable for the worker subprocess.
|
|
278
|
+
|
|
279
|
+
This ensures the worker uses the same Python environment as the CLI,
|
|
280
|
+
which is critical for module imports to work correctly.
|
|
281
|
+
|
|
282
|
+
Returns:
|
|
283
|
+
Path to Python executable
|
|
284
|
+
"""
|
|
285
|
+
# First, try to detect if we're running in a pipx environment
|
|
286
|
+
# by checking if the current executable is in a pipx venv
|
|
287
|
+
current_executable = sys.executable
|
|
288
|
+
|
|
289
|
+
# Check if we're in a pipx venv (path contains /pipx/venvs/)
|
|
290
|
+
if "/pipx/venvs/" in current_executable:
|
|
291
|
+
logger.debug(f"Using pipx Python executable: {current_executable}")
|
|
292
|
+
return current_executable
|
|
293
|
+
|
|
294
|
+
# Check if we can find the mcp-ticketer executable and extract its Python
|
|
295
|
+
import shutil
|
|
296
|
+
mcp_ticketer_path = shutil.which("mcp-ticketer")
|
|
297
|
+
if mcp_ticketer_path:
|
|
298
|
+
try:
|
|
299
|
+
# Read the shebang line to get the Python executable
|
|
300
|
+
with open(mcp_ticketer_path, 'r') as f:
|
|
301
|
+
first_line = f.readline().strip()
|
|
302
|
+
if first_line.startswith("#!") and "python" in first_line:
|
|
303
|
+
python_path = first_line[2:].strip()
|
|
304
|
+
if os.path.exists(python_path):
|
|
305
|
+
logger.debug(f"Using Python from mcp-ticketer shebang: {python_path}")
|
|
306
|
+
return python_path
|
|
307
|
+
except (OSError, IOError):
|
|
308
|
+
pass
|
|
309
|
+
|
|
310
|
+
# Fallback to sys.executable
|
|
311
|
+
logger.debug(f"Using sys.executable as fallback: {current_executable}")
|
|
312
|
+
return current_executable
|
|
313
|
+
|
|
259
314
|
def _cleanup(self):
|
|
260
315
|
"""Clean up lock and PID files."""
|
|
261
316
|
self._release_lock()
|
mcp_ticketer/queue/run_worker.py
CHANGED
|
@@ -15,7 +15,12 @@ logger = logging.getLogger(__name__)
|
|
|
15
15
|
|
|
16
16
|
def main():
|
|
17
17
|
"""Run the worker process."""
|
|
18
|
+
import sys
|
|
19
|
+
import os
|
|
18
20
|
logger.info("Starting standalone worker process")
|
|
21
|
+
logger.info(f"Worker Python executable: {sys.executable}")
|
|
22
|
+
logger.info(f"Worker working directory: {os.getcwd()}")
|
|
23
|
+
logger.info(f"Worker Python path: {sys.path[:3]}...") # Show first 3 entries
|
|
19
24
|
|
|
20
25
|
try:
|
|
21
26
|
# Create queue and worker
|
mcp_ticketer/queue/worker.py
CHANGED
|
@@ -367,12 +367,17 @@ class Worker:
|
|
|
367
367
|
if project_path:
|
|
368
368
|
env_file = project_path / ".env.local"
|
|
369
369
|
if env_file.exists():
|
|
370
|
-
logger.
|
|
370
|
+
logger.info(f"Worker loading environment from {env_file}")
|
|
371
371
|
load_dotenv(env_file)
|
|
372
372
|
|
|
373
|
+
logger.info(f"Worker project_path: {project_path}")
|
|
374
|
+
logger.info(f"Worker current working directory: {os.getcwd()}")
|
|
375
|
+
|
|
373
376
|
config = load_config(project_dir=project_path)
|
|
377
|
+
logger.info(f"Worker loaded config: {config}")
|
|
374
378
|
adapters_config = config.get("adapters", {})
|
|
375
379
|
adapter_config = adapters_config.get(item.adapter, {})
|
|
380
|
+
logger.info(f"Worker adapter config for {item.adapter}: {adapter_config}")
|
|
376
381
|
|
|
377
382
|
# Add environment variables for authentication
|
|
378
383
|
if item.adapter == "linear":
|
|
@@ -387,7 +392,24 @@ class Worker:
|
|
|
387
392
|
if not adapter_config.get("email"):
|
|
388
393
|
adapter_config["email"] = os.getenv("JIRA_ACCESS_USER")
|
|
389
394
|
|
|
390
|
-
|
|
395
|
+
logger.info(f"Worker final adapter config: {adapter_config}")
|
|
396
|
+
|
|
397
|
+
# Add debugging for Linear adapter specifically
|
|
398
|
+
if item.adapter == "linear":
|
|
399
|
+
import os
|
|
400
|
+
linear_api_key = os.getenv("LINEAR_API_KEY", "Not set")
|
|
401
|
+
logger.info(f"Worker LINEAR_API_KEY: {linear_api_key[:20] if linear_api_key != 'Not set' else 'Not set'}...")
|
|
402
|
+
logger.info(f"Worker adapter_config api_key: {adapter_config.get('api_key', 'Not set')[:20] if adapter_config.get('api_key') else 'Not set'}...")
|
|
403
|
+
|
|
404
|
+
adapter = AdapterRegistry.get_adapter(item.adapter, adapter_config)
|
|
405
|
+
logger.info(f"Worker created adapter: {type(adapter)} with team_id: {getattr(adapter, 'team_id_config', 'Not set')}")
|
|
406
|
+
|
|
407
|
+
# Add more debugging for Linear adapter
|
|
408
|
+
if item.adapter == "linear":
|
|
409
|
+
logger.info(f"Worker Linear adapter api_key: {getattr(adapter, 'api_key', 'Not set')[:20] if getattr(adapter, 'api_key', None) else 'Not set'}...")
|
|
410
|
+
logger.info(f"Worker Linear adapter team_key: {getattr(adapter, 'team_key', 'Not set')}")
|
|
411
|
+
|
|
412
|
+
return adapter
|
|
391
413
|
|
|
392
414
|
async def _execute_operation(self, adapter, item: QueueItem) -> dict[str, Any]:
|
|
393
415
|
"""Execute the queued operation.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-ticketer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.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>
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
mcp_ticketer/__init__.py,sha256=Xx4WaprO5PXhVPbYi1L6tBmwmJMkYS-lMyG4ieN6QP0,717
|
|
2
|
-
mcp_ticketer/__version__.py,sha256=
|
|
2
|
+
mcp_ticketer/__version__.py,sha256=9j49fzPH9jSgtpm7Tgb5_MiRjdY95EWDMnBbiisOXqM,1117
|
|
3
3
|
mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
mcp_ticketer/adapters/__init__.py,sha256=B5DFllWn23hkhmrLykNO5uMMSdcFuuPHXyLw_jyFzuE,358
|
|
5
5
|
mcp_ticketer/adapters/aitrackdown.py,sha256=stlbge8K6w-EyQkw_vEQNSXQgCOWN5tOlQUgGWZQNMQ,17936
|
|
6
|
-
mcp_ticketer/adapters/github.py,sha256=
|
|
6
|
+
mcp_ticketer/adapters/github.py,sha256=rhf8yaK9vOGMstvFwddguWnokVIfpasoYMBlyjNg_vY,47335
|
|
7
7
|
mcp_ticketer/adapters/hybrid.py,sha256=UADYZLc_UNw0xHPSbgguBNzvUCnuYn12Qi9ea-zdlMk,19086
|
|
8
|
-
mcp_ticketer/adapters/jira.py,sha256=
|
|
9
|
-
mcp_ticketer/adapters/linear.py,sha256=
|
|
8
|
+
mcp_ticketer/adapters/jira.py,sha256=IoyMaznYE7NliaNGv-I_q2UodUS6JhOllLP1gUEXThs,35375
|
|
9
|
+
mcp_ticketer/adapters/linear.py,sha256=fcQ9s_V7IgP4z2K12lbWXYHUVs1avu1uzUzDCK2eEg4,552
|
|
10
|
+
mcp_ticketer/adapters/linear/__init__.py,sha256=dOPx6caymloIsdyjxS33E09gfPQS6kprisDWwOT2-bE,735
|
|
11
|
+
mcp_ticketer/adapters/linear/adapter.py,sha256=emvjHU-NSFVdxS7lxRjcTv6QNxn26-8RbZNg-x-z5xE,26641
|
|
12
|
+
mcp_ticketer/adapters/linear/client.py,sha256=6IKgYRNy0GF6MhXwxaEBeBE2FM-d1WfhOQ43Mhj0-3s,8871
|
|
13
|
+
mcp_ticketer/adapters/linear/mappers.py,sha256=96euA9TuOTEWEPDKvixjYHb82Ha1zD6gxuo9VsLT2wA,9636
|
|
14
|
+
mcp_ticketer/adapters/linear/queries.py,sha256=chcHCHqvyQbKHPp9wWHGo3HdUGV_6RHNdRadP2pZkVQ,7112
|
|
15
|
+
mcp_ticketer/adapters/linear/types.py,sha256=VuGPu1Z5jGHtbI2zkCyL5YFnwQNukGW-UV72k6zF0p4,8097
|
|
10
16
|
mcp_ticketer/cache/__init__.py,sha256=Xcd-cKnt-Cx7jBzvfzUUUPaGkmyXFi5XUFWw3Z4b7d4,138
|
|
11
17
|
mcp_ticketer/cache/memory.py,sha256=2yBqGi9i0SanlUhJoOC7nijWjoMa3_ntPe-V-AV-LfU,5042
|
|
12
18
|
mcp_ticketer/cli/__init__.py,sha256=l9Q8iKmfGkTu0cssHBVqNZTsL4eAtFzOB25AED_0G6g,89
|
|
@@ -16,19 +22,22 @@ mcp_ticketer/cli/configure.py,sha256=BsA_pSHQMQS0t1bJO_wMM8LWsd5sWJDASjEPRHvwC18
|
|
|
16
22
|
mcp_ticketer/cli/diagnostics.py,sha256=AC7cMQHVWdHfrYH2Y1tkhmRezM2-mID5E_Dhfil7F3U,28923
|
|
17
23
|
mcp_ticketer/cli/discover.py,sha256=AF_qlQc1Oo0UkWayoF5pmRChS5J3fJjH6f2YZzd_k8w,13188
|
|
18
24
|
mcp_ticketer/cli/gemini_configure.py,sha256=ZNSA1lBW-itVToza-JxW95Po7daVXKiZAh7lp6pmXMU,9343
|
|
19
|
-
mcp_ticketer/cli/
|
|
25
|
+
mcp_ticketer/cli/linear_commands.py,sha256=b5v4c9uBNPwj_vdy314JkLZbyC1fXU6IcY2VoG0z7gI,17193
|
|
26
|
+
mcp_ticketer/cli/main.py,sha256=9e83BCxds9AESIYueK1VjeJ96H7AvRbvPiMYwd4EeKs,62258
|
|
20
27
|
mcp_ticketer/cli/mcp_configure.py,sha256=RzV50UjXgOmvMp-9S0zS39psuvjffVByaMrqrUaAGAM,9594
|
|
21
28
|
mcp_ticketer/cli/migrate_config.py,sha256=MYsr_C5ZxsGg0P13etWTWNrJ_lc6ElRCkzfQADYr3DM,5956
|
|
22
29
|
mcp_ticketer/cli/queue_commands.py,sha256=mm-3H6jmkUGJDyU_E46o9iRpek8tvFCm77F19OtHiZI,7884
|
|
23
30
|
mcp_ticketer/cli/simple_health.py,sha256=oLAaSiVrBtdPCZyoHa1YHEoLG58QaupfuC-kPWRubdM,8013
|
|
24
|
-
mcp_ticketer/cli/utils.py,sha256=
|
|
31
|
+
mcp_ticketer/cli/utils.py,sha256=bGoLcqsNsv7YMjVeWc9tlqKQC5zeOmWZp7wEfe0JfzM,22964
|
|
25
32
|
mcp_ticketer/core/__init__.py,sha256=eXovsaJymQRP2AwOBuOy6mFtI3I68D7gGenZ5V-IMqo,349
|
|
26
33
|
mcp_ticketer/core/adapter.py,sha256=q64LxOInIno7EIbmuxItf8KEsd-g9grCs__Z4uwZHto,10273
|
|
27
34
|
mcp_ticketer/core/config.py,sha256=hvn8RoN2BSmYzESKqCvcpKleX0PrGiHVQ5v35nX12Mc,19241
|
|
28
35
|
mcp_ticketer/core/env_discovery.py,sha256=It62C97UBt96CgVbZCql5NQtONmCHMkX3c8W2kEl-Qk,18716
|
|
36
|
+
mcp_ticketer/core/env_loader.py,sha256=fX8EpHcAJxxhPJ-XY5BD8HlLs-Y9jdlQ24Qtt5ylBNo,12032
|
|
37
|
+
mcp_ticketer/core/exceptions.py,sha256=78tzV3Muc7E_UhEIByF0NtsPe1I0lFVrbpdDNX56kQg,3737
|
|
29
38
|
mcp_ticketer/core/http_client.py,sha256=s5ikMiwEJ8TJjNn73wu3gv3OdAtyBEpAqPnSroRMW2k,13971
|
|
30
39
|
mcp_ticketer/core/mappers.py,sha256=1aG1jFsHTCwmGRVgOlXW-VOSTGzc86gv7qjDfiR1ups,17462
|
|
31
|
-
mcp_ticketer/core/models.py,sha256=
|
|
40
|
+
mcp_ticketer/core/models.py,sha256=a_2AbL3NlN0pfdZad-hXus_zb4bSi9zISHcsNYl0sng,12486
|
|
32
41
|
mcp_ticketer/core/project_config.py,sha256=yYxlgxjcEPeOwx-b-SXFpe0k9pW9xzBRAK72PsItG-o,23346
|
|
33
42
|
mcp_ticketer/core/registry.py,sha256=ShYLDPE62KFJpB0kj_zFyQzRxSH3LkQEEuo1jaakb1k,3483
|
|
34
43
|
mcp_ticketer/mcp/__init__.py,sha256=Y05eTzsPk0wH8yKNIM-ekpGjgSDO0bQr0EME-vOP4GE,123
|
|
@@ -36,14 +45,14 @@ mcp_ticketer/mcp/server.py,sha256=vs0WR9_KhDaYyhrkbTuTsEThT0bMj6gwuFmAxmzCxwU,76
|
|
|
36
45
|
mcp_ticketer/queue/__init__.py,sha256=1YIaCpZpFqPcqvDEQXiEvDLiw94DXRdCJkBaVIFQrms,231
|
|
37
46
|
mcp_ticketer/queue/__main__.py,sha256=gc_tE9NUdK07OJfTZuD4t6KeBD_vxFQIhknGTQUG_jk,109
|
|
38
47
|
mcp_ticketer/queue/health_monitor.py,sha256=aQrlBzfbLWu8-fV2b5CuHs4oqyTqGGcntKIHM3r-dDI,11844
|
|
39
|
-
mcp_ticketer/queue/manager.py,sha256=
|
|
48
|
+
mcp_ticketer/queue/manager.py,sha256=BupBsftxKxeThDWFU96vBsEp4iUXhht7FFbeV0ikltI,10182
|
|
40
49
|
mcp_ticketer/queue/queue.py,sha256=jSAkYNEIbNH1cbYuF8s6eFuZmXqn8WHXx3mbfMU2Ud8,17131
|
|
41
|
-
mcp_ticketer/queue/run_worker.py,sha256=
|
|
50
|
+
mcp_ticketer/queue/run_worker.py,sha256=F7anuhdkgZF9lXZntHuJ7rEzuEkAfAZO1qvGh3R57bw,1033
|
|
42
51
|
mcp_ticketer/queue/ticket_registry.py,sha256=k8FYg2cFYsI4POb94-o-fTrIVr-ttfi60r0O5YhJYck,15321
|
|
43
|
-
mcp_ticketer/queue/worker.py,sha256=
|
|
44
|
-
mcp_ticketer-0.
|
|
45
|
-
mcp_ticketer-0.
|
|
46
|
-
mcp_ticketer-0.
|
|
47
|
-
mcp_ticketer-0.
|
|
48
|
-
mcp_ticketer-0.
|
|
49
|
-
mcp_ticketer-0.
|
|
52
|
+
mcp_ticketer/queue/worker.py,sha256=zXJpyhRJ99be0VLaez3YPtC9OU17vVNu5qhr1dCGaLg,19992
|
|
53
|
+
mcp_ticketer-0.2.0.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
|
|
54
|
+
mcp_ticketer-0.2.0.dist-info/METADATA,sha256=bvHYuQNE5HYIEgM2BlrpPwCesfgm3jWiax7lwTNGGB0,13219
|
|
55
|
+
mcp_ticketer-0.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
56
|
+
mcp_ticketer-0.2.0.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
|
|
57
|
+
mcp_ticketer-0.2.0.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
|
|
58
|
+
mcp_ticketer-0.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|