huhaa-myskills 0.1.5
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 +384 -0
- package/docs/GUIDE.md +190 -0
- package/docs/PLAN.md +359 -0
- package/docs/RULES.md +329 -0
- package/docs/RUNBOOK-myskills.md +258 -0
- package/docs/SYNC-SKILLS.md +259 -0
- package/docs/releases/README.md +47 -0
- package/docs/releases/v0.1.0.md +256 -0
- package/docs/releases/v0.1.1.md +297 -0
- package/docs/releases/v0.1.2.md +207 -0
- package/docs/releases/v0.1.3.md +269 -0
- package/docs/todo/v0.1.2.md +98 -0
- package/docs/todo/v0.1.3.md +40 -0
- package/docs/todo/v0.1.4.md +36 -0
- package/docs/todo/v0.1.5.md +41 -0
- package/docs/todo/v0.1.6.md +43 -0
- package/docs/todo/v0.1.7.md +38 -0
- package/docs/todo/v0.1.8.md +36 -0
- package/docs/todo/v0.1.9.md +54 -0
- package/install-and-sync.sh +209 -0
- package/package.json +68 -0
- package/service/bin/huhaa-myskills.mjs +314 -0
- package/service/bin/lib/paths.mjs +57 -0
- package/service/bin/lib/port.mjs +23 -0
- package/service/config/sources.example.yaml +121 -0
- package/service/packages/scanner/src/adapters/file-docs.mjs +158 -0
- package/service/packages/scanner/src/adapters/hermes-plugin.mjs +149 -0
- package/service/packages/scanner/src/adapters/markdown-skill.mjs +219 -0
- package/service/packages/scanner/src/adapters/mcp-config.mjs +171 -0
- package/service/packages/scanner/src/index.mjs +234 -0
- package/service/packages/scanner/src/types.d.ts +88 -0
- package/service/packages/scanner/src/utils.mjs +186 -0
- package/service/packages/server/src/index.mjs +549 -0
- package/service/packages/web/README.md +5 -0
- package/service/packages/web/dist/assets/index-CTh5OdBd.js +36 -0
- package/service/packages/web/dist/assets/index-CtoiGnQ7.css +1 -0
- package/service/packages/web/dist/index.html +13 -0
- package/service/scripts/build-web.mjs +29 -0
- package/service/scripts/prepare-publish.mjs +44 -0
- package/service/scripts/restore-publish.mjs +17 -0
- package/service/scripts/sync-skills.sh +427 -0
- package/service/scripts/verify.mjs +132 -0
package/docs/PLAN.md
ADDED
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
# HuHaa-MySkills — 本地 Skill / Plugin / MCP 聚合中枢
|
|
2
|
+
|
|
3
|
+
按 gstack/plan-eng-review 评审骨架编写(架构 / 代码质量 / 测试 / 性能 / NOT-in-scope / 必填输出),用于实施前锁定方案。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 0. 项目定位(一句话)
|
|
8
|
+
|
|
9
|
+
一个本地纯 Node.js 项目,`npm install && npm start` 起 `http://localhost:11520`,把散落在 Hermes / Claude Code / Codex / Cursor / Obsidian / 各项目根目录的「skill / plugin / MCP / 部署 RUNBOOK」**聚合成一个浏览器目录**,按 工具 → 项目 → 目录 → 产品/品牌 四级浏览,详情页提供描述、参数、用法示例、**一键复制路径 / 复制原文 / 在编辑器中打开**,让"想用某技能 → 切回 Cursor 粘贴上下文"这条路从「翻 5 个目录 + grep」收敛成「11520 搜一下点复制」。
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. 架构评审(Architecture)
|
|
14
|
+
|
|
15
|
+
### 1.1 顶层组件
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
HuHaa-MySkills/
|
|
19
|
+
├── packages/
|
|
20
|
+
│ ├── scanner/ # 扫描器:多源 → 统一 IR
|
|
21
|
+
│ ├── server/ # Fastify HTTP + SSE 热更新
|
|
22
|
+
│ └── web/ # Vite + Vue3 SPA
|
|
23
|
+
├── config/
|
|
24
|
+
│ └── sources.yaml # 用户声明的扫描源
|
|
25
|
+
├── data/
|
|
26
|
+
│ └── cache.json # IR 缓存(gitignore)
|
|
27
|
+
└── package.json # workspaces 单仓
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
不拆 monorepo 的多包发布,只拿 npm workspaces 做内部代码隔离 —— 用户口径"最简能跑",单仓单 `npm start`。
|
|
31
|
+
|
|
32
|
+
### 1.2 数据流
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
sources.yaml ──┐
|
|
36
|
+
├─→ Scanner ──→ Adapters ──→ 统一 IR (JSON) ──┐
|
|
37
|
+
fs walkers ────┘ (per-type) │ ├─→ cache.json
|
|
38
|
+
▼ │
|
|
39
|
+
chokidar watch ────── SSE ────→ Browser SPA
|
|
40
|
+
└─→ /api/skills
|
|
41
|
+
/api/copy
|
|
42
|
+
/api/open
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
关键设计:**所有源都被适配器规范化成同一份 IR**,前端只认 IR,不关心源是 Hermes 还是 Cursor。
|
|
46
|
+
|
|
47
|
+
### 1.3 统一 IR(Intermediate Representation)
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
type SkillItem = {
|
|
51
|
+
id: string; // sha1(absPath),稳定
|
|
52
|
+
kind: 'skill' | 'plugin' | 'mcp' | 'runbook' | 'agent-rule';
|
|
53
|
+
source: 'hermes' | 'claude-code' | 'codex' | 'cursor' | 'obsidian' | 'project' | 'mcp-config';
|
|
54
|
+
name: string; // frontmatter.name 或 文件名
|
|
55
|
+
title?: string; // 人类可读
|
|
56
|
+
description?: string;
|
|
57
|
+
category?: string; // 例:devops, mlops/inference
|
|
58
|
+
brand?: string; // 例:OpenAI, Anthropic, Google, Cloudflare(从 description / 路径推断)
|
|
59
|
+
product?: string; // 例:new-api, frp, vLLM
|
|
60
|
+
triggers?: string[]; // when_to_use / triggers / aliases
|
|
61
|
+
params?: ParamSpec[]; // MCP tools 才有;skill 一般为空
|
|
62
|
+
tags?: string[];
|
|
63
|
+
paths: {
|
|
64
|
+
abs: string; // 绝对路径(复制按钮用)
|
|
65
|
+
rel?: string; // 相对项目根
|
|
66
|
+
rootKind: 'home' | 'project' | 'icloud';
|
|
67
|
+
};
|
|
68
|
+
preview: string; // 截前 N 行 markdown body
|
|
69
|
+
raw: string; // 完整文件原文(详情页 lazy load)
|
|
70
|
+
links?: { label: string; url: string }[];
|
|
71
|
+
updatedAt: string; // ISO
|
|
72
|
+
};
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 1.4 适配器矩阵(决定能聚合到什么)
|
|
76
|
+
|
|
77
|
+
| Adapter | 扫描路径 | 解析 | kind |
|
|
78
|
+
|----------------|--------------------------------------------------------------------------|-----------------------------------------------|---------------------|
|
|
79
|
+
| hermes | `~/.hermes/skills/**/SKILL.md`,`~/.hermes/profiles/*/skills/**` | YAML frontmatter + body | skill |
|
|
80
|
+
| claude-code | `~/.claude/skills/**/SKILL.md` | YAML frontmatter + body | skill |
|
|
81
|
+
| codex-agents | 工程根 `AGENTS.md`,`~/.codex/AGENTS.md` | 纯 markdown,h1/h2 切段 | agent-rule |
|
|
82
|
+
| cursor-rules | 工程根 `.cursorrules`,`.cursor/rules/*.mdc` | mdc frontmatter + body | agent-rule |
|
|
83
|
+
| claude-md | 工程根 `CLAUDE.md` | 纯 markdown | agent-rule |
|
|
84
|
+
| mcp-config | `~/.cursor/mcp.json`,`~/.codex/config.toml [mcp_servers]`,`~/Library/Application Support/Claude/claude_desktop_config.json`,`~/.hermes/config.yaml mcp:` | JSON / TOML / YAML 解析出 servers + tools | mcp |
|
|
85
|
+
| hermes-plugin | `~/.hermes/plugins/**/manifest.*` | manifest.json/yaml | plugin |
|
|
86
|
+
| project-runbook| `**/docs/RUNBOOK-*.md`(按 sources.yaml 声明的项目根) | 纯 markdown | runbook |
|
|
87
|
+
| obsidian | 用户声明 vault 路径下打了 `#skill` 标签的 note | frontmatter + tags | skill |
|
|
88
|
+
|
|
89
|
+
`sources.yaml` 默认开 hermes / claude-code / mcp-config,其他要用户白名单具体项目根(避免误扫整个磁盘)。
|
|
90
|
+
|
|
91
|
+
### 1.5 单一职责边界
|
|
92
|
+
|
|
93
|
+
- **Scanner** 只产 IR,不碰 HTTP。
|
|
94
|
+
- **Server** 只读 IR + 提供 API + 静态文件 + SSE,不解析任何源文件。
|
|
95
|
+
- **Web** 只渲染 IR + 调三个 endpoint:`/api/skills`、`/api/copy`、`/api/open`。
|
|
96
|
+
- 复制路径走 `/api/copy?path=...` → 后端 `pbcopy`(macOS)/ `clip`(win)/ `xclip`(linux),**不**靠浏览器 `navigator.clipboard`(HTTP 在非 localhost 域会卡权限,且复制原文时绕过 N KB 上限更稳)。
|
|
97
|
+
- "在编辑器中打开"走 `/api/open?path=...&editor=cursor` → 后端 `open -a 'Cursor' <path>` 或 `cursor <path>` / `code <path>`。
|
|
98
|
+
|
|
99
|
+
### 1.6 关键失败场景与对策
|
|
100
|
+
|
|
101
|
+
| 场景 | 后果 | 对策 |
|
|
102
|
+
|-------------------------------------------------|-------------------|-------------------------------------------------------------------|
|
|
103
|
+
| 用户声明的项目根不存在(机器搬迁) | 扫描器抛错 | 单源 try/catch,UI 上单源标 `unavailable`,其他源照常 |
|
|
104
|
+
| YAML frontmatter 损坏(手改坏的) | 整文件丢失 | parse 失败时降级:name=文件名、preview=前 30 行、`parseError` 字段 |
|
|
105
|
+
| 11520 端口被占 | 起不来 | 启动检测,`PORT` env 覆盖;CLI 输出 fallback 端口 |
|
|
106
|
+
| 文件数量爆炸(vault 含 10k notes) | 扫描卡 CPU | sources.yaml 强制 `include`/`exclude` glob,`maxFiles: 5000` 硬限 |
|
|
107
|
+
| 浏览器在远端(SSH 转发)打开页面,复制按钮失效 | 复制不动 | `/api/copy` 在远端跑 pbcopy 也无意义 —— UI 同时给"原文+点击全选" |
|
|
108
|
+
| chokidar 在 macOS 全盘监听耗 fd | 系统卡 | 只 watch sources.yaml 列出的具体子树,`usePolling: false` |
|
|
109
|
+
|
|
110
|
+
### 1.7 安全 / 数据边界
|
|
111
|
+
|
|
112
|
+
- 全程 **localhost only**:server bind `127.0.0.1`,**不**支持 `0.0.0.0`。
|
|
113
|
+
- `/api/open` 路径白名单:必须在 sources.yaml 已声明的根之下,否则 403 —— 防 `?path=/etc/passwd` 这类。
|
|
114
|
+
- `/api/copy` 同样白名单 —— 防当文件读取代理。
|
|
115
|
+
- 不上传不联网,不写 telemetry。
|
|
116
|
+
- `data/cache.json` 进 `.gitignore`,但 `.env` / `sources.yaml` 用户决定(按你的 git 习惯:`.env` 入库)。
|
|
117
|
+
|
|
118
|
+
### 1.8 分发架构
|
|
119
|
+
|
|
120
|
+
- **不发 npm**。私仓 git clone + `npm install && npm start`。
|
|
121
|
+
- `package.json` 暴露三条 script:
|
|
122
|
+
- `npm start` — 一键:扫一次 → 起 server → 自动 `open http://localhost:11520`
|
|
123
|
+
- `npm run scan` — 只扫描,dump IR 到 stdout(debug 用)
|
|
124
|
+
- `npm run dev` — Vite dev server + nodemon server,前后端热重载
|
|
125
|
+
- 后续要给别的机器用,直接 `git clone + npm i + npm start`。
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 2. 代码质量评审(Code Quality)
|
|
130
|
+
|
|
131
|
+
### 2.1 技术选型(决策已锁)
|
|
132
|
+
|
|
133
|
+
| 维度 | 选型 | 理由 |
|
|
134
|
+
|---------------|-------------------------------|---------------------------------------------------------------------|
|
|
135
|
+
| Runtime | Node 20+ | LTS、Fastify v5 要求、原生 `fs.glob` |
|
|
136
|
+
| 包管理 | npm workspaces | 你机器装的是 npm,pnpm 不强制 |
|
|
137
|
+
| HTTP 框架 | **Fastify 5** | Express 已死气;Fastify 内置 schema validation + 更快 |
|
|
138
|
+
| YAML | `yaml` (eemeli/yaml) | 比 js-yaml 更宽容损坏 frontmatter |
|
|
139
|
+
| TOML | `@iarna/toml` | Codex config.toml 必须 |
|
|
140
|
+
| 文件 watch | `chokidar` v3 | 跨平台、稳定 |
|
|
141
|
+
| Frontend | **Vite 5 + Vue 3 + TS** | 单 SPA、轻、官方 Devtools、UI 用 [Vuetify](https://vuetifyjs.com) |
|
|
142
|
+
| 状态 | Pinia | Vue 官方,简单 |
|
|
143
|
+
| 搜索 | Fuse.js | 全在前端,无需后端 ES |
|
|
144
|
+
| 编辑器跳转 | `child_process.spawn` | 直接 `cursor` / `code` / `open -a` |
|
|
145
|
+
| 剪贴板 | `clipboardy` 或自写 pbcopy | clipboardy 4.x ESM-only 注意 |
|
|
146
|
+
|
|
147
|
+
> 不要 React —— 单人小工具用 Vue 心智更轻;不要 Next/Nuxt —— 没 SSR 需求,纯 SPA 够。
|
|
148
|
+
> 不要 TypeScript on backend 也无所谓,但**前端必须 TS**(IR 类型定义会救命)。
|
|
149
|
+
|
|
150
|
+
### 2.2 模块边界(强约束 — 防滑坡)
|
|
151
|
+
|
|
152
|
+
- 适配器 **不允许**互相 import,全部产同一份 `SkillItem[]`。新增源 = 新文件 + 注册表登记一行。
|
|
153
|
+
- Server 的 route handler **不允许**做扫描,启动期 + watch 事件触发 scanner,handler 只读内存 IR。
|
|
154
|
+
- 前端 **不允许**直接读文件 fetch,全部走 `/api/*`。
|
|
155
|
+
- DRY:所有适配器共享 `parseFrontmatter(text)` / `inferBrand(item)` / `normalizePath(p)` 三个 util,禁止各自实现。
|
|
156
|
+
|
|
157
|
+
### 2.3 配置文件 schema(sources.yaml 草案)
|
|
158
|
+
|
|
159
|
+
```yaml
|
|
160
|
+
sources:
|
|
161
|
+
hermes:
|
|
162
|
+
enabled: true
|
|
163
|
+
roots:
|
|
164
|
+
- ~/.hermes/skills
|
|
165
|
+
- ~/.hermes/profiles/*/skills
|
|
166
|
+
claude-code:
|
|
167
|
+
enabled: true
|
|
168
|
+
roots:
|
|
169
|
+
- ~/.claude/skills
|
|
170
|
+
mcp-config:
|
|
171
|
+
enabled: true
|
|
172
|
+
files:
|
|
173
|
+
- ~/.cursor/mcp.json
|
|
174
|
+
- ~/.codex/config.toml
|
|
175
|
+
- ~/Library/Application Support/Claude/claude_desktop_config.json
|
|
176
|
+
- ~/.hermes/config.yaml
|
|
177
|
+
project-runbook:
|
|
178
|
+
enabled: true
|
|
179
|
+
roots:
|
|
180
|
+
- ~/Project/HuHaa-AI-Platform
|
|
181
|
+
- ~/Project/HuHaa-Open-Guide
|
|
182
|
+
- ~/Project/HuHaa-Quark-Bridge
|
|
183
|
+
- ~/Library/Mobile Documents/com~apple~CloudDocs/notes
|
|
184
|
+
glob: 'docs/RUNBOOK-*.md'
|
|
185
|
+
ui:
|
|
186
|
+
port: 11520
|
|
187
|
+
autoOpen: true
|
|
188
|
+
defaultEditor: cursor # cursor | code | open
|
|
189
|
+
groupBy: [source, category, brand]
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 2.4 你已经踩过坑、要预先避免的反模式
|
|
193
|
+
|
|
194
|
+
- **不**新建 `xxxProxy.ts` / `xxxAdapter` 层去包装 Fastify —— 直接路由 + handler。
|
|
195
|
+
- **不**在 server 里做"先看 cache 再决定扫"的乐观快路径 —— 启动一定全扫一次,避免缓存陈旧(首扫 < 1s,没必要省)。
|
|
196
|
+
- **不**做 SSR、登录、用户系统、多租户。这是单机工具。
|
|
197
|
+
- **不**把扫描和 HTTP 混进同一个文件 —— 两件事。
|
|
198
|
+
|
|
199
|
+
### 2.5 错误处理
|
|
200
|
+
|
|
201
|
+
- 适配器解析失败 → IR 里 `parseError: string` 字段,UI 红角标显示。
|
|
202
|
+
- HTTP handler 全部用 Fastify schema 校验入参。
|
|
203
|
+
- `/api/open` 失败(编辑器没装)→ 200 返回 `{ ok:false, hint:"未检测到 cursor,请安装 Cursor 命令行" }`,UI 弹 toast。
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
## 3. 测试评审(Test)
|
|
208
|
+
|
|
209
|
+
### 3.1 测试栈
|
|
210
|
+
|
|
211
|
+
- **Vitest**(前后端通吃)+ `supertest` 打 Fastify。
|
|
212
|
+
- E2E 不做(单人工具,过度工程)。
|
|
213
|
+
|
|
214
|
+
### 3.2 必测覆盖(按代码路径 + 用户路径)
|
|
215
|
+
|
|
216
|
+
```
|
|
217
|
+
适配器层(每个 adapter 独立 fixture 目录)
|
|
218
|
+
├─ hermes.adapter.test.ts
|
|
219
|
+
│ ├── ★★★ 正常 SKILL.md → 完整 IR
|
|
220
|
+
│ ├── ★★★ frontmatter 损坏 → 降级 + parseError
|
|
221
|
+
│ ├── ★★ 目录不存在 → 单源 unavailable,不 throw
|
|
222
|
+
│ └── ★★ description 含 brand 关键字 → brand 推断正确
|
|
223
|
+
├─ mcp-config.adapter.test.ts
|
|
224
|
+
│ ├── ★★★ 解析 cursor mcp.json
|
|
225
|
+
│ ├── ★★★ 解析 codex config.toml [mcp_servers]
|
|
226
|
+
│ └── ★★ 字段缺失(command 没写)→ parseError
|
|
227
|
+
├─ cursor-rules.adapter.test.ts ── ★★ mdc frontmatter
|
|
228
|
+
└─ project-runbook.adapter.test.ts ── ★★ glob 命中
|
|
229
|
+
|
|
230
|
+
Server 层
|
|
231
|
+
├─ GET /api/skills ★★★ 返回全量 IR
|
|
232
|
+
├─ GET /api/skills/:id ★★★ 返回 raw + 详情
|
|
233
|
+
├─ POST /api/copy { path } ★★★ 白名单内 → pbcopy;白名单外 → 403
|
|
234
|
+
├─ POST /api/open { path, editor } ★★★ 白名单内 → spawn;编辑器没装 → 友好失败
|
|
235
|
+
├─ GET /sse ★★ watch 触发 → 推 'reload' 事件
|
|
236
|
+
└─ Port 11520 已占 ★★ fallback 提示
|
|
237
|
+
|
|
238
|
+
前端
|
|
239
|
+
└─ 不写单测;靠手测 + Pinia DevTools 即可(单人小工具,不值得)
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
覆盖率目标:**适配器与 server 90% 行覆盖**,前端 0%。
|
|
243
|
+
|
|
244
|
+
### 3.3 关键回归用例(必须打住的退化)
|
|
245
|
+
|
|
246
|
+
- 任何对 frontmatter 解析的修改 → 回归一遍"损坏 YAML 不 crash 整次扫描"。
|
|
247
|
+
- 任何对路径白名单的修改 → 回归"路径穿越 `../../etc/passwd` 必 403"。
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 4. 性能评审(Performance)
|
|
252
|
+
|
|
253
|
+
### 4.1 扫描期
|
|
254
|
+
|
|
255
|
+
- 你机器上初步统计:Hermes 116 + gstack 545 + 项目 RUNBOOK 数十 ≈ **800 文件量级**。读 + parse YAML ≈ 100-300 ms(M 系列),完全不需要 worker pool。
|
|
256
|
+
- 上限保护:`maxFiles: 5000` + `maxFileBytes: 1MB`,超过跳过 + warn。
|
|
257
|
+
|
|
258
|
+
### 4.2 运行期
|
|
259
|
+
|
|
260
|
+
- IR 全量内存(800 条 × 平均 2KB raw ≈ 2MB),单进程吃得下。
|
|
261
|
+
- `/api/skills` 只返回 IR 元信息(不带 raw),约 200KB gzip 后 < 30KB。
|
|
262
|
+
- raw 走 `/api/skills/:id`,懒加载,详情页打开才取。
|
|
263
|
+
- 前端 Fuse.js 索引在加载后构建一次,800 条搜索延迟 < 5ms。
|
|
264
|
+
|
|
265
|
+
### 4.3 watch 风暴
|
|
266
|
+
|
|
267
|
+
- chokidar 在 SKILL.md 改动 → debounce 500ms → 单源重扫(不全量)→ SSE broadcast `{type:'reload', source:'hermes'}`。
|
|
268
|
+
- 前端收到后只重拉对应 source 的 IR,不全量刷新。
|
|
269
|
+
|
|
270
|
+
### 4.4 不优化的事
|
|
271
|
+
|
|
272
|
+
- 不做 lazy 适配器(首扫 < 1s 没必要)。
|
|
273
|
+
- 不做 IndexedDB 前端缓存(每次刷新重拉 200KB 没影响)。
|
|
274
|
+
- 不做 SSR / 预渲染。
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 5. NOT in scope(已考虑但显式不做,每条带理由)
|
|
279
|
+
|
|
280
|
+
- **写 / 编辑技能**:本工具是只读浏览器,编辑请回到 Cursor / Hermes CLI。原因:避免变成第二个编辑器,scope 爆炸。
|
|
281
|
+
- **跨机同步**:每台机器自己跑,sources.yaml 自己写。原因:你已有 iCloud / git 同步习惯,重复造轮子。
|
|
282
|
+
- **AI 推荐 / 智能调用**:不在页面里调 LLM 帮你选技能。原因:你有 Hermes / Claude Code,那是它们的事。
|
|
283
|
+
- **打包成 Electron 桌面 app**:只是浏览器 SPA。原因:单人工具,浏览器够用,省 200MB。
|
|
284
|
+
- **多用户 / 鉴权**:localhost only。原因:单机工具。
|
|
285
|
+
- **写入 MCP 服务器配置**:只读展示。原因:写配置是一次性的事,不值得做 UI。
|
|
286
|
+
- **远程 SSH skill 聚合**:只扫本机。原因:你机器之间通常 git 同步项目,跨机扫盘没必要。
|
|
287
|
+
- **Windows / Linux 一等公民**:开发以 macOS 为准;其他平台尽量兼容但不专门测。原因:你是 Mac 用户。
|
|
288
|
+
- **OAuth / 私有 Git 拉技能**:源限文件系统。原因:scope。
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## 6. 必填输出
|
|
293
|
+
|
|
294
|
+
### 6.1 验收标准(Done definition)
|
|
295
|
+
|
|
296
|
+
- [ ] `git clone && npm install && npm start` → 浏览器自动打开 `localhost:11520`,主页可见至少 hermes / claude-code / mcp-config 三个 source 的合计技能数。
|
|
297
|
+
- [ ] 左侧树支持四种分组切换:source / category / brand / product。
|
|
298
|
+
- [ ] 详情页有:description、triggers、参数表(仅 MCP)、preview、原文、**复制路径按钮**、**复制原文按钮**、**在 Cursor 中打开按钮**。
|
|
299
|
+
- [ ] 修改 `~/.hermes/skills/devops/new-api-deployment/SKILL.md` 后,浏览器在 1s 内自动刷新该条目。
|
|
300
|
+
- [ ] 关掉 Cursor,点"在 Cursor 中打开" → toast "未检测到 cursor 命令",不崩。
|
|
301
|
+
- [ ] `curl 'http://localhost:11520/api/copy?path=/etc/passwd'` → 403。
|
|
302
|
+
- [ ] 任何一个源的根目录不存在 → 该源标 `unavailable`,其他源照常列出。
|
|
303
|
+
|
|
304
|
+
### 6.2 实施阶段(按你 30s 协议,每阶段一个可验产物)
|
|
305
|
+
|
|
306
|
+
| 阶段 | 交付 | 验证 | 估时 |
|
|
307
|
+
|------|----------------------------------------------------------|-------------------------------------------------|--------|
|
|
308
|
+
| P0 | 仓骨架 + workspaces + sources.yaml + IR 类型 | `npm install` 通过 | 30 min |
|
|
309
|
+
| P1 | hermes + claude-code 适配器 + `npm run scan` 出全量 IR | stdout 看到 660+ 条 | 60 min |
|
|
310
|
+
| P2 | Fastify server + `/api/skills` + `/api/skills/:id` | curl 返回 JSON | 45 min |
|
|
311
|
+
| P3 | Vue SPA 主页 + 列表 + 详情 + 复制路径 | 浏览器能浏览 + 复制 | 90 min |
|
|
312
|
+
| P4 | mcp-config + cursor-rules + project-runbook 适配器 | 主页见到 MCP servers + RUNBOOK | 60 min |
|
|
313
|
+
| P5 | chokidar + SSE 热更新 | 改 SKILL.md → 页面 1s 内刷新 | 45 min |
|
|
314
|
+
| P6 | brand/product 推断 + 四种分组 | 切分组下拉 → UI 重排 | 30 min |
|
|
315
|
+
| P7 | `/api/open` + Vitest 测试 | 点按钮跳 Cursor + `npm test` 全绿 | 45 min |
|
|
316
|
+
|
|
317
|
+
合计约 7-8 小时净工作量,分两到三天。
|
|
318
|
+
|
|
319
|
+
### 6.3 风险登记(Risks)
|
|
320
|
+
|
|
321
|
+
| ID | 风险 | 影响 | 缓解 |
|
|
322
|
+
|----|--------------------------------------------|----------|-------------------------------------------------------|
|
|
323
|
+
| R1 | 适配器对每种格式假设错误(实际 frontmatter 字段名不一致) | 数据错乱 | P1 出 IR 后人工抽 20 条对照原文 |
|
|
324
|
+
| R2 | macOS pbcopy 在 Cursor terminal session 复制不到系统剪贴板 | 复制按钮无效 | 提供"双轨":后端 pbcopy + 前端 navigator.clipboard fallback |
|
|
325
|
+
| R3 | 11520 已被你某个服务占 | 起不来 | 启动期 try-listen,占用就 +1 试到 11530,最终值打到日志 |
|
|
326
|
+
| R4 | iCloud 路径含空格 + `~/Library/Mobile Documents/com~apple~CloudDocs` 这种波浪号 | 路径解析炸 | 统一用 `os.homedir() + path.join`,不字符串拼 |
|
|
327
|
+
|
|
328
|
+
### 6.4 Cross-model tension(自我反诘)
|
|
329
|
+
|
|
330
|
+
- **是否该用 Tauri 而非纯 Web SPA?** 我倾向**否**。Tauri 给本地剪贴板/打开文件更原生,但带来 Rust 工具链 + 打包复杂度,单人工具划不来;浏览器 + `/api/copy` `/api/open` 已覆盖核心诉求。
|
|
331
|
+
- **是否该把 Hermes 自己做的 skill 浏览器(如果有)直接借用?** Hermes 的 `hermes skills` 是 CLI、且只看 Hermes 自己的目录。本项目核心价值是**跨工具聚合**,不可替代。
|
|
332
|
+
|
|
333
|
+
---
|
|
334
|
+
|
|
335
|
+
## 7. Open questions(开干前需要你确认)
|
|
336
|
+
|
|
337
|
+
仅 4 条 —— 其他默认按上面写法。
|
|
338
|
+
|
|
339
|
+
Q1. **sources.yaml 默认要不要包含 `~/.codex/`、Cursor 项目 `.cursorrules`?**
|
|
340
|
+
A) 默认全开(hermes + claude-code + cursor + codex + mcp-config + 你列的 4 个项目根的 RUNBOOK)
|
|
341
|
+
B) 只默认开 hermes + claude-code + mcp-config,剩余手动加(更保守)
|
|
342
|
+
我建议 A,理由:你机器上这些路径都真实存在,默认聚合才有"中枢"感。
|
|
343
|
+
|
|
344
|
+
Q2. **前端 UI 风格?**
|
|
345
|
+
A) Vuetify Material Design(最快,组件全)
|
|
346
|
+
B) 自己写 Tailwind + 极简(你 HuHaa 系产品的 brand 一致)
|
|
347
|
+
我建议 A 第一版上,P7 之后看心情换 B。
|
|
348
|
+
|
|
349
|
+
Q3. **"复制原文"按钮要不要带 frontmatter?**
|
|
350
|
+
A) 带(粘到 Cursor 里 LLM 能看到 triggers / when_to_use,更聪明)
|
|
351
|
+
B) 只复制 body
|
|
352
|
+
我建议 A。
|
|
353
|
+
|
|
354
|
+
Q4. **要不要顺便加一个 `/api/exec-skill?id=...` —— 直接调起对应的 Hermes / Claude Code 命令?**
|
|
355
|
+
A) 加(一键执行)
|
|
356
|
+
B) **本期不加**,只复制路径 → 你回 Cursor 自己说 "用这个 skill"
|
|
357
|
+
我建议 B —— 原始诉求是"复制按钮回到编辑器使用",多搞执行通道 = scope 爆炸 + 安全面变大。
|
|
358
|
+
|
|
359
|
+
回我 `Q1=A Q2=A Q3=A Q4=B`(或任意改动)我就进入 P0。
|
package/docs/RULES.md
ADDED
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
# 版本发布规范
|
|
2
|
+
|
|
3
|
+
本文档定义 HuHaa-MySkills 版本发布、更新日志、Issue 和 Pull Request 的标准格式。
|
|
4
|
+
|
|
5
|
+
## 版本号规则
|
|
6
|
+
|
|
7
|
+
遵循 Semantic Versioning:
|
|
8
|
+
|
|
9
|
+
- `v0.1.x` - Alpha 阶段(核心功能开发)
|
|
10
|
+
- `v1.0.0+` - 稳定版(计划 v0.1.9 之后)
|
|
11
|
+
|
|
12
|
+
### 版本发布清单
|
|
13
|
+
|
|
14
|
+
| 环节 | 检查项 |
|
|
15
|
+
|------|--------|
|
|
16
|
+
| 代码 | [ ] 所有测试通过 / [ ] 代码审查完成 / [ ] 无 TODO 注释 |
|
|
17
|
+
| 文档 | [ ] README 更新 / [ ] CHANGELOG 更新 / [ ] API 文档更新 |
|
|
18
|
+
| 发布 | [ ] git tag 创建 / [ ] GitHub Release 发布 / [ ] npm publish(如适用) |
|
|
19
|
+
| 验证 | [ ] 真实环境测试 / [ ] 向后兼容性检查 |
|
|
20
|
+
|
|
21
|
+
## CHANGELOG 格式
|
|
22
|
+
|
|
23
|
+
参考 [Keep a Changelog](https://keepachangelog.com/):
|
|
24
|
+
|
|
25
|
+
```markdown
|
|
26
|
+
# Changelog
|
|
27
|
+
|
|
28
|
+
## [v0.1.2] - 2026-06-25
|
|
29
|
+
|
|
30
|
+
### Added
|
|
31
|
+
- Keyboard shortcuts support (/, Escape, arrow keys)
|
|
32
|
+
- Virtual scrolling for 800+ items
|
|
33
|
+
- `/api/search` endpoint with filter syntax
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
- Search performance optimization
|
|
37
|
+
- YAML frontmatter parsing robustness
|
|
38
|
+
|
|
39
|
+
### Changed
|
|
40
|
+
- Improved error handling in adapters
|
|
41
|
+
|
|
42
|
+
### Removed
|
|
43
|
+
- Legacy cache format
|
|
44
|
+
|
|
45
|
+
### Deprecated
|
|
46
|
+
- Old search API (use `/api/search` instead)
|
|
47
|
+
|
|
48
|
+
## [v0.1.1] - 2026-06-18
|
|
49
|
+
|
|
50
|
+
### Added
|
|
51
|
+
- npm global install support
|
|
52
|
+
- Normalized bin path for cross-platform compatibility
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Git Commit 格式
|
|
56
|
+
|
|
57
|
+
遵循 Conventional Commits:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
<type>(<scope>): <subject>
|
|
61
|
+
|
|
62
|
+
<body>
|
|
63
|
+
|
|
64
|
+
<footer>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### 类型(type)
|
|
68
|
+
|
|
69
|
+
- **feat** - 新功能
|
|
70
|
+
- **fix** - Bug 修复
|
|
71
|
+
- **docs** - 文档变更
|
|
72
|
+
- **style** - 代码风格(不影响功能)
|
|
73
|
+
- **refactor** - 重构(不改变外部行为)
|
|
74
|
+
- **perf** - 性能优化
|
|
75
|
+
- **test** - 测试相关
|
|
76
|
+
- **chore** - 工具、依赖更新
|
|
77
|
+
|
|
78
|
+
### 范围(scope)
|
|
79
|
+
|
|
80
|
+
- `scanner` - 扫描器模块
|
|
81
|
+
- `server` - HTTP 服务器
|
|
82
|
+
- `web` - 前端界面
|
|
83
|
+
- `adapter` - 适配器系列
|
|
84
|
+
- `cli` - 命令行工具
|
|
85
|
+
- `docs` - 文档
|
|
86
|
+
|
|
87
|
+
### 示例
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
feat(web): add keyboard shortcuts support
|
|
91
|
+
|
|
92
|
+
- Implement / key to focus search box
|
|
93
|
+
- Implement Escape to clear search
|
|
94
|
+
- Implement arrow keys to navigate list
|
|
95
|
+
|
|
96
|
+
Closes #42
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## GitHub Issues 模板
|
|
100
|
+
|
|
101
|
+
### Bug Report
|
|
102
|
+
|
|
103
|
+
```markdown
|
|
104
|
+
## 描述问题
|
|
105
|
+
|
|
106
|
+
清晰简洁的问题描述。
|
|
107
|
+
|
|
108
|
+
## 复现步骤
|
|
109
|
+
|
|
110
|
+
1. ...
|
|
111
|
+
2. ...
|
|
112
|
+
3. ...
|
|
113
|
+
|
|
114
|
+
## 期望行为
|
|
115
|
+
|
|
116
|
+
应该发生什么?
|
|
117
|
+
|
|
118
|
+
## 实际行为
|
|
119
|
+
|
|
120
|
+
实际发生了什么?
|
|
121
|
+
|
|
122
|
+
## 环境
|
|
123
|
+
|
|
124
|
+
- 操作系统:macOS / Linux / Windows
|
|
125
|
+
- Node.js 版本:20.x
|
|
126
|
+
- HuHaa-MySkills 版本:v0.1.1
|
|
127
|
+
|
|
128
|
+
## 额外信息
|
|
129
|
+
|
|
130
|
+
日志、截图等。
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Feature Request
|
|
134
|
+
|
|
135
|
+
```markdown
|
|
136
|
+
## 功能描述
|
|
137
|
+
|
|
138
|
+
这个功能要解决什么问题?
|
|
139
|
+
|
|
140
|
+
## 使用场景
|
|
141
|
+
|
|
142
|
+
什么时候会用到?
|
|
143
|
+
|
|
144
|
+
## 建议的实现方式
|
|
145
|
+
|
|
146
|
+
你有什么想法吗?
|
|
147
|
+
|
|
148
|
+
## 替代方案
|
|
149
|
+
|
|
150
|
+
有其他可能的实现吗?
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## Pull Request 模板
|
|
154
|
+
|
|
155
|
+
```markdown
|
|
156
|
+
## 变更说明
|
|
157
|
+
|
|
158
|
+
这个 PR 做了什么?简要描述关键变更。
|
|
159
|
+
|
|
160
|
+
## 类型
|
|
161
|
+
|
|
162
|
+
- [ ] Bug 修复
|
|
163
|
+
- [ ] 新功能
|
|
164
|
+
- [ ] 文档更新
|
|
165
|
+
- [ ] 性能优化
|
|
166
|
+
|
|
167
|
+
## 相关 Issue
|
|
168
|
+
|
|
169
|
+
Fixes #123
|
|
170
|
+
|
|
171
|
+
## 测试
|
|
172
|
+
|
|
173
|
+
- [ ] 本地测试通过
|
|
174
|
+
- [ ] 新增单元测试
|
|
175
|
+
- [ ] 回归测试通过
|
|
176
|
+
|
|
177
|
+
## 检查清单
|
|
178
|
+
|
|
179
|
+
- [ ] 代码风格符合项目规范
|
|
180
|
+
- [ ] 无新的 linting 警告
|
|
181
|
+
- [ ] CHANGELOG 已更新
|
|
182
|
+
- [ ] 文档已更新
|
|
183
|
+
- [ ] 提交消息格式正确
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Release Notes 模板
|
|
187
|
+
|
|
188
|
+
```markdown
|
|
189
|
+
# v0.1.2: 搜索与交互优化
|
|
190
|
+
|
|
191
|
+
## 概览
|
|
192
|
+
|
|
193
|
+
这个版本改进了搜索体验和 UI 交互,支持键盘快捷键和高性能虚拟滚动。
|
|
194
|
+
|
|
195
|
+
## ✨ 新功能
|
|
196
|
+
|
|
197
|
+
### 键盘快捷键
|
|
198
|
+
- `/ ` - 聚焦搜索框
|
|
199
|
+
- `Esc` - 清空搜索
|
|
200
|
+
- `↑ ↓` - 导航列表
|
|
201
|
+
|
|
202
|
+
### 快速搜索 API
|
|
203
|
+
```
|
|
204
|
+
GET /api/search?q=...&source=hermes&brand=OpenAI
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## 🐛 Bug 修复
|
|
208
|
+
|
|
209
|
+
- 修复 frontmatter 解析容错性 (#45)
|
|
210
|
+
- 改进 SSE 连接稳定性 (#48)
|
|
211
|
+
|
|
212
|
+
## 📊 性能
|
|
213
|
+
|
|
214
|
+
- 列表虚拟滚动:支持 800+ 条目无卡顿
|
|
215
|
+
- 搜索延迟:< 5ms(Fuse.js)
|
|
216
|
+
- 内存占用:保持 ~50MB
|
|
217
|
+
|
|
218
|
+
## 🔄 更新指南
|
|
219
|
+
|
|
220
|
+
```bash
|
|
221
|
+
# 从 npm 全局安装更新
|
|
222
|
+
npm update -g github:aquarkgn/HuHaa-MySkills
|
|
223
|
+
|
|
224
|
+
# 或从源码
|
|
225
|
+
cd ~/Project/HuHaa-MySkills
|
|
226
|
+
git pull origin main
|
|
227
|
+
npm install
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
## 🙏 贡献者
|
|
231
|
+
|
|
232
|
+
感谢 @contributor1 @contributor2 的贡献。
|
|
233
|
+
|
|
234
|
+
---
|
|
235
|
+
|
|
236
|
+
**完整变更日志** - [CHANGELOG.md](../CHANGELOG.md)
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## GitHub Actions 工作流
|
|
240
|
+
|
|
241
|
+
### 验证工作流 (.github/workflows/verify.yml)
|
|
242
|
+
|
|
243
|
+
```yaml
|
|
244
|
+
name: Verify
|
|
245
|
+
|
|
246
|
+
on:
|
|
247
|
+
push:
|
|
248
|
+
branches: [main]
|
|
249
|
+
pull_request:
|
|
250
|
+
branches: [main]
|
|
251
|
+
|
|
252
|
+
jobs:
|
|
253
|
+
verify:
|
|
254
|
+
runs-on: macos-latest
|
|
255
|
+
steps:
|
|
256
|
+
- uses: actions/checkout@v4
|
|
257
|
+
- uses: actions/setup-node@v4
|
|
258
|
+
with:
|
|
259
|
+
node-version: '20'
|
|
260
|
+
- run: npm ci
|
|
261
|
+
- run: npm run verify
|
|
262
|
+
- run: npm test
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### 发布工作流 (.github/workflows/release.yml)
|
|
266
|
+
|
|
267
|
+
```yaml
|
|
268
|
+
name: Release
|
|
269
|
+
|
|
270
|
+
on:
|
|
271
|
+
push:
|
|
272
|
+
tags:
|
|
273
|
+
- 'v*'
|
|
274
|
+
|
|
275
|
+
jobs:
|
|
276
|
+
release:
|
|
277
|
+
runs-on: macos-latest
|
|
278
|
+
steps:
|
|
279
|
+
- uses: actions/checkout@v4
|
|
280
|
+
- uses: actions/setup-node@v4
|
|
281
|
+
with:
|
|
282
|
+
node-version: '20'
|
|
283
|
+
- run: npm ci
|
|
284
|
+
- run: npm run verify
|
|
285
|
+
- run: npm publish # 如果要发布到 npm
|
|
286
|
+
- name: Create Release
|
|
287
|
+
uses: actions/create-release@v1
|
|
288
|
+
env:
|
|
289
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
## 文档结构
|
|
293
|
+
|
|
294
|
+
```
|
|
295
|
+
docs/
|
|
296
|
+
├── README.md # 项目总览
|
|
297
|
+
├── GUIDE.md # 快速启动指南(本文件)
|
|
298
|
+
├── PLAN.md # 架构和设计文档
|
|
299
|
+
├── RULES.md # 本发布规范
|
|
300
|
+
├── CHANGELOG.md # 变更日志
|
|
301
|
+
├── RUNBOOK-*.md # 操作手册
|
|
302
|
+
├── ARCHITECTURE.md # 详细架构(TODO)
|
|
303
|
+
├── API.md # API 参考(TODO)
|
|
304
|
+
├── CONTRIBUTING.md # 贡献指南(TODO)
|
|
305
|
+
└── todo/
|
|
306
|
+
├── v0.1.2.md
|
|
307
|
+
├── v0.1.3.md
|
|
308
|
+
└── ...
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
## 标签(Labels)
|
|
312
|
+
|
|
313
|
+
推荐在 GitHub Issues 中使用以下标签:
|
|
314
|
+
|
|
315
|
+
| 标签 | 说明 |
|
|
316
|
+
|------|------|
|
|
317
|
+
| `bug` | 缺陷报告 |
|
|
318
|
+
| `enhancement` | 功能请求 |
|
|
319
|
+
| `documentation` | 文档改进 |
|
|
320
|
+
| `good first issue` | 适合新贡献者 |
|
|
321
|
+
| `help wanted` | 寻求帮助 |
|
|
322
|
+
| `question` | 提问 |
|
|
323
|
+
| `wontfix` | 无意修复 |
|
|
324
|
+
| `duplicate` | 重复问题 |
|
|
325
|
+
| `v0.1.x` | 版本标记 |
|
|
326
|
+
|
|
327
|
+
---
|
|
328
|
+
|
|
329
|
+
**相关文档** → [CONTRIBUTING.md(待完善)](./CONTRIBUTING.md)
|