@khorsheed/dsh-file-preview 0.4.1 → 0.4.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,7 +1,8 @@
1
1
  /* Generated by @deepseek-ai/dsh-typert-generator from the Host FaceModel — do not edit. */
2
2
  import type {
3
3
  RemoteResult,
4
- TypertRemoteContribution,
4
+ TypertRemoteInfo,
5
+ TypertRemoteMethod,
5
6
  } from '@deepseek-ai/dsh-typert-protocol'
6
7
  import type { SessionId } from '@deepseek-ai/dsh-session/types'
7
8
  import type { FilePreviewList, FilePreviewOpenExternal, FilePreviewRead, FilePreviewReveal, FilePreviewTurnMap } from '@khorsheed/dsh-file-preview/types'
@@ -35,6 +36,13 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
35
36
  }
36
37
  }
37
38
 
38
- export declare const TYPERT_REMOTE: TypertRemoteContribution
39
+ export declare const TYPERT_REMOTE: TypertRemoteInfo<{
40
+ readonly 'filePreview/capabilities': TypertRemoteMethod<{ }, { protocolVersion: 1; }>
41
+ readonly 'filePreview/list': TypertRemoteMethod<{ readonly 'agentId': SessionId }, FilePreviewList>
42
+ readonly 'filePreview/openExternal': TypertRemoteMethod<{ readonly 'agentId': SessionId; readonly 'path': string; readonly 'app': string }, FilePreviewOpenExternal>
43
+ readonly 'filePreview/read': TypertRemoteMethod<{ readonly 'agentId': SessionId; readonly 'path': string }, FilePreviewRead>
44
+ readonly 'filePreview/reveal': TypertRemoteMethod<{ readonly 'agentId': SessionId; readonly 'path': string }, FilePreviewReveal>
45
+ readonly 'filePreview/turnFiles': TypertRemoteMethod<{ readonly 'agentId': SessionId }, FilePreviewTurnMap>
46
+ }>
39
47
  export default TYPERT_REMOTE
40
48
  //# sourceMappingURL=typert.remote-client.d.ts.map
@@ -1,99 +1,117 @@
1
1
  /* Generated by @deepseek-ai/dsh-typert-generator from the Host FaceModel — do not edit. */
2
2
  import { z } from 'zod'
3
3
 
4
+ import { createTypertRemoteInfo } from '@deepseek-ai/dsh-typert-protocol/remote-info'
5
+
4
6
  let _khorsheed_dsh_file_preview_filePreview_capabilities_result$schema$value
5
7
  const _khorsheed_dsh_file_preview_filePreview_capabilities_result$schema = () => (_khorsheed_dsh_file_preview_filePreview_capabilities_result$schema$value ??= z.object({
6
8
  'protocolVersion': z.literal(1),
7
9
  }))
8
10
  let _khorsheed_dsh_file_preview_filePreview_list_parameter_0$schema$value
9
- const _khorsheed_dsh_file_preview_filePreview_list_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_list_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
11
+ const _khorsheed_dsh_file_preview_filePreview_list_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_list_parameter_0$schema$value ??= z.string())
10
12
  let _khorsheed_dsh_file_preview_filePreview_list_result$schema$value
11
13
  const _khorsheed_dsh_file_preview_filePreview_list_result$schema = () => (_khorsheed_dsh_file_preview_filePreview_list_result$schema$value ??= z.object({
12
14
  'entries': z.array(z.object({
13
- 'path': z.string().readonly(),
14
- 'op': z.union([z.literal("read"), z.literal("write"), z.literal("edit")]).readonly(),
15
- 'seq': z.number().readonly(),
16
- 'turn': z.number().readonly(),
17
- 'step': z.number().readonly(),
15
+ 'path': z.string().readonly().describe('Display path exactly as the tool call recorded it (relative to the session cwd when it was).'),
16
+ 'op': z.union([z.literal("edit"), z.literal("write"), z.literal("read")]).readonly().describe('The last recorded operation.'),
17
+ 'seq': z.number().readonly().describe('Seq of the last `tool/call` event recorded for this path.'),
18
+ 'turn': z.number().readonly().describe('Turn of the last occurrence.'),
19
+ 'step': z.number().readonly().describe('Step of the last occurrence.'),
18
20
  'diffs': z.array(z.object({
19
- 'seq': z.number().readonly(),
20
- 'turn': z.number().readonly(),
21
- 'step': z.number().readonly(),
22
- 'oldText': z.union([z.literal(null), z.string()]).readonly(),
23
- 'newText': z.string().readonly(),
24
- })).readonly(),
21
+ 'seq': z.number().readonly().describe('Seq of the `tool/result` event whose meta carried this diff.'),
22
+ 'turn': z.number().readonly().describe('Turn of the change.'),
23
+ 'step': z.number().readonly().describe('Step of the change.'),
24
+ 'oldText': z.union([z.literal(null), z.string()]).readonly().describe('Prior content, or null for a new file / an overwrite.'),
25
+ 'newText': z.string().readonly().describe('Content after the change.'),
26
+ })).readonly().describe('Each write/edit change\'s diff, captured from the tool results\' presentation meta, in event order.'),
25
27
  'lastDiff': z.union([z.undefined(), z.object({
26
28
  'oldText': z.union([z.literal(null), z.string()]).readonly(),
27
29
  'newText': z.string().readonly(),
28
- })]).readonly().optional(),
29
- })).readonly(),
30
- 'asOfSeq': z.number().readonly(),
31
- 'truncated': z.boolean().readonly(),
30
+ })]).readonly().optional().describe('The last write/edit change\'s diff (the final `diffs` entry, for callers that want just the latest).'),
31
+ })).readonly().describe('Files in first-seen order, deduplicated by display path.'),
32
+ 'asOfSeq': z.number().readonly().describe('Seq of the last scanned session event (`-1` for an empty log).'),
33
+ 'truncated': z.boolean().readonly().describe('Whether the list was capped at the service\'s `maxFiles` limit.'),
32
34
  }))
