@zleap-ai/dsh-sag 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.1 - 2026-09-11
4
+
5
+ - Keep settings namespace branding type-only so dsh host helper-export changes cannot prevent plugin startup.
6
+ - Validate the packaged bundle against the dsh host selected by `DSH_BIN` instead of a fixed historical version.
7
+
3
8
  ## 0.1.0 - 2026-08-29
4
9
 
5
10
  - Validate the published bundle against the npm `latest` DeepSeek Harness `0.1.1-rc.2` release.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  dsh-sag lets DeepSeek Harness use the local SAG personal knowledge base for search, reading, upload, note ingestion, and document management.
4
4
 
5
- Compatible with DeepSeek Harness `0.1.1-rc.2`, the current npm `latest` (there is no final `0.1.1` release yet). SAG must include the Connect dsh setting and local connector API. The unmodified SAG `1.8.3` release does not include this capability; use the build from [SAG PR #154](https://github.com/Zleap-AI/SAG/pull/154), or a later SAG release that includes it.
5
+ Compatible with DeepSeek Harness `0.1.x`, starting at `0.1.1-rc.2`. SAG must include the Connect dsh setting and local connector API. The unmodified SAG `1.8.3` release does not include this capability; use the build from [SAG PR #154](https://github.com/Zleap-AI/SAG/pull/154), or a later SAG release that includes it.
6
6
 
7
7
  ## Quick start
8
8
 
package/README.zh.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  dsh-sag 让 DeepSeek Harness 直接使用运行在本机的 SAG 个人知识库,包括检索、阅读、上传、写入和文档管理。
4
4
 
5
- 适用于 DeepSeek Harness `0.1.1-rc.2`(当前 npm `latest`;目前没有正式的 `0.1.1` 稳定版)。SAG 需要包含“连接 dsh”设置和本地连接器 API;当前未修改的 SAG `1.8.3` 尚未包含该能力,请使用 [SAG PR #154](https://github.com/Zleap-AI/SAG/pull/154) 对应构建,或后续包含该能力的正式版本。
5
+ 适用于 DeepSeek Harness `0.1.x`,最低版本为 `0.1.1-rc.2`。SAG 需要包含“连接 dsh”设置和本地连接器 API;当前未修改的 SAG `1.8.3` 尚未包含该能力,请使用 [SAG PR #154](https://github.com/Zleap-AI/SAG/pull/154) 对应构建,或后续包含该能力的正式版本。
6
6
 
7
7
  ## 开始使用
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  Generated from the package manifests and license files used by the standalone dsh-sag CLI build.
4
4
 
5
- ## @deepseek-ai/cordis@4.0.1
5
+ ## @deepseek-ai/cordis@4.0.2
6
6
 
7
7
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: vendor/cordis)
8
8
  License: MIT
@@ -30,7 +30,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30
30
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
31
31
  SOFTWARE.
32
32
 
33
- ## @deepseek-ai/cosmokit@1.8.2
33
+ ## @deepseek-ai/cosmokit@1.8.3
34
34
 
35
35
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: vendor/cosmokit)
36
36
  License: MIT
@@ -58,7 +58,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
58
58
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
59
59
  SOFTWARE.
60
60
 
61
- ## @deepseek-ai/dsh-atomic-write@0.1.1-rc.2
61
+ ## @deepseek-ai/dsh-atomic-write@0.1.5-rc.2
62
62
 
63
63
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/util/atomic-write)
64
64
  License: MIT
@@ -86,7 +86,35 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
86
86
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
87
87
  SOFTWARE.
88
88
 
89
- ## @deepseek-ai/dsh-credentials-local@0.1.1-rc.2
89
+ ## @deepseek-ai/dsh-brand@0.1.5-rc.2
90
+
91
+ Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/util/brand)
92
+ License: MIT
93
+ License file: LICENSE
94
+
95
+ MIT License
96
+
97
+ Copyright (c) 2026 DeepSeek
98
+
99
+ Permission is hereby granted, free of charge, to any person obtaining a copy
100
+ of this software and associated documentation files (the "Software"), to deal
101
+ in the Software without restriction, including without limitation the rights
102
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
103
+ copies of the Software, and to permit persons to whom the Software is
104
+ furnished to do so, subject to the following conditions:
105
+
106
+ The above copyright notice and this permission notice shall be included in all
107
+ copies or substantial portions of the Software.
108
+
109
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
110
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
111
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
112
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
113
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
114
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
115
+ SOFTWARE.
116
+
117
+ ## @deepseek-ai/dsh-credentials-local@0.1.5-rc.2
90
118
 
91
119
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/credentials/credentials-local)
92
120
  License: MIT
@@ -114,7 +142,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
114
142
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
115
143
  SOFTWARE.
116
144
 
117
- ## @deepseek-ai/dsh-credentials@0.1.1-rc.2
145
+ ## @deepseek-ai/dsh-credentials@0.1.5-rc.2
118
146
 
