@dsh-workbench/core 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -3
- package/bin/dsh-workbench +38 -6
- package/client.js +669 -305
- package/dist/client/client.body.js +669 -305
- package/dist/client/index.js +669 -305
- package/dist/host/index.js +445 -37
- package/dist/types/app/layouts/market/discover-sources-dialog.d.ts +4 -0
- package/dist/types/app/layouts/market/discover-states.d.ts +3 -0
- package/dist/types/app/layouts/market/use-add-module.d.ts +0 -1
- package/dist/types/app/layouts/market/use-discover.d.ts +1 -0
- package/dist/types/app/layouts/rightbar/MarketView.d.ts +3 -1
- package/dist/types/app/layouts/rightbar/market-names.d.ts +8 -0
- package/dist/types/app/layouts/rightbar/market-row-types.d.ts +11 -3
- package/dist/types/app/layouts/rightbar/market-rows.d.ts +6 -4
- package/dist/types/app/layouts/rightbar/market-view-text.d.ts +4 -3
- package/dist/types/app/units/unit-titles.d.ts +3 -0
- package/dist/types/kernel/contract/bundle-install.d.ts +1 -1
- package/dist/types/kernel/contract/market-index.d.ts +1 -1
- package/dist/types/modules/panels/model/diy-tools.d.ts +1 -1
- package/dist/types/modules/panels/model/market-dispatch.d.ts +8 -0
- package/dist/types/modules/panels/model/market-follow-up.d.ts +16 -0
- package/dist/types/modules/panels/model/market-sources-act.d.ts +2 -0
- package/dist/types/modules/panels/model/market-types.d.ts +5 -0
- package/dist/types/modules/panels/model/market.d.ts +2 -0
- package/dist/types/modules/panels/model/publish-preview-routes.d.ts +1 -1
- package/dist/types/shared/api/host/diy-publish-preview.d.ts +11 -0
- package/dist/types/shared/api/host/follow-up-dismiss.d.ts +2 -0
- package/dist/types/shared/api/host/migrate-workbench.d.ts +20 -0
- package/dist/types/shared/api/host/migration-follow-up.d.ts +12 -0
- package/dist/types/shared/hooks/market-queries.d.ts +3 -2
- package/dist/types/shared/hooks/resource-view.d.ts +14 -0
- package/dist/types/shared/hooks/use-api-resource.d.ts +3 -7
- package/package.json +3 -3
- package/scripts/seed-profile.sh +9 -7
- package/scripts/share-data-root.mjs +272 -64
- package/skills/workbench-module-diy/FAMILY.md +1 -1
- package/skills/workbench-module-diy/REVIEW.md +2 -2
- package/skills/workbench-module-diy/SKILL.md +1 -0
- package/skills/workbench-module-diy/TOOLS.md +1 -1
- package/skills/workbench-module-diy/WIRING.md +3 -1
- package/skills/workbench-module-diy/WRITES.md +1 -1
package/dist/host/index.js
CHANGED
|
@@ -5,8 +5,9 @@ import { createHash, randomUUID } from "node:crypto";
|
|
|
5
5
|
import fs, { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
6
6
|
import { createRequire } from "node:module";
|
|
7
7
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
-
import { deflateSync, inflateSync } from "node:zlib";
|
|
9
8
|
import writeFileAtomic from "write-file-atomic";
|
|
9
|
+
import { deflateSync, inflateSync } from "node:zlib";
|
|
10
|
+
import { execa } from "execa";
|
|
10
11
|
//#region \0rolldown/runtime.js
|
|
11
12
|
var __create = Object.create;
|
|
12
13
|
var __defProp = Object.defineProperty;
|
|
@@ -86,6 +87,14 @@ function encodeRef(ref) {
|
|
|
86
87
|
//#endregion
|
|
87
88
|
//#region ../shared/dist/contract/unit.js
|
|
88
89
|
/**
|
|
90
|
+
* 外壳替模块名合成的词表键:模块自己不必写名字键,名字直接从清单里的 title 注册进来。
|
|
91
|
+
* @param unit 单元 id。
|
|
92
|
+
* @returns 该单元名字在词表里的键。
|
|
93
|
+
*/
|
|
94
|
+
function unitTitleKey(unit) {
|
|
95
|
+
return `dsh-workbench.unit.${unit}.title`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
89
98
|
* 模块声明的全部环境需要(没写就是空表)。
|
|
90
99
|
* @param manifest 模块清单。
|
|
91
100
|
* @returns need 列表。
|
|
@@ -382,13 +391,14 @@ function boardSituation(probe, workshop) {
|
|
|
382
391
|
/**
|
|
383
392
|
* 外壳愿意认的协议版本;不在表里的模块当场被拒,不猜语义。
|
|
384
393
|
*/
|
|
385
|
-
var SUPPORTED_API_VERSIONS = [
|
|
394
|
+
var SUPPORTED_API_VERSIONS = [3];
|
|
386
395
|
/**
|
|
387
396
|
* 协议认得的全部键;写了别的键这份清单会被拒(`protocol` 判据与运行时同一套),拼错当场报出来。
|
|
388
397
|
*/
|
|
389
398
|
var DECLARATION_KEYS = [
|
|
390
399
|
"apiVersion",
|
|
391
400
|
"unit",
|
|
401
|
+
"title",
|
|
392
402
|
"card",
|
|
393
403
|
"tools",
|
|
394
404
|
"host",
|
|
@@ -400,11 +410,13 @@ var DECLARATION_KEYS = [
|
|
|
400
410
|
var DECLARATION_REQUIRED_KEYS = [
|
|
401
411
|
"apiVersion",
|
|
402
412
|
"unit",
|
|
413
|
+
"title",
|
|
403
414
|
"card",
|
|
404
415
|
"tools",
|
|
405
416
|
"host"
|
|
406
417
|
];
|
|
407
|
-
var CARD_KEYS = ["
|
|
418
|
+
var CARD_KEYS = ["order"];
|
|
419
|
+
var TITLE_KEYS = ["zh", "en"];
|
|
408
420
|
var TOOL_KEYS = [
|
|
409
421
|
"name",
|
|
410
422
|
"writes",
|
|
@@ -418,6 +430,16 @@ function text$2(value) {
|
|
|
418
430
|
function isRecord(value) {
|
|
419
431
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
420
432
|
}
|
|
433
|
+
/**
|
|
434
|
+
* 读一份声明里的协议版本;不是对象或 apiVersion 不是整数时给 undefined。
|
|
435
|
+
* @param raw 清单里 dsh.workbench 那段原始值。
|
|
436
|
+
* @returns 声明声明的协议版本,读不出来时 undefined。
|
|
437
|
+
*/
|
|
438
|
+
function declarationApiVersionOf(raw) {
|
|
439
|
+
if (!isRecord(raw)) return void 0;
|
|
440
|
+
const version = raw.apiVersion;
|
|
441
|
+
return Number.isInteger(version) ? version : void 0;
|
|
442
|
+
}
|
|
421
443
|
function outsideKeys(value, allowed) {
|
|
422
444
|
return Object.keys(value).filter((key) => !allowed.includes(key));
|
|
423
445
|
}
|
|
@@ -437,22 +459,30 @@ function stringArrayProblems(at, value) {
|
|
|
437
459
|
function declarationProblemsOf(subject, raw) {
|
|
438
460
|
if (!isRecord(raw)) return [`${subject}: dsh.workbench 不是一个对象 —— ${JSON.stringify(raw)}`];
|
|
439
461
|
const version = raw.apiVersion;
|
|
440
|
-
if (version === void 0) return [`${subject}: dsh.workbench 没有 apiVersion —— 协议从
|
|
462
|
+
if (version === void 0) return [`${subject}: dsh.workbench 没有 apiVersion —— 协议从 v3 起,写 \`"apiVersion": 3\`。缺它 = 外壳不认这个模块`];
|
|
441
463
|
if (!Number.isInteger(version) || !SUPPORTED_API_VERSIONS.includes(version)) {
|
|
442
|
-
const hint = version ===
|
|
464
|
+
const hint = version === 2 ? " —— v3 把卡片标题挪成了顶层 `title`(`{ \"zh\": \"…\", \"en\": \"…\" }` 字面量):把 `card.titleKey` 删掉、在顶层写 title,再把 apiVersion 改成 3" : "";
|
|
443
465
|
return [`${subject}: dsh.workbench.apiVersion 是 ${JSON.stringify(version)},这里只认 ${SUPPORTED_API_VERSIONS.join(" / ")}(要整数)${hint}`];
|
|
444
466
|
}
|
|
445
467
|
const problems = [];
|
|
446
468
|
const unknown = outsideKeys(raw, DECLARATION_KEYS);
|
|
447
|
-
if (unknown.length > 0) problems.push(`${subject}: dsh.workbench 里有协议
|
|
469
|
+
if (unknown.length > 0) problems.push(`${subject}: dsh.workbench 里有协议 v3 不认识的键 ${listOf(unknown)} —— 只有 ${listOf(DECLARATION_KEYS)}。(协议外的键会让这份清单被拒:那句声明等于没写)`);
|
|
448
470
|
for (const key of DECLARATION_REQUIRED_KEYS) if (raw[key] === void 0) problems.push(`${subject}: dsh.workbench 缺 ${key}` + (key === "card" ? "(这个模块没有卡片就写 `\"card\": null`)" : ""));
|
|
471
|
+
const title = raw.title;
|
|
472
|
+
if (title !== void 0) {
|
|
473
|
+
if (!isRecord(title)) problems.push(`${subject}: dsh.workbench.title 要是对象(中英各一份),现在是 ${JSON.stringify(title)}`);
|
|
474
|
+
else {
|
|
475
|
+
const extra = outsideKeys(title, TITLE_KEYS);
|
|
476
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.title 里有不认的键 ${listOf(extra)} —— title 只有 ${listOf(TITLE_KEYS)}`);
|
|
477
|
+
for (const language of TITLE_KEYS) if (text$2(title[language]) === "") problems.push(`${subject}: dsh.workbench.title.${language} 要是非空字符串(市场和面板里显示的名字)`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
449
480
|
const card = raw.card;
|
|
450
481
|
if (card !== void 0 && card !== null) {
|
|
451
482
|
if (!isRecord(card)) problems.push(`${subject}: dsh.workbench.card 要么是对象、要么是 null,现在是 ${JSON.stringify(card)}`);
|
|
452
483
|
else {
|
|
453
484
|
const extra = outsideKeys(card, CARD_KEYS);
|
|
454
|
-
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.card 里有不认的键 ${listOf(extra)} —— card 只有 ${listOf(CARD_KEYS)}
|
|
455
|
-
if (text$2(card.titleKey) === "") problems.push(`${subject}: dsh.workbench.card.titleKey 要是非空字符串(面板那一格的文案键)`);
|
|
485
|
+
if (extra.length > 0) problems.push(`${subject}: dsh.workbench.card 里有不认的键 ${listOf(extra)} —— card 只有 ${listOf(CARD_KEYS)}(名字写在顶层的 title 里;卡片默认显不显示由运行期的面板配置决定,清单里没有这一位)`);
|
|
456
486
|
if (typeof card.order !== "number" || !Number.isFinite(card.order)) problems.push(`${subject}: dsh.workbench.card.order 要是数字,现在是 ${JSON.stringify(card.order)}`);
|
|
457
487
|
}
|
|
458
488
|
}
|
|
@@ -516,13 +546,18 @@ function readDeclaration(subject, raw) {
|
|
|
516
546
|
warnings: needsRead.warnings
|
|
517
547
|
};
|
|
518
548
|
const card = declaration.card;
|
|
549
|
+
const id = text$2(declaration.unit);
|
|
519
550
|
return {
|
|
520
551
|
declaration,
|
|
521
552
|
problems: [],
|
|
522
553
|
manifest: {
|
|
523
|
-
id
|
|
554
|
+
id,
|
|
555
|
+
title: {
|
|
556
|
+
zh: text$2(declaration.title.zh),
|
|
557
|
+
en: text$2(declaration.title.en)
|
|
558
|
+
},
|
|
524
559
|
card: card === null ? null : {
|
|
525
|
-
titleKey:
|
|
560
|
+
titleKey: unitTitleKey(id),
|
|
526
561
|
order: card.order
|
|
527
562
|
},
|
|
528
563
|
tools: declaration.tools.map((tool) => ({
|
|
@@ -1192,7 +1227,9 @@ var PROVISION_ACTIONS = [
|
|
|
1192
1227
|
"update-dependency",
|
|
1193
1228
|
"update-plugin",
|
|
1194
1229
|
"uninstall-plugin",
|
|
1195
|
-
"update-workbench"
|
|
1230
|
+
"update-workbench",
|
|
1231
|
+
"migrate-workbench",
|
|
1232
|
+
"dismiss-followup"
|
|
1196
1233
|
];
|
|
1197
1234
|
var DEPENDENCY_ACTIONS = ["update-dependency"];
|
|
1198
1235
|
function isDependencyAction(action) {
|
|
@@ -1203,7 +1240,8 @@ function provisionTargetOf(action) {
|
|
|
1203
1240
|
if (action === "install-bundle" || action === "install-version") return "spec";
|
|
1204
1241
|
if (action === "remove-bundle") return "name";
|
|
1205
1242
|
if (action === "update-plugin" || action === "uninstall-plugin") return "name";
|
|
1206
|
-
if (action === "update-workbench") return "name";
|
|
1243
|
+
if (action === "update-workbench" || action === "migrate-workbench") return "name";
|
|
1244
|
+
if (action === "dismiss-followup") return "id";
|
|
1207
1245
|
if (action === "cancel-install") return "requestId";
|
|
1208
1246
|
return "unit";
|
|
1209
1247
|
}
|
|
@@ -1239,10 +1277,14 @@ function requestOf$1(action, value) {
|
|
|
1239
1277
|
action,
|
|
1240
1278
|
name: value
|
|
1241
1279
|
};
|
|
1242
|
-
if (action === "update-workbench") return {
|
|
1280
|
+
if (action === "update-workbench" || action === "migrate-workbench") return {
|
|
1243
1281
|
action,
|
|
1244
1282
|
name: value
|
|
1245
1283
|
};
|
|
1284
|
+
if (action === "dismiss-followup") return {
|
|
1285
|
+
action,
|
|
1286
|
+
id: value
|
|
1287
|
+
};
|
|
1246
1288
|
if (action === "cancel-install") return {
|
|
1247
1289
|
action,
|
|
1248
1290
|
requestId: value
|
|
@@ -3990,6 +4032,31 @@ function refusalReason() {
|
|
|
3990
4032
|
return "这个包既不是工作台的模块,也不是 opencli 的插件,装了也用不上";
|
|
3991
4033
|
}
|
|
3992
4034
|
//#endregion
|
|
4035
|
+
//#region ../shared/dist/host/plugin-source.js
|
|
4036
|
+
function envValue(env, name) {
|
|
4037
|
+
const value = env[name]?.trim();
|
|
4038
|
+
return value === void 0 || value === "" ? { ok: false } : {
|
|
4039
|
+
ok: true,
|
|
4040
|
+
value
|
|
4041
|
+
};
|
|
4042
|
+
}
|
|
4043
|
+
function npmRegistryOf(source, env) {
|
|
4044
|
+
const name = source.registryEnv ?? "";
|
|
4045
|
+
if (name !== "") {
|
|
4046
|
+
const fromEnv = envValue(env, name);
|
|
4047
|
+
if (fromEnv.ok) return fromEnv;
|
|
4048
|
+
}
|
|
4049
|
+
const fallback = source.registryDefault?.trim();
|
|
4050
|
+
if (fallback === void 0 || fallback === "") return {
|
|
4051
|
+
ok: false,
|
|
4052
|
+
env: name
|
|
4053
|
+
};
|
|
4054
|
+
return {
|
|
4055
|
+
ok: true,
|
|
4056
|
+
value: fallback
|
|
4057
|
+
};
|
|
4058
|
+
}
|
|
4059
|
+
//#endregion
|
|
3993
4060
|
//#region ../shared/dist/host/supply-index.js
|
|
3994
4061
|
function text$1(value) {
|
|
3995
4062
|
return value === void 0 ? "" : value.trim();
|
|
@@ -4015,24 +4082,28 @@ function packageOf(need) {
|
|
|
4015
4082
|
function keyOf(kind, pkg) {
|
|
4016
4083
|
return `${kind}:${pkg}`;
|
|
4017
4084
|
}
|
|
4018
|
-
function
|
|
4085
|
+
function registryAddressOf(source, env) {
|
|
4086
|
+
const resolved = npmRegistryOf(source, env);
|
|
4087
|
+
return resolved.ok ? resolved.value : void 0;
|
|
4088
|
+
}
|
|
4089
|
+
function sourceCompatible(left, right, env) {
|
|
4019
4090
|
if (left.kind !== right.kind) return false;
|
|
4020
4091
|
if (left.kind === "npm" && right.kind === "npm") {
|
|
4021
4092
|
if (text$1(left.package) !== "" && text$1(right.package) !== "" && text$1(left.package) !== text$1(right.package)) return false;
|
|
4022
|
-
|
|
4023
|
-
const
|
|
4024
|
-
|
|
4025
|
-
return
|
|
4093
|
+
const l = registryAddressOf(left, env);
|
|
4094
|
+
const r = registryAddressOf(right, env);
|
|
4095
|
+
if (l !== void 0 && r !== void 0) return l === r;
|
|
4096
|
+
return text$1(left.registryEnv) === text$1(right.registryEnv);
|
|
4026
4097
|
}
|
|
4027
4098
|
if (left.kind === "git" && right.kind === "git") return text$1(left.url) === text$1(right.url);
|
|
4028
4099
|
if (left.kind === "local" && right.kind === "local") return text$1(left.env) === text$1(right.env) && text$1(left.path) === text$1(right.path);
|
|
4029
4100
|
return false;
|
|
4030
4101
|
}
|
|
4031
|
-
function sourcesCompatible(left, right) {
|
|
4102
|
+
function sourcesCompatible(left, right, env) {
|
|
4032
4103
|
if (left.length !== right.length) return false;
|
|
4033
4104
|
return left.every((source, index) => {
|
|
4034
4105
|
const other = right[index];
|
|
4035
|
-
return other !== void 0 && sourceCompatible(source, other);
|
|
4106
|
+
return other !== void 0 && sourceCompatible(source, other, env);
|
|
4036
4107
|
});
|
|
4037
4108
|
}
|
|
4038
4109
|
function mergedSource(left, right) {
|
|
@@ -4047,13 +4118,13 @@ function mergedSource(left, right) {
|
|
|
4047
4118
|
}
|
|
4048
4119
|
return left;
|
|
4049
4120
|
}
|
|
4050
|
-
function mergeSources(entry, sources) {
|
|
4121
|
+
function mergeSources(entry, sources, env) {
|
|
4051
4122
|
if (!entry.declared) {
|
|
4052
4123
|
entry.declared = true;
|
|
4053
4124
|
entry.sources = [...sources];
|
|
4054
4125
|
return true;
|
|
4055
4126
|
}
|
|
4056
|
-
if (!sourcesCompatible(entry.sources, sources)) {
|
|
4127
|
+
if (!sourcesCompatible(entry.sources, sources, env)) {
|
|
4057
4128
|
entry.conflicted = true;
|
|
4058
4129
|
return false;
|
|
4059
4130
|
}
|
|
@@ -4072,7 +4143,8 @@ function addDeclarer(entry, unit, commands) {
|
|
|
4072
4143
|
if (!entry.declarers.includes(unit)) entry.declarers.push(unit);
|
|
4073
4144
|
for (const command of commands) if (!entry.commands.includes(command)) entry.commands.push(command);
|
|
4074
4145
|
}
|
|
4075
|
-
function buildSupplyIndex(declarations) {
|
|
4146
|
+
function buildSupplyIndex(declarations, options = {}) {
|
|
4147
|
+
const env = options.env ?? {};
|
|
4076
4148
|
const entries = /* @__PURE__ */ new Map();
|
|
4077
4149
|
const byName = /* @__PURE__ */ new Map();
|
|
4078
4150
|
const conflicts = [];
|
|
@@ -4103,7 +4175,7 @@ function buildSupplyIndex(declarations) {
|
|
|
4103
4175
|
entry.runtime = need.runtime;
|
|
4104
4176
|
addDeclarer(entry, declaration.id, need.commands ?? []);
|
|
4105
4177
|
} else addDeclarer(entry, declaration.id, []);
|
|
4106
|
-
if (!mergeSources(entry, need.sources ?? [])) conflicts.push({
|
|
4178
|
+
if (!mergeSources(entry, need.sources ?? [], env)) conflicts.push({
|
|
4107
4179
|
kind: "source-mismatch",
|
|
4108
4180
|
key: entry.key,
|
|
4109
4181
|
names: [...entry.names],
|
|
@@ -4477,6 +4549,7 @@ var MARKET_DISCOVER_ROUTE = "panels/market-discover";
|
|
|
4477
4549
|
var MARKET_DOC_ROUTE = "panels/market-doc";
|
|
4478
4550
|
var MARKET_PUBLISH_PREVIEW_ROUTE = "panels/market-publish-preview";
|
|
4479
4551
|
var MARKET_SOURCES_RESOURCE = "market-sources";
|
|
4552
|
+
var MARKET_SOURCES_ROUTE = "panels/market-sources";
|
|
4480
4553
|
//#endregion
|
|
4481
4554
|
//#region ../shared/dist/lib/market-index.js
|
|
4482
4555
|
var BRANCH = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;
|
|
@@ -5010,6 +5083,94 @@ var BUNDLE_REGISTRIES_ROUTE = "bundle-registries";
|
|
|
5010
5083
|
var BUNDLE_INSPECT_ROUTE = "bundle-inspect";
|
|
5011
5084
|
var MODULE_VERSIONS_ROUTE = "module-versions";
|
|
5012
5085
|
//#endregion
|
|
5086
|
+
//#region src/shared/api/host/follow-up-dismiss.ts
|
|
5087
|
+
var DISMISS_FILE = "follow-ups.json";
|
|
5088
|
+
function fileOf$1(runtimeRoot) {
|
|
5089
|
+
return join(runtimeRoot, DISMISS_FILE);
|
|
5090
|
+
}
|
|
5091
|
+
function readDismissed(runtimeRoot) {
|
|
5092
|
+
try {
|
|
5093
|
+
const value = JSON.parse(readFileSync(fileOf$1(runtimeRoot), "utf8"));
|
|
5094
|
+
if (typeof value !== "object" || value === null) return {};
|
|
5095
|
+
const dismissed = value["dismissed"];
|
|
5096
|
+
if (typeof dismissed !== "object" || dismissed === null) return {};
|
|
5097
|
+
return dismissed;
|
|
5098
|
+
} catch {
|
|
5099
|
+
return {};
|
|
5100
|
+
}
|
|
5101
|
+
}
|
|
5102
|
+
function isFollowUpDismissed(runtimeRoot, id) {
|
|
5103
|
+
return Object.prototype.hasOwnProperty.call(readDismissed(runtimeRoot), id);
|
|
5104
|
+
}
|
|
5105
|
+
function dismissFollowUp(runtimeRoot, id) {
|
|
5106
|
+
const file = fileOf$1(runtimeRoot);
|
|
5107
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
5108
|
+
const dismissed = {
|
|
5109
|
+
...readDismissed(runtimeRoot),
|
|
5110
|
+
[id]: { at: (/* @__PURE__ */ new Date()).toISOString() }
|
|
5111
|
+
};
|
|
5112
|
+
writeFileAtomic.sync(file, `${JSON.stringify({ dismissed }, null, 2)}\n`);
|
|
5113
|
+
}
|
|
5114
|
+
//#endregion
|
|
5115
|
+
//#region src/shared/api/host/migration-follow-up.ts
|
|
5116
|
+
var MIGRATION_FOLLOW_UP_ID = "data-root-migration";
|
|
5117
|
+
function hasEntries(dir) {
|
|
5118
|
+
try {
|
|
5119
|
+
return readdirSync(dir).some((name) => name !== ".DS_Store");
|
|
5120
|
+
} catch {
|
|
5121
|
+
return false;
|
|
5122
|
+
}
|
|
5123
|
+
}
|
|
5124
|
+
function legacyDataIn(root) {
|
|
5125
|
+
return existsSync(join(root, "storages", "workspace.json")) || hasEntries(join(root, "sessions")) || hasEntries(join(root, "attachments"));
|
|
5126
|
+
}
|
|
5127
|
+
function pathsIn(file) {
|
|
5128
|
+
try {
|
|
5129
|
+
const value = JSON.parse(readFileSync(file, "utf8"));
|
|
5130
|
+
if (typeof value !== "object" || value === null) return /* @__PURE__ */ new Set();
|
|
5131
|
+
const tables = value["tables"];
|
|
5132
|
+
if (typeof tables !== "object" || tables === null) return /* @__PURE__ */ new Set();
|
|
5133
|
+
const workspaces = tables["workspaces"];
|
|
5134
|
+
if (typeof workspaces !== "object" || workspaces === null) return /* @__PURE__ */ new Set();
|
|
5135
|
+
const paths = /* @__PURE__ */ new Set();
|
|
5136
|
+
for (const entry of Object.values(workspaces)) {
|
|
5137
|
+
if (typeof entry !== "object" || entry === null) continue;
|
|
5138
|
+
const path = entry["path"];
|
|
5139
|
+
if (typeof path === "string") paths.add(path);
|
|
5140
|
+
}
|
|
5141
|
+
return paths;
|
|
5142
|
+
} catch {
|
|
5143
|
+
return /* @__PURE__ */ new Set();
|
|
5144
|
+
}
|
|
5145
|
+
}
|
|
5146
|
+
function hasMissingPaths(sourceFile, targetFile) {
|
|
5147
|
+
const source = pathsIn(sourceFile);
|
|
5148
|
+
if (source.size === 0) return false;
|
|
5149
|
+
const target = pathsIn(targetFile);
|
|
5150
|
+
for (const path of source) if (!target.has(path)) return true;
|
|
5151
|
+
return false;
|
|
5152
|
+
}
|
|
5153
|
+
function migrationFollowUp(input) {
|
|
5154
|
+
const runtimeRoot = input.runtimeRoot ?? join(input.home, input.profile);
|
|
5155
|
+
if (resolve(runtimeRoot) === resolve(input.home)) return void 0;
|
|
5156
|
+
if (isFollowUpDismissed(runtimeRoot, "data-root-migration")) return void 0;
|
|
5157
|
+
if (!legacyDataIn(runtimeRoot)) return void 0;
|
|
5158
|
+
const marker = join(runtimeRoot, ".data-root-shared");
|
|
5159
|
+
if (!existsSync(marker)) return {
|
|
5160
|
+
id: MIGRATION_FOLLOW_UP_ID,
|
|
5161
|
+
kind: "data-migration",
|
|
5162
|
+
hard: false
|
|
5163
|
+
};
|
|
5164
|
+
const source = join(runtimeRoot, "storages", "workspace.json");
|
|
5165
|
+
const target = join(input.home, "storages", "workspace.json");
|
|
5166
|
+
if (!existsSync(source) || !existsSync(target)) return void 0;
|
|
5167
|
+
return hasMissingPaths(source, target) ? {
|
|
5168
|
+
id: MIGRATION_FOLLOW_UP_ID,
|
|
5169
|
+
kind: "data-migration",
|
|
5170
|
+
hard: false
|
|
5171
|
+
} : void 0;
|
|
5172
|
+
}
|
|
5173
|
+
//#endregion
|
|
5013
5174
|
//#region src/shared/api/host/bundle-routes.ts
|
|
5014
5175
|
function registryOf(search) {
|
|
5015
5176
|
const raw = param(search, "registry");
|
|
@@ -5033,6 +5194,25 @@ function bundleRegistriesHandler(ctx) {
|
|
|
5033
5194
|
}
|
|
5034
5195
|
var refusalLog = /* @__PURE__ */ new Map();
|
|
5035
5196
|
var holdLog = /* @__PURE__ */ new Map();
|
|
5197
|
+
function updateBlockOf(raw, problems) {
|
|
5198
|
+
if (problems.length === 0) return void 0;
|
|
5199
|
+
const declared = declarationApiVersionOf(raw);
|
|
5200
|
+
const newest = Math.max(...SUPPORTED_API_VERSIONS);
|
|
5201
|
+
return declared !== void 0 && declared > newest ? "needs-workbench" : "incompatible";
|
|
5202
|
+
}
|
|
5203
|
+
function titleOf(raw) {
|
|
5204
|
+
if (typeof raw !== "object" || raw === null) return void 0;
|
|
5205
|
+
const title = raw.title;
|
|
5206
|
+
if (typeof title !== "object" || title === null || Array.isArray(title)) return void 0;
|
|
5207
|
+
const record = title;
|
|
5208
|
+
const zh = typeof record.zh === "string" ? record.zh.trim() : "";
|
|
5209
|
+
const en = typeof record.en === "string" ? record.en.trim() : "";
|
|
5210
|
+
if (zh === "" || en === "") return void 0;
|
|
5211
|
+
return {
|
|
5212
|
+
zh,
|
|
5213
|
+
en
|
|
5214
|
+
};
|
|
5215
|
+
}
|
|
5036
5216
|
async function latestIfReleaseReady(supply, input) {
|
|
5037
5217
|
const missing = await supply.missingReleaseParts({
|
|
5038
5218
|
shell: input.shell,
|
|
@@ -5075,7 +5255,8 @@ async function workbenchVersion(supply, input) {
|
|
|
5075
5255
|
installed: read.version,
|
|
5076
5256
|
...latest === void 0 ? {} : { latest },
|
|
5077
5257
|
...input.running === void 0 ? {} : { running: input.running },
|
|
5078
|
-
...read.local === true ? { local: true } : {}
|
|
5258
|
+
...read.local === true ? { local: true } : {},
|
|
5259
|
+
...input.followUp === void 0 ? {} : { followUp: input.followUp }
|
|
5079
5260
|
};
|
|
5080
5261
|
}
|
|
5081
5262
|
function moduleVersionsHandler(ctx, shell, running, selfUpdate) {
|
|
@@ -5101,7 +5282,15 @@ function moduleVersionsHandler(ctx, shell, running, selfUpdate) {
|
|
|
5101
5282
|
});
|
|
5102
5283
|
const raw = supply.moduleDeclarationOf(dir, module.pkg);
|
|
5103
5284
|
const declared = raw === void 0 ? [] : declarationProblemsOf(module.pkg, raw);
|
|
5285
|
+
const title = titleOf(raw);
|
|
5104
5286
|
const refused = refusals.get(module.unit) ?? (declared.length === 0 ? void 0 : declared);
|
|
5287
|
+
const latestRaw = latest === void 0 || latest === module.version || shell === void 0 || registry === void 0 ? void 0 : await supply.registryDeclarationOf({
|
|
5288
|
+
shell,
|
|
5289
|
+
name: module.pkg,
|
|
5290
|
+
registry,
|
|
5291
|
+
force
|
|
5292
|
+
});
|
|
5293
|
+
const latestBlocked = latestRaw === void 0 ? void 0 : updateBlockOf(latestRaw, declarationProblemsOf(module.pkg, latestRaw));
|
|
5105
5294
|
if (refused === void 0) refusalLog.delete(module.pkg);
|
|
5106
5295
|
else {
|
|
5107
5296
|
const line = refused.join(";");
|
|
@@ -5114,18 +5303,28 @@ function moduleVersionsHandler(ctx, shell, running, selfUpdate) {
|
|
|
5114
5303
|
unit: module.unit,
|
|
5115
5304
|
pkg: module.pkg,
|
|
5116
5305
|
installed: module.version,
|
|
5306
|
+
...title === void 0 ? {} : { title },
|
|
5117
5307
|
...latest === void 0 ? {} : { latest },
|
|
5308
|
+
...latestBlocked === void 0 ? {} : { latestBlocked },
|
|
5118
5309
|
...module.local === true ? { local: true } : {},
|
|
5119
5310
|
...refused === void 0 ? {} : { refused }
|
|
5120
5311
|
};
|
|
5121
5312
|
}));
|
|
5122
5313
|
const selfUpdateNow = selfUpdate?.();
|
|
5314
|
+
const profile = dir === null ? "" : basename(dir);
|
|
5315
|
+
const home = dir === null ? void 0 : dirname(dirname(dir));
|
|
5316
|
+
const followUp = profile === "" || home === void 0 ? void 0 : migrationFollowUp({
|
|
5317
|
+
home,
|
|
5318
|
+
profile,
|
|
5319
|
+
...process.env.DSH_WORKBENCH_HOME === void 0 || process.env.DSH_WORKBENCH_HOME === "" ? {} : { runtimeRoot: process.env.DSH_WORKBENCH_HOME }
|
|
5320
|
+
});
|
|
5123
5321
|
const workbench = await workbenchVersion(supply, {
|
|
5124
5322
|
dir,
|
|
5125
5323
|
shell,
|
|
5126
5324
|
fallback,
|
|
5127
5325
|
force,
|
|
5128
5326
|
...running === void 0 ? {} : { running },
|
|
5327
|
+
...followUp === void 0 ? {} : { followUp },
|
|
5129
5328
|
logger: ctx.logger
|
|
5130
5329
|
});
|
|
5131
5330
|
return {
|
|
@@ -8894,7 +9093,7 @@ function renderList(root, modules, shape = "bare") {
|
|
|
8894
9093
|
//#endregion
|
|
8895
9094
|
//#region src/modules/panels/model/diy-tools.ts
|
|
8896
9095
|
var PUBLISH_TIMEOUT_MS = 18e5;
|
|
8897
|
-
function registerDiyTools(ctx, market, panels, debug, previewOf = () => null) {
|
|
9096
|
+
function registerDiyTools(ctx, market, panels, debug, previewOf = () => null, inferredAuthorOf = async () => void 0) {
|
|
8898
9097
|
const supply = supplyPortOf(ctx);
|
|
8899
9098
|
const tools = ctx.get("tools");
|
|
8900
9099
|
if (tools === void 0) {
|
|
@@ -9171,6 +9370,10 @@ function registerDiyTools(ctx, market, panels, debug, previewOf = () => null) {
|
|
|
9171
9370
|
type: "string",
|
|
9172
9371
|
description: "公开发布用的许可证(MIT / Apache-2.0 / 仓库已有 LICENSE)。"
|
|
9173
9372
|
},
|
|
9373
|
+
author: {
|
|
9374
|
+
type: "string",
|
|
9375
|
+
description: "署谁的名(姓名,或 姓名 <邮箱>);用户点了名才传,不传按模块里写的,没写用推断的署名。"
|
|
9376
|
+
},
|
|
9174
9377
|
refresh: {
|
|
9175
9378
|
type: "boolean",
|
|
9176
9379
|
description: "只刷市集元数据(标题/作者/说明),不升版本、不重发产物。"
|
|
@@ -9190,8 +9393,10 @@ function registerDiyTools(ctx, market, panels, debug, previewOf = () => null) {
|
|
|
9190
9393
|
const target = asText(asRecord$1(raw)["target"]);
|
|
9191
9394
|
const version = asText(asRecord$1(raw)["version"]);
|
|
9192
9395
|
const license = asText(asRecord$1(raw)["license"]);
|
|
9396
|
+
let author = asText(asRecord$1(raw)["author"]);
|
|
9193
9397
|
const verify = asRecord$1(raw)["verify"] === true;
|
|
9194
9398
|
const resume = asRecord$1(raw)["resume"] === true;
|
|
9399
|
+
if (!verify && target !== "local" && author === "" && (previewOf(found.unit)?.author ?? "") === "") author = await inferredAuthorOf(found.unit) ?? "";
|
|
9195
9400
|
const argv = [
|
|
9196
9401
|
bin,
|
|
9197
9402
|
"release",
|
|
@@ -9205,6 +9410,7 @@ function registerDiyTools(ctx, market, panels, debug, previewOf = () => null) {
|
|
|
9205
9410
|
if (target !== "") argv.push("--target", target);
|
|
9206
9411
|
if (version !== "") argv.push("--version", version);
|
|
9207
9412
|
if (license !== "") argv.push("--license", license);
|
|
9413
|
+
if (author !== "") argv.push("--author", author);
|
|
9208
9414
|
if (asRecord$1(raw)["refresh"] === true) argv.push("--refresh");
|
|
9209
9415
|
const result = await runShell(shell, argv.map((one) => quoteShellArg(one)).join(" "), {
|
|
9210
9416
|
workdir: root,
|
|
@@ -9311,17 +9517,28 @@ function selectedGitSource() {
|
|
|
9311
9517
|
return parsed.source.policy === "artifacts-in-repo" ? parsed.source : void 0;
|
|
9312
9518
|
}
|
|
9313
9519
|
}
|
|
9314
|
-
function
|
|
9520
|
+
function publishedEntryOf(source, name) {
|
|
9315
9521
|
const file = join(workbenchRoot(), "market-index", marketSourceKey(source), "worktree", source.path ?? "market.json");
|
|
9316
9522
|
if (!existsSync(file)) return void 0;
|
|
9317
9523
|
try {
|
|
9318
9524
|
const parsed = parseMarketIndexJson(readFileSync(file, "utf8"));
|
|
9319
9525
|
if (!parsed.ok) return void 0;
|
|
9320
|
-
|
|
9526
|
+
const entry = parsed.index.plugins.find((one) => one.name === name);
|
|
9527
|
+
if (entry === void 0) return {
|
|
9528
|
+
versions: [],
|
|
9529
|
+
author: ""
|
|
9530
|
+
};
|
|
9531
|
+
return {
|
|
9532
|
+
versions: entry.versions.map((one) => one.version),
|
|
9533
|
+
author: typeof entry.author === "string" ? entry.author.trim() : ""
|
|
9534
|
+
};
|
|
9321
9535
|
} catch {
|
|
9322
9536
|
return;
|
|
9323
9537
|
}
|
|
9324
9538
|
}
|
|
9539
|
+
function publishedVersionsOf(source, name) {
|
|
9540
|
+
return publishedEntryOf(source, name)?.versions;
|
|
9541
|
+
}
|
|
9325
9542
|
function bumped(version, kind) {
|
|
9326
9543
|
const match = SEMVER.exec(version);
|
|
9327
9544
|
if (match === null) return version;
|
|
@@ -9358,6 +9575,71 @@ function marketOf(unit, dir, name, version) {
|
|
|
9358
9575
|
...nextVersion === void 0 ? {} : { nextVersion }
|
|
9359
9576
|
};
|
|
9360
9577
|
}
|
|
9578
|
+
function moduleFactOf(root, unit) {
|
|
9579
|
+
if (root === null || root === void 0 || unit === "") return null;
|
|
9580
|
+
const found = modulesIn(root).find((one) => one.unit === unit);
|
|
9581
|
+
if (found === void 0) return null;
|
|
9582
|
+
let manifest;
|
|
9583
|
+
try {
|
|
9584
|
+
manifest = JSON.parse(readFileSync(join(found.dir, "package.json"), "utf8"));
|
|
9585
|
+
} catch {
|
|
9586
|
+
return null;
|
|
9587
|
+
}
|
|
9588
|
+
if (typeof manifest !== "object" || manifest === null) return null;
|
|
9589
|
+
const record = manifest;
|
|
9590
|
+
return {
|
|
9591
|
+
dir: found.dir,
|
|
9592
|
+
name: typeof record["name"] === "string" ? record["name"].trim() : "",
|
|
9593
|
+
author: authorOf(record)
|
|
9594
|
+
};
|
|
9595
|
+
}
|
|
9596
|
+
function siblingAuthorOf(root, unit) {
|
|
9597
|
+
const authors = /* @__PURE__ */ new Set();
|
|
9598
|
+
for (const module of modulesIn(root)) {
|
|
9599
|
+
if (module.unit === unit) continue;
|
|
9600
|
+
try {
|
|
9601
|
+
const manifest = JSON.parse(readFileSync(join(module.dir, "package.json"), "utf8"));
|
|
9602
|
+
if (typeof manifest !== "object" || manifest === null) continue;
|
|
9603
|
+
const author = authorOf(manifest);
|
|
9604
|
+
if (author !== "") authors.add(author);
|
|
9605
|
+
} catch {
|
|
9606
|
+
continue;
|
|
9607
|
+
}
|
|
9608
|
+
}
|
|
9609
|
+
return authors.size === 1 ? [...authors][0] : void 0;
|
|
9610
|
+
}
|
|
9611
|
+
async function localGitIdentityOf(shell, dir) {
|
|
9612
|
+
if (shell === void 0) return void 0;
|
|
9613
|
+
const read = async (argv) => {
|
|
9614
|
+
const result = await runShell(shell, `git -C ${quoteShellArg(dir)} ${argv}`, { workdir: dir });
|
|
9615
|
+
return result.exitCode === 0 ? result.stdout.trim() : "";
|
|
9616
|
+
};
|
|
9617
|
+
const name = await read(`config ${quoteShellArg("user.name")}`);
|
|
9618
|
+
if (name === "") return void 0;
|
|
9619
|
+
const email = await read(`config ${quoteShellArg("user.email")}`);
|
|
9620
|
+
return email === "" ? name : `${name} <${email}>`;
|
|
9621
|
+
}
|
|
9622
|
+
async function lastCommitAuthorOf(shell, dir) {
|
|
9623
|
+
if (shell === void 0) return void 0;
|
|
9624
|
+
const result = await runShell(shell, `git -C ${quoteShellArg(dir)} log -1 --format=${quoteShellArg("%an <%ae>")}`, { workdir: dir });
|
|
9625
|
+
const author = result.exitCode === 0 ? result.stdout.trim() : "";
|
|
9626
|
+
return author === "" ? void 0 : author;
|
|
9627
|
+
}
|
|
9628
|
+
async function inferredAuthorOf(root, unit, shell) {
|
|
9629
|
+
const fact = moduleFactOf(root, unit);
|
|
9630
|
+
if (fact === null) return void 0;
|
|
9631
|
+
if (fact.author !== "") return fact.author;
|
|
9632
|
+
const source = selectedGitSource();
|
|
9633
|
+
if (source !== void 0 && fact.name !== "") {
|
|
9634
|
+
const published = publishedEntryOf(source, fact.name)?.author ?? "";
|
|
9635
|
+
if (published !== "") return published;
|
|
9636
|
+
}
|
|
9637
|
+
const sibling = root === null || root === void 0 ? void 0 : siblingAuthorOf(root, unit);
|
|
9638
|
+
if (sibling !== void 0) return sibling;
|
|
9639
|
+
const local = await localGitIdentityOf(shell, fact.dir);
|
|
9640
|
+
if (local !== void 0) return local;
|
|
9641
|
+
return lastCommitAuthorOf(shell, fact.dir);
|
|
9642
|
+
}
|
|
9361
9643
|
function publishPreviewOf(root, unit, options = {}) {
|
|
9362
9644
|
if (root === null || root === void 0 || unit === "") return null;
|
|
9363
9645
|
const found = modulesIn(root).find((one) => one.unit === unit);
|
|
@@ -9377,7 +9659,8 @@ function publishPreviewOf(root, unit, options = {}) {
|
|
|
9377
9659
|
const registry = typeof publishConfig === "object" && publishConfig !== null ? publishConfig["registry"] : void 0;
|
|
9378
9660
|
const market = marketOf(found.unit, found.dir, name, version);
|
|
9379
9661
|
const target = targetVersionOf(version, (options.version ?? "").trim(), market);
|
|
9380
|
-
const
|
|
9662
|
+
const askedAuthor = (options.author ?? "").trim();
|
|
9663
|
+
const author = askedAuthor === "" ? authorOf(record) : askedAuthor;
|
|
9381
9664
|
return {
|
|
9382
9665
|
name,
|
|
9383
9666
|
version,
|
|
@@ -11137,7 +11420,7 @@ function findDependency(manifests, id, isReleased) {
|
|
|
11137
11420
|
const index = buildSupplyIndex(manifests.map((manifest) => ({
|
|
11138
11421
|
id: manifest.id,
|
|
11139
11422
|
needs: needsOf(manifest)
|
|
11140
|
-
})));
|
|
11423
|
+
})), { env: process.env });
|
|
11141
11424
|
const entry = parsed.kind === "extension" || parsed.kind === "lib" ? index.entryOf(parsed.kind, parsed.name) : void 0;
|
|
11142
11425
|
const conflict = entry?.conflicted === true ? index.conflicts.find((item) => item.names.includes(parsed.name))?.detail : void 0;
|
|
11143
11426
|
return {
|
|
@@ -11469,6 +11752,15 @@ async function updateModuleBundle(unit, deps) {
|
|
|
11469
11752
|
registry,
|
|
11470
11753
|
force: true
|
|
11471
11754
|
});
|
|
11755
|
+
if (latest !== void 0 && deps.shell !== void 0 && registry !== void 0) {
|
|
11756
|
+
const declared = await supply.registryDeclarationOf({
|
|
11757
|
+
shell: deps.shell,
|
|
11758
|
+
name: pkg,
|
|
11759
|
+
registry,
|
|
11760
|
+
force: true
|
|
11761
|
+
});
|
|
11762
|
+
if (declared !== void 0 && supply.declarationRefusalOf(pkg, declared).length > 0) throw new Error("源上的新版和当前这一版工作台不匹配 —— 先升级工作台,再更新这个模块。");
|
|
11763
|
+
}
|
|
11472
11764
|
const spec = latest === void 0 ? pkg : `${pkg}@${latest}`;
|
|
11473
11765
|
const outcome = await replaceDshBundle(deps.routeDeps, spec, { ...registry === void 0 ? {} : { registry } });
|
|
11474
11766
|
await deps.sweep();
|
|
@@ -11578,6 +11870,80 @@ async function updateWorkbenchOnce(deps) {
|
|
|
11578
11870
|
};
|
|
11579
11871
|
}
|
|
11580
11872
|
//#endregion
|
|
11873
|
+
//#region src/shared/api/host/migrate-workbench.ts
|
|
11874
|
+
async function migrateWorkbench(input) {
|
|
11875
|
+
const script = join(input.home, "profiles", input.profile, "node_modules", input.pkg, "scripts", "share-data-root.mjs");
|
|
11876
|
+
if (!existsSync(script)) throw new Error(`找不到迁移脚本(${script})—— 这一份没装全?`);
|
|
11877
|
+
const runtimeRoot = process.env.DSH_WORKBENCH_HOME ?? join(input.home, input.profile);
|
|
11878
|
+
const result = await input.run({
|
|
11879
|
+
script,
|
|
11880
|
+
env: {
|
|
11881
|
+
DSH_HOME: input.home,
|
|
11882
|
+
WORKBENCH_PROFILE: input.profile,
|
|
11883
|
+
DSH_WORKBENCH_HOME: runtimeRoot
|
|
11884
|
+
}
|
|
11885
|
+
});
|
|
11886
|
+
if (result.exitCode !== 0) {
|
|
11887
|
+
const tail = (result.stderr || result.stdout).trim().split("\n").slice(-6).join("\n");
|
|
11888
|
+
throw new Error(`迁移没成(退出码 ${result.exitCode})${tail === "" ? "" : `:${tail}`}`);
|
|
11889
|
+
}
|
|
11890
|
+
return {
|
|
11891
|
+
added: Number.parseInt(/新增\s+(\d+)\s+个项目/.exec(result.stdout)?.[1] ?? "0", 10),
|
|
11892
|
+
files: Number.parseInt(/补了\s+(\d+)\s+个文件/.exec(result.stdout)?.[1] ?? "0", 10)
|
|
11893
|
+
};
|
|
11894
|
+
}
|
|
11895
|
+
//#endregion
|
|
11896
|
+
//#region src/modules/panels/model/market-follow-up.ts
|
|
11897
|
+
function createWorkbenchFollowUps(deps) {
|
|
11898
|
+
const runMigration = deps.runMigration ?? (async (input) => {
|
|
11899
|
+
const result = await execa(process.execPath, [
|
|
11900
|
+
input.script,
|
|
11901
|
+
"--migrate",
|
|
11902
|
+
"--force"
|
|
11903
|
+
], {
|
|
11904
|
+
env: {
|
|
11905
|
+
...process.env,
|
|
11906
|
+
ELECTRON_RUN_AS_NODE: "1",
|
|
11907
|
+
...input.env
|
|
11908
|
+
},
|
|
11909
|
+
reject: false,
|
|
11910
|
+
timeout: 12e4
|
|
11911
|
+
});
|
|
11912
|
+
return {
|
|
11913
|
+
exitCode: result.exitCode ?? 1,
|
|
11914
|
+
stdout: result.stdout,
|
|
11915
|
+
stderr: result.stderr
|
|
11916
|
+
};
|
|
11917
|
+
});
|
|
11918
|
+
function homeAndProfile() {
|
|
11919
|
+
if (deps.dshHome === void 0 || deps.profileName === void 0) throw new Error("拿不到 DSH_HOME 或 profile 名字 —— 这一步做不了。");
|
|
11920
|
+
const home = deps.dshHome();
|
|
11921
|
+
const profile = deps.profileName();
|
|
11922
|
+
if (profile === null || profile === "") throw new Error("拿不到 profile 名字 —— 这一步做不了。");
|
|
11923
|
+
return {
|
|
11924
|
+
home,
|
|
11925
|
+
profile
|
|
11926
|
+
};
|
|
11927
|
+
}
|
|
11928
|
+
return {
|
|
11929
|
+
async migrateWorkbench() {
|
|
11930
|
+
const { home, profile } = homeAndProfile();
|
|
11931
|
+
const read = deps.workbench?.(PLUGIN_ID);
|
|
11932
|
+
if (read === void 0) throw new Error(`读不到 profile 里装的 ${PLUGIN_ID} —— 迁移做不了。`);
|
|
11933
|
+
return migrateWorkbench({
|
|
11934
|
+
home,
|
|
11935
|
+
profile,
|
|
11936
|
+
pkg: read.pkg,
|
|
11937
|
+
run: runMigration
|
|
11938
|
+
});
|
|
11939
|
+
},
|
|
11940
|
+
async dismissFollowUp(id) {
|
|
11941
|
+
const { home, profile } = homeAndProfile();
|
|
11942
|
+
dismissFollowUp(process.env.DSH_WORKBENCH_HOME ?? join(home, profile), id);
|
|
11943
|
+
}
|
|
11944
|
+
};
|
|
11945
|
+
}
|
|
11946
|
+
//#endregion
|
|
11581
11947
|
//#region src/modules/panels/model/plugin-actions.ts
|
|
11582
11948
|
function pluginKeptOf(retention, detail) {
|
|
11583
11949
|
if (retention === "keep-held") return { kind: "held" };
|
|
@@ -11751,7 +12117,7 @@ function createEnvDropper(options) {
|
|
|
11751
12117
|
const index = buildSupplyIndex(catalog().filter((item) => options.isReleased?.(item.id) !== true).map((item) => ({
|
|
11752
12118
|
id: item.id,
|
|
11753
12119
|
needs: needsOf(item)
|
|
11754
|
-
})));
|
|
12120
|
+
})), { env: process.env });
|
|
11755
12121
|
const extensions = (needs ?? []).filter((need) => need.kind === "extension");
|
|
11756
12122
|
const libs = (needs ?? []).filter((need) => need.kind === "lib");
|
|
11757
12123
|
const onMachine = new Set(before.needs.filter((state) => state.kind === "extension" && state.status !== "missing").map((state) => state.name));
|
|
@@ -12181,6 +12547,12 @@ function createMarketService(options) {
|
|
|
12181
12547
|
await reprobePlugin(pkg, outcome.name);
|
|
12182
12548
|
return outcome;
|
|
12183
12549
|
},
|
|
12550
|
+
...createWorkbenchFollowUps({
|
|
12551
|
+
dshHome,
|
|
12552
|
+
profileName,
|
|
12553
|
+
workbench,
|
|
12554
|
+
...options.runMigration === void 0 ? {} : { runMigration: options.runMigration }
|
|
12555
|
+
}),
|
|
12184
12556
|
updateDependency: updateDependencyRow$1
|
|
12185
12557
|
};
|
|
12186
12558
|
return service;
|
|
@@ -12410,6 +12782,12 @@ function marketDiscoverRoutes(discover) {
|
|
|
12410
12782
|
}
|
|
12411
12783
|
//#endregion
|
|
12412
12784
|
//#region src/modules/panels/model/market-sources-act.ts
|
|
12785
|
+
function marketSourcesRoutes(store) {
|
|
12786
|
+
return { [MARKET_SOURCES_ROUTE]: async () => ({
|
|
12787
|
+
ok: true,
|
|
12788
|
+
...store.read()
|
|
12789
|
+
}) };
|
|
12790
|
+
}
|
|
12413
12791
|
function asRecord(value) {
|
|
12414
12792
|
return typeof value === "object" && value !== null ? value : void 0;
|
|
12415
12793
|
}
|
|
@@ -12491,13 +12869,29 @@ function marketSourcesAction(store, init) {
|
|
|
12491
12869
|
}
|
|
12492
12870
|
//#endregion
|
|
12493
12871
|
//#region src/modules/panels/model/publish-preview-routes.ts
|
|
12494
|
-
function publishPreviewRoutes(workshop) {
|
|
12495
|
-
return { [MARKET_PUBLISH_PREVIEW_ROUTE]: (search) => {
|
|
12872
|
+
function publishPreviewRoutes(workshop, inferredAuthorOf = async () => void 0) {
|
|
12873
|
+
return { [MARKET_PUBLISH_PREVIEW_ROUTE]: async (search) => {
|
|
12496
12874
|
const unit = (param(search, "unit") ?? "").trim();
|
|
12497
12875
|
const version = (param(search, "version") ?? "").trim();
|
|
12876
|
+
const author = (param(search, "author") ?? "").trim();
|
|
12877
|
+
if (unit === "") return {
|
|
12878
|
+
ok: true,
|
|
12879
|
+
preview: null
|
|
12880
|
+
};
|
|
12881
|
+
let preview = publishPreviewOf(workshop, unit, {
|
|
12882
|
+
version,
|
|
12883
|
+
author
|
|
12884
|
+
});
|
|
12885
|
+
if (preview !== null && author === "" && (preview.author === void 0 || preview.author === "")) {
|
|
12886
|
+
const inferred = await inferredAuthorOf(unit);
|
|
12887
|
+
if (inferred !== void 0 && inferred !== "") preview = {
|
|
12888
|
+
...preview,
|
|
12889
|
+
author: inferred
|
|
12890
|
+
};
|
|
12891
|
+
}
|
|
12498
12892
|
return {
|
|
12499
12893
|
ok: true,
|
|
12500
|
-
preview
|
|
12894
|
+
preview
|
|
12501
12895
|
};
|
|
12502
12896
|
} };
|
|
12503
12897
|
}
|
|
@@ -12506,6 +12900,7 @@ function publishPreviewRoutes(workshop) {
|
|
|
12506
12900
|
var DEFAULT_TTL_MS = 3e5;
|
|
12507
12901
|
var DEFAULT_TIMEOUT_MS$2 = 3e4;
|
|
12508
12902
|
var DEFAULT_MAX_BYTES$1 = 4194304;
|
|
12903
|
+
var GIT_NO_PROMPT = `${quoteShellArg("env")} GIT_TERMINAL_PROMPT=0`;
|
|
12509
12904
|
function messageOf$1(error) {
|
|
12510
12905
|
return error instanceof Error ? error.message : String(error);
|
|
12511
12906
|
}
|
|
@@ -12671,7 +13066,7 @@ function createMarketIndexReader(options) {
|
|
|
12671
13066
|
}
|
|
12672
13067
|
};
|
|
12673
13068
|
try {
|
|
12674
|
-
const result = await runShell(shell, line
|
|
13069
|
+
const result = await runShell(shell, `${GIT_NO_PROMPT} ${line}`, { timeoutMs });
|
|
12675
13070
|
if (result.exitCode !== 0) return {
|
|
12676
13071
|
ok: false,
|
|
12677
13072
|
problem: classifyGitError(result.stderr, result.timedOut),
|
|
@@ -13228,6 +13623,18 @@ async function dispatchMarket(market, request) {
|
|
|
13228
13623
|
action: "cancel-install",
|
|
13229
13624
|
cancellation: await market.cancelInstall(request.requestId ?? "")
|
|
13230
13625
|
};
|
|
13626
|
+
if (request.action === "migrate-workbench") return {
|
|
13627
|
+
ok: true,
|
|
13628
|
+
action: "migrate-workbench",
|
|
13629
|
+
...await market.migrateWorkbench()
|
|
13630
|
+
};
|
|
13631
|
+
if (request.action === "dismiss-followup") {
|
|
13632
|
+
await market.dismissFollowUp(request.id ?? "");
|
|
13633
|
+
return {
|
|
13634
|
+
ok: true,
|
|
13635
|
+
action: "dismiss-followup"
|
|
13636
|
+
};
|
|
13637
|
+
}
|
|
13231
13638
|
if (request.action === "update-workbench") return {
|
|
13232
13639
|
ok: true,
|
|
13233
13640
|
action: "update-workbench",
|
|
@@ -14382,12 +14789,13 @@ var OWNED = [{
|
|
|
14382
14789
|
...diyDebugRoutes(debug),
|
|
14383
14790
|
...diyRecordRoutes(record),
|
|
14384
14791
|
...marketDiscoverRoutes(discover),
|
|
14385
|
-
...
|
|
14792
|
+
...marketSourcesRoutes(marketSources),
|
|
14793
|
+
...publishPreviewRoutes(workshopPathOf(ctx), (unit) => inferredAuthorOf(workshopPathOf(ctx), unit, shell))
|
|
14386
14794
|
},
|
|
14387
14795
|
registerTools: () => [
|
|
14388
14796
|
...registerPanelTools(ctx, panels, values),
|
|
14389
14797
|
...registerMarketTools(ctx, market),
|
|
14390
|
-
...registerDiyTools(ctx, market, panels, debug, (unit) => publishPreviewOf(workshopPathOf(ctx), unit)),
|
|
14798
|
+
...registerDiyTools(ctx, market, panels, debug, (unit) => publishPreviewOf(workshopPathOf(ctx), unit), (unit) => inferredAuthorOf(workshopPathOf(ctx), unit, shell)),
|
|
14391
14799
|
...registerRecordTools(ctx, record),
|
|
14392
14800
|
...registerLongTaskTools(ctx, longTaskRuns)
|
|
14393
14801
|
],
|