dsh-neotui 0.0.18 → 0.0.19

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/views.js +40 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-neotui",
3
- "version": "0.0.18",
3
+ "version": "0.0.19",
4
4
  "description": "Neo-TUI: mouse-driven terminal UI client for DeepSeek Harness (B-tier per dsh-tui-design.md)",
5
5
  "type": "module",
6
6
  "bin": { "dsh-neotui": "bin/dsh-tui.js" },
package/src/views.js CHANGED
@@ -817,7 +817,8 @@ export class ChatView extends Widget {
817
817
  send(text) {
818
818
  if (!this.sessionId) return;
819
819
  const trimmed = text.trim();
820
- if (trimmed === "/reload") { this.app.reloadApp(); return; }
820
+ if (trimmed === "/reload") { this.app.softReload(); return; }
821
+ if (trimmed === "/restart") { this.app.restartApp(); return; }
821
822
  if (!trimmed) return;
822
823
  const { parts, images, errors } = buildPromptParts(trimmed, {
823
824
  readFile: (p) => {
@@ -2194,17 +2195,49 @@ export class App {
2194
2195
  showModePicker() { this.overlay = buildModePicker(this); this.redraw(); }
2195
2196
  showPermissionPicker() { this.overlay = buildPermissionPicker(this); this.redraw(); }
2196
2197
 
2197
- /** /reload: restart the TUI process in the same terminal so a freshly
2198
- * published build (the profile symlinks the repo) takes effect without
2199
- * quitting and re-running `dsh` by hand. */
2200
- async reloadApp() {
2201
- this.toast("正在重启 TUI…");
2198
+ /** /reload: in-place soft reload fresh session list, fresh chat history,
2199
+ * panels rebuilt, screen re-rendered. No process churn, no terminal
2200
+ * handoff (the old process-restart approach leaked mouse bytes into the
2201
+ * boot of the new instance). */
2202
+ async softReload() {
2203
+ this.closeOverlay();
2204
+ this.menu = null;
2205
+ this.popup = null;
2206
+ for (const p of [this.workspacePanel, this.trajectoryPanel, this.settingsPanel, this.subagentPanel, this.skillsPanel]) {
2207
+ if (p?.dispose) { try { p.dispose(); } catch {} }
2208
+ }
2209
+ this.workspacePanel = this.trajectoryPanel = this.settingsPanel = this.subagentPanel = this.skillsPanel = null;
2210
+ this.chat.cache.clear();
2211
+ this.chat.nodes = [];
2212
+ this.chat.collapsedBlocks.clear();
2213
+ this.chat.expanded.clear();
2214
+ this.chat.expandedTools.clear();
2215
+ this.chat.queueRebuild();
2216
+ this.chat.view.anchorLock = null;
2217
+ this.mode = "chat";
2218
+ this.focus(this.chat);
2219
+ this.toast("正在重新加载…");
2220
+ await this.refreshSessions();
2221
+ if (this.currentSession) await this.openSession(this.currentSession);
2222
+ else await this.newSessionIn(null);
2223
+ this.layout();
2224
+ this.redraw();
2225
+ this.toast("已重新加载会话与界面");
2226
+ }
2227
+
2228
+ /** /restart: restart the TUI process in the same terminal so a freshly
2229
+ * published build (the profile symlinks the repo) takes effect. The new
2230
+ * instance starts one second after this process restores the terminal —
2231
+ * no stray mouse/keyboard bytes leak into its boot. */
2232
+ async restartApp() {
2233
+ this.toast("正在重启 TUI(加载新版本代码)…");
2202
2234
  this.redraw();
2203
2235
  await new Promise((r) => setTimeout(r, 250));
2204
2236
  try { this.term?.stop?.(); } catch {}
2205
2237
  try {
2206
2238
  const { spawn } = await import("node:child_process");
2207
- const child = spawn(process.argv[0], process.argv.slice(1), { detached: true, stdio: "inherit" });
2239
+ const argv = process.argv.slice(1);
2240
+ const child = spawn("sh", ["-c", 'sleep 1; exec "$@"', "sh", ...argv], { detached: true, stdio: "inherit" });
2208
2241
  child.unref();
2209
2242
  } catch (e) {
2210
2243
  this.toast(`重启失败: ${e.message}(请手动重启)`);