33
35
  let _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0$schema$value
34
- const _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
36
+ const _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0$schema$value ??= z.string())
35
37
  let _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1$schema$value
36
38
  const _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1$schema$value ??= z.string())
37
39
  let _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2$schema$value
38
40
  const _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2$schema$value ??= z.string())
39
41
  let _khorsheed_dsh_file_preview_filePreview_openExternal_result$schema$value
40
42
  const _khorsheed_dsh_file_preview_filePreview_openExternal_result$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_result$schema$value ??= z.union([z.object({
41
- 'opened': z.literal(true).readonly(),
43
+ 'opened': z.literal(true).readonly().describe('The application launched on the file.'),
42
44
  }), z.object({
43
- 'opened': z.literal(false).readonly(),
44
- 'reason': z.union([z.literal("missing"), z.literal("unknown-app"), z.literal("unsupported-platform"), z.literal("launch-failed")]).readonly(),
45
+ 'opened': z.literal(false).readonly().describe('The file could not be opened in the named application.'),
46
+ 'reason': z.union([z.literal("missing"), z.literal("unknown-app"), z.literal("unsupported-platform"), z.literal("launch-failed")]).readonly().describe('Why: `missing` = the recorded path does not resolve to an existing target; `unknown-app` = the catalog id is not mapped; `unsupported-platform` = the host is not macOS; `launch-failed` = the native launch rejected.'),
45
47
  })]))
46
48
  let _khorsheed_dsh_file_preview_filePreview_read_parameter_0$schema$value
47
- const _khorsheed_dsh_file_preview_filePreview_read_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_read_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
49
+ const _khorsheed_dsh_file_preview_filePreview_read_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_read_parameter_0$schema$value ??= z.string())
48
50
  let _khorsheed_dsh_file_preview_filePreview_read_parameter_1$schema$value
49
51
  const _khorsheed_dsh_file_preview_filePreview_read_parameter_1$schema = () => (_khorsheed_dsh_file_preview_filePreview_read_parameter_1$schema$value ??= z.string())
50
52
  let _khorsheed_dsh_file_preview_filePreview_read_result$schema$value
51
53
  const _khorsheed_dsh_file_preview_filePreview_read_result$schema = () => (_khorsheed_dsh_file_preview_filePreview_read_result$schema$value ??= z.object({
52
- 'path': z.string().readonly(),
53
- 'kind': z.union([z.literal("missing"), z.literal("too-large"), z.literal("error"), z.literal("text"), z.literal("binary"), z.literal("image")]).readonly(),
54
- 'content': z.string().readonly().optional(),
55
- 'url': z.string().readonly().optional(),
56
- 'truncated': z.boolean().readonly().optional(),
57
- 'htmlScripted': z.boolean().readonly().optional(),
58
- 'size': z.number().readonly().optional(),
59
- 'message': z.string().readonly().optional(),
54
+ 'path': z.string().readonly().describe('The resolved display path of the read target.'),
55
+ 'kind': z.union([z.literal("text"), z.literal("image"), z.literal("error"), z.literal("missing"), z.literal("too-large"), z.literal("binary")]).readonly().describe('Outcome classification; `text`/`image` carry a renderable value, `error` carries message.'),
56
+ 'content': z.string().readonly().optional().describe('Current text content for `text` reads, capped by the service\'s `maxReadBytes` (HTML files by `htmlMaxReadBytes`).'),
57
+ 'url': z.string().readonly().optional().describe('Browser-loadable URL for `image` reads (host-served bytes, session-scoped).'),
58
+ 'truncated': z.boolean().readonly().optional().describe('Whether `content` was truncated to the byte cap.'),
59
+ 'htmlScripted': z.boolean().readonly().optional().describe('HTML files only: best-effort hint that the document contains scripts (`<script>` tags, inline event handlers, or `javascript:` URLs). A hint for default-mode selection and warning — never a trust decision; the sandbox and CSP are the real boundary. Absent for non-HTML reads and for HTML without script markers.'),
60
+ 'size': z.number().readonly().optional().describe('Byte size of the file when the backend reported one.'),
61
+ 'message': z.string().readonly().optional().describe('Human-readable failure detail for `error` reads.'),
60
62
  }))
61
63
  let _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0$schema$value
62
- const _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_reveal_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
64
+ const _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_reveal_parameter_0$schema$value ??= z.string())
63
65
  let _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1$schema$value
64
66
  const _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1$schema = () => (_khorsheed_dsh_file_preview_filePreview_reveal_parameter_1$schema$value ??= z.string())
65
67
  let _khorsheed_dsh_file_preview_filePreview_reveal_result$schema$value
