TevinClaw
12 hours ago 0f9deaa16bfd125a55283b2750d1586606a01532
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
#!/usr/bin/env python3
"""
memory-md-hot 每日维护脚本
维护 memory.md 文件的事件流水和重要事件
保留所有历史记录,需配合 memory-md-archive 技能归档
"""
 
import os
import re
import sys
from datetime import datetime
from pathlib import Path
 
# 配置
MEMORY_FILE = Path.home() / ".openclaw" / "workspace" / "MEMORY.md"
ARCHIVE_THRESHOLD_KB = 50  # 建议归档的阈值(仅提示,不强制)
 
 
def read_memory_file():
    """读取 memory.md 文件内容"""
    if not MEMORY_FILE.exists():
        return ""
    return MEMORY_FILE.read_text(encoding='utf-8')
 
 
def write_memory_file(content):
    """写入 memory.md 文件"""
    MEMORY_FILE.parent.mkdir(parents=True, exist_ok=True)
    MEMORY_FILE.write_text(content, encoding='utf-8')
 
 
def get_file_size():
    """获取文件大小(字节)"""
    if not MEMORY_FILE.exists():
        return 0
    return MEMORY_FILE.stat().st_size
 
 
def parse_date_from_line(line):
    """从行中提取日期(YYYY-MM-DD 格式)"""
    match = re.search(r'(\d{4}-\d{2}-\d{2})', line)
    if match:
        try:
            return datetime.strptime(match.group(1), '%Y-%m-%d').date()
        except ValueError:
            return None
    return None
 
 
def extract_event_entries(content):
    """
    从内容中提取事件条目
    返回: (important_events, daily_events) 元组
    """
    important_events = []
    daily_events = []
    
    lines = content.split('\n')
    in_important = False
    in_daily = False
    
    for line in lines:
        stripped = line.strip()
        
        # 检测区块
        if '重要事件' in stripped and stripped.startswith('#'):
            in_important = True
            in_daily = False
            continue
        elif ('事件流水' in stripped) and stripped.startswith('#'):
            in_important = False
            in_daily = True
            continue
        elif stripped.startswith('#') and in_important:
            in_important = False
        elif stripped.startswith('#') and in_daily:
            in_daily = False
            
        # 收集事件
        if in_important and stripped.startswith('-'):
            if len(stripped) > 10:  # 过滤空行和短行
                important_events.append(line)
        elif in_daily and (stripped.startswith('-') or stripped.startswith('*')):
            daily_events.append(line)
    
    return important_events, daily_events
 
 
def generate_default_content():
    """生成默认的 memory.md 内容"""
    today = datetime.now().strftime('%Y-%m-%d')
    return f"""# MEMORY.md - 热记忆 / 活跃记忆
 
> 本文件记录近期发生的重要事情,详细信息可通过记忆检索获取。
 
---
 
## 🔔 重要事件
 
> 记录具有全局长期性影响的重要决策和事件。
> 添加重要事件时会告知用户。
 
<!-- 重要事件在此添加 -->
 
---
 
## 📅 事件流水
 
> 按天分组,每天主要事情的概要。
> 所有记录永久保留,可使用 memory-md-archive 技能归档瘦身。
 
### {{today}}
 
- {today} 10:00 | memory.md 初始化 | 热记忆系统
 
---
 
*文件大小: ~0.5KB | 事件数: 1*
*维护脚本: `memory-md-hot/scripts/daily_maintenance.py`*
*归档提示: 文件较大时请使用 memory-md-archive 技能归档*
""".format(today=today)
 
 
def update_memory_file(new_daily_events=None, important_event=None):
    """
    更新 memory.md 文件
    
    Args:
        new_daily_events: 新的每日事件列表 [(date, time, summary, keywords), ...]
        important_event: 重要事件元组 (date, time, summary, keywords) 或 None
    
    Returns:
        dict: 操作结果
    """
    result = {
        'success': True,
        'added_daily': 0,
        'added_important': False,
        'current_size_kb': 0,
        'total_events': 0,
        'archive_suggested': False,
        'messages': []
    }
    
    # 读取现有内容
    content = read_memory_file()
    if not content:
        content = generate_default_content()
    
    # 提取现有事件
    existing_important, existing_daily = extract_event_entries(content)
    
    # 保留所有现有日常事件(不再移除旧记录)
    all_daily = list(existing_daily)
    
    # 添加新的日常事件
    if new_daily_events:
        for event in new_daily_events:
            date, time, summary, keywords = event
            entry = f"- {date} {time} | {summary} | {keywords}"
            # 检查是否已存在
            if not any(entry.strip() in existing.strip() for existing in all_daily):
                all_daily.append(entry)
                result['added_daily'] += 1
    
    # 添加重要事件
    new_important = list(existing_important)
    if important_event:
        date, time, summary, keywords = important_event
        entry = f"- {date} {time} | {summary} | {keywords}"
        new_important.append(entry)
        result['added_important'] = True
        result['messages'].append(f"重要事件已记录: {summary}")
    
    # 重新构建文件内容
    today = datetime.now().strftime('%Y-%m-%d')
    
    # 按日期分组日常事件
    daily_by_date = {}
    for line in all_daily:
        date = parse_date_from_line(line)
        if date:
            date_str = date.strftime('%Y-%m-%d')
            if date_str not in daily_by_date:
                daily_by_date[date_str] = []
            daily_by_date[date_str].append(line)
    
    # 构建日常事件区块
    daily_sections = []
    for date_str in sorted(daily_by_date.keys(), reverse=True):
        daily_sections.append(f"\n### {date_str}\n")
        daily_sections.extend([f"{line}\n" for line in daily_by_date[date_str]])
    
    daily_content = ''.join(daily_sections) if daily_sections else f"\n### {today}\n\n- {today} --:-- | 暂无记录 | --\n"
    
    # 构建重要事件区块
    important_content = '\n'.join(new_important) if new_important else "<!-- 重要事件在此添加 -->"
    
    # 计算统计
    total_events = len(all_daily) + len(new_important)
    result['total_events'] = total_events
    
    # 组装最终内容
    current_size = get_file_size()
    result['current_size_kb'] = round(current_size / 1024, 2)
    
    new_content = f"""# MEMORY.md - 热记忆 / 活跃记忆
 
> 本文件记录近期发生的重要事情,详细信息可通过记忆检索获取。
 
---
 
## 🔔 重要事件
 
> 记录具有全局长期性影响的重要决策和事件。
> 添加重要事件时会告知用户。
 
{important_content}
 
---
 
## 📅 事件流水
 
> 按天分组,每天主要事情的概要。
> 所有记录永久保留,可使用 memory-md-archive 技能归档瘦身。
{daily_content}
---
 
*文件大小: ~{result['current_size_kb']:.1f}KB | 事件数: {total_events}*
*维护脚本: `memory-md-hot/scripts/daily_maintenance.py`*
*归档提示: 文件较大时请使用 memory-md-archive 技能归档*
"""
    
    # 写入文件
    write_memory_file(new_content)
    
    # 检查是否需要建议归档
    new_size = get_file_size()
    result['current_size_kb'] = round(new_size / 1024, 2)
    
    if result['current_size_kb'] > ARCHIVE_THRESHOLD_KB:
        result['archive_suggested'] = True
        result['messages'].append(f"提示: 文件大小 ({result['current_size_kb']}KB) 超过 {ARCHIVE_THRESHOLD_KB}KB,建议使用 memory-md-archive 技能归档")
    
    return result
 
 
