@hippo-memo/cli 1.0.1 → 1.0.3

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.
@@ -15,8 +15,14 @@ Hippo Memory 的预设内存模板集合。
15
15
  ```
16
16
  template/
17
17
  ├── mcp/ # MCP 服务器相关模板
18
- │ └── system/ # 系统级内存模板
18
+ │ └── AGENTS.md # MCP 协议配置
19
+ ├── skill/ # Claude Code Skill 模板
20
+ │ ├── hippo-memory/ # 记忆管理技能
21
+ │ └── hippo-init/ # 初始化引导技能
19
22
  └── system/ # 通用系统模板
23
+ ├── agent.md # AI 能力边界
24
+ ├── soul.md # AI 身份和行为模式
25
+ └── user.md # 用户信息和偏好
20
26
  ```
21
27
 
22
28
  ## 系统模板
@@ -50,4 +56,38 @@ AI 能力边界定义
50
56
 
51
57
  ## 使用方式
52
58
 
53
- 模板通常在初始化新的 Hippo Memory 实例时自动应用,通过 `@hippo-memo/core` 包的初始化功能加载。
59
+ ### CLI 初始化
60
+
61
+ 运行 `hippo init` 时会自动:
62
+
63
+ 1. 创建 `.hippo` 记忆存储目录
64
+ 2. 初始化系统记忆(system://boot, system://soul, system://user)
65
+ 3. 提示选择 Claude Code 集成方式:
66
+ - **MCP 模式**:将协议注入到 `AGENTS.md` 或 `CLAUDE.md`
67
+ - **Skill 模式**:复制技能模板到 `.claude/skills/`
68
+ - **混合模式**:同时配置 MCP 和 Skill
69
+
70
+ ### MCP vs Skill
71
+
72
+ | 特性 | MCP | Skill |
73
+ |------|-----|-------|
74
+ | **作用域** | 全局/用户级 | 项目级 |
75
+ | **存储位置** | Claude 配置目录 | `.claude/skills/` |
76
+ | **版本控制** | 不推荐 | 推荐 |
77
+ | **适用场景** | 跨项目共享 | 项目特定流程 |
78
+
79
+ ### 技能说明
80
+
81
+ #### hippo-memory
82
+ 提供完整的 Hippo Memory 操作指南,包括:
83
+ - 创建、读取、更新、删除记忆
84
+ - 搜索记忆内容
85
+ - 管理记忆别名
86
+ - URI 设计规范和最佳实践
87
+
88
+ #### hippo-init
89
+ 项目初始化引导技能,包括:
90
+ - 记忆目录创建
91
+ - MCP vs Skill 选择指导
92
+ - 配置文件说明
93
+ - 故障排查
@@ -0,0 +1,21 @@
1
+ # 🧠 Hippo Memory
2
+
3
+ **hippo-memory** 是项目的持久记忆层 skill,用于存储用户偏好、项目上下文、技术决策等跨会话信息。
4
+
5
+ ## ⚡ 会话启动
6
+
7
+ **每次新会话必须检索系统引导记忆,了解用户偏好、项目上下文和核心配置。**
8
+
9
+ ## 🎯 调用指南
10
+
11
+ **触发场景:**
12
+ - 用户询问或提及任何可被记忆的信息(偏好、配置、决策、历史、上下文等)
13
+ - 关键词命中:我/我的/习惯/喜欢/选择/决定/记住/保存/my/I prefer/remember/save/previous/architecture/config/settings/架构/配置/规范
14
+ - 用户透露任何可存储的信息(新的偏好、决策、习惯、技术选型等)
15
+ - 回答涉及用户私有信息时需要验证
16
+
17
+ **核心原则:**
18
+ - 涉及用户私有信息时,必须先检索记忆,禁止猜测
19
+ - 用户透露新信息时,立即存储到记忆
20
+
21
+ ---
@@ -0,0 +1,257 @@
1
+ ---
2
+ name: hippo-memory
3
+ description: "🧠 Persistent memory layer. ALWAYS ACTIVE: (1) SEARCH when user asks about memorable info, (2) STORE when user reveals storable info. Keywords: 我/我的/习惯/喜欢/选择/决定/记住/保存/my/I prefer/remember/save/previous/architecture/config/架构/配置. Never guess without searching."
4
+ ---
5
+
6
+ # Hippo Memory Skill
7
+
8
+ ## 概述
9
+
10
+ 此技能提供 Hippo Memory 存储系统的管理功能,通过 `bunx @hippo-memo/cli@latest` 命令进行记忆的增删改查、搜索和别名操作。
11
+
12
+ ## ⚡ 会话启动协议
13
+
14
+ **每次新会话必须且只能执行:**
15
+ ```bash
16
+ bunx @hippo-memo/cli@latest memory read "system://boot"
17
+ ```
18
+
19
+ ## 🎯 "三思而后答"强制检查
20
+
21
+ **回复前必须完成以下思维链:**
22
+
23
+ | 检查项 | 判定 | 动作 |
24
+ |--------|------|------|
25
+ | **A. 领域** | 用户询问私有记忆/历史/偏好? | → 立即检索 |
26
+ | **B. 完备性** | 我有确凿证据支撑回答? | → 不确定则先验证 |
27
+ | **C. 决策** | A=B=是 | → **调用 CLI 后再输出** |
28
+
29
+ **违规 = 任务失败**
30
+
31
+ ## 🏗️ 系统节点
32
+
33
+ 推荐创建以下系统级记忆节点:
34
+
35
+ | URI | 作用 |
36
+ |-----|------|
37
+ | `system://boot` | 会话入口,合成核心摘要 |
38
+ | `system://soul` | 身份/行为模式 |
39
+ | `system://user` | 用户信息/偏好 |
40
+ | `system://project` | 项目核心信息 |
41
+ | `system://recent` | 近期事件 |
42
+
43
+ ## 📖 读取协议:检索优先
44
+
45
+ ### 必须检索的触发条件(任一)
46
+ 1. 用户提到:项目名、人名、过往约定
47
+ 2. 问题包含:"我记得"、"之前说过"、"我的配置"
48
+ 3. 涉及时间线:"上周"、"上次"
49
+ 4. disclosure 被触发
50
+ 5. 回答依赖"可能"、"大概"
51
+
52
+ ### 检索策略
53
+ ```bash
54
+ # 确切 URI
55
+ bunx @hippo-memo/cli@latest memory read "system://user"
56
+
57
+ # 大致位置
58
+ bunx @hippo-memo/cli@latest memory search "数据库"
59
+
60
+ # 不确定 - 多个关键词尝试
61
+ bunx @hippo-memo/cli@latest memory search "上周 项目 数据库"
62
+ ```
63
+
64
+ ### ❌ 禁止
65
+ - 基于通用知识回答私有信息
66
+ - 使用"可能"、"大概"而不验证
67
+ - 未检索时说"我记得..."
68
+
69
+ ### ✅ 正确
70
+ 调用 CLI → "根据您的记录..."
71
+
72
+ ## ✍️ 写入协议
73
+
74
+ ### create_memory 触发条件
75
+ - 新的重要认知/感悟
76
+ - 用户透露重要信息
77
+ - 发生重大事件
78
+ - 跨会话复用的结论
79
+
80
+ ### update_memory 触发条件
81
+ - **必须先 `memory read`**,再修正
82
+ - 发现过去认知错误
83
+ - 用户纠正你
84
+ - 信息过时
85
+
86
+ **铁律:改记忆前,先读记忆。**
87
+
88
+ ## URI 设计规范
89
+
90
+ ### 域名分类
91
+ - `system://` - 系统级记忆(身份、配置)
92
+ - `project://` - 项目级记忆(架构、决策)
93
+ - `user://` - 用户级记忆(偏好、习惯)
94
+ - `knowledge://` - 知识库(技术文档、最佳实践)
95
+ - `temp://` - 临时记忆(会话缓存)
96
+
97
+ ### 路径设计
98
+ ```
99
+ system://boot
100
+ system://soul
101
+ system://user/preferences
102
+ system://project/{project-name}
103
+ project://myapp/architecture/database
104
+ user://preferences/pkg-manager
105
+ knowledge://tech/auth-jwt
106
+ temp://session/cache
107
+ ```
108
+
109
+ ## CLI 命令
110
+
111
+ ### 1. 创建记忆
112
+ ```bash
113
+ bunx @hippo-memo/cli@latest memory create "user://note/test" "# 测试笔记\n这是内容"
114
+ ```
115
+ 选项:
116
+ - `-p, --priority <1-10>` - 优先级(默认: 5)
117
+ - `-d, --disclosure <string>` - 触发条件
118
+ - `--dir <directory>` - 记忆目录(默认: .memory)
119
+
120
+ ### 2. 读取记忆
121
+ ```bash
122
+ bunx @hippo-memo/cli@latest memory read "user://note/test"
123
+ ```
124
+
125
+ ### 3. 更新记忆
126
+ ```bash
127
+ bunx @hippo-memo/cli@latest memory update "user://note/test" "更新内容"
128
+ ```
129
+ 选项:
130
+ - `-p, --priority <1-10>` - 更新优先级
131
+ - `-d, --disclosure <string>` - 更新触发条件
132
+
133
+ ### 4. 删除记忆
134
+ ```bash
135
+ bunx @hippo-memo/cli@latest memory delete "user://note/test"
136
+ ```
137
+ 选项:
138
+ - `-r, --recursive` - 递归删除子记忆
139
+ - `--permanent` - 永久删除(不进入回收站)
140
+
141
+ ### 5. 搜索记忆
142
+ ```bash
143
+ bunx @hippo-memo/cli@latest memory search "测试"
144
+ ```
145
+ 选项:
146
+ - `--domain <string>` - 限定域名
147
+ - `-l, --limit <number>` - 结果数量(默认: 20)
148
+
149
+ ### 6. 列出所有记忆
150
+ ```bash
151
+ bunx @hippo-memo/cli@latest memory list
152
+ ```
153
+ 选项:
154
+ - `--domain <string>` - 限定域名
155
+
156
+ ### 7. 添加别名
157
+ ```bash
158
+ bunx @hippo-memo/cli@latest memory alias "alias://test" "user://note/test"
159
+ ```
160
+ 选项:
161
+ - `-p, --priority <1-10>` - 别名优先级(继承目标默认)
162
+ - `-d, --disclosure <string>` - 别名触发条件
163
+
164
+ ## 🔄 结构操作
165
+
166
+ ```bash
167
+ # 移动/重命名:先建后删
168
+ bunx @hippo-memo/cli@latest memory alias "new" "old"
169
+ bunx @hippo-memo/cli@latest memory delete "old"
170
+
171
+ # 删除前:先读确认
172
+ bunx @hippo-memo/cli@latest memory read "to_delete"
173
+ bunx @hippo-memo/cli@latest memory delete "to_delete"
174
+
175
+ # 多重入口
176
+ bunx @hippo-memo/cli@latest memory alias "path/a" "path/b"
177
+ bunx @hippo-memo/cli@latest memory alias "path/c" "path/b"
178
+ ```
179
+
180
+ ## 最佳实践
181
+
182
+ ### 优先级指南
183
+ | 级别 | 含义 | 上限 | 示例 |
184
+ |------|------|------|------|
185
+ | **10** | 核心身份 | 5条 | `system://boot`, `system://soul` |
186
+ | **8-9** | 关键事实/高频模式 | 15条 | 用户偏好、项目架构决策 |
187
+ | **5-7** | 一般记忆 | 无限制 | 技术文档、会议记录 |
188
+ | **1-4** | 冷门信息 | 无限制 | 临时缓存、调试信息 |
189
+
190
+ ### Disclosure 规范
191
+ Disclosure 定义了记忆的自动触发条件,帮助 LLM 主动检索:
192
+
193
+ ✅ **好的 disclosure**:
194
+ ```
195
+ "当用户提到项目 hippo 时"
196
+ "当讨论包管理器选择时"
197
+ "当周五或周末安排任务时"
198
+ "当实现认证功能时"
199
+ ```
200
+
201
+ ❌ **不好的 disclosure**:
202
+ ```
203
+ "重要"
204
+ "记住"
205
+ "用户信息"
206
+ "配置"
207
+ ```
208
+
209
+ ### 主动触发场景
210
+
211
+ | 场景 | 示例输入 | 存储动作 |
212
+ |------|----------|----------|
213
+ | **显性请求** | "记住我周末不工作" | `memory create "user://availability/weekend" ...` |
214
+ | **偏好表达** | "我喜欢用 pnpm" | `memory create "user://pref/pkg-manager" "pnpm" --disclosure "当选择包管理器时"` |
215
+ | **架构决策** | "这个项目用 PostgreSQL" | `memory create "project://myapp/database" "PostgreSQL 15+" --disclosure "当讨论数据库时"` |
216
+ | **技术约定** | "组件都用 shadcn/ui" | `memory create "project://myapp/ui-lib" "shadcn/ui" --disclosure "当创建 UI 组件时"` |
217
+
218
+ ## 🎭 Few-Shot 示例
219
+
220
+ ### 检索优先
221
+ ```
222
+ 用户:"我上周项目用的什么数据库?"
223
+
224
+ ❌ "可能是 PostgreSQL..."
225
+ ✅ bunx @hippo-memo/cli@latest memory search "上周 项目 数据库"
226
+ → bunx @hippo-memo/cli@latest memory read "..."
227
+ → "根据记录,用的是 MongoDB"
228
+ ```
229
+
230
+ ### Disclosure 触发
231
+ ```
232
+ 用户:"我要实现登录功能"
233
+
234
+ ✅ 检测到"登录"
235
+ → bunx @hippo-memo/cli@latest memory read "knowledge/auth"
236
+ → "您之前确定用 JWT 方案,对吗?"
237
+ ```
238
+
239
+ ### 写入新记忆
240
+ ```
241
+ 用户:"我周末不工作"
242
+
243
+ ✅ bunx @hippo-memo/cli@latest memory create \
244
+ "user://availability/weekend" \
245
+ "用户周末不工作,周一处理" \
246
+ --priority 8 \
247
+ --disclosure "当周五/周末安排任务时"
248
+ ```
249
+
250
+ ## 🔚 回复前自检
251
+
252
+ - [ ] 涉及私有信息?→ 调用 `memory read`/`memory search`
253
+ - [ ] 不确定?→ 先验证而非猜测
254
+ - [ ] 用户新信息?→ 立即 `memory create`
255
+ - [ ] 引用记忆?→ 标注来源 URI
256
+
257
+ **全部通过 → 输出 | 任一未通过 → 先执行 CLI**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hippo-memo/cli",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "hippo": "./dist/index.js"
@@ -16,6 +16,7 @@
16
16
  },
