feat(session-export): add command and Header action
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write .agents/notes/implemented/feature/2026-08-11-web-export-command-and-dialog.md
|
||||
2026-08-11-web-export-command-and-dialog.md: f08a47faab770f59f531076bbb20d3a2e43563ab
|
||||
2026-08-11-web-export-command-and-dialog.zh.md: 88d5995ad4072eb1dd254dda209fafc6f1b349f6
|
||||
@@ -0,0 +1,31 @@
|
||||
# Agent Note: Web `/export` shares the streamed Session ZIP download
|
||||
|
||||
Status: implemented
|
||||
|
||||
English | [中文](2026-08-11-web-export-command-and-dialog.zh.md)
|
||||
|
||||
## Problem
|
||||
|
||||
Session export needs a stable Session-level visible action and an equivalent slash-command path. A second backend reader or Host-path writer would duplicate the download implementation and introduce platform-specific file-permission and path-reveal problems.
|
||||
|
||||
## Decision
|
||||
|
||||
`@deepseek-ai/dsh-session-export` registers a Web-only `/export` human command and provides the browser `ctx.sessionExport` controller. The command records an ordinary `command/run` and `command/done`; after `command.execute` returns a successful result, `dsh-client-ui-command` emits a local acknowledgment that asks this browser's controller to download ApiProxy's existing `GET /api/session.export` ZIP. Other clients render the broadcast command nodes without repeating the browser side effect. The 111×32 `Session log` capsule in the Session Header calls that controller directly. Both paths therefore use the same Host endpoint, browser save operation, in-flight state, error handling, and Modal.
|
||||
|
||||
The Header contribution occupies the right-aligned `conversation.session.header.utilities` list and renders the `Session log` text capsule with its trailing download icon plus the shared Modal. The title-adjacent `conversation.session.header.actions` list continues to own mode, Subagent, and Task entries, so mounting Session export does not reorder or move them. The export contribution does not observe Session history. A per-Session controller collapses concurrent gestures, aborts active fetches when its plugin disposes, ignores late requests after disposal, and preserves a user's closed state when the request later completes.
|
||||
|
||||
The ZIP endpoint and persistence `readRaw` capability remain owned by `dsh-host-apiproxy` and the persistence package. The endpoint flushes a live root Session before reading its artifact, so the local acknowledgment cannot race ahead of durable command lifecycle rows. This package does not serialize Session events, write Host files, deliver Host paths, or implement SQLite fallback.
|
||||
|
||||
The package compiles its Host command and invariant through `tsconfig.host.json`, while `tsconfig.client.json` owns the browser controller, Header action, Modal, and their face-named tests. The repository Host and Client aggregates reference only the matching project, so their incompatible Cordis `Context` merges never enter one TypeScript program.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**Put the visible action in Trajectory.** Rejected because export is a Session-level operation and must remain discoverable without opening a diagnostic view.
|
||||
|
||||
**Write a Host-side JSONL file from `/export`.** Rejected because it would diverge from the descendant-and-attachment ZIP, require Windows ACL handling, and return a Host path that may be meaningless to a remote browser.
|
||||
|
||||
**Keep both Header and Trajectory buttons.** Rejected because two visible controls for the same Session operation create duplicate ownership and inconsistent placement.
|
||||
|
||||
## Consequences
|
||||
|
||||
The Header action and `/export` download the same ZIP and show the same feedback. An executed command remains visible in the durable transcript without creating a model turn. Deployments whose persistence backend has no raw per-Session artifact receive the endpoint's existing failure; SQLite support remains separate work. Command availability before a Session's first turn is separate work.
|
||||
@@ -0,0 +1,31 @@
|
||||
# Agent Note: Web `/export` 共用流式 Session ZIP 下载
|
||||
|
||||
Status: implemented
|
||||
|
||||
[English](2026-08-11-web-export-command-and-dialog.md) | 中文
|
||||
|
||||
## Problem
|
||||
|
||||
Session 导出需要一个稳定的 Session 级外显入口,以及语义等价的斜杠命令路径。第二套后端读取器或 Host 路径写入器会重复下载实现,并引入平台相关的文件权限和路径公开问题。
|
||||
|
||||
## Decision
|
||||
|
||||
`@deepseek-ai/dsh-session-export` 注册 Web 专用的 `/export` 用户命令,并提供浏览器 `ctx.sessionExport` 控制器。该命令记录普通的 `command/run` 和 `command/done`;`command.execute` 返回成功结果后,`dsh-client-ui-command` 会发布本地确认,请求当前浏览器的控制器下载 ApiProxy 现有的 `GET /api/session.export` ZIP。其他客户端会渲染广播的命令节点,但不会重复执行浏览器副作用。Session Header 中 111×32 的 `Session log` 胶囊按钮会直接调用该控制器。因此,两种入口共用同一个 Host 端点、浏览器保存操作、进行中状态、错误处理和 Modal。
|
||||
|
||||
Header 贡献占用最右侧的 `conversation.session.header.utilities` 列表,渲染带尾部下载图标的 `Session log` 文字 capsule 和共享 Modal。标题旁的 `conversation.session.header.actions` 列表继续承载模式、Subagent 和 Task 配置项,挂载 Session export 不会改变它们的顺序或位置。导出贡献不观察 Session 历史。逐 Session 控制器会折叠并发操作,在插件释放时取消活动 fetch,忽略释放后的迟到请求,并在请求后来完成时保留用户已经关闭弹窗的状态。
|
||||
|
||||
ZIP 端点与持久化 `readRaw` 能力仍由 `dsh-host-apiproxy` 和持久化包拥有。端点会在读取工件前 flush 活动的根 Session,因此本地确认不会早于持久命令生命周期行。本包不序列化 Session 事件、不写 Host 文件、不交付 Host 路径,也不实现 SQLite 回退。
|
||||
|
||||
本包通过 `tsconfig.host.json` 编译 Host 命令和 invariant,`tsconfig.client.json` 则负责浏览器控制器、Header 操作、Modal 及其带编译面后缀的测试。仓库的 Host 和 Client 聚合只引用对应项目,因此两种不兼容的 Cordis `Context` 合并不会进入同一个 TypeScript program。
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
**把外显入口放进 Trajectory。** 不采用,因为导出是 Session 级操作,用户不应先打开诊断视图才能发现它。
|
||||
|
||||
**让 `/export` 写入 Host 侧 JSONL 文件。** 不采用,因为这会偏离包含子 Session 与附件的 ZIP,需要处理 Windows ACL,并返回对远程浏览器可能没有意义的 Host 路径。
|
||||
|
||||
**同时保留 Header 与 Trajectory 按钮。** 不采用,因为两个外显控件执行同一项 Session 操作,会形成重复归属和不一致的位置。
|
||||
|
||||
## Consequences
|
||||
|
||||
Header 操作与 `/export` 会下载同一个 ZIP,并显示相同反馈。已执行命令保留在持久文本记录中,且不创建模型轮次。持久化后端没有逐 Session 原始工件时,用户会收到端点现有的失败;SQLite 支持保留为独立工作。Session 首轮前的命令可用性属于独立工作。
|
||||
Reference in New Issue
Block a user