@sparkelf/dsh-plus 0.1.0-rc.34 → 0.1.0-rc.36

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 CHANGED
@@ -6,6 +6,7 @@ import { createWriteStream, existsSync, mkdirSync, readFileSync, readdirSync, rm
6
6
  import { dirname, join, posix, resolve, win32 } from "node:path";
7
7
  import { homedir } from "node:os";
8
8
  import semver from "semver";
9
+ import { parseDocument } from "yaml";
9
10
  import { fileURLToPath } from "node:url";
10
11
  import { createServer } from "node:net";
11
12
  //#region lib/types/registry-versions.js
@@ -306,7 +307,8 @@ function resolveDistributionDirectory(anchor) {
306
307
  /** The reviewed bundle order and pins the installed distribution declares. */
307
308
  function readDistributionProfile(distributionDirectory) {
308
309
  const manifest = requireRecord(JSON.parse(readFileSync(join(distributionDirectory, "package.json"), "utf8")), "Plus distribution manifest");
309
- const profile = requireRecord(requireRecord(manifest.dshPlus, "dshPlus").profile, "dshPlus.profile");
310
+ const plus = requireRecord(manifest.dshPlus, "dshPlus");
311
+ const profile = requireRecord(plus.profile, "dshPlus.profile");
310
312
  const rawDependencies = requireRecord(profile.dependencies, "dshPlus.profile.dependencies");
311
313
  const rawAllowBuilds = requireRecord(profile.allowBuilds, "dshPlus.profile.allowBuilds");
312
314
  const dependencies = {};
@@ -319,36 +321,59 @@ function readDistributionProfile(distributionDirectory) {
319
321
  if (typeof allowed !== "boolean") throw new Error("dshPlus.profile.allowBuilds." + name + " must be a boolean");
320
322
  allowBuilds[name] = allowed;
321
323
  }
324
+ const overrides = {};
325
+ const rawOverrides = profile.overrides === void 0 ? {} : requireRecord(profile.overrides, "dshPlus.profile.overrides");
326
+ for (const [name, spec] of Object.entries(rawOverrides)) {
327
+ if (typeof spec !== "string" || spec === "") throw new Error("dshPlus.profile.overrides." + name + " must be a non-empty string");
328
+ overrides[name] = spec;
329
+ }
330
+ const compatibility = requireRecord(plus.compatibility, "dshPlus.compatibility");
322
331
  return {
323
332
  name: String(manifest.name),
324
333
  bundles: requireStringArray(profile.bundles, "dshPlus.profile.bundles"),
325
334
  dependencies,
326
335
  allowBuilds,
336
+ overrides,
337
+ dshRange: String(compatibility.dsh),
327
338
  version: String(manifest.version)
328
339
  };
329
340
  }
330
341
  /**
331
- * Point the profile at the consumer's installed packages.
342
+ * Give the profile its own installed tree, built from the distribution's declarations.
332
343
  *
333
- * The launcher resolves a bundle from the profile directory, so a profile with no
334
- * `node_modules` cannot see packages the consumer installed beside it. One link to
335
- * the consumer's directory keeps a single installed copy as the only authority.
344
+ * The launcher resolves a bundle from the profile directory, so the profile needs its
345
+ * own `node_modules`. Pointing it at the consumer's tree was cheaper, but it made the
346
+ * profile inherit whatever npm had already installed including the official packages
347
+ * the distribution's `overrides` exist to replace. npm applies `overrides` only from a
348
+ * project's own root, so a profile without its own tree cannot receive them at all, and
349
+ * a patch delivered that way silently never arrives.
336
350
  *
337
- * npm hoists what it can and nests the rest, so a bundle can sit at the consumer's
338
- * top level or inside the package that depends on it. The profile reaches the first
339
- * through one link and the second through the distribution's own `node_modules`, and
340
- * a bundle found in neither is one the installation does not carry at all.
351
+ * Installing here makes the profile that root: pnpm reads `overrides` from the
352
+ * profile's own `pnpm-workspace.yaml`, which `writeProfileOverrides` writes before this
353
+ * runs. The install is skipped once the tree exists so a start does not pay for it
354
+ * twice; `dsh-plus apply` remains the command that reinstalls after a change.
341
355
  *
342
356
  * @param paths - resolved standalone paths.
343
- * @param consumerDirectory - directory whose `node_modules` holds the packages.
357
+ * @param consumerDirectory - directory whose `node_modules` holds the installation.
344
358
  */
345
- function linkConsumerPackages(paths, consumerDirectory) {
346
- const target = join(consumerDirectory, "node_modules");
347
- if (!existsSync(target)) throw new Error("no node_modules in " + consumerDirectory + "; run npm install there first");
348
- mkdirSync(paths.profileDirectory, { recursive: true });
349
- const link = join(paths.profileDirectory, "node_modules");
350
- if (!existsSync(link)) symlinkSync(target, link, "junction");
351
- linkNestedBundles(paths, target);
359
+ function installProfilePackages(paths, consumerDirectory) {
360
+ if (!existsSync(join(consumerDirectory, "node_modules"))) throw new Error("no node_modules in " + consumerDirectory + "; run npm install there first");
361
+ const profileModules = join(paths.profileDirectory, "node_modules");
362
+ if (existsSync(profileModules)) {
363
+ linkNestedBundles(paths, profileModules);
364
+ return;
365
+ }
366
+ runPnpm(paths.profileDirectory, ["install", "--no-frozen-lockfile"], "pnpm install in the plus profile");
367
+ linkNestedBundles(paths, profileModules);
368
+ }
369
+ /** Run pnpm in one directory, inheriting its output. */
370
+ function runPnpm(cwd, args, label) {
371
+ const result = spawnSync(process.platform === "win32" ? "pnpm.cmd" : "pnpm", [...args], {
372
+ cwd,
373
+ stdio: "inherit"
374
+ });
375
+ if (result.error !== void 0) throw result.error;
376
+ if (result.status !== 0) throw new Error(label + " failed with exit code " + String(result.status));
352
377
  }
353
378
  /**
354
379
  * Expose the distribution's nested packages at the top level the profile searches.
@@ -405,10 +430,13 @@ function resolvePaths(anchor, env = process.env) {
405
430
  * @returns whether this call created the manifest.
406
431
  */
407
432
  function ensureProfile(paths, consumerDirectory) {
408
- linkConsumerPackages(paths, consumerDirectory);
409
433
  const manifestPath = join(paths.profileDirectory, "package.json");
410
- if (existsSync(manifestPath)) return false;
411
434
  const distribution = readDistributionProfile(paths.distributionDirectory);
435
+ if (existsSync(manifestPath)) {
436
+ writeProfileOverrides(paths.profileDirectory, distribution.overrides, distribution.allowBuilds);
437
+ installProfilePackages(paths, consumerDirectory);
438
+ return false;
439
+ }
412
440
  mkdirSync(paths.profileDirectory, { recursive: true });
413
441
  const manifest = {
414
442
  name: "dsh-profile-plus",
@@ -416,6 +444,7 @@ function ensureProfile(paths, consumerDirectory) {
416
444
  type: "module",
417
445
  dependencies: {
418
446
  "@sparkelf/dsh-plus": distribution.version,
447
+ "@deepseek-ai/dsh": distribution.dshRange,
419
448
  ...distribution.dependencies
420
449
  },
421
450
  dsh: { profile: {
@@ -424,8 +453,32 @@ function ensureProfile(paths, consumerDirectory) {
424
453
  } }
425
454
  };
426
455
  writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
456
+ writeProfileOverrides(paths.profileDirectory, distribution.overrides, distribution.allowBuilds);
457
+ installProfilePackages(paths, consumerDirectory);
427
458
  return true;
428
459
  }
460
+ /**
461
+ * Record the distribution's package substitutions in the profile workspace.
462
+ *
463
+ * pnpm reads \`overrides\` from \`pnpm-workspace.yaml\` since version 10 and ignores the
464
+ * same key in \`package.json\`, so a profile that carried it in the manifest would
465
+ * silently install the official package the override meant to replace.
466
+ *
467
+ * @param profileDirectory - the standalone profile directory.
468
+ * @param overrides - official package name to published replacement spec.
469
+ */
470
+ function writeProfileOverrides(profileDirectory, overrides, allowBuilds) {
471
+ const workspacePath = join(profileDirectory, "pnpm-workspace.yaml");
472
+ const document = parseDocument(existsSync(workspacePath) ? readFileSync(workspacePath, "utf8") : "");
473
+ const [documentError] = document.errors;
474
+ if (documentError !== void 0) throw new Error("Plus profile workspace is not valid YAML", { cause: documentError });
475
+ if (document.get("packages") === void 0) document.set("packages", ["."]);
476
+ for (const [name, spec] of Object.entries(overrides)) document.setIn(["overrides", name], spec);
477
+ for (const [name, allowed] of Object.entries(allowBuilds)) document.setIn(["allowBuilds", name], allowed);
478
+ if (document.get("nodeLinker") === void 0) document.set("nodeLinker", "hoisted");
479
+ if (document.get("autoInstallPeers") === void 0) document.set("autoInstallPeers", false);
480
+ writeFileSync(workspacePath, String(document));
481
+ }
429
482
  /** Run git in one directory, returning undefined instead of throwing when asked to. */
430
483
  function git(root, args, acceptFailure = false) {
431
484
  const result = spawnSync("git", args, {
@@ -54,24 +54,29 @@ export declare function readDistributionProfile(distributionDirectory: string):
54
54
  readonly bundles: readonly string[];
55
55
  readonly dependencies: Readonly<Record<string, string>>;
56
56
  readonly allowBuilds: Readonly<Record<string, boolean>>;
57
+ readonly overrides: Readonly<Record<string, string>>;
58
+ readonly dshRange: string;
57
59
  readonly version: string;
58
60
  };
59
61
  /**
60
- * Point the profile at the consumer's installed packages.
62
+ * Give the profile its own installed tree, built from the distribution's declarations.
61
63
  *
62
- * The launcher resolves a bundle from the profile directory, so a profile with no
63
- * `node_modules` cannot see packages the consumer installed beside it. One link to
64
- * the consumer's directory keeps a single installed copy as the only authority.
64
+ * The launcher resolves a bundle from the profile directory, so the profile needs its
65
+ * own `node_modules`. Pointing it at the consumer's tree was cheaper, but it made the
66
+ * profile inherit whatever npm had already installed including the official packages
67
+ * the distribution's `overrides` exist to replace. npm applies `overrides` only from a
68
+ * project's own root, so a profile without its own tree cannot receive them at all, and
69
+ * a patch delivered that way silently never arrives.
65
70
  *
66
- * npm hoists what it can and nests the rest, so a bundle can sit at the consumer's
67
- * top level or inside the package that depends on it. The profile reaches the first
68
- * through one link and the second through the distribution's own `node_modules`, and
69
- * a bundle found in neither is one the installation does not carry at all.
71
+ * Installing here makes the profile that root: pnpm reads `overrides` from the
72
+ * profile's own `pnpm-workspace.yaml`, which `writeProfileOverrides` writes before this
73
+ * runs. The install is skipped once the tree exists so a start does not pay for it
74
+ * twice; `dsh-plus apply` remains the command that reinstalls after a change.
70
75
  *
71
76
  * @param paths - resolved standalone paths.
72
- * @param consumerDirectory - directory whose `node_modules` holds the packages.
77
+ * @param consumerDirectory - directory whose `node_modules` holds the installation.
73
78
  */
74
- export declare function linkConsumerPackages(paths: StandalonePaths, consumerDirectory: string): void;
79
+ export declare function installProfilePackages(paths: StandalonePaths, consumerDirectory: string): void;
75
80
  /** Resolve every path a command needs, without creating anything. */
76
81
  export declare function resolvePaths(anchor: string, env?: NodeJS.ProcessEnv): StandalonePaths;
77
82
  /**
@@ -13,6 +13,7 @@ import { existsSync, mkdirSync, readdirSync, readFileSync, symlinkSync, writeFil
13
13
  import { createRequire } from 'node:module';
14
14
  import { homedir } from 'node:os';
15
15
  import { dirname, join, posix, resolve, win32 } from 'node:path';
16
+ import { parseDocument } from 'yaml';
16
17
  /** Profile name a standalone installation owns. */
17
18
  export const STANDALONE_PROFILE = 'plus';
18
19
  function requireRecord(value, label) {
@@ -105,41 +106,70 @@ export function readDistributionProfile(distributionDirectory) {
105
106
  throw new Error('dshPlus.profile.allowBuilds.' + name + ' must be a boolean');
106
107
  allowBuilds[name] = allowed;
107
108
  }
109
+ // An override substitutes our republished build for an official package by name: the
110
+ // built code imports the official specifier, so the installed location has to keep
111
+ // that name while its contents come from ours.
112
+ const overrides = {};
113
+ const rawOverrides = profile.overrides === undefined
114
+ ? {}
115
+ : requireRecord(profile.overrides, 'dshPlus.profile.overrides');
116
+ for (const [name, spec] of Object.entries(rawOverrides)) {
117
+ if (typeof spec !== 'string' || spec === '')
118
+ throw new Error('dshPlus.profile.overrides.' + name + ' must be a non-empty string');
119
+ overrides[name] = spec;
120
+ }
121
+ const compatibility = requireRecord(plus.compatibility, 'dshPlus.compatibility');
108
122
  return {
109
123
  name: String(manifest.name),
110
124
  bundles: requireStringArray(profile.bundles, 'dshPlus.profile.bundles'),
111
125
  dependencies,
112
126
  allowBuilds,
127
+ overrides,
128
+ dshRange: String(compatibility.dsh),
113
129
  version: String(manifest.version),
114
130
  };
115
131
  }
116
132
  /**
117
- * Point the profile at the consumer's installed packages.
133
+ * Give the profile its own installed tree, built from the distribution's declarations.
118
134
  *
119
- * The launcher resolves a bundle from the profile directory, so a profile with no
120
- * `node_modules` cannot see packages the consumer installed beside it. One link to
121
- * the consumer's directory keeps a single installed copy as the only authority.
135
+ * The launcher resolves a bundle from the profile directory, so the profile needs its
136
+ * own `node_modules`. Pointing it at the consumer's tree was cheaper, but it made the
137
+ * profile inherit whatever npm had already installed including the official packages
138
+ * the distribution's `overrides` exist to replace. npm applies `overrides` only from a
139
+ * project's own root, so a profile without its own tree cannot receive them at all, and
140
+ * a patch delivered that way silently never arrives.
122
141
  *
123
- * npm hoists what it can and nests the rest, so a bundle can sit at the consumer's
124
- * top level or inside the package that depends on it. The profile reaches the first
125
- * through one link and the second through the distribution's own `node_modules`, and
126
- * a bundle found in neither is one the installation does not carry at all.
142
+ * Installing here makes the profile that root: pnpm reads `overrides` from the
143
+ * profile's own `pnpm-workspace.yaml`, which `writeProfileOverrides` writes before this
144
+ * runs. The install is skipped once the tree exists so a start does not pay for it
145
+ * twice; `dsh-plus apply` remains the command that reinstalls after a change.
127
146
  *
128
147
  * @param paths - resolved standalone paths.
129
- * @param consumerDirectory - directory whose `node_modules` holds the packages.
148
+ * @param consumerDirectory - directory whose `node_modules` holds the installation.
130
149
  */
131
- export function linkConsumerPackages(paths, consumerDirectory) {
132
- const target = join(consumerDirectory, 'node_modules');
133
- if (!existsSync(target)) {
150
+ export function installProfilePackages(paths, consumerDirectory) {
151
+ const consumerModules = join(consumerDirectory, 'node_modules');
152
+ if (!existsSync(consumerModules)) {
134
153
  throw new Error('no node_modules in ' + consumerDirectory + '; run npm install there first');
135
154
  }
136
- mkdirSync(paths.profileDirectory, { recursive: true });
137
- const link = join(paths.profileDirectory, 'node_modules');
138
- if (!existsSync(link))
139
- symlinkSync(target, link, 'junction');
140
- // A profile created before the installation changed must still reach what npm nested
141
- // afterwards, so this runs on every start rather than only when the profile is new.
142
- linkNestedBundles(paths, target);
155
+ const profileModules = join(paths.profileDirectory, 'node_modules');
156
+ if (existsSync(profileModules)) {
157
+ // A profile installed before the distribution declared overrides still needs the
158
+ // packages it reaches from the consumer tree, which npm nested rather than hoisted.
159
+ linkNestedBundles(paths, profileModules);
160
+ return;
161
+ }
162
+ runPnpm(paths.profileDirectory, ['install', '--no-frozen-lockfile'], 'pnpm install in the plus profile');
163
+ linkNestedBundles(paths, profileModules);
164
+ }
165
+ /** Run pnpm in one directory, inheriting its output. */
166
+ function runPnpm(cwd, args, label) {
167
+ const command = process.platform === 'win32' ? 'pnpm.cmd' : 'pnpm';
168
+ const result = spawnSync(command, [...args], { cwd, stdio: 'inherit' });
169
+ if (result.error !== undefined)
170
+ throw result.error;
171
+ if (result.status !== 0)
172
+ throw new Error(label + ' failed with exit code ' + String(result.status));
143
173
  }
144
174
  /**
145
175
  * Expose the distribution's nested packages at the top level the profile searches.
@@ -203,17 +233,30 @@ export function resolvePaths(anchor, env = process.env) {
203
233
  * @returns whether this call created the manifest.
204
234
  */
205
235
  export function ensureProfile(paths, consumerDirectory) {
206
- linkConsumerPackages(paths, consumerDirectory);
207
236
  const manifestPath = join(paths.profileDirectory, 'package.json');
208
- if (existsSync(manifestPath))
209
- return false;
210
237
  const distribution = readDistributionProfile(paths.distributionDirectory);
238
+ if (existsSync(manifestPath)) {
239
+ // The workspace carries decisions the distribution owns — overrides and the build
240
+ // script allowlist — and a distribution release changes them. Rewriting on every
241
+ // start is what lets an upgraded installation receive the new values; a profile
242
+ // written once keeps whatever its own release decided and can never be corrected.
243
+ writeProfileOverrides(paths.profileDirectory, distribution.overrides, distribution.allowBuilds);
244
+ installProfilePackages(paths, consumerDirectory);
245
+ return false;
246
+ }
211
247
  mkdirSync(paths.profileDirectory, { recursive: true });
212
248
  const manifest = {
213
249
  name: 'dsh-profile-' + STANDALONE_PROFILE,
214
250
  private: true,
215
251
  type: 'module',
216
- dependencies: { '@sparkelf/dsh-plus': distribution.version, ...distribution.dependencies },
252
+ dependencies: {
253
+ '@sparkelf/dsh-plus': distribution.version,
254
+ // The launcher's own tree supplies every service package the bundles mount. A
255
+ // profile that lists only the distribution's plugins installs a partial tree and
256
+ // fails at load with a module the launcher would have carried.
257
+ '@deepseek-ai/dsh': distribution.dshRange,
258
+ ...distribution.dependencies,
259
+ },
217
260
  dsh: {
218
261
  profile: {
219
262
  bundles: distribution.bundles,
@@ -222,8 +265,44 @@ export function ensureProfile(paths, consumerDirectory) {
222
265
  },
223
266
  };
224
267
  writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + '\n');
268
+ // The overrides must reach the workspace before the install that reads them.
269
+ writeProfileOverrides(paths.profileDirectory, distribution.overrides, distribution.allowBuilds);
270
+ installProfilePackages(paths, consumerDirectory);
225
271
  return true;
226
272
  }
273
+ /**
274
+ * Record the distribution's package substitutions in the profile workspace.
275
+ *
276
+ * pnpm reads \`overrides\` from \`pnpm-workspace.yaml\` since version 10 and ignores the
277
+ * same key in \`package.json\`, so a profile that carried it in the manifest would
278
+ * silently install the official package the override meant to replace.
279
+ *
280
+ * @param profileDirectory - the standalone profile directory.
281
+ * @param overrides - official package name to published replacement spec.
282
+ */
283
+ function writeProfileOverrides(profileDirectory, overrides, allowBuilds) {
284
+ const workspacePath = join(profileDirectory, 'pnpm-workspace.yaml');
285
+ const document = parseDocument(existsSync(workspacePath) ? readFileSync(workspacePath, 'utf8') : '');
286
+ const [documentError] = document.errors;
287
+ if (documentError !== undefined)
288
+ throw new Error('Plus profile workspace is not valid YAML', { cause: documentError });
289
+ if (document.get('packages') === undefined)
290
+ document.set('packages', ['.']);
291
+ for (const [name, spec] of Object.entries(overrides))
292
+ document.setIn(['overrides', name], spec);
293
+ // pnpm refuses an install whose packages want to run build scripts until each is
294
+ // decided, so the distribution's reviewed decisions travel with the install rather
295
+ // than waiting for an interactive approval no start can offer.
296
+ for (const [name, allowed] of Object.entries(allowBuilds))
297
+ document.setIn(['allowBuilds', name], allowed);
298
+ // The profile resolves bundles from this directory, so peers the official tree would
299
+ // supply have to come from what the consumer installed.
300
+ if (document.get('nodeLinker') === undefined)
301
+ document.set('nodeLinker', 'hoisted');
302
+ if (document.get('autoInstallPeers') === undefined)
303
+ document.set('autoInstallPeers', false);
304
+ writeFileSync(workspacePath, String(document));
305
+ }
227
306
  /** Run git in one directory, returning undefined instead of throwing when asked to. */
228
307
  function git(root, args, acceptFailure = false) {
229
308
  const result = spawnSync('git', args, { cwd: root, encoding: 'utf8' });
package/package.json CHANGED
@@ -58,12 +58,16 @@
58
58
  ],
59
59
  "profile": {
60
60
  "allowBuilds": {
61
- "@officecli/officecli": true,
62
- "cpu-features": false,
63
- "node-pty": true,
64
- "oracledb": true,
65
- "protobufjs": false,
66
- "ssh2": true
61
+ "@deepseek-ai/dsh-subprocess-local@0.1.5-rc.2": true,
62
+ "@google/genai@1.52.0": false,
63
+ "@officecli/officecli@1.0.147": true,
64
+ "cpu-features@0.0.10": false,
65
+ "koffi@3.3.0": true,
66
+ "node-pty@1.1.0": true,
67
+ "node-pty@1.2.0-beta.15": true,
68
+ "oracledb@7.0.1": true,
69
+ "protobufjs@7.6.6": false,
70
+ "ssh2@1.17.0": true
67
71
  },
68
72
  "bundles": [
69
73
  "@deepseek-ai/dsh-base",
@@ -98,6 +102,28 @@
98
102
  "dsh-better-sidebar": "0.19.1",
99
103
  "dsh-sql-workbench": "0.5.1",
100
104
  "dsh-video-preview": "0.1.4"
105
+ },
106
+ "overrides": {
107
+ "@deepseek-ai/dsh-agent-presets": "npm:@sparkelf/dsh-agent-presets@0.1.5-rc.6",
108
+ "@deepseek-ai/dsh-api-gateway": "npm:@sparkelf/dsh-api-gateway@0.1.5-rc.6",
109
+ "@deepseek-ai/dsh-api-session-controller": "npm:@sparkelf/dsh-api-session-controller@0.1.5-rc.6",
110
+ "@deepseek-ai/dsh-client-connection": "npm:@sparkelf/dsh-client-connection@0.1.5-rc.6",
111
+ "@deepseek-ai/dsh-client-ui-agent-preset": "npm:@sparkelf/dsh-client-ui-agent-preset@0.1.5-rc.6",
112
+ "@deepseek-ai/dsh-client-ui-conversation": "npm:@sparkelf/dsh-client-ui-conversation@0.1.5-rc.6",
113
+ "@deepseek-ai/dsh-client-ui-deliverables": "npm:@sparkelf/dsh-client-ui-deliverables@0.1.5-rc.6",
114
+ "@deepseek-ai/dsh-client-ui-layout": "npm:@sparkelf/dsh-client-ui-layout@0.1.5-rc.6",
115
+ "@deepseek-ai/dsh-client-ui-model-selection": "npm:@sparkelf/dsh-client-ui-model-selection@0.1.5-rc.6",
116
+ "@deepseek-ai/dsh-client-ui-primitives": "npm:@sparkelf/dsh-client-ui-primitives@0.1.5-rc.6",
117
+ "@deepseek-ai/dsh-client-ui-settings-models": "npm:@sparkelf/dsh-client-ui-settings-models@0.1.5-rc.6",
118
+ "@deepseek-ai/dsh-client-ui-trajectory": "npm:@sparkelf/dsh-client-ui-trajectory@0.1.5-rc.6",
119
+ "@deepseek-ai/dsh-host-frontend-static": "npm:@sparkelf/dsh-host-frontend-static@0.1.5-rc.6",
120
+ "@deepseek-ai/dsh-host-webserver": "npm:@sparkelf/dsh-host-webserver@0.1.5-rc.6",
121
+ "@deepseek-ai/dsh-llm-pi-ai": "npm:@sparkelf/dsh-llm-pi-ai@0.1.5-rc.6",
122
+ "@deepseek-ai/dsh-session-log-export": "npm:@sparkelf/dsh-session-log-export@0.1.5-rc.6",
123
+ "@deepseek-ai/dsh-tools": "npm:@sparkelf/dsh-tools@0.1.5-rc.6",
124
+ "@deepseek-ai/dsh-web-app": "npm:@sparkelf/dsh-web-app@0.1.5-rc.6",
125
+ "@deepseek-ai/dsh-web-frontend": "npm:@sparkelf/dsh-web-frontend@0.1.5-rc.6",
126
+ "@deepseek-ai/dsh-workspace": "npm:@sparkelf/dsh-workspace@0.1.5-rc.6"
101
127
  }
102
128
  },
103
129
  "sourceBase": {
@@ -140,5 +166,5 @@
140
166
  },
141
167
  "type": "module",
142
168
  "types": "lib/types/index.d.ts",
143
- "version": "0.1.0-rc.34"
169
+ "version": "0.1.0-rc.36"
144
170
  }