66
68
  const _khorsheed_dsh_file_preview_filePreview_reveal_result$schema = () => (_khorsheed_dsh_file_preview_filePreview_reveal_result$schema$value ??= z.union([z.object({
67
- 'revealed': z.literal(true).readonly(),
69
+ 'revealed': z.literal(true).readonly().describe('The host file manager opened the file\'s folder with the file selected.'),
68
70
  }), z.object({
69
- 'revealed': z.literal(false).readonly(),
70
- 'reason': z.union([z.literal("missing"), z.literal("select-failed")]).readonly(),
71
+ 'revealed': z.literal(false).readonly().describe('The file could not be revealed; the caller opens the parent folder instead.'),
72
+ 'reason': z.union([z.literal("missing"), z.literal("select-failed")]).readonly().describe('Why: `missing` = the recorded path does not resolve to an existing target; `select-failed` = the host could not select the file.'),
71
73
  })]))
72
74
  let _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0$schema$value
73
- const _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0$schema$value ??= z.intersection(z.string(), z.unknown()))
75
+ const _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0$schema = () => (_khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0$schema$value ??= z.string())
74
76
  let _khorsheed_dsh_file_preview_filePreview_turnFiles_result$schema$value
75
77
  const _khorsheed_dsh_file_preview_filePreview_turnFiles_result$schema = () => (_khorsheed_dsh_file_preview_filePreview_turnFiles_result$schema$value ??= z.object({
76
78
  'turns': z.array(z.object({
77
79
  'turn': z.number().readonly(),
78
80
  'files': z.array(z.object({
79
- 'path': z.string().readonly(),
80
- 'seq': z.number().readonly(),
81
+ 'path': z.string().readonly().describe('The display path (absolute for bash-captured writes; as-recorded otherwise).'),
82
+ 'seq': z.number().readonly().describe('Seq of the first mutation recorded for this path in this turn (stable ordering).'),
81
83
  'step': z.number().readonly(),
82
- 'added': z.number().readonly().optional(),
83
- 'removed': z.number().readonly().optional(),
84
- })).readonly(),
84
+ 'added': z.number().readonly().optional().describe('Lines added across the turn\'s mutations of this path.'),
85
+ 'removed': z.number().readonly().optional().describe('Lines removed; 0 for a create; absent when an uncounted mutation (a write whose prior content was not diffable, a PTC dispatch) reported no total.'),
85
86
  })).readonly(),
86
- 'asOfSeq': z.number().readonly(),
87
+ })).readonly().describe('Files mutated per turn, in event order within each turn.'),
88
+ 'asOfSeq': z.number().readonly().describe('Seq of the last scanned session event (cache invalidation watermark).'),
87
89
  }))
90
+ let _khorsheed_dsh_file_preview_filePreview_list_parameter_0_strict$schema$value
91
+ const _khorsheed_dsh_file_preview_filePreview_list_parameter_0_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_list_parameter_0_strict$schema$value ??= z.string())
92
+ let _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0_strict$schema$value
93
+ const _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0_strict$schema$value ??= z.string())
94
+ let _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1_strict$schema$value
95
+ const _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1_strict$schema$value ??= z.string())
96
+ let _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2_strict$schema$value
97
+ const _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2_strict$schema$value ??= z.string())
98
+ let _khorsheed_dsh_file_preview_filePreview_read_parameter_0_strict$schema$value
99
+ const _khorsheed_dsh_file_preview_filePreview_read_parameter_0_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_read_parameter_0_strict$schema$value ??= z.string())
100
+ let _khorsheed_dsh_file_preview_filePreview_read_parameter_1_strict$schema$value
101
+ const _khorsheed_dsh_file_preview_filePreview_read_parameter_1_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_read_parameter_1_strict$schema$value ??= z.string())
102
+ let _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0_strict$schema$value
103
+ const _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_reveal_parameter_0_strict$schema$value ??= z.string())
104
+ let _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1_strict$schema$value
105
+ const _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_reveal_parameter_1_strict$schema$value ??= z.string())
106
+ let _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0_strict$schema$value
107
+ const _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0_strict$schema = () => (_khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0_strict$schema$value ??= z.string())
88
108
 
