monoco-toolkit 0.3.5__py3-none-any.whl → 0.3.9__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/cli/workspace.py +1 -1
- monoco/core/config.py +51 -0
- monoco/core/hooks/__init__.py +19 -0
- monoco/core/hooks/base.py +104 -0
- monoco/core/hooks/builtin/__init__.py +11 -0
- monoco/core/hooks/builtin/git_cleanup.py +266 -0
- monoco/core/hooks/builtin/logging_hook.py +78 -0
- monoco/core/hooks/context.py +131 -0
- monoco/core/hooks/registry.py +222 -0
- monoco/core/integrations.py +6 -0
- monoco/core/registry.py +2 -0
- monoco/core/setup.py +1 -1
- monoco/core/skills.py +226 -42
- monoco/features/{scheduler → agent}/__init__.py +4 -2
- monoco/features/{scheduler → agent}/cli.py +134 -80
- monoco/features/{scheduler → agent}/config.py +17 -3
- monoco/features/agent/defaults.py +55 -0
- monoco/features/agent/flow_skills.py +281 -0
- monoco/features/{scheduler → agent}/manager.py +39 -2
- monoco/features/{scheduler → agent}/models.py +6 -3
- monoco/features/{scheduler → agent}/reliability.py +1 -1
- monoco/features/agent/resources/skills/flow_engineer/SKILL.md +94 -0
- monoco/features/agent/resources/skills/flow_manager/SKILL.md +88 -0
- monoco/features/agent/resources/skills/flow_reviewer/SKILL.md +114 -0
- monoco/features/{scheduler → agent}/session.py +39 -5
- monoco/features/{scheduler → agent}/worker.py +2 -2
- monoco/features/i18n/resources/skills/i18n_scan_workflow/SKILL.md +105 -0
- monoco/features/issue/commands.py +427 -21
- monoco/features/issue/core.py +104 -0
- monoco/features/issue/criticality.py +553 -0
- monoco/features/issue/domain/models.py +28 -2
- monoco/features/issue/engine/machine.py +65 -37
- monoco/features/issue/git_service.py +185 -0
- monoco/features/issue/linter.py +291 -62
- monoco/features/issue/models.py +91 -14
- monoco/features/issue/resources/en/SKILL.md +48 -0
- monoco/features/issue/resources/skills/issue_lifecycle_workflow/SKILL.md +159 -0
- monoco/features/issue/resources/zh/SKILL.md +50 -0
- monoco/features/issue/test_priority_integration.py +1 -0
- monoco/features/issue/validator.py +185 -65
- monoco/features/memo/__init__.py +4 -0
- monoco/features/memo/adapter.py +32 -0
- monoco/features/memo/cli.py +112 -0
- monoco/features/memo/core.py +146 -0
- monoco/features/memo/resources/skills/note_processing_workflow/SKILL.md +140 -0
- monoco/features/memo/resources/zh/AGENTS.md +8 -0
- monoco/features/memo/resources/zh/SKILL.md +75 -0
- monoco/features/spike/resources/skills/research_workflow/SKILL.md +121 -0
- monoco/main.py +6 -3
- {monoco_toolkit-0.3.5.dist-info → monoco_toolkit-0.3.9.dist-info}/METADATA +1 -1
- {monoco_toolkit-0.3.5.dist-info → monoco_toolkit-0.3.9.dist-info}/RECORD +56 -35
- monoco/features/scheduler/defaults.py +0 -54
- monoco/features/skills/__init__.py +0 -0
- monoco/features/skills/core.py +0 -102
- /monoco/core/{hooks.py → githooks.py} +0 -0
- /monoco/features/{scheduler → agent}/engines.py +0 -0
- {monoco_toolkit-0.3.5.dist-info → monoco_toolkit-0.3.9.dist-info}/WHEEL +0 -0
- {monoco_toolkit-0.3.5.dist-info → monoco_toolkit-0.3.9.dist-info}/entry_points.txt +0 -0
- {monoco_toolkit-0.3.5.dist-info → monoco_toolkit-0.3.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import typer
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Optional
|
|
4
|
+
from rich.console import Console
|
|
5
|
+
from rich.table import Table
|
|
6
|
+
from monoco.core.config import get_config
|
|
7
|
+
from .core import add_memo, list_memos, delete_memo, get_inbox_path, validate_content_language
|
|
8
|
+
|
|
9
|
+
app = typer.Typer(help="Manage memos (fleeting notes).")
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def get_issues_root(config=None) -> Path:
|
|
14
|
+
if config is None:
|
|
15
|
+
config = get_config()
|
|
16
|
+
# Resolve absolute path for issues
|
|
17
|
+
from monoco.core.config import find_monoco_root
|
|
18
|
+
|
|
19
|
+
project_root = find_monoco_root()
|
|
20
|
+
return project_root / config.paths.issues
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@app.command("add")
|
|
24
|
+
def add_command(
|
|
25
|
+
content: str = typer.Argument(..., help="The content of the memo."),
|
|
26
|
+
context: Optional[str] = typer.Option(
|
|
27
|
+
None, "--context", "-c", help="Context reference (e.g. file:line)."
|
|
28
|
+
),
|
|
29
|
+
force: bool = typer.Option(
|
|
30
|
+
False, "--force", "-f", help="Bypass i18n language validation."
|
|
31
|
+
),
|
|
32
|
+
):
|
|
33
|
+
"""
|
|
34
|
+
Capture a new idea or thought into the Memo Inbox.
|
|
35
|
+
"""
|
|
36
|
+
config = get_config()
|
|
37
|
+
issues_root = get_issues_root(config)
|
|
38
|
+
|
|
39
|
+
# Language Validation
|
|
40
|
+
source_lang = config.i18n.source_lang
|
|
41
|
+
if not force and not validate_content_language(content, source_lang):
|
|
42
|
+
console.print(
|
|
43
|
+
f"[red]Error: Content language mismatch.[/red] Content does not match configured source language: [bold]{source_lang}[/bold]."
|
|
44
|
+
)
|
|
45
|
+
console.print(
|
|
46
|
+
"[yellow]Tip: Use --force to bypass this check if you really want to add this content.[/yellow]"
|
|
47
|
+
)
|
|
48
|
+
raise typer.Exit(code=1)
|
|
49
|
+
|
|
50
|
+
uid = add_memo(issues_root, content, context)
|
|
51
|
+
|
|
52
|
+
console.print(f"[green]✔ Memo recorded.[/green] ID: [bold]{uid}[/bold]")
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
@app.command("list")
|
|
56
|
+
def list_command():
|
|
57
|
+
"""
|
|
58
|
+
List all memos in the inbox.
|
|
59
|
+
"""
|
|
60
|
+
issues_root = get_issues_root()
|
|
61
|
+
|
|
62
|
+
memos = list_memos(issues_root)
|
|
63
|
+
|
|
64
|
+
if not memos:
|
|
65
|
+
console.print("No memos found. Use `monoco memo add` to create one.")
|
|
66
|
+
return
|
|
67
|
+
|
|
68
|
+
table = Table(title="Memo Inbox")
|
|
69
|
+
table.add_column("ID", style="cyan", no_wrap=True)
|
|
70
|
+
table.add_column("Timestamp", style="magenta")
|
|
71
|
+
table.add_column("Content")
|
|
72
|
+
|
|
73
|
+
for memo in memos:
|
|
74
|
+
# Truncate content for list view
|
|
75
|
+
content_preview = memo["content"].split("\n")[0]
|
|
76
|
+
if len(memo["content"]) > 50:
|
|
77
|
+
content_preview = content_preview[:47] + "..."
|
|
78
|
+
|
|
79
|
+
table.add_row(memo["id"], memo["timestamp"], content_preview)
|
|
80
|
+
|
|
81
|
+
console.print(table)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@app.command("open")
|
|
85
|
+
def open_command():
|
|
86
|
+
"""
|
|
87
|
+
Open the inbox file in the default editor.
|
|
88
|
+
"""
|
|
89
|
+
issues_root = get_issues_root()
|
|
90
|
+
inbox_path = get_inbox_path(issues_root)
|
|
91
|
+
|
|
92
|
+
if not inbox_path.exists():
|
|
93
|
+
console.print("[yellow]Inbox does not exist yet.[/yellow]")
|
|
94
|
+
return
|
|
95
|
+
|
|
96
|
+
typer.launch(str(inbox_path))
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@app.command("delete")
|
|
100
|
+
def delete_command(
|
|
101
|
+
memo_id: str = typer.Argument(..., help="The ID of the memo to delete.")
|
|
102
|
+
):
|
|
103
|
+
"""
|
|
104
|
+
Delete a memo from the inbox by its ID.
|
|
105
|
+
"""
|
|
106
|
+
issues_root = get_issues_root()
|
|
107
|
+
|
|
108
|
+
if delete_memo(issues_root, memo_id):
|
|
109
|
+
console.print(f"[green]✔ Memo [bold]{memo_id}[/bold] deleted successfully.[/green]")
|
|
110
|
+
else:
|
|
111
|
+
console.print(f"[red]Error: Memo with ID [bold]{memo_id}[/bold] not found.[/red]")
|
|
112
|
+
raise typer.Exit(code=1)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from datetime import datetime
|
|
4
|
+
from typing import List, Dict, Optional
|
|
5
|
+
import secrets
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def is_chinese(text: str) -> bool:
|
|
9
|
+
"""Check if the text contains at least one Chinese character."""
|
|
10
|
+
return any("\u4e00" <= char <= "\u9fff" for char in text)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def validate_content_language(content: str, source_lang: str) -> bool:
|
|
14
|
+
"""
|
|
15
|
+
Check if content matches source language using simple heuristics.
|
|
16
|
+
Returns True if matched or if detection is not supported for the lang.
|
|
17
|
+
"""
|
|
18
|
+
if source_lang == "zh":
|
|
19
|
+
return is_chinese(content)
|
|
20
|
+
# For 'en', we generally allow everything but could be more strict.
|
|
21
|
+
# Requirement is mainly about enforcing 'zh' when configured.
|
|
22
|
+
return True
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def get_memos_dir(issues_root: Path) -> Path:
|
|
26
|
+
"""
|
|
27
|
+
Get the directory for memos.
|
|
28
|
+
Convention: Sibling of Issues directory.
|
|
29
|
+
"""
|
|
30
|
+
# issues_root is usually ".../Issues"
|
|
31
|
+
return issues_root.parent / "Memos"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def get_inbox_path(issues_root: Path) -> Path:
|
|
35
|
+
return get_memos_dir(issues_root) / "inbox.md"
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def generate_memo_id() -> str:
|
|
39
|
+
"""Generate a short 6-char ID."""
|
|
40
|
+
return secrets.token_hex(3)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def format_memo(uid: str, content: str, context: Optional[str] = None) -> str:
|
|
44
|
+
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
|
45
|
+
header = f"## [{uid}] {timestamp}"
|
|
46
|
+
|
|
47
|
+
body = content.strip()
|
|
48
|
+
|
|
49
|
+
if context:
|
|
50
|
+
body = f"> **Context**: `{context}`\n\n{body}"
|
|
51
|
+
|
|
52
|
+
return f"\n{header}\n{body}\n"
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def add_memo(issues_root: Path, content: str, context: Optional[str] = None) -> str:
|
|
56
|
+
"""
|
|
57
|
+
Append a memo to the inbox.
|
|
58
|
+
Returns the generated UID.
|
|
59
|
+
"""
|
|
60
|
+
inbox_path = get_inbox_path(issues_root)
|
|
61
|
+
|
|
62
|
+
if not inbox_path.exists():
|
|
63
|
+
inbox_path.parent.mkdir(parents=True, exist_ok=True)
|
|
64
|
+
inbox_path.write_text("# Monoco Memos Inbox\n", encoding="utf-8")
|
|
65
|
+
|
|
66
|
+
uid = generate_memo_id()
|
|
67
|
+
entry = format_memo(uid, content, context)
|
|
68
|
+
|
|
69
|
+
with inbox_path.open("a", encoding="utf-8") as f:
|
|
70
|
+
f.write(entry)
|
|
71
|
+
|
|
72
|
+
return uid
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def list_memos(issues_root: Path) -> List[Dict[str, str]]:
|
|
76
|
+
"""
|
|
77
|
+
Parse memos from inbox.
|
|
78
|
+
"""
|
|
79
|
+
inbox_path = get_inbox_path(issues_root)
|
|
80
|
+
if not inbox_path.exists():
|
|
81
|
+
return []
|
|
82
|
+
|
|
83
|
+
content = inbox_path.read_text(encoding="utf-8")
|
|
84
|
+
|
|
85
|
+
# Regex to find headers: ## [uid] timestamp
|
|
86
|
+
# We split by headers
|
|
87
|
+
|
|
88
|
+
pattern = re.compile(r"^## \[([a-f0-9]+)\] (.*?)$", re.MULTILINE)
|
|
89
|
+
|
|
90
|
+
memos = []
|
|
91
|
+
matches = list(pattern.finditer(content))
|
|
92
|
+
|
|
93
|
+
for i, match in enumerate(matches):
|
|
94
|
+
uid = match.group(1)
|
|
95
|
+
timestamp = match.group(2)
|
|
96
|
+
|
|
97
|
+
start = match.end()
|
|
98
|
+
end = matches[i + 1].start() if i + 1 < len(matches) else len(content)
|
|
99
|
+
|
|
100
|
+
body = content[start:end].strip()
|
|
101
|
+
|
|
102
|
+
memos.append({"id": uid, "timestamp": timestamp, "content": body})
|
|
103
|
+
|
|
104
|
+
return memos
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def delete_memo(issues_root: Path, memo_id: str) -> bool:
|
|
108
|
+
"""
|
|
109
|
+
Delete a memo by its ID.
|
|
110
|
+
Returns True if deleted, False if not found.
|
|
111
|
+
"""
|
|
112
|
+
inbox_path = get_inbox_path(issues_root)
|
|
113
|
+
if not inbox_path.exists():
|
|
114
|
+
return False
|
|
115
|
+
|
|
116
|
+
content = inbox_path.read_text(encoding="utf-8")
|
|
117
|
+
pattern = re.compile(r"^## \[([a-f0-9]+)\] (.*?)$", re.MULTILINE)
|
|
118
|
+
|
|
119
|
+
matches = list(pattern.finditer(content))
|
|
120
|
+
target_idx = -1
|
|
121
|
+
for i, m in enumerate(matches):
|
|
122
|
+
if m.group(1) == memo_id:
|
|
123
|
+
target_idx = i
|
|
124
|
+
break
|
|
125
|
+
|
|
126
|
+
if target_idx == -1:
|
|
127
|
+
return False
|
|
128
|
+
|
|
129
|
+
# Find boundaries
|
|
130
|
+
start = matches[target_idx].start()
|
|
131
|
+
# Include the potential newline before the header if it exists
|
|
132
|
+
if start > 0 and content[start - 1] == "\n":
|
|
133
|
+
start -= 1
|
|
134
|
+
|
|
135
|
+
if target_idx + 1 < len(matches):
|
|
136
|
+
end = matches[target_idx + 1].start()
|
|
137
|
+
# Back up if there's a newline before the next header that we should keep?
|
|
138
|
+
# Actually, if we delete a memo, we should probably remove one "entry block".
|
|
139
|
+
# Entry blocks are format_memo: \n## header\nbody\n
|
|
140
|
+
# So we want to remove the leading \n and the trailing parts.
|
|
141
|
+
else:
|
|
142
|
+
end = len(content)
|
|
143
|
+
|
|
144
|
+
new_content = content[:start] + content[end:]
|
|
145
|
+
inbox_path.write_text(new_content, encoding="utf-8")
|
|
146
|
+
return True
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: note-processing-workflow
|
|
3
|
+
description: Memo 笔记处理工作流 (Flow Skill)。定义从捕获 fleeting notes 到组织归档的标准操作流程,确保想法有效管理。
|
|
4
|
+
type: flow
|
|
5
|
+
domain: memo
|
|
6
|
+
version: 1.0.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Note Processing Workflow
|
|
10
|
+
|
|
11
|
+
Memo 笔记处理的标准化工作流,确保 "Capture → Process → Organize → Archive/Convert" 流程。
|
|
12
|
+
|
|
13
|
+
## 工作流状态机
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
stateDiagram-v2
|
|
17
|
+
[*] --> Capture: 想法闪现
|
|
18
|
+
|
|
19
|
+
Capture --> Process: 定期整理
|
|
20
|
+
Capture --> Capture: 继续记录
|
|
21
|
+
|
|
22
|
+
Process --> Organize: 分类完成
|
|
23
|
+
Process --> Archive: 无价值<br/>(直接归档)
|
|
24
|
+
|
|
25
|
+
Organize --> Convert: 可执行
|
|
26
|
+
Organize --> Organize: 需补充<br/>(完善信息)
|
|
27
|
+
Organize --> Archive: 纯参考<br/>(归档保存)
|
|
28
|
+
|
|
29
|
+
Convert --> [*]: 转为 Issue
|
|
30
|
+
|
|
31
|
+
Archive --> [*]: 归档完成
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 执行步骤
|
|
35
|
+
|
|
36
|
+
### 1. Capture (捕获)
|
|
37
|
+
|
|
38
|
+
- **目标**: 快速记录 fleeting ideas,不中断当前工作
|
|
39
|
+
- **输入**: 想法、灵感、代码片段、链接
|
|
40
|
+
- **输出**: Memo 记录
|
|
41
|
+
- **检查点**:
|
|
42
|
+
- [ ] 使用 `monoco memo add "内容"`
|
|
43
|
+
- [ ] 保持简洁,无需详细描述
|
|
44
|
+
- [ ] 添加上下文(`-c file:line` 如适用)
|
|
45
|
+
- [ ] 不中断当前任务流
|
|
46
|
+
|
|
47
|
+
### 2. Process (处理)
|
|
48
|
+
|
|
49
|
+
- **目标**: 定期回顾和分类 Memo
|
|
50
|
+
- **策略**: 定期整理(每日/每周)
|
|
51
|
+
- **检查点**:
|
|
52
|
+
- [ ] 运行 `monoco memo list` 查看所有 Memo
|
|
53
|
+
- [ ] 评估每个 Memo 的价值
|
|
54
|
+
- [ ] 分类:可执行 / 纯参考 / 无价值
|
|
55
|
+
- [ ] 补充缺失信息
|
|
56
|
+
|
|
57
|
+
### 3. Organize (组织)
|
|
58
|
+
|
|
59
|
+
- **目标**: 对有价值的 Memo 进行结构化整理
|
|
60
|
+
- **策略**: 根据类型选择处理方式
|
|
61
|
+
- **检查点**:
|
|
62
|
+
- [ ] 为相关 Memo 添加标签或分类
|
|
63
|
+
- [ ] 合并相似的 Memo
|
|
64
|
+
- [ ] 完善模糊的记录
|
|
65
|
+
- [ ] 设置优先级(如适用)
|
|
66
|
+
|
|
67
|
+
### 4. Archive/Convert (归档或转化)
|
|
68
|
+
|
|
69
|
+
- **目标**: 处理完毕的 Memo 归档或转化为 Issue
|
|
70
|
+
- **检查点**:
|
|
71
|
+
- [ ] **Convert**: 可执行的想法转为 Issue
|
|
72
|
+
- 使用 `monoco issue create feature/chore/fix -t "标题"`
|
|
73
|
+
- 在 Issue 中引用原始 Memo
|
|
74
|
+
- [ ] **Archive**: 纯参考内容归档保存
|
|
75
|
+
- 移动到知识库或文档
|
|
76
|
+
- 从 Memo 列表中移除
|
|
77
|
+
- [ ] **Delete**: 无价值的 Memo 直接删除
|
|
78
|
+
|
|
79
|
+
## 决策分支
|
|
80
|
+
|
|
81
|
+
| 条件 | 动作 |
|
|
82
|
+
|------|------|
|
|
83
|
+
| 想法可执行 | Convert,创建 Issue |
|
|
84
|
+
| 纯参考资料 | Archive,保存到知识库 |
|
|
85
|
+
| 无价值/过时 | Delete,直接删除 |
|
|
86
|
+
| 信息不完整 | 返回 Organize,补充信息 |
|
|
87
|
+
|
|
88
|
+
## 合规要求
|
|
89
|
+
|
|
90
|
+
- **必须**: Memo 是临时的,不应无限堆积
|
|
91
|
+
- **必须**: 可执行的想法必须转为 Issue 追踪
|
|
92
|
+
- **建议**: 定期处理(建议每周)
|
|
93
|
+
- **建议**: 保持 Memo 简洁,避免长篇大论
|
|
94
|
+
|
|
95
|
+
## 相关命令
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# 添加 Memo
|
|
99
|
+
monoco memo add "考虑使用 Redis 缓存用户会话"
|
|
100
|
+
|
|
101
|
+
# 带上下文的 Memo
|
|
102
|
+
monoco memo add "递归可能导致栈溢出" -c "src/utils.py:42"
|
|
103
|
+
|
|
104
|
+
# 查看所有 Memo
|
|
105
|
+
monoco memo list
|
|
106
|
+
|
|
107
|
+
# 编辑 Memo
|
|
108
|
+
monoco memo open
|
|
109
|
+
|
|
110
|
+
# 创建 Issue(转化 Memo)
|
|
111
|
+
monoco issue create feature -t "实现 Redis 缓存"
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 使用场景
|
|
115
|
+
|
|
116
|
+
| 场景 | 使用 Memo | 后续处理 |
|
|
117
|
+
|------|-----------|----------|
|
|
118
|
+
| 代码审查时的改进建议 | `memo add "重构建议: ..."` | Process → Convert to Issue |
|
|
119
|
+
| 会议中的临时想法 | `memo add "想法: ..."` | Process → Organize → Convert |
|
|
120
|
+
| 有用的代码片段 | `memo add "Snippet: ..."` | Process → Archive to 知识库 |
|
|
121
|
+
| 技术文章链接 | `memo add "Read: https://..."` | Process → Archive |
|
|
122
|
+
| Bug 线索 | `memo add "可能的 Bug: ..."` | Process → Convert to Fix Issue |
|
|
123
|
+
|
|
124
|
+
## 与 Issue 的区别
|
|
125
|
+
|
|
126
|
+
| 维度 | Memo | Issue |
|
|
127
|
+
|------|------|-------|
|
|
128
|
+
| 目的 | 记录想法 | 追踪任务 |
|
|
129
|
+
| 生命周期 | 临时,需定期清理 | 正式,完整生命周期 |
|
|
130
|
+
| 完成标准 | 归档或转化 | 验收标准通过 |
|
|
131
|
+
| 复杂度 | 简单,一句话 | 详细,有 AC 和 Tasks |
|
|
132
|
+
| 追踪 | 无 | 完整追踪 |
|
|
133
|
+
|
|
134
|
+
## 最佳实践
|
|
135
|
+
|
|
136
|
+
1. **及时记录**: 想法闪现时立即记录,避免遗忘
|
|
137
|
+
2. **定期整理**: 每周至少处理一次 Memo 列表
|
|
138
|
+
3. **快速转化**: 有价值的想法尽快转为 Issue
|
|
139
|
+
4. **果断删除**: 过时或无价值的 Memo 果断删除
|
|
140
|
+
5. **保持简洁**: Memo 是速记,不需要详细描述
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
### Memo (Fleeting Notes)
|
|
2
|
+
|
|
3
|
+
Lightweight note-taking for ideas and quick thoughts.
|
|
4
|
+
|
|
5
|
+
- **Add**: `monoco memo add "Content" [-c context]`
|
|
6
|
+
- **List**: `monoco memo list`
|
|
7
|
+
- **Open**: `monoco memo open` (Edit in default editor)
|
|
8
|
+
- **Guideline**: Use Memos for ideas; use Issues for actionable tasks.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: monoco-memo
|
|
3
|
+
description: 轻量级备忘录系统,用于快速记录想法、灵感和临时笔记。与正式的 Issue 系统区分开来。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Monoco Memo (备忘录)
|
|
7
|
+
|
|
8
|
+
使用此技能快速捕捉 fleeting notes( fleeting 想法),无需创建正式的 Issue。
|
|
9
|
+
|
|
10
|
+
## 何时使用 Memo vs Issue
|
|
11
|
+
|
|
12
|
+
| 场景 | 使用 | 原因 |
|
|
13
|
+
|------|------|------|
|
|
14
|
+
| 临时想法、灵感 | **Memo** | 不需要追踪、不需要完成状态 |
|
|
15
|
+
| 代码片段、链接收藏 | **Memo** | 快速记录,后续整理 |
|
|
16
|
+
| 会议速记 | **Memo** | 先记录,再提炼成任务 |
|
|
17
|
+
| 可执行的工作单元 | **Issue** | 需要追踪、验收标准、生命周期 |
|
|
18
|
+
| Bug 修复 | **Issue** | 需要记录复现步骤、验证结果 |
|
|
19
|
+
| 功能开发 | **Issue** | 需要设计、分解、交付 |
|
|
20
|
+
|
|
21
|
+
> **核心原则**: Memos 记录**想法**;Issues 处理**可执行任务**。
|
|
22
|
+
|
|
23
|
+
## 命令
|
|
24
|
+
|
|
25
|
+
### 添加备忘录
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
monoco memo add "你的备忘录内容"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
可选参数:
|
|
32
|
+
- `-c, --context`: 添加上下文引用(如 `file:line`)
|
|
33
|
+
|
|
34
|
+
示例:
|
|
35
|
+
```bash
|
|
36
|
+
# 简单记录
|
|
37
|
+
monoco memo add "考虑使用 Redis 缓存用户会话"
|
|
38
|
+
|
|
39
|
+
# 带上下文的记录
|
|
40
|
+
monoco memo add "这里的递归可能导致栈溢出" -c "src/utils.py:42"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### 查看备忘录列表
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
monoco memo list
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
显示所有未归档的备忘录。
|
|
50
|
+
|
|
51
|
+
### 打开备忘录文件
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
monoco memo open
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
在默认编辑器中打开备忘录文件,用于整理或批量编辑。
|
|
58
|
+
|
|
59
|
+
## 工作流程
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
想法闪现 → monoco memo add "..." → 定期整理 → 提炼成 Issue 或归档
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
1. **捕捉**: 有想法时立即使用 `monoco memo add` 记录
|
|
66
|
+
2. **整理**: 定期(如每日/每周)运行 `monoco memo list` 回顾
|
|
67
|
+
3. **转化**: 将有价值的备忘录转化为正式的 Issue
|
|
68
|
+
4. **归档**: 处理完毕后从备忘录中移除
|
|
69
|
+
|
|
70
|
+
## 最佳实践
|
|
71
|
+
|
|
72
|
+
1. **保持简洁**: Memo 是速记,不需要详细描述
|
|
73
|
+
2. **及时转化**: 有价值的想法应尽快转为 Issue,避免遗忘
|
|
74
|
+
3. **定期清理**: Memos 是临时的,不要让它们无限堆积
|
|
75
|
+
4. **使用上下文**: 记录代码相关想法时,使用 `-c` 参数标注位置
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: research-workflow
|
|
3
|
+
description: Spike 研究工作流 (Flow Skill)。定义从添加外部仓库到知识提取和归档的标准操作流程,确保外部知识有效管理。
|
|
4
|
+
type: flow
|
|
5
|
+
domain: spike
|
|
6
|
+
version: 1.0.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Research Workflow
|
|
10
|
+
|
|
11
|
+
Spike 研究的标准化工作流,确保 "Add → Sync → Analyze → Extract → Archive" 流程。
|
|
12
|
+
|
|
13
|
+
## 工作流状态机
|
|
14
|
+
|
|
15
|
+
```mermaid
|
|
16
|
+
stateDiagram-v2
|
|
17
|
+
[*] --> Add: 发现参考仓库
|
|
18
|
+
|
|
19
|
+
Add --> Sync: 添加配置
|
|
20
|
+
Add --> Add: URL 无效<br/>(重新输入)
|
|
21
|
+
|
|
22
|
+
Sync --> Analyze: 同步完成
|
|
23
|
+
Sync --> Sync: 同步失败<br/>(网络/权限)
|
|
24
|
+
|
|
25
|
+
Analyze --> Extract: 分析完成
|
|
26
|
+
Analyze --> Analyze: 内容不符<br/>(重新评估)
|
|
27
|
+
|
|
28
|
+
Extract --> Archive: 知识提取完成
|
|
29
|
+
|
|
30
|
+
Archive --> [*]: 归档完成
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 执行步骤
|
|
34
|
+
|
|
35
|
+
### 1. Add (添加仓库)
|
|
36
|
+
|
|
37
|
+
- **目标**: 将外部仓库添加为参考
|
|
38
|
+
- **输入**: 仓库 URL、参考目的
|
|
39
|
+
- **输出**: 配置更新
|
|
40
|
+
- **检查点**:
|
|
41
|
+
- [ ] 验证仓库 URL 可访问
|
|
42
|
+
- [ ] 确认仓库与当前项目相关
|
|
43
|
+
- [ ] 运行 `monoco spike add <url>`
|
|
44
|
+
- [ ] 检查 `.monoco/config.yaml` 已更新
|
|
45
|
+
|
|
46
|
+
### 2. Sync (同步)
|
|
47
|
+
|
|
48
|
+
- **目标**: 下载或更新参考仓库内容
|
|
49
|
+
- **检查点**:
|
|
50
|
+
- [ ] 运行 `monoco spike sync`
|
|
51
|
+
- [ ] 验证仓库克隆到 `.references/<name>/`
|
|
52
|
+
- [ ] 检查同步日志,确认无错误
|
|
53
|
+
- [ ] 验证文件权限正确(只读)
|
|
54
|
+
|
|
55
|
+
### 3. Analyze (分析)
|
|
56
|
+
|
|
57
|
+
- **目标**: 研究参考仓库的结构和内容
|
|
58
|
+
- **策略**: 系统性浏览和标记
|
|
59
|
+
- **检查点**:
|
|
60
|
+
- [ ] 浏览仓库整体结构
|
|
61
|
+
- [ ] 识别与当前项目相关的模块
|
|
62
|
+
- [ ] 标记有价值的代码模式
|
|
63
|
+
- [ ] 记录架构设计亮点
|
|
64
|
+
|
|
65
|
+
### 4. Extract (提取知识)
|
|
66
|
+
|
|
67
|
+
- **目标**: 从参考仓库提取可用知识
|
|
68
|
+
- **策略**: 文档化有价值的发现
|
|
69
|
+
- **检查点**:
|
|
70
|
+
- [ ] 提取关键代码片段(不修改原文件)
|
|
71
|
+
- [ ] 记录设计模式和最佳实践
|
|
72
|
+
- [ ] 创建学习笔记(使用 Memo 或 Issue)
|
|
73
|
+
- [ ] 标注知识来源(仓库 URL + Commit)
|
|
74
|
+
|
|
75
|
+
### 5. Archive (归档)
|
|
76
|
+
|
|
77
|
+
- **目标**: 整理和归档研究成果
|
|
78
|
+
- **检查点**:
|
|
79
|
+
- [ ] 更新项目文档,引用参考仓库
|
|
80
|
+
- [ ] 创建知识索引(如需要)
|
|
81
|
+
- [ ] 运行 `monoco spike list` 验证状态
|
|
82
|
+
- [ ] 定期清理不再需要的参考
|
|
83
|
+
|
|
84
|
+
## 决策分支
|
|
85
|
+
|
|
86
|
+
| 条件 | 动作 |
|
|
87
|
+
|------|------|
|
|
88
|
+
| URL 无效 | 返回 Add,检查 URL 格式 |
|
|
89
|
+
| 同步失败 | 检查网络、权限,重试或跳过 |
|
|
90
|
+
| 内容不相关 | 从配置中移除,重新选择 |
|
|
91
|
+
| 发现重要模式 | 创建 Issue,计划引入项目 |
|
|
92
|
+
|
|
93
|
+
## 合规要求
|
|
94
|
+
|
|
95
|
+
- **禁止**: 编辑 `.references/` 中的任何文件
|
|
96
|
+
- **必须**: 所有外部知识必须标注来源
|
|
97
|
+
- **必须**: 定期同步以获取更新
|
|
98
|
+
- **建议**: 只添加高质量、相关的仓库
|
|
99
|
+
|
|
100
|
+
## 相关命令
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
# 添加参考仓库
|
|
104
|
+
monoco spike add <url>
|
|
105
|
+
|
|
106
|
+
# 同步所有仓库
|
|
107
|
+
monoco spike sync
|
|
108
|
+
|
|
109
|
+
# 列出已配置的仓库
|
|
110
|
+
monoco spike list
|
|
111
|
+
|
|
112
|
+
# 记录研究发现
|
|
113
|
+
monoco memo add "发现: {insight}" -c "spike:{repo_name}"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## 最佳实践
|
|
117
|
+
|
|
118
|
+
1. **精选选择**: 只添加与项目高度相关的仓库
|
|
119
|
+
2. **只读访问**: 将 `.references/` 视为外部知识库,永不修改
|
|
120
|
+
3. **定期同步**: 每月运行 `monoco spike sync` 获取更新
|
|
121
|
+
4. **知识转化**: 将学到的模式转化为项目的实际改进
|
monoco/main.py
CHANGED
|
@@ -166,10 +166,13 @@ app.add_typer(config_cmd.app, name="config", help="Manage configuration")
|
|
|
166
166
|
app.add_typer(project_cmd.app, name="project", help="Manage projects")
|
|
167
167
|
app.add_typer(workspace_cmd.app, name="workspace", help="Manage workspace")
|
|
168
168
|
|
|
169
|
-
from monoco.features.
|
|
169
|
+
from monoco.features.agent import cli as scheduler_cmd
|
|
170
170
|
|
|
171
|
-
app.add_typer(scheduler_cmd.app, name="agent", help="Manage agent sessions")
|
|
172
|
-
|
|
171
|
+
app.add_typer(scheduler_cmd.app, name="agent", help="Manage agent sessions and roles")
|
|
172
|
+
|
|
173
|
+
from monoco.features.memo import app as memo_app
|
|
174
|
+
|
|
175
|
+
app.add_typer(memo_app, name="memo", help="Manage fleeting notes (memos)")
|
|
173
176
|
|
|
174
177
|
|
|
175
178
|
from monoco.daemon.commands import serve
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: monoco-toolkit
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.9
|
|
4
4
|
Summary: Agent Native Toolkit for Monoco - Task Management & Kanban for AI Agents
|
|
5
5
|
Project-URL: Homepage, https://monoco.io
|
|
6
6
|
Project-URL: Repository, https://github.com/IndenScale/Monoco
|