@deepseek-ai/dsh-api-workspace-files 0.1.5-alpha.1 → 0.1.5-alpha.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.
- package/README.i18n.yaml +2 -2
- package/README.md +21 -19
- package/README.zh.md +21 -19
- package/lib/client.js +34 -82
- package/lib/index.js +138 -62
- package/lib/typert.host.js +160 -525
- package/lib/typert.remote-client.d.ts +14 -17
- package/lib/typert.remote-client.js +125 -40
- package/lib/types/changes.d.ts +2 -2
- package/lib/types/changes.js +2 -2
- package/lib/types/client/change-feed.d.ts +6 -18
- package/lib/types/client/change-feed.js +6 -38
- package/lib/types/client/index.d.ts +3 -4
- package/lib/types/client/index.js +4 -8
- package/lib/types/client/provider.d.ts +9 -20
- package/lib/types/client/provider.js +13 -33
- package/lib/types/client/types.d.ts +7 -26
- package/lib/types/index.d.ts +65 -50
- package/lib/types/index.js +108 -61
- package/lib/types/types.d.ts +4 -4
- package/package.json +12 -14
package/lib/types/index.js
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Workspace file service:
|
|
3
|
-
* listings, and the
|
|
4
|
-
*
|
|
2
|
+
* Workspace file service: read-only file previews, workspace directory
|
|
3
|
+
* listings, and the filesystem-observation change feed, exposed as
|
|
4
|
+
* `workspaceFiles`.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* path strings: `resolve` realpaths, so a prefix test cannot see a symlink
|
|
13
|
-
* that leaves the root. `lstat` rejects a link before that follow happens.
|
|
14
|
-
* 3. Every cap is validated Config, changeable per deployment. A page is cut by
|
|
15
|
-
* lines and refused, not shortened, when its bytes exceed the byte cap; a
|
|
16
|
-
* listing is cut by entries and says so.
|
|
17
|
-
* 4. Failures are one `RemoteError` per reason, declared in `./types`.
|
|
6
|
+
* File reads follow the composed filesystem's read access, including paths
|
|
7
|
+
* outside the workspace. The selected Session header supplies the base for
|
|
8
|
+
* relative paths, with the sandbox policy root as its no-cwd fallback, not a
|
|
9
|
+
* read-containment restriction. Directory listings and change observations
|
|
10
|
+
* remain workspace-scoped. File-kind checks and configured read caps apply to
|
|
11
|
+
* every preview; this service exposes no mutations.
|
|
18
12
|
*
|
|
19
13
|
* A page is cut from `streamText`, which decodes and rejects non-UTF-8 as it
|
|
20
14
|
* goes, so the file is read only up to the first character past the page and
|
|
@@ -58,6 +52,7 @@ var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn,
|
|
|
58
52
|
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
59
53
|
done = true;
|
|
60
54
|
};
|
|
55
|
+
import { posix, win32 } from 'node:path';
|
|
61
56
|
import z from '@deepseek-ai/schemastery';
|
|
62
57
|
import { Remote, RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
|
|
63
58
|
import { WorkspaceChangeFeed } from "./changes.js";
|
|
@@ -139,12 +134,14 @@ function directoryEntry(child) {
|
|
|
139
134
|
...child.size === undefined ? {} : { size: child.size },
|
|
140
135
|
};
|
|
141
136
|
}
|
|
142
|
-
/** Host Remote
|
|
137
|
+
/** Host Remote file reads and workspace directory observations over the composed filesystem. */
|
|
143
138
|
let WorkspaceFiles = (() => {
|
|
144
139
|
let _classSuper = TypertRemoteService;
|
|
145
140
|
let _instanceExtraInitializers = [];
|
|
146
141
|
let _read_decorators;
|
|
147
142
|
let _readBytes_decorators;
|
|
143
|
+
let _readAll_decorators;
|
|
144
|
+
let _readRelated_decorators;
|
|
148
145
|
let _stat_decorators;
|
|
149
146
|
let _list_decorators;
|
|
150
147
|
let _changes_decorators;
|
|
@@ -153,20 +150,25 @@ let WorkspaceFiles = (() => {
|
|
|
153
150
|
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
154
151
|
_read_decorators = [Remote];
|
|
155
152
|
_readBytes_decorators = [Remote];
|
|
153
|
+
_readAll_decorators = [Remote];
|
|
154
|
+
_readRelated_decorators = [Remote];
|
|
156
155
|
_stat_decorators = [Remote];
|
|
157
156
|
_list_decorators = [Remote];
|
|
158
157
|
_changes_decorators = [Remote({ mode: 'stream' })];
|
|
159
158
|
__esDecorate(this, null, _read_decorators, { kind: "method", name: "read", static: false, private: false, access: { has: obj => "read" in obj, get: obj => obj.read }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
160
159
|
__esDecorate(this, null, _readBytes_decorators, { kind: "method", name: "readBytes", static: false, private: false, access: { has: obj => "readBytes" in obj, get: obj => obj.readBytes }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
160
|
+
__esDecorate(this, null, _readAll_decorators, { kind: "method", name: "readAll", static: false, private: false, access: { has: obj => "readAll" in obj, get: obj => obj.readAll }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
161
|
+
__esDecorate(this, null, _readRelated_decorators, { kind: "method", name: "readRelated", static: false, private: false, access: { has: obj => "readRelated" in obj, get: obj => obj.readRelated }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
161
162
|
__esDecorate(this, null, _stat_decorators, { kind: "method", name: "stat", static: false, private: false, access: { has: obj => "stat" in obj, get: obj => obj.stat }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
162
163
|
__esDecorate(this, null, _list_decorators, { kind: "method", name: "list", static: false, private: false, access: { has: obj => "list" in obj, get: obj => obj.list }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
163
164
|
__esDecorate(this, null, _changes_decorators, { kind: "method", name: "changes", static: false, private: false, access: { has: obj => "changes" in obj, get: obj => obj.changes }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
164
165
|
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
165
166
|
}
|
|
166
167
|
config = __runInitializers(this, _instanceExtraInitializers);
|
|
167
|
-
static inject = ['fs', 'sandboxPolicy', 'typert'];
|
|
168
|
+
static inject = ['fs', 'sandboxPolicy', 'sessions', 'typert'];
|
|
168
169
|
static Config = z.object({
|
|
169
170
|
maxBytes: z.number().step(1).min(1).default(2 * 1024 * 1024),
|
|
171
|
+
maxFileBytes: z.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER - 1).default(32 * 1024 * 1024),
|
|
170
172
|
maxLines: z.number().step(1).min(1).default(5000),
|
|
171
173
|
maxEntries: z.number().step(1).min(1).default(2000),
|
|
172
174
|
});
|
|
@@ -179,18 +181,39 @@ let WorkspaceFiles = (() => {
|
|
|
179
181
|
super(ctx, 'workspaceFiles');
|
|
180
182
|
this.config = config;
|
|
181
183
|
this.feed = new WorkspaceChangeFeed(ctx);
|
|
184
|
+
ctx.inject(['sessions', 'typert'], (scope) => {
|
|
185
|
+
scope.typert.lookups.register('workspaceFileScope', {
|
|
186
|
+
parameter: 'workspaceFileScope',
|
|
187
|
+
wire: 'workspaceFileScopeId',
|
|
188
|
+
hostTypeSymbol: '@deepseek-ai/dsh-api-workspace-files#WorkspaceFileScope',
|
|
189
|
+
wireTypeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
190
|
+
resolve: async (sessionId) => {
|
|
191
|
+
const live = scope.sessions.get(sessionId)?.header;
|
|
192
|
+
const stored = live === undefined
|
|
193
|
+
? await scope.get('sessionPersistence')?.stat(sessionId)
|
|
194
|
+
: undefined;
|
|
195
|
+
const header = live ?? stored?.header;
|
|
196
|
+
if (header === undefined)
|
|
197
|
+
return undefined;
|
|
198
|
+
return {
|
|
199
|
+
sessionId,
|
|
200
|
+
workspaceRoot: header.cwd ?? scope.sandboxPolicy.workspaceRoot,
|
|
201
|
+
};
|
|
202
|
+
},
|
|
203
|
+
});
|
|
204
|
+
});
|
|
182
205
|
}
|
|
183
206
|
/**
|
|
184
|
-
* Read one page of lines from a UTF-8
|
|
185
|
-
* @param
|
|
186
|
-
* @param path -
|
|
207
|
+
* Read one page of lines from a UTF-8 file readable by the filesystem backend.
|
|
208
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
209
|
+
* @param path - absolute path or path relative to the workspace root; files outside it are allowed.
|
|
187
210
|
* @param range - the line window; omitted fields take the page defaults.
|
|
188
211
|
* @param signal - caller cancellation.
|
|
189
212
|
* @returns the page, the file's version at the stat before it, and whether it reaches the last line.
|
|
190
213
|
*/
|
|
191
|
-
async read(
|
|
214
|
+
async read(workspaceFileScope, path, range, signal) {
|
|
192
215
|
const { offset, limit } = this.resolvePage(range);
|
|
193
|
-
const { target, info } = await this.locateFile(
|
|
216
|
+
const { target, info } = await this.locateFile(workspaceFileScope, path, signal);
|
|
194
217
|
const page = await this.cutPage(target, offset, limit, signal, path);
|
|
195
218
|
if (page.text.includes(NUL)) {
|
|
196
219
|
throw new RemoteError('workspace-file/not-text', `"${path}" contains NUL bytes`, { path });
|
|
@@ -198,41 +221,78 @@ let WorkspaceFiles = (() => {
|
|
|
198
221
|
return { ...this.statOf(target, info), offset, text: page.text, lines: page.lines, eof: page.eof };
|
|
199
222
|
}
|
|
200
223
|
/**
|
|
201
|
-
* Read one byte window of a regular file
|
|
224
|
+
* Read one byte window of a regular file readable by the filesystem backend: raw
|
|
202
225
|
* bytes, no text decoding and no binary rejection.
|
|
203
|
-
* @param
|
|
204
|
-
* @param path -
|
|
226
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
227
|
+
* @param path - absolute path or path relative to the workspace root; files outside it are allowed.
|
|
205
228
|
* @param range - the byte window; omitted fields take the window defaults.
|
|
206
229
|
* @param signal - caller cancellation.
|
|
207
230
|
* @returns the window in base64, the file's version and size at the stat before it, and whether it reaches the last byte.
|
|
208
231
|
*/
|
|
209
|
-
async readBytes(
|
|
232
|
+
async readBytes(workspaceFileScope, path, range, signal) {
|
|
210
233
|
const { offset, length } = this.resolveWindow(range, path);
|
|
211
|
-
const { target, info } = await this.locateFile(
|
|
234
|
+
const { target, info } = await this.locateFile(workspaceFileScope, path, signal);
|
|
212
235
|
const data = await this.ctx.fs.readByteRange(target, { offset, length }, signal);
|
|
213
236
|
const eof = info.size === undefined ? data.length < length : offset + data.length >= info.size;
|
|
214
237
|
return { ...this.statOf(target, info), offset, data: Buffer.from(data).toString('base64'), eof };
|
|
215
238
|
}
|
|
239
|
+
/**
|
|
240
|
+
* Read a complete regular file as bytes, subject to the configured full-file cap.
|
|
241
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
242
|
+
* @param path - absolute or workspace-relative file path.
|
|
243
|
+
* @param signal - caller cancellation.
|
|
244
|
+
* @returns one complete base64 window with offset zero and eof true; oversized files fail with too-large.
|
|
245
|
+
*/
|
|
246
|
+
async readAll(workspaceFileScope, path, signal) {
|
|
247
|
+
const { target, info } = await this.locateFile(workspaceFileScope, path, signal);
|
|
248
|
+
const limit = this.config.maxFileBytes;
|
|
249
|
+
if (info.size !== undefined && info.size > limit) {
|
|
250
|
+
throw new RemoteError('workspace-file/too-large', `"${path}" exceeds the ${limit} byte full-file cap`, { path, limit });
|
|
251
|
+
}
|
|
252
|
+
const data = await this.ctx.fs.readByteRange(target, { offset: 0, length: limit + 1 }, signal);
|
|
253
|
+
if (data.length > limit) {
|
|
254
|
+
throw new RemoteError('workspace-file/too-large', `"${path}" exceeds the ${limit} byte full-file cap`, { path, limit });
|
|
255
|
+
}
|
|
256
|
+
return { ...this.statOf(target, info), offset: 0, data: Buffer.from(data).toString('base64'), eof: true };
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Read a complete file relative to another file's directory, including outside the workspace.
|
|
260
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
261
|
+
* @param path - base file, absolute or workspace-relative.
|
|
262
|
+
* @param relativePath - relative filesystem path, not a URL or absolute path.
|
|
263
|
+
* @param signal - caller cancellation.
|
|
264
|
+
* @returns the complete related file using the ordinary file-size and access checks.
|
|
265
|
+
*/
|
|
266
|
+
async readRelated(workspaceFileScope, path, relativePath, signal) {
|
|
267
|
+
const relative = relativePath.replace(/\\/g, '/');
|
|
268
|
+
if (relative.length === 0 || relative.startsWith('/') || /^[a-z][a-z\d+.-]*:/iu.test(relative) || relative.includes(NUL)) {
|
|
269
|
+
throw new RemoteError('gateway/bad-request', 'relativePath must be a relative filesystem path', {});
|
|
270
|
+
}
|
|
271
|
+
const { target } = await this.locateFile(workspaceFileScope, path, signal);
|
|
272
|
+
const absolute = this.ctx.fs.processPath(target);
|
|
273
|
+
const paths = absolute.startsWith('/') ? posix : win32;
|
|
274
|
+
return this.readAll(workspaceFileScope, paths.resolve(paths.dirname(absolute), relative), signal);
|
|
275
|
+
}
|
|
216
276
|
/**
|
|
217
277
|
* Report one regular file's identity, version, and size without its content.
|
|
218
|
-
* @param
|
|
219
|
-
* @param path -
|
|
278
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
279
|
+
* @param path - absolute path or path relative to the workspace root; files outside it are allowed.
|
|
220
280
|
* @param signal - caller cancellation.
|
|
221
281
|
* @returns the file's absolute path, current version, and byte size.
|
|
222
282
|
*/
|
|
223
|
-
async stat(
|
|
224
|
-
const { target, info } = await this.locateFile(
|
|
283
|
+
async stat(workspaceFileScope, path, signal) {
|
|
284
|
+
const { target, info } = await this.locateFile(workspaceFileScope, path, signal);
|
|
225
285
|
return this.statOf(target, info);
|
|
226
286
|
}
|
|
227
287
|
/**
|
|
228
|
-
* List the direct children of one directory inside the
|
|
229
|
-
* @param
|
|
288
|
+
* List the direct children of one directory inside the Session's workspace.
|
|
289
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
230
290
|
* @param path - workspace path, absolute or relative to the workspace root.
|
|
231
291
|
* @param signal - caller cancellation.
|
|
232
292
|
* @returns the directory's children in the backend's stable name order, bounded by the entry cap.
|
|
233
293
|
*/
|
|
234
|
-
async list(
|
|
235
|
-
const { root, workspaceRoot, entry } = await this.inspect(
|
|
294
|
+
async list(workspaceFileScope, path, signal) {
|
|
295
|
+
const { root, workspaceRoot, entry } = await this.inspect(workspaceFileScope, path, signal);
|
|
236
296
|
if (entry.type !== 'directory') {
|
|
237
297
|
throw new RemoteError('workspace-file/not-directory', `"${path}" is a ${entry.type}`, { path, kind: entry.type });
|
|
238
298
|
}
|
|
@@ -245,16 +305,16 @@ let WorkspaceFiles = (() => {
|
|
|
245
305
|
};
|
|
246
306
|
}
|
|
247
307
|
/**
|
|
248
|
-
* Stream every `fs/observed` observation of a file inside the
|
|
249
|
-
* workspace. Only
|
|
250
|
-
* watched.
|
|
251
|
-
* @param
|
|
308
|
+
* Stream every `fs/observed` observation of a file inside the Session's
|
|
309
|
+
* workspace. Only instrumented filesystem operations report here; the OS is
|
|
310
|
+
* not watched.
|
|
311
|
+
* @param workspaceFileScope - header-derived workspace root for the Session identity on the wire.
|
|
252
312
|
* @param signal - generation cancellation.
|
|
253
313
|
* @returns `ready` once the Host observation queue is active and the workspace
|
|
254
314
|
* root is resolved, then queued and live observations in emission order.
|
|
255
315
|
*/
|
|
256
|
-
changes(
|
|
257
|
-
return this.feed.follow(
|
|
316
|
+
changes(workspaceFileScope, signal) {
|
|
317
|
+
return this.feed.follow(workspaceFileScope.workspaceRoot, signal);
|
|
258
318
|
}
|
|
259
319
|
/** Apply the page defaults and caps here, so the request never carries them implicitly. */
|
|
260
320
|
resolvePage(range) {
|
|
@@ -278,26 +338,13 @@ let WorkspaceFiles = (() => {
|
|
|
278
338
|
return { offset, length };
|
|
279
339
|
}
|
|
280
340
|
/**
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* `fs-local` whose cwd differs, and resolving explicitly makes the answer
|
|
284
|
-
* the same whichever instance answers.
|
|
341
|
+
* Inspect the requested path itself before resolution follows its final
|
|
342
|
+
* component. Directory containment is checked separately by `list`.
|
|
285
343
|
*/
|
|
286
|
-
|
|
287
|
-
return this.ctx.sandboxPolicy.resolve({ session: agent.session }).workspaceRoot;
|
|
288
|
-
}
|
|
289
|
-
/**
|
|
290
|
-
* Gates 1 and 2 up to the point where the path's own type is known. The
|
|
291
|
-
* path is inspected before containment is decided, so a caller learns whether
|
|
292
|
-
* an outside path exists and what kind it is before `outside-workspace`
|
|
293
|
-
* refuses it; the caller is the Session's own owner, who can read the Host
|
|
294
|
-
* through the Agent anyway, and the accepted cost buys one `lstat` gate for
|
|
295
|
-
* every method instead of two resolution orders.
|
|
296
|
-
*/
|
|
297
|
-
async inspect(agent, path, signal) {
|
|
344
|
+
async inspect(workspaceFileScope, path, signal) {
|
|
298
345
|
if (path.length === 0)
|
|
299
346
|
throw new RemoteError('gateway/bad-request', 'path is required', {});
|
|
300
|
-
const workspaceRoot =
|
|
347
|
+
const { workspaceRoot } = workspaceFileScope;
|
|
301
348
|
const root = await this.ctx.fs.resolve(workspaceRoot, { signal });
|
|
302
349
|
// Gate on the path itself before anything follows it.
|
|
303
350
|
const entry = await this.ctx.fs.lstat(path, { cwd: workspaceRoot }, signal);
|
|
@@ -319,12 +366,12 @@ let WorkspaceFiles = (() => {
|
|
|
319
366
|
* and size. The stat re-checks what `lstat` saw: the file may have gone or
|
|
320
367
|
* changed kind in between.
|
|
321
368
|
*/
|
|
322
|
-
async locateFile(
|
|
323
|
-
const {
|
|
369
|
+
async locateFile(workspaceFileScope, path, signal) {
|
|
370
|
+
const { workspaceRoot, entry } = await this.inspect(workspaceFileScope, path, signal);
|
|
324
371
|
if (entry.type !== 'file') {
|
|
325
372
|
throw new RemoteError('workspace-file/not-regular-file', `"${path}" is a ${entry.type}`, { path, kind: entry.type });
|
|
326
373
|
}
|
|
327
|
-
const target = await this.
|
|
374
|
+
const target = await this.ctx.fs.resolve(path, { cwd: workspaceRoot, signal });
|
|
328
375
|
const info = await this.ctx.fs.stat(target, signal);
|
|
329
376
|
if (info === undefined) {
|
|
330
377
|
throw new RemoteError('workspace-file/not-found', `no entry at "${path}"`, { path });
|
package/lib/types/types.d.ts
CHANGED
|
@@ -103,9 +103,9 @@ export interface WorkspaceDirectoryListing {
|
|
|
103
103
|
readonly truncated: boolean;
|
|
104
104
|
}
|
|
105
105
|
/**
|
|
106
|
-
* One observation of a workspace file made by an
|
|
107
|
-
* operation. Frames report observations, not deltas: a consumer already
|
|
108
|
-
* `version` learns nothing new from the frame and can ignore it.
|
|
106
|
+
* One observation of a workspace file made by an instrumented filesystem
|
|
107
|
+
* operation. Frames report observations, not deltas: a consumer already
|
|
108
|
+
* holding `version` learns nothing new from the frame and can ignore it.
|
|
109
109
|
*/
|
|
110
110
|
export type WorkspaceFileChange = {
|
|
111
111
|
/** Absolute path of the observed file, in the same form as {@link WorkspaceFileStat.absolutePath}. */
|
|
@@ -135,7 +135,7 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
|
|
|
135
135
|
'workspace-file/not-found': {
|
|
136
136
|
readonly path: string;
|
|
137
137
|
};
|
|
138
|
-
/** The path resolves outside the session's workspace root. */
|
|
138
|
+
/** The directory listing path resolves outside the session's workspace root. */
|
|
139
139
|
'workspace-file/outside-workspace': {
|
|
140
140
|
readonly path: string;
|
|
141
141
|
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-api-workspace-files",
|
|
3
3
|
"description": "Workspace file service and Client resource provider: bounded reads, directory listing, and live metadata over the workspaceFiles Remote namespace",
|
|
4
|
-
"version": "0.1.5-alpha.
|
|
4
|
+
"version": "0.1.5-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -41,7 +41,6 @@
|
|
|
41
41
|
"client": {
|
|
42
42
|
"inject": [
|
|
43
43
|
"@deepseek-ai/dsh-api-gateway",
|
|
44
|
-
"@deepseek-ai/dsh-api-session-controller",
|
|
45
44
|
"@deepseek-ai/dsh-client-resources"
|
|
46
45
|
],
|
|
47
46
|
"platform": "web"
|
|
@@ -50,24 +49,23 @@
|
|
|
50
49
|
"license": "MIT",
|
|
51
50
|
"dependencies": {
|
|
52
51
|
"zod": "^4.4.3",
|
|
53
|
-
"@deepseek-ai/dsh-
|
|
54
|
-
"@deepseek-ai/
|
|
55
|
-
"@deepseek-ai/
|
|
52
|
+
"@deepseek-ai/dsh-deque": "^0.1.5-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.2",
|
|
54
|
+
"@deepseek-ai/schemastery": "^3.18.2"
|
|
56
55
|
},
|
|
57
56
|
"peerDependencies": {
|
|
58
57
|
"@deepseek-ai/cordis": "^4.0.2"
|
|
59
58
|
},
|
|
60
59
|
"devDependencies": {
|
|
61
60
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
62
|
-
"@deepseek-ai/dsh-
|
|
63
|
-
"@deepseek-ai/dsh-
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-client-
|
|
66
|
-
"@deepseek-ai/dsh-
|
|
67
|
-
"@deepseek-ai/dsh-
|
|
68
|
-
"@deepseek-ai/dsh-
|
|
69
|
-
"@deepseek-ai/dsh-
|
|
70
|
-
"@deepseek-ai/dsh-util-workspace-path": "^0.1.5-alpha.1"
|
|
61
|
+
"@deepseek-ai/dsh-api-gateway": "^0.1.5-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-client-resources": "^0.1.5-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-fs": "^0.1.5-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.5-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-sandbox-policy": "^0.1.5-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
|
|
67
|
+
"@deepseek-ai/dsh-session-persistence": "^0.1.5-alpha.2",
|
|
68
|
+
"@deepseek-ai/dsh-util-workspace-path": "^0.1.5-alpha.2"
|
|
71
69
|
},
|
|
72
70
|
"files": [
|
|
73
71
|
"lib/index.js",
|