17
17
  "devDependencies": {
18
18
  "@types/node": "^20",
19
+ "@types/prompts": "^2.4.9",
19
20
  "concurrently": "^9.2.1",
20
21
  "typescript": "^5"
21
22
  }
@@ -1,2 +1,3 @@
1
1
  export * from "./init";
2
+ export * from "./memory";
2
3
  export * from "./web";
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  access,
3
3
  constants,
4
+ cp,
4
5
  mkdir,
5
6
  readFile,
6
7
  writeFile
@@ -9,10 +10,19 @@ import { EOL } from "node:os";
9
10
  import { join } from "node:path";
10
11
  import { createConfig, createStore } from "@hippo-memo/core";
11
12
  import { MEMORY_DIR_NAME } from "@hippo-memo/shared";
13
+ import prompts from "prompts";
12
14
 
13
15
  const __dirname = import.meta.dirname;
14
16
  const TEMPLATE_DIR = join(__dirname, "../../template/system");
15
- const AGENTS_TEMPLATE_PATH = join(__dirname, "../../template/mcp/AGENTS.md");
17
+ const MCP_AGENTS_TEMPLATE_PATH = join(
18
+ __dirname,
19
+ "../../template/mcp/AGENTS.md"
20
+ );
21
+ const SKILL_AGENTS_TEMPLATE_PATH = join(
22
+ __dirname,
23
+ "../../template/skill/AGENTS.md"
24
+ );
25
+ const SKILL_TEMPLATE_DIR = join(__dirname, "../../template/skill");
16
26
 
