关于 temp-files
供 Agent 之间临时传递文件、目录和整站快照的技能,适用于短期协作交接。它按路径存储并支持短链接,文件会过期,且用户与 Agent 各自使用隔离空间。
主要功能
- 01上传和覆盖文件或目录
- 02列出中继空间内容
- 03下载文件或目录 ZIP
- 04删除文件及目录
- 05创建和撤销短链接
- 06下载后自动解压归档
适用场景
- 01将技能文件交给另一个 Agent 测试
- 02向协作者传递暂存网站快照
- 03通过短链接让接收方获取文件
- 04清理已完成交接的临时文件
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ starchild-ai-agent/ official-skills --skill temp-files安装后在 Claude Code 中输入/temp-files确认已加载。
附带文件scripts/tf.py
详细介绍
Temp-Files — Workroom 文件中转
此技能可让一个 Agent 将临时文件、目录或整个网站快照交给另一个 Agent,而不会污染长期备份命名空间,也无需使用外部文件托管服务。
| 触发语 | 流程 | 功能 |
|---|---|---|
/tf put、"drop this file in the relay"、"share this with agent B" | A. 上传 | 写入路径 → 返回 expires_at |
/tf list、"show me what's in the relay"、"list temp files" | B. 列表 | 单层 ls:文件和子目录 |
/tf get、"pull X down"、"download X" | C. 下载 | 文件直接传输 / 目录打包为 zip |
/tf rm、"delete X from the relay" | D. 删除 | 单个文件,或使用 --recursive 删除子树 |
/tf link、"make a temp link for agent B" | E. 短链接 | 创建 tf_xxxx 内部短链接 |
每条命令都会访问同一个服务(sc-agent-backup.internal),并使用容器内置的 CONTAINER_JWT 进行身份验证。身份和路径从 JWT 中派生:
user_id = JWT.userInfoID、agent_scope = JWT.containerId(默认为
default)。你无法访问、查看或删除属于其他用户或其他 Agent 的中转文件。
与 backup 技能的区别(必读)
| 维度 | backup 技能 | temp-files 技能(本技能) |
|---|---|---|
| 用途 | Agent 长期状态 | 短期交接、协作中转 |
| 寻址方式 | 服务端生成的 backup_id | 调用方指定的路径 |
| 模型 | 不可变的 tar.gz 包 | 基于路径的文件系统,可覆盖 |
| 配额 | 每位用户 5 个包,硬性上限 | 字节配额 + 单文件大小限制 |
| TTL | 无 | 默认 7 天,访问或覆盖时滑动续期,硬性上限为 60 天 |
| 跨 Agent | 恢复整个包 | 按文件 / 目录操作 + 短链接 |
切勿混用。“恢复整个 Agent 状态” → 使用 backup。
“交接单个产物,让另一个 Agent 接着处理” → 使用本技能。
操作规则
规则 1 — 不要将中转服务用作文件托管
文件的默认 TTL 为 7 天。即使覆盖或下载会滑动续期,硬性上限仍为 60 天。需要长期保留的内容应通过 backup 或 volume-backup 处理。
规则 2 — 路径白名单
服务端只接受匹配 [A-Za-z0-9._\- ] 的路径片段。它会拒绝
..、绝对路径、空片段和控制字符。只需传入相对路径:
skills/my-skill/SKILL.md✅sites/staging/index.html✅../escape.txt❌ → 400 bad_path/abs/oops.md会去掉开头的斜杠 — 最好不要这样传入
规则 3 — 短链接用于“Agent 之间的内部传递”,而非公开分享
第一版短链接采用能力 URL 模型:
- 持有
tf_xxxxxxxx的任何人都可以获取文件(代码本身就是凭证,熵为 64 位) - 但仍需连接 6PN 内部网络,并提供有效的
CONTAINER_JWT(用于审计) - 浏览器或未携带令牌的
curl会收到 401 — 这是预期行为,不是缺陷 - 跨用户 Agent 可以获取文件,因为这正是 Workroom 交接的使用场景
正确流程:
- Agent A 调用
/tf put上传文件 - Agent A 调用
/tf link并收到tf_xxxxxxxx - Agent A 通过 Workroom 将短链接发送给 Agent B
- Agent B(位于 Fly 内部,使用自己的
CONTAINER_JWT,用户也可能不同)调用tf fetch tf_xxxxxxxx获取文件
不要将 http://sc-agent-backup.internal:8080/t/<code> 交给最终用户,让其在浏览器中打开 — 该地址无法通过公网访问。如果/当公开分享功能上线,请等待 B 阶段的公共解析器。
清理规则:接收方确认已收到文件后,发送方应立即执行 tf unlink <code>,撤销短链接并避免令牌继续留存。敏感内容必须取消链接 — 不要依赖 TTL 作为兜底。
规则 4 — 失败时停止,不要静默重试
如果任何 tf.py 子命令以非零状态退出,立即停止,并将 stderr 原样返回给用户。不要说“我再帮你试一次”。
安装路径
该技能安装在 /data/workspace/skills/temp-files/。所有命令都从 Agent 的工作目录运行:
python3 skills/temp-files/scripts/tf.py <subcommand> ...
命令参考
所有命令的环境变量:
CONTAINER_JWT— 由 ai-agent 注入,必需TEMP_STORAGE_URL— 可选,默认为http://sc-agent-backup.internal:8080
全局输出开关(放在子命令之前):
--verbose:输出完整负载/错误元数据(用于调试)--json:稳定的 JSON 封装,成功和失败时使用相同的键- 成功:
{ok: true, error: "", message: "ok", detail: "", data: {...}}data默认为命令的精简视图(包含最少的实用字段)- 使用
--verbose时,data将变为服务端的原始负载(包含所有字段)
- 失败:
{ok: false, error: "<code>", message: "...", detail: "...", exit_code: N}error是服务端的错误代码(例如bad_path/not_found/quota_exceeded)或usage_error/http_error- 使用
--verbose时,会包含meta子结构(HTTP 状态/服务端原始消息和详情)
- 成功:
- 默认(不使用开关):精简输出,只包含最实用的最少字段(便于人类和 Agent 阅读)
注意:不带 --json 时,tf list 和 tf links 会输出便于阅读的表格;
使用 --json 时,它们会通过封装输出,并由 data 携带完整的
entries/links 数组。
推荐默认值(速查)
| 标志 | 推荐值 | 原因 |
|---|---|---|
link --ttl-seconds | 3600(1 小时) | 时间足够让接收方获取一次,又不会过久 |
put --ttl-days | 7(默认值) | 覆盖典型的审核周期 |
fetch --extract | 始终传入 | 自动解压,少一步操作,并内置 zip-slip 防护 |
对目录使用 get | 必须传入 --zip | 服务端不支持直接下载普通目录 |
交接后执行 unlink | 收到接收方确认后立即调用 | 短代码等同凭证;必须撤销敏感内容的访问权限 |
A. 上传/覆盖
python3 skills/temp-files/scripts/tf.py put <local-file> <remote-path> \
[--ttl-days N]
示例:
python3 skills/temp-files/scripts/tf.py put ./SKILL.md skills/demo/SKILL.md
# → {"path": "...", "size_bytes": ..., "expires_at": ...}
同名上传会覆盖原文件;响应会返回新的 expires_at。
B. 列出
python3 skills/temp-files/scripts/tf.py list [--prefix PATH]
不带 --prefix 时会列出根目录;--prefix sites/ 会列出该目录下的一层内容。
C. 下载
# Single file
python3 skills/temp-files/scripts/tf.py get <remote-path> <local-dest>
# Whole directory as a zip
python3 skills/temp-files/scripts/tf.py get <remote-dir> <local-dest.zip> --zip
下载成功后,TTL 会延长 7 天。
D. 删除
# Single file / empty directory
python3 skills/temp-files/scripts/tf.py rm <remote-path>
# Non-empty directory
python3 skills/temp-files/scripts/tf.py rm <remote-dir> --recursive
E. 短链接
python3 skills/temp-files/scripts/tf.py link <remote-path> \
[--zip] [--ttl-seconds 3600]
# → {"code": "tf_xxxxxxxx", "url": "http://.../t/tf_xxxxxxxx", ...}
# List currently active short links
python3 skills/temp-files/scripts/tf.py links
# Revoke
python3 skills/temp-files/scripts/tf.py unlink <code>
短链接 TTL 默认为 1 小时,最长为 7 天(独立于文件自身的 TTL)。
F. 通过短链接拉取数据(接收方 Agent 运行的命令)
# Download + auto-unpack (strongly recommended)
python3 skills/temp-files/scripts/tf.py fetch <code> <local-dest> --extract
# Or specify the extract directory
python3 skills/temp-files/scripts/tf.py fetch <code> ./pack.zip --extract ./out
# Without --extract: download only, no unpack
python3 skills/temp-files/scripts/tf.py fetch <code> <local-dest>
任何持有有效 CONTAINER_JWT 的调用方都可以获取数据(允许跨用户)。
Zip 自动检测:当服务端返回 Content-Type: application/zip 时,fetch 和
get 会自动将本地文件重命名为以 .zip 结尾,并在 JSON 输出中通过 "kind": "zip" 告知你。
自动解压(--extract):
- 使用 Python 内置的
zipfile/tarfile;无需依赖系统的unzip/7z - 支持的格式:
.zip/.tar/.tar.gz/.tar.bz2/.tar.xz(根据 魔数检测,而非文件后缀) - 内置 zip-slip/tar-slip 防护:拒绝包含
..片段的路径;拒绝符号链接成员 - 不带值时:解压到同级目录(名称为归档文件名去掉后缀);带值时:解压到指定目录
- 解压成功后,JSON 输出会包含
extracted_kind/extracted_to/extracted_top
示例 JSON 输出(使用 --extract):
{
"saved": "output/tf_from_4814.zip",
"kind": "zip",
"bytes": 7363,
"sha256": "...",
"content_type": "application/zip",
"server_filename": "temp-files-share.zip",
"extracted_kind": "zip",
"extracted_to": "output/tf_from_4814",
"extracted_top": ["temp-files-share/"]
}
因此,接收方 Agent 应当:
- 默认使用
--extract调用fetch - 从 stdout JSON 中读取
extracted_to— 文件位于该目录中 - 如果 JSON 包含
extract_skipped或extract_error,则回退到saved路径,并根据kind手动处理
典型场景
场景 1:Agent A 将技能交给 Agent B 测试
# A:
python3 skills/temp-files/scripts/tf.py put ./my-skill.zip skills/my-skill.zip
python3 skills/temp-files/scripts/tf.py link skills/my-skill.zip --ttl-seconds 3600
# Receive tf_xxxxxxxx, post it to B in Workroom
# B: (recommended: fetch + auto-unpack in one shot)
python3 skills/temp-files/scripts/tf.py fetch tf_xxxxxxxx ./inbox.zip --extract
# The fetch JSON already includes sha256 — no need to rerun sha256sum
# cd into JSON.extracted_to to test; write a report
python3 skills/temp-files/scripts/tf.py put ./test-report.md reports/test-report.md
python3 skills/temp-files/scripts/tf.py link reports/test-report.md --ttl-seconds 1800
# Send the report short link back to A
# Once A has the report:
python3 skills/temp-files/scripts/tf.py unlink tf_xxxxxxxx # revoke the original skill short link
场景 2:Agent A 将预发布站点交给 Agent B
# A:
cd ./staging-site/
python3 skills/temp-files/scripts/tf.py put-dir . sites/foo --ttl-days 14
python3 skills/temp-files/scripts/tf.py link sites/foo --zip
# B receives a directory-zip link
# B:
python3 skills/temp-files/scripts/tf.py fetch tf_xxxxxxxx ./foo.zip --extract
cd ./foo
# Edit, then push back
python3 skills/temp-files/scripts/tf.py put-dir . sites/foo
安全边界速查表
- 仅限 6PN:服务在公共互联网中会返回 403
- JWT 必须有效,且
type ∈ {container, access} - 每位用户都有隔离的命名空间;该用户下的每个 Agent 都有自己的子范围
- 直接访问
/temp-files/...路径时会隔离用户(无法访问其他用户的文件) /t/<code>短链接是访问凭证:任何知道该代码的人都可以获取(仍需 6PN + 任意有效 JWT 以供审计)- 路径会拒绝
..和控制字符 - 单个文件上限为 200 MB,每位用户的配额为 2 GiB(可由服务端调整)
常见错误 / 故障排查
先查看
ERROR + DETAIL,再判断问题属于参数、权限还是对象缺失。 如果命令以非零状态退出,请遵循既定规则:停止,不要悄悄重试。
| 场景 | 常见 stderr | 根本原因 | 处理方式 |
|---|---|---|---|
路径非法(../空片段/非法字符) | HTTP 400 + DETAIL: error=bad_path, message=... | remote-path 不符合白名单 | 改用常规相对路径,例如 skills/demo/SKILL.md |
| 对象不存在 | HTTP 404 + DETAIL: error=not_found, message=... | 目标文件/目录缺失 | 运行 tf list --prefix ... 确认,然后重试 |
| TTL 超出范围 | ERROR: --ttl-days must be <= 60 或 --ttl-seconds ... | CLI 参数超出范围(预先检查) | 使用允许范围内的值 |
| 未获授权 | HTTP 401/403 | 缺少/无效的 CONTAINER_JWT,或在内部网络之外运行 | 在 Fly 机器内运行;确认已注入 JWT |
未使用 --zip 下载目录 | HTTP 400(DETAIL 中提及下载模式) | 服务端要求目录使用 zip 模式 | tf get <dir> out.zip --zip |
| 未使用递归选项删除非空目录 | HTTP 400/409 | 目录非空,但未传入 --recursive | tf rm <dir> --recursive |
| 文件过大或目录压缩包超出限制 | HTTP 413 | 超出服务端大小限制 | 拆分目录/文件后重新上传 |
最小回归检查清单(P1 门槛)
每次修改 CLI 输出或错误处理后,至少运行以下六项:
- 默认输出简洁(不带
--verbose),但 put/get/fetch 仍包含sha256,link 仍包含url --verbose会输出完整字段集(信封中的data= 服务端原始负载)- 成功时,
--json包含所有键:ok, error, message, detail, data - 失败时,
--json包含所有键:ok, error, message, detail, exit_code(其中error为服务端错误代码) - 退出代码保持一致:成功 = 0,业务失败 = 1,用法错误 = 2
tf --json list和tf --json links使用信封格式(不要让子解析器的--json覆盖)
快速分诊流程(与协作者分享)
tf list --prefix <target-prefix>:确认对象确实存在。- 保留失败命令原始的 stderr(尤其是
DETAIL:)。 - 遇到 4xx:修正参数——不要重试相同命令。
- 遇到 5xx / 网络错误:稍等片刻,然后重试一次。
备注
- 文件 TTL 默认为 7 天;每次下载/覆盖都会续期 7 天;硬上限为 60 天
- 短链接 TTL 默认为 1 小时,上限为 7 天
- 如需强制缩短 TTL:上传时传入
--ttl-days 1(仍受有效期限限制) - 目录 zip 的默认上限:5000 个文件 / 500 MB;超过任一上限 → 413