119
147
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/credentials/credentials)
120
148
  License: MIT
@@ -142,7 +170,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
142
170
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
143
171
  SOFTWARE.
144
172
 
145
- ## @deepseek-ai/dsh-home-paths@0.1.1-rc.2
173
+ ## @deepseek-ai/dsh-home-paths@0.1.5-rc.2
146
174
 
147
175
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/util/home-paths)
148
176
  License: MIT
@@ -170,7 +198,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
170
198
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
171
199
  SOFTWARE.
172
200
 
173
- ## @deepseek-ai/dsh-launch-environment@0.1.1-rc.2
201
+ ## @deepseek-ai/dsh-launch-environment@0.1.5-rc.2
174
202
 
175
203
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/util/launch-environment)
176
204
  License: MIT
@@ -198,7 +226,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
198
226
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
199
227
  SOFTWARE.
200
228
 
201
- ## @deepseek-ai/dsh-settings-file@0.1.1-rc.2
229
+ ## @deepseek-ai/dsh-settings-file@0.1.5-rc.2
202
230
 
203
231
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/settings/settings-file)
204
232
  License: MIT
@@ -226,7 +254,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
226
254
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
227
255
  SOFTWARE.
228
256
 
229
- ## @deepseek-ai/dsh-settings@0.1.1-rc.2
257
+ ## @deepseek-ai/dsh-settings@0.1.5-rc.2
230
258
 
231
259
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/settings/settings)
232
260
  License: MIT
@@ -254,7 +282,35 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
254
282
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
255
283
  SOFTWARE.
256
284
 
257
- ## @deepseek-ai/schemastery@3.18.1
285
+ ## @deepseek-ai/dsh-util-values@0.1.5-rc.2
286
+
287
+ Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: packages/util/values)
288
+ License: MIT
289
+ License file: LICENSE
290
+
291
+ MIT License
292
+
293
+ Copyright (c) 2026 DeepSeek
294
+
295
+ Permission is hereby granted, free of charge, to any person obtaining a copy
296
+ of this software and associated documentation files (the "Software"), to deal
297
+ in the Software without restriction, including without limitation the rights
298
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
299
+ copies of the Software, and to permit persons to whom the Software is
300
+ furnished to do so, subject to the following conditions:
301
+
302
+ The above copyright notice and this permission notice shall be included in all
303
+ copies or substantial portions of the Software.
304
+
305
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
306
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
307
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
308
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
309
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
310
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
311
+ SOFTWARE.
312
+
313
+ ## @deepseek-ai/schemastery@3.18.2
258
314
 
259
315
  Source: git+https://github.com/deepseek-ai/deepseek-harness.git (directory: vendor/schemastery)
260
316
  License: MIT
@@ -1,9 +1,9 @@
1
1
  import type { Context } from '@deepseek-ai/cordis';
2
2
  import { type CredentialProvider } from '@deepseek-ai/dsh-credentials';
3
- import { type SettingsScope } from '@deepseek-ai/dsh-settings';
3
+ import type { SettingsNamespace, SettingsScope } from '@deepseek-ai/dsh-settings';
4
4
  import type { SagConnectionDescriptor, SagLocalSettings } from './types.js';
5
- /** The fixed settings namespace for the locally managed SAG connection. */
6
- export declare const SAG_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
5
+ /** The fixed settings namespace; its brand is type-only so host loading needs no helper export. */
6
+ export declare const SAG_SETTINGS_NAMESPACE: SettingsNamespace;
7
7
  /** The only credential record owned by the local SAG connection. */
8
8
  export declare const SAG_CREDENTIAL_KEY: import("@deepseek-ai/dsh-credentials").CredentialKey;
9
9
  /** Machine-readable error for saved connection data that cannot be used safely. */
@@ -1,9 +1,8 @@
1
1
  import { credentialKey } from '@deepseek-ai/dsh-credentials';
2
- import { settingsNamespace } from '@deepseek-ai/dsh-settings';
3
2
  import z from '@deepseek-ai/schemastery';
4
3
  import { parseConnectionDescriptor } from './descriptor.js';
5
- /** The fixed settings namespace for the locally managed SAG connection. */
6
- export const SAG_SETTINGS_NAMESPACE = settingsNamespace('dsh-sag');
4
+ /** The fixed settings namespace; its brand is type-only so host loading needs no helper export. */
5
+ export const SAG_SETTINGS_NAMESPACE = 'dsh-sag';
7
6
  /** The only credential record owned by the local SAG connection. */
8
7
  export const SAG_CREDENTIAL_KEY = credentialKey('dsh-sag', 'local');
9
8
  /** Machine-readable error for saved connection data that cannot be used safely. */
@@ -25639,7 +25639,7 @@ import { readFile as readFile3 } from "node:fs/promises";
25639
25639
  import { homedir as homedir2 } from "node:os";
25640
25640
  import { resolve as resolve7 } from "node:path";
