feat(acp/handlers): fs/read_text_file + fs/write_text_file with path safety

This commit is contained in:
2026-05-07 12:19:03 +08:00
parent de73ad4935
commit b9f38b6e94
5 changed files with 294 additions and 3 deletions
+40
View File
@@ -0,0 +1,40 @@
package handlers
import (
"context"
"encoding/json"
"os"
"path/filepath"
)
// FsWriteHandler handles fs/write_text_file (spec §5.4).
type FsWriteHandler struct{}
// NewFsWriteHandler constructs an FsWriteHandler.
func NewFsWriteHandler() *FsWriteHandler { return &FsWriteHandler{} }
type fsWriteParams struct {
SessionID string `json:"sessionId"`
Path string `json:"path"`
Content string `json:"content"`
}
// Handle writes a file inside sess.CwdPath, creating parent dirs as needed.
// Returns FsError for path-escape or filesystem failure.
func (h *FsWriteHandler) Handle(_ context.Context, sess SessionContext, paramsJSON json.RawMessage) FsResult {
var p fsWriteParams
if err := json.Unmarshal(paramsJSON, &p); err != nil {
return FsResult{Err: &FsError{Code: -32602, Message: "invalid params: " + err.Error()}}
}
abs, err := resolveSafePath(sess.CwdPath, p.Path)
if err != nil {
return FsResult{Err: &FsError{Code: -32001, Message: err.Error()}}
}
if err := os.MkdirAll(filepath.Dir(abs), 0o755); err != nil {
return FsResult{Err: &FsError{Code: -32603, Message: "mkdir: " + err.Error()}}
}
if err := os.WriteFile(abs, []byte(p.Content), 0o644); err != nil {
return FsResult{Err: &FsError{Code: -32603, Message: "write: " + err.Error()}}
}
return FsResult{OK: json.RawMessage(`{}`)}
}