recallnest 1.4.1 → 2.2.1
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.
- package/.env +4 -0
- package/CLAUDE.md +7 -3
- package/README.md +202 -130
- package/README_CN.md +263 -190
- package/bin/recallnest.mjs +62 -0
- package/config.json +55 -0
- package/daily-recall.sh +23 -0
- package/integrations/setup-all.sh +31 -0
- package/logs/daily-recall.error.log +0 -0
- package/logs/daily-recall.log +30 -0
- package/logs/ingest-2026-04-11.log +110 -0
- package/logs/ingest-2026-04-12.log +90 -0
- package/logs/launchagent-stderr.log +0 -0
- package/logs/launchagent-stdout.log +0 -0
- package/package.json +10 -3
- package/src/access-tracker.ts +3 -2
- package/src/activity-counter.ts +109 -0
- package/src/adaptive-retrieval.ts +6 -5
- package/src/admission-control.ts +163 -0
- package/src/anchor-generator.ts +80 -0
- package/src/api-server.ts +10 -0
- package/src/audit-log.ts +122 -0
- package/src/auto-gc.ts +98 -29
- package/src/auto-recall.ts +33 -4
- package/src/capture-engine.ts +372 -23
- package/src/cascade-forget.ts +3 -2
- package/src/cli.ts +107 -5
- package/src/compat.ts +22 -0
- package/src/confidence-tracker.ts +210 -47
- package/src/conflict-store.ts +12 -3
- package/src/consolidation-engine.ts +296 -8
- package/src/context-collapse-renderer.ts +222 -0
- package/src/context-composer-stable-selection.ts +5 -1
- package/src/context-composer.ts +239 -4
- package/src/context-reconstructor.ts +404 -0
- package/src/conversation-importer.ts +441 -0
- package/src/data-checkup.ts +232 -0
- package/src/decay-engine.ts +84 -0
- package/src/distill-lock.ts +122 -0
- package/src/doctor.ts +8 -10
- package/src/dream-pipeline.ts +227 -0
- package/src/emotion-detector.ts +90 -0
- package/src/eval.ts +3 -2
- package/src/forget-engine.ts +269 -0
- package/src/frequency-tracker.ts +175 -0
- package/src/graph-export.ts +644 -0
- package/src/ingest.ts +36 -6
- package/src/interference-detector.ts +187 -0
- package/src/kg-extractor.ts +15 -24
- package/src/kg-store.ts +2 -1
- package/src/language-hook.ts +67 -0
- package/src/llm-client.ts +289 -6
- package/src/mcp-server.ts +707 -80
- package/src/memory-assets.ts +22 -5
- package/src/memory-evolution.ts +365 -0
- package/src/memory-lint.ts +429 -0
- package/src/memory-output.ts +69 -0
- package/src/memory-schema.ts +74 -2
- package/src/narrative-schema.ts +79 -0
- package/src/narrative-tagger.ts +164 -0
- package/src/pii-detector.ts +98 -0
- package/src/post-retrieval-filter.ts +76 -0
- package/src/prediction-engine.ts +253 -0
- package/src/preference-slots.ts +65 -2
- package/src/prospective-memory.ts +215 -0
- package/src/query-expander.ts +67 -0
- package/src/recall-governor.ts +183 -0
- package/src/retention-policy.ts +90 -0
- package/src/retriever.ts +828 -55
- package/src/rif.ts +34 -8
- package/src/runtime-config.ts +23 -8
- package/src/scope-inventory.ts +4 -3
- package/src/scope-policy.ts +4 -0
- package/src/session-distiller.ts +307 -0
- package/src/session-output.ts +40 -0
- package/src/session-schema.ts +37 -0
- package/src/session-store.ts +7 -2
- package/src/skill-engine.ts +208 -0
- package/src/skill-promotion.ts +293 -0
- package/src/skill-schema.ts +39 -0
- package/src/store.ts +96 -10
- package/src/topic-tag.ts +66 -0
- package/src/tracker.ts +3 -1
- package/src/ui-server.ts +80 -8
- package/src/workflow-observation-scope-review.ts +2 -1
- package/src/workflow-observation-store.ts +2 -1
- package/src/write-verifier.ts +126 -0
- package/.claude-plugin/CLAUDE.md +0 -29
- package/.claude-plugin/marketplace.json +0 -18
- package/.github/workflows/ci.yml +0 -28
- package/.mcp.json +0 -9
- package/CHANGELOG.md +0 -51
- package/DEMO.md +0 -94
- package/EVAL.md +0 -89
- package/FAILURES.md +0 -75
- package/OPERATIONS.md +0 -59
- package/ROADMAP.md +0 -198
- package/assets/recallnest-workbench.png +0 -0
- package/assets/ui/app.js +0 -807
- package/assets/ui/index.html +0 -154
- package/assets/ui/styles.css +0 -605
- package/assets/wechat-qr.jpg +0 -0
- package/daily-reflections/2026-03-05.md +0 -15
- package/daily-reflections/2026-03-06.md +0 -15
- package/daily-reflections/2026-03-07.md +0 -7
- package/daily-reflections/2026-03-08.md +0 -34
- package/daily-reflections/2026-03-09.md +0 -35
- package/daily-reflections/2026-03-10.md +0 -36
- package/daily-reflections/2026-03-11.md +0 -35
- package/daily-reflections/2026-03-12.md +0 -36
- package/daily-reflections/2026-03-13.md +0 -35
- package/daily-reflections/2026-03-14.md +0 -35
- package/daily-reflections/2026-03-15.md +0 -35
- package/daily-reflections/2026-03-16.md +0 -41
- package/daily-reflections/2026-03-17.md +0 -10
- package/daily-reflections/2026-03-18.md +0 -10
- package/daily-reflections/2026-03-19.md +0 -10
- package/daily-reflections/2026-03-20.md +0 -10
- package/daily-reflections/2026-03-21.md +0 -10
- package/daily-reflections/2026-03-22.md +0 -10
- package/daily-reflections/2026-03-23.md +0 -10
- package/daily-reflections/2026-03-24.md +0 -10
- package/daily-reflections/2026-03-25.md +0 -32
- package/daily-reflections/2026-03-26.md +0 -37
- package/daily-reflections/2026-03-27.md +0 -35
- package/daily-reflections/2026-03-28.md +0 -35
- package/daily-reflections/2026-03-29.md +0 -35
- package/daily-reflections/2026-03-30.md +0 -36
- package/daily-reflections/2026-03-31.md +0 -35
- package/daily-reflections/2026-04-01.md +0 -35
- package/docs/api-reference.md +0 -1291
- package/docs/architecture.md +0 -168
- package/docs/memory-boundary-contract.md +0 -226
- package/docs/memory-categories.md +0 -119
- package/docs/pipeline-audit-ultramemory.md +0 -177
- package/docs/plans/2026-03-08-query-expansion.md +0 -270
- package/docs/plans/2026-03-16-continuity-layer.md +0 -196
- package/docs/plans/mcp-tiering-plan.md +0 -126
- package/docs/research/recall-quality-audit-2026-03-22.md +0 -153
- package/docs/self-evolution.md +0 -198
- package/docs/superpowers/plans/2026-03-19-ingest-pipeline-upgrade.md +0 -782
- package/docs/superpowers/specs/2026-03-19-ingest-pipeline-upgrade-design.md +0 -77
- package/docs/superpowers/specs/2026-03-23-pull-claude-desktop-design.md +0 -95
- package/eval/continuity/results-2026-03-16.md +0 -117
- package/eval/continuity/results-2026-03-19.md +0 -453
- package/eval/continuity/runbook.md +0 -110
- package/eval/continuity/seed-cases.md +0 -54
- package/eval/reports/2026-03-06-abstract-query-baseline.md +0 -96
- package/eval/reports/2026-03-06-aws-ssh-baseline.md +0 -82
- package/eval/reports/2026-03-06-baseline.md +0 -82
- package/eval/reports/query-expansion.md +0 -138
- package/lm +0 -19
- package/plan-v1.2-distributable.md +0 -105
- package/scripts/archive-distilled-junk.ts +0 -116
- package/scripts/backfill-l0l1l2.ts +0 -98
- package/scripts/blind-scan.ts +0 -588
- package/scripts/cleanup-step1-exact-dups.ts +0 -117
- package/scripts/cleanup-step2-template-dups.ts +0 -113
- package/scripts/cleanup-step3-stale-content.ts +0 -149
- package/scripts/cleanup-step4-orphan-scopes.ts +0 -131
- package/scripts/delete-distilled-junk.ts +0 -88
- package/scripts/distill-facts.ts +0 -305
- package/scripts/health-check.ts +0 -343
- package/scripts/incremental-ingest.sh +0 -71
- package/scripts/mlp-health-check.ts +0 -382
- package/scripts/pull-claude-desktop.ts +0 -515
- package/scripts/re-ingest-cc.sh +0 -66
- package/scripts/rebalance-memory-health.ts +0 -181
- package/scripts/run-desktop-ingest.sh +0 -11
- package/scripts/start-server.sh +0 -12
- package/scripts/viz-dashboard.html +0 -423
- package/scripts/viz-export.ts +0 -703
- package/src/__tests__/access-tracker-novelty.test.ts +0 -228
- package/src/__tests__/auto-consolidation.test.ts +0 -168
- package/src/__tests__/auto-recall.test.ts +0 -131
- package/src/__tests__/batch-dedup.test.ts +0 -65
- package/src/__tests__/capture-engine.test.ts +0 -1142
- package/src/__tests__/capture-heuristic.test.ts +0 -171
- package/src/__tests__/cascade-forget.test.ts +0 -210
- package/src/__tests__/category-min-scores.test.ts +0 -33
- package/src/__tests__/confidence-tracker.test.ts +0 -196
- package/src/__tests__/conflict-advisor.test.ts +0 -206
- package/src/__tests__/conflict-escalation.test.ts +0 -149
- package/src/__tests__/conflict-lifecycle.test.ts +0 -83
- package/src/__tests__/conflict-output.test.ts +0 -85
- package/src/__tests__/conflict-store.test.ts +0 -374
- package/src/__tests__/consolidation-engine.test.ts +0 -181
- package/src/__tests__/context-composer-pins.test.ts +0 -64
- package/src/__tests__/context-composer-task-selection.test.ts +0 -24
- package/src/__tests__/context-renderer.test.ts +0 -91
- package/src/__tests__/continuity-eval.test.ts +0 -275
- package/src/__tests__/continuity-schema.test.ts +0 -97
- package/src/__tests__/core-recall-eval.test.ts +0 -235
- package/src/__tests__/core-summary.test.ts +0 -109
- package/src/__tests__/dedup-actions.test.ts +0 -58
- package/src/__tests__/deterministic-id.test.ts +0 -39
- package/src/__tests__/doctor.test.ts +0 -303
- package/src/__tests__/drill-down.test.ts +0 -108
- package/src/__tests__/embedder.test.ts +0 -122
- package/src/__tests__/entity-resolver.test.ts +0 -58
- package/src/__tests__/event-segmenter.test.ts +0 -153
- package/src/__tests__/hotness-blend.test.ts +0 -76
- package/src/__tests__/ingest.test.ts +0 -360
- package/src/__tests__/kg-extractor.test.ts +0 -184
- package/src/__tests__/kg-store.test.ts +0 -198
- package/src/__tests__/llm-consolidation.test.ts +0 -226
- package/src/__tests__/memory-boundaries.test.ts +0 -237
- package/src/__tests__/memory-health-rebalance.test.ts +0 -144
- package/src/__tests__/memory-output.test.ts +0 -215
- package/src/__tests__/multi-vector.test.ts +0 -242
- package/src/__tests__/ppr-traversal.test.ts +0 -256
- package/src/__tests__/preference-guard-smoke.test.ts +0 -211
- package/src/__tests__/preference-matcher.test.ts +0 -230
- package/src/__tests__/preference-slots.test.ts +0 -106
- package/src/__tests__/prospective-memory.test.ts +0 -283
- package/src/__tests__/query-entity-detector.test.ts +0 -171
- package/src/__tests__/query-expander.test.ts +0 -34
- package/src/__tests__/recall-mode.test.ts +0 -64
- package/src/__tests__/result-synthesizer.test.ts +0 -198
- package/src/__tests__/resume-context.test.ts +0 -4743
- package/src/__tests__/retrieval-trace.test.ts +0 -213
- package/src/__tests__/retriever-boundary-weight.test.ts +0 -136
- package/src/__tests__/retroactive-boost.test.ts +0 -223
- package/src/__tests__/scope-inventory.test.ts +0 -200
- package/src/__tests__/scope-policy.test.ts +0 -69
- package/src/__tests__/session-checkpoint.test.ts +0 -259
- package/src/__tests__/session-gc.test.ts +0 -215
- package/src/__tests__/store-scope-audit.test.ts +0 -81
- package/src/__tests__/temporal-parser.test.ts +0 -241
- package/src/__tests__/term-registry.test.ts +0 -121
- package/src/__tests__/tool-output-compressor.test.ts +0 -133
- package/src/__tests__/version-manager.test.ts +0 -213
- package/src/__tests__/workflow-observation.test.ts +0 -400
package/config.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"dbPath": "./data/lancedb",
|
|
3
|
+
"recallMode": "full",
|
|
4
|
+
"embedding": {
|
|
5
|
+
"provider": "jina",
|
|
6
|
+
"apiKey": "${JINA_API_KEY}",
|
|
7
|
+
"model": "jina-embeddings-v5-text-small",
|
|
8
|
+
"baseURL": "https://api.jina.ai/v1",
|
|
9
|
+
"dimensions": 1024,
|
|
10
|
+
"taskQuery": "retrieval.query",
|
|
11
|
+
"taskPassage": "retrieval.passage"
|
|
12
|
+
},
|
|
13
|
+
"llm": {
|
|
14
|
+
"apiKey": "${QWEN_API_KEY}",
|
|
15
|
+
"model": "qwen-turbo",
|
|
16
|
+
"baseURL": "https://dashscope.aliyuncs.com/compatible-mode/v1"
|
|
17
|
+
},
|
|
18
|
+
"sources": {
|
|
19
|
+
"cc": {
|
|
20
|
+
"path": "auto",
|
|
21
|
+
"glob": "*.jsonl",
|
|
22
|
+
"description": "Claude Code transcripts"
|
|
23
|
+
},
|
|
24
|
+
"codex": {
|
|
25
|
+
"path": "~/.codex/sessions",
|
|
26
|
+
"glob": "*.jsonl",
|
|
27
|
+
"description": "Codex sessions"
|
|
28
|
+
},
|
|
29
|
+
"memory": {
|
|
30
|
+
"path": "auto",
|
|
31
|
+
"glob": "*.md",
|
|
32
|
+
"description": "Claude Code memory files"
|
|
33
|
+
},
|
|
34
|
+
"gemini": {
|
|
35
|
+
"path": "~/.gemini/tmp",
|
|
36
|
+
"glob": "session-*.json",
|
|
37
|
+
"description": "Gemini CLI sessions"
|
|
38
|
+
},
|
|
39
|
+
"desktop": {
|
|
40
|
+
"path": "./data/desktop-import",
|
|
41
|
+
"glob": "*.jsonl",
|
|
42
|
+
"description": "Claude Desktop / claude.ai web conversations"
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
"retrieval": {
|
|
46
|
+
"mode": "hybrid",
|
|
47
|
+
"vectorWeight": 0.6,
|
|
48
|
+
"bm25Weight": 0.4,
|
|
49
|
+
"recencyHalfLifeDays": 30,
|
|
50
|
+
"timeDecayHalfLifeDays": 60,
|
|
51
|
+
"hardMinScore": 0.38,
|
|
52
|
+
"hotnessWeight": 0.15
|
|
53
|
+
},
|
|
54
|
+
"recallDepthDefault": "l1"
|
|
55
|
+
}
|
package/daily-recall.sh
CHANGED
|
@@ -48,6 +48,25 @@ TODAY_QUERY="${QUERIES[$IDX]}"
|
|
|
48
48
|
|
|
49
49
|
echo " 今日主题 (#$((IDX+1))): $TODAY_QUERY" | tee -a "$LOG_FILE"
|
|
50
50
|
|
|
51
|
+
# ── CC-6 + HP-3: Distill gate — lock + session gate + activity gate ─────
|
|
52
|
+
echo " 检查 distill gate..." | tee -a "$LOG_FILE"
|
|
53
|
+
GATE_RESULT=$(bun -e "
|
|
54
|
+
const { acquireLock, shouldDistill } = require('./src/distill-lock.ts');
|
|
55
|
+
const { getDistillTier } = require('./src/activity-counter.ts');
|
|
56
|
+
const cp = parseInt(process.argv[1] || '0', 10);
|
|
57
|
+
const tier = getDistillTier();
|
|
58
|
+
const sessionReady = shouldDistill(cp);
|
|
59
|
+
if (tier === 'none' && !sessionReady) { console.log('SKIP:no_activity'); process.exit(0); }
|
|
60
|
+
if (!acquireLock()) { console.log('SKIP:lock_held'); process.exit(0); }
|
|
61
|
+
console.log('OK:' + tier);
|
|
62
|
+
" "$(bun run "$SCRIPT_DIR/src/cli.ts" checkpoint-count 2>/dev/null || echo 5)" 2>&1 || echo "OK:standard")
|
|
63
|
+
|
|
64
|
+
if [[ "$GATE_RESULT" == SKIP:* ]]; then
|
|
65
|
+
echo " [跳过] distill gate: $GATE_RESULT" | tee -a "$LOG_FILE"
|
|
66
|
+
else
|
|
67
|
+
echo " distill gate: $GATE_RESULT" | tee -a "$LOG_FILE"
|
|
68
|
+
fi
|
|
69
|
+
|
|
51
70
|
# ── 用 lm distill 提取结构化洞察 ──────────────────────────────
|
|
52
71
|
echo " 执行 distill..." | tee -a "$LOG_FILE"
|
|
53
72
|
DISTILL_OUTPUT=$("$LM" distill "$TODAY_QUERY" --profile writing --limit 8 --all-scopes 2>&1 || true)
|
|
@@ -64,6 +83,10 @@ fi
|
|
|
64
83
|
|
|
65
84
|
echo " distill 完成,$(echo "$DISTILL_OUTPUT" | wc -l | tr -d ' ') 行" | tee -a "$LOG_FILE"
|
|
66
85
|
|
|
86
|
+
# CC-6: Release lock on success + HP-3: Reset activity counter
|
|
87
|
+
bun -e "try { require('./src/distill-lock.ts').releaseLock(); } catch {}" 2>/dev/null || true
|
|
88
|
+
bun -e "try { require('./src/activity-counter.ts').resetWriteCount(); } catch {}" 2>/dev/null || true
|
|
89
|
+
|
|
67
90
|
# ── 写入输出文件 ──────────────────────────────────────────────
|
|
68
91
|
cat > "$OUTPUT_FILE" << EOF
|
|
69
92
|
# 每日回顾 · $DATE
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# RecallNest — setup all three terminals at once (idempotent)
|
|
3
|
+
# Usage: bash integrations/setup-all.sh
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
|
|
9
|
+
echo "RecallNest — setting up all terminals"
|
|
10
|
+
echo "======================================"
|
|
11
|
+
echo ""
|
|
12
|
+
|
|
13
|
+
echo "--- Claude Code ---"
|
|
14
|
+
bash "$SCRIPT_DIR/claude-code/setup.sh"
|
|
15
|
+
echo ""
|
|
16
|
+
|
|
17
|
+
echo "--- Codex ---"
|
|
18
|
+
bash "$SCRIPT_DIR/codex/setup.sh"
|
|
19
|
+
echo ""
|
|
20
|
+
|
|
21
|
+
echo "--- Gemini CLI ---"
|
|
22
|
+
bash "$SCRIPT_DIR/gemini-cli/setup.sh"
|
|
23
|
+
echo ""
|
|
24
|
+
|
|
25
|
+
echo "======================================"
|
|
26
|
+
echo "All terminals configured."
|
|
27
|
+
echo ""
|
|
28
|
+
echo "Next steps:"
|
|
29
|
+
echo " 1. Restart each terminal"
|
|
30
|
+
echo " 2. Run: bun run seed:continuity"
|
|
31
|
+
echo " 3. Run: bun run src/cli.ts doctor"
|
|
File without changes
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
=== 2026-04-12 08:00:01 daily-recall 开始 ===
|
|
2
|
+
=== 2026-04-12 08:00:01 daily-recall 开始 ===
|
|
3
|
+
今日主题 (#7): 踩坑 修复 经验总结
|
|
4
|
+
今日主题 (#7): 踩坑 修复 经验总结
|
|
5
|
+
检查 distill gate...
|
|
6
|
+
检查 distill gate...
|
|
7
|
+
distill gate:
|
|
8
|
+
distill gate:
|
|
9
|
+
执行 distill...
|
|
10
|
+
执行 distill...
|
|
11
|
+
distill 完成,27 行
|
|
12
|
+
distill 完成,27 行
|
|
13
|
+
[完成] 回顾已写入: /Users/anxianjingya/recallnest/daily-reflections/2026-04-12.md
|
|
14
|
+
[完成] 回顾已写入: /Users/anxianjingya/recallnest/daily-reflections/2026-04-12.md
|
|
15
|
+
执行 checkpoint-gc...
|
|
16
|
+
执行 checkpoint-gc...
|
|
17
|
+
checkpoint-gc: === Checkpoint GC ===
|
|
18
|
+
|
|
19
|
+
Kept : 217
|
|
20
|
+
Archived : 0
|
|
21
|
+
Deleted : 0
|
|
22
|
+
Errors : 0
|
|
23
|
+
checkpoint-gc: === Checkpoint GC ===
|
|
24
|
+
|
|
25
|
+
Kept : 217
|
|
26
|
+
Archived : 0
|
|
27
|
+
Deleted : 0
|
|
28
|
+
Errors : 0
|
|
29
|
+
=== 2026-04-12 08:00:13 daily-recall 结束 ===
|
|
30
|
+
=== 2026-04-12 08:00:13 daily-recall 结束 ===
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
=== 2026-04-11 19:22:04 增量更新开始 ===
|
|
2
|
+
[INFO] LLM client initialized: qwen-turbo @ https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
3
|
+
|
|
4
|
+
🔑 验证 Embedding API...
|
|
5
|
+
✅ jina-embeddings-v5-text-small (1024d)
|
|
6
|
+
✅ LLM: qwen-turbo (L0 摘要 + 语义去重)
|
|
7
|
+
✅ 两阶段去重: vector + LLM 语义判断
|
|
8
|
+
|
|
9
|
+
🔄 开始导入记忆 (source: all)...
|
|
10
|
+
|
|
11
|
+
📝 导入 Claude Code 对话...
|
|
12
|
+
CC: 230/962 files, 120 chunks ingested
|
|
13
|
+
CC: 470/962 files, 186 chunks ingested
|
|
14
|
+
[INFO] noise-filter: denial pattern matched: "**Phase 5: Predictive Prospective Memory — DONE** ✅
|
|
15
|
+
|
|
16
|
+
总结一下做了什..."
|
|
17
|
+
✅ CC: 24 files, 528 ingested, 474 deduped (hard:17, exact:160, llm-skip:150, llm-merge:147), 0 errors
|
|
18
|
+
🤖 导入 Codex 对话...
|
|
19
|
+
[INFO] noise-filter: meta-question filtered: "# AGENTS.md instructions for /Users/anxianjingya/Projects/re..."
|
|
20
|
+
[INFO] noise-filter: meta-question filtered: "# AGENTS.md instructions for /Users/anxianjingya
|
|
21
|
+
|
|
22
|
+
<INSTRUCTI..."
|
|
23
|
+
Codex: 294/294 files, 39 chunks ingested
|
|
24
|
+
✅ Codex: 2 files, 39 ingested, 22 deduped (hard:6, exact:0, llm-skip:8, llm-merge:8), 0 errors
|
|
25
|
+
💎 导入 Gemini 对话...
|
|
26
|
+
✅ Gemini: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
27
|
+
🖥️ 导入 Claude Desktop 对话...
|
|
28
|
+
CC: 10/349 files, 43 chunks ingested
|
|
29
|
+
[INFO] noise-filter: denial pattern matched: "好的!我来手把手教你!别担心,超简单! 😊
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 📍 **Step 1: 找到文件在哪**
|
|
34
|
+
|
|
35
|
+
我刚才给你..."
|
|
36
|
+
CC: 20/349 files, 70 chunks ingested
|
|
37
|
+
CC: 30/349 files, 73 chunks ingested
|
|
38
|
+
[INFO] noise-filter: short boilerplate filtered: "好的,我来帮你截图。"
|
|
39
|
+
CC: 40/349 files, 160 chunks ingested
|
|
40
|
+
CC: 50/349 files, 180 chunks ingested
|
|
41
|
+
CC: 60/349 files, 226 chunks ingested
|
|
42
|
+
CC: 70/349 files, 256 chunks ingested
|
|
43
|
+
[INFO] noise-filter: meta-question filtered: "你记不记得我让你帮我弄孩子们的简历..."
|
|
44
|
+
[INFO] noise-filter: denial pattern matched: "我查找一下我们之前关于孩子们简历的对话...
|
|
45
|
+
|
|
46
|
+
让我搜索一下相关内容。
|
|
47
|
+
|
|
48
|
+
我没有找到我们之前讨论过帮孩子们制作简历的记录..."
|
|
49
|
+
CC: 80/349 files, 316 chunks ingested
|
|
50
|
+
CC: 90/349 files, 335 chunks ingested
|
|
51
|
+
CC: 100/349 files, 412 chunks ingested
|
|
52
|
+
CC: 110/349 files, 501 chunks ingested
|
|
53
|
+
CC: 120/349 files, 520 chunks ingested
|
|
54
|
+
[INFO] noise-filter: boilerplate filtered: "Hello! How can I help you today?..."
|
|
55
|
+
[INFO] noise-filter: denial pattern matched: "不能。我无法访问你本地电脑上的文件或 Claude Code 的 session 记录。
|
|
56
|
+
|
|
57
|
+
我能访问的是:
|
|
58
|
+
1. **我..."
|
|
59
|
+
[INFO] noise-filter: denial pattern matched: "这个我不太确定,因为 Claude Desktop 的会话索引存在 `~/Library/Application Sup..."
|
|
60
|
+
[INFO] noise-filter: boilerplate filtered: "Hi Alice,
|
|
61
|
+
I understand you're looking for a way to rebuild t..."
|
|
62
|
+
CC: 130/349 files, 547 chunks ingested
|
|
63
|
+
CC: 140/349 files, 585 chunks ingested
|
|
64
|
+
[INFO] noise-filter: denial pattern matched: "啊,你说得对!我理解错了。
|
|
65
|
+
|
|
66
|
+
让我重新想想这个问题...
|
|
67
|
+
|
|
68
|
+
Antigravity 确实也是通过 Claude in C..."
|
|
69
|
+
CC: 150/349 files, 618 chunks ingested
|
|
70
|
+
[INFO] noise-filter: denial pattern matched: "我来帮你查看workspace里的PPT相关文件,分析其逻辑是否与截图中描述的一致。
|
|
71
|
+
|
|
72
|
+
让我先看看目录结构:
|
|
73
|
+
我看到wo..."
|
|
74
|
+
CC: 160/349 files, 659 chunks ingested
|
|
75
|
+
CC: 170/349 files, 681 chunks ingested
|
|
76
|
+
[INFO] noise-filter: denial pattern matched: "我不确定Claude Opus 4.5的具体知识截止日期是否与我的相同。
|
|
77
|
+
|
|
78
|
+
让我搜索一下Anthropic官方文档来确认..."
|
|
79
|
+
CC: 180/349 files, 685 chunks ingested
|
|
80
|
+
CC: 190/349 files, 694 chunks ingested
|
|
81
|
+
CC: 210/349 files, 919 chunks ingested
|
|
82
|
+
CC: 220/349 files, 927 chunks ingested
|
|
83
|
+
CC: 230/349 files, 956 chunks ingested
|
|
84
|
+
CC: 240/349 files, 977 chunks ingested
|
|
85
|
+
CC: 250/349 files, 1018 chunks ingested
|
|
86
|
+
CC: 260/349 files, 1030 chunks ingested
|
|
87
|
+
CC: 270/349 files, 1048 chunks ingested
|
|
88
|
+
CC: 280/349 files, 1185 chunks ingested
|
|
89
|
+
CC: 290/349 files, 1196 chunks ingested
|
|
90
|
+
[INFO] noise-filter: boilerplate filtered: "Hi Alice! Here's what I've learned about you from our past c..."
|
|
91
|
+
CC: 300/349 files, 1211 chunks ingested
|
|
92
|
+
CC: 310/349 files, 1243 chunks ingested
|
|
93
|
+
CC: 320/349 files, 1276 chunks ingested
|
|
94
|
+
[INFO] noise-filter: denial pattern matched: "我想不起来给你的这些提示词和视觉skill是哪里来的..."
|
|
95
|
+
[INFO] noise-filter: denial pattern matched: "* 全网AI集体翻车?为了读一篇公众号文章,我扒开了Grok的“谎言”
|
|
96
|
+
* Gemini、Claude、元宝全试了,竟..."
|
|
97
|
+
[INFO] noise-filter: denial pattern matched: "让我先查看歌舞剧院的总结,提取人才相关数据:
|
|
98
|
+
好的,我现在已经了解了录音中领导的修改意见和两家院团的总结内容。根据领导的..."
|
|
99
|
+
CC: 330/349 files, 1331 chunks ingested
|
|
100
|
+
CC: 340/349 files, 1348 chunks ingested
|
|
101
|
+
CC: 349/349 files, 1372 chunks ingested
|
|
102
|
+
✅ Desktop: 343 files, 1372 ingested, 3805 deduped (hard:440, exact:1721, llm-skip:1045, llm-merge:599), 0 errors
|
|
103
|
+
📚 导入记忆文件...
|
|
104
|
+
✅ Memory: 8 files, 11 ingested, 279 deduped (hard:0, exact:257, llm-skip:15, llm-merge:7), 0 errors
|
|
105
|
+
|
|
106
|
+
📊 导入汇总:
|
|
107
|
+
总计: 1950 chunks 已索引, 4580 chunks 去重 (hard:463, exact:2138, llm-skip:1218, llm-merge:761), 0 errors
|
|
108
|
+
|
|
109
|
+
=== 2026-04-11 20:37:10 增量更新完成 ===
|
|
110
|
+
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
=== 2026-04-12 03:00:01 增量更新开始 ===
|
|
2
|
+
[INFO] LLM client initialized: qwen-turbo @ https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
3
|
+
|
|
4
|
+
🔑 验证 Embedding API...
|
|
5
|
+
✅ jina-embeddings-v5-text-small (1024d)
|
|
6
|
+
✅ LLM: qwen-turbo (L0 摘要 + 语义去重)
|
|
7
|
+
✅ 两阶段去重: vector + LLM 语义判断
|
|
8
|
+
|
|
9
|
+
🔄 开始导入记忆 (source: all)...
|
|
10
|
+
|
|
11
|
+
📝 导入 Claude Code 对话...
|
|
12
|
+
[INFO] noise-filter: denial pattern matched: "<task-notification>
|
|
13
|
+
<task-id>ac1e8c3a46f90bcc6</task-id>
|
|
14
|
+
<to..."
|
|
15
|
+
CC: 400/976 files, 269 chunks ingested
|
|
16
|
+
[INFO] noise-filter: denial pattern matched: "完全破案了。
|
|
17
|
+
|
|
18
|
+
**根因:4月10日 22:55(新加坡时间)发生了一次批量仓库可见性修改**
|
|
19
|
+
|
|
20
|
+
时间线还原:
|
|
21
|
+
|
|
22
|
+
| U..."
|
|
23
|
+
CC: 770/976 files, 541 chunks ingested
|
|
24
|
+
✅ CC: 19 files, 563 ingested, 505 deduped (hard:24, exact:228, llm-skip:114, llm-merge:139), 0 errors
|
|
25
|
+
🤖 导入 Codex 对话...
|
|
26
|
+
✅ Codex: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
27
|
+
💎 导入 Gemini 对话...
|
|
28
|
+
✅ Gemini: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
29
|
+
🖥️ 导入 Claude Desktop 对话...
|
|
30
|
+
✅ Desktop: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
31
|
+
📚 导入记忆文件...
|
|
32
|
+
✅ Memory: 5 files, 4 ingested, 188 deduped (hard:0, exact:172, llm-skip:13, llm-merge:3), 0 errors
|
|
33
|
+
|
|
34
|
+
📊 导入汇总:
|
|
35
|
+
总计: 567 chunks 已索引, 693 chunks 去重 (hard:24, exact:400, llm-skip:127, llm-merge:142), 0 errors
|
|
36
|
+
|
|
37
|
+
=== 2026-04-12 03:16:02 增量更新完成 ===
|
|
38
|
+
|
|
39
|
+
=== 2026-04-12 11:16:02 增量更新开始 ===
|
|
40
|
+
[INFO] LLM client initialized: qwen-turbo @ https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
41
|
+
|
|
42
|
+
🔑 验证 Embedding API...
|
|
43
|
+
✅ jina-embeddings-v5-text-small (1024d)
|
|
44
|
+
✅ LLM: qwen-turbo (L0 摘要 + 语义去重)
|
|
45
|
+
✅ 两阶段去重: vector + LLM 语义判断
|
|
46
|
+
|
|
47
|
+
🔄 开始导入记忆 (source: all)...
|
|
48
|
+
|
|
49
|
+
📝 导入 Claude Code 对话...
|
|
50
|
+
✅ CC: 5 files, 141 ingested, 90 deduped (hard:4, exact:24, llm-skip:30, llm-merge:32), 0 errors
|
|
51
|
+
🤖 导入 Codex 对话...
|
|
52
|
+
✅ Codex: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
53
|
+
💎 导入 Gemini 对话...
|
|
54
|
+
✅ Gemini: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
55
|
+
🖥️ 导入 Claude Desktop 对话...
|
|
56
|
+
✅ Desktop: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
57
|
+
📚 导入记忆文件...
|
|
58
|
+
✅ Memory: 1 files, 0 ingested, 182 deduped (hard:0, exact:171, llm-skip:11, llm-merge:0), 0 errors
|
|
59
|
+
|
|
60
|
+
📊 导入汇总:
|
|
61
|
+
总计: 141 chunks 已索引, 272 chunks 去重 (hard:4, exact:195, llm-skip:41, llm-merge:32), 0 errors
|
|
62
|
+
|
|
63
|
+
=== 2026-04-12 11:21:02 增量更新完成 ===
|
|
64
|
+
|
|
65
|
+
=== 2026-04-12 19:21:02 增量更新开始 ===
|
|
66
|
+
[INFO] LLM client initialized: qwen-turbo @ https://dashscope.aliyuncs.com/compatible-mode/v1
|
|
67
|
+
|
|
68
|
+
🔑 验证 Embedding API...
|
|
69
|
+
✅ jina-embeddings-v5-text-small (1024d)
|
|
70
|
+
✅ LLM: qwen-turbo (L0 摘要 + 语义去重)
|
|
71
|
+
✅ 两阶段去重: vector + LLM 语义判断
|
|
72
|
+
|
|
73
|
+
🔄 开始导入记忆 (source: all)...
|
|
74
|
+
|
|
75
|
+
📝 导入 Claude Code 对话...
|
|
76
|
+
✅ CC: 3 files, 55 ingested, 188 deduped (hard:2, exact:134, llm-skip:33, llm-merge:19), 0 errors
|
|
77
|
+
🤖 导入 Codex 对话...
|
|
78
|
+
✅ Codex: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
79
|
+
💎 导入 Gemini 对话...
|
|
80
|
+
✅ Gemini: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
81
|
+
🖥️ 导入 Claude Desktop 对话...
|
|
82
|
+
✅ Desktop: 0 files, 0 ingested, 0 deduped (hard:0, exact:0, llm-skip:0, llm-merge:0), 0 errors
|
|
83
|
+
📚 导入记忆文件...
|
|
84
|
+
✅ Memory: 1 files, 0 ingested, 182 deduped (hard:0, exact:171, llm-skip:11, llm-merge:0), 0 errors
|
|
85
|
+
|
|
86
|
+
📊 导入汇总:
|
|
87
|
+
总计: 55 chunks 已索引, 370 chunks 去重 (hard:2, exact:305, llm-skip:44, llm-merge:19), 0 errors
|
|
88
|
+
|
|
89
|
+
=== 2026-04-12 19:25:03 增量更新完成 ===
|
|
90
|
+
|
|
File without changes
|
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "recallnest",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "RecallNest \u2014 MCP-native, local-first memory search and distillation for AI conversations",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"recallnest": "
|
|
9
|
-
"local-memory": "
|
|
8
|
+
"recallnest": "bin/recallnest.mjs",
|
|
9
|
+
"local-memory": "bin/recallnest.mjs"
|
|
10
10
|
},
|
|
11
11
|
"scripts": {
|
|
12
12
|
"search": "bun run src/cli.ts search",
|
|
@@ -35,13 +35,20 @@
|
|
|
35
35
|
"ui": "bun run src/ui-server.ts",
|
|
36
36
|
"api": "bun run src/api-server.ts"
|
|
37
37
|
},
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18.0.0"
|
|
40
|
+
},
|
|
38
41
|
"dependencies": {
|
|
39
42
|
"@lancedb/lancedb": "^0.26.0",
|
|
40
43
|
"@modelcontextprotocol/sdk": "^1.27.1",
|
|
41
44
|
"commander": "^12.0.0",
|
|
42
45
|
"openai": "^4.0.0",
|
|
46
|
+
"tsx": "^4.19.0",
|
|
43
47
|
"zod": "^3.25.76"
|
|
44
48
|
},
|
|
49
|
+
"optionalDependencies": {
|
|
50
|
+
"babel-memory": ">=1.0.0"
|
|
51
|
+
},
|
|
45
52
|
"repository": {
|
|
46
53
|
"type": "git",
|
|
47
54
|
"url": "git+https://github.com/AliceLJY/recallnest.git"
|
package/src/access-tracker.ts
CHANGED
|
@@ -95,10 +95,11 @@ export class AccessTracker {
|
|
|
95
95
|
* Accumulates deltas in memory; flushed to store after debounce.
|
|
96
96
|
*
|
|
97
97
|
* @param ids Memory entry IDs to record access for
|
|
98
|
-
* @param scores Optional parallel array of similarity scores for novelty gating.
|
|
98
|
+
* @param scores Optional parallel array of raw similarity scores for novelty gating.
|
|
99
|
+
* Entries with an undefined score skip novelty gating.
|
|
99
100
|
* When provided, only entries passing shouldReinforce() are recorded.
|
|
100
101
|
*/
|
|
101
|
-
recordAccess(ids: string[], scores?: number
|
|
102
|
+
recordAccess(ids: string[], scores?: Array<number | undefined>): void {
|
|
102
103
|
if (ids.length === 0) return;
|
|
103
104
|
|
|
104
105
|
const now = Date.now();
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HP-3: Activity-driven distill frequency.
|
|
3
|
+
* Tracks write operations since last distill, exposes tier-based thresholds.
|
|
4
|
+
* Complements CC-6 distill-lock: HP-3 decides "when to trigger", CC-6 decides "whether to allow".
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
existsSync,
|
|
9
|
+
readFileSync,
|
|
10
|
+
writeFileSync,
|
|
11
|
+
mkdirSync,
|
|
12
|
+
} from "node:fs";
|
|
13
|
+
import { join, dirname } from "node:path";
|
|
14
|
+
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
// Config
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
export interface ActivityCounterConfig {
|
|
20
|
+
/** Path to the stats file (default: data/activity-stats.json) */
|
|
21
|
+
statsPath: string;
|
|
22
|
+
/** Writes needed for light scoring/tagging pass */
|
|
23
|
+
lightThreshold: number;
|
|
24
|
+
/** Writes needed for standard distill */
|
|
25
|
+
standardThreshold: number;
|
|
26
|
+
/** Writes needed for deep checkpoint */
|
|
27
|
+
deepThreshold: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const DEFAULT_ACTIVITY_CONFIG: ActivityCounterConfig = {
|
|
31
|
+
statsPath: join(
|
|
32
|
+
process.env.RECALLNEST_DATA_DIR || "data",
|
|
33
|
+
"activity-stats.json",
|
|
34
|
+
),
|
|
35
|
+
lightThreshold: 15,
|
|
36
|
+
standardThreshold: 50,
|
|
37
|
+
deepThreshold: 200,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type DistillTier = "none" | "light" | "standard" | "deep";
|
|
41
|
+
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
// Internal
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
|
|
46
|
+
interface ActivityStats {
|
|
47
|
+
writesSinceLastDistill: number;
|
|
48
|
+
lastResetAt: number;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function resolveConfig(
|
|
52
|
+
cfg?: Partial<ActivityCounterConfig>,
|
|
53
|
+
): ActivityCounterConfig {
|
|
54
|
+
return { ...DEFAULT_ACTIVITY_CONFIG, ...cfg };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function readStats(statsPath: string): ActivityStats {
|
|
58
|
+
if (!existsSync(statsPath)) {
|
|
59
|
+
return { writesSinceLastDistill: 0, lastResetAt: Date.now() };
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
return JSON.parse(readFileSync(statsPath, "utf-8"));
|
|
63
|
+
} catch {
|
|
64
|
+
return { writesSinceLastDistill: 0, lastResetAt: Date.now() };
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function writeStats(statsPath: string, stats: ActivityStats): void {
|
|
69
|
+
mkdirSync(dirname(statsPath), { recursive: true });
|
|
70
|
+
writeFileSync(statsPath, JSON.stringify(stats, null, 2), "utf-8");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
// Public API
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
|
|
77
|
+
/** Increment write counter by n (default 1). Returns new count. */
|
|
78
|
+
export function incrementWriteCount(
|
|
79
|
+
n = 1,
|
|
80
|
+
cfg?: Partial<ActivityCounterConfig>,
|
|
81
|
+
): number {
|
|
82
|
+
const { statsPath } = resolveConfig(cfg);
|
|
83
|
+
const stats = readStats(statsPath);
|
|
84
|
+
stats.writesSinceLastDistill += n;
|
|
85
|
+
writeStats(statsPath, stats);
|
|
86
|
+
return stats.writesSinceLastDistill;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** Read current write count without modifying. */
|
|
90
|
+
export function getWriteCount(cfg?: Partial<ActivityCounterConfig>): number {
|
|
91
|
+
const { statsPath } = resolveConfig(cfg);
|
|
92
|
+
return readStats(statsPath).writesSinceLastDistill;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/** Reset counter after successful distill. */
|
|
96
|
+
export function resetWriteCount(cfg?: Partial<ActivityCounterConfig>): void {
|
|
97
|
+
const { statsPath } = resolveConfig(cfg);
|
|
98
|
+
writeStats(statsPath, { writesSinceLastDistill: 0, lastResetAt: Date.now() });
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Determine which distill tier the current write count warrants. */
|
|
102
|
+
export function getDistillTier(cfg?: Partial<ActivityCounterConfig>): DistillTier {
|
|
103
|
+
const config = resolveConfig(cfg);
|
|
104
|
+
const count = getWriteCount(cfg);
|
|
105
|
+
if (count >= config.deepThreshold) return "deep";
|
|
106
|
+
if (count >= config.standardThreshold) return "standard";
|
|
107
|
+
if (count >= config.lightThreshold) return "light";
|
|
108
|
+
return "none";
|
|
109
|
+
}
|
|
@@ -44,15 +44,16 @@ export function shouldSkipRetrieval(query: string, minLength?: number): boolean
|
|
|
44
44
|
// Force retrieve if query has memory-related intent (BEFORE length check)
|
|
45
45
|
if (FORCE_RETRIEVE_PATTERNS.some(p => p.test(trimmed))) return false;
|
|
46
46
|
|
|
47
|
-
//
|
|
48
|
-
|
|
47
|
+
// CJK-aware: Chinese chars carry much more semantic density than ASCII.
|
|
48
|
+
// 2 Chinese chars ("轮巡") is a meaningful query equivalent to "daily patrol".
|
|
49
|
+
const hasCJK = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff]/.test(trimmed);
|
|
50
|
+
const absoluteMin = hasCJK ? 2 : 4;
|
|
51
|
+
if (trimmed.length < absoluteMin) return true;
|
|
49
52
|
|
|
50
53
|
// Pattern-based skip
|
|
51
54
|
if (SKIP_PATTERNS.some(p => p.test(trimmed))) return true;
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
const hasCJK = /[\u4e00-\u9fff\u3040-\u309f\u30a0-\u30ff]/.test(trimmed);
|
|
55
|
-
const effectiveMinLength = minLength ?? (hasCJK ? 6 : 15);
|
|
56
|
+
const effectiveMinLength = minLength ?? (hasCJK ? 2 : 15);
|
|
56
57
|
|
|
57
58
|
// Short non-question messages are skipped; questions (? ?) are always worth checking
|
|
58
59
|
if (trimmed.length < effectiveMinLength &&
|