25641
25641
 
25642
- // ../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.2/node_modules/@deepseek-ai/cosmokit/lib/index.js
25642
+ // ../../node_modules/.pnpm/@deepseek-ai+cosmokit@1.8.3/node_modules/@deepseek-ai/cosmokit/lib/index.js
25643
25643
  function isNullable(value) {
25644
25644
  return value === null || value === void 0;
25645
25645
  }
@@ -25861,7 +25861,7 @@ var Time;
25861
25861
  Time2.template = template;
25862
25862
  })(Time || (Time = {}));
25863
25863
 
25864
- // ../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.1/node_modules/@deepseek-ai/cordis/lib/index.js
25864
+ // ../../node_modules/.pnpm/@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/cordis/lib/index.js
25865
25865
  var DisposableList = class {
25866
25866
  sn = 0;
25867
25867
  map = /* @__PURE__ */ new Map();
@@ -27584,7 +27584,7 @@ var Service = class Service2 {
27584
27584
  }
27585
27585
  };
27586
27586
 
27587
- // ../../node_modules/.pnpm/@deepseek-ai+schemastery@3.18.1/node_modules/@deepseek-ai/schemastery/lib/index.mjs
27587
+ // ../../node_modules/.pnpm/@deepseek-ai+schemastery@3.18.2/node_modules/@deepseek-ai/schemastery/lib/index.mjs
27588
27588
  var kSchema = /* @__PURE__ */ Symbol.for("schemastery");
27589
27589
  var kValidationError2 = /* @__PURE__ */ Symbol.for("ValidationError");
27590
27590
  globalThis.__schemastery_index__ ??= 0;
@@ -29876,15 +29876,41 @@ function watch(paths, options = {}) {
29876
29876
  return watcher;
29877
29877
  }
29878
29878
 
29879
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials-local@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+ds_7bb67d14430a2d1ff3cabd2ed2468913/node_modules/@deepseek-ai/dsh-credentials-local/lib/index.js
29879
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials-local@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+ds_2d5b638b86a42b295b9688f1f1de1a2b/node_modules/@deepseek-ai/dsh-credentials-local/lib/index.js
29880
29880
  var import_yaml = __toESM(require_dist2(), 1);
29881
29881
  import { mkdir as mkdir2, readFile, stat as stat4 } from "node:fs/promises";
29882
29882
  import { dirname as dirname5, join as join4, resolve as resolve5 } from "node:path";
29883
29883
 
29884
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-atomic-write@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+dsh-inv_762db61a27c1f9c9369d223d4c8b5b1f/node_modules/@deepseek-ai/dsh-atomic-write/lib/index.js
29884
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-atomic-write@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-atomic-write/lib/index.js
29885
29885
  import { randomBytes } from "node:crypto";
29886
29886
  import { lstat as lstat3, mkdir, rename, rm, writeFile } from "node:fs/promises";
29887
29887
  import { dirname as dirname3 } from "node:path";
29888
+ var WINDOWS_TRANSIENT_RENAME_ERRORS = /* @__PURE__ */ new Set([
29889
+ "EACCES",
29890
+ "EBUSY",
29891
+ "EPERM"
29892
+ ]);
29893
+ var WINDOWS_RENAME_RETRY_INITIAL_MS = 20;
29894
+ var WINDOWS_RENAME_RETRY_MAX_MS = 200;
29895
+ var WINDOWS_RENAME_RETRY_LIMIT = 8;
29896
+ function isTransientWindowsRenameError(error2) {
29897
+ if (process.platform !== "win32") return false;
29898
+ return WINDOWS_TRANSIENT_RENAME_ERRORS.has(error2?.code ?? "");
29899
+ }
29900
+ async function renameAtomicTemp(temp, filename) {
29901
+ let delay = WINDOWS_RENAME_RETRY_INITIAL_MS;
29902
+ for (let retries = 0; ; retries += 1) {
29903
+ try {
29904
+ await rename(temp, filename);
29905
+ return;
29906
+ } catch (error2) {
29907
+ if (!isTransientWindowsRenameError(error2)) throw error2;
29908
+ if (retries >= WINDOWS_RENAME_RETRY_LIMIT) throw error2;
29909
+ }
29910
+ await new Promise((resolve8) => setTimeout(resolve8, delay));
29911
+ delay = Math.min(delay * 2, WINDOWS_RENAME_RETRY_MAX_MS);
29912
+ }
29913
+ }
29888
29914
  async function writeFileAtomic(filename, content, options) {
29889
29915
  await mkdir(dirname3(filename), {
29890
29916
  recursive: true,
@@ -29896,7 +29922,7 @@ async function writeFileAtomic(filename, content, options) {
29896
29922
  mode: options.mode,
29897
29923
  flag: "wx"
29898
29924
  });
29899
- await rename(temp, filename);
29925
+ await renameAtomicTemp(temp, filename);
29900
29926
  } catch (error2) {
29901
29927
  await rm(temp, { force: true });
29902
29928
  throw error2;
@@ -29942,7 +29968,7 @@ async function withFileLock(filename, operation, options) {
29942
29968
  }
29943
29969
  }
29944
29970
 
29945
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-home-paths@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+dsh-invar_260f8dde1d5adbe84fd51b779f4f83da/node_modules/@deepseek-ai/dsh-home-paths/lib/index.js
29971
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-home-paths@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-home-paths/lib/index.js
29946
29972
  import { opendir, realpath as realpath2 } from "node:fs/promises";
29947
29973
  import { homedir } from "node:os";
29948
29974
  import { basename as basename3, dirname as dirname4, join as join3, resolve as resolve4 } from "node:path";
@@ -29977,7 +30003,7 @@ function resolveDshHome(configured, env = process.env) {
29977
30003
  return resolve4(expandHomePath(configured ?? (fromEnv !== void 0 && fromEnv.trim().length > 0 ? fromEnv : defaultDshHome())));
29978
30004
  }
29979
30005
 
29980
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-launch-environment@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+d_bf942fcb3d7f6e25f5c2c0613a680229/node_modules/@deepseek-ai/dsh-launch-environment/lib/index.js
30006
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-launch-environment@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-launch-environment/lib/index.js
29981
30007
  var SOURCE_ORDER = [
29982
30008
  "process",
29983
30009
  "project-env",
@@ -30018,19 +30044,24 @@ function launchEnvironmentOf(ctx) {
30018
30044
  }]);
