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,278 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: monoco_atom_artifact
|
|
3
|
+
description: 多模态文档处理 Skill。指导 Agent 将 Office 文档转换为 PDF 并渲染为 WebP 图片,注册到 Monoco Artifact 系统。
|
|
4
|
+
type: atom
|
|
5
|
+
version: 1.0.0
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Monoco Artifact: 多模态文档处理
|
|
9
|
+
|
|
10
|
+
本 Skill 指导 Agent 执行 Office 文档 → PDF → WebP 的完整转换流程,并将结果注册为 Monoco Artifact。
|
|
11
|
+
|
|
12
|
+
## 概述
|
|
13
|
+
|
|
14
|
+
多模态文档处理允许 Agent:
|
|
15
|
+
|
|
16
|
+
1. 将 Office 文档 (.docx, .xlsx, .pptx) 转换为 PDF
|
|
17
|
+
2. 将 PDF 页面渲染为 WebP 图片 (150 DPI)
|
|
18
|
+
3. 使用 Monoco CLI 注册转换产物为 Artifact
|
|
19
|
+
|
|
20
|
+
## 环境探测
|
|
21
|
+
|
|
22
|
+
在执行转换前,Agent 必须探测以下依赖:
|
|
23
|
+
|
|
24
|
+
### 1. LibreOffice (soffice)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 检查 soffice 是否可用
|
|
28
|
+
which soffice
|
|
29
|
+
soffice --version
|
|
30
|
+
|
|
31
|
+
# 常见安装路径 (macOS)
|
|
32
|
+
# /Applications/LibreOffice.app/Contents/MacOS/soffice
|
|
33
|
+
|
|
34
|
+
# 常见安装路径 (Linux)
|
|
35
|
+
# /usr/bin/soffice
|
|
36
|
+
# /usr/lib/libreoffice/program/soffice
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**如果未安装**:
|
|
40
|
+
|
|
41
|
+
- **macOS**: `brew install --cask libreoffice`
|
|
42
|
+
- **Ubuntu/Debian**: `sudo apt-get install libreoffice`
|
|
43
|
+
- **CentOS/RHEL**: `sudo yum install libreoffice`
|
|
44
|
+
|
|
45
|
+
### 2. Python 依赖
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# 检查 PyMuPDF (fitz)
|
|
49
|
+
python3 -c "import fitz; print(fitz.__doc__)"
|
|
50
|
+
|
|
51
|
+
# 安装依赖
|
|
52
|
+
pip install pymupdf pillow
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. Monoco CLI
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# 验证 monoco 可用
|
|
59
|
+
monoco --version
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## 转换工作流
|
|
63
|
+
|
|
64
|
+
### 标准转换流程
|
|
65
|
+
|
|
66
|
+
```mermaid
|
|
67
|
+
flowchart LR
|
|
68
|
+
A[Office Doc] -->|soffice| B[PDF]
|
|
69
|
+
B -->|fitz| C[WebP Images]
|
|
70
|
+
C -->|monoco| D[Artifact Registry]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 步骤 1: Office → PDF
|
|
74
|
+
|
|
75
|
+
使用 LibreOffice Headless 模式进行转换:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 基础转换
|
|
79
|
+
soffice --headless --convert-to pdf --outdir /output/path /input/document.docx
|
|
80
|
+
|
|
81
|
+
# 推荐参数 (高质量、安全模式)
|
|
82
|
+
soffice \
|
|
83
|
+
--headless \
|
|
84
|
+
--convert-to pdf:writer_pdf_Export:ExportBookmarks=true \
|
|
85
|
+
--outdir /output/path \
|
|
86
|
+
/input/document.docx
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**参数说明**:
|
|
90
|
+
|
|
91
|
+
- `--headless`: 无 GUI 模式,适合服务器/自动化环境
|
|
92
|
+
- `--convert-to pdf`: 指定输出格式
|
|
93
|
+
- `--outdir`: 输出目录
|
|
94
|
+
- `ExportBookmarks=true`: 保留文档书签
|
|
95
|
+
|
|
96
|
+
### 步骤 2: PDF → WebP
|
|
97
|
+
|
|
98
|
+
使用 PyMuPDF (fitz) 渲染页面:
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import fitz # PyMuPDF
|
|
102
|
+
from pathlib import Path
|
|
103
|
+
|
|
104
|
+
def pdf_to_webp(pdf_path: str, output_dir: str, dpi: int = 150) -> list[str]:
|
|
105
|
+
"""
|
|
106
|
+
将 PDF 页面渲染为 WebP 图片。
|
|
107
|
+
|
|
108
|
+
Args:
|
|
109
|
+
pdf_path: PDF 文件路径
|
|
110
|
+
output_dir: 输出目录
|
|
111
|
+
dpi: 渲染分辨率 (默认 150 DPI)
|
|
112
|
+
|
|
113
|
+
Returns:
|
|
114
|
+
生成的 WebP 文件路径列表
|
|
115
|
+
"""
|
|
116
|
+
doc = fitz.open(pdf_path)
|
|
117
|
+
output_path = Path(output_dir)
|
|
118
|
+
output_path.mkdir(parents=True, exist_ok=True)
|
|
119
|
+
|
|
120
|
+
webp_files = []
|
|
121
|
+
zoom = dpi / 72 # 72 DPI 是 PDF 默认分辨率
|
|
122
|
+
mat = fitz.Matrix(zoom, zoom)
|
|
123
|
+
|
|
124
|
+
for page_num in range(len(doc)):
|
|
125
|
+
page = doc[page_num]
|
|
126
|
+
pix = page.get_pixmap(matrix=mat)
|
|
127
|
+
|
|
128
|
+
webp_file = output_path / f"page_{page_num + 1:03d}.webp"
|
|
129
|
+
pix.save(str(webp_file))
|
|
130
|
+
webp_files.append(str(webp_file))
|
|
131
|
+
|
|
132
|
+
doc.close()
|
|
133
|
+
return webp_files
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
**DPI 选择指南**:
|
|
137
|
+
| DPI | 用途 | 文件大小 |
|
|
138
|
+
|-----|------|----------|
|
|
139
|
+
| 72 | 预览/缩略图 | 小 |
|
|
140
|
+
| 150 | 标准阅读 (推荐) | 中等 |
|
|
141
|
+
| 300 | 高质量打印 | 大 |
|
|
142
|
+
|
|
143
|
+
### 步骤 3: 注册 Artifact
|
|
144
|
+
|
|
145
|
+
使用 Monoco CLI 注册产物:
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# 注册单个文件
|
|
149
|
+
monoco artifact register \
|
|
150
|
+
--file /path/to/page_001.webp \
|
|
151
|
+
--type image/webp \
|
|
152
|
+
--source-document original.docx \
|
|
153
|
+
--page 1
|
|
154
|
+
|
|
155
|
+
# 批量注册整个目录
|
|
156
|
+
monoco artifact register-batch \
|
|
157
|
+
--dir /path/to/webp/output \
|
|
158
|
+
--pattern "*.webp" \
|
|
159
|
+
--source-document original.docx
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
> **注意**: 如果 `monoco artifact` 命令不可用,使用 `monoco project` 或文件元数据记录产物信息。
|
|
163
|
+
|
|
164
|
+
## 辅助脚本
|
|
165
|
+
|
|
166
|
+
项目提供 `scripts/doc-to-webp.py` 脚本简化转换流程:
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# 完整转换流程
|
|
170
|
+
python scripts/doc-to-webp.py /path/to/document.docx --output ./artifacts --dpi 150
|
|
171
|
+
|
|
172
|
+
# 仅转换特定页面
|
|
173
|
+
python scripts/doc-to-webp.py document.docx --pages 1-5,10
|
|
174
|
+
|
|
175
|
+
# 保留中间 PDF
|
|
176
|
+
python scripts/doc-to-webp.py document.docx --keep-pdf
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## 异常处理
|
|
180
|
+
|
|
181
|
+
### 常见问题排查
|
|
182
|
+
|
|
183
|
+
#### 1. 字体缺失
|
|
184
|
+
|
|
185
|
+
**症状**: PDF 中文字显示为方块或乱码
|
|
186
|
+
|
|
187
|
+
**解决方案**:
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# macOS: 安装中文字体
|
|
191
|
+
brew install font-noto-cjk
|
|
192
|
+
|
|
193
|
+
# Linux: 安装文泉驿字体
|
|
194
|
+
sudo apt-get install fonts-wqy-zenhei
|
|
195
|
+
|
|
196
|
+
# 或使用 Docker 运行 (包含完整字体)
|
|
197
|
+
docker run --rm -v $(pwd):/docs \
|
|
198
|
+
linuxserver/libreoffice \
|
|
199
|
+
soffice --headless --convert-to pdf /docs/input.docx
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### 2. 转换锁死/超时
|
|
203
|
+
|
|
204
|
+
**症状**: soffice 进程无响应
|
|
205
|
+
|
|
206
|
+
**解决方案**:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# 设置超时
|
|
210
|
+
timeout 60 soffice --headless --convert-to pdf input.docx
|
|
211
|
+
|
|
212
|
+
# 检查并清理僵尸进程
|
|
213
|
+
pkill -9 soffice
|
|
214
|
+
pkill -9 soffice.bin
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
#### 3. PDF 渲染质量差
|
|
218
|
+
|
|
219
|
+
**症状**: WebP 图片模糊或有锯齿
|
|
220
|
+
|
|
221
|
+
**解决方案**:
|
|
222
|
+
|
|
223
|
+
- 提高 DPI (建议 150-300)
|
|
224
|
+
- 使用抗锯齿矩阵:
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
mat = fitz.Matrix(zoom, zoom).prerotate(0)
|
|
228
|
+
pix = page.get_pixmap(matrix=mat, alpha=False)
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### 4. 内存不足 (大文档)
|
|
232
|
+
|
|
233
|
+
**症状**: 处理大 PDF 时内存溢出
|
|
234
|
+
|
|
235
|
+
**解决方案**:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
# 逐页处理,及时释放内存
|
|
239
|
+
for page_num in range(len(doc)):
|
|
240
|
+
page = doc[page_num]
|
|
241
|
+
pix = page.get_pixmap(matrix=mat)
|
|
242
|
+
pix.save(f"page_{page_num}.webp")
|
|
243
|
+
pix = None # 显式释放
|
|
244
|
+
page = None
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Agent 执行模板
|
|
248
|
+
|
|
249
|
+
当用户要求处理文档时,按以下步骤执行:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
1. [探测] 检查 soffice 和 PyMuPDF 是否可用
|
|
253
|
+
└─ 如果缺失 → 提示用户安装并提供命令
|
|
254
|
+
|
|
255
|
+
2. [转换] Office → PDF
|
|
256
|
+
└─ 使用 soffice --headless --convert-to pdf
|
|
257
|
+
└─ 验证 PDF 生成成功
|
|
258
|
+
|
|
259
|
+
3. [渲染] PDF → WebP
|
|
260
|
+
└─ 使用 scripts/doc-to-webp.py 或内联代码
|
|
261
|
+
└─ 默认 150 DPI,可根据需求调整
|
|
262
|
+
|
|
263
|
+
4. [注册] 调用 monoco 注册 Artifact
|
|
264
|
+
└─ 记录 source-document 和 page 元数据
|
|
265
|
+
|
|
266
|
+
5. [汇报] 向用户展示:
|
|
267
|
+
- 生成的文件列表
|
|
268
|
+
- 文件大小统计
|
|
269
|
+
- 任何警告或错误
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## 最佳实践
|
|
273
|
+
|
|
274
|
+
1. **临时文件管理**: 使用 `tempfile.TemporaryDirectory` 管理中间文件
|
|
275
|
+
2. **错误重试**: 转换失败时自动重试 1-2 次
|
|
276
|
+
3. **并发控制**: 大文档处理时限制并发页面数
|
|
277
|
+
4. **元数据保留**: 始终记录原始文档名称和转换参数
|
|
278
|
+
5. **清理策略**: 转换完成后可选保留或删除中间 PDF
|
|
@@ -1,18 +1,29 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
from typing import Dict
|
|
3
|
-
from monoco.core.
|
|
3
|
+
from monoco.core.loader import FeatureModule, FeatureMetadata
|
|
4
|
+
from monoco.core.feature import IntegrationData
|
|
4
5
|
|
|
5
6
|
|
|
6
|
-
class GlossaryFeature(
|
|
7
|
-
|
|
8
|
-
def name(self) -> str:
|
|
9
|
-
return "glossary"
|
|
7
|
+
class GlossaryFeature(FeatureModule):
|
|
8
|
+
"""Glossary feature module with unified lifecycle support."""
|
|
10
9
|
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
@property
|
|
11
|
+
def metadata(self) -> FeatureMetadata:
|
|
12
|
+
return FeatureMetadata(
|
|
13
|
+
name="glossary",
|
|
14
|
+
version="1.0.0",
|
|
15
|
+
description="Terminology and glossary management",
|
|
16
|
+
dependencies=["core"],
|
|
17
|
+
priority=60,
|
|
18
|
+
lazy=True, # Can be lazy loaded - not critical for startup
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
def _on_mount(self, context: "FeatureContext") -> None: # type: ignore
|
|
22
|
+
"""Glossary does not require file initialization in the workspace."""
|
|
13
23
|
pass
|
|
14
24
|
|
|
15
25
|
def integrate(self, root: Path, config: Dict) -> IntegrationData:
|
|
26
|
+
"""Provide integration data for agent environment."""
|
|
16
27
|
# Determine language from config, default to 'en'
|
|
17
28
|
lang = config.get("i18n", {}).get("source_lang", "en")
|
|
18
29
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Git Hooks management feature for Monoco.
|
|
3
|
+
|
|
4
|
+
Provides distributed hooks architecture where each Feature can contribute
|
|
5
|
+
its own hooks in resources/hooks/, aggregated by this feature.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from .core import GitHooksManager, HookDeclaration, HookType
|
|
9
|
+
from .adapter import HooksFeature
|
|
10
|
+
|
|
11
|
+
__all__ = ["GitHooksManager", "HookDeclaration", "HookType", "HooksFeature"]
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Feature adapter for Git Hooks management.
|
|
3
|
+
|
|
4
|
+
Integrates with Monoco's feature loading system.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from pathlib import Path
|
|
8
|
+
from typing import Dict
|
|
9
|
+
|
|
10
|
+
from monoco.core.loader import FeatureModule, FeatureMetadata
|
|
11
|
+
from monoco.core.feature import IntegrationData
|
|
12
|
+
|
|
13
|
+
from .core import GitHooksManager, HookConfig
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class HooksFeature(FeatureModule):
|
|
17
|
+
"""Git Hooks management feature module."""
|
|
18
|
+
|
|
19
|
+
@property
|
|
20
|
+
def metadata(self) -> FeatureMetadata:
|
|
21
|
+
return FeatureMetadata(
|
|
22
|
+
name="hooks",
|
|
23
|
+
version="1.0.0",
|
|
24
|
+
description="Git hooks management for Monoco development workflow",
|
|
25
|
+
dependencies=["core"],
|
|
26
|
+
priority=5, # Load early to be available for other features
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
def _on_mount(self, context: "FeatureContext") -> None: # type: ignore
|
|
30
|
+
"""Initialize hooks feature with workspace context."""
|
|
31
|
+
# Hooks are installed on-demand via CLI commands
|
|
32
|
+
pass
|
|
33
|
+
|
|
34
|
+
def integrate(self, root: Path, config: Dict) -> IntegrationData:
|
|
35
|
+
"""Provide integration data for agent environment."""
|
|
36
|
+
# Read hooks-specific prompts if available
|
|
37
|
+
base_dir = Path(__file__).parent / "resources"
|
|
38
|
+
prompt_file = base_dir / "AGENTS.md"
|
|
39
|
+
|
|
40
|
+
content = ""
|
|
41
|
+
if prompt_file.exists():
|
|
42
|
+
content = prompt_file.read_text(encoding="utf-8").strip()
|
|
43
|
+
|
|
44
|
+
return IntegrationData(system_prompts={"Git Hooks": content})
|
|
45
|
+
|
|
46
|
+
def create_manager(self, project_root: Path, config: Dict) -> GitHooksManager:
|
|
47
|
+
"""
|
|
48
|
+
Create a GitHooksManager instance from configuration.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
project_root: Project root directory
|
|
52
|
+
config: Configuration dictionary (from workspace.yaml)
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Configured GitHooksManager instance
|
|
56
|
+
"""
|
|
57
|
+
hooks_config = config.get("hooks", {})
|
|
58
|
+
hook_config = HookConfig(
|
|
59
|
+
enabled=hooks_config.get("enabled", True),
|
|
60
|
+
enabled_features=hooks_config.get("features", {}),
|
|
61
|
+
enabled_hooks=hooks_config.get("hooks", {
|
|
62
|
+
"pre-commit": True,
|
|
63
|
+
"pre-push": False,
|
|
64
|
+
"post-checkout": False,
|
|
65
|
+
}),
|
|
66
|
+
)
|
|
67
|
+
return GitHooksManager(project_root, hook_config)
|