@zhangfengshun/dsh-remote-ssh 2.0.0 → 2.0.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/CHANGELOG.md CHANGED
@@ -2,6 +2,11 @@
2
2
 
3
3
  本文件的版本号与 `package.json` 的 `version` 保持一致。每个版本对应一个 Cordis Package 快照(`pkg-N`)。
4
4
 
5
+ ## [2.0.1] — 修复远程检测:从 payload.path 也查找 .remote-ssh.json
6
+ ### 修复
7
+ - **sessionCwd 为空时无法检测远程工作区**:客户端请求有时只带 `payload.path` 不带 `cwd`,而 `ctx.sessions.get(sessionId)` 可能返回 undefined(session 未创建或 ID 不匹配)。现改为:先尝试 `sessionCwd`,再尝试 `payload.path`,两者都会检查 `.remote-ssh.json`。
8
+ - 添加调试日志(`ctx.logger.info`)记录每次拦截的方法、sessionId、cwd 和远程检测结果。
9
+
5
10
  ## [2.0.0] — 内置文件页签直接 SSH 读写远程文件(不再需要同步)
6
11
  ### 重大变更
7
12
  - **内置「文件」页签直接操作远程文件**:通过注册更长前缀 `/sidebar/api/fs.` 拦截 better-sidebar 的文件 API(`fs.tree`/`fs.read`/`fs.write`/`fs.search`),在远程工作区中直接通过 SSH 读写远程文件,不再需要 sync/push 同步。
package/lib/index.js CHANGED
@@ -1564,30 +1564,42 @@ function apply(ctx, config) {
1564
1564
  const session = ctx.sessions.get(sessionId);
1565
1565
  sessionCwd = session && session.header && session.header.cwd;
1566
1566
  }
1567
+ // 如果 sessionCwd 还是空,尝试用 payload.path 的父目录(文件操作时 path 是文件路径)
1568
+ if ((!sessionCwd || sessionCwd === "") && payload && payload.path) {
1569
+ sessionCwd = payload.path;
1570
+ }
1567
1571
  // 检查是否远程工作区
1568
1572
  const remoteInfo = readRemoteInfoSync(sessionCwd);
1573
+ // 如果 cwd 本身没有 .remote-ssh.json,尝试从 payload.path 向上查找
1574
+ let remoteInfoFromPath = remoteInfo;
1575
+ if (!remoteInfo && payload && payload.path) {
1576
+ remoteInfoFromPath = readRemoteInfoSync(payload.path);
1577
+ }
1578
+ ctx.logger?.info("[dsh-remote-ssh] fs.* intercept: method=" + method + " sessionId=" + sessionId + " cwd=" + sessionCwd + " payload.path=" + (payload && payload.path) + " remoteInfo=" + (remoteInfo ? "YES" : "NO") + " remoteInfoFromPath=" + (remoteInfoFromPath ? "YES" : "NO"));
1569
1579
  let result;
1570
- if (remoteInfo && remoteInfo.keyPath && remoteInfo.host && remoteInfo.user) {
1580
+ if (remoteInfoFromPath && remoteInfoFromPath.keyPath && remoteInfoFromPath.host && remoteInfoFromPath.user) {
1581
+ const actualRemoteInfo = remoteInfo || remoteInfoFromPath;
1582
+ const actualCwd = sessionCwd || (payload && payload.path) || "";
1571
1583
  // ---- 远程工作区:走 SSH ----
1572
- const profile = getProfile(remoteInfo.profileId);
1584
+ const profile = getProfile(actualRemoteInfo.profileId);
1573
1585
  if (!profile) { writeJson(res, 500, { ok: false, error: { code: "internal", message: "remote profile not found" } }); return; }
1574
1586
  if (method === "fs.tree") {
1575
- const localPath = payload.path || sessionCwd;
1576
- const rp = localToRemote(localPath, sessionCwd, remoteInfo.remotePath);
1587
+ const localPath = payload.path || actualCwd;
1588
+ const rp = localToRemote(localPath, actualCwd, actualRemoteInfo.remotePath);
1577
1589
  result = await remoteListForSidebar(profile, rp, localPath);
1578
1590
  } else if (method === "fs.read") {
1579
- const localPath = payload.path || sessionCwd;
1580
- const rp = localToRemote(localPath, sessionCwd, remoteInfo.remotePath);
1591
+ const localPath = payload.path || actualCwd;
1592
+ const rp = localToRemote(localPath, actualCwd, actualRemoteInfo.remotePath);
1581
1593
  result = await remoteReadForSidebar(profile, rp);
1582
1594
  } else if (method === "fs.write") {
1583
- const localPath = payload.path || sessionCwd;
1584
- const rp = localToRemote(localPath, sessionCwd, remoteInfo.remotePath);
1595
+ const localPath = payload.path || actualCwd;
1596
+ const rp = localToRemote(localPath, actualCwd, actualRemoteInfo.remotePath);
1585
1597
  result = await remoteWriteFile(runPooled, profile, rp, payload.content || "");
1586
1598
  } else if (method === "fs.search") {
1587
- const rp = remoteInfo.remotePath;
1599
+ const rp = actualRemoteInfo.remotePath;
1588
1600
  const r = await remoteGlob(runPooled, profile, "*" + (payload.query || "") + "*", rp);
1589
1601
  result = { entries: (r.files || []).map(function (f) {
1590
- return { path: join(sessionCwd, f), isDir: false };
1602
+ return { path: join(actualCwd, f), isDir: false };
1591
1603
  }), truncated: !!r.truncated };
1592
1604
  } else {
1593
1605
  writeJson(res, 404, { ok: false, error: { code: "not-found", message: "unknown method " + method } }); return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhangfengshun/dsh-remote-ssh",
3
- "version": "2.0.0",
3
+ "version": "2.0.1",
4
4
  "description": "DSH web plugin: VSCode Remote-SSH-like remote development (SSH to supercomputers/servers, remote workspace, file explorer, integrated terminal), integrated with dsh-better-sidebar and DSH settings.",
5
5
  "keywords": [
6
6
  "dsh",