@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
|
@@ -8,29 +8,26 @@ import type { SessionId } from '@deepseek-ai/dsh-session/types'
|
|
|
8
8
|
|
|
9
9
|
declare module '@deepseek-ai/dsh-typert-protocol' {
|
|
10
10
|
interface TypertRemoteNamespace$776f726b737061636546696c6573 {
|
|
11
|
-
changes: (
|
|
12
|
-
list: (
|
|
13
|
-
read: (
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
changes: (workspaceFileScopeId: SessionId, signal?: AbortSignal) => AsyncIterable<WorkspaceFileWatchFrame>
|
|
12
|
+
list: (workspaceFileScopeId: SessionId, path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceDirectoryListing>>
|
|
13
|
+
read: (workspaceFileScopeId: SessionId, path: string, range: WorkspaceFileRange, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileText>>
|
|
14
|
+
readAll: (workspaceFileScopeId: SessionId, path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileBytes>>
|
|
15
|
+
readBytes: (workspaceFileScopeId: SessionId, path: string, range: WorkspaceByteRange, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileBytes>>
|
|
16
|
+
readRelated: (workspaceFileScopeId: SessionId, path: string, relativePath: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileBytes>>
|
|
17
|
+
stat: (workspaceFileScopeId: SessionId, path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileStat>>
|
|
16
18
|
}
|
|
17
19
|
interface TypertRemoteMap {
|
|
18
|
-
'workspaceFiles/changes': (
|
|
19
|
-
'workspaceFiles/list': (
|
|
20
|
-
'workspaceFiles/read': (
|
|
21
|
-
'workspaceFiles/
|
|
22
|
-
'workspaceFiles/
|
|
20
|
+
'workspaceFiles/changes': (workspaceFileScopeId: SessionId, signal?: AbortSignal) => AsyncIterable<WorkspaceFileWatchFrame>
|
|
21
|
+
'workspaceFiles/list': (workspaceFileScopeId: SessionId, path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceDirectoryListing>>
|
|
22
|
+
'workspaceFiles/read': (workspaceFileScopeId: SessionId, path: string, range: WorkspaceFileRange, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileText>>
|
|
23
|
+
'workspaceFiles/readAll': (workspaceFileScopeId: SessionId, path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileBytes>>
|
|
24
|
+
'workspaceFiles/readBytes': (workspaceFileScopeId: SessionId, path: string, range: WorkspaceByteRange, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileBytes>>
|
|
25
|
+
'workspaceFiles/readRelated': (workspaceFileScopeId: SessionId, path: string, relativePath: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileBytes>>
|
|
26
|
+
'workspaceFiles/stat': (workspaceFileScopeId: SessionId, path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileStat>>
|
|
23
27
|
}
|
|
24
28
|
interface TypertRemoteNamespaceMap {
|
|
25
29
|
'workspaceFiles': TypertRemoteNamespace$776f726b737061636546696c6573
|
|
26
30
|
}
|
|
27
|
-
interface TypertRemoteScopeMap {
|
|
28
|
-
'agent:workspaceFiles/changes': (signal?: AbortSignal) => AsyncIterable<WorkspaceFileWatchFrame>
|
|
29
|
-
'agent:workspaceFiles/list': (path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceDirectoryListing>>
|
|
30
|
-
'agent:workspaceFiles/read': (path: string, range: WorkspaceFileRange, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileText>>
|
|
31
|
-
'agent:workspaceFiles/readBytes': (path: string, range: WorkspaceByteRange, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileBytes>>
|
|
32
|
-
'agent:workspaceFiles/stat': (path: string, signal?: AbortSignal) => Promise<RemoteResult<WorkspaceFileStat>>
|
|
33
|
-
}
|
|
34
31
|
}
|
|
35
32
|
|
|
36
33
|
export declare const TYPERT_REMOTE: TypertRemoteContribution
|
|
@@ -40,6 +40,16 @@ const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_read_result$schema = z
|
|
|
40
40
|
'version': z.string().readonly(),
|
|
41
41
|
'bytes': z.number().readonly().optional(),
|
|
42
42
|
})
|
|
43
|
+
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readAll_parameter_0$schema = z.intersection(z.string(), z.unknown())
|
|
44
|
+
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readAll_parameter_1$schema = z.string()
|
|
45
|
+
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readAll_result$schema = z.object({
|
|
46
|
+
'offset': z.number().readonly(),
|
|
47
|
+
'data': z.string().readonly(),
|
|
48
|
+
'eof': z.boolean().readonly(),
|
|
49
|
+
'absolutePath': z.string().readonly(),
|
|
50
|
+
'version': z.string().readonly(),
|
|
51
|
+
'bytes': z.number().readonly().optional(),
|
|
52
|
+
})
|
|
43
53
|
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readBytes_parameter_0$schema = z.intersection(z.string(), z.unknown())
|
|
44
54
|
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readBytes_parameter_1$schema = z.string()
|
|
45
55
|
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readBytes_parameter_2$schema = z.object({
|
|
@@ -54,6 +64,17 @@ const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readBytes_result$schem
|
|
|
54
64
|
'version': z.string().readonly(),
|
|
55
65
|
'bytes': z.number().readonly().optional(),
|
|
56
66
|
})
|
|
67
|
+
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_parameter_0$schema = z.intersection(z.string(), z.unknown())
|
|
68
|
+
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_parameter_1$schema = z.string()
|
|
69
|
+
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_parameter_2$schema = z.string()
|
|
70
|
+
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_result$schema = z.object({
|
|
71
|
+
'offset': z.number().readonly(),
|
|
72
|
+
'data': z.string().readonly(),
|
|
73
|
+
'eof': z.boolean().readonly(),
|
|
74
|
+
'absolutePath': z.string().readonly(),
|
|
75
|
+
'version': z.string().readonly(),
|
|
76
|
+
'bytes': z.number().readonly().optional(),
|
|
77
|
+
})
|
|
57
78
|
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_stat_parameter_0$schema = z.intersection(z.string(), z.unknown())
|
|
58
79
|
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_stat_parameter_1$schema = z.string()
|
|
59
80
|
const _deepseek_ai_dsh_api_workspace_files_workspaceFiles_stat_result$schema = z.object({
|
|
@@ -72,16 +93,12 @@ export const TYPERT_REMOTE = {
|
|
|
72
93
|
method: 'changes',
|
|
73
94
|
mode: 'stream',
|
|
74
95
|
invocation: { kind: 'direct' },
|
|
75
|
-
scope: {
|
|
76
|
-
context: 'agent',
|
|
77
|
-
wire: 'agentId',
|
|
78
|
-
},
|
|
79
96
|
parameters: [
|
|
80
97
|
{
|
|
81
|
-
name: '
|
|
82
|
-
wire: '
|
|
98
|
+
name: 'workspaceFileScope',
|
|
99
|
+
wire: 'workspaceFileScopeId',
|
|
83
100
|
source: 'lookup',
|
|
84
|
-
lookup: '
|
|
101
|
+
lookup: 'workspaceFileScope',
|
|
85
102
|
codec: {
|
|
86
103
|
mode: 'strict',
|
|
87
104
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
@@ -95,7 +112,7 @@ export const TYPERT_REMOTE = {
|
|
|
95
112
|
typeSymbol: '@deepseek-ai/dsh-api-workspace-files/types#WorkspaceFileWatchFrame',
|
|
96
113
|
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_changes_result$schema,
|
|
97
114
|
},
|
|
98
|
-
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":
|
|
115
|
+
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":365,"column":3},
|
|
99
116
|
},
|
|
100
117
|
{
|
|
101
118
|
id: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/list',
|
|
@@ -103,16 +120,12 @@ export const TYPERT_REMOTE = {
|
|
|
103
120
|
namespace: 'workspaceFiles',
|
|
104
121
|
method: 'list',
|
|
105
122
|
invocation: { kind: 'direct' },
|
|
106
|
-
scope: {
|
|
107
|
-
context: 'agent',
|
|
108
|
-
wire: 'agentId',
|
|
109
|
-
},
|
|
110
123
|
parameters: [
|
|
111
124
|
{
|
|
112
|
-
name: '
|
|
113
|
-
wire: '
|
|
125
|
+
name: 'workspaceFileScope',
|
|
126
|
+
wire: 'workspaceFileScopeId',
|
|
114
127
|
source: 'lookup',
|
|
115
|
-
lookup: '
|
|
128
|
+
lookup: 'workspaceFileScope',
|
|
116
129
|
codec: {
|
|
117
130
|
mode: 'strict',
|
|
118
131
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
@@ -136,7 +149,7 @@ export const TYPERT_REMOTE = {
|
|
|
136
149
|
typeSymbol: '@deepseek-ai/dsh-api-workspace-files/types#WorkspaceDirectoryListing',
|
|
137
150
|
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_list_result$schema,
|
|
138
151
|
},
|
|
139
|
-
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":
|
|
152
|
+
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":337,"column":9},
|
|
140
153
|
},
|
|
141
154
|
{
|
|
142
155
|
id: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/read',
|
|
@@ -144,16 +157,12 @@ export const TYPERT_REMOTE = {
|
|
|
144
157
|
namespace: 'workspaceFiles',
|
|
145
158
|
method: 'read',
|
|
146
159
|
invocation: { kind: 'direct' },
|
|
147
|
-
scope: {
|
|
148
|
-
context: 'agent',
|
|
149
|
-
wire: 'agentId',
|
|
150
|
-
},
|
|
151
160
|
parameters: [
|
|
152
161
|
{
|
|
153
|
-
name: '
|
|
154
|
-
wire: '
|
|
162
|
+
name: 'workspaceFileScope',
|
|
163
|
+
wire: 'workspaceFileScopeId',
|
|
155
164
|
source: 'lookup',
|
|
156
|
-
lookup: '
|
|
165
|
+
lookup: 'workspaceFileScope',
|
|
157
166
|
codec: {
|
|
158
167
|
mode: 'strict',
|
|
159
168
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
@@ -187,7 +196,44 @@ export const TYPERT_REMOTE = {
|
|
|
187
196
|
typeSymbol: '@deepseek-ai/dsh-api-workspace-files/types#WorkspaceFileText',
|
|
188
197
|
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_read_result$schema,
|
|
189
198
|
},
|
|
190
|
-
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":
|
|
199
|
+
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":232,"column":9},
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
id: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/readAll',
|
|
203
|
+
service: 'workspaceFiles',
|
|
204
|
+
namespace: 'workspaceFiles',
|
|
205
|
+
method: 'readAll',
|
|
206
|
+
invocation: { kind: 'direct' },
|
|
207
|
+
parameters: [
|
|
208
|
+
{
|
|
209
|
+
name: 'workspaceFileScope',
|
|
210
|
+
wire: 'workspaceFileScopeId',
|
|
211
|
+
source: 'lookup',
|
|
212
|
+
lookup: 'workspaceFileScope',
|
|
213
|
+
codec: {
|
|
214
|
+
mode: 'strict',
|
|
215
|
+
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
216
|
+
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readAll_parameter_0$schema,
|
|
217
|
+
},
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
name: 'path',
|
|
221
|
+
wire: 'path',
|
|
222
|
+
source: 'json',
|
|
223
|
+
codec: {
|
|
224
|
+
mode: 'strict',
|
|
225
|
+
typeSymbol: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/readAll:path',
|
|
226
|
+
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readAll_parameter_1$schema,
|
|
227
|
+
},
|
|
228
|
+
},
|
|
229
|
+
],
|
|
230
|
+
cancellation: { parameter: 'signal' },
|
|
231
|
+
result: {
|
|
232
|
+
mode: 'strict',
|
|
233
|
+
typeSymbol: '@deepseek-ai/dsh-api-workspace-files/types#WorkspaceFileBytes',
|
|
234
|
+
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readAll_result$schema,
|
|
235
|
+
},
|
|
236
|
+
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":278,"column":9},
|
|
191
237
|
},
|
|
192
238
|
{
|
|
193
239
|
id: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/readBytes',
|
|
@@ -195,16 +241,12 @@ export const TYPERT_REMOTE = {
|
|
|
195
241
|
namespace: 'workspaceFiles',
|
|
196
242
|
method: 'readBytes',
|
|
197
243
|
invocation: { kind: 'direct' },
|
|
198
|
-
scope: {
|
|
199
|
-
context: 'agent',
|
|
200
|
-
wire: 'agentId',
|
|
201
|
-
},
|
|
202
244
|
parameters: [
|
|
203
245
|
{
|
|
204
|
-
name: '
|
|
205
|
-
wire: '
|
|
246
|
+
name: 'workspaceFileScope',
|
|
247
|
+
wire: 'workspaceFileScopeId',
|
|
206
248
|
source: 'lookup',
|
|
207
|
-
lookup: '
|
|
249
|
+
lookup: 'workspaceFileScope',
|
|
208
250
|
codec: {
|
|
209
251
|
mode: 'strict',
|
|
210
252
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
@@ -238,7 +280,54 @@ export const TYPERT_REMOTE = {
|
|
|
238
280
|
typeSymbol: '@deepseek-ai/dsh-api-workspace-files/types#WorkspaceFileBytes',
|
|
239
281
|
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readBytes_result$schema,
|
|
240
282
|
},
|
|
241
|
-
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":
|
|
283
|
+
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":257,"column":9},
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
id: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/readRelated',
|
|
287
|
+
service: 'workspaceFiles',
|
|
288
|
+
namespace: 'workspaceFiles',
|
|
289
|
+
method: 'readRelated',
|
|
290
|
+
invocation: { kind: 'direct' },
|
|
291
|
+
parameters: [
|
|
292
|
+
{
|
|
293
|
+
name: 'workspaceFileScope',
|
|
294
|
+
wire: 'workspaceFileScopeId',
|
|
295
|
+
source: 'lookup',
|
|
296
|
+
lookup: 'workspaceFileScope',
|
|
297
|
+
codec: {
|
|
298
|
+
mode: 'strict',
|
|
299
|
+
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
300
|
+
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_parameter_0$schema,
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
{
|
|
304
|
+
name: 'path',
|
|
305
|
+
wire: 'path',
|
|
306
|
+
source: 'json',
|
|
307
|
+
codec: {
|
|
308
|
+
mode: 'strict',
|
|
309
|
+
typeSymbol: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/readRelated:path',
|
|
310
|
+
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_parameter_1$schema,
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
name: 'relativePath',
|
|
315
|
+
wire: 'relativePath',
|
|
316
|
+
source: 'json',
|
|
317
|
+
codec: {
|
|
318
|
+
mode: 'strict',
|
|
319
|
+
typeSymbol: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/readRelated:relativePath',
|
|
320
|
+
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_parameter_2$schema,
|
|
321
|
+
},
|
|
322
|
+
},
|
|
323
|
+
],
|
|
324
|
+
cancellation: { parameter: 'signal' },
|
|
325
|
+
result: {
|
|
326
|
+
mode: 'strict',
|
|
327
|
+
typeSymbol: '@deepseek-ai/dsh-api-workspace-files/types#WorkspaceFileBytes',
|
|
328
|
+
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_readRelated_result$schema,
|
|
329
|
+
},
|
|
330
|
+
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":300,"column":9},
|
|
242
331
|
},
|
|
243
332
|
{
|
|
244
333
|
id: '@deepseek-ai/dsh-api-workspace-files#workspaceFiles/stat',
|
|
@@ -246,16 +335,12 @@ export const TYPERT_REMOTE = {
|
|
|
246
335
|
namespace: 'workspaceFiles',
|
|
247
336
|
method: 'stat',
|
|
248
337
|
invocation: { kind: 'direct' },
|
|
249
|
-
scope: {
|
|
250
|
-
context: 'agent',
|
|
251
|
-
wire: 'agentId',
|
|
252
|
-
},
|
|
253
338
|
parameters: [
|
|
254
339
|
{
|
|
255
|
-
name: '
|
|
256
|
-
wire: '
|
|
340
|
+
name: 'workspaceFileScope',
|
|
341
|
+
wire: 'workspaceFileScopeId',
|
|
257
342
|
source: 'lookup',
|
|
258
|
-
lookup: '
|
|
343
|
+
lookup: 'workspaceFileScope',
|
|
259
344
|
codec: {
|
|
260
345
|
mode: 'strict',
|
|
261
346
|
typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
|
|
@@ -279,7 +364,7 @@ export const TYPERT_REMOTE = {
|
|
|
279
364
|
typeSymbol: '@deepseek-ai/dsh-api-workspace-files/types#WorkspaceFileStat',
|
|
280
365
|
schema: _deepseek_ai_dsh_api_workspace_files_workspaceFiles_stat_result$schema,
|
|
281
366
|
},
|
|
282
|
-
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":
|
|
367
|
+
sourceLocation: {"file":"packages/api/workspace-files/src/index.ts","line":324,"column":9},
|
|
283
368
|
},
|
|
284
369
|
],
|
|
285
370
|
}
|
package/lib/types/changes.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Producer of the `changes` stream: every `fs/observed` emission whose target
|
|
3
3
|
* lies inside a generation's workspace root becomes one frame of that
|
|
4
|
-
* generation.
|
|
5
|
-
*
|
|
4
|
+
* generation. Instrumented filesystem operations emit these observations; the
|
|
5
|
+
* operating system is not watched.
|
|
6
6
|
* Each generation acknowledges its observation queue and resolved workspace
|
|
7
7
|
* root with `ready` before emitting any queued or live changes.
|
|
8
8
|
*/
|
package/lib/types/changes.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Producer of the `changes` stream: every `fs/observed` emission whose target
|
|
3
3
|
* lies inside a generation's workspace root becomes one frame of that
|
|
4
|
-
* generation.
|
|
5
|
-
*
|
|
4
|
+
* generation. Instrumented filesystem operations emit these observations; the
|
|
5
|
+
* operating system is not watched.
|
|
6
6
|
* Each generation acknowledges its observation queue and resolved workspace
|
|
7
7
|
* root with `ready` before emitting any queued or live changes.
|
|
8
8
|
*/
|
|
@@ -7,15 +7,13 @@
|
|
|
7
7
|
* arrives, hands each frame to the followers of its path, and disposes the
|
|
8
8
|
* stream when the last follower leaves. A follower buffers session changes
|
|
9
9
|
* until `stat` supplies its Host absolute path, then filters queued and live
|
|
10
|
-
* frames by that path, with `\\` normalized to `/`.
|
|
11
|
-
* reload requests; they never determine a notification path.
|
|
10
|
+
* frames by that path, with `\\` normalized to `/`.
|
|
12
11
|
*/
|
|
13
12
|
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
14
13
|
import type { WorkspaceFilesRemote } from './remote.ts';
|
|
15
14
|
import type { WorkspaceFileNotice } from './types.ts';
|
|
16
15
|
/** Notices of one follower, delivered in order and pulled by its consumer. */
|
|
17
16
|
declare class Follower implements AsyncIterable<WorkspaceFileNotice> {
|
|
18
|
-
readonly address: string;
|
|
19
17
|
private readonly leave;
|
|
20
18
|
private readonly pending;
|
|
21
19
|
private readonly started;
|
|
@@ -28,12 +26,9 @@ declare class Follower implements AsyncIterable<WorkspaceFileNotice> {
|
|
|
28
26
|
*/
|
|
29
27
|
readonly ready: Promise<boolean>;
|
|
30
28
|
/**
|
|
31
|
-
* @param address - resource address used for reload lookup.
|
|
32
29
|
* @param leave - unregisters this follower and its abort listener.
|
|
33
30
|
*/
|
|
34
|
-
constructor(
|
|
35
|
-
/** The normalized Host path, absent until a successful stat. */
|
|
36
|
-
get key(): string | undefined;
|
|
31
|
+
constructor(leave: () => void);
|
|
37
32
|
/**
|
|
38
33
|
* Select the Host path for queued and future changes.
|
|
39
34
|
* @param absolutePath - the successful stat's absolute path.
|
|
@@ -44,9 +39,9 @@ declare class Follower implements AsyncIterable<WorkspaceFileNotice> {
|
|
|
44
39
|
/**
|
|
45
40
|
* Queue one notice.
|
|
46
41
|
* @param notice - what the consumer receives next.
|
|
47
|
-
* @param key - normalized Host path for
|
|
42
|
+
* @param key - normalized Host path for the change.
|
|
48
43
|
*/
|
|
49
|
-
push(notice: WorkspaceFileNotice, key
|
|
44
|
+
push(notice: WorkspaceFileNotice, key: string): void;
|
|
50
45
|
/** Deliver what is queued, then finish. */
|
|
51
46
|
end(): void;
|
|
52
47
|
/** Unregister even when the consumer has not started pulling notices. */
|
|
@@ -70,7 +65,7 @@ export declare class ChangeFeed {
|
|
|
70
65
|
*/
|
|
71
66
|
constructor(remote: WorkspaceFilesRemote);
|
|
72
67
|
/**
|
|
73
|
-
* Follow one resource
|
|
68
|
+
* Follow one resource in one session before its Host path is known.
|
|
74
69
|
*
|
|
75
70
|
* The follower is registered on call, not on first pull. Changes delivered
|
|
76
71
|
* to this Client are queued while stat is pending. The first follower starts
|
|
@@ -82,17 +77,10 @@ export declare class ChangeFeed {
|
|
|
82
77
|
* any session write can trigger a retry; after binding, only matching queued
|
|
83
78
|
* and live changes pass.
|
|
84
79
|
* @param sessionId - the session whose workspace holds the file.
|
|
85
|
-
* @param address - the resource address, used only for reload lookup.
|
|
86
80
|
* @param signal - ends the follow.
|
|
87
81
|
* @returns a single-consumer subscription with Host-path binding and explicit disposal.
|
|
88
82
|
*/
|
|
89
|
-
follow(sessionId: SessionId,
|
|
90
|
-
/**
|
|
91
|
-
* Ask an address and its same-session Host-path peers to `stat` again.
|
|
92
|
-
* @param sessionId - the session whose workspace holds the file.
|
|
93
|
-
* @param address - the resource address requesting a reload.
|
|
94
|
-
*/
|
|
95
|
-
requestRestat(sessionId: SessionId, address: string): void;
|
|
83
|
+
follow(sessionId: SessionId, signal: AbortSignal): Follower;
|
|
96
84
|
/**
|
|
97
85
|
* Wait for every stream that is still closing, so an owner tearing down
|
|
98
86
|
* leaves no Host stream behind.
|
|
@@ -8,7 +8,6 @@ function keyOf(path) {
|
|
|
8
8
|
}
|
|
9
9
|
/** Notices of one follower, delivered in order and pulled by its consumer. */
|
|
10
10
|
class Follower {
|
|
11
|
-
address;
|
|
12
11
|
leave;
|
|
13
12
|
pending = [];
|
|
14
13
|
started = Promise.withResolvers();
|
|
@@ -21,17 +20,11 @@ class Follower {
|
|
|
21
20
|
*/
|
|
22
21
|
ready = this.started.promise;
|
|
23
22
|
/**
|
|
24
|
-
* @param address - resource address used for reload lookup.
|
|
25
23
|
* @param leave - unregisters this follower and its abort listener.
|
|
26
24
|
*/
|
|
27
|
-
constructor(
|
|
28
|
-
this.address = address;
|
|
25
|
+
constructor(leave) {
|
|
29
26
|
this.leave = leave;
|
|
30
27
|
}
|
|
31
|
-
/** The normalized Host path, absent until a successful stat. */
|
|
32
|
-
get key() {
|
|
33
|
-
return this.hostKey;
|
|
34
|
-
}
|
|
35
28
|
/**
|
|
36
29
|
* Select the Host path for queued and future changes.
|
|
37
30
|
* @param absolutePath - the successful stat's absolute path.
|
|
@@ -46,7 +39,7 @@ class Follower {
|
|
|
46
39
|
/**
|
|
47
40
|
* Queue one notice.
|
|
48
41
|
* @param notice - what the consumer receives next.
|
|
49
|
-
* @param key - normalized Host path for
|
|
42
|
+
* @param key - normalized Host path for the change.
|
|
50
43
|
*/
|
|
51
44
|
push(notice, key) {
|
|
52
45
|
this.pending.push({ key, notice });
|
|
@@ -68,7 +61,7 @@ class Follower {
|
|
|
68
61
|
while (true) {
|
|
69
62
|
const next = this.pending.shift();
|
|
70
63
|
if (next !== undefined) {
|
|
71
|
-
if (
|
|
64
|
+
if (this.hostKey === undefined || next.key === this.hostKey)
|
|
72
65
|
yield next.notice;
|
|
73
66
|
continue;
|
|
74
67
|
}
|
|
@@ -130,22 +123,6 @@ class SessionFeed {
|
|
|
130
123
|
if (this.followers.size === 0)
|
|
131
124
|
this.close();
|
|
132
125
|
}
|
|
133
|
-
/**
|
|
134
|
-
* Reload an address and every follower bound to the same Host path.
|
|
135
|
-
* @param address - the resource address requesting a reload.
|
|
136
|
-
*/
|
|
137
|
-
requestRestat(address) {
|
|
138
|
-
const keys = new Set();
|
|
139
|
-
for (const follower of this.followers) {
|
|
140
|
-
if (follower.address === address && follower.key !== undefined)
|
|
141
|
-
keys.add(follower.key);
|
|
142
|
-
}
|
|
143
|
-
for (const follower of this.followers) {
|
|
144
|
-
if (follower.address === address || (follower.key !== undefined && keys.has(follower.key))) {
|
|
145
|
-
follower.push({ kind: 'restat' });
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
126
|
async pump() {
|
|
150
127
|
try {
|
|
151
128
|
for await (const item of this.stream) {
|
|
@@ -227,7 +204,7 @@ export class ChangeFeed {
|
|
|
227
204
|
this.remote = remote;
|
|
228
205
|
}
|
|
229
206
|
/**
|
|
230
|
-
* Follow one resource
|
|
207
|
+
* Follow one resource in one session before its Host path is known.
|
|
231
208
|
*
|
|
232
209
|
* The follower is registered on call, not on first pull. Changes delivered
|
|
233
210
|
* to this Client are queued while stat is pending. The first follower starts
|
|
@@ -239,18 +216,17 @@ export class ChangeFeed {
|
|
|
239
216
|
* any session write can trigger a retry; after binding, only matching queued
|
|
240
217
|
* and live changes pass.
|
|
241
218
|
* @param sessionId - the session whose workspace holds the file.
|
|
242
|
-
* @param address - the resource address, used only for reload lookup.
|
|
243
219
|
* @param signal - ends the follow.
|
|
244
220
|
* @returns a single-consumer subscription with Host-path binding and explicit disposal.
|
|
245
221
|
*/
|
|
246
|
-
follow(sessionId,
|
|
222
|
+
follow(sessionId, signal) {
|
|
247
223
|
const feed = signal.aborted ? undefined : this.feedOf(sessionId);
|
|
248
224
|
const leave = () => {
|
|
249
225
|
signal.removeEventListener('abort', leave);
|
|
250
226
|
follower.end();
|
|
251
227
|
feed?.remove(follower);
|
|
252
228
|
};
|
|
253
|
-
const follower = new Follower(
|
|
229
|
+
const follower = new Follower(leave);
|
|
254
230
|
if (feed === undefined) {
|
|
255
231
|
follower.end();
|
|
256
232
|
}
|
|
@@ -260,14 +236,6 @@ export class ChangeFeed {
|
|
|
260
236
|
}
|
|
261
237
|
return follower;
|
|
262
238
|
}
|
|
263
|
-
/**
|
|
264
|
-
* Ask an address and its same-session Host-path peers to `stat` again.
|
|
265
|
-
* @param sessionId - the session whose workspace holds the file.
|
|
266
|
-
* @param address - the resource address requesting a reload.
|
|
267
|
-
*/
|
|
268
|
-
requestRestat(sessionId, address) {
|
|
269
|
-
this.sessions.get(sessionId)?.requestRestat(address);
|
|
270
|
-
}
|
|
271
239
|
/**
|
|
272
240
|
* Wait for every stream that is still closing, so an owner tearing down
|
|
273
241
|
* leaves no Host stream behind.
|
|
@@ -6,13 +6,12 @@
|
|
|
6
6
|
* stream, and this module only wires them into `ctx.resources`.
|
|
7
7
|
*/
|
|
8
8
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
9
|
-
export type {
|
|
10
|
-
|
|
11
|
-
/** Required browser services: the resource model, the Remote carrier and its namespace, and the Session list. */
|
|
9
|
+
export type { WorkspaceFileParams } from './types.ts';
|
|
10
|
+
/** Required browser services: the resource model, the Remote carrier and its namespace. */
|
|
12
11
|
export declare const inject: string[];
|
|
13
12
|
/**
|
|
14
13
|
* Client plugin body: register the `file` provider for this plugin's lifetime.
|
|
15
|
-
* @param ctx - client root context carrying `resources
|
|
14
|
+
* @param ctx - client root context carrying `resources` and the Remote face.
|
|
16
15
|
*/
|
|
17
16
|
export declare function apply(ctx: ClientContext): void;
|
|
18
17
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,18 +1,14 @@
|
|
|
1
1
|
import { ChangeFeed } from "./change-feed.js";
|
|
2
2
|
import { createFileResourceProvider } from "./provider.js";
|
|
3
|
-
/** Required browser services: the resource model, the Remote carrier and its namespace
|
|
4
|
-
export const inject = ['resources', 'remote', 'remote.workspaceFiles'
|
|
3
|
+
/** Required browser services: the resource model, the Remote carrier and its namespace. */
|
|
4
|
+
export const inject = ['resources', 'remote', 'remote.workspaceFiles'];
|
|
5
5
|
/**
|
|
6
6
|
* Client plugin body: register the `file` provider for this plugin's lifetime.
|
|
7
|
-
* @param ctx - client root context carrying `resources
|
|
7
|
+
* @param ctx - client root context carrying `resources` and the Remote face.
|
|
8
8
|
*/
|
|
9
9
|
export function apply(ctx) {
|
|
10
|
-
// The current Session changes with navigation; absolute addresses read it on demand.
|
|
11
|
-
const sessions = {
|
|
12
|
-
current: () => ctx.sessions.list.getSnapshot().current,
|
|
13
|
-
};
|
|
14
10
|
const changes = new ChangeFeed(ctx.remote);
|
|
15
|
-
const provider = createFileResourceProvider(ctx.remote, changes
|
|
11
|
+
const provider = createFileResourceProvider(ctx.remote, changes);
|
|
16
12
|
ctx.effect(() => {
|
|
17
13
|
const release = ctx.resources.register(provider);
|
|
18
14
|
// Teardown waits for every session stream still closing, so the plugin
|
|
@@ -3,43 +3,32 @@
|
|
|
3
3
|
* `RemoteResult` frames.
|
|
4
4
|
*
|
|
5
5
|
* An address names the file in one of two scopes. A `session` address,
|
|
6
|
-
* `dsh-resource://file/session/<sessionId>/<path>`, carries
|
|
7
|
-
* that Session's workspace root: the Host receives the
|
|
6
|
+
* `dsh-resource://file/session/<sessionId>/<path>`, carries an absolute path or one
|
|
7
|
+
* relative to that Session's workspace root: the Host receives the path as-is and
|
|
8
8
|
* resolves it against the root it holds. Only the Host's `stat.absolutePath`
|
|
9
9
|
* selects the change-feed key; no Client Session summary is needed.
|
|
10
10
|
* An `absolute` address, `dsh-resource://file/absolute/<path>`, carries no
|
|
11
|
-
* Session and
|
|
11
|
+
* Session and cannot authorize a Host call. An address neither scope
|
|
12
12
|
* resolves yields one failure frame — `workspace-file/unsupported-address` for
|
|
13
13
|
* a string outside the grammar, `workspace-file/unknown-workspace` when the
|
|
14
|
-
*
|
|
14
|
+
* address carries no Session — and ends.
|
|
15
15
|
*
|
|
16
16
|
* The first frame is the file's `stat`; every Host-reported write yields the
|
|
17
|
-
* metadata
|
|
18
|
-
* last stat had failed, runs `stat` again
|
|
19
|
-
* runs `stat` again and clears the flag. Failures travel as `ok: false` frames, never as thrown errors: the
|
|
17
|
+
* metadata with its reported version; a reported disappearance, or a write while the
|
|
18
|
+
* last stat had failed, runs `stat` again. Failures travel as `ok: false` frames, never as thrown errors: the
|
|
20
19
|
* Remote face does not reject, and anything thrown inside the stream is a
|
|
21
20
|
* programming error the resource model lets surface. A failed stat does not end
|
|
22
|
-
* the stream: the next write
|
|
21
|
+
* the stream: the next write stats again. One {@link ChangeFeed}
|
|
23
22
|
* serves every open file of the Client.
|
|
24
23
|
*/
|
|
25
24
|
import type { ResourceProvider } from '@deepseek-ai/dsh-client-resources/client';
|
|
26
|
-
import type { SessionId } from '@deepseek-ai/dsh-session/types';
|
|
27
25
|
import type { ChangeFeed } from './change-feed.ts';
|
|
28
26
|
import type { WorkspaceFilesRemote } from './remote.ts';
|
|
29
|
-
/** The current Session used to authorize an absolute address. */
|
|
30
|
-
export interface SessionLookup {
|
|
31
|
-
/**
|
|
32
|
-
* The Session on screen, which an `absolute` address is read through.
|
|
33
|
-
* @returns its id, or `undefined` while no Session is current.
|
|
34
|
-
*/
|
|
35
|
-
current(): SessionId | undefined;
|
|
36
|
-
}
|
|
37
27
|
/**
|
|
38
|
-
* Build the `file` provider over one Remote face
|
|
28
|
+
* Build the `file` provider over one Remote face and one change feed.
|
|
39
29
|
* @param remote - the Remote face carrying `workspaceFiles.stat`.
|
|
40
30
|
* @param changes - the per-session change fan-out.
|
|
41
|
-
* @param sessions - the current Session, read for absolute addresses on every open and reload.
|
|
42
31
|
* @returns the provider to register into `ctx.resources`.
|
|
43
32
|
*/
|
|
44
|
-
export declare function createFileResourceProvider(remote: WorkspaceFilesRemote, changes: ChangeFeed
|
|
33
|
+
export declare function createFileResourceProvider(remote: WorkspaceFilesRemote, changes: ChangeFeed): ResourceProvider<'file'>;
|
|
45
34
|
//# sourceMappingURL=provider.d.ts.map
|