89
- export const TYPERT_REMOTE = {
109
+ export const TYPERT_REMOTE = createTypertRemoteInfo({
90
110
  package: '@khorsheed/dsh-file-preview',
91
- descriptors: [
92
- {
93
- id: '@khorsheed/dsh-file-preview#filePreview/capabilities',
111
+ methods: {
112
+ 'filePreview/capabilities': {
94
113
  service: 'filePreview',
95
- namespace: 'filePreview',
96
- method: 'capabilities',
114
+ description: 'Zero-session availability handshake for browser companions.',
97
115
  invocation: { kind: 'direct' },
98
116
  parameters: [
99
117
  ],
@@ -102,14 +120,13 @@ export const TYPERT_REMOTE = {
102
120
  typeSymbol: '@khorsheed/dsh-file-preview#filePreview/capabilities:result',
103
121
  create: _khorsheed_dsh_file_preview_filePreview_capabilities_result$schema,
104
122
  schema: _khorsheed_dsh_file_preview_filePreview_capabilities_result$schema(),
123
+ jsonSchema: {"type":"object","properties":{"protocolVersion":{"type":"number","const":1}},"required":["protocolVersion"],"additionalProperties":true},
105
124
  },
106
- sourceLocation: {"file":"packages/file-preview/src/index.ts","line":196,"column":3},
125
+ sourceLocation: {"file":"packages/file-preview/src/index.ts","line":135,"column":3},
107
126
  },
108
- {
109
- id: '@khorsheed/dsh-file-preview#filePreview/list',
127
+ 'filePreview/list': {
110
128
  service: 'filePreview',
111
- namespace: 'filePreview',
112
- method: 'list',
129
+ description: 'List the files one session wrote or edited: the log fold plus any bash-written files the collector verified (the S2 seam), merged so a captured path the fold already knows keeps its log-derived entry. Only paths that currently exist on disk are returned — a file the session wrote and later deleted is history, not a product.',
113
130
  invocation: { kind: 'direct' },
114
131
  scope: {
115
132
  context: 'agent',
@@ -119,6 +136,7 @@ export const TYPERT_REMOTE = {
119
136
  {
120
137
  name: 'agent',
121
138
  wire: 'agentId',
139
+ description: 'owning live agent; its session log is the data source.',
122
140
  source: 'lookup',
123
141
  lookup: 'agent',
124
142
  codec: {
@@ -126,6 +144,14 @@ export const TYPERT_REMOTE = {
126
144
  typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
127
145
  create: _khorsheed_dsh_file_preview_filePreview_list_parameter_0$schema,
128
146
  schema: _khorsheed_dsh_file_preview_filePreview_list_parameter_0$schema(),
147
+ jsonSchema: {"type":"string"},
148
+ },
149
+ strictCodec: {
150
+ mode: 'strict',
151
+ typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
152
+ create: _khorsheed_dsh_file_preview_filePreview_list_parameter_0_strict$schema,
153
+ schema: _khorsheed_dsh_file_preview_filePreview_list_parameter_0_strict$schema(),
154
+ jsonSchema: {"type":"string"},
129
155
  },
130
156
  },
131
157
  ],
@@ -134,14 +160,14 @@ export const TYPERT_REMOTE = {
134
160
  typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewList',
135
161
  create: _khorsheed_dsh_file_preview_filePreview_list_result$schema,
136
162
  schema: _khorsheed_dsh_file_preview_filePreview_list_result$schema(),
163
+ description: 'existing first-seen files capped by `maxFiles`, with the log watermark.',
164
+ jsonSchema: {"type":"object","properties":{"entries":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"Display path exactly as the tool call recorded it (relative to the session cwd when it was)."},"op":{"type":"string","enum":["edit","write","read"],"description":"The last recorded operation."},"seq":{"type":"number","description":"Seq of the last `tool/call` event recorded for this path."},"turn":{"type":"number","description":"Turn of the last occurrence."},"step":{"type":"number","description":"Step of the last occurrence."},"diffs":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"number","description":"Seq of the `tool/result` event whose meta carried this diff."},"turn":{"type":"number","description":"Turn of the change."},"step":{"type":"number","description":"Step of the change."},"oldText":{"oneOf":[{"type":"null","const":null},{"type":"string"}],"description":"Prior content, or null for a new file / an overwrite."},"newText":{"type":"string","description":"Content after the change."}},"required":["seq","turn","step","oldText","newText"],"additionalProperties":true},"description":"Each write/edit change's diff, captured from the tool results' presentation meta, in event order."},"lastDiff":{"type":"object","properties":{"oldText":{"oneOf":[{"type":"null","const":null},{"type":"string"}]},"newText":{"type":"string"}},"required":["oldText","newText"],"additionalProperties":true,"description":"The last write/edit change's diff (the final `diffs` entry, for callers that want just the latest)."}},"required":["path","op","seq","turn","step","diffs"],"additionalProperties":true},"description":"Files in first-seen order, deduplicated by display path."},"asOfSeq":{"type":"number","description":"Seq of the last scanned session event (`-1` for an empty log)."},"truncated":{"type":"boolean","description":"Whether the list was capped at the service's `maxFiles` limit."}},"required":["entries","asOfSeq","truncated"],"additionalProperties":true},
137
165
  },
138
- sourceLocation: {"file":"packages/file-preview/src/index.ts","line":316,"column":9},
166
+ sourceLocation: {"file":"packages/file-preview/src/index.ts","line":227,"column":9},
139
167
  },
140
- {
141
- id: '@khorsheed/dsh-file-preview#filePreview/openExternal',
168
+ 'filePreview/openExternal': {
142
169
  service: 'filePreview',
143
- namespace: 'filePreview',
144
- method: 'openExternal',
170
+ description: 'Open one recorded file in a specific host application (the "open in IDE" gesture). The official open-in-app route only accepts directories — a file path 404s — so file-exact opens go through this method: macOS `open -a <App> <path>` via the same native-command runner reveal uses. The browser names the application by official open-in-app catalog id (probed from `/open-in-app/apps`); the id → app-name map lives in open-external.ts. Non-macOS hosts and unknown ids answer without launching, and the client hides the gesture.',
145
171
  invocation: { kind: 'direct' },
146
172
  scope: {
147
173
  context: 'agent',
@@ -151,6 +177,7 @@ export const TYPERT_REMOTE = {
151
177
  {
152
178
  name: 'agent',
153
179
  wire: 'agentId',
180
+ description: 'owning live agent; its session cwd anchors relative paths.',
154
181
  source: 'lookup',
155
182
  lookup: 'agent',
156
183
  codec: {
@@ -158,28 +185,52 @@ export const TYPERT_REMOTE = {
158
185
  typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
159
186
  create: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0$schema,
160
187
  schema: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0$schema(),
188
+ jsonSchema: {"type":"string"},
189
+ },
190
+ strictCodec: {
191
+ mode: 'strict',
192
+ typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
193
+ create: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0_strict$schema,
194
+ schema: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_0_strict$schema(),
195
+ jsonSchema: {"type":"string"},
161
196
  },
162
197
  },
163
198
  {
164
199
  name: 'path',
165
- wire: 'path',
200
+ description: 'the display path recorded by the read/write/edit tool call.',
166
201
  source: 'json',
167
202
  codec: {
168
203
  mode: 'strict',
169
204
  typeSymbol: '@khorsheed/dsh-file-preview#filePreview/openExternal:path',
170
205
  create: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1$schema,
171
206
  schema: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1$schema(),
207
+ jsonSchema: {"type":"string"},
208
+ },
209
+ strictCodec: {
210
+ mode: 'strict',
211
+ typeSymbol: '@khorsheed/dsh-file-preview#filePreview/openExternal:path',
212
+ create: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1_strict$schema,
213
+ schema: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_1_strict$schema(),
214
+ jsonSchema: {"type":"string"},
172
215
  },
173
216
  },
174
217
  {
175
218
  name: 'app',
176
- wire: 'app',
219
+ description: 'official open-in-app catalog id (e.g. `cursor`).',
177
220
  source: 'json',
178
221
  codec: {
179
222
  mode: 'strict',
180
223
  typeSymbol: '@khorsheed/dsh-file-preview#filePreview/openExternal:app',
181
224
  create: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2$schema,
182
225
  schema: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2$schema(),
226
+ jsonSchema: {"type":"string"},
227
+ },
228
+ strictCodec: {
229
+ mode: 'strict',
230
+ typeSymbol: '@khorsheed/dsh-file-preview#filePreview/openExternal:app',
231
+ create: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2_strict$schema,
232
+ schema: _khorsheed_dsh_file_preview_filePreview_openExternal_parameter_2_strict$schema(),
233
+ jsonSchema: {"type":"string"},
183
234
  },
184
235
  },
185
236
  ],
@@ -189,14 +240,14 @@ export const TYPERT_REMOTE = {
189
240
  typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewOpenExternal',
190
241
  create: _khorsheed_dsh_file_preview_filePreview_openExternal_result$schema,
191
242
  schema: _khorsheed_dsh_file_preview_filePreview_openExternal_result$schema(),
243
+ description: 'whether the application launched, or why not.',
244
+ jsonSchema: {"oneOf":[{"type":"object","properties":{"opened":{"type":"boolean","const":true,"description":"The application launched on the file."}},"required":["opened"],"additionalProperties":true},{"type":"object","properties":{"opened":{"type":"boolean","const":false,"description":"The file could not be opened in the named application."},"reason":{"type":"string","enum":["missing","unknown-app","unsupported-platform","launch-failed"],"description":"Why: `missing` = the recorded path does not resolve to an existing target; `unknown-app` = the catalog id is not mapped; `unsupported-platform` = the host is not macOS; `launch-failed` = the native launch rejected."}},"required":["opened","reason"],"additionalProperties":true}]},
192
245
  },
193
- sourceLocation: {"file":"packages/file-preview/src/index.ts","line":539,"column":9},
246
+ sourceLocation: {"file":"packages/file-preview/src/index.ts","line":369,"column":9},
194
247
  },
195
- {
196
- id: '@khorsheed/dsh-file-preview#filePreview/read',
248
+ 'filePreview/read': {
197
249
  service: 'filePreview',
198
- namespace: 'filePreview',
199
- method: 'read',
250
+ description: 'Read the current content of one recorded file, resolved against the session cwd and capped by `maxReadBytes`. The text read is a bounded byte window (`readByteRange` of cap + 1 bytes), so an oversized file costs the cap, never its full size; a known oversized stat still short-circuits to `too-large` before any bytes move.',
200
251
  invocation: { kind: 'direct' },
201
252
  scope: {
202
253
  context: 'agent',
@@ -206,6 +257,7 @@ export const TYPERT_REMOTE = {
206
257
  {
207
258
  name: 'agent',
208
259
  wire: 'agentId',
260
+ description: 'owning live agent; its session cwd anchors relative paths.',
209
261
  source: 'lookup',
210
262
  lookup: 'agent',
211
263
  codec: {
@@ -213,17 +265,33 @@ export const TYPERT_REMOTE = {
213
265
  typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
214
266
  create: _khorsheed_dsh_file_preview_filePreview_read_parameter_0$schema,
215
267
  schema: _khorsheed_dsh_file_preview_filePreview_read_parameter_0$schema(),
268
+ jsonSchema: {"type":"string"},
269
+ },
270
+ strictCodec: {
271
+ mode: 'strict',
272
+ typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
273
+ create: _khorsheed_dsh_file_preview_filePreview_read_parameter_0_strict$schema,
274
+ schema: _khorsheed_dsh_file_preview_filePreview_read_parameter_0_strict$schema(),
275
+ jsonSchema: {"type":"string"},
216
276
  },
217
277
  },
218
278
  {
219
279
  name: 'path',
220
- wire: 'path',
280
+ description: 'the display path recorded by the write/edit tool call.',
221
281
  source: 'json',
222
282
  codec: {
223
283
  mode: 'strict',
224
284
  typeSymbol: '@khorsheed/dsh-file-preview#filePreview/read:path',
225
285
  create: _khorsheed_dsh_file_preview_filePreview_read_parameter_1$schema,
226
286
  schema: _khorsheed_dsh_file_preview_filePreview_read_parameter_1$schema(),
287
+ jsonSchema: {"type":"string"},
288
+ },
289
+ strictCodec: {
290
+ mode: 'strict',
291
+ typeSymbol: '@khorsheed/dsh-file-preview#filePreview/read:path',
292
+ create: _khorsheed_dsh_file_preview_filePreview_read_parameter_1_strict$schema,
293
+ schema: _khorsheed_dsh_file_preview_filePreview_read_parameter_1_strict$schema(),
294
+ jsonSchema: {"type":"string"},
227
295
  },
228
296
  },
229
297
  ],
@@ -233,14 +301,14 @@ export const TYPERT_REMOTE = {
233
301
  typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewRead',
234
302
  create: _khorsheed_dsh_file_preview_filePreview_read_result$schema,
235
303
  schema: _khorsheed_dsh_file_preview_filePreview_read_result$schema(),
304
+ description: 'the classified read; `text` carries content, `image` carries a browser URL, other kinds carry the size or a human-readable reason.',
305
+ jsonSchema: {"type":"object","properties":{"path":{"type":"string","description":"The resolved display path of the read target."},"kind":{"type":"string","enum":["text","image","error","missing","too-large","binary"],"description":"Outcome classification; `text`/`image` carry a renderable value, `error` carries message."},"content":{"type":"string","description":"Current text content for `text` reads, capped by the service's `maxReadBytes` (HTML files by `htmlMaxReadBytes`)."},"url":{"type":"string","description":"Browser-loadable URL for `image` reads (host-served bytes, session-scoped)."},"truncated":{"type":"boolean","description":"Whether `content` was truncated to the byte cap."},"htmlScripted":{"type":"boolean","description":"HTML files only: best-effort hint that the document contains scripts (`<script>` tags, inline event handlers, or `javascript:` URLs). A hint for default-mode selection and warning — never a trust decision; the sandbox and CSP are the real boundary. Absent for non-HTML reads and for HTML without script markers."},"size":{"type":"number","description":"Byte size of the file when the backend reported one."},"message":{"type":"string","description":"Human-readable failure detail for `error` reads."}},"required":["path","kind"],"additionalProperties":true},
236
306
  },
237
- sourceLocation: {"file":"packages/file-preview/src/index.ts","line":409,"column":9},
307
+ sourceLocation: {"file":"packages/file-preview/src/index.ts","line":286,"column":9},
238
308
  },
239
- {
240
- id: '@khorsheed/dsh-file-preview#filePreview/reveal',
309
+ 'filePreview/reveal': {
241
310
  service: 'filePreview',
242
- namespace: 'filePreview',
243
- method: 'reveal',
311
+ description: 'Reveal one recorded file in the host file manager — open its folder and select the file (macOS Finder, Windows Explorer, or a select-capable desktop file manager). The display path resolves against the session cwd; the native reveal runs on the host. A path that does not resolve to an existing target, or a platform that cannot select, answers `revealed: false` and the caller opens the parent folder instead (the pre-reveal "show in folder" behavior), so the gesture always lands somewhere visible.',
244
312
  invocation: { kind: 'direct' },
245
313
  scope: {
246
314
  context: 'agent',
@@ -250,6 +318,7 @@ export const TYPERT_REMOTE = {
250
318
  {
251
319
  name: 'agent',
252
320
  wire: 'agentId',
321
+ description: 'owning live agent; its session cwd anchors relative paths.',
253
322
  source: 'lookup',
254
323
  lookup: 'agent',
255
324
  codec: {
@@ -257,17 +326,33 @@ export const TYPERT_REMOTE = {
257
326
  typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
258
327
  create: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0$schema,
259
328
  schema: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0$schema(),
329
+ jsonSchema: {"type":"string"},
330
+ },
331
+ strictCodec: {
332
+ mode: 'strict',
333
+ typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
334
+ create: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0_strict$schema,
335
+ schema: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_0_strict$schema(),
336
+ jsonSchema: {"type":"string"},
260
337
  },
261
338
  },
262
339
  {
263
340
  name: 'path',
264
- wire: 'path',
341
+ description: 'the display path recorded by the read/write/edit tool call.',
265
342
  source: 'json',
266
343
  codec: {
267
344
  mode: 'strict',
268
345
  typeSymbol: '@khorsheed/dsh-file-preview#filePreview/reveal:path',
269
346
  create: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1$schema,
270
347
  schema: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1$schema(),
348
+ jsonSchema: {"type":"string"},
349
+ },
350
+ strictCodec: {
351
+ mode: 'strict',
352
+ typeSymbol: '@khorsheed/dsh-file-preview#filePreview/reveal:path',
353
+ create: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1_strict$schema,
354
+ schema: _khorsheed_dsh_file_preview_filePreview_reveal_parameter_1_strict$schema(),
355
+ jsonSchema: {"type":"string"},
271
356
  },
272
357
  },
273
358
  ],
@@ -277,14 +362,14 @@ export const TYPERT_REMOTE = {
277
362
  typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewReveal',
278
363
  create: _khorsheed_dsh_file_preview_filePreview_reveal_result$schema,
279
364
  schema: _khorsheed_dsh_file_preview_filePreview_reveal_result$schema(),
365
+ description: 'whether the file manager selected the file, or why not.',
366
+ jsonSchema: {"oneOf":[{"type":"object","properties":{"revealed":{"type":"boolean","const":true,"description":"The host file manager opened the file's folder with the file selected."}},"required":["revealed"],"additionalProperties":true},{"type":"object","properties":{"revealed":{"type":"boolean","const":false,"description":"The file could not be revealed; the caller opens the parent folder instead."},"reason":{"type":"string","enum":["missing","select-failed"],"description":"Why: `missing` = the recorded path does not resolve to an existing target; `select-failed` = the host could not select the file."}},"required":["revealed","reason"],"additionalProperties":true}]},
280
367
  },
281
- sourceLocation: {"file":"packages/file-preview/src/index.ts","line":489,"column":9},
368
+ sourceLocation: {"file":"packages/file-preview/src/index.ts","line":319,"column":9},
282
369
  },
283
- {
284
- id: '@khorsheed/dsh-file-preview#filePreview/turnFiles',
370
+ 'filePreview/turnFiles': {
285
371
  service: 'filePreview',
286
- namespace: 'filePreview',
287
- method: 'turnFiles',
372
+ description: 'Every turn\'s file mutations for the turn-tail card — the single source of truth the card renders (the client\'s old write/edit-only fold retired). Built by folding the session log per turn (write/edit calls, PTC dispatches borrowing the root call\'s turn, and render-intent paths from result diff meta) and merging the collector\'s bash-written captures by their own turn. The fold is cached per session and invalidated by the log watermark, so repeated card fetches do not refold. A path touched in two turns appears in BOTH turn groups — per-turn attribution is exact. Only paths that currently exist on disk are returned (a deleted temp script is history, not a product); existence is probed fresh on every call, so the cached fold is filtered per request rather than cached.',
288
373
  invocation: { kind: 'direct' },
289
374
  scope: {
290
375
  context: 'agent',
@@ -294,6 +379,7 @@ export const TYPERT_REMOTE = {
294
379
  {
295
380
  name: 'agent',
296
381
  wire: 'agentId',
382
+ description: 'owning live agent; its session log is the data source.',
297
383
  source: 'lookup',
298
384
  lookup: 'agent',
299
385
  codec: {
@@ -301,6 +387,14 @@ export const TYPERT_REMOTE = {
301
387
  typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
302
388
  create: _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0$schema,
303
389
  schema: _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0$schema(),
390
+ jsonSchema: {"type":"string"},
391
+ },
392
+ strictCodec: {
393
+ mode: 'strict',
394
+ typeSymbol: '@deepseek-ai/dsh-session/types#SessionId',
395
+ create: _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0_strict$schema,
396
+ schema: _khorsheed_dsh_file_preview_filePreview_turnFiles_parameter_0_strict$schema(),
397
+ jsonSchema: {"type":"string"},
304
398
  },
305
399
  },
306
400
  ],
@@ -309,10 +403,12 @@ export const TYPERT_REMOTE = {
309
403
  typeSymbol: '@khorsheed/dsh-file-preview/types#FilePreviewTurnMap',
310
404
  create: _khorsheed_dsh_file_preview_filePreview_turnFiles_result$schema,
311
405
  schema: _khorsheed_dsh_file_preview_filePreview_turnFiles_result$schema(),
406
+ description: 'existing per-turn file groups plus the scanned watermark.',
407
+ jsonSchema: {"type":"object","properties":{"turns":{"type":"array","items":{"type":"object","properties":{"turn":{"type":"number"},"files":{"type":"array","items":{"type":"object","properties":{"path":{"type":"string","description":"The display path (absolute for bash-captured writes; as-recorded otherwise)."},"seq":{"type":"number","description":"Seq of the first mutation recorded for this path in this turn (stable ordering)."},"step":{"type":"number"},"added":{"type":"number","description":"Lines added across the turn's mutations of this path."},"removed":{"type":"number","description":"Lines removed; 0 for a create; absent when an uncounted mutation (a write whose prior content was not diffable, a PTC dispatch) reported no total."}},"required":["path","seq","step"],"additionalProperties":true}}},"required":["turn","files"],"additionalProperties":true},"description":"Files mutated per turn, in event order within each turn."},"asOfSeq":{"type":"number","description":"Seq of the last scanned session event (cache invalidation watermark)."}},"required":["turns","asOfSeq"],"additionalProperties":true},
312
408
  },
313
- sourceLocation: {"file":"packages/file-preview/src/index.ts","line":353,"column":9},
409
+ sourceLocation: {"file":"packages/file-preview/src/index.ts","line":253,"column":9},
314
410
  },
315
- ],
316
- }
411
+ },
412
+ }, z)
317
413
 
318
414
  export default TYPERT_REMOTE
@@ -16,6 +16,7 @@
16
16
  * @module @khorsheed/dsh-file-preview
17
17
  */
18
18
  import type { Context } from '@deepseek-ai/cordis';
19
+ import type { SessionEvent } from '@deepseek-ai/dsh-session';
19
20
  import type { FileSystem } from '@deepseek-ai/dsh-fs';
20
21
  /** One verified captured write, merged into the fold as a `write` entry. */
21
22
  export interface CapturedWrite {
@@ -53,7 +54,9 @@ export declare function extractWriteTargets(command: string): string[];
53
54
  export declare function expandShellPath(token: string, env: NodeJS.ProcessEnv, home: string, cwd: string | undefined): string | null;
54
55
  /** Options for {@link BashWriteCollector}. */
55
56
  export interface BashWriteCollectorOptions {
56
- fs: FileSystem;
57
+ /** The fs face candidates resolve and stat through (the two members the
58
+ * collector reads from `ctx.fs`; any face honoring the same contract plugs in). */
59
+ fs: Pick<FileSystem, 'resolve' | 'stat'>;
57
60
  env?: NodeJS.ProcessEnv;
58
61
  home?: string;
59
62
  /** Cap on captured writes per session (mirrors the fold's maxFiles). */
@@ -79,5 +82,20 @@ export declare class BashWriteCollector {
79
82
  attach(ctx: Context): () => void;
80
83
  /** Verified captures for one session (the fold-merge source), or undefined. */
81
84
  captured(sessionId: string): ReadonlyMap<string, CapturedWrite> | undefined;
85
+ /**
86
+ * Rebuild one session's captures from its own event snapshot — the
87
+ * snapshot-driven twin of the live feed's replay, for a caller that holds
88
+ * the session's events rather than a composition's event feed. The same
89
+ * extraction, expansion, and stat-verification pipeline runs in event
90
+ * order, every verification awaited, so the result mirrors what the live
91
+ * feed would have captured from the same events. Nothing is stored in the
92
+ * live registry: pending candidates and verified captures are local to the
93
+ * call.
94
+ * @param cwd - the session's cwd for relative write targets, or undefined.
95
+ * @param events - the session's events in ascending seq order.
96
+ * @returns the verified captures (undefined when none survived, mirroring
97
+ * `captured`).
98
+ */
99
+ replaySnapshot(cwd: string | undefined, events: readonly SessionEvent[]): Promise<ReadonlyMap<string, CapturedWrite> | undefined>;
82
100
  }
83
101
  //# sourceMappingURL=bash-writes.d.ts.map
@@ -301,6 +301,56 @@ export class BashWriteCollector {
301
301
  captured(sessionId) {
302
302
  return this.#captured.get(sessionId);
303
303
  }
304
+ /**
305
+ * Rebuild one session's captures from its own event snapshot — the
306
+ * snapshot-driven twin of the live feed's replay, for a caller that holds
307
+ * the session's events rather than a composition's event feed. The same
308
+ * extraction, expansion, and stat-verification pipeline runs in event
309
+ * order, every verification awaited, so the result mirrors what the live
310
+ * feed would have captured from the same events. Nothing is stored in the
311
+ * live registry: pending candidates and verified captures are local to the
312
+ * call.
313
+ * @param cwd - the session's cwd for relative write targets, or undefined.
314
+ * @param events - the session's events in ascending seq order.
315
+ * @returns the verified captures (undefined when none survived, mirroring
316
+ * `captured`).
317
+ */
318
+ async replaySnapshot(cwd, events) {
319
+ const pending = new Map();
320
+ const captured = new Map();
321
+ for (const event of events) {
322
+ if (event.type === 'tool/call') {
323
+ if (event.data.name !== 'bash')
324
+ continue;
325
+ const command = parseArguments(event.data.arguments).command;
326
+ if (typeof command !== 'string' || command.length === 0)
327
+ continue;
328
+ const candidates = extractWriteTargets(command)
329
+ .map(token => expandShellPath(token, this.#env, this.#home, cwd))
330
+ .filter((path) => path !== null);
331
+ if (candidates.length === 0)
332
+ continue;
333
+ pending.set(String(event.data.callId), {
334
+ turn: event.data.turn,
335
+ step: event.data.step,
336
+ seq: event.seq,
337
+ candidates,
338
+ });
339
+ continue;
340
+ }
341
+ if (event.type === 'tool/result') {
342
+ const callId = String(event.data.message?.source?.callId ?? '');
343
+ const write = pending.get(callId);
344
+ if (write === undefined)
345
+ continue;
346
+ pending.delete(callId);
347
+ // Awaited in event order so the capture map's contents and insertion
348
+ // order are the deterministic twin of the live feed's.
349
+ await this.#verifyInto(captured, write);
350
+ }
351
+ }
352
+ return captured.size === 0 ? undefined : captured;
353
+ }
304
354
  /** Rebuild one session's registry from its own history (host restart). */
305
355
  #replay(session) {
306
356
  this.#pending.set(session.id, new Map());
@@ -345,6 +395,12 @@ export class BashWriteCollector {
345
395
  /** stat-verify the pending candidates and store the survivors. */
346
396
  async #verify(session, pending) {
347
397
  const captured = this.#captured.get(session.id) ?? new Map();
398
+ await this.#verifyInto(captured, pending);
399
+ if (captured.size > 0)
400
+ this.#captured.set(session.id, captured);
401
+ }
402
+ /** stat-verify the pending candidates into the given capture map. */
403
+ async #verifyInto(captured, pending) {
348
404
  for (const candidate of pending.candidates) {
349
405
  if (captured.size >= this.#maxFiles || captured.has(candidate))
350
406
  continue;
@@ -361,7 +417,5 @@ export class BashWriteCollector {
361
417
  captured.set(candidate, { turn: pending.turn, step: pending.step, seq: pending.seq });
362
418
  }
363
419
  }
364
- if (captured.size > 0)
365
- this.#captured.set(session.id, captured);
366
420
  }
367
421
  }