@xiaoqiong0v0/opencode-ssh-tool 0.6.9 → 0.6.12

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 (51) hide show
  1. package/dist/agent.d.ts.map +1 -1
  2. package/dist/agent.js +82 -8
  3. package/dist/agent.js.map +1 -1
  4. package/dist/base-session.d.ts +32 -5
  5. package/dist/base-session.d.ts.map +1 -1
  6. package/dist/base-session.js +79 -53
  7. package/dist/base-session.js.map +1 -1
  8. package/dist/constants.d.ts +29 -1
  9. package/dist/constants.d.ts.map +1 -1
  10. package/dist/constants.js +30 -1
  11. package/dist/constants.js.map +1 -1
  12. package/dist/escapes.d.ts +9 -0
  13. package/dist/escapes.d.ts.map +1 -0
  14. package/dist/escapes.js +65 -0
  15. package/dist/escapes.js.map +1 -0
  16. package/dist/history.d.ts +10 -3
  17. package/dist/history.d.ts.map +1 -1
  18. package/dist/history.js +18 -3
  19. package/dist/history.js.map +1 -1
  20. package/dist/i18n.d.ts +21 -5
  21. package/dist/i18n.d.ts.map +1 -1
  22. package/dist/i18n.js +7 -3
  23. package/dist/i18n.js.map +1 -1
  24. package/dist/index.d.ts.map +1 -1
  25. package/dist/index.js +34 -16
  26. package/dist/index.js.map +1 -1
  27. package/dist/local-session.js +5 -5
  28. package/dist/local-session.js.map +1 -1
  29. package/dist/log.d.ts +72 -0
  30. package/dist/log.d.ts.map +1 -1
  31. package/dist/log.js +262 -1
  32. package/dist/log.js.map +1 -1
  33. package/dist/server-entry.js +1 -1
  34. package/dist/server-entry.js.map +1 -1
  35. package/dist/server-manager.d.ts.map +1 -1
  36. package/dist/server-manager.js +18 -2
  37. package/dist/server-manager.js.map +1 -1
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +185 -21
  40. package/dist/server.js.map +1 -1
  41. package/dist/session-store.d.ts +10 -2
  42. package/dist/session-store.d.ts.map +1 -1
  43. package/dist/session-store.js +30 -5
  44. package/dist/session-store.js.map +1 -1
  45. package/dist/session.d.ts.map +1 -1
  46. package/dist/session.js +26 -12
  47. package/dist/session.js.map +1 -1
  48. package/dist/web/app.css +6 -4
  49. package/dist/web/app.js +9 -9
  50. package/dist/web/index.html +4 -1
  51. package/package.json +2 -2
package/dist/session.js CHANGED
@@ -1,8 +1,8 @@
1
1
  // SshSession:ssh2 长驻连接 + PTY shell 管理,
2
2
  // 完成标记法:注入 PROMPT_COMMAND 脚本,命令完成时输出 <SSH_DONE:退出码>
3
3
  import { Client } from "ssh2";
4
- import log from "./log.js";
5
- import { INJECT_TIMEOUT_MS, PTY_COLS, PTY_ROWS, READY_TIMEOUT_MS } from "./constants.js";
4
+ import log, { isDebugEnabled, ssh2Trace } from "./log.js";
5
+ import { INJECT_TIMEOUT_MS, PTY_COLS, PTY_ROWS, READY_TIMEOUT_MS, SSH_KEEPALIVE_COUNT_MAX, SSH_KEEPALIVE_INTERVAL_MS, } from "./constants.js";
6
6
  import { tr } from "./i18n.js";
7
7
  import { resolveAuth, resolvePassword } from "./ssh-auth.js";
8
8
  import { BaseSession } from "./base-session.js";
@@ -32,7 +32,7 @@ export class SshSession extends BaseSession {
32
32
  }
33
33
  catch { /* ignore */ }
34
34
  }
