@xiaoqiong0v0/opencode-ssh-tool 0.6.18 → 0.7.0
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.md +30 -2
- package/dist/agent.d.ts +7 -0
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +1 -0
- package/dist/agent.js.map +1 -1
- package/dist/constants.d.ts +42 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +44 -1
- package/dist/constants.js.map +1 -1
- package/dist/i18n.d.ts +138 -4
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +114 -4
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +237 -12
- package/dist/index.js.map +1 -1
- package/dist/path-utils.d.ts +8 -0
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/path-utils.js +17 -0
- package/dist/path-utils.js.map +1 -0
- package/dist/payload.d.ts.map +1 -1
- package/dist/payload.js +2 -15
- package/dist/payload.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +123 -1
- package/dist/server.js.map +1 -1
- package/dist/session.d.ts +59 -0
- package/dist/session.d.ts.map +1 -1
- package/dist/session.js +215 -1
- package/dist/session.js.map +1 -1
- package/dist/transfer-events.d.ts +41 -0
- package/dist/transfer-events.d.ts.map +1 -0
- package/dist/transfer-events.js +79 -0
- package/dist/transfer-events.js.map +1 -0
- package/dist/transfer.d.ts +121 -0
- package/dist/transfer.d.ts.map +1 -0
- package/dist/transfer.js +1001 -0
- package/dist/transfer.js.map +1 -0
- package/dist/web/app.css +47 -1
- package/dist/web/app.js +10 -10
- package/dist/web/index.html +11 -0
- package/package.json +2 -2
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// 文件传输任务事件(agent → server → Web):只承载元数据,绝不包含文件内容。
|
|
2
|
+
//
|
|
3
|
+
// 协议:
|
|
4
|
+
// - agent → server:{ type: "transfer", task }
|
|
5
|
+
// - server → web: { type: "transfer", task } 广播;{ type: "transfers", tasks } 快照
|
|
6
|
+
//
|
|
7
|
+
// 本模块只做类型定义与不可信输入的严格校验;server 在写内存/广播前必须先经 parseTransferTask,
|
|
8
|
+
// 避免 agent 侧的异常值(未知方向/状态、超长路径、负数字节等)污染服务端状态或 Web 页面。
|
|
9
|
+
import { TRANSFER_TASK_ERROR_CODE_MAX, TRANSFER_TASK_ID_MAX, TRANSFER_TASK_NAME_MAX, TRANSFER_TASK_PATH_MAX, TRANSFER_TASK_SESSION_ID_MAX, } from "./constants.js";
|
|
10
|
+
const DIRECTIONS = ["upload", "download"];
|
|
11
|
+
const STATES = ["running", "done", "failed"];
|
|
12
|
+
/**
|
|
13
|
+
* 判断是否为长度受限的非空字符串。
|
|
14
|
+
* @param value 待校验值
|
|
15
|
+
* @param max 最大长度
|
|
16
|
+
* @returns true 表示合法
|
|
17
|
+
*/
|
|
18
|
+
function isBoundedNonEmptyString(value, max) {
|
|
19
|
+
return typeof value === "string" && value.length > 0 && value.length <= max;
|
|
20
|
+
}
|
|
21
|
+
/** 判断是否为非负有限整数(字节数/时间戳) */
|
|
22
|
+
function isNonNegativeInt(value) {
|
|
23
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 解析并校验不可信的传输任务(agent 上报 / 测试输入)。
|
|
27
|
+
* - 字段类型与长度严格校验,未知 direction/state 一律拒绝;
|
|
28
|
+
* - 只保留协议白名单字段,丢弃未知字段(防止文件内容/额外敏感数据被透传);
|
|
29
|
+
* - 不校验 bytes ≤ total(进度回调与最终结果允许在文件增长等边界下不严格相等)。
|
|
30
|
+
* @param value 不可信输入
|
|
31
|
+
* @returns 校验通过的任务副本;不合法时 null
|
|
32
|
+
*/
|
|
33
|
+
export function parseTransferTask(value) {
|
|
34
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
35
|
+
return null;
|
|
36
|
+
const v = value;
|
|
37
|
+
if (!isBoundedNonEmptyString(v.id, TRANSFER_TASK_ID_MAX))
|
|
38
|
+
return null;
|
|
39
|
+
if (!isBoundedNonEmptyString(v.sessionID, TRANSFER_TASK_SESSION_ID_MAX))
|
|
40
|
+
return null;
|
|
41
|
+
if (!isBoundedNonEmptyString(v.name, TRANSFER_TASK_NAME_MAX))
|
|
42
|
+
return null;
|
|
43
|
+
if (typeof v.direction !== "string" || !DIRECTIONS.includes(v.direction))
|
|
44
|
+
return null;
|
|
45
|
+
if (!isBoundedNonEmptyString(v.localPath, TRANSFER_TASK_PATH_MAX))
|
|
46
|
+
return null;
|
|
47
|
+
if (!isBoundedNonEmptyString(v.remotePath, TRANSFER_TASK_PATH_MAX))
|
|
48
|
+
return null;
|
|
49
|
+
if (typeof v.state !== "string" || !STATES.includes(v.state))
|
|
50
|
+
return null;
|
|
51
|
+
if (!isNonNegativeInt(v.bytes))
|
|
52
|
+
return null;
|
|
53
|
+
if (!isNonNegativeInt(v.total))
|
|
54
|
+
return null;
|
|
55
|
+
if (!isNonNegativeInt(v.startedAt))
|
|
56
|
+
return null;
|
|
57
|
+
if (v.endedAt !== undefined && !isNonNegativeInt(v.endedAt))
|
|
58
|
+
return null;
|
|
59
|
+
if (v.errorCode !== undefined && !isBoundedNonEmptyString(v.errorCode, TRANSFER_TASK_ERROR_CODE_MAX))
|
|
60
|
+
return null;
|
|
61
|
+
const task = {
|
|
62
|
+
id: v.id,
|
|
63
|
+
sessionID: v.sessionID,
|
|
64
|
+
name: v.name,
|
|
65
|
+
direction: v.direction,
|
|
66
|
+
localPath: v.localPath,
|
|
67
|
+
remotePath: v.remotePath,
|
|
68
|
+
state: v.state,
|
|
69
|
+
bytes: v.bytes,
|
|
70
|
+
total: v.total,
|
|
71
|
+
startedAt: v.startedAt,
|
|
72
|
+
};
|
|
73
|
+
if (v.endedAt !== undefined)
|
|
74
|
+
task.endedAt = v.endedAt;
|
|
75
|
+
if (v.errorCode !== undefined)
|
|
76
|
+
task.errorCode = v.errorCode;
|
|
77
|
+
return task;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=transfer-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transfer-events.js","sourceRoot":"","sources":["../src/transfer-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import type { Readable, Writable } from "node:stream";
|
|
2
|
+
import type { ReadStreamOptions, Stats, WriteStreamOptions } from "ssh2";
|
|
3
|
+
/** 传输错误机器码(展示文案由 index.ts 按语言映射,不在本模块硬编码可见文本) */
|
|
4
|
+
export type TransferErrorCode = "exists" | "local_missing" | "local_is_dir" | "remote_missing" | "remote_is_dir" | "symlink" | "parent_missing" | "too_large" | "sftp_unavailable" | "timeout" | "io" | "unsupported" | "ssh_only" | "denied" | "tilde_user" | "remote_path_backslash";
|
|
5
|
+
/**
|
|
6
|
+
* 传输错误:只携带机器码 + 路径 + 内部诊断信息,展示文案由调用方按语言生成。
|
|
7
|
+
*/
|
|
8
|
+
export declare class TransferError extends Error {
|
|
9
|
+
readonly code: TransferErrorCode;
|
|
10
|
+
/** 出错涉及的路径(本地或远端,供文案回显) */
|
|
11
|
+
readonly path?: string;
|
|
12
|
+
/** 内部诊断信息(仅用于日志/io 文案,不是可见文案本身) */
|
|
13
|
+
readonly detail?: string;
|
|
14
|
+
/**
|
|
15
|
+
* @param code 机器码
|
|
16
|
+
* @param path 出错路径
|
|
17
|
+
* @param detail 内部诊断信息
|
|
18
|
+
*/
|
|
19
|
+
constructor(code: TransferErrorCode, path?: string, detail?: string);
|
|
20
|
+
}
|
|
21
|
+
/** 本模块使用的最小 SFTP 接口(与 ssh2 SFTPWrapper 结构兼容,单测可注入 fake) */
|
|
22
|
+
export interface TransferSftp {
|
|
23
|
+
stat(path: string, callback: (err: Error | undefined, stats: Stats) => void): void;
|
|
24
|
+
lstat(path: string, callback: (err: Error | undefined, stats: Stats) => void): void;
|
|
25
|
+
mkdir(path: string, callback: (err?: Error | null) => void): void;
|
|
26
|
+
rename(srcPath: string, destPath: string, callback: (err?: Error | null) => void): void;
|
|
27
|
+
unlink(path: string, callback: (err?: Error | null) => void): void;
|
|
28
|
+
realpath(path: string, callback: (err: Error | undefined, absPath: string) => void): void;
|
|
29
|
+
createReadStream(path: string, options?: ReadStreamOptions): Readable;
|
|
30
|
+
createWriteStream(path: string, options?: WriteStreamOptions): Writable;
|
|
31
|
+
end(): void;
|
|
32
|
+
destroy(): void;
|
|
33
|
+
}
|
|
34
|
+
/** 传输结果(成功时返回;不含文件内容) */
|
|
35
|
+
export interface TransferResult {
|
|
36
|
+
/** 实际使用的插件进程本机路径(~ 已展开) */
|
|
37
|
+
localPath: string;
|
|
38
|
+
/** 实际使用的远端路径(~/ 已由 SFTP 展开为绝对路径) */
|
|
39
|
+
remotePath: string;
|
|
40
|
+
/** 实际读/写字节数(来自流计数,不使用传输前 stat 值) */
|
|
41
|
+
bytes: number;
|
|
42
|
+
/** 耗时(毫秒) */
|
|
43
|
+
duration: number;
|
|
44
|
+
}
|
|
45
|
+
/** 上传参数(sftp 由 SshSession 注入) */
|
|
46
|
+
export interface UploadOptions {
|
|
47
|
+
sftp: TransferSftp;
|
|
48
|
+
localPath: string;
|
|
49
|
+
remotePath: string;
|
|
50
|
+
/** 目标存在时是否允许覆盖(默认 false = 独占创建,直接失败) */
|
|
51
|
+
overwrite?: boolean;
|
|
52
|
+
/** 父目录不存在时是否递归创建(默认 false = parent_missing) */
|
|
53
|
+
mkdir?: boolean;
|
|
54
|
+
/** 整个传输的超时(毫秒,默认 TRANSFER_TIMEOUT_MS) */
|
|
55
|
+
timeoutMs?: number;
|
|
56
|
+
/** 大小上限(字节,默认 MAX_TRANSFER_BYTES) */
|
|
57
|
+
maxBytes?: number;
|
|
58
|
+
/** 外部中止信号(会话层通道错误/超时注入;中止后立即拒绝且不再提交) */
|
|
59
|
+
abortSignal?: AbortSignal;
|
|
60
|
+
/**
|
|
61
|
+
* 进度回调(已传字节数 / 总字节数):拿到本地 stat 后先回调 `(0, size)`,
|
|
62
|
+
* 之后每累计一块回调一次;回调抛错会被吞掉,不影响传输本身。
|
|
63
|
+
*/
|
|
64
|
+
onProgress?: (bytes: number, total: number) => void;
|
|
65
|
+
}
|
|
66
|
+
/** 下载参数(sftp 由 SshSession 注入) */
|
|
67
|
+
export interface DownloadOptions {
|
|
68
|
+
sftp: TransferSftp;
|
|
69
|
+
remotePath: string;
|
|
70
|
+
localPath: string;
|
|
71
|
+
/** 本地目标存在时是否允许覆盖(默认 false = 独占创建,直接失败) */
|
|
72
|
+
overwrite?: boolean;
|
|
73
|
+
/** 本地父目录不存在时是否递归创建(默认 false = parent_missing) */
|
|
74
|
+
mkdir?: boolean;
|
|
75
|
+
/** 整个传输的超时(毫秒,默认 TRANSFER_TIMEOUT_MS) */
|
|
76
|
+
timeoutMs?: number;
|
|
77
|
+
/** 大小上限(字节,默认 MAX_TRANSFER_BYTES) */
|
|
78
|
+
maxBytes?: number;
|
|
79
|
+
/** 外部中止信号(会话层通道错误/超时注入;中止后立即拒绝且不再提交) */
|
|
80
|
+
abortSignal?: AbortSignal;
|
|
81
|
+
/** 进度回调(已传字节数 / 总字节数);语义同 UploadOptions.onProgress */
|
|
82
|
+
onProgress?: (bytes: number, total: number) => void;
|
|
83
|
+
}
|
|
84
|
+
/** 可执行文件传输的会话能力(仅 SshSession 实现;LocalSession 明确没有) */
|
|
85
|
+
export interface TransferCapableSession {
|
|
86
|
+
uploadFile(opts: Omit<UploadOptions, "sftp">): Promise<TransferResult>;
|
|
87
|
+
downloadFile(opts: Omit<DownloadOptions, "sftp">): Promise<TransferResult>;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* 上传:插件进程本机普通文件 → SSH 远端(SFTP)。
|
|
91
|
+
* 默认独占创建目标(flags "wx");overwrite 时写同目录临时文件再 rename 提交。
|
|
92
|
+
* 任一步失败清理临时/已创建的部分文件;超时中止通道且不主动发起新的 rename/commit(已发出的 rename 可能仍被执行)。
|
|
93
|
+
* @param opts 上传参数
|
|
94
|
+
* @returns 传输结果(路径/实际字节/耗时,不含内容)
|
|
95
|
+
*/
|
|
96
|
+
export declare function uploadFile(opts: UploadOptions): Promise<TransferResult>;
|
|
97
|
+
/**
|
|
98
|
+
* 下载:SSH 远端普通文件(SFTP)→ 插件进程本机。
|
|
99
|
+
* 默认本地独占创建(fs flags "wx");overwrite 时写同目录临时文件再 rename 提交。
|
|
100
|
+
* 任一步失败清理临时/已创建的部分文件;超时中止通道且不主动发起新的 rename/commit(已发出的 rename 可能仍被执行)。
|
|
101
|
+
* @param opts 下载参数
|
|
102
|
+
* @returns 传输结果(路径/实际字节/耗时,不含内容)
|
|
103
|
+
*/
|
|
104
|
+
export declare function downloadFile(opts: DownloadOptions): Promise<TransferResult>;
|
|
105
|
+
/**
|
|
106
|
+
* 校验 upload/download 的位置参数:必须恰好两个非空路径(多给/少给都报用法)。
|
|
107
|
+
* @param positionals 位置参数
|
|
108
|
+
* @returns 两个路径;不合法时 null
|
|
109
|
+
*/
|
|
110
|
+
export declare function parseTransferPositionals(positionals: string[]): {
|
|
111
|
+
first: string;
|
|
112
|
+
second: string;
|
|
113
|
+
} | null;
|
|
114
|
+
/**
|
|
115
|
+
* 断言会话具备文件传输能力(仅 SSH 会话):LocalSession 等明确拒绝。
|
|
116
|
+
* 用结构判定而非 instanceof,避免 transfer.ts 反向依赖 session.ts(循环导入)。
|
|
117
|
+
* @param session 终端会话
|
|
118
|
+
* @throws {TransferError} code=ssh_only
|
|
119
|
+
*/
|
|
120
|
+
export declare function assertTransferCapable(session: unknown): asserts session is TransferCapableSession;
|
|
121
|
+
//# sourceMappingURL=transfer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transfer.d.ts","sourceRoot":"","sources":["../src/transfer.ts"],"names":[],"mappings":"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"}
|