30019
30045
  }
30020
30046
 
30021
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+dsh-bran_07859f6f9ce036fd17600077e6a695b1/node_modules/@deepseek-ai/dsh-credentials/lib/index.js
30047
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-brand@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-brand/lib/index.js
30048
+ function brandString(value) {
30049
+ return value;
30050
+ }
30051
+
30052
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+dsh-inva_51080d1f5daa97dd95d6cec6dfb5ca6d/node_modules/@deepseek-ai/dsh-credentials/lib/index.js
30022
30053
  var REF_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
30023
30054
  var KEY_SEGMENT_PATTERN = /^[a-z][a-z0-9-]*$/;
30024
30055
  function credentialRef(value) {
30025
30056
  if (!isCredentialRefName(value)) throw new TypeError(`credential ref "${value}" must match ${String(REF_PATTERN)}`);
30026
- return value;
30057
+ return brandString(value);
30027
30058
  }
30028
30059
  function isCredentialRefName(value) {
30029
30060
  return REF_PATTERN.test(value);
30030
30061
  }
30031
30062
  function credentialKey(scope, id) {
30032
30063
  for (const segment of [scope, id]) if (!KEY_SEGMENT_PATTERN.test(segment)) throw new TypeError(`credential key segment "${segment}" must match ${String(KEY_SEGMENT_PATTERN)}`);
30033
- return `${scope}/${id}`;
30064
+ return brandString(`${scope}/${id}`);
30034
30065
  }
30035
30066
  function parseCredentialKey(value) {
30036
30067
  const segments = value.split("/");
@@ -30089,7 +30120,7 @@ var CredentialProvider = class extends Service {
30089
30120
  }
30090
30121
  };
30091
30122
 
30092
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials-local@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+ds_7bb67d14430a2d1ff3cabd2ed2468913/node_modules/@deepseek-ai/dsh-credentials-local/lib/index.js
30123
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-credentials-local@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+ds_2d5b638b86a42b295b9688f1f1de1a2b/node_modules/@deepseek-ai/dsh-credentials-local/lib/index.js
30093
30124
  function resolveSpec(config2) {
30094
30125
  return {
30095
30126
  filename: resolve5(config2.path ?? join4(resolveDshHome(config2.dshHome), ".credentials.yaml")),
@@ -30650,12 +30681,62 @@ var LocalCredentialProvider = class extends CredentialProvider {
30650
30681
  }
30651
30682
  };
30652
30683
 
30653
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-settings-file@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+dsh-at_07dac851674f547bcb0fed2f2776d133/node_modules/@deepseek-ai/dsh-settings-file/lib/index.js
30684
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-settings-file@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+dsh-at_0e4791dacea9086d39c0e6f7037cd78b/node_modules/@deepseek-ai/dsh-settings-file/lib/index.js
30654
30685
  var import_yaml2 = __toESM(require_dist2(), 1);
30655
30686
  import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile2 } from "node:fs/promises";
30656
30687
  import { dirname as dirname6, extname as extname2, join as join5, resolve as resolve6 } from "node:path";
30657
30688
 
