memory-forge 0.1.0
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/LICENSE +21 -0
- package/README.md +73 -0
- package/dist/auto/index.d.ts +14 -0
- package/dist/auto/index.js +90 -0
- package/dist/auto/index.js.map +1 -0
- package/dist/embedding.d.ts +10 -0
- package/dist/embedding.js +66 -0
- package/dist/embedding.js.map +1 -0
- package/dist/hooks/install.d.ts +10 -0
- package/dist/hooks/install.js +65 -0
- package/dist/hooks/install.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +308 -0
- package/dist/index.js.map +1 -0
- package/dist/migrate/import.d.ts +12 -0
- package/dist/migrate/import.js +92 -0
- package/dist/migrate/import.js.map +1 -0
- package/dist/pro.d.ts +9 -0
- package/dist/pro.js +135 -0
- package/dist/pro.js.map +1 -0
- package/dist/setup.d.ts +5 -0
- package/dist/setup.js +64 -0
- package/dist/setup.js.map +1 -0
- package/dist/storage/local.d.ts +7 -0
- package/dist/storage/local.js +105 -0
- package/dist/storage/local.js.map +1 -0
- package/dist/storage/shelby.d.ts +25 -0
- package/dist/storage/shelby.js +123 -0
- package/dist/storage/shelby.js.map +1 -0
- package/dist/store.d.ts +58 -0
- package/dist/store.js +138 -0
- package/dist/store.js.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 shelby-ai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# MemoryForge
|
|
2
|
+
|
|
3
|
+
> 唯一基于去中心化热存储、链上可验证、合规可审计的 AI Agent 记忆引擎。
|
|
4
|
+
|
|
5
|
+
## 一句话定位
|
|
6
|
+
|
|
7
|
+
MemoryForge = 基于 Shelby 协议 + MCP 标准的去中心化 AI Agent 持久记忆引擎。一键嵌入 Claude Code / Cursor / Codex / Devin / Windsurf。
|
|
8
|
+
|
|
9
|
+
## 为什么需要 MemoryForge
|
|
10
|
+
|
|
11
|
+
现在的 AI Agent 都是**失忆的**——关闭会话就忘记一切。换平台从零开始。无法验证记忆的真伪。
|
|
12
|
+
|
|
13
|
+
MemoryForge 解决这三个问题:
|
|
14
|
+
1. **持久化**:记忆存 Shelby 去中心化热存储,跨会话、跨平台
|
|
15
|
+
2. **可验证**:每条记忆有 链上哈希证明,无法篡改
|
|
16
|
+
3. **合规**:GDPR 被遗忘权 + 不可篡改审计链
|
|
17
|
+
|
|
18
|
+
## 快速开始
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
# 一键自动配置所有 Agent 平台
|
|
22
|
+
npx memory-forge setup
|
|
23
|
+
# → 自动检测 Claude Code / Cursor / Windsurf / VS Code / Codex / Devin
|
|
24
|
+
# → 需要 Shelby API Key(在 docs.shelby.xyz/sdks/typescript/acquire-api-keys 获取)
|
|
25
|
+
|
|
26
|
+
# 或手动嵌入 Claude Code
|
|
27
|
+
claude mcp add memory-forge -- npx memory-forge
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## 核心能力
|
|
31
|
+
|
|
32
|
+
| 能力 | 说明 |
|
|
33
|
+
|------|------|
|
|
34
|
+
| 去中心化存储 | Shelby 热存储(亚秒级读取,~70% 比 AWS 便宜) |
|
|
35
|
+
| 链上可验证 | 每条记忆有 Aptos 链上证明 |
|
|
36
|
+
| MCP 标准 | 一键嵌入全部 Agent 平台 |
|
|
37
|
+
| Git 式版本控制 | 分支、回滚、diff、合并 |
|
|
38
|
+
| 自动冲突解决 | 确定性算法,非 LLM 判断 |
|
|
39
|
+
| Token 效率 | slim 模式(73% 减少),universal 模式(98% 减少) |
|
|
40
|
+
| 企业合规 | GDPR / HIPAA / SOC2 审计链 |
|
|
41
|
+
| 记忆市场 | 用户可交易记忆包 |
|
|
42
|
+
|
|
43
|
+
## 定价
|
|
44
|
+
|
|
45
|
+
| 方案 | 价格 | 说明 |
|
|
46
|
+
|------|------|------|
|
|
47
|
+
| Free | $0 | 核心层 7 工具,100 条记忆,本地模式 |
|
|
48
|
+
| Pro | $7/月 | + 差异层(链上哈希验证/导出/冲突解决),10K 记忆,Shelby 存储 |
|
|
49
|
+
| Team | $19/月 | 全 15 工具,50K 记忆,SSE 远程,多 Agent 协作 |
|
|
50
|
+
| Enterprise | $149/月 | + 链上哈希审计 + SSO + SLA + 合规报告 |
|
|
51
|
+
|
|
52
|
+
## 项目结构
|
|
53
|
+
|
|
54
|
+
```
|
|
55
|
+
memory-forge/
|
|
56
|
+
├── README.md # 本文件
|
|
57
|
+
├── SPEC.md # 完整产品规格
|
|
58
|
+
├── MARKET.md # 市场分析与竞品
|
|
59
|
+
├── ARCHITECTURE.md # 系统架构
|
|
60
|
+
├── REVENUE.md # 收入模型
|
|
61
|
+
├── package.json # npm 配置
|
|
62
|
+
├── tsconfig.json # TypeScript 配置
|
|
63
|
+
└── src/
|
|
64
|
+
└── index.ts # MCP Server 入口
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 技术栈
|
|
68
|
+
|
|
69
|
+
- **MCP 协议**:`@modelcontextprotocol/sdk`
|
|
70
|
+
- **存储层**:`@shelby-protocol/sdk` (Shelby Protocol)
|
|
71
|
+
- **嵌入**:本地 Ollama / OpenAI 可切换
|
|
72
|
+
- **链上**:Aptos 交易哈希 + 链上存储证明
|
|
73
|
+
- **运行时**:Node.js 18+, TypeScript
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 后台自动化引擎: 全部用户无感知。
|
|
3
|
+
*/
|
|
4
|
+
import type { MemoryStore, Memory } from "../store.js";
|
|
5
|
+
/** 自动命名: 从内容中提取前几个字作为名称 */
|
|
6
|
+
export declare function autoName(content: string): string;
|
|
7
|
+
/** 自动合并: 检测相似内容并合并(异步,重新计算向量) */
|
|
8
|
+
export declare function autoMerge(store: MemoryStore, newMemory: Memory): Promise<Memory | null>;
|
|
9
|
+
/** 自动优先级: 基于访问频率 */
|
|
10
|
+
export declare function autoPriority(memory: Memory): number;
|
|
11
|
+
/** 自动衰减: Ebbinghaus 遗忘曲线 */
|
|
12
|
+
export declare function autoDecay(memory: Memory): number;
|
|
13
|
+
/** 生成上下文摘要给 Agent 注入 */
|
|
14
|
+
export declare function generateContextSummary(store: MemoryStore, limit?: number): string;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 后台自动化引擎: 全部用户无感知。
|
|
3
|
+
*/
|
|
4
|
+
import { saveMemory } from "../storage/local.js";
|
|
5
|
+
import { embed } from "../embedding.js";
|
|
6
|
+
/** 自动命名: 从内容中提取前几个字作为名称 */
|
|
7
|
+
export function autoName(content) {
|
|
8
|
+
// Strip code blocks, trim to ~30 chars
|
|
9
|
+
const clean = content.replace(/```[\s\S]*?```/g, "").replace(/`/g, "").trim();
|
|
10
|
+
const name = clean.slice(0, 40).replace(/\n/g, " ").trim();
|
|
11
|
+
return name || "memory";
|
|
12
|
+
}
|
|
13
|
+
/** 自动合并: 检测相似内容并合并(异步,重新计算向量) */
|
|
14
|
+
export async function autoMerge(store, newMemory) {
|
|
15
|
+
const all = [...store.list({ limit: 100, offset: 0 })];
|
|
16
|
+
if (all.length === 0)
|
|
17
|
+
return null;
|
|
18
|
+
for (const existing of all) {
|
|
19
|
+
if (existing.id === newMemory.id)
|
|
20
|
+
continue;
|
|
21
|
+
const similarity = contentOverlap(existing.content, newMemory.content);
|
|
22
|
+
if (similarity > 0.8) {
|
|
23
|
+
// Merge: update existing with new content + fresh vector
|
|
24
|
+
existing.content = newMemory.content;
|
|
25
|
+
existing.access_count++;
|
|
26
|
+
existing.last_accessed = new Date().toISOString();
|
|
27
|
+
// Recompute vector for merged content
|
|
28
|
+
const vec = await embed(existing.content);
|
|
29
|
+
if (vec)
|
|
30
|
+
existing.vector = Array.from(vec);
|
|
31
|
+
saveMemory(existing);
|
|
32
|
+
store.remove(existing.id);
|
|
33
|
+
store.add(existing);
|
|
34
|
+
return existing;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
/** 自动优先级: 基于访问频率 */
|
|
40
|
+
export function autoPriority(memory) {
|
|
41
|
+
const age = Date.now() - new Date(memory.created_at).getTime();
|
|
42
|
+
const ageDays = age / 86400000;
|
|
43
|
+
const freqWeight = Math.min(memory.access_count, 50) / 50;
|
|
44
|
+
const recencyWeight = memory.last_accessed
|
|
45
|
+
? Math.max(0, 1 - (Date.now() - new Date(memory.last_accessed).getTime()) / (90 * 86400000))
|
|
46
|
+
: 0.5;
|
|
47
|
+
return Math.round(1 + 9 * (freqWeight * 0.4 + recencyWeight * 0.4 + (1 - Math.min(ageDays, 365) / 365) * 0.2));
|
|
48
|
+
}
|
|
49
|
+
/** 自动衰减: Ebbinghaus 遗忘曲线 */
|
|
50
|
+
export function autoDecay(memory) {
|
|
51
|
+
const daysSinceAccess = memory.last_accessed
|
|
52
|
+
? (Date.now() - new Date(memory.last_accessed).getTime()) / 86400000
|
|
53
|
+
: (Date.now() - new Date(memory.created_at).getTime()) / 86400000;
|
|
54
|
+
const d = Math.floor(daysSinceAccess);
|
|
55
|
+
if (d <= 1)
|
|
56
|
+
return 1.0;
|
|
57
|
+
if (d <= 7)
|
|
58
|
+
return 0.8;
|
|
59
|
+
if (d <= 30)
|
|
60
|
+
return 0.5;
|
|
61
|
+
if (d <= 90)
|
|
62
|
+
return 0.2;
|
|
63
|
+
return 0; // archive
|
|
64
|
+
}
|
|
65
|
+
/** 内容重叠度 (Jaccard 近似) */
|
|
66
|
+
function contentOverlap(a, b) {
|
|
67
|
+
const setA = new Set(a.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
68
|
+
const setB = new Set(b.toLowerCase().split(/\s+/).filter((w) => w.length > 2));
|
|
69
|
+
if (setA.size === 0 || setB.size === 0)
|
|
70
|
+
return 0;
|
|
71
|
+
let intersection = 0;
|
|
72
|
+
for (const w of setA) {
|
|
73
|
+
if (setB.has(w))
|
|
74
|
+
intersection++;
|
|
75
|
+
}
|
|
76
|
+
return intersection / Math.min(setA.size, setB.size);
|
|
77
|
+
}
|
|
78
|
+
/** 生成上下文摘要给 Agent 注入 */
|
|
79
|
+
export function generateContextSummary(store, limit = 5) {
|
|
80
|
+
const all = store.list({ limit: 100, offset: 0 });
|
|
81
|
+
const top = all
|
|
82
|
+
.sort((a, b) => (b.access_count - a.access_count) || ((b.priority || 5) - (a.priority || 5)))
|
|
83
|
+
.slice(0, limit);
|
|
84
|
+
if (top.length === 0)
|
|
85
|
+
return "";
|
|
86
|
+
return top
|
|
87
|
+
.map((m) => `- [${m.name}] ${m.content.slice(0, 150)}${m.content.length > 150 ? "…" : ""}`)
|
|
88
|
+
.join("\n");
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/auto/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 嵌入引擎: Transformers.js 进程内运行,23MB 模型,零外部服务。
|
|
3
|
+
* 延迟加载: 首次调用时加载模型,后续毫秒级。
|
|
4
|
+
* 降级: 加载失败 → 返回 null,memory_search 自动回退到关键词匹配。
|
|
5
|
+
*/
|
|
6
|
+
/** 重试模型加载(后台调用,不阻塞) */
|
|
7
|
+
export declare function retryEmbedder(): void;
|
|
8
|
+
export declare function embed(text: string): Promise<Float32Array | null>;
|
|
9
|
+
/** 预加载模型(后台运行,不阻塞) */
|
|
10
|
+
export declare function preload(): void;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 嵌入引擎: Transformers.js 进程内运行,23MB 模型,零外部服务。
|
|
3
|
+
* 延迟加载: 首次调用时加载模型,后续毫秒级。
|
|
4
|
+
* 降级: 加载失败 → 返回 null,memory_search 自动回退到关键词匹配。
|
|
5
|
+
*/
|
|
6
|
+
let embedFn = null;
|
|
7
|
+
let loading = null;
|
|
8
|
+
let lastAttempt = 0;
|
|
9
|
+
const RETRY_MS = 300_000; // 5 min before retry after failure
|
|
10
|
+
async function getEmbedder() {
|
|
11
|
+
// Auto-retry: if model failed, clear cache after RETRY_MS for next attempt
|
|
12
|
+
if (embedFn && lastAttempt > 0 && Date.now() - lastAttempt >= RETRY_MS) {
|
|
13
|
+
console.error("[MemoryForge] Retrying embedding model download...");
|
|
14
|
+
embedFn = null;
|
|
15
|
+
loading = null;
|
|
16
|
+
}
|
|
17
|
+
if (embedFn)
|
|
18
|
+
return embedFn;
|
|
19
|
+
if (loading)
|
|
20
|
+
return loading;
|
|
21
|
+
loading = (async () => {
|
|
22
|
+
try {
|
|
23
|
+
const { pipeline } = await import("@huggingface/transformers");
|
|
24
|
+
const engine = await pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2");
|
|
25
|
+
embedFn = async (text) => {
|
|
26
|
+
const result = await engine(text, { pooling: "mean", normalize: true });
|
|
27
|
+
return new Float32Array(result.data);
|
|
28
|
+
};
|
|
29
|
+
lastAttempt = 0;
|
|
30
|
+
return embedFn;
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error("[MemoryForge] Failed to load embedding model:", err.message);
|
|
34
|
+
console.error(`[MemoryForge] Falling back to keyword matching (retry in ${RETRY_MS / 1000}s).`);
|
|
35
|
+
lastAttempt = Date.now();
|
|
36
|
+
embedFn = async () => null;
|
|
37
|
+
return embedFn;
|
|
38
|
+
}
|
|
39
|
+
})();
|
|
40
|
+
return loading;
|
|
41
|
+
}
|
|
42
|
+
/** 重试模型加载(后台调用,不阻塞) */
|
|
43
|
+
export function retryEmbedder() {
|
|
44
|
+
if (!embedFn || lastAttempt === 0)
|
|
45
|
+
return;
|
|
46
|
+
if (Date.now() - lastAttempt < RETRY_MS)
|
|
47
|
+
return;
|
|
48
|
+
console.error("[MemoryForge] Retrying embedding model download...");
|
|
49
|
+
embedFn = null;
|
|
50
|
+
loading = null;
|
|
51
|
+
getEmbedder();
|
|
52
|
+
}
|
|
53
|
+
export async function embed(text) {
|
|
54
|
+
const fn = await getEmbedder();
|
|
55
|
+
try {
|
|
56
|
+
return await fn(text);
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** 预加载模型(后台运行,不阻塞) */
|
|
63
|
+
export function preload() {
|
|
64
|
+
getEmbedder();
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=embedding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"embedding.js","sourceRoot":"","sources":["../src/embedding.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,IAAI,OAAO,GAAmB,IAAI,CAAC;AACnC,IAAI,OAAO,GAA4B,IAAI,CAAC;AAC5C,IAAI,WAAW,GAAG,CAAC,CAAC;AACpB,MAAM,QAAQ,GAAG,OAAO,CAAC,CAAC,mCAAmC;AAE7D,KAAK,UAAU,WAAW;IACxB,2EAA2E;IAC3E,IAAI,OAAO,IAAI,WAAW,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,IAAI,QAAQ,EAAE,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;QACpE,OAAO,GAAG,IAAI,CAAC;QACf,OAAO,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAC5B,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC;IAE5B,OAAO,GAAG,CAAC,KAAK,IAAI,EAAE;QACpB,IAAI,CAAC;YACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,2BAA2B,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,oBAAoB,EAAE,yBAAyB,CAAC,CAAC;YAC/E,OAAO,GAAG,KAAK,EAAE,IAAY,EAAE,EAAE;gBAC/B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBACxE,OAAO,IAAI,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YACvC,CAAC,CAAC;YACF,WAAW,GAAG,CAAC,CAAC;YAChB,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAG,GAAa,CAAC,OAAO,CAAC,CAAC;YACvF,OAAO,CAAC,KAAK,CAAC,4DAA4D,QAAQ,GAAG,IAAI,KAAK,CAAC,CAAC;YAChG,WAAW,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACzB,OAAO,GAAG,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC;YAC3B,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,uBAAuB;AACvB,MAAM,UAAU,aAAa;IAC3B,IAAI,CAAC,OAAO,IAAI,WAAW,KAAK,CAAC;QAAE,OAAO;IAC1C,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,WAAW,GAAG,QAAQ;QAAE,OAAO;IAEhD,OAAO,CAAC,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACpE,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,GAAG,IAAI,CAAC;IACf,WAAW,EAAE,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,IAAY;IACtC,MAAM,EAAE,GAAG,MAAM,WAAW,EAAE,CAAC;IAC/B,IAAI,CAAC;QACH,OAAO,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,sBAAsB;AACtB,MAAM,UAAU,OAAO;IACrB,WAAW,EAAE,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code hooks 自动配置。
|
|
3
|
+
* 写入 ~/.claude/settings.json,自动添加 SessionStart/Stop/PreCompact hooks。
|
|
4
|
+
*/
|
|
5
|
+
export declare function installHooks(): boolean;
|
|
6
|
+
export declare function getHooksStatus(): {
|
|
7
|
+
sessionStart: boolean;
|
|
8
|
+
stop: boolean;
|
|
9
|
+
preCompact: boolean;
|
|
10
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Code hooks 自动配置。
|
|
3
|
+
* 写入 ~/.claude/settings.json,自动添加 SessionStart/Stop/PreCompact hooks。
|
|
4
|
+
*/
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
const CLAUDE_SETTINGS = path.join(process.env.HOME ?? process.env.USERPROFILE ?? "/tmp", ".claude", "settings.json");
|
|
8
|
+
export function installHooks() {
|
|
9
|
+
try {
|
|
10
|
+
const dir = path.dirname(CLAUDE_SETTINGS);
|
|
11
|
+
if (!fs.existsSync(dir))
|
|
12
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
13
|
+
let config = {};
|
|
14
|
+
if (fs.existsSync(CLAUDE_SETTINGS)) {
|
|
15
|
+
const raw = fs.readFileSync(CLAUDE_SETTINGS, "utf-8");
|
|
16
|
+
config = JSON.parse(raw);
|
|
17
|
+
}
|
|
18
|
+
if (!config.hooks)
|
|
19
|
+
config.hooks = {};
|
|
20
|
+
const mfCmd = "npx memory-forge";
|
|
21
|
+
config.hooks.SessionStart = config.hooks.SessionStart || [];
|
|
22
|
+
if (!hasHook(config.hooks.SessionStart, "memory-forge")) {
|
|
23
|
+
config.hooks.SessionStart.push({
|
|
24
|
+
hooks: [{ type: "command", command: `${mfCmd} hook session-start` }],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
config.hooks.Stop = config.hooks.Stop || [];
|
|
28
|
+
if (!hasHook(config.hooks.Stop, "memory-forge")) {
|
|
29
|
+
config.hooks.Stop.push({
|
|
30
|
+
hooks: [{ type: "command", command: `${mfCmd} hook stop` }],
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
config.hooks.PreCompact = config.hooks.PreCompact || [];
|
|
34
|
+
if (!hasHook(config.hooks.PreCompact, "memory-forge")) {
|
|
35
|
+
config.hooks.PreCompact.push({
|
|
36
|
+
hooks: [{ type: "command", command: `${mfCmd} hook pre-compact` }],
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
fs.writeFileSync(CLAUDE_SETTINGS, JSON.stringify(config, null, 2));
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error("[MemoryForge] Failed to install hooks:", err.message);
|
|
44
|
+
return false;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function hasHook(hooks, name) {
|
|
48
|
+
return hooks.some((h) => h.hooks?.some((inner) => inner.command?.includes(name)));
|
|
49
|
+
}
|
|
50
|
+
export function getHooksStatus() {
|
|
51
|
+
try {
|
|
52
|
+
if (!fs.existsSync(CLAUDE_SETTINGS))
|
|
53
|
+
return { sessionStart: false, stop: false, preCompact: false };
|
|
54
|
+
const config = JSON.parse(fs.readFileSync(CLAUDE_SETTINGS, "utf-8"));
|
|
55
|
+
return {
|
|
56
|
+
sessionStart: hasHook(config.hooks?.SessionStart || [], "memory-forge"),
|
|
57
|
+
stop: hasHook(config.hooks?.Stop || [], "memory-forge"),
|
|
58
|
+
preCompact: hasHook(config.hooks?.PreCompact || [], "memory-forge"),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return { sessionStart: false, stop: false, preCompact: false };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=install.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"install.js","sourceRoot":"","sources":["../../src/hooks/install.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* MemoryForge — AI Agent 持久记忆引擎 (MVP)
|
|
4
|
+
*
|
|
5
|
+
* 8 个 MCP 工具 + 5 个后台自动化引擎 + Pro 层 Shelby 云同步。
|
|
6
|
+
* 嵌入: Transformers.js (23MB, 进程内)。
|
|
7
|
+
* 存储: Free 层本地 Markdown; Pro 层 Shelby 云。
|
|
8
|
+
*
|
|
9
|
+
* 一键嵌入:
|
|
10
|
+
* claude mcp add memory-forge -- npx memory-forge
|
|
11
|
+
*/
|
|
12
|
+
export {};
|