Skip to content

Releases: Nexus-Aethra/Nexus-Terminal

dshell 0.1.15 — 设备面板:这台机器在跑什么

Choose a tag to compare

@wpplight wpplight released this 24 Oct 10:15
3fc6eac

0.1.15 — 设备面板:这台机器在跑什么

0.1.15 这条线,是给设备会话配一块面板:这台机器在跑什么、哪些容器在、谁占着端口,右侧直接写清楚,
不用再自己开一个 ssh 去问。装它需要 dsh 0.2.1-rc.3(0.1.14 在 rc.3 上装不进去,见「兼容与升级」)。

一句话

设备会话的右侧多了一个设备页签:进程、容器、监听端口三张表,能筛、能排序、能点开看细节——
「刚才那个吃满 CPU 的进程是什么」这种问题,不必再开一个终端。

新能力

  • 右侧的设备面板。 dsh 右侧栏多一个设备页签(dshell 自己的页签类型,不抢 dsh 内置的),四页:
    概览 / 进程 / 容器 / 端口。概览写这台机器是谁、CPU 与内存多少;其余三页各是一张表。开始页上还有一张
    设备详情卡片,点开就是这块面板。
  • 三张表是工具,不是流水。 一台机器两百个进程、四十个监听端口,滚是滚不完的,所以:按你知道的筛
    (命令名、整条命令行、属主、pid、端口、地址、占端口的进程、协议)、按任意一列排(Shift 加一列当次要键,
    最多三键,键上有 ①②③ 标出优先级)、点开一行看表里放不下的(完整命令行、属主、状态、跑了多久、父进程)、
    点端口那一行的进程直接跳到进程表并已经筛好了它。
  • 一次往返,一个答案。 设备是被一次 bash -c 问的,所以会话决定问哪台机器——宿主自己的路由说这是本机
    还是这台设备,这个包里没有一行代码知道 ssh 的存在。
  • 表头和表身是同一套栅格。 表头和数据行曾经是两套布局,列对不齐,瞄着「CPU」结果排的是内存;现在共用一份
    grid-template-columns,还有一条回归测试钉着它们。
  • 支持 dsh 0.2.1-rc.3。 dshell 声明的每个 dsh peer 版本区间都加上了它。

修好的问题

  • 表头点了没反应。 表头是用 key="cpu" 拿自己的列的,而 key 是 React 的保留 prop,在调用组件之前就被
    吃掉了:每个表头拿到的列都是 undefined,四个表头一起挂着同一个「1」徽章,顺序一动不动。类型检查、
    单元测试、渲染测试全是绿的——只有真点一下才会发现。现在这个 prop 叫 column,并有两条测试钉着它。
  • 概览的负载永远是破折号。 面板读了负载那个 seat,却从不订阅它,所以负载有多新取决于别人有没有
    在看:会话的状态卡不在屏幕上时,那三个读数就一直空着。seat 是引用计数的,所以面板也订阅它并不多花一次 ssh
    往返——而且只在概览这一页订阅,因为设备上每次轮询都是一趟 ssh。
  • 列表页那层折叠是多余的。 已经进了设备详情页,列表就是读者要看的东西,一层「打开/关闭」只多一次点击。
  • 筛选时看不出还剩多少。 筛选之后数量会写成 12 / 168。

兼容与升级

  • 无破坏性变化。
  • dshell 0.1.15 支持 dsh 0.2.1-rc.3;更老的 dsh 仍按原来的 peer 区间可用。
  • 注意:0.1.14 在 dsh 0.2.1-rc.3 上装不进去——dsh 会拿插件声明的每个 @deepseek-ai/dsh-* peer 去
    校验自己的版本,有一个不匹配就整个 bundle 跳过(不是警告)。所以你在 rc.3 上,要换的就是这一版。
  • 桌面版:在 设置 → 插件 里把 @nexus-aethra/dshell-bundle 换成 @0.1.15(先卸载再装),重启宿主。

