资料库空间操作工具集(space-ops)
概述
把"操作 WorkBuddy 资料库(空间)"相关的所有动作收敛到一个技能里:上传文件、递归上传目录树、建文档、建文件夹、挪文件(移动节点)、改名字、列目录、搜索。用户在对话里说"上传/建文档/建文件夹/挪到某文件夹/重命名/列一下/搜一下 空间"时,Agent 应加载本技能并调用 scripts/space_ops.py。
底层全部复用 WorkBuddy 内置 library 技能的官方脚本(space_api.py / doc/create_doc.py / manage/create_folder.py),本技能只在上传环节做了加固(curl -k + 双凭证类型)+ 目录分组能力,不重复造轮子。
⚠️ 硬规则(务必遵守,曾经被用户反复纠正)
> 上传「一个目录」或「一批分属不同子目录的文件」时,必须先在空间建好与源目录结构对应的子文件夹,再分门别类上传。严禁把几十个文件全部平铺到同一个文件夹里。
- 整目录上传 → 一律用
upload-tree(自动按本地目录树建同名子文件夹并归位),不要用upload一个个平铺。 - 只有"少量、本来就在同一层的文件"才用
upload平铺(例如 2~5 个文档直接丢进某文件夹)。 - 判断标准:源有子目录 → 空间也要有对应子文件夹(镜像结构);源是一堆同层文件 → 才可以平铺。
- 传完后必须
list复核结构,确认子文件夹与归位正确,再向用户汇报。
> 空间没有删除 API。任何"待删除 / 待清理 / 待归档"的节点,一律 move 到「该空间顶层下的『删除』文件夹」,由用户在界面统一清理。
>
> - 约定:每个空间的顶层保留一个名为 「删除」 的文件夹,作为"待删暂存区"。首次用到时若不存在,则先 create-folder --title "删除"(建在空间顶层)。
> - 遇到"删不掉/要不要删/清理一下"的节点 → 直接 move 进「删除」文件夹,然后告知用户"已移入『删除』,可在界面统一清理"。
> - 严禁因为"空间删不掉"就卡住、把待删节点留在原处、或随便丢到别的业务文件夹。
> - 节点移入「删除」后不再从原处列出(等于软删除);这是本技能的标准清理路径。
何时使用
- 用户要把本地文件/脚本/模型/文档上传到空间某文件夹(含整个目录,如一个工程仓库)。
- 用户要新建一篇在线文档(Markdown),或改写/覆盖已有文档正文。
- 用户要新建文件夹做分组,或把节点移动/重命名做整理。
- 用户要列出某个文件夹内容,或搜索空间里的节点。
前置依赖
- 内置 library 技能必须已安装(提供
space_api.py等)。工具会自动探测其路径;异常时可用环境变量LIBRARY_SKILL_DIR覆盖。 - 需要知道目标的
spaceId(空间 ID)和文件夹nodeId(parent-id/--target-parent-id)。用list子命令或在 library 技能里list-user-spaces/list-nodes查。
工作流(统一入口:space_ops.py)
所有子命令都通过本技能 scripts/space_ops.py 转发。通用参数:--space-id <ID>、--parent-id <ID> 也可用环境变量 SPACE_ID / PARENT_ID 提供。
1) ★ 递归上传整个目录(推荐,自动分组)★
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" upload-tree \
D:/path/to/ks_farm \
--space-id <spaceId> --parent-id <folderNodeId>
- 会先建一个名为源目录名(
ks_farm)的文件夹,再按其下的core/ flow/ po/ test/ ...自动建同名子文件夹,文件各归其位(镜像本地目录树)。 - 默认跳过
.git、.state、__pycache__、node_modules等目录与隐藏文件(见脚本SKIP_DIRS)。 - 传多个目录:
upload-tree dirA dirB --space-id X --parent-id Y。 --strip-root:不额外包一层根文件夹,直接把每个目录的内容铺到--parent-id下(当你想把core/ po/ ...直接挂在既有的「04-工程脚本」下时用这个)。
2) 上传少量同层文件(平铺)
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" upload \
path/to/a.stl path/to/b.md \
--space-id <spaceId> --parent-id <folderNodeId>
仅用于"本来就同层的少量文件"。.md 会自动转成在线 doc 节点,其余为 drive 节点。
若文件分属多个子目录 → 不要用本命令,改用 upload-tree。
3) 新建文档
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" create-doc \
--title "我的文档" --content-file doc.md \
--space-id <spaceId> --parent-id <folderNodeId>
4) 改写 / 全量覆盖已有文档(⚠️ 危险:清空原正文)
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" create-doc \
--node-id <已有文档节点ID> --space-id <spaceId> \
--content-file new_doc.md --confirm-overwrite
必须先取得用户明确同意——此操作会清空并替换目标文档整棵正文块树(节点链接、标题、ID 保留)。
5) 新建文件夹(纯容器,无正文)
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" create-folder \
--title "01-设计文档" --space-id <spaceId> --parent-id <folderNodeId>
6) 移动节点到目标文件夹
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" move \
--node-id <要移动的节点ID> --target-parent-id <目标文件夹ID>
> "待删除"节点:--target-parent-id 填该空间顶层的 「删除」文件夹(见"硬规则")。这是空间唯一的"删除"路径。
7) 重命名节点
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" rename \
--node-id <节点ID> --title "新名字"
8) 列出文件夹 / 空间顶层子节点
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" list \
--space-id <spaceId> --parent-id <folderNodeId> --limit 100
# 省略 --parent-id 则列出空间顶层
9) 搜索节点
python3 "${CODEBUDDY_SKILL_DIR}/scripts/space_ops.py" search --query "交接" --num 20
注意:搜索按内容/标题索引,可能不全,正式定位节点请以 list 为准。
关键避坑(排错前必读)
完整清单见 references/space_ops_pitfalls.md。最致命的几条:
- ❗上传整目录必须用
upload-tree分组:用户已两次明确纠正"传完一堆脚本却平铺在一个文件夹里,看起来很乱"。凡源目录有子目录,空间就必须建对应子文件夹。 - 上传必须
curl -k:本机 Pythonurllib直连 COS 报WinError 10061;curl不带-k会因 Windows schannel 证书吊销检查(CRYPT_E_REVOCATION_OFFLINE)失败。该坑已内置于upload_to_space.py,不要试图改回 urllib。 - 两种凭证类型:
drive类型(代码/二进制)带headers.Authorization+confirmKey;cos类型(.md)的uploadUrl自带签名、无confirmKey。脚本已自动分支,不要硬编码单路径。 - 改写文档要双重保险:
--confirm-overwrite必须显式传,且调用前需用户明确同意(清空正文不可逆)。 - 建文档仅支持 Markdown:正文里若出现
<Paragraph>/<Table>等组件标签,create_doc.py会拒绝。 - 空间没有删除 API:删除节点只能在 WorkBuddy 界面手动操作。标准清理路径=把待删节点
move到该空间顶层的「删除」文件夹(见"硬规则"),再由用户在界面统一清理——不要因为"删不掉"就卡住或把待删节点乱放。 - 移动"空文件夹"可能失败:实测对空文件夹执行
move报code=11510 node index not found(空节点未被索引)。对策:需要移动空文件夹时请用户在界面删除,或先往其中放一个占位节点再移。 - 覆盖已有文件别"重传":更新空间里已存在的文件内容,用
upload_drive_file.py <path> --node-id <现有节点ID>覆盖同一节点;不要重新upload一个同名新文件——那会产生重复节点(曾因此堆出 7 份重复文档)。 - 改在线文档正文块走
submit_doc_edit.py(组件语法),与create_doc.py(整篇 Markdown)是两条路;表格单元格在 direct-edit 下无 in-cell 路径(报 11607),须整表替换(insert 新表→读回→删旧表)。详见references/space_ops_pitfalls.md第 8 节。
资源
scripts/space_ops.py—— 统一入口(8 个子命令,含upload-tree递归分组上传)。scripts/upload_to_space.py—— 加固上传器(被upload/upload-tree复用;也可单独使用)。references/space_ops_pitfalls.md—— 所有操作的综合避坑手册。
变更记录
- v2.2.0(2026-10-13):新增「删除」文件夹约定 —— 空间无删除 API,任何待删节点统一
move到空间顶层的「删除」文件夹暂存、由用户在界面统一清理(已写入"硬规则"、第 6 节 move、避坑手册第 7 节);并补充"移动空文件夹会失败(code=11510)"的避坑。 - v2.1.1:上传加固(
curl -k+ drive/cos 双凭证);新增upload-tree递归分组上传;覆盖已有文件防重复节点。