30658
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-settings@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+dsh-brand@0_02aaf429ec98c58247037e2222c17a8f/node_modules/@deepseek-ai/dsh-settings/lib/index.js
30689
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-util-values@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2/node_modules/@deepseek-ai/dsh-util-values/lib/index.js
30690
+ function deepEqualJson(a, b) {
30691
+ if (a === b) return true;
30692
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
30693
+ if (Array.isArray(a) || Array.isArray(b)) {
30694
+ if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
30695
+ return a.every((entry, index) => deepEqualJson(entry, b[index]));
30696
+ }
30697
+ const left = a;
30698
+ const right = b;
30699
+ const keys = Object.keys(left);
30700
+ if (keys.length !== Object.keys(right).length) return false;
30701
+ return keys.every((key) => key in right && deepEqualJson(left[key], right[key]));
30702
+ }
30703
+ function deepFreeze(value) {
30704
+ const seen = /* @__PURE__ */ new WeakSet();
30705
+ const pending = [{
30706
+ kind: "visit",
30707
+ node: value
30708
+ }];
30709
+ while (pending.length > 0) {
30710
+ const task = pending.pop();
30711
+ if (task === void 0) continue;
30712
+ if (task.kind === "property") {
30713
+ pending.push({
30714
+ kind: "visit",
30715
+ node: task.source[task.key]
30716
+ });
30717
+ continue;
30718
+ }
30719
+ const node = task.node;
30720
+ if (node === null || typeof node !== "object") continue;
30721
+ if (node instanceof AbortSignal) continue;
30722
+ if (seen.has(node)) continue;
30723
+ seen.add(node);
30724
+ Object.freeze(node);
30725
+ const keys = Object.keys(node);
30726
+ for (let index = keys.length - 1; index >= 0; index--) {
30727
+ const key = keys[index];
30728
+ if (key === void 0) continue;
30729
+ pending.push({
30730
+ kind: "property",
30731
+ source: node,
30732
+ key
30733
+ });
30734
+ }
30735
+ }
30736
+ return value;
30737
+ }
30738
+
30739
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-settings@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+dsh-brand@0_5ca2e2f4bdf76868bb49b995ddcd3d9b/node_modules/@deepseek-ai/dsh-settings/lib/index.js
30659
30740
  function isRecord(value) {
30660
30741
  return typeof value === "object" && value !== null && !Array.isArray(value);
30661
30742
  }
@@ -30707,23 +30788,10 @@ function redactSecrets(schema, value) {
30707
30788
  };
30708
30789
  }
30709
30790
  var NAMESPACE_PATTERN = /^[a-z][a-z0-9-]*$/;
