Files
homeagent-sdk/example/files
JianFeeeee b6a6168e65 chore(module)!: module 路径随托管地迁移 gitcode → github
SDK 仓已迁到 GitHub 作为权威源,go module 路径同步:
`gitcode.com/JianFeeeee/homeagent-sdk` → `github.com/JianFeeeee/homeagentsdk`

## 范围

74 个文件:71 个 Go 源码 + go.mod/go.sum + hmapdev 模板 + CI 与打包脚本。

主仓(HomeAgent)侧对应改动是 6d38a164。本仓这些文件当时**不在工作树上**
(见下),所以那次的批量替换扫不到它们——这里是补偿。

## 为何这批文件当时不在工作树上(事故与恢复)

10-08 07:58 主仓做 checkout/cherry-pick 序列时,把本仓工作树的 20 个文件
误清理了(`example/*/plugin.go` + `plg.json`,10 个示例)。

根因是**结构误判**:本仓是「一目录两仓库」结构下主仓 `third_party/` 里的
**独立 git 仓库**,而主仓 .gitignore 忽略了 `example/`,于是它在主仓
`git status` 里不可见 —— 看着像「不受跟踪的构建产物」,实际是本仓受跟踪的源码。

已全部恢复(`git checkout -- <D 文件>`,只恢复删除、不动迁移改动),
20 个文件与 HEAD 逐字节一致。

**破坏的连锁后果**:恢复出来的 `plugin.go` 仍写着旧 module 路径,
因为迁移时它们已不在工作树上。所以这次补偿是必须的,不是可选优化。

## 保留 gitcode 引用

以下位置的 `gitcode` **有意保留**,不要"顺手清掉":
- README.md / docs 里「二进制实际分发地址目前是 gitcode」的说明
- mkdocs.yml 的 gitcode 镜像链接(国内直连更快)
- `tools/hmapdev/templates.go` 里「SDK 已从 gitcode 迁到 GitHub」的注释

gitcode 仍是**只读镜像**(源码同步;release 附件暂时仍在那边)。

## 验证

- 本仓根 module:`go build ./...` + `go test ./...` 全通过
- 全部 20 个 example:`go vet` 通过(补偿前 10 个因旧 module 路径失败)
- example/qq:`go test` 通过,且能从源码 build 出可用 plugin 产物
2026-10-09 07:25:25 +08:00
..

files · 沙箱文件操作

读写与编辑文件,全部操作限制在沙箱目录内。

工具

工具 说明
files_read 读文件内容,支持 offset / limit 读大文件
files_write 写文件,自动创建父目录
files_edit 按精确字符串替换改文件
files_ls 列目录(目录名带 / 后缀)

files_edit 用 edits[] 传多组替换,每组 {old, new}:

  • 每个 old 必须在原文件中恰好出现一次 —— 不唯一会报错,避免改错地方。
  • 所有替换都针对原内容匹配,不要在同一个 edits 里写相互重叠的改动。

配置项

键 默认 说明
dir 空 允许访问的根目录。留空用默认沙箱(主数据目录下的 files_sandbox)。不建议设为 /

沙箱实现

路径校验不止一次,是两道:

  1. 规范化后判断:filepath.Abs + filepath.Clean,再用 withinSandbox 检查结果是否在根目录之下(/ 作为特例放行)。
  2. 解析符号链接后再判断:filepath.EvalSymlinks 求出真实路径,再查一次沙箱。

第 2 步是关键:只做第 1 步的话,沙箱内一个指向外部的软链接就能绕过限制 (.../sandbox/link -> /etc)。报错文案也区分了这两种情况 (path outside sandbox vs path escapes sandbox via symlink)。

对不存在的路径(write 会用到),求真实路径时只对已存在的部分做 EvalSymlinks, 其余保留为未创建的尾部。

构建

hmapdev build