s3-upload

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

S3 Upload

S3 Upload

通过
scripts/s3-cli.js
操作 S3 兼容存储(七牛 Kodo、MinIO、AWS S3 等)。配置来自环境变量,与
src/app-agent/lib/server/s3-storage.ts
.env-template
一致。
Operate S3-compatible storage (Qiniu Kodo, MinIO, AWS S3, etc.) via
scripts/s3-cli.js
. Configurations come from environment variables, consistent with
src/app-agent/lib/server/s3-storage.ts
and
.env-template
.

Agent 工作流

Agent Workflow

  1. 先检查配置 — 未配置时不要猜测密钥,提示用户补全
    .env
    bash
    node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js config
  2. 选命令 — 上传用
    upload
    ;浏览用
    list
    ;按名称搜用
    find
    ;取公网链用
    url
  3. 优先
    --json
    — 需要解析结果给后续步骤时用 JSON 输出。
  4. 从仓库根目录执行 — 依赖根目录
    node_modules
    中的
    @aws-sdk/client-s3
  5. 删除需
    --yes
    — 避免误删;向用户确认后再删。
  6. 失败时必须给出正确反馈 — 见下方「错误处理」;不要编造 URL 或假装上传成功。
  1. Check Configuration First — Do not guess credentials when not configured, prompt the user to complete
    .env
    :
    bash
    node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js config
  2. Select Command — Use
    upload
    for uploading;
    list
    for browsing;
    find
    for searching by name;
    url
    for getting public links.
  3. Prioritize
    --json
    — Use JSON output when results need to be parsed for subsequent steps.
  4. Execute from Repository Root — Depends on
    @aws-sdk/client-s3
    in the root directory's
    node_modules
    .
  5. --yes
    Required for Deletion
    — Avoid accidental deletion; confirm with the user before deleting.
  6. Must Provide Correct Feedback on Failure — See "Error Handling" below; do not fabricate URLs or pretend uploads were successful.

错误处理(Agent 必遵)

Error Handling (Mandatory for Agent)

CLI 失败时 exit code = 1。加
--json
时 stdout 为结构化 JSON(含
code
error
hint
),Agent 必须解析后再回复用户
When the CLI fails, exit code = 1. When adding
--json
, stdout is structured JSON (containing
code
,
error
,
hint
), and the Agent must parse it before replying to the user.

回复用户格式

User Reply Format

失败时按此结构告知用户(用中文,不要只贴原始 stack):
  1. 发生了什么 — 引用
    error
    字段
  2. 可能原因 — 结合
    code
    与上下文
  3. 下一步 — 引用
    hint
    ;若可自动修复(如
    --no-acl
    ),先尝试再汇报
禁止: 忽略 exit code;把 stderr 当成功;未验证就回复公网 URL;向用户展示完整 Secret Key。
When failing, inform the user in this structure:
  1. What Happened — Reference the
    error
    field
  2. Possible Cause — Combine
    code
    with context
  3. Next Steps — Reference the
    hint
    ; if auto-fix is available (e.g.,
    --no-acl
    ), attempt it first before reporting
Prohibited: Ignore exit code; treat stderr as success; reply with public URL without verification; show complete Secret Key to users.

错误码对照

Error Code Reference

