dsh-skill-hub 0.3.13 → 0.3.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/CONTRIBUTING.md +6 -4
- package/README.md +9 -5
- package/README.zh.md +9 -5
- package/lib/client.js +55 -58
- package/lib/client.js.map +1 -1
- package/lib/index.js +529 -315
- package/lib/types/client/SkillHubSettingsCard.d.ts +5 -3
- package/lib/types/client/icons.d.ts +4 -5
- package/lib/types/client/index.d.ts +13 -12
- package/lib/types/client/locales/market.d.ts +1 -0
- package/lib/types/client/locales.d.ts +1 -0
- package/lib/types/client/settings-form.d.ts +9 -3
- package/lib/types/client/slash-dots.d.ts +20 -11
- package/lib/types/index.d.ts +59 -24
- package/lib/types/protocol/api.d.ts +22 -2
- package/lib/types/protocol/config.d.ts +30 -4
- package/lib/types/protocol/market.d.ts +1 -1
- package/lib/types/protocol/repo.d.ts +18 -1
- package/lib/types/protocol.d.ts +3 -3
- package/lib/types/repo/discovery.d.ts +59 -3
- package/lib/types/repo/github-client.d.ts +16 -0
- package/lib/types/repo.d.ts +6 -3
- package/lib/types/routes/helpers.d.ts +8 -1
- package/lib/types/routes/market.d.ts +2 -2
- package/lib/types/routes.d.ts +1 -1
- package/lib/types/store/store.d.ts +4 -0
- package/package.json +31 -41
- package/src/client/SkillHubSettingsCard.tsx +5 -3
- package/src/client/icons.tsx +4 -5
- package/src/client/index.tsx +33 -32
- package/src/client/locales/market.ts +2 -0
- package/src/client/panel/RepoScanCard.tsx +6 -3
- package/src/client/panel/SkillHubPanel.tsx +1 -1
- package/src/client/panel/SourcesView.tsx +1 -1
- package/src/client/panel/hooks/useGroupFlow.ts +1 -8
- package/src/client/settings-form.ts +9 -4
- package/src/client/slash-dots.test.ts +19 -36
- package/src/client/slash-dots.tsx +30 -60
- package/src/index.ts +145 -82
- package/src/protocol/api.ts +24 -2
- package/src/protocol/config.ts +35 -4
- package/src/protocol/market.ts +1 -1
- package/src/protocol/repo.ts +22 -1
- package/src/protocol.ts +3 -3
- package/src/repo/discovery.ts +120 -33
- package/src/repo/github-client.ts +18 -1
- package/src/repo/install.ts +8 -7
- package/src/repo.test.ts +158 -4
- package/src/repo.ts +10 -2
- package/src/routes/config.ts +19 -2
- package/src/routes/helpers.ts +9 -2
- package/src/routes/market.ts +49 -37
- package/src/routes/repo-import.ts +3 -2
- package/src/routes/sources.ts +2 -1
- package/src/routes.test.ts +107 -1
- package/src/routes.ts +21 -3
- package/src/store/migrate.ts +3 -2
- package/src/store/store.ts +7 -2
- package/src/store.test.ts +50 -0
- package/src/update.ts +4 -2
package/CONTRIBUTING.md
CHANGED
|
@@ -39,7 +39,7 @@ src/client/locales/ dictionaries by view (common/skills/market/sources/detai
|
|
|
39
39
|
```bash
|
|
40
40
|
npm install
|
|
41
41
|
npm run typecheck # tsc --noEmit
|
|
42
|
-
npm test # vitest (
|
|
42
|
+
npm test # vitest (255 tests across 14 suites)
|
|
43
43
|
npm run build # tsc declarations + tsdown bundles (lib/index.js + lib/client.js)
|
|
44
44
|
```
|
|
45
45
|
|
|
@@ -53,8 +53,8 @@ npm run build # tsc declarations + tsdown bundles (lib/index.js + lib/clie
|
|
|
53
53
|
live GUI.
|
|
54
54
|
3. **Build** — `npm run build` must produce `lib/index.js` and `lib/client.js`.
|
|
55
55
|
4. **Keep the diff focused** — one logical change per PR, with a clear title and description.
|
|
56
|
-
5. **Documentation** — update `README.md` (
|
|
57
|
-
behavior or the API surface changes.
|
|
56
|
+
5. **Documentation** — update `README.md` **and** `README.zh.md` (both ship with the package and are
|
|
57
|
+
kept in sync) when behavior or the API surface changes.
|
|
58
58
|
|
|
59
59
|
## Code style
|
|
60
60
|
|
|
@@ -68,7 +68,9 @@ npm run build # tsc declarations + tsdown bundles (lib/index.js + lib/clie
|
|
|
68
68
|
```bash
|
|
69
69
|
# after a change:
|
|
70
70
|
npm run build
|
|
71
|
-
# restart the dsh web process, then verify
|
|
71
|
+
# restart the dsh web process, then verify both surfaces:
|
|
72
|
+
# Settings → 技能 — the skill hub panel
|
|
73
|
+
# sidebar 插件 → dsh-skill-hub — the plugin's settings card
|
|
72
74
|
```
|
|
73
75
|
|
|
74
76
|
When the web profile installs this repo as a link (`"dsh-skill-hub": "link:/path/to/repo"`, the
|
package/README.md
CHANGED
|
@@ -24,7 +24,9 @@ dsh plugin --profile web add dsh-skill-hub
|
|
|
24
24
|
# restart dsh web → Settings → 技能 → Market → scan → import
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
Requires `Node ^22.19 || >=24` + dsh web
|
|
27
|
+
Requires `Node ^22.19 || >=24` + dsh web `>=0.1.7-alpha.1 <0.2`.
|
|
28
|
+
|
|
29
|
+
Two surfaces — the hub panel lives at **Settings → 技能**, and this plugin's own configuration card sits on the plugin's page in the **Plugins manager** (sidebar → 插件 → dsh-skill-hub). The card is registered by the plugin itself into the `plugins.bundle.config` slot — dsh has no auto-generated config page — and covers the master switch, announce-to-agent, dot colors, usage display and the stats window/interval.
|
|
28
30
|
|
|
29
31
|
## Features
|
|
30
32
|
|
|
@@ -35,10 +37,10 @@ Requires `Node ^22.19 || >=24` + dsh web (`0.1.6-alpha.1`, `0.1.x` forward compa
|
|
|
35
37
|
- **Organize** — scenes (tags) plus auto-aggregated source collections, all drag-reorderable and persisted in `~/.dsh/dsh-skill-hub.json`. Edit mode reveals delete/reorder without cluttering the read view.
|
|
36
38
|
- **Diagnose & fix** — files the provider skips (missing frontmatter, bad YAML, name mismatch, short description) show up with reasons; auto-fixable ones (e.g. unquoted `:` in descriptions) get a one-click Fix button.
|
|
37
39
|
- **Scaffold** — new-skill wizard writing to `~/.dsh/skills` or `~/.agents/skills` (`SKILL.md` template below).
|
|
38
|
-
- **Market** — built-in curated repos plus custom `owner/repo` sources. Any top-level directory containing `SKILL.md` scans as a root (no allowlist). Async import with byte-level progress and cancel. Each source pins a version — click the ref badge to switch between releases, branches, or a custom ref.
|
|
40
|
+
- **Market** — built-in curated repos plus custom `owner/repo` sources. Any top-level directory containing `SKILL.md` scans as a root (no allowlist), and a `SKILL.md` at the repo root itself scans as a single skill named after the repo (minus repo tooling such as `.github/`). Async import with byte-level progress and cancel. Each source pins a version — click the ref badge to switch between releases, branches, or a custom ref.
|
|
39
41
|
- **Track updates** — imported skills record a repo + commit snapshot. Check all / update-all, per-source badges (installed / updatable / deleted upstream / new release). Sync overwrites local edits (with confirm); upstream deletions move into a restorable trash that keeps source and scene membership.
|
|
40
42
|
- **Stats** — per-skill call counts + last-used times from session logs (incremental cache), group summaries; window and scan interval live-configurable from the settings card.
|
|
41
|
-
- **Settings card** — master switch, announce-to-agent, invocation dot colors, usage display toggles, stats window/interval
|
|
43
|
+
- **Settings card** — registered on the plugin's own page in the **Plugins manager** (sidebar → 插件 → dsh-skill-hub; collapsed until you expand the title): master switch, announce-to-agent, invocation dot colors, usage display toggles, stats window/interval.
|
|
42
44
|
|
|
43
45
|
## Why not just the read-only browser?
|
|
44
46
|
|
|
@@ -92,7 +94,7 @@ Host uses only `ctx.skills.snapshot/get`, `ctx.webServer.register`, `ctx.systemP
|
|
|
92
94
|
| `/api/skill-hub/config` | GET/POST | runtime config (`null` clears) |
|
|
93
95
|
| `/api/skill-hub/groups` | GET | tags + collections + orders |
|
|
94
96
|
| `/api/skill-hub/tag` etc. | POST | create/rename, delete, set members, reorder |
|
|
95
|
-
| `/api/skill-hub/market` etc. | GET/POST | list/add/delete/pin/check/sync
|
|
97
|
+
| `/api/skill-hub/market` etc. | GET/POST | list/add/delete/pin sources; `…/source/check` + `…/source/sync` update them |
|
|
96
98
|
| `/api/skill-hub/market/source/versions?repo=` | GET | releases + branches for the version picker |
|
|
97
99
|
| `/api/skill-hub/repo?repo=` | GET | discover (any root) |
|
|
98
100
|
| `/api/skill-hub/repo/import` | POST | async job `{jobId, total, totalBytes}` |
|
|
@@ -100,12 +102,13 @@ Host uses only `ctx.skills.snapshot/get`, `ctx.webServer.register`, `ctx.systemP
|
|
|
100
102
|
| `/api/skill-hub/repo/import/cancel` | POST | cancel job |
|
|
101
103
|
| `/api/skill-hub/sources` etc. | GET/POST | list/check/sync/delete/restore/clear trash |
|
|
102
104
|
| `/api/skill-hub/update` | GET | plugin latest release |
|
|
105
|
+
| unknown `/api/skill-hub/*` | GET/POST | `404 {error}` naming the path — a typo must not read as an auth failure (the SPA fallback answers 401 for `/api/*` it does not own) |
|
|
103
106
|
|
|
104
107
|
## Development
|
|
105
108
|
|
|
106
109
|
```bash
|
|
107
110
|
npm run typecheck # tsc --noEmit
|
|
108
|
-
npm test #
|
|
111
|
+
npm test # 255 tests, 14 suites
|
|
109
112
|
npm run build # tsc + tsdown → lib/index.js + lib/client.js
|
|
110
113
|
```
|
|
111
114
|
|
|
@@ -117,6 +120,7 @@ npm run build # tsc + tsdown → lib/index.js + lib/client.js
|
|
|
117
120
|
- Skill missing — check the diagnostics section (frontmatter / name mismatch / short description).
|
|
118
121
|
- Empty source group — its skills were deleted, or their disabled records were lost (sidecar restored/hand-edited). Startup reconciles `.disabled` files on disk; source groups with no visible member are no longer rendered.
|
|
119
122
|
- Dots missing in `/` menu — dsh internals changed; catalog still works.
|
|
123
|
+
- Settings card missing — open the plugin in the Plugins manager (sidebar → 插件 → dsh-skill-hub) and expand the 「技能中枢」 card at the top of the page (collapsed by default). On dsh older than `0.1.7-alpha.1` this plugin does not load at all (the settings API it targets does not exist there).
|
|
120
124
|
|
|
121
125
|
## Community
|
|
122
126
|
|
package/README.zh.md
CHANGED
|
@@ -24,7 +24,9 @@ dsh plugin --profile web add dsh-skill-hub
|
|
|
24
24
|
# 重启 dsh web → 设置 → 技能 → 市场 → 扫描 → 导入
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
要求 `Node ^22.19 || >=24` + dsh web
|
|
27
|
+
要求 `Node ^22.19 || >=24` + dsh web `>=0.1.7-alpha.1 <0.2`。
|
|
28
|
+
|
|
29
|
+
两个界面 —— 管理面板在 **设置 → 技能**;本插件自身的配置卡片在 **插件管理页** 的插件自有页面上(侧边栏「插件」→ dsh-skill-hub)。该卡片由本插件自己注册进 `plugins.bundle.config` 槽位(dsh 没有自动生成的配置页),覆盖总开关、向 Agent 公告、圆点颜色、用量显示与统计窗口/间隔。
|
|
28
30
|
|
|
29
31
|
## 功能
|
|
30
32
|
|
|
@@ -35,10 +37,10 @@ dsh plugin --profile web add dsh-skill-hub
|
|
|
35
37
|
- **整理** — 场景(tag)+ 自动聚合的来源集合,全部可拖拽排序并持久化到 `~/.dsh/dsh-skill-hub.json`。编辑模式收敛删除/排序控件,阅读视图保持干净。
|
|
36
38
|
- **诊断与修复** — provider 跳过的文件给出原因(缺 frontmatter、YAML 非法、名称不一致、描述过短);可自动修复的(如描述里未加引号的 `:`)一键 Fix 落盘。
|
|
37
39
|
- **新建** — 新技能向导,写入 `~/.dsh/skills` 或 `~/.agents/skills`(`SKILL.md` 模板见下)。
|
|
38
|
-
- **市场** — 内置精选仓库 + 自定义 `owner/repo`。任何含 `SKILL.md`
|
|
40
|
+
- **市场** — 内置精选仓库 + 自定义 `owner/repo`。任何含 `SKILL.md` 的顶层目录都可扫描(无白名单);`SKILL.md` 直接放在仓库根时,整个仓库算一个技能,技能名取仓库名(`.github/` 等仓库基建不计入)。异步导入,字节级进度+取消。每个源钉一个版本 —— 点 ref 徽标可在发布版/分支/手输之间切换。
|
|
39
41
|
- **跟踪更新** — 导入的技能记录 repo+commit 快照。检查全部/一键全更;每源徽章(已装/可更新/上游已删/新版本)。同步覆盖本地修改(先确认);上游删除跟进移入回收站,恢复保留来源与场景归属。
|
|
40
42
|
- **统计** — 会话日志的调用次数+最近使用,分组头汇总;窗口与扫描间隔在设置卡片实时可调。
|
|
41
|
-
- **设置卡片** —
|
|
43
|
+
- **设置卡片** — 注册在 **插件管理页** 的插件自有页面上(侧边栏「插件」→ dsh-skill-hub,默认折叠,点标题展开):总开关、向 Agent 公告、调用圆点颜色、用量显示开关、统计窗口/间隔。
|
|
42
44
|
|
|
43
45
|
## 为什么还需要一个管理器?
|
|
44
46
|
|
|
@@ -92,7 +94,7 @@ GitHub 仓库 ──扫描/导入──▶ ~/.dsh/skills
|
|
|
92
94
|
| `/api/skill-hub/config` | GET/POST | 运行时配置(`null` 清除) |
|
|
93
95
|
| `/api/skill-hub/groups` | GET | tags+集合+排序 |
|
|
94
96
|
| `/api/skill-hub/tag` 等 | POST | 新建/重命名、删除、设成员、排序 |
|
|
95
|
-
| `/api/skill-hub/market` 等 | GET/POST | 市场源 列表/添加/删除/钉 ref
|
|
97
|
+
| `/api/skill-hub/market` 等 | GET/POST | 市场源 列表/添加/删除/钉 ref;`…/source/check` + `…/source/sync` 检查与同步 |
|
|
96
98
|
| `/api/skill-hub/market/source/versions?repo=` | GET | 版本选择器的 releases+branches |
|
|
97
99
|
| `/api/skill-hub/repo?repo=` | GET | 发现(任意根) |
|
|
98
100
|
| `/api/skill-hub/repo/import` | POST | 异步任务 `{jobId, total, totalBytes}` |
|
|
@@ -100,12 +102,13 @@ GitHub 仓库 ──扫描/导入──▶ ~/.dsh/skills
|
|
|
100
102
|
| `/api/skill-hub/repo/import/cancel` | POST | 取消任务 |
|
|
101
103
|
| `/api/skill-hub/sources` 等 | GET/POST | 来源 列表/检查/同步/删除/恢复/清空回收站 |
|
|
102
104
|
| `/api/skill-hub/update` | GET | 插件最新发布 |
|
|
105
|
+
| 未知的 `/api/skill-hub/*` | GET/POST | `404 {error}` 且写明路径 —— 拼错路径不该被读成鉴权失败(宿主 SPA fallback 对自己不拥有的 `/api/*` 一律回 401) |
|
|
103
106
|
|
|
104
107
|
## 开发
|
|
105
108
|
|
|
106
109
|
```bash
|
|
107
110
|
npm run typecheck # tsc --noEmit
|
|
108
|
-
npm test #
|
|
111
|
+
npm test # 255 tests, 14 suites
|
|
109
112
|
npm run build # tsc + tsdown → lib/index.js + lib/client.js
|
|
110
113
|
```
|
|
111
114
|
|
|
@@ -117,6 +120,7 @@ npm run build # tsc + tsdown → lib/index.js + lib/client.js
|
|
|
117
120
|
- 技能不出现 — 看诊断区(缺 frontmatter / 名称不一致 / 描述过短)。
|
|
118
121
|
- 来源组空壳 — 组内技能已被删除、或禁用记录丢失(状态文件被恢复/手改)。启动时自动对账磁盘上的 `.disabled` 文件补记录;无可见成员的来源组不再渲染。
|
|
119
122
|
- `/` 菜单圆点消失 — dsh 内部触发源变更,目录功能不受影响。
|
|
123
|
+
- 找不到配置卡片 — 在插件管理页打开本插件(侧边栏「插件」→ dsh-skill-hub),展开页面顶部的「技能中枢」卡片(默认折叠)。dsh 低于 `0.1.7-alpha.1` 时本插件无法加载(它所用的 settings API 在旧版不存在)。
|
|
120
124
|
|
|
121
125
|
## 社区
|
|
122
126
|
|
package/lib/client.js
CHANGED
|
@@ -7,7 +7,13 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let react = require("react");
|
|
8
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
9
9
|
//#region src/protocol/api.ts
|
|
10
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Browser-facing base paths of the skill-hub API family.
|
|
12
|
+
*
|
|
13
|
+
* Naming rule: a path's segments mirror its scope. Market sources own the
|
|
14
|
+
* `/market/source/*` subtree — add, delete, ref, versions, check, sync — so
|
|
15
|
+
* the update check and the sync that acts on its result sit side by side.
|
|
16
|
+
*/
|
|
11
17
|
const SKILL_HUB_API = {
|
|
12
18
|
catalog: "/api/skill-hub/catalog",
|
|
13
19
|
skill: "/api/skill-hub/skill",
|
|
@@ -21,7 +27,7 @@ window.__ModuleLoader__.load({
|
|
|
21
27
|
marketSource: "/api/skill-hub/market/source",
|
|
22
28
|
marketSourceDelete: "/api/skill-hub/market/source/delete",
|
|
23
29
|
marketSourceRef: "/api/skill-hub/market/source/ref",
|
|
24
|
-
marketCheck: "/api/skill-hub/market/check",
|
|
30
|
+
marketCheck: "/api/skill-hub/market/source/check",
|
|
25
31
|
marketSync: "/api/skill-hub/market/source/sync",
|
|
26
32
|
repo: "/api/skill-hub/repo",
|
|
27
33
|
repoImport: "/api/skill-hub/repo/import",
|
|
@@ -46,6 +52,16 @@ window.__ModuleLoader__.load({
|
|
|
46
52
|
marketStats: "/api/skill-hub/market/stats"
|
|
47
53
|
};
|
|
48
54
|
//#endregion
|
|
55
|
+
//#region src/protocol/config.ts
|
|
56
|
+
/**
|
|
57
|
+
* This plugin's Loader entry id — the settings namespace dsh serves its config
|
|
58
|
+
* under. It is cordis.patch.yml's insert id, NOT the package name, and it is
|
|
59
|
+
* shared by contract because the browser half addresses the same form through
|
|
60
|
+
* `ctx.configForms.get(HUB_ENTRY_ID)` while the host half writes through
|
|
61
|
+
* `ctx.settings.update(HUB_ENTRY_ID, …)`.
|
|
62
|
+
*/
|
|
63
|
+
const HUB_ENTRY_ID = "skill-hub";
|
|
64
|
+
//#endregion
|
|
49
65
|
//#region src/protocol/sources.ts
|
|
50
66
|
/** 项目级技能来源(它们有 workspace 归属,不属于「个人」组)。 */
|
|
51
67
|
function isProjectSource(source) {
|
|
@@ -480,6 +496,7 @@ window.__ModuleLoader__.load({
|
|
|
480
496
|
"repo.cancel": "取消",
|
|
481
497
|
"repo.cancelled": "已取消 · 已导入 {imported}/{total} 已保留,临时文件已清理",
|
|
482
498
|
"repo.importingCurrent": "正在导入: {name} ({done}/{total})",
|
|
499
|
+
"repo.root.self": "仓库根",
|
|
483
500
|
"repo.root.skills": "skills",
|
|
484
501
|
"repo.root.designTemplates": "design-templates",
|
|
485
502
|
"repo.root.generic": "{root}"
|
|
@@ -559,6 +576,7 @@ window.__ModuleLoader__.load({
|
|
|
559
576
|
"repo.cancel": "Cancel",
|
|
560
577
|
"repo.cancelled": "Cancelled · {imported}/{total} kept, temp files cleaned",
|
|
561
578
|
"repo.importingCurrent": "Importing: {name} ({done}/{total})",
|
|
579
|
+
"repo.root.self": "Repo root",
|
|
562
580
|
"repo.root.skills": "Skills",
|
|
563
581
|
"repo.root.designTemplates": "Templates",
|
|
564
582
|
"repo.root.generic": "{root}"
|
|
@@ -1164,36 +1182,11 @@ window.__ModuleLoader__.load({
|
|
|
1164
1182
|
}
|
|
1165
1183
|
}
|
|
1166
1184
|
/**
|
|
1167
|
-
*
|
|
1168
|
-
*
|
|
1169
|
-
* @param
|
|
1170
|
-
* @
|
|
1171
|
-
|
|
1172
|
-
function dotIcon(color) {
|
|
1173
|
-
return (0, react.createElement)("span", {
|
|
1174
|
-
"aria-hidden": true,
|
|
1175
|
-
style: {
|
|
1176
|
-
display: "inline-block",
|
|
1177
|
-
width: 6,
|
|
1178
|
-
height: 6,
|
|
1179
|
-
borderRadius: 3,
|
|
1180
|
-
background: color,
|
|
1181
|
-
flex: "none"
|
|
1182
|
-
}
|
|
1183
|
-
});
|
|
1184
|
-
}
|
|
1185
|
-
/**
|
|
1186
|
-
* Wrap the core skill source so every menu row carries the invocation dot.
|
|
1187
|
-
* Exported for unit tests; production wiring goes through setupSkillSlashDots.
|
|
1188
|
-
* @param source - the registered `/skill` source.
|
|
1189
|
-
* @param api - hub browser API for the modelInvocable lookup.
|
|
1190
|
-
* @param scope - hub settings scope for the dot colors.
|
|
1191
|
-
* @returns a disposer restoring the original candidates.
|
|
1192
|
-
*/
|
|
1193
|
-
/**
|
|
1194
|
-
* DOM 兜底:在 alpha.2 新版 MenuView(icon 仅枚举)下通过直接操作
|
|
1195
|
-
* 已渲染的 `[role="option"]` 列表注入彩色点,绕过 `icon` 限制。
|
|
1196
|
-
* 旧版仍走 `icon` 注入,此处仅为新版。
|
|
1185
|
+
* 通过直接操作已渲染的 `[role="option"]` 列表注入彩色点,
|
|
1186
|
+
* 绕过 MenuView 对 `icon` 的枚举限制。
|
|
1187
|
+
* @param modelByName - 技能名 → 模型可调用性;不在表内的候选不注点。
|
|
1188
|
+
* @param modelColor - 模型可调用技能的点色。
|
|
1189
|
+
* @param userColor - 仅用户可调用技能的点色。
|
|
1197
1190
|
*/
|
|
1198
1191
|
function injectDotsViaDOM(modelByName, modelColor, userColor) {
|
|
1199
1192
|
if (typeof document === "undefined" || typeof requestAnimationFrame === "undefined") return;
|
|
@@ -1231,25 +1224,24 @@ window.__ModuleLoader__.load({
|
|
|
1231
1224
|
};
|
|
1232
1225
|
requestAnimationFrame(() => setTimeout(run, 0));
|
|
1233
1226
|
}
|
|
1227
|
+
/**
|
|
1228
|
+
* Wrap the core skill source so every menu row carries the invocation dot.
|
|
1229
|
+
* Exported for unit tests; production wiring goes through setupSkillSlashDots.
|
|
1230
|
+
* @param source - the registered `/skill` source.
|
|
1231
|
+
* @param api - hub browser API for the modelInvocable lookup.
|
|
1232
|
+
* @param scope - hub settings scope for the dot colors.
|
|
1233
|
+
* @returns a disposer restoring the original candidates.
|
|
1234
|
+
*/
|
|
1234
1235
|
function wrapSkillSource(source, api, scope) {
|
|
1235
1236
|
const original = source.candidates;
|
|
1236
1237
|
source.candidates = async (session, req) => {
|
|
1237
1238
|
const items = await original(session, req);
|
|
1238
1239
|
if (req.signal.aborted) return items;
|
|
1239
|
-
const isNewHost = req !== null && typeof req === "object" && "drilled" in req;
|
|
1240
1240
|
const modelByName = await modelInvocableMap(api);
|
|
1241
1241
|
if (req.signal.aborted) return items;
|
|
1242
1242
|
const snapshot = scope.getSnapshot();
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
if (isNewHost) {
|
|
1246
|
-
injectDotsViaDOM(modelByName, modelColor, userColor);
|
|
1247
|
-
return items;
|
|
1248
|
-
}
|
|
1249
|
-
return items.map((item) => ({
|
|
1250
|
-
...item,
|
|
1251
|
-
icon: dotIcon(modelByName.get(item.name) ?? true ? modelColor : userColor)
|
|
1252
|
-
}));
|
|
1243
|
+
injectDotsViaDOM(modelByName, snapshot.value?.dotModelColor ?? "#2f81f7", snapshot.value?.dotUserColor ?? "#3fb950");
|
|
1244
|
+
return items;
|
|
1253
1245
|
};
|
|
1254
1246
|
return () => {
|
|
1255
1247
|
source.candidates = original;
|
|
@@ -2585,8 +2577,10 @@ window.__ModuleLoader__.load({
|
|
|
2585
2577
|
* The dsh-skill-hub plugin settings card: bridges the hub's settings
|
|
2586
2578
|
* namespace (bound through the official settings transport) onto the
|
|
2587
2579
|
* family-style staged card form (enabled master switch + agent announcement).
|
|
2588
|
-
* Registered into
|
|
2589
|
-
*
|
|
2580
|
+
* Registered into `plugins.bundle.config` under the bundle's package name, so
|
|
2581
|
+
* the Plugins manager renders it on dsh-skill-hub's own page. That slot is
|
|
2582
|
+
* dispatched with `view: 'page'` only, so the card always renders its full
|
|
2583
|
+
* form (no `summary` one-liner variant).
|
|
2590
2584
|
*/
|
|
2591
2585
|
/** Bridges the hub's config scope onto the card's staged form. */
|
|
2592
2586
|
var SkillHubSettingsCardController = class {
|
|
@@ -3860,7 +3854,7 @@ window.__ModuleLoader__.load({
|
|
|
3860
3854
|
const visible = visibleCollections(groupsState?.collections ?? [], sourceFiltered, catalog?.disabled ?? [], normalized, sourceFilter, origins);
|
|
3861
3855
|
const collections = visible.map((entry) => entry.collection);
|
|
3862
3856
|
const uncategorized = sourceFiltered.filter((skill) => origins[skill.name] === void 0 && !isProjectSource(skill.source));
|
|
3863
|
-
const personalDisabled = (catalog?.disabled ?? []).filter((record) => origins[record.name] === void 0).filter((record) => normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized)).filter((
|
|
3857
|
+
const personalDisabled = (catalog?.disabled ?? []).filter((record) => origins[record.name] === void 0).filter((record) => normalized.length === 0 || record.name.toLocaleLowerCase().includes(normalized) || record.description.toLocaleLowerCase().includes(normalized)).filter(() => sourceFilter === "all" || sourceFilter === "private");
|
|
3864
3858
|
const allPersonalNames = [...uncategorized.map((s) => s.name), ...personalDisabled.map((r) => r.name)];
|
|
3865
3859
|
const hasPersonal = allPersonalNames.length > 0;
|
|
3866
3860
|
const defaultTopKeys = [
|
|
@@ -4761,8 +4755,11 @@ window.__ModuleLoader__.load({
|
|
|
4761
4755
|
/**
|
|
4762
4756
|
* 已知技能根的显示名键;未知根直接显示目录名。
|
|
4763
4757
|
* zh 字典里这两项就是目录名本身(与接线前的硬编码文本一致)。
|
|
4758
|
+
* 空串是「技能就在仓库根」的哨兵根(host 侧 REPO_ROOT),目录名无从显示,
|
|
4759
|
+
* 给它一个可读标签,否则筛选按钮会是一片空白。
|
|
4764
4760
|
*/
|
|
4765
4761
|
function rootLabelKey(root) {
|
|
4762
|
+
if (root === "") return "repo.root.self";
|
|
4766
4763
|
if (root === "skills") return "repo.root.skills";
|
|
4767
4764
|
if (root === "design-templates") return "repo.root.designTemplates";
|
|
4768
4765
|
return "repo.root.generic";
|
|
@@ -4923,7 +4920,7 @@ window.__ModuleLoader__.load({
|
|
|
4923
4920
|
" ",
|
|
4924
4921
|
counts.get(root) ?? 0
|
|
4925
4922
|
]
|
|
4926
|
-
}, root))
|
|
4923
|
+
}, root === "" ? "repo-root" : root))
|
|
4927
4924
|
]
|
|
4928
4925
|
});
|
|
4929
4926
|
})(),
|
|
@@ -5013,7 +5010,7 @@ window.__ModuleLoader__.load({
|
|
|
5013
5010
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5014
5011
|
className: panel_module_css_default.rowDesc,
|
|
5015
5012
|
children: [
|
|
5016
|
-
entry.dir,
|
|
5013
|
+
entry.dir === "" ? tt("repo.root.self") : entry.dir,
|
|
5017
5014
|
" · ",
|
|
5018
5015
|
tt("repo.files", {
|
|
5019
5016
|
count: entry.fileCount,
|
|
@@ -6941,7 +6938,7 @@ window.__ModuleLoader__.load({
|
|
|
6941
6938
|
const [workspaceDraft, setWorkspaceDraft] = (0, react.useState)("");
|
|
6942
6939
|
/** 「筛选」面板开合(来源 + 调用方式收进这里;搜索/排序/视图切换始终可见)。 */
|
|
6943
6940
|
const [filtersOpen, setFiltersOpen] = (0, react.useState)(false);
|
|
6944
|
-
const { catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc, formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search, workspace, setWorkspace, sourcesState, tagBusy, batchBusy,
|
|
6941
|
+
const { catalog, loading, loadError, successBanner, updateState, detail, detailLoading, showForm, formName, formDesc, formRoot, formBusy, formMessage, hubConfig, tab, skillView, sourceFilter, sortKey, search, workspace, setWorkspace, sourcesState, tagBusy, batchBusy, sourceOptions, filtered, conflictDialog, confirmDialog, deleteSkillDialog, deleteGroupDialog, confirmClearTrash, branchChoice, branchBusy, marketSyncDialog, syncBusy, editingTag, editName, membersDraft, editSearch, uses, groupsState, sourceCheck, checkingSource, syncingSource, showLegend, editMode, setLoadError, setSuccessBanner, setDetail, setShowForm, setFormName, setFormDesc, setFormRoot, setFormMessage, setTab, setSkillView, setSourceFilter, setSortKey, setSearch, setConflictDialog, setConfirmDialog, setDeleteSkillDialog, setDeleteGroupDialog, setConfirmClearTrash, setBranchChoice, setMarketSyncDialog, setEditingTag, setEditName, setMembersDraft, setEditSearch, setShowLegend, setEditMode, checkUpdate, loadMarket, checkSources, requestSync, requestDelete, restoreTrash, clearTrash, runDeleteSkill, runDeleteGroup, runConfirmed, resolveConflict, confirmBranchChoice, confirmMarketSync, create, saveTag, deleteTag, enableDisabled } = hub;
|
|
6945
6942
|
const { shortenedCount, fixingPaths, clearListFilters } = hub;
|
|
6946
6943
|
if (detail !== null) {
|
|
6947
6944
|
const disabledRecord = catalog?.disabled.find((record) => record.name === detail.name);
|
|
@@ -7588,16 +7585,16 @@ window.__ModuleLoader__.load({
|
|
|
7588
7585
|
/**
|
|
7589
7586
|
* Required services (fiber inject waiting — the runtime must be up first).
|
|
7590
7587
|
* `connection`/`remote` are the settings transport's own prerequisites
|
|
7591
|
-
* (`ctx.
|
|
7592
|
-
* `
|
|
7593
|
-
* settings-plugins inject list.
|
|
7588
|
+
* (`ctx.configForms.get` resolves them on the caller's fiber), and
|
|
7589
|
+
* `configForms` is the shared settings-form service itself; mirror the
|
|
7590
|
+
* official settings-plugins inject list.
|
|
7594
7591
|
*/
|
|
7595
7592
|
const inject = [
|
|
7596
7593
|
"slots",
|
|
7597
7594
|
"locale",
|
|
7598
7595
|
"connection",
|
|
7599
7596
|
"remote",
|
|
7600
|
-
"
|
|
7597
|
+
"configForms",
|
|
7601
7598
|
"inputTriggers"
|
|
7602
7599
|
];
|
|
7603
7600
|
/**
|
|
@@ -7611,15 +7608,15 @@ window.__ModuleLoader__.load({
|
|
|
7611
7608
|
}), "dsh-skill-hub: dictionaries");
|
|
7612
7609
|
const t = ctx.locale.bind(NS);
|
|
7613
7610
|
const api = new SkillHubApi();
|
|
7614
|
-
const scope = ctx.
|
|
7611
|
+
const scope = ctx.configForms.get(HUB_ENTRY_ID);
|
|
7615
7612
|
const settingsCard = new SkillHubSettingsCardController(scope);
|
|
7616
7613
|
ctx.effect(() => setupSkillSlashDots(ctx, api, scope), "dsh-skill-hub: slash dots");
|
|
7617
|
-
ctx.effect(() => ctx.slots.inject("
|
|
7618
|
-
name: "
|
|
7619
|
-
key:
|
|
7614
|
+
ctx.effect(() => ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({
|
|
7615
|
+
name: "plugins.bundle.config",
|
|
7616
|
+
key: "dsh-skill-hub",
|
|
7620
7617
|
locale: NS,
|
|
7621
7618
|
inject: () => settingsCard.inject()
|
|
7622
|
-
}, SkillHubSettingsCard)), "dsh-skill-hub:
|
|
7619
|
+
}, SkillHubSettingsCard)), "dsh-skill-hub: plugin config");
|
|
7623
7620
|
ctx.effect(() => ctx.slots.inject("settings.section", () => ctx.slots.register({
|
|
7624
7621
|
name: "settings.section",
|
|
7625
7622
|
id: "skill-hub",
|