@deepseek-ai/dsh-tool-workspace-dependencies 0.2.1-alpha.2 → 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 CHANGED
@@ -21,8 +21,8 @@
21
21
  en: 97b1f99b4e9c2569
22
22
  zh: bf6c6ce74073413f
23
23
  /deepseek-ai-dsh-tool-workspace-dependencies/use-this-package/payload-layout:
24
- en: 0ba9c7e3b9738e4d
25
- zh: a98344644ac55182
24
+ en: 709eda9a01bc0a81
25
+ zh: bb4693ddd755866a
26
26
  /deepseek-ai-dsh-tool-workspace-dependencies/use-this-package/build-a-carrier-payload:
27
27
  en: 0f3e570525053f09
28
28
  zh: 1b0cd3b653e1bd5d
package/README.md CHANGED
@@ -44,6 +44,8 @@ Mount the plugin beside the tool registry with the payload directory. Configurat
44
44
 
45
45
  `runtime.json` records `desktopVersion`, `platform` (`win32`, `darwin`, or `linux`), `arch`, optional `payloadDigest`, top-level `python`, optional `node`/`pnpm` versions, and the complete `pythonPackages` distribution-version map. A pnpm entry requires Node.js. Python libraries, including numpy and pandas, appear only in `pythonPackages`. Entries live under `dependencies/`: `python/bin/python3` (`python/python.exe` on Windows) with `site-packages` beneath it, and, when declared, `node/bin/node` with `node/node_modules` and `pnpm/bin/pnpm.mjs`. A manifest whose platform or architecture differs from the running process is rejected.
46
46
 
47
+ On macOS and Linux, the builder retains `python` and `python3` as relative links to the sibling versioned interpreter (for example, `python3.12`). Installation preserves these two aliases and materializes other links. Alias validation requires the exact sibling filename and a regular target file; carriers that cannot preserve links, including Python wheels, retain supported regular command files. Windows keeps its ordinary `python.exe` file.
48
+
47
49
  The packaged `sdk` profile uses its bundled Python and Office skills by default; `DSH_PRIMARY_RUNTIME` overrides the resource location, and an empty value opts out. Source launches without a carrier default remain opt-in. See [runtime configuration](../../../python/sdk-runtime/README.md) for independent skill selection. Missing skill resources produce a startup warning; invalid or incomplete external runtime payloads fail the first tool call. Profile configuration changes require restarting the SDK process.
48
50
 
49
51
  ### Build a carrier payload
package/README.zh.md CHANGED
@@ -44,6 +44,8 @@ kind: "package-reference"
44
44
 
45
45
  `runtime.json` 记录 `desktopVersion`、`platform`(`win32`、`darwin` 或 `linux`)、`arch`、可选的 `payloadDigest`、顶层 `python` 与可选的 `node`/`pnpm` 版本,以及完整的 `pythonPackages` 分发包版本表。声明 pnpm 时必须同时声明 Node.js。numpy、pandas 等 Python 库只出现在 `pythonPackages` 中。条目位于 `dependencies/`:`python/bin/python3`(Windows 为 `python/python.exe`)及其下的 `site-packages`;声明了才有的 `node/bin/node`、`node/node_modules` 与 `pnpm/bin/pnpm.mjs`。平台或架构与当前进程不符的清单被拒绝。
46
46
 
47
+ 在 macOS 和 Linux 上,构建器将 `python` 和 `python3` 保留为指向同目录版本化解释器(例如 `python3.12`)的相对链接。安装时保留这两个别名,其他链接展开为实际文件。别名校验要求目标名称与同目录解释器文件名完全一致,且目标为普通文件;Python wheel 等无法保留链接的载体使用普通命令文件,同样受支持。Windows 保留普通的 `python.exe` 文件。
48
+
47
49
  打包的 `sdk` profile 默认使用随包 Python 和 Office skills;`DSH_PRIMARY_RUNTIME` 覆盖资源位置,空值表示禁用。没有载体默认路径的源码启动仍需显式启用。独立选择 skills 的方式见[运行时配置](../../../python/sdk-runtime/README.zh.md)。缺少 skill 资源会产生启动警告;无效或不完整的外部运行时 payload 在首次工具调用时失败。profile 配置变更需要重启 SDK 进程。
