titan-cli 0.1.3__py3-none-any.whl → 0.1.4__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.
- titan_cli/core/plugins/models.py +35 -7
- titan_cli/core/plugins/plugin_registry.py +11 -2
- titan_cli/ui/tui/screens/plugin_config_wizard.py +40 -9
- {titan_cli-0.1.3.dist-info → titan_cli-0.1.4.dist-info}/METADATA +1 -1
- {titan_cli-0.1.3.dist-info → titan_cli-0.1.4.dist-info}/RECORD +8 -8
- {titan_cli-0.1.3.dist-info → titan_cli-0.1.4.dist-info}/LICENSE +0 -0
- {titan_cli-0.1.3.dist-info → titan_cli-0.1.4.dist-info}/WHEEL +0 -0
- {titan_cli-0.1.3.dist-info → titan_cli-0.1.4.dist-info}/entry_points.txt +0 -0
titan_cli/core/plugins/models.py
CHANGED
|
@@ -30,15 +30,43 @@ class JiraPluginConfig(BaseModel):
|
|
|
30
30
|
Credentials (base_url, email, api_token) should be configured at global level (~/.titan/config.toml).
|
|
31
31
|
Project-specific settings (default_project) can override at project level (.titan/config.toml).
|
|
32
32
|
"""
|
|
33
|
-
base_url: Optional[str] = Field(
|
|
34
|
-
|
|
33
|
+
base_url: Optional[str] = Field(
|
|
34
|
+
None,
|
|
35
|
+
description="JIRA instance URL (e.g., 'https://jira.company.com')",
|
|
36
|
+
json_schema_extra={"config_scope": "global"}
|
|
37
|
+
)
|
|
38
|
+
email: Optional[str] = Field(
|
|
39
|
+
None,
|
|
40
|
+
description="User email for authentication",
|
|
41
|
+
json_schema_extra={"config_scope": "global"}
|
|
42
|
+
)
|
|
35
43
|
# api_token is stored in secrets, not in config.toml
|
|
36
44
|
# It appears in the JSON schema for interactive configuration but is optional in the model
|
|
37
|
-
api_token: Optional[str] = Field(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
45
|
+
api_token: Optional[str] = Field(
|
|
46
|
+
None,
|
|
47
|
+
description="JIRA API token (Personal Access Token)",
|
|
48
|
+
json_schema_extra={"format": "password", "required_in_schema": True}
|
|
49
|
+
)
|
|
50
|
+
default_project: Optional[str] = Field(
|
|
51
|
+
None,
|
|
52
|
+
description="Default JIRA project key (e.g., 'ECAPP', 'PROJ')",
|
|
53
|
+
json_schema_extra={"config_scope": "project"}
|
|
54
|
+
)
|
|
55
|
+
timeout: int = Field(
|
|
56
|
+
30,
|
|
57
|
+
description="Request timeout in seconds",
|
|
58
|
+
json_schema_extra={"config_scope": "global"}
|
|
59
|
+
)
|
|
60
|
+
enable_cache: bool = Field(
|
|
61
|
+
True,
|
|
62
|
+
description="Enable caching for API responses",
|
|
63
|
+
json_schema_extra={"config_scope": "global"}
|
|
64
|
+
)
|
|
65
|
+
cache_ttl: int = Field(
|
|
66
|
+
300,
|
|
67
|
+
description="Cache time-to-live in seconds",
|
|
68
|
+
json_schema_extra={"config_scope": "global"}
|
|
69
|
+
)
|
|
42
70
|
|
|
43
71
|
@field_validator('base_url')
|
|
44
72
|
@classmethod
|
|
@@ -20,10 +20,19 @@ class PluginRegistry:
|
|
|
20
20
|
logger = logging.getLogger('titan_cli.ui.tui.screens.project_setup_wizard')
|
|
21
21
|
|
|
22
22
|
discovered = entry_points(group='titan.plugins')
|
|
23
|
-
self._discovered_plugin_names = [ep.name for ep in discovered]
|
|
24
|
-
logger.debug(f"PluginRegistry.discover() - Found {len(self._discovered_plugin_names)} plugins: {self._discovered_plugin_names}")
|
|
25
23
|
|
|
24
|
+
# Deduplicate entry points (can happen in dev mode with editable installs)
|
|
25
|
+
seen = {}
|
|
26
|
+
unique_eps = []
|
|
26
27
|
for ep in discovered:
|
|
28
|
+
if ep.name not in seen:
|
|
29
|
+
seen[ep.name] = ep
|
|
30
|
+
unique_eps.append(ep)
|
|
31
|
+
|
|
32
|
+
self._discovered_plugin_names = [ep.name for ep in unique_eps]
|
|
33
|
+
logger.debug(f"PluginRegistry.discover() - Found {len(self._discovered_plugin_names)} plugins: {self._discovered_plugin_names}")
|
|
34
|
+
|
|
35
|
+
for ep in unique_eps:
|
|
27
36
|
try:
|
|
28
37
|
logger.debug(f"Loading plugin: {ep.name}")
|
|
29
38
|
plugin_class = ep.load()
|
|
@@ -494,22 +494,43 @@ class PluginConfigWizardScreen(BaseScreen):
|
|
|
494
494
|
|
|
495
495
|
try:
|
|
496
496
|
project_cfg_path = self.config.project_config_path
|
|
497
|
+
global_cfg_path = self.config._global_config_path
|
|
498
|
+
|
|
497
499
|
if not project_cfg_path:
|
|
498
500
|
self.app.notify("No project config found", severity="error")
|
|
499
501
|
return
|
|
500
502
|
|
|
503
|
+
# Load existing configs
|
|
501
504
|
project_cfg_dict = {}
|
|
502
505
|
if project_cfg_path.exists():
|
|
503
506
|
with open(project_cfg_path, "rb") as f:
|
|
504
507
|
project_cfg_dict = tomli.load(f)
|
|
505
508
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
+
global_cfg_dict = {}
|
|
510
|
+
if global_cfg_path.exists():
|
|
511
|
+
with open(global_cfg_path, "rb") as f:
|
|
512
|
+
global_cfg_dict = tomli.load(f)
|
|
513
|
+
|
|
514
|
+
# Prepare plugin tables
|
|
515
|
+
project_plugins_table = project_cfg_dict.setdefault("plugins", {})
|
|
516
|
+
project_plugin_table = project_plugins_table.setdefault(self.plugin_name, {})
|
|
517
|
+
project_config_table = project_plugin_table.setdefault("config", {})
|
|
518
|
+
|
|
519
|
+
global_plugins_table = global_cfg_dict.setdefault("plugins", {})
|
|
520
|
+
global_plugin_table = global_plugins_table.setdefault(self.plugin_name, {})
|
|
521
|
+
global_config_table = global_plugin_table.setdefault("config", {})
|
|
509
522
|
|
|
510
|
-
#
|
|
523
|
+
# Get field metadata from schema
|
|
524
|
+
field_scopes = {}
|
|
525
|
+
if self.schema and "properties" in self.schema:
|
|
526
|
+
for field_name, field_info in self.schema["properties"].items():
|
|
527
|
+
scope = field_info.get("config_scope", "project") # Default to project
|
|
528
|
+
field_scopes[field_name] = scope
|
|
529
|
+
|
|
530
|
+
# Separate secrets and config by scope
|
|
511
531
|
secrets_to_save = {}
|
|
512
|
-
|
|
532
|
+
global_config_values = {}
|
|
533
|
+
project_config_values = {}
|
|
513
534
|
|
|
514
535
|
for field_name, value in self.config_data.items():
|
|
515
536
|
if isinstance(value, dict) and value.get("_is_secret"):
|
|
@@ -524,15 +545,25 @@ class PluginConfigWizardScreen(BaseScreen):
|
|
|
524
545
|
else:
|
|
525
546
|
secrets_to_save[secret_key] = value["_value"]
|
|
526
547
|
else:
|
|
527
|
-
|
|
548
|
+
# Route to global or project based on field scope
|
|
549
|
+
scope = field_scopes.get(field_name, "project")
|
|
550
|
+
if scope == "global":
|
|
551
|
+
global_config_values[field_name] = value
|
|
552
|
+
else:
|
|
553
|
+
project_config_values[field_name] = value
|
|
528
554
|
|
|
529
|
-
# Update
|
|
530
|
-
|
|
555
|
+
# Update configs
|
|
556
|
+
project_config_table.update(project_config_values)
|
|
557
|
+
global_config_table.update(global_config_values)
|
|
531
558
|
|
|
532
|
-
# Write config
|
|
559
|
+
# Write config files
|
|
533
560
|
with open(project_cfg_path, "wb") as f:
|
|
534
561
|
tomli_w.dump(project_cfg_dict, f)
|
|
535
562
|
|
|
563
|
+
if global_config_values: # Only write global if there are global values
|
|
564
|
+
with open(global_cfg_path, "wb") as f:
|
|
565
|
+
tomli_w.dump(global_cfg_dict, f)
|
|
566
|
+
|
|
536
567
|
# Save secrets
|
|
537
568
|
project_name = self.config.get_project_name()
|
|
538
569
|
for secret_key, secret_value in secrets_to_save.items():
|
|
@@ -86,9 +86,9 @@ titan_cli/core/discovery.py,sha256=SPU5OcCg7mJTiA8cIR_6gHw8AdZmDVGi-nK80138HRU,1
|
|
|
86
86
|
titan_cli/core/errors.py,sha256=I-xX6CCIFhno0ZUK8IRPX6RhXfj3Q7mckiCj-xintdY,2419
|
|
87
87
|
titan_cli/core/models.py,sha256=468qjAXv6KBK3ZSEg4oV3wVOfNKDFzXIkqugBfMiisI,2373
|
|
88
88
|
titan_cli/core/plugins/available.py,sha256=__ejonPeOqw2Zy9gIRB-CHeFO9SvTFclG095afgnIz4,1163
|
|
89
|
-
titan_cli/core/plugins/models.py,sha256=
|
|
89
|
+
titan_cli/core/plugins/models.py,sha256=CdaktVAEcq4t41X4IfXrBgjFxly6FxdJikqqkyJtTtM,4012
|
|
90
90
|
titan_cli/core/plugins/plugin_base.py,sha256=TtHjO-g1PBS0W0vfAM-5z-0xwL0IT2Ohi3BJ0TIfTEU,2597
|
|
91
|
-
titan_cli/core/plugins/plugin_registry.py,sha256=
|
|
91
|
+
titan_cli/core/plugins/plugin_registry.py,sha256=cuoarcNnsvLv30-01uGnjWwrqy2Jaf_eJGJelzcv_k0,7753
|
|
92
92
|
titan_cli/core/secrets.py,sha256=4A4rszaie1wJh7xccetOO9rM_0jwYiIQIZVgCM0tCT4,4642
|
|
93
93
|
titan_cli/core/workflows/__init__.py,sha256=CvpDKR4Co5Vzbb5aFTt5r6vyoqjGexj6Mt1_x0Z4iwg,653
|
|
94
94
|
titan_cli/core/workflows/models.py,sha256=xMXmZKMTYRawUeuAO0hG5dF6QMRCM-TWFNfoveBxJpQ,4746
|
|
@@ -122,7 +122,7 @@ titan_cli/ui/tui/screens/base.py,sha256=ufVYBkVzetQxsPQTobN0HgUGdSB0ARfRtvo-02DS
|
|
|
122
122
|
titan_cli/ui/tui/screens/cli_launcher.py,sha256=C9XWe1jUr0-Q_PGwchL6bVu9N2g-QLa83jJZGl7ucHI,4385
|
|
123
123
|
titan_cli/ui/tui/screens/global_setup_wizard.py,sha256=gbkGMGXWJdfrIWvRvT5DDFZKKRWmf7nlGUuUkTtDiKI,12115
|
|
124
124
|
titan_cli/ui/tui/screens/main_menu.py,sha256=5Z27Ny69PPJF0q6_H5zcNPOh8vrRDr_xgYFSmUbn244,4493
|
|
125
|
-
titan_cli/ui/tui/screens/plugin_config_wizard.py,sha256=
|
|
125
|
+
titan_cli/ui/tui/screens/plugin_config_wizard.py,sha256=a8QIsVLGNNCLebJ7bWlRpftZU7yPhTRcf06XOLzFB4w,20416
|
|
126
126
|
titan_cli/ui/tui/screens/plugin_management.py,sha256=2UvdxISzaiQBpm1OW1cpDrQS4ghTSC_87nlpx5Nrjhw,12356
|
|
127
127
|
titan_cli/ui/tui/screens/project_setup_wizard.py,sha256=Q2cCHlzWpiLdtGUTHnkHnXapkxZahRAVTx5MI78sszU,24210
|
|
128
128
|
titan_cli/ui/tui/screens/workflow_execution.py,sha256=JHZlKtqpYRosVP4TVSGzT1L8UxlCoCNorBFVXYPyzik,23526
|
|
@@ -139,8 +139,8 @@ titan_cli/ui/tui/widgets/table.py,sha256=uWXyUda6mvflBybrrUSZh5Nvf794ege8SUe_0D2
|
|
|
139
139
|
titan_cli/ui/tui/widgets/text.py,sha256=p5h2V9w-JmPigwUFn-ky_D7gyYiix_93FJNqNmCYNHY,4057
|
|
140
140
|
titan_cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
141
141
|
titan_cli/utils/autoupdate.py,sha256=Tq3SJp3iOMNONQZOw-48G6AmpKrPOyWV9RxuCA03q4M,4151
|
|
142
|
-
titan_cli-0.1.
|
|
143
|
-
titan_cli-0.1.
|
|
144
|
-
titan_cli-0.1.
|
|
145
|
-
titan_cli-0.1.
|
|
146
|
-
titan_cli-0.1.
|
|
142
|
+
titan_cli-0.1.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
143
|
+
titan_cli-0.1.4.dist-info/METADATA,sha256=v_-VyxKvwr3BZJD5jtjp4yDiBLUOAKFLntIJMdVEso4,4526
|
|
144
|
+
titan_cli-0.1.4.dist-info/WHEEL,sha256=FMvqSimYX_P7y0a7UY-_Mc83r5zkBZsCYPm7Lr0Bsq4,88
|
|
145
|
+
titan_cli-0.1.4.dist-info/entry_points.txt,sha256=i_Zucivhsx6FcrkKDQS00MJ_Nwse-nAEkuksCcs_Ym8,186
|
|
146
|
+
titan_cli-0.1.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|