monoco-toolkit 0.3.10__py3-none-any.whl → 0.3.11__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.
- monoco/__main__.py +8 -0
- monoco/core/artifacts/__init__.py +16 -0
- monoco/core/artifacts/manager.py +575 -0
- monoco/core/artifacts/models.py +161 -0
- monoco/core/config.py +31 -4
- monoco/core/git.py +23 -0
- monoco/core/ingestion/__init__.py +20 -0
- monoco/core/ingestion/discovery.py +248 -0
- monoco/core/ingestion/watcher.py +343 -0
- monoco/core/ingestion/worker.py +436 -0
- monoco/core/loader.py +633 -0
- monoco/core/registry.py +34 -25
- monoco/core/skills.py +119 -80
- monoco/daemon/app.py +77 -1
- monoco/daemon/commands.py +10 -0
- monoco/daemon/mailroom_service.py +196 -0
- monoco/daemon/models.py +1 -0
- monoco/daemon/scheduler.py +236 -0
- monoco/daemon/services.py +185 -0
- monoco/daemon/triggers.py +55 -0
- monoco/features/agent/adapter.py +17 -7
- monoco/features/agent/apoptosis.py +4 -4
- monoco/features/agent/manager.py +41 -5
- monoco/{core/resources/en/skills/monoco_core → features/agent/resources/en/skills/monoco_atom_core}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_engineer → monoco_workflow_agent_engineer}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_manager → monoco_workflow_agent_manager}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_planner → monoco_workflow_agent_planner}/SKILL.md +2 -2
- monoco/features/agent/resources/en/skills/{flow_reviewer → monoco_workflow_agent_reviewer}/SKILL.md +2 -2
- monoco/features/agent/resources/{roles/role-engineer.yaml → zh/roles/monoco_role_engineer.yaml} +3 -3
- monoco/features/agent/resources/{roles/role-manager.yaml → zh/roles/monoco_role_manager.yaml} +8 -8
- monoco/features/agent/resources/{roles/role-planner.yaml → zh/roles/monoco_role_planner.yaml} +8 -8
- monoco/features/agent/resources/{roles/role-reviewer.yaml → zh/roles/monoco_role_reviewer.yaml} +8 -8
- monoco/{core/resources/zh/skills/monoco_core → features/agent/resources/zh/skills/monoco_atom_core}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_engineer → monoco_workflow_agent_engineer}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_manager → monoco_workflow_agent_manager}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_planner → monoco_workflow_agent_planner}/SKILL.md +2 -2
- monoco/features/agent/resources/zh/skills/{flow_reviewer → monoco_workflow_agent_reviewer}/SKILL.md +2 -2
- monoco/features/agent/session.py +59 -11
- monoco/features/artifact/__init__.py +0 -0
- monoco/features/artifact/adapter.py +33 -0
- monoco/features/artifact/resources/zh/AGENTS.md +14 -0
- monoco/features/artifact/resources/zh/skills/monoco_atom_artifact/SKILL.md +278 -0
- monoco/features/glossary/adapter.py +18 -7
- monoco/features/glossary/resources/en/skills/{monoco_glossary → monoco_atom_glossary}/SKILL.md +2 -2
- monoco/features/glossary/resources/zh/skills/{monoco_glossary → monoco_atom_glossary}/SKILL.md +2 -2
- monoco/features/hooks/__init__.py +11 -0
- monoco/features/hooks/adapter.py +67 -0
- monoco/features/hooks/commands.py +309 -0
- monoco/features/hooks/core.py +441 -0
- monoco/features/hooks/resources/ADDING_HOOKS.md +234 -0
- monoco/features/i18n/adapter.py +18 -5
- monoco/features/i18n/core.py +482 -17
- monoco/features/i18n/resources/en/skills/{monoco_i18n → monoco_atom_i18n}/SKILL.md +2 -2
- monoco/features/i18n/resources/en/skills/{i18n_scan_workflow → monoco_workflow_i18n_scan}/SKILL.md +2 -2
- monoco/features/i18n/resources/zh/skills/{monoco_i18n → monoco_atom_i18n}/SKILL.md +2 -2
- monoco/features/i18n/resources/zh/skills/{i18n_scan_workflow → monoco_workflow_i18n_scan}/SKILL.md +2 -2
- monoco/features/issue/adapter.py +19 -6
- monoco/features/issue/commands.py +281 -7
- monoco/features/issue/core.py +227 -13
- monoco/features/issue/engine/machine.py +114 -4
- monoco/features/issue/linter.py +60 -5
- monoco/features/issue/models.py +2 -2
- monoco/features/issue/resources/en/AGENTS.md +109 -0
- monoco/features/issue/resources/en/skills/{monoco_issue → monoco_atom_issue}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_create_workflow → monoco_workflow_issue_creation}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_develop_workflow → monoco_workflow_issue_development}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_lifecycle_workflow → monoco_workflow_issue_management}/SKILL.md +2 -2
- monoco/features/issue/resources/en/skills/{issue_refine_workflow → monoco_workflow_issue_refinement}/SKILL.md +2 -2
- monoco/features/issue/resources/hooks/post-checkout.sh +39 -0
- monoco/features/issue/resources/hooks/pre-commit.sh +41 -0
- monoco/features/issue/resources/hooks/pre-push.sh +35 -0
- monoco/features/issue/resources/zh/AGENTS.md +109 -0
- monoco/features/issue/resources/zh/skills/{monoco_issue → monoco_atom_issue_lifecycle}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_create_workflow → monoco_workflow_issue_creation}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_develop_workflow → monoco_workflow_issue_development}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_lifecycle_workflow → monoco_workflow_issue_management}/SKILL.md +2 -2
- monoco/features/issue/resources/zh/skills/{issue_refine_workflow → monoco_workflow_issue_refinement}/SKILL.md +2 -2
- monoco/features/issue/validator.py +101 -1
- monoco/features/memo/adapter.py +21 -8
- monoco/features/memo/cli.py +103 -10
- monoco/features/memo/core.py +178 -92
- monoco/features/memo/models.py +53 -0
- monoco/features/memo/resources/en/skills/{monoco_memo → monoco_atom_memo}/SKILL.md +2 -2
- monoco/features/memo/resources/en/skills/{note_processing_workflow → monoco_workflow_note_processing}/SKILL.md +2 -2
- monoco/features/memo/resources/zh/skills/{monoco_memo → monoco_atom_memo}/SKILL.md +2 -2
- monoco/features/memo/resources/zh/skills/{note_processing_workflow → monoco_workflow_note_processing}/SKILL.md +2 -2
- monoco/features/spike/adapter.py +18 -5
- monoco/features/spike/resources/en/skills/{monoco_spike → monoco_atom_spike}/SKILL.md +2 -2
- monoco/features/spike/resources/en/skills/{research_workflow → monoco_workflow_research}/SKILL.md +2 -2
- monoco/features/spike/resources/zh/skills/{monoco_spike → monoco_atom_spike}/SKILL.md +2 -2
- monoco/features/spike/resources/zh/skills/{research_workflow → monoco_workflow_research}/SKILL.md +2 -2
- monoco/main.py +38 -1
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.11.dist-info}/METADATA +7 -1
- monoco_toolkit-0.3.11.dist-info/RECORD +181 -0
- monoco_toolkit-0.3.10.dist-info/RECORD +0 -156
- /monoco/{core → features/agent}/resources/en/AGENTS.md +0 -0
- /monoco/{core → features/agent}/resources/zh/AGENTS.md +0 -0
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.11.dist-info}/WHEEL +0 -0
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.11.dist-info}/entry_points.txt +0 -0
- {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.11.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"""
|
|
2
|
+
CLI commands for Git Hooks management.
|
|
3
|
+
|
|
4
|
+
Provides:
|
|
5
|
+
- monoco hooks install
|
|
6
|
+
- monoco hooks uninstall
|
|
7
|
+
- monoco hooks status
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import typer
|
|
11
|
+
from pathlib import Path
|
|
12
|
+
from typing import Optional
|
|
13
|
+
from rich.console import Console
|
|
14
|
+
from rich.table import Table
|
|
15
|
+
from rich.panel import Panel
|
|
16
|
+
from rich.tree import Tree
|
|
17
|
+
|
|
18
|
+
from monoco.core.config import get_config
|
|
19
|
+
from monoco.core.output import OutputManager
|
|
20
|
+
from .core import GitHooksManager, HookConfig
|
|
21
|
+
|
|
22
|
+
app = typer.Typer(help="Manage Git hooks for development workflow.")
|
|
23
|
+
console = Console()
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _get_manager() -> GitHooksManager:
|
|
27
|
+
"""Get configured GitHooksManager instance."""
|
|
28
|
+
config = get_config()
|
|
29
|
+
project_root = Path(config.paths.root).resolve()
|
|
30
|
+
|
|
31
|
+
hooks_config = HookConfig(
|
|
32
|
+
enabled=config.hooks.enabled,
|
|
33
|
+
enabled_features=config.hooks.features,
|
|
34
|
+
enabled_hooks=config.hooks.hooks,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
return GitHooksManager(project_root, hooks_config)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
@app.command("install")
|
|
41
|
+
def install(
|
|
42
|
+
hook_type: Optional[str] = typer.Argument(
|
|
43
|
+
None,
|
|
44
|
+
help="Specific hook type to install (pre-commit, pre-push, post-checkout). If not specified, installs all enabled hooks."
|
|
45
|
+
),
|
|
46
|
+
force: bool = typer.Option(
|
|
47
|
+
False,
|
|
48
|
+
"--force",
|
|
49
|
+
"-f",
|
|
50
|
+
help="Force installation even if hook already exists",
|
|
51
|
+
),
|
|
52
|
+
json: bool = typer.Option(
|
|
53
|
+
False,
|
|
54
|
+
"--json",
|
|
55
|
+
help="Output in JSON format (for agent mode)",
|
|
56
|
+
),
|
|
57
|
+
):
|
|
58
|
+
"""
|
|
59
|
+
Install git hooks to .git/hooks/.
|
|
60
|
+
|
|
61
|
+
Discovers hooks from all Features and generates combined hook scripts.
|
|
62
|
+
"""
|
|
63
|
+
manager = _get_manager()
|
|
64
|
+
|
|
65
|
+
if not manager.is_git_repo():
|
|
66
|
+
OutputManager.error("Not a git repository. Cannot install hooks.")
|
|
67
|
+
raise typer.Exit(code=1)
|
|
68
|
+
|
|
69
|
+
if hook_type:
|
|
70
|
+
# Install specific hook type
|
|
71
|
+
from .core import HookType
|
|
72
|
+
try:
|
|
73
|
+
htype = HookType(hook_type)
|
|
74
|
+
except ValueError:
|
|
75
|
+
valid_types = [t.value for t in HookType]
|
|
76
|
+
OutputManager.error(f"Invalid hook type: {hook_type}. Valid types: {', '.join(valid_types)}")
|
|
77
|
+
raise typer.Exit(code=1)
|
|
78
|
+
|
|
79
|
+
# Temporarily enable this hook type
|
|
80
|
+
manager.config.enabled_hooks[hook_type] = True
|
|
81
|
+
|
|
82
|
+
results = manager.install()
|
|
83
|
+
|
|
84
|
+
if OutputManager.is_agent_mode() or json:
|
|
85
|
+
OutputManager.print({
|
|
86
|
+
"status": "installed",
|
|
87
|
+
"hooks": {k.value: v for k, v in results.items()}
|
|
88
|
+
})
|
|
89
|
+
else:
|
|
90
|
+
installed = [k.value for k, v in results.items() if v]
|
|
91
|
+
skipped = [k.value for k, v in results.items() if not v]
|
|
92
|
+
|
|
93
|
+
if installed:
|
|
94
|
+
console.print(f"[green]✓ Installed hooks:[/green] {', '.join(installed)}")
|
|
95
|
+
if skipped:
|
|
96
|
+
console.print(f"[yellow]⚠ Skipped hooks:[/yellow] {', '.join(skipped)}")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@app.command("uninstall")
|
|
100
|
+
def uninstall(
|
|
101
|
+
hook_type: Optional[str] = typer.Argument(
|
|
102
|
+
None,
|
|
103
|
+
help="Specific hook type to uninstall. If not specified, uninstalls all Monoco-managed hooks."
|
|
104
|
+
),
|
|
105
|
+
json: bool = typer.Option(
|
|
106
|
+
False,
|
|
107
|
+
"--json",
|
|
108
|
+
help="Output in JSON format (for agent mode)",
|
|
109
|
+
),
|
|
110
|
+
):
|
|
111
|
+
"""
|
|
112
|
+
Uninstall Monoco-managed git hooks from .git/hooks/.
|
|
113
|
+
|
|
114
|
+
Only removes hooks that were installed by Monoco (identified by marker).
|
|
115
|
+
"""
|
|
116
|
+
manager = _get_manager()
|
|
117
|
+
|
|
118
|
+
if not manager.is_git_repo():
|
|
119
|
+
OutputManager.error("Not a git repository.")
|
|
120
|
+
raise typer.Exit(code=1)
|
|
121
|
+
|
|
122
|
+
if hook_type:
|
|
123
|
+
# Uninstall specific hook type
|
|
124
|
+
hook_path = manager.hooks_dir / hook_type
|
|
125
|
+
if hook_path.exists():
|
|
126
|
+
try:
|
|
127
|
+
content = hook_path.read_text(encoding="utf-8")
|
|
128
|
+
if manager.MONOCO_MARKER in content:
|
|
129
|
+
hook_path.unlink()
|
|
130
|
+
results = {hook_type: True}
|
|
131
|
+
else:
|
|
132
|
+
results = {hook_type: False}
|
|
133
|
+
except Exception as e:
|
|
134
|
+
OutputManager.error(f"Failed to uninstall {hook_type}: {e}")
|
|
135
|
+
raise typer.Exit(code=1)
|
|
136
|
+
else:
|
|
137
|
+
results = {hook_type: False}
|
|
138
|
+
else:
|
|
139
|
+
results = manager.uninstall()
|
|
140
|
+
|
|
141
|
+
if OutputManager.is_agent_mode() or json:
|
|
142
|
+
OutputManager.print({
|
|
143
|
+
"status": "uninstalled",
|
|
144
|
+
"hooks": {k.value if hasattr(k, 'value') else k: v for k, v in results.items()}
|
|
145
|
+
})
|
|
146
|
+
else:
|
|
147
|
+
removed = [k.value if hasattr(k, 'value') else k for k, v in results.items() if v]
|
|
148
|
+
skipped = [k.value if hasattr(k, 'value') else k for k, v in results.items() if not v]
|
|
149
|
+
|
|
150
|
+
if removed:
|
|
151
|
+
console.print(f"[green]✓ Removed hooks:[/green] {', '.join(removed)}")
|
|
152
|
+
if skipped:
|
|
153
|
+
console.print(f"[dim]- Skipped (not managed by Monoco):[/dim] {', '.join(skipped)}")
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
@app.command("status")
|
|
157
|
+
def status(
|
|
158
|
+
json: bool = typer.Option(
|
|
159
|
+
False,
|
|
160
|
+
"--json",
|
|
161
|
+
help="Output in JSON format (for agent mode)",
|
|
162
|
+
),
|
|
163
|
+
):
|
|
164
|
+
"""
|
|
165
|
+
Show current hooks installation status.
|
|
166
|
+
|
|
167
|
+
Displays which hooks are installed, discovered, and their configuration.
|
|
168
|
+
"""
|
|
169
|
+
manager = _get_manager()
|
|
170
|
+
status_info = manager.get_status()
|
|
171
|
+
|
|
172
|
+
if OutputManager.is_agent_mode() or json:
|
|
173
|
+
OutputManager.print(status_info)
|
|
174
|
+
return
|
|
175
|
+
|
|
176
|
+
# Human-readable output
|
|
177
|
+
if not status_info["is_git_repo"]:
|
|
178
|
+
console.print("[red]Not a git repository.[/red]")
|
|
179
|
+
raise typer.Exit(code=1)
|
|
180
|
+
|
|
181
|
+
console.print(Panel("[bold blue]Git Hooks Status[/bold blue]", expand=False))
|
|
182
|
+
|
|
183
|
+
# Installed hooks table
|
|
184
|
+
table = Table(title="Installed Hooks")
|
|
185
|
+
table.add_column("Hook Type", style="cyan")
|
|
186
|
+
table.add_column("Status", style="green")
|
|
187
|
+
table.add_column("Managed By", style="dim")
|
|
188
|
+
|
|
189
|
+
for hook_type, info in status_info["installed"].items():
|
|
190
|
+
if info["exists"]:
|
|
191
|
+
status_str = "[green]Installed[/green]"
|
|
192
|
+
managed = "Monoco" if info.get("managed_by_monoco") else "External"
|
|
193
|
+
else:
|
|
194
|
+
status_str = "[dim]Not installed[/dim]"
|
|
195
|
+
managed = "-"
|
|
196
|
+
table.add_row(hook_type, status_str, managed)
|
|
197
|
+
|
|
198
|
+
console.print(table)
|
|
199
|
+
|
|
200
|
+
# Discovered hooks
|
|
201
|
+
if status_info["discovered"]:
|
|
202
|
+
console.print("\n[bold]Discovered Hook Scripts:[/bold]")
|
|
203
|
+
for hook_type, scripts in status_info["discovered"].items():
|
|
204
|
+
tree = Tree(f"[cyan]{hook_type}[/cyan]")
|
|
205
|
+
for script in scripts:
|
|
206
|
+
tree.add(f"[dim]{script['feature']}[/dim] (priority: {script['priority']})")
|
|
207
|
+
console.print(tree)
|
|
208
|
+
else:
|
|
209
|
+
console.print("\n[yellow]No hook scripts discovered from Features.[/yellow]")
|
|
210
|
+
|
|
211
|
+
# Configuration
|
|
212
|
+
config_tree = Tree("[bold]Configuration:[/bold]")
|
|
213
|
+
config_tree.add(f"Hooks enabled: {status_info['config']['enabled']}")
|
|
214
|
+
|
|
215
|
+
if status_info['config']['enabled_features']:
|
|
216
|
+
features_branch = config_tree.add("Feature-specific settings:")
|
|
217
|
+
for feature, enabled in status_info['config']['enabled_features'].items():
|
|
218
|
+
status = "enabled" if enabled else "disabled"
|
|
219
|
+
features_branch.add(f"{feature}: {status}")
|
|
220
|
+
|
|
221
|
+
if status_info['config']['enabled_hooks']:
|
|
222
|
+
hooks_branch = config_tree.add("Hook-type settings:")
|
|
223
|
+
for hook, enabled in status_info['config']['enabled_hooks'].items():
|
|
224
|
+
status = "enabled" if enabled else "disabled"
|
|
225
|
+
hooks_branch.add(f"{hook}: {status}")
|
|
226
|
+
|
|
227
|
+
console.print(config_tree)
|
|
228
|
+
|
|
229
|
+
|
|
230
|
+
@app.command("enable")
|
|
231
|
+
def enable(
|
|
232
|
+
hook_type: str = typer.Argument(..., help="Hook type to enable (pre-commit, pre-push, post-checkout)"),
|
|
233
|
+
):
|
|
234
|
+
"""
|
|
235
|
+
Enable a specific hook type in configuration.
|
|
236
|
+
|
|
237
|
+
This updates workspace.yaml to enable the hook for future installs.
|
|
238
|
+
"""
|
|
239
|
+
from .core import HookType
|
|
240
|
+
try:
|
|
241
|
+
HookType(hook_type)
|
|
242
|
+
except ValueError:
|
|
243
|
+
valid_types = [t.value for t in HookType]
|
|
244
|
+
OutputManager.error(f"Invalid hook type: {hook_type}. Valid types: {', '.join(valid_types)}")
|
|
245
|
+
raise typer.Exit(code=1)
|
|
246
|
+
|
|
247
|
+
# Update workspace.yaml
|
|
248
|
+
config = get_config()
|
|
249
|
+
config_path = Path(config.paths.root) / ".monoco" / "workspace.yaml"
|
|
250
|
+
try:
|
|
251
|
+
import yaml
|
|
252
|
+
with open(config_path, 'r') as f:
|
|
253
|
+
data = yaml.safe_load(f) or {}
|
|
254
|
+
|
|
255
|
+
if 'hooks' not in data:
|
|
256
|
+
data['hooks'] = {}
|
|
257
|
+
if 'hooks' not in data['hooks']:
|
|
258
|
+
data['hooks']['hooks'] = {}
|
|
259
|
+
data['hooks']['hooks'][hook_type] = True
|
|
260
|
+
|
|
261
|
+
with open(config_path, 'w') as f:
|
|
262
|
+
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
|
|
263
|
+
|
|
264
|
+
console.print(f"[green]✓ Enabled {hook_type} hook in configuration[/green]")
|
|
265
|
+
console.print(f"[dim]Run 'monoco hooks install' to apply changes.[/dim]")
|
|
266
|
+
except Exception as e:
|
|
267
|
+
OutputManager.error(f"Failed to update configuration: {e}")
|
|
268
|
+
raise typer.Exit(code=1)
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
@app.command("disable")
|
|
272
|
+
def disable(
|
|
273
|
+
hook_type: str = typer.Argument(..., help="Hook type to disable (pre-commit, pre-push, post-checkout)"),
|
|
274
|
+
):
|
|
275
|
+
"""
|
|
276
|
+
Disable a specific hook type in configuration.
|
|
277
|
+
|
|
278
|
+
This updates workspace.yaml to disable the hook for future installs.
|
|
279
|
+
"""
|
|
280
|
+
from .core import HookType
|
|
281
|
+
try:
|
|
282
|
+
HookType(hook_type)
|
|
283
|
+
except ValueError:
|
|
284
|
+
valid_types = [t.value for t in HookType]
|
|
285
|
+
OutputManager.error(f"Invalid hook type: {hook_type}. Valid types: {', '.join(valid_types)}")
|
|
286
|
+
raise typer.Exit(code=1)
|
|
287
|
+
|
|
288
|
+
# Update workspace.yaml
|
|
289
|
+
config = get_config()
|
|
290
|
+
config_path = Path(config.paths.root) / ".monoco" / "workspace.yaml"
|
|
291
|
+
try:
|
|
292
|
+
import yaml
|
|
293
|
+
with open(config_path, 'r') as f:
|
|
294
|
+
data = yaml.safe_load(f) or {}
|
|
295
|
+
|
|
296
|
+
if 'hooks' not in data:
|
|
297
|
+
data['hooks'] = {}
|
|
298
|
+
if 'hooks' not in data['hooks']:
|
|
299
|
+
data['hooks']['hooks'] = {}
|
|
300
|
+
data['hooks']['hooks'][hook_type] = False
|
|
301
|
+
|
|
302
|
+
with open(config_path, 'w') as f:
|
|
303
|
+
yaml.dump(data, f, default_flow_style=False, allow_unicode=True)
|
|
304
|
+
|
|
305
|
+
console.print(f"[green]✓ Disabled {hook_type} hook in configuration[/green]")
|
|
306
|
+
console.print(f"[dim]Run 'monoco hooks uninstall {hook_type}' to remove existing hook.[/dim]")
|
|
307
|
+
except Exception as e:
|
|
308
|
+
OutputManager.error(f"Failed to update configuration: {e}")
|
|
309
|
+
raise typer.Exit(code=1)
|