30 秒自检

  1. 绑一台设备,打开它的会话,右侧栏切到设备页签——概览写着这台机器的名字、CPU 和内存。
  2. 切到进程页,点「CPU」旁边的三角——顺序真的翻了(不是点了没反应)。
  3. 切到端口页,点占用进程那一列的名字——进程表开在那一个进程上。

已知边界

  • 端口转发还没做:这块面板是它的地基(端口表,和谁占着它),功能本身还没开始。
  • 设备面板只对设备会话出现;普通会话里右侧栏没有这个页签。
  • 设备侧那个常驻的 helper 掉了时,面板会写「设备不可达」——到 设置 → 插件 → SSH 设备 里点一次「部署 helper」
    就恢复。

dshell 0.1.14 — 设备会话不再像代理

Choose a tag to compare

@wpplight wpplight released this 20 Oct 12:04
3ecd82f

0.1.14 — 设备会话不再像代理

0.1.14 这条线,是让设备会话像个会话,而不是像个代理。装它需要 dsh 0.2.1-rc.2。

一句话

设备绑定的会话里,agent 说设备的方言(工具叫 bash、路径是设备的、运行时上下文是设备的),文件面板列的是设备的目录树(不是宿主目录),而这两件事曾经都是反的。

新能力

  • agent 说设备的方言。 绑到设备的会话给自己的 agent 一个专属的 shell 工具:名字是设备的(bash),描述写明在哪台机器、什么方言、什么路径;宿主那个 pwsh 在这个 agent 眼前被藏起来。执行体没动(后台任务、沙箱升级、结果渲染全不变),只有契约变了。运行时上下文里的工作目录也一并改成设备的。
  • 文件面板列的是设备。 设备会话的「文件」页签开在设备自己的 /root,面包屑写的就是 /root——不是宿主目录拼过去的、两边都不存在的路径。
  • 支持 dsh 0.2.1-rc.2。 dshell 声明的每个 dsh peer 版本区间都加上了它。

修好的问题

  • Windows 桌面版整个崩掉。 追加模式打开的文件不能截断(SetEndOfFile 需要 FILE_WRITE_DATA,追加句柄只有 FILE_APPEND_DATA)→ PTY 日志重置抛 EPERM → 宿主把没接住的 rejection 当致命错误 → dsh: fatal load failure 退出。改成按路径截断,不引平台分支。
  • 设备口令只留在内存。 原来每份凭据都会落成数据根下的一个文件,好让传输层再读回来。现在明文口令不再写盘。
  • 一台设备一条连接。 连接池原来按次拨号,一个回合读四个文件就是四条连接;而 release() 可能掐掉别的操作正在用的那条,回合因此报成「已中断」。现在同一设备共享一次拨号。
  • 回合不再死于协议校验。 设备问不了的路径(Windows 宿主拼法)以前会变成一段裸的 zod issue 数组,工具层认不出来,整个回合以 error 收尾、模型压根没被调用。现在 seam 自己回答:问不了就是「设备上没有这个东西」。
  • 设备 shell 的起始目录。 ~ 之前被整个引号包住,设备读到的是「一个叫 ~ 的目录」,每起一次终端打一行「远端目录 ~ 不存在」。
  • 工具调用按真实顺序穿插,slash 命令按 commandId 匹配(/compact 不再把后面的历史串到前面),运行中的那一轮戴上 dsh 的鲸尾标记。
  • 真正的 UTF-8 locale。 设备 shell 跑在 C.UTF-8 这类 C 族 locale 下时,ls 会把中文文件名转义成 '$'\346\226\207\346\241\243';现在会升级到机器上真正带 UTF-8 码集的 locale。

