@deepseek-ai/dsh-subagent 0.1.7-alpha.2 → 0.1.7-rc.2

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.
@@ -1,10 +1,6 @@
1
1
  /**
2
- * Direct-child discovery from a parent-owned `subagent/catalog` projection,
3
- * plus complete descendant-tree enumeration from the Session corpus. A direct
4
- * listing owns one parent observation and reads no child log. Descendant
5
- * enumeration retains the complete corpus and the child identity projection
6
- * because ordinary Sessions and one-shot children remain traversal nodes.
7
- *
2
+ * Direct-child and recursive descendant discovery from parent-owned catalogs.
3
+ * Each catalog read releases its Session observation before the next branch.
8
4
  * @module @deepseek-ai/dsh-subagent
9
5
  */
10
6
  var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
@@ -60,12 +56,6 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
60
56
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
61
57
  });
62
58
  import { SubagentError } from "./error.js";
63
- /**
64
- * Concurrent cold observations per explicit catalog listing. Current Session
65
- * persistence providers are local; a networked provider must promote this to
66
- * a validated deployment setting.
67
- */
68
- const COLD_READ_CONCURRENCY = 4;
69
59
  /**
70
60
  * Read one parent's durable catalog through a live-preferred Session observation.
71
61
  * @param ctx - context carrying the Session query service.
@@ -99,279 +89,78 @@ export async function listChildren(ctx, parentSessionId, signal) {
99
89
  }
100
90
  }
101
91
  /**
102
- * Enumerate every session-backed subagent below one root in stable pre-order.
103
- * Ordinary sessions and one-shot children remain traversal nodes, so a
104
- * continuable child below either is still discovered. Classification uses the
105
- * registered child identity projection; no Agent is loaded or resumed.
106
- * @see SubagentRuntime.listDescendants for the public cancellation and failure contract.
107
- * @param ctx - context carrying the session store, projection registry, and optional persistence/cache.
108
- * @param rootSessionId - session whose complete descendant tree is listed.
109
- * @param signal - caller-owned cancellation observed around every persistence read.
110
- * @returns interpreted subagents with durable direct-parent and root-relative depth.
111
- * @throws {@link SubagentError} when listing dependencies are unavailable or the caller cancels.
92
+ * Walk reachable parent catalogs in stable pre-order without loading Agents.
93
+ * @see SubagentRuntime.listDescendants for failure and cancellation semantics.
94
+ * @param ctx - context carrying the Session store and query service.
95
+ * @param rootSessionId - parent whose catalog starts the traversal.
96
+ * @param signal - cancellation checked around each catalog read.
97
+ * @returns children and branch diagnostics with catalog parent and depth.
112
98
  */
