harveyz-skill 0.15.0 → 0.17.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/CHANGELOG.md +14 -0
- package/bin/cli.js +29 -9
- package/lib/bundles.js +3 -0
- package/package.json +2 -1
- package/skills/coding/init-workflow/SKILL.md +12 -11
- package/skills/design/sync-design/SKILL.md +8 -2
- package/skills/meta/clean-git/SKILL.md +3 -3
- package/skills/meta/release-project/SKILL.md +9 -9
- package/skills/research/learn-skill/SKILL.md +91 -0
- package/skills/research/learn-skill/evals/evals.json +44 -0
- package/skills/writing/forge-doc/scripts/__pycache__/md_to_pdf.cpython-314.pyc +0 -0
- package/skills-index.json +31 -39
- package/tools/hub/docs/design-previews/git-textual-tui-design.html +359 -0
- package/tools/hub/docs/design-previews/tasks-textual-tui-design.html +371 -0
- package/tools/hub/hub/cli/__init__.py +2 -0
- package/tools/hub/hub/cli/__pycache__/__init__.cpython-314.pyc +0 -0
- package/tools/hub/hub/cli/__pycache__/git.cpython-314.pyc +0 -0
- package/tools/hub/hub/cli/__pycache__/projects.cpython-314.pyc +0 -0
- package/tools/hub/hub/cli/git.py +202 -0
- package/tools/hub/hub/core/__pycache__/projects.cpython-314.pyc +0 -0
- package/tools/hub/hub/tui/__pycache__/app.cpython-314.pyc +0 -0
- package/tools/hub/hub/tui/app.py +126 -3
- package/tools/hub/hub/tui/panels/__pycache__/git.cpython-314.pyc +0 -0
- package/tools/hub/hub/tui/panels/__pycache__/projects.cpython-314.pyc +0 -0
- package/tools/hub/hub/tui/panels/__pycache__/tasks.cpython-314.pyc +0 -0
- package/tools/hub/hub/tui/panels/git.py +213 -67
- package/tools/hub/hub/tui/panels/tasks.py +4 -2
- package/tools/hub/hub.sh +12 -2
- package/tools/hub/pyproject.toml +1 -1
- package/tools/hub/tests/__pycache__/test_cli.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_cli.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_db.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_migrate.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_projects.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_scan.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_scan.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tasks.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_app.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_app.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_git.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_git_panel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_git_panel.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_projects_panel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_projects_panel.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_tasks_panel.cpython-314-pytest-9.0.2.pyc +0 -0
- package/tools/hub/tests/__pycache__/test_tui_tasks_panel.cpython-314-pytest-9.1.0.pyc +0 -0
- package/tools/hub/tests/test_cli.py +107 -0
- package/tools/hub/tests/test_tui_app.py +59 -0
- package/tools/hub/tests/test_tui_git_panel.py +356 -22
- package/tools/hub/tool.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,20 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.17.0] - 2026-06-15
|
|
11
|
+
|
|
12
|
+
## [0.16.0] - 2026-06-15
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
- `hub git`:新增 CLI 子命令,与 TUI git 面板功能对等
|
|
16
|
+
- `hub git status [--project <name>]`:显示当前分支、upstream 同步状态、工作区变更、最近提交
|
|
17
|
+
- `hub git fetch [--project <name>]`:fetch 所有 remote
|
|
18
|
+
- `hub git branches [--project <name>]`:列出所有分支及 ahead/behind 状态
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- `hub`:版本升至 1.1.0
|
|
22
|
+
- `hub`:安装升级机制改为基于源码文件内容哈希(sha256)检测,不再依赖版本号;npm 更新后下次启动自动重装
|
|
23
|
+
|
|
10
24
|
## [0.15.0] - 2026-06-15
|
|
11
25
|
|
|
12
26
|
### Added
|
package/bin/cli.js
CHANGED
|
@@ -184,7 +184,7 @@ if (subcommand === 'list') {
|
|
|
184
184
|
const sorted = [...skills].sort((a, b) => a.bundle.localeCompare(b.bundle) || a.path.split('/').pop().localeCompare(b.path.split('/').pop()))
|
|
185
185
|
if (jsonFlag) {
|
|
186
186
|
console.log(JSON.stringify({
|
|
187
|
-
skills: sorted.map(s => ({ name: s.path.split('/').pop(), path: s.path, bundle: s.bundle })),
|
|
187
|
+
skills: sorted.map(s => ({ name: s.path.split('/').pop(), path: s.path, bundle: s.bundle, global: s.global ?? false })),
|
|
188
188
|
tools: tools.map(t => t.name),
|
|
189
189
|
}, null, 2))
|
|
190
190
|
process.exit(0)
|
|
@@ -225,7 +225,22 @@ if (subcommand === 'status' || subcommand === 'outdated') {
|
|
|
225
225
|
|
|
226
226
|
function icon(status) {
|
|
227
227
|
if (status === 'up-to-date') return chalk.green('✓')
|
|
228
|
-
if (status === 'update') return chalk.
|
|
228
|
+
if (status === 'update') return chalk.red('↑')
|
|
229
|
+
return chalk.dim('—')
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
function userIcon(status, installScope) {
|
|
233
|
+
if (status === 'up-to-date') return chalk.green('✓')
|
|
234
|
+
if (status === 'update') return chalk.red('↑')
|
|
235
|
+
if (installScope === 'essential') return chalk.yellow('»')
|
|
236
|
+
if (installScope === 'global') return chalk.cyan('▸')
|
|
237
|
+
return chalk.dim('—')
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function projectIcon(status, installScope) {
|
|
241
|
+
if (status === 'up-to-date') return chalk.green('✓')
|
|
242
|
+
if (status === 'update') return chalk.red('↑')
|
|
243
|
+
if (installScope === 'project') return chalk.cyan('▸')
|
|
229
244
|
return chalk.dim('—')
|
|
230
245
|
}
|
|
231
246
|
|
|
@@ -233,13 +248,14 @@ if (subcommand === 'status' || subcommand === 'outdated') {
|
|
|
233
248
|
const inst = checkInstalled(s.skillName, s.version ?? '—')
|
|
234
249
|
return {
|
|
235
250
|
name: s.skillName, bundle: s.bundle ?? '—', version: s.version ?? '—',
|
|
251
|
+
installScope: s.installScope ?? null,
|
|
236
252
|
userStatus: scopeSummary(inst.user), projectStatus: scopeSummary(inst.project),
|
|
237
253
|
userDetail: inst.user, projectDetail: inst.project,
|
|
238
254
|
}
|
|
239
255
|
}).sort((a, b) => a.bundle.localeCompare(b.bundle) || a.name.localeCompare(b.name))
|
|
240
256
|
const toolRows = toolItems.map(t => {
|
|
241
257
|
const inst = checkToolInstalled(t.toolName, t.srcPath)
|
|
242
|
-
return { name: t.toolName, version: t.version ?? '—', ...inst }
|
|
258
|
+
return { name: t.toolName, version: t.version ?? '—', installScope: t.installScope ?? null, ...inst }
|
|
243
259
|
})
|
|
244
260
|
|
|
245
261
|
if (jsonFlag) {
|
|
@@ -317,7 +333,8 @@ if (subcommand === 'status' || subcommand === 'outdated') {
|
|
|
317
333
|
console.log(sep)
|
|
318
334
|
console.log(' ' + ''.padEnd(nw + vw + bw + 5) + chalk.dim('user project'))
|
|
319
335
|
for (const r of skillRows) {
|
|
320
|
-
const u =
|
|
336
|
+
const u = userIcon(r.userStatus, r.installScope)
|
|
337
|
+
const p = projectIcon(r.projectStatus, r.installScope)
|
|
321
338
|
console.log(' ' + r.name.padEnd(nw) + ' ' + chalk.dim(r.version.padEnd(vw)) + ' ' + chalk.dim(r.bundle.padEnd(bw)) + ' ' + u + ' ' + p)
|
|
322
339
|
}
|
|
323
340
|
|
|
@@ -325,7 +342,7 @@ if (subcommand === 'status' || subcommand === 'outdated') {
|
|
|
325
342
|
console.log(' ' + chalk.bold('TOOLS') + chalk.dim(` — ${toolRows.length} available`))
|
|
326
343
|
console.log(sep)
|
|
327
344
|
for (const r of toolRows) {
|
|
328
|
-
console.log(' ' + r.name.padEnd(nw) + ' ' + chalk.dim(r.version.padEnd(vw)) + ' ' +
|
|
345
|
+
console.log(' ' + r.name.padEnd(nw) + ' ' + chalk.dim(r.version.padEnd(vw)) + ' ' + userIcon(r.status, r.installScope))
|
|
329
346
|
}
|
|
330
347
|
|
|
331
348
|
// ── hooks ──
|
|
@@ -333,15 +350,17 @@ if (subcommand === 'status' || subcommand === 'outdated') {
|
|
|
333
350
|
console.log('')
|
|
334
351
|
console.log(' ' + chalk.bold('HOOKS') + chalk.dim(` — ${hookItems.length} available`))
|
|
335
352
|
console.log(sep)
|
|
336
|
-
function hIcon(s) {
|
|
337
|
-
if (s === 'installed')
|
|
338
|
-
if (s === 'partial')
|
|
353
|
+
function hIcon(s, installScope) {
|
|
354
|
+
if (s === 'installed') return chalk.green('✓')
|
|
355
|
+
if (s === 'partial') return chalk.yellow('~')
|
|
356
|
+
if (installScope === 'essential') return chalk.yellow('»')
|
|
357
|
+
if (installScope === 'global') return chalk.cyan('›')
|
|
339
358
|
return chalk.dim('—')
|
|
340
359
|
}
|
|
341
360
|
for (const h of hookItems) {
|
|
342
361
|
const inst = checkHookInstalled(h.name)
|
|
343
362
|
const ver = resolveHookDisplayVersion(inst, h.version)
|
|
344
|
-
console.log(' ' + h.name.padEnd(nw) + ' ' + chalk.dim(ver.padEnd(vw)) + ' ' + hIcon(inst.user.status) + ' ' + hIcon(inst.project.status) + ' ' + chalk.dim(h.description))
|
|
363
|
+
console.log(' ' + h.name.padEnd(nw) + ' ' + chalk.dim(ver.padEnd(vw)) + ' ' + hIcon(inst.user.status, h.installScope) + ' ' + hIcon(inst.project.status, h.installScope) + ' ' + chalk.dim(h.description))
|
|
345
364
|
}
|
|
346
365
|
}
|
|
347
366
|
|
|
@@ -352,6 +371,7 @@ if (subcommand === 'status' || subcommand === 'outdated') {
|
|
|
352
371
|
const outdatedNote = outdatedCount ? ' · ' + chalk.yellow(outdatedCount + ' outdated') : ''
|
|
353
372
|
console.log('')
|
|
354
373
|
console.log(chalk.dim(` ${installedSkills} of ${skillRows.length} skills installed · ${installedTools} of ${toolRows.length} tools installed${outdatedNote}`))
|
|
374
|
+
console.log(chalk.dim(` ${chalk.green('✓')} installed ${chalk.red('↑')} update ${chalk.yellow('»')} essential ${chalk.cyan('▸')} global/project — other`))
|
|
355
375
|
console.log('')
|
|
356
376
|
process.exit(0)
|
|
357
377
|
}
|
package/lib/bundles.js
CHANGED
|
@@ -109,6 +109,7 @@ export function getAllSkillItems() {
|
|
|
109
109
|
kind: 'skill',
|
|
110
110
|
skillName: skill.path.split('/').pop(),
|
|
111
111
|
bundle: skill.bundle,
|
|
112
|
+
installScope: skill.installScope ?? null,
|
|
112
113
|
srcPath,
|
|
113
114
|
version: readVersion(srcPath),
|
|
114
115
|
}
|
|
@@ -122,6 +123,7 @@ export function getAllToolItems() {
|
|
|
122
123
|
return {
|
|
123
124
|
kind: 'tool',
|
|
124
125
|
toolName: tool.name,
|
|
126
|
+
installScope: tool.installScope ?? null,
|
|
125
127
|
srcPath,
|
|
126
128
|
version: readToolMeta(path.join(srcPath, 'tool.json')),
|
|
127
129
|
}
|
|
@@ -184,6 +186,7 @@ export function getAllHookItems() {
|
|
|
184
186
|
const srcPath = path.join(repoRoot, hook.path, `${hook.name}.sh`)
|
|
185
187
|
return {
|
|
186
188
|
...hook,
|
|
189
|
+
installScope: hook.installScope ?? null,
|
|
187
190
|
srcPath,
|
|
188
191
|
version: readHookVersion(srcPath),
|
|
189
192
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "harveyz-skill",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.0",
|
|
4
4
|
"description": "Skill manager for Claude Code, Cursor, and Codex",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"bundles.json",
|
|
17
17
|
"skills-index.json",
|
|
18
18
|
"CHANGELOG.md",
|
|
19
|
+
"skills/research/learn-skill/",
|
|
19
20
|
"skills/research/extract-url/",
|
|
20
21
|
"skills/research/extract-vision/",
|
|
21
22
|
"skills/research/learn-video/",
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: init-workflow
|
|
3
|
-
description: "Initialize or update git branch management standards: reads workflow-config.yml, audits config, incrementally generates and deploys git hooks (pre-commit, commit-msg, pre-push, post-checkout), and generates workflow docs. Triggers: initializing a new git repo, first-time git setup, user asks to set/update branch protection or naming rules, reinstalling git hooks, or syncing after skill/template updates."
|
|
3
|
+
description: "Initialize or update git branch management standards: reads .hskill/init-workflow/workflow-config.yml, audits config, incrementally generates and deploys git hooks (pre-commit, commit-msg, pre-push, post-checkout), and generates workflow docs. Triggers: initializing a new git repo, first-time git setup, user asks to set/update branch protection or naming rules, reinstalling git hooks, or syncing after skill/template updates."
|
|
4
4
|
user_invocable: true
|
|
5
5
|
version: "4.1.0"
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Git 工作流初始化
|
|
9
9
|
|
|
10
|
-
读取
|
|
10
|
+
读取 `.hskill/init-workflow/workflow-config.yml`,审核配置,差量部署 git hooks。
|
|
11
11
|
重新运行时自动检测配置变更、用户手改冲突、用户代码与新规则的交叉冲突,一次性汇总让用户决策后再写入。
|
|
12
12
|
|
|
13
13
|
---
|
|
@@ -26,16 +26,17 @@ git rev-parse --show-toplevel
|
|
|
26
26
|
|
|
27
27
|
### Step 2 — 读取配置
|
|
28
28
|
|
|
29
|
-
|
|
29
|
+
按以下顺序查找配置文件:
|
|
30
30
|
|
|
31
|
-
1.
|
|
32
|
-
2. 项目根目录
|
|
31
|
+
1. `.hskill/init-workflow/workflow-config.yml`
|
|
32
|
+
2. 项目根目录 `workflow-config.yml`(向后兼容)
|
|
33
|
+
3. 项目根目录 `.claude/workflow-config.yml`(向后兼容)
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
- 使用默认配置(从此 skill 的 `references/workflow-config.yml`
|
|
35
|
+
若均不存在,询问用户:
|
|
36
|
+
- 使用默认配置(从此 skill 的 `references/workflow-config.yml` 复制到 `.hskill/init-workflow/workflow-config.yml`)
|
|
36
37
|
- 还是中止并自行创建后重新运行
|
|
37
38
|
|
|
38
|
-
找到后读取并解析 YAML
|
|
39
|
+
找到后读取并解析 YAML。若文件来自向后兼容路径(2 或 3),询问用户是否将其移动到 `.hskill/init-workflow/workflow-config.yml`;用户同意则执行移动,否则继续使用原位置(不影响本次运行)。
|
|
39
40
|
|
|
40
41
|
---
|
|
41
42
|
|
|
@@ -154,13 +155,13 @@ git config merge.ff false
|
|
|
154
155
|
|
|
155
156
|
### Step 7 — 从配置渲染并写入工作流文档(差量)
|
|
156
157
|
|
|
157
|
-
每次运行都根据当前
|
|
158
|
+
每次运行都根据当前 `.hskill/init-workflow/workflow-config.yml` 的最终状态重新渲染文档,确保文档与配置始终一致。
|
|
158
159
|
|
|
159
160
|
#### 7a. 渲染文档
|
|
160
161
|
|
|
161
162
|
```bash
|
|
162
163
|
python3 <skill-path>/references/render_docs.py \
|
|
163
|
-
workflow-config.yml \
|
|
164
|
+
.hskill/init-workflow/workflow-config.yml \
|
|
164
165
|
<skill-path>/references/git-workflow-template.md \
|
|
165
166
|
docs/reference/git-workflow.md
|
|
166
167
|
# 输出 NEW / UPDATED / UNCHANGED
|
|
@@ -205,7 +206,7 @@ python3 <skill-path>/references/render_docs.py \
|
|
|
205
206
|
```
|
|
206
207
|
文件 状态
|
|
207
208
|
─────────────────────────────────────────────────────
|
|
208
|
-
workflow-config.yml
|
|
209
|
+
.hskill/init-workflow/workflow-config.yml 已读取
|
|
209
210
|
.githooks/.workflow-config.lock UPDATED(记录新配置快照)
|
|
210
211
|
.githooks/pre-commit UPDATED(main 块 hash 更新;develop 块新增)
|
|
211
212
|
.githooks/commit-msg UNCHANGED
|
|
@@ -15,7 +15,7 @@ user_invocable: true
|
|
|
15
15
|
|
|
16
16
|
## 步骤 ①:读取 Manifest
|
|
17
17
|
|
|
18
|
-
读取
|
|
18
|
+
读取 `.hskill/sync-design/manifest.json`。
|
|
19
19
|
|
|
20
20
|
**如果文件不存在:**
|
|
21
21
|
执行【附录 A:首次初始化流程】,完成后继续步骤 ②。
|
|
@@ -182,7 +182,7 @@ git diff <entry.lastSyncCommit 或 manifest.baseBranch(如无 lastSyncCommit
|
|
|
182
182
|
**用户选「是」:**
|
|
183
183
|
1. `git rev-parse HEAD` 获取当前 commit hash
|
|
184
184
|
2. 将所有已处理 entry 的 `lastSyncCommit` 更新为该 hash
|
|
185
|
-
3. 写回
|
|
185
|
+
3. 写回 `.hskill/sync-design/manifest.json`(含配置演进的 patterns 变更)
|
|
186
186
|
4. 询问是否 `git add` 并给出建议 commit message:
|
|
187
187
|
`chore: sync HTML design backups — <entry id 列表>`
|
|
188
188
|
|
|
@@ -304,6 +304,12 @@ find src -name "*.scss" -o -name "variables.css" 2>/dev/null | head -3
|
|
|
304
304
|
|
|
305
305
|
### A-5. 创建 Manifest
|
|
306
306
|
|
|
307
|
+
```bash
|
|
308
|
+
mkdir -p .hskill/sync-design
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
将以下内容写入 `.hskill/sync-design/manifest.json`:
|
|
312
|
+
|
|
307
313
|
```json
|
|
308
314
|
{
|
|
309
315
|
"version": 3,
|
|
@@ -21,7 +21,7 @@ version: "1.0.0"
|
|
|
21
21
|
|
|
22
22
|
## Step 1:读取配置
|
|
23
23
|
|
|
24
|
-
检查 `.
|
|
24
|
+
检查 `.hskill/clean-git/branch-cleanup.md` 是否存在:
|
|
25
25
|
|
|
26
26
|
**存在** → 解析三段内容:
|
|
27
27
|
- `## Always Delete` 段:每行 `` `pattern` `` 为必删 glob 规则
|
|
@@ -182,8 +182,8 @@ git branch -r | grep "origin/<branch>"
|
|
|
182
182
|
**若本次无配置文件,询问:**
|
|
183
183
|
|
|
184
184
|
```
|
|
185
|
-
未检测到 .
|
|
185
|
+
未检测到 .hskill/clean-git/branch-cleanup.md。
|
|
186
186
|
是否根据本次规则生成配置文件,方便下次复用?[y/n]
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
若用户确认,生成 `.
|
|
189
|
+
若用户确认,生成 `.hskill/clean-git/branch-cleanup.md`,内容包含本次使用的 Always Delete / Always Keep 规则和 LLM context。
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: release-project
|
|
3
|
-
description: "Universal project release skill. Triggers on: release, bump version, publish, new version, cut release. Two phases: Init (first run — scans project and generates .hskill/release-profile.md); Execute (daily use — reads profile and runs full release flow). Works with npm, Python, Rust, Java, or any versioned project."
|
|
3
|
+
description: "Universal project release skill. Triggers on: release, bump version, publish, new version, cut release. Two phases: Init (first run — scans project and generates .hskill/release-project/release-profile.md); Execute (daily use — reads profile and runs full release flow). Works with npm, Python, Rust, Java, or any versioned project."
|
|
4
4
|
user_invocable: true
|
|
5
5
|
version: "1.1.0"
|
|
6
6
|
---
|
|
@@ -9,17 +9,17 @@ version: "1.1.0"
|
|
|
9
9
|
|
|
10
10
|
通用项目发布 skill,两个阶段:
|
|
11
11
|
|
|
12
|
-
- **Init** — 扫描项目,和用户确认,生成 `.hskill/release-profile.md`(每个项目做一次)
|
|
12
|
+
- **Init** — 扫描项目,和用户确认,生成 `.hskill/release-project/release-profile.md`(每个项目做一次)
|
|
13
13
|
- **Execute** — 读取 profile,完全按照它走发布流程
|
|
14
14
|
|
|
15
15
|
---
|
|
16
16
|
|
|
17
17
|
## 入口判断
|
|
18
18
|
|
|
19
|
-
检查 `.hskill/release-profile.md` 是否存在:
|
|
19
|
+
检查 `.hskill/release-project/release-profile.md` 是否存在:
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
ls .hskill/release-profile.md 2>/dev/null && echo "EXISTS" || echo "NOT_FOUND"
|
|
22
|
+
ls .hskill/release-project/release-profile.md 2>/dev/null && echo "EXISTS" || echo "NOT_FOUND"
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
- **NOT_FOUND** → 执行 Init 阶段
|
|
@@ -36,7 +36,7 @@ ls .hskill/release-profile.md 2>/dev/null && echo "EXISTS" || echo "NOT_FOUND"
|
|
|
36
36
|
|
|
37
37
|
依次从以下来源收集信息:
|
|
38
38
|
|
|
39
|
-
1.
|
|
39
|
+
1. 项目配置文件:`.hskill/init-workflow/workflow-config.yml`、`CLAUDE.md`、`AGENTS.md`、`CONTRIBUTING.md`
|
|
40
40
|
2. git 历史和现有分支:
|
|
41
41
|
|
|
42
42
|
```bash
|
|
@@ -101,18 +101,18 @@ ls .github/workflows/ .gitlab-ci.yml .circleci/ 2>/dev/null
|
|
|
101
101
|
读取 `references/release-profile-template.md` 作为骨架,把 I-1 到 I-4 收集到的信息填进去。
|
|
102
102
|
|
|
103
103
|
```bash
|
|
104
|
-
mkdir -p .hskill
|
|
104
|
+
mkdir -p .hskill/release-project
|
|
105
105
|
```
|
|
106
106
|
|
|
107
107
|
模板只提供四个顶级节(分支模型、版本文件、发布方式、特殊规则),每节的具体内容完全由项目决定,用最能清楚表达意图的方式写——几行文字、表格、命令示例均可。没有特殊规则就删掉那节。
|
|
108
108
|
|
|
109
|
-
写完后给用户看,确认无误再保存。告诉用户:**`.hskill/release-profile.md` 可以随时手动编辑**,是下次发版的唯一依据。
|
|
109
|
+
写完后给用户看,确认无误再保存。告诉用户:**`.hskill/release-project/release-profile.md` 可以随时手动编辑**,是下次发版的唯一依据。
|
|
110
110
|
|
|
111
111
|
---
|
|
112
112
|
|
|
113
113
|
## Execute 阶段
|
|
114
114
|
|
|
115
|
-
**读取 `.hskill/release-profile.md`,完全按照它执行。** profile 是唯一依据,不在 profile 里的事不要自己发明。
|
|
115
|
+
**读取 `.hskill/release-project/release-profile.md`,完全按照它执行。** profile 是唯一依据,不在 profile 里的事不要自己发明。
|
|
116
116
|
|
|
117
117
|
### Step E-0 — 读取 profile + 前置检查
|
|
118
118
|
|
|
@@ -215,7 +215,7 @@ git push origin <tag>
|
|
|
215
215
|
|
|
216
216
|
## 常见问题
|
|
217
217
|
|
|
218
|
-
**profile 信息有误** — 直接编辑 `.hskill/release-profile.md` 后重新触发 Execute。
|
|
218
|
+
**profile 信息有误** — 直接编辑 `.hskill/release-project/release-profile.md` 后重新触发 Execute。
|
|
219
219
|
|
|
220
220
|
**发版前检查失败** — 按失败信息修复后,重新从 E-0 开始。
|
|
221
221
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: learn-skill
|
|
3
|
+
description: "Deep-reads a single skill's SKILL.md to help you understand its internal logic. Analyzes across four dimensions: Design Philosophy (why it was designed this way), Execution Flow (how it runs), Standards (what conventions it follows), and Editing Conditions (when to modify it). Use when you want to understand a skill's design intent, how a skill works, its workflow, or the reasoning behind its design. Trigger phrases: 'help me understand this skill', 'how does this skill work', 'explain this skill', 'what is this skill doing', 'walk me through this skill', 'what's the design philosophy of this skill'."
|
|
4
|
+
user_invocable: true
|
|
5
|
+
version: "1.4.0"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# inspect-skill
|
|
9
|
+
|
|
10
|
+
深度解读单个 skill 的 SKILL.md,帮助用户理解它的设计意图、运作方式、规范约定和维护逻辑。输出的是解读,不是评审。
|
|
11
|
+
|
|
12
|
+
如果用户的 prompt 含有评估意图(「有什么问题」、「可以发布了吗」、「quality report」等),不要顺着评估——这个 skill 的定位是帮用户理解 skill,不是审查它。完成解读后,在结尾询问用户是否需要另外做评审。
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Step 1 — 定位目标 skill
|
|
17
|
+
|
|
18
|
+
从上下文判断要分析哪个 skill:
|
|
19
|
+
|
|
20
|
+
1. **直接路径**:用户提供了路径(如 `skills/meta/analyze-skill/`)→ 直接使用
|
|
21
|
+
2. **名称推断**:用户提到了 skill 名称 → 在 `~/.claude/skills/` 和当前 repo 的 `skills/` 目录中搜索
|
|
22
|
+
3. **当前上下文**:对话中刚刚在讨论某个 skill → 直接分析该 skill
|
|
23
|
+
4. **不明确**:列出候选,请用户选择
|
|
24
|
+
|
|
25
|
+
读取目标 `SKILL.md`。若存在 `references/` 子目录,读取其中每个不超过 200 行的文件(逐个判断,不合并计算)。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Step 2 — 四维解读
|
|
30
|
+
|
|
31
|
+
从以下四个维度解读 skill。每个维度的目标是让读者理解,而不是评判好坏。具体引用 skill 中的实际段落或步骤来说明,不要泛泛而谈。
|
|
32
|
+
|
|
33
|
+
### 维度 1:设计哲学(Design Philosophy)
|
|
34
|
+
|
|
35
|
+
解释这个 skill 背后的设计意图和取舍逻辑。大多数 SKILL.md 不会直接写「我的设计哲学是…」,需要从它做了什么、省略了什么、在哪里明确约束而在哪里信任模型来推断:
|
|
36
|
+
|
|
37
|
+
- 这个 skill 做了哪些有意识的取舍?为什么选择这种方式而不是另一种?
|
|
38
|
+
- 它在哪些地方信任模型自己判断,在哪些地方选择了明确约束?
|
|
39
|
+
- 它的「lean」体现在哪里——哪些东西被刻意省略了?
|
|
40
|
+
- 如果有一个核心设计原则贯穿整个 skill,那是什么?
|
|
41
|
+
|
|
42
|
+
### 维度 2:流程执行(Execution Flow)
|
|
43
|
+
|
|
44
|
+
解释这个 skill 实际上是怎么跑的:
|
|
45
|
+
|
|
46
|
+
- 它的入口在哪里?什么触发条件会启动它?
|
|
47
|
+
- 执行路径是什么?主流程的步骤顺序是什么?
|
|
48
|
+
- 有哪些分支或条件判断?不同情况下走哪条路?
|
|
49
|
+
- 它在什么时候「结束」?输出或退出条件是什么?
|
|
50
|
+
- 步骤之间有哪些依赖关系——前一步的产物被后一步怎么用?
|
|
51
|
+
|
|
52
|
+
### 维度 3:规范标准(Standards)
|
|
53
|
+
|
|
54
|
+
解释这个 skill 遵循了哪些约定和规范:
|
|
55
|
+
|
|
56
|
+
- Frontmatter 字段的设置方式(name、description、version 各写了什么、为什么这样写)
|
|
57
|
+
- Description 的触发策略(覆盖了哪些使用场景,用了什么语言)
|
|
58
|
+
- 篇幅和结构的组织方式(是否使用了 bundled resources,如何分层)
|
|
59
|
+
- 输出格式的约定(期望产出什么,格式如何定义)
|
|
60
|
+
- 写作风格的选择(祈使句、中英文混用、注释方式等)
|
|
61
|
+
|
|
62
|
+
### 维度 4:编辑条件(Editing Conditions)
|
|
63
|
+
|
|
64
|
+
解释在什么情况下应该修改这个 skill:
|
|
65
|
+
|
|
66
|
+
- 哪些外部变化会让这个 skill 失效或过时?(依赖的工具、路径、API 变了怎么办)
|
|
67
|
+
- 哪些使用场景目前没有被覆盖——如果用户遇到这些情况,skill 会怎么处理?
|
|
68
|
+
- skill 里有没有硬编码的内容?它们在什么条件下需要更新?
|
|
69
|
+
- 如果要扩展这个 skill 的能力,最自然的切入点在哪里?
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Step 3 — 完整性自查(输出前)
|
|
74
|
+
|
|
75
|
+
分析完成后,**先不要输出报告**,对照原始 SKILL.md 检查一遍:
|
|
76
|
+
|
|
77
|
+
- **遗漏**:skill 里的关键步骤、分支、约定,分析里有没有覆盖?
|
|
78
|
+
- **准确性**:描述是否和原文一致,有没有误读?
|
|
79
|
+
- **心理模型**:读完报告的人,能不能不翻原文就理解这个 skill 是怎么工作的?
|
|
80
|
+
|
|
81
|
+
发现问题就补进分析,然后进入 Step 4 输出。
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Step 4 — 输出解读报告
|
|
86
|
+
|
|
87
|
+
**语言:全部中文。** 保留英文的只有:维度标题括号内的英文名、代码/命令/字段名。
|
|
88
|
+
|
|
89
|
+
报告覆盖四个维度,顺序和格式灵活,不要加评分、verdict,或建议修改的段落。
|
|
90
|
+
|
|
91
|
+
报告结尾询问用户:「还有哪个部分想深入了解?」
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "inspect-skill",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "帮我分析一下 contribute-skill 这个 skill,它有什么问题,有没有什么需要改进的地方?目录在 /Users/harveyzhang96/Projects/harveyz-skill/skills/meta/contribute-skill/",
|
|
7
|
+
"expected_output": "中文解读报告,以设计哲学为第一个维度,涵盖四维,不含额外评估段落,结尾以收尾问句收口。",
|
|
8
|
+
"files": ["/Users/harveyzhang96/Projects/harveyz-skill/skills/meta/contribute-skill/SKILL.md"],
|
|
9
|
+
"assertions": [
|
|
10
|
+
"报告包含四个维度,且设计哲学(Design Philosophy)是第一个出现的维度标题",
|
|
11
|
+
"报告不包含评分标签(Excellent / Good / Needs Work / Poor 或数字评分)",
|
|
12
|
+
"报告不包含额外评估段落(如 '## 问题与改进建议'、'## 发布评估'、'## 改进建议'、'## 总体结论' 等评审性标题)",
|
|
13
|
+
"报告主体叙述使用中文",
|
|
14
|
+
"报告结尾包含收尾问句(询问用户是否想深入了解某部分),而不是以改进建议或评审内容结束"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": 2,
|
|
19
|
+
"prompt": "can you inspect the analyze-skill skill and give me a quality report? path is /Users/harveyzhang96/Projects/harveyz-skill/skills/meta/analyze-skill/SKILL.md",
|
|
20
|
+
"expected_output": "中文解读报告,以设计哲学为第一个维度,涵盖四维,不含额外评估段落,结尾以收尾问句收口。",
|
|
21
|
+
"files": ["/Users/harveyzhang96/Projects/harveyz-skill/skills/meta/analyze-skill/SKILL.md"],
|
|
22
|
+
"assertions": [
|
|
23
|
+
"报告包含四个维度,且设计哲学(Design Philosophy)是第一个出现的维度标题",
|
|
24
|
+
"报告不包含评分标签(Excellent / Good / Needs Work / Poor 或数字评分)",
|
|
25
|
+
"报告不包含额外评估段落(如 '## 问题与改进建议'、'## 发布评估'、'## 改进建议'、'## 总体结论' 等评审性标题)",
|
|
26
|
+
"报告主体叙述使用中文",
|
|
27
|
+
"报告结尾包含收尾问句(询问用户是否想深入了解某部分),而不是以改进建议或评审内容结束"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": 3,
|
|
32
|
+
"prompt": "这个 clean-git skill 可以发布了吗?帮我做个全面的 skill 质量审查。路径:/Users/harveyzhang96/Projects/harveyz-skill/skills/meta/clean-git/SKILL.md",
|
|
33
|
+
"expected_output": "中文解读报告,以设计哲学为第一个维度,涵盖四维,不含额外评估段落,结尾以收尾问句收口。",
|
|
34
|
+
"files": ["/Users/harveyzhang96/Projects/harveyz-skill/skills/meta/clean-git/SKILL.md"],
|
|
35
|
+
"assertions": [
|
|
36
|
+
"报告包含四个维度,且设计哲学(Design Philosophy)是第一个出现的维度标题",
|
|
37
|
+
"报告不包含评分标签(Excellent / Good / Needs Work / Poor 或数字评分)",
|
|
38
|
+
"报告不包含额外评估段落(如 '## 问题与改进建议'、'## 发布评估'、'## 改进建议'、'## 总体结论' 等评审性标题)",
|
|
39
|
+
"报告主体叙述使用中文",
|
|
40
|
+
"报告结尾包含收尾问句(询问用户是否想深入了解某部分),而不是以改进建议或评审内容结束"
|
|
41
|
+
]
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
}
|
|
Binary file
|
package/skills-index.json
CHANGED
|
@@ -4,22 +4,12 @@
|
|
|
4
4
|
"tools": "开发者 OS 工具(hub — 项目管理 + git 状态 + 任务跟踪)"
|
|
5
5
|
},
|
|
6
6
|
"tools": [
|
|
7
|
-
{
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
},
|
|
11
|
-
{
|
|
12
|
-
"name": "todo-tool",
|
|
13
|
-
"bundle": "shell-tools"
|
|
14
|
-
},
|
|
15
|
-
{
|
|
16
|
-
"name": "hub",
|
|
17
|
-
"path": "tools/hub",
|
|
18
|
-
"bundle": "tools"
|
|
19
|
-
}
|
|
7
|
+
{ "name": "p-launch", "bundle": "shell-tools", "installScope": "global" },
|
|
8
|
+
{ "name": "todo-tool", "bundle": "shell-tools", "installScope": "global" },
|
|
9
|
+
{ "name": "hub", "path": "tools/hub", "bundle": "tools", "installScope": "essential" }
|
|
20
10
|
],
|
|
21
11
|
"bundleMeta": {
|
|
22
|
-
"research": "研究工具(extract-url + learn-video + extract-vision)",
|
|
12
|
+
"research": "研究工具(extract-url + learn-video + extract-vision + learn-skill)",
|
|
23
13
|
"creative": "创意工具(capture-todo + capture-insight)",
|
|
24
14
|
"coding": "程序工具(init-workflow + setup-debug + dispatch-task + close-task)",
|
|
25
15
|
"writing": "写作工具(forge-doc + draw-diagram + manage-docs + manage-dir + migrate-spec)",
|
|
@@ -27,36 +17,38 @@
|
|
|
27
17
|
"meta": "元操作工具(analyze-skill + clean-git + archive-skill + dedup-skill + contribute-skill + publish-skill + release-project + runby-opencode)"
|
|
28
18
|
},
|
|
29
19
|
"skills": [
|
|
30
|
-
{ "path": "research/
|
|
31
|
-
{ "path": "research/extract-
|
|
32
|
-
{ "path": "research/
|
|
33
|
-
{ "path": "
|
|
34
|
-
{ "path": "creative/capture-
|
|
35
|
-
{ "path": "
|
|
36
|
-
{ "path": "coding/
|
|
37
|
-
{ "path": "coding/
|
|
38
|
-
{ "path": "coding/
|
|
39
|
-
{ "path": "
|
|
40
|
-
{ "path": "writing/
|
|
41
|
-
{ "path": "writing/
|
|
42
|
-
{ "path": "writing/manage-
|
|
43
|
-
{ "path": "writing/
|
|
44
|
-
{ "path": "
|
|
45
|
-
{ "path": "design/
|
|
46
|
-
{ "path": "design/
|
|
47
|
-
{ "path": "
|
|
48
|
-
{ "path": "meta/
|
|
49
|
-
{ "path": "meta/
|
|
50
|
-
{ "path": "meta/
|
|
51
|
-
{ "path": "meta/
|
|
52
|
-
{ "path": "meta/
|
|
53
|
-
{ "path": "meta/
|
|
54
|
-
{ "path": "meta/
|
|
20
|
+
{ "path": "research/learn-skill", "bundle": "research", "installScope": "global" },
|
|
21
|
+
{ "path": "research/extract-url", "bundle": "research", "installScope": "global" },
|
|
22
|
+
{ "path": "research/extract-vision", "bundle": "research", "installScope": "global" },
|
|
23
|
+
{ "path": "research/learn-video", "bundle": "research", "installScope": "global" },
|
|
24
|
+
{ "path": "creative/capture-todo", "bundle": "creative", "installScope": "essential" },
|
|
25
|
+
{ "path": "creative/capture-insight","bundle": "creative", "installScope": "essential" },
|
|
26
|
+
{ "path": "coding/init-workflow", "bundle": "coding", "installScope": "essential" },
|
|
27
|
+
{ "path": "coding/setup-debug", "bundle": "coding", "installScope": "project" },
|
|
28
|
+
{ "path": "coding/dispatch-task", "bundle": "coding", "installScope": "global" },
|
|
29
|
+
{ "path": "coding/close-task", "bundle": "coding", "installScope": "global" },
|
|
30
|
+
{ "path": "writing/forge-doc", "bundle": "writing", "installScope": "global" },
|
|
31
|
+
{ "path": "writing/draw-diagram", "bundle": "writing", "installScope": "global" },
|
|
32
|
+
{ "path": "writing/manage-docs", "bundle": "writing", "installScope": "project" },
|
|
33
|
+
{ "path": "writing/manage-dir", "bundle": "writing", "installScope": "project" },
|
|
34
|
+
{ "path": "writing/migrate-spec", "bundle": "writing", "installScope": "project" },
|
|
35
|
+
{ "path": "design/scout-brand", "bundle": "design", "installScope": "project" },
|
|
36
|
+
{ "path": "design/build-style", "bundle": "design", "installScope": "project" },
|
|
37
|
+
{ "path": "design/sync-design", "bundle": "design", "installScope": "project" },
|
|
38
|
+
{ "path": "meta/analyze-skill", "bundle": "meta" },
|
|
39
|
+
{ "path": "meta/clean-git", "bundle": "meta", "installScope": "essential" },
|
|
40
|
+
{ "path": "meta/archive-skill", "bundle": "meta" },
|
|
41
|
+
{ "path": "meta/dedup-skill", "bundle": "meta" },
|
|
42
|
+
{ "path": "meta/contribute-skill", "bundle": "meta" },
|
|
43
|
+
{ "path": "meta/publish-skill", "bundle": "meta" },
|
|
44
|
+
{ "path": "meta/runby-opencode", "bundle": "meta" },
|
|
45
|
+
{ "path": "meta/release-project", "bundle": "meta", "installScope": "essential" }
|
|
55
46
|
],
|
|
56
47
|
"hooks": [
|
|
57
48
|
{
|
|
58
49
|
"name": "check-similar-branch",
|
|
59
50
|
"description": "用 LLM 语义分析检测相似分支",
|
|
51
|
+
"installScope": "essential",
|
|
60
52
|
"path": "hooks/check-similar-branch",
|
|
61
53
|
"event": "PreToolUse",
|
|
62
54
|
"matcher": "Bash",
|