@sparkelf/dsh-plus 0.2.2-alpha.2.1 → 0.2.2-alpha.2.10
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/lib/bin.js +106 -20
- package/lib/types/standalone-cli.js +40 -3
- package/lib/types/standalone-profile.js +113 -21
- package/package.json +31 -53
package/lib/bin.js
CHANGED
|
@@ -900,11 +900,12 @@ function isWithin(candidate, parent, platform = process.platform) {
|
|
|
900
900
|
* @returns absolute path to the installed distribution.
|
|
901
901
|
*/
|
|
902
902
|
function resolveDistributionDirectory(anchor) {
|
|
903
|
+
const ownDirectory = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
903
904
|
let resolved;
|
|
904
905
|
try {
|
|
905
906
|
resolved = dirname(createRequire(anchor).resolve("@sparkelf/dsh-plus/package.json"));
|
|
906
907
|
} catch {
|
|
907
|
-
|
|
908
|
+
return ownDirectory;
|
|
908
909
|
}
|
|
909
910
|
let current = resolve(dirname(anchor));
|
|
910
911
|
for (;;) {
|
|
@@ -913,7 +914,7 @@ function resolveDistributionDirectory(anchor) {
|
|
|
913
914
|
if (parent === current) break;
|
|
914
915
|
current = parent;
|
|
915
916
|
}
|
|
916
|
-
|
|
917
|
+
return ownDirectory;
|
|
917
918
|
}
|
|
918
919
|
function readDistributionProfile(distributionDirectory) {
|
|
919
920
|
const manifest = requireRecord(JSON.parse(readFileSync(join(distributionDirectory, "package.json"), "utf8")), "Plus distribution manifest");
|
|
@@ -982,7 +983,11 @@ function requireDependencyMap(value, label) {
|
|
|
982
983
|
* @param consumerDirectory - directory whose `node_modules` holds the installation.
|
|
983
984
|
*/
|
|
984
985
|
function installProfilePackages(paths, consumerDirectory) {
|
|
985
|
-
if (!existsSync(join(consumerDirectory, "node_modules")))
|
|
986
|
+
if (!existsSync(join(consumerDirectory, "node_modules"))) {
|
|
987
|
+
installWithRegistryFallback(paths);
|
|
988
|
+
alignReplacedPackageNames(join(paths.profileDirectory, "node_modules"));
|
|
989
|
+
return;
|
|
990
|
+
}
|
|
986
991
|
const profileModules = join(paths.profileDirectory, "node_modules");
|
|
987
992
|
if (existsSync(profileModules)) {
|
|
988
993
|
linkNestedBundles(paths, profileModules);
|
|
@@ -1004,6 +1009,7 @@ function installProfilePackages(paths, consumerDirectory) {
|
|
|
1004
1009
|
function installWithRegistryFallback(paths) {
|
|
1005
1010
|
const registries = registryOrder();
|
|
1006
1011
|
for (const [index, registry] of registries.entries()) {
|
|
1012
|
+
if (index > 0) rmSync(join(paths.profileDirectory, "pnpm-lock.yaml"), { force: true });
|
|
1007
1013
|
const result = spawnSync("pnpm", [
|
|
1008
1014
|
"install",
|
|
1009
1015
|
"--no-frozen-lockfile",
|
|
@@ -1072,7 +1078,7 @@ const MAINLAND_REGISTRY = "https://registry.npmmirror.com";
|
|
|
1072
1078
|
*/
|
|
1073
1079
|
function registryOrder() {
|
|
1074
1080
|
const configured = process.env.DSH_PLUS_INSTALL_REGISTRY;
|
|
1075
|
-
if (configured !== void 0 && configured !== "") return [configured, MAINLAND_REGISTRY];
|
|
1081
|
+
if (configured !== void 0 && configured !== "") return [configured, configured === MAINLAND_REGISTRY ? OFFICIAL_REGISTRY : MAINLAND_REGISTRY];
|
|
1076
1082
|
const locale = [
|
|
1077
1083
|
process.env.LANG,
|
|
1078
1084
|
process.env.LC_ALL,
|
|
@@ -1184,20 +1190,70 @@ function ensureProfile(paths, consumerDirectory, edition) {
|
|
|
1184
1190
|
const offered = Object.keys(distribution.editions);
|
|
1185
1191
|
throw new Error("unknown edition \"" + edition + "\"; this release offers " + (offered.length === 0 ? "(none)" : offered.join(", ")));
|
|
1186
1192
|
}
|
|
1187
|
-
const
|
|
1188
|
-
const
|
|
1193
|
+
for (const name of Object.keys(composition?.packages ?? {})) if (name.startsWith("@deepseek-ai/")) throw new Error("edition \"" + String(edition) + "\" lists the official package " + name + "; editions contain only third-party or self-developed plugins");
|
|
1194
|
+
const runtime = distribution.dshRange.replace(/^>=?/u, "");
|
|
1195
|
+
const baseBundles = composition === void 0 ? distribution.bundles : distribution.bundles.filter((bundle) => bundle.startsWith("@deepseek-ai/") || bundle === "@sparkelf/dsh-plus");
|
|
1196
|
+
const basePackages = composition === void 0 ? distribution.dependencies : {
|
|
1197
|
+
"@deepseek-ai/dsh": distribution.dshRange,
|
|
1198
|
+
"@sparkelf/dsh-plus": distribution.version,
|
|
1199
|
+
"@deepseek-ai/cordis": "^4.0.6-alpha.1",
|
|
1200
|
+
"@deepseek-ai/cordis-plugin-group": "^1.0.6-alpha.1",
|
|
1201
|
+
"@deepseek-ai/cordis-plugin-include": "^1.0.11-alpha.1",
|
|
1202
|
+
"@deepseek-ai/cordis-plugin-loader": "^1.0.7-alpha.1",
|
|
1203
|
+
"@deepseek-ai/dsh-home-paths": runtime,
|
|
1204
|
+
"@deepseek-ai/dsh-launch-environment": runtime,
|
|
1205
|
+
"@deepseek-ai/dsh-agent": runtime,
|
|
1206
|
+
"@deepseek-ai/dsh-llm": runtime,
|
|
1207
|
+
"@deepseek-ai/dsh-scope": runtime,
|
|
1208
|
+
"@deepseek-ai/dsh-session": runtime,
|
|
1209
|
+
"@deepseek-ai/dsh-system-prompt": runtime,
|
|
1210
|
+
"@deepseek-ai/dsh-user-approval": runtime,
|
|
1211
|
+
"@deepseek-ai/dsh-attachment": runtime,
|
|
1212
|
+
"@deepseek-ai/dsh-compaction": runtime,
|
|
1213
|
+
"@deepseek-ai/dsh-fs": runtime,
|
|
1214
|
+
"@deepseek-ai/dsh-shell": runtime,
|
|
1215
|
+
"@deepseek-ai/dsh-spill": runtime,
|
|
1216
|
+
"@deepseek-ai/dsh-sandbox": runtime,
|
|
1217
|
+
"@deepseek-ai/dsh-ptc-runtime": runtime,
|
|
1218
|
+
"@deepseek-ai/dsh-llm-deepseek": runtime,
|
|
1219
|
+
"@deepseek-ai/dsh-deepseek-account": runtime,
|
|
1220
|
+
"@deepseek-ai/dsh-anonymous-user-id": runtime,
|
|
1221
|
+
"@deepseek-ai/dsh-bash-local": runtime,
|
|
1222
|
+
"@deepseek-ai/dsh-client-store": runtime,
|
|
1223
|
+
"@deepseek-ai/dsh-jobs": runtime,
|
|
1224
|
+
"@deepseek-ai/dsh-sdk-protocol": runtime,
|
|
1225
|
+
"@deepseek-ai/dsh-session-persistence": runtime,
|
|
1226
|
+
"@deepseek-ai/dsh-session-telemetry": runtime,
|
|
1227
|
+
"@deepseek-ai/dsh-session-title-llm": runtime,
|
|
1228
|
+
"@deepseek-ai/dsh-util-workspace-path": runtime,
|
|
1229
|
+
"@deepseek-ai/dsh-workflow": runtime,
|
|
1230
|
+
...Object.fromEntries(baseBundles.filter((bundle) => bundle.startsWith("@deepseek-ai/dsh-")).map((bundle) => [bundle, runtime]))
|
|
1231
|
+
};
|
|
1232
|
+
const compositionPackages = composition === void 0 ? basePackages : {
|
|
1233
|
+
...basePackages,
|
|
1234
|
+
...composition.packages
|
|
1235
|
+
};
|
|
1236
|
+
for (const [alias, target] of Object.entries({
|
|
1237
|
+
"dsh-better-sidebar": "@sparkelf/dsh-better-sidebar",
|
|
1238
|
+
"dsh-sql-workbench": "@sparkelf/dsh-sql-workbench"
|
|
1239
|
+
})) {
|
|
1240
|
+
const spec = compositionPackages[target];
|
|
1241
|
+
if (spec !== void 0 && compositionPackages[alias] === void 0) compositionPackages[alias] = "npm:" + target + "@" + spec;
|
|
1242
|
+
}
|
|
1243
|
+
const compositionBundles = composition === void 0 ? baseBundles : [...baseBundles, ...composition.bundles];
|
|
1189
1244
|
if (existsSync(manifestPath)) {
|
|
1190
1245
|
if (composition !== void 0) {
|
|
1191
1246
|
const manifest = requireRecord(JSON.parse(readFileSync(manifestPath, "utf8")), "Plus profile manifest");
|
|
1192
1247
|
manifest.dependencies = {
|
|
1193
1248
|
...manifest.dependencies,
|
|
1194
|
-
...
|
|
1249
|
+
...compositionPackages
|
|
1195
1250
|
};
|
|
1196
1251
|
manifest.dsh = {
|
|
1197
1252
|
...manifest.dsh,
|
|
1198
1253
|
profile: {
|
|
1199
1254
|
...manifest.dsh?.profile,
|
|
1200
|
-
bundles: [...
|
|
1255
|
+
bundles: [...compositionBundles],
|
|
1256
|
+
...edition === void 0 ? {} : { plusEdition: edition }
|
|
1201
1257
|
}
|
|
1202
1258
|
};
|
|
1203
1259
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
|
|
@@ -1211,15 +1267,11 @@ function ensureProfile(paths, consumerDirectory, edition) {
|
|
|
1211
1267
|
name: "dsh-profile-plus",
|
|
1212
1268
|
private: true,
|
|
1213
1269
|
type: "module",
|
|
1214
|
-
dependencies:
|
|
1215
|
-
"@sparkelf/dsh-plus": distribution.version,
|
|
1216
|
-
"@deepseek-ai/dsh": distribution.dshRange,
|
|
1217
|
-
...distribution.dependencies,
|
|
1218
|
-
...editionPackages
|
|
1219
|
-
},
|
|
1270
|
+
dependencies: compositionPackages,
|
|
1220
1271
|
dsh: { profile: {
|
|
1221
|
-
bundles: [...
|
|
1222
|
-
patchReload: "live"
|
|
1272
|
+
bundles: [...compositionBundles],
|
|
1273
|
+
patchReload: "live",
|
|
1274
|
+
...edition === void 0 ? {} : { plusEdition: edition }
|
|
1223
1275
|
} }
|
|
1224
1276
|
};
|
|
1225
1277
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
|
|
@@ -1247,7 +1299,7 @@ function writeProfileOverrides(profileDirectory, overrides, allowBuilds, omitted
|
|
|
1247
1299
|
for (const [name, spec] of Object.entries(omittedPackages)) document.setIn(["overrides", name], spec);
|
|
1248
1300
|
for (const [name, allowed] of Object.entries(allowBuilds)) document.setIn(["allowBuilds", name], allowed);
|
|
1249
1301
|
if (document.get("nodeLinker") === void 0) document.set("nodeLinker", "hoisted");
|
|
1250
|
-
if (document.get("autoInstallPeers") === void 0) document.set("autoInstallPeers",
|
|
1302
|
+
if (document.get("autoInstallPeers") === void 0) document.set("autoInstallPeers", true);
|
|
1251
1303
|
writeFileSync(workspacePath, String(document));
|
|
1252
1304
|
}
|
|
1253
1305
|
/** Run git in one directory, returning undefined instead of throwing when asked to. */
|
|
@@ -1483,6 +1535,7 @@ function runForeground(entry, profileName, port, host, open) {
|
|
|
1483
1535
|
/** Parse the install command's edition selection. */
|
|
1484
1536
|
function parseInstallOptions(argv) {
|
|
1485
1537
|
let edition;
|
|
1538
|
+
let profile;
|
|
1486
1539
|
for (let index = 0; index < argv.length; index += 1) {
|
|
1487
1540
|
const token = argv[index];
|
|
1488
1541
|
if (token === "--edition") {
|
|
@@ -1492,10 +1545,20 @@ function parseInstallOptions(argv) {
|
|
|
1492
1545
|
index += 1;
|
|
1493
1546
|
continue;
|
|
1494
1547
|
}
|
|
1548
|
+
if (token === "--profile") {
|
|
1549
|
+
const value = argv[index + 1];
|
|
1550
|
+
if (value === void 0 || value === "") throw new Error("--profile requires a value");
|
|
1551
|
+
profile = value;
|
|
1552
|
+
index += 1;
|
|
1553
|
+
continue;
|
|
1554
|
+
}
|
|
1495
1555
|
throw new Error("unknown option: " + String(token));
|
|
1496
1556
|
}
|
|
1497
1557
|
if (edition === void 0) throw new Error("install requires --edition personal or --edition team");
|
|
1498
|
-
return {
|
|
1558
|
+
return {
|
|
1559
|
+
edition,
|
|
1560
|
+
profile
|
|
1561
|
+
};
|
|
1499
1562
|
}
|
|
1500
1563
|
/**
|
|
1501
1564
|
* Install one edition's package manifest into the profile.
|
|
@@ -1508,8 +1571,13 @@ function parseInstallOptions(argv) {
|
|
|
1508
1571
|
* @returns the process exit code.
|
|
1509
1572
|
*/
|
|
1510
1573
|
function install(argv) {
|
|
1511
|
-
const { edition } = parseInstallOptions(argv);
|
|
1512
|
-
const
|
|
1574
|
+
const { edition, profile } = parseInstallOptions(argv);
|
|
1575
|
+
const base = resolvePaths(declarationAnchor());
|
|
1576
|
+
const paths = profile === void 0 ? base : {
|
|
1577
|
+
...base,
|
|
1578
|
+
profileName: profile,
|
|
1579
|
+
profileDirectory: join(base.home, "profiles", profile)
|
|
1580
|
+
};
|
|
1513
1581
|
ensureProfile(paths, installationRoot(), edition);
|
|
1514
1582
|
console.log("Installed the " + edition + " edition into " + paths.profileDirectory);
|
|
1515
1583
|
return 0;
|
|
@@ -1892,6 +1960,23 @@ async function doctor() {
|
|
|
1892
1960
|
const record = readCapabilityRecord(paths.home);
|
|
1893
1961
|
const drifted = record === void 0 ? [] : CAPABILITIES.filter((capability) => record.enabled.includes(capability.id) !== actual.mounted.includes(capability.id));
|
|
1894
1962
|
check(drifted.length === 0, drifted.length === 0 ? "capabilities: " + (actual.mounted.length === 0 ? "(none enabled)" : actual.mounted.join(", ")) : "capabilities disagree with capabilities.json: " + drifted.map((capability) => capability.id).join(", ") + " (run dsh-plus capabilities)");
|
|
1963
|
+
const profileManifestPath = join(paths.profileDirectory, "package.json");
|
|
1964
|
+
if (existsSync(profileManifestPath)) {
|
|
1965
|
+
const profileManifest = JSON.parse(readFileSync(profileManifestPath, "utf8"));
|
|
1966
|
+
const editionId = profileManifest.dsh?.profile?.plusEdition;
|
|
1967
|
+
if (editionId !== void 0) {
|
|
1968
|
+
const edition = readDistributionProfile(paths.distributionDirectory).editions[editionId];
|
|
1969
|
+
if (edition === void 0) check(false, "edition \"" + editionId + "\" is not declared by this distribution");
|
|
1970
|
+
else {
|
|
1971
|
+
const bundles = new Set(profileManifest.dsh?.profile?.bundles ?? []);
|
|
1972
|
+
const missingBundles = edition.bundles.filter((bundle) => !bundles.has(bundle));
|
|
1973
|
+
const packageNames = Object.keys(edition.packages);
|
|
1974
|
+
const missingPackages = packageNames.filter((name) => !existsSync(join(paths.profileDirectory, "node_modules", ...name.split("/"), "package.json")));
|
|
1975
|
+
check(missingBundles.length === 0, "edition " + editionId + ": " + String(edition.bundles.length - missingBundles.length) + "/" + String(edition.bundles.length) + " bundles mounted" + (missingBundles.length === 0 ? "" : " (missing " + missingBundles.join(", ") + ")"));
|
|
1976
|
+
check(missingPackages.length === 0, "edition " + editionId + ": " + String(packageNames.length - missingPackages.length) + "/" + String(packageNames.length) + " packages installed" + (missingPackages.length === 0 ? "" : " (missing " + missingPackages.join(", ") + ")"));
|
|
1977
|
+
}
|
|
1978
|
+
}
|
|
1979
|
+
}
|
|
1895
1980
|
console.log(failures === 0 ? "No problems found." : String(failures) + " problem(s) found.");
|
|
1896
1981
|
return failures === 0 ? 0 : 1;
|
|
1897
1982
|
}
|
|
@@ -1916,6 +2001,7 @@ const USAGE = [
|
|
|
1916
2001
|
"",
|
|
1917
2002
|
"install options:",
|
|
1918
2003
|
" --edition <id> package manifest to install (personal or team)",
|
|
2004
|
+
" --profile <n> profile name to install into (default: this installation)",
|
|
1919
2005
|
"",
|
|
1920
2006
|
"capabilities options:",
|
|
1921
2007
|
" --enable <ids> enable the comma-separated capability ids",
|
|
@@ -169,6 +169,7 @@ function runForeground(entry, profileName, port, host, open) {
|
|
|
169
169
|
/** Parse the install command's edition selection. */
|
|
170
170
|
function parseInstallOptions(argv) {
|
|
171
171
|
let edition;
|
|
172
|
+
let profile;
|
|
172
173
|
for (let index = 0; index < argv.length; index += 1) {
|
|
173
174
|
const token = argv[index];
|
|
174
175
|
if (token === '--edition') {
|
|
@@ -179,11 +180,19 @@ function parseInstallOptions(argv) {
|
|
|
179
180
|
index += 1;
|
|
180
181
|
continue;
|
|
181
182
|
}
|
|
183
|
+
if (token === '--profile') {
|
|
184
|
+
const value = argv[index + 1];
|
|
185
|
+
if (value === undefined || value === '')
|
|
186
|
+
throw new Error('--profile requires a value');
|
|
187
|
+
profile = value;
|
|
188
|
+
index += 1;
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
182
191
|
throw new Error('unknown option: ' + String(token));
|
|
183
192
|
}
|
|
184
193
|
if (edition === undefined)
|
|
185
194
|
throw new Error('install requires --edition personal or --edition team');
|
|
186
|
-
return { edition };
|
|
195
|
+
return { edition, profile };
|
|
187
196
|
}
|
|
188
197
|
/**
|
|
189
198
|
* Install one edition's package manifest into the profile.
|
|
@@ -196,8 +205,11 @@ function parseInstallOptions(argv) {
|
|
|
196
205
|
* @returns the process exit code.
|
|
197
206
|
*/
|
|
198
207
|
function install(argv) {
|
|
199
|
-
const { edition } = parseInstallOptions(argv);
|
|
200
|
-
const
|
|
208
|
+
const { edition, profile } = parseInstallOptions(argv);
|
|
209
|
+
const base = resolvePaths(declarationAnchor());
|
|
210
|
+
const paths = profile === undefined
|
|
211
|
+
? base
|
|
212
|
+
: { ...base, profileName: profile, profileDirectory: join(base.home, 'profiles', profile) };
|
|
201
213
|
ensureProfile(paths, installationRoot(), edition);
|
|
202
214
|
console.log('Installed the ' + edition + ' edition into ' + paths.profileDirectory);
|
|
203
215
|
return 0;
|
|
@@ -628,6 +640,30 @@ async function doctor() {
|
|
|
628
640
|
? 'capabilities: ' + (actual.mounted.length === 0 ? '(none enabled)' : actual.mounted.join(', '))
|
|
629
641
|
: 'capabilities disagree with ' + CAPABILITY_RECORD + ': ' + drifted.map(capability => capability.id).join(', ')
|
|
630
642
|
+ ' (run dsh-plus capabilities)');
|
|
643
|
+
const profileManifestPath = join(paths.profileDirectory, 'package.json');
|
|
644
|
+
if (existsSync(profileManifestPath)) {
|
|
645
|
+
const profileManifest = JSON.parse(readFileSync(profileManifestPath, 'utf8'));
|
|
646
|
+
const editionId = profileManifest.dsh?.profile?.plusEdition;
|
|
647
|
+
if (editionId !== undefined) {
|
|
648
|
+
const distribution = readDistributionProfile(paths.distributionDirectory);
|
|
649
|
+
const edition = distribution.editions[editionId];
|
|
650
|
+
if (edition === undefined) {
|
|
651
|
+
check(false, 'edition "' + editionId + '" is not declared by this distribution');
|
|
652
|
+
}
|
|
653
|
+
else {
|
|
654
|
+
const bundles = new Set(profileManifest.dsh?.profile?.bundles ?? []);
|
|
655
|
+
const missingBundles = edition.bundles.filter(bundle => !bundles.has(bundle));
|
|
656
|
+
const packageNames = Object.keys(edition.packages);
|
|
657
|
+
const missingPackages = packageNames.filter(name => !existsSync(join(paths.profileDirectory, 'node_modules', ...name.split('/'), 'package.json')));
|
|
658
|
+
check(missingBundles.length === 0, 'edition ' + editionId + ': ' + String(edition.bundles.length - missingBundles.length) + '/'
|
|
659
|
+
+ String(edition.bundles.length) + ' bundles mounted'
|
|
660
|
+
+ (missingBundles.length === 0 ? '' : ' (missing ' + missingBundles.join(', ') + ')'));
|
|
661
|
+
check(missingPackages.length === 0, 'edition ' + editionId + ': ' + String(packageNames.length - missingPackages.length) + '/'
|
|
662
|
+
+ String(packageNames.length) + ' packages installed'
|
|
663
|
+
+ (missingPackages.length === 0 ? '' : ' (missing ' + missingPackages.join(', ') + ')'));
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
}
|
|
631
667
|
console.log(failures === 0 ? 'No problems found.' : String(failures) + ' problem(s) found.');
|
|
632
668
|
return failures === 0 ? 0 : 1;
|
|
633
669
|
}
|
|
@@ -652,6 +688,7 @@ const USAGE = [
|
|
|
652
688
|
'',
|
|
653
689
|
'install options:',
|
|
654
690
|
' --edition <id> package manifest to install (personal or team)',
|
|
691
|
+
' --profile <n> profile name to install into (default: this installation)',
|
|
655
692
|
'',
|
|
656
693
|
'capabilities options:',
|
|
657
694
|
' --enable <ids> enable the comma-separated capability ids',
|
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
* bundle's own list.
|
|
10
10
|
*/
|
|
11
11
|
import { spawnSync } from 'node:child_process';
|
|
12
|
-
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
12
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, renameSync, rmSync, symlinkSync, writeFileSync } from 'node:fs';
|
|
13
13
|
import { createRequire } from 'node:module';
|
|
14
|
+
import { fileURLToPath } from 'node:url';
|
|
14
15
|
import { homedir } from 'node:os';
|
|
15
16
|
import { dirname, join, posix, resolve, win32 } from 'node:path';
|
|
16
17
|
import { parseDocument } from 'yaml';
|
|
@@ -142,12 +143,15 @@ export function isWithin(candidate, parent, platform = process.platform) {
|
|
|
142
143
|
* @returns absolute path to the installed distribution.
|
|
143
144
|
*/
|
|
144
145
|
export function resolveDistributionDirectory(anchor) {
|
|
146
|
+
const ownDirectory = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
145
147
|
let resolved;
|
|
146
148
|
try {
|
|
147
149
|
resolved = dirname(createRequire(anchor).resolve('@sparkelf/dsh-plus/package.json'));
|
|
148
150
|
}
|
|
149
151
|
catch {
|
|
150
|
-
|
|
152
|
+
// `npx @sparkelf/dsh-plus ...` runs the CLI from a temporary install, so the consumer
|
|
153
|
+
// tree has no copy to resolve. The running module's own package is the distribution.
|
|
154
|
+
return ownDirectory;
|
|
151
155
|
}
|
|
152
156
|
// A resolution that leaves the consumer tree means the module answered from its own
|
|
153
157
|
// installation, which reports health for a distribution the consumer never installed.
|
|
@@ -163,7 +167,7 @@ export function resolveDistributionDirectory(anchor) {
|
|
|
163
167
|
break;
|
|
164
168
|
current = parent;
|
|
165
169
|
}
|
|
166
|
-
|
|
170
|
+
return ownDirectory;
|
|
167
171
|
}
|
|
168
172
|
export function readDistributionProfile(distributionDirectory) {
|
|
169
173
|
const manifest = requireRecord(JSON.parse(readFileSync(join(distributionDirectory, 'package.json'), 'utf8')), 'Plus distribution manifest');
|
|
@@ -242,7 +246,12 @@ function requireDependencyMap(value, label) {
|
|
|
242
246
|
export function installProfilePackages(paths, consumerDirectory) {
|
|
243
247
|
const consumerModules = join(consumerDirectory, 'node_modules');
|
|
244
248
|
if (!existsSync(consumerModules)) {
|
|
245
|
-
|
|
249
|
+
// `npx @sparkelf/dsh-plus` runs from a temporary package tree that has no launcher
|
|
250
|
+
// beside it. The profile installs its own tree, so there is nothing to link from
|
|
251
|
+
// the caller; only the profile's packages matter.
|
|
252
|
+
installWithRegistryFallback(paths);
|
|
253
|
+
alignReplacedPackageNames(join(paths.profileDirectory, 'node_modules'));
|
|
254
|
+
return;
|
|
246
255
|
}
|
|
247
256
|
const profileModules = join(paths.profileDirectory, 'node_modules');
|
|
248
257
|
if (existsSync(profileModules)) {
|
|
@@ -267,6 +276,11 @@ export function installProfilePackages(paths, consumerDirectory) {
|
|
|
267
276
|
function installWithRegistryFallback(paths) {
|
|
268
277
|
const registries = registryOrder();
|
|
269
278
|
for (const [index, registry] of registries.entries()) {
|
|
279
|
+
// A lockfile written against the previous registry keeps its resolved URLs, so the
|
|
280
|
+
// second attempt would fetch from the registry that just failed. Drop it and resolve
|
|
281
|
+
// against the registry being tried.
|
|
282
|
+
if (index > 0)
|
|
283
|
+
rmSync(join(paths.profileDirectory, 'pnpm-lock.yaml'), { force: true });
|
|
270
284
|
const result = spawnSync('pnpm', ['install', '--no-frozen-lockfile', '--registry', registry], {
|
|
271
285
|
cwd: paths.profileDirectory,
|
|
272
286
|
stdio: 'inherit',
|
|
@@ -336,8 +350,12 @@ const MAINLAND_REGISTRY = 'https://registry.npmmirror.com';
|
|
|
336
350
|
*/
|
|
337
351
|
export function registryOrder() {
|
|
338
352
|
const configured = process.env.DSH_PLUS_INSTALL_REGISTRY;
|
|
339
|
-
if (configured !== undefined && configured !== '')
|
|
340
|
-
|
|
353
|
+
if (configured !== undefined && configured !== '') {
|
|
354
|
+
// The fallback must be the other registry, not the configured one again: an override
|
|
355
|
+
// set to the mirror used to fall back to the same mirror and fail twice.
|
|
356
|
+
const fallback = configured === MAINLAND_REGISTRY ? OFFICIAL_REGISTRY : MAINLAND_REGISTRY;
|
|
357
|
+
return [configured, fallback];
|
|
358
|
+
}
|
|
341
359
|
// Intl reports the system locale on every platform. The POSIX variables are empty on
|
|
342
360
|
// Windows, so reading them alone classified every Windows console as non-mainland and
|
|
343
361
|
// reached the origin first — measured in a consumer's log, which showed npmjs failing
|
|
@@ -466,17 +484,98 @@ export function ensureProfile(paths, consumerDirectory, edition) {
|
|
|
466
484
|
throw new Error('unknown edition "' + edition + '"; this release offers '
|
|
467
485
|
+ (offered.length === 0 ? '(none)' : offered.join(', ')));
|
|
468
486
|
}
|
|
469
|
-
|
|
470
|
-
|
|
487
|
+
// An edition lists only third-party, fork, and self-developed plugins. The official
|
|
488
|
+
// runtime is the CLI's responsibility and must not be duplicated in that list.
|
|
489
|
+
for (const name of Object.keys(composition?.packages ?? {})) {
|
|
490
|
+
if (name.startsWith('@deepseek-ai/')) {
|
|
491
|
+
throw new Error('edition "' + String(edition) + '" lists the official package ' + name
|
|
492
|
+
+ '; editions contain only third-party or self-developed plugins');
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
const runtime = distribution.dshRange.replace(/^>=?/u, '');
|
|
496
|
+
const baseBundles = composition === undefined
|
|
497
|
+
? distribution.bundles
|
|
498
|
+
: distribution.bundles.filter(bundle => bundle.startsWith('@deepseek-ai/') || bundle === '@sparkelf/dsh-plus');
|
|
499
|
+
const basePackages = composition === undefined
|
|
500
|
+
? distribution.dependencies
|
|
501
|
+
: {
|
|
502
|
+
'@deepseek-ai/dsh': distribution.dshRange,
|
|
503
|
+
'@sparkelf/dsh-plus': distribution.version,
|
|
504
|
+
// `dsh-app-boot` declares its launcher as peer dependencies, and pnpm does not
|
|
505
|
+
// install a profile's transitive peers. Without these the boot loader resolves
|
|
506
|
+
// `@deepseek-ai/cordis-plugin-group` and fails before any plugin mounts.
|
|
507
|
+
'@deepseek-ai/cordis': '^4.0.6-alpha.1',
|
|
508
|
+
'@deepseek-ai/cordis-plugin-group': '^1.0.6-alpha.1',
|
|
509
|
+
'@deepseek-ai/cordis-plugin-include': '^1.0.11-alpha.1',
|
|
510
|
+
'@deepseek-ai/cordis-plugin-loader': '^1.0.7-alpha.1',
|
|
511
|
+
'@deepseek-ai/dsh-home-paths': runtime,
|
|
512
|
+
'@deepseek-ai/dsh-launch-environment': runtime,
|
|
513
|
+
// `dsh-session` / `dsh-tools` declare the rest of the runtime as peers; pnpm leaves
|
|
514
|
+
// them out of a profile install for the same reason as the launcher peers above.
|
|
515
|
+
'@deepseek-ai/dsh-agent': runtime,
|
|
516
|
+
'@deepseek-ai/dsh-llm': runtime,
|
|
517
|
+
'@deepseek-ai/dsh-scope': runtime,
|
|
518
|
+
'@deepseek-ai/dsh-session': runtime,
|
|
519
|
+
'@deepseek-ai/dsh-system-prompt': runtime,
|
|
520
|
+
'@deepseek-ai/dsh-user-approval': runtime,
|
|
521
|
+
// Capability packages that the official plugins import but declare only as peers.
|
|
522
|
+
// A profile install leaves them out and boot then fails inside an otherwise
|
|
523
|
+
// healthy plugin's import with ERR_MODULE_NOT_FOUND.
|
|
524
|
+
'@deepseek-ai/dsh-attachment': runtime,
|
|
525
|
+
'@deepseek-ai/dsh-compaction': runtime,
|
|
526
|
+
'@deepseek-ai/dsh-fs': runtime,
|
|
527
|
+
'@deepseek-ai/dsh-shell': runtime,
|
|
528
|
+
'@deepseek-ai/dsh-spill': runtime,
|
|
529
|
+
'@deepseek-ai/dsh-sandbox': runtime,
|
|
530
|
+
'@deepseek-ai/dsh-ptc-runtime': runtime,
|
|
531
|
+
'@deepseek-ai/dsh-llm-deepseek': runtime,
|
|
532
|
+
'@deepseek-ai/dsh-deepseek-account': runtime,
|
|
533
|
+
'@deepseek-ai/dsh-anonymous-user-id': runtime,
|
|
534
|
+
'@deepseek-ai/dsh-bash-local': runtime,
|
|
535
|
+
'@deepseek-ai/dsh-client-store': runtime,
|
|
536
|
+
'@deepseek-ai/dsh-jobs': runtime,
|
|
537
|
+
'@deepseek-ai/dsh-sdk-protocol': runtime,
|
|
538
|
+
'@deepseek-ai/dsh-session-persistence': runtime,
|
|
539
|
+
'@deepseek-ai/dsh-session-telemetry': runtime,
|
|
540
|
+
'@deepseek-ai/dsh-session-title-llm': runtime,
|
|
541
|
+
'@deepseek-ai/dsh-util-workspace-path': runtime,
|
|
542
|
+
'@deepseek-ai/dsh-workflow': runtime,
|
|
543
|
+
...Object.fromEntries(baseBundles
|
|
544
|
+
.filter(bundle => bundle.startsWith('@deepseek-ai/dsh-'))
|
|
545
|
+
.map(bundle => [bundle, runtime])),
|
|
546
|
+
};
|
|
547
|
+
const compositionPackages = composition === undefined
|
|
548
|
+
? basePackages
|
|
549
|
+
: { ...basePackages, ...composition.packages };
|
|
550
|
+
// Official cordis rows name the historical unscoped packages. The fork ships under
|
|
551
|
+
// `@sparkelf/*`, so the row would fail to resolve unless the profile also carries the
|
|
552
|
+
// historical name as an alias to the same version.
|
|
553
|
+
const rowAliases = {
|
|
554
|
+
'dsh-better-sidebar': '@sparkelf/dsh-better-sidebar',
|
|
555
|
+
'dsh-sql-workbench': '@sparkelf/dsh-sql-workbench',
|
|
556
|
+
};
|
|
557
|
+
for (const [alias, target] of Object.entries(rowAliases)) {
|
|
558
|
+
const spec = compositionPackages[target];
|
|
559
|
+
if (spec !== undefined && compositionPackages[alias] === undefined) {
|
|
560
|
+
compositionPackages[alias] = 'npm:' + target + '@' + spec;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
const compositionBundles = composition === undefined
|
|
564
|
+
? baseBundles
|
|
565
|
+
: [...baseBundles, ...composition.bundles];
|
|
471
566
|
if (existsSync(manifestPath)) {
|
|
472
567
|
// A selected edition is an explicit install choice, so its packages and bundle order
|
|
473
568
|
// replace the profile's rather than being ignored. Other profile decisions stay.
|
|
474
569
|
if (composition !== undefined) {
|
|
475
570
|
const manifest = requireRecord(JSON.parse(readFileSync(manifestPath, 'utf8')), 'Plus profile manifest');
|
|
476
|
-
manifest.dependencies = { ...manifest.dependencies, ...
|
|
571
|
+
manifest.dependencies = { ...manifest.dependencies, ...compositionPackages };
|
|
477
572
|
manifest.dsh = {
|
|
478
573
|
...manifest.dsh,
|
|
479
|
-
profile: {
|
|
574
|
+
profile: {
|
|
575
|
+
...manifest.dsh?.profile,
|
|
576
|
+
bundles: [...compositionBundles],
|
|
577
|
+
...(edition === undefined ? {} : { plusEdition: edition }),
|
|
578
|
+
},
|
|
480
579
|
};
|
|
481
580
|
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
|
|
482
581
|
}
|
|
@@ -493,19 +592,12 @@ export function ensureProfile(paths, consumerDirectory, edition) {
|
|
|
493
592
|
name: 'dsh-profile-' + STANDALONE_PROFILE,
|
|
494
593
|
private: true,
|
|
495
594
|
type: 'module',
|
|
496
|
-
dependencies:
|
|
497
|
-
'@sparkelf/dsh-plus': distribution.version,
|
|
498
|
-
// The launcher's own tree supplies every service package the bundles mount. A
|
|
499
|
-
// profile that lists only the distribution's plugins installs a partial tree and
|
|
500
|
-
// fails at load with a module the launcher would have carried.
|
|
501
|
-
'@deepseek-ai/dsh': distribution.dshRange,
|
|
502
|
-
...distribution.dependencies,
|
|
503
|
-
...editionPackages,
|
|
504
|
-
},
|
|
595
|
+
dependencies: compositionPackages,
|
|
505
596
|
dsh: {
|
|
506
597
|
profile: {
|
|
507
|
-
bundles: [...
|
|
598
|
+
bundles: [...compositionBundles],
|
|
508
599
|
patchReload: 'live',
|
|
600
|
+
...(edition === undefined ? {} : { plusEdition: edition }),
|
|
509
601
|
},
|
|
510
602
|
},
|
|
511
603
|
};
|
|
@@ -550,7 +642,7 @@ function writeProfileOverrides(profileDirectory, overrides, allowBuilds, omitted
|
|
|
550
642
|
if (document.get('nodeLinker') === undefined)
|
|
551
643
|
document.set('nodeLinker', 'hoisted');
|
|
552
644
|
if (document.get('autoInstallPeers') === undefined)
|
|
553
|
-
document.set('autoInstallPeers',
|
|
645
|
+
document.set('autoInstallPeers', true);
|
|
554
646
|
writeFileSync(workspacePath, String(document));
|
|
555
647
|
}
|
|
556
648
|
/** Run git in one directory, returning undefined instead of throwing when asked to. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sparkelf/dsh-plus",
|
|
3
3
|
"description": "DeepSeek Harness Plus official-base Web distribution profile and ranged compatibility patchset",
|
|
4
|
-
"version": "0.2.2-alpha.2.
|
|
4
|
+
"version": "0.2.2-alpha.2.10",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -132,7 +132,8 @@
|
|
|
132
132
|
"@deepseek-ai/dsh-client-ui-schedule": "npm:@sparkelf/dsh-client-ui-schedule@0.2.2-alpha.2",
|
|
133
133
|
"@deepseek-ai/dsh-client-ui-sidebar-right": "npm:@sparkelf/dsh-client-ui-sidebar-right@0.2.2-alpha.2",
|
|
134
134
|
"@deepseek-ai/dsh-atomic-write": "npm:@sparkelf/dsh-atomic-write@0.2.2-alpha.2",
|
|
135
|
-
"@deepseek-ai/dsh-tool-executor-ptc": "npm:@sparkelf/dsh-tool-executor-ptc@0.2.2-alpha.2"
|
|
135
|
+
"@deepseek-ai/dsh-tool-executor-ptc": "npm:@sparkelf/dsh-tool-executor-ptc@0.2.2-alpha.2",
|
|
136
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.2-alpha.2"
|
|
136
137
|
},
|
|
137
138
|
"standaloneVariants": {
|
|
138
139
|
"dataops": {
|
|
@@ -553,20 +554,15 @@
|
|
|
553
554
|
"personal": {
|
|
554
555
|
"label": "个人版",
|
|
555
556
|
"bundles": [
|
|
556
|
-
"@deepseek-ai/dsh-base",
|
|
557
|
-
"@deepseek-ai/dsh-experimental-agent-team-profile",
|
|
558
|
-
"@deepseek-ai/dsh-web-app",
|
|
559
|
-
"@deepseek-ai/dsh-experimental-auto-review",
|
|
560
557
|
"@sparkelf/dsh-mineru",
|
|
561
558
|
"@sparkelf/dsh-officecli",
|
|
562
559
|
"dshmarket",
|
|
563
|
-
"dsh-better-sidebar",
|
|
560
|
+
"@sparkelf/dsh-better-sidebar",
|
|
564
561
|
"@sparkelf/dsh-office-viewer-fonts",
|
|
565
562
|
"dsh-video-preview",
|
|
566
563
|
"@sparkelf/dsh-genui",
|
|
567
564
|
"@sparkelf/dsh-plugin-supervisor",
|
|
568
|
-
"@sparkelf/dsh-
|
|
569
|
-
"dsh-sql-workbench",
|
|
565
|
+
"@sparkelf/dsh-sql-workbench",
|
|
570
566
|
"@sparkelf/dsh-ssh-manager",
|
|
571
567
|
"@sparkelf/dsh-api-client",
|
|
572
568
|
"dsh-right-bg-anim",
|
|
@@ -575,89 +571,71 @@
|
|
|
575
571
|
"@sparkelf/dsh-client-ui-diagram-viewer"
|
|
576
572
|
],
|
|
577
573
|
"packages": {
|
|
578
|
-
"@deepseek-ai/dsh": "0.2.2-alpha.2",
|
|
579
|
-
"@deepseek-ai/dsh-base": "0.2.2-alpha.2",
|
|
580
|
-
"@deepseek-ai/dsh-web-app": "0.2.2-alpha.2",
|
|
581
|
-
"@sparkelf/dsh-plus": "0.2.2-alpha.2.1",
|
|
582
574
|
"@sparkelf/dsh-mineru": "0.1.4",
|
|
583
575
|
"@sparkelf/dsh-officecli": "0.1.4",
|
|
584
576
|
"@sparkelf/dsh-plugin-supervisor": "0.1.9",
|
|
585
|
-
"dsh-sql-workbench": "0.5.3",
|
|
586
577
|
"@sparkelf/dsh-workbench-vault": "0.1.2",
|
|
587
|
-
"@sparkelf/dsh-ssh-manager": "0.7.
|
|
578
|
+
"@sparkelf/dsh-ssh-manager": "0.7.5",
|
|
588
579
|
"@sparkelf/dsh-api-client": "0.5.3",
|
|
589
|
-
"dsh-
|
|
590
|
-
"@sparkelf/dsh-office-viewer-fonts": "0.1.5",
|
|
580
|
+
"@sparkelf/dsh-office-viewer-fonts": "0.1.6",
|
|
591
581
|
"dsh-video-preview": "0.1.4",
|
|
592
582
|
"dsh-right-bg-anim": "1.1.0",
|
|
593
|
-
"@deepseek-ai/dsh-experimental-agent-team-profile": ">=0.2.2-alpha.2",
|
|
594
583
|
"@sparkelf/dsh-mobile-bridge": "0.2.18",
|
|
595
584
|
"@sparkelf/dsh-quant": "0.91.0-sparkelf.13",
|
|
596
|
-
"@
|
|
597
|
-
"@sparkelf/dsh-
|
|
598
|
-
"@sparkelf/dsh-
|
|
585
|
+
"@sparkelf/dsh-genui": "0.15.0-sparkelf.1",
|
|
586
|
+
"@sparkelf/dsh-client-ui-diagram-viewer": "0.2.1-alpha.28",
|
|
587
|
+
"@sparkelf/dsh-sql-workbench": "0.5.4-sparkelf.1",
|
|
588
|
+
"@sparkelf/dsh-better-sidebar": "0.29.0-sparkelf.2"
|
|
599
589
|
}
|
|
600
590
|
},
|
|
601
591
|
"team": {
|
|
602
592
|
"label": "团队版",
|
|
603
593
|
"bundles": [
|
|
604
|
-
"@deepseek-ai/dsh-base",
|
|
605
|
-
"@deepseek-ai/dsh-experimental-agent-team-profile",
|
|
606
|
-
"@deepseek-ai/dsh-web-app",
|
|
607
|
-
"@deepseek-ai/dsh-experimental-auto-review",
|
|
608
594
|
"@sparkelf/dsh-mineru",
|
|
609
595
|
"@sparkelf/dsh-officecli",
|
|
610
596
|
"dshmarket",
|
|
611
|
-
"dsh-better-sidebar",
|
|
612
597
|
"@sparkelf/dsh-office-viewer-fonts",
|
|
613
598
|
"@sparkelf/dsh-genui",
|
|
614
599
|
"@sparkelf/dsh-plugin-supervisor",
|
|
615
|
-
"@sparkelf/dsh-
|
|
616
|
-
"dsh-sql-workbench",
|
|
600
|
+
"@sparkelf/dsh-sql-workbench",
|
|
617
601
|
"@sparkelf/dsh-ssh-manager",
|
|
618
602
|
"@sparkelf/dsh-api-client",
|
|
619
603
|
"dsh-right-bg-anim",
|
|
620
604
|
"@sparkelf/dsh-client-ui-diagram-viewer",
|
|
621
605
|
"@sparkelf/dsh-dataops-managed",
|
|
622
606
|
"@sparkelf/dsh-query-result-analysis",
|
|
623
|
-
"@sparkelf/dsh-
|
|
607
|
+
"@sparkelf/dsh-better-sidebar",
|
|
624
608
|
"@sparkelf/dsh-credential-manager",
|
|
609
|
+
"@sparkelf/dsh-knowledge-base",
|
|
625
610
|
"@sparkelf/dsh-group-chat",
|
|
611
|
+
"@sparkelf/dsh-ocr",
|
|
612
|
+
"@sparkelf/dsh-dataops-account",
|
|
626
613
|
"@sparkelf/dsh-kb-citation",
|
|
627
614
|
"@sparkelf/dsh-task-bus"
|
|
628
615
|
],
|
|
629
616
|
"packages": {
|
|
630
|
-
"@
|
|
631
|
-
"@sparkelf/dsh-
|
|
617
|
+
"@sparkelf/dsh-api-client": "0.5.3",
|
|
618
|
+
"@sparkelf/dsh-client-ui-diagram-viewer": "0.2.1-alpha.28",
|
|
619
|
+
"@sparkelf/dsh-dataops-managed": "0.3.21",
|
|
620
|
+
"@sparkelf/dsh-genui": "0.15.0-sparkelf.1",
|
|
621
|
+
"@sparkelf/dsh-knowledge-base": "0.1.21",
|
|
632
622
|
"@sparkelf/dsh-mineru": "0.1.4",
|
|
623
|
+
"@sparkelf/dsh-office-viewer-fonts": "0.1.6",
|
|
633
624
|
"@sparkelf/dsh-officecli": "0.1.4",
|
|
634
625
|
"@sparkelf/dsh-plugin-supervisor": "0.1.9",
|
|
635
|
-
"dsh-
|
|
626
|
+
"@sparkelf/dsh-ssh-manager": "0.7.5",
|
|
636
627
|
"@sparkelf/dsh-workbench-vault": "0.1.2",
|
|
637
|
-
"@sparkelf/dsh-ssh-manager": "0.7.4",
|
|
638
|
-
"@sparkelf/dsh-api-client": "0.5.3",
|
|
639
|
-
"dsh-better-sidebar": "0.28.0",
|
|
640
|
-
"@sparkelf/dsh-office-viewer-fonts": "0.1.5",
|
|
641
628
|
"dsh-right-bg-anim": "1.1.0",
|
|
642
|
-
"@
|
|
643
|
-
"@
|
|
644
|
-
"@sparkelf/dsh-
|
|
645
|
-
"@sparkelf/dsh-client-ui-diagram-viewer": "0.2.1-alpha.28",
|
|
646
|
-
"@deepseek-ai/dsh-tool-session-query": "0.2.2-alpha.2",
|
|
647
|
-
"@sparkelf/dsh-client-ui-skill-center": "0.2.1-rc.2.4",
|
|
648
|
-
"@sparkelf/dsh-image-hoist": ">=0.1.3",
|
|
649
|
-
"@sparkelf/dsh-plugin-backup": "0.2.1-rc.2.4",
|
|
650
|
-
"@sparkelf/dsh-plugin-mcp-credentials": "0.2.1-rc.2.6",
|
|
651
|
-
"dshmarket": ">=1.66.7",
|
|
652
|
-
"semver": ">=7.7.3",
|
|
653
|
-
"yaml": ">=2.9.0",
|
|
654
|
-
"@sparkelf/dsh-dataops-managed": "0.3.21",
|
|
655
|
-
"@sparkelf/dsh-query-result-analysis": "0.1.4",
|
|
656
|
-
"@sparkelf/dsh-knowledge-base": "0.1.21",
|
|
657
|
-
"@sparkelf/dsh-credential-manager": "0.1.0",
|
|
629
|
+
"@sparkelf/dsh-task-bus": "0.1.0",
|
|
630
|
+
"@sparkelf/dsh-credential-manager": "0.1.1",
|
|
631
|
+
"@sparkelf/dsh-dataops-account": "0.2.0",
|
|
658
632
|
"@sparkelf/dsh-group-chat": "0.5.1",
|
|
659
633
|
"@sparkelf/dsh-kb-citation": "0.1.3",
|
|
660
|
-
"@sparkelf/dsh-
|
|
634
|
+
"@sparkelf/dsh-ocr": "0.1.0",
|
|
635
|
+
"@sparkelf/dsh-query-result-analysis": "0.1.4",
|
|
636
|
+
"@sparkelf/dsh-better-sidebar": "0.29.0-sparkelf.3",
|
|
637
|
+
"dsh-video-preview": "0.1.4",
|
|
638
|
+
"@sparkelf/dsh-sql-workbench": "0.5.4-sparkelf.1"
|
|
661
639
|
}
|
|
662
640
|
}
|
|
663
641
|
}
|