mcp-ticketer 0.1.12__py3-none-any.whl → 0.1.13__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/linear.py +427 -3
- mcp_ticketer/cli/discover.py +402 -0
- mcp_ticketer/cli/main.py +4 -0
- mcp_ticketer/core/__init__.py +2 -1
- mcp_ticketer/core/adapter.py +155 -2
- mcp_ticketer/core/env_discovery.py +555 -0
- mcp_ticketer/core/models.py +58 -6
- mcp_ticketer/core/project_config.py +62 -9
- {mcp_ticketer-0.1.12.dist-info → mcp_ticketer-0.1.13.dist-info}/METADATA +1 -1
- {mcp_ticketer-0.1.12.dist-info → mcp_ticketer-0.1.13.dist-info}/RECORD +15 -13
- {mcp_ticketer-0.1.12.dist-info → mcp_ticketer-0.1.13.dist-info}/WHEEL +0 -0
- {mcp_ticketer-0.1.12.dist-info → mcp_ticketer-0.1.13.dist-info}/entry_points.txt +0 -0
- {mcp_ticketer-0.1.12.dist-info → mcp_ticketer-0.1.13.dist-info}/licenses/LICENSE +0 -0
- {mcp_ticketer-0.1.12.dist-info → mcp_ticketer-0.1.13.dist-info}/top_level.txt +0 -0
|
@@ -301,7 +301,15 @@ class ConfigValidator:
|
|
|
301
301
|
|
|
302
302
|
|
|
303
303
|
class ConfigResolver:
|
|
304
|
-
"""Resolve configuration from multiple sources with hierarchical precedence.
|
|
304
|
+
"""Resolve configuration from multiple sources with hierarchical precedence.
|
|
305
|
+
|
|
306
|
+
Resolution order (highest to lowest priority):
|
|
307
|
+
1. CLI overrides
|
|
308
|
+
2. Environment variables
|
|
309
|
+
3. Project-specific config (.mcp-ticketer/config.json)
|
|
310
|
+
4. Auto-discovered .env files
|
|
311
|
+
5. Global config (~/.mcp-ticketer/config.json)
|
|
312
|
+
"""
|
|
305
313
|
|
|
306
314
|
# Global config location
|
|
307
315
|
GLOBAL_CONFIG_PATH = Path.home() / ".mcp-ticketer" / "config.json"
|
|
@@ -309,15 +317,18 @@ class ConfigResolver:
|
|
|
309
317
|
# Project config location (relative to project root)
|
|
310
318
|
PROJECT_CONFIG_SUBPATH = ".mcp-ticketer" / Path("config.json")
|
|
311
319
|
|
|
312
|
-
def __init__(self, project_path: Optional[Path] = None):
|
|
320
|
+
def __init__(self, project_path: Optional[Path] = None, enable_env_discovery: bool = True):
|
|
313
321
|
"""Initialize config resolver.
|
|
314
322
|
|
|
315
323
|
Args:
|
|
316
324
|
project_path: Path to project root (defaults to cwd)
|
|
325
|
+
enable_env_discovery: Enable auto-discovery from .env files (default: True)
|
|
317
326
|
"""
|
|
318
327
|
self.project_path = project_path or Path.cwd()
|
|
328
|
+
self.enable_env_discovery = enable_env_discovery
|
|
319
329
|
self._global_config: Optional[TicketerConfig] = None
|
|
320
330
|
self._project_config: Optional[TicketerConfig] = None
|
|
331
|
+
self._discovered_config: Optional['DiscoveryResult'] = None
|
|
321
332
|
|
|
322
333
|
def load_global_config(self) -> TicketerConfig:
|
|
323
334
|
"""Load global configuration from ~/.mcp-ticketer/config.json."""
|
|
@@ -380,6 +391,22 @@ class ConfigResolver:
|
|
|
380
391
|
json.dump(config.to_dict(), f, indent=2)
|
|
381
392
|
logger.info(f"Saved project config to {config_path}")
|
|
382
393
|
|
|
394
|
+
def get_discovered_config(self) -> Optional['DiscoveryResult']:
|
|
395
|
+
"""Get auto-discovered configuration from .env files.
|
|
396
|
+
|
|
397
|
+
Returns:
|
|
398
|
+
DiscoveryResult if env discovery is enabled, None otherwise
|
|
399
|
+
"""
|
|
400
|
+
if not self.enable_env_discovery:
|
|
401
|
+
return None
|
|
402
|
+
|
|
403
|
+
if self._discovered_config is None:
|
|
404
|
+
# Import here to avoid circular dependency
|
|
405
|
+
from .env_discovery import discover_config
|
|
406
|
+
self._discovered_config = discover_config(self.project_path)
|
|
407
|
+
|
|
408
|
+
return self._discovered_config
|
|
409
|
+
|
|
383
410
|
def resolve_adapter_config(
|
|
384
411
|
self,
|
|
385
412
|
adapter_name: Optional[str] = None,
|
|
@@ -389,9 +416,10 @@ class ConfigResolver:
|
|
|
389
416
|
|
|
390
417
|
Precedence (highest to lowest):
|
|
391
418
|
1. CLI overrides
|
|
392
|
-
2. Environment variables
|
|
393
|
-
3. Project-specific config
|
|
394
|
-
4.
|
|
419
|
+
2. Environment variables (os.getenv)
|
|
420
|
+
3. Project-specific config (.mcp-ticketer/config.json)
|
|
421
|
+
4. Auto-discovered .env files
|
|
422
|
+
5. Global config (~/.mcp-ticketer/config.json)
|
|
395
423
|
|
|
396
424
|
Args:
|
|
397
425
|
adapter_name: Name of adapter to configure (defaults to default_adapter)
|
|
@@ -410,7 +438,16 @@ class ConfigResolver:
|
|
|
410
438
|
elif project_config and project_config.default_adapter:
|
|
411
439
|
target_adapter = project_config.default_adapter
|
|
412
440
|
else:
|
|
413
|
-
|
|
441
|
+
# Try to infer from discovered config
|
|
442
|
+
discovered = self.get_discovered_config()
|
|
443
|
+
if discovered:
|
|
444
|
+
primary = discovered.get_primary_adapter()
|
|
445
|
+
if primary:
|
|
446
|
+
target_adapter = primary.adapter_type
|
|
447
|
+
else:
|
|
448
|
+
target_adapter = global_config.default_adapter
|
|
449
|
+
else:
|
|
450
|
+
target_adapter = global_config.default_adapter
|
|
414
451
|
|
|
415
452
|
# Start with empty config
|
|
416
453
|
resolved_config = {"adapter": target_adapter}
|
|
@@ -420,7 +457,23 @@ class ConfigResolver:
|
|
|
420
457
|
global_adapter_config = global_config.adapters[target_adapter].to_dict()
|
|
421
458
|
resolved_config.update(global_adapter_config)
|
|
422
459
|
|
|
423
|
-
# 2. Apply
|
|
460
|
+
# 2. Apply auto-discovered .env config (if enabled)
|
|
461
|
+
if self.enable_env_discovery:
|
|
462
|
+
discovered = self.get_discovered_config()
|
|
463
|
+
if discovered:
|
|
464
|
+
discovered_adapter = discovered.get_adapter_by_type(target_adapter)
|
|
465
|
+
if discovered_adapter:
|
|
466
|
+
# Merge discovered config
|
|
467
|
+
discovered_dict = {
|
|
468
|
+
k: v for k, v in discovered_adapter.config.items()
|
|
469
|
+
if k != "adapter" # Don't override adapter type
|
|
470
|
+
}
|
|
471
|
+
resolved_config.update(discovered_dict)
|
|
472
|
+
logger.debug(
|
|
473
|
+
f"Applied auto-discovered config from {discovered_adapter.found_in}"
|
|
474
|
+
)
|
|
475
|
+
|
|
476
|
+
# 3. Apply project-specific config if exists
|
|
424
477
|
if project_config:
|
|
425
478
|
# Check if this project has specific adapter config
|
|
426
479
|
project_path_str = str(self.project_path)
|
|
@@ -433,11 +486,11 @@ class ConfigResolver:
|
|
|
433
486
|
proj_global_adapter_config = project_config.adapters[target_adapter].to_dict()
|
|
434
487
|
resolved_config.update(proj_global_adapter_config)
|
|
435
488
|
|
|
436
|
-
#
|
|
489
|
+
# 4. Apply environment variable overrides (os.getenv)
|
|
437
490
|
env_overrides = self._get_env_overrides(target_adapter)
|
|
438
491
|
resolved_config.update(env_overrides)
|
|
439
492
|
|
|
440
|
-
#
|
|
493
|
+
# 5. Apply CLI overrides
|
|
441
494
|
if cli_overrides:
|
|
442
495
|
resolved_config.update(cli_overrides)
|
|
443
496
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mcp-ticketer
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.13
|
|
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,27 +1,29 @@
|
|
|
1
1
|
mcp_ticketer/__init__.py,sha256=ayPQdFr6msypD06_G96a1H0bdFCT1m1wDtv8MZBpY4I,496
|
|
2
|
-
mcp_ticketer/__version__.py,sha256=
|
|
2
|
+
mcp_ticketer/__version__.py,sha256=_43DgubrWUqhaLrhYbn9KefWfUiLWjH_hMHmCrgw1Tc,1115
|
|
3
3
|
mcp_ticketer/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
mcp_ticketer/adapters/__init__.py,sha256=K_1egvhHb5F_7yFceUx2YzPGEoc7vX-q8dMVaS4K6gw,356
|
|
5
5
|
mcp_ticketer/adapters/aitrackdown.py,sha256=gqS_N6VGLoG5itUu17ANG5SefaAITYoW-t2xL9SrY-Y,15372
|
|
6
6
|
mcp_ticketer/adapters/github.py,sha256=onT8NhYaf9fIw2eCOTbZSkk7q4IoM7ZADRvRl9qrUz8,43850
|
|
7
7
|
mcp_ticketer/adapters/hybrid.py,sha256=H9B-pfWmDKXO3GgzxB8undEcZTMzLz_1a6zWhj7xfR0,18556
|
|
8
8
|
mcp_ticketer/adapters/jira.py,sha256=rd-8PseTsRyQNPjsrUJ8vJ8vfBpa6HWFBieOUyvw0Tg,28954
|
|
9
|
-
mcp_ticketer/adapters/linear.py,sha256=
|
|
9
|
+
mcp_ticketer/adapters/linear.py,sha256=BUK40EF4yNVJV5ldJPFx7Ne4FXHYbrGCUAaFy2gWC9Y,65211
|
|
10
10
|
mcp_ticketer/cache/__init__.py,sha256=MSi3GLXancfP2-edPC9TFAJk7r0j6H5-XmpMHnkGPbI,137
|
|
11
11
|
mcp_ticketer/cache/memory.py,sha256=gTzv-xF7qGfiYVUjG7lnzo0ZcqgXQajMl4NAYUcaytg,5133
|
|
12
12
|
mcp_ticketer/cli/__init__.py,sha256=YeljyLtv906TqkvRuEPhmKO-Uk0CberQ9I6kx1tx2UA,88
|
|
13
13
|
mcp_ticketer/cli/configure.py,sha256=etFutvc0QpaVDMOsZiiN7wKuaT98Od1Tj9W6lsEWw5A,16351
|
|
14
|
-
mcp_ticketer/cli/
|
|
14
|
+
mcp_ticketer/cli/discover.py,sha256=putWrGcctUH8K0fOMtr9MZA9VnWoXzbtoe7mXSkDxhg,13156
|
|
15
|
+
mcp_ticketer/cli/main.py,sha256=3NAHRr5Q4nCExbyQ6YIiUxn1nyqi_e4TBgR8OuMhHqk,30461
|
|
15
16
|
mcp_ticketer/cli/migrate_config.py,sha256=iZIstnlr9vkhiW_MlnSyJOkMi4KHQqrZ6Hz1ECD_VUk,6045
|
|
16
17
|
mcp_ticketer/cli/queue_commands.py,sha256=f3pEHKZ43dBHEIoCBvdfvjfMB9_WJltps9ATwTzorY0,8160
|
|
17
18
|
mcp_ticketer/cli/utils.py,sha256=NxsS91vKA8xZnDXKU2y0Gcyc4I_ctRyJj-wT7Xd1Q_Q,18589
|
|
18
|
-
mcp_ticketer/core/__init__.py,sha256=
|
|
19
|
-
mcp_ticketer/core/adapter.py,sha256=
|
|
19
|
+
mcp_ticketer/core/__init__.py,sha256=qpCZveQMyqU2JvYG9MG_c6X35z_VoSmjWdXGcUZqqmA,348
|
|
20
|
+
mcp_ticketer/core/adapter.py,sha256=6KfhceINHfDjs--RyA_rOLeM2phVD_D85S9D6s2lcuU,10075
|
|
20
21
|
mcp_ticketer/core/config.py,sha256=9a2bksbcFr7KXeHSPY6KoSP5Pzt54utYPCmbM-1QKmk,13932
|
|
22
|
+
mcp_ticketer/core/env_discovery.py,sha256=SPoyq_y5j-3gJG5gYNVjCIIrbdzimOdDbTYySmQWZOA,17536
|
|
21
23
|
mcp_ticketer/core/http_client.py,sha256=RM9CEMNcuRb-FxhAijmM_FeBMgxgh1OII9HIPBdJue0,13855
|
|
22
24
|
mcp_ticketer/core/mappers.py,sha256=8I4jcqDqoQEdWlteDMpVeVF3Wo0fDCkmFPRr8oNv8gA,16933
|
|
23
|
-
mcp_ticketer/core/models.py,sha256=
|
|
24
|
-
mcp_ticketer/core/project_config.py,sha256=
|
|
25
|
+
mcp_ticketer/core/models.py,sha256=GhuTitY6t_QlqfEUvWT6Q2zvY7qAtx_SQyCMMn8iYkk,6473
|
|
26
|
+
mcp_ticketer/core/project_config.py,sha256=UqJpxAunmCvR9R_ev9ZrsLvG4engQe1OFQBEmcRx9cs,22254
|
|
25
27
|
mcp_ticketer/core/registry.py,sha256=fwje0fnjp0YKPZ0SrVWk82SMNLs7CD0JlHQmx7SigNo,3537
|
|
26
28
|
mcp_ticketer/mcp/__init__.py,sha256=Bvzof9vBu6VwcXcIZK8RgKv6ycRV9tDlO-9TUmd8zqQ,122
|
|
27
29
|
mcp_ticketer/mcp/server.py,sha256=TDuU8ChZC2QYSRo0uGHkVReblTf--hriOjxo-pSAF_Y,34068
|
|
@@ -31,9 +33,9 @@ mcp_ticketer/queue/manager.py,sha256=79AH9oUxdBXH3lmJ3kIlFf2GQkWHL6XB6u5JqVWPq60
|
|
|
31
33
|
mcp_ticketer/queue/queue.py,sha256=z4aivQCtsH5_OUr2OfXSfnFKzugTahNnwHw0LS3ZhZc,11549
|
|
32
34
|
mcp_ticketer/queue/run_worker.py,sha256=HFoykfDpOoz8OUxWbQ2Fka_UlGrYwjPVZ-DEimGFH9o,802
|
|
33
35
|
mcp_ticketer/queue/worker.py,sha256=cVjHR_kfnGKAkiUg0HuXCnbKeKNBBEuj0XZHgIuIn4k,14017
|
|
34
|
-
mcp_ticketer-0.1.
|
|
35
|
-
mcp_ticketer-0.1.
|
|
36
|
-
mcp_ticketer-0.1.
|
|
37
|
-
mcp_ticketer-0.1.
|
|
38
|
-
mcp_ticketer-0.1.
|
|
39
|
-
mcp_ticketer-0.1.
|
|
36
|
+
mcp_ticketer-0.1.13.dist-info/licenses/LICENSE,sha256=KOVrunjtILSzY-2N8Lqa3-Q8dMaZIG4LrlLTr9UqL08,1073
|
|
37
|
+
mcp_ticketer-0.1.13.dist-info/METADATA,sha256=29lPCGuZI3U_pdIoRYH3C5h4Xn3DaZo-AfKDXQX7IYs,11211
|
|
38
|
+
mcp_ticketer-0.1.13.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
39
|
+
mcp_ticketer-0.1.13.dist-info/entry_points.txt,sha256=o1IxVhnHnBNG7FZzbFq-Whcs1Djbofs0qMjiUYBLx2s,60
|
|
40
|
+
mcp_ticketer-0.1.13.dist-info/top_level.txt,sha256=WnAG4SOT1Vm9tIwl70AbGG_nA217YyV3aWFhxLH2rxw,13
|
|
41
|
+
mcp_ticketer-0.1.13.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|