/** * shell 型 execution-env 适配器把一次 **exec 失败**包成 `FileError` 时的**共享码映射**。 * * ── 为什么需要它(2026-07-25,深挖第一轮的跨腿对拆)──────────────────────────────────────────────── * `ssh` / `k8s` / `adb` / `local-docker` 的文件面都是「发一条 shell 命令,再把 `ExecutionError` 包成 * `FileError`」。**28 处**包装点写的全是同一句 `new FileError("unknown", r.error.message, …)` —— * 于是 exec 层已经正确分类出来的 `aborted`(用户取消)在文件层被**一律抹成 `unknown`**。 * * 🔴 后果不是"码不好看":`FileErrorCode` 里的 `aborted` 存在的唯一意义,就是让调用方分辨 * **「用户取消」与「硬失败」**。抹成 unknown 之后:①一次取消被措辞成失败;②任何 keyed-on-code 的重试 * 会把**已被取消的操作再打一遍**。host 腿没有这个问题,因为它直接用 `fs` + 自己的分类器 * (AbortError → `aborted`)—— 也就是说这 4 条腿丢的正是 host 腿有的那个信息。 * * 做成**一个共享函数而不是各腿各修一处**的理由:这一族有 28 个包装点,逐处修必然漏(core [ref] [ref] * 那条教训:宣布"类修完成"而三个实现只落了一个)。收成一处之后,判据只有一条 —— * **文件面的 exec 包装必须走这里**,而这条能被机器检查(见 `test/env-adapter-file-error-parity.test.ts`)。 */ import { FileError, type ExecutionError, type RemoteExecutionError } from "@sema-agent/core"; /** exec 层的错误码 → 文件层的码。只映射**有对应语义**的那些,其余落 `unknown`(诚实降级)。 */ export declare function fileErrorFromExec(e: ExecutionError | RemoteExecutionError, path?: string): FileError; /** * shell 命令 exit≠0 时把 **stderr** 分类成 `FileError` 的共享分类器([ref] B6 R2 裁决:k8s 形=正形)。 * * 此前四腿三向分叉:ssh/adb 硬编码 `not_found`(把 EACCES 谎报成"不存在"——keyed-on-code 的调用方会 * 对一个权限问题走"不存在"分支);local-docker 分类但无 fallback(缺文件报 unknown),且其 * `/no such file|not found/` 宽包含会把 `sh: realpath: not found`(**命令**缺失,127)误判成**文件**不存在。 * * 护栏次序是本函数的语义主体,先于分类: * 1. 命令缺失形(`command not found` / `applet not found` / `: not found`)→ `unknown` —— 工具不存在 * 不是文件不存在;probe 族的 not_found fallback 绝不能吞它。 * 2. 完整硬失败(EIO/ELOOP/ENAMETOOLONG/ENOSPC)→ `unknown` —— 同 k8s 原注:真错不被 read-op 的 * not_found fallback 吞掉。 * * `fallback` 由站点显式给:probe 族(readlink/realpath/stat——"它在吗"类问题)传 `not_found` * (空 stderr + exit≠0 的主导原因就是缺文件);mutate 族(mkdir/rm/mktemp)传 `unknown`(诚实降级)。 */ export declare function classifyFsStderr(stderr: string, p: string | undefined, fallback?: "unknown" | "not_found"): FileError; //# sourceMappingURL=remote-env-file-error.d.ts.map