code
含义Agent 动作
CONFIG_MISSING
缺环境变量列出
missing
,指向
.env-template
,请用户补全后重跑
config
INVALID_CREDENTIALS
密钥错误请用户核对 AK/SK,不要重复用同一错误密钥盲试
ACCESS_DENIED
无权限说明权限不足;upload 时若 hint 提到
--no-acl
,自动重试一次
ACL_NOT_SUPPORTED
不支持 ACL
--no-acl
重试 upload
BUCKET_NOT_FOUND
桶不存在检查
S3_BUCKET_NAME
S3_ENDPOINT
是否匹配
OBJECT_NOT_FOUND
对象不存在建议
list --prefix
/
find
查正确 key
LOCAL_FILE_NOT_FOUND
本地文件不存在检查路径、cwd 是否在仓库根目录
DELETE_REQUIRES_CONFIRM
未加
--yes
向用户确认后再加
--yes
USAGE_ERROR
参数缺失按 hint 修正命令,不要猜参数
NETWORK_ERROR
网络/端点不可达检查 endpoint、region、代理
DEPENDENCY_MISSING
缺 SDK在仓库根目录
bun install
后重试
S3_ERROR
其他 S3 错误汇报
error
+
details
/
httpStatus
,建议跑
config
code
MeaningAgent Action
CONFIG_MISSING
Missing environment variablesList the
missing
variables, point to
.env-template
, ask the user to complete them and re-run
config
INVALID_CREDENTIALS
Invalid credentialsAsk the user to check AK/SK, do not blindly retry with the same invalid credentials
ACCESS_DENIED
Permission deniedExplain insufficient permissions; if the hint mentions
--no-acl
during upload, automatically retry once
ACL_NOT_SUPPORTED
ACL not supportedRetry upload with
--no-acl
BUCKET_NOT_FOUND
Bucket does not existCheck if
S3_BUCKET_NAME
matches
S3_ENDPOINT
OBJECT_NOT_FOUND
Object does not existSuggest using
list --prefix
/
find
to locate the correct key
LOCAL_FILE_NOT_FOUND
Local file does not existCheck the path and whether cwd is in the repository root
DELETE_REQUIRES_CONFIRM
--yes
not added
Confirm with the user before adding
--yes
USAGE_ERROR
Missing parametersCorrect the command according to the hint, do not guess parameters
NETWORK_ERROR
Network/endpoint unreachableCheck endpoint, region, and proxy
DEPENDENCY_MISSING
Missing SDKRetry after running
bun install
in the repository root
S3_ERROR
Other S3 errorsReport
error
+
details
/
httpStatus
, suggest running
config

诊断流程

Diagnostic Flow

命令失败 (exit 1)
  ├─ 加 --json 重跑,读取 code
  ├─ CONFIG_* / INVALID_CREDENTIALS → config
  ├─ OBJECT_NOT_FOUND → list/find 定位 key
  ├─ ACCESS_DENIED + upload → 试 --no-acl
  └─ 仍失败 → 原样汇报 error/hint/details,不要擅自改密钥
Command failed (exit 1)
  ├─ Re-run with --json, read code
  ├─ CONFIG_* / INVALID_CREDENTIALS → config
  ├─ OBJECT_NOT_FOUND → list/find to locate key
  ├─ ACCESS_DENIED + upload → try --no-acl
  └─ Still failed → Report error/hint/details as is, do not modify credentials without permission

示例:向用户反馈

Example: User Feedback

配置缺失:
S3 未配置完整,缺少
S3_SECRET_ACCESS_KEY
。请在项目根目录
.env
中补全(参考
.env-template
),保存后我再验证。
上传 ACL 失败(Agent 应先重试):
存储不支持 ACL,已改用
--no-acl
重新上传并成功。公网 URL: …
对象不存在:
桶内没有
assets/demo/missing.png
。当前
assets/demo/
下共有 3 个文件:…
Missing Configuration:
S3 is not fully configured, missing
S3_SECRET_ACCESS_KEY
. Please complete it in the
.env
file at the project root (refer to
.env-template
), and I will verify it after saving.
Upload ACL Failure (Agent should retry first):
The storage does not support ACL. Has re-uploaded successfully using
--no-acl
. Public URL: …
Object Not Found:
The object
assets/demo/missing.png
does not exist in the bucket. There are 3 files under current
assets/demo/
: …

快速开始

Quick Start

bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js --help
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js config
上传并拿到公网 URL:
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js upload ./local.png --prefix assets/demo/
列出 / 查找:
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js list --prefix uploads/ --max 50
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js find "photo" --prefix assets/
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js find "*.png" --prefix assets/
下载 / 删除 / URL:
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js download assets/demo/photo.png --output ./photo.png
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js url assets/demo/photo.png
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js delete assets/demo/old.png --yes
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js --help
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js config
Upload and get public URL:
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js upload ./local.png --prefix assets/demo/
List / Find:
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js list --prefix uploads/ --max 50
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js find "photo" --prefix assets/
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js find "*.png" --prefix assets/
Download / Delete / URL:
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js download assets/demo/photo.png --output ./photo.png
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js url assets/demo/photo.png
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js delete assets/demo/old.png --yes

环境变量

Environment Variables

