dsh-mattpocock-skills-deck 1.7.13 → 1.7.15
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/README.md +202 -154
- package/lib/bootstrap.js +207 -0
- package/lib/client.js +4362 -2638
- package/lib/commentThreads.js +244 -0
- package/lib/detectChain.js +267 -0
- package/lib/dispatchMeta.js +23 -0
- package/lib/handoffClaim.js +167 -0
- package/lib/index.js +196 -3840
- package/lib/issueDetail.js +349 -0
- package/lib/issueList.js +291 -0
- package/lib/logPhones.js +118 -0
- package/lib/logStore.js +278 -0
- package/lib/mapBody.js +81 -0
- package/lib/namingGuardian.js +347 -0
- package/lib/pickerShell.js +114 -0
- package/lib/platform/darwin/index.js +11 -0
- package/lib/platform/index.js +47 -0
- package/lib/platform/linux/index.js +10 -0
- package/lib/platform/win32/index.js +22 -0
- package/lib/platformChannel.js +250 -0
- package/lib/publishFlow.js +187 -0
- package/lib/remotePredicates.js +74 -0
- package/lib/repoKeys.js +250 -0
- package/lib/sessionLifecycle.js +64 -0
- package/lib/sessionRefresh.js +319 -0
- package/lib/sessionSnapshot.js +330 -0
- package/lib/skillProbe.js +344 -0
- package/lib/ticketGrouping.js +62 -0
- package/lib/tracker/backends/README.md +33 -33
- package/lib/tracker/backends/github/backend.js +106 -0
- package/lib/tracker/backends/github/checks.js +55 -0
- package/lib/tracker/backends/github/client.js +196 -135
- package/lib/tracker/backends/github/errors.js +51 -15
- package/lib/tracker/backends/github/fallback-reason.js +50 -0
- package/lib/tracker/backends/github/index.js +23 -490
- package/lib/tracker/backends/github/init-project.js +213 -0
- package/lib/tracker/backends/github/issues-write.js +276 -0
- package/lib/tracker/backends/github/issues.js +140 -290
- package/lib/tracker/backends/github/normalize.js +62 -0
- package/lib/tracker/backends/github/pulls.js +84 -0
- package/lib/tracker/backends/github/queries.js +55 -1
- package/lib/tracker/backends/github/repo.js +155 -0
- package/lib/tracker/backends/gitlab/graph-blocking.js +245 -0
- package/lib/tracker/backends/gitlab/graph-membership.js +101 -0
- package/lib/tracker/backends/gitlab/graph.js +7 -344
- package/lib/tracker/backends/markdown/issues-create.js +86 -0
- package/lib/tracker/backends/markdown/issues-labels.js +45 -0
- package/lib/tracker/backends/markdown/issues-locate.js +77 -0
- package/lib/tracker/backends/markdown/issues-patch.js +185 -0
- package/lib/tracker/backends/markdown/issues-read.js +192 -0
- package/lib/tracker/backends/markdown/issues-status.js +140 -0
- package/lib/tracker/backends/markdown/issues.js +11 -683
- package/lib/tracker/capability.js +60 -58
- package/lib/tracker/contract.js +4 -1
- package/lib/tracker/detection/detectionService.js +1 -1
- package/lib/tracker/detection/workspaceStore.js +74 -69
- package/lib/tracker/fixContract.js +2 -2
- package/lib/tracker/generic.js +11 -8
- package/lib/tracker/index.js +3 -1
- package/lib/tracker/predicateCore.js +120 -0
- package/lib/tracker/{predicateRegistry.js → predicatePrimitives.js} +19 -121
- package/lib/tracker/{registry.js → registryCore.js} +21 -165
- package/lib/tracker/registryShape.js +82 -0
- package/lib/tracker/registryViews.js +85 -0
- package/lib/tracker/snapshot.js +46 -8
- package/lib/update.js +223 -0
- package/lib/updateReader.js +206 -0
- package/lib/updateStore.js +323 -0
- package/lib/workspaceCwd.js +99 -0
- package/package.json +2 -2
- package/shared/naming-attribution.js +172 -0
- package/shared/naming-titles.js +146 -0
- package/shared/{naming-guardian.js → naming-tracking.js} +285 -498
- package/shared/tracker/chain-evaluate.js +268 -0
- package/shared/tracker/chain-types.js +233 -0
- package/shared/tracker/chain-validate.js +244 -0
- package/shared/tracker/{check-catalog.js → check-catalog-dirs.js} +245 -356
- package/shared/tracker/check-catalog-views.js +154 -0
- package/shared/tracker/deck-derive.js +219 -183
- package/shared/tracker/shape.js +218 -202
- package/shared/update/commands.js +73 -0
- package/shared/update/ports.js +5 -0
- package/shared/update/service.js +348 -0
- package/shared/tracker/chain.js +0 -682
package/README.md
CHANGED
|
@@ -1,208 +1,256 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
> DSH(DeepSeek Harness)Web 界面的 **Matt Skills Deck 控制面板**插件(Client + Host 双端)——**非官方** Matt Pocock 技能套件(mattpocock/skills)配套工具:wayfinder 地图/票务/进度、triage / grilling / handoff 动作注入。
|
|
4
|
-
> **设计理念**:Matt 的 map 拨开迷雾看到终点;本插件再加一层游戏式任务栏——接任务、推进一步、随时存档交接,每一步都清晰可见。
|
|
5
|
-
> **配合 [Matt Pocock skills](https://github.com/mattpocock/skills) 的 wayfinder / triage / grilling / handoff 等技能使用**:
|
|
6
|
-
> 输入区状态栏胶囊(可接/阻塞/沉淀/交接/环境/更新)+ 右侧 details 列面板(列表 / 技能 / 环境检查三视图,
|
|
7
|
-
> 唯一打开形式)+ GitHub issue 动作注入(诊断 / 修复 / 讨论 / 执行,均带 `/wayfinder` `/triage` 技能命令)
|
|
8
|
-
> + 交接开新会话。
|
|
9
|
-
|
|
10
|
-
- **插件包名**: `dsh-mattpocock-skills-deck`(可分发 npm 包,见 `package/`,当前 **v1.7.13**(`latest`,品牌迁移自 dsh-waystation v1.5.0,`npm view` 已验):v1.4 详情页(#441)+ v1.5 升级 map 全量落地 —— 状态栏 BUG/诊断过滤 + 设置直达 + 删 panelHeight + Matt 引导 + 新增 wayfinder + 仓库身份 + 双语 + 仓库级缓存架构(git 根检测 → 磁盘缓存秒开 → 自动探测刷新)+ 进度契约与阶段闸门 + 正文格式容错 + markdown 白名单渲染 + 3 项 bug 修复 + T10 自动刷新机制(变化行高亮/即时转圈反馈))
|
|
11
|
-
- **动态版 pluginId**: `wfst-1`(v9–v24 迭代产物)
|
|
12
|
-
- **平台**: Client(浏览器页面)+ Host(Node 进程,gh CLI 数据层)
|
|
13
|
-
- **配套**: [mattpocock/skills](https://github.com/mattpocock/skills)(wayfinder / triage / grilling / handoff / ask-matt 等)
|
|
14
|
-
- **两种形态**: ① 正式安装(npm 一条命令,开机自启,推荐);② 动态加载(进程内,会话级)
|
|
15
|
-
## 功能
|
|
16
|
-
|
|
17
|
-
| 模块 | 说明 |
|
|
18
|
-
|---|---|
|
|
19
|
-
| 状态栏胶囊 | 输入区上方:可接 / 阻塞 / 沉淀(零丢失快照)/ 交接 / 环境 / 更新,点击直达对应面板视图 |
|
|
20
|
-
| 面板 · 列表 | GitHub issue 全列表(map 置顶 + 子票迷你圆环进度)、标签过滤 chips(GitHub 配置色)、阻塞筛选、已关闭折叠、行级动作按钮;行布局 = 两行结构(编号/map 竖排 + 标题占满整宽限 2 行 + 标签/按钮行) |
|
|
21
|
-
| 标签贪心折叠 | 单行不换行:宽面板显示多标签、窄面板少标签(最少 1 个),放不下的折叠为 +N 弹窗(fixed 定位 · 自适应面板左右边界 · 内容完整可见) |
|
|
22
|
-
| 进度显示 | map 行右侧 18px 迷你圆环 + n/total(等宽数字右缘对齐,圆环零间隙) |
|
|
23
|
-
| 面板 · 技能 | 技能雷达(推荐 / 列表 / 圆环),点击注入 /skill |
|
|
24
|
-
| 面板 · 环境检查 | 8 项前置检查(仓库定位 / setup / tracker / gh CLI / 登录 / API / 技能探测),红黄绿分组 + 一键处理 |
|
|
25
|
-
| tabs 行 | 列表 / 技能 / 环境检查 + 右侧刷新按钮 + 最右侧版本号(如 v1.7.13),便于核对已更新 |
|
|
26
|
-
| 行级动作 | 按 label 四选一:诊断(/triage) / 修复(/wayfinder) / 讨论(/wayfinder) / 执行(/wayfinder),按钮色 = GitHub label 配置色,点击预填输入框;执行/新会话按钮常显(复制/外链也常显) |
|
|
27
|
-
| map 详情 | 顶部「执行」+ 任务按状态动作、可接/已认领/被阻塞/已关闭垂直走廊、Decision/Fog/Out-of-scope 折叠 |
|
|
28
|
-
| 交接 | 第一击注入 /handoff 时间戳模板;第二击预填 /read + 复述确认 prompt 并开新会话 |
|
|
29
|
-
| 统一引导句 | 动作注入统一带「从第一性原理出发完成任务,并对抗式审查。」 |
|
|
30
|
-
|
|
31
|
-
## 使用方式
|
|
32
|
-
|
|
33
|
-
### 第 0 步:安装 DSH CLI(仅首次 · 一次性)
|
|
34
|
-
|
|
35
|
-
DSH CLI 提供 `dsh` 命令行工具(用于安装/更新/卸载插件、查看 DSH 状态)。
|
|
36
|
-
本插件的安装/更新/卸载都通过 `dsh` 命令完成。
|
|
37
|
-
|
|
38
|
-
**推荐一 · npm 全局安装(最常用)**
|
|
1
|
+
<!-- AUTO-GENERATED by scripts/build.mjs — DO NOT EDIT. Source: ../README.md @ v1.7.15 -->
|
|
39
2
|
|
|
40
|
-
|
|
41
|
-
npm install -g @deepseek-ai/dsh
|
|
42
|
-
```
|
|
3
|
+
<h1 align="center">dsh-mattpocock-skills-deck</h1>
|
|
43
4
|
|
|
44
|
-
|
|
5
|
+
<div align="center">
|
|
45
6
|
|
|
46
|
-
|
|
47
|
-
dsh --version
|
|
48
|
-
# 期望输出类似 dsh@1.0.x 或更新版本
|
|
49
|
-
```
|
|
7
|
+
**中文** · [English](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/blob/main/docs/README.en.md)
|
|
50
8
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- **macOS / Linux**:可能需要手动加 `$(npm config get prefix)/bin` 到 `~/.bashrc` 或 `~/.zshrc`
|
|
9
|
+
**拨开战争迷雾看见终点,剩下的交给 MattSkillsDeck。**
|
|
10
|
+
让 [mattpocock/skills](https://github.com/mattpocock/skills) 在 DSH 里化作一块看得见、派得动的任务板。
|
|
54
11
|
|
|
55
|
-
|
|
12
|
+
你的 ⭐是我夜空中最亮的星。
|
|
56
13
|
|
|
57
|
-
|
|
58
|
-
npx --yes @deepseek-ai/dsh --version
|
|
59
|
-
```
|
|
14
|
+
*Part the fog of war, see the end — MattSkillsDeck handles the rest.*
|
|
60
15
|
|
|
61
|
-
|
|
16
|
+
[](https://www.npmjs.com/package/dsh-mattpocock-skills-deck) [](https://www.npmjs.com/package/dsh-mattpocock-skills-deck) [](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/commits/main) [](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/graphs/commit-activity) [](LICENSE) [](https://github.com/mattpocock/skills) [](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/issues) [](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/blob/main/docs/ROADMAP.md)
|
|
62
17
|
|
|
63
|
-
|
|
18
|
+
</div>
|
|
64
19
|
|
|
65
|
-
|
|
66
|
-
`~/.dsh` = DSH 的家,`DSH_HOME` 自定义过就换成它的路径):
|
|
20
|
+
<h2 align="center"><sub>INSTALL</sub><br>安装</h2>
|
|
67
21
|
|
|
68
|
-
|
|
22
|
+
<div align="center">
|
|
69
23
|
|
|
70
|
-
|
|
71
|
-
dsh plugin --profile desktop add dsh-better-sidebar # 与插件同一个 profile(web 服务用户换 --profile web)
|
|
72
|
-
```
|
|
24
|
+
前置要求:[DSH](https://www.npmjs.com/package/@deepseek-ai/dsh)(DeepSeek Harness)。在 DSH 里,你下指令、AI 干活;MattSkillsDeck 把这些活变成面板上的任务。
|
|
73
25
|
|
|
74
|
-
|
|
26
|
+
</div>
|
|
75
27
|
|
|
76
28
|
```bash
|
|
77
|
-
|
|
78
|
-
|
|
29
|
+
# ① 安装 DSH CLI(已装跳过)
|
|
30
|
+
npm install -g @deepseek-ai/dsh
|
|
31
|
+
|
|
32
|
+
# ② 安装 MattSkillsDeck —— --profile 必填:装进你实际使用的 DSH 入口对应的 profile
|
|
33
|
+
# (装错 profile 等于没装,重启多少次都不会加载)
|
|
34
|
+
dsh plugin --profile web add dsh-mattpocock-skills-deck # 用自启 web 服务(dsh web)
|
|
35
|
+
# 或者
|
|
36
|
+
dsh plugin --profile desktop add dsh-mattpocock-skills-deck # 用 DSH Desktop 桌面应用
|
|
37
|
+
# 锁定最新版更稳(当前 1.7.15):
|
|
38
|
+
dsh plugin --profile web add dsh-mattpocock-skills-deck@1.7.15 --registry https://registry.npmjs.org
|
|
39
|
+
# 或者
|
|
40
|
+
dsh plugin --profile desktop add dsh-mattpocock-skills-deck@1.7.15 --registry https://registry.npmjs.org
|
|
79
41
|
```
|
|
80
42
|
|
|
81
|
-
|
|
43
|
+
<div align="center">
|
|
44
|
+
|
|
45
|
+
装完**重启一次对应的 DSH 入口**即生效:桌面应用完全退出并重开 DSH Desktop;web 服务重启 `dsh web` 后刷新页面。零配置。
|
|
46
|
+
|
|
47
|
+
窄屏用户可顺手把 dsh-better-sidebar 装进同一个 profile,列表与详情并排看。
|
|
48
|
+
|
|
49
|
+
**👇 装完重启,面板就绪就是这个样子。**
|
|
50
|
+
|
|
51
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/readme/01-install-board-ready.png" width="640" alt="安装成功后任务板就绪的样子" style="border:1px solid #30363d;border-radius:6px">
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<details>
|
|
56
|
+
<summary>进阶安装:免全局、更新不生效、交给 AI</summary>
|
|
57
|
+
|
|
58
|
+
下面命令以 web profile 为例——**DSH Desktop 桌面应用用户请把所有 `--profile web` 换成 `--profile desktop`**。
|
|
82
59
|
|
|
83
60
|
```bash
|
|
84
|
-
|
|
85
|
-
|
|
61
|
+
# 免全局安装(想更稳,像上面一样锁版本)
|
|
62
|
+
npx --yes @deepseek-ai/dsh plugin --profile web add dsh-mattpocock-skills-deck
|
|
63
|
+
|
|
64
|
+
# 更新被静默忽略时,显式指定官方源
|
|
65
|
+
dsh plugin --profile web add dsh-mattpocock-skills-deck@latest --registry https://registry.npmjs.org
|
|
86
66
|
```
|
|
87
67
|
|
|
88
|
-
|
|
68
|
+
复制下面这段发给你的 AI,它会确认 profile、检查环境并按需安装:
|
|
89
69
|
|
|
90
70
|
```text
|
|
91
|
-
请帮我安装 DeepSeek Harness 插件 dsh-mattpocock-skills-deck(
|
|
71
|
+
请帮我安装 DeepSeek Harness 插件 dsh-mattpocock-skills-deck(MattSkillsDeck)。
|
|
92
72
|
先读仓库 README:https://github.com/FeatherHunter/dsh-mattpocock-skills-deck
|
|
93
73
|
先确认我实际使用的 DSH 入口对应哪个 profile(DSH Desktop 桌面应用 → desktop;自启 web 服务 → web),把插件装进正确的 profile;
|
|
94
74
|
然后自行检查环境并按需安装(已装的跳过),完成后简要汇报结果。
|
|
95
75
|
```
|
|
96
76
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
- 🩺 **装了重启还是没面板?九成是 profile 没对上**:核对 `~/.dsh/profiles/<你的profile>/package.json`——
|
|
101
|
-
`dependencies` 里应有 `dsh-mattpocock-skills-deck`,且 `dsh.profile.bundles` 数组里应有同名条目。
|
|
102
|
-
桌面应用当前选中的 profile 见 `%APPDATA%\DSH Desktop\profile-selection\state.json` 的 `"active"` 字段。
|
|
103
|
-
- ✅ **一键装完即用(bundle 装配)**:本包声明 `dsh.bundle.patch`(包根 `cordis.patch.yml`),
|
|
104
|
-
`dsh plugin add` 自动把包加入 profile 的 `dsh.profile.bundles`,启动时 loadProfile 自动应用——
|
|
105
|
-
**无构建脚本**(pnpm v10 不再拦截),无需手动编辑任何文件;`dsh plugin remove` 自动移除。
|
|
106
|
-
|
|
107
|
-
- ⛔ **千万不要用 `npm install --prefix ~/.dsh/profiles` 安装**:`profiles/node_modules` 是 DSH 的
|
|
108
|
-
**扁平回退软链区**(启动时 `healProfilesModuleFallback` 自动重建,装的是 npx 全家桶),
|
|
109
|
-
npm `--prefix` 会把它当新项目,把 package.json 未声明的包(含你的插件)**全部 prune 掉**。
|
|
110
|
-
**2026-08-14 实测事故**:一次安装插件连带删掉 511 个包,DSH 插件全部加载失败。
|
|
111
|
-
插件正确安装位 = `profiles/web/node_modules`(官方命令负责),注册写 `web/cordis.patch.yml`。
|
|
112
|
-
- 为什么不用 `npm install -g`:`-g` 装到 `%APPDATA%\npm\node_modules`,而 Node 的默认解析链
|
|
113
|
-
**不包含该目录**(本机实测 `require.resolve` 失败)——DSH 进程 require 不到,装了也白装。
|
|
114
|
-
独立 CLI 应用(如 `dsh-feishu-bot`)靠 bin 快捷方式运行所以能 `-g`;**插件必须被 DSH 进程
|
|
115
|
-
解析**,所以装 Harness 自己的 profile。
|
|
116
|
-
|
|
117
|
-
**升级**(desktop profile 用户把 `--profile web` 换成 `--profile desktop`):
|
|
77
|
+
</details>
|
|
78
|
+
|
|
79
|
+
升级 · 卸载(desktop profile 用户把 `--profile web` 换成 `--profile desktop`):
|
|
118
80
|
|
|
119
81
|
```bash
|
|
120
|
-
dsh plugin --profile web update dsh-mattpocock-skills-deck
|
|
121
|
-
|
|
82
|
+
dsh plugin --profile web update dsh-mattpocock-skills-deck # 升级
|
|
83
|
+
dsh plugin --profile web remove dsh-mattpocock-skills-deck # 卸载
|
|
122
84
|
```
|
|
123
85
|
|
|
124
|
-
>
|
|
125
|
-
|
|
126
|
-
>
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
86
|
+
<h2 align="center"><sub>BOARD</sub><br>任务板列表</h2>
|
|
87
|
+
|
|
88
|
+
<div align="center">
|
|
89
|
+
|
|
90
|
+
仓库里的任务不再是流水账:面板把它们按可接、阻塞、已关闭归位,进度走到哪一格一眼看清。每行任务的按钮就是动作入口:点一下,写好的指令填进输入框,确认后再发送。地图类型的行永远置顶,已关闭的收成一行。
|
|
91
|
+
|
|
92
|
+
**👇 任务在哪看、状态怎么筛,全在这张图。**
|
|
93
|
+
|
|
94
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/readme/02-task-board-list.png" width="640" alt="任务板列表:状态筛选、标签筛选与行动作按钮" style="border:1px solid #30363d;border-radius:6px">
|
|
95
|
+
|
|
96
|
+
</div>
|
|
97
|
+
|
|
98
|
+
<h2 align="center"><sub>STATUSBAR</sub><br>底部任务栏</h2>
|
|
99
|
+
|
|
100
|
+
<div align="center">
|
|
101
|
+
|
|
102
|
+
每条会话输入框下面都有一条胶囊状态栏:可接数量、待修(BUG)数量、诊断、沉淀、交接、环境进度都在上面。点可接、环境等主要分段,即跳到对应面板页,看完即回,不打断手头会话。
|
|
103
|
+
|
|
104
|
+
**👇 离手最近的操作条,完整一条长这样。**
|
|
105
|
+
|
|
106
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/readme/03-statusbar-capsule.png" width="720" alt="底部任务栏:输入框下面完整一条胶囊" style="border:1px solid #30363d;border-radius:6px">
|
|
107
|
+
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<h2 align="center"><sub>DETAIL</sub><br>ISSUE 详情与评论</h2>
|
|
111
|
+
|
|
112
|
+
<div align="center">
|
|
113
|
+
|
|
114
|
+
点开任意一条任务,描述、标签、认领人与评论都在面板里排好版,不用跳终端。在底部输入框直接回话,一般只按标签显示其中一个(诊断、修复、讨论、执行),需要另起再点新会话。
|
|
115
|
+
|
|
116
|
+
**👇 点开一条任务,看透并回上话。**
|
|
117
|
+
|
|
118
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/readme/04-issue-detail-comment.png" width="640" alt="点开一条任务后的详情与评论区首屏" style="border:1px solid #30363d;border-radius:6px">
|
|
119
|
+
|
|
120
|
+
</div>
|
|
121
|
+
|
|
122
|
+
<h2 align="center"><sub>NEW SESSION</sub><br>新会话</h2>
|
|
123
|
+
|
|
124
|
+
<div align="center">
|
|
130
125
|
|
|
131
|
-
|
|
126
|
+
任何活都能另起干净会话干:详情页顶部点新会话,新会话标题自动起好,承接指令已预填,人只管检查后发送。当前会话不受扰,脏活累活都在新会话里。
|
|
127
|
+
|
|
128
|
+
**👇 点一下新会话,指令已预填等人发。**
|
|
129
|
+
|
|
130
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/readme/05-new-session-prefilled.png" width="640" alt="点新会话后新会话输入框被预填指令的样子" style="border:1px solid #30363d;border-radius:6px">
|
|
131
|
+
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<h2 align="center"><sub>SKILLS</sub><br>技能快捷入口</h2>
|
|
135
|
+
|
|
136
|
+
<div align="center">
|
|
137
|
+
|
|
138
|
+
随包 25 个技能(快照 v1.2.3)装好即用:面板技能页顶部给通用推荐(默认 /ask-matt),列表一行讲清一个技能的中文用途,点加载就把斜杠指令填进输入框。完整名单与教程见 Matt 官方 [aihero.dev/skills](https://www.aihero.dev/skills),本插件只讲入口与推荐。
|
|
139
|
+
|
|
140
|
+
</div>
|
|
141
|
+
|
|
142
|
+
<h2 align="center"><sub>BACKENDS</sub><br>多后端切换</h2>
|
|
143
|
+
|
|
144
|
+
<div align="center">
|
|
145
|
+
|
|
146
|
+
同一个面板可换跑道:设置页后端选择器列出 GitHub、本地 Markdown、GitLab 与 Other(无后端)逃生舱。切换只换数据源:切换后原数据不可见,原后端数据保留,切回来又可见。新人第一次大多只用一条跑道,知道能换即可。
|
|
147
|
+
|
|
148
|
+
**👇 换跑道不断数据,选择器长这样。**
|
|
149
|
+
|
|
150
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/readme/07-backend-switch.png" width="560" alt="设置页后端选择器四行与来源小胶囊" style="border:1px solid #30363d;border-radius:6px">
|
|
151
|
+
|
|
152
|
+
</div>
|
|
153
|
+
|
|
154
|
+
<h2 align="center"><sub>FAQ</sub><br>常见问题</h2>
|
|
155
|
+
|
|
156
|
+
<details open>
|
|
157
|
+
<summary>更新之后还是旧版本?</summary>
|
|
158
|
+
|
|
159
|
+
这是 DSH 桌面端的 pnpm 供应链策略(`minimumReleaseAge`)导致的:刚发布的版本,几个小时内 `dsh plugin update` 和插件市场的「更新」按钮都会静默跳过。更新后请完全退出 DSH 再重开,按 Ctrl+F5 刷新页面;还没更新的话,显式指定官方源装一次:
|
|
132
160
|
|
|
133
161
|
```bash
|
|
134
|
-
dsh plugin --profile web
|
|
135
|
-
# 或用 npx:npx --yes @deepseek-ai/dsh plugin --profile web remove dsh-mattpocock-skills-deck
|
|
136
|
-
# 并手动删除 cordis.patch.yml 里的 dsh-mattpocock-skills-deck insert 块(或保留,DSH 找不到包会忽略)
|
|
162
|
+
dsh plugin --profile web add dsh-mattpocock-skills-deck@latest --registry https://registry.npmjs.org
|
|
137
163
|
```
|
|
138
164
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
>
|
|
165
|
+
**👇 官方源装最新版,成功回显长这样。**
|
|
166
|
+
|
|
167
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/readme/08-faq-stale-version-fix.png" width="640" alt="终端用官方源装最新版的成功回显" style="border:1px solid #30363d;border-radius:6px">
|
|
168
|
+
|
|
169
|
+
</details>
|
|
170
|
+
|
|
171
|
+
<h2 align="center"><sub>ARCHITECTURE</sub><br>架构</h2>
|
|
172
|
+
|
|
173
|
+
<div align="center">
|
|
144
174
|
|
|
145
|
-
|
|
175
|
+
整体结构、数据流与关键状态见 [在线预览](https://featherhunter.github.io/dsh-mattpocock-skills-deck/architecture/MattSkills-architecture.html)或本地 [MattSkills-architecture.html](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/blob/main/docs/architecture/MattSkills-architecture.html)(克隆后直接打开)。
|
|
146
176
|
|
|
147
|
-
|
|
177
|
+
</div>
|
|
148
178
|
|
|
149
|
-
|
|
150
|
-
[host.js](./host.js) 的内容、code.client 填入 [client.js](./client.js) 的内容。
|
|
151
|
-
2. `cordis_run` —— 首次运行需在界面批准(安全机制,Client 代码要在页面执行)。
|
|
152
|
-
3. 生效后输入区出现 Matt Skills Deck 胶囊;Run 卡片内出现控制面板。
|
|
179
|
+
<h2 align="center"><sub>DEVELOPMENT</sub><br>开发</h2>
|
|
153
180
|
|
|
154
|
-
|
|
181
|
+
<div align="center">
|
|
155
182
|
|
|
156
|
-
-
|
|
157
|
-
`D:\2Study\StudyNotes\SKILLS`,可随会话 cwd 切换)。
|
|
158
|
-
- 数据流:`gh issue list` 枚举全量 issues(map 列表从中过滤 `wayfinder:map`)→ **GraphQL aliases 一次查询全部 map 详情**(subIssues + labels + assignees + blockedBy)→ 组装快照(map 五区块解析 + tickets + stats)。
|
|
159
|
-
- RPC 通道 `/dsws`:`status` / `snapshot` / `refresh` / `cwd` / `handoffLatest` / `claim`。
|
|
160
|
-
- 刷新策略:纯手动(状态栏「更新」/ 列表「刷新」/ 打开面板即刷)+ **60s 快照缓存**、30s 环境检查缓存。
|
|
161
|
-
- 性能:v1.3.3 起快照加载 ~35s → ~12s(aliases 批量 8 次 GraphQL → 1 次)。
|
|
183
|
+
开发说明(构建、验证、同步、发布)见 [DEV-WORKFLOW.md](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/blob/main/docs/workflow/DEV-WORKFLOW.md)。
|
|
162
184
|
|
|
163
|
-
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<h2 align="center"><sub>MORE</sub><br>作者的其他作品</h2>
|
|
188
|
+
|
|
189
|
+
<div align="center">
|
|
164
190
|
|
|
165
191
|
喜欢这个插件的话,这些可能你也用得上:
|
|
166
192
|
|
|
167
|
-
|
|
168
|
-
|
|
193
|
+
**[dsh-opencode-palette](https://github.com/FeatherHunter/dsh-opencode-palette)** —— 34 款 opencode 经典配色一键换装 DSH,即点即换,重启不丢
|
|
194
|
+
|
|
195
|
+
**[dsh-prompt](https://github.com/FeatherHunter/dsh-prompt)** —— Prompt 工具箱:24 条深度模板随手点,别再复制粘贴
|
|
196
|
+
|
|
197
|
+
**[dsh-chinese-skill-patch](https://github.com/FeatherHunter/dsh-chinese-skill-patch)** —— 让 DSH 直接用中文技能名:输入 /私 就能直达「私家大厨」,技能不必改英文名
|
|
198
|
+
|
|
199
|
+
**[dsh-im-companion](https://github.com/FeatherHunter/dsh-im-companion)** —— 给每个聊天机器人安个家:哪个工作区有助理在管、在不在线一眼看清,拖一下就能搬家
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
有问题、有想法?[提交 ISSUE](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/issues),或到 [讨论区](https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/discussions)聊聊
|
|
204
|
+
|
|
205
|
+
个人作品,与 [mattpocock/skills](https://github.com/mattpocock/skills) 官方没有关系。
|
|
206
|
+
MIT © FeatherHunter
|
|
207
|
+
|
|
208
|
+
</div>
|
|
209
|
+
|
|
210
|
+
<h2 align="center"><sub>THANKS</sub><br>致谢</h2>
|
|
211
|
+
|
|
212
|
+
<div align="left">
|
|
213
|
+
|
|
214
|
+
感谢每一位提交 Issue、PR 与参与讨论的朋友,是你们让这个插件一点点变好。
|
|
215
|
+
|
|
216
|
+
[@pioneerAlone](https://github.com/pioneerAlone) — 反馈了 #298(details/better-sidebar 重复,附完整复现与截图)、#274、#234 等状态栏与健康检查误报,并提交了修复 PR #273、#316,感谢你让「重装后到处异常」的体感得以一次清爽修复 🌹
|
|
217
|
+
|
|
218
|
+
[@Shimmernight](https://github.com/Shimmernight) — 提交了 #277 等 Issue,以及 PR #287、#275、#106(toast 主题、命名修正、macOS 适配)
|
|
219
|
+
|
|
220
|
+
[@21967201](https://github.com/21967201) — 提交了 PR #321(完善 triage + wayfinder 标签文档)
|
|
221
|
+
|
|
222
|
+
[@angenet](https://github.com/angenet) — 反馈了 #295、#262 等 macOS 环境检测问题
|
|
223
|
+
|
|
224
|
+
[@hyperion2144](https://github.com/hyperion2144) — 反馈了 #110 等环境检查问题
|
|
225
|
+
|
|
226
|
+
[@tafcear](https://github.com/tafcear) — 反馈了 #422(非编码工作区状态栏降噪诉求),感谢你让非编码工作区不再被初始化横幅打扰 🌹
|
|
227
|
+
|
|
228
|
+
也感谢在评论区与讨论区留下想法的每一位朋友。如果你也遇到了问题或有新想法,欢迎直接提 Issue 或发起讨论。
|
|
169
229
|
|
|
170
|
-
|
|
230
|
+
</div>
|
|
171
231
|
|
|
172
|
-
|
|
173
|
-
- UI 逐版定稿:C 卡片式两行结构、编号/map 竖排、18px 迷你圆环进度、标签贪心折叠 +N 弹窗(自适应面板)、窄屏按钮正方形
|
|
174
|
-
- tabs 行刷新按钮 + 最右侧版本号 v1.3.3
|
|
175
|
-
- 快照性能提速 ~35s → ~12s(GraphQL aliases 批量 + 合并 fetchMaps + 缓存 60s)
|
|
176
|
-
- 开发工作流文档 DEV-WORKFLOW.md(改 bug → 实时生效完整流程)
|
|
232
|
+
<h2 align="center"><sub>CONNECT</sub><br>加入我们</h2>
|
|
177
233
|
|
|
178
|
-
|
|
234
|
+
<div align="center">
|
|
179
235
|
|
|
180
|
-
|
|
181
|
-
- Matt 技能安装引导(设置页 + 环境检查页)+「新增 wayfinder」按钮(prompt 带仓库信息)+ 仓库身份组件
|
|
182
|
-
- 全量中英双语 + 进度契约(## 进度:N%)与阶段闸门(needs-triage 前置诊断)
|
|
183
|
-
- 仓库级缓存数据架构:git 根上溯检测 → 宿主磁盘缓存 → 打开/重启秒开 → 自动探测刷新(probe + 轮询 + focus + 动作后)
|
|
184
|
-
- 正文格式容错自愈(字面 \n + BOM 还原)+ 正文格式契约 + issue 正文 markdown 白名单渲染
|
|
185
|
-
- 3 项 bug 修复(setup 误报 / 新会话 prompt 缺 issue 标识 / 完成态按钮配色)+ 手动刷新去遮罩(按钮即时转圈反馈 · 文字恒定)+ 变化行高亮/新增绿闪/删除提示
|
|
236
|
+
扫码加入话题群——二维码永久有效。日常闲聊与快速答疑走群里,Bug 与需求请直接提 ISSUE,更高效可追溯。
|
|
186
237
|
|
|
187
|
-
|
|
238
|
+
<img src="https://github.com/FeatherHunter/dsh-mattpocock-skills-deck/raw/main/assets/qr-topic-group.png" width="280" alt="扫码加入话题群,dsh-mattpocock-skills 的组织">
|
|
239
|
+
<br>
|
|
240
|
+
<strong>加入话题群</strong>
|
|
241
|
+
<br>
|
|
242
|
+
<sub>dsh-mattpocock-skills · 该二维码永久有效</sub>
|
|
188
243
|
|
|
189
|
-
|
|
244
|
+
</div>
|
|
190
245
|
|
|
191
|
-
|
|
192
|
-
- `package/` —— **可分发插件包**(正式安装用,标准 npm 包结构)
|
|
193
|
-
- `package.json` —— 包声明:`dsh.client`(platform web / immediately)+ `dsh.bundle.patch`(装配)
|
|
194
|
-
- `cordis.patch.yml` —— bundle 装配 patch(`dsh plugin add` 自动应用,无构建脚本)
|
|
195
|
-
- `lib/index.js` —— 宿主半(ESM:gh 数据层 + `/dsws` RPC 通道注册)
|
|
196
|
-
- `lib/client.js` —— 浏览器半 bundle(`window.__ModuleLoader__.load` 注册格式)
|
|
197
|
-
- `README.md` —— 本说明
|
|
198
|
-
- `issues-checklist.html` —— 迭代需求清单(v9–v24,43+ 项)
|
|
199
|
-
- `DESIGN.md` / `prototype.html` —— 设计定稿与原型
|
|
200
|
-
- `tests/` —— host 逻辑测试(verify-status / verify-panel)
|
|
246
|
+
<div align="center">
|
|
201
247
|
|
|
202
|
-
|
|
248
|
+
<a href="https://featherhunter.github.io/dsh-mattpocock-skills-deck/star-history.html">
|
|
249
|
+
<picture>
|
|
250
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/FeatherHunter/dsh-mattpocock-skills-deck/main/docs/star-history-dark.svg?v=20260905" />
|
|
251
|
+
<source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/FeatherHunter/dsh-mattpocock-skills-deck/main/docs/star-history-light.svg?v=20260905" />
|
|
252
|
+
<img alt="Star History Chart" src="https://raw.githubusercontent.com/FeatherHunter/dsh-mattpocock-skills-deck/main/docs/star-history-light.svg?v=20260905" />
|
|
253
|
+
</picture>
|
|
254
|
+
</a>
|
|
203
255
|
|
|
204
|
-
|
|
205
|
-
建议保留正式安装版即可,动态版 `cordis_stop` 掉。
|
|
206
|
-
- 本插件需要 GitHub 仓库工作目录(wayfinder 地图仓库)才能取到数据;
|
|
207
|
-
非仓库目录下环境检查会提示「仓库定位」未就绪。
|
|
208
|
-
- 用户界面偏好(开始模板等)存浏览器 localStorage,与动态版共用同一 key。
|
|
256
|
+
</div>
|
package/lib/bootstrap.js
ADDED
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
// src/host/bootstrap.js —— 启动技底与技能名单(H1 #445 从 host/index.js 31–215/235–249 搬出,纯结构、行为零变化)
|
|
2
|
+
// 以后谁改它:改启动装配、兜底技能 provider 或技能名单惰性加载的人。预估约 250 行,超 350 打回。
|
|
3
|
+
// 接线:由 index.js 动态 import 动态加载,依赖全显式传入(仅 ctx);本文件不引用其他新文件。
|
|
4
|
+
export function createBootstrap(deps) {
|
|
5
|
+
const { ctx } = deps
|
|
6
|
+
// === T2 #389 bundled 兜底 provider(rank 600,trustedHost,ctx.effect 托管)===
|
|
7
|
+
// 零代码声明:无需 env 晚置,直接 registerProvider;list 返回 package/bundled-skills 的 25 个,rank 600 兜底,bundled 随包消失
|
|
8
|
+
// 选择 provider 而非 env 的依据见 R1 研究(env 构造时一次性读,晚置失效);参见 docs/adr/20260828-skill-probe-union-channels.md 的 trustedHost 约束
|
|
9
|
+
;(() => {
|
|
10
|
+
try {
|
|
11
|
+
const skills = ctx.get('skills')
|
|
12
|
+
if (!skills || typeof skills.registerProvider !== 'function') return
|
|
13
|
+
;(async () => {
|
|
14
|
+
let bundledDir = null
|
|
15
|
+
try {
|
|
16
|
+
const pathMod = await import('node:path')
|
|
17
|
+
const fsSync = await import('node:fs')
|
|
18
|
+
const osMod = await import('node:os')
|
|
19
|
+
const candidates = []
|
|
20
|
+
const cwd = (typeof process !== 'undefined' && typeof process.cwd === 'function') ? String(process.cwd() || '') : ''
|
|
21
|
+
if (cwd) {
|
|
22
|
+
candidates.push(pathMod.resolve(cwd, 'package/bundled-skills'))
|
|
23
|
+
candidates.push(pathMod.resolve(cwd, '../package/bundled-skills'))
|
|
24
|
+
candidates.push(pathMod.resolve(cwd, '../../package/bundled-skills'))
|
|
25
|
+
candidates.push(pathMod.resolve(cwd, 'bundled-skills'))
|
|
26
|
+
let cur = cwd
|
|
27
|
+
for (let i = 0; i < 4; i++) {
|
|
28
|
+
candidates.push(pathMod.join(cur, 'package/bundled-skills'))
|
|
29
|
+
candidates.push(pathMod.join(cur, 'node_modules/dsh-mattpocock-skills-deck/bundled-skills'))
|
|
30
|
+
cur = pathMod.dirname(cur)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const home = osMod.homedir()
|
|
35
|
+
if (home) {
|
|
36
|
+
candidates.push(pathMod.join(home, '.dsh/profiles/web/node_modules/dsh-mattpocock-skills-deck/bundled-skills'))
|
|
37
|
+
candidates.push(pathMod.join(home, '.dsh/profiles/desktop/node_modules/dsh-mattpocock-skills-deck/bundled-skills'))
|
|
38
|
+
try {
|
|
39
|
+
const profilesDir = pathMod.join(home, '.dsh/profiles')
|
|
40
|
+
const entries = await (await import('node:fs/promises')).readdir(profilesDir, { withFileTypes: true }).catch(() => [])
|
|
41
|
+
for (const e of entries) if (e.isDirectory()) candidates.push(pathMod.join(profilesDir, e.name, 'node_modules/dsh-mattpocock-skills-deck/bundled-skills'))
|
|
42
|
+
} catch {}
|
|
43
|
+
}
|
|
44
|
+
} catch {}
|
|
45
|
+
const seen = new Set()
|
|
46
|
+
const uniq = []
|
|
47
|
+
for (const c of candidates) {
|
|
48
|
+
const n = pathMod.normalize(c)
|
|
49
|
+
if (!seen.has(n)) { seen.add(n); uniq.push(n) }
|
|
50
|
+
}
|
|
51
|
+
for (const cand of uniq) {
|
|
52
|
+
try {
|
|
53
|
+
const st = fsSync.statSync(cand)
|
|
54
|
+
if (st && st.isDirectory()) {
|
|
55
|
+
try {
|
|
56
|
+
const way = pathMod.join(cand, 'wayfinder', 'SKILL.md')
|
|
57
|
+
const wst = fsSync.statSync(way)
|
|
58
|
+
if (wst && wst.isFile()) { bundledDir = cand; break }
|
|
59
|
+
} catch {}
|
|
60
|
+
try {
|
|
61
|
+
const ents = fsSync.readdirSync(cand, { withFileTypes: true })
|
|
62
|
+
const dcount = ents.filter(e => e.isDirectory()).length
|
|
63
|
+
if (dcount >= 20) { bundledDir = cand; break }
|
|
64
|
+
} catch {}
|
|
65
|
+
}
|
|
66
|
+
} catch {}
|
|
67
|
+
}
|
|
68
|
+
} catch (e) { bundledDir = null }
|
|
69
|
+
if (!bundledDir) {
|
|
70
|
+
try { ctx.get('logger')?.warn?.('[bundled] dir not found, skip provider') } catch {}
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
function parseSkillRaw(raw) {
|
|
74
|
+
try {
|
|
75
|
+
const s = String(raw || '').replace(/^/, '')
|
|
76
|
+
const m = s.match(/^---\s*\r?\n([\s\S]*?)\r?\n---/)
|
|
77
|
+
if (!m) return undefined
|
|
78
|
+
const front = m[1]
|
|
79
|
+
const body = s.slice(m[0].length)
|
|
80
|
+
const getField = (key) => {
|
|
81
|
+
const re = new RegExp('^\\s*' + key.replace(/-/g, '\\-') + '\\s*:\\s*(.+)$', 'm')
|
|
82
|
+
const mm = front.match(re)
|
|
83
|
+
if (!mm) return undefined
|
|
84
|
+
let v = mm[1].trim()
|
|
85
|
+
if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) v = v.slice(1, -1)
|
|
86
|
+
return v.trim()
|
|
87
|
+
}
|
|
88
|
+
const name = getField('name')
|
|
89
|
+
const description = getField('description')
|
|
90
|
+
if (!name || !description) return undefined
|
|
91
|
+
const whenToUse = getField('whenToUse')
|
|
92
|
+
const parseBool = (val) => {
|
|
93
|
+
if (val === undefined) return undefined
|
|
94
|
+
const l = String(val).toLowerCase().trim()
|
|
95
|
+
if (l === 'true' || l === 'yes' || l === 'on' || l === '1') return true
|
|
96
|
+
if (l === 'false' || l === 'no' || l === 'off' || l === '0') return false
|
|
97
|
+
return undefined
|
|
98
|
+
}
|
|
99
|
+
const disableModel = parseBool(getField('disable-model-invocation'))
|
|
100
|
+
const userInv = parseBool(getField('user-invocable'))
|
|
101
|
+
const invocation = { modelInvocable: disableModel !== true, userInvocable: userInv !== false }
|
|
102
|
+
return { name, description, whenToUse: whenToUse || undefined, invocation, body: body.trim(), content: body.trim() }
|
|
103
|
+
} catch { return undefined }
|
|
104
|
+
}
|
|
105
|
+
function isValidSkillName(n) { try { return /^[\p{L}0-9]+(?:-[\p{L}0-9]+)*$/u.test(n) } catch { return /^[a-z0-9]+(?:-[a-z0-9]+)*$/i.test(n) } }
|
|
106
|
+
const BUNDLED_RANK = 600
|
|
107
|
+
const PROVIDER_NAME = 'bundled-mattpocock'
|
|
108
|
+
const createBundledProvider = (control) => {
|
|
109
|
+
return {
|
|
110
|
+
name: PROVIDER_NAME,
|
|
111
|
+
async list(opts) {
|
|
112
|
+
try {
|
|
113
|
+
const fsp = await import('node:fs/promises')
|
|
114
|
+
const pathMod2 = await import('node:path')
|
|
115
|
+
if (opts && opts.signal && opts.signal.aborted) throw opts.signal.reason
|
|
116
|
+
let entries = []
|
|
117
|
+
try { entries = await fsp.readdir(bundledDir, { withFileTypes: true }) } catch { return [] }
|
|
118
|
+
const out = []
|
|
119
|
+
for (const ent of entries) {
|
|
120
|
+
if (!ent.isDirectory()) continue
|
|
121
|
+
const dirName = ent.name
|
|
122
|
+
if (!isValidSkillName(dirName)) continue
|
|
123
|
+
const mdPath = pathMod2.join(bundledDir, dirName, 'SKILL.md')
|
|
124
|
+
try {
|
|
125
|
+
const raw = await fsp.readFile(mdPath, 'utf8')
|
|
126
|
+
const parsed = parseSkillRaw(raw)
|
|
127
|
+
if (!parsed) continue
|
|
128
|
+
if (parsed.name !== dirName) continue
|
|
129
|
+
out.push({
|
|
130
|
+
name: parsed.name,
|
|
131
|
+
description: parsed.description,
|
|
132
|
+
...(parsed.whenToUse ? { whenToUse: parsed.whenToUse } : {}),
|
|
133
|
+
invocation: parsed.invocation,
|
|
134
|
+
source: 'bundled',
|
|
135
|
+
provider: PROVIDER_NAME,
|
|
136
|
+
rank: BUNDLED_RANK,
|
|
137
|
+
locator: { path: mdPath, directory: pathMod2.join(bundledDir, dirName) },
|
|
138
|
+
resourceBase: { kind: 'directory', path: pathMod2.join(bundledDir, dirName) },
|
|
139
|
+
path: mdPath
|
|
140
|
+
})
|
|
141
|
+
} catch {}
|
|
142
|
+
}
|
|
143
|
+
out.sort((a, b) => a.name.localeCompare(b.name))
|
|
144
|
+
return out
|
|
145
|
+
} catch (e) {
|
|
146
|
+
try { ctx.get('logger')?.warn?.('[bundled] list failed: ' + String(e && e.message || e)) } catch {}
|
|
147
|
+
return []
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
async get(candidate, opts) {
|
|
151
|
+
try {
|
|
152
|
+
const fsp2 = await import('node:fs/promises')
|
|
153
|
+
if (opts && opts.signal && opts.signal.aborted) throw opts.signal.reason
|
|
154
|
+
const loc = candidate && candidate.locator ? candidate.locator : null
|
|
155
|
+
const p = (loc && loc.path) ? loc.path : (candidate && candidate.path) ? candidate.path : null
|
|
156
|
+
if (!p) return undefined
|
|
157
|
+
let raw
|
|
158
|
+
try { raw = await fsp2.readFile(p, 'utf8') } catch { return undefined }
|
|
159
|
+
const parsed = parseSkillRaw(raw)
|
|
160
|
+
if (!parsed) return undefined
|
|
161
|
+
if (parsed.name !== candidate.name) return undefined
|
|
162
|
+
const dir = loc && loc.directory ? loc.directory : (await import('node:path')).dirname(p)
|
|
163
|
+
if (opts && opts.signal && opts.signal.aborted) throw opts.signal.reason
|
|
164
|
+
return {
|
|
165
|
+
name: parsed.name,
|
|
166
|
+
description: parsed.description,
|
|
167
|
+
...(parsed.whenToUse ? { whenToUse: parsed.whenToUse } : {}),
|
|
168
|
+
invocation: parsed.invocation,
|
|
169
|
+
source: 'bundled',
|
|
170
|
+
provider: PROVIDER_NAME,
|
|
171
|
+
resourceBase: { kind: 'directory', path: dir },
|
|
172
|
+
path: p,
|
|
173
|
+
content: parsed.content
|
|
174
|
+
}
|
|
175
|
+
} catch { return undefined }
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
let dispose = null
|
|
180
|
+
try {
|
|
181
|
+
dispose = skills.registerProvider(createBundledProvider)
|
|
182
|
+
try { ctx.effect(() => () => { try { dispose && dispose() } catch {} }) } catch {}
|
|
183
|
+
try { ctx.get('logger')?.info?.('[bundled] provider registered at ' + bundledDir + ' rank ' + BUNDLED_RANK) } catch {}
|
|
184
|
+
console.log('[bundled] provider registered at ' + bundledDir + ' rank ' + BUNDLED_RANK + ' (25 skills expected)')
|
|
185
|
+
} catch (e) {
|
|
186
|
+
try { console.warn('[bundled] registerProvider failed ' + String(e && e.message || e)) } catch {}
|
|
187
|
+
}
|
|
188
|
+
})()
|
|
189
|
+
} catch {}
|
|
190
|
+
})()
|
|
191
|
+
// 技能名单(#280 单一真源:与 check-catalog + client SKILLS 同步;拼写以真实目录为准,B 语义由 skills.get 覆盖)
|
|
192
|
+
// 真源 = shared/matt-skills.js(MATT_SKILL_PROBE_NAMES)。本字段由 getMattSkillProbeNames() 惰性加载。
|
|
193
|
+
let SKILL_PROBE_NAMES = null
|
|
194
|
+
async function getMattSkillProbeNames() {
|
|
195
|
+
if (SKILL_PROBE_NAMES) return SKILL_PROBE_NAMES
|
|
196
|
+
try {
|
|
197
|
+
const m = await import('../shared/matt-skills.js')
|
|
198
|
+
SKILL_PROBE_NAMES = (m && (m.MATT_SKILL_PROBE_NAMES || m.default?.MATT_SKILL_PROBE_NAMES)) || null
|
|
199
|
+
if (!SKILL_PROBE_NAMES) throw new Error('shared/matt-skills.js 未导出 MATT_SKILL_PROBE_NAMES')
|
|
200
|
+
} catch (e) {
|
|
201
|
+
// 兜底:内联一份与真源一致的常量(仅在 shared 文件丢失时使用;CI/构建必须保证真源在场)
|
|
202
|
+
SKILL_PROBE_NAMES = ['ask-matt','code-review','codebase-design','diagnosing-bugs','domain-modeling','grill-with-docs','implement','improve-codebase-architecture','prototype','research','resolving-merge-conflicts','setup-matt-pocock-skills','tdd','to-spec','to-tickets','triage','wayfinder','wizard','grill-me','grilling','handoff','teach','to-questionnaire','wait-what','writing-for-agents']
|
|
203
|
+
}
|
|
204
|
+
return SKILL_PROBE_NAMES
|
|
205
|
+
}
|
|
206
|
+
return { getMattSkillProbeNames }
|
|
207
|
+
}
|