35
- log.hook("ssh_disconnect", `关闭会话 ${this._host}`);
35
+ log.hook("ssh_disconnect", `关闭会话 ${this._host} (session ${this.sessionID}, term ${this.name})`);
36
36
  }
37
37
  async connect(opts) {
38
38
  const port = opts.port ?? 22;
@@ -49,7 +49,14 @@ export class SshSession extends BaseSession {
49
49
  port,
50
50
  username: opts.user,
51
51
  readyTimeout: READY_TIMEOUT_MS,
52
- debug: (msg) => log.info(`[ssh2] ${msg}`),
52
+ // 协议级保活(连接层带外,`keepalive@openssh.com` 全局请求,不写入 channel/PTY):
53
+ // 空闲时定期发 keepalive,避免被路径上的 NAT/防火墙/远端 sshd 的空闲超时掐断长驻连接;
54
+ // 连续 SSH_KEEPALIVE_COUNT_MAX 次无响应则由 ssh2 判定连接死亡(error.level="client-timeout")。
55
+ keepaliveInterval: SSH_KEEPALIVE_INTERVAL_MS,
56
+ keepaliveCountMax: SSH_KEEPALIVE_COUNT_MAX,
57
+ // ssh2 协议 trace 属 debug 级;仅在真正会输出时才注册回调,避免关闭时 ssh2 每次仍做无谓的消息拼装。
58
+ // ssh2Trace 内部再丢弃随输出量增长的 CHANNEL_DATA 等行,只记有界的握手/认证事件。
59
+ ...(isDebugEnabled() ? { debug: (msg) => ssh2Trace(this._logTag, msg) } : {}),
53
60
  ...auth,
54
61
  };
55
62
  const client = new Client();
@@ -59,7 +66,7 @@ export class SshSession extends BaseSession {
59
66
  if (settled)
60
67
  return;
61
68
  settled = true;
62
- log.error(`连接失败 ${opts.host}`, msg);
69
+ log.error(`连接失败 ${opts.host} (session ${this.sessionID}, term ${this.name})`, msg);
63
70
  resolve({ ok: false, host: opts.host, user: opts.user, port, error: msg });
64
71
  };
65
72
  // 常驻错误监听:ssh2 可能多次发 error(断线/通道异常),once 首次触发后失效会变 unhandled
@@ -68,9 +75,16 @@ export class SshSession extends BaseSession {
68
75
  fail(err.message);
69
76
  return;
70
77
  }
71
- log.error(`SSH 会话错误 ${opts.host}`, err);
78
+ // 保活判死(ssh2 在连续 keepalive 无响应后置 level="client-timeout")与普通断线的日志可区分
79
+ const level = err.level;
80
+ if (level === "client-timeout") {
81
+ log.error(`SSH 保活超时,连接判定死亡 ${opts.host} (session ${this.sessionID}, term ${this.name})`, err);
82
+ }
83
+ else {
84
+ log.error(`SSH 会话错误 ${opts.host} (session ${this.sessionID}, term ${this.name})`, err);
85
+ }
72
86
  this._connected = false;
73
- this._remoteBusy = false;
87
+ this._setBusy(false, "SSH 会话错误");
74
88
  this._clearRunningContext();
75
89
  if (this._watchTimer) {
76
90
  clearInterval(this._watchTimer);
@@ -94,26 +108,26 @@ export class SshSession extends BaseSession {
94
108
  this._connectedAt = Date.now();
95
109
  this._lastActive = Date.now();
96
110
  stream.on("data", (chunk) => { this._appendBuffer(chunk.toString()); });
97
- stream.on("close", () => { this._connected = false; this._remoteBusy = false; });
98
- stream.on("error", (e) => { log.error("PTY stream 错误", e); this._connected = false; });
111
+ stream.on("close", () => { this._connected = false; this._setBusy(false, "PTY stream 关闭"); });
112
+ stream.on("error", (e) => { log.error(`PTY stream 错误 (session ${this.sessionID}, term ${this.name})`, e); this._connected = false; });
99
113
  (async () => {
100
114
  await new Promise((r) => setTimeout(r, 400));
101
115
  this._buffer = "";
102
116
  this._cursor = 0;
103
117
  this._runningStartPos = null;
104
- log.info(`连接成功 ${opts.user}@${opts.host}:${port} (session ${this.sessionID})`);
118
+ log.info(`连接成功 ${opts.user}@${opts.host}:${port} (session ${this.sessionID}, term ${this.name})`);
105
119
  if (this._history.totalPairs() > 0)
106
120
  this._history.clear();
107
121
  const deadline = Date.now() + INJECT_TIMEOUT_MS;
108
122
  const adapter = await this._probeShell(deadline);
109
123
  if (!adapter) {
110
- log.error(`Shell 探测超时,终止连接 ${opts.user}@${opts.host}`);
124
+ log.error(`Shell 探测超时,终止连接 ${opts.user}@${opts.host} (session ${this.sessionID}, term ${this.name})`);
111
125
  this.close();
112
126
  resolve({ ok: false, host: opts.user, user: opts.user, port, error: tr("shell_probe_timeout", this._lang) });
113
127
  return;
114
128
  }
115
129
  this._adapter = adapter;
116
- log.info(`Shell 探测结果: ${this._adapter.name}`);
130
+ log.info(`Shell 探测结果: ${this._adapter.name} (session ${this.sessionID}, term ${this.name})`);
117
131
  this._buffer = "";
118
132
  this._cursor = 0;
119
133
  resolve({ ok: true, host: opts.user, user: opts.user, port });
@@ -1 +1 @@
1
- {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
package/dist/web/app.css CHANGED
@@ -41,8 +41,10 @@ body:not(.show-time) .row .t { display: none; }
41
41
  #cmdInput { flex: 1; box-sizing: border-box; background: #0d1117; color: #c9d1d9; border: 1px solid #30363d; border-radius: 6px; padding: 8px 12px; font-family: "CaskaydiaCove Nerd Font Mono", "Cascadia Code", "Fira Code", "JetBrains Mono", "Noto Sans Mono", "Hack", Consolas, "Courier New", monospace; font-size: 13px; outline: none; resize: none; max-height: 120px; overflow-y: auto; }
42
42
  #cmdInput:focus { border-color: #58a6ff; }
43
43
  #cmdInput:disabled { opacity: 0.4; }
44
- #cmdKey { flex: 0 0 auto; width: 72px; text-align: center; background: #21262d; color: #c9d1d9; border: 1px solid #30363d; border-radius: 6px; padding: 8px 6px; font-size: 12px; white-space: nowrap; overflow: hidden; cursor: crosshair; user-select: none; display: flex; align-items: center; justify-content: center; transition: border-color .15s; }
45
- #cmdKey.capture { border-color: #e67e22; animation: pulse 0.6s ease-in-out infinite alternate; }
46
- #cmdKey.disabled { opacity: 0.35; cursor: default; }
44
+ #cmdKey { flex: 0 0 auto; max-width: 46%; text-align: center; background: #21262d; color: #e6edf3; border: 1px solid #30363d; border-radius: 6px; padding: 8px 12px; font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; user-select: none; cursor: pointer; display: flex; align-items: center; justify-content: center; }
45
+ #cmdKey.on { border-color: #3fb950; color: #3fb950; background: #0f2417; }
46
+ #cmdKey.off { border-color: #30363d; color: #8b949e; background: #161b22; }
47
+ #cmdKey.disabled { opacity: 0.35; cursor: default; pointer-events: none; }
47
48
  .tgl.disabled { opacity: 0.35; pointer-events: none; }
48
- @keyframes pulse { from { opacity: 0.6; } to { opacity: 1; } }
49
+ .conn-status { display: none; flex: 0 0 auto; padding: 6px 16px; background: #3d1f1f; color: #ff7b72; border-top: 1px solid #30363d; font-size: 13px; }
50
+ .conn-status.show { display: block; }