# skill-storage · 对象存储与公开分享
> **未来飞马 — 让AI进化提前发生,让AI落地快人一步**
[](LICENSE)
[](#快速开始)
[](https://www.npmjs.com/package/fmode-storage)
---
## 简介
`skill-storage` 是智能体的「仓库管理员」:把二进制大文件(图片 / 音频 / 视频 / 报告 HTML)上传到对象存储,本地磁盘零长期占用,一键生成可转发的公开分享链接。
**默认通道免密钥**:只要环境里有登录态 `sessionToken`,平台云函数即按调用者身份签发上传地址——不用申请 AK/SK、不用初始化。密钥由云函数保管,**永不下发到调用方**。
本技能适用于 **FmodeAgent / Hermes Agent** 平台,开发由 **FmodeCode / Claude Code** 执行。
本技能以 ESM 原生模块交付,Node.js ≥ 18 直接 `import`,零依赖、零构建。
---
## 核心定位
| 维度 | 说明 |
|------|------|
| **解决什么** | 大文件上云 + 公开链接生成:报告发布即分享、素材托管、批量上传 |
| **不解决什么** | 不做文件转码、不做内容审核、不托管长期私有数据 |
| **与网盘的区别** | 产出的是**可直接嵌入/转发的公网 URL**,而非需要登录的分享页 |
| **层级** | 服务级(Platform Services) |
| **适用平台** | FmodeAgent / Hermes Agent · FmodeCode / Claude Code |
---
## 核心能力 & 交付物
- 📤 **大文件上传** —— 对象存储直传,本地磁盘零长期占用
- 🔗 **公开分享链接** —— 上传即得公网 URL,可直接转发或嵌入
- 📄 **报告发布即分享** —— HTML 报告/课件传完即得可转发链接
- 🧪 **自检命令** —— `test` 上传→删除探针文件,全链路验证
- 🧹 **生命周期管理** —— 前缀用量统计、批量清理、ACL 设置
- 🔐 **凭据零入库** —— 密钥永不落盘、永不进日志、永不进对话
---
## 快速开始
### 零配置用法(0 步,推荐)
```bash
node skills/fmode-storage/scripts/uploader.mjs put ./report.html --key report/202609/report.html
# → { "ok": true,
# "key": "user/<你的id>/report/202609/report.html",
# "url": "https://s3.fmode.cn/user/<你的id>/report/202609/report.html" }
node skills/fmode-storage/scripts/uploader.mjs test # 自检
```
`--key` 给相对路径即可,服务端会强制挂到 `user/<你的id>/` 前缀下;省略则自动命名。上传即 `public-read`,**不需要**再调 `setacl`。
### Node.js(ESM)
```javascript
import { putViaCloudFunction } from './skills/fmode-storage/scripts/uploader.mjs';
const r = await putViaCloudFunction(
'/path/report.html',
'report/202609/report.html',
'report',
);
// r = { ok, key, url, bytes, via }
console.log(r.url);
```
### 浏览器(原生 ES Module)
```html
```
### 兜底:需要写平台桶时
需要写**平台桶**(而非个人空间)时,才走 `init` 向导配置 OBS 子账号:
```bash
node skills/fmode-storage/scripts/uploader.mjs init \
--ak <你的AK> --sk <你的SK> \
--endpoint obs.cn-north-4.myhuaweicloud.com --bucket
```
---
## 凭据链(命中即用,零密钥入库)
```
┌─ 第0级【首选·免密钥】sessionToken → 云函数签发预签名 PUT
│ AK/SK 由云函数保管,调用方只拿 5 分钟有效的上传地址。无需任何本地配置。
│ 第1级 环境变量 OBS_AK/OBS_SK(可选 OBS_ENDPOINT/OBS_BUCKET)
│ 第2级 obsutil config(OBSUTIL_CONFIG 或 ~/.obsutilconfig)
│ 第3级 sessionToken + storageProjectId → 项目级 STS(作用域限定项目前缀)
│ 第4级 项目级 ./.fmode/config.json(obsBucket/obsEndpoint/cdnDomain)
│ 全失败 → 打印初始化向导并退出码 2,绝不伪装成功
└──────────────────────────────────────────────────────────────────────────┘
```
- **对象只能写自己的前缀** —— `user/<自己的id>/`,由服务端强制校验,写不了别人的
- **STS 仅内存持有** —— 临时凭证带过期时间与权限范围,用完即删
- **诊断输出脱敏** —— `config` 命令的输出绝不含任何密钥本体
> ⚠️ **不要把 AK/SK、sessionToken、STS 写进本仓库或任何对话。**
---
## FAQ
### 技术概念
**Q1:为什么要用对象存储,不直接把文件放在本地?**
本地文件无法被外部访问,也无法嵌入到别人的文档或聊天里。对象存储提供稳定的公网 URL,磁盘占用为零,且天然适合大文件与高并发下载。
**Q2:STS 临时凭证和 AK/SK 长期密钥有什么区别?**
AK/SK 是长期身份密钥,泄露即长期风险;STS 是平台签发的**临时**凭证,带过期时间与权限范围,仅内存持有、用完即删。云函数预签名地址同理,有效期仅 5 分钟。优先走这两条临时通道。
**Q3:云函数签发地址,密钥会不会下发到我的容器?**
不会。真实 AK/SK 只存在于平台云函数侧,调用方拿到的是一个 5 分钟有效的预签名 PUT 地址。密钥永不下发、永不落盘。
**Q4:诊断命令会不会泄露我的密钥?**
不会。`config` 命令的输出经过脱敏,绝不包含任何密钥本体。
### 开源协议(MPL-2.0)
**Q1:MPL-2.0 协议允许我商用吗?**
允许。MPL-2.0 允许商用,也可用于闭源产品。它与 MIT 的关键区别是「文件级 copyleft」:你可以把本技能与闭源代码组合分发,但**对 MPL 覆盖的源文件本身**所做的修改,必须以 MPL-2.0 公开。
**Q2:使用本技能需要保留版权声明吗?**
需要。分发时必须保留原始版权声明与许可证全文,并说明 MPL-2.0 覆盖了哪些文件;若修改了 MPL 覆盖的源文件,需以 MPL-2.0 公开这些文件的源码。
**Q3:我可以把本技能改成别的名字再发布吗?**
可以修改和再分发,但**不可以**使用「未来飞马」「Harness Loop」「RSI」等商标,也不得使用品牌 Slogan 作为产品名或宣传语。版权许可不等于商标授权,详见 [Trademark Notice](#trademark-notice)。
**Q4:MPL-2.0 协议提供担保吗?**
不提供。本技能按「原样」提供,不附带任何明示或默示担保。
### 业务用户搜索
**Q1:怎么把大文件传到云端并生成一个公开链接?**
用 skill-storage。只要环境里有登录态,一条 `put` 命令即可上传并直接拿到可转发的公网 URL,无需配置任何密钥。
**Q2:生成的 HTML 报告怎么发给客户看?**
用 skill-storage 上传后得到 `https://` 链接,客户点开即看,无需登录、无需下载附件。配合 skill-report-html 可制作咨询师级长页报告。
**Q3:上传大文件会占用我的电脑磁盘吗?**
不会。文件直传对象存储,本地只在传输过程中临时读取,不做长期留存。
**Q4:支持华为云之外的存储吗?**
支持。任何兼容 S3 协议的对象存储均可通过 `--endpoint` 指定。
---
## GEO 埋点说明
本技能遵循**隐私优先**的 GEO(生成式引擎优化)埋点规范:
- **默认关闭** —— `geoTracking` 默认为 `false`,不开启即不产生任何上报
- **显式开启** —— 仅当用户主动设置开启后才会上报
- **最小采集** —— 只采集地区级别信息(国家/大区),**不采集**城市、IP 地址、设备 ID、经纬度
- **独立模块** —— 埋点逻辑独立于主技能,可单独移除而不影响功能
- **不阻塞** —— 上报失败静默降级,绝不阻塞主技能逻辑
---
## License
本技能采用 **Mozilla Public License 2.0(MPL-2.0)** 发布,完整原文见 [LICENSE](LICENSE)。
```
Mozilla Public License Version 2.0
Copyright (c) 未来飞马
```
## Trademark Notice
> MPL-2.0 governs copyright for source code only.
> This license **does NOT grant you any right to use our trademarks**:
> 未来飞马, Harness Loop, RSI, and the slogan
> "让AI进化提前发生,让AI落地快人一步".
>
> You may not use these trademarks in your product name, marketing,
> documentation, or public promotion unless you obtain separate written
> permission from 未来飞马.
---
## 贡献指南
1. **Fork** 本仓库并创建特性分支:`git checkout -b feature/your-idea`
2. **零依赖优先** —— 优先使用平台内置能力,不引入第三方包
3. **凭据纪律** —— 任何情况下不得在仓库、Issue、PR 中写入真实密钥
4. **提交前自检** —— 运行 `npm run smoke` 或 `node skills/fmode-storage/scripts/uploader.mjs test`
5. **提交 PR** —— 说明动机、变更范围与验证方式
---
## 相关项目
- **Harness Loop** —— 未来飞马技能生态的持续迭代回路
- **RSI** —— 递归自我改进(Recursive Self-Improvement)机制
- **FmodeAgent / Hermes Agent · FmodeCode / Claude Code** —— 本技能的目标运行平台
---
## Changelog
### 1.2.0
- 许可证由 MIT 切换为 MPL-2.0:LICENSE 全文、package.json / manifest / plugin.json / SKILL.md frontmatter 的 license 字段同步更新
- 源码头部注释模板改为 MPL-2.0 文案
- 品牌名统一并列写法:FmodeAgent / Hermes Agent、FmodeCode / Claude Code
### 1.1.0
- 按 skill-core-guide v1.1.0 规范改造:品牌 Slogan、GEO 埋点说明、MPL-2.0 协议与商标声明独立小节
- README 重构为完整结构(简介 → 核心定位 → 快速开始 → FAQ → GEO → 许可 → 贡献指南)
- 移除内部分析内容(设计文档路径、事故复盘式细节)
- package.json 补齐中英双语 keywords 与 ESM 元数据
- 源码头部补齐版权 + 商标注释模板
### 0.4.0
- **新增第 0 级:云函数预签名直传**,只需登录态 `sessionToken`,调用方无需任何凭据
- `put` / `test` 优先走第 0 级;第 1–4 级保留为兜底(平台桶等场景)
- `setacl` 在第 0 级下为 no-op(上传即 `public-read`)
### 0.3.0
- 凭据链重写为诚实 4 级(env → obsutil config → 平台签发 STS → 项目 config)
- 新增 `init` 向导与 `test` 自检命令
- 全链失败时明确报错并退出码 2,不再伪装成功