113
99
  export async function listDescendants(ctx, rootSessionId, signal) {
114
- const listing = await prepareListing(ctx, signal);
115
- const positioned = descendantCandidates(listing.corpus, rootSessionId);
116
- const rows = await resolveCandidateRows(positioned.map(candidate => candidate.record), listing, signal);
117
- const entries = [];
118
- positioned.forEach((position, index) => {
119
- const row = rows[index];
120
- if (row !== undefined) {
121
- entries.push({ ...row, parentId: position.parentId, depth: position.depth });
122
- }
123
- });
124
- return entries;
125
- }
126
- /** Resolve listing services once and build one live-preferred session corpus. */
127
- async function prepareListing(ctx, signal) {
128
- const projections = ctx.get('sessionProjections');
129
- // Checked before any read, even with zero candidates: mode/label are the
130
- // row's strong contract, so a missing fold capability is a deterministic
131
- // deployment configuration error, never an empty success.
132
- if (projections === undefined) {
133
- throw new SubagentError('listing subagents requires the sessionProjections registry (load @deepseek-ai/dsh-session-projection)', 'SUBAGENT_CONTROL_PROJECTIONS_UNAVAILABLE');
134
- }
135
- // Strict global read, never the `ctx.sessions` property proxy: the proxy is
136
- // caller-scope bound, so a consumer plugin without its own `sessions`
137
- // injection (the model-facing tool, the API proxy) would throw on access.
138
100
  const sessions = ctx.get('sessions');
139
101
  if (sessions === undefined) {
140
102
  throw new SubagentError('listing subagents requires the session store (load @deepseek-ai/dsh-session)', 'SUBAGENT_CONTROL_SESSION_STORE_UNAVAILABLE');
141
103
  }
142
- assertListingNotCancelled(signal);
143
- const query = ctx.get('sessionQuery');
144
- if (query === undefined) {
145
- throw new SubagentError('listing subagents requires the sessionQuery service (load @deepseek-ai/dsh-session-query)', 'SUBAGENT_CONTROL_QUERY_UNAVAILABLE');
146
- }
147
- // Optional acceleration only: an absent cache service just means every
148
- // cold candidate takes the authoritative preparation rung, so it carries
149
- // no error code and no configuration check.
150
- const cache = ctx.get('sessionProjectionCache');
151
- let records;
152
- try {
153
- records = await query.listSessions(signal);
154
- }
155
- catch (error) {
104
+ const readChildren = async (id) => {
156
105
  assertListingNotCancelled(signal);
157
- throw error;
158
- }
159
- assertListingNotCancelled(signal);
160
- // Live-preferred merge without header reconciliation: a live record wins
161
- // its id wholesale, exactly as a live-preferred corpus would serve it.
162
- const corpus = new Map();
163
- for (const record of records) {
164
- const live = sessions.get(record.header.id);
165
- corpus.set(record.header.id, {
166
- header: live?.header ?? record.header,
167
- live,
168
- });
169
- }
170
- const subagentParents = new Set();
171
- for (const record of corpus.values()) {
172
- if (record.header.origin === 'subagent' && record.header.parentSession !== undefined) {
173
- subagentParents.add(record.header.parentSession);
174
- }
175
- }
176
- return { projections, query, cache, corpus, subagentParents };
177
- }
178
- /** Resolve projection-backed rows for aligned candidates with bounded cold reads. */
179
- async function resolveCandidateRows(candidates, listing, signal) {
180
- const { projections, query, cache, subagentParents } = listing;
181
- const rows = Array.from({ length: candidates.length });
182
- const coldReads = [];
183
- candidates.forEach((candidate, index) => {
184
- const childId = candidate.header.id;
185
- if (candidate.live === undefined) {
186
- coldReads.push({ index, header: candidate.header });
187
- return;
188
- }
189
- // Read only the identity unit. A live child without an identity yet is the
190
- // creation window before the establishing provider appends its descriptor.
191
- let identity;
106
+ let children;
192
107
  try {
193
- identity = projections.snapshot(candidate.live, ['subagent']).values.subagent;
108
+ children = await listChildren(ctx, id, signal);
194
109
  }
195
- catch {
196
- // A rejecting identity fold is deterministic data damage in this child;
197
- // contain it as one diagnostic instead of failing the whole listing.
198
- rows[index] = { kind: 'diagnostic', id: childId, reason: 'corrupt' };
199
- return;
110
+ catch (error) {
111
+ assertListingNotCancelled(signal);
112
+ throw error;
200
113
  }
201
- // The unit's serializable no-value sentinel is `null`; `undefined` can
202
- // only mean the key was dropped at a JSON boundary. Both are no value.
203
- if (identity === undefined || identity === null
204
- || !candidate.live.isOwnSeq(identity.seq))
205
- return;
206
- rows[index] = childRow(childId, identity, 'running', subagentParents.has(childId));
207
- });
208
- // Cold candidates came from the query corpus and are resolved concurrently.
209
- if (coldReads.length > 0) {
210
- const queue = [...coldReads];
211
- await Promise.all(Array.from({ length: Math.min(COLD_READ_CONCURRENCY, queue.length) }, async () => {
212
- for (let job = queue.shift(); job !== undefined; job = queue.shift()) {
213
- rows[job.index] = await resolveColdIdentity(query, cache, job.header, subagentParents.has(job.header.id), signal);
214
- }
215
- }));
216
- }
217
- assertListingNotCancelled(signal);
218
- return rows;
219
- }
220
- /** Build origin-classified candidates from the complete tree without recursion. */
221
- function descendantCandidates(corpus, rootSessionId) {
222
- const children = new Map();
223
- for (const record of corpus.values()) {
224
- const parentId = record.header.parentSession;
225
- if (parentId === undefined)
226
- continue;
227
- const siblings = children.get(parentId);
228
- if (siblings === undefined)
229
- children.set(parentId, [record]);
230
- else
231
- siblings.push(record);
232
- }
233
- for (const siblings of children.values())
234
- siblings.sort(compareCorpusRecords);
235
- const positioned = [];
236
- const stack = (children.get(rootSessionId) ?? [])
237
- .map(record => ({ record, parentId: rootSessionId, depth: 1 }))
114
+ assertListingNotCancelled(signal);
115
+ return children;
116
+ };
117
+ const stack = (await readChildren(rootSessionId))
118
+ .map(entry => ({ entry, parentId: rootSessionId, depth: 1 }))
238
119
  .reverse();
239
120
  const visited = new Set([rootSessionId]);
240
- while (stack.length > 0) {
241
- // The length guard proves one frame exists.
242
- // oxlint-disable-next-line typescript/no-non-null-assertion
243
- const position = stack.pop();
244
- const id = position.record.header.id;
245
- if (visited.has(id))
121
+ const result = [];
122
+ for (let position = stack.pop(); position !== undefined; position = stack.pop()) {
123
+ const { entry, parentId, depth } = position;
124
+ if (visited.has(entry.id))
246
125
  continue;
247
- visited.add(id);
248
- if (position.record.header.origin === 'subagent')
249
- positioned.push(position);
250
- const descendants = children.get(id) ?? [];
251
- for (const record of [...descendants].reverse()) {
252
- stack.push({ record, parentId: id, depth: position.depth + 1 });
253
- }
254
- }
255
- return positioned;
256
- }
257
- /** Compare siblings by durable creation time, then id. */
258
- function compareCorpusRecords(a, b) {
259
- return a.header.createdAt - b.header.createdAt || a.header.id.localeCompare(b.header.id);
260
- }
261
- /**
262
- * Resolve one cold candidate down the remaining ladder: an unseeded durable
263
- * projection-cache row, otherwise one shared Session observation. An absent or transiently failed
264
- * observation is one `unavailable` row retried on the next listing; an observation
265
- * source naming another lifecycle, and a
266
- * settled log the fold cannot identify — or that makes any registered unit
267
- * throw — are final, so they report `corrupt`.
268
- */
269
- async function resolveColdIdentity(query, cache, header, hasChildren, signal) {
270
- const env_2 = { stack: [], error: void 0, hasError: false };
271
- try {
272
- const childId = header.id;
273
- // A header deliberately exposes only whether a fork cut exists, not its
274
- // integer. An unseeded lifecycle has the exact cut 0, so its cached
275
- // descriptor is owned at every valid seq; a seeded lifecycle must read the
276
- // body before an identity seq can be classified as inherited or owned.
277
- if (cache !== undefined && !header.isSeeded) {
278
- let cached;
279
- try {
280
- cached = cache.cachedSnapshot(header, ['subagent'])?.values.subagent;
281
- }
282
- catch {
283
- // Unlike the preparation fold below, a throwing cache read renders no
284
- // verdict: the cache is derived data, so its damage (a poisoned stored
285
- // row of ANY unit) silently falls through to the authoritative re-fold.
286
- cached = undefined;
287
- }
288
- // An unseeded child's descriptor is owned at every valid seq. Everything
289
- // else falls through to preparation: an absent key and the `null`
290
- // sentinel, whose verdict belongs to the authoritative re-fold, not to a
291
- // derived row.
292
- if (cached !== undefined && cached !== null) {
293
- return childRow(childId, cached, 'inactive', hasChildren);
294
- }
295
- }
296
- assertListingNotCancelled(signal);
297
- let observation;
126
+ visited.add(entry.id);
127
+ let children;
298
128
  try {
299
- observation = await query.observeSession(childId, {
300
- ...(signal === undefined ? {} : { signal }),
301
- });
129
+ children = await readChildren(entry.id);
302
130
  }
303
131
  catch (error) {
304
- // Per-child isolation: durable corruption is stable; absence and backend
305
- // failures remain retryable. Either way, the listing itself still succeeds.
306
- assertListingNotCancelled(signal);
307
- return {
308
- kind: 'diagnostic',
309
- id: childId,
310
- reason: sessionQueryCode(error) === 'SESSION_QUERY_CORRUPT_SESSION'
311
- || sessionQueryCode(error) === 'SESSION_QUERY_SOURCE_CONFLICT'
312
- ? 'corrupt'
313
- : 'unavailable',
314
- };
132
+ if (error instanceof SubagentError)
133
+ throw error;
134
+ const code = error instanceof Error && 'code' in error ? error.code : undefined;
135
+ result.push({
136
+ kind: 'diagnostic', id: entry.id, parentId, depth,
137
+ reason: code === 'SESSION_QUERY_CORRUPT_SESSION' || code === 'SESSION_QUERY_SOURCE_CONFLICT'
138
+ ? 'corrupt' : 'unavailable',
139
+ });
140
+ continue;
315
141
  }
316
- const ownedObservation = __addDisposableResource(env_2, observation, false);
317
- assertListingNotCancelled(signal);
318
- // A session id names a slot, not a lifecycle: a child deleted and
319
- // re-published under another owner between the enumeration and this read
320
- // must not leak into the old parent's listing.
321
- if (!sameLifecycle(ownedObservation.header, header)) {
322
- return { kind: 'diagnostic', id: childId, reason: 'corrupt' };
142
+ if (entry.mode === 'unknown') {
143
+ result.push({ kind: 'diagnostic', id: entry.id, parentId, depth, reason: 'unsupported' });
323
144
  }
324
- const identity = ownedObservation.projections?.values.subagent;
325
- if (identity === undefined || identity === null
326
- || identity.seq < ownedObservation.inheritedEventCount) {
327
- return { kind: 'diagnostic', id: childId, reason: 'corrupt' };
145
+ else {
146
+ const { createdAt: _createdAt, ...identity } = entry;
147
+ result.push({
148
+ ...identity, kind: 'child', parentId, depth,
149
+ activity: sessions.get(entry.id) === undefined ? 'inactive' : 'running',
150
+ hasChildren: children.length > 0,
151
+ });
328
152
  }
329
- return childRow(childId, identity, 'inactive', hasChildren);
330
- }
331
- catch (e_2) {
332
- env_2.error = e_2;
333
- env_2.hasError = true;
334
- }
335
- finally {
336
- __disposeResources(env_2);
337
- }
338
- }
339
- /** Materialize one served identity as its child row. */
340
- function childRow(id, identity, activity, hasChildren) {
341
- return identity.mode === 'one-shot'
342
- ? {
343
- kind: 'child',
344
- id,
345
- mode: 'one-shot',
346
- ...identity.label !== undefined ? { label: identity.label } : {},
347
- activity,
348
- hasChildren,
153
+ // Catalog event order defines siblings; the stack visits the first one next.
154
+ for (const child of [...children].reverse()) {
155
+ stack.push({ entry: child, parentId: entry.id, depth: depth + 1 });
349
156
  }
350
- : {
351
- kind: 'child',
352
- id,
353
- mode: 'continuable',
354
- label: identity.label,
355
- activity,
356
- hasChildren,
357
- };
358
- }
359
- /** Immutable header fields that distinguish one session lifecycle from another under the same id. */
360
- const LIFECYCLE_WITNESS_KEYS = [
361
- 'version', 'id', 'createdAt', 'cwd', 'parentSession', 'isSeeded', 'delegationDepth',
362
- 'origin', 'agentPreset',
363
- ];
364
- /** Whether an inspected log still belongs to the enumerated lifecycle. */
365
- function sameLifecycle(meta, expected) {
366
- return LIFECYCLE_WITNESS_KEYS.every(key => meta[key] === expected[key]);
157
+ }
158
+ return result;
367
159
  }
368
- /** Stop a listing at its next cancellation checkpoint. */
160
+ /** Stop the complete traversal when its caller cancels. */
369
161
  function assertListingNotCancelled(signal) {
370
162
  if (signal?.aborted) {
371
163
  throw new SubagentError('subagent listing was cancelled', 'CANCELLED');
372
164
  }
373
165
  }
374
- function sessionQueryCode(error) {
375
- return error instanceof Error && 'code' in error ? error.code : undefined;
376
- }
377
166
  //# sourceMappingURL=list-children.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-subagent",
3
3
  "description": "Abstract subagent seam (ctx.subagents): named-provider registry for delegating to child agents",
4
- "version": "0.1.7-alpha.2",
4
+ "version": "0.1.7-rc.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -54,34 +54,33 @@
54
54
  "license": "MIT",
55
55
  "dependencies": {
56
56
  "zod": "^4.4.3",
57
- "@deepseek-ai/dsh-chunked-list": "0.1.7-alpha.2",
58
- "@deepseek-ai/dsh-brand": "0.1.7-alpha.2",
59
- "@deepseek-ai/dsh-util-values": "0.1.7-alpha.2",
57
+ "@deepseek-ai/dsh-brand": "0.1.7-rc.2",
58
+ "@deepseek-ai/dsh-util-values": "0.1.7-rc.2",
59
+ "@deepseek-ai/dsh-chunked-list": "0.1.7-rc.2",
60
60
  "@deepseek-ai/schemastery": "~3.18.4"
61
61
  },
62
62
  "peerDependencies": {
63
63
  "@deepseek-ai/cordis": "~4.0.4",
64
- "@deepseek-ai/dsh-agent": "0.1.7-alpha.2",
65
- "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-alpha.2",
66
- "@deepseek-ai/dsh-attachment": "0.1.7-alpha.2",
67
- "@deepseek-ai/dsh-invariants": "0.1.7-alpha.2",
68
- "@deepseek-ai/dsh-llm": "0.1.7-alpha.2",
69
- "@deepseek-ai/dsh-jobs": "0.1.7-alpha.2",
70
- "@deepseek-ai/dsh-sandbox": "0.1.7-alpha.2",
71
- "@deepseek-ai/dsh-sandbox-policy": "0.1.7-alpha.2",
72
- "@deepseek-ai/dsh-scope": "0.1.7-alpha.2",
73
- "@deepseek-ai/dsh-session": "0.1.7-alpha.2",
74
- "@deepseek-ai/dsh-session-persistence": "0.1.7-alpha.2",
75
- "@deepseek-ai/dsh-session-projection": "0.1.7-alpha.2",
76
- "@deepseek-ai/dsh-system-prompt": "0.1.7-alpha.2",
77
- "@deepseek-ai/dsh-tools": "0.1.7-alpha.2",
78
- "@deepseek-ai/dsh-typert-protocol": "0.1.7-alpha.2",
79
- "@deepseek-ai/dsh-user-approval": "0.1.7-alpha.2",
80
- "@deepseek-ai/dsh-workspace": "0.1.7-alpha.2",
81
- "@deepseek-ai/dsh-util-time": "0.1.7-alpha.2",
82
- "@deepseek-ai/dsh-session-query": "0.1.7-alpha.2",
83
- "@deepseek-ai/dsh-session-projection-cache": "0.1.7-alpha.2",
84
- "@deepseek-ai/dsh-permission-presets": "0.1.7-alpha.2"
64
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.2",
65
+ "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2",
66
+ "@deepseek-ai/dsh-attachment": "0.1.7-rc.2",
67
+ "@deepseek-ai/dsh-invariants": "0.1.7-rc.2",
68
+ "@deepseek-ai/dsh-jobs": "0.1.7-rc.2",
69
+ "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2",
70
+ "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2",
71
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
72
+ "@deepseek-ai/dsh-scope": "0.1.7-rc.2",
73
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
74
+ "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2",
75
+ "@deepseek-ai/dsh-session-query": "0.1.7-rc.2",
76
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2",
77
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2",
78
+ "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2",
79
+ "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2",
80
+ "@deepseek-ai/dsh-util-time": "0.1.7-rc.2",
81
+ "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2",
82
+ "@deepseek-ai/dsh-workspace": "0.1.7-rc.2",
83
+ "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2"
85
84
  },
86
85
  "peerDependenciesMeta": {
87
86
  "@deepseek-ai/dsh-agent-preset-registry": {
@@ -102,9 +101,6 @@
102
101
  "@deepseek-ai/dsh-session-projection": {
103
102
  "optional": true
104
103
  },
105
- "@deepseek-ai/dsh-session-projection-cache": {
106
- "optional": true
107
- },
108
104
  "@deepseek-ai/dsh-session-query": {
109
105
  "optional": true
110
106
  },
@@ -122,31 +118,30 @@
122
118
  }
123
119
  },
124
120
  "devDependencies": {
121
+ "@deepseek-ai/dsh-agent": "0.1.7-rc.2",
125
122
  "@deepseek-ai/cordis": "~4.0.4",
126
- "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-alpha.2",
127
- "@deepseek-ai/dsh-attachment": "0.1.7-alpha.2",
128
- "@deepseek-ai/dsh-invariants": "0.1.7-alpha.2",
129
- "@deepseek-ai/dsh-jobs": "0.1.7-alpha.2",
130
- "@deepseek-ai/dsh-llm": "0.1.7-alpha.2",
131
- "@deepseek-ai/dsh-sandbox": "0.1.7-alpha.2",
132
- "@deepseek-ai/dsh-sandbox-policy": "0.1.7-alpha.2",
133
- "@deepseek-ai/dsh-scope": "0.1.7-alpha.2",
134
- "@deepseek-ai/dsh-schedule": "0.1.7-alpha.2",
135
- "@deepseek-ai/dsh-session": "0.1.7-alpha.2",
136
- "@deepseek-ai/dsh-session-persistence": "0.1.7-alpha.2",
137
- "@deepseek-ai/dsh-session-projection": "0.1.7-alpha.2",
138
- "@deepseek-ai/dsh-session-projection-cache": "0.1.7-alpha.2",
139
- "@deepseek-ai/dsh-storage": "0.1.7-alpha.2",
140
- "@deepseek-ai/dsh-storage-json": "0.1.7-alpha.2",
141
- "@deepseek-ai/dsh-system-prompt": "0.1.7-alpha.2",
142
- "@deepseek-ai/dsh-tools": "0.1.7-alpha.2",
143
- "@deepseek-ai/dsh-user-approval": "0.1.7-alpha.2",
144
- "@deepseek-ai/dsh-typert-protocol": "0.1.7-alpha.2",
145
- "@deepseek-ai/dsh-util-time": "0.1.7-alpha.2",
146
- "@deepseek-ai/dsh-workspace": "0.1.7-alpha.2",
147
- "@deepseek-ai/dsh-permission-presets": "0.1.7-alpha.2",
148
- "@deepseek-ai/dsh-storage-domain": "0.1.7-alpha.2",
149
- "@deepseek-ai/dsh-session-query": "0.1.7-alpha.2",
150
- "@deepseek-ai/dsh-agent": "0.1.7-alpha.2"
123
+ "@deepseek-ai/dsh-agent-preset-registry": "0.1.7-rc.2",
124
+ "@deepseek-ai/dsh-attachment": "0.1.7-rc.2",
125
+ "@deepseek-ai/dsh-invariants": "0.1.7-rc.2",
126
+ "@deepseek-ai/dsh-jobs": "0.1.7-rc.2",
127
+ "@deepseek-ai/dsh-llm": "0.1.7-rc.2",
128
+ "@deepseek-ai/dsh-sandbox": "0.1.7-rc.2",
129
+ "@deepseek-ai/dsh-sandbox-policy": "0.1.7-rc.2",
130
+ "@deepseek-ai/dsh-schedule": "0.1.7-rc.2",
131
+ "@deepseek-ai/dsh-scope": "0.1.7-rc.2",
132
+ "@deepseek-ai/dsh-session": "0.1.7-rc.2",
133
+ "@deepseek-ai/dsh-session-persistence": "0.1.7-rc.2",
134
+ "@deepseek-ai/dsh-session-projection": "0.1.7-rc.2",
135
+ "@deepseek-ai/dsh-session-query": "0.1.7-rc.2",
136
+ "@deepseek-ai/dsh-storage": "0.1.7-rc.2",
137
+ "@deepseek-ai/dsh-storage-domain": "0.1.7-rc.2",
138
+ "@deepseek-ai/dsh-storage-json": "0.1.7-rc.2",
139
+ "@deepseek-ai/dsh-system-prompt": "0.1.7-rc.2",
140
+ "@deepseek-ai/dsh-tools": "0.1.7-rc.2",
141
+ "@deepseek-ai/dsh-typert-protocol": "0.1.7-rc.2",
142
+ "@deepseek-ai/dsh-user-approval": "0.1.7-rc.2",
143
+ "@deepseek-ai/dsh-util-time": "0.1.7-rc.2",
144
+ "@deepseek-ai/dsh-permission-presets": "0.1.7-rc.2",
145
+ "@deepseek-ai/dsh-workspace": "0.1.7-rc.2"
151
146
  }
152
147
  }