🎉 init: 小龙的工作空间

This commit is contained in:
大海
2026-06-06 10:40:48 +08:00
commit a188ee1426
3201 changed files with 231817 additions and 0 deletions
+269
View File
@@ -0,0 +1,269 @@
#!/usr/bin/env bash
# session-compact.sh — 会话压缩与快速存档 + Write Gate 前置检查
#
# v3 — 加入 pre-compact 钩子:上下文压缩前自动扫描未保存的纠正/决策/承诺
# v2 — 加入 Write Gate 自动路由:preference/correction/decision 触发寄存器写入
#
# 用法:
# bash scripts/session-compact.sh save "任何想记住的内容"
# bash scripts/session-compact.sh save --type preference "偏好内容"
# bash scripts/session-compact.sh save --type correction "纠正内容"
# bash scripts/session-compact.sh save --type decision "决策内容"
# bash scripts/session-compact.sh pre-compact # 上下文压缩前扫描 + 同步
# bash scripts/session-compact.sh status # 看会话统计
# bash scripts/session-compact.sh flush # 触发 Dream Cycle 同步
# bash scripts/session-compact.sh check # Write Gate 诊断
set -euo pipefail
WORKSPACE="$(cd "$(dirname "$0")/.." && pwd)"
MEMORY_SERVER="http://111.229.145.18"
# 加载环境变量(MEMORY_API_KEY 等)
if [ -z "${MEMORY_API_KEY:-}" ] && [ -f ~/.zshrc ]; then
MEMORY_API_KEY=$(grep '^export MEMORY_API_KEY=' ~/.zshrc 2>/dev/null | cut -d'"' -f2 || true)
fi
export MEMORY_API_KEY
DAILY="$WORKSPACE/memory/daily/$(date +%Y-%m-%d).md"
REGISTERS="$WORKSPACE/memory/registers"
SESSION_LOG="$WORKSPACE/memory/.session-compact.log"
# ── Write Gate 路由 ──────────────────────────────────────
write_to_register() {
local type="$1" content="$2" timestamp
timestamp=$(date '+%Y-%m-%d %H:%M')
case "$type" in
preference)
printf "\n| %s | %s | %s | session-compact | medium |\n" \
"$(wc -l < "$REGISTERS/preferences.md" | tr -d ' ')" \
"$content" "$timestamp" >> "$REGISTERS/preferences.md"
echo " 📝 → preferences 寄存器"
;;
correction)
printf "\n[correction: %s]\n- **new**: %s\n- **source**: session-compact\n" \
"$timestamp" "$content" >> "$REGISTERS/open-loops.md"
echo " 🔧 → open-loops 寄存器 (correction)"
;;
decision)
printf "\n- %s: %s (session-compact)\n" "$timestamp" "$content" \
>> "$WORKSPACE/memory/vault.md"
echo " 📋 → vault.md (decision)"
;;
event)
# 事件记录到 daily/ 已足够,不写寄存器
echo " 📌 → daily/ (event,不写寄存器)"
;;
fact|behavior|code|rule|tool|project)
# 新类型:写入 vault.md 的决策时间线
printf "\n- %s: [%s] %s (session-compact)\n" "$timestamp" "$type" "$content" \
>> "$WORKSPACE/memory/vault.md"
echo " 📋 → vault.md ($type)"
;;
*)
echo " ⚠️ 未知类型 '$type',仅写入 daily/"
;;
esac
}
# ── 命令处理 ─────────────────────────────────────────────
case "${1:-help}" in
save)
shift
# 解析参数
type=""
content=""
recall_context=""
while [ $# -gt 0 ]; do
case "$1" in
--type) type="$2"; shift 2 ;;
--type=*) type="${1#*=}"; shift ;;
--recall-context) recall_context="$2"; shift 2 ;;
--recall-context=*) recall_context="${1#*=}"; shift ;;
*) content="$1"; shift ;;
esac
done
if [ -z "$content" ]; then
echo "用法: bash scripts/session-compact.sh save [--type <type>] [--recall-context <context>] <内容>"
exit 1
fi
# ── Step 1: LLM Write Gate 判断(如果未指定 type)──
if [ -z "$type" ] && [ -f "$WORKSPACE/scripts/memory-write-gate.sh" ]; then
echo " 🧠 Write Gate LLM 判断中..."
GATE_RESULT=$(echo "$content" | bash "$WORKSPACE/scripts/memory-write-gate.sh" 2>/dev/null || echo '{"should_remember":false}')
SHOULD_REMEMBER=$(echo "$GATE_RESULT" | jq -r '.should_remember // false' 2>/dev/null || echo "false")
if [ "$SHOULD_REMEMBER" = "true" ]; then
type=$(echo "$GATE_RESULT" | jq -r '.type // ""' 2>/dev/null || echo "")
importance=$(echo "$GATE_RESULT" | jq -r '.importance // 0.5' 2>/dev/null || echo "0.5")
gate_content=$(echo "$GATE_RESULT" | jq -r '.content // ""' 2>/dev/null || echo "")
gate_recall=$(echo "$GATE_RESULT" | jq -r '.recall_context // [] | join(",")' 2>/dev/null || echo "")
gate_tags=$(echo "$GATE_RESULT" | jq -r '.tags // [] | join(",")' 2>/dev/null || echo "")
# 用 LLM 精炼的内容覆盖原始内容
[ -n "$gate_content" ] && [ "$gate_content" != "null" ] && content="$gate_content"
# 用 LLM 的 recall_context(如果用户没指定)
[ -z "$recall_context" ] && [ -n "$gate_recall" ] && [ "$gate_recall" != "null" ] && recall_context="$gate_recall"
echo " ✅ Write Gate: 值得记 (type=$type, importance=$importance)"
else
gate_reason=$(echo "$GATE_RESULT" | jq -r '.reason // "not_important"' 2>/dev/null || echo "not_important")
echo " ️ Write Gate: 不值得记 ($gate_reason),仅写入 daily/"
fi
fi
# ── Step 2: 写入 daily/(带 YAML frontmatter)──
mkdir -p "$(dirname "$DAILY")"
memory_id="mem_$(date +%Y%m%d)_$(openssl rand -hex 3 2>/dev/null || date +%s)"
# 如果有 recall_context,用 YAML frontmatter 格式
if [ -n "$type" ] || [ -n "$recall_context" ]; then
{
echo ""
echo "---"
echo "memory_id: $memory_id"
[ -n "$type" ] && echo "type: $type"
echo "created_at: $(date -Iseconds)"
[ -n "$recall_context" ] && echo "recall_context: [$recall_context]"
echo "---"
echo "[session-flush] $(date +%H:%M)$content"
} >> "$DAILY"
else
echo "" >> "$DAILY"
echo "[session-flush] $(date +%H:%M)$content" >> "$DAILY"
fi
echo " ✅ 已写入 $DAILY (id: $memory_id)"
# ── Step 3: Write Gate — 写寄存器 ──
if [ -n "$type" ]; then
write_to_register "$type" "$content"
fi
# ── Step 4: ContextGraph 集成 ──
if [ "$type" = "decision" ] || [ "$type" = "correction" ] || [ "$type" = "event" ]; then
node -e "
try {
const { ContextGraph } = require('$WORKSPACE/src/memory/context-graph');
const g = new ContextGraph();
const entityId = 'session:$(date +%Y%m%d)';
g.entity(entityId, { type: 'session', name: 'Session $(date +%Y-%m-%d)' });
g.observe(entityId, {
type: '$type',
priority: '$type' === 'decision' ? 'high' : 'normal',
summary: process.argv[1].substring(0, 200),
details: { source: 'session-compact', memory_id: '$memory_id' }
});
g.save();
console.log(' 🕸️ → ContextGraph');
} catch(e) { console.log(' ⚠️ ContextGraph: ' + e.message); }
" "$content" 2>/dev/null || echo " ⚠️ ContextGraph 写入失败"
fi
# ── Step 5: 推到远程服务器(带新字段)──
clean=$(echo "$content" | sed 's/"/\\"/g' | head -c 400)
remote_payload=$(jq -n \
--arg c "$clean" \
--arg t "${type:-session-flush}" \
--arg rc "${recall_context:-}" \
--arg mid "$memory_id" \
'{content:$c, type:$t, project:"xiaolong", source:"session-compact", memory_id:$mid, recall_context:($rc | split(",") | map(select(. != "")))}')
resp=$(curl -s --max-time 5 -X POST "$MEMORY_SERVER/api/v2/add" \
-H "Content-Type: application/json" \
-H "X-API-Key: ${MEMORY_API_KEY:-}" \
-d "$remote_payload" 2>/dev/null) || true
if echo "$resp" | grep -q 'stored\|ok'; then
echo " ✅ 已同步到远程服务器"
else
echo " ⚠️ 远程同步: ${resp:-无响应}"
fi
echo "$(date '+%Y-%m-%d %H:%M') | ${type:-general} | $content" >> "$SESSION_LOG"
;;
check)
echo "🔍 Write Gate 诊断"
echo ""
echo " 寄存器状态:"
for f in "$REGISTERS"/*.md; do
[ -f "$f" ] || continue
name=$(basename "$f" .md)
lines=$(wc -l < "$f" | tr -d ' ')
size=$(wc -c < "$f" | tr -d ' ')
echo " $name: ${lines}行 / ${size}字节"
done
echo ""
echo " 最近 5 条 compact:"
[ -f "$SESSION_LOG" ] && tail -5 "$SESSION_LOG" || echo " 无记录"
echo ""
echo " 今天 daily:"
[ -f "$DAILY" ] && wc -l < "$DAILY" | xargs echo " lines:" || echo " (空)"
;;
status)
echo "📊 会话状态"
echo " 每日日志: $DAILY"
echo " 寄存器:"
ls "$REGISTERS"/*.md 2>/dev/null | while read -r f; do
echo " $(basename "$f" .md): $(wc -l < "$f")"
done
echo " Compact 历史:"
[ -f "$SESSION_LOG" ] && tail -5 "$SESSION_LOG" || echo " 无记录"
;;
flush)
echo "🔄 触发立即存档..."
bash "$WORKSPACE/scripts/dream-cycle.sh" sync-remote 2>&1
;;
pre-compact)
echo "🛡️ Pre-Compaction Hook — 上下文压缩前安全检查"
echo ""
has_flush=false
if [ -f "$DAILY" ]; then
if grep -q '\[session-flush\]' "$DAILY"; then
echo " ✅ 今天已有 [session-flush] 标记"
has_flush=true
grep '\[session-flush\]' "$DAILY" | tail -3 | while read -r line; do
echo " $(echo "$line" | cut -c1-80)"
done
fi
fi
if [ "$has_flush" = false ]; then
echo " ⚠️ 今天 daily/ 无 [session-flush] 标记 — 压缩前请先存档关键信息"
fi
echo ""
echo " 🌐 远程服务器:"
remote_resp=$(curl -s --max-time 5 "$MEMORY_SERVER/api/v2/stats" 2>/dev/null || echo '{"error":"unreachable"}')
if echo "$remote_resp" | grep -q 'xiaolong'; then
echo " ✅ 在线"
else
echo " ⚠️ 不可达"
fi
echo ""
echo " 📤 触发同步..."
bash "$WORKSPACE/scripts/dream-cycle.sh" sync-remote 2>&1 | sed 's/^/ /'
echo ""
echo " ✅ Pre-Compaction Hook 完成"
;;
*)
echo "用法:"
echo " bash scripts/session-compact.sh save <内容> — 快速存关键信息"
echo " bash scripts/session-compact.sh save --type preference <内容> — 记偏好(→registers"
echo " bash scripts/session-compact.sh save --type correction <内容> — 记纠正(→registers"
echo " bash scripts/session-compact.sh save --type decision <内容> — 记决策(→vault"
echo " bash scripts/session-compact.sh pre-compact — 压缩前安全检查 + 同步"
echo " bash scripts/session-compact.sh status — 查看状态"
echo " bash scripts/session-compact.sh check — Write Gate 诊断"
echo " bash scripts/session-compact.sh flush — 触发全部同步"
;;
esac