def get_stats():
    """获取文件统计信息"""
    content = read_memory_file()
    if not content:
        return {
            'size_bytes': 0,
            'size_kb': 0,
            'total_events': 0,
            'important_events': 0,
            'daily_events': 0,
            'archive_suggested': False
        }
    
    important, daily = extract_event_entries(content)
    size = get_file_size()
    size_kb = round(size / 1024, 2)
    
    return {
        'size_bytes': size,
        'size_kb': size_kb,
        'total_events': len(important) + len(daily),
        'important_events': len(important),
        'daily_events': len(daily),
        'archive_suggested': size_kb > ARCHIVE_THRESHOLD_KB
    }
 
 
def main():
    """主函数 - 供命令行调用"""
    if len(sys.argv) < 2:
        print("用法: python daily_maintenance.py <command> [args]")
        print("")
        print("命令:")
        print("  update                     - 执行每日更新")
        print("  stats                      - 查看文件统计")
        print("  add-daily <date> <time> <summary> <keywords>")
        print("                             - 添加日常事件")
        print("  add-important <date> <time> <summary> <keywords>")
        print("                             - 添加重要事件")
        print("")
        print("示例:")
        print('  python daily_maintenance.py add-daily 2026-03-16 "10:30" "测试脚本" "开发,测试"')
        sys.exit(1)
    
    command = sys.argv[1]
    
    if command == "update":
        result = update_memory_file()
        print(f"更新完成:")
        print(f"  - 添加日常事件: {result['added_daily']}")
        print(f"  - 添加重要事件: {'是' if result['added_important'] else '否'}")
        print(f"  - 当前大小: {result['current_size_kb']}KB")
        print(f"  - 总事件数: {result['total_events']}")
        for msg in result['messages']:
            print(f"  - {msg}")
    
    elif command == "stats":
        stats = get_stats()
        print(f"文件统计:")
        print(f"  - 文件大小: {stats['size_kb']}KB ({stats['size_bytes']} 字节)")
        print(f"  - 总事件数: {stats['total_events']}")
        print(f"  - 重要事件: {stats['important_events']}")
        print(f"  - 日常事件: {stats['daily_events']}")
        if stats['archive_suggested']:
            print(f"  - 归档建议: 文件较大,建议使用 memory-md-archive 技能归档")
        else:
            print(f"  - 归档建议: 暂无需要")
    
    elif command == "add-daily" and len(sys.argv) >= 6:
        event = (sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
        result = update_memory_file(new_daily_events=[event])
        print(f"已添加日常事件: {event}")
        if result['archive_suggested']:
            print(f"提示: 文件大小 {result['current_size_kb']}KB,建议归档")
    
    elif command == "add-important" and len(sys.argv) >= 6:
        event = (sys.argv[2], sys.argv[3], sys.argv[4], sys.argv[5])
        result = update_memory_file(important_event=event)
        print(f"已添加重要事件: {event}")
        print(f"ℹ️ 请知悉用户: 已记录重要事件 '{sys.argv[4]}'")
        if result['archive_suggested']:
            print(f"提示: 文件大小 {result['current_size_kb']}KB,建议归档")
    
    else:
        print(f"未知命令或参数不足: {command}")
        sys.exit(1)
 
 
if __name__ == "__main__":
    main()