dsh-m 0.4.3 → 0.5.1
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.en.md +12 -0
- package/README.md +12 -0
- package/docs/DESIGN.md +30 -0
- package/lib/cli.js +94 -20
- package/lib/client.js +282 -17
- package/lib/core/community-adapter.js +181 -0
- package/lib/core/community.js +433 -0
- package/lib/core/host-api.js +53 -19
- package/lib/core/httpx.js +38 -0
- package/lib/core/install-guard.js +308 -0
- package/lib/core/market.js +707 -57
- package/lib/core/profile-transaction.js +238 -1
- package/lib/core/registry-controller.js +8 -0
- package/lib/core/registry.js +3 -3
- package/lib/core/settings-compat.js +4 -0
- package/lib/core/toggle.js +6 -1
- package/lib/core/versions.js +149 -25
- package/lib/host.js +2 -0
- package/lib/tools.js +139 -33
- package/package.json +1 -1
- package/registry.json +19 -0
package/lib/client.js
CHANGED
|
@@ -27,10 +27,13 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
27
27
|
var market_state_exports = {};
|
|
28
28
|
__export(market_state_exports, {
|
|
29
29
|
MARKET_PAGE_SIZE: () => MARKET_PAGE_SIZE,
|
|
30
|
+
marketNotice: () => marketNotice,
|
|
30
31
|
normalizeMarketQuery: () => normalizeMarketQuery,
|
|
31
32
|
normalizeMarketResponse: () => normalizeMarketResponse,
|
|
32
33
|
registryNotice: () => registryNotice,
|
|
33
|
-
resetPageOnFilterChange: () => resetPageOnFilterChange
|
|
34
|
+
resetPageOnFilterChange: () => resetPageOnFilterChange,
|
|
35
|
+
sortMergedItems: () => sortMergedItems,
|
|
36
|
+
splitCategories: () => splitCategories
|
|
34
37
|
});
|
|
35
38
|
function toSafeInt(value, fallback, min, max) {
|
|
36
39
|
const n = typeof value === "number" && Number.isFinite(value) ? Math.floor(value) : fallback;
|
|
@@ -41,10 +44,11 @@ function toSafeInt(value, fallback, min, max) {
|
|
|
41
44
|
function normalizeMarketQuery(input) {
|
|
42
45
|
const raw = input && typeof input === "object" ? input : {};
|
|
43
46
|
const query = typeof raw.query === "string" ? raw.query.trim() : "";
|
|
44
|
-
const category = typeof raw.category === "string" && CATEGORIES.includes(raw.category) ? raw.category : null;
|
|
47
|
+
const category = typeof raw.category === "string" && (CATEGORIES.includes(raw.category) || COMMUNITY_SLUG_RE.test(raw.category)) ? raw.category : null;
|
|
45
48
|
const offset = toSafeInt(raw.offset, 0, 0);
|
|
46
49
|
const limit = toSafeInt(raw.limit, MARKET_PAGE_SIZE, 1, MARKET_PAGE_SIZE);
|
|
47
|
-
|
|
50
|
+
const primaryOnly = raw.primaryOnly === true;
|
|
51
|
+
return { query, category, offset, limit, primaryOnly };
|
|
48
52
|
}
|
|
49
53
|
function resetPageOnFilterChange(previous, next) {
|
|
50
54
|
const prev = previous && typeof previous === "object" ? previous : {};
|
|
@@ -72,6 +76,20 @@ function normalizeMarketResponse(raw) {
|
|
|
72
76
|
...rs,
|
|
73
77
|
errors: Array.isArray(rs.errors) ? rs.errors.map(String) : []
|
|
74
78
|
};
|
|
79
|
+
const c = body.community && typeof body.community === "object" && !Array.isArray(body.community) ? body.community : {};
|
|
80
|
+
const community = {
|
|
81
|
+
...FALLBACK_COMMUNITY,
|
|
82
|
+
...c,
|
|
83
|
+
enabled: c.enabled === true,
|
|
84
|
+
status: typeof c.status === "string" ? c.status : "disabled",
|
|
85
|
+
acceptedCount: typeof c.acceptedCount === "number" && Number.isFinite(c.acceptedCount) ? c.acceptedCount : 0,
|
|
86
|
+
upstreamCount: typeof c.upstreamCount === "number" && Number.isFinite(c.upstreamCount) ? c.upstreamCount : null,
|
|
87
|
+
displaced: typeof c.displaced === "number" && Number.isFinite(c.displaced) ? c.displaced : 0,
|
|
88
|
+
skippedDirty: typeof c.skippedDirty === "number" && Number.isFinite(c.skippedDirty) ? c.skippedDirty : 0,
|
|
89
|
+
skippedSubpathNoNpm: typeof c.skippedSubpathNoNpm === "number" && Number.isFinite(c.skippedSubpathNoNpm) ? c.skippedSubpathNoNpm : 0,
|
|
90
|
+
errors: Array.isArray(c.errors) ? c.errors.map(String) : [],
|
|
91
|
+
warnings: Array.isArray(c.warnings) ? c.warnings.map(String) : []
|
|
92
|
+
};
|
|
75
93
|
return {
|
|
76
94
|
items,
|
|
77
95
|
total,
|
|
@@ -79,6 +97,7 @@ function normalizeMarketResponse(raw) {
|
|
|
79
97
|
limit,
|
|
80
98
|
categoryCounts,
|
|
81
99
|
registryState,
|
|
100
|
+
community,
|
|
82
101
|
installedComplete: body.installedComplete === true,
|
|
83
102
|
latestComplete: body.latestComplete === true,
|
|
84
103
|
latestTimedOut: body.latestTimedOut === true
|
|
@@ -92,7 +111,40 @@ function registryNotice(summary, total) {
|
|
|
92
111
|
else if (!s.isDefault) key = "notice.custom";
|
|
93
112
|
return { key, count: typeof total === "number" && Number.isFinite(total) ? total : 0 };
|
|
94
113
|
}
|
|
95
|
-
|
|
114
|
+
function splitCategories(categoryCounts) {
|
|
115
|
+
const counts = categoryCounts && typeof categoryCounts === "object" && !Array.isArray(categoryCounts) ? categoryCounts : {};
|
|
116
|
+
const curated = CURATED_CATEGORIES.map(({ id, label }) => ({ id, label, count: typeof counts[id] === "number" ? counts[id] : 0 }));
|
|
117
|
+
const community = [];
|
|
118
|
+
const unknown = [];
|
|
119
|
+
for (const [id, raw] of Object.entries(counts)) {
|
|
120
|
+
const count = typeof raw === "number" && Number.isFinite(raw) ? raw : 0;
|
|
121
|
+
if (CURATED_IDS.has(id)) continue;
|
|
122
|
+
if (COMMUNITY_KNOWN_LABELS[id]) community.push({ id, label: COMMUNITY_KNOWN_LABELS[id], count });
|
|
123
|
+
else if (!SHARED_BUCKETS.has(id)) unknown.push({ id, label: id, count });
|
|
124
|
+
}
|
|
125
|
+
return { curated, community, unknown };
|
|
126
|
+
}
|
|
127
|
+
function marketNotice(registryState, community) {
|
|
128
|
+
const base = registryNotice(registryState, void 0);
|
|
129
|
+
const c = community && typeof community === "object" ? community : {};
|
|
130
|
+
if (c.status === "stale") base.communityStale = true;
|
|
131
|
+
if (registryState && registryState.status === "unavailable" && (c.status === "ready" || c.status === "stale")) {
|
|
132
|
+
base.communityFallback = true;
|
|
133
|
+
}
|
|
134
|
+
return base;
|
|
135
|
+
}
|
|
136
|
+
function sortMergedItems(items) {
|
|
137
|
+
const list = Array.isArray(items) ? items.filter((it) => it && typeof it === "object") : [];
|
|
138
|
+
const primary = list.filter((it) => it.community !== true);
|
|
139
|
+
const community = list.filter((it) => it.community === true).slice().sort((a, b) => {
|
|
140
|
+
const da = typeof a.downloads === "number" && Number.isFinite(a.downloads) ? a.downloads : -1;
|
|
141
|
+
const db = typeof b.downloads === "number" && Number.isFinite(b.downloads) ? b.downloads : -1;
|
|
142
|
+
if (da !== db) return db - da;
|
|
143
|
+
return String(a.name).localeCompare(String(b.name));
|
|
144
|
+
});
|
|
145
|
+
return [...primary, ...community];
|
|
146
|
+
}
|
|
147
|
+
var MARKET_PAGE_SIZE, CATEGORIES, FALLBACK_REGISTRY_STATE, COMMUNITY_SLUG_RE, CURATED_CATEGORIES, CURATED_IDS, SHARED_BUCKETS, COMMUNITY_KNOWN_LABELS, FALLBACK_COMMUNITY;
|
|
96
148
|
var init_market_state = __esm({
|
|
97
149
|
"src/client/market-state.js"() {
|
|
98
150
|
"use strict";
|
|
@@ -109,6 +161,53 @@ var init_market_state = __esm({
|
|
|
109
161
|
errors: [],
|
|
110
162
|
count: 0
|
|
111
163
|
};
|
|
164
|
+
COMMUNITY_SLUG_RE = /^[a-z0-9-]{1,32}$/;
|
|
165
|
+
CURATED_CATEGORIES = [
|
|
166
|
+
{ id: "market", label: "\u5E02\u573A" },
|
|
167
|
+
{ id: "tools", label: "\u5DE5\u5177" },
|
|
168
|
+
{ id: "ui", label: "\u754C\u9762" },
|
|
169
|
+
{ id: "search", label: "\u641C\u7D22" },
|
|
170
|
+
{ id: "other", label: "\u5176\u4ED6" }
|
|
171
|
+
];
|
|
172
|
+
CURATED_IDS = new Set(CURATED_CATEGORIES.map((c) => c.id));
|
|
173
|
+
SHARED_BUCKETS = /* @__PURE__ */ new Set(["ui", "tools", "market"]);
|
|
174
|
+
COMMUNITY_KNOWN_LABELS = {
|
|
175
|
+
agi: "AGI \u67B6\u6784\u63A2\u7D22",
|
|
176
|
+
usage: "\u7528\u91CF\u4E0E\u8BA1\u8D39",
|
|
177
|
+
theme: "\u4E3B\u9898\u4E0E\u5916\u89C2",
|
|
178
|
+
model: "\u6A21\u578B\u4E0E\u8D26\u53F7\u63A5\u5165",
|
|
179
|
+
identity: "\u8EAB\u4EFD\u4E0E\u901A\u4FE1",
|
|
180
|
+
session: "\u4F1A\u8BDD\u4E0E\u6D88\u606F",
|
|
181
|
+
memory: "\u8BB0\u5FC6",
|
|
182
|
+
wsl: "WSL \u4E0E Windows \u4E92\u64CD\u4F5C",
|
|
183
|
+
browser: "\u6D4F\u89C8\u5668\u4E0E\u7F51\u9875",
|
|
184
|
+
vision: "\u89C6\u89C9\u4E0E\u591A\u6A21\u6001",
|
|
185
|
+
voice: "\u8BED\u97F3\u4E0E\u97F3\u9891",
|
|
186
|
+
docs: "\u6587\u6863\u4E0E\u6E32\u67D3",
|
|
187
|
+
skill: "\u6280\u80FD\u5305",
|
|
188
|
+
workflow: "\u5DE5\u4F5C\u6D41\u4E0E\u81EA\u52A8\u5316",
|
|
189
|
+
git: "Git \u4E0E\u4EE3\u7801\u8BC4\u5BA1",
|
|
190
|
+
notify: "\u901A\u77E5\u4E0E\u96C6\u6210",
|
|
191
|
+
dev: "\u5F00\u53D1\u4E0E\u8FD0\u884C\u65F6",
|
|
192
|
+
security: "\u5B89\u5168\u4E0E\u6743\u9650",
|
|
193
|
+
remote: "\u8FDC\u7A0B\u4E0E\u79FB\u52A8\u7AEF",
|
|
194
|
+
fun: "\u5A31\u4E50"
|
|
195
|
+
};
|
|
196
|
+
FALLBACK_COMMUNITY = {
|
|
197
|
+
enabled: false,
|
|
198
|
+
status: "disabled",
|
|
199
|
+
version: null,
|
|
200
|
+
checkedAt: null,
|
|
201
|
+
fetchedAt: null,
|
|
202
|
+
route: null,
|
|
203
|
+
acceptedCount: 0,
|
|
204
|
+
upstreamCount: null,
|
|
205
|
+
displaced: 0,
|
|
206
|
+
skippedDirty: 0,
|
|
207
|
+
skippedSubpathNoNpm: 0,
|
|
208
|
+
errors: [],
|
|
209
|
+
warnings: []
|
|
210
|
+
};
|
|
112
211
|
}
|
|
113
212
|
});
|
|
114
213
|
|
|
@@ -309,7 +408,11 @@ function installedViewModel(it) {
|
|
|
309
408
|
latestLabelDetail: it.latestTag || (it.latestVersion ? `v${it.latestVersion}` : "\u2014"),
|
|
310
409
|
// 0.4.0(Task 17):运行相位/开关状态的 sub 行渲染原料;相位点 class 映射归 toggle-view
|
|
311
410
|
phaseKey: it.phase ? `phase.${it.phase}` : null,
|
|
312
|
-
enabledLabelKey: it.enabled === false ? "toggle.state.off" : "toggle.state.on"
|
|
411
|
+
enabledLabelKey: it.enabled === false ? "toggle.state.off" : "toggle.state.on",
|
|
412
|
+
// M1 Task 5:社区收录徽标(卡片/已装卡显示「社区收录」)
|
|
413
|
+
community: it.community === true,
|
|
414
|
+
// M1 Task 7 ⑩:检查未完成标注(latestError 行渲染原料;code → 安全化原因由调用方 i18n/lookup)
|
|
415
|
+
latestIssue: it.latestError ? { code: it.latestErrorCode ?? null, note: it.latestError } : null
|
|
313
416
|
};
|
|
314
417
|
}
|
|
315
418
|
function registrySourceKey(data) {
|
|
@@ -482,7 +585,7 @@ var h = React.createElement;
|
|
|
482
585
|
var { useState, useEffect, useCallback, useMemo, useRef } = React;
|
|
483
586
|
var PLUGIN_ID = "dsh-m";
|
|
484
587
|
var API = "/dshm";
|
|
485
|
-
var { MARKET_PAGE_SIZE: MARKET_PAGE_SIZE2, normalizeMarketQuery: normalizeMarketQuery2, resetPageOnFilterChange: resetPageOnFilterChange2, normalizeMarketResponse: normalizeMarketResponse2, registryNotice: registryNotice2 } = (init_market_state(), __toCommonJS(market_state_exports));
|
|
588
|
+
var { MARKET_PAGE_SIZE: MARKET_PAGE_SIZE2, normalizeMarketQuery: normalizeMarketQuery2, resetPageOnFilterChange: resetPageOnFilterChange2, normalizeMarketResponse: normalizeMarketResponse2, registryNotice: registryNotice2, splitCategories: splitCategories2, marketNotice: marketNotice2, sortMergedItems: sortMergedItems2 } = (init_market_state(), __toCommonJS(market_state_exports));
|
|
486
589
|
var { createMarkdown: createMarkdown2 } = (init_markdown(), __toCommonJS(markdown_exports));
|
|
487
590
|
var { ExtLink, MdImg, renderMarkdown } = createMarkdown2(h);
|
|
488
591
|
var { installedViewModel: installedViewModel2, registrySourceKey: registrySourceKey2 } = (init_installed_view(), __toCommonJS(installed_view_exports));
|
|
@@ -616,6 +719,30 @@ var ZH = {
|
|
|
616
719
|
"market.page.info": "\u7B2C {page} / {pages} \u9875 \xB7 \u5171 {total} \u6761",
|
|
617
720
|
"market.perf": "\u6536\u5F55\u8D85\u8FC7 200 \u6761\uFF1A\u4EC5\u67E5\u8BE2\u5F53\u524D\u9875\u7684\u6700\u65B0\u7248\u672C\uFF08\u6BCF\u9875 50 \u6761\uFF09\uFF0C\u5982\u9700\u5168\u90E8\u8BF7\u7528\u641C\u7D22/\u5206\u7C7B\u8FC7\u6EE4",
|
|
618
721
|
"notice.toolview.err": "\u6536\u5F55\u6E05\u5355\u6682\u4E0D\u53EF\u7528",
|
|
722
|
+
"cat.primaryonly": "\u53EA\u770B\u4E3B\u6E05\u5355",
|
|
723
|
+
"community.group": "\u793E\u533A",
|
|
724
|
+
"community.newgroup": "\u793E\u533A \xB7 \u65B0\u5206\u7C7B",
|
|
725
|
+
"badge.community": "\u793E\u533A\u6536\u5F55",
|
|
726
|
+
"community.stale": "\u793E\u533A\u76EE\u5F55\u4E3A\u7F13\u5B58\u5FEB\u7167\uFF08\u663E\u793A\u7684\u4E0D\u662F\u6700\u65B0\u6570\u636E\uFF09",
|
|
727
|
+
"community.fallback": "\u6536\u5F55\u6E05\u5355\u4E0D\u53EF\u7528\uFF0C\u5F53\u524D\u5C55\u793A\u793E\u533A\u6E05\u5355\u6761\u76EE",
|
|
728
|
+
"detail.capabilities": "\u80FD\u529B\u62AB\u9732",
|
|
729
|
+
"detail.capabilities.unscanned": "\u672A\u626B\u63CF \u2260 \u672A\u68C0\u51FA",
|
|
730
|
+
"detail.redlines": "\u80FD\u529B\u7EA2\u7EBF",
|
|
731
|
+
"guard.blocked": "\u5B89\u88C5\u88AB\u88C5\u540E\u5B88\u536B\u62E6\u622A",
|
|
732
|
+
"guard.compstatus": "\u8865\u507F\u7EC8\u6001",
|
|
733
|
+
"guard.repairbasis": "\u4FEE\u590D\u4F9D\u636E",
|
|
734
|
+
"guard.restartsafenow": "\u53EF\u4EE5\u91CD\u542F DSH Web",
|
|
735
|
+
"guard.restartunsafe": "\u4FEE\u590D\u540E\u518D\u91CD\u542F\uFF08\u4E0D\u8981\u73B0\u5728\u4E00\u952E\u91CD\u542F\uFF09",
|
|
736
|
+
"guard.noforce": "\u5B88\u536B\u62E6\u622A\u65E0\u300C\u4ECD\u8981\u5B89\u88C5\u300D\u901A\u9053\uFF0C\u8BF7\u6309\u4FEE\u590D\u4F9D\u636E\u4EBA\u5DE5\u5904\u7406",
|
|
737
|
+
"detail.screenshots": "\u622A\u56FE",
|
|
738
|
+
"installed.check.incomplete": "\u68C0\u67E5\u672A\u5B8C\u6210",
|
|
739
|
+
"settings.community": "\u793E\u533A\u6E05\u5355\uFF08awesome-dsh-plugin \u76EE\u5F55\uFF09",
|
|
740
|
+
"settings.community.none": "\u793E\u533A\u6E05\u5355\u672A\u542F\u7528\u6216\u4E0D\u53EF\u7528",
|
|
741
|
+
"settings.community.status": "\u72B6\u6001",
|
|
742
|
+
"settings.community.version": "\u76EE\u5F55\u7248\u672C",
|
|
743
|
+
"settings.community.route": "\u83B7\u53D6\u7EBF\u8DEF",
|
|
744
|
+
"settings.community.accepted": "\u6536\u5F55 / \u4E0A\u6E38",
|
|
745
|
+
"settings.community.displaced": "\u4E0E\u4E3B\u6E05\u5355\u91CD\u590D\u8BA9\u4F4D",
|
|
619
746
|
"self.upgraded": "dsh-m \u5DF2\u66F4\u65B0\u5230 v{v}\uFF0C\u91CD\u542F\u540E\u751F\u6548",
|
|
620
747
|
"self.failed": "\u81EA\u66F4\u65B0\u5931\u8D25\uFF1A{err}",
|
|
621
748
|
"registry.refreshed": "\u6536\u5F55\u6E05\u5355\u5DF2\u5F3A\u5236\u5237\u65B0",
|
|
@@ -807,6 +934,30 @@ var EN = {
|
|
|
807
934
|
"market.page.info": "Page {page} / {pages} \xB7 {total} listings",
|
|
808
935
|
"market.perf": "200+ listings: latest versions are queried for the current page only (50 per page); use search/category filters",
|
|
809
936
|
"notice.toolview.err": "Registry temporarily unavailable",
|
|
937
|
+
"cat.primaryonly": "Primary only",
|
|
938
|
+
"community.group": "Community",
|
|
939
|
+
"community.newgroup": "Community \xB7 New",
|
|
940
|
+
"badge.community": "Community",
|
|
941
|
+
"community.stale": "Community catalog served from cache (not the latest data)",
|
|
942
|
+
"community.fallback": "Registry unavailable \u2014 showing community listings",
|
|
943
|
+
"detail.capabilities": "Capabilities",
|
|
944
|
+
"detail.capabilities.unscanned": "Not scanned \u2260 not detected",
|
|
945
|
+
"detail.redlines": "Capability red lines",
|
|
946
|
+
"guard.blocked": "Install blocked by post-install guard",
|
|
947
|
+
"guard.compstatus": "Compensation status",
|
|
948
|
+
"guard.repairbasis": "Repair basis",
|
|
949
|
+
"guard.restartsafenow": "You can restart DSH Web now",
|
|
950
|
+
"guard.restartunsafe": "Fix before restarting (do not one-click restart now)",
|
|
951
|
+
"guard.noforce": "Guard blocks have no force channel \u2014 repair manually per the basis above",
|
|
952
|
+
"detail.screenshots": "Screenshots",
|
|
953
|
+
"installed.check.incomplete": "Check incomplete",
|
|
954
|
+
"settings.community": "Community catalog (awesome-dsh-plugin)",
|
|
955
|
+
"settings.community.none": "Community catalog disabled or unavailable",
|
|
956
|
+
"settings.community.status": "Status",
|
|
957
|
+
"settings.community.version": "Catalog version",
|
|
958
|
+
"settings.community.route": "Route",
|
|
959
|
+
"settings.community.accepted": "Accepted / upstream",
|
|
960
|
+
"settings.community.displaced": "Displaced (duplicate of primary)",
|
|
810
961
|
"self.upgraded": "dsh-m updated to v{v} \u2014 restart to take effect",
|
|
811
962
|
"self.failed": "Self-update failed: {err}",
|
|
812
963
|
"registry.refreshed": "Registry force-refreshed",
|
|
@@ -1031,6 +1182,9 @@ async function api(method, params, signal) {
|
|
|
1031
1182
|
if (!res.ok || data.ok === false) {
|
|
1032
1183
|
const err = new Error(data.error || `API ${res.status}`);
|
|
1033
1184
|
if (data && typeof data === "object" && data.issue) err.issue = data.issue;
|
|
1185
|
+
if (data && typeof data === "object" && data.kind && Array.isArray(data.violations)) {
|
|
1186
|
+
err.guard = { kind: data.kind, violations: data.violations, compensation: data.compensation, needsRestart: data.needsRestart === true, restartSafe: data.restartSafe === true, repairBasis: data.repairBasis };
|
|
1187
|
+
}
|
|
1034
1188
|
throw err;
|
|
1035
1189
|
}
|
|
1036
1190
|
return data;
|
|
@@ -1069,6 +1223,7 @@ function useMarketData() {
|
|
|
1069
1223
|
const params = {
|
|
1070
1224
|
query: nextQuery.query || void 0,
|
|
1071
1225
|
category: nextQuery.category || void 0,
|
|
1226
|
+
primaryOnly: nextQuery.primaryOnly === true ? true : void 0,
|
|
1072
1227
|
offset: nextQuery.offset,
|
|
1073
1228
|
limit: nextQuery.limit,
|
|
1074
1229
|
...force ? { force: true } : {}
|
|
@@ -1114,6 +1269,19 @@ function Icon({ entry }) {
|
|
|
1114
1269
|
function Spin() {
|
|
1115
1270
|
return h("span", { className: "dshm-spin" });
|
|
1116
1271
|
}
|
|
1272
|
+
function safeScreenshots(entry) {
|
|
1273
|
+
const list = Array.isArray(entry && entry.screenshots) ? entry.screenshots : [];
|
|
1274
|
+
return list.filter((u) => typeof u === "string" && u.length <= 2048).map((u) => {
|
|
1275
|
+
try {
|
|
1276
|
+
const parsed = new URL(u);
|
|
1277
|
+
if (parsed.protocol !== "https:") return null;
|
|
1278
|
+
if (parsed.hostname === "github.com" || parsed.hostname.endsWith(".githubusercontent.com")) return u;
|
|
1279
|
+
return null;
|
|
1280
|
+
} catch {
|
|
1281
|
+
return null;
|
|
1282
|
+
}
|
|
1283
|
+
}).filter(Boolean).slice(0, 8);
|
|
1284
|
+
}
|
|
1117
1285
|
function officialLinks({ npm, github, homepage }) {
|
|
1118
1286
|
const links = [];
|
|
1119
1287
|
if (github) links.push(["GitHub", `https://github.com/${github}`]);
|
|
@@ -1234,14 +1402,14 @@ function MarketTab({ notify, market, onMutation }) {
|
|
|
1234
1402
|
const [busyId, setBusyId] = useState(null);
|
|
1235
1403
|
const [qInput, setQInput] = useState(query.query);
|
|
1236
1404
|
const debounceRef = useRef(null);
|
|
1237
|
-
const items = data && data.items || [];
|
|
1405
|
+
const items = sortMergedItems2(data && data.items || []);
|
|
1238
1406
|
const total = data && data.total || 0;
|
|
1239
1407
|
const limit = data && data.limit || MARKET_PAGE_SIZE2;
|
|
1240
1408
|
const offset = data && data.offset || 0;
|
|
1241
1409
|
const page = total > 0 ? Math.floor(offset / limit) + 1 : 1;
|
|
1242
1410
|
const pages = total > 0 ? Math.max(1, Math.ceil(total / limit)) : 1;
|
|
1243
1411
|
const counts = data && data.categoryCounts || {};
|
|
1244
|
-
const notice = data ?
|
|
1412
|
+
const notice = data ? marketNotice2(data.registryState, data.community) : null;
|
|
1245
1413
|
const onSearchInput = (value) => {
|
|
1246
1414
|
setQInput(value);
|
|
1247
1415
|
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
@@ -1262,7 +1430,18 @@ function MarketTab({ notify, market, onMutation }) {
|
|
|
1262
1430
|
installDone(res);
|
|
1263
1431
|
await (onMutation ? onMutation() : reload(false));
|
|
1264
1432
|
} catch (e) {
|
|
1265
|
-
if (e && e.
|
|
1433
|
+
if (e && e.guard) {
|
|
1434
|
+
notify({
|
|
1435
|
+
kind: "err",
|
|
1436
|
+
text: [
|
|
1437
|
+
lookup("guard.blocked"),
|
|
1438
|
+
`${lookup("guard.compstatus")}: ${e.guard.compensation?.status || "\u2014"}\uFF08${e.guard.compensation?.note || ""}\uFF09`,
|
|
1439
|
+
e.guard.repairBasis ? `${lookup("guard.repairbasis")}: ${e.guard.repairBasis}` : null,
|
|
1440
|
+
lookup("guard.noforce"),
|
|
1441
|
+
e.guard.restartSafe ? lookup("guard.restartsafenow") : lookup("guard.restartunsafe")
|
|
1442
|
+
].filter(Boolean).join(" | ")
|
|
1443
|
+
});
|
|
1444
|
+
} else if (e && e.issue) {
|
|
1266
1445
|
setCompatConfirm({ it, version, issue: e.issue });
|
|
1267
1446
|
} else {
|
|
1268
1447
|
notify({ kind: "err", text: lookup("failed.install", { err: e && e.message || e }) });
|
|
@@ -1316,6 +1495,8 @@ function MarketTab({ notify, market, onMutation }) {
|
|
|
1316
1495
|
{ className: notice.key === "notice.unavailable" ? "dshm-err" : "dshm-hint" },
|
|
1317
1496
|
lookup(notice.key, { count: notice.count })
|
|
1318
1497
|
) : null,
|
|
1498
|
+
notice && notice.communityFallback ? h("div", { className: "dshm-hint" }, lookup("community.fallback")) : null,
|
|
1499
|
+
notice && notice.communityStale ? h("div", { className: "dshm-hint" }, lookup("community.stale")) : null,
|
|
1319
1500
|
total > 200 ? h("div", { className: "dshm-hint" }, lookup("market.perf")) : null,
|
|
1320
1501
|
h(
|
|
1321
1502
|
"div",
|
|
@@ -1331,7 +1512,8 @@ function MarketTab({ notify, market, onMutation }) {
|
|
|
1331
1512
|
h(
|
|
1332
1513
|
"div",
|
|
1333
1514
|
{ className: "dshm-chips" },
|
|
1334
|
-
h("button", { className: `dshm-chip${query.category === null ? " on" : ""}`, onClick: () => updateQuery({ category: null, offset: 0 }) }, lookup("cat.all")),
|
|
1515
|
+
h("button", { className: `dshm-chip${query.category === null ? " on" : ""}`, onClick: () => updateQuery({ category: null, primaryOnly: false, offset: 0 }) }, lookup("cat.all")),
|
|
1516
|
+
h("button", { className: `dshm-chip${query.primaryOnly === true ? " on" : ""}`, onClick: () => updateQuery({ primaryOnly: query.primaryOnly !== true, offset: 0 }) }, lookup("cat.primaryonly")),
|
|
1335
1517
|
CATEGORIES2.map((key) => {
|
|
1336
1518
|
const n = typeof counts[key] === "number" ? counts[key] : 0;
|
|
1337
1519
|
return h(
|
|
@@ -1341,6 +1523,31 @@ function MarketTab({ notify, market, onMutation }) {
|
|
|
1341
1523
|
);
|
|
1342
1524
|
})
|
|
1343
1525
|
),
|
|
1526
|
+
(() => {
|
|
1527
|
+
const groups = splitCategories2(counts);
|
|
1528
|
+
if (!groups.community.length && !groups.unknown.length) return null;
|
|
1529
|
+
const chip = (c) => h(
|
|
1530
|
+
"button",
|
|
1531
|
+
{ key: c.id, className: `dshm-chip${query.category === c.id ? " on" : ""}`, onClick: () => updateQuery({ category: query.category === c.id ? null : c.id, offset: 0 }) },
|
|
1532
|
+
`${c.label}${c.count ? ` ${c.count}` : ""}`
|
|
1533
|
+
);
|
|
1534
|
+
return h(
|
|
1535
|
+
React.Fragment,
|
|
1536
|
+
null,
|
|
1537
|
+
groups.community.length ? h(
|
|
1538
|
+
"div",
|
|
1539
|
+
{ className: "dshm-chips" },
|
|
1540
|
+
h("span", { className: "dshm-hint" }, lookup("community.group")),
|
|
1541
|
+
...groups.community.map(chip)
|
|
1542
|
+
) : null,
|
|
1543
|
+
groups.unknown.length ? h(
|
|
1544
|
+
"div",
|
|
1545
|
+
{ className: "dshm-chips" },
|
|
1546
|
+
h("span", { className: "dshm-hint" }, lookup("community.newgroup")),
|
|
1547
|
+
...groups.unknown.map(chip)
|
|
1548
|
+
) : null
|
|
1549
|
+
);
|
|
1550
|
+
})(),
|
|
1344
1551
|
busyId ? h(ProgressLine, { key: "prog" }) : null,
|
|
1345
1552
|
loading && !data ? h("div", { className: "dshm-empty" }, lookup("market.loading"), Spin()) : error ? h("div", { className: "dshm-err" }, lookup("failed.load", { err: error })) : items.length === 0 ? h("div", { className: "dshm-empty" }, lookup("market.empty")) : h(
|
|
1346
1553
|
React.Fragment,
|
|
@@ -1355,6 +1562,7 @@ function MarketTab({ notify, market, onMutation }) {
|
|
|
1355
1562
|
badges: [
|
|
1356
1563
|
it.outdated ? h("span", { className: "dshm-badge warn", key: "u" }, lookup("badge.update")) : null,
|
|
1357
1564
|
it.installed ? h("span", { className: "dshm-badge", key: "i" }, lookup("badge.installed")) : null,
|
|
1565
|
+
it.community === true ? h("span", { className: "dshm-badge info", key: "c" }, lookup("badge.community")) : null,
|
|
1358
1566
|
h("span", { className: "dshm-badge info", key: "s" }, it.source === "npm" ? "npm" : "github")
|
|
1359
1567
|
],
|
|
1360
1568
|
desc: it.description,
|
|
@@ -1372,7 +1580,13 @@ function MarketTab({ notify, market, onMutation }) {
|
|
|
1372
1580
|
[lookup("detail.latest"), it.latestVersion ? `v${it.latestVersion}` : it.latestTag ? it.latestTag : it.latestSha ? it.latestSha : it.latestError || "\u2014"],
|
|
1373
1581
|
[lookup("detail.installed"), it.installedPkg ? `${it.installedPkg} v${it.installedVersion || "?"}` : lookup("installed.none")],
|
|
1374
1582
|
[lookup("detail.tags"), (it.tags || []).join(", ") || "\u2014"],
|
|
1375
|
-
it.latestError ? [lookup("version.failed"), it.latestError] : null
|
|
1583
|
+
it.latestError ? [lookup("version.failed"), it.latestError] : null,
|
|
1584
|
+
it.community === true ? [lookup("detail.capabilities"), Array.isArray(it.capabilities) && it.capabilities.length ? `${it.capabilities.join(", ")}${Array.isArray(it.capabilityRedLines) && it.capabilityRedLines.length ? `\uFF1B${lookup("detail.redlines")}: ${it.capabilityRedLines.join("; ")}` : ""}` : lookup("detail.capabilities.unscanned")] : null,
|
|
1585
|
+
it.community === true && safeScreenshots(it).length ? [lookup("detail.screenshots"), h(
|
|
1586
|
+
"div",
|
|
1587
|
+
{ className: "dshm-chips" },
|
|
1588
|
+
...safeScreenshots(it).map((src) => h("img", { key: src, src, alt: "", loading: "lazy", referrerPolicy: "no-referrer", style: { maxWidth: "220px", maxHeight: "140px", borderRadius: "6px", border: "1px solid rgba(127,127,127,.25)" } }))
|
|
1589
|
+
)] : null
|
|
1376
1590
|
]),
|
|
1377
1591
|
actions: [
|
|
1378
1592
|
it.installed ? h("span", { className: "dshm-hint", key: "hint" }, lookup("manage.hint")) : h(
|
|
@@ -1516,7 +1730,20 @@ function InstalledTab({ notify, installed, onMutation }) {
|
|
|
1516
1730
|
});
|
|
1517
1731
|
await (onMutation ? onMutation() : reload());
|
|
1518
1732
|
} catch (e) {
|
|
1519
|
-
|
|
1733
|
+
if (e && e.guard) {
|
|
1734
|
+
notify({
|
|
1735
|
+
kind: "err",
|
|
1736
|
+
text: [
|
|
1737
|
+
lookup("guard.blocked"),
|
|
1738
|
+
`${lookup("guard.compstatus")}: ${e.guard.compensation?.status || "\u2014"}\uFF08${e.guard.compensation?.note || ""}\uFF09`,
|
|
1739
|
+
e.guard.repairBasis ? `${lookup("guard.repairbasis")}: ${e.guard.repairBasis}` : null,
|
|
1740
|
+
lookup("guard.noforce"),
|
|
1741
|
+
e.guard.restartSafe ? lookup("guard.restartsafenow") : lookup("guard.restartunsafe")
|
|
1742
|
+
].filter(Boolean).join(" | ")
|
|
1743
|
+
});
|
|
1744
|
+
} else {
|
|
1745
|
+
notify({ kind: "err", text: lookup("failed.upgrade", { err: e && e.message || e }) });
|
|
1746
|
+
}
|
|
1520
1747
|
} finally {
|
|
1521
1748
|
setBusyPkg(null);
|
|
1522
1749
|
}
|
|
@@ -1548,15 +1775,16 @@ function InstalledTab({ notify, installed, onMutation }) {
|
|
|
1548
1775
|
}),
|
|
1549
1776
|
badges: [
|
|
1550
1777
|
it.outdated ? h("span", { className: "dshm-badge warn", key: "u" }, `\u2B06 ${vm.latestLabel}`.trim()) : null,
|
|
1551
|
-
it.registryId ? h("span", { className: "dshm-badge", key: "r" }, lookup("badge.market")) : h("span", { className: "dshm-badge info", key: "r" }, lookup("badge.nonmarket"))
|
|
1778
|
+
it.community === true ? h("span", { className: "dshm-badge info", key: "r" }, lookup("badge.community")) : it.registryId ? h("span", { className: "dshm-badge", key: "r" }, lookup("badge.market")) : h("span", { className: "dshm-badge info", key: "r" }, lookup("badge.nonmarket"))
|
|
1552
1779
|
],
|
|
1553
1780
|
desc: it.description || "\uFF08\u65E0\u63CF\u8FF0\uFF09",
|
|
1554
1781
|
sub: [
|
|
1555
1782
|
h(PhaseDot, { key: "dot", vm: tvm }),
|
|
1556
1783
|
vm.phaseKey ? lookup(vm.phaseKey) : lookup(vm.enabledLabelKey),
|
|
1557
1784
|
`v${it.version || "?"}`,
|
|
1558
|
-
vm.sourceLabelKey ? lookup(vm.sourceLabelKey) : it.source
|
|
1559
|
-
|
|
1785
|
+
vm.sourceLabelKey ? lookup(vm.sourceLabelKey) : it.source,
|
|
1786
|
+
vm.latestIssue ? lookup("installed.check.incomplete") : null
|
|
1787
|
+
].filter(Boolean).map((part, i) => i === 0 ? part : [" \xB7 ", part]).flat(),
|
|
1560
1788
|
links: h(LinksRow, {
|
|
1561
1789
|
npm: it.source === "npm" ? it.pkg : null,
|
|
1562
1790
|
github: vm.githubRepo
|
|
@@ -1569,6 +1797,7 @@ function InstalledTab({ notify, installed, onMutation }) {
|
|
|
1569
1797
|
[lookup("detail.latest"), vm.latestLabelDetail],
|
|
1570
1798
|
[lookup("detail.listed"), it.registryId || lookup("detail.listed.no")],
|
|
1571
1799
|
[lookup("detail.path"), it.path],
|
|
1800
|
+
vm.latestIssue ? [lookup("installed.check.incomplete"), vm.latestIssue.note] : null,
|
|
1572
1801
|
vm.guard.warnKey ? [lookup("detail.note"), lookup(vm.guard.warnKey, vm.guard.warnParams)] : null
|
|
1573
1802
|
]),
|
|
1574
1803
|
actions: [
|
|
@@ -1700,9 +1929,27 @@ function SettingsTab({ notify, onRegistryChanged }) {
|
|
|
1700
1929
|
};
|
|
1701
1930
|
const snap = cfgData || {};
|
|
1702
1931
|
const state = snap.registryState || (reg.data ? reg.data.registryState : null) || null;
|
|
1932
|
+
const communitySummary = reg.data && reg.data.community && typeof reg.data.community === "object" ? reg.data.community : null;
|
|
1933
|
+
const communityRows = communitySummary && (communitySummary.status === "ready" || communitySummary.status === "stale") ? [
|
|
1934
|
+
[lookup("settings.community.status"), communitySummary.status === "stale" ? lookup("community.stale") : lookup("settings.status.ready")],
|
|
1935
|
+
[lookup("settings.community.version"), communitySummary.version || "\u2014"],
|
|
1936
|
+
[lookup("settings.community.route"), communitySummary.route || "\u2014"],
|
|
1937
|
+
[lookup("settings.community.accepted"), `${communitySummary.acceptedCount} / ${communitySummary.upstreamCount ?? "\u2014"}`],
|
|
1938
|
+
[lookup("settings.community.displaced"), String(communitySummary.displaced ?? 0)]
|
|
1939
|
+
] : [[lookup("settings.community.status"), lookup("settings.community.none")]];
|
|
1703
1940
|
return h(
|
|
1704
1941
|
React.Fragment,
|
|
1705
1942
|
null,
|
|
1943
|
+
Section(
|
|
1944
|
+
lookup("settings.community"),
|
|
1945
|
+
...communityRows.map(([k, v]) => h(
|
|
1946
|
+
"div",
|
|
1947
|
+
{ key: k, className: "dshm-row", style: { justifyContent: "space-between" } },
|
|
1948
|
+
h("span", { className: "dshm-hint" }, k),
|
|
1949
|
+
h("span", null, v)
|
|
1950
|
+
)),
|
|
1951
|
+
communitySummary && Array.isArray(communitySummary.errors) && communitySummary.errors.length ? h("div", { className: "dshm-err" }, communitySummary.errors.join("\uFF1B")) : null
|
|
1952
|
+
),
|
|
1706
1953
|
Section(
|
|
1707
1954
|
lookup("settings.registry"),
|
|
1708
1955
|
h(
|
|
@@ -1810,7 +2057,20 @@ function SettingsTab({ notify, onRegistryChanged }) {
|
|
|
1810
2057
|
notify({ kind: "ok", text: lookup("self.upgraded", { v: res.version }), needsRestart: true });
|
|
1811
2058
|
await self.reload();
|
|
1812
2059
|
} catch (e) {
|
|
1813
|
-
|
|
2060
|
+
if (e && e.guard) {
|
|
2061
|
+
notify({
|
|
2062
|
+
kind: "err",
|
|
2063
|
+
text: [
|
|
2064
|
+
lookup("guard.blocked"),
|
|
2065
|
+
`${lookup("guard.compstatus")}: ${e.guard.compensation?.status || "\u2014"}\uFF08${e.guard.compensation?.note || ""}\uFF09`,
|
|
2066
|
+
e.guard.repairBasis ? `${lookup("guard.repairbasis")}: ${e.guard.repairBasis}` : null,
|
|
2067
|
+
lookup("guard.noforce"),
|
|
2068
|
+
e.guard.restartSafe ? lookup("guard.restartsafenow") : lookup("guard.restartunsafe")
|
|
2069
|
+
].filter(Boolean).join(" | ")
|
|
2070
|
+
});
|
|
2071
|
+
} else {
|
|
2072
|
+
notify({ kind: "err", text: lookup("failed.selfupdate", { err: e && e.message || e }) });
|
|
2073
|
+
}
|
|
1814
2074
|
} finally {
|
|
1815
2075
|
setUpgrading(false);
|
|
1816
2076
|
}
|
|
@@ -2054,13 +2314,17 @@ function registerSlot(slots, options, component) {
|
|
|
2054
2314
|
}
|
|
2055
2315
|
function ToolCardRow({ it, onInstalled }) {
|
|
2056
2316
|
const [busy, setBusy] = useState(false);
|
|
2317
|
+
const [guardNote, setGuardNote] = useState(null);
|
|
2057
2318
|
const install = async (e) => {
|
|
2058
2319
|
e.stopPropagation();
|
|
2059
2320
|
setBusy(true);
|
|
2060
2321
|
try {
|
|
2061
2322
|
const res = await api("install", { id: it.id });
|
|
2062
2323
|
onInstalled({ ...it, installed: true, installedPkg: res.pkg, installedVersion: res.version });
|
|
2063
|
-
} catch {
|
|
2324
|
+
} catch (e2) {
|
|
2325
|
+
if (e2 && e2.guard) {
|
|
2326
|
+
setGuardNote(`${lookup("guard.blocked")} \xB7 ${e2.guard.compensation?.status || "\u2014"} \xB7 ${lookup("guard.noforce")}`);
|
|
2327
|
+
}
|
|
2064
2328
|
} finally {
|
|
2065
2329
|
setBusy(false);
|
|
2066
2330
|
}
|
|
@@ -2080,6 +2344,7 @@ function ToolCardRow({ it, onInstalled }) {
|
|
|
2080
2344
|
it.installed ? h("span", { className: "dshm-badge" }, "\u5DF2\u5B89\u88C5") : null
|
|
2081
2345
|
),
|
|
2082
2346
|
h("div", { className: "dshm-desc" }, it.description),
|
|
2347
|
+
guardNote ? h("div", { className: "dshm-err" }, guardNote) : null,
|
|
2083
2348
|
h("div", { className: "dshm-sub" }, `${it.id} \xB7 ${(it.tags || []).join("\u3001") || it.category}`),
|
|
2084
2349
|
h(LinksRow, { npm: it.npm, github: it.github, homepage: it.homepage }),
|
|
2085
2350
|
h(
|