@xmoon76/dsh-pi-tui 0.5.1 → 0.5.2-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.en.md CHANGED
@@ -55,13 +55,15 @@ next compatibility range, and fallback paths.
55
55
  | TUI package line | Official DSH tags for the pairing | Notes |
56
56
  |---|---|---|
57
57
  | `0.5.1` (stable / `@latest`) | `dsh-v0.2.0-rc.2` | Current stable line; both the minimum and the exact validation target are the 0.2.0-rc.2 family |
58
+ | `0.5.2-rc.1` (next preview / `@next`) | `dsh-v0.2.0-rc.2` | Current next-line preview; the DSH baseline is identical to `0.5.1` (the 0.2.0-rc.2 family is both the minimum and the exact validation target) |
58
59
  | `0.5.0` (stable, previous) | `dsh-v0.1.7-rc.2`, `dsh-v0.2.0-rc.1` | Previous stable; 0.1.7-rc.2 minimum, exact validation target 0.2.0-rc.1 |
59
60
  | `0.4.9` (stable, previous) | `dsh-v0.1.7-rc.2` | Previous stable; the compatible TUI for a 0.1.7-rc.2 runtime |
60
61
  | `0.4.8` (stable, previous) | `dsh-v0.1.7-rc.1` | Previous stable; the compatible TUI for a 0.1.7-rc.1 runtime |
61
62
  | `0.4.6` (stable, previous) | `dsh-v0.1.5-rc.1`, `dsh-v0.1.5-rc.2` | Previous stable; the compatible TUI for a 0.1.5 runtime |
62
63
  | `0.4.7-alpha.2` (next, previous) | `dsh-v0.1.6-alpha.2` | Previous next line; the compatible TUI for a 0.1.6-alpha.2 runtime |
63
64
 
64
- Do not mix the stable and `@next` prerelease lines. `0.5.1` lifts the whole DSH
65
+ Do not mix the stable and `@next` prerelease lines. `@next` currently resolves to
66
+ the `0.5.2-rc.1` preview, whose DSH baseline is identical to `0.5.1`. `0.5.1` lifts the whole DSH
65
67
  peer floor to `>=0.2.0-rc.2`: the Question lifecycle
66
68
  consumes contracts published only in rc.2 (the `userQuestions.attachWait`/
67
69
  `answer` Remotes and the `userQuestions` Session projection), so mixing in the
@@ -132,7 +134,7 @@ dsh --profile pi-tui --session <session-id>
132
134
 
133
135
  ### Conversation display
134
136
 
135
- `/display focus` groups the current turn's Thinking, Tool Calls, and intermediate replies into a live Thought block; `/display full` restores the normal Transcript projection. `/focus` remains available as a compatibility command. The Compact preset is reserved and `/display compact` is rejected until its projection ships.
137
+ `/display` switches between three presentation presets: `full` (default) is the normal Transcript projection; `focus` groups the current turn's Thinking, Tool Calls, and intermediate replies into a live Thought block; `compact` folds contiguous process into `Activity` spans with Header + `Think:` / `Action:` previews, keeps the session and assistant intermediate output visible in chronological order, renders injected notice / relay / recall entries separately (adjacent environment injections merge into an expandable Context cluster), and expands with a mouse click or `Ctrl+O`. The `Display` row in `/settings` offers the same values and persists the choice; `/focus` remains available as a compatibility command.
136
138
 
137
139
  The full process can still be expanded when needed. In fullscreen Focus, Thought roots can be expanded/collapsed in bulk or opened with an individual card click, and the viewport survives switches and resizes. Display presets only change presentation; they do not modify Session events.
138
140
 
@@ -185,10 +187,14 @@ Regular `↑` / `↓` history recall is still available for recent input.
185
187
 
186
188
  `/tasks` opens the full Task Center, showing the work the current Session's
187
189
  Job Registry / Subagent catalog still tracks; the Footer's `↓` opens the
