dshmarket 1.2.1 → 1.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/README.zh.md +8 -0
- package/client/client.js +141 -83
- package/client/client.js.map +1 -1
- package/lib/dsh-cli.js +164 -0
- package/lib/http.js +39 -0
- package/lib/install.js +110 -0
- package/lib/pnpm-compat.js +72 -0
- package/lib/profile.js +121 -0
- package/lib/routes.js +63 -552
- package/lib/sources.js +85 -0
- package/lib/themes.js +102 -0
- package/lib/types/dsh-cli.d.ts +61 -0
- package/lib/types/http.d.ts +12 -0
- package/lib/types/install.d.ts +49 -0
- package/lib/types/pnpm-compat.d.ts +42 -0
- package/lib/types/profile.d.ts +24 -0
- package/lib/types/routes.d.ts +7 -21
- package/lib/types/sources.d.ts +42 -0
- package/lib/types/themes.d.ts +40 -0
- package/lib/types/updates.d.ts +16 -0
- package/lib/updates.js +61 -0
- package/package.json +5 -2
- package/src/client/Market.module.css +4 -1
- package/src/client/MarketSection.tsx +25 -39
- package/src/client/locales.ts +2 -0
- package/src/client/market-data.ts +103 -7
- package/src/dsh-cli.ts +194 -0
- package/src/http.ts +41 -0
- package/src/install.ts +121 -0
- package/src/pnpm-compat.ts +83 -0
- package/src/profile.ts +120 -0
- package/src/routes.ts +68 -583
- package/src/sources.ts +84 -0
- package/src/themes.ts +120 -0
- package/src/updates.ts +70 -0
package/README.md
CHANGED
|
@@ -51,6 +51,14 @@ Installs prefer npm tarballs over full-repo GitHub downloads whenever a plugin p
|
|
|
51
51
|
|
|
52
52
|
Live from [awesome-dsh-plugin.com/plugins.json](https://awesome-dsh-plugin.com/plugins.json) — curated entries, npm mapping, and star counts refreshed daily by CI — with a bundled snapshot as offline fallback.
|
|
53
53
|
|
|
54
|
+
## Related projects
|
|
55
|
+
|
|
56
|
+
### DeepSeek Harness Desktop
|
|
57
|
+
|
|
58
|
+
[DeepSeek Harness Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop) is a modern desktop client for the DeepSeek Harness ecosystem — start and manage a local Harness service without installing Node.js or touching the command line. Plugin marketplace, mobile remote control, and IM Channels are on its roadmap.
|
|
59
|
+
|
|
60
|
+
[Website](https://www.dshdesktop.cn) · [GitHub](https://github.com/anywhere-labs/deepseek-harness-desktop)
|
|
61
|
+
|
|
54
62
|
## License
|
|
55
63
|
|
|
56
64
|
MIT · [dshmarket.com](https://dshmarket.com)
|
package/README.zh.md
CHANGED
|
@@ -51,6 +51,14 @@ dsh plugin --profile web add dshmarket
|
|
|
51
51
|
|
|
52
52
|
实时来自 [awesome-dsh-plugin.com/plugins.json](https://awesome-dsh-plugin.com/plugins.json)——精选条目、npm 映射、star 数由 CI 每日刷新——内置快照做离线兜底。
|
|
53
53
|
|
|
54
|
+
## 友情链接
|
|
55
|
+
|
|
56
|
+
### DeepSeek Harness Desktop
|
|
57
|
+
|
|
58
|
+
[DeepSeek Harness Desktop](https://github.com/anywhere-labs/deepseek-harness-desktop) 是一款为 DeepSeek Harness 生态打造的现代化桌面端,让用户无需配置 Node.js 或执行命令,即可启动和管理本地 Harness 服务。项目后续还将支持插件市场、移动端远程控制和 IM Channels。
|
|
59
|
+
|
|
60
|
+
[访问官网](https://www.dshdesktop.cn) · [GitHub](https://github.com/anywhere-labs/deepseek-harness-desktop)
|
|
61
|
+
|
|
54
62
|
## 许可
|
|
55
63
|
|
|
56
64
|
MIT · [dshmarket.com](https://dshmarket.com)
|
package/client/client.js
CHANGED
|
@@ -38,6 +38,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
38
38
|
update: "更新",
|
|
39
39
|
updating: "更新中…",
|
|
40
40
|
updated: "✓ 已更新,重启后生效",
|
|
41
|
+
updateNow: "立即更新",
|
|
41
42
|
updateFail: "更新失败",
|
|
42
43
|
upToDate: "已是最新",
|
|
43
44
|
linkedDev: "本地开发链接",
|
|
@@ -96,6 +97,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
96
97
|
update: "Update",
|
|
97
98
|
updating: "Updating…",
|
|
98
99
|
updated: "✓ Updated — restart to apply",
|
|
100
|
+
updateNow: "Update now",
|
|
99
101
|
updateFail: "Update failed",
|
|
100
102
|
upToDate: "Up to date",
|
|
101
103
|
linkedDev: "linked (dev)",
|
|
@@ -132,10 +134,6 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
132
134
|
for (let i = 0; i < name.length; i++) hash = hash * 31 + name.charCodeAt(i) | 0;
|
|
133
135
|
return "hsl(" + (hash % 360 + 360) % 360 + " 55% 52%)";
|
|
134
136
|
}
|
|
135
|
-
function repoOf(url) {
|
|
136
|
-
const m = /^https:\/\/github\.com\/([^/]+\/[^/]+?)(?:\/tree\/.+)?\/?$/.exec(url);
|
|
137
|
-
return m ? m[1] : null;
|
|
138
|
-
}
|
|
139
137
|
function readSession(key) {
|
|
140
138
|
try {
|
|
141
139
|
return JSON.parse(sessionStorage.getItem(key) || "null");
|
|
@@ -148,14 +146,75 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
148
146
|
const desc = plugin.description && (plugin.description[lang] || plugin.description.en) || "";
|
|
149
147
|
return /\b(tui|cli|tty|terminal)\b|终端|命令行/i.test(plugin.name + " " + desc);
|
|
150
148
|
}
|
|
151
|
-
/**
|
|
149
|
+
/**
|
|
150
|
+
* The discover list: category filter, then search across name / owner /
|
|
151
|
+
* localized description, then the selected sort. Pure — the section renders
|
|
152
|
+
* exactly this.
|
|
153
|
+
*/
|
|
154
|
+
function visiblePlugins(plugins, options) {
|
|
155
|
+
const query = options.query.trim().toLowerCase();
|
|
156
|
+
const list = plugins.filter((p) => {
|
|
157
|
+
if (options.category !== "all" && p.category !== options.category) return false;
|
|
158
|
+
if (query === "") return true;
|
|
159
|
+
const desc = p.description && (p.description[options.lang] || p.description.en) || "";
|
|
160
|
+
return p.name.toLowerCase().includes(query) || p.owner.toLowerCase().includes(query) || desc.toLowerCase().includes(query);
|
|
161
|
+
});
|
|
162
|
+
if (options.sort === "hot") return [...list].sort((a, b) => (b.stars ?? -1) - (a.stars ?? -1));
|
|
163
|
+
if (options.sort === "new") return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)));
|
|
164
|
+
return list;
|
|
165
|
+
}
|
|
166
|
+
/** The themes tab listing: theme category only, most-starred first. */
|
|
167
|
+
function themePlugins(plugins) {
|
|
168
|
+
return plugins.filter((p) => p.category === "theme").sort((a, b) => (b.stars || 0) - (a.stars || 0));
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Category chip order: collapsed with an active non-'all' chip, the active
|
|
172
|
+
* one moves to the front so it stays visible inside the two-row clip.
|
|
173
|
+
*/
|
|
174
|
+
function orderedCategories(categories, active, open) {
|
|
175
|
+
return open || active === "all" ? categories : [active, ...categories.filter((id) => id !== active)];
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Unified installed-state matching (#15): both sides collapse to lowercase
|
|
179
|
+
* identity sets — the registry entry contributes its bare name, npm name and
|
|
180
|
+
* owner/repo; the dependency contributes its key and the repo inside its
|
|
181
|
+
* spec — and any exact intersection counts. Exact equality, not substrings,
|
|
182
|
+
* so prefix-related repo names cannot cross-match.
|
|
183
|
+
*/
|
|
184
|
+
function entryIdentities(plugin) {
|
|
185
|
+
const ids = /* @__PURE__ */ new Set([plugin.name.toLowerCase()]);
|
|
186
|
+
if (plugin.npm) ids.add(plugin.npm.toLowerCase());
|
|
187
|
+
const m = /^https:\/\/github\.com\/([^/]+\/[^/]+?)(?:\/tree\/[^/]+\/(.+?))?\/?$/.exec(plugin.url);
|
|
188
|
+
if (m !== null) ids.add(m[2] !== void 0 ? `${m[1].toLowerCase()}#path:/${m[2].toLowerCase()}` : m[1].toLowerCase());
|
|
189
|
+
return ids;
|
|
190
|
+
}
|
|
191
|
+
function depIdentities(name, spec) {
|
|
192
|
+
const ids = /* @__PURE__ */ new Set([name.toLowerCase()]);
|
|
193
|
+
const scoped = /^@([^/]+)\/(.+)$/.exec(name);
|
|
194
|
+
if (scoped !== null) ids.add(`${scoped[1].toLowerCase()}/${scoped[2].toLowerCase()}`);
|
|
195
|
+
const match = /github:([A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+)(?:#path:\/([A-Za-z0-9_./-]+))?/i.exec(spec);
|
|
196
|
+
if (match !== null) {
|
|
197
|
+
ids.add(match[1].toLowerCase());
|
|
198
|
+
if (match[2] !== void 0) ids.add(`${match[1].toLowerCase()}#path:/${match[2].toLowerCase()}`);
|
|
199
|
+
}
|
|
200
|
+
return ids;
|
|
201
|
+
}
|
|
202
|
+
/** The installed dependency name a registry entry corresponds to, or null. */
|
|
203
|
+
function matchInstalledName(plugin, installed) {
|
|
204
|
+
const ids = entryIdentities(plugin);
|
|
205
|
+
for (const [name, spec] of Object.entries(installed)) for (const id of depIdentities(name, String(spec))) if (ids.has(id)) return name;
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
/** The registry entry an installed dependency corresponds to, or undefined. */
|
|
209
|
+
function entryForDep(plugins, name, spec) {
|
|
210
|
+
const ids = depIdentities(name, String(spec));
|
|
211
|
+
return plugins.find((plugin) => {
|
|
212
|
+
for (const id of entryIdentities(plugin)) if (ids.has(id)) return true;
|
|
213
|
+
return false;
|
|
214
|
+
});
|
|
215
|
+
}
|
|
152
216
|
function isInstalled(plugin, installed) {
|
|
153
|
-
|
|
154
|
-
if (plugin.npm && installed[plugin.npm] !== void 0) return true;
|
|
155
|
-
const repo = repoOf(plugin.url);
|
|
156
|
-
if (repo === null) return false;
|
|
157
|
-
const needle = ("github:" + repo).toLowerCase();
|
|
158
|
-
return Object.values(installed).some((spec) => String(spec).toLowerCase().includes(needle));
|
|
217
|
+
return matchInstalledName(plugin, installed) !== null;
|
|
159
218
|
}
|
|
160
219
|
/**
|
|
161
220
|
* The brand mark (assets/logo.svg — shared block-grid mark with
|
|
@@ -205,7 +264,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
205
264
|
}
|
|
206
265
|
//#endregion
|
|
207
266
|
//#region \0dsh-css:/home/runner/work/dsh-market/dsh-market/src/client/Market.module.css.mjs
|
|
208
|
-
const css = ".eGUBIq_root{min-width:0;height:100%;color:var(--dsw-alias-label-primary,#1f2328);flex-direction:column;display:flex;position:relative}.eGUBIq_head{flex-direction:column;gap:12px;padding:4px 4px 12px;display:flex}.eGUBIq_title{margin:0;font-size:16px;font-weight:500;line-height:24px}.eGUBIq_sub{color:var(--dsw-alias-label-tertiary,#8b93a1);margin:0;font-size:14px;line-height:22px}.eGUBIq_searchInline{flex-shrink:0;width:200px;margin-bottom:6px}.eGUBIq_tabs{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:flex-end;gap:2px;display:flex}.eGUBIq_tab{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;padding:7px 12px;font-size:13px}.eGUBIq_tab.eGUBIq_on{color:var(--dsw-alias-brand-primary,#4f6ef7);border-bottom-color:var(--dsw-alias-brand-primary,#4f6ef7);font-weight:600}.eGUBIq_restart{background:var(--dsw-alias-bg-layer-2,#fdf3e3);border:1px solid var(--dsw-alias-border-l2,#f3e3c3);border-radius:8px;align-items:center;gap:8px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_body{flex:1;padding:12px 4px 24px;overflow-x:hidden;overflow-y:auto}.eGUBIq_cats{z-index:5;background:var(--dsw-alias-bg-layer-2,#f7f8fa);margin:-12px -4px 2px;padding:12px 4px 4px;position:sticky;top:-13px}.eGUBIq_catsRow{align-items:flex-start;gap:8px;display:flex;position:relative}.eGUBIq_sort{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l1,#e5e7eb);border-radius:8px;flex-shrink:0;gap:2px;padding:2px;display:flex}.eGUBIq_sort button{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:3px 10px;font-size:12px}.eGUBIq_sort button.eGUBIq_on{background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#1f2328);font-weight:600;box-shadow:0 1px 3px #00000014}.eGUBIq_star{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px}.eGUBIq_top{z-index:20;border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);width:38px;height:38px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;border-radius:99px;font-size:16px;position:absolute;bottom:18px;right:18px;box-shadow:0 4px 14px #0000001f}.eGUBIq_top:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_tag{border:1px solid var(--dsw-alias-border-l3,#d9dde3);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:4px;flex-shrink:0;padding:1px 6px;font-size:11px;line-height:16px}.eGUBIq_okState{color:var(--dsw-alias-state-success-primary,#16a34a);white-space:nowrap;font-size:12px;font-weight:600}.eGUBIq_dangerBtn.eGUBIq_dangerBtn{border-color:var(--dsw-alias-state-error-primary,#dc2626);color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_dangerArmed.eGUBIq_dangerArmed{background:var(--dsw-alias-state-error-primary,#dc2626);color:#fff}.eGUBIq_warnBtn.eGUBIq_warnBtn{background:var(--dsw-alias-state-warn-primary,#ea580c);color:#fff}.eGUBIq_catsWrap{flex-wrap:wrap;flex:1;align-items:center;gap:6px;min-width:0;display:flex}.eGUBIq_catsCollapsed{max-height:62px;overflow:hidden}.eGUBIq_catsToggle.eGUBIq_catsToggle{height:26px;min-height:26px;color:var(--dsw-alias-label-secondary,#6b7280);padding:0 6px}.eGUBIq_cmdDetails{margin:0}.eGUBIq_cmdSummary{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:6px;align-items:center;gap:6px;margin-left:-4px;padding:2px 4px;font-size:12px;font-weight:500;line-height:18px;list-style:none;display:flex}.eGUBIq_cmdSummary::-webkit-details-marker{display:none}.eGUBIq_cmdSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.eGUBIq_cmdDetails[open]>.eGUBIq_cmdSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.eGUBIq_cmdSummary:hover{color:var(--dsw-alias-label-primary,#1f2328)}.eGUBIq_cmd{background:var(--dsw-alias-bg-layer-2,#f3f4f6);word-break:break-all;border-radius:6px;margin:8px 0 0;padding:8px 10px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:18px}.eGUBIq_warnLine{color:var(--dsw-alias-state-warn-primary,#b45309);margin:0;font-size:12px;font-weight:600;line-height:18px}.eGUBIq_modalNote{color:var(--dsw-alias-label-tertiary,#8b93a1);margin:12px 0 0;font-size:12px;line-height:18px}.eGUBIq_grid{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px;display:grid}.eGUBIq_sect{color:var(--dsw-alias-label-secondary,#6b7280);margin:14px 2px 8px;font-size:12px;font-weight:600}.eGUBIq_sect:first-child{margin-top:2px}.eGUBIq_swatches{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;gap:0;height:34px;display:flex;overflow:hidden}.eGUBIq_themesGrid{margin-bottom:12px}.eGUBIq_swatches i{flex:1}.eGUBIq_card{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}.eGUBIq_row1{align-items:center;gap:10px;min-width:0;display:flex}.eGUBIq_av{color:#fff;object-fit:cover;background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:8px;flex-shrink:0;place-items:center;width:32px;height:32px;font-size:14px;font-weight:700;display:grid}.eGUBIq_nm{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:22px;overflow:hidden}.eGUBIq_owner{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px}.eGUBIq_desc{color:var(--dsw-alias-label-tertiary,#8b93a1);min-height:36px;margin:0;font-size:12px;line-height:18px}.eGUBIq_foot{align-items:center;gap:8px;margin-top:auto;display:flex}.eGUBIq_grow{flex:1}.eGUBIq_titleRow{align-items:center;gap:10px;display:flex}.eGUBIq_descTight{min-height:0}.eGUBIq_src{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px;text-decoration:none}.eGUBIq_src:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_dot{vertical-align:2px;margin-left:5px}.eGUBIq_loading{color:var(--dsw-alias-label-secondary,#9ca3af);flex-direction:column;align-items:center;gap:12px;padding:48px;font-size:13px;display:flex}.eGUBIq_spin{border:3px solid var(--dsw-alias-border-l1,#e5e7eb);border-top-color:var(--dsw-alias-brand-primary,#4f6ef7);border-radius:99px;width:22px;height:22px;animation:.8s linear infinite eGUBIq_sp}@keyframes eGUBIq_sp{to{transform:rotate(360deg)}}.eGUBIq_progress{background:var(--dsw-alias-bg-layer-2,#f3f4f6);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:8px;align-items:center;gap:9px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_irow .eGUBIq_progress{margin-top:8px}.eGUBIq_progress .eGUBIq_spin{border-width:2px;flex-shrink:0;width:14px;height:14px}.eGUBIq_progress code{text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,Menlo,monospace;font-size:11px;overflow:hidden}.eGUBIq_empty{color:var(--dsw-alias-label-secondary,#9ca3af);text-align:center;padding:32px;font-size:13px}.eGUBIq_err{color:var(--dsw-alias-state-error-primary,#dc2626);white-space:pre-wrap;word-break:break-all;margin:8px 0;font-size:12px}.eGUBIq_irow{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;align-items:center;gap:10px;margin-bottom:8px;padding:12px 14px;display:flex}.eGUBIq_irow>.eGUBIq_src,.eGUBIq_irow>.eGUBIq_owner,.
|
|
267
|
+
const css = ".eGUBIq_root{min-width:0;height:100%;color:var(--dsw-alias-label-primary,#1f2328);flex-direction:column;display:flex;position:relative}.eGUBIq_head{flex-direction:column;gap:12px;padding:4px 4px 12px;display:flex}.eGUBIq_title{margin:0;font-size:16px;font-weight:500;line-height:24px}.eGUBIq_sub{color:var(--dsw-alias-label-tertiary,#8b93a1);margin:0;font-size:14px;line-height:22px}.eGUBIq_searchInline{flex-shrink:0;width:200px;margin-bottom:6px}.eGUBIq_tabs{border-bottom:1px solid var(--dsw-alias-border-l2,#e5e7eb);align-items:flex-end;gap:2px;display:flex}.eGUBIq_tab{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border:none;border-bottom:2px solid #0000;padding:7px 12px;font-size:13px}.eGUBIq_tab.eGUBIq_on{color:var(--dsw-alias-brand-primary,#4f6ef7);border-bottom-color:var(--dsw-alias-brand-primary,#4f6ef7);font-weight:600}.eGUBIq_restart{background:var(--dsw-alias-bg-layer-2,#fdf3e3);border:1px solid var(--dsw-alias-border-l2,#f3e3c3);border-radius:8px;align-items:center;gap:8px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_body{flex:1;padding:12px 4px 24px;overflow-x:hidden;overflow-y:auto}.eGUBIq_cats{z-index:5;background:var(--dsw-alias-bg-layer-2,#f7f8fa);margin:-12px -4px 2px;padding:12px 4px 4px;position:sticky;top:-13px}.eGUBIq_catsRow{align-items:flex-start;gap:8px;display:flex;position:relative}.eGUBIq_sort{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l1,#e5e7eb);border-radius:8px;flex-shrink:0;gap:2px;padding:2px;display:flex}.eGUBIq_sort button{font:inherit;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:none;border-radius:6px;padding:3px 10px;font-size:12px}.eGUBIq_sort button.eGUBIq_on{background:var(--dsw-alias-bg-layer-1,#fff);color:var(--dsw-alias-label-primary,#1f2328);font-weight:600;box-shadow:0 1px 3px #00000014}.eGUBIq_star{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px}.eGUBIq_top{z-index:20;border:1px solid var(--dsw-alias-border-l1,#e5e7eb);background:var(--dsw-alias-bg-layer-1,#fff);width:38px;height:38px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;border-radius:99px;font-size:16px;position:absolute;bottom:18px;right:18px;box-shadow:0 4px 14px #0000001f}.eGUBIq_top:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_tag{border:1px solid var(--dsw-alias-border-l3,#d9dde3);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:4px;flex-shrink:0;padding:1px 6px;font-size:11px;line-height:16px}.eGUBIq_okState{color:var(--dsw-alias-state-success-primary,#16a34a);white-space:nowrap;font-size:12px;font-weight:600}.eGUBIq_dangerBtn.eGUBIq_dangerBtn{border-color:var(--dsw-alias-state-error-primary,#dc2626);color:var(--dsw-alias-state-error-primary,#dc2626)}.eGUBIq_dangerArmed.eGUBIq_dangerArmed{background:var(--dsw-alias-state-error-primary,#dc2626);color:#fff}.eGUBIq_warnBtn.eGUBIq_warnBtn{background:var(--dsw-alias-state-warn-primary,#ea580c);color:#fff}.eGUBIq_catsWrap{flex-wrap:wrap;flex:1;align-items:center;gap:6px;min-width:0;display:flex}.eGUBIq_catsCollapsed{max-height:62px;overflow:hidden}.eGUBIq_catsToggle.eGUBIq_catsToggle{height:26px;min-height:26px;color:var(--dsw-alias-label-secondary,#6b7280);padding:0 6px}.eGUBIq_cmdDetails{margin:0}.eGUBIq_cmdSummary{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary,#6b7280);border-radius:6px;align-items:center;gap:6px;margin-left:-4px;padding:2px 4px;font-size:12px;font-weight:500;line-height:18px;list-style:none;display:flex}.eGUBIq_cmdSummary::-webkit-details-marker{display:none}.eGUBIq_cmdSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.eGUBIq_cmdDetails[open]>.eGUBIq_cmdSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.eGUBIq_cmdSummary:hover{color:var(--dsw-alias-label-primary,#1f2328)}.eGUBIq_cmd{background:var(--dsw-alias-bg-layer-2,#f3f4f6);word-break:break-all;border-radius:6px;margin:8px 0 0;padding:8px 10px;font-family:ui-monospace,Menlo,monospace;font-size:11px;line-height:18px}.eGUBIq_warnLine{color:var(--dsw-alias-state-warn-primary,#b45309);margin:0;font-size:12px;font-weight:600;line-height:18px}.eGUBIq_modalNote{color:var(--dsw-alias-label-tertiary,#8b93a1);margin:12px 0 0;font-size:12px;line-height:18px}.eGUBIq_grid{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:12px;display:grid}.eGUBIq_sect{color:var(--dsw-alias-label-secondary,#6b7280);margin:14px 2px 8px;font-size:12px;font-weight:600}.eGUBIq_sect:first-child{margin-top:2px}.eGUBIq_swatches{border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:8px;gap:0;height:34px;display:flex;overflow:hidden}.eGUBIq_themesGrid{margin-bottom:12px}.eGUBIq_swatches i{flex:1}.eGUBIq_card{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}.eGUBIq_row1{align-items:center;gap:10px;min-width:0;display:flex}.eGUBIq_av{color:#fff;object-fit:cover;background:var(--dsw-alias-bg-layer-2,#f3f4f6);border-radius:8px;flex-shrink:0;place-items:center;width:32px;height:32px;font-size:14px;font-weight:700;display:grid}.eGUBIq_nm{text-overflow:ellipsis;white-space:nowrap;font-size:14px;font-weight:500;line-height:22px;overflow:hidden}.eGUBIq_owner{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px}.eGUBIq_desc{color:var(--dsw-alias-label-tertiary,#8b93a1);min-height:36px;margin:0;font-size:12px;line-height:18px}.eGUBIq_foot{align-items:center;gap:8px;margin-top:auto;display:flex}.eGUBIq_grow{flex:1}.eGUBIq_titleRow{align-items:center;gap:10px;display:flex}.eGUBIq_descTight{min-height:0}.eGUBIq_src{color:var(--dsw-alias-label-secondary,#9ca3af);font-size:11px;text-decoration:none}.eGUBIq_src:hover{color:var(--dsw-alias-brand-primary,#4f6ef7)}.eGUBIq_dot{vertical-align:2px;margin-left:5px}.eGUBIq_loading{color:var(--dsw-alias-label-secondary,#9ca3af);flex-direction:column;align-items:center;gap:12px;padding:48px;font-size:13px;display:flex}.eGUBIq_spin{border:3px solid var(--dsw-alias-border-l1,#e5e7eb);border-top-color:var(--dsw-alias-brand-primary,#4f6ef7);border-radius:99px;width:22px;height:22px;animation:.8s linear infinite eGUBIq_sp}@keyframes eGUBIq_sp{to{transform:rotate(360deg)}}.eGUBIq_progress{background:var(--dsw-alias-bg-layer-2,#f3f4f6);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);color:var(--dsw-alias-label-secondary,#6b7280);border-radius:8px;align-items:center;gap:9px;margin:0;padding:8px 12px;font-size:12px;display:flex}.eGUBIq_irow .eGUBIq_progress{margin-top:8px}.eGUBIq_progress .eGUBIq_spin{border-width:2px;flex-shrink:0;width:14px;height:14px}.eGUBIq_progress code{text-overflow:ellipsis;white-space:nowrap;font-family:ui-monospace,Menlo,monospace;font-size:11px;overflow:hidden}.eGUBIq_empty{color:var(--dsw-alias-label-secondary,#9ca3af);text-align:center;padding:32px;font-size:13px}.eGUBIq_err{color:var(--dsw-alias-state-error-primary,#dc2626);white-space:pre-wrap;word-break:break-all;margin:8px 0;font-size:12px}.eGUBIq_irow{background:var(--dsw-alias-bg-layer-1,#fff);border:1px solid var(--dsw-alias-border-l2,#e5e7eb);border-radius:12px;align-items:center;gap:10px;margin-bottom:8px;padding:12px 14px;display:flex}.eGUBIq_irow>.eGUBIq_src,.eGUBIq_irow>.eGUBIq_owner,.eGUBIq_dangerBtn.eGUBIq_dangerBtn,.eGUBIq_warnBtn.eGUBIq_warnBtn,.eGUBIq_dangerArmed.eGUBIq_dangerArmed{white-space:nowrap;flex-shrink:0}.eGUBIq_spec{color:var(--dsw-alias-label-secondary,#9ca3af);font-family:ui-monospace,Menlo,monospace;font-size:11px}.eGUBIq_staleAction{margin-top:8px}";
|
|
209
268
|
const tagId = "dshmarket/Market.module.css";
|
|
210
269
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
|
|
211
270
|
const tag = document.createElement("style");
|
|
@@ -215,59 +274,59 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
215
274
|
document.head.appendChild(tag);
|
|
216
275
|
}
|
|
217
276
|
var Market_module_css_default = {
|
|
218
|
-
"head": "eGUBIq_head",
|
|
219
277
|
"grid": "eGUBIq_grid",
|
|
220
|
-
"
|
|
221
|
-
"
|
|
222
|
-
"
|
|
223
|
-
"err": "eGUBIq_err",
|
|
278
|
+
"cmdDetails": "eGUBIq_cmdDetails",
|
|
279
|
+
"title": "eGUBIq_title",
|
|
280
|
+
"body": "eGUBIq_body",
|
|
224
281
|
"empty": "eGUBIq_empty",
|
|
225
|
-
"
|
|
226
|
-
"
|
|
282
|
+
"nm": "eGUBIq_nm",
|
|
283
|
+
"on": "eGUBIq_on",
|
|
284
|
+
"loading": "eGUBIq_loading",
|
|
285
|
+
"card": "eGUBIq_card",
|
|
227
286
|
"modalNote": "eGUBIq_modalNote",
|
|
287
|
+
"catsRow": "eGUBIq_catsRow",
|
|
288
|
+
"cats": "eGUBIq_cats",
|
|
289
|
+
"foot": "eGUBIq_foot",
|
|
290
|
+
"tabs": "eGUBIq_tabs",
|
|
291
|
+
"catsWrap": "eGUBIq_catsWrap",
|
|
292
|
+
"titleRow": "eGUBIq_titleRow",
|
|
293
|
+
"warnLine": "eGUBIq_warnLine",
|
|
294
|
+
"src": "eGUBIq_src",
|
|
228
295
|
"cmdSummary": "eGUBIq_cmdSummary",
|
|
229
|
-
"
|
|
230
|
-
"
|
|
231
|
-
"
|
|
232
|
-
"
|
|
233
|
-
"
|
|
234
|
-
"
|
|
235
|
-
"
|
|
296
|
+
"restart": "eGUBIq_restart",
|
|
297
|
+
"root": "eGUBIq_root",
|
|
298
|
+
"dangerArmed": "eGUBIq_dangerArmed",
|
|
299
|
+
"desc": "eGUBIq_desc",
|
|
300
|
+
"err": "eGUBIq_err",
|
|
301
|
+
"top": "eGUBIq_top",
|
|
302
|
+
"catsToggle": "eGUBIq_catsToggle",
|
|
236
303
|
"tab": "eGUBIq_tab",
|
|
237
|
-
"
|
|
238
|
-
"
|
|
304
|
+
"av": "eGUBIq_av",
|
|
305
|
+
"dangerBtn": "eGUBIq_dangerBtn",
|
|
306
|
+
"dot": "eGUBIq_dot",
|
|
307
|
+
"irow": "eGUBIq_irow",
|
|
239
308
|
"cmd": "eGUBIq_cmd",
|
|
309
|
+
"swatches": "eGUBIq_swatches",
|
|
310
|
+
"spin": "eGUBIq_spin",
|
|
240
311
|
"sort": "eGUBIq_sort",
|
|
241
|
-
"
|
|
242
|
-
"
|
|
243
|
-
"
|
|
312
|
+
"spec": "eGUBIq_spec",
|
|
313
|
+
"grow": "eGUBIq_grow",
|
|
314
|
+
"star": "eGUBIq_star",
|
|
244
315
|
"themesGrid": "eGUBIq_themesGrid",
|
|
245
|
-
"
|
|
246
|
-
"
|
|
247
|
-
"
|
|
248
|
-
"
|
|
249
|
-
"
|
|
316
|
+
"okState": "eGUBIq_okState",
|
|
317
|
+
"sect": "eGUBIq_sect",
|
|
318
|
+
"staleAction": "eGUBIq_staleAction",
|
|
319
|
+
"sub": "eGUBIq_sub",
|
|
320
|
+
"row1": "eGUBIq_row1",
|
|
321
|
+
"owner": "eGUBIq_owner",
|
|
250
322
|
"sp": "eGUBIq_sp",
|
|
323
|
+
"head": "eGUBIq_head",
|
|
251
324
|
"warnBtn": "eGUBIq_warnBtn",
|
|
252
|
-
"
|
|
253
|
-
"src": "eGUBIq_src",
|
|
254
|
-
"spin": "eGUBIq_spin",
|
|
325
|
+
"catsCollapsed": "eGUBIq_catsCollapsed",
|
|
255
326
|
"progress": "eGUBIq_progress",
|
|
256
|
-
"
|
|
257
|
-
"title": "eGUBIq_title",
|
|
258
|
-
"descTight": "eGUBIq_descTight",
|
|
259
|
-
"catsRow": "eGUBIq_catsRow",
|
|
260
|
-
"catsToggle": "eGUBIq_catsToggle",
|
|
261
|
-
"cats": "eGUBIq_cats",
|
|
327
|
+
"searchInline": "eGUBIq_searchInline",
|
|
262
328
|
"tag": "eGUBIq_tag",
|
|
263
|
-
"
|
|
264
|
-
"grow": "eGUBIq_grow",
|
|
265
|
-
"root": "eGUBIq_root",
|
|
266
|
-
"on": "eGUBIq_on",
|
|
267
|
-
"card": "eGUBIq_card",
|
|
268
|
-
"foot": "eGUBIq_foot",
|
|
269
|
-
"dot": "eGUBIq_dot",
|
|
270
|
-
"loading": "eGUBIq_loading"
|
|
329
|
+
"descTight": "eGUBIq_descTight"
|
|
271
330
|
};
|
|
272
331
|
//#endregion
|
|
273
332
|
//#region src/client/MarketSection.tsx
|
|
@@ -317,6 +376,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
317
376
|
const [installError, setInstallError] = (0, react.useState)(null);
|
|
318
377
|
const [updates, setUpdates] = (0, react.useState)({});
|
|
319
378
|
const [updatingName, setUpdatingName] = (0, react.useState)(null);
|
|
379
|
+
const [staleName, setStaleName] = (0, react.useState)(null);
|
|
320
380
|
const [updatingAll, setUpdatingAll] = (0, react.useState)(false);
|
|
321
381
|
const [updatedNames, setUpdatedNames] = (0, react.useState)([]);
|
|
322
382
|
const [hotUrls, setHotUrls] = (0, react.useState)([]);
|
|
@@ -423,19 +483,12 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
423
483
|
updatingName,
|
|
424
484
|
data
|
|
425
485
|
]);
|
|
426
|
-
const plugins = (0, react.useMemo)(() => {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
const desc = p.description && (p.description[lang] || p.description.en) || "";
|
|
433
|
-
return p.name.toLowerCase().includes(query) || p.owner.toLowerCase().includes(query) || desc.toLowerCase().includes(query);
|
|
434
|
-
});
|
|
435
|
-
if (sort === "hot") return [...list].sort((a, b) => (b.stars ?? -1) - (a.stars ?? -1));
|
|
436
|
-
if (sort === "new") return [...list].sort((a, b) => String(b.added).localeCompare(String(a.added)));
|
|
437
|
-
return list;
|
|
438
|
-
}, [
|
|
486
|
+
const plugins = (0, react.useMemo)(() => data === null ? [] : visiblePlugins(data.plugins, {
|
|
487
|
+
category: cat,
|
|
488
|
+
query: q,
|
|
489
|
+
lang,
|
|
490
|
+
sort
|
|
491
|
+
}), [
|
|
439
492
|
data,
|
|
440
493
|
q,
|
|
441
494
|
cat,
|
|
@@ -479,13 +532,17 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
479
532
|
setInstallError(t("installFail") + ": " + String(error));
|
|
480
533
|
}).finally(() => setBusyUrl(null));
|
|
481
534
|
}, [refreshInstalled, t]);
|
|
482
|
-
const doUpdate = (0, react.useCallback)((name) => {
|
|
535
|
+
const doUpdate = (0, react.useCallback)((name, force = false) => {
|
|
483
536
|
setInstallError(null);
|
|
537
|
+
setStaleName(null);
|
|
484
538
|
setUpdatingName(name);
|
|
485
539
|
return fetch("/dsh-market/update", {
|
|
486
540
|
method: "POST",
|
|
487
541
|
headers: { "content-type": "application/json" },
|
|
488
|
-
body: JSON.stringify(
|
|
542
|
+
body: JSON.stringify(force ? {
|
|
543
|
+
name,
|
|
544
|
+
force: true
|
|
545
|
+
} : { name })
|
|
489
546
|
}).then((res) => res.json().then((body) => ({
|
|
490
547
|
status: res.status,
|
|
491
548
|
body
|
|
@@ -494,6 +551,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
494
551
|
setUpdatedNames((names) => names.concat(name));
|
|
495
552
|
refreshInstalled();
|
|
496
553
|
} else {
|
|
554
|
+
if (body.stale === true) setStaleName(name);
|
|
497
555
|
const text = (v) => typeof v === "string" ? v : v && typeof v.text === "string" ? v.text : v == null ? "" : JSON.stringify(v);
|
|
498
556
|
const detail = text(body.error) || [text(body.stderr), text(body.stdout)].filter(Boolean).join("\n").trim() || "exit " + body.exitCode;
|
|
499
557
|
setInstallError(t("updateFail") + ": " + name + " — " + detail.trim().slice(-600));
|
|
@@ -556,7 +614,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
556
614
|
}, [updatableNames, doUpdate]);
|
|
557
615
|
const pendingRestart = doneUrls.length + updatedNames.length + removedCount;
|
|
558
616
|
const hasUpdates = Object.keys(installed).some((name) => !updatedNames.includes(name) && updates[name] && updates[name].updateAvailable);
|
|
559
|
-
const themePlugins = data === null ? [] : data.plugins
|
|
617
|
+
const themePlugins$1 = data === null ? [] : themePlugins(data.plugins);
|
|
560
618
|
const pluginCard = (p) => {
|
|
561
619
|
const desc = p.description && (p.description[lang] || p.description.en) || "";
|
|
562
620
|
const done = doneUrls.includes(p.url) || hotUrls.includes(p.url);
|
|
@@ -641,14 +699,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
641
699
|
]
|
|
642
700
|
}, p.url);
|
|
643
701
|
};
|
|
644
|
-
const installedNameOf = (p) =>
|
|
645
|
-
if (installed[p.name] !== void 0) return p.name;
|
|
646
|
-
const repo = repoOf(p.url);
|
|
647
|
-
if (repo === null) return null;
|
|
648
|
-
const needle = ("github:" + repo).toLowerCase();
|
|
649
|
-
for (const [name, spec] of Object.entries(installed)) if (String(spec).toLowerCase().includes(needle)) return name;
|
|
650
|
-
return null;
|
|
651
|
-
};
|
|
702
|
+
const installedNameOf = (p) => matchInstalledName(p, installed);
|
|
652
703
|
const bootEntries = typeof window !== "undefined" && window.__DSH_BOOT__ && Array.isArray(window.__DSH_BOOT__.entries) ? window.__DSH_BOOT__.entries : [];
|
|
653
704
|
const themePluginCard = (p) => {
|
|
654
705
|
const instName = installedNameOf(p);
|
|
@@ -947,9 +998,16 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
947
998
|
})
|
|
948
999
|
]
|
|
949
1000
|
}),
|
|
950
|
-
installError !== null && /* @__PURE__ */ (0, react_jsx_runtime.
|
|
1001
|
+
installError !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
951
1002
|
className: Market_module_css_default.err,
|
|
952
|
-
children: installError
|
|
1003
|
+
children: [installError, staleName !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1004
|
+
className: Market_module_css_default.staleAction,
|
|
1005
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1006
|
+
size: "sm",
|
|
1007
|
+
onClick: () => doUpdate(staleName, true),
|
|
1008
|
+
children: t("updateNow")
|
|
1009
|
+
})
|
|
1010
|
+
})]
|
|
953
1011
|
}),
|
|
954
1012
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
955
1013
|
className: Market_module_css_default.body,
|
|
@@ -969,7 +1027,7 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
969
1027
|
ref: catsWrapRef,
|
|
970
1028
|
className: catsOpen || visibleCats === null ? `${Market_module_css_default.catsWrap} ${Market_module_css_default.catsCollapsed}` : Market_module_css_default.catsWrap,
|
|
971
1029
|
children: (() => {
|
|
972
|
-
const ordered =
|
|
1030
|
+
const ordered = orderedCategories(categories, cat, catsOpen);
|
|
973
1031
|
const shown = catsOpen || visibleCats === null ? ordered : ordered.slice(0, Math.max(0, visibleCats - 1));
|
|
974
1032
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
975
1033
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Pill, {
|
|
@@ -1018,17 +1076,17 @@ window.__ModuleLoader__.load({ id: "dshmarket", factory: (require) => {
|
|
|
1018
1076
|
})(), data === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1019
1077
|
className: Market_module_css_default.loading,
|
|
1020
1078
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: Market_module_css_default.spin }), t("loading")]
|
|
1021
|
-
}) : themePlugins.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1079
|
+
}) : themePlugins$1.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1022
1080
|
className: Market_module_css_default.empty,
|
|
1023
1081
|
children: t("themeEmpty")
|
|
1024
1082
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1025
1083
|
className: Market_module_css_default.grid,
|
|
1026
|
-
children: themePlugins.map(themePluginCard)
|
|
1084
|
+
children: themePlugins$1.map(themePluginCard)
|
|
1027
1085
|
})] }) : Object.keys(installed).length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1028
1086
|
className: Market_module_css_default.empty,
|
|
1029
1087
|
children: t("installedEmpty")
|
|
1030
1088
|
}) : Object.entries(installed).map(([name, spec]) => {
|
|
1031
|
-
const entry = data === null ? void 0 : data.plugins
|
|
1089
|
+
const entry = data === null ? void 0 : entryForDep(data.plugins, name, String(spec));
|
|
1032
1090
|
const status = updates[name];
|
|
1033
1091
|
const version = status && status.version ? "v" + status.version : "";
|
|
1034
1092
|
const specText = String(spec);
|