变量必填说明
S3_BUCKET_NAME
存储桶
S3_ACCESS_KEY_ID
Access Key
S3_SECRET_ACCESS_KEY
Secret Key
S3_ENDPOINT
服务端点(如
https://s3.cn-south-1.qiniucs.com
S3_REGION
默认
cn-south-1
(七牛);阿里云填
cn-hangzhou
S3_CDN
CDN 域名;
url
/ 上传结果优先用 CDN 拼公网 URL
S3_PROVIDER
提供商标识(
kodo
/
aliyun
/
minio
等);
aliyun
时 upload 默认不带 ACL
CLI 会自动读取仓库根目录
.env
(不覆盖已有
process.env
)。也可显式传
node --env-file-if-exists=.env
禁止 把密钥写入 skill、脚本或提交到 git。只读
.env
或用户提供的 env。
VariableRequiredDescription
S3_BUCKET_NAME
YesStorage bucket
S3_ACCESS_KEY_ID
YesAccess Key
S3_SECRET_ACCESS_KEY
YesSecret Key
S3_ENDPOINT
YesService endpoint (e.g.,
https://s3.cn-south-1.qiniucs.com
)
S3_REGION
NoDefaults to
cn-south-1
(Qiniu); fill in
cn-hangzhou
etc. for Alibaba Cloud
S3_CDN
NoCDN domain name;
url
/ upload results will use CDN to generate public URLs first
S3_PROVIDER
NoProvider identifier (
kodo
/
aliyun
/
minio
etc.); when
aliyun
is set, upload does not include ACL by default
The CLI automatically reads the
.env
file in the repository root (does not overwrite existing
process.env
). You can also explicitly pass
node --env-file-if-exists=.env
.
Do NOT write credentials into skills, scripts, or commit to git. Only read from
.env
or user-provided env.

阿里云 OSS(
S3_PROVIDER=aliyun

Alibaba Cloud OSS (
S3_PROVIDER=aliyun
)

env
S3_BUCKET_NAME=<bucket>
S3_ACCESS_KEY_ID=<RAM AccessKey ID>
S3_SECRET_ACCESS_KEY=<RAM AccessKey Secret>
S3_ENDPOINT=https://<bucket>.s3.oss-<region>.aliyuncs.com
S3_REGION=cn-hangzhou
S3_CDN=https://<your-cdn-domain>
S3_PROVIDER=aliyun
要点:
  • Endpoint — 推荐 S3 兼容格式:
    https://<bucket>.s3.oss-cn-hangzhou.aliyuncs.com
    (与
    S3_BUCKET_NAME
    一致);亦可用
    https://s3.oss-cn-hangzhou.aliyuncs.com
    (path-style)。CLI 会自动识别 endpoint 是否已含 bucket 子域。
  • Region — 与 endpoint 中的地域一致(如
    cn-hangzhou
    ),不要用占位符
    <your-region>
  • ACL — 新版 OSS 桶通常禁用 Object ACL;CLI 在
    aliyun
    默认不上传 ACL。若仍报 ACL 错,显式加
    --no-acl
  • 公网 URL — 配置了
    S3_CDN
    时:
    https://cdn.example.com/<objectKey>
    ;需确保 CDN 已绑定该桶并开启回源。
  • RAM 权限 — 密钥需有目标桶的
    oss:PutObject
    oss:GetObject
    oss:ListObjects
    oss:DeleteObject
    等。
env
S3_BUCKET_NAME=<bucket>
S3_ACCESS_KEY_ID=<RAM AccessKey ID>
S3_SECRET_ACCESS_KEY=<RAM AccessKey Secret>
S3_ENDPOINT=https://<bucket>.s3.oss-<region>.aliyuncs.com
S3_REGION=cn-hangzhou
S3_CDN=https://<your-cdn-domain>
S3_PROVIDER=aliyun
Key Points:
  • Endpoint — Recommended S3-compatible format:
    https://<bucket>.s3.oss-cn-hangzhou.aliyuncs.com
    (consistent with
    S3_BUCKET_NAME
    ); you can also use
    https://s3.oss-cn-hangzhou.aliyuncs.com
    (path-style). The CLI will automatically detect whether the endpoint contains a bucket subdomain.
  • Region — Consistent with the region in the endpoint (e.g.,
    cn-hangzhou
    ), do not use placeholder
    <your-region>
    .
  • ACL — New OSS buckets usually disable Object ACL; the CLI does not upload ACL by default when
    aliyun
    is set. If you still get an ACL error, explicitly add
    --no-acl
    .
  • Public URL — When
    S3_CDN
    is configured:
    https://cdn.example.com/<objectKey>
    ; ensure the CDN is bound to the bucket and origin-pull is enabled.
  • RAM Permissions — The credentials need permissions like
    oss:PutObject
    ,
    oss:GetObject
    ,
    oss:ListObjects
    ,
    oss:DeleteObject
    for the target bucket.

命令参考

Command Reference

命令用途
config
验证配置,密钥脱敏输出
upload <file>
上传;
--key
/
--prefix
/
--content-type
/
--acl
/
--no-acl
list
--prefix
列出;
--max
限制条数
find <pattern>
key 子串或
*
?
通配;配合
--prefix
head <key>
是否存在及元数据
download <key>
下载;
--output
指定路径
delete <key> --yes
删除对象
url <key>
输出公网 URL
全局:
--json
-h
/
--help
CommandPurpose
config
Verify configuration, output credentials in desensitized format
upload <file>
Upload; options:
--key
/
--prefix
/
--content-type
/
--acl
/
--no-acl
list
List by
--prefix
;
--max
limits the number of items
find <pattern>
Substring or wildcard (
*
?
) search for keys; use with
--prefix
head <key>
Check existence and metadata
download <key>
Download;
--output
specifies the path
delete <key> --yes
Delete object
url <key>
Output public URL
Global options:
--json
,
-h
/
--help
.

与应用代码的关系

Relationship with Application Code

  • 服务端上传逻辑见
    src/app-agent/lib/server/s3-storage.ts
    (Presigned POST、CDN URL 解析等)。
  • Agent 运维/一次性上传 用本 skill 的 CLI,不要在对话里重写 SDK 逻辑。
  • 应用内功能 继续用
    s3-storage.ts
    或现有 OSS 管道,不要混用 CLI。
  • Server-side upload logic can be found in
    src/app-agent/lib/server/s3-storage.ts
    (Presigned POST, CDN URL parsing, etc.).
  • Agent operation/one-time upload uses this skill's CLI; do not rewrite SDK logic in conversations.
  • In-app functions continue to use
    s3-storage.ts
    or existing OSS pipelines; do not mix with the CLI.

常见场景

Common Scenarios

用户要上传截图/构建产物并分享链接
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js upload ./dist/bundle.zip --key releases/v1.2.0/bundle.zip --json
从 JSON 取
publicUrl
回复用户。
用户问某前缀下有哪些文件
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js list --prefix static/_next/ --max 100 --json
用户给了 CDN URL,要确认 key 是否存在
objectKeyFromPublicUrl
的逻辑:去掉 CDN 前缀得 key,再
head
配置报错
缺少必填 env → CLI 返回
CONFIG_MISSING
missing
数组 → 对照
.env-template
请用户补全 → 重跑
config
直到
ok: true
CLI 返回 JSON 错误示例
json
{
  "ok": false,
  "code": "ACL_NOT_SUPPORTED",
  "error": "当前存储不支持 ACL 字段",
  "hint": "重试: upload <file> ... --no-acl",
  "details": "…"
}
Agent 应执行 hint 中的重试,成功后再回复用户。
.env
中勿重复定义
S3_*
同一文件内出现多组
S3_BUCKET_NAME
等变量时,后出现的会覆盖先前的(Node
--env-file
行为)。只保留一组配置,旧配置注释掉。
User wants to upload screenshots/build artifacts and share links
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js upload ./dist/bundle.zip --key releases/v1.2.0/bundle.zip --json
Extract
publicUrl
from JSON to reply to the user.
User asks which files are under a certain prefix
bash
node --env-file-if-exists=.env .cursor/skills/s3-upload/scripts/s3-cli.js list --prefix static/_next/ --max 100 --json
User provides a CDN URL and wants to confirm if the key exists
Use the logic of
objectKeyFromPublicUrl
: remove the CDN prefix to get the key, then run
head
.
Configuration Error
Missing required env → CLI returns
CONFIG_MISSING
and
missing
array → Ask the user to complete it by referring to
.env-template
→ Re-run
config
until
ok: true
.
CLI JSON Error Example
json
{
  "ok": false,
  "code": "ACL_NOT_SUPPORTED",
  "error": "Current storage does not support ACL field",
  "hint": "Retry: upload <file> ... --no-acl",
  "details": "…"
}
The Agent should execute the retry in the hint, then reply to the user after success.
Do NOT Define
S3_*
Repeatedly in
.env
When multiple sets of variables like
S3_BUCKET_NAME
appear in the same file, the later ones will overwrite the earlier ones (Node
--env-file
behavior). Keep only one set of configurations, comment out old ones.