Files
2026-06-06 10:40:48 +08:00

211 lines
6.5 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# memory-sync — 记忆同步与维护工具
#
# 从 Hermes Agent MemoryManager + MemoryStore 模式内化
# 管理 memory/index.md -> 键值对索引
# 管理 memory/projects/ -> 项目级记忆
#
# 用法:
# bash scripts/memory-sync.sh index # 重建记忆索引
# bash scripts/memory-sync.sh check # 检查记忆健康状况
# bash scripts/memory-sync.sh prefetch <key> # 根据关键词召回相关记忆
# bash scripts/memory-sync.sh backup # 备份所有记忆文件
set -euo pipefail
WORKSPACE="$(cd "$(dirname "$0")/.." && pwd)"
MEMORY_DIR="$WORKSPACE/memory"
PROJECTS_DIR="$MEMORY_DIR/projects"
INDEX_FILE="$MEMORY_DIR/index.md"
# ── 颜色 ──
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
case "${1:-}" in
index)
echo "🔨 重建记忆索引..."
# 清空并重建索引
cat > "$INDEX_FILE" << 'EOF'
# 记忆索引
> 自动生成,供 Fast-Path 快速查找。
> 格式:`关键词 | 所在文件 | 摘要`
EOF
# 索引 MEMORY.md 中的关键段落
echo "" >> "$INDEX_FILE"
echo "## MEMORY.md" >> "$INDEX_FILE"
# 提取各章节标题
while IFS= read -r line; do
if echo "$line" | grep -qE '^### '; then
title=$(echo "$line" | sed 's/^### //')
echo "- $title | MEMORY.md | 章节" >> "$INDEX_FILE"
fi
done < "$WORKSPACE/MEMORY.md"
# 索引项目记忆
echo "" >> "$INDEX_FILE"
echo "## 项目记忆" >> "$INDEX_FILE"
for f in "$PROJECTS_DIR"/*.md; do
[ -f "$f" ] || continue
name=$(basename "$f" .md)
echo "- $name | memory/projects/$name.md | 项目记忆" >> "$INDEX_FILE"
# 提取项目中的关键标签
while IFS= read -r line; do
if echo "$line" | grep -qE '^\| .+ \| .+ \|'; then
echo " - $(echo "$line" | awk -F'|' '{print $2}' | xargs)" >> "$INDEX_FILE"
fi
done < "$f"
done
# 索引 daily 日志
echo "" >> "$INDEX_FILE"
echo "## 日常日志" >> "$INDEX_FILE"
for f in "$MEMORY_DIR/daily"/*.md; do
[ -f "$f" ] || continue
name=$(basename "$f" .md)
# 读取第一行非空标题
title=$(head -3 "$f" | grep -E '^# ' | sed 's/^# //' || echo "$name")
echo "- $title | memory/daily/$name" >> "$INDEX_FILE"
done
echo -e "${GREEN}✅ 索引重建完成:$INDEX_FILE${NC}"
wc -l < "$INDEX_FILE" | xargs echo " $(( $(wc -l < "$INDEX_FILE") - 4 )) 条索引条目"
;;
check)
echo "🔍 记忆健康检查 (Hermes 风格)"
echo ""
# 1. 检查索引是否存在
if [ -f "$INDEX_FILE" ]; then
echo -e " ${GREEN}✅ 索引文件存在${NC}"
echo " $(grep -c '^-' "$INDEX_FILE") 条可用索引"
else
echo -e " ${YELLOW}⚠️ 索引文件缺失,运行 memory-sync.sh index 创建${NC}"
fi
# 2. MEMORY.md 大小检查
SIZE=$(wc -c < "$WORKSPACE/MEMORY.md")
if [ "$SIZE" -gt 10000 ]; then
echo -e " ${YELLOW}⚠️ MEMORY.md 较大: ${SIZE} 字节 (>10K),建议精简${NC}"
else
echo -e " ${GREEN}✅ MEMORY.md: ${SIZE} 字节${NC}"
fi
# 3. 项目记忆数量
PCOUNT=$(find "$PROJECTS_DIR" -name '*.md' 2>/dev/null | wc -l | tr -d ' ')
echo -e " ${GREEN}✅ 项目记忆: ${PCOUNT}${NC}"
# 4. 最近的 daily 记录
LATEST=$(ls -t "$MEMORY_DIR/daily/" 2>/dev/null | head -1)
if [ -n "$LATEST" ]; then
echo -e " ${GREEN}✅ 最近 daily: $LATEST${NC}"
fi
# 5. git 状态
cd "$WORKSPACE"
if [ -n "$(git status --short 2>/dev/null)" ]; then
echo -e " ${YELLOW}⚠️ 有未提交的记忆更改${NC}"
else
echo -e " ${GREEN}✅ 所有记忆更改已提交${NC}"
fi
;;
prefetch)
KEY="${2:-}"
if [ -z "$KEY" ]; then
echo "用法: bash scripts/memory-sync.sh prefetch <关键词>"
echo "示例: bash scripts/memory-sync.sh prefetch hermes"
exit 1
fi
echo "🔎 预取记忆:$KEY"
echo ""
# 1. 查索引
if [ -f "$INDEX_FILE" ]; then
MATCHES=$(grep -i "$KEY" "$INDEX_FILE" | head -10)
if [ -n "$MATCHES" ]; then
echo "📋 索引匹配:"
echo "$MATCHES"
echo ""
fi
fi
# 2. 查项目记忆
for f in "$PROJECTS_DIR"/*.md; do
[ -f "$f" ] || continue
if grep -qi "$KEY" "$f"; then
name=$(basename "$f" .md)
echo "📂 项目记忆匹配:$name"
grep -i "$KEY" "$f" | head -5
echo ""
fi
done
# 3. 查 MEMORY.md
if grep -qi "$KEY" "$WORKSPACE/MEMORY.md"; then
echo "📄 MEMORY.md 匹配:"
grep -i "$KEY" "$WORKSPACE/MEMORY.md" | head -5
fi
;;
backup)
BACKUP_DIR="$WORKSPACE/.memory-backup-$(date '+%Y%m%d-%H%M%S')"
echo "💾 备份记忆文件到 $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
cp "$WORKSPACE/MEMORY.md" "$BACKUP_DIR/" 2>/dev/null || true
cp -r "$MEMORY_DIR" "$BACKUP_DIR/" 2>/dev/null || true
echo -e "${GREEN}✅ 备份完成${NC}"
;;
compact)
echo "🧹 检查 MEMORY.md 是否需要压缩..."
LINES=$(wc -l < "$WORKSPACE/MEMORY.md")
CHARS=$(wc -c < "$WORKSPACE/MEMORY.md")
echo " 当前: ${LINES} 行 / ${CHARS} 字节"
if [ "$LINES" -gt 200 ] || [ "$CHARS" -gt 10000 ]; then
echo -e " ${YELLOW}⚠️ 需要压缩(超限)${NC}"
echo " 压缩策略:"
echo " 1. 低优先级条目(环境事实)→ 移至 daily/ 存档"
echo " 2. 同类条目合并为一条"
echo " 3. 已固化的技能从 MEMORY.md 移入 tools/"
else
echo -e " ${GREEN}✅ 大小正常${NC}"
fi
;;
stats)
echo "📊 记忆仓使用统计"
echo ""
for f in "$WORKSPACE/MEMORY.md" "$MEMORY_DIR/USER.md" "$MEMORY_DIR/index.md"; do
if [ -f "$f" ]; then
L=$(wc -l < "$f")
C=$(wc -c < "$f")
echo " $(basename "$f"): ${L} 行 / ${C} 字节"
fi
done
echo ""
echo " daily/$(ls "$MEMORY_DIR/daily/" 2>/dev/null | wc -l) 个文件"
echo " projects/$(ls "$MEMORY_DIR/projects/" 2>/dev/null | wc -l) 个文件"
;;
*)
echo "用法: bash scripts/memory-sync.sh <子命令>"
echo ""
echo " index 重建记忆索引"
echo " check 检查记忆健康状况"
echo " prefetch <k> 根据关键词召回相关记忆"
echo " backup 备份所有记忆文件"
echo " compact 压缩 MEMORY.md(溢出时合并同类条目)"
echo " stats 统计各记忆仓使用情况"
;;
esac