48
50
 
49
51
  ### 构建载体 payload
package/lib/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { cp, lstat, mkdir, mkdtemp, readFile, rename, rm, stat } from "node:fs/promises";
1
+ import { cp, lstat, mkdir, mkdtemp, readFile, readlink, rename, rm, stat, symlink } from "node:fs/promises";
2
2
  import { dirname, isAbsolute, join } from "node:path";
3
3
  import z from "@deepseek-ai/schemastery";
4
4
  import { defineTool } from "@deepseek-ai/dsh-tools";
@@ -75,6 +75,49 @@ async function readPrimaryRuntime(root) {
75
75
  return parsePrimaryRuntime(JSON.parse(await readFile(join(root, "runtime.json"), "utf8")));
76
76
  }
77
77
  /**
78
+ * Identify POSIX interpreter aliases that can survive payload relocation.
79
+ * @param root - Payload directory.
80
+ * @param manifest - Validated payload metadata.
81
+ * @returns Relative alias paths mapped to their sibling interpreter filename; regular command files are omitted.
82
+ * @throws When an interpreter alias does not point directly to the versioned regular file.
83
+ */
84
+ async function primaryRuntimePythonAliases(root, manifest) {
85
+ const aliases = /* @__PURE__ */ new Map();
86
+ if (manifest.platform === "win32") return aliases;
87
+ const interpreter = `python${manifest.python.split(".").slice(0, 2).join(".")}`;
88
+ for (const name of ["python", "python3"]) {
89
+ const path = `dependencies/python/bin/${name}`;
90
+ let entry;
91
+ try {
92
+ entry = await lstat(join(root, path));
93
+ } catch (error) {
94
+ if (error.code === "ENOENT") continue;
95
+ throw error;
96
+ }
97
+ if (!entry.isSymbolicLink()) continue;
98
+ if (await readlink(join(root, path)) !== interpreter || !(await lstat(join(root, "dependencies/python/bin", interpreter))).isFile()) throw new Error(`primary runtime: invalid Python alias ${path}`);
99
+ aliases.set(path, interpreter);
100
+ }
101
+ return aliases;
102
+ }
103
+ /**
104
+ * Copy a payload, retaining only validated Python interpreter aliases as relative links.
105
+ * @param source - Payload directory; all other links are materialized.
106
+ * @param destination - Empty destination owned by the caller.
107
+ * @param manifest - Validated source metadata.
108
+ * @returns Resolves after every copied file and interpreter alias is available independently of the source.
109
+ */
110
+ async function copyPrimaryRuntime(source, destination, manifest) {
111
+ const aliases = await primaryRuntimePythonAliases(source, manifest);
112
+ const excluded = new Set([...aliases.keys()].map((path) => join(source, path)));
113
+ await cp(source, destination, {
114
+ recursive: true,
115
+ dereference: true,
116
+ filter: (path) => !excluded.has(path)
117
+ });
118
+ for (const [path, target] of aliases) await symlink(target, join(destination, path));
119
+ }
120
+ /**
78
121
  * Resolve platform-specific interpreter and library locations without changing the environment.
79
122
  * @param root - Absolute payload or installation directory.
80
123
  * @param manifest - Validated runtime metadata.
@@ -129,7 +172,9 @@ async function compatibleManifest(source) {
129
172
  * @returns Paths into the payload itself.
130
173
  */
131
174
  async function resolvePrimaryRuntime(source) {
132
- const paths = workspaceDependencyPaths(source, await compatibleManifest(source));
175
+ const manifest = await compatibleManifest(source);
176
+ await primaryRuntimePythonAliases(source, manifest);
177
+ const paths = workspaceDependencyPaths(source, manifest);
133
178
  await validatePayloadEntries(paths);
134
179
  return paths;
135
180
  }
