@deepseek-ai/dsh-app-boot 0.2.1-alpha.3 → 0.2.1-alpha.4
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.i18n.yaml +2 -2
- package/README.md +2 -2
- package/README.zh.md +2 -2
- package/lib/index.js +40 -26
- package/lib/types/plugin-compatibility.d.ts +11 -10
- package/lib/types/profile.d.ts +2 -2
- package/package.json +8 -8
package/README.i18n.yaml
CHANGED
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
en: 4a424cd401556f20
|
|
25
25
|
zh: 0b34dd18e0db6cea
|
|
26
26
|
/deepseek-ai-dsh-app-boot/use-this-package/profiles:
|
|
27
|
-
en:
|
|
28
|
-
zh:
|
|
27
|
+
en: d2d520668668292c
|
|
28
|
+
zh: b7deeab27032a3ad
|
|
29
29
|
/deepseek-ai-dsh-app-boot/use-this-package/previewing-the-effective-configuration:
|
|
30
30
|
en: 646a0ccdd7881ad1
|
|
31
31
|
zh: e3696acb1573dd7b
|
package/README.md
CHANGED
|
@@ -49,9 +49,9 @@ Import profile and bundle declaration types from [`@deepseek-ai/dsh-package-mani
|
|
|
49
49
|
|
|
50
50
|
A profile is how one dsh installation ships different app surfaces: `web`, `headless`, `acp`, `sdk`, and `sdk-minimal` start distinct compositions from the same launcher. A profile lives at `$DSH_HOME/profiles/<name>` and combines installable bundles with its own `cordis.patch.yml`. A bundle's `dsh.bundle.patch` names one patch file or an ordered list of files; `bundlePatchFiles` validates the declaration and `bundlePatchPaths` resolves it to absolute paths; the layer concatenates their patch lists in that order. The YAML composition enables or disables HMR. The shipped `web` template uses live reload, while the other shipped templates apply patches only at startup. `sdk-minimal` names only its standalone bundle; the other templates retain base-plus-mode stacks. `dsh --profile <name> --from-default-profile <template>` creates or replaces a custom profile at a non-shipped name from one shipped template, while `dsh plugin` initializes a base-backed profile and manages its installed bundles. Bundle resolution, manifest, and patch-loading failures skip that bundle without changing its selection; the loaded profile lists each skip in `skippedBundles`, and the launcher prints them once per start with `reportSkippedBundles`. Remaining bundles keep their order; profile and user-patch errors still fail startup. Skipping a bundle does not guarantee that the remaining composition can provide the required services. Application-owned npm projects, such as Electron's reserved Desktop profile, use `loadProfileDirectory` to load an already initialized directory without exposing it through CLI profile lookup.
|
|
51
51
|
|
|
52
|
-
Before a profile imports a plugin, DSH checks its
|
|
52
|
+
Before a profile imports a plugin, DSH checks its declared DSH requirement against the single runtime version returned by `getDshRuntimeVersion()`. When the manifest declares `engines.dsh`, that range alone decides and `peerDependencies` are ignored. Otherwise every `peerDependencies` range on `@deepseek-ai/dsh` and `@deepseek-ai/dsh-*` must match, and source-workspace `workspace:^`, `workspace:~`, and `workspace:*` peers refer to that same runtime. Prereleases participate in range matching. A manifest with neither declaration imposes no constraint; empty or invalid ranges, including a `workspace:` value in `engines.dsh`, are incompatible. A non-object `engines` or a non-string `engines.dsh` is a malformed manifest. A refusal names the unmet requirements, keyed `engines.dsh` or by peer package name. These checks are not a sandbox against malicious package code.
|
|
53
53
|
|
|
54
|
-
Admission happens only at composition boundaries DSH owns, and a denied row is denied in the launcher's own copy of the composition: no profile patch layer, dependency manifest, or bundle list changes. `prepareProfilePatches` composes over the launcher's empty profile root and runs while the root Include is mounted and on every profile recomposition, so a denied plugin never imports its module. `prepareProfileEntries` does the same for a preset's rows. A denied ordinary row becomes a detached `disabled: true` row; a native group stays mounted and its denied children do not load; a native Include that reaches a denied plugin is omitted whole, because its file is never rewritten. A row denied by policy keeps its configured `disabled` value in the profile, and every refusal is reported with the package, versions, and risk. A bundle is not a row, so `loadProfileDirectory` checks each bundle's own DSH
|
|
54
|
+
Admission happens only at composition boundaries DSH owns, and a denied row is denied in the launcher's own copy of the composition: no profile patch layer, dependency manifest, or bundle list changes. `prepareProfilePatches` composes over the launcher's empty profile root and runs while the root Include is mounted and on every profile recomposition, so a denied plugin never imports its module. `prepareProfileEntries` does the same for a preset's rows. A denied ordinary row becomes a detached `disabled: true` row; a native group stays mounted and its denied children do not load; a native Include that reaches a denied plugin is omitted whole, because its file is never rewritten. A row denied by policy keeps its configured `disabled` value in the profile, and every refusal is reported with the package, versions, and risk. A bundle is not a row, so `loadProfileDirectory` checks each bundle's own DSH requirement when it loads the profile's bundle layers, at startup and on every recomposition; an incompatible bundle without an exemption is skipped like an unreadable one and listed in `skippedBundles`. These boundaries do not cover plugins another embedder mounts through its own `ctx.plugin` call. Two edits made directly to files during a session are judged only at the next recomposition or startup: a running plugin's own `package.json` DSH requirement, and an entry-list file the Loader reads itself, such as the launcher's root config or a nested `cordis:include` file. `--dump-config` reports the configured composition, so a denied plugin row still appears there while a denied bundle contributes no rows, and `--dump-config-schema` imports each composed module to read its schema; run it only against a profile whose plugins you already trust.
|
|
55
55
|
|
|
56
56
|
Exact-version exemptions live in the profile's own `compatibility.json`, not in its `package.json`, so an exemption write never touches the dependency manifest, the bundle list, or Cordis patch files. It maps exact `package-name@version` keys to lists of exact DSH runtime versions; neither a plugin upgrade nor a DSH upgrade inherits permission. A missing file means no exemptions. A malformed one never stops the profile from starting: records the reader accepts still apply, each rejected record is reported on stderr beside the plugin denials, and the file is then treated as read-only, so a grant or revocation refuses and asks the user to repair it by hand instead of overwriting their content. [Plugin Manager](../plugin-manager/README.md#version-compatibility-and-exemptions) owns the grant, revocation, and risk confirmation each change requires.
|
|
57
57
|
|
package/README.zh.md
CHANGED
|
@@ -49,9 +49,9 @@ Profile 与组合包的声明类型从 [`@deepseek-ai/dsh-package-manifest`](../
|
|
|
49
49
|
|
|
50
50
|
profile 是同一套 dsh 安装提供不同应用界面的方式:`web`、`headless`、`acp`、`sdk` 与 `sdk-minimal` 从同一 launcher 启动不同组合。profile 位于 `$DSH_HOME/profiles/<name>`,由可安装组合包和自身 `cordis.patch.yml` 组成。组合包的 `dsh.bundle.patch` 指定一个 patch 文件或一个有序的文件列表;`bundlePatchFiles` 校验该声明,`bundlePatchPaths` 把它解析为绝对路径;该层按此顺序拼接各文件的 patch 列表。YAML 组合决定是否启用 HMR。随产品交付的 `web` 模板实时重载,其他随附模板只在启动时应用 patch。`sdk-minimal` 只列出自身的独立组合包,其他模板保留 base 加模式的组合包栈。`dsh --profile <name> --from-default-profile <template>` 从一个随附模板,在非内置名称处创建或替换自定义 profile;`dsh plugin` 则初始化以 base 为基础的 profile,并管理其中安装的组合包。组合包解析、manifest 读取或 patch 加载失败时会跳过该组合包,不改变其选择状态;加载结果在 `skippedBundles` 中列出每个被跳过的组合包,启动器每次启动时通过 `reportSkippedBundles` 输出一次。其余组合包保持原顺序;profile 和用户 patch 错误仍会导致启动失败。跳过组合包不保证剩余组合能够提供所需服务。由应用持有的 npm 项目(例如 Electron 保留的 Desktop profile)通过 `loadProfileDirectory` 加载已经初始化的目录,而不会将它暴露给 CLI profile 查找。
|
|
51
51
|
|
|
52
|
-
profile 导入插件前,DSH
|
|
52
|
+
profile 导入插件前,DSH 会将其声明的 DSH 版本要求与 `getDshRuntimeVersion()` 返回的唯一运行时版本比较。清单声明了 `engines.dsh` 时,只由该范围决定,忽略 `peerDependencies`。否则 `peerDependencies` 中对 `@deepseek-ai/dsh` 和 `@deepseek-ai/dsh-*` 的每个范围都必须匹配,源码工作区的 `workspace:^`、`workspace:~` 和 `workspace:*` peer 指向同一个运行时。预发布版本参与范围匹配。两者都未声明时不施加版本约束;空范围或无效范围视为不兼容,`engines.dsh` 中的 `workspace:` 值也属于无效范围。`engines` 不是对象或 `engines.dsh` 不是字符串时,清单视为格式错误。拒绝结果会列出未满足的要求,键为 `engines.dsh` 或 peer 包名。这些检查不是防范恶意包代码的沙箱。
|
|
53
53
|
|
|
54
|
-
检查只发生在 DSH 自己持有的组合入口,改写的是启动器自己的那份组合:profile 的 patch 层、依赖清单与组合包列表都不会改变。`prepareProfilePatches` 在启动器的空 profile 根之上组合,并在挂载根 Include 时以及每次 profile 重新组合时执行,因此被拒绝的插件永远不会导入其模块;`prepareProfileEntries` 对 preset 行做同样的事。被拒绝的普通行会变成游离的 `disabled: true` 行;原生 group 保持挂载,其被拒绝的子行不会加载;若某个原生 Include 会到达被拒绝的插件,则整体省略该 Include,因为它的文件不会被改写。被策略拒绝的行在 profile 中保留其配置的 `disabled` 值,每次拒绝都会报告包名、版本与风险。组合包本身不是行,因此 `loadProfileDirectory` 在启动和每次重新组合加载 profile 的组合包层时,检查每个组合包自己声明的 DSH
|
|
54
|
+
检查只发生在 DSH 自己持有的组合入口,改写的是启动器自己的那份组合:profile 的 patch 层、依赖清单与组合包列表都不会改变。`prepareProfilePatches` 在启动器的空 profile 根之上组合,并在挂载根 Include 时以及每次 profile 重新组合时执行,因此被拒绝的插件永远不会导入其模块;`prepareProfileEntries` 对 preset 行做同样的事。被拒绝的普通行会变成游离的 `disabled: true` 行;原生 group 保持挂载,其被拒绝的子行不会加载;若某个原生 Include 会到达被拒绝的插件,则整体省略该 Include,因为它的文件不会被改写。被策略拒绝的行在 profile 中保留其配置的 `disabled` 值,每次拒绝都会报告包名、版本与风险。组合包本身不是行,因此 `loadProfileDirectory` 在启动和每次重新组合加载 profile 的组合包层时,检查每个组合包自己声明的 DSH 版本要求;没有豁免的不兼容组合包会像无法读取的组合包一样被跳过,并列入 `skippedBundles`。这些入口不覆盖其他嵌入方通过自己的 `ctx.plugin` 调用挂载的插件。会话中直接改文件的两类编辑只在下一次重新组合或启动时才被判定:正在运行的插件自己的 `package.json` DSH 版本要求,以及 Loader 自己读取的入口清单文件(如启动器的根配置或嵌套的 `cordis:include` 文件)。`--dump-config` 报告的是配置出的组合,因此被拒绝的插件行仍会出现在其中,而被拒绝的组合包不提供任何行;`--dump-config-schema` 会导入每个组合模块以读取其 schema,请只对已经信任其插件的 profile 运行。
|
|
55
55
|
|
|
56
56
|
精确版本豁免保存在 profile 自己的 `compatibility.json` 中,而不是 `package.json`,因此写豁免不会触及依赖清单、组合包列表或 Cordis patch 文件。它把精确的 `package-name@version` 键映射到精确 DSH 运行时版本列表;插件升级和 DSH 升级都不继承授权。文件缺失表示没有豁免。文件损坏绝不会阻止 profile 启动:读取器接受的记录仍然生效,每条被拒绝的记录会与插件拒绝信息一起输出到 stderr,此后该文件被视为只读,因此授予或撤销会拒绝执行并要求用户手工修复,而不是覆盖用户的内容。[插件管理器](../plugin-manager/README.zh.md#version-compatibility-and-exemptions)负责每次变更所需的授权、撤销与风险确认。
|
|
57
57
|
|
package/lib/index.js
CHANGED
|
@@ -249,7 +249,7 @@ var Include = class extends EntryTree {
|
|
|
249
249
|
};
|
|
250
250
|
//#endregion
|
|
251
251
|
//#region lib/types/plugin-compatibility.js
|
|
252
|
-
/** Evaluate plugin dsh
|
|
252
|
+
/** Evaluate plugin dsh requirements (`engines.dsh`, else dsh peers) without importing plugin code. */
|
|
253
253
|
function objectOf$1(value, field) {
|
|
254
254
|
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new Error(`${field} must be an object`);
|
|
255
255
|
return value;
|
|
@@ -260,7 +260,7 @@ function runtimeVersionOf(value) {
|
|
|
260
260
|
}
|
|
261
261
|
function identityField(manifest, field) {
|
|
262
262
|
const value = Object.hasOwn(manifest, field) ? manifest[field] : void 0;
|
|
263
|
-
if (typeof value !== "string" || value.trim() === "") throw new Error(`Plugin manifest ${field} must be a non-empty string when dsh
|
|
263
|
+
if (typeof value !== "string" || value.trim() === "") throw new Error(`Plugin manifest ${field} must be a non-empty string when dsh requirements are unmet`);
|
|
264
264
|
return value;
|
|
265
265
|
}
|
|
266
266
|
/**
|
|
@@ -273,33 +273,46 @@ function getDshRuntimeVersion() {
|
|
|
273
273
|
const manifest = objectOf$1(JSON.parse(fs.readFileSync(filename, "utf8")), "app-boot package.json");
|
|
274
274
|
return runtimeVersionOf(Object.hasOwn(manifest, "version") ? manifest.version : void 0);
|
|
275
275
|
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
runtimeVersionOf(runtimeVersion);
|
|
288
|
-
const fields = objectOf$1(manifest, "Plugin manifest");
|
|
289
|
-
if (!Object.hasOwn(fields, "peerDependencies")) return void 0;
|
|
276
|
+
function satisfies(runtimeVersion, range) {
|
|
277
|
+
return range.trim() !== "" && semver.satisfies(runtimeVersion, range, { includePrerelease: true });
|
|
278
|
+
}
|
|
279
|
+
function unmetRequirements(fields, runtimeVersion) {
|
|
280
|
+
const engines = Object.hasOwn(fields, "engines") ? objectOf$1(fields.engines, "Plugin manifest engines") : {};
|
|
281
|
+
if (Object.hasOwn(engines, "dsh")) {
|
|
282
|
+
const range = engines.dsh;
|
|
283
|
+
if (typeof range !== "string") throw new Error("Plugin manifest engines.dsh must be a string");
|
|
284
|
+
return satisfies(runtimeVersion, range) ? {} : { "engines.dsh": range };
|
|
285
|
+
}
|
|
286
|
+
if (!Object.hasOwn(fields, "peerDependencies")) return {};
|
|
290
287
|
const dependencies = objectOf$1(fields.peerDependencies, "Plugin manifest peerDependencies");
|
|
291
|
-
const
|
|
288
|
+
const unmet = {};
|
|
292
289
|
for (const [name, range] of Object.entries(dependencies)) {
|
|
293
290
|
if (typeof range !== "string") throw new Error(`Plugin manifest peerDependencies[${JSON.stringify(name)}] must be a string`);
|
|
294
291
|
if (name !== "@deepseek-ai/dsh" && !name.startsWith("@deepseek-ai/dsh-")) continue;
|
|
295
|
-
|
|
292
|
+
if (!satisfies(runtimeVersion, [
|
|
296
293
|
"workspace:^",
|
|
297
294
|
"workspace:~",
|
|
298
295
|
"workspace:*"
|
|
299
|
-
].includes(range) ? runtimeVersion : range;
|
|
300
|
-
if (requirement.trim() === "" || !semver.satisfies(runtimeVersion, requirement, { includePrerelease: true })) peers[name] = range;
|
|
296
|
+
].includes(range) ? runtimeVersion : range)) unmet[name] = range;
|
|
301
297
|
}
|
|
302
|
-
|
|
298
|
+
return unmet;
|
|
299
|
+
}
|
|
300
|
+
/**
|
|
301
|
+
* Check the plugin's dsh requirements against the runtime. An own `engines.dsh` range decides alone and
|
|
302
|
+
* peerDependencies are ignored; otherwise every @deepseek-ai/dsh or @deepseek-ai/dsh-* peer must match.
|
|
303
|
+
* Prereleases participate in ranges. For peers only, workspace:^, workspace:~, and workspace:* refer to
|
|
304
|
+
* the current runtime; other empty or invalid ranges, including any workspace: `engines.dsh`, are unmet.
|
|
305
|
+
* @param manifest - parsed plugin package.json; inherited fields are ignored.
|
|
306
|
+
* @param exemptions - exact plugin name@version keys mapped to exact runtime versions.
|
|
307
|
+
* @param runtimeVersion - running dsh version, defaulting to this app-boot package.
|
|
308
|
+
* @returns unmet requirements and exemption status, or undefined when every requirement is met.
|
|
309
|
+
* @throws for malformed manifest engines or peer fields, invalid runtime versions, or missing identity on a mismatch.
|
|
310
|
+
*/
|
|
311
|
+
function evaluatePluginCompatibility(manifest, exemptions = {}, runtimeVersion = getDshRuntimeVersion()) {
|
|
312
|
+
runtimeVersionOf(runtimeVersion);
|
|
313
|
+
const fields = objectOf$1(manifest, "Plugin manifest");
|
|
314
|
+
const requirements = unmetRequirements(fields, runtimeVersion);
|
|
315
|
+
if (Object.keys(requirements).length === 0) return void 0;
|
|
303
316
|
const name = identityField(fields, "name");
|
|
304
317
|
const version = identityField(fields, "version");
|
|
305
318
|
const key = `${name}@${version}`;
|
|
@@ -307,19 +320,19 @@ function evaluatePluginCompatibility(manifest, exemptions = {}, runtimeVersion =
|
|
|
307
320
|
name,
|
|
308
321
|
version,
|
|
309
322
|
runtimeVersion,
|
|
310
|
-
|
|
323
|
+
requirements,
|
|
311
324
|
exempted: (Object.hasOwn(exemptions, key) ? exemptions[key] : void 0)?.includes(runtimeVersion) === true
|
|
312
325
|
};
|
|
313
326
|
}
|
|
314
327
|
/**
|
|
315
|
-
* Describe
|
|
328
|
+
* Describe unmet requirements, their risk, and the exact-version remedy.
|
|
316
329
|
* Surfaces with their own grant mechanism or locale render the structured result themselves.
|
|
317
330
|
* @param issue - incompatible plugin/runtime result, including exempted mismatches.
|
|
318
331
|
* @returns an English diagnostic for logs and stderr.
|
|
319
332
|
*/
|
|
320
333
|
function pluginCompatibilityWarning(issue) {
|
|
321
334
|
const key = `${issue.name}@${issue.version}`;
|
|
322
|
-
return `Plugin ${key} is incompatible with dsh ${issue.runtimeVersion}:
|
|
335
|
+
return `Plugin ${key} is incompatible with dsh ${issue.runtimeVersion}: requirements ${JSON.stringify(issue.requirements)}. Running it may cause crashes or data loss. Update the plugin or install a plugin version compatible with this dsh runtime. To accept this risk explicitly, grant the exact-version exemption for ${key} on dsh ${issue.runtimeVersion} with \`dsh plugin allow-version\` or the plugin manager, then retry the installation or restart dsh. Exact-version exemption: ${issue.exempted ? "active" : "not active"}.`;
|
|
323
336
|
}
|
|
324
337
|
//#endregion
|
|
325
338
|
//#region lib/types/profile-compatibility.js
|
|
@@ -574,6 +587,7 @@ const OPTIONAL_BUNDLES = [
|
|
|
574
587
|
"@deepseek-ai/dsh-experimental-cot-translation-bundle",
|
|
575
588
|
"@deepseek-ai/dsh-experimental-auto-review",
|
|
576
589
|
"@deepseek-ai/dsh-experimental-inspector-profile",
|
|
590
|
+
"@deepseek-ai/dsh-experimental-plugin-market-bundle",
|
|
577
591
|
"@deepseek-ai/dsh-experimental-tool-worktree"
|
|
578
592
|
];
|
|
579
593
|
const PROFILE_PATCH_TEMPLATE = `# Your patch layer for this dsh profile, applied after every bundle layer:
|
|
@@ -990,7 +1004,7 @@ function resolveBundleDir(binName, packageName, installAnchor, profileDir) {
|
|
|
990
1004
|
* the shared Harness home. This is used by application-owned profiles whose
|
|
991
1005
|
* package project and lifecycle belong to that application.
|
|
992
1006
|
* Retired bundles are removed from the stored bundle list first, rewriting the
|
|
993
|
-
* manifest when it listed one. Unreadable bundles, and bundles whose own dsh
|
|
1007
|
+
* manifest when it listed one. Unreadable bundles, and bundles whose own dsh requirements the profile does not exempt, are skipped
|
|
994
1008
|
* without changing the manifest and listed in `skippedBundles`; nothing is printed.
|
|
995
1009
|
* @param binName - the diagnostic prefix on thrown errors.
|
|
996
1010
|
* @param dir - absolute profile package directory.
|
|
@@ -2313,7 +2327,7 @@ function preflight(ctx, entries, parentURL, report) {
|
|
|
2313
2327
|
const issue = evaluatePluginCompatibility(manifest, exemptions);
|
|
2314
2328
|
return issue === void 0 || issue.exempted ? void 0 : pluginCompatibilityWarning(issue);
|
|
2315
2329
|
} catch (error) {
|
|
2316
|
-
return `its declared
|
|
2330
|
+
return `its declared dsh requirements cannot be validated: ${error instanceof Error ? error.message : String(error)}`;
|
|
2317
2331
|
}
|
|
2318
2332
|
};
|
|
2319
2333
|
const deny = (row, reason) => {
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
/** Evaluate plugin dsh
|
|
2
|
-
/**
|
|
1
|
+
/** Evaluate plugin dsh requirements (`engines.dsh`, else dsh peers) without importing plugin code. */
|
|
2
|
+
/** Unmet dsh requirements and the exact plugin/runtime exemption decision. */
|
|
3
3
|
export interface PluginCompatibility {
|
|
4
4
|
name: string;
|
|
5
5
|
version: string;
|
|
6
6
|
runtimeVersion: string;
|
|
7
|
-
/** Only
|
|
8
|
-
|
|
7
|
+
/** Only requirements the running dsh version does not satisfy: `engines.dsh`, or dsh peer package names. */
|
|
8
|
+
requirements: Record<string, string>;
|
|
9
9
|
exempted: boolean;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
@@ -15,18 +15,19 @@ export interface PluginCompatibility {
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function getDshRuntimeVersion(): string;
|
|
17
17
|
/**
|
|
18
|
-
* Check
|
|
19
|
-
*
|
|
20
|
-
*
|
|
18
|
+
* Check the plugin's dsh requirements against the runtime. An own `engines.dsh` range decides alone and
|
|
19
|
+
* peerDependencies are ignored; otherwise every @deepseek-ai/dsh or @deepseek-ai/dsh-* peer must match.
|
|
20
|
+
* Prereleases participate in ranges. For peers only, workspace:^, workspace:~, and workspace:* refer to
|
|
21
|
+
* the current runtime; other empty or invalid ranges, including any workspace: `engines.dsh`, are unmet.
|
|
21
22
|
* @param manifest - parsed plugin package.json; inherited fields are ignored.
|
|
22
23
|
* @param exemptions - exact plugin name@version keys mapped to exact runtime versions.
|
|
23
24
|
* @param runtimeVersion - running dsh version, defaulting to this app-boot package.
|
|
24
|
-
* @returns
|
|
25
|
-
* @throws for malformed manifest peer fields, invalid runtime versions, or missing identity on a mismatch.
|
|
25
|
+
* @returns unmet requirements and exemption status, or undefined when every requirement is met.
|
|
26
|
+
* @throws for malformed manifest engines or peer fields, invalid runtime versions, or missing identity on a mismatch.
|
|
26
27
|
*/
|
|
27
28
|
export declare function evaluatePluginCompatibility(manifest: object, exemptions?: Readonly<Record<string, readonly string[]>>, runtimeVersion?: string): PluginCompatibility | undefined;
|
|
28
29
|
/**
|
|
29
|
-
* Describe
|
|
30
|
+
* Describe unmet requirements, their risk, and the exact-version remedy.
|
|
30
31
|
* Surfaces with their own grant mechanism or locale render the structured result themselves.
|
|
31
32
|
* @param issue - incompatible plugin/runtime result, including exempted mismatches.
|
|
32
33
|
* @returns an English diagnostic for logs and stderr.
|
package/lib/types/profile.d.ts
CHANGED
|
@@ -76,7 +76,7 @@ export interface Profile {
|
|
|
76
76
|
/** Selected bundles that contributed no layer, in `dsh.profile.bundles` order, with why. */
|
|
77
77
|
skippedBundles: SkippedBundle[];
|
|
78
78
|
}
|
|
79
|
-
/** A selected bundle the profile could not load, or whose own DSH
|
|
79
|
+
/** A selected bundle the profile could not load, or whose own DSH requirements the profile does not exempt. */
|
|
80
80
|
export interface SkippedBundle {
|
|
81
81
|
/** The bundle's package name from `dsh.profile.bundles`. */
|
|
82
82
|
packageName: string;
|
|
@@ -237,7 +237,7 @@ export declare function resolveBundleDir(binName: string, packageName: string, i
|
|
|
237
237
|
* the shared Harness home. This is used by application-owned profiles whose
|
|
238
238
|
* package project and lifecycle belong to that application.
|
|
239
239
|
* Retired bundles are removed from the stored bundle list first, rewriting the
|
|
240
|
-
* manifest when it listed one. Unreadable bundles, and bundles whose own dsh
|
|
240
|
+
* manifest when it listed one. Unreadable bundles, and bundles whose own dsh requirements the profile does not exempt, are skipped
|
|
241
241
|
* without changing the manifest and listed in `skippedBundles`; nothing is printed.
|
|
242
242
|
* @param binName - the diagnostic prefix on thrown errors.
|
|
243
243
|
* @param dir - absolute profile package directory.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-app-boot",
|
|
3
3
|
"description": "Shared boot glue for the app bins: .env loading, fail-loud Loader guards, snapshot-aware config resolution, and the Loader boot sequence",
|
|
4
|
-
"version": "0.2.1-alpha.
|
|
4
|
+
"version": "0.2.1-alpha.4",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
],
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@deepseek-ai/dsh-atomic-write": "0.2.1-alpha.
|
|
36
|
-
"@deepseek-ai/dsh-package-manifest": "0.2.1-alpha.
|
|
35
|
+
"@deepseek-ai/dsh-atomic-write": "0.2.1-alpha.4",
|
|
36
|
+
"@deepseek-ai/dsh-package-manifest": "0.2.1-alpha.4",
|
|
37
37
|
"@eslint-community/regexpp": "^4.12.2",
|
|
38
38
|
"ajv": "^8.20.0",
|
|
39
39
|
"js-yaml": "^4.3.2",
|
|
@@ -45,8 +45,8 @@
|
|
|
45
45
|
"@deepseek-ai/cordis-plugin-group": "~1.0.5-alpha.2",
|
|
46
46
|
"@deepseek-ai/cordis-plugin-include": "~1.0.10-alpha.2",
|
|
47
47
|
"@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.2",
|
|
48
|
-
"@deepseek-ai/dsh-launch-environment": "0.2.1-alpha.
|
|
49
|
-
"@deepseek-ai/dsh-home-paths": "0.2.1-alpha.
|
|
48
|
+
"@deepseek-ai/dsh-launch-environment": "0.2.1-alpha.4",
|
|
49
|
+
"@deepseek-ai/dsh-home-paths": "0.2.1-alpha.4",
|
|
50
50
|
"@deepseek-ai/cordis": "~4.0.5-alpha.2"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
@@ -55,9 +55,9 @@
|
|
|
55
55
|
"@deepseek-ai/cordis-plugin-include": "~1.0.10-alpha.2",
|
|
56
56
|
"@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.2",
|
|
57
57
|
"@deepseek-ai/cordis-plugin-timer": "~1.1.7-alpha.2",
|
|
58
|
-
"@deepseek-ai/dsh-launch-environment": "0.2.1-alpha.
|
|
59
|
-
"@deepseek-ai/dsh-home-paths": "0.2.1-alpha.
|
|
60
|
-
"@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.
|
|
58
|
+
"@deepseek-ai/dsh-launch-environment": "0.2.1-alpha.4",
|
|
59
|
+
"@deepseek-ai/dsh-home-paths": "0.2.1-alpha.4",
|
|
60
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4",
|
|
61
61
|
"@types/js-yaml": "^4.0.9",
|
|
62
62
|
"@types/semver": "^7.8.0",
|
|
63
63
|
"@deepseek-ai/cordis": "~4.0.5-alpha.2"
|