17
27
  const TEMPLATE_URIS = {
18
28
  agent: "system://agent",
@@ -20,6 +30,8 @@ const TEMPLATE_URIS = {
20
30
  user: "system://user"
21
31
  };
22
32
 
33
+ type InitMode = "mcp" | "skill";
34
+
23
35
  async function readTemplateContent(filename: string): Promise<string> {
24
36
  return readFile(join(TEMPLATE_DIR, filename), "utf-8");
25
37
  }
@@ -38,15 +50,12 @@ function getInjectionMarker(content: string): string {
38
50
  */
39
51
  function isAlreadyInjected(content: string, marker: string): boolean {
40
52
  const lines = content.split("\n");
41
- // 跳过开头的空行
42
53
  const firstNonEmptyLine = lines.find((line) => line.trim() !== "");
43
54
  return firstNonEmptyLine?.trim() === marker;
44
55
  }
45
56
 
46
57
  /**
47
58
  * 安全地将内容注入到文件顶部
48
- * @param filePath 目标文件路径
49
- * @param contentToInject 要注入的内容
50
59
  */
51
60
  async function injectToTopOfFile(
52
61
  filePath: string,
@@ -61,10 +70,8 @@ async function injectToTopOfFile(
61
70
  originalContent = "";
62
71
  }
63
72
 
64
- // 从注入内容中提取第一行作为标识符
65
73
  const injectionMarker = getInjectionMarker(contentToInject);
66
74
 
67
- // 幂等性检查:通过第一行判断是否已注入
68
75
  if (
69
76
  originalContent &&
70
77
  isAlreadyInjected(originalContent, injectionMarker)
@@ -73,7 +80,6 @@ async function injectToTopOfFile(
73
80
  return;
74
81
  }
75
82
 
76
- // 拼接内容,注意处理换行符
77
83
  const separator = originalContent ? `${EOL}${EOL}` : "";
78
84
  const updatedContent = `${contentToInject}${separator}${originalContent}`;
79
85
 
@@ -88,7 +94,11 @@ async function injectToTopOfFile(
88
94
  /**
89
95
  * 检测并处理 AGENTS.md 和 CLAUDE.md 文件
90
96
  */
91
- async function handleAgentsAndClaudeFiles(directory: string): Promise<void> {
97
+ async function handleAgentsAndClaudeFiles(
98
+ directory: string,
99
+ templatePath: string,
100
+ mode: InitMode
101
+ ): Promise<void> {
92
102
  const agentsPath = join(directory, "AGENTS.md");
93
103
  const claudePath = join(directory, "CLAUDE.md");
94
104
 
@@ -109,24 +119,139 @@ async function handleAgentsAndClaudeFiles(directory: string): Promise<void> {
109
119
  // CLAUDE.md 不存在
110
120
  }
111
121
 
112
- // 读取 AGENTS.md 模板内容
113
- const agentsContent = await readFile(AGENTS_TEMPLATE_PATH, "utf-8");
122
+ const agentsContent = await readFile(templatePath, "utf-8");
123
+ const configName = mode === "mcp" ? "MCP" : "Skill";
114
124
 
115
125
  if (hasClaude) {
116
- // CLAUDE.md 存在:优先注入到 CLAUDE.md 顶部
117
126
  console.log("› Found: CLAUDE.md");
118
- await injectToTopOfFile(claudePath, agentsContent);
127
+
128
+ // 检查是否已注入
129
+ const existingContent = await readFile(claudePath, "utf-8");
130
+ const injectionMarker = getInjectionMarker(agentsContent);
131
+
132
+ if (!isAlreadyInjected(existingContent, injectionMarker)) {
133
+ const response = await prompts({
134
+ type: "confirm",
135
+ name: "inject",
136
+ message: `Inject ${configName} configuration to CLAUDE.md?`,
137
+ initial: true
138
+ });
139
+
140
+ if (response.inject) {
141
+ await injectToTopOfFile(claudePath, agentsContent);
142
+ } else {
143
+ console.log("› Skipped: CLAUDE.md");
144
+ }
145
+ } else {
146
+ console.log("› Skipped: content already exists");
147
+ }
119
148
  } else if (hasAgents) {
120
- // 只有 AGENTS.md 存在:注入到 AGENTS.md 顶部
121
149
  console.log("› Found: AGENTS.md");
122
- await injectToTopOfFile(agentsPath, agentsContent);
150
+
151
+ const existingContent = await readFile(agentsPath, "utf-8");
152
+ const injectionMarker = getInjectionMarker(agentsContent);
153
+
154
+ if (!isAlreadyInjected(existingContent, injectionMarker)) {
155
+ const response = await prompts({
156
+ type: "confirm",
157
+ name: "inject",
158
+ message: `Inject ${configName} configuration to AGENTS.md?`,
159
+ initial: true
160
+ });
161
+
162
+ if (response.inject) {
163
+ await injectToTopOfFile(agentsPath, agentsContent);
164
+ } else {
165
+ console.log("› Skipped: AGENTS.md");
166
+ }
167
+ } else {
168
+ console.log("› Skipped: content already exists");
169
+ }
123
170
  } else {
124
- // 两者都不存在:创建 AGENTS.md
125
- console.log("✔ Created: AGENTS.md");
171
+ console.log(`✔ Created: AGENTS.md`);
126
172
  await writeFile(agentsPath, agentsContent, "utf-8");
127
173
  }
128
174
  }
129
175
 
176
+ /**
177
+ * 复制 Skill 模板到项目目录
178
+ */
179
+ async function copySkillTemplates(directory: string): Promise<void> {
180
+ const targetSkillDir = join(directory, ".claude", "skills");
181
+
182
+ try {
183
+ await mkdir(targetSkillDir, { recursive: true });
184
+ } catch {
185
+ // 目录可能已存在
186
+ }
187
+
188
+ const skills = ["hippo-memory"];
189
+
190
+ for (const skill of skills) {
191
+ const sourceDir = join(SKILL_TEMPLATE_DIR, skill);
192
+ const targetDir = join(targetSkillDir, skill);
193
+ const targetFile = join(targetDir, "SKILL.md");
194
+
195
+ try {
196
+ await mkdir(targetDir, { recursive: true });
197
+
198
+ // 检查文件是否已存在
199
+ let fileExists = false;
200
+ try {
201
+ await access(targetFile, constants.F_OK);
202
+ fileExists = true;
203
+ } catch {
204
+ // 文件不存在
205
+ }
206
+
207
+ if (fileExists) {
208
+ const response = await prompts({
209
+ type: "confirm",
210
+ name: "overwrite",
211
+ message: `Skill ${skill} already exists. Overwrite?`,
212
+ initial: false
213
+ });
214
+
215
+ if (!response.overwrite) {
216
+ console.log(`› Skipped: ${skill}`);
217
+ continue;
218
+ }
219
+ }
220
+
221
+ await cp(join(sourceDir, "SKILL.md"), targetFile);
222
+ console.log(`✔ Installed skill: ${skill}`);
223
+ } catch (error: unknown) {
224
+ console.error(`✖ Failed to install skill: ${skill}`, error);
225
+ }
226
+ }
227
+ }
228
+
229
+ /**
230
+ * 询问用户初始化模式
231
+ */
232
+ async function askInitMode(): Promise<InitMode> {
233
+ const response = await prompts({
234
+ type: "select",
235
+ name: "mode",
236
+ message: "选择 Claude Code 集成方式:",
237
+ choices: [
238
+ {
239
+ title: "🔌 MCP 模式 (推荐全局配置)",
240
+ description: "适用于跨项目共享记忆,需要单独配置 MCP 服务器",
241
+ value: "mcp"
242
+ },
243
+ {
244
+ title: "📜 Skill 模式 (推荐项目配置)",
245
+ description: "项目级技能,可提交到 Git 与团队共享",
246
+ value: "skill"
247
+ }
248
+ ],
249
+ initial: 1
250
+ });
251
+
252
+ return (response.mode as InitMode) || "skill";
253
+ }
254
+
130
255
  export async function init(directory: string): Promise<void> {
131
256
  const memoryRoot = join(directory, MEMORY_DIR_NAME);
132
257
 
@@ -134,7 +259,6 @@ export async function init(directory: string): Promise<void> {
134
259
  await access(memoryRoot, constants.F_OK);
135
260
  console.log(`Memory directory already exists at ${memoryRoot}`);
136
261
  } catch {
137
- // Directory doesn't exist, proceed with creation
138
262
  await mkdir(memoryRoot, { recursive: true });
139
263
 
140
264
  const store = createStore({
@@ -149,10 +273,38 @@ export async function init(directory: string): Promise<void> {
149
273
  })
150
274
  );
151
275
 
152
- console.log(`Initialized hippo memory at ${memoryRoot}`);
276
+ console.log(`✔ Initialized hippo memory at ${memoryRoot}`);
153
277
  }
154
278
 
155
- // 处理 AGENTS.md 和 CLAUDE.md 文件
156
- console.log("◇ Checking AGENTS.md and CLAUDE.md...");
157
- await handleAgentsAndClaudeFiles(directory);
279
+ // 询问初始化模式
280
+ const mode = await askInitMode();
281
+
282
+ // 处理 MCP 配置 (注入到 AGENTS.md/CLAUDE.md)
283
+ if (mode === "mcp") {
284
+ console.log(`${EOL}◇ Setting up MCP integration...`);
285
+ await handleAgentsAndClaudeFiles(directory, MCP_AGENTS_TEMPLATE_PATH, mode);
286
+ console.log(`${EOL}✨ Setup complete!${EOL}`);
287
+ console.log("📌 Next steps:");
288
+ console.log(" 1. Configure MCP server in Claude Code settings");
289
+ console.log(" 2. Run: hippo web -p 3000");
290
+ console.log("");
291
+ }
292
+
293
+ // 处理 Skill 配置
294
+ if (mode === "skill") {
295
+ console.log(`${EOL}◇ Installing Claude Code Skills...`);
296
+ await handleAgentsAndClaudeFiles(
297
+ directory,
298
+ SKILL_AGENTS_TEMPLATE_PATH,
299
+ mode
300
+ );
301
+ await copySkillTemplates(directory);
302
+ console.log(`${EOL}✨ Setup complete!${EOL}`);
303
+ console.log("📌 Next steps:");
304
+ console.log(" 1. Skills installed in .claude/skills/");
305
+ console.log(" 2. Configuration injected to CLAUDE.md");
306
+ console.log(" 3. LLM will automatically trigger when needed");
307
+ console.log(" 4. Commit to Git to share with your team");
308
+ console.log("");
309
+ }
158
310
  }