@@ -146,16 +191,14 @@ async function installPrimaryRuntime(source, root) {
146
191
  const previousExists = await exists(previous);
147
192
  if (!await exists(root) && previousExists) await rename(previous, root);
148
193
  if (await exists(join(root, "runtime.json")) && JSON.stringify(await readPrimaryRuntime(root)) === JSON.stringify(manifest)) {
194
+ await primaryRuntimePythonAliases(root, manifest);
149
195
  const paths = workspaceDependencyPaths(root, manifest);
150
196
  await validatePayloadEntries(paths);
151
197
  return paths;
152
198
  }
153
199
  const staging = await mkdtemp(join(dirname(root), ".primary-runtime-"));
154
200
  try {
155
- await cp(source, staging, {
156
- recursive: true,
157
- dereference: true
158
- });
201
+ await copyPrimaryRuntime(source, staging, manifest);
159
202
  await validatePayloadEntries(workspaceDependencyPaths(staging, manifest));
160
203
  await rm(previous, {
161
204
  recursive: true,
@@ -249,4 +292,4 @@ function apply(ctx, config) {
249
292
  }));
250
293
  }
251
294
  //#endregion
252
- export { Config, apply, inject, installPrimaryRuntime, name, parsePrimaryRuntime, readPrimaryRuntime, resolvePrimaryRuntime, workspaceDependencyPaths };
295
+ export { Config, apply, copyPrimaryRuntime, inject, installPrimaryRuntime, name, parsePrimaryRuntime, primaryRuntimePythonAliases, readPrimaryRuntime, resolvePrimaryRuntime, workspaceDependencyPaths };
@@ -57,6 +57,22 @@ export declare function parsePrimaryRuntime(value: unknown): PrimaryRuntimeManif
57
57
  * @returns Validated top-level versions and target identifiers, including for legacy components manifests.
58
58
  */
59
59
  export declare function readPrimaryRuntime(root: string): Promise<PrimaryRuntimeManifest>;
60
+ /**
61
+ * Identify POSIX interpreter aliases that can survive payload relocation.
62
+ * @param root - Payload directory.
63
+ * @param manifest - Validated payload metadata.
64
+ * @returns Relative alias paths mapped to their sibling interpreter filename; regular command files are omitted.
65
+ * @throws When an interpreter alias does not point directly to the versioned regular file.
66
+ */
67
+ export declare function primaryRuntimePythonAliases(root: string, manifest: PrimaryRuntimeManifest): Promise<ReadonlyMap<string, string>>;
68
+ /**
69
+ * Copy a payload, retaining only validated Python interpreter aliases as relative links.
70
+ * @param source - Payload directory; all other links are materialized.
71
+ * @param destination - Empty destination owned by the caller.
72
+ * @param manifest - Validated source metadata.
73
+ * @returns Resolves after every copied file and interpreter alias is available independently of the source.
74
+ */
75
+ export declare function copyPrimaryRuntime(source: string, destination: string, manifest: PrimaryRuntimeManifest): Promise<void>;
60
76
  /**
61
77
  * Resolve platform-specific interpreter and library locations without changing the environment.
62
78
  * @param root - Absolute payload or installation directory.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-tool-workspace-dependencies",
3
3
  "description": "The load_workspace_dependencies tool: absolute paths into a bundled Python, Node.js, and pnpm payload",
4
- "version": "0.2.1-alpha.2",
4
+ "version": "0.2.1-alpha.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -26,19 +26,19 @@
26
26
  ],
27
27
  "license": "MIT",
28
28
  "peerDependencies": {
29
- "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
30
- "@deepseek-ai/cordis": "~4.0.5-alpha.1"
29
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.4",
30
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2"
31
31
  },
32
32
  "devDependencies": {
33
- "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
34
- "@deepseek-ai/cordis": "~4.0.5-alpha.1",
35
- "@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.1",
36
- "@deepseek-ai/cordis-plugin-include": "~1.0.10-alpha.1",
37
- "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
38
- "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
39
- "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.2"
33
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.4",
34
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2",
35
+ "@deepseek-ai/cordis-plugin-loader": "~1.0.6-alpha.2",
36
+ "@deepseek-ai/cordis-plugin-include": "~1.0.10-alpha.2",
37
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.4",
38
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.4",
39
+ "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4"
40
40
  },
41
41
  "dependencies": {
42
- "@deepseek-ai/schemastery": "~3.18.5-alpha.1"
42
+ "@deepseek-ai/schemastery": "~3.18.5-alpha.2"
43
43
  }
44
44
  }