# skill-storage · 对象存储与公开分享 > **未来飞马 — 让AI进化提前发生,让AI落地快人一步** [![License: MPL-2.0](https://img.shields.io/badge/License-MPL--2.0-brightgreen.svg)](LICENSE) [![ESM](https://img.shields.io/badge/module-ESM--only-orange.svg)](#快速开始) [![npm](https://img.shields.io/badge/npm-fmode--storage-blue.svg)](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,不再伪装成功