@deepseek-ai/dsh-api-session-controller 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 CHANGED
@@ -2,5 +2,5 @@
2
2
  # side as of the last confirmed-consistent state. Both languages carry equal authority;
3
3
  # after editing either side, bring the other along and re-record with:
4
4
  # pnpm run verify-translation-pairing --write packages/api/session-controller/README.md
5
- README.md: ef6ffb35636f9f1a87c3b30832f68540d5dcd0ea
6
- README.zh.md: 97949e01379446e6171debb9fb1250e8088413f8
5
+ README.md: 24cfbba626ddec510452e3b6c8bc4333c03876bd
6
+ README.zh.md: c90357c60eab9427f5656b48c4ea99252d87e2bf
package/README.md CHANGED
@@ -28,7 +28,7 @@ History pages and follow opening snapshots carry one `{ type: 'event', event: Se
28
28
 
29
29
  The Client journal validates exact V3 event envelopes before publishing follow snapshots, live entries, or history pages. It reuses the browser-safe Session validators for required surface markers, exact replacement endpoints, earlier unique source seqs, embedded Assistant provenance, request-header omissions, and tool-error consistency. Invalid records fail without field stripping or normalization; range membership and source existence remain durable-log checks on the Host.
30
30
 
31
- Each endpoint states its activation policy. List reads only stored headers and projection-cache rows: it never calls per-session stat or opens a cold Session body. A current-format cache identity may supply every list hint; a lifecycle-matching predecessor cache may supply only its version-compatible title as a stale display fact, never as an authoritative fold seed. Search, attachment, history pages, log following, skill discovery, and workspace-path opening can inspect persistence without activating an Agent; `canOpenWorkspacePath()` reports native-opening availability without addressing a Session. Queue mutation and cancellation require live state; model, rename, prompt, and file-reference operations may resolve or resume an ordinary Session. Prompt rejects content with neither non-whitespace text nor an attachment before resolving the Agent or appending Session events; queue edits accept only non-empty text content. Prompt admission consumes opaque receipts from the injected [`fileUploads`](../../client/file-upload/README.md) Host service and resolves every same-Agent receipt before sending the complete ordered content list through `ctx.attachments`. Prompt retries whose `requestId` is already queued or logged return the original acceptance without inserting another message. Create and fork are the only operations that create a new Agent directly. The service applies one preset-aware resume policy and subagent ownership fence to its own methods and to the Typert Agent and Session lookups used by other Remote namespaces. Queue mutation has one narrow exception: a live child whose current projected identity is continuable and comes from its own non-seed suffix accepts the ordinary Edit, Remove, and QueueDock Steer actions across both inbox destinations. One-shot, missing, unknown, corrupt, seed-only, or cold children remain rejected without resume. The skill catalog uses a live Agent when present or the recorded preset's standing scope when cold, so listing never starts an Agent.
31
+ Each endpoint states its activation policy. List reads only stored headers and projection-cache rows: it never calls per-session stat or opens a cold Session body. A current-format cache identity may supply every list hint; a lifecycle-matching predecessor cache may supply only its version-compatible title as a stale display fact, never as an authoritative fold seed. Search, attachment, history pages, log following, skill discovery, and workspace-path opening can inspect persistence without activating an Agent; `canOpenWorkspacePath()` reports native-opening availability without addressing a Session. Queue mutation and cancellation require live state; model, rename, prompt, and file-reference operations may resolve or resume an ordinary Session. Prompt rejects content with neither non-whitespace text nor an attachment before resolving the Agent or appending Session events; queue edits accept only non-empty text content. Prompt admission consumes opaque receipts from the injected [`fileUploads`](../../client/file-upload/README.md) Host service and resolves every same-Agent receipt before sending the complete ordered content list through `ctx.attachments`. Prompt retries whose `requestId` is already queued or logged return the original acceptance without inserting another message. Create and fork are the only operations that create a new Agent directly. The service applies one preset-aware resume policy and subagent ownership fence to its own methods and to the Typert Agent and Session lookups used by other Remote namespaces. Queue mutation has one narrow exception: a live child whose current projected identity is continuable and comes from its own non-seed suffix accepts the ordinary Edit, Remove, and QueueDock Steer actions across both inbox destinations. One-shot, missing, unknown, corrupt, seed-only, or cold children remain rejected without resume. The skill catalog uses a live Agent when present or the recorded preset's standing scope when cold, so listing never starts an Agent. The authenticated delivery routes use `workspaceDesktop()` for the serving Host name and file-manager behavior. `openWorkspacePath({ path, action: "reveal" })` delegates file-manager navigation to the native adapter; omitting `action` opens the default application.
32
32
 
33
33
  The Client adapter exposes `SessionEventStream`, a Gateway `RemoteJournalStream` bound to one ordinary or direct-subagent address. It opens follow before the initial page, publishes only contiguous `replace`, `prepend`, `append`, and `settle-assistant` changes, and repairs reconnect or sequence gaps through a tail page. Backwards paging has two verbs: `loadOlder()` pulls one 50-message page, and `loadThrough(seq)` — the turn-jump loader — loops 200-message pages until the window covers the target seq, lowering a shared target on repeated calls, stopping on a page that makes no progress, and reporting busy through the same `loadingOlder` snapshot bit. The Web adapter explicitly opts into cursorless Assistant frames: each opening carries the active attempt's `startedAfterSeq`, `nextIndex`, and compact stream, and every stream member becomes a Client-only `assistant/live-chunk` entry ordered between durable cursors. The Host captures a follower-local arrival ordinal with that baseline and suppresses buffered frames at or before the cut; a replacement Agent may restart frame revision at one. A durable `assistant/message` or `assistant/attempt` arriving after an active opening stays staged only when its seq follows `startedAfterSeq` and its Turn and Step match; the matching end type, seq, and index publishes one named settlement delta that retires the attempt's transient rows and adds the durable entry while earlier same-step retries remain visible. Revision, dense-index, or settlement gaps for a known attempt reopen follow, while a controller that missed the start ignores unknown-attempt frames and publishes their durable settlement normally. An abandoned end publishes a settlement delta without a durable entry so its transient rows retire immediately. A durable gap-repair page has no Assistant baseline, so its held notification reopens follow once for a paired page and baseline. Every history record covers exactly its event seq. A business, persistence, or unresolved continuity failure terminates the stream, while only physical carrier loss selects automatic resumption. `SessionControlStream` is a Gateway `RemoteSnapshotStream`; every generation opens with a complete process-local baseline, so reconnect replaces queue, jobs, and projection state instead of treating transient values as durable events. For each inbox change, the Host publishes the projection frame first and derives the queue replacement from that same validated post-fold value, so listener registration order cannot produce a stale queue frame.Client Agent contexts provide the identity used by the independent [`fileUpload`](../../client/file-upload/README.md) service; Session objects expose lifecycle, prompt, queue, and history operations rather than file transfer.
34
34
 
package/README.zh.md CHANGED
@@ -28,7 +28,7 @@ kind: "package-reference"
28
28
 
29
29
  Client journal 在发布 follow snapshot、live entry 或历史页之前验证精确的 V3 event envelope。它复用浏览器安全的 Session validator,检查必需的 surface marker、精确的 replacement endpoint、更早且唯一的 source seq、内嵌 Assistant 来源、request header 可选字段的省略规则以及 tool error 一致性。无效 record 直接失败,不删除字段或归一化;范围成员与来源存在性仍由 Host 的持久日志检查。
30
30
 
31
- 每个 endpoint 都声明自己的激活策略。列表只读取持久化 header 与 projection cache row,绝不调用逐 Session stat 或打开冷 Session body。当前格式 cache identity 可以提供全部列表 hint;生命周期匹配的 predecessor cache 只能提供版本兼容的 title,作为可能过时的展示事实,绝不能作为权威 fold seed。搜索、附件、历史页、日志跟随、skill 发现和工作区路径打开可以在不激活 Agent 的情况下检查 persistence;`canOpenWorkspacePath()` 无需指定 Session 即可报告原生打开能力。queue 变更与取消要求 live 状态;模型、重命名、prompt 和文件引用操作可以解析或恢复普通 Session。prompt 会在解析 Agent 或追加 Session event 前,拒绝既没有非空白文本也没有附件的 content;queue edit 只接受非空文本 content。prompt 准入从注入的 [`fileUploads`](../../client/file-upload/README.zh.md) Host 服务取得不透明凭证,在把完整有序内容列表交给 `ctx.attachments` 前解析每个属于同一 Agent 的凭证。`requestId` 已进入 queue 或日志时,prompt 重试直接返回原来的接受结果,不会重复插入消息。只有 create 与 fork 会直接创建新 Agent。该服务把同一套感知 preset 的恢复策略和 subagent ownership fence 同时用于自身方法,以及其他 Remote namespace 使用的 Typert Agent 与 Session lookup。Queue 变更只有一个狭窄例外:当前 projection identity 为 continuable 且来自自身非 seed suffix 的在线 child,可以在两个 inbox 目标上使用普通 Edit、Remove 与 QueueDock Steer action。One-shot、缺失、未知、损坏、仅含 seed identity 或冷 child 继续被拒绝,且不会恢复。skill 目录优先使用已有 live Agent,否则使用所记录 preset 的常驻 scope,因此列表查询绝不会启动 Agent。
31
+ 每个 endpoint 都声明自己的激活策略。列表只读取持久化 header 与 projection cache row,绝不调用逐 Session stat 或打开冷 Session body。当前格式 cache identity 可以提供全部列表 hint;生命周期匹配的 predecessor cache 只能提供版本兼容的 title,作为可能过时的展示事实,绝不能作为权威 fold seed。搜索、附件、历史页、日志跟随、skill 发现和工作区路径打开可以在不激活 Agent 的情况下检查 persistence;`canOpenWorkspacePath()` 无需指定 Session 即可报告原生打开能力。queue 变更与取消要求 live 状态;模型、重命名、prompt 和文件引用操作可以解析或恢复普通 Session。prompt 会在解析 Agent 或追加 Session event 前,拒绝既没有非空白文本也没有附件的 content;queue edit 只接受非空文本 content。prompt 准入从注入的 [`fileUploads`](../../client/file-upload/README.zh.md) Host 服务取得不透明凭证,在把完整有序内容列表交给 `ctx.attachments` 前解析每个属于同一 Agent 的凭证。`requestId` 已进入 queue 或日志时,prompt 重试直接返回原来的接受结果,不会重复插入消息。只有 create 与 fork 会直接创建新 Agent。该服务把同一套感知 preset 的恢复策略和 subagent ownership fence 同时用于自身方法,以及其他 Remote namespace 使用的 Typert Agent 与 Session lookup。Queue 变更只有一个狭窄例外:当前 projection identity 为 continuable 且来自自身非 seed suffix 的在线 child,可以在两个 inbox 目标上使用普通 Edit、Remove 与 QueueDock Steer action。One-shot、缺失、未知、损坏、仅含 seed identity 或冷 child 继续被拒绝,且不会恢复。skill 目录优先使用已有 live Agent,否则使用所记录 preset 的常驻 scope,因此列表查询绝不会启动 Agent。 经过认证的文件交付路由通过 `workspaceDesktop()` 获取提供服务的 Host 名称和文件管理器行为。`openWorkspacePath({ path, action: "reveal" })` 将文件管理器导航委托给原生适配器;省略 `action` 时打开默认应用。
32
32
 
33
33
  Client adapter 提供 `SessionEventStream`,即绑定到一个普通 Session 或 direct subagent address 的 Gateway `RemoteJournalStream`。它在读取首个 page 前打开 follow,只发布连续的 `replace`、`prepend`、`append` 与 `settle-assistant` 变更,并通过 tail page 修复重连或 seq 缺口。向后分页有两个动词:`loadOlder()` 拉一页 50 条 message,而 `loadThrough(seq)`——轮次跳转加载器——按 200 条 message 一页循环拉取直到窗口覆盖目标 seq,重复调用会下调共享目标,遇到无进展的页即停止,忙碌状态复用同一个 `loadingOlder` 快照位。Web adapter 显式选择接收无 cursor 的 Assistant frame:每个 opening 携带活跃 attempt 的 `startedAfterSeq`、`nextIndex` 与紧凑 stream,每个 stream member 都成为排在持久 cursor 之间的 Client-only `assistant/live-chunk` 条目。Host 会随该 baseline 捕获 follower 本地到达序号,并抑制该 cut 及之前的 buffered frame;replacement Agent 可以从 revision 一重新开始。活跃 opening 之后到达的持久 `assistant/message` 或 `assistant/attempt` 只有在其 seq 晚于 `startedAfterSeq` 且 Turn 与 Step 匹配时才会保持暂存;匹配的 end type、seq 与 index 会发布一个具名 settlement delta,删除该 attempt 的瞬态 row、加入持久条目,并保留同一步骤中更早的 retry。已知 attempt 的 revision、密集 index 或 settlement 缺口会重新打开 follow;若 controller 错过 start,则忽略 unknown-attempt frame,并正常发布其持久 settlement。Abandoned end 会发布不含持久条目的 settlement delta,使瞬态 row 立即退出。持久缺口修复 page 不携带 Assistant baseline,因此 held notification 会重新打开 follow 一次,以取得配对的 page 与 baseline。每条历史 record 只覆盖自身的 event seq。业务、persistence 或无法恢复的连续性错误会终止 stream,只有物理载体断开才触发自动恢复。`SessionControlStream` 是 Gateway `RemoteSnapshotStream`;每代都以完整的进程本地 baseline 开始,因此重连会替换 queue、jobs 和 projection 状态,而不会把瞬态值当作 durable event。每次 inbox 变更时,Host 会先发布 projection frame,再从同一份已校验的折叠后值派生 queue replacement,因此监听器注册顺序不会产生陈旧的 queue frame。Client Agent context 提供独立 [`fileUpload`](../../client/file-upload/README.zh.md) 服务使用的身份;Session 对象提供生命周期、prompt、queue 与历史操作,不提供文件传输。
34
34
 
package/lib/client.js CHANGED
@@ -127,6 +127,7 @@ window.__ModuleLoader__.load({
127
127
  "compaction/prune",
128
128
  "compaction/start",
129
129
  "compaction/summary",
130
+ "deliverables/presented",
130
131
  "feedback/message-delete",
131
132
  "feedback/message-put",
132
133
  "feedback/record",
@@ -148,6 +149,7 @@ window.__ModuleLoader__.load({
148
149
  "session/title-llm-request",
149
150
  "step/end",
150
151
  "step/start",
152
+ "subagent/catalog",
151
153
  "subagent/descriptor",
152
154
  "subagent/model-selection-policy",
153
155
  "system/message",
package/lib/index.js CHANGED
@@ -1,6 +1,7 @@
1
+ import { hostname } from "node:os";
1
2
  import z from "@deepseek-ai/schemastery";
2
3
  import { AssistantStreamAccumulator, ReasoningEffortId, assistantStreamChunks, createUserMessage, errorChain, freezeMessage } from "@deepseek-ai/dsh-llm";
3
- import { canOpenNativePath, openNativePath } from "@deepseek-ai/dsh-native-command";
4
+ import { canOpenNativePath, nativeFileManager, openNativePath, revealNativePath } from "@deepseek-ai/dsh-native-command";
4
5
  import { Remote, RemoteError, TypertRemoteService, remoteErrorOf } from "@deepseek-ai/dsh-typert-protocol";
5
6
  import { mkdir } from "node:fs/promises";
6
7
  import { installModelSelection } from "@deepseek-ai/dsh-agent";
@@ -2713,6 +2714,7 @@ let SessionController = (() => {
2713
2714
  history;
2714
2715
  listState;
2715
2716
  openPath;
2717
+ revealPath;
2716
2718
  canOpenPath;
2717
2719
  promotions = /* @__PURE__ */ new Set();
2718
2720
  /**
@@ -2739,6 +2741,7 @@ let SessionController = (() => {
2739
2741
  });
2740
2742
  this.listState = new ApiSessionList(ctx);
2741
2743
  this.openPath = internals.openPath ?? openNativePath;
2744
+ this.revealPath = internals.revealPath ?? revealNativePath;
2742
2745
  this.canOpenPath = internals.canOpenPath ?? (() => config.nativeOpen ?? (internals.openPath !== void 0 || canOpenNativePath()));
2743
2746
  ctx.plugin(SessionFileReferences);
2744
2747
  ctx.plugin(SessionMediaReferences);
@@ -2862,6 +2865,18 @@ let SessionController = (() => {
2862
2865
  return this.canOpenPath();
2863
2866
  }
2864
2867
  /**
2868
+ * Describe the serving desktop for authenticated file-action routes.
2869
+ * @returns Host name, configured availability, and platform-specific file-manager behavior.
2870
+ */
2871
+ workspaceDesktop() {
2872
+ const fileManager = nativeFileManager();
2873
+ return {
2874
+ name: hostname(),
2875
+ available: fileManager !== null && this.canOpenPath(),
2876
+ fileManager
2877
+ };
2878
+ }
2879
+ /**
2865
2880
  * Open one path prepared by a Session-aware caller on the Host desktop.
2866
2881
  * @param request - path after best-effort Session workspace resolution.
2867
2882
  * @param signal - caller lifetime; abort terminates the native command.
@@ -2872,7 +2887,8 @@ let SessionController = (() => {
2872
2887
  if (request.path.length === 0) throw new RemoteError("gateway/bad-request", "session.openWorkspacePath requires a non-empty path", {});
2873
2888
  signal.throwIfAborted();
2874
2889
  try {
2875
- await this.openPath(request.path, signal);
2890
+ if (request.action === "reveal") await this.revealPath(request.path, signal);
2891
+ else await this.openPath(request.path, signal);
2876
2892
  return { opened: true };
2877
2893
  } catch (error) {
2878
2894
  if (signal.aborted) throw new RemoteError("gateway/cancelled", "path open was aborted", {});
@@ -133,6 +133,19 @@ const _deepseek_ai_dsh_api_session_controller_session_control_result$schema = z.
133
133
  'reasoningEffort': z.string().readonly().optional(),
134
134
  })]).readonly(),
135
135
  }).optional(),
136
+ 'subagentCatalog': z.array(z.union([z.intersection(z.object({
137
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
138
+ 'createdAt': z.number().readonly(),
139
+ }), z.object({
140
+ 'mode': z.literal("one-shot").readonly(),
141
+ 'label': z.string().readonly().optional(),
142
+ })), z.intersection(z.object({
143
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
144
+ 'createdAt': z.number().readonly(),
145
+ }), z.object({
146
+ 'mode': z.literal("continuable").readonly(),
147
+ 'label': z.string().readonly(),
148
+ }))])).optional(),
136
149
  'subagentTiming': z.object({
137
150
  'settledMs': z.number(),
138
151
  'active': z.object({
@@ -298,6 +311,19 @@ const _deepseek_ai_dsh_api_session_controller_session_follow_result$schema = z.u
298
311
  'reasoningEffort': z.string().readonly().optional(),
299
312
  })]).readonly(),
300
313
  }).optional(),
314
+ 'subagentCatalog': z.array(z.union([z.intersection(z.object({
315
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
316
+ 'createdAt': z.number().readonly(),
317
+ }), z.object({
318
+ 'mode': z.literal("one-shot").readonly(),
319
+ 'label': z.string().readonly().optional(),
320
+ })), z.intersection(z.object({
321
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
322
+ 'createdAt': z.number().readonly(),
323
+ }), z.object({
324
+ 'mode': z.literal("continuable").readonly(),
325
+ 'label': z.string().readonly(),
326
+ }))])).optional(),
301
327
  'subagentTiming': z.object({
302
328
  'settledMs': z.number(),
303
329
  'active': z.object({
@@ -429,6 +455,19 @@ const _deepseek_ai_dsh_api_session_controller_session_list_result$schema = z.obj
429
455
  'reasoningEffort': z.string().readonly().optional(),
430
456
  })]).readonly(),
431
457
  }).optional(),
458
+ 'subagentCatalog': z.array(z.union([z.intersection(z.object({
459
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
460
+ 'createdAt': z.number().readonly(),
461
+ }), z.object({
462
+ 'mode': z.literal("one-shot").readonly(),
463
+ 'label': z.string().readonly().optional(),
464
+ })), z.intersection(z.object({
465
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
466
+ 'createdAt': z.number().readonly(),
467
+ }), z.object({
468
+ 'mode': z.literal("continuable").readonly(),
469
+ 'label': z.string().readonly(),
470
+ }))])).optional(),
432
471
  'subagentTiming': z.object({
433
472
  'settledMs': z.number(),
434
473
  'active': z.object({
@@ -496,6 +535,7 @@ const _deepseek_ai_dsh_api_session_controller_session_modelCatalog_result$schema
496
535
  })).readonly(),
497
536
  })
498
537
  const _deepseek_ai_dsh_api_session_controller_session_openWorkspacePath_parameter_0$schema = z.object({
538
+ 'action': z.literal("reveal").readonly().optional(),
499
539
  'path': z.string().readonly(),
500
540
  })
501
541
  const _deepseek_ai_dsh_api_session_controller_session_openWorkspacePath_result$schema = z.object({
@@ -716,7 +756,7 @@ export const TYPERT = {
716
756
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionAttachmentValue',
717
757
  schema: _deepseek_ai_dsh_api_session_controller_session_attachment_result$schema,
718
758
  },
719
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":342,"column":3},
759
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":357,"column":3},
720
760
  },
721
761
  {
722
762
  id: '@deepseek-ai/dsh-api-session-controller#session/cancel',
@@ -741,7 +781,7 @@ export const TYPERT = {
741
781
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionCancelValue',
742
782
  schema: _deepseek_ai_dsh_api_session_controller_session_cancel_result$schema,
743
783
  },
744
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":362,"column":3},
784
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":377,"column":3},
745
785
  },
746
786
  {
747
787
  id: '@deepseek-ai/dsh-api-session-controller#session/canOpenWorkspacePath',
@@ -756,7 +796,7 @@ export const TYPERT = {
756
796
  typeSymbol: '@deepseek-ai/dsh-api-session-controller#session/canOpenWorkspacePath:result',
757
797
  schema: _deepseek_ai_dsh_api_session_controller_session_canOpenWorkspacePath_result$schema,
758
798
  },
759
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":267,"column":3},
799
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":272,"column":3},
760
800
  },
761
801
  {
762
802
  id: '@deepseek-ai/dsh-api-session-controller#session/control',
@@ -773,7 +813,7 @@ export const TYPERT = {
773
813
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionControlFrame',
774
814
  schema: _deepseek_ai_dsh_api_session_controller_session_control_result$schema,
775
815
  },
776
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":395,"column":3},
816
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":410,"column":3},
777
817
  },
778
818
  {
779
819
  id: '@deepseek-ai/dsh-api-session-controller#session/create',
@@ -798,7 +838,7 @@ export const TYPERT = {
798
838
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionCreateValue',
799
839
  schema: _deepseek_ai_dsh_api_session_controller_session_create_result$schema,
800
840
  },
801
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":239,"column":3},
841
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":244,"column":3},
802
842
  },
803
843
  {
804
844
  id: '@deepseek-ai/dsh-api-session-controller#session/follow',
@@ -825,7 +865,7 @@ export const TYPERT = {
825
865
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionFollowFrame',
826
866
  schema: _deepseek_ai_dsh_api_session_controller_session_follow_result$schema,
827
867
  },
828
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":385,"column":3},
868
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":400,"column":3},
829
869
  },
830
870
  {
831
871
  id: '@deepseek-ai/dsh-api-session-controller#session/fork',
@@ -850,7 +890,7 @@ export const TYPERT = {
850
890
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionForkValue',
851
891
  schema: _deepseek_ai_dsh_api_session_controller_session_fork_result$schema,
852
892
  },
853
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":320,"column":3},
893
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":335,"column":3},
854
894
  },
855
895
  {
856
896
  id: '@deepseek-ai/dsh-api-session-controller#session/list',
@@ -876,7 +916,7 @@ export const TYPERT = {
876
916
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionListValue',
877
917
  schema: _deepseek_ai_dsh_api_session_controller_session_list_result$schema,
878
918
  },
879
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":218,"column":9},
919
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":223,"column":9},
880
920
  },
881
921
  {
882
922
  id: '@deepseek-ai/dsh-api-session-controller#session/modelCatalog',
@@ -891,7 +931,7 @@ export const TYPERT = {
891
931
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#ModelCatalog',
892
932
  schema: _deepseek_ai_dsh_api_session_controller_session_modelCatalog_result$schema,
893
933
  },
894
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":258,"column":3},
934
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":263,"column":3},
895
935
  },
896
936
  {
897
937
  id: '@deepseek-ai/dsh-api-session-controller#session/openWorkspacePath',
@@ -917,7 +957,7 @@ export const TYPERT = {
917
957
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionOpenWorkspacePathValue',
918
958
  schema: _deepseek_ai_dsh_api_session_controller_session_openWorkspacePath_result$schema,
919
959
  },
920
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":279,"column":9},
960
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":293,"column":9},
921
961
  },
922
962
  {
923
963
  id: '@deepseek-ai/dsh-api-session-controller#session/page',
@@ -943,7 +983,7 @@ export const TYPERT = {
943
983
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionPage',
944
984
  schema: _deepseek_ai_dsh_api_session_controller_session_page_result$schema,
945
985
  },
946
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":373,"column":3},
986
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":388,"column":3},
947
987
  },
948
988
  {
949
989
  id: '@deepseek-ai/dsh-api-session-controller#session/prompt',
@@ -969,7 +1009,7 @@ export const TYPERT = {
969
1009
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionPromptValue',
970
1010
  schema: _deepseek_ai_dsh_api_session_controller_session_prompt_result$schema,
971
1011
  },
972
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":331,"column":3},
1012
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":346,"column":3},
973
1013
  },
974
1014
  {
975
1015
  id: '@deepseek-ai/dsh-api-session-controller#session/rename',
@@ -994,7 +1034,7 @@ export const TYPERT = {
994
1034
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionRenameValue',
995
1035
  schema: _deepseek_ai_dsh_api_session_controller_session_rename_result$schema,
996
1036
  },
997
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":310,"column":3},
1037
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":325,"column":3},
998
1038
  },
999
1039
  {
1000
1040
  id: '@deepseek-ai/dsh-api-session-controller#session/search',
@@ -1020,7 +1060,7 @@ export const TYPERT = {
1020
1060
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionSearchValue',
1021
1061
  schema: _deepseek_ai_dsh_api_session_controller_session_search_result$schema,
1022
1062
  },
1023
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":229,"column":3},
1063
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":234,"column":3},
1024
1064
  },
1025
1065
  {
1026
1066
  id: '@deepseek-ai/dsh-api-session-controller#session/selectModel',
@@ -1045,7 +1085,7 @@ export const TYPERT = {
1045
1085
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionSelectModelValue',
1046
1086
  schema: _deepseek_ai_dsh_api_session_controller_session_selectModel_result$schema,
1047
1087
  },
1048
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":249,"column":3},
1088
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":254,"column":3},
1049
1089
  },
1050
1090
  {
1051
1091
  id: '@deepseek-ai/dsh-api-session-controller#session/updateQueue',
@@ -1070,7 +1110,7 @@ export const TYPERT = {
1070
1110
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionUpdateQueueValue',
1071
1111
  schema: _deepseek_ai_dsh_api_session_controller_session_updateQueue_result$schema,
1072
1112
  },
1073
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":352,"column":3},
1113
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":367,"column":3},
1074
1114
  },
1075
1115
  {
1076
1116
  id: '@deepseek-ai/dsh-api-session-controller#skills/list',
@@ -1165,6 +1205,13 @@ export const TYPERT = {
1165
1205
  "summary": "Report whether this deployment can hand a Session workspace path to a native desktop.",
1166
1206
  "jsDoc": "/**\n * Report whether this deployment can hand a Session workspace path to a native desktop.\n * @returns true when the matching open operation is available.\n */"
1167
1207
  },
1208
+ {
1209
+ "kind": "method",
1210
+ "name": "workspaceDesktop",
1211
+ "signature": "workspaceDesktop(): { name: string; available: boolean; fileManager: 'finder' | 'explorer' | 'directory' | null }",
1212
+ "summary": "Describe the serving desktop for authenticated file-action routes.",
1213
+ "jsDoc": "/**\n * Describe the serving desktop for authenticated file-action routes.\n * @returns Host name, configured availability, and platform-specific file-manager behavior.\n */"
1214
+ },
1168
1215
  {
1169
1216
  "kind": "method",
1170
1217
  "name": "openWorkspacePath",
@@ -1349,6 +1396,14 @@ export const TYPERT = {
1349
1396
  "name": "EpochHeader",
1350
1397
  "declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n tools?: ToolSchema[];\n}"
1351
1398
  },
1399
+ {
1400
+ "name": "FeedbackCategory",
1401
+ "declaration": "export type FeedbackCategory = 'task-result' | 'instruction-following' | 'product-interaction' | 'service-stability' | 'resource-cost' | 'security-privacy-permission' | 'other';"
1402
+ },
1403
+ {
1404
+ "name": "FeedbackRecord",
1405
+ "declaration": "export interface FeedbackRecord {\n readonly text?: string;\n readonly category?: FeedbackCategory;\n}"
1406
+ },
1352
1407
  {
1353
1408
  "name": "FileAttachmentRef",
1354
1409
  "declaration": "export interface FileAttachmentRef {\n attachmentId: AttachmentId;\n name: string;\n bytes: number;\n}"
@@ -1471,7 +1526,7 @@ export const TYPERT = {
1471
1526
  },
1472
1527
  {
1473
1528
  "name": "MessageFeedbackItem",
1474
- "declaration": "export interface MessageFeedbackItem {\n readonly messageId: MessageId;\n readonly rating: MessageFeedbackRating;\n readonly note?: string;\n readonly version: MessageFeedbackVersion;\n readonly createdAt: number;\n readonly updatedAt: number;\n}"
1529
+ "declaration": "export interface MessageFeedbackItem {\n readonly messageId: MessageId;\n readonly rating: MessageFeedbackRating;\n readonly note?: string;\n readonly category?: FeedbackCategory;\n readonly version: MessageFeedbackVersion;\n readonly createdAt: number;\n readonly updatedAt: number;\n}"
1475
1530
  },
1476
1531
  {
1477
1532
  "name": "MessageFeedbackPut",
@@ -1659,7 +1714,7 @@ export const TYPERT = {
1659
1714
  },
1660
1715
  {
1661
1716
  "name": "SessionEventMap",
1662
- "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
1717
+ "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'subagent/catalog': SubagentCatalogEvent;\n 'feedback/record': FeedbackRecord;\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
1663
1718
  },
1664
1719
  {
1665
1720
  "name": "SessionEventType",
@@ -1719,7 +1774,7 @@ export const TYPERT = {
1719
1774
  },
1720
1775
  {
1721
1776
  "name": "SessionOpenWorkspacePathRequest",
1722
- "declaration": "export interface SessionOpenWorkspacePathRequest {\n readonly path: string;\n}"
1777
+ "declaration": "export interface SessionOpenWorkspacePathRequest {\n readonly action?: 'reveal';\n readonly path: string;\n}"
1723
1778
  },
1724
1779
  {
1725
1780
  "name": "SessionOpenWorkspacePathValue",
@@ -1743,7 +1798,7 @@ export const TYPERT = {
1743
1798
  },
1744
1799
  {
1745
1800
  "name": "SessionProjectionMap",
1746
- "declaration": "export interface SessionProjectionMap {\n inbox: InboxWireState;\n agentPreset: string | null;\n title: string | null;\n todos: TodoItem[] | null;\n sessionListMetadata: SessionListMetadata;\n imageLimits: ImageAttachmentLimits;\n modelSelection: ModelSelectionProjection;\n subagentTiming: SubagentTimingProjection;\n subagent: SubagentIdentityProjection | null;\n goal: GoalProjection | null;\n}"
1801
+ "declaration": "export interface SessionProjectionMap {\n inbox: InboxWireState;\n agentPreset: string | null;\n title: string | null;\n todos: TodoItem[] | null;\n sessionListMetadata: SessionListMetadata;\n imageLimits: ImageAttachmentLimits;\n modelSelection: ModelSelectionProjection;\n subagentCatalog: SubagentCatalogEntry[];\n subagentTiming: SubagentTimingProjection;\n subagent: SubagentIdentityProjection | null;\n goal: GoalProjection | null;\n}"
1747
1802
  },
1748
1803
  {
1749
1804
  "name": "SessionProjectionUpdate",
@@ -1865,6 +1920,14 @@ export const TYPERT = {
1865
1920
  "name": "StreamChunk",
1866
1921
  "declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id: ToolCallId; name?: string; argumentsDelta: string; } | { type: 'block-end'; index: number; block: ContentBlock; } | { type: 'usage'; usage: TokenUsage; } | { type: 'finish'; reason: FinishReason; replayState?: ReplayEnvelope; };"
1867
1922
  },
1923
+ {
1924
+ "name": "SubagentCatalogEntry",
1925
+ "declaration": "export type SubagentCatalogEntry = { readonly id: SessionId; readonly createdAt: number; } & ({ readonly mode: 'one-shot'; readonly label?: string; } | { readonly mode: 'continuable'; readonly label: string; });"
1926
+ },
1927
+ {
1928
+ "name": "SubagentCatalogEvent",
1929
+ "declaration": "export type SubagentCatalogEvent = { readonly version: 0; readonly childId: SessionId; readonly childCreatedAt: number; } & ({ readonly mode: 'one-shot'; readonly label?: string; } | { readonly mode: 'continuable'; readonly label: string; });"
1930
+ },
1868
1931
  {
1869
1932
  "name": "SubagentDescriptorBase",
1870
1933
  "declaration": "export interface SubagentDescriptorBase {\n readonly version: number;\n readonly mode: 'one-shot' | 'continuable';\n readonly provider: string;\n}"
@@ -2124,6 +2187,14 @@ export const TYPERT = {
2124
2187
  "name": "EpochHeader",
2125
2188
  "declaration": "export interface EpochHeader {\n config: LlmCallConfig;\n adapterDefaults?: LlmCallConfigAdapterDefaults;\n tools?: ToolSchema[];\n}"
2126
2189
  },
2190
+ {
2191
+ "name": "FeedbackCategory",
2192
+ "declaration": "export type FeedbackCategory = 'task-result' | 'instruction-following' | 'product-interaction' | 'service-stability' | 'resource-cost' | 'security-privacy-permission' | 'other';"
2193
+ },
2194
+ {
2195
+ "name": "FeedbackRecord",
2196
+ "declaration": "export interface FeedbackRecord {\n readonly text?: string;\n readonly category?: FeedbackCategory;\n}"
2197
+ },
2127
2198
  {
2128
2199
  "name": "FileAttachmentRef",
2129
2200
  "declaration": "export interface FileAttachmentRef {\n attachmentId: AttachmentId;\n name: string;\n bytes: number;\n}"
@@ -2230,7 +2301,7 @@ export const TYPERT = {
2230
2301
  },
2231
2302
  {
2232
2303
  "name": "MessageFeedbackItem",
2233
- "declaration": "export interface MessageFeedbackItem {\n readonly messageId: MessageId;\n readonly rating: MessageFeedbackRating;\n readonly note?: string;\n readonly version: MessageFeedbackVersion;\n readonly createdAt: number;\n readonly updatedAt: number;\n}"
2304
+ "declaration": "export interface MessageFeedbackItem {\n readonly messageId: MessageId;\n readonly rating: MessageFeedbackRating;\n readonly note?: string;\n readonly category?: FeedbackCategory;\n readonly version: MessageFeedbackVersion;\n readonly createdAt: number;\n readonly updatedAt: number;\n}"
2234
2305
  },
2235
2306
  {
2236
2307
  "name": "MessageFeedbackPut",
@@ -2318,7 +2389,7 @@ export const TYPERT = {
2318
2389
  },
2319
2390
  {
2320
2391
  "name": "SessionEventMap",
2321
- "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
2392
+ "declaration": "export interface SessionEventMap {\n 'turn/start': { turn: number; };\n 'turn/end': { turn: number; reason: TurnEndReason; };\n 'step/start': { turn: number; step: number; };\n 'step/end': { turn: number; step: number; };\n 'user/message': UserMessage;\n 'system/message': { turn: number; step: number; message: SystemMessage; };\n 'assistant/message': { turn: number; step: number; message: AssistantMessage; stream: AssistantStreamRecord[]; usage?: TokenUsage; interrupted?: true; };\n 'assistant/attempt': { turn: number; step: number; stream: AssistantStreamRecord[]; };\n 'tool/call': { turn: number; step: number; callId: ToolCallId; name: string; arguments: string; };\n 'tool/result': { turn: number; step: number; message: ToolResultMessage; error?: { name: string; code: string; }; meta?: JsonValue; };\n 'request/header': { header: EpochHeader; reason: RequestHeaderReason; startsSeries?: true; };\n 'request/context': RequestContext;\n 'session/end-seed': { inherited?: true; };\n 'agent/inbox/spliced': { target: InboxTarget; start: number; removedCount?: number; inserted: UserMessage[]; outcome?: 'canceled'; };\n 'approval/asked': { id: ApprovalRequestId; toolName: string; callId?: ToolCallId; reason?: string; };\n 'approval/decided': { id: ApprovalRequestId; outcome: ApprovalOutcome; };\n 'approval/policy': { policy: ApprovalPolicy; source?: 'delegation'; };\n 'tool/ptc-dispatch-start': PtcDispatchStartEventData;\n 'tool/ptc-dispatch': PtcDispatchEventData;\n 'agent-preset/selected': { agentPreset: string; };\n 'command/run': { commandId: CommandId; name: string; args?: string; source: CommandSource; };\n 'command/done': { commandId: CommandId; kind: 'success' | 'error'; text?: string; sourceEventSeq?: import('@deepseek-ai/dsh-session/types').SessionSeq; };\n 'session/title': SessionTitleEventData;\n 'todo/write': { todos: TodoItem[]; };\n 'model/selection': ModelSelection;\n 'subagent/descriptor': SubagentDescriptorData;\n 'sandbox/mode': { mode: SandboxMode; source?: 'delegation'; };\n 'subagent/catalog': SubagentCatalogEvent;\n 'feedback/record': FeedbackRecord;\n 'team/member': { version: 2; teamId: TeamId; member: TeamMemberSnapshot; };\n 'team/task': { version: 2; teamId: TeamId; task: TeamTaskSnapshot; };\n 'team/message/queued': { version: 2; teamId: TeamId; message: TeamMessageSnapshot; };\n 'team/message/delivered': { version: 2; teamId: TeamId; messageId: TeamMessageId; targetId: SessionId; };\n 'goal/change': GoalChangeMeta;\n 'feedback/message-put': MessageFeedbackPut;\n 'feedback/message-delete': MessageFeedbackDelete;\n 'compaction/start': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; };\n 'compaction/summary': { compactionId: CompactionId; sourceCommandId?: CommandId; summary: ContentBlock[]; shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; provider: string; model: string; maxTokens?: number; usage?: TokenUsage; } & ({ rawOutput: ContentBlock[]; llmStreamCall: true; } | { rawOutput?: ContentBlock[]; llmStreamCall?: never; });\n 'compaction/end': { compactionId: CompactionId; sourceCommandId?: CommandId; turn: number | null; error?: string; };\n 'compaction/prune': { shadowedRange: { start: SessionSeq; end: SessionSeq; }; shadowedSeqs: SessionSeq[]; shadowedTokenCount: number; };\n}"
2322
2393
  },
2323
2394
  {
2324
2395
  "name": "SessionEventType",
@@ -2376,6 +2447,10 @@ export const TYPERT = {
2376
2447
  "name": "StreamChunk",
2377
2448
  "declaration": "export type StreamChunk = { type: 'block-start'; index: number; blockType: ContentBlockType; } | { type: 'text-delta'; index: number; text: string; } | { type: 'reasoning-delta'; index: number; text: string; } | { type: 'tool-call-delta'; index: number; id: ToolCallId; name?: string; argumentsDelta: string; } | { type: 'block-end'; index: number; block: ContentBlock; } | { type: 'usage'; usage: TokenUsage; } | { type: 'finish'; reason: FinishReason; replayState?: ReplayEnvelope; };"
2378
2449
  },
2450
+ {
2451
+ "name": "SubagentCatalogEvent",
2452
+ "declaration": "export type SubagentCatalogEvent = { readonly version: 0; readonly childId: SessionId; readonly childCreatedAt: number; } & ({ readonly mode: 'one-shot'; readonly label?: string; } | { readonly mode: 'continuable'; readonly label: string; });"
2453
+ },
2379
2454
  {
2380
2455
  "name": "SubagentDescriptorBase",
2381
2456
  "declaration": "export interface SubagentDescriptorBase {\n readonly version: number;\n readonly mode: 'one-shot' | 'continuable';\n readonly provider: string;\n}"
@@ -133,6 +133,19 @@ const _deepseek_ai_dsh_api_session_controller_session_control_result$schema = z.
133
133
  'reasoningEffort': z.string().readonly().optional(),
134
134
  })]).readonly(),
135
135
  }).optional(),
136
+ 'subagentCatalog': z.array(z.union([z.intersection(z.object({
137
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
138
+ 'createdAt': z.number().readonly(),
139
+ }), z.object({
140
+ 'mode': z.literal("one-shot").readonly(),
141
+ 'label': z.string().readonly().optional(),
142
+ })), z.intersection(z.object({
143
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
144
+ 'createdAt': z.number().readonly(),
145
+ }), z.object({
146
+ 'mode': z.literal("continuable").readonly(),
147
+ 'label': z.string().readonly(),
148
+ }))])).optional(),
136
149
  'subagentTiming': z.object({
137
150
  'settledMs': z.number(),
138
151
  'active': z.object({
@@ -298,6 +311,19 @@ const _deepseek_ai_dsh_api_session_controller_session_follow_result$schema = z.u
298
311
  'reasoningEffort': z.string().readonly().optional(),
299
312
  })]).readonly(),
300
313
  }).optional(),
314
+ 'subagentCatalog': z.array(z.union([z.intersection(z.object({
315
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
316
+ 'createdAt': z.number().readonly(),
317
+ }), z.object({
318
+ 'mode': z.literal("one-shot").readonly(),
319
+ 'label': z.string().readonly().optional(),
320
+ })), z.intersection(z.object({
321
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
322
+ 'createdAt': z.number().readonly(),
323
+ }), z.object({
324
+ 'mode': z.literal("continuable").readonly(),
325
+ 'label': z.string().readonly(),
326
+ }))])).optional(),
301
327
  'subagentTiming': z.object({
302
328
  'settledMs': z.number(),
303
329
  'active': z.object({
@@ -429,6 +455,19 @@ const _deepseek_ai_dsh_api_session_controller_session_list_result$schema = z.obj
429
455
  'reasoningEffort': z.string().readonly().optional(),
430
456
  })]).readonly(),
431
457
  }).optional(),
458
+ 'subagentCatalog': z.array(z.union([z.intersection(z.object({
459
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
460
+ 'createdAt': z.number().readonly(),
461
+ }), z.object({
462
+ 'mode': z.literal("one-shot").readonly(),
463
+ 'label': z.string().readonly().optional(),
464
+ })), z.intersection(z.object({
465
+ 'id': z.intersection(z.string(), z.unknown()).readonly(),
466
+ 'createdAt': z.number().readonly(),
467
+ }), z.object({
468
+ 'mode': z.literal("continuable").readonly(),
469
+ 'label': z.string().readonly(),
470
+ }))])).optional(),
432
471
  'subagentTiming': z.object({
433
472
  'settledMs': z.number(),
434
473
  'active': z.object({
@@ -496,6 +535,7 @@ const _deepseek_ai_dsh_api_session_controller_session_modelCatalog_result$schema
496
535
  })).readonly(),
497
536
  })
498
537
  const _deepseek_ai_dsh_api_session_controller_session_openWorkspacePath_parameter_0$schema = z.object({
538
+ 'action': z.literal("reveal").readonly().optional(),
499
539
  'path': z.string().readonly(),
500
540
  })
501
541
  const _deepseek_ai_dsh_api_session_controller_session_openWorkspacePath_result$schema = z.object({
@@ -713,7 +753,7 @@ export const TYPERT_REMOTE = {
713
753
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionAttachmentValue',
714
754
  schema: _deepseek_ai_dsh_api_session_controller_session_attachment_result$schema,
715
755
  },
716
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":342,"column":3},
756
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":357,"column":3},
717
757
  },
718
758
  {
719
759
  id: '@deepseek-ai/dsh-api-session-controller#session/cancel',
@@ -738,7 +778,7 @@ export const TYPERT_REMOTE = {
738
778
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionCancelValue',
739
779
  schema: _deepseek_ai_dsh_api_session_controller_session_cancel_result$schema,
740
780
  },
741
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":362,"column":3},
781
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":377,"column":3},
742
782
  },
743
783
  {
744
784
  id: '@deepseek-ai/dsh-api-session-controller#session/canOpenWorkspacePath',
@@ -753,7 +793,7 @@ export const TYPERT_REMOTE = {
753
793
  typeSymbol: '@deepseek-ai/dsh-api-session-controller#session/canOpenWorkspacePath:result',
754
794
  schema: _deepseek_ai_dsh_api_session_controller_session_canOpenWorkspacePath_result$schema,
755
795
  },
756
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":267,"column":3},
796
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":272,"column":3},
757
797
  },
758
798
  {
759
799
  id: '@deepseek-ai/dsh-api-session-controller#session/control',
@@ -770,7 +810,7 @@ export const TYPERT_REMOTE = {
770
810
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionControlFrame',
771
811
  schema: _deepseek_ai_dsh_api_session_controller_session_control_result$schema,
772
812
  },
773
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":395,"column":3},
813
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":410,"column":3},
774
814
  },
775
815
  {
776
816
  id: '@deepseek-ai/dsh-api-session-controller#session/create',
@@ -795,7 +835,7 @@ export const TYPERT_REMOTE = {
795
835
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionCreateValue',
796
836
  schema: _deepseek_ai_dsh_api_session_controller_session_create_result$schema,
797
837
  },
798
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":239,"column":3},
838
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":244,"column":3},
799
839
  },
800
840
  {
801
841
  id: '@deepseek-ai/dsh-api-session-controller#session/follow',
@@ -822,7 +862,7 @@ export const TYPERT_REMOTE = {
822
862
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionFollowFrame',
823
863
  schema: _deepseek_ai_dsh_api_session_controller_session_follow_result$schema,
824
864
  },
825
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":385,"column":3},
865
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":400,"column":3},
826
866
  },
827
867
  {
828
868
  id: '@deepseek-ai/dsh-api-session-controller#session/fork',
@@ -847,7 +887,7 @@ export const TYPERT_REMOTE = {
847
887
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionForkValue',
848
888
  schema: _deepseek_ai_dsh_api_session_controller_session_fork_result$schema,
849
889
  },
850
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":320,"column":3},
890
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":335,"column":3},
851
891
  },
852
892
  {
853
893
  id: '@deepseek-ai/dsh-api-session-controller#session/list',
@@ -873,7 +913,7 @@ export const TYPERT_REMOTE = {
873
913
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionListValue',
874
914
  schema: _deepseek_ai_dsh_api_session_controller_session_list_result$schema,
875
915
  },
876
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":218,"column":9},
916
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":223,"column":9},
877
917
  },
878
918
  {
879
919
  id: '@deepseek-ai/dsh-api-session-controller#session/modelCatalog',
@@ -888,7 +928,7 @@ export const TYPERT_REMOTE = {
888
928
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#ModelCatalog',
889
929
  schema: _deepseek_ai_dsh_api_session_controller_session_modelCatalog_result$schema,
890
930
  },
891
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":258,"column":3},
931
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":263,"column":3},
892
932
  },
893
933
  {
894
934
  id: '@deepseek-ai/dsh-api-session-controller#session/openWorkspacePath',
@@ -914,7 +954,7 @@ export const TYPERT_REMOTE = {
914
954
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionOpenWorkspacePathValue',
915
955
  schema: _deepseek_ai_dsh_api_session_controller_session_openWorkspacePath_result$schema,
916
956
  },
917
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":279,"column":9},
957
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":293,"column":9},
918
958
  },
919
959
  {
920
960
  id: '@deepseek-ai/dsh-api-session-controller#session/page',
@@ -940,7 +980,7 @@ export const TYPERT_REMOTE = {
940
980
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionPage',
941
981
  schema: _deepseek_ai_dsh_api_session_controller_session_page_result$schema,
942
982
  },
943
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":373,"column":3},
983
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":388,"column":3},
944
984
  },
945
985
  {
946
986
  id: '@deepseek-ai/dsh-api-session-controller#session/prompt',
@@ -966,7 +1006,7 @@ export const TYPERT_REMOTE = {
966
1006
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionPromptValue',
967
1007
  schema: _deepseek_ai_dsh_api_session_controller_session_prompt_result$schema,
968
1008
  },
969
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":331,"column":3},
1009
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":346,"column":3},
970
1010
  },
971
1011
  {
972
1012
  id: '@deepseek-ai/dsh-api-session-controller#session/rename',
@@ -991,7 +1031,7 @@ export const TYPERT_REMOTE = {
991
1031
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionRenameValue',
992
1032
  schema: _deepseek_ai_dsh_api_session_controller_session_rename_result$schema,
993
1033
  },
994
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":310,"column":3},
1034
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":325,"column":3},
995
1035
  },
996
1036
  {
997
1037
  id: '@deepseek-ai/dsh-api-session-controller#session/search',
@@ -1017,7 +1057,7 @@ export const TYPERT_REMOTE = {
1017
1057
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionSearchValue',
1018
1058
  schema: _deepseek_ai_dsh_api_session_controller_session_search_result$schema,
1019
1059
  },
1020
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":229,"column":3},
1060
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":234,"column":3},
1021
1061
  },
1022
1062
  {
1023
1063
  id: '@deepseek-ai/dsh-api-session-controller#session/selectModel',
@@ -1042,7 +1082,7 @@ export const TYPERT_REMOTE = {
1042
1082
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionSelectModelValue',
1043
1083
  schema: _deepseek_ai_dsh_api_session_controller_session_selectModel_result$schema,
1044
1084
  },
1045
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":249,"column":3},
1085
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":254,"column":3},
1046
1086
  },
1047
1087
  {
1048
1088
  id: '@deepseek-ai/dsh-api-session-controller#session/updateQueue',
@@ -1067,7 +1107,7 @@ export const TYPERT_REMOTE = {
1067
1107
  typeSymbol: '@deepseek-ai/dsh-api-session-controller/types#SessionUpdateQueueValue',
1068
1108
  schema: _deepseek_ai_dsh_api_session_controller_session_updateQueue_result$schema,
1069
1109
  },
1070
- sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":352,"column":3},
1110
+ sourceLocation: {"file":"packages/api/session-controller/src/index.ts","line":367,"column":3},
1071
1111
  },
1072
1112
  {
1073
1113
  id: '@deepseek-ai/dsh-api-session-controller#skills/list',
@@ -26,6 +26,8 @@ export interface Config {
26
26
  export interface SessionControllerInternals {
27
27
  /** Native default-application handoff. */
28
28
  readonly openPath?: (path: string, signal: AbortSignal) => Promise<void>;
29
+ /** Native file-manager handoff. */
30
+ readonly revealPath?: (path: string, signal: AbortSignal) => Promise<void>;
29
31
  /** Native handoff availability probe. */
30
32
  readonly canOpenPath?: () => boolean;
31
33
  }
@@ -39,6 +41,7 @@ export declare class SessionController extends TypertRemoteService {
39
41
  private readonly history;
40
42
  private readonly listState;
41
43
  private readonly openPath;
44
+ private readonly revealPath;
42
45
  private readonly canOpenPath;
43
46
  private readonly promotions;
44
47
  /**
@@ -97,6 +100,15 @@ export declare class SessionController extends TypertRemoteService {
97
100
  * @returns true when the matching open operation is available.
98
101
  */
99
102
  canOpenWorkspacePath(): boolean;
103
+ /**
104
+ * Describe the serving desktop for authenticated file-action routes.
105
+ * @returns Host name, configured availability, and platform-specific file-manager behavior.
106
+ */
107
+ workspaceDesktop(): {
108
+ name: string;
109
+ available: boolean;
110
+ fileManager: 'finder' | 'explorer' | 'directory' | null;
111
+ };
100
112
  /**
101
113
  * Open one path prepared by a Session-aware caller on the Host desktop.
102
114
  * @param request - path after best-effort Session workspace resolution.
@@ -85,9 +85,10 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
85
85
  var e = new Error(message);
86
86
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
87
87
  });
88
+ import { hostname } from 'node:os';
88
89
  import z from '@deepseek-ai/schemastery';
89
90
  import { errorChain } from '@deepseek-ai/dsh-llm';
90
- import { canOpenNativePath, openNativePath } from '@deepseek-ai/dsh-native-command';
91
+ import { canOpenNativePath, nativeFileManager, openNativePath, revealNativePath } from '@deepseek-ai/dsh-native-command';
91
92
  import { Remote, RemoteError, TypertRemoteService } from '@deepseek-ai/dsh-typert-protocol';
92
93
  import { ApiSessionAgentController, inspectApiSession, } from "./agent.js";
93
94
  import { SessionCommandController } from "./commands.js";
@@ -180,6 +181,7 @@ let SessionController = (() => {
180
181
  history;
181
182
  listState;
182
183
  openPath;
184
+ revealPath;
183
185
  canOpenPath;
184
186
  promotions = new Set();
185
187
  /**
@@ -207,6 +209,7 @@ let SessionController = (() => {
207
209
  this.history = new SessionHistoryController(ctx, (observation) => { this.promote(observation); });
208
210
  this.listState = new ApiSessionList(ctx);
209
211
  this.openPath = internals.openPath ?? openNativePath;
212
+ this.revealPath = internals.revealPath ?? revealNativePath;
210
213
  this.canOpenPath = internals.canOpenPath
211
214
  ?? (() => config.nativeOpen ?? (internals.openPath !== undefined || canOpenNativePath()));
212
215
  ctx.plugin(SessionFileReferences);
@@ -331,6 +334,14 @@ let SessionController = (() => {
331
334
  canOpenWorkspacePath() {
332
335
  return this.canOpenPath();
333
336
  }
337
+ /**
338
+ * Describe the serving desktop for authenticated file-action routes.
339
+ * @returns Host name, configured availability, and platform-specific file-manager behavior.
340
+ */
341
+ workspaceDesktop() {
342
+ const fileManager = nativeFileManager();
343
+ return { name: hostname(), available: fileManager !== null && this.canOpenPath(), fileManager };
344
+ }
334
345
  /**
335
346
  * Open one path prepared by a Session-aware caller on the Host desktop.
336
347
  * @param request - path after best-effort Session workspace resolution.
@@ -344,7 +355,10 @@ let SessionController = (() => {
344
355
  }
345
356
  signal.throwIfAborted();
346
357
  try {
347
- await this.openPath(request.path, signal);
358
+ if (request.action === 'reveal')
359
+ await this.revealPath(request.path, signal);
360
+ else
361
+ await this.openPath(request.path, signal);
348
362
  return { opened: true };
349
363
  }
350
364
  catch (error) {
@@ -332,6 +332,8 @@ export interface SessionCancelValue {
332
332
  }
333
333
  /** Request to open one path prepared by a Session-aware caller on the Host desktop. */
334
334
  export interface SessionOpenWorkspacePathRequest {
335
+ /** File-manager navigation when requested; omission uses the default application. */
336
+ readonly action?: 'reveal';
335
337
  /** Path after best-effort Session workspace resolution, in Host filesystem syntax. */
336
338
  readonly path: string;
337
339
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-api-session-controller",
3
3
  "description": "Session Remote commands, cold reads, and live control transport",
4
- "version": "0.1.5-alpha.1",
4
+ "version": "0.1.5-alpha.2",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -66,40 +66,40 @@
66
66
  "dependencies": {
67
67
  "mime-types": "^3.0.2",
68
68
  "zod": "^4.4.3",
69
+ "@deepseek-ai/dsh-deque": "^0.1.5-alpha.2",
69
70
  "@deepseek-ai/schemastery": "^3.18.2",
70
- "@deepseek-ai/dsh-brand": "^0.1.5-alpha.1",
71
- "@deepseek-ai/dsh-deque": "^0.1.5-alpha.1"
71
+ "@deepseek-ai/dsh-brand": "^0.1.5-alpha.2"
72
72
  },
73
73
  "peerDependencies": {
74
+ "@deepseek-ai/dsh-agent": "^0.1.5-alpha.2",
75
+ "@deepseek-ai/dsh-agent-default-model": "^0.1.5-alpha.2",
74
76
  "@deepseek-ai/cordis": "^4.0.2",
75
- "@deepseek-ai/dsh-agent": "^0.1.5-alpha.1",
76
- "@deepseek-ai/dsh-agent-default-model": "^0.1.5-alpha.1",
77
- "@deepseek-ai/dsh-api-gateway": "^0.1.5-alpha.1",
78
- "@deepseek-ai/dsh-agent-presets": "^0.1.5-alpha.1",
79
- "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.1",
80
- "@deepseek-ai/dsh-client-file-upload": "^0.1.5-alpha.1",
81
- "@deepseek-ai/dsh-file-reference": "^0.1.5-alpha.1",
82
- "@deepseek-ai/dsh-commands": "^0.1.5-alpha.1",
83
- "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.1",
84
- "@deepseek-ai/dsh-fs": "^0.1.5-alpha.1",
85
- "@deepseek-ai/dsh-jobs": "^0.1.5-alpha.1",
86
- "@deepseek-ai/dsh-llm": "^0.1.5-alpha.1",
87
- "@deepseek-ai/dsh-native-command": "^0.1.5-alpha.1",
88
- "@deepseek-ai/dsh-scope": "^0.1.5-alpha.1",
89
- "@deepseek-ai/dsh-session": "^0.1.5-alpha.1",
90
- "@deepseek-ai/dsh-session-persistence": "^0.1.5-alpha.1",
91
- "@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.1",
92
- "@deepseek-ai/dsh-session-query": "^0.1.5-alpha.1",
93
- "@deepseek-ai/dsh-session-title": "^0.1.5-alpha.1",
94
- "@deepseek-ai/dsh-skill": "^0.1.5-alpha.1",
95
- "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.1",
96
- "@deepseek-ai/dsh-subagent": "^0.1.5-alpha.1",
97
- "@deepseek-ai/dsh-typert-registry": "^0.1.5-alpha.1",
98
- "@deepseek-ai/dsh-util-time": "^0.1.5-alpha.1",
99
- "@deepseek-ai/dsh-util-values": "^0.1.5-alpha.1",
100
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-alpha.1",
101
- "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-alpha.1",
102
- "@deepseek-ai/dsh-workspace": "^0.1.5-alpha.1"
77
+ "@deepseek-ai/dsh-agent-presets": "^0.1.5-alpha.2",
78
+ "@deepseek-ai/dsh-api-gateway": "^0.1.5-alpha.2",
79
+ "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.2",
80
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.2",
81
+ "@deepseek-ai/dsh-client-file-upload": "^0.1.5-alpha.2",
82
+ "@deepseek-ai/dsh-commands": "^0.1.5-alpha.2",
83
+ "@deepseek-ai/dsh-file-reference": "^0.1.5-alpha.2",
84
+ "@deepseek-ai/dsh-jobs": "^0.1.5-alpha.2",
85
+ "@deepseek-ai/dsh-llm": "^0.1.5-alpha.2",
86
+ "@deepseek-ai/dsh-native-command": "^0.1.5-alpha.2",
87
+ "@deepseek-ai/dsh-scope": "^0.1.5-alpha.2",
88
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
89
+ "@deepseek-ai/dsh-session-persistence": "^0.1.5-alpha.2",
90
+ "@deepseek-ai/dsh-fs": "^0.1.5-alpha.2",
91
+ "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-alpha.2",
92
+ "@deepseek-ai/dsh-session-query": "^0.1.5-alpha.2",
93
+ "@deepseek-ai/dsh-skill": "^0.1.5-alpha.2",
94
+ "@deepseek-ai/dsh-subagent": "^0.1.5-alpha.2",
95
+ "@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.2",
96
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.2",
97
+ "@deepseek-ai/dsh-session-title": "^0.1.5-alpha.2",
98
+ "@deepseek-ai/dsh-util-time": "^0.1.5-alpha.2",
99
+ "@deepseek-ai/dsh-typert-registry": "^0.1.5-alpha.2",
100
+ "@deepseek-ai/dsh-util-values": "^0.1.5-alpha.2",
101
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-alpha.2",
102
+ "@deepseek-ai/dsh-workspace": "^0.1.5-alpha.2"
103
103
  },
104
104
  "peerDependenciesMeta": {
105
105
  "@deepseek-ai/dsh-jobs": {
@@ -115,43 +115,43 @@
115
115
  "devDependencies": {
116
116
  "@types/mime-types": "^3.0.1",
117
117
  "@deepseek-ai/cordis": "^4.0.2",
118
- "@deepseek-ai/dsh-agent": "^0.1.5-alpha.1",
119
- "@deepseek-ai/dsh-agent-default-model": "^0.1.5-alpha.1",
120
- "@deepseek-ai/dsh-agent-loop": "^0.1.5-alpha.1",
121
- "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.5-alpha.1",
122
- "@deepseek-ai/dsh-agent-presets": "^0.1.5-alpha.1",
123
- "@deepseek-ai/dsh-api-gateway": "^0.1.5-alpha.1",
124
- "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.1",
125
- "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.1",
126
- "@deepseek-ai/dsh-client-file-upload": "^0.1.5-alpha.1",
127
- "@deepseek-ai/dsh-client-store": "^0.1.5-alpha.1",
128
- "@deepseek-ai/dsh-commands": "^0.1.5-alpha.1",
129
- "@deepseek-ai/dsh-fs": "^0.1.5-alpha.1",
130
- "@deepseek-ai/dsh-file-reference": "^0.1.5-alpha.1",
131
- "@deepseek-ai/dsh-jobs": "^0.1.5-alpha.1",
132
- "@deepseek-ai/dsh-llm": "^0.1.5-alpha.1",
133
- "@deepseek-ai/dsh-native-command": "^0.1.5-alpha.1",
134
- "@deepseek-ai/dsh-permission-presets": "^0.1.5-alpha.1",
135
- "@deepseek-ai/dsh-scope": "^0.1.5-alpha.1",
136
- "@deepseek-ai/dsh-session": "^0.1.5-alpha.1",
137
- "@deepseek-ai/dsh-session-persistence": "^0.1.5-alpha.1",
138
- "@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.1",
139
- "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-alpha.1",
140
- "@deepseek-ai/dsh-fs-local": "^0.1.5-alpha.1",
141
- "@deepseek-ai/dsh-session-query": "^0.1.5-alpha.1",
142
- "@deepseek-ai/dsh-skill": "^0.1.5-alpha.1",
143
- "@deepseek-ai/dsh-storage": "^0.1.5-alpha.1",
144
- "@deepseek-ai/dsh-storage-domain": "^0.1.5-alpha.1",
145
- "@deepseek-ai/dsh-storage-json": "^0.1.5-alpha.1",
146
- "@deepseek-ai/dsh-subagent": "^0.1.5-alpha.1",
147
- "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.1",
148
- "@deepseek-ai/dsh-typert-registry": "^0.1.5-alpha.1",
149
- "@deepseek-ai/dsh-util-crypto": "^0.1.5-alpha.1",
150
- "@deepseek-ai/dsh-util-time": "^0.1.5-alpha.1",
151
- "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-alpha.1",
152
- "@deepseek-ai/dsh-util-values": "^0.1.5-alpha.1",
153
- "@deepseek-ai/dsh-workspace": "^0.1.5-alpha.1",
154
- "@deepseek-ai/dsh-session-title": "^0.1.5-alpha.1"
118
+ "@deepseek-ai/dsh-agent": "^0.1.5-alpha.2",
119
+ "@deepseek-ai/dsh-agent-default-model": "^0.1.5-alpha.2",
120
+ "@deepseek-ai/dsh-agent-loop": "^0.1.5-alpha.2",
121
+ "@deepseek-ai/dsh-agent-loop-testkit": "^0.1.5-alpha.2",
122
+ "@deepseek-ai/dsh-agent-presets": "^0.1.5-alpha.2",
123
+ "@deepseek-ai/dsh-api-gateway": "^0.1.5-alpha.2",
124
+ "@deepseek-ai/dsh-attachment": "^0.1.5-alpha.2",
125
+ "@deepseek-ai/dsh-client-connection": "^0.1.5-alpha.2",
126
+ "@deepseek-ai/dsh-client-file-upload": "^0.1.5-alpha.2",
127
+ "@deepseek-ai/dsh-client-store": "^0.1.5-alpha.2",
128
+ "@deepseek-ai/dsh-commands": "^0.1.5-alpha.2",
129
+ "@deepseek-ai/dsh-file-reference": "^0.1.5-alpha.2",
130
+ "@deepseek-ai/dsh-fs": "^0.1.5-alpha.2",
131
+ "@deepseek-ai/dsh-fs-local": "^0.1.5-alpha.2",
132
+ "@deepseek-ai/dsh-jobs": "^0.1.5-alpha.2",
133
+ "@deepseek-ai/dsh-llm": "^0.1.5-alpha.2",
134
+ "@deepseek-ai/dsh-native-command": "^0.1.5-alpha.2",
135
+ "@deepseek-ai/dsh-permission-presets": "^0.1.5-alpha.2",
136
+ "@deepseek-ai/dsh-session": "^0.1.5-alpha.2",
137
+ "@deepseek-ai/dsh-session-persistence": "^0.1.5-alpha.2",
138
+ "@deepseek-ai/dsh-session-projection": "^0.1.5-alpha.2",
139
+ "@deepseek-ai/dsh-session-projection-cache": "^0.1.5-alpha.2",
140
+ "@deepseek-ai/dsh-session-query": "^0.1.5-alpha.2",
141
+ "@deepseek-ai/dsh-session-title": "^0.1.5-alpha.2",
142
+ "@deepseek-ai/dsh-skill": "^0.1.5-alpha.2",
143
+ "@deepseek-ai/dsh-storage": "^0.1.5-alpha.2",
144
+ "@deepseek-ai/dsh-storage-json": "^0.1.5-alpha.2",
145
+ "@deepseek-ai/dsh-storage-domain": "^0.1.5-alpha.2",
146
+ "@deepseek-ai/dsh-subagent": "^0.1.5-alpha.2",
147
+ "@deepseek-ai/dsh-typert-protocol": "^0.1.5-alpha.2",
148
+ "@deepseek-ai/dsh-scope": "^0.1.5-alpha.2",
149
+ "@deepseek-ai/dsh-typert-registry": "^0.1.5-alpha.2",
150
+ "@deepseek-ai/dsh-util-crypto": "^0.1.5-alpha.2",
151
+ "@deepseek-ai/dsh-util-time": "^0.1.5-alpha.2",
152
+ "@deepseek-ai/dsh-util-values": "^0.1.5-alpha.2",
153
+ "@deepseek-ai/dsh-util-workspace-path": "^0.1.5-alpha.2",
154
+ "@deepseek-ai/dsh-workspace": "^0.1.5-alpha.2"
155
155
  },
156
156
  "scripts": {
157
157
  "bundle": "tsdown",