monoco-toolkit 0.3.10__py3-none-any.whl → 0.3.12__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.
Files changed (130) hide show
  1. monoco/__main__.py +8 -0
  2. monoco/core/artifacts/__init__.py +16 -0
  3. monoco/core/artifacts/manager.py +575 -0
  4. monoco/core/artifacts/models.py +161 -0
  5. monoco/core/automation/__init__.py +51 -0
  6. monoco/core/automation/config.py +338 -0
  7. monoco/core/automation/field_watcher.py +296 -0
  8. monoco/core/automation/handlers.py +723 -0
  9. monoco/core/config.py +31 -4
  10. monoco/core/executor/__init__.py +38 -0
  11. monoco/core/executor/agent_action.py +254 -0
  12. monoco/core/executor/git_action.py +303 -0
  13. monoco/core/executor/im_action.py +309 -0
  14. monoco/core/executor/pytest_action.py +218 -0
  15. monoco/core/git.py +38 -0
  16. monoco/core/hooks/context.py +74 -13
  17. monoco/core/ingestion/__init__.py +20 -0
  18. monoco/core/ingestion/discovery.py +248 -0
  19. monoco/core/ingestion/watcher.py +343 -0
  20. monoco/core/ingestion/worker.py +436 -0
  21. monoco/core/loader.py +633 -0
  22. monoco/core/registry.py +34 -25
  23. monoco/core/router/__init__.py +55 -0
  24. monoco/core/router/action.py +341 -0
  25. monoco/core/router/router.py +392 -0
  26. monoco/core/scheduler/__init__.py +63 -0
  27. monoco/core/scheduler/base.py +152 -0
  28. monoco/core/scheduler/engines.py +175 -0
  29. monoco/core/scheduler/events.py +171 -0
  30. monoco/core/scheduler/local.py +377 -0
  31. monoco/core/skills.py +119 -80
  32. monoco/core/watcher/__init__.py +57 -0
  33. monoco/core/watcher/base.py +365 -0
  34. monoco/core/watcher/dropzone.py +152 -0
  35. monoco/core/watcher/issue.py +303 -0
  36. monoco/core/watcher/memo.py +200 -0
  37. monoco/core/watcher/task.py +238 -0
  38. monoco/daemon/app.py +77 -1
  39. monoco/daemon/commands.py +10 -0
  40. monoco/daemon/events.py +34 -0
  41. monoco/daemon/mailroom_service.py +196 -0
  42. monoco/daemon/models.py +1 -0
  43. monoco/daemon/scheduler.py +207 -0
  44. monoco/daemon/services.py +27 -58
  45. monoco/daemon/triggers.py +55 -0
  46. monoco/features/agent/__init__.py +25 -7
  47. monoco/features/agent/adapter.py +17 -7
  48. monoco/features/agent/cli.py +91 -57
  49. monoco/features/agent/engines.py +31 -170
  50. monoco/{core/resources/en/skills/monoco_core → features/agent/resources/en/skills/monoco_atom_core}/SKILL.md +2 -2
  51. monoco/features/agent/resources/en/skills/{flow_engineer → monoco_workflow_agent_engineer}/SKILL.md +2 -2
  52. monoco/features/agent/resources/en/skills/{flow_manager → monoco_workflow_agent_manager}/SKILL.md +2 -2
  53. monoco/features/agent/resources/en/skills/{flow_planner → monoco_workflow_agent_planner}/SKILL.md +2 -2
  54. monoco/features/agent/resources/en/skills/{flow_reviewer → monoco_workflow_agent_reviewer}/SKILL.md +2 -2
  55. monoco/features/agent/resources/{roles/role-engineer.yaml → zh/roles/monoco_role_engineer.yaml} +3 -3
  56. monoco/features/agent/resources/{roles/role-manager.yaml → zh/roles/monoco_role_manager.yaml} +8 -8
  57. monoco/features/agent/resources/{roles/role-planner.yaml → zh/roles/monoco_role_planner.yaml} +8 -8
  58. monoco/features/agent/resources/{roles/role-reviewer.yaml → zh/roles/monoco_role_reviewer.yaml} +8 -8
  59. monoco/{core/resources/zh/skills/monoco_core → features/agent/resources/zh/skills/monoco_atom_core}/SKILL.md +2 -2
  60. monoco/features/agent/resources/zh/skills/{flow_engineer → monoco_workflow_agent_engineer}/SKILL.md +2 -2
  61. monoco/features/agent/resources/zh/skills/{flow_manager → monoco_workflow_agent_manager}/SKILL.md +2 -2
  62. monoco/features/agent/resources/zh/skills/{flow_planner → monoco_workflow_agent_planner}/SKILL.md +2 -2
  63. monoco/features/agent/resources/zh/skills/{flow_reviewer → monoco_workflow_agent_reviewer}/SKILL.md +2 -2
  64. monoco/features/agent/worker.py +1 -1
  65. monoco/features/artifact/__init__.py +0 -0
  66. monoco/features/artifact/adapter.py +33 -0
  67. monoco/features/artifact/resources/zh/AGENTS.md +14 -0
  68. monoco/features/artifact/resources/zh/skills/monoco_atom_artifact/SKILL.md +278 -0
  69. monoco/features/glossary/adapter.py +18 -7
  70. monoco/features/glossary/resources/en/skills/{monoco_glossary → monoco_atom_glossary}/SKILL.md +2 -2
  71. monoco/features/glossary/resources/zh/skills/{monoco_glossary → monoco_atom_glossary}/SKILL.md +2 -2
  72. monoco/features/hooks/__init__.py +11 -0
  73. monoco/features/hooks/adapter.py +67 -0
  74. monoco/features/hooks/commands.py +309 -0
  75. monoco/features/hooks/core.py +441 -0
  76. monoco/features/hooks/resources/ADDING_HOOKS.md +234 -0
  77. monoco/features/i18n/adapter.py +18 -5
  78. monoco/features/i18n/core.py +482 -17
  79. monoco/features/i18n/resources/en/skills/{monoco_i18n → monoco_atom_i18n}/SKILL.md +2 -2
  80. monoco/features/i18n/resources/en/skills/{i18n_scan_workflow → monoco_workflow_i18n_scan}/SKILL.md +2 -2
  81. monoco/features/i18n/resources/zh/skills/{monoco_i18n → monoco_atom_i18n}/SKILL.md +2 -2
  82. monoco/features/i18n/resources/zh/skills/{i18n_scan_workflow → monoco_workflow_i18n_scan}/SKILL.md +2 -2
  83. monoco/features/issue/adapter.py +19 -6
  84. monoco/features/issue/commands.py +352 -20
  85. monoco/features/issue/core.py +475 -16
  86. monoco/features/issue/engine/machine.py +114 -4
  87. monoco/features/issue/linter.py +60 -5
  88. monoco/features/issue/models.py +2 -2
  89. monoco/features/issue/resources/en/AGENTS.md +109 -0
  90. monoco/features/issue/resources/en/skills/{monoco_issue → monoco_atom_issue}/SKILL.md +2 -2
  91. monoco/features/issue/resources/en/skills/{issue_create_workflow → monoco_workflow_issue_creation}/SKILL.md +2 -2
  92. monoco/features/issue/resources/en/skills/{issue_develop_workflow → monoco_workflow_issue_development}/SKILL.md +2 -2
  93. monoco/features/issue/resources/en/skills/{issue_lifecycle_workflow → monoco_workflow_issue_management}/SKILL.md +2 -2
  94. monoco/features/issue/resources/en/skills/{issue_refine_workflow → monoco_workflow_issue_refinement}/SKILL.md +2 -2
  95. monoco/features/issue/resources/hooks/post-checkout.sh +39 -0
  96. monoco/features/issue/resources/hooks/pre-commit.sh +41 -0
  97. monoco/features/issue/resources/hooks/pre-push.sh +35 -0
  98. monoco/features/issue/resources/zh/AGENTS.md +109 -0
  99. monoco/features/issue/resources/zh/skills/{monoco_issue → monoco_atom_issue_lifecycle}/SKILL.md +2 -2
  100. monoco/features/issue/resources/zh/skills/{issue_create_workflow → monoco_workflow_issue_creation}/SKILL.md +2 -2
  101. monoco/features/issue/resources/zh/skills/{issue_develop_workflow → monoco_workflow_issue_development}/SKILL.md +2 -2
  102. monoco/features/issue/resources/zh/skills/{issue_lifecycle_workflow → monoco_workflow_issue_management}/SKILL.md +2 -2
  103. monoco/features/issue/resources/zh/skills/{issue_refine_workflow → monoco_workflow_issue_refinement}/SKILL.md +2 -2
  104. monoco/features/issue/validator.py +101 -1
  105. monoco/features/memo/adapter.py +21 -8
  106. monoco/features/memo/cli.py +103 -10
  107. monoco/features/memo/core.py +178 -92
  108. monoco/features/memo/models.py +53 -0
  109. monoco/features/memo/resources/en/skills/{monoco_memo → monoco_atom_memo}/SKILL.md +2 -2
  110. monoco/features/memo/resources/en/skills/{note_processing_workflow → monoco_workflow_note_processing}/SKILL.md +2 -2
  111. monoco/features/memo/resources/zh/skills/{monoco_memo → monoco_atom_memo}/SKILL.md +2 -2
  112. monoco/features/memo/resources/zh/skills/{note_processing_workflow → monoco_workflow_note_processing}/SKILL.md +2 -2
  113. monoco/features/spike/adapter.py +18 -5
  114. monoco/features/spike/commands.py +5 -3
  115. monoco/features/spike/resources/en/skills/{monoco_spike → monoco_atom_spike}/SKILL.md +2 -2
  116. monoco/features/spike/resources/en/skills/{research_workflow → monoco_workflow_research}/SKILL.md +2 -2
  117. monoco/features/spike/resources/zh/skills/{monoco_spike → monoco_atom_spike}/SKILL.md +2 -2
  118. monoco/features/spike/resources/zh/skills/{research_workflow → monoco_workflow_research}/SKILL.md +2 -2
  119. monoco/main.py +38 -1
  120. {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.dist-info}/METADATA +7 -1
  121. monoco_toolkit-0.3.12.dist-info/RECORD +202 -0
  122. monoco/features/agent/apoptosis.py +0 -44
  123. monoco/features/agent/manager.py +0 -91
  124. monoco/features/agent/session.py +0 -121
  125. monoco_toolkit-0.3.10.dist-info/RECORD +0 -156
  126. /monoco/{core → features/agent}/resources/en/AGENTS.md +0 -0
  127. /monoco/{core → features/agent}/resources/zh/AGENTS.md +0 -0
  128. {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.dist-info}/WHEEL +0 -0
  129. {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.dist-info}/entry_points.txt +0 -0
  130. {monoco_toolkit-0.3.10.dist-info → monoco_toolkit-0.3.12.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)