兼容与升级

  • 无破坏性变化。
  • dshell 0.1.14 支持 dsh 0.2.1-rc.2;更老的 dsh 仍按原来的 peer 区间可用。
  • 桌面版:在 设置 → 插件 里把 @nexus-aethra/dshell-bundle 换成 @0.1.14(先卸载再装),重启宿主。
  • 这次发布还带上了发布侧的加固:每个包在打包前自己重建一次(lib/ 不在版本控制里,以前发出去的是磁盘上那一份);commands 与 bundle 的 exports["."].types 指向了不存在的文件,消费方拿不到类型;已跟踪的截图与文档里的设备公网 IP 已按仓库自己的规矩打码。

30 秒自检

  1. 绑一台设备,在 agent 模式问它「跑个 uname -a」——拿到的是设备的 Linux 答案,不是 command not found。
  2. 打开设备会话的「文件」页签——面包屑是设备的 /root,列出来的是设备上的目录。
  3. 展开状态卡——报的是设备的 CPU 与内存,并写出设备名。

已知边界

  • 浏览器与桌面对设备会话的控制仍然只对本地会话开放(两者都会在「这台机器」上动手,而会话在另一台)。
  • 设备会话的全屏只读备用屏幕;其余全屏程序用 /fullscreen 进入。
  • 管道面板靠轮询刷新(约 3 秒一次),没有推送通道。

dshell 0.1.3

Choose a tag to compare

@wpplight wpplight released this 18 Sep 14:22

Twelve packages at 0.1.3, published in dependency order. The install root is the bundle:

dsh plugin --profile web add -w @nexus-aethra/dshell-bundle@0.1.3

A full-screen program gets the whole surface

Until now dshell had one input model: the composer is the input line, and a shell stretch renders as
a region of the log. That is right for commands and wrong for a program that takes the screen —
vim, htop, less, a coding TUI such as minimax-code. Such a program places every character
itself, at a grid it was told the size of, and reads the keyboard directly.

It now gets the surface instead of the timeline. The composer steps aside, the terminal fills the
column, and every key goes straight to the program: the arrows, Tab, Escape, the control chords,
and the mouse reporting it asks for. Quitting the program brings the timeline back on its own, a
全屏 button beside the mode chip is the way in for a program the reading misses, and a small bar
over the program's own screen is the way out.

dshell decides this from two readings of the session's terminal, because neither is enough alone:

  • The PTY's foreground process group. This is the only signal that catches the full-screen
    programs that never switch buffers — minimax-code is one, measured rather than assumed. It is
    also true for sleep 30 and npm install, so it counts only once the program has shown it is
    painting the screen: hiding the cursor, opening a synchronized update, enabling mouse reporting.
  • The alternate screen — vim, less, htop, tmux. It is also the only signal available to
    a device session, whose local process is ssh, so the button covers the rest there.

While a program holds the terminal its bytes stay out of the block log and the command splitter: its
repaints would land in the timeline as a wall of half-drawn screens the moment the mode ends. They
stay in the session's raw log, which is what lets a reconnect replay the screen.

The compact rail stops showing the SSH badge

Collapsing the sidebar narrows a session row's title to zero width, but dshell's SSH badge is a
fixed-width pill and went on rendering — a column of badges, wider than the rail itself, where the
titles had gone.

Verified

  • pnpm typecheck clean; pnpm test 297 passed (21 files), including a new spec that pins the
    reading's rules — the /proc field offsets with a comm containing parentheses, the alternate
    screen split across a chunk boundary, a foreground program that writes but does not paint,
    evidence not inherited by the next command, and an unreadable name not counting as a different
    program.
  • Live against a real minimax-code in headless Chrome: the mode is entered without a reload,
    the keys reach the program (a probe string echoes in its own input line), quitting it brings the
    timeline back while the connection stays open, and both directions of the manual button work.
  • All twelve tarballs checked before publishing: versions agree, workspace:^ edges rewritten, no
    missing relative import from any entry, and cordis.patch.yml inside the bundle.

The twelve

dshell-std dshell-storage dshell-terminal-bridge dshell-mode dshell-commands
dshell-conversation dshell-workspace dshell-files dshell-ssh dshell-buffer
dshell-host-tools dshell-bundle — all at 0.1.3, all latest on npmjs.