188
- lightweight Quick Tasks view for the current active work. Selecting a Job
189
- opens a detail with the official non-consuming live
190
- output preview (status, progress and the retained output tail); it never consumes
191
- the model's `job_output` cursor and never becomes session history.
190
+ lightweight Quick Tasks view for the current active work. Selecting a Job opens
191
+ the fullscreen Job workspace: one status row with the Job identity, the themed
192
+ status and the `[GAP]`/`[ERROR]`/`[SETTLED]` facts, followed by the real
193
+ progress/detail, the command summary and the `Output` / `Command` reading tabs.
194
+ Output is the official non-consuming live preview (scrollable, searchable and
195
+ explicitly labelled as a retained tail rather than the full history), and the
196
+ Command page shows and copies the original shell command. It never consumes the
197
+ model's `job_output` cursor and never becomes session history.
192
198
 
193
199
  Task Center is a live tracked/control projection, not an execution-history
194
200
  list. `ACTIVE` / `TRACKED` are presentation scopes: `ACTIVE` shows only the
@@ -335,6 +341,61 @@ Common entry points:
335
341
 
336
342
  Model selection, Reasoning Effort, permission presets, Plan, and Goal all keep the corresponding DSH runtime semantics.
337
343
 
344
+ `/settings` opens a real full-screen workspace where the three-, two- and
345
+ single-column layouts are projections of the SAME `categories → rows → detail`
346
+ levels: wide terminals show all three columns, medium ones show
347
+ `categories + rows` or `rows + details` for the current level, and narrow ones
348
+ show only the current level. At every width ASCII `Right` advances exactly one
349
+ level and `Left` returns one level (inert at L0); `Enter` follows the same
350
+ transitions, and `Esc`/`Backspace` step back, closing at the outermost level.
351
+ `Tab`/`Shift+Tab` remain inert. The Action Bar stays pinned to the last physical
352
+ row. Multi-column choosing retains the active `[Details]` marker unless that
353
+ heading would consume the only content row. It presents the real Appearance /
354
+ Display facts: the theme's source-qualified raw value plus its friendly name,
355
+ Icon style, the live Transcript display preset alongside the persisted preference,
356
+ the live Thinking detail state, and each row's configuration Scope and backend
357
+ readiness. `R`
358
+ re-reads and `C` copies the selected row's exact source value. Browsing, choosing
359
+ and copying alone never write configuration.
360
+
361
+ The **`Configured theme` and `Transcript display` rows are directly editable**:
362
+ from L1, `Right` or `Enter`, the painted `[Change…]` button, or ordinary visible
363
+ Detail content opens the candidate choice in the SAME L2 pane. Current-value and
364
+ Runtime/Persisted facts stay in the same pane above the candidate region and scroll
365
+ independently. `Up`/`Down`/`Home`/`End` move the candidate; `PgUp`/`PgDn` and the
366
+ wheel over facts scroll only the fact region, while the candidate wheel scrolls
367
+ independently. During choice, `C` copies the original row value only while the
368
+ Action Bar paints `c copy`; it never copies or commits the draft candidate. `Enter`
369
+ or `[Confirm]` confirms explicitly, and `Left`/`Esc`/`Backspace` or `[Cancel]`
370
+ cancels directly to L1 without writing anything. If the selected candidate identity
371
+ has scrolled out of view, the first Enter only reveals it; confirmation requires a
372
+ later Enter. From L2 browse or a settled outcome, Enter reopens choice for a
373
+ writable non-pending row. At 44×8, a long identity may first reclaim the optional
374
+ `Choose value` heading; if still needed, the fact area shrinks only to one original
375
+ `Value` row. The complete identity, `Confirm` and `Enter confirm` must be visible
376
+ before a write.
377
+ An identity beyond the remaining candidate capacity stays unconfirmable. Only
378
+ buttons and candidates that are really painted can be clicked. A confirmed change is stored through the existing
379
+ serialized whole-document write path and then re-read from the authority: the
380
+ detail names the live runtime fact (`Runtime`, e.g. the current palette) and the
381
+ stored preference (`Persisted`) separately and states `Saving…`, `Verified`,
382
+ `Not saved · <reason>`, `Commit accepted · verification unavailable` or
383
+ `Outcome unknown · <reason>` — only a completed write whose authoritative
384
+ re-read agrees is called Verified; a rejected write re-reads the authority first
385
+ and reports Not saved only while it still carries the value the request started
386
+ from; a third value, a value already in place or an unreadable authority is
387
+ Outcome unknown, and a success whose readable readback disagrees is a failure
388
+ rather than "verification unavailable". On a non-ready backend the theme is
389
+ neither applied nor written; a display preset may already be live locally and
390
+ then says that it was not stored instead of pretending it was. A plugin theme is
391
+ resolved again by its source-qualified identity at confirm time, so an unloaded
392
+ plugin theme is listed as unavailable and refused rather than degrading into a
393
+ same-named file theme. Icon style and Thinking detail stay read-only rows. The
394
+ existing complete settings editor is still available: `Other settings` → `Open
395
+ existing settings…` retires the workspace and restores the surface it paused
396
+ before opening the original editor, so Theme, the Plugin Manager, keybindings,
397
+ permissions and extension settings keep every existing write path.
398
+
338
399
  The `Icon style` option in `/settings` switches the TUI's structural icons:
339
400
  `Emoji` (default, colorful), `Symbols` (compact single-cell terminal
340
401
  symbols), or `Minimal` (decorative icons hidden; only status/interaction
package/README.md CHANGED
@@ -53,13 +53,15 @@ pnpm compat:dsh:npm
53
53
  | TUI 包版本 | 对应的官方 DSH tags | 说明 |
54
54
  |---|---|---|
55
55
  | `0.5.1`(stable / `@latest`) | `dsh-v0.2.0-rc.2` | 当前稳定版;最低与精确验证目标均为 0.2.0-rc.2 family |
56
+ | `0.5.2-rc.1`(next 预览 / `@next`) | `dsh-v0.2.0-rc.2` | 当前 next 线预览;DSH 基线与 `0.5.1` 相同,最低与精确验证目标均为 0.2.0-rc.2 family |
56
57
  | `0.5.0`(stable,历史) | `dsh-v0.1.7-rc.2`、`dsh-v0.2.0-rc.1` | 上一稳定版;最低 0.1.7-rc.2,精确验证目标 0.2.0-rc.1 |
57
58
  | `0.4.9`(stable,历史) | `dsh-v0.1.7-rc.2` | 上一稳定版;0.1.7-rc.2 runtime 的兼容 TUI |
58
59
  | `0.4.8`(stable,历史) | `dsh-v0.1.7-rc.1` | 上一稳定版;0.1.7-rc.1 runtime 的兼容 TUI |
59
60
  | `0.4.6`(stable,历史) | `dsh-v0.1.5-rc.1`、`dsh-v0.1.5-rc.2` | 上一稳定版;0.1.5 runtime 的兼容 TUI |
60
61
  | `0.4.7-alpha.2`(next,历史) | `dsh-v0.1.6-alpha.2` | 上一条 next 线;0.1.6-alpha.2 runtime 的兼容 TUI |
61
62
 
62
- 不要把稳定线与 `@next` 预发布线混装。`0.5.1` 把整个 DSH peer
63
+ 不要把稳定线与 `@next` 预发布线混装。当前 `@next` 指向 `0.5.2-rc.1` 预览,
64
+ 它的 DSH 基线与 `0.5.1` 完全相同。`0.5.1` 把整个 DSH peer
63
65
  floor 提升到 `>=0.2.0-rc.2`:Question 生命周期消费 rc.2 才发布的公开契约
64
66
  (`userQuestions.attachWait`/`answer` Remote 与 `userQuestions` Session
65
67
  projection),rc.1 family 不提供这些契约,混装属于虚假的兼容声明。上一稳定版
@@ -124,7 +126,7 @@ dsh --profile pi-tui --session <session-id>
124
126
 
125
127
  ### Conversation display
126
128
 
127
- `/display focus` 将运行中的 Thinking、Tool Call 和中间回复聚合为一个实时更新的 Thought 区块;`/display full` 恢复普通 Transcript 展示。`/focus` 仍作为兼容命令保留。Compact 预设尚未开放,`/display compact` 会明确拒绝。
129
+ `/display` 在三种展示预设间切换:`full`(默认)是普通 Transcript 展示;`focus` 将当前回合的 Thinking、Tool Call 和中间回复聚合为一个实时更新的 Thought 区块;`compact` 把连续的过程折叠为带 Header + `Think:` / `Action:` 预览的 `Activity` 段,会话与 assistant 的中间输出仍按时间顺序可见,注入的 notice / relay / recall 改为独立呈现(相邻的环境类注入合并为可展开的 Context 簇),展开用鼠标点击或 `Ctrl+O`。`/settings` 的 `Display` 行提供同一组取值并持久化;`/focus` 仍作为兼容命令保留。
128
130
 
129
131
  需要查看过程时可以展开,关闭 Focus 后恢复普通 Transcript 展示。全屏 Focus 中可以按 Thought root 批量展开/收起,也可以单独点击卡片;切换或缩放时会保留 viewport。展示预设只影响界面投影,不修改 Session 中保存的事件。
130
132
 
@@ -175,7 +177,7 @@ Rewind 会从选中的历史 User Turn 创建新的 Child Session,并把对应
175
177
 
176
178
  ### Subagent 与 Task Center
177
179
 
178
- `/tasks` 打开完整 Task Center,显示当前 Session 中仍由 Job Registry / Subagent catalog 跟踪的工作;Footer 的 `↓` 打开轻量 Quick Tasks,只看当前活动(active)工作。选中 Job 后,详情会显示官方非消耗式的实时输出预览(状态、进度与保留的输出尾部),不会消耗模型的 `job_output` 游标,也不写入会话历史。
180
+ `/tasks` 打开完整 Task Center,显示当前 Session 中仍由 Job Registry / Subagent catalog 跟踪的工作;Footer 的 `↓`(仅在光标位于编辑器最后一个可视行时)打开按需的 Quick 窗口,它默认不占行、出现在整个 Footer 之下。选中 Job 后进入全屏 Job 工作区:顶部一行显示 Job 身份、主题状态与大写状态及 `[GAP]`/`[ERROR]`/`[SETTLED]` 事实,下面是真实进度/说明、命令摘要与 `Output`/`Command` 阅读标签。Output 是官方非消耗式的实时输出预览(可滚动、可搜索,并明确标注为保留尾部而非完整历史),Command 页可阅读并按原文复制 shell 命令。工作区不会消耗模型的 `job_output` 游标,也不写入会话历史。
179
181
 
180
182
  Task Center 的 `ACTIVE` / `TRACKED` 是展示范围:`ACTIVE` 只显示当前活动项,`TRACKED` 显示当前跟踪源(Job Registry / Subagent catalog)仍列出的全部项;`TRACKED` 不是 Session 执行历史。DSH `0.1.7` 会在普通前台 `bash` / `pwsh` 执行期间临时注册 Job,使其可以在 Task Center 中观察和停止;如果命令在前台等待内完成,DSH 会移除该临时记录,最终结果仍保留在 Transcript 的 tool card 中。显式 `run_in_background: true` 或被提升为后台的 Job 在完成后,只要 Job Registry 继续保留其记录,就仍可在 `TRACKED` 中查看。
181
183
 
@@ -198,9 +200,9 @@ main
198
200
  * nested descendant
199
201
  * Job Registry 跟踪的 Job(含运行中的前台 shell)
200
202
 
201
- Footer `↓` 打开的 Quick Tasks 是轻量浏览视图,只提供方向键导航、左右展开/折叠、`Tab` 类型过滤、`Enter` 打开和 `Esc` 关闭。底部 “Open Task Center” 行可进入完整 Task Center。
203
+ Footer `↓` 打开的 Quick 窗口默认不占行,只在编辑器最后一个可视行按 `↓` 时展开到 Footer 之下:`↑↓` / `PgUp` / `PgDn` 选择,`Enter` 用真实任务身份打开既有详情,`↑`(首行)或 `Esc` 返回编辑器并保留草稿;列表末尾的 “Open Task Center” 行进入完整 Task Center。
202
204
 
203
- 完整 Task Center 额外提供 `A` 切换 Active / Tracked、`/` 搜索、`Tab` / `Shift+Tab` 双向切换类型、`S`(确认后)停止所选任务以及 `R` 刷新 / 重试。Quick Tasks 只消费上述白名单按键,其余输入一律 no-op,不会进入搜索、停止确认或任务管理状态,因此 `Esc` 始终一层关闭。
205
+ 完整 Task Center 额外提供 `A` 切换 Active / Tracked、`/` 搜索、`Tab` / `Shift+Tab` 双向切换类型、`S`(确认后)停止所选任务以及 `R` 刷新 / 重试。Quick 窗口只消费上述导航键,其余输入一律 no-op,不会进入搜索、停止确认或任务管理状态,因此 `Esc` 始终一层关闭。
204
206
 
205
207
  已经结束的 one-shot Subagent 仍可以打开并查看持久化 Transcript。
206
208
 
@@ -299,6 +301,37 @@ TUI 使用 DSH 提供的模型和设置服务。
299
301
 
300
302
  模型切换、Reasoning Effort、权限 Preset、Plan 和 Goal 都沿用 DSH 对应的运行时语义。
301
303
 
304
+ `/settings` 打开一个真正的全屏工作区,三栏 / 两栏 / 单栏只是同一套
305
+ `分类 → 设置行 → 详情` 三层的投影:宽屏同时显示三栏,中屏按当前层显示
306
+ `分类 + 设置行` 或 `设置行 + 详情`,窄屏只显示当前层。所有宽度上 `Right` 只前进一层,
307
+ `Left` 返回一层(在最外层无效);`Enter` 遵循相同层级,`Esc`/`Backspace` 逐级返回,
308
+ 最外层关闭工作区。`Tab`/`Shift+Tab` 不承担导航,底部操作栏始终固定在最后一行。多栏编辑态仍
309
+ 保留 `[Details]` 焦点标识;只有标题会占掉唯一内容行时才让位。
310
+ 它展示 Appearance / Display 的真实事实:主题的 source-qualified 原始值与友好名称、
311
+ Icon style、Transcript display 的运行时当前值与持久偏好、Thinking detail 的当前运行
312
+ 态,以及每个条目的配置来源 Scope 与 backend 就绪状态;`R` 重新读取、`C` 复制所选行的
313
+ 原始值;浏览、选择与复制本身都不写入配置。
314
+
315
+ 其中**「Configured theme」和「Transcript display」两行可以直接修改**:在 L1 设置行按
316
+ `Right` 或 `Enter`,或点击 `[Change…]` / 可见的 Detail 内容,即可在同一 L2 详情中打开
317
+ 候选选择;当前值与 Runtime / Persisted 事实留在同一详情事实区,并与候选列表独立滚动。`Up`/`Down`/`Home`/`End`
318
+ 移动候选,`PgUp`/`PgDn` 和事实区上的滚轮只滚动详情事实,候选区滚轮独立滚动候选;
319
+ 选择期间可按 `C` 复制仍未更改的原始值,但仅当动作栏实际绘出 `c copy`,它不会提交候选。
320
+ `Enter` 或点击 `[Confirm]` 明确确认,`Left`/`Esc`/`Backspace` 或 `[Cancel]` 取消并直接回到
321
+ L1,零写入。L2 浏览/已结算时,`Enter` 可重新打开可写行的选择;pending 写入时不触发新选择。若当前候选身份已滚出可见区域,第一次 `Enter` 只将其重新显示,之后才能确认;
322
+ 44×8 短屏在长身份需要空间时先省略可选的 `Choose value` 标题;若仍不足,再将事实区压到只保留旧 `Value` 的一行。只有完整身份、`Confirm` 与 `Enter confirm` 同屏可见时才能确认,超过剩余容量仍拒绝写入。只有实际绘制出来的
323
+ 按钮与候选行可以点击。确认后走既有的串行整文档写入路径落盘,再从权威来源重读目标字段核对:
324
+ 详情里分别显示运行态(`Runtime`,如当前 palette)与持久偏好(`Persisted`),并显示
325
+ `Saving…` / `Verified` / `Not saved · 原因` / `Commit accepted · verification unavailable` /
326
+ `Outcome unknown · 原因`,只有写入完成、backend `ready` 且权威回读一致才显示 Verified;
327
+ 被拒绝的写入会先重读权威:仍停留在请求起点值才报 Not saved,出现第三个值、已是目标值或无法读取
328
+ 则如实报 Outcome unknown;写返回成功但权威可读地不一致同样按失败显示,而不是
329
+ "verification unavailable"。backend 不 ready 时主题不会被应用或写入;显示预设可以先在本机生效,
330
+ 此时会明确说明未能保存,而不是假装保存成功。插件主题在确认时再次按 source-qualified 身份解析,
331
+ 已卸载的插件主题标记为 unavailable 并拒绝确认,不会退化成同名文件主题。Icon style 与
332
+ Thinking detail 仍是只读行。旧的完整设置编辑器仍然可用:`Other settings` → `Open existing settings…`
333
+ 会先关闭工作区并恢复原界面,再打开原有编辑器,Theme、Plugin Manager、键位、权限与扩展设置的写入路径全部不变。
334
+
302
335
  `/settings` 中的 `Icon style` 可切换 TUI 结构图标的风格:`Emoji`(默认,
303
336
  彩色)、`Symbols`(紧凑的单格终端符号)、`Minimal`(隐藏装饰性图标,只
304
337
  保留状态/交互标记);切换立即生效并持久化。
package/cordis.patch.yml CHANGED
@@ -24,6 +24,18 @@
24
24
  name: '@xmoon76/dsh-pi-tui/builtins'
25
25
  inject: [tuiStartup, piTuiExtensions]
26
26
 
27
+ # The bundle's OWN Host performance projection (plan PR-1): the single
28
+ # authority for the R5 / All model-request output rate and the recent TTFB.
29
+ # It registers the `piTuiPerformance` unit on the official
30
+ # `sessionProjections` seam — the same seam the official `sessionStats` row
31
+ # uses — and then publishes the `piTuiPerformanceReady` gate. Gating on
32
+ # `tuiStartup` keeps `--help` from mounting it; the `sessionProjections`
33
+ # inject makes the row wait for the Host registry instead of registering
34
+ # into a missing seam.
35
+ - id: pi-tui-performance-host
36
+ name: '@xmoon76/dsh-pi-tui/performance-host'
37
+ inject: [tuiStartup, sessionProjections]
38
+
27
39
  - id: tui-app
28
40
  name: '@xmoon76/dsh-pi-tui'
29
41
  # `workspaceRegistry` is injected, not merely looked up: D2.4 Direct fork
@@ -36,7 +48,11 @@
36
48
  # dsh-base layer already mounts it (disabled only without a profile),
37
49
  # so this is an explicit lifecycle ordering dependency, never a second
38
50
  # package-manager row.
39
- inject: [tuiStartup, piTuiExtensions, authorization, workspaceRegistry, pluginManager, jobController]
51
+ # `piTuiPerformanceReady` is the bundle's own Host projection gate: the
52
+ # surface must not mount without its performance authority, so a profile
53
+ # that disables the `pi-tui-performance-host` row fails loudly here
54
+ # instead of silently falling back to a Client-side estimate.
55
+ inject: [tuiStartup, piTuiExtensions, authorization, workspaceRegistry, pluginManager, jobController, piTuiPerformanceReady]
40
56
  config:
41
57
  sessionId: ''
42
58
 
package/dist/builtins.mjs CHANGED
@@ -1,6 +1,7 @@
1
- import { a as PI_TUI_EXTENSIONS_SERVICE, gt as __exportAll } from "./extensions-1WYBUQ8I.mjs";
2
- import { n as TUI_STARTUP_SERVICE } from "./startup-CmTYVTGC.mjs";
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
2
+ import { n as TUI_STARTUP_SERVICE } from "./startup-CWQl0-0n.mjs";
3
3
  import { n as dshVersion, t as bundleVersion } from "./version-a-eF-QER.mjs";
4
+ import { a as PI_TUI_EXTENSIONS_SERVICE } from "./extensions-VuoIE_Jc.mjs";
4
5
  //#region src/builtins.ts
5
6
  var builtins_exports = /* @__PURE__ */ __exportAll({
6
7
  apply: () => apply,