30710
- function settingsNamespace(value) {
30791
+ function parseSettingsNamespace(value) {
30711
30792
  if (!NAMESPACE_PATTERN.test(value)) throw new TypeError(`settings namespace "${value}" must match ${String(NAMESPACE_PATTERN)}`);
30712
30793
  return value;
30713
30794
  }
30714
- function deepEqualJson(a, b) {
30715
- if (a === b) return true;
30716
- if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
30717
- if (Array.isArray(a) || Array.isArray(b)) {
30718
- if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
30719
- return a.every((entry, index) => deepEqualJson(entry, b[index]));
30720
- }
30721
- const left = a;
30722
- const right = b;
30723
- const keys = Object.keys(left);
30724
- if (keys.length !== Object.keys(right).length) return false;
30725
- return keys.every((key) => key in right && deepEqualJson(left[key], right[key]));
30726
- }
30727
30795
  var SettingsConflictError = class extends Error {
30728
30796
  /** Stable machine code for wire layers mapping this to their own taxonomy. */
30729
30797
  code = "SETTINGS_CONFLICT";
@@ -30827,11 +30895,6 @@ function mergeLayers(under, over) {
30827
30895
  for (const [key, value] of Object.entries(over)) merged[key] = key in merged ? mergeLayers(merged[key], value) : value;
30828
30896
  return merged;
30829
30897
  }
30830
- function deepFreeze(value) {
30831
- if (typeof value !== "object" || value === null || Object.isFrozen(value)) return value;
30832
- for (const entry of Object.values(value)) deepFreeze(entry);
30833
- return Object.freeze(value);
30834
- }
30835
30898
  var SettingsProvider = class extends Service {
30836
30899
  registrations = /* @__PURE__ */ new Map();
30837
30900
  /** Latest published raw document; empty until the provider's first publish. */
@@ -30889,23 +30952,25 @@ var SettingsProvider = class extends Service {
30889
30952
  * @param schema - schemastery schema resolving this namespace's value.
30890
30953
  * @param options - composition `base` layer and effect timing.
30891
30954
  * @returns the owner scope for reads, observation, and updates.
30955
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
30892
30956
  */
30893
30957
  register(ns, schema, options) {
30894
- if (this.registrations.has(ns)) throw new Error(`settings namespace "${ns}" is already registered`);
30958
+ const parsedNs = parseSettingsNamespace(ns);
30959
+ if (this.registrations.has(parsedNs)) throw new Error(`settings namespace "${parsedNs}" is already registered`);
30895
30960
  const registration = {
30896
- ns,
30961
+ ns: parsedNs,
30897
30962
  schema,
30898
30963
  base: options?.base,
30899
30964
  applies: options?.applies ?? "live",
30900
30965
  ...options?.validate === void 0 ? {} : { validate: options.validate },
30901
- resolved: deepFreeze(this.resolve(schema, options?.base, this.section(ns), options?.validate)),
30966
+ resolved: deepFreeze(this.resolve(schema, options?.base, this.section(parsedNs), options?.validate)),
30902
30967
  revision: 0,
30903
30968
  watchers: /* @__PURE__ */ new Set()
30904
30969
  };
30905
30970
  this.ctx.effect(() => {
30906
- this.registrations.set(ns, registration);
30907
- return () => this.registrations.delete(ns);
30908
- }, `settings.register(${JSON.stringify(String(ns))})`);
30971
+ this.registrations.set(parsedNs, registration);
30972
+ return () => this.registrations.delete(parsedNs);
30973
+ }, `settings.register(${JSON.stringify(String(parsedNs))})`);
30909
30974
  return {
30910
30975
  get: () => registration.resolved,
30911
30976
  watch: (callback) => {
@@ -30920,11 +30985,39 @@ var SettingsProvider = class extends Service {
30920
30985
  registration.watchers.delete(watcher);
30921
30986
  };
30922
30987
  },
30923
- update: (patch) => this.update(ns, patch),
30924
- replace: (section) => this.replace(ns, section)
30988
+ update: (patch) => this.update(parsedNs, patch),
30989
+ replace: (section) => this.replace(parsedNs, section)
30925
30990
  };
30926
30991
  }
30927
30992
  /**
30993
+ * Attach one optional-settings consumer to this provider. The consumer
30994
+ * registers its composition entry as the base layer while this provider is
30995
+ * present, then falls back to that entry if the provider detaches.
30996
+ * @param owner - consumer context whose unload suppresses fallback work.
30997
+ * @param ns - consumer-owned settings namespace.
30998
+ * @param schema - schema resolving the namespace.
30999
+ * @param entry - composition entry used as the base and fallback value.
31000
+ * @param hooks - source sink, change notification, and optional validation.
31001
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
31002
+ */
31003
+ installSection(owner, ns, schema, entry, hooks) {
31004
+ const scope = this.register(ns, schema, {
31005
+ base: entry,
31006
+ ...hooks.validate === void 0 ? {} : { validate: hooks.validate }
31007
+ });
31008
+ hooks.setSource(() => scope.get());
31009
+ this.ctx.effect(() => () => {
31010
+ if (isUnloading(owner)) return;
31011
+ hooks.setSource(() => entry);
31012
+ hooks.onChange();
31013
+ });
31014
+ hooks.onChange();
31015
+ scope.watch(() => {
31016
+ if (isUnloading(owner)) return;
31017
+ hooks.onChange();
31018
+ });
31019
+ }
31020
+ /**
30928
31021
  * Describe every registered namespace for configuration surfaces, including
30929
31022
  * the composition `base` and raw user layers so a form can mark which fields
30930
31023
  * the user overrode (presence in `user`) and what a reset returns to.
@@ -30966,9 +31059,10 @@ var SettingsProvider = class extends Service {
30966
31059
  * Read one registered namespace's resolved value.
30967
31060
  * @param ns - the namespace to read.
30968
31061
  * @returns the resolved value, or `undefined` while unregistered.
31062
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
30969
31063
  */
30970
31064
  get(ns) {
30971
- return this.registrations.get(ns)?.resolved;
31065
+ return this.registrations.get(parseSettingsNamespace(ns))?.resolved;
30972
31066
  }
30973
31067
  /**
30974
31068
  * Merge a patch into one registered namespace's user layer, validate the
@@ -30980,9 +31074,10 @@ var SettingsProvider = class extends Service {
30980
31074
  * @param patch - plain-object patch over the user section.
30981
31075
  * @param expectedRevision - the descriptor `revision` the caller read; a
30982
31076
  * namespace that moved past it rejects with {@link SettingsConflictError}.
31077
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
30983
31078
  */
30984
31079
  async update(ns, patch, expectedRevision) {
30985
- return this.write(ns, patch, "merge", expectedRevision);
31080
+ return this.write(parseSettingsNamespace(ns), patch, "merge", expectedRevision);
30986
31081
  }
30987
31082
  /**
30988
31083
  * Replace one registered namespace's user section wholesale, validate,
@@ -30993,9 +31088,10 @@ var SettingsProvider = class extends Service {
30993
31088
  * @param section - the complete next user section.
30994
31089
  * @param expectedRevision - the descriptor `revision` the caller read; a
30995
31090
  * namespace that moved past it rejects with {@link SettingsConflictError}.
31091
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
30996
31092
  */
30997
31093
  async replace(ns, section, expectedRevision) {
30998
- return this.write(ns, section, "replace", expectedRevision);
31094
+ return this.write(parseSettingsNamespace(ns), section, "replace", expectedRevision);
30999
31095
  }
31000
31096
  /**
31001
31097
  * Apply path-addressed edits to one registered namespace's user section,
@@ -31008,14 +31104,16 @@ var SettingsProvider = class extends Service {
31008
31104
  * @param ops - ordered path edits; later ops observe earlier ones.
31009
31105
  * @param expectedRevision - the descriptor `revision` the caller read; a
31010
31106
  * namespace that moved past it rejects with {@link SettingsConflictError}.
31107
+ * @throws {TypeError} when `ns` is not a lowercase hyphenated identifier.
31011
31108
  */
31012
31109
  async mutate(ns, ops, expectedRevision) {
31013
- if (!Array.isArray(ops)) throw new TypeError(`settings mutate for "${ns}" must be an array of path ops`);
31110
+ const parsedNs = parseSettingsNamespace(ns);
31111
+ if (!Array.isArray(ops)) throw new TypeError(`settings mutate for "${parsedNs}" must be an array of path ops`);
31014
31112
  for (const op of ops) {
31015
- if (!isPlainObject5(op) || op["op"] !== "set" && op["op"] !== "unset") throw new TypeError(`settings mutate for "${ns}" ops must be {op:'set'|'unset', path}`);
31016
- if (!Array.isArray(op["path"]) || op["path"].some((part) => typeof part !== "string")) throw new TypeError(`settings mutate for "${ns}" op paths must be arrays of strings`);
31113
+ if (!isPlainObject5(op) || op["op"] !== "set" && op["op"] !== "unset") throw new TypeError(`settings mutate for "${parsedNs}" ops must be {op:'set'|'unset', path}`);
31114
+ if (!Array.isArray(op["path"]) || op["path"].some((part) => typeof part !== "string")) throw new TypeError(`settings mutate for "${parsedNs}" op paths must be arrays of strings`);
31017
31115
  }
31018
- return this.write(ns, ops, "mutate", expectedRevision);
31116
+ return this.write(parsedNs, ops, "mutate", expectedRevision);
31019
31117
  }
31020
31118
  /** Validate a write, then queue it on the namespace's serialized write chain. */
31021
31119
  write(ns, input, mode, expectedRevision) {
@@ -31172,8 +31270,14 @@ var SettingsProvider = class extends Service {
31172
31270
  this.ctx.logger.warn(error2);
31173
31271
  }
31174
31272
  };
31273
+ var FIBER_DISPOSED = 4;
31274
+ var FIBER_UNLOADING = 5;
31275
+ function isUnloading(ctx) {
31276
+ const state = ctx.fiber.state;
31277
+ return state === FIBER_UNLOADING || state === FIBER_DISPOSED;
31278
+ }
31175
31279
 
31176
- // ../../node_modules/.pnpm/@deepseek-ai+dsh-settings-file@0.1.1-rc.2_@deepseek-ai+cordis@4.0.1_@deepseek-ai+dsh-at_07dac851674f547bcb0fed2f2776d133/node_modules/@deepseek-ai/dsh-settings-file/lib/index.js
31280
+ // ../../node_modules/.pnpm/@deepseek-ai+dsh-settings-file@0.1.5-rc.2_@deepseek-ai+cordis@4.0.2_@deepseek-ai+dsh-at_0e4791dacea9086d39c0e6f7037cd78b/node_modules/@deepseek-ai/dsh-settings-file/lib/index.js
31177
31281
  var FORMATS = {
31178
31282
  ".yaml": "yaml",
31179
31283
  ".yml": "yaml",
@@ -31677,7 +31781,7 @@ async function discoverConnection(options, signal) {
31677
31781
  }
31678
31782
 
31679
31783
  // lib/connection/store.js
31680
- var SAG_SETTINGS_NAMESPACE = settingsNamespace("dsh-sag");
31784
+ var SAG_SETTINGS_NAMESPACE = "dsh-sag";
31681
31785
  var SAG_CREDENTIAL_KEY = credentialKey("dsh-sag", "local");
31682
31786
  var SagConnectionConfigurationError = class extends Error {
31683
31787
  /** Stable error code for interactive configuration surfaces. */
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zleap-ai/dsh-sag",
3
3
  "description": "Local SAG personal knowledge base plugin for DeepSeek Harness",
4
- "version": "0.1.0",
4
+ "version": "0.1.1",
5
5
  "keywords": [
6
6
  "deepseek-harness",
7
7
  "dsh",
@@ -52,36 +52,45 @@
52
52
  "node": "^22.19.0 || >=24.0.0"
53
53
  },
54
54
  "dependencies": {
55
- "@deepseek-ai/schemastery": "3.18.1",
55
+ "@deepseek-ai/schemastery": "3.18.2",
56
56
  "@modelcontextprotocol/sdk": "^1.12.0"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "@deepseek-ai/cordis": "^4.0.1",
60
- "@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
61
- "@deepseek-ai/dsh-credentials-local": "0.1.1-rc.2",
62
- "@deepseek-ai/dsh-fs": "0.1.1-rc.2",
63
- "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
64
- "@deepseek-ai/dsh-session": "0.1.1-rc.2",
65
- "@deepseek-ai/dsh-settings": "0.1.1-rc.2",
66
- "@deepseek-ai/dsh-settings-file": "0.1.1-rc.2",
67
- "@deepseek-ai/dsh-subprocess": "0.1.1-rc.2",
68
- "@deepseek-ai/dsh-subprocess-local": "0.1.1-rc.2",
69
- "@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
70
- "@deepseek-ai/dsh-tools": "0.1.1-rc.2"
60
+ "@deepseek-ai/dsh-credentials": ">=0.1.1-rc.2 <0.2.0-0",
61
+ "@deepseek-ai/dsh-credentials-local": ">=0.1.1-rc.2 <0.2.0-0",
62
+ "@deepseek-ai/dsh-fs": ">=0.1.1-rc.2 <0.2.0-0",
63
+ "@deepseek-ai/dsh-llm": ">=0.1.1-rc.2 <0.2.0-0",
64
+ "@deepseek-ai/dsh-session": ">=0.1.1-rc.2 <0.2.0-0",
65
+ "@deepseek-ai/dsh-settings": ">=0.1.1-rc.2 <0.2.0-0",
66
+ "@deepseek-ai/dsh-settings-file": ">=0.1.1-rc.2 <0.2.0-0",
67
+ "@deepseek-ai/dsh-subprocess": ">=0.1.1-rc.2 <0.2.0-0",
68
+ "@deepseek-ai/dsh-subprocess-local": ">=0.1.1-rc.2 <0.2.0-0",
69
+ "@deepseek-ai/dsh-system-prompt": ">=0.1.1-rc.2 <0.2.0-0",
70
+ "@deepseek-ai/dsh-tools": ">=0.1.1-rc.2 <0.2.0-0"
71
71
  },
72
72
  "devDependencies": {
73
- "@deepseek-ai/cordis": "4.0.1",
74
- "@deepseek-ai/dsh-credentials": "0.1.1-rc.2",
75
- "@deepseek-ai/dsh-credentials-local": "0.1.1-rc.2",
76
- "@deepseek-ai/dsh-fs": "0.1.1-rc.2",
77
- "@deepseek-ai/dsh-llm": "0.1.1-rc.2",
78
- "@deepseek-ai/dsh-session": "0.1.1-rc.2",
79
- "@deepseek-ai/dsh-settings": "0.1.1-rc.2",
80
- "@deepseek-ai/dsh-settings-file": "0.1.1-rc.2",
81
- "@deepseek-ai/dsh-subprocess": "0.1.1-rc.2",
82
- "@deepseek-ai/dsh-subprocess-local": "0.1.1-rc.2",
83
- "@deepseek-ai/dsh-system-prompt": "0.1.1-rc.2",
84
- "@deepseek-ai/dsh-tools": "0.1.1-rc.2",
73
+ "@deepseek-ai/cordis": "4.0.2",
74
+ "@deepseek-ai/dsh-agent": "0.1.5-rc.2",
75
+ "@deepseek-ai/dsh-atomic-write": "0.1.5-rc.2",
76
+ "@deepseek-ai/dsh-code-runtime": "0.1.5-rc.2",
77
+ "@deepseek-ai/dsh-credentials": "0.1.5-rc.2",
78
+ "@deepseek-ai/dsh-credentials-local": "0.1.5-rc.2",
79
+ "@deepseek-ai/dsh-fs": "0.1.5-rc.2",
80
+ "@deepseek-ai/dsh-home-paths": "0.1.5-rc.2",
81
+ "@deepseek-ai/dsh-invariants": "0.1.5-rc.2",
82
+ "@deepseek-ai/dsh-launch-environment": "0.1.5-rc.2",
83
+ "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
84
+ "@deepseek-ai/dsh-sandbox": "0.1.5-rc.2",
85
+ "@deepseek-ai/dsh-session": "0.1.5-rc.2",
86
+ "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
87
+ "@deepseek-ai/dsh-settings-file": "0.1.5-rc.2",
88
+ "@deepseek-ai/dsh-scope": "0.1.5-rc.2",
89
+ "@deepseek-ai/dsh-subprocess": "0.1.5-rc.2",
90
+ "@deepseek-ai/dsh-subprocess-local": "0.1.5-rc.2",
91
+ "@deepseek-ai/dsh-system-prompt": "0.1.5-rc.2",
92
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
93
+ "@deepseek-ai/dsh-user-approval": "0.1.5-rc.2",
85
94
  "@types/node": "^24.3.0",
86
95
  "typescript": "^5.9.2"
87
96
  },