@lingxi-ai-cn/dsh-tui-runtime 0.1.7-alpha.2 → 0.1.9-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +5 -2
- package/README.zh.md +5 -2
- package/lib/index.js +108 -47
- package/lib/types/exit.d.ts +7 -0
- package/lib/types/host.d.ts +4 -3
- package/lib/types/startup-guidance.d.ts +1 -1
- package/lib/types/theme.d.ts +3 -1
- package/package.json +90 -89
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/ui/tui/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 390fc8c2bfb7f8efd2026abb0a3bc3bb23ef088f
|
|
6
|
+
README.zh.md: a4df4260acb414c7fe64e4103f04ed28085d2013
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ While the root Agent is running, a non-empty draft uses Enter to steer the curre
|
|
|
19
19
|
|
|
20
20
|
Native full-screen terminal frontend for one owned root DeepSeek Harness Agent and its live continuable child views. The plugin waits for Loader settlement, creates or resumes the root through `ctx.agents`, retains only its root `AgentHandle`, renders committed `session/event` rows with Ink, and disposes the root after flushing its Session. It mounts no HTTP server and imports no browser Client package.
|
|
21
21
|
|
|
22
|
-
An empty root Session opens a centered startup workspace with a nine-row, 60-cell Electric `DSH` foreground-block mark when the complete workspace fits, and a compact `DSH` mark otherwise. Extended-color terminals evaluate the source design's cosine high-voltage-arc palette at each mark cell, ANSI 16-color terminals use the theme accent, and colorless output emits only the block characters. The workspace retains a bounded composer, the resolved model hint, and the workspace footer. After the first admitted input or when a Session already has transcript rows, the header becomes a compact activity row, the transcript follows the live tail above the composer, and short output remains bottom anchored. While an Agent is running, the activity row uses the configured fixed-width dots, pulse, minimal marker, or disabled animation and shows `Esc stop`; Escape uses the existing Agent cancellation path. `/quit` and `/exit` accept no arguments, settle their command audit before requesting exit, and converge on the terminal-first idempotent shutdown path.
|
|
22
|
+
An empty root Session opens a centered startup workspace with a nine-row, 60-cell Electric `DSH` foreground-block mark when the complete workspace fits, and a compact `DSH` mark otherwise. Extended-color terminals evaluate the source design's cosine high-voltage-arc palette at each mark cell, ANSI 16-color terminals use the theme accent, and colorless output emits only the block characters. The workspace retains a bounded composer, the resolved model hint, and the workspace footer. After the first admitted input or when a Session already has transcript rows, the header becomes a compact activity row, the transcript follows the live tail above the composer, and short output remains bottom anchored. While an Agent is running, the activity row uses the configured fixed-width dots, pulse, minimal marker, or disabled animation and shows `Esc stop`; Escape uses the existing Agent cancellation path. `/quit` and `/exit` accept no arguments, settle their command audit before requesting exit, and converge on the terminal-first idempotent shutdown path. The launcher receives the exit request before asynchronous cleanup; cancelled startup catalog reads stop blocking the TUI, and Agent cancellation, Session flush, and disposal proceed alongside background-task settlement.
|
|
23
23
|
|
|
24
24
|
Before the first request, the startup workspace derives process-local guidance from the successful `tuiStartup` Host snapshot, the selected provider's public authentication and model-catalog reads, and mounted Plugin Hub availability. A Host or provider failure points to `/doctor`; an unconfigured provider uses its provider-owned authentication label and points to `/models`; a configured route with an empty advisory catalog offers a generic `/models` retry because the LLM service exposes no provider remediation field. A healthy route retains the selected model and reasoning effort, then offers `/models`, `/plugins` when available, and `/help` as secondary actions. Provider topology and successful model changes refresh the snapshot. Every line is terminal-sanitized and Unicode-cell bounded, required status does not depend on dim color, and a narrow workspace mounts only the highest-priority executable line. The collector never reads credential values, environment variables, or the system prompt, and it creates no Session event.
|
|
25
25
|
|
|
@@ -33,7 +33,7 @@ A completed Turn adds one exact token-usage node folded by the official token-me
|
|
|
33
33
|
|
|
34
34
|
The composer sends ordinary text with `Agent.followup()` while idle and `Agent.steer()` while running. It keeps one Unicode grapheme-aware insertion point, supports left/right and word movement, logical-line Home/End, backward/forward and previous-word deletion, submitted-history traversal with unsent-draft restoration, and up to five visible wrapped rows. `Ctrl+J` inserts a newline while Enter submits the original non-blank text without trimming its outer whitespace. `Ctrl+_` or `Ctrl+Shift+-` undoes an edit and `Ctrl+Y` redoes it through at most 100 process-local text-and-cursor snapshots. Rapid single-grapheme typing and same-direction deletion coalesce; paste, multiline insertion, suggestion acceptance, and history acceptance remain separate units, while cursor movement only ends coalescing. A bracketed paste of at least eight lines or 4 KiB becomes one bounded `[Pasted text]` placeholder; its terminal-safe original remains process-local and expands only at submission. `Ctrl+V` requests one typed system-clipboard read through the platform provider; macOS uses `pbpaste`, Linux Wayland uses `wl-paste`, and Linux X11 tries `xclip` then `xsel`. The provider uses argv-only execution, a short timeout, a complete byte cap, and independent image magic validation; file-list payloads are parsed as local `file:` paths. Unsupported Windows, headless SSH, missing utilities, and invalid media return a live notice and leave the draft untouched, so terminal paste and `@` path completion remain the fallback. Clipboard text and admitted image chips are inserted as one undo unit. Deleting the placeholder removes its payload, while undo, redo, stash, submitted history, and Agent-view switching retain the reference without mounting the pasted lines. `Ctrl+R` searches unique prompts submitted by the current TUI process newest-first; repeated use selects an older match, Enter accepts it, and Escape restores the exact draft and cursor. `Ctrl+S` stashes a non-empty draft, restores it into an empty editor, or swaps it with another non-empty draft so restoration never overwrites text; each draft retains its own edit history. Prompt-history search, stash, paste references, and edit history remain process-local and never enter the Session log. A command-only slash query opens the shared suggestion controller over the effective `ctx.commands.list(agent)` descriptors; the compatibility catalog retains TUI-owned localized metadata when an older Host omits additive discovery fields, while exact legacy first-party descriptions receive a localized fallback without rewriting same-name third-party text. An `@token` at the draft or after whitespace opens the same controller over cancellable workspace results: a Host-provided `ctx.fs.completePaths()` is preferred, while a legacy Host uses an equivalent bounded traversal over `listDir()` and `contains()`. Both paths stay rooted at the current Session workspace; loading, no-match, and truncated states remain bounded, directory acceptance keeps its trailing slash, and file acceptance adds one separating space. The bounded list marks one selection; Up/Down moves it without traversing prompt history, Shift+Tab moves backward, Tab or Enter accepts the selected command or path, and Escape closes the list while preserving the draft. One immutable action registry owns the effective Global, Composer, Suggestion, HistorySearch, TranscriptSearch, Transcript, Detail, Dialog, Footer, Work, and Approval bindings and their input priority. `/help` keeps returning the effective command descriptors and also opens a bounded, scrollable interaction panel generated from that registry; unsupported capability actions are omitted, `/help extra` remains a usage error, and Escape returns to the prior local mode. `Alt+P` opens the existing model picker without replacing the current draft. A leading slash first uses `ctx.commands.execute()`; an unmatched line remains an ordinary prompt so skill gestures retain their shared Agent path. Approvals are scoped to the exact owned Agent and expose only allow-once/reject. `ctx.userQuestions.registerProvider()` supplies a FIFO structured-question surface whose Dialog owns Enter even while the Agent is running.
|
|
35
35
|
|
|
36
|
-
`/models` opens a bounded, scrollable selector over `ctx.llm.listProviders()` and each provider's live `listModels()` result. Providers that advertise interactive authentication appear as sign-in actions until configured. The first native flow is OpenAI Codex: choosing **Sign in with ChatGPT** runs the provider-owned browser OAuth flow through the official authorization owner, stores the refreshable grant through the scoped credential-record owner, refreshes the account model catalog, and returns to the selector. Older Hosts fall back to the provider-neutral LLM authentication bridge without changing the UI contract. After a model declares selectable reasoning efforts, a second bounded question chooses one exact effort. The resolved model and effort are persisted
|
|
36
|
+
`/models` opens a bounded, scrollable selector over `ctx.llm.listProviders()` and each provider's live `listModels()` result. Providers that advertise interactive authentication appear as sign-in actions until configured. The first native flow is OpenAI Codex: choosing **Sign in with ChatGPT** runs the provider-owned browser OAuth flow through the official authorization owner, stores the refreshable grant through the scoped credential-record owner, refreshes the account model catalog, and returns to the selector. Older Hosts fall back to the provider-neutral LLM authentication bridge without changing the UI contract. After a model declares selectable reasoning efforts, a second bounded question chooses one exact effort. The resolved model and effort are persisted in `tui.defaultModel` through the settings owner, become the owned Agent's next-step selection, and update the idle header immediately; an already-running step keeps its captured selection.
|
|
37
37
|
|
|
38
38
|
`/mode` opens the dynamic `ctx.agentPresets` roster, with localized names and descriptions for Standard (`standard`), PTC (`ptc`), Minimal (`minimal`), and Creator (`cordis`) plus installed user presets. Missing and broken rows remain visible with bounded disabled reasons, without exposing preset paths. A downstream Session that durably records the retired `code` preset is interpreted as PTC and appends the canonical `ptc` selection only when a successful recomposition commits. A blank Session switches through `ctx.agentPresets.recompose()` under one single-flight transaction and appends `agent-preset/selected` only after the new composition commits. After the first `turn/start`, selection opens the existing fresh-Session confirmation instead; Escape keeps the current Agent, draft, transcript anchor, and footer, while confirmation creates and publishes a new Session under the selected preset before disposing the old handle. The current mode is an actionable footer item, and both footer and single-select menu rows use the same state transition for keyboard and primary SGR clicks. This package selects existing presets but does not copy, edit, or remove them.
|
|
39
39
|
|
|
@@ -146,10 +146,13 @@ The post-install runtime keeps every official-package import in `src/host.ts`. T
|
|
|
146
146
|
|
|
147
147
|
### User settings
|
|
148
148
|
|
|
149
|
+
New TUI Agents prefer `tui.defaultModel` and fall back to `agent-default-model` when it is unset. `/models` leaves the shared default unchanged. The enhanced `lingxi-openai-codex` route uses `llm-openai-codex/openai-codex` credentials; the official `openai-codex` route uses its own authorization flow. If the shared default still names `openai-codex` and that official route is not enabled, set `tui.defaultModel` to provider `lingxi-openai-codex` and the existing model id before starting the TUI. Keep shared defaults and credential records unchanged.
|
|
150
|
+
|
|
149
151
|
When `ctx.settings` is mounted, the package registers the `tui` namespace. The file provider persists the theme, optional custom-theme file, activity animation, `en`/`zh` locale, mouse ownership, and keybinding overrides in the shared user-settings document; the TUI never writes that file directly. The locale catalog is versioned, uses English as a missing-key fallback, and bounds translated content with the same terminal-cell rules as English output.
|
|
150
152
|
|
|
151
153
|
| Key | Default | Behavior |
|
|
152
154
|
|---|---:|---|
|
|
155
|
+
| `defaultModel` | unset | TUI-only provider, model, and optional reasoning effort for new Agents. |
|
|
153
156
|
| `theme` | `auto` | Select `auto` to follow the probed terminal background, or pin `dark`, `light`, or `no-color` semantic terminal tokens. |
|
|
154
157
|
| `themeFile` | unset | Load one declarative JSON palette by file name from `$DSH_HOME/themes`; traversal, symlinks, oversized files, unknown fields, and unsupported colors are rejected. |
|
|
155
158
|
| `locale` | `en` | Select the runtime catalog used by first-party TUI text; `/lang` changes this setting without replacing the Agent or view. |
|
package/README.zh.md
CHANGED
|
@@ -19,7 +19,7 @@ root Agent running 时,非空 draft 使用 Enter steer 当前 turn,Tab 排
|
|
|
19
19
|
|
|
20
20
|
面向一个自有 root DeepSeek Harness Agent 及其 live continuable child view 的原生全屏终端前端。该插件等待 Loader 结算,通过 `ctx.agents` 创建或恢复 root,只持有它的 root `AgentHandle`,用 Ink 渲染已提交的 `session/event` 行,并在 flush 其 Session 后处置 root。它不挂载 HTTP server,也不导入浏览器 Client 包。
|
|
21
21
|
|
|
22
|
-
空的 root Session 会打开居中的启动工作区;完整工作区能容纳时显示九行、60 cell 的 Electric `DSH` 前景色块标志,否则显示紧凑的 `DSH` 标志。扩展颜色终端会在每个标志 cell 上计算源设计的余弦高压电弧调色板,ANSI 16 色终端使用主题 accent,无色输出则只发出块字符。工作区保留有界 composer、已解析的 model 提示和 workspace footer。第一次 admitted input 之后,或 Session 已经存在 transcript 行时,header 会变成紧凑 activity row,transcript 会在 composer 上方跟随 live tail,短输出保持在底部锚定。Agent running 时,activity row 会使用已配置的固定宽度移动点、脉冲、简洁标记或关闭动效,并显示 `Esc stop`;Escape 复用已有的 Agent cancellation path。`/quit` 与 `/exit` 不接受参数,会在请求退出前完成 command audit,并汇入 terminal-first 的幂等 shutdown path。
|
|
22
|
+
空的 root Session 会打开居中的启动工作区;完整工作区能容纳时显示九行、60 cell 的 Electric `DSH` 前景色块标志,否则显示紧凑的 `DSH` 标志。扩展颜色终端会在每个标志 cell 上计算源设计的余弦高压电弧调色板,ANSI 16 色终端使用主题 accent,无色输出则只发出块字符。工作区保留有界 composer、已解析的 model 提示和 workspace footer。第一次 admitted input 之后,或 Session 已经存在 transcript 行时,header 会变成紧凑 activity row,transcript 会在 composer 上方跟随 live tail,短输出保持在底部锚定。Agent running 时,activity row 会使用已配置的固定宽度移动点、脉冲、简洁标记或关闭动效,并显示 `Esc stop`;Escape 复用已有的 Agent cancellation path。`/quit` 与 `/exit` 不接受参数,会在请求退出前完成 command audit,并汇入 terminal-first 的幂等 shutdown path。 launcher 会在异步清理前收到退出请求;已取消的启动目录读取不再阻塞 TUI,Agent 取消、Session flush 与处置会和后台任务收尾并行进行。
|
|
23
23
|
|
|
24
24
|
第一次请求前,启动工作区会根据已成功的 `tuiStartup` Host 快照、所选 provider 的公开认证与模型目录读取结果,以及 Plugin Hub 是否挂载,生成只存在于当前进程的引导。Host 或 provider 失败时指向 `/doctor`;provider 未配置时使用该 provider 自有的认证名称并指向 `/models`;已配置 route 的 advisory 目录为空时提供通用 `/models` 重试,因为 LLM service 没有暴露 provider 修复字段。健康 route 保留已选 model 与 reasoning effort,并把 `/models`、可用时的 `/plugins` 和 `/help` 作为次要操作。Provider topology 和成功的 model 变更会刷新该快照。每行都会清理终端控制字符并按 Unicode cell 限界,必要状态不依赖 dim color,窄工作区只挂载一条优先级最高的可执行提示。Collector 不读取 credential 值、环境变量或 system prompt,也不创建 Session event。
|
|
25
25
|
|
|
@@ -33,7 +33,7 @@ Transcript 是对耐久 Session 日志的纯 fold。以 append 方式产生的
|
|
|
33
33
|
|
|
34
34
|
Agent idle 时,composer 用 `Agent.followup()` 发送普通文本;running 时使用 `Agent.steer()`。它维护一个感知 Unicode grapheme 的插入点,支持左右与按词移动、逻辑行 Home/End、向前/向后及删除前一词、保留未提交草稿的已提交历史遍历,以及最多五行可见换行内容。`Ctrl+J` 插入换行,Enter 提交原始非空白文本而不裁掉首尾空白。`Ctrl+_` 或 `Ctrl+Shift+-` 通过最多 100 份进程内文本与光标快照撤销编辑,`Ctrl+Y` 则重做。快速的单 grapheme 输入和同方向删除会合并;paste、多行插入、suggestion 接受与历史接受各自形成独立 unit,光标移动只会终止合并。至少八行或 4 KiB 的 bracketed paste 会变成一条有界的 `[Pasted text]` placeholder;经过终端安全处理的原文只保留在当前进程中,并仅在提交时展开。`Ctrl+V` 会通过平台 provider 请求一次 typed system clipboard 读取;macOS 使用 `pbpaste`,Linux Wayland 使用 `wl-paste`,Linux X11 依次尝试 `xclip` 与 `xsel`。provider 使用仅 argv 的执行方式、短超时、完整字节上限和独立的图片 magic 校验;file-list 只解析本地 `file:` path。Windows、无头 SSH、缺少 utility 或媒体无效时只显示 live notice 并保留 draft,回退到 terminal paste 与 `@` 路径补全。剪贴板文本和已准入的图片 chip 作为一个 undo unit 插入。删除 placeholder 会移除其 payload;undo、redo、stash、已提交历史与 Agent view 切换都能保留 reference,而不挂载被粘贴的行。`Ctrl+R` 按从新到旧的顺序搜索当前 TUI 进程提交的去重 prompt;重复触发会选择更早的匹配,Enter 接受匹配,Escape 恢复原 draft 和确切光标。`Ctrl+S` 会暂存非空 draft、把它恢复到空 editor,或与另一个非空 draft 交换,因此恢复不会覆盖文本;每份 draft 保留自己的编辑历史。Prompt-history 搜索、暂存、paste reference 与编辑历史仅存在于当前进程,绝不进入 Session 日志。只含命令的斜杠查询会通过共享 suggestion controller 使用有效的 `ctx.commands.list(agent)` descriptor;旧版 Host 省略 additive discovery 字段时,compatibility catalog 会保留 TUI 自有的本地化 metadata,而确切匹配旧版 first-party 命令描述的条目会得到本地化 fallback,不会改写同名第三方文本。在 draft 开头或空白之后的 `@token` 会通过同一 controller 使用可取消的 workspace 结果:优先调用 Host 提供的 `ctx.fs.completePaths()`,旧版 Host 则通过 `listDir()` 与 `contains()` 执行等价的有界遍历。两条路径都以当前 Session workspace 为根;loading、无匹配和 truncated 状态保持有界,目录接受时保留尾部斜杠,文件接受时追加一个分隔空格。有界列表标出一个选中项;Up/Down 移动选中项而不遍历 prompt history,Shift+Tab 向前移动,Tab 或 Enter 接受选中的命令或路径,Escape 关闭列表但保留 draft。一个不可变 action registry 统一拥有有效的 Global、Composer、Suggestion、HistorySearch、TranscriptSearch、Transcript、Detail、Dialog、Footer、Work 与 Approval binding 及其输入优先级。`/help` 继续返回有效 command descriptor,同时打开由该 registry 生成的有界可滚动交互面板;不支持的 capability action 会被省略,`/help extra` 仍返回 usage error,Escape 会回到之前的本地模式。`Alt+P` 可打开现有 model picker,且不会替换当前 draft。以斜杠开头的输入会先尝试 `ctx.commands.execute()`;未匹配行仍作为普通提示提交,使 skill 手势继续走共享 Agent 路径。审批限定到确切的自有 Agent,只提供单次允许/拒绝。`ctx.userQuestions.registerProvider()` 提供 FIFO 结构化问题界面;即使 Agent 正在 running,其 Dialog 也拥有 Enter。
|
|
35
35
|
|
|
36
|
-
`/models` 会在 `ctx.llm.listProviders()` 及各提供方实时 `listModels()` 结果上打开有界、可滚动的选择器。声明了交互认证的提供方在尚未配置时显示为登录操作。首个原生流程是 OpenAI Codex:选择 **使用 ChatGPT 登录** 后,界面会通过官方 authorization owner 运行提供方自有的浏览器 OAuth flow,经 scoped credential-record owner 保存可刷新的 grant,刷新账户模型目录,再回到选择器。旧版 Host 会回退到 provider-neutral LLM authentication bridge,而不改变 UI 契约。模型声明可选 reasoning effort 时,第二个有界问题会选择一个确切等级。解析后的模型与 effort 会经 `
|
|
36
|
+
`/models` 会在 `ctx.llm.listProviders()` 及各提供方实时 `listModels()` 结果上打开有界、可滚动的选择器。声明了交互认证的提供方在尚未配置时显示为登录操作。首个原生流程是 OpenAI Codex:选择 **使用 ChatGPT 登录** 后,界面会通过官方 authorization owner 运行提供方自有的浏览器 OAuth flow,经 scoped credential-record owner 保存可刷新的 grant,刷新账户模型目录,再回到选择器。旧版 Host 会回退到 provider-neutral LLM authentication bridge,而不改变 UI 契约。模型声明可选 reasoning effort 时,第二个有界问题会选择一个确切等级。解析后的模型与 effort 会经 settings owner 持久化到 `tui.defaultModel`,成为自有 Agent 的下一步选择,并立即更新 idle header;已经运行中的 step 仍保留它捕获的选择。
|
|
37
37
|
|
|
38
38
|
`/mode` 会打开动态 `ctx.agentPresets` roster,其中包含本地化的 Standard(`standard`)、PTC(`ptc`)、Minimal(`minimal`)和 Creator(`cordis`)名称与说明,以及已经安装的 user preset。缺失和损坏的行会继续显示有界的禁用原因,但不会暴露 preset path。耐久记录旧 downstream `code` preset 的 Session 会按 PTC 解释,并且只有成功 recomposition 提交时才追加规范的 `ptc` selection。空白 Session 会在一项 single-flight transaction 中通过 `ctx.agentPresets.recompose()` 切换,并且只在新组装提交后追加 `agent-preset/selected`。第一次 `turn/start` 之后,选择操作会改为打开现有的新 Session 确认;Escape 会保持当前 Agent、draft、transcript anchor 与 footer,确认则会使用所选 preset 创建并发布新 Session,然后处置旧 handle。当前模式是可操作的 footer item;footer 与单选菜单行无论通过键盘还是 primary SGR click,都会使用同一项状态转换。本 package 只选择既有 preset,不会复制、编辑或移除 preset。
|
|
39
39
|
|
|
@@ -150,10 +150,13 @@ Registry 收录默认显示全部已接纳的目录记录,并按 Stars 排序
|
|
|
150
150
|
|
|
151
151
|
### 用户设置
|
|
152
152
|
|
|
153
|
+
新 TUI Agent 优先使用 `tui.defaultModel`,未设置时回退到 `agent-default-model`。`/models` 保持共享默认值不变。增强版 `lingxi-openai-codex` 路由使用 `llm-openai-codex/openai-codex` 凭据;官方 `openai-codex` 路由使用其自己的授权流程。 若共享默认值仍指向 `openai-codex`,且该官方路由未启用,请在启动 TUI 前把 `tui.defaultModel` 设置为 provider `lingxi-openai-codex` 和已有 model id,保持共享默认值与凭据记录不变。
|
|
154
|
+
|
|
153
155
|
挂载 `ctx.settings` 时,本包会注册 `tui` namespace。文件 provider 会把 theme、可选 custom-theme 文件、activity animation、`en`/`zh` locale、mouse ownership 和 keybinding override 持久化到共享用户设置文档;TUI 从不直接写该文件。locale catalog 带有版本号,缺失翻译键回退到英文,并对中英文使用同一套 terminal cell 有界规则。
|
|
154
156
|
|
|
155
157
|
| 键 | 默认值 | 行为 |
|
|
156
158
|
|---|---:|---|
|
|
159
|
+
| `defaultModel` | 未设置 | 新 Agent 专用的 TUI provider、model 及可选 reasoning effort。 |
|
|
157
160
|
| `theme` | `auto` | 选择 `auto` 跟随探测到的终端背景,或固定使用 `dark`、`light` 或 `no-color` 语义终端 token。 |
|
|
158
161
|
| `themeFile` | 未设置 | 从 `$DSH_HOME/themes` 按文件名加载一个声明式 JSON palette;路径穿越、symlink、超大文件、未知字段与不支持的颜色都会被拒绝。 |
|
|
159
162
|
| `locale` | `en` | 选择 first-party TUI 文案使用的 runtime catalog;`/lang` 会在不替换 Agent 或 view 的情况下切换该设置。 |
|
package/lib/index.js
CHANGED
|
@@ -13,11 +13,12 @@ import { dshHomePath } from "@deepseek-ai/dsh-home-paths";
|
|
|
13
13
|
import z from "@deepseek-ai/schemastery";
|
|
14
14
|
import { assembleContextFor, installModelSelection } from "@deepseek-ai/dsh-agent";
|
|
15
15
|
import { JobId } from "@deepseek-ai/dsh-jobs";
|
|
16
|
-
import { createUserMessage, errorChain, freezeMessage, normalizeApiKey } from "@deepseek-ai/dsh-llm";
|
|
16
|
+
import { ReasoningEffortId, createUserMessage, errorChain, freezeMessage, normalizeApiKey } from "@deepseek-ai/dsh-llm";
|
|
17
17
|
import { MessageId } from "@deepseek-ai/dsh-llm/brand";
|
|
18
18
|
import { runNativeCommand } from "@deepseek-ai/dsh-native-command";
|
|
19
19
|
import { isAppendSurfaceEvent } from "@deepseek-ai/dsh-session/surface";
|
|
20
|
-
import { SESSION_FORMAT_VERSION, SessionId } from "@deepseek-ai/dsh-session";
|
|
20
|
+
import { SESSION_FORMAT_VERSION, SessionId, SessionLogOffset } from "@deepseek-ai/dsh-session";
|
|
21
|
+
import { queueHostSubagentPrompt } from "@deepseek-ai/dsh-subagent/internal";
|
|
21
22
|
import { activeAtToken, formatFileMention } from "@deepseek-ai/dsh-file-reference";
|
|
22
23
|
import { formatSessionReferenceMention } from "@deepseek-ai/dsh-session-reference";
|
|
23
24
|
import { deriveTurnTokenUsage } from "@deepseek-ai/dsh-token-meter/client";
|
|
@@ -34,6 +35,17 @@ import { StringDecoder } from "node:string_decoder";
|
|
|
34
35
|
import { spawn } from "node:child_process";
|
|
35
36
|
import { tmpdir } from "node:os";
|
|
36
37
|
import { fileURLToPath } from "node:url";
|
|
38
|
+
//#region lib/types/exit.js
|
|
39
|
+
/**
|
|
40
|
+
* Hand terminal ownership back before starting the launcher's bounded teardown.
|
|
41
|
+
* @param releaseTerminal - Synchronous unmount and terminal restoration.
|
|
42
|
+
* @param exit - Launcher exit request, absent during owner disposal.
|
|
43
|
+
*/
|
|
44
|
+
function requestTuiExit(releaseTerminal, exit) {
|
|
45
|
+
releaseTerminal();
|
|
46
|
+
exit?.();
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
37
49
|
//#region lib/types/host.js
|
|
38
50
|
const SETTINGS_NAMESPACE_PATTERN = /^[a-z][a-z0-9-]*$/;
|
|
39
51
|
/** Validate and brand one dynamic settings namespace before calling the Host owner. */
|
|
@@ -41,7 +53,7 @@ function settingsNamespace(value) {
|
|
|
41
53
|
if (!SETTINGS_NAMESPACE_PATTERN.test(value)) throw new TypeError(`settings namespace "${value}" must match ${String(SETTINGS_NAMESPACE_PATTERN)}`);
|
|
42
54
|
return brandString(value);
|
|
43
55
|
}
|
|
44
|
-
/** Install one TUI settings section through the
|
|
56
|
+
/** Install one TUI settings section through the rc.1 owner method. */
|
|
45
57
|
function installSettingsSection(ctx, namespace, schema, entry, hooks) {
|
|
46
58
|
ctx.inject(["settings"], (settingsCtx) => {
|
|
47
59
|
settingsCtx.settings.installSection(ctx, namespace, schema, entry, hooks);
|
|
@@ -173,8 +185,7 @@ function authenticationLlm(host) {
|
|
|
173
185
|
function authorizationEntry(host, provider) {
|
|
174
186
|
const authorization = host.get("authorization");
|
|
175
187
|
if (authorization === void 0) return void 0;
|
|
176
|
-
|
|
177
|
-
return matches.find((entry) => credentialKeyScope(entry.key) === "llm-openai-codex") ?? matches[0];
|
|
188
|
+
return authorization.list().find((entry) => provider === "lingxi-openai-codex" ? credentialKeyScope(entry.key) === "llm-openai-codex" && credentialKeyId(entry.key) === "openai-codex" : credentialKeyScope(entry.key) !== "llm-openai-codex" && credentialKeyId(entry.key) === provider);
|
|
178
189
|
}
|
|
179
190
|
/**
|
|
180
191
|
* Read provider authentication when the Host exposes that optional seam.
|
|
@@ -6523,6 +6534,11 @@ const DEFAULT_TUI_SETTINGS = Object.freeze({
|
|
|
6523
6534
|
sessionManager: DEFAULT_TUI_SESSION_MANAGER_PREFERENCES
|
|
6524
6535
|
});
|
|
6525
6536
|
const TUI_SETTINGS_FIELDS = z.object({
|
|
6537
|
+
defaultModel: z.union([z.const(void 0), z.object({
|
|
6538
|
+
provider: z.string().required(),
|
|
6539
|
+
model: z.string().required(),
|
|
6540
|
+
reasoningEffort: z.string()
|
|
6541
|
+
})]),
|
|
6526
6542
|
theme: z.union([...TUI_THEME_PREFERENCES]).default(DEFAULT_TUI_SETTINGS.theme),
|
|
6527
6543
|
themeFile: z.string(),
|
|
6528
6544
|
locale: z.union([...TUI_LOCALES]).default(DEFAULT_TUI_SETTINGS.locale),
|
|
@@ -6553,6 +6569,11 @@ const TUI_SETTINGS_SCHEMA = z.transform(TUI_SETTINGS_FIELDS, (settings) => {
|
|
|
6553
6569
|
const themeFile = settings.themeFile?.trim();
|
|
6554
6570
|
if (themeFile !== void 0 && !/^[A-Za-z0-9][A-Za-z0-9._-]*\.json$/u.test(themeFile)) throw new Error("TUI themeFile must be one JSON file name under the Harness themes directory");
|
|
6555
6571
|
return {
|
|
6572
|
+
...settings.defaultModel == null ? {} : { defaultModel: {
|
|
6573
|
+
provider: settings.defaultModel.provider,
|
|
6574
|
+
model: settings.defaultModel.model,
|
|
6575
|
+
...settings.defaultModel.reasoningEffort == null ? {} : { reasoningEffort: ReasoningEffortId(settings.defaultModel.reasoningEffort) }
|
|
6576
|
+
} },
|
|
6556
6577
|
theme: settings.theme ?? DEFAULT_TUI_SETTINGS.theme,
|
|
6557
6578
|
...themeFile === void 0 || themeFile === "" ? {} : { themeFile },
|
|
6558
6579
|
locale: settings.locale ?? DEFAULT_TUI_SETTINGS.locale,
|
|
@@ -14073,16 +14094,33 @@ function tuiLoadedContextPanelLines(snapshot, width) {
|
|
|
14073
14094
|
/** Pure, bounded first-run guidance over public Host and provider facts. */
|
|
14074
14095
|
const GRAPHEMES$1 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
14075
14096
|
const NARROW_CONTENT_COLUMNS = 40;
|
|
14097
|
+
/** Stop waiting for a Host read even when that Host has no cancellation parameter. */
|
|
14098
|
+
async function cancellableRead(read, signal) {
|
|
14099
|
+
signal?.throwIfAborted();
|
|
14100
|
+
if (signal === void 0) return read();
|
|
14101
|
+
let abort = () => {};
|
|
14102
|
+
const cancelled = new Promise((_resolve, reject) => {
|
|
14103
|
+
abort = () => {
|
|
14104
|
+
reject(signal.reason instanceof Error ? signal.reason : new Error("Startup guidance cancelled", { cause: signal.reason }));
|
|
14105
|
+
};
|
|
14106
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
14107
|
+
});
|
|
14108
|
+
try {
|
|
14109
|
+
return await Promise.race([read(), cancelled]);
|
|
14110
|
+
} finally {
|
|
14111
|
+
signal.removeEventListener("abort", abort);
|
|
14112
|
+
}
|
|
14113
|
+
}
|
|
14076
14114
|
/**
|
|
14077
14115
|
* Inspect one selected provider without retaining credentials or raw failures.
|
|
14078
14116
|
* @param provider - registered provider identity and display name.
|
|
14079
14117
|
* @param inspector - public authentication and model-catalog reads.
|
|
14080
|
-
* @param signal - cancellation
|
|
14118
|
+
* @param signal - cancellation stops waiting for provider-owned asynchronous reads.
|
|
14081
14119
|
* @returns configured, unconfigured, or contained-failure state.
|
|
14082
14120
|
*/
|
|
14083
14121
|
async function inspectTuiStartupProvider(provider, inspector, signal) {
|
|
14084
14122
|
try {
|
|
14085
|
-
const authentication = await inspector.authentication(provider.id);
|
|
14123
|
+
const authentication = await cancellableRead(() => inspector.authentication(provider.id), signal);
|
|
14086
14124
|
signal?.throwIfAborted();
|
|
14087
14125
|
if (!authentication.configured) return Object.freeze({
|
|
14088
14126
|
state: "unconfigured",
|
|
@@ -14090,7 +14128,7 @@ async function inspectTuiStartupProvider(provider, inspector, signal) {
|
|
|
14090
14128
|
name: provider.name,
|
|
14091
14129
|
...authentication.methods[0]?.name === void 0 ? {} : { method: authentication.methods[0].name }
|
|
14092
14130
|
});
|
|
14093
|
-
const models = await inspector.listModels(provider.id);
|
|
14131
|
+
const models = await cancellableRead(() => inspector.listModels(provider.id), signal);
|
|
14094
14132
|
signal?.throwIfAborted();
|
|
14095
14133
|
return Object.freeze({
|
|
14096
14134
|
state: "configured",
|
|
@@ -27296,7 +27334,7 @@ var TuiController = class {
|
|
|
27296
27334
|
return;
|
|
27297
27335
|
}
|
|
27298
27336
|
this.handle = handle;
|
|
27299
|
-
this.events = new SessionEventStore(handle.agent.session.
|
|
27337
|
+
this.events = new SessionEventStore(handle.agent.session.snapshotEvents());
|
|
27300
27338
|
this.status = new AgentStatusStore(handle.agent.status);
|
|
27301
27339
|
this.selection = prepared.selection;
|
|
27302
27340
|
this.modelSelection.set(prepared.selectedModel);
|
|
@@ -27331,14 +27369,16 @@ var TuiController = class {
|
|
|
27331
27369
|
const pluginHub = this.ctx.get("pluginHub");
|
|
27332
27370
|
if (pluginHub !== void 0 && pluginHub.hasProvider()) await pluginHub.markMaintenanceReady();
|
|
27333
27371
|
await this.instance.waitUntilExit();
|
|
27372
|
+
this.requestExit(this.requestedExit);
|
|
27334
27373
|
await this.shutdown();
|
|
27335
27374
|
if (!this.isOwnerDisposed()) this.ctx.get("appExit")?.(this.requestedExit);
|
|
27336
27375
|
} catch (error) {
|
|
27337
|
-
await this.shutdown();
|
|
27338
27376
|
if (!this.ownerDisposed) {
|
|
27377
|
+
this.terminal.restore();
|
|
27339
27378
|
terminalInternals.stderr.write(`dsh --profile tui: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
27340
|
-
this.ctx.get("appExit")?.(1);
|
|
27341
27379
|
}
|
|
27380
|
+
this.requestExit(1);
|
|
27381
|
+
await this.shutdown();
|
|
27342
27382
|
}
|
|
27343
27383
|
}
|
|
27344
27384
|
appElement(root, rootEvents, rootStatus) {
|
|
@@ -27775,7 +27815,7 @@ var TuiController = class {
|
|
|
27775
27815
|
const presets = hostAgentPresets(this.ctx);
|
|
27776
27816
|
const requestedPreset = request.kind === "resume" ? void 0 : request.preset;
|
|
27777
27817
|
const resolvedPreset = request.kind === "resume" ? void 0 : await presets.resolve(requestedPreset);
|
|
27778
|
-
const configuredSelection = request.kind === "fresh" || request.kind === "rewind" ? request.selection : defaultModel.currentSelection();
|
|
27818
|
+
const configuredSelection = request.kind === "fresh" || request.kind === "rewind" ? request.selection : this.settingsSource().defaultModel ?? defaultModel.currentSelection();
|
|
27779
27819
|
const resolvedDefault = await this.ctx.llm.resolveCallConfig(configuredSelection, signal);
|
|
27780
27820
|
const defaultSelection = {
|
|
27781
27821
|
provider: resolvedDefault.provider,
|
|
@@ -27791,8 +27831,11 @@ var TuiController = class {
|
|
|
27791
27831
|
const setup = async (agentCtx) => {
|
|
27792
27832
|
const session = agentCtx.agent?.session;
|
|
27793
27833
|
if (session === void 0) throw new Error("TUI Agent setup cannot resolve its unpublished Session");
|
|
27794
|
-
const presetId = request.kind === "resume" ? this.assertResumeCompatible(session.header, session.
|
|
27795
|
-
migration.legacyPreset = request.kind === "resume" && sessionUsesLegacyCodePreset(
|
|
27834
|
+
const presetId = request.kind === "resume" ? this.assertResumeCompatible(session.header, session.snapshotEvents()) : resolvedPreset?.id;
|
|
27835
|
+
migration.legacyPreset = request.kind === "resume" && sessionUsesLegacyCodePreset({
|
|
27836
|
+
header: session.header,
|
|
27837
|
+
events: session.snapshotEvents()
|
|
27838
|
+
});
|
|
27796
27839
|
if (presetId === void 0) throw new Error("TUI Agent setup has no resolved Agent preset");
|
|
27797
27840
|
const logged = session.requestHeader()?.config;
|
|
27798
27841
|
if (logged !== void 0) selected.current = {
|
|
@@ -27801,7 +27844,7 @@ var TuiController = class {
|
|
|
27801
27844
|
...logged.reasoningEffort === void 0 ? {} : { reasoningEffort: logged.reasoningEffort }
|
|
27802
27845
|
};
|
|
27803
27846
|
else if (request.kind === "resume") {
|
|
27804
|
-
const route = resumeRoute(session.
|
|
27847
|
+
const route = resumeRoute(session.snapshotEvents());
|
|
27805
27848
|
if (route !== void 0) selected.current = route;
|
|
27806
27849
|
}
|
|
27807
27850
|
installModelSelection(agentCtx, selected);
|
|
@@ -27831,9 +27874,12 @@ var TuiController = class {
|
|
|
27831
27874
|
cwd: request.cwd,
|
|
27832
27875
|
agentPreset: resolvedPreset.id,
|
|
27833
27876
|
parentSession: request.parentSession,
|
|
27834
|
-
|
|
27877
|
+
isSeeded: true
|
|
27835
27878
|
},
|
|
27836
|
-
...request.kind === "rewind" ? {
|
|
27879
|
+
...request.kind === "rewind" ? {
|
|
27880
|
+
seed: request.seed,
|
|
27881
|
+
inheritedEventCount: SessionLogOffset(request.seed.length)
|
|
27882
|
+
} : {},
|
|
27837
27883
|
agentOptions: {
|
|
27838
27884
|
provider: defaultSelection.provider,
|
|
27839
27885
|
model: defaultSelection.model
|
|
@@ -28395,7 +28441,7 @@ var TuiController = class {
|
|
|
28395
28441
|
acceptsInput: true
|
|
28396
28442
|
}),
|
|
28397
28443
|
agent: child,
|
|
28398
|
-
events: new SessionEventStore(child.session.
|
|
28444
|
+
events: new SessionEventStore(child.session.snapshotEvents()),
|
|
28399
28445
|
status: new AgentStatusStore(child.status)
|
|
28400
28446
|
};
|
|
28401
28447
|
try {
|
|
@@ -29937,7 +29983,10 @@ var TuiController = class {
|
|
|
29937
29983
|
text: tuiMessage(this.locale, "plugin.command.dialog")
|
|
29938
29984
|
};
|
|
29939
29985
|
const presets = hostAgentPresets(this.ctx);
|
|
29940
|
-
const currentId = resolveSessionPreset(
|
|
29986
|
+
const currentId = resolveSessionPreset({
|
|
29987
|
+
header: invocation.agent.session.header,
|
|
29988
|
+
events: invocation.agent.session.snapshotEvents()
|
|
29989
|
+
}) ?? presets.composedPreset(invocation.agent.ctx);
|
|
29941
29990
|
if (currentId === void 0) throw new Error("The active TUI Agent has no composed preset");
|
|
29942
29991
|
const roster = tuiAgentModeOptions(await presets.list(), currentId, this.locale);
|
|
29943
29992
|
const options = Object.freeze([...roster.filter((option) => option.preset.id === currentId), ...roster.filter((option) => option.preset.id !== currentId)]);
|
|
@@ -29969,7 +30018,7 @@ var TuiController = class {
|
|
|
29969
30018
|
kind: "success",
|
|
29970
30019
|
text: tuiMessage(this.locale, "mode.same", { mode: selected.name })
|
|
29971
30020
|
};
|
|
29972
|
-
if (invocation.agent.session.
|
|
30021
|
+
if (invocation.agent.session.snapshotEvents().some((event) => event.type === "turn/start")) {
|
|
29973
30022
|
const cwd = invocation.agent.session.header.cwd;
|
|
29974
30023
|
if (cwd === void 0) return {
|
|
29975
30024
|
kind: "error",
|
|
@@ -30444,7 +30493,7 @@ var TuiController = class {
|
|
|
30444
30493
|
this.rewindDialog.set({
|
|
30445
30494
|
...dialog,
|
|
30446
30495
|
phase: "browsing",
|
|
30447
|
-
candidates: tuiRewindCandidates(agent.session.
|
|
30496
|
+
candidates: tuiRewindCandidates(agent.session.snapshotEvents())
|
|
30448
30497
|
});
|
|
30449
30498
|
}
|
|
30450
30499
|
closeRewind() {
|
|
@@ -30474,10 +30523,13 @@ var TuiController = class {
|
|
|
30474
30523
|
}
|
|
30475
30524
|
const detached = this.detachedRewindSource?.id === dialog.currentSessionId ? this.detachedRewindSource : void 0;
|
|
30476
30525
|
const sourceId = detached?.id ?? agent.session.id;
|
|
30477
|
-
const sourceEvents = detached?.events ?? agent.session.
|
|
30526
|
+
const sourceEvents = detached?.events ?? agent.session.snapshotEvents();
|
|
30478
30527
|
const cwd = detached?.cwd ?? agent.session.header.cwd;
|
|
30479
30528
|
const selectedModel = detached?.selection ?? this.selection?.current ?? this.modelSelection.getSnapshot();
|
|
30480
|
-
const preset = detached?.preset ?? resolveSessionPreset(
|
|
30529
|
+
const preset = detached?.preset ?? resolveSessionPreset({
|
|
30530
|
+
header: agent.session.header,
|
|
30531
|
+
events: agent.session.snapshotEvents()
|
|
30532
|
+
});
|
|
30481
30533
|
if (cwd === void 0 || selectedModel === void 0) {
|
|
30482
30534
|
this.rewindDialog.set({
|
|
30483
30535
|
...dialog,
|
|
@@ -30990,7 +31042,7 @@ var TuiController = class {
|
|
|
30990
31042
|
openTrajectory() {
|
|
30991
31043
|
const root = this.handle?.agent;
|
|
30992
31044
|
if (root === void 0) return;
|
|
30993
|
-
const events = root.session.
|
|
31045
|
+
const events = root.session.snapshotEvents();
|
|
30994
31046
|
const snapshot = this.trajectoryProjection.update(events, this.trajectoryLimit);
|
|
30995
31047
|
this.trajectoryStore.set(snapshot);
|
|
30996
31048
|
}
|
|
@@ -31159,7 +31211,7 @@ var TuiController = class {
|
|
|
31159
31211
|
const live = this.ctx.sessions.get(id);
|
|
31160
31212
|
const source = live === void 0 ? await this.ctx.sessionQuery.readSession(id) : {
|
|
31161
31213
|
session: live.header,
|
|
31162
|
-
events: live.
|
|
31214
|
+
events: live.snapshotEvents()
|
|
31163
31215
|
};
|
|
31164
31216
|
if (source.session.version !== SESSION_FORMAT_VERSION) throw new Error("the source Session format is incompatible");
|
|
31165
31217
|
if (source.session.origin === "subagent") throw new Error("subagent-owned Sessions cannot be forked here");
|
|
@@ -31289,7 +31341,7 @@ var TuiController = class {
|
|
|
31289
31341
|
const live = this.ctx.sessions.get(record.header.id);
|
|
31290
31342
|
const session = live === void 0 ? await this.ctx.sessionQuery.readSession(record.header.id) : {
|
|
31291
31343
|
session: live.header,
|
|
31292
|
-
events: live.
|
|
31344
|
+
events: live.snapshotEvents()
|
|
31293
31345
|
};
|
|
31294
31346
|
signal.throwIfAborted();
|
|
31295
31347
|
const id = resolveSessionPreset({
|
|
@@ -31389,7 +31441,7 @@ var TuiController = class {
|
|
|
31389
31441
|
async resumeActivityTime(record, signal) {
|
|
31390
31442
|
signal.throwIfAborted();
|
|
31391
31443
|
const live = this.ctx.sessions.get(record.header.id);
|
|
31392
|
-
if (live !== void 0) return live.
|
|
31444
|
+
if (live !== void 0) return live.snapshotEvents().at(-1)?.time;
|
|
31393
31445
|
const location = this.ctx.get("sessionPersistence")?.locate(record.header);
|
|
31394
31446
|
if (location === void 0) return void 0;
|
|
31395
31447
|
try {
|
|
@@ -31443,7 +31495,7 @@ var TuiController = class {
|
|
|
31443
31495
|
async projectedResumeTitle(cache, record, signal) {
|
|
31444
31496
|
const live = this.ctx.sessions.get(record.header.id);
|
|
31445
31497
|
if (live !== void 0) return this.ctx.get("sessionProjections")?.snapshot(live).values.title;
|
|
31446
|
-
const cached = cache.cachedSnapshot(record.header);
|
|
31498
|
+
const cached = record.header.isSeeded ? void 0 : cache.cachedSnapshot(record.header, SessionLogOffset(0), ["title"]);
|
|
31447
31499
|
if (cached !== void 0 && "title" in cached.values) return cached.values.title;
|
|
31448
31500
|
const observation = await this.ctx.sessionQuery.observeSession(record.header.id, { signal });
|
|
31449
31501
|
try {
|
|
@@ -31626,7 +31678,10 @@ var TuiController = class {
|
|
|
31626
31678
|
if (!this.ownsAgent(oldAgent)) throw new Error("the active TUI Session changed");
|
|
31627
31679
|
const initialStatus = this.agentStatus(oldAgent);
|
|
31628
31680
|
if (initialStatus !== "idle") throw new Error(`current Agent is ${initialStatus}`);
|
|
31629
|
-
const preset = targetPreset?.id ?? resolveSessionPreset(
|
|
31681
|
+
const preset = targetPreset?.id ?? resolveSessionPreset({
|
|
31682
|
+
header: oldAgent.session.header,
|
|
31683
|
+
events: oldAgent.session.snapshotEvents()
|
|
31684
|
+
});
|
|
31630
31685
|
if (preset === void 0) throw new Error("the current Session has no Agent preset to inherit");
|
|
31631
31686
|
const prepared = await this.prepareAgent({
|
|
31632
31687
|
kind: "fresh",
|
|
@@ -31688,7 +31743,7 @@ var TuiController = class {
|
|
|
31688
31743
|
const oldExportDialog = this.sessionExportDialog.getSnapshot();
|
|
31689
31744
|
const oldActiveView = this.activeView;
|
|
31690
31745
|
if (oldHandle?.agent !== oldAgent || oldEvents === void 0 || oldStatus === void 0 || this.instance === void 0) throw new Error("TUI Agent switch lost its current owner");
|
|
31691
|
-
const nextEvents = new SessionEventStore(prepared.handle.agent.session.
|
|
31746
|
+
const nextEvents = new SessionEventStore(prepared.handle.agent.session.snapshotEvents());
|
|
31692
31747
|
const nextStatus = new AgentStatusStore(prepared.handle.agent.status);
|
|
31693
31748
|
this.handle = prepared.handle;
|
|
31694
31749
|
this.events = nextEvents;
|
|
@@ -31986,7 +32041,7 @@ var TuiController = class {
|
|
|
31986
32041
|
...resolved.reasoningEffort === void 0 ? {} : { reasoningEffort: resolved.reasoningEffort }
|
|
31987
32042
|
};
|
|
31988
32043
|
if (this.selection === void 0) throw new Error("TUI model selection is unavailable before Agent setup");
|
|
31989
|
-
await this.ctx.
|
|
32044
|
+
await this.ctx.get("settings")?.update(TUI_SETTINGS_NAMESPACE, { defaultModel: selected });
|
|
31990
32045
|
invocation.signal.throwIfAborted();
|
|
31991
32046
|
this.selection.current = selected;
|
|
31992
32047
|
this.modelSelection.set(selected);
|
|
@@ -32127,13 +32182,10 @@ var TuiController = class {
|
|
|
32127
32182
|
}
|
|
32128
32183
|
}
|
|
32129
32184
|
const controller = new AbortController();
|
|
32130
|
-
const completion = this.ctx.subagents
|
|
32185
|
+
const completion = queueHostSubagentPrompt(this.ctx.subagents, parent, view.agent.id, [{
|
|
32131
32186
|
type: "text",
|
|
32132
32187
|
text
|
|
32133
|
-
}, ...imageBlocks], {
|
|
32134
|
-
source: { kind: "user" },
|
|
32135
|
-
signal: controller.signal
|
|
32136
|
-
});
|
|
32188
|
+
}, ...imageBlocks], { kind: "user" }, controller.signal);
|
|
32137
32189
|
const operation = {
|
|
32138
32190
|
controller,
|
|
32139
32191
|
completion
|
|
@@ -32148,7 +32200,12 @@ var TuiController = class {
|
|
|
32148
32200
|
requestExit(code) {
|
|
32149
32201
|
this.requestedExit = Math.max(this.requestedExit, code);
|
|
32150
32202
|
this.terminal.setInputCursor(void 0);
|
|
32151
|
-
|
|
32203
|
+
requestTuiExit(() => {
|
|
32204
|
+
this.instance?.unmount();
|
|
32205
|
+
this.terminal.restore();
|
|
32206
|
+
}, this.ownerDisposed ? void 0 : () => {
|
|
32207
|
+
this.ctx.get("appExit")?.(this.requestedExit);
|
|
32208
|
+
});
|
|
32152
32209
|
}
|
|
32153
32210
|
isOwnerDisposed() {
|
|
32154
32211
|
return this.ownerDisposed;
|
|
@@ -32279,7 +32336,21 @@ var TuiController = class {
|
|
|
32279
32336
|
this.disposers.sessionEvents?.();
|
|
32280
32337
|
this.disposers.questionProvider?.();
|
|
32281
32338
|
this.terminal.restore();
|
|
32339
|
+
const releaseAgent = async () => {
|
|
32340
|
+
await activeAgentSwitch?.completion.catch(() => void 0);
|
|
32341
|
+
const handle = this.handle;
|
|
32342
|
+
this.handle = void 0;
|
|
32343
|
+
this.events = void 0;
|
|
32344
|
+
this.status = void 0;
|
|
32345
|
+
if (handle !== void 0) {
|
|
32346
|
+
if (handle.agent.status === "running") handle.agent.cancel({ kind: "disposed" });
|
|
32347
|
+
await handle.agent.whenIdle().catch(() => void 0);
|
|
32348
|
+
await this.ctx.get("sessions")?.flush(handle.agent.session).catch(() => void 0);
|
|
32349
|
+
await handle.dispose().catch(() => void 0);
|
|
32350
|
+
}
|
|
32351
|
+
};
|
|
32282
32352
|
await Promise.all([
|
|
32353
|
+
releaseAgent(),
|
|
32283
32354
|
activeCommand?.completion.catch(() => void 0),
|
|
32284
32355
|
startupGuidanceRefresh?.completion.catch(() => void 0),
|
|
32285
32356
|
activeSessionExport?.completion.catch(() => void 0),
|
|
@@ -32294,16 +32365,6 @@ var TuiController = class {
|
|
|
32294
32365
|
updateCheck?.completion.catch(() => void 0),
|
|
32295
32366
|
themeLoad?.completion.catch(() => void 0)
|
|
32296
32367
|
]);
|
|
32297
|
-
const handle = this.handle;
|
|
32298
|
-
this.handle = void 0;
|
|
32299
|
-
this.events = void 0;
|
|
32300
|
-
this.status = void 0;
|
|
32301
|
-
if (handle !== void 0) {
|
|
32302
|
-
if (handle.agent.status === "running") handle.agent.cancel({ kind: "disposed" });
|
|
32303
|
-
await handle.agent.whenIdle().catch(() => void 0);
|
|
32304
|
-
await this.ctx.get("sessions")?.flush(handle.agent.session).catch(() => void 0);
|
|
32305
|
-
await handle.dispose().catch(() => void 0);
|
|
32306
|
-
}
|
|
32307
32368
|
}
|
|
32308
32369
|
};
|
|
32309
32370
|
function resumeRoute(events) {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hand terminal ownership back before starting the launcher's bounded teardown.
|
|
3
|
+
* @param releaseTerminal - Synchronous unmount and terminal restoration.
|
|
4
|
+
* @param exit - Launcher exit request, absent during owner disposal.
|
|
5
|
+
*/
|
|
6
|
+
export declare function requestTuiExit(releaseTerminal: () => void, exit: (() => void) | undefined): void;
|
|
7
|
+
//# sourceMappingURL=exit.d.ts.map
|
package/lib/types/host.d.ts
CHANGED
|
@@ -31,18 +31,19 @@ export type { AgentPreset, AgentPresetComposition, AgentPresetCompositionRow, }
|
|
|
31
31
|
export type { CommandInvocation, CommandResult } from '@deepseek-ai/dsh-commands';
|
|
32
32
|
export { JobId } from '@deepseek-ai/dsh-jobs';
|
|
33
33
|
export type { JobSnapshot, JobStatus } from '@deepseek-ai/dsh-jobs';
|
|
34
|
-
export { createUserMessage, errorChain, freezeMessage, normalizeApiKey } from '@deepseek-ai/dsh-llm';
|
|
34
|
+
export { createUserMessage, errorChain, freezeMessage, normalizeApiKey, ReasoningEffortId } from '@deepseek-ai/dsh-llm';
|
|
35
35
|
export type { ContentBlock, LlmConfigurableProvider, LlmDiscoveredModel, LlmModelDiscoveryRequest, StreamChunk, TokenUsage, UserMessage, } from '@deepseek-ai/dsh-llm';
|
|
36
36
|
export { MessageId } from '@deepseek-ai/dsh-llm/brand';
|
|
37
37
|
export { runNativeCommand } from '@deepseek-ai/dsh-native-command';
|
|
38
38
|
export type { PermissionSelect } from '@deepseek-ai/dsh-permission-presets';
|
|
39
39
|
export { isAppendSurfaceEvent, } from '@deepseek-ai/dsh-session/surface';
|
|
40
|
-
export { SESSION_FORMAT_VERSION, SessionId, } from '@deepseek-ai/dsh-session';
|
|
40
|
+
export { SESSION_FORMAT_VERSION, SessionId, SessionLogOffset, } from '@deepseek-ai/dsh-session';
|
|
41
41
|
export type { SessionEvent, SessionHeader, SessionId as SessionIdType, TurnEndReason } from '@deepseek-ai/dsh-session';
|
|
42
42
|
export type { SessionPersistence } from '@deepseek-ai/dsh-session-persistence';
|
|
43
43
|
export type { TodoItem } from '@deepseek-ai/dsh-tool-todo';
|
|
44
44
|
export type { SessionProjectionCache } from '@deepseek-ai/dsh-session-projection-cache';
|
|
45
45
|
export type { SessionRecord } from '@deepseek-ai/dsh-session-query';
|
|
46
|
+
export { queueHostSubagentPrompt } from '@deepseek-ai/dsh-subagent/internal';
|
|
46
47
|
export type { SettingsDescriptor, SettingsNamespace, SettingsPathOp, SettingsProvider, } from '@deepseek-ai/dsh-settings';
|
|
47
48
|
export { activeAtToken, formatFileMention } from '@deepseek-ai/dsh-file-reference';
|
|
48
49
|
export type { FileReferenceCandidate } from '@deepseek-ai/dsh-file-reference';
|
|
@@ -60,7 +61,7 @@ export interface TuiSettingsSectionHooks<T> {
|
|
|
60
61
|
/** Refuse a resolved settings section the TUI cannot apply. */
|
|
61
62
|
validate?: (value: T) => void;
|
|
62
63
|
}
|
|
63
|
-
/** Install one TUI settings section through the
|
|
64
|
+
/** Install one TUI settings section through the rc.1 owner method. */
|
|
64
65
|
export declare function installSettingsSection<T>(ctx: HostContext, namespace: string, schema: z<T>, entry: T, hooks: TuiSettingsSectionHooks<T>): void;
|
|
65
66
|
/** Resolve the shared Host settings owner through the reviewed adapter boundary. */
|
|
66
67
|
export declare function hostSettings(ctx: HostContext): import('@deepseek-ai/dsh-settings').SettingsProvider;
|
|
@@ -52,7 +52,7 @@ export interface TuiStartupProviderInspector {
|
|
|
52
52
|
* Inspect one selected provider without retaining credentials or raw failures.
|
|
53
53
|
* @param provider - registered provider identity and display name.
|
|
54
54
|
* @param inspector - public authentication and model-catalog reads.
|
|
55
|
-
* @param signal - cancellation
|
|
55
|
+
* @param signal - cancellation stops waiting for provider-owned asynchronous reads.
|
|
56
56
|
* @returns configured, unconfigured, or contained-failure state.
|
|
57
57
|
*/
|
|
58
58
|
export declare function inspectTuiStartupProvider(provider: Readonly<{
|
package/lib/types/theme.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** Semantic terminal colors and user settings for the native TUI. */
|
|
2
2
|
import React, { type ReactNode } from 'react';
|
|
3
|
-
import { z } from './host.ts';
|
|
3
|
+
import { z, type ModelSelection } from './host.ts';
|
|
4
4
|
import { type TuiKeybindingOverrides } from './keybindings.ts';
|
|
5
5
|
import { TUI_LOCALES, type TuiLocale } from './locale.ts';
|
|
6
6
|
import type { TuiTerminalBackground, TuiTerminalColorDepth } from './terminal-session.ts';
|
|
@@ -28,6 +28,8 @@ export declare const TUI_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings")
|
|
|
28
28
|
export declare const TUI_PROVIDER_ONBOARDING_VERSION: 1;
|
|
29
29
|
/** User settings consumed live by the native TUI. */
|
|
30
30
|
export interface TuiSettings {
|
|
31
|
+
/** Default for new TUI Agents; never changes the shared Web model selection. */
|
|
32
|
+
defaultModel?: ModelSelection;
|
|
31
33
|
/** Built-in semantic terminal theme. */
|
|
32
34
|
theme: TuiThemePreference;
|
|
33
35
|
/** Optional JSON file name under the Harness home `themes` directory. */
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lingxi-ai-cn/dsh-tui-runtime",
|
|
3
3
|
"description": "Native terminal UI for one in-process DeepSeek Harness Agent and Session",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.9-rc.1",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -40,53 +40,53 @@
|
|
|
40
40
|
"string-width": "^7.2.0"
|
|
41
41
|
},
|
|
42
42
|
"peerDependencies": {
|
|
43
|
-
"@deepseek-ai/dsh-brand": "0.1.2-
|
|
44
|
-
"@deepseek-ai/dsh-attachment": "0.1.2-
|
|
45
|
-
"@deepseek-ai/dsh-authorization": "0.1.2-
|
|
43
|
+
"@deepseek-ai/dsh-brand": "0.1.2-rc.1",
|
|
44
|
+
"@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
|
|
45
|
+
"@deepseek-ai/dsh-authorization": "0.1.2-rc.1",
|
|
46
46
|
"@deepseek-ai/cordis-plugin-loader": "1.0.3",
|
|
47
|
-
"@deepseek-ai/dsh-agent": "0.1.2-
|
|
48
|
-
"@deepseek-ai/dsh-agent-default-model": "0.1.2-
|
|
49
|
-
"@deepseek-ai/dsh-agent-presets": "0.1.2-
|
|
50
|
-
"@deepseek-ai/dsh-atomic-write": "0.1.2-
|
|
51
|
-
"@deepseek-ai/dsh-cmdline": "0.1.2-
|
|
52
|
-
"@deepseek-ai/dsh-compaction": "0.1.2-
|
|
53
|
-
"@deepseek-ai/dsh-commands": "0.1.2-
|
|
54
|
-
"@deepseek-ai/dsh-credentials": "0.1.2-
|
|
55
|
-
"@deepseek-ai/dsh-fs": "0.1.2-
|
|
56
|
-
"@deepseek-ai/dsh-file-reference": "0.1.2-
|
|
57
|
-
"@deepseek-ai/dsh-home-paths": "0.1.2-
|
|
58
|
-
"@deepseek-ai/dsh-host-directory-picker": "0.1.2-
|
|
59
|
-
"@deepseek-ai/dsh-host-plugin-inventory": "0.1.2-
|
|
60
|
-
"@deepseek-ai/dsh-goal": "0.1.2-
|
|
61
|
-
"@deepseek-ai/dsh-invariants": "0.1.2-
|
|
62
|
-
"@deepseek-ai/dsh-jobs": "0.1.2-
|
|
63
|
-
"@deepseek-ai/dsh-llm": "0.1.2-
|
|
64
|
-
"@deepseek-ai/dsh-message-feedback": "0.1.2-
|
|
65
|
-
"@deepseek-ai/dsh-native-command": "0.1.2-
|
|
66
|
-
"@deepseek-ai/dsh-permission-presets": "0.1.2-
|
|
67
|
-
"@deepseek-ai/dsh-plan-mode": "0.1.2-
|
|
68
|
-
"@deepseek-ai/dsh-session": "0.1.2-
|
|
69
|
-
"@deepseek-ai/dsh-session-projection": "0.1.2-
|
|
70
|
-
"@deepseek-ai/dsh-session-projection-cache": "0.1.2-
|
|
71
|
-
"@deepseek-ai/dsh-session-stats": "0.1.2-
|
|
72
|
-
"@deepseek-ai/dsh-session-query": "0.1.2-
|
|
73
|
-
"@deepseek-ai/dsh-session-reference": "0.1.2-
|
|
74
|
-
"@deepseek-ai/dsh-schedule": "0.1.2-
|
|
75
|
-
"@deepseek-ai/dsh-session-title": "0.1.2-
|
|
76
|
-
"@deepseek-ai/dsh-settings": "0.1.2-
|
|
77
|
-
"@deepseek-ai/dsh-subagent": "0.1.2-
|
|
78
|
-
"@deepseek-ai/dsh-token-meter": "0.1.2-
|
|
79
|
-
"@deepseek-ai/dsh-tool-todo": "0.1.2-
|
|
80
|
-
"@deepseek-ai/dsh-tools": "0.1.2-
|
|
81
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.2-
|
|
82
|
-
"@deepseek-ai/dsh-subprocess": "0.1.2-
|
|
83
|
-
"@deepseek-ai/dsh-user-approval": "0.1.2-
|
|
84
|
-
"@deepseek-ai/dsh-user-questions": "0.1.2-
|
|
85
|
-
"@deepseek-ai/dsh-workspace": "0.1.2-
|
|
47
|
+
"@deepseek-ai/dsh-agent": "0.1.2-rc.1",
|
|
48
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.2-rc.1",
|
|
49
|
+
"@deepseek-ai/dsh-agent-presets": "0.1.2-rc.1",
|
|
50
|
+
"@deepseek-ai/dsh-atomic-write": "0.1.2-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-cmdline": "0.1.2-rc.1",
|
|
52
|
+
"@deepseek-ai/dsh-compaction": "0.1.2-rc.1",
|
|
53
|
+
"@deepseek-ai/dsh-commands": "0.1.2-rc.1",
|
|
54
|
+
"@deepseek-ai/dsh-credentials": "0.1.2-rc.1",
|
|
55
|
+
"@deepseek-ai/dsh-fs": "0.1.2-rc.1",
|
|
56
|
+
"@deepseek-ai/dsh-file-reference": "0.1.2-rc.1",
|
|
57
|
+
"@deepseek-ai/dsh-home-paths": "0.1.2-rc.1",
|
|
58
|
+
"@deepseek-ai/dsh-host-directory-picker": "0.1.2-rc.1",
|
|
59
|
+
"@deepseek-ai/dsh-host-plugin-inventory": "0.1.2-rc.1",
|
|
60
|
+
"@deepseek-ai/dsh-goal": "0.1.2-rc.1",
|
|
61
|
+
"@deepseek-ai/dsh-invariants": "0.1.2-rc.1",
|
|
62
|
+
"@deepseek-ai/dsh-jobs": "0.1.2-rc.1",
|
|
63
|
+
"@deepseek-ai/dsh-llm": "0.1.2-rc.1",
|
|
64
|
+
"@deepseek-ai/dsh-message-feedback": "0.1.2-rc.1",
|
|
65
|
+
"@deepseek-ai/dsh-native-command": "0.1.2-rc.1",
|
|
66
|
+
"@deepseek-ai/dsh-permission-presets": "0.1.2-rc.1",
|
|
67
|
+
"@deepseek-ai/dsh-plan-mode": "0.1.2-rc.1",
|
|
68
|
+
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
|
|
69
|
+
"@deepseek-ai/dsh-session-projection": "0.1.2-rc.1",
|
|
70
|
+
"@deepseek-ai/dsh-session-projection-cache": "0.1.2-rc.1",
|
|
71
|
+
"@deepseek-ai/dsh-session-stats": "0.1.2-rc.1",
|
|
72
|
+
"@deepseek-ai/dsh-session-query": "0.1.2-rc.1",
|
|
73
|
+
"@deepseek-ai/dsh-session-reference": "0.1.2-rc.1",
|
|
74
|
+
"@deepseek-ai/dsh-schedule": "0.1.2-rc.1",
|
|
75
|
+
"@deepseek-ai/dsh-session-title": "0.1.2-rc.1",
|
|
76
|
+
"@deepseek-ai/dsh-settings": "0.1.2-rc.1",
|
|
77
|
+
"@deepseek-ai/dsh-subagent": "0.1.2-rc.1",
|
|
78
|
+
"@deepseek-ai/dsh-token-meter": "0.1.2-rc.1",
|
|
79
|
+
"@deepseek-ai/dsh-tool-todo": "0.1.2-rc.1",
|
|
80
|
+
"@deepseek-ai/dsh-tools": "0.1.2-rc.1",
|
|
81
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.2-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-subprocess": "0.1.2-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-user-approval": "0.1.2-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-user-questions": "0.1.2-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-workspace": "0.1.2-rc.1",
|
|
86
86
|
"@deepseek-ai/cordis": "4.0.2",
|
|
87
87
|
"@deepseek-ai/schemastery": "3.18.2",
|
|
88
|
-
"@lingxi-ai-cn/dsh-session-export": "0.1.
|
|
89
|
-
"@lingxi-ai-cn/dsh-plugin-hub": "0.1.
|
|
88
|
+
"@lingxi-ai-cn/dsh-session-export": "0.1.9-rc.1",
|
|
89
|
+
"@lingxi-ai-cn/dsh-plugin-hub": "0.1.9-rc.1"
|
|
90
90
|
},
|
|
91
91
|
"peerDependenciesMeta": {
|
|
92
92
|
"@deepseek-ai/dsh-attachment": {
|
|
@@ -226,53 +226,54 @@
|
|
|
226
226
|
}
|
|
227
227
|
},
|
|
228
228
|
"devDependencies": {
|
|
229
|
-
"@deepseek-ai/dsh-brand": "0.1.2-
|
|
230
|
-
"@deepseek-ai/dsh-atomic-write": "0.1.2-
|
|
231
|
-
"@deepseek-ai/dsh-home-paths": "0.1.2-
|
|
232
|
-
"@deepseek-ai/dsh-host-directory-picker": "0.1.2-
|
|
233
|
-
"@deepseek-ai/dsh-host-plugin-inventory": "0.1.2-
|
|
234
|
-
"@deepseek-ai/dsh-goal": "0.1.2-
|
|
235
|
-
"@deepseek-ai/dsh-attachment": "0.1.2-
|
|
236
|
-
"@deepseek-ai/dsh-authorization": "0.1.2-
|
|
229
|
+
"@deepseek-ai/dsh-brand": "0.1.2-rc.1",
|
|
230
|
+
"@deepseek-ai/dsh-atomic-write": "0.1.2-rc.1",
|
|
231
|
+
"@deepseek-ai/dsh-home-paths": "0.1.2-rc.1",
|
|
232
|
+
"@deepseek-ai/dsh-host-directory-picker": "0.1.2-rc.1",
|
|
233
|
+
"@deepseek-ai/dsh-host-plugin-inventory": "0.1.2-rc.1",
|
|
234
|
+
"@deepseek-ai/dsh-goal": "0.1.2-rc.1",
|
|
235
|
+
"@deepseek-ai/dsh-attachment": "0.1.2-rc.1",
|
|
236
|
+
"@deepseek-ai/dsh-authorization": "0.1.2-rc.1",
|
|
237
237
|
"@deepseek-ai/cordis-plugin-loader": "1.0.3",
|
|
238
|
-
"@deepseek-ai/dsh-agent": "0.1.2-
|
|
239
|
-
"@deepseek-ai/dsh-agent-default-model": "0.1.2-
|
|
240
|
-
"@deepseek-ai/dsh-agent-presets": "0.1.2-
|
|
241
|
-
"@deepseek-ai/dsh-cmdline": "0.1.2-
|
|
242
|
-
"@deepseek-ai/dsh-compaction": "0.1.2-
|
|
243
|
-
"@deepseek-ai/dsh-commands": "0.1.2-
|
|
244
|
-
"@deepseek-ai/dsh-credentials": "0.1.2-
|
|
245
|
-
"@deepseek-ai/dsh-fs": "0.1.2-
|
|
246
|
-
"@deepseek-ai/dsh-file-reference": "0.1.2-
|
|
247
|
-
"@deepseek-ai/dsh-invariants": "0.1.2-
|
|
248
|
-
"@deepseek-ai/dsh-jobs": "0.1.2-
|
|
249
|
-
"@deepseek-ai/dsh-llm": "0.1.2-
|
|
250
|
-
"@deepseek-ai/dsh-message-feedback": "0.1.2-
|
|
251
|
-
"@deepseek-ai/dsh-native-command": "0.1.2-
|
|
252
|
-
"@deepseek-ai/dsh-permission-presets": "0.1.2-
|
|
253
|
-
"@deepseek-ai/dsh-plan-mode": "0.1.2-
|
|
254
|
-
"@deepseek-ai/dsh-session": "0.1.2-
|
|
255
|
-
"@deepseek-ai/dsh-session-projection": "0.1.2-
|
|
256
|
-
"@deepseek-ai/dsh-session-projection-cache": "0.1.2-
|
|
257
|
-
"@deepseek-ai/dsh-session-stats": "0.1.2-
|
|
258
|
-
"@deepseek-ai/dsh-session-query": "0.1.2-
|
|
259
|
-
"@deepseek-ai/dsh-session-reference": "0.1.2-
|
|
260
|
-
"@deepseek-ai/dsh-schedule": "0.1.2-
|
|
261
|
-
"@deepseek-ai/dsh-session-title": "0.1.2-
|
|
262
|
-
"@deepseek-ai/dsh-settings": "0.1.2-
|
|
263
|
-
"@deepseek-ai/dsh-subagent": "0.1.2-
|
|
264
|
-
"@deepseek-ai/dsh-token-meter": "0.1.2-
|
|
265
|
-
"@deepseek-ai/dsh-tool-todo": "0.1.2-
|
|
266
|
-
"@deepseek-ai/dsh-tools": "0.1.2-
|
|
267
|
-
"@deepseek-ai/dsh-session-persistence": "0.1.2-
|
|
268
|
-
"@deepseek-ai/dsh-subprocess": "0.1.2-
|
|
269
|
-
"@deepseek-ai/dsh-user-approval": "0.1.2-
|
|
270
|
-
"@deepseek-ai/dsh-user-questions": "0.1.2-
|
|
271
|
-
"@deepseek-ai/dsh-workspace": "0.1.2-
|
|
238
|
+
"@deepseek-ai/dsh-agent": "0.1.2-rc.1",
|
|
239
|
+
"@deepseek-ai/dsh-agent-default-model": "0.1.2-rc.1",
|
|
240
|
+
"@deepseek-ai/dsh-agent-presets": "0.1.2-rc.1",
|
|
241
|
+
"@deepseek-ai/dsh-cmdline": "0.1.2-rc.1",
|
|
242
|
+
"@deepseek-ai/dsh-compaction": "0.1.2-rc.1",
|
|
243
|
+
"@deepseek-ai/dsh-commands": "0.1.2-rc.1",
|
|
244
|
+
"@deepseek-ai/dsh-credentials": "0.1.2-rc.1",
|
|
245
|
+
"@deepseek-ai/dsh-fs": "0.1.2-rc.1",
|
|
246
|
+
"@deepseek-ai/dsh-file-reference": "0.1.2-rc.1",
|
|
247
|
+
"@deepseek-ai/dsh-invariants": "0.1.2-rc.1",
|
|
248
|
+
"@deepseek-ai/dsh-jobs": "0.1.2-rc.1",
|
|
249
|
+
"@deepseek-ai/dsh-llm": "0.1.2-rc.1",
|
|
250
|
+
"@deepseek-ai/dsh-message-feedback": "0.1.2-rc.1",
|
|
251
|
+
"@deepseek-ai/dsh-native-command": "0.1.2-rc.1",
|
|
252
|
+
"@deepseek-ai/dsh-permission-presets": "0.1.2-rc.1",
|
|
253
|
+
"@deepseek-ai/dsh-plan-mode": "0.1.2-rc.1",
|
|
254
|
+
"@deepseek-ai/dsh-session": "0.1.2-rc.1",
|
|
255
|
+
"@deepseek-ai/dsh-session-projection": "0.1.2-rc.1",
|
|
256
|
+
"@deepseek-ai/dsh-session-projection-cache": "0.1.2-rc.1",
|
|
257
|
+
"@deepseek-ai/dsh-session-stats": "0.1.2-rc.1",
|
|
258
|
+
"@deepseek-ai/dsh-session-query": "0.1.2-rc.1",
|
|
259
|
+
"@deepseek-ai/dsh-session-reference": "0.1.2-rc.1",
|
|
260
|
+
"@deepseek-ai/dsh-schedule": "0.1.2-rc.1",
|
|
261
|
+
"@deepseek-ai/dsh-session-title": "0.1.2-rc.1",
|
|
262
|
+
"@deepseek-ai/dsh-settings": "0.1.2-rc.1",
|
|
263
|
+
"@deepseek-ai/dsh-subagent": "0.1.2-rc.1",
|
|
264
|
+
"@deepseek-ai/dsh-token-meter": "0.1.2-rc.1",
|
|
265
|
+
"@deepseek-ai/dsh-tool-todo": "0.1.2-rc.1",
|
|
266
|
+
"@deepseek-ai/dsh-tools": "0.1.2-rc.1",
|
|
267
|
+
"@deepseek-ai/dsh-session-persistence": "0.1.2-rc.1",
|
|
268
|
+
"@deepseek-ai/dsh-subprocess": "0.1.2-rc.1",
|
|
269
|
+
"@deepseek-ai/dsh-user-approval": "0.1.2-rc.1",
|
|
270
|
+
"@deepseek-ai/dsh-user-questions": "0.1.2-rc.1",
|
|
271
|
+
"@deepseek-ai/dsh-workspace": "0.1.2-rc.1",
|
|
272
272
|
"@deepseek-ai/cordis": "4.0.2",
|
|
273
273
|
"@deepseek-ai/schemastery": "3.18.2",
|
|
274
274
|
"@types/react": "~18.3.1",
|
|
275
|
-
"@
|
|
276
|
-
"@lingxi-ai-cn/dsh-plugin-hub": "0.1.
|
|
275
|
+
"@deepseek-ai/dsh-settings-file": "0.1.2-rc.1",
|
|
276
|
+
"@lingxi-ai-cn/dsh-plugin-hub": "0.1.9-rc.1",
|
|
277
|
+
"@lingxi-ai-cn/dsh-session-export": "0.1.9-rc.1"
|
|
277
278
|
}
|
|
278
279
|
}
|